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
.setConfig(SkBitmap::kARGB_8888_Config
, width
, height
);
59 bitmap
.eraseARGB(255, 0, 255, 0);
63 gfx::ImageSkia
CreateImageSkia(int width
, int height
) {
64 return gfx::ImageSkia::CreateFrom1xBitmap(CreateBitmap(width
, height
));
67 scoped_refptr
<base::RefCountedMemory
> CreatePNGBytes(int edge_size
) {
68 SkBitmap bitmap
= CreateBitmap(edge_size
, edge_size
);
69 scoped_refptr
<base::RefCountedBytes
> bytes(new base::RefCountedBytes());
70 PNGCodec::EncodeBGRASkBitmap(bitmap
, false, &bytes
->data());
74 gfx::Image
CreateImage() {
75 return CreateImage(100, 50);
78 gfx::Image
CreateImage(int width
, int height
) {
79 return gfx::Image::CreateFrom1xBitmap(CreateBitmap(width
, height
));
82 bool IsEqual(const gfx::Image
& img1
, const gfx::Image
& img2
) {
83 std::vector
<gfx::ImageSkiaRep
> img1_reps
= img1
.AsImageSkia().image_reps();
84 gfx::ImageSkia image_skia2
= img2
.AsImageSkia();
85 if (image_skia2
.image_reps().size() != img1_reps
.size())
88 for (size_t i
= 0; i
< img1_reps
.size(); ++i
) {
89 float scale
= img1_reps
[i
].scale();
90 const gfx::ImageSkiaRep
& image_rep2
= image_skia2
.GetRepresentation(scale
);
91 if (image_rep2
.scale() != scale
||
92 !IsEqual(img1_reps
[i
].sk_bitmap(), image_rep2
.sk_bitmap())) {
99 bool IsEqual(const SkBitmap
& bmp1
, const SkBitmap
& bmp2
) {
100 if (bmp1
.isNull() && bmp2
.isNull())
103 if (bmp1
.width() != bmp2
.width() ||
104 bmp1
.height() != bmp2
.height() ||
105 bmp1
.config() != SkBitmap::kARGB_8888_Config
||
106 bmp2
.config() != SkBitmap::kARGB_8888_Config
) {
110 SkAutoLockPixels
lock1(bmp1
);
111 SkAutoLockPixels
lock2(bmp2
);
112 if (!bmp1
.getPixels() || !bmp2
.getPixels())
115 for (int y
= 0; y
< bmp1
.height(); ++y
) {
116 for (int x
= 0; x
< bmp1
.width(); ++x
) {
117 if (!ColorsClose(bmp1
.getColor(x
,y
), bmp2
.getColor(x
,y
)))
125 bool IsEqual(const scoped_refptr
<base::RefCountedMemory
>& bytes
,
126 const SkBitmap
& bitmap
) {
129 !PNGCodec::Decode(bytes
->front(), bytes
->size(), &decoded
)) {
130 return bitmap
.isNull();
133 return IsEqual(bitmap
, decoded
);
136 void CheckImageIndicatesPNGDecodeFailure(const gfx::Image
& image
) {
137 SkBitmap bitmap
= image
.AsBitmap();
138 EXPECT_FALSE(bitmap
.isNull());
139 EXPECT_LE(16, bitmap
.width());
140 EXPECT_LE(16, bitmap
.height());
141 SkAutoLockPixels
auto_lock(bitmap
);
142 CheckColors(bitmap
.getColor(10, 10), SK_ColorRED
);
145 bool ImageSkiaStructureMatches(
146 const gfx::ImageSkia
& image_skia
,
149 const std::vector
<float>& scales
) {
150 if (image_skia
.isNull() ||
151 image_skia
.width() != width
||
152 image_skia
.height() != height
||
153 image_skia
.image_reps().size() != scales
.size()) {
157 for (size_t i
= 0; i
< scales
.size(); ++i
) {
158 gfx::ImageSkiaRep image_rep
=
159 image_skia
.GetRepresentation(scales
[i
]);
160 if (image_rep
.is_null() || image_rep
.scale() != scales
[i
])
163 if (image_rep
.pixel_width() != static_cast<int>(width
* scales
[i
]) ||
164 image_rep
.pixel_height() != static_cast<int>(height
* scales
[i
])) {
171 bool IsEmpty(const gfx::Image
& image
) {
172 const SkBitmap
& bmp
= *image
.ToSkBitmap();
173 return bmp
.isNull() ||
174 (bmp
.width() == 0 && bmp
.height() == 0);
177 PlatformImage
CreatePlatformImage() {
178 const SkBitmap
bitmap(CreateBitmap(25, 25));
180 float scale
= ImageSkia::GetMaxSupportedScale();
182 base::ScopedCFTypeRef
<CGColorSpaceRef
> color_space(
183 CGColorSpaceCreateDeviceRGB());
185 gfx::SkBitmapToUIImageWithColorSpace(bitmap
, scale
, color_space
);
186 base::mac::NSObjectRetain(image
);
188 #elif defined(OS_MACOSX)
189 NSImage
* image
= gfx::SkBitmapToNSImage(bitmap
);
190 base::mac::NSObjectRetain(image
);
193 return gfx::ImageSkia::CreateFrom1xBitmap(bitmap
);
197 gfx::Image::RepresentationType
GetPlatformRepresentationType() {
199 return gfx::Image::kImageRepCocoaTouch
;
200 #elif defined(OS_MACOSX)
201 return gfx::Image::kImageRepCocoa
;
203 return gfx::Image::kImageRepSkia
;
207 PlatformImage
ToPlatformType(const gfx::Image
& image
) {
209 return image
.ToUIImage();
210 #elif defined(OS_MACOSX)
211 return image
.ToNSImage();
213 return image
.AsImageSkia();
217 PlatformImage
CopyPlatformType(const gfx::Image
& image
) {
219 return image
.CopyUIImage();
220 #elif defined(OS_MACOSX)
221 return image
.CopyNSImage();
223 return image
.AsImageSkia();
227 #if defined(OS_MACOSX)
228 // Defined in image_unittest_util_mac.mm.
230 SkColor
GetPlatformImageColor(PlatformImage image
, int x
, int y
) {
231 SkBitmap bitmap
= *image
.bitmap();
232 SkAutoLockPixels
auto_lock(bitmap
);
233 return bitmap
.getColor(x
, y
);
237 void CheckColors(SkColor color1
, SkColor color2
) {
238 EXPECT_TRUE(ColorsClose(color1
, color2
));
241 void CheckIsTransparent(SkColor color
) {
242 EXPECT_LT(SkColorGetA(color
) / 255.0, 0.05);
245 bool IsPlatformImageValid(PlatformImage image
) {
246 #if defined(OS_MACOSX)
247 return image
!= NULL
;
249 return !image
.isNull();
253 bool PlatformImagesEqual(PlatformImage image1
, PlatformImage image2
) {
254 #if defined(OS_MACOSX)
255 return image1
== image2
;
257 return image1
.BackedBySameObjectAs(image2
);