Home | History | Annotate | Download | only in images
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      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 
      9 
     10 #include "SkImageDecoder.h"
     11 #include "SkBitmap.h"
     12 #include "SkPixelRef.h"
     13 #include "SkStream.h"
     14 #include "SkTemplates.h"
     15 #include "SkCanvas.h"
     16 
     17 SkVMMemoryReporter::~SkVMMemoryReporter() {
     18 }
     19 
     20 const char *SkImageDecoder::kFormatName[] = {
     21     "Unknown Format",
     22     "BMP",
     23     "GIF",
     24     "ICO",
     25     "JPEG",
     26     "PNG",
     27     "WBMP",
     28     "WEBP",
     29 };
     30 
     31 static SkBitmap::Config gDeviceConfig = SkBitmap::kNo_Config;
     32 
     33 SkBitmap::Config SkImageDecoder::GetDeviceConfig()
     34 {
     35     return gDeviceConfig;
     36 }
     37 
     38 void SkImageDecoder::SetDeviceConfig(SkBitmap::Config config)
     39 {
     40     gDeviceConfig = config;
     41 }
     42 
     43 ///////////////////////////////////////////////////////////////////////////////
     44 
     45 SkImageDecoder::SkImageDecoder()
     46     : fReporter(NULL), fPeeker(NULL), fChooser(NULL), fAllocator(NULL),
     47       fSampleSize(1), fDefaultPref(SkBitmap::kNo_Config), fDitherImage(true),
     48       fUsePrefTable(false),fPreferQualityOverSpeed(false) {
     49 }
     50 
     51 SkImageDecoder::~SkImageDecoder() {
     52     SkSafeUnref(fPeeker);
     53     SkSafeUnref(fChooser);
     54     SkSafeUnref(fAllocator);
     55     SkSafeUnref(fReporter);
     56 }
     57 
     58 SkImageDecoder::Format SkImageDecoder::getFormat() const {
     59     return kUnknown_Format;
     60 }
     61 
     62 SkImageDecoder::Peeker* SkImageDecoder::setPeeker(Peeker* peeker) {
     63     SkRefCnt_SafeAssign(fPeeker, peeker);
     64     return peeker;
     65 }
     66 
     67 SkImageDecoder::Chooser* SkImageDecoder::setChooser(Chooser* chooser) {
     68     SkRefCnt_SafeAssign(fChooser, chooser);
     69     return chooser;
     70 }
     71 
     72 SkBitmap::Allocator* SkImageDecoder::setAllocator(SkBitmap::Allocator* alloc) {
     73     SkRefCnt_SafeAssign(fAllocator, alloc);
     74     return alloc;
     75 }
     76 
     77 SkVMMemoryReporter* SkImageDecoder::setReporter(SkVMMemoryReporter* reporter) {
     78     SkRefCnt_SafeAssign(fReporter, reporter);
     79     return reporter;
     80 }
     81 
     82 void SkImageDecoder::setSampleSize(int size) {
     83     if (size < 1) {
     84         size = 1;
     85     }
     86     fSampleSize = size;
     87 }
     88 
     89 bool SkImageDecoder::chooseFromOneChoice(SkBitmap::Config config, int width,
     90                                          int height) const {
     91     Chooser* chooser = fChooser;
     92 
     93     if (NULL == chooser) {    // no chooser, we just say YES to decoding :)
     94         return true;
     95     }
     96     chooser->begin(1);
     97     chooser->inspect(0, config, width, height);
     98     return chooser->choose() == 0;
     99 }
    100 
    101 bool SkImageDecoder::allocPixelRef(SkBitmap* bitmap,
    102                                    SkColorTable* ctable) const {
    103     return bitmap->allocPixels(fAllocator, ctable);
    104 }
    105 
    106 ///////////////////////////////////////////////////////////////////////////////
    107 
    108 void SkImageDecoder::setPrefConfigTable(const SkBitmap::Config pref[6]) {
    109     if (NULL == pref) {
    110         fUsePrefTable = false;
    111     } else {
    112         fUsePrefTable = true;
    113         memcpy(fPrefTable, pref, sizeof(fPrefTable));
    114     }
    115 }
    116 
    117 SkBitmap::Config SkImageDecoder::getPrefConfig(SrcDepth srcDepth,
    118                                                bool srcHasAlpha) const {
    119     SkBitmap::Config config;
    120 
    121     if (fUsePrefTable) {
    122         int index = 0;
    123         switch (srcDepth) {
    124             case kIndex_SrcDepth:
    125                 index = 0;
    126                 break;
    127             case k16Bit_SrcDepth:
    128                 index = 2;
    129                 break;
    130             case k32Bit_SrcDepth:
    131                 index = 4;
    132                 break;
    133         }
    134         if (srcHasAlpha) {
    135             index += 1;
    136         }
    137         config = fPrefTable[index];
    138     } else {
    139         config = fDefaultPref;
    140     }
    141 
    142     if (SkBitmap::kNo_Config == config) {
    143         config = SkImageDecoder::GetDeviceConfig();
    144     }
    145     return config;
    146 }
    147 
    148 bool SkImageDecoder::decode(SkStream* stream, SkBitmap* bm,
    149                             SkBitmap::Config pref, Mode mode, bool reuseBitmap) {
    150     // pass a temporary bitmap, so that if we return false, we are assured of
    151     // leaving the caller's bitmap untouched.
    152     SkBitmap    tmp;
    153 
    154     // we reset this to false before calling onDecode
    155     fShouldCancelDecode = false;
    156     // assign this, for use by getPrefConfig(), in case fUsePrefTable is false
    157     fDefaultPref = pref;
    158 
    159     if (reuseBitmap) {
    160         SkAutoLockPixels alp(*bm);
    161         if (bm->getPixels() != NULL) {
    162             return this->onDecode(stream, bm, mode);
    163         }
    164     }
    165     if (!this->onDecode(stream, &tmp, mode)) {
    166         return false;
    167     }
    168     bm->swap(tmp);
    169     return true;
    170 }
    171 
    172 bool SkImageDecoder::decodeRegion(SkBitmap* bm, SkIRect rect,
    173                                   SkBitmap::Config pref) {
    174     // we reset this to false before calling onDecodeRegion
    175     fShouldCancelDecode = false;
    176     // assign this, for use by getPrefConfig(), in case fUsePrefTable is false
    177     fDefaultPref = pref;
    178 
    179     if (!this->onDecodeRegion(bm, rect)) {
    180         return false;
    181     }
    182     return true;
    183 }
    184 
    185 bool SkImageDecoder::buildTileIndex(SkStream* stream,
    186                                 int *width, int *height) {
    187     // we reset this to false before calling onBuildTileIndex
    188     fShouldCancelDecode = false;
    189 
    190     return this->onBuildTileIndex(stream, width, height);
    191 }
    192 
    193 void SkImageDecoder::cropBitmap(SkBitmap *dest, SkBitmap *src,
    194                                     int sampleSize, int destX, int destY,
    195                                     int width, int height, int srcX, int srcY) {
    196     int w = width / sampleSize;
    197     int h = height / sampleSize;
    198     // if the destination has no pixels then we must allocate them.
    199     if (dest->isNull()) {
    200         dest->setConfig(src->getConfig(), w, h);
    201         dest->setIsOpaque(src->isOpaque());
    202 
    203         if (!this->allocPixelRef(dest, NULL)) {
    204             SkDEBUGF(("failed to allocate pixels needed to crop the bitmap"));
    205             return;
    206         }
    207     }
    208     // check to see if the destination is large enough to decode the desired
    209     // region. If this assert fails we will just draw as much of the source
    210     // into the destination that we can.
    211     SkASSERT(dest->width() >= w && dest->height() >= h);
    212 
    213     // Set the Src_Mode for the paint to prevent transparency issue in the
    214     // dest in the event that the dest was being re-used.
    215     SkPaint paint;
    216     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
    217 
    218     SkCanvas canvas(*dest);
    219     canvas.drawSprite(*src, (srcX - destX) / sampleSize,
    220                             (srcY - destY) / sampleSize,
    221                             &paint);
    222 }
    223 
    224 ///////////////////////////////////////////////////////////////////////////////
    225 
    226 bool SkImageDecoder::DecodeFile(const char file[], SkBitmap* bm,
    227                             SkBitmap::Config pref,  Mode mode, Format* format) {
    228     SkASSERT(file);
    229     SkASSERT(bm);
    230 
    231     SkFILEStream    stream(file);
    232     if (stream.isValid()) {
    233         if (SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format)) {
    234             bm->pixelRef()->setURI(file);
    235             return true;
    236         }
    237     }
    238     return false;
    239 }
    240 
    241 bool SkImageDecoder::DecodeMemory(const void* buffer, size_t size, SkBitmap* bm,
    242                           SkBitmap::Config pref, Mode mode, Format* format) {
    243     if (0 == size) {
    244         return false;
    245     }
    246     SkASSERT(buffer);
    247 
    248     SkMemoryStream  stream(buffer, size);
    249     return SkImageDecoder::DecodeStream(&stream, bm, pref, mode, format);
    250 }
    251 
    252 bool SkImageDecoder::DecodeStream(SkStream* stream, SkBitmap* bm,
    253                           SkBitmap::Config pref, Mode mode, Format* format) {
    254     SkASSERT(stream);
    255     SkASSERT(bm);
    256 
    257     bool success = false;
    258     SkImageDecoder* codec = SkImageDecoder::Factory(stream);
    259 
    260     if (NULL != codec) {
    261         success = codec->decode(stream, bm, pref, mode);
    262         if (success && format) {
    263             *format = codec->getFormat();
    264         }
    265         delete codec;
    266     }
    267     return success;
    268 }
    269