locationtech / geotrellis

GeoTrellis is a geographic data processing engine for high performance applications.
http://geotrellis.io
Other
1.32k stars 360 forks source link

Reading a TIFF and then writing it back may loose BitsPerSample information #3516

Open julienrf opened 11 months ago

julienrf commented 11 months ago

Describe the bug

BitsPerSample is modeled as an Int, although in multi-band TIFFs this tag contains as many values as SamplesPerPixel. This results in producing invalid multi-band TIFFs that cannot be consumed by third-party tools.

To Reproduce

Add a file read-and-write-back.scala to the project root directory with the following content:

//> using scala 3
//> using dep "org.locationtech.geotrellis:geotrellis-raster_2.13:3.7.0"

import geotrellis.raster.io.geotiff.MultibandGeoTiff

@main def run() =
  val originalTiff = MultibandGeoTiff("./raster/data/geotiff-test-files/overviews/multiband.tif")
  originalTiff.write("/tmp/multiband.tif")

Then, run the following commands from a shell, from within the project root directory:

scala-cli read-and-write-back.scala
exiftool -IFD0:BitsPerSample /tmp/multiband.tif
exiftool -IFD0:BitsPerSample ./raster/data/geotiff-test-files/overviews/multiband.tif

Actual output:

Bits Per Sample                 : 8
Bits Per Sample                 : 8 8 8 8

Note that the BitsPerSample tag of the written file /tmp/multiband.tif is 8, whereas the original file contained 8 8 8 8.

Expected output:

Bits Per Sample                 : 8 8 8 8
Bits Per Sample                 : 8 8 8 8

The BitsPerSample tag should be a collection.

Environment

Additional context

According to the following comment, this issue seems to be known from the project maintainers:

https://github.com/locationtech/geotrellis/blob/d65d6a22eb70efd96caa5c6f5f660b2b936b2763/raster/src/main/scala/geotrellis/raster/io/geotiff/tags/BasicTags.scala#L25

However, the comments refers to a lib libtiff which I am not sure to follow what it refers to. Is this comment legacy? If yes, would you consider changing the model of bitsPerSample to be an Array[Short] instead of an Int?