void Decoder::Write(const char* aBuffer, PRUint32 aCount) { // We're strict about decoder errors NS_ABORT_IF_FALSE(!HasDecoderError(), "Not allowed to make more decoder calls after error!"); // If a data error occured, just ignore future data if (HasDataError()) return; // Pass the data along to the implementation WriteInternal(aBuffer, aCount); }
void Decoder::FlushInvalidations() { NS_ABORT_IF_FALSE(!HasDecoderError(), "Not allowed to make more decoder calls after error!"); // If we've got an empty invalidation rect, we have nothing to do if (mInvalidRect.IsEmpty()) return; // Tell the image that it's been updated mImage->FrameUpdated(mFrameCount - 1, mInvalidRect); // Fire OnDataAvailable if (mObserver) { PRBool isCurrentFrame = mImage->GetCurrentFrameIndex() == (mFrameCount - 1); mObserver->OnDataAvailable(nsnull, isCurrentFrame, &mInvalidRect); } // Clear the invalidation rectangle mInvalidRect.SetEmpty(); }
void Decoder::FlushInvalidations() { NS_ABORT_IF_FALSE(!HasDecoderError(), "Not allowed to make more decoder calls after error!"); // If we've got an empty invalidation rect, we have nothing to do if (mInvalidRect.IsEmpty()) return; // Tell the image that it's been updated mImage.FrameUpdated(mFrameCount - 1, mInvalidRect); // Fire OnDataAvailable if (mObserver) { #ifdef XP_MACOSX // Bug 703231 // Because of high quality down sampling on mac we show scan lines while decoding. // Bypass this problem by redrawing the border. PRInt32 width; PRInt32 height; mImage.GetWidth(&width); mImage.GetHeight(&height); nsIntRect mImageBound(0, 0, width, height); mInvalidRect.Inflate(1); mInvalidRect = mInvalidRect.Intersect(mImageBound); #endif bool isCurrentFrame = mImage.GetCurrentFrameIndex() == (mFrameCount - 1); mObserver->OnDataAvailable(nsnull, isCurrentFrame, &mInvalidRect); } // Clear the invalidation rectangle mInvalidRect.SetEmpty(); }
void Decoder::Write(const char* aBuffer, uint32_t aCount) { PROFILER_LABEL("ImageDecoder", "Write", js::ProfileEntry::Category::GRAPHICS); MOZ_ASSERT(aBuffer); MOZ_ASSERT(aCount > 0); // We're strict about decoder errors MOZ_ASSERT(!HasDecoderError(), "Not allowed to make more decoder calls after error!"); // Begin recording telemetry data. TimeStamp start = TimeStamp::Now(); mChunkCount++; // Keep track of the total number of bytes written. mBytesDecoded += aCount; // If a data error occured, just ignore future data. if (HasDataError()) { return; } if (IsMetadataDecode() && HasSize()) { // More data came in since we found the size. We have nothing to do here. return; } // Pass the data along to the implementation. WriteInternal(aBuffer, aCount); // Finish telemetry. mDecodeTime += (TimeStamp::Now() - start); }
void Decoder::Finish(RasterImage::eShutdownIntent aShutdownIntent) { // Implementation-specific finalization if (!HasError()) FinishInternal(); // If the implementation left us mid-frame, finish that up. if (mInFrame && !HasError()) PostFrameStop(); // If PostDecodeDone() has not been called, we need to sent teardown // notifications. if (!IsSizeDecode() && !mDecodeDone) { // Log data errors to the error console nsCOMPtr<nsIConsoleService> consoleService = do_GetService(NS_CONSOLESERVICE_CONTRACTID); nsCOMPtr<nsIScriptError> errorObject = do_CreateInstance(NS_SCRIPTERROR_CONTRACTID); if (consoleService && errorObject && !HasDecoderError()) { nsAutoString msg(NS_LITERAL_STRING("Image corrupt or truncated: ") + NS_ConvertUTF8toUTF16(mImage.GetURIString())); if (NS_SUCCEEDED(errorObject->InitWithWindowID( msg, NS_ConvertUTF8toUTF16(mImage.GetURIString()), EmptyString(), 0, 0, nsIScriptError::errorFlag, "Image", mImage.InnerWindowID() ))) { consoleService->LogMessage(errorObject); } } bool usable = true; if (aShutdownIntent != RasterImage::eShutdownIntent_NotNeeded && !HasDecoderError()) { // If we only have a data error, we're usable if we have at least one complete frame. if (GetCompleteFrameCount() == 0) { usable = false; } } // If we're usable, do exactly what we should have when the decoder // completed. if (usable) { if (mInFrame) { PostFrameStop(); } PostDecodeDone(); } else { if (mObserver) { mObserver->OnStopDecode(NS_ERROR_FAILURE); } } } // Set image metadata before calling DecodingComplete, because DecodingComplete calls Optimize(). mImageMetadata.SetOnImage(&mImage); if (mDecodeDone) { mImage.DecodingComplete(); } }
void Decoder::Finish(ShutdownReason aReason) { MOZ_ASSERT(NS_IsMainThread()); // Implementation-specific finalization if (!HasError()) FinishInternal(); // If the implementation left us mid-frame, finish that up. if (mInFrame && !HasError()) PostFrameStop(); // If PostDecodeDone() has not been called, we need to sent teardown // notifications. if (!IsSizeDecode() && !mDecodeDone) { // Log data errors to the error console nsCOMPtr<nsIConsoleService> consoleService = do_GetService(NS_CONSOLESERVICE_CONTRACTID); nsCOMPtr<nsIScriptError> errorObject = do_CreateInstance(NS_SCRIPTERROR_CONTRACTID); if (consoleService && errorObject && !HasDecoderError()) { nsAutoString msg(NS_LITERAL_STRING("Image corrupt or truncated: ") + NS_ConvertUTF8toUTF16(mImage.GetURIString())); if (NS_SUCCEEDED(errorObject->InitWithWindowID( msg, NS_ConvertUTF8toUTF16(mImage.GetURIString()), EmptyString(), 0, 0, nsIScriptError::errorFlag, "Image", mImage.InnerWindowID() ))) { consoleService->LogMessage(errorObject); } } bool usable = !HasDecoderError(); if (aReason != ShutdownReason::NOT_NEEDED && !HasDecoderError()) { // If we only have a data error, we're usable if we have at least one complete frame. if (GetCompleteFrameCount() == 0) { usable = false; } } // If we're usable, do exactly what we should have when the decoder // completed. if (usable) { if (mInFrame) { PostFrameStop(); } PostDecodeDone(); } else { if (!IsSizeDecode()) { mProgress |= FLAG_DECODE_COMPLETE | FLAG_ONLOAD_UNBLOCKED; } mProgress |= FLAG_HAS_ERROR; } } // Set image metadata before calling DecodingComplete, because // DecodingComplete calls Optimize(). mImageMetadata.SetOnImage(&mImage); if (mDecodeDone) { MOZ_ASSERT(HasError() || mCurrentFrame, "Should have an error or a frame"); mImage.DecodingComplete(mCurrentFrame.get()); } }