#!/usr/bin/env python # # prw2ppm - convert Artlantis Preview files to PPM # # Copyright (C) 2012 Antonio Ospite # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import os import sys import struct def get_be32(f): fmt = '>I' length = struct.calcsize(fmt) data = f.read(length) value = struct.unpack_from(fmt, data) return value[0] def to_rgb(data): r = (data & 0x00FF0000) >> 16 g = (data & 0x0000FF00) >> 8 b = (data & 0x000000FF) return (r, g, b) def usage(name): sys.stdout.write("usage: %s \n" % name) def prw2ppm(prw_filename, ppm_filename): f = open(prw_filename, "rb") # file type or frame number, # or maybe the type of the first packet? (run-length or raw) file_type = get_be32(f) if file_type != 1: sys.stdderr.write("Unknown preview file type.\n") sys.exit(1) width = get_be32(f) height = get_be32(f) outfile = open(ppm_filename, "w") outfile.write("P3\n") outfile.write("%d %d\n" % (width, height)) outfile.write("%d\n" % 255) n = 0 n_pixels = width * height # Read the first packet here, # AFAIK it is always a run-length packet count = get_be32(f) data = get_be32(f) old_data = data while True: if data == old_data: # run-length packet for i in range(0, count): outfile.write("%d %d %d\n" % to_rgb(data)) else: # raw packet outfile.write("%d %d %d\n" % to_rgb(data)) for i in range(0, count - 1): data = get_be32(f) outfile.write("%d %d %d\n" % to_rgb(data)) n += count if n == n_pixels: break old_data = data # read next packet count = get_be32(f) data = get_be32(f) outfile.close() if __name__ == "__main__": if len(sys.argv) < 2: usage(sys.argv[0]) sys.exit(1) prw_filename = sys.argv[1] basename_no_ext = os.path.splitext(prw_filename)[0] ppm_filename = basename_no_ext + ".ppm" prw2ppm(prw_filename, ppm_filename) sys.exit(0)