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