@@ -44,7 +44,7 @@ class ImageInfo:
44
44
45
45
Attributes:
46
46
filespec (str): The filespec given to read(), copied verbatim
47
- filetype (str): File type: png|pnm|pfm|bmp|jpeg|insp|tiff|exr|dng|cr2|nef|raw|npy
47
+ filetype (str): File type: png|pnm|pfm|bmp|jpeg|insp|tiff|exr|hdr| dng|cr2|nef|raw|npy|...
48
48
filesize (int): Size of the file on disk in bytes
49
49
header_size (int): Size of .raw file header in bytes
50
50
isfloat (bool): True if the image is in floating-point format
@@ -91,8 +91,10 @@ def read(filespec):
91
91
"""
92
92
Parses a lowest common denominator set of metadata from the given
93
93
image, i.e., the dimensions and bit depth. Does not read the entire
94
- file but only what's necessary. Returns an ImageInfo with all fields
95
- filled in, or None in case of failure.
94
+ file but only what's necessary. If the file type is recognized and
95
+ parsing succeeds, returns an ImageInfo with all fields filled in.
96
+ Otherwise, an exception is raised or only the basic file attributes
97
+ (name, type, size) are filled in.
96
98
97
99
Example:
98
100
info = imsize.read("myfile.jpg")
@@ -114,6 +116,7 @@ def read(filespec):
114
116
"tiff" : _read_tiff ,
115
117
"tif" : _read_tiff ,
116
118
"exr" : _read_exr ,
119
+ "hdr" : _read_hdr ,
117
120
"dng" : _read_dng ,
118
121
"cr2" : _read_cr2 ,
119
122
"nef" : _read_nef ,
@@ -123,7 +126,15 @@ def read(filespec):
123
126
handler = handlers [filetype ]
124
127
info = handler (filespec )
125
128
return info
126
- return None
129
+ else :
130
+ # unrecognized file extension
131
+ info = ImageInfo ()
132
+ info .filespec = filespec
133
+ info .filetype = filetype
134
+ info .filesize = os .path .getsize (filespec )
135
+ info .nbytes = info .filesize
136
+ info .uncertain = True
137
+ return info
127
138
128
139
129
140
######################################################################################
@@ -154,6 +165,7 @@ def _read_png(filespec):
154
165
6 : 4 }[ihdr [3 ]] # truecolor_alpha => 4 channels
155
166
info = _complete (info )
156
167
return info
168
+ raise RuntimeError (f"File { filespec } is not a valid PNG file." )
157
169
158
170
159
171
def _read_pnm (filespec ):
@@ -188,6 +200,30 @@ def _read_pfm(filespec):
188
200
return info
189
201
190
202
203
+ def _read_hdr (filespec ):
204
+ info = ImageInfo ()
205
+ info .filespec = filespec
206
+ info .filetype = "hdr"
207
+ info .filesize = os .path .getsize (filespec )
208
+ info .isfloat = True
209
+ info .cfa_raw = False
210
+ info .nchan = 3
211
+ info .bitdepth = 32
212
+ info .bytedepth = 4
213
+ with open (filespec , "rb" ) as f :
214
+ if f .readline () != b"#?RADIANCE\n " :
215
+ raise RuntimeError (f"File { filespec } is not a valid Radiance HDR file." )
216
+ for line in f :
217
+ if line == b"\n " :
218
+ dims = f .readline ().decode ("utf-8" ) # '-Y 480 +X 720'
219
+ dims = dims .split (" " )
220
+ info .height = int (dims [1 ])
221
+ info .width = int (dims [3 ])
222
+ info = _complete (info )
223
+ return info
224
+ raise RuntimeError (f"File { filespec } is not a valid Radiance HDR file." )
225
+
226
+
191
227
def _read_bmp (filespec ):
192
228
info = ImageInfo ()
193
229
info .filespec = filespec
@@ -211,6 +247,7 @@ def _read_bmp(filespec):
211
247
info .maxval = 255
212
248
info = _complete (info )
213
249
return info
250
+ raise RuntimeError (f"File { filespec } is not a valid BMP file." )
214
251
215
252
216
253
def _read_exr (filespec ):
@@ -249,7 +286,8 @@ def _read_jpeg(filespec):
249
286
info .width = sof [2 ]
250
287
info .nchan = sof [3 ]
251
288
info = _complete (info )
252
- return info
289
+ return info
290
+ raise RuntimeError (f"File { filespec } is not a valid JPEG file." )
253
291
254
292
255
293
def _read_insp (filespec ):
@@ -380,8 +418,6 @@ def _read_raw(filespec): # reading the whole file ==> SLOW
380
418
minbits = max (minbits , 10 ) # 10, 12, 14, 16
381
419
info .bitdepth = int (minbits ) # can underestimate bpp if image is very dark
382
420
info = _complete (info )
383
- else :
384
- info = None
385
421
return info
386
422
387
423
@@ -408,6 +444,7 @@ def _read_npy(filespec):
408
444
info .maxval = 1.0 if info .isfloat else 2 ** info .bitdepth - 1
409
445
info = _complete (info )
410
446
return info
447
+ raise RuntimeError (f"File { filespec } is not a valid NPY file." )
411
448
412
449
413
450
def _complete (info ):
0 commit comments