mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-28 02:04:36 +03:00
Merge pull request #2898 from wiredfool/pr_2790
Add support for sRGB and cHRM chunks, permit sRGB when no iCCP chunk
This commit is contained in:
commit
bd5f99f19d
|
@ -387,12 +387,31 @@ class PngStream(ChunkStream):
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def chunk_gAMA(self, pos, length):
|
def chunk_gAMA(self, pos, length):
|
||||||
|
|
||||||
# gamma setting
|
# gamma setting
|
||||||
s = ImageFile._safe_read(self.fp, length)
|
s = ImageFile._safe_read(self.fp, length)
|
||||||
self.im_info["gamma"] = i32(s) / 100000.0
|
self.im_info["gamma"] = i32(s) / 100000.0
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
def chunk_cHRM(self, pos, length):
|
||||||
|
# chromaticity, 8 unsigned ints, actual value is scaled by 100,000
|
||||||
|
# WP x,y, Red x,y, Green x,y Blue x,y
|
||||||
|
|
||||||
|
s = ImageFile._safe_read(self.fp, length)
|
||||||
|
raw_vals = struct.unpack('>%dI' % (len(s) // 4), s)
|
||||||
|
self.im_info['chromaticity'] = tuple(elt/100000.0 for elt in raw_vals)
|
||||||
|
return s
|
||||||
|
|
||||||
|
def chunk_sRGB(self, pos, length):
|
||||||
|
# srgb rendering intent, 1 byte
|
||||||
|
# 0 perceptual
|
||||||
|
# 1 relative colorimetric
|
||||||
|
# 2 saturation
|
||||||
|
# 3 absolute colorimetric
|
||||||
|
|
||||||
|
s = ImageFile._safe_read(self.fp, length)
|
||||||
|
self.im_info['srgb'] = i8(s)
|
||||||
|
return s
|
||||||
|
|
||||||
def chunk_pHYs(self, pos, length):
|
def chunk_pHYs(self, pos, length):
|
||||||
|
|
||||||
# pixels per unit
|
# pixels per unit
|
||||||
|
@ -731,7 +750,9 @@ def _save(im, fp, filename, chunk=putchunk):
|
||||||
name = b"ICC Profile"
|
name = b"ICC Profile"
|
||||||
data = name + b"\0\0" + zlib.compress(icc)
|
data = name + b"\0\0" + zlib.compress(icc)
|
||||||
chunk(fp, b"iCCP", data)
|
chunk(fp, b"iCCP", data)
|
||||||
else:
|
|
||||||
|
# You must either have sRGB or iCCP.
|
||||||
|
# Disallow sRGB chunks when an iCCP-chunk has been emitted.
|
||||||
chunks.remove(b"sRGB")
|
chunks.remove(b"sRGB")
|
||||||
|
|
||||||
info = im.encoderinfo.get("pnginfo")
|
info = im.encoderinfo.get("pnginfo")
|
||||||
|
|
|
@ -49,6 +49,21 @@ class TestFilePng(PillowTestCase):
|
||||||
if "zip_encoder" not in codecs or "zip_decoder" not in codecs:
|
if "zip_encoder" not in codecs or "zip_decoder" not in codecs:
|
||||||
self.skipTest("zip/deflate support not available")
|
self.skipTest("zip/deflate support not available")
|
||||||
|
|
||||||
|
def get_chunks(self, filename):
|
||||||
|
chunks = []
|
||||||
|
with open(filename, "rb") as fp:
|
||||||
|
fp.read(8)
|
||||||
|
with PngImagePlugin.PngStream(fp) as png:
|
||||||
|
while True:
|
||||||
|
cid, pos, length = png.read()
|
||||||
|
chunks.append(cid)
|
||||||
|
try:
|
||||||
|
s = png.call(cid, pos, length)
|
||||||
|
except EOFError:
|
||||||
|
break
|
||||||
|
png.crc(cid, s)
|
||||||
|
return chunks
|
||||||
|
|
||||||
def test_sanity(self):
|
def test_sanity(self):
|
||||||
|
|
||||||
# internal version number
|
# internal version number
|
||||||
|
@ -501,18 +516,7 @@ class TestFilePng(PillowTestCase):
|
||||||
test_file = self.tempfile("temp.png")
|
test_file = self.tempfile("temp.png")
|
||||||
im.convert("P").save(test_file, dpi=(100, 100))
|
im.convert("P").save(test_file, dpi=(100, 100))
|
||||||
|
|
||||||
chunks = []
|
chunks = self.get_chunks(test_file)
|
||||||
with open(test_file, "rb") as fp:
|
|
||||||
fp.read(8)
|
|
||||||
with PngImagePlugin.PngStream(fp) as png:
|
|
||||||
while True:
|
|
||||||
cid, pos, length = png.read()
|
|
||||||
chunks.append(cid)
|
|
||||||
try:
|
|
||||||
s = png.call(cid, pos, length)
|
|
||||||
except EOFError:
|
|
||||||
break
|
|
||||||
png.crc(cid, s)
|
|
||||||
|
|
||||||
# https://www.w3.org/TR/PNG/#5ChunkOrdering
|
# https://www.w3.org/TR/PNG/#5ChunkOrdering
|
||||||
# IHDR - shall be first
|
# IHDR - shall be first
|
||||||
|
|
|
@ -408,9 +408,22 @@ PIL identifies, reads, and writes PNG files containing ``1``, ``L``, ``P``,
|
||||||
The :py:meth:`~PIL.Image.Image.open` method sets the following
|
The :py:meth:`~PIL.Image.Image.open` method sets the following
|
||||||
:py:attr:`~PIL.Image.Image.info` properties, when appropriate:
|
:py:attr:`~PIL.Image.Image.info` properties, when appropriate:
|
||||||
|
|
||||||
|
**chromaticity**
|
||||||
|
The chromaticity points, as an 8 tuple of floats. (``White Point
|
||||||
|
X``, ``White Point Y``, ``Red X``, ``Red Y``, ``Green X``, ``Green
|
||||||
|
Y``, ``Blue X``, ``Blue Y``)
|
||||||
|
|
||||||
**gamma**
|
**gamma**
|
||||||
Gamma, given as a floating point number.
|
Gamma, given as a floating point number.
|
||||||
|
|
||||||
|
**srgb**
|
||||||
|
The sRGB rendering intent as an integer.
|
||||||
|
|
||||||
|
* 0 Perceptual
|
||||||
|
* 1 Relative Colorimetric
|
||||||
|
* 2 Saturation
|
||||||
|
* 3 Absolute Colorimetric
|
||||||
|
|
||||||
**transparency**
|
**transparency**
|
||||||
For ``P`` images: Either the palette index for full transparent pixels,
|
For ``P`` images: Either the palette index for full transparent pixels,
|
||||||
or a byte string with alpha values for each palette entry.
|
or a byte string with alpha values for each palette entry.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user