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