summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/libwebp/src/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/libwebp/src/utils')
-rw-r--r--src/3rdparty/libwebp/src/utils/bit_reader.c18
-rw-r--r--src/3rdparty/libwebp/src/utils/bit_reader_inl.h3
-rw-r--r--src/3rdparty/libwebp/src/utils/color_cache.c2
-rw-r--r--src/3rdparty/libwebp/src/utils/huffman.c2
-rw-r--r--src/3rdparty/libwebp/src/utils/huffman_encode.c2
-rw-r--r--src/3rdparty/libwebp/src/utils/quant_levels_dec.c33
-rw-r--r--src/3rdparty/libwebp/src/utils/quant_levels_dec.h4
-rw-r--r--src/3rdparty/libwebp/src/utils/utils.c66
-rw-r--r--src/3rdparty/libwebp/src/utils/utils.h22
9 files changed, 118 insertions, 34 deletions
diff --git a/src/3rdparty/libwebp/src/utils/bit_reader.c b/src/3rdparty/libwebp/src/utils/bit_reader.c
index 45198e1..50ffb74 100644
--- a/src/3rdparty/libwebp/src/utils/bit_reader.c
+++ b/src/3rdparty/libwebp/src/utils/bit_reader.c
@@ -16,6 +16,7 @@
#endif
#include "./bit_reader_inl.h"
+#include "../utils/utils.h"
//------------------------------------------------------------------------------
// VP8BitReader
@@ -119,11 +120,10 @@ int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) {
#define VP8L_LOG8_WBITS 4 // Number of bytes needed to store VP8L_WBITS bits.
-#if !defined(WEBP_FORCE_ALIGNED) && \
- (defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || \
- defined(__i386__) || defined(_M_IX86) || \
- defined(__x86_64__) || defined(_M_X64))
-#define VP8L_USE_UNALIGNED_LOAD
+#if defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || \
+ defined(__i386__) || defined(_M_IX86) || \
+ defined(__x86_64__) || defined(_M_X64)
+#define VP8L_USE_FAST_LOAD
#endif
static const uint32_t kBitMask[VP8L_MAX_NUM_BIT_READ + 1] = {
@@ -191,15 +191,11 @@ static void ShiftBytes(VP8LBitReader* const br) {
void VP8LDoFillBitWindow(VP8LBitReader* const br) {
assert(br->bit_pos_ >= VP8L_WBITS);
- // TODO(jzern): given the fixed read size it may be possible to force
- // alignment in this block.
-#if defined(VP8L_USE_UNALIGNED_LOAD)
+#if defined(VP8L_USE_FAST_LOAD)
if (br->pos_ + sizeof(br->val_) < br->len_) {
br->val_ >>= VP8L_WBITS;
br->bit_pos_ -= VP8L_WBITS;
- // The expression below needs a little-endian arch to work correctly.
- // This gives a large speedup for decoding speed.
- br->val_ |= (vp8l_val_t)WebPMemToUint32(br->buf_ + br->pos_) <<
+ br->val_ |= (vp8l_val_t)HToLE32(WebPMemToUint32(br->buf_ + br->pos_)) <<
(VP8L_LBITS - VP8L_WBITS);
br->pos_ += VP8L_LOG8_WBITS;
return;
diff --git a/src/3rdparty/libwebp/src/utils/bit_reader_inl.h b/src/3rdparty/libwebp/src/utils/bit_reader_inl.h
index 3721570..99ed313 100644
--- a/src/3rdparty/libwebp/src/utils/bit_reader_inl.h
+++ b/src/3rdparty/libwebp/src/utils/bit_reader_inl.h
@@ -55,7 +55,8 @@ void VP8LoadFinalBytes(VP8BitReader* const br);
// Inlined critical functions
// makes sure br->value_ has at least BITS bits worth of data
-static WEBP_INLINE void VP8LoadNewBytes(VP8BitReader* const br) {
+static WEBP_UBSAN_IGNORE_UNDEF WEBP_INLINE
+void VP8LoadNewBytes(VP8BitReader* const br) {
assert(br != NULL && br->buf_ != NULL);
// Read 'BITS' bits at a time if possible.
if (br->buf_ < br->buf_max_) {
diff --git a/src/3rdparty/libwebp/src/utils/color_cache.c b/src/3rdparty/libwebp/src/utils/color_cache.c
index f9ff4b5..c34b2e7 100644
--- a/src/3rdparty/libwebp/src/utils/color_cache.c
+++ b/src/3rdparty/libwebp/src/utils/color_cache.c
@@ -15,7 +15,7 @@
#include <stdlib.h>
#include <string.h>
#include "./color_cache.h"
-#include "../utils/utils.h"
+#include "./utils.h"
//------------------------------------------------------------------------------
// VP8LColorCache.
diff --git a/src/3rdparty/libwebp/src/utils/huffman.c b/src/3rdparty/libwebp/src/utils/huffman.c
index d57376a..36e5502 100644
--- a/src/3rdparty/libwebp/src/utils/huffman.c
+++ b/src/3rdparty/libwebp/src/utils/huffman.c
@@ -15,7 +15,7 @@
#include <stdlib.h>
#include <string.h>
#include "./huffman.h"
-#include "../utils/utils.h"
+#include "./utils.h"
#include "../webp/format_constants.h"
// Huffman data read via DecodeImageStream is represented in two (red and green)
diff --git a/src/3rdparty/libwebp/src/utils/huffman_encode.c b/src/3rdparty/libwebp/src/utils/huffman_encode.c
index 6421c2b..4e5ef6b 100644
--- a/src/3rdparty/libwebp/src/utils/huffman_encode.c
+++ b/src/3rdparty/libwebp/src/utils/huffman_encode.c
@@ -15,7 +15,7 @@
#include <stdlib.h>
#include <string.h>
#include "./huffman_encode.h"
-#include "../utils/utils.h"
+#include "./utils.h"
#include "../webp/format_constants.h"
// -----------------------------------------------------------------------------
diff --git a/src/3rdparty/libwebp/src/utils/quant_levels_dec.c b/src/3rdparty/libwebp/src/utils/quant_levels_dec.c
index 5b8b8b4..ee0a3fe 100644
--- a/src/3rdparty/libwebp/src/utils/quant_levels_dec.c
+++ b/src/3rdparty/libwebp/src/utils/quant_levels_dec.c
@@ -44,6 +44,7 @@ static const uint8_t kOrderedDither[DSIZE][DSIZE] = {
typedef struct {
int width_, height_; // dimension
+ int stride_; // stride in bytes
int row_; // current input row being processed
uint8_t* src_; // input pointer
uint8_t* dst_; // output pointer
@@ -99,7 +100,7 @@ static void VFilter(SmoothParams* const p) {
// We replicate edges, as it's somewhat easier as a boundary condition.
// That's why we don't update the 'src' pointer on top/bottom area:
if (p->row_ >= 0 && p->row_ < p->height_ - 1) {
- p->src_ += p->width_;
+ p->src_ += p->stride_;
}
}
@@ -149,7 +150,7 @@ static void ApplyFilter(SmoothParams* const p) {
#endif
}
}
- p->dst_ += w; // advance output pointer
+ p->dst_ += p->stride_; // advance output pointer
}
//------------------------------------------------------------------------------
@@ -178,17 +179,20 @@ static void InitCorrectionLUT(int16_t* const lut, int min_dist) {
lut[0] = 0;
}
-static void CountLevels(const uint8_t* const data, int size,
- SmoothParams* const p) {
- int i, last_level;
+static void CountLevels(SmoothParams* const p) {
+ int i, j, last_level;
uint8_t used_levels[256] = { 0 };
+ const uint8_t* data = p->src_;
p->min_ = 255;
p->max_ = 0;
- for (i = 0; i < size; ++i) {
- const int v = data[i];
- if (v < p->min_) p->min_ = v;
- if (v > p->max_) p->max_ = v;
- used_levels[v] = 1;
+ for (j = 0; j < p->height_; ++j) {
+ for (i = 0; i < p->width_; ++i) {
+ const int v = data[i];
+ if (v < p->min_) p->min_ = v;
+ if (v > p->max_) p->max_ = v;
+ used_levels[v] = 1;
+ }
+ data += p->stride_;
}
// Compute the mininum distance between two non-zero levels.
p->min_level_dist_ = p->max_ - p->min_;
@@ -208,7 +212,7 @@ static void CountLevels(const uint8_t* const data, int size,
}
// Initialize all params.
-static int InitParams(uint8_t* const data, int width, int height,
+static int InitParams(uint8_t* const data, int width, int height, int stride,
int radius, SmoothParams* const p) {
const int R = 2 * radius + 1; // total size of the kernel
@@ -233,6 +237,7 @@ static int InitParams(uint8_t* const data, int width, int height,
p->width_ = width;
p->height_ = height;
+ p->stride_ = stride;
p->src_ = data;
p->dst_ = data;
p->radius_ = radius;
@@ -240,7 +245,7 @@ static int InitParams(uint8_t* const data, int width, int height,
p->row_ = -radius;
// analyze the input distribution so we can best-fit the threshold
- CountLevels(data, width * height, p);
+ CountLevels(p);
// correction table
p->correction_ = ((int16_t*)mem) + LUT_SIZE;
@@ -253,7 +258,7 @@ static void CleanupParams(SmoothParams* const p) {
WebPSafeFree(p->mem_);
}
-int WebPDequantizeLevels(uint8_t* const data, int width, int height,
+int WebPDequantizeLevels(uint8_t* const data, int width, int height, int stride,
int strength) {
const int radius = 4 * strength / 100;
if (strength < 0 || strength > 100) return 0;
@@ -261,7 +266,7 @@ int WebPDequantizeLevels(uint8_t* const data, int width, int height,
if (radius > 0) {
SmoothParams p;
memset(&p, 0, sizeof(p));
- if (!InitParams(data, width, height, radius, &p)) return 0;
+ if (!InitParams(data, width, height, stride, radius, &p)) return 0;
if (p.num_levels_ > 2) {
for (; p.row_ < p.height_; ++p.row_) {
VFilter(&p); // accumulate average of input
diff --git a/src/3rdparty/libwebp/src/utils/quant_levels_dec.h b/src/3rdparty/libwebp/src/utils/quant_levels_dec.h
index 9aab068..59a1349 100644
--- a/src/3rdparty/libwebp/src/utils/quant_levels_dec.h
+++ b/src/3rdparty/libwebp/src/utils/quant_levels_dec.h
@@ -21,11 +21,11 @@ extern "C" {
#endif
// Apply post-processing to input 'data' of size 'width'x'height' assuming that
-// the source was quantized to a reduced number of levels.
+// the source was quantized to a reduced number of levels. 'stride' is in bytes.
// Strength is in [0..100] and controls the amount of dithering applied.
// Returns false in case of error (data is NULL, invalid parameters,
// malloc failure, ...).
-int WebPDequantizeLevels(uint8_t* const data, int width, int height,
+int WebPDequantizeLevels(uint8_t* const data, int width, int height, int stride,
int strength);
#ifdef __cplusplus
diff --git a/src/3rdparty/libwebp/src/utils/utils.c b/src/3rdparty/libwebp/src/utils/utils.c
index d8e3093..2602ca3 100644
--- a/src/3rdparty/libwebp/src/utils/utils.c
+++ b/src/3rdparty/libwebp/src/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
+
+//------------------------------------------------------------------------------
diff --git a/src/3rdparty/libwebp/src/utils/utils.h b/src/3rdparty/libwebp/src/utils/utils.h
index f506d66..e0a8112 100644
--- a/src/3rdparty/libwebp/src/utils/utils.h
+++ b/src/3rdparty/libwebp/src/utils/utils.h
@@ -21,6 +21,7 @@
#include <assert.h>
+#include "../dsp/dsp.h"
#include "../webp/types.h"
#ifdef __cplusplus
@@ -51,7 +52,7 @@ WEBP_EXTERN(void) WebPSafeFree(void* const ptr);
// Alignment
#define WEBP_ALIGN_CST 31
-#define WEBP_ALIGN(PTR) ((uintptr_t)((PTR) + WEBP_ALIGN_CST) & ~WEBP_ALIGN_CST)
+#define WEBP_ALIGN(PTR) (((uintptr_t)(PTR) + WEBP_ALIGN_CST) & ~WEBP_ALIGN_CST)
#if defined(WEBP_FORCE_ALIGNED)
#include <string.h>
@@ -65,10 +66,12 @@ static WEBP_INLINE void WebPUint32ToMem(uint8_t* const ptr, uint32_t val) {
memcpy(ptr, &val, sizeof(val));
}
#else
-static WEBP_INLINE uint32_t WebPMemToUint32(const uint8_t* const ptr) {
+static WEBP_UBSAN_IGNORE_UNDEF WEBP_INLINE
+uint32_t WebPMemToUint32(const uint8_t* const ptr) {
return *(const uint32_t*)ptr;
}
-static WEBP_INLINE void WebPUint32ToMem(uint8_t* const ptr, uint32_t val) {
+static WEBP_UBSAN_IGNORE_UNDEF WEBP_INLINE
+void WebPUint32ToMem(uint8_t* const ptr, uint32_t val) {
*(uint32_t*)ptr = val;
}
#endif
@@ -158,6 +161,19 @@ WEBP_EXTERN(void) WebPCopyPixels(const struct WebPPicture* const src,
struct WebPPicture* const dst);
//------------------------------------------------------------------------------
+// Unique colors.
+
+// Returns count of unique colors in 'pic', assuming pic->use_argb is true.
+// If the unique color count is more than MAX_COLOR_COUNT, returns
+// MAX_COLOR_COUNT+1.
+// If 'palette' is not NULL and number of unique colors is less than or equal to
+// MAX_COLOR_COUNT, also outputs the actual unique colors into 'palette'.
+// Note: 'palette' is assumed to be an array already allocated with at least
+// MAX_COLOR_COUNT elements.
+WEBP_EXTERN(int) WebPGetColorPalette(const struct WebPPicture* const pic,
+ uint32_t* const palette);
+
+//------------------------------------------------------------------------------
#ifdef __cplusplus
} // extern "C"