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