1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Smacker decoder
3cabdff1aSopenharmony_ci * Copyright (c) 2006 Konstantin Shishkov
4cabdff1aSopenharmony_ci *
5cabdff1aSopenharmony_ci * This file is part of FFmpeg.
6cabdff1aSopenharmony_ci *
7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
11cabdff1aSopenharmony_ci *
12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15cabdff1aSopenharmony_ci * Lesser General Public License for more details.
16cabdff1aSopenharmony_ci *
17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20cabdff1aSopenharmony_ci */
21cabdff1aSopenharmony_ci
22cabdff1aSopenharmony_ci/**
23cabdff1aSopenharmony_ci * @file
24cabdff1aSopenharmony_ci * Smacker decoder
25cabdff1aSopenharmony_ci */
26cabdff1aSopenharmony_ci
27cabdff1aSopenharmony_ci/*
28cabdff1aSopenharmony_ci * Based on http://wiki.multimedia.cx/index.php?title=Smacker
29cabdff1aSopenharmony_ci */
30cabdff1aSopenharmony_ci
31cabdff1aSopenharmony_ci#include <stdio.h>
32cabdff1aSopenharmony_ci#include <stdlib.h>
33cabdff1aSopenharmony_ci
34cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h"
35cabdff1aSopenharmony_ci
36cabdff1aSopenharmony_ci#include "avcodec.h"
37cabdff1aSopenharmony_ci
38cabdff1aSopenharmony_ci#define SMKTREE_BITS 9
39cabdff1aSopenharmony_ci#define SMK_NODE 0x80000000
40cabdff1aSopenharmony_ci
41cabdff1aSopenharmony_ci#define SMKTREE_DECODE_MAX_RECURSION FFMIN(32, 3 * SMKTREE_BITS)
42cabdff1aSopenharmony_ci#define SMKTREE_DECODE_BIG_MAX_RECURSION 500
43cabdff1aSopenharmony_ci
44cabdff1aSopenharmony_ci/* The maximum possible unchecked overread happens in decode_header_trees:
45cabdff1aSopenharmony_ci * Decoding the MMAP tree can overread by 6 * SMKTREE_BITS + 1, followed by
46cabdff1aSopenharmony_ci * three get_bits1, followed by at most 2 + 3 * 16 read bits when reading
47cabdff1aSopenharmony_ci * the TYPE tree before the next check. 64 is because of 64 bit reads. */
48cabdff1aSopenharmony_ci#if (6 * SMKTREE_BITS + 1 + 3 + (2 + 3 * 16) + 64) <= 8 * AV_INPUT_BUFFER_PADDING_SIZE
49cabdff1aSopenharmony_ci#define UNCHECKED_BITSTREAM_READER 1
50cabdff1aSopenharmony_ci#endif
51cabdff1aSopenharmony_ci#define BITSTREAM_READER_LE
52cabdff1aSopenharmony_ci#include "bytestream.h"
53cabdff1aSopenharmony_ci#include "codec_internal.h"
54cabdff1aSopenharmony_ci#include "get_bits.h"
55cabdff1aSopenharmony_ci#include "internal.h"
56cabdff1aSopenharmony_ci#include "mathops.h"
57cabdff1aSopenharmony_ci
58cabdff1aSopenharmony_citypedef struct SmackVContext {
59cabdff1aSopenharmony_ci    AVCodecContext *avctx;
60cabdff1aSopenharmony_ci    AVFrame *pic;
61cabdff1aSopenharmony_ci
62cabdff1aSopenharmony_ci    int *mmap_tbl, *mclr_tbl, *full_tbl, *type_tbl;
63cabdff1aSopenharmony_ci    int mmap_last[3], mclr_last[3], full_last[3], type_last[3];
64cabdff1aSopenharmony_ci} SmackVContext;
65cabdff1aSopenharmony_ci
66cabdff1aSopenharmony_citypedef struct HuffEntry {
67cabdff1aSopenharmony_ci    uint8_t value;
68cabdff1aSopenharmony_ci    uint8_t length;
69cabdff1aSopenharmony_ci} HuffEntry;
70cabdff1aSopenharmony_ci
71cabdff1aSopenharmony_ci/**
72cabdff1aSopenharmony_ci * Context used for code reconstructing
73cabdff1aSopenharmony_ci */
74cabdff1aSopenharmony_citypedef struct HuffContext {
75cabdff1aSopenharmony_ci    int current;
76cabdff1aSopenharmony_ci    HuffEntry entries[256];
77cabdff1aSopenharmony_ci} HuffContext;
78cabdff1aSopenharmony_ci
79cabdff1aSopenharmony_ci/* common parameters used for decode_bigtree */
80cabdff1aSopenharmony_citypedef struct DBCtx {
81cabdff1aSopenharmony_ci    int current, length;
82cabdff1aSopenharmony_ci    int *values;
83cabdff1aSopenharmony_ci    VLC *v1, *v2;
84cabdff1aSopenharmony_ci    uint8_t vals[2];
85cabdff1aSopenharmony_ci    int escapes[3];
86cabdff1aSopenharmony_ci    int *last;
87cabdff1aSopenharmony_ci} DBCtx;
88cabdff1aSopenharmony_ci
89cabdff1aSopenharmony_ci/* possible runs of blocks */
90cabdff1aSopenharmony_cistatic const int block_runs[64] = {
91cabdff1aSopenharmony_ci      1,    2,    3,    4,    5,    6,    7,    8,
92cabdff1aSopenharmony_ci      9,   10,   11,   12,   13,   14,   15,   16,
93cabdff1aSopenharmony_ci     17,   18,   19,   20,   21,   22,   23,   24,
94cabdff1aSopenharmony_ci     25,   26,   27,   28,   29,   30,   31,   32,
95cabdff1aSopenharmony_ci     33,   34,   35,   36,   37,   38,   39,   40,
96cabdff1aSopenharmony_ci     41,   42,   43,   44,   45,   46,   47,   48,
97cabdff1aSopenharmony_ci     49,   50,   51,   52,   53,   54,   55,   56,
98cabdff1aSopenharmony_ci     57,   58,   59,  128,  256,  512, 1024, 2048 };
99cabdff1aSopenharmony_ci
100cabdff1aSopenharmony_cienum SmkBlockTypes {
101cabdff1aSopenharmony_ci    SMK_BLK_MONO = 0,
102cabdff1aSopenharmony_ci    SMK_BLK_FULL = 1,
103cabdff1aSopenharmony_ci    SMK_BLK_SKIP = 2,
104cabdff1aSopenharmony_ci    SMK_BLK_FILL = 3 };
105cabdff1aSopenharmony_ci
106cabdff1aSopenharmony_ci/**
107cabdff1aSopenharmony_ci * Decode local frame tree
108cabdff1aSopenharmony_ci *
109cabdff1aSopenharmony_ci * Can read SMKTREE_DECODE_MAX_RECURSION before the first check;
110cabdff1aSopenharmony_ci * does not overread gb on success.
111cabdff1aSopenharmony_ci */
112cabdff1aSopenharmony_cistatic int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, int length)
113cabdff1aSopenharmony_ci{
114cabdff1aSopenharmony_ci    if (length > SMKTREE_DECODE_MAX_RECURSION || length > 3 * SMKTREE_BITS) {
115cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "Maximum tree recursion level exceeded.\n");
116cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
117cabdff1aSopenharmony_ci    }
118cabdff1aSopenharmony_ci
119cabdff1aSopenharmony_ci    if(!get_bits1(gb)){ //Leaf
120cabdff1aSopenharmony_ci        if (hc->current >= 256) {
121cabdff1aSopenharmony_ci            av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n");
122cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
123cabdff1aSopenharmony_ci        }
124cabdff1aSopenharmony_ci        if (get_bits_left(gb) < 8)
125cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
126cabdff1aSopenharmony_ci        hc->entries[hc->current++] = (HuffEntry){ get_bits(gb, 8), length };
127cabdff1aSopenharmony_ci        return 0;
128cabdff1aSopenharmony_ci    } else { //Node
129cabdff1aSopenharmony_ci        int r;
130cabdff1aSopenharmony_ci        length++;
131cabdff1aSopenharmony_ci        r = smacker_decode_tree(gb, hc, length);
132cabdff1aSopenharmony_ci        if(r)
133cabdff1aSopenharmony_ci            return r;
134cabdff1aSopenharmony_ci        return smacker_decode_tree(gb, hc, length);
135cabdff1aSopenharmony_ci    }
136cabdff1aSopenharmony_ci}
137cabdff1aSopenharmony_ci
138cabdff1aSopenharmony_ci/**
139cabdff1aSopenharmony_ci * Decode header tree
140cabdff1aSopenharmony_ci *
141cabdff1aSopenharmony_ci * Checks before the first read, can overread by 6 * SMKTREE_BITS on success.
142cabdff1aSopenharmony_ci */
143cabdff1aSopenharmony_cistatic int smacker_decode_bigtree(GetBitContext *gb, DBCtx *ctx, int length)
144cabdff1aSopenharmony_ci{
145cabdff1aSopenharmony_ci    // Larger length can cause segmentation faults due to too deep recursion.
146cabdff1aSopenharmony_ci    if (length > SMKTREE_DECODE_BIG_MAX_RECURSION) {
147cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "Maximum bigtree recursion level exceeded.\n");
148cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
149cabdff1aSopenharmony_ci    }
150cabdff1aSopenharmony_ci
151cabdff1aSopenharmony_ci    if (ctx->current >= ctx->length) {
152cabdff1aSopenharmony_ci        av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n");
153cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
154cabdff1aSopenharmony_ci    }
155cabdff1aSopenharmony_ci    if (get_bits_left(gb) <= 0)
156cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
157cabdff1aSopenharmony_ci    if(!get_bits1(gb)){ //Leaf
158cabdff1aSopenharmony_ci        int val, i1, i2;
159cabdff1aSopenharmony_ci        i1 = ctx->v1->table ? get_vlc2(gb, ctx->v1->table, SMKTREE_BITS, 3)
160cabdff1aSopenharmony_ci                            : ctx->vals[0];
161cabdff1aSopenharmony_ci        i2 = ctx->v2->table ? get_vlc2(gb, ctx->v2->table, SMKTREE_BITS, 3)
162cabdff1aSopenharmony_ci                            : ctx->vals[1];
163cabdff1aSopenharmony_ci        val = i1 | (i2 << 8);
164cabdff1aSopenharmony_ci        if(val == ctx->escapes[0]) {
165cabdff1aSopenharmony_ci            ctx->last[0] = ctx->current;
166cabdff1aSopenharmony_ci            val = 0;
167cabdff1aSopenharmony_ci        } else if(val == ctx->escapes[1]) {
168cabdff1aSopenharmony_ci            ctx->last[1] = ctx->current;
169cabdff1aSopenharmony_ci            val = 0;
170cabdff1aSopenharmony_ci        } else if(val == ctx->escapes[2]) {
171cabdff1aSopenharmony_ci            ctx->last[2] = ctx->current;
172cabdff1aSopenharmony_ci            val = 0;
173cabdff1aSopenharmony_ci        }
174cabdff1aSopenharmony_ci
175cabdff1aSopenharmony_ci        ctx->values[ctx->current++] = val;
176cabdff1aSopenharmony_ci        return 1;
177cabdff1aSopenharmony_ci    } else { //Node
178cabdff1aSopenharmony_ci        int r = 0, r_new, t;
179cabdff1aSopenharmony_ci
180cabdff1aSopenharmony_ci        t = ctx->current++;
181cabdff1aSopenharmony_ci        r = smacker_decode_bigtree(gb, ctx, length + 1);
182cabdff1aSopenharmony_ci        if(r < 0)
183cabdff1aSopenharmony_ci            return r;
184cabdff1aSopenharmony_ci        ctx->values[t] = SMK_NODE | r;
185cabdff1aSopenharmony_ci        r++;
186cabdff1aSopenharmony_ci        r_new = smacker_decode_bigtree(gb, ctx, length + 1);
187cabdff1aSopenharmony_ci        if (r_new < 0)
188cabdff1aSopenharmony_ci            return r_new;
189cabdff1aSopenharmony_ci        return r + r_new;
190cabdff1aSopenharmony_ci    }
191cabdff1aSopenharmony_ci}
192cabdff1aSopenharmony_ci
193cabdff1aSopenharmony_ci/**
194cabdff1aSopenharmony_ci * Store large tree as FFmpeg's vlc codes
195cabdff1aSopenharmony_ci *
196cabdff1aSopenharmony_ci * Can read FFMAX(1 + SMKTREE_DECODE_MAX_RECURSION, 2 + 3 * 16) bits
197cabdff1aSopenharmony_ci * before the first check; can overread by 6 * SMKTREE_BITS + 1 on success.
198cabdff1aSopenharmony_ci */
199cabdff1aSopenharmony_cistatic int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int **recodes, int *last, int size)
200cabdff1aSopenharmony_ci{
201cabdff1aSopenharmony_ci    VLC vlc[2] = { { 0 } };
202cabdff1aSopenharmony_ci    int escapes[3];
203cabdff1aSopenharmony_ci    DBCtx ctx;
204cabdff1aSopenharmony_ci    int err;
205cabdff1aSopenharmony_ci
206cabdff1aSopenharmony_ci    if(size >= UINT_MAX>>4){ // (((size + 3) >> 2) + 3) << 2 must not overflow
207cabdff1aSopenharmony_ci        av_log(smk->avctx, AV_LOG_ERROR, "size too large\n");
208cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
209cabdff1aSopenharmony_ci    }
210cabdff1aSopenharmony_ci
211cabdff1aSopenharmony_ci    for (int i = 0; i < 2; i++) {
212cabdff1aSopenharmony_ci        HuffContext h;
213cabdff1aSopenharmony_ci        h.current = 0;
214cabdff1aSopenharmony_ci        if (!get_bits1(gb)) {
215cabdff1aSopenharmony_ci            ctx.vals[i] = 0;
216cabdff1aSopenharmony_ci            av_log(smk->avctx, AV_LOG_ERROR, "Skipping %s bytes tree\n",
217cabdff1aSopenharmony_ci                   i ? "high" : "low");
218cabdff1aSopenharmony_ci            continue;
219cabdff1aSopenharmony_ci        }
220cabdff1aSopenharmony_ci        err = smacker_decode_tree(gb, &h, 0);
221cabdff1aSopenharmony_ci        if (err < 0)
222cabdff1aSopenharmony_ci            goto error;
223cabdff1aSopenharmony_ci        skip_bits1(gb);
224cabdff1aSopenharmony_ci        if (h.current > 1) {
225cabdff1aSopenharmony_ci            err = ff_init_vlc_from_lengths(&vlc[i], SMKTREE_BITS, h.current,
226cabdff1aSopenharmony_ci                                           &h.entries[0].length, sizeof(*h.entries),
227cabdff1aSopenharmony_ci                                           &h.entries[0].value,  sizeof(*h.entries), 1,
228cabdff1aSopenharmony_ci                                           0, INIT_VLC_OUTPUT_LE, smk->avctx);
229cabdff1aSopenharmony_ci            if (err < 0) {
230cabdff1aSopenharmony_ci                av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
231cabdff1aSopenharmony_ci                goto error;
232cabdff1aSopenharmony_ci            }
233cabdff1aSopenharmony_ci        } else
234cabdff1aSopenharmony_ci            ctx.vals[i] = h.entries[0].value;
235cabdff1aSopenharmony_ci    }
236cabdff1aSopenharmony_ci
237cabdff1aSopenharmony_ci    escapes[0]  = get_bits(gb, 16);
238cabdff1aSopenharmony_ci    escapes[1]  = get_bits(gb, 16);
239cabdff1aSopenharmony_ci    escapes[2]  = get_bits(gb, 16);
240cabdff1aSopenharmony_ci
241cabdff1aSopenharmony_ci    last[0] = last[1] = last[2] = -1;
242cabdff1aSopenharmony_ci
243cabdff1aSopenharmony_ci    ctx.escapes[0] = escapes[0];
244cabdff1aSopenharmony_ci    ctx.escapes[1] = escapes[1];
245cabdff1aSopenharmony_ci    ctx.escapes[2] = escapes[2];
246cabdff1aSopenharmony_ci    ctx.v1 = &vlc[0];
247cabdff1aSopenharmony_ci    ctx.v2 = &vlc[1];
248cabdff1aSopenharmony_ci    ctx.last = last;
249cabdff1aSopenharmony_ci    ctx.length  = (size + 3) >> 2;
250cabdff1aSopenharmony_ci    ctx.current = 0;
251cabdff1aSopenharmony_ci    ctx.values  = av_malloc_array(ctx.length + 3, sizeof(ctx.values[0]));
252cabdff1aSopenharmony_ci    if (!ctx.values) {
253cabdff1aSopenharmony_ci        err = AVERROR(ENOMEM);
254cabdff1aSopenharmony_ci        goto error;
255cabdff1aSopenharmony_ci    }
256cabdff1aSopenharmony_ci    *recodes = ctx.values;
257cabdff1aSopenharmony_ci
258cabdff1aSopenharmony_ci    err = smacker_decode_bigtree(gb, &ctx, 0);
259cabdff1aSopenharmony_ci    if (err < 0)
260cabdff1aSopenharmony_ci        goto error;
261cabdff1aSopenharmony_ci    skip_bits1(gb);
262cabdff1aSopenharmony_ci    if (ctx.last[0] == -1) ctx.last[0] = ctx.current++;
263cabdff1aSopenharmony_ci    if (ctx.last[1] == -1) ctx.last[1] = ctx.current++;
264cabdff1aSopenharmony_ci    if (ctx.last[2] == -1) ctx.last[2] = ctx.current++;
265cabdff1aSopenharmony_ci
266cabdff1aSopenharmony_ci    err = 0;
267cabdff1aSopenharmony_cierror:
268cabdff1aSopenharmony_ci    for (int i = 0; i < 2; i++) {
269cabdff1aSopenharmony_ci        ff_free_vlc(&vlc[i]);
270cabdff1aSopenharmony_ci    }
271cabdff1aSopenharmony_ci
272cabdff1aSopenharmony_ci    return err;
273cabdff1aSopenharmony_ci}
274cabdff1aSopenharmony_ci
275cabdff1aSopenharmony_cistatic int decode_header_trees(SmackVContext *smk) {
276cabdff1aSopenharmony_ci    GetBitContext gb;
277cabdff1aSopenharmony_ci    int mmap_size, mclr_size, full_size, type_size, ret;
278cabdff1aSopenharmony_ci    int skip = 0;
279cabdff1aSopenharmony_ci
280cabdff1aSopenharmony_ci    mmap_size = AV_RL32(smk->avctx->extradata);
281cabdff1aSopenharmony_ci    mclr_size = AV_RL32(smk->avctx->extradata + 4);
282cabdff1aSopenharmony_ci    full_size = AV_RL32(smk->avctx->extradata + 8);
283cabdff1aSopenharmony_ci    type_size = AV_RL32(smk->avctx->extradata + 12);
284cabdff1aSopenharmony_ci
285cabdff1aSopenharmony_ci    ret = init_get_bits8(&gb, smk->avctx->extradata + 16, smk->avctx->extradata_size - 16);
286cabdff1aSopenharmony_ci    if (ret < 0)
287cabdff1aSopenharmony_ci        return ret;
288cabdff1aSopenharmony_ci
289cabdff1aSopenharmony_ci    if(!get_bits1(&gb)) {
290cabdff1aSopenharmony_ci        skip ++;
291cabdff1aSopenharmony_ci        av_log(smk->avctx, AV_LOG_INFO, "Skipping MMAP tree\n");
292cabdff1aSopenharmony_ci        smk->mmap_tbl = av_malloc(sizeof(int) * 2);
293cabdff1aSopenharmony_ci        if (!smk->mmap_tbl)
294cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
295cabdff1aSopenharmony_ci        smk->mmap_tbl[0] = 0;
296cabdff1aSopenharmony_ci        smk->mmap_last[0] = smk->mmap_last[1] = smk->mmap_last[2] = 1;
297cabdff1aSopenharmony_ci    } else {
298cabdff1aSopenharmony_ci        ret = smacker_decode_header_tree(smk, &gb, &smk->mmap_tbl, smk->mmap_last, mmap_size);
299cabdff1aSopenharmony_ci        if (ret < 0)
300cabdff1aSopenharmony_ci            return ret;
301cabdff1aSopenharmony_ci    }
302cabdff1aSopenharmony_ci    if(!get_bits1(&gb)) {
303cabdff1aSopenharmony_ci        skip ++;
304cabdff1aSopenharmony_ci        av_log(smk->avctx, AV_LOG_INFO, "Skipping MCLR tree\n");
305cabdff1aSopenharmony_ci        smk->mclr_tbl = av_malloc(sizeof(int) * 2);
306cabdff1aSopenharmony_ci        if (!smk->mclr_tbl)
307cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
308cabdff1aSopenharmony_ci        smk->mclr_tbl[0] = 0;
309cabdff1aSopenharmony_ci        smk->mclr_last[0] = smk->mclr_last[1] = smk->mclr_last[2] = 1;
310cabdff1aSopenharmony_ci    } else {
311cabdff1aSopenharmony_ci        ret = smacker_decode_header_tree(smk, &gb, &smk->mclr_tbl, smk->mclr_last, mclr_size);
312cabdff1aSopenharmony_ci        if (ret < 0)
313cabdff1aSopenharmony_ci            return ret;
314cabdff1aSopenharmony_ci    }
315cabdff1aSopenharmony_ci    if(!get_bits1(&gb)) {
316cabdff1aSopenharmony_ci        skip ++;
317cabdff1aSopenharmony_ci        av_log(smk->avctx, AV_LOG_INFO, "Skipping FULL tree\n");
318cabdff1aSopenharmony_ci        smk->full_tbl = av_malloc(sizeof(int) * 2);
319cabdff1aSopenharmony_ci        if (!smk->full_tbl)
320cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
321cabdff1aSopenharmony_ci        smk->full_tbl[0] = 0;
322cabdff1aSopenharmony_ci        smk->full_last[0] = smk->full_last[1] = smk->full_last[2] = 1;
323cabdff1aSopenharmony_ci    } else {
324cabdff1aSopenharmony_ci        ret = smacker_decode_header_tree(smk, &gb, &smk->full_tbl, smk->full_last, full_size);
325cabdff1aSopenharmony_ci        if (ret < 0)
326cabdff1aSopenharmony_ci            return ret;
327cabdff1aSopenharmony_ci    }
328cabdff1aSopenharmony_ci    if(!get_bits1(&gb)) {
329cabdff1aSopenharmony_ci        skip ++;
330cabdff1aSopenharmony_ci        av_log(smk->avctx, AV_LOG_INFO, "Skipping TYPE tree\n");
331cabdff1aSopenharmony_ci        smk->type_tbl = av_malloc(sizeof(int) * 2);
332cabdff1aSopenharmony_ci        if (!smk->type_tbl)
333cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
334cabdff1aSopenharmony_ci        smk->type_tbl[0] = 0;
335cabdff1aSopenharmony_ci        smk->type_last[0] = smk->type_last[1] = smk->type_last[2] = 1;
336cabdff1aSopenharmony_ci    } else {
337cabdff1aSopenharmony_ci        ret = smacker_decode_header_tree(smk, &gb, &smk->type_tbl, smk->type_last, type_size);
338cabdff1aSopenharmony_ci        if (ret < 0)
339cabdff1aSopenharmony_ci            return ret;
340cabdff1aSopenharmony_ci    }
341cabdff1aSopenharmony_ci    if (skip == 4 || get_bits_left(&gb) < 0)
342cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
343cabdff1aSopenharmony_ci
344cabdff1aSopenharmony_ci    return 0;
345cabdff1aSopenharmony_ci}
346cabdff1aSopenharmony_ci
347cabdff1aSopenharmony_cistatic av_always_inline void last_reset(int *recode, int *last) {
348cabdff1aSopenharmony_ci    recode[last[0]] = recode[last[1]] = recode[last[2]] = 0;
349cabdff1aSopenharmony_ci}
350cabdff1aSopenharmony_ci
351cabdff1aSopenharmony_ci/* Get code and update history.
352cabdff1aSopenharmony_ci * Checks before reading, does not overread. */
353cabdff1aSopenharmony_cistatic av_always_inline int smk_get_code(GetBitContext *gb, int *recode, int *last) {
354cabdff1aSopenharmony_ci    register int *table = recode;
355cabdff1aSopenharmony_ci    int v;
356cabdff1aSopenharmony_ci
357cabdff1aSopenharmony_ci    while(*table & SMK_NODE) {
358cabdff1aSopenharmony_ci        if (get_bits_left(gb) < 1)
359cabdff1aSopenharmony_ci            return AVERROR_INVALIDDATA;
360cabdff1aSopenharmony_ci        if(get_bits1(gb))
361cabdff1aSopenharmony_ci            table += (*table) & (~SMK_NODE);
362cabdff1aSopenharmony_ci        table++;
363cabdff1aSopenharmony_ci    }
364cabdff1aSopenharmony_ci    v = *table;
365cabdff1aSopenharmony_ci
366cabdff1aSopenharmony_ci    if(v != recode[last[0]]) {
367cabdff1aSopenharmony_ci        recode[last[2]] = recode[last[1]];
368cabdff1aSopenharmony_ci        recode[last[1]] = recode[last[0]];
369cabdff1aSopenharmony_ci        recode[last[0]] = v;
370cabdff1aSopenharmony_ci    }
371cabdff1aSopenharmony_ci    return v;
372cabdff1aSopenharmony_ci}
373cabdff1aSopenharmony_ci
374cabdff1aSopenharmony_cistatic int decode_frame(AVCodecContext *avctx, AVFrame *rframe,
375cabdff1aSopenharmony_ci                        int *got_frame, AVPacket *avpkt)
376cabdff1aSopenharmony_ci{
377cabdff1aSopenharmony_ci    SmackVContext * const smk = avctx->priv_data;
378cabdff1aSopenharmony_ci    uint8_t *out;
379cabdff1aSopenharmony_ci    uint32_t *pal;
380cabdff1aSopenharmony_ci    GetByteContext gb2;
381cabdff1aSopenharmony_ci    GetBitContext gb;
382cabdff1aSopenharmony_ci    int blocks, blk, bw, bh;
383cabdff1aSopenharmony_ci    int i, ret;
384cabdff1aSopenharmony_ci    int stride;
385cabdff1aSopenharmony_ci    int flags;
386cabdff1aSopenharmony_ci
387cabdff1aSopenharmony_ci    if (avpkt->size <= 769)
388cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
389cabdff1aSopenharmony_ci
390cabdff1aSopenharmony_ci    if ((ret = ff_reget_buffer(avctx, smk->pic, 0)) < 0)
391cabdff1aSopenharmony_ci        return ret;
392cabdff1aSopenharmony_ci
393cabdff1aSopenharmony_ci    /* make the palette available on the way out */
394cabdff1aSopenharmony_ci    pal = (uint32_t*)smk->pic->data[1];
395cabdff1aSopenharmony_ci    bytestream2_init(&gb2, avpkt->data, avpkt->size);
396cabdff1aSopenharmony_ci    flags = bytestream2_get_byteu(&gb2);
397cabdff1aSopenharmony_ci    smk->pic->palette_has_changed = flags & 1;
398cabdff1aSopenharmony_ci    smk->pic->key_frame = !!(flags & 2);
399cabdff1aSopenharmony_ci    if (smk->pic->key_frame)
400cabdff1aSopenharmony_ci        smk->pic->pict_type = AV_PICTURE_TYPE_I;
401cabdff1aSopenharmony_ci    else
402cabdff1aSopenharmony_ci        smk->pic->pict_type = AV_PICTURE_TYPE_P;
403cabdff1aSopenharmony_ci
404cabdff1aSopenharmony_ci    for(i = 0; i < 256; i++)
405cabdff1aSopenharmony_ci        *pal++ = 0xFFU << 24 | bytestream2_get_be24u(&gb2);
406cabdff1aSopenharmony_ci
407cabdff1aSopenharmony_ci    last_reset(smk->mmap_tbl, smk->mmap_last);
408cabdff1aSopenharmony_ci    last_reset(smk->mclr_tbl, smk->mclr_last);
409cabdff1aSopenharmony_ci    last_reset(smk->full_tbl, smk->full_last);
410cabdff1aSopenharmony_ci    last_reset(smk->type_tbl, smk->type_last);
411cabdff1aSopenharmony_ci    if ((ret = init_get_bits8(&gb, avpkt->data + 769, avpkt->size - 769)) < 0)
412cabdff1aSopenharmony_ci        return ret;
413cabdff1aSopenharmony_ci
414cabdff1aSopenharmony_ci    blk = 0;
415cabdff1aSopenharmony_ci    bw = avctx->width >> 2;
416cabdff1aSopenharmony_ci    bh = avctx->height >> 2;
417cabdff1aSopenharmony_ci    blocks = bw * bh;
418cabdff1aSopenharmony_ci    stride = smk->pic->linesize[0];
419cabdff1aSopenharmony_ci    while(blk < blocks) {
420cabdff1aSopenharmony_ci        int type, run, mode;
421cabdff1aSopenharmony_ci        uint16_t pix;
422cabdff1aSopenharmony_ci
423cabdff1aSopenharmony_ci        type = smk_get_code(&gb, smk->type_tbl, smk->type_last);
424cabdff1aSopenharmony_ci        if (type < 0)
425cabdff1aSopenharmony_ci            return type;
426cabdff1aSopenharmony_ci        run = block_runs[(type >> 2) & 0x3F];
427cabdff1aSopenharmony_ci        switch(type & 3){
428cabdff1aSopenharmony_ci        case SMK_BLK_MONO:
429cabdff1aSopenharmony_ci            while(run-- && blk < blocks){
430cabdff1aSopenharmony_ci                int clr, map;
431cabdff1aSopenharmony_ci                int hi, lo;
432cabdff1aSopenharmony_ci                clr = smk_get_code(&gb, smk->mclr_tbl, smk->mclr_last);
433cabdff1aSopenharmony_ci                map = smk_get_code(&gb, smk->mmap_tbl, smk->mmap_last);
434cabdff1aSopenharmony_ci                out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
435cabdff1aSopenharmony_ci                hi = clr >> 8;
436cabdff1aSopenharmony_ci                lo = clr & 0xFF;
437cabdff1aSopenharmony_ci                for(i = 0; i < 4; i++) {
438cabdff1aSopenharmony_ci                    if(map & 1) out[0] = hi; else out[0] = lo;
439cabdff1aSopenharmony_ci                    if(map & 2) out[1] = hi; else out[1] = lo;
440cabdff1aSopenharmony_ci                    if(map & 4) out[2] = hi; else out[2] = lo;
441cabdff1aSopenharmony_ci                    if(map & 8) out[3] = hi; else out[3] = lo;
442cabdff1aSopenharmony_ci                    map >>= 4;
443cabdff1aSopenharmony_ci                    out += stride;
444cabdff1aSopenharmony_ci                }
445cabdff1aSopenharmony_ci                blk++;
446cabdff1aSopenharmony_ci            }
447cabdff1aSopenharmony_ci            break;
448cabdff1aSopenharmony_ci        case SMK_BLK_FULL:
449cabdff1aSopenharmony_ci            mode = 0;
450cabdff1aSopenharmony_ci            if(avctx->codec_tag == MKTAG('S', 'M', 'K', '4')) { // In case of Smacker v4 we have three modes
451cabdff1aSopenharmony_ci                if (get_bits_left(&gb) < 1)
452cabdff1aSopenharmony_ci                    return AVERROR_INVALIDDATA;
453cabdff1aSopenharmony_ci                if(get_bits1(&gb)) mode = 1;
454cabdff1aSopenharmony_ci                else if(get_bits1(&gb)) mode = 2;
455cabdff1aSopenharmony_ci            }
456cabdff1aSopenharmony_ci            while(run-- && blk < blocks){
457cabdff1aSopenharmony_ci                out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
458cabdff1aSopenharmony_ci                switch(mode){
459cabdff1aSopenharmony_ci                case 0:
460cabdff1aSopenharmony_ci                    for(i = 0; i < 4; i++) {
461cabdff1aSopenharmony_ci                        pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);
462cabdff1aSopenharmony_ci                        AV_WL16(out+2,pix);
463cabdff1aSopenharmony_ci                        pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);
464cabdff1aSopenharmony_ci                        AV_WL16(out,pix);
465cabdff1aSopenharmony_ci                        out += stride;
466cabdff1aSopenharmony_ci                    }
467cabdff1aSopenharmony_ci                    break;
468cabdff1aSopenharmony_ci                case 1:
469cabdff1aSopenharmony_ci                    pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);
470cabdff1aSopenharmony_ci                    out[0] = out[1] = pix & 0xFF;
471cabdff1aSopenharmony_ci                    out[2] = out[3] = pix >> 8;
472cabdff1aSopenharmony_ci                    out += stride;
473cabdff1aSopenharmony_ci                    out[0] = out[1] = pix & 0xFF;
474cabdff1aSopenharmony_ci                    out[2] = out[3] = pix >> 8;
475cabdff1aSopenharmony_ci                    out += stride;
476cabdff1aSopenharmony_ci                    pix = smk_get_code(&gb, smk->full_tbl, smk->full_last);
477cabdff1aSopenharmony_ci                    out[0] = out[1] = pix & 0xFF;
478cabdff1aSopenharmony_ci                    out[2] = out[3] = pix >> 8;
479cabdff1aSopenharmony_ci                    out += stride;
480cabdff1aSopenharmony_ci                    out[0] = out[1] = pix & 0xFF;
481cabdff1aSopenharmony_ci                    out[2] = out[3] = pix >> 8;
482cabdff1aSopenharmony_ci                    break;
483cabdff1aSopenharmony_ci                case 2:
484cabdff1aSopenharmony_ci                    for(i = 0; i < 2; i++) {
485cabdff1aSopenharmony_ci                        uint16_t pix1, pix2;
486cabdff1aSopenharmony_ci                        pix2 = smk_get_code(&gb, smk->full_tbl, smk->full_last);
487cabdff1aSopenharmony_ci                        pix1 = smk_get_code(&gb, smk->full_tbl, smk->full_last);
488cabdff1aSopenharmony_ci                        AV_WL16(out,pix1);
489cabdff1aSopenharmony_ci                        AV_WL16(out+2,pix2);
490cabdff1aSopenharmony_ci                        out += stride;
491cabdff1aSopenharmony_ci                        AV_WL16(out,pix1);
492cabdff1aSopenharmony_ci                        AV_WL16(out+2,pix2);
493cabdff1aSopenharmony_ci                        out += stride;
494cabdff1aSopenharmony_ci                    }
495cabdff1aSopenharmony_ci                    break;
496cabdff1aSopenharmony_ci                }
497cabdff1aSopenharmony_ci                blk++;
498cabdff1aSopenharmony_ci            }
499cabdff1aSopenharmony_ci            break;
500cabdff1aSopenharmony_ci        case SMK_BLK_SKIP:
501cabdff1aSopenharmony_ci            while(run-- && blk < blocks)
502cabdff1aSopenharmony_ci                blk++;
503cabdff1aSopenharmony_ci            break;
504cabdff1aSopenharmony_ci        case SMK_BLK_FILL:
505cabdff1aSopenharmony_ci            mode = type >> 8;
506cabdff1aSopenharmony_ci            while(run-- && blk < blocks){
507cabdff1aSopenharmony_ci                uint32_t col;
508cabdff1aSopenharmony_ci                out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4;
509cabdff1aSopenharmony_ci                col = mode * 0x01010101U;
510cabdff1aSopenharmony_ci                for(i = 0; i < 4; i++) {
511cabdff1aSopenharmony_ci                    *((uint32_t*)out) = col;
512cabdff1aSopenharmony_ci                    out += stride;
513cabdff1aSopenharmony_ci                }
514cabdff1aSopenharmony_ci                blk++;
515cabdff1aSopenharmony_ci            }
516cabdff1aSopenharmony_ci            break;
517cabdff1aSopenharmony_ci        }
518cabdff1aSopenharmony_ci
519cabdff1aSopenharmony_ci    }
520cabdff1aSopenharmony_ci
521cabdff1aSopenharmony_ci    if ((ret = av_frame_ref(rframe, smk->pic)) < 0)
522cabdff1aSopenharmony_ci        return ret;
523cabdff1aSopenharmony_ci
524cabdff1aSopenharmony_ci    *got_frame = 1;
525cabdff1aSopenharmony_ci
526cabdff1aSopenharmony_ci    /* always report that the buffer was completely consumed */
527cabdff1aSopenharmony_ci    return avpkt->size;
528cabdff1aSopenharmony_ci}
529cabdff1aSopenharmony_ci
530cabdff1aSopenharmony_ci
531cabdff1aSopenharmony_cistatic av_cold int decode_end(AVCodecContext *avctx)
532cabdff1aSopenharmony_ci{
533cabdff1aSopenharmony_ci    SmackVContext * const smk = avctx->priv_data;
534cabdff1aSopenharmony_ci
535cabdff1aSopenharmony_ci    av_freep(&smk->mmap_tbl);
536cabdff1aSopenharmony_ci    av_freep(&smk->mclr_tbl);
537cabdff1aSopenharmony_ci    av_freep(&smk->full_tbl);
538cabdff1aSopenharmony_ci    av_freep(&smk->type_tbl);
539cabdff1aSopenharmony_ci
540cabdff1aSopenharmony_ci    av_frame_free(&smk->pic);
541cabdff1aSopenharmony_ci
542cabdff1aSopenharmony_ci    return 0;
543cabdff1aSopenharmony_ci}
544cabdff1aSopenharmony_ci
545cabdff1aSopenharmony_ci
546cabdff1aSopenharmony_cistatic av_cold int decode_init(AVCodecContext *avctx)
547cabdff1aSopenharmony_ci{
548cabdff1aSopenharmony_ci    SmackVContext * const c = avctx->priv_data;
549cabdff1aSopenharmony_ci    int ret;
550cabdff1aSopenharmony_ci
551cabdff1aSopenharmony_ci    c->avctx = avctx;
552cabdff1aSopenharmony_ci
553cabdff1aSopenharmony_ci    avctx->pix_fmt = AV_PIX_FMT_PAL8;
554cabdff1aSopenharmony_ci
555cabdff1aSopenharmony_ci    c->pic = av_frame_alloc();
556cabdff1aSopenharmony_ci    if (!c->pic)
557cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
558cabdff1aSopenharmony_ci
559cabdff1aSopenharmony_ci    /* decode huffman trees from extradata */
560cabdff1aSopenharmony_ci    if (avctx->extradata_size <= 16){
561cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Extradata missing!\n");
562cabdff1aSopenharmony_ci        return AVERROR(EINVAL);
563cabdff1aSopenharmony_ci    }
564cabdff1aSopenharmony_ci
565cabdff1aSopenharmony_ci    ret = decode_header_trees(c);
566cabdff1aSopenharmony_ci    if (ret < 0) {
567cabdff1aSopenharmony_ci        return ret;
568cabdff1aSopenharmony_ci    }
569cabdff1aSopenharmony_ci
570cabdff1aSopenharmony_ci    return 0;
571cabdff1aSopenharmony_ci}
572cabdff1aSopenharmony_ci
573cabdff1aSopenharmony_ci
574cabdff1aSopenharmony_cistatic av_cold int smka_decode_init(AVCodecContext *avctx)
575cabdff1aSopenharmony_ci{
576cabdff1aSopenharmony_ci    int channels = avctx->ch_layout.nb_channels;
577cabdff1aSopenharmony_ci    if (channels < 1 || channels > 2) {
578cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
579cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
580cabdff1aSopenharmony_ci    }
581cabdff1aSopenharmony_ci    av_channel_layout_uninit(&avctx->ch_layout);
582cabdff1aSopenharmony_ci    av_channel_layout_default(&avctx->ch_layout, channels);
583cabdff1aSopenharmony_ci    avctx->sample_fmt = avctx->bits_per_coded_sample == 8 ? AV_SAMPLE_FMT_U8 : AV_SAMPLE_FMT_S16;
584cabdff1aSopenharmony_ci
585cabdff1aSopenharmony_ci    return 0;
586cabdff1aSopenharmony_ci}
587cabdff1aSopenharmony_ci
588cabdff1aSopenharmony_ci/**
589cabdff1aSopenharmony_ci * Decode Smacker audio data
590cabdff1aSopenharmony_ci */
591cabdff1aSopenharmony_cistatic int smka_decode_frame(AVCodecContext *avctx, AVFrame *frame,
592cabdff1aSopenharmony_ci                             int *got_frame_ptr, AVPacket *avpkt)
593cabdff1aSopenharmony_ci{
594cabdff1aSopenharmony_ci    const uint8_t *buf = avpkt->data;
595cabdff1aSopenharmony_ci    int buf_size = avpkt->size;
596cabdff1aSopenharmony_ci    GetBitContext gb;
597cabdff1aSopenharmony_ci    VLC vlc[4]       = { { 0 } };
598cabdff1aSopenharmony_ci    int16_t *samples;
599cabdff1aSopenharmony_ci    uint8_t *samples8;
600cabdff1aSopenharmony_ci    uint8_t values[4];
601cabdff1aSopenharmony_ci    int i, res, ret;
602cabdff1aSopenharmony_ci    int unp_size;
603cabdff1aSopenharmony_ci    int bits, stereo;
604cabdff1aSopenharmony_ci    unsigned pred[2], val, val2;
605cabdff1aSopenharmony_ci
606cabdff1aSopenharmony_ci    if (buf_size <= 4) {
607cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
608cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
609cabdff1aSopenharmony_ci    }
610cabdff1aSopenharmony_ci
611cabdff1aSopenharmony_ci    unp_size = AV_RL32(buf);
612cabdff1aSopenharmony_ci
613cabdff1aSopenharmony_ci    if (unp_size > (1U<<24)) {
614cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "packet is too big\n");
615cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
616cabdff1aSopenharmony_ci    }
617cabdff1aSopenharmony_ci
618cabdff1aSopenharmony_ci    if ((ret = init_get_bits8(&gb, buf + 4, buf_size - 4)) < 0)
619cabdff1aSopenharmony_ci        return ret;
620cabdff1aSopenharmony_ci
621cabdff1aSopenharmony_ci    if(!get_bits1(&gb)){
622cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_INFO, "Sound: no data\n");
623cabdff1aSopenharmony_ci        *got_frame_ptr = 0;
624cabdff1aSopenharmony_ci        return 1;
625cabdff1aSopenharmony_ci    }
626cabdff1aSopenharmony_ci    stereo = get_bits1(&gb);
627cabdff1aSopenharmony_ci    bits = get_bits1(&gb);
628cabdff1aSopenharmony_ci    if (stereo ^ (avctx->ch_layout.nb_channels != 1)) {
629cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "channels mismatch\n");
630cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
631cabdff1aSopenharmony_ci    }
632cabdff1aSopenharmony_ci    if (bits == (avctx->sample_fmt == AV_SAMPLE_FMT_U8)) {
633cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "sample format mismatch\n");
634cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
635cabdff1aSopenharmony_ci    }
636cabdff1aSopenharmony_ci
637cabdff1aSopenharmony_ci    /* get output buffer */
638cabdff1aSopenharmony_ci    frame->nb_samples = unp_size / (avctx->ch_layout.nb_channels * (bits + 1));
639cabdff1aSopenharmony_ci    if (unp_size % (avctx->ch_layout.nb_channels * (bits + 1))) {
640cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR,
641cabdff1aSopenharmony_ci               "The buffer does not contain an integer number of samples\n");
642cabdff1aSopenharmony_ci        return AVERROR_INVALIDDATA;
643cabdff1aSopenharmony_ci    }
644cabdff1aSopenharmony_ci    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
645cabdff1aSopenharmony_ci        return ret;
646cabdff1aSopenharmony_ci    samples  = (int16_t *)frame->data[0];
647cabdff1aSopenharmony_ci    samples8 =            frame->data[0];
648cabdff1aSopenharmony_ci
649cabdff1aSopenharmony_ci    // Initialize
650cabdff1aSopenharmony_ci    for(i = 0; i < (1 << (bits + stereo)); i++) {
651cabdff1aSopenharmony_ci        HuffContext h;
652cabdff1aSopenharmony_ci        h.current = 0;
653cabdff1aSopenharmony_ci        skip_bits1(&gb);
654cabdff1aSopenharmony_ci        if ((ret = smacker_decode_tree(&gb, &h, 0)) < 0)
655cabdff1aSopenharmony_ci            goto error;
656cabdff1aSopenharmony_ci        skip_bits1(&gb);
657cabdff1aSopenharmony_ci        if (h.current > 1) {
658cabdff1aSopenharmony_ci            ret = ff_init_vlc_from_lengths(&vlc[i], SMKTREE_BITS, h.current,
659cabdff1aSopenharmony_ci                                           &h.entries[0].length, sizeof(*h.entries),
660cabdff1aSopenharmony_ci                                           &h.entries[0].value,  sizeof(*h.entries), 1,
661cabdff1aSopenharmony_ci                                           0, INIT_VLC_OUTPUT_LE, avctx);
662cabdff1aSopenharmony_ci            if (ret < 0) {
663cabdff1aSopenharmony_ci                av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
664cabdff1aSopenharmony_ci                goto error;
665cabdff1aSopenharmony_ci            }
666cabdff1aSopenharmony_ci        } else
667cabdff1aSopenharmony_ci            values[i] = h.entries[0].value;
668cabdff1aSopenharmony_ci    }
669cabdff1aSopenharmony_ci    /* this codec relies on wraparound instead of clipping audio */
670cabdff1aSopenharmony_ci    if(bits) { //decode 16-bit data
671cabdff1aSopenharmony_ci        for(i = stereo; i >= 0; i--)
672cabdff1aSopenharmony_ci            pred[i] = av_bswap16(get_bits(&gb, 16));
673cabdff1aSopenharmony_ci        for(i = 0; i <= stereo; i++)
674cabdff1aSopenharmony_ci            *samples++ = pred[i];
675cabdff1aSopenharmony_ci        unp_size /= 2;
676cabdff1aSopenharmony_ci
677cabdff1aSopenharmony_ci        if (vlc[0       ].table || vlc[         1].table ||
678cabdff1aSopenharmony_ci            vlc[2*stereo].table || vlc[2*stereo+1].table) {
679cabdff1aSopenharmony_ci            for(; i < unp_size ; i++) {
680cabdff1aSopenharmony_ci                unsigned idx = 2 * (i & stereo);
681cabdff1aSopenharmony_ci                if (get_bits_left(&gb) < 0) {
682cabdff1aSopenharmony_ci                    ret = AVERROR_INVALIDDATA;
683cabdff1aSopenharmony_ci                    goto error;
684cabdff1aSopenharmony_ci                }
685cabdff1aSopenharmony_ci                if (vlc[idx].table)
686cabdff1aSopenharmony_ci                    res = get_vlc2(&gb, vlc[idx].table, SMKTREE_BITS, 3);
687cabdff1aSopenharmony_ci                else
688cabdff1aSopenharmony_ci                    res = values[idx];
689cabdff1aSopenharmony_ci                val  = res;
690cabdff1aSopenharmony_ci                if (vlc[++idx].table)
691cabdff1aSopenharmony_ci                    res = get_vlc2(&gb, vlc[idx].table, SMKTREE_BITS, 3);
692cabdff1aSopenharmony_ci                else
693cabdff1aSopenharmony_ci                    res = values[idx];
694cabdff1aSopenharmony_ci                val |= res << 8;
695cabdff1aSopenharmony_ci                pred[idx / 2] += val;
696cabdff1aSopenharmony_ci                *samples++ = pred[idx / 2];
697cabdff1aSopenharmony_ci            }
698cabdff1aSopenharmony_ci        } else if (stereo) {
699cabdff1aSopenharmony_ci            val  = 256*values[1] + values[0];
700cabdff1aSopenharmony_ci            val2 = 256*values[3] + values[2];
701cabdff1aSopenharmony_ci            for(; i < unp_size; i+=2) {
702cabdff1aSopenharmony_ci                pred[0] += val;
703cabdff1aSopenharmony_ci                pred[1] += val2;
704cabdff1aSopenharmony_ci                *samples++ = pred[0];
705cabdff1aSopenharmony_ci                *samples++ = pred[1];
706cabdff1aSopenharmony_ci            }
707cabdff1aSopenharmony_ci        } else {
708cabdff1aSopenharmony_ci            val = 256*values[1] + values[0];
709cabdff1aSopenharmony_ci            for(; i < unp_size; i++) {
710cabdff1aSopenharmony_ci                pred[0] += val;
711cabdff1aSopenharmony_ci                *samples++ = pred[0];
712cabdff1aSopenharmony_ci            }
713cabdff1aSopenharmony_ci        }
714cabdff1aSopenharmony_ci    } else { //8-bit data
715cabdff1aSopenharmony_ci        for(i = stereo; i >= 0; i--)
716cabdff1aSopenharmony_ci            pred[i] = get_bits(&gb, 8);
717cabdff1aSopenharmony_ci        for(i = 0; i <= stereo; i++)
718cabdff1aSopenharmony_ci            *samples8++ = pred[i];
719cabdff1aSopenharmony_ci        for(; i < unp_size; i++) {
720cabdff1aSopenharmony_ci            unsigned idx = i & stereo;
721cabdff1aSopenharmony_ci            if (get_bits_left(&gb) < 0) {
722cabdff1aSopenharmony_ci                ret = AVERROR_INVALIDDATA;
723cabdff1aSopenharmony_ci                goto error;
724cabdff1aSopenharmony_ci            }
725cabdff1aSopenharmony_ci            if (vlc[idx].table)
726cabdff1aSopenharmony_ci                val = get_vlc2(&gb, vlc[idx].table, SMKTREE_BITS, 3);
727cabdff1aSopenharmony_ci            else
728cabdff1aSopenharmony_ci                val = values[idx];
729cabdff1aSopenharmony_ci            pred[idx] += val;
730cabdff1aSopenharmony_ci            *samples8++ = pred[idx];
731cabdff1aSopenharmony_ci        }
732cabdff1aSopenharmony_ci    }
733cabdff1aSopenharmony_ci
734cabdff1aSopenharmony_ci    *got_frame_ptr = 1;
735cabdff1aSopenharmony_ci    ret = buf_size;
736cabdff1aSopenharmony_ci
737cabdff1aSopenharmony_cierror:
738cabdff1aSopenharmony_ci    for(i = 0; i < 4; i++) {
739cabdff1aSopenharmony_ci        ff_free_vlc(&vlc[i]);
740cabdff1aSopenharmony_ci    }
741cabdff1aSopenharmony_ci
742cabdff1aSopenharmony_ci    return ret;
743cabdff1aSopenharmony_ci}
744cabdff1aSopenharmony_ci
745cabdff1aSopenharmony_ciconst FFCodec ff_smacker_decoder = {
746cabdff1aSopenharmony_ci    .p.name         = "smackvid",
747cabdff1aSopenharmony_ci    .p.long_name    = NULL_IF_CONFIG_SMALL("Smacker video"),
748cabdff1aSopenharmony_ci    .p.type         = AVMEDIA_TYPE_VIDEO,
749cabdff1aSopenharmony_ci    .p.id           = AV_CODEC_ID_SMACKVIDEO,
750cabdff1aSopenharmony_ci    .priv_data_size = sizeof(SmackVContext),
751cabdff1aSopenharmony_ci    .init           = decode_init,
752cabdff1aSopenharmony_ci    .close          = decode_end,
753cabdff1aSopenharmony_ci    FF_CODEC_DECODE_CB(decode_frame),
754cabdff1aSopenharmony_ci    .p.capabilities = AV_CODEC_CAP_DR1,
755cabdff1aSopenharmony_ci    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE,
756cabdff1aSopenharmony_ci};
757cabdff1aSopenharmony_ci
758cabdff1aSopenharmony_ciconst FFCodec ff_smackaud_decoder = {
759cabdff1aSopenharmony_ci    .p.name         = "smackaud",
760cabdff1aSopenharmony_ci    .p.long_name    = NULL_IF_CONFIG_SMALL("Smacker audio"),
761cabdff1aSopenharmony_ci    .p.type         = AVMEDIA_TYPE_AUDIO,
762cabdff1aSopenharmony_ci    .p.id           = AV_CODEC_ID_SMACKAUDIO,
763cabdff1aSopenharmony_ci    .init           = smka_decode_init,
764cabdff1aSopenharmony_ci    FF_CODEC_DECODE_CB(smka_decode_frame),
765cabdff1aSopenharmony_ci    .p.capabilities = AV_CODEC_CAP_DR1,
766cabdff1aSopenharmony_ci    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
767cabdff1aSopenharmony_ci};
768