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