/*
 * 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 "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;

/**
 * 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 *last, void *cur, int last2, int w,
                                  int stride, int comp, int bits)
{
    int x = 0;
    int Ra, Rb, Rc, Rd;
    int D0, D1, D2;

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

        /* compute gradients */
        Ra = x ? R(cur, x - stride) : R(last, x);
        Rb = R(last, x);
        Rc = x ? R(last, x - stride) : last2;
        Rd = (x >= w - stride) ? R(last, x) : R(last, 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(cur, x) - RUNval) <= state->near)) {
                run++;
                W(cur, x, Ra);
                x += stride;
            }
            ls_encode_run(state, pb, run, comp, x < w);
            if (x >= w)
                return;
            Rb     = R(last, x);
            RItype = FFABS(Ra - Rb) <= state->near;
            pred   = RItype ? Ra : Rb;
            err    = R(cur, 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);
                W(cur, 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(cur, x);
            } else {
                sign = 0;
                pred = av_clip(pred + state->C[context], 0, state->maxval);
                err  = R(cur, 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);
                W(cur, x, Ra);
            }

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

static void ls_store_lse(JLSState *state, PutBitContext *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(pb, LSE);
    put_bits(pb, 16, 13);
    put_bits(pb, 8, 1);
    put_bits(pb, 16, state->maxval);
    put_bits(pb, 16, state->T1);
    put_bits(pb, 16, state->T2);
    put_bits(pb, 16, state->T3);
    put_bits(pb, 16, 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;
    PutBitContext pb, pb2;
    GetBitContext gb;
    uint8_t *buf2 = NULL;
    uint8_t *zero = NULL;
    uint8_t *cur  = NULL;
    uint8_t *last = NULL;
    JLSState *state = NULL;
    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;

    buf2 = av_malloc(pkt->size);
    if (!buf2)
        goto memfail;

    init_put_bits(&pb, pkt->data, pkt->size);
    init_put_bits(&pb2, buf2, pkt->size);

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

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

    state = av_mallocz(sizeof(JLSState));
    if (!state)
        goto memfail;

    /* 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);

    zero = last = av_mallocz(FFABS(p->linesize[0]));
    if (!zero)
        goto memfail;

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

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

        for (i = 0; i < avctx->height; i++) {
            ls_encode_line(state, &pb2, last, cur, t, avctx->width, 1, 0, 16);
            t    = *((uint16_t *)last);
            last = cur;
            cur += 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++) {
                ls_encode_line(state, &pb2, last + j, cur + j, Rc[j],
                               width, 3, j, 8);
                Rc[j] = last[j];
            }
            last = cur;
            cur += 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--) {
                ls_encode_line(state, &pb2, last + j, cur + j, Rc[j],
                               width, 3, j, 8);
                Rc[j] = last[j];
            }
            last = cur;
            cur += p->linesize[0];
        }
    }

    av_freep(&zero);
    av_freep(&state);

    /* 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, buf2, size);
    size -= 7;
    while (get_bits_count(&gb) < size) {
        int v;
        v = get_bits(&gb, 8);
        put_bits(&pb, 8, v);
        if (v == 0xFF) {
            v = get_bits(&gb, 7);
            put_bits(&pb, 8, v);
        }
    }
    avpriv_align_put_bits(&pb);
    av_freep(&buf2);

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

    emms_c();

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

memfail:
    av_packet_unref(pkt);
    av_freep(&buf2);
    av_freep(&state);
    av_freep(&zero);
    return AVERROR(ENOMEM);
}

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 | AV_CODEC_CAP_INTRA_ONLY,
    .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,
};
