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 #include "components/favicon_base/select_favicon_frames.h" | |
6 | |
7 #include "testing/gtest/include/gtest/gtest.h" | |
8 #include "third_party/skia/include/core/SkBitmap.h" | |
9 #include "third_party/skia/include/core/SkColor.h" | |
10 #include "ui/base/layout.h" | |
11 #include "ui/gfx/image/image_skia.h" | |
12 | |
13 using std::vector; | |
14 | |
15 namespace { | |
16 | |
17 const ui::ScaleFactor FaviconScaleFactor1x[] = { | |
18 ui::SCALE_FACTOR_100P, | |
19 }; | |
20 | |
21 const ui::ScaleFactor FaviconScaleFactor1xAnd2x[] = { | |
22 ui::SCALE_FACTOR_100P, | |
23 ui::SCALE_FACTOR_200P, | |
24 }; | |
25 | |
26 #define SCOPED_FAVICON_SCALE_FACTOR(list) \ | |
27 ui::test::ScopedSetSupportedScaleFactors scoped( \ | |
28 std::vector<ui::ScaleFactor>(list, list + arraysize(list))) | |
29 | |
30 #define SCOPED_FAVICON_SCALE_FACTOR_1X \ | |
31 SCOPED_FAVICON_SCALE_FACTOR(FaviconScaleFactor1x) | |
32 #define SCOPED_FAVICON_SCALE_FACTOR_1XAND2X \ | |
33 SCOPED_FAVICON_SCALE_FACTOR(FaviconScaleFactor1xAnd2x) | |
34 | |
35 // Return gfx::Size vector with the pixel sizes of |bitmaps|. | |
36 vector<gfx::Size> SizesFromBitmaps(const vector<SkBitmap>& bitmaps) { | |
37 vector<gfx::Size> sizes; | |
38 for (size_t i = 0; i < bitmaps.size(); ++i) | |
39 sizes.push_back(gfx::Size(bitmaps[i].width(), bitmaps[i].height())); | |
40 return sizes; | |
41 } | |
42 | |
43 SkBitmap MakeBitmap(SkColor color, int w, int h) { | |
44 SkBitmap bitmap; | |
45 bitmap.allocN32Pixels(w, h); | |
46 bitmap.eraseColor(color); | |
47 return bitmap; | |
48 } | |
49 | |
50 SkColor GetColor(const gfx::ImageSkia& image, float scale, | |
51 int x = -1, int y = -1) { | |
52 const SkBitmap& bitmap = | |
53 image.GetRepresentation(scale).sk_bitmap(); | |
54 if (x == -1) | |
55 x = bitmap.width() / 2; | |
56 if (y == -1) | |
57 y = bitmap.width() / 2; | |
58 bitmap.lockPixels(); | |
59 SkColor color = bitmap.getColor(x, y); | |
60 bitmap.unlockPixels(); | |
61 return color; | |
62 } | |
63 | |
64 SkColor GetColor1x(const gfx::ImageSkia& image) { | |
65 return GetColor(image, 1.0f); | |
66 } | |
67 | |
68 SkColor GetColor2x(const gfx::ImageSkia& image) { | |
69 return GetColor(image, 2.0f); | |
70 } | |
71 | |
72 TEST(SelectFaviconFramesTest, ZeroSizePicksLargest) { | |
73 vector<SkBitmap> bitmaps; | |
74 bitmaps.push_back(MakeBitmap(SK_ColorRED, 16, 16)); | |
75 bitmaps.push_back(MakeBitmap(SK_ColorGREEN, 48, 48)); | |
76 bitmaps.push_back(MakeBitmap(SK_ColorBLUE, 32, 32)); | |
77 | |
78 gfx::ImageSkia image = CreateFaviconImageSkia(bitmaps, | |
79 SizesFromBitmaps(bitmaps), 0, NULL); | |
80 EXPECT_EQ(1u, image.image_reps().size()); | |
81 ASSERT_TRUE(image.HasRepresentation(1.0f)); | |
82 EXPECT_EQ(48, image.width()); | |
83 EXPECT_EQ(48, image.height()); | |
84 | |
85 EXPECT_EQ(SK_ColorGREEN, GetColor1x(image)); | |
86 } | |
87 | |
88 TEST(SelectFaviconFramesTest, _16From16) { | |
89 SCOPED_FAVICON_SCALE_FACTOR_1X; | |
90 | |
91 vector<SkBitmap> bitmaps; | |
92 bitmaps.push_back(MakeBitmap(SK_ColorRED, 15, 15)); | |
93 bitmaps.push_back(MakeBitmap(SK_ColorGREEN, 16, 16)); | |
94 bitmaps.push_back(MakeBitmap(SK_ColorBLUE, 17, 17)); | |
95 | |
96 gfx::ImageSkia image = CreateFaviconImageSkia(bitmaps, | |
97 SizesFromBitmaps(bitmaps), 16, NULL); | |
98 image.EnsureRepsForSupportedScales(); | |
99 EXPECT_EQ(1u, image.image_reps().size()); | |
100 ASSERT_TRUE(image.HasRepresentation(1.0f)); | |
101 EXPECT_EQ(16, image.width()); | |
102 EXPECT_EQ(16, image.height()); | |
103 EXPECT_EQ(SK_ColorGREEN, GetColor1x(image)); | |
104 | |
105 #if !defined(OS_IOS) | |
106 const gfx::ImageSkiaRep& rep = image.GetRepresentation(1.5f); | |
107 EXPECT_EQ(1.5f, rep.scale()); | |
108 EXPECT_EQ(16, rep.GetWidth()); | |
109 EXPECT_EQ(16, rep.GetHeight()); | |
110 EXPECT_EQ(24, rep.pixel_width()); | |
111 EXPECT_EQ(24, rep.pixel_height()); | |
112 EXPECT_EQ(2u, image.image_reps().size()); | |
113 #endif | |
114 } | |
115 | |
116 TEST(SelectFaviconFramesTest, _16From17) { | |
117 SCOPED_FAVICON_SCALE_FACTOR_1X; | |
118 | |
119 vector<SkBitmap> bitmaps; | |
120 bitmaps.push_back(MakeBitmap(SK_ColorRED, 15, 15)); | |
121 bitmaps.push_back(MakeBitmap(SK_ColorGREEN, 17, 17)); | |
122 | |
123 // Should resample from the bigger candidate. | |
124 gfx::ImageSkia image = CreateFaviconImageSkia(bitmaps, | |
125 SizesFromBitmaps(bitmaps), 16, NULL); | |
126 image.EnsureRepsForSupportedScales(); | |
127 EXPECT_EQ(1u, image.image_reps().size()); | |
128 ASSERT_TRUE(image.HasRepresentation(1.0f)); | |
129 EXPECT_EQ(16, image.width()); | |
130 EXPECT_EQ(16, image.height()); | |
131 EXPECT_EQ(SK_ColorGREEN, GetColor1x(image)); | |
132 } | |
133 | |
134 TEST(SelectFaviconFramesTest, _16From15) { | |
135 SCOPED_FAVICON_SCALE_FACTOR_1X; | |
136 | |
137 vector<SkBitmap> bitmaps; | |
138 bitmaps.push_back(MakeBitmap(SK_ColorRED, 14, 14)); | |
139 bitmaps.push_back(MakeBitmap(SK_ColorGREEN, 15, 15)); | |
140 | |
141 // If nothing else is available, should resample from the next smaller | |
142 // candidate. | |
143 gfx::ImageSkia image = CreateFaviconImageSkia(bitmaps, | |
144 SizesFromBitmaps(bitmaps), 16, NULL); | |
145 image.EnsureRepsForSupportedScales(); | |
146 EXPECT_EQ(1u, image.image_reps().size()); | |
147 ASSERT_TRUE(image.HasRepresentation(1.0f)); | |
148 EXPECT_EQ(16, image.width()); | |
149 EXPECT_EQ(16, image.height()); | |
150 EXPECT_EQ(SK_ColorGREEN, GetColor1x(image)); | |
151 } | |
152 | |
153 TEST(SelectFaviconFramesTest, _16From16_Scale2x_32_From_16) { | |
154 SCOPED_FAVICON_SCALE_FACTOR_1XAND2X; | |
155 vector<SkBitmap> bitmaps; | |
156 bitmaps.push_back(MakeBitmap(SK_ColorGREEN, 16, 16)); | |
157 | |
158 gfx::ImageSkia image = CreateFaviconImageSkia(bitmaps, | |
159 SizesFromBitmaps(bitmaps), 16, NULL); | |
160 image.EnsureRepsForSupportedScales(); | |
161 EXPECT_EQ(2u, image.image_reps().size()); | |
162 ASSERT_TRUE(image.HasRepresentation(1.0f)); | |
163 ASSERT_TRUE(image.HasRepresentation(2.0f)); | |
164 EXPECT_EQ(16, image.width()); | |
165 EXPECT_EQ(16, image.height()); | |
166 EXPECT_EQ(SK_ColorGREEN, GetColor1x(image)); | |
167 EXPECT_EQ(SK_ColorGREEN, GetColor2x(image)); | |
168 } | |
169 | |
170 TEST(SelectFaviconFramesTest, _16From16_Scale2x_32_From_32) { | |
171 SCOPED_FAVICON_SCALE_FACTOR_1XAND2X; | |
172 | |
173 vector<SkBitmap> bitmaps; | |
174 bitmaps.push_back(MakeBitmap(SK_ColorGREEN, 16, 16)); | |
175 bitmaps.push_back(MakeBitmap(SK_ColorBLUE, 32, 32)); | |
176 | |
177 gfx::ImageSkia image = CreateFaviconImageSkia(bitmaps, | |
178 SizesFromBitmaps(bitmaps), 16, NULL); | |
179 image.EnsureRepsForSupportedScales(); | |
180 EXPECT_EQ(2u, image.image_reps().size()); | |
181 ASSERT_TRUE(image.HasRepresentation(1.0f)); | |
182 ASSERT_TRUE(image.HasRepresentation(2.0f)); | |
183 EXPECT_EQ(16, image.width()); | |
184 EXPECT_EQ(16, image.height()); | |
185 EXPECT_EQ(SK_ColorGREEN, GetColor1x(image)); | |
186 EXPECT_EQ(SK_ColorBLUE, GetColor2x(image)); | |
187 | |
188 #if !defined(OS_IOS) | |
189 const gfx::ImageSkiaRep& rep = image.GetRepresentation(1.5f); | |
190 EXPECT_EQ(1.5f, rep.scale()); | |
191 EXPECT_EQ(16, rep.GetWidth()); | |
192 EXPECT_EQ(16, rep.GetHeight()); | |
193 EXPECT_EQ(24, rep.pixel_width()); | |
194 EXPECT_EQ(24, rep.pixel_height()); | |
195 EXPECT_EQ(3u, image.image_reps().size()); | |
196 #endif | |
197 } | |
198 | |
199 TEST(SelectFaviconFramesTest, ExactMatchBetterThanLargeBitmap) { | |
200 SCOPED_FAVICON_SCALE_FACTOR_1XAND2X; | |
201 | |
202 float score1; | |
203 vector<SkBitmap> bitmaps1; | |
204 bitmaps1.push_back(MakeBitmap(SK_ColorGREEN, 48, 48)); | |
205 CreateFaviconImageSkia( | |
206 bitmaps1, | |
207 SizesFromBitmaps(bitmaps1), 16, &score1); | |
208 | |
209 float score2; | |
210 vector<SkBitmap> bitmaps2; | |
211 bitmaps2.push_back(MakeBitmap(SK_ColorGREEN, 16, 16)); | |
212 bitmaps2.push_back(MakeBitmap(SK_ColorGREEN, 32, 32)); | |
213 CreateFaviconImageSkia(bitmaps2, | |
214 SizesFromBitmaps(bitmaps2), 16, &score2); | |
215 | |
216 EXPECT_GT(score2, score1); | |
217 } | |
218 | |
219 TEST(SelectFaviconFramesTest, UpsampleABitBetterThanHugeBitmap) { | |
220 SCOPED_FAVICON_SCALE_FACTOR_1XAND2X; | |
221 | |
222 float score1; | |
223 vector<SkBitmap> bitmaps1; | |
224 bitmaps1.push_back(MakeBitmap(SK_ColorGREEN, 128, 128)); | |
225 CreateFaviconImageSkia(bitmaps1, | |
226 SizesFromBitmaps(bitmaps1), 16, &score1); | |
227 | |
228 float score2; | |
229 vector<SkBitmap> bitmaps2; | |
230 bitmaps2.push_back(MakeBitmap(SK_ColorGREEN, 24, 24)); | |
231 CreateFaviconImageSkia(bitmaps2, | |
232 SizesFromBitmaps(bitmaps2), 16, &score2); | |
233 | |
234 float score3; | |
235 vector<SkBitmap> bitmaps3; | |
236 bitmaps3.push_back(MakeBitmap(SK_ColorGREEN, 16, 16)); | |
237 CreateFaviconImageSkia(bitmaps3, | |
238 SizesFromBitmaps(bitmaps3), 16, &score3); | |
239 | |
240 float score4; | |
241 vector<SkBitmap> bitmaps4; | |
242 bitmaps4.push_back(MakeBitmap(SK_ColorGREEN, 15, 15)); | |
243 CreateFaviconImageSkia(bitmaps4, | |
244 SizesFromBitmaps(bitmaps4), 16, &score4); | |
245 | |
246 EXPECT_GT(score2, score1); | |
247 EXPECT_GT(score3, score1); | |
248 EXPECT_GT(score4, score1); | |
249 } | |
250 | |
251 TEST(SelectFaviconFramesTest, DownsamplingBetterThanUpsampling) { | |
252 SCOPED_FAVICON_SCALE_FACTOR_1XAND2X; | |
253 | |
254 float score1; | |
255 vector<SkBitmap> bitmaps1; | |
256 bitmaps1.push_back(MakeBitmap(SK_ColorGREEN, 8, 8)); | |
257 CreateFaviconImageSkia(bitmaps1, | |
258 SizesFromBitmaps(bitmaps1), 16, &score1); | |
259 | |
260 float score2; | |
261 vector<SkBitmap> bitmaps2; | |
262 bitmaps2.push_back(MakeBitmap(SK_ColorGREEN, 24, 24)); | |
263 CreateFaviconImageSkia(bitmaps2, | |
264 SizesFromBitmaps(bitmaps2), 16, &score2); | |
265 | |
266 EXPECT_GT(score2, score1); | |
267 } | |
268 | |
269 TEST(SelectFaviconFramesTest, DownsamplingLessIsBetter) { | |
270 SCOPED_FAVICON_SCALE_FACTOR_1XAND2X; | |
271 | |
272 float score1; | |
273 vector<SkBitmap> bitmaps1; | |
274 bitmaps1.push_back(MakeBitmap(SK_ColorGREEN, 34, 34)); | |
275 CreateFaviconImageSkia(bitmaps1, | |
276 SizesFromBitmaps(bitmaps1), 16, &score1); | |
277 | |
278 float score2; | |
279 vector<SkBitmap> bitmaps2; | |
280 bitmaps2.push_back(MakeBitmap(SK_ColorGREEN, 33, 33)); | |
281 CreateFaviconImageSkia(bitmaps2, | |
282 SizesFromBitmaps(bitmaps2), 16, &score2); | |
283 | |
284 EXPECT_GT(score2, score1); | |
285 } | |
286 | |
287 TEST(SelectFaviconFramesTest, UpsamplingLessIsBetter) { | |
288 SCOPED_FAVICON_SCALE_FACTOR_1XAND2X; | |
289 | |
290 float score1; | |
291 vector<SkBitmap> bitmaps1; | |
292 bitmaps1.push_back(MakeBitmap(SK_ColorGREEN, 8, 8)); | |
293 CreateFaviconImageSkia(bitmaps1, | |
294 SizesFromBitmaps(bitmaps1), 16, &score1); | |
295 | |
296 float score2; | |
297 vector<SkBitmap> bitmaps2; | |
298 bitmaps2.push_back(MakeBitmap(SK_ColorGREEN, 9, 9)); | |
299 CreateFaviconImageSkia(bitmaps2, | |
300 SizesFromBitmaps(bitmaps2), 16, &score2); | |
301 | |
302 EXPECT_GT(score2, score1); | |
303 } | |
304 | |
305 // Test that the score is determined by the |original_sizes| parameter, not the | |
306 // |bitmaps| parameter to SelectFaviconFrames(). | |
307 TEST(SelectFaviconFramesTest, ScoreDeterminedByOriginalSizes) { | |
308 SCOPED_FAVICON_SCALE_FACTOR_1XAND2X; | |
309 | |
310 vector<SkBitmap> bitmaps1; | |
311 bitmaps1.push_back(MakeBitmap(SK_ColorGREEN, 16, 16)); | |
312 vector<gfx::Size> sizes1; | |
313 sizes1.push_back(gfx::Size(256, 256)); | |
314 float score1; | |
315 CreateFaviconImageSkia(bitmaps1, sizes1, 16, &score1); | |
316 | |
317 vector<SkBitmap> bitmaps2; | |
318 bitmaps2.push_back(MakeBitmap(SK_ColorGREEN, 15, 15)); | |
319 vector<gfx::Size> sizes2; | |
320 sizes2.push_back(gfx::Size(15, 15)); | |
321 float score2; | |
322 CreateFaviconImageSkia(bitmaps2, sizes2, 16, &score2); | |
323 | |
324 EXPECT_GT(score2, score1); | |
325 } | |
326 | |
327 } // namespace | |
OLD | NEW |