|
|
@ -222,7 +222,7 @@ static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx) |
|
|
|
* @param plane pointer to the plane descriptor |
|
|
|
* @param plane pointer to the plane descriptor |
|
|
|
* @param cell pointer to the cell descriptor |
|
|
|
* @param cell pointer to the cell descriptor |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) |
|
|
|
static int copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int h, w, mv_x, mv_y, offset, offset_dst; |
|
|
|
int h, w, mv_x, mv_y, offset, offset_dst; |
|
|
|
uint8_t *src, *dst; |
|
|
|
uint8_t *src, *dst; |
|
|
@ -232,6 +232,16 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) |
|
|
|
dst = plane->pixels[ctx->buf_sel] + offset_dst; |
|
|
|
dst = plane->pixels[ctx->buf_sel] + offset_dst; |
|
|
|
mv_y = cell->mv_ptr[0]; |
|
|
|
mv_y = cell->mv_ptr[0]; |
|
|
|
mv_x = cell->mv_ptr[1]; |
|
|
|
mv_x = cell->mv_ptr[1]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -1 because there is an extra line on top for prediction */ |
|
|
|
|
|
|
|
if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 || |
|
|
|
|
|
|
|
((cell->ypos + cell->height) << 2) + mv_y >= plane->height || |
|
|
|
|
|
|
|
((cell->xpos + cell->width) << 2) + mv_x >= plane->width) { |
|
|
|
|
|
|
|
av_log(ctx->avctx, AV_LOG_ERROR, |
|
|
|
|
|
|
|
"Motion vectors point out of the frame.\n"); |
|
|
|
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
offset = offset_dst + mv_y * plane->pitch + mv_x; |
|
|
|
offset = offset_dst + mv_y * plane->pitch + mv_x; |
|
|
|
src = plane->pixels[ctx->buf_sel ^ 1] + offset; |
|
|
|
src = plane->pixels[ctx->buf_sel ^ 1] + offset; |
|
|
|
|
|
|
|
|
|
|
@ -259,6 +269,8 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) |
|
|
|
dst += 4; |
|
|
|
dst += 4; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -585,11 +597,23 @@ static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx, |
|
|
|
} else if (mode >= 10) { |
|
|
|
} else if (mode >= 10) { |
|
|
|
/* for mode 10 and 11 INTER first copy the predicted cell into the current one */ |
|
|
|
/* for mode 10 and 11 INTER first copy the predicted cell into the current one */ |
|
|
|
/* so we don't need to do data copying for each RLE code later */ |
|
|
|
/* so we don't need to do data copying for each RLE code later */ |
|
|
|
copy_cell(ctx, plane, cell); |
|
|
|
int ret = copy_cell(ctx, plane, cell); |
|
|
|
|
|
|
|
if (ret < 0) |
|
|
|
|
|
|
|
return ret; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
/* set the pointer to the reference pixels for modes 0-4 INTER */ |
|
|
|
/* set the pointer to the reference pixels for modes 0-4 INTER */ |
|
|
|
mv_y = cell->mv_ptr[0]; |
|
|
|
mv_y = cell->mv_ptr[0]; |
|
|
|
mv_x = cell->mv_ptr[1]; |
|
|
|
mv_x = cell->mv_ptr[1]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -1 because there is an extra line on top for prediction */ |
|
|
|
|
|
|
|
if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 || |
|
|
|
|
|
|
|
((cell->ypos + cell->height) << 2) + mv_y >= plane->height || |
|
|
|
|
|
|
|
((cell->xpos + cell->width) << 2) + mv_x >= plane->width) { |
|
|
|
|
|
|
|
av_log(ctx->avctx, AV_LOG_ERROR, |
|
|
|
|
|
|
|
"Motion vectors point out of the frame.\n"); |
|
|
|
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
offset += mv_y * plane->pitch + mv_x; |
|
|
|
offset += mv_y * plane->pitch + mv_x; |
|
|
|
ref_block = plane->pixels[ctx->buf_sel ^ 1] + offset; |
|
|
|
ref_block = plane->pixels[ctx->buf_sel ^ 1] + offset; |
|
|
|
} |
|
|
|
} |
|
|
@ -723,7 +747,7 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, |
|
|
|
const int depth, const int strip_width) |
|
|
|
const int depth, const int strip_width) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Cell curr_cell; |
|
|
|
Cell curr_cell; |
|
|
|
int bytes_used; |
|
|
|
int bytes_used, ret; |
|
|
|
|
|
|
|
|
|
|
|
if (depth <= 0) { |
|
|
|
if (depth <= 0) { |
|
|
|
av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n"); |
|
|
|
av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n"); |
|
|
@ -774,8 +798,8 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, |
|
|
|
CHECK_CELL |
|
|
|
CHECK_CELL |
|
|
|
if (!curr_cell.mv_ptr) |
|
|
|
if (!curr_cell.mv_ptr) |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
copy_cell(ctx, plane, &curr_cell); |
|
|
|
ret = copy_cell(ctx, plane, &curr_cell); |
|
|
|
return 0; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
case INTER_DATA: |
|
|
|
case INTER_DATA: |
|
|
|