Index: third_party/libwebp/dsp/lossless.h |
diff --git a/third_party/libwebp/dsp/lossless.h b/third_party/libwebp/dsp/lossless.h |
index 7490ec8efe21ebd23a93a18dc9eae014a85b534c..0f1d44200b4cc1a21ac91909a38381d21349794e 100644 |
--- a/third_party/libwebp/dsp/lossless.h |
+++ b/third_party/libwebp/dsp/lossless.h |
@@ -18,11 +18,31 @@ |
#include "../webp/types.h" |
#include "../webp/decode.h" |
-#if defined(__cplusplus) || defined(c_plusplus) |
+#ifdef __cplusplus |
extern "C" { |
#endif |
//------------------------------------------------------------------------------ |
+// |
+ |
+typedef uint32_t (*VP8LPredClampedAddSubFunc)(uint32_t c0, uint32_t c1, |
+ uint32_t c2); |
+typedef uint32_t (*VP8LPredSelectFunc)(uint32_t c0, uint32_t c1, uint32_t c2); |
+typedef void (*VP8LSubtractGreenFromBlueAndRedFunc)(uint32_t* argb_data, |
+ int num_pixs); |
+typedef void (*VP8LAddGreenToBlueAndRedFunc)(uint32_t* data_start, |
+ const uint32_t* data_end); |
+ |
+extern VP8LPredClampedAddSubFunc VP8LClampedAddSubtractFull; |
+extern VP8LPredClampedAddSubFunc VP8LClampedAddSubtractHalf; |
+extern VP8LPredSelectFunc VP8LSelect; |
+extern VP8LSubtractGreenFromBlueAndRedFunc VP8LSubtractGreenFromBlueAndRed; |
+extern VP8LAddGreenToBlueAndRedFunc VP8LAddGreenToBlueAndRed; |
+ |
+// Must be called before calling any of the above methods. |
+void VP8LDspInit(void); |
+ |
+//------------------------------------------------------------------------------ |
// Image transforms. |
struct VP8LTransform; // Defined in dec/vp8li.h. |
@@ -42,9 +62,6 @@ void VP8LColorIndexInverseTransformAlpha( |
const struct VP8LTransform* const transform, int y_start, int y_end, |
const uint8_t* src, uint8_t* dst); |
-// Subtracts green from blue and red channels. |
-void VP8LSubtractGreenFromBlueAndRed(uint32_t* argb_data, int num_pixs); |
- |
void VP8LResidualImage(int width, int height, int bits, |
uint32_t* const argb, uint32_t* const argb_scratch, |
uint32_t* const image); |
@@ -72,8 +89,8 @@ static WEBP_INLINE uint32_t VP8LSubSampleSize(uint32_t size, |
#define LOG_LOOKUP_IDX_MAX 256 |
extern const float kLog2Table[LOG_LOOKUP_IDX_MAX]; |
extern const float kSLog2Table[LOG_LOOKUP_IDX_MAX]; |
-extern float VP8LFastLog2Slow(int v); |
-extern float VP8LFastSLog2Slow(int v); |
+float VP8LFastLog2Slow(int v); |
+float VP8LFastSLog2Slow(int v); |
static WEBP_INLINE float VP8LFastLog2(int v) { |
return (v < LOG_LOOKUP_IDX_MAX) ? kLog2Table[v] : VP8LFastLog2Slow(v); |
} |
@@ -82,6 +99,105 @@ static WEBP_INLINE float VP8LFastSLog2(int v) { |
return (v < LOG_LOOKUP_IDX_MAX) ? kSLog2Table[v] : VP8LFastSLog2Slow(v); |
} |
+// ----------------------------------------------------------------------------- |
+// PrefixEncode() |
+ |
+// use GNU builtins where available. |
+#if defined(__GNUC__) && \ |
+ ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4) |
+static WEBP_INLINE int BitsLog2Floor(uint32_t n) { |
+ return 31 ^ __builtin_clz(n); |
+} |
+#elif defined(_MSC_VER) && _MSC_VER > 1310 && \ |
+ (defined(_M_X64) || defined(_M_IX86)) |
+#include <intrin.h> |
+#pragma intrinsic(_BitScanReverse) |
+ |
+static WEBP_INLINE int BitsLog2Floor(uint32_t n) { |
+ unsigned long first_set_bit; |
+ _BitScanReverse(&first_set_bit, n); |
+ return first_set_bit; |
+} |
+#else |
+// Returns (int)floor(log2(n)). n must be > 0. |
+static WEBP_INLINE int BitsLog2Floor(uint32_t n) { |
+ int log = 0; |
+ uint32_t value = n; |
+ int i; |
+ |
+ for (i = 4; i >= 0; --i) { |
+ const int shift = (1 << i); |
+ const uint32_t x = value >> shift; |
+ if (x != 0) { |
+ value = x; |
+ log += shift; |
+ } |
+ } |
+ return log; |
+} |
+#endif |
+ |
+static WEBP_INLINE int VP8LBitsLog2Ceiling(uint32_t n) { |
+ const int log_floor = BitsLog2Floor(n); |
+ if (n == (n & ~(n - 1))) // zero or a power of two. |
+ return log_floor; |
+ else |
+ return log_floor + 1; |
+} |
+ |
+// Splitting of distance and length codes into prefixes and |
+// extra bits. The prefixes are encoded with an entropy code |
+// while the extra bits are stored just as normal bits. |
+static WEBP_INLINE void VP8LPrefixEncodeBitsNoLUT(int distance, int* const code, |
+ int* const extra_bits) { |
+ const int highest_bit = BitsLog2Floor(--distance); |
+ const int second_highest_bit = (distance >> (highest_bit - 1)) & 1; |
+ *extra_bits = highest_bit - 1; |
+ *code = 2 * highest_bit + second_highest_bit; |
+} |
+ |
+static WEBP_INLINE void VP8LPrefixEncodeNoLUT(int distance, int* const code, |
+ int* const extra_bits, |
+ int* const extra_bits_value) { |
+ const int highest_bit = BitsLog2Floor(--distance); |
+ const int second_highest_bit = (distance >> (highest_bit - 1)) & 1; |
+ *extra_bits = highest_bit - 1; |
+ *extra_bits_value = distance & ((1 << *extra_bits) - 1); |
+ *code = 2 * highest_bit + second_highest_bit; |
+} |
+ |
+#define PREFIX_LOOKUP_IDX_MAX 512 |
+typedef struct { |
+ int8_t code_; |
+ int8_t extra_bits_; |
+} VP8LPrefixCode; |
+ |
+// These tables are derived using VP8LPrefixEncodeNoLUT. |
+extern const VP8LPrefixCode kPrefixEncodeCode[PREFIX_LOOKUP_IDX_MAX]; |
+extern const uint8_t kPrefixEncodeExtraBitsValue[PREFIX_LOOKUP_IDX_MAX]; |
+static WEBP_INLINE void VP8LPrefixEncodeBits(int distance, int* const code, |
+ int* const extra_bits) { |
+ if (distance < PREFIX_LOOKUP_IDX_MAX) { |
+ const VP8LPrefixCode prefix_code = kPrefixEncodeCode[distance]; |
+ *code = prefix_code.code_; |
+ *extra_bits = prefix_code.extra_bits_; |
+ } else { |
+ VP8LPrefixEncodeBitsNoLUT(distance, code, extra_bits); |
+ } |
+} |
+ |
+static WEBP_INLINE void VP8LPrefixEncode(int distance, int* const code, |
+ int* const extra_bits, |
+ int* const extra_bits_value) { |
+ if (distance < PREFIX_LOOKUP_IDX_MAX) { |
+ const VP8LPrefixCode prefix_code = kPrefixEncodeCode[distance]; |
+ *code = prefix_code.code_; |
+ *extra_bits = prefix_code.extra_bits_; |
+ *extra_bits_value = kPrefixEncodeExtraBitsValue[distance]; |
+ } else { |
+ VP8LPrefixEncodeNoLUT(distance, code, extra_bits, extra_bits_value); |
+ } |
+} |
// In-place difference of each component with mod 256. |
static WEBP_INLINE uint32_t VP8LSubPixels(uint32_t a, uint32_t b) { |
@@ -97,7 +213,7 @@ void VP8LBundleColorMap(const uint8_t* const row, int width, |
//------------------------------------------------------------------------------ |
-#if defined(__cplusplus) || defined(c_plusplus) |
+#ifdef __cplusplus |
} // extern "C" |
#endif |