| Index: src/images/SkImageDecoder_libpng.cpp
|
| diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp
|
| index bcf8196f4d9478f72961e69b278b4373287fcdd4..47963b5543ece7d3c8224340c8c6f34056eee7c6 100644
|
| --- a/src/images/SkImageDecoder_libpng.cpp
|
| +++ b/src/images/SkImageDecoder_libpng.cpp
|
| @@ -82,10 +82,6 @@ public:
|
| virtual ~SkPNGImageDecoder() { delete fImageIndex; }
|
|
|
| protected:
|
| -#ifdef SK_PNG_INDEX_SUPPORTED
|
| - bool onBuildTileIndex(SkStreamRewindable *stream, int *width, int *height) override;
|
| - bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& region) override;
|
| -#endif
|
| Result onDecode(SkStream* stream, SkBitmap* bm, Mode) override;
|
|
|
| private:
|
| @@ -126,16 +122,6 @@ static void sk_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) {
|
| }
|
| }
|
|
|
| -#ifdef SK_PNG_INDEX_SUPPORTED
|
| -static void sk_seek_fn(png_structp png_ptr, png_uint_32 offset) {
|
| - SkStreamRewindable* sk_stream = (SkStreamRewindable*) png_get_io_ptr(png_ptr);
|
| - if (!sk_stream->rewind()) {
|
| - png_error(png_ptr, "Failed to rewind stream!");
|
| - }
|
| - (void)sk_stream->skip(offset);
|
| -}
|
| -#endif
|
| -
|
| #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
|
| static int sk_read_user_chunk(png_structp png_ptr, png_unknown_chunkp chunk) {
|
| SkImageDecoder::Peeker* peeker =
|
| @@ -256,9 +242,6 @@ bool SkPNGImageDecoder::onDecodeInit(SkStream* sk_stream, png_structp *png_ptrp,
|
| * png_init_io() here you would call:
|
| */
|
| png_set_read_fn(png_ptr, (void *)sk_stream, sk_read_fn);
|
| -#ifdef SK_PNG_INDEX_SUPPORTED
|
| - png_set_seek_fn(png_ptr, sk_seek_fn);
|
| -#endif
|
| /* where user_io_ptr is a structure you want available to the callbacks */
|
| /* If we have already read some of the signature */
|
| // png_set_sig_bytes(png_ptr, 0 /* sig_read */ );
|
| @@ -720,267 +703,6 @@ bool SkPNGImageDecoder::decodePalette(png_structp png_ptr, png_infop info_ptr,
|
| return true;
|
| }
|
|
|
| -#ifdef SK_PNG_INDEX_SUPPORTED
|
| -
|
| -bool SkPNGImageDecoder::onBuildTileIndex(SkStreamRewindable* sk_stream, int *width, int *height) {
|
| - SkAutoTDelete<SkStreamRewindable> streamDeleter(sk_stream);
|
| - png_structp png_ptr;
|
| - png_infop info_ptr;
|
| -
|
| - if (!onDecodeInit(sk_stream, &png_ptr, &info_ptr)) {
|
| - return false;
|
| - }
|
| -
|
| - if (setjmp(png_jmpbuf(png_ptr)) != 0) {
|
| - png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
|
| - return false;
|
| - }
|
| -
|
| - png_uint_32 origWidth, origHeight;
|
| - int bitDepth, colorType;
|
| - png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth,
|
| - &colorType, int_p_NULL, int_p_NULL, int_p_NULL);
|
| -
|
| - *width = origWidth;
|
| - *height = origHeight;
|
| -
|
| - png_build_index(png_ptr);
|
| -
|
| - if (fImageIndex) {
|
| - delete fImageIndex;
|
| - }
|
| - fImageIndex = new SkPNGImageIndex(streamDeleter.detach(), png_ptr, info_ptr);
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool SkPNGImageDecoder::onDecodeSubset(SkBitmap* bm, const SkIRect& region) {
|
| - if (nullptr == fImageIndex) {
|
| - return false;
|
| - }
|
| -
|
| - png_structp png_ptr = fImageIndex->fPng_ptr;
|
| - png_infop info_ptr = fImageIndex->fInfo_ptr;
|
| - if (setjmp(png_jmpbuf(png_ptr))) {
|
| - return false;
|
| - }
|
| -
|
| - png_uint_32 origWidth, origHeight;
|
| - int bitDepth, pngColorType, interlaceType;
|
| - png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth,
|
| - &pngColorType, &interlaceType, int_p_NULL, int_p_NULL);
|
| -
|
| - SkIRect rect = SkIRect::MakeWH(origWidth, origHeight);
|
| -
|
| - if (!rect.intersect(region)) {
|
| - // If the requested region is entirely outside the image, just
|
| - // returns false
|
| - return false;
|
| - }
|
| -
|
| - SkColorType colorType;
|
| - bool hasAlpha = false;
|
| - SkPMColor theTranspColor = 0; // 0 tells us not to try to match
|
| -
|
| - if (!this->getBitmapColorType(png_ptr, info_ptr, &colorType, &hasAlpha, &theTranspColor)) {
|
| - return false;
|
| - }
|
| -
|
| - const int sampleSize = this->getSampleSize();
|
| - SkScaledBitmapSampler sampler(origWidth, rect.height(), sampleSize);
|
| -
|
| - SkBitmap decodedBitmap;
|
| - decodedBitmap.setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledHeight(),
|
| - colorType, kPremul_SkAlphaType));
|
| -
|
| - // from here down we are concerned with colortables and pixels
|
| -
|
| - // we track if we actually see a non-opaque pixels, since sometimes a PNG sets its colortype
|
| - // to |= PNG_COLOR_MASK_ALPHA, but all of its pixels are in fact opaque. We care, since we
|
| - // draw lots faster if we can flag the bitmap has being opaque
|
| - bool reallyHasAlpha = false;
|
| - SkColorTable* colorTable = nullptr;
|
| -
|
| - if (pngColorType == PNG_COLOR_TYPE_PALETTE) {
|
| - decodePalette(png_ptr, info_ptr, bitDepth, &hasAlpha, &reallyHasAlpha, &colorTable);
|
| - }
|
| -
|
| - SkAutoUnref aur(colorTable);
|
| -
|
| - // Check ahead of time if the swap(dest, src) is possible.
|
| - // If yes, then we will stick to AllocPixelRef since it's cheaper with the swap happening.
|
| - // If no, then we will use alloc to allocate pixels to prevent garbage collection.
|
| - int w = rect.width() / sampleSize;
|
| - int h = rect.height() / sampleSize;
|
| - const bool swapOnly = (rect == region) && (w == decodedBitmap.width()) &&
|
| - (h == decodedBitmap.height()) && bm->isNull();
|
| - const bool needColorTable = kIndex_8_SkColorType == colorType;
|
| - if (swapOnly) {
|
| - if (!this->allocPixelRef(&decodedBitmap, needColorTable ? colorTable : nullptr)) {
|
| - return false;
|
| - }
|
| - } else {
|
| - if (!decodedBitmap.tryAllocPixels(nullptr, needColorTable ? colorTable : nullptr)) {
|
| - return false;
|
| - }
|
| - }
|
| - SkAutoLockPixels alp(decodedBitmap);
|
| -
|
| - /* Turn on interlace handling. REQUIRED if you are not using
|
| - * png_read_image(). To see how to handle interlacing passes,
|
| - * see the png_read_row() method below:
|
| - */
|
| - const int number_passes = (interlaceType != PNG_INTERLACE_NONE) ?
|
| - png_set_interlace_handling(png_ptr) : 1;
|
| -
|
| - /* Optional call to gamma correct and add the background to the palette
|
| - * and update info structure. REQUIRED if you are expecting libpng to
|
| - * update the palette for you (ie you selected such a transform above).
|
| - */
|
| -
|
| - // Direct access to png_ptr fields is deprecated in libpng > 1.2.
|
| -#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
|
| - png_ptr->pass = 0;
|
| -#else
|
| - // FIXME: This sets pass as desired, but also sets iwidth. Is that ok?
|
| - png_set_interlaced_pass(png_ptr, 0);
|
| -#endif
|
| - png_read_update_info(png_ptr, info_ptr);
|
| -
|
| - int actualTop = rect.fTop;
|
| -
|
| - if ((kAlpha_8_SkColorType == colorType || kIndex_8_SkColorType == colorType)
|
| - && 1 == sampleSize) {
|
| - if (kAlpha_8_SkColorType == colorType) {
|
| - // For an A8 bitmap, we assume there is an alpha for speed. It is
|
| - // possible the bitmap is opaque, but that is an unlikely use case
|
| - // since it would not be very interesting.
|
| - reallyHasAlpha = true;
|
| - // A8 is only allowed if the original was GRAY.
|
| - SkASSERT(PNG_COLOR_TYPE_GRAY == pngColorType);
|
| - }
|
| -
|
| - for (int i = 0; i < number_passes; i++) {
|
| - png_configure_decoder(png_ptr, &actualTop, i);
|
| - for (int j = 0; j < rect.fTop - actualTop; j++) {
|
| - uint8_t* bmRow = decodedBitmap.getAddr8(0, 0);
|
| - png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
|
| - }
|
| - png_uint_32 bitmapHeight = (png_uint_32) decodedBitmap.height();
|
| - for (png_uint_32 y = 0; y < bitmapHeight; y++) {
|
| - uint8_t* bmRow = decodedBitmap.getAddr8(0, y);
|
| - png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
|
| - }
|
| - }
|
| - } else {
|
| - SkScaledBitmapSampler::SrcConfig sc;
|
| - int srcBytesPerPixel = 4;
|
| -
|
| - if (colorTable != nullptr) {
|
| - sc = SkScaledBitmapSampler::kIndex;
|
| - srcBytesPerPixel = 1;
|
| - } else if (kAlpha_8_SkColorType == colorType) {
|
| - // A8 is only allowed if the original was GRAY.
|
| - SkASSERT(PNG_COLOR_TYPE_GRAY == pngColorType);
|
| - sc = SkScaledBitmapSampler::kGray;
|
| - srcBytesPerPixel = 1;
|
| - } else if (hasAlpha) {
|
| - sc = SkScaledBitmapSampler::kRGBA;
|
| - } else {
|
| - sc = SkScaledBitmapSampler::kRGBX;
|
| - }
|
| -
|
| - /* We have to pass the colortable explicitly, since we may have one
|
| - even if our decodedBitmap doesn't, due to the request that we
|
| - upscale png's palette to a direct model
|
| - */
|
| - const SkPMColor* colors = colorTable ? colorTable->readColors() : nullptr;
|
| - if (!sampler.begin(&decodedBitmap, sc, *this, colors)) {
|
| - return false;
|
| - }
|
| - const int height = decodedBitmap.height();
|
| -
|
| - if (number_passes > 1) {
|
| - SkAutoMalloc storage(origWidth * origHeight * srcBytesPerPixel);
|
| - uint8_t* base = (uint8_t*)storage.get();
|
| - size_t rb = origWidth * srcBytesPerPixel;
|
| -
|
| - for (int i = 0; i < number_passes; i++) {
|
| - png_configure_decoder(png_ptr, &actualTop, i);
|
| - for (int j = 0; j < rect.fTop - actualTop; j++) {
|
| - png_read_rows(png_ptr, &base, png_bytepp_NULL, 1);
|
| - }
|
| - uint8_t* row = base;
|
| - for (int32_t y = 0; y < rect.height(); y++) {
|
| - uint8_t* bmRow = row;
|
| - png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
|
| - row += rb;
|
| - }
|
| - }
|
| - // now sample it
|
| - base += sampler.srcY0() * rb;
|
| - for (int y = 0; y < height; y++) {
|
| - reallyHasAlpha |= sampler.next(base);
|
| - base += sampler.srcDY() * rb;
|
| - }
|
| - } else {
|
| - SkAutoMalloc storage(origWidth * srcBytesPerPixel);
|
| - uint8_t* srcRow = (uint8_t*)storage.get();
|
| -
|
| - png_configure_decoder(png_ptr, &actualTop, 0);
|
| - skip_src_rows(png_ptr, srcRow, sampler.srcY0());
|
| -
|
| - for (int i = 0; i < rect.fTop - actualTop; i++) {
|
| - png_read_rows(png_ptr, &srcRow, png_bytepp_NULL, 1);
|
| - }
|
| - for (int y = 0; y < height; y++) {
|
| - uint8_t* tmp = srcRow;
|
| - png_read_rows(png_ptr, &tmp, png_bytepp_NULL, 1);
|
| - reallyHasAlpha |= sampler.next(srcRow);
|
| - if (y < height - 1) {
|
| - skip_src_rows(png_ptr, srcRow, sampler.srcDY() - 1);
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| - if (0 != theTranspColor) {
|
| - reallyHasAlpha |= substituteTranspColor(&decodedBitmap, theTranspColor);
|
| - }
|
| - if (reallyHasAlpha && this->getRequireUnpremultipliedColors()) {
|
| - switch (decodedBitmap.colorType()) {
|
| - case kIndex_8_SkColorType:
|
| - // Fall through.
|
| - case kARGB_4444_SkColorType:
|
| - // We have chosen not to support unpremul for these colortypess.
|
| - return false;
|
| - default: {
|
| - // Fall through to finish the decode. This config either
|
| - // supports unpremul or it is irrelevant because it has no
|
| - // alpha (or only alpha).
|
| - // These brackets prevent a warning.
|
| - }
|
| - }
|
| - }
|
| - SkAlphaType alphaType = kOpaque_SkAlphaType;
|
| - if (reallyHasAlpha) {
|
| - if (this->getRequireUnpremultipliedColors()) {
|
| - alphaType = kUnpremul_SkAlphaType;
|
| - } else {
|
| - alphaType = kPremul_SkAlphaType;
|
| - }
|
| - }
|
| - decodedBitmap.setAlphaType(alphaType);
|
| -
|
| - if (swapOnly) {
|
| - bm->swap(decodedBitmap);
|
| - return true;
|
| - }
|
| - return this->cropBitmap(bm, &decodedBitmap, sampleSize, region.x(), region.y(),
|
| - region.width(), region.height(), 0, rect.y());
|
| -}
|
| -#endif
|
| -
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| #include "SkColorPriv.h"
|
|
|