00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <unistd.h>
00026
00027 #include "avcodec.h"
00028 #include "dsputil.h"
00029 #include "mpegvideo.h"
00030 #include "bytestream.h"
00031
00032 #include "indeo3data.h"
00033
00034 typedef struct
00035 {
00036 unsigned char *Ybuf;
00037 unsigned char *Ubuf;
00038 unsigned char *Vbuf;
00039 unsigned char *the_buf;
00040 unsigned int the_buf_size;
00041 unsigned short y_w, y_h;
00042 unsigned short uv_w, uv_h;
00043 } YUVBufs;
00044
00045 typedef struct Indeo3DecodeContext {
00046 AVCodecContext *avctx;
00047 int width, height;
00048 AVFrame frame;
00049
00050 YUVBufs iv_frame[2];
00051 YUVBufs *cur_frame;
00052 YUVBufs *ref_frame;
00053
00054 unsigned char *ModPred;
00055 unsigned short *corrector_type;
00056 } Indeo3DecodeContext;
00057
00058 static const int corrector_type_0[24] = {
00059 195, 159, 133, 115, 101, 93, 87, 77,
00060 195, 159, 133, 115, 101, 93, 87, 77,
00061 128, 79, 79, 79, 79, 79, 79, 79
00062 };
00063
00064 static const int corrector_type_2[8] = { 9, 7, 6, 8, 5, 4, 3, 2 };
00065
00066 static void build_modpred(Indeo3DecodeContext *s)
00067 {
00068 int i, j;
00069
00070 s->ModPred = (unsigned char *) av_malloc (8 * 128);
00071
00072 for (i=0; i < 128; ++i) {
00073 s->ModPred[i+0*128] = (i > 126) ? 254 : 2*((i + 1) - ((i + 1) % 2));
00074 s->ModPred[i+1*128] = (i == 7) ? 20 : ((i == 119 || i == 120)
00075 ? 236 : 2*((i + 2) - ((i + 1) % 3)));
00076 s->ModPred[i+2*128] = (i > 125) ? 248 : 2*((i + 2) - ((i + 2) % 4));
00077 s->ModPred[i+3*128] = 2*((i + 1) - ((i - 3) % 5));
00078 s->ModPred[i+4*128] = (i == 8) ? 20 : 2*((i + 1) - ((i - 3) % 6));
00079 s->ModPred[i+5*128] = 2*((i + 4) - ((i + 3) % 7));
00080 s->ModPred[i+6*128] = (i > 123) ? 240 : 2*((i + 4) - ((i + 4) % 8));
00081 s->ModPred[i+7*128] = 2*((i + 5) - ((i + 4) % 9));
00082 }
00083
00084 s->corrector_type = (unsigned short *) av_malloc (24 * 256 * sizeof(unsigned short));
00085
00086 for (i=0; i < 24; ++i) {
00087 for (j=0; j < 256; ++j) {
00088 s->corrector_type[i*256+j] = (j < corrector_type_0[i])
00089 ? 1 : ((j < 248 || (i == 16 && j == 248))
00090 ? 0 : corrector_type_2[j - 248]);
00091 }
00092 }
00093 }
00094
00095 static void iv_Decode_Chunk(Indeo3DecodeContext *s, unsigned char *cur,
00096 unsigned char *ref, int width, int height, const unsigned char *buf1,
00097 long fflags2, const unsigned char *hdr,
00098 const unsigned char *buf2, int min_width_160);
00099
00100
00101 static void iv_alloc_frames(Indeo3DecodeContext *s)
00102 {
00103 int luma_width, luma_height, luma_pixels, chroma_width, chroma_height,
00104 chroma_pixels, i;
00105 unsigned int bufsize;
00106
00107 luma_width = (s->width + 3) & (~3);
00108 luma_height = (s->height + 3) & (~3);
00109
00110 s->iv_frame[0].y_w = s->iv_frame[0].y_h =
00111 s->iv_frame[0].the_buf_size = 0;
00112 s->iv_frame[1].y_w = s->iv_frame[1].y_h =
00113 s->iv_frame[1].the_buf_size = 0;
00114 s->iv_frame[1].the_buf = NULL;
00115
00116 chroma_width = ((luma_width >> 2) + 3) & (~3);
00117 chroma_height = ((luma_height>> 2) + 3) & (~3);
00118 luma_pixels = luma_width * luma_height;
00119 chroma_pixels = chroma_width * chroma_height;
00120
00121 bufsize = luma_pixels * 2 + luma_width * 3 +
00122 (chroma_pixels + chroma_width) * 4;
00123
00124 if((s->iv_frame[0].the_buf =
00125 (s->iv_frame[0].the_buf_size == 0 ? av_malloc(bufsize) :
00126 av_realloc(s->iv_frame[0].the_buf, bufsize))) == NULL)
00127 return;
00128 s->iv_frame[0].y_w = s->iv_frame[1].y_w = luma_width;
00129 s->iv_frame[0].y_h = s->iv_frame[1].y_h = luma_height;
00130 s->iv_frame[0].uv_w = s->iv_frame[1].uv_w = chroma_width;
00131 s->iv_frame[0].uv_h = s->iv_frame[1].uv_h = chroma_height;
00132 s->iv_frame[0].the_buf_size = bufsize;
00133
00134 s->iv_frame[0].Ybuf = s->iv_frame[0].the_buf + luma_width;
00135 i = luma_pixels + luma_width * 2;
00136 s->iv_frame[1].Ybuf = s->iv_frame[0].the_buf + i;
00137 i += (luma_pixels + luma_width);
00138 s->iv_frame[0].Ubuf = s->iv_frame[0].the_buf + i;
00139 i += (chroma_pixels + chroma_width);
00140 s->iv_frame[1].Ubuf = s->iv_frame[0].the_buf + i;
00141 i += (chroma_pixels + chroma_width);
00142 s->iv_frame[0].Vbuf = s->iv_frame[0].the_buf + i;
00143 i += (chroma_pixels + chroma_width);
00144 s->iv_frame[1].Vbuf = s->iv_frame[0].the_buf + i;
00145
00146 for(i = 1; i <= luma_width; i++)
00147 s->iv_frame[0].Ybuf[-i] = s->iv_frame[1].Ybuf[-i] =
00148 s->iv_frame[0].Ubuf[-i] = 0x80;
00149
00150 for(i = 1; i <= chroma_width; i++) {
00151 s->iv_frame[1].Ubuf[-i] = 0x80;
00152 s->iv_frame[0].Vbuf[-i] = 0x80;
00153 s->iv_frame[1].Vbuf[-i] = 0x80;
00154 s->iv_frame[1].Vbuf[chroma_pixels+i-1] = 0x80;
00155 }
00156 }
00157
00158
00159 static void iv_free_func(Indeo3DecodeContext *s)
00160 {
00161 int i;
00162
00163 for(i = 0 ; i < 2 ; i++) {
00164 if(s->iv_frame[i].the_buf != NULL)
00165 av_free(s->iv_frame[i].the_buf);
00166 s->iv_frame[i].Ybuf = s->iv_frame[i].Ubuf =
00167 s->iv_frame[i].Vbuf = NULL;
00168 s->iv_frame[i].the_buf = NULL;
00169 s->iv_frame[i].the_buf_size = 0;
00170 s->iv_frame[i].y_w = s->iv_frame[i].y_h = 0;
00171 s->iv_frame[i].uv_w = s->iv_frame[i].uv_h = 0;
00172 }
00173
00174 av_free(s->ModPred);
00175 av_free(s->corrector_type);
00176 }
00177
00178
00179 static unsigned long iv_decode_frame(Indeo3DecodeContext *s,
00180 const unsigned char *buf, int buf_size)
00181 {
00182 unsigned int hdr_width, hdr_height,
00183 chroma_width, chroma_height;
00184 unsigned long fflags1, fflags2, fflags3, offs1, offs2, offs3, offs;
00185 const unsigned char *hdr_pos, *buf_pos;
00186
00187 buf_pos = buf;
00188 buf_pos += 18;
00189
00190 fflags1 = bytestream_get_le16(&buf_pos);
00191 fflags3 = bytestream_get_le32(&buf_pos);
00192 fflags2 = *buf_pos++;
00193 buf_pos += 3;
00194 hdr_height = bytestream_get_le16(&buf_pos);
00195 hdr_width = bytestream_get_le16(&buf_pos);
00196
00197 if(avcodec_check_dimensions(NULL, hdr_width, hdr_height))
00198 return -1;
00199
00200 chroma_height = ((hdr_height >> 2) + 3) & 0x7ffc;
00201 chroma_width = ((hdr_width >> 2) + 3) & 0x7ffc;
00202 offs1 = bytestream_get_le32(&buf_pos);
00203 offs2 = bytestream_get_le32(&buf_pos);
00204 offs3 = bytestream_get_le32(&buf_pos);
00205 buf_pos += 4;
00206 hdr_pos = buf_pos;
00207 if(fflags3 == 0x80) return 4;
00208
00209 if(fflags1 & 0x200) {
00210 s->cur_frame = s->iv_frame + 1;
00211 s->ref_frame = s->iv_frame;
00212 } else {
00213 s->cur_frame = s->iv_frame;
00214 s->ref_frame = s->iv_frame + 1;
00215 }
00216
00217 buf_pos = buf + 16 + offs1;
00218 offs = bytestream_get_le32(&buf_pos);
00219
00220 iv_Decode_Chunk(s, s->cur_frame->Ybuf, s->ref_frame->Ybuf, hdr_width,
00221 hdr_height, buf_pos + offs * 2, fflags2, hdr_pos, buf_pos,
00222 FFMIN(hdr_width, 160));
00223
00224 if (!(s->avctx->flags & CODEC_FLAG_GRAY))
00225 {
00226
00227 buf_pos = buf + 16 + offs2;
00228 offs = bytestream_get_le32(&buf_pos);
00229
00230 iv_Decode_Chunk(s, s->cur_frame->Vbuf, s->ref_frame->Vbuf, chroma_width,
00231 chroma_height, buf_pos + offs * 2, fflags2, hdr_pos, buf_pos,
00232 FFMIN(chroma_width, 40));
00233
00234 buf_pos = buf + 16 + offs3;
00235 offs = bytestream_get_le32(&buf_pos);
00236
00237 iv_Decode_Chunk(s, s->cur_frame->Ubuf, s->ref_frame->Ubuf, chroma_width,
00238 chroma_height, buf_pos + offs * 2, fflags2, hdr_pos, buf_pos,
00239 FFMIN(chroma_width, 40));
00240
00241 }
00242
00243 return 8;
00244 }
00245
00246 typedef struct {
00247 long xpos;
00248 long ypos;
00249 long width;
00250 long height;
00251 long split_flag;
00252 long split_direction;
00253 long usl7;
00254 } ustr_t;
00255
00256
00257
00258 #define LV1_CHECK(buf1,rle_v3,lv1,lp2) \
00259 if((lv1 & 0x80) != 0) { \
00260 if(rle_v3 != 0) \
00261 rle_v3 = 0; \
00262 else { \
00263 rle_v3 = 1; \
00264 buf1 -= 2; \
00265 } \
00266 } \
00267 lp2 = 4;
00268
00269
00270 #define RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3) \
00271 if(rle_v3 == 0) { \
00272 rle_v2 = *buf1; \
00273 rle_v1 = 1; \
00274 if(rle_v2 > 32) { \
00275 rle_v2 -= 32; \
00276 rle_v1 = 0; \
00277 } \
00278 rle_v3 = 1; \
00279 } \
00280 buf1--;
00281
00282
00283 #define LP2_CHECK(buf1,rle_v3,lp2) \
00284 if(lp2 == 0 && rle_v3 != 0) \
00285 rle_v3 = 0; \
00286 else { \
00287 buf1--; \
00288 rle_v3 = 1; \
00289 }
00290
00291
00292 #define RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2) \
00293 rle_v2--; \
00294 if(rle_v2 == 0) { \
00295 rle_v3 = 0; \
00296 buf1 += 2; \
00297 } \
00298 lp2 = 4;
00299
00300 static void iv_Decode_Chunk(Indeo3DecodeContext *s,
00301 unsigned char *cur, unsigned char *ref, int width, int height,
00302 const unsigned char *buf1, long fflags2, const unsigned char *hdr,
00303 const unsigned char *buf2, int min_width_160)
00304 {
00305 unsigned char bit_buf;
00306 unsigned long bit_pos, lv, lv1, lv2;
00307 long *width_tbl, width_tbl_arr[10];
00308 const signed char *ref_vectors;
00309 unsigned char *cur_frm_pos, *ref_frm_pos, *cp, *cp2;
00310 uint32_t *cur_lp, *ref_lp;
00311 const uint32_t *correction_lp[2], *correctionloworder_lp[2], *correctionhighorder_lp[2];
00312 unsigned short *correction_type_sp[2];
00313 ustr_t strip_tbl[20], *strip;
00314 int i, j, k, lp1, lp2, flag1, cmd, blks_width, blks_height, region_160_width,
00315 rle_v1, rle_v2, rle_v3;
00316 unsigned short res;
00317
00318 bit_buf = 0;
00319 ref_vectors = NULL;
00320
00321 width_tbl = width_tbl_arr + 1;
00322 i = (width < 0 ? width + 3 : width)/4;
00323 for(j = -1; j < 8; j++)
00324 width_tbl[j] = i * j;
00325
00326 strip = strip_tbl;
00327
00328 for(region_160_width = 0; region_160_width < (width - min_width_160); region_160_width += min_width_160);
00329
00330 strip->ypos = strip->xpos = 0;
00331 for(strip->width = min_width_160; width > strip->width; strip->width *= 2);
00332 strip->height = height;
00333 strip->split_direction = 0;
00334 strip->split_flag = 0;
00335 strip->usl7 = 0;
00336
00337 bit_pos = 0;
00338
00339 rle_v1 = rle_v2 = rle_v3 = 0;
00340
00341 while(strip >= strip_tbl) {
00342 if(bit_pos <= 0) {
00343 bit_pos = 8;
00344 bit_buf = *buf1++;
00345 }
00346
00347 bit_pos -= 2;
00348 cmd = (bit_buf >> bit_pos) & 0x03;
00349
00350 if(cmd == 0) {
00351 strip++;
00352 memcpy(strip, strip-1, sizeof(ustr_t));
00353 strip->split_flag = 1;
00354 strip->split_direction = 0;
00355 strip->height = (strip->height > 8 ? ((strip->height+8)>>4)<<3 : 4);
00356 continue;
00357 } else if(cmd == 1) {
00358 strip++;
00359 memcpy(strip, strip-1, sizeof(ustr_t));
00360 strip->split_flag = 1;
00361 strip->split_direction = 1;
00362 strip->width = (strip->width > 8 ? ((strip->width+8)>>4)<<3 : 4);
00363 continue;
00364 } else if(cmd == 2) {
00365 if(strip->usl7 == 0) {
00366 strip->usl7 = 1;
00367 ref_vectors = NULL;
00368 continue;
00369 }
00370 } else if(cmd == 3) {
00371 if(strip->usl7 == 0) {
00372 strip->usl7 = 1;
00373 ref_vectors = (const signed char*)buf2 + (*buf1 * 2);
00374 buf1++;
00375 continue;
00376 }
00377 }
00378
00379 cur_frm_pos = cur + width * strip->ypos + strip->xpos;
00380
00381 if((blks_width = strip->width) < 0)
00382 blks_width += 3;
00383 blks_width >>= 2;
00384 blks_height = strip->height;
00385
00386 if(ref_vectors != NULL) {
00387 ref_frm_pos = ref + (ref_vectors[0] + strip->ypos) * width +
00388 ref_vectors[1] + strip->xpos;
00389 } else
00390 ref_frm_pos = cur_frm_pos - width_tbl[4];
00391
00392 if(cmd == 2) {
00393 if(bit_pos <= 0) {
00394 bit_pos = 8;
00395 bit_buf = *buf1++;
00396 }
00397
00398 bit_pos -= 2;
00399 cmd = (bit_buf >> bit_pos) & 0x03;
00400
00401 if(cmd == 0 || ref_vectors != NULL) {
00402 for(lp1 = 0; lp1 < blks_width; lp1++) {
00403 for(i = 0, j = 0; i < blks_height; i++, j += width_tbl[1])
00404 ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j];
00405 cur_frm_pos += 4;
00406 ref_frm_pos += 4;
00407 }
00408 } else if(cmd != 1)
00409 return;
00410 } else {
00411 k = *buf1 >> 4;
00412 j = *buf1 & 0x0f;
00413 buf1++;
00414 lv = j + fflags2;
00415
00416 if((lv - 8) <= 7 && (k == 0 || k == 3 || k == 10)) {
00417 cp2 = s->ModPred + ((lv - 8) << 7);
00418 cp = ref_frm_pos;
00419 for(i = 0; i < blks_width << 2; i++) {
00420 int v = *cp >> 1;
00421 *(cp++) = cp2[v];
00422 }
00423 }
00424
00425 if(k == 1 || k == 4) {
00426 lv = (hdr[j] & 0xf) + fflags2;
00427 correction_type_sp[0] = s->corrector_type + (lv << 8);
00428 correction_lp[0] = correction + (lv << 8);
00429 lv = (hdr[j] >> 4) + fflags2;
00430 correction_lp[1] = correction + (lv << 8);
00431 correction_type_sp[1] = s->corrector_type + (lv << 8);
00432 } else {
00433 correctionloworder_lp[0] = correctionloworder_lp[1] = correctionloworder + (lv << 8);
00434 correctionhighorder_lp[0] = correctionhighorder_lp[1] = correctionhighorder + (lv << 8);
00435 correction_type_sp[0] = correction_type_sp[1] = s->corrector_type + (lv << 8);
00436 correction_lp[0] = correction_lp[1] = correction + (lv << 8);
00437 }
00438
00439 switch(k) {
00440 case 1:
00441 case 0:
00442 for( ; blks_height > 0; blks_height -= 4) {
00443 for(lp1 = 0; lp1 < blks_width; lp1++) {
00444 for(lp2 = 0; lp2 < 4; ) {
00445 k = *buf1++;
00446 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2];
00447 ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2];
00448
00449 switch(correction_type_sp[0][k]) {
00450 case 0:
00451 *cur_lp = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
00452 lp2++;
00453 break;
00454 case 1:
00455 res = ((le2me_16(((unsigned short *)(ref_lp))[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1;
00456 ((unsigned short *)cur_lp)[0] = le2me_16(res);
00457 res = ((le2me_16(((unsigned short *)(ref_lp))[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
00458 ((unsigned short *)cur_lp)[1] = le2me_16(res);
00459 buf1++;
00460 lp2++;
00461 break;
00462 case 2:
00463 if(lp2 == 0) {
00464 for(i = 0, j = 0; i < 2; i++, j += width_tbl[1])
00465 cur_lp[j] = ref_lp[j];
00466 lp2 += 2;
00467 }
00468 break;
00469 case 3:
00470 if(lp2 < 2) {
00471 for(i = 0, j = 0; i < (3 - lp2); i++, j += width_tbl[1])
00472 cur_lp[j] = ref_lp[j];
00473 lp2 = 3;
00474 }
00475 break;
00476 case 8:
00477 if(lp2 == 0) {
00478 RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
00479
00480 if(rle_v1 == 1 || ref_vectors != NULL) {
00481 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
00482 cur_lp[j] = ref_lp[j];
00483 }
00484
00485 RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
00486 break;
00487 } else {
00488 rle_v1 = 1;
00489 rle_v2 = *buf1 - 1;
00490 }
00491 case 5:
00492 LP2_CHECK(buf1,rle_v3,lp2)
00493 case 4:
00494 for(i = 0, j = 0; i < (4 - lp2); i++, j += width_tbl[1])
00495 cur_lp[j] = ref_lp[j];
00496 lp2 = 4;
00497 break;
00498
00499 case 7:
00500 if(rle_v3 != 0)
00501 rle_v3 = 0;
00502 else {
00503 buf1--;
00504 rle_v3 = 1;
00505 }
00506 case 6:
00507 if(ref_vectors != NULL) {
00508 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
00509 cur_lp[j] = ref_lp[j];
00510 }
00511 lp2 = 4;
00512 break;
00513
00514 case 9:
00515 lv1 = *buf1++;
00516 lv = (lv1 & 0x7F) << 1;
00517 lv += (lv << 8);
00518 lv += (lv << 16);
00519 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
00520 cur_lp[j] = lv;
00521
00522 LV1_CHECK(buf1,rle_v3,lv1,lp2)
00523 break;
00524 default:
00525 return;
00526 }
00527 }
00528
00529 cur_frm_pos += 4;
00530 ref_frm_pos += 4;
00531 }
00532
00533 cur_frm_pos += ((width - blks_width) * 4);
00534 ref_frm_pos += ((width - blks_width) * 4);
00535 }
00536 break;
00537
00538 case 4:
00539 case 3:
00540 if(ref_vectors != NULL)
00541 return;
00542 flag1 = 1;
00543
00544 for( ; blks_height > 0; blks_height -= 8) {
00545 for(lp1 = 0; lp1 < blks_width; lp1++) {
00546 for(lp2 = 0; lp2 < 4; ) {
00547 k = *buf1++;
00548
00549 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
00550 ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];
00551
00552 switch(correction_type_sp[lp2 & 0x01][k]) {
00553 case 0:
00554 cur_lp[width_tbl[1]] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
00555 if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)
00556 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
00557 else
00558 cur_lp[0] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
00559 lp2++;
00560 break;
00561
00562 case 1:
00563 res = ((le2me_16(((unsigned short *)ref_lp)[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1;
00564 ((unsigned short *)cur_lp)[width_tbl[2]] = le2me_16(res);
00565 res = ((le2me_16(((unsigned short *)ref_lp)[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1;
00566 ((unsigned short *)cur_lp)[width_tbl[2]+1] = le2me_16(res);
00567
00568 if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)
00569 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
00570 else
00571 cur_lp[0] = cur_lp[width_tbl[1]];
00572 buf1++;
00573 lp2++;
00574 break;
00575
00576 case 2:
00577 if(lp2 == 0) {
00578 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
00579 cur_lp[j] = *ref_lp;
00580 lp2 += 2;
00581 }
00582 break;
00583
00584 case 3:
00585 if(lp2 < 2) {
00586 for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])
00587 cur_lp[j] = *ref_lp;
00588 lp2 = 3;
00589 }
00590 break;
00591
00592 case 6:
00593 lp2 = 4;
00594 break;
00595
00596 case 7:
00597 if(rle_v3 != 0)
00598 rle_v3 = 0;
00599 else {
00600 buf1--;
00601 rle_v3 = 1;
00602 }
00603 lp2 = 4;
00604 break;
00605
00606 case 8:
00607 if(lp2 == 0) {
00608 RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
00609
00610 if(rle_v1 == 1) {
00611 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
00612 cur_lp[j] = ref_lp[j];
00613 }
00614
00615 RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
00616 break;
00617 } else {
00618 rle_v2 = (*buf1) - 1;
00619 rle_v1 = 1;
00620 }
00621 case 5:
00622 LP2_CHECK(buf1,rle_v3,lp2)
00623 case 4:
00624 for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])
00625 cur_lp[j] = *ref_lp;
00626 lp2 = 4;
00627 break;
00628
00629 case 9:
00630 av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
00631 lv1 = *buf1++;
00632 lv = (lv1 & 0x7F) << 1;
00633 lv += (lv << 8);
00634 lv += (lv << 16);
00635
00636 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
00637 cur_lp[j] = lv;
00638
00639 LV1_CHECK(buf1,rle_v3,lv1,lp2)
00640 break;
00641
00642 default:
00643 return;
00644 }
00645 }
00646
00647 cur_frm_pos += 4;
00648 }
00649
00650 cur_frm_pos += (((width * 2) - blks_width) * 4);
00651 flag1 = 0;
00652 }
00653 break;
00654
00655 case 10:
00656 if(ref_vectors == NULL) {
00657 flag1 = 1;
00658
00659 for( ; blks_height > 0; blks_height -= 8) {
00660 for(lp1 = 0; lp1 < blks_width; lp1 += 2) {
00661 for(lp2 = 0; lp2 < 4; ) {
00662 k = *buf1++;
00663 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
00664 ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];
00665 lv1 = ref_lp[0];
00666 lv2 = ref_lp[1];
00667 if(lp2 == 0 && flag1 != 0) {
00668 #ifdef WORDS_BIGENDIAN
00669 lv1 = lv1 & 0xFF00FF00;
00670 lv1 = (lv1 >> 8) | lv1;
00671 lv2 = lv2 & 0xFF00FF00;
00672 lv2 = (lv2 >> 8) | lv2;
00673 #else
00674 lv1 = lv1 & 0x00FF00FF;
00675 lv1 = (lv1 << 8) | lv1;
00676 lv2 = lv2 & 0x00FF00FF;
00677 lv2 = (lv2 << 8) | lv2;
00678 #endif
00679 }
00680
00681 switch(correction_type_sp[lp2 & 0x01][k]) {
00682 case 0:
00683 cur_lp[width_tbl[1]] = le2me_32(((le2me_32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1);
00684 cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(lv2) >> 1) + correctionhighorder_lp[lp2 & 0x01][k]) << 1);
00685 if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {
00686 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
00687 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
00688 } else {
00689 cur_lp[0] = cur_lp[width_tbl[1]];
00690 cur_lp[1] = cur_lp[width_tbl[1]+1];
00691 }
00692 lp2++;
00693 break;
00694
00695 case 1:
00696 cur_lp[width_tbl[1]] = le2me_32(((le2me_32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][*buf1]) << 1);
00697 cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(lv2) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1);
00698 if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {
00699 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
00700 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
00701 } else {
00702 cur_lp[0] = cur_lp[width_tbl[1]];
00703 cur_lp[1] = cur_lp[width_tbl[1]+1];
00704 }
00705 buf1++;
00706 lp2++;
00707 break;
00708
00709 case 2:
00710 if(lp2 == 0) {
00711 if(flag1 != 0) {
00712 for(i = 0, j = width_tbl[1]; i < 3; i++, j += width_tbl[1]) {
00713 cur_lp[j] = lv1;
00714 cur_lp[j+1] = lv2;
00715 }
00716 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
00717 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
00718 } else {
00719 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {
00720 cur_lp[j] = lv1;
00721 cur_lp[j+1] = lv2;
00722 }
00723 }
00724 lp2 += 2;
00725 }
00726 break;
00727
00728 case 3:
00729 if(lp2 < 2) {
00730 if(lp2 == 0 && flag1 != 0) {
00731 for(i = 0, j = width_tbl[1]; i < 5; i++, j += width_tbl[1]) {
00732 cur_lp[j] = lv1;
00733 cur_lp[j+1] = lv2;
00734 }
00735 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
00736 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
00737 } else {
00738 for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {
00739 cur_lp[j] = lv1;
00740 cur_lp[j+1] = lv2;
00741 }
00742 }
00743 lp2 = 3;
00744 }
00745 break;
00746
00747 case 8:
00748 if(lp2 == 0) {
00749 RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
00750 if(rle_v1 == 1) {
00751 if(flag1 != 0) {
00752 for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {
00753 cur_lp[j] = lv1;
00754 cur_lp[j+1] = lv2;
00755 }
00756 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
00757 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
00758 } else {
00759 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {
00760 cur_lp[j] = lv1;
00761 cur_lp[j+1] = lv2;
00762 }
00763 }
00764 }
00765 RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
00766 break;
00767 } else {
00768 rle_v1 = 1;
00769 rle_v2 = (*buf1) - 1;
00770 }
00771 case 5:
00772 LP2_CHECK(buf1,rle_v3,lp2)
00773 case 4:
00774 if(lp2 == 0 && flag1 != 0) {
00775 for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {
00776 cur_lp[j] = lv1;
00777 cur_lp[j+1] = lv2;
00778 }
00779 cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;
00780 cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;
00781 } else {
00782 for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {
00783 cur_lp[j] = lv1;
00784 cur_lp[j+1] = lv2;
00785 }
00786 }
00787 lp2 = 4;
00788 break;
00789
00790 case 6:
00791 lp2 = 4;
00792 break;
00793
00794 case 7:
00795 if(lp2 == 0) {
00796 if(rle_v3 != 0)
00797 rle_v3 = 0;
00798 else {
00799 buf1--;
00800 rle_v3 = 1;
00801 }
00802 lp2 = 4;
00803 }
00804 break;
00805
00806 case 9:
00807 av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
00808 lv1 = *buf1;
00809 lv = (lv1 & 0x7F) << 1;
00810 lv += (lv << 8);
00811 lv += (lv << 16);
00812 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
00813 cur_lp[j] = lv;
00814 LV1_CHECK(buf1,rle_v3,lv1,lp2)
00815 break;
00816
00817 default:
00818 return;
00819 }
00820 }
00821
00822 cur_frm_pos += 8;
00823 }
00824
00825 cur_frm_pos += (((width * 2) - blks_width) * 4);
00826 flag1 = 0;
00827 }
00828 } else {
00829 for( ; blks_height > 0; blks_height -= 8) {
00830 for(lp1 = 0; lp1 < blks_width; lp1 += 2) {
00831 for(lp2 = 0; lp2 < 4; ) {
00832 k = *buf1++;
00833 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
00834 ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2];
00835
00836 switch(correction_type_sp[lp2 & 0x01][k]) {
00837 case 0:
00838 lv1 = correctionloworder_lp[lp2 & 0x01][k];
00839 lv2 = correctionhighorder_lp[lp2 & 0x01][k];
00840 cur_lp[0] = le2me_32(((le2me_32(ref_lp[0]) >> 1) + lv1) << 1);
00841 cur_lp[1] = le2me_32(((le2me_32(ref_lp[1]) >> 1) + lv2) << 1);
00842 cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1);
00843 cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1);
00844 lp2++;
00845 break;
00846
00847 case 1:
00848 lv1 = correctionloworder_lp[lp2 & 0x01][*buf1++];
00849 lv2 = correctionloworder_lp[lp2 & 0x01][k];
00850 cur_lp[0] = le2me_32(((le2me_32(ref_lp[0]) >> 1) + lv1) << 1);
00851 cur_lp[1] = le2me_32(((le2me_32(ref_lp[1]) >> 1) + lv2) << 1);
00852 cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1);
00853 cur_lp[width_tbl[1]+1] = le2me_32(((le2me_32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1);
00854 lp2++;
00855 break;
00856
00857 case 2:
00858 if(lp2 == 0) {
00859 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {
00860 cur_lp[j] = ref_lp[j];
00861 cur_lp[j+1] = ref_lp[j+1];
00862 }
00863 lp2 += 2;
00864 }
00865 break;
00866
00867 case 3:
00868 if(lp2 < 2) {
00869 for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {
00870 cur_lp[j] = ref_lp[j];
00871 cur_lp[j+1] = ref_lp[j+1];
00872 }
00873 lp2 = 3;
00874 }
00875 break;
00876
00877 case 8:
00878 if(lp2 == 0) {
00879 RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
00880 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {
00881 ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j];
00882 ((uint32_t *)cur_frm_pos)[j+1] = ((uint32_t *)ref_frm_pos)[j+1];
00883 }
00884 RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
00885 break;
00886 } else {
00887 rle_v1 = 1;
00888 rle_v2 = (*buf1) - 1;
00889 }
00890 case 5:
00891 case 7:
00892 LP2_CHECK(buf1,rle_v3,lp2)
00893 case 6:
00894 case 4:
00895 for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {
00896 cur_lp[j] = ref_lp[j];
00897 cur_lp[j+1] = ref_lp[j+1];
00898 }
00899 lp2 = 4;
00900 break;
00901
00902 case 9:
00903 av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
00904 lv1 = *buf1;
00905 lv = (lv1 & 0x7F) << 1;
00906 lv += (lv << 8);
00907 lv += (lv << 16);
00908 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
00909 ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)cur_frm_pos)[j+1] = lv;
00910 LV1_CHECK(buf1,rle_v3,lv1,lp2)
00911 break;
00912
00913 default:
00914 return;
00915 }
00916 }
00917
00918 cur_frm_pos += 8;
00919 ref_frm_pos += 8;
00920 }
00921
00922 cur_frm_pos += (((width * 2) - blks_width) * 4);
00923 ref_frm_pos += (((width * 2) - blks_width) * 4);
00924 }
00925 }
00926 break;
00927
00928 case 11:
00929 if(ref_vectors == NULL)
00930 return;
00931
00932 for( ; blks_height > 0; blks_height -= 8) {
00933 for(lp1 = 0; lp1 < blks_width; lp1++) {
00934 for(lp2 = 0; lp2 < 4; ) {
00935 k = *buf1++;
00936 cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];
00937 ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2];
00938
00939 switch(correction_type_sp[lp2 & 0x01][k]) {
00940 case 0:
00941 cur_lp[0] = le2me_32(((le2me_32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
00942 cur_lp[width_tbl[1]] = le2me_32(((le2me_32(ref_lp[width_tbl[1]]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);
00943 lp2++;
00944 break;
00945
00946 case 1:
00947 lv1 = (unsigned short)(correction_lp[lp2 & 0x01][*buf1++]);
00948 lv2 = (unsigned short)(correction_lp[lp2 & 0x01][k]);
00949 res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[0]) >> 1) + lv1) << 1);
00950 ((unsigned short *)cur_lp)[0] = le2me_16(res);
00951 res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[1]) >> 1) + lv2) << 1);
00952 ((unsigned short *)cur_lp)[1] = le2me_16(res);
00953 res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[width_tbl[2]]) >> 1) + lv1) << 1);
00954 ((unsigned short *)cur_lp)[width_tbl[2]] = le2me_16(res);
00955 res = (unsigned short)(((le2me_16(((unsigned short *)ref_lp)[width_tbl[2]+1]) >> 1) + lv2) << 1);
00956 ((unsigned short *)cur_lp)[width_tbl[2]+1] = le2me_16(res);
00957 lp2++;
00958 break;
00959
00960 case 2:
00961 if(lp2 == 0) {
00962 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
00963 cur_lp[j] = ref_lp[j];
00964 lp2 += 2;
00965 }
00966 break;
00967
00968 case 3:
00969 if(lp2 < 2) {
00970 for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])
00971 cur_lp[j] = ref_lp[j];
00972 lp2 = 3;
00973 }
00974 break;
00975
00976 case 8:
00977 if(lp2 == 0) {
00978 RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)
00979
00980 for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])
00981 cur_lp[j] = ref_lp[j];
00982
00983 RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)
00984 break;
00985 } else {
00986 rle_v1 = 1;
00987 rle_v2 = (*buf1) - 1;
00988 }
00989 case 5:
00990 case 7:
00991 LP2_CHECK(buf1,rle_v3,lp2)
00992 case 4:
00993 case 6:
00994 for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])
00995 cur_lp[j] = ref_lp[j];
00996 lp2 = 4;
00997 break;
00998
00999 case 9:
01000 av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");
01001 lv1 = *buf1++;
01002 lv = (lv1 & 0x7F) << 1;
01003 lv += (lv << 8);
01004 lv += (lv << 16);
01005 for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])
01006 cur_lp[j] = lv;
01007 LV1_CHECK(buf1,rle_v3,lv1,lp2)
01008 break;
01009
01010 default:
01011 return;
01012 }
01013 }
01014
01015 cur_frm_pos += 4;
01016 ref_frm_pos += 4;
01017 }
01018
01019 cur_frm_pos += (((width * 2) - blks_width) * 4);
01020 ref_frm_pos += (((width * 2) - blks_width) * 4);
01021 }
01022 break;
01023
01024 default:
01025 return;
01026 }
01027 }
01028
01029 if(strip < strip_tbl)
01030 return;
01031
01032 for( ; strip >= strip_tbl; strip--) {
01033 if(strip->split_flag != 0) {
01034 strip->split_flag = 0;
01035 strip->usl7 = (strip-1)->usl7;
01036
01037 if(strip->split_direction) {
01038 strip->xpos += strip->width;
01039 strip->width = (strip-1)->width - strip->width;
01040 if(region_160_width <= strip->xpos && width < strip->width + strip->xpos)
01041 strip->width = width - strip->xpos;
01042 } else {
01043 strip->ypos += strip->height;
01044 strip->height = (strip-1)->height - strip->height;
01045 }
01046 break;
01047 }
01048 }
01049 }
01050 }
01051
01052 static int indeo3_decode_init(AVCodecContext *avctx)
01053 {
01054 Indeo3DecodeContext *s = avctx->priv_data;
01055
01056 s->avctx = avctx;
01057 s->width = avctx->width;
01058 s->height = avctx->height;
01059 avctx->pix_fmt = PIX_FMT_YUV410P;
01060
01061 build_modpred(s);
01062 iv_alloc_frames(s);
01063
01064 return 0;
01065 }
01066
01067 static int indeo3_decode_frame(AVCodecContext *avctx,
01068 void *data, int *data_size,
01069 const unsigned char *buf, int buf_size)
01070 {
01071 Indeo3DecodeContext *s=avctx->priv_data;
01072 unsigned char *src, *dest;
01073 int y;
01074
01075 iv_decode_frame(s, buf, buf_size);
01076
01077 if(s->frame.data[0])
01078 avctx->release_buffer(avctx, &s->frame);
01079
01080 s->frame.reference = 0;
01081 if(avctx->get_buffer(avctx, &s->frame) < 0) {
01082 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
01083 return -1;
01084 }
01085
01086 src = s->cur_frame->Ybuf;
01087 dest = s->frame.data[0];
01088 for (y = 0; y < s->height; y++) {
01089 memcpy(dest, src, s->cur_frame->y_w);
01090 src += s->cur_frame->y_w;
01091 dest += s->frame.linesize[0];
01092 }
01093
01094 if (!(s->avctx->flags & CODEC_FLAG_GRAY))
01095 {
01096 src = s->cur_frame->Ubuf;
01097 dest = s->frame.data[1];
01098 for (y = 0; y < s->height / 4; y++) {
01099 memcpy(dest, src, s->cur_frame->uv_w);
01100 src += s->cur_frame->uv_w;
01101 dest += s->frame.linesize[1];
01102 }
01103
01104 src = s->cur_frame->Vbuf;
01105 dest = s->frame.data[2];
01106 for (y = 0; y < s->height / 4; y++) {
01107 memcpy(dest, src, s->cur_frame->uv_w);
01108 src += s->cur_frame->uv_w;
01109 dest += s->frame.linesize[2];
01110 }
01111 }
01112
01113 *data_size=sizeof(AVFrame);
01114 *(AVFrame*)data= s->frame;
01115
01116 return buf_size;
01117 }
01118
01119 static int indeo3_decode_end(AVCodecContext *avctx)
01120 {
01121 Indeo3DecodeContext *s = avctx->priv_data;
01122
01123 iv_free_func(s);
01124
01125 return 0;
01126 }
01127
01128 AVCodec indeo3_decoder = {
01129 "indeo3",
01130 CODEC_TYPE_VIDEO,
01131 CODEC_ID_INDEO3,
01132 sizeof(Indeo3DecodeContext),
01133 indeo3_decode_init,
01134 NULL,
01135 indeo3_decode_end,
01136 indeo3_decode_frame,
01137 0,
01138 NULL
01139 };