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.
5 #include "components/favicon_base/select_favicon_frames.h"
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"
17 const ui::ScaleFactor FaviconScaleFactor1x
[] = {
18 ui::SCALE_FACTOR_100P
,
21 const ui::ScaleFactor FaviconScaleFactor1xAnd2x
[] = {
22 ui::SCALE_FACTOR_100P
,
23 ui::SCALE_FACTOR_200P
,
26 #define SCOPED_FAVICON_SCALE_FACTOR(list) \
27 ui::test::ScopedSetSupportedScaleFactors scoped( \
28 std::vector<ui::ScaleFactor>(list, list + arraysize(list)))
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)
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()));
43 SkBitmap
MakeBitmap(SkColor color
, int w
, int h
) {
45 bitmap
.allocN32Pixels(w
, h
);
46 bitmap
.eraseColor(color
);
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();
55 x
= bitmap
.width() / 2;
57 y
= bitmap
.width() / 2;
59 SkColor color
= bitmap
.getColor(x
, y
);
60 bitmap
.unlockPixels();
64 SkColor
GetColor1x(const gfx::ImageSkia
& image
) {
65 return GetColor(image
, 1.0f
);
68 SkColor
GetColor2x(const gfx::ImageSkia
& image
) {
69 return GetColor(image
, 2.0f
);
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));
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());
85 EXPECT_EQ(SK_ColorGREEN
, GetColor1x(image
));
88 TEST(SelectFaviconFramesTest
, _16From16
) {
89 SCOPED_FAVICON_SCALE_FACTOR_1X
;
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));
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
));
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());
116 TEST(SelectFaviconFramesTest
, _16From17
) {
117 SCOPED_FAVICON_SCALE_FACTOR_1X
;
119 vector
<SkBitmap
> bitmaps
;
120 bitmaps
.push_back(MakeBitmap(SK_ColorRED
, 15, 15));
121 bitmaps
.push_back(MakeBitmap(SK_ColorGREEN
, 17, 17));
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
));
134 TEST(SelectFaviconFramesTest
, _16From15
) {
135 SCOPED_FAVICON_SCALE_FACTOR_1X
;
137 vector
<SkBitmap
> bitmaps
;
138 bitmaps
.push_back(MakeBitmap(SK_ColorRED
, 14, 14));
139 bitmaps
.push_back(MakeBitmap(SK_ColorGREEN
, 15, 15));
141 // If nothing else is available, should resample from the next smaller
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
));
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));
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
));
170 TEST(SelectFaviconFramesTest
, _16From16_Scale2x_32_From_32
) {
171 SCOPED_FAVICON_SCALE_FACTOR_1XAND2X
;
173 vector
<SkBitmap
> bitmaps
;
174 bitmaps
.push_back(MakeBitmap(SK_ColorGREEN
, 16, 16));
175 bitmaps
.push_back(MakeBitmap(SK_ColorBLUE
, 32, 32));
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
));
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());
199 TEST(SelectFaviconFramesTest
, ExactMatchBetterThanLargeBitmap
) {
200 SCOPED_FAVICON_SCALE_FACTOR_1XAND2X
;
203 vector
<SkBitmap
> bitmaps1
;
204 bitmaps1
.push_back(MakeBitmap(SK_ColorGREEN
, 48, 48));
205 CreateFaviconImageSkia(
207 SizesFromBitmaps(bitmaps1
), 16, &score1
);
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
);
216 EXPECT_GT(score2
, score1
);
219 TEST(SelectFaviconFramesTest
, UpsampleABitBetterThanHugeBitmap
) {
220 SCOPED_FAVICON_SCALE_FACTOR_1XAND2X
;
223 vector
<SkBitmap
> bitmaps1
;
224 bitmaps1
.push_back(MakeBitmap(SK_ColorGREEN
, 128, 128));
225 CreateFaviconImageSkia(bitmaps1
,
226 SizesFromBitmaps(bitmaps1
), 16, &score1
);
229 vector
<SkBitmap
> bitmaps2
;
230 bitmaps2
.push_back(MakeBitmap(SK_ColorGREEN
, 24, 24));
231 CreateFaviconImageSkia(bitmaps2
,
232 SizesFromBitmaps(bitmaps2
), 16, &score2
);
235 vector
<SkBitmap
> bitmaps3
;
236 bitmaps3
.push_back(MakeBitmap(SK_ColorGREEN
, 16, 16));
237 CreateFaviconImageSkia(bitmaps3
,
238 SizesFromBitmaps(bitmaps3
), 16, &score3
);
241 vector
<SkBitmap
> bitmaps4
;
242 bitmaps4
.push_back(MakeBitmap(SK_ColorGREEN
, 15, 15));
243 CreateFaviconImageSkia(bitmaps4
,
244 SizesFromBitmaps(bitmaps4
), 16, &score4
);
246 EXPECT_GT(score2
, score1
);
247 EXPECT_GT(score3
, score1
);
248 EXPECT_GT(score4
, score1
);
251 TEST(SelectFaviconFramesTest
, DownsamplingBetterThanUpsampling
) {
252 SCOPED_FAVICON_SCALE_FACTOR_1XAND2X
;
255 vector
<SkBitmap
> bitmaps1
;
256 bitmaps1
.push_back(MakeBitmap(SK_ColorGREEN
, 8, 8));
257 CreateFaviconImageSkia(bitmaps1
,
258 SizesFromBitmaps(bitmaps1
), 16, &score1
);
261 vector
<SkBitmap
> bitmaps2
;
262 bitmaps2
.push_back(MakeBitmap(SK_ColorGREEN
, 24, 24));
263 CreateFaviconImageSkia(bitmaps2
,
264 SizesFromBitmaps(bitmaps2
), 16, &score2
);
266 EXPECT_GT(score2
, score1
);
269 TEST(SelectFaviconFramesTest
, DownsamplingLessIsBetter
) {
270 SCOPED_FAVICON_SCALE_FACTOR_1XAND2X
;
273 vector
<SkBitmap
> bitmaps1
;
274 bitmaps1
.push_back(MakeBitmap(SK_ColorGREEN
, 34, 34));
275 CreateFaviconImageSkia(bitmaps1
,
276 SizesFromBitmaps(bitmaps1
), 16, &score1
);
279 vector
<SkBitmap
> bitmaps2
;
280 bitmaps2
.push_back(MakeBitmap(SK_ColorGREEN
, 33, 33));
281 CreateFaviconImageSkia(bitmaps2
,
282 SizesFromBitmaps(bitmaps2
), 16, &score2
);
284 EXPECT_GT(score2
, score1
);
287 TEST(SelectFaviconFramesTest
, UpsamplingLessIsBetter
) {
288 SCOPED_FAVICON_SCALE_FACTOR_1XAND2X
;
291 vector
<SkBitmap
> bitmaps1
;
292 bitmaps1
.push_back(MakeBitmap(SK_ColorGREEN
, 8, 8));
293 CreateFaviconImageSkia(bitmaps1
,
294 SizesFromBitmaps(bitmaps1
), 16, &score1
);
297 vector
<SkBitmap
> bitmaps2
;
298 bitmaps2
.push_back(MakeBitmap(SK_ColorGREEN
, 9, 9));
299 CreateFaviconImageSkia(bitmaps2
,
300 SizesFromBitmaps(bitmaps2
), 16, &score2
);
302 EXPECT_GT(score2
, score1
);
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
;
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));
315 CreateFaviconImageSkia(bitmaps1
, sizes1
, 16, &score1
);
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));
322 CreateFaviconImageSkia(bitmaps2
, sizes2
, 16, &score2
);
324 EXPECT_GT(score2
, score1
);