Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / ui / gfx / image / image_mac_unittest.mm
blob2cbbd117a9772df42a734a0c93663546d6759aa5
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 #include <Cocoa/Cocoa.h>
7 #include "base/logging.h"
8 #include "base/mac/scoped_nsobject.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "ui/gfx/image/image.h"
11 #include "ui/gfx/image/image_png_rep.h"
12 #include "ui/gfx/image/image_skia.h"
13 #include "ui/gfx/image/image_skia_util_mac.h"
14 #include "ui/gfx/image/image_unittest_util.h"
16 namespace {
18 // Returns true if the structure of |ns_image| matches the structure
19 // described by |width|, |height|, and |scales|.
20 // The structure matches if:
21 // - |ns_image| is not nil.
22 // - |ns_image| has NSImageReps of |scales|.
23 // - Each of the NSImageReps has a pixel size of [|ns_image| size] *
24 //   scale.
25 bool NSImageStructureMatches(
26     NSImage* ns_image,
27     int width,
28     int height,
29     const std::vector<float>& scales) {
30   if (!ns_image ||
31       [ns_image size].width != width ||
32       [ns_image size].height != height ||
33       [ns_image representations].count != scales.size()) {
34     return false;
35   }
37   for (size_t i = 0; i < scales.size(); ++i) {
38     float scale = scales[i];
39     bool found_match = false;
40     for (size_t j = 0; j < [ns_image representations].count; ++j) {
41       NSImageRep* ns_image_rep = [[ns_image representations] objectAtIndex:j];
42       if (ns_image_rep &&
43           [ns_image_rep pixelsWide] == width * scale &&
44           [ns_image_rep pixelsHigh] == height * scale) {
45         found_match = true;
46         break;
47       }
48     }
49     if (!found_match)
50       return false;
51   }
52   return true;
55 void BitmapImageRep(int width, int height,
56      NSBitmapImageRep** image_rep) {
57   *image_rep = [[[NSBitmapImageRep alloc]
58       initWithBitmapDataPlanes:NULL
59                     pixelsWide:width
60                    pixelsHigh:height
61                 bitsPerSample:8
62               samplesPerPixel:3
63                      hasAlpha:NO
64                      isPlanar:NO
65                colorSpaceName:NSDeviceRGBColorSpace
66                  bitmapFormat:0
67                   bytesPerRow:0
68                  bitsPerPixel:0]
69       autorelease];
70   unsigned char* image_rep_data = [*image_rep bitmapData];
71   for (int i = 0; i < width * height * 3; ++i)
72     image_rep_data[i] = 255;
75 class ImageMacTest : public testing::Test {
76  public:
77   ImageMacTest() {
78     gfx::ImageSkia::SetSupportedScales(gfx::test::Get1xAnd2xScales());
79   }
81   virtual ~ImageMacTest() {
82   }
84  private:
85   DISALLOW_COPY_AND_ASSIGN(ImageMacTest);
88 namespace gt = gfx::test;
90 TEST_F(ImageMacTest, MultiResolutionNSImageToImageSkia) {
91   const int kWidth1x = 10;
92   const int kHeight1x = 12;
93   const int kWidth2x = 20;
94   const int kHeight2x = 24;
96   NSBitmapImageRep* ns_image_rep1;
97   BitmapImageRep(kWidth1x, kHeight1x, &ns_image_rep1);
98   NSBitmapImageRep* ns_image_rep2;
99   BitmapImageRep(kWidth2x, kHeight2x, &ns_image_rep2);
100   base::scoped_nsobject<NSImage> ns_image(
101       [[NSImage alloc] initWithSize:NSMakeSize(kWidth1x, kHeight1x)]);
102   [ns_image addRepresentation:ns_image_rep1];
103   [ns_image addRepresentation:ns_image_rep2];
105   gfx::Image image(ns_image.release());
107   EXPECT_EQ(1u, image.RepresentationCount());
109   const gfx::ImageSkia* image_skia = image.ToImageSkia();
111   std::vector<float> scales;
112   scales.push_back(1.0f);
113   scales.push_back(2.0f);
114   EXPECT_TRUE(gt::ImageSkiaStructureMatches(*image_skia, kWidth1x, kHeight1x,
115                                             scales));
117   // ToImageSkia should create a second representation.
118   EXPECT_EQ(2u, image.RepresentationCount());
121 // Test that convertng to an ImageSkia from an NSImage with scale factors
122 // other than 1x and 2x results in an ImageSkia with scale factors 1x and
123 // 2x;
124 TEST_F(ImageMacTest, UnalignedMultiResolutionNSImageToImageSkia) {
125   const int kWidth1x = 10;
126   const int kHeight1x= 12;
127   const int kWidth4x = 40;
128   const int kHeight4x = 48;
130   NSBitmapImageRep* ns_image_rep4;
131   BitmapImageRep(kWidth4x, kHeight4x, &ns_image_rep4);
132   base::scoped_nsobject<NSImage> ns_image(
133       [[NSImage alloc] initWithSize:NSMakeSize(kWidth1x, kHeight1x)]);
134   [ns_image addRepresentation:ns_image_rep4];
136   gfx::Image image(ns_image.release());
138   EXPECT_EQ(1u, image.RepresentationCount());
140   const gfx::ImageSkia* image_skia = image.ToImageSkia();
142   std::vector<float> scales;
143   scales.push_back(1.0f);
144   scales.push_back(2.0f);
145   EXPECT_TRUE(gt::ImageSkiaStructureMatches(*image_skia, kWidth1x, kHeight1x,
146                                             scales));
148   // ToImageSkia should create a second representation.
149   EXPECT_EQ(2u, image.RepresentationCount());
152 TEST_F(ImageMacTest, MultiResolutionImageSkiaToNSImage) {
153   const int kWidth1x = 10;
154   const int kHeight1x= 12;
155   const int kWidth2x = 20;
156   const int kHeight2x = 24;
158   gfx::ImageSkia image_skia;
159   image_skia.AddRepresentation(gfx::ImageSkiaRep(
160       gt::CreateBitmap(kWidth1x, kHeight1x), 1.0f));
161   image_skia.AddRepresentation(gfx::ImageSkiaRep(
162       gt::CreateBitmap(kWidth2x, kHeight2x), 2.0f));
164   gfx::Image image(image_skia);
166   EXPECT_EQ(1u, image.RepresentationCount());
167   EXPECT_EQ(2u, image.ToImageSkia()->image_reps().size());
169   NSImage* ns_image = image.ToNSImage();
171   std::vector<float> scales;
172   scales.push_back(1.0f);
173   scales.push_back(2.0f);
174   EXPECT_TRUE(NSImageStructureMatches(ns_image, kWidth1x, kHeight1x, scales));
176   // Request for NSImage* should create a second representation.
177   EXPECT_EQ(2u, image.RepresentationCount());
180 TEST_F(ImageMacTest, MultiResolutionPNGToNSImage) {
181   const int kSize1x = 25;
182   const int kSize2x = 50;
184   scoped_refptr<base::RefCountedMemory> bytes1x = gt::CreatePNGBytes(kSize1x);
185   scoped_refptr<base::RefCountedMemory> bytes2x = gt::CreatePNGBytes(kSize2x);
186   std::vector<gfx::ImagePNGRep> image_png_reps;
187   image_png_reps.push_back(gfx::ImagePNGRep(bytes1x, 1.0f));
188   image_png_reps.push_back(gfx::ImagePNGRep(bytes2x, 2.0f));
190   gfx::Image image(image_png_reps);
192   NSImage* ns_image = image.ToNSImage();
193   std::vector<float> scales;
194   scales.push_back(1.0f);
195   scales.push_back(2.0f);
196   EXPECT_TRUE(NSImageStructureMatches(ns_image, kSize1x, kSize1x, scales));
198   // Converting from PNG to NSImage should not go through ImageSkia.
199   EXPECT_FALSE(image.HasRepresentation(gfx::Image::kImageRepSkia));
201   // Convert to ImageSkia to check pixel contents of NSImageReps.
202   gfx::ImageSkia image_skia = gfx::ImageSkiaFromNSImage(ns_image);
203   EXPECT_TRUE(gt::IsEqual(bytes1x,
204       image_skia.GetRepresentation(1.0f).sk_bitmap()));
205   EXPECT_TRUE(gt::IsEqual(bytes2x,
206       image_skia.GetRepresentation(2.0f).sk_bitmap()));
209 } // namespace