blob: e12d689c478a276131a49333a30dfd64b7542139 [file] [log] [blame]
Kostya Shishkov1232a162013-05-16 05:21:081/*
2 * Apple Intermediate Codec decoder
3 *
4 * Copyright (c) 2013 Konstantin Shishkov
5 *
Michael Niedermayer5bc892c2013-05-17 08:37:366 * This file is part of FFmpeg.
Kostya Shishkov1232a162013-05-16 05:21:087 *
Michael Niedermayer5bc892c2013-05-17 08:37:368 * FFmpeg is free software; you can redistribute it and/or
Kostya Shishkov1232a162013-05-16 05:21:089 * 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 *
Michael Niedermayer5bc892c2013-05-17 08:37:3613 * FFmpeg is distributed in the hope that it will be useful,
Kostya Shishkov1232a162013-05-16 05:21:0814 * 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
Michael Niedermayer5bc892c2013-05-17 08:37:3619 * License along with FFmpeg; if not, write to the Free Software
Kostya Shishkov1232a162013-05-16 05:21:0820 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
Diego Biurruncc8163e2014-03-13 11:13:3323#include <inttypes.h>
24
Andreas Rheinhardt790f7932024-03-25 00:30:3725#include "libavutil/mem.h"
Anton Khirnove1537102020-05-27 12:54:3826#include "libavutil/mem_internal.h"
27
Kostya Shishkov1232a162013-05-16 05:21:0828#include "avcodec.h"
29#include "bytestream.h"
Andreas Rheinhardta688f3c2022-03-16 17:18:2830#include "codec_internal.h"
Kostya Shishkov1232a162013-05-16 05:21:0831#include "get_bits.h"
32#include "golomb.h"
Diego Biurrune3fcb142014-01-24 10:55:1633#include "idctdsp.h"
Paul B Mahol8e069eb2016-05-20 18:54:1034#include "thread.h"
Kostya Shishkov1232a162013-05-16 05:21:0835#include "unary.h"
36
37#define AIC_HDR_SIZE 24
38#define AIC_BAND_COEFFS (64 + 32 + 192 + 96)
39
40enum AICBands {
41 COEFF_LUMA = 0,
42 COEFF_CHROMA,
43 COEFF_LUMA_EXT,
44 COEFF_CHROMA_EXT,
45 NUM_BANDS
46};
47
Andreas Rheinhardta1a88152019-06-19 02:39:4748static const uint8_t aic_num_band_coeffs[NUM_BANDS] = { 64, 32, 192, 96 };
Kostya Shishkov1232a162013-05-16 05:21:0849
Andreas Rheinhardta1a88152019-06-19 02:39:4750static const uint16_t aic_band_off[NUM_BANDS] = { 0, 64, 96, 288 };
Kostya Shishkov1232a162013-05-16 05:21:0851
52static 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
63static 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
74static 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
101static 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
112static 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
Reimar Döffingerd9e2ace2014-08-28 22:32:32139static const uint8_t * const aic_scan[NUM_BANDS] = {
Kostya Shishkov1232a162013-05-16 05:21:08140 aic_y_scan, aic_c_scan, aic_y_ext_scan, aic_c_ext_scan
141};
142
143typedef struct AICContext {
144 AVCodecContext *avctx;
145 AVFrame *frame;
Diego Biurrune3fcb142014-01-24 10:55:16146 IDCTDSPContext idsp;
Kostya Shishkov1232a162013-05-16 05:21:08147
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];
Michael Niedermayer0a2004b2014-06-05 21:21:15158 DECLARE_ALIGNED(16, uint8_t, quant_matrix)[64];
Kostya Shishkov1232a162013-05-16 05:21:08159} AICContext;
160
161static int aic_decode_header(AICContext *ctx, const uint8_t *src, int size)
162{
163 uint32_t frame_size;
164 int width, height;
165
166 if (src[0] != 1) {
167 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid version %d\n", src[0]);
168 return AVERROR_INVALIDDATA;
169 }
170 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 frame_size = AV_RB32(src + 2);
175 width = AV_RB16(src + 6);
176 height = AV_RB16(src + 8);
177 if (frame_size > size) {
Diego Biurruncc8163e2014-03-13 11:13:33178 av_log(ctx->avctx, AV_LOG_ERROR, "Frame size should be %"PRIu32" got %d\n",
Kostya Shishkov1232a162013-05-16 05:21:08179 frame_size, size);
180 return AVERROR_INVALIDDATA;
181 }
182 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 ctx->quant = src[15];
189 ctx->interlaced = ((src[16] >> 4) == 3);
190
191 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
204static int aic_decode_coeffs(GetBitContext *gb, int16_t *dst,
Kostya Shishkov41006692013-07-03 18:46:28205 int band, int slice_width, int force_chroma)
Kostya Shishkov1232a162013-05-16 05:21:08206{
207 int has_skips, coeff_type, coeff_bits, skip_type, skip_bits;
208 const int num_coeffs = aic_num_band_coeffs[band];
Kostya Shishkov41006692013-07-03 18:46:28209 const uint8_t *scan = aic_scan[band | force_chroma];
Michael Niedermayer657875b2013-05-22 19:29:45210 int mb, idx;
211 unsigned val;
Kostya Shishkov1232a162013-05-16 05:21:08212
Michael Niedermayer951bb762019-02-25 12:26:25213 if (get_bits_left(gb) < 5)
214 return AVERROR_INVALIDDATA;
215
Kostya Shishkov1232a162013-05-16 05:21:08216 has_skips = get_bits1(gb);
217 coeff_type = get_bits1(gb);
218 coeff_bits = get_bits(gb, 3);
219
220 if (has_skips) {
221 skip_type = get_bits1(gb);
222 skip_bits = get_bits(gb, 3);
223
224 for (mb = 0; mb < slice_width; mb++) {
225 idx = -1;
226 do {
227 GET_CODE(val, skip_type, skip_bits);
Michael Niedermayer657875b2013-05-22 19:29:45228 if (val >= 0x10000)
229 return AVERROR_INVALIDDATA;
Kostya Shishkov1232a162013-05-16 05:21:08230 idx += val + 1;
231 if (idx >= num_coeffs)
232 break;
233 GET_CODE(val, coeff_type, coeff_bits);
234 val++;
Michael Niedermayerbfe14452013-09-12 14:34:24235 if (val >= 0x10000)
Kostya Shishkov1232a162013-05-16 05:21:08236 return AVERROR_INVALIDDATA;
237 dst[scan[idx]] = val;
238 } while (idx < num_coeffs - 1);
239 dst += num_coeffs;
240 }
241 } else {
242 for (mb = 0; mb < slice_width; mb++) {
243 for (idx = 0; idx < num_coeffs; idx++) {
244 GET_CODE(val, coeff_type, coeff_bits);
Michael Niedermayerbfe14452013-09-12 14:34:24245 if (val >= 0x10000)
Kostya Shishkov1232a162013-05-16 05:21:08246 return AVERROR_INVALIDDATA;
247 dst[scan[idx]] = val;
248 }
249 dst += num_coeffs;
250 }
251 }
252 return 0;
253}
254
255static void recombine_block(int16_t *dst, const uint8_t *scan,
256 int16_t **base, int16_t **ext)
257{
258 int i, j;
259
260 for (i = 0; i < 4; i++) {
261 for (j = 0; j < 4; j++)
262 dst[scan[i * 8 + j]] = (*base)[j];
263 for (j = 0; j < 4; j++)
264 dst[scan[i * 8 + j + 4]] = (*ext)[j];
265 *base += 4;
266 *ext += 4;
267 }
268 for (; i < 8; i++) {
269 for (j = 0; j < 8; j++)
270 dst[scan[i * 8 + j]] = (*ext)[j];
271 *ext += 8;
272 }
273}
274
275static 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 if (block_no < 2) {
282 for (i = 0; i < 8; i++) {
283 for (j = 0; j < 4; j++)
284 dst[scan[i * 8 + j]] = (*base)[j];
285 for (j = 0; j < 4; j++)
286 dst[scan[i * 8 + j + 4]] = (*ext)[j];
287 *base += 4;
288 *ext += 4;
289 }
290 } else {
291 for (i = 0; i < 64; i++)
292 dst[scan[i]] = (*ext)[i];
293 *ext += 64;
294 }
295}
296
Michael Niedermayer0a2004b2014-06-05 21:21:15297static void unquant_block(int16_t *block, int q, uint8_t *quant_matrix)
Kostya Shishkov1232a162013-05-16 05:21:08298{
299 int i;
300
301 for (i = 0; i < 64; i++) {
302 int val = (uint16_t)block[i];
303 int sign = val & 1;
304
Michael Niedermayer0a2004b2014-06-05 21:21:15305 block[i] = (((val >> 1) ^ -sign) * q * quant_matrix[i] >> 4)
Kostya Shishkov1232a162013-05-16 05:21:08306 + sign;
307 }
308}
309
310static 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 int slice_width = FFMIN(ctx->slice_width, ctx->mb_width - mb_x);
Paul B Mahol5710fda2018-03-30 19:08:47316 int last_row = mb_y && mb_y == ctx->mb_height - 1;
317 int y_pos, c_pos;
Kostya Shishkov1232a162013-05-16 05:21:08318 uint8_t *Y, *C[2];
319 uint8_t *dst;
320 int16_t *base_y = ctx->data_ptr[COEFF_LUMA];
321 int16_t *base_c = ctx->data_ptr[COEFF_CHROMA];
322 int16_t *ext_y = ctx->data_ptr[COEFF_LUMA_EXT];
323 int16_t *ext_c = ctx->data_ptr[COEFF_CHROMA_EXT];
324 const int ystride = ctx->frame->linesize[0];
325
Paul B Mahol5710fda2018-03-30 19:08:47326 if (last_row) {
327 y_pos = (ctx->avctx->height - 16);
328 c_pos = ((ctx->avctx->height+1)/2 - 8);
329 } else {
330 y_pos = mb_y * 16;
331 c_pos = mb_y * 8;
332 }
333
334 Y = ctx->frame->data[0] + mb_x * 16 + y_pos * ystride;
Kostya Shishkov1232a162013-05-16 05:21:08335 for (i = 0; i < 2; i++)
336 C[i] = ctx->frame->data[i + 1] + mb_x * 8
Paul B Mahol5710fda2018-03-30 19:08:47337 + c_pos * ctx->frame->linesize[i + 1];
Kostya Shishkov1232a162013-05-16 05:21:08338 init_get_bits(&gb, src, src_size * 8);
339
340 memset(ctx->slice_data, 0,
341 sizeof(*ctx->slice_data) * slice_width * AIC_BAND_COEFFS);
342 for (i = 0; i < NUM_BANDS; i++)
343 if ((ret = aic_decode_coeffs(&gb, ctx->data_ptr[i],
Kostya Shishkov41006692013-07-03 18:46:28344 i, slice_width,
345 !ctx->interlaced)) < 0)
Kostya Shishkov1232a162013-05-16 05:21:08346 return ret;
347
348 for (mb = 0; mb < slice_width; mb++) {
349 for (blk = 0; blk < 4; blk++) {
350 if (!ctx->interlaced)
Andreas Rheinhardt4c9dee62022-10-19 16:22:55351 recombine_block(ctx->block, ctx->idsp.idct_permutation,
Kostya Shishkov1232a162013-05-16 05:21:08352 &base_y, &ext_y);
353 else
Andreas Rheinhardt4c9dee62022-10-19 16:22:55354 recombine_block_il(ctx->block, ctx->idsp.idct_permutation,
Kostya Shishkov1232a162013-05-16 05:21:08355 &base_y, &ext_y, blk);
Michael Niedermayer0a2004b2014-06-05 21:21:15356 unquant_block(ctx->block, ctx->quant, ctx->quant_matrix);
Diego Biurrune3fcb142014-01-24 10:55:16357 ctx->idsp.idct(ctx->block);
Kostya Shishkov1232a162013-05-16 05:21:08358
359 if (!ctx->interlaced) {
Kostya Shishkov41006692013-07-03 18:46:28360 dst = Y + (blk >> 1) * 8 * ystride + (blk & 1) * 8;
Diego Biurrune3fcb142014-01-24 10:55:16361 ctx->idsp.put_signed_pixels_clamped(ctx->block, dst, ystride);
Kostya Shishkov1232a162013-05-16 05:21:08362 } else {
363 dst = Y + (blk & 1) * 8 + (blk >> 1) * ystride;
Diego Biurrune3fcb142014-01-24 10:55:16364 ctx->idsp.put_signed_pixels_clamped(ctx->block, dst,
365 ystride * 2);
Kostya Shishkov1232a162013-05-16 05:21:08366 }
367 }
368 Y += 16;
369
370 for (blk = 0; blk < 2; blk++) {
Andreas Rheinhardt4c9dee62022-10-19 16:22:55371 recombine_block(ctx->block, ctx->idsp.idct_permutation,
Kostya Shishkov1232a162013-05-16 05:21:08372 &base_c, &ext_c);
Michael Niedermayer0a2004b2014-06-05 21:21:15373 unquant_block(ctx->block, ctx->quant, ctx->quant_matrix);
Diego Biurrune3fcb142014-01-24 10:55:16374 ctx->idsp.idct(ctx->block);
375 ctx->idsp.put_signed_pixels_clamped(ctx->block, C[blk],
376 ctx->frame->linesize[blk + 1]);
Kostya Shishkov1232a162013-05-16 05:21:08377 C[blk] += 8;
378 }
379 }
380
381 return 0;
382}
383
Andreas Rheinhardtce7dbd02022-03-30 19:33:24384static int aic_decode_frame(AVCodecContext *avctx, AVFrame *frame,
385 int *got_frame, AVPacket *avpkt)
Kostya Shishkov1232a162013-05-16 05:21:08386{
387 AICContext *ctx = avctx->priv_data;
388 const uint8_t *buf = avpkt->data;
389 int buf_size = avpkt->size;
390 GetByteContext gb;
391 uint32_t off;
392 int x, y, ret;
393 int slice_size;
Kostya Shishkov1232a162013-05-16 05:21:08394
Andreas Rheinhardtce7dbd02022-03-30 19:33:24395 ctx->frame = frame;
Kostya Shishkov1232a162013-05-16 05:21:08396
397 off = FFALIGN(AIC_HDR_SIZE + ctx->num_x_slices * ctx->mb_height * 2, 4);
398
399 if (buf_size < off) {
400 av_log(avctx, AV_LOG_ERROR, "Too small frame\n");
401 return AVERROR_INVALIDDATA;
402 }
403
Vittorio Giovarad8d124e2015-06-15 17:27:53404 ret = aic_decode_header(ctx, buf, buf_size);
405 if (ret < 0) {
406 av_log(avctx, AV_LOG_ERROR, "Invalid header\n");
Kostya Shishkov1232a162013-05-16 05:21:08407 return ret;
Vittorio Giovarad8d124e2015-06-15 17:27:53408 }
Kostya Shishkov1232a162013-05-16 05:21:08409
Andreas Rheinhardt02220b82022-02-06 13:49:23410 if ((ret = ff_thread_get_buffer(avctx, ctx->frame, 0)) < 0)
Kostya Shishkov1232a162013-05-16 05:21:08411 return ret;
412
413 bytestream2_init(&gb, buf + AIC_HDR_SIZE,
414 ctx->num_x_slices * ctx->mb_height * 2);
415
416 for (y = 0; y < ctx->mb_height; y++) {
417 for (x = 0; x < ctx->mb_width; x += ctx->slice_width) {
418 slice_size = bytestream2_get_le16(&gb) * 4;
419 if (slice_size + off > buf_size || !slice_size) {
Vittorio Giovarad8d124e2015-06-15 17:27:53420 av_log(avctx, AV_LOG_ERROR,
421 "Incorrect slice size %d at %d.%d\n", slice_size, x, y);
Kostya Shishkov1232a162013-05-16 05:21:08422 return AVERROR_INVALIDDATA;
423 }
424
Vittorio Giovarad8d124e2015-06-15 17:27:53425 ret = aic_decode_slice(ctx, x, y, buf + off, slice_size);
426 if (ret < 0) {
427 av_log(avctx, AV_LOG_ERROR,
428 "Error decoding slice at %d.%d\n", x, y);
Kostya Shishkov1232a162013-05-16 05:21:08429 return ret;
Vittorio Giovarad8d124e2015-06-15 17:27:53430 }
Kostya Shishkov1232a162013-05-16 05:21:08431
432 off += slice_size;
433 }
434 }
435
436 *got_frame = 1;
437
438 return avpkt->size;
439}
440
441static av_cold int aic_decode_init(AVCodecContext *avctx)
442{
443 AICContext *ctx = avctx->priv_data;
444 int i;
Kostya Shishkov1232a162013-05-16 05:21:08445
446 ctx->avctx = avctx;
447
448 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
449
Diego Biurrune3fcb142014-01-24 10:55:16450 ff_idctdsp_init(&ctx->idsp, avctx);
Kostya Shishkov1232a162013-05-16 05:21:08451
452 for (i = 0; i < 64; i++)
Michael Niedermayer581b5f02014-07-01 12:38:57453 ctx->quant_matrix[ctx->idsp.idct_permutation[i]] = aic_quant_matrix[i];
Kostya Shishkov1232a162013-05-16 05:21:08454
455 ctx->mb_width = FFALIGN(avctx->width, 16) >> 4;
456 ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
457
Vittorio Giovarae878ec02015-02-27 19:00:25458 ctx->num_x_slices = (ctx->mb_width + 15) >> 4;
459 ctx->slice_width = 16;
Paul B Maholfa3e4952017-02-24 10:29:42460 for (i = 1; i < ctx->mb_width; i++) {
Vittorio Giovara303ec062015-06-28 08:50:42461 if (!(ctx->mb_width % i) && (ctx->mb_width / i <= 32)) {
Kostya Shishkov1232a162013-05-16 05:21:08462 ctx->slice_width = ctx->mb_width / i;
463 ctx->num_x_slices = i;
464 break;
465 }
466 }
467
Michael Niedermayerde3f6c82024-08-04 20:30:03468 ctx->slice_data = av_calloc(ctx->slice_width, AIC_BAND_COEFFS * sizeof(*ctx->slice_data));
Kostya Shishkov1232a162013-05-16 05:21:08469 if (!ctx->slice_data) {
470 av_log(avctx, AV_LOG_ERROR, "Error allocating slice buffer\n");
471
472 return AVERROR(ENOMEM);
473 }
474
475 for (i = 0; i < NUM_BANDS; i++)
476 ctx->data_ptr[i] = ctx->slice_data + ctx->slice_width
477 * aic_band_off[i];
478
479 return 0;
480}
481
482static av_cold int aic_decode_close(AVCodecContext *avctx)
483{
484 AICContext *ctx = avctx->priv_data;
485
486 av_freep(&ctx->slice_data);
487
488 return 0;
489}
490
Andreas Rheinhardt20f97272022-03-16 20:09:54491const FFCodec ff_aic_decoder = {
492 .p.name = "aic",
Andreas Rheinhardt48286d42022-08-29 11:38:02493 CODEC_LONG_NAME("Apple Intermediate Codec"),
Andreas Rheinhardt20f97272022-03-16 20:09:54494 .p.type = AVMEDIA_TYPE_VIDEO,
495 .p.id = AV_CODEC_ID_AIC,
Kostya Shishkov1232a162013-05-16 05:21:08496 .priv_data_size = sizeof(AICContext),
497 .init = aic_decode_init,
498 .close = aic_decode_close,
Andreas Rheinhardt4243da42022-03-30 21:28:24499 FF_CODEC_DECODE_CB(aic_decode_frame),
Andreas Rheinhardt20f97272022-03-16 20:09:54500 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
Kostya Shishkov1232a162013-05-16 05:21:08501};