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