]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blob - libavcodec/indeo3.c
* fixing a few of gcc 'clean-code' warnings
[frescor/ffmpeg.git] / libavcodec / indeo3.c
1 /*
2  * Intel Indeo 3 (IV31, IV32, etc.) video decoder for ffmpeg
3  * written, produced, and directed by Alan Smithee
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 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24
25 #include "common.h"
26 #include "avcodec.h"
27 #include "dsputil.h"
28 #include "mpegvideo.h"
29
30 #include "indeo3data.h"
31
32 typedef struct
33 {
34   unsigned char *Ybuf;
35   unsigned char *Ubuf;
36   unsigned char *Vbuf;
37   unsigned char *the_buf;
38   unsigned int the_buf_size;
39   unsigned short y_w, y_h;
40   unsigned short uv_w, uv_h;
41 } YUVBufs;
42
43 typedef struct Indeo3DecodeContext {
44     AVCodecContext *avctx;
45     int width, height;
46     AVFrame frame;
47
48     YUVBufs iv_frame[2];
49     YUVBufs *cur_frame;
50     YUVBufs *ref_frame;
51
52     unsigned char *ModPred;
53     unsigned short *corrector_type;
54 } Indeo3DecodeContext;
55
56 static int corrector_type_0[24] = {
57   195, 159, 133, 115, 101,  93,  87,  77,
58   195, 159, 133, 115, 101,  93,  87,  77,
59   128,  79,  79,  79,  79,  79,  79,  79
60 };
61
62 static int corrector_type_2[8] = { 9, 7, 6, 8, 5, 4, 3, 2 };
63
64 static void build_modpred(Indeo3DecodeContext *s) 
65 {
66   int i, j;
67
68   s->ModPred = (unsigned char *) av_malloc (8 * 128);
69
70   for (i=0; i < 128; ++i) {
71     s->ModPred[i+0*128] = (i > 126) ? 254 : 2*((i + 1) - ((i + 1) % 2));
72     s->ModPred[i+1*128] = (i == 7)  ?  20 : ((i == 119 || i == 120)
73                                  ? 236 : 2*((i + 2) - ((i + 1) % 3)));
74     s->ModPred[i+2*128] = (i > 125) ? 248 : 2*((i + 2) - ((i + 2) % 4));
75     s->ModPred[i+3*128] =                        2*((i + 1) - ((i - 3) % 5));
76     s->ModPred[i+4*128] = (i == 8)  ?  20 : 2*((i + 1) - ((i - 3) % 6));
77     s->ModPred[i+5*128] =                        2*((i + 4) - ((i + 3) % 7));
78     s->ModPred[i+6*128] = (i > 123) ? 240 : 2*((i + 4) - ((i + 4) % 8));
79     s->ModPred[i+7*128] =                        2*((i + 5) - ((i + 4) % 9));
80   }
81
82   s->corrector_type = (unsigned short *) av_malloc (24 * 256 * sizeof(unsigned short));
83
84   for (i=0; i < 24; ++i) {
85     for (j=0; j < 256; ++j) {
86       s->corrector_type[i*256+j] = (j < corrector_type_0[i])
87                                 ? 1 : ((j < 248 || (i == 16 && j == 248))
88                                        ? 0 : corrector_type_2[j - 248]);
89     }
90   }
91 }
92
93 static void iv_Decode_Chunk(Indeo3DecodeContext *s, unsigned char *cur, 
94   unsigned char *ref, int width, int height, unsigned char *buf1, 
95   long fflags2, unsigned char *hdr,
96   unsigned char *buf2, int min_width_160);
97
98 #define min(a,b) ((a) < (b) ? (a) : (b))
99
100 /* ---------------------------------------------------------------------- */
101 static void iv_alloc_frames(Indeo3DecodeContext *s) 
102 {
103   int luma_width, luma_height, luma_pixels, chroma_width, chroma_height,
104       chroma_pixels, i;
105   unsigned int bufsize;
106
107   luma_width   = (s->width  + 3) & (~3);
108   luma_height  = (s->height + 3) & (~3);
109
110   s->iv_frame[0].y_w = s->iv_frame[0].y_h = 
111     s->iv_frame[0].the_buf_size = 0;
112   s->iv_frame[1].y_w = s->iv_frame[1].y_h = 
113     s->iv_frame[1].the_buf_size = 0;
114   s->iv_frame[1].the_buf = NULL;
115
116   chroma_width  = ((luma_width >> 2) + 3) & (~3);
117   chroma_height = ((luma_height>> 2) + 3) & (~3);
118   luma_pixels = luma_width * luma_height;
119   chroma_pixels = chroma_width * chroma_height;
120
121   bufsize = luma_pixels * 2 + luma_width * 3 + 
122     (chroma_pixels + chroma_width) * 4;
123
124   if((s->iv_frame[0].the_buf = 
125     (s->iv_frame[0].the_buf_size == 0 ? av_malloc(bufsize) : 
126       av_realloc(s->iv_frame[0].the_buf, bufsize))) == NULL)
127     return;
128   s->iv_frame[0].y_w = s->iv_frame[1].y_w = luma_width;
129   s->iv_frame[0].y_h = s->iv_frame[1].y_h = luma_height;
130   s->iv_frame[0].uv_w = s->iv_frame[1].uv_w = chroma_width;
131   s->iv_frame[0].uv_h = s->iv_frame[1].uv_h = chroma_height;
132   s->iv_frame[0].the_buf_size = bufsize;
133
134   s->iv_frame[0].Ybuf = s->iv_frame[0].the_buf + luma_width;
135   i = luma_pixels + luma_width * 2;
136   s->iv_frame[1].Ybuf = s->iv_frame[0].the_buf + i;
137   i += (luma_pixels + luma_width);
138   s->iv_frame[0].Ubuf = s->iv_frame[0].the_buf + i;
139   i += (chroma_pixels + chroma_width);
140   s->iv_frame[1].Ubuf = s->iv_frame[0].the_buf + i;
141   i += (chroma_pixels + chroma_width);
142   s->iv_frame[0].Vbuf = s->iv_frame[0].the_buf + i;
143   i += (chroma_pixels + chroma_width);
144   s->iv_frame[1].Vbuf = s->iv_frame[0].the_buf + i;
145
146   for(i = 1; i <= luma_width; i++)
147     s->iv_frame[0].Ybuf[-i] = s->iv_frame[1].Ybuf[-i] = 
148       s->iv_frame[0].Ubuf[-i] = 0x80;
149
150   for(i = 1; i <= chroma_width; i++) {
151     s->iv_frame[1].Ubuf[-i] = 0x80;
152     s->iv_frame[0].Vbuf[-i] = 0x80;
153     s->iv_frame[1].Vbuf[-i] = 0x80;
154     s->iv_frame[1].Vbuf[chroma_pixels+i-1] = 0x80;
155   }
156 }
157
158 /* ---------------------------------------------------------------------- */
159 static void iv_free_func(Indeo3DecodeContext *s) 
160 {
161   int i;
162
163   for(i = 0 ; i < 2 ; i++) {
164     if(s->iv_frame[i].the_buf != NULL) 
165       av_free(s->iv_frame[i].the_buf);
166     s->iv_frame[i].Ybuf = s->iv_frame[i].Ubuf = 
167       s->iv_frame[i].Vbuf = NULL;
168     s->iv_frame[i].the_buf = NULL;
169     s->iv_frame[i].the_buf_size = 0;
170     s->iv_frame[i].y_w = s->iv_frame[i].y_h = 0;
171     s->iv_frame[i].uv_w = s->iv_frame[i].uv_h = 0;
172   }
173
174   av_free(s->ModPred);
175   av_free(s->corrector_type);
176 }
177
178 /* ---------------------------------------------------------------------- */
179 static unsigned long iv_decode_frame(Indeo3DecodeContext *s, 
180                                      unsigned char *buf, int buf_size) 
181 {
182   unsigned int hdr_width, hdr_height,
183     chroma_width, chroma_height;
184   unsigned long fflags1, fflags2, fflags3, offs1, offs2, offs3, offs;
185   unsigned char *hdr_pos, *buf_pos;
186
187   buf_pos = buf;
188   buf_pos += 18;
189
190   fflags1 = le2me_16(*(uint16_t *)buf_pos);
191   buf_pos += 2;
192   fflags3 = le2me_32(*(uint32_t *)buf_pos);
193   buf_pos += 4;
194   fflags2 = *buf_pos++;
195   buf_pos += 3;
196   hdr_height = le2me_16(*(uint16_t *)buf_pos);
197   buf_pos += 2;
198   hdr_width = le2me_16(*(uint16_t *)buf_pos);
199   buf_pos += 2;
200   chroma_height = ((hdr_height >> 2) + 3) & 0x7ffc;
201   chroma_width = ((hdr_width >> 2) + 3) & 0x7ffc;
202   offs1 = le2me_32(*(uint32_t *)buf_pos);
203   buf_pos += 4;
204   offs2 = le2me_32(*(uint32_t *)buf_pos);
205   buf_pos += 4;
206   offs3 = le2me_32(*(uint32_t *)buf_pos);
207   buf_pos += 8;
208   hdr_pos = buf_pos;
209   if(fflags3 == 0x80) return 4;
210
211   if(fflags1 & 0x200) {
212     s->cur_frame = s->iv_frame + 1;
213     s->ref_frame = s->iv_frame;
214   } else {
215     s->cur_frame = s->iv_frame;
216     s->ref_frame = s->iv_frame + 1;
217   }
218
219   buf_pos = buf + 16 + offs1;
220   offs = le2me_32(*(uint32_t *)buf_pos);
221   buf_pos += 4;
222
223   iv_Decode_Chunk(s, s->cur_frame->Ybuf, s->ref_frame->Ybuf, hdr_width, 
224     hdr_height, buf_pos + offs * 2, fflags2, hdr_pos, buf_pos, 
225     min(hdr_width, 160));
226
227   if (!(s->avctx->flags & CODEC_FLAG_GRAY))
228   {
229
230   buf_pos = buf + 16 + offs2;
231   offs = le2me_32(*(uint32_t *)buf_pos);
232   buf_pos += 4;
233
234   iv_Decode_Chunk(s, s->cur_frame->Vbuf, s->ref_frame->Vbuf, chroma_width, 
235     chroma_height, buf_pos + offs * 2, fflags2, hdr_pos, buf_pos, 
236     min(chroma_width, 40));
237
238   buf_pos = buf + 16 + offs3;
239   offs = le2me_32(*(uint32_t *)buf_pos);
240   buf_pos += 4;
241
242   iv_Decode_Chunk(s, s->cur_frame->Ubuf, s->ref_frame->Ubuf, chroma_width, 
243     chroma_height, buf_pos + offs * 2, fflags2, hdr_pos, buf_pos, 
244     min(chroma_width, 40));
245
246   }
247
248   return 8;
249 }
250
251 typedef struct {
252   long xpos;
253   long ypos;
254   long width;
255   long height;
256   long split_flag;
257   long split_direction;
258   long usl7;
259 } ustr_t;
260
261 /* ---------------------------------------------------------------------- */
262
263 #define LV1_CHECK(buf1,rle_v3,lv1,lp2)  \
264   if((lv1 & 0x80) != 0) {   \
265     if(rle_v3 != 0)         \
266       rle_v3 = 0;           \
267     else {                  \
268       rle_v3 = 1;           \
269       buf1 -= 2;            \
270     }                       \
271   }                         \
272   lp2 = 4;
273
274
275 #define RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)  \
276   if(rle_v3 == 0) {         \
277     rle_v2 = *buf1;         \
278     rle_v1 = 1;             \
279     if(rle_v2 > 32) {       \
280       rle_v2 -= 32;         \
281       rle_v1 = 0;           \
282     }                       \
283     rle_v3 = 1;             \
284   }                         \
285   buf1--;
286
287
288 #define LP2_CHECK(buf1,rle_v3,lp2)  \
289   if(lp2 == 0 && rle_v3 != 0)     \
290     rle_v3 = 0;           \
291   else {                  \
292     buf1--;               \
293     rle_v3 = 1;           \
294   }
295
296
297 #define RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) \
298   rle_v2--;             \
299   if(rle_v2 == 0) {     \
300     rle_v3 = 0;         \
301     buf1 += 2;          \
302   }                     \
303   lp2 = 4;
304
305 static void iv_Decode_Chunk(Indeo3DecodeContext *s,
306   unsigned char *cur, unsigned char *ref, int width, int height, 
307   unsigned char *buf1, long fflags2, unsigned char *hdr,
308   unsigned char *buf2, int min_width_160)
309 {
310   unsigned char bit_buf;
311   unsigned long bit_pos, lv, lv1, lv2;
312   long *width_tbl, width_tbl_arr[10];
313   char *ref_vectors;
314   unsigned char *cur_frm_pos, *ref_frm_pos, *cp, *cp2;
315   uint32_t *cur_lp, *ref_lp;
316   const uint32_t *correction_lp[2], *correctionloworder_lp[2], *correctionhighorder_lp[2];
317   unsigned short *correction_type_sp[2];
318   ustr_t strip_tbl[20], *strip;
319   int i, j, k, lp1, lp2, flag1, cmd, blks_width, blks_height, region_160_width,
320     rle_v1, rle_v2, rle_v3;
321
322   bit_buf = 0;
323   ref_vectors = NULL;
324
325   width_tbl = width_tbl_arr + 1;
326   i = (width < 0 ? width + 3 : width)/4;
327   for(j = -1; j < 8; j++) 
328     width_tbl[j] = i * j;
329
330   strip = strip_tbl;
331
332   for(region_160_width = 0; region_160_width < (width - min_width_160); region_160_width += min_width_160);
333
334   strip->ypos = strip->xpos = 0;
335   for(strip->width = min_width_160; width > strip->width; strip->width *= 2);
336   strip->height = height;
337   strip->split_direction = 0;
338   strip->split_flag = 0;
339   strip->usl7 = 0;
340
341   bit_pos = 0;
342
343   rle_v1 = rle_v2 = rle_v3 = 0;
344
345   while(strip >= strip_tbl) {
346     if(bit_pos <= 0) {
347       bit_pos = 8;
348       bit_buf = *buf1++;
349     }
350
351     bit_pos -= 2;
352     cmd = (bit_buf >> bit_pos) & 0x03;
353
354     if(cmd == 0) {
355       strip++;
356       memcpy(strip, strip-1, sizeof(ustr_t));
357       strip->split_flag = 1;
358       strip->split_direction = 0;
359       strip->height = (strip->height > 8 ? ((strip->height+8)>>4)<<3 : 4);
360       continue;
361     } else if(cmd == 1) {
362       strip++;
363       memcpy(strip, strip-1, sizeof(ustr_t));
364       strip->split_flag = 1;
365       strip->split_direction = 1;
366       strip->width = (strip->width > 8 ? ((strip->width+8)>>4)<<3 : 4);
367       continue;
368     } else if(cmd == 2) {
369       if(strip->usl7 == 0) {
370         strip->usl7 = 1;
371         ref_vectors = NULL;
372         continue;
373       }
374     } else if(cmd == 3) {
375       if(strip->usl7 == 0) {
376         strip->usl7 = 1;
377         ref_vectors = buf2 + (*buf1 * 2);
378         buf1++;
379         continue;
380       }
381     }
382
383     cur_frm_pos = cur + width * strip->ypos + strip->xpos;
384
385     if((blks_width = strip->width) < 0) 
386       blks_width += 3;
387     blks_width >>= 2;
388     blks_height = strip->height;
389
390     if(ref_vectors != NULL) {
391       ref_frm_pos = ref + (ref_vectors[0] + strip->ypos) * width +
392         ref_vectors[1] + strip->xpos;
393     } else 
394       ref_frm_pos = cur_frm_pos - width_tbl[4];
395
396     if(cmd == 2) {
397       if(bit_pos <= 0) {
398         bit_pos = 8;
399         bit_buf = *buf1++;
400       }
401
402       bit_pos -= 2;
403       cmd = (bit_buf >> bit_pos) & 0x03;
404
405       if(cmd == 0 || ref_vectors != NULL) {
406         for(lp1 = 0; lp1 < blks_width; lp1++) {
407           for(i = 0, j = 0; i < blks_height; i++, j += width_tbl[1])
408             ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j];
409           cur_frm_pos += 4;
410           ref_frm_pos += 4;
411         }
412       } else if(cmd != 1) 
413         return;
414     } else {
415       k = *buf1 >> 4;
416       j = *buf1 & 0x0f;
417       buf1++;
418       lv = j + fflags2;
419
420       if((lv - 8) <= 7 && (k == 0 || k == 3 || k == 10)) {
421         cp2 = s->ModPred + ((lv - 8) << 7);
422         cp = ref_frm_pos;
423         for(i = 0; i < blks_width << 2; i++) { 
424             int v = *cp >> 1;
425             *(cp++) = cp2[v]; 
426         }
427       }
428
429       if(k == 1 || k == 4) {
430         lv = (hdr[j] & 0xf) + fflags2;
431         correction_type_sp[0] = s->corrector_type + (lv << 8);
432         correction_lp[0] = correction + (lv << 8);
433         lv = (hdr[j] >> 4) + fflags2;
434         correction_lp[1] = correction + (lv << 8);
435         correction_type_sp[1] = s->corrector_type + (lv << 8);
436       } else {
437         correctionloworder_lp[0] = correctionloworder_lp[1] = correctionloworder + (lv << 8);
438         correctionhighorder_lp[0] = correctionhighorder_lp[1] = correctionhighorder + (lv << 8);
439         correction_type_sp[0] = correction_type_sp[1] = s->corrector_type + (lv << 8);
440         correction_lp[0] = correction_lp[1] = correction + (lv << 8);
441       }
442
443       switch(k) {
444         case 1:
445         case 0:                    /********** CASE 0 **********/
446           for( ; blks_height > 0; blks_height -= 4) {
447             for(lp1 = 0; lp1 < blks_width; lp1++) {
448               for(lp2 = 0; lp2 < 4; ) {
449                 k = *buf1++;
450                 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2];
451                 ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2];
452
453                 switch(correction_type_sp[0][k]) {
454                   case 0:
455                     *cur_lp = ((*ref_lp >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
456                     lp2++;
457                     break;
458                   case 1:
459                     ((unsigned short *)cur_lp)[0] = ((((unsigned short *)(ref_lp))[0] >> 1)
460                       + correction_lp[lp2 & 0x01][*buf1++]) << 1;
461                     ((unsigned short *)cur_lp)[1] = ((((unsigned short *)(ref_lp))[1] >> 1)
462                       + correction_lp[lp2 & 0x01][k]) << 1;
463                     lp2++;
464                     break;
465                   case 2:
466                     if(lp2 == 0) {
467                       for(i = 0, j = 0; i < 2; i++, j += width_tbl[1])
468                         cur_lp[j] = ref_lp[j];
469                       lp2 += 2;
470                     }
471                     break;
472                   case 3:
473                     if(lp2 < 2) {
474                       for(i = 0, j = 0; i < (3 - lp2); i++, j += width_tbl[1])
475                         cur_lp[j] = ref_lp[j];
476                       lp2 = 3;
477                     }
478                     break;
479                   case 8:
480                     if(lp2 == 0) {
481                       RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
482
483                       if(rle_v1 == 1 || ref_vectors != NULL) {
484                         for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
485                           cur_lp[j] = ref_lp[j];
486                       }
487
488                       RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
489                       break;
490                     } else {
491                       rle_v1 = 1;
492                       rle_v2 = *buf1 - 1;
493                     }
494                   case 5:
495                       LP2_CHECK(buf1,rle_v3,lp2)
496                   case 4:
497                     for(i = 0, j = 0; i < (4 - lp2); i++, j += width_tbl[1])
498                       cur_lp[j] = ref_lp[j];
499                     lp2 = 4;
500                     break;
501
502                   case 7:
503                     if(rle_v3 != 0) 
504                       rle_v3 = 0;
505                     else {
506                       buf1--;
507                       rle_v3 = 1;
508                     }
509                   case 6:
510                     if(ref_vectors != NULL) {
511                       for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
512                         cur_lp[j] = ref_lp[j];
513                     }
514                     lp2 = 4;
515                     break;
516
517                   case 9:
518                     lv1 = *buf1++;
519                     lv = (lv1 & 0x7F) << 1;
520                     lv += (lv << 8);
521                     lv += (lv << 16);
522                     for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
523                       cur_lp[j] = lv;
524
525                     LV1_CHECK(buf1,rle_v3,lv1,lp2)
526                     break;
527                   default: 
528                     return;
529                 }
530               }
531
532               cur_frm_pos += 4;
533               ref_frm_pos += 4;
534             }
535
536             cur_frm_pos += ((width - blks_width) * 4);
537             ref_frm_pos += ((width - blks_width) * 4);
538           }
539           break;
540
541         case 4:
542         case 3:                    /********** CASE 3 **********/
543           if(ref_vectors != NULL) 
544             return;
545           flag1 = 1;
546
547           for( ; blks_height > 0; blks_height -= 8) {
548             for(lp1 = 0; lp1 < blks_width; lp1++) {
549               for(lp2 = 0; lp2 < 4; ) {
550                 k = *buf1++;
551
552                 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
553                 ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];
554
555                 switch(correction_type_sp[lp2 & 0x01][k]) {
556                   case 0:
557                     cur_lp[width_tbl[1]] = ((*ref_lp >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
558                     if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)
559                       cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
560                     else
561                       cur_lp[0] = ((*ref_lp >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
562                     lp2++;
563                     break;
564
565                   case 1:
566                     ((unsigned short *)cur_lp)[width_tbl[2]] =
567                       ((((unsigned short *)ref_lp)[0] >> 1) + correction_lp[lp2 & 0x01][*buf1++]) << 1;
568                     ((unsigned short *)cur_lp)[width_tbl[2]+1] =
569                       ((((unsigned short *)ref_lp)[1] >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
570                     if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)
571                       cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
572                     else
573                       cur_lp[0] = cur_lp[width_tbl[1]];
574                     lp2++;
575                     break;
576
577                   case 2:
578                     if(lp2 == 0) {
579                       for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
580                         cur_lp[j] = *ref_lp;
581                       lp2 += 2;
582                     }
583                     break;
584
585                   case 3:
586                     if(lp2 < 2) {
587                       for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])
588                         cur_lp[j] = *ref_lp;
589                       lp2 = 3;
590                     }
591                     break;
592
593                   case 6:
594                     lp2 = 4;
595                     break;
596
597                   case 7:
598                     if(rle_v3 != 0) 
599                       rle_v3 = 0;
600                     else {
601                       buf1--;
602                       rle_v3 = 1;
603                     }
604                     lp2 = 4;
605                     break;
606
607                   case 8:
608                     if(lp2 == 0) {
609                       RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
610
611                       if(rle_v1 == 1) {
612                         for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
613                           cur_lp[j] = ref_lp[j];
614                       }
615
616                       RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
617                       break;
618                     } else {
619                       rle_v2 = (*buf1) - 1;
620                       rle_v1 = 1;
621                     }
622                   case 5:
623                       LP2_CHECK(buf1,rle_v3,lp2)
624                   case 4:
625                     for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])
626                       cur_lp[j] = *ref_lp;
627                     lp2 = 4;
628                     break;
629
630                   case 9:
631                     av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
632                     lv1 = *buf1++;
633                     lv = (lv1 & 0x7F) << 1;
634                     lv += (lv << 8);
635                     lv += (lv << 16);
636
637                     for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
638                       cur_lp[j] = lv;
639
640                     LV1_CHECK(buf1,rle_v3,lv1,lp2)
641                     break;
642
643                   default: 
644                     return;
645                 }
646               }
647
648               cur_frm_pos += 4;
649             }
650
651             cur_frm_pos += (((width * 2) - blks_width) * 4);
652             flag1 = 0;
653           }
654           break;
655
656         case 10:                    /********** CASE 10 **********/
657           if(ref_vectors == NULL) {
658             flag1 = 1;
659
660             for( ; blks_height > 0; blks_height -= 8) {
661               for(lp1 = 0; lp1 < blks_width; lp1 += 2) {
662                 for(lp2 = 0; lp2 < 4; ) {
663                   k = *buf1++;
664                   cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
665                   ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];
666                   lv1 = ref_lp[0];
667                   lv2 = ref_lp[1];
668                   if(lp2 == 0 && flag1 != 0) {
669                     lv1 = lv1 & 0x00FF00FF;
670                     lv1 = (lv1 << 8) | lv1;
671                     lv2 = lv2 & 0x00FF00FF;
672                     lv2 = (lv2 << 8) | lv2;
673                   }
674
675                   switch(correction_type_sp[lp2 & 0x01][k]) {
676                     case 0:
677                       cur_lp[width_tbl[1]] = ((lv1 >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1;
678                       cur_lp[width_tbl[1]+1] = ((lv2 >> 1) + correctionhighorder_lp[lp2 & 0x01][k]) << 1;
679                       if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {
680                         cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
681                         cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
682                       } else {
683                         cur_lp[0] = cur_lp[width_tbl[1]];
684                         cur_lp[1] = cur_lp[width_tbl[1]+1];
685                       }
686                       lp2++;
687                       break;
688
689                     case 1:
690                       cur_lp[width_tbl[1]] = ((lv1 >> 1) + correctionloworder_lp[lp2 & 0x01][*buf1++]) << 1;
691                       cur_lp[width_tbl[1]+1] = ((lv2 >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1;
692                       if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {
693                         cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
694                         cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
695                       } else {
696                         cur_lp[0] = cur_lp[width_tbl[1]];
697                         cur_lp[1] = cur_lp[width_tbl[1]+1];
698                       }
699                       lp2++;
700                       break;
701
702                     case 2:
703                       if(lp2 == 0) {
704                         if(flag1 != 0) {
705                           for(i = 0, j = width_tbl[1]; i < 3; i++, j += width_tbl[1]) {
706                             cur_lp[j] = lv1;
707                             cur_lp[j+1] = lv2;
708                           }
709                           cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
710                           cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
711                         } else {
712                           for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {
713                             cur_lp[j] = lv1;
714                             cur_lp[j+1] = lv2;
715                           }
716                         }
717                         lp2 += 2;
718                       }
719                       break;
720
721                     case 3:
722                       if(lp2 < 2) {
723                         if(lp2 == 0 && flag1 != 0) {
724                           for(i = 0, j = width_tbl[1]; i < 5; i++, j += width_tbl[1]) {
725                             cur_lp[j] = lv1;
726                             cur_lp[j+1] = lv2;
727                           }
728                           cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
729                           cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
730                         } else {
731                           for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {
732                             cur_lp[j] = lv1;
733                             cur_lp[j+1] = lv2;
734                           }
735                         }
736                         lp2 = 3;
737                       }
738                       break;
739
740                     case 8:
741                       if(lp2 == 0) {
742                         RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
743                         if(rle_v1 == 1) {
744                           if(flag1 != 0) {
745                             for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {
746                               cur_lp[j] = lv1;
747                               cur_lp[j+1] = lv2;
748                             }
749                             cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
750                             cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
751                           } else {
752                             for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {
753                               cur_lp[j] = lv1;
754                               cur_lp[j+1] = lv2;
755                             }
756                           }
757                         }
758                         RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
759                         break;
760                       } else {
761                         rle_v1 = 1;
762                         rle_v2 = (*buf1) - 1;
763                       }
764                     case 5:
765                         LP2_CHECK(buf1,rle_v3,lp2)
766                     case 4:
767                       if(lp2 == 0 && flag1 != 0) {
768                         for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {
769                           cur_lp[j] = lv1;
770                           cur_lp[j+1] = lv2;
771                         }
772                         cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
773                         cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
774                       } else {
775                         for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {
776                           cur_lp[j] = lv1;
777                           cur_lp[j+1] = lv2;
778                         }
779                       }
780                       lp2 = 4;
781                       break;
782
783                     case 6:
784                       lp2 = 4;
785                       break;
786
787                     case 7:
788                       if(lp2 == 0) {
789                         if(rle_v3 != 0) 
790                           rle_v3 = 0;
791                         else {
792                           buf1--;
793                           rle_v3 = 1;
794                         }
795                         lp2 = 4;
796                       }
797                       break;
798
799                     case 9:
800                       av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
801                       lv1 = *buf1;
802                       lv = (lv1 & 0x7F) << 1;
803                       lv += (lv << 8);
804                       lv += (lv << 16);
805                       for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
806                         cur_lp[j] = lv;
807                       LV1_CHECK(buf1,rle_v3,lv1,lp2)
808                       break;
809
810                     default: 
811                       return;
812                   }
813                 }
814
815                 cur_frm_pos += 8;
816               }
817
818               cur_frm_pos += (((width * 2) - blks_width) * 4);
819               flag1 = 0;
820             }
821           } else {
822             for( ; blks_height > 0; blks_height -= 8) {
823               for(lp1 = 0; lp1 < blks_width; lp1 += 2) {
824                 for(lp2 = 0; lp2 < 4; ) {
825                   k = *buf1++;
826                   cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
827                   ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2];
828
829                   switch(correction_type_sp[lp2 & 0x01][k]) {
830                     case 0:
831                       lv1 = correctionloworder_lp[lp2 & 0x01][k];
832                       lv2 = correctionhighorder_lp[lp2 & 0x01][k];
833                       cur_lp[0] = ((ref_lp[0] >> 1) + lv1) << 1;
834                       cur_lp[1] = ((ref_lp[1] >> 1) + lv2) << 1;
835                       cur_lp[width_tbl[1]] = ((ref_lp[width_tbl[1]] >> 1) + lv1) << 1;
836                       cur_lp[width_tbl[1]+1] = ((ref_lp[width_tbl[1]+1] >> 1) + lv2) << 1;
837                       lp2++;
838                       break;
839
840                     case 1:
841                       lv1 = correctionloworder_lp[lp2 & 0x01][*buf1++];
842                       lv2 = correctionloworder_lp[lp2 & 0x01][k];
843                       cur_lp[0] = ((ref_lp[0] >> 1) + lv1) << 1;
844                       cur_lp[1] = ((ref_lp[1] >> 1) + lv2) << 1;
845                       cur_lp[width_tbl[1]] = ((ref_lp[width_tbl[1]] >> 1) + lv1) << 1;
846                       cur_lp[width_tbl[1]+1] = ((ref_lp[width_tbl[1]+1] >> 1) + lv2) << 1;
847                       lp2++;
848                       break;
849
850                     case 2:
851                       if(lp2 == 0) {
852                         for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {
853                           cur_lp[j] = ref_lp[j];
854                           cur_lp[j+1] = ref_lp[j+1];
855                         }
856                         lp2 += 2;
857                       }
858                       break;
859
860                     case 3:
861                       if(lp2 < 2) {
862                         for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {
863                           cur_lp[j] = ref_lp[j];
864                           cur_lp[j+1] = ref_lp[j+1];
865                         }
866                         lp2 = 3;
867                       }
868                       break;
869
870                     case 8:
871                       if(lp2 == 0) {
872                         RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
873                         for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {
874                           ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j];
875                           ((uint32_t *)cur_frm_pos)[j+1] = ((uint32_t *)ref_frm_pos)[j+1];
876                         }
877                         RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
878                         break;
879                       } else {
880                         rle_v1 = 1;
881                         rle_v2 = (*buf1) - 1;
882                       }
883                     case 5:
884                     case 7:
885                         LP2_CHECK(buf1,rle_v3,lp2)
886                     case 6:
887                     case 4:
888                       for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {
889                         cur_lp[j] = ref_lp[j];
890                         cur_lp[j+1] = ref_lp[j+1];
891                       }
892                       lp2 = 4;
893                       break;
894
895                     case 9:
896                       av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
897                       lv1 = *buf1;
898                       lv = (lv1 & 0x7F) << 1;
899                       lv += (lv << 8);
900                       lv += (lv << 16);
901                       for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
902                         ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)cur_frm_pos)[j+1] = lv;
903                       LV1_CHECK(buf1,rle_v3,lv1,lp2)
904                       break;
905
906                     default: 
907                       return;
908                   }
909                 }
910
911                 cur_frm_pos += 8;
912                 ref_frm_pos += 8;
913               }
914
915               cur_frm_pos += (((width * 2) - blks_width) * 4);
916               ref_frm_pos += (((width * 2) - blks_width) * 4);
917             }
918           }
919           break;
920
921         case 11:                    /********** CASE 11 **********/
922           if(ref_vectors == NULL) 
923             return;
924
925           for( ; blks_height > 0; blks_height -= 8) {
926             for(lp1 = 0; lp1 < blks_width; lp1++) {
927               for(lp2 = 0; lp2 < 4; ) {
928                 k = *buf1++;
929                 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
930                 ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2];
931
932                 switch(correction_type_sp[lp2 & 0x01][k]) {
933                   case 0:
934                     cur_lp[0] = ((*ref_lp >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
935                     cur_lp[width_tbl[1]] = ((ref_lp[width_tbl[1]] >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
936                     lp2++;
937                     break;
938
939                   case 1:
940                     lv1 = (unsigned short)(correction_lp[lp2 & 0x01][*buf1++]);
941                     lv2 = (unsigned short)(correction_lp[lp2 & 0x01][k]);
942                     ((unsigned short *)cur_lp)[0] = ((((unsigned short *)ref_lp)[0] >> 1) + lv1) << 1;
943                     ((unsigned short *)cur_lp)[1] = ((((unsigned short *)ref_lp)[1] >> 1) + lv2) << 1;
944                     ((unsigned short *)cur_lp)[width_tbl[2]] = ((((unsigned short *)ref_lp)[width_tbl[2]] >> 1) + lv1) << 1;
945                     ((unsigned short *)cur_lp)[width_tbl[2]+1] = ((((unsigned short *)ref_lp)[width_tbl[2]+1] >> 1) + lv2) << 1;
946                     lp2++;
947                     break;
948
949                   case 2:
950                     if(lp2 == 0) {
951                       for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
952                         cur_lp[j] = ref_lp[j];
953                       lp2 += 2;
954                     }
955                     break;
956
957                   case 3:
958                     if(lp2 < 2) {
959                       for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])
960                         cur_lp[j] = ref_lp[j];
961                       lp2 = 3;
962                     }
963                     break;
964
965                   case 8:
966                     if(lp2 == 0) {
967                       RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
968
969                       for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
970                         cur_lp[j] = ref_lp[j];
971
972                       RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
973                       break;
974                     } else {
975                       rle_v1 = 1;
976                       rle_v2 = (*buf1) - 1;
977                     }
978                   case 5:
979                   case 7:
980                       LP2_CHECK(buf1,rle_v3,lp2)
981                   case 4:
982                   case 6:
983                     for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])
984                       cur_lp[j] = ref_lp[j];
985                     lp2 = 4;
986                     break;
987
988                 case 9:
989                   av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
990                   lv1 = *buf1++;
991                   lv = (lv1 & 0x7F) << 1;
992                   lv += (lv << 8);
993                   lv += (lv << 16);
994                   for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
995                     cur_lp[j] = lv;
996                   LV1_CHECK(buf1,rle_v3,lv1,lp2)
997                   break;
998
999                   default: 
1000                     return;
1001                 }
1002               }
1003
1004               cur_frm_pos += 4;
1005               ref_frm_pos += 4;
1006             }
1007
1008             cur_frm_pos += (((width * 2) - blks_width) * 4);
1009             ref_frm_pos += (((width * 2) - blks_width) * 4);
1010           }
1011           break;
1012
1013         default: 
1014           return;
1015       }
1016     }
1017
1018     if(strip < strip_tbl) 
1019       return;
1020
1021     for( ; strip >= strip_tbl; strip--) {
1022       if(strip->split_flag != 0) {
1023         strip->split_flag = 0;
1024         strip->usl7 = (strip-1)->usl7;
1025
1026         if(strip->split_direction) {
1027           strip->xpos += strip->width;
1028           strip->width = (strip-1)->width - strip->width;
1029           if(region_160_width <= strip->xpos && width < strip->width + strip->xpos)
1030             strip->width = width - strip->xpos;
1031         } else {
1032           strip->ypos += strip->height;
1033           strip->height = (strip-1)->height - strip->height;
1034         }
1035         break;
1036       }
1037     }
1038   }
1039 }
1040
1041 static int indeo3_decode_init(AVCodecContext *avctx)
1042 {
1043     Indeo3DecodeContext *s = avctx->priv_data;
1044
1045     s->avctx = avctx;
1046     s->width = avctx->width;
1047     s->height = avctx->height;
1048     avctx->pix_fmt = PIX_FMT_YUV410P;
1049     avctx->has_b_frames = 0;
1050
1051     build_modpred(s);
1052     iv_alloc_frames(s);
1053
1054     return 0;
1055 }
1056
1057 static int indeo3_decode_frame(AVCodecContext *avctx,
1058                                void *data, int *data_size,
1059                                unsigned char *buf, int buf_size)
1060 {
1061     Indeo3DecodeContext *s=avctx->priv_data;
1062     unsigned char *src, *dest;
1063     int y;
1064
1065     /* no supplementary picture */
1066     if (buf_size == 0) {
1067         return 0;
1068     }
1069
1070     iv_decode_frame(s, buf, buf_size);
1071
1072     if(s->frame.data[0])
1073         avctx->release_buffer(avctx, &s->frame);
1074
1075     s->frame.reference = 0;
1076     if(avctx->get_buffer(avctx, &s->frame) < 0) {
1077         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
1078         return -1;
1079     }
1080
1081     src = s->cur_frame->Ybuf;
1082     dest = s->frame.data[0];
1083     for (y = 0; y < s->height; y++) {
1084       memcpy(dest, src, s->cur_frame->y_w);
1085       src += s->cur_frame->y_w;
1086       dest += s->frame.linesize[0];
1087     }
1088
1089     if (!(s->avctx->flags & CODEC_FLAG_GRAY))
1090     {
1091     src = s->cur_frame->Ubuf;
1092     dest = s->frame.data[1];
1093     for (y = 0; y < s->height / 4; y++) {
1094       memcpy(dest, src, s->cur_frame->uv_w);
1095       src += s->cur_frame->uv_w;
1096       dest += s->frame.linesize[1];
1097     }
1098
1099     src = s->cur_frame->Vbuf;
1100     dest = s->frame.data[2];
1101     for (y = 0; y < s->height / 4; y++) {
1102       memcpy(dest, src, s->cur_frame->uv_w);
1103       src += s->cur_frame->uv_w;
1104       dest += s->frame.linesize[2];
1105     }
1106     }
1107
1108     *data_size=sizeof(AVFrame);
1109     *(AVFrame*)data= s->frame;
1110
1111     return buf_size;
1112 }
1113
1114 static int indeo3_decode_end(AVCodecContext *avctx)
1115 {
1116     Indeo3DecodeContext *s = avctx->priv_data;
1117
1118     iv_free_func(s);
1119
1120     return 0;
1121 }
1122
1123 AVCodec indeo3_decoder = {
1124     "indeo3",
1125     CODEC_TYPE_VIDEO,
1126     CODEC_ID_INDEO3,
1127     sizeof(Indeo3DecodeContext),
1128     indeo3_decode_init,
1129     NULL,
1130     indeo3_decode_end,
1131     indeo3_decode_frame,
1132     0,
1133     NULL
1134 };