| OLD | NEW |
| 1 // Copyright 2010 Google Inc. All Rights Reserved. | 1 // Copyright 2010 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 // YUV->RGB conversion functions | 10 // YUV->RGB conversion functions |
| 11 // | 11 // |
| 12 // Author: Skal (pascal.massimino@gmail.com) | 12 // Author: Skal (pascal.massimino@gmail.com) |
| 13 | 13 |
| 14 #include "./yuv.h" | 14 #include "./yuv.h" |
| 15 | 15 |
| 16 #include <stdlib.h> |
| 17 |
| 16 #if defined(WEBP_YUV_USE_TABLE) | 18 #if defined(WEBP_YUV_USE_TABLE) |
| 17 | 19 |
| 18 static int done = 0; | 20 static int done = 0; |
| 19 | 21 |
| 20 static WEBP_INLINE uint8_t clip(int v, int max_value) { | 22 static WEBP_INLINE uint8_t clip(int v, int max_value) { |
| 21 return v < 0 ? 0 : v > max_value ? max_value : v; | 23 return v < 0 ? 0 : v > max_value ? max_value : v; |
| 22 } | 24 } |
| 23 | 25 |
| 24 int16_t VP8kVToR[256], VP8kUToB[256]; | 26 int16_t VP8kVToR[256], VP8kUToB[256]; |
| 25 int32_t VP8kVToG[256], VP8kUToG[256]; | 27 int32_t VP8kVToG[256], VP8kUToG[256]; |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 int i; | 239 int i; |
| 238 for (i = 0; i < width; i += 1, rgb += 4) { | 240 for (i = 0; i < width; i += 1, rgb += 4) { |
| 239 const int r = rgb[0], g = rgb[1], b = rgb[2]; | 241 const int r = rgb[0], g = rgb[1], b = rgb[2]; |
| 240 u[i] = VP8RGBToU(r, g, b, YUV_HALF << 2); | 242 u[i] = VP8RGBToU(r, g, b, YUV_HALF << 2); |
| 241 v[i] = VP8RGBToV(r, g, b, YUV_HALF << 2); | 243 v[i] = VP8RGBToV(r, g, b, YUV_HALF << 2); |
| 242 } | 244 } |
| 243 } | 245 } |
| 244 | 246 |
| 245 //----------------------------------------------------------------------------- | 247 //----------------------------------------------------------------------------- |
| 246 | 248 |
| 249 #define MAX_Y ((1 << 10) - 1) // 10b precision over 16b-arithmetic |
| 250 static uint16_t clip_y(int v) { |
| 251 return (v < 0) ? 0 : (v > MAX_Y) ? MAX_Y : (uint16_t)v; |
| 252 } |
| 253 |
| 254 static uint64_t SharpYUVUpdateY_C(const uint16_t* ref, const uint16_t* src, |
| 255 uint16_t* dst, int len) { |
| 256 uint64_t diff = 0; |
| 257 int i; |
| 258 for (i = 0; i < len; ++i) { |
| 259 const int diff_y = ref[i] - src[i]; |
| 260 const int new_y = (int)dst[i] + diff_y; |
| 261 dst[i] = clip_y(new_y); |
| 262 diff += (uint64_t)abs(diff_y); |
| 263 } |
| 264 return diff; |
| 265 } |
| 266 |
| 267 static void SharpYUVUpdateRGB_C(const int16_t* ref, const int16_t* src, |
| 268 int16_t* dst, int len) { |
| 269 int i; |
| 270 for (i = 0; i < len; ++i) { |
| 271 const int diff_uv = ref[i] - src[i]; |
| 272 dst[i] += diff_uv; |
| 273 } |
| 274 } |
| 275 |
| 276 static void SharpYUVFilterRow_C(const int16_t* A, const int16_t* B, int len, |
| 277 const uint16_t* best_y, uint16_t* out) { |
| 278 int i; |
| 279 for (i = 0; i < len; ++i, ++A, ++B) { |
| 280 const int v0 = (A[0] * 9 + A[1] * 3 + B[0] * 3 + B[1] + 8) >> 4; |
| 281 const int v1 = (A[1] * 9 + A[0] * 3 + B[1] * 3 + B[0] + 8) >> 4; |
| 282 out[2 * i + 0] = clip_y(best_y[2 * i + 0] + v0); |
| 283 out[2 * i + 1] = clip_y(best_y[2 * i + 1] + v1); |
| 284 } |
| 285 } |
| 286 |
| 287 #undef MAX_Y |
| 288 |
| 289 //----------------------------------------------------------------------------- |
| 290 |
| 247 void (*WebPConvertRGB24ToY)(const uint8_t* rgb, uint8_t* y, int width); | 291 void (*WebPConvertRGB24ToY)(const uint8_t* rgb, uint8_t* y, int width); |
| 248 void (*WebPConvertBGR24ToY)(const uint8_t* bgr, uint8_t* y, int width); | 292 void (*WebPConvertBGR24ToY)(const uint8_t* bgr, uint8_t* y, int width); |
| 249 void (*WebPConvertRGBA32ToUV)(const uint16_t* rgb, | 293 void (*WebPConvertRGBA32ToUV)(const uint16_t* rgb, |
| 250 uint8_t* u, uint8_t* v, int width); | 294 uint8_t* u, uint8_t* v, int width); |
| 251 | 295 |
| 252 void (*WebPConvertARGBToY)(const uint32_t* argb, uint8_t* y, int width); | 296 void (*WebPConvertARGBToY)(const uint32_t* argb, uint8_t* y, int width); |
| 253 void (*WebPConvertARGBToUV)(const uint32_t* argb, uint8_t* u, uint8_t* v, | 297 void (*WebPConvertARGBToUV)(const uint32_t* argb, uint8_t* u, uint8_t* v, |
| 254 int src_width, int do_store); | 298 int src_width, int do_store); |
| 255 | 299 |
| 300 uint64_t (*WebPSharpYUVUpdateY)(const uint16_t* ref, const uint16_t* src, |
| 301 uint16_t* dst, int len); |
| 302 void (*WebPSharpYUVUpdateRGB)(const int16_t* ref, const int16_t* src, |
| 303 int16_t* dst, int len); |
| 304 void (*WebPSharpYUVFilterRow)(const int16_t* A, const int16_t* B, int len, |
| 305 const uint16_t* best_y, uint16_t* out); |
| 306 |
| 256 static volatile VP8CPUInfo rgba_to_yuv_last_cpuinfo_used = | 307 static volatile VP8CPUInfo rgba_to_yuv_last_cpuinfo_used = |
| 257 (VP8CPUInfo)&rgba_to_yuv_last_cpuinfo_used; | 308 (VP8CPUInfo)&rgba_to_yuv_last_cpuinfo_used; |
| 258 | 309 |
| 259 extern void WebPInitConvertARGBToYUVSSE2(void); | 310 extern void WebPInitConvertARGBToYUVSSE2(void); |
| 311 extern void WebPInitSharpYUVSSE2(void); |
| 260 | 312 |
| 261 WEBP_TSAN_IGNORE_FUNCTION void WebPInitConvertARGBToYUV(void) { | 313 WEBP_TSAN_IGNORE_FUNCTION void WebPInitConvertARGBToYUV(void) { |
| 262 if (rgba_to_yuv_last_cpuinfo_used == VP8GetCPUInfo) return; | 314 if (rgba_to_yuv_last_cpuinfo_used == VP8GetCPUInfo) return; |
| 263 | 315 |
| 264 WebPConvertARGBToY = ConvertARGBToY; | 316 WebPConvertARGBToY = ConvertARGBToY; |
| 265 WebPConvertARGBToUV = WebPConvertARGBToUV_C; | 317 WebPConvertARGBToUV = WebPConvertARGBToUV_C; |
| 266 | 318 |
| 267 WebPConvertRGB24ToY = ConvertRGB24ToY; | 319 WebPConvertRGB24ToY = ConvertRGB24ToY; |
| 268 WebPConvertBGR24ToY = ConvertBGR24ToY; | 320 WebPConvertBGR24ToY = ConvertBGR24ToY; |
| 269 | 321 |
| 270 WebPConvertRGBA32ToUV = WebPConvertRGBA32ToUV_C; | 322 WebPConvertRGBA32ToUV = WebPConvertRGBA32ToUV_C; |
| 271 | 323 |
| 324 WebPSharpYUVUpdateY = SharpYUVUpdateY_C; |
| 325 WebPSharpYUVUpdateRGB = SharpYUVUpdateRGB_C; |
| 326 WebPSharpYUVFilterRow = SharpYUVFilterRow_C; |
| 327 |
| 272 if (VP8GetCPUInfo != NULL) { | 328 if (VP8GetCPUInfo != NULL) { |
| 273 #if defined(WEBP_USE_SSE2) | 329 #if defined(WEBP_USE_SSE2) |
| 274 if (VP8GetCPUInfo(kSSE2)) { | 330 if (VP8GetCPUInfo(kSSE2)) { |
| 275 WebPInitConvertARGBToYUVSSE2(); | 331 WebPInitConvertARGBToYUVSSE2(); |
| 332 WebPInitSharpYUVSSE2(); |
| 276 } | 333 } |
| 277 #endif // WEBP_USE_SSE2 | 334 #endif // WEBP_USE_SSE2 |
| 278 } | 335 } |
| 279 rgba_to_yuv_last_cpuinfo_used = VP8GetCPUInfo; | 336 rgba_to_yuv_last_cpuinfo_used = VP8GetCPUInfo; |
| 280 } | 337 } |
| OLD | NEW |