Skip to content

Commit

Permalink
More fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Scondo committed Dec 3, 2016
1 parent d4f6bdd commit d6cfc66
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 19 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ matrix:
env: USE_CYTHON=yes

install:
- pip install argparse
- pip install pillow
- pip install -r pip_numpy.txt
- if [[ $TRAVIS_PYTHON_VERSION == '3.2' ]]; then pip install "coverage<4"; fi
Expand Down
1 change: 1 addition & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ install:
# pip will build them from source using the MSVC compiler matching the
# target Python version and architecture
- "%CMD_IN_ENV% easy_install nose"
- "%CMD_IN_ENV% easy_install argparse"
# - "%CMD_IN_ENV% easy_install PIL"
# Disabled due to https://github.com/lemurheavy/coveralls-public/issues/613
# - "if %py_minor% GEQ 6 %CMD_IN_ENV% easy_install coverage"
Expand Down
34 changes: 31 additions & 3 deletions extools/pngrepack.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,35 @@
import sys
import png
import zlib
import logging


def buf_emu(not_buffer):
if hasattr(not_buffer, 'tostring'):
return not_buffer.tostring()
else:
return bytes(not_buffer)


try:
buffer
except NameError:
try:
buffer = memoryview
except NameError:
buffer = buf_emu

if sys.platform.startswith('java'):
# buffer object in Jython is not compatible with zlib
oldbuf = buffer
def buffer(src):
return str(oldbuf(src))


def comp_idat(idat, level):
compressor = zlib.compressobj(level)
for dat in idat:
compressed = compressor.compress(dat)
compressed = compressor.compress(buffer(dat))
if compressed:
yield compressed
flushed = compressor.flush()
Expand All @@ -24,16 +47,20 @@ def Recompress(inp, out, level=6, filt='keep'):
p = png.Reader(file=inp)
if filt == 'keep':
p.preamble()
# Python 2.3 doesn' work with inline if
if p.plte:
palette = p.palette()
else:
palette = None
wr = png.Writer(size=(p.width, p.height),
greyscale=p.greyscale, alpha=p.alpha,
bitdepth=p.bitdepth,
palette=p.palette() if p.plte else None,
palette=palette,
transparent=getattr(p, 'transparent', None),
background=getattr(p, 'background', None),
gamma=getattr(p, 'gamma', None),
compression=level,
interlace=p.interlace)
wr.color_type = p.color_type # just to be sure. Check if needed?
wr.write_idat(out, comp_idat(p.idatdecomp(), level))
else:
pix, meta = p.read()[2:]
Expand All @@ -56,6 +83,7 @@ def main(argv=None):
a = p.parse_args(argv[1:])

Recompress(a.input, a.output, a.level, a.filter)
a.input.close()


if __name__ == '__main__':
Expand Down
3 changes: 2 additions & 1 deletion png/PngImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ def _open(self):
self.info.update(meta['text']) # experimental

def verify(self):
"Verify PNG file"
"""Verify PNG file"""
# TODO: actual verivy (e.g load all chunks to check CRC)
pass

def load_read(self, n_bytes):
Expand Down
34 changes: 21 additions & 13 deletions png/png.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,11 +359,11 @@ def check_sizes(size, width, height):
if width is not None and width != size[0]:
raise ValueError(
"size[0] (%r) and width (%r) should match when both are used."
% (size[0], width))
% (size[0], width))
if height is not None and height != size[1]:
raise ValueError(
"size[1] (%r) and height (%r) should match when both are used."
% (size[1], height))
% (size[1], height))
return size


Expand Down Expand Up @@ -757,7 +757,7 @@ def __init__(self, width=None, height=None,
see :meth:`set_resolution`
filter_type
Enable and specify PNG filter
see :meth:`set_filter`
see :meth:`set_filter_type`
The image size (in pixels) can be specified either by using the
`width` and `height` arguments, or with the single `size`
Expand Down Expand Up @@ -963,14 +963,19 @@ def __init__(self, width=None, height=None,
self.chunk_limit = chunk_limit
self.interlace = bool(interlace)

colormap = bool(self.palette)
self.color_type = 4 * self.alpha + 2 * (not greyscale) + 1 * colormap
assert self.color_type in (0, 2, 3, 4, 6)
if bool(self.palette) and (self.greyscale or self.alpha):
raise FormatError("Paletted image could not be grayscale or"
" contain alpha plane")

self.color_planes = (3, 1)[self.greyscale or colormap]
self.planes = self.color_planes + self.alpha
self.planes = (3, 1)[self.greyscale or bool(self.palette)] + self.alpha

def set_icc_profile(self, profile=None, name='ICC Profile'):
"""
Add ICC Profile.
Prefered way is tuple (`profile_name`, `profile_bytes`), but only
bytes with name as separate argument is also supported.
"""
if isinstance(profile, (basestring, bytes)):
icc_profile = [name, profile]
# TODO: more check
Expand All @@ -984,7 +989,8 @@ def set_icc_profile(self, profile=None, name='ICC Profile'):
self.icc_profile = icc_profile

def set_text(self, text=None, **kwargs):
"""Add textual information.
"""
Add textual information passed as dictionary.
All pairs in dictionary will be written, but keys should be latin-1;
registered keywords could be used as arguments.
Expand All @@ -1000,7 +1006,7 @@ def set_text(self, text=None, **kwargs):
*(check_time(text['Creation Time'])[:6])).isoformat()
self.text = text

def set_filter(self, filter_type=None):
def set_filter_type(self, filter_type=None):
"""
Set(modify) filtering mode for better compression
Expand Down Expand Up @@ -1255,11 +1261,13 @@ def write_idat(self, outfile, idat_sequence):
"""
# http://www.w3.org/TR/PNG/#5PNG-file-signature
outfile.write(png_signature)
color_type = 4 * self.alpha + 2 * (not self.greyscale) +\
bool(self.palette)

# http://www.w3.org/TR/PNG/#11IHDR
write_chunk(outfile, 'IHDR',
struct.pack("!2I5B", self.width, self.height,
self.bitdepth, self.color_type,
self.bitdepth, color_type,
0, 0, self.interlace))
# See :chunk:order
self.__write_srgb(outfile)
Expand Down Expand Up @@ -2184,7 +2192,7 @@ def deinterlace(self, raw):
# Last pass (0, 1, 1, 2))
assert xstart == 0
offset = y * vpr
a[offset:offset + end_offset] = flat
a[offset:end_offset] = flat
else:
offset = y * vpr + xstart * self.planes
for i in range(self.planes):
Expand Down Expand Up @@ -2372,7 +2380,7 @@ def _process_IHDR(self, data):

# Derived values
# http://www.w3.org/TR/PNG/#6Colour-values
colormap = bool(self.color_type & 1)
colormap = bool(self.color_type & 1)
greyscale = not (self.color_type & 2)
alpha = bool(self.color_type & 4)
color_planes = (3,1)[greyscale or colormap]
Expand Down
6 changes: 4 additions & 2 deletions test_png.py
Original file line number Diff line number Diff line change
Expand Up @@ -1173,12 +1173,14 @@ def testRepackKeep(self):
lambda: extools.pngrepack.main(['repackkeep', '-l 1',
s, '-']))
o.seek(0)
r = png.Reader(bytes=o.getvalue())
r = png.Reader(o)
sr = png.Reader(filename=s)
rpix, metar = r.read()[2:]
spix, metas = sr.read()[2:]
self.assertEqual(metar, metas)
self.assertEqual(list(rpix), list(spix))
rpix = list(rpix)
spix = list(spix)
self.assertEqual(rpix, spix)

def testRepackSum(self):
"""Test repack tool repacking image with sum strategy"""
Expand Down

0 comments on commit d6cfc66

Please sign in to comment.