#include "ivi_common.h"
#include "ivi_dsp.h"
-extern const IVIHuffDesc ff_ivi_mb_huff_desc[8]; ///< static macroblock huffman tables
-extern const IVIHuffDesc ff_ivi_blk_huff_desc[8]; ///< static block huffman tables
+/**
+ * These are 2x8 predefined Huffman codebooks for coding macroblock/block
+ * signals. They are specified using "huffman descriptors" in order to
+ * avoid huge static tables. The decoding tables will be generated at
+ * startup from these descriptors.
+ */
+/** static macroblock huffman tables */
+static const IVIHuffDesc ivi_mb_huff_desc[8] = {
+ {8, {0, 4, 5, 4, 4, 4, 6, 6}},
+ {12, {0, 2, 2, 3, 3, 3, 3, 5, 3, 2, 2, 2}},
+ {12, {0, 2, 3, 4, 3, 3, 3, 3, 4, 3, 2, 2}},
+ {12, {0, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2}},
+ {13, {0, 4, 4, 3, 3, 3, 3, 2, 3, 3, 2, 1, 1}},
+ {9, {0, 4, 4, 4, 4, 3, 3, 3, 2}},
+ {10, {0, 4, 4, 4, 4, 3, 3, 2, 2, 2}},
+ {12, {0, 4, 4, 4, 3, 3, 2, 3, 2, 2, 2, 2}}
+};
+
+/** static block huffman tables */
+static const IVIHuffDesc ivi_blk_huff_desc[8] = {
+ {10, {1, 2, 3, 4, 4, 7, 5, 5, 4, 1}},
+ {11, {2, 3, 4, 4, 4, 7, 5, 4, 3, 3, 2}},
+ {12, {2, 4, 5, 5, 5, 5, 6, 4, 4, 3, 1, 1}},
+ {13, {3, 3, 4, 4, 5, 6, 6, 4, 4, 3, 2, 1, 1}},
+ {11, {3, 4, 4, 5, 5, 5, 6, 5, 4, 2, 2}},
+ {13, {3, 4, 5, 5, 5, 5, 6, 4, 3, 3, 2, 1, 1}},
+ {13, {3, 4, 5, 5, 5, 6, 5, 4, 3, 3, 2, 1, 1}},
+ {9, {3, 4, 4, 5, 5, 5, 6, 5, 5}}
+};
static VLC ivi_mb_vlc_tabs [8]; ///< static macroblock Huffman tables
static VLC ivi_blk_vlc_tabs[8]; ///< static block Huffman tables
typedef void (*ivi_mc_func) (int16_t *buf, const int16_t *ref_buf,
uint32_t pitch, int mc_type);
+static int ivi_mc(IVIBandDesc *band, ivi_mc_func mc,
+ int offs, int mv_x, int mv_y, int mc_type)
+{
+ int ref_offs = offs + mv_y * band->pitch + mv_x;
+ int buf_size = band->pitch * band->aheight;
+ int min_size = band->pitch * (band->blk_size - 1) + band->blk_size;
+ int ref_size = (mc_type > 1) * band->pitch + (mc_type & 1);
+
+ if (offs < 0 || ref_offs < 0 || !band->ref_buf)
+ return AVERROR_INVALIDDATA;
+ if (buf_size - min_size < offs)
+ return AVERROR_INVALIDDATA;
+ if (buf_size - min_size - ref_size < ref_offs)
+ return AVERROR_INVALIDDATA;
+
+ mc(band->buf + offs, band->ref_buf + ref_offs, band->pitch, mc_type);
+
+ return 0;
+}
+
/**
* Reverse "nbits" bits of the value "val" and return the result
* in the least significant bits.
for (i = 0; i < 8; i++) {
ivi_mb_vlc_tabs[i].table = table_data + i * 2 * 8192;
ivi_mb_vlc_tabs[i].table_allocated = 8192;
- ivi_create_huff_from_desc(&ff_ivi_mb_huff_desc[i],
+ ivi_create_huff_from_desc(&ivi_mb_huff_desc[i],
&ivi_mb_vlc_tabs[i], 1);
ivi_blk_vlc_tabs[i].table = table_data + (i * 2 + 1) * 8192;
ivi_blk_vlc_tabs[i].table_allocated = 8192;
- ivi_create_huff_from_desc(&ff_ivi_blk_huff_desc[i],
+ ivi_create_huff_from_desc(&ivi_blk_huff_desc[i],
&ivi_blk_vlc_tabs[i], 1);
}
initialized_vlcs = 1;
av_freep(&planes[p].bands[b].tiles);
}
av_freep(&planes[p].bands);
+ planes[p].num_bands = 0;
}
}
ivi_free_buffers(planes);
+ if (cfg->pic_width < 1 || cfg->pic_height < 1 ||
+ cfg->luma_bands < 1 || cfg->chroma_bands < 1)
+ return AVERROR_INVALIDDATA;
+
/* fill in the descriptor of the luminance plane */
planes[0].width = cfg->pic_width;
planes[0].height = cfg->pic_height;
tile->ref_mbs = 0;
if (p || b) {
+ if (tile->num_MBs != ref_tile->num_MBs)
+ return AVERROR_INVALIDDATA;
tile->ref_mbs = ref_tile->mbs;
ref_tile++;
}
return len;
}
+static int ivi_dc_transform(IVIBandDesc *band, int *prev_dc, int buf_offs,
+ int blk_size)
+{
+ int buf_size = band->pitch * band->aheight - buf_offs;
+ int min_size = (blk_size - 1) * band->pitch + blk_size;
+
+ if (!band->dc_transform)
+ return 0;
+
+
+ if (min_size > buf_size)
+ return AVERROR_INVALIDDATA;
+
+ band->dc_transform(prev_dc, band->buf + buf_offs,
+ band->pitch, blk_size);
+
+ return 0;
+}
static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band,
ivi_mc_func mc, int mv_x, int mv_y,
int num_coeffs = blk_size * blk_size;
int col_mask = blk_size - 1;
int scan_pos = -1;
+ int min_size = band->pitch * (band->transform_size - 1) +
+ band->transform_size;
+ int buf_size = band->pitch * band->aheight - offs;
+
+ if (min_size > buf_size)
+ return AVERROR_INVALIDDATA;
if (!band->scan) {
av_log(avctx, AV_LOG_ERROR, "Scan pattern is not set.\n");
/* de-zigzag and dequantize */
scan_pos += run;
- if (scan_pos >= num_coeffs)
+ if (scan_pos >= num_coeffs || scan_pos < 0)
break;
pos = band->scan[scan_pos];
col_flags[pos & col_mask] |= !!val;
}
- if (scan_pos >= num_coeffs && sym != rvmap->eob_sym)
+ if (scan_pos < 0 || scan_pos >= num_coeffs && sym != rvmap->eob_sym)
return AVERROR_INVALIDDATA; /* corrupt block data */
/* undoing DC coeff prediction for intra-blocks */
/* apply motion compensation */
if (!is_intra)
- mc(band->buf + offs,
- band->ref_buf + offs + mv_y * band->pitch + mv_x,
- band->pitch, mc_type);
+ return ivi_mc(band, mc, offs, mv_x, mv_y, mc_type);
return 0;
}
/* for intra blocks apply the dc slant transform */
/* for inter - perform the motion compensation without delta */
if (is_intra) {
- if (band->dc_transform)
- band->dc_transform(&prev_dc, band->buf + buf_offs,
- band->pitch, blk_size);
- } else
- mc_no_delta_func(band->buf + buf_offs,
- band->ref_buf + buf_offs + mv_y * band->pitch + mv_x,
- band->pitch, mc_type);
+ ret = ivi_dc_transform(band, &prev_dc, buf_offs, blk_size);
+ if (ret < 0)
+ return ret;
+ } else {
+ ret = ivi_mc(band, mc_no_delta_func, buf_offs,
+ mv_x, mv_y, mc_type);
+ if (ret < 0)
+ return ret;
+ }
}
cbp >>= 1;
IVITile *tile, int32_t mv_scale)
{
int x, y, need_mc, mbn, blk, num_blocks, mv_x, mv_y, mc_type;
- int offs, mb_offset, row_offset;
+ int offs, mb_offset, row_offset, ret;
IVIMbInfo *mb, *ref_mb;
const int16_t *src;
int16_t *dst;
for (blk = 0; blk < num_blocks; blk++) {
/* adjust block position in the buffer according with its number */
offs = mb->buf_offs + band->blk_size * ((blk & 1) + !!(blk & 2) * band->pitch);
- mc_no_delta_func(band->buf + offs,
- band->ref_buf + offs + mv_y * band->pitch + mv_x,
- band->pitch, mc_type);
+ ret = ivi_mc(band, mc_no_delta_func, offs,
+ mv_x, mv_y, mc_type);
+ if (ret < 0)
+ return ret;
}
}
} else {
return AVERROR_PATCHWELCOME;
}
+ if (!ctx->planes[0].bands) {
+ av_log(avctx, AV_LOG_ERROR, "Color planes not initialized yet\n");
+ return AVERROR_INVALIDDATA;
+ }
+
ctx->switch_buffers(ctx);
//{ START_TIMER;
}
}
}
+ } else {
+ if (ctx->is_scalable)
+ return AVERROR_INVALIDDATA;
+
+ for (p = 0; p < 3; p++) {
+ if (!ctx->planes[p].bands[0].buf)
+ return AVERROR_INVALIDDATA;
+ }
}
//STOP_TIMER("decode_planes"); }
av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n");
}
- avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height);
+ result = ff_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height);
+ if (result < 0)
+ return result;
+
if ((result = ff_get_buffer(avctx, frame, 0)) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return result;
}
-/**
- * These are 2x8 predefined Huffman codebooks for coding macroblock/block
- * signals. They are specified using "huffman descriptors" in order to
- * avoid huge static tables. The decoding tables will be generated at
- * startup from these descriptors.
- */
-const IVIHuffDesc ff_ivi_mb_huff_desc[8] = {
- {8, {0, 4, 5, 4, 4, 4, 6, 6}},
- {12, {0, 2, 2, 3, 3, 3, 3, 5, 3, 2, 2, 2}},
- {12, {0, 2, 3, 4, 3, 3, 3, 3, 4, 3, 2, 2}},
- {12, {0, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2}},
- {13, {0, 4, 4, 3, 3, 3, 3, 2, 3, 3, 2, 1, 1}},
- {9, {0, 4, 4, 4, 4, 3, 3, 3, 2}},
- {10, {0, 4, 4, 4, 4, 3, 3, 2, 2, 2}},
- {12, {0, 4, 4, 4, 3, 3, 2, 3, 2, 2, 2, 2}}
-};
-
-const IVIHuffDesc ff_ivi_blk_huff_desc[8] = {
- {10, {1, 2, 3, 4, 4, 7, 5, 5, 4, 1}},
- {11, {2, 3, 4, 4, 4, 7, 5, 4, 3, 3, 2}},
- {12, {2, 4, 5, 5, 5, 5, 6, 4, 4, 3, 1, 1}},
- {13, {3, 3, 4, 4, 5, 6, 6, 4, 4, 3, 2, 1, 1}},
- {11, {3, 4, 4, 5, 5, 5, 6, 5, 4, 2, 2}},
- {13, {3, 4, 5, 5, 5, 5, 6, 4, 3, 3, 2, 1, 1}},
- {13, {3, 4, 5, 5, 5, 6, 5, 4, 3, 3, 2, 1, 1}},
- {9, {3, 4, 4, 5, 5, 5, 6, 5, 5}}
-};
-
-
/**
* Scan patterns shared between indeo4 and indeo5
*/