/src/ffmpeg/libavcodec/scpr.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * ScreenPressor decoder |
3 | | * |
4 | | * Copyright (c) 2017 Paul B Mahol |
5 | | * |
6 | | * This file is part of FFmpeg. |
7 | | * |
8 | | * FFmpeg is free software; you can redistribute it and/or |
9 | | * modify it under the terms of the GNU Lesser General Public |
10 | | * License as published by the Free Software Foundation; either |
11 | | * version 2.1 of the License, or (at your option) any later version. |
12 | | * |
13 | | * FFmpeg is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | | * Lesser General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU Lesser General Public |
19 | | * License along with FFmpeg; if not, write to the Free Software |
20 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
21 | | */ |
22 | | |
23 | | #include <string.h> |
24 | | |
25 | | #include "libavutil/mem.h" |
26 | | #include "avcodec.h" |
27 | | #include "bytestream.h" |
28 | | #include "codec_internal.h" |
29 | | #include "decode.h" |
30 | | #include "scpr.h" |
31 | | #include "scpr3.h" |
32 | | |
33 | 55.8M | #define TOP 0x01000000 |
34 | 25.2M | #define BOT 0x010000 |
35 | | |
36 | | #include "scpr3.c" |
37 | | |
38 | | static void init_rangecoder(RangeCoder *rc, GetByteContext *gb) |
39 | 926k | { |
40 | 926k | rc->code1 = 0; |
41 | 926k | rc->range = 0xFFFFFFFFU; |
42 | 926k | rc->code = bytestream2_get_be32(gb); |
43 | 926k | } |
44 | | |
45 | | static void reinit_tables(SCPRContext *s) |
46 | 19.7k | { |
47 | 19.7k | int comp, i, j; |
48 | | |
49 | 79.0k | for (comp = 0; comp < 3; comp++) { |
50 | 243M | for (j = 0; j < 4096; j++) { |
51 | 242M | if (s->pixel_model[comp][j].total_freq != 256) { |
52 | 4.19G | for (i = 0; i < 256; i++) |
53 | 4.17G | s->pixel_model[comp][j].freq[i] = 1; |
54 | 277M | for (i = 0; i < 16; i++) |
55 | 261M | s->pixel_model[comp][j].lookup[i] = 16; |
56 | 16.3M | s->pixel_model[comp][j].total_freq = 256; |
57 | 16.3M | } |
58 | 242M | } |
59 | 59.3k | } |
60 | | |
61 | 138k | for (j = 0; j < 6; j++) { |
62 | 118k | uint32_t *p = s->run_model[j]; |
63 | 30.4M | for (i = 0; i < 256; i++) |
64 | 30.3M | p[i] = 1; |
65 | 118k | p[256] = 256; |
66 | 118k | } |
67 | | |
68 | 138k | for (j = 0; j < 6; j++) { |
69 | 118k | uint32_t *op = s->op_model[j]; |
70 | 830k | for (i = 0; i < 6; i++) |
71 | 711k | op[i] = 1; |
72 | 118k | op[6] = 6; |
73 | 118k | } |
74 | | |
75 | 5.08M | for (i = 0; i < 256; i++) { |
76 | 5.06M | s->range_model[i] = 1; |
77 | 5.06M | s->count_model[i] = 1; |
78 | 5.06M | } |
79 | 19.7k | s->range_model[256] = 256; |
80 | 19.7k | s->count_model[256] = 256; |
81 | | |
82 | 118k | for (i = 0; i < 5; i++) { |
83 | 98.8k | s->fill_model[i] = 1; |
84 | 98.8k | } |
85 | 19.7k | s->fill_model[5] = 5; |
86 | | |
87 | 98.8k | for (j = 0; j < 4; j++) { |
88 | 1.34M | for (i = 0; i < 16; i++) { |
89 | 1.26M | s->sxy_model[j][i] = 1; |
90 | 1.26M | } |
91 | 79.0k | s->sxy_model[j][16] = 16; |
92 | 79.0k | } |
93 | | |
94 | 10.1M | for (i = 0; i < 512; i++) { |
95 | 10.1M | s->mv_model[0][i] = 1; |
96 | 10.1M | s->mv_model[1][i] = 1; |
97 | 10.1M | } |
98 | 19.7k | s->mv_model[0][512] = 512; |
99 | 19.7k | s->mv_model[1][512] = 512; |
100 | 19.7k | } |
101 | | |
102 | | static int decode(GetByteContext *gb, RangeCoder *rc, uint32_t cumFreq, uint32_t freq, uint32_t total_freq) |
103 | 5.49M | { |
104 | 5.49M | rc->code -= cumFreq * rc->range; |
105 | 5.49M | rc->range *= freq; |
106 | | |
107 | 5.69M | while (rc->range < TOP && bytestream2_get_bytes_left(gb) > 0) { |
108 | 199k | uint32_t byte = bytestream2_get_byteu(gb); |
109 | 199k | rc->code = (rc->code << 8) | byte; |
110 | 199k | rc->range <<= 8; |
111 | 199k | } |
112 | | |
113 | 5.49M | return 0; |
114 | 5.49M | } |
115 | | |
116 | | static int get_freq(RangeCoder *rc, uint32_t total_freq, uint32_t *freq) |
117 | 5.50M | { |
118 | 5.50M | if (total_freq == 0) |
119 | 0 | return AVERROR_INVALIDDATA; |
120 | | |
121 | 5.50M | rc->range = rc->range / total_freq; |
122 | | |
123 | 5.50M | if (rc->range == 0) |
124 | 14.4k | return AVERROR_INVALIDDATA; |
125 | | |
126 | 5.49M | *freq = rc->code / rc->range; |
127 | | |
128 | 5.49M | return 0; |
129 | 5.50M | } |
130 | | |
131 | | static int decode0(GetByteContext *gb, RangeCoder *rc, uint32_t cumFreq, uint32_t freq, uint32_t total_freq) |
132 | 19.7M | { |
133 | 19.7M | uint32_t t; |
134 | | |
135 | 19.7M | if (total_freq == 0) |
136 | 0 | return AVERROR_INVALIDDATA; |
137 | | |
138 | 19.7M | t = rc->range * (uint64_t)cumFreq / total_freq; |
139 | | |
140 | 19.7M | rc->code1 += t + 1; |
141 | 19.7M | rc->range = rc->range * (uint64_t)(freq + cumFreq) / total_freq - (t + 1); |
142 | | |
143 | 22.2M | while (rc->range < TOP && bytestream2_get_bytes_left(gb) > 0) { |
144 | 2.47M | uint32_t byte = bytestream2_get_byteu(gb); |
145 | 2.47M | rc->code = (rc->code << 8) | byte; |
146 | 2.47M | rc->code1 <<= 8; |
147 | 2.47M | rc->range <<= 8; |
148 | 2.47M | } |
149 | | |
150 | 19.7M | return 0; |
151 | 19.7M | } |
152 | | |
153 | | static int get_freq0(RangeCoder *rc, uint32_t total_freq, uint32_t *freq) |
154 | 19.8M | { |
155 | 19.8M | if (rc->range == 0) |
156 | 20.9k | return AVERROR_INVALIDDATA; |
157 | | |
158 | 19.8M | *freq = total_freq * (uint64_t)(rc->code - rc->code1) / rc->range; |
159 | | |
160 | 19.8M | return 0; |
161 | 19.8M | } |
162 | | |
163 | | static int decode_value(SCPRContext *s, uint32_t *cnt, uint32_t maxc, uint32_t step, uint32_t *rval) |
164 | 23.2M | { |
165 | 23.2M | GetByteContext *gb = &s->gb; |
166 | 23.2M | RangeCoder *rc = &s->rc; |
167 | 23.2M | uint32_t totfr = cnt[maxc]; |
168 | 23.2M | uint32_t value; |
169 | 23.2M | uint32_t c = 0, cumfr = 0, cnt_c = 0; |
170 | 23.2M | int i, ret; |
171 | | |
172 | 23.2M | if ((ret = s->get_freq(rc, totfr, &value)) < 0) |
173 | 30.2k | return ret; |
174 | | |
175 | 798M | while (c < maxc) { |
176 | 797M | cnt_c = cnt[c]; |
177 | 797M | if (value >= cumfr + cnt_c) |
178 | 774M | cumfr += cnt_c; |
179 | 23.1M | else |
180 | 23.1M | break; |
181 | 774M | c++; |
182 | 774M | } |
183 | | |
184 | 23.2M | if (c >= maxc) |
185 | 105k | return AVERROR_INVALIDDATA; |
186 | | |
187 | 23.1M | if ((ret = s->decode(gb, rc, cumfr, cnt_c, totfr)) < 0) |
188 | 0 | return ret; |
189 | | |
190 | 23.1M | cnt[c] = cnt_c + step; |
191 | 23.1M | totfr += step; |
192 | 23.1M | if (totfr > BOT) { |
193 | 89.3k | totfr = 0; |
194 | 7.09M | for (i = 0; i < maxc; i++) { |
195 | 7.00M | uint32_t nc = (cnt[i] >> 1) + 1; |
196 | 7.00M | cnt[i] = nc; |
197 | 7.00M | totfr += nc; |
198 | 7.00M | } |
199 | 89.3k | } |
200 | | |
201 | 23.1M | cnt[maxc] = totfr; |
202 | 23.1M | *rval = c; |
203 | | |
204 | 23.1M | return 0; |
205 | 23.1M | } |
206 | | |
207 | | static int decode_unit(SCPRContext *s, PixelModel *pixel, uint32_t step, uint32_t *rval) |
208 | 2.09M | { |
209 | 2.09M | GetByteContext *gb = &s->gb; |
210 | 2.09M | RangeCoder *rc = &s->rc; |
211 | 2.09M | uint32_t totfr = pixel->total_freq; |
212 | 2.09M | uint32_t value, x = 0, cumfr = 0, cnt_x = 0; |
213 | 2.09M | int i, j, ret, c, cnt_c; |
214 | | |
215 | 2.09M | if ((ret = s->get_freq(rc, totfr, &value)) < 0) |
216 | 5.21k | return ret; |
217 | | |
218 | 22.0M | while (x < 16) { |
219 | 22.0M | cnt_x = pixel->lookup[x]; |
220 | 22.0M | if (value >= cumfr + cnt_x) |
221 | 20.0M | cumfr += cnt_x; |
222 | 2.08M | else |
223 | 2.08M | break; |
224 | 20.0M | x++; |
225 | 20.0M | } |
226 | | |
227 | 2.08M | c = x * 16; |
228 | 2.08M | cnt_c = 0; |
229 | 22.7M | while (c < 256) { |
230 | 22.7M | cnt_c = pixel->freq[c]; |
231 | 22.7M | if (value >= cumfr + cnt_c) |
232 | 20.6M | cumfr += cnt_c; |
233 | 2.08M | else |
234 | 2.08M | break; |
235 | 20.6M | c++; |
236 | 20.6M | } |
237 | 2.08M | if (x >= 16 || c >= 256) { |
238 | 4.12k | return AVERROR_INVALIDDATA; |
239 | 4.12k | } |
240 | | |
241 | 2.08M | if ((ret = s->decode(gb, rc, cumfr, cnt_c, totfr)) < 0) |
242 | 0 | return ret; |
243 | | |
244 | 2.08M | pixel->freq[c] = cnt_c + step; |
245 | 2.08M | pixel->lookup[x] = cnt_x + step; |
246 | 2.08M | totfr += step; |
247 | 2.08M | if (totfr > BOT) { |
248 | 11.8k | totfr = 0; |
249 | 3.04M | for (i = 0; i < 256; i++) { |
250 | 3.03M | uint32_t nc = (pixel->freq[i] >> 1) + 1; |
251 | 3.03M | pixel->freq[i] = nc; |
252 | 3.03M | totfr += nc; |
253 | 3.03M | } |
254 | 201k | for (i = 0; i < 16; i++) { |
255 | 189k | uint32_t sum = 0; |
256 | 189k | uint32_t i16_17 = i << 4; |
257 | 3.22M | for (j = 0; j < 16; j++) |
258 | 3.03M | sum += pixel->freq[i16_17 + j]; |
259 | 189k | pixel->lookup[i] = sum; |
260 | 189k | } |
261 | 11.8k | } |
262 | 2.08M | pixel->total_freq = totfr; |
263 | | |
264 | 2.08M | *rval = c & s->cbits; |
265 | | |
266 | 2.08M | return 0; |
267 | 2.08M | } |
268 | | |
269 | | static int decode_units(SCPRContext *s, uint32_t *r, uint32_t *g, uint32_t *b, |
270 | | int *cx, int *cx1) |
271 | 699k | { |
272 | 699k | const int cxshift = s->cxshift; |
273 | 699k | int ret; |
274 | | |
275 | 699k | ret = decode_unit(s, &s->pixel_model[0][*cx + *cx1], 400, r); |
276 | 699k | if (ret < 0) |
277 | 1.03k | return ret; |
278 | | |
279 | 698k | *cx1 = (*cx << 6) & 0xFC0; |
280 | 698k | *cx = *r >> cxshift; |
281 | 698k | ret = decode_unit(s, &s->pixel_model[1][*cx + *cx1], 400, g); |
282 | 698k | if (ret < 0) |
283 | 4.57k | return ret; |
284 | | |
285 | 693k | *cx1 = (*cx << 6) & 0xFC0; |
286 | 693k | *cx = *g >> cxshift; |
287 | 693k | ret = decode_unit(s, &s->pixel_model[2][*cx + *cx1], 400, b); |
288 | 693k | if (ret < 0) |
289 | 3.72k | return ret; |
290 | | |
291 | 690k | *cx1 = (*cx << 6) & 0xFC0; |
292 | 690k | *cx = *b >> cxshift; |
293 | | |
294 | 690k | return 0; |
295 | 693k | } |
296 | | |
297 | | static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize) |
298 | 19.7k | { |
299 | 19.7k | SCPRContext *s = avctx->priv_data; |
300 | 19.7k | GetByteContext *gb = &s->gb; |
301 | 19.7k | int cx = 0, cx1 = 0, k = 0; |
302 | 19.7k | int run, off, y = 0, x = 0, ret; |
303 | 19.7k | uint32_t clr = 0, r, g, b, backstep = linesize - avctx->width; |
304 | 19.7k | uint32_t lx, ly, ptype; |
305 | | |
306 | 19.7k | reinit_tables(s); |
307 | 19.7k | bytestream2_skip(gb, 2); |
308 | 19.7k | init_rangecoder(&s->rc, gb); |
309 | | |
310 | 380k | while (k < avctx->width + 1) { |
311 | 371k | ret = decode_units(s, &r, &g, &b, &cx, &cx1); |
312 | 371k | if (ret < 0) |
313 | 2.98k | return ret; |
314 | | |
315 | 368k | ret = decode_value(s, s->run_model[0], 256, 400, &run); |
316 | 368k | if (ret < 0) |
317 | 7.08k | return ret; |
318 | 361k | if (run <= 0) |
319 | 530 | return AVERROR_INVALIDDATA; |
320 | | |
321 | 361k | clr = (b << 16) + (g << 8) + r; |
322 | 361k | k += run; |
323 | 70.7M | while (run-- > 0) { |
324 | 70.4M | if (y >= avctx->height) |
325 | 476 | return AVERROR_INVALIDDATA; |
326 | | |
327 | 70.4M | dst[y * linesize + x] = clr; |
328 | 70.4M | lx = x; |
329 | 70.4M | ly = y; |
330 | 70.4M | x++; |
331 | 70.4M | if (x >= avctx->width) { |
332 | 50.2k | x = 0; |
333 | 50.2k | y++; |
334 | 50.2k | } |
335 | 70.4M | } |
336 | 361k | } |
337 | 8.70k | off = -linesize - 1; |
338 | 8.70k | ptype = 0; |
339 | | |
340 | 1.01M | while (x < avctx->width && y < avctx->height) { |
341 | 1.01M | ret = decode_value(s, s->op_model[ptype], 6, 1000, &ptype); |
342 | 1.01M | if (ret < 0) |
343 | 2.26k | return ret; |
344 | 1.01M | if (ptype == 0) { |
345 | 56.7k | ret = decode_units(s, &r, &g, &b, &cx, &cx1); |
346 | 56.7k | if (ret < 0) |
347 | 1.46k | return ret; |
348 | | |
349 | 55.2k | clr = (b << 16) + (g << 8) + r; |
350 | 55.2k | } |
351 | 1.01M | if (ptype > 5) |
352 | 0 | return AVERROR_INVALIDDATA; |
353 | 1.01M | ret = decode_value(s, s->run_model[ptype], 256, 400, &run); |
354 | 1.01M | if (ret < 0) |
355 | 2.41k | return ret; |
356 | 1.00M | if (run <= 0) |
357 | 321 | return AVERROR_INVALIDDATA; |
358 | | |
359 | 1.00M | ret = decode_run_i(avctx, ptype, run, &x, &y, clr, |
360 | 1.00M | dst, linesize, &lx, &ly, |
361 | 1.00M | backstep, off, &cx, &cx1); |
362 | 1.00M | if (ret < 0) |
363 | 1.25k | return ret; |
364 | 1.00M | } |
365 | | |
366 | 989 | return 0; |
367 | 8.70k | } |
368 | | |
369 | | static int decompress_p(AVCodecContext *avctx, |
370 | | uint32_t *dst, int linesize, |
371 | | uint32_t *prev, int plinesize) |
372 | 979k | { |
373 | 979k | SCPRContext *s = avctx->priv_data; |
374 | 979k | GetByteContext *gb = &s->gb; |
375 | 979k | int ret, temp = 0, min, max, x, y, cx = 0, cx1 = 0; |
376 | 979k | int backstep = linesize - avctx->width; |
377 | | |
378 | 979k | if (bytestream2_get_byte(gb) == 0) |
379 | 72.6k | return 1; |
380 | 906k | bytestream2_skip(gb, 1); |
381 | 906k | init_rangecoder(&s->rc, gb); |
382 | | |
383 | 906k | ret = decode_value(s, s->range_model, 256, 1, &min); |
384 | 906k | ret |= decode_value(s, s->range_model, 256, 1, &temp); |
385 | 906k | if (ret < 0) |
386 | 79.5k | return ret; |
387 | | |
388 | 827k | min += temp << 8; |
389 | 827k | ret = decode_value(s, s->range_model, 256, 1, &max); |
390 | 827k | ret |= decode_value(s, s->range_model, 256, 1, &temp); |
391 | 827k | if (ret < 0) |
392 | 629 | return ret; |
393 | | |
394 | 826k | max += temp << 8; |
395 | 826k | if (min > max || min >= s->nbcount) |
396 | 38.4k | return AVERROR_INVALIDDATA; |
397 | | |
398 | 788k | memset(s->blocks, 0, sizeof(*s->blocks) * s->nbcount); |
399 | | |
400 | 5.24M | while (min <= max) { |
401 | 5.20M | int fill, count; |
402 | | |
403 | 5.20M | ret = decode_value(s, s->fill_model, 5, 10, &fill); |
404 | 5.20M | ret |= decode_value(s, s->count_model, 256, 20, &count); |
405 | 5.20M | if (ret < 0) |
406 | 8.51k | return ret; |
407 | 5.19M | if (count <= 0) |
408 | 742k | return AVERROR_INVALIDDATA; |
409 | | |
410 | 47.5M | while (min < s->nbcount && count-- > 0) { |
411 | 43.0M | s->blocks[min++] = fill; |
412 | 43.0M | } |
413 | 4.45M | } |
414 | | |
415 | 37.1k | ret = av_frame_copy(s->current_frame, s->last_frame); |
416 | 37.1k | if (ret < 0) |
417 | 691 | return ret; |
418 | | |
419 | 2.10M | for (y = 0; y < s->nby; y++) { |
420 | 174M | for (x = 0; x < s->nbx; x++) { |
421 | 172M | int sy1 = 0, sy2 = 16, sx1 = 0, sx2 = 16; |
422 | | |
423 | 172M | if (s->blocks[y * s->nbx + x] == 0) |
424 | 171M | continue; |
425 | | |
426 | 1.56M | if (((s->blocks[y * s->nbx + x] - 1) & 1) > 0) { |
427 | 1.29M | ret = decode_value(s, s->sxy_model[0], 16, 100, &sx1); |
428 | 1.29M | ret |= decode_value(s, s->sxy_model[1], 16, 100, &sy1); |
429 | 1.29M | ret |= decode_value(s, s->sxy_model[2], 16, 100, &sx2); |
430 | 1.29M | ret |= decode_value(s, s->sxy_model[3], 16, 100, &sy2); |
431 | 1.29M | if (ret < 0) |
432 | 7.74k | return ret; |
433 | | |
434 | 1.28M | sx2++; |
435 | 1.28M | sy2++; |
436 | 1.28M | } |
437 | 1.55M | if (((s->blocks[y * s->nbx + x] - 1) & 2) > 0) { |
438 | 120k | int i, j, by = y * 16, bx = x * 16; |
439 | 120k | int mvx, mvy; |
440 | | |
441 | 120k | ret = decode_value(s, s->mv_model[0], 512, 100, &mvx); |
442 | 120k | ret |= decode_value(s, s->mv_model[1], 512, 100, &mvy); |
443 | 120k | if (ret < 0) |
444 | 2.31k | return ret; |
445 | | |
446 | 118k | mvx -= 256; |
447 | 118k | mvy -= 256; |
448 | | |
449 | 118k | if (by + mvy + sy1 < 0 || bx + mvx + sx1 < 0 || |
450 | 118k | by + mvy + sy1 >= avctx->height || bx + mvx + sx1 >= avctx->width) |
451 | 2.39k | return AVERROR_INVALIDDATA; |
452 | | |
453 | 1.40M | for (i = 0; i < sy2 - sy1 && (by + sy1 + i) < avctx->height && (by + mvy + sy1 + i) < avctx->height; i++) { |
454 | 21.0M | for (j = 0; j < sx2 - sx1 && (bx + sx1 + j) < avctx->width && (bx + mvx + sx1 + j) < avctx->width; j++) { |
455 | 19.7M | dst[(by + i + sy1) * linesize + bx + sx1 + j] = prev[(by + mvy + sy1 + i) * plinesize + bx + sx1 + mvx + j]; |
456 | 19.7M | } |
457 | 1.29M | } |
458 | 1.43M | } else { |
459 | 1.43M | int run, bx = x * 16 + sx1, by = y * 16 + sy1; |
460 | 1.43M | uint32_t r, g, b, clr, ptype = 0; |
461 | | |
462 | 1.43M | if (bx >= avctx->width) |
463 | 2.88k | return AVERROR_INVALIDDATA; |
464 | | |
465 | 2.21M | for (; by < y * 16 + sy2 && by < avctx->height;) { |
466 | 796k | ret = decode_value(s, s->op_model[ptype], 6, 1000, &ptype); |
467 | 796k | if (ret < 0) |
468 | 1.43k | return ret; |
469 | 795k | if (ptype == 0) { |
470 | 270k | ret = decode_units(s, &r, &g, &b, &cx, &cx1); |
471 | 270k | if (ret < 0) |
472 | 4.89k | return ret; |
473 | | |
474 | 265k | clr = (b << 16) + (g << 8) + r; |
475 | 265k | } |
476 | 790k | if (ptype > 5) |
477 | 0 | return AVERROR_INVALIDDATA; |
478 | 790k | ret = decode_value(s, s->run_model[ptype], 256, 400, &run); |
479 | 790k | if (ret < 0) |
480 | 3.20k | return ret; |
481 | 787k | if (run <= 0) |
482 | 5.95k | return AVERROR_INVALIDDATA; |
483 | | |
484 | 781k | ret = decode_run_p(avctx, ptype, run, x, y, clr, |
485 | 781k | dst, prev, linesize, plinesize, &bx, &by, |
486 | 781k | backstep, sx1, sx2, &cx, &cx1); |
487 | 781k | if (ret < 0) |
488 | 3.34k | return ret; |
489 | 781k | } |
490 | 1.43M | } |
491 | 1.55M | } |
492 | 2.10M | } |
493 | | |
494 | 2.24k | return 0; |
495 | 36.4k | } |
496 | | |
497 | | static int decode_frame(AVCodecContext *avctx, AVFrame *frame, |
498 | | int *got_frame, AVPacket *avpkt) |
499 | 1.15M | { |
500 | 1.15M | SCPRContext *s = avctx->priv_data; |
501 | 1.15M | GetByteContext *gb = &s->gb; |
502 | 1.15M | int ret, type; |
503 | | |
504 | 1.15M | if (avctx->bits_per_coded_sample == 16) { |
505 | 882k | if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) |
506 | 615 | return ret; |
507 | 882k | } |
508 | | |
509 | 1.15M | if ((ret = ff_reget_buffer(avctx, s->current_frame, 0)) < 0) |
510 | 14.1k | return ret; |
511 | | |
512 | 1.13M | bytestream2_init(gb, avpkt->data, avpkt->size); |
513 | | |
514 | 1.13M | type = bytestream2_peek_byte(gb); |
515 | | |
516 | 1.13M | if (type == 2) { |
517 | 9.05k | s->version = 1; |
518 | 9.05k | s->get_freq = get_freq0; |
519 | 9.05k | s->decode = decode0; |
520 | 9.05k | frame->flags |= AV_FRAME_FLAG_KEY; |
521 | 9.05k | ret = decompress_i(avctx, (uint32_t *)s->current_frame->data[0], |
522 | 9.05k | s->current_frame->linesize[0] / 4); |
523 | 1.12M | } else if (type == 18) { |
524 | 10.7k | s->version = 2; |
525 | 10.7k | s->get_freq = get_freq; |
526 | 10.7k | s->decode = decode; |
527 | 10.7k | frame->flags |= AV_FRAME_FLAG_KEY; |
528 | 10.7k | ret = decompress_i(avctx, (uint32_t *)s->current_frame->data[0], |
529 | 10.7k | s->current_frame->linesize[0] / 4); |
530 | 1.11M | } else if (type == 34) { |
531 | 19.6k | frame->flags |= AV_FRAME_FLAG_KEY; |
532 | 19.6k | s->version = 3; |
533 | 19.6k | ret = decompress_i3(avctx, (uint32_t *)s->current_frame->data[0], |
534 | 19.6k | s->current_frame->linesize[0] / 4); |
535 | 1.09M | } else if (type == 17 || type == 33) { |
536 | 5.13k | uint32_t clr, *dst = (uint32_t *)s->current_frame->data[0]; |
537 | 5.13k | int y; |
538 | | |
539 | 5.13k | if (bytestream2_get_bytes_left(gb) < 3) |
540 | 284 | return AVERROR_INVALIDDATA; |
541 | | |
542 | 4.85k | frame->flags |= AV_FRAME_FLAG_KEY; |
543 | 4.85k | bytestream2_skip(gb, 1); |
544 | 4.85k | if (avctx->bits_per_coded_sample == 16) { |
545 | 1.73k | uint16_t value = bytestream2_get_le16(gb); |
546 | 1.73k | int r, g, b; |
547 | | |
548 | 1.73k | r = (value ) & 31; |
549 | 1.73k | g = (value >> 5) & 31; |
550 | 1.73k | b = (value >> 10) & 31; |
551 | 1.73k | clr = (r << 16) + (g << 8) + b; |
552 | 3.11k | } else { |
553 | 3.11k | clr = bytestream2_get_le24(gb); |
554 | 3.11k | } |
555 | 87.1M | for (y = 0; y < avctx->height; y++) { |
556 | 87.1M | dst[0] = clr; |
557 | 87.1M | av_memcpy_backptr((uint8_t*)(dst+1), 4, 4*avctx->width - 4); |
558 | 87.1M | dst += s->current_frame->linesize[0] / 4; |
559 | 87.1M | } |
560 | 1.09M | } else if (type == 0 || type == 1) { |
561 | 1.06M | frame->flags &= ~AV_FRAME_FLAG_KEY; |
562 | | |
563 | 1.06M | if (s->version == 1 || s->version == 2) |
564 | 979k | ret = decompress_p(avctx, (uint32_t *)s->current_frame->data[0], |
565 | 979k | s->current_frame->linesize[0] / 4, |
566 | 979k | (uint32_t *)s->last_frame->data[0], |
567 | 979k | s->last_frame->linesize[0] / 4); |
568 | 90.1k | else |
569 | 90.1k | ret = decompress_p3(avctx, (uint32_t *)s->current_frame->data[0], |
570 | 90.1k | s->current_frame->linesize[0] / 4, |
571 | 90.1k | (uint32_t *)s->last_frame->data[0], |
572 | 90.1k | s->last_frame->linesize[0] / 4); |
573 | 1.06M | if (ret == 1) |
574 | 81.2k | return avpkt->size; |
575 | 1.06M | } else { |
576 | 21.9k | return AVERROR_PATCHWELCOME; |
577 | 21.9k | } |
578 | | |
579 | 1.03M | if (ret < 0) |
580 | 1.01M | return ret; |
581 | | |
582 | 18.0k | if (bytestream2_get_bytes_left(gb) > 5) |
583 | 13.3k | return AVERROR_INVALIDDATA; |
584 | | |
585 | 4.66k | if (avctx->bits_per_coded_sample != 16) { |
586 | 2.85k | ret = av_frame_ref(frame, s->current_frame); |
587 | 2.85k | if (ret < 0) |
588 | 0 | return ret; |
589 | 2.85k | } else { |
590 | 1.81k | uint8_t *dst = frame->data[0]; |
591 | 1.81k | int x, y; |
592 | | |
593 | 1.81k | ret = av_frame_copy(frame, s->current_frame); |
594 | 1.81k | if (ret < 0) |
595 | 0 | return ret; |
596 | | |
597 | | // scale up each sample by 8 |
598 | 48.5M | for (y = 0; y < avctx->height; y++) { |
599 | | // If the image is sufficiently aligned, compute 8 samples at once |
600 | 48.5M | if (!(((uintptr_t)dst) & 7)) { |
601 | 48.5M | uint64_t *dst64 = (uint64_t *)dst; |
602 | 48.5M | int w = avctx->width>>1; |
603 | 783M | for (x = 0; x < w; x++) { |
604 | 734M | dst64[x] = (dst64[x] << 3) & 0xFCFCFCFCFCFCFCFCULL; |
605 | 734M | } |
606 | 48.5M | x *= 8; |
607 | 48.5M | } else |
608 | 0 | x = 0; |
609 | 61.0M | for (; x < avctx->width * 4; x++) { |
610 | 12.4M | dst[x] = dst[x] << 3; |
611 | 12.4M | } |
612 | 48.5M | dst += frame->linesize[0]; |
613 | 48.5M | } |
614 | 1.81k | } |
615 | | |
616 | 4.66k | frame->pict_type = (frame->flags & AV_FRAME_FLAG_KEY) ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; |
617 | | |
618 | 4.66k | FFSWAP(AVFrame *, s->current_frame, s->last_frame); |
619 | | |
620 | 4.66k | frame->data[0] += frame->linesize[0] * (avctx->height - 1); |
621 | 4.66k | frame->linesize[0] *= -1; |
622 | | |
623 | 4.66k | *got_frame = 1; |
624 | | |
625 | 4.66k | return avpkt->size; |
626 | 4.66k | } |
627 | | |
628 | | static av_cold int decode_init(AVCodecContext *avctx) |
629 | 2.11k | { |
630 | 2.11k | SCPRContext *s = avctx->priv_data; |
631 | | |
632 | 2.11k | switch (avctx->bits_per_coded_sample) { |
633 | 605 | case 16: avctx->pix_fmt = AV_PIX_FMT_RGB0; break; |
634 | 1.28k | case 24: |
635 | 1.39k | case 32: avctx->pix_fmt = AV_PIX_FMT_BGR0; break; |
636 | 110 | default: |
637 | 110 | av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n", avctx->bits_per_coded_sample); |
638 | 110 | return AVERROR_INVALIDDATA; |
639 | 2.11k | } |
640 | | |
641 | 2.00k | s->get_freq = get_freq0; |
642 | 2.00k | s->decode = decode0; |
643 | | |
644 | 2.00k | s->cxshift = avctx->bits_per_coded_sample == 16 ? 0 : 2; |
645 | 2.00k | s->cbits = avctx->bits_per_coded_sample == 16 ? 0x1F : 0xFF; |
646 | 2.00k | s->nbx = (avctx->width + 15) / 16; |
647 | 2.00k | s->nby = (avctx->height + 15) / 16; |
648 | 2.00k | s->nbcount = s->nbx * s->nby; |
649 | 2.00k | s->blocks = av_malloc_array(s->nbcount, sizeof(*s->blocks)); |
650 | 2.00k | if (!s->blocks) |
651 | 0 | return AVERROR(ENOMEM); |
652 | | |
653 | 2.00k | s->last_frame = av_frame_alloc(); |
654 | 2.00k | s->current_frame = av_frame_alloc(); |
655 | 2.00k | if (!s->last_frame || !s->current_frame) |
656 | 0 | return AVERROR(ENOMEM); |
657 | | |
658 | 2.00k | return 0; |
659 | 2.00k | } |
660 | | |
661 | | static av_cold int decode_close(AVCodecContext *avctx) |
662 | 2.11k | { |
663 | 2.11k | SCPRContext *s = avctx->priv_data; |
664 | | |
665 | 2.11k | av_freep(&s->blocks); |
666 | 2.11k | av_frame_free(&s->last_frame); |
667 | 2.11k | av_frame_free(&s->current_frame); |
668 | | |
669 | 2.11k | return 0; |
670 | 2.11k | } |
671 | | |
672 | | const FFCodec ff_scpr_decoder = { |
673 | | .p.name = "scpr", |
674 | | CODEC_LONG_NAME("ScreenPressor"), |
675 | | .p.type = AVMEDIA_TYPE_VIDEO, |
676 | | .p.id = AV_CODEC_ID_SCPR, |
677 | | .priv_data_size = sizeof(SCPRContext), |
678 | | .init = decode_init, |
679 | | .close = decode_close, |
680 | | FF_CODEC_DECODE_CB(decode_frame), |
681 | | .p.capabilities = AV_CODEC_CAP_DR1, |
682 | | .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, |
683 | | }; |