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