FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/aic.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 169 190 88.9%
Functions: 9 9 100.0%
Branches: 95 114 83.3%

Line Branch Exec Source
1 /*
2 * Apple Intermediate Codec decoder
3 *
4 * Copyright (c) 2013 Konstantin Shishkov
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include <inttypes.h>
24
25 #include "libavutil/mem.h"
26 #include "libavutil/mem_internal.h"
27
28 #include "avcodec.h"
29 #include "bytestream.h"
30 #include "codec_internal.h"
31 #include "get_bits.h"
32 #include "golomb.h"
33 #include "idctdsp.h"
34 #include "thread.h"
35 #include "unary.h"
36
37 #define AIC_HDR_SIZE 24
38 #define AIC_BAND_COEFFS (64 + 32 + 192 + 96)
39
40 enum AICBands {
41 COEFF_LUMA = 0,
42 COEFF_CHROMA,
43 COEFF_LUMA_EXT,
44 COEFF_CHROMA_EXT,
45 NUM_BANDS
46 };
47
48 static const uint8_t aic_num_band_coeffs[NUM_BANDS] = { 64, 32, 192, 96 };
49
50 static const uint16_t aic_band_off[NUM_BANDS] = { 0, 64, 96, 288 };
51
52 static const uint8_t aic_quant_matrix[64] = {
53 8, 16, 19, 22, 22, 26, 26, 27,
54 16, 16, 22, 22, 26, 27, 27, 29,
55 19, 22, 26, 26, 27, 29, 29, 35,
56 22, 24, 27, 27, 29, 32, 34, 38,
57 26, 27, 29, 29, 32, 35, 38, 46,
58 27, 29, 34, 34, 35, 40, 46, 56,
59 29, 34, 34, 37, 40, 48, 56, 69,
60 34, 37, 38, 40, 48, 58, 69, 83,
61 };
62
63 static const uint8_t aic_y_scan[64] = {
64 0, 4, 1, 2, 5, 8, 12, 9,
65 6, 3, 7, 10, 13, 14, 11, 15,
66 47, 43, 46, 45, 42, 39, 35, 38,
67 41, 44, 40, 37, 34, 33, 36, 32,
68 16, 20, 17, 18, 21, 24, 28, 25,
69 22, 19, 23, 26, 29, 30, 27, 31,
70 63, 59, 62, 61, 58, 55, 51, 54,
71 57, 60, 56, 53, 50, 49, 52, 48,
72 };
73
74 static const uint8_t aic_y_ext_scan[192] = {
75 64, 72, 65, 66, 73, 80, 88, 81,
76 74, 67, 75, 82, 89, 90, 83, 91,
77 0, 4, 1, 2, 5, 8, 12, 9,
78 6, 3, 7, 10, 13, 14, 11, 15,
79 16, 20, 17, 18, 21, 24, 28, 25,
80 22, 19, 23, 26, 29, 30, 27, 31,
81 155, 147, 154, 153, 146, 139, 131, 138,
82 145, 152, 144, 137, 130, 129, 136, 128,
83 47, 43, 46, 45, 42, 39, 35, 38,
84 41, 44, 40, 37, 34, 33, 36, 32,
85 63, 59, 62, 61, 58, 55, 51, 54,
86 57, 60, 56, 53, 50, 49, 52, 48,
87 96, 104, 97, 98, 105, 112, 120, 113,
88 106, 99, 107, 114, 121, 122, 115, 123,
89 68, 76, 69, 70, 77, 84, 92, 85,
90 78, 71, 79, 86, 93, 94, 87, 95,
91 100, 108, 101, 102, 109, 116, 124, 117,
92 110, 103, 111, 118, 125, 126, 119, 127,
93 187, 179, 186, 185, 178, 171, 163, 170,
94 177, 184, 176, 169, 162, 161, 168, 160,
95 159, 151, 158, 157, 150, 143, 135, 142,
96 149, 156, 148, 141, 134, 133, 140, 132,
97 191, 183, 190, 189, 182, 175, 167, 174,
98 181, 188, 180, 173, 166, 165, 172, 164,
99 };
100
101 static const uint8_t aic_c_scan[64] = {
102 0, 4, 1, 2, 5, 8, 12, 9,
103 6, 3, 7, 10, 13, 14, 11, 15,
104 31, 27, 30, 29, 26, 23, 19, 22,
105 25, 28, 24, 21, 18, 17, 20, 16,
106 32, 36, 33, 34, 37, 40, 44, 41,
107 38, 35, 39, 42, 45, 46, 43, 47,
108 63, 59, 62, 61, 58, 55, 51, 54,
109 57, 60, 56, 53, 50, 49, 52, 48,
110 };
111
112 static const uint8_t aic_c_ext_scan[192] = {
113 16, 24, 17, 18, 25, 32, 40, 33,
114 26, 19, 27, 34, 41, 42, 35, 43,
115 0, 4, 1, 2, 5, 8, 12, 9,
116 6, 3, 7, 10, 13, 14, 11, 15,
117 20, 28, 21, 22, 29, 36, 44, 37,
118 30, 23, 31, 38, 45, 46, 39, 47,
119 95, 87, 94, 93, 86, 79, 71, 78,
120 85, 92, 84, 77, 70, 69, 76, 68,
121 63, 59, 62, 61, 58, 55, 51, 54,
122 57, 60, 56, 53, 50, 49, 52, 48,
123 91, 83, 90, 89, 82, 75, 67, 74,
124 81, 88, 80, 73, 66, 65, 72, 64,
125 112, 120, 113, 114, 121, 128, 136, 129,
126 122, 115, 123, 130, 137, 138, 131, 139,
127 96, 100, 97, 98, 101, 104, 108, 105,
128 102, 99, 103, 106, 109, 110, 107, 111,
129 116, 124, 117, 118, 125, 132, 140, 133,
130 126, 119, 127, 134, 141, 142, 135, 143,
131 191, 183, 190, 189, 182, 175, 167, 174,
132 181, 188, 180, 173, 166, 165, 172, 164,
133 159, 155, 158, 157, 154, 151, 147, 150,
134 153, 156, 152, 149, 146, 145, 148, 144,
135 187, 179, 186, 185, 178, 171, 163, 170,
136 177, 184, 176, 169, 162, 161, 168, 160,
137 };
138
139 static const uint8_t * const aic_scan[NUM_BANDS] = {
140 aic_y_scan, aic_c_scan, aic_y_ext_scan, aic_c_ext_scan
141 };
142
143 typedef struct AICContext {
144 AVCodecContext *avctx;
145 AVFrame *frame;
146 IDCTDSPContext idsp;
147
148 int num_x_slices;
149 int slice_width;
150 int mb_width, mb_height;
151 int quant;
152 int interlaced;
153
154 int16_t *slice_data;
155 int16_t *data_ptr[NUM_BANDS];
156
157 DECLARE_ALIGNED(16, int16_t, block)[64];
158 DECLARE_ALIGNED(16, uint8_t, quant_matrix)[64];
159 } AICContext;
160
161 73 static int aic_decode_header(AICContext *ctx, const uint8_t *src, int size)
162 {
163 uint32_t frame_size;
164 int width, height;
165
166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 if (src[0] != 1) {
167 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid version %d\n", src[0]);
168 return AVERROR_INVALIDDATA;
169 }
170
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 if (src[1] != AIC_HDR_SIZE - 2) {
171 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid header size %d\n", src[1]);
172 return AVERROR_INVALIDDATA;
173 }
174 73 frame_size = AV_RB32(src + 2);
175 73 width = AV_RB16(src + 6);
176 73 height = AV_RB16(src + 8);
177
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 72 times.
73 if (frame_size > size) {
178 1 av_log(ctx->avctx, AV_LOG_ERROR, "Frame size should be %"PRIu32" got %d\n",
179 frame_size, size);
180 1 return AVERROR_INVALIDDATA;
181 }
182
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 72 times.
72 if (width != ctx->avctx->width || height != ctx->avctx->height) {
183 av_log(ctx->avctx, AV_LOG_ERROR,
184 "Picture dimension changed: old: %d x %d, new: %d x %d\n",
185 ctx->avctx->width, ctx->avctx->height, width, height);
186 return AVERROR_INVALIDDATA;
187 }
188 72 ctx->quant = src[15];
189 72 ctx->interlaced = ((src[16] >> 4) == 3);
190
191 72 return 0;
192 }
193
194 #define GET_CODE(val, type, add_bits) \
195 do { \
196 if (type) \
197 val = get_ue_golomb(gb); \
198 else \
199 val = get_unary(gb, 1, 31); \
200 if (add_bits) \
201 val = (val << add_bits) + get_bits(gb, add_bits); \
202 } while (0)
203
204 15888 static int aic_decode_coeffs(GetBitContext *gb, int16_t *dst,
205 int band, int slice_width, int force_chroma)
206 {
207 int has_skips, coeff_type, coeff_bits, skip_type, skip_bits;
208 15888 const int num_coeffs = aic_num_band_coeffs[band];
209 15888 const uint8_t *scan = aic_scan[band | force_chroma];
210 int mb, idx;
211 unsigned val;
212
213
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 15888 times.
15888 if (get_bits_left(gb) < 5)
214 return AVERROR_INVALIDDATA;
215
216 15888 has_skips = get_bits1(gb);
217 15888 coeff_type = get_bits1(gb);
218 15888 coeff_bits = get_bits(gb, 3);
219
220
2/2
✓ Branch 0 taken 13996 times.
✓ Branch 1 taken 1892 times.
15888 if (has_skips) {
221 13996 skip_type = get_bits1(gb);
222 13996 skip_bits = get_bits(gb, 3);
223
224
2/2
✓ Branch 0 taken 423437 times.
✓ Branch 1 taken 13996 times.
437433 for (mb = 0; mb < slice_width; mb++) {
225 423437 idx = -1;
226 do {
227
3/4
✓ Branch 0 taken 5032630 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 323504 times.
✓ Branch 5 taken 4709126 times.
5032630 GET_CODE(val, skip_type, skip_bits);
228
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5032630 times.
5032630 if (val >= 0x10000)
229 return AVERROR_INVALIDDATA;
230 5032630 idx += val + 1;
231
2/2
✓ Branch 0 taken 252068 times.
✓ Branch 1 taken 4780562 times.
5032630 if (idx >= num_coeffs)
232 252068 break;
233
4/4
✓ Branch 0 taken 4639461 times.
✓ Branch 1 taken 141101 times.
✓ Branch 4 taken 4639461 times.
✓ Branch 5 taken 141101 times.
4780562 GET_CODE(val, coeff_type, coeff_bits);
234 4780562 val++;
235
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4780562 times.
4780562 if (val >= 0x10000)
236 return AVERROR_INVALIDDATA;
237 4780562 dst[scan[idx]] = val;
238
2/2
✓ Branch 0 taken 4609193 times.
✓ Branch 1 taken 171369 times.
4780562 } while (idx < num_coeffs - 1);
239 423437 dst += num_coeffs;
240 }
241 } else {
242
2/2
✓ Branch 0 taken 56851 times.
✓ Branch 1 taken 1892 times.
58743 for (mb = 0; mb < slice_width; mb++) {
243
2/2
✓ Branch 0 taken 10519744 times.
✓ Branch 1 taken 56851 times.
10576595 for (idx = 0; idx < num_coeffs; idx++) {
244
3/4
✓ Branch 0 taken 10519744 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 180544 times.
✓ Branch 5 taken 10339200 times.
10519744 GET_CODE(val, coeff_type, coeff_bits);
245
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10519744 times.
10519744 if (val >= 0x10000)
246 return AVERROR_INVALIDDATA;
247 10519744 dst[scan[idx]] = val;
248 }
249 56851 dst += num_coeffs;
250 }
251 }
252 15888 return 0;
253 }
254
255 353232 static void recombine_block(int16_t *dst, const uint8_t *scan,
256 int16_t **base, int16_t **ext)
257 {
258 int i, j;
259
260
2/2
✓ Branch 0 taken 1412928 times.
✓ Branch 1 taken 353232 times.
1766160 for (i = 0; i < 4; i++) {
261
2/2
✓ Branch 0 taken 5651712 times.
✓ Branch 1 taken 1412928 times.
7064640 for (j = 0; j < 4; j++)
262 5651712 dst[scan[i * 8 + j]] = (*base)[j];
263
2/2
✓ Branch 0 taken 5651712 times.
✓ Branch 1 taken 1412928 times.
7064640 for (j = 0; j < 4; j++)
264 5651712 dst[scan[i * 8 + j + 4]] = (*ext)[j];
265 1412928 *base += 4;
266 1412928 *ext += 4;
267 }
268
2/2
✓ Branch 0 taken 1412928 times.
✓ Branch 1 taken 353232 times.
1766160 for (; i < 8; i++) {
269
2/2
✓ Branch 0 taken 11303424 times.
✓ Branch 1 taken 1412928 times.
12716352 for (j = 0; j < 8; j++)
270 11303424 dst[scan[i * 8 + j]] = (*ext)[j];
271 1412928 *ext += 8;
272 }
273 353232 }
274
275 367200 static void recombine_block_il(int16_t *dst, const uint8_t *scan,
276 int16_t **base, int16_t **ext,
277 int block_no)
278 {
279 int i, j;
280
281
2/2
✓ Branch 0 taken 183600 times.
✓ Branch 1 taken 183600 times.
367200 if (block_no < 2) {
282
2/2
✓ Branch 0 taken 1468800 times.
✓ Branch 1 taken 183600 times.
1652400 for (i = 0; i < 8; i++) {
283
2/2
✓ Branch 0 taken 5875200 times.
✓ Branch 1 taken 1468800 times.
7344000 for (j = 0; j < 4; j++)
284 5875200 dst[scan[i * 8 + j]] = (*base)[j];
285
2/2
✓ Branch 0 taken 5875200 times.
✓ Branch 1 taken 1468800 times.
7344000 for (j = 0; j < 4; j++)
286 5875200 dst[scan[i * 8 + j + 4]] = (*ext)[j];
287 1468800 *base += 4;
288 1468800 *ext += 4;
289 }
290 } else {
291
2/2
✓ Branch 0 taken 11750400 times.
✓ Branch 1 taken 183600 times.
11934000 for (i = 0; i < 64; i++)
292 11750400 dst[scan[i]] = (*ext)[i];
293 183600 *ext += 64;
294 }
295 367200 }
296
297 720432 static void unquant_block(int16_t *block, int q, uint8_t *quant_matrix)
298 {
299 int i;
300
301
2/2
✓ Branch 0 taken 46107648 times.
✓ Branch 1 taken 720432 times.
46828080 for (i = 0; i < 64; i++) {
302 46107648 int val = (uint16_t)block[i];
303 46107648 int sign = val & 1;
304
305 46107648 block[i] = (((val >> 1) ^ -sign) * q * quant_matrix[i] >> 4)
306 46107648 + sign;
307 }
308 720432 }
309
310 3972 static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y,
311 const uint8_t *src, int src_size)
312 {
313 GetBitContext gb;
314 int ret, i, mb, blk;
315 3972 int slice_width = FFMIN(ctx->slice_width, ctx->mb_width - mb_x);
316
4/4
✓ Branch 0 taken 3870 times.
✓ Branch 1 taken 102 times.
✓ Branch 2 taken 102 times.
✓ Branch 3 taken 3768 times.
3972 int last_row = mb_y && mb_y == ctx->mb_height - 1;
317 int y_pos, c_pos;
318 uint8_t *Y, *C[2];
319 uint8_t *dst;
320 3972 int16_t *base_y = ctx->data_ptr[COEFF_LUMA];
321 3972 int16_t *base_c = ctx->data_ptr[COEFF_CHROMA];
322 3972 int16_t *ext_y = ctx->data_ptr[COEFF_LUMA_EXT];
323 3972 int16_t *ext_c = ctx->data_ptr[COEFF_CHROMA_EXT];
324 3972 const int ystride = ctx->frame->linesize[0];
325
326
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 3870 times.
3972 if (last_row) {
327 102 y_pos = (ctx->avctx->height - 16);
328 102 c_pos = ((ctx->avctx->height+1)/2 - 8);
329 } else {
330 3870 y_pos = mb_y * 16;
331 3870 c_pos = mb_y * 8;
332 }
333
334 3972 Y = ctx->frame->data[0] + mb_x * 16 + y_pos * ystride;
335
2/2
✓ Branch 0 taken 7944 times.
✓ Branch 1 taken 3972 times.
11916 for (i = 0; i < 2; i++)
336 7944 C[i] = ctx->frame->data[i + 1] + mb_x * 8
337 7944 + c_pos * ctx->frame->linesize[i + 1];
338 3972 init_get_bits(&gb, src, src_size * 8);
339
340 3972 memset(ctx->slice_data, 0,
341 sizeof(*ctx->slice_data) * slice_width * AIC_BAND_COEFFS);
342
2/2
✓ Branch 0 taken 15888 times.
✓ Branch 1 taken 3972 times.
19860 for (i = 0; i < NUM_BANDS; i++)
343
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15888 times.
15888 if ((ret = aic_decode_coeffs(&gb, ctx->data_ptr[i],
344 i, slice_width,
345 15888 !ctx->interlaced)) < 0)
346 return ret;
347
348
2/2
✓ Branch 0 taken 120072 times.
✓ Branch 1 taken 3972 times.
124044 for (mb = 0; mb < slice_width; mb++) {
349
2/2
✓ Branch 0 taken 480288 times.
✓ Branch 1 taken 120072 times.
600360 for (blk = 0; blk < 4; blk++) {
350
2/2
✓ Branch 0 taken 113088 times.
✓ Branch 1 taken 367200 times.
480288 if (!ctx->interlaced)
351 113088 recombine_block(ctx->block, ctx->idsp.idct_permutation,
352 &base_y, &ext_y);
353 else
354 367200 recombine_block_il(ctx->block, ctx->idsp.idct_permutation,
355 &base_y, &ext_y, blk);
356 480288 unquant_block(ctx->block, ctx->quant, ctx->quant_matrix);
357 480288 ctx->idsp.idct(ctx->block);
358
359
2/2
✓ Branch 0 taken 113088 times.
✓ Branch 1 taken 367200 times.
480288 if (!ctx->interlaced) {
360 113088 dst = Y + (blk >> 1) * 8 * ystride + (blk & 1) * 8;
361 113088 ctx->idsp.put_signed_pixels_clamped(ctx->block, dst, ystride);
362 } else {
363 367200 dst = Y + (blk & 1) * 8 + (blk >> 1) * ystride;
364 367200 ctx->idsp.put_signed_pixels_clamped(ctx->block, dst,
365 367200 ystride * 2);
366 }
367 }
368 120072 Y += 16;
369
370
2/2
✓ Branch 0 taken 240144 times.
✓ Branch 1 taken 120072 times.
360216 for (blk = 0; blk < 2; blk++) {
371 240144 recombine_block(ctx->block, ctx->idsp.idct_permutation,
372 &base_c, &ext_c);
373 240144 unquant_block(ctx->block, ctx->quant, ctx->quant_matrix);
374 240144 ctx->idsp.idct(ctx->block);
375 240144 ctx->idsp.put_signed_pixels_clamped(ctx->block, C[blk],
376 240144 ctx->frame->linesize[blk + 1]);
377 240144 C[blk] += 8;
378 }
379 }
380
381 3972 return 0;
382 }
383
384 73 static int aic_decode_frame(AVCodecContext *avctx, AVFrame *frame,
385 int *got_frame, AVPacket *avpkt)
386 {
387 73 AICContext *ctx = avctx->priv_data;
388 73 const uint8_t *buf = avpkt->data;
389 73 int buf_size = avpkt->size;
390 GetByteContext gb;
391 uint32_t off;
392 int x, y, ret;
393 int slice_size;
394
395 73 ctx->frame = frame;
396
397 73 off = FFALIGN(AIC_HDR_SIZE + ctx->num_x_slices * ctx->mb_height * 2, 4);
398
399
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73 times.
73 if (buf_size < off) {
400 av_log(avctx, AV_LOG_ERROR, "Too small frame\n");
401 return AVERROR_INVALIDDATA;
402 }
403
404 73 ret = aic_decode_header(ctx, buf, buf_size);
405
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 72 times.
73 if (ret < 0) {
406 1 av_log(avctx, AV_LOG_ERROR, "Invalid header\n");
407 1 return ret;
408 }
409
410
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
72 if ((ret = ff_thread_get_buffer(avctx, ctx->frame, 0)) < 0)
411 return ret;
412
413 72 bytestream2_init(&gb, buf + AIC_HDR_SIZE,
414 72 ctx->num_x_slices * ctx->mb_height * 2);
415
416
2/2
✓ Branch 0 taken 1932 times.
✓ Branch 1 taken 72 times.
2004 for (y = 0; y < ctx->mb_height; y++) {
417
2/2
✓ Branch 0 taken 3972 times.
✓ Branch 1 taken 1932 times.
5904 for (x = 0; x < ctx->mb_width; x += ctx->slice_width) {
418 3972 slice_size = bytestream2_get_le16(&gb) * 4;
419
2/4
✓ Branch 0 taken 3972 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3972 times.
3972 if (slice_size + off > buf_size || !slice_size) {
420 av_log(avctx, AV_LOG_ERROR,
421 "Incorrect slice size %d at %d.%d\n", slice_size, x, y);
422 return AVERROR_INVALIDDATA;
423 }
424
425 3972 ret = aic_decode_slice(ctx, x, y, buf + off, slice_size);
426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3972 times.
3972 if (ret < 0) {
427 av_log(avctx, AV_LOG_ERROR,
428 "Error decoding slice at %d.%d\n", x, y);
429 return ret;
430 }
431
432 3972 off += slice_size;
433 }
434 }
435
436 72 *got_frame = 1;
437
438 72 return avpkt->size;
439 }
440
441 4 static av_cold int aic_decode_init(AVCodecContext *avctx)
442 {
443 4 AICContext *ctx = avctx->priv_data;
444 int i;
445
446 4 ctx->avctx = avctx;
447
448 4 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
449
450 4 ff_idctdsp_init(&ctx->idsp, avctx);
451
452
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 4 times.
260 for (i = 0; i < 64; i++)
453 256 ctx->quant_matrix[ctx->idsp.idct_permutation[i]] = aic_quant_matrix[i];
454
455 4 ctx->mb_width = FFALIGN(avctx->width, 16) >> 4;
456 4 ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
457
458 4 ctx->num_x_slices = (ctx->mb_width + 15) >> 4;
459 4 ctx->slice_width = 16;
460
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 for (i = 1; i < ctx->mb_width; i++) {
461
3/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
8 if (!(ctx->mb_width % i) && (ctx->mb_width / i <= 32)) {
462 4 ctx->slice_width = ctx->mb_width / i;
463 4 ctx->num_x_slices = i;
464 4 break;
465 }
466 }
467
468 4 ctx->slice_data = av_calloc(ctx->slice_width, AIC_BAND_COEFFS * sizeof(*ctx->slice_data));
469
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!ctx->slice_data) {
470 av_log(avctx, AV_LOG_ERROR, "Error allocating slice buffer\n");
471
472 return AVERROR(ENOMEM);
473 }
474
475
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 4 times.
20 for (i = 0; i < NUM_BANDS; i++)
476 16 ctx->data_ptr[i] = ctx->slice_data + ctx->slice_width
477 16 * aic_band_off[i];
478
479 4 return 0;
480 }
481
482 4 static av_cold int aic_decode_close(AVCodecContext *avctx)
483 {
484 4 AICContext *ctx = avctx->priv_data;
485
486 4 av_freep(&ctx->slice_data);
487
488 4 return 0;
489 }
490
491 const FFCodec ff_aic_decoder = {
492 .p.name = "aic",
493 CODEC_LONG_NAME("Apple Intermediate Codec"),
494 .p.type = AVMEDIA_TYPE_VIDEO,
495 .p.id = AV_CODEC_ID_AIC,
496 .priv_data_size = sizeof(AICContext),
497 .init = aic_decode_init,
498 .close = aic_decode_close,
499 FF_CODEC_DECODE_CB(aic_decode_frame),
500 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
501 };
502