Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 46250e2

Browse files
committed
Bug 1258741 - Part 2. Ensure we consistently render partially decoded images. r=tnikkel
1 parent 54d6f7e commit 46250e2

2 files changed

Lines changed: 44 additions & 38 deletions

File tree

image/Decoder.cpp

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -190,41 +190,39 @@ Decoder::CompleteDecode()
190190
PostError();
191191
}
192192

193-
// If this was a metadata decode and we never got a size, the decode failed.
194-
if (IsMetadataDecode() && !HasSize()) {
195-
PostError();
193+
if (IsMetadataDecode()) {
194+
// If this was a metadata decode and we never got a size, the decode failed.
195+
if (!HasSize()) {
196+
PostError();
197+
}
198+
return;
196199
}
197200

198-
// If the implementation left us mid-frame, finish that up.
199-
if (mInFrame && !HasError()) {
201+
// If the implementation left us mid-frame, finish that up. Note that it may
202+
// have left us transparent.
203+
if (mInFrame) {
204+
PostHasTransparency();
200205
PostFrameStop();
201206
}
202207

203-
// If PostDecodeDone() has not been called, we need to send teardown
204-
// notifications (and report an error to the console later).
205-
if (!mDecodeDone && !IsMetadataDecode()) {
208+
// If PostDecodeDone() has not been called, we may need to send teardown
209+
// notifications if it is unrecoverable.
210+
if (!mDecodeDone) {
211+
// We should always report an error to the console in this case.
206212
mShouldReportError = true;
207213

208-
// Even if we encountered an error, we're still usable if we have at least
209-
// one complete frame.
210214
if (GetCompleteFrameCount() > 0) {
211-
// We're usable, so do exactly what we should have when the decoder
212-
// completed.
213-
214-
// Not writing to the entire frame may have left us transparent.
215+
// We're usable if we have at least one complete frame, so do exactly
216+
// what we should have when the decoder completed.
215217
PostHasTransparency();
216-
217-
if (mInFrame) {
218-
PostFrameStop();
219-
}
220218
PostDecodeDone();
221219
} else {
222220
// We're not usable. Record some final progress indicating the error.
223221
mProgress |= FLAG_DECODE_COMPLETE | FLAG_HAS_ERROR;
224222
}
225223
}
226224

227-
if (mDecodeDone && !IsMetadataDecode()) {
225+
if (mDecodeDone) {
228226
MOZ_ASSERT(HasError() || mCurrentFrame, "Should have an error or a frame");
229227

230228
// If this image wasn't animated and isn't a transient image, mark its frame
@@ -510,8 +508,12 @@ Decoder::PostError()
510508
{
511509
mError = true;
512510

513-
if (mInFrame && mCurrentFrame) {
511+
if (mInFrame) {
512+
MOZ_ASSERT(mCurrentFrame);
513+
MOZ_ASSERT(mFrameCount > 0);
514514
mCurrentFrame->Abort();
515+
mInFrame = false;
516+
--mFrameCount;
515517
}
516518
}
517519

image/RasterImage.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,40 +1617,44 @@ RasterImage::NotifyDecodeComplete(const DecoderFinalStatus& aStatus,
16171617
mAnimationState->SetDoneDecoding(true);
16181618
}
16191619

1620-
if (!aStatus.mWasMetadataDecode && aTelemetry.mChunkCount) {
1621-
Telemetry::Accumulate(Telemetry::IMAGE_DECODE_CHUNKS, aTelemetry.mChunkCount);
1622-
}
1620+
// Do some telemetry if this isn't a metadata decode.
1621+
if (!aStatus.mWasMetadataDecode) {
1622+
if (aTelemetry.mChunkCount) {
1623+
Telemetry::Accumulate(Telemetry::IMAGE_DECODE_CHUNKS, aTelemetry.mChunkCount);
1624+
}
16231625

1624-
if (aStatus.mFinished) {
1625-
// Do some telemetry if this isn't a metadata decode.
1626-
if (!aStatus.mWasMetadataDecode) {
1626+
if (aStatus.mFinished) {
16271627
Telemetry::Accumulate(Telemetry::IMAGE_DECODE_TIME,
16281628
int32_t(aTelemetry.mDecodeTime.ToMicroseconds()));
16291629

16301630
if (aTelemetry.mSpeedHistogram) {
16311631
Telemetry::Accumulate(*aTelemetry.mSpeedHistogram, aTelemetry.Speed());
16321632
}
16331633
}
1634+
}
16341635

1635-
// Detect errors.
1636-
if (aStatus.mHadError) {
1637-
DoError();
1638-
} else if (aStatus.mWasMetadataDecode && !mHasSize) {
1639-
DoError();
1640-
}
1636+
// Only act on errors if we have no usable frames from the decoder.
1637+
if (aStatus.mHadError &&
1638+
(!mAnimationState || mAnimationState->KnownFrameCount() == 0)) {
1639+
DoError();
1640+
} else if (aStatus.mWasMetadataDecode && !mHasSize) {
1641+
DoError();
1642+
}
16411643

1644+
// XXX(aosmond): Can we get this far without mFinished == true?
1645+
if (aStatus.mFinished && aStatus.mWasMetadataDecode) {
16421646
// If we were waiting to fire the load event, go ahead and fire it now.
1643-
if (mLoadProgress && aStatus.mWasMetadataDecode) {
1647+
if (mLoadProgress) {
16441648
NotifyForLoadEvent(*mLoadProgress);
16451649
mLoadProgress = Nothing();
16461650
NotifyProgress(FLAG_ONLOAD_UNBLOCKED);
16471651
}
1648-
}
16491652

1650-
// If we were a metadata decode and a full decode was requested, do it.
1651-
if (aStatus.mFinished && aStatus.mWasMetadataDecode && mWantFullDecode) {
1652-
mWantFullDecode = false;
1653-
RequestDecodeForSize(mSize, DECODE_FLAGS_DEFAULT);
1653+
// If we were a metadata decode and a full decode was requested, do it.
1654+
if (mWantFullDecode) {
1655+
mWantFullDecode = false;
1656+
RequestDecodeForSize(mSize, DECODE_FLAGS_DEFAULT);
1657+
}
16541658
}
16551659
}
16561660

0 commit comments

Comments
 (0)