Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent XMP data retrieval: Failure with specific JPEG files #7324

Closed
ckanaar opened this issue Aug 7, 2023 · 4 comments · Fixed by #7274
Closed

Inconsistent XMP data retrieval: Failure with specific JPEG files #7324

ckanaar opened this issue Aug 7, 2023 · 4 comments · Fixed by #7274
Labels

Comments

@ckanaar
Copy link

ckanaar commented Aug 7, 2023

What did you do?

I'm loading a .jpg image using Pillow in an attempt to extract the XMP metadata:

from PIL import Image

image = Image.open("lib/filename_example_1.jpg")
raw_xmp_info = image.getxmp()

What did you expect to happen?

I'm expecting getxmp() to return a dictionary containing the image's XMP metadata: {'xmpmeta: {<metadata>}.

What actually happened?

Pillow can't extract the XMP metadata from the image:

Traceback (most recent call last):
  File "/path/to/main.py", line 4, in <module>
    raw_xmp_info = image.getxmp()
                   ^^^^^^^^^^^^^^
  File "/path/to/venv/site-packages/PIL/JpegImagePlugin.py", line 501, in getxmp
    return self._getxmp(xmp_tags)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/path/to/venv/site-packages/PIL/Image.py", line 1410, in _getxmp
    return {get_name(root.tag): get_value(root)}
                                ^^^^^^^^^^^^^^^
  File "/path/to/venv/site-packages/PIL/Image.py", line 1391, in get_value
    child_value = get_value(child)
                  ^^^^^^^^^^^^^^^^
  File "/path/to/venv/site-packages/PIL/Image.py", line 1391, in get_value
    child_value = get_value(child)
                  ^^^^^^^^^^^^^^^^
  File "/path/to/venv/site-packages/PIL/Image.py", line 1386, in get_value
    value = {get_name(k): v for k, v in element.attrib.items()}
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/path/to/venv/site-packages/PIL/Image.py", line 1386, in <dictcomp>
    value = {get_name(k): v for k, v in element.attrib.items()}
             ^^^^^^^^^^^
  File "/path/to/venv/site-packages/PIL/Image.py", line 1383, in get_name
    return tag.split("}")[1]
           ~~~~~~~~~~~~~~^^^
IndexError: list index out of range

What are your OS, Python and Pillow versions?

  • OS: WSL2 - Ubuntu 22.04.2 LTS
  • Python: 3.11.4
  • Pillow: 10.0.0 (also getting the error with 9.x)

Additional information.

Printing image.info reveals:

{'jfif': 257, 'jfif_version': (1, 1), 'dpi': (240, 240), 'jfif_unit': 1, 'jfif_density': (240, 240), 'photoshop': {1028: b'\x1c\x02\x00\x00\x02\x00\x02\x1c\x01Z\x00\x03\x1b%G\x1c\x02i\x00\x1f"Enkeltrick"-Betrug vor Gericht\x1c\x02\x19\x00\x14.Nordrhein-Westfalen\x1c\x02\x19\x00\x03Ges\x1c\x02\x19\x00\rKriminalit\xc3\xa4t\x1c\x02\x19\x00\x03lnw\x1c\x02\x19\x00\x08Prozesse\x1c\x02\x19\x00\tRegierung\x1c\x02\x19\x00\x08Senioren\x1c\x02\x19\x00\nSicherheit\x1c\x02\x19\x00\x07Telefon\x1c\x02\x19\x00\x0bVermischtes\x1c\x02\x19\x00\x0c\xc3\x9cberwachung\x1c\x02\x19\x00\x12\xc3\x9cberwachungsstaat\x1c\x02\x19\x00\x07XGV2011\x1c\x02Z\x00\x07Dresden\x1c\x02_\x00\x07Sachsen\x1c\x02e\x00\x0bDeutschland\x1c\x02d\x00\x03DEU\x1c\x027\x00\x0820131216\x1c\x02P\x00\nArno Burgi\x1c\x02t\x00-picture alliance / Arno Burgi/dpa-Zentralbild\x1c\x02z\x00\x17abu vfd htf kno sup bsc\x1c\x02n\x00-picture alliance / Arno Burgi/dpa-Zentralbild\x1c\x02s\x00\x0fdpa-Zentralbild\x1c\x02\x05\x00\x0886540586\x1c\x02\x83\x00\tlandscape\x1c\x02x\x01uARCHIV\xc2\xa0- ILLUSTRATION - Eine Frau telefoniert am 16.12.2013 in Dresden (Sachsen) mit ihrem Mobiltelefon an der Wand zeichnet sich ihr Schatten ab. Beim Enkeltrick gaukeln Betr\xc3\xbcger ihren meist betagten Opfern am Telefon vor, ein naher Verwandter - etwa ein Enkel - zu sein. Foto: Arno Burgi/dpa (zu dpa vom 16.12.2016) Foto: Arno Burgi/dpa-Zentralbild +++ dpa-Bildfunk +++\x1c\x02(\x00\x00\x00'}, 'icc_profile': b'\x00\x00\x0cHLino\x02\x10\x00\x00mntrRGB XYZ \x07\xce\x00\x02\x00\t\x00\x06\x001\x00\x00acspMSFT\x00\x00\x00\x00IEC sRGB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xd6\x00\x01\x00\x00\x00\x00\xd3-HP  \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11cprt\x00\x00\x01P\x00\x00\x003desc\x00\x00\x01\x84\x00\x00\x00lwtpt\x00\x00\x01\xf0\x00\x00\x00\x14bkpt\x00\x00\x02\x04\x00\x00\x00\x14rXYZ\x00\x00\x02\x18\x00\x00\x00\x14gXYZ\x00\x00\x02,\x00\x00\x00\x14bXYZ\x00\x00\x02@\x00\x00\x00\x14dmnd\x00\x00\x02T\x00\x00\x00pdmdd\x00\x00\x02\xc4\x00\x00\x00\x88vued\x00\x00\x03L\x00\x00\x00\x86view\x00\x00\x03\xd4\x00\x00\x00$lumi\x00\x00\x03\xf8\x00\x00\x00\x14meas\x00\x00\x04\x0c\x00\x00\x00$tech\x00\x00\x040\x00\x00\x00\x0crTRC\x00\x00\x04<\x00\x00\x08\x0cgTRC\x00\x00\x04<\x00\x00\x08\x0cbTRC\x00\x00\x04<\x00\x00\x08\x0ctext\x00\x00\x00\x00Copyright (c) 1998 Hewlett-Packard Company\x00\x00desc\x00\x00\x00\x00\x00\x00\x00\x12sRGB IEC61966-2.1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12sRGB IEC61966-2.1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00XYZ \x00\x00\x00\x00\x00\x00\xf3Q\x00\x01\x00\x00\x00\x01\x16\xccXYZ \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00XYZ \x00\x00\x00\x00\x00\x00o\xa2\x00\x008\xf5\x00\x00\x03\x90XYZ \x00\x00\x00\x00\x00\x00b\x99\x00\x00\xb7\x85\x00\x00\x18\xdaXYZ \x00\x00\x00\x00\x00\x00$\xa0\x00\x00\x0f\x84\x00\x00\xb6\xcfdesc\x00\x00\x00\x00\x00\x00\x00\x16IEC http://www.iec.ch\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16IEC http://www.iec.ch\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00desc\x00\x00\x00\x00\x00\x00\x00.IEC 61966-2.1 Default RGB colour space - sRGB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.IEC 61966-2.1 Default RGB colour space - sRGB\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00desc\x00\x00\x00\x00\x00\x00\x00,Reference Viewing Condition in IEC61966-2.1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,Reference Viewing Condition in IEC61966-2.1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00view\x00\x00\x00\x00\x00\x13\xa4\xfe\x00\x14_.\x00\x10\xcf\x14\x00\x03\xed\xcc\x00\x04\x13\x0b\x00\x03\\\x9e\x00\x00\x00\x01XYZ \x00\x00\x00\x00\x00L\tV\x00P\x00\x00\x00W\x1f\xe7meas\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x8f\x00\x00\x00\x02sig \x00\x00\x00\x00CRT curv\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x05\x00\n\x00\x0f\x00\x14\x00\x19\x00\x1e\x00#\x00(\x00-\x002\x007\x00;\x00@\x00E\x00J\x00O\x00T\x00Y\x00^\x00c\x00h\x00m\x00r\x00w\x00|\x00\x81\x00\x86\x00\x8b\x00\x90\x00\x95\x00\x9a\x00\x9f\x00\xa4\x00\xa9\x00\xae\x00\xb2\x00\xb7\x00\xbc\x00\xc1\x00\xc6\x00\xcb\x00\xd0\x00\xd5\x00\xdb\x00\xe0\x00\xe5\x00\xeb\x00\xf0\x00\xf6\x00\xfb\x01\x01\x01\x07\x01\r\x01\x13\x01\x19\x01\x1f\x01%\x01+\x012\x018\x01>\x01E\x01L\x01R\x01Y\x01`\x01g\x01n\x01u\x01|\x01\x83\x01\x8b\x01\x92\x01\x9a\x01\xa1\x01\xa9\x01\xb1\x01\xb9\x01\xc1\x01\xc9\x01\xd1\x01\xd9\x01\xe1\x01\xe9\x01\xf2\x01\xfa\x02\x03\x02\x0c\x02\x14\x02\x1d\x02&\x02/\x028\x02A\x02K\x02T\x02]\x02g\x02q\x02z\x02\x84\x02\x8e\x02\x98\x02\xa2\x02\xac\x02\xb6\x02\xc1\x02\xcb\x02\xd5\x02\xe0\x02\xeb\x02\xf5\x03\x00\x03\x0b\x03\x16\x03!\x03-\x038\x03C\x03O\x03Z\x03f\x03r\x03~\x03\x8a\x03\x96\x03\xa2\x03\xae\x03\xba\x03\xc7\x03\xd3\x03\xe0\x03\xec\x03\xf9\x04\x06\x04\x13\x04 \x04-\x04;\x04H\x04U\x04c\x04q\x04~\x04\x8c\x04\x9a\x04\xa8\x04\xb6\x04\xc4\x04\xd3\x04\xe1\x04\xf0\x04\xfe\x05\r\x05\x1c\x05+\x05:\x05I\x05X\x05g\x05w\x05\x86\x05\x96\x05\xa6\x05\xb5\x05\xc5\x05\xd5\x05\xe5\x05\xf6\x06\x06\x06\x16\x06\'\x067\x06H\x06Y\x06j\x06{\x06\x8c\x06\x9d\x06\xaf\x06\xc0\x06\xd1\x06\xe3\x06\xf5\x07\x07\x07\x19\x07+\x07=\x07O\x07a\x07t\x07\x86\x07\x99\x07\xac\x07\xbf\x07\xd2\x07\xe5\x07\xf8\x08\x0b\x08\x1f\x082\x08F\x08Z\x08n\x08\x82\x08\x96\x08\xaa\x08\xbe\x08\xd2\x08\xe7\x08\xfb\t\x10\t%\t:\tO\td\ty\t\x8f\t\xa4\t\xba\t\xcf\t\xe5\t\xfb\n\x11\n\'\n=\nT\nj\n\x81\n\x98\n\xae\n\xc5\n\xdc\n\xf3\x0b\x0b\x0b"\x0b9\x0bQ\x0bi\x0b\x80\x0b\x98\x0b\xb0\x0b\xc8\x0b\xe1\x0b\xf9\x0c\x12\x0c*\x0cC\x0c\\\x0cu\x0c\x8e\x0c\xa7\x0c\xc0\x0c\xd9\x0c\xf3\r\r\r&\r@\rZ\rt\r\x8e\r\xa9\r\xc3\r\xde\r\xf8\x0e\x13\x0e.\x0eI\x0ed\x0e\x7f\x0e\x9b\x0e\xb6\x0e\xd2\x0e\xee\x0f\t\x0f%\x0fA\x0f^\x0fz\x0f\x96\x0f\xb3\x0f\xcf\x0f\xec\x10\t\x10&\x10C\x10a\x10~\x10\x9b\x10\xb9\x10\xd7\x10\xf5\x11\x13\x111\x11O\x11m\x11\x8c\x11\xaa\x11\xc9\x11\xe8\x12\x07\x12&\x12E\x12d\x12\x84\x12\xa3\x12\xc3\x12\xe3\x13\x03\x13#\x13C\x13c\x13\x83\x13\xa4\x13\xc5\x13\xe5\x14\x06\x14\'\x14I\x14j\x14\x8b\x14\xad\x14\xce\x14\xf0\x15\x12\x154\x15V\x15x\x15\x9b\x15\xbd\x15\xe0\x16\x03\x16&\x16I\x16l\x16\x8f\x16\xb2\x16\xd6\x16\xfa\x17\x1d\x17A\x17e\x17\x89\x17\xae\x17\xd2\x17\xf7\x18\x1b\x18@\x18e\x18\x8a\x18\xaf\x18\xd5\x18\xfa\x19 \x19E\x19k\x19\x91\x19\xb7\x19\xdd\x1a\x04\x1a*\x1aQ\x1aw\x1a\x9e\x1a\xc5\x1a\xec\x1b\x14\x1b;\x1bc\x1b\x8a\x1b\xb2\x1b\xda\x1c\x02\x1c*\x1cR\x1c{\x1c\xa3\x1c\xcc\x1c\xf5\x1d\x1e\x1dG\x1dp\x1d\x99\x1d\xc3\x1d\xec\x1e\x16\x1e@\x1ej\x1e\x94\x1e\xbe\x1e\xe9\x1f\x13\x1f>\x1fi\x1f\x94\x1f\xbf\x1f\xea \x15 A l \x98 \xc4 \xf0!\x1c!H!u!\xa1!\xce!\xfb"\'"U"\x82"\xaf"\xdd#\n#8#f#\x94#\xc2#\xf0$\x1f$M$|$\xab$\xda%\t%8%h%\x97%\xc7%\xf7&\'&W&\x87&\xb7&\xe8\'\x18\'I\'z\'\xab\'\xdc(\r(?(q(\xa2(\xd4)\x06)8)k)\x9d)\xd0*\x02*5*h*\x9b*\xcf+\x02+6+i+\x9d+\xd1,\x05,9,n,\xa2,\xd7-\x0c-A-v-\xab-\xe1.\x16.L.\x82.\xb7.\xee/$/Z/\x91/\xc7/\xfe050l0\xa40\xdb1\x121J1\x821\xba1\xf22*2c2\x9b2\xd43\r3F3\x7f3\xb83\xf14+4e4\x9e4\xd85\x135M5\x875\xc25\xfd676r6\xae6\xe97$7`7\x9c7\xd78\x148P8\x8c8\xc89\x059B9\x7f9\xbc9\xf9:6:t:\xb2:\xef;-;k;\xaa;\xe8<\'<e<\xa4<\xe3="=a=\xa1=\xe0> >`>\xa0>\xe0?!?a?\xa2?\xe2@#@d@\xa6@\xe7A)AjA\xacA\xeeB0BrB\xb5B\xf7C:C}C\xc0D\x03DGD\x8aD\xceE\x12EUE\x9aE\xdeF"FgF\xabF\xf0G5G{G\xc0H\x05HKH\x91H\xd7I\x1dIcI\xa9I\xf0J7J}J\xc4K\x0cKSK\x9aK\xe2L*LrL\xbaM\x02MJM\x93M\xdcN%NnN\xb7O\x00OIO\x93O\xddP\'PqP\xbbQ\x06QPQ\x9bQ\xe6R1R|R\xc7S\x13S_S\xaaS\xf6TBT\x8fT\xdbU(UuU\xc2V\x0fV\\V\xa9V\xf7WDW\x92W\xe0X/X}X\xcbY\x1aYiY\xb8Z\x07ZVZ\xa6Z\xf5[E[\x95[\xe5\\5\\\x86\\\xd6]\']x]\xc9^\x1a^l^\xbd_\x0f_a_\xb3`\x05`W`\xaa`\xfcaOa\xa2a\xf5bIb\x9cb\xf0cCc\x97c\xebd@d\x94d\xe9e=e\x92e\xe7f=f\x92f\xe8g=g\x93g\xe9h?h\x96h\xeciCi\x9ai\xf1jHj\x9fj\xf7kOk\xa7k\xfflWl\xafm\x08m`m\xb9n\x12nkn\xc4o\x1eoxo\xd1p+p\x86p\xe0q:q\x95q\xf0rKr\xa6s\x01s]s\xb8t\x14tpt\xccu(u\x85u\xe1v>v\x9bv\xf8wVw\xb3x\x11xnx\xccy*y\x89y\xe7zFz\xa5{\x04{c{\xc2|!|\x81|\xe1}A}\xa1~\x01~b~\xc2\x7f#\x7f\x84\x7f\xe5\x80G\x80\xa8\x81\n\x81k\x81\xcd\x820\x82\x92\x82\xf4\x83W\x83\xba\x84\x1d\x84\x80\x84\xe3\x85G\x85\xab\x86\x0e\x86r\x86\xd7\x87;\x87\x9f\x88\x04\x88i\x88\xce\x893\x89\x99\x89\xfe\x8ad\x8a\xca\x8b0\x8b\x96\x8b\xfc\x8cc\x8c\xca\x8d1\x8d\x98\x8d\xff\x8ef\x8e\xce\x8f6\x8f\x9e\x90\x06\x90n\x90\xd6\x91?\x91\xa8\x92\x11\x92z\x92\xe3\x93M\x93\xb6\x94 \x94\x8a\x94\xf4\x95_\x95\xc9\x964\x96\x9f\x97\n\x97u\x97\xe0\x98L\x98\xb8\x99$\x99\x90\x99\xfc\x9ah\x9a\xd5\x9bB\x9b\xaf\x9c\x1c\x9c\x89\x9c\xf7\x9dd\x9d\xd2\x9e@\x9e\xae\x9f\x1d\x9f\x8b\x9f\xfa\xa0i\xa0\xd8\xa1G\xa1\xb6\xa2&\xa2\x96\xa3\x06\xa3v\xa3\xe6\xa4V\xa4\xc7\xa58\xa5\xa9\xa6\x1a\xa6\x8b\xa6\xfd\xa7n\xa7\xe0\xa8R\xa8\xc4\xa97\xa9\xa9\xaa\x1c\xaa\x8f\xab\x02\xabu\xab\xe9\xac\\\xac\xd0\xadD\xad\xb8\xae-\xae\xa1\xaf\x16\xaf\x8b\xb0\x00\xb0u\xb0\xea\xb1`\xb1\xd6\xb2K\xb2\xc2\xb38\xb3\xae\xb4%\xb4\x9c\xb5\x13\xb5\x8a\xb6\x01\xb6y\xb6\xf0\xb7h\xb7\xe0\xb8Y\xb8\xd1\xb9J\xb9\xc2\xba;\xba\xb5\xbb.\xbb\xa7\xbc!\xbc\x9b\xbd\x15\xbd\x8f\xbe\n\xbe\x84\xbe\xff\xbfz\xbf\xf5\xc0p\xc0\xec\xc1g\xc1\xe3\xc2_\xc2\xdb\xc3X\xc3\xd4\xc4Q\xc4\xce\xc5K\xc5\xc8\xc6F\xc6\xc3\xc7A\xc7\xbf\xc8=\xc8\xbc\xc9:\xc9\xb9\xca8\xca\xb7\xcb6\xcb\xb6\xcc5\xcc\xb5\xcd5\xcd\xb5\xce6\xce\xb6\xcf7\xcf\xb8\xd09\xd0\xba\xd1<\xd1\xbe\xd2?\xd2\xc1\xd3D\xd3\xc6\xd4I\xd4\xcb\xd5N\xd5\xd1\xd6U\xd6\xd8\xd7\\\xd7\xe0\xd8d\xd8\xe8\xd9l\xd9\xf1\xdav\xda\xfb\xdb\x80\xdc\x05\xdc\x8a\xdd\x10\xdd\x96\xde\x1c\xde\xa2\xdf)\xdf\xaf\xe06\xe0\xbd\xe1D\xe1\xcc\xe2S\xe2\xdb\xe3c\xe3\xeb\xe4s\xe4\xfc\xe5\x84\xe6\r\xe6\x96\xe7\x1f\xe7\xa9\xe82\xe8\xbc\xe9F\xe9\xd0\xea[\xea\xe5\xebp\xeb\xfb\xec\x86\xed\x11\xed\x9c\xee(\xee\xb4\xef@\xef\xcc\xf0X\xf0\xe5\xf1r\xf1\xff\xf2\x8c\xf3\x19\xf3\xa7\xf44\xf4\xc2\xf5P\xf5\xde\xf6m\xf6\xfb\xf7\x8a\xf8\x19\xf8\xa8\xf98\xf9\xc7\xfaW\xfa\xe7\xfbw\xfc\x07\xfc\x98\xfd)\xfd\xba\xfeK\xfe\xdc\xffm\xff\xff'}

Due to confidentiality reasons, I can not provide the image that I'm trying to process. However, I will provide the anonomised XMP metadata of the image that causes the error (filename_example_1.jpg) and one which doesn't cause an error (filename_example_2.jpg). This XMP metadata was extracted using https://www.imgonline.com.ua/. This shows that the metadata is present for both the working and the erroneous files.

filename_example_1.jpg (erroneous):

  • About: Anonymous
  • City: Anonymous
  • State: Anonymous
  • Country: Anonymous
  • Credit: Anonymous
  • Source: Anonymous
  • Caption Writer: Anonymous
  • Headline: Anonymous
  • Create Date: Anonymous
  • Marked: True
  • Creator: Anonymous
  • Subject: Anonymous
  • Description: Anonymous
  • Rights: Anonymous
  • Title: 86540586
  • Country Code: Anonymous
  • Creator Contact Info: Anonymous

filename_example_2.jpg (successfully loaded by Pillow):

  • Metadata Date: Anonymous
  • Rating: 0
  • Format: image/jpeg
  • Subject: Anonymous
  • Description: Anonymous
  • Creator: Anonymous
  • Rights: Anonymous
  • Lens: EF70-200mm f/4L USM
  • Image Number: 0
  • Approximate Focus Distance: 4294967295
  • Flash Compensation: 0
  • Firmware: 1.3.3
  • Color Mode: RGB
  • ICC Profile Name: sRGB IEC61966-2. 1
  • City: Anonymous
  • State: Anonymous
  • Country: Anonymous
  • Category: SPO
  • Credit: Anonymous
  • Source: Anonymous
  • Headline: Anonymous
  • Date Created: Anonymous
  • Document ID: Anonymous
  • Instance ID: Anonymous
  • Original Document ID: Anonymous
  • History Action: saved, saved
  • History Instance ID: Anonymous
  • History When: Anonymous
  • History Sofware Agent: Anonymous
  • History Changed: /, /
  • Marked: True
  • Prefs: Tagged:0, ColorClass:0, Rating: 0, FrameNum:00115
  • PM Version: PM4
  • Country Code: Anonymous
  • Location: Anonymous

If anyone is able to provide some insights into this bug, please let me know!

@radarhere
Copy link
Member

Hi. Looking at your traceback, I think we actually have a fix in progress for this already - #7274. Are you able to test that and see if it solves your problem?

@radarhere radarhere added the JPEG label Aug 7, 2023
@ckanaar
Copy link
Author

ckanaar commented Aug 7, 2023

Thank you for the reply. How can I test this fix though, as it seems to be implemented in the source code? (I'm rather new to this, so apologies for any obvious questions).

@radarhere
Copy link
Member

No worries, not a silly question at all.

You could
a) download the code from https://github.com/radarhere/Pillow/tree/jpeg_xmp (the branch of the PR) and install Pillow from source out of that directory
b) since it is just a Python change, it is likely you could just determine the path to your installed copy of Pillow, open up Image.py in your favourite editor, and change the code directly

But the simplest, least invasive method would be
c) just monkeypatch Pillow - meaning, replace the code at runtime.

So, for Option C, just run the following code and kindly report back if it works.

from PIL import Image

def _getxmp(self, xmp_tags):
    def get_name(tag):
        return re.sub("^{[^}]+}", "", tag)

    def get_value(element):
        value = {get_name(k): v for k, v in element.attrib.items()}
        children = list(element)
        if children:
            for child in children:
                name = get_name(child.tag)
                child_value = get_value(child)
                if name in value:
                    if not isinstance(value[name], list):
                        value[name] = [value[name]]
                    value[name].append(child_value)
                else:
                    value[name] = child_value
        elif value:
            if element.text:
                value["text"] = element.text
        else:
            return element.text
        return value

    if ElementTree is None:
        warnings.warn("XMP data cannot be read without defusedxml dependency")
        return {}
    else:
        root = ElementTree.fromstring(xmp_tags)
        return {get_name(root.tag): get_value(root)}

Image.Image._getxmp = _getxmp

image = Image.open("lib/filename_example_1.jpg")
raw_xmp_info = image.getxmp()

@ckanaar
Copy link
Author

ckanaar commented Aug 8, 2023

Thank you for your reply. I have tested my JPEG using the code snippet you provided and it succesfully loads the XMP data. Therefore it works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants