1
2
3 """
4
5 Authors: Henning O. Sorensen & Erik Knudsen
6 Center for Fundamental Research: Metal Structures in Four Dimensions
7 Risoe National Laboratory
8 Frederiksborgvej 399
9 DK-4000 Roskilde
10 email:henning.sorensen@risoe.dk
11
12 """
13
14 import numpy, logging
15 logger = logging.getLogger("pnmimage")
16 from fabioimage import fabioimage
17
18 SUBFORMATS = ['P1', 'P2', 'P3', 'P4', 'P5', 'P6', 'P7']
19
20 HEADERITEMS = ['SUBFORMAT', 'DIMENSIONS', 'MAXVAL']
21 P7HEADERITEMS = ['WIDTH', 'HEIGHT', 'DEPTH', 'MAXVAL', 'TUPLTYPE', 'ENDHDR']
34
36
37
38
39
40 self.header_keys = ['SUBFORMAT', 'DIMENSIONS', 'MAXVAL']
41
42 l = f.readline().strip()
43 if l not in SUBFORMATS:
44 raise IOError, ('unknown subformat of pnm: %s' % l)
45 else:
46 self.header['SUBFORMAT'] = l
47
48 if self.header['SUBFORMAT'] == 'P7':
49 self.header_keys = P7HEADERITEMS
50
51 while 'ENDHDR' not in l:
52 l = f.readline()
53 while(l[0] == '#'): l = f.readline()
54 s = l.lsplit(' ', 1)
55 if s[0] not in P7HEADERITEMS:
56 raise IOError, ('Illegal pam (netpnm p7) headeritem %s' % s[0])
57 self.header[s[0]] = s[1]
58 else:
59 self.header_keys = HEADERITEMS
60 for k in self.header_keys[1:]:
61 l = f.readline()
62 while(l[0] == '#'): l = f.readline()
63 self.header[k] = l.strip()
64
65
66 dims = (self.header['DIMENSIONS'].split())
67 self.dim1, self.dim2 = int(dims[0]), int(dims[1])
68
69
70 m = int(self.header['MAXVAL'])
71 if m < 256:
72 self.bytecode = numpy.uint8
73 elif m < 65536:
74 self.bytecode = numpy.uint16
75 elif m < 2147483648L:
76 self.bytecode = numpy.uint32
77 logger.warning('32-bit pixels are not really supported by the netpgm standard')
78 else:
79 raise IOError, 'could not figure out what kind of pixels you have'
80
81 - def read(self, fname, frame=None):
82 """
83 try to read PNM images
84 @param fname: name of the file
85 @param frame: not relevant here! PNM is always single framed
86 """
87 self.header = {}
88 self.resetvals()
89 infile = self._open(fname)
90 self._readheader(infile)
91
92
93 decoder_name = "%sdec" % self.header['SUBFORMAT']
94 if decoder_name in dir(pnmimage):
95 decoder = getattr(pnmimage, decoder_name)
96 self.data = decoder(infile, self.bytecode)
97 else:
98 raise IOError("No decoder named %s for file %s" % (decoder_name, fname))
99 self.resetvals()
100 return self
101
102 @staticmethod
103 - def P1dec(buf, bytecode):
104 data = numpy.zeros((self.dim2, self.dim1))
105 i = 0
106 for l in buf.readlines():
107 try:
108 data[i, :] = numpy.array(l.split()).astype(bytecode)
109 except ValueError:
110 raise IOError, 'Size spec in pnm-header does not match size of image data field'
111 return data
112
113 @staticmethod
114 - def P4dec(buf, bytecode):
115 err = 'single bit (pbm) images are not supported - yet'
116 logger.error(err)
117 raise NotImplementedError(err)
118
119 @staticmethod
120 - def P2dec(buf, bytecode):
121 data = numpy.zeros((self.dim2, self.dim1))
122 i = 0
123 for l in buf.readlines():
124 try:
125 data[i, :] = numpy.array(l.split()).astype(bytecode)
126 except ValueError:
127 raise IOError, 'Size spec in pnm-header does not match size of image data field'
128 return data
129
130 @staticmethod
131 - def P5dec(buf, bytecode):
132 l = buf.read()
133 try:
134 data = numpy.reshape(numpy.fromstring(l, bytecode), [self.dim2, self.dim1]).byteswap()
135 except ValueError:
136 raise IOError, 'Size spec in pnm-header does not match size of image data field'
137 return data
138
139 @staticmethod
140 - def P3dec(buf, bytecode):
141 err = '(plain-ppm) RGB images are not supported - yet'
142 logger.error(err)
143 raise NotImplementedError(err)
144
145 @staticmethod
146 - def P6dec(buf, bytecode):
147 err = '(ppm) RGB images are not supported - yet'
148 logger.error(err)
149 raise NotImplementedError(err)
150
151 @staticmethod
152 - def P7dec(buf, bytecode):
153 err = '(pam) images are not supported - yet'
154 logger.error(err)
155 raise NotImplementedError(err)
156
157 - def write(self, filename):
158 raise NotImplementedError('write pnm images is not implemented yet.')
159
160 @staticmethod
162 if data is None:
163 return None
164 else:
165 return data.astype(int)
166