| Index: third_party/libwebp/dec/vp8l.c
 | 
| diff --git a/third_party/libwebp/dec/vp8l.c b/third_party/libwebp/dec/vp8l.c
 | 
| index 1665fe174228d80913488f15b22884eb7548b44d..89b5b4bf6e04c298999fa1afb5421a291d032a56 100644
 | 
| --- a/third_party/libwebp/dec/vp8l.c
 | 
| +++ b/third_party/libwebp/dec/vp8l.c
 | 
| @@ -1,8 +1,10 @@
 | 
|  // Copyright 2012 Google Inc. All Rights Reserved.
 | 
|  //
 | 
| -// This code is licensed under the same terms as WebM:
 | 
| -//  Software License Agreement:  http://www.webmproject.org/license/software/
 | 
| -//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
 | 
| +// Use of this source code is governed by a BSD-style license
 | 
| +// that can be found in the COPYING file in the root of the source
 | 
| +// tree. An additional intellectual property rights grant can be found
 | 
| +// in the file PATENTS. All contributing project authors may
 | 
| +// be found in the AUTHORS file in the root of the source tree.
 | 
|  // -----------------------------------------------------------------------------
 | 
|  //
 | 
|  // main entry for the decoder
 | 
| @@ -625,10 +627,24 @@ static void ApplyInverseTransforms(VP8LDecoder* const dec, int num_rows,
 | 
|    }
 | 
|  }
 | 
|  
 | 
| +// Special method for paletted alpha data.
 | 
| +static void ApplyInverseTransformsAlpha(VP8LDecoder* const dec, int num_rows,
 | 
| +                                        const uint8_t* const rows) {
 | 
| +  const int start_row = dec->last_row_;
 | 
| +  const int end_row = start_row + num_rows;
 | 
| +  const uint8_t* rows_in = rows;
 | 
| +  uint8_t* rows_out = (uint8_t*)dec->io_->opaque + dec->io_->width * start_row;
 | 
| +  VP8LTransform* const transform = &dec->transforms_[0];
 | 
| +  assert(dec->next_transform_ == 1);
 | 
| +  assert(transform->type_ == COLOR_INDEXING_TRANSFORM);
 | 
| +  VP8LColorIndexInverseTransformAlpha(transform, start_row, end_row, rows_in,
 | 
| +                                      rows_out);
 | 
| +}
 | 
| +
 | 
|  // Processes (transforms, scales & color-converts) the rows decoded after the
 | 
|  // last call.
 | 
|  static void ProcessRows(VP8LDecoder* const dec, int row) {
 | 
| -  const uint32_t* const rows = dec->argb_ + dec->width_ * dec->last_row_;
 | 
| +  const uint32_t* const rows = dec->pixels_ + dec->width_ * dec->last_row_;
 | 
|    const int num_rows = row - dec->last_row_;
 | 
|  
 | 
|    if (num_rows <= 0) return;  // Nothing to be done.
 | 
| @@ -667,121 +683,135 @@ static void ProcessRows(VP8LDecoder* const dec, int row) {
 | 
|    assert(dec->last_row_ <= dec->height_);
 | 
|  }
 | 
|  
 | 
| -static int DecodeImageData(VP8LDecoder* const dec,
 | 
| -                           uint32_t* const data, int width, int height,
 | 
| -                           ProcessRowsFunc process_func) {
 | 
| -  int ok = 1;
 | 
| -  int col = 0, row = 0;
 | 
| -  VP8LBitReader* const br = &dec->br_;
 | 
| -  VP8LMetadata* const hdr = &dec->hdr_;
 | 
| -  HTreeGroup* htree_group = hdr->htree_groups_;
 | 
| -  uint32_t* src = data;
 | 
| -  uint32_t* last_cached = data;
 | 
| -  uint32_t* const src_end = data + width * height;
 | 
| -  const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES;
 | 
| -  const int color_cache_limit = len_code_limit + hdr->color_cache_size_;
 | 
| -  VP8LColorCache* const color_cache =
 | 
| -      (hdr->color_cache_size_ > 0) ? &hdr->color_cache_ : NULL;
 | 
| -  const int mask = hdr->huffman_mask_;
 | 
| -
 | 
| -  assert(htree_group != NULL);
 | 
| -
 | 
| -  while (!br->eos_ && src < src_end) {
 | 
| -    int code;
 | 
| -    // Only update when changing tile. Note we could use the following test:
 | 
| -    //   if "((((prev_col ^ col) | prev_row ^ row)) > mask)" -> tile changed
 | 
| -    // but that's actually slower and requires storing the previous col/row
 | 
| -    if ((col & mask) == 0) {
 | 
| -      htree_group = GetHtreeGroupForPos(hdr, col, row);
 | 
| -    }
 | 
| -    VP8LFillBitWindow(br);
 | 
| -    code = ReadSymbol(&htree_group->htrees_[GREEN], br);
 | 
| -    if (code < NUM_LITERAL_CODES) {   // Literal.
 | 
| -      int red, green, blue, alpha;
 | 
| -      red = ReadSymbol(&htree_group->htrees_[RED], br);
 | 
| -      green = code;
 | 
| -      VP8LFillBitWindow(br);
 | 
| -      blue = ReadSymbol(&htree_group->htrees_[BLUE], br);
 | 
| -      alpha = ReadSymbol(&htree_group->htrees_[ALPHA], br);
 | 
| -      *src = (alpha << 24) + (red << 16) + (green << 8) + blue;
 | 
| - AdvanceByOne:
 | 
| -      ++src;
 | 
| -      ++col;
 | 
| -      if (col >= width) {
 | 
| -        col = 0;
 | 
| -        ++row;
 | 
| -        if ((process_func != NULL) && (row % NUM_ARGB_CACHE_ROWS == 0)) {
 | 
| -          process_func(dec, row);
 | 
| -        }
 | 
| -        if (color_cache != NULL) {
 | 
| -          while (last_cached < src) {
 | 
| -            VP8LColorCacheInsert(color_cache, *last_cached++);
 | 
| -          }
 | 
| -        }
 | 
| -      }
 | 
| -    } else if (code < len_code_limit) {           // Backward reference
 | 
| -      int dist_code, dist;
 | 
| -      const int length_sym = code - NUM_LITERAL_CODES;
 | 
| -      const int length = GetCopyLength(length_sym, br);
 | 
| -      const int dist_symbol = ReadSymbol(&htree_group->htrees_[DIST], br);
 | 
| -      VP8LFillBitWindow(br);
 | 
| -      dist_code = GetCopyDistance(dist_symbol, br);
 | 
| -      dist = PlaneCodeToDistance(width, dist_code);
 | 
| -      if (src - data < dist || src_end - src < length) {
 | 
| -        ok = 0;
 | 
| -        goto End;
 | 
| -      }
 | 
| -      {
 | 
| -        int i;
 | 
| -        for (i = 0; i < length; ++i) src[i] = src[i - dist];
 | 
| -        src += length;
 | 
| -      }
 | 
| -      col += length;
 | 
| -      while (col >= width) {
 | 
| -        col -= width;
 | 
| -        ++row;
 | 
| -        if ((process_func != NULL) && (row % NUM_ARGB_CACHE_ROWS == 0)) {
 | 
| -          process_func(dec, row);
 | 
| -        }
 | 
| -      }
 | 
| -      if (src < src_end) {
 | 
| -        htree_group = GetHtreeGroupForPos(hdr, col, row);
 | 
| -        if (color_cache != NULL) {
 | 
| -          while (last_cached < src) {
 | 
| -            VP8LColorCacheInsert(color_cache, *last_cached++);
 | 
| -          }
 | 
| -        }
 | 
| -      }
 | 
| -    } else if (code < color_cache_limit) {    // Color cache.
 | 
| -      const int key = code - len_code_limit;
 | 
| -      assert(color_cache != NULL);
 | 
| -      while (last_cached < src) {
 | 
| -        VP8LColorCacheInsert(color_cache, *last_cached++);
 | 
| -      }
 | 
| -      *src = VP8LColorCacheLookup(color_cache, key);
 | 
| -      goto AdvanceByOne;
 | 
| -    } else {    // Not reached.
 | 
| -      ok = 0;
 | 
| -      goto End;
 | 
| -    }
 | 
| -    ok = !br->error_;
 | 
| -    if (!ok) goto End;
 | 
| -  }
 | 
| -  // Process the remaining rows corresponding to last row-block.
 | 
| -  if (process_func != NULL) process_func(dec, row);
 | 
| +#define DECODE_DATA_FUNC(FUNC_NAME, TYPE, STORE_PIXEL)                         \
 | 
| +static int FUNC_NAME(VP8LDecoder* const dec, TYPE* const data, int width,      \
 | 
| +                     int height, ProcessRowsFunc process_func) {               \
 | 
| +  int ok = 1;                                                                  \
 | 
| +  int col = 0, row = 0;                                                        \
 | 
| +  VP8LBitReader* const br = &dec->br_;                                         \
 | 
| +  VP8LMetadata* const hdr = &dec->hdr_;                                        \
 | 
| +  HTreeGroup* htree_group = hdr->htree_groups_;                                \
 | 
| +  TYPE* src = data;                                                            \
 | 
| +  TYPE* last_cached = data;                                                    \
 | 
| +  TYPE* const src_end = data + width * height;                                 \
 | 
| +  const int len_code_limit = NUM_LITERAL_CODES + NUM_LENGTH_CODES;             \
 | 
| +  const int color_cache_limit = len_code_limit + hdr->color_cache_size_;       \
 | 
| +  VP8LColorCache* const color_cache =                                          \
 | 
| +      (hdr->color_cache_size_ > 0) ? &hdr->color_cache_ : NULL;                \
 | 
| +  const int mask = hdr->huffman_mask_;                                         \
 | 
| +  assert(htree_group != NULL);                                                 \
 | 
| +  while (!br->eos_ && src < src_end) {                                         \
 | 
| +    int code;                                                                  \
 | 
| +    /* Only update when changing tile. Note we could use this test:        */  \
 | 
| +    /* if "((((prev_col ^ col) | prev_row ^ row)) > mask)" -> tile changed */  \
 | 
| +    /* but that's actually slower and needs storing the previous col/row.  */  \
 | 
| +    if ((col & mask) == 0) {                                                   \
 | 
| +      htree_group = GetHtreeGroupForPos(hdr, col, row);                        \
 | 
| +    }                                                                          \
 | 
| +    VP8LFillBitWindow(br);                                                     \
 | 
| +    code = ReadSymbol(&htree_group->htrees_[GREEN], br);                       \
 | 
| +    if (code < NUM_LITERAL_CODES) {  /* Literal*/                              \
 | 
| +      int red, green, blue, alpha;                                             \
 | 
| +      red = ReadSymbol(&htree_group->htrees_[RED], br);                        \
 | 
| +      green = code;                                                            \
 | 
| +      VP8LFillBitWindow(br);                                                   \
 | 
| +      blue = ReadSymbol(&htree_group->htrees_[BLUE], br);                      \
 | 
| +      alpha = ReadSymbol(&htree_group->htrees_[ALPHA], br);                    \
 | 
| +      *src = STORE_PIXEL(alpha, red, green, blue);                             \
 | 
| +    AdvanceByOne:                                                              \
 | 
| +      ++src;                                                                   \
 | 
| +      ++col;                                                                   \
 | 
| +      if (col >= width) {                                                      \
 | 
| +        col = 0;                                                               \
 | 
| +        ++row;                                                                 \
 | 
| +        if ((process_func != NULL) && (row % NUM_ARGB_CACHE_ROWS == 0)) {      \
 | 
| +          process_func(dec, row);                                              \
 | 
| +        }                                                                      \
 | 
| +        if (color_cache != NULL) {                                             \
 | 
| +          while (last_cached < src) {                                          \
 | 
| +            VP8LColorCacheInsert(color_cache, *last_cached++);                 \
 | 
| +          }                                                                    \
 | 
| +        }                                                                      \
 | 
| +      }                                                                        \
 | 
| +    } else if (code < len_code_limit) {  /* Backward reference */              \
 | 
| +      int dist_code, dist;                                                     \
 | 
| +      const int length_sym = code - NUM_LITERAL_CODES;                         \
 | 
| +      const int length = GetCopyLength(length_sym, br);                        \
 | 
| +      const int dist_symbol = ReadSymbol(&htree_group->htrees_[DIST], br);     \
 | 
| +      VP8LFillBitWindow(br);                                                   \
 | 
| +      dist_code = GetCopyDistance(dist_symbol, br);                            \
 | 
| +      dist = PlaneCodeToDistance(width, dist_code);                            \
 | 
| +      if (src - data < dist || src_end - src < length) {                       \
 | 
| +        ok = 0;                                                                \
 | 
| +        goto End;                                                              \
 | 
| +      }                                                                        \
 | 
| +      {                                                                        \
 | 
| +        int i;                                                                 \
 | 
| +        for (i = 0; i < length; ++i) src[i] = src[i - dist];                   \
 | 
| +        src += length;                                                         \
 | 
| +      }                                                                        \
 | 
| +      col += length;                                                           \
 | 
| +      while (col >= width) {                                                   \
 | 
| +        col -= width;                                                          \
 | 
| +        ++row;                                                                 \
 | 
| +        if ((process_func != NULL) && (row % NUM_ARGB_CACHE_ROWS == 0)) {      \
 | 
| +          process_func(dec, row);                                              \
 | 
| +        }                                                                      \
 | 
| +      }                                                                        \
 | 
| +      if (src < src_end) {                                                     \
 | 
| +        htree_group = GetHtreeGroupForPos(hdr, col, row);                      \
 | 
| +        if (color_cache != NULL) {                                             \
 | 
| +          while (last_cached < src) {                                          \
 | 
| +            VP8LColorCacheInsert(color_cache, *last_cached++);                 \
 | 
| +          }                                                                    \
 | 
| +        }                                                                      \
 | 
| +      }                                                                        \
 | 
| +    } else if (code < color_cache_limit) {  /* Color cache */                  \
 | 
| +      const int key = code - len_code_limit;                                   \
 | 
| +      assert(color_cache != NULL);                                             \
 | 
| +      while (last_cached < src) {                                              \
 | 
| +        VP8LColorCacheInsert(color_cache, *last_cached++);                     \
 | 
| +      }                                                                        \
 | 
| +      *src = VP8LColorCacheLookup(color_cache, key);                           \
 | 
| +      goto AdvanceByOne;                                                       \
 | 
| +    } else {  /* Not reached */                                                \
 | 
| +      ok = 0;                                                                  \
 | 
| +      goto End;                                                                \
 | 
| +    }                                                                          \
 | 
| +    ok = !br->error_;                                                          \
 | 
| +    if (!ok) goto End;                                                         \
 | 
| +  }                                                                            \
 | 
| +  /* Process the remaining rows corresponding to last row-block. */            \
 | 
| +  if (process_func != NULL) process_func(dec, row);                            \
 | 
| +End:                                                                           \
 | 
| +  if (br->error_ || !ok || (br->eos_ && src < src_end)) {                      \
 | 
| +    ok = 0;                                                                    \
 | 
| +    dec->status_ =                                                             \
 | 
| +        (!br->eos_) ? VP8_STATUS_BITSTREAM_ERROR : VP8_STATUS_SUSPENDED;       \
 | 
| +  } else if (src == src_end) {                                                 \
 | 
| +    dec->state_ = READ_DATA;                                                   \
 | 
| +  }                                                                            \
 | 
| +  return ok;                                                                   \
 | 
| +}
 | 
|  
 | 
| - End:
 | 
| -  if (br->error_ || !ok || (br->eos_ && src < src_end)) {
 | 
| -    ok = 0;
 | 
| -    dec->status_ = (!br->eos_) ?
 | 
| -        VP8_STATUS_BITSTREAM_ERROR : VP8_STATUS_SUSPENDED;
 | 
| -  } else if (src == src_end) {
 | 
| -    dec->state_ = READ_DATA;
 | 
| -  }
 | 
| +static WEBP_INLINE uint32_t GetARGBPixel(int alpha, int red, int green,
 | 
| +                                         int blue) {
 | 
| +  return (alpha << 24) | (red << 16) | (green << 8) | blue;
 | 
| +}
 | 
|  
 | 
| -  return ok;
 | 
| +static WEBP_INLINE uint8_t GetAlphaPixel(int alpha, int red, int green,
 | 
| +                                         int blue) {
 | 
| +  (void)alpha;
 | 
| +  (void)red;
 | 
| +  (void)blue;
 | 
| +  return green;  // Alpha value is stored in green channel.
 | 
|  }
 | 
|  
 | 
| +DECODE_DATA_FUNC(DecodeImageData, uint32_t, GetARGBPixel)
 | 
| +DECODE_DATA_FUNC(DecodeAlphaData, uint8_t, GetAlphaPixel)
 | 
| +
 | 
| +#undef DECODE_DATA_FUNC
 | 
| +
 | 
|  // -----------------------------------------------------------------------------
 | 
|  // VP8LTransform
 | 
|  
 | 
| @@ -903,8 +933,8 @@ void VP8LClear(VP8LDecoder* const dec) {
 | 
|    if (dec == NULL) return;
 | 
|    ClearMetadata(&dec->hdr_);
 | 
|  
 | 
| -  free(dec->argb_);
 | 
| -  dec->argb_ = NULL;
 | 
| +  free(dec->pixels_);
 | 
| +  dec->pixels_ = NULL;
 | 
|    for (i = 0; i < dec->next_transform_; ++i) {
 | 
|      ClearTransform(&dec->transforms_[i]);
 | 
|    }
 | 
| @@ -1028,35 +1058,39 @@ static int DecodeImageStream(int xsize, int ysize,
 | 
|  }
 | 
|  
 | 
|  //------------------------------------------------------------------------------
 | 
| -// Allocate dec->argb_ and dec->argb_cache_ using dec->width_ and dec->height_
 | 
| -
 | 
| -static int AllocateARGBBuffers(VP8LDecoder* const dec, int final_width) {
 | 
| +// Allocate internal buffers dec->pixels_ and dec->argb_cache_.
 | 
| +static int AllocateInternalBuffers(VP8LDecoder* const dec, int final_width,
 | 
| +                                   size_t bytes_per_pixel) {
 | 
| +  const int argb_cache_needed = (bytes_per_pixel == sizeof(uint32_t));
 | 
|    const uint64_t num_pixels = (uint64_t)dec->width_ * dec->height_;
 | 
|    // Scratch buffer corresponding to top-prediction row for transforming the
 | 
| -  // first row in the row-blocks.
 | 
| -  const uint64_t cache_top_pixels = final_width;
 | 
| -  // Scratch buffer for temporary BGRA storage.
 | 
| -  const uint64_t cache_pixels = (uint64_t)final_width * NUM_ARGB_CACHE_ROWS;
 | 
| +  // first row in the row-blocks. Not needed for paletted alpha.
 | 
| +  const uint64_t cache_top_pixels =
 | 
| +      argb_cache_needed ? (uint16_t)final_width : 0ULL;
 | 
| +  // Scratch buffer for temporary BGRA storage. Not needed for paletted alpha.
 | 
| +  const uint64_t cache_pixels =
 | 
| +      argb_cache_needed ? (uint64_t)final_width * NUM_ARGB_CACHE_ROWS : 0ULL;
 | 
|    const uint64_t total_num_pixels =
 | 
|        num_pixels + cache_top_pixels + cache_pixels;
 | 
|  
 | 
|    assert(dec->width_ <= final_width);
 | 
| -  dec->argb_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, sizeof(*dec->argb_));
 | 
| -  if (dec->argb_ == NULL) {
 | 
| +  dec->pixels_ = (uint32_t*)WebPSafeMalloc(total_num_pixels, bytes_per_pixel);
 | 
| +  if (dec->pixels_ == NULL) {
 | 
|      dec->argb_cache_ = NULL;    // for sanity check
 | 
|      dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
 | 
|      return 0;
 | 
|    }
 | 
| -  dec->argb_cache_ = dec->argb_ + num_pixels + cache_top_pixels;
 | 
| +  dec->argb_cache_ =
 | 
| +      argb_cache_needed ? dec->pixels_ + num_pixels + cache_top_pixels : NULL;
 | 
|    return 1;
 | 
|  }
 | 
|  
 | 
|  //------------------------------------------------------------------------------
 | 
| -// Special row-processing that only stores the alpha data.
 | 
|  
 | 
| +// Special row-processing that only stores the alpha data.
 | 
|  static void ExtractAlphaRows(VP8LDecoder* const dec, int row) {
 | 
|    const int num_rows = row - dec->last_row_;
 | 
| -  const uint32_t* const in = dec->argb_ + dec->width_ * dec->last_row_;
 | 
| +  const uint32_t* const in = dec->pixels_ + dec->width_ * dec->last_row_;
 | 
|  
 | 
|    if (num_rows <= 0) return;  // Nothing to be done.
 | 
|    ApplyInverseTransforms(dec, num_rows, in);
 | 
| @@ -1070,7 +1104,17 @@ static void ExtractAlphaRows(VP8LDecoder* const dec, int row) {
 | 
|      int i;
 | 
|      for (i = 0; i < cache_pixs; ++i) dst[i] = (src[i] >> 8) & 0xff;
 | 
|    }
 | 
| +  dec->last_row_ = dec->last_out_row_ = row;
 | 
| +}
 | 
|  
 | 
| +// Row-processing for the special case when alpha data contains only one
 | 
| +// transform: color indexing.
 | 
| +static void ExtractPalettedAlphaRows(VP8LDecoder* const dec, int row) {
 | 
| +  const int num_rows = row - dec->last_row_;
 | 
| +  const uint8_t* const in =
 | 
| +      (uint8_t*)dec->pixels_ + dec->width_ * dec->last_row_;
 | 
| +  if (num_rows <= 0) return;  // Nothing to be done.
 | 
| +  ApplyInverseTransformsAlpha(dec, num_rows, in);
 | 
|    dec->last_row_ = dec->last_out_row_ = row;
 | 
|  }
 | 
|  
 | 
| @@ -1079,6 +1123,7 @@ int VP8LDecodeAlphaImageStream(int width, int height, const uint8_t* const data,
 | 
|    VP8Io io;
 | 
|    int ok = 0;
 | 
|    VP8LDecoder* const dec = VP8LNew();
 | 
| +  size_t bytes_per_pixel = sizeof(uint32_t);  // Default: BGRA mode.
 | 
|    if (dec == NULL) return 0;
 | 
|  
 | 
|    dec->width_ = width;
 | 
| @@ -1097,13 +1142,25 @@ int VP8LDecodeAlphaImageStream(int width, int height, const uint8_t* const data,
 | 
|    dec->action_ = READ_HDR;
 | 
|    if (!DecodeImageStream(width, height, 1, dec, NULL)) goto Err;
 | 
|  
 | 
| -  // Allocate output (note that dec->width_ may have changed here).
 | 
| -  if (!AllocateARGBBuffers(dec, width)) goto Err;
 | 
| +  // Special case: if alpha data uses only the color indexing transform and
 | 
| +  // doesn't use color cache (a frequent case), we will use DecodeAlphaData()
 | 
| +  // method that only needs allocation of 1 byte per pixel (alpha channel).
 | 
| +  if (dec->next_transform_ == 1 &&
 | 
| +      dec->transforms_[0].type_ == COLOR_INDEXING_TRANSFORM &&
 | 
| +      dec->hdr_.color_cache_size_ == 0) {
 | 
| +    bytes_per_pixel = sizeof(uint8_t);
 | 
| +  }
 | 
| +
 | 
| +  // Allocate internal buffers (note that dec->width_ may have changed here).
 | 
| +  if (!AllocateInternalBuffers(dec, width, bytes_per_pixel)) goto Err;
 | 
|  
 | 
|    // Decode (with special row processing).
 | 
|    dec->action_ = READ_DATA;
 | 
| -  ok = DecodeImageData(dec, dec->argb_, dec->width_, dec->height_,
 | 
| -                       ExtractAlphaRows);
 | 
| +  ok = (bytes_per_pixel == sizeof(uint8_t)) ?
 | 
| +      DecodeAlphaData(dec, (uint8_t*)dec->pixels_, dec->width_, dec->height_,
 | 
| +                      ExtractPalettedAlphaRows) :
 | 
| +      DecodeImageData(dec, dec->pixels_, dec->width_, dec->height_,
 | 
| +                      ExtractAlphaRows);
 | 
|  
 | 
|   Err:
 | 
|    VP8LDelete(dec);
 | 
| @@ -1143,6 +1200,7 @@ int VP8LDecodeHeader(VP8LDecoder* const dec, VP8Io* const io) {
 | 
|  }
 | 
|  
 | 
|  int VP8LDecodeImage(VP8LDecoder* const dec) {
 | 
| +  const size_t bytes_per_pixel = sizeof(uint32_t);
 | 
|    VP8Io* io = NULL;
 | 
|    WebPDecParams* params = NULL;
 | 
|  
 | 
| @@ -1162,13 +1220,13 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
 | 
|      goto Err;
 | 
|    }
 | 
|  
 | 
| -  if (!AllocateARGBBuffers(dec, io->width)) goto Err;
 | 
| +  if (!AllocateInternalBuffers(dec, io->width, bytes_per_pixel)) goto Err;
 | 
|  
 | 
|    if (io->use_scaling && !AllocateAndInitRescaler(dec, io)) goto Err;
 | 
|  
 | 
|    // Decode.
 | 
|    dec->action_ = READ_DATA;
 | 
| -  if (!DecodeImageData(dec, dec->argb_, dec->width_, dec->height_,
 | 
| +  if (!DecodeImageData(dec, dec->pixels_, dec->width_, dec->height_,
 | 
|                         ProcessRows)) {
 | 
|      goto Err;
 | 
|    }
 | 
| 
 |