1 /* 2 * Copyright 2007, The Android Open Source Project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 #include "BitmapAllocatorAndroid.h" 28 #include "ImageSource.h" 29 #include "IntSize.h" 30 #include "NotImplemented.h" 31 #include "SharedBuffer.h" 32 #include "PlatformString.h" 33 34 #include "SkBitmapRef.h" 35 #include "SkImageDecoder.h" 36 #include "SkImageRef.h" 37 #include "SkStream.h" 38 #include "SkTemplates.h" 39 40 #ifdef ANDROID_ANIMATED_GIF 41 #include "EmojiFont.h" 42 #include "GIFImageDecoder.h" 43 44 using namespace android; 45 #endif 46 47 // TODO: We should make use of some of the common code in platform/graphics/ImageSource.cpp. 48 49 SkPixelRef* SkCreateRLEPixelRef(const SkBitmap& src); 50 51 //#define TRACE_SUBSAMPLE_BITMAPS 52 //#define TRACE_RLE_BITMAPS 53 54 55 // flag to tell us when we're on a large-ram device (e.g. >= 256M) 56 #ifdef ANDROID_LARGE_MEMORY_DEVICE 57 // don't use RLE for images smaller than this, since they incur a drawing cost 58 // (and don't work as patterns yet) we only want to use RLE when we must 59 #define MIN_RLE_ALLOC_SIZE (8*1024*1024) 60 61 // see dox for computeMaxBitmapSizeForCache() 62 #define MAX_SIZE_BEFORE_SUBSAMPLE (32*1024*1024) 63 64 // preserve quality for 24/32bit src 65 static const SkBitmap::Config gPrefConfigTable[6] = { 66 SkBitmap::kIndex8_Config, // src: index, opaque 67 SkBitmap::kIndex8_Config, // src: index, alpha 68 SkBitmap::kRGB_565_Config, // src: 16bit, opaque 69 SkBitmap::kARGB_8888_Config, // src: 16bit, alpha (promote to 32bit) 70 SkBitmap::kARGB_8888_Config, // src: 32bit, opaque 71 SkBitmap::kARGB_8888_Config, // src: 32bit, alpha 72 }; 73 #else 74 #define MIN_RLE_ALLOC_SIZE (2*1024*1024) 75 #define MAX_SIZE_BEFORE_SUBSAMPLE (2*1024*1024) 76 77 // tries to minimize memory usage (i.e. demote opaque 32bit -> 16bit) 78 static const SkBitmap::Config gPrefConfigTable[6] = { 79 SkBitmap::kIndex8_Config, // src: index, opaque 80 SkBitmap::kIndex8_Config, // src: index, alpha 81 SkBitmap::kRGB_565_Config, // src: 16bit, opaque 82 SkBitmap::kARGB_8888_Config, // src: 16bit, alpha (promote to 32bit) 83 SkBitmap::kRGB_565_Config, // src: 32bit, opaque (demote to 16bit) 84 SkBitmap::kARGB_8888_Config, // src: 32bit, alpha 85 }; 86 #endif 87 88 /* Images larger than this should be subsampled. Using ashmem, the decoded 89 pixels will be purged as needed, so this value can be pretty large. Making 90 it too small hurts image quality (e.g. abc.com background). 2Meg works for 91 the sites I've tested, but if we hit important sites that need more, we 92 should try increasing it and see if it has negative impact on performance 93 (i.e. we end up thrashing because we need to keep decoding images that have 94 been purged. 95 96 Perhaps this value should be some fraction of the available RAM... 97 */ 98 size_t computeMaxBitmapSizeForCache() { 99 return MAX_SIZE_BEFORE_SUBSAMPLE; 100 } 101 102 /* 8bit images larger than this should be recompressed in RLE, to reduce 103 on the imageref cache. 104 105 Downside: performance, since we have to decode/encode 106 and then rle-decode when we draw. 107 */ 108 static bool shouldReencodeAsRLE(const SkBitmap& bm) { 109 const SkBitmap::Config c = bm.config(); 110 return (SkBitmap::kIndex8_Config == c || SkBitmap::kA8_Config == c) 111 && 112 bm.width() >= 64 // narrower than this won't compress well in RLE 113 && 114 bm.getSize() > MIN_RLE_ALLOC_SIZE; 115 } 116 117 /////////////////////////////////////////////////////////////////////////////// 118 119 class PrivateAndroidImageSourceRec : public SkBitmapRef { 120 public: 121 PrivateAndroidImageSourceRec(const SkBitmap& bm, int origWidth, 122 int origHeight, int sampleSize) 123 : SkBitmapRef(bm), fSampleSize(sampleSize), fAllDataReceived(false) { 124 this->setOrigSize(origWidth, origHeight); 125 } 126 127 int fSampleSize; 128 bool fAllDataReceived; 129 }; 130 131 namespace WebCore { 132 133 ImageSource::ImageSource(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption) 134 : m_alphaOption(alphaOption) 135 , m_gammaAndColorProfileOption(gammaAndColorProfileOption) 136 { 137 m_decoder.m_image = NULL; 138 #ifdef ANDROID_ANIMATED_GIF 139 m_decoder.m_gifDecoder = 0; 140 #endif 141 } 142 143 ImageSource::~ImageSource() { 144 delete m_decoder.m_image; 145 #ifdef ANDROID_ANIMATED_GIF 146 delete m_decoder.m_gifDecoder; 147 #endif 148 } 149 150 bool ImageSource::initialized() const { 151 return 152 #ifdef ANDROID_ANIMATED_GIF 153 m_decoder.m_gifDecoder || 154 #endif 155 m_decoder.m_image != NULL; 156 } 157 158 static int computeSampleSize(const SkBitmap& bitmap) { 159 const size_t maxSize = computeMaxBitmapSizeForCache(); 160 size_t size = bitmap.getSize(); 161 int sampleSize = 1; 162 163 while (size > maxSize) { 164 sampleSize <<= 1; 165 size >>= 2; 166 } 167 168 #ifdef TRACE_SUBSAMPLE_BITMAPS 169 if (sampleSize > 1) { 170 SkDebugf("------- bitmap [%d %d] config=%d origSize=%d predictSize=%d sampleSize=%d\n", 171 bitmap.width(), bitmap.height(), bitmap.config(), 172 bitmap.getSize(), size, sampleSize); 173 } 174 #endif 175 return sampleSize; 176 } 177 178 static SkPixelRef* convertToRLE(SkBitmap* bm, const void* data, size_t len) { 179 if (!shouldReencodeAsRLE(*bm)) { 180 return NULL; 181 } 182 183 SkBitmap tmp; 184 185 if (!SkImageDecoder::DecodeMemory(data, len, &tmp) || !tmp.getPixels()) { 186 return NULL; 187 } 188 189 SkPixelRef* ref = SkCreateRLEPixelRef(tmp); 190 if (NULL == ref) { 191 return NULL; 192 } 193 194 #ifdef TRACE_RLE_BITMAPS 195 SkDebugf("---- reencode bitmap as RLE: [%d %d] encodeSize=%d\n", 196 tmp.width(), tmp.height(), len); 197 #endif 198 199 bm->setConfig(SkBitmap::kRLE_Index8_Config, tmp.width(), tmp.height()); 200 return ref; 201 } 202 203 void ImageSource::clearURL() 204 { 205 m_decoder.m_url.reset(); 206 } 207 208 void ImageSource::setURL(const String& url) 209 { 210 m_decoder.m_url.setUTF16(url.characters(), url.length()); 211 } 212 213 #ifdef ANDROID_ANIMATED_GIF 214 // we only animate small GIFs for now, to save memory 215 // also, we only support this in Japan, hence the Emoji check 216 static bool should_use_animated_gif(int width, int height) { 217 #ifdef ANDROID_LARGE_MEMORY_DEVICE 218 return true; 219 #else 220 return EmojiFont::IsAvailable() && 221 width <= 32 && height <= 32; 222 #endif 223 } 224 #endif 225 226 void ImageSource::setData(SharedBuffer* data, bool allDataReceived) 227 { 228 #ifdef ANDROID_ANIMATED_GIF 229 // This is only necessary if we allow ourselves to partially decode GIF 230 bool disabledAnimatedGif = false; 231 if (m_decoder.m_gifDecoder 232 && !m_decoder.m_gifDecoder->failed()) { 233 m_decoder.m_gifDecoder->setData(data, allDataReceived); 234 if (!allDataReceived || m_decoder.m_gifDecoder->frameCount() != 1) 235 return; 236 disabledAnimatedGif = true; 237 delete m_decoder.m_gifDecoder; 238 m_decoder.m_gifDecoder = 0; 239 } 240 #endif 241 if (NULL == m_decoder.m_image 242 #ifdef ANDROID_ANIMATED_GIF 243 && !m_decoder.m_gifDecoder 244 #endif 245 ) { 246 SkBitmap tmp; 247 248 SkMemoryStream stream(data->data(), data->size(), false); 249 SkImageDecoder* codec = SkImageDecoder::Factory(&stream); 250 if (!codec) 251 return; 252 253 SkAutoTDelete<SkImageDecoder> ad(codec); 254 codec->setPrefConfigTable(gPrefConfigTable); 255 if (!codec->decode(&stream, &tmp, SkImageDecoder::kDecodeBounds_Mode)) 256 return; 257 258 int origW = tmp.width(); 259 int origH = tmp.height(); 260 261 #ifdef ANDROID_ANIMATED_GIF 262 // First, check to see if this is an animated GIF 263 const char* contents = data->data(); 264 if (data->size() > 3 && strncmp(contents, "GIF8", 4) == 0 265 && should_use_animated_gif(origW, origH) 266 && !disabledAnimatedGif) { 267 // This means we are looking at a GIF, so create special 268 // GIF Decoder 269 // Need to wait for all data received if we are assigning an 270 // allocator (which we are not at the moment). 271 if (!m_decoder.m_gifDecoder /*&& allDataReceived*/) 272 m_decoder.m_gifDecoder = new GIFImageDecoder(m_alphaOption, m_gammaAndColorProfileOption); 273 int frameCount = 0; 274 if (!m_decoder.m_gifDecoder->failed()) { 275 m_decoder.m_gifDecoder->setData(data, allDataReceived); 276 if (!allDataReceived) 277 return; 278 frameCount = m_decoder.m_gifDecoder->frameCount(); 279 } 280 if (frameCount != 1) 281 return; 282 delete m_decoder.m_gifDecoder; 283 m_decoder.m_gifDecoder = 0; 284 } 285 #endif 286 287 int sampleSize = computeSampleSize(tmp); 288 if (sampleSize > 1) { 289 codec->setSampleSize(sampleSize); 290 stream.rewind(); 291 if (!codec->decode(&stream, &tmp, 292 SkImageDecoder::kDecodeBounds_Mode)) { 293 return; 294 } 295 } 296 297 m_decoder.m_image = new PrivateAndroidImageSourceRec(tmp, origW, origH, 298 sampleSize); 299 300 // SkDebugf("----- started: [%d %d] %s\n", origW, origH, m_decoder.m_url.c_str()); 301 } 302 303 PrivateAndroidImageSourceRec* decoder = m_decoder.m_image; 304 if (allDataReceived && decoder && !decoder->fAllDataReceived) { 305 decoder->fAllDataReceived = true; 306 307 SkBitmap* bm = &decoder->bitmap(); 308 SkPixelRef* ref = convertToRLE(bm, data->data(), data->size()); 309 310 if (ref) { 311 bm->setPixelRef(ref)->unref(); 312 } else { 313 BitmapAllocatorAndroid alloc(data, decoder->fSampleSize); 314 if (!alloc.allocPixelRef(bm, NULL)) { 315 return; 316 } 317 ref = bm->pixelRef(); 318 } 319 320 // we promise to never change the pixels (makes picture recording fast) 321 ref->setImmutable(); 322 // give it the URL if we have one 323 ref->setURI(m_decoder.m_url); 324 } 325 } 326 327 bool ImageSource::isSizeAvailable() 328 { 329 return 330 #ifdef ANDROID_ANIMATED_GIF 331 (m_decoder.m_gifDecoder 332 && m_decoder.m_gifDecoder->isSizeAvailable()) || 333 #endif 334 m_decoder.m_image != NULL; 335 } 336 337 IntSize ImageSource::size() const 338 { 339 #ifdef ANDROID_ANIMATED_GIF 340 if (m_decoder.m_gifDecoder) 341 return m_decoder.m_gifDecoder->size(); 342 #endif 343 if (m_decoder.m_image) { 344 return IntSize(m_decoder.m_image->origWidth(), m_decoder.m_image->origHeight()); 345 } 346 return IntSize(0, 0); 347 } 348 349 int ImageSource::repetitionCount() 350 { 351 #ifdef ANDROID_ANIMATED_GIF 352 if (m_decoder.m_gifDecoder) 353 return m_decoder.m_gifDecoder->repetitionCount(); 354 if (!m_decoder.m_image) return 0; 355 #endif 356 return 1; 357 // A property with value 0 means loop forever. 358 } 359 360 size_t ImageSource::frameCount() const 361 { 362 #ifdef ANDROID_ANIMATED_GIF 363 if (m_decoder.m_gifDecoder) { 364 return m_decoder.m_gifDecoder->failed() ? 0 365 : m_decoder.m_gifDecoder->frameCount(); 366 } 367 #endif 368 // i.e. 0 frames if we're not decoded, or 1 frame if we are 369 return m_decoder.m_image != NULL; 370 } 371 372 SkBitmapRef* ImageSource::createFrameAtIndex(size_t index) 373 { 374 #ifdef ANDROID_ANIMATED_GIF 375 if (m_decoder.m_gifDecoder) { 376 ImageFrame* buffer = 377 m_decoder.m_gifDecoder->frameBufferAtIndex(index); 378 if (!buffer || buffer->status() == ImageFrame::FrameEmpty) 379 return 0; 380 SkBitmap& bitmap = buffer->bitmap(); 381 SkPixelRef* pixelRef = bitmap.pixelRef(); 382 if (pixelRef) 383 pixelRef->setURI(m_decoder.m_url); 384 return new SkBitmapRef(bitmap); 385 } 386 #else 387 SkASSERT(index == 0); 388 #endif 389 SkASSERT(m_decoder.m_image != NULL); 390 m_decoder.m_image->ref(); 391 return m_decoder.m_image; 392 } 393 394 float ImageSource::frameDurationAtIndex(size_t index) 395 { 396 float duration = 0; 397 #ifdef ANDROID_ANIMATED_GIF 398 if (m_decoder.m_gifDecoder) { 399 ImageFrame* buffer 400 = m_decoder.m_gifDecoder->frameBufferAtIndex(index); 401 if (!buffer || buffer->status() == ImageFrame::FrameEmpty) 402 return 0; 403 duration = buffer->duration() / 1000.0f; 404 } 405 #else 406 SkASSERT(index == 0); 407 #endif 408 409 // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. 410 // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify 411 // a duration of <= 10 ms. See gfxImageFrame::GetTimeout in Gecko or Radar 4051389 for more. 412 if (duration <= 0.010f) 413 duration = 0.100f; 414 return duration; 415 } 416 417 bool ImageSource::frameHasAlphaAtIndex(size_t index) 418 { 419 #ifdef ANDROID_ANIMATED_GIF 420 if (m_decoder.m_gifDecoder) { 421 ImageFrame* buffer = 422 m_decoder.m_gifDecoder->frameBufferAtIndex(index); 423 if (!buffer || buffer->status() == ImageFrame::FrameEmpty) 424 return false; 425 426 return buffer->hasAlpha(); 427 } 428 #else 429 SkASSERT(0 == index); 430 #endif 431 432 if (NULL == m_decoder.m_image) 433 return true; // if we're not sure, assume the worse-case 434 const PrivateAndroidImageSourceRec& decoder = *m_decoder.m_image; 435 // if we're 16bit, we know even without all the data available 436 if (decoder.bitmap().getConfig() == SkBitmap::kRGB_565_Config) 437 return false; 438 439 if (!decoder.fAllDataReceived) 440 return true; // if we're not sure, assume the worse-case 441 442 return !decoder.bitmap().isOpaque(); 443 } 444 445 bool ImageSource::frameIsCompleteAtIndex(size_t index) 446 { 447 #ifdef ANDROID_ANIMATED_GIF 448 if (m_decoder.m_gifDecoder) { 449 ImageFrame* buffer = 450 m_decoder.m_gifDecoder->frameBufferAtIndex(index); 451 return buffer && buffer->status() == ImageFrame::FrameComplete; 452 } 453 #else 454 SkASSERT(0 == index); 455 #endif 456 return m_decoder.m_image && m_decoder.m_image->fAllDataReceived; 457 } 458 459 void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame, SharedBuffer* data, bool allDataReceived) 460 { 461 #ifdef ANDROID_ANIMATED_GIF 462 if (!destroyAll) { 463 if (m_decoder.m_gifDecoder) 464 m_decoder.m_gifDecoder->clearFrameBufferCache(clearBeforeFrame); 465 return; 466 } 467 468 delete m_decoder.m_gifDecoder; 469 m_decoder.m_gifDecoder = 0; 470 if (data) 471 setData(data, allDataReceived); 472 #endif 473 // do nothing, since the cache is managed elsewhere 474 } 475 476 IntSize ImageSource::frameSizeAtIndex(size_t index) const 477 { 478 // for now, all (1) of our frames are the same size 479 return this->size(); 480 } 481 482 String ImageSource::filenameExtension() const 483 { 484 // FIXME: need to add virtual to our decoders to return "jpg/png/gif/..." 485 #ifdef ANDROID_ANIMATED_GIF 486 if (m_decoder.m_gifDecoder) 487 return m_decoder.m_gifDecoder->filenameExtension(); 488 #endif 489 return String(); 490 } 491 492 bool ImageSource::getHotSpot(IntPoint&) const 493 { 494 return false; 495 } 496 497 size_t ImageSource::bytesDecodedToDetermineProperties() const 498 { 499 return 0; 500 } 501 502 } 503