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