alpha_processing.c (19532B)
1 // Copyright 2013 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 // Utilities for processing transparent channel. 11 // 12 // Author: Skal (pascal.massimino@gmail.com) 13 14 #include <assert.h> 15 #include <stddef.h> 16 17 #include "src/dsp/cpu.h" 18 #include "src/dsp/dsp.h" 19 #include "src/webp/types.h" 20 21 // Tables can be faster on some platform but incur some extra binary size (~2k). 22 #if !defined(USE_TABLES_FOR_ALPHA_MULT) 23 #define USE_TABLES_FOR_ALPHA_MULT 0 // ALTERNATE_CODE 24 #endif 25 26 27 // ----------------------------------------------------------------------------- 28 29 #define MFIX 24 // 24bit fixed-point arithmetic 30 #define HALF ((1u << MFIX) >> 1) 31 #define KINV_255 ((1u << MFIX) / 255u) 32 33 static uint32_t Mult(uint8_t x, uint32_t mult) { 34 const uint32_t v = (x * mult + HALF) >> MFIX; 35 assert(v <= 255); // <- 24bit precision is enough to ensure that. 36 return v; 37 } 38 39 #if (USE_TABLES_FOR_ALPHA_MULT == 1) 40 41 static const uint32_t kMultTables[2][256] = { 42 { // (255u << MFIX) / alpha 43 0x00000000, 0xff000000, 0x7f800000, 0x55000000, 0x3fc00000, 0x33000000, 44 0x2a800000, 0x246db6db, 0x1fe00000, 0x1c555555, 0x19800000, 0x172e8ba2, 45 0x15400000, 0x139d89d8, 0x1236db6d, 0x11000000, 0x0ff00000, 0x0f000000, 46 0x0e2aaaaa, 0x0d6bca1a, 0x0cc00000, 0x0c249249, 0x0b9745d1, 0x0b1642c8, 47 0x0aa00000, 0x0a333333, 0x09cec4ec, 0x0971c71c, 0x091b6db6, 0x08cb08d3, 48 0x08800000, 0x0839ce73, 0x07f80000, 0x07ba2e8b, 0x07800000, 0x07492492, 49 0x07155555, 0x06e45306, 0x06b5e50d, 0x0689d89d, 0x06600000, 0x063831f3, 50 0x06124924, 0x05ee23b8, 0x05cba2e8, 0x05aaaaaa, 0x058b2164, 0x056cefa8, 51 0x05500000, 0x05343eb1, 0x05199999, 0x05000000, 0x04e76276, 0x04cfb2b7, 52 0x04b8e38e, 0x04a2e8ba, 0x048db6db, 0x0479435e, 0x04658469, 0x045270d0, 53 0x04400000, 0x042e29f7, 0x041ce739, 0x040c30c3, 0x03fc0000, 0x03ec4ec4, 54 0x03dd1745, 0x03ce540f, 0x03c00000, 0x03b21642, 0x03a49249, 0x03976fc6, 55 0x038aaaaa, 0x037e3f1f, 0x03722983, 0x03666666, 0x035af286, 0x034fcace, 56 0x0344ec4e, 0x033a5440, 0x03300000, 0x0325ed09, 0x031c18f9, 0x0312818a, 57 0x03092492, 0x03000000, 0x02f711dc, 0x02ee5846, 0x02e5d174, 0x02dd7baf, 58 0x02d55555, 0x02cd5cd5, 0x02c590b2, 0x02bdef7b, 0x02b677d4, 0x02af286b, 59 0x02a80000, 0x02a0fd5c, 0x029a1f58, 0x029364d9, 0x028ccccc, 0x0286562d, 60 0x02800000, 0x0279c952, 0x0273b13b, 0x026db6db, 0x0267d95b, 0x026217ec, 61 0x025c71c7, 0x0256e62a, 0x0251745d, 0x024c1bac, 0x0246db6d, 0x0241b2f9, 62 0x023ca1af, 0x0237a6f4, 0x0232c234, 0x022df2df, 0x02293868, 0x02249249, 63 0x02200000, 0x021b810e, 0x021714fb, 0x0212bb51, 0x020e739c, 0x020a3d70, 64 0x02061861, 0x02020408, 0x01fe0000, 0x01fa0be8, 0x01f62762, 0x01f25213, 65 0x01ee8ba2, 0x01ead3ba, 0x01e72a07, 0x01e38e38, 0x01e00000, 0x01dc7f10, 66 0x01d90b21, 0x01d5a3e9, 0x01d24924, 0x01cefa8d, 0x01cbb7e3, 0x01c880e5, 67 0x01c55555, 0x01c234f7, 0x01bf1f8f, 0x01bc14e5, 0x01b914c1, 0x01b61eed, 68 0x01b33333, 0x01b05160, 0x01ad7943, 0x01aaaaaa, 0x01a7e567, 0x01a5294a, 69 0x01a27627, 0x019fcbd2, 0x019d2a20, 0x019a90e7, 0x01980000, 0x01957741, 70 0x0192f684, 0x01907da4, 0x018e0c7c, 0x018ba2e8, 0x018940c5, 0x0186e5f0, 71 0x01849249, 0x018245ae, 0x01800000, 0x017dc11f, 0x017b88ee, 0x0179574e, 72 0x01772c23, 0x01750750, 0x0172e8ba, 0x0170d045, 0x016ebdd7, 0x016cb157, 73 0x016aaaaa, 0x0168a9b9, 0x0166ae6a, 0x0164b8a7, 0x0162c859, 0x0160dd67, 74 0x015ef7bd, 0x015d1745, 0x015b3bea, 0x01596596, 0x01579435, 0x0155c7b4, 75 0x01540000, 0x01523d03, 0x01507eae, 0x014ec4ec, 0x014d0fac, 0x014b5edc, 76 0x0149b26c, 0x01480a4a, 0x01466666, 0x0144c6af, 0x01432b16, 0x0141938b, 77 0x01400000, 0x013e7063, 0x013ce4a9, 0x013b5cc0, 0x0139d89d, 0x01385830, 78 0x0136db6d, 0x01356246, 0x0133ecad, 0x01327a97, 0x01310bf6, 0x012fa0be, 79 0x012e38e3, 0x012cd459, 0x012b7315, 0x012a150a, 0x0128ba2e, 0x01276276, 80 0x01260dd6, 0x0124bc44, 0x01236db6, 0x01222222, 0x0120d97c, 0x011f93bc, 81 0x011e50d7, 0x011d10c4, 0x011bd37a, 0x011a98ef, 0x0119611a, 0x01182bf2, 82 0x0116f96f, 0x0115c988, 0x01149c34, 0x0113716a, 0x01124924, 0x01112358, 83 0x01100000, 0x010edf12, 0x010dc087, 0x010ca458, 0x010b8a7d, 0x010a72f0, 84 0x01095da8, 0x01084a9f, 0x010739ce, 0x01062b2e, 0x01051eb8, 0x01041465, 85 0x01030c30, 0x01020612, 0x01010204, 0x01000000 }, 86 { // alpha * KINV_255 87 0x00000000, 0x00010101, 0x00020202, 0x00030303, 0x00040404, 0x00050505, 88 0x00060606, 0x00070707, 0x00080808, 0x00090909, 0x000a0a0a, 0x000b0b0b, 89 0x000c0c0c, 0x000d0d0d, 0x000e0e0e, 0x000f0f0f, 0x00101010, 0x00111111, 90 0x00121212, 0x00131313, 0x00141414, 0x00151515, 0x00161616, 0x00171717, 91 0x00181818, 0x00191919, 0x001a1a1a, 0x001b1b1b, 0x001c1c1c, 0x001d1d1d, 92 0x001e1e1e, 0x001f1f1f, 0x00202020, 0x00212121, 0x00222222, 0x00232323, 93 0x00242424, 0x00252525, 0x00262626, 0x00272727, 0x00282828, 0x00292929, 94 0x002a2a2a, 0x002b2b2b, 0x002c2c2c, 0x002d2d2d, 0x002e2e2e, 0x002f2f2f, 95 0x00303030, 0x00313131, 0x00323232, 0x00333333, 0x00343434, 0x00353535, 96 0x00363636, 0x00373737, 0x00383838, 0x00393939, 0x003a3a3a, 0x003b3b3b, 97 0x003c3c3c, 0x003d3d3d, 0x003e3e3e, 0x003f3f3f, 0x00404040, 0x00414141, 98 0x00424242, 0x00434343, 0x00444444, 0x00454545, 0x00464646, 0x00474747, 99 0x00484848, 0x00494949, 0x004a4a4a, 0x004b4b4b, 0x004c4c4c, 0x004d4d4d, 100 0x004e4e4e, 0x004f4f4f, 0x00505050, 0x00515151, 0x00525252, 0x00535353, 101 0x00545454, 0x00555555, 0x00565656, 0x00575757, 0x00585858, 0x00595959, 102 0x005a5a5a, 0x005b5b5b, 0x005c5c5c, 0x005d5d5d, 0x005e5e5e, 0x005f5f5f, 103 0x00606060, 0x00616161, 0x00626262, 0x00636363, 0x00646464, 0x00656565, 104 0x00666666, 0x00676767, 0x00686868, 0x00696969, 0x006a6a6a, 0x006b6b6b, 105 0x006c6c6c, 0x006d6d6d, 0x006e6e6e, 0x006f6f6f, 0x00707070, 0x00717171, 106 0x00727272, 0x00737373, 0x00747474, 0x00757575, 0x00767676, 0x00777777, 107 0x00787878, 0x00797979, 0x007a7a7a, 0x007b7b7b, 0x007c7c7c, 0x007d7d7d, 108 0x007e7e7e, 0x007f7f7f, 0x00808080, 0x00818181, 0x00828282, 0x00838383, 109 0x00848484, 0x00858585, 0x00868686, 0x00878787, 0x00888888, 0x00898989, 110 0x008a8a8a, 0x008b8b8b, 0x008c8c8c, 0x008d8d8d, 0x008e8e8e, 0x008f8f8f, 111 0x00909090, 0x00919191, 0x00929292, 0x00939393, 0x00949494, 0x00959595, 112 0x00969696, 0x00979797, 0x00989898, 0x00999999, 0x009a9a9a, 0x009b9b9b, 113 0x009c9c9c, 0x009d9d9d, 0x009e9e9e, 0x009f9f9f, 0x00a0a0a0, 0x00a1a1a1, 114 0x00a2a2a2, 0x00a3a3a3, 0x00a4a4a4, 0x00a5a5a5, 0x00a6a6a6, 0x00a7a7a7, 115 0x00a8a8a8, 0x00a9a9a9, 0x00aaaaaa, 0x00ababab, 0x00acacac, 0x00adadad, 116 0x00aeaeae, 0x00afafaf, 0x00b0b0b0, 0x00b1b1b1, 0x00b2b2b2, 0x00b3b3b3, 117 0x00b4b4b4, 0x00b5b5b5, 0x00b6b6b6, 0x00b7b7b7, 0x00b8b8b8, 0x00b9b9b9, 118 0x00bababa, 0x00bbbbbb, 0x00bcbcbc, 0x00bdbdbd, 0x00bebebe, 0x00bfbfbf, 119 0x00c0c0c0, 0x00c1c1c1, 0x00c2c2c2, 0x00c3c3c3, 0x00c4c4c4, 0x00c5c5c5, 120 0x00c6c6c6, 0x00c7c7c7, 0x00c8c8c8, 0x00c9c9c9, 0x00cacaca, 0x00cbcbcb, 121 0x00cccccc, 0x00cdcdcd, 0x00cecece, 0x00cfcfcf, 0x00d0d0d0, 0x00d1d1d1, 122 0x00d2d2d2, 0x00d3d3d3, 0x00d4d4d4, 0x00d5d5d5, 0x00d6d6d6, 0x00d7d7d7, 123 0x00d8d8d8, 0x00d9d9d9, 0x00dadada, 0x00dbdbdb, 0x00dcdcdc, 0x00dddddd, 124 0x00dedede, 0x00dfdfdf, 0x00e0e0e0, 0x00e1e1e1, 0x00e2e2e2, 0x00e3e3e3, 125 0x00e4e4e4, 0x00e5e5e5, 0x00e6e6e6, 0x00e7e7e7, 0x00e8e8e8, 0x00e9e9e9, 126 0x00eaeaea, 0x00ebebeb, 0x00ececec, 0x00ededed, 0x00eeeeee, 0x00efefef, 127 0x00f0f0f0, 0x00f1f1f1, 0x00f2f2f2, 0x00f3f3f3, 0x00f4f4f4, 0x00f5f5f5, 128 0x00f6f6f6, 0x00f7f7f7, 0x00f8f8f8, 0x00f9f9f9, 0x00fafafa, 0x00fbfbfb, 129 0x00fcfcfc, 0x00fdfdfd, 0x00fefefe, 0x00ffffff } 130 }; 131 132 static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) { 133 return kMultTables[!inverse][a]; 134 } 135 136 #else 137 138 static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) { 139 return inverse ? (255u << MFIX) / a : a * KINV_255; 140 } 141 142 #endif // USE_TABLES_FOR_ALPHA_MULT 143 144 void WebPMultARGBRow_C(uint32_t* const ptr, int width, int inverse) { 145 int x; 146 for (x = 0; x < width; ++x) { 147 const uint32_t argb = ptr[x]; 148 if (argb < 0xff000000u) { // alpha < 255 149 if (argb <= 0x00ffffffu) { // alpha == 0 150 ptr[x] = 0; 151 } else { 152 const uint32_t alpha = (argb >> 24) & 0xff; 153 const uint32_t scale = GetScale(alpha, inverse); 154 uint32_t out = argb & 0xff000000u; 155 out |= Mult(argb >> 0, scale) << 0; 156 out |= Mult(argb >> 8, scale) << 8; 157 out |= Mult(argb >> 16, scale) << 16; 158 ptr[x] = out; 159 } 160 } 161 } 162 } 163 164 void WebPMultRow_C(uint8_t* WEBP_RESTRICT const ptr, 165 const uint8_t* WEBP_RESTRICT const alpha, 166 int width, int inverse) { 167 int x; 168 for (x = 0; x < width; ++x) { 169 const uint32_t a = alpha[x]; 170 if (a != 255) { 171 if (a == 0) { 172 ptr[x] = 0; 173 } else { 174 const uint32_t scale = GetScale(a, inverse); 175 ptr[x] = Mult(ptr[x], scale); 176 } 177 } 178 } 179 } 180 181 #undef KINV_255 182 #undef HALF 183 #undef MFIX 184 185 void (*WebPMultARGBRow)(uint32_t* const ptr, int width, int inverse); 186 void (*WebPMultRow)(uint8_t* WEBP_RESTRICT const ptr, 187 const uint8_t* WEBP_RESTRICT const alpha, 188 int width, int inverse); 189 190 //------------------------------------------------------------------------------ 191 // Generic per-plane calls 192 193 void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows, 194 int inverse) { 195 int n; 196 for (n = 0; n < num_rows; ++n) { 197 WebPMultARGBRow((uint32_t*)ptr, width, inverse); 198 ptr += stride; 199 } 200 } 201 202 void WebPMultRows(uint8_t* WEBP_RESTRICT ptr, int stride, 203 const uint8_t* WEBP_RESTRICT alpha, int alpha_stride, 204 int width, int num_rows, int inverse) { 205 int n; 206 for (n = 0; n < num_rows; ++n) { 207 WebPMultRow(ptr, alpha, width, inverse); 208 ptr += stride; 209 alpha += alpha_stride; 210 } 211 } 212 213 //------------------------------------------------------------------------------ 214 // Premultiplied modes 215 216 // non dithered-modes 217 218 // (x * a * 32897) >> 23 is bit-wise equivalent to (int)(x * a / 255.) 219 // for all 8bit x or a. For bit-wise equivalence to (int)(x * a / 255. + .5), 220 // one can use instead: (x * a * 65793 + (1 << 23)) >> 24 221 #if 1 // (int)(x * a / 255.) 222 #define MULTIPLIER(a) ((a) * 32897U) 223 #define PREMULTIPLY(x, m) (((x) * (m)) >> 23) 224 #else // (int)(x * a / 255. + .5) 225 #define MULTIPLIER(a) ((a) * 65793U) 226 #define PREMULTIPLY(x, m) (((x) * (m) + (1U << 23)) >> 24) 227 #endif 228 229 #if !WEBP_NEON_OMIT_C_CODE 230 static void ApplyAlphaMultiply_C(uint8_t* rgba, int alpha_first, 231 int w, int h, int stride) { 232 while (h-- > 0) { 233 uint8_t* const rgb = rgba + (alpha_first ? 1 : 0); 234 const uint8_t* const alpha = rgba + (alpha_first ? 0 : 3); 235 int i; 236 for (i = 0; i < w; ++i) { 237 const uint32_t a = alpha[4 * i]; 238 if (a != 0xff) { 239 const uint32_t mult = MULTIPLIER(a); 240 rgb[4 * i + 0] = PREMULTIPLY(rgb[4 * i + 0], mult); 241 rgb[4 * i + 1] = PREMULTIPLY(rgb[4 * i + 1], mult); 242 rgb[4 * i + 2] = PREMULTIPLY(rgb[4 * i + 2], mult); 243 } 244 } 245 rgba += stride; 246 } 247 } 248 #endif // !WEBP_NEON_OMIT_C_CODE 249 #undef MULTIPLIER 250 #undef PREMULTIPLY 251 252 // rgbA4444 253 254 #define MULTIPLIER(a) ((a) * 0x1111) // 0x1111 ~= (1 << 16) / 15 255 256 static WEBP_INLINE uint8_t dither_hi(uint8_t x) { 257 return (x & 0xf0) | (x >> 4); 258 } 259 260 static WEBP_INLINE uint8_t dither_lo(uint8_t x) { 261 return (x & 0x0f) | (x << 4); 262 } 263 264 static WEBP_INLINE uint8_t multiply(uint8_t x, uint32_t m) { 265 return (x * m) >> 16; 266 } 267 268 static WEBP_INLINE void ApplyAlphaMultiply4444_C(uint8_t* rgba4444, 269 int w, int h, int stride, 270 int rg_byte_pos /* 0 or 1 */) { 271 while (h-- > 0) { 272 int i; 273 for (i = 0; i < w; ++i) { 274 const uint32_t rg = rgba4444[2 * i + rg_byte_pos]; 275 const uint32_t ba = rgba4444[2 * i + (rg_byte_pos ^ 1)]; 276 const uint8_t a = ba & 0x0f; 277 const uint32_t mult = MULTIPLIER(a); 278 const uint8_t r = multiply(dither_hi(rg), mult); 279 const uint8_t g = multiply(dither_lo(rg), mult); 280 const uint8_t b = multiply(dither_hi(ba), mult); 281 rgba4444[2 * i + rg_byte_pos] = (r & 0xf0) | ((g >> 4) & 0x0f); 282 rgba4444[2 * i + (rg_byte_pos ^ 1)] = (b & 0xf0) | a; 283 } 284 rgba4444 += stride; 285 } 286 } 287 #undef MULTIPLIER 288 289 static void ApplyAlphaMultiply_16b_C(uint8_t* rgba4444, 290 int w, int h, int stride) { 291 #if (WEBP_SWAP_16BIT_CSP == 1) 292 ApplyAlphaMultiply4444_C(rgba4444, w, h, stride, 1); 293 #else 294 ApplyAlphaMultiply4444_C(rgba4444, w, h, stride, 0); 295 #endif 296 } 297 298 #if !WEBP_NEON_OMIT_C_CODE 299 static int DispatchAlpha_C(const uint8_t* WEBP_RESTRICT alpha, int alpha_stride, 300 int width, int height, 301 uint8_t* WEBP_RESTRICT dst, int dst_stride) { 302 uint32_t alpha_mask = 0xff; 303 int i, j; 304 305 for (j = 0; j < height; ++j) { 306 for (i = 0; i < width; ++i) { 307 const uint32_t alpha_value = alpha[i]; 308 dst[4 * i] = alpha_value; 309 alpha_mask &= alpha_value; 310 } 311 alpha += alpha_stride; 312 dst += dst_stride; 313 } 314 315 return (alpha_mask != 0xff); 316 } 317 318 static void DispatchAlphaToGreen_C(const uint8_t* WEBP_RESTRICT alpha, 319 int alpha_stride, int width, int height, 320 uint32_t* WEBP_RESTRICT dst, 321 int dst_stride) { 322 int i, j; 323 for (j = 0; j < height; ++j) { 324 for (i = 0; i < width; ++i) { 325 dst[i] = alpha[i] << 8; // leave A/R/B channels zero'd. 326 } 327 alpha += alpha_stride; 328 dst += dst_stride; 329 } 330 } 331 332 static int ExtractAlpha_C(const uint8_t* WEBP_RESTRICT argb, int argb_stride, 333 int width, int height, 334 uint8_t* WEBP_RESTRICT alpha, int alpha_stride) { 335 uint8_t alpha_mask = 0xff; 336 int i, j; 337 338 for (j = 0; j < height; ++j) { 339 for (i = 0; i < width; ++i) { 340 const uint8_t alpha_value = argb[4 * i]; 341 alpha[i] = alpha_value; 342 alpha_mask &= alpha_value; 343 } 344 argb += argb_stride; 345 alpha += alpha_stride; 346 } 347 return (alpha_mask == 0xff); 348 } 349 350 static void ExtractGreen_C(const uint32_t* WEBP_RESTRICT argb, 351 uint8_t* WEBP_RESTRICT alpha, int size) { 352 int i; 353 for (i = 0; i < size; ++i) alpha[i] = argb[i] >> 8; 354 } 355 #endif // !WEBP_NEON_OMIT_C_CODE 356 357 //------------------------------------------------------------------------------ 358 359 static int HasAlpha8b_C(const uint8_t* src, int length) { 360 while (length-- > 0) if (*src++ != 0xff) return 1; 361 return 0; 362 } 363 364 static int HasAlpha32b_C(const uint8_t* src, int length) { 365 int x; 366 for (x = 0; length-- > 0; x += 4) if (src[x] != 0xff) return 1; 367 return 0; 368 } 369 370 static void AlphaReplace_C(uint32_t* src, int length, uint32_t color) { 371 int x; 372 for (x = 0; x < length; ++x) if ((src[x] >> 24) == 0) src[x] = color; 373 } 374 375 //------------------------------------------------------------------------------ 376 // Simple channel manipulations. 377 378 static WEBP_INLINE uint32_t MakeARGB32(int a, int r, int g, int b) { 379 return (((uint32_t)a << 24) | (r << 16) | (g << 8) | b); 380 } 381 382 #ifdef WORDS_BIGENDIAN 383 static void PackARGB_C(const uint8_t* WEBP_RESTRICT a, 384 const uint8_t* WEBP_RESTRICT r, 385 const uint8_t* WEBP_RESTRICT g, 386 const uint8_t* WEBP_RESTRICT b, 387 int len, uint32_t* WEBP_RESTRICT out) { 388 int i; 389 for (i = 0; i < len; ++i) { 390 out[i] = MakeARGB32(a[4 * i], r[4 * i], g[4 * i], b[4 * i]); 391 } 392 } 393 #endif 394 395 static void PackRGB_C(const uint8_t* WEBP_RESTRICT r, 396 const uint8_t* WEBP_RESTRICT g, 397 const uint8_t* WEBP_RESTRICT b, 398 int len, int step, uint32_t* WEBP_RESTRICT out) { 399 int i, offset = 0; 400 for (i = 0; i < len; ++i) { 401 out[i] = MakeARGB32(0xff, r[offset], g[offset], b[offset]); 402 offset += step; 403 } 404 } 405 406 void (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int); 407 void (*WebPApplyAlphaMultiply4444)(uint8_t*, int, int, int); 408 int (*WebPDispatchAlpha)(const uint8_t* WEBP_RESTRICT, int, int, int, 409 uint8_t* WEBP_RESTRICT, int); 410 void (*WebPDispatchAlphaToGreen)(const uint8_t* WEBP_RESTRICT, int, int, int, 411 uint32_t* WEBP_RESTRICT, int); 412 int (*WebPExtractAlpha)(const uint8_t* WEBP_RESTRICT, int, int, int, 413 uint8_t* WEBP_RESTRICT, int); 414 void (*WebPExtractGreen)(const uint32_t* WEBP_RESTRICT argb, 415 uint8_t* WEBP_RESTRICT alpha, int size); 416 #ifdef WORDS_BIGENDIAN 417 void (*WebPPackARGB)(const uint8_t* a, const uint8_t* r, const uint8_t* g, 418 const uint8_t* b, int, uint32_t*); 419 #endif 420 void (*WebPPackRGB)(const uint8_t* WEBP_RESTRICT r, 421 const uint8_t* WEBP_RESTRICT g, 422 const uint8_t* WEBP_RESTRICT b, 423 int len, int step, uint32_t* WEBP_RESTRICT out); 424 425 int (*WebPHasAlpha8b)(const uint8_t* src, int length); 426 int (*WebPHasAlpha32b)(const uint8_t* src, int length); 427 void (*WebPAlphaReplace)(uint32_t* src, int length, uint32_t color); 428 429 //------------------------------------------------------------------------------ 430 // Init function 431 432 extern VP8CPUInfo VP8GetCPUInfo; 433 extern void WebPInitAlphaProcessingMIPSdspR2(void); 434 extern void WebPInitAlphaProcessingSSE2(void); 435 extern void WebPInitAlphaProcessingSSE41(void); 436 extern void WebPInitAlphaProcessingNEON(void); 437 438 WEBP_DSP_INIT_FUNC(WebPInitAlphaProcessing) { 439 WebPMultARGBRow = WebPMultARGBRow_C; 440 WebPMultRow = WebPMultRow_C; 441 WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b_C; 442 443 #ifdef WORDS_BIGENDIAN 444 WebPPackARGB = PackARGB_C; 445 #endif 446 WebPPackRGB = PackRGB_C; 447 #if !WEBP_NEON_OMIT_C_CODE 448 WebPApplyAlphaMultiply = ApplyAlphaMultiply_C; 449 WebPDispatchAlpha = DispatchAlpha_C; 450 WebPDispatchAlphaToGreen = DispatchAlphaToGreen_C; 451 WebPExtractAlpha = ExtractAlpha_C; 452 WebPExtractGreen = ExtractGreen_C; 453 #endif 454 455 WebPHasAlpha8b = HasAlpha8b_C; 456 WebPHasAlpha32b = HasAlpha32b_C; 457 WebPAlphaReplace = AlphaReplace_C; 458 459 // If defined, use CPUInfo() to overwrite some pointers with faster versions. 460 if (VP8GetCPUInfo != NULL) { 461 #if defined(WEBP_HAVE_SSE2) 462 if (VP8GetCPUInfo(kSSE2)) { 463 WebPInitAlphaProcessingSSE2(); 464 #if defined(WEBP_HAVE_SSE41) 465 if (VP8GetCPUInfo(kSSE4_1)) { 466 WebPInitAlphaProcessingSSE41(); 467 } 468 #endif 469 } 470 #endif 471 #if defined(WEBP_USE_MIPS_DSP_R2) 472 if (VP8GetCPUInfo(kMIPSdspR2)) { 473 WebPInitAlphaProcessingMIPSdspR2(); 474 } 475 #endif 476 } 477 478 #if defined(WEBP_HAVE_NEON) 479 if (WEBP_NEON_OMIT_C_CODE || 480 (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) { 481 WebPInitAlphaProcessingNEON(); 482 } 483 #endif 484 485 assert(WebPMultARGBRow != NULL); 486 assert(WebPMultRow != NULL); 487 assert(WebPApplyAlphaMultiply != NULL); 488 assert(WebPApplyAlphaMultiply4444 != NULL); 489 assert(WebPDispatchAlpha != NULL); 490 assert(WebPDispatchAlphaToGreen != NULL); 491 assert(WebPExtractAlpha != NULL); 492 assert(WebPExtractGreen != NULL); 493 #ifdef WORDS_BIGENDIAN 494 assert(WebPPackARGB != NULL); 495 #endif 496 assert(WebPPackRGB != NULL); 497 assert(WebPHasAlpha8b != NULL); 498 assert(WebPHasAlpha32b != NULL); 499 assert(WebPAlphaReplace != NULL); 500 }