00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00032 #include "libavutil/imgutils.h"
00033 #include "libavutil/intreadwrite.h"
00034 #include "avcodec.h"
00035 #include "dsputil.h"
00036 #include "bytestream.h"
00037 #include "get_bits.h"
00038
00039 #include "indeo3data.h"
00040
00041
00042 enum {
00043 RLE_ESC_F9 = 249,
00044 RLE_ESC_FA = 250,
00045 RLE_ESC_FB = 251,
00046 RLE_ESC_FC = 252,
00047 RLE_ESC_FD = 253,
00048 RLE_ESC_FE = 254,
00049 RLE_ESC_FF = 255
00050 };
00051
00052
00053
00054 #define BS_8BIT_PEL (1 << 1)
00055 #define BS_KEYFRAME (1 << 2)
00056 #define BS_MV_Y_HALF (1 << 4)
00057 #define BS_MV_X_HALF (1 << 5)
00058 #define BS_NONREF (1 << 8)
00059 #define BS_BUFFER 9
00060
00061
00062 typedef struct Plane {
00063 uint8_t *buffers[2];
00064 uint8_t *pixels[2];
00065 uint32_t width;
00066 uint32_t height;
00067 uint32_t pitch;
00068 } Plane;
00069
00070 #define CELL_STACK_MAX 20
00071
00072 typedef struct Cell {
00073 int16_t xpos;
00074 int16_t ypos;
00075 int16_t width;
00076 int16_t height;
00077 uint8_t tree;
00078 const int8_t *mv_ptr;
00079 } Cell;
00080
00081 typedef struct Indeo3DecodeContext {
00082 AVCodecContext *avctx;
00083 AVFrame frame;
00084 DSPContext dsp;
00085
00086 GetBitContext gb;
00087 int need_resync;
00088 int skip_bits;
00089 const uint8_t *next_cell_data;
00090 const uint8_t *last_byte;
00091 const int8_t *mc_vectors;
00092
00093 int16_t width, height;
00094 uint32_t frame_num;
00095 uint32_t data_size;
00096 uint16_t frame_flags;
00097 uint8_t cb_offset;
00098 uint8_t buf_sel;
00099 const uint8_t *y_data_ptr;
00100 const uint8_t *v_data_ptr;
00101 const uint8_t *u_data_ptr;
00102 int32_t y_data_size;
00103 int32_t v_data_size;
00104 int32_t u_data_size;
00105 const uint8_t *alt_quant;
00106 Plane planes[3];
00107 } Indeo3DecodeContext;
00108
00109
00110 static uint8_t requant_tab[8][128];
00111
00112
00113
00114
00115
00116
00117 static av_cold void build_requant_tab(void)
00118 {
00119 static int8_t offsets[8] = { 1, 1, 2, -3, -3, 3, 4, 4 };
00120 static int8_t deltas [8] = { 0, 1, 0, 4, 4, 1, 0, 1 };
00121
00122 int i, j, step;
00123
00124 for (i = 0; i < 8; i++) {
00125 step = i + 2;
00126 for (j = 0; j < 128; j++)
00127 requant_tab[i][j] = (j + offsets[i]) / step * step + deltas[i];
00128 }
00129
00130
00131
00132
00133 requant_tab[0][127] = 126;
00134 requant_tab[1][119] = 118;
00135 requant_tab[1][120] = 118;
00136 requant_tab[2][126] = 124;
00137 requant_tab[2][127] = 124;
00138 requant_tab[6][124] = 120;
00139 requant_tab[6][125] = 120;
00140 requant_tab[6][126] = 120;
00141 requant_tab[6][127] = 120;
00142
00143
00144 requant_tab[1][7] = 10;
00145 requant_tab[4][8] = 10;
00146 }
00147
00148
00149 static av_cold int allocate_frame_buffers(Indeo3DecodeContext *ctx,
00150 AVCodecContext *avctx)
00151 {
00152 int p, luma_width, luma_height, chroma_width, chroma_height;
00153 int luma_pitch, chroma_pitch, luma_size, chroma_size;
00154
00155 luma_width = ctx->width;
00156 luma_height = ctx->height;
00157
00158 if (luma_width < 16 || luma_width > 640 ||
00159 luma_height < 16 || luma_height > 480 ||
00160 luma_width & 3 || luma_height & 3) {
00161 av_log(avctx, AV_LOG_ERROR, "Invalid picture dimensions: %d x %d!\n",
00162 luma_width, luma_height);
00163 return AVERROR_INVALIDDATA;
00164 }
00165
00166 chroma_width = FFALIGN(luma_width >> 2, 4);
00167 chroma_height = FFALIGN(luma_height >> 2, 4);
00168
00169 luma_pitch = FFALIGN(luma_width, 16);
00170 chroma_pitch = FFALIGN(chroma_width, 16);
00171
00172
00173
00174 luma_size = luma_pitch * (luma_height + 1);
00175
00176
00177
00178 chroma_size = chroma_pitch * (chroma_height + 1);
00179
00180
00181 for (p = 0; p < 3; p++) {
00182 ctx->planes[p].pitch = !p ? luma_pitch : chroma_pitch;
00183 ctx->planes[p].width = !p ? luma_width : chroma_width;
00184 ctx->planes[p].height = !p ? luma_height : chroma_height;
00185
00186 ctx->planes[p].buffers[0] = av_malloc(!p ? luma_size : chroma_size);
00187 ctx->planes[p].buffers[1] = av_malloc(!p ? luma_size : chroma_size);
00188
00189
00190 memset(ctx->planes[p].buffers[0], 0x40, ctx->planes[p].pitch);
00191 memset(ctx->planes[p].buffers[1], 0x40, ctx->planes[p].pitch);
00192
00193
00194 ctx->planes[p].pixels[0] = ctx->planes[p].buffers[0] + ctx->planes[p].pitch;
00195 ctx->planes[p].pixels[1] = ctx->planes[p].buffers[1] + ctx->planes[p].pitch;
00196 }
00197
00198 return 0;
00199 }
00200
00201
00202 static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx)
00203 {
00204 int p;
00205
00206 for (p = 0; p < 3; p++) {
00207 av_freep(&ctx->planes[p].buffers[0]);
00208 av_freep(&ctx->planes[p].buffers[1]);
00209 }
00210 }
00211
00212
00221 static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
00222 {
00223 int h, w, mv_x, mv_y, offset, offset_dst;
00224 uint8_t *src, *dst;
00225
00226
00227 offset_dst = (cell->ypos << 2) * plane->pitch + (cell->xpos << 2);
00228 dst = plane->pixels[ctx->buf_sel] + offset_dst;
00229 if(cell->mv_ptr){
00230 mv_y = cell->mv_ptr[0];
00231 mv_x = cell->mv_ptr[1];
00232 }else
00233 mv_x= mv_y= 0;
00234 offset = offset_dst + mv_y * plane->pitch + mv_x;
00235 src = plane->pixels[ctx->buf_sel ^ 1] + offset;
00236
00237 h = cell->height << 2;
00238
00239 for (w = cell->width; w > 0;) {
00240
00241 if (!((cell->xpos << 2) & 15) && w >= 4) {
00242 for (; w >= 4; src += 16, dst += 16, w -= 4)
00243 ctx->dsp.put_no_rnd_pixels_tab[0][0](dst, src, plane->pitch, h);
00244 }
00245
00246
00247 if (!((cell->xpos << 2) & 7) && w >= 2) {
00248 ctx->dsp.put_no_rnd_pixels_tab[1][0](dst, src, plane->pitch, h);
00249 w -= 2;
00250 src += 8;
00251 dst += 8;
00252 }
00253
00254 if (w >= 1) {
00255 copy_block4(dst, src, plane->pitch, plane->pitch, h);
00256 w--;
00257 src += 4;
00258 dst += 4;
00259 }
00260 }
00261 }
00262
00263
00264
00265 #define AVG_32(dst, src, ref) \
00266 AV_WN32A(dst, ((AV_RN32A(src) + AV_RN32A(ref)) >> 1) & 0x7F7F7F7FUL)
00267
00268 #define AVG_64(dst, src, ref) \
00269 AV_WN64A(dst, ((AV_RN64A(src) + AV_RN64A(ref)) >> 1) & 0x7F7F7F7F7F7F7F7FULL)
00270
00271
00272
00273
00274
00275
00276 static inline uint64_t replicate64(uint64_t a) {
00277 #if HAVE_BIGENDIAN
00278 a &= 0xFF00FF00FF00FF00ULL;
00279 a |= a >> 8;
00280 #else
00281 a &= 0x00FF00FF00FF00FFULL;
00282 a |= a << 8;
00283 #endif
00284 return a;
00285 }
00286
00287 static inline uint32_t replicate32(uint32_t a) {
00288 #if HAVE_BIGENDIAN
00289 a &= 0xFF00FF00UL;
00290 a |= a >> 8;
00291 #else
00292 a &= 0x00FF00FFUL;
00293 a |= a << 8;
00294 #endif
00295 return a;
00296 }
00297
00298
00299
00300 static inline void fill_64(uint8_t *dst, const uint64_t pix, int32_t n,
00301 int32_t row_offset)
00302 {
00303 for (; n > 0; dst += row_offset, n--)
00304 AV_WN64A(dst, pix);
00305 }
00306
00307
00308
00309 enum {
00310 IV3_NOERR = 0,
00311 IV3_BAD_RLE = 1,
00312 IV3_BAD_DATA = 2,
00313 IV3_BAD_COUNTER = 3,
00314 IV3_UNSUPPORTED = 4,
00315 IV3_OUT_OF_DATA = 5
00316 };
00317
00318
00319 #define BUFFER_PRECHECK \
00320 if (*data_ptr >= last_ptr) \
00321 return IV3_OUT_OF_DATA; \
00322
00323 #define RLE_BLOCK_COPY \
00324 if (cell->mv_ptr || !skip_flag) \
00325 copy_block4(dst, ref, row_offset, row_offset, 4 << v_zoom)
00326
00327 #define RLE_BLOCK_COPY_8 \
00328 pix64 = AV_RN64A(ref);\
00329 if (is_first_row) {\
00330 pix64 = replicate64(pix64);\
00331 fill_64(dst + row_offset, pix64, 7, row_offset);\
00332 AVG_64(dst, ref, dst + row_offset);\
00333 } else \
00334 fill_64(dst, pix64, 8, row_offset)
00335
00336 #define RLE_LINES_COPY \
00337 copy_block4(dst, ref, row_offset, row_offset, num_lines << v_zoom)
00338
00339 #define RLE_LINES_COPY_M10 \
00340 pix64 = AV_RN64A(ref);\
00341 if (is_top_of_cell) {\
00342 pix64 = replicate64(pix64);\
00343 fill_64(dst + row_offset, pix64, (num_lines << 1) - 1, row_offset);\
00344 AVG_64(dst, ref, dst + row_offset);\
00345 } else \
00346 fill_64(dst, pix64, num_lines << 1, row_offset)
00347
00348 #define APPLY_DELTA_4 \
00349 AV_WN16A(dst + line_offset , AV_RN16A(ref ) + delta_tab->deltas[dyad1]);\
00350 AV_WN16A(dst + line_offset + 2, AV_RN16A(ref + 2) + delta_tab->deltas[dyad2]);\
00351 if (mode >= 3) {\
00352 if (is_top_of_cell && !cell->ypos) {\
00353 AV_COPY32(dst, dst + row_offset);\
00354 } else {\
00355 AVG_32(dst, ref, dst + row_offset);\
00356 }\
00357 }
00358
00359 #define APPLY_DELTA_8 \
00360 \
00361 if (is_top_of_cell) { \
00362 AV_WN32A(dst + row_offset , \
00363 replicate32(AV_RN32A(ref )) + delta_tab->deltas_m10[dyad1]);\
00364 AV_WN32A(dst + row_offset + 4, \
00365 replicate32(AV_RN32A(ref + 4)) + delta_tab->deltas_m10[dyad2]);\
00366 } else { \
00367 AV_WN32A(dst + row_offset , \
00368 AV_RN32A(ref ) + delta_tab->deltas_m10[dyad1]);\
00369 AV_WN32A(dst + row_offset + 4, \
00370 AV_RN32A(ref + 4) + delta_tab->deltas_m10[dyad2]);\
00371 } \
00372 \
00373 \
00374 \
00375 if (is_top_of_cell && !cell->ypos) {\
00376 AV_COPY64(dst, dst + row_offset);\
00377 } else \
00378 AVG_64(dst, ref, dst + row_offset);
00379
00380
00381 #define APPLY_DELTA_1011_INTER \
00382 if (mode == 10) { \
00383 AV_WN32A(dst , \
00384 AV_RN32A(dst ) + delta_tab->deltas_m10[dyad1]);\
00385 AV_WN32A(dst + 4 , \
00386 AV_RN32A(dst + 4 ) + delta_tab->deltas_m10[dyad2]);\
00387 AV_WN32A(dst + row_offset , \
00388 AV_RN32A(dst + row_offset ) + delta_tab->deltas_m10[dyad1]);\
00389 AV_WN32A(dst + row_offset + 4, \
00390 AV_RN32A(dst + row_offset + 4) + delta_tab->deltas_m10[dyad2]);\
00391 } else { \
00392 AV_WN16A(dst , \
00393 AV_RN16A(dst ) + delta_tab->deltas[dyad1]);\
00394 AV_WN16A(dst + 2 , \
00395 AV_RN16A(dst + 2 ) + delta_tab->deltas[dyad2]);\
00396 AV_WN16A(dst + row_offset , \
00397 AV_RN16A(dst + row_offset ) + delta_tab->deltas[dyad1]);\
00398 AV_WN16A(dst + row_offset + 2, \
00399 AV_RN16A(dst + row_offset + 2) + delta_tab->deltas[dyad2]);\
00400 }
00401
00402
00403 static int decode_cell_data(Cell *cell, uint8_t *block, uint8_t *ref_block,
00404 int pitch, int h_zoom, int v_zoom, int mode,
00405 const vqEntry *delta[2], int swap_quads[2],
00406 const uint8_t **data_ptr, const uint8_t *last_ptr)
00407 {
00408 int x, y, line, num_lines;
00409 int rle_blocks = 0;
00410 uint8_t code, *dst, *ref;
00411 const vqEntry *delta_tab;
00412 unsigned int dyad1, dyad2;
00413 uint64_t pix64;
00414 int skip_flag = 0, is_top_of_cell, is_first_row = 1;
00415 int row_offset, blk_row_offset, line_offset;
00416
00417 row_offset = pitch;
00418 blk_row_offset = (row_offset << (2 + v_zoom)) - (cell->width << 2);
00419 line_offset = v_zoom ? row_offset : 0;
00420
00421 for (y = 0; y < cell->height; is_first_row = 0, y += 1 + v_zoom) {
00422 for (x = 0; x < cell->width; x += 1 + h_zoom) {
00423 ref = ref_block;
00424 dst = block;
00425
00426 if (rle_blocks > 0) {
00427 if (mode <= 4) {
00428 RLE_BLOCK_COPY;
00429 } else if (mode == 10 && !cell->mv_ptr) {
00430 RLE_BLOCK_COPY_8;
00431 }
00432 rle_blocks--;
00433 } else {
00434 for (line = 0; line < 4;) {
00435 num_lines = 1;
00436 is_top_of_cell = is_first_row && !line;
00437
00438
00439 if (mode <= 4)
00440 delta_tab = delta[line & 1];
00441 else
00442 delta_tab = delta[1];
00443 BUFFER_PRECHECK;
00444 code = bytestream_get_byte(data_ptr);
00445 if (code < 248) {
00446 if (code < delta_tab->num_dyads) {
00447 BUFFER_PRECHECK;
00448 dyad1 = bytestream_get_byte(data_ptr);
00449 dyad2 = code;
00450 if (dyad1 >= delta_tab->num_dyads || dyad1 >= 248)
00451 return IV3_BAD_DATA;
00452 } else {
00453
00454 code -= delta_tab->num_dyads;
00455 dyad1 = code / delta_tab->quad_exp;
00456 dyad2 = code % delta_tab->quad_exp;
00457 if (swap_quads[line & 1])
00458 FFSWAP(unsigned int, dyad1, dyad2);
00459 }
00460 if (mode <= 4) {
00461 APPLY_DELTA_4;
00462 } else if (mode == 10 && !cell->mv_ptr) {
00463 APPLY_DELTA_8;
00464 } else {
00465 APPLY_DELTA_1011_INTER;
00466 }
00467 } else {
00468
00469 switch (code) {
00470 case RLE_ESC_FC:
00471 skip_flag = 0;
00472 rle_blocks = 1;
00473 code = 253;
00474
00475 case RLE_ESC_FF:
00476 case RLE_ESC_FE:
00477 case RLE_ESC_FD:
00478 num_lines = 257 - code - line;
00479 if (num_lines <= 0)
00480 return IV3_BAD_RLE;
00481 if (mode <= 4) {
00482 RLE_LINES_COPY;
00483 } else if (mode == 10 && !cell->mv_ptr) {
00484 RLE_LINES_COPY_M10;
00485 }
00486 break;
00487 case RLE_ESC_FB:
00488 BUFFER_PRECHECK;
00489 code = bytestream_get_byte(data_ptr);
00490 rle_blocks = (code & 0x1F) - 1;
00491 if (code >= 64 || rle_blocks < 0)
00492 return IV3_BAD_COUNTER;
00493 skip_flag = code & 0x20;
00494 num_lines = 4 - line;
00495 if (mode >= 10 || (cell->mv_ptr || !skip_flag)) {
00496 if (mode <= 4) {
00497 RLE_LINES_COPY;
00498 } else if (mode == 10 && !cell->mv_ptr) {
00499 RLE_LINES_COPY_M10;
00500 }
00501 }
00502 break;
00503 case RLE_ESC_F9:
00504 skip_flag = 1;
00505 rle_blocks = 1;
00506
00507 case RLE_ESC_FA:
00508 if (line)
00509 return IV3_BAD_RLE;
00510 num_lines = 4;
00511 if (cell->mv_ptr) {
00512 if (mode <= 4) {
00513 RLE_LINES_COPY;
00514 } else if (mode == 10 && !cell->mv_ptr) {
00515 RLE_LINES_COPY_M10;
00516 }
00517 }
00518 break;
00519 default:
00520 return IV3_UNSUPPORTED;
00521 }
00522 }
00523
00524 line += num_lines;
00525 ref += row_offset * (num_lines << v_zoom);
00526 dst += row_offset * (num_lines << v_zoom);
00527 }
00528 }
00529
00530
00531 block += 4 << h_zoom;
00532 ref_block += 4 << h_zoom;
00533 }
00534
00535
00536 ref_block += blk_row_offset;
00537 block += blk_row_offset;
00538 }
00539 return IV3_NOERR;
00540 }
00541
00542
00556 static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
00557 Plane *plane, Cell *cell, const uint8_t *data_ptr,
00558 const uint8_t *last_ptr)
00559 {
00560 int x, mv_x, mv_y, mode, vq_index, prim_indx, second_indx;
00561 int zoom_fac;
00562 int offset, error = 0, swap_quads[2];
00563 uint8_t code, *block, *ref_block = 0;
00564 const vqEntry *delta[2];
00565 const uint8_t *data_start = data_ptr;
00566
00567
00568 code = *data_ptr++;
00569 mode = code >> 4;
00570 vq_index = code & 0xF;
00571
00572
00573 offset = (cell->ypos << 2) * plane->pitch + (cell->xpos << 2);
00574 block = plane->pixels[ctx->buf_sel] + offset;
00575 if (!cell->mv_ptr) {
00576
00577 ref_block = block - plane->pitch;
00578 } else if (mode >= 10) {
00579
00580
00581 copy_cell(ctx, plane, cell);
00582 } else {
00583
00584 mv_y = cell->mv_ptr[0];
00585 mv_x = cell->mv_ptr[1];
00586 offset += mv_y * plane->pitch + mv_x;
00587 ref_block = plane->pixels[ctx->buf_sel ^ 1] + offset;
00588 }
00589
00590
00591
00592
00593 if (mode == 1 || mode == 4) {
00594 code = ctx->alt_quant[vq_index];
00595 prim_indx = (code >> 4) + ctx->cb_offset;
00596 second_indx = (code & 0xF) + ctx->cb_offset;
00597 } else {
00598 vq_index += ctx->cb_offset;
00599 prim_indx = second_indx = vq_index;
00600 }
00601
00602 if (prim_indx >= 24 || second_indx >= 24) {
00603 av_log(avctx, AV_LOG_ERROR, "Invalid VQ table indexes! Primary: %d, secondary: %d!\n",
00604 prim_indx, second_indx);
00605 return AVERROR_INVALIDDATA;
00606 }
00607
00608 delta[0] = &vq_tab[second_indx];
00609 delta[1] = &vq_tab[prim_indx];
00610 swap_quads[0] = second_indx >= 16;
00611 swap_quads[1] = prim_indx >= 16;
00612
00613
00614
00615 if (vq_index >= 8 && ref_block) {
00616 for (x = 0; x < cell->width << 2; x++)
00617 ref_block[x] = requant_tab[vq_index & 7][ref_block[x]];
00618 }
00619
00620 error = IV3_NOERR;
00621
00622 switch (mode) {
00623 case 0:
00624 case 1:
00625 case 3:
00626 case 4:
00627 if (mode >= 3 && cell->mv_ptr) {
00628 av_log(avctx, AV_LOG_ERROR, "Attempt to apply Mode 3/4 to an INTER cell!\n");
00629 return AVERROR_INVALIDDATA;
00630 }
00631
00632 zoom_fac = mode >= 3;
00633 error = decode_cell_data(cell, block, ref_block, plane->pitch, 0, zoom_fac,
00634 mode, delta, swap_quads, &data_ptr, last_ptr);
00635 break;
00636 case 10:
00637 case 11:
00638 if (mode == 10 && !cell->mv_ptr) {
00639 error = decode_cell_data(cell, block, ref_block, plane->pitch, 1, 1,
00640 mode, delta, swap_quads, &data_ptr, last_ptr);
00641 } else {
00642 if (mode == 11 && !cell->mv_ptr) {
00643 av_log(avctx, AV_LOG_ERROR, "Attempt to use Mode 11 for an INTRA cell!\n");
00644 return AVERROR_INVALIDDATA;
00645 }
00646
00647 zoom_fac = mode == 10;
00648 error = decode_cell_data(cell, block, ref_block, plane->pitch,
00649 zoom_fac, 1, mode, delta, swap_quads,
00650 &data_ptr, last_ptr);
00651 }
00652 break;
00653 default:
00654 av_log(avctx, AV_LOG_ERROR, "Unsupported coding mode: %d\n", mode);
00655 return AVERROR_INVALIDDATA;
00656 }
00657
00658 switch (error) {
00659 case IV3_BAD_RLE:
00660 av_log(avctx, AV_LOG_ERROR, "Mode %d: RLE code %X is not allowed at the current line\n",
00661 mode, data_ptr[-1]);
00662 return AVERROR_INVALIDDATA;
00663 case IV3_BAD_DATA:
00664 av_log(avctx, AV_LOG_ERROR, "Mode %d: invalid VQ data\n", mode);
00665 return AVERROR_INVALIDDATA;
00666 case IV3_BAD_COUNTER:
00667 av_log(avctx, AV_LOG_ERROR, "Mode %d: RLE-FB invalid counter: %d\n", mode, code);
00668 return AVERROR_INVALIDDATA;
00669 case IV3_UNSUPPORTED:
00670 av_log(avctx, AV_LOG_ERROR, "Mode %d: unsupported RLE code: %X\n", mode, data_ptr[-1]);
00671 return AVERROR_INVALIDDATA;
00672 case IV3_OUT_OF_DATA:
00673 av_log(avctx, AV_LOG_ERROR, "Mode %d: attempt to read past end of buffer\n", mode);
00674 return AVERROR_INVALIDDATA;
00675 }
00676
00677 return data_ptr - data_start;
00678 }
00679
00680
00681
00682 enum {
00683 H_SPLIT = 0,
00684 V_SPLIT = 1,
00685 INTRA_NULL = 2,
00686 INTER_DATA = 3
00687 };
00688
00689
00690 #define SPLIT_CELL(size, new_size) (new_size) = ((size) > 2) ? ((((size) + 2) >> 2) << 1) : 1
00691
00692 #define UPDATE_BITPOS(n) \
00693 ctx->skip_bits += (n); \
00694 ctx->need_resync = 1
00695
00696 #define RESYNC_BITSTREAM \
00697 if (ctx->need_resync && !(get_bits_count(&ctx->gb) & 7)) { \
00698 skip_bits_long(&ctx->gb, ctx->skip_bits); \
00699 ctx->skip_bits = 0; \
00700 ctx->need_resync = 0; \
00701 }
00702
00703 #define CHECK_CELL \
00704 if (curr_cell.xpos + curr_cell.width > (plane->width >> 2) || \
00705 curr_cell.ypos + curr_cell.height > (plane->height >> 2)) { \
00706 av_log(avctx, AV_LOG_ERROR, "Invalid cell: x=%d, y=%d, w=%d, h=%d\n", \
00707 curr_cell.xpos, curr_cell.ypos, curr_cell.width, curr_cell.height); \
00708 return AVERROR_INVALIDDATA; \
00709 }
00710
00711
00712 static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
00713 Plane *plane, int code, Cell *ref_cell,
00714 const int depth, const int strip_width)
00715 {
00716 Cell curr_cell;
00717 int bytes_used;
00718
00719 if (depth <= 0) {
00720 av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n");
00721 return AVERROR_INVALIDDATA;
00722 }
00723
00724 curr_cell = *ref_cell;
00725 if (code == H_SPLIT) {
00726 SPLIT_CELL(ref_cell->height, curr_cell.height);
00727 ref_cell->ypos += curr_cell.height;
00728 ref_cell->height -= curr_cell.height;
00729 } else if (code == V_SPLIT) {
00730 if (curr_cell.width > strip_width) {
00731
00732 curr_cell.width = (curr_cell.width <= (strip_width << 1) ? 1 : 2) * strip_width;
00733 } else
00734 SPLIT_CELL(ref_cell->width, curr_cell.width);
00735 ref_cell->xpos += curr_cell.width;
00736 ref_cell->width -= curr_cell.width;
00737 }
00738
00739 while (get_bits_left(&ctx->gb) >= 2) {
00740 RESYNC_BITSTREAM;
00741 switch (code = get_bits(&ctx->gb, 2)) {
00742 case H_SPLIT:
00743 case V_SPLIT:
00744 if (parse_bintree(ctx, avctx, plane, code, &curr_cell, depth - 1, strip_width))
00745 return AVERROR_INVALIDDATA;
00746 break;
00747 case INTRA_NULL:
00748 if (!curr_cell.tree) {
00749 curr_cell.mv_ptr = 0;
00750 curr_cell.tree = 1;
00751 } else {
00752 RESYNC_BITSTREAM;
00753 code = get_bits(&ctx->gb, 2);
00754 if (code >= 2) {
00755 av_log(avctx, AV_LOG_ERROR, "Invalid VQ_NULL code: %d\n", code);
00756 return AVERROR_INVALIDDATA;
00757 }
00758 if (code == 1)
00759 av_log(avctx, AV_LOG_ERROR, "SkipCell procedure not implemented yet!\n");
00760
00761 CHECK_CELL
00762 if (!curr_cell.mv_ptr)
00763 return AVERROR_INVALIDDATA;
00764 copy_cell(ctx, plane, &curr_cell);
00765 return 0;
00766 }
00767 break;
00768 case INTER_DATA:
00769 if (!curr_cell.tree) {
00770
00771 if (!ctx->need_resync)
00772 ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3];
00773 if(ctx->mc_vectors)
00774 curr_cell.mv_ptr = &ctx->mc_vectors[*(ctx->next_cell_data++) << 1];
00775 curr_cell.tree = 1;
00776 UPDATE_BITPOS(8);
00777 } else {
00778 if (!ctx->need_resync)
00779 ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3];
00780
00781 CHECK_CELL
00782 bytes_used = decode_cell(ctx, avctx, plane, &curr_cell,
00783 ctx->next_cell_data, ctx->last_byte);
00784 if (bytes_used < 0)
00785 return AVERROR_INVALIDDATA;
00786
00787 UPDATE_BITPOS(bytes_used << 3);
00788 ctx->next_cell_data += bytes_used;
00789 return 0;
00790 }
00791 break;
00792 }
00793 }
00794
00795 return AVERROR_INVALIDDATA;
00796 }
00797
00798
00799 static int decode_plane(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
00800 Plane *plane, const uint8_t *data, int32_t data_size,
00801 int32_t strip_width)
00802 {
00803 Cell curr_cell;
00804 uint32_t num_vectors;
00805
00806
00807
00808 num_vectors = bytestream_get_le32(&data);
00809 if(num_vectors >= data_size/2)
00810 return AVERROR_INVALIDDATA;
00811 ctx->mc_vectors = num_vectors ? data : 0;
00812 data += num_vectors * 2;
00813 data_size-= num_vectors * 2;
00814
00815
00816 init_get_bits(&ctx->gb, data, data_size << 3);
00817 ctx->skip_bits = 0;
00818 ctx->need_resync = 0;
00819
00820 ctx->last_byte = data + data_size - 1;
00821
00822
00823 curr_cell.xpos = curr_cell.ypos = 0;
00824 curr_cell.width = plane->width >> 2;
00825 curr_cell.height = plane->height >> 2;
00826 curr_cell.tree = 0;
00827 curr_cell.mv_ptr = 0;
00828
00829 return parse_bintree(ctx, avctx, plane, INTRA_NULL, &curr_cell, CELL_STACK_MAX, strip_width);
00830 }
00831
00832
00833 #define OS_HDR_ID MKBETAG('F', 'R', 'M', 'H')
00834
00835 static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx,
00836 const uint8_t *buf, int buf_size)
00837 {
00838 const uint8_t *buf_ptr = buf, *bs_hdr;
00839 uint32_t frame_num, word2, check_sum, data_size;
00840 uint32_t y_offset, u_offset, v_offset, starts[3], ends[3];
00841 uint16_t height, width;
00842 int i, j;
00843
00844
00845 frame_num = bytestream_get_le32(&buf_ptr);
00846 word2 = bytestream_get_le32(&buf_ptr);
00847 check_sum = bytestream_get_le32(&buf_ptr);
00848 data_size = bytestream_get_le32(&buf_ptr);
00849
00850 if ((frame_num ^ word2 ^ data_size ^ OS_HDR_ID) != check_sum) {
00851 av_log(avctx, AV_LOG_ERROR, "OS header checksum mismatch!\n");
00852 return AVERROR_INVALIDDATA;
00853 }
00854
00855
00856 bs_hdr = buf_ptr;
00857
00858 if (bytestream_get_le16(&buf_ptr) != 32) {
00859 av_log(avctx, AV_LOG_ERROR, "Unsupported codec version!\n");
00860 return AVERROR_INVALIDDATA;
00861 }
00862
00863 ctx->frame_num = frame_num;
00864 ctx->frame_flags = bytestream_get_le16(&buf_ptr);
00865 ctx->data_size = (bytestream_get_le32(&buf_ptr) + 7) >> 3;
00866 ctx->cb_offset = *buf_ptr++;
00867
00868 if (ctx->data_size == 16)
00869 return 4;
00870 if (ctx->data_size > buf_size)
00871 ctx->data_size = buf_size;
00872
00873 buf_ptr += 3;
00874
00875
00876 height = bytestream_get_le16(&buf_ptr);
00877 width = bytestream_get_le16(&buf_ptr);
00878 if (av_image_check_size(width, height, 0, avctx))
00879 return AVERROR_INVALIDDATA;
00880
00881 if (width != ctx->width || height != ctx->height) {
00882 av_dlog(avctx, "Frame dimensions changed!\n");
00883
00884 ctx->width = width;
00885 ctx->height = height;
00886
00887 free_frame_buffers(ctx);
00888 if(allocate_frame_buffers(ctx, avctx) < 0)
00889 return AVERROR_INVALIDDATA;
00890 avcodec_set_dimensions(avctx, width, height);
00891 }
00892
00893 y_offset = bytestream_get_le32(&buf_ptr);
00894 v_offset = bytestream_get_le32(&buf_ptr);
00895 u_offset = bytestream_get_le32(&buf_ptr);
00896
00897
00898
00899 starts[0] = y_offset;
00900 starts[1] = v_offset;
00901 starts[2] = u_offset;
00902
00903 for (j = 0; j < 3; j++) {
00904 ends[j] = ctx->data_size;
00905 for (i = 2; i >= 0; i--)
00906 if (starts[i] < ends[j] && starts[i] > starts[j])
00907 ends[j] = starts[i];
00908 }
00909
00910 ctx->y_data_size = ends[0] - starts[0];
00911 ctx->v_data_size = ends[1] - starts[1];
00912 ctx->u_data_size = ends[2] - starts[2];
00913 if (FFMAX3(y_offset, v_offset, u_offset) >= ctx->data_size - 16 ||
00914 FFMIN3(ctx->y_data_size, ctx->v_data_size, ctx->u_data_size) <= 0) {
00915 av_log(avctx, AV_LOG_ERROR, "One of the y/u/v offsets is invalid\n");
00916 return AVERROR_INVALIDDATA;
00917 }
00918
00919 ctx->y_data_ptr = bs_hdr + y_offset;
00920 ctx->v_data_ptr = bs_hdr + v_offset;
00921 ctx->u_data_ptr = bs_hdr + u_offset;
00922 ctx->alt_quant = buf_ptr + sizeof(uint32_t);
00923
00924 if (ctx->data_size == 16) {
00925 av_log(avctx, AV_LOG_DEBUG, "Sync frame encountered!\n");
00926 return 16;
00927 }
00928
00929 if (ctx->frame_flags & BS_8BIT_PEL) {
00930 av_log_ask_for_sample(avctx, "8-bit pixel format\n");
00931 return AVERROR_PATCHWELCOME;
00932 }
00933
00934 if (ctx->frame_flags & BS_MV_X_HALF || ctx->frame_flags & BS_MV_Y_HALF) {
00935 av_log_ask_for_sample(avctx, "halfpel motion vectors\n");
00936 return AVERROR_PATCHWELCOME;
00937 }
00938
00939 return 0;
00940 }
00941
00942
00952 static void output_plane(const Plane *plane, int buf_sel, uint8_t *dst, int dst_pitch)
00953 {
00954 int x,y;
00955 const uint8_t *src = plane->pixels[buf_sel];
00956 uint32_t pitch = plane->pitch;
00957
00958 for (y = 0; y < plane->height; y++) {
00959
00960 for (x = 0; x < plane->width >> 2; x++) {
00961 AV_WN32A(dst, (AV_RN32A(src) & 0x7F7F7F7F) << 1);
00962 src += 4;
00963 dst += 4;
00964 }
00965
00966 for (x <<= 2; x < plane->width; x++)
00967 *dst++ = *src++ << 1;
00968
00969 src += pitch - plane->width;
00970 dst += dst_pitch - plane->width;
00971 }
00972 }
00973
00974
00975 static av_cold int decode_init(AVCodecContext *avctx)
00976 {
00977 Indeo3DecodeContext *ctx = avctx->priv_data;
00978
00979 ctx->avctx = avctx;
00980 ctx->width = avctx->width;
00981 ctx->height = avctx->height;
00982 avctx->pix_fmt = PIX_FMT_YUV410P;
00983 avcodec_get_frame_defaults(&ctx->frame);
00984
00985 build_requant_tab();
00986
00987 dsputil_init(&ctx->dsp, avctx);
00988
00989 return allocate_frame_buffers(ctx, avctx);
00990 }
00991
00992
00993 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
00994 AVPacket *avpkt)
00995 {
00996 Indeo3DecodeContext *ctx = avctx->priv_data;
00997 const uint8_t *buf = avpkt->data;
00998 int buf_size = avpkt->size;
00999 int res;
01000
01001 res = decode_frame_headers(ctx, avctx, buf, buf_size);
01002 if (res < 0)
01003 return res;
01004
01005
01006 if (res) {
01007
01008 *data_size = 0;
01009 return buf_size;
01010 }
01011
01012
01013 if (ctx->frame_flags & BS_NONREF &&
01014 (avctx->skip_frame >= AVDISCARD_NONREF))
01015 return 0;
01016
01017
01018 if (!(ctx->frame_flags & BS_KEYFRAME) && avctx->skip_frame >= AVDISCARD_NONKEY)
01019 return 0;
01020
01021
01022 ctx->buf_sel = (ctx->frame_flags >> BS_BUFFER) & 1;
01023
01024
01025 if ((res = decode_plane(ctx, avctx, ctx->planes, ctx->y_data_ptr, ctx->y_data_size, 40)))
01026 return res;
01027
01028
01029 if ((res = decode_plane(ctx, avctx, &ctx->planes[1], ctx->u_data_ptr, ctx->u_data_size, 10)))
01030 return res;
01031
01032 if ((res = decode_plane(ctx, avctx, &ctx->planes[2], ctx->v_data_ptr, ctx->v_data_size, 10)))
01033 return res;
01034
01035 if (ctx->frame.data[0])
01036 avctx->release_buffer(avctx, &ctx->frame);
01037
01038 ctx->frame.reference = 0;
01039 if ((res = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
01040 av_log(ctx->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
01041 return res;
01042 }
01043
01044 output_plane(&ctx->planes[0], ctx->buf_sel, ctx->frame.data[0], ctx->frame.linesize[0]);
01045 output_plane(&ctx->planes[1], ctx->buf_sel, ctx->frame.data[1], ctx->frame.linesize[1]);
01046 output_plane(&ctx->planes[2], ctx->buf_sel, ctx->frame.data[2], ctx->frame.linesize[2]);
01047
01048 *data_size = sizeof(AVFrame);
01049 *(AVFrame*)data = ctx->frame;
01050
01051 return buf_size;
01052 }
01053
01054
01055 static av_cold int decode_close(AVCodecContext *avctx)
01056 {
01057 Indeo3DecodeContext *ctx = avctx->priv_data;
01058
01059 free_frame_buffers(avctx->priv_data);
01060
01061 if (ctx->frame.data[0])
01062 avctx->release_buffer(avctx, &ctx->frame);
01063
01064 return 0;
01065 }
01066
01067 AVCodec ff_indeo3_decoder = {
01068 .name = "indeo3",
01069 .type = AVMEDIA_TYPE_VIDEO,
01070 .id = CODEC_ID_INDEO3,
01071 .priv_data_size = sizeof(Indeo3DecodeContext),
01072 .init = decode_init,
01073 .close = decode_close,
01074 .decode = decode_frame,
01075 .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 3"),
01076 };