else {
int i, e, a;
e = 0;
- while (get_rac(c, state + 1 + FFMIN(e, 9))) // 1..10
+ while (get_rac(c, state + 1 + FFMIN(e, 9))) { // 1..10
e++;
+ if (e > 31)
+ return AVERROR_INVALIDDATA;
+ }
a = 1;
for (i = e - 1; i >= 0; i--)
for (i = 0; i < f->plane_count; i++) {
PlaneContext * const p = &fs->plane[i];
int idx = get_symbol(c, state, 0);
- if (idx > (unsigned)f->quant_table_count) {
+ if (idx >= (unsigned)f->quant_table_count) {
av_log(f->avctx, AV_LOG_ERROR, "quant_table_index out of range\n");
return -1;
}
FFV1Context *fs = *(void **)arg;
FFV1Context *f = fs->avctx->priv_data;
int width, height, x, y, ret;
- const int ps = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step_minus1 + 1;
+ const int ps = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step;
AVFrame * const p = f->cur;
int i, si;
int context_count = 1;
for (i = 0; i < 5; i++) {
- context_count *= read_quant_table(c, quant_table[i], context_count);
+ int ret = read_quant_table(c, quant_table[i], context_count);
+ if (ret < 0)
+ return ret;
+ context_count *= ret;
if (context_count > 32768U) {
return AVERROR_INVALIDDATA;
}
av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n");
return AVERROR_INVALIDDATA;
}
+ f->slice_count = f->max_slice_count;
} else if (f->version < 3) {
f->slice_count = get_symbol(c, state, 0);
} else {
p -= size + trailer;
}
}
- if (f->slice_count > (unsigned)MAX_SLICES || f->slice_count <= 0) {
- av_log(f->avctx, AV_LOG_ERROR, "slice count %d is invalid\n", f->slice_count);
+ if (f->slice_count > (unsigned)MAX_SLICES || f->slice_count <= 0 || f->slice_count > f->max_slice_count) {
+ av_log(f->avctx, AV_LOG_ERROR, "slice count %d is invalid (max=%d)\n", f->slice_count, f->max_slice_count);
return AVERROR_INVALIDDATA;
}
FFV1Context *fs = f->slice_context[i];
int j;
if (fs->slice_damaged && f->last_picture.f->data[0]) {
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
const uint8_t *src[4];
uint8_t *dst[4];
ff_thread_await_progress(&f->last_picture, INT_MAX, 0);
for (j = 0; j < 4; j++) {
+ int pixshift = desc->comp[j].depth > 8;
int sh = (j == 1 || j == 2) ? f->chroma_h_shift : 0;
int sv = (j == 1 || j == 2) ? f->chroma_v_shift : 0;
dst[j] = p->data[j] + p->linesize[j] *
- (fs->slice_y >> sv) + (fs->slice_x >> sh);
+ (fs->slice_y >> sv) + ((fs->slice_x >> sh) << pixshift);
src[j] = f->last_picture.f->data[j] + f->last_picture.f->linesize[j] *
- (fs->slice_y >> sv) + (fs->slice_x >> sh);
+ (fs->slice_y >> sv) + ((fs->slice_x >> sh) << pixshift);
}
av_image_copy(dst, p->linesize, src,
f->last_picture.f->linesize,
f->picture.f = NULL;
f->last_picture.f = NULL;
f->sample_buffer = NULL;
+ f->max_slice_count = 0;
f->slice_count = 0;
for (i = 0; i < f->quant_table_count; i++) {
av_assert0(!fdst->sample_buffer);
}
- av_assert1(fdst->slice_count == fsrc->slice_count);
+ av_assert1(fdst->max_slice_count == fsrc->max_slice_count);
ff_thread_release_buffer(dst, &fdst->picture);