Skip to content

Commit

Permalink
GTiff: make WEBP_LEVEL to be honored in Create() mode (fixes #1594)
Browse files Browse the repository at this point in the history
  • Loading branch information
rouault committed May 28, 2019
1 parent 98ae646 commit ba46395
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 48 deletions.
49 changes: 49 additions & 0 deletions autotest/gcore/tiff_write.py
Original file line number Diff line number Diff line change
Expand Up @@ -6985,6 +6985,55 @@ def test_tiff_write_no_gdal_metadata_tag_for_ycbcr_jpeg():
gdaltest.tiff_drv.Delete(tmpfile)
gdaltest.tiff_drv.Delete(tmpfile2)

###############################################################################
# Test that compression parameters are taken into account in Create() mode

def test_tiff_write_compression_create_and_createcopy():

md = gdaltest.tiff_drv.GetMetadata()
tests = []

if 'DEFLATE' in md['DMD_CREATIONOPTIONLIST']:
tests.append((['COMPRESS=DEFLATE', 'ZLEVEL=1'],['COMPRESS=DEFLATE', 'ZLEVEL=9']))

if 'LZMA' in md['DMD_CREATIONOPTIONLIST']:
tests.append((['COMPRESS=LZMA', 'LZMA_PRESET=1'],['COMPRESS=LZMA', 'LZMA_PRESET=9']))

if 'JPEG' in md['DMD_CREATIONOPTIONLIST']:
tests.append((['COMPRESS=JPEG', 'JPEG_QUALITY=95'],['COMPRESS=JPEG', 'JPEG_QUALITY=50']))

if 'ZSTD' in md['DMD_CREATIONOPTIONLIST']:
tests.append((['COMPRESS=ZSTD', 'ZSTD_LEVEL=1'],['COMPRESS=ZSTD', 'ZSTD_LEVEL=9']))

if 'LERC_DEFLATE' in md['DMD_CREATIONOPTIONLIST']:
tests.append((['COMPRESS=LERC_DEFLATE', 'ZLEVEL=1'],['COMPRESS=LERC_DEFLATE', 'ZLEVEL=9']))

if 'WEBP' in md['DMD_CREATIONOPTIONLIST']:
tests.append((['COMPRESS=WEBP', 'WEBP_LEVEL=95'],['COMPRESS=WEBP', 'WEBP_LEVEL=15']))

tmpfile = '/vsimem/test_tiff_write_compression_create.tif'

src_ds = gdal.Open('data/rgbsmall.tif')
data = src_ds.ReadRaster()
for (before, after) in tests:
ds = gdaltest.tiff_drv.Create(tmpfile, src_ds.RasterXSize, src_ds.RasterYSize, src_ds.RasterCount, options = before)
ds.WriteRaster(0, 0, src_ds.RasterXSize, src_ds.RasterYSize, data)
ds = None
size_before = gdal.VSIStatL(tmpfile).size
ds = gdaltest.tiff_drv.Create(tmpfile, src_ds.RasterXSize, src_ds.RasterYSize, src_ds.RasterCount, options = after)
ds.WriteRaster(0, 0, src_ds.RasterXSize, src_ds.RasterYSize, data)
ds = None
size_after = gdal.VSIStatL(tmpfile).size
assert size_after < size_before, (before, after, size_before, size_after)

gdaltest.tiff_drv.CreateCopy(tmpfile, src_ds, options = before)
size_before = gdal.VSIStatL(tmpfile).size
gdaltest.tiff_drv.CreateCopy(tmpfile, src_ds, options = after)
size_after = gdal.VSIStatL(tmpfile).size
assert size_after < size_before, (before, after, size_before, size_after)

gdaltest.tiff_drv.Delete(tmpfile)

###############################################################################
# Ask to run again tests with GDAL_API_PROXY=YES

Expand Down
66 changes: 18 additions & 48 deletions gdal/frmts/gtiff/geotiff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ class GTiffDataset final : public GDALPamDataset
bool bCrystalized;

void Crystalize(); // TODO: Spelling.
void RestoreVolatileParameters();

GDALColorTable *poColorTable;

Expand Down Expand Up @@ -8626,26 +8627,9 @@ void GTiffDataset::ThreadCompressionFunc( void* pData )
TIFFSetField(hTIFFTmp, TIFFTAG_COMPRESSION, poDS->nCompression);
if( psJob->nPredictor != PREDICTOR_NONE )
TIFFSetField(hTIFFTmp, TIFFTAG_PREDICTOR, psJob->nPredictor);
if( poDS->nZLevel >= 0 && (poDS->nCompression == COMPRESSION_ADOBE_DEFLATE ||
poDS->nCompression == COMPRESSION_LERC) )
TIFFSetField(hTIFFTmp, TIFFTAG_ZIPQUALITY, poDS->nZLevel);
if( poDS->nLZMAPreset > 0 && poDS->nCompression == COMPRESSION_LZMA)
TIFFSetField(hTIFFTmp, TIFFTAG_LZMAPRESET, poDS->nLZMAPreset);
if( poDS->nZSTDLevel > 0 && (poDS->nCompression == COMPRESSION_ZSTD ||
poDS->nCompression == COMPRESSION_LERC) )
TIFFSetField(hTIFFTmp, TIFFTAG_ZSTD_LEVEL, poDS->nZSTDLevel);
#if HAVE_LERC
if( poDS->nCompression == COMPRESSION_LERC )
{
TIFFSetField(hTIFFTmp, TIFFTAG_LERC_MAXZERROR, poDS->dfMaxZError);
TIFFSetField(hTIFFTmp, TIFFTAG_LERC_PARAMETERS, 2,
poDS->anLercAddCompressionAndVersion);
}
#endif
if( poDS->nWebPLevel > 0 && poDS->nCompression == COMPRESSION_WEBP)
TIFFSetField(hTIFFTmp, TIFFTAG_WEBP_LEVEL, poDS->nWebPLevel);
if( poDS->bWebPLossless && poDS->nCompression == COMPRESSION_WEBP)
TIFFSetField(hTIFFTmp, TIFFTAG_WEBP_LOSSLESS, 1);

poDS->RestoreVolatileParameters();

TIFFSetField(hTIFFTmp, TIFFTAG_PHOTOMETRIC, poDS->nPhotometric);
TIFFSetField(hTIFFTmp, TIFFTAG_SAMPLEFORMAT, poDS->nSampleFormat);
TIFFSetField(hTIFFTmp, TIFFTAG_SAMPLESPERPIXEL, poDS->nSamplesPerPixel);
Expand Down Expand Up @@ -9241,17 +9225,6 @@ void GTiffDataset::Crystalize()

TIFFWriteCheck( hTIFF, TIFFIsTiled(hTIFF), "GTiffDataset::Crystalize");

// Keep zip and tiff quality, and jpegcolormode which get reset when
// we call TIFFWriteDirectory.
int jquality = -1;
TIFFGetField(hTIFF, TIFFTAG_JPEGQUALITY, &jquality);
int zquality = -1;
TIFFGetField(hTIFF, TIFFTAG_ZIPQUALITY, &zquality);
int nColorMode = -1;
TIFFGetField( hTIFF, TIFFTAG_JPEGCOLORMODE, &nColorMode );
int nJpegTablesModeIn = -1;
TIFFGetField( hTIFF, TIFFTAG_JPEGTABLESMODE, &nJpegTablesModeIn );

TIFFWriteDirectory( hTIFF );
if( bStreamingOut )
{
Expand Down Expand Up @@ -9293,15 +9266,7 @@ void GTiffDataset::Crystalize()
TIFFSetDirectory( hTIFF, 0 );
}

// Now, reset zip and tiff quality and jpegcolormode.
if( jquality > 0 )
TIFFSetField(hTIFF, TIFFTAG_JPEGQUALITY, jquality);
if( zquality > 0 )
TIFFSetField(hTIFF, TIFFTAG_ZIPQUALITY, zquality);
if( nColorMode >= 0 )
TIFFSetField(hTIFF, TIFFTAG_JPEGCOLORMODE, nColorMode);
if( nJpegTablesModeIn >= 0 )
TIFFSetField(hTIFF, TIFFTAG_JPEGTABLESMODE, nJpegTablesModeIn);
RestoreVolatileParameters();

nDirOffset = TIFFCurrentDirOffset( hTIFF );
}
Expand Down Expand Up @@ -12017,17 +11982,22 @@ bool GTiffDataset::SetDirectory( toff_t nNewOffset )
if( !nSetDirResult )
return false;

RestoreVolatileParameters();

return true;
}

/************************************************************************/
/* RestoreVolatileParameters() */
/************************************************************************/

void GTiffDataset::RestoreVolatileParameters()
{
/* -------------------------------------------------------------------- */
/* YCbCr JPEG compressed images should be translated on the fly */
/* to RGB by libtiff/libjpeg unless specifically requested */
/* otherwise. */
/* -------------------------------------------------------------------- */
if( !TIFFGetField( hTIFF, TIFFTAG_COMPRESSION, &(nCompression) ) )
nCompression = COMPRESSION_NONE;

if( !TIFFGetField( hTIFF, TIFFTAG_PHOTOMETRIC, &(nPhotometric) ) )
nPhotometric = PHOTOMETRIC_MINISBLACK;

if( nCompression == COMPRESSION_JPEG
&& nPhotometric == PHOTOMETRIC_YCBCR
&& CPLTestBool( CPLGetConfigOption("CONVERT_YCBCR_TO_RGB",
Expand Down Expand Up @@ -12068,15 +12038,15 @@ bool GTiffDataset::SetDirectory( toff_t nNewOffset )
if( nCompression == COMPRESSION_LERC )
{
TIFFSetField(hTIFF, TIFFTAG_LERC_MAXZERROR, dfMaxZError);
TIFFSetField(hTIFF, TIFFTAG_LERC_PARAMETERS, 2,
anLercAddCompressionAndVersion);
}
#endif
if( nWebPLevel > 0 && nCompression == COMPRESSION_WEBP)
TIFFSetField(hTIFF, TIFFTAG_WEBP_LEVEL, nWebPLevel);
if( bWebPLossless && nCompression == COMPRESSION_WEBP)
TIFFSetField(hTIFF, TIFFTAG_WEBP_LOSSLESS, 1);
}

return true;
}

/************************************************************************/
Expand Down

0 comments on commit ba46395

Please sign in to comment.