Home | History | Annotate | Download | only in enc
      1 // Copyright 2012 Google Inc. All Rights Reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style license
      4 // that can be found in the COPYING file in the root of the source
      5 // tree. An additional intellectual property rights grant can be found
      6 // in the file PATENTS. All contributing project authors may
      7 // be found in the AUTHORS file in the root of the source tree.
      8 // -----------------------------------------------------------------------------
      9 //
     10 // main entry for the lossless encoder.
     11 //
     12 // Author: Vikas Arora (vikaas.arora (at) gmail.com)
     13 //
     14 
     15 #include <assert.h>
     16 #include <stdlib.h>
     17 
     18 #include "src/enc/backward_references_enc.h"
     19 #include "src/enc/histogram_enc.h"
     20 #include "src/enc/vp8i_enc.h"
     21 #include "src/enc/vp8li_enc.h"
     22 #include "src/dsp/lossless.h"
     23 #include "src/dsp/lossless_common.h"
     24 #include "src/utils/bit_writer_utils.h"
     25 #include "src/utils/huffman_encode_utils.h"
     26 #include "src/utils/utils.h"
     27 #include "src/webp/format_constants.h"
     28 
     29 #include "src/enc/delta_palettization_enc.h"
     30 
     31 // Maximum number of histogram images (sub-blocks).
     32 #define MAX_HUFF_IMAGE_SIZE       2600
     33 
     34 // Palette reordering for smaller sum of deltas (and for smaller storage).
     35 
     36 static int PaletteCompareColorsForQsort(const void* p1, const void* p2) {
     37   const uint32_t a = WebPMemToUint32((uint8_t*)p1);
     38   const uint32_t b = WebPMemToUint32((uint8_t*)p2);
     39   assert(a != b);
     40   return (a < b) ? -1 : 1;
     41 }
     42 
     43 static WEBP_INLINE uint32_t PaletteComponentDistance(uint32_t v) {
     44   return (v <= 128) ? v : (256 - v);
     45 }
     46 
     47 // Computes a value that is related to the entropy created by the
     48 // palette entry diff.
     49 //
     50 // Note that the last & 0xff is a no-operation in the next statement, but
     51 // removed by most compilers and is here only for regularity of the code.
     52 static WEBP_INLINE uint32_t PaletteColorDistance(uint32_t col1, uint32_t col2) {
     53   const uint32_t diff = VP8LSubPixels(col1, col2);
     54   const int kMoreWeightForRGBThanForAlpha = 9;
     55   uint32_t score;
     56   score =  PaletteComponentDistance((diff >>  0) & 0xff);
     57   score += PaletteComponentDistance((diff >>  8) & 0xff);
     58   score += PaletteComponentDistance((diff >> 16) & 0xff);
     59   score *= kMoreWeightForRGBThanForAlpha;
     60   score += PaletteComponentDistance((diff >> 24) & 0xff);
     61   return score;
     62 }
     63 
     64 static WEBP_INLINE void SwapColor(uint32_t* const col1, uint32_t* const col2) {
     65   const uint32_t tmp = *col1;
     66   *col1 = *col2;
     67   *col2 = tmp;
     68 }
     69 
     70 static void GreedyMinimizeDeltas(uint32_t palette[], int num_colors) {
     71   // Find greedily always the closest color of the predicted color to minimize
     72   // deltas in the palette. This reduces storage needs since the
     73   // palette is stored with delta encoding.
     74   uint32_t predict = 0x00000000;
     75   int i, k;
     76   for (i = 0; i < num_colors; ++i) {
     77     int best_ix = i;
     78     uint32_t best_score = ~0U;
     79     for (k = i; k < num_colors; ++k) {
     80       const uint32_t cur_score = PaletteColorDistance(palette[k], predict);
     81       if (best_score > cur_score) {
     82         best_score = cur_score;
     83         best_ix = k;
     84       }
     85     }
     86     SwapColor(&palette[best_ix], &palette[i]);
     87     predict = palette[i];
     88   }
     89 }
     90 
     91 // The palette has been sorted by alpha. This function checks if the other
     92 // components of the palette have a monotonic development with regards to
     93 // position in the palette. If all have monotonic development, there is
     94 // no benefit to re-organize them greedily. A monotonic development
     95 // would be spotted in green-only situations (like lossy alpha) or gray-scale
     96 // images.
     97 static int PaletteHasNonMonotonousDeltas(uint32_t palette[], int num_colors) {
     98   uint32_t predict = 0x000000;
     99   int i;
    100   uint8_t sign_found = 0x00;
    101   for (i = 0; i < num_colors; ++i) {
    102     const uint32_t diff = VP8LSubPixels(palette[i], predict);
    103     const uint8_t rd = (diff >> 16) & 0xff;
    104     const uint8_t gd = (diff >>  8) & 0xff;
    105     const uint8_t bd = (diff >>  0) & 0xff;
    106     if (rd != 0x00) {
    107       sign_found |= (rd < 0x80) ? 1 : 2;
    108     }
    109     if (gd != 0x00) {
    110       sign_found |= (gd < 0x80) ? 8 : 16;
    111     }
    112     if (bd != 0x00) {
    113       sign_found |= (bd < 0x80) ? 64 : 128;
    114     }
    115     predict = palette[i];
    116   }
    117   return (sign_found & (sign_found << 1)) != 0;  // two consequent signs.
    118 }
    119 
    120 // -----------------------------------------------------------------------------
    121 // Palette
    122 
    123 // If number of colors in the image is less than or equal to MAX_PALETTE_SIZE,
    124 // creates a palette and returns true, else returns false.
    125 static int AnalyzeAndCreatePalette(const WebPPicture* const pic,
    126                                    int low_effort,
    127                                    uint32_t palette[MAX_PALETTE_SIZE],
    128                                    int* const palette_size) {
    129   const int num_colors = WebPGetColorPalette(pic, palette);
    130   if (num_colors > MAX_PALETTE_SIZE) {
    131     *palette_size = 0;
    132     return 0;
    133   }
    134   *palette_size = num_colors;
    135   qsort(palette, num_colors, sizeof(*palette), PaletteCompareColorsForQsort);
    136   if (!low_effort && PaletteHasNonMonotonousDeltas(palette, num_colors)) {
    137     GreedyMinimizeDeltas(palette, num_colors);
    138   }
    139   return 1;
    140 }
    141 
    142 // These five modes are evaluated and their respective entropy is computed.
    143 typedef enum {
    144   kDirect = 0,
    145   kSpatial = 1,
    146   kSubGreen = 2,
    147   kSpatialSubGreen = 3,
    148   kPalette = 4,
    149   kNumEntropyIx = 5
    150 } EntropyIx;
    151 
    152 typedef enum {
    153   kHistoAlpha = 0,
    154   kHistoAlphaPred,
    155   kHistoGreen,
    156   kHistoGreenPred,
    157   kHistoRed,
    158   kHistoRedPred,
    159   kHistoBlue,
    160   kHistoBluePred,
    161   kHistoRedSubGreen,
    162   kHistoRedPredSubGreen,
    163   kHistoBlueSubGreen,
    164   kHistoBluePredSubGreen,
    165   kHistoPalette,
    166   kHistoTotal  // Must be last.
    167 } HistoIx;
    168 
    169 static void AddSingleSubGreen(int p, uint32_t* const r, uint32_t* const b) {
    170   const int green = p >> 8;  // The upper bits are masked away later.
    171   ++r[((p >> 16) - green) & 0xff];
    172   ++b[((p >>  0) - green) & 0xff];
    173 }
    174 
    175 static void AddSingle(uint32_t p,
    176                       uint32_t* const a, uint32_t* const r,
    177                       uint32_t* const g, uint32_t* const b) {
    178   ++a[(p >> 24) & 0xff];
    179   ++r[(p >> 16) & 0xff];
    180   ++g[(p >>  8) & 0xff];
    181   ++b[(p >>  0) & 0xff];
    182 }
    183 
    184 static WEBP_INLINE uint32_t HashPix(uint32_t pix) {
    185   // Note that masking with 0xffffffffu is for preventing an
    186   // 'unsigned int overflow' warning. Doesn't impact the compiled code.
    187   return ((((uint64_t)pix + (pix >> 19)) * 0x39c5fba7ull) & 0xffffffffu) >> 24;
    188 }
    189 
    190 static int AnalyzeEntropy(const uint32_t* argb,
    191                           int width, int height, int argb_stride,
    192                           int use_palette,
    193                           int palette_size, int transform_bits,
    194                           EntropyIx* const min_entropy_ix,
    195                           int* const red_and_blue_always_zero) {
    196   // Allocate histogram set with cache_bits = 0.
    197   uint32_t* histo;
    198 
    199   if (use_palette && palette_size <= 16) {
    200     // In the case of small palettes, we pack 2, 4 or 8 pixels together. In
    201     // practice, small palettes are better than any other transform.
    202     *min_entropy_ix = kPalette;
    203     *red_and_blue_always_zero = 1;
    204     return 1;
    205   }
    206   histo = (uint32_t*)WebPSafeCalloc(kHistoTotal, sizeof(*histo) * 256);
    207   if (histo != NULL) {
    208     int i, x, y;
    209     const uint32_t* prev_row = NULL;
    210     const uint32_t* curr_row = argb;
    211     uint32_t pix_prev = argb[0];  // Skip the first pixel.
    212     for (y = 0; y < height; ++y) {
    213       for (x = 0; x < width; ++x) {
    214         const uint32_t pix = curr_row[x];
    215         const uint32_t pix_diff = VP8LSubPixels(pix, pix_prev);
    216         pix_prev = pix;
    217         if ((pix_diff == 0) || (prev_row != NULL && pix == prev_row[x])) {
    218           continue;
    219         }
    220         AddSingle(pix,
    221                   &histo[kHistoAlpha * 256],
    222                   &histo[kHistoRed * 256],
    223                   &histo[kHistoGreen * 256],
    224                   &histo[kHistoBlue * 256]);
    225         AddSingle(pix_diff,
    226                   &histo[kHistoAlphaPred * 256],
    227                   &histo[kHistoRedPred * 256],
    228                   &histo[kHistoGreenPred * 256],
    229                   &histo[kHistoBluePred * 256]);
    230         AddSingleSubGreen(pix,
    231                           &histo[kHistoRedSubGreen * 256],
    232                           &histo[kHistoBlueSubGreen * 256]);
    233         AddSingleSubGreen(pix_diff,
    234                           &histo[kHistoRedPredSubGreen * 256],
    235                           &histo[kHistoBluePredSubGreen * 256]);
    236         {
    237           // Approximate the palette by the entropy of the multiplicative hash.
    238           const uint32_t hash = HashPix(pix);
    239           ++histo[kHistoPalette * 256 + hash];
    240         }
    241       }
    242       prev_row = curr_row;
    243       curr_row += argb_stride;
    244     }
    245     {
    246       double entropy_comp[kHistoTotal];
    247       double entropy[kNumEntropyIx];
    248       int k;
    249       int last_mode_to_analyze = use_palette ? kPalette : kSpatialSubGreen;
    250       int j;
    251       // Let's add one zero to the predicted histograms. The zeros are removed
    252       // too efficiently by the pix_diff == 0 comparison, at least one of the
    253       // zeros is likely to exist.
    254       ++histo[kHistoRedPredSubGreen * 256];
    255       ++histo[kHistoBluePredSubGreen * 256];
    256       ++histo[kHistoRedPred * 256];
    257       ++histo[kHistoGreenPred * 256];
    258       ++histo[kHistoBluePred * 256];
    259       ++histo[kHistoAlphaPred * 256];
    260 
    261       for (j = 0; j < kHistoTotal; ++j) {
    262         entropy_comp[j] = VP8LBitsEntropy(&histo[j * 256], 256, NULL);
    263       }
    264       entropy[kDirect] = entropy_comp[kHistoAlpha] +
    265           entropy_comp[kHistoRed] +
    266           entropy_comp[kHistoGreen] +
    267           entropy_comp[kHistoBlue];
    268       entropy[kSpatial] = entropy_comp[kHistoAlphaPred] +
    269           entropy_comp[kHistoRedPred] +
    270           entropy_comp[kHistoGreenPred] +
    271           entropy_comp[kHistoBluePred];
    272       entropy[kSubGreen] = entropy_comp[kHistoAlpha] +
    273           entropy_comp[kHistoRedSubGreen] +
    274           entropy_comp[kHistoGreen] +
    275           entropy_comp[kHistoBlueSubGreen];
    276       entropy[kSpatialSubGreen] = entropy_comp[kHistoAlphaPred] +
    277           entropy_comp[kHistoRedPredSubGreen] +
    278           entropy_comp[kHistoGreenPred] +
    279           entropy_comp[kHistoBluePredSubGreen];
    280       entropy[kPalette] = entropy_comp[kHistoPalette];
    281 
    282       // When including transforms, there is an overhead in bits from
    283       // storing them. This overhead is small but matters for small images.
    284       // For spatial, there are 14 transformations.
    285       entropy[kSpatial] += VP8LSubSampleSize(width, transform_bits) *
    286                            VP8LSubSampleSize(height, transform_bits) *
    287                            VP8LFastLog2(14);
    288       // For color transforms: 24 as only 3 channels are considered in a
    289       // ColorTransformElement.
    290       entropy[kSpatialSubGreen] += VP8LSubSampleSize(width, transform_bits) *
    291                                    VP8LSubSampleSize(height, transform_bits) *
    292                                    VP8LFastLog2(24);
    293       // For palettes, add the cost of storing the palette.
    294       // We empirically estimate the cost of a compressed entry as 8 bits.
    295       // The palette is differential-coded when compressed hence a much
    296       // lower cost than sizeof(uint32_t)*8.
    297       entropy[kPalette] += palette_size * 8;
    298 
    299       *min_entropy_ix = kDirect;
    300       for (k = kDirect + 1; k <= last_mode_to_analyze; ++k) {
    301         if (entropy[*min_entropy_ix] > entropy[k]) {
    302           *min_entropy_ix = (EntropyIx)k;
    303         }
    304       }
    305       assert((int)*min_entropy_ix <= last_mode_to_analyze);
    306       *red_and_blue_always_zero = 1;
    307       // Let's check if the histogram of the chosen entropy mode has
    308       // non-zero red and blue values. If all are zero, we can later skip
    309       // the cross color optimization.
    310       {
    311         static const uint8_t kHistoPairs[5][2] = {
    312           { kHistoRed, kHistoBlue },
    313           { kHistoRedPred, kHistoBluePred },
    314           { kHistoRedSubGreen, kHistoBlueSubGreen },
    315           { kHistoRedPredSubGreen, kHistoBluePredSubGreen },
    316           { kHistoRed, kHistoBlue }
    317         };
    318         const uint32_t* const red_histo =
    319             &histo[256 * kHistoPairs[*min_entropy_ix][0]];
    320         const uint32_t* const blue_histo =
    321             &histo[256 * kHistoPairs[*min_entropy_ix][1]];
    322         for (i = 1; i < 256; ++i) {
    323           if ((red_histo[i] | blue_histo[i]) != 0) {
    324             *red_and_blue_always_zero = 0;
    325             break;
    326           }
    327         }
    328       }
    329     }
    330     WebPSafeFree(histo);
    331     return 1;
    332   } else {
    333     return 0;
    334   }
    335 }
    336 
    337 static int GetHistoBits(int method, int use_palette, int width, int height) {
    338   // Make tile size a function of encoding method (Range: 0 to 6).
    339   int histo_bits = (use_palette ? 9 : 7) - method;
    340   while (1) {
    341     const int huff_image_size = VP8LSubSampleSize(width, histo_bits) *
    342                                 VP8LSubSampleSize(height, histo_bits);
    343     if (huff_image_size <= MAX_HUFF_IMAGE_SIZE) break;
    344     ++histo_bits;
    345   }
    346   return (histo_bits < MIN_HUFFMAN_BITS) ? MIN_HUFFMAN_BITS :
    347          (histo_bits > MAX_HUFFMAN_BITS) ? MAX_HUFFMAN_BITS : histo_bits;
    348 }
    349 
    350 static int GetTransformBits(int method, int histo_bits) {
    351   const int max_transform_bits = (method < 4) ? 6 : (method > 4) ? 4 : 5;
    352   const int res =
    353       (histo_bits > max_transform_bits) ? max_transform_bits : histo_bits;
    354   assert(res <= MAX_TRANSFORM_BITS);
    355   return res;
    356 }
    357 
    358 // Set of parameters to be used in each iteration of the cruncher.
    359 #define CRUNCH_CONFIGS_LZ77_MAX 2
    360 typedef struct {
    361   int entropy_idx_;
    362   int lz77s_types_to_try_[CRUNCH_CONFIGS_LZ77_MAX];
    363   int lz77s_types_to_try_size_;
    364 } CrunchConfig;
    365 
    366 #define CRUNCH_CONFIGS_MAX kNumEntropyIx
    367 
    368 static int EncoderAnalyze(VP8LEncoder* const enc,
    369                           CrunchConfig crunch_configs[CRUNCH_CONFIGS_MAX],
    370                           int* const crunch_configs_size,
    371                           int* const red_and_blue_always_zero) {
    372   const WebPPicture* const pic = enc->pic_;
    373   const int width = pic->width;
    374   const int height = pic->height;
    375   const WebPConfig* const config = enc->config_;
    376   const int method = config->method;
    377   const int low_effort = (config->method == 0);
    378   int i;
    379   int use_palette;
    380   int n_lz77s;
    381   assert(pic != NULL && pic->argb != NULL);
    382 
    383   use_palette =
    384       AnalyzeAndCreatePalette(pic, low_effort,
    385                               enc->palette_, &enc->palette_size_);
    386 
    387   // TODO(jyrki): replace the decision to be based on an actual estimate
    388   // of entropy, or even spatial variance of entropy.
    389   enc->histo_bits_ = GetHistoBits(method, use_palette,
    390                                   pic->width, pic->height);
    391   enc->transform_bits_ = GetTransformBits(method, enc->histo_bits_);
    392 
    393   if (low_effort) {
    394     // AnalyzeEntropy is somewhat slow.
    395     crunch_configs[0].entropy_idx_ = use_palette ? kPalette : kSpatialSubGreen;
    396     n_lz77s = 1;
    397     *crunch_configs_size = 1;
    398   } else {
    399     EntropyIx min_entropy_ix;
    400     // Try out multiple LZ77 on images with few colors.
    401     n_lz77s = (enc->palette_size_ > 0 && enc->palette_size_ <= 16) ? 2 : 1;
    402     if (!AnalyzeEntropy(pic->argb, width, height, pic->argb_stride, use_palette,
    403                         enc->palette_size_, enc->transform_bits_,
    404                         &min_entropy_ix, red_and_blue_always_zero)) {
    405       return 0;
    406     }
    407     if (method == 6 && config->quality == 100) {
    408       // Go brute force on all transforms.
    409       *crunch_configs_size = 0;
    410       for (i = 0; i < kNumEntropyIx; ++i) {
    411         if (i != kPalette || use_palette) {
    412           assert(*crunch_configs_size < CRUNCH_CONFIGS_MAX);
    413           crunch_configs[(*crunch_configs_size)++].entropy_idx_ = i;
    414         }
    415       }
    416     } else {
    417       // Only choose the guessed best transform.
    418       *crunch_configs_size = 1;
    419       crunch_configs[0].entropy_idx_ = min_entropy_ix;
    420     }
    421   }
    422   // Fill in the different LZ77s.
    423   assert(n_lz77s <= CRUNCH_CONFIGS_LZ77_MAX);
    424   for (i = 0; i < *crunch_configs_size; ++i) {
    425     int j;
    426     for (j = 0; j < n_lz77s; ++j) {
    427       crunch_configs[i].lz77s_types_to_try_[j] =
    428           (j == 0) ? kLZ77Standard | kLZ77RLE : kLZ77Box;
    429     }
    430     crunch_configs[i].lz77s_types_to_try_size_ = n_lz77s;
    431   }
    432   return 1;
    433 }
    434 
    435 static int EncoderInit(VP8LEncoder* const enc) {
    436   const WebPPicture* const pic = enc->pic_;
    437   const int width = pic->width;
    438   const int height = pic->height;
    439   const int pix_cnt = width * height;
    440   // we round the block size up, so we're guaranteed to have
    441   // at most MAX_REFS_BLOCK_PER_IMAGE blocks used:
    442   const int refs_block_size = (pix_cnt - 1) / MAX_REFS_BLOCK_PER_IMAGE + 1;
    443   int i;
    444   if (!VP8LHashChainInit(&enc->hash_chain_, pix_cnt)) return 0;
    445 
    446   for (i = 0; i < 3; ++i) VP8LBackwardRefsInit(&enc->refs_[i], refs_block_size);
    447 
    448   return 1;
    449 }
    450 
    451 // Returns false in case of memory error.
    452 static int GetHuffBitLengthsAndCodes(
    453     const VP8LHistogramSet* const histogram_image,
    454     HuffmanTreeCode* const huffman_codes) {
    455   int i, k;
    456   int ok = 0;
    457   uint64_t total_length_size = 0;
    458   uint8_t* mem_buf = NULL;
    459   const int histogram_image_size = histogram_image->size;
    460   int max_num_symbols = 0;
    461   uint8_t* buf_rle = NULL;
    462   HuffmanTree* huff_tree = NULL;
    463 
    464   // Iterate over all histograms and get the aggregate number of codes used.
    465   for (i = 0; i < histogram_image_size; ++i) {
    466     const VP8LHistogram* const histo = histogram_image->histograms[i];
    467     HuffmanTreeCode* const codes = &huffman_codes[5 * i];
    468     for (k = 0; k < 5; ++k) {
    469       const int num_symbols =
    470           (k == 0) ? VP8LHistogramNumCodes(histo->palette_code_bits_) :
    471           (k == 4) ? NUM_DISTANCE_CODES : 256;
    472       codes[k].num_symbols = num_symbols;
    473       total_length_size += num_symbols;
    474     }
    475   }
    476 
    477   // Allocate and Set Huffman codes.
    478   {
    479     uint16_t* codes;
    480     uint8_t* lengths;
    481     mem_buf = (uint8_t*)WebPSafeCalloc(total_length_size,
    482                                        sizeof(*lengths) + sizeof(*codes));
    483     if (mem_buf == NULL) goto End;
    484 
    485     codes = (uint16_t*)mem_buf;
    486     lengths = (uint8_t*)&codes[total_length_size];
    487     for (i = 0; i < 5 * histogram_image_size; ++i) {
    488       const int bit_length = huffman_codes[i].num_symbols;
    489       huffman_codes[i].codes = codes;
    490       huffman_codes[i].code_lengths = lengths;
    491       codes += bit_length;
    492       lengths += bit_length;
    493       if (max_num_symbols < bit_length) {
    494         max_num_symbols = bit_length;
    495       }
    496     }
    497   }
    498 
    499   buf_rle = (uint8_t*)WebPSafeMalloc(1ULL, max_num_symbols);
    500   huff_tree = (HuffmanTree*)WebPSafeMalloc(3ULL * max_num_symbols,
    501                                            sizeof(*huff_tree));
    502   if (buf_rle == NULL || huff_tree == NULL) goto End;
    503 
    504   // Create Huffman trees.
    505   for (i = 0; i < histogram_image_size; ++i) {
    506     HuffmanTreeCode* const codes = &huffman_codes[5 * i];
    507     VP8LHistogram* const histo = histogram_image->histograms[i];
    508     VP8LCreateHuffmanTree(histo->literal_, 15, buf_rle, huff_tree, codes + 0);
    509     VP8LCreateHuffmanTree(histo->red_, 15, buf_rle, huff_tree, codes + 1);
    510     VP8LCreateHuffmanTree(histo->blue_, 15, buf_rle, huff_tree, codes + 2);
    511     VP8LCreateHuffmanTree(histo->alpha_, 15, buf_rle, huff_tree, codes + 3);
    512     VP8LCreateHuffmanTree(histo->distance_, 15, buf_rle, huff_tree, codes + 4);
    513   }
    514   ok = 1;
    515  End:
    516   WebPSafeFree(huff_tree);
    517   WebPSafeFree(buf_rle);
    518   if (!ok) {
    519     WebPSafeFree(mem_buf);
    520     memset(huffman_codes, 0, 5 * histogram_image_size * sizeof(*huffman_codes));
    521   }
    522   return ok;
    523 }
    524 
    525 static void StoreHuffmanTreeOfHuffmanTreeToBitMask(
    526     VP8LBitWriter* const bw, const uint8_t* code_length_bitdepth) {
    527   // RFC 1951 will calm you down if you are worried about this funny sequence.
    528   // This sequence is tuned from that, but more weighted for lower symbol count,
    529   // and more spiking histograms.
    530   static const uint8_t kStorageOrder[CODE_LENGTH_CODES] = {
    531     17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
    532   };
    533   int i;
    534   // Throw away trailing zeros:
    535   int codes_to_store = CODE_LENGTH_CODES;
    536   for (; codes_to_store > 4; --codes_to_store) {
    537     if (code_length_bitdepth[kStorageOrder[codes_to_store - 1]] != 0) {
    538       break;
    539     }
    540   }
    541   VP8LPutBits(bw, codes_to_store - 4, 4);
    542   for (i = 0; i < codes_to_store; ++i) {
    543     VP8LPutBits(bw, code_length_bitdepth[kStorageOrder[i]], 3);
    544   }
    545 }
    546 
    547 static void ClearHuffmanTreeIfOnlyOneSymbol(
    548     HuffmanTreeCode* const huffman_code) {
    549   int k;
    550   int count = 0;
    551   for (k = 0; k < huffman_code->num_symbols; ++k) {
    552     if (huffman_code->code_lengths[k] != 0) {
    553       ++count;
    554       if (count > 1) return;
    555     }
    556   }
    557   for (k = 0; k < huffman_code->num_symbols; ++k) {
    558     huffman_code->code_lengths[k] = 0;
    559     huffman_code->codes[k] = 0;
    560   }
    561 }
    562 
    563 static void StoreHuffmanTreeToBitMask(
    564     VP8LBitWriter* const bw,
    565     const HuffmanTreeToken* const tokens, const int num_tokens,
    566     const HuffmanTreeCode* const huffman_code) {
    567   int i;
    568   for (i = 0; i < num_tokens; ++i) {
    569     const int ix = tokens[i].code;
    570     const int extra_bits = tokens[i].extra_bits;
    571     VP8LPutBits(bw, huffman_code->codes[ix], huffman_code->code_lengths[ix]);
    572     switch (ix) {
    573       case 16:
    574         VP8LPutBits(bw, extra_bits, 2);
    575         break;
    576       case 17:
    577         VP8LPutBits(bw, extra_bits, 3);
    578         break;
    579       case 18:
    580         VP8LPutBits(bw, extra_bits, 7);
    581         break;
    582     }
    583   }
    584 }
    585 
    586 // 'huff_tree' and 'tokens' are pre-alloacted buffers.
    587 static void StoreFullHuffmanCode(VP8LBitWriter* const bw,
    588                                  HuffmanTree* const huff_tree,
    589                                  HuffmanTreeToken* const tokens,
    590                                  const HuffmanTreeCode* const tree) {
    591   uint8_t code_length_bitdepth[CODE_LENGTH_CODES] = { 0 };
    592   uint16_t code_length_bitdepth_symbols[CODE_LENGTH_CODES] = { 0 };
    593   const int max_tokens = tree->num_symbols;
    594   int num_tokens;
    595   HuffmanTreeCode huffman_code;
    596   huffman_code.num_symbols = CODE_LENGTH_CODES;
    597   huffman_code.code_lengths = code_length_bitdepth;
    598   huffman_code.codes = code_length_bitdepth_symbols;
    599 
    600   VP8LPutBits(bw, 0, 1);
    601   num_tokens = VP8LCreateCompressedHuffmanTree(tree, tokens, max_tokens);
    602   {
    603     uint32_t histogram[CODE_LENGTH_CODES] = { 0 };
    604     uint8_t buf_rle[CODE_LENGTH_CODES] = { 0 };
    605     int i;
    606     for (i = 0; i < num_tokens; ++i) {
    607       ++histogram[tokens[i].code];
    608     }
    609 
    610     VP8LCreateHuffmanTree(histogram, 7, buf_rle, huff_tree, &huffman_code);
    611   }
    612 
    613   StoreHuffmanTreeOfHuffmanTreeToBitMask(bw, code_length_bitdepth);
    614   ClearHuffmanTreeIfOnlyOneSymbol(&huffman_code);
    615   {
    616     int trailing_zero_bits = 0;
    617     int trimmed_length = num_tokens;
    618     int write_trimmed_length;
    619     int length;
    620     int i = num_tokens;
    621     while (i-- > 0) {
    622       const int ix = tokens[i].code;
    623       if (ix == 0 || ix == 17 || ix == 18) {
    624         --trimmed_length;   // discount trailing zeros
    625         trailing_zero_bits += code_length_bitdepth[ix];
    626         if (ix == 17) {
    627           trailing_zero_bits += 3;
    628         } else if (ix == 18) {
    629           trailing_zero_bits += 7;
    630         }
    631       } else {
    632         break;
    633       }
    634     }
    635     write_trimmed_length = (trimmed_length > 1 && trailing_zero_bits > 12);
    636     length = write_trimmed_length ? trimmed_length : num_tokens;
    637     VP8LPutBits(bw, write_trimmed_length, 1);
    638     if (write_trimmed_length) {
    639       if (trimmed_length == 2) {
    640         VP8LPutBits(bw, 0, 3 + 2);     // nbitpairs=1, trimmed_length=2
    641       } else {
    642         const int nbits = BitsLog2Floor(trimmed_length - 2);
    643         const int nbitpairs = nbits / 2 + 1;
    644         assert(trimmed_length > 2);
    645         assert(nbitpairs - 1 < 8);
    646         VP8LPutBits(bw, nbitpairs - 1, 3);
    647         VP8LPutBits(bw, trimmed_length - 2, nbitpairs * 2);
    648       }
    649     }
    650     StoreHuffmanTreeToBitMask(bw, tokens, length, &huffman_code);
    651   }
    652 }
    653 
    654 // 'huff_tree' and 'tokens' are pre-alloacted buffers.
    655 static void StoreHuffmanCode(VP8LBitWriter* const bw,
    656                              HuffmanTree* const huff_tree,
    657                              HuffmanTreeToken* const tokens,
    658                              const HuffmanTreeCode* const huffman_code) {
    659   int i;
    660   int count = 0;
    661   int symbols[2] = { 0, 0 };
    662   const int kMaxBits = 8;
    663   const int kMaxSymbol = 1 << kMaxBits;
    664 
    665   // Check whether it's a small tree.
    666   for (i = 0; i < huffman_code->num_symbols && count < 3; ++i) {
    667     if (huffman_code->code_lengths[i] != 0) {
    668       if (count < 2) symbols[count] = i;
    669       ++count;
    670     }
    671   }
    672 
    673   if (count == 0) {   // emit minimal tree for empty cases
    674     // bits: small tree marker: 1, count-1: 0, large 8-bit code: 0, code: 0
    675     VP8LPutBits(bw, 0x01, 4);
    676   } else if (count <= 2 && symbols[0] < kMaxSymbol && symbols[1] < kMaxSymbol) {
    677     VP8LPutBits(bw, 1, 1);  // Small tree marker to encode 1 or 2 symbols.
    678     VP8LPutBits(bw, count - 1, 1);
    679     if (symbols[0] <= 1) {
    680       VP8LPutBits(bw, 0, 1);  // Code bit for small (1 bit) symbol value.
    681       VP8LPutBits(bw, symbols[0], 1);
    682     } else {
    683       VP8LPutBits(bw, 1, 1);
    684       VP8LPutBits(bw, symbols[0], 8);
    685     }
    686     if (count == 2) {
    687       VP8LPutBits(bw, symbols[1], 8);
    688     }
    689   } else {
    690     StoreFullHuffmanCode(bw, huff_tree, tokens, huffman_code);
    691   }
    692 }
    693 
    694 static WEBP_INLINE void WriteHuffmanCode(VP8LBitWriter* const bw,
    695                              const HuffmanTreeCode* const code,
    696                              int code_index) {
    697   const int depth = code->code_lengths[code_index];
    698   const int symbol = code->codes[code_index];
    699   VP8LPutBits(bw, symbol, depth);
    700 }
    701 
    702 static WEBP_INLINE void WriteHuffmanCodeWithExtraBits(
    703     VP8LBitWriter* const bw,
    704     const HuffmanTreeCode* const code,
    705     int code_index,
    706     int bits,
    707     int n_bits) {
    708   const int depth = code->code_lengths[code_index];
    709   const int symbol = code->codes[code_index];
    710   VP8LPutBits(bw, (bits << depth) | symbol, depth + n_bits);
    711 }
    712 
    713 static WebPEncodingError StoreImageToBitMask(
    714     VP8LBitWriter* const bw, int width, int histo_bits,
    715     const VP8LBackwardRefs* const refs,
    716     const uint16_t* histogram_symbols,
    717     const HuffmanTreeCode* const huffman_codes) {
    718   const int histo_xsize = histo_bits ? VP8LSubSampleSize(width, histo_bits) : 1;
    719   const int tile_mask = (histo_bits == 0) ? 0 : -(1 << histo_bits);
    720   // x and y trace the position in the image.
    721   int x = 0;
    722   int y = 0;
    723   int tile_x = x & tile_mask;
    724   int tile_y = y & tile_mask;
    725   int histogram_ix = histogram_symbols[0];
    726   const HuffmanTreeCode* codes = huffman_codes + 5 * histogram_ix;
    727   VP8LRefsCursor c = VP8LRefsCursorInit(refs);
    728   while (VP8LRefsCursorOk(&c)) {
    729     const PixOrCopy* const v = c.cur_pos;
    730     if ((tile_x != (x & tile_mask)) || (tile_y != (y & tile_mask))) {
    731       tile_x = x & tile_mask;
    732       tile_y = y & tile_mask;
    733       histogram_ix = histogram_symbols[(y >> histo_bits) * histo_xsize +
    734                                        (x >> histo_bits)];
    735       codes = huffman_codes + 5 * histogram_ix;
    736     }
    737     if (PixOrCopyIsLiteral(v)) {
    738       static const uint8_t order[] = { 1, 2, 0, 3 };
    739       int k;
    740       for (k = 0; k < 4; ++k) {
    741         const int code = PixOrCopyLiteral(v, order[k]);
    742         WriteHuffmanCode(bw, codes + k, code);
    743       }
    744     } else if (PixOrCopyIsCacheIdx(v)) {
    745       const int code = PixOrCopyCacheIdx(v);
    746       const int literal_ix = 256 + NUM_LENGTH_CODES + code;
    747       WriteHuffmanCode(bw, codes, literal_ix);
    748     } else {
    749       int bits, n_bits;
    750       int code;
    751 
    752       const int distance = PixOrCopyDistance(v);
    753       VP8LPrefixEncode(v->len, &code, &n_bits, &bits);
    754       WriteHuffmanCodeWithExtraBits(bw, codes, 256 + code, bits, n_bits);
    755 
    756       // Don't write the distance with the extra bits code since
    757       // the distance can be up to 18 bits of extra bits, and the prefix
    758       // 15 bits, totaling to 33, and our PutBits only supports up to 32 bits.
    759       // TODO(jyrki): optimize this further.
    760       VP8LPrefixEncode(distance, &code, &n_bits, &bits);
    761       WriteHuffmanCode(bw, codes + 4, code);
    762       VP8LPutBits(bw, bits, n_bits);
    763     }
    764     x += PixOrCopyLength(v);
    765     while (x >= width) {
    766       x -= width;
    767       ++y;
    768     }
    769     VP8LRefsCursorNext(&c);
    770   }
    771   return bw->error_ ? VP8_ENC_ERROR_OUT_OF_MEMORY : VP8_ENC_OK;
    772 }
    773 
    774 // Special case of EncodeImageInternal() for cache-bits=0, histo_bits=31
    775 static WebPEncodingError EncodeImageNoHuffman(VP8LBitWriter* const bw,
    776                                               const uint32_t* const argb,
    777                                               VP8LHashChain* const hash_chain,
    778                                               VP8LBackwardRefs* const refs_tmp1,
    779                                               VP8LBackwardRefs* const refs_tmp2,
    780                                               int width, int height,
    781                                               int quality, int low_effort) {
    782   int i;
    783   int max_tokens = 0;
    784   WebPEncodingError err = VP8_ENC_OK;
    785   VP8LBackwardRefs* refs;
    786   HuffmanTreeToken* tokens = NULL;
    787   HuffmanTreeCode huffman_codes[5] = { { 0, NULL, NULL } };
    788   const uint16_t histogram_symbols[1] = { 0 };    // only one tree, one symbol
    789   int cache_bits = 0;
    790   VP8LHistogramSet* histogram_image = NULL;
    791   HuffmanTree* const huff_tree = (HuffmanTree*)WebPSafeMalloc(
    792         3ULL * CODE_LENGTH_CODES, sizeof(*huff_tree));
    793   if (huff_tree == NULL) {
    794     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
    795     goto Error;
    796   }
    797 
    798   // Calculate backward references from ARGB image.
    799   if (!VP8LHashChainFill(hash_chain, quality, argb, width, height,
    800                          low_effort)) {
    801     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
    802     goto Error;
    803   }
    804   refs = VP8LGetBackwardReferences(width, height, argb, quality, 0,
    805                                    kLZ77Standard | kLZ77RLE, &cache_bits,
    806                                    hash_chain, refs_tmp1, refs_tmp2);
    807   if (refs == NULL) {
    808     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
    809     goto Error;
    810   }
    811   histogram_image = VP8LAllocateHistogramSet(1, cache_bits);
    812   if (histogram_image == NULL) {
    813     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
    814     goto Error;
    815   }
    816 
    817   // Build histogram image and symbols from backward references.
    818   VP8LHistogramStoreRefs(refs, histogram_image->histograms[0]);
    819 
    820   // Create Huffman bit lengths and codes for each histogram image.
    821   assert(histogram_image->size == 1);
    822   if (!GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) {
    823     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
    824     goto Error;
    825   }
    826 
    827   // No color cache, no Huffman image.
    828   VP8LPutBits(bw, 0, 1);
    829 
    830   // Find maximum number of symbols for the huffman tree-set.
    831   for (i = 0; i < 5; ++i) {
    832     HuffmanTreeCode* const codes = &huffman_codes[i];
    833     if (max_tokens < codes->num_symbols) {
    834       max_tokens = codes->num_symbols;
    835     }
    836   }
    837 
    838   tokens = (HuffmanTreeToken*)WebPSafeMalloc(max_tokens, sizeof(*tokens));
    839   if (tokens == NULL) {
    840     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
    841     goto Error;
    842   }
    843 
    844   // Store Huffman codes.
    845   for (i = 0; i < 5; ++i) {
    846     HuffmanTreeCode* const codes = &huffman_codes[i];
    847     StoreHuffmanCode(bw, huff_tree, tokens, codes);
    848     ClearHuffmanTreeIfOnlyOneSymbol(codes);
    849   }
    850 
    851   // Store actual literals.
    852   err = StoreImageToBitMask(bw, width, 0, refs, histogram_symbols,
    853                             huffman_codes);
    854 
    855  Error:
    856   WebPSafeFree(tokens);
    857   WebPSafeFree(huff_tree);
    858   VP8LFreeHistogramSet(histogram_image);
    859   WebPSafeFree(huffman_codes[0].codes);
    860   return err;
    861 }
    862 
    863 static WebPEncodingError EncodeImageInternal(
    864     VP8LBitWriter* const bw, const uint32_t* const argb,
    865     VP8LHashChain* const hash_chain, VP8LBackwardRefs refs_array[3], int width,
    866     int height, int quality, int low_effort, int use_cache,
    867     const CrunchConfig* const config, int* cache_bits, int histogram_bits,
    868     size_t init_byte_position, int* const hdr_size, int* const data_size) {
    869   WebPEncodingError err = VP8_ENC_OK;
    870   const uint32_t histogram_image_xysize =
    871       VP8LSubSampleSize(width, histogram_bits) *
    872       VP8LSubSampleSize(height, histogram_bits);
    873   VP8LHistogramSet* histogram_image = NULL;
    874   VP8LHistogram* tmp_histo = NULL;
    875   int histogram_image_size = 0;
    876   size_t bit_array_size = 0;
    877   HuffmanTree* const huff_tree = (HuffmanTree*)WebPSafeMalloc(
    878       3ULL * CODE_LENGTH_CODES, sizeof(*huff_tree));
    879   HuffmanTreeToken* tokens = NULL;
    880   HuffmanTreeCode* huffman_codes = NULL;
    881   VP8LBackwardRefs* refs_best;
    882   VP8LBackwardRefs* refs_tmp;
    883   uint16_t* const histogram_symbols =
    884       (uint16_t*)WebPSafeMalloc(histogram_image_xysize,
    885                                 sizeof(*histogram_symbols));
    886   int lz77s_idx;
    887   VP8LBitWriter bw_init = *bw, bw_best;
    888   int hdr_size_tmp;
    889   assert(histogram_bits >= MIN_HUFFMAN_BITS);
    890   assert(histogram_bits <= MAX_HUFFMAN_BITS);
    891   assert(hdr_size != NULL);
    892   assert(data_size != NULL);
    893 
    894   if (histogram_symbols == NULL) {
    895     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
    896     goto Error;
    897   }
    898 
    899   if (use_cache) {
    900     // If the value is different from zero, it has been set during the
    901     // palette analysis.
    902     if (*cache_bits == 0) *cache_bits = MAX_COLOR_CACHE_BITS;
    903   } else {
    904     *cache_bits = 0;
    905   }
    906   // 'best_refs' is the reference to the best backward refs and points to one
    907   // of refs_array[0] or refs_array[1].
    908   // Calculate backward references from ARGB image.
    909   if (huff_tree == NULL ||
    910       !VP8LHashChainFill(hash_chain, quality, argb, width, height,
    911                          low_effort) ||
    912       !VP8LBitWriterInit(&bw_best, 0) ||
    913       (config->lz77s_types_to_try_size_ > 1 &&
    914        !VP8LBitWriterClone(bw, &bw_best))) {
    915     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
    916     goto Error;
    917   }
    918   for (lz77s_idx = 0; lz77s_idx < config->lz77s_types_to_try_size_;
    919        ++lz77s_idx) {
    920     refs_best = VP8LGetBackwardReferences(
    921         width, height, argb, quality, low_effort,
    922         config->lz77s_types_to_try_[lz77s_idx], cache_bits, hash_chain,
    923         &refs_array[0], &refs_array[1]);
    924     if (refs_best == NULL) {
    925       err = VP8_ENC_ERROR_OUT_OF_MEMORY;
    926       goto Error;
    927     }
    928     // Keep the best references aside and use the other element from the first
    929     // two as a temporary for later usage.
    930     refs_tmp = &refs_array[refs_best == &refs_array[0] ? 1 : 0];
    931 
    932     histogram_image =
    933         VP8LAllocateHistogramSet(histogram_image_xysize, *cache_bits);
    934     tmp_histo = VP8LAllocateHistogram(*cache_bits);
    935     if (histogram_image == NULL || tmp_histo == NULL) {
    936       err = VP8_ENC_ERROR_OUT_OF_MEMORY;
    937       goto Error;
    938     }
    939 
    940     // Build histogram image and symbols from backward references.
    941     if (!VP8LGetHistoImageSymbols(width, height, refs_best, quality, low_effort,
    942                                   histogram_bits, *cache_bits, histogram_image,
    943                                   tmp_histo, histogram_symbols)) {
    944       err = VP8_ENC_ERROR_OUT_OF_MEMORY;
    945       goto Error;
    946     }
    947     // Create Huffman bit lengths and codes for each histogram image.
    948     histogram_image_size = histogram_image->size;
    949     bit_array_size = 5 * histogram_image_size;
    950     huffman_codes = (HuffmanTreeCode*)WebPSafeCalloc(bit_array_size,
    951                                                      sizeof(*huffman_codes));
    952     // Note: some histogram_image entries may point to tmp_histos[], so the
    953     // latter need to outlive the following call to GetHuffBitLengthsAndCodes().
    954     if (huffman_codes == NULL ||
    955         !GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) {
    956       err = VP8_ENC_ERROR_OUT_OF_MEMORY;
    957       goto Error;
    958     }
    959     // Free combined histograms.
    960     VP8LFreeHistogramSet(histogram_image);
    961     histogram_image = NULL;
    962 
    963     // Free scratch histograms.
    964     VP8LFreeHistogram(tmp_histo);
    965     tmp_histo = NULL;
    966 
    967     // Color Cache parameters.
    968     if (*cache_bits > 0) {
    969       VP8LPutBits(bw, 1, 1);
    970       VP8LPutBits(bw, *cache_bits, 4);
    971     } else {
    972       VP8LPutBits(bw, 0, 1);
    973     }
    974 
    975     // Huffman image + meta huffman.
    976     {
    977       const int write_histogram_image = (histogram_image_size > 1);
    978       VP8LPutBits(bw, write_histogram_image, 1);
    979       if (write_histogram_image) {
    980         uint32_t* const histogram_argb =
    981             (uint32_t*)WebPSafeMalloc(histogram_image_xysize,
    982                                       sizeof(*histogram_argb));
    983         int max_index = 0;
    984         uint32_t i;
    985         if (histogram_argb == NULL) {
    986           err = VP8_ENC_ERROR_OUT_OF_MEMORY;
    987           goto Error;
    988         }
    989         for (i = 0; i < histogram_image_xysize; ++i) {
    990           const int symbol_index = histogram_symbols[i] & 0xffff;
    991           histogram_argb[i] = (symbol_index << 8);
    992           if (symbol_index >= max_index) {
    993             max_index = symbol_index + 1;
    994           }
    995         }
    996         histogram_image_size = max_index;
    997 
    998         VP8LPutBits(bw, histogram_bits - 2, 3);
    999         err = EncodeImageNoHuffman(
   1000             bw, histogram_argb, hash_chain, refs_tmp, &refs_array[2],
   1001             VP8LSubSampleSize(width, histogram_bits),
   1002             VP8LSubSampleSize(height, histogram_bits), quality, low_effort);
   1003         WebPSafeFree(histogram_argb);
   1004         if (err != VP8_ENC_OK) goto Error;
   1005       }
   1006     }
   1007 
   1008     // Store Huffman codes.
   1009     {
   1010       int i;
   1011       int max_tokens = 0;
   1012       // Find maximum number of symbols for the huffman tree-set.
   1013       for (i = 0; i < 5 * histogram_image_size; ++i) {
   1014         HuffmanTreeCode* const codes = &huffman_codes[i];
   1015         if (max_tokens < codes->num_symbols) {
   1016           max_tokens = codes->num_symbols;
   1017         }
   1018       }
   1019       tokens = (HuffmanTreeToken*)WebPSafeMalloc(max_tokens, sizeof(*tokens));
   1020       if (tokens == NULL) {
   1021         err = VP8_ENC_ERROR_OUT_OF_MEMORY;
   1022         goto Error;
   1023       }
   1024       for (i = 0; i < 5 * histogram_image_size; ++i) {
   1025         HuffmanTreeCode* const codes = &huffman_codes[i];
   1026         StoreHuffmanCode(bw, huff_tree, tokens, codes);
   1027         ClearHuffmanTreeIfOnlyOneSymbol(codes);
   1028       }
   1029     }
   1030     // Store actual literals.
   1031     hdr_size_tmp = (int)(VP8LBitWriterNumBytes(bw) - init_byte_position);
   1032     err = StoreImageToBitMask(bw, width, histogram_bits, refs_best,
   1033                               histogram_symbols, huffman_codes);
   1034     // Keep track of the smallest image so far.
   1035     if (lz77s_idx == 0 ||
   1036         VP8LBitWriterNumBytes(bw) < VP8LBitWriterNumBytes(&bw_best)) {
   1037       *hdr_size = hdr_size_tmp;
   1038       *data_size =
   1039           (int)(VP8LBitWriterNumBytes(bw) - init_byte_position - *hdr_size);
   1040       VP8LBitWriterSwap(bw, &bw_best);
   1041     }
   1042     // Reset the bit writer for the following iteration if any.
   1043     if (config->lz77s_types_to_try_size_ > 1) VP8LBitWriterReset(&bw_init, bw);
   1044     WebPSafeFree(tokens);
   1045     tokens = NULL;
   1046     if (huffman_codes != NULL) {
   1047       WebPSafeFree(huffman_codes->codes);
   1048       WebPSafeFree(huffman_codes);
   1049       huffman_codes = NULL;
   1050     }
   1051   }
   1052   VP8LBitWriterSwap(bw, &bw_best);
   1053 
   1054  Error:
   1055   WebPSafeFree(tokens);
   1056   WebPSafeFree(huff_tree);
   1057   VP8LFreeHistogramSet(histogram_image);
   1058   VP8LFreeHistogram(tmp_histo);
   1059   if (huffman_codes != NULL) {
   1060     WebPSafeFree(huffman_codes->codes);
   1061     WebPSafeFree(huffman_codes);
   1062   }
   1063   WebPSafeFree(histogram_symbols);
   1064   VP8LBitWriterWipeOut(&bw_best);
   1065   return err;
   1066 }
   1067 
   1068 // -----------------------------------------------------------------------------
   1069 // Transforms
   1070 
   1071 static void ApplySubtractGreen(VP8LEncoder* const enc, int width, int height,
   1072                                VP8LBitWriter* const bw) {
   1073   VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
   1074   VP8LPutBits(bw, SUBTRACT_GREEN, 2);
   1075   VP8LSubtractGreenFromBlueAndRed(enc->argb_, width * height);
   1076 }
   1077 
   1078 static WebPEncodingError ApplyPredictFilter(const VP8LEncoder* const enc,
   1079                                             int width, int height,
   1080                                             int quality, int low_effort,
   1081                                             int used_subtract_green,
   1082                                             VP8LBitWriter* const bw) {
   1083   const int pred_bits = enc->transform_bits_;
   1084   const int transform_width = VP8LSubSampleSize(width, pred_bits);
   1085   const int transform_height = VP8LSubSampleSize(height, pred_bits);
   1086   // we disable near-lossless quantization if palette is used.
   1087   const int near_lossless_strength = enc->use_palette_ ? 100
   1088                                    : enc->config_->near_lossless;
   1089 
   1090   VP8LResidualImage(width, height, pred_bits, low_effort, enc->argb_,
   1091                     enc->argb_scratch_, enc->transform_data_,
   1092                     near_lossless_strength, enc->config_->exact,
   1093                     used_subtract_green);
   1094   VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
   1095   VP8LPutBits(bw, PREDICTOR_TRANSFORM, 2);
   1096   assert(pred_bits >= 2);
   1097   VP8LPutBits(bw, pred_bits - 2, 3);
   1098   return EncodeImageNoHuffman(
   1099       bw, enc->transform_data_, (VP8LHashChain*)&enc->hash_chain_,
   1100       (VP8LBackwardRefs*)&enc->refs_[0],  // cast const away
   1101       (VP8LBackwardRefs*)&enc->refs_[1], transform_width, transform_height,
   1102       quality, low_effort);
   1103 }
   1104 
   1105 static WebPEncodingError ApplyCrossColorFilter(const VP8LEncoder* const enc,
   1106                                                int width, int height,
   1107                                                int quality, int low_effort,
   1108                                                VP8LBitWriter* const bw) {
   1109   const int ccolor_transform_bits = enc->transform_bits_;
   1110   const int transform_width = VP8LSubSampleSize(width, ccolor_transform_bits);
   1111   const int transform_height = VP8LSubSampleSize(height, ccolor_transform_bits);
   1112 
   1113   VP8LColorSpaceTransform(width, height, ccolor_transform_bits, quality,
   1114                           enc->argb_, enc->transform_data_);
   1115   VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
   1116   VP8LPutBits(bw, CROSS_COLOR_TRANSFORM, 2);
   1117   assert(ccolor_transform_bits >= 2);
   1118   VP8LPutBits(bw, ccolor_transform_bits - 2, 3);
   1119   return EncodeImageNoHuffman(
   1120       bw, enc->transform_data_, (VP8LHashChain*)&enc->hash_chain_,
   1121       (VP8LBackwardRefs*)&enc->refs_[0],  // cast const away
   1122       (VP8LBackwardRefs*)&enc->refs_[1], transform_width, transform_height,
   1123       quality, low_effort);
   1124 }
   1125 
   1126 // -----------------------------------------------------------------------------
   1127 
   1128 static WebPEncodingError WriteRiffHeader(const WebPPicture* const pic,
   1129                                          size_t riff_size, size_t vp8l_size) {
   1130   uint8_t riff[RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE + VP8L_SIGNATURE_SIZE] = {
   1131     'R', 'I', 'F', 'F', 0, 0, 0, 0, 'W', 'E', 'B', 'P',
   1132     'V', 'P', '8', 'L', 0, 0, 0, 0, VP8L_MAGIC_BYTE,
   1133   };
   1134   PutLE32(riff + TAG_SIZE, (uint32_t)riff_size);
   1135   PutLE32(riff + RIFF_HEADER_SIZE + TAG_SIZE, (uint32_t)vp8l_size);
   1136   if (!pic->writer(riff, sizeof(riff), pic)) {
   1137     return VP8_ENC_ERROR_BAD_WRITE;
   1138   }
   1139   return VP8_ENC_OK;
   1140 }
   1141 
   1142 static int WriteImageSize(const WebPPicture* const pic,
   1143                           VP8LBitWriter* const bw) {
   1144   const int width = pic->width - 1;
   1145   const int height = pic->height - 1;
   1146   assert(width < WEBP_MAX_DIMENSION && height < WEBP_MAX_DIMENSION);
   1147 
   1148   VP8LPutBits(bw, width, VP8L_IMAGE_SIZE_BITS);
   1149   VP8LPutBits(bw, height, VP8L_IMAGE_SIZE_BITS);
   1150   return !bw->error_;
   1151 }
   1152 
   1153 static int WriteRealAlphaAndVersion(VP8LBitWriter* const bw, int has_alpha) {
   1154   VP8LPutBits(bw, has_alpha, 1);
   1155   VP8LPutBits(bw, VP8L_VERSION, VP8L_VERSION_BITS);
   1156   return !bw->error_;
   1157 }
   1158 
   1159 static WebPEncodingError WriteImage(const WebPPicture* const pic,
   1160                                     VP8LBitWriter* const bw,
   1161                                     size_t* const coded_size) {
   1162   WebPEncodingError err = VP8_ENC_OK;
   1163   const uint8_t* const webpll_data = VP8LBitWriterFinish(bw);
   1164   const size_t webpll_size = VP8LBitWriterNumBytes(bw);
   1165   const size_t vp8l_size = VP8L_SIGNATURE_SIZE + webpll_size;
   1166   const size_t pad = vp8l_size & 1;
   1167   const size_t riff_size = TAG_SIZE + CHUNK_HEADER_SIZE + vp8l_size + pad;
   1168 
   1169   err = WriteRiffHeader(pic, riff_size, vp8l_size);
   1170   if (err != VP8_ENC_OK) goto Error;
   1171 
   1172   if (!pic->writer(webpll_data, webpll_size, pic)) {
   1173     err = VP8_ENC_ERROR_BAD_WRITE;
   1174     goto Error;
   1175   }
   1176 
   1177   if (pad) {
   1178     const uint8_t pad_byte[1] = { 0 };
   1179     if (!pic->writer(pad_byte, 1, pic)) {
   1180       err = VP8_ENC_ERROR_BAD_WRITE;
   1181       goto Error;
   1182     }
   1183   }
   1184   *coded_size = CHUNK_HEADER_SIZE + riff_size;
   1185   return VP8_ENC_OK;
   1186 
   1187  Error:
   1188   return err;
   1189 }
   1190 
   1191 // -----------------------------------------------------------------------------
   1192 
   1193 static void ClearTransformBuffer(VP8LEncoder* const enc) {
   1194   WebPSafeFree(enc->transform_mem_);
   1195   enc->transform_mem_ = NULL;
   1196   enc->transform_mem_size_ = 0;
   1197 }
   1198 
   1199 // Allocates the memory for argb (W x H) buffer, 2 rows of context for
   1200 // prediction and transform data.
   1201 // Flags influencing the memory allocated:
   1202 //  enc->transform_bits_
   1203 //  enc->use_predict_, enc->use_cross_color_
   1204 static WebPEncodingError AllocateTransformBuffer(VP8LEncoder* const enc,
   1205                                                  int width, int height) {
   1206   WebPEncodingError err = VP8_ENC_OK;
   1207   const uint64_t image_size = width * height;
   1208   // VP8LResidualImage needs room for 2 scanlines of uint32 pixels with an extra
   1209   // pixel in each, plus 2 regular scanlines of bytes.
   1210   // TODO(skal): Clean up by using arithmetic in bytes instead of words.
   1211   const uint64_t argb_scratch_size =
   1212       enc->use_predict_
   1213           ? (width + 1) * 2 +
   1214             (width * 2 + sizeof(uint32_t) - 1) / sizeof(uint32_t)
   1215           : 0;
   1216   const uint64_t transform_data_size =
   1217       (enc->use_predict_ || enc->use_cross_color_)
   1218           ? VP8LSubSampleSize(width, enc->transform_bits_) *
   1219                 VP8LSubSampleSize(height, enc->transform_bits_)
   1220           : 0;
   1221   const uint64_t max_alignment_in_words =
   1222       (WEBP_ALIGN_CST + sizeof(uint32_t) - 1) / sizeof(uint32_t);
   1223   const uint64_t mem_size =
   1224       image_size + max_alignment_in_words +
   1225       argb_scratch_size + max_alignment_in_words +
   1226       transform_data_size;
   1227   uint32_t* mem = enc->transform_mem_;
   1228   if (mem == NULL || mem_size > enc->transform_mem_size_) {
   1229     ClearTransformBuffer(enc);
   1230     mem = (uint32_t*)WebPSafeMalloc(mem_size, sizeof(*mem));
   1231     if (mem == NULL) {
   1232       err = VP8_ENC_ERROR_OUT_OF_MEMORY;
   1233       goto Error;
   1234     }
   1235     enc->transform_mem_ = mem;
   1236     enc->transform_mem_size_ = (size_t)mem_size;
   1237     enc->argb_content_ = kEncoderNone;
   1238   }
   1239   enc->argb_ = mem;
   1240   mem = (uint32_t*)WEBP_ALIGN(mem + image_size);
   1241   enc->argb_scratch_ = mem;
   1242   mem = (uint32_t*)WEBP_ALIGN(mem + argb_scratch_size);
   1243   enc->transform_data_ = mem;
   1244 
   1245   enc->current_width_ = width;
   1246  Error:
   1247   return err;
   1248 }
   1249 
   1250 static WebPEncodingError MakeInputImageCopy(VP8LEncoder* const enc) {
   1251   WebPEncodingError err = VP8_ENC_OK;
   1252   const WebPPicture* const picture = enc->pic_;
   1253   const int width = picture->width;
   1254   const int height = picture->height;
   1255   int y;
   1256   err = AllocateTransformBuffer(enc, width, height);
   1257   if (err != VP8_ENC_OK) return err;
   1258   if (enc->argb_content_ == kEncoderARGB) return VP8_ENC_OK;
   1259   for (y = 0; y < height; ++y) {
   1260     memcpy(enc->argb_ + y * width,
   1261            picture->argb + y * picture->argb_stride,
   1262            width * sizeof(*enc->argb_));
   1263   }
   1264   enc->argb_content_ = kEncoderARGB;
   1265   assert(enc->current_width_ == width);
   1266   return VP8_ENC_OK;
   1267 }
   1268 
   1269 // -----------------------------------------------------------------------------
   1270 
   1271 static WEBP_INLINE int SearchColorNoIdx(const uint32_t sorted[], uint32_t color,
   1272                                         int hi) {
   1273   int low = 0;
   1274   if (sorted[low] == color) return low;  // loop invariant: sorted[low] != color
   1275   while (1) {
   1276     const int mid = (low + hi) >> 1;
   1277     if (sorted[mid] == color) {
   1278       return mid;
   1279     } else if (sorted[mid] < color) {
   1280       low = mid;
   1281     } else {
   1282       hi = mid;
   1283     }
   1284   }
   1285 }
   1286 
   1287 #define APPLY_PALETTE_GREEDY_MAX 4
   1288 
   1289 static WEBP_INLINE uint32_t SearchColorGreedy(const uint32_t palette[],
   1290                                               int palette_size,
   1291                                               uint32_t color) {
   1292   (void)palette_size;
   1293   assert(palette_size < APPLY_PALETTE_GREEDY_MAX);
   1294   assert(3 == APPLY_PALETTE_GREEDY_MAX - 1);
   1295   if (color == palette[0]) return 0;
   1296   if (color == palette[1]) return 1;
   1297   if (color == palette[2]) return 2;
   1298   return 3;
   1299 }
   1300 
   1301 static WEBP_INLINE uint32_t ApplyPaletteHash0(uint32_t color) {
   1302   // Focus on the green color.
   1303   return (color >> 8) & 0xff;
   1304 }
   1305 
   1306 #define PALETTE_INV_SIZE_BITS 11
   1307 #define PALETTE_INV_SIZE (1 << PALETTE_INV_SIZE_BITS)
   1308 
   1309 static WEBP_INLINE uint32_t ApplyPaletteHash1(uint32_t color) {
   1310   // Forget about alpha.
   1311   return ((uint32_t)((color & 0x00ffffffu) * 4222244071ull)) >>
   1312          (32 - PALETTE_INV_SIZE_BITS);
   1313 }
   1314 
   1315 static WEBP_INLINE uint32_t ApplyPaletteHash2(uint32_t color) {
   1316   // Forget about alpha.
   1317   return ((uint32_t)((color & 0x00ffffffu) * ((1ull << 31) - 1))) >>
   1318          (32 - PALETTE_INV_SIZE_BITS);
   1319 }
   1320 
   1321 // Sort palette in increasing order and prepare an inverse mapping array.
   1322 static void PrepareMapToPalette(const uint32_t palette[], int num_colors,
   1323                                 uint32_t sorted[], uint32_t idx_map[]) {
   1324   int i;
   1325   memcpy(sorted, palette, num_colors * sizeof(*sorted));
   1326   qsort(sorted, num_colors, sizeof(*sorted), PaletteCompareColorsForQsort);
   1327   for (i = 0; i < num_colors; ++i) {
   1328     idx_map[SearchColorNoIdx(sorted, palette[i], num_colors)] = i;
   1329   }
   1330 }
   1331 
   1332 // Use 1 pixel cache for ARGB pixels.
   1333 #define APPLY_PALETTE_FOR(COLOR_INDEX) do {         \
   1334   uint32_t prev_pix = palette[0];                   \
   1335   uint32_t prev_idx = 0;                            \
   1336   for (y = 0; y < height; ++y) {                    \
   1337     for (x = 0; x < width; ++x) {                   \
   1338       const uint32_t pix = src[x];                  \
   1339       if (pix != prev_pix) {                        \
   1340         prev_idx = COLOR_INDEX;                     \
   1341         prev_pix = pix;                             \
   1342       }                                             \
   1343       tmp_row[x] = prev_idx;                        \
   1344     }                                               \
   1345     VP8LBundleColorMap(tmp_row, width, xbits, dst); \
   1346     src += src_stride;                              \
   1347     dst += dst_stride;                              \
   1348   }                                                 \
   1349 } while (0)
   1350 
   1351 // Remap argb values in src[] to packed palettes entries in dst[]
   1352 // using 'row' as a temporary buffer of size 'width'.
   1353 // We assume that all src[] values have a corresponding entry in the palette.
   1354 // Note: src[] can be the same as dst[]
   1355 static WebPEncodingError ApplyPalette(const uint32_t* src, uint32_t src_stride,
   1356                                       uint32_t* dst, uint32_t dst_stride,
   1357                                       const uint32_t* palette, int palette_size,
   1358                                       int width, int height, int xbits) {
   1359   // TODO(skal): this tmp buffer is not needed if VP8LBundleColorMap() can be
   1360   // made to work in-place.
   1361   uint8_t* const tmp_row = (uint8_t*)WebPSafeMalloc(width, sizeof(*tmp_row));
   1362   int x, y;
   1363 
   1364   if (tmp_row == NULL) return VP8_ENC_ERROR_OUT_OF_MEMORY;
   1365 
   1366   if (palette_size < APPLY_PALETTE_GREEDY_MAX) {
   1367     APPLY_PALETTE_FOR(SearchColorGreedy(palette, palette_size, pix));
   1368   } else {
   1369     int i, j;
   1370     uint16_t buffer[PALETTE_INV_SIZE];
   1371     uint32_t (*const hash_functions[])(uint32_t) = {
   1372         ApplyPaletteHash0, ApplyPaletteHash1, ApplyPaletteHash2
   1373     };
   1374 
   1375     // Try to find a perfect hash function able to go from a color to an index
   1376     // within 1 << PALETTE_INV_SIZE_BITS in order to build a hash map to go
   1377     // from color to index in palette.
   1378     for (i = 0; i < 3; ++i) {
   1379       int use_LUT = 1;
   1380       // Set each element in buffer to max uint16_t.
   1381       memset(buffer, 0xff, sizeof(buffer));
   1382       for (j = 0; j < palette_size; ++j) {
   1383         const uint32_t ind = hash_functions[i](palette[j]);
   1384         if (buffer[ind] != 0xffffu) {
   1385           use_LUT = 0;
   1386           break;
   1387         } else {
   1388           buffer[ind] = j;
   1389         }
   1390       }
   1391       if (use_LUT) break;
   1392     }
   1393 
   1394     if (i == 0) {
   1395       APPLY_PALETTE_FOR(buffer[ApplyPaletteHash0(pix)]);
   1396     } else if (i == 1) {
   1397       APPLY_PALETTE_FOR(buffer[ApplyPaletteHash1(pix)]);
   1398     } else if (i == 2) {
   1399       APPLY_PALETTE_FOR(buffer[ApplyPaletteHash2(pix)]);
   1400     } else {
   1401       uint32_t idx_map[MAX_PALETTE_SIZE];
   1402       uint32_t palette_sorted[MAX_PALETTE_SIZE];
   1403       PrepareMapToPalette(palette, palette_size, palette_sorted, idx_map);
   1404       APPLY_PALETTE_FOR(
   1405           idx_map[SearchColorNoIdx(palette_sorted, pix, palette_size)]);
   1406     }
   1407   }
   1408   WebPSafeFree(tmp_row);
   1409   return VP8_ENC_OK;
   1410 }
   1411 #undef APPLY_PALETTE_FOR
   1412 #undef PALETTE_INV_SIZE_BITS
   1413 #undef PALETTE_INV_SIZE
   1414 #undef APPLY_PALETTE_GREEDY_MAX
   1415 
   1416 // Note: Expects "enc->palette_" to be set properly.
   1417 static WebPEncodingError MapImageFromPalette(VP8LEncoder* const enc,
   1418                                              int in_place) {
   1419   WebPEncodingError err = VP8_ENC_OK;
   1420   const WebPPicture* const pic = enc->pic_;
   1421   const int width = pic->width;
   1422   const int height = pic->height;
   1423   const uint32_t* const palette = enc->palette_;
   1424   const uint32_t* src = in_place ? enc->argb_ : pic->argb;
   1425   const int src_stride = in_place ? enc->current_width_ : pic->argb_stride;
   1426   const int palette_size = enc->palette_size_;
   1427   int xbits;
   1428 
   1429   // Replace each input pixel by corresponding palette index.
   1430   // This is done line by line.
   1431   if (palette_size <= 4) {
   1432     xbits = (palette_size <= 2) ? 3 : 2;
   1433   } else {
   1434     xbits = (palette_size <= 16) ? 1 : 0;
   1435   }
   1436 
   1437   err = AllocateTransformBuffer(enc, VP8LSubSampleSize(width, xbits), height);
   1438   if (err != VP8_ENC_OK) return err;
   1439 
   1440   err = ApplyPalette(src, src_stride,
   1441                      enc->argb_, enc->current_width_,
   1442                      palette, palette_size, width, height, xbits);
   1443   enc->argb_content_ = kEncoderPalette;
   1444   return err;
   1445 }
   1446 
   1447 // Save palette_[] to bitstream.
   1448 static WebPEncodingError EncodePalette(VP8LBitWriter* const bw, int low_effort,
   1449                                        VP8LEncoder* const enc) {
   1450   int i;
   1451   uint32_t tmp_palette[MAX_PALETTE_SIZE];
   1452   const int palette_size = enc->palette_size_;
   1453   const uint32_t* const palette = enc->palette_;
   1454   VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
   1455   VP8LPutBits(bw, COLOR_INDEXING_TRANSFORM, 2);
   1456   assert(palette_size >= 1 && palette_size <= MAX_PALETTE_SIZE);
   1457   VP8LPutBits(bw, palette_size - 1, 8);
   1458   for (i = palette_size - 1; i >= 1; --i) {
   1459     tmp_palette[i] = VP8LSubPixels(palette[i], palette[i - 1]);
   1460   }
   1461   tmp_palette[0] = palette[0];
   1462   return EncodeImageNoHuffman(bw, tmp_palette, &enc->hash_chain_,
   1463                               &enc->refs_[0], &enc->refs_[1], palette_size, 1,
   1464                               20 /* quality */, low_effort);
   1465 }
   1466 
   1467 #ifdef WEBP_EXPERIMENTAL_FEATURES
   1468 
   1469 static WebPEncodingError EncodeDeltaPalettePredictorImage(
   1470     VP8LBitWriter* const bw, VP8LEncoder* const enc, int quality,
   1471     int low_effort) {
   1472   const WebPPicture* const pic = enc->pic_;
   1473   const int width = pic->width;
   1474   const int height = pic->height;
   1475 
   1476   const int pred_bits = 5;
   1477   const int transform_width = VP8LSubSampleSize(width, pred_bits);
   1478   const int transform_height = VP8LSubSampleSize(height, pred_bits);
   1479   const int pred = 7;   // default is Predictor7 (Top/Left Average)
   1480   const int tiles_per_row = VP8LSubSampleSize(width, pred_bits);
   1481   const int tiles_per_col = VP8LSubSampleSize(height, pred_bits);
   1482   uint32_t* predictors;
   1483   int tile_x, tile_y;
   1484   WebPEncodingError err = VP8_ENC_OK;
   1485 
   1486   predictors = (uint32_t*)WebPSafeMalloc(tiles_per_col * tiles_per_row,
   1487                                          sizeof(*predictors));
   1488   if (predictors == NULL) return VP8_ENC_ERROR_OUT_OF_MEMORY;
   1489 
   1490   for (tile_y = 0; tile_y < tiles_per_col; ++tile_y) {
   1491     for (tile_x = 0; tile_x < tiles_per_row; ++tile_x) {
   1492       predictors[tile_y * tiles_per_row + tile_x] = 0xff000000u | (pred << 8);
   1493     }
   1494   }
   1495 
   1496   VP8LPutBits(bw, TRANSFORM_PRESENT, 1);
   1497   VP8LPutBits(bw, PREDICTOR_TRANSFORM, 2);
   1498   VP8LPutBits(bw, pred_bits - 2, 3);
   1499   err = EncodeImageNoHuffman(
   1500       bw, predictors, &enc->hash_chain_,
   1501       (VP8LBackwardRefs*)&enc->refs_[0],  // cast const away
   1502       (VP8LBackwardRefs*)&enc->refs_[1],
   1503       transform_width, transform_height, quality, low_effort);
   1504   WebPSafeFree(predictors);
   1505   return err;
   1506 }
   1507 
   1508 #endif // WEBP_EXPERIMENTAL_FEATURES
   1509 
   1510 // -----------------------------------------------------------------------------
   1511 // VP8LEncoder
   1512 
   1513 static VP8LEncoder* VP8LEncoderNew(const WebPConfig* const config,
   1514                                    const WebPPicture* const picture) {
   1515   VP8LEncoder* const enc = (VP8LEncoder*)WebPSafeCalloc(1ULL, sizeof(*enc));
   1516   if (enc == NULL) {
   1517     WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
   1518     return NULL;
   1519   }
   1520   enc->config_ = config;
   1521   enc->pic_ = picture;
   1522   enc->argb_content_ = kEncoderNone;
   1523 
   1524   VP8LEncDspInit();
   1525 
   1526   return enc;
   1527 }
   1528 
   1529 static void VP8LEncoderDelete(VP8LEncoder* enc) {
   1530   if (enc != NULL) {
   1531     int i;
   1532     VP8LHashChainClear(&enc->hash_chain_);
   1533     for (i = 0; i < 3; ++i) VP8LBackwardRefsClear(&enc->refs_[i]);
   1534     ClearTransformBuffer(enc);
   1535     WebPSafeFree(enc);
   1536   }
   1537 }
   1538 
   1539 // -----------------------------------------------------------------------------
   1540 // Main call
   1541 
   1542 typedef struct {
   1543   const WebPConfig* config_;
   1544   const WebPPicture* picture_;
   1545   VP8LBitWriter* bw_;
   1546   VP8LEncoder* enc_;
   1547   int use_cache_;
   1548   CrunchConfig crunch_configs_[CRUNCH_CONFIGS_MAX];
   1549   int num_crunch_configs_;
   1550   int red_and_blue_always_zero_;
   1551   WebPEncodingError err_;
   1552   WebPAuxStats* stats_;
   1553 } StreamEncodeContext;
   1554 
   1555 static int EncodeStreamHook(void* input, void* data2) {
   1556   StreamEncodeContext* const params = (StreamEncodeContext*)input;
   1557   const WebPConfig* const config = params->config_;
   1558   const WebPPicture* const picture = params->picture_;
   1559   VP8LBitWriter* const bw = params->bw_;
   1560   VP8LEncoder* const enc = params->enc_;
   1561   const int use_cache = params->use_cache_;
   1562   const CrunchConfig* const crunch_configs = params->crunch_configs_;
   1563   const int num_crunch_configs = params->num_crunch_configs_;
   1564   const int red_and_blue_always_zero = params->red_and_blue_always_zero_;
   1565 #if !defined(WEBP_DISABLE_STATS)
   1566   WebPAuxStats* const stats = params->stats_;
   1567 #endif
   1568   WebPEncodingError err = VP8_ENC_OK;
   1569   const int quality = (int)config->quality;
   1570   const int low_effort = (config->method == 0);
   1571 #if (WEBP_NEAR_LOSSLESS == 1) || defined(WEBP_EXPERIMENTAL_FEATURES)
   1572   const int width = picture->width;
   1573 #endif
   1574   const int height = picture->height;
   1575   const size_t byte_position = VP8LBitWriterNumBytes(bw);
   1576 #if (WEBP_NEAR_LOSSLESS == 1)
   1577   int use_near_lossless = 0;
   1578 #endif
   1579   int hdr_size = 0;
   1580   int data_size = 0;
   1581   int use_delta_palette = 0;
   1582   int idx;
   1583   size_t best_size = 0;
   1584   VP8LBitWriter bw_init = *bw, bw_best;
   1585   (void)data2;
   1586 
   1587   if (!VP8LBitWriterInit(&bw_best, 0) ||
   1588       (num_crunch_configs > 1 && !VP8LBitWriterClone(bw, &bw_best))) {
   1589     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
   1590     goto Error;
   1591   }
   1592 
   1593   for (idx = 0; idx < num_crunch_configs; ++idx) {
   1594     const int entropy_idx = crunch_configs[idx].entropy_idx_;
   1595     enc->use_palette_ = (entropy_idx == kPalette);
   1596     enc->use_subtract_green_ =
   1597         (entropy_idx == kSubGreen) || (entropy_idx == kSpatialSubGreen);
   1598     enc->use_predict_ =
   1599         (entropy_idx == kSpatial) || (entropy_idx == kSpatialSubGreen);
   1600     if (low_effort) {
   1601       enc->use_cross_color_ = 0;
   1602     } else {
   1603       enc->use_cross_color_ = red_and_blue_always_zero ? 0 : enc->use_predict_;
   1604     }
   1605     // Reset any parameter in the encoder that is set in the previous iteration.
   1606     enc->cache_bits_ = 0;
   1607     VP8LBackwardRefsClear(&enc->refs_[0]);
   1608     VP8LBackwardRefsClear(&enc->refs_[1]);
   1609 
   1610 #if (WEBP_NEAR_LOSSLESS == 1)
   1611     // Apply near-lossless preprocessing.
   1612     use_near_lossless = (config->near_lossless < 100) && !enc->use_palette_ &&
   1613                         !enc->use_predict_;
   1614     if (use_near_lossless) {
   1615       err = AllocateTransformBuffer(enc, width, height);
   1616       if (err != VP8_ENC_OK) goto Error;
   1617       if ((enc->argb_content_ != kEncoderNearLossless) &&
   1618           !VP8ApplyNearLossless(picture, config->near_lossless, enc->argb_)) {
   1619         err = VP8_ENC_ERROR_OUT_OF_MEMORY;
   1620         goto Error;
   1621       }
   1622       enc->argb_content_ = kEncoderNearLossless;
   1623     } else {
   1624       enc->argb_content_ = kEncoderNone;
   1625     }
   1626 #else
   1627     enc->argb_content_ = kEncoderNone;
   1628 #endif
   1629 
   1630 #ifdef WEBP_EXPERIMENTAL_FEATURES
   1631     if (config->use_delta_palette) {
   1632       enc->use_predict_ = 1;
   1633       enc->use_cross_color_ = 0;
   1634       enc->use_subtract_green_ = 0;
   1635       enc->use_palette_ = 1;
   1636       if (enc->argb_content_ != kEncoderNearLossless &&
   1637           enc->argb_content_ != kEncoderPalette) {
   1638         err = MakeInputImageCopy(enc);
   1639         if (err != VP8_ENC_OK) goto Error;
   1640       }
   1641       err = WebPSearchOptimalDeltaPalette(enc);
   1642       if (err != VP8_ENC_OK) goto Error;
   1643       if (enc->use_palette_) {
   1644         err = AllocateTransformBuffer(enc, width, height);
   1645         if (err != VP8_ENC_OK) goto Error;
   1646         err = EncodeDeltaPalettePredictorImage(bw, enc, quality, low_effort);
   1647         if (err != VP8_ENC_OK) goto Error;
   1648         use_delta_palette = 1;
   1649       }
   1650     }
   1651 #endif  // WEBP_EXPERIMENTAL_FEATURES
   1652 
   1653     // Encode palette
   1654     if (enc->use_palette_) {
   1655       err = EncodePalette(bw, low_effort, enc);
   1656       if (err != VP8_ENC_OK) goto Error;
   1657       err = MapImageFromPalette(enc, use_delta_palette);
   1658       if (err != VP8_ENC_OK) goto Error;
   1659       // If using a color cache, do not have it bigger than the number of
   1660       // colors.
   1661       if (use_cache && enc->palette_size_ < (1 << MAX_COLOR_CACHE_BITS)) {
   1662         enc->cache_bits_ = BitsLog2Floor(enc->palette_size_) + 1;
   1663       }
   1664     }
   1665     if (!use_delta_palette) {
   1666       // In case image is not packed.
   1667       if (enc->argb_content_ != kEncoderNearLossless &&
   1668           enc->argb_content_ != kEncoderPalette) {
   1669         err = MakeInputImageCopy(enc);
   1670         if (err != VP8_ENC_OK) goto Error;
   1671       }
   1672 
   1673       // -----------------------------------------------------------------------
   1674       // Apply transforms and write transform data.
   1675 
   1676       if (enc->use_subtract_green_) {
   1677         ApplySubtractGreen(enc, enc->current_width_, height, bw);
   1678       }
   1679 
   1680       if (enc->use_predict_) {
   1681         err = ApplyPredictFilter(enc, enc->current_width_, height, quality,
   1682                                  low_effort, enc->use_subtract_green_, bw);
   1683         if (err != VP8_ENC_OK) goto Error;
   1684       }
   1685 
   1686       if (enc->use_cross_color_) {
   1687         err = ApplyCrossColorFilter(enc, enc->current_width_, height, quality,
   1688                                     low_effort, bw);
   1689         if (err != VP8_ENC_OK) goto Error;
   1690       }
   1691     }
   1692 
   1693     VP8LPutBits(bw, !TRANSFORM_PRESENT, 1);  // No more transforms.
   1694 
   1695     // -------------------------------------------------------------------------
   1696     // Encode and write the transformed image.
   1697     err = EncodeImageInternal(bw, enc->argb_, &enc->hash_chain_, enc->refs_,
   1698                               enc->current_width_, height, quality, low_effort,
   1699                               use_cache, &crunch_configs[idx],
   1700                               &enc->cache_bits_, enc->histo_bits_,
   1701                               byte_position, &hdr_size, &data_size);
   1702     if (err != VP8_ENC_OK) goto Error;
   1703 
   1704     // If we are better than what we already have.
   1705     if (idx == 0 || VP8LBitWriterNumBytes(bw) < best_size) {
   1706       best_size = VP8LBitWriterNumBytes(bw);
   1707       // Store the BitWriter.
   1708       VP8LBitWriterSwap(bw, &bw_best);
   1709 #if !defined(WEBP_DISABLE_STATS)
   1710       // Update the stats.
   1711       if (stats != NULL) {
   1712         stats->lossless_features = 0;
   1713         if (enc->use_predict_) stats->lossless_features |= 1;
   1714         if (enc->use_cross_color_) stats->lossless_features |= 2;
   1715         if (enc->use_subtract_green_) stats->lossless_features |= 4;
   1716         if (enc->use_palette_) stats->lossless_features |= 8;
   1717         stats->histogram_bits = enc->histo_bits_;
   1718         stats->transform_bits = enc->transform_bits_;
   1719         stats->cache_bits = enc->cache_bits_;
   1720         stats->palette_size = enc->palette_size_;
   1721         stats->lossless_size = (int)(best_size - byte_position);
   1722         stats->lossless_hdr_size = hdr_size;
   1723         stats->lossless_data_size = data_size;
   1724       }
   1725 #endif
   1726     }
   1727     // Reset the bit writer for the following iteration if any.
   1728     if (num_crunch_configs > 1) VP8LBitWriterReset(&bw_init, bw);
   1729   }
   1730   VP8LBitWriterSwap(&bw_best, bw);
   1731 
   1732 Error:
   1733   VP8LBitWriterWipeOut(&bw_best);
   1734   params->err_ = err;
   1735   // The hook should return false in case of error.
   1736   return (err == VP8_ENC_OK);
   1737 }
   1738 
   1739 WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
   1740                                    const WebPPicture* const picture,
   1741                                    VP8LBitWriter* const bw_main,
   1742                                    int use_cache) {
   1743   WebPEncodingError err = VP8_ENC_OK;
   1744   VP8LEncoder* const enc_main = VP8LEncoderNew(config, picture);
   1745   VP8LEncoder* enc_side = NULL;
   1746   CrunchConfig crunch_configs[CRUNCH_CONFIGS_MAX];
   1747   int num_crunch_configs_main, num_crunch_configs_side = 0;
   1748   int idx;
   1749   int red_and_blue_always_zero = 0;
   1750   WebPWorker worker_main, worker_side;
   1751   StreamEncodeContext params_main, params_side;
   1752   // The main thread uses picture->stats, the side thread uses stats_side.
   1753   WebPAuxStats stats_side;
   1754   VP8LBitWriter bw_side;
   1755   const WebPWorkerInterface* const worker_interface = WebPGetWorkerInterface();
   1756   int ok_main;
   1757 
   1758   // Analyze image (entropy, num_palettes etc)
   1759   if (enc_main == NULL ||
   1760       !EncoderAnalyze(enc_main, crunch_configs, &num_crunch_configs_main,
   1761                       &red_and_blue_always_zero) ||
   1762       !EncoderInit(enc_main) || !VP8LBitWriterInit(&bw_side, 0)) {
   1763     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
   1764     goto Error;
   1765   }
   1766 
   1767   // Split the configs between the main and side threads (if any).
   1768   if (config->thread_level > 0) {
   1769     num_crunch_configs_side = num_crunch_configs_main / 2;
   1770     for (idx = 0; idx < num_crunch_configs_side; ++idx) {
   1771       params_side.crunch_configs_[idx] =
   1772           crunch_configs[num_crunch_configs_main - num_crunch_configs_side +
   1773                          idx];
   1774     }
   1775     params_side.num_crunch_configs_ = num_crunch_configs_side;
   1776   }
   1777   num_crunch_configs_main -= num_crunch_configs_side;
   1778   for (idx = 0; idx < num_crunch_configs_main; ++idx) {
   1779     params_main.crunch_configs_[idx] = crunch_configs[idx];
   1780   }
   1781   params_main.num_crunch_configs_ = num_crunch_configs_main;
   1782 
   1783   // Fill in the parameters for the thread workers.
   1784   {
   1785     const int params_size = (num_crunch_configs_side > 0) ? 2 : 1;
   1786     for (idx = 0; idx < params_size; ++idx) {
   1787       // Create the parameters for each worker.
   1788       WebPWorker* const worker = (idx == 0) ? &worker_main : &worker_side;
   1789       StreamEncodeContext* const param =
   1790           (idx == 0) ? &params_main : &params_side;
   1791       param->config_ = config;
   1792       param->picture_ = picture;
   1793       param->use_cache_ = use_cache;
   1794       param->red_and_blue_always_zero_ = red_and_blue_always_zero;
   1795       if (idx == 0) {
   1796         param->stats_ = picture->stats;
   1797         param->bw_ = bw_main;
   1798         param->enc_ = enc_main;
   1799       } else {
   1800         param->stats_ = (picture->stats == NULL) ? NULL : &stats_side;
   1801         // Create a side bit writer.
   1802         if (!VP8LBitWriterClone(bw_main, &bw_side)) {
   1803           err = VP8_ENC_ERROR_OUT_OF_MEMORY;
   1804           goto Error;
   1805         }
   1806         param->bw_ = &bw_side;
   1807         // Create a side encoder.
   1808         enc_side = VP8LEncoderNew(config, picture);
   1809         if (enc_side == NULL || !EncoderInit(enc_side)) {
   1810           err = VP8_ENC_ERROR_OUT_OF_MEMORY;
   1811           goto Error;
   1812         }
   1813         // Copy the values that were computed for the main encoder.
   1814         enc_side->histo_bits_ = enc_main->histo_bits_;
   1815         enc_side->transform_bits_ = enc_main->transform_bits_;
   1816         enc_side->palette_size_ = enc_main->palette_size_;
   1817         memcpy(enc_side->palette_, enc_main->palette_,
   1818                sizeof(enc_main->palette_));
   1819         param->enc_ = enc_side;
   1820       }
   1821       // Create the workers.
   1822       worker_interface->Init(worker);
   1823       worker->data1 = param;
   1824       worker->data2 = NULL;
   1825       worker->hook = (WebPWorkerHook)EncodeStreamHook;
   1826     }
   1827   }
   1828 
   1829   // Start the second thread if needed.
   1830   if (num_crunch_configs_side != 0) {
   1831     if (!worker_interface->Reset(&worker_side)) {
   1832       err = VP8_ENC_ERROR_OUT_OF_MEMORY;
   1833       goto Error;
   1834     }
   1835 #if !defined(WEBP_DISABLE_STATS)
   1836     // This line is here and not in the param initialization above to remove a
   1837     // Clang static analyzer warning.
   1838     if (picture->stats != NULL) {
   1839       memcpy(&stats_side, picture->stats, sizeof(stats_side));
   1840     }
   1841 #endif
   1842     // This line is only useful to remove a Clang static analyzer warning.
   1843     params_side.err_ = VP8_ENC_OK;
   1844     worker_interface->Launch(&worker_side);
   1845   }
   1846   // Execute the main thread.
   1847   worker_interface->Execute(&worker_main);
   1848   ok_main = worker_interface->Sync(&worker_main);
   1849   worker_interface->End(&worker_main);
   1850   if (num_crunch_configs_side != 0) {
   1851     // Wait for the second thread.
   1852     const int ok_side = worker_interface->Sync(&worker_side);
   1853     worker_interface->End(&worker_side);
   1854     if (!ok_main || !ok_side) {
   1855       err = ok_main ? params_side.err_ : params_main.err_;
   1856       goto Error;
   1857     }
   1858     if (VP8LBitWriterNumBytes(&bw_side) < VP8LBitWriterNumBytes(bw_main)) {
   1859       VP8LBitWriterSwap(bw_main, &bw_side);
   1860 #if !defined(WEBP_DISABLE_STATS)
   1861       if (picture->stats != NULL) {
   1862         memcpy(picture->stats, &stats_side, sizeof(*picture->stats));
   1863       }
   1864 #endif
   1865     }
   1866   } else {
   1867     if (!ok_main) {
   1868       err = params_main.err_;
   1869       goto Error;
   1870     }
   1871   }
   1872 
   1873 Error:
   1874   VP8LBitWriterWipeOut(&bw_side);
   1875   VP8LEncoderDelete(enc_main);
   1876   VP8LEncoderDelete(enc_side);
   1877   return err;
   1878 }
   1879 
   1880 #undef CRUNCH_CONFIGS_MAX
   1881 #undef CRUNCH_CONFIGS_LZ77_MAX
   1882 
   1883 int VP8LEncodeImage(const WebPConfig* const config,
   1884                     const WebPPicture* const picture) {
   1885   int width, height;
   1886   int has_alpha;
   1887   size_t coded_size;
   1888   int percent = 0;
   1889   int initial_size;
   1890   WebPEncodingError err = VP8_ENC_OK;
   1891   VP8LBitWriter bw;
   1892 
   1893   if (picture == NULL) return 0;
   1894 
   1895   if (config == NULL || picture->argb == NULL) {
   1896     err = VP8_ENC_ERROR_NULL_PARAMETER;
   1897     WebPEncodingSetError(picture, err);
   1898     return 0;
   1899   }
   1900 
   1901   width = picture->width;
   1902   height = picture->height;
   1903   // Initialize BitWriter with size corresponding to 16 bpp to photo images and
   1904   // 8 bpp for graphical images.
   1905   initial_size = (config->image_hint == WEBP_HINT_GRAPH) ?
   1906       width * height : width * height * 2;
   1907   if (!VP8LBitWriterInit(&bw, initial_size)) {
   1908     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
   1909     goto Error;
   1910   }
   1911 
   1912   if (!WebPReportProgress(picture, 1, &percent)) {
   1913  UserAbort:
   1914     err = VP8_ENC_ERROR_USER_ABORT;
   1915     goto Error;
   1916   }
   1917   // Reset stats (for pure lossless coding)
   1918   if (picture->stats != NULL) {
   1919     WebPAuxStats* const stats = picture->stats;
   1920     memset(stats, 0, sizeof(*stats));
   1921     stats->PSNR[0] = 99.f;
   1922     stats->PSNR[1] = 99.f;
   1923     stats->PSNR[2] = 99.f;
   1924     stats->PSNR[3] = 99.f;
   1925     stats->PSNR[4] = 99.f;
   1926   }
   1927 
   1928   // Write image size.
   1929   if (!WriteImageSize(picture, &bw)) {
   1930     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
   1931     goto Error;
   1932   }
   1933 
   1934   has_alpha = WebPPictureHasTransparency(picture);
   1935   // Write the non-trivial Alpha flag and lossless version.
   1936   if (!WriteRealAlphaAndVersion(&bw, has_alpha)) {
   1937     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
   1938     goto Error;
   1939   }
   1940 
   1941   if (!WebPReportProgress(picture, 5, &percent)) goto UserAbort;
   1942 
   1943   // Encode main image stream.
   1944   err = VP8LEncodeStream(config, picture, &bw, 1 /*use_cache*/);
   1945   if (err != VP8_ENC_OK) goto Error;
   1946 
   1947   // TODO(skal): have a fine-grained progress report in VP8LEncodeStream().
   1948   if (!WebPReportProgress(picture, 90, &percent)) goto UserAbort;
   1949 
   1950   // Finish the RIFF chunk.
   1951   err = WriteImage(picture, &bw, &coded_size);
   1952   if (err != VP8_ENC_OK) goto Error;
   1953 
   1954   if (!WebPReportProgress(picture, 100, &percent)) goto UserAbort;
   1955 
   1956 #if !defined(WEBP_DISABLE_STATS)
   1957   // Save size.
   1958   if (picture->stats != NULL) {
   1959     picture->stats->coded_size += (int)coded_size;
   1960     picture->stats->lossless_size = (int)coded_size;
   1961   }
   1962 #endif
   1963 
   1964   if (picture->extra_info != NULL) {
   1965     const int mb_w = (width + 15) >> 4;
   1966     const int mb_h = (height + 15) >> 4;
   1967     memset(picture->extra_info, 0, mb_w * mb_h * sizeof(*picture->extra_info));
   1968   }
   1969 
   1970  Error:
   1971   if (bw.error_) err = VP8_ENC_ERROR_OUT_OF_MEMORY;
   1972   VP8LBitWriterWipeOut(&bw);
   1973   if (err != VP8_ENC_OK) {
   1974     WebPEncodingSetError(picture, err);
   1975     return 0;
   1976   }
   1977   return 1;
   1978 }
   1979 
   1980 //------------------------------------------------------------------------------
   1981