select_favicon_frames_unittest.cc 10 KB

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