/*
 * JPEG-LS encoder
 * Copyright (c) 2003 Michael Niedermayer
 * Copyright (c) 2006 Konstantin Shishkov
 *
 * 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
 * JPEG-LS encoder.
 */

#include "avcodec.h"
#include "bytestream.h"
#include "get_bits.h"
#include "put_bits.h"
#include "golomb.h"
#include "internal.h"
#include "mathops.h"
#include "mjpeg.h"
#include "mjpegenc.h"
#include "jpegls.h"

typedef struct JPEGLSContext {
    AVClass *class;

    int pred;
} JPEGLSContext;

static inline void put_marker_byteu(PutByteContext *pb, enum JpegMarker code)
{
    bytestream2_put_byteu(pb, 0xff);
    bytestream2_put_byteu(pb, code);
}

static inline void put_marker_byte(PutByteContext *pb, enum JpegMarker code)
{
    bytestream2_put_byte(pb, 0xff);
    bytestream2_put_byte(pb, code);
}

/**
 * Encode error from regular symbol
 */
static inline void ls_encode_regular(JLSState *state, PutBitContext *pb, int Q,
                                     int err)
{
    int k;
    int val;
    int map;

    for (k = 0; (state->N[Q] << k) < state->A[Q]; k++)
        ;

    map = !state->near && !k && (2 * state->B[Q] <= -state->N[Q]);

    if (err < 0)
        err += state->range;
    if (err >= (state->range + 1 >> 1)) {
        err -= state->range;
        val  = 2 * FFABS(err) - 1 - map;
    } else
        val = 2 * err + map;

    set_ur_golomb_jpegls(pb, val, k, state->limit, state->qbpp);

    ff_jpegls_update_state_regular(state, Q, err);
}

/**
 * Encode error from run termination
 */
static inline void ls_encode_runterm(JLSState *state, PutBitContext *pb,
                                     int RItype, int err, int limit_add)
{
    int k;
    int val, map;
    int Q = 365 + RItype;
    int temp;

    temp = state->A[Q];
    if (RItype)
        temp += state->N[Q] >> 1;
    for (k = 0; (state->N[Q] << k) < temp; k++)
        ;
    map = 0;
    if (!k && err && (2 * state->B[Q] < state->N[Q]))
        map = 1;

    if (err < 0)
        val = -(2 * err) - 1 - RItype + map;
    else
        val = 2 * err - RItype - map;
    set_ur_golomb_jpegls(pb, val, k, state->limit - limit_add - 1, state->qbpp);

    if (err < 0)
        state->B[Q]++;
    state->A[Q] += (val + 1 - RItype) >> 1;

    ff_jpegls_downscale_state(state, Q);
}

/**
 * Encode run value as specified by JPEG-LS standard
 */
static inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run,
                                 int comp, int trail)
{
    while (run >= (1 << ff_log2_run[state->run_index[comp]])) {
        put_bits(pb, 1, 1);
        run -= 1 << ff_log2_run[state->run_index[comp]];
        if (state->run_index[comp] < 31)
            state->run_index[comp]++;
    }
    /* if hit EOL, encode another full run, else encode aborted run */
    if (!trail && run) {
        put_bits(pb, 1, 1);
    } else if (trail) {
        put_bits(pb, 1, 0);
        if (ff_log2_run[state->run_index[comp]])
            put_bits(pb, ff_log2_run[state->run_index[comp]], run);
    }
}

/**
 * Encode one line of image
 */
static inline void ls_encode_line(JLSState *state, PutBitContext *pb,
                                  void *tmp, const void *in, int last2, int w,
                                  int stride, int comp, int bits)
{
    int x = 0;
    int Ra = R(tmp, 0), Rb, Rc = last2, Rd;
    int D0, D1, D2;

    while (x < w) {
        int err, pred, sign;

        /* compute gradients */
        Rb = R(tmp, x);
        Rd = (x >= w - stride) ? R(tmp, x) : R(tmp, x + stride);
        D0 = Rd - Rb;
        D1 = Rb - Rc;
        D2 = Rc - Ra;

        /* run mode */
        if ((FFABS(D0) <= state->near) &&
            (FFABS(D1) <= state->near) &&
            (FFABS(D2) <= state->near)) {
            int RUNval, RItype, run;

            run    = 0;
            RUNval = Ra;
            while (x < w && (FFABS(R(in, x) - RUNval) <= state->near)) {
                run++;
                W(tmp, x, Ra);
                x += stride;
            }
            ls_encode_run(state, pb, run, comp, x < w);
            if (x >= w)
                return;
            Rb     = R(tmp, x);
            RItype = FFABS(Ra - Rb) <= state->near;
            pred   = RItype ? Ra : Rb;
            err    = R(in, x) - pred;

            if (!RItype && Ra > Rb)
                err = -err;

            if (state->near) {
                if (err > 0)
                    err =  (state->near + err) / state->twonear;
                else
                    err = -(state->near - err) / state->twonear;

                if (RItype || (Rb >= Ra))
                    Ra = av_clip(pred + err * state->twonear, 0, state->maxval);
                else
                    Ra = av_clip(pred - err * state->twonear, 0, state->maxval);
            } else
                Ra = R(in, x);
            W(tmp, x, Ra);

            if (err < 0)
                err += state->range;
            if (err >= state->range + 1 >> 1)
                err -= state->range;

            ls_encode_runterm(state, pb, RItype, err,
                              ff_log2_run[state->run_index[comp]]);

            if (state->run_index[comp] > 0)
                state->run_index[comp]--;
        } else { /* regular mode */
            int context;

            context = ff_jpegls_quantize(state, D0) * 81 +
                      ff_jpegls_quantize(state, D1) *  9 +
                      ff_jpegls_quantize(state, D2);
            pred    = mid_pred(Ra, Ra + Rb - Rc, Rb);

            if (context < 0) {
                context = -context;
                sign    = 1;
                pred    = av_clip(pred - state->C[context], 0, state->maxval);
                err     = pred - R(in, x);
            } else {
                sign = 0;
                pred = av_clip(pred + state->C[context], 0, state->maxval);
                err  = R(in, x) - pred;
            }

            if (state->near) {
                if (err > 0)
                    err =  (state->near + err) / state->twonear;
                else
                    err = -(state->near - err) / state->twonear;
                if (!sign)
                    Ra = av_clip(pred + err * state->twonear, 0, state->maxval);
                else
                    Ra = av_clip(pred - err * state->twonear, 0, state->maxval);
            } else
                Ra = R(in, x);
            W(tmp, x, Ra);

            ls_encode_regular(state, pb, context, err);
        }
        Rc = Rb;
        x += stride;
    }
}

static void ls_store_lse(JLSState *state, PutByteContext *pb)
{
    /* Test if we have default params and don't need to store LSE */
    JLSState state2 = { 0 };
    state2.bpp  = state->bpp;
    state2.near = state->near;
    ff_jpegls_reset_coding_parameters(&state2, 1);
    if (state->T1 == state2.T1 &&
        state->T2 == state2.T2 &&
        state->T3 == state2.T3 &&
        state->reset == state2.reset)
        return;
    /* store LSE type 1 */
    put_marker_byteu(pb, LSE);
    bytestream2_put_be16u(pb, 13);
    bytestream2_put_byteu(pb, 1);
    bytestream2_put_be16u(pb, state->maxval);
    bytestream2_put_be16u(pb, state->T1);
    bytestream2_put_be16u(pb, state->T2);
    bytestream2_put_be16u(pb, state->T3);
    bytestream2_put_be16u(pb, state->reset);
}

static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt,
                             const AVFrame *pict, int *got_packet)
{
    JPEGLSContext *ctx = avctx->priv_data;
    const AVFrame *const p = pict;
    PutByteContext pb;
    PutBitContext pb2;
    GetBitContext gb;
    const uint8_t *in;
    uint8_t *last = NULL;
    JLSState state = { 0 };
    int i, size, ret;
    int comps;

#if FF_API_PRIVATE_OPT
FF_DISABLE_DEPRECATION_WARNINGS
    if (avctx->prediction_method)
        ctx->pred = avctx->prediction_method;
FF_ENABLE_DEPRECATION_WARNINGS
#endif

    if (avctx->pix_fmt == AV_PIX_FMT_GRAY8 ||
        avctx->pix_fmt == AV_PIX_FMT_GRAY16)
        comps = 1;
    else
        comps = 3;

    if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width  *avctx->height * comps * 4 +
                                AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
        return ret;

    last = av_malloc((unsigned)pkt->size + FFABS(p->linesize[0]));
    if (!last)
        return AVERROR(ENOMEM);
    memset(last, 0, FFABS(p->linesize[0]));

    bytestream2_init_writer(&pb, pkt->data, pkt->size);
    init_put_bits(&pb2, last + FFABS(p->linesize[0]), pkt->size);

    /* write our own JPEG header, can't use mjpeg_picture_header */
    put_marker_byteu(&pb, SOI);
    put_marker_byteu(&pb, SOF48);
    bytestream2_put_be16u(&pb, 8 + comps * 3); // header size depends on components
    bytestream2_put_byteu(&pb, (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8);  // bpp
    bytestream2_put_be16u(&pb, avctx->height);
    bytestream2_put_be16u(&pb, avctx->width);
    bytestream2_put_byteu(&pb, comps);          // components
    for (i = 1; i <= comps; i++) {
        bytestream2_put_byteu(&pb, i);     // component ID
        bytestream2_put_byteu(&pb, 0x11);  // subsampling: none
        bytestream2_put_byteu(&pb, 0);     // Tiq, used by JPEG-LS ext
    }

    put_marker_byteu(&pb, SOS);
    bytestream2_put_be16u(&pb, 6 + comps * 2);
    bytestream2_put_byteu(&pb, comps);
    for (i = 1; i <= comps; i++) {
        bytestream2_put_byteu(&pb, i);   // component ID
        bytestream2_put_byteu(&pb, 0);   // mapping index: none
    }
    bytestream2_put_byteu(&pb, ctx->pred);
    bytestream2_put_byteu(&pb, (comps > 1) ? 1 : 0);  // interleaving: 0 - plane, 1 - line
    bytestream2_put_byteu(&pb, 0);  // point transform: none

    /* initialize JPEG-LS state from JPEG parameters */
    state.near = ctx->pred;
    state.bpp  = (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8;
    ff_jpegls_reset_coding_parameters(&state, 0);
    ff_jpegls_init_state(&state);

    ls_store_lse(&state, &pb);

    in = p->data[0];
    if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
        int t = 0;

        for (i = 0; i < avctx->height; i++) {
            int last0 = last[0];
            ls_encode_line(&state, &pb2, last, in, t, avctx->width, 1, 0, 8);
            t   = last0;
            in += p->linesize[0];
        }
    } else if (avctx->pix_fmt == AV_PIX_FMT_GRAY16) {
        int t = 0;

        for (i = 0; i < avctx->height; i++) {
            int last0 = *((uint16_t *)last);
            ls_encode_line(&state, &pb2, last, in, t, avctx->width, 1, 0, 16);
            t   = last0;
            in += p->linesize[0];
        }
    } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) {
        int j, width;
        int Rc[3] = { 0, 0, 0 };

        width = avctx->width * 3;
        for (i = 0; i < avctx->height; i++) {
            for (j = 0; j < 3; j++) {
                int last0 = last[j];
                ls_encode_line(&state, &pb2, last + j, in + j, Rc[j],
                               width, 3, j, 8);
                Rc[j] = last0;
            }
            in += p->linesize[0];
        }
    } else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
        int j, width;
        int Rc[3] = { 0, 0, 0 };

        width = avctx->width * 3;
        for (i = 0; i < avctx->height; i++) {
            for (j = 2; j >= 0; j--) {
                int last0 = last[j];
                ls_encode_line(&state, &pb2, last + j, in + j, Rc[j],
                               width, 3, j, 8);
                Rc[j] = last0;
            }
            in += p->linesize[0];
        }
    }

    /* the specification says that after doing 0xff escaping unused bits in
     * the last byte must be set to 0, so just append 7 "optional" zero bits
     * to avoid special-casing. */
    put_bits(&pb2, 7, 0);
    size = put_bits_count(&pb2);
    flush_put_bits(&pb2);
    /* do escape coding */
    init_get_bits(&gb, pb2.buf, size);
    size -= 7;
    while (get_bits_count(&gb) < size) {
        int v;
        v = get_bits(&gb, 8);
        bytestream2_put_byte(&pb, v);
        if (v == 0xFF) {
            v = get_bits(&gb, 7);
            bytestream2_put_byte(&pb, v);
        }
    }
    av_freep(&last);

    /* End of image */
    put_marker_byte(&pb, EOI);

    emms_c();

    pkt->size   = bytestream2_tell_p(&pb);
    pkt->flags |= AV_PKT_FLAG_KEY;
    *got_packet = 1;
    return 0;
}

static av_cold int encode_init_ls(AVCodecContext *ctx)
{
#if FF_API_CODED_FRAME
FF_DISABLE_DEPRECATION_WARNINGS
    ctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
    ctx->coded_frame->key_frame = 1;
FF_ENABLE_DEPRECATION_WARNINGS
#endif

    if (ctx->pix_fmt != AV_PIX_FMT_GRAY8  &&
        ctx->pix_fmt != AV_PIX_FMT_GRAY16 &&
        ctx->pix_fmt != AV_PIX_FMT_RGB24  &&
        ctx->pix_fmt != AV_PIX_FMT_BGR24) {
        av_log(ctx, AV_LOG_ERROR,
               "Only grayscale and RGB24/BGR24 images are supported\n");
        return -1;
    }
    return 0;
}

#define OFFSET(x) offsetof(JPEGLSContext, x)
#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
{ "pred", "Prediction method", OFFSET(pred), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, VE, "pred" },
    { "left",   NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "pred" },
    { "plane",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "pred" },
    { "median", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "pred" },

    { NULL},
};

static const AVClass jpegls_class = {
    .class_name = "jpegls",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};

AVCodec ff_jpegls_encoder = {
    .name           = "jpegls",
    .long_name      = NULL_IF_CONFIG_SMALL("JPEG-LS"),
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = AV_CODEC_ID_JPEGLS,
    .priv_data_size = sizeof(JPEGLSContext),
    .priv_class     = &jpegls_class,
    .init           = encode_init_ls,
    .capabilities   = AV_CODEC_CAP_FRAME_THREADS,
    .encode2        = encode_picture_ls,
    .pix_fmts       = (const enum AVPixelFormat[]) {
        AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB24,
        AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16,
        AV_PIX_FMT_NONE
    },
    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
                      FF_CODEC_CAP_INIT_CLEANUP,
};
