OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 | 6 |
7 #include "skia/ext/image_operations.h" | 7 #include "skia/ext/image_operations.h" |
8 #include "skia/include/SkColorPriv.h" | |
9 #include "testing/gtest/include/gtest/gtest.h" | 8 #include "testing/gtest/include/gtest/gtest.h" |
10 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
11 | 10 |
12 namespace { | 11 namespace { |
13 | 12 |
14 // Computes the average pixel value for the given range, inclusive. | 13 // Computes the average pixel value for the given range, inclusive. |
15 uint32_t AveragePixel(const SkBitmap& bmp, | 14 uint32_t AveragePixel(const SkBitmap& bmp, |
16 int x_min, int x_max, | 15 int x_min, int x_max, |
17 int y_min, int y_max) { | 16 int y_min, int y_max) { |
18 float accum[4] = {0, 0, 0, 0}; | 17 float accum[4] = {0, 0, 0, 0}; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 ASSERT_EQ(src_h, results.height()); | 138 ASSERT_EQ(src_h, results.height()); |
140 | 139 |
141 SkAutoLockPixels src_lock(src); | 140 SkAutoLockPixels src_lock(src); |
142 SkAutoLockPixels results_lock(results); | 141 SkAutoLockPixels results_lock(results); |
143 for (int y = 0; y < src_h; y++) { | 142 for (int y = 0; y < src_h; y++) { |
144 for (int x = 0; x < src_w; x++) { | 143 for (int x = 0; x < src_w; x++) { |
145 EXPECT_EQ(*src.getAddr32(x, y), *results.getAddr32(x, y)); | 144 EXPECT_EQ(*src.getAddr32(x, y), *results.getAddr32(x, y)); |
146 } | 145 } |
147 } | 146 } |
148 } | 147 } |
149 | |
150 // Blend two bitmaps together at 50% alpha and verify that the result | |
151 // is the middle-blend of the two. | |
152 TEST(ImageOperations, CreateBlendedBitmap) { | |
153 int src_w = 16, src_h = 16; | |
154 SkBitmap src_a; | |
155 src_a.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); | |
156 src_a.allocPixels(); | |
157 | |
158 SkBitmap src_b; | |
159 src_b.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); | |
160 src_b.allocPixels(); | |
161 | |
162 for (int y = 0, i = 0; y < src_h; y++) { | |
163 for (int x = 0; x < src_w; x++) { | |
164 *src_a.getAddr32(x, y) = SkColorSetARGB(255, 0, i * 2 % 255, i % 255); | |
165 *src_b.getAddr32(x, y) = | |
166 SkColorSetARGB((255 - i) % 255, i % 255, i * 4 % 255, 0); | |
167 i++; | |
168 } | |
169 } | |
170 | |
171 // Shift to red. | |
172 SkBitmap blended = skia::ImageOperations::CreateBlendedBitmap( | |
173 src_a, src_b, 0.5); | |
174 SkAutoLockPixels srca_lock(src_a); | |
175 SkAutoLockPixels srcb_lock(src_b); | |
176 SkAutoLockPixels blended_lock(blended); | |
177 | |
178 for (int y = 0; y < src_h; y++) { | |
179 for (int x = 0; x < src_w; x++) { | |
180 int i = y * src_w + x; | |
181 EXPECT_EQ((255 + ((255 - i) % 255)) / 2, | |
182 SkColorGetA(*blended.getAddr32(x, y))); | |
183 EXPECT_EQ(i % 255 / 2, | |
184 SkColorGetR(*blended.getAddr32(x, y))); | |
185 EXPECT_EQ(((i * 2) % 255 + (i * 4) % 255) / 2, | |
186 SkColorGetG(*blended.getAddr32(x, y))); | |
187 EXPECT_EQ(i % 255 / 2, | |
188 SkColorGetB(*blended.getAddr32(x, y))); | |
189 } | |
190 } | |
191 } | |
192 | |
193 // Test our masking functions. | |
194 TEST(ImageOperations, CreateMaskedBitmap) { | |
195 int src_w = 16, src_h = 16; | |
196 | |
197 SkBitmap src; | |
198 FillDataToBitmap(src_w, src_h, &src); | |
199 | |
200 // Generate alpha mask | |
201 SkBitmap alpha; | |
202 alpha.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); | |
203 alpha.allocPixels(); | |
204 | |
205 unsigned char* src_data = | |
206 reinterpret_cast<unsigned char*>(alpha.getAddr32(0, 0)); | |
207 for (int i = 0; i < src_w * src_h; i++) { | |
208 src_data[i * 4] = SkColorSetARGB(i + 128 % 255, | |
209 i + 128 % 255, | |
210 i + 64 % 255, | |
211 i + 0 % 255); | |
212 } | |
213 | |
214 SkBitmap masked = skia::ImageOperations::CreateMaskedBitmap(src, alpha); | |
215 | |
216 SkAutoLockPixels src_lock(src); | |
217 SkAutoLockPixels masked_lock(masked); | |
218 for (int y = 0; y < src_h; y++) { | |
219 for (int x = 0; x < src_w; x++) { | |
220 // Test that the alpha is equal. | |
221 SkColor src_pixel = *src.getAddr32(x, y); | |
222 SkColor alpha_pixel = *alpha.getAddr32(x, y); | |
223 SkColor masked_pixel = *masked.getAddr32(x, y); | |
224 | |
225 // Test that the alpha is equal. | |
226 int alpha = (alpha_pixel & 0xff000000) >> SK_A32_SHIFT; | |
227 EXPECT_EQ(alpha, (masked_pixel & 0xff000000) >> SK_A32_SHIFT); | |
228 | |
229 // Test that the colors are right - SkBitmaps have premultiplied alpha, | |
230 // so we can't just do a direct comparison. | |
231 EXPECT_EQ(SkColorGetR(masked_pixel), | |
232 SkAlphaMul(SkColorGetR(src_pixel), alpha)); | |
233 } | |
234 } | |
235 } | |
236 | |
237 // Testing blur without reimplementing the blur algorithm here is tough, | |
238 // so we just check to see if the pixels have moved in the direction we | |
239 // think they should move in (and also checking the wrapping behavior). | |
240 // This will allow us to tweak the blur algorithm to suit speed/visual | |
241 // needs without breaking the fundamentals. | |
242 TEST(ImageOperations, CreateBlurredBitmap) { | |
243 int src_w = 4, src_h = 4; | |
244 SkBitmap src; | |
245 src.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); | |
246 src.allocPixels(); | |
247 | |
248 for (int y = 0, i = 0; y < src_h; y++) { | |
249 for (int x = 0; x < src_w; x++) { | |
250 int r = (y == 0) ? 255 : 0; // Make the top row red. | |
251 int g = (i % 2 == 0) ? 255 : 0; // Make green alternate in each pixel. | |
252 int b = (y == src_h - 1) ? 255 : 0; // Make the bottom row blue. | |
253 | |
254 *src.getAddr32(x, y) = SkColorSetARGB(255, r, g, b); | |
255 i++; | |
256 } | |
257 } | |
258 | |
259 // Perform a small blur (enough to shove the values in the direction we | |
260 // need - more would just be an unneccessary unit test slowdown). | |
261 SkBitmap blurred = skia::ImageOperations::CreateBlurredBitmap(src, 2); | |
262 | |
263 SkAutoLockPixels src_lock(src); | |
264 SkAutoLockPixels blurred_lock(blurred); | |
265 for (int y = 0, i = 0; y < src_w; y++) { | |
266 for (int x = 0; x < src_h; x++) { | |
267 SkColor src_pixel = *src.getAddr32(x, y); | |
268 SkColor blurred_pixel = *blurred.getAddr32(x, y); | |
269 if (y == 0) { | |
270 // We expect our red to have decreased, but our blue to have | |
271 // increased (from the wrapping from the bottom line). | |
272 EXPECT_TRUE(SkColorGetR(blurred_pixel) < SkColorGetR(src_pixel)); | |
273 EXPECT_TRUE(SkColorGetB(blurred_pixel) > SkColorGetB(src_pixel)); | |
274 } else if (y == src_h - 1) { | |
275 // Now for the opposite. | |
276 EXPECT_TRUE(SkColorGetB(blurred_pixel) < SkColorGetB(src_pixel)); | |
277 EXPECT_TRUE(SkColorGetR(blurred_pixel) > SkColorGetR(src_pixel)); | |
278 } | |
279 | |
280 // Expect the green channel to have moved towards the center (but | |
281 // not past it). | |
282 if (i % 2 == 0) { | |
283 EXPECT_LT(SkColorGetG(blurred_pixel), SkColorGetG(src_pixel)); | |
284 EXPECT_GE(SkColorGetG(blurred_pixel), static_cast<uint32>(128)); | |
285 } else { | |
286 EXPECT_GT(SkColorGetG(blurred_pixel), SkColorGetG(src_pixel)); | |
287 EXPECT_LE(SkColorGetG(blurred_pixel), static_cast<uint32>(128)); | |
288 } | |
289 | |
290 i++; | |
291 } | |
292 } | |
293 } | |
294 | |
295 // Make sure that when shifting a bitmap without any shift parameters, | |
296 // the end result is close enough to the original (rounding errors | |
297 // notwithstanding). | |
298 TEST(ImageOperations, CreateHSLShiftedBitmapToSame) { | |
299 int src_w = 4, src_h = 4; | |
300 SkBitmap src; | |
301 src.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); | |
302 src.allocPixels(); | |
303 | |
304 for (int y = 0, i = 0; y < src_h; y++) { | |
305 for (int x = 0; x < src_w; x++) { | |
306 *src.getAddr32(x, y) = SkColorSetARGB(i + 128 % 255, | |
307 i + 128 % 255, i + 64 % 255, i + 0 % 255); | |
308 i++; | |
309 } | |
310 } | |
311 | |
312 float hsl[3] = { -1, -1, -1 }; | |
313 | |
314 SkBitmap shifted = skia::ImageOperations::CreateHSLShiftedBitmap(src, hsl); | |
315 | |
316 SkAutoLockPixels src_lock(src); | |
317 SkAutoLockPixels shifted_lock(shifted); | |
318 | |
319 for (int y = 0; y < src_w; y++) { | |
320 for (int x = 0; x < src_h; x++) { | |
321 SkColor src_pixel = *src.getAddr32(x, y); | |
322 SkColor shifted_pixel = *shifted.getAddr32(x, y); | |
323 EXPECT_TRUE(ColorsClose(src_pixel, shifted_pixel)); | |
324 } | |
325 } | |
326 } | |
327 | |
328 // Shift a blue bitmap to red. | |
329 TEST(ImageOperations, CreateHSLShiftedBitmapHueOnly) { | |
330 int src_w = 16, src_h = 16; | |
331 SkBitmap src; | |
332 src.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); | |
333 src.allocPixels(); | |
334 | |
335 for (int y = 0, i = 0; y < src_h; y++) { | |
336 for (int x = 0; x < src_w; x++) { | |
337 *src.getAddr32(x, y) = SkColorSetARGB(255, 0, 0, i % 255); | |
338 i++; | |
339 } | |
340 } | |
341 | |
342 // Shift to red. | |
343 float hsl[3] = { 0, -1, -1 }; | |
344 | |
345 SkBitmap shifted = skia::ImageOperations::CreateHSLShiftedBitmap(src, hsl); | |
346 | |
347 SkAutoLockPixels src_lock(src); | |
348 SkAutoLockPixels shifted_lock(shifted); | |
349 | |
350 for (int y = 0, i = 0; y < src_h; y++) { | |
351 for (int x = 0; x < src_w; x++) { | |
352 EXPECT_TRUE(ColorsClose(*shifted.getAddr32(x, y), | |
353 SkColorSetARGB(255, i % 255, 0, 0))); | |
354 i++; | |
355 } | |
356 } | |
357 } | |
358 | |
359 // Test our cropping. | |
360 TEST(ImageOperations, CreateCroppedBitmap) { | |
361 int src_w = 16, src_h = 16; | |
362 SkBitmap src; | |
363 FillDataToBitmap(src_w, src_h, &src); | |
364 | |
365 SkBitmap cropped = skia::ImageOperations::CreateTiledBitmap(src, 4, 4, | |
366 8, 8); | |
367 ASSERT_EQ(8, cropped.width()); | |
368 ASSERT_EQ(8, cropped.height()); | |
369 | |
370 SkAutoLockPixels src_lock(src); | |
371 SkAutoLockPixels cropped_lock(cropped); | |
372 for (int y = 4; y < 12; y++) { | |
373 for (int x = 4; x < 12; x++) { | |
374 EXPECT_EQ(*src.getAddr32(x, y), | |
375 *cropped.getAddr32(x - 4, y - 4)); | |
376 } | |
377 } | |
378 } | |
379 | |
380 // Test whether our cropping correctly wraps across image boundaries. | |
381 TEST(ImageOperations, CreateCroppedBitmapWrapping) { | |
382 int src_w = 16, src_h = 16; | |
383 SkBitmap src; | |
384 FillDataToBitmap(src_w, src_h, &src); | |
385 | |
386 SkBitmap cropped = skia::ImageOperations::CreateTiledBitmap( | |
387 src, src_w / 2, src_h / 2, src_w, src_h); | |
388 ASSERT_EQ(src_w, cropped.width()); | |
389 ASSERT_EQ(src_h, cropped.height()); | |
390 | |
391 SkAutoLockPixels src_lock(src); | |
392 SkAutoLockPixels cropped_lock(cropped); | |
393 for (int y = 0; y < src_h; y++) { | |
394 for (int x = 0; x < src_w; x++) { | |
395 EXPECT_EQ(*src.getAddr32(x, y), | |
396 *cropped.getAddr32((x + src_w / 2) % src_w, | |
397 (y + src_h / 2) % src_h)); | |
398 } | |
399 } | |
400 } | |
401 | |
OLD | NEW |