Open pomadchin opened 5 years ago
Potentially the issue is caused by the bits padding we do. I could fix partially tiff conversion by using paddedCols
to compute pixel position in a segment during the conversion step, but it also introduced a slight image shift (and this is true only in some cases, depending on how the segment layout is sliced).
The difference between tiled and striped tiffs in this case is that all tiled
segments require no padding and they are already 'padded'. Striped tiffs are occupying the minimum required space to encode bits.
Padding here means to adjust number of array size that backs segment to fit bits but in bytes ((cols / 7) * 8)
Leaving a GDAL reference here: https://github.com/OSGeo/gdal/blob/master/gdal/frmts/gtiff/geotiff.cpp#L6594
There is a partial fix to this in #3129. Full solution issue us going to the backlog for a little while as our priorities shift. Since we're shifting to expectations that GeoTiffs we're working with are COGs (tiled, not striped) and bit geotiff is relatively uncommon.
PR https://github.com/locationtech/geotrellis/pull/3102 addresses
Tiled
BitGeoTiffs
support, and allows to read such tiles, convert, transform, and to perform all operations withTiled
BitGeoTiffs
.However, the following code would fail:
It turned out, the problem is more deep, and it looks like we don't have a fully correct support of
Striped
BitGeoTiffs`. Even if we will try to persist tiff using the following code:The output would look incorrect:
The original image:
This is caused by the way we compute
rowsPerStrip
: https://github.com/locationtech/geotrellis/blob/b9ca38cffc86fb846534a51436f71629ea2c37eb/raster/src/main/scala/geotrellis/raster/io/geotiff/StorageMethod.scala#L32-L43In this particular example with the
bilevel.tif
the result of this function computation would be8
(rowsPerStrip(rows, Bit) == 8
). If we'll force the output of this function to equal1
(1 row per strip:if(ris == 0) 1 else math.min(ris, 1)
) the result image would look correct, but there would still be issues with performing any operations on suchBitGeoTiffTile
:convert
,foreach
,map
, etc - it looks like the BitGeoTiff paddings logic works only for thetiled
case.The task is to fix
Striped
BitGeoTiffs
support. Also it may be the case, that we have a not fully working generalStriped
TIFFs support and it just worked because we usually never face a case when we had computedSegmentLayouts
with more than a single row per strip.As a reference related to why QGIS fails reads Striped BitTiffs created by GeoTrellis: mb there is smth in how we are setting RowsPerStrip TIFF Tag.
This guess was done that in this case GeoTiffReader reads tags as it has
72
rows per strip, butgdalinfo
andexiftool
read it as8
(8 is a correct number).An example of a
.convert(BitCellType)
stack trace using the unit test posted in the beginning of this post (segment layout is incorrect? or in case of a striped layout paddings should be calculated differently?):