惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Commits to openclaw:main
Recent Commits to openclaw:main
L
LangChain Blog
月光博客
月光博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 【当耐特】
宝玉的分享
宝玉的分享
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
博客园_首页
T
Tailwind CSS Blog
P
Proofpoint News Feed
雷峰网
雷峰网
D
Darknet – Hacking Tools, Hacker News & Cyber Security
IT之家
IT之家
V
Vulnerabilities – Threatpost
阮一峰的网络日志
阮一峰的网络日志
C
CERT Recently Published Vulnerability Notes
Attack and Defense Labs
Attack and Defense Labs
S
Schneier on Security
Security Archives - TechRepublic
Security Archives - TechRepublic
L
Lohrmann on Cybersecurity
V
Visual Studio Blog
云风的 BLOG
云风的 BLOG
WordPress大学
WordPress大学
The Register - Security
The Register - Security
N
Netflix TechBlog - Medium
Hugging Face - Blog
Hugging Face - Blog
Project Zero
Project Zero
博客园 - 叶小钗
F
Full Disclosure
大猫的无限游戏
大猫的无限游戏
Latest news
Latest news
S
SegmentFault 最新的问题
C
Cyber Attacks, Cyber Crime and Cyber Security
Google Online Security Blog
Google Online Security Blog
Recorded Future
Recorded Future
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Hacker News - Newest:
Hacker News - Newest: "LLM"
腾讯CDC
L
LINUX DO - 最新话题
Google DeepMind News
Google DeepMind News
P
Privacy International News Feed
I
InfoQ
F
Fortinet All Blogs
Vercel News
Vercel News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Threatpost
T
Tenable Blog
B
Blog RSS Feed

Henri Sivonen’s pages

Parin vuoden tutkimattomuus crates.io: Rust Package Registry Asiakirjatonta toimintaa It’s not wrong that "🤦🏼‍♂️".length == 7 Koulutartuntojen tilastointimenettely Perusteasiakirjoja hallussapitämättä ikärajoitettu Asiantuntijat ja nukkuva vallan vahtikoira Koronapassilausunto Suppealla tietopohjalla ohimeneväksi väitetty Text Encoding Menu in 2021 The Text Encoding Submenu Is Gone An HTML5 Conformance Checker Not Part of the Technology Stack Browser Technology Stack Bogo-XML Declaration Returns to Gecko A Look at Encoding Detection and Encoding Menu Telemetry from Firefox 86 Why Supporting Unlabeled UTF-8 in HTML on the Web Would Be Problematic Rust Target Names Aren’t Passed to LLVM Toimintamalli Activating Browser Modes with Doctype Johtopäätöksiä mallin rakenteesta Tehtävänmäärittelyä kirjoittamatta ja kuolemia laskematta laumasuojamallinnettu Character Encoding Menu in 2014 Erillissuosituksen tarpeettomuudesta yleissuosituksen poikkeukseksi? STM:n maskiaikajana Rust 2021 Oma-aloitteisesti mallinnettu Kokopinovaatimuksin kilpailutettu chardetng: A More Compact Character Encoding Detector for the Legacy Web Varauksia paisutellen tiedotettu Perusteasiakirjoitta tiedotettu Always Use UTF-8 & Always Label Your HTML Saying So IME Smoke Testing The Validator.nu HTML Parser About the Hiragino Fonts with CSS It’s Time to Stop Adding New Features for Non-Unicode Execution Encodings in C++ Rust 2020 The Last of the Parsing Quirks About about:blank Rust 2019 a Web-Compatible Character Encoding Library in Rust How I Wrote a Modern C++ Library in Rust Using cargo-fuzz to Transfer Code Review of Simple Safe Code to Complex Code that Uses unsafe A Rust Crate that Also Quacks Like a Modern C++ Library #Rust2018 No Namespaces in JSON, Please A Lecture about HTML5 Julkisesti luotettu varmenne ikidomainille TLS:ää (SSL:ää) varten -webkit-HTML5 Lists in Attribute Values If You Want Software Freedom on Phones, You Should Work on Firefox OS, Custom Hardware and Web App Self-Hostablility HTML5 Parser Improvements ARIA in HTML5 Integration: Document Conformance (Draft, Take Two) Schema.org and Pre-Existing Communities Lowering memory requirements by replacing Schematron HTML5 Parsing in Gecko: A Build Introducing SAX Tree NVDL Support in Validator.nu HOWTO Avoid Being Called a Bozo When Producing XML An Unofficial Q&A about the Discontinuation of the XHTML2 WG Thoughts on HTML5 Becoming a W3C Recommendation Four Finnish Banks Training Users to Give Banking Credentials to Another Site Unimpressed by Leopard Sergeant Semantics The Content Sink Inheritance Diagram – 2006-06-30 What is EME? About Points and Pixels as Units The Performance Cost of the HTML Tree Builder Social Media Impression Management The spacer Element Is Gone Openmind 2006 Performance Mistake XHTML and Mobile Devices WebM-Enabled Browser Usage Share Exceeds H.264-Enabled Browser Usage Share on Desktop (in StatCounter Numbers) HTML5 Parser-Based View Source Syntax Highlighting Vendor Prefixes Are Hurting the Web Accept-Charset Is No More Dualroids Writing Structural Stylable Document in Mozilla Editor ISO-8859-15 on haitallinen Hourglass The Scientific Method According to Hixie Maemo Source Code Karpelan lukkovertaus ontuu Digitaalisesta arkistoinnista ARIA in HTML5 Integration: Document Conformance (Draft) XHTML—What’s the Point? (Draft, incomplete) Mac OS X Browser Comparison HOWTO Spot a Wannabe Web Standards Advocate An Idea About Intermediate Language Trees and Web UI Generation Thoughts on Using SSL/TLS Certificates as the Solution to Phishing Bureaucracy Meets the Web Europe Day HOWTO Establish a 100% Literacy Rate What to Do with All These Photos? Charmod Norm Checking Validator Web Service Interface Ideas DTDs Don’t Work on the Web EFFI’s Day in Court Speaking at XTech
The Sad Story of PNG Gamma “Correction”
Henri Sivonen · 2015-07-14 · via Henri Sivonen’s pages

Browsers have supported the PNG bitmap format for quite some time. But still, even though PNG files can either be made smaller than GIFs or, alternatively, can contain more colors, lots of Web designers keep using JPEGs and GIFs. In fact, even designers who (for other reasons) don’t care about old browsers still often haven’t made the switch to PNG. Is it just about being stuck with the old ways or is there a good reason not to switch? Sadly, it turns out there is a reason not to switch: gamma “correction” gone wrong.

Why PNG? (Quick Recap)

Unencumbered by patents

The common expert belief is that the deflate compression algorithm which is used in the PNG format is not under patents when implemented in the way it is implemented in the zlib compression library. On the other hand, the LZW compression algorithm used when writing GIFs was subject to a U.S. patent owned by Unisys (and to similar patents in some other countries). Unisys has enforced the patent and effectively taxed software that writes GIFs. The U.S. patent has now expired, so this it is no longer a reason for avoiding GIF.

Smaller file size

This feature of PNG may not be obvious when comparing the PNGs and GIFs written by Photoshop for example, because many programs don’t use the full compression potential of PNG. However, when the full potential of the compression and the data rearrangement filters of PNG are used (eg. using pngcrush), PNG files are smaller than GIFs with the same image data.

More colors

The maximum number of colors in a GIF image is 256. The PNG format can handle RGB colors up to 16 bits per channel. Of course, with current display hardware the ability to use 8 bits per channel (Apple’s “millions of colors” or Microsoft’s “true color”) has more practical value.

Alpha channel

In GIF, one color can be made fully transparent. PNG images can have a full alpha channel which allows semi-transparent pixels.

Gamma correction
Gamma correction is supposed to make a cool bullet point. However, this is why you may not want to use PNGs in practice.

The Original Problem

Traditionally, RGB colors have been displayed simply by handing the numeric RGB color values to the display hardware—a display card controlling a cathode ray tube (CRT). This is also what Web browsers have done. The RGB color values from GIF color palettes, decoded JPEG images and from HTML have been passed unmodified to the graphics API of the system.

But mapping the numeric color values to screen colors is not that simple. Even if the numeric values were mapped linearly to voltages on the display card, the phosphors of the CRT won’t excite linearly depending on the input voltage. On most systems, the numeric color values have just been chosen in such a way that the desired colors are produced on an average CRT—or at least the CRT of the person originally choosing the color values.

Some system designers were not satisfied with the non-linear behavior of the CRT and chose to compensate by adding a transfer function to the display card. This was done by Apple, NeXT and SGI. However, they chose different default compensations. As a result, the same numeric color values produce different colors on different computer setups even when the physical properties of the CRT are the same.

To put it simply: A color with the same numeric RGB values looks brighter on an out-of-the-box Mac or SGI box than it does on an average PC.

The “Correction”

The transfer function in question is simple. The color values are scaled to the range 0.0…1.0 and then raised to power. The exponent is called gamma. It follows that the inverse function simply has the reciprocal of the gamma as the exponent. Also, it is easy to make a composite of consecutively applied functions by simply multiplying the exponents.

So compensating the effect of the transfer function looks simple—in theory.

The New Problem

In order to compensate for the different gammas, the display gamma of the system an image was authored on and the display gamma of the system where the image is being displayed both need to be known to the piece of software displaying the image. The PNG format provides a means for storing the (reciprocal of) display gamma of the authoring system to the image file. It is up to the program writing the file to store the native display gamma of the image, and then it is up to program displaying the file to compensate.

The new problem is that the programs that read and write PNG files usually have no idea about the display gamma of the system they are running on. The usual method is to take a guess based on the platform the program is running on and pick one of the default values mentioned for Mac, SGI, NeXT and PC clones in the Gamma Tutorial appendix of the PNG specification.

This approach is bogus. The platform defaults are only that: defaults. The display gamma is configurable on many systems. Also, on uncalibrated systems the default values are not exact. Writing bogus gamma information to files and then doing gamma “correction” using different bogus gamma information is not solving the problem—only perturbing it further.

In practice, a rather arbitrary gamma change is often applied to a PNG image when the image is opened in a program that did not write the file. When a PNG image is viewed in isolation, the gamma disturbance may not be obvious. However, when the colors of an image are meant to match some surrounding colors—such as the colors of a Web page—the problem becomes more serious.

Inconsistent Color on the Web

When images are used as parts of a Web page design, consistent color handling is often more important than colorimetric correcness. For a design that combines CSS and images, it is important that a color with a particular RGB value is displayed consistently regardless of the source—style sheet or image file—of the color value.

Given the same RGB values, the colors specified in CSS, HTML, JPEG, or GIF have traditionally matched. Everyone has just taken it for granted. (Colors are not represented as RGB internally in JPEG, but everyone uses the de facto color conversion of libjpeg from the Independent JPEG Group.)

PNG breaks the consistency. When the gamma of PNG images is disturbed but the CSS colors are left untouched, the colors no longer match.

There are at least two natural reactions: trying to opt out of gamma “correction” or trying to make it so that the PNG images are considered to be in the same color space as CSS colors.

Opting Out

Including the gamma information in a PNG file is optional. It would be reasonable to expect the colors of PNG images to be treated like the colors of GIF and JPEG images if the gamma information is omitted.

Sadly, it doesn’t work that way in every PNG-supporting browser. In older versions of Opera and in pre-Tiger Safari, PNG colors don’t match CSS colors when there is no color space information stored in the PNG files. Also some old Mac versions of Mozilla and Netscape 6 applied a gamma change to unlabeled PNGs.

It could be argued that a browser is free to guess anything about the color space of the incoming file and, therefore, is free to apply any arbitrary gamma change. After all, no standard mandates that in the absence of gamma information PNGs should be treated color-wise in the same way as GIFs and JPEGs. Still, treating the colors of unlabeled PNGs differently from the colors of (unlabeled) GIFs and JPEGs makes no sense.

Opera 7, the Mac version of Opera 6 and Safari 2.0 on Mac OS X 10.4 fix this problem and make the colors of PNGs that don’t carry color space information consistent with CSS colors. Even though Opera 7 and Safari 2.0 behave reasonably with unlabeled PNGs, the old versions continue to be out there.

Of the various PNG-supporting browsers, Safari on Mac OS X prior to 10.4 is the most prominent problem: It applies a gamma change to unlabeled PNGs. This means that even unlabeled PNGs are no good those who want consistent colors between images and CSS in Safari on Mac OS X 10.3 and 10.2.

The gamma information and other fancier color space information can be removed using pngcrush: pngcrush -rem gAMA -rem cHRM -rem iCCP -rem sRGB infile.png outfile.png

Making the Color Spaces Match

In theory, one could try to use the color management features of PNG to make the colors match with CSS colors. However, in practice this does not work and can even make matters worse, because what is said about color in the specifications is not generally implemented.

sRGB

When you touch the issue of color values in a formal specification, you are supposed to somehow define the meaning of the values. The easy way to describe the meaning of color values would be this: “The color values are passed to the Windows graphics API. Authors should pick the color values in such a way that the intended appearance is achieved on an average PC.” Of course, that definition wouldn’t look good in a specification that is supposed to be precise and platform-neutral. It would look much better if there were a normative reference to a formal color space definition.

Some people working with color issues realized that it isn’t realistic to try to force Windows PCs to do color management. sRGB is a color space that models an average office PC with a usual mediocre CRT.

When a Windows PC or a Linux box is said to be an “sRGB system”, it is important to realize that these device/software combinations are not explicitly engineered to conform to a specification called sRGB. Instead, the specification is designed to conform to the systems! However, not all PCs are the same, so it’s not like all PCs have an exact common color space. sRGB is just an approximation of an average case.

Also, when it it said that a Mac is not an sRGB system, it is important to realize that a Mac can be configured to be one. It just might be that a Mac owner with a fancy Apple flat panel screen doesn’t necessarily want his/her display to emulate a mediocre office CRT.

sRGB in the CSS and PNG Specifications

According to the CSS2 specification, the CSS color values refer to the sRGB color space. In practice, however, all browsers except Mac IE 5 with ColorSync enabled (disabled by default) seem to just treat the CSS color values as values in whatever color space the system color space happens to be. Still, it would be reasonable to expect the colors of an sRGB-labeled PNG image to be treated consistently with CSS colors.

Again, it just doesn’t work that way in practice.

The PNG 1.0 specification, which is a W3C Recommendation, didn’t have an unambiguous way of indicating that the color space of an image is sRGB exactly. In theory, the result should be close if the gamma value of the image is set to 1/2.2. However, in practice the colors of images labeled that way do not match CSS colors in eg. Windows IE.

The PNG 1.1 specification, which is not a W3C Recommendation, added an unambiguous way of indicating that the color space of an image is sRGB—the sRGB chunk. There are problems, however.

  • In Mac IE 5 the colors of sRGB-labeled PNGs don’t match CSS colors when the ColorSync support is disabled as it is by default.
  • Safari applies a gamma change to sRGB-labeled PNGs but not to CSS colors making the colors not match.
  • The CSS2 specification doesn’t specify which ICC rendering intent should be used when mapping sRGB colors to the system color space. PNG 1.2, on the other hand, allows the rendering intent for the color space conversion to be defined. If a browser does color space conversion using ICC profiles and the rendering intent it uses for the CSS colors is different from the rendering intent defined in a PNG file, the resulting colors might differ even if the original colors were the same and in the same color space.

Impact on Authoring

In a nutshell: There is no way of making PNG images that match CSS colors in all PNG-supporting browsers. This reduces the usefulness of the otherwise excellent image format. If the image colors and the colors defined in a style sheet need to match, it is safer to use GIF or JPEG. If you want to use PNG and don’t care about older browser versions (pre-Tiger Safari in particular), the best course of action is removing all the color space information from the PNG files. If you only want a match with the background color, you could make the background a PNG image as well.

However, in cases where matching image colors with surrounding page colors is not of utmost importance, PNG images are safe to use. This not only means cases where the image is an independent rectangle but also cases where alpha blending is used.

Icons with a lighter and a darker rendering looking reasonable on different background colors thanks to alpha-blended edges.For example, fiMUG’s list of upcoming events has anti-aliased icons that can appear on two different backgrounds. Since it is a page of a Mac user group, we went ahead and used full PNG alpha transparency even though Windows IE doesn’t support it. Camino and Safari render the CSS background colors the same way but pre-Tiger Safari changes the gamma of the icons. However, thanks to alpha blending, the gamma change is mostly harmless in this case. (In the image, Camino’s rendering is on the left and pre-Tiger Safari’s is on the right.)

How did it come to this?

PNG gamma correction was supposed to make color consistent across platforms. However, the implementors weren’t sufficiently warned about the effects of gamma “correction” in situations where the image is not in isolation, so instead of fixing the original problem PNG gamma “correction” created a new, even worse problem: inconsistent color within a Web page.

The emphasis was put on doing some change to the gamma instead of emphasizing consistency with the surrounding colors in browsers. Also, guessing the gamma based on the operating system was presented as an acceptable method in the specification itself. That is, doing something was emphasized over correctness and consistency.

I’m sure many designers would agree that color consistency within a page is more important than color sameness across different computers or operating systems. I’d like to ask implementors of applications that deal with PNGs to pay attention to consistent color handling and not to do arbitrary gamma changes when the gamma properties of the output device are just guesses. Also, please treat the colors of PNGs with no color space information the same way you would treat the colors any other image file that doesn’t carry color space information.