1 2 /* 3 * Copyright 2006 The Android Open Source Project 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 9 10 #include "SkImageDecoder.h" 11 #include "SkBitmap.h" 12 #include "SkPixelRef.h" 13 #include "SkStream.h" 14 #include "SkTemplates.h" 15 #include "SkCanvas.h" 16 17 SkVMMemoryReporter::~SkVMMemoryReporter() { 18 } 19 20 const char *SkImageDecoder::kFormatName[] = { 21 "Unknown Format", 22 "BMP", 23 "GIF", 24 "ICO", 25 "JPEG", 26 "PNG", 27 "WBMP", 28 "WEBP", 29 }; 30 31 static SkBitmap::Config gDeviceConfig = SkBitmap::kNo_Config; 32 33 SkBitmap::Config SkImageDecoder::GetDeviceConfig() 34 { 35 return gDeviceConfig; 36 } 37 38 void SkImageDecoder::SetDeviceConfig(SkBitmap::Config config) 39 { 40 gDeviceConfig = config; 41 } 42 43 /////////////////////////////////////////////////////////////////////////////// 44 45 SkImageDecoder::SkImageDecoder() 46 : fReporter(NULL), fPeeker(NULL), fChooser(NULL), fAllocator(NULL), 47 fSampleSize(1), fDefaultPref(SkBitmap::kNo_Config), fDitherImage(true), 48 fUsePrefTable(false),fPreferQualityOverSpeed(false) { 49 } 50 51 SkImageDecoder::~SkImageDecoder() { 52 SkSafeUnref(fPeeker); 53 SkSafeUnref(fChooser); 54 SkSafeUnref(fAllocator); 55 SkSafeUnref(fReporter); 56 } 57 58 SkImageDecoder::Format SkImageDecoder::getFormat() const { 59 return kUnknown_Format; 60 } 61 62 SkImageDecoder::Peeker* SkImageDecoder::setPeeker(Peeker* peeker) { 63 SkRefCnt_SafeAssign(fPeeker, peeker); 64 return peeker; 65 } 66 67 SkImageDecoder::Chooser* SkImageDecoder::setChooser(Chooser* chooser) { 68 SkRefCnt_SafeAssign(fChooser, chooser); 69 return chooser; 70 } 71 72 SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) { 73 SkRefCnt_SafeAssign(fAllocator, alloc); 74 return alloc; 75 } 76 77 SkVMMemoryReporter* SkImageDecoder::setReporter(SkVMMemoryReporter* reporter) { 78 SkRefCnt_SafeAssign(fReporter, reporter); 79 return reporter; 80 } 81 82 void SkImageDecoder::setSampleSize(int size) { 83 if (size < 1) { 84 size = 1; 85 } 86 fSampleSize = size; 87 } 88 89 bool SkImageDecoder::chooseFromOneChoice(SkBitmap::Config config, int width, 90 int height) const { 91 Chooser* chooser = fChooser; 92 93 if (NULL == chooser) { // no chooser, we just say YES to decoding :) 94 return true; 95 } 96 chooser->begin(1); 97 chooser->inspect(0, config, width, height); 98 return chooser->choose() == 0; 99 } 100 101 bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap, 102 SkColorTable* ctable) const { 103 return bitmap->allocPixels(fAllocator, ctable); 104 } 105 106 /////////////////////////////////////////////////////////////////////////////// 107 108 void SkImageDecoder::setPrefConfigTable(const SkBitmap::Config pref[6]) { 109 if (NULL == pref) { 110 fUsePrefTable = false; 111 } else { 112 fUsePrefTable = true; 113 memcpy(fPrefTable, pref, sizeof(fPrefTable)); 114 } 115 } 116 117 SkBitmap::Config SkImageDecoder::getPrefConfig(SrcDepth srcDepth, 118 bool srcHasAlpha) const { 119 SkBitmap::Config config; 120 121 if (fUsePrefTable) { 122 int index = 0; 123 switch (srcDepth) { 124 case kIndex_SrcDepth: 125 index = 0; 126 break; 127 case k16Bit_SrcDepth: 128 index = 2; 129 break; 130 case k32Bit_SrcDepth: 131 index = 4; 132 break; 133 } 134 if (srcHasAlpha) { 135 index += 1; 136 } 137 config = fPrefTable[index]; 138 } else { 139 config = fDefaultPref; 140 } 141 142 if (SkBitmap::kNo_Config == config) { 143 config = SkImageDecoder::GetDeviceConfig(); 144 } 145 return config; 146 } 147 148 bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, 149 SkBitmap::Config pref, Mode mode, bool reuseBitmap) { 150 // pass a temporary bitmap, so that if we return false, we are assured of 151 // leaving the caller's bitmap untouched. 152 SkBitmap tmp; 153 154 // we reset this to false before calling onDecode 155 fShouldCancelDecode = false; 156 // assign this, for use by getPrefConfig(), in case fUsePrefTable is false 157 fDefaultPref = pref; 158 159 if (reuseBitmap) { 160 SkAutoLockPixels alp(*bm); 161 if (bm->getPixels() != NULL) { 162 return this->onDecode(stream, bm, mode); 163 } 164 } 165 if (!this->onDecode(stream, &tmp, mode)) { 166 return false; 167 } 168 bm->swap(tmp); 169 return true; 170 } 171 172 bool SkImageDecoder::decodeRegion(SkBitmap* bm, SkIRect rect, 173 SkBitmap::Config pref) { 174 // we reset this to false before calling onDecodeRegion 175 fShouldCancelDecode = false; 176 // assign this, for use by getPrefConfig(), in case fUsePrefTable is false 177 fDefaultPref = pref; 178 179 if (!this->onDecodeRegion(bm, rect)) { 180 return false; 181 } 182 return true; 183 } 184 185 bool SkImageDecoder::buildTileIndex(SkStream* stream, 186 int *width, int *height) { 187 // we reset this to false before calling onBuildTileIndex 188 fShouldCancelDecode = false; 189 190 return this->onBuildTileIndex(stream, width, height); 191 } 192 193 void SkImageDecoder::cropBitmap(SkBitmap *dest, SkBitmap *src, 194 int sampleSize, int destX, int destY, 195 int width, int height, int srcX, int srcY) { 196 int w = width / sampleSize; 197 int h = height / sampleSize; 198 // if the destination has no pixels then we must allocate them. 199 if (dest->isNull()) { 200 dest->setConfig(src->getConfig(), w, h); 201 dest->setIsOpaque(src->isOpaque()); 202 203 if (!this->allocPixelRef(dest, NULL)) { 204 SkDEBUGF(("failed to allocate pixels needed to crop the bitmap")); 205 return; 206 } 207 } 208 // check to see if the destination is large enough to decode the desired 209 // region. If this assert fails we will just draw as much of the source 210 // into the destination that we can. 211 SkASSERT(dest->width() >= w && dest->height() >= h); 212 213 // Set the Src_Mode for the paint to prevent transparency issue in the 214 // dest in the event that the dest was being re-used. 215 SkPaint paint; 216 paint.setXfermodeMode(SkXfermode::kSrc_Mode); 217 218 SkCanvas canvas(*dest); 219 canvas.drawSprite(*src, (srcX - destX) / sampleSize, 220 (srcY - destY) / sampleSize, 221 &paint); 222 } 223 224 /////////////////////////////////////////////////////////////////////////////// 225 226 bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, 227 SkBitmap::Config pref, Mode mode, Format* format) { 228 SkASSERT(file); 229 SkASSERT(bm); 230 231 SkFILEStream stream(file); 232 if (stream.isValid()) { 233 if (SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format)) { 234 bm->pixelRef()->setURI(file); 235 return true; 236 } 237 } 238 return false; 239 } 240 241 bool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm, 242 SkBitmap::Config pref, Mode mode, Format* format) { 243 if (0 == size) { 244 return false; 245 } 246 SkASSERT(buffer); 247 248 SkMemoryStream stream(buffer, size); 249 return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format); 250 } 251 252 bool SkImageDecoder::DecodeStream(SkStream* stream, SkBitmap* bm, 253 SkBitmap::Config pref, Mode mode, Format* format) { 254 SkASSERT(stream); 255 SkASSERT(bm); 256 257 bool success = false; 258 SkImageDecoder* codec = SkImageDecoder::Factory(stream); 259 260 if (NULL != codec) { 261 success = codec->decode(stream, bm, pref, mode); 262 if (success && format) { 263 *format = codec->getFormat(); 264 } 265 delete codec; 266 } 267 return success; 268 } 269