2021.12.08 03:38 "[Tiff] Windows - difference in behavior when large RowsPerStrip is specified while writing Uncompressed vs LZW compressed TIFF file", by Nalini Vishnoi

2021.12.08 03:38 "[Tiff] Windows - difference in behavior when large RowsPerStrip is specified while writing Uncompressed vs LZW compressed TIFF file", by Nalini Vishnoi

Hello everyone,

I am writing to understand a behavior I observed on Windows with libTIFF. I am using libTIFF 4.2.0.

I write a TIFF file with RowsPerStrip=25000 using two different ways:

  1. Uncompressed
  2. Using LZW compression.

When the file is written without any compression, RowsPerStrip is automatically changed to 1 from 25000 while writing the file. See the output of the code added below (in case of writing uncompressed file):

Status after setting rowsPerStrip = 1
Status after reading rowsPerStrip = 1
Rows per strip = 25000
Size of strip = 2500000000
NumStrips = 1
Status after writing the file = 2500000000

NumStrips = 25000
Size of strip = 100000
Rows per strip = 1
Status after reading the image = 100000

However, when I use LZW compression, the written file become corrupted:

Status after setting rowsPerStrip = 1
Status after reading rowsPerStrip = 1
Rows per strip = 25000
Size of strip = 2500000000
NumStrips = 1
Status after writing the file = 2500000000

NumStrips = 1
Size of strip = 2500000000
Rows per strip = 25000
Status after reading the image = -1

Are these results expected (RowsPerStrip automatically changing its value AND the file getting corrupted with LZW compression)? Please let me know if I any additional information is needed.

I look forward to your reply.

Thanks,
Nalini

Here is my code:

#include<stdlib.h>
#include<tiffio.h>
#include<tiff.h>
#include<iostream>
#include<vector>
#define FILENAME "mytest.tif"


int main()
{
TIFF* tif = TIFFOpen(FILENAME, "w");
std::vector<uint16_t> v(1,0);
tsize_t rowsPerStrip=0, stripSize;
int64 status = -10;

TIFFSetField(tif,TIFFTAG_PHOTOMETRIC, 2);
TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE, 8);
TIFFSetField(tif,TIFFTAG_IMAGELENGTH, 25000);
TIFFSetField(tif,TIFFTAG_IMAGEWIDTH, 25000);
TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL, 4);
TIFFSetField(tif,TIFFTAG_PLANARCONFIG, 1);
status = TIFFSetField(tif,TIFFTAG_ROWSPERSTRIP, uint32_t(25000));
std::cout << "\nStatus after setting rowsPerStrip = "<< status ;
status = TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP, &rowsPerStrip);
std::cout << "\nStatus after reading rowsPerStrip = "<< status ;
std::cout<<"\nRows per strip = "<< rowsPerStrip;

// LZW compression
// TIFFSetField(tif,TIFFTAG_COMPRESSION, 5);
TIFFSetField(tif,TIFFTAG_EXTRASAMPLES, v.size(), &v[0]);
tsize_t numBytes = tsize_t(25000)*25000*4;
stripSize = TIFFStripSize(tif);
std::cout<<"\nSize of strip = "<<stripSize;
std::vector<uint8_t> writeBuffer(stripSize, 10);
tstrip_t numStrips = TIFFNumberOfStrips(tif);
std::cout << "\nNumStrips = " << numStrips;
tdata_t buffer = static_cast<tdata_t>(&writeBuffer[0]);

status = TIFFWriteEncodedStrip(tif, 0, buffer, numBytes );
std::cout << "\nStatus after writing the file = "<< status <<'\n';
TIFFClose(tif);

tif = TIFFOpen(FILENAME, "r");
numStrips = TIFFNumberOfStrips(tif);
std::cout<< "\nNumStrips = "<<numStrips;
stripSize = TIFFStripSize(tif);
std::cout<<"\nSize of strip = "<<stripSize;
TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP, &rowsPerStrip);
std::cout<<"\nRows per strip = "<<rowsPerStrip;

status = TIFFReadEncodedStrip(tif, 0, &writeBuffer[0], -1);
std::cout<<"\nStatus after reading the image = "<<status<<'\n';
TIFFClose(tif);

}