Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ui / gfx / image / image_mac_unittest.mm
blob5f706c713f8f2dfd7c35241d8c4fec286d56df6f
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  private:
82   DISALLOW_COPY_AND_ASSIGN(ImageMacTest);
85 namespace gt = gfx::test;
87 TEST_F(ImageMacTest, MultiResolutionNSImageToImageSkia) {
88   const int kWidth1x = 10;
89   const int kHeight1x = 12;
90   const int kWidth2x = 20;
91   const int kHeight2x = 24;
93   NSBitmapImageRep* ns_image_rep1;
94   BitmapImageRep(kWidth1x, kHeight1x, &ns_image_rep1);
95   NSBitmapImageRep* ns_image_rep2;
96   BitmapImageRep(kWidth2x, kHeight2x, &ns_image_rep2);
97   base::scoped_nsobject<NSImage> ns_image(
98       [[NSImage alloc] initWithSize:NSMakeSize(kWidth1x, kHeight1x)]);
99   [ns_image addRepresentation:ns_image_rep1];
100   [ns_image addRepresentation:ns_image_rep2];
102   gfx::Image image(ns_image.release());
104   EXPECT_EQ(1u, image.RepresentationCount());
106   const gfx::ImageSkia* image_skia = image.ToImageSkia();
108   std::vector<float> scales;
109   scales.push_back(1.0f);
110   scales.push_back(2.0f);
111   EXPECT_TRUE(gt::ImageSkiaStructureMatches(*image_skia, kWidth1x, kHeight1x,
112                                             scales));
114   // ToImageSkia should create a second representation.
115   EXPECT_EQ(2u, image.RepresentationCount());
118 // Test that convertng to an ImageSkia from an NSImage with scale factors
119 // other than 1x and 2x results in an ImageSkia with scale factors 1x and
120 // 2x;
121 TEST_F(ImageMacTest, UnalignedMultiResolutionNSImageToImageSkia) {
122   const int kWidth1x = 10;
123   const int kHeight1x= 12;
124   const int kWidth4x = 40;
125   const int kHeight4x = 48;
127   NSBitmapImageRep* ns_image_rep4;
128   BitmapImageRep(kWidth4x, kHeight4x, &ns_image_rep4);
129   base::scoped_nsobject<NSImage> ns_image(
130       [[NSImage alloc] initWithSize:NSMakeSize(kWidth1x, kHeight1x)]);
131   [ns_image addRepresentation:ns_image_rep4];
133   gfx::Image image(ns_image.release());
135   EXPECT_EQ(1u, image.RepresentationCount());
137   const gfx::ImageSkia* image_skia = image.ToImageSkia();
139   std::vector<float> scales;
140   scales.push_back(1.0f);
141   scales.push_back(2.0f);
142   EXPECT_TRUE(gt::ImageSkiaStructureMatches(*image_skia, kWidth1x, kHeight1x,
143                                             scales));
145   // ToImageSkia should create a second representation.
146   EXPECT_EQ(2u, image.RepresentationCount());
149 TEST_F(ImageMacTest, MultiResolutionImageSkiaToNSImage) {
150   const int kWidth1x = 10;
151   const int kHeight1x= 12;
152   const int kWidth2x = 20;
153   const int kHeight2x = 24;
155   gfx::ImageSkia image_skia;
156   image_skia.AddRepresentation(gfx::ImageSkiaRep(
157       gt::CreateBitmap(kWidth1x, kHeight1x), 1.0f));
158   image_skia.AddRepresentation(gfx::ImageSkiaRep(
159       gt::CreateBitmap(kWidth2x, kHeight2x), 2.0f));
161   gfx::Image image(image_skia);
163   EXPECT_EQ(1u, image.RepresentationCount());
164   EXPECT_EQ(2u, image.ToImageSkia()->image_reps().size());
166   NSImage* ns_image = image.ToNSImage();
168   std::vector<float> scales;
169   scales.push_back(1.0f);
170   scales.push_back(2.0f);
171   EXPECT_TRUE(NSImageStructureMatches(ns_image, kWidth1x, kHeight1x, scales));
173   // Request for NSImage* should create a second representation.
174   EXPECT_EQ(2u, image.RepresentationCount());
177 TEST_F(ImageMacTest, MultiResolutionPNGToNSImage) {
178   const int kSize1x = 25;
179   const int kSize2x = 50;
181   scoped_refptr<base::RefCountedMemory> bytes1x = gt::CreatePNGBytes(kSize1x);
182   scoped_refptr<base::RefCountedMemory> bytes2x = gt::CreatePNGBytes(kSize2x);
183   std::vector<gfx::ImagePNGRep> image_png_reps;
184   image_png_reps.push_back(gfx::ImagePNGRep(bytes1x, 1.0f));
185   image_png_reps.push_back(gfx::ImagePNGRep(bytes2x, 2.0f));
187   gfx::Image image(image_png_reps);
189   NSImage* ns_image = image.ToNSImage();
190   std::vector<float> scales;
191   scales.push_back(1.0f);
192   scales.push_back(2.0f);
193   EXPECT_TRUE(NSImageStructureMatches(ns_image, kSize1x, kSize1x, scales));
195   // Converting from PNG to NSImage should not go through ImageSkia.
196   EXPECT_FALSE(image.HasRepresentation(gfx::Image::kImageRepSkia));
198   // Convert to ImageSkia to check pixel contents of NSImageReps.
199   gfx::ImageSkia image_skia = gfx::ImageSkiaFromNSImage(ns_image);
200   EXPECT_TRUE(gt::IsEqual(bytes1x,
201       image_skia.GetRepresentation(1.0f).sk_bitmap()));
202   EXPECT_TRUE(gt::IsEqual(bytes2x,
203       image_skia.GetRepresentation(2.0f).sk_bitmap()));
206 } // namespace