- add sources.
[platform/framework/web/crosswalk.git] / src / third_party / libwebp / enc / vp8l.c
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@gmail.com)
13 //
14
15 #include <assert.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18
19 #include "./backward_references.h"
20 #include "./vp8enci.h"
21 #include "./vp8li.h"
22 #include "../dsp/lossless.h"
23 #include "../utils/bit_writer.h"
24 #include "../utils/huffman_encode.h"
25 #include "../utils/utils.h"
26 #include "../webp/format_constants.h"
27
28 #if defined(__cplusplus) || defined(c_plusplus)
29 extern "C" {
30 #endif
31
32 #define PALETTE_KEY_RIGHT_SHIFT   22  // Key for 1K buffer.
33 #define MAX_HUFF_IMAGE_SIZE       (16 * 1024 * 1024)
34 #define MAX_COLORS_FOR_GRAPH      64
35
36 // -----------------------------------------------------------------------------
37 // Palette
38
39 static int CompareColors(const void* p1, const void* p2) {
40   const uint32_t a = *(const uint32_t*)p1;
41   const uint32_t b = *(const uint32_t*)p2;
42   assert(a != b);
43   return (a < b) ? -1 : 1;
44 }
45
46 // If number of colors in the image is less than or equal to MAX_PALETTE_SIZE,
47 // creates a palette and returns true, else returns false.
48 static int AnalyzeAndCreatePalette(const WebPPicture* const pic,
49                                    uint32_t palette[MAX_PALETTE_SIZE],
50                                    int* const palette_size) {
51   int i, x, y, key;
52   int num_colors = 0;
53   uint8_t in_use[MAX_PALETTE_SIZE * 4] = { 0 };
54   uint32_t colors[MAX_PALETTE_SIZE * 4];
55   static const uint32_t kHashMul = 0x1e35a7bd;
56   const uint32_t* argb = pic->argb;
57   const int width = pic->width;
58   const int height = pic->height;
59   uint32_t last_pix = ~argb[0];   // so we're sure that last_pix != argb[0]
60
61   for (y = 0; y < height; ++y) {
62     for (x = 0; x < width; ++x) {
63       if (argb[x] == last_pix) {
64         continue;
65       }
66       last_pix = argb[x];
67       key = (kHashMul * last_pix) >> PALETTE_KEY_RIGHT_SHIFT;
68       while (1) {
69         if (!in_use[key]) {
70           colors[key] = last_pix;
71           in_use[key] = 1;
72           ++num_colors;
73           if (num_colors > MAX_PALETTE_SIZE) {
74             return 0;
75           }
76           break;
77         } else if (colors[key] == last_pix) {
78           // The color is already there.
79           break;
80         } else {
81           // Some other color sits there.
82           // Do linear conflict resolution.
83           ++key;
84           key &= (MAX_PALETTE_SIZE * 4 - 1);  // key mask for 1K buffer.
85         }
86       }
87     }
88     argb += pic->argb_stride;
89   }
90
91   // TODO(skal): could we reuse in_use[] to speed up EncodePalette()?
92   num_colors = 0;
93   for (i = 0; i < (int)(sizeof(in_use) / sizeof(in_use[0])); ++i) {
94     if (in_use[i]) {
95       palette[num_colors] = colors[i];
96       ++num_colors;
97     }
98   }
99
100   qsort(palette, num_colors, sizeof(*palette), CompareColors);
101   *palette_size = num_colors;
102   return 1;
103 }
104
105 static int AnalyzeEntropy(const uint32_t* argb,
106                           int width, int height, int argb_stride,
107                           double* const nonpredicted_bits,
108                           double* const predicted_bits) {
109   int x, y;
110   const uint32_t* last_line = NULL;
111   uint32_t last_pix = argb[0];    // so we're sure that pix_diff == 0
112
113   VP8LHistogram* nonpredicted = NULL;
114   VP8LHistogram* predicted =
115       (VP8LHistogram*)malloc(2 * sizeof(*predicted));
116   if (predicted == NULL) return 0;
117   nonpredicted = predicted + 1;
118
119   VP8LHistogramInit(predicted, 0);
120   VP8LHistogramInit(nonpredicted, 0);
121   for (y = 0; y < height; ++y) {
122     for (x = 0; x < width; ++x) {
123       const uint32_t pix = argb[x];
124       const uint32_t pix_diff = VP8LSubPixels(pix, last_pix);
125       if (pix_diff == 0) continue;
126       if (last_line != NULL && pix == last_line[x]) {
127         continue;
128       }
129       last_pix = pix;
130       {
131         const PixOrCopy pix_token = PixOrCopyCreateLiteral(pix);
132         const PixOrCopy pix_diff_token = PixOrCopyCreateLiteral(pix_diff);
133         VP8LHistogramAddSinglePixOrCopy(nonpredicted, &pix_token);
134         VP8LHistogramAddSinglePixOrCopy(predicted, &pix_diff_token);
135       }
136     }
137     last_line = argb;
138     argb += argb_stride;
139   }
140   *nonpredicted_bits = VP8LHistogramEstimateBitsBulk(nonpredicted);
141   *predicted_bits = VP8LHistogramEstimateBitsBulk(predicted);
142   free(predicted);
143   return 1;
144 }
145
146 static int VP8LEncAnalyze(VP8LEncoder* const enc, WebPImageHint image_hint) {
147   const WebPPicture* const pic = enc->pic_;
148   assert(pic != NULL && pic->argb != NULL);
149
150   enc->use_palette_ =
151       AnalyzeAndCreatePalette(pic, enc->palette_, &enc->palette_size_);
152
153   if (image_hint == WEBP_HINT_GRAPH) {
154     if (enc->use_palette_ && enc->palette_size_ < MAX_COLORS_FOR_GRAPH) {
155       enc->use_palette_ = 0;
156     }
157   }
158
159   if (!enc->use_palette_) {
160     if (image_hint == WEBP_HINT_PHOTO) {
161       enc->use_predict_ = 1;
162       enc->use_cross_color_ = 1;
163     } else {
164       double non_pred_entropy, pred_entropy;
165       if (!AnalyzeEntropy(pic->argb, pic->width, pic->height, pic->argb_stride,
166                           &non_pred_entropy, &pred_entropy)) {
167         return 0;
168       }
169       if (pred_entropy < 0.95 * non_pred_entropy) {
170         enc->use_predict_ = 1;
171         // TODO(vikasa): Observed some correlation of cross_color transform with
172         // predict. Need to investigate this further and add separate heuristic
173         // for setting use_cross_color flag.
174         enc->use_cross_color_ = 1;
175       }
176     }
177   }
178
179   return 1;
180 }
181
182 static int GetHuffBitLengthsAndCodes(
183     const VP8LHistogramSet* const histogram_image,
184     HuffmanTreeCode* const huffman_codes) {
185   int i, k;
186   int ok = 1;
187   uint64_t total_length_size = 0;
188   uint8_t* mem_buf = NULL;
189   const int histogram_image_size = histogram_image->size;
190
191   // Iterate over all histograms and get the aggregate number of codes used.
192   for (i = 0; i < histogram_image_size; ++i) {
193     const VP8LHistogram* const histo = histogram_image->histograms[i];
194     HuffmanTreeCode* const codes = &huffman_codes[5 * i];
195     for (k = 0; k < 5; ++k) {
196       const int num_symbols = (k == 0) ? VP8LHistogramNumCodes(histo)
197                             : (k == 4) ? NUM_DISTANCE_CODES
198                             : 256;
199       codes[k].num_symbols = num_symbols;
200       total_length_size += num_symbols;
201     }
202   }
203
204   // Allocate and Set Huffman codes.
205   {
206     uint16_t* codes;
207     uint8_t* lengths;
208     mem_buf = (uint8_t*)WebPSafeCalloc(total_length_size,
209                                        sizeof(*lengths) + sizeof(*codes));
210     if (mem_buf == NULL) {
211       ok = 0;
212       goto End;
213     }
214     codes = (uint16_t*)mem_buf;
215     lengths = (uint8_t*)&codes[total_length_size];
216     for (i = 0; i < 5 * histogram_image_size; ++i) {
217       const int bit_length = huffman_codes[i].num_symbols;
218       huffman_codes[i].codes = codes;
219       huffman_codes[i].code_lengths = lengths;
220       codes += bit_length;
221       lengths += bit_length;
222     }
223   }
224
225   // Create Huffman trees.
226   for (i = 0; ok && (i < histogram_image_size); ++i) {
227     HuffmanTreeCode* const codes = &huffman_codes[5 * i];
228     VP8LHistogram* const histo = histogram_image->histograms[i];
229     ok = ok && VP8LCreateHuffmanTree(histo->literal_, 15, codes + 0);
230     ok = ok && VP8LCreateHuffmanTree(histo->red_, 15, codes + 1);
231     ok = ok && VP8LCreateHuffmanTree(histo->blue_, 15, codes + 2);
232     ok = ok && VP8LCreateHuffmanTree(histo->alpha_, 15, codes + 3);
233     ok = ok && VP8LCreateHuffmanTree(histo->distance_, 15, codes + 4);
234   }
235
236  End:
237   if (!ok) {
238     free(mem_buf);
239     // If one VP8LCreateHuffmanTree() above fails, we need to clean up behind.
240     memset(huffman_codes, 0, 5 * histogram_image_size * sizeof(*huffman_codes));
241   }
242   return ok;
243 }
244
245 static void StoreHuffmanTreeOfHuffmanTreeToBitMask(
246     VP8LBitWriter* const bw, const uint8_t* code_length_bitdepth) {
247   // RFC 1951 will calm you down if you are worried about this funny sequence.
248   // This sequence is tuned from that, but more weighted for lower symbol count,
249   // and more spiking histograms.
250   static const uint8_t kStorageOrder[CODE_LENGTH_CODES] = {
251     17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
252   };
253   int i;
254   // Throw away trailing zeros:
255   int codes_to_store = CODE_LENGTH_CODES;
256   for (; codes_to_store > 4; --codes_to_store) {
257     if (code_length_bitdepth[kStorageOrder[codes_to_store - 1]] != 0) {
258       break;
259     }
260   }
261   VP8LWriteBits(bw, 4, codes_to_store - 4);
262   for (i = 0; i < codes_to_store; ++i) {
263     VP8LWriteBits(bw, 3, code_length_bitdepth[kStorageOrder[i]]);
264   }
265 }
266
267 static void ClearHuffmanTreeIfOnlyOneSymbol(
268     HuffmanTreeCode* const huffman_code) {
269   int k;
270   int count = 0;
271   for (k = 0; k < huffman_code->num_symbols; ++k) {
272     if (huffman_code->code_lengths[k] != 0) {
273       ++count;
274       if (count > 1) return;
275     }
276   }
277   for (k = 0; k < huffman_code->num_symbols; ++k) {
278     huffman_code->code_lengths[k] = 0;
279     huffman_code->codes[k] = 0;
280   }
281 }
282
283 static void StoreHuffmanTreeToBitMask(
284     VP8LBitWriter* const bw,
285     const HuffmanTreeToken* const tokens, const int num_tokens,
286     const HuffmanTreeCode* const huffman_code) {
287   int i;
288   for (i = 0; i < num_tokens; ++i) {
289     const int ix = tokens[i].code;
290     const int extra_bits = tokens[i].extra_bits;
291     VP8LWriteBits(bw, huffman_code->code_lengths[ix], huffman_code->codes[ix]);
292     switch (ix) {
293       case 16:
294         VP8LWriteBits(bw, 2, extra_bits);
295         break;
296       case 17:
297         VP8LWriteBits(bw, 3, extra_bits);
298         break;
299       case 18:
300         VP8LWriteBits(bw, 7, extra_bits);
301         break;
302     }
303   }
304 }
305
306 static int StoreFullHuffmanCode(VP8LBitWriter* const bw,
307                                 const HuffmanTreeCode* const tree) {
308   int ok = 0;
309   uint8_t code_length_bitdepth[CODE_LENGTH_CODES] = { 0 };
310   uint16_t code_length_bitdepth_symbols[CODE_LENGTH_CODES] = { 0 };
311   const int max_tokens = tree->num_symbols;
312   int num_tokens;
313   HuffmanTreeCode huffman_code;
314   HuffmanTreeToken* const tokens =
315       (HuffmanTreeToken*)WebPSafeMalloc((uint64_t)max_tokens, sizeof(*tokens));
316   if (tokens == NULL) return 0;
317
318   huffman_code.num_symbols = CODE_LENGTH_CODES;
319   huffman_code.code_lengths = code_length_bitdepth;
320   huffman_code.codes = code_length_bitdepth_symbols;
321
322   VP8LWriteBits(bw, 1, 0);
323   num_tokens = VP8LCreateCompressedHuffmanTree(tree, tokens, max_tokens);
324   {
325     int histogram[CODE_LENGTH_CODES] = { 0 };
326     int i;
327     for (i = 0; i < num_tokens; ++i) {
328       ++histogram[tokens[i].code];
329     }
330
331     if (!VP8LCreateHuffmanTree(histogram, 7, &huffman_code)) {
332       goto End;
333     }
334   }
335
336   StoreHuffmanTreeOfHuffmanTreeToBitMask(bw, code_length_bitdepth);
337   ClearHuffmanTreeIfOnlyOneSymbol(&huffman_code);
338   {
339     int trailing_zero_bits = 0;
340     int trimmed_length = num_tokens;
341     int write_trimmed_length;
342     int length;
343     int i = num_tokens;
344     while (i-- > 0) {
345       const int ix = tokens[i].code;
346       if (ix == 0 || ix == 17 || ix == 18) {
347         --trimmed_length;   // discount trailing zeros
348         trailing_zero_bits += code_length_bitdepth[ix];
349         if (ix == 17) {
350           trailing_zero_bits += 3;
351         } else if (ix == 18) {
352           trailing_zero_bits += 7;
353         }
354       } else {
355         break;
356       }
357     }
358     write_trimmed_length = (trimmed_length > 1 && trailing_zero_bits > 12);
359     length = write_trimmed_length ? trimmed_length : num_tokens;
360     VP8LWriteBits(bw, 1, write_trimmed_length);
361     if (write_trimmed_length) {
362       const int nbits = VP8LBitsLog2Ceiling(trimmed_length - 1);
363       const int nbitpairs = (nbits == 0) ? 1 : (nbits + 1) / 2;
364       VP8LWriteBits(bw, 3, nbitpairs - 1);
365       assert(trimmed_length >= 2);
366       VP8LWriteBits(bw, nbitpairs * 2, trimmed_length - 2);
367     }
368     StoreHuffmanTreeToBitMask(bw, tokens, length, &huffman_code);
369   }
370   ok = 1;
371  End:
372   free(tokens);
373   return ok;
374 }
375
376 static int StoreHuffmanCode(VP8LBitWriter* const bw,
377                             const HuffmanTreeCode* const huffman_code) {
378   int i;
379   int count = 0;
380   int symbols[2] = { 0, 0 };
381   const int kMaxBits = 8;
382   const int kMaxSymbol = 1 << kMaxBits;
383
384   // Check whether it's a small tree.
385   for (i = 0; i < huffman_code->num_symbols && count < 3; ++i) {
386     if (huffman_code->code_lengths[i] != 0) {
387       if (count < 2) symbols[count] = i;
388       ++count;
389     }
390   }
391
392   if (count == 0) {   // emit minimal tree for empty cases
393     // bits: small tree marker: 1, count-1: 0, large 8-bit code: 0, code: 0
394     VP8LWriteBits(bw, 4, 0x01);
395     return 1;
396   } else if (count <= 2 && symbols[0] < kMaxSymbol && symbols[1] < kMaxSymbol) {
397     VP8LWriteBits(bw, 1, 1);  // Small tree marker to encode 1 or 2 symbols.
398     VP8LWriteBits(bw, 1, count - 1);
399     if (symbols[0] <= 1) {
400       VP8LWriteBits(bw, 1, 0);  // Code bit for small (1 bit) symbol value.
401       VP8LWriteBits(bw, 1, symbols[0]);
402     } else {
403       VP8LWriteBits(bw, 1, 1);
404       VP8LWriteBits(bw, 8, symbols[0]);
405     }
406     if (count == 2) {
407       VP8LWriteBits(bw, 8, symbols[1]);
408     }
409     return 1;
410   } else {
411     return StoreFullHuffmanCode(bw, huffman_code);
412   }
413 }
414
415 static void WriteHuffmanCode(VP8LBitWriter* const bw,
416                              const HuffmanTreeCode* const code,
417                              int code_index) {
418   const int depth = code->code_lengths[code_index];
419   const int symbol = code->codes[code_index];
420   VP8LWriteBits(bw, depth, symbol);
421 }
422
423 static void StoreImageToBitMask(
424     VP8LBitWriter* const bw, int width, int histo_bits,
425     const VP8LBackwardRefs* const refs,
426     const uint16_t* histogram_symbols,
427     const HuffmanTreeCode* const huffman_codes) {
428   // x and y trace the position in the image.
429   int x = 0;
430   int y = 0;
431   const int histo_xsize = histo_bits ? VP8LSubSampleSize(width, histo_bits) : 1;
432   int i;
433   for (i = 0; i < refs->size; ++i) {
434     const PixOrCopy* const v = &refs->refs[i];
435     const int histogram_ix = histogram_symbols[histo_bits ?
436                                                (y >> histo_bits) * histo_xsize +
437                                                (x >> histo_bits) : 0];
438     const HuffmanTreeCode* const codes = huffman_codes + 5 * histogram_ix;
439     if (PixOrCopyIsCacheIdx(v)) {
440       const int code = PixOrCopyCacheIdx(v);
441       const int literal_ix = 256 + NUM_LENGTH_CODES + code;
442       WriteHuffmanCode(bw, codes, literal_ix);
443     } else if (PixOrCopyIsLiteral(v)) {
444       static const int order[] = { 1, 2, 0, 3 };
445       int k;
446       for (k = 0; k < 4; ++k) {
447         const int code = PixOrCopyLiteral(v, order[k]);
448         WriteHuffmanCode(bw, codes + k, code);
449       }
450     } else {
451       int bits, n_bits;
452       int code, distance;
453
454       PrefixEncode(v->len, &code, &n_bits, &bits);
455       WriteHuffmanCode(bw, codes, 256 + code);
456       VP8LWriteBits(bw, n_bits, bits);
457
458       distance = PixOrCopyDistance(v);
459       PrefixEncode(distance, &code, &n_bits, &bits);
460       WriteHuffmanCode(bw, codes + 4, code);
461       VP8LWriteBits(bw, n_bits, bits);
462     }
463     x += PixOrCopyLength(v);
464     while (x >= width) {
465       x -= width;
466       ++y;
467     }
468   }
469 }
470
471 // Special case of EncodeImageInternal() for cache-bits=0, histo_bits=31
472 static int EncodeImageNoHuffman(VP8LBitWriter* const bw,
473                                 const uint32_t* const argb,
474                                 int width, int height, int quality) {
475   int i;
476   int ok = 0;
477   VP8LBackwardRefs refs;
478   HuffmanTreeCode huffman_codes[5] = { { 0, NULL, NULL } };
479   const uint16_t histogram_symbols[1] = { 0 };    // only one tree, one symbol
480   VP8LHistogramSet* const histogram_image = VP8LAllocateHistogramSet(1, 0);
481   if (histogram_image == NULL) return 0;
482
483   // Calculate backward references from ARGB image.
484   if (!VP8LGetBackwardReferences(width, height, argb, quality, 0, 1, &refs)) {
485     goto Error;
486   }
487   // Build histogram image and symbols from backward references.
488   VP8LHistogramStoreRefs(&refs, histogram_image->histograms[0]);
489
490   // Create Huffman bit lengths and codes for each histogram image.
491   assert(histogram_image->size == 1);
492   if (!GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) {
493     goto Error;
494   }
495
496   // No color cache, no Huffman image.
497   VP8LWriteBits(bw, 1, 0);
498
499   // Store Huffman codes.
500   for (i = 0; i < 5; ++i) {
501     HuffmanTreeCode* const codes = &huffman_codes[i];
502     if (!StoreHuffmanCode(bw, codes)) {
503       goto Error;
504     }
505     ClearHuffmanTreeIfOnlyOneSymbol(codes);
506   }
507
508   // Store actual literals.
509   StoreImageToBitMask(bw, width, 0, &refs, histogram_symbols, huffman_codes);
510   ok = 1;
511
512  Error:
513   free(histogram_image);
514   VP8LClearBackwardRefs(&refs);
515   free(huffman_codes[0].codes);
516   return ok;
517 }
518
519 static int EncodeImageInternal(VP8LBitWriter* const bw,
520                                const uint32_t* const argb,
521                                int width, int height, int quality,
522                                int cache_bits, int histogram_bits) {
523   int ok = 0;
524   const int use_2d_locality = 1;
525   const int use_color_cache = (cache_bits > 0);
526   const uint32_t histogram_image_xysize =
527       VP8LSubSampleSize(width, histogram_bits) *
528       VP8LSubSampleSize(height, histogram_bits);
529   VP8LHistogramSet* histogram_image =
530       VP8LAllocateHistogramSet(histogram_image_xysize, 0);
531   int histogram_image_size = 0;
532   size_t bit_array_size = 0;
533   HuffmanTreeCode* huffman_codes = NULL;
534   VP8LBackwardRefs refs;
535   uint16_t* const histogram_symbols =
536       (uint16_t*)WebPSafeMalloc((uint64_t)histogram_image_xysize,
537                                 sizeof(*histogram_symbols));
538   assert(histogram_bits >= MIN_HUFFMAN_BITS);
539   assert(histogram_bits <= MAX_HUFFMAN_BITS);
540
541   if (histogram_image == NULL || histogram_symbols == NULL) {
542     free(histogram_image);
543     free(histogram_symbols);
544     return 0;
545   }
546
547   // Calculate backward references from ARGB image.
548   if (!VP8LGetBackwardReferences(width, height, argb, quality, cache_bits,
549                                  use_2d_locality, &refs)) {
550     goto Error;
551   }
552   // Build histogram image and symbols from backward references.
553   if (!VP8LGetHistoImageSymbols(width, height, &refs,
554                                 quality, histogram_bits, cache_bits,
555                                 histogram_image,
556                                 histogram_symbols)) {
557     goto Error;
558   }
559   // Create Huffman bit lengths and codes for each histogram image.
560   histogram_image_size = histogram_image->size;
561   bit_array_size = 5 * histogram_image_size;
562   huffman_codes = (HuffmanTreeCode*)WebPSafeCalloc(bit_array_size,
563                                                    sizeof(*huffman_codes));
564   if (huffman_codes == NULL ||
565       !GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) {
566     goto Error;
567   }
568   // Free combined histograms.
569   free(histogram_image);
570   histogram_image = NULL;
571
572   // Color Cache parameters.
573   VP8LWriteBits(bw, 1, use_color_cache);
574   if (use_color_cache) {
575     VP8LWriteBits(bw, 4, cache_bits);
576   }
577
578   // Huffman image + meta huffman.
579   {
580     const int write_histogram_image = (histogram_image_size > 1);
581     VP8LWriteBits(bw, 1, write_histogram_image);
582     if (write_histogram_image) {
583       uint32_t* const histogram_argb =
584           (uint32_t*)WebPSafeMalloc((uint64_t)histogram_image_xysize,
585                                     sizeof(*histogram_argb));
586       int max_index = 0;
587       uint32_t i;
588       if (histogram_argb == NULL) goto Error;
589       for (i = 0; i < histogram_image_xysize; ++i) {
590         const int symbol_index = histogram_symbols[i] & 0xffff;
591         histogram_argb[i] = 0xff000000 | (symbol_index << 8);
592         if (symbol_index >= max_index) {
593           max_index = symbol_index + 1;
594         }
595       }
596       histogram_image_size = max_index;
597
598       VP8LWriteBits(bw, 3, histogram_bits - 2);
599       ok = EncodeImageNoHuffman(bw, histogram_argb,
600                                 VP8LSubSampleSize(width, histogram_bits),
601                                 VP8LSubSampleSize(height, histogram_bits),
602                                 quality);
603       free(histogram_argb);
604       if (!ok) goto Error;
605     }
606   }
607
608   // Store Huffman codes.
609   {
610     int i;
611     for (i = 0; i < 5 * histogram_image_size; ++i) {
612       HuffmanTreeCode* const codes = &huffman_codes[i];
613       if (!StoreHuffmanCode(bw, codes)) goto Error;
614       ClearHuffmanTreeIfOnlyOneSymbol(codes);
615     }
616   }
617
618   // Store actual literals.
619   StoreImageToBitMask(bw, width, histogram_bits, &refs,
620                       histogram_symbols, huffman_codes);
621   ok = 1;
622
623  Error:
624   free(histogram_image);
625
626   VP8LClearBackwardRefs(&refs);
627   if (huffman_codes != NULL) {
628     free(huffman_codes->codes);
629     free(huffman_codes);
630   }
631   free(histogram_symbols);
632   return ok;
633 }
634
635 // -----------------------------------------------------------------------------
636 // Transforms
637
638 // Check if it would be a good idea to subtract green from red and blue. We
639 // only impact entropy in red/blue components, don't bother to look at others.
640 static int EvalAndApplySubtractGreen(VP8LEncoder* const enc,
641                                      int width, int height,
642                                      VP8LBitWriter* const bw) {
643   if (!enc->use_palette_) {
644     int i;
645     const uint32_t* const argb = enc->argb_;
646     double bit_cost_before, bit_cost_after;
647     VP8LHistogram* const histo = (VP8LHistogram*)malloc(sizeof(*histo));
648     if (histo == NULL) return 0;
649
650     VP8LHistogramInit(histo, 1);
651     for (i = 0; i < width * height; ++i) {
652       const uint32_t c = argb[i];
653       ++histo->red_[(c >> 16) & 0xff];
654       ++histo->blue_[(c >> 0) & 0xff];
655     }
656     bit_cost_before = VP8LHistogramEstimateBits(histo);
657
658     VP8LHistogramInit(histo, 1);
659     for (i = 0; i < width * height; ++i) {
660       const uint32_t c = argb[i];
661       const int green = (c >> 8) & 0xff;
662       ++histo->red_[((c >> 16) - green) & 0xff];
663       ++histo->blue_[((c >> 0) - green) & 0xff];
664     }
665     bit_cost_after = VP8LHistogramEstimateBits(histo);
666     free(histo);
667
668     // Check if subtracting green yields low entropy.
669     enc->use_subtract_green_ = (bit_cost_after < bit_cost_before);
670     if (enc->use_subtract_green_) {
671       VP8LWriteBits(bw, 1, TRANSFORM_PRESENT);
672       VP8LWriteBits(bw, 2, SUBTRACT_GREEN);
673       VP8LSubtractGreenFromBlueAndRed(enc->argb_, width * height);
674     }
675   }
676   return 1;
677 }
678
679 static int ApplyPredictFilter(const VP8LEncoder* const enc,
680                               int width, int height, int quality,
681                               VP8LBitWriter* const bw) {
682   const int pred_bits = enc->transform_bits_;
683   const int transform_width = VP8LSubSampleSize(width, pred_bits);
684   const int transform_height = VP8LSubSampleSize(height, pred_bits);
685
686   VP8LResidualImage(width, height, pred_bits, enc->argb_, enc->argb_scratch_,
687                     enc->transform_data_);
688   VP8LWriteBits(bw, 1, TRANSFORM_PRESENT);
689   VP8LWriteBits(bw, 2, PREDICTOR_TRANSFORM);
690   assert(pred_bits >= 2);
691   VP8LWriteBits(bw, 3, pred_bits - 2);
692   if (!EncodeImageNoHuffman(bw, enc->transform_data_,
693                             transform_width, transform_height, quality)) {
694     return 0;
695   }
696   return 1;
697 }
698
699 static int ApplyCrossColorFilter(const VP8LEncoder* const enc,
700                                  int width, int height, int quality,
701                                  VP8LBitWriter* const bw) {
702   const int ccolor_transform_bits = enc->transform_bits_;
703   const int transform_width = VP8LSubSampleSize(width, ccolor_transform_bits);
704   const int transform_height = VP8LSubSampleSize(height, ccolor_transform_bits);
705   const int step = (quality == 0) ? 32 : 8;
706
707   VP8LColorSpaceTransform(width, height, ccolor_transform_bits, step,
708                           enc->argb_, enc->transform_data_);
709   VP8LWriteBits(bw, 1, TRANSFORM_PRESENT);
710   VP8LWriteBits(bw, 2, CROSS_COLOR_TRANSFORM);
711   assert(ccolor_transform_bits >= 2);
712   VP8LWriteBits(bw, 3, ccolor_transform_bits - 2);
713   if (!EncodeImageNoHuffman(bw, enc->transform_data_,
714                             transform_width, transform_height, quality)) {
715     return 0;
716   }
717   return 1;
718 }
719
720 // -----------------------------------------------------------------------------
721
722 static WebPEncodingError WriteRiffHeader(const WebPPicture* const pic,
723                                          size_t riff_size, size_t vp8l_size) {
724   uint8_t riff[RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE + VP8L_SIGNATURE_SIZE] = {
725     'R', 'I', 'F', 'F', 0, 0, 0, 0, 'W', 'E', 'B', 'P',
726     'V', 'P', '8', 'L', 0, 0, 0, 0, VP8L_MAGIC_BYTE,
727   };
728   PutLE32(riff + TAG_SIZE, (uint32_t)riff_size);
729   PutLE32(riff + RIFF_HEADER_SIZE + TAG_SIZE, (uint32_t)vp8l_size);
730   if (!pic->writer(riff, sizeof(riff), pic)) {
731     return VP8_ENC_ERROR_BAD_WRITE;
732   }
733   return VP8_ENC_OK;
734 }
735
736 static int WriteImageSize(const WebPPicture* const pic,
737                           VP8LBitWriter* const bw) {
738   const int width = pic->width - 1;
739   const int height = pic->height - 1;
740   assert(width < WEBP_MAX_DIMENSION && height < WEBP_MAX_DIMENSION);
741
742   VP8LWriteBits(bw, VP8L_IMAGE_SIZE_BITS, width);
743   VP8LWriteBits(bw, VP8L_IMAGE_SIZE_BITS, height);
744   return !bw->error_;
745 }
746
747 static int WriteRealAlphaAndVersion(VP8LBitWriter* const bw, int has_alpha) {
748   VP8LWriteBits(bw, 1, has_alpha);
749   VP8LWriteBits(bw, VP8L_VERSION_BITS, VP8L_VERSION);
750   return !bw->error_;
751 }
752
753 static WebPEncodingError WriteImage(const WebPPicture* const pic,
754                                     VP8LBitWriter* const bw,
755                                     size_t* const coded_size) {
756   WebPEncodingError err = VP8_ENC_OK;
757   const uint8_t* const webpll_data = VP8LBitWriterFinish(bw);
758   const size_t webpll_size = VP8LBitWriterNumBytes(bw);
759   const size_t vp8l_size = VP8L_SIGNATURE_SIZE + webpll_size;
760   const size_t pad = vp8l_size & 1;
761   const size_t riff_size = TAG_SIZE + CHUNK_HEADER_SIZE + vp8l_size + pad;
762
763   err = WriteRiffHeader(pic, riff_size, vp8l_size);
764   if (err != VP8_ENC_OK) goto Error;
765
766   if (!pic->writer(webpll_data, webpll_size, pic)) {
767     err = VP8_ENC_ERROR_BAD_WRITE;
768     goto Error;
769   }
770
771   if (pad) {
772     const uint8_t pad_byte[1] = { 0 };
773     if (!pic->writer(pad_byte, 1, pic)) {
774       err = VP8_ENC_ERROR_BAD_WRITE;
775       goto Error;
776     }
777   }
778   *coded_size = CHUNK_HEADER_SIZE + riff_size;
779   return VP8_ENC_OK;
780
781  Error:
782   return err;
783 }
784
785 // -----------------------------------------------------------------------------
786
787 // Allocates the memory for argb (W x H) buffer, 2 rows of context for
788 // prediction and transform data.
789 static WebPEncodingError AllocateTransformBuffer(VP8LEncoder* const enc,
790                                                  int width, int height) {
791   WebPEncodingError err = VP8_ENC_OK;
792   const int tile_size = 1 << enc->transform_bits_;
793   const uint64_t image_size = width * height;
794   const uint64_t argb_scratch_size = tile_size * width + width;
795   const uint64_t transform_data_size =
796       (uint64_t)VP8LSubSampleSize(width, enc->transform_bits_) *
797       (uint64_t)VP8LSubSampleSize(height, enc->transform_bits_);
798   const uint64_t total_size =
799       image_size + argb_scratch_size + transform_data_size;
800   uint32_t* mem = (uint32_t*)WebPSafeMalloc(total_size, sizeof(*mem));
801   if (mem == NULL) {
802     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
803     goto Error;
804   }
805   enc->argb_ = mem;
806   mem += image_size;
807   enc->argb_scratch_ = mem;
808   mem += argb_scratch_size;
809   enc->transform_data_ = mem;
810   enc->current_width_ = width;
811
812  Error:
813   return err;
814 }
815
816 static void ApplyPalette(uint32_t* src, uint32_t* dst,
817                          uint32_t src_stride, uint32_t dst_stride,
818                          const uint32_t* palette, int palette_size,
819                          int width, int height, int xbits, uint8_t* row) {
820   int i, x, y;
821   int use_LUT = 1;
822   for (i = 0; i < palette_size; ++i) {
823     if ((palette[i] & 0xffff00ffu) != 0) {
824       use_LUT = 0;
825       break;
826     }
827   }
828
829   if (use_LUT) {
830     int inv_palette[MAX_PALETTE_SIZE] = { 0 };
831     for (i = 0; i < palette_size; ++i) {
832       const int color = (palette[i] >> 8) & 0xff;
833       inv_palette[color] = i;
834     }
835     for (y = 0; y < height; ++y) {
836       for (x = 0; x < width; ++x) {
837         const int color = (src[x] >> 8) & 0xff;
838         row[x] = inv_palette[color];
839       }
840       VP8LBundleColorMap(row, width, xbits, dst);
841       src += src_stride;
842       dst += dst_stride;
843     }
844   } else {
845     // Use 1 pixel cache for ARGB pixels.
846     uint32_t last_pix = palette[0];
847     int last_idx = 0;
848     for (y = 0; y < height; ++y) {
849       for (x = 0; x < width; ++x) {
850         const uint32_t pix = src[x];
851         if (pix != last_pix) {
852           for (i = 0; i < palette_size; ++i) {
853             if (pix == palette[i]) {
854               last_idx = i;
855               last_pix = pix;
856               break;
857             }
858           }
859         }
860         row[x] = last_idx;
861       }
862       VP8LBundleColorMap(row, width, xbits, dst);
863       src += src_stride;
864       dst += dst_stride;
865     }
866   }
867 }
868
869 // Note: Expects "enc->palette_" to be set properly.
870 // Also, "enc->palette_" will be modified after this call and should not be used
871 // later.
872 static WebPEncodingError EncodePalette(VP8LBitWriter* const bw,
873                                        VP8LEncoder* const enc, int quality) {
874   WebPEncodingError err = VP8_ENC_OK;
875   int i;
876   const WebPPicture* const pic = enc->pic_;
877   uint32_t* src = pic->argb;
878   uint32_t* dst;
879   const int width = pic->width;
880   const int height = pic->height;
881   uint32_t* const palette = enc->palette_;
882   const int palette_size = enc->palette_size_;
883   uint8_t* row = NULL;
884   int xbits;
885
886   // Replace each input pixel by corresponding palette index.
887   // This is done line by line.
888   if (palette_size <= 4) {
889     xbits = (palette_size <= 2) ? 3 : 2;
890   } else {
891     xbits = (palette_size <= 16) ? 1 : 0;
892   }
893
894   err = AllocateTransformBuffer(enc, VP8LSubSampleSize(width, xbits), height);
895   if (err != VP8_ENC_OK) goto Error;
896   dst = enc->argb_;
897
898   row = WebPSafeMalloc((uint64_t)width, sizeof(*row));
899   if (row == NULL) return VP8_ENC_ERROR_OUT_OF_MEMORY;
900
901   ApplyPalette(src, dst, pic->argb_stride, enc->current_width_,
902                palette, palette_size, width, height, xbits, row);
903
904   // Save palette to bitstream.
905   VP8LWriteBits(bw, 1, TRANSFORM_PRESENT);
906   VP8LWriteBits(bw, 2, COLOR_INDEXING_TRANSFORM);
907   assert(palette_size >= 1);
908   VP8LWriteBits(bw, 8, palette_size - 1);
909   for (i = palette_size - 1; i >= 1; --i) {
910     palette[i] = VP8LSubPixels(palette[i], palette[i - 1]);
911   }
912   if (!EncodeImageNoHuffman(bw, palette, palette_size, 1, quality)) {
913     err = VP8_ENC_ERROR_INVALID_CONFIGURATION;
914     goto Error;
915   }
916
917  Error:
918   free(row);
919   return err;
920 }
921
922 // -----------------------------------------------------------------------------
923
924 static int GetHistoBits(int method, int use_palette, int width, int height) {
925   const uint64_t hist_size = sizeof(VP8LHistogram);
926   // Make tile size a function of encoding method (Range: 0 to 6).
927   int histo_bits = (use_palette ? 9 : 7) - method;
928   while (1) {
929     const uint64_t huff_image_size = VP8LSubSampleSize(width, histo_bits) *
930                                      VP8LSubSampleSize(height, histo_bits) *
931                                      hist_size;
932     if (huff_image_size <= MAX_HUFF_IMAGE_SIZE) break;
933     ++histo_bits;
934   }
935   return (histo_bits < MIN_HUFFMAN_BITS) ? MIN_HUFFMAN_BITS :
936          (histo_bits > MAX_HUFFMAN_BITS) ? MAX_HUFFMAN_BITS : histo_bits;
937 }
938
939 static void FinishEncParams(VP8LEncoder* const enc) {
940   const WebPConfig* const config = enc->config_;
941   const WebPPicture* const pic = enc->pic_;
942   const int method = config->method;
943   const float quality = config->quality;
944   const int use_palette = enc->use_palette_;
945   enc->transform_bits_ = (method < 4) ? 5 : (method > 4) ? 3 : 4;
946   enc->histo_bits_ = GetHistoBits(method, use_palette, pic->width, pic->height);
947   enc->cache_bits_ = (quality <= 25.f) ? 0 : 7;
948 }
949
950 // -----------------------------------------------------------------------------
951 // VP8LEncoder
952
953 static VP8LEncoder* VP8LEncoderNew(const WebPConfig* const config,
954                                    const WebPPicture* const picture) {
955   VP8LEncoder* const enc = (VP8LEncoder*)calloc(1, sizeof(*enc));
956   if (enc == NULL) {
957     WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
958     return NULL;
959   }
960   enc->config_ = config;
961   enc->pic_ = picture;
962   return enc;
963 }
964
965 static void VP8LEncoderDelete(VP8LEncoder* enc) {
966   free(enc->argb_);
967   free(enc);
968 }
969
970 // -----------------------------------------------------------------------------
971 // Main call
972
973 WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
974                                    const WebPPicture* const picture,
975                                    VP8LBitWriter* const bw) {
976   WebPEncodingError err = VP8_ENC_OK;
977   const int quality = (int)config->quality;
978   const int width = picture->width;
979   const int height = picture->height;
980   VP8LEncoder* const enc = VP8LEncoderNew(config, picture);
981   const size_t byte_position = VP8LBitWriterNumBytes(bw);
982
983   if (enc == NULL) {
984     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
985     goto Error;
986   }
987
988   // ---------------------------------------------------------------------------
989   // Analyze image (entropy, num_palettes etc)
990
991   if (!VP8LEncAnalyze(enc, config->image_hint)) {
992     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
993     goto Error;
994   }
995
996   FinishEncParams(enc);
997
998   if (enc->use_palette_) {
999     err = EncodePalette(bw, enc, quality);
1000     if (err != VP8_ENC_OK) goto Error;
1001     // Color cache is disabled for palette.
1002     enc->cache_bits_ = 0;
1003   }
1004
1005   // In case image is not packed.
1006   if (enc->argb_ == NULL) {
1007     int y;
1008     err = AllocateTransformBuffer(enc, width, height);
1009     if (err != VP8_ENC_OK) goto Error;
1010     for (y = 0; y < height; ++y) {
1011       memcpy(enc->argb_ + y * width,
1012              picture->argb + y * picture->argb_stride,
1013              width * sizeof(*enc->argb_));
1014     }
1015     enc->current_width_ = width;
1016   }
1017
1018   // ---------------------------------------------------------------------------
1019   // Apply transforms and write transform data.
1020
1021   if (!EvalAndApplySubtractGreen(enc, enc->current_width_, height, bw)) {
1022     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
1023     goto Error;
1024   }
1025
1026   if (enc->use_predict_) {
1027     if (!ApplyPredictFilter(enc, enc->current_width_, height, quality, bw)) {
1028       err = VP8_ENC_ERROR_INVALID_CONFIGURATION;
1029       goto Error;
1030     }
1031   }
1032
1033   if (enc->use_cross_color_) {
1034     if (!ApplyCrossColorFilter(enc, enc->current_width_, height, quality, bw)) {
1035       err = VP8_ENC_ERROR_INVALID_CONFIGURATION;
1036       goto Error;
1037     }
1038   }
1039
1040   VP8LWriteBits(bw, 1, !TRANSFORM_PRESENT);  // No more transforms.
1041
1042   // ---------------------------------------------------------------------------
1043   // Estimate the color cache size.
1044
1045   if (enc->cache_bits_ > 0) {
1046     if (!VP8LCalculateEstimateForCacheSize(enc->argb_, enc->current_width_,
1047                                            height, &enc->cache_bits_)) {
1048       err = VP8_ENC_ERROR_INVALID_CONFIGURATION;
1049       goto Error;
1050     }
1051   }
1052
1053   // ---------------------------------------------------------------------------
1054   // Encode and write the transformed image.
1055
1056   if (!EncodeImageInternal(bw, enc->argb_, enc->current_width_, height,
1057                            quality, enc->cache_bits_, enc->histo_bits_)) {
1058     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
1059     goto Error;
1060   }
1061
1062   if (picture->stats != NULL) {
1063     WebPAuxStats* const stats = picture->stats;
1064     stats->lossless_features = 0;
1065     if (enc->use_predict_) stats->lossless_features |= 1;
1066     if (enc->use_cross_color_) stats->lossless_features |= 2;
1067     if (enc->use_subtract_green_) stats->lossless_features |= 4;
1068     if (enc->use_palette_) stats->lossless_features |= 8;
1069     stats->histogram_bits = enc->histo_bits_;
1070     stats->transform_bits = enc->transform_bits_;
1071     stats->cache_bits = enc->cache_bits_;
1072     stats->palette_size = enc->palette_size_;
1073     stats->lossless_size = (int)(VP8LBitWriterNumBytes(bw) - byte_position);
1074   }
1075
1076  Error:
1077   VP8LEncoderDelete(enc);
1078   return err;
1079 }
1080
1081 int VP8LEncodeImage(const WebPConfig* const config,
1082                     const WebPPicture* const picture) {
1083   int width, height;
1084   int has_alpha;
1085   size_t coded_size;
1086   int percent = 0;
1087   WebPEncodingError err = VP8_ENC_OK;
1088   VP8LBitWriter bw;
1089
1090   if (picture == NULL) return 0;
1091
1092   if (config == NULL || picture->argb == NULL) {
1093     err = VP8_ENC_ERROR_NULL_PARAMETER;
1094     WebPEncodingSetError(picture, err);
1095     return 0;
1096   }
1097
1098   width = picture->width;
1099   height = picture->height;
1100   if (!VP8LBitWriterInit(&bw, (width * height) >> 1)) {
1101     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
1102     goto Error;
1103   }
1104
1105   if (!WebPReportProgress(picture, 1, &percent)) {
1106  UserAbort:
1107     err = VP8_ENC_ERROR_USER_ABORT;
1108     goto Error;
1109   }
1110   // Reset stats (for pure lossless coding)
1111   if (picture->stats != NULL) {
1112     WebPAuxStats* const stats = picture->stats;
1113     memset(stats, 0, sizeof(*stats));
1114     stats->PSNR[0] = 99.f;
1115     stats->PSNR[1] = 99.f;
1116     stats->PSNR[2] = 99.f;
1117     stats->PSNR[3] = 99.f;
1118     stats->PSNR[4] = 99.f;
1119   }
1120
1121   // Write image size.
1122   if (!WriteImageSize(picture, &bw)) {
1123     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
1124     goto Error;
1125   }
1126
1127   has_alpha = WebPPictureHasTransparency(picture);
1128   // Write the non-trivial Alpha flag and lossless version.
1129   if (!WriteRealAlphaAndVersion(&bw, has_alpha)) {
1130     err = VP8_ENC_ERROR_OUT_OF_MEMORY;
1131     goto Error;
1132   }
1133
1134   if (!WebPReportProgress(picture, 5, &percent)) goto UserAbort;
1135
1136   // Encode main image stream.
1137   err = VP8LEncodeStream(config, picture, &bw);
1138   if (err != VP8_ENC_OK) goto Error;
1139
1140   // TODO(skal): have a fine-grained progress report in VP8LEncodeStream().
1141   if (!WebPReportProgress(picture, 90, &percent)) goto UserAbort;
1142
1143   // Finish the RIFF chunk.
1144   err = WriteImage(picture, &bw, &coded_size);
1145   if (err != VP8_ENC_OK) goto Error;
1146
1147   if (!WebPReportProgress(picture, 100, &percent)) goto UserAbort;
1148
1149   // Save size.
1150   if (picture->stats != NULL) {
1151     picture->stats->coded_size += (int)coded_size;
1152     picture->stats->lossless_size = (int)coded_size;
1153   }
1154
1155   if (picture->extra_info != NULL) {
1156     const int mb_w = (width + 15) >> 4;
1157     const int mb_h = (height + 15) >> 4;
1158     memset(picture->extra_info, 0, mb_w * mb_h * sizeof(*picture->extra_info));
1159   }
1160
1161  Error:
1162   if (bw.error_) err = VP8_ENC_ERROR_OUT_OF_MEMORY;
1163   VP8LBitWriterDestroy(&bw);
1164   if (err != VP8_ENC_OK) {
1165     WebPEncodingSetError(picture, err);
1166     return 0;
1167   }
1168   return 1;
1169 }
1170
1171 //------------------------------------------------------------------------------
1172
1173 #if defined(__cplusplus) || defined(c_plusplus)
1174 }    // extern "C"
1175 #endif