FFmpeg coverage


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