| Line | Branch | Exec | Source | 
|---|---|---|---|
| 1 | /* | ||
| 2 | * Microsoft Screen 4 (aka Microsoft Expression Encoder Screen) decoder | ||
| 3 | * Copyright (c) 2012 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 | * Microsoft Screen 4 (aka Microsoft Titanium Screen 2, | ||
| 25 | * aka Microsoft Expression Encoder Screen) decoder | ||
| 26 | */ | ||
| 27 | |||
| 28 | #include "libavutil/mem.h" | ||
| 29 | #include "libavutil/thread.h" | ||
| 30 | #include "libavutil/imgutils.h" | ||
| 31 | |||
| 32 | #include "avcodec.h" | ||
| 33 | #include "bytestream.h" | ||
| 34 | #include "codec_internal.h" | ||
| 35 | #include "decode.h" | ||
| 36 | #include "get_bits.h" | ||
| 37 | #include "jpegtables.h" | ||
| 38 | #include "mss34dsp.h" | ||
| 39 | #include "unary.h" | ||
| 40 | |||
| 41 | #define HEADER_SIZE 8 | ||
| 42 | |||
| 43 | enum FrameType { | ||
| 44 | INTRA_FRAME = 0, | ||
| 45 | INTER_FRAME, | ||
| 46 | SKIP_FRAME | ||
| 47 | }; | ||
| 48 | |||
| 49 | enum BlockType { | ||
| 50 | SKIP_BLOCK = 0, | ||
| 51 | DCT_BLOCK, | ||
| 52 | IMAGE_BLOCK, | ||
| 53 | }; | ||
| 54 | |||
| 55 | enum CachePos { | ||
| 56 | LEFT = 0, | ||
| 57 | TOP_LEFT, | ||
| 58 | TOP, | ||
| 59 | }; | ||
| 60 | |||
| 61 | static const uint8_t mss4_dc_vlc_lens[2][16] = { | ||
| 62 | { 0, 1, 5, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 63 | { 0, 3, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0 } | ||
| 64 | }; | ||
| 65 | |||
| 66 | static const uint8_t vec_len_syms[2][4] = { | ||
| 67 | { 4, 2, 3, 1 }, | ||
| 68 | { 4, 1, 2, 3 } | ||
| 69 | }; | ||
| 70 | |||
| 71 | static const uint8_t mss4_vec_entry_vlc_lens[2][16] = { | ||
| 72 | { 0, 2, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 73 | { 0, 1, 5, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } | ||
| 74 | }; | ||
| 75 | |||
| 76 | static const uint8_t mss4_vec_entry_vlc_syms[2][9] = { | ||
| 77 | { 0, 7, 6, 5, 8, 4, 3, 1, 2 }, | ||
| 78 | { 0, 2, 3, 4, 5, 6, 7, 1, 8 } | ||
| 79 | }; | ||
| 80 | |||
| 81 | #define MAX_ENTRIES 162 | ||
| 82 | |||
| 83 | typedef struct MSS4Context { | ||
| 84 | AVFrame *pic; | ||
| 85 | |||
| 86 | int block[64]; | ||
| 87 | uint8_t imgbuf[3][16 * 16]; | ||
| 88 | |||
| 89 | int quality; | ||
| 90 | uint16_t quant_mat[2][64]; | ||
| 91 | |||
| 92 | int *prev_dc[3]; | ||
| 93 | ptrdiff_t dc_stride[3]; | ||
| 94 | int dc_cache[4][4]; | ||
| 95 | |||
| 96 | int prev_vec[3][4]; | ||
| 97 | } MSS4Context; | ||
| 98 | |||
| 99 | static VLC dc_vlc[2], ac_vlc[2]; | ||
| 100 | static VLC vec_entry_vlc[2]; | ||
| 101 | |||
| 102 | 12 | static av_cold void mss4_init_vlc(VLC *vlc, unsigned *offset, | |
| 103 | const uint8_t *lens, const uint8_t *syms) | ||
| 104 | { | ||
| 105 | static VLCElem vlc_buf[2146]; | ||
| 106 | uint8_t bits[MAX_ENTRIES]; | ||
| 107 | int i, j; | ||
| 108 | 12 | int idx = 0; | |
| 109 | |||
| 110 | 
        2/2✓ Branch 0 taken 192 times. 
          ✓ Branch 1 taken 12 times. 
         | 
      204 | for (i = 0; i < 16; i++) { | 
| 111 | 
        2/2✓ Branch 0 taken 732 times. 
          ✓ Branch 1 taken 192 times. 
         | 
      924 | for (j = 0; j < lens[i]; j++) { | 
| 112 | 732 | bits[idx] = i + 1; | |
| 113 | 732 | idx++; | |
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | 12 | vlc->table = &vlc_buf[*offset]; | |
| 118 | 12 | vlc->table_allocated = FF_ARRAY_ELEMS(vlc_buf) - *offset; | |
| 119 | 12 | ff_vlc_init_from_lengths(vlc, FFMIN(bits[idx - 1], 9), idx, | |
| 120 | bits, 1, syms, 1, 1, | ||
| 121 | 0, VLC_INIT_STATIC_OVERLONG, NULL); | ||
| 122 | 12 | *offset += vlc->table_size; | |
| 123 | 12 | } | |
| 124 | |||
| 125 | 2 | static av_cold void mss4_init_vlcs(void) | |
| 126 | { | ||
| 127 | 
        2/2✓ Branch 0 taken 4 times. 
          ✓ Branch 1 taken 2 times. 
         | 
      6 | for (unsigned i = 0, offset = 0; i < 2; i++) { | 
| 128 | 4 | mss4_init_vlc(&dc_vlc[i], &offset, mss4_dc_vlc_lens[i], NULL); | |
| 129 | 
        4/4✓ Branch 0 taken 2 times. 
          ✓ Branch 1 taken 2 times. 
          ✓ Branch 2 taken 2 times. 
          ✓ Branch 3 taken 2 times. 
         | 
      4 | mss4_init_vlc(&ac_vlc[i], &offset, | 
| 130 | i ? ff_mjpeg_bits_ac_chrominance + 1 | ||
| 131 | : ff_mjpeg_bits_ac_luminance + 1, | ||
| 132 | i ? ff_mjpeg_val_ac_chrominance | ||
| 133 | : ff_mjpeg_val_ac_luminance); | ||
| 134 | 4 | mss4_init_vlc(&vec_entry_vlc[i], &offset, mss4_vec_entry_vlc_lens[i], | |
| 135 | 4 | mss4_vec_entry_vlc_syms[i]); | |
| 136 | } | ||
| 137 | 2 | } | |
| 138 | |||
| 139 | /* This function returns values in the range | ||
| 140 | * (-range + 1; -range/2] U [range/2; range - 1) | ||
| 141 | * i.e. | ||
| 142 | * nbits = 0 -> 0 | ||
| 143 | * nbits = 1 -> -1, 1 | ||
| 144 | * nbits = 2 -> -3, -2, 2, 3 | ||
| 145 | */ | ||
| 146 | 315916 | static av_always_inline int get_coeff_bits(GetBitContext *gb, int nbits) | |
| 147 | { | ||
| 148 | int val; | ||
| 149 | |||
| 150 | 
        2/2✓ Branch 0 taken 133329 times. 
          ✓ Branch 1 taken 182587 times. 
         | 
      315916 | if (!nbits) | 
| 151 | 133329 | return 0; | |
| 152 | |||
| 153 | 182587 | val = get_bits(gb, nbits); | |
| 154 | 
        2/2✓ Branch 0 taken 98069 times. 
          ✓ Branch 1 taken 84518 times. 
         | 
      182587 | if (val < (1 << (nbits - 1))) | 
| 155 | 98069 | val -= (1 << nbits) - 1; | |
| 156 | |||
| 157 | 182587 | return val; | |
| 158 | } | ||
| 159 | |||
| 160 | 180586 | static inline int get_coeff(GetBitContext *gb, const VLC *vlc, | |
| 161 | int nb_bits, int max_depth) | ||
| 162 | { | ||
| 163 | 180586 | int val = get_vlc2(gb, vlc->table, nb_bits, max_depth); | |
| 164 | |||
| 165 | 180586 | return get_coeff_bits(gb, val); | |
| 166 | } | ||
| 167 | |||
| 168 | 85284 | static int mss4_decode_dct(GetBitContext *gb, VLC *dc_vlc, VLC *ac_vlc, | |
| 169 | int *block, int *dc_cache, | ||
| 170 | int bx, int by, uint16_t *quant_mat) | ||
| 171 | { | ||
| 172 | 85284 | int skip, val, pos = 1, zz_pos, dc; | |
| 173 | |||
| 174 | 85284 | memset(block, 0, sizeof(*block) * 64); | |
| 175 | |||
| 176 | 85284 | dc = get_coeff(gb, dc_vlc, dc_vlc->bits, 2); | |
| 177 | // DC prediction is the same as in MSS3 | ||
| 178 | 
        2/2✓ Branch 0 taken 84904 times. 
          ✓ Branch 1 taken 380 times. 
         | 
      85284 | if (by) { | 
| 179 | 
        2/2✓ Branch 0 taken 83868 times. 
          ✓ Branch 1 taken 1036 times. 
         | 
      84904 | if (bx) { | 
| 180 | int l, tl, t; | ||
| 181 | |||
| 182 | 83868 | l = dc_cache[LEFT]; | |
| 183 | 83868 | tl = dc_cache[TOP_LEFT]; | |
| 184 | 83868 | t = dc_cache[TOP]; | |
| 185 | |||
| 186 | 
        2/2✓ Branch 0 taken 80876 times. 
          ✓ Branch 1 taken 2992 times. 
         | 
      83868 | if (FFABS(t - tl) <= FFABS(l - tl)) | 
| 187 | 80876 | dc += l; | |
| 188 | else | ||
| 189 | 2992 | dc += t; | |
| 190 | } else { | ||
| 191 | 1036 | dc += dc_cache[TOP]; | |
| 192 | } | ||
| 193 | 
        1/2✓ Branch 0 taken 380 times. 
          ✗ Branch 1 not taken. 
         | 
      380 | } else if (bx) { | 
| 194 | 380 | dc += dc_cache[LEFT]; | |
| 195 | } | ||
| 196 | 85284 | dc_cache[LEFT] = dc; | |
| 197 | 85284 | block[0] = dc * quant_mat[0]; | |
| 198 | |||
| 199 | 
        2/2✓ Branch 0 taken 219785 times. 
          ✓ Branch 1 taken 897 times. 
         | 
      220682 | while (pos < 64) { | 
| 200 | 219785 | val = get_vlc2(gb, ac_vlc->table, 9, 2); | |
| 201 | 
        2/2✓ Branch 0 taken 84387 times. 
          ✓ Branch 1 taken 135398 times. 
         | 
      219785 | if (!val) | 
| 202 | 84387 | return 0; | |
| 203 | 
        1/2✗ Branch 0 not taken. 
          ✓ Branch 1 taken 135398 times. 
         | 
      135398 | if (val == -1) | 
| 204 | ✗ | return -1; | |
| 205 | 
        2/2✓ Branch 0 taken 68 times. 
          ✓ Branch 1 taken 135330 times. 
         | 
      135398 | if (val == 0xF0) { | 
| 206 | 68 | pos += 16; | |
| 207 | 68 | continue; | |
| 208 | } | ||
| 209 | 135330 | skip = val >> 4; | |
| 210 | 135330 | val = get_coeff_bits(gb, val & 0xF); | |
| 211 | 135330 | pos += skip; | |
| 212 | 
        1/2✗ Branch 0 not taken. 
          ✓ Branch 1 taken 135330 times. 
         | 
      135330 | if (pos >= 64) | 
| 213 | ✗ | return -1; | |
| 214 | |||
| 215 | 135330 | zz_pos = ff_zigzag_direct[pos]; | |
| 216 | 135330 | block[zz_pos] = val * quant_mat[zz_pos]; | |
| 217 | 135330 | pos++; | |
| 218 | } | ||
| 219 | |||
| 220 | 
        1/2✓ Branch 0 taken 897 times. 
          ✗ Branch 1 not taken. 
         | 
      897 | return pos == 64 ? 0 : -1; | 
| 221 | } | ||
| 222 | |||
| 223 | 14214 | static int mss4_decode_dct_block(MSS4Context *c, GetBitContext *gb, | |
| 224 | uint8_t *dst[3], int mb_x, int mb_y) | ||
| 225 | { | ||
| 226 | int i, j, k, ret; | ||
| 227 | 14214 | uint8_t *out = dst[0]; | |
| 228 | |||
| 229 | 
        2/2✓ Branch 0 taken 28428 times. 
          ✓ Branch 1 taken 14214 times. 
         | 
      42642 | for (j = 0; j < 2; j++) { | 
| 230 | 
        2/2✓ Branch 0 taken 56856 times. 
          ✓ Branch 1 taken 28428 times. 
         | 
      85284 | for (i = 0; i < 2; i++) { | 
| 231 | 56856 | int xpos = mb_x * 2 + i; | |
| 232 | 56856 | c->dc_cache[j][TOP_LEFT] = c->dc_cache[j][TOP]; | |
| 233 | 56856 | c->dc_cache[j][TOP] = c->prev_dc[0][mb_x * 2 + i]; | |
| 234 | 56856 | ret = mss4_decode_dct(gb, &dc_vlc[0], &ac_vlc[0], c->block, | |
| 235 | 56856 | c->dc_cache[j], | |
| 236 | 56856 | xpos, mb_y * 2 + j, c->quant_mat[0]); | |
| 237 | 
        1/2✗ Branch 0 not taken. 
          ✓ Branch 1 taken 56856 times. 
         | 
      56856 | if (ret) | 
| 238 | ✗ | return ret; | |
| 239 | 56856 | c->prev_dc[0][mb_x * 2 + i] = c->dc_cache[j][LEFT]; | |
| 240 | |||
| 241 | 56856 | ff_mss34_dct_put(out + xpos * 8, c->pic->linesize[0], | |
| 242 | 56856 | c->block); | |
| 243 | } | ||
| 244 | 28428 | out += 8 * c->pic->linesize[0]; | |
| 245 | } | ||
| 246 | |||
| 247 | 
        2/2✓ Branch 0 taken 28428 times. 
          ✓ Branch 1 taken 14214 times. 
         | 
      42642 | for (i = 1; i < 3; i++) { | 
| 248 | 28428 | c->dc_cache[i + 1][TOP_LEFT] = c->dc_cache[i + 1][TOP]; | |
| 249 | 28428 | c->dc_cache[i + 1][TOP] = c->prev_dc[i][mb_x]; | |
| 250 | 28428 | ret = mss4_decode_dct(gb, &dc_vlc[1], &ac_vlc[1], | |
| 251 | 28428 | c->block, c->dc_cache[i + 1], mb_x, mb_y, | |
| 252 | 28428 | c->quant_mat[1]); | |
| 253 | 
        1/2✗ Branch 0 not taken. 
          ✓ Branch 1 taken 28428 times. 
         | 
      28428 | if (ret) | 
| 254 | ✗ | return ret; | |
| 255 | 28428 | c->prev_dc[i][mb_x] = c->dc_cache[i + 1][LEFT]; | |
| 256 | |||
| 257 | 28428 | ff_mss34_dct_put(c->imgbuf[i], 8, c->block); | |
| 258 | 28428 | out = dst[i] + mb_x * 16; | |
| 259 | // Since the DCT block is coded as YUV420 and the whole frame as YUV444, | ||
| 260 | // we need to scale chroma. | ||
| 261 | 
        2/2✓ Branch 0 taken 454848 times. 
          ✓ Branch 1 taken 28428 times. 
         | 
      483276 | for (j = 0; j < 16; j++) { | 
| 262 | 
        2/2✓ Branch 0 taken 3638784 times. 
          ✓ Branch 1 taken 454848 times. 
         | 
      4093632 | for (k = 0; k < 8; k++) | 
| 263 | 3638784 | AV_WN16A(out + k * 2, c->imgbuf[i][k + (j & ~1) * 4] * 0x101); | |
| 264 | 454848 | out += c->pic->linesize[i]; | |
| 265 | } | ||
| 266 | } | ||
| 267 | |||
| 268 | 14214 | return 0; | |
| 269 | } | ||
| 270 | |||
| 271 | 281245 | static void read_vec_pos(GetBitContext *gb, int *vec_pos, int *sel_flag, | |
| 272 | int *sel_len, int *prev) | ||
| 273 | { | ||
| 274 | 281245 | int i, y_flag = 0; | |
| 275 | |||
| 276 | 
        2/2✓ Branch 0 taken 843735 times. 
          ✓ Branch 1 taken 281245 times. 
         | 
      1124980 | for (i = 2; i >= 0; i--) { | 
| 277 | 
        2/2✓ Branch 0 taken 192630 times. 
          ✓ Branch 1 taken 651105 times. 
         | 
      843735 | if (!sel_flag[i]) { | 
| 278 | 192630 | vec_pos[i] = 0; | |
| 279 | 192630 | continue; | |
| 280 | } | ||
| 281 | 
        6/6✓ Branch 0 taken 281245 times. 
          ✓ Branch 1 taken 369860 times. 
          ✓ Branch 2 taken 169880 times. 
          ✓ Branch 3 taken 111365 times. 
          ✓ Branch 5 taken 442701 times. 
          ✓ Branch 6 taken 97039 times. 
         | 
      651105 | if ((!i && !y_flag) || get_bits1(gb)) { | 
| 282 | 
        2/2✓ Branch 0 taken 549560 times. 
          ✓ Branch 1 taken 4506 times. 
         | 
      554066 | if (sel_len[i] > 0) { | 
| 283 | 549560 | int pval = prev[i]; | |
| 284 | 549560 | vec_pos[i] = get_bits(gb, sel_len[i]); | |
| 285 | 
        2/2✓ Branch 0 taken 297455 times. 
          ✓ Branch 1 taken 252105 times. 
         | 
      549560 | if (vec_pos[i] >= pval) | 
| 286 | 297455 | vec_pos[i]++; | |
| 287 | } else { | ||
| 288 | 4506 | vec_pos[i] = !prev[i]; | |
| 289 | } | ||
| 290 | 554066 | y_flag = 1; | |
| 291 | } else { | ||
| 292 | 97039 | vec_pos[i] = prev[i]; | |
| 293 | } | ||
| 294 | } | ||
| 295 | 281245 | } | |
| 296 | |||
| 297 | 8739072 | static int get_value_cached(GetBitContext *gb, int vec_pos, uint8_t *vec, | |
| 298 | int vec_size, int component, int shift, int *prev) | ||
| 299 | { | ||
| 300 | 
        2/2✓ Branch 0 taken 8442194 times. 
          ✓ Branch 1 taken 296878 times. 
         | 
      8739072 | if (vec_pos < vec_size) | 
| 301 | 8442194 | return vec[vec_pos]; | |
| 302 | 
        2/2✓ Branch 1 taken 46525 times. 
          ✓ Branch 2 taken 250353 times. 
         | 
      296878 | if (!get_bits1(gb)) | 
| 303 | 46525 | return prev[component]; | |
| 304 | 250353 | prev[component] = get_bits(gb, 8 - shift) << shift; | |
| 305 | 250353 | return prev[component]; | |
| 306 | } | ||
| 307 | |||
| 308 | #define MKVAL(vals) ((vals)[0] | ((vals)[1] << 3) | ((vals)[2] << 6)) | ||
| 309 | |||
| 310 | /* Image mode - the hardest to comprehend MSS4 coding mode. | ||
| 311 | * | ||
| 312 | * In this mode all three 16x16 blocks are coded together with a method | ||
| 313 | * remotely similar to the methods employed in MSS1-MSS3. | ||
| 314 | * The idea is that every component has a vector of 1-4 most common symbols | ||
| 315 | * and an escape mode for reading new value from the bitstream. Decoding | ||
| 316 | * consists of retrieving pixel values from the vector or reading new ones | ||
| 317 | * from the bitstream; depending on flags read from the bitstream, these vector | ||
| 318 | * positions can be updated or reused from the state of the previous line | ||
| 319 | * or previous pixel. | ||
| 320 | */ | ||
| 321 | 11379 | static int mss4_decode_image_block(MSS4Context *ctx, GetBitContext *gb, | |
| 322 | uint8_t *picdst[3], int mb_x, int mb_y) | ||
| 323 | { | ||
| 324 | uint8_t vec[3][4]; | ||
| 325 | int vec_len[3]; | ||
| 326 | int sel_len[3], sel_flag[3]; | ||
| 327 | int i, j, k, mode, split; | ||
| 328 | 11379 | int prev_vec1 = 0, prev_split = 0; | |
| 329 | 11379 | int vals[3] = { 0 }; | |
| 330 | 11379 | int prev_pix[3] = { 0 }; | |
| 331 | 11379 | int prev_mode[16] = { 0 }; | |
| 332 | uint8_t *dst[3]; | ||
| 333 | |||
| 334 | 
        1/2✗ Branch 0 not taken. 
          ✓ Branch 1 taken 11379 times. 
         | 
      11379 | const int val_shift = ctx->quality == 100 ? 0 : 2; | 
| 335 | |||
| 336 | 
        2/2✓ Branch 0 taken 34137 times. 
          ✓ Branch 1 taken 11379 times. 
         | 
      45516 | for (i = 0; i < 3; i++) | 
| 337 | 34137 | dst[i] = ctx->imgbuf[i]; | |
| 338 | |||
| 339 | 
        2/2✓ Branch 0 taken 34137 times. 
          ✓ Branch 1 taken 11379 times. 
         | 
      45516 | for (i = 0; i < 3; i++) { | 
| 340 | 34137 | vec_len[i] = vec_len_syms[!!i][get_unary(gb, 0, 3)]; | |
| 341 | 
        2/2✓ Branch 0 taken 95302 times. 
          ✓ Branch 1 taken 34137 times. 
         | 
      129439 | for (j = 0; j < vec_len[i]; j++) { | 
| 342 | 95302 | vec[i][j] = get_coeff(gb, &vec_entry_vlc[!!i], 5, 1); | |
| 343 | 95302 | vec[i][j] += ctx->prev_vec[i][j]; | |
| 344 | 95302 | ctx->prev_vec[i][j] = vec[i][j]; | |
| 345 | } | ||
| 346 | 34137 | sel_flag[i] = vec_len[i] > 1; | |
| 347 | 34137 | sel_len[i] = vec_len[i] > 2 ? vec_len[i] - 2 : 0; | |
| 348 | } | ||
| 349 | |||
| 350 | 
        2/2✓ Branch 0 taken 182064 times. 
          ✓ Branch 1 taken 11379 times. 
         | 
      193443 | for (j = 0; j < 16; j++) { | 
| 351 | 
        2/2✓ Branch 1 taken 56004 times. 
          ✓ Branch 2 taken 126060 times. 
         | 
      182064 | if (get_bits1(gb)) { | 
| 352 | 56004 | split = 0; | |
| 353 | 
        2/2✓ Branch 1 taken 35860 times. 
          ✓ Branch 2 taken 20144 times. 
         | 
      56004 | if (get_bits1(gb)) { | 
| 354 | 35860 | prev_mode[0] = 0; | |
| 355 | 35860 | vals[0] = vals[1] = vals[2] = 0; | |
| 356 | 35860 | mode = 2; | |
| 357 | } else { | ||
| 358 | 20144 | mode = get_bits1(gb); | |
| 359 | 
        2/2✓ Branch 0 taken 3817 times. 
          ✓ Branch 1 taken 16327 times. 
         | 
      20144 | if (mode) | 
| 360 | 3817 | split = get_bits(gb, 4); | |
| 361 | } | ||
| 362 | 
        2/2✓ Branch 0 taken 896064 times. 
          ✓ Branch 1 taken 56004 times. 
         | 
      952068 | for (i = 0; i < 16; i++) { | 
| 363 | 
        2/2✓ Branch 0 taken 322304 times. 
          ✓ Branch 1 taken 573760 times. 
         | 
      896064 | if (mode <= 1) { | 
| 364 | 322304 | vals[0] = prev_mode[i] & 7; | |
| 365 | 322304 | vals[1] = (prev_mode[i] >> 3) & 7; | |
| 366 | 322304 | vals[2] = prev_mode[i] >> 6; | |
| 367 | 
        4/4✓ Branch 0 taken 61072 times. 
          ✓ Branch 1 taken 261232 times. 
          ✓ Branch 2 taken 3817 times. 
          ✓ Branch 3 taken 57255 times. 
         | 
      322304 | if (mode == 1 && i == split) { | 
| 368 | 3817 | read_vec_pos(gb, vals, sel_flag, sel_len, vals); | |
| 369 | } | ||
| 370 | 
        1/2✓ Branch 0 taken 573760 times. 
          ✗ Branch 1 not taken. 
         | 
      573760 | } else if (mode == 2) { | 
| 371 | 
        2/2✓ Branch 1 taken 261389 times. 
          ✓ Branch 2 taken 312371 times. 
         | 
      573760 | if (get_bits1(gb)) | 
| 372 | 261389 | read_vec_pos(gb, vals, sel_flag, sel_len, vals); | |
| 373 | } | ||
| 374 | 
        2/2✓ Branch 0 taken 2688192 times. 
          ✓ Branch 1 taken 896064 times. 
         | 
      3584256 | for (k = 0; k < 3; k++) | 
| 375 | 2688192 | *dst[k]++ = get_value_cached(gb, vals[k], vec[k], | |
| 376 | vec_len[k], k, | ||
| 377 | val_shift, prev_pix); | ||
| 378 | 896064 | prev_mode[i] = MKVAL(vals); | |
| 379 | } | ||
| 380 | } else { | ||
| 381 | 
        2/2✓ Branch 1 taken 21425 times. 
          ✓ Branch 2 taken 104635 times. 
         | 
      126060 | if (get_bits1(gb)) { | 
| 382 | 21425 | split = get_bits(gb, 4); | |
| 383 | 
        2/2✓ Branch 0 taken 15525 times. 
          ✓ Branch 1 taken 5900 times. 
         | 
      21425 | if (split >= prev_split) | 
| 384 | 15525 | split++; | |
| 385 | 21425 | prev_split = split; | |
| 386 | } else { | ||
| 387 | 104635 | split = prev_split; | |
| 388 | } | ||
| 389 | 
        2/2✓ Branch 0 taken 109261 times. 
          ✓ Branch 1 taken 16799 times. 
         | 
      126060 | if (split) { | 
| 390 | 109261 | vals[0] = prev_mode[0] & 7; | |
| 391 | 109261 | vals[1] = (prev_mode[0] >> 3) & 7; | |
| 392 | 109261 | vals[2] = prev_mode[0] >> 6; | |
| 393 | 
        2/2✓ Branch 0 taken 327783 times. 
          ✓ Branch 1 taken 109261 times. 
         | 
      437044 | for (i = 0; i < 3; i++) { | 
| 394 | 
        2/2✓ Branch 0 taken 5114922 times. 
          ✓ Branch 1 taken 327783 times. 
         | 
      5442705 | for (k = 0; k < split; k++) { | 
| 395 | 5114922 | *dst[i]++ = get_value_cached(gb, vals[i], vec[i], | |
| 396 | vec_len[i], i, val_shift, | ||
| 397 | prev_pix); | ||
| 398 | 5114922 | prev_mode[k] = MKVAL(vals); | |
| 399 | } | ||
| 400 | } | ||
| 401 | } | ||
| 402 | |||
| 403 | 
        2/2✓ Branch 0 taken 22314 times. 
          ✓ Branch 1 taken 103746 times. 
         | 
      126060 | if (split != 16) { | 
| 404 | 22314 | vals[0] = prev_vec1 & 7; | |
| 405 | 22314 | vals[1] = (prev_vec1 >> 3) & 7; | |
| 406 | 22314 | vals[2] = prev_vec1 >> 6; | |
| 407 | 
        2/2✓ Branch 1 taken 16039 times. 
          ✓ Branch 2 taken 6275 times. 
         | 
      22314 | if (get_bits1(gb)) { | 
| 408 | 16039 | read_vec_pos(gb, vals, sel_flag, sel_len, vals); | |
| 409 | 16039 | prev_vec1 = MKVAL(vals); | |
| 410 | } | ||
| 411 | 
        2/2✓ Branch 0 taken 66942 times. 
          ✓ Branch 1 taken 22314 times. 
         | 
      89256 | for (i = 0; i < 3; i++) { | 
| 412 | 
        2/2✓ Branch 0 taken 935958 times. 
          ✓ Branch 1 taken 66942 times. 
         | 
      1002900 | for (k = 0; k < 16 - split; k++) { | 
| 413 | 935958 | *dst[i]++ = get_value_cached(gb, vals[i], vec[i], | |
| 414 | vec_len[i], i, val_shift, | ||
| 415 | prev_pix); | ||
| 416 | 935958 | prev_mode[split + k] = MKVAL(vals); | |
| 417 | } | ||
| 418 | } | ||
| 419 | } | ||
| 420 | } | ||
| 421 | } | ||
| 422 | |||
| 423 | 
        2/2✓ Branch 0 taken 34137 times. 
          ✓ Branch 1 taken 11379 times. 
         | 
      45516 | for (i = 0; i < 3; i++) | 
| 424 | 
        2/2✓ Branch 0 taken 546192 times. 
          ✓ Branch 1 taken 34137 times. 
         | 
      580329 | for (j = 0; j < 16; j++) | 
| 425 | 546192 | memcpy(picdst[i] + mb_x * 16 + j * ctx->pic->linesize[i], | |
| 426 | 546192 | ctx->imgbuf[i] + j * 16, 16); | |
| 427 | |||
| 428 | 11379 | return 0; | |
| 429 | } | ||
| 430 | |||
| 431 | 175050 | static inline void mss4_update_dc_cache(MSS4Context *c, int mb_x) | |
| 432 | { | ||
| 433 | int i; | ||
| 434 | |||
| 435 | 175050 | c->dc_cache[0][TOP] = c->prev_dc[0][mb_x * 2 + 1]; | |
| 436 | 175050 | c->dc_cache[0][LEFT] = 0; | |
| 437 | 175050 | c->dc_cache[1][TOP] = 0; | |
| 438 | 175050 | c->dc_cache[1][LEFT] = 0; | |
| 439 | |||
| 440 | 
        2/2✓ Branch 0 taken 350100 times. 
          ✓ Branch 1 taken 175050 times. 
         | 
      525150 | for (i = 0; i < 2; i++) | 
| 441 | 350100 | c->prev_dc[0][mb_x * 2 + i] = 0; | |
| 442 | |||
| 443 | 
        2/2✓ Branch 0 taken 350100 times. 
          ✓ Branch 1 taken 175050 times. 
         | 
      525150 | for (i = 1; i < 3; i++) { | 
| 444 | 350100 | c->dc_cache[i + 1][TOP] = c->prev_dc[i][mb_x]; | |
| 445 | 350100 | c->dc_cache[i + 1][LEFT] = 0; | |
| 446 | 350100 | c->prev_dc[i][mb_x] = 0; | |
| 447 | } | ||
| 448 | 175050 | } | |
| 449 | |||
| 450 | 145 | static int mss4_decode_frame(AVCodecContext *avctx, AVFrame *rframe, | |
| 451 | int *got_frame, AVPacket *avpkt) | ||
| 452 | { | ||
| 453 | 145 | const uint8_t *buf = avpkt->data; | |
| 454 | 145 | int buf_size = avpkt->size; | |
| 455 | 145 | MSS4Context *c = avctx->priv_data; | |
| 456 | GetBitContext gb; | ||
| 457 | GetByteContext bc; | ||
| 458 | uint8_t *dst[3]; | ||
| 459 | int width, height, quality, frame_type; | ||
| 460 | int x, y, i, mb_width, mb_height, blk_type; | ||
| 461 | int ret; | ||
| 462 | |||
| 463 | 
        1/2✗ Branch 0 not taken. 
          ✓ Branch 1 taken 145 times. 
         | 
      145 | if (buf_size < HEADER_SIZE) { | 
| 464 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
| 465 | "Frame should have at least %d bytes, got %d instead\n", | ||
| 466 | HEADER_SIZE, buf_size); | ||
| 467 | ✗ | return AVERROR_INVALIDDATA; | |
| 468 | } | ||
| 469 | |||
| 470 | 145 | bytestream2_init(&bc, buf, buf_size); | |
| 471 | 145 | width = bytestream2_get_be16(&bc); | |
| 472 | 145 | height = bytestream2_get_be16(&bc); | |
| 473 | 145 | bytestream2_skip(&bc, 2); | |
| 474 | 145 | quality = bytestream2_get_byte(&bc); | |
| 475 | 145 | frame_type = bytestream2_get_byte(&bc); | |
| 476 | |||
| 477 | 
        1/2✓ Branch 0 taken 145 times. 
          ✗ Branch 1 not taken. 
         | 
      145 | if (width > avctx->width || | 
| 478 | 
        1/2✗ Branch 0 not taken. 
          ✓ Branch 1 taken 145 times. 
         | 
      145 | height != avctx->height) { | 
| 479 | ✗ | av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions %dx%d\n", | |
| 480 | width, height); | ||
| 481 | ✗ | return AVERROR_INVALIDDATA; | |
| 482 | } | ||
| 483 | 
        1/2✗ Branch 1 not taken. 
          ✓ Branch 2 taken 145 times. 
         | 
      145 | if (av_image_check_size2(width, height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0) | 
| 484 | ✗ | return AVERROR_INVALIDDATA; | |
| 485 | |||
| 486 | 
        2/4✓ Branch 0 taken 145 times. 
          ✗ Branch 1 not taken. 
          ✗ Branch 2 not taken. 
          ✓ Branch 3 taken 145 times. 
         | 
      145 | if (quality < 1 || quality > 100) { | 
| 487 | ✗ | av_log(avctx, AV_LOG_ERROR, "Invalid quality setting %d\n", quality); | |
| 488 | ✗ | return AVERROR_INVALIDDATA; | |
| 489 | } | ||
| 490 | 
        2/4✓ Branch 0 taken 145 times. 
          ✗ Branch 1 not taken. 
          ✗ Branch 2 not taken. 
          ✓ Branch 3 taken 145 times. 
         | 
      145 | if ((frame_type & ~3) || frame_type == 3) { | 
| 491 | ✗ | av_log(avctx, AV_LOG_ERROR, "Invalid frame type %d\n", frame_type); | |
| 492 | ✗ | return AVERROR_INVALIDDATA; | |
| 493 | } | ||
| 494 | |||
| 495 | 
        3/4✓ Branch 0 taken 47 times. 
          ✓ Branch 1 taken 98 times. 
          ✗ Branch 3 not taken. 
          ✓ Branch 4 taken 47 times. 
         | 
      145 | if (frame_type != SKIP_FRAME && !bytestream2_get_bytes_left(&bc)) { | 
| 496 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
| 497 | "Empty frame found but it is not a skip frame.\n"); | ||
| 498 | ✗ | return AVERROR_INVALIDDATA; | |
| 499 | } | ||
| 500 | 145 | mb_width = FFALIGN(width, 16) >> 4; | |
| 501 | 145 | mb_height = FFALIGN(height, 16) >> 4; | |
| 502 | |||
| 503 | 
        3/4✓ Branch 0 taken 47 times. 
          ✓ Branch 1 taken 98 times. 
          ✗ Branch 2 not taken. 
          ✓ Branch 3 taken 47 times. 
         | 
      145 | if (frame_type != SKIP_FRAME && 8*buf_size < 8*HEADER_SIZE + mb_width*mb_height) | 
| 504 | ✗ | return AVERROR_INVALIDDATA; | |
| 505 | |||
| 506 | 
        1/2✗ Branch 1 not taken. 
          ✓ Branch 2 taken 145 times. 
         | 
      145 | if ((ret = ff_reget_buffer(avctx, c->pic, 0)) < 0) | 
| 507 | ✗ | return ret; | |
| 508 | 
        2/2✓ Branch 0 taken 3 times. 
          ✓ Branch 1 taken 142 times. 
         | 
      145 | if (frame_type == INTRA_FRAME) | 
| 509 | 3 | c->pic->flags |= AV_FRAME_FLAG_KEY; | |
| 510 | else | ||
| 511 | 142 | c->pic->flags &= ~AV_FRAME_FLAG_KEY; | |
| 512 | 145 | c->pic->pict_type = (frame_type == INTRA_FRAME) ? AV_PICTURE_TYPE_I | |
| 513 | 
        2/2✓ Branch 0 taken 3 times. 
          ✓ Branch 1 taken 142 times. 
         | 
      145 | : AV_PICTURE_TYPE_P; | 
| 514 | 
        2/2✓ Branch 0 taken 98 times. 
          ✓ Branch 1 taken 47 times. 
         | 
      145 | if (frame_type == SKIP_FRAME) { | 
| 515 | 98 | *got_frame = 1; | |
| 516 | 
        1/2✗ Branch 1 not taken. 
          ✓ Branch 2 taken 98 times. 
         | 
      98 | if ((ret = av_frame_ref(rframe, c->pic)) < 0) | 
| 517 | ✗ | return ret; | |
| 518 | |||
| 519 | 98 | return buf_size; | |
| 520 | } | ||
| 521 | |||
| 522 | 
        2/2✓ Branch 0 taken 2 times. 
          ✓ Branch 1 taken 45 times. 
         | 
      47 | if (c->quality != quality) { | 
| 523 | 2 | c->quality = quality; | |
| 524 | 
        2/2✓ Branch 0 taken 4 times. 
          ✓ Branch 1 taken 2 times. 
         | 
      6 | for (i = 0; i < 2; i++) | 
| 525 | 4 | ff_mss34_gen_quant_mat(c->quant_mat[i], quality, !i); | |
| 526 | } | ||
| 527 | |||
| 528 | 
        1/2✗ Branch 1 not taken. 
          ✓ Branch 2 taken 47 times. 
         | 
      47 | if ((ret = init_get_bits8(&gb, buf + HEADER_SIZE, buf_size - HEADER_SIZE)) < 0) | 
| 529 | ✗ | return ret; | |
| 530 | 47 | dst[0] = c->pic->data[0]; | |
| 531 | 47 | dst[1] = c->pic->data[1]; | |
| 532 | 47 | dst[2] = c->pic->data[2]; | |
| 533 | |||
| 534 | 47 | memset(c->prev_vec, 0, sizeof(c->prev_vec)); | |
| 535 | 
        2/2✓ Branch 0 taken 2472 times. 
          ✓ Branch 1 taken 47 times. 
         | 
      2519 | for (y = 0; y < mb_height; y++) { | 
| 536 | 2472 | memset(c->dc_cache, 0, sizeof(c->dc_cache)); | |
| 537 | 
        2/2✓ Branch 0 taken 189264 times. 
          ✓ Branch 1 taken 2472 times. 
         | 
      191736 | for (x = 0; x < mb_width; x++) { | 
| 538 | 189264 | blk_type = decode012(&gb); | |
| 539 | 
        3/4✓ Branch 0 taken 14214 times. 
          ✓ Branch 1 taken 11379 times. 
          ✓ Branch 2 taken 163671 times. 
          ✗ Branch 3 not taken. 
         | 
      189264 | switch (blk_type) { | 
| 540 | 14214 | case DCT_BLOCK: | |
| 541 | 
        1/2✗ Branch 1 not taken. 
          ✓ Branch 2 taken 14214 times. 
         | 
      14214 | if (mss4_decode_dct_block(c, &gb, dst, x, y) < 0) { | 
| 542 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
| 543 | "Error decoding DCT block %d,%d\n", | ||
| 544 | x, y); | ||
| 545 | ✗ | return AVERROR_INVALIDDATA; | |
| 546 | } | ||
| 547 | 14214 | break; | |
| 548 | 11379 | case IMAGE_BLOCK: | |
| 549 | 
        1/2✗ Branch 1 not taken. 
          ✓ Branch 2 taken 11379 times. 
         | 
      11379 | if (mss4_decode_image_block(c, &gb, dst, x, y) < 0) { | 
| 550 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
| 551 | "Error decoding VQ block %d,%d\n", | ||
| 552 | x, y); | ||
| 553 | ✗ | return AVERROR_INVALIDDATA; | |
| 554 | } | ||
| 555 | 11379 | break; | |
| 556 | 163671 | case SKIP_BLOCK: | |
| 557 | 
        1/2✗ Branch 0 not taken. 
          ✓ Branch 1 taken 163671 times. 
         | 
      163671 | if (frame_type == INTRA_FRAME) { | 
| 558 | ✗ | av_log(avctx, AV_LOG_ERROR, "Skip block in intra frame\n"); | |
| 559 | ✗ | return AVERROR_INVALIDDATA; | |
| 560 | } | ||
| 561 | 163671 | break; | |
| 562 | } | ||
| 563 | 
        2/2✓ Branch 0 taken 175050 times. 
          ✓ Branch 1 taken 14214 times. 
         | 
      189264 | if (blk_type != DCT_BLOCK) | 
| 564 | 175050 | mss4_update_dc_cache(c, x); | |
| 565 | } | ||
| 566 | 2472 | dst[0] += c->pic->linesize[0] * 16; | |
| 567 | 2472 | dst[1] += c->pic->linesize[1] * 16; | |
| 568 | 2472 | dst[2] += c->pic->linesize[2] * 16; | |
| 569 | } | ||
| 570 | |||
| 571 | 
        1/2✗ Branch 1 not taken. 
          ✓ Branch 2 taken 47 times. 
         | 
      47 | if ((ret = av_frame_ref(rframe, c->pic)) < 0) | 
| 572 | ✗ | return ret; | |
| 573 | |||
| 574 | 47 | *got_frame = 1; | |
| 575 | |||
| 576 | 47 | return buf_size; | |
| 577 | } | ||
| 578 | |||
| 579 | 4 | static av_cold int mss4_decode_end(AVCodecContext *avctx) | |
| 580 | { | ||
| 581 | 4 | MSS4Context * const c = avctx->priv_data; | |
| 582 | int i; | ||
| 583 | |||
| 584 | 4 | av_frame_free(&c->pic); | |
| 585 | 
        2/2✓ Branch 0 taken 12 times. 
          ✓ Branch 1 taken 4 times. 
         | 
      16 | for (i = 0; i < 3; i++) | 
| 586 | 12 | av_freep(&c->prev_dc[i]); | |
| 587 | |||
| 588 | 4 | return 0; | |
| 589 | } | ||
| 590 | |||
| 591 | 4 | static av_cold int mss4_decode_init(AVCodecContext *avctx) | |
| 592 | { | ||
| 593 | static AVOnce init_static_once = AV_ONCE_INIT; | ||
| 594 | 4 | MSS4Context * const c = avctx->priv_data; | |
| 595 | int i; | ||
| 596 | |||
| 597 | 
        2/2✓ Branch 0 taken 12 times. 
          ✓ Branch 1 taken 4 times. 
         | 
      16 | for (i = 0; i < 3; i++) { | 
| 598 | 
        2/2✓ Branch 0 taken 8 times. 
          ✓ Branch 1 taken 4 times. 
         | 
      12 | c->dc_stride[i] = FFALIGN(avctx->width, 16) >> (2 + !!i); | 
| 599 | 12 | c->prev_dc[i] = av_malloc_array(c->dc_stride[i], sizeof(**c->prev_dc)); | |
| 600 | 
        1/2✗ Branch 0 not taken. 
          ✓ Branch 1 taken 12 times. 
         | 
      12 | if (!c->prev_dc[i]) { | 
| 601 | ✗ | av_log(avctx, AV_LOG_ERROR, "Cannot allocate buffer\n"); | |
| 602 | ✗ | return AVERROR(ENOMEM); | |
| 603 | } | ||
| 604 | } | ||
| 605 | |||
| 606 | 4 | c->pic = av_frame_alloc(); | |
| 607 | 
        1/2✗ Branch 0 not taken. 
          ✓ Branch 1 taken 4 times. 
         | 
      4 | if (!c->pic) | 
| 608 | ✗ | return AVERROR(ENOMEM); | |
| 609 | |||
| 610 | 4 | avctx->pix_fmt = AV_PIX_FMT_YUV444P; | |
| 611 | |||
| 612 | 4 | ff_thread_once(&init_static_once, mss4_init_vlcs); | |
| 613 | |||
| 614 | 4 | return 0; | |
| 615 | } | ||
| 616 | |||
| 617 | const FFCodec ff_mts2_decoder = { | ||
| 618 | .p.name = "mts2", | ||
| 619 | CODEC_LONG_NAME("MS Expression Encoder Screen"), | ||
| 620 | .p.type = AVMEDIA_TYPE_VIDEO, | ||
| 621 | .p.id = AV_CODEC_ID_MTS2, | ||
| 622 | .priv_data_size = sizeof(MSS4Context), | ||
| 623 | .init = mss4_decode_init, | ||
| 624 | .close = mss4_decode_end, | ||
| 625 | FF_CODEC_DECODE_CB(mss4_decode_frame), | ||
| 626 | .p.capabilities = AV_CODEC_CAP_DR1, | ||
| 627 | .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, | ||
| 628 | }; | ||
| 629 |