1 /* libs/graphics/images/SkImageDecoder.cpp 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #include "SkImageDecoder.h" 19 #include "SkBitmap.h" 20 #include "SkPixelRef.h" 21 #include "SkStream.h" 22 #include "SkTemplates.h" 23 #include "SkCanvas.h" 24 25 SkVMMemoryReporter::~SkVMMemoryReporter() { 26 } 27 28 const char *SkImageDecoder::kFormatName[] = { 29 "Unknown Format", 30 "BMP", 31 "GIF", 32 "ICO", 33 "JPEG", 34 "PNG", 35 "WBMP", 36 }; 37 38 static SkBitmap::Config gDeviceConfig = SkBitmap::kNo_Config; 39 40 SkBitmap::Config SkImageDecoder::GetDeviceConfig() 41 { 42 return gDeviceConfig; 43 } 44 45 void SkImageDecoder::SetDeviceConfig(SkBitmap::Config config) 46 { 47 gDeviceConfig = config; 48 } 49 50 /////////////////////////////////////////////////////////////////////////////// 51 52 SkImageDecoder::SkImageDecoder() 53 : fReporter(NULL), fPeeker(NULL), fChooser(NULL), fAllocator(NULL), 54 fSampleSize(1), fDefaultPref(SkBitmap::kNo_Config), fDitherImage(true), 55 fUsePrefTable(false) { 56 } 57 58 SkImageDecoder::~SkImageDecoder() { 59 fPeeker->safeUnref(); 60 fChooser->safeUnref(); 61 fAllocator->safeUnref(); 62 fReporter->safeUnref(); 63 } 64 65 SkImageDecoder::Format SkImageDecoder::getFormat() const { 66 return kUnknown_Format; 67 } 68 69 SkImageDecoder::Peeker* SkImageDecoder::setPeeker(Peeker* peeker) { 70 SkRefCnt_SafeAssign(fPeeker, peeker); 71 return peeker; 72 } 73 74 SkImageDecoder::Chooser* SkImageDecoder::setChooser(Chooser* chooser) { 75 SkRefCnt_SafeAssign(fChooser, chooser); 76 return chooser; 77 } 78 79 SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) { 80 SkRefCnt_SafeAssign(fAllocator, alloc); 81 return alloc; 82 } 83 84 SkVMMemoryReporter* SkImageDecoder::setReporter(SkVMMemoryReporter* reporter) { 85 SkRefCnt_SafeAssign(fReporter, reporter); 86 return reporter; 87 } 88 89 void SkImageDecoder::setSampleSize(int size) { 90 if (size < 1) { 91 size = 1; 92 } 93 fSampleSize = size; 94 } 95 96 bool SkImageDecoder::chooseFromOneChoice(SkBitmap::Config config, int width, 97 int height) const { 98 Chooser* chooser = fChooser; 99 100 if (NULL == chooser) { // no chooser, we just say YES to decoding :) 101 return true; 102 } 103 chooser->begin(1); 104 chooser->inspect(0, config, width, height); 105 return chooser->choose() == 0; 106 } 107 108 bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap, 109 SkColorTable* ctable) const { 110 return bitmap->allocPixels(fAllocator, ctable); 111 } 112 113 /////////////////////////////////////////////////////////////////////////////// 114 115 void SkImageDecoder::setPrefConfigTable(const SkBitmap::Config pref[6]) { 116 if (NULL == pref) { 117 fUsePrefTable = false; 118 } else { 119 fUsePrefTable = true; 120 memcpy(fPrefTable, pref, sizeof(fPrefTable)); 121 } 122 } 123 124 SkBitmap::Config SkImageDecoder::getPrefConfig(SrcDepth srcDepth, 125 bool srcHasAlpha) const { 126 SkBitmap::Config config; 127 128 if (fUsePrefTable) { 129 int index = 0; 130 switch (srcDepth) { 131 case kIndex_SrcDepth: 132 index = 0; 133 break; 134 case k16Bit_SrcDepth: 135 index = 2; 136 break; 137 case k32Bit_SrcDepth: 138 index = 4; 139 break; 140 } 141 if (srcHasAlpha) { 142 index += 1; 143 } 144 config = fPrefTable[index]; 145 } else { 146 config = fDefaultPref; 147 } 148 149 if (SkBitmap::kNo_Config == config) { 150 config = SkImageDecoder::GetDeviceConfig(); 151 } 152 return config; 153 } 154 155 bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, 156 SkBitmap::Config pref, Mode mode) { 157 // pass a temporary bitmap, so that if we return false, we are assured of 158 // leaving the caller's bitmap untouched. 159 SkBitmap tmp; 160 161 // we reset this to false before calling onDecode 162 fShouldCancelDecode = false; 163 // assign this, for use by getPrefConfig(), in case fUsePrefTable is false 164 fDefaultPref = pref; 165 166 if (!this->onDecode(stream, &tmp, mode)) { 167 return false; 168 } 169 bm->swap(tmp); 170 return true; 171 } 172 173 bool SkImageDecoder::decodeRegion(SkBitmap* bm, SkIRect rect, 174 SkBitmap::Config pref) { 175 // pass a temporary bitmap, so that if we return false, we are assured of 176 // leaving the caller's bitmap untouched. 177 SkBitmap tmp; 178 179 // we reset this to false before calling onDecodeRegion 180 fShouldCancelDecode = false; 181 // assign this, for use by getPrefConfig(), in case fUsePrefTable is false 182 fDefaultPref = pref; 183 184 if (!this->onDecodeRegion(&tmp, rect)) { 185 return false; 186 } 187 bm->swap(tmp); 188 return true; 189 } 190 191 bool SkImageDecoder::buildTileIndex(SkStream* stream, 192 int *width, int *height) { 193 // we reset this to false before calling onBuildTileIndex 194 fShouldCancelDecode = false; 195 196 return this->onBuildTileIndex(stream, width, height); 197 } 198 199 void SkImageDecoder::cropBitmap(SkBitmap *dest, SkBitmap *src, 200 int sampleSize, int destX, int destY, 201 int width, int height, int srcX, int srcY) { 202 int w = width / sampleSize; 203 int h = height / sampleSize; 204 if (w == src->width() && h == src->height() && 205 (srcX - destX) / sampleSize == 0 && (srcY - destY) / sampleSize == 0) { 206 // The output rect is the same as the decode result 207 dest->swap(*src); 208 return; 209 } 210 dest->setConfig(src->getConfig(), w, h); 211 dest->setIsOpaque(src->isOpaque()); 212 this->allocPixelRef(dest, NULL); 213 214 SkCanvas canvas(*dest); 215 canvas.drawBitmap(*src, (srcX - destX) / sampleSize, 216 (srcY - destY) / sampleSize); 217 } 218 219 /////////////////////////////////////////////////////////////////////////////// 220 221 bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, 222 SkBitmap::Config pref, Mode mode, Format* format) { 223 SkASSERT(file); 224 SkASSERT(bm); 225 226 SkFILEStream stream(file); 227 if (stream.isValid()) { 228 if (SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format)) { 229 bm->pixelRef()->setURI(file); 230 } 231 return true; 232 } 233 return false; 234 } 235 236 bool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm, 237 SkBitmap::Config pref, Mode mode, Format* format) { 238 if (0 == size) { 239 return false; 240 } 241 SkASSERT(buffer); 242 243 SkMemoryStream stream(buffer, size); 244 return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format); 245 } 246 247 bool SkImageDecoder::DecodeStream(SkStream* stream, SkBitmap* bm, 248 SkBitmap::Config pref, Mode mode, Format* format) { 249 SkASSERT(stream); 250 SkASSERT(bm); 251 252 bool success = false; 253 SkImageDecoder* codec = SkImageDecoder::Factory(stream); 254 255 if (NULL != codec) { 256 success = codec->decode(stream, bm, pref, mode); 257 if (success && format) { 258 *format = codec->getFormat(); 259 } 260 delete codec; 261 } 262 return success; 263 } 264