1 /* 2 * Copyright 2006 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 9 #include "SkImageDecoder.h" 10 #include "SkBitmap.h" 11 #include "SkImagePriv.h" 12 #include "SkPixelRef.h" 13 #include "SkStream.h" 14 #include "SkTemplates.h" 15 #include "SkCanvas.h" 16 17 SK_DEFINE_INST_COUNT(SkImageDecoder::Peeker) 18 SK_DEFINE_INST_COUNT(SkImageDecoder::Chooser) 19 SK_DEFINE_INST_COUNT(SkImageDecoderFactory) 20 21 static SkBitmap::Config gDeviceConfig = SkBitmap::kNo_Config; 22 23 SkBitmap::Config SkImageDecoder::GetDeviceConfig() 24 { 25 return gDeviceConfig; 26 } 27 28 void SkImageDecoder::SetDeviceConfig(SkBitmap::Config config) 29 { 30 gDeviceConfig = config; 31 } 32 33 /////////////////////////////////////////////////////////////////////////////// 34 35 SkImageDecoder::SkImageDecoder() 36 : fPeeker(NULL) 37 , fChooser(NULL) 38 , fAllocator(NULL) 39 , fSampleSize(1) 40 , fDefaultPref(SkBitmap::kNo_Config) 41 , fDitherImage(true) 42 , fUsePrefTable(false) 43 , fPreferQualityOverSpeed(false) 44 , fRequireUnpremultipliedColors(false) { 45 } 46 47 SkImageDecoder::~SkImageDecoder() { 48 SkSafeUnref(fPeeker); 49 SkSafeUnref(fChooser); 50 SkSafeUnref(fAllocator); 51 } 52 53 void SkImageDecoder::copyFieldsToOther(SkImageDecoder* other) { 54 if (NULL == other) { 55 return; 56 } 57 other->setPeeker(fPeeker); 58 other->setChooser(fChooser); 59 other->setAllocator(fAllocator); 60 other->setSampleSize(fSampleSize); 61 if (fUsePrefTable) { 62 other->setPrefConfigTable(fPrefTable); 63 } else { 64 other->fDefaultPref = fDefaultPref; 65 } 66 other->setPreferQualityOverSpeed(fPreferQualityOverSpeed); 67 other->setRequireUnpremultipliedColors(fRequireUnpremultipliedColors); 68 } 69 70 SkImageDecoder::Format SkImageDecoder::getFormat() const { 71 return kUnknown_Format; 72 } 73 74 const char* SkImageDecoder::getFormatName() const { 75 return GetFormatName(this->getFormat()); 76 } 77 78 const char* SkImageDecoder::GetFormatName(Format format) { 79 switch (format) { 80 case kUnknown_Format: 81 return "Unknown Format"; 82 case kBMP_Format: 83 return "BMP"; 84 case kGIF_Format: 85 return "GIF"; 86 case kICO_Format: 87 return "ICO"; 88 case kJPEG_Format: 89 return "JPEG"; 90 case kPNG_Format: 91 return "PNG"; 92 case kWBMP_Format: 93 return "WBMP"; 94 case kWEBP_Format: 95 return "WEBP"; 96 default: 97 SkASSERT(!"Invalid format type!"); 98 } 99 return "Unknown Format"; 100 } 101 102 SkImageDecoder::Peeker* SkImageDecoder::setPeeker(Peeker* peeker) { 103 SkRefCnt_SafeAssign(fPeeker, peeker); 104 return peeker; 105 } 106 107 SkImageDecoder::Chooser* SkImageDecoder::setChooser(Chooser* chooser) { 108 SkRefCnt_SafeAssign(fChooser, chooser); 109 return chooser; 110 } 111 112 SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) { 113 SkRefCnt_SafeAssign(fAllocator, alloc); 114 return alloc; 115 } 116 117 void SkImageDecoder::setSampleSize(int size) { 118 if (size < 1) { 119 size = 1; 120 } 121 fSampleSize = size; 122 } 123 124 bool SkImageDecoder::chooseFromOneChoice(SkBitmap::Config config, int width, 125 int height) const { 126 Chooser* chooser = fChooser; 127 128 if (NULL == chooser) { // no chooser, we just say YES to decoding :) 129 return true; 130 } 131 chooser->begin(1); 132 chooser->inspect(0, config, width, height); 133 return chooser->choose() == 0; 134 } 135 136 bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap, 137 SkColorTable* ctable) const { 138 return bitmap->allocPixels(fAllocator, ctable); 139 } 140 141 /////////////////////////////////////////////////////////////////////////////// 142 143 void SkImageDecoder::setPrefConfigTable(const SkBitmap::Config pref[6]) { 144 if (NULL == pref) { 145 fUsePrefTable = false; 146 } else { 147 fUsePrefTable = true; 148 fPrefTable.fPrefFor_8Index_NoAlpha_src = pref[0]; 149 fPrefTable.fPrefFor_8Index_YesAlpha_src = pref[1]; 150 fPrefTable.fPrefFor_8Gray_src = SkBitmap::kNo_Config; 151 fPrefTable.fPrefFor_8bpc_NoAlpha_src = pref[4]; 152 fPrefTable.fPrefFor_8bpc_YesAlpha_src = pref[5]; 153 } 154 } 155 156 void SkImageDecoder::setPrefConfigTable(const PrefConfigTable& prefTable) { 157 fUsePrefTable = true; 158 fPrefTable = prefTable; 159 } 160 161 SkBitmap::Config SkImageDecoder::getPrefConfig(SrcDepth srcDepth, 162 bool srcHasAlpha) const { 163 SkBitmap::Config config = SkBitmap::kNo_Config; 164 165 if (fUsePrefTable) { 166 switch (srcDepth) { 167 case kIndex_SrcDepth: 168 config = srcHasAlpha ? fPrefTable.fPrefFor_8Index_YesAlpha_src 169 : fPrefTable.fPrefFor_8Index_NoAlpha_src; 170 break; 171 case k8BitGray_SrcDepth: 172 config = fPrefTable.fPrefFor_8Gray_src; 173 break; 174 case k32Bit_SrcDepth: 175 config = srcHasAlpha ? fPrefTable.fPrefFor_8bpc_YesAlpha_src 176 : fPrefTable.fPrefFor_8bpc_NoAlpha_src; 177 break; 178 } 179 } else { 180 config = fDefaultPref; 181 } 182 183 if (SkBitmap::kNo_Config == config) { 184 config = SkImageDecoder::GetDeviceConfig(); 185 } 186 return config; 187 } 188 189 bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm, 190 SkBitmap::Config pref, Mode mode) { 191 // we reset this to false before calling onDecode 192 fShouldCancelDecode = false; 193 // assign this, for use by getPrefConfig(), in case fUsePrefTable is false 194 fDefaultPref = pref; 195 196 // pass a temporary bitmap, so that if we return false, we are assured of 197 // leaving the caller's bitmap untouched. 198 SkBitmap tmp; 199 if (!this->onDecode(stream, &tmp, mode)) { 200 return false; 201 } 202 bm->swap(tmp); 203 return true; 204 } 205 206 bool SkImageDecoder::decodeSubset(SkBitmap* bm, const SkIRect& rect, 207 SkBitmap::Config pref) { 208 // we reset this to false before calling onDecodeSubset 209 fShouldCancelDecode = false; 210 // assign this, for use by getPrefConfig(), in case fUsePrefTable is false 211 fDefaultPref = pref; 212 213 return this->onDecodeSubset(bm, rect); 214 } 215 216 bool SkImageDecoder::buildTileIndex(SkStream* stream, 217 int *width, int *height) { 218 // we reset this to false before calling onBuildTileIndex 219 fShouldCancelDecode = false; 220 221 return this->onBuildTileIndex(stream, width, height); 222 } 223 224 bool SkImageDecoder::cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize, 225 int dstX, int dstY, int width, int height, 226 int srcX, int srcY) { 227 int w = width / sampleSize; 228 int h = height / sampleSize; 229 if (src->getConfig() == SkBitmap::kIndex8_Config) { 230 // kIndex8 does not allow drawing via an SkCanvas, as is done below. 231 // Instead, use extractSubset. Note that this shares the SkPixelRef and 232 // SkColorTable. 233 // FIXME: Since src is discarded in practice, this holds on to more 234 // pixels than is strictly necessary. Switch to a copy if memory 235 // savings are more important than speed here. This also means 236 // that the pixels in dst can not be reused (though there is no 237 // allocation, which was already done on src). 238 int x = (dstX - srcX) / sampleSize; 239 int y = (dstY - srcY) / sampleSize; 240 SkIRect subset = SkIRect::MakeXYWH(x, y, w, h); 241 return src->extractSubset(dst, subset); 242 } 243 // if the destination has no pixels then we must allocate them. 244 if (dst->isNull()) { 245 dst->setConfig(src->getConfig(), w, h); 246 dst->setIsOpaque(src->isOpaque()); 247 248 if (!this->allocPixelRef(dst, NULL)) { 249 SkDEBUGF(("failed to allocate pixels needed to crop the bitmap")); 250 return false; 251 } 252 } 253 // check to see if the destination is large enough to decode the desired 254 // region. If this assert fails we will just draw as much of the source 255 // into the destination that we can. 256 if (dst->width() < w || dst->height() < h) { 257 SkDEBUGF(("SkImageDecoder::cropBitmap does not have a large enough bitmap.\n")); 258 } 259 260 // Set the Src_Mode for the paint to prevent transparency issue in the 261 // dest in the event that the dest was being re-used. 262 SkPaint paint; 263 paint.setXfermodeMode(SkXfermode::kSrc_Mode); 264 265 SkCanvas canvas(*dst); 266 canvas.drawSprite(*src, (srcX - dstX) / sampleSize, 267 (srcY - dstY) / sampleSize, 268 &paint); 269 return true; 270 } 271 272 /////////////////////////////////////////////////////////////////////////////// 273 274 bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm, 275 SkBitmap::Config pref, Mode mode, Format* format) { 276 SkASSERT(file); 277 SkASSERT(bm); 278 279 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(file)); 280 if (stream.get()) { 281 if (SkImageDecoder::DecodeStream(stream, bm, pref, mode, format)) { 282 bm->pixelRef()->setURI(file); 283 return true; 284 } 285 } 286 return false; 287 } 288 289 bool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm, 290 SkBitmap::Config pref, Mode mode, Format* format) { 291 if (0 == size) { 292 return false; 293 } 294 SkASSERT(buffer); 295 296 SkMemoryStream stream(buffer, size); 297 return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format); 298 } 299 300 /** 301 * Special allocator used by DecodeMemoryToTarget. Uses preallocated memory 302 * provided if the bm is 8888. Otherwise, uses a heap allocator. The same 303 * allocator will be used again for a copy to 8888, when the preallocated 304 * memory will be used. 305 */ 306 class TargetAllocator : public SkBitmap::HeapAllocator { 307 308 public: 309 TargetAllocator(void* target) 310 : fTarget(target) {} 311 312 virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) SK_OVERRIDE { 313 // If the config is not 8888, allocate a pixelref using the heap. 314 // fTarget will be used to store the final pixels when copied to 315 // 8888. 316 if (bm->config() != SkBitmap::kARGB_8888_Config) { 317 return INHERITED::allocPixelRef(bm, ct); 318 } 319 // In kARGB_8888_Config, there is no colortable. 320 SkASSERT(NULL == ct); 321 bm->setPixels(fTarget); 322 return true; 323 } 324 325 private: 326 void* fTarget; 327 typedef SkBitmap::HeapAllocator INHERITED; 328 }; 329 330 /** 331 * Helper function for DecodeMemoryToTarget. DecodeMemoryToTarget wants 332 * 8888, so set the config to it. All parameters must not be null. 333 * @param decoder Decoder appropriate for this stream. 334 * @param stream Rewound stream to the encoded data. 335 * @param bitmap On success, will have its bounds set to the bounds of the 336 * encoded data, and its config set to 8888. 337 * @return True if the bounds were decoded and the bitmap is 8888 or can be 338 * copied to 8888. 339 */ 340 static bool decode_bounds_to_8888(SkImageDecoder* decoder, SkStream* stream, 341 SkBitmap* bitmap) { 342 SkASSERT(decoder != NULL); 343 SkASSERT(stream != NULL); 344 SkASSERT(bitmap != NULL); 345 346 if (!decoder->decode(stream, bitmap, SkImageDecoder::kDecodeBounds_Mode)) { 347 return false; 348 } 349 350 if (bitmap->config() == SkBitmap::kARGB_8888_Config) { 351 return true; 352 } 353 354 if (!bitmap->canCopyTo(SkBitmap::kARGB_8888_Config)) { 355 return false; 356 } 357 358 bitmap->setConfig(SkBitmap::kARGB_8888_Config, bitmap->width(), bitmap->height()); 359 return true; 360 } 361 362 /** 363 * Helper function for DecodeMemoryToTarget. Decodes the stream into bitmap, and if 364 * the bitmap is not 8888, then it is copied to 8888. Either way, the end result has 365 * its pixels stored in target. All parameters must not be null. 366 * @param decoder Decoder appropriate for this stream. 367 * @param stream Rewound stream to the encoded data. 368 * @param bitmap On success, will contain the decoded image, with its pixels stored 369 * at target. 370 * @param target Preallocated memory for storing pixels. 371 * @return bool Whether the decode (and copy, if necessary) succeeded. 372 */ 373 static bool decode_pixels_to_8888(SkImageDecoder* decoder, SkStream* stream, 374 SkBitmap* bitmap, void* target) { 375 SkASSERT(decoder != NULL); 376 SkASSERT(stream != NULL); 377 SkASSERT(bitmap != NULL); 378 SkASSERT(target != NULL); 379 380 TargetAllocator allocator(target); 381 decoder->setAllocator(&allocator); 382 383 bool success = decoder->decode(stream, bitmap, SkImageDecoder::kDecodePixels_Mode); 384 decoder->setAllocator(NULL); 385 386 if (!success) { 387 return false; 388 } 389 390 if (bitmap->config() == SkBitmap::kARGB_8888_Config) { 391 return true; 392 } 393 394 SkBitmap bm8888; 395 if (!bitmap->copyTo(&bm8888, SkBitmap::kARGB_8888_Config, &allocator)) { 396 return false; 397 } 398 399 bitmap->swap(bm8888); 400 return true; 401 } 402 403 bool SkImageDecoder::DecodeMemoryToTarget(const void* buffer, size_t size, 404 SkImage::Info* info, 405 const SkBitmapFactory::Target* target) { 406 if (NULL == info) { 407 return false; 408 } 409 410 // FIXME: Just to get this working, implement in terms of existing 411 // ImageDecoder calls. 412 SkBitmap bm; 413 SkMemoryStream stream(buffer, size); 414 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream)); 415 if (NULL == decoder.get()) { 416 return false; 417 } 418 419 if (!decode_bounds_to_8888(decoder.get(), &stream, &bm)) { 420 return false; 421 } 422 423 SkASSERT(bm.config() == SkBitmap::kARGB_8888_Config); 424 425 // Now set info properly. 426 // Since Config is SkBitmap::kARGB_8888_Config, SkBitmapToImageInfo 427 // will always succeed. 428 SkAssertResult(SkBitmapToImageInfo(bm, info)); 429 430 if (NULL == target) { 431 return true; 432 } 433 434 if (target->fRowBytes != SkToU32(bm.rowBytes())) { 435 if (target->fRowBytes < SkImageMinRowBytes(*info)) { 436 SkASSERT(!"Desired row bytes is too small"); 437 return false; 438 } 439 bm.setConfig(bm.config(), bm.width(), bm.height(), target->fRowBytes); 440 } 441 442 // SkMemoryStream.rewind() will always return true. 443 SkAssertResult(stream.rewind()); 444 return decode_pixels_to_8888(decoder.get(), &stream, &bm, target->fAddr); 445 } 446 447 448 bool SkImageDecoder::DecodeStream(SkStream* stream, SkBitmap* bm, 449 SkBitmap::Config pref, Mode mode, Format* format) { 450 SkASSERT(stream); 451 SkASSERT(bm); 452 453 bool success = false; 454 SkImageDecoder* codec = SkImageDecoder::Factory(stream); 455 456 if (NULL != codec) { 457 success = codec->decode(stream, bm, pref, mode); 458 if (success && format) { 459 *format = codec->getFormat(); 460 if (kUnknown_Format == *format) { 461 if (stream->rewind()) { 462 *format = GetStreamFormat(stream); 463 } 464 } 465 } 466 delete codec; 467 } 468 return success; 469 } 470