// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/themes/browser_theme_pack.h"

#include <limits>

#include "base/files/file.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "chrome/browser/themes/theme_properties.h"
#include "chrome/common/extensions/manifest_handlers/theme_handler.h"
#include "components/crx_file/id_util.h"
#include "content/public/browser/browser_thread.h"
#include "grit/theme_resources.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/base/resource/data_pack.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/image/canvas_image_source.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/size_conversions.h"
#include "ui/gfx/skia_util.h"
#include "ui/resources/grit/ui_resources.h"

using content::BrowserThread;
using extensions::Extension;

namespace {

// Version number of the current theme pack. We just throw out and rebuild
// theme packs that aren't int-equal to this. Increment this number if you
// change default theme assets.
const int kThemePackVersion = 35;

// IDs that are in the DataPack won't clash with the positive integer
// uint16. kHeaderID should always have the maximum value because we want the
// "header" to be written last. That way we can detect whether the pack was
// successfully written and ignore and regenerate if it was only partially
// written (i.e. chrome crashed on a different thread while writing the pack).
const int kMaxID = 0x0000FFFF;  // Max unsigned 16-bit int.
const int kHeaderID = kMaxID - 1;
const int kTintsID = kMaxID - 2;
const int kColorsID = kMaxID - 3;
const int kDisplayPropertiesID = kMaxID - 4;
const int kSourceImagesID = kMaxID - 5;
const int kScaleFactorsID = kMaxID - 6;

// The sum of kFrameBorderThickness and kNonClientRestoredExtraThickness from
// OpaqueBrowserFrameView.
const int kRestoredTabVerticalOffset = 15;

// Persistent constants for the main images that we need. These have the same
// names as their IDR_* counterparts but these values will always stay the
// same.
const int PRS_THEME_FRAME = 1;
const int PRS_THEME_FRAME_INACTIVE = 2;
const int PRS_THEME_FRAME_INCOGNITO = 3;
const int PRS_THEME_FRAME_INCOGNITO_INACTIVE = 4;
const int PRS_THEME_TOOLBAR = 5;
const int PRS_THEME_TAB_BACKGROUND = 6;
const int PRS_THEME_TAB_BACKGROUND_INCOGNITO = 7;
const int PRS_THEME_TAB_BACKGROUND_V = 8;
const int PRS_THEME_NTP_BACKGROUND = 9;
const int PRS_THEME_FRAME_OVERLAY = 10;
const int PRS_THEME_FRAME_OVERLAY_INACTIVE = 11;
const int PRS_THEME_BUTTON_BACKGROUND = 12;
const int PRS_THEME_NTP_ATTRIBUTION = 13;
const int PRS_THEME_WINDOW_CONTROL_BACKGROUND = 14;

struct PersistingImagesTable {
  // A non-changing integer ID meant to be saved in theme packs. This ID must
  // not change between versions of chrome.
  int persistent_id;

  // The IDR that depends on the whims of GRIT and therefore changes whenever
  // someone adds a new resource.
  int idr_id;

  // String to check for when parsing theme manifests or NULL if this isn't
  // supposed to be changeable by the user.
  const char* key;
};

// IDR_* resource names change whenever new resources are added; use persistent
// IDs when storing to a cached pack.
//
// TODO(erg): The cocoa port is the last user of the IDR_*_[HP] variants. These
// should be removed once the cocoa port no longer uses them.
PersistingImagesTable kPersistingImages[] = {
  { PRS_THEME_FRAME, IDR_THEME_FRAME,
    "theme_frame" },
  { PRS_THEME_FRAME_INACTIVE, IDR_THEME_FRAME_INACTIVE,
    "theme_frame_inactive" },
  { PRS_THEME_FRAME_INCOGNITO, IDR_THEME_FRAME_INCOGNITO,
    "theme_frame_incognito" },
  { PRS_THEME_FRAME_INCOGNITO_INACTIVE, IDR_THEME_FRAME_INCOGNITO_INACTIVE,
    "theme_frame_incognito_inactive" },
  { PRS_THEME_TOOLBAR, IDR_THEME_TOOLBAR,
    "theme_toolbar" },
  { PRS_THEME_TAB_BACKGROUND, IDR_THEME_TAB_BACKGROUND,
    "theme_tab_background" },
#if !defined(OS_MACOSX)
  { PRS_THEME_TAB_BACKGROUND_INCOGNITO, IDR_THEME_TAB_BACKGROUND_INCOGNITO,
    "theme_tab_background_incognito" },
#endif
  { PRS_THEME_TAB_BACKGROUND_V, IDR_THEME_TAB_BACKGROUND_V,
    "theme_tab_background_v"},
  { PRS_THEME_NTP_BACKGROUND, IDR_THEME_NTP_BACKGROUND,
    "theme_ntp_background" },
  { PRS_THEME_FRAME_OVERLAY, IDR_THEME_FRAME_OVERLAY,
    "theme_frame_overlay" },
  { PRS_THEME_FRAME_OVERLAY_INACTIVE, IDR_THEME_FRAME_OVERLAY_INACTIVE,
    "theme_frame_overlay_inactive" },
  { PRS_THEME_BUTTON_BACKGROUND, IDR_THEME_BUTTON_BACKGROUND,
    "theme_button_background" },
  { PRS_THEME_NTP_ATTRIBUTION, IDR_THEME_NTP_ATTRIBUTION,
    "theme_ntp_attribution" },
  { PRS_THEME_WINDOW_CONTROL_BACKGROUND, IDR_THEME_WINDOW_CONTROL_BACKGROUND,
    "theme_window_control_background"},

  // The rest of these entries have no key because they can't be overridden
  // from the json manifest.
  { 15, IDR_BACK, NULL },
  { 16, IDR_BACK_D, NULL },
  { 17, IDR_BACK_H, NULL },
  { 18, IDR_BACK_P, NULL },
  { 19, IDR_FORWARD, NULL },
  { 20, IDR_FORWARD_D, NULL },
  { 21, IDR_FORWARD_H, NULL },
  { 22, IDR_FORWARD_P, NULL },
  { 23, IDR_HOME, NULL },
  { 24, IDR_HOME_H, NULL },
  { 25, IDR_HOME_P, NULL },
  { 26, IDR_RELOAD, NULL },
  { 27, IDR_RELOAD_H, NULL },
  { 28, IDR_RELOAD_P, NULL },
  { 29, IDR_STOP, NULL },
  { 30, IDR_STOP_D, NULL },
  { 31, IDR_STOP_H, NULL },
  { 32, IDR_STOP_P, NULL },
  { 33, IDR_BROWSER_ACTIONS_OVERFLOW, NULL },
  { 34, IDR_BROWSER_ACTIONS_OVERFLOW_H, NULL },
  { 35, IDR_BROWSER_ACTIONS_OVERFLOW_P, NULL },
  { 36, IDR_TOOLS, NULL },
  { 37, IDR_TOOLS_H, NULL },
  { 38, IDR_TOOLS_P, NULL },
  { 39, IDR_MENU_DROPARROW, NULL },
  { 40, IDR_THROBBER, NULL },
  { 41, IDR_THROBBER_WAITING, NULL },
  { 42, IDR_THROBBER_LIGHT, NULL },
  { 43, IDR_TOOLBAR_BEZEL_HOVER, NULL },
  { 44, IDR_TOOLBAR_BEZEL_PRESSED, NULL },
  { 45, IDR_TOOLS_BAR, NULL },
};
const size_t kPersistingImagesLength = arraysize(kPersistingImages);

#if defined(USE_ASH) && !defined(OS_CHROMEOS)
// Persistent theme ids for Windows.
const int PRS_THEME_FRAME_DESKTOP = 100;
const int PRS_THEME_FRAME_INACTIVE_DESKTOP = 101;
const int PRS_THEME_FRAME_INCOGNITO_DESKTOP = 102;
const int PRS_THEME_FRAME_INCOGNITO_INACTIVE_DESKTOP = 103;
const int PRS_THEME_TOOLBAR_DESKTOP = 104;
const int PRS_THEME_TAB_BACKGROUND_DESKTOP = 105;
const int PRS_THEME_TAB_BACKGROUND_INCOGNITO_DESKTOP = 106;

// Persistent theme to resource id mapping for Windows AURA.
PersistingImagesTable kPersistingImagesDesktopAura[] = {
  { PRS_THEME_FRAME_DESKTOP, IDR_THEME_FRAME_DESKTOP,
    "theme_frame" },
  { PRS_THEME_FRAME_INACTIVE_DESKTOP, IDR_THEME_FRAME_INACTIVE_DESKTOP,
    "theme_frame_inactive" },
  { PRS_THEME_FRAME_INCOGNITO_DESKTOP, IDR_THEME_FRAME_INCOGNITO_DESKTOP,
    "theme_frame_incognito" },
  { PRS_THEME_FRAME_INCOGNITO_INACTIVE_DESKTOP,
    IDR_THEME_FRAME_INCOGNITO_INACTIVE_DESKTOP,
    "theme_frame_incognito_inactive" },
  { PRS_THEME_TOOLBAR_DESKTOP, IDR_THEME_TOOLBAR_DESKTOP,
    "theme_toolbar" },
  { PRS_THEME_TAB_BACKGROUND_DESKTOP, IDR_THEME_TAB_BACKGROUND_DESKTOP,
    "theme_tab_background" },
  { PRS_THEME_TAB_BACKGROUND_INCOGNITO_DESKTOP,
    IDR_THEME_TAB_BACKGROUND_INCOGNITO_DESKTOP,
    "theme_tab_background_incognito" },
};
const size_t kPersistingImagesDesktopAuraLength =
    arraysize(kPersistingImagesDesktopAura);
#endif

int GetPersistentIDByNameHelper(const std::string& key,
                                const PersistingImagesTable* image_table,
                                size_t image_table_size) {
  for (size_t i = 0; i < image_table_size; ++i) {
    if (image_table[i].key != NULL &&
        base::strcasecmp(key.c_str(), image_table[i].key) == 0) {
      return image_table[i].persistent_id;
    }
  }
  return -1;
}

int GetPersistentIDByName(const std::string& key) {
  return GetPersistentIDByNameHelper(key,
                                     kPersistingImages,
                                     kPersistingImagesLength);
}

int GetPersistentIDByIDR(int idr) {
  static std::map<int,int>* lookup_table = new std::map<int,int>();
  if (lookup_table->empty()) {
    for (size_t i = 0; i < kPersistingImagesLength; ++i) {
      int idr = kPersistingImages[i].idr_id;
      int prs_id = kPersistingImages[i].persistent_id;
      (*lookup_table)[idr] = prs_id;
    }
#if defined(USE_ASH) && !defined(OS_CHROMEOS)
    for (size_t i = 0; i < kPersistingImagesDesktopAuraLength; ++i) {
      int idr = kPersistingImagesDesktopAura[i].idr_id;
      int prs_id = kPersistingImagesDesktopAura[i].persistent_id;
      (*lookup_table)[idr] = prs_id;
    }
#endif
  }
  std::map<int,int>::iterator it = lookup_table->find(idr);
  return (it == lookup_table->end()) ? -1 : it->second;
}

// Returns the maximum persistent id.
int GetMaxPersistentId() {
  static int max_prs_id = -1;
  if (max_prs_id == -1) {
    for (size_t i = 0; i < kPersistingImagesLength; ++i) {
      if (kPersistingImages[i].persistent_id > max_prs_id)
        max_prs_id = kPersistingImages[i].persistent_id;
    }
#if defined(USE_ASH) && !defined(OS_CHROMEOS)
    for (size_t i = 0; i < kPersistingImagesDesktopAuraLength; ++i) {
      if (kPersistingImagesDesktopAura[i].persistent_id > max_prs_id)
        max_prs_id = kPersistingImagesDesktopAura[i].persistent_id;
    }
#endif
  }
  return max_prs_id;
}

// Returns true if the scales in |input| match those in |expected|.
// The order must match as the index is used in determining the raw id.
bool InputScalesValid(const base::StringPiece& input,
                      const std::vector<ui::ScaleFactor>& expected) {
  size_t scales_size = static_cast<size_t>(input.size() / sizeof(float));
  if (scales_size != expected.size())
    return false;
  scoped_ptr<float[]> scales(new float[scales_size]);
  // Do a memcpy to avoid misaligned memory access.
  memcpy(scales.get(), input.data(), input.size());
  for (size_t index = 0; index < scales_size; ++index) {
    if (scales[index] != ui::GetScaleForScaleFactor(expected[index]))
      return false;
  }
  return true;
}

// Returns |scale_factors| as a string to be written to disk.
std::string GetScaleFactorsAsString(
    const std::vector<ui::ScaleFactor>& scale_factors) {
  scoped_ptr<float[]> scales(new float[scale_factors.size()]);
  for (size_t i = 0; i < scale_factors.size(); ++i)
    scales[i] = ui::GetScaleForScaleFactor(scale_factors[i]);
  std::string out_string = std::string(
      reinterpret_cast<const char*>(scales.get()),
      scale_factors.size() * sizeof(float));
  return out_string;
}

struct StringToIntTable {
  const char* key;
  ThemeProperties::OverwritableByUserThemeProperty id;
};

// Strings used by themes to identify tints in the JSON.
StringToIntTable kTintTable[] = {
  { "buttons", ThemeProperties::TINT_BUTTONS },
  { "frame", ThemeProperties::TINT_FRAME },
  { "frame_inactive", ThemeProperties::TINT_FRAME_INACTIVE },
  { "frame_incognito", ThemeProperties::TINT_FRAME_INCOGNITO },
  { "frame_incognito_inactive",
    ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE },
  { "background_tab", ThemeProperties::TINT_BACKGROUND_TAB },
};
const size_t kTintTableLength = arraysize(kTintTable);

// Strings used by themes to identify colors in the JSON.
StringToIntTable kColorTable[] = {
  { "frame", ThemeProperties::COLOR_FRAME },
  { "frame_inactive", ThemeProperties::COLOR_FRAME_INACTIVE },
  { "frame_incognito", ThemeProperties::COLOR_FRAME_INCOGNITO },
  { "frame_incognito_inactive",
    ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE },
  { "toolbar", ThemeProperties::COLOR_TOOLBAR },
  { "tab_text", ThemeProperties::COLOR_TAB_TEXT },
  { "tab_background_text", ThemeProperties::COLOR_BACKGROUND_TAB_TEXT },
  { "bookmark_text", ThemeProperties::COLOR_BOOKMARK_TEXT },
  { "ntp_background", ThemeProperties::COLOR_NTP_BACKGROUND },
  { "ntp_text", ThemeProperties::COLOR_NTP_TEXT },
  { "ntp_link", ThemeProperties::COLOR_NTP_LINK },
  { "ntp_link_underline", ThemeProperties::COLOR_NTP_LINK_UNDERLINE },
  { "ntp_header", ThemeProperties::COLOR_NTP_HEADER },
  { "ntp_section", ThemeProperties::COLOR_NTP_SECTION },
  { "ntp_section_text", ThemeProperties::COLOR_NTP_SECTION_TEXT },
  { "ntp_section_link", ThemeProperties::COLOR_NTP_SECTION_LINK },
  { "ntp_section_link_underline",
    ThemeProperties::COLOR_NTP_SECTION_LINK_UNDERLINE },
  { "button_background", ThemeProperties::COLOR_BUTTON_BACKGROUND },
};
const size_t kColorTableLength = arraysize(kColorTable);

// Strings used by themes to identify display properties keys in JSON.
StringToIntTable kDisplayProperties[] = {
  { "ntp_background_alignment",
    ThemeProperties::NTP_BACKGROUND_ALIGNMENT },
  { "ntp_background_repeat", ThemeProperties::NTP_BACKGROUND_TILING },
  { "ntp_logo_alternate", ThemeProperties::NTP_LOGO_ALTERNATE },
};
const size_t kDisplayPropertiesSize = arraysize(kDisplayProperties);

int GetIntForString(const std::string& key,
                    StringToIntTable* table,
                    size_t table_length) {
  for (size_t i = 0; i < table_length; ++i) {
    if (base::strcasecmp(key.c_str(), table[i].key) == 0) {
      return table[i].id;
    }
  }

  return -1;
}

struct IntToIntTable {
  int key;
  int value;
};

// Mapping used in CreateFrameImages() to associate frame images with the
// tint ID that should maybe be applied to it.
IntToIntTable kFrameTintMap[] = {
  { PRS_THEME_FRAME, ThemeProperties::TINT_FRAME },
  { PRS_THEME_FRAME_INACTIVE, ThemeProperties::TINT_FRAME_INACTIVE },
  { PRS_THEME_FRAME_OVERLAY, ThemeProperties::TINT_FRAME },
  { PRS_THEME_FRAME_OVERLAY_INACTIVE,
    ThemeProperties::TINT_FRAME_INACTIVE },
  { PRS_THEME_FRAME_INCOGNITO, ThemeProperties::TINT_FRAME_INCOGNITO },
  { PRS_THEME_FRAME_INCOGNITO_INACTIVE,
    ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE },
#if defined(USE_ASH) && !defined(OS_CHROMEOS)
  { PRS_THEME_FRAME_DESKTOP, ThemeProperties::TINT_FRAME },
  { PRS_THEME_FRAME_INACTIVE_DESKTOP, ThemeProperties::TINT_FRAME_INACTIVE },
  { PRS_THEME_FRAME_INCOGNITO_DESKTOP, ThemeProperties::TINT_FRAME_INCOGNITO },
  { PRS_THEME_FRAME_INCOGNITO_INACTIVE_DESKTOP,
    ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE },
#endif
};

// Mapping used in GenerateTabBackgroundImages() to associate what frame image
// goes with which tab background.
IntToIntTable kTabBackgroundMap[] = {
  { PRS_THEME_TAB_BACKGROUND, PRS_THEME_FRAME },
  { PRS_THEME_TAB_BACKGROUND_INCOGNITO, PRS_THEME_FRAME_INCOGNITO },
#if defined(USE_ASH) && !defined(OS_CHROMEOS)
  { PRS_THEME_TAB_BACKGROUND_DESKTOP, PRS_THEME_FRAME_DESKTOP },
  { PRS_THEME_TAB_BACKGROUND_INCOGNITO_DESKTOP,
    PRS_THEME_FRAME_INCOGNITO_DESKTOP },
#endif
};

struct CropEntry {
  int prs_id;

  // The maximum useful height of the image at |prs_id|.
  int max_height;

  // Whether cropping the image at |prs_id| should be skipped on OSes which
  // have a frame border to the left and right of the web contents.
  // This should be true for images which can be used to decorate the border to
  // the left and the right of the web contents.
  bool skip_if_frame_border;
};

// The images which should be cropped before being saved to the data pack. The
// maximum heights are meant to be conservative as to give room for the UI to
// change without the maximum heights having to be modified.
// |kThemePackVersion| must be incremented if any of the maximum heights below
// are modified.
struct CropEntry kImagesToCrop[] = {
  { PRS_THEME_FRAME, 120, true },
  { PRS_THEME_FRAME_INACTIVE, 120, true },
  { PRS_THEME_FRAME_INCOGNITO, 120, true },
  { PRS_THEME_FRAME_INCOGNITO_INACTIVE, 120, true },
  { PRS_THEME_FRAME_OVERLAY, 120, true },
  { PRS_THEME_FRAME_OVERLAY_INACTIVE, 120, true },
  { PRS_THEME_TOOLBAR, 200, false },
  { PRS_THEME_BUTTON_BACKGROUND, 60, false },
  { PRS_THEME_WINDOW_CONTROL_BACKGROUND, 50, false },
#if defined(USE_ASH) && !defined(OS_CHROMEOS)
  { PRS_THEME_TOOLBAR_DESKTOP, 200, false }
#endif
};


// A list of images that don't need tinting or any other modification and can
// be byte-copied directly into the finished DataPack. This should contain the
// persistent IDs for all themeable image IDs that aren't in kFrameTintMap,
// kTabBackgroundMap or kImagesToCrop.
const int kPreloadIDs[] = {
  PRS_THEME_NTP_BACKGROUND,
  PRS_THEME_NTP_ATTRIBUTION,
};

// Returns true if this OS uses a browser frame which has a non zero width to
// the left and the right of the web contents.
bool HasFrameBorder() {
#if defined(OS_CHROMEOS) || defined(OS_MACOSX)
  return false;
#else
  return true;
#endif
}

// Returns a piece of memory with the contents of the file |path|.
base::RefCountedMemory* ReadFileData(const base::FilePath& path) {
  if (!path.empty()) {
    base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
    if (file.IsValid()) {
      int64 length = file.GetLength();
      if (length > 0 && length < INT_MAX) {
        int size = static_cast<int>(length);
        std::vector<unsigned char> raw_data;
        raw_data.resize(size);
        char* data = reinterpret_cast<char*>(&(raw_data.front()));
        if (file.ReadAtCurrentPos(data, size) == length)
          return base::RefCountedBytes::TakeVector(&raw_data);
      }
    }
  }

  return NULL;
}

// Shifts an image's HSL values. The caller is responsible for deleting
// the returned image.
gfx::Image CreateHSLShiftedImage(const gfx::Image& image,
                                 const color_utils::HSL& hsl_shift) {
  const gfx::ImageSkia* src_image = image.ToImageSkia();
  return gfx::Image(gfx::ImageSkiaOperations::CreateHSLShiftedImage(
      *src_image, hsl_shift));
}

// Computes a bitmap at one scale from a bitmap at a different scale.
SkBitmap CreateLowQualityResizedBitmap(const SkBitmap& source_bitmap,
                                       ui::ScaleFactor source_scale_factor,
                                       ui::ScaleFactor desired_scale_factor) {
  gfx::Size scaled_size = gfx::ToCeiledSize(
      gfx::ScaleSize(gfx::Size(source_bitmap.width(),
                               source_bitmap.height()),
                     ui::GetScaleForScaleFactor(desired_scale_factor) /
                     ui::GetScaleForScaleFactor(source_scale_factor)));
  SkBitmap scaled_bitmap;
  scaled_bitmap.allocN32Pixels(scaled_size.width(), scaled_size.height());
  scaled_bitmap.eraseARGB(0, 0, 0, 0);
  SkCanvas canvas(scaled_bitmap);
  SkRect scaled_bounds = RectToSkRect(gfx::Rect(scaled_size));
  // Note(oshima): The following scaling code doesn't work with
  // a mask image.
  canvas.drawBitmapRect(source_bitmap, NULL, scaled_bounds);
  return scaled_bitmap;
}

// A ImageSkiaSource that scales 100P image to the target scale factor
// if the ImageSkiaRep for the target scale factor isn't available.
class ThemeImageSource: public gfx::ImageSkiaSource {
 public:
  explicit ThemeImageSource(const gfx::ImageSkia& source) : source_(source) {
  }
  ~ThemeImageSource() override {}

  gfx::ImageSkiaRep GetImageForScale(float scale) override {
    if (source_.HasRepresentation(scale))
      return source_.GetRepresentation(scale);
    const gfx::ImageSkiaRep& rep_100p = source_.GetRepresentation(1.0f);
    SkBitmap scaled_bitmap = CreateLowQualityResizedBitmap(
        rep_100p.sk_bitmap(),
        ui::SCALE_FACTOR_100P,
        ui::GetSupportedScaleFactor(scale));
    return gfx::ImageSkiaRep(scaled_bitmap, scale);
  }

 private:
  const gfx::ImageSkia source_;

  DISALLOW_COPY_AND_ASSIGN(ThemeImageSource);
};

// An ImageSkiaSource that delays decoding PNG data into bitmaps until
// needed. Missing data for a scale factor is computed by scaling data for an
// available scale factor. Computed bitmaps are stored for future look up.
class ThemeImagePngSource : public gfx::ImageSkiaSource {
 public:
  typedef std::map<ui::ScaleFactor,
                   scoped_refptr<base::RefCountedMemory> > PngMap;

  explicit ThemeImagePngSource(const PngMap& png_map) : png_map_(png_map) {}

  ~ThemeImagePngSource() override {}

 private:
  gfx::ImageSkiaRep GetImageForScale(float scale) override {
    ui::ScaleFactor scale_factor = ui::GetSupportedScaleFactor(scale);
    // Look up the bitmap for |scale factor| in the bitmap map. If found
    // return it.
    BitmapMap::const_iterator exact_bitmap_it = bitmap_map_.find(scale_factor);
    if (exact_bitmap_it != bitmap_map_.end())
      return gfx::ImageSkiaRep(exact_bitmap_it->second, scale);

    // Look up the raw PNG data for |scale_factor| in the png map. If found,
    // decode it, store the result in the bitmap map and return it.
    PngMap::const_iterator exact_png_it = png_map_.find(scale_factor);
    if (exact_png_it != png_map_.end()) {
      SkBitmap bitmap;
      if (!gfx::PNGCodec::Decode(exact_png_it->second->front(),
                                 exact_png_it->second->size(),
                                 &bitmap)) {
        NOTREACHED();
        return gfx::ImageSkiaRep();
      }
      bitmap_map_[scale_factor] = bitmap;
      return gfx::ImageSkiaRep(bitmap, scale);
    }

    // Find an available PNG for another scale factor. We want to use the
    // highest available scale factor.
    PngMap::const_iterator available_png_it = png_map_.end();
    for (PngMap::const_iterator png_it = png_map_.begin();
         png_it != png_map_.end(); ++png_it) {
      if (available_png_it == png_map_.end() ||
          ui::GetScaleForScaleFactor(png_it->first) >
          ui::GetScaleForScaleFactor(available_png_it->first)) {
        available_png_it = png_it;
      }
    }
    if (available_png_it == png_map_.end())
      return gfx::ImageSkiaRep();
    ui::ScaleFactor available_scale_factor = available_png_it->first;

    // Look up the bitmap for |available_scale_factor| in the bitmap map.
    // If not found, decode the corresponging png data, store the result
    // in the bitmap map.
    BitmapMap::const_iterator available_bitmap_it =
        bitmap_map_.find(available_scale_factor);
    if (available_bitmap_it == bitmap_map_.end()) {
      SkBitmap available_bitmap;
      if (!gfx::PNGCodec::Decode(available_png_it->second->front(),
                                 available_png_it->second->size(),
                                 &available_bitmap)) {
        NOTREACHED();
        return gfx::ImageSkiaRep();
      }
      bitmap_map_[available_scale_factor] = available_bitmap;
      available_bitmap_it = bitmap_map_.find(available_scale_factor);
    }

    // Scale the available bitmap to the desired scale factor, store the result
    // in the bitmap map and return it.
    SkBitmap scaled_bitmap = CreateLowQualityResizedBitmap(
        available_bitmap_it->second,
        available_scale_factor,
        scale_factor);
    bitmap_map_[scale_factor] = scaled_bitmap;
    return gfx::ImageSkiaRep(scaled_bitmap, scale);
  }

  PngMap png_map_;

  typedef std::map<ui::ScaleFactor, SkBitmap> BitmapMap;
  BitmapMap bitmap_map_;

  DISALLOW_COPY_AND_ASSIGN(ThemeImagePngSource);
};

class TabBackgroundImageSource: public gfx::CanvasImageSource {
 public:
  TabBackgroundImageSource(const gfx::ImageSkia& image_to_tint,
                           const gfx::ImageSkia& overlay,
                           const color_utils::HSL& hsl_shift,
                           int vertical_offset)
      : gfx::CanvasImageSource(image_to_tint.size(), false),
        image_to_tint_(image_to_tint),
        overlay_(overlay),
        hsl_shift_(hsl_shift),
        vertical_offset_(vertical_offset) {
  }

  ~TabBackgroundImageSource() override {}

  // Overridden from CanvasImageSource:
  void Draw(gfx::Canvas* canvas) override {
    gfx::ImageSkia bg_tint =
        gfx::ImageSkiaOperations::CreateHSLShiftedImage(image_to_tint_,
            hsl_shift_);
    canvas->TileImageInt(bg_tint, 0, vertical_offset_, 0, 0,
        size().width(), size().height());

    // If they've provided a custom image, overlay it.
    if (!overlay_.isNull()) {
      canvas->TileImageInt(overlay_, 0, 0, size().width(),
                           overlay_.height());
    }
  }

 private:
  const gfx::ImageSkia image_to_tint_;
  const gfx::ImageSkia overlay_;
  const color_utils::HSL hsl_shift_;
  const int vertical_offset_;

  DISALLOW_COPY_AND_ASSIGN(TabBackgroundImageSource);
};

}  // namespace

BrowserThemePack::~BrowserThemePack() {
  if (!data_pack_.get()) {
    delete header_;
    delete [] tints_;
    delete [] colors_;
    delete [] display_properties_;
    delete [] source_images_;
  }
}

// static
scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromExtension(
    const Extension* extension) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK(extension);
  DCHECK(extension->is_theme());

  scoped_refptr<BrowserThemePack> pack(new BrowserThemePack);
  pack->BuildHeader(extension);
  pack->BuildTintsFromJSON(extensions::ThemeInfo::GetTints(extension));
  pack->BuildColorsFromJSON(extensions::ThemeInfo::GetColors(extension));
  pack->BuildDisplayPropertiesFromJSON(
      extensions::ThemeInfo::GetDisplayProperties(extension));

  // Builds the images. (Image building is dependent on tints).
  FilePathMap file_paths;
  pack->ParseImageNamesFromJSON(
      extensions::ThemeInfo::GetImages(extension),
      extension->path(),
      &file_paths);
  pack->BuildSourceImagesArray(file_paths);

  if (!pack->LoadRawBitmapsTo(file_paths, &pack->images_on_ui_thread_))
    return NULL;

  pack->CreateImages(&pack->images_on_ui_thread_);

  // Make sure the |images_on_file_thread_| has bitmaps for supported
  // scale factors before passing to FILE thread.
  pack->images_on_file_thread_ = pack->images_on_ui_thread_;
  for (ImageCache::iterator it = pack->images_on_file_thread_.begin();
       it != pack->images_on_file_thread_.end(); ++it) {
    gfx::ImageSkia* image_skia =
        const_cast<gfx::ImageSkia*>(it->second.ToImageSkia());
    image_skia->MakeThreadSafe();
  }

  // Set ThemeImageSource on |images_on_ui_thread_| to resample the source
  // image if a caller of BrowserThemePack::GetImageNamed() requests an
  // ImageSkiaRep for a scale factor not specified by the theme author.
  // Callers of BrowserThemePack::GetImageNamed() to be able to retrieve
  // ImageSkiaReps for all supported scale factors.
  for (ImageCache::iterator it = pack->images_on_ui_thread_.begin();
       it != pack->images_on_ui_thread_.end(); ++it) {
    const gfx::ImageSkia source_image_skia = it->second.AsImageSkia();
    ThemeImageSource* source = new ThemeImageSource(source_image_skia);
    // image_skia takes ownership of source.
    gfx::ImageSkia image_skia(source, source_image_skia.size());
    it->second = gfx::Image(image_skia);
  }

  // Generate raw images (for new-tab-page attribution and background) for
  // any missing scale from an available scale image.
  for (size_t i = 0; i < arraysize(kPreloadIDs); ++i) {
    pack->GenerateRawImageForAllSupportedScales(kPreloadIDs[i]);
  }

  // The BrowserThemePack is now in a consistent state.
  return pack;
}

// static
scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromDataPack(
    const base::FilePath& path, const std::string& expected_id) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  // Allow IO on UI thread due to deep-seated theme design issues.
  // (see http://crbug.com/80206)
  base::ThreadRestrictions::ScopedAllowIO allow_io;
  scoped_refptr<BrowserThemePack> pack(new BrowserThemePack);
  // Scale factor parameter is moot as data pack has image resources for all
  // supported scale factors.
  pack->data_pack_.reset(
      new ui::DataPack(ui::SCALE_FACTOR_NONE));

  if (!pack->data_pack_->LoadFromPath(path)) {
    LOG(ERROR) << "Failed to load theme data pack.";
    return NULL;
  }

  base::StringPiece pointer;
  if (!pack->data_pack_->GetStringPiece(kHeaderID, &pointer))
    return NULL;
  pack->header_ = reinterpret_cast<BrowserThemePackHeader*>(const_cast<char*>(
      pointer.data()));

  if (pack->header_->version != kThemePackVersion) {
    DLOG(ERROR) << "BuildFromDataPack failure! Version mismatch!";
    return NULL;
  }
  // TODO(erg): Check endianess once DataPack works on the other endian.
  std::string theme_id(reinterpret_cast<char*>(pack->header_->theme_id),
                       crx_file::id_util::kIdSize);
  std::string truncated_id = expected_id.substr(0, crx_file::id_util::kIdSize);
  if (theme_id != truncated_id) {
    DLOG(ERROR) << "Wrong id: " << theme_id << " vs " << expected_id;
    return NULL;
  }

  if (!pack->data_pack_->GetStringPiece(kTintsID, &pointer))
    return NULL;
  pack->tints_ = reinterpret_cast<TintEntry*>(const_cast<char*>(
      pointer.data()));

  if (!pack->data_pack_->GetStringPiece(kColorsID, &pointer))
    return NULL;
  pack->colors_ =
      reinterpret_cast<ColorPair*>(const_cast<char*>(pointer.data()));

  if (!pack->data_pack_->GetStringPiece(kDisplayPropertiesID, &pointer))
    return NULL;
  pack->display_properties_ = reinterpret_cast<DisplayPropertyPair*>(
      const_cast<char*>(pointer.data()));

  if (!pack->data_pack_->GetStringPiece(kSourceImagesID, &pointer))
    return NULL;
  pack->source_images_ = reinterpret_cast<int*>(
      const_cast<char*>(pointer.data()));

  if (!pack->data_pack_->GetStringPiece(kScaleFactorsID, &pointer))
    return NULL;

  if (!InputScalesValid(pointer, pack->scale_factors_)) {
    DLOG(ERROR) << "BuildFromDataPack failure! The pack scale factors differ "
                << "from those supported by platform.";
    return NULL;
  }
  return pack;
}

// static
void BrowserThemePack::GetThemeableImageIDRs(std::set<int>* result) {
  if (!result)
    return;

  result->clear();
  for (size_t i = 0; i < kPersistingImagesLength; ++i)
    result->insert(kPersistingImages[i].idr_id);

#if defined(USE_ASH) && !defined(OS_CHROMEOS)
  for (size_t i = 0; i < kPersistingImagesDesktopAuraLength; ++i)
    result->insert(kPersistingImagesDesktopAura[i].idr_id);
#endif
}

bool BrowserThemePack::WriteToDisk(const base::FilePath& path) const {
  // Add resources for each of the property arrays.
  RawDataForWriting resources;
  resources[kHeaderID] = base::StringPiece(
      reinterpret_cast<const char*>(header_), sizeof(BrowserThemePackHeader));
  resources[kTintsID] = base::StringPiece(
      reinterpret_cast<const char*>(tints_),
      sizeof(TintEntry[kTintTableLength]));
  resources[kColorsID] = base::StringPiece(
      reinterpret_cast<const char*>(colors_),
      sizeof(ColorPair[kColorTableLength]));
  resources[kDisplayPropertiesID] = base::StringPiece(
      reinterpret_cast<const char*>(display_properties_),
      sizeof(DisplayPropertyPair[kDisplayPropertiesSize]));

  int source_count = 1;
  int* end = source_images_;
  for (; *end != -1 ; end++)
    source_count++;
  resources[kSourceImagesID] = base::StringPiece(
      reinterpret_cast<const char*>(source_images_),
      source_count * sizeof(*source_images_));

  // Store results of GetScaleFactorsAsString() in std::string as
  // base::StringPiece does not copy data in constructor.
  std::string scale_factors_string = GetScaleFactorsAsString(scale_factors_);
  resources[kScaleFactorsID] = scale_factors_string;

  AddRawImagesTo(image_memory_, &resources);

  RawImages reencoded_images;
  RepackImages(images_on_file_thread_, &reencoded_images);
  AddRawImagesTo(reencoded_images, &resources);

  return ui::DataPack::WritePack(path, resources, ui::DataPack::BINARY);
}

bool BrowserThemePack::GetTint(int id, color_utils::HSL* hsl) const {
  if (tints_) {
    for (size_t i = 0; i < kTintTableLength; ++i) {
      if (tints_[i].id == id) {
        hsl->h = tints_[i].h;
        hsl->s = tints_[i].s;
        hsl->l = tints_[i].l;
        return true;
      }
    }
  }

  return false;
}

bool BrowserThemePack::GetColor(int id, SkColor* color) const {
  if (colors_) {
    for (size_t i = 0; i < kColorTableLength; ++i) {
      if (colors_[i].id == id) {
        *color = colors_[i].color;
        return true;
      }
    }
  }

  return false;
}

bool BrowserThemePack::GetDisplayProperty(int id, int* result) const {
  if (display_properties_) {
    for (size_t i = 0; i < kDisplayPropertiesSize; ++i) {
      if (display_properties_[i].id == id) {
        *result = display_properties_[i].property;
        return true;
      }
    }
  }

  return false;
}

gfx::Image BrowserThemePack::GetImageNamed(int idr_id) {
  int prs_id = GetPersistentIDByIDR(idr_id);
  if (prs_id == -1)
    return gfx::Image();

  // Check if the image is cached.
  ImageCache::const_iterator image_iter = images_on_ui_thread_.find(prs_id);
  if (image_iter != images_on_ui_thread_.end())
    return image_iter->second;

  ThemeImagePngSource::PngMap png_map;
  for (size_t i = 0; i < scale_factors_.size(); ++i) {
    scoped_refptr<base::RefCountedMemory> memory =
        GetRawData(idr_id, scale_factors_[i]);
    if (memory.get())
      png_map[scale_factors_[i]] = memory;
  }
  if (!png_map.empty()) {
    gfx::ImageSkia image_skia(new ThemeImagePngSource(png_map), 1.0f);
    // |image_skia| takes ownership of ThemeImagePngSource.
    gfx::Image ret = gfx::Image(image_skia);
    images_on_ui_thread_[prs_id] = ret;
    return ret;
  }

  return gfx::Image();
}

base::RefCountedMemory* BrowserThemePack::GetRawData(
    int idr_id,
    ui::ScaleFactor scale_factor) const {
  base::RefCountedMemory* memory = NULL;
  int prs_id = GetPersistentIDByIDR(idr_id);
  int raw_id = GetRawIDByPersistentID(prs_id, scale_factor);

  if (raw_id != -1) {
    if (data_pack_.get()) {
      memory = data_pack_->GetStaticMemory(raw_id);
    } else {
      RawImages::const_iterator it = image_memory_.find(raw_id);
      if (it != image_memory_.end()) {
        memory = it->second.get();
      }
    }
  }

  return memory;
}

bool BrowserThemePack::HasCustomImage(int idr_id) const {
  int prs_id = GetPersistentIDByIDR(idr_id);
  if (prs_id == -1)
    return false;

  int* img = source_images_;
  for (; *img != -1; ++img) {
    if (*img == prs_id)
      return true;
  }

  return false;
}

// private:

BrowserThemePack::BrowserThemePack()
    : CustomThemeSupplier(EXTENSION),
      header_(NULL),
      tints_(NULL),
      colors_(NULL),
      display_properties_(NULL),
      source_images_(NULL) {
  scale_factors_ = ui::GetSupportedScaleFactors();
  // On Windows HiDPI SCALE_FACTOR_100P may not be supported by default.
  if (std::find(scale_factors_.begin(), scale_factors_.end(),
                ui::SCALE_FACTOR_100P) == scale_factors_.end()) {
    scale_factors_.push_back(ui::SCALE_FACTOR_100P);
  }
}

void BrowserThemePack::BuildHeader(const Extension* extension) {
  header_ = new BrowserThemePackHeader;
  header_->version = kThemePackVersion;

  // TODO(erg): Need to make this endian safe on other computers. Prerequisite
  // is that ui::DataPack removes this same check.
#if defined(__BYTE_ORDER)
  // Linux check
  COMPILE_ASSERT(__BYTE_ORDER == __LITTLE_ENDIAN,
                 datapack_assumes_little_endian);
#elif defined(__BIG_ENDIAN__)
  // Mac check
  #error DataPack assumes little endian
#endif
  header_->little_endian = 1;

  const std::string& id = extension->id();
  memcpy(header_->theme_id, id.c_str(), crx_file::id_util::kIdSize);
}

void BrowserThemePack::BuildTintsFromJSON(
    const base::DictionaryValue* tints_value) {
  tints_ = new TintEntry[kTintTableLength];
  for (size_t i = 0; i < kTintTableLength; ++i) {
    tints_[i].id = -1;
    tints_[i].h = -1;
    tints_[i].s = -1;
    tints_[i].l = -1;
  }

  if (!tints_value)
    return;

  // Parse the incoming data from |tints_value| into an intermediary structure.
  std::map<int, color_utils::HSL> temp_tints;
  for (base::DictionaryValue::Iterator iter(*tints_value); !iter.IsAtEnd();
       iter.Advance()) {
    const base::ListValue* tint_list;
    if (iter.value().GetAsList(&tint_list) &&
        (tint_list->GetSize() == 3)) {
      color_utils::HSL hsl = { -1, -1, -1 };

      if (tint_list->GetDouble(0, &hsl.h) &&
          tint_list->GetDouble(1, &hsl.s) &&
          tint_list->GetDouble(2, &hsl.l)) {
        MakeHSLShiftValid(&hsl);
        int id = GetIntForString(iter.key(), kTintTable, kTintTableLength);
        if (id != -1) {
          temp_tints[id] = hsl;
        }
      }
    }
  }

  // Copy data from the intermediary data structure to the array.
  size_t count = 0;
  for (std::map<int, color_utils::HSL>::const_iterator it =
           temp_tints.begin();
       it != temp_tints.end() && count < kTintTableLength;
       ++it, ++count) {
    tints_[count].id = it->first;
    tints_[count].h = it->second.h;
    tints_[count].s = it->second.s;
    tints_[count].l = it->second.l;
  }
}

void BrowserThemePack::BuildColorsFromJSON(
    const base::DictionaryValue* colors_value) {
  colors_ = new ColorPair[kColorTableLength];
  for (size_t i = 0; i < kColorTableLength; ++i) {
    colors_[i].id = -1;
    colors_[i].color = SkColorSetRGB(0, 0, 0);
  }

  std::map<int, SkColor> temp_colors;
  if (colors_value)
    ReadColorsFromJSON(colors_value, &temp_colors);
  GenerateMissingColors(&temp_colors);

  // Copy data from the intermediary data structure to the array.
  size_t count = 0;
  for (std::map<int, SkColor>::const_iterator it = temp_colors.begin();
       it != temp_colors.end() && count < kColorTableLength; ++it, ++count) {
    colors_[count].id = it->first;
    colors_[count].color = it->second;
  }
}

void BrowserThemePack::ReadColorsFromJSON(
    const base::DictionaryValue* colors_value,
    std::map<int, SkColor>* temp_colors) {
  // Parse the incoming data from |colors_value| into an intermediary structure.
  for (base::DictionaryValue::Iterator iter(*colors_value); !iter.IsAtEnd();
       iter.Advance()) {
    const base::ListValue* color_list;
    if (iter.value().GetAsList(&color_list) &&
        ((color_list->GetSize() == 3) || (color_list->GetSize() == 4))) {
      SkColor color = SK_ColorWHITE;
      int r, g, b;
      if (color_list->GetInteger(0, &r) &&
          color_list->GetInteger(1, &g) &&
          color_list->GetInteger(2, &b)) {
        if (color_list->GetSize() == 4) {
          double alpha;
          int alpha_int;
          if (color_list->GetDouble(3, &alpha)) {
            color = SkColorSetARGB(static_cast<int>(alpha * 255), r, g, b);
          } else if (color_list->GetInteger(3, &alpha_int) &&
                     (alpha_int == 0 || alpha_int == 1)) {
            color = SkColorSetARGB(alpha_int ? 255 : 0, r, g, b);
          } else {
            // Invalid entry for part 4.
            continue;
          }
        } else {
          color = SkColorSetRGB(r, g, b);
        }

        int id = GetIntForString(iter.key(), kColorTable, kColorTableLength);
        if (id != -1) {
          (*temp_colors)[id] = color;
        }
      }
    }
  }
}

void BrowserThemePack::GenerateMissingColors(
    std::map<int, SkColor>* colors) {
  // Generate link colors, if missing. (See GetColor()).
  if (!colors->count(ThemeProperties::COLOR_NTP_HEADER) &&
      colors->count(ThemeProperties::COLOR_NTP_SECTION)) {
    (*colors)[ThemeProperties::COLOR_NTP_HEADER] =
        (*colors)[ThemeProperties::COLOR_NTP_SECTION];
  }

  if (!colors->count(ThemeProperties::COLOR_NTP_SECTION_LINK_UNDERLINE) &&
      colors->count(ThemeProperties::COLOR_NTP_SECTION_LINK)) {
    SkColor color_section_link =
        (*colors)[ThemeProperties::COLOR_NTP_SECTION_LINK];
    (*colors)[ThemeProperties::COLOR_NTP_SECTION_LINK_UNDERLINE] =
        SkColorSetA(color_section_link, SkColorGetA(color_section_link) / 3);
  }

  if (!colors->count(ThemeProperties::COLOR_NTP_LINK_UNDERLINE) &&
      colors->count(ThemeProperties::COLOR_NTP_LINK)) {
    SkColor color_link = (*colors)[ThemeProperties::COLOR_NTP_LINK];
    (*colors)[ThemeProperties::COLOR_NTP_LINK_UNDERLINE] =
        SkColorSetA(color_link, SkColorGetA(color_link) / 3);
  }

  // Generate frame colors, if missing. (See GenerateFrameColors()).
  SkColor frame;
  std::map<int, SkColor>::const_iterator it =
      colors->find(ThemeProperties::COLOR_FRAME);
  if (it != colors->end()) {
    frame = it->second;
  } else {
    frame = ThemeProperties::GetDefaultColor(
        ThemeProperties::COLOR_FRAME);
  }

  if (!colors->count(ThemeProperties::COLOR_FRAME)) {
    (*colors)[ThemeProperties::COLOR_FRAME] =
        HSLShift(frame, GetTintInternal(ThemeProperties::TINT_FRAME));
  }
  if (!colors->count(ThemeProperties::COLOR_FRAME_INACTIVE)) {
    (*colors)[ThemeProperties::COLOR_FRAME_INACTIVE] =
        HSLShift(frame, GetTintInternal(
            ThemeProperties::TINT_FRAME_INACTIVE));
  }
  if (!colors->count(ThemeProperties::COLOR_FRAME_INCOGNITO)) {
    (*colors)[ThemeProperties::COLOR_FRAME_INCOGNITO] =
        HSLShift(frame, GetTintInternal(
            ThemeProperties::TINT_FRAME_INCOGNITO));
  }
  if (!colors->count(ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE)) {
    (*colors)[ThemeProperties::COLOR_FRAME_INCOGNITO_INACTIVE] =
        HSLShift(frame, GetTintInternal(
            ThemeProperties::TINT_FRAME_INCOGNITO_INACTIVE));
  }
}

void BrowserThemePack::BuildDisplayPropertiesFromJSON(
    const base::DictionaryValue* display_properties_value) {
  display_properties_ = new DisplayPropertyPair[kDisplayPropertiesSize];
  for (size_t i = 0; i < kDisplayPropertiesSize; ++i) {
    display_properties_[i].id = -1;
    display_properties_[i].property = 0;
  }

  if (!display_properties_value)
    return;

  std::map<int, int> temp_properties;
  for (base::DictionaryValue::Iterator iter(*display_properties_value);
       !iter.IsAtEnd(); iter.Advance()) {
    int property_id = GetIntForString(iter.key(), kDisplayProperties,
                                      kDisplayPropertiesSize);
    switch (property_id) {
      case ThemeProperties::NTP_BACKGROUND_ALIGNMENT: {
        std::string val;
        if (iter.value().GetAsString(&val)) {
          temp_properties[ThemeProperties::NTP_BACKGROUND_ALIGNMENT] =
              ThemeProperties::StringToAlignment(val);
        }
        break;
      }
      case ThemeProperties::NTP_BACKGROUND_TILING: {
        std::string val;
        if (iter.value().GetAsString(&val)) {
          temp_properties[ThemeProperties::NTP_BACKGROUND_TILING] =
              ThemeProperties::StringToTiling(val);
        }
        break;
      }
      case ThemeProperties::NTP_LOGO_ALTERNATE: {
        int val = 0;
        if (iter.value().GetAsInteger(&val))
          temp_properties[ThemeProperties::NTP_LOGO_ALTERNATE] = val;
        break;
      }
    }
  }

  // Copy data from the intermediary data structure to the array.
  size_t count = 0;
  for (std::map<int, int>::const_iterator it = temp_properties.begin();
       it != temp_properties.end() && count < kDisplayPropertiesSize;
       ++it, ++count) {
    display_properties_[count].id = it->first;
    display_properties_[count].property = it->second;
  }
}

void BrowserThemePack::ParseImageNamesFromJSON(
    const base::DictionaryValue* images_value,
    const base::FilePath& images_path,
    FilePathMap* file_paths) const {
  if (!images_value)
    return;

  for (base::DictionaryValue::Iterator iter(*images_value); !iter.IsAtEnd();
       iter.Advance()) {
    if (iter.value().IsType(base::Value::TYPE_DICTIONARY)) {
      const base::DictionaryValue* inner_value = NULL;
      if (iter.value().GetAsDictionary(&inner_value)) {
        for (base::DictionaryValue::Iterator inner_iter(*inner_value);
             !inner_iter.IsAtEnd();
             inner_iter.Advance()) {
          std::string name;
          ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_NONE;
          if (GetScaleFactorFromManifestKey(inner_iter.key(), &scale_factor) &&
              inner_iter.value().IsType(base::Value::TYPE_STRING) &&
              inner_iter.value().GetAsString(&name)) {
            AddFileAtScaleToMap(iter.key(),
                                scale_factor,
                                images_path.AppendASCII(name),
                                file_paths);
          }
        }
      }
    } else if (iter.value().IsType(base::Value::TYPE_STRING)) {
      std::string name;
      if (iter.value().GetAsString(&name)) {
        AddFileAtScaleToMap(iter.key(),
                            ui::SCALE_FACTOR_100P,
                            images_path.AppendASCII(name),
                            file_paths);
      }
    }
  }
}

void BrowserThemePack::AddFileAtScaleToMap(const std::string& image_name,
                                           ui::ScaleFactor scale_factor,
                                           const base::FilePath& image_path,
                                           FilePathMap* file_paths) const {
  int id = GetPersistentIDByName(image_name);
  if (id != -1)
    (*file_paths)[id][scale_factor] = image_path;
#if defined(USE_ASH) && !defined(OS_CHROMEOS)
  id = GetPersistentIDByNameHelper(image_name,
                                   kPersistingImagesDesktopAura,
                                   kPersistingImagesDesktopAuraLength);
  if (id != -1)
    (*file_paths)[id][scale_factor] = image_path;
#endif
}

void BrowserThemePack::BuildSourceImagesArray(const FilePathMap& file_paths) {
  std::vector<int> ids;
  for (FilePathMap::const_iterator it = file_paths.begin();
       it != file_paths.end(); ++it) {
    ids.push_back(it->first);
  }

  source_images_ = new int[ids.size() + 1];
  std::copy(ids.begin(), ids.end(), source_images_);
  source_images_[ids.size()] = -1;
}

bool BrowserThemePack::LoadRawBitmapsTo(
    const FilePathMap& file_paths,
    ImageCache* image_cache) {
  // Themes should be loaded on the file thread, not the UI thread.
  // http://crbug.com/61838
  base::ThreadRestrictions::ScopedAllowIO allow_io;

  for (FilePathMap::const_iterator it = file_paths.begin();
       it != file_paths.end(); ++it) {
    int prs_id = it->first;
    // Some images need to go directly into |image_memory_|. No modification is
    // necessary or desirable.
    bool is_copyable = false;
    for (size_t i = 0; i < arraysize(kPreloadIDs); ++i) {
      if (kPreloadIDs[i] == prs_id) {
        is_copyable = true;
        break;
      }
    }
    gfx::ImageSkia image_skia;
    for (int pass = 0; pass < 2; ++pass) {
      // Two passes: In the first pass, we process only scale factor
      // 100% and in the second pass all other scale factors. We
      // process scale factor 100% first because the first image added
      // in image_skia.AddRepresentation() determines the DIP size for
      // all representations.
      for (ScaleFactorToFileMap::const_iterator s2f = it->second.begin();
           s2f != it->second.end(); ++s2f) {
        ui::ScaleFactor scale_factor = s2f->first;
        if ((pass == 0 && scale_factor != ui::SCALE_FACTOR_100P) ||
            (pass == 1 && scale_factor == ui::SCALE_FACTOR_100P)) {
          continue;
        }
        scoped_refptr<base::RefCountedMemory> raw_data(
            ReadFileData(s2f->second));
        if (!raw_data.get() || !raw_data->size()) {
          LOG(ERROR) << "Could not load theme image"
                     << " prs_id=" << prs_id
                     << " scale_factor_enum=" << scale_factor
                     << " file=" << s2f->second.value()
                     << (raw_data.get() ? " (zero size)" : " (read error)");
          return false;
        }
        if (is_copyable) {
          int raw_id = GetRawIDByPersistentID(prs_id, scale_factor);
          image_memory_[raw_id] = raw_data;
        } else {
          SkBitmap bitmap;
          if (gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(),
                                    &bitmap)) {
            image_skia.AddRepresentation(
                gfx::ImageSkiaRep(bitmap,
                                  ui::GetScaleForScaleFactor(scale_factor)));
          } else {
            NOTREACHED() << "Unable to decode theme image resource "
                         << it->first;
          }
        }
      }
    }
    if (!is_copyable && !image_skia.isNull())
      (*image_cache)[prs_id] = gfx::Image(image_skia);
  }

  return true;
}

void BrowserThemePack::CreateImages(ImageCache* images) const {
  CropImages(images);
  CreateFrameImages(images);
  CreateTintedButtons(GetTintInternal(ThemeProperties::TINT_BUTTONS), images);
  CreateTabBackgroundImages(images);
}

void BrowserThemePack::CropImages(ImageCache* images) const {
  bool has_frame_border = HasFrameBorder();
  for (size_t i = 0; i < arraysize(kImagesToCrop); ++i) {
    if (has_frame_border && kImagesToCrop[i].skip_if_frame_border)
      continue;

    int prs_id = kImagesToCrop[i].prs_id;
    ImageCache::iterator it = images->find(prs_id);
    if (it == images->end())
      continue;

    int crop_height = kImagesToCrop[i].max_height;
    gfx::ImageSkia image_skia = it->second.AsImageSkia();
    (*images)[prs_id] = gfx::Image(gfx::ImageSkiaOperations::ExtractSubset(
        image_skia, gfx::Rect(0, 0, image_skia.width(), crop_height)));
  }
}

void BrowserThemePack::CreateFrameImages(ImageCache* images) const {
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();

  // Create all the output images in a separate cache and move them back into
  // the input images because there can be name collisions.
  ImageCache temp_output;

  for (size_t i = 0; i < arraysize(kFrameTintMap); ++i) {
    int prs_id = kFrameTintMap[i].key;
    gfx::Image frame;
    // If there's no frame image provided for the specified id, then load
    // the default provided frame. If that's not provided, skip this whole
    // thing and just use the default images.
    int prs_base_id = 0;

#if defined(USE_ASH) && !defined(OS_CHROMEOS)
    if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE_DESKTOP) {
      prs_base_id = images->count(PRS_THEME_FRAME_INCOGNITO_DESKTOP) ?
                    PRS_THEME_FRAME_INCOGNITO_DESKTOP : PRS_THEME_FRAME_DESKTOP;
    } else if (prs_id == PRS_THEME_FRAME_INACTIVE_DESKTOP) {
      prs_base_id = PRS_THEME_FRAME_DESKTOP;
    } else if (prs_id == PRS_THEME_FRAME_INCOGNITO_DESKTOP &&
                !images->count(PRS_THEME_FRAME_INCOGNITO_DESKTOP)) {
      prs_base_id = PRS_THEME_FRAME_DESKTOP;
    }
#endif
    if (!prs_base_id) {
      if (prs_id == PRS_THEME_FRAME_INCOGNITO_INACTIVE) {
        prs_base_id = images->count(PRS_THEME_FRAME_INCOGNITO) ?
                      PRS_THEME_FRAME_INCOGNITO : PRS_THEME_FRAME;
      } else if (prs_id == PRS_THEME_FRAME_OVERLAY_INACTIVE) {
        prs_base_id = PRS_THEME_FRAME_OVERLAY;
      } else if (prs_id == PRS_THEME_FRAME_INACTIVE) {
        prs_base_id = PRS_THEME_FRAME;
      } else if (prs_id == PRS_THEME_FRAME_INCOGNITO &&
                 !images->count(PRS_THEME_FRAME_INCOGNITO)) {
        prs_base_id = PRS_THEME_FRAME;
      } else {
        prs_base_id = prs_id;
      }
    }
    if (images->count(prs_id)) {
      frame = (*images)[prs_id];
    } else if (prs_base_id != prs_id && images->count(prs_base_id)) {
      frame = (*images)[prs_base_id];
    } else if (prs_base_id == PRS_THEME_FRAME_OVERLAY) {
#if defined(USE_ASH) && !defined(OS_CHROMEOS)
      if (images->count(PRS_THEME_FRAME_DESKTOP)) {
#else
      if (images->count(PRS_THEME_FRAME)) {
#endif
        // If there is no theme overlay, don't tint the default frame,
        // because it will overwrite the custom frame image when we cache and
        // reload from disk.
        frame = gfx::Image();
      }
    } else {
      // If the theme doesn't specify an image, then apply the tint to
      // the default frame.
      frame = rb.GetImageNamed(IDR_THEME_FRAME);
#if defined(USE_ASH) && !defined(OS_CHROMEOS)
      if (prs_id >= PRS_THEME_FRAME_DESKTOP &&
          prs_id <= PRS_THEME_FRAME_INCOGNITO_INACTIVE_DESKTOP) {
        frame = rb.GetImageNamed(IDR_THEME_FRAME_DESKTOP);
      }
#endif
    }
    if (!frame.IsEmpty()) {
      temp_output[prs_id] = CreateHSLShiftedImage(
          frame, GetTintInternal(kFrameTintMap[i].value));
    }
  }
  MergeImageCaches(temp_output, images);
}

void BrowserThemePack::CreateTintedButtons(
    const color_utils::HSL& button_tint,
    ImageCache* processed_images) const {
  if (button_tint.h != -1 || button_tint.s != -1 || button_tint.l != -1) {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    const std::set<int>& idr_ids =
        ThemeProperties::GetTintableToolbarButtons();
    for (std::set<int>::const_iterator it = idr_ids.begin();
         it != idr_ids.end(); ++it) {
      int prs_id = GetPersistentIDByIDR(*it);
      DCHECK(prs_id > 0);

      // Fetch the image by IDR...
      gfx::Image& button = rb.GetImageNamed(*it);

      // but save a version with the persistent ID.
      (*processed_images)[prs_id] =
          CreateHSLShiftedImage(button, button_tint);
    }
  }
}

void BrowserThemePack::CreateTabBackgroundImages(ImageCache* images) const {
  ImageCache temp_output;
  for (size_t i = 0; i < arraysize(kTabBackgroundMap); ++i) {
    int prs_id = kTabBackgroundMap[i].key;
    int prs_base_id = kTabBackgroundMap[i].value;

    // We only need to generate the background tab images if we were provided
    // with a PRS_THEME_FRAME.
    ImageCache::const_iterator it = images->find(prs_base_id);
    if (it != images->end()) {
      gfx::ImageSkia image_to_tint = (it->second).AsImageSkia();
      color_utils::HSL hsl_shift = GetTintInternal(
          ThemeProperties::TINT_BACKGROUND_TAB);
      int vertical_offset = images->count(prs_id)
                            ? kRestoredTabVerticalOffset : 0;

      gfx::ImageSkia overlay;
      ImageCache::const_iterator overlay_it = images->find(prs_id);
      if (overlay_it != images->end())
        overlay = overlay_it->second.AsImageSkia();

      gfx::ImageSkiaSource* source = new TabBackgroundImageSource(
          image_to_tint, overlay, hsl_shift, vertical_offset);
      // ImageSkia takes ownership of |source|.
      temp_output[prs_id] = gfx::Image(gfx::ImageSkia(source,
          image_to_tint.size()));
    }
  }
  MergeImageCaches(temp_output, images);
}

void BrowserThemePack::RepackImages(const ImageCache& images,
                                    RawImages* reencoded_images) const {
  for (ImageCache::const_iterator it = images.begin();
       it != images.end(); ++it) {
    gfx::ImageSkia image_skia = *it->second.ToImageSkia();

    typedef std::vector<gfx::ImageSkiaRep> ImageSkiaReps;
    ImageSkiaReps image_reps = image_skia.image_reps();
    if (image_reps.empty()) {
      NOTREACHED() << "No image reps for resource " << it->first << ".";
    }
    for (ImageSkiaReps::iterator rep_it = image_reps.begin();
         rep_it != image_reps.end(); ++rep_it) {
      std::vector<unsigned char> bitmap_data;
      if (!gfx::PNGCodec::EncodeBGRASkBitmap(rep_it->sk_bitmap(), false,
                                             &bitmap_data)) {
        NOTREACHED() << "Image file for resource " << it->first
                     << " could not be encoded.";
      }
      int raw_id = GetRawIDByPersistentID(
          it->first,
          ui::GetSupportedScaleFactor(rep_it->scale()));
      (*reencoded_images)[raw_id] =
          base::RefCountedBytes::TakeVector(&bitmap_data);
    }
  }
}

void BrowserThemePack::MergeImageCaches(
    const ImageCache& source, ImageCache* destination) const {
  for (ImageCache::const_iterator it = source.begin(); it != source.end();
       ++it) {
    (*destination)[it->first] = it->second;
  }
}

void BrowserThemePack::AddRawImagesTo(const RawImages& images,
                                      RawDataForWriting* out) const {
  for (RawImages::const_iterator it = images.begin(); it != images.end();
       ++it) {
    (*out)[it->first] = base::StringPiece(
        it->second->front_as<char>(), it->second->size());
  }
}

color_utils::HSL BrowserThemePack::GetTintInternal(int id) const {
  if (tints_) {
    for (size_t i = 0; i < kTintTableLength; ++i) {
      if (tints_[i].id == id) {
        color_utils::HSL hsl;
        hsl.h = tints_[i].h;
        hsl.s = tints_[i].s;
        hsl.l = tints_[i].l;
        return hsl;
      }
    }
  }

  return ThemeProperties::GetDefaultTint(id);
}

int BrowserThemePack::GetRawIDByPersistentID(
    int prs_id,
    ui::ScaleFactor scale_factor) const {
  if (prs_id < 0)
    return -1;

  for (size_t i = 0; i < scale_factors_.size(); ++i) {
    if (scale_factors_[i] == scale_factor)
      return ((GetMaxPersistentId() + 1) * i) + prs_id;
  }
  return -1;
}

bool BrowserThemePack::GetScaleFactorFromManifestKey(
    const std::string& key,
    ui::ScaleFactor* scale_factor) const {
  int percent = 0;
  if (base::StringToInt(key, &percent)) {
    float scale = static_cast<float>(percent) / 100.0f;
    for (size_t i = 0; i < scale_factors_.size(); ++i) {
      if (fabs(ui::GetScaleForScaleFactor(scale_factors_[i]) - scale)
              < 0.001) {
        *scale_factor = scale_factors_[i];
        return true;
      }
    }
  }
  return false;
}

void BrowserThemePack::GenerateRawImageForAllSupportedScales(int prs_id) {
  // Compute (by scaling) bitmaps for |prs_id| for any scale factors
  // for which the theme author did not provide a bitmap. We compute
  // the bitmaps using the highest scale factor that theme author
  // provided.
  // Note: We use only supported scale factors. For example, if scale
  // factor 2x is supported by the current system, but 1.8x is not and
  // if the theme author did not provide an image for 2x but one for
  // 1.8x, we will not use the 1.8x image here. Here we will only use
  // images provided for scale factors supported by the current system.

  // See if any image is missing. If not, we're done.
  bool image_missing = false;
  for (size_t i = 0; i < scale_factors_.size(); ++i) {
    int raw_id = GetRawIDByPersistentID(prs_id, scale_factors_[i]);
    if (image_memory_.find(raw_id) == image_memory_.end()) {
      image_missing = true;
      break;
    }
  }
  if (!image_missing)
    return;

  // Find available scale factor with highest scale.
  ui::ScaleFactor available_scale_factor = ui::SCALE_FACTOR_NONE;
  for (size_t i = 0; i < scale_factors_.size(); ++i) {
    int raw_id = GetRawIDByPersistentID(prs_id, scale_factors_[i]);
    if ((available_scale_factor == ui::SCALE_FACTOR_NONE ||
         (ui::GetScaleForScaleFactor(scale_factors_[i]) >
          ui::GetScaleForScaleFactor(available_scale_factor))) &&
        image_memory_.find(raw_id) != image_memory_.end()) {
      available_scale_factor = scale_factors_[i];
    }
  }
  // If no scale factor is available, we're done.
  if (available_scale_factor == ui::SCALE_FACTOR_NONE)
    return;

  // Get bitmap for the available scale factor.
  int available_raw_id = GetRawIDByPersistentID(prs_id, available_scale_factor);
  RawImages::const_iterator it = image_memory_.find(available_raw_id);
  SkBitmap available_bitmap;
  if (!gfx::PNGCodec::Decode(it->second->front(),
                             it->second->size(),
                             &available_bitmap)) {
    NOTREACHED() << "Unable to decode theme image for prs_id="
                 << prs_id << " for scale_factor=" << available_scale_factor;
    return;
  }

  // Fill in all missing scale factors by scaling the available bitmap.
  for (size_t i = 0; i < scale_factors_.size(); ++i) {
    int scaled_raw_id = GetRawIDByPersistentID(prs_id, scale_factors_[i]);
    if (image_memory_.find(scaled_raw_id) != image_memory_.end())
      continue;
    SkBitmap scaled_bitmap =
        CreateLowQualityResizedBitmap(available_bitmap,
                                      available_scale_factor,
                                      scale_factors_[i]);
    std::vector<unsigned char> bitmap_data;
    if (!gfx::PNGCodec::EncodeBGRASkBitmap(scaled_bitmap,
                                           false,
                                           &bitmap_data)) {
      NOTREACHED() << "Unable to encode theme image for prs_id="
                   << prs_id << " for scale_factor=" << scale_factors_[i];
      break;
    }
    image_memory_[scaled_raw_id] =
        base::RefCountedBytes::TakeVector(&bitmap_data);
  }
}
