| Index: ui/gfx/codec/png_codec.cc
|
| diff --git a/ui/gfx/codec/png_codec.cc b/ui/gfx/codec/png_codec.cc
|
| index a0dfbbed0e612585a792eddef3fe758c219e3b62..c31f52a3181e8f3e6de1631cf0411c1ae2340568 100644
|
| --- a/ui/gfx/codec/png_codec.cc
|
| +++ b/ui/gfx/codec/png_codec.cc
|
| @@ -1,4 +1,4 @@
|
| -// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
| +// Copyright (c) 2011 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.
|
|
|
| @@ -6,6 +6,8 @@
|
|
|
| #include "base/logging.h"
|
| #include "base/scoped_ptr.h"
|
| +#include "base/string_util.h"
|
| +#include "ui/gfx/size.h"
|
| #include "third_party/skia/include/core/SkBitmap.h"
|
| #include "third_party/skia/include/core/SkUnPreMultiply.h"
|
| #include "third_party/skia/include/core/SkColorPriv.h"
|
| @@ -546,6 +548,58 @@ void ConvertBGRAtoRGB(const unsigned char* bgra, int pixel_width,
|
| }
|
| }
|
|
|
| +#ifdef PNG_TEXT_SUPPORTED
|
| +class CommentWriter {
|
| + public:
|
| + explicit CommentWriter(const std::vector<PNGCodec::Comment>& comments)
|
| + : comments_(comments),
|
| + png_text_(new png_text[comments.size()]) {
|
| + for (size_t i = 0; i < comments.size(); ++i)
|
| + AddComment(i, comments[i]);
|
| + }
|
| +
|
| + ~CommentWriter() {
|
| + for (size_t i = 0; i < comments_.size(); ++i) {
|
| + free(png_text_[i].key);
|
| + free(png_text_[i].text);
|
| + }
|
| + delete [] png_text_;
|
| + }
|
| +
|
| + bool HasComments() {
|
| + return !comments_.empty();
|
| + }
|
| +
|
| + png_text* get_png_text() {
|
| + return png_text_;
|
| + }
|
| +
|
| + int size() {
|
| + return static_cast<int>(comments_.size());
|
| + }
|
| +
|
| + private:
|
| + void AddComment(size_t pos, const PNGCodec::Comment& comment) {
|
| + png_text_[pos].compression = PNG_TEXT_COMPRESSION_NONE;
|
| + // A PNG comment's key can only be 79 characters long.
|
| + DCHECK(comment.key.length() < 79);
|
| + png_text_[pos].key = base::strdup(comment.key.substr(0, 78).c_str());
|
| + png_text_[pos].text = base::strdup(comment.text.c_str());
|
| + png_text_[pos].text_length = comment.text.length();
|
| +#ifdef PNG_iTXt_SUPPORTED
|
| + png_text_[pos].itxt_length = 0;
|
| + png_text_[pos].lang = 0;
|
| + png_text_[pos].lang_key = 0;
|
| +#endif
|
| + }
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(CommentWriter);
|
| +
|
| + const std::vector<PNGCodec::Comment> comments_;
|
| + png_text* png_text_;
|
| +};
|
| +#endif // PNG_TEXT_SUPPORTED
|
| +
|
| // The type of functions usable for converting between pixel formats.
|
| typedef void (*FormatConverter)(const unsigned char* in, int w,
|
| unsigned char* out, bool* is_opaque);
|
| @@ -559,7 +613,8 @@ bool DoLibpngWrite(png_struct* png_ptr, png_info* info_ptr,
|
| int width, int height, int row_byte_width,
|
| const unsigned char* input,
|
| int png_output_color_type, int output_color_components,
|
| - FormatConverter converter) {
|
| + FormatConverter converter,
|
| + const std::vector<PNGCodec::Comment>& comments) {
|
| // Make sure to not declare any locals here -- locals in the presence
|
| // of setjmp() in C++ code makes gcc complain.
|
|
|
| @@ -572,6 +627,15 @@ bool DoLibpngWrite(png_struct* png_ptr, png_info* info_ptr,
|
| png_set_IHDR(png_ptr, info_ptr, width, height, 8, png_output_color_type,
|
| PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
| PNG_FILTER_TYPE_DEFAULT);
|
| +
|
| +#ifdef PNG_TEXT_SUPPORTED
|
| + CommentWriter comment_writer(comments);
|
| + if (comment_writer.HasComments()) {
|
| + png_set_text(png_ptr, info_ptr, comment_writer.get_png_text(),
|
| + comment_writer.size());
|
| + }
|
| +#endif
|
| +
|
| png_write_info(png_ptr, info_ptr);
|
|
|
| if (!converter) {
|
| @@ -598,8 +662,9 @@ bool DoLibpngWrite(png_struct* png_ptr, png_info* info_ptr,
|
|
|
| // static
|
| bool PNGCodec::Encode(const unsigned char* input, ColorFormat format,
|
| - int w, int h, int row_byte_width,
|
| + const Size& size, int row_byte_width,
|
| bool discard_transparency,
|
| + const std::vector<Comment>& comments,
|
| std::vector<unsigned char>* output) {
|
| // Run to convert an input row into the output row format, NULL means no
|
| // conversion is necessary.
|
| @@ -660,7 +725,7 @@ bool PNGCodec::Encode(const unsigned char* input, ColorFormat format,
|
| }
|
|
|
| // Row stride should be at least as long as the length of the data.
|
| - DCHECK(input_color_components * w <= row_byte_width);
|
| + DCHECK(input_color_components * size.width() <= row_byte_width);
|
|
|
| png_struct* png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
| NULL, NULL, NULL);
|
| @@ -674,9 +739,9 @@ bool PNGCodec::Encode(const unsigned char* input, ColorFormat format,
|
|
|
| PngEncoderState state(output);
|
| bool success = DoLibpngWrite(png_ptr, info_ptr, &state,
|
| - w, h, row_byte_width, input,
|
| - png_output_color_type, output_color_components,
|
| - converter);
|
| + size.width(), size.height(), row_byte_width,
|
| + input, png_output_color_type,
|
| + output_color_components, converter, comments);
|
| png_destroy_write_struct(&png_ptr, &info_ptr);
|
|
|
| return success;
|
| @@ -692,8 +757,16 @@ bool PNGCodec::EncodeBGRASkBitmap(const SkBitmap& input,
|
| DCHECK(input.empty() || input.bytesPerPixel() == bbp);
|
|
|
| return Encode(reinterpret_cast<unsigned char*>(input.getAddr32(0, 0)),
|
| - FORMAT_SkBitmap, input.width(), input.height(),
|
| - input.width() * bbp, discard_transparency, output);
|
| + FORMAT_SkBitmap, Size(input.width(), input.height()),
|
| + input.width() * bbp, discard_transparency,
|
| + std::vector<Comment>(), output);
|
| +}
|
| +
|
| +PNGCodec::Comment::Comment(const std::string& k, const std::string& t)
|
| + : key(k), text(t) {
|
| +}
|
| +
|
| +PNGCodec::Comment::~Comment() {
|
| }
|
|
|
| } // namespace gfx
|
|
|