Commit eb69847a authored by Avi Drissman's avatar Avi Drissman Committed by Commit Bot

Allow indexed color PNGs for Mac icons

optipng sometimes finds that using indexed color yields a smaller PNG
file. Allow that.

Also add a comment to the sRGB code explaining why that value was
chosen.

Bug: 846451
Change-Id: Ia8d6ef7dba59e4a0a0cbbf4d3122f63c501cfabf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2148030
Commit-Queue: Avi Drissman <avi@chromium.org>
Reviewed-by: default avatarMark Mentovai <mark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#759421}
parent 2cf281d8
......@@ -26,14 +26,9 @@ scrambling of the icons in display. If the old types work, why mess with them?
## Source PNG files
Use whatever tools you want to create the PNG files, but please note the
following:
1. The PNG files must be in full RGB mode (i.e. not indexed-color). This will be
enforced by the `png_check.py` tool below.
1. The dimensions of the images in the PNG files must match exactly the size
indicated by their filename. This will be enforced by the `makeicns2` tool
below.
Use whatever tools you want to create the PNG files, but please note that the
dimensions of the images in the PNG files must match exactly the size indicated
by their filename. This will be enforced by the `makeicns2` tool below.
## Construction
......
[style]
based_on_style = chromium
indent_width = 4
\ No newline at end of file
indent_width = 4
......@@ -16,11 +16,19 @@ def verify(path):
magic = file.read(8)
assert magic == b'\x89\x50\x4e\x47\x0d\x0a\x1a\x0a'
color_type = None
chunk_types = []
while True:
chunk_header = file.read(8)
(chunk_length, chunk_type) = struct.unpack('>I4s', chunk_header)
file.seek(chunk_length, 1)
if chunk_type == b'IHDR':
ihdr = file.read(chunk_length)
(width, height, bit_depth, color_type, compression_method,
filter_method, interlace_method) = struct.unpack('>2I5b', ihdr)
else:
file.seek(chunk_length, 1)
chunk_footer = file.read(4)
(chunk_crc,) = struct.unpack('>I', chunk_footer)
......@@ -29,10 +37,16 @@ def verify(path):
if chunk_type == b'IEND':
break
assert chunk_types == [b'IHDR', b'sRGB', b'IDAT', b'IEND']
# Some images showed up with [b'IHDR', b'sRGB', b'PLTE', b'tRNS', b'IDAT',
# b'IEND'] but these wound up being smaller when compressed with
# optipng/advpng without being in indexed-color mode.
# The only two color types that have transparency and can be used for icons
# are types 3 (indexed) and 6 (direct RGBA).
assert color_type in (3, 6), "Disallowed color type {}".format(color_type)
allowed_chunk_types = [b'IHDR', b'sRGB', b'IDAT', b'IEND']
if color_type == 3:
allowed_chunk_types.extend([b'PLTE', b'tRNS'])
for chunk_type in chunk_types:
assert (chunk_type in allowed_chunk_types
), "Disallowed chunk of type {}".format(chunk_type)
eof = file.read(1)
assert len(eof) == 0
......
......@@ -10,6 +10,7 @@
# conflict with the sRGB. Obviously, only use this if it's desirable for the
# png file to be treated as sRGB.
import binascii
import struct
import sys
......@@ -51,8 +52,23 @@ def make_srgb(path):
remainder = file.read()
file.seek(after_ihdr)
# Length, type, data, CRC
file.write(b'\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9')
# Note that a value of 0 is a perceptual rendering intent (e.g.
# photographs) while a value of 1 is a relative colorimetric rendering
# intent (e.g. icons). Every macOS icon that has an 'sRGB' chunk uses 0
# so that is what is used here. Please forgive us, UX.
#
# Reference:
# http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.sRGB
srgb_chunk_type = struct.pack('>4s', b'sRGB')
srgb_chunk_data = struct.pack('>b', 0) # Perceptual
srgb_chunk_length = struct.pack('>I', len(srgb_chunk_data))
srgb_chunk_crc = struct.pack(
'>I',
binascii.crc32(srgb_chunk_type + srgb_chunk_data) & 0xffffffff)
srgb_chunk = (
srgb_chunk_length + srgb_chunk_type + srgb_chunk_data +
srgb_chunk_crc)
file.write(srgb_chunk)
file.write(remainder)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment