Closed Bug 46700 Opened 24 years ago Closed 24 years ago

change png binary transparency implementation from 8 bit to 1 bit.

Categories

(Core :: Graphics: ImageLib, defect, P3)

defect

Tracking

()

RESOLVED FIXED

People

(Reporter: pnunn, Assigned: tor)

References

()

Details

(Keywords: modern, perf)

Attachments

(2 files)

No description provided.
err, stupid question, but this is specifically for _binary_ transparency, right? ;)
yes. This only applies to _binary_ transparency.
Summary: change png transparency implementation from 8 bit to 1 bit. → change png binary transparency implementation from 8 bit to 1 bit.
Status: NEW → ASSIGNED
Target Milestone: --- → Future
This is closely related to bug 36002, in that they both affect many of the same performance issues. Specifically, of the following three issues: 1) Slow scrolling and redraw when binary-transparent PNGs are involved 2) Slow scrolling when alpha-transparent PNGs are involved 3) Slow performance when binary-transparent PNGs are involved in dynamic pages This bug applies to 1 and 3; 36002 applies to 1 and 2. In other words, a fix for this would provide half a fix for 36002 and vice versa.
This has become important because the new modern skin is using (abusing) PNGs with alpha channels. PNGs with binary tRNS chunks are being converted to 8-bit alpha images internally, which forces them through the slow compositing DrawImage paths.
Keywords: newmod, nsbeta3, perf
OS: Windows NT → All
The following simplistic approach doesn't work, as apparently PNGs are allowed to have a tRNS chunk as well as ordinary alpha information. Adding newt@pobox.com for his insight. Index: ipng.cpp =================================================================== RCS file: /cvsroot/mozilla/modules/libimg/pngcom/ipng.cpp,v retrieving revision 1.24 diff -u -r1.24 ipng.cpp --- ipng.cpp 2000/08/07 22:09:02 1.24 +++ ipng.cpp 2000/09/04 04:34:59 @@ -295,7 +295,8 @@ ipng_p->alpharow = NULL; #if defined(CAN_SUPPORT_8_BIT_MASK) - if(png_ptr->color_type || PNG_COLOR_MASK_ALPHA ) + if ((png_ptr->color_type || PNG_COLOR_MASK_ALPHA) && + !(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) ic->image->header.alpha_bits = 8/*png_ptr->pixel_depth*/; /* 8 */ else #endif
It's late enough that I'm a little fuzzy and not willing to go pore over CVS sources and libpng documentation at the moment, but two comments come to mind right off: (1) If by "allowed to have a tRNS chunk as well as ordinary alpha" you mean the *same* PNG, then no--tRNS is specifically disallowed in PNG images with an alpha channel. (It would have made sense in the same way that PLTE is allowed in RGB PNGs for the purpose of suggested palettes, but that's a completely separate issue.) (2) I'm not 100% certain, but I think the pre-png_update_info() transformations nullify a lot of the png_get_valid() stuff that would have worked earlier in the code. That is, until you do png_update_info(), the description of the image returned by the png_get_valid() calls corresponds to the actual, untransformed image--any transformation calls you may have made are just setting bits in the PNG struct, not actually doing anything to the image or affecting png_get_valid() info. But *after* png_update_info(), which I believe is where the code in the patch lives, all previously set transformations are treated as though they're in effect. So unless something else has changed upstream since I wrote the transformation code a year ago, all knowledge of PLTE and tRNS is gone at line 295; the image is either 24-bit RGB or 32-bit RGBA at this point. If it's just a matter of flagging that the 8-bit alpha channel really consists only of 0 and 255 values, then it should be possible to do that up above (i.e., set a flag up there and use it in this if-statement). Note, however, that you'll have to get all of the tRNS data--potentially 255 bytes--and check whether it includes any values other than 0 and 255; if it does, you won't be able to use the 1-bit code path. Sorry if I'm restating the obvious here.
Thanks for the explanation - that pointed out some of my misunderstandings regarding tRNS. I'm attaching a patch which makes libimg use 1-bit alpha if the tRNS information indicates binary transparency. Could you review it?
Taking bug, shifting milestone.
Assignee: pnunn → tor
Status: ASSIGNED → NEW
Target Milestone: Future → M18
Yes, that looks correct. (I'm not currently set up to compile the beast, so I haven't tested it to be sure.) But please change "png_ptr->color_type" to "color_type" in the outer if-test. And purely from a readability standpoint, I think the innermost if-test would be easier to understand if written as: if ((trans[i] != 0) && (trans[i] != 255)) { That's aesthetics, though. Greg
One other comment: since you're not using trans_values, you can eliminate the variable entirely and use "NULL" as the last argument to png_get_tRNS().
Checked in. Thanks for your help, Greg.
Status: NEW → RESOLVED
Closed: 24 years ago
Resolution: --- → FIXED
You betcha. Thanks for taking care of this one.
QA Contact: elig → tpreston
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: