1 // Copyright 2011 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 // Speed-critical functions. 11 // 12 // Author: Skal (pascal.massimino@gmail.com) 13 14 #ifndef WEBP_DSP_DSP_H_ 15 #define WEBP_DSP_DSP_H_ 16 17 #ifdef HAVE_CONFIG_H 18 #include "src/webp/config.h" 19 #endif 20 21 #include "src/webp/types.h" 22 23 #ifdef __cplusplus 24 extern "C" { 25 #endif 26 27 #define BPS 32 // this is the common stride for enc/dec 28 29 //------------------------------------------------------------------------------ 30 // CPU detection 31 32 #if defined(__GNUC__) 33 # define LOCAL_GCC_VERSION ((__GNUC__ << 8) | __GNUC_MINOR__) 34 # define LOCAL_GCC_PREREQ(maj, min) \ 35 (LOCAL_GCC_VERSION >= (((maj) << 8) | (min))) 36 #else 37 # define LOCAL_GCC_VERSION 0 38 # define LOCAL_GCC_PREREQ(maj, min) 0 39 #endif 40 41 #if defined(__clang__) 42 # define LOCAL_CLANG_VERSION ((__clang_major__ << 8) | __clang_minor__) 43 # define LOCAL_CLANG_PREREQ(maj, min) \ 44 (LOCAL_CLANG_VERSION >= (((maj) << 8) | (min))) 45 #else 46 # define LOCAL_CLANG_VERSION 0 47 # define LOCAL_CLANG_PREREQ(maj, min) 0 48 #endif 49 50 #ifndef __has_builtin 51 # define __has_builtin(x) 0 52 #endif 53 54 #if !defined(HAVE_CONFIG_H) 55 #if defined(_MSC_VER) && _MSC_VER > 1310 && \ 56 (defined(_M_X64) || defined(_M_IX86)) 57 #define WEBP_MSC_SSE2 // Visual C++ SSE2 targets 58 #endif 59 60 #if defined(_MSC_VER) && _MSC_VER >= 1500 && \ 61 (defined(_M_X64) || defined(_M_IX86)) 62 #define WEBP_MSC_SSE41 // Visual C++ SSE4.1 targets 63 #endif 64 #endif 65 66 // WEBP_HAVE_* are used to indicate the presence of the instruction set in dsp 67 // files without intrinsics, allowing the corresponding Init() to be called. 68 // Files containing intrinsics will need to be built targeting the instruction 69 // set so should succeed on one of the earlier tests. 70 #if defined(__SSE2__) || defined(WEBP_MSC_SSE2) || defined(WEBP_HAVE_SSE2) 71 #define WEBP_USE_SSE2 72 #endif 73 74 #if defined(__SSE4_1__) || defined(WEBP_MSC_SSE41) || defined(WEBP_HAVE_SSE41) 75 #define WEBP_USE_SSE41 76 #endif 77 78 #undef WEBP_MSC_SSE41 79 #undef WEBP_MSC_SSE2 80 81 // The intrinsics currently cause compiler errors with arm-nacl-gcc and the 82 // inline assembly would need to be modified for use with Native Client. 83 #if (defined(__ARM_NEON__) || \ 84 defined(__aarch64__) || defined(WEBP_HAVE_NEON)) && \ 85 !defined(__native_client__) 86 #define WEBP_USE_NEON 87 #endif 88 89 #if !defined(WEBP_USE_NEON) && defined(__ANDROID__) && \ 90 defined(__ARM_ARCH_7A__) && defined(HAVE_CPU_FEATURES_H) 91 #define WEBP_ANDROID_NEON // Android targets that may have NEON 92 #define WEBP_USE_NEON 93 #endif 94 95 #if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM) 96 #define WEBP_USE_NEON 97 #define WEBP_USE_INTRINSICS 98 #endif 99 100 #if defined(__mips__) && !defined(__mips64) && \ 101 defined(__mips_isa_rev) && (__mips_isa_rev >= 1) && (__mips_isa_rev < 6) 102 #define WEBP_USE_MIPS32 103 #if (__mips_isa_rev >= 2) 104 #define WEBP_USE_MIPS32_R2 105 #if defined(__mips_dspr2) || (defined(__mips_dsp_rev) && __mips_dsp_rev >= 2) 106 #define WEBP_USE_MIPS_DSP_R2 107 #endif 108 #endif 109 #endif 110 111 #if defined(__mips_msa) && defined(__mips_isa_rev) && (__mips_isa_rev >= 5) 112 #define WEBP_USE_MSA 113 #endif 114 115 #ifndef WEBP_DSP_OMIT_C_CODE 116 #define WEBP_DSP_OMIT_C_CODE 1 117 #endif 118 119 #if (defined(__aarch64__) || defined(__ARM_NEON__)) && WEBP_DSP_OMIT_C_CODE 120 #define WEBP_NEON_OMIT_C_CODE 1 121 #else 122 #define WEBP_NEON_OMIT_C_CODE 0 123 #endif 124 125 #if !(LOCAL_CLANG_PREREQ(3,8) || LOCAL_GCC_PREREQ(4,8) || defined(__aarch64__)) 126 #define WEBP_NEON_WORK_AROUND_GCC 1 127 #else 128 #define WEBP_NEON_WORK_AROUND_GCC 0 129 #endif 130 131 // This macro prevents thread_sanitizer from reporting known concurrent writes. 132 #define WEBP_TSAN_IGNORE_FUNCTION 133 #if defined(__has_feature) 134 #if __has_feature(thread_sanitizer) 135 #undef WEBP_TSAN_IGNORE_FUNCTION 136 #define WEBP_TSAN_IGNORE_FUNCTION __attribute__((no_sanitize_thread)) 137 #endif 138 #endif 139 140 #if defined(WEBP_USE_THREAD) && !defined(_WIN32) 141 #include <pthread.h> // NOLINT 142 143 #define WEBP_DSP_INIT(func) do { \ 144 static volatile VP8CPUInfo func ## _last_cpuinfo_used = \ 145 (VP8CPUInfo)&func ## _last_cpuinfo_used; \ 146 static pthread_mutex_t func ## _lock = PTHREAD_MUTEX_INITIALIZER; \ 147 if (pthread_mutex_lock(&func ## _lock)) break; \ 148 if (func ## _last_cpuinfo_used != VP8GetCPUInfo) func(); \ 149 func ## _last_cpuinfo_used = VP8GetCPUInfo; \ 150 (void)pthread_mutex_unlock(&func ## _lock); \ 151 } while (0) 152 #else // !(defined(WEBP_USE_THREAD) && !defined(_WIN32)) 153 #define WEBP_DSP_INIT(func) do { \ 154 static volatile VP8CPUInfo func ## _last_cpuinfo_used = \ 155 (VP8CPUInfo)&func ## _last_cpuinfo_used; \ 156 if (func ## _last_cpuinfo_used == VP8GetCPUInfo) break; \ 157 func(); \ 158 func ## _last_cpuinfo_used = VP8GetCPUInfo; \ 159 } while (0) 160 #endif // defined(WEBP_USE_THREAD) && !defined(_WIN32) 161 162 // Defines an Init + helper function that control multiple initialization of 163 // function pointers / tables. 164 /* Usage: 165 WEBP_DSP_INIT_FUNC(InitFunc) { 166 ...function body 167 } 168 */ 169 #define WEBP_DSP_INIT_FUNC(name) \ 170 static WEBP_TSAN_IGNORE_FUNCTION void name ## _body(void); \ 171 WEBP_TSAN_IGNORE_FUNCTION void name(void) { \ 172 WEBP_DSP_INIT(name ## _body); \ 173 } \ 174 static WEBP_TSAN_IGNORE_FUNCTION void name ## _body(void) 175 176 #define WEBP_UBSAN_IGNORE_UNDEF 177 #define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW 178 #if defined(__clang__) && defined(__has_attribute) 179 #if __has_attribute(no_sanitize) 180 // This macro prevents the undefined behavior sanitizer from reporting 181 // failures. This is only meant to silence unaligned loads on platforms that 182 // are known to support them. 183 #undef WEBP_UBSAN_IGNORE_UNDEF 184 #define WEBP_UBSAN_IGNORE_UNDEF \ 185 __attribute__((no_sanitize("undefined"))) 186 187 // This macro prevents the undefined behavior sanitizer from reporting 188 // failures related to unsigned integer overflows. This is only meant to 189 // silence cases where this well defined behavior is expected. 190 #undef WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW 191 #define WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW \ 192 __attribute__((no_sanitize("unsigned-integer-overflow"))) 193 #endif 194 #endif 195 196 // If 'ptr' is NULL, returns NULL. Otherwise returns 'ptr + off'. 197 // Prevents undefined behavior sanitizer nullptr-with-nonzero-offset warning. 198 #if !defined(WEBP_OFFSET_PTR) 199 #define WEBP_OFFSET_PTR(ptr, off) (((ptr) == NULL) ? NULL : ((ptr) + (off))) 200 #endif 201 202 // Regularize the definition of WEBP_SWAP_16BIT_CSP (backward compatibility) 203 #if !defined(WEBP_SWAP_16BIT_CSP) 204 #define WEBP_SWAP_16BIT_CSP 0 205 #endif 206 207 // some endian fix (e.g.: mips-gcc doesn't define __BIG_ENDIAN__) 208 #if !defined(WORDS_BIGENDIAN) && \ 209 (defined(__BIG_ENDIAN__) || defined(_M_PPC) || \ 210 (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))) 211 #define WORDS_BIGENDIAN 212 #endif 213 214 typedef enum { 215 kSSE2, 216 kSSE3, 217 kSlowSSSE3, // special feature for slow SSSE3 architectures 218 kSSE4_1, 219 kAVX, 220 kAVX2, 221 kNEON, 222 kMIPS32, 223 kMIPSdspR2, 224 kMSA 225 } CPUFeature; 226 // returns true if the CPU supports the feature. 227 typedef int (*VP8CPUInfo)(CPUFeature feature); 228 WEBP_EXTERN VP8CPUInfo VP8GetCPUInfo; 229 230 //------------------------------------------------------------------------------ 231 // Init stub generator 232 233 // Defines an init function stub to ensure each module exposes a symbol, 234 // avoiding a compiler warning. 235 #define WEBP_DSP_INIT_STUB(func) \ 236 extern void func(void); \ 237 void func(void) {} 238 239 //------------------------------------------------------------------------------ 240 // Encoding 241 242 // Transforms 243 // VP8Idct: Does one of two inverse transforms. If do_two is set, the transforms 244 // will be done for (ref, in, dst) and (ref + 4, in + 16, dst + 4). 245 typedef void (*VP8Idct)(const uint8_t* ref, const int16_t* in, uint8_t* dst, 246 int do_two); 247 typedef void (*VP8Fdct)(const uint8_t* src, const uint8_t* ref, int16_t* out); 248 typedef void (*VP8WHT)(const int16_t* in, int16_t* out); 249 extern VP8Idct VP8ITransform; 250 extern VP8Fdct VP8FTransform; 251 extern VP8Fdct VP8FTransform2; // performs two transforms at a time 252 extern VP8WHT VP8FTransformWHT; 253 // Predictions 254 // *dst is the destination block. *top and *left can be NULL. 255 typedef void (*VP8IntraPreds)(uint8_t* dst, const uint8_t* left, 256 const uint8_t* top); 257 typedef void (*VP8Intra4Preds)(uint8_t* dst, const uint8_t* top); 258 extern VP8Intra4Preds VP8EncPredLuma4; 259 extern VP8IntraPreds VP8EncPredLuma16; 260 extern VP8IntraPreds VP8EncPredChroma8; 261 262 typedef int (*VP8Metric)(const uint8_t* pix, const uint8_t* ref); 263 extern VP8Metric VP8SSE16x16, VP8SSE16x8, VP8SSE8x8, VP8SSE4x4; 264 typedef int (*VP8WMetric)(const uint8_t* pix, const uint8_t* ref, 265 const uint16_t* const weights); 266 // The weights for VP8TDisto4x4 and VP8TDisto16x16 contain a row-major 267 // 4 by 4 symmetric matrix. 268 extern VP8WMetric VP8TDisto4x4, VP8TDisto16x16; 269 270 // Compute the average (DC) of four 4x4 blocks. 271 // Each sub-4x4 block #i sum is stored in dc[i]. 272 typedef void (*VP8MeanMetric)(const uint8_t* ref, uint32_t dc[4]); 273 extern VP8MeanMetric VP8Mean16x4; 274 275 typedef void (*VP8BlockCopy)(const uint8_t* src, uint8_t* dst); 276 extern VP8BlockCopy VP8Copy4x4; 277 extern VP8BlockCopy VP8Copy16x8; 278 // Quantization 279 struct VP8Matrix; // forward declaration 280 typedef int (*VP8QuantizeBlock)(int16_t in[16], int16_t out[16], 281 const struct VP8Matrix* const mtx); 282 // Same as VP8QuantizeBlock, but quantizes two consecutive blocks. 283 typedef int (*VP8Quantize2Blocks)(int16_t in[32], int16_t out[32], 284 const struct VP8Matrix* const mtx); 285 286 extern VP8QuantizeBlock VP8EncQuantizeBlock; 287 extern VP8Quantize2Blocks VP8EncQuantize2Blocks; 288 289 // specific to 2nd transform: 290 typedef int (*VP8QuantizeBlockWHT)(int16_t in[16], int16_t out[16], 291 const struct VP8Matrix* const mtx); 292 extern VP8QuantizeBlockWHT VP8EncQuantizeBlockWHT; 293 294 extern const int VP8DspScan[16 + 4 + 4]; 295 296 // Collect histogram for susceptibility calculation. 297 #define MAX_COEFF_THRESH 31 // size of histogram used by CollectHistogram. 298 typedef struct { 299 // We only need to store max_value and last_non_zero, not the distribution. 300 int max_value; 301 int last_non_zero; 302 } VP8Histogram; 303 typedef void (*VP8CHisto)(const uint8_t* ref, const uint8_t* pred, 304 int start_block, int end_block, 305 VP8Histogram* const histo); 306 extern VP8CHisto VP8CollectHistogram; 307 // General-purpose util function to help VP8CollectHistogram(). 308 void VP8SetHistogramData(const int distribution[MAX_COEFF_THRESH + 1], 309 VP8Histogram* const histo); 310 311 // must be called before using any of the above 312 void VP8EncDspInit(void); 313 314 //------------------------------------------------------------------------------ 315 // cost functions (encoding) 316 317 extern const uint16_t VP8EntropyCost[256]; // 8bit fixed-point log(p) 318 // approximate cost per level: 319 extern const uint16_t VP8LevelFixedCosts[2047 /*MAX_LEVEL*/ + 1]; 320 extern const uint8_t VP8EncBands[16 + 1]; 321 322 struct VP8Residual; 323 typedef void (*VP8SetResidualCoeffsFunc)(const int16_t* const coeffs, 324 struct VP8Residual* const res); 325 extern VP8SetResidualCoeffsFunc VP8SetResidualCoeffs; 326 327 // Cost calculation function. 328 typedef int (*VP8GetResidualCostFunc)(int ctx0, 329 const struct VP8Residual* const res); 330 extern VP8GetResidualCostFunc VP8GetResidualCost; 331 332 // must be called before anything using the above 333 void VP8EncDspCostInit(void); 334 335 //------------------------------------------------------------------------------ 336 // SSIM / PSNR utils 337 338 // struct for accumulating statistical moments 339 typedef struct { 340 uint32_t w; // sum(w_i) : sum of weights 341 uint32_t xm, ym; // sum(w_i * x_i), sum(w_i * y_i) 342 uint32_t xxm, xym, yym; // sum(w_i * x_i * x_i), etc. 343 } VP8DistoStats; 344 345 // Compute the final SSIM value 346 // The non-clipped version assumes stats->w = (2 * VP8_SSIM_KERNEL + 1)^2. 347 double VP8SSIMFromStats(const VP8DistoStats* const stats); 348 double VP8SSIMFromStatsClipped(const VP8DistoStats* const stats); 349 350 #define VP8_SSIM_KERNEL 3 // total size of the kernel: 2 * VP8_SSIM_KERNEL + 1 351 typedef double (*VP8SSIMGetClippedFunc)(const uint8_t* src1, int stride1, 352 const uint8_t* src2, int stride2, 353 int xo, int yo, // center position 354 int W, int H); // plane dimension 355 356 #if !defined(WEBP_REDUCE_SIZE) 357 // This version is called with the guarantee that you can load 8 bytes and 358 // 8 rows at offset src1 and src2 359 typedef double (*VP8SSIMGetFunc)(const uint8_t* src1, int stride1, 360 const uint8_t* src2, int stride2); 361 362 extern VP8SSIMGetFunc VP8SSIMGet; // unclipped / unchecked 363 extern VP8SSIMGetClippedFunc VP8SSIMGetClipped; // with clipping 364 #endif 365 366 #if !defined(WEBP_DISABLE_STATS) 367 typedef uint32_t (*VP8AccumulateSSEFunc)(const uint8_t* src1, 368 const uint8_t* src2, int len); 369 extern VP8AccumulateSSEFunc VP8AccumulateSSE; 370 #endif 371 372 // must be called before using any of the above directly 373 void VP8SSIMDspInit(void); 374 375 //------------------------------------------------------------------------------ 376 // Decoding 377 378 typedef void (*VP8DecIdct)(const int16_t* coeffs, uint8_t* dst); 379 // when doing two transforms, coeffs is actually int16_t[2][16]. 380 typedef void (*VP8DecIdct2)(const int16_t* coeffs, uint8_t* dst, int do_two); 381 extern VP8DecIdct2 VP8Transform; 382 extern VP8DecIdct VP8TransformAC3; 383 extern VP8DecIdct VP8TransformUV; 384 extern VP8DecIdct VP8TransformDC; 385 extern VP8DecIdct VP8TransformDCUV; 386 extern VP8WHT VP8TransformWHT; 387 388 // *dst is the destination block, with stride BPS. Boundary samples are 389 // assumed accessible when needed. 390 typedef void (*VP8PredFunc)(uint8_t* dst); 391 extern VP8PredFunc VP8PredLuma16[/* NUM_B_DC_MODES */]; 392 extern VP8PredFunc VP8PredChroma8[/* NUM_B_DC_MODES */]; 393 extern VP8PredFunc VP8PredLuma4[/* NUM_BMODES */]; 394 395 // clipping tables (for filtering) 396 extern const int8_t* const VP8ksclip1; // clips [-1020, 1020] to [-128, 127] 397 extern const int8_t* const VP8ksclip2; // clips [-112, 112] to [-16, 15] 398 extern const uint8_t* const VP8kclip1; // clips [-255,511] to [0,255] 399 extern const uint8_t* const VP8kabs0; // abs(x) for x in [-255,255] 400 // must be called first 401 void VP8InitClipTables(void); 402 403 // simple filter (only for luma) 404 typedef void (*VP8SimpleFilterFunc)(uint8_t* p, int stride, int thresh); 405 extern VP8SimpleFilterFunc VP8SimpleVFilter16; 406 extern VP8SimpleFilterFunc VP8SimpleHFilter16; 407 extern VP8SimpleFilterFunc VP8SimpleVFilter16i; // filter 3 inner edges 408 extern VP8SimpleFilterFunc VP8SimpleHFilter16i; 409 410 // regular filter (on both macroblock edges and inner edges) 411 typedef void (*VP8LumaFilterFunc)(uint8_t* luma, int stride, 412 int thresh, int ithresh, int hev_t); 413 typedef void (*VP8ChromaFilterFunc)(uint8_t* u, uint8_t* v, int stride, 414 int thresh, int ithresh, int hev_t); 415 // on outer edge 416 extern VP8LumaFilterFunc VP8VFilter16; 417 extern VP8LumaFilterFunc VP8HFilter16; 418 extern VP8ChromaFilterFunc VP8VFilter8; 419 extern VP8ChromaFilterFunc VP8HFilter8; 420 421 // on inner edge 422 extern VP8LumaFilterFunc VP8VFilter16i; // filtering 3 inner edges altogether 423 extern VP8LumaFilterFunc VP8HFilter16i; 424 extern VP8ChromaFilterFunc VP8VFilter8i; // filtering u and v altogether 425 extern VP8ChromaFilterFunc VP8HFilter8i; 426 427 // Dithering. Combines dithering values (centered around 128) with dst[], 428 // according to: dst[] = clip(dst[] + (((dither[]-128) + 8) >> 4) 429 #define VP8_DITHER_DESCALE 4 430 #define VP8_DITHER_DESCALE_ROUNDER (1 << (VP8_DITHER_DESCALE - 1)) 431 #define VP8_DITHER_AMP_BITS 7 432 #define VP8_DITHER_AMP_CENTER (1 << VP8_DITHER_AMP_BITS) 433 extern void (*VP8DitherCombine8x8)(const uint8_t* dither, uint8_t* dst, 434 int dst_stride); 435 436 // must be called before anything using the above 437 void VP8DspInit(void); 438 439 //------------------------------------------------------------------------------ 440 // WebP I/O 441 442 #define FANCY_UPSAMPLING // undefined to remove fancy upsampling support 443 444 // Convert a pair of y/u/v lines together to the output rgb/a colorspace. 445 // bottom_y can be NULL if only one line of output is needed (at top/bottom). 446 typedef void (*WebPUpsampleLinePairFunc)( 447 const uint8_t* top_y, const uint8_t* bottom_y, 448 const uint8_t* top_u, const uint8_t* top_v, 449 const uint8_t* cur_u, const uint8_t* cur_v, 450 uint8_t* top_dst, uint8_t* bottom_dst, int len); 451 452 #ifdef FANCY_UPSAMPLING 453 454 // Fancy upsampling functions to convert YUV to RGB(A) modes 455 extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */]; 456 457 #endif // FANCY_UPSAMPLING 458 459 // Per-row point-sampling methods. 460 typedef void (*WebPSamplerRowFunc)(const uint8_t* y, 461 const uint8_t* u, const uint8_t* v, 462 uint8_t* dst, int len); 463 // Generic function to apply 'WebPSamplerRowFunc' to the whole plane: 464 void WebPSamplerProcessPlane(const uint8_t* y, int y_stride, 465 const uint8_t* u, const uint8_t* v, int uv_stride, 466 uint8_t* dst, int dst_stride, 467 int width, int height, WebPSamplerRowFunc func); 468 469 // Sampling functions to convert rows of YUV to RGB(A) 470 extern WebPSamplerRowFunc WebPSamplers[/* MODE_LAST */]; 471 472 // General function for converting two lines of ARGB or RGBA. 473 // 'alpha_is_last' should be true if 0xff000000 is stored in memory as 474 // as 0x00, 0x00, 0x00, 0xff (little endian). 475 WebPUpsampleLinePairFunc WebPGetLinePairConverter(int alpha_is_last); 476 477 // YUV444->RGB converters 478 typedef void (*WebPYUV444Converter)(const uint8_t* y, 479 const uint8_t* u, const uint8_t* v, 480 uint8_t* dst, int len); 481 482 extern WebPYUV444Converter WebPYUV444Converters[/* MODE_LAST */]; 483 484 // Must be called before using the WebPUpsamplers[] (and for premultiplied 485 // colorspaces like rgbA, rgbA4444, etc) 486 void WebPInitUpsamplers(void); 487 // Must be called before using WebPSamplers[] 488 void WebPInitSamplers(void); 489 // Must be called before using WebPYUV444Converters[] 490 void WebPInitYUV444Converters(void); 491 492 //------------------------------------------------------------------------------ 493 // ARGB -> YUV converters 494 495 // Convert ARGB samples to luma Y. 496 extern void (*WebPConvertARGBToY)(const uint32_t* argb, uint8_t* y, int width); 497 // Convert ARGB samples to U/V with downsampling. do_store should be '1' for 498 // even lines and '0' for odd ones. 'src_width' is the original width, not 499 // the U/V one. 500 extern void (*WebPConvertARGBToUV)(const uint32_t* argb, uint8_t* u, uint8_t* v, 501 int src_width, int do_store); 502 503 // Convert a row of accumulated (four-values) of rgba32 toward U/V 504 extern void (*WebPConvertRGBA32ToUV)(const uint16_t* rgb, 505 uint8_t* u, uint8_t* v, int width); 506 507 // Convert RGB or BGR to Y 508 extern void (*WebPConvertRGB24ToY)(const uint8_t* rgb, uint8_t* y, int width); 509 extern void (*WebPConvertBGR24ToY)(const uint8_t* bgr, uint8_t* y, int width); 510 511 // used for plain-C fallback. 512 extern void WebPConvertARGBToUV_C(const uint32_t* argb, uint8_t* u, uint8_t* v, 513 int src_width, int do_store); 514 extern void WebPConvertRGBA32ToUV_C(const uint16_t* rgb, 515 uint8_t* u, uint8_t* v, int width); 516 517 // utilities for accurate RGB->YUV conversion 518 extern uint64_t (*WebPSharpYUVUpdateY)(const uint16_t* src, const uint16_t* ref, 519 uint16_t* dst, int len); 520 extern void (*WebPSharpYUVUpdateRGB)(const int16_t* src, const int16_t* ref, 521 int16_t* dst, int len); 522 extern void (*WebPSharpYUVFilterRow)(const int16_t* A, const int16_t* B, 523 int len, 524 const uint16_t* best_y, uint16_t* out); 525 526 // Must be called before using the above. 527 void WebPInitConvertARGBToYUV(void); 528 529 //------------------------------------------------------------------------------ 530 // Rescaler 531 532 struct WebPRescaler; 533 534 // Import a row of data and save its contribution in the rescaler. 535 // 'channel' denotes the channel number to be imported. 'Expand' corresponds to 536 // the wrk->x_expand case. Otherwise, 'Shrink' is to be used. 537 typedef void (*WebPRescalerImportRowFunc)(struct WebPRescaler* const wrk, 538 const uint8_t* src); 539 540 extern WebPRescalerImportRowFunc WebPRescalerImportRowExpand; 541 extern WebPRescalerImportRowFunc WebPRescalerImportRowShrink; 542 543 // Export one row (starting at x_out position) from rescaler. 544 // 'Expand' corresponds to the wrk->y_expand case. 545 // Otherwise 'Shrink' is to be used 546 typedef void (*WebPRescalerExportRowFunc)(struct WebPRescaler* const wrk); 547 extern WebPRescalerExportRowFunc WebPRescalerExportRowExpand; 548 extern WebPRescalerExportRowFunc WebPRescalerExportRowShrink; 549 550 // Plain-C implementation, as fall-back. 551 extern void WebPRescalerImportRowExpand_C(struct WebPRescaler* const wrk, 552 const uint8_t* src); 553 extern void WebPRescalerImportRowShrink_C(struct WebPRescaler* const wrk, 554 const uint8_t* src); 555 extern void WebPRescalerExportRowExpand_C(struct WebPRescaler* const wrk); 556 extern void WebPRescalerExportRowShrink_C(struct WebPRescaler* const wrk); 557 558 // Main entry calls: 559 extern void WebPRescalerImportRow(struct WebPRescaler* const wrk, 560 const uint8_t* src); 561 // Export one row (starting at x_out position) from rescaler. 562 extern void WebPRescalerExportRow(struct WebPRescaler* const wrk); 563 564 // Must be called first before using the above. 565 void WebPRescalerDspInit(void); 566 567 //------------------------------------------------------------------------------ 568 // Utilities for processing transparent channel. 569 570 // Apply alpha pre-multiply on an rgba, bgra or argb plane of size w * h. 571 // alpha_first should be 0 for argb, 1 for rgba or bgra (where alpha is last). 572 extern void (*WebPApplyAlphaMultiply)( 573 uint8_t* rgba, int alpha_first, int w, int h, int stride); 574 575 // Same, buf specifically for RGBA4444 format 576 extern void (*WebPApplyAlphaMultiply4444)( 577 uint8_t* rgba4444, int w, int h, int stride); 578 579 // Dispatch the values from alpha[] plane to the ARGB destination 'dst'. 580 // Returns true if alpha[] plane has non-trivial values different from 0xff. 581 extern int (*WebPDispatchAlpha)(const uint8_t* alpha, int alpha_stride, 582 int width, int height, 583 uint8_t* dst, int dst_stride); 584 585 // Transfer packed 8b alpha[] values to green channel in dst[], zero'ing the 586 // A/R/B values. 'dst_stride' is the stride for dst[] in uint32_t units. 587 extern void (*WebPDispatchAlphaToGreen)(const uint8_t* alpha, int alpha_stride, 588 int width, int height, 589 uint32_t* dst, int dst_stride); 590 591 // Extract the alpha values from 32b values in argb[] and pack them into alpha[] 592 // (this is the opposite of WebPDispatchAlpha). 593 // Returns true if there's only trivial 0xff alpha values. 594 extern int (*WebPExtractAlpha)(const uint8_t* argb, int argb_stride, 595 int width, int height, 596 uint8_t* alpha, int alpha_stride); 597 598 // Extract the green values from 32b values in argb[] and pack them into alpha[] 599 // (this is the opposite of WebPDispatchAlphaToGreen). 600 extern void (*WebPExtractGreen)(const uint32_t* argb, uint8_t* alpha, int size); 601 602 // Pre-Multiply operation transforms x into x * A / 255 (where x=Y,R,G or B). 603 // Un-Multiply operation transforms x into x * 255 / A. 604 605 // Pre-Multiply or Un-Multiply (if 'inverse' is true) argb values in a row. 606 extern void (*WebPMultARGBRow)(uint32_t* const ptr, int width, int inverse); 607 608 // Same a WebPMultARGBRow(), but for several rows. 609 void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows, 610 int inverse); 611 612 // Same for a row of single values, with side alpha values. 613 extern void (*WebPMultRow)(uint8_t* const ptr, const uint8_t* const alpha, 614 int width, int inverse); 615 616 // Same a WebPMultRow(), but for several 'num_rows' rows. 617 void WebPMultRows(uint8_t* ptr, int stride, 618 const uint8_t* alpha, int alpha_stride, 619 int width, int num_rows, int inverse); 620 621 // Plain-C versions, used as fallback by some implementations. 622 void WebPMultRow_C(uint8_t* const ptr, const uint8_t* const alpha, 623 int width, int inverse); 624 void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse); 625 626 #ifdef WORDS_BIGENDIAN 627 // ARGB packing function: a/r/g/b input is rgba or bgra order. 628 extern void (*WebPPackARGB)(const uint8_t* a, const uint8_t* r, 629 const uint8_t* g, const uint8_t* b, int len, 630 uint32_t* out); 631 #endif 632 633 // RGB packing function. 'step' can be 3 or 4. r/g/b input is rgb or bgr order. 634 extern void (*WebPPackRGB)(const uint8_t* r, const uint8_t* g, const uint8_t* b, 635 int len, int step, uint32_t* out); 636 637 // This function returns true if src[i] contains a value different from 0xff. 638 extern int (*WebPHasAlpha8b)(const uint8_t* src, int length); 639 // This function returns true if src[4*i] contains a value different from 0xff. 640 extern int (*WebPHasAlpha32b)(const uint8_t* src, int length); 641 // replaces transparent values in src[] by 'color'. 642 extern void (*WebPAlphaReplace)(uint32_t* src, int length, uint32_t color); 643 644 // To be called first before using the above. 645 void WebPInitAlphaProcessing(void); 646 647 //------------------------------------------------------------------------------ 648 // Filter functions 649 650 typedef enum { // Filter types. 651 WEBP_FILTER_NONE = 0, 652 WEBP_FILTER_HORIZONTAL, 653 WEBP_FILTER_VERTICAL, 654 WEBP_FILTER_GRADIENT, 655 WEBP_FILTER_LAST = WEBP_FILTER_GRADIENT + 1, // end marker 656 WEBP_FILTER_BEST, // meta-types 657 WEBP_FILTER_FAST 658 } WEBP_FILTER_TYPE; 659 660 typedef void (*WebPFilterFunc)(const uint8_t* in, int width, int height, 661 int stride, uint8_t* out); 662 // In-place un-filtering. 663 // Warning! 'prev_line' pointer can be equal to 'cur_line' or 'preds'. 664 typedef void (*WebPUnfilterFunc)(const uint8_t* prev_line, const uint8_t* preds, 665 uint8_t* cur_line, int width); 666 667 // Filter the given data using the given predictor. 668 // 'in' corresponds to a 2-dimensional pixel array of size (stride * height) 669 // in raster order. 670 // 'stride' is number of bytes per scan line (with possible padding). 671 // 'out' should be pre-allocated. 672 extern WebPFilterFunc WebPFilters[WEBP_FILTER_LAST]; 673 674 // In-place reconstruct the original data from the given filtered data. 675 // The reconstruction will be done for 'num_rows' rows starting from 'row' 676 // (assuming rows upto 'row - 1' are already reconstructed). 677 extern WebPUnfilterFunc WebPUnfilters[WEBP_FILTER_LAST]; 678 679 // To be called first before using the above. 680 void VP8FiltersInit(void); 681 682 #ifdef __cplusplus 683 } // extern "C" 684 #endif 685 686 #endif // WEBP_DSP_DSP_H_ 687