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