Skip to content

Commit

Permalink
Bug 1352282. Always fill in the number of loops when decoding an APNG…
Browse files Browse the repository at this point in the history
… file. r=aosmond

If we were doing a first frame only decode we wouldn't fill in this value. The spec says this chunk must come before any image data so it should always be available at the end of any full decode (whether it be truly full or first frame only).
  • Loading branch information
tnikkel committed Apr 5, 2017
1 parent f84f44f commit 0e7000f
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 12 deletions.
39 changes: 27 additions & 12 deletions image/decoders/nsPNGDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,33 @@ nsPNGDecoder::DoYield(png_structp aPNGStruct)
Transition::ContinueUnbufferedAfterYield(State::PNG_DATA, consumedBytes);
}

nsresult
nsPNGDecoder::FinishInternal()
{
// We shouldn't be called in error cases.
MOZ_ASSERT(!HasError(), "Can't call FinishInternal on error!");

if (IsMetadataDecode()) {
return NS_OK;
}

int32_t loop_count = 0;
#ifdef PNG_APNG_SUPPORTED
if (png_get_valid(mPNG, mInfo, PNG_INFO_acTL)) {
int32_t num_plays = png_get_num_plays(mPNG, mInfo);
loop_count = num_plays - 1;
}
#endif

if (InFrame()) {
EndImageFrame();
}
PostDecodeDone(loop_count);

return NS_OK;
}


#ifdef PNG_APNG_SUPPORTED
// got the header of a new frame that's coming
void
Expand All @@ -959,7 +986,6 @@ nsPNGDecoder::frame_info_callback(png_structp png_ptr, png_uint_32 frame_num)
if (!previousFrameWasHidden && decoder->IsFirstFrameDecode()) {
// We're about to get a second non-hidden frame, but we only want the first.
// Stop decoding now. (And avoid allocating the unnecessary buffers below.)
decoder->PostDecodeDone();
return decoder->DoTerminate(png_ptr, TerminalState::SUCCESS);
}

Expand Down Expand Up @@ -1025,17 +1051,6 @@ nsPNGDecoder::end_callback(png_structp png_ptr, png_infop info_ptr)
// We shouldn't get here if we've hit an error
MOZ_ASSERT(!decoder->HasError(), "Finishing up PNG but hit error!");

int32_t loop_count = 0;
#ifdef PNG_APNG_SUPPORTED
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL)) {
int32_t num_plays = png_get_num_plays(png_ptr, info_ptr);
loop_count = num_plays - 1;
}
#endif

// Send final notifications.
decoder->EndImageFrame();
decoder->PostDecodeDone(loop_count);
return decoder->DoTerminate(png_ptr, TerminalState::SUCCESS);
}

Expand Down
1 change: 1 addition & 0 deletions image/decoders/nsPNGDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class nsPNGDecoder : public Decoder

protected:
nsresult InitInternal() override;
nsresult FinishInternal() override;
LexerResult DoDecode(SourceBufferIterator& aIterator,
IResumable* aOnResume) override;

Expand Down

0 comments on commit 0e7000f

Please sign in to comment.