/*
 * DPX (.dpx) image decoder
 * Copyright (c) 2009 Jimmy Christensen
 *
 * 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 "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
#include "libavutil/imgutils.h"
#include "bytestream.h"
#include "avcodec.h"
#include "internal.h"

static unsigned int read16(const uint8_t **ptr, int is_big)
{
    unsigned int temp;
    if (is_big) {
        temp = AV_RB16(*ptr);
    } else {
        temp = AV_RL16(*ptr);
    }
    *ptr += 2;
    return temp;
}

static unsigned int read32(const uint8_t **ptr, int is_big)
{
    unsigned int temp;
    if (is_big) {
        temp = AV_RB32(*ptr);
    } else {
        temp = AV_RL32(*ptr);
    }
    *ptr += 4;
    return temp;
}

static uint16_t read10in32(const uint8_t **ptr, uint32_t * lbuf,
                                  int * n_datum, int is_big)
{
    if (*n_datum)
        (*n_datum)--;
    else {
        *lbuf = read32(ptr, is_big);
        *n_datum = 2;
    }

    *lbuf = (*lbuf << 10) | (*lbuf >> 22);

    return *lbuf & 0x3FF;
}

static int decode_frame(AVCodecContext *avctx,
                        void *data,
                        int *got_frame,
                        AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size       = avpkt->size;
    AVFrame *const p = data;
    uint8_t *ptr[AV_NUM_DATA_POINTERS];

    unsigned int offset;
    int magic_num, endian;
    int x, y, stride, i, ret;
    int w, h, bits_per_color, descriptor, elements, packing;
    int encoding, need_align = 0;

    unsigned int rgbBuffer = 0;
    int n_datum = 0;

    if (avpkt->size <= 1634) {
        av_log(avctx, AV_LOG_ERROR, "Packet too small for DPX header\n");
        return AVERROR_INVALIDDATA;
    }

    magic_num = AV_RB32(buf);
    buf += 4;

    /* Check if the files "magic number" is "SDPX" which means it uses
     * big-endian or XPDS which is for little-endian files */
    if (magic_num == AV_RL32("SDPX")) {
        endian = 0;
    } else if (magic_num == AV_RB32("SDPX")) {
        endian = 1;
    } else {
        av_log(avctx, AV_LOG_ERROR, "DPX marker not found\n");
        return AVERROR_INVALIDDATA;
    }

    offset = read32(&buf, endian);
    if (avpkt->size <= offset) {
        av_log(avctx, AV_LOG_ERROR, "Invalid data start offset\n");
        return AVERROR_INVALIDDATA;
    }

    // Check encryption
    buf = avpkt->data + 660;
    ret = read32(&buf, endian);
    if (ret != 0xFFFFFFFF) {
        avpriv_report_missing_feature(avctx, "Encryption");
        av_log(avctx, AV_LOG_WARNING, "The image is encrypted and may "
               "not properly decode.\n");
    }

    // Need to end in 0x304 offset from start of file
    buf = avpkt->data + 0x304;
    w = read32(&buf, endian);
    h = read32(&buf, endian);

    if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
        return ret;

    // Need to end in 0x320 to read the descriptor
    buf += 20;
    descriptor = buf[0];

    // Need to end in 0x323 to read the bits per color
    buf += 3;
    avctx->bits_per_raw_sample =
    bits_per_color = buf[0];
    buf++;
    packing = read16(&buf, endian);
    encoding = read16(&buf, endian);

    if (packing > 1) {
        avpriv_report_missing_feature(avctx, "Packing %d", packing);
        return AVERROR_PATCHWELCOME;
    }
    if (encoding) {
        avpriv_report_missing_feature(avctx, "Encoding %d", encoding);
        return AVERROR_PATCHWELCOME;
    }

    buf += 820;
    avctx->sample_aspect_ratio.num = read32(&buf, endian);
    avctx->sample_aspect_ratio.den = read32(&buf, endian);
    if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0)
        av_reduce(&avctx->sample_aspect_ratio.num, &avctx->sample_aspect_ratio.den,
                   avctx->sample_aspect_ratio.num,  avctx->sample_aspect_ratio.den,
                  0x10000);
    else
        avctx->sample_aspect_ratio = (AVRational){ 0, 1 };

    if (offset >= 1724 + 4) {
        buf = avpkt->data + 1724;
        i = read32(&buf, endian);
        if(i) {
            AVRational q = av_d2q(av_int2float(i), 4096);
            if (q.num > 0 && q.den > 0)
                avctx->framerate = q;
        }
    }

    switch (descriptor) {
    case 6:  // Y
        elements = 1;
        break;
    case 52: // ABGR
    case 51: // RGBA
    case 103: // UYVA4444
        elements = 4;
        break;
    case 50: // RGB
    case 102: // UYV444
        elements = 3;
        break;
    case 100: // UYVY422
        elements = 2;
        break;
    default:
        avpriv_report_missing_feature(avctx, "Descriptor %d", descriptor);
        return AVERROR_PATCHWELCOME;
    }

    switch (bits_per_color) {
    case 8:
        stride = avctx->width * elements;
        break;
    case 10:
        if (!packing) {
            av_log(avctx, AV_LOG_ERROR, "Packing to 32bit required\n");
            return -1;
        }
        stride = (avctx->width * elements + 2) / 3 * 4;
        break;
    case 12:
        if (!packing) {
            av_log(avctx, AV_LOG_ERROR, "Packing to 16bit required\n");
            return -1;
        }
        stride = 2 * avctx->width * elements;
        break;
    case 16:
        stride = 2 * avctx->width * elements;
        break;
    case 1:
    case 32:
    case 64:
        avpriv_report_missing_feature(avctx, "Depth %d", bits_per_color);
        return AVERROR_PATCHWELCOME;
    default:
        return AVERROR_INVALIDDATA;
    }

    // Table 3c: Runs will always break at scan line boundaries. Packing
    // will always break to the next 32-bit word at scan-line boundaries.
    // Unfortunately, the encoder produced invalid files, so attempt
    // to detect it
    need_align = FFALIGN(stride, 4);
    if (need_align*avctx->height + (int64_t)offset > avpkt->size) {
        // Alignment seems unappliable, try without
        if (stride*avctx->height + (int64_t)offset > avpkt->size) {
            av_log(avctx, AV_LOG_ERROR, "Overread buffer. Invalid header?\n");
            return AVERROR_INVALIDDATA;
        } else {
            av_log(avctx, AV_LOG_INFO, "Decoding DPX without scanline "
                   "alignment.\n");
            need_align = 0;
        }
    } else {
        need_align -= stride;
        stride = FFALIGN(stride, 4);
    }

    switch (1000 * descriptor + 10 * bits_per_color + endian) {
    case 6081:
    case 6080:
        avctx->pix_fmt = AV_PIX_FMT_GRAY8;
        break;
    case 50081:
    case 50080:
        avctx->pix_fmt = AV_PIX_FMT_RGB24;
        break;
    case 52081:
    case 52080:
        avctx->pix_fmt = AV_PIX_FMT_ABGR;
        break;
    case 51081:
    case 51080:
        avctx->pix_fmt = AV_PIX_FMT_RGBA;
        break;
    case 50100:
    case 51100:
    case 50101:
    case 51101:
        avctx->pix_fmt = AV_PIX_FMT_GBRP10;
        break;
    case 50120:
    case 51120:
    case 50121:
    case 51121:
        avctx->pix_fmt = AV_PIX_FMT_GBRP12;
        break;
    case 6161:
        avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
        break;
    case 6160:
        avctx->pix_fmt = AV_PIX_FMT_GRAY16LE;
        break;
    case 50161:
        avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
        break;
    case 50160:
        avctx->pix_fmt = AV_PIX_FMT_RGB48LE;
        break;
    case 51161:
        avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
        break;
    case 51160:
        avctx->pix_fmt = AV_PIX_FMT_RGBA64LE;
        break;
    case 100081:
        avctx->pix_fmt = AV_PIX_FMT_UYVY422;
        break;
    case 102081:
        avctx->pix_fmt = AV_PIX_FMT_YUV444P;
        break;
    case 103081:
        avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
        break;
    default:
        av_log(avctx, AV_LOG_ERROR, "Unsupported format\n");
        return AVERROR_PATCHWELCOME;
    }

    ff_set_sar(avctx, avctx->sample_aspect_ratio);

    if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
        return ret;

    // Move pointer to offset from start of file
    buf =  avpkt->data + offset;

    for (i=0; i<AV_NUM_DATA_POINTERS; i++)
        ptr[i] = p->data[i];

    switch (bits_per_color) {
    case 10:
        for (x = 0; x < avctx->height; x++) {
            uint16_t *dst[3] = {(uint16_t*)ptr[0],
                                (uint16_t*)ptr[1],
                                (uint16_t*)ptr[2]};
            for (y = 0; y < avctx->width; y++) {
                *dst[2]++ = read10in32(&buf, &rgbBuffer,
                                       &n_datum, endian);
                *dst[0]++ = read10in32(&buf, &rgbBuffer,
                                       &n_datum, endian);
                *dst[1]++ = read10in32(&buf, &rgbBuffer,
                                       &n_datum, endian);
                // For 10 bit, ignore alpha
                if (elements == 4)
                    read10in32(&buf, &rgbBuffer,
                               &n_datum, endian);
            }
            n_datum = 0;
            for (i = 0; i < 3; i++)
                ptr[i] += p->linesize[i];
        }
        break;
    case 12:
        for (x = 0; x < avctx->height; x++) {
            uint16_t *dst[3] = {(uint16_t*)ptr[0],
                                (uint16_t*)ptr[1],
                                (uint16_t*)ptr[2]};
            for (y = 0; y < avctx->width; y++) {
                *dst[2] = read16(&buf, endian) >> 4;
                dst[2]++;
                *dst[0] = read16(&buf, endian) >> 4;
                dst[0]++;
                *dst[1] = read16(&buf, endian) >> 4;
                dst[1]++;
                // For 12 bit, ignore alpha
                if (elements == 4)
                    buf += 2;
            }
            for (i = 0; i < 3; i++)
                ptr[i] += p->linesize[i];
            // Jump to next aligned position
            buf += need_align;
        }
        break;
    case 16:
        elements *= 2;
    case 8:
        if (   avctx->pix_fmt == AV_PIX_FMT_YUVA444P
            || avctx->pix_fmt == AV_PIX_FMT_YUV444P) {
            for (x = 0; x < avctx->height; x++) {
                ptr[0] = p->data[0] + x * p->linesize[0];
                ptr[1] = p->data[1] + x * p->linesize[1];
                ptr[2] = p->data[2] + x * p->linesize[2];
                ptr[3] = p->data[3] + x * p->linesize[3];
                for (y = 0; y < avctx->width; y++) {
                    *ptr[1]++ = *buf++;
                    *ptr[0]++ = *buf++;
                    *ptr[2]++ = *buf++;
                    if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P)
                        *ptr[3]++ = *buf++;
                }
            }
        } else {
        av_image_copy_plane(ptr[0], p->linesize[0],
                            buf, stride,
                            elements * avctx->width, avctx->height);
        }
        break;
    }

    *got_frame = 1;

    return buf_size;
}

AVCodec ff_dpx_decoder = {
    .name           = "dpx",
    .long_name      = NULL_IF_CONFIG_SMALL("DPX (Digital Picture Exchange) image"),
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = AV_CODEC_ID_DPX,
    .decode         = decode_frame,
    .capabilities   = AV_CODEC_CAP_DR1,
};
