<commit_before>// Copyright (c) 2006-2008 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 "app/gfx/icon_util.h"

#include "app/win_util.h"
#include "base/file_util.h"
#include "base/gfx/size.h"
#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "skia/ext/image_operations.h"
#include "third_party/skia/include/core/SkBitmap.h"

// Defining the dimensions for the icon images. We store only one value because
// we always resize to a square image; that is, the value 48 means that we are
// going to resize the given bitmap to a 48 by 48 pixels bitmap.
//
// The icon images appear in the icon file in same order in which their
// corresponding dimensions appear in the |icon_dimensions_| array, so it is
// important to keep this array sorted. Also note that the maximum icon image
// size we can handle is 255 by 255.
const int IconUtil::icon_dimensions_[] = {
  8,    // Recommended by the MSDN as a nice to have icon size.
  10,   // Used by the Shell (e.g. for shortcuts).
  14,   // Recommended by the MSDN as a nice to have icon size.
  16,   // Toolbar, Application and Shell icon sizes.
  22,   // Recommended by the MSDN as a nice to have icon size.
  24,   // Used by the Shell (e.g. for shortcuts).
  32,   // Toolbar, Dialog and Wizard icon size.
  40,   // Quick Launch.
  48,   // Alt+Tab icon size.
  64,   // Recommended by the MSDN as a nice to have icon size.
  96,   // Recommended by the MSDN as a nice to have icon size.
  128   // Used by the Shell (e.g. for shortcuts).
};

HICON IconUtil::CreateHICONFromSkBitmap(const SkBitmap& bitmap) {
  // Only 32 bit ARGB bitmaps are supported. We also try to perform as many
  // validations as we can on the bitmap.
  SkAutoLockPixels bitmap_lock(bitmap);
  if ((bitmap.getConfig() != SkBitmap::kARGB_8888_Config) ||
      (bitmap.width() <= 0) || (bitmap.height() <= 0) ||
      (bitmap.getPixels() == NULL)) {
    return NULL;
  }

  // We start by creating a DIB which we'll use later on in order to create
  // the HICON. We use BITMAPV5HEADER since the bitmap we are about to convert
  // may contain an alpha channel and the V5 header allows us to specify the
  // alpha mask for the DIB.
  BITMAPV5HEADER bitmap_header;
  InitializeBitmapHeader(&bitmap_header, bitmap.width(), bitmap.height());
  void* bits;
  HDC hdc = ::GetDC(NULL);
  HBITMAP dib;
  dib = ::CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO*>(&bitmap_header),
                           DIB_RGB_COLORS, &bits, NULL, 0);
  DCHECK(dib);
  ::ReleaseDC(NULL, hdc);
  memcpy(bits, bitmap.getPixels(), bitmap.width() * bitmap.height() * 4);

  // Icons are generally created using an AND and XOR masks where the AND
  // specifies boolean transparency (the pixel is either opaque or
  // transparent) and the XOR mask contains the actual image pixels. If the XOR
  // mask bitmap has an alpha channel, the AND monochrome bitmap won't
  // actually be used for computing the pixel transparency. Even though all our
  // bitmap has an alpha channel, Windows might not agree when all alpha values
  // are zero. So the monochrome bitmap is created with all pixels transparent
  // for this case. Otherwise, it is created with all pixels opaque.
  bool bitmap_has_alpha_channel = PixelsHaveAlpha(
      static_cast<const uint32*>(bitmap.getPixels()),
      bitmap.width() * bitmap.height());

  scoped_array<uint8> mask_bits;
  if (!bitmap_has_alpha_channel) {
    // Bytes per line with paddings to make it word alignment.
    size_t bytes_per_line = (bitmap.width() + 0xF) / 16 * 2;
    size_t mask_bits_size = bytes_per_line * bitmap.height();

    mask_bits.reset(new uint8[mask_bits_size]);
    DCHECK(mask_bits.get());

    // Make all pixels transparent.
    memset(mask_bits.get(), 0xFF, mask_bits_size);
  }

  HBITMAP mono_bitmap = ::CreateBitmap(bitmap.width(), bitmap.height(), 1, 1,
      reinterpret_cast<LPVOID>(mask_bits.get()));
  DCHECK(mono_bitmap);

  ICONINFO icon_info;
  icon_info.fIcon = TRUE;
  icon_info.xHotspot = 0;
  icon_info.yHotspot = 0;
  icon_info.hbmMask = mono_bitmap;
  icon_info.hbmColor = dib;
  HICON icon = ::CreateIconIndirect(&icon_info);
  ::DeleteObject(dib);
  ::DeleteObject(mono_bitmap);
  return icon;
}

SkBitmap* IconUtil::CreateSkBitmapFromHICON(HICON icon, const gfx::Size& s) {
  // We start with validating parameters.
  ICONINFO icon_info;
  if (!icon || !(::GetIconInfo(icon, &icon_info)) ||
      !icon_info.fIcon || s.IsEmpty()) {
    return NULL;
  }

  // Allocating memory for the SkBitmap object. We are going to create an ARGB
  // bitmap so we should set the configuration appropriately.
  SkBitmap* bitmap = new SkBitmap;
  DCHECK(bitmap);
  bitmap->setConfig(SkBitmap::kARGB_8888_Config, s.width(), s.height());
  bitmap->allocPixels();
  SkAutoLockPixels bitmap_lock(*bitmap);

  // Now we should create a DIB so that we can use ::DrawIconEx in order to
  // obtain the icon's image.
  BITMAPV5HEADER h;
  InitializeBitmapHeader(&h, s.width(), s.height());
  HDC dc = ::GetDC(NULL);
  unsigned int* bits;
  HBITMAP dib = ::CreateDIBSection(dc,
                                   reinterpret_cast<BITMAPINFO*>(&h),
                                   DIB_RGB_COLORS,
                                   reinterpret_cast<void**>(&bits),
                                   NULL,
                                   0);
  DCHECK(dib);
  HDC dib_dc = CreateCompatibleDC(dc);<commit_msg>Init allocated SkBitmap pixels<commit_after>// Copyright (c) 2006-2008 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 "app/gfx/icon_util.h"

#include "app/win_util.h"
#include "base/file_util.h"
#include "base/gfx/size.h"
#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "skia/ext/image_operations.h"
#include "third_party/skia/include/core/SkBitmap.h"

// Defining the dimensions for the icon images. We store only one value because
// we always resize to a square image; that is, the value 48 means that we are
// going to resize the given bitmap to a 48 by 48 pixels bitmap.
//
// The icon images appear in the icon file in same order in which their
// corresponding dimensions appear in the |icon_dimensions_| array, so it is
// important to keep this array sorted. Also note that the maximum icon image
// size we can handle is 255 by 255.
const int IconUtil::icon_dimensions_[] = {
  8,    // Recommended by the MSDN as a nice to have icon size.
  10,   // Used by the Shell (e.g. for shortcuts).
  14,   // Recommended by the MSDN as a nice to have icon size.
  16,   // Toolbar, Application and Shell icon sizes.
  22,   // Recommended by the MSDN as a nice to have icon size.
  24,   // Used by the Shell (e.g. for shortcuts).
  32,   // Toolbar, Dialog and Wizard icon size.
  40,   // Quick Launch.
  48,   // Alt+Tab icon size.
  64,   // Recommended by the MSDN as a nice to have icon size.
  96,   // Recommended by the MSDN as a nice to have icon size.
  128   // Used by the Shell (e.g. for shortcuts).
};

HICON IconUtil::CreateHICONFromSkBitmap(const SkBitmap& bitmap) {
  // Only 32 bit ARGB bitmaps are supported. We also try to perform as many
  // validations as we can on the bitmap.
  SkAutoLockPixels bitmap_lock(bitmap);
  if ((bitmap.getConfig() != SkBitmap::kARGB_8888_Config) ||
      (bitmap.width() <= 0) || (bitmap.height() <= 0) ||
      (bitmap.getPixels() == NULL)) {
    return NULL;
  }

  // We start by creating a DIB which we'll use later on in order to create
  // the HICON. We use BITMAPV5HEADER since the bitmap we are about to convert
  // may contain an alpha channel and the V5 header allows us to specify the
  // alpha mask for the DIB.
  BITMAPV5HEADER bitmap_header;
  InitializeBitmapHeader(&bitmap_header, bitmap.width(), bitmap.height());
  void* bits;
  HDC hdc = ::GetDC(NULL);
  HBITMAP dib;
  dib = ::CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO*>(&bitmap_header),
                           DIB_RGB_COLORS, &bits, NULL, 0);
  DCHECK(dib);
  ::ReleaseDC(NULL, hdc);
  memcpy(bits, bitmap.getPixels(), bitmap.width() * bitmap.height() * 4);

  // Icons are generally created using an AND and XOR masks where the AND
  // specifies boolean transparency (the pixel is either opaque or
  // transparent) and the XOR mask contains the actual image pixels. If the XOR
  // mask bitmap has an alpha channel, the AND monochrome bitmap won't
  // actually be used for computing the pixel transparency. Even though all our
  // bitmap has an alpha channel, Windows might not agree when all alpha values
  // are zero. So the monochrome bitmap is created with all pixels transparent
  // for this case. Otherwise, it is created with all pixels opaque.
  bool bitmap_has_alpha_channel = PixelsHaveAlpha(
      static_cast<const uint32*>(bitmap.getPixels()),
      bitmap.width() * bitmap.height());

  scoped_array<uint8> mask_bits;
  if (!bitmap_has_alpha_channel) {
    // Bytes per line with paddings to make it word alignment.
    size_t bytes_per_line = (bitmap.width() + 0xF) / 16 * 2;
    size_t mask_bits_size = bytes_per_line * bitmap.height();

    mask_bits.reset(new uint8[mask_bits_size]);
    DCHECK(mask_bits.get());

    // Make all pixels transparent.
    memset(mask_bits.get(), 0xFF, mask_bits_size);
  }

  HBITMAP mono_bitmap = ::CreateBitmap(bitmap.width(), bitmap.height(), 1, 1,
      reinterpret_cast<LPVOID>(mask_bits.get()));
  DCHECK(mono_bitmap);

  ICONINFO icon_info;
  icon_info.fIcon = TRUE;
  icon_info.xHotspot = 0;
  icon_info.yHotspot = 0;
  icon_info.hbmMask = mono_bitmap;
  icon_info.hbmColor = dib;
  HICON icon = ::CreateIconIndirect(&icon_info);
  ::DeleteObject(dib);
  ::DeleteObject(mono_bitmap);
  return icon;
}

SkBitmap* IconUtil::CreateSkBitmapFromHICON(HICON icon, const gfx::Size& s) {
  // We start with validating parameters.
  ICONINFO icon_info;
  if (!icon || !(::GetIconInfo(icon, &icon_info)) ||
      !icon_info.fIcon || s.IsEmpty()) {
    return NULL;
  }

  // Allocating memory for the SkBitmap object. We are going to create an ARGB
  // bitmap so we should set the configuration appropriately.
  SkBitmap* bitmap = new SkBitmap;
  DCHECK(bitmap);
  bitmap->setConfig(SkBitmap::kARGB_8888_Config, s.width(), s.height());
  bitmap->allocPixels();
  bitmap->eraseARGB(0, 0, 0, 0);
  SkAutoLockPixels bitmap_lock(*bitmap);

  // Now we should create a DIB so that we can use ::DrawIconEx in order to
  // obtain the icon's image.
  BITMAPV5HEADER h;
  InitializeBitmapHeader(&h, s.width(), s.height());
  HDC dc = ::GetDC(NULL);
  unsigned int* bits;
  HBITMAP dib = ::CreateDIBSection(dc,
                                   reinterpret_cast<BITMAPINFO*>(&h),
                                   DIB_RGB_COLORS,
                                   reinterpret_cast<void**>(&bits),
                                   NULL,
                                   0);
  DCHECK(dib);
  HDC dib_dc = CreateCompatibleDC(dc);
{'fraction_non_alphanumeric': 0.10624434389140272, 'fraction_numerical': 0.01411764705882353, 'mean_word_length': 3.0975157582499073, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5962145', 'n_tokens_mistral': 3610, 'n_tokens_neox': 3470, 'n_words': 1224}