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

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

Issue 10832153: libwebp: update snapshot to v0.2.0-rc1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 Google Inc. 1 // Copyright 2011 Google Inc. All Rights Reserved.
2 // 2 //
3 // This code is licensed under the same terms as WebM: 3 // This code is licensed under the same terms as WebM:
4 // Software License Agreement: http://www.webmproject.org/license/software/ 4 // Software License Agreement: http://www.webmproject.org/license/software/
5 // Additional IP Rights Grant: http://www.webmproject.org/license/additional/ 5 // Additional IP Rights Grant: http://www.webmproject.org/license/additional/
6 // ----------------------------------------------------------------------------- 6 // -----------------------------------------------------------------------------
7 // 7 //
8 // YUV to RGB upsampling functions. 8 // YUV to RGB upsampling functions.
9 // 9 //
10 // Author: somnath@google.com (Somnath Banerjee) 10 // Author: somnath@google.com (Somnath Banerjee)
11 11
12 #include "./dsp.h" 12 #include "./dsp.h"
13 #include "./yuv.h" 13 #include "./yuv.h"
14 #include "../dec/webpi.h"
15 14
16 #if defined(__cplusplus) || defined(c_plusplus) 15 #if defined(__cplusplus) || defined(c_plusplus)
17 extern "C" { 16 extern "C" {
18 #endif 17 #endif
19 18
20 //------------------------------------------------------------------------------ 19 //------------------------------------------------------------------------------
21 // Fancy upsampler 20 // Fancy upsampler
22 21
23 #ifdef FANCY_UPSAMPLING 22 #ifdef FANCY_UPSAMPLING
24 23
25 // Fancy upsampling functions to convert YUV to RGB 24 // Fancy upsampling functions to convert YUV to RGB
26 WebPUpsampleLinePairFunc WebPUpsamplers[MODE_LAST]; 25 WebPUpsampleLinePairFunc WebPUpsamplers[MODE_LAST];
27 WebPUpsampleLinePairFunc WebPUpsamplersKeepAlpha[MODE_LAST];
28 26
29 // Given samples laid out in a square as: 27 // Given samples laid out in a square as:
30 // [a b] 28 // [a b]
31 // [c d] 29 // [c d]
32 // we interpolate u/v as: 30 // we interpolate u/v as:
33 // ([9*a + 3*b + 3*c + d 3*a + 9*b + 3*c + d] + [8 8]) / 16 31 // ([9*a + 3*b + 3*c + d 3*a + 9*b + 3*c + d] + [8 8]) / 16
34 // ([3*a + b + 9*c + 3*d a + 3*b + 3*c + 9*d] [8 8]) / 16 32 // ([3*a + b + 9*c + 3*d a + 3*b + 3*c + 9*d] [8 8]) / 16
35 33
36 // We process u and v together stashed into 32bit (16bit each). 34 // We process u and v together stashed into 32bit (16bit each).
37 #define LOAD_UV(u,v) ((u) | ((v) << 16)) 35 #define LOAD_UV(u,v) ((u) | ((v) << 16))
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 } 92 }
95 93
96 // All variants implemented. 94 // All variants implemented.
97 UPSAMPLE_FUNC(UpsampleRgbLinePair, VP8YuvToRgb, 3) 95 UPSAMPLE_FUNC(UpsampleRgbLinePair, VP8YuvToRgb, 3)
98 UPSAMPLE_FUNC(UpsampleBgrLinePair, VP8YuvToBgr, 3) 96 UPSAMPLE_FUNC(UpsampleBgrLinePair, VP8YuvToBgr, 3)
99 UPSAMPLE_FUNC(UpsampleRgbaLinePair, VP8YuvToRgba, 4) 97 UPSAMPLE_FUNC(UpsampleRgbaLinePair, VP8YuvToRgba, 4)
100 UPSAMPLE_FUNC(UpsampleBgraLinePair, VP8YuvToBgra, 4) 98 UPSAMPLE_FUNC(UpsampleBgraLinePair, VP8YuvToBgra, 4)
101 UPSAMPLE_FUNC(UpsampleArgbLinePair, VP8YuvToArgb, 4) 99 UPSAMPLE_FUNC(UpsampleArgbLinePair, VP8YuvToArgb, 4)
102 UPSAMPLE_FUNC(UpsampleRgba4444LinePair, VP8YuvToRgba4444, 2) 100 UPSAMPLE_FUNC(UpsampleRgba4444LinePair, VP8YuvToRgba4444, 2)
103 UPSAMPLE_FUNC(UpsampleRgb565LinePair, VP8YuvToRgb565, 2) 101 UPSAMPLE_FUNC(UpsampleRgb565LinePair, VP8YuvToRgb565, 2)
104 // These two don't erase the alpha value
105 UPSAMPLE_FUNC(UpsampleRgbKeepAlphaLinePair, VP8YuvToRgb, 4)
106 UPSAMPLE_FUNC(UpsampleBgrKeepAlphaLinePair, VP8YuvToBgr, 4)
107 UPSAMPLE_FUNC(UpsampleArgbKeepAlphaLinePair, VP8YuvToArgbKeepA, 4)
108 UPSAMPLE_FUNC(UpsampleRgba4444KeepAlphaLinePair, VP8YuvToRgba4444KeepA, 2)
109 102
110 #undef LOAD_UV 103 #undef LOAD_UV
111 #undef UPSAMPLE_FUNC 104 #undef UPSAMPLE_FUNC
112 105
113 #endif // FANCY_UPSAMPLING 106 #endif // FANCY_UPSAMPLING
114 107
115 //------------------------------------------------------------------------------ 108 //------------------------------------------------------------------------------
116 // simple point-sampling 109 // simple point-sampling
117 110
118 #define SAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP) \ 111 #define SAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP) \
(...skipping 30 matching lines...) Expand all
149 142
150 #undef SAMPLE_FUNC 143 #undef SAMPLE_FUNC
151 144
152 const WebPSampleLinePairFunc WebPSamplers[MODE_LAST] = { 145 const WebPSampleLinePairFunc WebPSamplers[MODE_LAST] = {
153 SampleRgbLinePair, // MODE_RGB 146 SampleRgbLinePair, // MODE_RGB
154 SampleRgbaLinePair, // MODE_RGBA 147 SampleRgbaLinePair, // MODE_RGBA
155 SampleBgrLinePair, // MODE_BGR 148 SampleBgrLinePair, // MODE_BGR
156 SampleBgraLinePair, // MODE_BGRA 149 SampleBgraLinePair, // MODE_BGRA
157 SampleArgbLinePair, // MODE_ARGB 150 SampleArgbLinePair, // MODE_ARGB
158 SampleRgba4444LinePair, // MODE_RGBA_4444 151 SampleRgba4444LinePair, // MODE_RGBA_4444
159 SampleRgb565LinePair // MODE_RGB_565 152 SampleRgb565LinePair, // MODE_RGB_565
153 SampleRgbaLinePair, // MODE_rgbA
154 SampleBgraLinePair, // MODE_bgrA
155 SampleArgbLinePair, // MODE_Argb
156 SampleRgba4444LinePair // MODE_rgbA_4444
160 }; 157 };
161 158
162 //------------------------------------------------------------------------------ 159 //------------------------------------------------------------------------------
160
161 #if !defined(FANCY_UPSAMPLING)
162 #define DUAL_SAMPLE_FUNC(FUNC_NAME, FUNC) \
163 static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bot_y, \
164 const uint8_t* top_u, const uint8_t* top_v, \
165 const uint8_t* bot_u, const uint8_t* bot_v, \
166 uint8_t* top_dst, uint8_t* bot_dst, int len) { \
167 const int half_len = len >> 1; \
168 int x; \
169 if (top_dst != NULL) { \
170 for (x = 0; x < half_len; ++x) { \
171 FUNC(top_y[2 * x + 0], top_u[x], top_v[x], top_dst + 8 * x + 0); \
172 FUNC(top_y[2 * x + 1], top_u[x], top_v[x], top_dst + 8 * x + 4); \
173 } \
174 if (len & 1) FUNC(top_y[2 * x + 0], top_u[x], top_v[x], top_dst + 8 * x); \
175 } \
176 if (bot_dst != NULL) { \
177 for (x = 0; x < half_len; ++x) { \
178 FUNC(bot_y[2 * x + 0], bot_u[x], bot_v[x], bot_dst + 8 * x + 0); \
179 FUNC(bot_y[2 * x + 1], bot_u[x], bot_v[x], bot_dst + 8 * x + 4); \
180 } \
181 if (len & 1) FUNC(bot_y[2 * x + 0], bot_u[x], bot_v[x], bot_dst + 8 * x); \
182 } \
183 }
184
185 DUAL_SAMPLE_FUNC(DualLineSamplerBGRA, VP8YuvToBgra)
186 DUAL_SAMPLE_FUNC(DualLineSamplerARGB, VP8YuvToArgb)
187 #undef DUAL_SAMPLE_FUNC
188
189 #endif // !FANCY_UPSAMPLING
190
191 WebPUpsampleLinePairFunc WebPGetLinePairConverter(int alpha_is_last) {
192 WebPInitUpsamplers();
193 VP8YUVInit();
194 #ifdef FANCY_UPSAMPLING
195 return WebPUpsamplers[alpha_is_last ? MODE_BGRA : MODE_ARGB];
196 #else
197 return (alpha_is_last ? DualLineSamplerBGRA : DualLineSamplerARGB);
198 #endif
199 }
200
201 //------------------------------------------------------------------------------
163 // YUV444 converter 202 // YUV444 converter
164 203
165 #define YUV444_FUNC(FUNC_NAME, FUNC, XSTEP) \ 204 #define YUV444_FUNC(FUNC_NAME, FUNC, XSTEP) \
166 static void FUNC_NAME(const uint8_t* y, const uint8_t* u, const uint8_t* v, \ 205 static void FUNC_NAME(const uint8_t* y, const uint8_t* u, const uint8_t* v, \
167 uint8_t* dst, int len) { \ 206 uint8_t* dst, int len) { \
168 int i; \ 207 int i; \
169 for (i = 0; i < len; ++i) FUNC(y[i], u[i], v[i], &dst[i * XSTEP]); \ 208 for (i = 0; i < len; ++i) FUNC(y[i], u[i], v[i], &dst[i * XSTEP]); \
170 } 209 }
171 210
172 YUV444_FUNC(Yuv444ToRgb, VP8YuvToRgb, 3) 211 YUV444_FUNC(Yuv444ToRgb, VP8YuvToRgb, 3)
173 YUV444_FUNC(Yuv444ToBgr, VP8YuvToBgr, 3) 212 YUV444_FUNC(Yuv444ToBgr, VP8YuvToBgr, 3)
174 YUV444_FUNC(Yuv444ToRgba, VP8YuvToRgba, 4) 213 YUV444_FUNC(Yuv444ToRgba, VP8YuvToRgba, 4)
175 YUV444_FUNC(Yuv444ToBgra, VP8YuvToBgra, 4) 214 YUV444_FUNC(Yuv444ToBgra, VP8YuvToBgra, 4)
176 YUV444_FUNC(Yuv444ToArgb, VP8YuvToArgb, 4) 215 YUV444_FUNC(Yuv444ToArgb, VP8YuvToArgb, 4)
177 YUV444_FUNC(Yuv444ToRgba4444, VP8YuvToRgba4444, 2) 216 YUV444_FUNC(Yuv444ToRgba4444, VP8YuvToRgba4444, 2)
178 YUV444_FUNC(Yuv444ToRgb565, VP8YuvToRgb565, 2) 217 YUV444_FUNC(Yuv444ToRgb565, VP8YuvToRgb565, 2)
179 218
180 #undef YUV444_FUNC 219 #undef YUV444_FUNC
181 220
182 const WebPYUV444Converter WebPYUV444Converters[MODE_LAST] = { 221 const WebPYUV444Converter WebPYUV444Converters[MODE_LAST] = {
183 Yuv444ToRgb, // MODE_RGB 222 Yuv444ToRgb, // MODE_RGB
184 Yuv444ToRgba, // MODE_RGBA 223 Yuv444ToRgba, // MODE_RGBA
185 Yuv444ToBgr, // MODE_BGR 224 Yuv444ToBgr, // MODE_BGR
186 Yuv444ToBgra, // MODE_BGRA 225 Yuv444ToBgra, // MODE_BGRA
187 Yuv444ToArgb, // MODE_ARGB 226 Yuv444ToArgb, // MODE_ARGB
188 Yuv444ToRgba4444, // MODE_RGBA_4444 227 Yuv444ToRgba4444, // MODE_RGBA_4444
189 Yuv444ToRgb565 // MODE_RGB_565 228 Yuv444ToRgb565, // MODE_RGB_565
229 Yuv444ToRgba, // MODE_rgbA
230 Yuv444ToBgra, // MODE_bgrA
231 Yuv444ToArgb, // MODE_Argb
232 Yuv444ToRgba4444 // MODE_rgbA_4444
190 }; 233 };
191 234
192 //------------------------------------------------------------------------------ 235 //------------------------------------------------------------------------------
236 // Premultiplied modes
237
238 // non dithered-modes
239
240 // (x * a * 32897) >> 23 is bit-wise equivalent to (int)(x * a / 255.)
241 // for all 8bit x or a. For bit-wise equivalence to (int)(x * a / 255. + .5),
242 // one can use instead: (x * a * 65793 + (1 << 23)) >> 24
243 #if 1 // (int)(x * a / 255.)
244 #define MULTIPLIER(a) ((a) * 32897UL)
245 #define PREMULTIPLY(x, m) (((x) * (m)) >> 23)
246 #else // (int)(x * a / 255. + .5)
247 #define MULTIPLIER(a) ((a) * 65793UL)
248 #define PREMULTIPLY(x, m) (((x) * (m) + (1UL << 23)) >> 24)
249 #endif
250
251 static void ApplyAlphaMultiply(uint8_t* rgba, int alpha_first,
252 int w, int h, int stride) {
253 while (h-- > 0) {
254 uint8_t* const rgb = rgba + (alpha_first ? 1 : 0);
255 const uint8_t* const alpha = rgba + (alpha_first ? 0 : 3);
256 int i;
257 for (i = 0; i < w; ++i) {
258 const uint32_t a = alpha[4 * i];
259 if (a != 0xff) {
260 const uint32_t mult = MULTIPLIER(a);
261 rgb[4 * i + 0] = PREMULTIPLY(rgb[4 * i + 0], mult);
262 rgb[4 * i + 1] = PREMULTIPLY(rgb[4 * i + 1], mult);
263 rgb[4 * i + 2] = PREMULTIPLY(rgb[4 * i + 2], mult);
264 }
265 }
266 rgba += stride;
267 }
268 }
269 #undef MULTIPLIER
270 #undef PREMULTIPLY
271
272 // rgbA4444
273
274 #define MULTIPLIER(a) ((a) * 0x11)
275 #define PREMULTIPLY(x, m) (((x) * (m)) >> 12)
276
277 static WEBP_INLINE uint8_t dither_hi(uint8_t x) {
278 return (x & 0xf0) | (x >> 4);
279 }
280
281 static WEBP_INLINE uint8_t dither_lo(uint8_t x) {
282 return (x & 0x0f) | (x << 4);
283 }
284
285 static void ApplyAlphaMultiply4444(uint8_t* rgba4444,
286 int w, int h, int stride) {
287 while (h-- > 0) {
288 int i;
289 for (i = 0; i < w; ++i) {
290 const uint8_t a = dither_lo(rgba4444[2 * i + 1]);
291 const uint32_t mult = MULTIPLIER(a);
292 const uint8_t r = PREMULTIPLY(dither_hi(rgba4444[2 * i + 0]), mult);
293 const uint8_t g = PREMULTIPLY(dither_lo(rgba4444[2 * i + 0]), mult);
294 const uint8_t b = PREMULTIPLY(dither_hi(rgba4444[2 * i + 1]), mult);
295 rgba4444[2 * i + 0] = (r & 0xf0) | (g & 0x0f);
296 rgba4444[2 * i + 1] = (b & 0xf0) | a;
297 }
298 rgba4444 += stride;
299 }
300 }
301 #undef MULTIPLIER
302 #undef PREMULTIPLY
303
304 void (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int)
305 = ApplyAlphaMultiply;
306 void (*WebPApplyAlphaMultiply4444)(uint8_t*, int, int, int)
307 = ApplyAlphaMultiply4444;
308
309 //------------------------------------------------------------------------------
193 // Main call 310 // Main call
194 311
195 void WebPInitUpsamplers(void) { 312 void WebPInitUpsamplers(void) {
196 #ifdef FANCY_UPSAMPLING 313 #ifdef FANCY_UPSAMPLING
197 WebPUpsamplers[MODE_RGB] = UpsampleRgbLinePair; 314 WebPUpsamplers[MODE_RGB] = UpsampleRgbLinePair;
198 WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePair; 315 WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePair;
199 WebPUpsamplers[MODE_BGR] = UpsampleBgrLinePair; 316 WebPUpsamplers[MODE_BGR] = UpsampleBgrLinePair;
200 WebPUpsamplers[MODE_BGRA] = UpsampleBgraLinePair; 317 WebPUpsamplers[MODE_BGRA] = UpsampleBgraLinePair;
201 WebPUpsamplers[MODE_ARGB] = UpsampleArgbLinePair; 318 WebPUpsamplers[MODE_ARGB] = UpsampleArgbLinePair;
202 WebPUpsamplers[MODE_RGBA_4444] = UpsampleRgba4444LinePair; 319 WebPUpsamplers[MODE_RGBA_4444] = UpsampleRgba4444LinePair;
203 WebPUpsamplers[MODE_RGB_565] = UpsampleRgb565LinePair; 320 WebPUpsamplers[MODE_RGB_565] = UpsampleRgb565LinePair;
204 321
205 WebPUpsamplersKeepAlpha[MODE_RGB] = UpsampleRgbLinePair;
206 WebPUpsamplersKeepAlpha[MODE_RGBA] = UpsampleRgbKeepAlphaLinePair;
207 WebPUpsamplersKeepAlpha[MODE_BGR] = UpsampleBgrLinePair;
208 WebPUpsamplersKeepAlpha[MODE_BGRA] = UpsampleBgrKeepAlphaLinePair;
209 WebPUpsamplersKeepAlpha[MODE_ARGB] = UpsampleArgbKeepAlphaLinePair;
210 WebPUpsamplersKeepAlpha[MODE_RGBA_4444] = UpsampleRgba4444KeepAlphaLinePair;
211 WebPUpsamplersKeepAlpha[MODE_RGB_565] = UpsampleRgb565LinePair;
212
213 // If defined, use CPUInfo() to overwrite some pointers with faster versions. 322 // If defined, use CPUInfo() to overwrite some pointers with faster versions.
214 if (VP8GetCPUInfo) { 323 if (VP8GetCPUInfo != NULL) {
215 #if defined(__SSE2__) || defined(_MSC_VER) 324 #if defined(WEBP_USE_SSE2)
216 if (VP8GetCPUInfo(kSSE2)) { 325 if (VP8GetCPUInfo(kSSE2)) {
217 WebPInitUpsamplersSSE2(); 326 WebPInitUpsamplersSSE2();
218 } 327 }
219 #endif 328 #endif
220 } 329 }
221 #endif // FANCY_UPSAMPLING 330 #endif // FANCY_UPSAMPLING
222 } 331 }
223 332
333 void WebPInitPremultiply(void) {
334 WebPApplyAlphaMultiply = ApplyAlphaMultiply;
335 WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply4444;
336
337 #ifdef FANCY_UPSAMPLING
338 WebPUpsamplers[MODE_rgbA] = UpsampleRgbaLinePair;
339 WebPUpsamplers[MODE_bgrA] = UpsampleBgraLinePair;
340 WebPUpsamplers[MODE_Argb] = UpsampleArgbLinePair;
341 WebPUpsamplers[MODE_rgbA_4444] = UpsampleRgba4444LinePair;
342
343 if (VP8GetCPUInfo != NULL) {
344 #if defined(WEBP_USE_SSE2)
345 if (VP8GetCPUInfo(kSSE2)) {
346 WebPInitPremultiplySSE2();
347 }
348 #endif
349 }
350 #endif // FANCY_UPSAMPLING
351 }
352
224 #if defined(__cplusplus) || defined(c_plusplus) 353 #if defined(__cplusplus) || defined(c_plusplus)
225 } // extern "C" 354 } // extern "C"
226 #endif 355 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698