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

geotiff files with empty tiles or strips cannot be read #304

Open
otfried-cheong opened this issue May 23, 2022 · 3 comments · May be fixed by #305
Open

geotiff files with empty tiles or strips cannot be read #304

otfried-cheong opened this issue May 23, 2022 · 3 comments · May be fixed by #305

Comments

@otfried-cheong
Copy link

We regularly encounter geotiff files that geotiff.js cannot read (it throws an exception in readRasters).

After some debugging it turns out that the problem is that these images contain tiles or strips with zero bytes:

$ tiffinfo -s a-3006.tif 
TIFF Directory at offset 0xc02f6 (787190)
  Image Width: 1399 Image Length: 915
  Tile Width: 1024 Tile Length: 16
  Bits/Sample: 8
  Sample Format: unsigned integer
  Compression Scheme: AdobeDeflate
  Photometric Interpretation: RGB color
  Samples/Pixel: 3
  Planar Configuration: single image plane
  Predictor: none 1 (0x1)
  116 Tiles:
      0: [    1328,       73]
      1: [    1401,     3852]
...
    102: [  743780,     7319]
    103: [  751099,     1565]
    104: [  752664,     8413]
    105: [  761077,     1501]
    106: [  762578,     8437]
    107: [  771015,     2171]
    108: [  773186,     8007]
    109: [  781193,      756]
    110: [  781949,     3307]
    111: [       0,        0]
    112: [  785256,     1933]
    113: [       0,        0]
    114: [       0,        0]
    115: [       0,        0]

I'm not sure if this is actually legal according to the tiff spec, but there seems to be some commonly used software around that produces such files - it simply omits the tile when it only contains nodata.

I have fixed this for our use case by adding this:

     if (byteCount === 0) {                                                      
      const outSize = this.planarConfiguration === 2                            
      ? this.getBlockHeight(y) * this.getTileWidth()                            
      : this.getBlockHeight(y) * this.getTileWidth() * this.getSamplesPerPixel(\
);                                                                              
      const data = new ArrayBuffer(outSize);                                    
      const bytes = new Uint8Array(data);                                       
      bytes.fill(this.getGDALNoData());                                         
      return { x, y, sample, data};                                             
    }                                                                           

in geotiffimage.js getTileOrStrip just before the fetch. This isn't quite correct - the type of the buffer should be correct for the sample - but it works for the files I've tested with.

Unfortunately I don't have an example file that I can share (and haven't figured out how to produce one).

@constantinius
Copy link
Member

@otfried-cheong

Thanks for submitting this issue!

This is indeed a common practice, GDAL even has a documentation section about this.

This feature was simply not yet requested, and I never came around to actually implement it. The solution you propose looks not too bad to me, I would be happy to accept it as a PR, if you'd like to create one. Of course, we would need to come up with a proper way to test this, though.

@otfried-cheong
Copy link
Author

Thanks, that link explains a lot. Now I finally know how to create such files myself:

gdal_translate -of GTiff -co "SPARSE_OK=TRUE" -co "COMPRESS=DEFLATE" a.tif b.tif

I will prepare a PR with the patch and test cases.

@otfried otfried linked a pull request May 24, 2022 that will close this issue
@zoltan-mihalyi
Copy link

+1

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

Successfully merging a pull request may close this issue.

3 participants