Fixes for JPEG subset decoding.

Ensure that the stream passed to JPEG for subset decoding is
neither deleted before it is no longer needed nor deleted an
extra time.

src/images/SkJpegUtility.h:
src/images/SkJpegUtility.cpp:
Always ref and unref the stream provided to skjpeg_source_mgr.
Add some comments explaining how skjpeg_source_mgr's members
handle ownership.
Fix a warning comparing signed and unsigned numbers, converting
to size_t which is more appropriate for measuring bytes.
Remove dead code referring to fMemoryBase and fMemoryBaseSize,
which are never used.

src/images/SkImageDecoder_libjpeg.cpp:
Call the new constructor for skjpeg_source_mgr, which no longer
takes a boolean to determine ownership.

include/images/SkBitmapRegionDecoder.h
src/images/SkBitmapRegionDecoder.cpp:
This small shim has been removed, since it is not needed to use
Skia's image decoders. Its functionality will be folded into
Android.

Required for the merge to Android.

R=djsollen@google.com

Review URL: https://codereview.chromium.org/21561002

git-svn-id: http://skia.googlecode.com/svn/trunk@10483 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
scroggo@google.com 2013-08-01 15:03:42 +00:00
parent 350b4d50ea
commit d4c3565aac
6 changed files with 16 additions and 93 deletions

View File

@ -34,8 +34,6 @@
'../src/images/bmpdecoderhelper.cpp',
'../src/images/bmpdecoderhelper.h',
'../src/images/SkBitmapRegionDecoder.cpp',
'../src/images/SkForceLinking.cpp',
'../src/images/SkImageDecoder.cpp',
'../src/images/SkImageDecoder_FactoryDefault.cpp',

View File

@ -1,54 +0,0 @@
/*
* Copyright 2011 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkBitmapRegionDecoder_DEFINED
#define SkBitmapRegionDecoder_DEFINED
#include "SkBitmap.h"
#include "SkImageDecoder.h"
#include "SkStream.h"
struct SkIRect;
/**
* SkBitmapRegionDecoder can be used to decode a specified rect from an image.
* This is particularly useful when the original image is large and you only
* need parts of the image.
*
* However, not all image codecs on all platforms support this feature so be
* prepared to fallback to standard decoding if decodeRegion(...) returns false.
*/
class SkBitmapRegionDecoder {
public:
SkBitmapRegionDecoder(SkImageDecoder* decoder, SkStream* stream,
int width, int height) {
fDecoder = decoder;
fStream = stream;
fWidth = width;
fHeight = height;
}
~SkBitmapRegionDecoder() {
SkDELETE(fDecoder);
SkSafeUnref(fStream);
}
bool decodeRegion(SkBitmap* bitmap, const SkIRect& rect,
SkBitmap::Config pref, int sampleSize);
SkImageDecoder* getDecoder() const { return fDecoder; }
int getWidth() const { return fWidth; }
int getHeight() const { return fHeight; }
private:
SkImageDecoder* fDecoder;
SkStream* fStream;
int fWidth;
int fHeight;
};
#endif

View File

@ -1,14 +0,0 @@
/*
* Copyright 2011 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkBitmapRegionDecoder.h"
bool SkBitmapRegionDecoder::decodeRegion(SkBitmap* bitmap, const SkIRect& rect,
SkBitmap::Config pref, int sampleSize) {
fDecoder->setSampleSize(sampleSize);
return fDecoder->decodeRegion(bitmap, rect, pref);
}

View File

@ -65,7 +65,7 @@ static void overwrite_mem_buffer_size(j_decompress_ptr cinfo) {
class SkJPEGImageIndex {
public:
SkJPEGImageIndex(SkStream* stream, SkImageDecoder* decoder)
: fSrcMgr(stream, decoder, true) {}
: fSrcMgr(stream, decoder) {}
~SkJPEGImageIndex() {
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
@ -238,7 +238,7 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
jpeg_decompress_struct cinfo;
skjpeg_error_mgr errorManager;
skjpeg_source_mgr srcManager(stream, this, false);
skjpeg_source_mgr srcManager(stream, this);
cinfo.err = jpeg_std_error(&errorManager);
errorManager.error_exit = skjpeg_error_exit;

View File

@ -29,15 +29,16 @@ static void sk_init_source(j_decompress_ptr cinfo) {
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
static boolean sk_seek_input_data(j_decompress_ptr cinfo, long byte_offset) {
skjpeg_source_mgr* src = (skjpeg_source_mgr*)cinfo->src;
size_t bo = (size_t) byte_offset;
if (byte_offset > src->current_offset) {
(void)src->fStream->skip(byte_offset - src->current_offset);
if (bo > src->current_offset) {
(void)src->fStream->skip(bo - src->current_offset);
} else {
src->fStream->rewind();
(void)src->fStream->skip(byte_offset);
(void)src->fStream->skip(bo);
}
src->current_offset = byte_offset;
src->current_offset = bo;
src->next_input_byte = (const JOCTET*)src->fBuffer;
src->bytes_in_buffer = 0;
return true;
@ -109,12 +110,9 @@ static void sk_term_source(j_decompress_ptr /*cinfo*/) {}
///////////////////////////////////////////////////////////////////////////////
skjpeg_source_mgr::skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder,
bool ownStream) : fStream(stream) {
fDecoder = decoder;
fMemoryBase = NULL;
fUnrefStream = ownStream;
fMemoryBaseSize = 0;
skjpeg_source_mgr::skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder)
: fStream(SkRef(stream))
, fDecoder(decoder) {
init_source = sk_init_source;
fill_input_buffer = sk_fill_input_buffer;
@ -128,12 +126,7 @@ skjpeg_source_mgr::skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder,
}
skjpeg_source_mgr::~skjpeg_source_mgr() {
if (fMemoryBase) {
sk_free(fMemoryBase);
}
if (fUnrefStream) {
fStream->unref();
}
SkSafeUnref(fStream);
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -34,13 +34,13 @@ void skjpeg_error_exit(j_common_ptr cinfo);
/* 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 ownStream);
skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder);
~skjpeg_source_mgr();
// fStream is ref'ed and unref'ed
SkStream* fStream;
void* fMemoryBase;
size_t fMemoryBaseSize;
bool fUnrefStream;
// Unowned pointer to the decoder, used to check if the decoding process
// has been cancelled.
SkImageDecoder* fDecoder;
enum {
kBufferSize = 1024