GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/rasc.c Lines: 0 473 0.0 %
Date: 2021-04-14 23:45:22 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 <stdlib.h>
25
#include <string.h>
26
27
#include "libavutil/avassert.h"
28
#include "libavutil/imgutils.h"
29
#include "libavutil/opt.h"
30
31
#include "avcodec.h"
32
#include "bytestream.h"
33
#include "internal.h"
34
35
#include <zlib.h>
36
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')
47
48
typedef struct RASCContext {
49
    AVClass        *class;
50
    int             skip_cursor;
51
    GetByteContext  gb;
52
    uint8_t        *delta;
53
    int             delta_size;
54
    uint8_t        *cursor;
55
    int             cursor_size;
56
    unsigned        cursor_w;
57
    unsigned        cursor_h;
58
    unsigned        cursor_x;
59
    unsigned        cursor_y;
60
    int             stride;
61
    int             bpp;
62
    z_stream        zstream;
63
    AVFrame        *frame;
64
    AVFrame        *frame1;
65
    AVFrame        *frame2;
66
} RASCContext;
67
68
static void clear_plane(AVCodecContext *avctx, AVFrame *frame)
69
{
70
    RASCContext *s = avctx->priv_data;
71
    uint8_t *dst = frame->data[0];
72
73
    if (!dst)
74
        return;
75
76
    for (int y = 0; y < avctx->height; y++) {
77
        memset(dst, 0, avctx->width * s->bpp);
78
        dst += frame->linesize[0];
79
    }
80
}
81
82
static void copy_plane(AVCodecContext *avctx, AVFrame *src, AVFrame *dst)
83
{
84
    RASCContext *s = avctx->priv_data;
85
    uint8_t *srcp = src->data[0];
86
    uint8_t *dstp = dst->data[0];
87
88
    for (int y = 0; y < avctx->height; y++) {
89
        memcpy(dstp, srcp, s->stride);
90
        srcp += src->linesize[0];
91
        dstp += dst->linesize[0];
92
    }
93
}
94
95
static int init_frames(AVCodecContext *avctx)
96
{
97
    RASCContext *s = avctx->priv_data;
98
    int ret;
99
100
    av_frame_unref(s->frame1);
101
    av_frame_unref(s->frame2);
102
    if ((ret = ff_get_buffer(avctx, s->frame1, 0)) < 0)
103
        return ret;
104
105
    if ((ret = ff_get_buffer(avctx, s->frame2, 0)) < 0)
106
        return ret;
107
108
    clear_plane(avctx, s->frame2);
109
    clear_plane(avctx, s->frame1);
110
111
    return 0;
112
}
113
114
static int decode_fint(AVCodecContext *avctx,
115
                       const AVPacket *avpkt, unsigned size)
116
{
117
    RASCContext *s = avctx->priv_data;
118
    GetByteContext *gb = &s->gb;
119
    unsigned w, h, fmt;
120
    int ret;
121
122
    if (bytestream2_peek_le32(gb) != 0x65) {
123
        if (!s->frame2->data[0] || !s->frame1->data[0])
124
            return AVERROR_INVALIDDATA;
125
126
        clear_plane(avctx, s->frame2);
127
        clear_plane(avctx, s->frame1);
128
        return 0;
129
    }
130
    if (bytestream2_get_bytes_left(gb) < 72)
131
        return AVERROR_INVALIDDATA;
132
133
    bytestream2_skip(gb, 8);
134
    w = bytestream2_get_le32(gb);
135
    h = bytestream2_get_le32(gb);
136
    bytestream2_skip(gb, 30);
137
    fmt = bytestream2_get_le16(gb);
138
    bytestream2_skip(gb, 24);
139
140
    switch (fmt) {
141
    case 8:  s->stride = FFALIGN(w, 4);
142
             s->bpp    = 1;
143
             fmt = AV_PIX_FMT_PAL8; break;
144
    case 16: s->stride = w * 2;
145
             s->bpp    = 2;
146
             fmt = AV_PIX_FMT_RGB555LE; break;
147
    case 32: s->stride = w * 4;
148
             s->bpp    = 4;
149
             fmt = AV_PIX_FMT_BGR0; break;
150
    default: return AVERROR_INVALIDDATA;
151
    }
152
153
    ret = ff_set_dimensions(avctx, w, h);
154
    if (ret < 0)
155
        return ret;
156
    avctx->width  = w;
157
    avctx->height = h;
158
    avctx->pix_fmt = fmt;
159
160
    ret = init_frames(avctx);
161
    if (ret < 0)
162
        return ret;
163
164
    if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
165
        uint32_t *pal = (uint32_t *)s->frame2->data[1];
166
167
        for (int i = 0; i < 256; i++)
168
            pal[i] = bytestream2_get_le32(gb) | 0xFF000000u;
169
    }
170
171
    return 0;
172
}
173
174
static int decode_zlib(AVCodecContext *avctx, const AVPacket *avpkt,
175
                       unsigned size, unsigned uncompressed_size)
176
{
177
    RASCContext *s = avctx->priv_data;
178
    GetByteContext *gb = &s->gb;
179
    int zret;
180
181
    zret = inflateReset(&s->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
    s->zstream.next_in  = avpkt->data + bytestream2_tell(gb);
192
    s->zstream.avail_in = FFMIN(size, bytestream2_get_bytes_left(gb));
193
194
    s->zstream.next_out  = s->delta;
195
    s->zstream.avail_out = s->delta_size;
196
197
    zret = inflate(&s->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] * (y + h - 1) + x * s->bpp;
383
    b2  = s->frame2->data[0] + s->frame2->linesize[0] * (y + h - 1) + 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
    GetByteContext *gb = &s->gb;
478
    uint8_t *dst;
479
    unsigned pos;
480
    int zret, ret;
481
482
    pos = bytestream2_tell(gb);
483
    if (bytestream2_peek_le32(gb) == 0x65) {
484
        ret = decode_fint(avctx, avpkt, size);
485
        if (ret < 0)
486
            return ret;
487
    }
488
489
    if (!s->frame2->data[0])
490
        return AVERROR_INVALIDDATA;
491
492
    zret = inflateReset(&s->zstream);
493
    if (zret != Z_OK) {
494
        av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
495
        return AVERROR_EXTERNAL;
496
    }
497
498
    s->zstream.next_in  = avpkt->data + bytestream2_tell(gb);
499
    s->zstream.avail_in = bytestream2_get_bytes_left(gb);
500
501
    dst = s->frame2->data[0] + (avctx->height - 1) * s->frame2->linesize[0];
502
    for (int i = 0; i < avctx->height; i++) {
503
        s->zstream.next_out  = dst;
504
        s->zstream.avail_out = s->stride;
505
506
        zret = inflate(&s->zstream, Z_SYNC_FLUSH);
507
        if (zret != Z_OK && zret != Z_STREAM_END) {
508
            av_log(avctx, AV_LOG_ERROR,
509
                   "Inflate failed with return code: %d.\n", zret);
510
            return AVERROR_INVALIDDATA;
511
        }
512
513
        dst -= s->frame2->linesize[0];
514
    }
515
516
    dst = s->frame1->data[0] + (avctx->height - 1) * s->frame1->linesize[0];
517
    for (int i = 0; i < avctx->height; i++) {
518
        s->zstream.next_out  = dst;
519
        s->zstream.avail_out = s->stride;
520
521
        zret = inflate(&s->zstream, Z_SYNC_FLUSH);
522
        if (zret != Z_OK && zret != Z_STREAM_END) {
523
            av_log(avctx, AV_LOG_ERROR,
524
                   "Inflate failed with return code: %d.\n", zret);
525
            return AVERROR_INVALIDDATA;
526
        }
527
528
        dst -= s->frame1->linesize[0];
529
    }
530
531
    bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
532
533
    return 0;
534
}
535
536
static int decode_mous(AVCodecContext *avctx,
537
                       const AVPacket *avpkt, unsigned size)
538
{
539
    RASCContext *s = avctx->priv_data;
540
    GetByteContext *gb = &s->gb;
541
    unsigned w, h, pos, uncompressed_size;
542
    int ret;
543
544
    pos = bytestream2_tell(gb);
545
    bytestream2_skip(gb, 8);
546
    w = bytestream2_get_le32(gb);
547
    h = bytestream2_get_le32(gb);
548
    bytestream2_skip(gb, 12);
549
    uncompressed_size = bytestream2_get_le32(gb);
550
551
    if (w > avctx->width || h > avctx->height)
552
        return AVERROR_INVALIDDATA;
553
554
    if (uncompressed_size != 3 * w * h)
555
        return AVERROR_INVALIDDATA;
556
557
    av_fast_padded_malloc(&s->cursor, &s->cursor_size, uncompressed_size);
558
    if (!s->cursor)
559
        return AVERROR(ENOMEM);
560
561
    ret = decode_zlib(avctx, avpkt,
562
                      size - (bytestream2_tell(gb) - pos),
563
                      uncompressed_size);
564
    if (ret < 0)
565
        return ret;
566
    memcpy(s->cursor, s->delta, uncompressed_size);
567
568
    bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
569
570
    s->cursor_w = w;
571
    s->cursor_h = h;
572
573
    return 0;
574
}
575
576
static int decode_mpos(AVCodecContext *avctx,
577
                       const AVPacket *avpkt, unsigned size)
578
{
579
    RASCContext *s = avctx->priv_data;
580
    GetByteContext *gb = &s->gb;
581
    unsigned pos;
582
583
    pos = bytestream2_tell(gb);
584
    bytestream2_skip(gb, 8);
585
    s->cursor_x = bytestream2_get_le32(gb);
586
    s->cursor_y = bytestream2_get_le32(gb);
587
588
    bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));
589
590
    return 0;
591
}
592
593
static void draw_cursor(AVCodecContext *avctx)
594
{
595
    RASCContext *s = avctx->priv_data;
596
    uint8_t *dst, *pal;
597
598
    if (!s->cursor)
599
        return;
600
601
    if (s->cursor_x >= avctx->width || s->cursor_y >= avctx->height)
602
        return;
603
604
    if (s->cursor_x + s->cursor_w > avctx->width ||
605
        s->cursor_y + s->cursor_h > avctx->height)
606
        return;
607
608
    if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
609
        pal = s->frame->data[1];
610
        for (int i = 0; i < s->cursor_h; i++) {
611
            for (int j = 0; j < s->cursor_w; j++) {
612
                int cr = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 0];
613
                int cg = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 1];
614
                int cb = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 2];
615
                int best = INT_MAX;
616
                int index = 0;
617
                int dist;
618
619
                if (cr == s->cursor[0] && cg == s->cursor[1] && cb == s->cursor[2])
620
                    continue;
621
622
                dst = s->frame->data[0] + s->frame->linesize[0] * (s->cursor_y + i) + (s->cursor_x + j);
623
                for (int k = 0; k < 256; k++) {
624
                    int pr = pal[k * 4 + 0];
625
                    int pg = pal[k * 4 + 1];
626
                    int pb = pal[k * 4 + 2];
627
628
                    dist = FFABS(cr - pr) + FFABS(cg - pg) + FFABS(cb - pb);
629
                    if (dist < best) {
630
                        best = dist;
631
                        index = k;
632
                    }
633
                }
634
                dst[0] = index;
635
            }
636
        }
637
    } else if (avctx->pix_fmt == AV_PIX_FMT_RGB555LE) {
638
        for (int i = 0; i < s->cursor_h; i++) {
639
            for (int j = 0; j < s->cursor_w; j++) {
640
                int cr = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 0];
641
                int cg = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 1];
642
                int cb = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 2];
643
644
                if (cr == s->cursor[0] && cg == s->cursor[1] && cb == s->cursor[2])
645
                    continue;
646
647
                cr >>= 3; cg >>=3; cb >>= 3;
648
                dst = s->frame->data[0] + s->frame->linesize[0] * (s->cursor_y + i) + 2 * (s->cursor_x + j);
649
                AV_WL16(dst, cr | cg << 5 | cb << 10);
650
            }
651
        }
652
    } else if (avctx->pix_fmt == AV_PIX_FMT_BGR0) {
653
        for (int i = 0; i < s->cursor_h; i++) {
654
            for (int j = 0; j < s->cursor_w; j++) {
655
                int cr = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 0];
656
                int cg = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 1];
657
                int cb = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 2];
658
659
                if (cr == s->cursor[0] && cg == s->cursor[1] && cb == s->cursor[2])
660
                    continue;
661
662
                dst = s->frame->data[0] + s->frame->linesize[0] * (s->cursor_y + i) + 4 * (s->cursor_x + j);
663
                dst[0] = cb;
664
                dst[1] = cg;
665
                dst[2] = cr;
666
            }
667
        }
668
    }
669
}
670
671
static int decode_frame(AVCodecContext *avctx,
672
                        void *data, int *got_frame,
673
                        AVPacket *avpkt)
674
{
675
    RASCContext *s = avctx->priv_data;
676
    GetByteContext *gb = &s->gb;
677
    int ret, intra = 0;
678
    AVFrame *frame = data;
679
680
    bytestream2_init(gb, avpkt->data, avpkt->size);
681
682
    if (bytestream2_peek_le32(gb) == EMPT)
683
        return avpkt->size;
684
685
    s->frame = frame;
686
687
    while (bytestream2_get_bytes_left(gb) > 0) {
688
        unsigned type, size = 0;
689
690
        if (bytestream2_get_bytes_left(gb) < 8)
691
            return AVERROR_INVALIDDATA;
692
693
        type = bytestream2_get_le32(gb);
694
        if (type == KBND || type == BNDL) {
695
            intra = type == KBND;
696
            type = bytestream2_get_le32(gb);
697
        }
698
699
        size = bytestream2_get_le32(gb);
700
        if (bytestream2_get_bytes_left(gb) < size)
701
            return AVERROR_INVALIDDATA;
702
703
        switch (type) {
704
        case FINT:
705
        case INIT:
706
            ret = decode_fint(avctx, avpkt, size);
707
            break;
708
        case KFRM:
709
            ret = decode_kfrm(avctx, avpkt, size);
710
            break;
711
        case DLTA:
712
            ret = decode_dlta(avctx, avpkt, size);
713
            break;
714
        case MOVE:
715
            ret = decode_move(avctx, avpkt, size);
716
            break;
717
        case MOUS:
718
            ret = decode_mous(avctx, avpkt, size);
719
            break;
720
        case MPOS:
721
            ret = decode_mpos(avctx, avpkt, size);
722
            break;
723
        default:
724
            bytestream2_skip(gb, size);
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
    s->frame->key_frame = intra;
744
    s->frame->pict_type = intra ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
745
746
    *got_frame = 1;
747
748
    return avpkt->size;
749
}
750
751
static av_cold int decode_init(AVCodecContext *avctx)
752
{
753
    RASCContext *s = avctx->priv_data;
754
    int zret;
755
756
    s->zstream.zalloc = Z_NULL;
757
    s->zstream.zfree = Z_NULL;
758
    s->zstream.opaque = Z_NULL;
759
    zret = inflateInit(&s->zstream);
760
    if (zret != Z_OK) {
761
        av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
762
        return AVERROR_EXTERNAL;
763
    }
764
765
    s->frame1 = av_frame_alloc();
766
    s->frame2 = av_frame_alloc();
767
    if (!s->frame1 || !s->frame2)
768
        return AVERROR(ENOMEM);
769
770
    return 0;
771
}
772
773
static av_cold int decode_close(AVCodecContext *avctx)
774
{
775
    RASCContext *s = avctx->priv_data;
776
777
    av_freep(&s->cursor);
778
    s->cursor_size = 0;
779
    av_freep(&s->delta);
780
    s->delta_size = 0;
781
    av_frame_free(&s->frame1);
782
    av_frame_free(&s->frame2);
783
    inflateEnd(&s->zstream);
784
785
    return 0;
786
}
787
788
static void decode_flush(AVCodecContext *avctx)
789
{
790
    RASCContext *s = avctx->priv_data;
791
792
    clear_plane(avctx, s->frame1);
793
    clear_plane(avctx, s->frame2);
794
}
795
796
static const AVOption options[] = {
797
{ "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
{ NULL },
799
};
800
801
static const AVClass rasc_decoder_class = {
802
    .class_name = "rasc decoder",
803
    .item_name  = av_default_item_name,
804
    .option     = options,
805
    .version    = LIBAVUTIL_VERSION_INT,
806
};
807
808
AVCodec ff_rasc_decoder = {
809
    .name             = "rasc",
810
    .long_name        = NULL_IF_CONFIG_SMALL("RemotelyAnywhere Screen Capture"),
811
    .type             = AVMEDIA_TYPE_VIDEO,
812
    .id               = AV_CODEC_ID_RASC,
813
    .priv_data_size   = sizeof(RASCContext),
814
    .init             = decode_init,
815
    .close            = decode_close,
816
    .decode           = decode_frame,
817
    .flush            = decode_flush,
818
    .capabilities     = AV_CODEC_CAP_DR1,
819
    .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
820
                        FF_CODEC_CAP_INIT_CLEANUP,
821
    .priv_class       = &rasc_decoder_class,
822
};