| Index: third_party/libwebp/utils/utils.c
|
| diff --git a/third_party/libwebp/utils/utils.c b/third_party/libwebp/utils/utils.c
|
| index d8e30930af298217438d45eb9b62f4c504c1b474..2602ca3c9f6e4fee63010b8beea6c5499e5869c6 100644
|
| --- a/third_party/libwebp/utils/utils.c
|
| +++ b/third_party/libwebp/utils/utils.c
|
| @@ -15,6 +15,7 @@
|
| #include <string.h> // for memcpy()
|
| #include "../webp/decode.h"
|
| #include "../webp/encode.h"
|
| +#include "../webp/format_constants.h" // for MAX_PALETTE_SIZE
|
| #include "./utils.h"
|
|
|
| // If PRINT_MEM_INFO is defined, extra info (like total memory used, number of
|
| @@ -237,3 +238,68 @@ void WebPCopyPixels(const WebPPicture* const src, WebPPicture* const dst) {
|
| }
|
|
|
| //------------------------------------------------------------------------------
|
| +
|
| +#define MAX_COLOR_COUNT MAX_PALETTE_SIZE
|
| +#define COLOR_HASH_SIZE (MAX_COLOR_COUNT * 4)
|
| +#define COLOR_HASH_RIGHT_SHIFT 22 // 32 - log2(COLOR_HASH_SIZE).
|
| +
|
| +int WebPGetColorPalette(const WebPPicture* const pic, uint32_t* const palette) {
|
| + int i;
|
| + int x, y;
|
| + int num_colors = 0;
|
| + uint8_t in_use[COLOR_HASH_SIZE] = { 0 };
|
| + uint32_t colors[COLOR_HASH_SIZE];
|
| + static const uint32_t kHashMul = 0x1e35a7bdU;
|
| + const uint32_t* argb = pic->argb;
|
| + const int width = pic->width;
|
| + const int height = pic->height;
|
| + uint32_t last_pix = ~argb[0]; // so we're sure that last_pix != argb[0]
|
| + assert(pic != NULL);
|
| + assert(pic->use_argb);
|
| +
|
| + for (y = 0; y < height; ++y) {
|
| + for (x = 0; x < width; ++x) {
|
| + int key;
|
| + if (argb[x] == last_pix) {
|
| + continue;
|
| + }
|
| + last_pix = argb[x];
|
| + key = (kHashMul * last_pix) >> COLOR_HASH_RIGHT_SHIFT;
|
| + while (1) {
|
| + if (!in_use[key]) {
|
| + colors[key] = last_pix;
|
| + in_use[key] = 1;
|
| + ++num_colors;
|
| + if (num_colors > MAX_COLOR_COUNT) {
|
| + return MAX_COLOR_COUNT + 1; // Exact count not needed.
|
| + }
|
| + break;
|
| + } else if (colors[key] == last_pix) {
|
| + break; // The color is already there.
|
| + } else {
|
| + // Some other color sits here, so do linear conflict resolution.
|
| + ++key;
|
| + key &= (COLOR_HASH_SIZE - 1); // Key mask.
|
| + }
|
| + }
|
| + }
|
| + argb += pic->argb_stride;
|
| + }
|
| +
|
| + if (palette != NULL) { // Fill the colors into palette.
|
| + num_colors = 0;
|
| + for (i = 0; i < COLOR_HASH_SIZE; ++i) {
|
| + if (in_use[i]) {
|
| + palette[num_colors] = colors[i];
|
| + ++num_colors;
|
| + }
|
| + }
|
| + }
|
| + return num_colors;
|
| +}
|
| +
|
| +#undef MAX_COLOR_COUNT
|
| +#undef COLOR_HASH_SIZE
|
| +#undef COLOR_HASH_RIGHT_SHIFT
|
| +
|
| +//------------------------------------------------------------------------------
|
|
|