#!/usr/bin/env python
# $URL: http://pypng.googlecode.com/svn/trunk/code/pipwindow $
# $Rev: 173 $

# pipwindow
# Tool to crop/expand an image to a rectangular window.  Come the
# revolution this tool will allow the image and the window to be placed
# arbitrarily (in particular the window can be bigger than the picture
# and/or overlap it only partially) and the image can be OpenGL style
# border/repeat effects (repeat, mirrored repeat, clamp, fixed
# background colour, background colour from source file).  For now it
# only acts as crop.  The window must be no greater than the image in
# both x and y.

def window(tl, br, inp, out):
    """Place a window onto the image and cut-out the resulting
    rectangle.  The window is an axis aligned rectangle opposite corners
    at *tl* and *br* (each being an (x,y) pair). *inp* specifies the
    input file which should be a PNG image.
    """

    import png

    r = png.Reader(file=inp)
    x,y,pixels,meta = r.asDirect()
    if not (0 <= tl[0] < br[0] <= x):
        raise NotImplementedError()
    if not (0 <= tl[1] < br[1] <= y):
        raise NotImplementedError()
    # Compute left and right bounds for each row
    l = tl[0] * meta['planes']
    r = br[0] * meta['planes']
    def itercrop():
        """An iterator to perform the crop."""

        for i,row in enumerate(pixels):
            if i < tl[1]:
                continue
            if i >= br[1]:
                # Same as "raise StopIteration"
                return
            yield row[l:r]
    meta['size'] = (br[0]-tl[0], br[1]-tl[1])
    w = png.Writer(**meta)
    w.write(out, itercrop())

def main(argv=None):
    import sys

    if argv is None:
        argv = sys.argv
    argv = argv[1:]

    tl = (0,0)
    br = tuple(map(int, argv[:2]))
    if len(argv) >= 4:
        tl = br
        br = tuple(map(int, argv[2:4]))
    if len(argv) in (2, 4):
        f = sys.stdin
    else:
        f = open(argv[-1], 'rb')

    return window(tl, br, f, sys.stdout)

if __name__ == '__main__':
    main()
