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