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#include "testing/gtest/include/gtest/gtest.h"
6#include "third_party/skia/include/core/SkCanvas.h"
7#include "third_party/skia/include/core/SkPaint.h"
8#include "ui/gfx/image/image.h"
9#include "ui/gfx/image/image_png_rep.h"
10#include "ui/gfx/image/image_skia.h"
11#include "ui/gfx/image/image_unittest_util.h"
12
13#if defined(OS_IOS)
14#include "base/mac/foundation_util.h"
15#include "skia/ext/skia_utils_ios.h"
16#elif defined(OS_MACOSX)
17#include "base/mac/mac_util.h"
18#include "skia/ext/skia_utils_mac.h"
19#endif
20
21namespace {
22
23#if defined(OS_IOS) || defined(OS_MACOSX)
24const bool kUsesSkiaNatively = false;
25#else
26const bool kUsesSkiaNatively = true;
27#endif
28
29class ImageTest : public testing::Test {
30 public:
31  ImageTest() {
32    std::vector<float> scales;
33    scales.push_back(1.0f);
34#if !defined(OS_IOS)
35    scales.push_back(2.0f);
36#endif
37    gfx::ImageSkia::SetSupportedScales(scales);
38  }
39};
40
41namespace gt = gfx::test;
42
43TEST_F(ImageTest, EmptyImage) {
44  // Test the default constructor.
45  gfx::Image image;
46  EXPECT_EQ(0U, image.RepresentationCount());
47  EXPECT_TRUE(image.IsEmpty());
48  EXPECT_EQ(0, image.Width());
49  EXPECT_EQ(0, image.Height());
50
51  // Test the copy constructor.
52  gfx::Image imageCopy(image);
53  EXPECT_TRUE(imageCopy.IsEmpty());
54  EXPECT_EQ(0, imageCopy.Width());
55  EXPECT_EQ(0, imageCopy.Height());
56
57  // Test calling SwapRepresentations() with an empty image.
58  gfx::Image image2(gt::CreateImageSkia(25, 25));
59  EXPECT_FALSE(image2.IsEmpty());
60  EXPECT_EQ(25, image2.Width());
61  EXPECT_EQ(25, image2.Height());
62
63  image.SwapRepresentations(&image2);
64  EXPECT_FALSE(image.IsEmpty());
65  EXPECT_EQ(25, image.Width());
66  EXPECT_EQ(25, image.Height());
67  EXPECT_TRUE(image2.IsEmpty());
68  EXPECT_EQ(0, image2.Width());
69  EXPECT_EQ(0, image2.Height());
70}
71
72// Test constructing a gfx::Image from an empty PlatformImage.
73TEST_F(ImageTest, EmptyImageFromEmptyPlatformImage) {
74#if defined(OS_IOS) || defined(OS_MACOSX)
75  gfx::Image image1(NULL);
76  EXPECT_TRUE(image1.IsEmpty());
77  EXPECT_EQ(0, image1.Width());
78  EXPECT_EQ(0, image1.Height());
79  EXPECT_EQ(0U, image1.RepresentationCount());
80#endif
81
82  // gfx::ImageSkia and gfx::ImagePNGRep are available on all platforms.
83  gfx::ImageSkia image_skia;
84  EXPECT_TRUE(image_skia.isNull());
85  gfx::Image image2(image_skia);
86  EXPECT_TRUE(image2.IsEmpty());
87  EXPECT_EQ(0, image2.Width());
88  EXPECT_EQ(0, image2.Height());
89  EXPECT_EQ(0U, image2.RepresentationCount());
90
91  std::vector<gfx::ImagePNGRep> image_png_reps;
92  gfx::Image image3(image_png_reps);
93  EXPECT_TRUE(image3.IsEmpty());
94  EXPECT_EQ(0, image3.Width());
95  EXPECT_EQ(0, image3.Height());
96  EXPECT_EQ(0U, image3.RepresentationCount());
97}
98
99// The resulting Image should be empty when it is created using obviously
100// invalid data.
101TEST_F(ImageTest, EmptyImageFromObviouslyInvalidPNGImage) {
102  std::vector<gfx::ImagePNGRep> image_png_reps1;
103  image_png_reps1.push_back(gfx::ImagePNGRep(NULL, 1.0f));
104  gfx::Image image1(image_png_reps1);
105  EXPECT_TRUE(image1.IsEmpty());
106  EXPECT_EQ(0U, image1.RepresentationCount());
107
108  std::vector<gfx::ImagePNGRep> image_png_reps2;
109  image_png_reps2.push_back(gfx::ImagePNGRep(
110      new base::RefCountedBytes(), 1.0f));
111  gfx::Image image2(image_png_reps2);
112  EXPECT_TRUE(image2.IsEmpty());
113  EXPECT_EQ(0U, image2.RepresentationCount());
114}
115
116// Test the Width, Height and Size of an empty and non-empty image.
117TEST_F(ImageTest, ImageSize) {
118  gfx::Image image;
119  EXPECT_EQ(0, image.Width());
120  EXPECT_EQ(0, image.Height());
121  EXPECT_EQ(gfx::Size(0, 0), image.Size());
122
123  gfx::Image image2(gt::CreateImageSkia(10, 25));
124  EXPECT_EQ(10, image2.Width());
125  EXPECT_EQ(25, image2.Height());
126  EXPECT_EQ(gfx::Size(10, 25), image2.Size());
127}
128
129TEST_F(ImageTest, SkiaToSkia) {
130  gfx::Image image(gt::CreateImageSkia(25, 25));
131  EXPECT_EQ(25, image.Width());
132  EXPECT_EQ(25, image.Height());
133
134  // Test ToImageSkia().
135  const gfx::ImageSkia* image_skia1 = image.ToImageSkia();
136  EXPECT_TRUE(image_skia1);
137  EXPECT_FALSE(image_skia1->isNull());
138  EXPECT_EQ(1U, image.RepresentationCount());
139
140  // Make sure double conversion doesn't happen.
141  const gfx::ImageSkia* image_skia2 = image.ToImageSkia();
142  EXPECT_EQ(1U, image.RepresentationCount());
143
144  // ToImageSkia() should always return the same gfx::ImageSkia.
145  EXPECT_EQ(image_skia1, image_skia2);
146
147  // Test ToSkBitmap().
148  const SkBitmap* bitmap1 = image.ToSkBitmap();
149  const SkBitmap* bitmap2 = image.ToSkBitmap();
150  EXPECT_TRUE(bitmap1);
151  EXPECT_FALSE(bitmap1->isNull());
152  EXPECT_EQ(bitmap1, bitmap2);
153
154  EXPECT_EQ(1U, image.RepresentationCount());
155  EXPECT_TRUE(image.HasRepresentation(gfx::Image::kImageRepSkia));
156  if (!kUsesSkiaNatively)
157    EXPECT_FALSE(image.HasRepresentation(gt::GetPlatformRepresentationType()));
158}
159
160TEST_F(ImageTest, EmptyImageToPNG) {
161  gfx::Image image;
162  scoped_refptr<base::RefCountedMemory> png_bytes = image.As1xPNGBytes();
163  EXPECT_TRUE(png_bytes.get());
164  EXPECT_FALSE(png_bytes->size());
165}
166
167// Check that getting the 1x PNG bytes from images which do not have a 1x
168// representation returns NULL.
169TEST_F(ImageTest, ImageNo1xToPNG) {
170  // Image with 2x only.
171  const int kSize2x = 50;
172  gfx::ImageSkia image_skia;
173  image_skia.AddRepresentation(gfx::ImageSkiaRep(gt::CreateBitmap(
174      kSize2x, kSize2x), 2.0f));
175  gfx::Image image1(image_skia);
176  scoped_refptr<base::RefCountedMemory> png_bytes1 = image1.As1xPNGBytes();
177  EXPECT_TRUE(png_bytes1.get());
178  EXPECT_FALSE(png_bytes1->size());
179
180  std::vector<gfx::ImagePNGRep> image_png_reps;
181  image_png_reps.push_back(gfx::ImagePNGRep(
182      gt::CreatePNGBytes(kSize2x), 2.0f));
183  gfx::Image image2(image_png_reps);
184  EXPECT_FALSE(image2.IsEmpty());
185  EXPECT_EQ(0, image2.Width());
186  EXPECT_EQ(0, image2.Height());
187  scoped_refptr<base::RefCountedMemory> png_bytes2 = image2.As1xPNGBytes();
188  EXPECT_TRUE(png_bytes2.get());
189  EXPECT_FALSE(png_bytes2->size());
190}
191
192// Check that for an image initialized with multi resolution PNG data,
193// As1xPNGBytes() returns the 1x bytes.
194TEST_F(ImageTest, CreateExtractPNGBytes) {
195  const int kSize1x = 25;
196  const int kSize2x = 50;
197
198  scoped_refptr<base::RefCountedMemory> bytes1x = gt::CreatePNGBytes(kSize1x);
199  std::vector<gfx::ImagePNGRep> image_png_reps;
200  image_png_reps.push_back(gfx::ImagePNGRep(bytes1x, 1.0f));
201  image_png_reps.push_back(gfx::ImagePNGRep(
202      gt::CreatePNGBytes(kSize2x), 2.0f));
203
204  gfx::Image image(image_png_reps);
205  EXPECT_FALSE(image.IsEmpty());
206  EXPECT_EQ(25, image.Width());
207  EXPECT_EQ(25, image.Height());
208
209  EXPECT_TRUE(std::equal(bytes1x->front(), bytes1x->front() + bytes1x->size(),
210                         image.As1xPNGBytes()->front()));
211}
212
213TEST_F(ImageTest, MultiResolutionImageSkiaToPNG) {
214  const int kSize1x = 25;
215  const int kSize2x = 50;
216
217  SkBitmap bitmap_1x = gt::CreateBitmap(kSize1x, kSize1x);
218  gfx::ImageSkia image_skia;
219  image_skia.AddRepresentation(gfx::ImageSkiaRep(bitmap_1x,
220                                                 1.0f));
221  image_skia.AddRepresentation(gfx::ImageSkiaRep(gt::CreateBitmap(
222      kSize2x, kSize2x), 2.0f));
223  gfx::Image image(image_skia);
224
225  EXPECT_TRUE(gt::IsEqual(image.As1xPNGBytes(), bitmap_1x));
226  EXPECT_TRUE(image.HasRepresentation(gfx::Image::kImageRepPNG));
227}
228
229TEST_F(ImageTest, MultiResolutionPNGToImageSkia) {
230  const int kSize1x = 25;
231  const int kSize2x = 50;
232
233  scoped_refptr<base::RefCountedMemory> bytes1x = gt::CreatePNGBytes(kSize1x);
234  scoped_refptr<base::RefCountedMemory> bytes2x = gt::CreatePNGBytes(kSize2x);
235
236  std::vector<gfx::ImagePNGRep> image_png_reps;
237  image_png_reps.push_back(gfx::ImagePNGRep(bytes1x, 1.0f));
238  image_png_reps.push_back(gfx::ImagePNGRep(bytes2x, 2.0f));
239  gfx::Image image(image_png_reps);
240
241  std::vector<float> scales;
242  scales.push_back(1.0f);
243  scales.push_back(2.0f);
244  gfx::ImageSkia image_skia = image.AsImageSkia();
245  EXPECT_TRUE(gt::IsEqual(bytes1x,
246      image_skia.GetRepresentation(1.0f).sk_bitmap()));
247  EXPECT_TRUE(gt::IsEqual(bytes2x,
248      image_skia.GetRepresentation(2.0f).sk_bitmap()));
249  EXPECT_TRUE(gt::ImageSkiaStructureMatches(image_skia, kSize1x, kSize1x,
250                                            scales));
251#if !defined(OS_IOS)
252  // IOS does not support arbitrary scale factors.
253  gfx::ImageSkiaRep rep_1_6x = image_skia.GetRepresentation(1.6f);
254  ASSERT_FALSE(rep_1_6x.is_null());
255  ASSERT_EQ(1.6f, rep_1_6x.scale());
256  EXPECT_EQ("40x40", rep_1_6x.pixel_size().ToString());
257
258  gfx::ImageSkiaRep rep_0_8x = image_skia.GetRepresentation(0.8f);
259  ASSERT_FALSE(rep_0_8x.is_null());
260  ASSERT_EQ(0.8f, rep_0_8x.scale());
261  EXPECT_EQ("20x20", rep_0_8x.pixel_size().ToString());
262#endif
263}
264
265TEST_F(ImageTest, MultiResolutionPNGToPlatform) {
266  const int kSize1x = 25;
267  const int kSize2x = 50;
268
269  scoped_refptr<base::RefCountedMemory> bytes1x = gt::CreatePNGBytes(kSize1x);
270  scoped_refptr<base::RefCountedMemory> bytes2x = gt::CreatePNGBytes(kSize2x);
271  std::vector<gfx::ImagePNGRep> image_png_reps;
272  image_png_reps.push_back(gfx::ImagePNGRep(bytes1x, 1.0f));
273  image_png_reps.push_back(gfx::ImagePNGRep(bytes2x, 2.0f));
274
275  gfx::Image from_png(image_png_reps);
276  gfx::Image from_platform(gt::CopyPlatformType(from_png));
277#if defined(OS_IOS)
278  // On iOS the platform type (UIImage) only supports one resolution.
279  std::vector<float> scales = gfx::ImageSkia::GetSupportedScales();
280  EXPECT_EQ(scales.size(), 1U);
281  if (scales[0] == 1.0f)
282    EXPECT_TRUE(gt::IsEqual(bytes1x, from_platform.AsBitmap()));
283  else if (scales[0] == 2.0f)
284    EXPECT_TRUE(gt::IsEqual(bytes2x, from_platform.AsBitmap()));
285  else
286    ADD_FAILURE() << "Unexpected platform scale factor.";
287#else
288  EXPECT_TRUE(gt::IsEqual(bytes1x, from_platform.AsBitmap()));
289#endif  // defined(OS_IOS)
290}
291
292
293TEST_F(ImageTest, PlatformToPNGEncodeAndDecode) {
294  gfx::Image image(gt::CreatePlatformImage());
295  scoped_refptr<base::RefCountedMemory> png_data = image.As1xPNGBytes();
296  EXPECT_TRUE(png_data.get());
297  EXPECT_TRUE(png_data->size());
298  EXPECT_TRUE(image.HasRepresentation(gfx::Image::kImageRepPNG));
299
300  std::vector<gfx::ImagePNGRep> image_png_reps;
301  image_png_reps.push_back(gfx::ImagePNGRep(png_data, 1.0f));
302  gfx::Image from_png(image_png_reps);
303
304  EXPECT_TRUE(from_png.HasRepresentation(gfx::Image::kImageRepPNG));
305  EXPECT_TRUE(gt::IsPlatformImageValid(gt::ToPlatformType(from_png)));
306}
307
308// The platform types use the platform provided encoding/decoding of PNGs. Make
309// sure these work with the Skia Encode/Decode.
310TEST_F(ImageTest, PNGEncodeFromSkiaDecodeToPlatform) {
311  // Force the conversion sequence skia to png to platform_type.
312  gfx::Image from_bitmap = gfx::Image::CreateFrom1xBitmap(
313      gt::CreateBitmap(25, 25));
314  scoped_refptr<base::RefCountedMemory> png_bytes =
315      from_bitmap.As1xPNGBytes();
316
317  std::vector<gfx::ImagePNGRep> image_png_reps;
318  image_png_reps.push_back(gfx::ImagePNGRep(png_bytes, 1.0f));
319  gfx::Image from_png(image_png_reps);
320
321  gfx::Image from_platform(gt::CopyPlatformType(from_png));
322
323  EXPECT_TRUE(gt::IsPlatformImageValid(gt::ToPlatformType(from_platform)));
324  EXPECT_TRUE(gt::IsEqual(png_bytes, from_platform.AsBitmap()));
325}
326
327TEST_F(ImageTest, PNGEncodeFromPlatformDecodeToSkia) {
328  // Force the conversion sequence platform_type to png to skia.
329  gfx::Image from_platform(gt::CreatePlatformImage());
330  scoped_refptr<base::RefCountedMemory> png_bytes =
331      from_platform.As1xPNGBytes();
332  std::vector<gfx::ImagePNGRep> image_png_reps;
333  image_png_reps.push_back(gfx::ImagePNGRep(png_bytes, 1.0f));
334  gfx::Image from_png(image_png_reps);
335
336  EXPECT_TRUE(gt::IsEqual(from_platform.AsBitmap(), from_png.AsBitmap()));
337}
338
339TEST_F(ImageTest, PNGDecodeToSkiaFailure) {
340  scoped_refptr<base::RefCountedBytes> invalid_bytes(
341      new base::RefCountedBytes());
342  invalid_bytes->data().push_back('0');
343  std::vector<gfx::ImagePNGRep> image_png_reps;
344  image_png_reps.push_back(gfx::ImagePNGRep(
345      invalid_bytes, 1.0f));
346  gfx::Image image(image_png_reps);
347  gt::CheckImageIndicatesPNGDecodeFailure(image);
348}
349
350TEST_F(ImageTest, PNGDecodeToPlatformFailure) {
351  scoped_refptr<base::RefCountedBytes> invalid_bytes(
352      new base::RefCountedBytes());
353  invalid_bytes->data().push_back('0');
354  std::vector<gfx::ImagePNGRep> image_png_reps;
355  image_png_reps.push_back(gfx::ImagePNGRep(
356      invalid_bytes, 1.0f));
357  gfx::Image from_png(image_png_reps);
358  gfx::Image from_platform(gt::CopyPlatformType(from_png));
359  gt::CheckImageIndicatesPNGDecodeFailure(from_platform);
360}
361
362TEST_F(ImageTest, SkiaToPlatform) {
363  gfx::Image image(gt::CreateImageSkia(25, 25));
364  EXPECT_EQ(25, image.Width());
365  EXPECT_EQ(25, image.Height());
366  const size_t kRepCount = kUsesSkiaNatively ? 1U : 2U;
367
368  EXPECT_TRUE(image.HasRepresentation(gfx::Image::kImageRepSkia));
369  if (!kUsesSkiaNatively)
370    EXPECT_FALSE(image.HasRepresentation(gt::GetPlatformRepresentationType()));
371
372  EXPECT_TRUE(gt::IsPlatformImageValid(gt::ToPlatformType(image)));
373  EXPECT_EQ(kRepCount, image.RepresentationCount());
374
375  const SkBitmap* bitmap = image.ToSkBitmap();
376  EXPECT_FALSE(bitmap->isNull());
377  EXPECT_EQ(kRepCount, image.RepresentationCount());
378
379  EXPECT_TRUE(image.HasRepresentation(gfx::Image::kImageRepSkia));
380  EXPECT_TRUE(image.HasRepresentation(gt::GetPlatformRepresentationType()));
381  EXPECT_EQ(25, image.Width());
382  EXPECT_EQ(25, image.Height());
383}
384
385TEST_F(ImageTest, PlatformToSkia) {
386  gfx::Image image(gt::CreatePlatformImage());
387  EXPECT_EQ(25, image.Width());
388  EXPECT_EQ(25, image.Height());
389  const size_t kRepCount = kUsesSkiaNatively ? 1U : 2U;
390
391  EXPECT_TRUE(image.HasRepresentation(gt::GetPlatformRepresentationType()));
392  if (!kUsesSkiaNatively)
393    EXPECT_FALSE(image.HasRepresentation(gfx::Image::kImageRepSkia));
394
395  const SkBitmap* bitmap = image.ToSkBitmap();
396  EXPECT_TRUE(bitmap);
397  EXPECT_FALSE(bitmap->isNull());
398  EXPECT_EQ(kRepCount, image.RepresentationCount());
399
400  EXPECT_TRUE(gt::IsPlatformImageValid(gt::ToPlatformType(image)));
401  EXPECT_EQ(kRepCount, image.RepresentationCount());
402
403  EXPECT_TRUE(image.HasRepresentation(gfx::Image::kImageRepSkia));
404  EXPECT_EQ(25, image.Width());
405  EXPECT_EQ(25, image.Height());
406}
407
408TEST_F(ImageTest, PlatformToPlatform) {
409  gfx::Image image(gt::CreatePlatformImage());
410  EXPECT_EQ(25, image.Width());
411  EXPECT_EQ(25, image.Height());
412  EXPECT_TRUE(gt::IsPlatformImageValid(gt::ToPlatformType(image)));
413  EXPECT_EQ(1U, image.RepresentationCount());
414
415  // Make sure double conversion doesn't happen.
416  EXPECT_TRUE(gt::IsPlatformImageValid(gt::ToPlatformType(image)));
417  EXPECT_EQ(1U, image.RepresentationCount());
418
419  EXPECT_TRUE(image.HasRepresentation(gt::GetPlatformRepresentationType()));
420  if (!kUsesSkiaNatively)
421    EXPECT_FALSE(image.HasRepresentation(gfx::Image::kImageRepSkia));
422  EXPECT_EQ(25, image.Width());
423  EXPECT_EQ(25, image.Height());
424}
425
426TEST_F(ImageTest, PlatformToSkiaToCopy) {
427  const gfx::ImageSkia* image_skia = NULL;
428  {
429    gfx::Image image(gt::CreatePlatformImage());
430    image_skia = image.CopyImageSkia();
431  }
432  EXPECT_TRUE(image_skia);
433  EXPECT_FALSE(image_skia->isNull());
434  delete image_skia;
435
436  const SkBitmap* bitmap = NULL;
437  {
438    gfx::Image image(gt::CreatePlatformImage());
439    bitmap = image.CopySkBitmap();
440  }
441
442  EXPECT_TRUE(bitmap);
443  EXPECT_FALSE(bitmap->isNull());
444  delete bitmap;
445}
446
447#if defined(OS_IOS)
448TEST_F(ImageTest, SkiaToCocoaTouchCopy) {
449  UIImage* ui_image;
450
451  {
452    gfx::Image image(gt::CreateImageSkia(25, 25));
453    ui_image = image.CopyUIImage();
454  }
455
456  EXPECT_TRUE(ui_image);
457  base::mac::NSObjectRelease(ui_image);
458}
459#elif defined(OS_MACOSX)
460TEST_F(ImageTest, SkiaToCocoaCopy) {
461  NSImage* ns_image;
462
463  {
464    gfx::Image image(gt::CreateImageSkia(25, 25));
465    ns_image = image.CopyNSImage();
466  }
467
468  EXPECT_TRUE(ns_image);
469  base::mac::NSObjectRelease(ns_image);
470}
471#endif
472
473TEST_F(ImageTest, CheckSkiaColor) {
474  gfx::Image image(gt::CreatePlatformImage());
475
476  const SkBitmap* bitmap = image.ToSkBitmap();
477  SkAutoLockPixels auto_lock(*bitmap);
478  gt::CheckColors(bitmap->getColor(10, 10), SK_ColorGREEN);
479}
480
481TEST_F(ImageTest, SkBitmapConversionPreservesOrientation) {
482  const int width = 50;
483  const int height = 50;
484  SkBitmap bitmap;
485  bitmap.allocN32Pixels(width, height);
486  bitmap.eraseARGB(255, 0, 255, 0);
487
488  // Paint the upper half of the image in red (lower half is in green).
489  SkCanvas canvas(bitmap);
490  SkPaint red;
491  red.setColor(SK_ColorRED);
492  canvas.drawRect(SkRect::MakeWH(width, height / 2), red);
493  {
494    SCOPED_TRACE("Checking color of the initial SkBitmap");
495    gt::CheckColors(bitmap.getColor(10, 10), SK_ColorRED);
496    gt::CheckColors(bitmap.getColor(10, 40), SK_ColorGREEN);
497  }
498
499  // Convert from SkBitmap to a platform representation, then check the upper
500  // half of the platform image to make sure it is red, not green.
501  gfx::Image from_skbitmap = gfx::Image::CreateFrom1xBitmap(bitmap);
502  {
503    SCOPED_TRACE("Checking color of the platform image");
504    gt::CheckColors(
505        gt::GetPlatformImageColor(gt::ToPlatformType(from_skbitmap), 10, 10),
506        SK_ColorRED);
507    gt::CheckColors(
508        gt::GetPlatformImageColor(gt::ToPlatformType(from_skbitmap), 10, 40),
509        SK_ColorGREEN);
510  }
511
512  // Force a conversion back to SkBitmap and check that the upper half is red.
513  gfx::Image from_platform(gt::CopyPlatformType(from_skbitmap));
514  const SkBitmap* bitmap2 = from_platform.ToSkBitmap();
515  SkAutoLockPixels auto_lock(*bitmap2);
516  {
517    SCOPED_TRACE("Checking color after conversion back to SkBitmap");
518    gt::CheckColors(bitmap2->getColor(10, 10), SK_ColorRED);
519    gt::CheckColors(bitmap2->getColor(10, 40), SK_ColorGREEN);
520  }
521}
522
523TEST_F(ImageTest, SkBitmapConversionPreservesTransparency) {
524  const int width = 50;
525  const int height = 50;
526  SkBitmap bitmap;
527  bitmap.allocN32Pixels(width, height);
528  bitmap.eraseARGB(0, 0, 255, 0);
529
530  // Paint the upper half of the image in red (lower half is transparent).
531  SkCanvas canvas(bitmap);
532  SkPaint red;
533  red.setColor(SK_ColorRED);
534  canvas.drawRect(SkRect::MakeWH(width, height / 2), red);
535  {
536    SCOPED_TRACE("Checking color of the initial SkBitmap");
537    gt::CheckColors(bitmap.getColor(10, 10), SK_ColorRED);
538    gt::CheckIsTransparent(bitmap.getColor(10, 40));
539  }
540
541  // Convert from SkBitmap to a platform representation, then check the upper
542  // half of the platform image to make sure it is red, not green.
543  gfx::Image from_skbitmap = gfx::Image::CreateFrom1xBitmap(bitmap);
544  {
545    SCOPED_TRACE("Checking color of the platform image");
546    gt::CheckColors(
547        gt::GetPlatformImageColor(gt::ToPlatformType(from_skbitmap), 10, 10),
548        SK_ColorRED);
549    gt::CheckIsTransparent(
550        gt::GetPlatformImageColor(gt::ToPlatformType(from_skbitmap), 10, 40));
551  }
552
553  // Force a conversion back to SkBitmap and check that the upper half is red.
554  gfx::Image from_platform(gt::CopyPlatformType(from_skbitmap));
555  const SkBitmap* bitmap2 = from_platform.ToSkBitmap();
556  SkAutoLockPixels auto_lock(*bitmap2);
557  {
558    SCOPED_TRACE("Checking color after conversion back to SkBitmap");
559    gt::CheckColors(bitmap2->getColor(10, 10), SK_ColorRED);
560    gt::CheckIsTransparent(bitmap.getColor(10, 40));
561  }
562}
563
564TEST_F(ImageTest, SwapRepresentations) {
565  const size_t kRepCount = kUsesSkiaNatively ? 1U : 2U;
566
567  gfx::Image image1(gt::CreateImageSkia(25, 25));
568  const gfx::ImageSkia* image_skia1 = image1.ToImageSkia();
569  EXPECT_EQ(1U, image1.RepresentationCount());
570
571  gfx::Image image2(gt::CreatePlatformImage());
572  const gfx::ImageSkia* image_skia2 = image2.ToImageSkia();
573  gt::PlatformImage platform_image = gt::ToPlatformType(image2);
574  EXPECT_EQ(kRepCount, image2.RepresentationCount());
575
576  image1.SwapRepresentations(&image2);
577
578  EXPECT_EQ(image_skia2, image1.ToImageSkia());
579  EXPECT_TRUE(gt::PlatformImagesEqual(platform_image,
580                                      gt::ToPlatformType(image1)));
581  EXPECT_EQ(image_skia1, image2.ToImageSkia());
582  EXPECT_EQ(kRepCount, image1.RepresentationCount());
583  EXPECT_EQ(1U, image2.RepresentationCount());
584}
585
586TEST_F(ImageTest, Copy) {
587  const size_t kRepCount = kUsesSkiaNatively ? 1U : 2U;
588
589  gfx::Image image1(gt::CreateImageSkia(25, 25));
590  EXPECT_EQ(25, image1.Width());
591  EXPECT_EQ(25, image1.Height());
592  gfx::Image image2(image1);
593  EXPECT_EQ(25, image2.Width());
594  EXPECT_EQ(25, image2.Height());
595
596  EXPECT_EQ(1U, image1.RepresentationCount());
597  EXPECT_EQ(1U, image2.RepresentationCount());
598  EXPECT_EQ(image1.ToImageSkia(), image2.ToImageSkia());
599
600  EXPECT_TRUE(gt::IsPlatformImageValid(gt::ToPlatformType(image2)));
601  EXPECT_EQ(kRepCount, image2.RepresentationCount());
602  EXPECT_EQ(kRepCount, image1.RepresentationCount());
603}
604
605TEST_F(ImageTest, Assign) {
606  gfx::Image image1(gt::CreatePlatformImage());
607  EXPECT_EQ(25, image1.Width());
608  EXPECT_EQ(25, image1.Height());
609  // Assignment must be on a separate line to the declaration in order to test
610  // assignment operator (instead of copy constructor).
611  gfx::Image image2;
612  image2 = image1;
613  EXPECT_EQ(25, image2.Width());
614  EXPECT_EQ(25, image2.Height());
615
616  EXPECT_EQ(1U, image1.RepresentationCount());
617  EXPECT_EQ(1U, image2.RepresentationCount());
618  EXPECT_EQ(image1.ToSkBitmap(), image2.ToSkBitmap());
619}
620
621TEST_F(ImageTest, MultiResolutionImageSkia) {
622  const int kWidth1x = 10;
623  const int kHeight1x = 12;
624  const int kWidth2x = 20;
625  const int kHeight2x = 24;
626
627  gfx::ImageSkia image_skia;
628  image_skia.AddRepresentation(gfx::ImageSkiaRep(
629      gt::CreateBitmap(kWidth1x, kHeight1x),
630      1.0f));
631  image_skia.AddRepresentation(gfx::ImageSkiaRep(
632      gt::CreateBitmap(kWidth2x, kHeight2x),
633      2.0f));
634
635  std::vector<float> scales;
636  scales.push_back(1.0f);
637  scales.push_back(2.0f);
638  EXPECT_TRUE(gt::ImageSkiaStructureMatches(image_skia, kWidth1x, kHeight1x,
639                                            scales));
640
641  // Check that the image has a single representation.
642  gfx::Image image(image_skia);
643  EXPECT_EQ(1u, image.RepresentationCount());
644  EXPECT_EQ(kWidth1x, image.Width());
645  EXPECT_EQ(kHeight1x, image.Height());
646}
647
648TEST_F(ImageTest, RemoveFromMultiResolutionImageSkia) {
649  const int kWidth2x = 20;
650  const int kHeight2x = 24;
651
652  gfx::ImageSkia image_skia;
653
654  image_skia.AddRepresentation(gfx::ImageSkiaRep(
655      gt::CreateBitmap(kWidth2x, kHeight2x), 2.0f));
656  EXPECT_EQ(1u, image_skia.image_reps().size());
657
658  image_skia.RemoveRepresentation(1.0f);
659  EXPECT_EQ(1u, image_skia.image_reps().size());
660
661  image_skia.RemoveRepresentation(2.0f);
662  EXPECT_EQ(0u, image_skia.image_reps().size());
663}
664
665// Tests that gfx::Image does indeed take ownership of the SkBitmap it is
666// passed.
667TEST_F(ImageTest, OwnershipTest) {
668  gfx::Image image;
669  {
670    SkBitmap bitmap(gt::CreateBitmap(10, 10));
671    EXPECT_TRUE(!bitmap.isNull());
672    image = gfx::Image(gfx::ImageSkia(
673        gfx::ImageSkiaRep(bitmap, 1.0f)));
674  }
675  EXPECT_TRUE(!image.ToSkBitmap()->isNull());
676}
677
678// Integration tests with UI toolkit frameworks require linking against the
679// Views library and cannot be here (ui_unittests doesn't include it). They
680// instead live in /chrome/browser/ui/tests/ui_gfx_image_unittest.cc.
681
682}  // namespace
683