# -*- Mode: Python -*- # Convert a 'Kolor Raw' file (.kro) from AutopanoPro to a netpbm PPM file/stream. import struct def read_kro_header (fi): block = fi.read (20) magic, width, height, bits, colors = struct.unpack ('>4sllll', block) assert (magic == 'KRO\x01') return magic, width, height, bits, colors def write_ppm_header (fo, bits, w, h): if bits == 8: fo.write ('P6\n#converted from KRO\n%d %d\n255\n' % (w, h)) elif bits == 16: fo.write ('P6\n#converted from KRO\n%d %d\n65535\n' % (w, h)) else: raise NotImplementedError def copy (fi, fo): magic, width, height, bits, colors = read_kro_header (fi) pixels = width * height write_ppm_header (fo, bits, width, height) if bits == 8: # doing this in blocks roughly doubles the speed... while 1: block = fi.read (16384) if not block: break else: oblock = [] for x in range (0, len(block), 4): oblock.append (block[x:x+3]) fo.write (''.join (oblock)) elif bits == 16: while pixels: r,g,b,a = struct.unpack ('>HHHH', fi.read (8)) # some tools (e.g., XnView) expect little-endian shorts in # 16-bit PPM files, use this line instead: #fo.write (struct.pack ('HHH', r,g,b)) pixels -= 1 else: raise NotImplementedError if __name__ == '__main__': import sys fi = open (sys.argv[1], 'rb') # '-c' will output to stdout, for example: # $ python kro2ppm.py input.kro -c | pnmscale 0.5 | cjpeg > output.jpg if '-c' in sys.argv: fo = sys.stdout else: fo = open (sys.argv[1] + '.ppm', 'wb') copy (fi, fo) fo.close() fi.close()