README.asciidoc: write "32-bit" instead of "32 bit"
[aof2obj.git] / prw2ppm.py
1 #!/usr/bin/env python
2 #
3 # prw2ppm - convert Artlantis Preview files to PPM
4 #
5 # Copyright (C) 2012  Antonio Ospite <ospite@studenti.unina.it>
6 #
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20 import os
21 import sys
22 import struct
23
24
25 def get_be32(f):
26     fmt = '>I'
27
28     length = struct.calcsize(fmt)
29     data = f.read(length)
30     value = struct.unpack_from(fmt, data)
31
32     return  value[0]
33
34
35 def to_rgb(data):
36     r = (data & 0x00FF0000) >> 16
37     g = (data & 0x0000FF00) >> 8
38     b = (data & 0x000000FF)
39
40     return (r, g, b)
41
42
43 def usage(name):
44     sys.stdout.write("usage: %s <prw file>\n" % name)
45
46
47 def prw2ppm(prw_filename, ppm_filename):
48     f = open(prw_filename, "rb")
49
50     # file type or frame number,
51     # or maybe the type of the first packet? (run-length or raw)
52     file_type = get_be32(f)
53     if file_type != 1:
54         sys.stdderr.write("Unknown preview file type.\n")
55         sys.exit(1)
56
57     width = get_be32(f)
58     height = get_be32(f)
59
60     outfile = open(ppm_filename, "w")
61
62     outfile.write("P3\n")
63     outfile.write("%d %d\n" % (width, height))
64     outfile.write("%d\n" % 255)
65
66     n = 0
67     n_pixels = width * height
68
69     # Read the first packet here,
70     # AFAIK it is always a run-length packet
71     count = get_be32(f)
72     data = get_be32(f)
73     old_data = data
74
75     while True:
76         if data == old_data:
77             # run-length packet
78             for i in range(0, count):
79                 outfile.write("%d %d %d\n" % to_rgb(data))
80         else:
81             # raw packet
82             outfile.write("%d %d %d\n" % to_rgb(data))
83             for i in range(0, count - 1):
84                 data = get_be32(f)
85                 outfile.write("%d %d %d\n" % to_rgb(data))
86
87         n += count
88         if n == n_pixels:
89             break
90
91         old_data = data
92
93         # read next packet
94         count = get_be32(f)
95         data = get_be32(f)
96
97     outfile.close()
98
99
100 if __name__ == "__main__":
101
102     if len(sys.argv) < 2:
103         usage(sys.argv[0])
104         sys.exit(1)
105
106     prw_filename = sys.argv[1]
107
108     basename_no_ext = os.path.splitext(prw_filename)[0]
109     ppm_filename = basename_no_ext + ".ppm"
110
111     prw2ppm(prw_filename, ppm_filename)
112
113     sys.exit(0)