CPLErr USGSDEMRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff, CPL_UNUSED int nBlockYOff, void * pImage ) { /* int bad = FALSE; */ USGSDEMDataset *poGDS = reinterpret_cast<USGSDEMDataset *>( poDS ); /* -------------------------------------------------------------------- */ /* Initialize image buffer to nodata value. */ /* -------------------------------------------------------------------- */ for( int k = GetXSize() * GetYSize() - 1; k >= 0; k-- ) { if( GetRasterDataType() == GDT_Int16 ) reinterpret_cast<GInt16 *>( pImage )[k] = USGSDEM_NODATA; else reinterpret_cast<float *>( pImage )[k] = USGSDEM_NODATA; } /* -------------------------------------------------------------------- */ /* Seek to data. */ /* -------------------------------------------------------------------- */ CPL_IGNORE_RET_VAL(VSIFSeekL(poGDS->fp, poGDS->nDataStartOffset, 0)); double dfYMin = poGDS->adfGeoTransform[3] + (GetYSize()-0.5) * poGDS->adfGeoTransform[5]; /* -------------------------------------------------------------------- */ /* Read all the profiles into the image buffer. */ /* -------------------------------------------------------------------- */ Buffer sBuffer; sBuffer.max_size = 32768; sBuffer.buffer = reinterpret_cast<char *>( CPLMalloc( sBuffer.max_size + 1 ) ); sBuffer.fp = poGDS->fp; sBuffer.buffer_size = 0; sBuffer.cur_index = 0; for( int i = 0; i < GetXSize(); i++) { int bSuccess; const int nRowNumber = USGSDEMReadIntFromBuffer(&sBuffer, &bSuccess); if( nRowNumber != 1 ) CPLDebug("USGSDEM", "i = %d, nRowNumber = %d", i, nRowNumber); if( bSuccess ) { const int nColNumber = USGSDEMReadIntFromBuffer(&sBuffer, &bSuccess); if( nColNumber != i + 1 ) { CPLDebug("USGSDEM", "i = %d, nColNumber = %d", i, nColNumber); } } const int nCPoints = (bSuccess) ? USGSDEMReadIntFromBuffer(&sBuffer, &bSuccess) : 0; #ifdef DEBUG_VERBOSE CPLDebug("USGSDEM", "i = %d, nCPoints = %d", i, nCPoints); #endif if( bSuccess ) { const int nNumberOfCols = USGSDEMReadIntFromBuffer(&sBuffer, &bSuccess); if( nNumberOfCols != 1 ) { CPLDebug("USGSDEM", "i = %d, nNumberOfCols = %d", i, nNumberOfCols); } } // x-start if( bSuccess ) /* dxStart = */ USGSDEMReadDoubleFromBuffer(&sBuffer, 24, &bSuccess); double dyStart = (bSuccess) ? USGSDEMReadDoubleFromBuffer(&sBuffer, 24, &bSuccess) : 0; const double dfElevOffset = (bSuccess) ? USGSDEMReadDoubleFromBuffer(&sBuffer, 24, &bSuccess) : 0; // min z value if( bSuccess ) /* djunk = */ USGSDEMReadDoubleFromBuffer(&sBuffer, 24, &bSuccess); // max z value if( bSuccess ) /* djunk = */ USGSDEMReadDoubleFromBuffer(&sBuffer, 24, &bSuccess); if( !bSuccess ) { CPLFree(sBuffer.buffer); return CE_Failure; } if( STARTS_WITH_CI(poGDS->pszProjection, "GEOGCS") ) dyStart = dyStart / 3600.0; double dygap = (dfYMin - dyStart)/poGDS->adfGeoTransform[5]+ 0.5; if( dygap <= INT_MIN || dygap >= INT_MAX || !CPLIsFinite(dygap) ) { CPLFree(sBuffer.buffer); return CE_Failure; } int lygap = static_cast<int>(dygap); if( nCPoints <= 0 ) continue; if( lygap > INT_MAX - nCPoints ) lygap = INT_MAX - nCPoints; for (int j=lygap; j < (nCPoints + lygap); j++) { const int iY = GetYSize() - j - 1; const int nElev = USGSDEMReadIntFromBuffer(&sBuffer, &bSuccess); #ifdef DEBUG_VERBOSE CPLDebug("USGSDEM", " j - lygap = %d, nElev = %d", j - lygap, nElev); #endif if( !bSuccess ) { CPLFree(sBuffer.buffer); return CE_Failure; } if (iY < 0 || iY >= GetYSize() ) { /* bad = TRUE; */ } else if( nElev == USGSDEM_NODATA ) /* leave in output buffer as nodata */; else { const float fComputedElev = static_cast<float>(nElev * poGDS->fVRes + dfElevOffset); if( GetRasterDataType() == GDT_Int16 ) { GUInt16 nVal = ( fComputedElev < -32768 ) ? -32768 : ( fComputedElev > 32767 ) ? 32767 : static_cast<GInt16>( fComputedElev ); reinterpret_cast<GInt16 *>( pImage )[i + iY*GetXSize()] = nVal; } else { reinterpret_cast<float *>( pImage )[i + iY*GetXSize()] = fComputedElev; } } } if( poGDS->nDataStartOffset == 1024 ) { // Seek to the next 1024 byte boundary. // Some files have 'junk' profile values after the valid/declared ones vsi_l_offset nCurPos = USGSDEMGetCurrentFilePos(&sBuffer); vsi_l_offset nNewPos = (nCurPos + 1023) / 1024 * 1024; if( nNewPos > nCurPos ) { USGSDEMSetCurrentFilePos(&sBuffer, nNewPos); } } } CPLFree(sBuffer.buffer); return CE_None; }
CPLErr USGSDEMRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff, CPL_UNUSED int nBlockYOff, void * pImage ) { double dfYMin; /* int bad = FALSE; */ USGSDEMDataset *poGDS = (USGSDEMDataset *) poDS; /* -------------------------------------------------------------------- */ /* Initialize image buffer to nodata value. */ /* -------------------------------------------------------------------- */ for( int k = GetXSize() * GetYSize() - 1; k >= 0; k-- ) { if( GetRasterDataType() == GDT_Int16 ) ((GInt16 *) pImage)[k] = USGSDEM_NODATA; else ((float *) pImage)[k] = USGSDEM_NODATA; } /* -------------------------------------------------------------------- */ /* Seek to data. */ /* -------------------------------------------------------------------- */ VSIFSeekL(poGDS->fp, poGDS->nDataStartOffset, 0); dfYMin = poGDS->adfGeoTransform[3] + (GetYSize()-0.5) * poGDS->adfGeoTransform[5]; /* -------------------------------------------------------------------- */ /* Read all the profiles into the image buffer. */ /* -------------------------------------------------------------------- */ Buffer sBuffer; sBuffer.max_size = 32768; sBuffer.buffer = (char*) CPLMalloc(sBuffer.max_size + 1); sBuffer.fp = poGDS->fp; sBuffer.buffer_size = 0; sBuffer.cur_index = 0; for( int i = 0; i < GetXSize(); i++) { int /* njunk, */ nCPoints, lygap; double /* djunk, dxStart, */ dyStart, dfElevOffset; /* njunk = */ USGSDEMReadIntFromBuffer(&sBuffer); /* njunk = */ USGSDEMReadIntFromBuffer(&sBuffer); nCPoints = USGSDEMReadIntFromBuffer(&sBuffer); /* njunk = */ USGSDEMReadIntFromBuffer(&sBuffer); /* dxStart = */ USGSDEMReadDoubleFromBuffer(&sBuffer, 24); dyStart = USGSDEMReadDoubleFromBuffer(&sBuffer, 24); dfElevOffset = USGSDEMReadDoubleFromBuffer(&sBuffer, 24); /* djunk = */ USGSDEMReadDoubleFromBuffer(&sBuffer, 24); /* djunk = */ USGSDEMReadDoubleFromBuffer(&sBuffer, 24); if( EQUALN(poGDS->pszProjection,"GEOGCS",6) ) dyStart = dyStart / 3600.0; lygap = (int)((dfYMin - dyStart)/poGDS->adfGeoTransform[5]+ 0.5); for (int j=lygap; j < (nCPoints+(int)lygap); j++) { int iY = GetYSize() - j - 1; int nElev; int bSuccess; nElev = USGSDEMReadIntFromBuffer(&sBuffer, &bSuccess); if( !bSuccess ) { CPLFree(sBuffer.buffer); return CE_Failure; } if (iY < 0 || iY >= GetYSize() ) { /* bad = TRUE; */ } else if( nElev == USGSDEM_NODATA ) /* leave in output buffer as nodata */; else { float fComputedElev = (float)(nElev * poGDS->fVRes + dfElevOffset); if( GetRasterDataType() == GDT_Int16 ) { ((GInt16 *) pImage)[i + iY*GetXSize()] = (GInt16) fComputedElev; } else { ((float *) pImage)[i + iY*GetXSize()] = fComputedElev; } } } } CPLFree(sBuffer.buffer); return CE_None; }