1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * JPEG-LS encoder
3cabdff1aSopenharmony_ci * Copyright (c) 2003 Michael Niedermayer
4cabdff1aSopenharmony_ci * Copyright (c) 2006 Konstantin Shishkov
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * This file is part of FFmpeg.
7cabdff1aSopenharmony_ci *
8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
12cabdff1aSopenharmony_ci *
13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16cabdff1aSopenharmony_ci * Lesser General Public License for more details.
17cabdff1aSopenharmony_ci *
18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21cabdff1aSopenharmony_ci */
22cabdff1aSopenharmony_ci
23cabdff1aSopenharmony_ci/**
24cabdff1aSopenharmony_ci * @file
25cabdff1aSopenharmony_ci * JPEG-LS encoder.
26cabdff1aSopenharmony_ci */
27cabdff1aSopenharmony_ci
28cabdff1aSopenharmony_ci#define UNCHECKED_BITSTREAM_READER 1
29cabdff1aSopenharmony_ci#include "libavutil/opt.h"
30cabdff1aSopenharmony_ci#include "avcodec.h"
31cabdff1aSopenharmony_ci#include "bytestream.h"
32cabdff1aSopenharmony_ci#include "codec_internal.h"
33cabdff1aSopenharmony_ci#include "encode.h"
34cabdff1aSopenharmony_ci#include "get_bits.h"
35cabdff1aSopenharmony_ci#include "put_bits.h"
36cabdff1aSopenharmony_ci#include "put_golomb.h"
37cabdff1aSopenharmony_ci#include "mathops.h"
38cabdff1aSopenharmony_ci#include "mjpeg.h"
39cabdff1aSopenharmony_ci#include "jpegls.h"
40cabdff1aSopenharmony_ci
41cabdff1aSopenharmony_citypedef struct JPEGLSContext {
42cabdff1aSopenharmony_ci    AVClass *class;
43cabdff1aSopenharmony_ci
44cabdff1aSopenharmony_ci    int pred;
45cabdff1aSopenharmony_ci    int comps;
46cabdff1aSopenharmony_ci
47cabdff1aSopenharmony_ci    size_t size;
48cabdff1aSopenharmony_ci    uint8_t *buf;
49cabdff1aSopenharmony_ci} JPEGLSContext;
50cabdff1aSopenharmony_ci
51cabdff1aSopenharmony_cistatic inline void put_marker_byteu(PutByteContext *pb, enum JpegMarker code)
52cabdff1aSopenharmony_ci{
53cabdff1aSopenharmony_ci    bytestream2_put_byteu(pb, 0xff);
54cabdff1aSopenharmony_ci    bytestream2_put_byteu(pb, code);
55cabdff1aSopenharmony_ci}
56cabdff1aSopenharmony_ci
57cabdff1aSopenharmony_ci/**
58cabdff1aSopenharmony_ci * Encode error from regular symbol
59cabdff1aSopenharmony_ci */
60cabdff1aSopenharmony_cistatic inline void ls_encode_regular(JLSState *state, PutBitContext *pb, int Q,
61cabdff1aSopenharmony_ci                                     int err)
62cabdff1aSopenharmony_ci{
63cabdff1aSopenharmony_ci    int k;
64cabdff1aSopenharmony_ci    int val;
65cabdff1aSopenharmony_ci    int map;
66cabdff1aSopenharmony_ci
67cabdff1aSopenharmony_ci    for (k = 0; (state->N[Q] << k) < state->A[Q]; k++)
68cabdff1aSopenharmony_ci        ;
69cabdff1aSopenharmony_ci
70cabdff1aSopenharmony_ci    map = !state->near && !k && (2 * state->B[Q] <= -state->N[Q]);
71cabdff1aSopenharmony_ci
72cabdff1aSopenharmony_ci    if (err < 0)
73cabdff1aSopenharmony_ci        err += state->range;
74cabdff1aSopenharmony_ci    if (err >= (state->range + 1 >> 1)) {
75cabdff1aSopenharmony_ci        err -= state->range;
76cabdff1aSopenharmony_ci        val  = 2 * FFABS(err) - 1 - map;
77cabdff1aSopenharmony_ci    } else
78cabdff1aSopenharmony_ci        val = 2 * err + map;
79cabdff1aSopenharmony_ci
80cabdff1aSopenharmony_ci    set_ur_golomb_jpegls(pb, val, k, state->limit, state->qbpp);
81cabdff1aSopenharmony_ci
82cabdff1aSopenharmony_ci    ff_jpegls_update_state_regular(state, Q, err);
83cabdff1aSopenharmony_ci}
84cabdff1aSopenharmony_ci
85cabdff1aSopenharmony_ci/**
86cabdff1aSopenharmony_ci * Encode error from run termination
87cabdff1aSopenharmony_ci */
88cabdff1aSopenharmony_cistatic inline void ls_encode_runterm(JLSState *state, PutBitContext *pb,
89cabdff1aSopenharmony_ci                                     int RItype, int err, int limit_add)
90cabdff1aSopenharmony_ci{
91cabdff1aSopenharmony_ci    int k;
92cabdff1aSopenharmony_ci    int val, map;
93cabdff1aSopenharmony_ci    int Q = 365 + RItype;
94cabdff1aSopenharmony_ci    int temp;
95cabdff1aSopenharmony_ci
96cabdff1aSopenharmony_ci    temp = state->A[Q];
97cabdff1aSopenharmony_ci    if (RItype)
98cabdff1aSopenharmony_ci        temp += state->N[Q] >> 1;
99cabdff1aSopenharmony_ci    for (k = 0; (state->N[Q] << k) < temp; k++)
100cabdff1aSopenharmony_ci        ;
101cabdff1aSopenharmony_ci    map = 0;
102cabdff1aSopenharmony_ci    if (!k && err && (2 * state->B[Q] < state->N[Q]))
103cabdff1aSopenharmony_ci        map = 1;
104cabdff1aSopenharmony_ci
105cabdff1aSopenharmony_ci    if (err < 0)
106cabdff1aSopenharmony_ci        val = -(2 * err) - 1 - RItype + map;
107cabdff1aSopenharmony_ci    else
108cabdff1aSopenharmony_ci        val = 2 * err - RItype - map;
109cabdff1aSopenharmony_ci    set_ur_golomb_jpegls(pb, val, k, state->limit - limit_add - 1, state->qbpp);
110cabdff1aSopenharmony_ci
111cabdff1aSopenharmony_ci    if (err < 0)
112cabdff1aSopenharmony_ci        state->B[Q]++;
113cabdff1aSopenharmony_ci    state->A[Q] += (val + 1 - RItype) >> 1;
114cabdff1aSopenharmony_ci
115cabdff1aSopenharmony_ci    ff_jpegls_downscale_state(state, Q);
116cabdff1aSopenharmony_ci}
117cabdff1aSopenharmony_ci
118cabdff1aSopenharmony_ci/**
119cabdff1aSopenharmony_ci * Encode run value as specified by JPEG-LS standard
120cabdff1aSopenharmony_ci */
121cabdff1aSopenharmony_cistatic inline void ls_encode_run(JLSState *state, PutBitContext *pb, int run,
122cabdff1aSopenharmony_ci                                 int comp, int trail)
123cabdff1aSopenharmony_ci{
124cabdff1aSopenharmony_ci    while (run >= (1 << ff_log2_run[state->run_index[comp]])) {
125cabdff1aSopenharmony_ci        put_bits(pb, 1, 1);
126cabdff1aSopenharmony_ci        run -= 1 << ff_log2_run[state->run_index[comp]];
127cabdff1aSopenharmony_ci        if (state->run_index[comp] < 31)
128cabdff1aSopenharmony_ci            state->run_index[comp]++;
129cabdff1aSopenharmony_ci    }
130cabdff1aSopenharmony_ci    /* if hit EOL, encode another full run, else encode aborted run */
131cabdff1aSopenharmony_ci    if (!trail && run) {
132cabdff1aSopenharmony_ci        put_bits(pb, 1, 1);
133cabdff1aSopenharmony_ci    } else if (trail) {
134cabdff1aSopenharmony_ci        put_bits(pb, 1, 0);
135cabdff1aSopenharmony_ci        if (ff_log2_run[state->run_index[comp]])
136cabdff1aSopenharmony_ci            put_bits(pb, ff_log2_run[state->run_index[comp]], run);
137cabdff1aSopenharmony_ci    }
138cabdff1aSopenharmony_ci}
139cabdff1aSopenharmony_ci
140cabdff1aSopenharmony_ci/**
141cabdff1aSopenharmony_ci * Encode one line of image
142cabdff1aSopenharmony_ci */
143cabdff1aSopenharmony_cistatic inline void ls_encode_line(JLSState *state, PutBitContext *pb,
144cabdff1aSopenharmony_ci                                  void *tmp, const void *in, int last2, int w,
145cabdff1aSopenharmony_ci                                  int stride, int comp, int bits)
146cabdff1aSopenharmony_ci{
147cabdff1aSopenharmony_ci    int x = 0;
148cabdff1aSopenharmony_ci    int Ra = R(tmp, 0), Rb, Rc = last2, Rd;
149cabdff1aSopenharmony_ci    int D0, D1, D2;
150cabdff1aSopenharmony_ci
151cabdff1aSopenharmony_ci    while (x < w) {
152cabdff1aSopenharmony_ci        int err, pred, sign;
153cabdff1aSopenharmony_ci
154cabdff1aSopenharmony_ci        /* compute gradients */
155cabdff1aSopenharmony_ci        Rb = R(tmp, x);
156cabdff1aSopenharmony_ci        Rd = (x >= w - stride) ? R(tmp, x) : R(tmp, x + stride);
157cabdff1aSopenharmony_ci        D0 = Rd - Rb;
158cabdff1aSopenharmony_ci        D1 = Rb - Rc;
159cabdff1aSopenharmony_ci        D2 = Rc - Ra;
160cabdff1aSopenharmony_ci
161cabdff1aSopenharmony_ci        /* run mode */
162cabdff1aSopenharmony_ci        if ((FFABS(D0) <= state->near) &&
163cabdff1aSopenharmony_ci            (FFABS(D1) <= state->near) &&
164cabdff1aSopenharmony_ci            (FFABS(D2) <= state->near)) {
165cabdff1aSopenharmony_ci            int RUNval, RItype, run;
166cabdff1aSopenharmony_ci
167cabdff1aSopenharmony_ci            run    = 0;
168cabdff1aSopenharmony_ci            RUNval = Ra;
169cabdff1aSopenharmony_ci            while (x < w && (FFABS(R(in, x) - RUNval) <= state->near)) {
170cabdff1aSopenharmony_ci                run++;
171cabdff1aSopenharmony_ci                W(tmp, x, Ra);
172cabdff1aSopenharmony_ci                x += stride;
173cabdff1aSopenharmony_ci            }
174cabdff1aSopenharmony_ci            ls_encode_run(state, pb, run, comp, x < w);
175cabdff1aSopenharmony_ci            if (x >= w)
176cabdff1aSopenharmony_ci                return;
177cabdff1aSopenharmony_ci            Rb     = R(tmp, x);
178cabdff1aSopenharmony_ci            RItype = FFABS(Ra - Rb) <= state->near;
179cabdff1aSopenharmony_ci            pred   = RItype ? Ra : Rb;
180cabdff1aSopenharmony_ci            err    = R(in, x) - pred;
181cabdff1aSopenharmony_ci
182cabdff1aSopenharmony_ci            if (!RItype && Ra > Rb)
183cabdff1aSopenharmony_ci                err = -err;
184cabdff1aSopenharmony_ci
185cabdff1aSopenharmony_ci            if (state->near) {
186cabdff1aSopenharmony_ci                if (err > 0)
187cabdff1aSopenharmony_ci                    err =  (state->near + err) / state->twonear;
188cabdff1aSopenharmony_ci                else
189cabdff1aSopenharmony_ci                    err = -(state->near - err) / state->twonear;
190cabdff1aSopenharmony_ci
191cabdff1aSopenharmony_ci                if (RItype || (Rb >= Ra))
192cabdff1aSopenharmony_ci                    Ra = av_clip(pred + err * state->twonear, 0, state->maxval);
193cabdff1aSopenharmony_ci                else
194cabdff1aSopenharmony_ci                    Ra = av_clip(pred - err * state->twonear, 0, state->maxval);
195cabdff1aSopenharmony_ci            } else
196cabdff1aSopenharmony_ci                Ra = R(in, x);
197cabdff1aSopenharmony_ci            W(tmp, x, Ra);
198cabdff1aSopenharmony_ci
199cabdff1aSopenharmony_ci            if (err < 0)
200cabdff1aSopenharmony_ci                err += state->range;
201cabdff1aSopenharmony_ci            if (err >= state->range + 1 >> 1)
202cabdff1aSopenharmony_ci                err -= state->range;
203cabdff1aSopenharmony_ci
204cabdff1aSopenharmony_ci            ls_encode_runterm(state, pb, RItype, err,
205cabdff1aSopenharmony_ci                              ff_log2_run[state->run_index[comp]]);
206cabdff1aSopenharmony_ci
207cabdff1aSopenharmony_ci            if (state->run_index[comp] > 0)
208cabdff1aSopenharmony_ci                state->run_index[comp]--;
209cabdff1aSopenharmony_ci        } else { /* regular mode */
210cabdff1aSopenharmony_ci            int context;
211cabdff1aSopenharmony_ci
212cabdff1aSopenharmony_ci            context = ff_jpegls_quantize(state, D0) * 81 +
213cabdff1aSopenharmony_ci                      ff_jpegls_quantize(state, D1) *  9 +
214cabdff1aSopenharmony_ci                      ff_jpegls_quantize(state, D2);
215cabdff1aSopenharmony_ci            pred    = mid_pred(Ra, Ra + Rb - Rc, Rb);
216cabdff1aSopenharmony_ci
217cabdff1aSopenharmony_ci            if (context < 0) {
218cabdff1aSopenharmony_ci                context = -context;
219cabdff1aSopenharmony_ci                sign    = 1;
220cabdff1aSopenharmony_ci                pred    = av_clip(pred - state->C[context], 0, state->maxval);
221cabdff1aSopenharmony_ci                err     = pred - R(in, x);
222cabdff1aSopenharmony_ci            } else {
223cabdff1aSopenharmony_ci                sign = 0;
224cabdff1aSopenharmony_ci                pred = av_clip(pred + state->C[context], 0, state->maxval);
225cabdff1aSopenharmony_ci                err  = R(in, x) - pred;
226cabdff1aSopenharmony_ci            }
227cabdff1aSopenharmony_ci
228cabdff1aSopenharmony_ci            if (state->near) {
229cabdff1aSopenharmony_ci                if (err > 0)
230cabdff1aSopenharmony_ci                    err =  (state->near + err) / state->twonear;
231cabdff1aSopenharmony_ci                else
232cabdff1aSopenharmony_ci                    err = -(state->near - err) / state->twonear;
233cabdff1aSopenharmony_ci                if (!sign)
234cabdff1aSopenharmony_ci                    Ra = av_clip(pred + err * state->twonear, 0, state->maxval);
235cabdff1aSopenharmony_ci                else
236cabdff1aSopenharmony_ci                    Ra = av_clip(pred - err * state->twonear, 0, state->maxval);
237cabdff1aSopenharmony_ci            } else
238cabdff1aSopenharmony_ci                Ra = R(in, x);
239cabdff1aSopenharmony_ci            W(tmp, x, Ra);
240cabdff1aSopenharmony_ci
241cabdff1aSopenharmony_ci            ls_encode_regular(state, pb, context, err);
242cabdff1aSopenharmony_ci        }
243cabdff1aSopenharmony_ci        Rc = Rb;
244cabdff1aSopenharmony_ci        x += stride;
245cabdff1aSopenharmony_ci    }
246cabdff1aSopenharmony_ci}
247cabdff1aSopenharmony_ci
248cabdff1aSopenharmony_cistatic void ls_store_lse(JLSState *state, PutByteContext *pb)
249cabdff1aSopenharmony_ci{
250cabdff1aSopenharmony_ci    /* Test if we have default params and don't need to store LSE */
251cabdff1aSopenharmony_ci    JLSState state2 = { 0 };
252cabdff1aSopenharmony_ci    state2.bpp  = state->bpp;
253cabdff1aSopenharmony_ci    state2.near = state->near;
254cabdff1aSopenharmony_ci    ff_jpegls_reset_coding_parameters(&state2, 1);
255cabdff1aSopenharmony_ci    if (state->T1 == state2.T1 &&
256cabdff1aSopenharmony_ci        state->T2 == state2.T2 &&
257cabdff1aSopenharmony_ci        state->T3 == state2.T3 &&
258cabdff1aSopenharmony_ci        state->reset == state2.reset)
259cabdff1aSopenharmony_ci        return;
260cabdff1aSopenharmony_ci    /* store LSE type 1 */
261cabdff1aSopenharmony_ci    put_marker_byteu(pb, LSE);
262cabdff1aSopenharmony_ci    bytestream2_put_be16u(pb, 13);
263cabdff1aSopenharmony_ci    bytestream2_put_byteu(pb, 1);
264cabdff1aSopenharmony_ci    bytestream2_put_be16u(pb, state->maxval);
265cabdff1aSopenharmony_ci    bytestream2_put_be16u(pb, state->T1);
266cabdff1aSopenharmony_ci    bytestream2_put_be16u(pb, state->T2);
267cabdff1aSopenharmony_ci    bytestream2_put_be16u(pb, state->T3);
268cabdff1aSopenharmony_ci    bytestream2_put_be16u(pb, state->reset);
269cabdff1aSopenharmony_ci}
270cabdff1aSopenharmony_ci
271cabdff1aSopenharmony_cistatic int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt,
272cabdff1aSopenharmony_ci                             const AVFrame *pict, int *got_packet)
273cabdff1aSopenharmony_ci{
274cabdff1aSopenharmony_ci    JPEGLSContext *ctx = avctx->priv_data;
275cabdff1aSopenharmony_ci    const AVFrame *const p = pict;
276cabdff1aSopenharmony_ci    PutByteContext pb;
277cabdff1aSopenharmony_ci    PutBitContext pb2;
278cabdff1aSopenharmony_ci    GetBitContext gb;
279cabdff1aSopenharmony_ci    const uint8_t *in;
280cabdff1aSopenharmony_ci    uint8_t *last = NULL;
281cabdff1aSopenharmony_ci    JLSState state = { 0 };
282cabdff1aSopenharmony_ci    size_t size;
283cabdff1aSopenharmony_ci    int i, ret, size_in_bits;
284cabdff1aSopenharmony_ci    int comps;
285cabdff1aSopenharmony_ci
286cabdff1aSopenharmony_ci    last = av_mallocz(FFABS(p->linesize[0]));
287cabdff1aSopenharmony_ci    if (!last)
288cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
289cabdff1aSopenharmony_ci
290cabdff1aSopenharmony_ci    init_put_bits(&pb2, ctx->buf, ctx->size);
291cabdff1aSopenharmony_ci
292cabdff1aSopenharmony_ci    comps = ctx->comps;
293cabdff1aSopenharmony_ci    /* initialize JPEG-LS state from JPEG parameters */
294cabdff1aSopenharmony_ci    state.near = ctx->pred;
295cabdff1aSopenharmony_ci    state.bpp  = (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8;
296cabdff1aSopenharmony_ci    ff_jpegls_reset_coding_parameters(&state, 0);
297cabdff1aSopenharmony_ci    ff_jpegls_init_state(&state);
298cabdff1aSopenharmony_ci
299cabdff1aSopenharmony_ci    in = p->data[0];
300cabdff1aSopenharmony_ci    if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
301cabdff1aSopenharmony_ci        int t = 0;
302cabdff1aSopenharmony_ci
303cabdff1aSopenharmony_ci        for (i = 0; i < avctx->height; i++) {
304cabdff1aSopenharmony_ci            int last0 = last[0];
305cabdff1aSopenharmony_ci            ls_encode_line(&state, &pb2, last, in, t, avctx->width, 1, 0, 8);
306cabdff1aSopenharmony_ci            t   = last0;
307cabdff1aSopenharmony_ci            in += p->linesize[0];
308cabdff1aSopenharmony_ci        }
309cabdff1aSopenharmony_ci    } else if (avctx->pix_fmt == AV_PIX_FMT_GRAY16) {
310cabdff1aSopenharmony_ci        int t = 0;
311cabdff1aSopenharmony_ci
312cabdff1aSopenharmony_ci        for (i = 0; i < avctx->height; i++) {
313cabdff1aSopenharmony_ci            int last0 = *((uint16_t *)last);
314cabdff1aSopenharmony_ci            ls_encode_line(&state, &pb2, last, in, t, avctx->width, 1, 0, 16);
315cabdff1aSopenharmony_ci            t   = last0;
316cabdff1aSopenharmony_ci            in += p->linesize[0];
317cabdff1aSopenharmony_ci        }
318cabdff1aSopenharmony_ci    } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) {
319cabdff1aSopenharmony_ci        int j, width;
320cabdff1aSopenharmony_ci        int Rc[3] = { 0, 0, 0 };
321cabdff1aSopenharmony_ci
322cabdff1aSopenharmony_ci        width = avctx->width * 3;
323cabdff1aSopenharmony_ci        for (i = 0; i < avctx->height; i++) {
324cabdff1aSopenharmony_ci            for (j = 0; j < 3; j++) {
325cabdff1aSopenharmony_ci                int last0 = last[j];
326cabdff1aSopenharmony_ci                ls_encode_line(&state, &pb2, last + j, in + j, Rc[j],
327cabdff1aSopenharmony_ci                               width, 3, j, 8);
328cabdff1aSopenharmony_ci                Rc[j] = last0;
329cabdff1aSopenharmony_ci            }
330cabdff1aSopenharmony_ci            in += p->linesize[0];
331cabdff1aSopenharmony_ci        }
332cabdff1aSopenharmony_ci    } else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
333cabdff1aSopenharmony_ci        int j, width;
334cabdff1aSopenharmony_ci        int Rc[3] = { 0, 0, 0 };
335cabdff1aSopenharmony_ci
336cabdff1aSopenharmony_ci        width = avctx->width * 3;
337cabdff1aSopenharmony_ci        for (i = 0; i < avctx->height; i++) {
338cabdff1aSopenharmony_ci            for (j = 2; j >= 0; j--) {
339cabdff1aSopenharmony_ci                int last0 = last[j];
340cabdff1aSopenharmony_ci                ls_encode_line(&state, &pb2, last + j, in + j, Rc[j],
341cabdff1aSopenharmony_ci                               width, 3, j, 8);
342cabdff1aSopenharmony_ci                Rc[j] = last0;
343cabdff1aSopenharmony_ci            }
344cabdff1aSopenharmony_ci            in += p->linesize[0];
345cabdff1aSopenharmony_ci        }
346cabdff1aSopenharmony_ci    }
347cabdff1aSopenharmony_ci    av_free(last);
348cabdff1aSopenharmony_ci    /* Now the actual image data has been written, which enables us to estimate
349cabdff1aSopenharmony_ci     * the needed packet size: For every 15 input bits, an escape bit might be
350cabdff1aSopenharmony_ci     * added below; and if put_bits_count % 15 is >= 8, then another bit might
351cabdff1aSopenharmony_ci     * be added.
352cabdff1aSopenharmony_ci     * Furthermore the specification says that after doing 0xff escaping unused
353cabdff1aSopenharmony_ci     * bits in the last byte must be set to 0, so just append 7 "optional" zero
354cabdff1aSopenharmony_ci     * bits to avoid special-casing. This also simplifies the size calculation:
355cabdff1aSopenharmony_ci     * Properly rounding up is now automatically baked-in. */
356cabdff1aSopenharmony_ci    put_bits(&pb2, 7, 0);
357cabdff1aSopenharmony_ci    /* Make sure that the bit count + padding is representable in an int;
358cabdff1aSopenharmony_ci       necessary for put_bits_count() as well as for using a GetBitContext. */
359cabdff1aSopenharmony_ci    if (put_bytes_count(&pb2, 0) > INT_MAX / 8 - AV_INPUT_BUFFER_PADDING_SIZE)
360cabdff1aSopenharmony_ci        return AVERROR(ERANGE);
361cabdff1aSopenharmony_ci    size_in_bits = put_bits_count(&pb2);
362cabdff1aSopenharmony_ci    flush_put_bits(&pb2);
363cabdff1aSopenharmony_ci    size  = size_in_bits * 2U / 15;
364cabdff1aSopenharmony_ci    size += 2 + 2 + 2 + 1 + 2 + 2 + 1 + comps * (1 + 1 + 1) + 2 + 2 + 1
365cabdff1aSopenharmony_ci            + comps * (1 + 1) + 1 + 1 + 1; /* Header */
366cabdff1aSopenharmony_ci    size += 2 + 2 + 1 + 2 + 2 + 2 + 2 + 2; /* LSE */
367cabdff1aSopenharmony_ci    size += 2; /* EOI */
368cabdff1aSopenharmony_ci    if ((ret = ff_get_encode_buffer(avctx, pkt, size, 0)) < 0)
369cabdff1aSopenharmony_ci        return ret;
370cabdff1aSopenharmony_ci
371cabdff1aSopenharmony_ci    bytestream2_init_writer(&pb, pkt->data, pkt->size);
372cabdff1aSopenharmony_ci
373cabdff1aSopenharmony_ci    /* write our own JPEG header, can't use mjpeg_picture_header */
374cabdff1aSopenharmony_ci    put_marker_byteu(&pb, SOI);
375cabdff1aSopenharmony_ci    put_marker_byteu(&pb, SOF48);
376cabdff1aSopenharmony_ci    bytestream2_put_be16u(&pb, 8 + comps * 3); // header size depends on components
377cabdff1aSopenharmony_ci    bytestream2_put_byteu(&pb, (avctx->pix_fmt == AV_PIX_FMT_GRAY16) ? 16 : 8);  // bpp
378cabdff1aSopenharmony_ci    bytestream2_put_be16u(&pb, avctx->height);
379cabdff1aSopenharmony_ci    bytestream2_put_be16u(&pb, avctx->width);
380cabdff1aSopenharmony_ci    bytestream2_put_byteu(&pb, comps);          // components
381cabdff1aSopenharmony_ci    for (i = 1; i <= comps; i++) {
382cabdff1aSopenharmony_ci        bytestream2_put_byteu(&pb, i);     // component ID
383cabdff1aSopenharmony_ci        bytestream2_put_byteu(&pb, 0x11);  // subsampling: none
384cabdff1aSopenharmony_ci        bytestream2_put_byteu(&pb, 0);     // Tiq, used by JPEG-LS ext
385cabdff1aSopenharmony_ci    }
386cabdff1aSopenharmony_ci
387cabdff1aSopenharmony_ci    put_marker_byteu(&pb, SOS);
388cabdff1aSopenharmony_ci    bytestream2_put_be16u(&pb, 6 + comps * 2);
389cabdff1aSopenharmony_ci    bytestream2_put_byteu(&pb, comps);
390cabdff1aSopenharmony_ci    for (i = 1; i <= comps; i++) {
391cabdff1aSopenharmony_ci        bytestream2_put_byteu(&pb, i);   // component ID
392cabdff1aSopenharmony_ci        bytestream2_put_byteu(&pb, 0);   // mapping index: none
393cabdff1aSopenharmony_ci    }
394cabdff1aSopenharmony_ci    bytestream2_put_byteu(&pb, ctx->pred);
395cabdff1aSopenharmony_ci    bytestream2_put_byteu(&pb, (comps > 1) ? 1 : 0);  // interleaving: 0 - plane, 1 - line
396cabdff1aSopenharmony_ci    bytestream2_put_byteu(&pb, 0);  // point transform: none
397cabdff1aSopenharmony_ci
398cabdff1aSopenharmony_ci    ls_store_lse(&state, &pb);
399cabdff1aSopenharmony_ci
400cabdff1aSopenharmony_ci    /* do escape coding */
401cabdff1aSopenharmony_ci    init_get_bits(&gb, pb2.buf, size_in_bits);
402cabdff1aSopenharmony_ci    size_in_bits -= 7;
403cabdff1aSopenharmony_ci    while (get_bits_count(&gb) < size_in_bits) {
404cabdff1aSopenharmony_ci        int v;
405cabdff1aSopenharmony_ci        v = get_bits(&gb, 8);
406cabdff1aSopenharmony_ci        bytestream2_put_byteu(&pb, v);
407cabdff1aSopenharmony_ci        if (v == 0xFF) {
408cabdff1aSopenharmony_ci            v = get_bits(&gb, 7);
409cabdff1aSopenharmony_ci            bytestream2_put_byteu(&pb, v);
410cabdff1aSopenharmony_ci        }
411cabdff1aSopenharmony_ci    }
412cabdff1aSopenharmony_ci
413cabdff1aSopenharmony_ci    /* End of image */
414cabdff1aSopenharmony_ci    put_marker_byteu(&pb, EOI);
415cabdff1aSopenharmony_ci
416cabdff1aSopenharmony_ci    emms_c();
417cabdff1aSopenharmony_ci
418cabdff1aSopenharmony_ci    av_shrink_packet(pkt, bytestream2_tell_p(&pb));
419cabdff1aSopenharmony_ci    *got_packet = 1;
420cabdff1aSopenharmony_ci    return 0;
421cabdff1aSopenharmony_ci}
422cabdff1aSopenharmony_ci
423cabdff1aSopenharmony_cistatic av_cold int encode_jpegls_init(AVCodecContext *avctx)
424cabdff1aSopenharmony_ci{
425cabdff1aSopenharmony_ci    JPEGLSContext *ctx = avctx->priv_data;
426cabdff1aSopenharmony_ci    size_t size;
427cabdff1aSopenharmony_ci
428cabdff1aSopenharmony_ci    if ((avctx->width | avctx->height) > UINT16_MAX) {
429cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Dimensions exceeding 65535x65535\n");
430cabdff1aSopenharmony_ci        return AVERROR(EINVAL);
431cabdff1aSopenharmony_ci    }
432cabdff1aSopenharmony_ci    if (avctx->pix_fmt == AV_PIX_FMT_GRAY8 ||
433cabdff1aSopenharmony_ci        avctx->pix_fmt == AV_PIX_FMT_GRAY16)
434cabdff1aSopenharmony_ci        ctx->comps = 1;
435cabdff1aSopenharmony_ci    else
436cabdff1aSopenharmony_ci        ctx->comps = 3;
437cabdff1aSopenharmony_ci    size = AV_INPUT_BUFFER_MIN_SIZE;
438cabdff1aSopenharmony_ci    /* INT_MAX due to PutBit-API. */
439cabdff1aSopenharmony_ci    if (avctx->width * (unsigned)avctx->height > (INT_MAX - size) / 4 / ctx->comps)
440cabdff1aSopenharmony_ci        return AVERROR(ERANGE);
441cabdff1aSopenharmony_ci    size += 4 * ctx->comps * avctx->width * avctx->height;
442cabdff1aSopenharmony_ci    ctx->size = size;
443cabdff1aSopenharmony_ci    ctx->buf = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
444cabdff1aSopenharmony_ci    if (!ctx->buf)
445cabdff1aSopenharmony_ci        return AVERROR(ENOMEM);
446cabdff1aSopenharmony_ci
447cabdff1aSopenharmony_ci    return 0;
448cabdff1aSopenharmony_ci}
449cabdff1aSopenharmony_ci
450cabdff1aSopenharmony_cistatic av_cold int encode_jpegls_close(AVCodecContext *avctx)
451cabdff1aSopenharmony_ci{
452cabdff1aSopenharmony_ci    JPEGLSContext *ctx = avctx->priv_data;
453cabdff1aSopenharmony_ci
454cabdff1aSopenharmony_ci    av_freep(&ctx->buf);
455cabdff1aSopenharmony_ci    return 0;
456cabdff1aSopenharmony_ci}
457cabdff1aSopenharmony_ci
458cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(JPEGLSContext, x)
459cabdff1aSopenharmony_ci#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
460cabdff1aSopenharmony_cistatic const AVOption options[] = {
461cabdff1aSopenharmony_ci{ "pred", "Prediction method", OFFSET(pred), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, VE, "pred" },
462cabdff1aSopenharmony_ci    { "left",   NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "pred" },
463cabdff1aSopenharmony_ci    { "plane",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "pred" },
464cabdff1aSopenharmony_ci    { "median", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "pred" },
465cabdff1aSopenharmony_ci
466cabdff1aSopenharmony_ci    { NULL},
467cabdff1aSopenharmony_ci};
468cabdff1aSopenharmony_ci
469cabdff1aSopenharmony_cistatic const AVClass jpegls_class = {
470cabdff1aSopenharmony_ci    .class_name = "jpegls",
471cabdff1aSopenharmony_ci    .item_name  = av_default_item_name,
472cabdff1aSopenharmony_ci    .option     = options,
473cabdff1aSopenharmony_ci    .version    = LIBAVUTIL_VERSION_INT,
474cabdff1aSopenharmony_ci};
475cabdff1aSopenharmony_ci
476cabdff1aSopenharmony_ciconst FFCodec ff_jpegls_encoder = {
477cabdff1aSopenharmony_ci    .p.name         = "jpegls",
478cabdff1aSopenharmony_ci    .p.long_name    = NULL_IF_CONFIG_SMALL("JPEG-LS"),
479cabdff1aSopenharmony_ci    .p.type         = AVMEDIA_TYPE_VIDEO,
480cabdff1aSopenharmony_ci    .p.id           = AV_CODEC_ID_JPEGLS,
481cabdff1aSopenharmony_ci    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
482cabdff1aSopenharmony_ci    .priv_data_size = sizeof(JPEGLSContext),
483cabdff1aSopenharmony_ci    .p.priv_class   = &jpegls_class,
484cabdff1aSopenharmony_ci    .init           = encode_jpegls_init,
485cabdff1aSopenharmony_ci    FF_CODEC_ENCODE_CB(encode_picture_ls),
486cabdff1aSopenharmony_ci    .close          = encode_jpegls_close,
487cabdff1aSopenharmony_ci    .p.pix_fmts     = (const enum AVPixelFormat[]) {
488cabdff1aSopenharmony_ci        AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB24,
489cabdff1aSopenharmony_ci        AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16,
490cabdff1aSopenharmony_ci        AV_PIX_FMT_NONE
491cabdff1aSopenharmony_ci    },
492cabdff1aSopenharmony_ci    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
493cabdff1aSopenharmony_ci                      FF_CODEC_CAP_INIT_CLEANUP,
494cabdff1aSopenharmony_ci};
495