--- a/degal/exif_data.py Sat Jun 13 18:34:55 2009 +0300
+++ b/degal/exif_data.py Sat Jun 13 19:21:12 2009 +0300
@@ -43,6 +43,67 @@
"""
+import decimal, itertools
+
+def filter_ascii (values) :
+ """
+ Default post-filter for ASCII values.
+
+ This takes a single item of string data, splits it up into strings by ASCII-NUL, and trims the induvidual strings
+ """
+
+ return [string.rstrip() for string in values[0].split('\x00') if string]
+
+
+def build_ratio (num, denom) :
+ """
+ Builds a Decimal ratio out of the given numerator and denominator
+ """
+
+ return decimal.Decimal(num) / decimal.Decimal(denom)
+
+def filter_ratio (values) :
+ """
+ Default post-filter for Ratio values.
+
+ This takes the pairs of numerator/denominator values and builds Decimals out of them
+ """
+
+ return [build_ratio(values[i], values[i + 1]) for i in xrange(0, len(values), 2)]
+
+
+# IFD Tag type information, indexed by code
+# { type_code: (type_fmt, name, filter_func) }
+#
+# type_fmt's that are one char will be prefixed with the count for use with struct.unpack, those with more chars will
+# be repeated as many times for use with struct.unpack.
+FIELD_TYPES = {
+# 0x0000: (None, 'Proprietary' ), # ??? no such type
+ 0x0001: ('B', 'Byte', None ),
+ 0x0002: ('s', 'ASCII', filter_ascii ),
+ 0x0003: ('H', 'Short', None ),
+ 0x0004: ('L', 'Long', None ),
+ 0x0005: ('LL', 'Ratio', filter_ratio ),
+ 0x0006: ('b', 'Signed Byte', None ),
+ 0x0007: ('s', 'Undefined', None ),
+ 0x0008: ('h', 'Signed Short', None ),
+ 0x0009: ('l', 'Signed Long', None ),
+ 0x000A: ('ll', 'Signed Ratio', filter_ratio ),
+}
+
+def map_value (spec, value) :
+ """
+ Map the given tag value to a printable string using the given value spec.
+ """
+
+ if callable(spec):
+ # call mapping function
+ return spec(value)
+
+ else:
+ return spec.get(value, repr(value))
+
+
def make_string (seq):
"""
Filter a string to strip out non-printing chars
@@ -73,33 +134,6 @@
## allows JIS and Unicode.
return make_string(seq)
-# IFD Tag type information, indexed by code
-# { type_code: (type_fmt, name) }
-FIELD_TYPES = {
-# 0x0000: (None, 'Proprietary' ), # ??? no such type
- 0x0001: ('B', 'Byte' ),
- 0x0002: ('s', 'ASCII' ),
- 0x0003: ('H', 'Short' ),
- 0x0004: ('L', 'Long' ),
- 0x0005: ('LL', 'Ratio' ),
- 0x0006: ('b', 'Signed Byte' ),
- 0x0007: ('c', 'Undefined' ),
- 0x0008: ('h', 'Signed Short' ),
- 0x0009: ('l', 'Signed Long' ),
- 0x000A: ('ll', 'Signed Ratio' ),
-}
-
-def map_value (spec, value) :
- """
- Map the given tag value to a printable string using the given value spec.
- """
-
- if callable(spec):
- # call mapping function
- return spec(value)
-
- else:
- return spec.get(value, repr(value))
# dictionary of main EXIF tag names
# first element of tuple is tag name, optional second element is