#include "libavutil/imgutils.h"
#include "libavutil/intreadwrite.h"
#include "avcodec.h"
-#include "dsputil.h"
#include "bytestream.h"
#include "get_bits.h"
+#include "hpeldsp.h"
#include "internal.h"
#include "indeo3data.h"
typedef struct Indeo3DecodeContext {
AVCodecContext *avctx;
- DSPContext dsp;
+ HpelDSPContext hdsp;
GetBitContext gb;
int need_resync;
* @param plane pointer to the plane 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;
uint8_t *src, *dst;
dst = plane->pixels[ctx->buf_sel] + offset_dst;
mv_y = cell->mv_ptr[0];
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;
src = plane->pixels[ctx->buf_sel ^ 1] + offset;
/* copy using 16xH blocks */
if (!((cell->xpos << 2) & 15) && w >= 4) {
for (; w >= 4; src += 16, dst += 16, w -= 4)
- ctx->dsp.put_no_rnd_pixels_tab[0][0](dst, src, plane->pitch, h);
+ ctx->hdsp.put_pixels_tab[0][0](dst, src, plane->pitch, h);
}
/* copy using 8xH blocks */
if (!((cell->xpos << 2) & 7) && w >= 2) {
- ctx->dsp.put_no_rnd_pixels_tab[1][0](dst, src, plane->pitch, h);
+ ctx->hdsp.put_pixels_tab[1][0](dst, src, plane->pitch, h);
w -= 2;
src += 8;
dst += 8;
}
if (w >= 1) {
- ctx->dsp.put_no_rnd_pixels_tab[2][0](dst, src, plane->pitch, h);
+ ctx->hdsp.put_pixels_tab[2][0](dst, src, plane->pitch, h);
w--;
src += 4;
dst += 4;
}
}
+
+ return 0;
}
#define RLE_BLOCK_COPY \
if (cell->mv_ptr || !skip_flag) \
- ctx->dsp.put_pixels_tab[2][0](dst, ref, row_offset, 4 << v_zoom)
+ ctx->hdsp.put_pixels_tab[2][0](dst, ref, row_offset, 4 << v_zoom)
#define RLE_BLOCK_COPY_8 \
pix64 = AV_RN64A(ref);\
fill_64(dst, pix64, 8, row_offset)
#define RLE_LINES_COPY \
- ctx->dsp.put_pixels_tab[2][0](dst, ref, row_offset, num_lines << v_zoom)
+ ctx->hdsp.put_pixels_tab[2][0](dst, ref, row_offset, num_lines << v_zoom)
#define RLE_LINES_COPY_M10 \
pix64 = AV_RN64A(ref);\
} else if (mode >= 10) {
/* 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 */
- copy_cell(ctx, plane, cell);
+ int ret = copy_cell(ctx, plane, cell);
+ if (ret < 0)
+ return ret;
} else {
/* set the pointer to the reference pixels for modes 0-4 INTER */
mv_y = cell->mv_ptr[0];
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;
ref_block = plane->pixels[ctx->buf_sel ^ 1] + offset;
}
const int depth, const int strip_width)
{
Cell curr_cell;
- int bytes_used;
+ int bytes_used, ret;
if (depth <= 0) {
av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n");
CHECK_CELL
if (!curr_cell.mv_ptr)
return AVERROR_INVALIDDATA;
- copy_cell(ctx, plane, &curr_cell);
- return 0;
+ ret = copy_cell(ctx, plane, &curr_cell);
+ return ret;
}
break;
case INTER_DATA:
build_requant_tab();
- ff_dsputil_init(&ctx->dsp, avctx);
+ ff_hpeldsp_init(&ctx->hdsp, avctx->flags);
allocate_frame_buffers(ctx, avctx);