image_unittest_util.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
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(TOOLKIT_GTK) 19#include <gtk/gtk.h> 20#include "ui/gfx/gtk_util.h" 21#elif defined(OS_IOS) 22#include "base/mac/foundation_util.h" 23#include "base/mac/scoped_cftyperef.h" 24#include "skia/ext/skia_utils_ios.h" 25#elif defined(OS_MACOSX) 26#include "base/mac/mac_util.h" 27#include "skia/ext/skia_utils_mac.h" 28#endif 29 30namespace gfx { 31namespace test { 32 33namespace { 34 35bool ColorComponentsClose(SkColor component1, SkColor component2) { 36 int c1 = static_cast<int>(component1); 37 int c2 = static_cast<int>(component2); 38 return std::abs(c1 - c2) <= 40; 39} 40 41bool ColorsClose(SkColor color1, SkColor color2) { 42 // Be tolerant of floating point rounding and lossy color space conversions. 43 return ColorComponentsClose(SkColorGetR(color1), SkColorGetR(color2)) && 44 ColorComponentsClose(SkColorGetG(color1), SkColorGetG(color2)) && 45 ColorComponentsClose(SkColorGetB(color1), SkColorGetB(color2)) && 46 ColorComponentsClose(SkColorGetA(color1), SkColorGetA(color2)); 47} 48 49} // namespace 50 51std::vector<float> Get1xAnd2xScales() { 52 std::vector<float> scales; 53 scales.push_back(1.0f); 54 scales.push_back(2.0f); 55 return scales; 56} 57 58const SkBitmap CreateBitmap(int width, int height) { 59 SkBitmap bitmap; 60 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); 61 bitmap.allocPixels(); 62 bitmap.eraseRGB(0, 255, 0); 63 return bitmap; 64} 65 66gfx::ImageSkia CreateImageSkia(int width, int height) { 67 return gfx::ImageSkia::CreateFrom1xBitmap(CreateBitmap(width, height)); 68} 69 70scoped_refptr<base::RefCountedMemory> CreatePNGBytes(int edge_size) { 71 SkBitmap bitmap = CreateBitmap(edge_size, edge_size); 72 scoped_refptr<base::RefCountedBytes> bytes(new base::RefCountedBytes()); 73 PNGCodec::EncodeBGRASkBitmap(bitmap, false, &bytes->data()); 74 return bytes; 75} 76 77gfx::Image CreateImage() { 78 return CreateImage(100, 50); 79} 80 81gfx::Image CreateImage(int width, int height) { 82 return gfx::Image::CreateFrom1xBitmap(CreateBitmap(width, height)); 83} 84 85bool IsEqual(const gfx::Image& img1, const gfx::Image& img2) { 86 std::vector<gfx::ImageSkiaRep> img1_reps = img1.AsImageSkia().image_reps(); 87 gfx::ImageSkia image_skia2 = img2.AsImageSkia(); 88 if (image_skia2.image_reps().size() != img1_reps.size()) 89 return false; 90 91 for (size_t i = 0; i < img1_reps.size(); ++i) { 92 float scale = img1_reps[i].scale(); 93 const gfx::ImageSkiaRep& image_rep2 = image_skia2.GetRepresentation(scale); 94 if (image_rep2.scale() != scale || 95 !IsEqual(img1_reps[i].sk_bitmap(), image_rep2.sk_bitmap())) { 96 return false; 97 } 98 } 99 return true; 100} 101 102bool IsEqual(const SkBitmap& bmp1, const SkBitmap& bmp2) { 103 if (bmp1.isNull() && bmp2.isNull()) 104 return true; 105 106 if (bmp1.width() != bmp2.width() || 107 bmp1.height() != bmp2.height() || 108 bmp1.config() != SkBitmap::kARGB_8888_Config || 109 bmp2.config() != SkBitmap::kARGB_8888_Config) { 110 return false; 111 } 112 113 SkAutoLockPixels lock1(bmp1); 114 SkAutoLockPixels lock2(bmp2); 115 if (!bmp1.getPixels() || !bmp2.getPixels()) 116 return false; 117 118 for (int y = 0; y < bmp1.height(); ++y) { 119 for (int x = 0; x < bmp1.width(); ++x) { 120 if (!ColorsClose(bmp1.getColor(x,y), bmp2.getColor(x,y))) 121 return false; 122 } 123 } 124 125 return true; 126} 127 128bool IsEqual(const scoped_refptr<base::RefCountedMemory>& bytes, 129 const SkBitmap& bitmap) { 130 SkBitmap decoded; 131 if (!bytes.get() || 132 !PNGCodec::Decode(bytes->front(), bytes->size(), &decoded)) { 133 return bitmap.isNull(); 134 } 135 136 return IsEqual(bitmap, decoded); 137} 138 139void CheckImageIndicatesPNGDecodeFailure(const gfx::Image& image) { 140 SkBitmap bitmap = image.AsBitmap(); 141 EXPECT_FALSE(bitmap.isNull()); 142 EXPECT_LE(16, bitmap.width()); 143 EXPECT_LE(16, bitmap.height()); 144 SkAutoLockPixels auto_lock(bitmap); 145 CheckColors(bitmap.getColor(10, 10), SK_ColorRED); 146} 147 148bool ImageSkiaStructureMatches( 149 const gfx::ImageSkia& image_skia, 150 int width, 151 int height, 152 const std::vector<float>& scales) { 153 if (image_skia.isNull() || 154 image_skia.width() != width || 155 image_skia.height() != height || 156 image_skia.image_reps().size() != scales.size()) { 157 return false; 158 } 159 160 for (size_t i = 0; i < scales.size(); ++i) { 161 gfx::ImageSkiaRep image_rep = 162 image_skia.GetRepresentation(scales[i]); 163 if (image_rep.is_null() || image_rep.scale() != scales[i]) 164 return false; 165 166 if (image_rep.pixel_width() != static_cast<int>(width * scales[i]) || 167 image_rep.pixel_height() != static_cast<int>(height * scales[i])) { 168 return false; 169 } 170 } 171 return true; 172} 173 174bool IsEmpty(const gfx::Image& image) { 175 const SkBitmap& bmp = *image.ToSkBitmap(); 176 return bmp.isNull() || 177 (bmp.width() == 0 && bmp.height() == 0); 178} 179 180PlatformImage CreatePlatformImage() { 181 const SkBitmap bitmap(CreateBitmap(25, 25)); 182#if defined(OS_IOS) 183 float scale = ImageSkia::GetMaxSupportedScale(); 184 185 base::ScopedCFTypeRef<CGColorSpaceRef> color_space( 186 CGColorSpaceCreateDeviceRGB()); 187 UIImage* image = 188 gfx::SkBitmapToUIImageWithColorSpace(bitmap, scale, color_space); 189 base::mac::NSObjectRetain(image); 190 return image; 191#elif defined(OS_MACOSX) 192 NSImage* image = gfx::SkBitmapToNSImage(bitmap); 193 base::mac::NSObjectRetain(image); 194 return image; 195#elif defined(TOOLKIT_GTK) 196 return gfx::GdkPixbufFromSkBitmap(bitmap); 197#else 198 return gfx::ImageSkia::CreateFrom1xBitmap(bitmap); 199#endif 200} 201 202gfx::Image::RepresentationType GetPlatformRepresentationType() { 203#if defined(OS_IOS) 204 return gfx::Image::kImageRepCocoaTouch; 205#elif defined(OS_MACOSX) 206 return gfx::Image::kImageRepCocoa; 207#elif defined(TOOLKIT_GTK) 208 return gfx::Image::kImageRepGdk; 209#else 210 return gfx::Image::kImageRepSkia; 211#endif 212} 213 214PlatformImage ToPlatformType(const gfx::Image& image) { 215#if defined(OS_IOS) 216 return image.ToUIImage(); 217#elif defined(OS_MACOSX) 218 return image.ToNSImage(); 219#elif defined(TOOLKIT_GTK) 220 return image.ToGdkPixbuf(); 221#else 222 return image.AsImageSkia(); 223#endif 224} 225 226PlatformImage CopyPlatformType(const gfx::Image& image) { 227#if defined(OS_IOS) 228 return image.CopyUIImage(); 229#elif defined(OS_MACOSX) 230 return image.CopyNSImage(); 231#elif defined(TOOLKIT_GTK) 232 return image.CopyGdkPixbuf(); 233#else 234 return image.AsImageSkia(); 235#endif 236} 237 238#if defined(OS_MACOSX) 239// Defined in image_unittest_util_mac.mm. 240#elif defined(TOOLKIT_GTK) 241SkColor GetPlatformImageColor(PlatformImage image, int x, int y) { 242 int n_channels = gdk_pixbuf_get_n_channels(image); 243 int rowstride = gdk_pixbuf_get_rowstride(image); 244 guchar* gdk_pixels = gdk_pixbuf_get_pixels(image); 245 246 guchar* pixel = gdk_pixels + (y * rowstride) + (x * n_channels); 247 guchar alpha = gdk_pixbuf_get_has_alpha(image) ? pixel[3] : 255; 248 return SkColorSetARGB(alpha, pixel[0], pixel[1], pixel[2]); 249} 250#else 251SkColor GetPlatformImageColor(PlatformImage image, int x, int y) { 252 SkBitmap bitmap = *image.bitmap(); 253 SkAutoLockPixels auto_lock(bitmap); 254 return bitmap.getColor(x, y); 255} 256#endif 257 258void CheckColors(SkColor color1, SkColor color2) { 259 EXPECT_TRUE(ColorsClose(color1, color2)); 260} 261 262void CheckIsTransparent(SkColor color) { 263 EXPECT_LT(SkColorGetA(color) / 255.0, 0.05); 264} 265 266bool IsPlatformImageValid(PlatformImage image) { 267#if defined(OS_MACOSX) || defined(TOOLKIT_GTK) 268 return image != NULL; 269#else 270 return !image.isNull(); 271#endif 272} 273 274bool PlatformImagesEqual(PlatformImage image1, PlatformImage image2) { 275#if defined(OS_MACOSX) || defined(TOOLKIT_GTK) 276 return image1 == image2; 277#else 278 return image1.BackedBySameObjectAs(image2); 279#endif 280} 281 282} // namespace test 283} // namespace gfx 284