diff --git a/.travis.yml b/.travis.yml index 89abb58..88a299b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,10 +9,10 @@ python: - 3.3 - 3.4 - 3.5 - - 3.6-dev + - 3.6 install: - - pip install pillow==2.9.0 + - pip install pillow==4.0.0 - pip install coveralls script: diff --git a/doc/appendices.rst b/doc/appendices.rst index a85a838..dec742d 100644 --- a/doc/appendices.rst +++ b/doc/appendices.rst @@ -82,3 +82,21 @@ On GoogleAppEngine, it can't save files on disk. Therefore files must be handled # transplant piexif.transplant(jpg_data1, jpg_data2, output) + +Invalid EXIF Thumbnails +----------------------- + +EXIF data will sometimes be either corrupted or written by non-compliant software. When this happens, it's possible +that the thumbnail stored in EXIF cannot be found when attempting to dump the EXIF dictionary. + +A good solution would be to remove the thumbnail from the EXIF dictionary and then re-attempt the dump: + +:: + + try: + exif_bytes = piexif.dump(exif_dict) + except InvalidImageDataError: + del exif_dict["1st"] + del exif_dict["thumbnail"] + exif_bytes = piexif.dump(exif_dict) + diff --git a/doc/changes.rst b/doc/changes.rst index 9541bbc..0491af6 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -1,6 +1,14 @@ Changelog ========= +1.0.12 +------ + +- Added explicit InvalidImageDataError exception to aid users. Related to https://github.com/hMatoba/Piexif/issues/30. +- Fixed minor issue with tests. +- Removed minor amounts of unused logic. +- Updated .travis.yml for Python and Pillow versions. + 1.0.11 ------ diff --git a/piexif/__init__.py b/piexif/__init__.py index 7b68e65..46133d2 100644 --- a/piexif/__init__.py +++ b/piexif/__init__.py @@ -4,6 +4,7 @@ from ._transplant import transplant from ._insert import insert from ._exif import * +from ._exeptions import * -VERSION = '1.0.11' +VERSION = '1.0.12' diff --git a/piexif/_common.py b/piexif/_common.py index aa632a7..f8ca2fd 100644 --- a/piexif/_common.py +++ b/piexif/_common.py @@ -1,11 +1,13 @@ import struct +from ._exeptions import InvalidImageDataError + def split_into_segments(data): """Slices JPEG meta data into a list from JPEG binary data. """ if data[0:2] != b"\xff\xd8": - raise ValueError("Given data isn't JPEG.") + raise InvalidImageDataError("Given data isn't JPEG.") head = 2 segments = [b"\xff\xd8"] @@ -21,7 +23,7 @@ def split_into_segments(data): head = endPoint if (head >= len(data)): - raise ValueError("Wrong JPEG data.") + raise InvalidImageDataError("Wrong JPEG data.") return segments def read_exif_from_file(filename): @@ -31,10 +33,9 @@ def read_exif_from_file(filename): data = f.read(6) if data[0:2] != b"\xff\xd8": - raise ValueError("Given data isn't JPEG.") + raise InvalidImageDataError("Given data isn't JPEG.") head = data[2:6] - head_pos = 2 HEAD_LENGTH = 4 exif = None while 1: diff --git a/piexif/_exeptions.py b/piexif/_exeptions.py new file mode 100644 index 0000000..bde0908 --- /dev/null +++ b/piexif/_exeptions.py @@ -0,0 +1,2 @@ +class InvalidImageDataError(ValueError): + pass diff --git a/piexif/_insert.py b/piexif/_insert.py index 90b3eb1..6df0eac 100644 --- a/piexif/_insert.py +++ b/piexif/_insert.py @@ -2,6 +2,7 @@ import struct from ._common import * +from ._exeptions import InvalidImageDataError def insert(exif, image, new_file=None): @@ -24,10 +25,9 @@ def insert(exif, image, new_file=None): with open(image, 'rb') as f: image_data = f.read() if image_data[0:2] != b"\xff\xd8": - raise ValueError + raise InvalidImageDataError output_file = True segments = split_into_segments(image_data) - image_exif = get_exif_seg(segments) new_data = merge_segments(segments, exif) if isinstance(new_file, io.BytesIO): diff --git a/piexif/_load.py b/piexif/_load.py index 98f6eb9..784faab 100644 --- a/piexif/_load.py +++ b/piexif/_load.py @@ -1,6 +1,7 @@ import struct from ._common import * +from ._exeptions import InvalidImageDataError from ._exif import * @@ -90,7 +91,7 @@ def __init__(self, data): with open(data, 'rb') as f: self.tiftag = f.read() else: - raise ValueError("Given file is neither JPEG nor TIFF.") + raise InvalidImageDataError("Given file is neither JPEG nor TIFF.") def get_ifd_dict(self, pointer, ifd_name, read_unknown=False): ifd_dict = {} diff --git a/piexif/_transplant.py b/piexif/_transplant.py index 36c6c1a..c0eea6f 100644 --- a/piexif/_transplant.py +++ b/piexif/_transplant.py @@ -30,7 +30,6 @@ def transplant(exif_src, image, new_file=None): image_data = f.read() output_file = True segments = split_into_segments(image_data) - image_exif = get_exif_seg(segments) new_data = merge_segments(segments, exif) if isinstance(new_file, io.BytesIO): diff --git a/tests/s_test.py b/tests/s_test.py index b4dce02..9bf0796 100644 --- a/tests/s_test.py +++ b/tests/s_test.py @@ -9,7 +9,7 @@ from PIL import Image import piexif -from piexif import _common, ImageIFD, ExifIFD, GPSIFD, TAGS +from piexif import _common, ImageIFD, ExifIFD, GPSIFD, TAGS, InvalidImageDataError print("piexif version: {0}".format(piexif.VERSION)) @@ -596,7 +596,7 @@ def test_ExifReader_return_unknown(self): b2 = b"\x00\x01" + b"\xff\xff\x00\x00\x00\x00" + b"\x00\x00\x00\x00" er = piexif._load._ExifReader(b1 + b2) if er.tiftag[0:2] == b"II": - exifReader.endian_mark = "<" + er.endian_mark = "<" else: er.endian_mark = ">" ifd = er.get_ifd_dict(8, "0th", True) @@ -610,7 +610,7 @@ def test_ExifReader_convert_value_fail(self): er.convert_value((None, None, None, None)) def test_split_into_segments_fail1(self): - with self.assertRaises(ValueError): + with self.assertRaises(InvalidImageDataError): _common.split_into_segments(b"I'm not JPEG") def test_split_into_segments_fail2(self):