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