summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authordcheng@chromium.org <dcheng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-13 21:13:15 +0000
committerdcheng@chromium.org <dcheng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-13 21:13:15 +0000
commitc05a26cc654acceb8062a759adecedeceeeb89b3 (patch)
tree17b7d972e6cd416a8220dda0c029756c46763d2b /ui
parente04dc4124a2455bf8fe0588793ab0c40f60b912e (diff)
downloadchromium_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.cc21
-rw-r--r--ui/gfx/codec/png_codec.h27
-rw-r--r--ui/gfx/codec/png_codec_unittest.cc46
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