1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
import sys import struct from typing import Union, Tuple
SOI_MARKER = b'\xff\xd8' EOI_MARKER = b'\xff\xd9' STRIPPED_APP_MARKERS = [ b'\xff\xe0', b'\xff\xe1', b'\xff\xed' ]
def _unpack(format: str, data: bytes, data_length: int=None) -> \ Union[int,bytes]: if format == '{}s' and data_length is not None: format = '{}s'.format(data_length) return struct.unpack(format, data)[0]
def _to_int(content: bytes) -> int: return _unpack('>H', content)
def _is_app_marker(content: bytes) -> bool: value = _to_int(content) return value >= 0xff00 and content not in [SOI_MARKER, EOI_MARKER]
def _read(content: bytes, index: int, size: int) -> Tuple[bytes, int]: return content[index:index + size], index + size
def read_file(filename: str) -> bytes: with open(filename, 'rb') as f: return f.read()
def write_file(filename: str, content: bytes) -> None: with open(filename, 'wb') as f: f.write(content)
def drop_exif(source: bytes) -> bytes: target = bytearray() if len(source) <= 2 or source[0:2] != SOI_MARKER: return source target += SOI_MARKER index = 2 app_index = 0 while index < len(source): app_marker, index = _read(source, index, 2) app_index += 1 print('APP Marker[{}, {}]: {}'.format(app_index, index - 2, app_marker)) if _is_app_marker(app_marker): size_bytes, index = _read(source, index, 2) size = _to_int(size_bytes) if app_marker not in STRIPPED_APP_MARKERS: target += app_marker target += source[index - 2:index - 2 + size] print(' NON-EXIF segment is found, copy it...') else: print(' EXIF segment is found, skip it...') index = index - 2 + size else: target += app_marker target += source[index:] index = len(source) print(' Image stream is found, copy until the end.') return bytes(target)
if __name__ == '__main__': if len(sys.argv) < 3: print("Usage: strip_exif.py <source.jpg> <target.jpg>") exit(0) source_file = sys.argv[1] target_file = sys.argv[2] source = read_file(source_file) target = drop_exif(source) write_file(target_file, target) print('Done.')
|