diff -r ef2c1ffdca8f -r 63e89dc2d6f1 degal/exif_data.py --- 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