2970
|
1 /*
|
|
2 * JPEG-LS encoder and decoder
|
|
3 * Copyright (c) 2003 Michael Niedermayer
|
|
4 *
|
|
5 * This library is free software; you can redistribute it and/or
|
|
6 * modify it under the terms of the GNU Lesser General Public
|
|
7 * License as published by the Free Software Foundation; either
|
|
8 * version 2 of the License, or (at your option) any later version.
|
|
9 *
|
|
10 * This library is distributed in the hope that it will be useful,
|
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
13 * Lesser General Public License for more details.
|
|
14 *
|
|
15 * You should have received a copy of the GNU Lesser General Public
|
|
16 * License along with this library; if not, write to the Free Software
|
|
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
18 */
|
|
19
|
|
20 /**
|
|
21 * @file jpeg_ls.c
|
|
22 * JPEG-LS encoder and decoder.
|
|
23 */
|
|
24
|
|
25 #undef printf
|
|
26 #undef fprintf
|
|
27
|
|
28 static inline int quantize(MJpegDecodeContext *s, int v){ //FIXME optimize
|
|
29 if(v==0) return 0;
|
|
30 if(v < 0){
|
|
31 if (v >-s->t1) return -1;
|
|
32 else if(v >-s->t2) return -2;
|
|
33 else if(v >-s->t3) return -3;
|
|
34 else return -4;
|
|
35 }else{
|
|
36 if (v < s->t1) return 1;
|
|
37 else if(v < s->t2) return 2;
|
|
38 else if(v < s->t3) return 3;
|
|
39 else return 4;
|
|
40 }
|
|
41 }
|
|
42
|
|
43 static inline int predict8(uint8_t *src, uint8_t *last){ //FIXME perhaps its better to suppress these 2
|
|
44 const int LT= last[-1];
|
|
45 const int T= last[ 0];
|
|
46 const int L = src[-1];
|
|
47
|
|
48 return mid_pred(L, L + T - LT, T);
|
|
49 }
|
|
50
|
|
51 static inline int predict16(uint16_t *src, uint16_t *last){
|
|
52 const int LT= last[-1];
|
|
53 const int T= last[ 0];
|
|
54 const int L = src[-1];
|
|
55
|
|
56 return mid_pred(L, L + T - LT, T);
|
|
57 }
|
|
58
|
|
59 static int encode_picture_ls(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
|
|
60 return 0;
|
|
61 }
|
|
62
|
|
63 static int iso_clip(int v, int vmin, int vmax){
|
|
64 if(v > vmax || v < vmin) return vmin;
|
|
65 else return v;
|
|
66 }
|
|
67
|
|
68 static void reset_ls_coding_parameters(MJpegDecodeContext *s, int reset_all){
|
|
69 const int basic_t1= 3;
|
|
70 const int basic_t2= 7;
|
|
71 const int basic_t3= 21;
|
|
72 int factor;
|
|
73
|
|
74 if(s->maxval==0 || reset_all) s->maxval= (1<<s->bits) - 1;
|
|
75
|
|
76 if(s->maxval >=128){
|
|
77 factor= (FFMIN(s->maxval, 4096) + 128)>>8;
|
|
78
|
|
79 if(s->t1==0 || reset_all)
|
|
80 s->t1= iso_clip(factor*(basic_t1-2) + 2 + 3*s->near, s->near+1, s->maxval);
|
|
81 if(s->t2==0 || reset_all)
|
|
82 s->t2= iso_clip(factor*(basic_t2-3) + 3 + 5*s->near, s->t1, s->maxval);
|
|
83 if(s->t3==0 || reset_all)
|
|
84 s->t3= iso_clip(factor*(basic_t3-4) + 4 + 7*s->near, s->t2, s->maxval);
|
|
85 }else{
|
|
86 factor= 256 / (s->maxval + 1);
|
|
87
|
|
88 if(s->t1==0 || reset_all)
|
|
89 s->t1= iso_clip(FFMAX(2, basic_t1/factor + 3*s->near), s->near+1, s->maxval);
|
|
90 if(s->t2==0 || reset_all)
|
|
91 s->t2= iso_clip(FFMAX(3, basic_t2/factor + 5*s->near), s->t1, s->maxval);
|
|
92 if(s->t3==0 || reset_all)
|
|
93 s->t3= iso_clip(FFMAX(4, basic_t3/factor + 6*s->near), s->t2, s->maxval);
|
|
94 }
|
|
95
|
|
96 if(s->reset==0 || reset_all) s->reset= 64;
|
|
97 }
|
|
98
|
|
99 static int decode_lse(MJpegDecodeContext *s)
|
|
100 {
|
|
101 int len, id;
|
|
102
|
|
103 /* XXX: verify len field validity */
|
|
104 len = get_bits(&s->gb, 16);
|
|
105 id = get_bits(&s->gb, 8);
|
|
106
|
|
107 switch(id){
|
|
108 case 1:
|
|
109 s->maxval= get_bits(&s->gb, 16);
|
|
110 s->t1= get_bits(&s->gb, 16);
|
|
111 s->t2= get_bits(&s->gb, 16);
|
|
112 s->t3= get_bits(&s->gb, 16);
|
|
113 s->reset= get_bits(&s->gb, 16);
|
|
114
|
|
115 reset_ls_coding_parameters(s, 0);
|
|
116 //FIXME quant table?
|
|
117 break;
|
|
118 case 2:
|
|
119 case 3:
|
|
120 printf("palette not supported\n");
|
|
121 return -1;
|
|
122 case 4:
|
|
123 printf("oversize image not supported\n");
|
|
124 return -1;
|
|
125 default:
|
|
126 printf("invalid id %d\n", id);
|
|
127 return -1;
|
|
128 }
|
|
129
|
|
130 return 0;
|
|
131 }
|
|
132 #if 0
|
|
133 static inline void update_vlc_state(VlcState * const state, const int v, int half_count){
|
|
134 int drift= state->drift;
|
|
135 int count= state->count;
|
|
136 state->error_sum += ABS(v);
|
|
137 drift += v;
|
|
138
|
|
139 if(count == half_count){
|
|
140 count >>= 1;
|
|
141 drift >>= 1;
|
|
142 state->error_sum >>= 1;
|
|
143 }
|
|
144 count++;
|
|
145
|
|
146 if(drift <= -count){
|
|
147 if(state->bias > -128) state->bias--;
|
|
148
|
|
149 drift += count;
|
|
150 if(drift <= -count)
|
|
151 drift= -count + 1;
|
|
152 }else if(drift > 0){
|
|
153 if(state->bias < 127) state->bias++;
|
|
154
|
|
155 drift -= count;
|
|
156 if(drift > 0)
|
|
157 drift= 0;
|
|
158 }
|
|
159
|
|
160 state->drift= drift;
|
|
161 state->count= count;
|
|
162 }
|
|
163
|
|
164 #define R(p, i) (is_uint8 ? (((uint8_t*)p)[i] : ((uint16_t*)p)[i])
|
|
165
|
|
166 static inline int ls_decode_line(MJpegDecodeContext *s, void *lastv, void *dstv, int last2,
|
|
167 int w, int point_transform, int is_uint8){
|
|
168 int i, x, y;
|
|
169
|
|
170 for(x=0; x < w; x++){
|
|
171 int l, t, lt, rt;
|
|
172
|
|
173 t= R(last, 0);
|
|
174 if(x){
|
|
175 l = t;
|
|
176 lt= last2;
|
|
177 }else{
|
|
178 l = R(dst, x-1);
|
|
179 lt= R(last, x-1);
|
|
180 }
|
|
181
|
|
182 if(x<w-1) rt= R(last, x+1);
|
|
183 else rt= t;
|
|
184
|
|
185 hr_gradient= rt - t;
|
|
186 hl_gradient= t - lt;
|
|
187 v_gradient= lt - l;
|
|
188
|
|
189 context= quantize(s, v_gradient) + 9*(quantize(s, hl_gradient) + 9*quantize(s, hr_gradient));
|
|
190
|
|
191 if(context){
|
|
192 int pred= mid_pred(l, l + t - lt, t);
|
|
193
|
|
194 if(context < 0){
|
|
195 context= -context;
|
|
196 sign= 1;
|
|
197 pred= clip(0, pred - state->bias, maxval);
|
|
198 }else{
|
|
199 sign= 0;
|
|
200 pred= clip(0, pred + state->bias, maxval);
|
|
201 }
|
|
202
|
|
203 i= state->count;
|
|
204 k=0;
|
|
205 while(i < state->error_sum){ //FIXME optimize
|
|
206 k++;
|
|
207 i += i;
|
|
208 }
|
|
209
|
|
210 v= get_ur_golomb_jpegls(gb, k, LIMIT-qbpp, qbpp);
|
|
211 #if 1
|
|
212 v++;
|
|
213 if(v&1) v= (v>>1);
|
|
214 else v= -(v>>1);
|
|
215
|
|
216 if(k==0 && 2*state->drift <= - state->count) v ^= (-1);
|
|
217 #else
|
|
218 v ^= (k==0 && 2*state->drift <= - state->count);
|
|
219 v++;
|
|
220 if(v&1) v= (v>>1);
|
|
221 else v= -(v>>1);
|
|
222
|
|
223 #endif
|
|
224 update_vlc_state(state, v, half_count);
|
|
225
|
|
226 if(sign) v= -v;
|
|
227
|
|
228 if(is_uint8) ((uint8_t *)dst)[x]= (pred + v) & maxval;
|
|
229 else ((uint16_t*)dst)[x]= (pred + v) & maxval;
|
|
230 }else{
|
|
231 int run_count;
|
|
232
|
|
233 while(get_bits1(&s->gb)){
|
|
234 run_count = 1<<log2_run[run_index];
|
|
235 if(x + run_count > w) run_count= w - x;
|
|
236 else run_index++;
|
|
237
|
|
238 for(; run_count; run_count--){
|
|
239 if(is_uint8) ((uint8_t *)dst)[x++]= l;
|
|
240 else ((uint16_t*)dst)[x++]= l;
|
|
241 }
|
|
242
|
|
243 if(x >= w) return 0;
|
|
244 }
|
|
245
|
|
246 run_count= get_bits(&s->gb, log2_run[run_index]);
|
|
247
|
|
248 for(; run_count; run_count--){
|
|
249 if(is_uint8) ((uint8_t *)dst)[x++]= l;
|
|
250 else ((uint16_t*)dst)[x++]= l;
|
|
251 }
|
|
252
|
|
253 if(run_index) run_index--;
|
|
254
|
|
255 if(x >= w) return 0;
|
|
256
|
|
257 t= R(last, 0);
|
|
258
|
|
259 RItype= (l==t);
|
|
260 if(l==t){
|
|
261 state= 366;
|
|
262 temp= state->error_sum + (state->count>>1);
|
|
263 }else{
|
|
264 state= 365;
|
|
265 temp= state->error_sum;
|
|
266 }
|
|
267
|
|
268 pred= t;
|
|
269 sign= l > t;
|
|
270
|
|
271 i= state->count;
|
|
272 k=0;
|
|
273 while(i < temp){ //FIXME optimize
|
|
274 k++;
|
|
275 i += i;
|
|
276 }
|
|
277
|
|
278 assert(Errval != 0);
|
|
279 map = (k==0 && 2*Nn < state->count) == (Errval>0);
|
|
280
|
|
281
|
|
282 if(run_count==0 && run_mode==1){
|
|
283 if(get_bits1(&s->gb)){
|
|
284 run_count = 1<<log2_run[run_index];
|
|
285 if(x + run_count <= w) run_index++;
|
|
286 }else{
|
|
287 if(log2_run[run_index]) run_count = get_bits(&s->gb, log2_run[run_index]);
|
|
288 else run_count=0;
|
|
289 if(run_index) run_index--;
|
|
290 run_mode=2;
|
|
291 }
|
|
292 }
|
|
293 run_count--;
|
|
294 if(run_count < 0){
|
|
295 run_mode=0;
|
|
296 run_count=0;
|
|
297 diff= get_vlc_symbol(&s->gb, &p->vlc_state[context]);
|
|
298 if(diff>=0) diff++;
|
|
299 }else
|
|
300 diff=0;
|
|
301
|
|
302 }
|
|
303 }
|
|
304
|
|
305 /* if (s->restart_interval && !s->restart_count)
|
|
306 s->restart_count = s->restart_interval;*/
|
|
307
|
|
308 if(mb_x==0 || mb_y==0 || s->interlaced){
|
|
309 for(i=0;i<nb_components;i++) {
|
|
310 uint8_t *ptr;
|
|
311 int n, h, v, x, y, c, j, linesize;
|
|
312 n = s->nb_blocks[i];
|
|
313 c = s->comp_index[i];
|
|
314 h = s->h_scount[i];
|
|
315 v = s->v_scount[i];
|
|
316 x = 0;
|
|
317 y = 0;
|
|
318 linesize= s->linesize[c];
|
|
319
|
|
320 for(j=0; j<n; j++) {
|
|
321 int pred;
|
|
322
|
|
323 ptr = s->current_picture[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
|
|
324 if(y==0 && mb_y==0){
|
|
325 if(x==0 && mb_x==0){
|
|
326 pred= 128 << point_transform;
|
|
327 }else{
|
|
328 pred= ptr[-1];
|
|
329 }
|
|
330 }else{
|
|
331 if(x==0 && mb_x==0){
|
|
332 pred= ptr[-linesize];
|
|
333 }else{
|
|
334 PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
|
|
335 }
|
|
336 }
|
|
337
|
|
338 if (s->interlaced && s->bottom_field)
|
|
339 ptr += linesize >> 1;
|
|
340 *ptr= pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform);
|
|
341
|
|
342 if (++x == h) {
|
|
343 x = 0;
|
|
344 y++;
|
|
345 }
|
|
346 }
|
|
347 }
|
|
348 }else{
|
|
349 for(i=0;i<nb_components;i++) {
|
|
350 uint8_t *ptr;
|
|
351 int n, h, v, x, y, c, j, linesize;
|
|
352 n = s->nb_blocks[i];
|
|
353 c = s->comp_index[i];
|
|
354 h = s->h_scount[i];
|
|
355 v = s->v_scount[i];
|
|
356 x = 0;
|
|
357 y = 0;
|
|
358 linesize= s->linesize[c];
|
|
359
|
|
360 for(j=0; j<n; j++) {
|
|
361 int pred;
|
|
362
|
|
363 ptr = s->current_picture[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
|
|
364 PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
|
|
365 *ptr= pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform);
|
|
366 if (++x == h) {
|
|
367 x = 0;
|
|
368 y++;
|
|
369 }
|
|
370 }
|
|
371 }
|
|
372 }
|
|
373 if (s->restart_interval && !--s->restart_count) {
|
|
374 align_get_bits(&s->gb);
|
|
375 skip_bits(&s->gb, 16); /* skip RSTn */
|
|
376 }
|
|
377 return 0;
|
|
378 }
|
|
379 #endif
|
|
380
|
|
381 #ifdef CONFIG_ENCODERS
|
|
382 AVCodec jpegls_encoder = { //FIXME avoid MPV_* lossless jpeg shouldnt need them
|
|
383 "jpegls",
|
|
384 CODEC_TYPE_VIDEO,
|
|
385 CODEC_ID_JPEGLS,
|
|
386 sizeof(MpegEncContext),
|
|
387 MPV_encode_init,
|
|
388 encode_picture_ls,
|
|
389 MPV_encode_end,
|
|
390 };
|
|
391 #endif
|