Fix bug in SkImageDecoder
Change-Id: I6d214e4d8cce49f7e12eeb924493161dadd5aa26
diff --git a/include/core/SkStream.h b/include/core/SkStream.h
index 3a82991..798c6be 100644
--- a/include/core/SkStream.h
+++ b/include/core/SkStream.h
@@ -176,6 +176,7 @@
*/
virtual void setMemory(const void* data, size_t length,
bool copyData = false);
+ virtual void setMemoryOwned(const void* src, size_t size);
void skipToAlign4();
virtual bool rewind();
virtual size_t read(void* buffer, size_t size);
diff --git a/include/images/SkImageDecoder.h b/include/images/SkImageDecoder.h
index a3d7f1d..767a09a 100644
--- a/include/images/SkImageDecoder.h
+++ b/include/images/SkImageDecoder.h
@@ -204,9 +204,7 @@
* Return true for success or false on failure.
*/
virtual bool buildTileIndex(SkStream*,
- int *width, int *height, bool isShareable) {
- return false;
- }
+ int *width, int *height);
/**
* Decode a rectangle region in the image specified by rect.
@@ -307,7 +305,15 @@
// must be overridden in subclasses. This guy is called by decode(...)
virtual bool onDecode(SkStream*, SkBitmap* bitmap, Mode) = 0;
- // must be overridden in subclasses. This guy is called by decodeRegion(...)
+ // If the decoder wants to support tiled based decoding,
+ // this method must be overridden. This guy is called by buildTileIndex(...)
+ virtual bool onBuildTileIndex(SkStream*,
+ int *width, int *height) {
+ return false;
+ }
+
+ // If the decoder wants to support tiled based decoding,
+ // this method must be overridden. This guy is called by decodeRegion(...)
virtual bool onDecodeRegion(SkBitmap* bitmap, SkIRect rect) {
return false;
}
diff --git a/include/images/SkJpegUtility.h b/include/images/SkJpegUtility.h
index 5dd789c9..e9dd977 100644
--- a/include/images/SkJpegUtility.h
+++ b/include/images/SkJpegUtility.h
@@ -41,7 +41,7 @@
/* Our source struct for directing jpeg to our stream object.
*/
struct skjpeg_source_mgr : jpeg_source_mgr {
- skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder, bool copyStream, bool ownStream);
+ skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder, bool ownStream);
~skjpeg_source_mgr();
SkStream* fStream;
diff --git a/src/core/SkStream.cpp b/src/core/SkStream.cpp
index 6187f81..6157105 100644
--- a/src/core/SkStream.cpp
+++ b/src/core/SkStream.cpp
@@ -265,6 +265,18 @@
sk_free((void*)fSrc);
}
+void SkMemoryStream::setMemoryOwned(const void* src, size_t size)
+{
+ if (fWeOwnTheData)
+ sk_free((void*)fSrc);
+
+ fSize = size;
+ fOffset = 0;
+ fWeOwnTheData = true;
+
+ fSrc = src;
+}
+
void SkMemoryStream::setMemory(const void* src, size_t size, bool copyData)
{
if (fWeOwnTheData)
diff --git a/src/images/SkImageDecoder.cpp b/src/images/SkImageDecoder.cpp
index 8c57886..053caea 100644
--- a/src/images/SkImageDecoder.cpp
+++ b/src/images/SkImageDecoder.cpp
@@ -188,6 +188,14 @@
return true;
}
+bool SkImageDecoder::buildTileIndex(SkStream* stream,
+ int *width, int *height) {
+ // we reset this to false before calling onBuildTileIndex
+ fShouldCancelDecode = false;
+
+ return this->onBuildTileIndex(stream, width, height);
+}
+
///////////////////////////////////////////////////////////////////////////////
bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm,
diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp
index 29c4b46..0565a3b 100644
--- a/src/images/SkImageDecoder_libjpeg.cpp
+++ b/src/images/SkImageDecoder_libjpeg.cpp
@@ -77,10 +77,10 @@
virtual Format getFormat() const {
return kJPEG_Format;
}
- virtual bool buildTileIndex(SkStream *stream,
- int *width, int *height, bool isShareable);
protected:
+ virtual bool onBuildTileIndex(SkStream *stream,
+ int *width, int *height);
virtual bool onDecodeRegion(SkBitmap* bitmap, SkIRect rect);
virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode);
virtual void cropBitmap(SkBitmap *dest, SkBitmap *src, int sampleSize,
@@ -208,7 +208,7 @@
jpeg_decompress_struct cinfo;
skjpeg_error_mgr sk_err;
- skjpeg_source_mgr sk_stream(stream, this, false, false);
+ skjpeg_source_mgr sk_stream(stream, this, false);
cinfo.err = jpeg_std_error(&sk_err);
sk_err.error_exit = skjpeg_error_exit;
@@ -433,9 +433,8 @@
return true;
}
-bool SkJPEGImageDecoder::buildTileIndex(SkStream* stream,
- int *width, int *height,
- bool isShareable) {
+bool SkJPEGImageDecoder::onBuildTileIndex(SkStream* stream,
+ int *width, int *height) {
SkAutoMalloc srcStorage;
SkJPEGImageIndex *index = new SkJPEGImageIndex;
@@ -443,7 +442,7 @@
malloc(sizeof(jpeg_decompress_struct));
skjpeg_error_mgr sk_err;
skjpeg_source_mgr *sk_stream =
- new skjpeg_source_mgr(stream, this, !isShareable, true);
+ new skjpeg_source_mgr(stream, this, true);
if (cinfo == NULL || sk_stream == NULL) {
return false;
}
diff --git a/src/images/SkJpegUtility.cpp b/src/images/SkJpegUtility.cpp
index ac65b9e..a2fe9a8 100644
--- a/src/images/SkJpegUtility.cpp
+++ b/src/images/SkJpegUtility.cpp
@@ -131,43 +131,21 @@
///////////////////////////////////////////////////////////////////////////////
skjpeg_source_mgr::skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder,
- bool copyStream, bool ownStream) : fStream(stream) {
+ bool ownStream) : fStream(stream) {
fDecoder = decoder;
const void* baseAddr = stream->getMemoryBase();
size_t bufferSize = 4096;
size_t len;
fMemoryBase = NULL;
fUnrefStream = ownStream;
- if (copyStream) {
- fMemoryBaseSize = 0;
- fMemoryBase = sk_malloc_throw(bufferSize);
- while ((len = stream->read((char*)fMemoryBase + fMemoryBaseSize,
- bufferSize - fMemoryBaseSize)) != 0) {
- fMemoryBaseSize += len;
- if (fMemoryBaseSize == bufferSize) {
- bufferSize *= 2;
- fMemoryBase = sk_realloc_throw(fMemoryBase, bufferSize);
- }
- }
- fMemoryBase = sk_realloc_throw(fMemoryBase, fMemoryBaseSize);
+ fMemoryBaseSize = 0;
- init_source = skmem_init_source;
- fill_input_buffer = skmem_fill_input_buffer;
- skip_input_data = skmem_skip_input_data;
- resync_to_restart = skmem_resync_to_restart;
- term_source = skmem_term_source;
- seek_input_data = NULL;
- } else {
- fMemoryBase = NULL;
- fMemoryBaseSize = 0;
-
- init_source = sk_init_source;
- fill_input_buffer = sk_fill_input_buffer;
- skip_input_data = sk_skip_input_data;
- resync_to_restart = sk_resync_to_restart;
- term_source = sk_term_source;
- seek_input_data = sk_seek_input_data;
- }
+ init_source = sk_init_source;
+ fill_input_buffer = sk_fill_input_buffer;
+ skip_input_data = sk_skip_input_data;
+ resync_to_restart = sk_resync_to_restart;
+ term_source = sk_term_source;
+ seek_input_data = sk_seek_input_data;
// SkDebugf("**************** use memorybase %p %d\n", fMemoryBase, fMemoryBaseSize);
}