image.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/image/image_png_rep.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_IOS)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/codec/png_codec.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gdk-pixbuf/gdk-pixbuf.h>
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gdk/gdk.h>
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <glib-object.h>
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/gtk/scoped_gobject.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/gtk_util.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/cairo_cached_surface.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_IOS)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/foundation_util.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia_util_ios.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/mac_util.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia_util_mac.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ImageSkia ImageSkiaFromGdkPixbuf(GdkPixbuf* pixbuf) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(pixbuf);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Canvas canvas(gfx::Size(gdk_pixbuf_get_width(pixbuf),
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               gdk_pixbuf_get_height(pixbuf)),
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     ui::SCALE_FACTOR_100P,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     false);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skia::ScopedPlatformPaint scoped_platform_paint(canvas.sk_canvas());
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cairo_t* cr = scoped_platform_paint.GetPlatformSurface();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cairo_paint(cr);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ImageSkia(canvas.ExtractImageRep());
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns a 16x16 red pixbuf to visually show error in decoding PNG.
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Also logs error to console.
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GdkPixbuf* GetErrorPixbuf() {
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LOG(ERROR) << "Unable to decode PNG.";
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 16, 16);
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gdk_pixbuf_fill(pixbuf, 0xff0000ff);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return pixbuf;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GdkPixbuf* GdkPixbufFromPNG(
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<gfx::ImagePNGRep>& image_png_reps) {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::RefCountedMemory> png_bytes(NULL);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < image_png_reps.size(); ++i) {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (image_png_reps[i].scale_factor == ui::SCALE_FACTOR_100P)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      png_bytes = image_png_reps[i].raw_data;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!png_bytes.get())
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return GetErrorPixbuf();
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkPixbuf* pixbuf = NULL;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::ScopedGObject<GdkPixbufLoader>::Type loader(gdk_pixbuf_loader_new());
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ok = gdk_pixbuf_loader_write(loader.get(),
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      reinterpret_cast<const guint8*>(png_bytes->front()), png_bytes->size(),
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NULL);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calling gdk_pixbuf_loader_close forces the data to be parsed by the
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // loader. This must be done before calling gdk_pixbuf_loader_get_pixbuf.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ok)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ok = gdk_pixbuf_loader_close(loader.get(), NULL);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ok)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pixbuf = gdk_pixbuf_loader_get_pixbuf(loader.get());
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pixbuf) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The pixbuf is owned by the scoped loader which will delete its ref when
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // it goes out of scope. Add a ref so that the pixbuf still exists.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_object_ref(pixbuf);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return GetErrorPixbuf();
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pixbuf;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromPixbuf(
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GdkPixbuf* pixbuf) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gchar* image = NULL;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gsize image_size;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GError* error = NULL;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(gdk_pixbuf_save_to_buffer(
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pixbuf, &image, &image_size, "png", &error, NULL));
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::RefCountedBytes> png_bytes(
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new base::RefCountedBytes());
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  png_bytes->data().assign(image, image + image_size);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_free(image);
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return png_bytes;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(TOOLKIT_GTK)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromUIImage(
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UIImage* uiimage);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Caller takes ownership of the returned UIImage.
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)UIImage* CreateUIImageFromPNG(
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<gfx::ImagePNGRep>& image_png_reps);
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Size UIImageSize(UIImage* image);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromNSImage(
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NSImage* nsimage);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Caller takes ownership of the returned NSImage.
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NSImage* NSImageFromPNG(const std::vector<gfx::ImagePNGRep>& image_png_reps);
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Size NSImageSize(NSImage* image);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_MACOSX)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ImageSkia* ImageSkiaFromPNG(
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<gfx::ImagePNGRep>& image_png_reps);
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromImageSkia(
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ImageSkia* skia);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns a 16x16 red image to visually show error in decoding PNG.
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Caller takes ownership of returned ImageSkia.
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ImageSkia* GetErrorImageSkia() {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap bitmap;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bitmap.setConfig(SkBitmap::kARGB_8888_Config, 16, 16);
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bitmap.allocPixels();
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bitmap.eraseRGB(0xff, 0, 0);
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return new gfx::ImageSkia(gfx::ImageSkiaRep(bitmap, ui::SCALE_FACTOR_100P));
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ImageSkia* ImageSkiaFromPNG(
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<gfx::ImagePNGRep>& image_png_reps) {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (image_png_reps.empty())
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return GetErrorImageSkia();
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<gfx::ImageSkia> image_skia(new ImageSkia());
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < image_png_reps.size(); ++i) {
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<base::RefCountedMemory> raw_data =
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        image_png_reps[i].raw_data;
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CHECK(raw_data.get());
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkBitmap bitmap;
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(),
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               &bitmap)) {
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(ERROR) << "Unable to decode PNG for "
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << ui::GetScaleFactorScale(image_png_reps[i].scale_factor)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << ".";
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GetErrorImageSkia();
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    image_skia->AddRepresentation(gfx::ImageSkiaRep(
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        bitmap, image_png_reps[i].scale_factor));
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return image_skia.release();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromImageSkia(
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ImageSkia* image_skia) {
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ImageSkiaRep image_skia_rep = image_skia->GetRepresentation(
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ui::SCALE_FACTOR_100P);
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::RefCountedBytes> png_bytes(new base::RefCountedBytes());
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (image_skia_rep.scale_factor() != ui::SCALE_FACTOR_100P ||
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !gfx::PNGCodec::EncodeBGRASkBitmap(image_skia_rep.sk_bitmap(), false,
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &png_bytes->data())) {
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return png_bytes;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepPNG;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepSkia;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepGdk;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepCairo;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepCocoa;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepCocoaTouch;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An ImageRep is the object that holds the backing memory for an Image. Each
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RepresentationType has an ImageRep subclass that is responsible for freeing
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the memory that the ImageRep holds. When an ImageRep is created, it expects
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to take ownership of the image, without having to retain it or increase its
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reference count.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRep {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ImageRep(Image::RepresentationType rep) : type_(rep) {}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Deletes the associated pixels of an ImageRep.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ImageRep() {}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cast helpers ("fake RTTI").
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageRepPNG* AsImageRepPNG() {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(type_, Image::kImageRepPNG);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return reinterpret_cast<ImageRepPNG*>(this);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageRepSkia* AsImageRepSkia() {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(type_, Image::kImageRepSkia);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return reinterpret_cast<ImageRepSkia*>(this);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageRepGdk* AsImageRepGdk() {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(type_, Image::kImageRepGdk);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return reinterpret_cast<ImageRepGdk*>(this);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageRepCairo* AsImageRepCairo() {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(type_, Image::kImageRepCairo);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return reinterpret_cast<ImageRepCairo*>(this);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageRepCocoaTouch* AsImageRepCocoaTouch() {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(type_, Image::kImageRepCocoaTouch);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return reinterpret_cast<ImageRepCocoaTouch*>(this);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageRepCocoa* AsImageRepCocoa() {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_EQ(type_, Image::kImageRepCocoa);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return reinterpret_cast<ImageRepCocoa*>(this);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Image::RepresentationType type() const { return type_; }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual int Width() const = 0;
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual int Height() const = 0;
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual gfx::Size Size() const = 0;
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Image::RepresentationType type_;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepPNG : public ImageRep {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageRepPNG() : ImageRep(Image::kImageRepPNG) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ImageRepPNG(const std::vector<ImagePNGRep>& image_png_reps)
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : ImageRep(Image::kImageRepPNG),
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        image_png_reps_(image_png_reps) {
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ImageRepPNG() {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual int Width() const OVERRIDE {
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return Size().width();
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual int Height() const OVERRIDE {
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return Size().height();
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual gfx::Size Size() const OVERRIDE {
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Read the PNG data to get the image size, caching it.
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!size_cache_) {
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (std::vector<ImagePNGRep>::const_iterator it = image_reps().begin();
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           it != image_reps().end(); ++it) {
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (it->scale_factor == ui::SCALE_FACTOR_100P) {
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          size_cache_.reset(new gfx::Size(it->Size()));
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          return *size_cache_;
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      size_cache_.reset(new gfx::Size);
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return *size_cache_;
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const std::vector<ImagePNGRep>& image_reps() const { return image_png_reps_; }
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<ImagePNGRep> image_png_reps_;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Cached to avoid having to parse the raw data multiple times.
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  mutable scoped_ptr<gfx::Size> size_cache_;
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ImageRepPNG);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepSkia : public ImageRep {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Takes ownership of |image|.
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ImageRepSkia(ImageSkia* image)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : ImageRep(Image::kImageRepSkia),
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        image_(image) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ImageRepSkia() {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual int Width() const OVERRIDE {
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return image_->width();
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual int Height() const OVERRIDE {
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return image_->height();
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual gfx::Size Size() const OVERRIDE {
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return image_->size();
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageSkia* image() { return image_.get(); }
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ImageSkia> image_;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ImageRepSkia);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepGdk : public ImageRep {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ImageRepGdk(GdkPixbuf* pixbuf)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : ImageRep(Image::kImageRepGdk),
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pixbuf_(pixbuf) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(pixbuf);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ImageRepGdk() {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pixbuf_) {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      g_object_unref(pixbuf_);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pixbuf_ = NULL;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual int Width() const OVERRIDE {
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return gdk_pixbuf_get_width(pixbuf_);
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual int Height() const OVERRIDE {
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return gdk_pixbuf_get_height(pixbuf_);
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual gfx::Size Size() const OVERRIDE {
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return gfx::Size(Width(), Height());
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkPixbuf* pixbuf() const { return pixbuf_; }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkPixbuf* pixbuf_;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ImageRepGdk);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Represents data that lives on the display server instead of in the client.
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepCairo : public ImageRep {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ImageRepCairo(GdkPixbuf* pixbuf)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : ImageRep(Image::kImageRepCairo),
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cairo_cache_(new CairoCachedSurface) {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(pixbuf);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cairo_cache_->UsePixbuf(pixbuf);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ImageRepCairo() {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete cairo_cache_;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual int Width() const OVERRIDE {
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return cairo_cache_->Width();
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual int Height() const OVERRIDE {
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return cairo_cache_->Height();
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual gfx::Size Size() const OVERRIDE {
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return gfx::Size(Width(), Height());
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CairoCachedSurface* surface() const { return cairo_cache_; }
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CairoCachedSurface* cairo_cache_;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ImageRepCairo);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(TOOLKIT_GTK)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepCocoaTouch : public ImageRep {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ImageRepCocoaTouch(UIImage* image)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : ImageRep(Image::kImageRepCocoaTouch),
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        image_(image) {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(image);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ImageRepCocoaTouch() {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::mac::NSObjectRelease(image_);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    image_ = nil;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual int Width() const OVERRIDE {
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return Size().width();
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual int Height() const OVERRIDE {
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return Size().height();
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
42290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual gfx::Size Size() const OVERRIDE {
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return internal::UIImageSize(image_);
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UIImage* image() const { return image_; }
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UIImage* image_;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ImageRepCocoaTouch);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageRepCocoa : public ImageRep {
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ImageRepCocoa(NSImage* image)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : ImageRep(Image::kImageRepCocoa),
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        image_(image) {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(image);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ImageRepCocoa() {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::mac::NSObjectRelease(image_);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    image_ = nil;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual int Width() const OVERRIDE {
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return Size().width();
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual int Height() const OVERRIDE {
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return Size().height();
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual gfx::Size Size() const OVERRIDE {
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return internal::NSImageSize(image_);
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSImage* image() const { return image_; }
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSImage* image_;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ImageRepCocoa);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // defined(OS_MACOSX)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The Storage class acts similarly to the pixels in a SkBitmap: the Image
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// class holds a refptr instance of Storage, which in turn holds all the
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ImageReps. This way, the Image can be cheaply copied.
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageStorage : public base::RefCounted<ImageStorage> {
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageStorage(gfx::Image::RepresentationType default_type)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : default_representation_type_(default_type),
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        representations_deleter_(&representations_) {
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Image::RepresentationType default_representation_type() {
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return default_representation_type_;
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Image::RepresentationMap& representations() { return representations_; }
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCounted<ImageStorage>;
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ImageStorage() {}
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The type of image that was passed to the constructor. This key will always
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // exist in the |representations_| map.
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Image::RepresentationType default_representation_type_;
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All the representations of an Image. Size will always be at least one, with
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // more for any converted representations.
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Image::RepresentationMap representations_;
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  STLValueDeleter<Image::RepresentationMap> representations_deleter_;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ImageStorage);
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image::Image() {
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |storage_| is NULL for empty Images.
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Image::Image(const std::vector<ImagePNGRep>& image_reps) {
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Do not store obviously invalid ImagePNGReps.
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<ImagePNGRep> filtered;
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < image_reps.size(); ++i) {
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (image_reps[i].raw_data.get() && image_reps[i].raw_data->size())
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      filtered.push_back(image_reps[i]);
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (filtered.empty())
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  storage_ = new internal::ImageStorage(Image::kImageRepPNG);
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  internal::ImageRepPNG* rep = new internal::ImageRepPNG(filtered);
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRepresentation(rep);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image::Image(const ImageSkia& image) {
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!image.isNull()) {
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    storage_ = new internal::ImageStorage(Image::kImageRepSkia);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    internal::ImageRepSkia* rep = new internal::ImageRepSkia(
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new ImageSkia(image));
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddRepresentation(rep);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image::Image(GdkPixbuf* pixbuf) {
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pixbuf) {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    storage_ = new internal::ImageStorage(Image::kImageRepGdk);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    internal::ImageRepGdk* rep = new internal::ImageRepGdk(pixbuf);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddRepresentation(rep);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image::Image(UIImage* image)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : storage_(new internal::ImageStorage(Image::kImageRepCocoaTouch)) {
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (image) {
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    internal::ImageRepCocoaTouch* rep = new internal::ImageRepCocoaTouch(image);
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddRepresentation(rep);
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image::Image(NSImage* image) {
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (image) {
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    storage_ = new internal::ImageStorage(Image::kImageRepCocoa);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    internal::ImageRepCocoa* rep = new internal::ImageRepCocoa(image);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddRepresentation(rep);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image::Image(const Image& other) : storage_(other.storage_) {
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image& Image::operator=(const Image& other) {
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  storage_ = other.storage_;
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *this;
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image::~Image() {
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Image Image::CreateFrom1xBitmap(const SkBitmap& bitmap) {
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gfx::Image(ImageSkia::CreateFrom1xBitmap(bitmap));
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Image Image::CreateFrom1xPNGBytes(const unsigned char* input,
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  size_t input_size) {
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (input_size == 0u)
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return gfx::Image();
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::RefCountedBytes> raw_data(new base::RefCountedBytes());
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  raw_data->data().assign(input, input + input_size);
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<gfx::ImagePNGRep> image_reps;
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  image_reps.push_back(ImagePNGRep(raw_data, ui::SCALE_FACTOR_100P));
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return gfx::Image(image_reps);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkBitmap* Image::ToSkBitmap() const {
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Possibly create and cache an intermediate ImageRepSkia.
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ToImageSkia()->bitmap();
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ImageSkia* Image::ToImageSkia() const {
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ImageRep* rep = GetRepresentation(kImageRepSkia, false);
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!rep) {
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (DefaultRepresentationType()) {
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case kImageRepPNG: {
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        internal::ImageRepPNG* png_rep =
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetRepresentation(kImageRepPNG, true)->AsImageRepPNG();
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rep = new internal::ImageRepSkia(
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            internal::ImageSkiaFromPNG(png_rep->image_reps()));
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK)
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case kImageRepGdk: {
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        internal::ImageRepGdk* native_rep =
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetRepresentation(kImageRepGdk, true)->AsImageRepGdk();
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rep = new internal::ImageRepSkia(new ImageSkia(
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            internal::ImageSkiaFromGdkPixbuf(native_rep->pixbuf())));
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_IOS)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case kImageRepCocoaTouch: {
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        internal::ImageRepCocoaTouch* native_rep =
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetRepresentation(kImageRepCocoaTouch, true)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ->AsImageRepCocoaTouch();
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rep = new internal::ImageRepSkia(new ImageSkia(
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ImageSkiaFromUIImage(native_rep->image())));
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case kImageRepCocoa: {
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        internal::ImageRepCocoa* native_rep =
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetRepresentation(kImageRepCocoa, true)->AsImageRepCocoa();
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rep = new internal::ImageRepSkia(new ImageSkia(
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ImageSkiaFromNSImage(native_rep->image())));
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(rep);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddRepresentation(rep);
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rep->AsImageRepSkia()->image();
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GdkPixbuf* Image::ToGdkPixbuf() const {
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ImageRep* rep = GetRepresentation(kImageRepGdk, false);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!rep) {
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (DefaultRepresentationType()) {
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case kImageRepPNG: {
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        internal::ImageRepPNG* png_rep =
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetRepresentation(kImageRepPNG, true)->AsImageRepPNG();
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rep = new internal::ImageRepGdk(internal::GdkPixbufFromPNG(
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            png_rep->image_reps()));
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case kImageRepSkia: {
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        internal::ImageRepSkia* skia_rep =
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetRepresentation(kImageRepSkia, true)->AsImageRepSkia();
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rep = new internal::ImageRepGdk(gfx::GdkPixbufFromSkBitmap(
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            *skia_rep->image()->bitmap()));
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(rep);
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddRepresentation(rep);
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rep->AsImageRepGdk()->pixbuf();
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CairoCachedSurface* const Image::ToCairo() const {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ImageRep* rep = GetRepresentation(kImageRepCairo, false);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!rep) {
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Handle any-to-Cairo conversion. This may create and cache an intermediate
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // pixbuf before sending the data to the display server.
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rep = new internal::ImageRepCairo(ToGdkPixbuf());
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(rep);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddRepresentation(rep);
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rep->AsImageRepCairo()->surface();
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS)
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UIImage* Image::ToUIImage() const {
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ImageRep* rep = GetRepresentation(kImageRepCocoaTouch, false);
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!rep) {
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (DefaultRepresentationType()) {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case kImageRepPNG: {
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        internal::ImageRepPNG* png_rep =
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetRepresentation(kImageRepPNG, true)->AsImageRepPNG();
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rep = new internal::ImageRepCocoaTouch(internal::CreateUIImageFromPNG(
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            png_rep->image_reps()));
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case kImageRepSkia: {
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        internal::ImageRepSkia* skia_rep =
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetRepresentation(kImageRepSkia, true)->AsImageRepSkia();
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UIImage* image = UIImageFromImageSkia(*skia_rep->image());
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::mac::NSObjectRetain(image);
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rep = new internal::ImageRepCocoaTouch(image);
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(rep);
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddRepresentation(rep);
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rep->AsImageRepCocoaTouch()->image();
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSImage* Image::ToNSImage() const {
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ImageRep* rep = GetRepresentation(kImageRepCocoa, false);
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!rep) {
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (DefaultRepresentationType()) {
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case kImageRepPNG: {
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        internal::ImageRepPNG* png_rep =
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetRepresentation(kImageRepPNG, true)->AsImageRepPNG();
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rep = new internal::ImageRepCocoa(internal::NSImageFromPNG(
7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            png_rep->image_reps()));
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case kImageRepSkia: {
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        internal::ImageRepSkia* skia_rep =
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetRepresentation(kImageRepSkia, true)->AsImageRepSkia();
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NSImage* image = NSImageFromImageSkia(*skia_rep->image());
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::mac::NSObjectRetain(image);
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rep = new internal::ImageRepCocoa(image);
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(rep);
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddRepresentation(rep);
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rep->AsImageRepCocoa()->image();
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<base::RefCountedMemory> Image::As1xPNGBytes() const {
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsEmpty())
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return new base::RefCountedBytes();
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  internal::ImageRep* rep = GetRepresentation(kImageRepPNG, false);
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rep) {
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<gfx::ImagePNGRep>& image_png_reps =
7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        rep->AsImageRepPNG()->image_reps();
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < image_png_reps.size(); ++i) {
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (image_png_reps[i].scale_factor == ui::SCALE_FACTOR_100P)
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return image_png_reps[i].raw_data;
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return new base::RefCountedBytes();
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::RefCountedMemory> png_bytes(NULL);
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (DefaultRepresentationType()) {
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(TOOLKIT_GTK)
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kImageRepGdk: {
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      internal::ImageRepGdk* gdk_rep =
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRepresentation(kImageRepGdk, true)->AsImageRepGdk();
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      png_bytes = internal::Get1xPNGBytesFromPixbuf(gdk_rep->pixbuf());
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_IOS)
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kImageRepCocoaTouch: {
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      internal::ImageRepCocoaTouch* cocoa_touch_rep =
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRepresentation(kImageRepCocoaTouch, true)
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              ->AsImageRepCocoaTouch();
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      png_bytes = internal::Get1xPNGBytesFromUIImage(
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          cocoa_touch_rep->image());
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_MACOSX)
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kImageRepCocoa: {
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      internal::ImageRepCocoa* cocoa_rep =
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRepresentation(kImageRepCocoa, true)->AsImageRepCocoa();
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      png_bytes = internal::Get1xPNGBytesFromNSImage(cocoa_rep->image());
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kImageRepSkia: {
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      internal::ImageRepSkia* skia_rep =
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetRepresentation(kImageRepSkia, true)->AsImageRepSkia();
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      png_bytes = internal::Get1xPNGBytesFromImageSkia(skia_rep->image());
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!png_bytes.get() || !png_bytes->size()) {
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Add an ImageRepPNG with no data such that the conversion is not
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // attempted each time we want the PNG bytes.
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddRepresentation(new internal::ImageRepPNG());
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return new base::RefCountedBytes();
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Do not insert representations for scale factors other than 1x even if
7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // they are available because:
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // - Only the 1x PNG bytes can be accessed.
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // - ImageRepPNG is not used as an intermediate type in converting to a
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   final type eg (converting from ImageRepSkia to ImageRepPNG to get an
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   ImageRepCocoa).
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<ImagePNGRep> image_png_reps;
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  image_png_reps.push_back(gfx::ImagePNGRep(png_bytes,
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            ui::SCALE_FACTOR_100P));
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rep = new internal::ImageRepPNG(image_png_reps);
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddRepresentation(rep);
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return png_bytes;
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkBitmap Image::AsBitmap() const {
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return IsEmpty() ? SkBitmap() : *ToSkBitmap();
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageSkia Image::AsImageSkia() const {
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return IsEmpty() ? ImageSkia() : *ToImageSkia();
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) && !defined(OS_IOS)
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSImage* Image::AsNSImage() const {
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return IsEmpty() ? nil : ToNSImage();
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<base::RefCountedMemory> Image::Copy1xPNGBytes() const {
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::RefCountedMemory> original = As1xPNGBytes();
8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::RefCountedBytes> copy(new base::RefCountedBytes());
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  copy->data().assign(original->front(), original->front() + original->size());
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return copy;
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ImageSkia* Image::CopyImageSkia() const {
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new ImageSkia(*ToImageSkia());
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkBitmap* Image::CopySkBitmap() const {
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new SkBitmap(*ToSkBitmap());
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK)
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GdkPixbuf* Image::CopyGdkPixbuf() const {
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkPixbuf* pixbuf = ToGdkPixbuf();
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_object_ref(pixbuf);
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pixbuf;
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS)
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UIImage* Image::CopyUIImage() const {
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UIImage* image = ToUIImage();
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::mac::NSObjectRetain(image);
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return image;
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSImage* Image::CopyNSImage() const {
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSImage* image = ToNSImage();
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::mac::NSObjectRetain(image);
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return image;
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Image::HasRepresentation(RepresentationType type) const {
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return storage_.get() && storage_->representations().count(type) != 0;
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t Image::RepresentationCount() const {
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!storage_.get())
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return storage_->representations().size();
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Image::IsEmpty() const {
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return RepresentationCount() == 0;
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int Image::Width() const {
878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsEmpty())
879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return 0;
880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return GetRepresentation(DefaultRepresentationType(), true)->Width();
881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int Image::Height() const {
884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsEmpty())
885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return 0;
886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return GetRepresentation(DefaultRepresentationType(), true)->Height();
887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Size Image::Size() const {
890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsEmpty())
891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return gfx::Size();
892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return GetRepresentation(DefaultRepresentationType(), true)->Size();
893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Image::SwapRepresentations(gfx::Image* other) {
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  storage_.swap(other->storage_);
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Image::RepresentationType Image::DefaultRepresentationType() const {
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(storage_.get());
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RepresentationType default_type = storage_->default_representation_type();
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The conversions above assume that the default representation type is never
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // kImageRepCairo.
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(default_type, kImageRepCairo);
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return default_type;
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)internal::ImageRep* Image::GetRepresentation(
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RepresentationType rep_type, bool must_exist) const {
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(storage_.get());
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RepresentationMap::iterator it = storage_->representations().find(rep_type);
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == storage_->representations().end()) {
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(!must_exist);
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return it->second;
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Image::AddRepresentation(internal::ImageRep* rep) const {
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(storage_.get());
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  storage_->representations().insert(std::make_pair(rep->type(), rep));
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gfx
925