Closed Bug 1187569 Opened 9 years ago Closed 9 years ago

PNGs getting stuck in a pixelated state.

Categories

(Core :: Graphics: ImageLib, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla43
Tracking Status
firefox43 --- fixed

People

(Reporter: caspy77, Assigned: glennrp+bmo)

References

Details

(Whiteboard: [gfx-noted])

Attachments

(4 files, 2 obsolete files)

Attached image Bad PNG.png
I'm not sure how relavent it is (but I was told to file this :) I use the Imagus addon to allow me to hover the pointer over images and see a larger/zoomed version of them.
Whenever I was browsing reddit and hovered over http://imgur.com/a/IRE3B?gallery many of its full sized images are PNGs and would be extremely pixelated (see attached screenshot) for a while before resolving, but I was able to replicate more than once it simply becoming stuck at the pixelated state.  If I used the arrow button to leave the problem picture and then go back again, the correct image was shown

If it's of interest, here is the reddit posting for the imgur image gallery in question:
https://www.reddit.com/r/interestingasfuck/comments/3efelk/americas_hidden_treasure_room/
seth, can you check the bug?
Flags: needinfo?(seth)
Whiteboard: [gfx-noted]
The source image corresponding to the attached "BAD png.png" (http://i.imgur.com/hN8Li0k.png) is a 3MB interlaced PNG, so it's not surprising that it would look "pixelated" for a while.  I don't know why it would become "stuck" though.
Attached image example.png
Attached file example.html
I can no longer reproduce the issue but I was getting similar behavior with "example.png" when the height of the image was 915px.
The height bit is probably not relevant.

1. Visit: https://en.wikipedia.org/wiki/Security-Enhanced_Linux
2. Hard refresh (Ctrl+F5)
3. Click image on the right
If I follow these instructions, but instead of clicking on the image, just hover the image. Then the Imagus addon kicks in and shows the partially-loaded pixelated image.  If I move the mouse away and then back again, the image displays properly.
It's possible this is somehow a problem induced by the addon, but if others are able to demonstrate it by clicking the image, it sounds like an actual issue in Firefox.
I'm seeing it by simply clicking the image, with nightly.  It looks to me like some interaction between decoding interlaced PNGs and the "first_frame_is_hidden" treatment.  Taking the bug.
Assignee: nobody → glennrp+bmo
Status: NEW → ASSIGNED
Behavior also observed with FF 40.0 so it's not a new bug.
I added some debug printout to today's mozilla-central to verify that nsPNGDecoder is processing all seven interlace passes and reaching the end_callback function, whether the image appears clearly or is pixelated.  When it's pixelated, it clears up if I left-click on the image, but there's no indication that nsPNGDecoder re-processes the image at that time.
Additional clues:  I converted the SELinux image to interlaced GIF and don't see any pixelation.  I also used pngcrush to remove the opaque alpha channel and did not see any change in behavior (still stops sometimes with the pixelated display).  Interestingly, frequently the top of the image looks more pixelated than the bottom.  The SELinux image has 974 rows, which is not divisible by 8.  I added two rows to make it divisible by 8, but observed the same bad behavior.
Depends on: 1194900
This looks to me like an invalidation issue. It made me notice that nsPNGDecoder is trying to be too smart about sending invalidations, and duplicating decisions that we're making at the Decoder level. I've filed bug 1194900 about fixing that. I doubt that'll fix this bug, though.

I don't have time to investigate beyond that at the moment, but one way things could go wrong is if this invalidation rect is wrong in the interlaced case:

https://dxr.mozilla.org/mozilla-central/source/image/decoders/nsPNGDecoder.cpp?case=true&from=nsPNGDecoder.cpp&offset=0#768
Flags: needinfo?(seth)
Yes, we invalidate after every row of every pass of the first image.  I'm testing a scheme that
invalidates after every 8 rows on the first pass, then not at all on the even passes, and only once
at the end of each odd pass (the square ones).  It seems relatively snappy and is not showing
pixelated images when done.
Attached patch v00-1187569-fewer-invalidations (obsolete) — Splinter Review
This suppresses the bug by reducing the number of Invalidations while processing interlaced PNGs.  Instead if invalidating each line of each pass, we only invalidate the entire image at the end of each pass.
Comment on attachment 8648454 [details] [diff] [review]
v00-1187569-fewer-invalidations

Review of attachment 8648454 [details] [diff] [review]:
-----------------------------------------------------------------

Thanks for investigating this, Glenn! The patch looks good; are you still testing, or is it ready to go?

Some minor nits below:

::: image/decoders/nsPNGDecoder.cpp
@@ +772,5 @@
>          png_longjmp(decoder->mPNG, 1);
>      }
>  
> +    if (!decoder->interlacebuf)
> +    {

Nit: per Mozilla style, the |{| should go on the same line as the |if|.

@@ +775,5 @@
> +    if (!decoder->interlacebuf)
> +    {
> +      // Do line-by-line partial invalidations for non-interlaced images
> +      decoder->PostInvalidation(IntRect(0, row_num, width, 1));
> +    } else if (row_num == (png_uint_32) decoder->mFrameRect.height - 1) {

Nit: please use a C++-style cast.
Blocks: 1194900
No longer depends on: 1194900
(In reply to Seth Fowler [:seth] [:s2h] from comment #14)
> Comment on attachment 8648454 [details] [diff] [review]
> v00-1187569-fewer-invalidations
> 
> Review of attachment 8648454 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> Thanks for investigating this, Glenn! The patch looks good; are you still
> testing, or is it ready to go?
> 
> Some minor nits below:
> 
> ::: image/decoders/nsPNGDecoder.cpp
> @@ +772,5 @@
> >          png_longjmp(decoder->mPNG, 1);
> >      }
> >  
> > +    if (!decoder->interlacebuf)
> > +    {
> 
> Nit: per Mozilla style, the |{| should go on the same line as the |if|.
> 
> @@ +775,5 @@
> > +    if (!decoder->interlacebuf)
> > +    {
> > +      // Do line-by-line partial invalidations for non-interlaced images
> > +      decoder->PostInvalidation(IntRect(0, row_num, width, 1));
> > +    } else if (row_num == (png_uint_32) decoder->mFrameRect.height - 1) {
> 
> Nit: please use a C++-style cast.

It's good to go except for the review nits, and it'll need to be rebased when 1194900 lands.
Attached patch v01-1187569-fewer-invalidations (obsolete) — Splinter Review
Fixed seth's review nits.  Need tryserver run.
Attachment #8648454 - Attachment is obsolete: true
Flags: needinfo?(ryanvm)
Comment on attachment 8649512 [details] [diff] [review]
v01-1187569-fewer-invalidations

Uploaded the wrong file...
Attachment #8649512 - Attachment is obsolete: true
Need try server run.
Flags: needinfo?(ryanvm)
Comment on attachment 8649520 [details] [diff] [review]
v02-1187569-fewer-invalidations

The try run looks OK.  Just 3 orange that don't appear to have anything to do with PNG.  R?
Attachment #8649520 - Flags: review?(seth)
Comment on attachment 8649520 [details] [diff] [review]
v02-1187569-fewer-invalidations

Review of attachment 8649520 [details] [diff] [review]:
-----------------------------------------------------------------

Looks good. I think we're ready to land. If inbound's open I'll go ahead and do that now.
Attachment #8649520 - Flags: review?(seth) → review+
inbound's not open, alas. =\
Keywords: checkin-needed
Blocks: 75077
https://hg.mozilla.org/mozilla-central/rev/935545bab632
Status: ASSIGNED → RESOLVED
Closed: 9 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla43
Recently I've been getting these notices occasionally.  I haven't isolated the cause yet, but I suspect it's related to this bug, and the "reordered frames" are passes over an interlaced PNG.

I/SampleTable( 3590): There are reordered frames present.
I/SampleTable( 3590): There are reordered frames present.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: