Opened 17 years ago

Closed 17 years ago

#1738 closed defect (fixed)

Just Generated Pixel Interleaved TIFF Overviews Appear as Zeros

Reported by: warmerdam Owned by: warmerdam
Priority: normal Milestone: 1.4.3
Component: GDAL_Raster Version: svn-trunk
Severity: normal Keywords: geotiff overview
Cc:

Description

When internal overviews are built in a GeoTIFF file that is pixel interleaved, the overviews appear to be all zero valued. The same is not true of a band interleaved file. If the dataset is closed and reopened the imagery is fine. Tracking it down, IsBlockAvailable() is returning FALSE when it presumably should be TRUE, but I'm not sure why. The problem can be demonstrated with this program and the attached file.

#include "gdal_priv.h"

int main()

{
    GDALDataset *poDS;

    GDALAllRegister();

    system( "cp mfloat_base.tif mfloat32.tif" );
    poDS = (GDALDataset *) GDALOpen( "mfloat32.tif", GA_Update );

    int anOverviews[2] = { 2, 4 };					
    GDALRasterBand *poOver;

    poDS->BuildOverviews( "NEAREST", 2, anOverviews, 0, NULL, 
                          GDALDummyProgress, NULL );
    
    poOver = poDS->GetRasterBand(3)->GetOverview(0);

    double dfMax;
    poOver->ComputeStatistics( FALSE, NULL, &dfMax, NULL, NULL, 
                               NULL, NULL );

    printf( "Max = %g\n", dfMax );

    delete poDS;
}

Attachments (2)

mfloat_base.tif (5.1 KB ) - added by warmerdam 17 years ago.
input file for example program.
gdal_svn_bug1738.patch (1021 bytes ) - added by Even Rouault 17 years ago.

Download all attachments as: .zip

Change History (6)

by warmerdam, 17 years ago

Attachment: mfloat_base.tif added

input file for example program.

comment:1 by warmerdam, 17 years ago

Temporarily forced gdalautotest/gcore/tiff_ovr.py (tiff_ovr_1) test to use interleave=band to work around this in test suite (r11891). Please remove this setting when bug fixed.

comment:2 by warmerdam, 17 years ago

This may be related to #1758.

comment:3 by Even Rouault, 17 years ago

I think I've understood what happens here. I've simplified a bit your test case to reduce to just 1 overview and 2 bands. The following analysis is based on this simplified test case.

When generating the overview, there are finally 2 calls to GTiffRasterBand::IWriteBlock (one for each band). In the pixel interleaved case (for optimization purpose apparently ?), a block is not written right away. Instead the flag poGDS->bLoadedBlockDirty = TRUE; is set. If one writes to another block, the method GTiffDataset::LoadBlockBuf will flush the previous block on the disk through the call to GTiffDataSet::FlushBlockBuf (it will also be flushed if GTiffDataset::FlushCache is called). Here, none of those 2 cases happen. When computing the stat, we issue a call to GTiffRasterBand::IReadBlock and this method supposes that the data is flushed... which is not the case. Bang ! That accounts for IsBlockAvailable returning 0.

My proposal for the fix is to have an explicit call to poGDS->FlushBlockBuf() just after the call to poGDS->SetDirectory() at the beginning of GTiffRasterBand::IReadBlock, GTiffRGBABand::IReadBlock, GTiffBitmapBand::IReadBlock and GTiffOddBitsBand::IReadBlock, so that previously cached writes are flushed before reading. See attached patch.

The fix works for this test case and IMHO shouldn't cause much harm for other cases.

The bad news is that it doesn't improve resolution of bug #1758.

by Even Rouault, 17 years ago

Attachment: gdal_svn_bug1738.patch added

comment:4 by warmerdam, 17 years ago

Milestone: 1.5.01.4.3
Resolution: fixed
Status: newclosed

Even,

Bingo! You are exactly right. I patched it slightly different, modifying SetDirectory() to flush a loaded block before changing directory and some other steps to avoid recursion but roughly the same change.

Patched in trunk (r11999), 1.4 (r12001).

I also restored tiff_ovr.py to check for this issue (r12000).

Note: See TracTickets for help on using tickets.