diff options
author | dcheng@chromium.org <dcheng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-13 21:13:15 +0000 |
---|---|---|
committer | dcheng@chromium.org <dcheng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-13 21:13:15 +0000 |
commit | c05a26cc654acceb8062a759adecedeceeeb89b3 (patch) | |
tree | 17b7d972e6cd416a8220dda0c029756c46763d2b /ui | |
parent | e04dc4124a2455bf8fe0588793ab0c40f60b912e (diff) | |
download | chromium_src-c05a26cc654acceb8062a759adecedeceeeb89b3.zip chromium_src-c05a26cc654acceb8062a759adecedeceeeb89b3.tar.gz chromium_src-c05a26cc654acceb8062a759adecedeceeeb89b3.tar.bz2 |
Allow caller to specify compression level of PNGs.
BUG=75237
TEST=ui_unittests --gtest_filter=PNGCodec.EncodeDecodeWithVaryingCompressionLevels
Review URL: http://codereview.chromium.org/6834011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81481 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/gfx/codec/png_codec.cc | 21 | ||||
-rw-r--r-- | ui/gfx/codec/png_codec.h | 27 | ||||
-rw-r--r-- | ui/gfx/codec/png_codec_unittest.cc | 46 |
3 files changed, 85 insertions, 9 deletions
diff --git a/ui/gfx/codec/png_codec.cc b/ui/gfx/codec/png_codec.cc index 0d9596e..829faa1 100644 --- a/ui/gfx/codec/png_codec.cc +++ b/ui/gfx/codec/png_codec.cc @@ -611,7 +611,7 @@ typedef void (*FormatConverter)(const unsigned char* in, int w, bool DoLibpngWrite(png_struct* png_ptr, png_info* info_ptr, PngEncoderState* state, int width, int height, int row_byte_width, - const unsigned char* input, + const unsigned char* input, int compression_level, int png_output_color_type, int output_color_components, FormatConverter converter, const std::vector<PNGCodec::Comment>& comments) { @@ -621,6 +621,8 @@ bool DoLibpngWrite(png_struct* png_ptr, png_info* info_ptr, if (setjmp(png_jmpbuf(png_ptr))) return false; + png_set_compression_level(png_ptr, compression_level); + // Set our callback for libpng to give us the data. png_set_write_fn(png_ptr, state, EncoderWriteCallback, FakeFlushCallback); @@ -666,6 +668,21 @@ bool PNGCodec::Encode(const unsigned char* input, ColorFormat format, bool discard_transparency, const std::vector<Comment>& comments, std::vector<unsigned char>* output) { + return PNGCodec::EncodeWithCompressionLevel(input, format, size, + row_byte_width, + discard_transparency, + comments, Z_DEFAULT_COMPRESSION, + output); +} + +// static +bool PNGCodec::EncodeWithCompressionLevel(const unsigned char* input, + ColorFormat format, const Size& size, + int row_byte_width, + bool discard_transparency, + const std::vector<Comment>& comments, + int compression_level, + std::vector<unsigned char>* output) { // Run to convert an input row into the output row format, NULL means no // conversion is necessary. FormatConverter converter = NULL; @@ -740,7 +757,7 @@ bool PNGCodec::Encode(const unsigned char* input, ColorFormat format, PngEncoderState state(output); bool success = DoLibpngWrite(png_ptr, info_ptr, &state, size.width(), size.height(), row_byte_width, - input, png_output_color_type, + input, compression_level, png_output_color_type, output_color_components, converter, comments); png_destroy_write_struct(&png_ptr, &info_ptr); diff --git a/ui/gfx/codec/png_codec.h b/ui/gfx/codec/png_codec.h index eac411d..4632ac1 100644 --- a/ui/gfx/codec/png_codec.h +++ b/ui/gfx/codec/png_codec.h @@ -51,6 +51,16 @@ class PNGCodec { std::string text; }; + // Calls PNGCodec::EncodeWithCompressionLevel with the default compression + // level. + 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); + // 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 @@ -68,13 +78,16 @@ class PNGCodec { // written to the resulting file. Otherwise, alpha values in the input // will be preserved. // 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); + // compression_level: An integer between -1 and 9, corresponding to zlib's + // compression levels. -1 is the default. + static bool EncodeWithCompressionLevel(const unsigned char* input, + ColorFormat format, + const Size& size, + int row_byte_width, + bool discard_transparency, + const std::vector<Comment>& comments, + int compression_level, + std::vector<unsigned char>* output); // Call PNGCodec::Encode on the supplied SkBitmap |input|, which is assumed // to be BGRA, 32 bits per pixel. The params |discard_transparency| and diff --git a/ui/gfx/codec/png_codec_unittest.cc b/ui/gfx/codec/png_codec_unittest.cc index b31dbd2..16ca34a 100644 --- a/ui/gfx/codec/png_codec_unittest.cc +++ b/ui/gfx/codec/png_codec_unittest.cc @@ -8,6 +8,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkUnPreMultiply.h" +#include "third_party/zlib/zlib.h" #include "ui/gfx/codec/png_codec.h" #include "ui/gfx/size.h" @@ -339,4 +340,49 @@ TEST(PNGCodec, EncodeWithComment) { encoded.end()); } +TEST(PNGCodec, EncodeDecodeWithVaryingCompressionLevels) { + const int w = 20, h = 20; + + // create an image with known values, a must be opaque because it will be + // lost during encoding + std::vector<unsigned char> original; + MakeRGBAImage(w, h, true, &original); + + // encode + std::vector<unsigned char> encoded_fast; + EXPECT_TRUE(PNGCodec::EncodeWithCompressionLevel( + &original[0], PNGCodec::FORMAT_RGBA, Size(w, h), w * 4, false, + std::vector<PNGCodec::Comment>(), Z_BEST_SPEED, &encoded_fast)); + + std::vector<unsigned char> encoded_best; + EXPECT_TRUE(PNGCodec::EncodeWithCompressionLevel( + &original[0], PNGCodec::FORMAT_RGBA, Size(w, h), w * 4, false, + std::vector<PNGCodec::Comment>(), Z_BEST_COMPRESSION, &encoded_best)); + + // Make sure the different compression settings actually do something; the + // sizes should be different. + EXPECT_NE(encoded_fast.size(), encoded_best.size()); + + // decode, it should have the same size as the original + std::vector<unsigned char> decoded; + int outw, outh; + EXPECT_TRUE(PNGCodec::Decode(&encoded_fast[0], encoded_fast.size(), + PNGCodec::FORMAT_RGBA, &decoded, + &outw, &outh)); + ASSERT_EQ(w, outw); + ASSERT_EQ(h, outh); + ASSERT_EQ(original.size(), decoded.size()); + + EXPECT_TRUE(PNGCodec::Decode(&encoded_best[0], encoded_best.size(), + PNGCodec::FORMAT_RGBA, &decoded, + &outw, &outh)); + ASSERT_EQ(w, outw); + ASSERT_EQ(h, outh); + ASSERT_EQ(original.size(), decoded.size()); + + // Images must be exactly equal + ASSERT_TRUE(original == decoded); +} + + } // namespace gfx |