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