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 24 static SkBitmap::Config gDeviceConfig = SkBitmap::kNo_Config; 25 26 SkBitmap::Config SkImageDecoder::GetDeviceConfig() 27 { 28 return gDeviceConfig; 29 } 30 31 void SkImageDecoder::SetDeviceConfig(SkBitmap::Config config) 32 { 33 gDeviceConfig = config; 34 } 35 36 /////////////////////////////////////////////////////////////////////////////// 37 38 SkImageDecoder::SkImageDecoder() 39 : fPeeker(NULL), fChooser(NULL), fAllocator(NULL), fSampleSize(1), 40 fDefaultPref(SkBitmap::kNo_Config), fDitherImage(true), 41 fUsePrefTable(false) { 42 } 43 44 SkImageDecoder::~SkImageDecoder() { 45 fPeeker->safeUnref(); 46 fChooser->safeUnref(); 47 fAllocator->safeUnref(); 48 } 49 50 SkImageDecoder::Format SkImageDecoder::getFormat() const { 51 return kUnknown_Format; 52 } 53 54 SkImageDecoder::Peeker* SkImageDecoder::setPeeker(Peeker* peeker) { 55 SkRefCnt_SafeAssign(fPeeker, peeker); 56 return peeker; 57 } 58 59 SkImageDecoder::Chooser* SkImageDecoder::setChooser(Chooser* chooser) { 60 SkRefCnt_SafeAssign(fChooser, chooser); 61 return chooser; 62 } 63 64 SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) { 65 SkRefCnt_SafeAssign(fAllocator, alloc); 66 return alloc; 67 } 68 69 void SkImageDecoder::setSampleSize(int size) { 70 if (size < 1) { 71 size = 1; 72 } 73 fSampleSize = size; 74 } 75 76 bool SkImageDecoder::chooseFromOneChoice(SkBitmap::Config config, int width, 77 int height) const { 78 Chooser* chooser = fChooser; 79 80 if (NULL == chooser) { // no chooser, we just say YES to decoding :) 81 return true; 82 } 83 chooser->begin(1); 84 chooser->inspect(0, config, width, height); 85 return chooser->choose() == 0; 86 } 87 88 bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap, 89 SkColorTable* ctable) const { 90 return bitmap->allocPixels(fAllocator, ctable); 91 } 92 93 /////////////////////////////////////////////////////////////////////////////// 94 95 void SkImageDecoder::setPrefConfigTable(const SkBitmap::Config pref[6]) { 96 if (NULL == pref) { 97 fUsePrefTable = false; 98 } else { 99 fUsePrefTable = true; 100 memcpy(fPrefTable, pref, sizeof(fPrefTable)); 101 } 102 } 103 104 SkBitmap::Config SkImageDecoder::getPrefConfig(SrcDepth srcDepth, 105 bool srcHasAlpha) const { 106 SkBitmap::Config config; 107 108 if (fUsePrefTable) { 109 int index = 0; 110 switch (srcDepth) { 111 case kIndex_SrcDepth: 112 index = 0; 113 break; 114 case k16Bit_SrcDepth: 115 index = 2; 116 break; 117 case k32Bit_SrcDepth: 118 index = 4; 119 break; 120 } 121 if (srcHasAlpha) { 122 index += 1; 123 } 124 config = fPrefTable[index]; 125 } else { 126 config = fDefaultPref; 127 } 128 129 if (SkBitmap::kNo_Config == config) { 130 config = SkImageDecoder::GetDeviceConfig(); 131 } 132 return config; 133 } 134 135 bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, 136 SkBitmap::Config pref, Mode mode) { 137 // pass a temporary bitmap, so that if we return false, we are assured of 138 // leaving the caller's bitmap untouched. 139 SkBitmap tmp; 140 141 // we reset this to false before calling onDecode 142 fShouldCancelDecode = false; 143 // assign this, for use by getPrefConfig(), in case fUsePrefTable is false 144 fDefaultPref = pref; 145 146 if (!this->onDecode(stream, &tmp, mode)) { 147 return false; 148 } 149 bm->swap(tmp); 150 return true; 151 } 152 153 /////////////////////////////////////////////////////////////////////////////// 154 155 bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, 156 SkBitmap::Config pref, Mode mode, Format* format) { 157 SkASSERT(file); 158 SkASSERT(bm); 159 160 SkFILEStream stream(file); 161 if (stream.isValid()) { 162 if (SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format)) { 163 bm->pixelRef()->setURI(file); 164 } 165 return true; 166 } 167 return false; 168 } 169 170 bool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm, 171 SkBitmap::Config pref, Mode mode, Format* format) { 172 if (0 == size) { 173 return false; 174 } 175 SkASSERT(buffer); 176 177 SkMemoryStream stream(buffer, size); 178 return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format); 179 } 180 181 bool SkImageDecoder::DecodeStream(SkStream* stream, SkBitmap* bm, 182 SkBitmap::Config pref, Mode mode, Format* format) { 183 SkASSERT(stream); 184 SkASSERT(bm); 185 186 bool success = false; 187 SkImageDecoder* codec = SkImageDecoder::Factory(stream); 188 189 if (NULL != codec) { 190 success = codec->decode(stream, bm, pref, mode); 191 if (success && format) { 192 *format = codec->getFormat(); 193 } 194 delete codec; 195 } 196 return success; 197 } 198 199