FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/rasc.c
Date: 2022-07-07 01:21:54
Exec Total Coverage
Lines: 0 468 0.0%
Branches: 0 298 0.0%

Line Branch Exec Source
1 /*
2 * RemotelyAnywhere Screen Capture decoder
3 *
4 * Copyright (c) 2018 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 "libavutil/imgutils.h"
28 #include "libavutil/opt.h"
29
30 #include "avcodec.h"
31 #include "bytestream.h"
32 #include "codec_internal.h"
33 #include "internal.h"
34 #include "zlib_wrapper.h"
35
36 #include <zlib.h>
37
38 #define KBND MKTAG('K', 'B', 'N', 'D')
39 #define FINT MKTAG('F', 'I', 'N', 'T')
40 #define INIT MKTAG('I', 'N', 'I', 'T')
41 #define BNDL MKTAG('B', 'N', 'D', 'L')
42 #define KFRM MKTAG('K', 'F', 'R', 'M')
43 #define DLTA MKTAG('D', 'L', 'T', 'A')
44 #define MOUS MKTAG('M', 'O', 'U', 'S')
45 #define MPOS MKTAG('M', 'P', 'O', 'S')
46 #define MOVE MKTAG('M', 'O', 'V', 'E')
47 #define EMPT MKTAG('E', 'M', 'P', 'T')
48
49 typedef struct RASCContext {
50 AVClass *class;
51 int skip_cursor;
52 GetByteContext gb;
53 uint8_t *delta;
54 int delta_size;
55 uint8_t *cursor;
56 int cursor_size;
57 unsigned cursor_w;
58 unsigned cursor_h;
59 unsigned cursor_x;
60 unsigned cursor_y;
61 int stride;
62 int bpp;
63 AVFrame *frame;
64 AVFrame *frame1;
65 AVFrame *frame2;
66 FFZStream zstream;
67 } RASCContext;
68
69 static void clear_plane(AVCodecContext *avctx, AVFrame *frame)
70 {
71 RASCContext *s = avctx->priv_data;
72 uint8_t *dst = frame->data[0];
73
74 if (!dst)
75 return;
76
77 for (int y = 0; y < avctx->height; y++) {
78 memset(dst, 0, avctx->width * s->bpp);
79 dst += frame->linesize[0];
80 }
81 }
82
83 static void copy_plane(AVCodecContext *avctx, AVFrame *src, AVFrame *dst)
84 {
85 RASCContext *s = avctx->priv_data;
86 uint8_t *srcp = src->data[0];
87 uint8_t *dstp = dst->data[0];
88
89 for (int y = 0; y < avctx->height; y++) {
90 memcpy(dstp, srcp, s->stride);
91 srcp += src->linesize[0];
92 dstp += dst->linesize[0];
93 }
94 }
95
96 static int init_frames(AVCodecContext *avctx)
97 {
98 RASCContext *s = avctx->priv_data;
99 int ret;
100
101 av_frame_unref(s->frame1);
102 av_frame_unref(s->frame2);
103 if ((ret = ff_get_buffer(avctx, s->frame1, 0)) < 0)
104 return ret;
105
106 if ((ret = ff_get_buffer(avctx, s->frame2, 0)) < 0)
107 return ret;
108
109 clear_plane(avctx, s->frame2);
110 clear_plane(avctx, s->frame1);
111
112 return 0;
113 }
114
115 static int decode_fint(AVCodecContext *avctx,
116 const AVPacket *avpkt, unsigned size)
117 {
118 RASCContext *s = avctx->priv_data;
119 GetByteContext *gb = &s->gb;
120 unsigned w, h, fmt;
121 int ret;
122
123 if (bytestream2_peek_le32(gb) != 0x65) {
124 if (!s->frame2->data[0] || !s->frame1->data[0])
125 return AVERROR_INVALIDDATA;
126
127 clear_plane(avctx, s->frame2);
128 clear_plane(avctx, s->frame1);
129 return 0;
130 }
131 if (bytestream2_get_bytes_left(gb) < 72)
132 return AVERROR_INVALIDDATA;
133
134 bytestream2_skip(gb, 8);
135 w = bytestream2_get_le32(gb);
136 h = bytestream2_get_le32(gb);
137 bytestream2_skip(gb, 30);
138 fmt = bytestream2_get_le16(gb);
139 bytestream2_skip(gb, 24);
140
141 switch (fmt) {
142 case 8: s->stride = FFALIGN(w, 4);
143 s->bpp = 1;
144 fmt = AV_PIX_FMT_PAL8; break;
145 case 16: s->stride = w * 2;
146 s->bpp = 2;
147 fmt = AV_PIX_FMT_RGB555LE; break;
148 case 32: s->stride = w * 4;
149 s->bpp = 4;
150 fmt = AV_PIX_FMT_BGR0; break;
151 default: return AVERROR_INVALIDDATA;
152 }
153
154 ret = ff_set_dimensions(avctx, w, h);
155 if (ret < 0)
156 return ret;
157 avctx->width = w;
158 avctx->height = h;
159 avctx->pix_fmt = fmt;
160
161 ret = init_frames(avctx);
162 if (ret < 0)
163 return ret;
164
165 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
166 uint32_t *pal = (uint32_t *)s->frame2->data[1];
167
168 for (int i = 0; i < 256; i++)
169 pal[i] = bytestream2_get_le32(gb) | 0xFF000000u;
170 }
171
172 return 0;
173 }
174
175 static int decode_zlib(AVCodecContext *avctx, const AVPacket *avpkt,
176 unsigned size, unsigned uncompressed_size)
177 {
178 RASCContext *s = avctx->priv_data;
179 z_stream *const zstream = &s->zstream.zstream;
180 GetByteContext *gb = &s->gb;
181 int zret;
182
183 zret = inflateReset(zstream);
184 if (zret != Z_OK) {
185 av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
186 return AVERROR_EXTERNAL;
187 }
188
189 av_fast_padded_malloc(&s->delta, &s->delta_size, uncompressed_size);
190 if (!s->delta)
191 return AVERROR(ENOMEM);
192
193 zstream->next_in = avpkt->data + bytestream2_tell(gb);
194 zstream->avail_in = FFMIN(size, bytestream2_get_bytes_left(gb));
195
196 zstream->next_out = s->delta;
197 zstream->avail_out = s->delta_size;
198
199 zret = inflate(zstream, Z_FINISH);
200 if (zret != Z_STREAM_END) {
201 av_log(avctx, AV_LOG_ERROR,
202 "Inflate failed with return code: %d.\n", zret);
203 return AVERROR_INVALIDDATA;
204 }
205
206 return 0;
207 }
208
209 static int decode_move(AVCodecContext *avctx,
210 const AVPacket *avpkt, unsigned size)
211 {
212 RASCContext *s = avctx->priv_data;
213 GetByteContext *gb = &s->gb;
214 GetByteContext mc;
215 unsigned pos, compression, nb_moves;
216 unsigned uncompressed_size;
217 int ret;
218
219 pos = bytestream2_tell(gb);
220 bytestream2_skip(gb, 8);
221 nb_moves = bytestream2_get_le32(gb);
222 bytestream2_skip(gb, 8);
223 compression = bytestream2_get_le32(gb);
224
225 if (nb_moves > INT32_MAX / 16 || nb_moves > avctx->width * avctx->height)
226 return AVERROR_INVALIDDATA;
227
228 uncompressed_size = 16 * nb_moves;
229
230 if (compression == 1) {
231 ret = decode_zlib(avctx, avpkt,
232 size - (bytestream2_tell(gb) - pos),
233 uncompressed_size);
234 if (ret < 0)
235 return ret;
236 bytestream2_init(&mc, s->delta, uncompressed_size);
237 } else if (compression == 0) {
238 bytestream2_init(&mc, avpkt->data + bytestream2_tell(gb),
239 bytestream2_get_bytes_left(gb));
240 } else if (compression == 2) {
241 avpriv_request_sample(avctx, "compression %d", compression);
242 return AVERROR_PATCHWELCOME;
243 } else {
244 return AVERROR_INVALIDDATA;
245 }
246
247 if (bytestream2_get_bytes_left(&mc) < uncompressed_size)
248 return AVERROR_INVALIDDATA;
249
250 for (int i = 0; i < nb_moves; i++) {
251 int type, start_x, start_y, end_x, end_y, mov_x, mov_y;
252 uint8_t *e2, *b1, *b2;
253 int w, h;
254
255 type = bytestream2_get_le16(&mc);
256 start_x = bytestream2_get_le16(&mc);
257 start_y = bytestream2_get_le16(&mc);
258 end_x = bytestream2_get_le16(&mc);
259 end_y = bytestream2_get_le16(&mc);
260 mov_x = bytestream2_get_le16(&mc);
261 mov_y = bytestream2_get_le16(&mc);
262 bytestream2_skip(&mc, 2);
263
264 if (start_x >= avctx->width || start_y >= avctx->height ||
265 end_x >= avctx->width || end_y >= avctx->height ||
266 mov_x >= avctx->width || mov_y >= avctx->height) {
267 continue;
268 }
269
270 if (start_x >= end_x || start_y >= end_y)
271 continue;
272
273 w = end_x - start_x;
274 h = end_y - start_y;
275
276 if (mov_x + w > avctx->width || mov_y + h > avctx->height)
277 continue;
278
279 if (!s->frame2->data[0] || !s->frame1->data[0])
280 return AVERROR_INVALIDDATA;
281
282 b1 = s->frame1->data[0] + s->frame1->linesize[0] * (start_y + h - 1) + start_x * s->bpp;
283 b2 = s->frame2->data[0] + s->frame2->linesize[0] * (start_y + h - 1) + start_x * s->bpp;
284 e2 = s->frame2->data[0] + s->frame2->linesize[0] * (mov_y + h - 1) + mov_x * s->bpp;
285
286 if (type == 2) {
287 for (int j = 0; j < h; j++) {
288 memcpy(b1, b2, w * s->bpp);
289 b1 -= s->frame1->linesize[0];
290 b2 -= s->frame2->linesize[0];
291 }
292 } else if (type == 1) {
293 for (int j = 0; j < h; j++) {
294 memset(b2, 0, w * s->bpp);
295 b2 -= s->frame2->linesize[0];
296 }
297 } else if (type == 0) {
298 uint8_t *buffer;
299
300 av_fast_padded_malloc(&s->delta, &s->delta_size, w * h * s->bpp);
301 buffer = s->delta;
302 if (!buffer)
303 return AVERROR(ENOMEM);
304
305 for (int j = 0; j < h; j++) {
306 memcpy(buffer + j * w * s->bpp, e2, w * s->bpp);
307 e2 -= s->frame2->linesize[0];
308 }
309
310 for (int j = 0; j < h; j++) {
311 memcpy(b2, buffer + j * w * s->bpp, w * s->bpp);
312 b2 -= s->frame2->linesize[0];
313 }
314 } else {
315 return AVERROR_INVALIDDATA;
316 }
317 }
318
319 bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
320
321 return 0;
322 }
323
324 #define NEXT_LINE \
325 if (cx >= w * s->bpp) { \
326 cx = 0; \
327 cy--; \
328 b1 -= s->frame1->linesize[0]; \
329 b2 -= s->frame2->linesize[0]; \
330 } \
331 len--;
332
333 static int decode_dlta(AVCodecContext *avctx,
334 const AVPacket *avpkt, unsigned size)
335 {
336 RASCContext *s = avctx->priv_data;
337 GetByteContext *gb = &s->gb;
338 GetByteContext dc;
339 unsigned uncompressed_size, pos;
340 unsigned x, y, w, h;
341 int ret, cx, cy, compression;
342 uint8_t *b1, *b2;
343
344 pos = bytestream2_tell(gb);
345 bytestream2_skip(gb, 12);
346 uncompressed_size = bytestream2_get_le32(gb);
347 x = bytestream2_get_le32(gb);
348 y = bytestream2_get_le32(gb);
349 w = bytestream2_get_le32(gb);
350 h = bytestream2_get_le32(gb);
351
352 if (x >= avctx->width || y >= avctx->height ||
353 w > avctx->width || h > avctx->height)
354 return AVERROR_INVALIDDATA;
355
356 if (x + w > avctx->width || y + h > avctx->height)
357 return AVERROR_INVALIDDATA;
358
359 bytestream2_skip(gb, 4);
360 compression = bytestream2_get_le32(gb);
361
362 if (compression == 1) {
363 if (w * h * s->bpp * 3 < uncompressed_size)
364 return AVERROR_INVALIDDATA;
365 ret = decode_zlib(avctx, avpkt, size, uncompressed_size);
366 if (ret < 0)
367 return ret;
368 bytestream2_init(&dc, s->delta, uncompressed_size);
369 } else if (compression == 0) {
370 if (bytestream2_get_bytes_left(gb) < uncompressed_size)
371 return AVERROR_INVALIDDATA;
372 bytestream2_init(&dc, avpkt->data + bytestream2_tell(gb),
373 uncompressed_size);
374 } else if (compression == 2) {
375 avpriv_request_sample(avctx, "compression %d", compression);
376 return AVERROR_PATCHWELCOME;
377 } else {
378 return AVERROR_INVALIDDATA;
379 }
380
381 if (!s->frame2->data[0] || !s->frame1->data[0])
382 return AVERROR_INVALIDDATA;
383
384 b1 = s->frame1->data[0] + s->frame1->linesize[0] * (y + h - 1) + x * s->bpp;
385 b2 = s->frame2->data[0] + s->frame2->linesize[0] * (y + h - 1) + x * s->bpp;
386 cx = 0, cy = h;
387 while (bytestream2_get_bytes_left(&dc) > 0) {
388 int type = bytestream2_get_byte(&dc);
389 int len = bytestream2_get_byte(&dc);
390 unsigned fill;
391
392 switch (type) {
393 case 1:
394 while (len > 0 && cy > 0) {
395 cx++;
396 NEXT_LINE
397 }
398 break;
399 case 2:
400 while (len > 0 && cy > 0) {
401 int v0 = b1[cx];
402 int v1 = b2[cx];
403
404 b2[cx] = v0;
405 b1[cx] = v1;
406 cx++;
407 NEXT_LINE
408 }
409 break;
410 case 3:
411 while (len > 0 && cy > 0) {
412 fill = bytestream2_get_byte(&dc);
413 b1[cx] = b2[cx];
414 b2[cx] = fill;
415 cx++;
416 NEXT_LINE
417 }
418 break;
419 case 4:
420 fill = bytestream2_get_byte(&dc);
421 while (len > 0 && cy > 0) {
422 AV_WL32(b1 + cx, AV_RL32(b2 + cx));
423 AV_WL32(b2 + cx, fill);
424 cx++;
425 NEXT_LINE
426 }
427 break;
428 case 7:
429 fill = bytestream2_get_le32(&dc);
430 while (len > 0 && cy > 0) {
431 AV_WL32(b1 + cx, AV_RL32(b2 + cx));
432 AV_WL32(b2 + cx, fill);
433 cx += 4;
434 NEXT_LINE
435 }
436 break;
437 case 10:
438 while (len > 0 && cy > 0) {
439 cx += 4;
440 NEXT_LINE
441 }
442 break;
443 case 12:
444 while (len > 0 && cy > 0) {
445 unsigned v0, v1;
446
447 v0 = AV_RL32(b2 + cx);
448 v1 = AV_RL32(b1 + cx);
449 AV_WL32(b2 + cx, v1);
450 AV_WL32(b1 + cx, v0);
451 cx += 4;
452 NEXT_LINE
453 }
454 break;
455 case 13:
456 while (len > 0 && cy > 0) {
457 fill = bytestream2_get_le32(&dc);
458 AV_WL32(b1 + cx, AV_RL32(b2 + cx));
459 AV_WL32(b2 + cx, fill);
460 cx += 4;
461 NEXT_LINE
462 }
463 break;
464 default:
465 avpriv_request_sample(avctx, "runlen %d", type);
466 return AVERROR_INVALIDDATA;
467 }
468 }
469
470 bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
471
472 return 0;
473 }
474
475 static int decode_kfrm(AVCodecContext *avctx,
476 const AVPacket *avpkt, unsigned size)
477 {
478 RASCContext *s = avctx->priv_data;
479 z_stream *const zstream = &s->zstream.zstream;
480 GetByteContext *gb = &s->gb;
481 uint8_t *dst;
482 unsigned pos;
483 int zret, ret;
484
485 pos = bytestream2_tell(gb);
486 if (bytestream2_peek_le32(gb) == 0x65) {
487 ret = decode_fint(avctx, avpkt, size);
488 if (ret < 0)
489 return ret;
490 }
491
492 if (!s->frame2->data[0])
493 return AVERROR_INVALIDDATA;
494
495 zret = inflateReset(zstream);
496 if (zret != Z_OK) {
497 av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
498 return AVERROR_EXTERNAL;
499 }
500
501 zstream->next_in = avpkt->data + bytestream2_tell(gb);
502 zstream->avail_in = bytestream2_get_bytes_left(gb);
503
504 dst = s->frame2->data[0] + (avctx->height - 1) * s->frame2->linesize[0];
505 for (int i = 0; i < avctx->height; i++) {
506 zstream->next_out = dst;
507 zstream->avail_out = s->stride;
508
509 zret = inflate(zstream, Z_SYNC_FLUSH);
510 if (zret != Z_OK && zret != Z_STREAM_END) {
511 av_log(avctx, AV_LOG_ERROR,
512 "Inflate failed with return code: %d.\n", zret);
513 return AVERROR_INVALIDDATA;
514 }
515
516 dst -= s->frame2->linesize[0];
517 }
518
519 dst = s->frame1->data[0] + (avctx->height - 1) * s->frame1->linesize[0];
520 for (int i = 0; i < avctx->height; i++) {
521 zstream->next_out = dst;
522 zstream->avail_out = s->stride;
523
524 zret = inflate(zstream, Z_SYNC_FLUSH);
525 if (zret != Z_OK && zret != Z_STREAM_END) {
526 av_log(avctx, AV_LOG_ERROR,
527 "Inflate failed with return code: %d.\n", zret);
528 return AVERROR_INVALIDDATA;
529 }
530
531 dst -= s->frame1->linesize[0];
532 }
533
534 bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
535
536 return 0;
537 }
538
539 static int decode_mous(AVCodecContext *avctx,
540 const AVPacket *avpkt, unsigned size)
541 {
542 RASCContext *s = avctx->priv_data;
543 GetByteContext *gb = &s->gb;
544 unsigned w, h, pos, uncompressed_size;
545 int ret;
546
547 pos = bytestream2_tell(gb);
548 bytestream2_skip(gb, 8);
549 w = bytestream2_get_le32(gb);
550 h = bytestream2_get_le32(gb);
551 bytestream2_skip(gb, 12);
552 uncompressed_size = bytestream2_get_le32(gb);
553
554 if (w > avctx->width || h > avctx->height)
555 return AVERROR_INVALIDDATA;
556
557 if (uncompressed_size != 3 * w * h)
558 return AVERROR_INVALIDDATA;
559
560 av_fast_padded_malloc(&s->cursor, &s->cursor_size, uncompressed_size);
561 if (!s->cursor)
562 return AVERROR(ENOMEM);
563
564 ret = decode_zlib(avctx, avpkt,
565 size - (bytestream2_tell(gb) - pos),
566 uncompressed_size);
567 if (ret < 0)
568 return ret;
569 memcpy(s->cursor, s->delta, uncompressed_size);
570
571 bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
572
573 s->cursor_w = w;
574 s->cursor_h = h;
575
576 return 0;
577 }
578
579 static int decode_mpos(AVCodecContext *avctx,
580 const AVPacket *avpkt, unsigned size)
581 {
582 RASCContext *s = avctx->priv_data;
583 GetByteContext *gb = &s->gb;
584 unsigned pos;
585
586 pos = bytestream2_tell(gb);
587 bytestream2_skip(gb, 8);
588 s->cursor_x = bytestream2_get_le32(gb);
589 s->cursor_y = bytestream2_get_le32(gb);
590
591 bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
592
593 return 0;
594 }
595
596 static void draw_cursor(AVCodecContext *avctx)
597 {
598 RASCContext *s = avctx->priv_data;
599 uint8_t *dst, *pal;
600
601 if (!s->cursor)
602 return;
603
604 if (s->cursor_x >= avctx->width || s->cursor_y >= avctx->height)
605 return;
606
607 if (s->cursor_x + s->cursor_w > avctx->width ||
608 s->cursor_y + s->cursor_h > avctx->height)
609 return;
610
611 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
612 pal = s->frame->data[1];
613 for (int i = 0; i < s->cursor_h; i++) {
614 for (int j = 0; j < s->cursor_w; j++) {
615 int cr = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 0];
616 int cg = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 1];
617 int cb = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 2];
618 int best = INT_MAX;
619 int index = 0;
620 int dist;
621
622 if (cr == s->cursor[0] && cg == s->cursor[1] && cb == s->cursor[2])
623 continue;
624
625 dst = s->frame->data[0] + s->frame->linesize[0] * (s->cursor_y + i) + (s->cursor_x + j);
626 for (int k = 0; k < 256; k++) {
627 int pr = pal[k * 4 + 0];
628 int pg = pal[k * 4 + 1];
629 int pb = pal[k * 4 + 2];
630
631 dist = FFABS(cr - pr) + FFABS(cg - pg) + FFABS(cb - pb);
632 if (dist < best) {
633 best = dist;
634 index = k;
635 }
636 }
637 dst[0] = index;
638 }
639 }
640 } else if (avctx->pix_fmt == AV_PIX_FMT_RGB555LE) {
641 for (int i = 0; i < s->cursor_h; i++) {
642 for (int j = 0; j < s->cursor_w; j++) {
643 int cr = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 0];
644 int cg = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 1];
645 int cb = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 2];
646
647 if (cr == s->cursor[0] && cg == s->cursor[1] && cb == s->cursor[2])
648 continue;
649
650 cr >>= 3; cg >>=3; cb >>= 3;
651 dst = s->frame->data[0] + s->frame->linesize[0] * (s->cursor_y + i) + 2 * (s->cursor_x + j);
652 AV_WL16(dst, cr | cg << 5 | cb << 10);
653 }
654 }
655 } else if (avctx->pix_fmt == AV_PIX_FMT_BGR0) {
656 for (int i = 0; i < s->cursor_h; i++) {
657 for (int j = 0; j < s->cursor_w; j++) {
658 int cr = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 0];
659 int cg = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 1];
660 int cb = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 2];
661
662 if (cr == s->cursor[0] && cg == s->cursor[1] && cb == s->cursor[2])
663 continue;
664
665 dst = s->frame->data[0] + s->frame->linesize[0] * (s->cursor_y + i) + 4 * (s->cursor_x + j);
666 dst[0] = cb;
667 dst[1] = cg;
668 dst[2] = cr;
669 }
670 }
671 }
672 }
673
674 static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
675 int *got_frame, AVPacket *avpkt)
676 {
677 RASCContext *s = avctx->priv_data;
678 GetByteContext *gb = &s->gb;
679 int ret, intra = 0;
680
681 bytestream2_init(gb, avpkt->data, avpkt->size);
682
683 if (bytestream2_peek_le32(gb) == EMPT)
684 return avpkt->size;
685
686 s->frame = frame;
687
688 while (bytestream2_get_bytes_left(gb) > 0) {
689 unsigned type, size = 0;
690
691 if (bytestream2_get_bytes_left(gb) < 8)
692 return AVERROR_INVALIDDATA;
693
694 type = bytestream2_get_le32(gb);
695 if (type == KBND || type == BNDL) {
696 intra = type == KBND;
697 type = bytestream2_get_le32(gb);
698 }
699
700 size = bytestream2_get_le32(gb);
701 if (bytestream2_get_bytes_left(gb) < size)
702 return AVERROR_INVALIDDATA;
703
704 switch (type) {
705 case FINT:
706 case INIT:
707 ret = decode_fint(avctx, avpkt, size);
708 break;
709 case KFRM:
710 ret = decode_kfrm(avctx, avpkt, size);
711 break;
712 case DLTA:
713 ret = decode_dlta(avctx, avpkt, size);
714 break;
715 case MOVE:
716 ret = decode_move(avctx, avpkt, size);
717 break;
718 case MOUS:
719 ret = decode_mous(avctx, avpkt, size);
720 break;
721 case MPOS:
722 ret = decode_mpos(avctx, avpkt, size);
723 break;
724 default:
725 bytestream2_skip(gb, size);
726 ret = 0;
727 }
728
729 if (ret < 0)
730 return ret;
731 }
732
733 if (!s->frame2->data[0] || !s->frame1->data[0])
734 return AVERROR_INVALIDDATA;
735
736 if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0)
737 return ret;
738
739 copy_plane(avctx, s->frame2, s->frame);
740 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
741 memcpy(s->frame->data[1], s->frame2->data[1], 1024);
742 if (!s->skip_cursor)
743 draw_cursor(avctx);
744
745 s->frame->key_frame = intra;
746 s->frame->pict_type = intra ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
747
748 *got_frame = 1;
749
750 return avpkt->size;
751 }
752
753 static av_cold int decode_init(AVCodecContext *avctx)
754 {
755 RASCContext *s = avctx->priv_data;
756
757 s->frame1 = av_frame_alloc();
758 s->frame2 = av_frame_alloc();
759 if (!s->frame1 || !s->frame2)
760 return AVERROR(ENOMEM);
761
762 return ff_inflate_init(&s->zstream, avctx);
763 }
764
765 static av_cold int decode_close(AVCodecContext *avctx)
766 {
767 RASCContext *s = avctx->priv_data;
768
769 av_freep(&s->cursor);
770 s->cursor_size = 0;
771 av_freep(&s->delta);
772 s->delta_size = 0;
773 av_frame_free(&s->frame1);
774 av_frame_free(&s->frame2);
775 ff_inflate_end(&s->zstream);
776
777 return 0;
778 }
779
780 static void decode_flush(AVCodecContext *avctx)
781 {
782 RASCContext *s = avctx->priv_data;
783
784 clear_plane(avctx, s->frame1);
785 clear_plane(avctx, s->frame2);
786 }
787
788 static const AVOption options[] = {
789 { "skip_cursor", "skip the cursor", offsetof(RASCContext, skip_cursor), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM },
790 { NULL },
791 };
792
793 static const AVClass rasc_decoder_class = {
794 .class_name = "rasc decoder",
795 .item_name = av_default_item_name,
796 .option = options,
797 .version = LIBAVUTIL_VERSION_INT,
798 };
799
800 const FFCodec ff_rasc_decoder = {
801 .p.name = "rasc",
802 .p.long_name = NULL_IF_CONFIG_SMALL("RemotelyAnywhere Screen Capture"),
803 .p.type = AVMEDIA_TYPE_VIDEO,
804 .p.id = AV_CODEC_ID_RASC,
805 .priv_data_size = sizeof(RASCContext),
806 .init = decode_init,
807 .close = decode_close,
808 FF_CODEC_DECODE_CB(decode_frame),
809 .flush = decode_flush,
810 .p.capabilities = AV_CODEC_CAP_DR1,
811 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
812 FF_CODEC_CAP_INIT_CLEANUP,
813 .p.priv_class = &rasc_decoder_class,
814 };
815