MissingRequired:TIFF directory is missing required "StripOffsets" field


maphew@...
 

Hi Folks,

I'm new to Rasterio. Is the StripOffsets error I'm getting a result of something I'm doing wrong or have I stumbled into a bug? (Sources attached)

'''Goal: merge the Red, Green, Blue and Near-infrared channels from two images
into a single RGB-Nir image, without modifying any pixel values.'''

import rasterio
ds_rgb = rasterio.open('rgb.tif') # Red, Green, Blue natural colour image
ds_bgn = rasterio.open('bgn.tif') # Near-infrared, Green, Blue false colour
 
R,G,B = ds_rgb.read(1), ds_rgb.read(2), ds_rgb.read(3)
NI = ds_bgn.read(1) # Near-infrared band from 2nd file
 
# Read metadata (to get extents, px dimensions, etc.)
profile = ds_rgb.profile
 
# Update to reflect the new number of layers
profile.update(count = 4)
 
# avoid PHOTOMETRIC=YCBCR not supported on a 4-band raster: only compatible of a 3-band (RGB) raster
if profile['photometric'].lower() == 'ycbcr':
   profile.pop('photometric')
 
# Read each layer and write them out to single file
with rasterio.open('rgb-nir.tif', 'w', **profile) as dst:
   dst.write_band(1, R)
   dst.write_band(2, G)
   dst.write_band(3, B)
   dst.write_band(4, NI)

Result:

Traceback (most recent call last):

File "T:\ENV.558\scratch\merge-rgb-nir\merge-rgb-nir.py", line 28, in <module>

with rasterio.open('rgb-nir.tif', 'w', **profile) as dst:

File "C:\apps\conda\envs\geo\lib\site-packages\rasterio\env.py", line 437, in wrapper

return f(*args, **kwds)

File "C:\apps\conda\envs\geo\lib\site-packages\rasterio\__init__.py", line 230, in open

s = writer(path, mode, driver=driver,

File "rasterio\_io.pyx", line 1122, in rasterio._io.DatasetWriterBase.__init__

File "rasterio\_io.pyx", line 70, in rasterio._io._delete_dataset_if_exists

File "rasterio\_shim.pyx", line 78, in rasterio._shim.open_dataset

File "rasterio\_err.pyx", line 216, in rasterio._err.exc_wrap_pointer

rasterio._err.CPLE_AppDefinedError: rgb-nir.tif: MissingRequired:TIFF directory is missing required "StripOffsets" field



If I use `meta` instead of `profile` the script runs successfully, but the output is many times larger than the sources because it's no longer compressed. I'm trying to avoid defining a new profile because the existing compression is jpeg and I don't to stack a lossy encoding on top of a lossy encoding. I'm hoping to copy the existing bands as-is, and just change their arrangement.

Thanks in advance for any insight you can provide.

--
-matt


Luke
 

Your code runs fine for me Matt. Update your rasterio version?  

I'm running:
$ rio --version
1.2.10
$ gdalinfo --version
GDAL 3.4.0, released 2021/11/04

You should note that by re-writing the file, you will be re-compressing (i.e. stacking a lossy encoding on top of a lossy encoding).  You can confirm that with something like:

import numpy as np
import rasterio

with rasterio.open('rgb.tif') as ds_rgb:
profile = ds_rgb.profile.copy()
rgb1 = ds_rgb.read()

with rasterio.open('rgb2.tif', 'w', **profile) as dst:
dst.write(rgb1)

with rasterio.open('rgb2.tif') as ds_rgb:
rgb2 = ds_rgb.read()

print(np.array_equal(rgb1, rgb2))

False



maphew@...
 

Thanks for looking Luke.

I have same rasterio and a newer gdal. Both installed with conda.

$ rio --version
1.2.10
$ gdalinfo --version
GDAL 3.4.1, released 2021/12/27

I definitely do not want to re-encode. Is there another approach I should be using?

--
-matt


Luke
 

Sorry Matt, I don't know. Even Rouault wrote a bit about the issue a number of years ago, but the re-writing without re-compressing was left in the "Ideas for later..." section.


maphew@...
 

Curious. I downgraded to Gdal 3.4.0 and still get the same error.

```
(geo)  T:\ENV.558\scratch\merge-rgb-nir
$ python merge-rgb-nir.py
Traceback (most recent call last):
  File "T:\ENV.558\scratch\merge-rgb-nir\merge-rgb-nir.py", line 26, in <module>
    with rasterio.open('rgb-nir.tif', 'w', **profile) as dst:
  File "C:\apps\conda\envs\geo\lib\site-packages\rasterio\env.py", line 437, in wrapper
    return f(*args, **kwds)
  File "C:\apps\conda\envs\geo\lib\site-packages\rasterio\__init__.py", line 230, in open
    s = writer(path, mode, driver=driver,
  File "rasterio\_io.pyx", line 1122, in rasterio._io.DatasetWriterBase.__init__
  File "rasterio\_io.pyx", line 70, in rasterio._io._delete_dataset_if_exists
  File "rasterio\_shim.pyx", line 78, in rasterio._shim.open_dataset
  File "rasterio\_err.pyx", line 216, in rasterio._err.exc_wrap_pointer
rasterio._err.CPLE_AppDefinedError: rgb-nir.tif: MissingRequired:TIFF directory is missing required "StripOffsets" field

(geo) T:\ENV.558\scratch\merge-rgb-nir
$ gdalinfo --version
GDAL 3.4.0, released 2021/11/04

(geo) T:\ENV.558\scratch\merge-rgb-nir
$ rio --version
1.2.10
```
--
-matt


Luke
 

I just tried on Windows and Linux and your code ran fine for me (using the test data you attached). The only other thing I can think of is I'm running rasterio/gdal installed from the conda-forge repo not the conda defaults repo...?