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