OLD | NEW |
1 // Copyright 2013 Google Inc. All Rights Reserved. | 1 // Copyright 2013 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Use of this source code is governed by a BSD-style license | 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 | 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 | 5 // tree. An additional intellectual property rights grant can be found |
6 // in the file PATENTS. All contributing project authors may | 6 // in the file PATENTS. All contributing project authors may |
7 // be found in the AUTHORS file in the root of the source tree. | 7 // be found in the AUTHORS file in the root of the source tree. |
8 // ----------------------------------------------------------------------------- | 8 // ----------------------------------------------------------------------------- |
9 // | 9 // |
10 // Utilities for processing transparent channel. | 10 // Utilities for processing transparent channel. |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 } | 127 } |
128 | 128 |
129 #else | 129 #else |
130 | 130 |
131 static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) { | 131 static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) { |
132 return inverse ? (255u << MFIX) / a : a * KINV_255; | 132 return inverse ? (255u << MFIX) / a : a * KINV_255; |
133 } | 133 } |
134 | 134 |
135 #endif // USE_TABLES_FOR_ALPHA_MULT | 135 #endif // USE_TABLES_FOR_ALPHA_MULT |
136 | 136 |
137 static void MultARGBRow(uint32_t* const ptr, int width, int inverse) { | 137 void WebPMultARGBRowC(uint32_t* const ptr, int width, int inverse) { |
138 int x; | 138 int x; |
139 for (x = 0; x < width; ++x) { | 139 for (x = 0; x < width; ++x) { |
140 const uint32_t argb = ptr[x]; | 140 const uint32_t argb = ptr[x]; |
141 if (argb < 0xff000000u) { // alpha < 255 | 141 if (argb < 0xff000000u) { // alpha < 255 |
142 if (argb <= 0x00ffffffu) { // alpha == 0 | 142 if (argb <= 0x00ffffffu) { // alpha == 0 |
143 ptr[x] = 0; | 143 ptr[x] = 0; |
144 } else { | 144 } else { |
145 const uint32_t alpha = (argb >> 24) & 0xff; | 145 const uint32_t alpha = (argb >> 24) & 0xff; |
146 const uint32_t scale = GetScale(alpha, inverse); | 146 const uint32_t scale = GetScale(alpha, inverse); |
147 uint32_t out = argb & 0xff000000u; | 147 uint32_t out = argb & 0xff000000u; |
148 out |= Mult(argb >> 0, scale) << 0; | 148 out |= Mult(argb >> 0, scale) << 0; |
149 out |= Mult(argb >> 8, scale) << 8; | 149 out |= Mult(argb >> 8, scale) << 8; |
150 out |= Mult(argb >> 16, scale) << 16; | 150 out |= Mult(argb >> 16, scale) << 16; |
151 ptr[x] = out; | 151 ptr[x] = out; |
152 } | 152 } |
153 } | 153 } |
154 } | 154 } |
155 } | 155 } |
156 | 156 |
157 static void MultRow(uint8_t* const ptr, const uint8_t* const alpha, | 157 void WebPMultRowC(uint8_t* const ptr, const uint8_t* const alpha, |
158 int width, int inverse) { | 158 int width, int inverse) { |
159 int x; | 159 int x; |
160 for (x = 0; x < width; ++x) { | 160 for (x = 0; x < width; ++x) { |
161 const uint32_t a = alpha[x]; | 161 const uint32_t a = alpha[x]; |
162 if (a != 255) { | 162 if (a != 255) { |
163 if (a == 0) { | 163 if (a == 0) { |
164 ptr[x] = 0; | 164 ptr[x] = 0; |
165 } else { | 165 } else { |
166 const uint32_t scale = GetScale(a, inverse); | 166 const uint32_t scale = GetScale(a, inverse); |
167 ptr[x] = Mult(ptr[x], scale); | 167 ptr[x] = Mult(ptr[x], scale); |
168 } | 168 } |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 | 277 |
278 static void ApplyAlphaMultiply_16b(uint8_t* rgba4444, | 278 static void ApplyAlphaMultiply_16b(uint8_t* rgba4444, |
279 int w, int h, int stride) { | 279 int w, int h, int stride) { |
280 #ifdef WEBP_SWAP_16BIT_CSP | 280 #ifdef WEBP_SWAP_16BIT_CSP |
281 ApplyAlphaMultiply4444(rgba4444, w, h, stride, 1); | 281 ApplyAlphaMultiply4444(rgba4444, w, h, stride, 1); |
282 #else | 282 #else |
283 ApplyAlphaMultiply4444(rgba4444, w, h, stride, 0); | 283 ApplyAlphaMultiply4444(rgba4444, w, h, stride, 0); |
284 #endif | 284 #endif |
285 } | 285 } |
286 | 286 |
| 287 static int DispatchAlpha(const uint8_t* alpha, int alpha_stride, |
| 288 int width, int height, |
| 289 uint8_t* dst, int dst_stride) { |
| 290 uint32_t alpha_mask = 0xff; |
| 291 int i, j; |
| 292 |
| 293 for (j = 0; j < height; ++j) { |
| 294 for (i = 0; i < width; ++i) { |
| 295 const uint32_t alpha_value = alpha[i]; |
| 296 dst[4 * i] = alpha_value; |
| 297 alpha_mask &= alpha_value; |
| 298 } |
| 299 alpha += alpha_stride; |
| 300 dst += dst_stride; |
| 301 } |
| 302 |
| 303 return (alpha_mask != 0xff); |
| 304 } |
| 305 |
| 306 static void DispatchAlphaToGreen(const uint8_t* alpha, int alpha_stride, |
| 307 int width, int height, |
| 308 uint32_t* dst, int dst_stride) { |
| 309 int i, j; |
| 310 for (j = 0; j < height; ++j) { |
| 311 for (i = 0; i < width; ++i) { |
| 312 dst[i] = alpha[i] << 8; // leave A/R/B channels zero'd. |
| 313 } |
| 314 alpha += alpha_stride; |
| 315 dst += dst_stride; |
| 316 } |
| 317 } |
| 318 |
287 static int ExtractAlpha(const uint8_t* argb, int argb_stride, | 319 static int ExtractAlpha(const uint8_t* argb, int argb_stride, |
288 int width, int height, | 320 int width, int height, |
289 uint8_t* alpha, int alpha_stride) { | 321 uint8_t* alpha, int alpha_stride) { |
290 uint8_t alpha_mask = 0xff; | 322 uint8_t alpha_mask = 0xff; |
291 int i, j; | 323 int i, j; |
292 | 324 |
293 for (j = 0; j < height; ++j) { | 325 for (j = 0; j < height; ++j) { |
294 for (i = 0; i < width; ++i) { | 326 for (i = 0; i < width; ++i) { |
295 const uint8_t alpha_value = argb[4 * i]; | 327 const uint8_t alpha_value = argb[4 * i]; |
296 alpha[i] = alpha_value; | 328 alpha[i] = alpha_value; |
297 alpha_mask &= alpha_value; | 329 alpha_mask &= alpha_value; |
298 } | 330 } |
299 argb += argb_stride; | 331 argb += argb_stride; |
300 alpha += alpha_stride; | 332 alpha += alpha_stride; |
301 } | 333 } |
302 return (alpha_mask == 0xff); | 334 return (alpha_mask == 0xff); |
303 } | 335 } |
304 | 336 |
305 void (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int); | 337 void (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int); |
306 void (*WebPApplyAlphaMultiply4444)(uint8_t*, int, int, int); | 338 void (*WebPApplyAlphaMultiply4444)(uint8_t*, int, int, int); |
| 339 int (*WebPDispatchAlpha)(const uint8_t*, int, int, int, uint8_t*, int); |
| 340 void (*WebPDispatchAlphaToGreen)(const uint8_t*, int, int, int, uint32_t*, int); |
307 int (*WebPExtractAlpha)(const uint8_t*, int, int, int, uint8_t*, int); | 341 int (*WebPExtractAlpha)(const uint8_t*, int, int, int, uint8_t*, int); |
308 | 342 |
309 //------------------------------------------------------------------------------ | 343 //------------------------------------------------------------------------------ |
310 // Init function | 344 // Init function |
311 | 345 |
| 346 extern void WebPInitAlphaProcessingMIPSdspR2(void); |
312 extern void WebPInitAlphaProcessingSSE2(void); | 347 extern void WebPInitAlphaProcessingSSE2(void); |
| 348 extern void WebPInitAlphaProcessingSSE41(void); |
313 | 349 |
314 static volatile VP8CPUInfo alpha_processing_last_cpuinfo_used = | 350 static volatile VP8CPUInfo alpha_processing_last_cpuinfo_used = |
315 (VP8CPUInfo)&alpha_processing_last_cpuinfo_used; | 351 (VP8CPUInfo)&alpha_processing_last_cpuinfo_used; |
316 | 352 |
317 void WebPInitAlphaProcessing(void) { | 353 WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessing(void) { |
318 if (alpha_processing_last_cpuinfo_used == VP8GetCPUInfo) return; | 354 if (alpha_processing_last_cpuinfo_used == VP8GetCPUInfo) return; |
319 | 355 |
320 WebPMultARGBRow = MultARGBRow; | 356 WebPMultARGBRow = WebPMultARGBRowC; |
321 WebPMultRow = MultRow; | 357 WebPMultRow = WebPMultRowC; |
322 WebPApplyAlphaMultiply = ApplyAlphaMultiply; | 358 WebPApplyAlphaMultiply = ApplyAlphaMultiply; |
323 WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b; | 359 WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b; |
| 360 WebPDispatchAlpha = DispatchAlpha; |
| 361 WebPDispatchAlphaToGreen = DispatchAlphaToGreen; |
324 WebPExtractAlpha = ExtractAlpha; | 362 WebPExtractAlpha = ExtractAlpha; |
325 | 363 |
326 // If defined, use CPUInfo() to overwrite some pointers with faster versions. | 364 // If defined, use CPUInfo() to overwrite some pointers with faster versions. |
327 if (VP8GetCPUInfo != NULL) { | 365 if (VP8GetCPUInfo != NULL) { |
328 #if defined(WEBP_USE_SSE2) | 366 #if defined(WEBP_USE_SSE2) |
329 if (VP8GetCPUInfo(kSSE2)) { | 367 if (VP8GetCPUInfo(kSSE2)) { |
330 WebPInitAlphaProcessingSSE2(); | 368 WebPInitAlphaProcessingSSE2(); |
| 369 #if defined(WEBP_USE_SSE41) |
| 370 if (VP8GetCPUInfo(kSSE4_1)) { |
| 371 WebPInitAlphaProcessingSSE41(); |
| 372 } |
| 373 #endif |
| 374 } |
| 375 #endif |
| 376 #if defined(WEBP_USE_MIPS_DSP_R2) |
| 377 if (VP8GetCPUInfo(kMIPSdspR2)) { |
| 378 WebPInitAlphaProcessingMIPSdspR2(); |
331 } | 379 } |
332 #endif | 380 #endif |
333 } | 381 } |
334 alpha_processing_last_cpuinfo_used = VP8GetCPUInfo; | 382 alpha_processing_last_cpuinfo_used = VP8GetCPUInfo; |
335 } | 383 } |
OLD | NEW |