For what is worth, I've tried Nalini's test code on Linux 64 bit and it works fine for the LZW compression with libtiff master. Not sure if it would be a Windows or 32-bit specific issue.

The fact that rows_per_strip = 1 when reading the uncompressed image is that libtiff has a strip chopping logic enabled by default (unless you pass the "c" flag in the TIFFOpen() flags) that make libtiff expose a single-strip uncompressed file as having rows_per_strip = 1, to avoid readers that use the TIFFReadEncodedStrip() API to have to allocate undecent amount of memory

Even

Le 08/12/2021 à 15:59, [email protected] a écrit :

Hi Nalini,

You are attempting to write a single strip of ca 2.5 G pixels. This is not a wise thing to do. Most probably there is some 32-bit counter somewhere which cannot cope with such sizes, probably in the LZW compression routines.

For such large files one should use the tiled format and write e.g. 512x512 pixel tiles. This enables the reader to “zoom in” into the image by reading only a few tiles. This is widely used in “pyramidal” TIFF files of various kinds.

Another option would be to just write smaller strips, but for such large images the tiles would be the right approach.

HTH

Paavo

*From:* Tiff <[email protected]> *On Behalf Of *Nalini Vishnoi
*Sent:* kolmapäev, 8. detsember 2021 05:38
*To:* [email protected]
*Subject:* [Tiff] Windows - difference in behavior when large RowsPerStrip is specified while writing Uncompressed vs LZW compressed TIFF file

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>

#defineFILENAME"mytest.tif"

intmain()

{

TIFF* tif = TIFFOpen(FILENAME, "w");

std::vector<uint16_t> v(1,0);

tsize_trowsPerStrip=0, stripSize;

int64status = -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_tnumBytes = tsize_t(25000)*25000*4;

stripSize = TIFFStripSize(tif);

std::cout<<"\nSize of strip = "<<stripSize;

std::vector<uint8_t> writeBuffer(stripSize, 10);

tstrip_tnumStrips = TIFFNumberOfStrips(tif);

std::cout <<"\nNumStrips = "<<numStrips;

tdata_tbuffer = 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);

}


_______________________________________________
Tiff mailing list
[email protected]
https://lists.osgeo.org/mailman/listinfo/tiff

--
http://www.spatialys.com
My software is free, but my time generally not.

_______________________________________________
Tiff mailing list
[email protected]
https://lists.osgeo.org/mailman/listinfo/tiff

Reply via email to