Skip to content

Commit

Permalink
Add: support num_plays (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
eight04 committed Apr 19, 2018
1 parent aeb6973 commit 6227156
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 3 deletions.
11 changes: 9 additions & 2 deletions apng/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,14 +214,18 @@ def from_bytes(cls, b):

class APNG:
"""Represent APNG image."""
def __init__(self):
def __init__(self, num_plays=0):
"""APNG is composed by multiple PNGs, which can be inserted with
:meth:`append`.
:arg int num_plays: Number of times to loop. 0 = infinite.
:var frames: Frames of APNG, a list of ``(png, control)`` tuple.
:vartype frames: list[tuple(PNG, FrameControl)]
:var int num_plays: same as ``num_plays``.
"""
self.frames = []
self.num_plays = num_plays

def append(self, png, **options):
"""Read a PNG file and append one frame.
Expand Down Expand Up @@ -258,7 +262,7 @@ def to_bytes(self):
out.append(png.hdr)

# acTL
out.append(make_chunk("acTL", struct.pack("!II", len(self.frames), 0)))
out.append(make_chunk("acTL", struct.pack("!II", len(self.frames), self.num_plays)))

# fcTL
if control:
Expand Down Expand Up @@ -337,6 +341,7 @@ def open(cls, file):

frame_chunks = []
frames = []
num_plays = 0

control = None

Expand All @@ -345,6 +350,7 @@ def open(cls, file):
hdr = data
frame_chunks.append((type, data))
elif type == "acTL":
num_frames, num_plays = struct.unpack("!II", data[8:-4])
continue
elif type == "fcTL":
if any(type == "IDAT" for type, data in frame_chunks):
Expand Down Expand Up @@ -376,6 +382,7 @@ def open(cls, file):

o = cls()
o.frames = frames
o.num_plays = num_plays
return o

def save(self, file):
Expand Down
11 changes: 10 additions & 1 deletion test.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ def iter_frames(dir):

for dir in pathlib.Path("test").iterdir():
with self.subTest("dir: {}".format(dir.name)):
im = APNG()
try:
property = json.loads(dir.joinpath("property.json").read_text())
except OSError:
property = {}
im = APNG(**property)
for png, ctrl in iter_frames(dir):
im.append(png, **ctrl)
filename = "{}-animated.png".format(dir.stem)
Expand All @@ -61,6 +65,11 @@ def test_disassemble(self):
for dir in pathlib.Path("test").iterdir():
with self.subTest(dir.stem):
im = APNG.open(dir.joinpath("animated.png"))
property = dir.joinpath("property.json")
if property.exists():
property = json.loads(property.read_text())
for key, value in property.items():
assert getattr(im, key) == value
for i, (png, ctrl) in enumerate(im.frames):
filename = "{}-{}.png".format(dir.stem, i + 1)
png.save(pathlib.Path("build").joinpath(filename))
Expand Down
Binary file added test/num_plays/animated.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/num_plays/frame-1.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/num_plays/frame-2.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions test/num_plays/property.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"num_plays": 3
}

0 comments on commit 6227156

Please sign in to comment.