/*
 * 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 "cbs.h"
#include "cbs_internal.h"
#include "cbs_jpeg.h"


#define HEADER(name) do { \
        ff_cbs_trace_header(ctx, name); \
    } while (0)

#define CHECK(call) do { \
        err = (call); \
        if (err < 0) \
            return err; \
    } while (0)

#define SUBSCRIPTS(subs, ...) (subs > 0 ? ((int[subs + 1]){ subs, __VA_ARGS__ }) : NULL)

#define u(width, name, range_min, range_max) \
    xu(width, name, range_min, range_max, 0, )
#define us(width, name, sub, range_min, range_max) \
    xu(width, name, range_min, range_max, 1, sub)


#define READ
#define READWRITE read
#define RWContext GetBitContext
#define FUNC(name) cbs_jpeg_read_ ## name

#define xu(width, name, range_min, range_max, subs, ...) do { \
        uint32_t value; \
        CHECK(ff_cbs_read_unsigned(ctx, rw, width, #name, \
                                   SUBSCRIPTS(subs, __VA_ARGS__), \
                                   &value, range_min, range_max)); \
        current->name = value; \
    } while (0)

#include "cbs_jpeg_syntax_template.c"

#undef READ
#undef READWRITE
#undef RWContext
#undef FUNC
#undef xu

#define WRITE
#define READWRITE write
#define RWContext PutBitContext
#define FUNC(name) cbs_jpeg_write_ ## name

#define xu(width, name, range_min, range_max, subs, ...) do { \
        uint32_t value = current->name; \
        CHECK(ff_cbs_write_unsigned(ctx, rw, width, #name, \
                                    SUBSCRIPTS(subs, __VA_ARGS__), \
                                    value, range_min, range_max)); \
    } while (0)


#include "cbs_jpeg_syntax_template.c"

#undef WRITE
#undef READWRITE
#undef RWContext
#undef FUNC
#undef xu


static void cbs_jpeg_free_application_data(void *opaque, uint8_t *content)
{
    JPEGRawApplicationData *ad = (JPEGRawApplicationData*)content;
    av_buffer_unref(&ad->Ap_ref);
    av_freep(&content);
}

static void cbs_jpeg_free_comment(void *opaque, uint8_t *content)
{
    JPEGRawComment *comment = (JPEGRawComment*)content;
    av_buffer_unref(&comment->Cm_ref);
    av_freep(&content);
}

static void cbs_jpeg_free_scan(void *opaque, uint8_t *content)
{
    JPEGRawScan *scan = (JPEGRawScan*)content;
    av_buffer_unref(&scan->data_ref);
    av_freep(&content);
}

static int cbs_jpeg_split_fragment(CodedBitstreamContext *ctx,
                                   CodedBitstreamFragment *frag,
                                   int header)
{
    AVBufferRef *data_ref;
    uint8_t *data;
    size_t data_size;
    int unit, start, end, marker, next_start, next_marker;
    int err, i, j, length;

    if (frag->data_size < 4) {
        // Definitely too short to be meaningful.
        return AVERROR_INVALIDDATA;
    }

    for (i = 0; i + 1 < frag->data_size && frag->data[i] != 0xff; i++);
    if (i > 0) {
        av_log(ctx->log_ctx, AV_LOG_WARNING, "Discarding %d bytes at "
               "beginning of image.\n", i);
    }
    for (++i; i + 1 < frag->data_size && frag->data[i] == 0xff; i++);
    if (i + 1 >= frag->data_size && frag->data[i]) {
        av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: "
               "no SOI marker found.\n");
        return AVERROR_INVALIDDATA;
    }
    marker = frag->data[i];
    if (marker != JPEG_MARKER_SOI) {
        av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: first "
               "marker is %02x, should be SOI.\n", marker);
        return AVERROR_INVALIDDATA;
    }
    for (++i; i + 1 < frag->data_size && frag->data[i] == 0xff; i++);
    if (i + 1 >= frag->data_size) {
        av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: "
               "no image content found.\n");
        return AVERROR_INVALIDDATA;
    }
    marker = frag->data[i];
    start  = i + 1;

    for (unit = 0;; unit++) {
        if (marker == JPEG_MARKER_EOI) {
            break;
        } else if (marker == JPEG_MARKER_SOS) {
            next_marker = -1;
            end = start;
            for (i = start; i + 1 < frag->data_size; i++) {
                if (frag->data[i] != 0xff)
                    continue;
                end = i;
                for (++i; i + 1 < frag->data_size &&
                          frag->data[i] == 0xff; i++);
                if (i + 1 < frag->data_size) {
                    if (frag->data[i] == 0x00)
                        continue;
                    next_marker = frag->data[i];
                    next_start  = i + 1;
                }
                break;
            }
        } else {
            i = start;
            if (i + 2 > frag->data_size) {
                av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: "
                       "truncated at %02x marker.\n", marker);
                return AVERROR_INVALIDDATA;
            }
            length = AV_RB16(frag->data + i);
            if (i + length > frag->data_size) {
                av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: "
                       "truncated at %02x marker segment.\n", marker);
                return AVERROR_INVALIDDATA;
            }
            end = start + length;

            i = end;
            if (frag->data[i] != 0xff) {
                next_marker = -1;
            } else {
                for (++i; i + 1 < frag->data_size &&
                          frag->data[i] == 0xff; i++);
                if (i + 1 >= frag->data_size) {
                    next_marker = -1;
                } else {
                    next_marker = frag->data[i];
                    next_start  = i + 1;
                }
            }
        }

        if (marker == JPEG_MARKER_SOS) {
            length = AV_RB16(frag->data + start);

            if (length > end - start)
                return AVERROR_INVALIDDATA;

            data_ref = NULL;
            data     = av_malloc(end - start +
                                 AV_INPUT_BUFFER_PADDING_SIZE);
            if (!data)
                return AVERROR(ENOMEM);

            memcpy(data, frag->data + start, length);
            for (i = start + length, j = length; i < end; i++, j++) {
                if (frag->data[i] == 0xff) {
                    while (frag->data[i] == 0xff)
                        ++i;
                    data[j] = 0xff;
                } else {
                    data[j] = frag->data[i];
                }
            }
            data_size = j;

            memset(data + data_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);

        } else {
            data      = frag->data + start;
            data_size = end - start;
            data_ref  = frag->data_ref;
        }

        err = ff_cbs_insert_unit_data(frag, unit, marker,
                                      data, data_size, data_ref);
        if (err < 0)
            return err;

        if (next_marker == -1)
            break;
        marker = next_marker;
        start  = next_start;
    }

    return 0;
}

static int cbs_jpeg_read_unit(CodedBitstreamContext *ctx,
                              CodedBitstreamUnit *unit)
{
    GetBitContext gbc;
    int err;

    err = init_get_bits(&gbc, unit->data, 8 * unit->data_size);
    if (err < 0)
        return err;

    if (unit->type >= JPEG_MARKER_SOF0 &&
        unit->type <= JPEG_MARKER_SOF3) {
        err = ff_cbs_alloc_unit_content(unit,
                                        sizeof(JPEGRawFrameHeader),
                                        NULL);
        if (err < 0)
            return err;

        err = cbs_jpeg_read_frame_header(ctx, &gbc, unit->content);
        if (err < 0)
            return err;

    } else if (unit->type >= JPEG_MARKER_APPN &&
               unit->type <= JPEG_MARKER_APPN + 15) {
        err = ff_cbs_alloc_unit_content(unit,
                                        sizeof(JPEGRawApplicationData),
                                        &cbs_jpeg_free_application_data);
        if (err < 0)
            return err;

        err = cbs_jpeg_read_application_data(ctx, &gbc, unit->content);
        if (err < 0)
            return err;

    } else if (unit->type == JPEG_MARKER_SOS) {
        JPEGRawScan *scan;
        int pos;

        err = ff_cbs_alloc_unit_content(unit,
                                        sizeof(JPEGRawScan),
                                        &cbs_jpeg_free_scan);
        if (err < 0)
            return err;
        scan = unit->content;

        err = cbs_jpeg_read_scan_header(ctx, &gbc, &scan->header);
        if (err < 0)
            return err;

        pos = get_bits_count(&gbc);
        av_assert0(pos % 8 == 0);
        if (pos > 0) {
            scan->data_size = unit->data_size - pos / 8;
            scan->data_ref  = av_buffer_ref(unit->data_ref);
            if (!scan->data_ref)
                return AVERROR(ENOMEM);
            scan->data = unit->data + pos / 8;
        }

    } else {
        switch (unit->type) {
#define SEGMENT(marker, type, func, free) \
        case JPEG_MARKER_ ## marker: \
            { \
                err = ff_cbs_alloc_unit_content(unit, \
                                                sizeof(type), free); \
                if (err < 0) \
                    return err; \
                err = cbs_jpeg_read_ ## func(ctx, &gbc, unit->content); \
                if (err < 0) \
                    return err; \
            } \
            break
            SEGMENT(DQT, JPEGRawQuantisationTableSpecification, dqt, NULL);
            SEGMENT(DHT, JPEGRawHuffmanTableSpecification,      dht, NULL);
            SEGMENT(COM, JPEGRawComment,  comment, &cbs_jpeg_free_comment);
#undef SEGMENT
        default:
            return AVERROR(ENOSYS);
        }
    }

    return 0;
}

static int cbs_jpeg_write_scan(CodedBitstreamContext *ctx,
                               CodedBitstreamUnit *unit,
                               PutBitContext *pbc)
{
    JPEGRawScan *scan = unit->content;
    int err;

    err = cbs_jpeg_write_scan_header(ctx, pbc, &scan->header);
    if (err < 0)
        return err;

    if (scan->data) {
        if (scan->data_size * 8 > put_bits_left(pbc))
            return AVERROR(ENOSPC);

        av_assert0(put_bits_count(pbc) % 8 == 0);

        flush_put_bits(pbc);

        memcpy(put_bits_ptr(pbc), scan->data, scan->data_size);
        skip_put_bytes(pbc, scan->data_size);
    }

    return 0;
}

static int cbs_jpeg_write_segment(CodedBitstreamContext *ctx,
                                  CodedBitstreamUnit *unit,
                                  PutBitContext *pbc)
{
    int err;

    if (unit->type >= JPEG_MARKER_SOF0 &&
        unit->type <= JPEG_MARKER_SOF3) {
        err = cbs_jpeg_write_frame_header(ctx, pbc, unit->content);
    } else if (unit->type >= JPEG_MARKER_APPN &&
               unit->type <= JPEG_MARKER_APPN + 15) {
        err = cbs_jpeg_write_application_data(ctx, pbc, unit->content);
    } else {
        switch (unit->type) {
#define SEGMENT(marker, func) \
            case JPEG_MARKER_ ## marker: \
                err = cbs_jpeg_write_ ## func(ctx, pbc, unit->content); \
                break;
            SEGMENT(DQT, dqt);
            SEGMENT(DHT, dht);
            SEGMENT(COM, comment);
        default:
            return AVERROR_PATCHWELCOME;
        }
    }

    return err;
}

static int cbs_jpeg_write_unit(CodedBitstreamContext *ctx,
                               CodedBitstreamUnit *unit,
                               PutBitContext *pbc)
{
    if (unit->type == JPEG_MARKER_SOS)
        return cbs_jpeg_write_scan   (ctx, unit, pbc);
    else
        return cbs_jpeg_write_segment(ctx, unit, pbc);
}

static int cbs_jpeg_assemble_fragment(CodedBitstreamContext *ctx,
                                       CodedBitstreamFragment *frag)
{
    const CodedBitstreamUnit *unit;
    uint8_t *data;
    size_t size, dp, sp;
    int i;

    size = 4; // SOI + EOI.
    for (i = 0; i < frag->nb_units; i++) {
        unit = &frag->units[i];
        size += 2 + unit->data_size;
        if (unit->type == JPEG_MARKER_SOS) {
            for (sp = 0; sp < unit->data_size; sp++) {
                if (unit->data[sp] == 0xff)
                    ++size;
            }
        }
    }

    frag->data_ref = av_buffer_alloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
    if (!frag->data_ref)
        return AVERROR(ENOMEM);
    data = frag->data_ref->data;

    dp = 0;

    data[dp++] = 0xff;
    data[dp++] = JPEG_MARKER_SOI;

    for (i = 0; i < frag->nb_units; i++) {
        unit = &frag->units[i];

        data[dp++] = 0xff;
        data[dp++] = unit->type;

        if (unit->type != JPEG_MARKER_SOS) {
            memcpy(data + dp, unit->data, unit->data_size);
            dp += unit->data_size;
        } else {
            sp = AV_RB16(unit->data);
            av_assert0(sp <= unit->data_size);
            memcpy(data + dp, unit->data, sp);
            dp += sp;

            for (; sp < unit->data_size; sp++) {
                if (unit->data[sp] == 0xff) {
                    data[dp++] = 0xff;
                    data[dp++] = 0x00;
                } else {
                    data[dp++] = unit->data[sp];
                }
            }
        }
    }

    data[dp++] = 0xff;
    data[dp++] = JPEG_MARKER_EOI;

    av_assert0(dp == size);

    memset(data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
    frag->data      = data;
    frag->data_size = size;

    return 0;
}

const CodedBitstreamType ff_cbs_type_jpeg = {
    .codec_id          = AV_CODEC_ID_MJPEG,

    .split_fragment    = &cbs_jpeg_split_fragment,
    .read_unit         = &cbs_jpeg_read_unit,
    .write_unit        = &cbs_jpeg_write_unit,
    .assemble_fragment = &cbs_jpeg_assemble_fragment,
};
