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