class UserComment: # # Names of encodings that we publicly support. # ASCII = 'ascii' JIS = 'jis' UNICODE = 'unicode' ENCODINGS = (ASCII, JIS, UNICODE) # # The actual encodings accepted by the standard library differ slightly from # the above. # _JIS = 'shift_jis' _UNICODE = 'utf_16_be' _PREFIX_SIZE = 8 # # From Table 9: Character Codes and their Designation # _ASCII_PREFIX = b'\x41\x53\x43\x49\x49\x00\x00\x00' _JIS_PREFIX = b'\x4a\x49\x53\x00\x00\x00\x00\x00' _UNICODE_PREFIX = b'\x55\x4e\x49\x43\x4f\x44\x45\x00' _UNDEFINED_PREFIX = b'\x00\x00\x00\x00\x00\x00\x00\x00' @classmethod def load(cls, data): """ Convert "UserComment" value in exif format to str. :param bytes data: "UserComment" value from exif :return: u"foobar" :rtype: str(Unicode) :raises: ValueError if the data does not conform to the EXIF specification, or the encoding is unsupported. """ if len(data) < cls._PREFIX_SIZE: raise ValueError('not enough data to decode UserComment') prefix = data[:cls._PREFIX_SIZE] body = data[cls._PREFIX_SIZE:] if prefix == cls._UNDEFINED_PREFIX: raise ValueError('prefix is UNDEFINED, unable to decode UserComment') try: encoding = { cls._ASCII_PREFIX: cls.ASCII, cls._JIS_PREFIX: cls._JIS, cls._UNICODE_PREFIX: cls._UNICODE, }[prefix] except KeyError: raise ValueError('unable to determine appropriate encoding') return body.decode(encoding, errors='replace') @classmethod def dump(cls, data, encoding="ascii"): """ Convert str to appropriate format for "UserComment". :param data: Like u"foobar" :param str encoding: "ascii", "jis", or "unicode" :return: b"ASCII\x00\x00\x00foobar" :rtype: bytes :raises: ValueError if the encoding is unsupported. """ if encoding not in cls.ENCODINGS: raise ValueError('encoding {!r} must be one of {!r}'.format(encoding, cls.ENCODINGS)) prefix = {cls.ASCII: cls._ASCII_PREFIX, cls.JIS: cls._JIS_PREFIX, cls.UNICODE: cls._UNICODE_PREFIX}[encoding] internal_encoding = {cls.UNICODE: cls._UNICODE, cls.JIS: cls._JIS}.get(encoding, encoding) return prefix + data.encode(internal_encoding, errors='replace')