Index: Source/platform/image-encoders/skia/PNGImageEncoder.cpp |
diff --git a/Source/platform/image-encoders/skia/PNGImageEncoder.cpp b/Source/platform/image-encoders/skia/PNGImageEncoder.cpp |
index b5da17265c610f5d8c300eb19e4e6bcc10488cf8..a38c85c78a7f2f89da09ae6db5a2d2296061ca4d 100644 |
--- a/Source/platform/image-encoders/skia/PNGImageEncoder.cpp |
+++ b/Source/platform/image-encoders/skia/PNGImageEncoder.cpp |
@@ -68,7 +68,7 @@ static void preMultipliedBGRAtoRGBA(const void* pixels, int pixelCount, unsigned |
} |
} |
-static bool encodePixels(IntSize imageSize, unsigned char* inputPixels, bool premultiplied, Vector<unsigned char>* output) |
+static bool encodePixels(IntSize imageSize, unsigned char* inputPixels, bool premultiplied, int quality, Vector<unsigned char>* output) |
{ |
imageSize.clampNegativeToZero(); |
Vector<unsigned char> row; |
@@ -80,17 +80,35 @@ static bool encodePixels(IntSize imageSize, unsigned char* inputPixels, bool pre |
return false; |
} |
- // Optimize compression for speed. |
- // The parameters are the same as what libpng uses by default for RGB and RGBA images, except: |
- // - the zlib compression level is 3 instead of 6, to avoid the lazy Ziv-Lempel match searching; |
- // - the delta filter is 1 ("sub") instead of 5 ("all"), to reduce the filter computations. |
- // The zlib memory level (8) and strategy (Z_FILTERED) will be set inside libpng. |
- // |
- // Avoid the zlib strategies Z_HUFFMAN_ONLY or Z_RLE. |
- // Although they are the fastest for poorly-compressible images (e.g. photographs), |
- // they are very slow for highly-compressible images (e.g. text, drawings or business graphics). |
- png_set_compression_level(png, 3); |
- png_set_filter(png, PNG_FILTER_TYPE_BASE, PNG_FILTER_SUB); |
+ int compression = static_cast<int>(quality / 10.0 + 0.5); |
+ if (compression > Z_BEST_COMPRESSION) |
+ compression = Z_BEST_COMPRESSION; |
+ else if (compression < Z_BEST_SPEED) |
+ compression = Z_BEST_SPEED; |
+ |
+ if (quality <= 0) { |
+ png_set_compression_level(png, Z_BEST_SPEED); |
+ png_set_filter(png, PNG_FILTER_TYPE_BASE, PNG_FILTER_NONE); |
+ } else if (compression <= 3) { |
+ // Optimize compression for speed. |
+ // The parameters are the libpng defaults for RGB and RGBA images, except that: |
+ // - the zlib compression level is lower than the libpng default 6, |
+ // to avoid the lazy Ziv-Lempel match searching. |
+ // - the delta filter is 1 ("sub"), instead of 5 ("all"), to reduce |
+ // filter computations. |
+ // Note: the zlib memory level (8) and strategy (Z_FILTERED) will be set inside |
+ // libpng. |
+ // Note: avoid the zlib strategies Z_HUFFMAN_ONLY or Z_RLE. Although they are the |
+ // fastest for poorly-compressible images (e.g. photographs) they are very slow |
+ // for highly-compressible images (e.g. text, drawings, and business graphics). |
+ png_set_compression_level(png, compression); |
+ png_set_filter(png, PNG_FILTER_TYPE_BASE, PNG_FILTER_SUB); |
+ } else if (compression <= 7) { |
+ png_set_compression_level(png, compression); |
+ png_set_filter(png, PNG_FILTER_TYPE_BASE, PNG_FILTER_PAETH); |
+ } else { |
+ png_set_compression_level(png, compression); |
+ } |
png_set_write_fn(png, output, writeOutput, 0); |
png_set_IHDR(png, info, imageSize.width(), imageSize.height(), |
@@ -114,19 +132,19 @@ static bool encodePixels(IntSize imageSize, unsigned char* inputPixels, bool pre |
return true; |
} |
-bool PNGImageEncoder::encode(const SkBitmap& bitmap, Vector<unsigned char>* output) |
+bool PNGImageEncoder::encode(const SkBitmap& bitmap, int quality, Vector<unsigned char>* output) |
{ |
SkAutoLockPixels bitmapLock(bitmap); |
if (bitmap.colorType() != kPMColor_SkColorType || !bitmap.getPixels()) |
return false; // Only support 32 bit/pixel skia bitmaps. |
- return encodePixels(IntSize(bitmap.width(), bitmap.height()), static_cast<unsigned char*>(bitmap.getPixels()), true, output); |
+ return encodePixels(IntSize(bitmap.width(), bitmap.height()), static_cast<unsigned char*>(bitmap.getPixels()), true, quality, output); |
} |
-bool PNGImageEncoder::encode(const ImageDataBuffer& imageData, Vector<unsigned char>* output) |
+bool PNGImageEncoder::encode(const ImageDataBuffer& imageData, int quality, Vector<unsigned char>* output) |
{ |
- return encodePixels(imageData.size(), imageData.data(), false, output); |
+ return encodePixels(imageData.size(), imageData.data(), false, quality, output); |
} |
} // namespace WebCore |