--- 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 :