/src/ffmpeg/libavcodec/scpr.c
Line | Count | Source |
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 | 56.6M | #define TOP 0x01000000 |
34 | 25.4M | #define BOT 0x010000 |
35 | | |
36 | | #include "scpr3.c" |
37 | | |
38 | | static void init_rangecoder(RangeCoder *rc, GetByteContext *gb) |
39 | 956k | { |
40 | 956k | rc->code1 = 0; |
41 | 956k | rc->range = 0xFFFFFFFFU; |
42 | 956k | rc->code = bytestream2_get_be32(gb); |
43 | 956k | } |
44 | | |
45 | | static void reinit_tables(SCPRContext *s) |
46 | 19.7k | { |
47 | 19.7k | int comp, i, j; |
48 | | |
49 | 78.9k | for (comp = 0; comp < 3; comp++) { |
50 | 242M | for (j = 0; j < 4096; j++) { |
51 | 242M | if (s->pixel_model[comp][j].total_freq != 256) { |
52 | 4.04G | for (i = 0; i < 256; i++) |
53 | 4.03G | s->pixel_model[comp][j].freq[i] = 1; |
54 | 267M | for (i = 0; i < 16; i++) |
55 | 252M | s->pixel_model[comp][j].lookup[i] = 16; |
56 | 15.7M | s->pixel_model[comp][j].total_freq = 256; |
57 | 15.7M | } |
58 | 242M | } |
59 | 59.1k | } |
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 | 828k | for (i = 0; i < 6; i++) |
71 | 710k | op[i] = 1; |
72 | 118k | op[6] = 6; |
73 | 118k | } |
74 | | |
75 | 5.07M | for (i = 0; i < 256; i++) { |
76 | 5.05M | s->range_model[i] = 1; |
77 | 5.05M | s->count_model[i] = 1; |
78 | 5.05M | } |
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.6k | s->fill_model[i] = 1; |
84 | 98.6k | } |
85 | 19.7k | s->fill_model[5] = 5; |
86 | | |
87 | 98.6k | 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 | 78.9k | s->sxy_model[j][16] = 16; |
92 | 78.9k | } |
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.87M | { |
104 | 5.87M | rc->code -= cumFreq * rc->range; |
105 | 5.87M | rc->range *= freq; |
106 | | |
107 | 6.13M | while (rc->range < TOP && bytestream2_get_bytes_left(gb) > 0) { |
108 | 263k | uint32_t byte = bytestream2_get_byteu(gb); |
109 | 263k | rc->code = (rc->code << 8) | byte; |
110 | 263k | rc->range <<= 8; |
111 | 263k | } |
112 | | |
113 | 5.87M | return 0; |
114 | 5.87M | } |
115 | | |
116 | | static int get_freq(RangeCoder *rc, uint32_t total_freq, uint32_t *freq) |
117 | 5.89M | { |
118 | 5.89M | if (total_freq == 0) |
119 | 0 | return AVERROR_INVALIDDATA; |
120 | | |
121 | 5.89M | rc->range = rc->range / total_freq; |
122 | | |
123 | 5.89M | if (rc->range == 0) |
124 | 17.1k | return AVERROR_INVALIDDATA; |
125 | | |
126 | 5.87M | *freq = rc->code / rc->range; |
127 | | |
128 | 5.87M | return 0; |
129 | 5.89M | } |
130 | | |
131 | | static int decode0(GetByteContext *gb, RangeCoder *rc, uint32_t cumFreq, uint32_t freq, uint32_t total_freq) |
132 | 19.5M | { |
133 | 19.5M | uint32_t t; |
134 | | |
135 | 19.5M | if (total_freq == 0) |
136 | 0 | return AVERROR_INVALIDDATA; |
137 | | |
138 | 19.5M | t = rc->range * (uint64_t)cumFreq / total_freq; |
139 | | |
140 | 19.5M | rc->code1 += t + 1; |
141 | 19.5M | 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.61M | uint32_t byte = bytestream2_get_byteu(gb); |
145 | 2.61M | rc->code = (rc->code << 8) | byte; |
146 | 2.61M | rc->code1 <<= 8; |
147 | 2.61M | rc->range <<= 8; |
148 | 2.61M | } |
149 | | |
150 | 19.5M | return 0; |
151 | 19.5M | } |
152 | | |
153 | | static int get_freq0(RangeCoder *rc, uint32_t total_freq, uint32_t *freq) |
154 | 19.7M | { |
155 | 19.7M | if (rc->range == 0) |
156 | 15.7k | return AVERROR_INVALIDDATA; |
157 | | |
158 | 19.6M | *freq = total_freq * (uint64_t)(rc->code - rc->code1) / rc->range; |
159 | | |
160 | 19.6M | return 0; |
161 | 19.7M | } |
162 | | |
163 | | static int decode_value(SCPRContext *s, uint32_t *cnt, uint32_t maxc, uint32_t step, uint32_t *rval) |
164 | 22.7M | { |
165 | 22.7M | GetByteContext *gb = &s->gb; |
166 | 22.7M | RangeCoder *rc = &s->rc; |
167 | 22.7M | uint32_t totfr = cnt[maxc]; |
168 | 22.7M | uint32_t value; |
169 | 22.7M | uint32_t c = 0, cumfr = 0, cnt_c = 0; |
170 | 22.7M | int i, ret; |
171 | | |
172 | 22.7M | if ((ret = s->get_freq(rc, totfr, &value)) < 0) |
173 | 29.1k | return ret; |
174 | | |
175 | 798M | while (c < maxc) { |
176 | 798M | cnt_c = cnt[c]; |
177 | 798M | if (value >= cumfr + cnt_c) |
178 | 775M | cumfr += cnt_c; |
179 | 22.6M | else |
180 | 22.6M | break; |
181 | 775M | c++; |
182 | 775M | } |
183 | | |
184 | 22.7M | if (c >= maxc) |
185 | 104k | return AVERROR_INVALIDDATA; |
186 | | |
187 | 22.6M | if ((ret = s->decode(gb, rc, cumfr, cnt_c, totfr)) < 0) |
188 | 0 | return ret; |
189 | | |
190 | 22.6M | cnt[c] = cnt_c + step; |
191 | 22.6M | totfr += step; |
192 | 22.6M | if (totfr > BOT) { |
193 | 86.1k | totfr = 0; |
194 | 7.62M | for (i = 0; i < maxc; i++) { |
195 | 7.53M | uint32_t nc = (cnt[i] >> 1) + 1; |
196 | 7.53M | cnt[i] = nc; |
197 | 7.53M | totfr += nc; |
198 | 7.53M | } |
199 | 86.1k | } |
200 | | |
201 | 22.6M | cnt[maxc] = totfr; |
202 | 22.6M | *rval = c; |
203 | | |
204 | 22.6M | return 0; |
205 | 22.6M | } |
206 | | |
207 | | static int decode_unit(SCPRContext *s, PixelModel *pixel, uint32_t step, uint32_t *rval) |
208 | 2.82M | { |
209 | 2.82M | GetByteContext *gb = &s->gb; |
210 | 2.82M | RangeCoder *rc = &s->rc; |
211 | 2.82M | uint32_t totfr = pixel->total_freq; |
212 | 2.82M | uint32_t value, x = 0, cumfr = 0, cnt_x = 0; |
213 | 2.82M | int i, j, ret, c, cnt_c; |
214 | | |
215 | 2.82M | if ((ret = s->get_freq(rc, totfr, &value)) < 0) |
216 | 3.69k | return ret; |
217 | | |
218 | 30.9M | while (x < 16) { |
219 | 30.9M | cnt_x = pixel->lookup[x]; |
220 | 30.9M | if (value >= cumfr + cnt_x) |
221 | 28.1M | cumfr += cnt_x; |
222 | 2.82M | else |
223 | 2.82M | break; |
224 | 28.1M | x++; |
225 | 28.1M | } |
226 | | |
227 | 2.82M | c = x * 16; |
228 | 2.82M | cnt_c = 0; |
229 | 31.4M | while (c < 256) { |
230 | 31.4M | cnt_c = pixel->freq[c]; |
231 | 31.4M | if (value >= cumfr + cnt_c) |
232 | 28.5M | cumfr += cnt_c; |
233 | 2.82M | else |
234 | 2.82M | break; |
235 | 28.5M | c++; |
236 | 28.5M | } |
237 | 2.82M | if (x >= 16 || c >= 256) { |
238 | 3.54k | return AVERROR_INVALIDDATA; |
239 | 3.54k | } |
240 | | |
241 | 2.82M | if ((ret = s->decode(gb, rc, cumfr, cnt_c, totfr)) < 0) |
242 | 0 | return ret; |
243 | | |
244 | 2.82M | pixel->freq[c] = cnt_c + step; |
245 | 2.82M | pixel->lookup[x] = cnt_x + step; |
246 | 2.82M | totfr += step; |
247 | 2.82M | if (totfr > BOT) { |
248 | 15.2k | totfr = 0; |
249 | 3.91M | for (i = 0; i < 256; i++) { |
250 | 3.90M | uint32_t nc = (pixel->freq[i] >> 1) + 1; |
251 | 3.90M | pixel->freq[i] = nc; |
252 | 3.90M | totfr += nc; |
253 | 3.90M | } |
254 | 259k | for (i = 0; i < 16; i++) { |
255 | 243k | uint32_t sum = 0; |
256 | 243k | uint32_t i16_17 = i << 4; |
257 | 4.14M | for (j = 0; j < 16; j++) |
258 | 3.90M | sum += pixel->freq[i16_17 + j]; |
259 | 243k | pixel->lookup[i] = sum; |
260 | 243k | } |
261 | 15.2k | } |
262 | 2.82M | pixel->total_freq = totfr; |
263 | | |
264 | 2.82M | *rval = c & s->cbits; |
265 | | |
266 | 2.82M | return 0; |
267 | 2.82M | } |
268 | | |
269 | | static int decode_units(SCPRContext *s, uint32_t *r, uint32_t *g, uint32_t *b, |
270 | | int *cx, int *cx1) |
271 | 944k | { |
272 | 944k | const int cxshift = s->cxshift; |
273 | 944k | int ret; |
274 | | |
275 | 944k | ret = decode_unit(s, &s->pixel_model[0][*cx + *cx1], 400, r); |
276 | 944k | if (ret < 0) |
277 | 870 | return ret; |
278 | | |
279 | 943k | *cx1 = (*cx << 6) & 0xFC0; |
280 | 943k | *cx = *r >> cxshift; |
281 | 943k | ret = decode_unit(s, &s->pixel_model[1][*cx + *cx1], 400, g); |
282 | 943k | if (ret < 0) |
283 | 3.87k | return ret; |
284 | | |
285 | 939k | *cx1 = (*cx << 6) & 0xFC0; |
286 | 939k | *cx = *g >> cxshift; |
287 | 939k | ret = decode_unit(s, &s->pixel_model[2][*cx + *cx1], 400, b); |
288 | 939k | if (ret < 0) |
289 | 2.49k | return ret; |
290 | | |
291 | 937k | *cx1 = (*cx << 6) & 0xFC0; |
292 | 937k | *cx = *b >> cxshift; |
293 | | |
294 | 937k | return 0; |
295 | 939k | } |
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 | 716k | while (k < avctx->width + 1) { |
311 | 707k | ret = decode_units(s, &r, &g, &b, &cx, &cx1); |
312 | 707k | if (ret < 0) |
313 | 3.13k | return ret; |
314 | | |
315 | 704k | ret = decode_value(s, s->run_model[0], 256, 400, &run); |
316 | 704k | if (ret < 0) |
317 | 7.48k | return ret; |
318 | 697k | if (run <= 0) |
319 | 577 | return AVERROR_INVALIDDATA; |
320 | | |
321 | 696k | clr = (b << 16) + (g << 8) + r; |
322 | 696k | k += run; |
323 | 107M | while (run-- > 0) { |
324 | 106M | if (y >= avctx->height) |
325 | 502 | return AVERROR_INVALIDDATA; |
326 | | |
327 | 106M | dst[y * linesize + x] = clr; |
328 | 106M | lx = x; |
329 | 106M | ly = y; |
330 | 106M | x++; |
331 | 106M | if (x >= avctx->width) { |
332 | 54.6k | x = 0; |
333 | 54.6k | y++; |
334 | 54.6k | } |
335 | 106M | } |
336 | 696k | } |
337 | 8.03k | off = -linesize - 1; |
338 | 8.03k | 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.02k | return ret; |
344 | 1.00M | if (ptype == 0) { |
345 | 43.5k | ret = decode_units(s, &r, &g, &b, &cx, &cx1); |
346 | 43.5k | if (ret < 0) |
347 | 1.14k | return ret; |
348 | | |
349 | 42.4k | clr = (b << 16) + (g << 8) + r; |
350 | 42.4k | } |
351 | 1.00M | if (ptype > 5) |
352 | 0 | return AVERROR_INVALIDDATA; |
353 | 1.00M | ret = decode_value(s, s->run_model[ptype], 256, 400, &run); |
354 | 1.00M | if (ret < 0) |
355 | 2.35k | return ret; |
356 | 1.00M | if (run <= 0) |
357 | 347 | 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.14k | return ret; |
364 | 1.00M | } |
365 | | |
366 | 1.01k | return 0; |
367 | 8.03k | } |
368 | | |
369 | | static int decompress_p(AVCodecContext *avctx, |
370 | | uint32_t *dst, int linesize, |
371 | | uint32_t *prev, int plinesize) |
372 | 1.00M | { |
373 | 1.00M | SCPRContext *s = avctx->priv_data; |
374 | 1.00M | GetByteContext *gb = &s->gb; |
375 | 1.00M | int ret, temp = 0, min, max, x, y, cx = 0, cx1 = 0; |
376 | 1.00M | int backstep = linesize - avctx->width; |
377 | | |
378 | 1.00M | if (bytestream2_get_byte(gb) == 0) |
379 | 65.6k | return 1; |
380 | 936k | bytestream2_skip(gb, 1); |
381 | 936k | init_rangecoder(&s->rc, gb); |
382 | | |
383 | 936k | ret = decode_value(s, s->range_model, 256, 1, &min); |
384 | 936k | ret |= decode_value(s, s->range_model, 256, 1, &temp); |
385 | 936k | if (ret < 0) |
386 | 83.0k | return ret; |
387 | | |
388 | 853k | min += temp << 8; |
389 | 853k | ret = decode_value(s, s->range_model, 256, 1, &max); |
390 | 853k | ret |= decode_value(s, s->range_model, 256, 1, &temp); |
391 | 853k | if (ret < 0) |
392 | 804 | return ret; |
393 | | |
394 | 853k | max += temp << 8; |
395 | 853k | if (min > max || min >= s->nbcount) |
396 | 38.2k | return AVERROR_INVALIDDATA; |
397 | | |
398 | 814k | memset(s->blocks, 0, sizeof(*s->blocks) * s->nbcount); |
399 | | |
400 | 5.19M | while (min <= max) { |
401 | 5.15M | int fill, count; |
402 | | |
403 | 5.15M | ret = decode_value(s, s->fill_model, 5, 10, &fill); |
404 | 5.15M | ret |= decode_value(s, s->count_model, 256, 20, &count); |
405 | 5.15M | if (ret < 0) |
406 | 9.03k | return ret; |
407 | 5.15M | if (count <= 0) |
408 | 766k | return AVERROR_INVALIDDATA; |
409 | | |
410 | 40.0M | while (min < s->nbcount && count-- > 0) { |
411 | 35.6M | s->blocks[min++] = fill; |
412 | 35.6M | } |
413 | 4.38M | } |
414 | | |
415 | 38.9k | ret = av_frame_copy(s->current_frame, s->last_frame); |
416 | 38.9k | if (ret < 0) |
417 | 452 | return ret; |
418 | | |
419 | 2.67M | for (y = 0; y < s->nby; y++) { |
420 | 180M | for (x = 0; x < s->nbx; x++) { |
421 | 178M | int sy1 = 0, sy2 = 16, sx1 = 0, sx2 = 16; |
422 | | |
423 | 178M | if (s->blocks[y * s->nbx + x] == 0) |
424 | 176M | continue; |
425 | | |
426 | 1.40M | if (((s->blocks[y * s->nbx + x] - 1) & 1) > 0) { |
427 | 1.15M | ret = decode_value(s, s->sxy_model[0], 16, 100, &sx1); |
428 | 1.15M | ret |= decode_value(s, s->sxy_model[1], 16, 100, &sy1); |
429 | 1.15M | ret |= decode_value(s, s->sxy_model[2], 16, 100, &sx2); |
430 | 1.15M | ret |= decode_value(s, s->sxy_model[3], 16, 100, &sy2); |
431 | 1.15M | if (ret < 0) |
432 | 5.83k | return ret; |
433 | | |
434 | 1.15M | sx2++; |
435 | 1.15M | sy2++; |
436 | 1.15M | } |
437 | 1.39M | if (((s->blocks[y * s->nbx + x] - 1) & 2) > 0) { |
438 | 100k | int i, j, by = y * 16, bx = x * 16; |
439 | 100k | int mvx, mvy; |
440 | | |
441 | 100k | ret = decode_value(s, s->mv_model[0], 512, 100, &mvx); |
442 | 100k | ret |= decode_value(s, s->mv_model[1], 512, 100, &mvy); |
443 | 100k | if (ret < 0) |
444 | 1.74k | return ret; |
445 | | |
446 | 98.6k | mvx -= 256; |
447 | 98.6k | mvy -= 256; |
448 | | |
449 | 98.6k | if (by + mvy + sy1 < 0 || bx + mvx + sx1 < 0 || |
450 | 86.8k | by + mvy + sy1 >= avctx->height || bx + mvx + sx1 >= avctx->width) |
451 | 12.8k | return AVERROR_INVALIDDATA; |
452 | | |
453 | 1.01M | for (i = 0; i < sy2 - sy1 && (by + sy1 + i) < avctx->height && (by + mvy + sy1 + i) < avctx->height; i++) { |
454 | 14.9M | for (j = 0; j < sx2 - sx1 && (bx + sx1 + j) < avctx->width && (bx + mvx + sx1 + j) < avctx->width; j++) { |
455 | 14.0M | dst[(by + i + sy1) * linesize + bx + sx1 + j] = prev[(by + mvy + sy1 + i) * plinesize + bx + sx1 + mvx + j]; |
456 | 14.0M | } |
457 | 926k | } |
458 | 1.29M | } else { |
459 | 1.29M | int run, bx = x * 16 + sx1, by = y * 16 + sy1; |
460 | 1.29M | uint32_t r, g, b, clr, ptype = 0; |
461 | | |
462 | 1.29M | if (bx >= avctx->width) |
463 | 2.05k | return AVERROR_INVALIDDATA; |
464 | | |
465 | 1.94M | for (; by < y * 16 + sy2 && by < avctx->height;) { |
466 | 661k | ret = decode_value(s, s->op_model[ptype], 6, 1000, &ptype); |
467 | 661k | if (ret < 0) |
468 | 1.52k | return ret; |
469 | 659k | if (ptype == 0) { |
470 | 192k | ret = decode_units(s, &r, &g, &b, &cx, &cx1); |
471 | 192k | if (ret < 0) |
472 | 2.95k | return ret; |
473 | | |
474 | 189k | clr = (b << 16) + (g << 8) + r; |
475 | 189k | } |
476 | 656k | if (ptype > 5) |
477 | 0 | return AVERROR_INVALIDDATA; |
478 | 656k | ret = decode_value(s, s->run_model[ptype], 256, 400, &run); |
479 | 656k | if (ret < 0) |
480 | 2.21k | return ret; |
481 | 654k | if (run <= 0) |
482 | 2.13k | return AVERROR_INVALIDDATA; |
483 | | |
484 | 652k | ret = decode_run_p(avctx, ptype, run, x, y, clr, |
485 | 652k | dst, prev, linesize, plinesize, &bx, &by, |
486 | 652k | backstep, sx1, sx2, &cx, &cx1); |
487 | 652k | if (ret < 0) |
488 | 3.89k | return ret; |
489 | 652k | } |
490 | 1.29M | } |
491 | 1.39M | } |
492 | 2.67M | } |
493 | | |
494 | 3.26k | return 0; |
495 | 38.4k | } |
496 | | |
497 | | static int decode_frame(AVCodecContext *avctx, AVFrame *frame, |
498 | | int *got_frame, AVPacket *avpkt) |
499 | 1.18M | { |
500 | 1.18M | SCPRContext *s = avctx->priv_data; |
501 | 1.18M | GetByteContext *gb = &s->gb; |
502 | 1.18M | int ret, type; |
503 | | |
504 | 1.18M | if (avctx->bits_per_coded_sample == 16) { |
505 | 934k | if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) |
506 | 588 | return ret; |
507 | 934k | } |
508 | | |
509 | 1.18M | if ((ret = ff_reget_buffer(avctx, s->current_frame, 0)) < 0) |
510 | 2.22k | return ret; |
511 | | |
512 | 1.18M | bytestream2_init(gb, avpkt->data, avpkt->size); |
513 | | |
514 | 1.18M | type = bytestream2_peek_byte(gb); |
515 | | |
516 | 1.18M | if (type == 2) { |
517 | 8.44k | s->version = 1; |
518 | 8.44k | s->get_freq = get_freq0; |
519 | 8.44k | s->decode = decode0; |
520 | 8.44k | frame->flags |= AV_FRAME_FLAG_KEY; |
521 | 8.44k | ret = decompress_i(avctx, (uint32_t *)s->current_frame->data[0], |
522 | 8.44k | s->current_frame->linesize[0] / 4); |
523 | 1.17M | } else if (type == 18) { |
524 | 11.2k | s->version = 2; |
525 | 11.2k | s->get_freq = get_freq; |
526 | 11.2k | s->decode = decode; |
527 | 11.2k | frame->flags |= AV_FRAME_FLAG_KEY; |
528 | 11.2k | ret = decompress_i(avctx, (uint32_t *)s->current_frame->data[0], |
529 | 11.2k | s->current_frame->linesize[0] / 4); |
530 | 1.16M | } else if (type == 34) { |
531 | 20.0k | frame->flags |= AV_FRAME_FLAG_KEY; |
532 | 20.0k | s->version = 3; |
533 | 20.0k | ret = decompress_i3(avctx, (uint32_t *)s->current_frame->data[0], |
534 | 20.0k | s->current_frame->linesize[0] / 4); |
535 | 1.14M | } else if (type == 17 || type == 33) { |
536 | 5.50k | uint32_t clr, *dst = (uint32_t *)s->current_frame->data[0]; |
537 | 5.50k | int y; |
538 | | |
539 | 5.50k | if (bytestream2_get_bytes_left(gb) < 3) |
540 | 360 | return AVERROR_INVALIDDATA; |
541 | | |
542 | 5.14k | frame->flags |= AV_FRAME_FLAG_KEY; |
543 | 5.14k | bytestream2_skip(gb, 1); |
544 | 5.14k | if (avctx->bits_per_coded_sample == 16) { |
545 | 2.08k | uint16_t value = bytestream2_get_le16(gb); |
546 | 2.08k | int r, g, b; |
547 | | |
548 | 2.08k | r = (value ) & 31; |
549 | 2.08k | g = (value >> 5) & 31; |
550 | 2.08k | b = (value >> 10) & 31; |
551 | 2.08k | clr = (r << 16) + (g << 8) + b; |
552 | 3.06k | } else { |
553 | 3.06k | clr = bytestream2_get_le24(gb); |
554 | 3.06k | } |
555 | 63.3M | for (y = 0; y < avctx->height; y++) { |
556 | 63.3M | dst[0] = clr; |
557 | 63.3M | av_memcpy_backptr((uint8_t*)(dst+1), 4, 4*avctx->width - 4); |
558 | 63.3M | dst += s->current_frame->linesize[0] / 4; |
559 | 63.3M | } |
560 | 1.13M | } else if (type == 0 || type == 1) { |
561 | 1.11M | frame->flags &= ~AV_FRAME_FLAG_KEY; |
562 | | |
563 | 1.11M | if (s->version == 1 || s->version == 2) |
564 | 1.00M | ret = decompress_p(avctx, (uint32_t *)s->current_frame->data[0], |
565 | 1.00M | s->current_frame->linesize[0] / 4, |
566 | 1.00M | (uint32_t *)s->last_frame->data[0], |
567 | 1.00M | s->last_frame->linesize[0] / 4); |
568 | 116k | else |
569 | 116k | ret = decompress_p3(avctx, (uint32_t *)s->current_frame->data[0], |
570 | 116k | s->current_frame->linesize[0] / 4, |
571 | 116k | (uint32_t *)s->last_frame->data[0], |
572 | 116k | s->last_frame->linesize[0] / 4); |
573 | 1.11M | if (ret == 1) |
574 | 71.0k | return avpkt->size; |
575 | 1.11M | } else { |
576 | 19.8k | return AVERROR_PATCHWELCOME; |
577 | 19.8k | } |
578 | | |
579 | 1.09M | if (ret < 0) |
580 | 1.07M | return ret; |
581 | | |
582 | 18.6k | if (bytestream2_get_bytes_left(gb) > 5) |
583 | 13.4k | return AVERROR_INVALIDDATA; |
584 | | |
585 | 5.15k | if (avctx->bits_per_coded_sample != 16) { |
586 | 2.88k | ret = av_frame_ref(frame, s->current_frame); |
587 | 2.88k | if (ret < 0) |
588 | 0 | return ret; |
589 | 2.88k | } else { |
590 | 2.27k | uint8_t *dst = frame->data[0]; |
591 | 2.27k | int x, y; |
592 | | |
593 | 2.27k | ret = av_frame_copy(frame, s->current_frame); |
594 | 2.27k | if (ret < 0) |
595 | 0 | return ret; |
596 | | |
597 | | // scale up each sample by 8 |
598 | 13.1M | for (y = 0; y < avctx->height; y++) { |
599 | | // If the image is sufficiently aligned, compute 8 samples at once |
600 | 13.1M | if (!(((uintptr_t)dst) & 7)) { |
601 | 13.1M | uint64_t *dst64 = (uint64_t *)dst; |
602 | 13.1M | int w = avctx->width>>1; |
603 | 753M | for (x = 0; x < w; x++) { |
604 | 740M | dst64[x] = (dst64[x] << 3) & 0xFCFCFCFCFCFCFCFCULL; |
605 | 740M | } |
606 | 13.1M | x *= 8; |
607 | 13.1M | } else |
608 | 0 | x = 0; |
609 | 23.6M | for (; x < avctx->width * 4; x++) { |
610 | 10.5M | dst[x] = dst[x] << 3; |
611 | 10.5M | } |
612 | 13.1M | dst += frame->linesize[0]; |
613 | 13.1M | } |
614 | 2.27k | } |
615 | | |
616 | 5.15k | frame->pict_type = (frame->flags & AV_FRAME_FLAG_KEY) ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; |
617 | | |
618 | 5.15k | FFSWAP(AVFrame *, s->current_frame, s->last_frame); |
619 | | |
620 | 5.15k | frame->data[0] += frame->linesize[0] * (avctx->height - 1); |
621 | 5.15k | frame->linesize[0] *= -1; |
622 | | |
623 | 5.15k | *got_frame = 1; |
624 | | |
625 | 5.15k | return avpkt->size; |
626 | 5.15k | } |
627 | | |
628 | | static av_cold int decode_init(AVCodecContext *avctx) |
629 | 2.10k | { |
630 | 2.10k | SCPRContext *s = avctx->priv_data; |
631 | | |
632 | 2.10k | switch (avctx->bits_per_coded_sample) { |
633 | 599 | case 16: avctx->pix_fmt = AV_PIX_FMT_RGB0; break; |
634 | 1.24k | case 24: |
635 | 1.38k | case 32: avctx->pix_fmt = AV_PIX_FMT_BGR0; break; |
636 | 119 | default: |
637 | 119 | av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n", avctx->bits_per_coded_sample); |
638 | 119 | return AVERROR_INVALIDDATA; |
639 | 2.10k | } |
640 | | |
641 | 1.98k | s->get_freq = get_freq0; |
642 | 1.98k | s->decode = decode0; |
643 | | |
644 | 1.98k | s->cxshift = avctx->bits_per_coded_sample == 16 ? 0 : 2; |
645 | 1.98k | s->cbits = avctx->bits_per_coded_sample == 16 ? 0x1F : 0xFF; |
646 | 1.98k | s->nbx = (avctx->width + 15) / 16; |
647 | 1.98k | s->nby = (avctx->height + 15) / 16; |
648 | 1.98k | s->nbcount = s->nbx * s->nby; |
649 | 1.98k | s->blocks = av_malloc_array(s->nbcount, sizeof(*s->blocks)); |
650 | 1.98k | if (!s->blocks) |
651 | 0 | return AVERROR(ENOMEM); |
652 | | |
653 | 1.98k | s->last_frame = av_frame_alloc(); |
654 | 1.98k | s->current_frame = av_frame_alloc(); |
655 | 1.98k | if (!s->last_frame || !s->current_frame) |
656 | 0 | return AVERROR(ENOMEM); |
657 | | |
658 | 1.98k | return 0; |
659 | 1.98k | } |
660 | | |
661 | | static av_cold int decode_close(AVCodecContext *avctx) |
662 | 2.10k | { |
663 | 2.10k | SCPRContext *s = avctx->priv_data; |
664 | | |
665 | 2.10k | av_freep(&s->blocks); |
666 | 2.10k | av_frame_free(&s->last_frame); |
667 | 2.10k | av_frame_free(&s->current_frame); |
668 | | |
669 | 2.10k | return 0; |
670 | 2.10k | } |
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 | | }; |