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 // Because the unit tests for gfx::Image are spread across multiple
6 // implementation files, this header contains the reusable components.
8 #include "ui/gfx/image/image_unittest_util.h"
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"
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"
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;
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
));
48 std::vector
<float> Get1xAnd2xScales() {
49 std::vector
<float> scales
;
50 scales
.push_back(1.0f
);
51 scales
.push_back(2.0f
);
55 const SkBitmap
CreateBitmap(int width
, int height
) {
57 bitmap
.allocN32Pixels(width
, height
);
58 bitmap
.eraseARGB(255, 0, 255, 0);
62 gfx::ImageSkia
CreateImageSkia(int width
, int height
) {
63 return gfx::ImageSkia::CreateFrom1xBitmap(CreateBitmap(width
, height
));
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());
73 gfx::Image
CreateImage() {
74 return CreateImage(100, 50);
77 gfx::Image
CreateImage(int width
, int height
) {
78 return gfx::Image::CreateFrom1xBitmap(CreateBitmap(width
, height
));
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())
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())) {
100 bool IsEqual(const SkBitmap
& bmp1
, const SkBitmap
& bmp2
) {
101 if (bmp1
.isNull() && bmp2
.isNull())
104 if (bmp1
.width() != bmp2
.width() ||
105 bmp1
.height() != bmp2
.height() ||
106 bmp1
.colorType() != kN32_SkColorType
||
107 bmp2
.colorType() != kN32_SkColorType
) {
111 SkAutoLockPixels
lock1(bmp1
);
112 SkAutoLockPixels
lock2(bmp2
);
113 if (!bmp1
.getPixels() || !bmp2
.getPixels())
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
)))
126 bool IsEqual(const scoped_refptr
<base::RefCountedMemory
>& bytes
,
127 const SkBitmap
& bitmap
) {
130 !PNGCodec::Decode(bytes
->front(), bytes
->size(), &decoded
)) {
131 return bitmap
.isNull();
134 return IsEqual(bitmap
, decoded
);
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
);
146 bool ImageSkiaStructureMatches(
147 const gfx::ImageSkia
& image_skia
,
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()) {
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
])
164 if (image_rep
.pixel_width() != static_cast<int>(width
* scales
[i
]) ||
165 image_rep
.pixel_height() != static_cast<int>(height
* scales
[i
])) {
172 bool IsEmpty(const gfx::Image
& image
) {
173 const SkBitmap
& bmp
= *image
.ToSkBitmap();
174 return bmp
.isNull() ||
175 (bmp
.width() == 0 && bmp
.height() == 0);
178 PlatformImage
CreatePlatformImage() {
179 const SkBitmap
bitmap(CreateBitmap(25, 25));
181 float scale
= ImageSkia::GetMaxSupportedScale();
183 base::ScopedCFTypeRef
<CGColorSpaceRef
> color_space(
184 CGColorSpaceCreateDeviceRGB());
186 gfx::SkBitmapToUIImageWithColorSpace(bitmap
, scale
, color_space
);
187 base::mac::NSObjectRetain(image
);
189 #elif defined(OS_MACOSX)
190 NSImage
* image
= gfx::SkBitmapToNSImage(bitmap
);
191 base::mac::NSObjectRetain(image
);
194 return gfx::ImageSkia::CreateFrom1xBitmap(bitmap
);
198 gfx::Image::RepresentationType
GetPlatformRepresentationType() {
200 return gfx::Image::kImageRepCocoaTouch
;
201 #elif defined(OS_MACOSX)
202 return gfx::Image::kImageRepCocoa
;
204 return gfx::Image::kImageRepSkia
;
208 PlatformImage
ToPlatformType(const gfx::Image
& image
) {
210 return image
.ToUIImage();
211 #elif defined(OS_MACOSX)
212 return image
.ToNSImage();
214 return image
.AsImageSkia();
218 PlatformImage
CopyPlatformType(const gfx::Image
& image
) {
220 return image
.CopyUIImage();
221 #elif defined(OS_MACOSX)
222 return image
.CopyNSImage();
224 return image
.AsImageSkia();
228 #if defined(OS_MACOSX)
229 // Defined in image_unittest_util_mac.mm.
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
);
238 void CheckColors(SkColor color1
, SkColor color2
) {
239 EXPECT_TRUE(ColorsClose(color1
, color2
));
242 void CheckIsTransparent(SkColor color
) {
243 EXPECT_LT(SkColorGetA(color
) / 255.0, 0.05);
246 bool IsPlatformImageValid(PlatformImage image
) {
247 #if defined(OS_MACOSX)
248 return image
!= NULL
;
250 return !image
.isNull();
254 bool PlatformImagesEqual(PlatformImage image1
, PlatformImage image2
) {
255 #if defined(OS_MACOSX)
256 return image1
== image2
;
258 return image1
.BackedBySameObjectAs(image2
);