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