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 13using std::vector; 14 15namespace { 16 17const ui::ScaleFactor FaviconScaleFactor1x[] = { 18 ui::SCALE_FACTOR_100P, 19}; 20 21const 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|. 36vector<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 43SkBitmap MakeBitmap(SkColor color, int w, int h) { 44 SkBitmap bitmap; 45 bitmap.allocN32Pixels(w, h); 46 bitmap.eraseColor(color); 47 return bitmap; 48} 49 50SkColor 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 64SkColor GetColor1x(const gfx::ImageSkia& image) { 65 return GetColor(image, 1.0f); 66} 67 68SkColor GetColor2x(const gfx::ImageSkia& image) { 69 return GetColor(image, 2.0f); 70} 71 72TEST(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 88TEST(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 116TEST(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 134TEST(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 153TEST(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 170TEST(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 199TEST(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 219TEST(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 251TEST(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 269TEST(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 287TEST(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(). 307TEST(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 328