/*
 * 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 = bytestream2_get_le32(gb);
        uint32_t a1 = bytestream2_get_le32(gb);
        uint32_t a2 = bytestream2_get_le32(gb);
        uint32_t 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;

        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;
            avctx->width   = bytestream2_get_le32(gb);
            avctx->height  = bytestream2_get_le32(gb);
            s->color_model = bytestream2_get_le32(gb);
            if (bytestream2_get_le32(gb) != 1)
                return AVERROR_INVALIDDATA;
            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]);

            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"),
};
