degal/exif_data.py
branchnew-exif
changeset 103 63e89dc2d6f1
parent 102 ef2c1ffdca8f
child 104 6afe59e5ffae
--- 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