Mercurial > libavcodec.hg
annotate jpeg_ls.c @ 3063:f02d0b59279c libavcodec
Remove all stray tabs and trailing whitespace, this time for good.
author | diego |
---|---|
date | Tue, 24 Jan 2006 10:33:14 +0000 |
parents | 0b546eab515d |
children | 1e63c12c2c71 |
rev | line source |
---|---|
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 | |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2970
diff
changeset
|
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
2970 | 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; | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
75 |
2970 | 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); | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
106 |
2970 | 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); | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
114 |
2970 | 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--; | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
148 |
2970 | 149 drift += count; |
150 if(drift <= -count) | |
151 drift= -count + 1; | |
152 }else if(drift > 0){ | |
153 if(state->bias < 127) state->bias++; | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
154 |
2970 | 155 drift -= count; |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
156 if(drift > 0) |
2970 | 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; | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
172 |
2970 | 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; | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
184 |
2970 | 185 hr_gradient= rt - t; |
186 hl_gradient= t - lt; | |
187 v_gradient= lt - l; | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
188 |
2970 | 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 } | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
209 |
2970 | 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); | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
225 |
2970 | 226 if(sign) v= -v; |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
227 |
2970 | 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++; | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
237 |
2970 | 238 for(; run_count; run_count--){ |
239 if(is_uint8) ((uint8_t *)dst)[x++]= l; | |
240 else ((uint16_t*)dst)[x++]= l; | |
241 } | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
242 |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
243 if(x >= w) return 0; |
2970 | 244 } |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
245 |
2970 | 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 } | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
252 |
2970 | 253 if(run_index) run_index--; |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
254 |
2970 | 255 if(x >= w) return 0; |
256 | |
257 t= R(last, 0); | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
258 |
2970 | 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 } | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
267 |
2970 | 268 pred= t; |
269 sign= l > t; | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
270 |
2970 | 271 i= state->count; |
272 k=0; | |
273 while(i < temp){ //FIXME optimize | |
274 k++; | |
275 i += i; | |
276 } | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
277 |
2970 | 278 assert(Errval != 0); |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
279 map = (k==0 && 2*Nn < state->count) == (Errval>0); |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
280 |
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
281 |
2970 | 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; | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
301 |
2970 | 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]; | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
319 |
2970 | 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 } | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
337 |
2970 | 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]; | |
3063
f02d0b59279c
Remove all stray tabs and trailing whitespace, this time for good.
diego
parents:
3036
diff
changeset
|
359 |
2970 | 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 |