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 "bytestream.h"
31 #include "indeo3data.h"
38 unsigned short y_w
, y_h
;
39 unsigned short uv_w
, uv_h
;
42 typedef struct Indeo3DecodeContext
{
43 AVCodecContext
*avctx
;
53 uint8_t *corrector_type
;
54 } Indeo3DecodeContext
;
56 static const uint8_t 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
62 static const uint8_t corrector_type_2
[8] = { 9, 7, 6, 8, 5, 4, 3, 2 };
64 static av_cold
int build_modpred(Indeo3DecodeContext
*s
)
68 if (!(s
->ModPred
= av_malloc(8 * 128)))
69 return AVERROR(ENOMEM
);
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 :
75 i
== 120 ? 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 if (!(s
->corrector_type
= av_malloc(24 * 256)))
85 return AVERROR(ENOMEM
);
87 for (i
=0; i
< 24; ++i
) {
88 for (j
=0; j
< 256; ++j
) {
89 s
->corrector_type
[i
*256+j
] = j
< corrector_type_0
[i
] ? 1 :
90 j
< 248 || (i
== 16 && j
== 248) ? 0 :
91 corrector_type_2
[j
- 248];
98 static av_cold
int iv_alloc_frames(Indeo3DecodeContext
*s
)
100 int luma_width
= (s
->width
+ 3) & ~3,
101 luma_height
= (s
->height
+ 3) & ~3,
102 chroma_width
= ((luma_width
>> 2) + 3) & ~3,
103 chroma_height
= ((luma_height
>> 2) + 3) & ~3,
104 luma_pixels
= luma_width
* luma_height
,
105 chroma_pixels
= chroma_width
* chroma_height
,
107 unsigned int bufsize
= luma_pixels
* 2 + luma_width
* 3 +
108 (chroma_pixels
+ chroma_width
) * 4;
110 if(!(s
->buf
= av_malloc(bufsize
)))
111 return AVERROR(ENOMEM
);
112 s
->iv_frame
[0].y_w
= s
->iv_frame
[1].y_w
= luma_width
;
113 s
->iv_frame
[0].y_h
= s
->iv_frame
[1].y_h
= luma_height
;
114 s
->iv_frame
[0].uv_w
= s
->iv_frame
[1].uv_w
= chroma_width
;
115 s
->iv_frame
[0].uv_h
= s
->iv_frame
[1].uv_h
= chroma_height
;
117 s
->iv_frame
[0].Ybuf
= s
->buf
+ luma_width
;
118 i
= luma_pixels
+ luma_width
* 2;
119 s
->iv_frame
[1].Ybuf
= s
->buf
+ i
;
120 i
+= (luma_pixels
+ luma_width
);
121 s
->iv_frame
[0].Ubuf
= s
->buf
+ i
;
122 i
+= (chroma_pixels
+ chroma_width
);
123 s
->iv_frame
[1].Ubuf
= s
->buf
+ i
;
124 i
+= (chroma_pixels
+ chroma_width
);
125 s
->iv_frame
[0].Vbuf
= s
->buf
+ i
;
126 i
+= (chroma_pixels
+ chroma_width
);
127 s
->iv_frame
[1].Vbuf
= s
->buf
+ i
;
129 for(i
= 1; i
<= luma_width
; i
++)
130 s
->iv_frame
[0].Ybuf
[-i
] = s
->iv_frame
[1].Ybuf
[-i
] =
131 s
->iv_frame
[0].Ubuf
[-i
] = 0x80;
133 for(i
= 1; i
<= chroma_width
; i
++) {
134 s
->iv_frame
[1].Ubuf
[-i
] = 0x80;
135 s
->iv_frame
[0].Vbuf
[-i
] = 0x80;
136 s
->iv_frame
[1].Vbuf
[-i
] = 0x80;
137 s
->iv_frame
[1].Vbuf
[chroma_pixels
+i
-1] = 0x80;
143 static av_cold
void iv_free_func(Indeo3DecodeContext
*s
)
147 av_free(s
->corrector_type
);
156 long split_direction
;
161 #define LV1_CHECK(buf1,rle_v3,lv1,lp2) \
162 if((lv1 & 0x80) != 0) { \
173 #define RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) \
186 #define LP2_CHECK(buf1,rle_v3,lp2) \
187 if(lp2 == 0 && rle_v3 != 0) \
195 #define RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) \
203 static void iv_Decode_Chunk(Indeo3DecodeContext
*s
,
204 uint8_t *cur
, uint8_t *ref
, int width
, int height
,
205 const uint8_t *buf1
, long cb_offset
, const uint8_t *hdr
,
206 const uint8_t *buf2
, int min_width_160
)
209 unsigned long bit_pos
, lv
, lv1
, lv2
;
210 long *width_tbl
, width_tbl_arr
[10];
211 const signed char *ref_vectors
;
212 uint8_t *cur_frm_pos
, *ref_frm_pos
, *cp
, *cp2
;
213 uint32_t *cur_lp
, *ref_lp
;
214 const uint32_t *correction_lp
[2], *correctionloworder_lp
[2], *correctionhighorder_lp
[2];
215 uint8_t *correction_type_sp
[2];
216 struct ustr strip_tbl
[20], *strip
;
217 int i
, j
, k
, lp1
, lp2
, flag1
, cmd
, blks_width
, blks_height
, region_160_width
,
218 rle_v1
, rle_v2
, rle_v3
;
224 width_tbl
= width_tbl_arr
+ 1;
225 i
= (width
< 0 ? width
+ 3 : width
)/4;
226 for(j
= -1; j
< 8; j
++)
227 width_tbl
[j
] = i
* j
;
231 for(region_160_width
= 0; region_160_width
< (width
- min_width_160
); region_160_width
+= min_width_160
);
233 strip
->ypos
= strip
->xpos
= 0;
234 for(strip
->width
= min_width_160
; width
> strip
->width
; strip
->width
*= 2);
235 strip
->height
= height
;
236 strip
->split_direction
= 0;
237 strip
->split_flag
= 0;
242 rle_v1
= rle_v2
= rle_v3
= 0;
244 while(strip
>= strip_tbl
) {
251 cmd
= (bit_buf
>> bit_pos
) & 0x03;
255 if(strip
>= strip_tbl
+ FF_ARRAY_ELEMS(strip_tbl
)) {
256 av_log(s
->avctx
, AV_LOG_WARNING
, "out of range strip\n");
259 memcpy(strip
, strip
-1, sizeof(*strip
));
260 strip
->split_flag
= 1;
261 strip
->split_direction
= 0;
262 strip
->height
= (strip
->height
> 8 ? ((strip
->height
+8)>>4)<<3 : 4);
264 } else if(cmd
== 1) {
266 if(strip
>= strip_tbl
+ FF_ARRAY_ELEMS(strip_tbl
)) {
267 av_log(s
->avctx
, AV_LOG_WARNING
, "out of range strip\n");
270 memcpy(strip
, strip
-1, sizeof(*strip
));
271 strip
->split_flag
= 1;
272 strip
->split_direction
= 1;
273 strip
->width
= (strip
->width
> 8 ? ((strip
->width
+8)>>4)<<3 : 4);
275 } else if(cmd
== 2) {
276 if(strip
->usl7
== 0) {
281 } else if(cmd
== 3) {
282 if(strip
->usl7
== 0) {
284 ref_vectors
= (const signed char*)buf2
+ (*buf1
* 2);
290 cur_frm_pos
= cur
+ width
* strip
->ypos
+ strip
->xpos
;
292 if((blks_width
= strip
->width
) < 0)
295 blks_height
= strip
->height
;
297 if(ref_vectors
!= NULL
) {
298 ref_frm_pos
= ref
+ (ref_vectors
[0] + strip
->ypos
) * width
+
299 ref_vectors
[1] + strip
->xpos
;
301 ref_frm_pos
= cur_frm_pos
- width_tbl
[4];
310 cmd
= (bit_buf
>> bit_pos
) & 0x03;
312 if(cmd
== 0 || ref_vectors
!= NULL
) {
313 for(lp1
= 0; lp1
< blks_width
; lp1
++) {
314 for(i
= 0, j
= 0; i
< blks_height
; i
++, j
+= width_tbl
[1])
315 ((uint32_t *)cur_frm_pos
)[j
] = ((uint32_t *)ref_frm_pos
)[j
];
327 if((lv
- 8) <= 7 && (k
== 0 || k
== 3 || k
== 10)) {
328 cp2
= s
->ModPred
+ ((lv
- 8) << 7);
330 for(i
= 0; i
< blks_width
<< 2; i
++) {
336 if(k
== 1 || k
== 4) {
337 lv
= (hdr
[j
] & 0xf) + cb_offset
;
338 correction_type_sp
[0] = s
->corrector_type
+ (lv
<< 8);
339 correction_lp
[0] = correction
+ (lv
<< 8);
340 lv
= (hdr
[j
] >> 4) + cb_offset
;
341 correction_lp
[1] = correction
+ (lv
<< 8);
342 correction_type_sp
[1] = s
->corrector_type
+ (lv
<< 8);
344 correctionloworder_lp
[0] = correctionloworder_lp
[1] = correctionloworder
+ (lv
<< 8);
345 correctionhighorder_lp
[0] = correctionhighorder_lp
[1] = correctionhighorder
+ (lv
<< 8);
346 correction_type_sp
[0] = correction_type_sp
[1] = s
->corrector_type
+ (lv
<< 8);
347 correction_lp
[0] = correction_lp
[1] = correction
+ (lv
<< 8);
352 case 0: /********** CASE 0 **********/
353 for( ; blks_height
> 0; blks_height
-= 4) {
354 for(lp1
= 0; lp1
< blks_width
; lp1
++) {
355 for(lp2
= 0; lp2
< 4; ) {
357 cur_lp
= ((uint32_t *)cur_frm_pos
) + width_tbl
[lp2
];
358 ref_lp
= ((uint32_t *)ref_frm_pos
) + width_tbl
[lp2
];
360 switch(correction_type_sp
[0][k
]) {
362 *cur_lp
= le2me_32(((le2me_32(*ref_lp
) >> 1) + correction_lp
[lp2
& 0x01][k
]) << 1);
366 res
= ((le2me_16(((unsigned short *)(ref_lp
))[0]) >> 1) + correction_lp
[lp2
& 0x01][*buf1
]) << 1;
367 ((unsigned short *)cur_lp
)[0] = le2me_16(res
);
368 res
= ((le2me_16(((unsigned short *)(ref_lp
))[1]) >> 1) + correction_lp
[lp2
& 0x01][k
]) << 1;
369 ((unsigned short *)cur_lp
)[1] = le2me_16(res
);
375 for(i
= 0, j
= 0; i
< 2; i
++, j
+= width_tbl
[1])
376 cur_lp
[j
] = ref_lp
[j
];
382 for(i
= 0, j
= 0; i
< (3 - lp2
); i
++, j
+= width_tbl
[1])
383 cur_lp
[j
] = ref_lp
[j
];
389 RLE_V3_CHECK(buf1
,rle_v1
,rle_v2
,rle_v3
)
391 if(rle_v1
== 1 || ref_vectors
!= NULL
) {
392 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1])
393 cur_lp
[j
] = ref_lp
[j
];
396 RLE_V2_CHECK(buf1
,rle_v2
, rle_v3
,lp2
)
403 LP2_CHECK(buf1
,rle_v3
,lp2
)
405 for(i
= 0, j
= 0; i
< (4 - lp2
); i
++, j
+= width_tbl
[1])
406 cur_lp
[j
] = ref_lp
[j
];
418 if(ref_vectors
!= NULL
) {
419 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1])
420 cur_lp
[j
] = ref_lp
[j
];
427 lv
= (lv1
& 0x7F) << 1;
430 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1])
433 LV1_CHECK(buf1
,rle_v3
,lv1
,lp2
)
444 cur_frm_pos
+= ((width
- blks_width
) * 4);
445 ref_frm_pos
+= ((width
- blks_width
) * 4);
450 case 3: /********** CASE 3 **********/
451 if(ref_vectors
!= NULL
)
455 for( ; blks_height
> 0; blks_height
-= 8) {
456 for(lp1
= 0; lp1
< blks_width
; lp1
++) {
457 for(lp2
= 0; lp2
< 4; ) {
460 cur_lp
= ((uint32_t *)cur_frm_pos
) + width_tbl
[lp2
* 2];
461 ref_lp
= ((uint32_t *)cur_frm_pos
) + width_tbl
[(lp2
* 2) - 1];
463 switch(correction_type_sp
[lp2
& 0x01][k
]) {
465 cur_lp
[width_tbl
[1]] = le2me_32(((le2me_32(*ref_lp
) >> 1) + correction_lp
[lp2
& 0x01][k
]) << 1);
466 if(lp2
> 0 || flag1
== 0 || strip
->ypos
!= 0)
467 cur_lp
[0] = ((cur_lp
[-width_tbl
[1]] >> 1) + (cur_lp
[width_tbl
[1]] >> 1)) & 0xFEFEFEFE;
469 cur_lp
[0] = le2me_32(((le2me_32(*ref_lp
) >> 1) + correction_lp
[lp2
& 0x01][k
]) << 1);
474 res
= ((le2me_16(((unsigned short *)ref_lp
)[0]) >> 1) + correction_lp
[lp2
& 0x01][*buf1
]) << 1;
475 ((unsigned short *)cur_lp
)[width_tbl
[2]] = le2me_16(res
);
476 res
= ((le2me_16(((unsigned short *)ref_lp
)[1]) >> 1) + correction_lp
[lp2
& 0x01][k
]) << 1;
477 ((unsigned short *)cur_lp
)[width_tbl
[2]+1] = le2me_16(res
);
479 if(lp2
> 0 || flag1
== 0 || strip
->ypos
!= 0)
480 cur_lp
[0] = ((cur_lp
[-width_tbl
[1]] >> 1) + (cur_lp
[width_tbl
[1]] >> 1)) & 0xFEFEFEFE;
482 cur_lp
[0] = cur_lp
[width_tbl
[1]];
489 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1])
497 for(i
= 0, j
= 0; i
< 6 - (lp2
* 2); i
++, j
+= width_tbl
[1])
519 RLE_V3_CHECK(buf1
,rle_v1
,rle_v2
,rle_v3
)
522 for(i
= 0, j
= 0; i
< 8; i
++, j
+= width_tbl
[1])
523 cur_lp
[j
] = ref_lp
[j
];
526 RLE_V2_CHECK(buf1
,rle_v2
, rle_v3
,lp2
)
529 rle_v2
= (*buf1
) - 1;
533 LP2_CHECK(buf1
,rle_v3
,lp2
)
535 for(i
= 0, j
= 0; i
< 8 - (lp2
* 2); i
++, j
+= width_tbl
[1])
541 av_log(s
->avctx
, AV_LOG_ERROR
, "UNTESTED.\n");
543 lv
= (lv1
& 0x7F) << 1;
547 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1])
550 LV1_CHECK(buf1
,rle_v3
,lv1
,lp2
)
561 cur_frm_pos
+= (((width
* 2) - blks_width
) * 4);
566 case 10: /********** CASE 10 **********/
567 if(ref_vectors
== NULL
) {
570 for( ; blks_height
> 0; blks_height
-= 8) {
571 for(lp1
= 0; lp1
< blks_width
; lp1
+= 2) {
572 for(lp2
= 0; lp2
< 4; ) {
574 cur_lp
= ((uint32_t *)cur_frm_pos
) + width_tbl
[lp2
* 2];
575 ref_lp
= ((uint32_t *)cur_frm_pos
) + width_tbl
[(lp2
* 2) - 1];
578 if(lp2
== 0 && flag1
!= 0) {
579 #ifdef WORDS_BIGENDIAN
580 lv1
= lv1
& 0xFF00FF00;
581 lv1
= (lv1
>> 8) | lv1
;
582 lv2
= lv2
& 0xFF00FF00;
583 lv2
= (lv2
>> 8) | lv2
;
585 lv1
= lv1
& 0x00FF00FF;
586 lv1
= (lv1
<< 8) | lv1
;
587 lv2
= lv2
& 0x00FF00FF;
588 lv2
= (lv2
<< 8) | lv2
;
592 switch(correction_type_sp
[lp2
& 0x01][k
]) {
594 cur_lp
[width_tbl
[1]] = le2me_32(((le2me_32(lv1
) >> 1) + correctionloworder_lp
[lp2
& 0x01][k
]) << 1);
595 cur_lp
[width_tbl
[1]+1] = le2me_32(((le2me_32(lv2
) >> 1) + correctionhighorder_lp
[lp2
& 0x01][k
]) << 1);
596 if(lp2
> 0 || strip
->ypos
!= 0 || flag1
== 0) {
597 cur_lp
[0] = ((cur_lp
[-width_tbl
[1]] >> 1) + (cur_lp
[width_tbl
[1]] >> 1)) & 0xFEFEFEFE;
598 cur_lp
[1] = ((cur_lp
[-width_tbl
[1]+1] >> 1) + (cur_lp
[width_tbl
[1]+1] >> 1)) & 0xFEFEFEFE;
600 cur_lp
[0] = cur_lp
[width_tbl
[1]];
601 cur_lp
[1] = cur_lp
[width_tbl
[1]+1];
607 cur_lp
[width_tbl
[1]] = le2me_32(((le2me_32(lv1
) >> 1) + correctionloworder_lp
[lp2
& 0x01][*buf1
]) << 1);
608 cur_lp
[width_tbl
[1]+1] = le2me_32(((le2me_32(lv2
) >> 1) + correctionloworder_lp
[lp2
& 0x01][k
]) << 1);
609 if(lp2
> 0 || strip
->ypos
!= 0 || flag1
== 0) {
610 cur_lp
[0] = ((cur_lp
[-width_tbl
[1]] >> 1) + (cur_lp
[width_tbl
[1]] >> 1)) & 0xFEFEFEFE;
611 cur_lp
[1] = ((cur_lp
[-width_tbl
[1]+1] >> 1) + (cur_lp
[width_tbl
[1]+1] >> 1)) & 0xFEFEFEFE;
613 cur_lp
[0] = cur_lp
[width_tbl
[1]];
614 cur_lp
[1] = cur_lp
[width_tbl
[1]+1];
623 for(i
= 0, j
= width_tbl
[1]; i
< 3; i
++, j
+= width_tbl
[1]) {
627 cur_lp
[0] = ((cur_lp
[-width_tbl
[1]] >> 1) + (cur_lp
[width_tbl
[1]] >> 1)) & 0xFEFEFEFE;
628 cur_lp
[1] = ((cur_lp
[-width_tbl
[1]+1] >> 1) + (cur_lp
[width_tbl
[1]+1] >> 1)) & 0xFEFEFEFE;
630 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1]) {
641 if(lp2
== 0 && flag1
!= 0) {
642 for(i
= 0, j
= width_tbl
[1]; i
< 5; i
++, j
+= width_tbl
[1]) {
646 cur_lp
[0] = ((cur_lp
[-width_tbl
[1]] >> 1) + (cur_lp
[width_tbl
[1]] >> 1)) & 0xFEFEFEFE;
647 cur_lp
[1] = ((cur_lp
[-width_tbl
[1]+1] >> 1) + (cur_lp
[width_tbl
[1]+1] >> 1)) & 0xFEFEFEFE;
649 for(i
= 0, j
= 0; i
< 6 - (lp2
* 2); i
++, j
+= width_tbl
[1]) {
660 RLE_V3_CHECK(buf1
,rle_v1
,rle_v2
,rle_v3
)
663 for(i
= 0, j
= width_tbl
[1]; i
< 7; i
++, j
+= width_tbl
[1]) {
667 cur_lp
[0] = ((cur_lp
[-width_tbl
[1]] >> 1) + (cur_lp
[width_tbl
[1]] >> 1)) & 0xFEFEFEFE;
668 cur_lp
[1] = ((cur_lp
[-width_tbl
[1]+1] >> 1) + (cur_lp
[width_tbl
[1]+1] >> 1)) & 0xFEFEFEFE;
670 for(i
= 0, j
= 0; i
< 8; i
++, j
+= width_tbl
[1]) {
676 RLE_V2_CHECK(buf1
,rle_v2
, rle_v3
,lp2
)
680 rle_v2
= (*buf1
) - 1;
683 LP2_CHECK(buf1
,rle_v3
,lp2
)
685 if(lp2
== 0 && flag1
!= 0) {
686 for(i
= 0, j
= width_tbl
[1]; i
< 7; i
++, j
+= width_tbl
[1]) {
690 cur_lp
[0] = ((cur_lp
[-width_tbl
[1]] >> 1) + (cur_lp
[width_tbl
[1]] >> 1)) & 0xFEFEFEFE;
691 cur_lp
[1] = ((cur_lp
[-width_tbl
[1]+1] >> 1) + (cur_lp
[width_tbl
[1]+1] >> 1)) & 0xFEFEFEFE;
693 for(i
= 0, j
= 0; i
< 8 - (lp2
* 2); i
++, j
+= width_tbl
[1]) {
718 av_log(s
->avctx
, AV_LOG_ERROR
, "UNTESTED.\n");
720 lv
= (lv1
& 0x7F) << 1;
723 for(i
= 0, j
= 0; i
< 8; i
++, j
+= width_tbl
[1])
725 LV1_CHECK(buf1
,rle_v3
,lv1
,lp2
)
736 cur_frm_pos
+= (((width
* 2) - blks_width
) * 4);
740 for( ; blks_height
> 0; blks_height
-= 8) {
741 for(lp1
= 0; lp1
< blks_width
; lp1
+= 2) {
742 for(lp2
= 0; lp2
< 4; ) {
744 cur_lp
= ((uint32_t *)cur_frm_pos
) + width_tbl
[lp2
* 2];
745 ref_lp
= ((uint32_t *)ref_frm_pos
) + width_tbl
[lp2
* 2];
747 switch(correction_type_sp
[lp2
& 0x01][k
]) {
749 lv1
= correctionloworder_lp
[lp2
& 0x01][k
];
750 lv2
= correctionhighorder_lp
[lp2
& 0x01][k
];
751 cur_lp
[0] = le2me_32(((le2me_32(ref_lp
[0]) >> 1) + lv1
) << 1);
752 cur_lp
[1] = le2me_32(((le2me_32(ref_lp
[1]) >> 1) + lv2
) << 1);
753 cur_lp
[width_tbl
[1]] = le2me_32(((le2me_32(ref_lp
[width_tbl
[1]]) >> 1) + lv1
) << 1);
754 cur_lp
[width_tbl
[1]+1] = le2me_32(((le2me_32(ref_lp
[width_tbl
[1]+1]) >> 1) + lv2
) << 1);
759 lv1
= correctionloworder_lp
[lp2
& 0x01][*buf1
++];
760 lv2
= correctionloworder_lp
[lp2
& 0x01][k
];
761 cur_lp
[0] = le2me_32(((le2me_32(ref_lp
[0]) >> 1) + lv1
) << 1);
762 cur_lp
[1] = le2me_32(((le2me_32(ref_lp
[1]) >> 1) + lv2
) << 1);
763 cur_lp
[width_tbl
[1]] = le2me_32(((le2me_32(ref_lp
[width_tbl
[1]]) >> 1) + lv1
) << 1);
764 cur_lp
[width_tbl
[1]+1] = le2me_32(((le2me_32(ref_lp
[width_tbl
[1]+1]) >> 1) + lv2
) << 1);
770 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1]) {
771 cur_lp
[j
] = ref_lp
[j
];
772 cur_lp
[j
+1] = ref_lp
[j
+1];
780 for(i
= 0, j
= 0; i
< 6 - (lp2
* 2); i
++, j
+= width_tbl
[1]) {
781 cur_lp
[j
] = ref_lp
[j
];
782 cur_lp
[j
+1] = ref_lp
[j
+1];
790 RLE_V3_CHECK(buf1
,rle_v1
,rle_v2
,rle_v3
)
791 for(i
= 0, j
= 0; i
< 8; i
++, j
+= width_tbl
[1]) {
792 ((uint32_t *)cur_frm_pos
)[j
] = ((uint32_t *)ref_frm_pos
)[j
];
793 ((uint32_t *)cur_frm_pos
)[j
+1] = ((uint32_t *)ref_frm_pos
)[j
+1];
795 RLE_V2_CHECK(buf1
,rle_v2
, rle_v3
,lp2
)
799 rle_v2
= (*buf1
) - 1;
803 LP2_CHECK(buf1
,rle_v3
,lp2
)
806 for(i
= 0, j
= 0; i
< 8 - (lp2
* 2); i
++, j
+= width_tbl
[1]) {
807 cur_lp
[j
] = ref_lp
[j
];
808 cur_lp
[j
+1] = ref_lp
[j
+1];
814 av_log(s
->avctx
, AV_LOG_ERROR
, "UNTESTED.\n");
816 lv
= (lv1
& 0x7F) << 1;
819 for(i
= 0, j
= 0; i
< 8; i
++, j
+= width_tbl
[1])
820 ((uint32_t *)cur_frm_pos
)[j
] = ((uint32_t *)cur_frm_pos
)[j
+1] = lv
;
821 LV1_CHECK(buf1
,rle_v3
,lv1
,lp2
)
833 cur_frm_pos
+= (((width
* 2) - blks_width
) * 4);
834 ref_frm_pos
+= (((width
* 2) - blks_width
) * 4);
839 case 11: /********** CASE 11 **********/
840 if(ref_vectors
== NULL
)
843 for( ; blks_height
> 0; blks_height
-= 8) {
844 for(lp1
= 0; lp1
< blks_width
; lp1
++) {
845 for(lp2
= 0; lp2
< 4; ) {
847 cur_lp
= ((uint32_t *)cur_frm_pos
) + width_tbl
[lp2
* 2];
848 ref_lp
= ((uint32_t *)ref_frm_pos
) + width_tbl
[lp2
* 2];
850 switch(correction_type_sp
[lp2
& 0x01][k
]) {
852 cur_lp
[0] = le2me_32(((le2me_32(*ref_lp
) >> 1) + correction_lp
[lp2
& 0x01][k
]) << 1);
853 cur_lp
[width_tbl
[1]] = le2me_32(((le2me_32(ref_lp
[width_tbl
[1]]) >> 1) + correction_lp
[lp2
& 0x01][k
]) << 1);
858 lv1
= (unsigned short)(correction_lp
[lp2
& 0x01][*buf1
++]);
859 lv2
= (unsigned short)(correction_lp
[lp2
& 0x01][k
]);
860 res
= (unsigned short)(((le2me_16(((unsigned short *)ref_lp
)[0]) >> 1) + lv1
) << 1);
861 ((unsigned short *)cur_lp
)[0] = le2me_16(res
);
862 res
= (unsigned short)(((le2me_16(((unsigned short *)ref_lp
)[1]) >> 1) + lv2
) << 1);
863 ((unsigned short *)cur_lp
)[1] = le2me_16(res
);
864 res
= (unsigned short)(((le2me_16(((unsigned short *)ref_lp
)[width_tbl
[2]]) >> 1) + lv1
) << 1);
865 ((unsigned short *)cur_lp
)[width_tbl
[2]] = le2me_16(res
);
866 res
= (unsigned short)(((le2me_16(((unsigned short *)ref_lp
)[width_tbl
[2]+1]) >> 1) + lv2
) << 1);
867 ((unsigned short *)cur_lp
)[width_tbl
[2]+1] = le2me_16(res
);
873 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1])
874 cur_lp
[j
] = ref_lp
[j
];
881 for(i
= 0, j
= 0; i
< 6 - (lp2
* 2); i
++, j
+= width_tbl
[1])
882 cur_lp
[j
] = ref_lp
[j
];
889 RLE_V3_CHECK(buf1
,rle_v1
,rle_v2
,rle_v3
)
891 for(i
= 0, j
= 0; i
< 8; i
++, j
+= width_tbl
[1])
892 cur_lp
[j
] = ref_lp
[j
];
894 RLE_V2_CHECK(buf1
,rle_v2
, rle_v3
,lp2
)
898 rle_v2
= (*buf1
) - 1;
902 LP2_CHECK(buf1
,rle_v3
,lp2
)
905 for(i
= 0, j
= 0; i
< 8 - (lp2
* 2); i
++, j
+= width_tbl
[1])
906 cur_lp
[j
] = ref_lp
[j
];
911 av_log(s
->avctx
, AV_LOG_ERROR
, "UNTESTED.\n");
913 lv
= (lv1
& 0x7F) << 1;
916 for(i
= 0, j
= 0; i
< 4; i
++, j
+= width_tbl
[1])
918 LV1_CHECK(buf1
,rle_v3
,lv1
,lp2
)
930 cur_frm_pos
+= (((width
* 2) - blks_width
) * 4);
931 ref_frm_pos
+= (((width
* 2) - blks_width
) * 4);
940 for( ; strip
>= strip_tbl
; strip
--) {
941 if(strip
->split_flag
!= 0) {
942 strip
->split_flag
= 0;
943 strip
->usl7
= (strip
-1)->usl7
;
945 if(strip
->split_direction
) {
946 strip
->xpos
+= strip
->width
;
947 strip
->width
= (strip
-1)->width
- strip
->width
;
948 if(region_160_width
<= strip
->xpos
&& width
< strip
->width
+ strip
->xpos
)
949 strip
->width
= width
- strip
->xpos
;
951 strip
->ypos
+= strip
->height
;
952 strip
->height
= (strip
-1)->height
- strip
->height
;
960 static av_cold
int indeo3_decode_init(AVCodecContext
*avctx
)
962 Indeo3DecodeContext
*s
= avctx
->priv_data
;
966 s
->width
= avctx
->width
;
967 s
->height
= avctx
->height
;
968 avctx
->pix_fmt
= PIX_FMT_YUV410P
;
970 if (!(ret
= build_modpred(s
)))
971 ret
= iv_alloc_frames(s
);
978 static int iv_decode_frame(Indeo3DecodeContext
*s
,
979 const uint8_t *buf
, int buf_size
)
981 unsigned int image_width
, image_height
,
982 chroma_width
, chroma_height
;
983 unsigned long flags
, cb_offset
, data_size
,
984 y_offset
, v_offset
, u_offset
, mc_vector_count
;
985 const uint8_t *hdr_pos
, *buf_pos
;
988 buf_pos
+= 18; /* skip OS header (16 bytes) and version number */
990 flags
= bytestream_get_le16(&buf_pos
);
991 data_size
= bytestream_get_le32(&buf_pos
);
992 cb_offset
= *buf_pos
++;
993 buf_pos
+= 3; /* skip reserved byte and checksum */
994 image_height
= bytestream_get_le16(&buf_pos
);
995 image_width
= bytestream_get_le16(&buf_pos
);
997 if(avcodec_check_dimensions(NULL
, image_width
, image_height
))
1000 chroma_height
= ((image_height
>> 2) + 3) & 0x7ffc;
1001 chroma_width
= ((image_width
>> 2) + 3) & 0x7ffc;
1002 y_offset
= bytestream_get_le32(&buf_pos
);
1003 v_offset
= bytestream_get_le32(&buf_pos
);
1004 u_offset
= bytestream_get_le32(&buf_pos
);
1005 buf_pos
+= 4; /* reserved */
1007 if(data_size
== 0x80) return 4;
1009 if(FFMAX3(y_offset
, v_offset
, u_offset
) >= buf_size
-16) {
1010 av_log(s
->avctx
, AV_LOG_ERROR
, "y/u/v offset outside buffer\n");
1015 s
->cur_frame
= s
->iv_frame
+ 1;
1016 s
->ref_frame
= s
->iv_frame
;
1018 s
->cur_frame
= s
->iv_frame
;
1019 s
->ref_frame
= s
->iv_frame
+ 1;
1022 buf_pos
= buf
+ 16 + y_offset
;
1023 mc_vector_count
= bytestream_get_le32(&buf_pos
);
1024 if(2LL*mc_vector_count
>= buf_size
-16-y_offset
) {
1025 av_log(s
->avctx
, AV_LOG_ERROR
, "mc_vector_count too large\n");
1029 iv_Decode_Chunk(s
, s
->cur_frame
->Ybuf
, s
->ref_frame
->Ybuf
, image_width
,
1030 image_height
, buf_pos
+ mc_vector_count
* 2, cb_offset
, hdr_pos
, buf_pos
,
1031 FFMIN(image_width
, 160));
1033 if (!(s
->avctx
->flags
& CODEC_FLAG_GRAY
))
1036 buf_pos
= buf
+ 16 + v_offset
;
1037 mc_vector_count
= bytestream_get_le32(&buf_pos
);
1038 if(2LL*mc_vector_count
>= buf_size
-16-v_offset
) {
1039 av_log(s
->avctx
, AV_LOG_ERROR
, "mc_vector_count too large\n");
1043 iv_Decode_Chunk(s
, s
->cur_frame
->Vbuf
, s
->ref_frame
->Vbuf
, chroma_width
,
1044 chroma_height
, buf_pos
+ mc_vector_count
* 2, cb_offset
, hdr_pos
, buf_pos
,
1045 FFMIN(chroma_width
, 40));
1047 buf_pos
= buf
+ 16 + u_offset
;
1048 mc_vector_count
= bytestream_get_le32(&buf_pos
);
1049 if(2LL*mc_vector_count
>= buf_size
-16-u_offset
) {
1050 av_log(s
->avctx
, AV_LOG_ERROR
, "mc_vector_count too large\n");
1054 iv_Decode_Chunk(s
, s
->cur_frame
->Ubuf
, s
->ref_frame
->Ubuf
, chroma_width
,
1055 chroma_height
, buf_pos
+ mc_vector_count
* 2, cb_offset
, hdr_pos
, buf_pos
,
1056 FFMIN(chroma_width
, 40));
1063 static int indeo3_decode_frame(AVCodecContext
*avctx
,
1064 void *data
, int *data_size
,
1067 const uint8_t *buf
= avpkt
->data
;
1068 int buf_size
= avpkt
->size
;
1069 Indeo3DecodeContext
*s
=avctx
->priv_data
;
1070 uint8_t *src
, *dest
;
1073 if (iv_decode_frame(s
, buf
, buf_size
) < 0)
1076 if(s
->frame
.data
[0])
1077 avctx
->release_buffer(avctx
, &s
->frame
);
1079 s
->frame
.reference
= 0;
1080 if(avctx
->get_buffer(avctx
, &s
->frame
) < 0) {
1081 av_log(s
->avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
1085 src
= s
->cur_frame
->Ybuf
;
1086 dest
= s
->frame
.data
[0];
1087 for (y
= 0; y
< s
->height
; y
++) {
1088 memcpy(dest
, src
, s
->cur_frame
->y_w
);
1089 src
+= s
->cur_frame
->y_w
;
1090 dest
+= s
->frame
.linesize
[0];
1093 if (!(s
->avctx
->flags
& CODEC_FLAG_GRAY
))
1095 src
= s
->cur_frame
->Ubuf
;
1096 dest
= s
->frame
.data
[1];
1097 for (y
= 0; y
< s
->height
/ 4; y
++) {
1098 memcpy(dest
, src
, s
->cur_frame
->uv_w
);
1099 src
+= s
->cur_frame
->uv_w
;
1100 dest
+= s
->frame
.linesize
[1];
1103 src
= s
->cur_frame
->Vbuf
;
1104 dest
= s
->frame
.data
[2];
1105 for (y
= 0; y
< s
->height
/ 4; y
++) {
1106 memcpy(dest
, src
, s
->cur_frame
->uv_w
);
1107 src
+= s
->cur_frame
->uv_w
;
1108 dest
+= s
->frame
.linesize
[2];
1112 *data_size
=sizeof(AVFrame
);
1113 *(AVFrame
*)data
= s
->frame
;
1118 static av_cold
int indeo3_decode_end(AVCodecContext
*avctx
)
1120 Indeo3DecodeContext
*s
= avctx
->priv_data
;
1127 AVCodec indeo3_decoder
= {
1131 sizeof(Indeo3DecodeContext
),
1135 indeo3_decode_frame
,
1138 .long_name
= NULL_IF_CONFIG_SMALL("Intel Indeo 3"),