5 TOKEN_RE = re.compile("[^" + string.whitespace + "]+")
6 WS_RE = re.compile("[" + string.whitespace + "]+")
9 class TexReaderException(Exception):
13 def consume_token(data, offset):
15 Reads a single whitespace-delimited token at the given offset.
19 match = TOKEN_RE.match(data, offset)
21 raise TexReaderException("Could not find token at offset %d"
27 def consume_ws(data, offset):
29 Returns the number of bytes of whitespace that occur at the given offset.
31 match = WS_RE.match(data, offset)
33 raise TexReaderException("Could not find whitespace at offset %d"
36 return len(match.group())
41 Parse the PPM data from the given byte string.
45 magic = consume_token(data, offset)
49 raise TexReaderException("Unrecognised magic %r" % (magic,))
51 offset += consume_ws(data, offset)
53 widthStr = consume_token(data, offset)
57 raise TexReaderException("Can't parse width %r at offset %d"
60 offset += len(widthStr)
61 offset += consume_ws(data, offset)
63 heightStr = consume_token(data, offset)
65 height = int(heightStr)
67 raise TexReaderException("Can't parse height %r at offset %d"
68 % (heightStr, offset))
70 offset += len(heightStr)
71 offset += consume_ws(data, offset)
73 sampleMaxStr = consume_token(data, offset)
75 sampleMax = int(sampleMaxStr)
77 raise TexReaderException("Can't parse sampleMax %r at offset %d"
78 % (sampleMaxStr, offset))
80 # Always exactly one whitespace char after the sample mox.
81 offset += len(sampleMaxStr) + 1
84 raise TexReaderException("Textures must have 8 bits per channel.")
86 # Now to convert this packed RGB pixel data to RGBA data that OpenGL can
89 for pxOffset in range(offset, offset + (width * height * 3), 3):
90 pixels.append(data[pxOffset:pxOffset+3])
93 return (width, height, "".join(pixels))
96 if __name__ == "__main__":
98 with open(sys.argv[1]) as handle:
100 print parse_ppm(data)