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 "SkImageEncoder.h"
     12 #include "SkColor.h"
     13 #include "SkColorPriv.h"
     14 #include "SkDither.h"
     15 #include "SkMath.h"
     16 #include "SkScaledBitmapSampler.h"
     17 #include "SkStream.h"
     18 #include "SkTemplates.h"
     19 #include "SkUtils.h"
     20 #include "transform_scanline.h"
     21 
     22 extern "C" {
     23 #include "png.h"
     24 }
     25 
     26 class SkPNGImageIndex {
     27 public:
     28     SkPNGImageIndex() {
     29         inputStream = NULL;
     30         png_ptr = NULL;
     31     }
     32     virtual ~SkPNGImageIndex() {
     33         if (png_ptr) {
     34             png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
     35         }
     36         if (inputStream) {
     37             delete inputStream;
     38         }
     39     }
     40     png_structp png_ptr;
     41     png_infop info_ptr;
     42     SkStream *inputStream;
     43 };
     44 
     45 class SkPNGImageDecoder : public SkImageDecoder {
     46 public:
     47     SkPNGImageDecoder() {
     48         index = NULL;
     49     }
     50     virtual Format getFormat() const {
     51         return kPNG_Format;
     52     }
     53     virtual ~SkPNGImageDecoder() {
     54         if (index) {
     55             delete index;
     56         }
     57     }
     58 
     59 protected:
     60     virtual bool onBuildTileIndex(SkStream *stream,
     61              int *width, int *height);
     62     virtual bool onDecodeRegion(SkBitmap* bitmap, SkIRect region);
     63     virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode);
     64 
     65 private:
     66     bool onDecodeInit(SkStream* stream, png_structp *png_ptrp,
     67             png_infop *info_ptrp);
     68     bool decodePalette(png_structp png_ptr, png_infop info_ptr,
     69         bool *hasAlphap, bool *reallyHasAlphap, SkColorTable **colorTablep);
     70     bool getBitmapConfig(png_structp png_ptr, png_infop info_ptr,
     71         SkBitmap::Config *config, bool *hasAlpha, bool *doDither,
     72         SkPMColor *theTranspColor);
     73     SkPNGImageIndex *index;
     74 };
     75 
     76 #ifndef png_jmpbuf
     77 #  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
     78 #endif
     79 
     80 #define PNG_BYTES_TO_CHECK 4
     81 
     82 /* Automatically clean up after throwing an exception */
     83 struct PNGAutoClean {
     84     PNGAutoClean(png_structp p, png_infop i): png_ptr(p), info_ptr(i) {}
     85     ~PNGAutoClean() {
     86         png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
     87     }
     88 private:
     89     png_structp png_ptr;
     90     png_infop info_ptr;
     91 };
     92 
     93 static void sk_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) {
     94     SkStream* sk_stream = (SkStream*) png_ptr->io_ptr;
     95     size_t bytes = sk_stream->read(data, length);
     96     if (bytes != length) {
     97         png_error(png_ptr, "Read Error!");
     98     }
     99 }
    100 
    101 static void sk_seek_fn(png_structp png_ptr, png_uint_32 offset) {
    102     SkStream* sk_stream = (SkStream*) png_ptr->io_ptr;
    103     sk_stream->rewind();
    104     (void)sk_stream->skip(offset);
    105 }
    106 
    107 static int sk_read_user_chunk(png_structp png_ptr, png_unknown_chunkp chunk) {
    108     SkImageDecoder::Peeker* peeker =
    109                     (SkImageDecoder::Peeker*)png_get_user_chunk_ptr(png_ptr);
    110     // peek() returning true means continue decoding
    111     return peeker->peek((const char*)chunk->name, chunk->data, chunk->size) ?
    112             1 : -1;
    113 }
    114 
    115 static void sk_error_fn(png_structp png_ptr, png_const_charp msg) {
    116 #if 0
    117     SkDebugf("------ png error %s\n", msg);
    118 #endif
    119     longjmp(png_jmpbuf(png_ptr), 1);
    120 }
    121 
    122 static void skip_src_rows(png_structp png_ptr, uint8_t storage[], int count) {
    123     for (int i = 0; i < count; i++) {
    124         uint8_t* tmp = storage;
    125         png_read_rows(png_ptr, &tmp, png_bytepp_NULL, 1);
    126     }
    127 }
    128 
    129 static bool pos_le(int value, int max) {
    130     return value > 0 && value <= max;
    131 }
    132 
    133 static bool substituteTranspColor(SkBitmap* bm, SkPMColor match) {
    134     SkASSERT(bm->config() == SkBitmap::kARGB_8888_Config);
    135 
    136     bool reallyHasAlpha = false;
    137 
    138     for (int y = bm->height() - 1; y >= 0; --y) {
    139         SkPMColor* p = bm->getAddr32(0, y);
    140         for (int x = bm->width() - 1; x >= 0; --x) {
    141             if (match == *p) {
    142                 *p = 0;
    143                 reallyHasAlpha = true;
    144             }
    145             p += 1;
    146         }
    147     }
    148     return reallyHasAlpha;
    149 }
    150 
    151 static bool canUpscalePaletteToConfig(SkBitmap::Config dstConfig,
    152                                       bool srcHasAlpha) {
    153     switch (dstConfig) {
    154         case SkBitmap::kARGB_8888_Config:
    155         case SkBitmap::kARGB_4444_Config:
    156             return true;
    157         case SkBitmap::kRGB_565_Config:
    158             // only return true if the src is opaque (since 565 is opaque)
    159             return !srcHasAlpha;
    160         default:
    161             return false;
    162     }
    163 }
    164 
    165 // call only if color_type is PALETTE. Returns true if the ctable has alpha
    166 static bool hasTransparencyInPalette(png_structp png_ptr, png_infop info_ptr) {
    167     png_bytep trans;
    168     int num_trans;
    169 
    170     if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
    171         png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
    172         return num_trans > 0;
    173     }
    174     return false;
    175 }
    176 
    177 bool SkPNGImageDecoder::onDecodeInit(SkStream* sk_stream,
    178         png_structp *png_ptrp, png_infop *info_ptrp)
    179 {
    180     /* Create and initialize the png_struct with the desired error handler
    181     * functions.  If you want to use the default stderr and longjump method,
    182     * you can supply NULL for the last three parameters.  We also supply the
    183     * the compiler header file version, so that we know if the application
    184     * was compiled with a compatible version of the library.  */
    185     png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
    186         NULL, sk_error_fn, NULL);
    187     //   png_voidp user_error_ptr, user_error_fn, user_warning_fn);
    188     if (png_ptr == NULL) {
    189         return false;
    190     }
    191     *png_ptrp = png_ptr;
    192 
    193     /* Allocate/initialize the memory for image information. */
    194     png_infop info_ptr = png_create_info_struct(png_ptr);
    195     if (info_ptr == NULL) {
    196         png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
    197         return false;
    198     }
    199     *info_ptrp = info_ptr;
    200 
    201     /* Set error handling if you are using the setjmp/longjmp method (this is
    202     * the normal method of doing things with libpng).  REQUIRED unless you
    203     * set up your own error handlers in the png_create_read_struct() earlier.
    204     */
    205     if (setjmp(png_jmpbuf(png_ptr))) {
    206         return false;
    207     }
    208 
    209     /* If you are using replacement read functions, instead of calling
    210     * png_init_io() here you would call:
    211     */
    212     png_set_read_fn(png_ptr, (void *)sk_stream, sk_read_fn);
    213     png_set_seek_fn(png_ptr, sk_seek_fn);
    214     /* where user_io_ptr is a structure you want available to the callbacks */
    215     /* If we have already read some of the signature */
    216     // png_set_sig_bytes(png_ptr, 0 /* sig_read */ );
    217 
    218     // hookup our peeker so we can see any user-chunks the caller may be interested in
    219     png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, (png_byte*)"", 0);
    220     if (this->getPeeker()) {
    221         png_set_read_user_chunk_fn(png_ptr, (png_voidp)this->getPeeker(), sk_read_user_chunk);
    222     }
    223 
    224     /* The call to png_read_info() gives us all of the information from the
    225     * PNG file before the first IDAT (image data chunk). */
    226     png_read_info(png_ptr, info_ptr);
    227     png_uint_32 origWidth, origHeight;
    228     int bit_depth, color_type, interlace_type;
    229     png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bit_depth,
    230             &color_type, &interlace_type, int_p_NULL, int_p_NULL);
    231 
    232     /* tell libpng to strip 16 bit/color files down to 8 bits/color */
    233     if (bit_depth == 16) {
    234         png_set_strip_16(png_ptr);
    235     }
    236     /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
    237      * byte into separate bytes (useful for paletted and grayscale images). */
    238     if (bit_depth < 8) {
    239         png_set_packing(png_ptr);
    240     }
    241     /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
    242     if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
    243         png_set_gray_1_2_4_to_8(png_ptr);
    244     }
    245 
    246     /* Make a grayscale image into RGB. */
    247     if (color_type == PNG_COLOR_TYPE_GRAY ||
    248         color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
    249         png_set_gray_to_rgb(png_ptr);
    250     }
    251     return true;
    252 }
    253 
    254 bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap,
    255                                  Mode mode) {
    256     png_structp png_ptr;
    257     png_infop info_ptr;
    258 
    259     if (onDecodeInit(sk_stream, &png_ptr, &info_ptr) == false) {
    260         return false;
    261     }
    262 
    263     if (setjmp(png_jmpbuf(png_ptr))) {
    264         return false;
    265     }
    266 
    267     PNGAutoClean autoClean(png_ptr, info_ptr);
    268 
    269     png_uint_32 origWidth, origHeight;
    270     int bit_depth, color_type, interlace_type;
    271     png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bit_depth,
    272             &color_type, &interlace_type, int_p_NULL, int_p_NULL);
    273 
    274     SkBitmap::Config    config;
    275     bool                hasAlpha = false;
    276     bool                doDither = this->getDitherImage();
    277     SkPMColor           theTranspColor = 0; // 0 tells us not to try to match
    278 
    279     if (getBitmapConfig(png_ptr, info_ptr, &config, &hasAlpha,
    280                 &doDither, &theTranspColor) == false) {
    281         return false;
    282     }
    283 
    284     const int sampleSize = this->getSampleSize();
    285     SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize);
    286 
    287     decodedBitmap->lockPixels();
    288     void* rowptr = (void*) decodedBitmap->getPixels();
    289     bool reuseBitmap = (rowptr != NULL);
    290     decodedBitmap->unlockPixels();
    291     if (reuseBitmap && (sampler.scaledWidth() != decodedBitmap->width() ||
    292             sampler.scaledHeight() != decodedBitmap->height())) {
    293         // Dimensions must match
    294         return false;
    295     }
    296 
    297     if (!reuseBitmap) {
    298         decodedBitmap->setConfig(config, sampler.scaledWidth(),
    299                                  sampler.scaledHeight(), 0);
    300     }
    301     if (SkImageDecoder::kDecodeBounds_Mode == mode) {
    302         return true;
    303     }
    304 
    305     // from here down we are concerned with colortables and pixels
    306 
    307     // we track if we actually see a non-opaque pixels, since sometimes a PNG sets its colortype
    308     // to |= PNG_COLOR_MASK_ALPHA, but all of its pixels are in fact opaque. We care, since we
    309     // draw lots faster if we can flag the bitmap has being opaque
    310     bool reallyHasAlpha = false;
    311     SkColorTable* colorTable = NULL;
    312 
    313     if (color_type == PNG_COLOR_TYPE_PALETTE) {
    314         decodePalette(png_ptr, info_ptr, &hasAlpha,
    315                 &reallyHasAlpha, &colorTable);
    316     }
    317 
    318     SkAutoUnref aur(colorTable);
    319 
    320     if (!reuseBitmap) {
    321         if (!this->allocPixelRef(decodedBitmap,
    322                                  SkBitmap::kIndex8_Config == config ?
    323                                     colorTable : NULL)) {
    324             return false;
    325         }
    326     }
    327 
    328     SkAutoLockPixels alp(*decodedBitmap);
    329 
    330     /* Add filler (or alpha) byte (before/after each RGB triplet) */
    331     if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY) {
    332         png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
    333     }
    334 
    335     /* Turn on interlace handling.  REQUIRED if you are not using
    336     * png_read_image().  To see how to handle interlacing passes,
    337     * see the png_read_row() method below:
    338     */
    339     const int number_passes = interlace_type != PNG_INTERLACE_NONE ?
    340                         png_set_interlace_handling(png_ptr) : 1;
    341 
    342     /* Optional call to gamma correct and add the background to the palette
    343     * and update info structure.  REQUIRED if you are expecting libpng to
    344     * update the palette for you (ie you selected such a transform above).
    345     */
    346     png_read_update_info(png_ptr, info_ptr);
    347 
    348     if (SkBitmap::kIndex8_Config == config && 1 == sampleSize) {
    349         for (int i = 0; i < number_passes; i++) {
    350             for (png_uint_32 y = 0; y < origHeight; y++) {
    351                 uint8_t* bmRow = decodedBitmap->getAddr8(0, y);
    352                 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
    353             }
    354         }
    355     } else {
    356         SkScaledBitmapSampler::SrcConfig sc;
    357         int srcBytesPerPixel = 4;
    358 
    359         if (colorTable != NULL) {
    360             sc = SkScaledBitmapSampler::kIndex;
    361             srcBytesPerPixel = 1;
    362         } else if (hasAlpha) {
    363             sc = SkScaledBitmapSampler::kRGBA;
    364         } else {
    365             sc = SkScaledBitmapSampler::kRGBX;
    366         }
    367 
    368         /*  We have to pass the colortable explicitly, since we may have one
    369             even if our decodedBitmap doesn't, due to the request that we
    370             upscale png's palette to a direct model
    371          */
    372         SkAutoLockColors ctLock(colorTable);
    373         if (!sampler.begin(decodedBitmap, sc, doDither, ctLock.colors())) {
    374             return false;
    375         }
    376         const int height = decodedBitmap->height();
    377 
    378         if (number_passes > 1) {
    379             SkAutoMalloc storage(origWidth * origHeight * srcBytesPerPixel);
    380             uint8_t* base = (uint8_t*)storage.get();
    381             size_t rb = origWidth * srcBytesPerPixel;
    382 
    383             for (int i = 0; i < number_passes; i++) {
    384                 uint8_t* row = base;
    385                 for (png_uint_32 y = 0; y < origHeight; y++) {
    386                     uint8_t* bmRow = row;
    387                     png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
    388                     row += rb;
    389                 }
    390             }
    391             // now sample it
    392             base += sampler.srcY0() * rb;
    393             for (int y = 0; y < height; y++) {
    394                 reallyHasAlpha |= sampler.next(base);
    395                 base += sampler.srcDY() * rb;
    396             }
    397         } else {
    398             SkAutoMalloc storage(origWidth * srcBytesPerPixel);
    399             uint8_t* srcRow = (uint8_t*)storage.get();
    400             skip_src_rows(png_ptr, srcRow, sampler.srcY0());
    401 
    402             for (int y = 0; y < height; y++) {
    403                 uint8_t* tmp = srcRow;
    404                 png_read_rows(png_ptr, &tmp, png_bytepp_NULL, 1);
    405                 reallyHasAlpha |= sampler.next(srcRow);
    406                 if (y < height - 1) {
    407                     skip_src_rows(png_ptr, srcRow, sampler.srcDY() - 1);
    408                 }
    409             }
    410 
    411             // skip the rest of the rows (if any)
    412             png_uint_32 read = (height - 1) * sampler.srcDY() +
    413                                sampler.srcY0() + 1;
    414             SkASSERT(read <= origHeight);
    415             skip_src_rows(png_ptr, srcRow, origHeight - read);
    416         }
    417     }
    418 
    419     /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
    420     png_read_end(png_ptr, info_ptr);
    421 
    422     if (0 != theTranspColor) {
    423         reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor);
    424     }
    425     decodedBitmap->setIsOpaque(!reallyHasAlpha);
    426     if (reuseBitmap) {
    427         decodedBitmap->notifyPixelsChanged();
    428     }
    429     return true;
    430 }
    431 
    432 bool SkPNGImageDecoder::onBuildTileIndex(SkStream* sk_stream, int *width,
    433         int *height) {
    434     png_structp png_ptr;
    435     png_infop   info_ptr;
    436 
    437     this->index = new SkPNGImageIndex();
    438 
    439     if (onDecodeInit(sk_stream, &png_ptr, &info_ptr) == false) {
    440         return false;
    441     }
    442 
    443     if (setjmp(png_jmpbuf(png_ptr)) != 0) {
    444         png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
    445         return false;
    446     }
    447 
    448     int bit_depth, color_type, interlace_type;
    449     png_uint_32 origWidth, origHeight;
    450     png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bit_depth,
    451             &color_type, &interlace_type, int_p_NULL, int_p_NULL);
    452 
    453     *width = origWidth;
    454     *height = origHeight;
    455 
    456     png_build_index(png_ptr);
    457     this->index->png_ptr = png_ptr;
    458     this->index->info_ptr = info_ptr;
    459     return true;
    460 }
    461 
    462 bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr,
    463         SkBitmap::Config *configp, bool *hasAlphap, bool *doDitherp,
    464         SkPMColor *theTranspColorp) {
    465     png_uint_32 origWidth, origHeight;
    466     int bit_depth, color_type, interlace_type;
    467     png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bit_depth,
    468             &color_type, &interlace_type, int_p_NULL, int_p_NULL);
    469 
    470     // check for sBIT chunk data, in case we should disable dithering because
    471     // our data is not truely 8bits per component
    472     if (*doDitherp) {
    473 #if 0
    474         SkDebugf("----- sBIT %d %d %d %d\n", info_ptr->sig_bit.red,
    475                  info_ptr->sig_bit.green, info_ptr->sig_bit.blue,
    476                  info_ptr->sig_bit.alpha);
    477 #endif
    478         // 0 seems to indicate no information available
    479         if (pos_le(info_ptr->sig_bit.red, SK_R16_BITS) &&
    480                 pos_le(info_ptr->sig_bit.green, SK_G16_BITS) &&
    481                 pos_le(info_ptr->sig_bit.blue, SK_B16_BITS)) {
    482             *doDitherp = false;
    483         }
    484     }
    485 
    486     if (color_type == PNG_COLOR_TYPE_PALETTE) {
    487         bool paletteHasAlpha = hasTransparencyInPalette(png_ptr, info_ptr);
    488         *configp = this->getPrefConfig(kIndex_SrcDepth, paletteHasAlpha);
    489         // now see if we can upscale to their requested config
    490         if (!canUpscalePaletteToConfig(*configp, paletteHasAlpha)) {
    491             *configp = SkBitmap::kIndex8_Config;
    492         }
    493     } else {
    494         png_color_16p   transpColor = NULL;
    495         int             numTransp = 0;
    496 
    497         png_get_tRNS(png_ptr, info_ptr, NULL, &numTransp, &transpColor);
    498 
    499         bool valid = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS);
    500 
    501         if (valid && numTransp == 1 && transpColor != NULL) {
    502             /*  Compute our transparent color, which we'll match against later.
    503                 We don't really handle 16bit components properly here, since we
    504                 do our compare *after* the values have been knocked down to 8bit
    505                 which means we will find more matches than we should. The real
    506                 fix seems to be to see the actual 16bit components, do the
    507                 compare, and then knock it down to 8bits ourselves.
    508             */
    509             if (color_type & PNG_COLOR_MASK_COLOR) {
    510                 if (16 == bit_depth) {
    511                     *theTranspColorp = SkPackARGB32(0xFF, transpColor->red >> 8,
    512                               transpColor->green >> 8, transpColor->blue >> 8);
    513                 } else {
    514                     *theTranspColorp = SkPackARGB32(0xFF, transpColor->red,
    515                                       transpColor->green, transpColor->blue);
    516                 }
    517             } else {    // gray
    518                 if (16 == bit_depth) {
    519                     *theTranspColorp = SkPackARGB32(0xFF, transpColor->gray >> 8,
    520                               transpColor->gray >> 8, transpColor->gray >> 8);
    521                 } else {
    522                     *theTranspColorp = SkPackARGB32(0xFF, transpColor->gray,
    523                                           transpColor->gray, transpColor->gray);
    524                 }
    525             }
    526         }
    527 
    528         if (valid ||
    529                 PNG_COLOR_TYPE_RGB_ALPHA == color_type ||
    530                 PNG_COLOR_TYPE_GRAY_ALPHA == color_type) {
    531             *hasAlphap = true;
    532         }
    533         *configp = this->getPrefConfig(k32Bit_SrcDepth, *hasAlphap);
    534         // now match the request against our capabilities
    535         if (*hasAlphap) {
    536             if (*configp != SkBitmap::kARGB_4444_Config) {
    537                 *configp = SkBitmap::kARGB_8888_Config;
    538             }
    539         } else {
    540             if (*configp != SkBitmap::kRGB_565_Config &&
    541                 *configp != SkBitmap::kARGB_4444_Config) {
    542                 *configp = SkBitmap::kARGB_8888_Config;
    543             }
    544         }
    545     }
    546 
    547     // sanity check for size
    548     {
    549         Sk64 size;
    550         size.setMul(origWidth, origHeight);
    551         if (size.isNeg() || !size.is32()) {
    552             return false;
    553         }
    554         // now check that if we are 4-bytes per pixel, we also don't overflow
    555         if (size.get32() > (0x7FFFFFFF >> 2)) {
    556             return false;
    557         }
    558     }
    559 
    560     if (!this->chooseFromOneChoice(*configp, origWidth, origHeight)) {
    561         return false;
    562     }
    563     return true;
    564 }
    565 
    566 bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr,
    567         bool *hasAlphap, bool *reallyHasAlphap, SkColorTable **colorTablep) {
    568     int num_palette;
    569     png_colorp palette;
    570     png_bytep trans;
    571     int num_trans;
    572     bool reallyHasAlpha = false;
    573     SkColorTable* colorTable = NULL;
    574 
    575     png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
    576 
    577     /*  BUGGY IMAGE WORKAROUND
    578 
    579         We hit some images (e.g. fruit_.png) who contain bytes that are == colortable_count
    580         which is a problem since we use the byte as an index. To work around this we grow
    581         the colortable by 1 (if its < 256) and duplicate the last color into that slot.
    582         */
    583     int colorCount = num_palette + (num_palette < 256);
    584 
    585     colorTable = SkNEW_ARGS(SkColorTable, (colorCount));
    586 
    587     SkPMColor* colorPtr = colorTable->lockColors();
    588     if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
    589         png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
    590         *hasAlphap = (num_trans > 0);
    591     } else {
    592         num_trans = 0;
    593         colorTable->setFlags(colorTable->getFlags() | SkColorTable::kColorsAreOpaque_Flag);
    594     }
    595     // check for bad images that might make us crash
    596     if (num_trans > num_palette) {
    597         num_trans = num_palette;
    598     }
    599 
    600     int index = 0;
    601     int transLessThanFF = 0;
    602 
    603     for (; index < num_trans; index++) {
    604         transLessThanFF |= (int)*trans - 0xFF;
    605         *colorPtr++ = SkPreMultiplyARGB(*trans++, palette->red, palette->green, palette->blue);
    606         palette++;
    607     }
    608     reallyHasAlpha |= (transLessThanFF < 0);
    609 
    610     for (; index < num_palette; index++) {
    611         *colorPtr++ = SkPackARGB32(0xFF, palette->red, palette->green, palette->blue);
    612         palette++;
    613     }
    614 
    615     // see BUGGY IMAGE WORKAROUND comment above
    616     if (num_palette < 256) {
    617         *colorPtr = colorPtr[-1];
    618     }
    619     colorTable->unlockColors(true);
    620     *colorTablep = colorTable;
    621     *reallyHasAlphap = reallyHasAlpha;
    622     return true;
    623 }
    624 
    625 bool SkPNGImageDecoder::onDecodeRegion(SkBitmap* bm, SkIRect region) {
    626     int i;
    627     png_structp png_ptr = this->index->png_ptr;
    628     png_infop info_ptr = this->index->info_ptr;
    629     if (setjmp(png_jmpbuf(png_ptr))) {
    630         return false;
    631     }
    632 
    633     png_uint_32 origWidth, origHeight;
    634     int bit_depth, color_type, interlace_type;
    635     png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bit_depth,
    636             &color_type, &interlace_type, int_p_NULL, int_p_NULL);
    637 
    638     SkIRect rect = SkIRect::MakeWH(origWidth, origHeight);
    639 
    640     if (!rect.intersect(region)) {
    641         // If the requested region is entirely outsides the image, just
    642         // returns false
    643         return false;
    644     }
    645 
    646     SkBitmap::Config    config;
    647     bool                hasAlpha = false;
    648     bool                doDither = this->getDitherImage();
    649     SkPMColor           theTranspColor = 0; // 0 tells us not to try to match
    650 
    651     if (getBitmapConfig(png_ptr, info_ptr, &config, &hasAlpha,
    652                 &doDither, &theTranspColor) == false) {
    653         return false;
    654     }
    655 
    656     const int sampleSize = this->getSampleSize();
    657     SkScaledBitmapSampler sampler(origWidth, rect.height(), sampleSize);
    658 
    659     SkBitmap *decodedBitmap = new SkBitmap;
    660     SkAutoTDelete<SkBitmap> adb(decodedBitmap);
    661 
    662     decodedBitmap->setConfig(config, sampler.scaledWidth(),
    663                              sampler.scaledHeight(), 0);
    664 
    665     // from here down we are concerned with colortables and pixels
    666 
    667     // we track if we actually see a non-opaque pixels, since sometimes a PNG sets its colortype
    668     // to |= PNG_COLOR_MASK_ALPHA, but all of its pixels are in fact opaque. We care, since we
    669     // draw lots faster if we can flag the bitmap has being opaque
    670     bool reallyHasAlpha = false;
    671     SkColorTable* colorTable = NULL;
    672 
    673     if (color_type == PNG_COLOR_TYPE_PALETTE) {
    674         decodePalette(png_ptr, info_ptr, &hasAlpha,
    675                 &reallyHasAlpha, &colorTable);
    676     }
    677 
    678     SkAutoUnref aur(colorTable);
    679 
    680     // Check ahead of time if the swap(dest, src) is possible in crop or not.
    681     // If yes, then we will stick to AllocPixelRef since it's cheaper with the swap happening.
    682     // If no, then we will use alloc to allocate pixels to prevent garbage collection.
    683     int w = rect.width() / sampleSize;
    684     int h = rect.height() / sampleSize;
    685     bool swapOnly = (rect == region) && (w == decodedBitmap->width()) &&
    686                     (h == decodedBitmap->height()) &&
    687                     ((0 - rect.x()) / sampleSize == 0) && bm->isNull();
    688     if (swapOnly) {
    689         if (!this->allocPixelRef(decodedBitmap,
    690                 SkBitmap::kIndex8_Config == config ? colorTable : NULL)) {
    691             return false;
    692         }
    693     } else {
    694         if (!decodedBitmap->allocPixels(
    695             NULL, SkBitmap::kIndex8_Config == config ? colorTable : NULL)) {
    696             return false;
    697         }
    698     }
    699     SkAutoLockPixels alp(*decodedBitmap);
    700 
    701     /* Add filler (or alpha) byte (before/after each RGB triplet) */
    702     if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY) {
    703         png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
    704     }
    705 
    706     /* Turn on interlace handling.  REQUIRED if you are not using
    707     * png_read_image().  To see how to handle interlacing passes,
    708     * see the png_read_row() method below:
    709     */
    710     const int number_passes = interlace_type != PNG_INTERLACE_NONE ?
    711                         png_set_interlace_handling(png_ptr) : 1;
    712 
    713     /* Optional call to gamma correct and add the background to the palette
    714     * and update info structure.  REQUIRED if you are expecting libpng to
    715     * update the palette for you (ie you selected such a transform above).
    716     */
    717     png_ptr->pass = 0;
    718     png_read_update_info(png_ptr, info_ptr);
    719 
    720     int actualTop = rect.fTop;
    721 
    722     if (SkBitmap::kIndex8_Config == config && 1 == sampleSize) {
    723         for (int i = 0; i < number_passes; i++) {
    724             png_configure_decoder(png_ptr, &actualTop, i);
    725             for (int j = 0; j < rect.fTop - actualTop; j++) {
    726                 uint8_t* bmRow = decodedBitmap->getAddr8(0, 0);
    727                 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
    728             }
    729             for (png_uint_32 y = 0; y < origHeight; y++) {
    730                 uint8_t* bmRow = decodedBitmap->getAddr8(0, y);
    731                 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
    732             }
    733         }
    734     } else {
    735         SkScaledBitmapSampler::SrcConfig sc;
    736         int srcBytesPerPixel = 4;
    737 
    738         if (colorTable != NULL) {
    739             sc = SkScaledBitmapSampler::kIndex;
    740             srcBytesPerPixel = 1;
    741         } else if (hasAlpha) {
    742             sc = SkScaledBitmapSampler::kRGBA;
    743         } else {
    744             sc = SkScaledBitmapSampler::kRGBX;
    745         }
    746 
    747         /*  We have to pass the colortable explicitly, since we may have one
    748             even if our decodedBitmap doesn't, due to the request that we
    749             upscale png's palette to a direct model
    750          */
    751         SkAutoLockColors ctLock(colorTable);
    752         if (!sampler.begin(decodedBitmap, sc, doDither, ctLock.colors())) {
    753             return false;
    754         }
    755         const int height = decodedBitmap->height();
    756 
    757         if (number_passes > 1) {
    758             SkAutoMalloc storage(origWidth * origHeight * srcBytesPerPixel);
    759             uint8_t* base = (uint8_t*)storage.get();
    760             size_t rb = origWidth * srcBytesPerPixel;
    761 
    762             for (int i = 0; i < number_passes; i++) {
    763                 png_configure_decoder(png_ptr, &actualTop, i);
    764                 for (int j = 0; j < rect.fTop - actualTop; j++) {
    765                     uint8_t* bmRow = (uint8_t*)decodedBitmap->getPixels();
    766                     png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
    767                 }
    768                 uint8_t* row = base;
    769                 for (png_uint_32 y = 0; y < rect.height(); y++) {
    770                     uint8_t* bmRow = row;
    771                     png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
    772                     row += rb;
    773                 }
    774             }
    775             // now sample it
    776             base += sampler.srcY0() * rb;
    777             for (int y = 0; y < height; y++) {
    778                 reallyHasAlpha |= sampler.next(base);
    779                 base += sampler.srcDY() * rb;
    780             }
    781         } else {
    782             SkAutoMalloc storage(origWidth * srcBytesPerPixel);
    783             uint8_t* srcRow = (uint8_t*)storage.get();
    784 
    785             png_configure_decoder(png_ptr, &actualTop, 0);
    786             skip_src_rows(png_ptr, srcRow, sampler.srcY0());
    787 
    788             for (int i = 0; i < rect.fTop - actualTop; i++) {
    789                 uint8_t* bmRow = (uint8_t*)decodedBitmap->getPixels();
    790                 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
    791             }
    792             for (int y = 0; y < height; y++) {
    793                 uint8_t* tmp = srcRow;
    794                 png_read_rows(png_ptr, &tmp, png_bytepp_NULL, 1);
    795                 reallyHasAlpha |= sampler.next(srcRow);
    796                 if (y < height - 1) {
    797                     skip_src_rows(png_ptr, srcRow, sampler.srcDY() - 1);
    798                 }
    799             }
    800         }
    801     }
    802     if (swapOnly) {
    803         bm->swap(*decodedBitmap);
    804     } else {
    805         cropBitmap(bm, decodedBitmap, sampleSize, region.x(), region.y(),
    806                    region.width(), region.height(), 0, rect.y());
    807     }
    808 
    809     if (0 != theTranspColor) {
    810         reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor);
    811     }
    812     decodedBitmap->setIsOpaque(!reallyHasAlpha);
    813     return true;
    814 }
    815 
    816 ///////////////////////////////////////////////////////////////////////////////
    817 
    818 #include "SkColorPriv.h"
    819 #include "SkUnPreMultiply.h"
    820 
    821 static void sk_write_fn(png_structp png_ptr, png_bytep data, png_size_t len) {
    822     SkWStream* sk_stream = (SkWStream*)png_ptr->io_ptr;
    823     if (!sk_stream->write(data, len)) {
    824         png_error(png_ptr, "sk_write_fn Error!");
    825     }
    826 }
    827 
    828 static transform_scanline_proc choose_proc(SkBitmap::Config config,
    829                                            bool hasAlpha) {
    830     // we don't care about search on alpha if we're kIndex8, since only the
    831     // colortable packing cares about that distinction, not the pixels
    832     if (SkBitmap::kIndex8_Config == config) {
    833         hasAlpha = false;   // we store false in the table entries for kIndex8
    834     }
    835 
    836     static const struct {
    837         SkBitmap::Config        fConfig;
    838         bool                    fHasAlpha;
    839         transform_scanline_proc fProc;
    840     } gMap[] = {
    841         { SkBitmap::kRGB_565_Config,    false,  transform_scanline_565 },
    842         { SkBitmap::kARGB_8888_Config,  false,  transform_scanline_888 },
    843         { SkBitmap::kARGB_8888_Config,  true,   transform_scanline_8888 },
    844         { SkBitmap::kARGB_4444_Config,  false,  transform_scanline_444 },
    845         { SkBitmap::kARGB_4444_Config,  true,   transform_scanline_4444 },
    846         { SkBitmap::kIndex8_Config,     false,  transform_scanline_memcpy },
    847     };
    848 
    849     for (int i = SK_ARRAY_COUNT(gMap) - 1; i >= 0; --i) {
    850         if (gMap[i].fConfig == config && gMap[i].fHasAlpha == hasAlpha) {
    851             return gMap[i].fProc;
    852         }
    853     }
    854     sk_throw();
    855     return NULL;
    856 }
    857 
    858 // return the minimum legal bitdepth (by png standards) for this many colortable
    859 // entries. SkBitmap always stores in 8bits per pixel, but for colorcount <= 16,
    860 // we can use fewer bits per in png
    861 static int computeBitDepth(int colorCount) {
    862 #if 0
    863     int bits = SkNextLog2(colorCount);
    864     SkASSERT(bits >= 1 && bits <= 8);
    865     // now we need bits itself to be a power of 2 (e.g. 1, 2, 4, 8)
    866     return SkNextPow2(bits);
    867 #else
    868     // for the moment, we don't know how to pack bitdepth < 8
    869     return 8;
    870 #endif
    871 }
    872 
    873 /*  Pack palette[] with the corresponding colors, and if hasAlpha is true, also
    874     pack trans[] and return the number of trans[] entries written. If hasAlpha
    875     is false, the return value will always be 0.
    876 
    877     Note: this routine takes care of unpremultiplying the RGB values when we
    878     have alpha in the colortable, since png doesn't support premul colors
    879 */
    880 static inline int pack_palette(SkColorTable* ctable,
    881                                png_color* SK_RESTRICT palette,
    882                                png_byte* SK_RESTRICT trans, bool hasAlpha) {
    883     SkAutoLockColors alc(ctable);
    884     const SkPMColor* SK_RESTRICT colors = alc.colors();
    885     const int ctCount = ctable->count();
    886     int i, num_trans = 0;
    887 
    888     if (hasAlpha) {
    889         /*  first see if we have some number of fully opaque at the end of the
    890             ctable. PNG allows num_trans < num_palette, but all of the trans
    891             entries must come first in the palette. If I was smarter, I'd
    892             reorder the indices and ctable so that all non-opaque colors came
    893             first in the palette. But, since that would slow down the encode,
    894             I'm leaving the indices and ctable order as is, and just looking
    895             at the tail of the ctable for opaqueness.
    896         */
    897         num_trans = ctCount;
    898         for (i = ctCount - 1; i >= 0; --i) {
    899             if (SkGetPackedA32(colors[i]) != 0xFF) {
    900                 break;
    901             }
    902             num_trans -= 1;
    903         }
    904 
    905         const SkUnPreMultiply::Scale* SK_RESTRICT table =
    906                                             SkUnPreMultiply::GetScaleTable();
    907 
    908         for (i = 0; i < num_trans; i++) {
    909             const SkPMColor c = *colors++;
    910             const unsigned a = SkGetPackedA32(c);
    911             const SkUnPreMultiply::Scale s = table[a];
    912             trans[i] = a;
    913             palette[i].red = SkUnPreMultiply::ApplyScale(s, SkGetPackedR32(c));
    914             palette[i].green = SkUnPreMultiply::ApplyScale(s,SkGetPackedG32(c));
    915             palette[i].blue = SkUnPreMultiply::ApplyScale(s, SkGetPackedB32(c));
    916         }
    917         // now fall out of this if-block to use common code for the trailing
    918         // opaque entries
    919     }
    920 
    921     // these (remaining) entries are opaque
    922     for (i = num_trans; i < ctCount; i++) {
    923         SkPMColor c = *colors++;
    924         palette[i].red = SkGetPackedR32(c);
    925         palette[i].green = SkGetPackedG32(c);
    926         palette[i].blue = SkGetPackedB32(c);
    927     }
    928     return num_trans;
    929 }
    930 
    931 class SkPNGImageEncoder : public SkImageEncoder {
    932 protected:
    933     virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality);
    934 private:
    935     bool doEncode(SkWStream* stream, const SkBitmap& bm,
    936                   const bool& hasAlpha, int colorType,
    937                   int bitDepth, SkBitmap::Config config,
    938                   png_color_8& sig_bit);
    939 };
    940 
    941 bool SkPNGImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bitmap,
    942                                  int /*quality*/) {
    943     SkBitmap::Config config = bitmap.getConfig();
    944 
    945     const bool hasAlpha = !bitmap.isOpaque();
    946     int colorType = PNG_COLOR_MASK_COLOR;
    947     int bitDepth = 8;   // default for color
    948     png_color_8 sig_bit;
    949 
    950     switch (config) {
    951         case SkBitmap::kIndex8_Config:
    952             colorType |= PNG_COLOR_MASK_PALETTE;
    953             // fall through to the ARGB_8888 case
    954         case SkBitmap::kARGB_8888_Config:
    955             sig_bit.red = 8;
    956             sig_bit.green = 8;
    957             sig_bit.blue = 8;
    958             sig_bit.alpha = 8;
    959             break;
    960         case SkBitmap::kARGB_4444_Config:
    961             sig_bit.red = 4;
    962             sig_bit.green = 4;
    963             sig_bit.blue = 4;
    964             sig_bit.alpha = 4;
    965             break;
    966         case SkBitmap::kRGB_565_Config:
    967             sig_bit.red = 5;
    968             sig_bit.green = 6;
    969             sig_bit.blue = 5;
    970             sig_bit.alpha = 0;
    971             break;
    972         default:
    973             return false;
    974     }
    975 
    976     if (hasAlpha) {
    977         // don't specify alpha if we're a palette, even if our ctable has alpha
    978         if (!(colorType & PNG_COLOR_MASK_PALETTE)) {
    979             colorType |= PNG_COLOR_MASK_ALPHA;
    980         }
    981     } else {
    982         sig_bit.alpha = 0;
    983     }
    984 
    985     SkAutoLockPixels alp(bitmap);
    986     // readyToDraw checks for pixels (and colortable if that is required)
    987     if (!bitmap.readyToDraw()) {
    988         return false;
    989     }
    990 
    991     // we must do this after we have locked the pixels
    992     SkColorTable* ctable = bitmap.getColorTable();
    993     if (NULL != ctable) {
    994         if (ctable->count() == 0) {
    995             return false;
    996         }
    997         // check if we can store in fewer than 8 bits
    998         bitDepth = computeBitDepth(ctable->count());
    999     }
   1000 
   1001     return doEncode(stream, bitmap, hasAlpha, colorType,
   1002                     bitDepth, config, sig_bit);
   1003 }
   1004 
   1005 bool SkPNGImageEncoder::doEncode(SkWStream* stream, const SkBitmap& bitmap,
   1006                   const bool& hasAlpha, int colorType,
   1007                   int bitDepth, SkBitmap::Config config,
   1008                   png_color_8& sig_bit) {
   1009 
   1010     png_structp png_ptr;
   1011     png_infop info_ptr;
   1012 
   1013     png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, sk_error_fn,
   1014                                       NULL);
   1015     if (NULL == png_ptr) {
   1016         return false;
   1017     }
   1018 
   1019     info_ptr = png_create_info_struct(png_ptr);
   1020     if (NULL == info_ptr) {
   1021         png_destroy_write_struct(&png_ptr,  png_infopp_NULL);
   1022         return false;
   1023     }
   1024 
   1025     /* Set error handling.  REQUIRED if you aren't supplying your own
   1026     * error handling functions in the png_create_write_struct() call.
   1027     */
   1028     if (setjmp(png_jmpbuf(png_ptr))) {
   1029         png_destroy_write_struct(&png_ptr, &info_ptr);
   1030         return false;
   1031     }
   1032 
   1033     png_set_write_fn(png_ptr, (void*)stream, sk_write_fn, png_flush_ptr_NULL);
   1034 
   1035     /* Set the image information here.  Width and height are up to 2^31,
   1036     * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
   1037     * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
   1038     * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
   1039     * or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
   1040     * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
   1041     * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
   1042     */
   1043 
   1044     png_set_IHDR(png_ptr, info_ptr, bitmap.width(), bitmap.height(),
   1045                  bitDepth, colorType,
   1046                  PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
   1047                  PNG_FILTER_TYPE_BASE);
   1048 
   1049     // set our colortable/trans arrays if needed
   1050     png_color paletteColors[256];
   1051     png_byte trans[256];
   1052     if (SkBitmap::kIndex8_Config == config) {
   1053         SkColorTable* ct = bitmap.getColorTable();
   1054         int numTrans = pack_palette(ct, paletteColors, trans, hasAlpha);
   1055         png_set_PLTE(png_ptr, info_ptr, paletteColors, ct->count());
   1056         if (numTrans > 0) {
   1057             png_set_tRNS(png_ptr, info_ptr, trans, numTrans, NULL);
   1058         }
   1059     }
   1060 
   1061     png_set_sBIT(png_ptr, info_ptr, &sig_bit);
   1062     png_write_info(png_ptr, info_ptr);
   1063 
   1064     const char* srcImage = (const char*)bitmap.getPixels();
   1065     SkAutoSMalloc<1024> rowStorage(bitmap.width() << 2);
   1066     char* storage = (char*)rowStorage.get();
   1067     transform_scanline_proc proc = choose_proc(config, hasAlpha);
   1068 
   1069     for (int y = 0; y < bitmap.height(); y++) {
   1070         png_bytep row_ptr = (png_bytep)storage;
   1071         proc(srcImage, bitmap.width(), storage);
   1072         png_write_rows(png_ptr, &row_ptr, 1);
   1073         srcImage += bitmap.rowBytes();
   1074     }
   1075 
   1076     png_write_end(png_ptr, info_ptr);
   1077 
   1078     /* clean up after the write, and free any memory allocated */
   1079     png_destroy_write_struct(&png_ptr, &info_ptr);
   1080     return true;
   1081 }
   1082 
   1083 ///////////////////////////////////////////////////////////////////////////////
   1084 DEFINE_DECODER_CREATOR(PNGImageDecoder);
   1085 DEFINE_ENCODER_CREATOR(PNGImageEncoder);
   1086 ///////////////////////////////////////////////////////////////////////////////
   1087 
   1088 #include "SkTRegistry.h"
   1089 
   1090 #ifdef SK_ENABLE_LIBPNG
   1091     SkImageDecoder* sk_libpng_dfactory(SkStream*);
   1092     SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type);
   1093 #endif
   1094 
   1095 SkImageDecoder* sk_libpng_dfactory(SkStream* stream) {
   1096     char buf[PNG_BYTES_TO_CHECK];
   1097     if (stream->read(buf, PNG_BYTES_TO_CHECK) == PNG_BYTES_TO_CHECK &&
   1098         !png_sig_cmp((png_bytep) buf, (png_size_t)0, PNG_BYTES_TO_CHECK)) {
   1099         return SkNEW(SkPNGImageDecoder);
   1100     }
   1101     return NULL;
   1102 }
   1103 
   1104 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) {
   1105     return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL;
   1106 }
   1107 
   1108 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libpng_efactory);
   1109 static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(sk_libpng_dfactory);
   1110