1#include "SkImageRef.h" 2#include "SkBitmap.h" 3#include "SkFlattenable.h" 4#include "SkImageDecoder.h" 5#include "SkStream.h" 6#include "SkTemplates.h" 7#include "SkThread.h" 8 9//#define DUMP_IMAGEREF_LIFECYCLE 10 11// can't be static, as SkImageRef_Pool needs to see it 12SkMutex gImageRefMutex; 13 14/////////////////////////////////////////////////////////////////////////////// 15 16SkImageRef::SkImageRef(SkStream* stream, SkBitmap::Config config, 17 int sampleSize) 18 : SkPixelRef(&gImageRefMutex), fErrorInDecoding(false) { 19 SkASSERT(stream); 20 stream->ref(); 21 fStream = stream; 22 fConfig = config; 23 fSampleSize = sampleSize; 24 fDoDither = true; 25 fPrev = fNext = NULL; 26 fFactory = NULL; 27 28#ifdef DUMP_IMAGEREF_LIFECYCLE 29 SkDebugf("add ImageRef %p [%d] data=%d\n", 30 this, config, (int)stream->getLength()); 31#endif 32} 33 34SkImageRef::~SkImageRef() { 35 SkASSERT(&gImageRefMutex == this->mutex()); 36 37#ifdef DUMP_IMAGEREF_LIFECYCLE 38 SkDebugf("delete ImageRef %p [%d] data=%d\n", 39 this, fConfig, (int)fStream->getLength()); 40#endif 41 42 fStream->unref(); 43 fFactory->safeUnref(); 44} 45 46bool SkImageRef::getInfo(SkBitmap* bitmap) { 47 SkAutoMutexAcquire ac(gImageRefMutex); 48 49 if (!this->prepareBitmap(SkImageDecoder::kDecodeBounds_Mode)) { 50 return false; 51 } 52 53 SkASSERT(SkBitmap::kNo_Config != fBitmap.config()); 54 if (bitmap) { 55 bitmap->setConfig(fBitmap.config(), fBitmap.width(), fBitmap.height()); 56 } 57 return true; 58} 59 60SkImageDecoderFactory* SkImageRef::setDecoderFactory( 61 SkImageDecoderFactory* fact) { 62 SkRefCnt_SafeAssign(fFactory, fact); 63 return fact; 64} 65 66/////////////////////////////////////////////////////////////////////////////// 67 68bool SkImageRef::onDecode(SkImageDecoder* codec, SkStream* stream, 69 SkBitmap* bitmap, SkBitmap::Config config, 70 SkImageDecoder::Mode mode) { 71 return codec->decode(stream, bitmap, config, mode); 72} 73 74bool SkImageRef::prepareBitmap(SkImageDecoder::Mode mode) { 75 SkASSERT(&gImageRefMutex == this->mutex()); 76 77 if (fErrorInDecoding) { 78 return false; 79 } 80 81 /* As soon as we really know our config, we record it, so that on 82 subsequent calls to the codec, we are sure we will always get the same 83 result. 84 */ 85 if (SkBitmap::kNo_Config != fBitmap.config()) { 86 fConfig = fBitmap.config(); 87 } 88 89 if (NULL != fBitmap.getPixels() || 90 (SkBitmap::kNo_Config != fBitmap.config() && 91 SkImageDecoder::kDecodeBounds_Mode == mode)) { 92 return true; 93 } 94 95 SkASSERT(fBitmap.getPixels() == NULL); 96 97 fStream->rewind(); 98 99 SkImageDecoder* codec; 100 if (fFactory) { 101 codec = fFactory->newDecoder(fStream); 102 } else { 103 codec = SkImageDecoder::Factory(fStream); 104 } 105 106 if (codec) { 107 SkAutoTDelete<SkImageDecoder> ad(codec); 108 109 codec->setSampleSize(fSampleSize); 110 codec->setDitherImage(fDoDither); 111 if (this->onDecode(codec, fStream, &fBitmap, fConfig, mode)) { 112 return true; 113 } 114 } 115 116#ifdef DUMP_IMAGEREF_LIFECYCLE 117 if (NULL == codec) { 118 SkDebugf("--- ImageRef: <%s> failed to find codec\n", this->getURI()); 119 } else { 120 SkDebugf("--- ImageRef: <%s> failed in codec for %d mode\n", 121 this->getURI(), mode); 122 } 123#endif 124 fErrorInDecoding = true; 125 fBitmap.reset(); 126 return false; 127} 128 129void* SkImageRef::onLockPixels(SkColorTable** ct) { 130 SkASSERT(&gImageRefMutex == this->mutex()); 131 132 if (NULL == fBitmap.getPixels()) { 133 (void)this->prepareBitmap(SkImageDecoder::kDecodePixels_Mode); 134 } 135 136 if (ct) { 137 *ct = fBitmap.getColorTable(); 138 } 139 return fBitmap.getPixels(); 140} 141 142void SkImageRef::onUnlockPixels() { 143 // we're already have the mutex locked 144 SkASSERT(&gImageRefMutex == this->mutex()); 145} 146 147size_t SkImageRef::ramUsed() const { 148 size_t size = 0; 149 150 if (fBitmap.getPixels()) { 151 size = fBitmap.getSize(); 152 if (fBitmap.getColorTable()) { 153 size += fBitmap.getColorTable()->count() * sizeof(SkPMColor); 154 } 155 } 156 return size; 157} 158 159/////////////////////////////////////////////////////////////////////////////// 160 161SkImageRef::SkImageRef(SkFlattenableReadBuffer& buffer) 162 : INHERITED(buffer, &gImageRefMutex), fErrorInDecoding(false) { 163 fConfig = (SkBitmap::Config)buffer.readU8(); 164 fSampleSize = buffer.readU8(); 165 fDoDither = buffer.readBool(); 166 167 size_t length = buffer.readU32(); 168 fStream = SkNEW_ARGS(SkMemoryStream, (length)); 169 buffer.read((void*)fStream->getMemoryBase(), length); 170 171 fPrev = fNext = NULL; 172 fFactory = NULL; 173} 174 175void SkImageRef::flatten(SkFlattenableWriteBuffer& buffer) const { 176 this->INHERITED::flatten(buffer); 177 178 buffer.write8(fConfig); 179 buffer.write8(fSampleSize); 180 buffer.writeBool(fDoDither); 181 size_t length = fStream->getLength(); 182 buffer.write32(length); 183 fStream->rewind(); 184 buffer.readFromStream(fStream, length); 185} 186 187