1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Interplay ACM decoder
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * Copyright (c) 2004-2008 Marko Kreen
5cabdff1aSopenharmony_ci * Copyright (c) 2008 Adam Gashlin
6cabdff1aSopenharmony_ci * Copyright (c) 2015 Paul B Mahol
7cabdff1aSopenharmony_ci *
8cabdff1aSopenharmony_ci * Permission to use, copy, modify, and distribute this software for any
9cabdff1aSopenharmony_ci * purpose with or without fee is hereby granted, provided that the above
10cabdff1aSopenharmony_ci * copyright notice and this permission notice appear in all copies.
11cabdff1aSopenharmony_ci *
12cabdff1aSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13cabdff1aSopenharmony_ci * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14cabdff1aSopenharmony_ci * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15cabdff1aSopenharmony_ci * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16cabdff1aSopenharmony_ci * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17cabdff1aSopenharmony_ci * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18cabdff1aSopenharmony_ci * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19cabdff1aSopenharmony_ci */
20cabdff1aSopenharmony_ci
21cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h"
22cabdff1aSopenharmony_ci#include "libavutil/thread.h"
23cabdff1aSopenharmony_ci
24cabdff1aSopenharmony_ci#define BITSTREAM_READER_LE
25cabdff1aSopenharmony_ci#include "avcodec.h"
26cabdff1aSopenharmony_ci#include "codec_internal.h"
27cabdff1aSopenharmony_ci#include "get_bits.h"
28cabdff1aSopenharmony_ci#include "internal.h"
29cabdff1aSopenharmony_ci
30cabdff1aSopenharmony_cistatic const int8_t map_1bit[]      = { -1, +1 };
31cabdff1aSopenharmony_cistatic const int8_t map_2bit_near[] = { -2, -1, +1, +2 };
32cabdff1aSopenharmony_cistatic const int8_t map_2bit_far[]  = { -3, -2, +2, +3 };
33cabdff1aSopenharmony_cistatic const int8_t map_3bit[]      = { -4, -3, -2, -1, +1, +2, +3, +4 };
34cabdff1aSopenharmony_ci
35cabdff1aSopenharmony_cistatic int mul_3x3 [3 * 3 * 3];
36cabdff1aSopenharmony_cistatic int mul_3x5 [5 * 5 * 5];
37cabdff1aSopenharmony_cistatic int mul_2x11[11  *  11];
38cabdff1aSopenharmony_ci
39cabdff1aSopenharmony_citypedef struct InterplayACMContext {
40cabdff1aSopenharmony_ci    GetBitContext gb;
41cabdff1aSopenharmony_ci    uint8_t *bitstream;
42cabdff1aSopenharmony_ci    int max_framesize;
43cabdff1aSopenharmony_ci    uint64_t max_samples;
44cabdff1aSopenharmony_ci    int bitstream_size;
45cabdff1aSopenharmony_ci    int bitstream_index;
46cabdff1aSopenharmony_ci
47cabdff1aSopenharmony_ci    int level;
48cabdff1aSopenharmony_ci    int rows;
49cabdff1aSopenharmony_ci    int cols;
50cabdff1aSopenharmony_ci    int wrapbuf_len;
51cabdff1aSopenharmony_ci    int block_len;
52cabdff1aSopenharmony_ci    int skip;
53cabdff1aSopenharmony_ci
54cabdff1aSopenharmony_ci    int *block;
55cabdff1aSopenharmony_ci    int *wrapbuf;
56cabdff1aSopenharmony_ci    int *ampbuf;
57cabdff1aSopenharmony_ci    int *midbuf;
58cabdff1aSopenharmony_ci} InterplayACMContext;
59cabdff1aSopenharmony_ci
60cabdff1aSopenharmony_cistatic av_cold void decode_init_static(void)
61cabdff1aSopenharmony_ci{
62cabdff1aSopenharmony_ci    for (int x3 = 0; x3 < 3; x3++)
63cabdff1aSopenharmony_ci        for (int x2 = 0; x2 < 3; x2++)
64cabdff1aSopenharmony_ci            for (int x1 = 0; x1 < 3; x1++)
65cabdff1aSopenharmony_ci                mul_3x3[x1 + x2 * 3 + x3 * 3 * 3] = x1 + (x2 << 4) + (x3 << 8);
66cabdff1aSopenharmony_ci    for (int x3 = 0; x3 < 5; x3++)
67cabdff1aSopenharmony_ci        for (int x2 = 0; x2 < 5; x2++)
68cabdff1aSopenharmony_ci            for (int x1 = 0; x1 < 5; x1++)
69cabdff1aSopenharmony_ci                mul_3x5[x1 + x2 * 5 + x3 * 5 * 5] = x1 + (x2 << 4) + (x3 << 8);
70cabdff1aSopenharmony_ci    for (int x2 = 0; x2 < 11; x2++)
71cabdff1aSopenharmony_ci        for (int x1 = 0; x1 < 11; x1++)
72cabdff1aSopenharmony_ci            mul_2x11[x1 + x2 * 11] = x1 + (x2 << 4);
73cabdff1aSopenharmony_ci}
74cabdff1aSopenharmony_ci
75cabdff1aSopenharmony_cistatic av_cold int decode_init(AVCodecContext *avctx)
76cabdff1aSopenharmony_ci{
77cabdff1aSopenharmony_ci    static AVOnce init_static_once = AV_ONCE_INIT;
78cabdff1aSopenharmony_ci    InterplayACMContext *s = avctx->priv_data;
79cabdff1aSopenharmony_ci
80cabdff1aSopenharmony_ci    if (avctx->extradata_size < 14)
81cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
82cabdff1aSopenharmony_ci
83cabdff1aSopenharmony_ci    if (avctx->ch_layout.nb_channels <= 0) {
84cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Invalid number of channels: %d\n", avctx->ch_layout.nb_channels);
85cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
86cabdff1aSopenharmony_ci    }
87cabdff1aSopenharmony_ci
88cabdff1aSopenharmony_ci    s->max_samples = AV_RL32(avctx->extradata + 4) / avctx->ch_layout.nb_channels;
89cabdff1aSopenharmony_ci    if (s->max_samples == 0)
90cabdff1aSopenharmony_ci        s->max_samples = UINT64_MAX;
91cabdff1aSopenharmony_ci    s->level = AV_RL16(avctx->extradata + 12) & 0xf;
92cabdff1aSopenharmony_ci    s->rows  = AV_RL16(avctx->extradata + 12) >>  4;
93cabdff1aSopenharmony_ci    s->cols  = 1 << s->level;
94cabdff1aSopenharmony_ci    s->wrapbuf_len = 2 * s->cols - 2;
95cabdff1aSopenharmony_ci    s->block_len = s->rows * s->cols;
96cabdff1aSopenharmony_ci    s->max_framesize = s->block_len;
97cabdff1aSopenharmony_ci
98cabdff1aSopenharmony_ci    s->block   = av_calloc(s->block_len, sizeof(int));
99cabdff1aSopenharmony_ci    s->wrapbuf = av_calloc(s->wrapbuf_len, sizeof(int));
100cabdff1aSopenharmony_ci    s->ampbuf  = av_calloc(0x10000, sizeof(int));
101cabdff1aSopenharmony_ci    s->bitstream = av_calloc(s->max_framesize + AV_INPUT_BUFFER_PADDING_SIZE / sizeof(*s->bitstream) + 1, sizeof(*s->bitstream));
102cabdff1aSopenharmony_ci    if (!s->block || !s->wrapbuf || !s->ampbuf || !s->bitstream)
103cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
104cabdff1aSopenharmony_ci
105cabdff1aSopenharmony_ci    s->midbuf  = s->ampbuf + 0x8000;
106cabdff1aSopenharmony_ci    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
107cabdff1aSopenharmony_ci
108cabdff1aSopenharmony_ci    ff_thread_once(&init_static_once, decode_init_static);
109cabdff1aSopenharmony_ci
110cabdff1aSopenharmony_ci    return 0;
111cabdff1aSopenharmony_ci}
112cabdff1aSopenharmony_ci
113cabdff1aSopenharmony_ci#define set_pos(s, r, c, idx) do {               \
114cabdff1aSopenharmony_ci        unsigned pos = ((r) << s->level) + (c);  \
115cabdff1aSopenharmony_ci        s->block[pos] = s->midbuf[(idx)];        \
116cabdff1aSopenharmony_ci    } while (0)
117cabdff1aSopenharmony_ci
118cabdff1aSopenharmony_cistatic int zero(InterplayACMContext *s, unsigned ind, unsigned col)
119cabdff1aSopenharmony_ci{
120cabdff1aSopenharmony_ci    unsigned i;
121cabdff1aSopenharmony_ci
122cabdff1aSopenharmony_ci    for (i = 0; i < s->rows; i++)
123cabdff1aSopenharmony_ci        set_pos(s, i, col, 0);
124cabdff1aSopenharmony_ci    return 0;
125cabdff1aSopenharmony_ci}
126cabdff1aSopenharmony_ci
127cabdff1aSopenharmony_cistatic int bad(InterplayACMContext *s, unsigned ind, unsigned col)
128cabdff1aSopenharmony_ci{
129cabdff1aSopenharmony_ci    return AVERROR_INVALIDDATA;
130cabdff1aSopenharmony_ci}
131cabdff1aSopenharmony_ci
132cabdff1aSopenharmony_cistatic int linear(InterplayACMContext *s, unsigned ind, unsigned col)
133cabdff1aSopenharmony_ci{
134cabdff1aSopenharmony_ci    GetBitContext *gb = &s->gb;
135cabdff1aSopenharmony_ci    unsigned int i;
136cabdff1aSopenharmony_ci    int b, middle = 1 << (ind - 1);
137cabdff1aSopenharmony_ci
138cabdff1aSopenharmony_ci    for (i = 0; i < s->rows; i++) {
139cabdff1aSopenharmony_ci        b = get_bits(gb, ind);
140cabdff1aSopenharmony_ci        set_pos(s, i, col, b - middle);
141cabdff1aSopenharmony_ci    }
142cabdff1aSopenharmony_ci    return 0;
143cabdff1aSopenharmony_ci}
144cabdff1aSopenharmony_ci
145cabdff1aSopenharmony_cistatic int k13(InterplayACMContext *s, unsigned ind, unsigned col)
146cabdff1aSopenharmony_ci{
147cabdff1aSopenharmony_ci    GetBitContext *gb = &s->gb;
148cabdff1aSopenharmony_ci    unsigned i, b;
149cabdff1aSopenharmony_ci
150cabdff1aSopenharmony_ci    for (i = 0; i < s->rows; i++) {
151cabdff1aSopenharmony_ci        b = get_bits1(gb);
152cabdff1aSopenharmony_ci        if (b == 0) {
153cabdff1aSopenharmony_ci            set_pos(s, i++, col, 0);
154cabdff1aSopenharmony_ci            if (i >= s->rows)
155cabdff1aSopenharmony_ci                break;
156cabdff1aSopenharmony_ci            set_pos(s, i, col, 0);
157cabdff1aSopenharmony_ci            continue;
158cabdff1aSopenharmony_ci        }
159cabdff1aSopenharmony_ci        b = get_bits1(gb);
160cabdff1aSopenharmony_ci        if (b == 0) {
161cabdff1aSopenharmony_ci            set_pos(s, i, col, 0);
162cabdff1aSopenharmony_ci            continue;
163cabdff1aSopenharmony_ci        }
164cabdff1aSopenharmony_ci        b = get_bits1(gb);
165cabdff1aSopenharmony_ci        set_pos(s, i, col, map_1bit[b]);
166cabdff1aSopenharmony_ci    }
167cabdff1aSopenharmony_ci    return 0;
168cabdff1aSopenharmony_ci}
169cabdff1aSopenharmony_ci
170cabdff1aSopenharmony_cistatic int k12(InterplayACMContext *s, unsigned ind, unsigned col)
171cabdff1aSopenharmony_ci{
172cabdff1aSopenharmony_ci    GetBitContext *gb = &s->gb;
173cabdff1aSopenharmony_ci    unsigned i, b;
174cabdff1aSopenharmony_ci
175cabdff1aSopenharmony_ci    for (i = 0; i < s->rows; i++) {
176cabdff1aSopenharmony_ci        b = get_bits1(gb);
177cabdff1aSopenharmony_ci        if (b == 0) {
178cabdff1aSopenharmony_ci            set_pos(s, i, col, 0);
179cabdff1aSopenharmony_ci            continue;
180cabdff1aSopenharmony_ci        }
181cabdff1aSopenharmony_ci
182cabdff1aSopenharmony_ci        b = get_bits1(gb);
183cabdff1aSopenharmony_ci        set_pos(s, i, col, map_1bit[b]);
184cabdff1aSopenharmony_ci    }
185cabdff1aSopenharmony_ci    return 0;
186cabdff1aSopenharmony_ci}
187cabdff1aSopenharmony_ci
188cabdff1aSopenharmony_cistatic int k24(InterplayACMContext *s, unsigned ind, unsigned col)
189cabdff1aSopenharmony_ci{
190cabdff1aSopenharmony_ci    GetBitContext *gb = &s->gb;
191cabdff1aSopenharmony_ci    unsigned i, b;
192cabdff1aSopenharmony_ci
193cabdff1aSopenharmony_ci    for (i = 0; i < s->rows; i++) {
194cabdff1aSopenharmony_ci        b = get_bits1(gb);
195cabdff1aSopenharmony_ci        if (b == 0) {
196cabdff1aSopenharmony_ci            set_pos(s, i++, col, 0);
197cabdff1aSopenharmony_ci            if (i >= s->rows) break;
198cabdff1aSopenharmony_ci            set_pos(s, i, col, 0);
199cabdff1aSopenharmony_ci            continue;
200cabdff1aSopenharmony_ci        }
201cabdff1aSopenharmony_ci
202cabdff1aSopenharmony_ci        b = get_bits1(gb);
203cabdff1aSopenharmony_ci        if (b == 0) {
204cabdff1aSopenharmony_ci            set_pos(s, i, col, 0);
205cabdff1aSopenharmony_ci            continue;
206cabdff1aSopenharmony_ci        }
207cabdff1aSopenharmony_ci
208cabdff1aSopenharmony_ci        b = get_bits(gb, 2);
209cabdff1aSopenharmony_ci        set_pos(s, i, col, map_2bit_near[b]);
210cabdff1aSopenharmony_ci    }
211cabdff1aSopenharmony_ci    return 0;
212cabdff1aSopenharmony_ci}
213cabdff1aSopenharmony_ci
214cabdff1aSopenharmony_cistatic int k23(InterplayACMContext *s, unsigned ind, unsigned col)
215cabdff1aSopenharmony_ci{
216cabdff1aSopenharmony_ci    GetBitContext *gb = &s->gb;
217cabdff1aSopenharmony_ci    unsigned i, b;
218cabdff1aSopenharmony_ci
219cabdff1aSopenharmony_ci    for (i = 0; i < s->rows; i++) {
220cabdff1aSopenharmony_ci        b = get_bits1(gb);
221cabdff1aSopenharmony_ci        if (b == 0) {
222cabdff1aSopenharmony_ci            set_pos(s, i, col, 0);
223cabdff1aSopenharmony_ci            continue;
224cabdff1aSopenharmony_ci        }
225cabdff1aSopenharmony_ci
226cabdff1aSopenharmony_ci        b = get_bits(gb, 2);
227cabdff1aSopenharmony_ci        set_pos(s, i, col, map_2bit_near[b]);
228cabdff1aSopenharmony_ci    }
229cabdff1aSopenharmony_ci    return 0;
230cabdff1aSopenharmony_ci}
231cabdff1aSopenharmony_ci
232cabdff1aSopenharmony_cistatic int k35(InterplayACMContext *s, unsigned ind, unsigned col)
233cabdff1aSopenharmony_ci{
234cabdff1aSopenharmony_ci    GetBitContext *gb = &s->gb;
235cabdff1aSopenharmony_ci    unsigned i, b;
236cabdff1aSopenharmony_ci
237cabdff1aSopenharmony_ci    for (i = 0; i < s->rows; i++) {
238cabdff1aSopenharmony_ci        b = get_bits1(gb);
239cabdff1aSopenharmony_ci        if (b == 0) {
240cabdff1aSopenharmony_ci            set_pos(s, i++, col, 0);
241cabdff1aSopenharmony_ci            if (i >= s->rows)
242cabdff1aSopenharmony_ci                break;
243cabdff1aSopenharmony_ci            set_pos(s, i, col, 0);
244cabdff1aSopenharmony_ci            continue;
245cabdff1aSopenharmony_ci        }
246cabdff1aSopenharmony_ci
247cabdff1aSopenharmony_ci        b = get_bits1(gb);
248cabdff1aSopenharmony_ci        if (b == 0) {
249cabdff1aSopenharmony_ci            set_pos(s, i, col, 0);
250cabdff1aSopenharmony_ci            continue;
251cabdff1aSopenharmony_ci        }
252cabdff1aSopenharmony_ci
253cabdff1aSopenharmony_ci        b = get_bits1(gb);
254cabdff1aSopenharmony_ci        if (b == 0) {
255cabdff1aSopenharmony_ci            b = get_bits1(gb);
256cabdff1aSopenharmony_ci            set_pos(s, i, col, map_1bit[b]);
257cabdff1aSopenharmony_ci            continue;
258cabdff1aSopenharmony_ci        }
259cabdff1aSopenharmony_ci
260cabdff1aSopenharmony_ci        b = get_bits(gb, 2);
261cabdff1aSopenharmony_ci        set_pos(s, i, col, map_2bit_far[b]);
262cabdff1aSopenharmony_ci    }
263cabdff1aSopenharmony_ci    return 0;
264cabdff1aSopenharmony_ci}
265cabdff1aSopenharmony_ci
266cabdff1aSopenharmony_cistatic int k34(InterplayACMContext *s, unsigned ind, unsigned col)
267cabdff1aSopenharmony_ci{
268cabdff1aSopenharmony_ci    GetBitContext *gb = &s->gb;
269cabdff1aSopenharmony_ci    unsigned i, b;
270cabdff1aSopenharmony_ci
271cabdff1aSopenharmony_ci    for (i = 0; i < s->rows; i++) {
272cabdff1aSopenharmony_ci        b = get_bits1(gb);
273cabdff1aSopenharmony_ci        if (b == 0) {
274cabdff1aSopenharmony_ci            set_pos(s, i, col, 0);
275cabdff1aSopenharmony_ci            continue;
276cabdff1aSopenharmony_ci        }
277cabdff1aSopenharmony_ci
278cabdff1aSopenharmony_ci        b = get_bits1(gb);
279cabdff1aSopenharmony_ci        if (b == 0) {
280cabdff1aSopenharmony_ci            b = get_bits1(gb);
281cabdff1aSopenharmony_ci            set_pos(s, i, col, map_1bit[b]);
282cabdff1aSopenharmony_ci            continue;
283cabdff1aSopenharmony_ci        }
284cabdff1aSopenharmony_ci
285cabdff1aSopenharmony_ci        b = get_bits(gb, 2);
286cabdff1aSopenharmony_ci        set_pos(s, i, col, map_2bit_far[b]);
287cabdff1aSopenharmony_ci    }
288cabdff1aSopenharmony_ci    return 0;
289cabdff1aSopenharmony_ci}
290cabdff1aSopenharmony_ci
291cabdff1aSopenharmony_cistatic int k45(InterplayACMContext *s, unsigned ind, unsigned col)
292cabdff1aSopenharmony_ci{
293cabdff1aSopenharmony_ci    GetBitContext *gb = &s->gb;
294cabdff1aSopenharmony_ci    unsigned i, b;
295cabdff1aSopenharmony_ci
296cabdff1aSopenharmony_ci    for (i = 0; i < s->rows; i++) {
297cabdff1aSopenharmony_ci        b = get_bits1(gb);
298cabdff1aSopenharmony_ci        if (b == 0) {
299cabdff1aSopenharmony_ci            set_pos(s, i, col, 0); i++;
300cabdff1aSopenharmony_ci            if (i >= s->rows)
301cabdff1aSopenharmony_ci                break;
302cabdff1aSopenharmony_ci            set_pos(s, i, col, 0);
303cabdff1aSopenharmony_ci            continue;
304cabdff1aSopenharmony_ci        }
305cabdff1aSopenharmony_ci
306cabdff1aSopenharmony_ci        b = get_bits1(gb);
307cabdff1aSopenharmony_ci        if (b == 0) {
308cabdff1aSopenharmony_ci            set_pos(s, i, col, 0);
309cabdff1aSopenharmony_ci            continue;
310cabdff1aSopenharmony_ci        }
311cabdff1aSopenharmony_ci
312cabdff1aSopenharmony_ci        b = get_bits(gb, 3);
313cabdff1aSopenharmony_ci        set_pos(s, i, col, map_3bit[b]);
314cabdff1aSopenharmony_ci    }
315cabdff1aSopenharmony_ci    return 0;
316cabdff1aSopenharmony_ci}
317cabdff1aSopenharmony_ci
318cabdff1aSopenharmony_cistatic int k44(InterplayACMContext *s, unsigned ind, unsigned col)
319cabdff1aSopenharmony_ci{
320cabdff1aSopenharmony_ci    GetBitContext *gb = &s->gb;
321cabdff1aSopenharmony_ci    unsigned i, b;
322cabdff1aSopenharmony_ci
323cabdff1aSopenharmony_ci    for (i = 0; i < s->rows; i++) {
324cabdff1aSopenharmony_ci        b = get_bits1(gb);
325cabdff1aSopenharmony_ci        if (b == 0) {
326cabdff1aSopenharmony_ci            set_pos(s, i, col, 0);
327cabdff1aSopenharmony_ci            continue;
328cabdff1aSopenharmony_ci        }
329cabdff1aSopenharmony_ci
330cabdff1aSopenharmony_ci        b = get_bits(gb, 3);
331cabdff1aSopenharmony_ci        set_pos(s, i, col, map_3bit[b]);
332cabdff1aSopenharmony_ci    }
333cabdff1aSopenharmony_ci    return 0;
334cabdff1aSopenharmony_ci}
335cabdff1aSopenharmony_ci
336cabdff1aSopenharmony_cistatic int t15(InterplayACMContext *s, unsigned ind, unsigned col)
337cabdff1aSopenharmony_ci{
338cabdff1aSopenharmony_ci    GetBitContext *gb = &s->gb;
339cabdff1aSopenharmony_ci    unsigned i, b;
340cabdff1aSopenharmony_ci    int n1, n2, n3;
341cabdff1aSopenharmony_ci
342cabdff1aSopenharmony_ci    for (i = 0; i < s->rows; i++) {
343cabdff1aSopenharmony_ci        /* b = (x1) + (x2 * 3) + (x3 * 9) */
344cabdff1aSopenharmony_ci        b = get_bits(gb, 5);
345cabdff1aSopenharmony_ci        if (b > 26) {
346cabdff1aSopenharmony_ci            av_log(NULL, AV_LOG_ERROR, "Too large b = %d > 26\n", b);
347cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
348cabdff1aSopenharmony_ci        }
349cabdff1aSopenharmony_ci
350cabdff1aSopenharmony_ci        n1 =  (mul_3x3[b] & 0x0F) - 1;
351cabdff1aSopenharmony_ci        n2 = ((mul_3x3[b] >> 4) & 0x0F) - 1;
352cabdff1aSopenharmony_ci        n3 = ((mul_3x3[b] >> 8) & 0x0F) - 1;
353cabdff1aSopenharmony_ci
354cabdff1aSopenharmony_ci        set_pos(s, i++, col, n1);
355cabdff1aSopenharmony_ci        if (i >= s->rows)
356cabdff1aSopenharmony_ci            break;
357cabdff1aSopenharmony_ci        set_pos(s, i++, col, n2);
358cabdff1aSopenharmony_ci        if (i >= s->rows)
359cabdff1aSopenharmony_ci            break;
360cabdff1aSopenharmony_ci        set_pos(s, i, col, n3);
361cabdff1aSopenharmony_ci    }
362cabdff1aSopenharmony_ci    return 0;
363cabdff1aSopenharmony_ci}
364cabdff1aSopenharmony_ci
365cabdff1aSopenharmony_cistatic int t27(InterplayACMContext *s, unsigned ind, unsigned col)
366cabdff1aSopenharmony_ci{
367cabdff1aSopenharmony_ci    GetBitContext *gb = &s->gb;
368cabdff1aSopenharmony_ci    unsigned i, b;
369cabdff1aSopenharmony_ci    int n1, n2, n3;
370cabdff1aSopenharmony_ci
371cabdff1aSopenharmony_ci    for (i = 0; i < s->rows; i++) {
372cabdff1aSopenharmony_ci        /* b = (x1) + (x2 * 5) + (x3 * 25) */
373cabdff1aSopenharmony_ci        b = get_bits(gb, 7);
374cabdff1aSopenharmony_ci        if (b > 124) {
375cabdff1aSopenharmony_ci            av_log(NULL, AV_LOG_ERROR, "Too large b = %d > 124\n", b);
376cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
377cabdff1aSopenharmony_ci        }
378cabdff1aSopenharmony_ci
379cabdff1aSopenharmony_ci        n1 =  (mul_3x5[b] & 0x0F) - 2;
380cabdff1aSopenharmony_ci        n2 = ((mul_3x5[b] >> 4) & 0x0F) - 2;
381cabdff1aSopenharmony_ci        n3 = ((mul_3x5[b] >> 8) & 0x0F) - 2;
382cabdff1aSopenharmony_ci
383cabdff1aSopenharmony_ci        set_pos(s, i++, col, n1);
384cabdff1aSopenharmony_ci        if (i >= s->rows)
385cabdff1aSopenharmony_ci            break;
386cabdff1aSopenharmony_ci        set_pos(s, i++, col, n2);
387cabdff1aSopenharmony_ci        if (i >= s->rows)
388cabdff1aSopenharmony_ci            break;
389cabdff1aSopenharmony_ci        set_pos(s, i, col, n3);
390cabdff1aSopenharmony_ci    }
391cabdff1aSopenharmony_ci    return 0;
392cabdff1aSopenharmony_ci}
393cabdff1aSopenharmony_ci
394cabdff1aSopenharmony_cistatic int t37(InterplayACMContext *s, unsigned ind, unsigned col)
395cabdff1aSopenharmony_ci{
396cabdff1aSopenharmony_ci    GetBitContext *gb = &s->gb;
397cabdff1aSopenharmony_ci    unsigned i, b;
398cabdff1aSopenharmony_ci    int n1, n2;
399cabdff1aSopenharmony_ci    for (i = 0; i < s->rows; i++) {
400cabdff1aSopenharmony_ci        /* b = (x1) + (x2 * 11) */
401cabdff1aSopenharmony_ci        b = get_bits(gb, 7);
402cabdff1aSopenharmony_ci        if (b > 120) {
403cabdff1aSopenharmony_ci            av_log(NULL, AV_LOG_ERROR, "Too large b = %d > 120\n", b);
404cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
405cabdff1aSopenharmony_ci        }
406cabdff1aSopenharmony_ci
407cabdff1aSopenharmony_ci        n1 =  (mul_2x11[b] & 0x0F) - 5;
408cabdff1aSopenharmony_ci        n2 = ((mul_2x11[b] >> 4) & 0x0F) - 5;
409cabdff1aSopenharmony_ci
410cabdff1aSopenharmony_ci        set_pos(s, i++, col, n1);
411cabdff1aSopenharmony_ci        if (i >= s->rows)
412cabdff1aSopenharmony_ci            break;
413cabdff1aSopenharmony_ci        set_pos(s, i, col, n2);
414cabdff1aSopenharmony_ci    }
415cabdff1aSopenharmony_ci    return 0;
416cabdff1aSopenharmony_ci}
417cabdff1aSopenharmony_ci
418cabdff1aSopenharmony_citypedef int (*filler)(InterplayACMContext *s, unsigned ind, unsigned col);
419cabdff1aSopenharmony_ci
420cabdff1aSopenharmony_cistatic const filler filler_list[] = {
421cabdff1aSopenharmony_ci    zero,   bad,    bad,    linear,
422cabdff1aSopenharmony_ci    linear, linear, linear, linear,
423cabdff1aSopenharmony_ci    linear, linear, linear, linear,
424cabdff1aSopenharmony_ci    linear, linear, linear, linear,
425cabdff1aSopenharmony_ci    linear, k13,    k12,    t15,
426cabdff1aSopenharmony_ci    k24,    k23,    t27,    k35,
427cabdff1aSopenharmony_ci    k34,    bad,    k45,    k44,
428cabdff1aSopenharmony_ci    bad,    t37,    bad,    bad,
429cabdff1aSopenharmony_ci};
430cabdff1aSopenharmony_ci
431cabdff1aSopenharmony_cistatic int fill_block(InterplayACMContext *s)
432cabdff1aSopenharmony_ci{
433cabdff1aSopenharmony_ci    GetBitContext *gb = &s->gb;
434cabdff1aSopenharmony_ci    unsigned i, ind;
435cabdff1aSopenharmony_ci    int ret;
436cabdff1aSopenharmony_ci
437cabdff1aSopenharmony_ci    for (i = 0; i < s->cols; i++) {
438cabdff1aSopenharmony_ci        ind = get_bits(gb, 5);
439cabdff1aSopenharmony_ci        ret = filler_list[ind](s, ind, i);
440cabdff1aSopenharmony_ci        if (ret < 0)
441cabdff1aSopenharmony_ci            return ret;
442cabdff1aSopenharmony_ci    }
443cabdff1aSopenharmony_ci    return 0;
444cabdff1aSopenharmony_ci}
445cabdff1aSopenharmony_ci
446cabdff1aSopenharmony_cistatic void juggle(int *wrap_p, int *block_p, unsigned sub_len, unsigned sub_count)
447cabdff1aSopenharmony_ci{
448cabdff1aSopenharmony_ci    unsigned i, j;
449cabdff1aSopenharmony_ci    int *p;
450cabdff1aSopenharmony_ci    unsigned int r0, r1, r2, r3;
451cabdff1aSopenharmony_ci
452cabdff1aSopenharmony_ci    for (i = 0; i < sub_len; i++) {
453cabdff1aSopenharmony_ci        p = block_p;
454cabdff1aSopenharmony_ci        r0 = wrap_p[0];
455cabdff1aSopenharmony_ci        r1 = wrap_p[1];
456cabdff1aSopenharmony_ci        for (j = 0; j < sub_count/2; j++) {
457cabdff1aSopenharmony_ci            r2 = *p;
458cabdff1aSopenharmony_ci            *p = r1 * 2 + (r0 + r2);
459cabdff1aSopenharmony_ci            p += sub_len;
460cabdff1aSopenharmony_ci            r3 = *p;
461cabdff1aSopenharmony_ci            *p = r2 * 2 - (r1 + r3);
462cabdff1aSopenharmony_ci            p += sub_len;
463cabdff1aSopenharmony_ci            r0 = r2;
464cabdff1aSopenharmony_ci            r1 = r3;
465cabdff1aSopenharmony_ci        }
466cabdff1aSopenharmony_ci
467cabdff1aSopenharmony_ci        *wrap_p++ = r0;
468cabdff1aSopenharmony_ci        *wrap_p++ = r1;
469cabdff1aSopenharmony_ci        block_p++;
470cabdff1aSopenharmony_ci    }
471cabdff1aSopenharmony_ci}
472cabdff1aSopenharmony_ci
473cabdff1aSopenharmony_cistatic void juggle_block(InterplayACMContext *s)
474cabdff1aSopenharmony_ci{
475cabdff1aSopenharmony_ci    unsigned sub_count, sub_len, todo_count, step_subcount, i;
476cabdff1aSopenharmony_ci    int *wrap_p, *block_p, *p;
477cabdff1aSopenharmony_ci
478cabdff1aSopenharmony_ci    /* juggle only if subblock_len > 1 */
479cabdff1aSopenharmony_ci    if (s->level == 0)
480cabdff1aSopenharmony_ci        return;
481cabdff1aSopenharmony_ci
482cabdff1aSopenharmony_ci    /* 2048 / subblock_len */
483cabdff1aSopenharmony_ci    if (s->level > 9)
484cabdff1aSopenharmony_ci        step_subcount = 1;
485cabdff1aSopenharmony_ci    else
486cabdff1aSopenharmony_ci        step_subcount = (2048 >> s->level) - 2;
487cabdff1aSopenharmony_ci
488cabdff1aSopenharmony_ci    /* Apply juggle()  (rows)x(cols)
489cabdff1aSopenharmony_ci     * from (step_subcount * 2)            x (subblock_len/2)
490cabdff1aSopenharmony_ci     * to   (step_subcount * subblock_len) x (1)
491cabdff1aSopenharmony_ci     */
492cabdff1aSopenharmony_ci    todo_count = s->rows;
493cabdff1aSopenharmony_ci    block_p = s->block;
494cabdff1aSopenharmony_ci    while (1) {
495cabdff1aSopenharmony_ci        wrap_p = s->wrapbuf;
496cabdff1aSopenharmony_ci        sub_count = step_subcount;
497cabdff1aSopenharmony_ci        if (sub_count > todo_count)
498cabdff1aSopenharmony_ci            sub_count = todo_count;
499cabdff1aSopenharmony_ci
500cabdff1aSopenharmony_ci        sub_len = s->cols / 2;
501cabdff1aSopenharmony_ci        sub_count *= 2;
502cabdff1aSopenharmony_ci
503cabdff1aSopenharmony_ci        juggle(wrap_p, block_p, sub_len, sub_count);
504cabdff1aSopenharmony_ci        wrap_p += sub_len * 2;
505cabdff1aSopenharmony_ci
506cabdff1aSopenharmony_ci        for (i = 0, p = block_p; i < sub_count; i++) {
507cabdff1aSopenharmony_ci            p[0]++;
508cabdff1aSopenharmony_ci            p += sub_len;
509cabdff1aSopenharmony_ci        }
510cabdff1aSopenharmony_ci
511cabdff1aSopenharmony_ci        while (sub_len > 1) {
512cabdff1aSopenharmony_ci            sub_len /= 2;
513cabdff1aSopenharmony_ci            sub_count *= 2;
514cabdff1aSopenharmony_ci            juggle(wrap_p, block_p, sub_len, sub_count);
515cabdff1aSopenharmony_ci            wrap_p += sub_len * 2;
516cabdff1aSopenharmony_ci        }
517cabdff1aSopenharmony_ci
518cabdff1aSopenharmony_ci        if (todo_count <= step_subcount)
519cabdff1aSopenharmony_ci            break;
520cabdff1aSopenharmony_ci
521cabdff1aSopenharmony_ci        todo_count -= step_subcount;
522cabdff1aSopenharmony_ci        block_p += step_subcount << s->level;
523cabdff1aSopenharmony_ci    }
524cabdff1aSopenharmony_ci}
525cabdff1aSopenharmony_ci
526cabdff1aSopenharmony_cistatic int decode_block(InterplayACMContext *s)
527cabdff1aSopenharmony_ci{
528cabdff1aSopenharmony_ci    GetBitContext *gb = &s->gb;
529cabdff1aSopenharmony_ci    int pwr, count, val, i, x, ret;
530cabdff1aSopenharmony_ci
531cabdff1aSopenharmony_ci    pwr = get_bits(gb, 4);
532cabdff1aSopenharmony_ci    val = get_bits(gb, 16);
533cabdff1aSopenharmony_ci
534cabdff1aSopenharmony_ci    count = 1 << pwr;
535cabdff1aSopenharmony_ci
536cabdff1aSopenharmony_ci    for (i = 0, x = 0; i < count; i++) {
537cabdff1aSopenharmony_ci        s->midbuf[i] = x;
538cabdff1aSopenharmony_ci        x += val;
539cabdff1aSopenharmony_ci    }
540cabdff1aSopenharmony_ci
541cabdff1aSopenharmony_ci    for (i = 1, x = -val; i <= count; i++) {
542cabdff1aSopenharmony_ci        s->midbuf[-i] = x;
543cabdff1aSopenharmony_ci        x -= (unsigned)val;
544cabdff1aSopenharmony_ci    }
545cabdff1aSopenharmony_ci
546cabdff1aSopenharmony_ci    ret = fill_block(s);
547cabdff1aSopenharmony_ci    if (ret < 0)
548cabdff1aSopenharmony_ci        return ret;
549cabdff1aSopenharmony_ci
550cabdff1aSopenharmony_ci    juggle_block(s);
551cabdff1aSopenharmony_ci
552cabdff1aSopenharmony_ci    return 0;
553cabdff1aSopenharmony_ci}
554cabdff1aSopenharmony_ci
555cabdff1aSopenharmony_cistatic int decode_frame(AVCodecContext *avctx, AVFrame *frame,
556cabdff1aSopenharmony_ci                        int *got_frame_ptr, AVPacket *pkt)
557cabdff1aSopenharmony_ci{
558cabdff1aSopenharmony_ci    InterplayACMContext *s = avctx->priv_data;
559cabdff1aSopenharmony_ci    GetBitContext *gb = &s->gb;
560cabdff1aSopenharmony_ci    const uint8_t *buf;
561cabdff1aSopenharmony_ci    int16_t *samples;
562cabdff1aSopenharmony_ci    int ret, n, buf_size, input_buf_size;
563cabdff1aSopenharmony_ci
564cabdff1aSopenharmony_ci    if (!pkt->size && !s->bitstream_size) {
565cabdff1aSopenharmony_ci        *got_frame_ptr = 0;
566cabdff1aSopenharmony_ci        return 0;
567cabdff1aSopenharmony_ci    }
568cabdff1aSopenharmony_ci
569cabdff1aSopenharmony_ci    buf_size = FFMIN(pkt->size, s->max_framesize - s->bitstream_size);
570cabdff1aSopenharmony_ci    input_buf_size = buf_size;
571cabdff1aSopenharmony_ci    if (s->bitstream_index + s->bitstream_size + buf_size > s->max_framesize) {
572cabdff1aSopenharmony_ci        memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size);
573cabdff1aSopenharmony_ci        s->bitstream_index = 0;
574cabdff1aSopenharmony_ci    }
575cabdff1aSopenharmony_ci    if (pkt->data)
576cabdff1aSopenharmony_ci        memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], pkt->data, buf_size);
577cabdff1aSopenharmony_ci    buf                = &s->bitstream[s->bitstream_index];
578cabdff1aSopenharmony_ci    buf_size          += s->bitstream_size;
579cabdff1aSopenharmony_ci    s->bitstream_size  = buf_size;
580cabdff1aSopenharmony_ci    if (buf_size < s->max_framesize && pkt->data) {
581cabdff1aSopenharmony_ci        *got_frame_ptr = 0;
582cabdff1aSopenharmony_ci        return input_buf_size;
583cabdff1aSopenharmony_ci    }
584cabdff1aSopenharmony_ci
585cabdff1aSopenharmony_ci    if ((ret = init_get_bits8(gb, buf, buf_size)) < 0)
586cabdff1aSopenharmony_ci        return ret;
587cabdff1aSopenharmony_ci
588cabdff1aSopenharmony_ci    frame->nb_samples = FFMIN(s->block_len / avctx->ch_layout.nb_channels, s->max_samples);
589cabdff1aSopenharmony_ci    s->max_samples -= FFMIN(frame->nb_samples, s->max_samples);
590cabdff1aSopenharmony_ci    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
591cabdff1aSopenharmony_ci        return ret;
592cabdff1aSopenharmony_ci
593cabdff1aSopenharmony_ci    skip_bits(gb, s->skip);
594cabdff1aSopenharmony_ci    ret = decode_block(s);
595cabdff1aSopenharmony_ci    if (ret < 0)
596cabdff1aSopenharmony_ci        return ret;
597cabdff1aSopenharmony_ci
598cabdff1aSopenharmony_ci    samples = (int16_t *)frame->data[0];
599cabdff1aSopenharmony_ci    for (n = 0; n < frame->nb_samples * avctx->ch_layout.nb_channels; n++) {
600cabdff1aSopenharmony_ci        int val = s->block[n] >> s->level;
601cabdff1aSopenharmony_ci        *samples++ = val;
602cabdff1aSopenharmony_ci    }
603cabdff1aSopenharmony_ci
604cabdff1aSopenharmony_ci    *got_frame_ptr = 1;
605cabdff1aSopenharmony_ci    s->skip = get_bits_count(gb) - 8 * (get_bits_count(gb) / 8);
606cabdff1aSopenharmony_ci    n = get_bits_count(gb) / 8;
607cabdff1aSopenharmony_ci
608cabdff1aSopenharmony_ci    if (n > buf_size && pkt->data) {
609cabdff1aSopenharmony_ci        s->bitstream_size = 0;
610cabdff1aSopenharmony_ci        s->bitstream_index = 0;
611cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
612cabdff1aSopenharmony_ci    }
613cabdff1aSopenharmony_ci
614cabdff1aSopenharmony_ci    if (s->bitstream_size > 0) {
615cabdff1aSopenharmony_ci        s->bitstream_index += n;
616cabdff1aSopenharmony_ci        s->bitstream_size  -= FFMIN(s->bitstream_size, n);
617cabdff1aSopenharmony_ci        return input_buf_size;
618cabdff1aSopenharmony_ci    }
619cabdff1aSopenharmony_ci    return n;
620cabdff1aSopenharmony_ci}
621cabdff1aSopenharmony_ci
622cabdff1aSopenharmony_cistatic av_cold int decode_close(AVCodecContext *avctx)
623cabdff1aSopenharmony_ci{
624cabdff1aSopenharmony_ci    InterplayACMContext *s = avctx->priv_data;
625cabdff1aSopenharmony_ci
626cabdff1aSopenharmony_ci    av_freep(&s->block);
627cabdff1aSopenharmony_ci    av_freep(&s->wrapbuf);
628cabdff1aSopenharmony_ci    av_freep(&s->ampbuf);
629cabdff1aSopenharmony_ci    av_freep(&s->bitstream);
630cabdff1aSopenharmony_ci    s->bitstream_size = 0;
631cabdff1aSopenharmony_ci
632cabdff1aSopenharmony_ci    return 0;
633cabdff1aSopenharmony_ci}
634cabdff1aSopenharmony_ci
635cabdff1aSopenharmony_ciconst FFCodec ff_interplay_acm_decoder = {
636cabdff1aSopenharmony_ci    .p.name         = "interplayacm",
637cabdff1aSopenharmony_ci    .p.long_name    = NULL_IF_CONFIG_SMALL("Interplay ACM"),
638cabdff1aSopenharmony_ci    .p.type         = AVMEDIA_TYPE_AUDIO,
639cabdff1aSopenharmony_ci    .p.id           = AV_CODEC_ID_INTERPLAY_ACM,
640cabdff1aSopenharmony_ci    .init           = decode_init,
641cabdff1aSopenharmony_ci    .close          = decode_close,
642cabdff1aSopenharmony_ci    FF_CODEC_DECODE_CB(decode_frame),
643cabdff1aSopenharmony_ci    .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1,
644cabdff1aSopenharmony_ci    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
645cabdff1aSopenharmony_ci    .priv_data_size = sizeof(InterplayACMContext),
646cabdff1aSopenharmony_ci};
647