hMatoba / Piexif

Exif manipulation with pure python script.
MIT License
367 stars 81 forks source link

.dump - UnboundLocalError exception when GPS Data in text form is converted to bytes #67

Open alexliggett opened 5 years ago

alexliggett commented 5 years ago

Hi,

Firstly thanks for the awesome work on this library, which is perfect for the project I'm working on.

Just a heads up that if you try to write strings (I know, probably a dumb idea, but one I assumed to be correct at first) to the GPS Latitude/Longitude/Altitude Key EXIF fields using .dump, the following exception is thrown:

Traceback (most recent call last): File "H:/files/Exif project/Exif_test.py", line 244, in main() File "H:/files/Exif project/Exif_test.py", line 50, in process_images(data_list, difference) File "H:/files/Exif project/Exif_test.py", line 130, in write_exif_2_photo(entry, current_file, photo_exif_dict, photo_time) File "H:/files/Exif project/Exif_test.py", line 190, in photo_exif_bytes = piexif.dump(photo_exif_dict) File "C:\Users\Alex.Liggett\AppData\Local\Programs\Python\Python36-32\Lib\site-packages\piexif_dump.py", line 74, in dump gps_set = _dict_to_bytes(gps_ifd, "GPS", zeroth_length + exif_length) File "C:\Users\Alex.Liggett\AppData\Local\Programs\Python\Python36-32\Lib\site-packages\piexif_dump.py", line 341, in _dict_to_bytes offset) File "C:\Users\Alex.Liggett\AppData\Local\Programs\Python\Python36-32\Lib\site-packages\piexif_dump.py", line 247, in _value_to_bytes four_bytes_over = new_value builtins.UnboundLocalError: local variable 'new_value' referenced before assignment

Happy to supply more information if it will help, but I suspect its something fairly straightforward.

Cheers Alex

skirienko commented 5 years ago

I probably have the same issue. My broken field is GPS['GPSHPositioningError']. iPhone treats this field as Ascii (type 2). So when we load exif data, this field is collected as Ascii (for example, b'65/1' for me). When we dump it, it tries to dump this Ascii field as it was Rational (type 5). Because in _exif.py this field is described as Rational.

We should probably either dump fields with the same type we loaded them or fix wrongly loaded types to canonical ones during dump (or right after load). Loading field by one rules and dumping by others is a way to errors.

Traceback (most recent call last):
  File ".\resize.py", line 105, in <module>
    byte_exif = piexif.dump(exif)
  File "C:\Program Files\Python37\lib\site-packages\piexif\_dump.py", line 74, in dump
    gps_set = _dict_to_bytes(gps_ifd, "GPS", zeroth_length + exif_length)
  File "C:\Program Files\Python37\lib\site-packages\piexif\_dump.py", line 341, in _dict_to_bytes
    '{0} in {1} IFD. Got as {2}.'.format(key, ifd, type(ifd_dict[key]))
ValueError: "dump" got wrong type of exif value.
31 in GPS IFD. Got as <class 'bytes'>.
hMatoba commented 5 years ago

Exif data in binary contains each data type. "load" uses it. On the other hand, to "dump" exif data, it needs some reference to convert value into binary. I use object in _exif.py that was made from the specification(http://www.cipa.jp/std/documents/e/DC-010-2012_E.pdf).

To fix type, we need very tricky code. b'65/1' or [some format that we can't unpredictable] or [other type and format] -> (65, 1)

"dump" should doubt type data that contained in exif binary? I think no.

iOS should fix it to comply with the specifications.