diff options
author | tony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-28 18:24:21 +0000 |
---|---|---|
committer | tony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-28 18:24:21 +0000 |
commit | c99fcf5a1913cea79dbf53cc5ca3dba8e3ee5d64 (patch) | |
tree | ec671064fb18a8e0cf198c514680ea6f86ecc345 | |
parent | a6e70b07a557d6c1765df2560c0104a9033c4015 (diff) | |
download | chromium_src-c99fcf5a1913cea79dbf53cc5ca3dba8e3ee5d64.zip chromium_src-c99fcf5a1913cea79dbf53cc5ca3dba8e3ee5d64.tar.gz chromium_src-c99fcf5a1913cea79dbf53cc5ca3dba8e3ee5d64.tar.bz2 |
Add the ability to write comments to PNGCodec::Encode.
I'm going to use this to write layout test checksums to the
expected png files.
Review URL: http://codereview.chromium.org/6696085
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79592 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/ui/window_snapshot/window_snapshot_win.cc | 4 | ||||
-rw-r--r-- | printing/image.cc | 4 | ||||
-rw-r--r-- | skia/ext/image_operations_unittest.cc | 5 | ||||
-rw-r--r-- | skia/ext/vector_canvas_unittest.cc | 5 | ||||
-rw-r--r-- | third_party/libpng/pngusr.h | 1 | ||||
-rw-r--r-- | tools/imagediff/DEPS | 2 | ||||
-rw-r--r-- | tools/imagediff/image_diff.cc | 6 | ||||
-rw-r--r-- | ui/gfx/codec/png_codec.cc | 89 | ||||
-rw-r--r-- | ui/gfx/codec/png_codec.h | 24 | ||||
-rw-r--r-- | ui/gfx/codec/png_codec_unittest.cc | 81 | ||||
-rw-r--r-- | webkit/support/webkit_support_gfx.h | 40 |
11 files changed, 211 insertions, 50 deletions
diff --git a/chrome/browser/ui/window_snapshot/window_snapshot_win.cc b/chrome/browser/ui/window_snapshot/window_snapshot_win.cc index b4fcdba..0885c7b 100644 --- a/chrome/browser/ui/window_snapshot/window_snapshot_win.cc +++ b/chrome/browser/ui/window_snapshot/window_snapshot_win.cc @@ -9,6 +9,7 @@ #include "ui/gfx/codec/png_codec.h" #include "ui/gfx/gdi_util.h" #include "ui/gfx/rect.h" +#include "ui/gfx/size.h" namespace browser { @@ -61,7 +62,8 @@ gfx::Rect GrabWindowSnapshot(gfx::NativeWindow window_handle, // encode it into a useful format for posting to the bug report // server. gfx::PNGCodec::Encode(bit_ptr, gfx::PNGCodec::FORMAT_BGRA, - width, height, width * 4, true, + gfx::Size(width, height), width * 4, true, + std::vector<gfx::PNGCodec::Comment>(), png_representation); ReleaseDC(window_handle, window_hdc); diff --git a/printing/image.cc b/printing/image.cc index 5c5213f..a7ae67d 100644 --- a/printing/image.cc +++ b/printing/image.cc @@ -60,10 +60,10 @@ bool Image::SaveToPng(const FilePath& filepath) const { std::vector<unsigned char> compressed; bool success = gfx::PNGCodec::Encode(&*data_.begin(), gfx::PNGCodec::FORMAT_BGRA, - size_.width(), - size_.height(), + size_, row_length_, true, + std::vector<gfx::PNGCodec::Comment>(), &compressed); DCHECK(success && compressed.size()); if (success) { diff --git a/skia/ext/image_operations_unittest.cc b/skia/ext/image_operations_unittest.cc index c1bd3e1..e8c0e9f 100644 --- a/skia/ext/image_operations_unittest.cc +++ b/skia/ext/image_operations_unittest.cc @@ -14,6 +14,7 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkRect.h" #include "ui/gfx/codec/png_codec.h" +#include "ui/gfx/size.h" namespace { @@ -193,9 +194,9 @@ void SaveBitmapToPNG(const SkBitmap& bmp, const char* path) { gfx::PNGCodec::ColorFormat color_format = gfx::PNGCodec::FORMAT_RGBA; if (!gfx::PNGCodec::Encode( reinterpret_cast<const unsigned char*>(bmp.getPixels()), - color_format, bmp.width(), bmp.height(), + color_format, gfx::Size(bmp.width(), bmp.height()), static_cast<int>(bmp.rowBytes()), - false, &png)) { + false, std::vector<gfx::PNGCodec::Comment>(), &png)) { FAIL() << "Failed to encode image"; } diff --git a/skia/ext/vector_canvas_unittest.cc b/skia/ext/vector_canvas_unittest.cc index 1066c0c..355aa13 100644 --- a/skia/ext/vector_canvas_unittest.cc +++ b/skia/ext/vector_canvas_unittest.cc @@ -18,6 +18,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/effects/SkDashPathEffect.h" #include "ui/gfx/codec/png_codec.h" +#include "ui/gfx/size.h" namespace skia { @@ -126,10 +127,10 @@ class Image { std::vector<unsigned char> compressed; ASSERT_TRUE(gfx::PNGCodec::Encode(&*data_.begin(), gfx::PNGCodec::FORMAT_BGRA, - width_, - height_, + gfx::Size(width_, height_), row_length_, true, + std::vector<gfx::PNGCodec::Comment>(), &compressed)); ASSERT_TRUE(compressed.size()); FILE* f = file_util::OpenFile(filename, "wb"); diff --git a/third_party/libpng/pngusr.h b/third_party/libpng/pngusr.h index 04415b1..f2446e1 100644 --- a/third_party/libpng/pngusr.h +++ b/third_party/libpng/pngusr.h @@ -97,7 +97,6 @@ #define PNG_NO_WRITE_sCAL #define PNG_NO_WRITE_sPLT #define PNG_NO_WRITE_sRGB -#define PNG_NO_WRITE_TEXT #define PNG_NO_WRITE_tIME #define PNG_NO_WRITE_UNKNOWN_CHUNKS #define PNG_NO_WRITE_USER_CHUNKS diff --git a/tools/imagediff/DEPS b/tools/imagediff/DEPS index 1a45e54..b273ae3 100644 --- a/tools/imagediff/DEPS +++ b/tools/imagediff/DEPS @@ -1,3 +1,3 @@ include_rules = [ - "+ui/gfx/codec", + "+ui/gfx", ] diff --git a/tools/imagediff/image_diff.cc b/tools/imagediff/image_diff.cc index 6f775a5..294e2e3 100644 --- a/tools/imagediff/image_diff.cc +++ b/tools/imagediff/image_diff.cc @@ -23,6 +23,7 @@ #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "ui/gfx/codec/png_codec.h" +#include "ui/gfx/size.h" #if defined(OS_WIN) #include "windows.h" @@ -316,8 +317,9 @@ int DiffImages(const FilePath& file1, const FilePath& file2, std::vector<unsigned char> png_encoding; gfx::PNGCodec::Encode(diff_image.data(), gfx::PNGCodec::FORMAT_RGBA, - diff_image.w(), diff_image.h(), diff_image.w() * 4, - false, &png_encoding); + gfx::Size(diff_image.w(), diff_image.h()), + diff_image.w() * 4, false, + std::vector<gfx::PNGCodec::Comment>(), &png_encoding); if (file_util::WriteFile(out_file, reinterpret_cast<char*>(&png_encoding.front()), png_encoding.size()) < 0) return kStatusError; diff --git a/ui/gfx/codec/png_codec.cc b/ui/gfx/codec/png_codec.cc index 6cd761f..0d9596e 100644 --- a/ui/gfx/codec/png_codec.cc +++ b/ui/gfx/codec/png_codec.cc @@ -6,6 +6,8 @@ #include "base/logging.h" #include "base/memory/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 diff --git a/ui/gfx/codec/png_codec.h b/ui/gfx/codec/png_codec.h index 73453fe..eac411d 100644 --- a/ui/gfx/codec/png_codec.h +++ b/ui/gfx/codec/png_codec.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 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,7 @@ #define UI_GFX_CODEC_PNG_CODEC_H_ #pragma once +#include <string> #include <vector> #include "base/basictypes.h" @@ -14,6 +15,8 @@ class SkBitmap; namespace gfx { +class Size; + // Interface for encoding and decoding PNG data. This is a wrapper around // libpng, which has an inconvenient interface for callers. This is currently // designed for use in tests only (where we control the files), so the handling @@ -39,6 +42,15 @@ class PNGCodec { FORMAT_SkBitmap }; + // Represents a comment in the tEXt ancillary chunk of the png. + struct Comment { + Comment(const std::string& k, const std::string& t); + ~Comment(); + + std::string key; + std::string text; + }; + // Encodes the given raw 'input' data, with each pixel being represented as // given in 'format'. The encoded PNG data will be written into the supplied // vector and true will be returned on success. On failure (false), the @@ -47,7 +59,7 @@ class PNGCodec { // When writing alpha values, the input colors are assumed to be post // multiplied. // - // w, h: dimensions of the image + // size: dimensions of the image // row_byte_width: the width in bytes of each row. This may be greater than // w * bytes_per_pixel if there is extra padding at the end of each row // (often, each row is padded to the next machine word). @@ -55,9 +67,13 @@ class PNGCodec { // alpha values, these alpha values will be discarded and only RGB will be // written to the resulting file. Otherwise, alpha values in the input // will be preserved. - static bool Encode(const unsigned char* input, ColorFormat format, - int w, int h, int row_byte_width, + // comments: comments to be written in the png's metadata. + static bool Encode(const unsigned char* input, + ColorFormat format, + const Size& size, + int row_byte_width, bool discard_transparency, + const std::vector<Comment>& comments, std::vector<unsigned char>* output); // Call PNGCodec::Encode on the supplied SkBitmap |input|, which is assumed diff --git a/ui/gfx/codec/png_codec_unittest.cc b/ui/gfx/codec/png_codec_unittest.cc index 72ed671..b31dbd2 100644 --- a/ui/gfx/codec/png_codec_unittest.cc +++ b/ui/gfx/codec/png_codec_unittest.cc @@ -1,13 +1,15 @@ -// Copyright (c) 2006-2008 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. -#include <math.h> +#include <algorithm> +#include <cmath> #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkUnPreMultiply.h" #include "ui/gfx/codec/png_codec.h" +#include "ui/gfx/size.h" namespace gfx { @@ -79,8 +81,10 @@ TEST(PNGCodec, EncodeDecodeRGB) { // encode std::vector<unsigned char> encoded; - EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB, w, h, - w * 3, false, &encoded)); + EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB, + Size(w, h), w * 3, false, + std::vector<PNGCodec::Comment>(), + &encoded)); // decode, it should have the same size as the original std::vector<unsigned char> decoded; @@ -106,8 +110,10 @@ TEST(PNGCodec, EncodeDecodeRGBA) { // encode std::vector<unsigned char> encoded; - EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGBA, w, h, - w * 4, false, &encoded)); + EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGBA, + Size(w, h), w * 4, false, + std::vector<PNGCodec::Comment>(), + &encoded)); // decode, it should have the same size as the original std::vector<unsigned char> decoded; @@ -140,8 +146,10 @@ TEST(PNGCodec, DecodeCorrupted) { // Make some compressed data. std::vector<unsigned char> compressed; - EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB, w, h, - w * 3, false, &compressed)); + EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB, + Size(w, h), w * 3, false, + std::vector<PNGCodec::Comment>(), + &compressed)); // Try decompressing a truncated version. EXPECT_FALSE(PNGCodec::Decode(&compressed[0], compressed.size() / 2, @@ -166,8 +174,10 @@ TEST(PNGCodec, EncodeDecodeBGRA) { // Encode. std::vector<unsigned char> encoded; - EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_BGRA, w, h, - w * 4, false, &encoded)); + EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_BGRA, + Size(w, h), w * 4, false, + std::vector<PNGCodec::Comment>(), + &encoded)); // Decode, it should have the same size as the original. std::vector<unsigned char> decoded; @@ -194,10 +204,10 @@ TEST(PNGCodec, StripAddAlpha) { // Encode RGBA data as RGB. std::vector<unsigned char> encoded; - EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], - PNGCodec::FORMAT_RGBA, - w, h, - w * 4, true, &encoded)); + EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], PNGCodec::FORMAT_RGBA, + Size(w, h), w * 4, true, + std::vector<PNGCodec::Comment>(), + &encoded)); // Decode the RGB to RGBA. std::vector<unsigned char> decoded; @@ -213,10 +223,10 @@ TEST(PNGCodec, StripAddAlpha) { ASSERT_TRUE(original_rgba == decoded); // Encode RGBA to RGBA. - EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], - PNGCodec::FORMAT_RGBA, - w, h, - w * 4, false, &encoded)); + EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], PNGCodec::FORMAT_RGBA, + Size(w, h), w * 4, false, + std::vector<PNGCodec::Comment>(), + &encoded)); // Decode the RGBA to RGB. EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), @@ -294,4 +304,39 @@ TEST(PNGCodec, EncodeBGRASkBitmapDiscardTransparency) { } } +TEST(PNGCodec, EncodeWithComment) { + const int w = 10, h = 10; + + std::vector<unsigned char> original; + MakeRGBImage(w, h, &original); + + std::vector<unsigned char> encoded; + std::vector<PNGCodec::Comment> comments; + comments.push_back(PNGCodec::Comment("key", "text")); + comments.push_back(PNGCodec::Comment("test", "something")); + comments.push_back(PNGCodec::Comment("have some", "spaces in both")); + EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB, + Size(w, h), w * 3, false, comments, &encoded)); + + // Each chunk is of the form length (4 bytes), chunk type (tEXt), data, + // checksum (4 bytes). Make sure we find all of them in the encoded + // results. + const unsigned char kExpected1[] = + "\x00\x00\x00\x08tEXtkey\x00text\x9e\xe7\x66\x51"; + const unsigned char kExpected2[] = + "\x00\x00\x00\x0etEXttest\x00something\x29\xba\xef\xac"; + const unsigned char kExpected3[] = + "\x00\x00\x00\x18tEXthave some\x00spaces in both\x8d\x69\x34\x2d"; + + EXPECT_NE(search(encoded.begin(), encoded.end(), kExpected1, + kExpected1 + arraysize(kExpected1)), + encoded.end()); + EXPECT_NE(search(encoded.begin(), encoded.end(), kExpected2, + kExpected2 + arraysize(kExpected2)), + encoded.end()); + EXPECT_NE(search(encoded.begin(), encoded.end(), kExpected3, + kExpected3 + arraysize(kExpected3)), + encoded.end()); +} + } // namespace gfx diff --git a/webkit/support/webkit_support_gfx.h b/webkit/support/webkit_support_gfx.h index 60bb765..e652d1c 100644 --- a/webkit/support/webkit_support_gfx.h +++ b/webkit/support/webkit_support_gfx.h @@ -1,13 +1,15 @@ -// Copyright (c) 2010 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. #ifndef WEBKIT_SUPPORT_WEBKIT_SUPPORT_GFX_H_ #define WEBKIT_SUPPORT_WEBKIT_SUPPORT_GFX_H_ +#include <string> #include <vector> #include "ui/gfx/codec/png_codec.h" +#include "ui/gfx/size.h" namespace webkit_support { @@ -20,20 +22,40 @@ inline bool DecodePNG(const unsigned char* input, size_t input_size, } // Encode an RGBA pixel array into a PNG. -inline bool EncodeRGBAPNG(const unsigned char* input, int width, int height, +inline bool EncodeRGBAPNG(const unsigned char* input, + int width, + int height, int row_byte_width, std::vector<unsigned char>* output) { - return gfx::PNGCodec::Encode(input, gfx::PNGCodec::FORMAT_RGBA, width, - height, row_byte_width, false, output); + return gfx::PNGCodec::Encode(input, gfx::PNGCodec::FORMAT_RGBA, + gfx::Size(width, height), row_byte_width, false, + std::vector<gfx::PNGCodec::Comment>(), output); } // Encode an BGRA pixel array into a PNG. -inline bool EncodeBGRAPNG(const unsigned char* input, int width, int height, - int row_byte_width, bool discard_transparency, +inline bool EncodeBGRAPNG(const unsigned char* input, + int width, + int height, + int row_byte_width, + bool discard_transparency, + std::vector<unsigned char>* output) { + return gfx::PNGCodec::Encode(input, gfx::PNGCodec::FORMAT_BGRA, + gfx::Size(width, height), row_byte_width, discard_transparency, + std::vector<gfx::PNGCodec::Comment>(), output); +} + +inline bool EncodeBGRAPNGWithChecksum(const unsigned char* input, + int width, + int height, + int row_byte_width, + bool discard_transparency, + const std::string& checksum, std::vector<unsigned char>* output) { - return gfx::PNGCodec::Encode(input, gfx::PNGCodec::FORMAT_BGRA, width, - height, row_byte_width, discard_transparency, - output); + std::vector<gfx::PNGCodec::Comment> comments; + comments.push_back(gfx::PNGCodec::Comment("checksum", checksum)); + return gfx::PNGCodec::Encode(input, gfx::PNGCodec::FORMAT_BGRA, + gfx::Size(width, height), row_byte_width, discard_transparency, + comments, output); } } // namespace webkit_support |