Remove bitmap reuse from SkImageDecoder.
Now that Android is using an SkBitmap::Allocator to reuse bitmap memory, remove the unnecessary code to handle bitmap reuse inside the decoders themselves. Leaves in the code for bitmap reuse in decodeSubset, which still may reuse bitmaps, and cropBitmap, which is called by decodeSubset. R=djsollen@google.com Review URL: https://codereview.chromium.org/17620004 git-svn-id: http://skia.googlecode.com/svn/trunk@9931 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
4b60dbe661
commit
bc69ce982f
@ -117,10 +117,10 @@ public:
|
|||||||
Peeker* getPeeker() const { return fPeeker; }
|
Peeker* getPeeker() const { return fPeeker; }
|
||||||
Peeker* setPeeker(Peeker*);
|
Peeker* setPeeker(Peeker*);
|
||||||
|
|
||||||
/** \class Peeker
|
/** \class Chooser
|
||||||
|
|
||||||
Base class for optional callbacks to retrieve meta/chunk data out of
|
Base class for optional callbacks to choose an image from a format that
|
||||||
an image as it is being decoded.
|
contains multiple images.
|
||||||
*/
|
*/
|
||||||
class Chooser : public SkRefCnt {
|
class Chooser : public SkRefCnt {
|
||||||
public:
|
public:
|
||||||
@ -219,11 +219,20 @@ public:
|
|||||||
* to pref if possible. Whether a conversion is feasible is
|
* to pref if possible. Whether a conversion is feasible is
|
||||||
* tested by Bitmap::canCopyTo(pref).
|
* tested by Bitmap::canCopyTo(pref).
|
||||||
|
|
||||||
note: document use of Allocator, Peeker and Chooser
|
If an SkBitmap::Allocator is installed via setAllocator, it will be
|
||||||
|
used to allocate the pixel memory. A clever allocator can be used
|
||||||
|
to allocate the memory from a cache, volatile memory, or even from
|
||||||
|
an existing bitmap's memory.
|
||||||
|
|
||||||
|
If a Peeker is installed via setPeeker, it may be used to peek into
|
||||||
|
meta data during the decode.
|
||||||
|
|
||||||
|
If a Chooser is installed via setChooser, it may be used to select
|
||||||
|
which image to return from a format that contains multiple images.
|
||||||
*/
|
*/
|
||||||
bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode, bool reuseBitmap = false);
|
bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode);
|
||||||
bool decode(SkStream* stream, SkBitmap* bitmap, Mode mode, bool reuseBitmap = false) {
|
bool decode(SkStream* stream, SkBitmap* bitmap, Mode mode) {
|
||||||
return this->decode(stream, bitmap, SkBitmap::kNo_Config, mode, reuseBitmap);
|
return this->decode(stream, bitmap, SkBitmap::kNo_Config, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -164,19 +164,12 @@ SkBitmap::Config SkImageDecoder::getPrefConfig(SrcDepth srcDepth,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm,
|
bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm,
|
||||||
SkBitmap::Config pref, Mode mode, bool reuseBitmap) {
|
SkBitmap::Config pref, Mode mode) {
|
||||||
// we reset this to false before calling onDecode
|
// we reset this to false before calling onDecode
|
||||||
fShouldCancelDecode = false;
|
fShouldCancelDecode = false;
|
||||||
// assign this, for use by getPrefConfig(), in case fUsePrefTable is false
|
// assign this, for use by getPrefConfig(), in case fUsePrefTable is false
|
||||||
fDefaultPref = pref;
|
fDefaultPref = pref;
|
||||||
|
|
||||||
if (reuseBitmap) {
|
|
||||||
SkAutoLockPixels alp(*bm);
|
|
||||||
if (NULL != bm->getPixels()) {
|
|
||||||
return this->onDecode(stream, bm, mode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// pass a temporary bitmap, so that if we return false, we are assured of
|
// pass a temporary bitmap, so that if we return false, we are assured of
|
||||||
// leaving the caller's bitmap untouched.
|
// leaving the caller's bitmap untouched.
|
||||||
SkBitmap tmp;
|
SkBitmap tmp;
|
||||||
|
@ -130,19 +130,13 @@ bool SkBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
|
|||||||
|
|
||||||
SkScaledBitmapSampler sampler(width, height, getSampleSize());
|
SkScaledBitmapSampler sampler(width, height, getSampleSize());
|
||||||
|
|
||||||
if (justBounds) {
|
|
||||||
bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight());
|
|
||||||
bm->setIsOpaque(true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// No Bitmap reuse supported for this format
|
|
||||||
if (!bm->isNull()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight());
|
bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight());
|
||||||
bm->setIsOpaque(true);
|
bm->setIsOpaque(true);
|
||||||
|
|
||||||
|
if (justBounds) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this->allocPixelRef(bm, NULL)) {
|
if (!this->allocPixelRef(bm, NULL)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -202,17 +202,11 @@ bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) {
|
|||||||
return error_return(gif, *bm, "chooseFromOneChoice");
|
return error_return(gif, *bm, "chooseFromOneChoice");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bm->setConfig(SkBitmap::kIndex8_Config, width, height);
|
||||||
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
|
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
|
||||||
bm->setConfig(SkBitmap::kIndex8_Config, width, height);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No Bitmap reuse supported for this format
|
|
||||||
if (!bm->isNull()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bm->setConfig(SkBitmap::kIndex8_Config, width, height);
|
|
||||||
SavedImage* image = &gif->SavedImages[gif->ImageCount-1];
|
SavedImage* image = &gif->SavedImages[gif->ImageCount-1];
|
||||||
const GifImageDesc& desc = image->ImageDesc;
|
const GifImageDesc& desc = image->ImageDesc;
|
||||||
|
|
||||||
|
@ -232,16 +232,12 @@ bool SkICOImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode)
|
|||||||
//if the andbitmap (mask) is all zeroes, then we can easily do an index bitmap
|
//if the andbitmap (mask) is all zeroes, then we can easily do an index bitmap
|
||||||
//however, with small images with large colortables, maybe it's better to still do argb_8888
|
//however, with small images with large colortables, maybe it's better to still do argb_8888
|
||||||
|
|
||||||
|
bm->setConfig(SkBitmap::kARGB_8888_Config, w, h, calculateRowBytesFor8888(w, bitCount));
|
||||||
|
|
||||||
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
|
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
|
||||||
bm->setConfig(SkBitmap::kARGB_8888_Config, w, h, calculateRowBytesFor8888(w, bitCount));
|
|
||||||
delete[] colors;
|
delete[] colors;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// No Bitmap reuse supported for this format
|
|
||||||
if (!bm->isNull()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bm->setConfig(SkBitmap::kARGB_8888_Config, w, h, calculateRowBytesFor8888(w, bitCount));
|
|
||||||
|
|
||||||
if (!this->allocPixelRef(bm, NULL))
|
if (!this->allocPixelRef(bm, NULL))
|
||||||
{
|
{
|
||||||
|
@ -357,29 +357,13 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampleSize);
|
SkScaledBitmapSampler sampler(cinfo.output_width, cinfo.output_height, sampleSize);
|
||||||
|
bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight());
|
||||||
bm->lockPixels();
|
bm->setIsOpaque(true);
|
||||||
JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels();
|
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
|
||||||
bm->unlockPixels();
|
return true;
|
||||||
bool reuseBitmap = (rowptr != NULL);
|
}
|
||||||
|
if (!this->allocPixelRef(bm, NULL)) {
|
||||||
if (reuseBitmap) {
|
return return_false(cinfo, *bm, "allocPixelRef");
|
||||||
if (sampler.scaledWidth() != bm->width() ||
|
|
||||||
sampler.scaledHeight() != bm->height()) {
|
|
||||||
// Dimensions must match
|
|
||||||
return false;
|
|
||||||
} else if (SkImageDecoder::kDecodeBounds_Mode == mode) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bm->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight());
|
|
||||||
bm->setIsOpaque(true);
|
|
||||||
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!this->allocPixelRef(bm, NULL)) {
|
|
||||||
return return_false(cinfo, *bm, "allocPixelRef");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SkAutoLockPixels alp(*bm);
|
SkAutoLockPixels alp(*bm);
|
||||||
@ -394,7 +378,7 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
|
|||||||
(config == SkBitmap::kRGB_565_Config &&
|
(config == SkBitmap::kRGB_565_Config &&
|
||||||
cinfo.out_color_space == JCS_RGB_565)))
|
cinfo.out_color_space == JCS_RGB_565)))
|
||||||
{
|
{
|
||||||
rowptr = (JSAMPLE*)bm->getPixels();
|
JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels();
|
||||||
INT32 const bpr = bm->rowBytes();
|
INT32 const bpr = bm->rowBytes();
|
||||||
|
|
||||||
while (cinfo.output_scanline < cinfo.output_height) {
|
while (cinfo.output_scanline < cinfo.output_height) {
|
||||||
@ -409,9 +393,6 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
|
|||||||
}
|
}
|
||||||
rowptr += bpr;
|
rowptr += bpr;
|
||||||
}
|
}
|
||||||
if (reuseBitmap) {
|
|
||||||
bm->notifyPixelsChanged();
|
|
||||||
}
|
|
||||||
jpeg_finish_decompress(&cinfo);
|
jpeg_finish_decompress(&cinfo);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -481,9 +462,6 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
|
|||||||
cinfo.output_height - cinfo.output_scanline)) {
|
cinfo.output_height - cinfo.output_scanline)) {
|
||||||
return return_false(cinfo, *bm, "skip rows");
|
return return_false(cinfo, *bm, "skip rows");
|
||||||
}
|
}
|
||||||
if (reuseBitmap) {
|
|
||||||
bm->notifyPixelsChanged();
|
|
||||||
}
|
|
||||||
jpeg_finish_decompress(&cinfo);
|
jpeg_finish_decompress(&cinfo);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -299,21 +299,8 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap,
|
|||||||
|
|
||||||
const int sampleSize = this->getSampleSize();
|
const int sampleSize = this->getSampleSize();
|
||||||
SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize);
|
SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize);
|
||||||
|
decodedBitmap->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight());
|
||||||
|
|
||||||
decodedBitmap->lockPixels();
|
|
||||||
void* rowptr = (void*) decodedBitmap->getPixels();
|
|
||||||
bool reuseBitmap = (rowptr != NULL);
|
|
||||||
decodedBitmap->unlockPixels();
|
|
||||||
if (reuseBitmap && (sampler.scaledWidth() != decodedBitmap->width() ||
|
|
||||||
sampler.scaledHeight() != decodedBitmap->height())) {
|
|
||||||
// Dimensions must match
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!reuseBitmap) {
|
|
||||||
decodedBitmap->setConfig(config, sampler.scaledWidth(),
|
|
||||||
sampler.scaledHeight());
|
|
||||||
}
|
|
||||||
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
|
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -332,11 +319,9 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap,
|
|||||||
|
|
||||||
SkAutoUnref aur(colorTable);
|
SkAutoUnref aur(colorTable);
|
||||||
|
|
||||||
if (!reuseBitmap) {
|
if (!this->allocPixelRef(decodedBitmap,
|
||||||
if (!this->allocPixelRef(decodedBitmap,
|
SkBitmap::kIndex8_Config == config ? colorTable : NULL)) {
|
||||||
SkBitmap::kIndex8_Config == config ? colorTable : NULL)) {
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SkAutoLockPixels alp(*decodedBitmap);
|
SkAutoLockPixels alp(*decodedBitmap);
|
||||||
@ -445,9 +430,6 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
decodedBitmap->setIsOpaque(!reallyHasAlpha);
|
decodedBitmap->setIsOpaque(!reallyHasAlpha);
|
||||||
if (reuseBitmap) {
|
|
||||||
decodedBitmap->notifyPixelsChanged();
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,25 +412,16 @@ bool SkWEBPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap,
|
|||||||
|
|
||||||
const int sampleSize = this->getSampleSize();
|
const int sampleSize = this->getSampleSize();
|
||||||
SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize);
|
SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize);
|
||||||
|
|
||||||
// If only bounds are requested, done
|
|
||||||
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
|
|
||||||
if (!setDecodeConfig(decodedBitmap, sampler.scaledWidth(),
|
|
||||||
sampler.scaledHeight())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No Bitmap reuse supported for this format
|
|
||||||
if (!decodedBitmap->isNull()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!setDecodeConfig(decodedBitmap, sampler.scaledWidth(),
|
if (!setDecodeConfig(decodedBitmap, sampler.scaledWidth(),
|
||||||
sampler.scaledHeight())) {
|
sampler.scaledHeight())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If only bounds are requested, done
|
||||||
|
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this->allocPixelRef(decodedBitmap, NULL)) {
|
if (!this->allocPixelRef(decodedBitmap, NULL)) {
|
||||||
return return_false(*decodedBitmap, "allocPixelRef");
|
return return_false(*decodedBitmap, "allocPixelRef");
|
||||||
}
|
}
|
||||||
|
@ -111,20 +111,13 @@ bool SkWBMPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap,
|
|||||||
int width = head.fWidth;
|
int width = head.fWidth;
|
||||||
int height = head.fHeight;
|
int height = head.fHeight;
|
||||||
|
|
||||||
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
|
|
||||||
decodedBitmap->setConfig(SkBitmap::kIndex8_Config, width, height);
|
|
||||||
decodedBitmap->setIsOpaque(true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No Bitmap reuse supported for this format
|
|
||||||
if (!decodedBitmap->isNull()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
decodedBitmap->setConfig(SkBitmap::kIndex8_Config, width, height);
|
decodedBitmap->setConfig(SkBitmap::kIndex8_Config, width, height);
|
||||||
decodedBitmap->setIsOpaque(true);
|
decodedBitmap->setIsOpaque(true);
|
||||||
|
|
||||||
|
if (SkImageDecoder::kDecodeBounds_Mode == mode) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const SkPMColor colors[] = { SK_ColorBLACK, SK_ColorWHITE };
|
const SkPMColor colors[] = { SK_ColorBLACK, SK_ColorWHITE };
|
||||||
SkColorTable* ct = SkNEW_ARGS(SkColorTable, (colors, 2));
|
SkColorTable* ct = SkNEW_ARGS(SkColorTable, (colors, 2));
|
||||||
SkAutoUnref aur(ct);
|
SkAutoUnref aur(ct);
|
||||||
|
@ -27,7 +27,7 @@ bool SkImageDecoder::DecodeFile(const char[], SkBitmap*, SkBitmap::Config,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkImageDecoder::decode(SkStream*, SkBitmap*, SkBitmap::Config, Mode, bool) {
|
bool SkImageDecoder::decode(SkStream*, SkBitmap*, SkBitmap::Config, Mode) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user