summaryrefslogtreecommitdiff
path: root/drivers/webp/utils/utils.c
diff options
context:
space:
mode:
authorvolzhs <volzhs@gmail.com>2016-07-08 19:29:58 +0900
committervolzhs <volzhs@gmail.com>2016-07-08 21:44:40 +0900
commitddd446f274d33d8624da3fd842c23e9ede0e6b11 (patch)
treef3b5de16472af57350b4f1de8d40b64365423b90 /drivers/webp/utils/utils.c
parentdc58be9f3542d640771722187959f56f042b5baa (diff)
Update webp driver to 0.5.1 (upstream)
Diffstat (limited to 'drivers/webp/utils/utils.c')
-rw-r--r--drivers/webp/utils/utils.c70
1 files changed, 68 insertions, 2 deletions
diff --git a/drivers/webp/utils/utils.c b/drivers/webp/utils/utils.c
index 35aeae6ab8..2602ca3c9f 100644
--- a/drivers/webp/utils/utils.c
+++ b/drivers/webp/utils/utils.c
@@ -13,8 +13,9 @@
#include <stdlib.h>
#include <string.h> // for memcpy()
-#include "webp/decode.h"
-#include "webp/encode.h"
+#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
+
+//------------------------------------------------------------------------------