/*
 * CRI image decoder
 *
 * Copyright (c) 2020 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
 */

/**
 * @file
 * Cintel RAW image decoder
 */

#define BITSTREAM_READER_LE

#include "libavutil/intfloat.h"
#include "libavutil/display.h"
#include "avcodec.h"
#include "bytestream.h"
#include "get_bits.h"
#include "internal.h"
#include "thread.h"

typedef struct CRIContext {
    AVCodecContext *jpeg_avctx;   // wrapper context for MJPEG
    AVFrame *jpgframe;            // decoded JPEG tile

    GetByteContext gb;
    int color_model;
    const uint8_t *data;
    unsigned data_size;
    uint64_t tile_size[4];
} CRIContext;

static av_cold int cri_decode_init(AVCodecContext *avctx)
{
    CRIContext *s = avctx->priv_data;
    const AVCodec *codec;
    int ret;

    s->jpgframe = av_frame_alloc();
    if (!s->jpgframe)
        return AVERROR(ENOMEM);

    codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);
    if (!codec)
        return AVERROR_BUG;
    s->jpeg_avctx = avcodec_alloc_context3(codec);
    if (!s->jpeg_avctx)
        return AVERROR(ENOMEM);
    s->jpeg_avctx->flags = avctx->flags;
    s->jpeg_avctx->flags2 = avctx->flags2;
    s->jpeg_avctx->dct_algo = avctx->dct_algo;
    s->jpeg_avctx->idct_algo = avctx->idct_algo;
    ret = avcodec_open2(s->jpeg_avctx, codec, NULL);
    if (ret < 0)
        return ret;

    return 0;
}

static void unpack_10bit(GetByteContext *gb, uint16_t *dst, int shift,
                         int w, int h, ptrdiff_t stride)
{
    int count = w * h;
    int pos = 0;

    while (count > 0) {
        uint32_t a0, a1, a2, a3;
        if (bytestream2_get_bytes_left(gb) < 4)
            break;
        a0 = bytestream2_get_le32(gb);
        a1 = bytestream2_get_le32(gb);
        a2 = bytestream2_get_le32(gb);
        a3 = bytestream2_get_le32(gb);
        dst[pos] = (((a0 >> 1) & 0xE00) | (a0 & 0x1FF)) << shift;
        pos++;
        if (pos >= w) {
            if (count == 1)
                break;
            dst += stride;
            pos = 0;
        }
        dst[pos] = (((a0 >> 13) & 0x3F) | ((a0 >> 14) & 0xFC0)) << shift;
        pos++;
        if (pos >= w) {
            if (count == 2)
                break;
            dst += stride;
            pos = 0;
        }
        dst[pos] = (((a0 >> 26) & 7) | ((a1 & 0x1FF) << 3)) << shift;
        pos++;
        if (pos >= w) {
            if (count == 3)
                break;
            dst += stride;
            pos = 0;
        }
        dst[pos] = (((a1 >> 10) & 0x1FF) | ((a1 >> 11) & 0xE00)) << shift;
        pos++;
        if (pos >= w) {
            if (count == 4)
                break;
            dst += stride;
            pos = 0;
        }
        dst[pos] = (((a1 >> 23) & 0x3F) | ((a2 & 0x3F) << 6)) << shift;
        pos++;
        if (pos >= w) {
            if (count == 5)
                break;
            dst += stride;
            pos = 0;
        }
        dst[pos] = (((a2 >> 7) & 0xFF8) | ((a2 >> 6) & 7)) << shift;
        pos++;
        if (pos >= w) {
            if (count == 6)
                break;
            dst += stride;
            pos = 0;
        }
        dst[pos] = (((a3 & 7) << 9) | ((a2 >> 20) & 0x1FF)) << shift;
        pos++;
        if (pos >= w) {
            if (count == 7)
                break;
            dst += stride;
            pos = 0;
        }
        dst[pos] = (((a3 >> 4) & 0xFC0) | ((a3 >> 3) & 0x3F)) << shift;
        pos++;
        if (pos >= w) {
            if (count == 8)
                break;
            dst += stride;
            pos = 0;
        }
        dst[pos] = (((a3 >> 16) & 7) | ((a3 >> 17) & 0xFF8)) << shift;
        pos++;
        if (pos >= w) {
            if (count == 9)
                break;
            dst += stride;
            pos = 0;
        }

        count -= 9;
    }
}

static int cri_decode_frame(AVCodecContext *avctx, void *data,
                            int *got_frame, AVPacket *avpkt)
{
    CRIContext *s = avctx->priv_data;
    GetByteContext *gb = &s->gb;
    ThreadFrame frame = { .f = data };
    int ret, bps, hflip = 0, vflip = 0;
    AVFrameSideData *rotation;
    int compressed = 0;
    AVFrame *p = data;

    s->data = NULL;
    s->data_size = 0;

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

    while (bytestream2_get_bytes_left(gb) > 8) {
        char codec_name[1024];
        uint32_t key, length;
        float framerate;
        int width, height;

        key    = bytestream2_get_le32(gb);
        length = bytestream2_get_le32(gb);

        switch (key) {
        case 1:
            if (length != 4)
                return AVERROR_INVALIDDATA;

            if (bytestream2_get_le32(gb) != MKTAG('D', 'V', 'C', 'C'))
                return AVERROR_INVALIDDATA;
            break;
        case 100:
            if (length < 16)
                return AVERROR_INVALIDDATA;
            width   = bytestream2_get_le32(gb);
            height  = bytestream2_get_le32(gb);
            s->color_model = bytestream2_get_le32(gb);
            if (bytestream2_get_le32(gb) != 1)
                return AVERROR_INVALIDDATA;
            ret = ff_set_dimensions(avctx, width, height);
            if (ret < 0)
                return ret;
            length -= 16;
            goto skip;
        case 101:
            if (length != 4)
                return AVERROR_INVALIDDATA;

            if (bytestream2_get_le32(gb) != 0)
                return AVERROR_INVALIDDATA;
            break;
        case 102:
            bytestream2_get_buffer(gb, codec_name, FFMIN(length, sizeof(codec_name) - 1));
            length -= FFMIN(length, sizeof(codec_name) - 1);
            if (strncmp(codec_name, "cintel_craw", FFMIN(length, sizeof(codec_name) - 1)))
                return AVERROR_INVALIDDATA;
            compressed = 1;
            goto skip;
        case 103:
            if (bytestream2_get_bytes_left(gb) < length)
                return AVERROR_INVALIDDATA;
            s->data = gb->buffer;
            s->data_size = length;
            goto skip;
        case 105:
            hflip = bytestream2_get_byte(gb) != 0;
            length--;
            goto skip;
        case 106:
            vflip = bytestream2_get_byte(gb) != 0;
            length--;
            goto skip;
        case 107:
            if (length != 4)
                return AVERROR_INVALIDDATA;
            framerate = av_int2float(bytestream2_get_le32(gb));
            avctx->framerate.num = framerate * 1000;
            avctx->framerate.den = 1000;
            break;
        case 119:
            if (length != 32)
                return AVERROR_INVALIDDATA;

            for (int i = 0; i < 4; i++)
                s->tile_size[i] = bytestream2_get_le64(gb);
            break;
        default:
            av_log(avctx, AV_LOG_DEBUG, "skipping unknown key %u of length %u\n", key, length);
skip:
            bytestream2_skip(gb, length);
        }
    }

    switch (s->color_model) {
    case 76:
    case 88:
        avctx->pix_fmt = AV_PIX_FMT_BAYER_BGGR16;
        break;
    case 77:
    case 89:
        avctx->pix_fmt = AV_PIX_FMT_BAYER_GBRG16;
        break;
    case 78:
    case 90:
        avctx->pix_fmt = AV_PIX_FMT_BAYER_RGGB16;
        break;
    case 45:
    case 79:
    case 91:
        avctx->pix_fmt = AV_PIX_FMT_BAYER_GRBG16;
        break;
    }

    switch (s->color_model) {
    case 45:
        bps = 10;
        break;
    case 76:
    case 77:
    case 78:
    case 79:
        bps = 12;
        break;
    case 88:
    case 89:
    case 90:
    case 91:
        bps = 16;
        break;
    default:
        return AVERROR_INVALIDDATA;
    }

    if (compressed) {
        for (int i = 0; i < 4; i++) {
            if (s->tile_size[i] >= s->data_size)
                return AVERROR_INVALIDDATA;
        }

        if (s->tile_size[0] + s->tile_size[1] + s->tile_size[2] + s->tile_size[3] !=
            s->data_size)
            return AVERROR_INVALIDDATA;
    }

    if (!s->data || !s->data_size)
        return AVERROR_INVALIDDATA;

    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
        return ret;

    avctx->bits_per_raw_sample = bps;

    if (!compressed && s->color_model == 45) {
        uint16_t *dst = (uint16_t *)p->data[0];
        GetByteContext gb;

        bytestream2_init(&gb, s->data, s->data_size);
        unpack_10bit(&gb, dst, 4, avctx->width, avctx->height, p->linesize[0] / 2);
    } else if (!compressed) {
        GetBitContext gbit;
        const int shift = 16 - bps;

        ret = init_get_bits8(&gbit, s->data, s->data_size);
        if (ret < 0)
            return ret;

        for (int y = 0; y < avctx->height; y++) {
            uint16_t *dst = (uint16_t *)(p->data[0] + y * p->linesize[0]);

            if (get_bits_left(&gbit) < avctx->width * bps)
                break;

            for (int x = 0; x < avctx->width; x++)
                dst[x] = get_bits(&gbit, bps) << shift;
        }
    } else {
        unsigned offset = 0;

        for (int tile = 0; tile < 4; tile++) {
            AVPacket jpkt;

            av_init_packet(&jpkt);
            jpkt.data = (uint8_t *)s->data + offset;
            jpkt.size = s->tile_size[tile];

            ret = avcodec_send_packet(s->jpeg_avctx, &jpkt);
            if (ret < 0) {
                av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n");
                return ret;
            }

            ret = avcodec_receive_frame(s->jpeg_avctx, s->jpgframe);
            if (ret < 0 || s->jpgframe->format != AV_PIX_FMT_GRAY16 ||
                s->jpeg_avctx->width  * 2 != avctx->width ||
                s->jpeg_avctx->height * 2 != avctx->height) {
                if (ret < 0) {
                    av_log(avctx, AV_LOG_ERROR,
                           "JPEG decoding error (%d).\n", ret);
                } else {
                    av_log(avctx, AV_LOG_ERROR,
                           "JPEG invalid format.\n");
                    ret = AVERROR_INVALIDDATA;
                }

                /* Normally skip, if error explode */
                if (avctx->err_recognition & AV_EF_EXPLODE)
                    return ret;
                else
                    return 0;
            }

            for (int y = 0; y < s->jpeg_avctx->height; y++) {
                const int hw =  s->jpgframe->width / 2;
                uint16_t *dst = (uint16_t *)(p->data[0] + (y * 2) * p->linesize[0] + tile * hw * 2);
                const uint16_t *src = (const uint16_t *)(s->jpgframe->data[0] + y * s->jpgframe->linesize[0]);

                memcpy(dst, src, hw * 2);
                src += hw;
                dst += p->linesize[0] / 2;
                memcpy(dst, src, hw * 2);
            }

            av_frame_unref(s->jpgframe);
            offset += s->tile_size[tile];
        }
    }

    if (hflip || vflip) {
        rotation = av_frame_new_side_data(p, AV_FRAME_DATA_DISPLAYMATRIX,
                                          sizeof(int32_t) * 9);
        if (rotation) {
            av_display_rotation_set((int32_t *)rotation->data, 0.f);
            av_display_matrix_flip((int32_t *)rotation->data, hflip, vflip);
        }
    }

    p->pict_type = AV_PICTURE_TYPE_I;
    p->key_frame = 1;

    *got_frame = 1;

    return 0;
}

static av_cold int cri_decode_close(AVCodecContext *avctx)
{
    CRIContext *s = avctx->priv_data;

    av_frame_free(&s->jpgframe);
    avcodec_free_context(&s->jpeg_avctx);

    return 0;
}

AVCodec ff_cri_decoder = {
    .name           = "cri",
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = AV_CODEC_ID_CRI,
    .priv_data_size = sizeof(CRIContext),
    .init           = cri_decode_init,
    .decode         = cri_decode_frame,
    .close          = cri_decode_close,
    .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
    .long_name      = NULL_IF_CONFIG_SMALL("Cintel RAW"),
};
