2 * RemotelyAnywhere Screen Capture decoder
4 * Copyright (c) 2018 Paul B Mahol
6 * This file is part of FFmpeg.
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.
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.
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
27 #include "libavutil/avassert.h"
28 #include "libavutil/imgutils.h"
29 #include "libavutil/opt.h"
32 #include "bytestream.h"
37 #define KBND MKTAG('K', 'B', 'N', 'D')
38 #define FINT MKTAG('F', 'I', 'N', 'T')
39 #define INIT MKTAG('I', 'N', 'I', 'T')
40 #define BNDL MKTAG('B', 'N', 'D', 'L')
41 #define KFRM MKTAG('K', 'F', 'R', 'M')
42 #define DLTA MKTAG('D', 'L', 'T', 'A')
43 #define MOUS MKTAG('M', 'O', 'U', 'S')
44 #define MPOS MKTAG('M', 'P', 'O', 'S')
45 #define MOVE MKTAG('M', 'O', 'V', 'E')
46 #define EMPT MKTAG('E', 'M', 'P', 'T')
48 typedef struct RASCContext {
68 static void clear_plane(AVCodecContext *avctx, AVFrame *frame)
70 RASCContext *s = avctx->priv_data;
71 uint8_t *dst = frame->data[0];
73 for (int y = 0; y < avctx->height; y++) {
74 memset(dst, 0, avctx->width * s->bpp);
75 dst += frame->linesize[0];
79 static void copy_plane(AVCodecContext *avctx, AVFrame *src, AVFrame *dst)
81 RASCContext *s = avctx->priv_data;
82 uint8_t *srcp = src->data[0];
83 uint8_t *dstp = dst->data[0];
85 for (int y = 0; y < avctx->height; y++) {
86 memcpy(dstp, srcp, s->stride);
87 srcp += src->linesize[0];
88 dstp += dst->linesize[0];
92 static int init_frames(AVCodecContext *avctx)
94 RASCContext *s = avctx->priv_data;
97 av_frame_unref(s->frame1);
98 av_frame_unref(s->frame2);
99 if ((ret = ff_get_buffer(avctx, s->frame1, 0)) < 0)
102 if ((ret = ff_get_buffer(avctx, s->frame2, 0)) < 0)
105 clear_plane(avctx, s->frame2);
106 clear_plane(avctx, s->frame1);
111 static int decode_fint(AVCodecContext *avctx,
112 AVPacket *avpkt, unsigned size)
114 RASCContext *s = avctx->priv_data;
115 GetByteContext *gb = &s->gb;
119 if (bytestream2_peek_le32(gb) != 0x65) {
120 if (!s->frame2->data[0] || !s->frame1->data[0])
121 return AVERROR_INVALIDDATA;
123 clear_plane(avctx, s->frame2);
124 clear_plane(avctx, s->frame1);
127 if (bytestream2_get_bytes_left(gb) < 72)
128 return AVERROR_INVALIDDATA;
130 bytestream2_skip(gb, 8);
131 w = bytestream2_get_le32(gb);
132 h = bytestream2_get_le32(gb);
133 bytestream2_skip(gb, 30);
134 fmt = bytestream2_get_le16(gb);
135 bytestream2_skip(gb, 24);
138 case 8: s->stride = FFALIGN(w, 4);
140 fmt = AV_PIX_FMT_PAL8; break;
141 case 16: s->stride = w * 2;
143 fmt = AV_PIX_FMT_RGB555LE; break;
144 case 32: s->stride = w * 4;
146 fmt = AV_PIX_FMT_BGR0; break;
147 default: return AVERROR_INVALIDDATA;
150 ret = ff_set_dimensions(avctx, w, h);
155 avctx->pix_fmt = fmt;
157 ret = init_frames(avctx);
161 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
162 uint32_t *pal = (uint32_t *)s->frame2->data[1];
164 for (int i = 0; i < 256; i++)
165 pal[i] = bytestream2_get_le32(gb) | 0xFF000000u;
171 static int decode_zlib(AVCodecContext *avctx, AVPacket *avpkt,
172 unsigned size, unsigned uncompressed_size)
174 RASCContext *s = avctx->priv_data;
175 GetByteContext *gb = &s->gb;
178 zret = inflateReset(&s->zstream);
180 av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
181 return AVERROR_EXTERNAL;
184 av_fast_padded_malloc(&s->delta, &s->delta_size, uncompressed_size);
186 return AVERROR(ENOMEM);
188 s->zstream.next_in = avpkt->data + bytestream2_tell(gb);
189 s->zstream.avail_in = FFMIN(size, bytestream2_get_bytes_left(gb));
191 s->zstream.next_out = s->delta;
192 s->zstream.avail_out = s->delta_size;
194 zret = inflate(&s->zstream, Z_FINISH);
195 if (zret != Z_STREAM_END) {
196 av_log(avctx, AV_LOG_ERROR,
197 "Inflate failed with return code: %d.\n", zret);
198 return AVERROR_INVALIDDATA;
204 static int decode_move(AVCodecContext *avctx,
205 AVPacket *avpkt, unsigned size)
207 RASCContext *s = avctx->priv_data;
208 GetByteContext *gb = &s->gb;
210 unsigned pos, compression, nb_moves;
211 unsigned uncompressed_size;
214 pos = bytestream2_tell(gb);
215 bytestream2_skip(gb, 8);
216 nb_moves = bytestream2_get_le32(gb);
217 bytestream2_skip(gb, 8);
218 compression = bytestream2_get_le32(gb);
220 if (nb_moves > INT32_MAX / 16 || nb_moves > avctx->width * avctx->height)
221 return AVERROR_INVALIDDATA;
223 uncompressed_size = 16 * nb_moves;
225 if (compression == 1) {
226 ret = decode_zlib(avctx, avpkt,
227 size - (bytestream2_tell(gb) - pos),
231 bytestream2_init(&mc, s->delta, uncompressed_size);
232 } else if (compression == 0) {
233 bytestream2_init(&mc, avpkt->data + bytestream2_tell(gb),
234 bytestream2_get_bytes_left(gb));
235 } else if (compression == 2) {
236 avpriv_request_sample(avctx, "compression %d", compression);
237 return AVERROR_PATCHWELCOME;
239 return AVERROR_INVALIDDATA;
242 if (bytestream2_get_bytes_left(&mc) < uncompressed_size)
243 return AVERROR_INVALIDDATA;
245 for (int i = 0; i < nb_moves; i++) {
246 int type, start_x, start_y, end_x, end_y, mov_x, mov_y;
247 uint8_t *e2, *b1, *b2;
250 type = bytestream2_get_le16(&mc);
251 start_x = bytestream2_get_le16(&mc);
252 start_y = bytestream2_get_le16(&mc);
253 end_x = bytestream2_get_le16(&mc);
254 end_y = bytestream2_get_le16(&mc);
255 mov_x = bytestream2_get_le16(&mc);
256 mov_y = bytestream2_get_le16(&mc);
257 bytestream2_skip(&mc, 2);
259 if (start_x >= avctx->width || start_y >= avctx->height ||
260 end_x >= avctx->width || end_y >= avctx->height ||
261 mov_x >= avctx->width || mov_y >= avctx->height) {
265 if (start_x >= end_x || start_y >= end_y)
271 if (mov_x + w > avctx->width || mov_y + h > avctx->height)
274 if (!s->frame2->data[0] || !s->frame1->data[0])
275 return AVERROR_INVALIDDATA;
277 b1 = s->frame1->data[0] + s->frame1->linesize[0] * (start_y + h - 1) + start_x * s->bpp;
278 b2 = s->frame2->data[0] + s->frame2->linesize[0] * (start_y + h - 1) + start_x * s->bpp;
279 e2 = s->frame2->data[0] + s->frame2->linesize[0] * (mov_y + h - 1) + mov_x * s->bpp;
282 for (int j = 0; j < h; j++) {
283 memcpy(b1, b2, w * s->bpp);
284 b1 -= s->frame1->linesize[0];
285 b2 -= s->frame2->linesize[0];
287 } else if (type == 1) {
288 for (int j = 0; j < h; j++) {
289 memset(b2, 0, w * s->bpp);
290 b2 -= s->frame2->linesize[0];
292 } else if (type == 0) {
295 av_fast_padded_malloc(&s->delta, &s->delta_size, w * h * s->bpp);
298 return AVERROR(ENOMEM);
300 for (int j = 0; j < h; j++) {
301 memcpy(buffer + j * w * s->bpp, e2, w * s->bpp);
302 e2 -= s->frame2->linesize[0];
305 for (int j = 0; j < h; j++) {
306 memcpy(b2, buffer + j * w * s->bpp, w * s->bpp);
307 b2 -= s->frame2->linesize[0];
310 return AVERROR_INVALIDDATA;
314 bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
320 if (cx >= w * s->bpp) { \
323 b1 -= s->frame1->linesize[0]; \
324 b2 -= s->frame2->linesize[0]; \
328 static int decode_dlta(AVCodecContext *avctx,
329 AVPacket *avpkt, unsigned size)
331 RASCContext *s = avctx->priv_data;
332 GetByteContext *gb = &s->gb;
334 unsigned uncompressed_size, pos;
336 int ret, cx, cy, compression;
339 pos = bytestream2_tell(gb);
340 bytestream2_skip(gb, 12);
341 uncompressed_size = bytestream2_get_le32(gb);
342 x = bytestream2_get_le32(gb);
343 y = bytestream2_get_le32(gb);
344 w = bytestream2_get_le32(gb);
345 h = bytestream2_get_le32(gb);
347 if (x >= avctx->width || y >= avctx->height ||
348 w > avctx->width || h > avctx->height)
349 return AVERROR_INVALIDDATA;
351 if (x + w > avctx->width || y + h > avctx->height)
352 return AVERROR_INVALIDDATA;
354 bytestream2_skip(gb, 4);
355 compression = bytestream2_get_le32(gb);
357 if (compression == 1) {
358 if (w * h * s->bpp * 3 < uncompressed_size)
359 return AVERROR_INVALIDDATA;
360 ret = decode_zlib(avctx, avpkt, size, uncompressed_size);
363 bytestream2_init(&dc, s->delta, uncompressed_size);
364 } else if (compression == 0) {
365 if (bytestream2_get_bytes_left(gb) < uncompressed_size)
366 return AVERROR_INVALIDDATA;
367 bytestream2_init(&dc, avpkt->data + bytestream2_tell(gb),
369 } else if (compression == 2) {
370 avpriv_request_sample(avctx, "compression %d", compression);
371 return AVERROR_PATCHWELCOME;
373 return AVERROR_INVALIDDATA;
376 if (!s->frame2->data[0] || !s->frame1->data[0])
377 return AVERROR_INVALIDDATA;
379 b1 = s->frame1->data[0] + s->frame1->linesize[0] * (y + h - 1) + x * s->bpp;
380 b2 = s->frame2->data[0] + s->frame2->linesize[0] * (y + h - 1) + x * s->bpp;
382 while (bytestream2_get_bytes_left(&dc) > 0) {
383 int type = bytestream2_get_byte(&dc);
384 int len = bytestream2_get_byte(&dc);
389 while (len > 0 && cy > 0) {
395 while (len > 0 && cy > 0) {
406 while (len > 0 && cy > 0) {
407 fill = bytestream2_get_byte(&dc);
415 fill = bytestream2_get_byte(&dc);
416 while (len > 0 && cy > 0) {
417 AV_WL32(b1 + cx, AV_RL32(b2 + cx));
418 AV_WL32(b2 + cx, fill);
424 fill = bytestream2_get_le32(&dc);
425 while (len > 0 && cy > 0) {
426 AV_WL32(b1 + cx, AV_RL32(b2 + cx));
427 AV_WL32(b2 + cx, fill);
433 while (len > 0 && cy > 0) {
439 while (len > 0 && cy > 0) {
442 v0 = AV_RL32(b2 + cx);
443 v1 = AV_RL32(b1 + cx);
444 AV_WL32(b2 + cx, v1);
445 AV_WL32(b1 + cx, v0);
451 while (len > 0 && cy > 0) {
452 fill = bytestream2_get_le32(&dc);
453 AV_WL32(b1 + cx, AV_RL32(b2 + cx));
454 AV_WL32(b2 + cx, fill);
460 avpriv_request_sample(avctx, "runlen %d", type);
461 return AVERROR_INVALIDDATA;
465 bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
470 static int decode_kfrm(AVCodecContext *avctx,
471 AVPacket *avpkt, unsigned size)
473 RASCContext *s = avctx->priv_data;
474 GetByteContext *gb = &s->gb;
479 pos = bytestream2_tell(gb);
480 if (bytestream2_peek_le32(gb) == 0x65) {
481 ret = decode_fint(avctx, avpkt, size);
486 if (!s->frame2->data[0])
487 return AVERROR_INVALIDDATA;
489 zret = inflateReset(&s->zstream);
491 av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
492 return AVERROR_EXTERNAL;
495 s->zstream.next_in = avpkt->data + bytestream2_tell(gb);
496 s->zstream.avail_in = bytestream2_get_bytes_left(gb);
498 dst = s->frame2->data[0] + (avctx->height - 1) * s->frame2->linesize[0];
499 for (int i = 0; i < avctx->height; i++) {
500 s->zstream.next_out = dst;
501 s->zstream.avail_out = s->stride;
503 zret = inflate(&s->zstream, Z_SYNC_FLUSH);
504 if (zret != Z_OK && zret != Z_STREAM_END) {
505 av_log(avctx, AV_LOG_ERROR,
506 "Inflate failed with return code: %d.\n", zret);
507 return AVERROR_INVALIDDATA;
510 dst -= s->frame2->linesize[0];
513 dst = s->frame1->data[0] + (avctx->height - 1) * s->frame1->linesize[0];
514 for (int i = 0; i < avctx->height; i++) {
515 s->zstream.next_out = dst;
516 s->zstream.avail_out = s->stride;
518 zret = inflate(&s->zstream, Z_SYNC_FLUSH);
519 if (zret != Z_OK && zret != Z_STREAM_END) {
520 av_log(avctx, AV_LOG_ERROR,
521 "Inflate failed with return code: %d.\n", zret);
522 return AVERROR_INVALIDDATA;
525 dst -= s->frame1->linesize[0];
528 bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
533 static int decode_mous(AVCodecContext *avctx,
534 AVPacket *avpkt, unsigned size)
536 RASCContext *s = avctx->priv_data;
537 GetByteContext *gb = &s->gb;
538 unsigned w, h, pos, uncompressed_size;
541 pos = bytestream2_tell(gb);
542 bytestream2_skip(gb, 8);
543 w = bytestream2_get_le32(gb);
544 h = bytestream2_get_le32(gb);
545 bytestream2_skip(gb, 12);
546 uncompressed_size = bytestream2_get_le32(gb);
548 if (w > avctx->width || h > avctx->height)
549 return AVERROR_INVALIDDATA;
551 if (uncompressed_size != 3 * w * h)
552 return AVERROR_INVALIDDATA;
554 av_fast_padded_malloc(&s->cursor, &s->cursor_size, uncompressed_size);
556 return AVERROR(ENOMEM);
558 ret = decode_zlib(avctx, avpkt,
559 size - (bytestream2_tell(gb) - pos),
563 memcpy(s->cursor, s->delta, uncompressed_size);
565 bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
573 static int decode_mpos(AVCodecContext *avctx,
574 AVPacket *avpkt, unsigned size)
576 RASCContext *s = avctx->priv_data;
577 GetByteContext *gb = &s->gb;
580 pos = bytestream2_tell(gb);
581 bytestream2_skip(gb, 8);
582 s->cursor_x = bytestream2_get_le32(gb);
583 s->cursor_y = bytestream2_get_le32(gb);
585 bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
590 static void draw_cursor(AVCodecContext *avctx)
592 RASCContext *s = avctx->priv_data;
598 if (s->cursor_x >= avctx->width || s->cursor_y >= avctx->height)
601 if (s->cursor_x + s->cursor_w > avctx->width ||
602 s->cursor_y + s->cursor_h > avctx->height)
605 if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
606 pal = s->frame->data[1];
607 for (int i = 0; i < s->cursor_h; i++) {
608 for (int j = 0; j < s->cursor_w; j++) {
609 int cr = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 0];
610 int cg = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 1];
611 int cb = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 2];
616 if (cr == s->cursor[0] && cg == s->cursor[1] && cb == s->cursor[2])
619 dst = s->frame->data[0] + s->frame->linesize[0] * (s->cursor_y + i) + (s->cursor_x + j);
620 for (int k = 0; k < 256; k++) {
621 int pr = pal[k * 4 + 0];
622 int pg = pal[k * 4 + 1];
623 int pb = pal[k * 4 + 2];
625 dist = FFABS(cr - pr) + FFABS(cg - pg) + FFABS(cb - pb);
634 } else if (avctx->pix_fmt == AV_PIX_FMT_RGB555LE) {
635 for (int i = 0; i < s->cursor_h; i++) {
636 for (int j = 0; j < s->cursor_w; j++) {
637 int cr = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 0];
638 int cg = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 1];
639 int cb = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 2];
641 if (cr == s->cursor[0] && cg == s->cursor[1] && cb == s->cursor[2])
644 cr >>= 3; cg >>=3; cb >>= 3;
645 dst = s->frame->data[0] + s->frame->linesize[0] * (s->cursor_y + i) + 2 * (s->cursor_x + j);
646 AV_WL16(dst, cr | cg << 5 | cb << 10);
649 } else if (avctx->pix_fmt == AV_PIX_FMT_BGR0) {
650 for (int i = 0; i < s->cursor_h; i++) {
651 for (int j = 0; j < s->cursor_w; j++) {
652 int cr = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 0];
653 int cg = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 1];
654 int cb = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 2];
656 if (cr == s->cursor[0] && cg == s->cursor[1] && cb == s->cursor[2])
659 dst = s->frame->data[0] + s->frame->linesize[0] * (s->cursor_y + i) + 4 * (s->cursor_x + j);
668 static int decode_frame(AVCodecContext *avctx,
669 void *data, int *got_frame,
672 RASCContext *s = avctx->priv_data;
673 GetByteContext *gb = &s->gb;
675 AVFrame *frame = data;
677 bytestream2_init(gb, avpkt->data, avpkt->size);
679 if (bytestream2_peek_le32(gb) == EMPT)
684 while (bytestream2_get_bytes_left(gb) > 0) {
685 unsigned type, size = 0;
687 if (bytestream2_get_bytes_left(gb) < 8)
688 return AVERROR_INVALIDDATA;
690 type = bytestream2_get_le32(gb);
691 if (type == KBND || type == BNDL) {
692 intra = type == KBND;
693 type = bytestream2_get_le32(gb);
696 size = bytestream2_get_le32(gb);
697 if (bytestream2_get_bytes_left(gb) < size)
698 return AVERROR_INVALIDDATA;
703 ret = decode_fint(avctx, avpkt, size);
706 ret = decode_kfrm(avctx, avpkt, size);
709 ret = decode_dlta(avctx, avpkt, size);
712 ret = decode_move(avctx, avpkt, size);
715 ret = decode_mous(avctx, avpkt, size);
718 ret = decode_mpos(avctx, avpkt, size);
721 bytestream2_skip(gb, size);
728 if (!s->frame2->data[0] || !s->frame1->data[0])
729 return AVERROR_INVALIDDATA;
731 if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0)
734 copy_plane(avctx, s->frame2, s->frame);
735 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
736 memcpy(s->frame->data[1], s->frame2->data[1], 1024);
740 s->frame->key_frame = intra;
741 s->frame->pict_type = intra ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
748 static av_cold int decode_init(AVCodecContext *avctx)
750 RASCContext *s = avctx->priv_data;
753 s->zstream.zalloc = Z_NULL;
754 s->zstream.zfree = Z_NULL;
755 s->zstream.opaque = Z_NULL;
756 zret = inflateInit(&s->zstream);
758 av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
759 return AVERROR_EXTERNAL;
762 s->frame1 = av_frame_alloc();
763 s->frame2 = av_frame_alloc();
764 if (!s->frame1 || !s->frame2)
765 return AVERROR(ENOMEM);
770 static av_cold int decode_close(AVCodecContext *avctx)
772 RASCContext *s = avctx->priv_data;
774 av_freep(&s->cursor);
778 av_frame_free(&s->frame1);
779 av_frame_free(&s->frame2);
780 inflateEnd(&s->zstream);
785 static void decode_flush(AVCodecContext *avctx)
787 RASCContext *s = avctx->priv_data;
789 clear_plane(avctx, s->frame1);
790 clear_plane(avctx, s->frame2);
793 static const AVOption options[] = {
794 { "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 },
798 static const AVClass rasc_decoder_class = {
799 .class_name = "rasc decoder",
800 .item_name = av_default_item_name,
802 .version = LIBAVUTIL_VERSION_INT,
805 AVCodec ff_rasc_decoder = {
807 .long_name = NULL_IF_CONFIG_SMALL("RemotelyAnywhere Screen Capture"),
808 .type = AVMEDIA_TYPE_VIDEO,
809 .id = AV_CODEC_ID_RASC,
810 .priv_data_size = sizeof(RASCContext),
812 .close = decode_close,
813 .decode = decode_frame,
814 .flush = decode_flush,
815 .capabilities = AV_CODEC_CAP_DR1,
816 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
817 FF_CODEC_CAP_INIT_CLEANUP,
818 .priv_class = &rasc_decoder_class,