Index: Source/platform/image-encoders/skia/WEBPImageEncoder.cpp |
diff --git a/Source/platform/image-encoders/skia/WEBPImageEncoder.cpp b/Source/platform/image-encoders/skia/WEBPImageEncoder.cpp |
index 0193b5df713d162259ffcdf8dbbab14181379c45..a680d25bb6e33adec9f2d685efda3aff48b16ce9 100644 |
--- a/Source/platform/image-encoders/skia/WEBPImageEncoder.cpp |
+++ b/Source/platform/image-encoders/skia/WEBPImageEncoder.cpp |
@@ -35,43 +35,19 @@ |
#include "platform/graphics/ImageBuffer.h" |
#include "webp/encode.h" |
-typedef int (*WebPImporter)(WebPPicture* const, const uint8_t* const data, int rowStride); |
- |
namespace blink { |
static int writeOutput(const uint8_t* data, size_t size, const WebPPicture* const picture) |
{ |
- static_cast<Vector<unsigned char>*>(picture->custom_ptr)->append(data, size); |
- return 1; |
+ return static_cast<Vector<unsigned char>*>(picture->custom_ptr)->append(data, size), 1; |
} |
-static bool rgbPictureImport(const unsigned char* pixels, WebPImporter importRGB, WebPPicture* picture) |
+inline bool importUnpremultipliedRGBA(const unsigned char* pixels, WebPPicture* picture) |
{ |
- // Write the RGB pixels to an rgb data buffer, alpha premultiplied, then import the rgb data. |
- |
- size_t pixelCount = picture->height * picture->width; |
- |
- OwnPtr<unsigned char[]> rgb = adoptArrayPtr(new unsigned char[pixelCount * 3]); |
- if (!rgb.get()) |
- return false; |
- |
- for (unsigned char* data = rgb.get(); pixelCount-- > 0; pixels += 4) { |
- unsigned char alpha = pixels[3]; |
- if (alpha != 255) { |
- *data++ = SkMulDiv255Round(pixels[0], alpha); |
- *data++ = SkMulDiv255Round(pixels[1], alpha); |
- *data++ = SkMulDiv255Round(pixels[2], alpha); |
- } else { |
- *data++ = pixels[0]; |
- *data++ = pixels[1]; |
- *data++ = pixels[2]; |
- } |
- } |
- |
- return importRGB(picture, rgb.get(), picture->width * 3); |
+ return WebPPictureImportRGBA(picture, pixels, picture->width * 4); |
} |
-static bool encodePixels(IntSize imageSize, const unsigned char* pixels, int quality, Vector<unsigned char>* output) |
+static bool encodePixels(IntSize imageSize, const unsigned char* pixels, int quality, Vector<unsigned char>* output, WEBPImageEncoder::Mode mode) |
{ |
if (imageSize.width() <= 0 || imageSize.width() > WEBP_MAX_DIMENSION) |
return false; |
@@ -88,25 +64,38 @@ static bool encodePixels(IntSize imageSize, const unsigned char* pixels, int qua |
picture.width = imageSize.width(); |
picture.height = imageSize.height(); |
- if (!rgbPictureImport(pixels, &WebPPictureImportRGB, &picture)) |
+ if (quality > 99 || mode == WEBPImageEncoder::Lossless) |
+ config.lossless = picture.use_argb = 1; |
+ |
+ if (!importUnpremultipliedRGBA(pixels, &picture)) |
return false; |
picture.custom_ptr = output; |
picture.writer = &writeOutput; |
- config.quality = quality; |
- config.method = 3; |
+ |
+ if (mode == WEBPImageEncoder::Lossless) { |
+ config.quality = quality; |
+ config.method = 2; |
+ } else if (quality > 99) { |
+ config.quality = 75; |
+ config.method = 0; |
+ } else { |
+ ASSERT(!config.lossless); |
+ config.quality = quality; |
+ config.method = 3; |
+ } |
bool success = WebPEncode(&config, &picture); |
WebPPictureFree(&picture); |
return success; |
} |
-bool WEBPImageEncoder::encode(const ImageDataBuffer& imageData, int quality, Vector<unsigned char>* output) |
+bool WEBPImageEncoder::encode(const ImageDataBuffer& imageData, int quality, Vector<unsigned char>* output, WEBPImageEncoder::Mode mode) |
{ |
if (!imageData.pixels()) |
return false; |
- return encodePixels(IntSize(imageData.width(), imageData.height()), imageData.pixels(), quality, output); |
+ return encodePixels(IntSize(imageData.width(), imageData.height()), imageData.pixels(), quality, output, mode); |
} |
} // namespace blink |