Home | History | Annotate | Download | only in images
      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