OSDN Git Service

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