Пример #1
0
def append(args):
    """
    Append files to an existing container 
    then reconstruct the png with the new keys attached
    """
    keys = generate_nkeys(len(args.files))
    random.shuffle(keys)
    (salt, key) = derive_key(args.key)
    fernet = Fernet(key)
    code_chunk = (CD_CHUNK, fernet.encrypt(cPickle.dumps(keys)))
    salt_chunk = (SL_CHUNK, salt)

    with open(args.container, "r") as container:
        reader = png.Reader(file=container)
        # This of course is horrible
        # We should use a temp file, but for now it is fine
        chunks = list(reader.chunks())
        (tend, iend) = chunks.pop()
        if tend != "IEND":
            print "Muh suck"
            sys.exit(1)

        for (file, key) in zip(args.files, keys):
            with open(file, "r") as hidee:
                name = file
                data = hidee.read()
                iname = (FN_CHUNK, name)
                fernet = Fernet(key)
                idata = (DT_CHUNK, fernet.encrypt(zlib.compress(data)))
                print "Packing %s" % (name)
                chunks = chunks + [iname] + [idata]
        with open(args.container + ".out", "w") as out:
            chunks = chunks + [code_chunk] + [salt_chunk] + [(tend, iend)]
            png.write_chunks(out, chunks)
Пример #2
0
def jrm_bake_streams(image_stream, assertion_string, newfile_stream=None):

    # Get the input stream from the image
    reader = png.Reader(file=image_stream)

    # Create a temporary file if no output file specified
    if newfile_stream is None:
        newfile_stream = NamedTemporaryFile(suffix='.png')

    # Build the chunk content with the assertion data
    chunkheader = "openbadges\x00\x00\x00\x00\x00"
    chunk_content = chunkheader + assertion_string

    # We are going to write the chunk in the "iTXt" chunk
    badge_chunk = (b'iTXt', chunk_content)

    # Insert our chunk as the second chunk in the image
    original_chunks = reader.chunks()
    final_chunks = []

    # Insert the first original chunk
    final_chunks.append(next(original_chunks))

    # Insert our chunk
    final_chunks.append(badge_chunk)

    # Insert the rest of the original chunks
    for t,c in original_chunks:
        final_chunks.append((t,c))

    # Write the new chunks into a new PNG file
    png.write_chunks(newfile_stream, final_chunks)

    newfile_stream.seek(0)
    return newfile_stream
Пример #3
0
 def helperFormat(self, f):
     r = png.Reader(bytes=pngsuite.basn0g01)
     o = BytesIO()
     def newchunks():
         for chunk in r.chunks():
             yield f(chunk)
     png.write_chunks(o, newchunks())
     r = png.Reader(bytes=o.getvalue())
     return list(r.asDirect()[2])
Пример #4
0
def bake(imageFile, assertion_json_string):
    reader = png.Reader(file=imageFile)

    filename = '%s.png' % hashlib.md5(str(assertion_json_string)).hexdigest()

    newfile = ContentFile("", name=filename)
    newfile.open()
    chunkheader = 'openbadges\x00\x00\x00\x00\x00'
    badge_chunk = ('iTXt', bytes(chunkheader + assertion_json_string))
    png.write_chunks(newfile, baked_chunks(reader.chunks(), badge_chunk))
    newfile.close()
    return newfile
Пример #5
0
def insert_text_chunk(src_png, dst_png, text):
    reader = png.Reader(filename=src_png)
    chunks = reader.chunks()
    chunk_list = list(chunks)

    chunk_item = tuple([b'tEXt', text])

    index = 1
    chunk_list.insert(index, chunk_item)

    with open(dst_png, 'wb') as dst_file:
        png.write_chunks(dst_file, chunk_list)
Пример #6
0
def insert_text_chunk(target, text, index=1):
    reader = png.Reader(filename=target)
    chunks = reader.chunks()
    chunk_list = list(chunks)
    # print(chunk_list[0])
    # print(chunk_list[1])
    # print(chunk_list[2])
    chunk_item = generate_text_chunk_tuple(text)
    chunk_list.insert(index, chunk_item)

    with open(target, 'wb') as dst_file:
        png.write_chunks(dst_file, chunk_list)
Пример #7
0
def insert_text_chunk(png_file,text):

    with open(text,'r') as text_file:
        text_content=text_file.read()

    reader = png.Reader(filename=png_file)
    chunks = reader.chunks()
    chunk_list = list(chunks)
    chunk_item = tuple(['tEXt',bytes(text_content,'utf-8')])
    chunk_list.insert(1, chunk_item) #insert tEXt chunk after iHDr

    with open(png_file,'wb') as dst_file:
        png.write_chunks(dst_file, chunk_list)
Пример #8
0
def insert_text_chunk(src_png, dst_png, text):
    reader = png.Reader(filename=src_png)
    chunks = reader.chunks()  # 创建一个每次返回一个chunk的生成器
    chunk_list = list(chunks)  # 把生成器的所有元素变成list
    # print(f"target png total chunks number is {len(chunk_list)}")
    chunk_item = tuple([b'tEXt', text])

    # 第一个chunk是固定的IHDR,我们把tEXt放在第2个chunk
    index = 1
    chunk_list.insert(index, chunk_item)

    with open(dst_png, 'wb') as dst_file:
        png.write_chunks(dst_file, chunk_list)
def read_icon(filename):
    if not os.path.exists(filename):
        print("ERROR: Cannot find file: {}".format(filename))
        sys.exit(1)

    reader = png.Reader(filename=filename)
    chunks = []
    for name, chunk in reader.chunks():
        if name in PNG_CHUNK_WHITELIST:
            chunks.append((name, chunk))

    output = io.BytesIO()
    png.write_chunks(output, chunks)
    return base64.b64encode(output.getvalue()).decode('ascii')
Пример #10
0
def _read_write_chunks_test():
    src = r'E:\temp\png\register_02.png'
    dst = r'E:\temp\png\register_03.png'
    reader = png.Reader(filename=src)
    chunks = reader.chunks()
    chunk_list = list(chunks)
    print(chunk_list[0])
    print(chunk_list[1])
    print(chunk_list[2])
    chunk_item = generate_text_chunk_tuple('what are you doing?')
    chunk_list.insert(1, chunk_item)

    with open(dst, 'wb') as dst_file:
        png.write_chunks(dst_file, chunk_list)
        print('from {} generated new png file {}.'.format(src, dst))
Пример #11
0
def read_modify_chunks(modify_chunk):
    """Create a temporary PNG file by modifying the chunks of
    an existing one, then read that temporary file.
    Each chunk is passed through the function `modify_chunk`.
    """

    r = png.Reader(bytes=pngsuite.basn0g01)
    o = BytesIO()

    def newchunks():
        for chunk in r.chunks():
            yield modify_chunk(chunk)

    png.write_chunks(o, newchunks())
    r = png.Reader(bytes=o.getvalue())
    return list(r.asDirect()[2])
Пример #12
0
def bake(imageFile, assertion_json_string):
    """
    Embeds a serialized representation of a badge instance in a PNG image file.
    """
    reader = png.Reader(file=imageFile)

    output_filename = "%s.png" % hashlib.md5(str(assertion_json_string)).hexdigest()

    newfile = ContentFile("", name=output_filename)
    newfile.open()
    chunkheader = "openbadges\x00\x00\x00\x00\x00"
    badge_chunk = ("iTXt", bytes(chunkheader + assertion_json_string))
    png.write_chunks(newfile, baked_chunks(reader.chunks(), badge_chunk))

    newfile.close()
    return newfile
Пример #13
0
def bake(imageFile, assertion_json_string):
    """
    Embeds a serialized representation of a badge instance in a PNG image file.
    """
    reader = png.Reader(file=imageFile)

    output_filename = '%s.png' % hashlib.md5(str(assertion_json_string)).hexdigest()

    newfile = ContentFile("", name=output_filename)
    newfile.open()
    chunkheader = 'openbadges\x00\x00\x00\x00\x00'
    badge_chunk = ('iTXt', bytes(chunkheader + assertion_json_string))
    png.write_chunks(newfile, baked_chunks(reader.chunks(), badge_chunk))

    newfile.close()
    return newfile
Пример #14
0
def insert_text_chunk(target, text, index=1):
    if index < 0:
        raise Exception('The index value {} less than 0!'.format(index))

    reader = png.Reader(filename=target)
    chunks = reader.chunks()
    chunk_list = list(chunks)
    print(chunk_list[0])
    print(chunk_list[1])
    print(chunk_list[2])
    chunk_item = generate_text_chunk_tuple(text)
    print('chunk_item', chunk_item)
    chunk_list.insert(index, chunk_item)

    with open(target, 'wb') as dst_file:
        png.write_chunks(dst_file, chunk_list)
Пример #15
0
def bake(imageFile, assertion_string, newfile=None):
    """
    Embeds a serialized representation of a badge instance in a PNG image file.
    """
    encoded_assertion_string = codecs.getwriter('utf-8')(assertion_string)
    reader = png.Reader(file=imageFile)

    if newfile is None:
        newfile = NamedTemporaryFile(suffix='.png')

    chunkheader = 'openbadges\x00\x00\x00\x00\x00'
    badge_chunk = ('iTXt',
                   bytes(chunkheader + encoded_assertion_string.stream))
    png.write_chunks(newfile, baked_chunks(reader.chunks(), badge_chunk))

    newfile.seek(0)
    return newfile
Пример #16
0
def insert_text_chunk(target, text, index=1):
    if index < 0:
        raise Exception('The index value {} less than 0!'.format(index))

    reader = png.Reader(filename=str(target))
    chunks = reader.chunks()
    chunk_list = list(chunks)

    # add non comment chunks to new list, basically removes all existing comments
    new_chunk_list = []
    for chunk in chunk_list:
        if b'tEXt' not in chunk[0]:
            new_chunk_list.append(chunk)

    # add the new comment with postions
    chunk_item = generate_text_chunk_tuple(text)
    new_chunk_list.insert(index, chunk_item)

    with open(str(target), 'wb') as dst_file:
        png.write_chunks(dst_file, new_chunk_list)
Пример #17
0
    def helperFormat(self, f, idat_only=True):
        """
        Helper for format tests

        call `f` function to change chunks
        """
        pngsuite.png["basn0g01"].seek(0)
        r = png.Reader(pngsuite.png["basn0g01"])
        o = BytesIO()

        def newchunks():
            """chunks conversion"""
            for chunk in r.chunks():
                if idat_only and chunk[0] != 'IDAT':
                    yield chunk
                else:
                    yield f(*chunk)
        png.write_chunks(o, newchunks())
        r = png.Reader(bytes=o.getvalue())
        return list(r.asDirect()[2])
Пример #18
0
    def test_plte_bkgd(self):
        """
        Test colortype 3 PNG with bKGD chunk.
        For coverage.
        """
        k = 'basn3p04'
        reader = png.Reader(bytes=pngsuite.png[k])

        def more_chunks():
            for t, v in reader.chunks():
                yield t, v
                if t == b'PLTE':
                    yield b'bKGD', b'\x00'

        o = BytesIO()
        png.write_chunks(o, more_chunks())

        reader = png.Reader(bytes=o.getvalue())
        _, _, rows, info = reader.read()
        list(rows)
Пример #19
0
    def test_chunk_after_idat(self):
        """
        Test with a PNG that has an ancillary chunk after IDAT chunks.
        For coverage.
        """
        k = 'f02n0g08'
        reader = png.Reader(bytes=pngsuite.png[k])
        text_chunk = (b'tEXt', b'Comment\x00Test chunk follows IDAT')

        def more_chunks():
            for t, v in reader.chunks():
                if t == b'IEND':
                    yield text_chunk
                yield t, v

        o = BytesIO()
        png.write_chunks(o, more_chunks())

        reader = png.Reader(bytes=o.getvalue())
        _, _, rows, info = reader.read()
        list(rows)
Пример #20
0
def bake(image, assertion_string: str, newfile=None):
    """
    Embeds a serialized representation of a badge instance in a PNG image file.
    """
    #    encoded_assertion_string = codecs.getwriter('utf-8')(assertion_string)

    # Prepare to read from the image (could be a file name, a stream or a byte array)
    reader = png.Reader(image)

    if newfile is None:
        newfile = "baked.png"

    chunkheader = b'openbadges\x00\x00\x00\x00\x00'
    chunk_content = chunkheader + bytes(assertion_string, encoding="utf-8")
    badge_chunk = (b'iTXt', chunk_content)

    with open(newfile, "wb") as newFileStream:
        png.write_chunks(newFileStream,
                         baked_chunks(reader.chunks(), badge_chunk))

    return
Пример #21
0
    def helperFormat(self, f, idat_only=True):
        """
        Helper for format tests

        call `f` function to change chunks
        """
        pngsuite.png["basn0g01"].seek(0)
        r = png.Reader(pngsuite.png["basn0g01"])
        o = BytesIO()

        def newchunks():
            """chunks conversion"""
            for chunk in r.chunks():
                if idat_only and chunk[0] != 'IDAT':
                    yield chunk
                else:
                    yield f(*chunk)

        png.write_chunks(o, newchunks())
        r = png.Reader(bytes=o.getvalue())
        return list(r.asDirect()[2])
Пример #22
0
def bake_badge(src, dest, url):
    """
    Bake the given PNG file with the given assertion URL. The source and
    destination can be filenames or file objects.

    Example:

        >>> bake_badge('unbaked.png', 'baked.png', 'http://f.org/a.json')
    """

    if isinstance(src, basestring): src = open(src, 'rb')
    if isinstance(dest, basestring): dest = open(dest, 'wb')

    reader = png.Reader(file=src)
    chunks = [
        (chunktype, content) for chunktype, content in reader.chunks()
        if not (chunktype == 'tEXt' and content.startswith('openbadges\x00'))
    ]

    chunks.insert(1, ('tEXt', '\x00'.join(('openbadges', url))))
    png.write_chunks(dest, chunks)
Пример #23
0
    def save(self, filename):
        """Save the image.

        PyPNG doesn't support sBIT chunks with a palette, but this method works
        around that and adds one anyway.
        """

        # Write to a temporary in-memory PNG
        temp_png = io.BytesIO()
        writer = png.Writer(width=self.width, height=self.height,
                            palette=self.palette)
        writer.write(temp_png, self.pixels)

        # Read temp PNG's chunks, and insert an sBIT chunk manually
        temp_png.seek(0)
        reader = png.Reader(temp_png)
        chunks = list(reader.chunks())
        chunks.insert(1, ('sBIT', b'\x05\x05\x05'))

        # Write chunks to an actual file
        with open(filename, 'wb') as png_file:
            png.write_chunks(png_file, chunks)
Пример #24
0
def bake_badge(src, dest, url):
    """
    Bake the given PNG file with the given assertion URL. The source and
    destination can be filenames or file objects.

    Example:

        >>> bake_badge('unbaked.png', 'baked.png', 'http://f.org/a.json')
    """

    if isinstance(src, basestring): src = open(src, 'rb')
    if isinstance(dest, basestring): dest = open(dest, 'wb')

    reader = png.Reader(file=src)
    chunks = [
        (chunktype, content)
        for chunktype, content in reader.chunks()
        if not (chunktype == 'tEXt' and content.startswith('openbadges\x00'))
    ]

    chunks.insert(1, ('tEXt', '\x00'.join(('openbadges', url))))
    png.write_chunks(dest, chunks)
Пример #25
0
def distill(f=None, filename=None):
    if filename:
        f = open(filename)

    if not f:
        raise ValueError('No file was supplied to distill')

    reader = png.Reader(f)
    chunks = [(ct, c) for (ct, c) in reader.chunks()]
    rebuilt_idat_chunk = build_idat_chunk(chunks)
    distilled_chunks = reduce(_reduce_chunks, chunks, [])

    def _remap_chunks(acc, c):
        if c[0] == 'IDAT':
            acc.append(rebuilt_idat_chunk)
        else:
            acc.append(c)

        return acc

    result_chunks = reduce(_remap_chunks, distilled_chunks, [])
    result = StringIO()
    png.write_chunks(result, result_chunks)
    return result
Пример #26
0
def distill(f=None, filename=None):
    if filename:
        f = open(filename)

    if not f:
        raise ValueError('No file was supplied to distill')

    reader = png.Reader(f)
    chunks = [(ct, c) for (ct, c) in reader.chunks()]
    rebuilt_idat_chunk = build_idat_chunk(chunks)
    distilled_chunks = reduce(_reduce_chunks, chunks, [])

    def _remap_chunks(acc, c):
        if c[0] == 'IDAT':
            acc.append(rebuilt_idat_chunk)
        else:
            acc.append(c)

        return acc

    result_chunks = reduce(_remap_chunks, distilled_chunks, [])
    result = StringIO()
    png.write_chunks(result, result_chunks)
    return result
Пример #27
0
import png
#pip install pypng
fin = open('odrrere.png', 'rb')
image = png.Reader(fin)
chunks = []
#initially found is empty
found = [0, 12, 8, 4, 9, 10, 6, 7, 3, 5, 2, 11, 1]
curr = 3 + len(found)

for i in image.chunks():
    chunks.append(i)
for i in range(0, 13):
    if i in found and i > 0:
        continue
    temp = list(chunks)
    fout = open('temp/' + str(curr) + '_' + str(i) + '.png', 'wb')
    for j in range(0, len(found)):
        temp[3 + j] = chunks[found[j] + 3]
    temp[curr] = chunks[3 + i]
    png.write_chunks(fout, temp)
    fout.close()
Пример #28
0
def append_json_to_png(filename, data):
    chunks = list(png.Reader(filename).chunks())
    bin_data = zlib.compress(bytes(json.dumps(data), "utf-8"))
    chunks.insert(len(chunks) - 1, (b"iTXt", bin_data))
    with open(filename, 'wb') as file:
        png.write_chunks(file, chunks)
Пример #29
0
def chunk(out, inp, l):
    """Process the input PNG file to the output, chunk by chunk.  Chunks
    can be inserted, removed, replaced, or sometimes edited.  Generally, 
    chunks are not inspected, so pixel data (in the ``IDAT`` chunks)
    cannot be modified.  `l` should be a list of (*chunktype*,
    *content*) pairs.  *chunktype* is usually the type of the PNG chunk,
    specified as a 4-byte Python string, and *content* is the chunk's
    content, also as a string; if *content* is ``None`` then *all*
    chunks of that type will be removed.

    This function *knows* about certain chunk types and will
    automatically convert from Python friendly representations to
    string-of-bytes.

    chunktype
    'gamma'     'gAMA'  float
    'sigbit'    'sBIT'  int, or tuple of length 1,2 or 3

    Note that the length of the strings used to identify *friendly*
    chunk types is greater than 4, hence they cannot be confused with
    canonical chunk types.

    Chunk types, if specified using the 4-byte syntax, need not be
    official PNG chunks at all.  Non-standard chunks can be created.
    """

    def canonical(p):
        """Take a pair (*chunktype*, *content*), and return canonical
        representation (*chunktype*, *content*) where `chunktype` is the
        4-byte PNG chunk type and `content` is a string.
        """

        t,v = p
        if len(t) == 4:
            return t,v
        if t == 'gamma':
            t = 'gAMA'
            v = int(round(1e5*v))
            v = struct.pack('>I', v)
        elif t == 'sigbit':
            t = 'sBIT'
            try:
                v[0]
            except TypeError:
                v = (v,)
            v = struct.pack('%dB' % len(v), *v)
        elif t == 'iccprofile':
            t = 'iCCP'
            # http://www.w3.org/TR/PNG/#11iCCP
            v = 'a color profile\x00\x00' + v.encode('zip')
        else:
            warnings.warn('Unknown chunk type %r' % t)
        return t[:4],v

    l = map(canonical, l)
    # Some chunks automagically replace ones that are present in the
    # source PNG.  There can only be one of each of these chunk types.
    # Create a 'replace' dictionary to record these chunks.
    add = []
    delete = set()
    replacing = set(['gAMA', 'sBIT', 'PLTE', 'tRNS', 'sPLT', 'IHDR'])
    replace = dict()
    for t,v in l:
        if v is None:
            delete.add(t)
        elif t in replacing:
            replace[t] = v
        else:
            add.append((t,v))
    del l
    r = png.Reader(file=inp)
    chunks = r.chunks()
    def iterchunks():
        for t,v in chunks:
            if t in delete:
                continue
            if t in replace:
                yield t,replace[t]
                del replace[t]
                continue
            if t == 'IDAT' and replace:
                # Insert into the output any chunks that are on the
                # replace list.  We haven't output them yet, because we
                # didn't see an original chunk of the same type to
                # replace.  Thus the "replace" is actually an "insert".
                for u,w in replace.items():
                    yield u,w
                    del replace[u]
            if t == 'IDAT' and add:
                for item in add:
                    yield item
                del add[:]
            yield t,v
    return png.write_chunks(out, iterchunks())
Пример #30
0
import png
#pip install pypng
fin = open('odrrere.png','rb')
image = png.Reader(fin)
chunks = []
#initially found is empty
found =[0,12,8,4,9,10,6,7,3,5,2,11,1]
curr = 3 + len(found)

for i in image.chunks():
    chunks.append(i)
for i in range(0,13):
    if i in found and i > 0:
        continue
    temp = list(chunks)
    fout = open('temp/'+str(curr)+'_'+str(i)+'.png','wb')
    for j in range(0,len(found)):
        temp[3+j] = chunks[found[j]+3]
    temp[curr]  = chunks[3+i]
    png.write_chunks(fout,temp)
    fout.close()
Пример #31
0
"""


from PIL import Image  # type: ignore
import glob
import re
import png  # type: ignore

for sprite in glob.glob("assets/sprites/*.png"):
    pre_chunk_list = list(png.Reader(sprite).chunks())
    img = Image.open(sprite)
    img.save(sprite, transparency=3, optimize=1)
    post_chunk_list = list(png.Reader(sprite).chunks())
    for chunk in pre_chunk_list:
        if re.compile(b"..Xt").match(chunk[0]):
            post_chunk_list.insert(2, chunk)
    with open(sprite, "wb") as out_sprite:
        png.write_chunks(out_sprite, post_chunk_list)


for ui_piece in glob.glob("assets/ui/*.png"):
    pre_chunk_list = list(png.Reader(ui_piece).chunks())
    img = Image.open(ui_piece)
    img.save(ui_piece, transparency=3, optimize=1)
    post_chunk_list = list(png.Reader(ui_piece).chunks())
    for chunk in pre_chunk_list:
        if re.compile(b"..Xt").match(chunk[0]):
            post_chunk_list.insert(2, chunk)
    with open(ui_piece, "wb") as out_ui_piece:
        png.write_chunks(out_ui_piece, post_chunk_list)
Пример #32
0
def extract_png(image):

    # TODO: Maybe just use APNG: https://pypi.org/project/apng/

    img = APNG.open(image.veritas.file_name)

    if len(img.frames) == 1:
        logger.debug('Only one frame detected.')
        return

    print("Extracting {} PNG frames.".format(len(img.frames)))
    for i, (png, control) in enumerate(img.frames):
        outfile = os.path.join(
            image.veritas.results_directory,
            '{}_frame_{}.png'.format(os.path.basename(image.veritas.file_name),
                                     i))
        png.save(outfile)

    return

    ### Below is some original work before finding that library

    # PIL apparently can't handle this. Neither can ffmpeg. ImageMagick can be fooled.
    # Time to write my own animated png extractor

    img = png.Reader(image.veritas.file_name)
    chunks = list(img.chunks())

    num_frames = len(list(x for x in chunks if x[0] in [b'fcTL']))
    """
    actl = next(x for x in chunks if x[0] == b'acTL')

    # How many frames does the image claim to have
    given_num_frames, _ = unpack('>II', actl[1])

    if given_num_frames != num_frames:
        print('Image only claims {} frames, but I discovered {}'.format(given_num_frames, num_frames))
        print('Patching and attempting to extract the frames')

        new_actl = (b'acTL', pack('>II',num_frames,0))

        new_chunks = []
        frame_number = 0
        for t,v in chunks:
            if t == b'acTL':
                new_chunks.append(new_actl)

            elif t == b'fcTL':
                new_chunks.append((t, pack('>I', frame_number) + v[4:]))
                frame_number += 1

            else:
                new_chunks.append((t,v))

        with open('blerg.png','wb') as f:
            png.write_chunks(f, new_chunks)

    return
    """

    #######

    if num_frames == 1:
        logger.debug('Only one frame discovered.')
        return

    print('Discovered multuple PNG frames. Attempting to extract them...')

    header_chunk = next(x for x in chunks if x[0] in [b'IHDR'])
    end_chunk = (b'IEND', b'')
    actl_chunk = (b'acTL', b'\x00\x00\x00\x01\x00\x00\x00\x00'
                  )  # looping, 1 frame

    new_image = []
    num_frames = 0

    # Type and value for the chunks
    for t, val in chunks:
        print(t)

        # We're done with this image
        if t in [b'fcTL', b'IEND']:

            # We have something to save
            if new_image != []:

                # Put propper chunks in place
                new_image.insert(0, copy(actl_chunk))
                new_header_chunk = list(copy(header_chunk))
                #new_header_chunk[1] = pack('>II', width, height) + new_header_chunk[1][8:]
                #new_header_chunk[1] = width_height + new_header_chunk[1][8:]
                new_header_chunk = tuple(new_header_chunk)
                new_image.insert(0, new_header_chunk)
                #new_image.insert(0, copy(header_chunk))
                new_image.append(copy(end_chunk))
                print(new_image)

                outfile = os.path.join(
                    image.veritas.results_directory, '{}_frame_{}.png'.format(
                        os.path.basename(image.veritas.file_name), num_frames))
                print(outfile)

                with open(outfile, 'wb') as f:
                    png.write_chunks(f, new_image)

                #new_image = [(t, val)]
                new_image = []
                num_frames += 1

            if t == b'fcTL':
                # Update our frame size
                #width, height = unpack('>II', val[4:12])
                #print('width and height: ' + str(width) + ' ' + str(height))
                #width_height = val[4:12]
                #new_image.append((t, b'\x00\x00\x00\x00' + val[4:]))
                new_image.append((t, val))

            # Nothing to save, just add our header in
            #else:
            #    new_image.append((t, val))

        elif t == b'IDAT':
            new_image.append((t, val))

        elif t == b'fdAT':
            # fdAT is simply IDAT with 4 bytes at the beginning
            new_image.append((b'IDAT', val[4:]))
        """