@@ -324,8 +324,9 @@ class ImageFileError(Exception):
324324class SpatialImage (object ):
325325 ''' Template class for images '''
326326 header_class = Header
327+ _meta_sniff_len = 0
327328 files_types = (('image' , None ),)
328- alternate_exts = () # Modified by @ImageOpener.register_ext_from_image
329+ valid_exts = ()
329330 _compressed_exts = ()
330331
331332 makeable = True # Used in test code
@@ -874,51 +875,37 @@ def from_image(klass, img):
874875 extra = img .extra .copy ())
875876
876877 @classmethod
877- def is_valid_extension (klass , ext ):
878- valid = tuple (ft [1 ] for ft in klass .files_types ) + klass .alternate_exts
879- return ext .lower () in valid
878+ def _sniff_meta_for (klass , filename , sniff_nbytes ):
879+ froot , ext , trailing = splitext_addext (filename ,
880+ klass ._compressed_exts )
881+ # Determine the metadata location, then sniff it
882+ t_fnames = types_filenames (filename ,
883+ klass .files_types ,
884+ trailing_suffixes = klass ._compressed_exts )
885+ meta_fname = t_fnames .get ('header' , filename )
886+ try :
887+ with ImageOpener (meta_fname , 'rb' ) as fobj :
888+ sniff = fobj .read (sniff_nbytes )
889+ except IOError :
890+ return None
891+ return sniff
880892
881893 @classmethod
882- def path_maybe_image (klass , filename , sniff = None ):
894+ def path_maybe_image (klass , filename , sniff = None , sniff_max = 1024 ):
883895 froot , ext , trailing = splitext_addext (filename ,
884896 klass ._compressed_exts )
885-
886- if not klass .is_valid_extension (ext ):
897+ if ext .lower () not in klass .valid_exts :
887898 return False , sniff
888- elif not hasattr (klass .header_class , 'may_contain_header' ):
899+ if not hasattr (klass .header_class , 'may_contain_header' ):
889900 return True , sniff
890-
891- # Determine the metadata location, then sniff it
892- header_exts = [ft [1 ] for ft in klass .files_types if ft [0 ] == 'header' ]
893- if len (header_exts ) == 0 :
894- metadata_filename = filename
895- else :
896- # Search for an acceptable existing header;
897- # could be compressed or not...
898- for ext in header_exts :
899- for tr_ext in np .unique ([trailing , '' ] +
900- list (klass ._compressed_exts )):
901- metadata_filename = froot + ext + tr_ext
902- if os .path .exists (metadata_filename ):
903- break
904-
905- try :
906- klass_sizeof_hdr = getattr (klass .header_class , 'sizeof_hdr' , 0 )
907-
908- if not sniff or len (sniff ) < klass_sizeof_hdr :
909- # 1024 bytes is currently larger than all headers
910- sizeof_hdr = np .max ([1024 , klass_sizeof_hdr ])
911- with ImageOpener (metadata_filename , 'rb' ) as fobj :
912- sniff = fobj .read (sizeof_hdr )
913-
914- may_contain_header = klass .header_class .may_contain_header (sniff )
915- except Exception :
916- # Can happen if: file doesn't exist,
917- # filesize < necessary sniff size (this happens!)
918- # other unexpected errors.
919- may_contain_header = False
920-
921- return may_contain_header , sniff
901+ if sniff is None or len (sniff ) < klass ._meta_sniff_len :
902+ sniff_nbytes = max (klass ._meta_sniff_len , sniff_max )
903+ sniff = klass ._sniff_meta_for (filename , sniff_nbytes )
904+ if sniff is None : # Can't sniff, won't sniff
905+ return False , None
906+ if len (sniff ) < klass ._meta_sniff_len :
907+ return False , sniff
908+ return klass .header_class .may_contain_header (sniff ), sniff
922909
923910 def __getitem__ (self ):
924911 ''' No slicing or dictionary interface for images
0 commit comments