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