diff -r 6afe59e5ffae -r effae6f38749 degal/exif.py --- a/degal/exif.py Sat Jun 13 20:31:51 2009 +0300 +++ b/degal/exif.py Sat Jun 13 20:59:53 2009 +0300 @@ -4,6 +4,8 @@ import struct, mmap, os +from utils import lazy_load, lazy_load_iter + def read_struct (file, fmt) : """ Utility function to read data from the a file using struct @@ -107,11 +109,12 @@ Represents a single Tag in an IFD """ - def __init__ (self, offset, tag, type, count, data_raw) : + def __init__ (self, ifd, offset, tag, type, count, data_raw) : """ Build a Tag with the given binary items from the IFD entry """ + self.ifd = ifd self.offset = offset self.tag = tag self.type = type @@ -126,13 +129,8 @@ self.type_format, self.type_name, self.type_func = self.type_data # lookup the tag data for this tag - self.tag_data = exif_data.EXIF_TAGS.get(tag) + self.tag_data = self.ifd.tag_dict.get(tag) - # unpack it - if self.tag_data : - # the EXIF tag name - self.tag_name, self.tag_value_spec = self.tag_data - @property def name (self) : """ @@ -140,7 +138,7 @@ """ if self.tag_data : - return self.tag_name + return self.tag_data.name else : return None @@ -166,14 +164,12 @@ """ if self.tag_data : - spec = self.tag_value_spec + # map it + return self.tag_data.map_values(values) else : - # fallback to default - spec = None - - # map it - return exif_data.map_values(spec, values) + # default value-mapping + return ", ".join(str(value) for value in values) # size of an IFD entry in bytes IFD_ENTRY_SIZE = 12 @@ -183,7 +179,7 @@ Represents an IFD (Image file directory) region in EXIF data. """ - def __init__ (self, buffer, **buffer_opts) : + def __init__ (self, buffer, tag_dict, **buffer_opts) : """ Access the IFD data from the given bufferable object with given buffer opts. @@ -192,6 +188,9 @@ # init super(IFD, self).__init__(buffer, **buffer_opts) + + # store + self.tag_dict = tag_dict # read header self.count = self.pread_item(0, 'H') @@ -199,7 +198,8 @@ # read next-offset self.next_offset = self.pread_item(0x02 + self.count * IFD_ENTRY_SIZE, 'I') - def iter_tags (self) : + @lazy_load_iter + def tags (self) : """ Iterate over all the Tag objects in this IFD """ @@ -210,7 +210,7 @@ tag, type, count, data_raw = self.pread_struct(offset, 'HHI4s') # yield the new Tag - yield Tag(offset, tag, type, count, data_raw) + yield Tag(self, offset, tag, type, count, data_raw) class EXIF (Buffer) : """ @@ -230,7 +230,8 @@ # store self.buffer = buffer - def iter_ifds (self) : + @lazy_load_iter + def ifds (self) : """ Iterate over the primary IFDs in this EXIF. """ @@ -240,7 +241,7 @@ while offset : # create and read the IFD, operating on the right sub-buffer - ifd = IFD(self.buf, offset=offset) + ifd = IFD(self.buf, exif_data.EXIF_TAGS, offset=offset) # yield it yield ifd @@ -252,8 +253,6 @@ """ Iterate over all of the IFDs contained within this EXIF, or within other IFDs. """ - - __iter__ = iter_ifds def tag_data_info (self, tag) : """ @@ -500,7 +499,7 @@ print "EXIF offset=%#08x, size=%d:" % (exif.offset, exif.size) - for i, ifd in enumerate(exif.iter_ifds()) : + for i, ifd in enumerate(exif.ifds) : print "\tIFD:%d offset=%#04x(%#08x), count=%d, next=%d:" % ( i, ifd.offset, ifd.offset + exif.offset, @@ -508,7 +507,7 @@ ifd.next_offset ) - for i, tag in enumerate(ifd.iter_tags()) : + for i, tag in enumerate(ifd.tags) : data_info = exif.tag_data_info(tag) if data_info :