15a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// Copyright 2012 Google Inc. All Rights Reserved.
25a50414796e9a458925c7a13a15055d02406bf43Vikas Arora//
35a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// This code is licensed under the same terms as WebM:
45a50414796e9a458925c7a13a15055d02406bf43Vikas Arora//  Software License Agreement:  http://www.webmproject.org/license/software/
55a50414796e9a458925c7a13a15055d02406bf43Vikas Arora//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
65a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// -----------------------------------------------------------------------------
75a50414796e9a458925c7a13a15055d02406bf43Vikas Arora//
85a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// main entry for the lossless encoder.
95a50414796e9a458925c7a13a15055d02406bf43Vikas Arora//
105a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// Author: Vikas Arora (vikaas.arora@gmail.com)
115a50414796e9a458925c7a13a15055d02406bf43Vikas Arora//
125a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
135a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#include <assert.h>
145a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#include <stdio.h>
155a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#include <stdlib.h>
165a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
175a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#include "./backward_references.h"
185a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#include "./vp8enci.h"
195a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#include "./vp8li.h"
205a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#include "../dsp/lossless.h"
215a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#include "../utils/bit_writer.h"
225a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#include "../utils/huffman_encode.h"
235a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#include "../utils/utils.h"
245a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#include "webp/format_constants.h"
255a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
265a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#if defined(__cplusplus) || defined(c_plusplus)
275a50414796e9a458925c7a13a15055d02406bf43Vikas Aroraextern "C" {
285a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#endif
295a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
305a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#define PALETTE_KEY_RIGHT_SHIFT   22  // Key for 1K buffer.
315a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#define MAX_HUFF_IMAGE_SIZE       (16 * 1024 * 1024)
325a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#define MAX_COLORS_FOR_GRAPH      64
335a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
345a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// -----------------------------------------------------------------------------
355a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// Palette
365a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
375a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic int CompareColors(const void* p1, const void* p2) {
385a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const uint32_t a = *(const uint32_t*)p1;
395a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const uint32_t b = *(const uint32_t*)p2;
405a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return (a < b) ? -1 : (a > b) ? 1 : 0;
415a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
425a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
435a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// If number of colors in the image is less than or equal to MAX_PALETTE_SIZE,
445a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// creates a palette and returns true, else returns false.
455a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic int AnalyzeAndCreatePalette(const WebPPicture* const pic,
465a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                   uint32_t palette[MAX_PALETTE_SIZE],
475a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                   int* const palette_size) {
485a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int i, x, y, key;
495a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int num_colors = 0;
505a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  uint8_t in_use[MAX_PALETTE_SIZE * 4] = { 0 };
515a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  uint32_t colors[MAX_PALETTE_SIZE * 4];
525a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  static const uint32_t kHashMul = 0x1e35a7bd;
535a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const uint32_t* argb = pic->argb;
545a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int width = pic->width;
555a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int height = pic->height;
565a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  uint32_t last_pix = ~argb[0];   // so we're sure that last_pix != argb[0]
575a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
585a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  for (y = 0; y < height; ++y) {
595a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    for (x = 0; x < width; ++x) {
605a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      if (argb[x] == last_pix) {
615a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        continue;
625a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      }
635a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      last_pix = argb[x];
645a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      key = (kHashMul * last_pix) >> PALETTE_KEY_RIGHT_SHIFT;
655a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      while (1) {
665a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        if (!in_use[key]) {
675a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          colors[key] = last_pix;
685a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          in_use[key] = 1;
695a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          ++num_colors;
705a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          if (num_colors > MAX_PALETTE_SIZE) {
715a50414796e9a458925c7a13a15055d02406bf43Vikas Arora            return 0;
725a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          }
735a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          break;
745a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        } else if (colors[key] == last_pix) {
755a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          // The color is already there.
765a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          break;
775a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        } else {
785a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          // Some other color sits there.
795a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          // Do linear conflict resolution.
805a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          ++key;
815a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          key &= (MAX_PALETTE_SIZE * 4 - 1);  // key mask for 1K buffer.
825a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        }
835a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      }
845a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
855a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    argb += pic->argb_stride;
865a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
875a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
885a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // TODO(skal): could we reuse in_use[] to speed up ApplyPalette()?
895a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  num_colors = 0;
905a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  for (i = 0; i < (int)(sizeof(in_use) / sizeof(in_use[0])); ++i) {
915a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (in_use[i]) {
925a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      palette[num_colors] = colors[i];
935a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      ++num_colors;
945a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
955a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
965a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
975a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  qsort(palette, num_colors, sizeof(*palette), CompareColors);
985a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  *palette_size = num_colors;
995a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return 1;
1005a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
1015a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
1025a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic int AnalyzeEntropy(const uint32_t* argb,
1035a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                          int width, int height, int argb_stride,
1045a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                          double* const nonpredicted_bits,
1055a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                          double* const predicted_bits) {
1065a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int x, y;
1075a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const uint32_t* last_line = NULL;
1085a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  uint32_t last_pix = argb[0];    // so we're sure that pix_diff == 0
1095a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
1105a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LHistogram* nonpredicted = NULL;
1115a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LHistogram* predicted =
1125a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      (VP8LHistogram*)malloc(2 * sizeof(*predicted));
1135a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (predicted == NULL) return 0;
1145a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  nonpredicted = predicted + 1;
1155a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
1165a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LHistogramInit(predicted, 0);
1175a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LHistogramInit(nonpredicted, 0);
1185a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  for (y = 0; y < height; ++y) {
1195a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    for (x = 0; x < width; ++x) {
1205a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      const uint32_t pix = argb[x];
1215a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      const uint32_t pix_diff = VP8LSubPixels(pix, last_pix);
1225a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      if (pix_diff == 0) continue;
1235a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      if (last_line != NULL && pix == last_line[x]) {
1245a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        continue;
1255a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      }
1265a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      last_pix = pix;
1275a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      {
1285a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        const PixOrCopy pix_token = PixOrCopyCreateLiteral(pix);
1295a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        const PixOrCopy pix_diff_token = PixOrCopyCreateLiteral(pix_diff);
1305a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        VP8LHistogramAddSinglePixOrCopy(nonpredicted, &pix_token);
1315a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        VP8LHistogramAddSinglePixOrCopy(predicted, &pix_diff_token);
1325a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      }
1335a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
1345a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    last_line = argb;
1355a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    argb += argb_stride;
1365a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
1375a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  *nonpredicted_bits = VP8LHistogramEstimateBitsBulk(nonpredicted);
1385a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  *predicted_bits = VP8LHistogramEstimateBitsBulk(predicted);
1395a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  free(predicted);
1405a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return 1;
1415a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
1425a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
1435a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic int VP8LEncAnalyze(VP8LEncoder* const enc, WebPImageHint image_hint) {
1445a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const WebPPicture* const pic = enc->pic_;
1455a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  assert(pic != NULL && pic->argb != NULL);
1465a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
1475a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  enc->use_palette_ =
1485a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      AnalyzeAndCreatePalette(pic, enc->palette_, &enc->palette_size_);
1495a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
1505a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (image_hint == WEBP_HINT_GRAPH) {
1515a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (enc->use_palette_ && enc->palette_size_ < MAX_COLORS_FOR_GRAPH) {
1525a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      enc->use_palette_ = 0;
1535a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
1545a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
1555a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
1565a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!enc->use_palette_) {
1575a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (image_hint == WEBP_HINT_PHOTO) {
1585a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      enc->use_predict_ = 1;
1595a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      enc->use_cross_color_ = 1;
1605a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    } else {
1615a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      double non_pred_entropy, pred_entropy;
1625a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      if (!AnalyzeEntropy(pic->argb, pic->width, pic->height, pic->argb_stride,
1635a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                          &non_pred_entropy, &pred_entropy)) {
1645a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        return 0;
1655a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      }
1665a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      if (pred_entropy < 0.95 * non_pred_entropy) {
1675a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        enc->use_predict_ = 1;
1685a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        // TODO(vikasa): Observed some correlation of cross_color transform with
1695a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        // predict. Need to investigate this further and add separate heuristic
1705a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        // for setting use_cross_color flag.
1715a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        enc->use_cross_color_ = 1;
1725a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      }
1735a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
1745a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
1755a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
1765a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return 1;
1775a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
1785a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
1795a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic int GetHuffBitLengthsAndCodes(
1805a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const VP8LHistogramSet* const histogram_image,
1815a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    HuffmanTreeCode* const huffman_codes) {
1825a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int i, k;
1835a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int ok = 1;
1845a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  uint64_t total_length_size = 0;
1855a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  uint8_t* mem_buf = NULL;
1865a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int histogram_image_size = histogram_image->size;
1875a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
1885a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Iterate over all histograms and get the aggregate number of codes used.
1895a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  for (i = 0; i < histogram_image_size; ++i) {
1905a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const VP8LHistogram* const histo = histogram_image->histograms[i];
1915a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    HuffmanTreeCode* const codes = &huffman_codes[5 * i];
1925a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    for (k = 0; k < 5; ++k) {
1935a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      const int num_symbols = (k == 0) ? VP8LHistogramNumCodes(histo)
1945a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                            : (k == 4) ? NUM_DISTANCE_CODES
1955a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                            : 256;
1965a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      codes[k].num_symbols = num_symbols;
1975a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      total_length_size += num_symbols;
1985a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
1995a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
2005a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
2015a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Allocate and Set Huffman codes.
2025a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  {
2035a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    uint16_t* codes;
2045a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    uint8_t* lengths;
2055a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    mem_buf = (uint8_t*)WebPSafeCalloc(total_length_size,
2065a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                       sizeof(*lengths) + sizeof(*codes));
2075a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (mem_buf == NULL) {
2085a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      ok = 0;
2095a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      goto End;
2105a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
2115a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    codes = (uint16_t*)mem_buf;
2125a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    lengths = (uint8_t*)&codes[total_length_size];
2135a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    for (i = 0; i < 5 * histogram_image_size; ++i) {
2145a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      const int bit_length = huffman_codes[i].num_symbols;
2155a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      huffman_codes[i].codes = codes;
2165a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      huffman_codes[i].code_lengths = lengths;
2175a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      codes += bit_length;
2185a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      lengths += bit_length;
2195a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
2205a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
2215a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
2225a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Create Huffman trees.
2235a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  for (i = 0; i < histogram_image_size; ++i) {
2245a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    HuffmanTreeCode* const codes = &huffman_codes[5 * i];
2255a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    VP8LHistogram* const histo = histogram_image->histograms[i];
2265a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    ok = ok && VP8LCreateHuffmanTree(histo->literal_, 15, codes + 0);
2275a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    ok = ok && VP8LCreateHuffmanTree(histo->red_, 15, codes + 1);
2285a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    ok = ok && VP8LCreateHuffmanTree(histo->blue_, 15, codes + 2);
2295a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    ok = ok && VP8LCreateHuffmanTree(histo->alpha_, 15, codes + 3);
2305a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    ok = ok && VP8LCreateHuffmanTree(histo->distance_, 15, codes + 4);
2315a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
2325a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
2335a50414796e9a458925c7a13a15055d02406bf43Vikas Arora End:
2345a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!ok) free(mem_buf);
2355a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return ok;
2365a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
2375a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
2385a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic void StoreHuffmanTreeOfHuffmanTreeToBitMask(
2395a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    VP8LBitWriter* const bw, const uint8_t* code_length_bitdepth) {
2405a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // RFC 1951 will calm you down if you are worried about this funny sequence.
2415a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // This sequence is tuned from that, but more weighted for lower symbol count,
2425a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // and more spiking histograms.
2435a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  static const uint8_t kStorageOrder[CODE_LENGTH_CODES] = {
2445a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
2455a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  };
2465a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int i;
2475a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Throw away trailing zeros:
2485a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int codes_to_store = CODE_LENGTH_CODES;
2495a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  for (; codes_to_store > 4; --codes_to_store) {
2505a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (code_length_bitdepth[kStorageOrder[codes_to_store - 1]] != 0) {
2515a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      break;
2525a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
2535a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
2545a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, 4, codes_to_store - 4);
2555a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  for (i = 0; i < codes_to_store; ++i) {
2565a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    VP8LWriteBits(bw, 3, code_length_bitdepth[kStorageOrder[i]]);
2575a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
2585a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
2595a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
2605a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic void ClearHuffmanTreeIfOnlyOneSymbol(
2615a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    HuffmanTreeCode* const huffman_code) {
2625a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int k;
2635a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int count = 0;
2645a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  for (k = 0; k < huffman_code->num_symbols; ++k) {
2655a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (huffman_code->code_lengths[k] != 0) {
2665a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      ++count;
2675a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      if (count > 1) return;
2685a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
2695a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
2705a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  for (k = 0; k < huffman_code->num_symbols; ++k) {
2715a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    huffman_code->code_lengths[k] = 0;
2725a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    huffman_code->codes[k] = 0;
2735a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
2745a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
2755a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
2765a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic void StoreHuffmanTreeToBitMask(
2775a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    VP8LBitWriter* const bw,
2785a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const HuffmanTreeToken* const tokens, const int num_tokens,
2795a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const HuffmanTreeCode* const huffman_code) {
2805a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int i;
2815a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  for (i = 0; i < num_tokens; ++i) {
2825a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const int ix = tokens[i].code;
2835a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const int extra_bits = tokens[i].extra_bits;
2845a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    VP8LWriteBits(bw, huffman_code->code_lengths[ix], huffman_code->codes[ix]);
2855a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    switch (ix) {
2865a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      case 16:
2875a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        VP8LWriteBits(bw, 2, extra_bits);
2885a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        break;
2895a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      case 17:
2905a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        VP8LWriteBits(bw, 3, extra_bits);
2915a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        break;
2925a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      case 18:
2935a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        VP8LWriteBits(bw, 7, extra_bits);
2945a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        break;
2955a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
2965a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
2975a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
2985a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
2995a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic int StoreFullHuffmanCode(VP8LBitWriter* const bw,
3005a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                const HuffmanTreeCode* const tree) {
3015a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int ok = 0;
3025a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  uint8_t code_length_bitdepth[CODE_LENGTH_CODES] = { 0 };
3035a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  uint16_t code_length_bitdepth_symbols[CODE_LENGTH_CODES] = { 0 };
3045a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int max_tokens = tree->num_symbols;
3055a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int num_tokens;
3065a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  HuffmanTreeCode huffman_code;
3075a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  HuffmanTreeToken* const tokens =
3085a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      (HuffmanTreeToken*)WebPSafeMalloc((uint64_t)max_tokens, sizeof(*tokens));
3095a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (tokens == NULL) return 0;
3105a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
3115a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  huffman_code.num_symbols = CODE_LENGTH_CODES;
3125a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  huffman_code.code_lengths = code_length_bitdepth;
3135a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  huffman_code.codes = code_length_bitdepth_symbols;
3145a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
3155a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, 1, 0);
3165a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  num_tokens = VP8LCreateCompressedHuffmanTree(tree, tokens, max_tokens);
3175a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  {
3185a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    int histogram[CODE_LENGTH_CODES] = { 0 };
3195a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    int i;
3205a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    for (i = 0; i < num_tokens; ++i) {
3215a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      ++histogram[tokens[i].code];
3225a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
3235a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
3245a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (!VP8LCreateHuffmanTree(histogram, 7, &huffman_code)) {
3255a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      goto End;
3265a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
3275a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
3285a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
3295a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  StoreHuffmanTreeOfHuffmanTreeToBitMask(bw, code_length_bitdepth);
3305a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  ClearHuffmanTreeIfOnlyOneSymbol(&huffman_code);
3315a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  {
3325a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    int trailing_zero_bits = 0;
3335a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    int trimmed_length = num_tokens;
3345a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    int write_trimmed_length;
3355a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    int length;
3365a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    int i = num_tokens;
3375a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    while (i-- > 0) {
3385a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      const int ix = tokens[i].code;
3395a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      if (ix == 0 || ix == 17 || ix == 18) {
3405a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        --trimmed_length;   // discount trailing zeros
3415a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        trailing_zero_bits += code_length_bitdepth[ix];
3425a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        if (ix == 17) {
3435a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          trailing_zero_bits += 3;
3445a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        } else if (ix == 18) {
3455a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          trailing_zero_bits += 7;
3465a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        }
3475a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      } else {
3485a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        break;
3495a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      }
3505a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
3515a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    write_trimmed_length = (trimmed_length > 1 && trailing_zero_bits > 12);
3525a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    length = write_trimmed_length ? trimmed_length : num_tokens;
3535a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    VP8LWriteBits(bw, 1, write_trimmed_length);
3545a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (write_trimmed_length) {
3555a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      const int nbits = VP8LBitsLog2Ceiling(trimmed_length - 1);
3565a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      const int nbitpairs = (nbits == 0) ? 1 : (nbits + 1) / 2;
3575a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      VP8LWriteBits(bw, 3, nbitpairs - 1);
3585a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      assert(trimmed_length >= 2);
3595a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      VP8LWriteBits(bw, nbitpairs * 2, trimmed_length - 2);
3605a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
3615a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    StoreHuffmanTreeToBitMask(bw, tokens, length, &huffman_code);
3625a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
3635a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  ok = 1;
3645a50414796e9a458925c7a13a15055d02406bf43Vikas Arora End:
3655a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  free(tokens);
3665a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return ok;
3675a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
3685a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
3695a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic int StoreHuffmanCode(VP8LBitWriter* const bw,
3705a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                            const HuffmanTreeCode* const huffman_code) {
3715a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int i;
3725a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int count = 0;
3735a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int symbols[2] = { 0, 0 };
3745a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int kMaxBits = 8;
3755a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int kMaxSymbol = 1 << kMaxBits;
3765a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
3775a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Check whether it's a small tree.
3785a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  for (i = 0; i < huffman_code->num_symbols && count < 3; ++i) {
3795a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (huffman_code->code_lengths[i] != 0) {
3805a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      if (count < 2) symbols[count] = i;
3815a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      ++count;
3825a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
3835a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
3845a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
3855a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (count == 0) {   // emit minimal tree for empty cases
3865a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    // bits: small tree marker: 1, count-1: 0, large 8-bit code: 0, code: 0
3875a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    VP8LWriteBits(bw, 4, 0x01);
3885a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    return 1;
3895a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  } else if (count <= 2 && symbols[0] < kMaxSymbol && symbols[1] < kMaxSymbol) {
3905a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    VP8LWriteBits(bw, 1, 1);  // Small tree marker to encode 1 or 2 symbols.
3915a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    VP8LWriteBits(bw, 1, count - 1);
3925a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (symbols[0] <= 1) {
3935a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      VP8LWriteBits(bw, 1, 0);  // Code bit for small (1 bit) symbol value.
3945a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      VP8LWriteBits(bw, 1, symbols[0]);
3955a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    } else {
3965a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      VP8LWriteBits(bw, 1, 1);
3975a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      VP8LWriteBits(bw, 8, symbols[0]);
3985a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
3995a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (count == 2) {
4005a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      VP8LWriteBits(bw, 8, symbols[1]);
4015a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
4025a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    return 1;
4035a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  } else {
4045a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    return StoreFullHuffmanCode(bw, huffman_code);
4055a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
4065a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
4075a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
4085a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic void WriteHuffmanCode(VP8LBitWriter* const bw,
4095a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                             const HuffmanTreeCode* const code, int index) {
4105a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int depth = code->code_lengths[index];
4115a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int symbol = code->codes[index];
4125a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, depth, symbol);
4135a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
4145a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
4155a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic void StoreImageToBitMask(
4165a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    VP8LBitWriter* const bw, int width, int histo_bits,
4175a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const VP8LBackwardRefs* const refs,
4185a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const uint16_t* histogram_symbols,
4195a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const HuffmanTreeCode* const huffman_codes) {
4205a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // x and y trace the position in the image.
4215a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int x = 0;
4225a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int y = 0;
4235a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int histo_xsize = histo_bits ? VP8LSubSampleSize(width, histo_bits) : 1;
4245a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int i;
4255a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  for (i = 0; i < refs->size; ++i) {
4265a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const PixOrCopy* const v = &refs->refs[i];
4275a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const int histogram_ix = histogram_symbols[histo_bits ?
4285a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                               (y >> histo_bits) * histo_xsize +
4295a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                               (x >> histo_bits) : 0];
4305a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const HuffmanTreeCode* const codes = huffman_codes + 5 * histogram_ix;
4315a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (PixOrCopyIsCacheIdx(v)) {
4325a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      const int code = PixOrCopyCacheIdx(v);
4335a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      const int literal_ix = 256 + NUM_LENGTH_CODES + code;
4345a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      WriteHuffmanCode(bw, codes, literal_ix);
4355a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    } else if (PixOrCopyIsLiteral(v)) {
4365a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      static const int order[] = { 1, 2, 0, 3 };
4375a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      int k;
4385a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      for (k = 0; k < 4; ++k) {
4395a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        const int code = PixOrCopyLiteral(v, order[k]);
4405a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        WriteHuffmanCode(bw, codes + k, code);
4415a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      }
4425a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    } else {
4435a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      int bits, n_bits;
4445a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      int code, distance;
4455a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
4465a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      PrefixEncode(v->len, &code, &n_bits, &bits);
4475a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      WriteHuffmanCode(bw, codes, 256 + code);
4485a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      VP8LWriteBits(bw, n_bits, bits);
4495a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
4505a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      distance = PixOrCopyDistance(v);
4515a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      PrefixEncode(distance, &code, &n_bits, &bits);
4525a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      WriteHuffmanCode(bw, codes + 4, code);
4535a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      VP8LWriteBits(bw, n_bits, bits);
4545a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
4555a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    x += PixOrCopyLength(v);
4565a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    while (x >= width) {
4575a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      x -= width;
4585a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      ++y;
4595a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
4605a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
4615a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
4625a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
4635a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// Special case of EncodeImageInternal() for cache-bits=0, histo_bits=31
4645a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic int EncodeImageNoHuffman(VP8LBitWriter* const bw,
4655a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                const uint32_t* const argb,
4665a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                int width, int height, int quality) {
4675a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int i;
4685a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int ok = 0;
4695a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LBackwardRefs refs;
4705a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  HuffmanTreeCode huffman_codes[5] = { { 0, NULL, NULL } };
4715a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const uint16_t histogram_symbols[1] = { 0 };    // only one tree, one symbol
4725a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LHistogramSet* const histogram_image = VP8LAllocateHistogramSet(1, 0);
4735a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (histogram_image == NULL) return 0;
4745a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
4755a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Calculate backward references from ARGB image.
4765a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!VP8LGetBackwardReferences(width, height, argb, quality, 0, 1, &refs)) {
4775a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    goto Error;
4785a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
4795a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Build histogram image and symbols from backward references.
4805a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LHistogramStoreRefs(&refs, histogram_image->histograms[0]);
4815a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
4825a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Create Huffman bit lengths and codes for each histogram image.
4835a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  assert(histogram_image->size == 1);
4845a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) {
4855a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    goto Error;
4865a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
4875a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
4885a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // No color cache, no Huffman image.
4895a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, 1, 0);
4905a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
4915a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Store Huffman codes.
4925a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  for (i = 0; i < 5; ++i) {
4935a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    HuffmanTreeCode* const codes = &huffman_codes[i];
4945a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (!StoreHuffmanCode(bw, codes)) {
4955a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      goto Error;
4965a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
4975a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    ClearHuffmanTreeIfOnlyOneSymbol(codes);
4985a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
4995a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
5005a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Store actual literals.
5015a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  StoreImageToBitMask(bw, width, 0, &refs, histogram_symbols, huffman_codes);
5025a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  ok = 1;
5035a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
5045a50414796e9a458925c7a13a15055d02406bf43Vikas Arora Error:
5055a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  free(histogram_image);
5065a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LClearBackwardRefs(&refs);
5075a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  free(huffman_codes[0].codes);
5085a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return ok;
5095a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
5105a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
5115a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic int EncodeImageInternal(VP8LBitWriter* const bw,
5125a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                               const uint32_t* const argb,
5135a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                               int width, int height, int quality,
5145a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                               int cache_bits, int histogram_bits) {
5155a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int ok = 0;
5165a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int use_2d_locality = 1;
5175a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int use_color_cache = (cache_bits > 0);
5185a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const uint32_t histogram_image_xysize =
5195a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      VP8LSubSampleSize(width, histogram_bits) *
5205a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      VP8LSubSampleSize(height, histogram_bits);
5215a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LHistogramSet* histogram_image =
5225a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      VP8LAllocateHistogramSet(histogram_image_xysize, 0);
5235a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int histogram_image_size = 0;
5245a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  size_t bit_array_size = 0;
5255a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  HuffmanTreeCode* huffman_codes = NULL;
5265a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LBackwardRefs refs;
5275a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  uint16_t* const histogram_symbols =
5285a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      (uint16_t*)WebPSafeMalloc((uint64_t)histogram_image_xysize,
5295a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                sizeof(*histogram_symbols));
5305a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  assert(histogram_bits >= MIN_HUFFMAN_BITS);
5315a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  assert(histogram_bits <= MAX_HUFFMAN_BITS);
5325a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (histogram_image == NULL || histogram_symbols == NULL) goto Error;
5335a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
5345a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Calculate backward references from ARGB image.
5355a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!VP8LGetBackwardReferences(width, height, argb, quality, cache_bits,
5365a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                 use_2d_locality, &refs)) {
5375a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    goto Error;
5385a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
5395a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Build histogram image and symbols from backward references.
5405a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!VP8LGetHistoImageSymbols(width, height, &refs,
5415a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                quality, histogram_bits, cache_bits,
5425a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                histogram_image,
5435a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                histogram_symbols)) {
5445a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    goto Error;
5455a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
5465a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Create Huffman bit lengths and codes for each histogram image.
5475a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  histogram_image_size = histogram_image->size;
5485a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  bit_array_size = 5 * histogram_image_size;
5495a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  huffman_codes = (HuffmanTreeCode*)WebPSafeCalloc(bit_array_size,
5505a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                                   sizeof(*huffman_codes));
5515a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (huffman_codes == NULL ||
5525a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      !GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) {
5535a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    goto Error;
5545a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
5555a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
5565a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Color Cache parameters.
5575a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, 1, use_color_cache);
5585a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (use_color_cache) {
5595a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    VP8LWriteBits(bw, 4, cache_bits);
5605a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
5615a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
5625a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Huffman image + meta huffman.
5635a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  {
5645a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const int write_histogram_image = (histogram_image_size > 1);
5655a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    VP8LWriteBits(bw, 1, write_histogram_image);
5665a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (write_histogram_image) {
5675a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      uint32_t* const histogram_argb =
5685a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          (uint32_t*)WebPSafeMalloc((uint64_t)histogram_image_xysize,
5695a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                    sizeof(*histogram_argb));
5705a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      int max_index = 0;
5715a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      uint32_t i;
5725a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      if (histogram_argb == NULL) goto Error;
5735a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      for (i = 0; i < histogram_image_xysize; ++i) {
5745a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        const int index = histogram_symbols[i] & 0xffff;
5755a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        histogram_argb[i] = 0xff000000 | (index << 8);
5765a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        if (index >= max_index) {
5775a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          max_index = index + 1;
5785a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        }
5795a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      }
5805a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      histogram_image_size = max_index;
5815a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
5825a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      VP8LWriteBits(bw, 3, histogram_bits - 2);
5835a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      ok = EncodeImageNoHuffman(bw, histogram_argb,
5845a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                VP8LSubSampleSize(width, histogram_bits),
5855a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                VP8LSubSampleSize(height, histogram_bits),
5865a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                quality);
5875a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      free(histogram_argb);
5885a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      if (!ok) goto Error;
5895a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
5905a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
5915a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
5925a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Store Huffman codes.
5935a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  {
5945a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    int i;
5955a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    for (i = 0; i < 5 * histogram_image_size; ++i) {
5965a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      HuffmanTreeCode* const codes = &huffman_codes[i];
5975a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      if (!StoreHuffmanCode(bw, codes)) goto Error;
5985a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      ClearHuffmanTreeIfOnlyOneSymbol(codes);
5995a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
6005a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
6015a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Free combined histograms.
6025a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  free(histogram_image);
6035a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  histogram_image = NULL;
6045a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
6055a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Store actual literals.
6065a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  StoreImageToBitMask(bw, width, histogram_bits, &refs,
6075a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                      histogram_symbols, huffman_codes);
6085a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  ok = 1;
6095a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
6105a50414796e9a458925c7a13a15055d02406bf43Vikas Arora Error:
6115a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!ok) free(histogram_image);
6125a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
6135a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LClearBackwardRefs(&refs);
6145a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (huffman_codes != NULL) {
6155a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    free(huffman_codes->codes);
6165a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    free(huffman_codes);
6175a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
6185a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  free(histogram_symbols);
6195a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return ok;
6205a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
6215a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
6225a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// -----------------------------------------------------------------------------
6235a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// Transforms
6245a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
6255a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// Check if it would be a good idea to subtract green from red and blue. We
6265a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// only impact entropy in red/blue components, don't bother to look at others.
6275a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic int EvalAndApplySubtractGreen(VP8LEncoder* const enc,
6285a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                     int width, int height,
6295a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                     VP8LBitWriter* const bw) {
6305a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!enc->use_palette_) {
6315a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    int i;
6325a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const uint32_t* const argb = enc->argb_;
6335a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    double bit_cost_before, bit_cost_after;
6345a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    VP8LHistogram* const histo = (VP8LHistogram*)malloc(sizeof(*histo));
6355a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (histo == NULL) return 0;
6365a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
6375a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    VP8LHistogramInit(histo, 1);
6385a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    for (i = 0; i < width * height; ++i) {
6395a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      const uint32_t c = argb[i];
6405a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      ++histo->red_[(c >> 16) & 0xff];
6415a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      ++histo->blue_[(c >> 0) & 0xff];
6425a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
6435a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    bit_cost_before = VP8LHistogramEstimateBits(histo);
6445a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
6455a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    VP8LHistogramInit(histo, 1);
6465a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    for (i = 0; i < width * height; ++i) {
6475a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      const uint32_t c = argb[i];
6485a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      const int green = (c >> 8) & 0xff;
6495a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      ++histo->red_[((c >> 16) - green) & 0xff];
6505a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      ++histo->blue_[((c >> 0) - green) & 0xff];
6515a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
6525a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    bit_cost_after = VP8LHistogramEstimateBits(histo);
6535a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    free(histo);
6545a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
6555a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    // Check if subtracting green yields low entropy.
6565a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    enc->use_subtract_green_ = (bit_cost_after < bit_cost_before);
6575a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (enc->use_subtract_green_) {
6585a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      VP8LWriteBits(bw, 1, TRANSFORM_PRESENT);
6595a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      VP8LWriteBits(bw, 2, SUBTRACT_GREEN);
6605a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      VP8LSubtractGreenFromBlueAndRed(enc->argb_, width * height);
6615a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
6625a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
6635a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return 1;
6645a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
6655a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
6665a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic int ApplyPredictFilter(const VP8LEncoder* const enc,
6675a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                              int width, int height, int quality,
6685a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                              VP8LBitWriter* const bw) {
6695a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int pred_bits = enc->transform_bits_;
6705a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int transform_width = VP8LSubSampleSize(width, pred_bits);
6715a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int transform_height = VP8LSubSampleSize(height, pred_bits);
6725a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
6735a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LResidualImage(width, height, pred_bits, enc->argb_, enc->argb_scratch_,
6745a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                    enc->transform_data_);
6755a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, 1, TRANSFORM_PRESENT);
6765a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, 2, PREDICTOR_TRANSFORM);
6775a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  assert(pred_bits >= 2);
6785a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, 3, pred_bits - 2);
6795a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!EncodeImageNoHuffman(bw, enc->transform_data_,
6805a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                            transform_width, transform_height, quality)) {
6815a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    return 0;
6825a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
6835a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return 1;
6845a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
6855a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
6865a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic int ApplyCrossColorFilter(const VP8LEncoder* const enc,
6875a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                 int width, int height, int quality,
6885a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                 VP8LBitWriter* const bw) {
6895a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int ccolor_transform_bits = enc->transform_bits_;
6905a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int transform_width = VP8LSubSampleSize(width, ccolor_transform_bits);
6915a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int transform_height = VP8LSubSampleSize(height, ccolor_transform_bits);
6925a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int step = (quality == 0) ? 32 : 8;
6935a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
6945a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LColorSpaceTransform(width, height, ccolor_transform_bits, step,
6955a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                          enc->argb_, enc->transform_data_);
6965a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, 1, TRANSFORM_PRESENT);
6975a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, 2, CROSS_COLOR_TRANSFORM);
6985a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  assert(ccolor_transform_bits >= 2);
6995a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, 3, ccolor_transform_bits - 2);
7005a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!EncodeImageNoHuffman(bw, enc->transform_data_,
7015a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                            transform_width, transform_height, quality)) {
7025a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    return 0;
7035a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
7045a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return 1;
7055a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
7065a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
7075a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// -----------------------------------------------------------------------------
7085a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
7095a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic void PutLE32(uint8_t* const data, uint32_t val) {
7105a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  data[0] = (val >>  0) & 0xff;
7115a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  data[1] = (val >>  8) & 0xff;
7125a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  data[2] = (val >> 16) & 0xff;
7135a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  data[3] = (val >> 24) & 0xff;
7145a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
7155a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
7165a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic WebPEncodingError WriteRiffHeader(const WebPPicture* const pic,
7175a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                         size_t riff_size, size_t vp8l_size) {
7185a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  uint8_t riff[RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE + VP8L_SIGNATURE_SIZE] = {
7195a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    'R', 'I', 'F', 'F', 0, 0, 0, 0, 'W', 'E', 'B', 'P',
7205a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    'V', 'P', '8', 'L', 0, 0, 0, 0, VP8L_MAGIC_BYTE,
7215a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  };
7225a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  PutLE32(riff + TAG_SIZE, (uint32_t)riff_size);
7235a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  PutLE32(riff + RIFF_HEADER_SIZE + TAG_SIZE, (uint32_t)vp8l_size);
7245a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!pic->writer(riff, sizeof(riff), pic)) {
7255a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    return VP8_ENC_ERROR_BAD_WRITE;
7265a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
7275a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return VP8_ENC_OK;
7285a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
7295a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
7305a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic int WriteImageSize(const WebPPicture* const pic,
7315a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                          VP8LBitWriter* const bw) {
7325a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int width = pic->width - 1;
7335a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int height = pic->height - 1;
7345a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  assert(width < WEBP_MAX_DIMENSION && height < WEBP_MAX_DIMENSION);
7355a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
7365a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, VP8L_IMAGE_SIZE_BITS, width);
7375a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, VP8L_IMAGE_SIZE_BITS, height);
7385a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return !bw->error_;
7395a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
7405a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
7415a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic int WriteRealAlphaAndVersion(VP8LBitWriter* const bw, int has_alpha) {
7425a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, 1, has_alpha);
7435a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, VP8L_VERSION_BITS, VP8L_VERSION);
7445a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return !bw->error_;
7455a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
7465a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
7475a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic WebPEncodingError WriteImage(const WebPPicture* const pic,
7485a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                    VP8LBitWriter* const bw,
7495a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                    size_t* const coded_size) {
7505a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  WebPEncodingError err = VP8_ENC_OK;
7515a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const uint8_t* const webpll_data = VP8LBitWriterFinish(bw);
7525a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const size_t webpll_size = VP8LBitWriterNumBytes(bw);
7535a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const size_t vp8l_size = VP8L_SIGNATURE_SIZE + webpll_size;
7545a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const size_t pad = vp8l_size & 1;
7555a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const size_t riff_size = TAG_SIZE + CHUNK_HEADER_SIZE + vp8l_size + pad;
7565a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
7575a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  err = WriteRiffHeader(pic, riff_size, vp8l_size);
7585a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (err != VP8_ENC_OK) goto Error;
7595a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
7605a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!pic->writer(webpll_data, webpll_size, pic)) {
7615a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    err = VP8_ENC_ERROR_BAD_WRITE;
7625a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    goto Error;
7635a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
7645a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
7655a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (pad) {
7665a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const uint8_t pad_byte[1] = { 0 };
7675a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (!pic->writer(pad_byte, 1, pic)) {
7685a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      err = VP8_ENC_ERROR_BAD_WRITE;
7695a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      goto Error;
7705a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
7715a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
7725a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  *coded_size = CHUNK_HEADER_SIZE + riff_size;
7735a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return VP8_ENC_OK;
7745a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
7755a50414796e9a458925c7a13a15055d02406bf43Vikas Arora Error:
7765a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return err;
7775a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
7785a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
7795a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// -----------------------------------------------------------------------------
7805a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
7815a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// Allocates the memory for argb (W x H) buffer, 2 rows of context for
7825a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// prediction and transform data.
7835a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic WebPEncodingError AllocateTransformBuffer(VP8LEncoder* const enc,
7845a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                                 int width, int height) {
7855a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  WebPEncodingError err = VP8_ENC_OK;
7865a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int tile_size = 1 << enc->transform_bits_;
7875a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const uint64_t image_size = width * height;
7885a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const uint64_t argb_scratch_size = tile_size * width + width;
7895a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const uint64_t transform_data_size =
7905a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      (uint64_t)VP8LSubSampleSize(width, enc->transform_bits_) *
7915a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      (uint64_t)VP8LSubSampleSize(height, enc->transform_bits_);
7925a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const uint64_t total_size =
7935a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      image_size + argb_scratch_size + transform_data_size;
7945a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  uint32_t* mem = (uint32_t*)WebPSafeMalloc(total_size, sizeof(*mem));
7955a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (mem == NULL) {
7965a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
7975a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    goto Error;
7985a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
7995a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  enc->argb_ = mem;
8005a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  mem += image_size;
8015a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  enc->argb_scratch_ = mem;
8025a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  mem += argb_scratch_size;
8035a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  enc->transform_data_ = mem;
8045a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  enc->current_width_ = width;
8055a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
8065a50414796e9a458925c7a13a15055d02406bf43Vikas Arora Error:
8075a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return err;
8085a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
8095a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
8105a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// Bundles multiple (2, 4 or 8) pixels into a single pixel.
8115a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// Returns the new xsize.
8125a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic void BundleColorMap(const WebPPicture* const pic,
8135a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                           int xbits, uint32_t* bundled_argb, int xs) {
8145a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int y;
8155a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int bit_depth = 1 << (3 - xbits);
8165a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  uint32_t code = 0;
8175a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const uint32_t* argb = pic->argb;
8185a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int width = pic->width;
8195a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int height = pic->height;
8205a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
8215a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  for (y = 0; y < height; ++y) {
8225a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    int x;
8235a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    for (x = 0; x < width; ++x) {
8245a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      const int mask = (1 << xbits) - 1;
8255a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      const int xsub = x & mask;
8265a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      if (xsub == 0) {
8275a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        code = 0;
8285a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      }
8295a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      // TODO(vikasa): simplify the bundling logic.
8305a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      code |= (argb[x] & 0xff00) << (bit_depth * xsub);
8315a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      bundled_argb[y * xs + (x >> xbits)] = 0xff000000 | code;
8325a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
8335a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    argb += pic->argb_stride;
8345a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
8355a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
8365a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
8375a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// Note: Expects "enc->palette_" to be set properly.
8385a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// Also, "enc->palette_" will be modified after this call and should not be used
8395a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// later.
8405a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic WebPEncodingError ApplyPalette(VP8LBitWriter* const bw,
8415a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                      VP8LEncoder* const enc, int quality) {
8425a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  WebPEncodingError err = VP8_ENC_OK;
8435a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int i, x, y;
8445a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const WebPPicture* const pic = enc->pic_;
8455a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  uint32_t* argb = pic->argb;
8465a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int width = pic->width;
8475a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int height = pic->height;
8485a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  uint32_t* const palette = enc->palette_;
8495a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int palette_size = enc->palette_size_;
8505a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
8515a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Replace each input pixel by corresponding palette index.
8525a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  for (y = 0; y < height; ++y) {
8535a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    for (x = 0; x < width; ++x) {
8545a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      const uint32_t pix = argb[x];
8555a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      for (i = 0; i < palette_size; ++i) {
8565a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        if (pix == palette[i]) {
8575a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          argb[x] = 0xff000000u | (i << 8);
8585a50414796e9a458925c7a13a15055d02406bf43Vikas Arora          break;
8595a50414796e9a458925c7a13a15055d02406bf43Vikas Arora        }
8605a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      }
8615a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
8625a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    argb += pic->argb_stride;
8635a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
8645a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
8655a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Save palette to bitstream.
8665a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, 1, TRANSFORM_PRESENT);
8675a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, 2, COLOR_INDEXING_TRANSFORM);
8685a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  assert(palette_size >= 1);
8695a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, 8, palette_size - 1);
8705a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  for (i = palette_size - 1; i >= 1; --i) {
8715a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    palette[i] = VP8LSubPixels(palette[i], palette[i - 1]);
8725a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
8735a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!EncodeImageNoHuffman(bw, palette, palette_size, 1, quality)) {
8745a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    err = VP8_ENC_ERROR_INVALID_CONFIGURATION;
8755a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    goto Error;
8765a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
8775a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
8785a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (palette_size <= 16) {
8795a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    // Image can be packed (multiple pixels per uint32_t).
8805a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    int xbits = 1;
8815a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (palette_size <= 2) {
8825a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      xbits = 3;
8835a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    } else if (palette_size <= 4) {
8845a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      xbits = 2;
8855a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
8865a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    err = AllocateTransformBuffer(enc, VP8LSubSampleSize(width, xbits), height);
8875a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (err != VP8_ENC_OK) goto Error;
8885a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    BundleColorMap(pic, xbits, enc->argb_, enc->current_width_);
8895a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
8905a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
8915a50414796e9a458925c7a13a15055d02406bf43Vikas Arora Error:
8925a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return err;
8935a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
8945a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
8955a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// -----------------------------------------------------------------------------
8965a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
8975a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic int GetHistoBits(const WebPConfig* const config,
8985a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                        const WebPPicture* const pic) {
8995a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int width = pic->width;
9005a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int height = pic->height;
9015a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const size_t hist_size = sizeof(VP8LHistogram);
9025a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Make tile size a function of encoding method (Range: 0 to 6).
9035a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int histo_bits = 7 - config->method;
9045a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  while (1) {
9055a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const size_t huff_image_size = VP8LSubSampleSize(width, histo_bits) *
9065a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                   VP8LSubSampleSize(height, histo_bits) *
9075a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                   hist_size;
9085a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (huff_image_size <= MAX_HUFF_IMAGE_SIZE) break;
9095a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    ++histo_bits;
9105a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
9115a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return (histo_bits < MIN_HUFFMAN_BITS) ? MIN_HUFFMAN_BITS :
9125a50414796e9a458925c7a13a15055d02406bf43Vikas Arora         (histo_bits > MAX_HUFFMAN_BITS) ? MAX_HUFFMAN_BITS : histo_bits;
9135a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
9145a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
9155a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic void InitEncParams(VP8LEncoder* const enc) {
9165a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const WebPConfig* const config = enc->config_;
9175a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const WebPPicture* const picture = enc->pic_;
9185a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int method = config->method;
9195a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const float quality = config->quality;
9205a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  enc->transform_bits_ = (method < 4) ? 5 : (method > 4) ? 3 : 4;
9215a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  enc->histo_bits_ = GetHistoBits(config, picture);
9225a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  enc->cache_bits_ = (quality <= 25.f) ? 0 : 7;
9235a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
9245a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
9255a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// -----------------------------------------------------------------------------
9265a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// VP8LEncoder
9275a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
9285a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic VP8LEncoder* VP8LEncoderNew(const WebPConfig* const config,
9295a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                   const WebPPicture* const picture) {
9305a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LEncoder* const enc = (VP8LEncoder*)calloc(1, sizeof(*enc));
9315a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (enc == NULL) {
9325a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
9335a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    return NULL;
9345a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
9355a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  enc->config_ = config;
9365a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  enc->pic_ = picture;
9375a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return enc;
9385a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
9395a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
9405a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic void VP8LEncoderDelete(VP8LEncoder* enc) {
9415a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  free(enc->argb_);
9425a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  free(enc);
9435a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
9445a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
9455a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// -----------------------------------------------------------------------------
9465a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// Main call
9475a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
9485a50414796e9a458925c7a13a15055d02406bf43Vikas AroraWebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
9495a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                   const WebPPicture* const picture,
9505a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                   VP8LBitWriter* const bw) {
9515a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  WebPEncodingError err = VP8_ENC_OK;
9525a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int quality = (int)config->quality;
9535a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int width = picture->width;
9545a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const int height = picture->height;
9555a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LEncoder* const enc = VP8LEncoderNew(config, picture);
9565a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  const size_t byte_position = VP8LBitWriterNumBytes(bw);
9575a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
9585a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (enc == NULL) {
9595a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
9605a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    goto Error;
9615a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
9625a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
9635a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  InitEncParams(enc);
9645a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
9655a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // ---------------------------------------------------------------------------
9665a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Analyze image (entropy, num_palettes etc)
9675a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
9685a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!VP8LEncAnalyze(enc, config->image_hint)) {
9695a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
9705a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    goto Error;
9715a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
9725a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
9735a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (enc->use_palette_) {
9745a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    err = ApplyPalette(bw, enc, quality);
9755a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (err != VP8_ENC_OK) goto Error;
9765a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    // Color cache is disabled for palette.
9775a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    enc->cache_bits_ = 0;
9785a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
9795a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
9805a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // In case image is not packed.
9815a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (enc->argb_ == NULL) {
9825a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    int y;
9835a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    err = AllocateTransformBuffer(enc, width, height);
9845a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (err != VP8_ENC_OK) goto Error;
9855a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    for (y = 0; y < height; ++y) {
9865a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      memcpy(enc->argb_ + y * width,
9875a50414796e9a458925c7a13a15055d02406bf43Vikas Arora             picture->argb + y * picture->argb_stride,
9885a50414796e9a458925c7a13a15055d02406bf43Vikas Arora             width * sizeof(*enc->argb_));
9895a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
9905a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    enc->current_width_ = width;
9915a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
9925a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
9935a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // ---------------------------------------------------------------------------
9945a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Apply transforms and write transform data.
9955a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
9965a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!EvalAndApplySubtractGreen(enc, enc->current_width_, height, bw)) {
9975a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
9985a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    goto Error;
9995a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
10005a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
10015a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (enc->use_predict_) {
10025a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (!ApplyPredictFilter(enc, enc->current_width_, height, quality, bw)) {
10035a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      err = VP8_ENC_ERROR_INVALID_CONFIGURATION;
10045a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      goto Error;
10055a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
10065a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
10075a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
10085a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (enc->use_cross_color_) {
10095a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (!ApplyCrossColorFilter(enc, enc->current_width_, height, quality, bw)) {
10105a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      err = VP8_ENC_ERROR_INVALID_CONFIGURATION;
10115a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      goto Error;
10125a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
10135a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
10145a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
10155a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LWriteBits(bw, 1, !TRANSFORM_PRESENT);  // No more transforms.
10165a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
10175a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // ---------------------------------------------------------------------------
10185a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Estimate the color cache size.
10195a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
10205a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (enc->cache_bits_ > 0) {
10215a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (!VP8LCalculateEstimateForCacheSize(enc->argb_, enc->current_width_,
10225a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                                           height, &enc->cache_bits_)) {
10235a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      err = VP8_ENC_ERROR_INVALID_CONFIGURATION;
10245a50414796e9a458925c7a13a15055d02406bf43Vikas Arora      goto Error;
10255a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    }
10265a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
10275a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
10285a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // ---------------------------------------------------------------------------
10295a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Encode and write the transformed image.
10305a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
10315a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!EncodeImageInternal(bw, enc->argb_, enc->current_width_, height,
10325a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                           quality, enc->cache_bits_, enc->histo_bits_)) {
10335a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
10345a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    goto Error;
10355a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
10365a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
10375a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (picture->stats != NULL) {
10385a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    WebPAuxStats* const stats = picture->stats;
10395a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    stats->lossless_features = 0;
10405a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (enc->use_predict_) stats->lossless_features |= 1;
10415a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (enc->use_cross_color_) stats->lossless_features |= 2;
10425a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (enc->use_subtract_green_) stats->lossless_features |= 4;
10435a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    if (enc->use_palette_) stats->lossless_features |= 8;
10445a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    stats->histogram_bits = enc->histo_bits_;
10455a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    stats->transform_bits = enc->transform_bits_;
10465a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    stats->cache_bits = enc->cache_bits_;
10475a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    stats->palette_size = enc->palette_size_;
10485a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    stats->lossless_size = (int)(VP8LBitWriterNumBytes(bw) - byte_position);
10495a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
10505a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
10515a50414796e9a458925c7a13a15055d02406bf43Vikas Arora Error:
10525a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LEncoderDelete(enc);
10535a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return err;
10545a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
10555a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
10565a50414796e9a458925c7a13a15055d02406bf43Vikas Aroraint VP8LEncodeImage(const WebPConfig* const config,
10575a50414796e9a458925c7a13a15055d02406bf43Vikas Arora                    const WebPPicture* const picture) {
10585a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int width, height;
10595a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int has_alpha;
10605a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  size_t coded_size;
10615a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  int percent = 0;
10625a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  WebPEncodingError err = VP8_ENC_OK;
10635a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LBitWriter bw;
10645a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
10655a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (picture == NULL) return 0;
10665a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
10675a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (config == NULL || picture->argb == NULL) {
10685a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    err = VP8_ENC_ERROR_NULL_PARAMETER;
10695a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    WebPEncodingSetError(picture, err);
10705a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    return 0;
10715a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
10725a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
10735a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  width = picture->width;
10745a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  height = picture->height;
10755a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!VP8LBitWriterInit(&bw, (width * height) >> 1)) {
10765a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
10775a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    goto Error;
10785a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
10795a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
10805a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!WebPReportProgress(picture, 1, &percent)) {
10815a50414796e9a458925c7a13a15055d02406bf43Vikas Arora UserAbort:
10825a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    err = VP8_ENC_ERROR_USER_ABORT;
10835a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    goto Error;
10845a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
10855a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Reset stats (for pure lossless coding)
10865a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (picture->stats != NULL) {
10875a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    WebPAuxStats* const stats = picture->stats;
10885a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    memset(stats, 0, sizeof(*stats));
10895a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    stats->PSNR[0] = 99.f;
10905a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    stats->PSNR[1] = 99.f;
10915a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    stats->PSNR[2] = 99.f;
10925a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    stats->PSNR[3] = 99.f;
10935a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    stats->PSNR[4] = 99.f;
10945a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
10955a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
10965a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Write image size.
10975a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!WriteImageSize(picture, &bw)) {
10985a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
10995a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    goto Error;
11005a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
11015a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
11025a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  has_alpha = WebPPictureHasTransparency(picture);
11035a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Write the non-trivial Alpha flag and lossless version.
11045a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!WriteRealAlphaAndVersion(&bw, has_alpha)) {
11055a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    err = VP8_ENC_ERROR_OUT_OF_MEMORY;
11065a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    goto Error;
11075a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
11085a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
11095a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!WebPReportProgress(picture, 5, &percent)) goto UserAbort;
11105a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
11115a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Encode main image stream.
11125a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  err = VP8LEncodeStream(config, picture, &bw);
11135a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (err != VP8_ENC_OK) goto Error;
11145a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
11155a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // TODO(skal): have a fine-grained progress report in VP8LEncodeStream().
11165a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!WebPReportProgress(picture, 90, &percent)) goto UserAbort;
11175a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
11185a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Finish the RIFF chunk.
11195a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  err = WriteImage(picture, &bw, &coded_size);
11205a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (err != VP8_ENC_OK) goto Error;
11215a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
11225a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (!WebPReportProgress(picture, 100, &percent)) goto UserAbort;
11235a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
11245a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  // Save size.
11255a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (picture->stats != NULL) {
11265a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    picture->stats->coded_size += (int)coded_size;
11275a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    picture->stats->lossless_size = (int)coded_size;
11285a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
11295a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
11305a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (picture->extra_info != NULL) {
11315a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const int mb_w = (width + 15) >> 4;
11325a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    const int mb_h = (height + 15) >> 4;
11335a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    memset(picture->extra_info, 0, mb_w * mb_h * sizeof(*picture->extra_info));
11345a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
11355a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
11365a50414796e9a458925c7a13a15055d02406bf43Vikas Arora Error:
11375a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (bw.error_) err = VP8_ENC_ERROR_OUT_OF_MEMORY;
11385a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  VP8LBitWriterDestroy(&bw);
11395a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  if (err != VP8_ENC_OK) {
11405a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    WebPEncodingSetError(picture, err);
11415a50414796e9a458925c7a13a15055d02406bf43Vikas Arora    return 0;
11425a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  }
11435a50414796e9a458925c7a13a15055d02406bf43Vikas Arora  return 1;
11445a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}
11455a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
11465a50414796e9a458925c7a13a15055d02406bf43Vikas Arora//------------------------------------------------------------------------------
11475a50414796e9a458925c7a13a15055d02406bf43Vikas Arora
11485a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#if defined(__cplusplus) || defined(c_plusplus)
11495a50414796e9a458925c7a13a15055d02406bf43Vikas Arora}    // extern "C"
11505a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#endif
1151