1 // Copyright 2010 Google Inc. All Rights Reserved.
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 // -----------------------------------------------------------------------------
10 // YUV->RGB conversion functions
12 // Author: Skal (pascal.massimino@gmail.com)
16 #if defined(WEBP_YUV_USE_TABLE)
20 static WEBP_INLINE
uint8_t clip(int v
, int max_value
) {
21 return v
< 0 ? 0 : v
> max_value
? max_value
: v
;
24 int16_t VP8kVToR
[256], VP8kUToB
[256];
25 int32_t VP8kVToG
[256], VP8kUToG
[256];
26 uint8_t VP8kClip
[YUV_RANGE_MAX
- YUV_RANGE_MIN
];
27 uint8_t VP8kClip4Bits
[YUV_RANGE_MAX
- YUV_RANGE_MIN
];
29 void VP8YUVInit(void) {
35 for (i
= 0; i
< 256; ++i
) {
36 VP8kVToR
[i
] = (89858 * (i
- 128) + YUV_HALF
) >> YUV_FIX
;
37 VP8kUToG
[i
] = -22014 * (i
- 128) + YUV_HALF
;
38 VP8kVToG
[i
] = -45773 * (i
- 128);
39 VP8kUToB
[i
] = (113618 * (i
- 128) + YUV_HALF
) >> YUV_FIX
;
41 for (i
= YUV_RANGE_MIN
; i
< YUV_RANGE_MAX
; ++i
) {
42 const int k
= ((i
- 16) * 76283 + YUV_HALF
) >> YUV_FIX
;
43 VP8kClip
[i
- YUV_RANGE_MIN
] = clip(k
, 255);
44 VP8kClip4Bits
[i
- YUV_RANGE_MIN
] = clip((k
+ 8) >> 4, 15);
47 for (i
= 0; i
< 256; ++i
) {
48 VP8kVToR
[i
] = (91881 * (i
- 128) + YUV_HALF
) >> YUV_FIX
;
49 VP8kUToG
[i
] = -22554 * (i
- 128) + YUV_HALF
;
50 VP8kVToG
[i
] = -46802 * (i
- 128);
51 VP8kUToB
[i
] = (116130 * (i
- 128) + YUV_HALF
) >> YUV_FIX
;
53 for (i
= YUV_RANGE_MIN
; i
< YUV_RANGE_MAX
; ++i
) {
55 VP8kClip
[i
- YUV_RANGE_MIN
] = clip(k
, 255);
56 VP8kClip4Bits
[i
- YUV_RANGE_MIN
] = clip((k
+ 8) >> 4, 15);
65 void VP8YUVInit(void) {}
67 #endif // WEBP_YUV_USE_TABLE
69 //-----------------------------------------------------------------------------
72 #define ROW_FUNC(FUNC_NAME, FUNC, XSTEP) \
73 static void FUNC_NAME(const uint8_t* y, \
74 const uint8_t* u, const uint8_t* v, \
75 uint8_t* dst, int len) { \
76 const uint8_t* const end = dst + (len & ~1) * XSTEP; \
77 while (dst != end) { \
78 FUNC(y[0], u[0], v[0], dst); \
79 FUNC(y[1], u[0], v[0], dst + XSTEP); \
86 FUNC(y[0], u[0], v[0], dst); \
90 // All variants implemented.
91 ROW_FUNC(YuvToRgbRow
, VP8YuvToRgb
, 3)
92 ROW_FUNC(YuvToBgrRow
, VP8YuvToBgr
, 3)
93 ROW_FUNC(YuvToRgbaRow
, VP8YuvToRgba
, 4)
94 ROW_FUNC(YuvToBgraRow
, VP8YuvToBgra
, 4)
95 ROW_FUNC(YuvToArgbRow
, VP8YuvToArgb
, 4)
96 ROW_FUNC(YuvToRgba4444Row
, VP8YuvToRgba4444
, 2)
97 ROW_FUNC(YuvToRgb565Row
, VP8YuvToRgb565
, 2)
101 // Main call for processing a plane with a WebPSamplerRowFunc function:
102 void WebPSamplerProcessPlane(const uint8_t* y
, int y_stride
,
103 const uint8_t* u
, const uint8_t* v
, int uv_stride
,
104 uint8_t* dst
, int dst_stride
,
105 int width
, int height
, WebPSamplerRowFunc func
) {
107 for (j
= 0; j
< height
; ++j
) {
108 func(y
, u
, v
, dst
, width
);
118 //-----------------------------------------------------------------------------
121 WebPSamplerRowFunc WebPSamplers
[MODE_LAST
];
123 extern void WebPInitSamplersSSE2(void);
124 extern void WebPInitSamplersMIPS32(void);
126 static volatile VP8CPUInfo yuv_last_cpuinfo_used
=
127 (VP8CPUInfo
)&yuv_last_cpuinfo_used
;
129 void WebPInitSamplers(void) {
130 if (yuv_last_cpuinfo_used
== VP8GetCPUInfo
) return;
132 WebPSamplers
[MODE_RGB
] = YuvToRgbRow
;
133 WebPSamplers
[MODE_RGBA
] = YuvToRgbaRow
;
134 WebPSamplers
[MODE_BGR
] = YuvToBgrRow
;
135 WebPSamplers
[MODE_BGRA
] = YuvToBgraRow
;
136 WebPSamplers
[MODE_ARGB
] = YuvToArgbRow
;
137 WebPSamplers
[MODE_RGBA_4444
] = YuvToRgba4444Row
;
138 WebPSamplers
[MODE_RGB_565
] = YuvToRgb565Row
;
139 WebPSamplers
[MODE_rgbA
] = YuvToRgbaRow
;
140 WebPSamplers
[MODE_bgrA
] = YuvToBgraRow
;
141 WebPSamplers
[MODE_Argb
] = YuvToArgbRow
;
142 WebPSamplers
[MODE_rgbA_4444
] = YuvToRgba4444Row
;
144 // If defined, use CPUInfo() to overwrite some pointers with faster versions.
145 if (VP8GetCPUInfo
!= NULL
) {
146 #if defined(WEBP_USE_SSE2)
147 if (VP8GetCPUInfo(kSSE2
)) {
148 WebPInitSamplersSSE2();
150 #endif // WEBP_USE_SSE2
151 #if defined(WEBP_USE_MIPS32)
152 if (VP8GetCPUInfo(kMIPS32
)) {
153 WebPInitSamplersMIPS32();
155 #endif // WEBP_USE_MIPS32
157 yuv_last_cpuinfo_used
= VP8GetCPUInfo
;
160 //-----------------------------------------------------------------------------