summaryrefslogtreecommitdiffstats
path: root/build/pypng/pdsimgtopng
diff options
context:
space:
mode:
Diffstat (limited to 'build/pypng/pdsimgtopng')
-rw-r--r--build/pypng/pdsimgtopng99
1 files changed, 99 insertions, 0 deletions
diff --git a/build/pypng/pdsimgtopng b/build/pypng/pdsimgtopng
new file mode 100644
index 0000000..975db93
--- /dev/null
+++ b/build/pypng/pdsimgtopng
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+# $URL: http://pypng.googlecode.com/svn/trunk/code/pdsimgtopng $
+# $Rev: 154 $
+# PDS Image to PNG
+
+import re
+import struct
+
+import png
+
+class FormatError(Exception):
+ pass
+
+def pdskey(s, k):
+ """Lookup key `k` in string `s`. Returns value (as a string), or
+ raises exception if not found.
+ """
+
+ assert re.match(r' *\^?[:\w]+$', k)
+ safere = '^' + re.escape(k) +r' *= *(\w+)'
+ m = re.search(safere, s, re.MULTILINE)
+ if not m:
+ raise FormatError("Can't find %s." % k)
+ return m.group(1)
+
+def img(inp):
+ """Open the PDS IMG file `inp` and return (*pixels*, *info*).
+ *pixels* is an iterator over the rows, *info* is the information
+ dictionary.
+ """
+
+ err = __import__('sys').stderr
+
+ consumed = 1024
+
+ s = inp.read(consumed)
+ record_type = pdskey(s, 'RECORD_TYPE')
+ if record_type != 'FIXED_LENGTH':
+ raise FormatError(
+ "Can only deal with FIXED_LENGTH record type (found %s)" %
+ record_type)
+ record_bytes = int(pdskey(s,'RECORD_BYTES'))
+ file_records = int(pdskey(s, 'FILE_RECORDS'))
+ label_records = int(pdskey(s, 'LABEL_RECORDS'))
+ remaining = label_records * record_bytes - consumed
+ s += inp.read(remaining)
+ consumed += remaining
+
+ image_pointer = int(pdskey(s, '^IMAGE'))
+ # "^IMAGE" locates a record. Records are numbered starting from 1.
+ image_index = image_pointer - 1
+ image_offset = image_index * record_bytes
+ gap = image_offset - consumed
+ assert gap >= 0
+ if gap:
+ inp.read(gap)
+ # This assumes there is only one OBJECT in the file, and it is the
+ # IMAGE.
+ height = int(pdskey(s, ' LINES'))
+ width = int(pdskey(s, ' LINE_SAMPLES'))
+ sample_type = pdskey(s, ' SAMPLE_TYPE')
+ sample_bits = int(pdskey(s, ' SAMPLE_BITS'))
+ # For Messenger MDIS, SAMPLE_BITS is reported as 16, but only values
+ # from 0 ot 4095 are used.
+ bitdepth = 12
+ if sample_type == 'MSB_UNSIGNED_INTEGER':
+ fmt = '>H'
+ else:
+ raise 'Unknown sample type: %s.' % sample_type
+ sample_bytes = (1,2)[bitdepth > 8]
+ row_bytes = sample_bytes * width
+ fmt = fmt[:1] + str(width) + fmt[1:]
+ def rowiter():
+ for y in range(height):
+ yield struct.unpack(fmt, inp.read(row_bytes))
+ info = dict(greyscale=True, alpha=False, bitdepth=bitdepth,
+ size=(width,height), gamma=1.0)
+ return rowiter(), info
+
+
+def main(argv=None):
+ import sys
+
+ if argv is None:
+ argv = sys.argv
+ argv = argv[1:]
+ arg = argv
+ if len(arg) >= 1:
+ f = open(arg[0], 'rb')
+ else:
+ f = sys.stdin
+ pixels,info = img(f)
+ w = png.Writer(**info)
+ w.write(sys.stdout, pixels)
+
+if __name__ == '__main__':
+ main()
+
+