зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1249576 - If the first frame of an APNG doesn't cover the whole image mark the image as transparent. r=edwin
In (non-animated) PNGs the image data is contained in IDAT chunks. In APNGs there are IDAT chunks, which contain the default image, and fDAT chunks, which contain frames of the animation. The default image is sometimes part of the animation (as the first frame), and sometimes not (displayed only by non-APNG aware viewers). The default image must have the same size as in the PNG header chunk. But the fDAT images can be any (smaller) size. So the first frame of a PNG is allowed to be smaller than the whole image size so long as we are in an APNG and the first frame is from an fDAT chunk, not an IDAT chunk. We post transparency if we encounter this case because we don't draw into those pixels on at least the first frame.
This commit is contained in:
Родитель
753cad635e
Коммит
c29791aa23
|
@ -133,9 +133,12 @@ nsPNGDecoder::CheckForTransparency(SurfaceFormat aFormat,
|
|||
PostHasTransparency();
|
||||
}
|
||||
|
||||
// PNGs shouldn't have first-frame padding.
|
||||
MOZ_ASSERT_IF(mNumFrames == 0,
|
||||
IntRect(IntPoint(), GetSize()).IsEqualEdges(aFrameRect));
|
||||
// If the first frame of animated image doesn't draw into the whole image,
|
||||
// then record that it is transparent.
|
||||
if (mNumFrames == 0 && !IntRect(IntPoint(), GetSize()).IsEqualEdges(aFrameRect)) {
|
||||
MOZ_ASSERT(HasAnimation());
|
||||
PostHasTransparency();
|
||||
}
|
||||
}
|
||||
|
||||
// CreateFrame() is used for both simple and animated images
|
||||
|
@ -597,6 +600,12 @@ nsPNGDecoder::info_callback(png_structp png_ptr, png_infop info_ptr)
|
|||
#endif
|
||||
|
||||
if (decoder->IsMetadataDecode()) {
|
||||
// If we are animated then the first frame rect is either: 1) the whole image
|
||||
// if the IDAT chunk is part of the animation 2) the frame rect of the first
|
||||
// fDAT chunk otherwise. If we are not animated then we want to make sure to
|
||||
// call PostHasTransparency in the metadata decode if we need to. So it's okay
|
||||
// to pass IntRect(0, 0, width, height) here for animated images; they will
|
||||
// call with the proper first frame rect in the full decode.
|
||||
decoder->CheckForTransparency(decoder->format,
|
||||
IntRect(0, 0, width, height));
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче