github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/webp/libwebp/src/dsp/lossless.h (about) 1 // Copyright 2012 Google Inc. All Rights Reserved. 2 // 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 5 // tree. An additional intellectual property rights grant can be found 6 // in the file PATENTS. All contributing project authors may 7 // be found in the AUTHORS file in the root of the source tree. 8 // ----------------------------------------------------------------------------- 9 // 10 // Image transforms and color space conversion methods for lossless decoder. 11 // 12 // Authors: Vikas Arora (vikaas.arora@gmail.com) 13 // Jyrki Alakuijala (jyrki@google.com) 14 15 #ifndef WEBP_DSP_LOSSLESS_H_ 16 #define WEBP_DSP_LOSSLESS_H_ 17 18 #include "../webp/types.h" 19 #include "../webp/decode.h" 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 //------------------------------------------------------------------------------ 26 // 27 28 typedef uint32_t (*VP8LPredClampedAddSubFunc)(uint32_t c0, uint32_t c1, 29 uint32_t c2); 30 typedef uint32_t (*VP8LPredSelectFunc)(uint32_t c0, uint32_t c1, uint32_t c2); 31 typedef void (*VP8LSubtractGreenFromBlueAndRedFunc)(uint32_t* argb_data, 32 int num_pixs); 33 typedef void (*VP8LAddGreenToBlueAndRedFunc)(uint32_t* data_start, 34 const uint32_t* data_end); 35 36 extern VP8LPredClampedAddSubFunc VP8LClampedAddSubtractFull; 37 extern VP8LPredClampedAddSubFunc VP8LClampedAddSubtractHalf; 38 extern VP8LPredSelectFunc VP8LSelect; 39 extern VP8LSubtractGreenFromBlueAndRedFunc VP8LSubtractGreenFromBlueAndRed; 40 extern VP8LAddGreenToBlueAndRedFunc VP8LAddGreenToBlueAndRed; 41 42 // Must be called before calling any of the above methods. 43 void VP8LDspInit(void); 44 45 //------------------------------------------------------------------------------ 46 // Image transforms. 47 48 struct VP8LTransform; // Defined in dec/vp8li.h. 49 50 // Performs inverse transform of data given transform information, start and end 51 // rows. Transform will be applied to rows [row_start, row_end[. 52 // The *in and *out pointers refer to source and destination data respectively 53 // corresponding to the intermediate row (row_start). 54 void VP8LInverseTransform(const struct VP8LTransform* const transform, 55 int row_start, int row_end, 56 const uint32_t* const in, uint32_t* const out); 57 58 // Similar to the static method ColorIndexInverseTransform() that is part of 59 // lossless.c, but used only for alpha decoding. It takes uint8_t (rather than 60 // uint32_t) arguments for 'src' and 'dst'. 61 void VP8LColorIndexInverseTransformAlpha( 62 const struct VP8LTransform* const transform, int y_start, int y_end, 63 const uint8_t* src, uint8_t* dst); 64 65 void VP8LResidualImage(int width, int height, int bits, 66 uint32_t* const argb, uint32_t* const argb_scratch, 67 uint32_t* const image); 68 69 void VP8LColorSpaceTransform(int width, int height, int bits, int step, 70 uint32_t* const argb, uint32_t* image); 71 72 //------------------------------------------------------------------------------ 73 // Color space conversion. 74 75 // Converts from BGRA to other color spaces. 76 void VP8LConvertFromBGRA(const uint32_t* const in_data, int num_pixels, 77 WEBP_CSP_MODE out_colorspace, uint8_t* const rgba); 78 79 //------------------------------------------------------------------------------ 80 // Misc methods. 81 82 // Computes sampled size of 'size' when sampling using 'sampling bits'. 83 static WEBP_INLINE uint32_t VP8LSubSampleSize(uint32_t size, 84 uint32_t sampling_bits) { 85 return (size + (1 << sampling_bits) - 1) >> sampling_bits; 86 } 87 88 // Faster logarithm for integers. Small values use a look-up table. 89 #define LOG_LOOKUP_IDX_MAX 256 90 extern const float kLog2Table[LOG_LOOKUP_IDX_MAX]; 91 extern const float kSLog2Table[LOG_LOOKUP_IDX_MAX]; 92 float VP8LFastLog2Slow(int v); 93 float VP8LFastSLog2Slow(int v); 94 static WEBP_INLINE float VP8LFastLog2(int v) { 95 return (v < LOG_LOOKUP_IDX_MAX) ? kLog2Table[v] : VP8LFastLog2Slow(v); 96 } 97 // Fast calculation of v * log2(v) for integer input. 98 static WEBP_INLINE float VP8LFastSLog2(int v) { 99 return (v < LOG_LOOKUP_IDX_MAX) ? kSLog2Table[v] : VP8LFastSLog2Slow(v); 100 } 101 102 // ----------------------------------------------------------------------------- 103 // PrefixEncode() 104 105 // use GNU builtins where available. 106 #if defined(__GNUC__) && \ 107 ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4) 108 static WEBP_INLINE int BitsLog2Floor(uint32_t n) { 109 return 31 ^ __builtin_clz(n); 110 } 111 #elif defined(_MSC_VER) && _MSC_VER > 1310 && \ 112 (defined(_M_X64) || defined(_M_IX86)) 113 #include <intrin.h> 114 #pragma intrinsic(_BitScanReverse) 115 116 static WEBP_INLINE int BitsLog2Floor(uint32_t n) { 117 unsigned long first_set_bit; 118 _BitScanReverse(&first_set_bit, n); 119 return first_set_bit; 120 } 121 #else 122 // Returns (int)floor(log2(n)). n must be > 0. 123 static WEBP_INLINE int BitsLog2Floor(uint32_t n) { 124 int log = 0; 125 uint32_t value = n; 126 int i; 127 128 for (i = 4; i >= 0; --i) { 129 const int shift = (1 << i); 130 const uint32_t x = value >> shift; 131 if (x != 0) { 132 value = x; 133 log += shift; 134 } 135 } 136 return log; 137 } 138 #endif 139 140 static WEBP_INLINE int VP8LBitsLog2Ceiling(uint32_t n) { 141 const int log_floor = BitsLog2Floor(n); 142 if (n == (n & ~(n - 1))) // zero or a power of two. 143 return log_floor; 144 else 145 return log_floor + 1; 146 } 147 148 // Splitting of distance and length codes into prefixes and 149 // extra bits. The prefixes are encoded with an entropy code 150 // while the extra bits are stored just as normal bits. 151 static WEBP_INLINE void VP8LPrefixEncodeBitsNoLUT(int distance, int* const code, 152 int* const extra_bits) { 153 const int highest_bit = BitsLog2Floor(--distance); 154 const int second_highest_bit = (distance >> (highest_bit - 1)) & 1; 155 *extra_bits = highest_bit - 1; 156 *code = 2 * highest_bit + second_highest_bit; 157 } 158 159 static WEBP_INLINE void VP8LPrefixEncodeNoLUT(int distance, int* const code, 160 int* const extra_bits, 161 int* const extra_bits_value) { 162 const int highest_bit = BitsLog2Floor(--distance); 163 const int second_highest_bit = (distance >> (highest_bit - 1)) & 1; 164 *extra_bits = highest_bit - 1; 165 *extra_bits_value = distance & ((1 << *extra_bits) - 1); 166 *code = 2 * highest_bit + second_highest_bit; 167 } 168 169 #define PREFIX_LOOKUP_IDX_MAX 512 170 typedef struct { 171 int8_t code_; 172 int8_t extra_bits_; 173 } VP8LPrefixCode; 174 175 // These tables are derived using VP8LPrefixEncodeNoLUT. 176 extern const VP8LPrefixCode kPrefixEncodeCode[PREFIX_LOOKUP_IDX_MAX]; 177 extern const uint8_t kPrefixEncodeExtraBitsValue[PREFIX_LOOKUP_IDX_MAX]; 178 static WEBP_INLINE void VP8LPrefixEncodeBits(int distance, int* const code, 179 int* const extra_bits) { 180 if (distance < PREFIX_LOOKUP_IDX_MAX) { 181 const VP8LPrefixCode prefix_code = kPrefixEncodeCode[distance]; 182 *code = prefix_code.code_; 183 *extra_bits = prefix_code.extra_bits_; 184 } else { 185 VP8LPrefixEncodeBitsNoLUT(distance, code, extra_bits); 186 } 187 } 188 189 static WEBP_INLINE void VP8LPrefixEncode(int distance, int* const code, 190 int* const extra_bits, 191 int* const extra_bits_value) { 192 if (distance < PREFIX_LOOKUP_IDX_MAX) { 193 const VP8LPrefixCode prefix_code = kPrefixEncodeCode[distance]; 194 *code = prefix_code.code_; 195 *extra_bits = prefix_code.extra_bits_; 196 *extra_bits_value = kPrefixEncodeExtraBitsValue[distance]; 197 } else { 198 VP8LPrefixEncodeNoLUT(distance, code, extra_bits, extra_bits_value); 199 } 200 } 201 202 // In-place difference of each component with mod 256. 203 static WEBP_INLINE uint32_t VP8LSubPixels(uint32_t a, uint32_t b) { 204 const uint32_t alpha_and_green = 205 0x00ff00ffu + (a & 0xff00ff00u) - (b & 0xff00ff00u); 206 const uint32_t red_and_blue = 207 0xff00ff00u + (a & 0x00ff00ffu) - (b & 0x00ff00ffu); 208 return (alpha_and_green & 0xff00ff00u) | (red_and_blue & 0x00ff00ffu); 209 } 210 211 void VP8LBundleColorMap(const uint8_t* const row, int width, 212 int xbits, uint32_t* const dst); 213 214 //------------------------------------------------------------------------------ 215 216 #ifdef __cplusplus 217 } // extern "C" 218 #endif 219 220 #endif // WEBP_DSP_LOSSLESS_H_