| Index: base/gfx/png_encoder.cc | 
| =================================================================== | 
| --- base/gfx/png_encoder.cc	(revision 27832) | 
| +++ base/gfx/png_encoder.cc	(working copy) | 
| @@ -1,240 +0,0 @@ | 
| -// 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 "base/basictypes.h" | 
| -#include "base/gfx/png_encoder.h" | 
| -#include "base/logging.h" | 
| -#include "base/scoped_ptr.h" | 
| -#include "third_party/skia/include/core/SkBitmap.h" | 
| -#include "third_party/skia/include/core/SkUnPreMultiply.h" | 
| - | 
| -extern "C" { | 
| -#if defined(USE_SYSTEM_LIBPNG) | 
| -#include <png.h> | 
| -#else | 
| -#include "third_party/libpng/png.h" | 
| -#endif | 
| -} | 
| - | 
| -namespace { | 
| - | 
| -// Converts BGRA->RGBA and RGBA->BGRA. | 
| -void ConvertBetweenBGRAandRGBA(const unsigned char* input, int pixel_width, | 
| -                               unsigned char* output) { | 
| -  for (int x = 0; x < pixel_width; x++) { | 
| -    const unsigned char* pixel_in = &input[x * 4]; | 
| -    unsigned char* pixel_out = &output[x * 4]; | 
| -    pixel_out[0] = pixel_in[2]; | 
| -    pixel_out[1] = pixel_in[1]; | 
| -    pixel_out[2] = pixel_in[0]; | 
| -    pixel_out[3] = pixel_in[3]; | 
| -  } | 
| -} | 
| - | 
| -void ConvertRGBAtoRGB(const unsigned char* rgba, int pixel_width, | 
| -                      unsigned char* rgb) { | 
| -  for (int x = 0; x < pixel_width; x++) { | 
| -    const unsigned char* pixel_in = &rgba[x * 4]; | 
| -    unsigned char* pixel_out = &rgb[x * 3]; | 
| -    pixel_out[0] = pixel_in[0]; | 
| -    pixel_out[1] = pixel_in[1]; | 
| -    pixel_out[2] = pixel_in[2]; | 
| -  } | 
| -} | 
| - | 
| -}  // namespace | 
| - | 
| -// Encoder -------------------------------------------------------------------- | 
| -// | 
| -// This section of the code is based on nsPNGEncoder.cpp in Mozilla | 
| -// (Copyright 2005 Google Inc.) | 
| - | 
| -namespace { | 
| - | 
| -// Passed around as the io_ptr in the png structs so our callbacks know where | 
| -// to write data. | 
| -struct PngEncoderState { | 
| -  PngEncoderState(std::vector<unsigned char>* o) : out(o) {} | 
| -  std::vector<unsigned char>* out; | 
| -}; | 
| - | 
| -// Called by libpng to flush its internal buffer to ours. | 
| -void EncoderWriteCallback(png_structp png, png_bytep data, png_size_t size) { | 
| -  PngEncoderState* state = static_cast<PngEncoderState*>(png_get_io_ptr(png)); | 
| -  DCHECK(state->out); | 
| - | 
| -  size_t old_size = state->out->size(); | 
| -  state->out->resize(old_size + size); | 
| -  memcpy(&(*state->out)[old_size], data, size); | 
| -} | 
| - | 
| -void ConvertBGRAtoRGB(const unsigned char* bgra, int pixel_width, | 
| -                      unsigned char* rgb) { | 
| -  for (int x = 0; x < pixel_width; x++) { | 
| -    const unsigned char* pixel_in = &bgra[x * 4]; | 
| -    unsigned char* pixel_out = &rgb[x * 3]; | 
| -    pixel_out[0] = pixel_in[2]; | 
| -    pixel_out[1] = pixel_in[1]; | 
| -    pixel_out[2] = pixel_in[0]; | 
| -  } | 
| -} | 
| - | 
| -// Automatically destroys the given write structs on destruction to make | 
| -// cleanup and error handling code cleaner. | 
| -class PngWriteStructDestroyer { | 
| - public: | 
| -  PngWriteStructDestroyer(png_struct** ps, png_info** pi) : ps_(ps), pi_(pi) { | 
| -  } | 
| -  ~PngWriteStructDestroyer() { | 
| -    png_destroy_write_struct(ps_, pi_); | 
| -  } | 
| - private: | 
| -  png_struct** ps_; | 
| -  png_info** pi_; | 
| - | 
| -  DISALLOW_EVIL_CONSTRUCTORS(PngWriteStructDestroyer); | 
| -}; | 
| - | 
| -}  // namespace | 
| - | 
| -// static | 
| -bool PNGEncoder::Encode(const unsigned char* input, ColorFormat format, | 
| -                      int w, int h, int row_byte_width, | 
| -                      bool discard_transparency, | 
| -                      std::vector<unsigned char>* output) { | 
| -  // Run to convert an input row into the output row format, NULL means no | 
| -  // conversion is necessary. | 
| -  void (*converter)(const unsigned char* in, int w, unsigned char* out) = NULL; | 
| - | 
| -  int input_color_components, output_color_components; | 
| -  int png_output_color_type; | 
| -  switch (format) { | 
| -    case FORMAT_RGB: | 
| -      input_color_components = 3; | 
| -      output_color_components = 3; | 
| -      png_output_color_type = PNG_COLOR_TYPE_RGB; | 
| -      discard_transparency = false; | 
| -      break; | 
| - | 
| -    case FORMAT_RGBA: | 
| -      input_color_components = 4; | 
| -      if (discard_transparency) { | 
| -        output_color_components = 3; | 
| -        png_output_color_type = PNG_COLOR_TYPE_RGB; | 
| -        converter = ConvertRGBAtoRGB; | 
| -      } else { | 
| -        output_color_components = 4; | 
| -        png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA; | 
| -        converter = NULL; | 
| -      } | 
| -      break; | 
| - | 
| -    case FORMAT_BGRA: | 
| -      input_color_components = 4; | 
| -      if (discard_transparency) { | 
| -        output_color_components = 3; | 
| -        png_output_color_type = PNG_COLOR_TYPE_RGB; | 
| -        converter = ConvertBGRAtoRGB; | 
| -      } else { | 
| -        output_color_components = 4; | 
| -        png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA; | 
| -        converter = ConvertBetweenBGRAandRGBA; | 
| -      } | 
| -      break; | 
| - | 
| -    default: | 
| -      NOTREACHED() << "Unknown pixel format"; | 
| -      return false; | 
| -  } | 
| - | 
| -  // Row stride should be at least as long as the length of the data. | 
| -  DCHECK(input_color_components * w <= row_byte_width); | 
| - | 
| -  png_struct* png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, | 
| -                                                png_voidp_NULL, | 
| -                                                png_error_ptr_NULL, | 
| -                                                png_error_ptr_NULL); | 
| -  if (!png_ptr) | 
| -    return false; | 
| -  png_info* info_ptr = png_create_info_struct(png_ptr); | 
| -  if (!info_ptr) { | 
| -    png_destroy_write_struct(&png_ptr, NULL); | 
| -    return false; | 
| -  } | 
| -  PngWriteStructDestroyer destroyer(&png_ptr, &info_ptr); | 
| - | 
| -  if (setjmp(png_jmpbuf(png_ptr))) { | 
| -    // The destroyer will ensure that the structures are cleaned up in this | 
| -    // case, even though we may get here as a jump from random parts of the | 
| -    // PNG library called below. | 
| -    return false; | 
| -  } | 
| - | 
| -  // Set our callback for libpng to give us the data. | 
| -  PngEncoderState state(output); | 
| -  png_set_write_fn(png_ptr, &state, EncoderWriteCallback, NULL); | 
| - | 
| -  png_set_IHDR(png_ptr, info_ptr, w, h, 8, png_output_color_type, | 
| -               PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, | 
| -               PNG_FILTER_TYPE_DEFAULT); | 
| -  png_write_info(png_ptr, info_ptr); | 
| - | 
| -  if (!converter) { | 
| -    // No conversion needed, give the data directly to libpng. | 
| -    for (int y = 0; y < h; y ++) | 
| -      png_write_row(png_ptr, | 
| -                    const_cast<unsigned char*>(&input[y * row_byte_width])); | 
| -  } else { | 
| -    // Needs conversion using a separate buffer. | 
| -    unsigned char* row = new unsigned char[w * output_color_components]; | 
| -    for (int y = 0; y < h; y ++) { | 
| -      converter(&input[y * row_byte_width], w, row); | 
| -      png_write_row(png_ptr, row); | 
| -    } | 
| -    delete[] row; | 
| -  } | 
| - | 
| -  png_write_end(png_ptr, info_ptr); | 
| -  return true; | 
| -} | 
| - | 
| -// static | 
| -bool PNGEncoder::EncodeBGRASkBitmap(const SkBitmap& input, | 
| -                                    bool discard_transparency, | 
| -                                    std::vector<unsigned char>* output) { | 
| -  static const int bbp = 4; | 
| - | 
| -  SkAutoLockPixels lock_input(input); | 
| -  DCHECK(input.empty() || input.bytesPerPixel() == bbp); | 
| - | 
| -  // SkBitmaps are premultiplied, we need to unpremultiply them. | 
| -  scoped_array<unsigned char> divided( | 
| -      new unsigned char[input.width() * input.height() * bbp]); | 
| - | 
| -  int i = 0; | 
| -  for (int y = 0; y < input.height(); y++) { | 
| -    for (int x = 0; x < input.width(); x++) { | 
| -      uint32 pixel = input.getAddr32(0, y)[x]; | 
| - | 
| -      int alpha = SkColorGetA(pixel); | 
| -      if (alpha != 0 && alpha != 255) { | 
| -        SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel); | 
| -        divided[i + 0] = SkColorGetR(unmultiplied); | 
| -        divided[i + 1] = SkColorGetG(unmultiplied); | 
| -        divided[i + 2] = SkColorGetB(unmultiplied); | 
| -        divided[i + 3] = alpha; | 
| -      } else { | 
| -        divided[i + 0] = SkColorGetR(pixel); | 
| -        divided[i + 1] = SkColorGetG(pixel); | 
| -        divided[i + 2] = SkColorGetB(pixel); | 
| -        divided[i + 3] = alpha; | 
| -      } | 
| -      i += bbp; | 
| -    } | 
| -  } | 
| - | 
| -  return Encode(divided.get(), | 
| -                PNGEncoder::FORMAT_RGBA, input.width(), input.height(), | 
| -                input.width() * bbp, discard_transparency, output); | 
| -} | 
|  |