Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: third_party/libwebp/dsp/yuv.c

Issue 1546003002: libwebp: update to 0.5.0 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase around clang-cl fix Created 4 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #if defined(WEBP_YUV_USE_TABLE) 16 #if defined(WEBP_YUV_USE_TABLE)
17 17
18 static int done = 0; 18 static int done = 0;
19 19
20 static WEBP_INLINE uint8_t clip(int v, int max_value) { 20 static WEBP_INLINE uint8_t clip(int v, int max_value) {
21 return v < 0 ? 0 : v > max_value ? max_value : v; 21 return v < 0 ? 0 : v > max_value ? max_value : v;
22 } 22 }
23 23
24 int16_t VP8kVToR[256], VP8kUToB[256]; 24 int16_t VP8kVToR[256], VP8kUToB[256];
25 int32_t VP8kVToG[256], VP8kUToG[256]; 25 int32_t VP8kVToG[256], VP8kUToG[256];
26 uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN]; 26 uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN];
27 uint8_t VP8kClip4Bits[YUV_RANGE_MAX - YUV_RANGE_MIN]; 27 uint8_t VP8kClip4Bits[YUV_RANGE_MAX - YUV_RANGE_MIN];
28 28
29 void VP8YUVInit(void) { 29 WEBP_TSAN_IGNORE_FUNCTION void VP8YUVInit(void) {
30 int i; 30 int i;
31 if (done) { 31 if (done) {
32 return; 32 return;
33 } 33 }
34 #ifndef USE_YUVj 34 #ifndef USE_YUVj
35 for (i = 0; i < 256; ++i) { 35 for (i = 0; i < 256; ++i) {
36 VP8kVToR[i] = (89858 * (i - 128) + YUV_HALF) >> YUV_FIX; 36 VP8kVToR[i] = (89858 * (i - 128) + YUV_HALF) >> YUV_FIX;
37 VP8kUToG[i] = -22014 * (i - 128) + YUV_HALF; 37 VP8kUToG[i] = -22014 * (i - 128) + YUV_HALF;
38 VP8kVToG[i] = -45773 * (i - 128); 38 VP8kVToG[i] = -45773 * (i - 128);
39 VP8kUToB[i] = (113618 * (i - 128) + YUV_HALF) >> YUV_FIX; 39 VP8kUToB[i] = (113618 * (i - 128) + YUV_HALF) >> YUV_FIX;
(...skipping 15 matching lines...) Expand all
55 VP8kClip[i - YUV_RANGE_MIN] = clip(k, 255); 55 VP8kClip[i - YUV_RANGE_MIN] = clip(k, 255);
56 VP8kClip4Bits[i - YUV_RANGE_MIN] = clip((k + 8) >> 4, 15); 56 VP8kClip4Bits[i - YUV_RANGE_MIN] = clip((k + 8) >> 4, 15);
57 } 57 }
58 #endif 58 #endif
59 59
60 done = 1; 60 done = 1;
61 } 61 }
62 62
63 #else 63 #else
64 64
65 void VP8YUVInit(void) {} 65 WEBP_TSAN_IGNORE_FUNCTION void VP8YUVInit(void) {}
66 66
67 #endif // WEBP_YUV_USE_TABLE 67 #endif // WEBP_YUV_USE_TABLE
68 68
69 //----------------------------------------------------------------------------- 69 //-----------------------------------------------------------------------------
70 // Plain-C version 70 // Plain-C version
71 71
72 #define ROW_FUNC(FUNC_NAME, FUNC, XSTEP) \ 72 #define ROW_FUNC(FUNC_NAME, FUNC, XSTEP) \
73 static void FUNC_NAME(const uint8_t* y, \ 73 static void FUNC_NAME(const uint8_t* y, \
74 const uint8_t* u, const uint8_t* v, \ 74 const uint8_t* u, const uint8_t* v, \
75 uint8_t* dst, int len) { \ 75 uint8_t* dst, int len) { \
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 } 115 }
116 } 116 }
117 117
118 //----------------------------------------------------------------------------- 118 //-----------------------------------------------------------------------------
119 // Main call 119 // Main call
120 120
121 WebPSamplerRowFunc WebPSamplers[MODE_LAST]; 121 WebPSamplerRowFunc WebPSamplers[MODE_LAST];
122 122
123 extern void WebPInitSamplersSSE2(void); 123 extern void WebPInitSamplersSSE2(void);
124 extern void WebPInitSamplersMIPS32(void); 124 extern void WebPInitSamplersMIPS32(void);
125 extern void WebPInitSamplersMIPSdspR2(void);
125 126
126 static volatile VP8CPUInfo yuv_last_cpuinfo_used = 127 static volatile VP8CPUInfo yuv_last_cpuinfo_used =
127 (VP8CPUInfo)&yuv_last_cpuinfo_used; 128 (VP8CPUInfo)&yuv_last_cpuinfo_used;
128 129
129 void WebPInitSamplers(void) { 130 WEBP_TSAN_IGNORE_FUNCTION void WebPInitSamplers(void) {
130 if (yuv_last_cpuinfo_used == VP8GetCPUInfo) return; 131 if (yuv_last_cpuinfo_used == VP8GetCPUInfo) return;
131 132
132 WebPSamplers[MODE_RGB] = YuvToRgbRow; 133 WebPSamplers[MODE_RGB] = YuvToRgbRow;
133 WebPSamplers[MODE_RGBA] = YuvToRgbaRow; 134 WebPSamplers[MODE_RGBA] = YuvToRgbaRow;
134 WebPSamplers[MODE_BGR] = YuvToBgrRow; 135 WebPSamplers[MODE_BGR] = YuvToBgrRow;
135 WebPSamplers[MODE_BGRA] = YuvToBgraRow; 136 WebPSamplers[MODE_BGRA] = YuvToBgraRow;
136 WebPSamplers[MODE_ARGB] = YuvToArgbRow; 137 WebPSamplers[MODE_ARGB] = YuvToArgbRow;
137 WebPSamplers[MODE_RGBA_4444] = YuvToRgba4444Row; 138 WebPSamplers[MODE_RGBA_4444] = YuvToRgba4444Row;
138 WebPSamplers[MODE_RGB_565] = YuvToRgb565Row; 139 WebPSamplers[MODE_RGB_565] = YuvToRgb565Row;
139 WebPSamplers[MODE_rgbA] = YuvToRgbaRow; 140 WebPSamplers[MODE_rgbA] = YuvToRgbaRow;
140 WebPSamplers[MODE_bgrA] = YuvToBgraRow; 141 WebPSamplers[MODE_bgrA] = YuvToBgraRow;
141 WebPSamplers[MODE_Argb] = YuvToArgbRow; 142 WebPSamplers[MODE_Argb] = YuvToArgbRow;
142 WebPSamplers[MODE_rgbA_4444] = YuvToRgba4444Row; 143 WebPSamplers[MODE_rgbA_4444] = YuvToRgba4444Row;
143 144
144 // If defined, use CPUInfo() to overwrite some pointers with faster versions. 145 // If defined, use CPUInfo() to overwrite some pointers with faster versions.
145 if (VP8GetCPUInfo != NULL) { 146 if (VP8GetCPUInfo != NULL) {
146 #if defined(WEBP_USE_SSE2) 147 #if defined(WEBP_USE_SSE2)
147 if (VP8GetCPUInfo(kSSE2)) { 148 if (VP8GetCPUInfo(kSSE2)) {
148 WebPInitSamplersSSE2(); 149 WebPInitSamplersSSE2();
149 } 150 }
150 #endif // WEBP_USE_SSE2 151 #endif // WEBP_USE_SSE2
151 #if defined(WEBP_USE_MIPS32) 152 #if defined(WEBP_USE_MIPS32)
152 if (VP8GetCPUInfo(kMIPS32)) { 153 if (VP8GetCPUInfo(kMIPS32)) {
153 WebPInitSamplersMIPS32(); 154 WebPInitSamplersMIPS32();
154 } 155 }
155 #endif // WEBP_USE_MIPS32 156 #endif // WEBP_USE_MIPS32
157 #if defined(WEBP_USE_MIPS_DSP_R2)
158 if (VP8GetCPUInfo(kMIPSdspR2)) {
159 WebPInitSamplersMIPSdspR2();
160 }
161 #endif // WEBP_USE_MIPS_DSP_R2
156 } 162 }
157 yuv_last_cpuinfo_used = VP8GetCPUInfo; 163 yuv_last_cpuinfo_used = VP8GetCPUInfo;
158 } 164 }
159 165
160 //----------------------------------------------------------------------------- 166 //-----------------------------------------------------------------------------
167 // ARGB -> YUV converters
168
169 static void ConvertARGBToY(const uint32_t* argb, uint8_t* y, int width) {
170 int i;
171 for (i = 0; i < width; ++i) {
172 const uint32_t p = argb[i];
173 y[i] = VP8RGBToY((p >> 16) & 0xff, (p >> 8) & 0xff, (p >> 0) & 0xff,
174 YUV_HALF);
175 }
176 }
177
178 void WebPConvertARGBToUV_C(const uint32_t* argb, uint8_t* u, uint8_t* v,
179 int src_width, int do_store) {
180 // No rounding. Last pixel is dealt with separately.
181 const int uv_width = src_width >> 1;
182 int i;
183 for (i = 0; i < uv_width; ++i) {
184 const uint32_t v0 = argb[2 * i + 0];
185 const uint32_t v1 = argb[2 * i + 1];
186 // VP8RGBToU/V expects four accumulated pixels. Hence we need to
187 // scale r/g/b value by a factor 2. We just shift v0/v1 one bit less.
188 const int r = ((v0 >> 15) & 0x1fe) + ((v1 >> 15) & 0x1fe);
189 const int g = ((v0 >> 7) & 0x1fe) + ((v1 >> 7) & 0x1fe);
190 const int b = ((v0 << 1) & 0x1fe) + ((v1 << 1) & 0x1fe);
191 const int tmp_u = VP8RGBToU(r, g, b, YUV_HALF << 2);
192 const int tmp_v = VP8RGBToV(r, g, b, YUV_HALF << 2);
193 if (do_store) {
194 u[i] = tmp_u;
195 v[i] = tmp_v;
196 } else {
197 // Approximated average-of-four. But it's an acceptable diff.
198 u[i] = (u[i] + tmp_u + 1) >> 1;
199 v[i] = (v[i] + tmp_v + 1) >> 1;
200 }
201 }
202 if (src_width & 1) { // last pixel
203 const uint32_t v0 = argb[2 * i + 0];
204 const int r = (v0 >> 14) & 0x3fc;
205 const int g = (v0 >> 6) & 0x3fc;
206 const int b = (v0 << 2) & 0x3fc;
207 const int tmp_u = VP8RGBToU(r, g, b, YUV_HALF << 2);
208 const int tmp_v = VP8RGBToV(r, g, b, YUV_HALF << 2);
209 if (do_store) {
210 u[i] = tmp_u;
211 v[i] = tmp_v;
212 } else {
213 u[i] = (u[i] + tmp_u + 1) >> 1;
214 v[i] = (v[i] + tmp_v + 1) >> 1;
215 }
216 }
217 }
218
219 //-----------------------------------------------------------------------------
220
221 static void ConvertRGB24ToY(const uint8_t* rgb, uint8_t* y, int width) {
222 int i;
223 for (i = 0; i < width; ++i, rgb += 3) {
224 y[i] = VP8RGBToY(rgb[0], rgb[1], rgb[2], YUV_HALF);
225 }
226 }
227
228 static void ConvertBGR24ToY(const uint8_t* bgr, uint8_t* y, int width) {
229 int i;
230 for (i = 0; i < width; ++i, bgr += 3) {
231 y[i] = VP8RGBToY(bgr[2], bgr[1], bgr[0], YUV_HALF);
232 }
233 }
234
235 void WebPConvertRGBA32ToUV_C(const uint16_t* rgb,
236 uint8_t* u, uint8_t* v, int width) {
237 int i;
238 for (i = 0; i < width; i += 1, rgb += 4) {
239 const int r = rgb[0], g = rgb[1], b = rgb[2];
240 u[i] = VP8RGBToU(r, g, b, YUV_HALF << 2);
241 v[i] = VP8RGBToV(r, g, b, YUV_HALF << 2);
242 }
243 }
244
245 //-----------------------------------------------------------------------------
246
247 void (*WebPConvertRGB24ToY)(const uint8_t* rgb, uint8_t* y, int width);
248 void (*WebPConvertBGR24ToY)(const uint8_t* bgr, uint8_t* y, int width);
249 void (*WebPConvertRGBA32ToUV)(const uint16_t* rgb,
250 uint8_t* u, uint8_t* v, int width);
251
252 void (*WebPConvertARGBToY)(const uint32_t* argb, uint8_t* y, int width);
253 void (*WebPConvertARGBToUV)(const uint32_t* argb, uint8_t* u, uint8_t* v,
254 int src_width, int do_store);
255
256 static volatile VP8CPUInfo rgba_to_yuv_last_cpuinfo_used =
257 (VP8CPUInfo)&rgba_to_yuv_last_cpuinfo_used;
258
259 extern void WebPInitConvertARGBToYUVSSE2(void);
260
261 WEBP_TSAN_IGNORE_FUNCTION void WebPInitConvertARGBToYUV(void) {
262 if (rgba_to_yuv_last_cpuinfo_used == VP8GetCPUInfo) return;
263
264 WebPConvertARGBToY = ConvertARGBToY;
265 WebPConvertARGBToUV = WebPConvertARGBToUV_C;
266
267 WebPConvertRGB24ToY = ConvertRGB24ToY;
268 WebPConvertBGR24ToY = ConvertBGR24ToY;
269
270 WebPConvertRGBA32ToUV = WebPConvertRGBA32ToUV_C;
271
272 if (VP8GetCPUInfo != NULL) {
273 #if defined(WEBP_USE_SSE2)
274 if (VP8GetCPUInfo(kSSE2)) {
275 WebPInitConvertARGBToYUVSSE2();
276 }
277 #endif // WEBP_USE_SSE2
278 }
279 rgba_to_yuv_last_cpuinfo_used = VP8GetCPUInfo;
280 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698