def unpack(f, rows, width, pixel, maxval):
    """Unpack `f` into pixels.
    Assumes the pixel format is such that
    the depth is either a multiple or a divisor of 8.
    `f` is assumed to be an iterator that returns blocks of input such
    that each block contains a whole number of pixels.  An iterator is
    returned that yields each pixel as an n-tuple.  `pixel` describes the
    pixel format using the Plan9 syntax ("k8", "r8g8b8", and so on).
    """

    def mask(w):
        """An integer, to be used as a mask, with bottom `w` bits set to 1."""

        return (1 << w) - 1

    def deblock(f, depth, width):
        """A "packer" used to convert multiple bytes into single pixels.
        `depth` is the pixel depth in bits (>= 8), `width` is the row width in
        pixels.
        """

        w = depth // 8
        i = 0
        for block in f:
            for i in range(len(block) // w):
                p = block[w * i: w * (i + 1)]
                i += w
                # Convert p to little-endian integer, x
                x = 0
                s = 1   # scale
                for j in p:
                    x += s * ord(j)
                    s <<= 8
                yield x

    def bitfunge(f, depth, width):
        """A "packer" used to convert single bytes into multiple pixels.
        Depth is the pixel depth (< 8), width is the row width in pixels.
        """

        for block in f:
            col = 0
            for i in block:
                x = ord(i)
                for j in range(8 / depth):
                    yield x >> (8 - depth)
                    col += 1
                    if col == width:
                        # A row-end forces a new byte even if
                        # we haven't consumed all of the current byte.
                        # Effectively rows are bit-padded to make
                        # a whole number of bytes.
                        col = 0
                        break
                    x <<= depth

    # number of bits in each channel
    chan = map(int, re.findall(r'\d+', pixel))
    # type of each channel
    type = re.findall('[a-z]', pixel)

    depth = sum(chan)

    # According to the value of depth pick a "packer" that either gathers
    # multiple bytes into a single pixel (for depth >= 8) or split bytes
    # into several pixels (for depth < 8)
    if depth >= 8:
        assert depth % 8 == 0
        packer = deblock
    else:
        assert 8 % depth == 0
        packer = bitfunge

    for x in packer(f, depth, width):
        # x is the pixel as an unsigned integer
        o = []
        # This is a bit yucky.  Extract each channel from the _most_
        # significant part of x.
        for j in range(len(chan)):
            v = (x >> (depth - chan[j])) & mask(chan[j])
            x <<= chan[j]
            if type[j] != 'x':
                # scale to maxval
                v = v * float(maxval) / mask(chan[j])
                v = int(v + 0.5)
                o.append(v)
        yield o
Unpack `f` into pixels.
    Assumes the pixel format is such that
    the depth is either a multiple or a divisor of 8.
    `f` is assumed to be an iterator that returns blocks of input such
    that each block contains a whole number of pixels.  An iterator is
    returned that yields each pixel as an n-tuple.  `pixel` describes the
    pixel format using the Plan9 syntax ("k8", "r8g8b8", and so on).