degal/exif.py
branchnew-exif
changeset 104 6afe59e5ffae
parent 103 63e89dc2d6f1
child 105 effae6f38749
equal deleted inserted replaced
103:63e89dc2d6f1 104:6afe59e5ffae
   129         self.tag_data = exif_data.EXIF_TAGS.get(tag)
   129         self.tag_data = exif_data.EXIF_TAGS.get(tag)
   130         
   130         
   131         # unpack it
   131         # unpack it
   132         if self.tag_data :
   132         if self.tag_data :
   133             # the EXIF tag name
   133             # the EXIF tag name
   134             self.tag_name = self.tag_data[0]
   134             self.tag_name, self.tag_value_spec = self.tag_data
   135             
   135             
   136             # the optional value formatting specification
       
   137             if len(self.tag_data) > 1 :
       
   138                 self.tag_value_spec = self.tag_data[1]
       
   139 
       
   140             else :
       
   141                 self.tag_value_spec = None
       
   142 
       
   143     @property
   136     @property
   144     def name (self) :
   137     def name (self) :
   145         """
   138         """
   146             Lookup the name of this tag via its code, returns None if unknown.
   139             Lookup the name of this tag via its code, returns None if unknown.
   147         """
   140         """
   163 
   156 
   164         else :
   157         else :
   165             # nada, just leave them
   158             # nada, just leave them
   166             return raw_values
   159             return raw_values
   167 
   160 
   168     def readable_value (self, value) :
   161     def readable_value (self, values) :
   169         """
   162         """
   170             Convert the given value for this tag into a human-readable string.
   163             Convert the given values for this tag into a human-readable string.
   171 
   164 
   172             Returns the value itself by default.
   165             Returns the comma-separated values by default.
   173         """
   166         """
   174 
   167 
   175         if self.tag_data and self.tag_value_spec :
   168         if self.tag_data :
   176             # map it
   169             spec = self.tag_value_spec
   177             return exif_data.map_value(self.tag_value_spec, value)
       
   178 
   170 
   179         else :
   171         else :
   180             # nope...
   172             # fallback to default
   181             return value
   173             spec = None
       
   174 
       
   175         # map it
       
   176         return exif_data.map_values(spec, values)
   182 
   177 
   183 # size of an IFD entry in bytes
   178 # size of an IFD entry in bytes
   184 IFD_ENTRY_SIZE = 12
   179 IFD_ENTRY_SIZE = 12
   185 
   180 
   186 class IFD (Buffer) :
   181 class IFD (Buffer) :
   235         # store
   230         # store
   236         self.buffer = buffer
   231         self.buffer = buffer
   237     
   232     
   238     def iter_ifds (self) :
   233     def iter_ifds (self) :
   239         """
   234         """
   240             Iterate over all of the IFD objects in this EXIF.
   235             Iterate over the primary IFDs in this EXIF.
   241         """
   236         """
   242 
   237 
   243         # starting offset
   238         # starting offset
   244         offset = self.pread_item(0x04, 'I')
   239         offset = self.pread_item(0x04, 'I')
   245 
   240 
   251             yield ifd
   246             yield ifd
   252 
   247 
   253             # skip to next offset
   248             # skip to next offset
   254             offset = ifd.next_offset
   249             offset = ifd.next_offset
   255     
   250     
       
   251     def iter_all_ifds (self) :
       
   252         """
       
   253             Iterate over all of the IFDs contained within this EXIF, or within other IFDs.
       
   254         """
       
   255 
   256     __iter__ = iter_ifds
   256     __iter__ = iter_ifds
   257     
   257     
   258     def tag_data_info (self, tag) :
   258     def tag_data_info (self, tag) :
   259         """
   259         """
   260             Calculate the location, format and size of the given tag's data.
   260             Calculate the location, format and size of the given tag's data.
   327         # unknown?
   327         # unknown?
   328         if not values :
   328         if not values :
   329             return ""
   329             return ""
   330 
   330 
   331         # return as comma-separated formatted string, yes
   331         # return as comma-separated formatted string, yes
   332         return ", ".join(tag.readable_value(value) for value in values)
   332         return tag.readable_value(values)
   333 
   333 
   334 # mapping from two-byte TIFF byte order marker to struct prefix
   334 # mapping from two-byte TIFF byte order marker to struct prefix
   335 TIFF_BYTE_ORDER = {
   335 TIFF_BYTE_ORDER = {
   336     'II': '<',
   336     'II': '<',
   337     'MM': '>',
   337     'MM': '>',
   523                 tag.tag, tag.name or '???',
   523                 tag.tag, tag.name or '???',
   524                 tag.type, tag.type_name if tag.type_data else '???',
   524                 tag.type, tag.type_name if tag.type_data else '???',
   525                 tag.count,
   525                 tag.count,
   526                 data_fmt, data_offset, data_size,
   526                 data_fmt, data_offset, data_size,
   527             )
   527             )
   528             
   528 
   529             for i, value in enumerate(exif.tag_values(tag)) :
   529             values = exif.tag_values(tag)
   530                 print "\t\t\t%02d: %r -> %s" % (i, value, tag.readable_value(value))
   530             
   531 
   531             for i, value in enumerate(values) :
   532 def main (path) :
   532                 print "\t\t\t%02d: %r" % (i, value)
       
   533 
       
   534             print "\t\t\t->  %s" % (tag.readable_value(values), )
       
   535 
       
   536 def main (path, quiet=False) :
   533     """
   537     """
   534         Load and dump EXIF data from the given path
   538         Load and dump EXIF data from the given path
   535     """
   539     """
   536     
   540     
   537     # try and load it
   541     # try and load it
   538     exif = load_path(path)
   542     exif = load_path(path)
   539 
   543 
   540     if not exif :
   544     if not exif :
   541         raise Exception("No EXIF data found")
   545         raise Exception("No EXIF data found")
   542     
   546     
   543     # dump it
   547     if not quiet :
   544     print "%s: " % path
   548         # dump it
   545     print
   549         print "%s: " % path
   546 
   550         print
   547     dump_exif(exif)
   551 
       
   552         dump_exif(exif)
   548 
   553 
   549 if __name__ == '__main__' :
   554 if __name__ == '__main__' :
   550     from sys import argv
   555     from sys import argv
   551 
   556 
   552     main(argv[1])
   557     main(argv[1], '-q' in argv)
   553 
   558