Home | History | Annotate | Download | only in images
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      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 #include "SkImageRef.h"
      9 #include "SkBitmap.h"
     10 #include "SkFlattenable.h"
     11 #include "SkImageDecoder.h"
     12 #include "SkStream.h"
     13 #include "SkTemplates.h"
     14 #include "SkThread.h"
     15 
     16 //#define DUMP_IMAGEREF_LIFECYCLE
     17 
     18 // can't be static, as SkImageRef_Pool needs to see it
     19 SK_DECLARE_GLOBAL_MUTEX(gImageRefMutex);
     20 
     21 ///////////////////////////////////////////////////////////////////////////////
     22 
     23 SkImageRef::SkImageRef(SkStream* stream, SkBitmap::Config config,
     24                        int sampleSize)
     25         : SkPixelRef(&gImageRefMutex), fErrorInDecoding(false) {
     26     SkASSERT(stream);
     27     stream->ref();
     28     fStream = stream;
     29     fConfig = config;
     30     fSampleSize = sampleSize;
     31     fDoDither = true;
     32     fPrev = fNext = NULL;
     33     fFactory = NULL;
     34 
     35 #ifdef DUMP_IMAGEREF_LIFECYCLE
     36     SkDebugf("add ImageRef %p [%d] data=%d\n",
     37               this, config, (int)stream->getLength());
     38 #endif
     39 }
     40 
     41 SkImageRef::~SkImageRef() {
     42     SkASSERT(&gImageRefMutex == this->mutex());
     43 
     44 #ifdef DUMP_IMAGEREF_LIFECYCLE
     45     SkDebugf("delete ImageRef %p [%d] data=%d\n",
     46               this, fConfig, (int)fStream->getLength());
     47 #endif
     48 
     49     fStream->unref();
     50     SkSafeUnref(fFactory);
     51 }
     52 
     53 bool SkImageRef::getInfo(SkBitmap* bitmap) {
     54     SkAutoMutexAcquire ac(gImageRefMutex);
     55 
     56     if (!this->prepareBitmap(SkImageDecoder::kDecodeBounds_Mode)) {
     57         return false;
     58     }
     59 
     60     SkASSERT(SkBitmap::kNo_Config != fBitmap.config());
     61     if (bitmap) {
     62         bitmap->setConfig(fBitmap.config(), fBitmap.width(), fBitmap.height());
     63     }
     64     return true;
     65 }
     66 
     67 bool SkImageRef::isOpaque(SkBitmap* bitmap) {
     68     if (bitmap && bitmap->pixelRef() == this) {
     69         bitmap->lockPixels();
     70         bitmap->setIsOpaque(fBitmap.isOpaque());
     71         bitmap->unlockPixels();
     72         return true;
     73     }
     74     return false;
     75 }
     76 
     77 SkImageDecoderFactory* SkImageRef::setDecoderFactory(
     78                                                 SkImageDecoderFactory* fact) {
     79     SkRefCnt_SafeAssign(fFactory, fact);
     80     return fact;
     81 }
     82 
     83 ///////////////////////////////////////////////////////////////////////////////
     84 
     85 bool SkImageRef::onDecode(SkImageDecoder* codec, SkStream* stream,
     86                           SkBitmap* bitmap, SkBitmap::Config config,
     87                           SkImageDecoder::Mode mode) {
     88     return codec->decode(stream, bitmap, config, mode);
     89 }
     90 
     91 bool SkImageRef::prepareBitmap(SkImageDecoder::Mode mode) {
     92     SkASSERT(&gImageRefMutex == this->mutex());
     93 
     94     if (fErrorInDecoding) {
     95         return false;
     96     }
     97 
     98     /*  As soon as we really know our config, we record it, so that on
     99         subsequent calls to the codec, we are sure we will always get the same
    100         result.
    101     */
    102     if (SkBitmap::kNo_Config != fBitmap.config()) {
    103         fConfig = fBitmap.config();
    104     }
    105 
    106     if (NULL != fBitmap.getPixels() ||
    107             (SkBitmap::kNo_Config != fBitmap.config() &&
    108              SkImageDecoder::kDecodeBounds_Mode == mode)) {
    109         return true;
    110     }
    111 
    112     SkASSERT(fBitmap.getPixels() == NULL);
    113 
    114     fStream->rewind();
    115 
    116     SkImageDecoder* codec;
    117     if (fFactory) {
    118         codec = fFactory->newDecoder(fStream);
    119     } else {
    120         codec = SkImageDecoder::Factory(fStream);
    121     }
    122 
    123     if (codec) {
    124         SkAutoTDelete<SkImageDecoder> ad(codec);
    125 
    126         codec->setSampleSize(fSampleSize);
    127         codec->setDitherImage(fDoDither);
    128         if (this->onDecode(codec, fStream, &fBitmap, fConfig, mode)) {
    129             return true;
    130         }
    131     }
    132 
    133 #ifdef DUMP_IMAGEREF_LIFECYCLE
    134     if (NULL == codec) {
    135         SkDebugf("--- ImageRef: <%s> failed to find codec\n", this->getURI());
    136     } else {
    137         SkDebugf("--- ImageRef: <%s> failed in codec for %d mode\n",
    138                  this->getURI(), mode);
    139     }
    140 #endif
    141     fErrorInDecoding = true;
    142     fBitmap.reset();
    143     return false;
    144 }
    145 
    146 void* SkImageRef::onLockPixels(SkColorTable** ct) {
    147     SkASSERT(&gImageRefMutex == this->mutex());
    148 
    149     if (NULL == fBitmap.getPixels()) {
    150         (void)this->prepareBitmap(SkImageDecoder::kDecodePixels_Mode);
    151     }
    152 
    153     if (ct) {
    154         *ct = fBitmap.getColorTable();
    155     }
    156     return fBitmap.getPixels();
    157 }
    158 
    159 void SkImageRef::onUnlockPixels() {
    160     // we're already have the mutex locked
    161     SkASSERT(&gImageRefMutex == this->mutex());
    162 }
    163 
    164 size_t SkImageRef::ramUsed() const {
    165     size_t size = 0;
    166 
    167     if (fBitmap.getPixels()) {
    168         size = fBitmap.getSize();
    169         if (fBitmap.getColorTable()) {
    170             size += fBitmap.getColorTable()->count() * sizeof(SkPMColor);
    171         }
    172     }
    173     return size;
    174 }
    175 
    176 ///////////////////////////////////////////////////////////////////////////////
    177 
    178 SkImageRef::SkImageRef(SkFlattenableReadBuffer& buffer)
    179         : INHERITED(buffer, &gImageRefMutex), fErrorInDecoding(false) {
    180     fConfig = (SkBitmap::Config)buffer.readU8();
    181     fSampleSize = buffer.readU8();
    182     fDoDither = buffer.readBool();
    183 
    184     size_t length = buffer.readU32();
    185     fStream = SkNEW_ARGS(SkMemoryStream, (length));
    186     buffer.read((void*)fStream->getMemoryBase(), length);
    187 
    188     fPrev = fNext = NULL;
    189     fFactory = NULL;
    190 }
    191 
    192 void SkImageRef::flatten(SkFlattenableWriteBuffer& buffer) const {
    193     this->INHERITED::flatten(buffer);
    194 
    195     buffer.write8(fConfig);
    196     buffer.write8(fSampleSize);
    197     buffer.writeBool(fDoDither);
    198     size_t length = fStream->getLength();
    199     buffer.write32(length);
    200     fStream->rewind();
    201     buffer.readFromStream(fStream, length);
    202 }
    203 
    204