Opened 15 years ago

Last modified 15 years ago

#1098 closed defect (fixed)

Odd ECW Resampling Problems

Reported by: warmerdam Owned by: warmerdam
Priority: high Milestone:
Component: GDAL_Raster Version: unspecified
Severity: normal Keywords:
Cc: frankie@…


SetView() is being used to downsample a file but seems to be producing 
results that are wrong by several scanlines in some cases.  In particular
a SetView with an output buffer that is 800x616 is producing very different
output than with an output buffer that is 800x615.  

When run against the test image, the following produces two .pgm files 
that show a substantial difference in output (look in 616 file to see
a substantial chunk at bottom is cut off).  I will attach the output
files converted to png to this bug report.  I can provide access to the
file if needed to reproduce the problem. 

#include <stdio.h>
#include <NCSECWClient.h>
#include <NCSECWCompressClient.h>
#include <NCSErrors.h>
#include <NCSFile.h>
#include <NCSJP2File.h>
#include <NCSJP2FileView.h>

int do_extract( int nXOutSize, int nYOutSize )

    CNCSJP2FileView *poFileView;
    CNCSError oErr;
    UINT32 iBand = 0;
/* -------------------------------------------------------------------- */
/*      Open file.                                                      */
/* -------------------------------------------------------------------- */
    poFileView = new CNCSFile();
    oErr = poFileView->Open( (char *) "mosaico_invernale_321.ecw", FALSE );

/* -------------------------------------------------------------------- */
/*      Set view, downsampling the whole image substantially.           */
/* -------------------------------------------------------------------- */
    poFileView->SetView( 1, &iBand, 0, 0, 10185, 7833, nXOutSize, nYOutSize );

/* -------------------------------------------------------------------- */
/*      Create output pgm file.                                         */
/* -------------------------------------------------------------------- */
    FILE *fpOut;
    char szFilename[1000];
    char szHeader[1000];

    sprintf( szFilename, "out_%dx%d.pgm", nXOutSize, nYOutSize );
    fpOut = fopen( szFilename, "wb" );

    sprintf( szHeader, "P5\n%d %d\n%d\n", nXOutSize, nYOutSize, 255 );
    fwrite( szHeader, strlen(szHeader) + 1, 1, fpOut );

/* -------------------------------------------------------------------- */
/*      Read and write file line by line.                               */
/* -------------------------------------------------------------------- */
    int iLine;
    unsigned char *pabySrcBuf = (unsigned char *) malloc(nXOutSize);

    for( iLine = 0; iLine < nYOutSize; iLine++ )
        poFileView->ReadLineBIL( NCSCT_UINT8, 1, (void **) &pabySrcBuf );
        fwrite( pabySrcBuf, nXOutSize, 1, fpOut );

    fclose( fpOut );
    delete poFileView;

int main()


    do_extract( 800, 616 );
    do_extract( 800, 615 );


Attachments (2)

out_800x615.png (142.5 KB) - added by warmerdam 15 years ago.
OK file.
out_800x616.png (142.7 KB) - added by warmerdam 15 years ago.
Improperly resampled file.

Download all attachments as: .zip

Change History (5)

Changed 15 years ago by warmerdam

Attachment: out_800x615.png added

OK file.

Changed 15 years ago by warmerdam

Attachment: out_800x616.png added

Improperly resampled file.

comment:1 Changed 15 years ago by warmerdam

Note, this was ECW SDK 3.3R2 on Linux.

Problem reported to Tom Lynch at ERMapper.

comment:2 Changed 15 years ago by tflynch@…

Turned out to be a gcc optimisation bug in the function
erw_decompress_read_region_line_bil.  The fix was a workaround to "solidify" the
calculation of a floating point value.

The empty function void gcc_optimisation_workaround(IEEE8 value) was added near
the end of this function and the related function erw_decompress_read_region_line.

I'm unaware of a more "elegant" fix at this point however if function-level
optimisation directives become available in a future gcc that would probably be it.

comment:3 Changed 15 years ago by warmerdam


Yikes!  Thanks for the heavy duty digging.
Note: See TracTickets for help on using tickets.