image_unittest_util.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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<ui::ScaleFactor> Get1xAnd2xScaleFactors() { 52 std::vector<ui::ScaleFactor> scale_factors; 53 scale_factors.push_back(ui::SCALE_FACTOR_100P); 54 scale_factors.push_back(ui::SCALE_FACTOR_200P); 55 return scale_factors; 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 ui::ScaleFactor scale_factor = img1_reps[i].scale_factor(); 93 const gfx::ImageSkiaRep& image_rep2 = image_skia2.GetRepresentation( 94 scale_factor); 95 if (image_rep2.scale_factor() != scale_factor || 96 !IsEqual(img1_reps[i].sk_bitmap(), image_rep2.sk_bitmap())) { 97 return false; 98 } 99 } 100 return true; 101} 102 103bool IsEqual(const SkBitmap& bmp1, const SkBitmap& bmp2) { 104 if (bmp1.isNull() && bmp2.isNull()) 105 return true; 106 107 if (bmp1.width() != bmp2.width() || 108 bmp1.height() != bmp2.height() || 109 bmp1.config() != SkBitmap::kARGB_8888_Config || 110 bmp2.config() != SkBitmap::kARGB_8888_Config) { 111 return false; 112 } 113 114 SkAutoLockPixels lock1(bmp1); 115 SkAutoLockPixels lock2(bmp2); 116 if (!bmp1.getPixels() || !bmp2.getPixels()) 117 return false; 118 119 for (int y = 0; y < bmp1.height(); ++y) { 120 for (int x = 0; x < bmp1.width(); ++x) { 121 if (!ColorsClose(bmp1.getColor(x,y), bmp2.getColor(x,y))) 122 return false; 123 } 124 } 125 126 return true; 127} 128 129bool IsEqual(const scoped_refptr<base::RefCountedMemory>& bytes, 130 const SkBitmap& bitmap) { 131 SkBitmap decoded; 132 if (!bytes.get() || 133 !PNGCodec::Decode(bytes->front(), bytes->size(), &decoded)) { 134 return bitmap.isNull(); 135 } 136 137 return IsEqual(bitmap, decoded); 138} 139 140void CheckImageIndicatesPNGDecodeFailure(const gfx::Image& image) { 141 SkBitmap bitmap = image.AsBitmap(); 142 EXPECT_FALSE(bitmap.isNull()); 143 EXPECT_LE(16, bitmap.width()); 144 EXPECT_LE(16, bitmap.height()); 145 SkAutoLockPixels auto_lock(bitmap); 146 CheckColors(bitmap.getColor(10, 10), SK_ColorRED); 147} 148 149bool ImageSkiaStructureMatches( 150 const gfx::ImageSkia& image_skia, 151 int width, 152 int height, 153 const std::vector<ui::ScaleFactor>& scale_factors) { 154 if (image_skia.isNull() || 155 image_skia.width() != width || 156 image_skia.height() != height || 157 image_skia.image_reps().size() != scale_factors.size()) { 158 return false; 159 } 160 161 for (size_t i = 0; i < scale_factors.size(); ++i) { 162 gfx::ImageSkiaRep image_rep = 163 image_skia.GetRepresentation(scale_factors[i]); 164 if (image_rep.is_null() || 165 image_rep.scale_factor() != scale_factors[i]) 166 return false; 167 168 float scale = ui::GetScaleFactorScale(scale_factors[i]); 169 if (image_rep.pixel_width() != static_cast<int>(width * scale) || 170 image_rep.pixel_height() != static_cast<int>(height * scale)) { 171 return false; 172 } 173 } 174 return true; 175} 176 177bool IsEmpty(const gfx::Image& image) { 178 const SkBitmap& bmp = *image.ToSkBitmap(); 179 return bmp.isNull() || 180 (bmp.width() == 0 && bmp.height() == 0); 181} 182 183PlatformImage CreatePlatformImage() { 184 const SkBitmap bitmap(CreateBitmap(25, 25)); 185#if defined(OS_IOS) 186 ui::ScaleFactor scale_factor = ui::GetMaxScaleFactor(); 187 float scale = ui::GetScaleFactorScale(scale_factor); 188 189 base::mac::ScopedCFTypeRef<CGColorSpaceRef> color_space( 190 CGColorSpaceCreateDeviceRGB()); 191 UIImage* image = 192 gfx::SkBitmapToUIImageWithColorSpace(bitmap, scale, color_space); 193 base::mac::NSObjectRetain(image); 194 return image; 195#elif defined(OS_MACOSX) 196 NSImage* image = gfx::SkBitmapToNSImage(bitmap); 197 base::mac::NSObjectRetain(image); 198 return image; 199#elif defined(TOOLKIT_GTK) 200 return gfx::GdkPixbufFromSkBitmap(bitmap); 201#else 202 return gfx::ImageSkia::CreateFrom1xBitmap(bitmap); 203#endif 204} 205 206gfx::Image::RepresentationType GetPlatformRepresentationType() { 207#if defined(OS_IOS) 208 return gfx::Image::kImageRepCocoaTouch; 209#elif defined(OS_MACOSX) 210 return gfx::Image::kImageRepCocoa; 211#elif defined(TOOLKIT_GTK) 212 return gfx::Image::kImageRepGdk; 213#else 214 return gfx::Image::kImageRepSkia; 215#endif 216} 217 218PlatformImage ToPlatformType(const gfx::Image& image) { 219#if defined(OS_IOS) 220 return image.ToUIImage(); 221#elif defined(OS_MACOSX) 222 return image.ToNSImage(); 223#elif defined(TOOLKIT_GTK) 224 return image.ToGdkPixbuf(); 225#else 226 return image.AsImageSkia(); 227#endif 228} 229 230PlatformImage CopyPlatformType(const gfx::Image& image) { 231#if defined(OS_IOS) 232 return image.CopyUIImage(); 233#elif defined(OS_MACOSX) 234 return image.CopyNSImage(); 235#elif defined(TOOLKIT_GTK) 236 return image.CopyGdkPixbuf(); 237#else 238 return image.AsImageSkia(); 239#endif 240} 241 242#if defined(OS_MACOSX) 243// Defined in image_unittest_util_mac.mm. 244#elif defined(TOOLKIT_GTK) 245SkColor GetPlatformImageColor(PlatformImage image, int x, int y) { 246 int n_channels = gdk_pixbuf_get_n_channels(image); 247 int rowstride = gdk_pixbuf_get_rowstride(image); 248 guchar* gdk_pixels = gdk_pixbuf_get_pixels(image); 249 250 guchar* pixel = gdk_pixels + (y * rowstride) + (x * n_channels); 251 guchar alpha = gdk_pixbuf_get_has_alpha(image) ? pixel[3] : 255; 252 return SkColorSetARGB(alpha, pixel[0], pixel[1], pixel[2]); 253} 254#else 255SkColor GetPlatformImageColor(PlatformImage image, int x, int y) { 256 SkBitmap bitmap = *image.bitmap(); 257 SkAutoLockPixels auto_lock(bitmap); 258 return bitmap.getColor(x, y); 259} 260#endif 261 262void CheckColors(SkColor color1, SkColor color2) { 263 EXPECT_TRUE(ColorsClose(color1, color2)); 264} 265 266void CheckIsTransparent(SkColor color) { 267 EXPECT_LT(SkColorGetA(color) / 255.0, 0.05); 268} 269 270bool IsPlatformImageValid(PlatformImage image) { 271#if defined(OS_MACOSX) || defined(TOOLKIT_GTK) 272 return image != NULL; 273#else 274 return !image.isNull(); 275#endif 276} 277 278bool PlatformImagesEqual(PlatformImage image1, PlatformImage image2) { 279#if defined(OS_MACOSX) || defined(TOOLKIT_GTK) 280 return image1 == image2; 281#else 282 return image1.BackedBySameObjectAs(image2); 283#endif 284} 285 286} // namespace test 287} // namespace gfx 288