| OLD | NEW |
| 1 // Copyright 2012 Google Inc. All Rights Reserved. | 1 // Copyright 2012 Google Inc. All Rights Reserved. |
| 2 // | 2 // |
| 3 // Use of this source code is governed by a BSD-style license | 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 | 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 | 5 // tree. An additional intellectual property rights grant can be found |
| 6 // in the file PATENTS. All contributing project authors may | 6 // in the file PATENTS. All contributing project authors may |
| 7 // be found in the AUTHORS file in the root of the source tree. | 7 // be found in the AUTHORS file in the root of the source tree. |
| 8 // ----------------------------------------------------------------------------- | 8 // ----------------------------------------------------------------------------- |
| 9 // | 9 // |
| 10 // main entry for the lossless encoder. | 10 // main entry for the lossless encoder. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 | 27 |
| 28 #include "./delta_palettization.h" | 28 #include "./delta_palettization.h" |
| 29 | 29 |
| 30 #define PALETTE_KEY_RIGHT_SHIFT 22 // Key for 1K buffer. | 30 #define PALETTE_KEY_RIGHT_SHIFT 22 // Key for 1K buffer. |
| 31 // Maximum number of histogram images (sub-blocks). | 31 // Maximum number of histogram images (sub-blocks). |
| 32 #define MAX_HUFF_IMAGE_SIZE 2600 | 32 #define MAX_HUFF_IMAGE_SIZE 2600 |
| 33 | 33 |
| 34 // Palette reordering for smaller sum of deltas (and for smaller storage). | 34 // Palette reordering for smaller sum of deltas (and for smaller storage). |
| 35 | 35 |
| 36 static int PaletteCompareColorsForQsort(const void* p1, const void* p2) { | 36 static int PaletteCompareColorsForQsort(const void* p1, const void* p2) { |
| 37 const uint32_t a = WebPMemToUint32(p1); | 37 const uint32_t a = WebPMemToUint32((uint8_t*)p1); |
| 38 const uint32_t b = WebPMemToUint32(p2); | 38 const uint32_t b = WebPMemToUint32((uint8_t*)p2); |
| 39 assert(a != b); | 39 assert(a != b); |
| 40 return (a < b) ? -1 : 1; | 40 return (a < b) ? -1 : 1; |
| 41 } | 41 } |
| 42 | 42 |
| 43 static WEBP_INLINE uint32_t PaletteComponentDistance(uint32_t v) { | 43 static WEBP_INLINE uint32_t PaletteComponentDistance(uint32_t v) { |
| 44 return (v <= 128) ? v : (256 - v); | 44 return (v <= 128) ? v : (256 - v); |
| 45 } | 45 } |
| 46 | 46 |
| 47 // Computes a value that is related to the entropy created by the | 47 // Computes a value that is related to the entropy created by the |
| 48 // palette entry diff. | 48 // palette entry diff. |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 const int hash = ((pix + (pix >> 19)) * 0x39c5fba7) >> 24; | 217 const int hash = ((pix + (pix >> 19)) * 0x39c5fba7) >> 24; |
| 218 ++histo[kHistoPalette * 256 + (hash & 0xff)]; | 218 ++histo[kHistoPalette * 256 + (hash & 0xff)]; |
| 219 } | 219 } |
| 220 } | 220 } |
| 221 prev_row = curr_row; | 221 prev_row = curr_row; |
| 222 curr_row += argb_stride; | 222 curr_row += argb_stride; |
| 223 } | 223 } |
| 224 { | 224 { |
| 225 double entropy_comp[kHistoTotal]; | 225 double entropy_comp[kHistoTotal]; |
| 226 double entropy[kNumEntropyIx]; | 226 double entropy[kNumEntropyIx]; |
| 227 EntropyIx k; | 227 int k; |
| 228 EntropyIx last_mode_to_analyze = | 228 int last_mode_to_analyze = use_palette ? kPalette : kSpatialSubGreen; |
| 229 use_palette ? kPalette : kSpatialSubGreen; | |
| 230 int j; | 229 int j; |
| 231 // Let's add one zero to the predicted histograms. The zeros are removed | 230 // Let's add one zero to the predicted histograms. The zeros are removed |
| 232 // too efficiently by the pix_diff == 0 comparison, at least one of the | 231 // too efficiently by the pix_diff == 0 comparison, at least one of the |
| 233 // zeros is likely to exist. | 232 // zeros is likely to exist. |
| 234 ++histo[kHistoRedPredSubGreen * 256]; | 233 ++histo[kHistoRedPredSubGreen * 256]; |
| 235 ++histo[kHistoBluePredSubGreen * 256]; | 234 ++histo[kHistoBluePredSubGreen * 256]; |
| 236 ++histo[kHistoRedPred * 256]; | 235 ++histo[kHistoRedPred * 256]; |
| 237 ++histo[kHistoGreenPred * 256]; | 236 ++histo[kHistoGreenPred * 256]; |
| 238 ++histo[kHistoBluePred * 256]; | 237 ++histo[kHistoBluePred * 256]; |
| 239 ++histo[kHistoAlphaPred * 256]; | 238 ++histo[kHistoAlphaPred * 256]; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 256 entropy[kSpatialSubGreen] = entropy_comp[kHistoAlphaPred] + | 255 entropy[kSpatialSubGreen] = entropy_comp[kHistoAlphaPred] + |
| 257 entropy_comp[kHistoRedPredSubGreen] + | 256 entropy_comp[kHistoRedPredSubGreen] + |
| 258 entropy_comp[kHistoGreenPred] + | 257 entropy_comp[kHistoGreenPred] + |
| 259 entropy_comp[kHistoBluePredSubGreen]; | 258 entropy_comp[kHistoBluePredSubGreen]; |
| 260 // Palette mode seems more efficient in a breakeven case. Bias with 1.0. | 259 // Palette mode seems more efficient in a breakeven case. Bias with 1.0. |
| 261 entropy[kPalette] = entropy_comp[kHistoPalette] - 1.0; | 260 entropy[kPalette] = entropy_comp[kHistoPalette] - 1.0; |
| 262 | 261 |
| 263 *min_entropy_ix = kDirect; | 262 *min_entropy_ix = kDirect; |
| 264 for (k = kDirect + 1; k <= last_mode_to_analyze; ++k) { | 263 for (k = kDirect + 1; k <= last_mode_to_analyze; ++k) { |
| 265 if (entropy[*min_entropy_ix] > entropy[k]) { | 264 if (entropy[*min_entropy_ix] > entropy[k]) { |
| 266 *min_entropy_ix = k; | 265 *min_entropy_ix = (EntropyIx)k; |
| 267 } | 266 } |
| 268 } | 267 } |
| 269 *red_and_blue_always_zero = 1; | 268 *red_and_blue_always_zero = 1; |
| 270 // Let's check if the histogram of the chosen entropy mode has | 269 // Let's check if the histogram of the chosen entropy mode has |
| 271 // non-zero red and blue values. If all are zero, we can later skip | 270 // non-zero red and blue values. If all are zero, we can later skip |
| 272 // the cross color optimization. | 271 // the cross color optimization. |
| 273 { | 272 { |
| 274 static const uint8_t kHistoPairs[5][2] = { | 273 static const uint8_t kHistoPairs[5][2] = { |
| 275 { kHistoRed, kHistoBlue }, | 274 { kHistoRed, kHistoBlue }, |
| 276 { kHistoRedPred, kHistoBluePred }, | 275 { kHistoRedPred, kHistoBluePred }, |
| (...skipping 1317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1594 if (bw.error_) err = VP8_ENC_ERROR_OUT_OF_MEMORY; | 1593 if (bw.error_) err = VP8_ENC_ERROR_OUT_OF_MEMORY; |
| 1595 VP8LBitWriterWipeOut(&bw); | 1594 VP8LBitWriterWipeOut(&bw); |
| 1596 if (err != VP8_ENC_OK) { | 1595 if (err != VP8_ENC_OK) { |
| 1597 WebPEncodingSetError(picture, err); | 1596 WebPEncodingSetError(picture, err); |
| 1598 return 0; | 1597 return 0; |
| 1599 } | 1598 } |
| 1600 return 1; | 1599 return 1; |
| 1601 } | 1600 } |
| 1602 | 1601 |
| 1603 //------------------------------------------------------------------------------ | 1602 //------------------------------------------------------------------------------ |
| OLD | NEW |