void Decoder::PostDecodeDone(int32_t aLoopCount /* = 0 */) { NS_ABORT_IF_FALSE(!IsSizeDecode(), "Can't be done with decoding with size decode!"); NS_ABORT_IF_FALSE(!mInFrame, "Can't be done decoding if we're mid-frame!"); NS_ABORT_IF_FALSE(!mDecodeDone, "Decode already done!"); mDecodeDone = true; mImageMetadata.SetLoopCount(aLoopCount); mImageMetadata.SetIsNonPremultiplied(GetDecodeFlags() & DECODER_NO_PREMULTIPLY_ALPHA); if (mObserver) { mObserver->OnStopDecode(NS_OK); } }
void Decoder::PostDecodeDone() { NS_ABORT_IF_FALSE(!IsSizeDecode(), "Can't be done with decoding with size decode!"); NS_ABORT_IF_FALSE(!mInFrame, "Can't be done decoding if we're mid-frame!"); NS_ABORT_IF_FALSE(!mDecodeDone, "Decode already done!"); mDecodeDone = true; // Set premult before DecodingComplete(), since DecodingComplete() calls Optimize() int frames = GetFrameCount(); bool isNonPremult = GetDecodeFlags() & DECODER_NO_PREMULTIPLY_ALPHA; for (int i = 0; i < frames; i++) { mImage.SetFrameAsNonPremult(i, isNonPremult); } // Notify mImage.DecodingComplete(); if (mObserver) { mObserver->OnStopContainer(nsnull, &mImage); mObserver->OnStopDecode(nsnull, NS_OK, nsnull); } }
void nsPNGDecoder::InitInternal() { // For size decodes, we don't need to initialize the png decoder if (IsSizeDecode()) { return; } mCMSMode = gfxPlatform::GetCMSMode(); if (GetDecodeFlags() & imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION) { mCMSMode = eCMSMode_Off; } mDisablePremultipliedAlpha = GetDecodeFlags() & imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA; #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED static png_byte color_chunks[]= { 99, 72, 82, 77, '\0', // cHRM 105, 67, 67, 80, '\0'}; // iCCP static png_byte unused_chunks[]= { 98, 75, 71, 68, '\0', // bKGD 104, 73, 83, 84, '\0', // hIST 105, 84, 88, 116, '\0', // iTXt 111, 70, 70, 115, '\0', // oFFs 112, 67, 65, 76, '\0', // pCAL 115, 67, 65, 76, '\0', // sCAL 112, 72, 89, 115, '\0', // pHYs 115, 66, 73, 84, '\0', // sBIT 115, 80, 76, 84, '\0', // sPLT 116, 69, 88, 116, '\0', // tEXt 116, 73, 77, 69, '\0', // tIME 122, 84, 88, 116, '\0'}; // zTXt #endif // For full decodes, do png init stuff // Initialize the container's source image header // Always decode to 24 bit pixdepth mPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nsPNGDecoder::error_callback, nsPNGDecoder::warning_callback); if (!mPNG) { PostDecoderError(NS_ERROR_OUT_OF_MEMORY); return; } mInfo = png_create_info_struct(mPNG); if (!mInfo) { PostDecoderError(NS_ERROR_OUT_OF_MEMORY); png_destroy_read_struct(&mPNG, nullptr, nullptr); return; } #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED // Ignore unused chunks if (mCMSMode == eCMSMode_Off) { png_set_keep_unknown_chunks(mPNG, 1, color_chunks, 2); } png_set_keep_unknown_chunks(mPNG, 1, unused_chunks, (int)sizeof(unused_chunks)/5); #endif #ifdef PNG_SET_USER_LIMITS_SUPPORTED if (mCMSMode != eCMSMode_Off) { png_set_chunk_malloc_max(mPNG, 4000000L); } #endif #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED // Disallow palette-index checking, for speed; we would ignore the warning // anyhow. This feature was added at libpng version 1.5.10 and is disabled // in the embedded libpng but enabled by default in the system libpng. This // call also disables it in the system libpng, for decoding speed. // Bug #745202. png_set_check_for_invalid_index(mPNG, 0); #endif #if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_sRGB_PROFILE_CHECKS) && \ PNG_sRGB_PROFILE_CHECKS >= 0 // Skip checking of sRGB ICC profiles png_set_option(mPNG, PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON); #endif // use this as libpng "progressive pointer" (retrieve in callbacks) png_set_progressive_read_fn(mPNG, static_cast<png_voidp>(this), nsPNGDecoder::info_callback, nsPNGDecoder::row_callback, nsPNGDecoder::end_callback); }