2 * Intel Indeo 3 (IV31, IV32, etc.) video decoder for ffmpeg
3 * written, produced, and directed by Alan Smithee
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "mpegvideo.h"
30 #include "bytestream.h"
32 #include "indeo3data.h"
39 unsigned char *the_buf
;
40 unsigned int the_buf_size
;
41 unsigned short y_w
, y_h
;
42 unsigned short uv_w
, uv_h
;
45 typedef struct Indeo3DecodeContext
{
46 AVCodecContext
*avctx
;
54 unsigned char *ModPred
;
55 unsigned short *corrector_type
;
56 } Indeo3DecodeContext
;
58 static const int corrector_type_0
[24] = {
59 195, 159, 133, 115, 101, 93, 87, 77,
60 195, 159, 133, 115, 101, 93, 87, 77,
61 128, 79, 79, 79, 79, 79, 79, 79
64 static const int corrector_type_2
[8] = { 9, 7, 6, 8, 5, 4, 3, 2 };
66 static void build_modpred(Indeo3DecodeContext
*s
)
70 s
->ModPred
= (unsigned char *) av_malloc (8 * 128);
72 for (i
=0; i
< 128; ++i
) {
73 s
->ModPred
[i
+0*128] = (i
> 126) ? 254 : 2*((i
+ 1) - ((i
+ 1) % 2));
74 s
->ModPred
[i
+1*128] = (i
== 7) ? 20 : ((i
== 119 || i
== 120)
75 ? 236 : 2*((i
+ 2) - ((i
+ 1) % 3)));
76 s
->ModPred
[i
+2*128] = (i
> 125) ? 248 : 2*((i
+ 2) - ((i
+ 2) % 4));
77 s
->ModPred
[i
+3*128] = 2*((i
+ 1) - ((i
- 3) % 5));
78 s
->ModPred
[i
+4*128] = (i
== 8) ? 20 : 2*((i
+ 1) - ((i
- 3) % 6));
79 s
->ModPred
[i
+5*128] = 2*((i
+ 4) - ((i
+ 3) % 7));
80 s
->ModPred
[i
+6*128] = (i
> 123) ? 240 : 2*((i
+ 4) - ((i
+ 4) % 8));
81 s
->ModPred
[i
+7*128] = 2*((i
+ 5) - ((i
+ 4) % 9));
84 s
->corrector_type
= (unsigned short *) av_malloc (24 * 256 * sizeof(unsigned short));
86 for (i
=0; i
< 24; ++i
) {
87 for (j
=0; j
< 256; ++j
) {
88 s
->corrector_type
[i
*256+j
] = (j
< corrector_type_0
[i
])
89 ? 1 : ((j
< 248 || (i
== 16 && j
== 248))
90 ? 0 : corrector_type_2
[j
- 248]);
95 static void iv_Decode_Chunk(Indeo3DecodeContext
*s
, unsigned char *cur
,
96 unsigned char *ref
, int width
, int height
, const unsigned char *buf1
,
97 long fflags2
, const unsigned char *hdr
,
98 const unsigned char *buf2
, int min_width_160
);
100 /* ---------------------------------------------------------------------- */
101 static void iv_alloc_frames(Indeo3DecodeContext
*s
)
103 int luma_width
, luma_height
, luma_pixels
, chroma_width
, chroma_height
,
105 unsigned int bufsize
;
107 luma_width
= (s
->width
+ 3) & (~3);
108 luma_height
= (s
->height
+ 3) & (~3);
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
;
116 chroma_width
= ((luma_width
>> 2) + 3) & (~3);
117 chroma_height
= ((luma_height
>> 2) + 3) & (~3);
118 luma_pixels
= luma_width
* luma_height
;
119 chroma_pixels
= chroma_width
* chroma_height
;
121 bufsize
= luma_pixels
* 2 + luma_width
* 3 +
122 (chroma_pixels
+ chroma_width
) * 4;
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
)
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
;
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
;
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;
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;
158 /* ---------------------------------------------------------------------- */
159 static void iv_free_func(Indeo3DecodeContext
*s
)
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;
175 av_free(s
->corrector_type
);
178 /* ---------------------------------------------------------------------- */
179 static unsigned long iv_decode_frame(Indeo3DecodeContext
*s
,
180 const unsigned char *buf
, int buf_size
)
182 unsigned int hdr_width
, hdr_height
,
183 chroma_width
, chroma_height
;
184 unsigned long fflags1
, fflags2
, fflags3
, offs1
, offs2
, offs3
, offs
;
185 const unsigned char *hdr_pos
, *buf_pos
;
190 fflags1
= bytestream_get_le16(&buf_pos
);
191 fflags3
= bytestream_get_le32(&buf_pos
);
192 fflags2
= *buf_pos
++;
194 hdr_height
= bytestream_get_le16(&buf_pos
);
195 hdr_width
= bytestream_get_le16(&buf_pos
);
197 if(avcodec_check_dimensions(NULL
, hdr_width
, hdr_height
))
200 chroma_height
= ((hdr_height
>> 2) + 3) & 0x7ffc;
201 chroma_width
= ((hdr_width
>> 2) + 3) & 0x7ffc;
202 offs1
= bytestream_get_le32(&buf_pos
);
203 offs2
= bytestream_get_le32(&buf_pos
);
204 offs3
= bytestream_get_le32(&buf_pos
);
207 if(fflags3
== 0x80) return 4;
209 if(fflags1
& 0x200) {
210 s
->cur_frame
= s
->iv_frame
+ 1;
211 s
->ref_frame
= s
->iv_frame
;
213 s
->cur_frame
= s
->iv_frame
;
214 s
->ref_frame
= s
->iv_frame
+ 1;
217 buf_pos
= buf
+ 16 + offs1
;
218 offs
= bytestream_get_le32(&buf_pos
);
220 iv_Decode_Chunk(s
, s
->cur_frame
->Ybuf
, s
->ref_frame
->Ybuf
, hdr_width
,
221 hdr_height
, buf_pos
+ offs
* 2, fflags2
, hdr_pos
, buf_pos
,
222 FFMIN(hdr_width
, 160));
224 if (!(s
->avctx
->flags
& CODEC_FLAG_GRAY
))
227 buf_pos
= buf
+ 16 + offs2
;
228 offs
= bytestream_get_le32(&buf_pos
);
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 FFMIN(chroma_width
, 40));
234 buf_pos
= buf
+ 16 + offs3
;
235 offs
= bytestream_get_le32(&buf_pos
);
237 iv_Decode_Chunk(s
, s
->cur_frame
->Ubuf
, s
->ref_frame
->Ubuf
, chroma_width
,
238 chroma_height
, buf_pos
+ offs
* 2, fflags2
, hdr_pos
, buf_pos
,
239 FFMIN(chroma_width
, 40));
252 long split_direction
;
256 /* ---------------------------------------------------------------------- */
258 #define LV1_CHECK(buf1,rle_v3,lv1,lp2) \
259 if((lv1 & 0x80) != 0) { \
270 #define RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) \
283 #define LP2_CHECK(buf1,rle_v3,lp2) \
284 if(lp2 == 0 && rle_v3 != 0) \
292 #define RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) \
300 static void iv_Decode_Chunk(Indeo3DecodeContext
*s
,
301 unsigned char *cur
, unsigned char *ref
, int width
, int height
,
302 const unsigned char *buf1
, long fflags2
, const unsigned char *hdr
,
303 const unsigned char *buf2
, int min_width_160
)
305 unsigned char bit_buf
;
306 unsigned long bit_pos
, lv
, lv1
, lv2
;
307 long *width_tbl
, width_tbl_arr
[10];
308 const signed char *ref_vectors
;
309 unsigned char *cur_frm_pos
, *ref_frm_pos
, *cp
, *cp2
;
310 uint32_t *cur_lp
, *ref_lp
;
311 const uint32_t *correction_lp
[2], *correctionloworder_lp
[2], *correctionhighorder_lp
[2];
312 unsigned short *correction_type_sp
[2];
313 ustr_t strip_tbl
[20], *strip
;
314 int i
, j
, k
, lp1
, lp2
, flag1
, cmd
, blks_width
, blks_height
, region_160_width
,
315 rle_v1
, rle_v2
, rle_v3
;
321 width_tbl
= width_tbl_arr
+ 1;
322 i
= (width
< 0 ? width
+ 3 : width
)/4;
323 for(j
= -1; j
< 8; j
++)
324 width_tbl
[j
] = i
* j
;
328 for(region_160_width
= 0; region_160_width
< (width
- min_width_160
); region_160_width
+= min_width_160
);
330 strip
->ypos
= strip
->xpos
= 0;
331 for(strip
->width
= min_width_160
; width
> strip
->width
; strip
->width
*= 2);
332 strip
->height
= height
;
333 strip
->split_direction
= 0;
334 strip
->split_flag
= 0;
339 rle_v1
= rle_v2
= rle_v3
= 0;
341 while(strip
>= strip_tbl
) {
348 cmd
= (bit_buf
>> bit_pos
) & 0x03;
352 memcpy(strip
, strip
-1, sizeof(ustr_t
));
353 strip
->split_flag
= 1;
354 strip
->split_direction
= 0;
355 strip
->height
= (strip
->height
> 8 ? ((strip
->height
+8)>>4)<<3 : 4);
357 } else if(cmd
== 1) {
359 memcpy(strip
, strip
-1, sizeof(ustr_t
));
360 strip
->split_flag
= 1;
361 strip
->split_direction
= 1;
362 strip
->width
= (strip
->width
> 8 ? ((strip
->width
+8)>>4)<<3 : 4);
364 } else if(cmd
== 2) {
365 if(strip
->usl7
== 0) {
370 } else if(cmd
== 3) {
371 if(strip
->usl7
== 0) {
373 ref_vectors
= (const signed char*)buf2
+ (*buf1
* 2);
379 cur_frm_pos
= cur
+ width
* strip
->ypos
+ strip
->xpos
;
381 if((blks_width
= strip
->width
) < 0)
384 blks_height
= strip
->height
;
386 if(ref_vectors
!= NULL
) {
387 ref_frm_pos
= ref
+ (ref_vectors
[0] + strip
->ypos
) * width
+
388 ref_vectors
[1] + strip
->xpos
;
390 ref_frm_pos
= cur_frm_pos
- width_tbl
[4];
399 cmd
= (bit_buf
>> bit_pos
) & 0x03;
401 if(cmd
== 0 || ref_vectors
!= NULL
) {
402 for(lp1
= 0; lp1
< blks_width
; lp1
++) {
403 for(i
= 0, j
= 0; i
< blks_height
; i
++, j
+= width_tbl
[1])
404 ((uint32_t *)cur_frm_pos
)[j
] = ((uint32_t *)ref_frm_pos
)[j
];
416 if((lv
- 8) <= 7 && (k
== 0 || k
== 3 || k
== 10)) {
417 cp2
= s
->ModPred
+ ((lv
- 8) << 7);
419 for(i
= 0; i
< blks_width
<< 2; i
++) {
425 if(k
== 1 || k
== 4) {
426 lv
= (hdr
[j
] & 0xf) + fflags2
;
427 correction_type_sp
[0] = s
->corrector_type
+ (lv
<< 8);
428 correction_lp
[0] = correction
+ (lv
<< 8);
429 lv
= (hdr
[j
] >> 4) + fflags2
;
430 correction_lp
[1] = correction
+ (lv
<< 8);
431 correction_type_sp
[1] = s
->corrector_type
+ (lv
<< 8);
433 correctionloworder_lp
[0] = correctionloworder_lp
[1] = correctionloworder
+ (lv
<< 8);
434 correctionhighorder_lp
[0] = correctionhighorder_lp
[1] = correctionhighorder
+ (lv
<< 8);
435 correction_type_sp
[0] = correction_type_sp
[1] = s
->corrector_type
+ (lv
<< 8);
436 correction_lp
[0] = correction_lp
[1] = correction
+ (lv
<< 8);
441 case 0: /********** CASE 0 **********/
442 for( ; blks_height
> 0; blks_height
-= 4) {
443 for(lp1
= 0; lp1
< blks_width
; lp1
++) {
444 for(lp2
= 0; lp2
< 4; ) {
446 cur_lp
= ((uint32_t *)cur_frm_pos
) + width_tbl
[lp2
];
447 ref_lp
= ((uint32_t *)ref_frm_pos
) + width_tbl
[lp2
];
449 switch(correction_type_sp
[0][k
]) {
451 *cur_lp
= le2me_32(((le2me_32(*ref_lp
) >> 1) + correction_lp
[lp2
& 0x01][k
]) << 1);
455 res
= ((le2me_16(((unsigned short *)(ref_lp
))[0]) >> 1) + correction_lp
[lp2
& 0x01][*buf1
]) << 1;
456 ((unsigned short *)cur_lp
)[0] = le2me_16(res
);
457 res
= ((le2me_16(((unsigned short *)(ref_lp
))[1]) >> 1) + correction_lp
[lp2
& 0x01][k
]) << 1;
458 ((unsigned short *)cur_lp
)[1] = le2me_16(res
);
464 for(i
= 0, j
= 0; i
< 2; i
++, j
+= width_tbl
[1])
465 cur_lp
[j
] = ref_lp
[j
];
471 for(i
= 0, j
= 0; i
< (3 - lp2
); i
++, j
+= width_tbl
[1])
472 cur_lp
[j
] = ref_lp
[j
];
478 RLE_V3_CHECK(buf1
,rle_v1
,rle_v2
,rle_v3
)
480 if(rle_v1
== 1 || ref_vectors
!= NULL
) {
481 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1])
482 cur_lp
[j
] = ref_lp
[j
];
485 RLE_V2_CHECK(buf1
,rle_v2
, rle_v3
,lp2
)
492 LP2_CHECK(buf1
,rle_v3
,lp2
)
494 for(i
= 0, j
= 0; i
< (4 - lp2
); i
++, j
+= width_tbl
[1])
495 cur_lp
[j
] = ref_lp
[j
];
507 if(ref_vectors
!= NULL
) {
508 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1])
509 cur_lp
[j
] = ref_lp
[j
];
516 lv
= (lv1
& 0x7F) << 1;
519 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1])
522 LV1_CHECK(buf1
,rle_v3
,lv1
,lp2
)
533 cur_frm_pos
+= ((width
- blks_width
) * 4);
534 ref_frm_pos
+= ((width
- blks_width
) * 4);
539 case 3: /********** CASE 3 **********/
540 if(ref_vectors
!= NULL
)
544 for( ; blks_height
> 0; blks_height
-= 8) {
545 for(lp1
= 0; lp1
< blks_width
; lp1
++) {
546 for(lp2
= 0; lp2
< 4; ) {
549 cur_lp
= ((uint32_t *)cur_frm_pos
) + width_tbl
[lp2
* 2];
550 ref_lp
= ((uint32_t *)cur_frm_pos
) + width_tbl
[(lp2
* 2) - 1];
552 switch(correction_type_sp
[lp2
& 0x01][k
]) {
554 cur_lp
[width_tbl
[1]] = le2me_32(((le2me_32(*ref_lp
) >> 1) + correction_lp
[lp2
& 0x01][k
]) << 1);
555 if(lp2
> 0 || flag1
== 0 || strip
->ypos
!= 0)
556 cur_lp
[0] = ((cur_lp
[-width_tbl
[1]] >> 1) + (cur_lp
[width_tbl
[1]] >> 1)) & 0xFEFEFEFE;
558 cur_lp
[0] = le2me_32(((le2me_32(*ref_lp
) >> 1) + correction_lp
[lp2
& 0x01][k
]) << 1);
563 res
= ((le2me_16(((unsigned short *)ref_lp
)[0]) >> 1) + correction_lp
[lp2
& 0x01][*buf1
]) << 1;
564 ((unsigned short *)cur_lp
)[width_tbl
[2]] = le2me_16(res
);
565 res
= ((le2me_16(((unsigned short *)ref_lp
)[1]) >> 1) + correction_lp
[lp2
& 0x01][k
]) << 1;
566 ((unsigned short *)cur_lp
)[width_tbl
[2]+1] = le2me_16(res
);
568 if(lp2
> 0 || flag1
== 0 || strip
->ypos
!= 0)
569 cur_lp
[0] = ((cur_lp
[-width_tbl
[1]] >> 1) + (cur_lp
[width_tbl
[1]] >> 1)) & 0xFEFEFEFE;
571 cur_lp
[0] = cur_lp
[width_tbl
[1]];
578 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1])
586 for(i
= 0, j
= 0; i
< 6 - (lp2
* 2); i
++, j
+= width_tbl
[1])
608 RLE_V3_CHECK(buf1
,rle_v1
,rle_v2
,rle_v3
)
611 for(i
= 0, j
= 0; i
< 8; i
++, j
+= width_tbl
[1])
612 cur_lp
[j
] = ref_lp
[j
];
615 RLE_V2_CHECK(buf1
,rle_v2
, rle_v3
,lp2
)
618 rle_v2
= (*buf1
) - 1;
622 LP2_CHECK(buf1
,rle_v3
,lp2
)
624 for(i
= 0, j
= 0; i
< 8 - (lp2
* 2); i
++, j
+= width_tbl
[1])
630 av_log(s
->avctx
, AV_LOG_ERROR
, "UNTESTED.\n");
632 lv
= (lv1
& 0x7F) << 1;
636 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1])
639 LV1_CHECK(buf1
,rle_v3
,lv1
,lp2
)
650 cur_frm_pos
+= (((width
* 2) - blks_width
) * 4);
655 case 10: /********** CASE 10 **********/
656 if(ref_vectors
== NULL
) {
659 for( ; blks_height
> 0; blks_height
-= 8) {
660 for(lp1
= 0; lp1
< blks_width
; lp1
+= 2) {
661 for(lp2
= 0; lp2
< 4; ) {
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];
667 if(lp2
== 0 && flag1
!= 0) {
668 #ifdef WORDS_BIGENDIAN
669 lv1
= lv1
& 0xFF00FF00;
670 lv1
= (lv1
>> 8) | lv1
;
671 lv2
= lv2
& 0xFF00FF00;
672 lv2
= (lv2
>> 8) | lv2
;
674 lv1
= lv1
& 0x00FF00FF;
675 lv1
= (lv1
<< 8) | lv1
;
676 lv2
= lv2
& 0x00FF00FF;
677 lv2
= (lv2
<< 8) | lv2
;
681 switch(correction_type_sp
[lp2
& 0x01][k
]) {
683 cur_lp
[width_tbl
[1]] = le2me_32(((le2me_32(lv1
) >> 1) + correctionloworder_lp
[lp2
& 0x01][k
]) << 1);
684 cur_lp
[width_tbl
[1]+1] = le2me_32(((le2me_32(lv2
) >> 1) + correctionhighorder_lp
[lp2
& 0x01][k
]) << 1);
685 if(lp2
> 0 || strip
->ypos
!= 0 || flag1
== 0) {
686 cur_lp
[0] = ((cur_lp
[-width_tbl
[1]] >> 1) + (cur_lp
[width_tbl
[1]] >> 1)) & 0xFEFEFEFE;
687 cur_lp
[1] = ((cur_lp
[-width_tbl
[1]+1] >> 1) + (cur_lp
[width_tbl
[1]+1] >> 1)) & 0xFEFEFEFE;
689 cur_lp
[0] = cur_lp
[width_tbl
[1]];
690 cur_lp
[1] = cur_lp
[width_tbl
[1]+1];
696 cur_lp
[width_tbl
[1]] = le2me_32(((le2me_32(lv1
) >> 1) + correctionloworder_lp
[lp2
& 0x01][*buf1
]) << 1);
697 cur_lp
[width_tbl
[1]+1] = le2me_32(((le2me_32(lv2
) >> 1) + correctionloworder_lp
[lp2
& 0x01][k
]) << 1);
698 if(lp2
> 0 || strip
->ypos
!= 0 || flag1
== 0) {
699 cur_lp
[0] = ((cur_lp
[-width_tbl
[1]] >> 1) + (cur_lp
[width_tbl
[1]] >> 1)) & 0xFEFEFEFE;
700 cur_lp
[1] = ((cur_lp
[-width_tbl
[1]+1] >> 1) + (cur_lp
[width_tbl
[1]+1] >> 1)) & 0xFEFEFEFE;
702 cur_lp
[0] = cur_lp
[width_tbl
[1]];
703 cur_lp
[1] = cur_lp
[width_tbl
[1]+1];
712 for(i
= 0, j
= width_tbl
[1]; i
< 3; i
++, j
+= width_tbl
[1]) {
716 cur_lp
[0] = ((cur_lp
[-width_tbl
[1]] >> 1) + (cur_lp
[width_tbl
[1]] >> 1)) & 0xFEFEFEFE;
717 cur_lp
[1] = ((cur_lp
[-width_tbl
[1]+1] >> 1) + (cur_lp
[width_tbl
[1]+1] >> 1)) & 0xFEFEFEFE;
719 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1]) {
730 if(lp2
== 0 && flag1
!= 0) {
731 for(i
= 0, j
= width_tbl
[1]; i
< 5; i
++, j
+= width_tbl
[1]) {
735 cur_lp
[0] = ((cur_lp
[-width_tbl
[1]] >> 1) + (cur_lp
[width_tbl
[1]] >> 1)) & 0xFEFEFEFE;
736 cur_lp
[1] = ((cur_lp
[-width_tbl
[1]+1] >> 1) + (cur_lp
[width_tbl
[1]+1] >> 1)) & 0xFEFEFEFE;
738 for(i
= 0, j
= 0; i
< 6 - (lp2
* 2); i
++, j
+= width_tbl
[1]) {
749 RLE_V3_CHECK(buf1
,rle_v1
,rle_v2
,rle_v3
)
752 for(i
= 0, j
= width_tbl
[1]; i
< 7; i
++, j
+= width_tbl
[1]) {
756 cur_lp
[0] = ((cur_lp
[-width_tbl
[1]] >> 1) + (cur_lp
[width_tbl
[1]] >> 1)) & 0xFEFEFEFE;
757 cur_lp
[1] = ((cur_lp
[-width_tbl
[1]+1] >> 1) + (cur_lp
[width_tbl
[1]+1] >> 1)) & 0xFEFEFEFE;
759 for(i
= 0, j
= 0; i
< 8; i
++, j
+= width_tbl
[1]) {
765 RLE_V2_CHECK(buf1
,rle_v2
, rle_v3
,lp2
)
769 rle_v2
= (*buf1
) - 1;
772 LP2_CHECK(buf1
,rle_v3
,lp2
)
774 if(lp2
== 0 && flag1
!= 0) {
775 for(i
= 0, j
= width_tbl
[1]; i
< 7; i
++, j
+= width_tbl
[1]) {
779 cur_lp
[0] = ((cur_lp
[-width_tbl
[1]] >> 1) + (cur_lp
[width_tbl
[1]] >> 1)) & 0xFEFEFEFE;
780 cur_lp
[1] = ((cur_lp
[-width_tbl
[1]+1] >> 1) + (cur_lp
[width_tbl
[1]+1] >> 1)) & 0xFEFEFEFE;
782 for(i
= 0, j
= 0; i
< 8 - (lp2
* 2); i
++, j
+= width_tbl
[1]) {
807 av_log(s
->avctx
, AV_LOG_ERROR
, "UNTESTED.\n");
809 lv
= (lv1
& 0x7F) << 1;
812 for(i
= 0, j
= 0; i
< 8; i
++, j
+= width_tbl
[1])
814 LV1_CHECK(buf1
,rle_v3
,lv1
,lp2
)
825 cur_frm_pos
+= (((width
* 2) - blks_width
) * 4);
829 for( ; blks_height
> 0; blks_height
-= 8) {
830 for(lp1
= 0; lp1
< blks_width
; lp1
+= 2) {
831 for(lp2
= 0; lp2
< 4; ) {
833 cur_lp
= ((uint32_t *)cur_frm_pos
) + width_tbl
[lp2
* 2];
834 ref_lp
= ((uint32_t *)ref_frm_pos
) + width_tbl
[lp2
* 2];
836 switch(correction_type_sp
[lp2
& 0x01][k
]) {
838 lv1
= correctionloworder_lp
[lp2
& 0x01][k
];
839 lv2
= correctionhighorder_lp
[lp2
& 0x01][k
];
840 cur_lp
[0] = le2me_32(((le2me_32(ref_lp
[0]) >> 1) + lv1
) << 1);
841 cur_lp
[1] = le2me_32(((le2me_32(ref_lp
[1]) >> 1) + lv2
) << 1);
842 cur_lp
[width_tbl
[1]] = le2me_32(((le2me_32(ref_lp
[width_tbl
[1]]) >> 1) + lv1
) << 1);
843 cur_lp
[width_tbl
[1]+1] = le2me_32(((le2me_32(ref_lp
[width_tbl
[1]+1]) >> 1) + lv2
) << 1);
848 lv1
= correctionloworder_lp
[lp2
& 0x01][*buf1
++];
849 lv2
= correctionloworder_lp
[lp2
& 0x01][k
];
850 cur_lp
[0] = le2me_32(((le2me_32(ref_lp
[0]) >> 1) + lv1
) << 1);
851 cur_lp
[1] = le2me_32(((le2me_32(ref_lp
[1]) >> 1) + lv2
) << 1);
852 cur_lp
[width_tbl
[1]] = le2me_32(((le2me_32(ref_lp
[width_tbl
[1]]) >> 1) + lv1
) << 1);
853 cur_lp
[width_tbl
[1]+1] = le2me_32(((le2me_32(ref_lp
[width_tbl
[1]+1]) >> 1) + lv2
) << 1);
859 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1]) {
860 cur_lp
[j
] = ref_lp
[j
];
861 cur_lp
[j
+1] = ref_lp
[j
+1];
869 for(i
= 0, j
= 0; i
< 6 - (lp2
* 2); i
++, j
+= width_tbl
[1]) {
870 cur_lp
[j
] = ref_lp
[j
];
871 cur_lp
[j
+1] = ref_lp
[j
+1];
879 RLE_V3_CHECK(buf1
,rle_v1
,rle_v2
,rle_v3
)
880 for(i
= 0, j
= 0; i
< 8; i
++, j
+= width_tbl
[1]) {
881 ((uint32_t *)cur_frm_pos
)[j
] = ((uint32_t *)ref_frm_pos
)[j
];
882 ((uint32_t *)cur_frm_pos
)[j
+1] = ((uint32_t *)ref_frm_pos
)[j
+1];
884 RLE_V2_CHECK(buf1
,rle_v2
, rle_v3
,lp2
)
888 rle_v2
= (*buf1
) - 1;
892 LP2_CHECK(buf1
,rle_v3
,lp2
)
895 for(i
= 0, j
= 0; i
< 8 - (lp2
* 2); i
++, j
+= width_tbl
[1]) {
896 cur_lp
[j
] = ref_lp
[j
];
897 cur_lp
[j
+1] = ref_lp
[j
+1];
903 av_log(s
->avctx
, AV_LOG_ERROR
, "UNTESTED.\n");
905 lv
= (lv1
& 0x7F) << 1;
908 for(i
= 0, j
= 0; i
< 8; i
++, j
+= width_tbl
[1])
909 ((uint32_t *)cur_frm_pos
)[j
] = ((uint32_t *)cur_frm_pos
)[j
+1] = lv
;
910 LV1_CHECK(buf1
,rle_v3
,lv1
,lp2
)
922 cur_frm_pos
+= (((width
* 2) - blks_width
) * 4);
923 ref_frm_pos
+= (((width
* 2) - blks_width
) * 4);
928 case 11: /********** CASE 11 **********/
929 if(ref_vectors
== NULL
)
932 for( ; blks_height
> 0; blks_height
-= 8) {
933 for(lp1
= 0; lp1
< blks_width
; lp1
++) {
934 for(lp2
= 0; lp2
< 4; ) {
936 cur_lp
= ((uint32_t *)cur_frm_pos
) + width_tbl
[lp2
* 2];
937 ref_lp
= ((uint32_t *)ref_frm_pos
) + width_tbl
[lp2
* 2];
939 switch(correction_type_sp
[lp2
& 0x01][k
]) {
941 cur_lp
[0] = le2me_32(((le2me_32(*ref_lp
) >> 1) + correction_lp
[lp2
& 0x01][k
]) << 1);
942 cur_lp
[width_tbl
[1]] = le2me_32(((le2me_32(ref_lp
[width_tbl
[1]]) >> 1) + correction_lp
[lp2
& 0x01][k
]) << 1);
947 lv1
= (unsigned short)(correction_lp
[lp2
& 0x01][*buf1
++]);
948 lv2
= (unsigned short)(correction_lp
[lp2
& 0x01][k
]);
949 res
= (unsigned short)(((le2me_16(((unsigned short *)ref_lp
)[0]) >> 1) + lv1
) << 1);
950 ((unsigned short *)cur_lp
)[0] = le2me_16(res
);
951 res
= (unsigned short)(((le2me_16(((unsigned short *)ref_lp
)[1]) >> 1) + lv2
) << 1);
952 ((unsigned short *)cur_lp
)[1] = le2me_16(res
);
953 res
= (unsigned short)(((le2me_16(((unsigned short *)ref_lp
)[width_tbl
[2]]) >> 1) + lv1
) << 1);
954 ((unsigned short *)cur_lp
)[width_tbl
[2]] = le2me_16(res
);
955 res
= (unsigned short)(((le2me_16(((unsigned short *)ref_lp
)[width_tbl
[2]+1]) >> 1) + lv2
) << 1);
956 ((unsigned short *)cur_lp
)[width_tbl
[2]+1] = le2me_16(res
);
962 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1])
963 cur_lp
[j
] = ref_lp
[j
];
970 for(i
= 0, j
= 0; i
< 6 - (lp2
* 2); i
++, j
+= width_tbl
[1])
971 cur_lp
[j
] = ref_lp
[j
];
978 RLE_V3_CHECK(buf1
,rle_v1
,rle_v2
,rle_v3
)
980 for(i
= 0, j
= 0; i
< 8; i
++, j
+= width_tbl
[1])
981 cur_lp
[j
] = ref_lp
[j
];
983 RLE_V2_CHECK(buf1
,rle_v2
, rle_v3
,lp2
)
987 rle_v2
= (*buf1
) - 1;
991 LP2_CHECK(buf1
,rle_v3
,lp2
)
994 for(i
= 0, j
= 0; i
< 8 - (lp2
* 2); i
++, j
+= width_tbl
[1])
995 cur_lp
[j
] = ref_lp
[j
];
1000 av_log(s
->avctx
, AV_LOG_ERROR
, "UNTESTED.\n");
1002 lv
= (lv1
& 0x7F) << 1;
1005 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1])
1007 LV1_CHECK(buf1
,rle_v3
,lv1
,lp2
)
1019 cur_frm_pos
+= (((width
* 2) - blks_width
) * 4);
1020 ref_frm_pos
+= (((width
* 2) - blks_width
) * 4);
1029 if(strip
< strip_tbl
)
1032 for( ; strip
>= strip_tbl
; strip
--) {
1033 if(strip
->split_flag
!= 0) {
1034 strip
->split_flag
= 0;
1035 strip
->usl7
= (strip
-1)->usl7
;
1037 if(strip
->split_direction
) {
1038 strip
->xpos
+= strip
->width
;
1039 strip
->width
= (strip
-1)->width
- strip
->width
;
1040 if(region_160_width
<= strip
->xpos
&& width
< strip
->width
+ strip
->xpos
)
1041 strip
->width
= width
- strip
->xpos
;
1043 strip
->ypos
+= strip
->height
;
1044 strip
->height
= (strip
-1)->height
- strip
->height
;
1052 static int indeo3_decode_init(AVCodecContext
*avctx
)
1054 Indeo3DecodeContext
*s
= avctx
->priv_data
;
1057 s
->width
= avctx
->width
;
1058 s
->height
= avctx
->height
;
1059 avctx
->pix_fmt
= PIX_FMT_YUV410P
;
1067 static int indeo3_decode_frame(AVCodecContext
*avctx
,
1068 void *data
, int *data_size
,
1069 const unsigned char *buf
, int buf_size
)
1071 Indeo3DecodeContext
*s
=avctx
->priv_data
;
1072 unsigned char *src
, *dest
;
1075 iv_decode_frame(s
, buf
, buf_size
);
1077 if(s
->frame
.data
[0])
1078 avctx
->release_buffer(avctx
, &s
->frame
);
1080 s
->frame
.reference
= 0;
1081 if(avctx
->get_buffer(avctx
, &s
->frame
) < 0) {
1082 av_log(s
->avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
1086 src
= s
->cur_frame
->Ybuf
;
1087 dest
= s
->frame
.data
[0];
1088 for (y
= 0; y
< s
->height
; y
++) {
1089 memcpy(dest
, src
, s
->cur_frame
->y_w
);
1090 src
+= s
->cur_frame
->y_w
;
1091 dest
+= s
->frame
.linesize
[0];
1094 if (!(s
->avctx
->flags
& CODEC_FLAG_GRAY
))
1096 src
= s
->cur_frame
->Ubuf
;
1097 dest
= s
->frame
.data
[1];
1098 for (y
= 0; y
< s
->height
/ 4; y
++) {
1099 memcpy(dest
, src
, s
->cur_frame
->uv_w
);
1100 src
+= s
->cur_frame
->uv_w
;
1101 dest
+= s
->frame
.linesize
[1];
1104 src
= s
->cur_frame
->Vbuf
;
1105 dest
= s
->frame
.data
[2];
1106 for (y
= 0; y
< s
->height
/ 4; y
++) {
1107 memcpy(dest
, src
, s
->cur_frame
->uv_w
);
1108 src
+= s
->cur_frame
->uv_w
;
1109 dest
+= s
->frame
.linesize
[2];
1113 *data_size
=sizeof(AVFrame
);
1114 *(AVFrame
*)data
= s
->frame
;
1119 static int indeo3_decode_end(AVCodecContext
*avctx
)
1121 Indeo3DecodeContext
*s
= avctx
->priv_data
;
1128 AVCodec indeo3_decoder
= {
1132 sizeof(Indeo3DecodeContext
),
1136 indeo3_decode_frame
,