Merge branch 'mirror' into vdpau
[FFMpeg-mirror/ffmpeg-vdpau.git] / libavcodec / indeo3.c
blob533057d46f8a1c4ff74965891285a5fe0c30a6c4
1 /*
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
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
27 #include "avcodec.h"
28 #include "dsputil.h"
29 #include "bytestream.h"
31 #include "indeo3data.h"
33 typedef struct
35 uint8_t *Ybuf;
36 uint8_t *Ubuf;
37 uint8_t *Vbuf;
38 unsigned short y_w, y_h;
39 unsigned short uv_w, uv_h;
40 } YUVBufs;
42 typedef struct Indeo3DecodeContext {
43 AVCodecContext *avctx;
44 int width, height;
45 AVFrame frame;
47 uint8_t *buf;
48 YUVBufs iv_frame[2];
49 YUVBufs *cur_frame;
50 YUVBufs *ref_frame;
52 uint8_t *ModPred;
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)
66 int i, j;
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 :
74 i == 119 ||
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];
95 return 0;
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;
140 return 0;
143 static av_cold void iv_free_func(Indeo3DecodeContext *s)
145 av_free(s->buf);
146 av_free(s->ModPred);
147 av_free(s->corrector_type);
150 typedef struct {
151 long xpos;
152 long ypos;
153 long width;
154 long height;
155 long split_flag;
156 long split_direction;
157 long usl7;
158 } ustr_t;
161 #define LV1_CHECK(buf1,rle_v3,lv1,lp2) \
162 if((lv1 & 0x80) != 0) { \
163 if(rle_v3 != 0) \
164 rle_v3 = 0; \
165 else { \
166 rle_v3 = 1; \
167 buf1 -= 2; \
170 lp2 = 4;
173 #define RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) \
174 if(rle_v3 == 0) { \
175 rle_v2 = *buf1; \
176 rle_v1 = 1; \
177 if(rle_v2 > 32) { \
178 rle_v2 -= 32; \
179 rle_v1 = 0; \
181 rle_v3 = 1; \
183 buf1--;
186 #define LP2_CHECK(buf1,rle_v3,lp2) \
187 if(lp2 == 0 && rle_v3 != 0) \
188 rle_v3 = 0; \
189 else { \
190 buf1--; \
191 rle_v3 = 1; \
195 #define RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) \
196 rle_v2--; \
197 if(rle_v2 == 0) { \
198 rle_v3 = 0; \
199 buf1 += 2; \
201 lp2 = 4;
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)
208 uint8_t bit_buf;
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 ustr_t 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;
219 unsigned short res;
221 bit_buf = 0;
222 ref_vectors = NULL;
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;
229 strip = strip_tbl;
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;
238 strip->usl7 = 0;
240 bit_pos = 0;
242 rle_v1 = rle_v2 = rle_v3 = 0;
244 while(strip >= strip_tbl) {
245 if(bit_pos <= 0) {
246 bit_pos = 8;
247 bit_buf = *buf1++;
250 bit_pos -= 2;
251 cmd = (bit_buf >> bit_pos) & 0x03;
253 if(cmd == 0) {
254 strip++;
255 memcpy(strip, strip-1, sizeof(ustr_t));
256 strip->split_flag = 1;
257 strip->split_direction = 0;
258 strip->height = (strip->height > 8 ? ((strip->height+8)>>4)<<3 : 4);
259 continue;
260 } else if(cmd == 1) {
261 strip++;
262 memcpy(strip, strip-1, sizeof(ustr_t));
263 strip->split_flag = 1;
264 strip->split_direction = 1;
265 strip->width = (strip->width > 8 ? ((strip->width+8)>>4)<<3 : 4);
266 continue;
267 } else if(cmd == 2) {
268 if(strip->usl7 == 0) {
269 strip->usl7 = 1;
270 ref_vectors = NULL;
271 continue;
273 } else if(cmd == 3) {
274 if(strip->usl7 == 0) {
275 strip->usl7 = 1;
276 ref_vectors = (const signed char*)buf2 + (*buf1 * 2);
277 buf1++;
278 continue;
282 cur_frm_pos = cur + width * strip->ypos + strip->xpos;
284 if((blks_width = strip->width) < 0)
285 blks_width += 3;
286 blks_width >>= 2;
287 blks_height = strip->height;
289 if(ref_vectors != NULL) {
290 ref_frm_pos = ref + (ref_vectors[0] + strip->ypos) * width +
291 ref_vectors[1] + strip->xpos;
292 } else
293 ref_frm_pos = cur_frm_pos - width_tbl[4];
295 if(cmd == 2) {
296 if(bit_pos <= 0) {
297 bit_pos = 8;
298 bit_buf = *buf1++;
301 bit_pos -= 2;
302 cmd = (bit_buf >> bit_pos) & 0x03;
304 if(cmd == 0 || ref_vectors != NULL) {
305 for(lp1 = 0; lp1 < blks_width; lp1++) {
306 for(i = 0, j = 0; i < blks_height; i++, j += width_tbl[1])
307 ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j];
308 cur_frm_pos += 4;
309 ref_frm_pos += 4;
311 } else if(cmd != 1)
312 return;
313 } else {
314 k = *buf1 >> 4;
315 j = *buf1 & 0x0f;
316 buf1++;
317 lv = j + cb_offset;
319 if((lv - 8) <= 7 && (k == 0 || k == 3 || k == 10)) {
320 cp2 = s->ModPred + ((lv - 8) << 7);
321 cp = ref_frm_pos;
322 for(i = 0; i < blks_width << 2; i++) {
323 int v = *cp >> 1;
324 *(cp++) = cp2[v];
328 if(k == 1 || k == 4) {
329 lv = (hdr[j] & 0xf) + cb_offset;
330 correction_type_sp[0] = s->corrector_type + (lv << 8);
331 correction_lp[0] = correction + (lv << 8);
332 lv = (hdr[j] >> 4) + cb_offset;
333 correction_lp[1] = correction + (lv << 8);
334 correction_type_sp[1] = s->corrector_type + (lv << 8);
335 } else {
336 correctionloworder_lp[0] = correctionloworder_lp[1] = correctionloworder + (lv << 8);
337 correctionhighorder_lp[0] = correctionhighorder_lp[1] = correctionhighorder + (lv << 8);
338 correction_type_sp[0] = correction_type_sp[1] = s->corrector_type + (lv << 8);
339 correction_lp[0] = correction_lp[1] = correction + (lv << 8);
342 switch(k) {
343 case 1:
344 case 0: /********** CASE 0 **********/
345 for( ; blks_height > 0; blks_height -= 4) {
346 for(lp1 = 0; lp1 < blks_width; lp1++) {
347 for(lp2 = 0; lp2 < 4; ) {
348 k = *buf1++;
349 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2];
350 ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2];
352 switch(correction_type_sp[0][k]) {
353 case 0:
354 *cur_lp = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
355 lp2++;
356 break;
357 case 1:
358 res = ((le2me_16(((unsigned short *)(ref_lp))[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1;
359 ((unsigned short *)cur_lp)[0] = le2me_16(res);
360 res = ((le2me_16(((unsigned short *)(ref_lp))[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
361 ((unsigned short *)cur_lp)[1] = le2me_16(res);
362 buf1++;
363 lp2++;
364 break;
365 case 2:
366 if(lp2 == 0) {
367 for(i = 0, j = 0; i < 2; i++, j += width_tbl[1])
368 cur_lp[j] = ref_lp[j];
369 lp2 += 2;
371 break;
372 case 3:
373 if(lp2 < 2) {
374 for(i = 0, j = 0; i < (3 - lp2); i++, j += width_tbl[1])
375 cur_lp[j] = ref_lp[j];
376 lp2 = 3;
378 break;
379 case 8:
380 if(lp2 == 0) {
381 RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
383 if(rle_v1 == 1 || ref_vectors != NULL) {
384 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
385 cur_lp[j] = ref_lp[j];
388 RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
389 break;
390 } else {
391 rle_v1 = 1;
392 rle_v2 = *buf1 - 1;
394 case 5:
395 LP2_CHECK(buf1,rle_v3,lp2)
396 case 4:
397 for(i = 0, j = 0; i < (4 - lp2); i++, j += width_tbl[1])
398 cur_lp[j] = ref_lp[j];
399 lp2 = 4;
400 break;
402 case 7:
403 if(rle_v3 != 0)
404 rle_v3 = 0;
405 else {
406 buf1--;
407 rle_v3 = 1;
409 case 6:
410 if(ref_vectors != NULL) {
411 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
412 cur_lp[j] = ref_lp[j];
414 lp2 = 4;
415 break;
417 case 9:
418 lv1 = *buf1++;
419 lv = (lv1 & 0x7F) << 1;
420 lv += (lv << 8);
421 lv += (lv << 16);
422 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
423 cur_lp[j] = lv;
425 LV1_CHECK(buf1,rle_v3,lv1,lp2)
426 break;
427 default:
428 return;
432 cur_frm_pos += 4;
433 ref_frm_pos += 4;
436 cur_frm_pos += ((width - blks_width) * 4);
437 ref_frm_pos += ((width - blks_width) * 4);
439 break;
441 case 4:
442 case 3: /********** CASE 3 **********/
443 if(ref_vectors != NULL)
444 return;
445 flag1 = 1;
447 for( ; blks_height > 0; blks_height -= 8) {
448 for(lp1 = 0; lp1 < blks_width; lp1++) {
449 for(lp2 = 0; lp2 < 4; ) {
450 k = *buf1++;
452 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
453 ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];
455 switch(correction_type_sp[lp2 & 0x01][k]) {
456 case 0:
457 cur_lp[width_tbl[1]] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
458 if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)
459 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
460 else
461 cur_lp[0] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
462 lp2++;
463 break;
465 case 1:
466 res = ((le2me_16(((unsigned short *)ref_lp)[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1;
467 ((unsigned short *)cur_lp)[width_tbl[2]] = le2me_16(res);
468 res = ((le2me_16(((unsigned short *)ref_lp)[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
469 ((unsigned short *)cur_lp)[width_tbl[2]+1] = le2me_16(res);
471 if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)
472 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
473 else
474 cur_lp[0] = cur_lp[width_tbl[1]];
475 buf1++;
476 lp2++;
477 break;
479 case 2:
480 if(lp2 == 0) {
481 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
482 cur_lp[j] = *ref_lp;
483 lp2 += 2;
485 break;
487 case 3:
488 if(lp2 < 2) {
489 for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])
490 cur_lp[j] = *ref_lp;
491 lp2 = 3;
493 break;
495 case 6:
496 lp2 = 4;
497 break;
499 case 7:
500 if(rle_v3 != 0)
501 rle_v3 = 0;
502 else {
503 buf1--;
504 rle_v3 = 1;
506 lp2 = 4;
507 break;
509 case 8:
510 if(lp2 == 0) {
511 RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
513 if(rle_v1 == 1) {
514 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
515 cur_lp[j] = ref_lp[j];
518 RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
519 break;
520 } else {
521 rle_v2 = (*buf1) - 1;
522 rle_v1 = 1;
524 case 5:
525 LP2_CHECK(buf1,rle_v3,lp2)
526 case 4:
527 for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])
528 cur_lp[j] = *ref_lp;
529 lp2 = 4;
530 break;
532 case 9:
533 av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
534 lv1 = *buf1++;
535 lv = (lv1 & 0x7F) << 1;
536 lv += (lv << 8);
537 lv += (lv << 16);
539 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
540 cur_lp[j] = lv;
542 LV1_CHECK(buf1,rle_v3,lv1,lp2)
543 break;
545 default:
546 return;
550 cur_frm_pos += 4;
553 cur_frm_pos += (((width * 2) - blks_width) * 4);
554 flag1 = 0;
556 break;
558 case 10: /********** CASE 10 **********/
559 if(ref_vectors == NULL) {
560 flag1 = 1;
562 for( ; blks_height > 0; blks_height -= 8) {
563 for(lp1 = 0; lp1 < blks_width; lp1 += 2) {
564 for(lp2 = 0; lp2 < 4; ) {
565 k = *buf1++;
566 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
567 ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];
568 lv1 = ref_lp[0];
569 lv2 = ref_lp[1];
570 if(lp2 == 0 && flag1 != 0) {
571 #ifdef WORDS_BIGENDIAN
572 lv1 = lv1 & 0xFF00FF00;
573 lv1 = (lv1 >> 8) | lv1;
574 lv2 = lv2 & 0xFF00FF00;
575 lv2 = (lv2 >> 8) | lv2;
576 #else
577 lv1 = lv1 & 0x00FF00FF;
578 lv1 = (lv1 << 8) | lv1;
579 lv2 = lv2 & 0x00FF00FF;
580 lv2 = (lv2 << 8) | lv2;
581 #endif
584 switch(correction_type_sp[lp2 & 0x01][k]) {
585 case 0:
586 cur_lp[width_tbl[1]] = le2me_32(((le2me_32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1);
587 cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(lv2) >> 1) + correctionhighorder_lp[lp2 & 0x01][k]) << 1);
588 if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {
589 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
590 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
591 } else {
592 cur_lp[0] = cur_lp[width_tbl[1]];
593 cur_lp[1] = cur_lp[width_tbl[1]+1];
595 lp2++;
596 break;
598 case 1:
599 cur_lp[width_tbl[1]] = le2me_32(((le2me_32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][*buf1]) << 1);
600 cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(lv2) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1);
601 if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {
602 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
603 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
604 } else {
605 cur_lp[0] = cur_lp[width_tbl[1]];
606 cur_lp[1] = cur_lp[width_tbl[1]+1];
608 buf1++;
609 lp2++;
610 break;
612 case 2:
613 if(lp2 == 0) {
614 if(flag1 != 0) {
615 for(i = 0, j = width_tbl[1]; i < 3; i++, j += width_tbl[1]) {
616 cur_lp[j] = lv1;
617 cur_lp[j+1] = lv2;
619 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
620 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
621 } else {
622 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {
623 cur_lp[j] = lv1;
624 cur_lp[j+1] = lv2;
627 lp2 += 2;
629 break;
631 case 3:
632 if(lp2 < 2) {
633 if(lp2 == 0 && flag1 != 0) {
634 for(i = 0, j = width_tbl[1]; i < 5; i++, j += width_tbl[1]) {
635 cur_lp[j] = lv1;
636 cur_lp[j+1] = lv2;
638 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
639 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
640 } else {
641 for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {
642 cur_lp[j] = lv1;
643 cur_lp[j+1] = lv2;
646 lp2 = 3;
648 break;
650 case 8:
651 if(lp2 == 0) {
652 RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
653 if(rle_v1 == 1) {
654 if(flag1 != 0) {
655 for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {
656 cur_lp[j] = lv1;
657 cur_lp[j+1] = lv2;
659 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
660 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
661 } else {
662 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {
663 cur_lp[j] = lv1;
664 cur_lp[j+1] = lv2;
668 RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
669 break;
670 } else {
671 rle_v1 = 1;
672 rle_v2 = (*buf1) - 1;
674 case 5:
675 LP2_CHECK(buf1,rle_v3,lp2)
676 case 4:
677 if(lp2 == 0 && flag1 != 0) {
678 for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {
679 cur_lp[j] = lv1;
680 cur_lp[j+1] = lv2;
682 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
683 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
684 } else {
685 for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {
686 cur_lp[j] = lv1;
687 cur_lp[j+1] = lv2;
690 lp2 = 4;
691 break;
693 case 6:
694 lp2 = 4;
695 break;
697 case 7:
698 if(lp2 == 0) {
699 if(rle_v3 != 0)
700 rle_v3 = 0;
701 else {
702 buf1--;
703 rle_v3 = 1;
705 lp2 = 4;
707 break;
709 case 9:
710 av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
711 lv1 = *buf1;
712 lv = (lv1 & 0x7F) << 1;
713 lv += (lv << 8);
714 lv += (lv << 16);
715 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
716 cur_lp[j] = lv;
717 LV1_CHECK(buf1,rle_v3,lv1,lp2)
718 break;
720 default:
721 return;
725 cur_frm_pos += 8;
728 cur_frm_pos += (((width * 2) - blks_width) * 4);
729 flag1 = 0;
731 } else {
732 for( ; blks_height > 0; blks_height -= 8) {
733 for(lp1 = 0; lp1 < blks_width; lp1 += 2) {
734 for(lp2 = 0; lp2 < 4; ) {
735 k = *buf1++;
736 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
737 ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2];
739 switch(correction_type_sp[lp2 & 0x01][k]) {
740 case 0:
741 lv1 = correctionloworder_lp[lp2 & 0x01][k];
742 lv2 = correctionhighorder_lp[lp2 & 0x01][k];
743 cur_lp[0] = le2me_32(((le2me_32(ref_lp[0]) >> 1) + lv1) << 1);
744 cur_lp[1] = le2me_32(((le2me_32(ref_lp[1]) >> 1) + lv2) << 1);
745 cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1);
746 cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1);
747 lp2++;
748 break;
750 case 1:
751 lv1 = correctionloworder_lp[lp2 & 0x01][*buf1++];
752 lv2 = correctionloworder_lp[lp2 & 0x01][k];
753 cur_lp[0] = le2me_32(((le2me_32(ref_lp[0]) >> 1) + lv1) << 1);
754 cur_lp[1] = le2me_32(((le2me_32(ref_lp[1]) >> 1) + lv2) << 1);
755 cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1);
756 cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1);
757 lp2++;
758 break;
760 case 2:
761 if(lp2 == 0) {
762 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {
763 cur_lp[j] = ref_lp[j];
764 cur_lp[j+1] = ref_lp[j+1];
766 lp2 += 2;
768 break;
770 case 3:
771 if(lp2 < 2) {
772 for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {
773 cur_lp[j] = ref_lp[j];
774 cur_lp[j+1] = ref_lp[j+1];
776 lp2 = 3;
778 break;
780 case 8:
781 if(lp2 == 0) {
782 RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
783 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {
784 ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j];
785 ((uint32_t *)cur_frm_pos)[j+1] = ((uint32_t *)ref_frm_pos)[j+1];
787 RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
788 break;
789 } else {
790 rle_v1 = 1;
791 rle_v2 = (*buf1) - 1;
793 case 5:
794 case 7:
795 LP2_CHECK(buf1,rle_v3,lp2)
796 case 6:
797 case 4:
798 for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {
799 cur_lp[j] = ref_lp[j];
800 cur_lp[j+1] = ref_lp[j+1];
802 lp2 = 4;
803 break;
805 case 9:
806 av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
807 lv1 = *buf1;
808 lv = (lv1 & 0x7F) << 1;
809 lv += (lv << 8);
810 lv += (lv << 16);
811 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
812 ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)cur_frm_pos)[j+1] = lv;
813 LV1_CHECK(buf1,rle_v3,lv1,lp2)
814 break;
816 default:
817 return;
821 cur_frm_pos += 8;
822 ref_frm_pos += 8;
825 cur_frm_pos += (((width * 2) - blks_width) * 4);
826 ref_frm_pos += (((width * 2) - blks_width) * 4);
829 break;
831 case 11: /********** CASE 11 **********/
832 if(ref_vectors == NULL)
833 return;
835 for( ; blks_height > 0; blks_height -= 8) {
836 for(lp1 = 0; lp1 < blks_width; lp1++) {
837 for(lp2 = 0; lp2 < 4; ) {
838 k = *buf1++;
839 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
840 ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2];
842 switch(correction_type_sp[lp2 & 0x01][k]) {
843 case 0:
844 cur_lp[0] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
845 cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
846 lp2++;
847 break;
849 case 1:
850 lv1 = (unsigned short)(correction_lp[lp2 & 0x01][*buf1++]);
851 lv2 = (unsigned short)(correction_lp[lp2 & 0x01][k]);
852 res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[0]) >> 1) + lv1) << 1);
853 ((unsigned short *)cur_lp)[0] = le2me_16(res);
854 res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[1]) >> 1) + lv2) << 1);
855 ((unsigned short *)cur_lp)[1] = le2me_16(res);
856 res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[width_tbl[2]]) >> 1) + lv1) << 1);
857 ((unsigned short *)cur_lp)[width_tbl[2]] = le2me_16(res);
858 res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[width_tbl[2]+1]) >> 1) + lv2) << 1);
859 ((unsigned short *)cur_lp)[width_tbl[2]+1] = le2me_16(res);
860 lp2++;
861 break;
863 case 2:
864 if(lp2 == 0) {
865 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
866 cur_lp[j] = ref_lp[j];
867 lp2 += 2;
869 break;
871 case 3:
872 if(lp2 < 2) {
873 for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])
874 cur_lp[j] = ref_lp[j];
875 lp2 = 3;
877 break;
879 case 8:
880 if(lp2 == 0) {
881 RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
883 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
884 cur_lp[j] = ref_lp[j];
886 RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
887 break;
888 } else {
889 rle_v1 = 1;
890 rle_v2 = (*buf1) - 1;
892 case 5:
893 case 7:
894 LP2_CHECK(buf1,rle_v3,lp2)
895 case 4:
896 case 6:
897 for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])
898 cur_lp[j] = ref_lp[j];
899 lp2 = 4;
900 break;
902 case 9:
903 av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
904 lv1 = *buf1++;
905 lv = (lv1 & 0x7F) << 1;
906 lv += (lv << 8);
907 lv += (lv << 16);
908 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
909 cur_lp[j] = lv;
910 LV1_CHECK(buf1,rle_v3,lv1,lp2)
911 break;
913 default:
914 return;
918 cur_frm_pos += 4;
919 ref_frm_pos += 4;
922 cur_frm_pos += (((width * 2) - blks_width) * 4);
923 ref_frm_pos += (((width * 2) - blks_width) * 4);
925 break;
927 default:
928 return;
932 if(strip < strip_tbl)
933 return;
935 for( ; strip >= strip_tbl; strip--) {
936 if(strip->split_flag != 0) {
937 strip->split_flag = 0;
938 strip->usl7 = (strip-1)->usl7;
940 if(strip->split_direction) {
941 strip->xpos += strip->width;
942 strip->width = (strip-1)->width - strip->width;
943 if(region_160_width <= strip->xpos && width < strip->width + strip->xpos)
944 strip->width = width - strip->xpos;
945 } else {
946 strip->ypos += strip->height;
947 strip->height = (strip-1)->height - strip->height;
949 break;
955 static av_cold int indeo3_decode_init(AVCodecContext *avctx)
957 Indeo3DecodeContext *s = avctx->priv_data;
958 int ret = 0;
960 s->avctx = avctx;
961 s->width = avctx->width;
962 s->height = avctx->height;
963 avctx->pix_fmt = PIX_FMT_YUV410P;
965 if (!(ret = build_modpred(s)))
966 ret = iv_alloc_frames(s);
967 if (ret)
968 iv_free_func(s);
970 return ret;
973 static unsigned long iv_decode_frame(Indeo3DecodeContext *s,
974 const uint8_t *buf, int buf_size)
976 unsigned int image_width, image_height,
977 chroma_width, chroma_height;
978 unsigned long flags, cb_offset, data_size,
979 y_offset, v_offset, u_offset, mc_vector_count;
980 const uint8_t *hdr_pos, *buf_pos;
982 buf_pos = buf;
983 buf_pos += 18; /* skip OS header (16 bytes) and version number */
985 flags = bytestream_get_le16(&buf_pos);
986 data_size = bytestream_get_le32(&buf_pos);
987 cb_offset = *buf_pos++;
988 buf_pos += 3; /* skip reserved byte and checksum */
989 image_height = bytestream_get_le16(&buf_pos);
990 image_width = bytestream_get_le16(&buf_pos);
992 if(avcodec_check_dimensions(NULL, image_width, image_height))
993 return -1;
995 chroma_height = ((image_height >> 2) + 3) & 0x7ffc;
996 chroma_width = ((image_width >> 2) + 3) & 0x7ffc;
997 y_offset = bytestream_get_le32(&buf_pos);
998 v_offset = bytestream_get_le32(&buf_pos);
999 u_offset = bytestream_get_le32(&buf_pos);
1000 buf_pos += 4; /* reserved */
1001 hdr_pos = buf_pos;
1002 if(data_size == 0x80) return 4;
1004 if(flags & 0x200) {
1005 s->cur_frame = s->iv_frame + 1;
1006 s->ref_frame = s->iv_frame;
1007 } else {
1008 s->cur_frame = s->iv_frame;
1009 s->ref_frame = s->iv_frame + 1;
1012 buf_pos = buf + 16 + y_offset;
1013 mc_vector_count = bytestream_get_le32(&buf_pos);
1015 iv_Decode_Chunk(s, s->cur_frame->Ybuf, s->ref_frame->Ybuf, image_width,
1016 image_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,
1017 FFMIN(image_width, 160));
1019 if (!(s->avctx->flags & CODEC_FLAG_GRAY))
1022 buf_pos = buf + 16 + v_offset;
1023 mc_vector_count = bytestream_get_le32(&buf_pos);
1025 iv_Decode_Chunk(s, s->cur_frame->Vbuf, s->ref_frame->Vbuf, chroma_width,
1026 chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,
1027 FFMIN(chroma_width, 40));
1029 buf_pos = buf + 16 + u_offset;
1030 mc_vector_count = bytestream_get_le32(&buf_pos);
1032 iv_Decode_Chunk(s, s->cur_frame->Ubuf, s->ref_frame->Ubuf, chroma_width,
1033 chroma_height, buf_pos + mc_vector_count * 2, cb_offset, hdr_pos, buf_pos,
1034 FFMIN(chroma_width, 40));
1038 return 8;
1041 static int indeo3_decode_frame(AVCodecContext *avctx,
1042 void *data, int *data_size,
1043 const uint8_t *buf, int buf_size)
1045 Indeo3DecodeContext *s=avctx->priv_data;
1046 uint8_t *src, *dest;
1047 int y;
1049 iv_decode_frame(s, buf, buf_size);
1051 if(s->frame.data[0])
1052 avctx->release_buffer(avctx, &s->frame);
1054 s->frame.reference = 0;
1055 if(avctx->get_buffer(avctx, &s->frame) < 0) {
1056 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
1057 return -1;
1060 src = s->cur_frame->Ybuf;
1061 dest = s->frame.data[0];
1062 for (y = 0; y < s->height; y++) {
1063 memcpy(dest, src, s->cur_frame->y_w);
1064 src += s->cur_frame->y_w;
1065 dest += s->frame.linesize[0];
1068 if (!(s->avctx->flags & CODEC_FLAG_GRAY))
1070 src = s->cur_frame->Ubuf;
1071 dest = s->frame.data[1];
1072 for (y = 0; y < s->height / 4; y++) {
1073 memcpy(dest, src, s->cur_frame->uv_w);
1074 src += s->cur_frame->uv_w;
1075 dest += s->frame.linesize[1];
1078 src = s->cur_frame->Vbuf;
1079 dest = s->frame.data[2];
1080 for (y = 0; y < s->height / 4; y++) {
1081 memcpy(dest, src, s->cur_frame->uv_w);
1082 src += s->cur_frame->uv_w;
1083 dest += s->frame.linesize[2];
1087 *data_size=sizeof(AVFrame);
1088 *(AVFrame*)data= s->frame;
1090 return buf_size;
1093 static av_cold int indeo3_decode_end(AVCodecContext *avctx)
1095 Indeo3DecodeContext *s = avctx->priv_data;
1097 iv_free_func(s);
1099 return 0;
1102 AVCodec indeo3_decoder = {
1103 "indeo3",
1104 CODEC_TYPE_VIDEO,
1105 CODEC_ID_INDEO3,
1106 sizeof(Indeo3DecodeContext),
1107 indeo3_decode_init,
1108 NULL,
1109 indeo3_decode_end,
1110 indeo3_decode_frame,
1112 NULL,
1113 .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 3"),