]> git.sesse.net Git - ffmpeg/blob - libavcodec/jpeg_ls.c
fix some potential arithmetic overflows in pred_direct_motion() and
[ffmpeg] / libavcodec / jpeg_ls.c
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