Package fabio :: Module pnmimage
[hide private]
[frames] | no frames]

Source Code for Module fabio.pnmimage

  1  #!/usr/bin/env python 
  2  #coding: utf8 
  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'] 
22 23 -class pnmimage(fabioimage):
24 - def __init__(self, *arg, **kwargs):
25 fabioimage.__init__(self, *arg, **kwargs) 26 fun = getattr(fabioimage, '__init__', lambda x: None) 27 fun(self) 28 self.data = None 29 self.header = {'Subformat':'P5'} 30 self.dim1 = self.dim2 = 0 31 self.m = self.maxval = self.stddev = self.minval = None 32 self.header_keys = self.header.keys() 33 self.bytecode = None
34
35 - def _readheader(self, f):
36 #pnm images have a 3-line header but ignore lines starting with '#' 37 #1st line contains the pnm image sub format 38 #2nd line contains the image pixel dimension 39 #3rd line contains the maximum pixel value (at least for grayscale - check this) 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 #this one has a special header 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 #set the dimensions 66 dims = (self.header['DIMENSIONS'].split()) 67 self.dim1, self.dim2 = int(dims[0]), int(dims[1]) 68 #figure out how many bytes are used to store the data 69 #case construct here! 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 #read the image data 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
161 - def checkData(data=None):
162 if data is None: 163 return None 164 else: 165 return data.astype(int)
166