| AWARE [SYSTEMS] | Imaging expertise for the Delphi developer | |||||||
![]() |
TIFF and LibTiff Mailing List Archive | |||||||
LibTiff Mailing List
TIFF and LibTiff Mailing List Archive Contact
The TIFF Mailing List Homepage |
2008.11.24 19:40 "TIFFWriteScanline corrupts buffer when compression with predication is enabled", by William B ThompsonAs best as I can tell, TIFFWriteScanline corrupts the input buffer in
the calling program with LZW and deflate (zip) compression when
horizontal prediction is enabled for integer values or floating point
prediction is enable for floating point values. This occurs with both
libtiff 3.8.2 and 4.0.0beta2. A test program for the 8 bit integer case
is included at the end of this message.
The declaration of TIFFWriteScanline does not include the "const"
qualifier for the buffer argument, so modifying values in the buffer is
not, strictly speaking, in violation of the specification. It seems to
me, however, that it is bad practice. It is certainly bad practice when
not described in the man page for TIFFWriteScanline.
One might argue that it is rare to rewrite or otherwise reuse an output
buffer that has just been written to a file. I can testify from
personal experience that it might be rare, but it does occur (and is a
pain to track down when it happens).
- Bill
/*
* Run with and without -p flag.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <tiffio.h>
#define OUTPUT_NAME "libtiff-prediction-test.tif"
int
main ( int argc, char *argv[] )
{
TIFF *output;
uint8 *output_buffer;
int i;
int prediction_flag = 0;
if ( ( argc == 2 ) && ( strcmp ( argv[1], "-p" ) == 0 ) ) {
prediction_flag = 1;
}
output_buffer = (uint8 *) _TIFFmalloc ( 10 * sizeof ( uint8 ) );
for ( i = 0; i < 10; i++ ) {
output_buffer[i] = 10;
}
output = TIFFOpen ( OUTPUT_NAME , "w" );
TIFFSetField ( output, TIFFTAG_IMAGEWIDTH, 10 );
TIFFSetField ( output, TIFFTAG_IMAGELENGTH, 1 );
TIFFSetField ( output, TIFFTAG_BITSPERSAMPLE, 8 );
TIFFSetField ( output, TIFFTAG_SAMPLESPERPIXEL, 1 );
TIFFSetField ( output, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
if ( prediction_flag ) {
printf ( "using horizontal prediction\n" );
TIFFSetField ( output, TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL );
} else {
printf ( "not using horizontal prediction\n" );
}
TIFFSetField ( output, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField ( output, TIFFTAG_ROWSPERSTRIP,
TIFFDefaultStripSize ( output, 0 ) );
TIFFSetField ( output, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
TIFFSetField ( output, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK );
printf ( "output buffer before call to TIFFWriteScanline:\n" );
for ( i = 0; i < 10; i++ ) {
printf ( "%4d", output_buffer[i] );
}
printf ( "\n" );
TIFFWriteScanline ( output, output_buffer, 0, 0 );
printf ( "output buffer after call to TIFFWriteScanline:\n" );
for ( i = 0; i < 10; i++ ) {
printf ( "%4d", output_buffer[i] );
}
printf ( "\n" );
TIFFClose ( output );
return ( EXIT_SUCCESS ); /* normal exit */
}
|
|||||||