aboutsummaryrefslogtreecommitdiffstats
path: root/src/images
diff options
context:
space:
mode:
authorMike Reed <reed@google.com>2010-01-27 12:28:13 -0500
committerMike Reed <reed@google.com>2010-01-27 12:28:13 -0500
commite4c504a1b99d639525192d79b33fe9acc521682e (patch)
tree8018f1b79b892aed9d04a4f6a38c4a26609b1bf8 /src/images
parent07a66af19347d1f2d0d4610158a48a7cd34477fc (diff)
downloadexternal_skia-e4c504a1b99d639525192d79b33fe9acc521682e.zip
external_skia-e4c504a1b99d639525192d79b33fe9acc521682e.tar.gz
external_skia-e4c504a1b99d639525192d79b33fe9acc521682e.tar.bz2
If jpeg_start_decompress fails, but we have valid output dimensions and we're in
kDecodeBounds_Mode, go ahead and return the config to the caller instead of reporting an error.
Diffstat (limited to 'src/images')
-rw-r--r--src/images/SkImageDecoder_libjpeg.cpp50
1 files changed, 39 insertions, 11 deletions
diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp
index 2bb922a..12fe76a 100644
--- a/src/images/SkImageDecoder_libjpeg.cpp
+++ b/src/images/SkImageDecoder_libjpeg.cpp
@@ -260,6 +260,25 @@ static void sk_error_exit(j_common_ptr cinfo) {
///////////////////////////////////////////////////////////////////////////////
+/* If we need to better match the request, we might examine the image and
+ output dimensions, and determine if the downsampling jpeg provided is
+ not sufficient. If so, we can recompute a modified sampleSize value to
+ make up the difference.
+
+ To skip this additional scaling, just set sampleSize = 1; below.
+ */
+static int recompute_sampleSize(int sampleSize,
+ const jpeg_decompress_struct& cinfo) {
+ return sampleSize * cinfo.output_width / cinfo.image_width;
+}
+
+static bool valid_output_dimensions(const jpeg_decompress_struct& cinfo) {
+ /* These are initialized to 0, so if they have non-zero values, we assume
+ they are "valid" (i.e. have been computed by libjpeg)
+ */
+ return cinfo.output_width != 0 && cinfo.output_height != 0;
+}
+
static bool skip_src_rows(jpeg_decompress_struct* cinfo, void* buffer,
int count) {
for (int i = 0; i < count; i++) {
@@ -381,18 +400,27 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm,
jpeg_start_decompress(), and then read output_width and output_height.
*/
if (!jpeg_start_decompress(&cinfo)) {
- return return_false(cinfo, *bm, "start_decompress");
+ /* If we failed here, we may still have enough information to return
+ to the caller if they just wanted (subsampled bounds). If sampleSize
+ was 1, then we would have already returned. Thus we just check if
+ we're in kDecodeBounds_Mode, and that we have valid output sizes.
+
+ One reason to fail here is that we have insufficient stream data
+ to complete the setup. However, output dimensions seem to get
+ computed very early, which is why this special check can pay off.
+ */
+ if (SkImageDecoder::kDecodeBounds_Mode == mode &&
+ valid_output_dimensions(cinfo)) {
+ SkScaledBitmapSampler smpl(cinfo.output_width, cinfo.output_height,
+ recompute_sampleSize(sampleSize, cinfo));
+ bm->setConfig(config, smpl.scaledWidth(), smpl.scaledHeight());
+ bm->setIsOpaque(true);
+ return true;
+ } else {
+ return return_false(cinfo, *bm, "start_decompress");
+ }
}
-
- /* If we need to better match the request, we might examine the image and
- output dimensions, and determine if the downsampling jpeg provided is
- not sufficient. If so, we can recompute a modified sampleSize value to
- make up the difference.
-
- To skip this additional scaling, just set sampleSize = 1; below.
- */
- sampleSize = sampleSize * cinfo.output_width / cinfo.image_width;
-
+ sampleSize = recompute_sampleSize(sampleSize, cinfo);
// should we allow the Chooser (if present) to pick a config for us???
if (!this->chooseFromOneChoice(config, cinfo.output_width,