DigitalSlideArchive / tifftools

Pure Python tools for reading and writing all TIFF IFDs, sub-IFDs, and tags.
Other
49 stars 5 forks source link

Readme example seems to be incorrect #63

Closed AmedeeBulle closed 2 years ago

AmedeeBulle commented 2 years ago

Running the sample code from the readme file gives:

$ python3 sample.py
Traceback (most recent call last):
  File "sample2.py", line 8, in <module>
    exififd['tags'][tifftools.constants.EXIFTag.FNumber.value] = {
TypeError: list indices must be integers or slices, not str

it seems that we are missing level for exifs (SubIDF?).

The following does works:

$ diff -u sample.py.orig sample.py
--- sample.py.orig      2022-02-28 18:19:35.000000000 +0100
+++ sample.py   2022-02-28 18:19:52.000000000 +0100
@@ -4,7 +4,7 @@
     'data': 'A dog digging.',
     'datatype': tifftools.Datatype.ASCII
 }
-exififd = info['ifds'][0]['tags'][tifftools.Tag.EXIFIFD.value]['ifds'][0]
+exififd = info['ifds'][0]['tags'][tifftools.Tag.EXIFIFD.value]['ifds'][0][0]
 exififd['tags'][tifftools.constants.EXIFTag.FNumber.value] = {
     'data': [54, 10],
     'datatype': tifftools.Datatype.RATIONAL
$ python3 sample.py
$ tifftools dump photograph_tagged.tif | grep FNumber
      FNumber 33437 (0x829D) RATIONAL: 54 10 (5.4)

Side note: the above code will fail if the TIFF file doesn't already contains EXIFs. Is the following snippet the correct way to add EXIF IFD?

try:
    exif = info["ifds"][0]["tags"][tifftools.Tag.EXIFIFD.value]
except KeyError:
    exif = {
        "datatype": tifftools.Datatype.IFD,
        "ifds": [[{"tags": {}, "path_or_fobj": info["ifds"][0]["path_or_fobj"]}]],
    }
    info["ifds"][0]["tags"][tifftools.Tag.EXIFIFD.value] = exif
exififd = exif["ifds"][0][0]
# add tags herunder
manthey commented 2 years ago

Thank you. There was a missing [0], as you noted. I've added a test to ensure code in the README executes as expected.

manthey commented 2 years ago

And, yes, your example is a correct way to add the EXIF IFD.

I should make it optional to populate the path_or_fobj field -- if the ifd doesn't contain byte offset records that need to be copied from a source file, it isn't actually used.