OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Because the unit tests for gfx::Image are spread across multiple | |
6 // implementation files, this header contains the reusable components. | |
7 | |
8 #include "ui/gfx/image/image_unittest_util.h" | |
9 | |
10 #include <cmath> | |
11 | |
12 #include "base/memory/scoped_ptr.h" | |
13 #include "testing/gtest/include/gtest/gtest.h" | |
14 #include "third_party/skia/include/core/SkBitmap.h" | |
15 #include "ui/gfx/codec/png_codec.h" | |
16 #include "ui/gfx/image/image_skia.h" | |
17 | |
18 #if defined(OS_IOS) | |
19 #include "base/mac/foundation_util.h" | |
20 #include "base/mac/scoped_cftyperef.h" | |
21 #include "skia/ext/skia_utils_ios.h" | |
22 #elif defined(OS_MACOSX) | |
23 #include "base/mac/mac_util.h" | |
24 #include "skia/ext/skia_utils_mac.h" | |
25 #endif | |
26 | |
27 namespace gfx { | |
28 namespace test { | |
29 | |
30 namespace { | |
31 | |
32 bool ColorComponentsClose(SkColor component1, SkColor component2) { | |
33 int c1 = static_cast<int>(component1); | |
34 int c2 = static_cast<int>(component2); | |
35 return std::abs(c1 - c2) <= 40; | |
36 } | |
37 | |
38 bool ColorsClose(SkColor color1, SkColor color2) { | |
39 // Be tolerant of floating point rounding and lossy color space conversions. | |
40 return ColorComponentsClose(SkColorGetR(color1), SkColorGetR(color2)) && | |
41 ColorComponentsClose(SkColorGetG(color1), SkColorGetG(color2)) && | |
42 ColorComponentsClose(SkColorGetB(color1), SkColorGetB(color2)) && | |
43 ColorComponentsClose(SkColorGetA(color1), SkColorGetA(color2)); | |
44 } | |
45 | |
46 } // namespace | |
47 | |
48 std::vector<float> Get1xAnd2xScales() { | |
49 std::vector<float> scales; | |
50 scales.push_back(1.0f); | |
51 scales.push_back(2.0f); | |
52 return scales; | |
53 } | |
54 | |
55 const SkBitmap CreateBitmap(int width, int height) { | |
56 SkBitmap bitmap; | |
57 bitmap.allocN32Pixels(width, height); | |
58 bitmap.eraseARGB(255, 0, 255, 0); | |
59 return bitmap; | |
60 } | |
61 | |
62 gfx::ImageSkia CreateImageSkia(int width, int height) { | |
63 return gfx::ImageSkia::CreateFrom1xBitmap(CreateBitmap(width, height)); | |
64 } | |
65 | |
66 scoped_refptr<base::RefCountedMemory> CreatePNGBytes(int edge_size) { | |
67 SkBitmap bitmap = CreateBitmap(edge_size, edge_size); | |
68 scoped_refptr<base::RefCountedBytes> bytes(new base::RefCountedBytes()); | |
69 PNGCodec::EncodeBGRASkBitmap(bitmap, false, &bytes->data()); | |
70 return bytes; | |
71 } | |
72 | |
73 gfx::Image CreateImage() { | |
74 return CreateImage(100, 50); | |
75 } | |
76 | |
77 gfx::Image CreateImage(int width, int height) { | |
78 return gfx::Image::CreateFrom1xBitmap(CreateBitmap(width, height)); | |
79 } | |
80 | |
81 bool IsEqual(const gfx::Image& img1, const gfx::Image& img2) { | |
82 img1.AsImageSkia().EnsureRepsForSupportedScales(); | |
83 img2.AsImageSkia().EnsureRepsForSupportedScales(); | |
84 std::vector<gfx::ImageSkiaRep> img1_reps = img1.AsImageSkia().image_reps(); | |
85 gfx::ImageSkia image_skia2 = img2.AsImageSkia(); | |
86 if (image_skia2.image_reps().size() != img1_reps.size()) | |
87 return false; | |
88 | |
89 for (size_t i = 0; i < img1_reps.size(); ++i) { | |
90 float scale = img1_reps[i].scale(); | |
91 const gfx::ImageSkiaRep& image_rep2 = image_skia2.GetRepresentation(scale); | |
92 if (image_rep2.scale() != scale || | |
93 !IsEqual(img1_reps[i].sk_bitmap(), image_rep2.sk_bitmap())) { | |
94 return false; | |
95 } | |
96 } | |
97 return true; | |
98 } | |
99 | |
100 bool IsEqual(const SkBitmap& bmp1, const SkBitmap& bmp2) { | |
101 if (bmp1.isNull() && bmp2.isNull()) | |
102 return true; | |
103 | |
104 if (bmp1.width() != bmp2.width() || | |
105 bmp1.height() != bmp2.height() || | |
106 bmp1.colorType() != kN32_SkColorType || | |
107 bmp2.colorType() != kN32_SkColorType) { | |
108 return false; | |
109 } | |
110 | |
111 SkAutoLockPixels lock1(bmp1); | |
112 SkAutoLockPixels lock2(bmp2); | |
113 if (!bmp1.getPixels() || !bmp2.getPixels()) | |
114 return false; | |
115 | |
116 for (int y = 0; y < bmp1.height(); ++y) { | |
117 for (int x = 0; x < bmp1.width(); ++x) { | |
118 if (!ColorsClose(bmp1.getColor(x,y), bmp2.getColor(x,y))) | |
119 return false; | |
120 } | |
121 } | |
122 | |
123 return true; | |
124 } | |
125 | |
126 bool IsEqual(const scoped_refptr<base::RefCountedMemory>& bytes, | |
127 const SkBitmap& bitmap) { | |
128 SkBitmap decoded; | |
129 if (!bytes.get() || | |
130 !PNGCodec::Decode(bytes->front(), bytes->size(), &decoded)) { | |
131 return bitmap.isNull(); | |
132 } | |
133 | |
134 return IsEqual(bitmap, decoded); | |
135 } | |
136 | |
137 void CheckImageIndicatesPNGDecodeFailure(const gfx::Image& image) { | |
138 SkBitmap bitmap = image.AsBitmap(); | |
139 EXPECT_FALSE(bitmap.isNull()); | |
140 EXPECT_LE(16, bitmap.width()); | |
141 EXPECT_LE(16, bitmap.height()); | |
142 SkAutoLockPixels auto_lock(bitmap); | |
143 CheckColors(bitmap.getColor(10, 10), SK_ColorRED); | |
144 } | |
145 | |
146 bool ImageSkiaStructureMatches( | |
147 const gfx::ImageSkia& image_skia, | |
148 int width, | |
149 int height, | |
150 const std::vector<float>& scales) { | |
151 if (image_skia.isNull() || | |
152 image_skia.width() != width || | |
153 image_skia.height() != height || | |
154 image_skia.image_reps().size() != scales.size()) { | |
155 return false; | |
156 } | |
157 | |
158 for (size_t i = 0; i < scales.size(); ++i) { | |
159 gfx::ImageSkiaRep image_rep = | |
160 image_skia.GetRepresentation(scales[i]); | |
161 if (image_rep.is_null() || image_rep.scale() != scales[i]) | |
162 return false; | |
163 | |
164 if (image_rep.pixel_width() != static_cast<int>(width * scales[i]) || | |
165 image_rep.pixel_height() != static_cast<int>(height * scales[i])) { | |
166 return false; | |
167 } | |
168 } | |
169 return true; | |
170 } | |
171 | |
172 bool IsEmpty(const gfx::Image& image) { | |
173 const SkBitmap& bmp = *image.ToSkBitmap(); | |
174 return bmp.isNull() || | |
175 (bmp.width() == 0 && bmp.height() == 0); | |
176 } | |
177 | |
178 PlatformImage CreatePlatformImage() { | |
179 const SkBitmap bitmap(CreateBitmap(25, 25)); | |
180 #if defined(OS_IOS) | |
181 float scale = ImageSkia::GetMaxSupportedScale(); | |
182 | |
183 base::ScopedCFTypeRef<CGColorSpaceRef> color_space( | |
184 CGColorSpaceCreateDeviceRGB()); | |
185 UIImage* image = | |
186 gfx::SkBitmapToUIImageWithColorSpace(bitmap, scale, color_space); | |
187 base::mac::NSObjectRetain(image); | |
188 return image; | |
189 #elif defined(OS_MACOSX) | |
190 NSImage* image = gfx::SkBitmapToNSImage(bitmap); | |
191 base::mac::NSObjectRetain(image); | |
192 return image; | |
193 #else | |
194 return gfx::ImageSkia::CreateFrom1xBitmap(bitmap); | |
195 #endif | |
196 } | |
197 | |
198 gfx::Image::RepresentationType GetPlatformRepresentationType() { | |
199 #if defined(OS_IOS) | |
200 return gfx::Image::kImageRepCocoaTouch; | |
201 #elif defined(OS_MACOSX) | |
202 return gfx::Image::kImageRepCocoa; | |
203 #else | |
204 return gfx::Image::kImageRepSkia; | |
205 #endif | |
206 } | |
207 | |
208 PlatformImage ToPlatformType(const gfx::Image& image) { | |
209 #if defined(OS_IOS) | |
210 return image.ToUIImage(); | |
211 #elif defined(OS_MACOSX) | |
212 return image.ToNSImage(); | |
213 #else | |
214 return image.AsImageSkia(); | |
215 #endif | |
216 } | |
217 | |
218 PlatformImage CopyPlatformType(const gfx::Image& image) { | |
219 #if defined(OS_IOS) | |
220 return image.CopyUIImage(); | |
221 #elif defined(OS_MACOSX) | |
222 return image.CopyNSImage(); | |
223 #else | |
224 return image.AsImageSkia(); | |
225 #endif | |
226 } | |
227 | |
228 #if defined(OS_MACOSX) | |
229 // Defined in image_unittest_util_mac.mm. | |
230 #else | |
231 SkColor GetPlatformImageColor(PlatformImage image, int x, int y) { | |
232 SkBitmap bitmap = *image.bitmap(); | |
233 SkAutoLockPixels auto_lock(bitmap); | |
234 return bitmap.getColor(x, y); | |
235 } | |
236 #endif | |
237 | |
238 void CheckColors(SkColor color1, SkColor color2) { | |
239 EXPECT_TRUE(ColorsClose(color1, color2)); | |
240 } | |
241 | |
242 void CheckIsTransparent(SkColor color) { | |
243 EXPECT_LT(SkColorGetA(color) / 255.0, 0.05); | |
244 } | |
245 | |
246 bool IsPlatformImageValid(PlatformImage image) { | |
247 #if defined(OS_MACOSX) | |
248 return image != NULL; | |
249 #else | |
250 return !image.isNull(); | |
251 #endif | |
252 } | |
253 | |
254 bool PlatformImagesEqual(PlatformImage image1, PlatformImage image2) { | |
255 #if defined(OS_MACOSX) | |
256 return image1 == image2; | |
257 #else | |
258 return image1.BackedBySameObjectAs(image2); | |
259 #endif | |
260 } | |
261 | |
262 } // namespace test | |
263 } // namespace gfx | |
OLD | NEW |