
# http://www.python.org/doc/2.4.4/lib/module-itertools.html
import itertools
import sys

import png

Description = """Join PNG images in a column top-to-bottom."""


class FormatError(Exception):
    """
    Some problem with the image format.
    """


def join_col(out, l):
    """
    Join the list of images.
    All input images must be same width and
    have the same number of channels.
    They are joined top-to-bottom.
    `out` is the (open file) destination for the output image.
    `l` should be a list of open files (the input image files).
    """

    image = 0
    stream = 0

    # When the first image is read, this will be the reference width,
    # which must be the same for all images.
    width = None
    # Total height (accumulated as images are read).
    height = 0
    # Accumulated rows.
    rows = []

    for f in l:
        stream += 1
        while True:
            im = png.Reader(file=f)
            try:
                im.preamble()
            except EOFError:
                break
            image += 1

            if not width:
                width = im.width
            elif width != im.width:
                raise FormatError('Image %d in stream %d has width %d; does not match %d.' %
                  (image, stream, im.width, width))

            height += im.height
            # Various bugs here because different numbers of channels and depths go wrong.
            w, h, p, info = im.asDirect()
            rows.extend(p)

    # Alarmingly re-use the last info object.
    tinfo = dict(info)
    del tinfo['size']
    w = png.Writer(width, height, **tinfo)

    w.write(out, rows)


def main(argv):
    import argparse

    parser = argparse.ArgumentParser(description=Description)
    parser.add_argument(
        "input", nargs="*", default="-", type=png.cli_open, metavar="PNG"
    )

    args = parser.parse_args()

    return join_col(png.binary_stdout(), args.input)

if __name__ == '__main__':
    main(sys.argv)
