]> git.sesse.net Git - ffmpeg/commitdiff
Merge commit 'c6698dfe7cdbc7634f33245875488ed3fa4a8ced'
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 3 Jul 2014 23:08:35 +0000 (01:08 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 3 Jul 2014 23:08:57 +0000 (01:08 +0200)
* commit 'c6698dfe7cdbc7634f33245875488ed3fa4a8ced':
  webpdec: Fix decoding of the huffman group indices.

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/webp.c

diff --combined libavcodec/webp.c
index 19cb1fc2236721b870f82005bc3a682ea1399611,b98fa4dea4755e2f8ad509e33ae471fc3d26ca45..c737f5492dcd79c59f50950f10fdf69806fd1ef4
@@@ -3,20 -3,20 +3,20 @@@
   * Copyright (c) 2013 Aneesh Dogra <aneesh@sugarlabs.org>
   * Copyright (c) 2013 Justin Ruggles <justin.ruggles@gmail.com>
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
   * Lossless decoder
   * Compressed alpha for lossy
   *
 + * @author James Almer <jamrial@gmail.com>
 + * Exif metadata
 + *
   * Unimplemented:
   *   - Animation
   *   - ICC profile
 - *   - Exif and XMP metadata
 + *   - XMP metadata
   */
  
  #define BITSTREAM_READER_LE
  #include "libavutil/imgutils.h"
  #include "avcodec.h"
  #include "bytestream.h"
 +#include "exif.h"
  #include "internal.h"
  #include "get_bits.h"
  #include "thread.h"
@@@ -195,8 -191,6 +195,8 @@@ typedef struct WebPContext 
      enum AlphaFilter alpha_filter;      /* filtering method for alpha chunk */
      uint8_t *alpha_data;                /* alpha chunk data */
      int alpha_data_size;                /* alpha chunk data size */
 +    int has_exif;                       /* set after an EXIF chunk has been processed */
 +    AVDictionary *exif_metadata;        /* EXIF chunk data */
      int width;                          /* image width */
      int height;                         /* image height */
      int lossless;                       /* indicates lossless or lossy */
@@@ -309,7 -303,7 +309,7 @@@ static int huff_reader_build_canonical(
      if (max_code_length == 0 || max_code_length > MAX_HUFFMAN_CODE_LENGTH)
          return AVERROR(EINVAL);
  
 -    codes = av_malloc(alphabet_size * sizeof(*codes));
 +    codes = av_malloc_array(alphabet_size, sizeof(*codes));
      if (!codes)
          return AVERROR(ENOMEM);
  
@@@ -482,7 -476,9 +482,9 @@@ static int decode_entropy_image(WebPCon
      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);
          }
      }
@@@ -567,7 -563,9 +569,9 @@@ static HuffReader *get_huffman_group(We
      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];
@@@ -1332,7 -1330,6 +1336,7 @@@ static int webp_decode_frame(AVCodecCon
      s->height    = 0;
      *got_frame   = 0;
      s->has_alpha = 0;
 +    s->has_exif  = 0;
      bytestream2_init(&gb, avpkt->data, avpkt->size);
  
      if (bytestream2_get_bytes_left(&gb) < 12)
          return AVERROR_INVALIDDATA;
      }
  
 +    av_dict_free(&s->exif_metadata);
      while (bytestream2_get_bytes_left(&gb) > 0) {
          char chunk_str[5] = { 0 };
  
  
              break;
          }
 +        case MKTAG('E', 'X', 'I', 'F'): {
 +            int le, ifd_offset, exif_offset = bytestream2_tell(&gb);
 +            GetByteContext exif_gb;
 +
 +            if (s->has_exif) {
 +                av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra EXIF chunk\n");
 +                goto exif_end;
 +            }
 +            if (!(vp8x_flags & VP8X_FLAG_EXIF_METADATA))
 +                av_log(avctx, AV_LOG_WARNING,
 +                       "EXIF chunk present, but Exif bit not set in the "
 +                       "VP8X header\n");
 +
 +            s->has_exif = 1;
 +            bytestream2_init(&exif_gb, avpkt->data + exif_offset,
 +                             avpkt->size - exif_offset);
 +            if (ff_tdecode_header(&exif_gb, &le, &ifd_offset) < 0) {
 +                av_log(avctx, AV_LOG_ERROR, "invalid TIFF header "
 +                       "in Exif data\n");
 +                goto exif_end;
 +            }
 +
 +            bytestream2_seek(&exif_gb, ifd_offset, SEEK_SET);
 +            if (avpriv_exif_decode_ifd(avctx, &exif_gb, le, 0, &s->exif_metadata) < 0) {
 +                av_log(avctx, AV_LOG_ERROR, "error decoding Exif data\n");
 +                goto exif_end;
 +            }
 +
 +            av_dict_copy(avpriv_frame_get_metadatap(data), s->exif_metadata, 0);
 +
 +exif_end:
 +            av_dict_free(&s->exif_metadata);
 +            bytestream2_skip(&gb, chunk_size);
 +            break;
 +        }
          case MKTAG('I', 'C', 'C', 'P'):
          case MKTAG('A', 'N', 'I', 'M'):
          case MKTAG('A', 'N', 'M', 'F'):
 -        case MKTAG('E', 'X', 'I', 'F'):
          case MKTAG('X', 'M', 'P', ' '):
              AV_WL32(chunk_str, chunk_type);
              av_log(avctx, AV_LOG_VERBOSE, "skipping unsupported chunk: %s\n",