• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Because the unit tests for gfx::Image are spread across multiple
6 // implementation files, this header contains the reusable components.
7 
8 #include "ui/gfx/image/image_unittest_util.h"
9 
10 #include <cmath>
11 
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"
17 
18 #if defined(OS_IOS)
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"
25 #endif
26 
27 namespace gfx {
28 namespace test {
29 
30 namespace {
31 
ColorComponentsClose(SkColor component1,SkColor component2)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;
36 }
37 
ColorsClose(SkColor color1,SkColor color2)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));
44 }
45 
46 }  // namespace
47 
Get1xAnd2xScales()48 std::vector<float> Get1xAnd2xScales() {
49   std::vector<float> scales;
50   scales.push_back(1.0f);
51   scales.push_back(2.0f);
52   return scales;
53 }
54 
CreateBitmap(int width,int height)55 const SkBitmap CreateBitmap(int width, int height) {
56   SkBitmap bitmap;
57   bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
58   bitmap.allocPixels();
59   bitmap.eraseARGB(255, 0, 255, 0);
60   return bitmap;
61 }
62 
CreateImageSkia(int width,int height)63 gfx::ImageSkia CreateImageSkia(int width, int height) {
64   return gfx::ImageSkia::CreateFrom1xBitmap(CreateBitmap(width, height));
65 }
66 
CreatePNGBytes(int edge_size)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());
71   return bytes;
72 }
73 
CreateImage()74 gfx::Image CreateImage() {
75   return CreateImage(100, 50);
76 }
77 
CreateImage(int width,int height)78 gfx::Image CreateImage(int width, int height) {
79   return gfx::Image::CreateFrom1xBitmap(CreateBitmap(width, height));
80 }
81 
IsEqual(const gfx::Image & img1,const gfx::Image & img2)82 bool IsEqual(const gfx::Image& img1, const gfx::Image& img2) {
83   img1.AsImageSkia().EnsureRepsForSupportedScales();
84   img2.AsImageSkia().EnsureRepsForSupportedScales();
85   std::vector<gfx::ImageSkiaRep> img1_reps = img1.AsImageSkia().image_reps();
86   gfx::ImageSkia image_skia2 = img2.AsImageSkia();
87   if (image_skia2.image_reps().size() != img1_reps.size())
88     return false;
89 
90   for (size_t i = 0; i < img1_reps.size(); ++i) {
91     float scale = img1_reps[i].scale();
92     const gfx::ImageSkiaRep& image_rep2 = image_skia2.GetRepresentation(scale);
93     if (image_rep2.scale() != scale ||
94         !IsEqual(img1_reps[i].sk_bitmap(), image_rep2.sk_bitmap())) {
95       return false;
96     }
97   }
98   return true;
99 }
100 
IsEqual(const SkBitmap & bmp1,const SkBitmap & bmp2)101 bool IsEqual(const SkBitmap& bmp1, const SkBitmap& bmp2) {
102   if (bmp1.isNull() && bmp2.isNull())
103     return true;
104 
105   if (bmp1.width() != bmp2.width() ||
106       bmp1.height() != bmp2.height() ||
107       bmp1.config() != SkBitmap::kARGB_8888_Config ||
108       bmp2.config() != SkBitmap::kARGB_8888_Config) {
109     return false;
110   }
111 
112   SkAutoLockPixels lock1(bmp1);
113   SkAutoLockPixels lock2(bmp2);
114   if (!bmp1.getPixels() || !bmp2.getPixels())
115     return false;
116 
117   for (int y = 0; y < bmp1.height(); ++y) {
118     for (int x = 0; x < bmp1.width(); ++x) {
119       if (!ColorsClose(bmp1.getColor(x,y), bmp2.getColor(x,y)))
120         return false;
121     }
122   }
123 
124   return true;
125 }
126 
IsEqual(const scoped_refptr<base::RefCountedMemory> & bytes,const SkBitmap & bitmap)127 bool IsEqual(const scoped_refptr<base::RefCountedMemory>& bytes,
128              const SkBitmap& bitmap) {
129   SkBitmap decoded;
130   if (!bytes.get() ||
131       !PNGCodec::Decode(bytes->front(), bytes->size(), &decoded)) {
132     return bitmap.isNull();
133   }
134 
135   return IsEqual(bitmap, decoded);
136 }
137 
CheckImageIndicatesPNGDecodeFailure(const gfx::Image & image)138 void CheckImageIndicatesPNGDecodeFailure(const gfx::Image& image) {
139   SkBitmap bitmap = image.AsBitmap();
140   EXPECT_FALSE(bitmap.isNull());
141   EXPECT_LE(16, bitmap.width());
142   EXPECT_LE(16, bitmap.height());
143   SkAutoLockPixels auto_lock(bitmap);
144   CheckColors(bitmap.getColor(10, 10), SK_ColorRED);
145 }
146 
ImageSkiaStructureMatches(const gfx::ImageSkia & image_skia,int width,int height,const std::vector<float> & scales)147 bool ImageSkiaStructureMatches(
148     const gfx::ImageSkia& image_skia,
149     int width,
150     int height,
151     const std::vector<float>& scales) {
152   if (image_skia.isNull() ||
153       image_skia.width() != width ||
154       image_skia.height() != height ||
155       image_skia.image_reps().size() != scales.size()) {
156     return false;
157   }
158 
159   for (size_t i = 0; i < scales.size(); ++i) {
160     gfx::ImageSkiaRep image_rep =
161         image_skia.GetRepresentation(scales[i]);
162     if (image_rep.is_null() || image_rep.scale() != scales[i])
163       return false;
164 
165     if (image_rep.pixel_width() != static_cast<int>(width * scales[i]) ||
166         image_rep.pixel_height() != static_cast<int>(height * scales[i])) {
167       return false;
168     }
169   }
170   return true;
171 }
172 
IsEmpty(const gfx::Image & image)173 bool IsEmpty(const gfx::Image& image) {
174   const SkBitmap& bmp = *image.ToSkBitmap();
175   return bmp.isNull() ||
176          (bmp.width() == 0 && bmp.height() == 0);
177 }
178 
CreatePlatformImage()179 PlatformImage CreatePlatformImage() {
180   const SkBitmap bitmap(CreateBitmap(25, 25));
181 #if defined(OS_IOS)
182   float scale = ImageSkia::GetMaxSupportedScale();
183 
184   base::ScopedCFTypeRef<CGColorSpaceRef> color_space(
185       CGColorSpaceCreateDeviceRGB());
186   UIImage* image =
187       gfx::SkBitmapToUIImageWithColorSpace(bitmap, scale, color_space);
188   base::mac::NSObjectRetain(image);
189   return image;
190 #elif defined(OS_MACOSX)
191   NSImage* image = gfx::SkBitmapToNSImage(bitmap);
192   base::mac::NSObjectRetain(image);
193   return image;
194 #else
195   return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
196 #endif
197 }
198 
GetPlatformRepresentationType()199 gfx::Image::RepresentationType GetPlatformRepresentationType() {
200 #if defined(OS_IOS)
201   return gfx::Image::kImageRepCocoaTouch;
202 #elif defined(OS_MACOSX)
203   return gfx::Image::kImageRepCocoa;
204 #else
205   return gfx::Image::kImageRepSkia;
206 #endif
207 }
208 
ToPlatformType(const gfx::Image & image)209 PlatformImage ToPlatformType(const gfx::Image& image) {
210 #if defined(OS_IOS)
211   return image.ToUIImage();
212 #elif defined(OS_MACOSX)
213   return image.ToNSImage();
214 #else
215   return image.AsImageSkia();
216 #endif
217 }
218 
CopyPlatformType(const gfx::Image & image)219 PlatformImage CopyPlatformType(const gfx::Image& image) {
220 #if defined(OS_IOS)
221   return image.CopyUIImage();
222 #elif defined(OS_MACOSX)
223   return image.CopyNSImage();
224 #else
225   return image.AsImageSkia();
226 #endif
227 }
228 
229 #if defined(OS_MACOSX)
230 // Defined in image_unittest_util_mac.mm.
231 #else
GetPlatformImageColor(PlatformImage image,int x,int y)232 SkColor GetPlatformImageColor(PlatformImage image, int x, int y) {
233   SkBitmap bitmap = *image.bitmap();
234   SkAutoLockPixels auto_lock(bitmap);
235   return bitmap.getColor(x, y);
236 }
237 #endif
238 
CheckColors(SkColor color1,SkColor color2)239 void CheckColors(SkColor color1, SkColor color2) {
240   EXPECT_TRUE(ColorsClose(color1, color2));
241 }
242 
CheckIsTransparent(SkColor color)243 void CheckIsTransparent(SkColor color) {
244   EXPECT_LT(SkColorGetA(color) / 255.0, 0.05);
245 }
246 
IsPlatformImageValid(PlatformImage image)247 bool IsPlatformImageValid(PlatformImage image) {
248 #if defined(OS_MACOSX)
249   return image != NULL;
250 #else
251   return !image.isNull();
252 #endif
253 }
254 
PlatformImagesEqual(PlatformImage image1,PlatformImage image2)255 bool PlatformImagesEqual(PlatformImage image1, PlatformImage image2) {
256 #if defined(OS_MACOSX)
257   return image1 == image2;
258 #else
259   return image1.BackedBySameObjectAs(image2);
260 #endif
261 }
262 
263 }  // namespace test
264 }  // namespace gfx
265