Permalink
Browse files

ENVI: support reading truncated datasets (fixes #915)

  • Loading branch information...
rouault committed Sep 13, 2018
1 parent ced9bbb commit 2b17ddc8a01e1c14659d16df3185f140da1a6340
Showing with 34 additions and 3 deletions.
  1. +27 −1 autotest/gdrivers/envi.py
  2. +7 −2 gdal/frmts/raw/rawdataset.cpp
View
@@ -354,7 +354,7 @@ def envi_15():
gdal.GetDriverByName('ENVI').CreateCopy('/vsimem/envi_15.dat', src_ds)
ds = gdal.Open('data/rotation.img')
ds = gdal.Open('/vsimem/envi_15.dat')
got_gt = ds.GetGeoTransform()
if max([abs((got_gt[i] - expected_gt[i]) / expected_gt[i]) for i in range(6)]) > 1e-5:
gdaltest.post_reason('did not get expected geotransform')
@@ -365,6 +365,31 @@ def envi_15():
return 'success'
###############################################################################
# Test reading a truncated ENVI dataset (see #915)
def envi_truncated():
gdal.GetDriverByName('ENVI').CreateCopy('/vsimem/envi_truncated.dat',
gdal.Open('data/byte.tif'))
f = gdal.VSIFOpenL('/vsimem/envi_truncated.dat', 'wb+')
gdal.VSIFTruncateL(f, 20 * 20 / 2)
gdal.VSIFCloseL(f)
with gdaltest.config_option('RAW_CHECK_FILE_SIZE', 'YES'):
ds = gdal.Open('/vsimem/envi_truncated.dat')
cs = ds.GetRasterBand(1).Checksum()
ds = None
gdal.GetDriverByName('ENVI').Delete('/vsimem/envi_truncated.dat')
if cs != 2315:
print(cs)
return 'fail'
return 'success'
gdaltest_list = [
envi_1,
@@ -382,6 +407,7 @@ def envi_15():
envi_13,
envi_14,
envi_15,
envi_truncated,
]
@@ -325,7 +325,9 @@ CPLErr RawRasterBand::AccessLine( int iLine )
const size_t nBytesActuallyRead = Read(pLineBuffer, 1, nBytesToRead);
if( nBytesActuallyRead < nBytesToRead )
{
if (poDS != nullptr && poDS->GetAccess() == GA_ReadOnly)
if (poDS != nullptr && poDS->GetAccess() == GA_ReadOnly &&
// ENVI datasets might be sparse (see #915)
poDS->GetMetadata("ENVI") == nullptr)
{
CPLError(CE_Failure, CPLE_FileIO,
"Failed to read scanline %d.",
@@ -1253,7 +1255,10 @@ bool RAWDatasetCheckMemoryUsage(int nXSize, int nYSize, int nBands,
(nXSize-1) * static_cast<vsi_l_offset>(nPixelOffset);
CPL_IGNORE_RET_VAL( VSIFSeekL(fp, 0, SEEK_END) );
vsi_l_offset nFileSize = VSIFTellL(fp);
if( nFileSize < nExpectedFileSize )
// Do not strictly compare against nExpectedFileSize, but use an arbitrary
// 50% margin, since some raw formats such as ENVI
// allow for sparse files (see https://github.com/OSGeo/gdal/issues/915)
if( nFileSize < nExpectedFileSize / 2 )
{
CPLError(CE_Failure, CPLE_AppDefined, "Image file is too small");
return false;

0 comments on commit 2b17ddc

Please sign in to comment.