/*
 * RemotelyAnywhere Screen Capture decoder
 *
 * Copyright (c) 2018 Paul B Mahol
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"

#include "avcodec.h"
#include "bytestream.h"
#include "internal.h"

#include <zlib.h>

#define KBND MKTAG('K', 'B', 'N', 'D')
#define FINT MKTAG('F', 'I', 'N', 'T')
#define INIT MKTAG('I', 'N', 'I', 'T')
#define BNDL MKTAG('B', 'N', 'D', 'L')
#define KFRM MKTAG('K', 'F', 'R', 'M')
#define DLTA MKTAG('D', 'L', 'T', 'A')
#define MOUS MKTAG('M', 'O', 'U', 'S')
#define MPOS MKTAG('M', 'P', 'O', 'S')
#define MOVE MKTAG('M', 'O', 'V', 'E')
#define EMPT MKTAG('E', 'M', 'P', 'T')

typedef struct RASCContext {
    AVClass        *class;
    int             skip_cursor;
    GetByteContext  gb;
    uint8_t        *delta;
    int             delta_size;
    uint8_t        *cursor;
    int             cursor_size;
    unsigned        cursor_w;
    unsigned        cursor_h;
    unsigned        cursor_x;
    unsigned        cursor_y;
    int             stride;
    int             bpp;
    z_stream        zstream;
    AVFrame        *frame;
    AVFrame        *frame1;
    AVFrame        *frame2;
} RASCContext;

static void clear_plane(AVCodecContext *avctx, AVFrame *frame)
{
    RASCContext *s = avctx->priv_data;
    uint8_t *dst = frame->data[0];

    for (int y = 0; y < avctx->height; y++) {
        memset(dst, 0, avctx->width * s->bpp);
        dst += frame->linesize[0];
    }
}

static void copy_plane(AVCodecContext *avctx, AVFrame *src, AVFrame *dst)
{
    RASCContext *s = avctx->priv_data;
    uint8_t *srcp = src->data[0];
    uint8_t *dstp = dst->data[0];

    for (int y = 0; y < avctx->height; y++) {
        memcpy(dstp, srcp, s->stride);
        srcp += src->linesize[0];
        dstp += dst->linesize[0];
    }
}

static int init_frames(AVCodecContext *avctx)
{
    RASCContext *s = avctx->priv_data;
    int ret;

    av_frame_unref(s->frame1);
    av_frame_unref(s->frame2);
    if ((ret = ff_get_buffer(avctx, s->frame1, 0)) < 0)
        return ret;

    if ((ret = ff_get_buffer(avctx, s->frame2, 0)) < 0)
        return ret;

    clear_plane(avctx, s->frame2);
    clear_plane(avctx, s->frame1);

    return 0;
}

static int decode_fint(AVCodecContext *avctx,
                       AVPacket *avpkt, unsigned size)
{
    RASCContext *s = avctx->priv_data;
    GetByteContext *gb = &s->gb;
    unsigned w, h, fmt;
    int ret;

    if (bytestream2_peek_le32(gb) != 0x65) {
        if (!s->frame2->data[0] || !s->frame1->data[0])
            return AVERROR_INVALIDDATA;

        clear_plane(avctx, s->frame2);
        clear_plane(avctx, s->frame1);
        return 0;
    }
    if (bytestream2_get_bytes_left(gb) < 72)
        return AVERROR_INVALIDDATA;

    bytestream2_skip(gb, 8);
    w = bytestream2_get_le32(gb);
    h = bytestream2_get_le32(gb);
    bytestream2_skip(gb, 30);
    fmt = bytestream2_get_le16(gb);
    bytestream2_skip(gb, 24);

    switch (fmt) {
    case 8:  s->stride = FFALIGN(w, 4);
             s->bpp    = 1;
             fmt = AV_PIX_FMT_PAL8; break;
    case 16: s->stride = w * 2;
             s->bpp    = 2;
             fmt = AV_PIX_FMT_RGB555LE; break;
    case 32: s->stride = w * 4;
             s->bpp    = 4;
             fmt = AV_PIX_FMT_BGR0; break;
    default: return AVERROR_INVALIDDATA;
    }

    ret = ff_set_dimensions(avctx, w, h);
    if (ret < 0)
        return ret;
    avctx->width  = w;
    avctx->height = h;
    avctx->pix_fmt = fmt;

    ret = init_frames(avctx);
    if (ret < 0)
        return ret;

    if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
        uint32_t *pal = (uint32_t *)s->frame2->data[1];

        for (int i = 0; i < 256; i++)
            pal[i] = bytestream2_get_le32(gb) | 0xFF000000u;
    }

    return 0;
}

static int decode_zlib(AVCodecContext *avctx, AVPacket *avpkt,
                       unsigned size, unsigned uncompressed_size)
{
    RASCContext *s = avctx->priv_data;
    GetByteContext *gb = &s->gb;
    int zret;

    zret = inflateReset(&s->zstream);
    if (zret != Z_OK) {
        av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
        return AVERROR_EXTERNAL;
    }

    av_fast_padded_malloc(&s->delta, &s->delta_size, uncompressed_size);
    if (!s->delta)
        return AVERROR(ENOMEM);

    s->zstream.next_in  = avpkt->data + bytestream2_tell(gb);
    s->zstream.avail_in = FFMIN(size, bytestream2_get_bytes_left(gb));

    s->zstream.next_out  = s->delta;
    s->zstream.avail_out = s->delta_size;

    zret = inflate(&s->zstream, Z_FINISH);
    if (zret != Z_STREAM_END) {
        av_log(avctx, AV_LOG_ERROR,
               "Inflate failed with return code: %d.\n", zret);
        return AVERROR_INVALIDDATA;
    }

    return 0;
}

static int decode_move(AVCodecContext *avctx,
                       AVPacket *avpkt, unsigned size)
{
    RASCContext *s = avctx->priv_data;
    GetByteContext *gb = &s->gb;
    GetByteContext mc;
    unsigned pos, compression, nb_moves;
    unsigned uncompressed_size;
    int ret;

    pos = bytestream2_tell(gb);
    bytestream2_skip(gb, 8);
    nb_moves = bytestream2_get_le32(gb);
    bytestream2_skip(gb, 8);
    compression = bytestream2_get_le32(gb);

    if (nb_moves > INT32_MAX / 16 || nb_moves > avctx->width * avctx->height)
        return AVERROR_INVALIDDATA;

    uncompressed_size = 16 * nb_moves;

    if (compression == 1) {
        ret = decode_zlib(avctx, avpkt,
                          size - (bytestream2_tell(gb) - pos),
                          uncompressed_size);
        if (ret < 0)
            return ret;
        bytestream2_init(&mc, s->delta, uncompressed_size);
    } else if (compression == 0) {
        bytestream2_init(&mc, avpkt->data + bytestream2_tell(gb),
                         bytestream2_get_bytes_left(gb));
    } else if (compression == 2) {
        avpriv_request_sample(avctx, "compression %d", compression);
        return AVERROR_PATCHWELCOME;
    } else {
        return AVERROR_INVALIDDATA;
    }

    if (bytestream2_get_bytes_left(&mc) < uncompressed_size)
        return AVERROR_INVALIDDATA;

    for (int i = 0; i < nb_moves; i++) {
        int type, start_x, start_y, end_x, end_y, mov_x, mov_y;
        uint8_t *e2, *b1, *b2;
        int w, h;

        type = bytestream2_get_le16(&mc);
        start_x = bytestream2_get_le16(&mc);
        start_y = bytestream2_get_le16(&mc);
        end_x = bytestream2_get_le16(&mc);
        end_y = bytestream2_get_le16(&mc);
        mov_x = bytestream2_get_le16(&mc);
        mov_y = bytestream2_get_le16(&mc);
        bytestream2_skip(&mc, 2);

        if (start_x >= avctx->width || start_y >= avctx->height ||
            end_x >= avctx->width || end_y >= avctx->height ||
            mov_x >= avctx->width || mov_y >= avctx->height) {
            continue;
        }

        if (start_x >= end_x || start_y >= end_y)
            continue;

        w = end_x - start_x;
        h = end_y - start_y;

        if (mov_x + w > avctx->width || mov_y + h > avctx->height)
            continue;

        if (!s->frame2->data[0] || !s->frame1->data[0])
            return AVERROR_INVALIDDATA;

        b1 = s->frame1->data[0] + s->frame1->linesize[0] * (start_y + h - 1) + start_x * s->bpp;
        b2 = s->frame2->data[0] + s->frame2->linesize[0] * (start_y + h - 1) + start_x * s->bpp;
        e2 = s->frame2->data[0] + s->frame2->linesize[0] * (mov_y + h - 1) + mov_x * s->bpp;

        if (type == 2) {
            for (int j = 0; j < h; j++) {
                memcpy(b1, b2, w * s->bpp);
                b1 -= s->frame1->linesize[0];
                b2 -= s->frame2->linesize[0];
            }
        } else if (type == 1) {
            for (int j = 0; j < h; j++) {
                memset(b2, 0, w * s->bpp);
                b2 -= s->frame2->linesize[0];
            }
        } else if (type == 0) {
            uint8_t *buffer;

            av_fast_padded_malloc(&s->delta, &s->delta_size, w * h * s->bpp);
            buffer = s->delta;
            if (!buffer)
                return AVERROR(ENOMEM);

            for (int j = 0; j < h; j++) {
                memcpy(buffer + j * w * s->bpp, e2, w * s->bpp);
                e2 -= s->frame2->linesize[0];
            }

            for (int j = 0; j < h; j++) {
                memcpy(b2, buffer + j * w * s->bpp, w * s->bpp);
                b2 -= s->frame2->linesize[0];
            }
        } else {
            return AVERROR_INVALIDDATA;
        }
    }

    bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));

    return 0;
}

#define NEXT_LINE                        \
    if (cx >= w * s->bpp) {              \
        cx = 0;                          \
        cy--;                            \
        b1 -= s->frame1->linesize[0];    \
        b2 -= s->frame2->linesize[0];    \
    }                                    \
    len--;

static int decode_dlta(AVCodecContext *avctx,
                       AVPacket *avpkt, unsigned size)
{
    RASCContext *s = avctx->priv_data;
    GetByteContext *gb = &s->gb;
    GetByteContext dc;
    unsigned uncompressed_size, pos;
    unsigned x, y, w, h;
    int ret, cx, cy, compression;
    uint8_t *b1, *b2;

    pos = bytestream2_tell(gb);
    bytestream2_skip(gb, 12);
    uncompressed_size = bytestream2_get_le32(gb);
    x = bytestream2_get_le32(gb);
    y = bytestream2_get_le32(gb);
    w = bytestream2_get_le32(gb);
    h = bytestream2_get_le32(gb);

    if (x >= avctx->width || y >= avctx->height ||
        w > avctx->width || h > avctx->height)
        return AVERROR_INVALIDDATA;

    if (x + w > avctx->width || y + h > avctx->height)
        return AVERROR_INVALIDDATA;

    bytestream2_skip(gb, 4);
    compression = bytestream2_get_le32(gb);

    if (compression == 1) {
        if (w * h * s->bpp * 3 < uncompressed_size)
            return AVERROR_INVALIDDATA;
        ret = decode_zlib(avctx, avpkt, size, uncompressed_size);
        if (ret < 0)
            return ret;
        bytestream2_init(&dc, s->delta, uncompressed_size);
    } else if (compression == 0) {
        if (bytestream2_get_bytes_left(gb) < uncompressed_size)
            return AVERROR_INVALIDDATA;
        bytestream2_init(&dc, avpkt->data + bytestream2_tell(gb),
                         uncompressed_size);
    } else if (compression == 2) {
        avpriv_request_sample(avctx, "compression %d", compression);
        return AVERROR_PATCHWELCOME;
    } else {
        return AVERROR_INVALIDDATA;
    }

    if (!s->frame2->data[0] || !s->frame1->data[0])
        return AVERROR_INVALIDDATA;

    b1  = s->frame1->data[0] + s->frame1->linesize[0] * (y + h - 1) + x * s->bpp;
    b2  = s->frame2->data[0] + s->frame2->linesize[0] * (y + h - 1) + x * s->bpp;
    cx = 0, cy = h;
    while (bytestream2_get_bytes_left(&dc) > 0) {
        int type = bytestream2_get_byte(&dc);
        int len = bytestream2_get_byte(&dc);
        unsigned fill;

        switch (type) {
        case 1:
            while (len > 0 && cy > 0) {
                cx++;
                NEXT_LINE
            }
            break;
        case 2:
            while (len > 0 && cy > 0) {
                int v0 = b1[cx];
                int v1 = b2[cx];

                b2[cx] = v0;
                b1[cx] = v1;
                cx++;
                NEXT_LINE
            }
            break;
        case 3:
            while (len > 0 && cy > 0) {
                fill = bytestream2_get_byte(&dc);
                b1[cx] = b2[cx];
                b2[cx] = fill;
                cx++;
                NEXT_LINE
            }
            break;
        case 4:
            fill = bytestream2_get_byte(&dc);
            while (len > 0 && cy > 0) {
                AV_WL32(b1 + cx, AV_RL32(b2 + cx));
                AV_WL32(b2 + cx, fill);
                cx++;
                NEXT_LINE
            }
            break;
        case 7:
            fill = bytestream2_get_le32(&dc);
            while (len > 0 && cy > 0) {
                AV_WL32(b1 + cx, AV_RL32(b2 + cx));
                AV_WL32(b2 + cx, fill);
                cx += 4;
                NEXT_LINE
            }
            break;
        case 10:
            while (len > 0 && cy > 0) {
                cx += 4;
                NEXT_LINE
            }
            break;
        case 12:
            while (len > 0 && cy > 0) {
                unsigned v0, v1;

                v0 = AV_RL32(b2 + cx);
                v1 = AV_RL32(b1 + cx);
                AV_WL32(b2 + cx, v1);
                AV_WL32(b1 + cx, v0);
                cx += 4;
                NEXT_LINE
            }
            break;
        case 13:
            while (len > 0 && cy > 0) {
                fill = bytestream2_get_le32(&dc);
                AV_WL32(b1 + cx, AV_RL32(b2 + cx));
                AV_WL32(b2 + cx, fill);
                cx += 4;
                NEXT_LINE
            }
            break;
        default:
            avpriv_request_sample(avctx, "runlen %d", type);
            return AVERROR_INVALIDDATA;
        }
    }

    bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));

    return 0;
}

static int decode_kfrm(AVCodecContext *avctx,
                       AVPacket *avpkt, unsigned size)
{
    RASCContext *s = avctx->priv_data;
    GetByteContext *gb = &s->gb;
    uint8_t *dst;
    unsigned pos;
    int zret, ret;

    pos = bytestream2_tell(gb);
    if (bytestream2_peek_le32(gb) == 0x65) {
        ret = decode_fint(avctx, avpkt, size);
        if (ret < 0)
            return ret;
    }

    if (!s->frame2->data[0])
        return AVERROR_INVALIDDATA;

    zret = inflateReset(&s->zstream);
    if (zret != Z_OK) {
        av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
        return AVERROR_EXTERNAL;
    }

    s->zstream.next_in  = avpkt->data + bytestream2_tell(gb);
    s->zstream.avail_in = bytestream2_get_bytes_left(gb);

    dst = s->frame2->data[0] + (avctx->height - 1) * s->frame2->linesize[0];
    for (int i = 0; i < avctx->height; i++) {
        s->zstream.next_out  = dst;
        s->zstream.avail_out = s->stride;

        zret = inflate(&s->zstream, Z_SYNC_FLUSH);
        if (zret != Z_OK && zret != Z_STREAM_END) {
            av_log(avctx, AV_LOG_ERROR,
                   "Inflate failed with return code: %d.\n", zret);
            return AVERROR_INVALIDDATA;
        }

        dst -= s->frame2->linesize[0];
    }

    dst = s->frame1->data[0] + (avctx->height - 1) * s->frame1->linesize[0];
    for (int i = 0; i < avctx->height; i++) {
        s->zstream.next_out  = dst;
        s->zstream.avail_out = s->stride;

        zret = inflate(&s->zstream, Z_SYNC_FLUSH);
        if (zret != Z_OK && zret != Z_STREAM_END) {
            av_log(avctx, AV_LOG_ERROR,
                   "Inflate failed with return code: %d.\n", zret);
            return AVERROR_INVALIDDATA;
        }

        dst -= s->frame1->linesize[0];
    }

    bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));

    return 0;
}

static int decode_mous(AVCodecContext *avctx,
                       AVPacket *avpkt, unsigned size)
{
    RASCContext *s = avctx->priv_data;
    GetByteContext *gb = &s->gb;
    unsigned w, h, pos, uncompressed_size;
    int ret;

    pos = bytestream2_tell(gb);
    bytestream2_skip(gb, 8);
    w = bytestream2_get_le32(gb);
    h = bytestream2_get_le32(gb);
    bytestream2_skip(gb, 12);
    uncompressed_size = bytestream2_get_le32(gb);

    if (w > avctx->width || h > avctx->height)
        return AVERROR_INVALIDDATA;

    if (uncompressed_size != 3 * w * h)
        return AVERROR_INVALIDDATA;

    av_fast_padded_malloc(&s->cursor, &s->cursor_size, uncompressed_size);
    if (!s->cursor)
        return AVERROR(ENOMEM);

    ret = decode_zlib(avctx, avpkt,
                      size - (bytestream2_tell(gb) - pos),
                      uncompressed_size);
    if (ret < 0)
        return ret;
    memcpy(s->cursor, s->delta, uncompressed_size);

    bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));

    s->cursor_w = w;
    s->cursor_h = h;

    return 0;
}

static int decode_mpos(AVCodecContext *avctx,
                       AVPacket *avpkt, unsigned size)
{
    RASCContext *s = avctx->priv_data;
    GetByteContext *gb = &s->gb;
    unsigned pos;

    pos = bytestream2_tell(gb);
    bytestream2_skip(gb, 8);
    s->cursor_x = bytestream2_get_le32(gb);
    s->cursor_y = bytestream2_get_le32(gb);

    bytestream2_skip(gb, size - (bytestream2_tell(gb) - pos));

    return 0;
}

static void draw_cursor(AVCodecContext *avctx)
{
    RASCContext *s = avctx->priv_data;
    uint8_t *dst, *pal;

    if (!s->cursor)
        return;

    if (s->cursor_x >= avctx->width || s->cursor_y >= avctx->height)
        return;

    if (s->cursor_x + s->cursor_w > avctx->width ||
        s->cursor_y + s->cursor_h > avctx->height)
        return;

    if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
        pal = s->frame->data[1];
        for (int i = 0; i < s->cursor_h; i++) {
            for (int j = 0; j < s->cursor_w; j++) {
                int cr = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 0];
                int cg = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 1];
                int cb = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 2];
                int best = INT_MAX;
                int index = 0;
                int dist;

                if (cr == s->cursor[0] && cg == s->cursor[1] && cb == s->cursor[2])
                    continue;

                dst = s->frame->data[0] + s->frame->linesize[0] * (s->cursor_y + i) + (s->cursor_x + j);
                for (int k = 0; k < 256; k++) {
                    int pr = pal[k * 4 + 0];
                    int pg = pal[k * 4 + 1];
                    int pb = pal[k * 4 + 2];

                    dist = FFABS(cr - pr) + FFABS(cg - pg) + FFABS(cb - pb);
                    if (dist < best) {
                        best = dist;
                        index = k;
                    }
                }
                dst[0] = index;
            }
        }
    } else if (avctx->pix_fmt == AV_PIX_FMT_RGB555LE) {
        for (int i = 0; i < s->cursor_h; i++) {
            for (int j = 0; j < s->cursor_w; j++) {
                int cr = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 0];
                int cg = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 1];
                int cb = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 2];

                if (cr == s->cursor[0] && cg == s->cursor[1] && cb == s->cursor[2])
                    continue;

                cr >>= 3; cg >>=3; cb >>= 3;
                dst = s->frame->data[0] + s->frame->linesize[0] * (s->cursor_y + i) + 2 * (s->cursor_x + j);
                AV_WL16(dst, cr | cg << 5 | cb << 10);
            }
        }
    } else if (avctx->pix_fmt == AV_PIX_FMT_BGR0) {
        for (int i = 0; i < s->cursor_h; i++) {
            for (int j = 0; j < s->cursor_w; j++) {
                int cr = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 0];
                int cg = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 1];
                int cb = s->cursor[3 * s->cursor_w * (s->cursor_h - i - 1) + 3 * j + 2];

                if (cr == s->cursor[0] && cg == s->cursor[1] && cb == s->cursor[2])
                    continue;

                dst = s->frame->data[0] + s->frame->linesize[0] * (s->cursor_y + i) + 4 * (s->cursor_x + j);
                dst[0] = cb;
                dst[1] = cg;
                dst[2] = cr;
            }
        }
    }
}

static int decode_frame(AVCodecContext *avctx,
                        void *data, int *got_frame,
                        AVPacket *avpkt)
{
    RASCContext *s = avctx->priv_data;
    GetByteContext *gb = &s->gb;
    int ret, intra = 0;
    AVFrame *frame = data;

    bytestream2_init(gb, avpkt->data, avpkt->size);

    if (bytestream2_peek_le32(gb) == EMPT)
        return avpkt->size;

    s->frame = frame;

    while (bytestream2_get_bytes_left(gb) > 0) {
        unsigned type, size = 0;

        if (bytestream2_get_bytes_left(gb) < 8)
            return AVERROR_INVALIDDATA;

        type = bytestream2_get_le32(gb);
        if (type == KBND || type == BNDL) {
            intra = type == KBND;
            type = bytestream2_get_le32(gb);
        }

        size = bytestream2_get_le32(gb);
        if (bytestream2_get_bytes_left(gb) < size)
            return AVERROR_INVALIDDATA;

        switch (type) {
        case FINT:
        case INIT:
            ret = decode_fint(avctx, avpkt, size);
            break;
        case KFRM:
            ret = decode_kfrm(avctx, avpkt, size);
            break;
        case DLTA:
            ret = decode_dlta(avctx, avpkt, size);
            break;
        case MOVE:
            ret = decode_move(avctx, avpkt, size);
            break;
        case MOUS:
            ret = decode_mous(avctx, avpkt, size);
            break;
        case MPOS:
            ret = decode_mpos(avctx, avpkt, size);
            break;
        default:
            bytestream2_skip(gb, size);
        }

        if (ret < 0)
            return ret;
    }

    if (!s->frame2->data[0] || !s->frame1->data[0])
        return AVERROR_INVALIDDATA;

    if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0)
        return ret;

    copy_plane(avctx, s->frame2, s->frame);
    if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
        memcpy(s->frame->data[1], s->frame2->data[1], 1024);
    if (!s->skip_cursor)
        draw_cursor(avctx);

    s->frame->key_frame = intra;
    s->frame->pict_type = intra ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;

    *got_frame = 1;

    return avpkt->size;
}

static av_cold int decode_init(AVCodecContext *avctx)
{
    RASCContext *s = avctx->priv_data;
    int zret;

    s->zstream.zalloc = Z_NULL;
    s->zstream.zfree = Z_NULL;
    s->zstream.opaque = Z_NULL;
    zret = inflateInit(&s->zstream);
    if (zret != Z_OK) {
        av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
        return AVERROR_EXTERNAL;
    }

    s->frame1 = av_frame_alloc();
    s->frame2 = av_frame_alloc();
    if (!s->frame1 || !s->frame2)
        return AVERROR(ENOMEM);

    return 0;
}

static av_cold int decode_close(AVCodecContext *avctx)
{
    RASCContext *s = avctx->priv_data;

    av_freep(&s->cursor);
    s->cursor_size = 0;
    av_freep(&s->delta);
    s->delta_size = 0;
    av_frame_free(&s->frame1);
    av_frame_free(&s->frame2);
    inflateEnd(&s->zstream);

    return 0;
}

static void decode_flush(AVCodecContext *avctx)
{
    RASCContext *s = avctx->priv_data;

    clear_plane(avctx, s->frame1);
    clear_plane(avctx, s->frame2);
}

static const AVOption options[] = {
{ "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 },
{ NULL },
};

static const AVClass rasc_decoder_class = {
    .class_name = "rasc decoder",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};

AVCodec ff_rasc_decoder = {
    .name             = "rasc",
    .long_name        = NULL_IF_CONFIG_SMALL("RemotelyAnywhere Screen Capture"),
    .type             = AVMEDIA_TYPE_VIDEO,
    .id               = AV_CODEC_ID_RASC,
    .priv_data_size   = sizeof(RASCContext),
    .init             = decode_init,
    .close            = decode_close,
    .decode           = decode_frame,
    .flush            = decode_flush,
    .capabilities     = AV_CODEC_CAP_DR1,
    .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
                        FF_CODEC_CAP_INIT_CLEANUP,
    .priv_class       = &rasc_decoder_class,
};
