blob: 465926af19f3ff8488607b86796fbaa93d2448ae
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 <stdio.h> |
24 | #include <stdlib.h> |
25 | #include <string.h> |
26 | |
27 | #include "avcodec.h" |
28 | #include "bytestream.h" |
29 | #include "internal.h" |
30 | |
31 | #define TOP 0x01000000 |
32 | #define BOT 0x010000 |
33 | |
34 | typedef struct RangeCoder { |
35 | unsigned code; |
36 | unsigned range; |
37 | unsigned code1; |
38 | } RangeCoder; |
39 | |
40 | typedef struct PixelModel { |
41 | unsigned freq[256]; |
42 | unsigned lookup[16]; |
43 | unsigned total_freq; |
44 | } PixelModel; |
45 | |
46 | typedef struct SCPRContext { |
47 | AVFrame *last_frame; |
48 | AVFrame *current_frame; |
49 | GetByteContext gb; |
50 | RangeCoder rc; |
51 | PixelModel pixel_model[3][4096]; |
52 | unsigned op_model[6][7]; |
53 | unsigned run_model[6][257]; |
54 | unsigned range_model[257]; |
55 | unsigned count_model[257]; |
56 | unsigned fill_model[6]; |
57 | unsigned sxy_model[4][17]; |
58 | unsigned mv_model[2][513]; |
59 | unsigned nbx, nby; |
60 | unsigned nbcount; |
61 | unsigned *blocks; |
62 | unsigned cbits; |
63 | int cxshift; |
64 | |
65 | int (*get_freq)(RangeCoder *rc, unsigned total_freq, unsigned *freq); |
66 | int (*decode)(GetByteContext *gb, RangeCoder *rc, unsigned cumFreq, unsigned freq, unsigned total_freq); |
67 | } SCPRContext; |
68 | |
69 | static void init_rangecoder(RangeCoder *rc, GetByteContext *gb) |
70 | { |
71 | rc->code1 = 0; |
72 | rc->range = 0xFFFFFFFFU; |
73 | rc->code = bytestream2_get_be32(gb); |
74 | } |
75 | |
76 | static void reinit_tables(SCPRContext *s) |
77 | { |
78 | int comp, i, j; |
79 | |
80 | for (comp = 0; comp < 3; comp++) { |
81 | for (j = 0; j < 4096; j++) { |
82 | if (s->pixel_model[comp][j].total_freq != 256) { |
83 | for (i = 0; i < 256; i++) |
84 | s->pixel_model[comp][j].freq[i] = 1; |
85 | for (i = 0; i < 16; i++) |
86 | s->pixel_model[comp][j].lookup[i] = 16; |
87 | s->pixel_model[comp][j].total_freq = 256; |
88 | } |
89 | } |
90 | } |
91 | |
92 | for (j = 0; j < 6; j++) { |
93 | unsigned *p = s->run_model[j]; |
94 | for (i = 0; i < 256; i++) |
95 | p[i] = 1; |
96 | p[256] = 256; |
97 | } |
98 | |
99 | for (j = 0; j < 6; j++) { |
100 | unsigned *op = s->op_model[j]; |
101 | for (i = 0; i < 6; i++) |
102 | op[i] = 1; |
103 | op[6] = 6; |
104 | } |
105 | |
106 | for (i = 0; i < 256; i++) { |
107 | s->range_model[i] = 1; |
108 | s->count_model[i] = 1; |
109 | } |
110 | s->range_model[256] = 256; |
111 | s->count_model[256] = 256; |
112 | |
113 | for (i = 0; i < 5; i++) { |
114 | s->fill_model[i] = 1; |
115 | } |
116 | s->fill_model[5] = 5; |
117 | |
118 | for (j = 0; j < 4; j++) { |
119 | for (i = 0; i < 16; i++) { |
120 | s->sxy_model[j][i] = 1; |
121 | } |
122 | s->sxy_model[j][16] = 16; |
123 | } |
124 | |
125 | for (i = 0; i < 512; i++) { |
126 | s->mv_model[0][i] = 1; |
127 | s->mv_model[1][i] = 1; |
128 | } |
129 | s->mv_model[0][512] = 512; |
130 | s->mv_model[1][512] = 512; |
131 | } |
132 | |
133 | static int decode(GetByteContext *gb, RangeCoder *rc, unsigned cumFreq, unsigned freq, unsigned total_freq) |
134 | { |
135 | rc->code -= cumFreq * rc->range; |
136 | rc->range *= freq; |
137 | |
138 | while (rc->range < TOP && bytestream2_get_bytes_left(gb) > 0) { |
139 | unsigned byte = bytestream2_get_byte(gb); |
140 | rc->code = (rc->code << 8) | byte; |
141 | rc->range <<= 8; |
142 | } |
143 | |
144 | return 0; |
145 | } |
146 | |
147 | static int get_freq(RangeCoder *rc, unsigned total_freq, unsigned *freq) |
148 | { |
149 | if (total_freq == 0) |
150 | return AVERROR_INVALIDDATA; |
151 | |
152 | rc->range = rc->range / total_freq; |
153 | |
154 | if (rc->range == 0) |
155 | return AVERROR_INVALIDDATA; |
156 | |
157 | *freq = rc->code / rc->range; |
158 | |
159 | return 0; |
160 | } |
161 | |
162 | static int decode0(GetByteContext *gb, RangeCoder *rc, unsigned cumFreq, unsigned freq, unsigned total_freq) |
163 | { |
164 | int t; |
165 | |
166 | if (total_freq == 0) |
167 | return AVERROR_INVALIDDATA; |
168 | |
169 | t = rc->range * (uint64_t)cumFreq / total_freq; |
170 | |
171 | rc->code1 += t + 1; |
172 | rc->range = rc->range * (uint64_t)(freq + cumFreq) / total_freq - (t + 1); |
173 | |
174 | while (rc->range < TOP && bytestream2_get_bytes_left(gb) > 0) { |
175 | unsigned byte = bytestream2_get_byte(gb); |
176 | rc->code = (rc->code << 8) | byte; |
177 | rc->code1 <<= 8; |
178 | rc->range <<= 8; |
179 | } |
180 | |
181 | return 0; |
182 | } |
183 | |
184 | static int get_freq0(RangeCoder *rc, unsigned total_freq, unsigned *freq) |
185 | { |
186 | if (rc->range == 0) |
187 | return AVERROR_INVALIDDATA; |
188 | |
189 | *freq = total_freq * (uint64_t)(rc->code - rc->code1) / rc->range; |
190 | |
191 | return 0; |
192 | } |
193 | |
194 | static int decode_value(SCPRContext *s, unsigned *cnt, unsigned maxc, unsigned step, unsigned *rval) |
195 | { |
196 | GetByteContext *gb = &s->gb; |
197 | RangeCoder *rc = &s->rc; |
198 | unsigned totfr = cnt[maxc]; |
199 | unsigned value; |
200 | unsigned c = 0, cumfr = 0, cnt_c = 0; |
201 | int i, ret; |
202 | |
203 | if ((ret = s->get_freq(rc, totfr, &value)) < 0) |
204 | return ret; |
205 | |
206 | while (c < maxc) { |
207 | cnt_c = cnt[c]; |
208 | if (value >= cumfr + cnt_c) |
209 | cumfr += cnt_c; |
210 | else |
211 | break; |
212 | c++; |
213 | } |
214 | if ((ret = s->decode(gb, rc, cumfr, cnt_c, totfr)) < 0) |
215 | return ret; |
216 | |
217 | cnt[c] = cnt_c + step; |
218 | totfr += step; |
219 | if (totfr > BOT) { |
220 | totfr = 0; |
221 | for (i = 0; i < maxc; i++) { |
222 | unsigned nc = (cnt[i] >> 1) + 1; |
223 | cnt[i] = nc; |
224 | totfr += nc; |
225 | } |
226 | } |
227 | |
228 | cnt[maxc] = totfr; |
229 | *rval = c; |
230 | |
231 | return 0; |
232 | } |
233 | |
234 | static int decode_unit(SCPRContext *s, PixelModel *pixel, unsigned step, unsigned *rval) |
235 | { |
236 | GetByteContext *gb = &s->gb; |
237 | RangeCoder *rc = &s->rc; |
238 | unsigned totfr = pixel->total_freq; |
239 | unsigned value, x = 0, cumfr = 0, cnt_x = 0; |
240 | int i, j, ret, c, cnt_c; |
241 | |
242 | if ((ret = s->get_freq(rc, totfr, &value)) < 0) |
243 | return ret; |
244 | |
245 | while (x < 16) { |
246 | cnt_x = pixel->lookup[x]; |
247 | if (value >= cumfr + cnt_x) |
248 | cumfr += cnt_x; |
249 | else |
250 | break; |
251 | x++; |
252 | } |
253 | |
254 | c = x * 16; |
255 | cnt_c = 0; |
256 | while (c < 256) { |
257 | cnt_c = pixel->freq[c]; |
258 | if (value >= cumfr + cnt_c) |
259 | cumfr += cnt_c; |
260 | else |
261 | break; |
262 | c++; |
263 | } |
264 | |
265 | if ((ret = s->decode(gb, rc, cumfr, cnt_c, totfr)) < 0) |
266 | return ret; |
267 | |
268 | pixel->freq[c] = cnt_c + step; |
269 | pixel->lookup[x] = cnt_x + step; |
270 | totfr += step; |
271 | if (totfr > BOT) { |
272 | totfr = 0; |
273 | for (i = 0; i < 256; i++) { |
274 | unsigned nc = (pixel->freq[i] >> 1) + 1; |
275 | pixel->freq[i] = nc; |
276 | totfr += nc; |
277 | } |
278 | for (i = 0; i < 16; i++) { |
279 | unsigned sum = 0; |
280 | unsigned i16_17 = i << 4; |
281 | for (j = 0; j < 16; j++) |
282 | sum += pixel->freq[i16_17 + j]; |
283 | pixel->lookup[i] = sum; |
284 | } |
285 | } |
286 | pixel->total_freq = totfr; |
287 | |
288 | *rval = c & s->cbits; |
289 | |
290 | return 0; |
291 | } |
292 | |
293 | static int decompress_i(AVCodecContext *avctx, uint32_t *dst, int linesize) |
294 | { |
295 | SCPRContext *s = avctx->priv_data; |
296 | GetByteContext *gb = &s->gb; |
297 | int cx = 0, cx1 = 0, k = 0, clr = 0; |
298 | int run, r, g, b, off, y = 0, x = 0, z, ret; |
299 | unsigned backstep = linesize - avctx->width; |
300 | const int cxshift = s->cxshift; |
301 | unsigned lx, ly, ptype; |
302 | |
303 | reinit_tables(s); |
304 | bytestream2_skip(gb, 2); |
305 | init_rangecoder(&s->rc, gb); |
306 | |
307 | while (k < avctx->width + 1) { |
308 | ret = decode_unit(s, &s->pixel_model[0][cx + cx1], 400, &r); |
309 | if (ret < 0) |
310 | return ret; |
311 | |
312 | cx1 = (cx << 6) & 0xFC0; |
313 | cx = r >> cxshift; |
314 | ret = decode_unit(s, &s->pixel_model[1][cx + cx1], 400, &g); |
315 | if (ret < 0) |
316 | return ret; |
317 | |
318 | cx1 = (cx << 6) & 0xFC0; |
319 | cx = g >> cxshift; |
320 | ret = decode_unit(s, &s->pixel_model[2][cx + cx1], 400, &b); |
321 | if (ret < 0) |
322 | return ret; |
323 | |
324 | cx1 = (cx << 6) & 0xFC0; |
325 | cx = b >> cxshift; |
326 | |
327 | ret = decode_value(s, s->run_model[0], 256, 400, &run); |
328 | if (ret < 0) |
329 | return ret; |
330 | |
331 | clr = (b << 16) + (g << 8) + r; |
332 | k += run; |
333 | while (run-- > 0) { |
334 | dst[y * linesize + x] = clr; |
335 | lx = x; |
336 | ly = y; |
337 | x++; |
338 | if (x >= avctx->width) { |
339 | x = 0; |
340 | y++; |
341 | } |
342 | } |
343 | } |
344 | off = -linesize - 1; |
345 | ptype = 0; |
346 | |
347 | while (x < avctx->width && y < avctx->height) { |
348 | ret = decode_value(s, s->op_model[ptype], 6, 1000, &ptype); |
349 | if (ret < 0) |
350 | return ret; |
351 | if (ptype == 0) { |
352 | ret = decode_unit(s, &s->pixel_model[0][cx + cx1], 400, &r); |
353 | if (ret < 0) |
354 | return ret; |
355 | |
356 | cx1 = (cx << 6) & 0xFC0; |
357 | cx = r >> cxshift; |
358 | ret = decode_unit(s, &s->pixel_model[1][cx + cx1], 400, &g); |
359 | if (ret < 0) |
360 | return ret; |
361 | |
362 | cx1 = (cx << 6) & 0xFC0; |
363 | cx = g >> cxshift; |
364 | ret = decode_unit(s, &s->pixel_model[2][cx + cx1], 400, &b); |
365 | if (ret < 0) |
366 | return ret; |
367 | |
368 | clr = (b << 16) + (g << 8) + r; |
369 | } |
370 | if (ptype > 5) |
371 | return AVERROR_INVALIDDATA; |
372 | ret = decode_value(s, s->run_model[ptype], 256, 400, &run); |
373 | if (ret < 0) |
374 | return ret; |
375 | |
376 | switch (ptype) { |
377 | case 0: |
378 | while (run-- > 0) { |
379 | if (y >= avctx->height) |
380 | return AVERROR_INVALIDDATA; |
381 | |
382 | dst[y * linesize + x] = clr; |
383 | lx = x; |
384 | ly = y; |
385 | x++; |
386 | if (x >= avctx->width) { |
387 | x = 0; |
388 | y++; |
389 | } |
390 | } |
391 | break; |
392 | case 1: |
393 | while (run-- > 0) { |
394 | if (y >= avctx->height) |
395 | return AVERROR_INVALIDDATA; |
396 | |
397 | dst[y * linesize + x] = dst[ly * linesize + lx]; |
398 | lx = x; |
399 | ly = y; |
400 | x++; |
401 | if (x >= avctx->width) { |
402 | x = 0; |
403 | y++; |
404 | } |
405 | } |
406 | clr = dst[ly * linesize + lx]; |
407 | break; |
408 | case 2: |
409 | while (run-- > 0) { |
410 | if (y < 1 || y >= avctx->height) |
411 | return AVERROR_INVALIDDATA; |
412 | |
413 | clr = dst[y * linesize + x + off + 1]; |
414 | dst[y * linesize + x] = clr; |
415 | lx = x; |
416 | ly = y; |
417 | x++; |
418 | if (x >= avctx->width) { |
419 | x = 0; |
420 | y++; |
421 | } |
422 | } |
423 | break; |
424 | case 4: |
425 | while (run-- > 0) { |
426 | uint8_t *odst = (uint8_t *)dst; |
427 | |
428 | if (y < 1 || y >= avctx->height || |
429 | (y == 1 && x == 0)) |
430 | return AVERROR_INVALIDDATA; |
431 | |
432 | if (x == 0) { |
433 | z = backstep; |
434 | } else { |
435 | z = 0; |
436 | } |
437 | |
438 | r = odst[(ly * linesize + lx) * 4] + |
439 | odst[((y * linesize + x) + off - z) * 4 + 4] - |
440 | odst[((y * linesize + x) + off - z) * 4]; |
441 | g = odst[(ly * linesize + lx) * 4 + 1] + |
442 | odst[((y * linesize + x) + off - z) * 4 + 5] - |
443 | odst[((y * linesize + x) + off - z) * 4 + 1]; |
444 | b = odst[(ly * linesize + lx) * 4 + 2] + |
445 | odst[((y * linesize + x) + off - z) * 4 + 6] - |
446 | odst[((y * linesize + x) + off - z) * 4 + 2]; |
447 | clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF); |
448 | dst[y * linesize + x] = clr; |
449 | lx = x; |
450 | ly = y; |
451 | x++; |
452 | if (x >= avctx->width) { |
453 | x = 0; |
454 | y++; |
455 | } |
456 | } |
457 | break; |
458 | case 5: |
459 | while (run-- > 0) { |
460 | if (y < 1 || y >= avctx->height || |
461 | (y == 1 && x == 0)) |
462 | return AVERROR_INVALIDDATA; |
463 | |
464 | if (x == 0) { |
465 | z = backstep; |
466 | } else { |
467 | z = 0; |
468 | } |
469 | |
470 | clr = dst[y * linesize + x + off - z]; |
471 | dst[y * linesize + x] = clr; |
472 | lx = x; |
473 | ly = y; |
474 | x++; |
475 | if (x >= avctx->width) { |
476 | x = 0; |
477 | y++; |
478 | } |
479 | } |
480 | break; |
481 | } |
482 | |
483 | if (avctx->bits_per_coded_sample == 16) { |
484 | cx1 = (clr & 0x3F00) >> 2; |
485 | cx = (clr & 0xFFFFFF) >> 16; |
486 | } else { |
487 | cx1 = (clr & 0xFC00) >> 4; |
488 | cx = (clr & 0xFFFFFF) >> 18; |
489 | } |
490 | } |
491 | |
492 | return 0; |
493 | } |
494 | |
495 | static int decompress_p(AVCodecContext *avctx, |
496 | uint32_t *dst, int linesize, |
497 | uint32_t *prev, int plinesize) |
498 | { |
499 | SCPRContext *s = avctx->priv_data; |
500 | GetByteContext *gb = &s->gb; |
501 | int ret, temp, min, max, x, y, cx = 0, cx1 = 0; |
502 | int backstep = linesize - avctx->width; |
503 | const int cxshift = s->cxshift; |
504 | |
505 | if (bytestream2_get_byte(gb) == 0) |
506 | return 0; |
507 | bytestream2_skip(gb, 1); |
508 | init_rangecoder(&s->rc, gb); |
509 | |
510 | ret = decode_value(s, s->range_model, 256, 1, &min); |
511 | ret |= decode_value(s, s->range_model, 256, 1, &temp); |
512 | min += temp << 8; |
513 | ret |= decode_value(s, s->range_model, 256, 1, &max); |
514 | ret |= decode_value(s, s->range_model, 256, 1, &temp); |
515 | if (ret < 0) |
516 | return ret; |
517 | |
518 | max += temp << 8; |
519 | memset(s->blocks, 0, sizeof(*s->blocks) * s->nbcount); |
520 | |
521 | while (min <= max) { |
522 | int fill, count; |
523 | |
524 | ret = decode_value(s, s->fill_model, 5, 10, &fill); |
525 | ret |= decode_value(s, s->count_model, 256, 20, &count); |
526 | if (ret < 0) |
527 | return ret; |
528 | |
529 | while (min < s->nbcount && count-- > 0) { |
530 | s->blocks[min++] = fill; |
531 | } |
532 | } |
533 | |
534 | for (y = 0; y < s->nby; y++) { |
535 | for (x = 0; x < s->nbx; x++) { |
536 | int sy1 = 0, sy2 = 16, sx1 = 0, sx2 = 16; |
537 | |
538 | if (s->blocks[y * s->nbx + x] == 0) |
539 | continue; |
540 | |
541 | if (((s->blocks[y * s->nbx + x] - 1) & 1) > 0) { |
542 | ret = decode_value(s, s->sxy_model[0], 16, 100, &sx1); |
543 | ret |= decode_value(s, s->sxy_model[1], 16, 100, &sy1); |
544 | ret |= decode_value(s, s->sxy_model[2], 16, 100, &sx2); |
545 | ret |= decode_value(s, s->sxy_model[3], 16, 100, &sy2); |
546 | if (ret < 0) |
547 | return ret; |
548 | |
549 | sx2++; |
550 | sy2++; |
551 | } |
552 | if (((s->blocks[y * s->nbx + x] - 1) & 2) > 0) { |
553 | int i, j, by = y * 16, bx = x * 16; |
554 | int mvx, mvy; |
555 | |
556 | ret = decode_value(s, s->mv_model[0], 512, 100, &mvx); |
557 | ret |= decode_value(s, s->mv_model[1], 512, 100, &mvy); |
558 | if (ret < 0) |
559 | return ret; |
560 | |
561 | mvx -= 256; |
562 | mvy -= 256; |
563 | |
564 | if (by + mvy + sy1 < 0 || bx + mvx + sx1 < 0 || |
565 | by + mvy + sy1 >= avctx->height || bx + mvx + sx1 >= avctx->width) |
566 | return AVERROR_INVALIDDATA; |
567 | |
568 | for (i = 0; i < sy2 - sy1 && (by + sy1 + i) < avctx->height && (by + mvy + sy1 + i) < avctx->height; i++) { |
569 | for (j = 0; j < sx2 - sx1 && (bx + sx1 + j) < avctx->width && (bx + mvx + sx1 + j) < avctx->width; j++) { |
570 | dst[(by + i + sy1) * linesize + bx + sx1 + j] = prev[(by + mvy + sy1 + i) * plinesize + bx + sx1 + mvx + j]; |
571 | } |
572 | } |
573 | } else { |
574 | int run, r, g, b, z, bx = x * 16 + sx1, by = y * 16 + sy1; |
575 | unsigned clr, ptype = 0; |
576 | |
577 | for (; by < y * 16 + sy2 && by < avctx->height;) { |
578 | ret = decode_value(s, s->op_model[ptype], 6, 1000, &ptype); |
579 | if (ptype == 0) { |
580 | ret = decode_unit(s, &s->pixel_model[0][cx + cx1], 400, &r); |
581 | if (ret < 0) |
582 | return ret; |
583 | |
584 | cx1 = (cx << 6) & 0xFC0; |
585 | cx = r >> cxshift; |
586 | ret = decode_unit(s, &s->pixel_model[1][cx + cx1], 400, &g); |
587 | if (ret < 0) |
588 | return ret; |
589 | |
590 | cx1 = (cx << 6) & 0xFC0; |
591 | cx = g >> cxshift; |
592 | ret = decode_unit(s, &s->pixel_model[2][cx + cx1], 400, &b); |
593 | if (ret < 0) |
594 | return ret; |
595 | |
596 | clr = (b << 16) + (g << 8) + r; |
597 | } |
598 | if (ptype > 5) |
599 | return AVERROR_INVALIDDATA; |
600 | ret = decode_value(s, s->run_model[ptype], 256, 400, &run); |
601 | if (ret < 0) |
602 | return ret; |
603 | |
604 | switch (ptype) { |
605 | case 0: |
606 | while (run-- > 0) { |
607 | if (by >= avctx->height) |
608 | return AVERROR_INVALIDDATA; |
609 | |
610 | dst[by * linesize + bx] = clr; |
611 | bx++; |
612 | if (bx >= x * 16 + sx2 || bx >= avctx->width) { |
613 | bx = x * 16 + sx1; |
614 | by++; |
615 | } |
616 | } |
617 | break; |
618 | case 1: |
619 | while (run-- > 0) { |
620 | if (bx == 0) { |
621 | if (by < 1) |
622 | return AVERROR_INVALIDDATA; |
623 | z = backstep; |
624 | } else { |
625 | z = 0; |
626 | } |
627 | |
628 | if (by >= avctx->height) |
629 | return AVERROR_INVALIDDATA; |
630 | |
631 | clr = dst[by * linesize + bx - 1 - z]; |
632 | dst[by * linesize + bx] = clr; |
633 | bx++; |
634 | if (bx >= x * 16 + sx2 || bx >= avctx->width) { |
635 | bx = x * 16 + sx1; |
636 | by++; |
637 | } |
638 | } |
639 | break; |
640 | case 2: |
641 | while (run-- > 0) { |
642 | if (by < 1 || by >= avctx->height) |
643 | return AVERROR_INVALIDDATA; |
644 | |
645 | clr = dst[(by - 1) * linesize + bx]; |
646 | dst[by * linesize + bx] = clr; |
647 | bx++; |
648 | if (bx >= x * 16 + sx2 || bx >= avctx->width) { |
649 | bx = x * 16 + sx1; |
650 | by++; |
651 | } |
652 | } |
653 | break; |
654 | case 3: |
655 | while (run-- > 0) { |
656 | if (by >= avctx->height) |
657 | return AVERROR_INVALIDDATA; |
658 | |
659 | clr = prev[by * plinesize + bx]; |
660 | dst[by * linesize + bx] = clr; |
661 | bx++; |
662 | if (bx >= x * 16 + sx2 || bx >= avctx->width) { |
663 | bx = x * 16 + sx1; |
664 | by++; |
665 | } |
666 | } |
667 | break; |
668 | case 4: |
669 | while (run-- > 0) { |
670 | uint8_t *odst = (uint8_t *)dst; |
671 | |
672 | if (by < 1 || by >= avctx->height) |
673 | return AVERROR_INVALIDDATA; |
674 | |
675 | if (bx == 0) { |
676 | z = backstep; |
677 | } else { |
678 | z = 0; |
679 | } |
680 | |
681 | r = odst[((by - 1) * linesize + bx) * 4] + |
682 | odst[(by * linesize + bx - 1 - z) * 4] - |
683 | odst[((by - 1) * linesize + bx - 1 - z) * 4]; |
684 | g = odst[((by - 1) * linesize + bx) * 4 + 1] + |
685 | odst[(by * linesize + bx - 1 - z) * 4 + 1] - |
686 | odst[((by - 1) * linesize + bx - 1 - z) * 4 + 1]; |
687 | b = odst[((by - 1) * linesize + bx) * 4 + 2] + |
688 | odst[(by * linesize + bx - 1 - z) * 4 + 2] - |
689 | odst[((by - 1) * linesize + bx - 1 - z) * 4 + 2]; |
690 | clr = ((b & 0xFF) << 16) + ((g & 0xFF) << 8) + (r & 0xFF); |
691 | dst[by * linesize + bx] = clr; |
692 | bx++; |
693 | if (bx >= x * 16 + sx2 || bx >= avctx->width) { |
694 | bx = x * 16 + sx1; |
695 | by++; |
696 | } |
697 | } |
698 | break; |
699 | case 5: |
700 | while (run-- > 0) { |
701 | if (by < 1 || by >= avctx->height) |
702 | return AVERROR_INVALIDDATA; |
703 | |
704 | if (bx == 0) { |
705 | z = backstep; |
706 | } else { |
707 | z = 0; |
708 | } |
709 | |
710 | clr = dst[(by - 1) * linesize + bx - 1 - z]; |
711 | dst[by * linesize + bx] = clr; |
712 | bx++; |
713 | if (bx >= x * 16 + sx2 || bx >= avctx->width) { |
714 | bx = x * 16 + sx1; |
715 | by++; |
716 | } |
717 | } |
718 | break; |
719 | } |
720 | |
721 | if (avctx->bits_per_coded_sample == 16) { |
722 | cx1 = (clr & 0x3F00) >> 2; |
723 | cx = (clr & 0xFFFFFF) >> 16; |
724 | } else { |
725 | cx1 = (clr & 0xFC00) >> 4; |
726 | cx = (clr & 0xFFFFFF) >> 18; |
727 | } |
728 | } |
729 | } |
730 | } |
731 | } |
732 | |
733 | return 0; |
734 | } |
735 | |
736 | static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, |
737 | AVPacket *avpkt) |
738 | { |
739 | SCPRContext *s = avctx->priv_data; |
740 | GetByteContext *gb = &s->gb; |
741 | AVFrame *frame = data; |
742 | int ret, type; |
743 | |
744 | if (avctx->bits_per_coded_sample == 16) { |
745 | if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) |
746 | return ret; |
747 | } |
748 | |
749 | if ((ret = ff_reget_buffer(avctx, s->current_frame)) < 0) |
750 | return ret; |
751 | |
752 | bytestream2_init(gb, avpkt->data, avpkt->size); |
753 | |
754 | type = bytestream2_peek_byte(gb); |
755 | |
756 | if (type == 2) { |
757 | s->get_freq = get_freq0; |
758 | s->decode = decode0; |
759 | frame->key_frame = 1; |
760 | ret = decompress_i(avctx, (uint32_t *)s->current_frame->data[0], |
761 | s->current_frame->linesize[0] / 4); |
762 | } else if (type == 18) { |
763 | s->get_freq = get_freq; |
764 | s->decode = decode; |
765 | frame->key_frame = 1; |
766 | ret = decompress_i(avctx, (uint32_t *)s->current_frame->data[0], |
767 | s->current_frame->linesize[0] / 4); |
768 | } else if (type == 17) { |
769 | uint32_t clr, *dst = (uint32_t *)s->current_frame->data[0]; |
770 | int x, y; |
771 | |
772 | frame->key_frame = 1; |
773 | bytestream2_skip(gb, 1); |
774 | if (avctx->bits_per_coded_sample == 16) { |
775 | uint16_t value = bytestream2_get_le16(gb); |
776 | int r, g, b; |
777 | |
778 | r = (value ) & 31; |
779 | g = (value >> 5) & 31; |
780 | b = (value >> 10) & 31; |
781 | clr = (r << 16) + (g << 8) + b; |
782 | } else { |
783 | clr = bytestream2_get_le24(gb); |
784 | } |
785 | for (y = 0; y < avctx->height; y++) { |
786 | for (x = 0; x < avctx->width; x++) { |
787 | dst[x] = clr; |
788 | } |
789 | dst += s->current_frame->linesize[0] / 4; |
790 | } |
791 | } else if (type == 0 || type == 1) { |
792 | frame->key_frame = 0; |
793 | |
794 | ret = av_frame_copy(s->current_frame, s->last_frame); |
795 | if (ret < 0) |
796 | return ret; |
797 | |
798 | ret = decompress_p(avctx, (uint32_t *)s->current_frame->data[0], |
799 | s->current_frame->linesize[0] / 4, |
800 | (uint32_t *)s->last_frame->data[0], |
801 | s->last_frame->linesize[0] / 4); |
802 | } else { |
803 | return AVERROR_PATCHWELCOME; |
804 | } |
805 | |
806 | if (ret < 0) |
807 | return ret; |
808 | |
809 | if (avctx->bits_per_coded_sample != 16) { |
810 | ret = av_frame_ref(data, s->current_frame); |
811 | if (ret < 0) |
812 | return ret; |
813 | } else { |
814 | uint8_t *dst = frame->data[0]; |
815 | int x, y; |
816 | |
817 | ret = av_frame_copy(frame, s->current_frame); |
818 | if (ret < 0) |
819 | return ret; |
820 | |
821 | for (y = 0; y < avctx->height; y++) { |
822 | for (x = 0; x < avctx->width * 4; x++) { |
823 | dst[x] = dst[x] << 3; |
824 | } |
825 | dst += frame->linesize[0]; |
826 | } |
827 | } |
828 | |
829 | frame->pict_type = frame->key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; |
830 | |
831 | FFSWAP(AVFrame *, s->current_frame, s->last_frame); |
832 | |
833 | frame->data[0] += frame->linesize[0] * (avctx->height - 1); |
834 | frame->linesize[0] *= -1; |
835 | |
836 | *got_frame = 1; |
837 | |
838 | return avpkt->size; |
839 | } |
840 | |
841 | static av_cold int decode_init(AVCodecContext *avctx) |
842 | { |
843 | SCPRContext *s = avctx->priv_data; |
844 | |
845 | switch (avctx->bits_per_coded_sample) { |
846 | case 16: avctx->pix_fmt = AV_PIX_FMT_RGB0; break; |
847 | case 24: |
848 | case 32: avctx->pix_fmt = AV_PIX_FMT_BGR0; break; |
849 | default: |
850 | av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n", avctx->bits_per_coded_sample); |
851 | return AVERROR_INVALIDDATA; |
852 | } |
853 | |
854 | s->get_freq = get_freq0; |
855 | s->decode = decode0; |
856 | |
857 | s->cxshift = avctx->bits_per_coded_sample == 16 ? 0 : 2; |
858 | s->cbits = avctx->bits_per_coded_sample == 16 ? 0x1F : 0xFF; |
859 | s->nbx = (avctx->width + 15) / 16; |
860 | s->nby = (avctx->height + 15) / 16; |
861 | s->nbcount = s->nbx * s->nby; |
862 | s->blocks = av_malloc_array(s->nbcount, sizeof(*s->blocks)); |
863 | if (!s->blocks) |
864 | return AVERROR(ENOMEM); |
865 | |
866 | s->last_frame = av_frame_alloc(); |
867 | s->current_frame = av_frame_alloc(); |
868 | if (!s->last_frame || !s->current_frame) |
869 | return AVERROR(ENOMEM); |
870 | |
871 | return 0; |
872 | } |
873 | |
874 | static av_cold int decode_close(AVCodecContext *avctx) |
875 | { |
876 | SCPRContext *s = avctx->priv_data; |
877 | |
878 | av_freep(&s->blocks); |
879 | av_frame_free(&s->last_frame); |
880 | av_frame_free(&s->current_frame); |
881 | |
882 | return 0; |
883 | } |
884 | |
885 | AVCodec ff_scpr_decoder = { |
886 | .name = "scpr", |
887 | .long_name = NULL_IF_CONFIG_SMALL("ScreenPressor"), |
888 | .type = AVMEDIA_TYPE_VIDEO, |
889 | .id = AV_CODEC_ID_SCPR, |
890 | .priv_data_size = sizeof(SCPRContext), |
891 | .init = decode_init, |
892 | .close = decode_close, |
893 | .decode = decode_frame, |
894 | .capabilities = AV_CODEC_CAP_DR1, |
895 | .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | |
896 | FF_CODEC_CAP_INIT_CLEANUP, |
897 | }; |
898 |