static int huff_reader_build_canonical(HuffReader *r, int *code_lengths,
int alphabet_size)
{
- int len, sym, code, ret;
+ int len = 0, sym, code = 0, ret;
int max_code_length = 0;
uint16_t *codes;
+ /* special-case 1 symbol since the vlc reader cannot handle it */
+ for (sym = 0; sym < alphabet_size; sym++) {
+ if (code_lengths[sym] > 0) {
+ len++;
+ code = sym;
+ if (len > 1)
+ break;
+ }
+ }
+ if (len == 1) {
+ r->nb_symbols = 1;
+ r->simple_symbols[0] = code;
+ r->simple = 1;
+ return 0;
+ }
+
for (sym = 0; sym < alphabet_size; sym++)
max_code_length = FFMAX(max_code_length, code_lengths[sym]);
max = 0;
for (y = 0; y < img->frame->height; y++) {
for (x = 0; x < img->frame->width; x++) {
- int p = GET_PIXEL_COMP(img->frame, x, y, 2);
+ int p0 = GET_PIXEL_COMP(img->frame, x, y, 1);
+ int p1 = GET_PIXEL_COMP(img->frame, x, y, 2);
+ int p = p0 << 8 | p1;
max = FFMAX(max, p);
}
}
if (gimg->size_reduction > 0) {
int group_x = x >> gimg->size_reduction;
int group_y = y >> gimg->size_reduction;
- group = GET_PIXEL_COMP(gimg->frame, group_x, group_y, 2);
+ int g0 = GET_PIXEL_COMP(gimg->frame, group_x, group_y, 1);
+ int g1 = GET_PIXEL_COMP(gimg->frame, group_x, group_y, 2);
+ group = g0 << 8 | g1;
}
return &img->huffman_groups[group * HUFFMAN_CODES_PER_META_CODE];
length = offset + get_bits(&s->gb, extra_bits) + 1;
}
prefix_code = huff_reader_get_symbol(&hg[HUFF_IDX_DIST], &s->gb);
+ if (prefix_code > 39) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "distance prefix code too large: %d\n", prefix_code);
+ return AVERROR_INVALIDDATA;
+ }
if (prefix_code < 4) {
distance = prefix_code + 1;
} else {
unsigned int data_size, int is_alpha_chunk)
{
WebPContext *s = avctx->priv_data;
- int w, h, ret, i;
+ int w, h, ret, i, used;
if (!is_alpha_chunk) {
s->lossless = 1;
s->width, w);
}
s->height = h;
- ret = av_image_check_size(s->width, s->height, 0, avctx);
+
+ ret = ff_set_dimensions(avctx, s->width, s->height);
if (ret < 0)
return ret;
- avcodec_set_dimensions(avctx, s->width, s->height);
s->has_alpha = get_bits1(&s->gb);
/* parse transformations */
s->nb_transforms = 0;
s->reduced_width = 0;
+ used = 0;
while (get_bits1(&s->gb)) {
enum TransformType transform = get_bits(&s->gb, 2);
s->transforms[s->nb_transforms++] = transform;
+ if (used & (1 << transform)) {
+ av_log(avctx, AV_LOG_ERROR, "Transform %d used more than once\n",
+ transform);
+ ret = AVERROR_INVALIDDATA;
+ goto free_and_return;
+ }
+ used |= (1 << transform);
switch (transform) {
case PREDICTOR_TRANSFORM:
ret = parse_transform_predictor(s);
if (is_alpha_chunk)
s->image[IMAGE_ROLE_ARGB].is_alpha_primary = 1;
ret = decode_entropy_coded_image(s, IMAGE_ROLE_ARGB, w, h);
- if (ret < 0) {
- av_frame_free(&p);
+ if (ret < 0)
goto free_and_return;
- }
/* apply transformations */
for (i = s->nb_transforms - 1; i >= 0; i--) {
ret = apply_color_indexing_transform(s);
break;
}
- if (ret < 0) {
- av_frame_free(&p);
+ if (ret < 0)
goto free_and_return;
- }
}
*got_frame = 1;
return AVERROR_INVALIDDATA;
}
- while (bytestream2_get_bytes_left(&gb) > 0) {
+ while (bytestream2_get_bytes_left(&gb) > 8) {
char chunk_str[5] = { 0 };
chunk_type = bytestream2_get_le32(&gb);