Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Aymara_v2/Build/ppmto565.py
blob: 46393f604f826133b5afc3803612b1de5eafeeb3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#!/usr/bin/python
"""Convert ppm-format files to XO-1 native 565 format."""
from __future__ import division, with_statement
import sys

def eat_comment(inf): # just read #, read until next EOL
    while True:
        c = inf.read(1)
        if c == '\n' or c == '\r': break # read to EOL
    return c

def read_token(inf):
    # eat up leading whitespace
    while True:
        c = inf.read(1)
        if c == '#': eat_comment(inf)
        elif not c.isspace(): break
    # now read in non-whitespace.
    s = c
    while True:
        c = inf.read(1)
        if c == '#': c = eat_comment(inf)
        if c.isspace(): break
        s += c
    # done!
    return s

def main(inf, outf, compress=False):
    import struct
    # read ppm from input
    magic = inf.read(2)
    assert magic == 'P6'
    width = int(read_token(inf))
    height = int(read_token(inf))
    maxval = int(read_token(inf))
    unpackstr = '!3B' if maxval < 256 else '!3H'
    unpacklen = struct.calcsize(unpackstr)
    # write header
    outf.write(struct.pack('@III', width, height, 1 if compress else 0))
    if compress:
        from zlib import compressobj
        off0 = outf.tell()
        # we'll come back and fill in the next field later w/ the right size.
        outf.write(struct.pack('@I', 0))
        off1 = outf.tell()
        comp = compressobj(9)
        encode_me = lambda bytes: comp.compress(bytes)
    else:
        encode_me = lambda bytes: bytes
    # read pixel data, convert, and write it to output
    def scale(x, y): return int((y*x/maxval)+0.5)
    for y in xrange(0, height):
        for x in xrange(0, width):
            red, green, blue = struct.unpack(unpackstr, inf.read(unpacklen))
            encoded = (scale(red, 0x1f) << 11) + \
                      (scale(green, 0x3f) << 5) + \
                      (scale(blue, 0x1f))
            outf.write(encode_me(struct.pack('@H', encoded)))
    if compress:
        outf.write(comp.flush())
        # go back and write the proper file size.
        off2 = outf.tell()
        outf.seek(off0)
        outf.write(struct.pack('@I', off2-off1))

if __name__ == '__main__':
    from optparse import OptionParser
    import sys
    parser = OptionParser()
    parser.add_option('-o','--output',default=None,dest='output',
                      metavar='FILE', help='output file name.')
    parser.add_option('-z','--compress',action='store_true',dest='compress',
                      help='use compressed image format')
    (options, args) = parser.parse_args()
    if options.compress and options.output is None:
        parser.error('Output file name required when writing '+
                     'compressed format.')
    infile = open(args[0]) if args else sys.stdin
    outfile = open(options.output, 'w') if options.output else sys.stdout
    main(infile, outfile, options.compress)