Implement on-the-fly image resizing (down-scaling).
Implement on-the-fly image resizing (down-scaling) for WebP images.
The image decoder is aware of the device memory constriant via
SampleSize set by the application like Webkit/WebCore.
sampleSize=1 implies no down-scaling. Likewise, SampleSize=2 implies
resizing image width & height by a factor of '1/2', resulting in '1/4'th
size for the decoded image.
SampleSize is merely a hint from the application to the decoder. Decoder
may choose to ignore this hint and decode the image at full scale.
Native WebP image decoder (new APIs) supports on-the-fly resizing.
Making the Skia-WebP decoder 'SampleSize' aware and implementing the
on-the-fly resizing in this change.
Change-Id: Ibbd62baf4a6ad2d3904aafb22807f4513641e64c
diff --git a/src/images/SkImageDecoder_libwebp.cpp b/src/images/SkImageDecoder_libwebp.cpp
index 51f8a46..7b4a39f 100644
--- a/src/images/SkImageDecoder_libwebp.cpp
+++ b/src/images/SkImageDecoder_libwebp.cpp
@@ -17,7 +17,6 @@
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkColorPriv.h"
-#include "SkDither.h"
#include "SkScaledBitmapSampler.h"
#include "SkStream.h"
#include "SkTemplates.h"
@@ -133,7 +132,8 @@
// Incremental WebP image decoding. Reads input buffer of 64K size iteratively
// and decodes this block to appropriate color-space as per config object.
-static bool webp_idecode(SkStream* stream, SkBitmap* decodedBitmap) {
+static bool webp_idecode(SkStream* stream, SkBitmap* decodedBitmap,
+ int origWidth, int origHeight) {
SkAutoLockPixels alp(*decodedBitmap);
stream->rewind();
@@ -161,6 +161,12 @@
decode_config.output.u.RGBA.stride = decodedBitmap->rowBytes();
decode_config.output.u.RGBA.size = decodedBitmap->getSize();
decode_config.output.is_external_memory = 1;
+ if (origWidth != decodedBitmap->width() ||
+ origHeight != decodedBitmap->height()) {
+ decode_config.options.use_scaling = 1;
+ decode_config.options.scaled_width = decodedBitmap->width();
+ decode_config.options.scaled_height = decodedBitmap->height();
+ }
WebPIDecoder* idec = WebPIDecode(NULL, NULL, &decode_config);
if (idec == NULL) {
@@ -210,7 +216,7 @@
}
bool SkWEBPImageDecoder::setDecodeConfig(SkBitmap* decodedBitmap,
- int origWidth, int origHeight) {
+ int width, int height) {
bool hasAlpha = false;
SkBitmap::Config config = this->getPrefConfig(k32Bit_SrcDepth, hasAlpha);
@@ -227,11 +233,11 @@
}
}
- if (!this->chooseFromOneChoice(config, origWidth, origHeight)) {
+ if (!this->chooseFromOneChoice(config, width, height)) {
return false;
}
- decodedBitmap->setConfig(config, origWidth, origHeight, 0);
+ decodedBitmap->setConfig(config, width, height, 0);
// Current WEBP specification has no support for alpha layer.
decodedBitmap->setIsOpaque(true);
@@ -239,7 +245,6 @@
return true;
}
-
bool SkWEBPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap,
Mode mode) {
#ifdef TIME_DECODE
@@ -251,7 +256,11 @@
return false;
}
- if (!setDecodeConfig(decodedBitmap, origWidth, origHeight)) {
+ const int sampleSize = this->getSampleSize();
+ SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize);
+
+ if (!setDecodeConfig(decodedBitmap, sampler.scaledWidth(),
+ sampler.scaledHeight())) {
return false;
}
@@ -265,7 +274,7 @@
}
// Decode the WebP image data stream using WebP incremental decoding.
- if (!webp_idecode(stream, decodedBitmap)) {
+ if (!webp_idecode(stream, decodedBitmap, origWidth, origHeight)) {
return false;
}