CPLErr GFFRasterBand::IReadBlock( int /* nBlockXOff */ , int nBlockYOff, void *pImage ) { GFFDataset *poGDS = (GFFDataset *)poDS; long nOffset = poGDS->nLength; VSIFSeekL(poGDS->fp, nOffset + (poGDS->GetRasterXSize() * nBlockYOff * (nSampleSize)),SEEK_SET); /* Ingest entire range line */ if (VSIFReadL(pImage,nRasterBandMemory,1,poGDS->fp) != 1) return CE_Failure; #if defined(CPL_MSB) if( GDALDataTypeIsComplex( eDataType ) ) { int nWordSize = GDALGetDataTypeSize(eDataType)/16; GDALSwapWords( pImage, nWordSize, nBlockXSize, 2*nWordSize ); GDALSwapWords( ((GByte *) pImage)+nWordSize, nWordSize, nBlockXSize, 2*nWordSize ); } #endif return CE_None; }
CPLErr NGSGEOIDRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage ) { NGSGEOIDDataset *poGDS = (NGSGEOIDDataset *) poDS; /* First values in the file corresponds to the south-most line of the imagery */ VSIFSeekL(poGDS->fp, HEADER_SIZE + (nRasterYSize - 1 - nBlockYOff) * nRasterXSize * 4, SEEK_SET); if ((int)VSIFReadL(pImage, 4, nRasterXSize, poGDS->fp) != nRasterXSize) return CE_Failure; if (poGDS->bIsLittleEndian) { #ifdef CPL_MSB GDALSwapWords( pImage, 4, nRasterXSize, 4 ); #endif } else { #ifdef CPL_LSB GDALSwapWords( pImage, 4, nRasterXSize, 4 ); #endif } return CE_None; }
CPLErr PALSARJaxaRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void *pImage ) { int nNumBytes = 0; if (nFileType == level_11) { nNumBytes = 8; } else { nNumBytes = 2; } int nOffset = IMAGE_OPT_DESC_LENGTH + ((nBlockYOff - 1) * nRecordSize) + (nFileType == level_11 ? SIG_DAT_REC_OFFSET : PROC_DAT_REC_OFFSET); VSIFSeekL( fp, nOffset, SEEK_SET ); VSIFReadL( pImage, nNumBytes, nRasterXSize, fp ); #ifdef CPL_LSB if (nFileType == level_11) GDALSwapWords( pImage, 4, nBlockXSize * 2, 4 ); else GDALSwapWords( pImage, 2, nBlockXSize, 2 ); #endif return CE_None; }
CPLErr IntergraphRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void *pImage ) { // -------------------------------------------------------------------- // Load Block Buffer // -------------------------------------------------------------------- if (HandleUninstantiatedTile( nBlockXOff, nBlockYOff, pImage )) return CE_None; uint32 nBytesRead = LoadBlockBuf( nBlockXOff, nBlockYOff, nBlockBufSize, pabyBlockBuf ); if( nBytesRead == 0 ) { memset( pImage, 0, nBlockXSize * nBlockYSize * GDALGetDataTypeSize( eDataType ) / 8 ); CPLError( CE_Failure, CPLE_FileIO, "Can't read (%s) tile with X offset %d and Y offset %d.\n", ((IntergraphDataset*)poDS)->pszFilename, nBlockXOff, nBlockYOff ); return CE_Failure; } // -------------------------------------------------------------------- // Reshape blocks if needed // -------------------------------------------------------------------- if( nBlockXOff == nFullBlocksX || nBlockYOff == nFullBlocksY ) { ReshapeBlock( nBlockXOff, nBlockYOff, nBlockBufSize, pabyBlockBuf ); } // -------------------------------------------------------------------- // Copy block buffer to image // -------------------------------------------------------------------- memcpy( pImage, pabyBlockBuf, nBlockXSize * nBlockYSize * GDALGetDataTypeSize( eDataType ) / 8 ); #ifdef CPL_MSB if( eDataType == GDT_Int16 || eDataType == GDT_UInt16) GDALSwapWords( pImage, 2, nBlockXSize * nBlockYSize, 2 ); else if( eDataType == GDT_Int32 || eDataType == GDT_UInt32 || eDataType == GDT_Float32 ) GDALSwapWords( pImage, 4, nBlockXSize * nBlockYSize, 4 ); else if (eDataType == GDT_Float64 ) GDALSwapWords( pImage, 8, nBlockXSize * nBlockYSize, 8 ); #endif return CE_None; }
CPLErr RawRasterBand::AccessBlock( vsi_l_offset nBlockOff, int nBlockSize, void * pData ) { int nBytesActuallyRead; /* -------------------------------------------------------------------- */ /* Seek to the right block. */ /* -------------------------------------------------------------------- */ if( Seek( nBlockOff, SEEK_SET ) == -1 ) { memset( pData, 0, nBlockSize ); return CE_None; } /* -------------------------------------------------------------------- */ /* Read the block. */ /* -------------------------------------------------------------------- */ nBytesActuallyRead = Read( pData, 1, nBlockSize ); if( nBytesActuallyRead < nBlockSize ) { memset( ((GByte *) pData) + nBytesActuallyRead, 0, nBlockSize - nBytesActuallyRead ); return CE_None; } /* -------------------------------------------------------------------- */ /* Byte swap the interesting data, if required. */ /* -------------------------------------------------------------------- */ if( !bNativeOrder && eDataType != GDT_Byte ) { if( GDALDataTypeIsComplex( eDataType ) ) { int nWordSize; nWordSize = GDALGetDataTypeSize(eDataType)/16; GDALSwapWords( pData, nWordSize, nBlockSize / nPixelOffset, nPixelOffset ); GDALSwapWords( ((GByte *) pData) + nWordSize, nWordSize, nBlockSize / nPixelOffset, nPixelOffset ); } else GDALSwapWords( pData, GDALGetDataTypeSize(eDataType) / 8, nBlockSize / nPixelOffset, nPixelOffset ); } return CE_None; }
CPLErr BTRasterBand::IReadBlock( int nBlockXOff, CPL_UNUSED int nBlockYOff, void * pImage ) { CPLAssert( nBlockYOff == 0 ); const int nDataSize = GDALGetDataTypeSizeBytes( eDataType ); /* -------------------------------------------------------------------- */ /* Seek to profile. */ /* -------------------------------------------------------------------- */ if( VSIFSeekL( fpImage, 256 + nBlockXOff * nDataSize * static_cast<vsi_l_offset>( nRasterYSize ), SEEK_SET ) != 0 ) { CPLError( CE_Failure, CPLE_FileIO, ".bt Seek failed:%s", VSIStrerror( errno ) ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Read the profile. */ /* -------------------------------------------------------------------- */ if( VSIFReadL( pImage, nDataSize, nRasterYSize, fpImage ) != static_cast<size_t>( nRasterYSize ) ) { CPLError( CE_Failure, CPLE_FileIO, ".bt Read failed:%s", VSIStrerror( errno ) ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Swap on MSB platforms. */ /* -------------------------------------------------------------------- */ #ifdef CPL_MSB GDALSwapWords( pImage, nDataSize, nRasterYSize, nDataSize ); #endif /* -------------------------------------------------------------------- */ /* Vertical flip, since GDAL expects values from top to bottom, */ /* but in .bt they are bottom to top. */ /* -------------------------------------------------------------------- */ for( int i = 0; i < nRasterYSize / 2; i++ ) { GByte abyWrk[8] = { 0 }; memcpy( abyWrk, reinterpret_cast<GByte *>(pImage) + i * nDataSize, nDataSize ); memcpy( reinterpret_cast<GByte *>(pImage) + i * nDataSize, reinterpret_cast<GByte *>(pImage) + (nRasterYSize - i - 1) * nDataSize, nDataSize ); memcpy( reinterpret_cast<GByte *>(pImage) + (nRasterYSize - i - 1) * nDataSize, abyWrk, nDataSize ); } return CE_None; }
CPLErr SRTMHGTRasterBand::IWriteBlock(int /*nBlockXOff*/, int nBlockYOff, void* pImage) { SRTMHGTDataset* poGDS = reinterpret_cast<SRTMHGTDataset *>( poDS ); if( poGDS->eAccess != GA_Update ) return CE_Failure; const int nDTSize = GDALGetDataTypeSizeBytes(eDataType); VSIFSeekL(poGDS->fpImage, nBlockYOff*nBlockXSize*nDTSize, SEEK_SET); #ifdef CPL_LSB if( nDTSize > 1 ) { memcpy(poGDS->panBuffer, pImage, nBlockXSize*nDTSize); GDALSwapWords(poGDS->panBuffer, nDTSize, nBlockXSize, nDTSize); VSIFWriteL( reinterpret_cast<unsigned char *>( poGDS->panBuffer ), nBlockXSize, nDTSize, poGDS->fpImage ); } else #endif { VSIFWriteL( reinterpret_cast<unsigned char *>( pImage ), nBlockXSize, nDTSize, poGDS->fpImage ); } return CE_None; }
CPLErr SRTMHGTRasterBand::IWriteBlock(int nBlockXOff, int nBlockYOff, void* pImage) { SRTMHGTDataset* poGDS = (SRTMHGTDataset*) poDS; CPLAssert(nBlockXOff == 0); if(nBlockXOff != 0) { CPLError(CE_Failure, CPLE_NotSupported, "unhandled nBlockXOff value : %d", nBlockXOff); return CE_Failure; } if((poGDS == NULL) || (poGDS->fpImage == NULL) || (poGDS->eAccess != GA_Update)) return CE_Failure; VSIFSeekL(poGDS->fpImage, nBlockYOff*nBlockXSize*2, SEEK_SET); #ifdef CPL_LSB memcpy(poGDS->panBuffer, pImage, nBlockXSize*sizeof(GInt16)); GDALSwapWords(poGDS->panBuffer, 2, nBlockXSize, 2); VSIFWriteL((unsigned char*)poGDS->panBuffer, nBlockXSize, 2, poGDS->fpImage); #else VSIFWriteL((unsigned char*)pImage, nBlockXSize, 2, poGDS->fpImage); #endif return CE_None; }
CPLErr SRTMHGTRasterBand::IReadBlock(int nBlockXOff, int nBlockYOff, void* pImage) { SRTMHGTDataset* poGDS = (SRTMHGTDataset*) poDS; CPLAssert(nBlockXOff == 0); if(nBlockXOff != 0) { CPLError(CE_Failure, CPLE_NotSupported, "unhandled nBlockXOff value : %d", nBlockXOff); return CE_Failure; } if((poGDS == NULL) || (poGDS->fpImage == NULL)) return CE_Failure; /* -------------------------------------------------------------------- */ /* Load the desired data into the working buffer. */ /* -------------------------------------------------------------------- */ VSIFSeekL(poGDS->fpImage, nBlockYOff*nBlockXSize*2, SEEK_SET); VSIFReadL((unsigned char*)pImage, nBlockXSize, 2, poGDS->fpImage); #ifdef CPL_LSB GDALSwapWords(pImage, 2, nBlockXSize, 2); #endif return CE_None; }
CPLErr COSARRasterBand::IReadBlock(CPL_UNUSED int nBlockXOff, int nBlockYOff, void *pImage) { unsigned long nRSFV = 0; unsigned long nRSLV = 0; COSARDataset *pCDS = (COSARDataset *) poDS; /* Find the line we want to be at */ /* To explain some magic numbers: * 4 bytes for an entire sample (2 I, 2 Q) * nBlockYOff + 4 = Y offset + 4 annotation lines at beginning * of file */ VSIFSeek(pCDS->fp,(this->nRTNB * (nBlockYOff + 4)), SEEK_SET); /* Read RSFV and RSLV (TX-GS-DD-3307) */ VSIFRead(&nRSFV,1,4,pCDS->fp); VSIFRead(&nRSLV,1,4,pCDS->fp); #ifdef CPL_LSB nRSFV = CPL_SWAP32(nRSFV); nRSLV = CPL_SWAP32(nRSLV); #endif if (nRSLV < nRSFV || nRSFV == 0 || nRSFV - 1 >= ((unsigned long) nBlockXSize) || nRSLV - nRSFV > ((unsigned long) nBlockXSize) || nRSFV >= this->nRTNB || nRSLV > this->nRTNB) { /* throw an error */ CPLError(CE_Failure, CPLE_AppDefined, "RSLV/RSFV values are not sane... oh dear.\n"); return CE_Failure; } /* zero out the range line */ for (int i = 0; i < this->nRasterXSize; i++) { ((GUInt32 *)pImage)[i] = 0; } /* properly account for validity mask */ if (nRSFV > 1) { VSIFSeek(pCDS->fp,(this->nRTNB*(nBlockYOff+4)+(nRSFV+1)*4), SEEK_SET); } /* Read the valid samples: */ VSIFRead(((char *)pImage)+((nRSFV - 1)*4),1,((nRSLV-1)*4)-((nRSFV-1)*4),pCDS->fp); #ifdef CPL_LSB // GDALSwapWords( pImage, 4, nBlockXSize * nBlockYSize, 4 ); GDALSwapWords( pImage, 2, nBlockXSize * nBlockYSize * 2, 2 ); #endif return CE_None; }
CPLErr ISISTiledBand::IReadBlock( int nXBlock, int nYBlock, void *pImage ) { GIntBig nOffset = nFirstTileOffset + nXBlock * nXTileOffset + nYBlock * nYTileOffset; size_t nBlockSize = (GDALGetDataTypeSize(eDataType)/8) * nBlockXSize * nBlockYSize; if( VSIFSeekL( fpVSIL, nOffset, SEEK_SET ) != 0 ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to seek to offset %d to read tile %d,%d.", (int) nOffset, nXBlock, nYBlock ); return CE_Failure; } if( VSIFReadL( pImage, 1, nBlockSize, fpVSIL ) != nBlockSize ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to read %d bytes for tile %d,%d.", (int) nBlockSize, nXBlock, nYBlock ); return CE_Failure; } if( !bNativeOrder ) GDALSwapWords( pImage, GDALGetDataTypeSize(eDataType)/8, nBlockXSize*nBlockYSize, GDALGetDataTypeSize(eDataType)/8 ); return CE_None; }
CPLErr COASPRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff, int nBlockYOff, void *pImage ) { if (this->fp == NULL) { CPLError(CE_Fatal, CPLE_AppDefined, "file pointer freed unexpectedly\n"); return CE_Fatal; } /* 8 bytes per pixel: 4 bytes I, 4 bytes Q */ unsigned long nByteNum = poDS->GetRasterXSize() * 8 * nBlockYOff; VSIFSeekL(this->fp, nByteNum, SEEK_SET); int nReadSize = (GDALGetDataTypeSize(eDataType)/8) * poDS->GetRasterXSize(); VSIFReadL((char *)pImage, 1, nReadSize, this->fp); #ifdef CPL_LSB GDALSwapWords( pImage, 4, nBlockXSize * 2, 4 ); #endif return CE_None; }
CPLErr TerragenRasterBand::IWriteBlock ( int nBlockXOff, int nBlockYOff, void* pImage ) { CPLAssert( nBlockXOff == 0 ); CPLAssert( pImage != NULL ); CPLAssert( m_pvLine != NULL ); #define sgn(_n) ((_n) < 0 ? -1 : ((_n) > 0 ? 1 : 0) ) #define sround(_f) \ (int)((_f) + (0.5 * sgn(_f))) const size_t pixelsize = sizeof(GInt16); TerragenDataset& ds = *(TerragenDataset*)poDS; if(m_bFirstTime) { m_bFirstTime = false; ds.write_header(); ds.m_nDataOffset = VSIFTellL(ds.m_fp); } const size_t rowbytes = nBlockXSize * pixelsize; GInt16* pLine = (GInt16*)m_pvLine; if(0 == VSIFSeekL( ds.m_fp, ds.m_nDataOffset + // Terragen is Y inverted. (ds.GetRasterYSize()-1-nBlockYOff) * rowbytes, SEEK_SET)) { // Convert each float32 to int16. float* pfImage = (float*)pImage; for(size_t x = 0; x < (size_t)nBlockXSize; x++) { double f = pfImage[x]; f *= ds.m_dMetersPerElevUnit; f /= ds.m_dSCAL; GInt16 hv = (GInt16)((f - ds.m_nBaseHeight) * 65536.0 / ds.m_nHeightScale /*+ ds.m_nShift*/); pLine[x] = hv; } #ifdef CPL_MSB GDALSwapWords( m_pvLine, pixelsize, nBlockXSize, pixelsize ); #endif if(1 == VSIFWriteL(m_pvLine, rowbytes, 1, ds.m_fp)) return CE_None; } return CE_Failure; }
CPLErr TerragenRasterBand::IWriteBlock ( CPL_UNUSED int nBlockXOff, int nBlockYOff, void* pImage ) { CPLAssert( nBlockXOff == 0 ); CPLAssert( pImage != NULL ); CPLAssert( m_pvLine != NULL ); const size_t pixelsize = sizeof(GInt16); TerragenDataset& ds = *reinterpret_cast<TerragenDataset *>(poDS ); if( m_bFirstTime ) { m_bFirstTime = false; ds.write_header(); ds.m_nDataOffset = VSIFTellL(ds.m_fp); } const size_t rowbytes = nBlockXSize * pixelsize; GInt16* pLine = reinterpret_cast<GInt16 *>( m_pvLine ); if(0 == VSIFSeekL( ds.m_fp, ds.m_nDataOffset + // Terragen is Y inverted. (ds.GetRasterYSize()-1-nBlockYOff) * rowbytes, SEEK_SET)) { // Convert each float32 to int16. float* pfImage = reinterpret_cast<float *>( pImage ); for( size_t x = 0; x < static_cast<size_t>( nBlockXSize ); x++ ) { const double f = pfImage[x] * ds.m_dMetersPerElevUnit / ds.m_dSCAL; const GInt16 hv = static_cast<GInt16>( ( f - ds.m_nBaseHeight ) * 65536.0 / ds.m_nHeightScale /*+ ds.m_nShift*/ ); pLine[x] = hv; } #ifdef CPL_MSB GDALSwapWords( m_pvLine, pixelsize, nBlockXSize, pixelsize ); #endif if(1 == VSIFWriteL(m_pvLine, rowbytes, 1, ds.m_fp)) return CE_None; } return CE_Failure; }
CPLErr TerragenRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void* pImage ) { //CPLAssert( sizeof(float) == sizeof(GInt32) ); CPLAssert( nBlockXOff == 0 ); CPLAssert( pImage != NULL ); TerragenDataset& ds = *(TerragenDataset *) poDS; /* -------------------------------------------------------------------- */ /* Seek to scanline. Terragen is a bottom-top format, so we have to invert the row location. -------------------------------------------------------------------- */ const size_t rowbytes = nBlockXSize * sizeof(GInt16); if(0 != VSIFSeekL( ds.m_fp, ds.m_nDataOffset + (ds.GetRasterYSize() -1 - nBlockYOff) * rowbytes, SEEK_SET)) { CPLError( CE_Failure, CPLE_FileIO, "Terragen Seek failed:%s", VSIStrerror( errno ) ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Read the scanline into the line buffer. */ /* -------------------------------------------------------------------- */ if( VSIFReadL( pImage, rowbytes, 1, ds.m_fp ) != 1 ) { CPLError( CE_Failure, CPLE_FileIO, "Terragen read failed:%s", VSIStrerror( errno ) ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Swap on MSB platforms. */ /* -------------------------------------------------------------------- */ #ifdef CPL_MSB GDALSwapWords( pImage, sizeof(GInt16), nRasterXSize, sizeof(GInt16) ); #endif return CE_None; }
// Test that GDALSwapWords() with unaligned buffers template<> template<> void object::test<10>() { GByte abyBuffer[ 8 * 2 + 1 ] = { 0, 1, 2, 3, 4, 5, 6, 7, 255, 7, 6, 5, 4, 3, 2, 1, 0 }; GDALSwapWords(abyBuffer, 4, 2, 9 ); ensure( abyBuffer[0] == 3 ); ensure( abyBuffer[1] == 2 ); ensure( abyBuffer[2] == 1 ); ensure( abyBuffer[3] == 0 ); ensure( abyBuffer[9] == 4 ); ensure( abyBuffer[10] == 5 ); ensure( abyBuffer[11] == 6 ); ensure( abyBuffer[12] == 7 ); GDALSwapWords(abyBuffer, 4, 2, 9 ); GDALSwapWords(abyBuffer, 8, 2, 9 ); ensure( abyBuffer[0] == 7 ); ensure( abyBuffer[1] == 6 ); ensure( abyBuffer[2] == 5 ); ensure( abyBuffer[3] == 4 ); ensure( abyBuffer[4] == 3 ); ensure( abyBuffer[5] == 2 ); ensure( abyBuffer[6] == 1 ); ensure( abyBuffer[7] == 0 ); ensure( abyBuffer[9] == 0 ); ensure( abyBuffer[10] == 1 ); ensure( abyBuffer[11] == 2 ); ensure( abyBuffer[12] == 3 ); ensure( abyBuffer[13] == 4 ); ensure( abyBuffer[14] == 5 ); ensure( abyBuffer[15] == 6 ); ensure( abyBuffer[16] == 7 ); GDALSwapWords(abyBuffer, 4, 2, 9 ); }
CPLErr LevellerRasterBand::IWriteBlock ( int nBlockXOff, int nBlockYOff, void* pImage ) { CPLAssert( nBlockXOff == 0 ); CPLAssert( pImage != NULL ); CPLAssert( m_pLine != NULL ); /* #define sgn(_n) ((_n) < 0 ? -1 : ((_n) > 0 ? 1 : 0) ) #define sround(_f) \ (int)((_f) + (0.5 * sgn(_f))) */ const size_t pixelsize = sizeof(float); LevellerDataset& ds = *(LevellerDataset*)poDS; if(m_bFirstTime) { m_bFirstTime = false; if(!ds.write_header()) return CE_Failure; ds.m_nDataOffset = VSIFTellL(ds.m_fp); } const size_t rowbytes = nBlockXSize * pixelsize; const float* pfImage = (float*)pImage; if(0 == VSIFSeekL( ds.m_fp, ds.m_nDataOffset + nBlockYOff * rowbytes, SEEK_SET)) { for(size_t x = 0; x < (size_t)nBlockXSize; x++) { // Convert logical elevations to physical. m_pLine[x] = (float) ((pfImage[x] - ds.m_dElevBase) / ds.m_dElevScale); } #ifdef CPL_MSB GDALSwapWords( m_pLine, pixelsize, nBlockXSize, pixelsize ); #endif if(1 == VSIFWriteL(m_pLine, rowbytes, 1, ds.m_fp)) return CE_None; } return CE_Failure; }
CPLErr SRTMHGTRasterBand::IReadBlock(int /*nBlockXOff*/, int nBlockYOff, void* pImage) { SRTMHGTDataset* poGDS = reinterpret_cast<SRTMHGTDataset *>( poDS ); /* -------------------------------------------------------------------- */ /* Load the desired data into the working buffer. */ /* -------------------------------------------------------------------- */ const int nDTSize = GDALGetDataTypeSizeBytes(eDataType); VSIFSeekL(poGDS->fpImage, nBlockYOff*nBlockXSize*nDTSize, SEEK_SET); VSIFReadL((unsigned char*)pImage, nBlockXSize, nDTSize, poGDS->fpImage); #ifdef CPL_LSB GDALSwapWords(pImage, nDTSize, nBlockXSize, nDTSize); #endif return CE_None; }
CPLErr RawRasterBand::IRasterIO( GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize, void * pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, int nPixelSpace, int nLineSpace ) { int nBandDataSize = GDALGetDataTypeSize(eDataType) / 8; int nBufDataSize = GDALGetDataTypeSize( eBufType ) / 8; int nBytesToRW = nPixelOffset * nXSize; /* -------------------------------------------------------------------- */ /* Use direct IO without caching if: */ /* */ /* GDAL_ONE_BIG_READ is enabled */ /* */ /* or */ /* */ /* the length of a scanline on disk is more than 50000 bytes, and the */ /* width of the requested chunk is less than 40% of the whole scanline */ /* and none of the requested scanlines are already in the cache. */ /* -------------------------------------------------------------------- */ if( nPixelOffset < 0 ) { return GDALRasterBand::IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace ); } if ( !CSLTestBoolean( CPLGetConfigOption( "GDAL_ONE_BIG_READ", "NO") ) ) { if ( nLineSize < 50000 || nBytesToRW > nLineSize / 5 * 2 || IsLineLoaded( nYOff, nYSize ) ) { return GDALRasterBand::IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace ); } } /* ==================================================================== */ /* Read data. */ /* ==================================================================== */ if ( eRWFlag == GF_Read ) { /* -------------------------------------------------------------------- */ /* Do we have overviews that would be appropriate to satisfy */ /* this request? */ /* -------------------------------------------------------------------- */ if( (nBufXSize < nXSize || nBufYSize < nYSize) && GetOverviewCount() > 0 ) { if( OverviewRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace ) == CE_None ) return CE_None; } /* ==================================================================== */ /* 1. Simplest case when we should get contiguous block */ /* of uninterleaved pixels. */ /* ==================================================================== */ if ( nXSize == GetXSize() && nXSize == nBufXSize && nYSize == nBufYSize && eBufType == eDataType && nPixelOffset == nBandDataSize && nPixelSpace == nBufDataSize && nLineSpace == nPixelSpace * nXSize ) { if ( AccessBlock( nImgOffset + (vsi_l_offset)nYOff * nLineOffset + nXOff, nXSize * nYSize * nBandDataSize, pData ) != CE_None ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to read %d bytes at %lu.", nXSize * nYSize * nBandDataSize, (unsigned long) (nImgOffset + (vsi_l_offset)nYOff * nLineOffset + nXOff) ); } } /* ==================================================================== */ /* 2. Case when we need deinterleave and/or subsample data. */ /* ==================================================================== */ else { GByte *pabyData; double dfSrcXInc, dfSrcYInc; int iLine; dfSrcXInc = (double)nXSize / nBufXSize; dfSrcYInc = (double)nYSize / nBufYSize; pabyData = (GByte *) CPLMalloc( nBytesToRW ); for ( iLine = 0; iLine < nBufYSize; iLine++ ) { if ( AccessBlock( nImgOffset + ((vsi_l_offset)nYOff + (int)(iLine * dfSrcYInc)) * nLineOffset + nXOff * nPixelOffset, nBytesToRW, pabyData ) != CE_None ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to read %d bytes at %lu.", nBytesToRW, (unsigned long)(nImgOffset + ((vsi_l_offset)nYOff + (int)(iLine * dfSrcYInc)) * nLineOffset + nXOff * nPixelOffset) ); } /* -------------------------------------------------------------------- */ /* Copy data from disk buffer to user block buffer and subsample, */ /* if needed. */ /* -------------------------------------------------------------------- */ if ( nXSize == nBufXSize && nYSize == nBufYSize ) { GDALCopyWords( pabyData, eDataType, nPixelOffset, (GByte *)pData + iLine * nLineSpace, eBufType, nPixelSpace, nXSize ); } else { int iPixel; for ( iPixel = 0; iPixel < nBufXSize; iPixel++ ) { GDALCopyWords( pabyData + (int)(iPixel * dfSrcXInc) * nPixelOffset, eDataType, 0, (GByte *)pData + iLine * nLineSpace + iPixel * nBufDataSize, eBufType, nPixelSpace, 1 ); } } } CPLFree( pabyData ); } } /* ==================================================================== */ /* Write data. */ /* ==================================================================== */ else { int nBytesActuallyWritten; /* ==================================================================== */ /* 1. Simplest case when we should write contiguous block */ /* of uninterleaved pixels. */ /* ==================================================================== */ if ( nXSize == GetXSize() && nXSize == nBufXSize && nYSize == nBufYSize && eBufType == eDataType && nPixelOffset == nBandDataSize && nPixelSpace == nBufDataSize && nLineSpace == nPixelSpace * nXSize ) { /* -------------------------------------------------------------------- */ /* Byte swap the data buffer, if required. */ /* -------------------------------------------------------------------- */ if( !bNativeOrder && eDataType != GDT_Byte ) { if( GDALDataTypeIsComplex( eDataType ) ) { int nWordSize; nWordSize = GDALGetDataTypeSize(eDataType)/16; GDALSwapWords( pData, nWordSize, nXSize, nPixelOffset ); GDALSwapWords( ((GByte *) pData) + nWordSize, nWordSize, nXSize, nPixelOffset ); } else GDALSwapWords( pData, nBandDataSize, nXSize, nPixelOffset ); } /* -------------------------------------------------------------------- */ /* Seek to the right block. */ /* -------------------------------------------------------------------- */ if( Seek( nImgOffset + (vsi_l_offset)nYOff * nLineOffset + nXOff, SEEK_SET) == -1 ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to seek to %lu to write data.\n", (unsigned long)(nImgOffset + (vsi_l_offset)nYOff * nLineOffset + nXOff) ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Write the block. */ /* -------------------------------------------------------------------- */ nBytesToRW = nXSize * nYSize * nBandDataSize; nBytesActuallyWritten = Write( pData, 1, nBytesToRW ); if( nBytesActuallyWritten < nBytesToRW ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to write %d bytes to file. %d bytes written", nBytesToRW, nBytesActuallyWritten ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Byte swap (if necessary) back into machine order so the */ /* buffer is still usable for reading purposes. */ /* -------------------------------------------------------------------- */ if( !bNativeOrder && eDataType != GDT_Byte ) { if( GDALDataTypeIsComplex( eDataType ) ) { int nWordSize; nWordSize = GDALGetDataTypeSize(eDataType)/16; GDALSwapWords( pData, nWordSize, nXSize, nPixelOffset ); GDALSwapWords( ((GByte *) pData) + nWordSize, nWordSize, nXSize, nPixelOffset ); } else GDALSwapWords( pData, nBandDataSize, nXSize, nPixelOffset ); } } /* ==================================================================== */ /* 2. Case when we need deinterleave and/or subsample data. */ /* ==================================================================== */ else { GByte *pabyData; double dfSrcXInc, dfSrcYInc; vsi_l_offset nBlockOff; int iLine; dfSrcXInc = (double)nXSize / nBufXSize; dfSrcYInc = (double)nYSize / nBufYSize; pabyData = (GByte *) CPLMalloc( nBytesToRW ); for ( iLine = 0; iLine < nBufYSize; iLine++ ) { nBlockOff = nImgOffset + ((vsi_l_offset)nYOff + (int)(iLine*dfSrcYInc))*nLineOffset + nXOff * nPixelOffset; /* -------------------------------------------------------------------- */ /* If the data for this band is completely contiguous we don't */ /* have to worry about pre-reading from disk. */ /* -------------------------------------------------------------------- */ if( nPixelOffset > nBandDataSize ) AccessBlock( nBlockOff, nBytesToRW, pabyData ); /* -------------------------------------------------------------------- */ /* Copy data from user block buffer to disk buffer and subsample, */ /* if needed. */ /* -------------------------------------------------------------------- */ if ( nXSize == nBufXSize && nYSize == nBufYSize ) { GDALCopyWords( (GByte *)pData + iLine * nLineSpace, eBufType, nPixelSpace, pabyData, eDataType, nPixelOffset, nXSize ); } else { int iPixel; for ( iPixel = 0; iPixel < nBufXSize; iPixel++ ) { GDALCopyWords( (GByte *)pData+iLine*nLineSpace + iPixel * nBufDataSize, eBufType, nPixelSpace, pabyData + (int)(iPixel * dfSrcXInc) * nPixelOffset, eDataType, 0, 1 ); } } /* -------------------------------------------------------------------- */ /* Byte swap the data buffer, if required. */ /* -------------------------------------------------------------------- */ if( !bNativeOrder && eDataType != GDT_Byte ) { if( GDALDataTypeIsComplex( eDataType ) ) { int nWordSize; nWordSize = GDALGetDataTypeSize(eDataType)/16; GDALSwapWords( pabyData, nWordSize, nXSize, nPixelOffset ); GDALSwapWords( ((GByte *) pabyData) + nWordSize, nWordSize, nXSize, nPixelOffset ); } else GDALSwapWords( pabyData, nBandDataSize, nXSize, nPixelOffset ); } /* -------------------------------------------------------------------- */ /* Seek to the right line in block. */ /* -------------------------------------------------------------------- */ if( Seek( nBlockOff, SEEK_SET) == -1 ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to seek to %ld to read.\n", (long)nBlockOff ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Write the line of block. */ /* -------------------------------------------------------------------- */ nBytesActuallyWritten = Write( pabyData, 1, nBytesToRW ); if( nBytesActuallyWritten < nBytesToRW ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to write %d bytes to file. %d bytes written", nBytesToRW, nBytesActuallyWritten ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Byte swap (if necessary) back into machine order so the */ /* buffer is still usable for reading purposes. */ /* -------------------------------------------------------------------- */ if( !bNativeOrder && eDataType != GDT_Byte ) { if( GDALDataTypeIsComplex( eDataType ) ) { int nWordSize; nWordSize = GDALGetDataTypeSize(eDataType)/16; GDALSwapWords( pabyData, nWordSize, nXSize, nPixelOffset ); GDALSwapWords( ((GByte *) pabyData) + nWordSize, nWordSize, nXSize, nPixelOffset ); } else GDALSwapWords( pabyData, nBandDataSize, nXSize, nPixelOffset ); } } bDirty = TRUE; CPLFree( pabyData ); } } return CE_None; }
CPLErr SAFERasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage ) { /* -------------------------------------------------------------------- */ /* If the last strip is partial, we need to avoid */ /* over-requesting. We also need to initialize the extra part */ /* of the block to zero. */ /* -------------------------------------------------------------------- */ int nRequestYSize; if( (nBlockYOff + 1) * nBlockYSize > nRasterYSize ) { nRequestYSize = nRasterYSize - nBlockYOff * nBlockYSize; memset( pImage, 0, (GDALGetDataTypeSize( eDataType ) / 8) * nBlockXSize * nBlockYSize ); } else { nRequestYSize = nBlockYSize; } /*-------------------------------------------------------------------- */ /* If the input imagery is tiled, also need to avoid over- */ /* requesting in the X-direction. */ /* ------------------------------------------------------------------- */ int nRequestXSize; if( (nBlockXOff + 1) * nBlockXSize > nRasterXSize ) { nRequestXSize = nRasterXSize - nBlockXOff * nBlockXSize; memset( pImage, 0, (GDALGetDataTypeSize( eDataType ) / 8) * nBlockXSize * nBlockYSize ); } else { nRequestXSize = nBlockXSize; } if( eDataType == GDT_CInt16 && poBandFile->GetRasterCount() == 2 ) return poBandFile->RasterIO( GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nRequestXSize, nRequestYSize, pImage, nRequestXSize, nRequestYSize, GDT_Int16, 2, nullptr, 4, nBlockXSize * 4, 2, nullptr ); /* -------------------------------------------------------------------- */ /* File has one sample marked as sample format void, a 32bits. */ /* -------------------------------------------------------------------- */ else if( eDataType == GDT_CInt16 && poBandFile->GetRasterCount() == 1 ) { CPLErr eErr = poBandFile->RasterIO( GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nRequestXSize, nRequestYSize, pImage, nRequestXSize, nRequestYSize, GDT_UInt32, 1, nullptr, 4, nBlockXSize * 4, 0, nullptr ); #ifdef CPL_LSB /* First, undo the 32bit swap. */ GDALSwapWords( pImage, 4, nBlockXSize * nBlockYSize, 4 ); /* Then apply 16 bit swap. */ GDALSwapWords( pImage, 2, nBlockXSize * nBlockYSize * 2, 2 ); #endif return eErr; } /* -------------------------------------------------------------------- */ /* The 16bit case is straight forward. The underlying file */ /* looks like a 16bit unsigned data too. */ /* -------------------------------------------------------------------- */ else if( eDataType == GDT_UInt16 ) return poBandFile->RasterIO( GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nRequestXSize, nRequestYSize, pImage, nRequestXSize, nRequestYSize, GDT_UInt16, 1, nullptr, 2, nBlockXSize * 2, 0, nullptr ); else if ( eDataType == GDT_Byte ) return poBandFile->RasterIO( GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nRequestXSize, nRequestYSize, pImage, nRequestXSize, nRequestYSize, GDT_Byte, 1, nullptr, 1, nBlockXSize, 0, nullptr ); CPLAssert( false ); return CE_Failure; }
CPLErr RawRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff, void * pImage ) { CPLErr eErr = CE_None; CPLAssert( nBlockXOff == 0 ); if (pLineBuffer == NULL) return CE_Failure; /* -------------------------------------------------------------------- */ /* If the data for this band is completely contiguous we don't */ /* have to worry about pre-reading from disk. */ /* -------------------------------------------------------------------- */ if( ABS(nPixelOffset) > GDALGetDataTypeSize(eDataType) / 8 ) eErr = AccessLine( nBlockYOff ); /* -------------------------------------------------------------------- */ /* Copy data from user buffer into disk buffer. */ /* -------------------------------------------------------------------- */ GDALCopyWords( pImage, eDataType, GDALGetDataTypeSize(eDataType)/8, pLineStart, eDataType, nPixelOffset, nBlockXSize ); /* -------------------------------------------------------------------- */ /* Byte swap (if necessary) back into disk order before writing. */ /* -------------------------------------------------------------------- */ if( !bNativeOrder && eDataType != GDT_Byte ) { if( GDALDataTypeIsComplex( eDataType ) ) { int nWordSize; nWordSize = GDALGetDataTypeSize(eDataType)/16; GDALSwapWords( pLineBuffer, nWordSize, nBlockXSize, ABS(nPixelOffset) ); GDALSwapWords( ((GByte *) pLineBuffer)+nWordSize, nWordSize, nBlockXSize, ABS(nPixelOffset) ); } else GDALSwapWords( pLineBuffer, GDALGetDataTypeSize(eDataType)/8, nBlockXSize, ABS(nPixelOffset) ); } /* -------------------------------------------------------------------- */ /* Figure out where to start reading. */ /* -------------------------------------------------------------------- */ vsi_l_offset nWriteStart; if( nPixelOffset >= 0 ) nWriteStart = nImgOffset + (vsi_l_offset)nBlockYOff * nLineOffset; else { nWriteStart = nImgOffset + (vsi_l_offset)nBlockYOff * nLineOffset - ABS(nPixelOffset) * (nBlockXSize-1); } /* -------------------------------------------------------------------- */ /* Seek to correct location. */ /* -------------------------------------------------------------------- */ if( Seek( nWriteStart, SEEK_SET ) == -1 ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to seek to scanline %d @ %d to write to file.\n", nBlockYOff, (int) (nImgOffset + nBlockYOff * nLineOffset) ); eErr = CE_Failure; } /* -------------------------------------------------------------------- */ /* Write data buffer. */ /* -------------------------------------------------------------------- */ int nBytesToWrite; nBytesToWrite = ABS(nPixelOffset) * (nBlockXSize - 1) + GDALGetDataTypeSize(GetRasterDataType()) / 8; if( eErr == CE_None && Write( pLineBuffer, 1, nBytesToWrite ) < (size_t) nBytesToWrite ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to write scanline %d to file.\n", nBlockYOff ); eErr = CE_Failure; } /* -------------------------------------------------------------------- */ /* Byte swap (if necessary) back into machine order so the */ /* buffer is still usable for reading purposes. */ /* -------------------------------------------------------------------- */ if( !bNativeOrder && eDataType != GDT_Byte ) { if( GDALDataTypeIsComplex( eDataType ) ) { int nWordSize; nWordSize = GDALGetDataTypeSize(eDataType)/16; GDALSwapWords( pLineBuffer, nWordSize, nBlockXSize, ABS(nPixelOffset) ); GDALSwapWords( ((GByte *) pLineBuffer)+nWordSize, nWordSize, nBlockXSize, ABS(nPixelOffset) ); } else GDALSwapWords( pLineBuffer, GDALGetDataTypeSize(eDataType)/8, nBlockXSize, ABS(nPixelOffset) ); } bDirty = TRUE; return eErr; }
CPLErr RawRasterBand::AccessLine( int iLine ) { if (pLineBuffer == NULL) return CE_Failure; if( nLoadedScanline == iLine ) return CE_None; /* -------------------------------------------------------------------- */ /* Figure out where to start reading. */ /* -------------------------------------------------------------------- */ vsi_l_offset nReadStart; if( nPixelOffset >= 0 ) nReadStart = nImgOffset + (vsi_l_offset)iLine * nLineOffset; else { nReadStart = nImgOffset + (vsi_l_offset)iLine * nLineOffset - ABS(nPixelOffset) * (nBlockXSize-1); } /* -------------------------------------------------------------------- */ /* Seek to the right line. */ /* -------------------------------------------------------------------- */ if( Seek(nReadStart, SEEK_SET) == -1 ) { if (poDS != NULL && poDS->GetAccess() == GA_ReadOnly) { CPLError( CE_Failure, CPLE_FileIO, "Failed to seek to scanline %d @ %d.\n", iLine, (int) (nImgOffset + (vsi_l_offset)iLine * nLineOffset) ); return CE_Failure; } else { memset( pLineBuffer, 0, nPixelOffset * nBlockXSize ); nLoadedScanline = iLine; return CE_None; } } /* -------------------------------------------------------------------- */ /* Read the line. Take care not to request any more bytes than */ /* are needed, and not to lose a partially successful scanline */ /* read. */ /* -------------------------------------------------------------------- */ int nBytesToRead, nBytesActuallyRead; nBytesToRead = ABS(nPixelOffset) * (nBlockXSize - 1) + GDALGetDataTypeSize(GetRasterDataType()) / 8; nBytesActuallyRead = Read( pLineBuffer, 1, nBytesToRead ); if( nBytesActuallyRead < nBlockXSize ) { if (poDS != NULL && poDS->GetAccess() == GA_ReadOnly) { CPLError( CE_Failure, CPLE_FileIO, "Failed to read scanline %d.\n", iLine); return CE_Failure; } else { memset( ((GByte *) pLineBuffer) + nBytesActuallyRead, 0, nBytesToRead - nBytesActuallyRead ); } } /* -------------------------------------------------------------------- */ /* Byte swap the interesting data, if required. */ /* -------------------------------------------------------------------- */ if( !bNativeOrder && eDataType != GDT_Byte ) { if( GDALDataTypeIsComplex( eDataType ) ) { int nWordSize; nWordSize = GDALGetDataTypeSize(eDataType)/16; GDALSwapWords( pLineBuffer, nWordSize, nBlockXSize, ABS(nPixelOffset) ); GDALSwapWords( ((GByte *) pLineBuffer)+nWordSize, nWordSize, nBlockXSize, ABS(nPixelOffset) ); } else GDALSwapWords( pLineBuffer, GDALGetDataTypeSize(eDataType)/8, nBlockXSize, ABS(nPixelOffset) ); } nLoadedScanline = iLine; return CE_None; }
CPLErr RawRasterBand::IRasterIO( GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize, void * pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, int nPixelSpace, int nLineSpace ) { int nBandDataSize = GDALGetDataTypeSize(eDataType) / 8; int nBufDataSize = GDALGetDataTypeSize( eBufType ) / 8; int nBytesToRW = nPixelOffset * nXSize; if( !CanUseDirectIO(nXOff, nYOff, nXSize, nYSize, eBufType ) ) { return GDALRasterBand::IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace ); } CPLDebug("RAW", "Using direct IO implementation"); /* ==================================================================== */ /* Read data. */ /* ==================================================================== */ if ( eRWFlag == GF_Read ) { /* -------------------------------------------------------------------- */ /* Do we have overviews that would be appropriate to satisfy */ /* this request? */ /* -------------------------------------------------------------------- */ if( (nBufXSize < nXSize || nBufYSize < nYSize) && GetOverviewCount() > 0 ) { if( OverviewRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace ) == CE_None ) return CE_None; } /* ==================================================================== */ /* 1. Simplest case when we should get contiguous block */ /* of uninterleaved pixels. */ /* ==================================================================== */ if ( nXSize == GetXSize() && nXSize == nBufXSize && nYSize == nBufYSize && eBufType == eDataType && nPixelOffset == nBandDataSize && nPixelSpace == nBufDataSize && nLineSpace == nPixelSpace * nXSize ) { vsi_l_offset nOffset = nImgOffset + (vsi_l_offset)nYOff * nLineOffset + nXOff; if ( AccessBlock( nOffset, nXSize * nYSize * nBandDataSize, pData ) != CE_None ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to read %d bytes at " CPL_FRMT_GUIB ".", nXSize * nYSize * nBandDataSize, nOffset); } } /* ==================================================================== */ /* 2. Case when we need deinterleave and/or subsample data. */ /* ==================================================================== */ else { GByte *pabyData; double dfSrcXInc, dfSrcYInc; int iLine; dfSrcXInc = (double)nXSize / nBufXSize; dfSrcYInc = (double)nYSize / nBufYSize; pabyData = (GByte *) CPLMalloc( nBytesToRW ); for ( iLine = 0; iLine < nBufYSize; iLine++ ) { vsi_l_offset nOffset = nImgOffset + ((vsi_l_offset)nYOff + (vsi_l_offset)(iLine * dfSrcYInc)) * nLineOffset + nXOff * nPixelOffset; if ( AccessBlock( nOffset, nBytesToRW, pabyData ) != CE_None ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to read %d bytes at " CPL_FRMT_GUIB ".", nBytesToRW, nOffset ); } /* -------------------------------------------------------------------- */ /* Copy data from disk buffer to user block buffer and subsample, */ /* if needed. */ /* -------------------------------------------------------------------- */ if ( nXSize == nBufXSize && nYSize == nBufYSize ) { GDALCopyWords( pabyData, eDataType, nPixelOffset, (GByte *)pData + (vsi_l_offset)iLine * nLineSpace, eBufType, nPixelSpace, nXSize ); } else { int iPixel; for ( iPixel = 0; iPixel < nBufXSize; iPixel++ ) { GDALCopyWords( pabyData + (vsi_l_offset)(iPixel * dfSrcXInc) * nPixelOffset, eDataType, nPixelOffset, (GByte *)pData + (vsi_l_offset)iLine * nLineSpace + (vsi_l_offset)iPixel * nPixelSpace, eBufType, nPixelSpace, 1 ); } } } CPLFree( pabyData ); } } /* ==================================================================== */ /* Write data. */ /* ==================================================================== */ else { int nBytesActuallyWritten; /* ==================================================================== */ /* 1. Simplest case when we should write contiguous block */ /* of uninterleaved pixels. */ /* ==================================================================== */ if ( nXSize == GetXSize() && nXSize == nBufXSize && nYSize == nBufYSize && eBufType == eDataType && nPixelOffset == nBandDataSize && nPixelSpace == nBufDataSize && nLineSpace == nPixelSpace * nXSize ) { /* -------------------------------------------------------------------- */ /* Byte swap the data buffer, if required. */ /* -------------------------------------------------------------------- */ if( !bNativeOrder && eDataType != GDT_Byte ) { if( GDALDataTypeIsComplex( eDataType ) ) { int nWordSize; nWordSize = GDALGetDataTypeSize(eDataType)/16; GDALSwapWords( pData, nWordSize, nXSize, nPixelOffset ); GDALSwapWords( ((GByte *) pData) + nWordSize, nWordSize, nXSize, nPixelOffset ); } else GDALSwapWords( pData, nBandDataSize, nXSize, nPixelOffset ); } /* -------------------------------------------------------------------- */ /* Seek to the right block. */ /* -------------------------------------------------------------------- */ vsi_l_offset nOffset = nImgOffset + (vsi_l_offset)nYOff * nLineOffset + nXOff; if( Seek( nOffset, SEEK_SET) == -1 ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to seek to " CPL_FRMT_GUIB " to write data.\n", nOffset); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Write the block. */ /* -------------------------------------------------------------------- */ nBytesToRW = nXSize * nYSize * nBandDataSize; nBytesActuallyWritten = Write( pData, 1, nBytesToRW ); if( nBytesActuallyWritten < nBytesToRW ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to write %d bytes to file. %d bytes written", nBytesToRW, nBytesActuallyWritten ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Byte swap (if necessary) back into machine order so the */ /* buffer is still usable for reading purposes. */ /* -------------------------------------------------------------------- */ if( !bNativeOrder && eDataType != GDT_Byte ) { if( GDALDataTypeIsComplex( eDataType ) ) { int nWordSize; nWordSize = GDALGetDataTypeSize(eDataType)/16; GDALSwapWords( pData, nWordSize, nXSize, nPixelOffset ); GDALSwapWords( ((GByte *) pData) + nWordSize, nWordSize, nXSize, nPixelOffset ); } else GDALSwapWords( pData, nBandDataSize, nXSize, nPixelOffset ); } } /* ==================================================================== */ /* 2. Case when we need deinterleave and/or subsample data. */ /* ==================================================================== */ else { GByte *pabyData; double dfSrcXInc, dfSrcYInc; vsi_l_offset nBlockOff; int iLine; dfSrcXInc = (double)nXSize / nBufXSize; dfSrcYInc = (double)nYSize / nBufYSize; pabyData = (GByte *) CPLMalloc( nBytesToRW ); for ( iLine = 0; iLine < nBufYSize; iLine++ ) { nBlockOff = nImgOffset + ((vsi_l_offset)nYOff + (vsi_l_offset)(iLine*dfSrcYInc))*nLineOffset + nXOff * nPixelOffset; /* -------------------------------------------------------------------- */ /* If the data for this band is completely contiguous we don't */ /* have to worry about pre-reading from disk. */ /* -------------------------------------------------------------------- */ if( nPixelOffset > nBandDataSize ) AccessBlock( nBlockOff, nBytesToRW, pabyData ); /* -------------------------------------------------------------------- */ /* Copy data from user block buffer to disk buffer and subsample, */ /* if needed. */ /* -------------------------------------------------------------------- */ if ( nXSize == nBufXSize && nYSize == nBufYSize ) { GDALCopyWords( (GByte *)pData + (vsi_l_offset)iLine * nLineSpace, eBufType, nPixelSpace, pabyData, eDataType, nPixelOffset, nXSize ); } else { int iPixel; for ( iPixel = 0; iPixel < nBufXSize; iPixel++ ) { GDALCopyWords( (GByte *)pData+(vsi_l_offset)iLine*nLineSpace + (vsi_l_offset)iPixel * nPixelSpace, eBufType, nPixelSpace, pabyData + (vsi_l_offset)(iPixel * dfSrcXInc) * nPixelOffset, eDataType, nPixelOffset, 1 ); } } /* -------------------------------------------------------------------- */ /* Byte swap the data buffer, if required. */ /* -------------------------------------------------------------------- */ if( !bNativeOrder && eDataType != GDT_Byte ) { if( GDALDataTypeIsComplex( eDataType ) ) { int nWordSize; nWordSize = GDALGetDataTypeSize(eDataType)/16; GDALSwapWords( pabyData, nWordSize, nXSize, nPixelOffset ); GDALSwapWords( ((GByte *) pabyData) + nWordSize, nWordSize, nXSize, nPixelOffset ); } else GDALSwapWords( pabyData, nBandDataSize, nXSize, nPixelOffset ); } /* -------------------------------------------------------------------- */ /* Seek to the right line in block. */ /* -------------------------------------------------------------------- */ if( Seek( nBlockOff, SEEK_SET) == -1 ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to seek to " CPL_FRMT_GUIB " to read.\n", nBlockOff ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Write the line of block. */ /* -------------------------------------------------------------------- */ nBytesActuallyWritten = Write( pabyData, 1, nBytesToRW ); if( nBytesActuallyWritten < nBytesToRW ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to write %d bytes to file. %d bytes written", nBytesToRW, nBytesActuallyWritten ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Byte swap (if necessary) back into machine order so the */ /* buffer is still usable for reading purposes. */ /* -------------------------------------------------------------------- */ if( !bNativeOrder && eDataType != GDT_Byte ) { if( GDALDataTypeIsComplex( eDataType ) ) { int nWordSize; nWordSize = GDALGetDataTypeSize(eDataType)/16; GDALSwapWords( pabyData, nWordSize, nXSize, nPixelOffset ); GDALSwapWords( ((GByte *) pabyData) + nWordSize, nWordSize, nXSize, nPixelOffset ); } else GDALSwapWords( pabyData, nBandDataSize, nXSize, nPixelOffset ); } } bDirty = TRUE; CPLFree( pabyData ); } } return CE_None; }
CPLErr HF2RasterBand::IReadBlock( int nBlockXOff, int nLineYOff, void * pImage ) { HF2Dataset *poGDS = (HF2Dataset *) poDS; int nXBlocks = (nRasterXSize + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (nRasterYSize + nBlockXSize - 1) / nBlockXSize; if (!poGDS->LoadBlockMap()) return CE_Failure; if (pafBlockData == NULL) { pafBlockData = (float*)VSIMalloc3(nXBlocks * sizeof(float), poGDS->nTileSize, poGDS->nTileSize); if (pafBlockData == NULL) return CE_Failure; } nLineYOff = nRasterYSize - 1 - nLineYOff; int nBlockYOff = nLineYOff / nBlockXSize; int nYOffInTile = nLineYOff % nBlockXSize; if (nBlockYOff != nLastBlockYOff) { nLastBlockYOff = nBlockYOff; memset(pafBlockData, 0, nXBlocks * sizeof(float) * nBlockXSize * nBlockXSize); /* 4 * nBlockXSize is the upper bound */ void* pabyData = CPLMalloc( 4 * nBlockXSize ); int nxoff; for(nxoff = 0; nxoff < nXBlocks; nxoff++) { VSIFSeekL(poGDS->fp, poGDS->panBlockOffset[(nYBlocks - 1 - nBlockYOff) * nXBlocks + nxoff], SEEK_SET); float fScale, fOff; VSIFReadL(&fScale, 4, 1, poGDS->fp); VSIFReadL(&fOff, 4, 1, poGDS->fp); CPL_LSBPTR32(&fScale); CPL_LSBPTR32(&fOff); int nTileWidth = MIN(nBlockXSize, nRasterXSize - nxoff * nBlockXSize); int nTileHeight = MIN(nBlockXSize, nRasterYSize - nBlockYOff * nBlockXSize); int j; for(j=0;j<nTileHeight;j++) { GByte nWordSize; VSIFReadL(&nWordSize, 1, 1, poGDS->fp); if (nWordSize != 1 && nWordSize != 2 && nWordSize != 4) { CPLError(CE_Failure, CPLE_AppDefined, "Unexpected word size : %d", (int)nWordSize); break; } GInt32 nVal; VSIFReadL(&nVal, 4, 1, poGDS->fp); CPL_LSBPTR32(&nVal); VSIFReadL(pabyData, nWordSize * (nTileWidth - 1), 1, poGDS->fp); #if defined(CPL_MSB) if (nWordSize > 1) GDALSwapWords(pabyData, nWordSize, nTileWidth - 1, nWordSize); #endif pafBlockData[nxoff * nBlockXSize * nBlockXSize + j * nBlockXSize + 0] = nVal * fScale + fOff; int i; for(i=1;i<nTileWidth;i++) { if (nWordSize == 1) nVal += ((signed char*)pabyData)[i-1]; else if (nWordSize == 2) nVal += ((GInt16*)pabyData)[i-1]; else nVal += ((GInt32*)pabyData)[i-1]; pafBlockData[nxoff * nBlockXSize * nBlockXSize + j * nBlockXSize + i] = nVal * fScale + fOff; } } } CPLFree(pabyData); } int nTileWidth = MIN(nBlockXSize, nRasterXSize - nBlockXOff * nBlockXSize); memcpy(pImage, pafBlockData + nBlockXOff * nBlockXSize * nBlockXSize + nYOffInTile * nBlockXSize, nTileWidth * sizeof(float)); return CE_None; }
CPLErr LevellerRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void* pImage ) { CPLAssert( sizeof(float) == sizeof(GInt32) ); CPLAssert( nBlockXOff == 0 ); CPLAssert( pImage != NULL ); LevellerDataset *poGDS = (LevellerDataset *) poDS; /* -------------------------------------------------------------------- */ /* Seek to scanline. */ /* -------------------------------------------------------------------- */ const size_t rowbytes = nBlockXSize * sizeof(float); if(0 != VSIFSeekL( poGDS->m_fp, poGDS->m_nDataOffset + nBlockYOff * rowbytes, SEEK_SET)) { CPLError( CE_Failure, CPLE_FileIO, ".bt Seek failed:%s", VSIStrerror( errno ) ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Read the scanline into the image buffer. */ /* -------------------------------------------------------------------- */ if( VSIFReadL( pImage, rowbytes, 1, poGDS->m_fp ) != 1 ) { CPLError( CE_Failure, CPLE_FileIO, "Leveller read failed:%s", VSIStrerror( errno ) ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Swap on MSB platforms. */ /* -------------------------------------------------------------------- */ #ifdef CPL_MSB GDALSwapWords( pImage, 4, nRasterXSize, 4 ); #endif /* -------------------------------------------------------------------- */ /* Convert from legacy-format fixed-point if necessary. */ /* -------------------------------------------------------------------- */ float* pf = (float*)pImage; if(poGDS->m_version < 6) { GInt32* pi = (int*)pImage; for(size_t i = 0; i < (size_t)nBlockXSize; i++) pf[i] = (float)pi[i] / 65536; } #if 0 /* -------------------------------------------------------------------- */ /* Convert raw elevations to realworld elevs. */ /* -------------------------------------------------------------------- */ for(size_t i = 0; i < nBlockXSize; i++) pf[i] *= poGDS->m_dWorldscale; //this->GetScale(); #endif return CE_None; }
/** * Fill all the raster properties with the string * hexwkb representation given as input. * This method swaps words if the raster endianess is distinct from * the machine endianess * Properties: * const char *: the string hexwkb representation of the raster */ int WKTRasterWrapper::Initialize(const char* pszHex) { int nBufferDataWithoutHeaderLen = 0; int nRasterHeaderLen = 0; int nRasterBandHeaderLen = 0; int nRasterDataLen = 0; GByte * pbyAuxPtr; GByte byMachineEndianess = NDR; // by default // Check machine endianess #ifdef CPL_LSB byMachineEndianess = NDR; #else byMachineEndianess = XDR; #endif /************************************************************************* * Check parameters *************************************************************************/ if (pszHex == NULL || strlen(pszHex) % 2) { CPLError(CE_Failure, CPLE_NotSupported, "Couldn't create raster wrapper, invalid raster hexwkb string"); return FALSE; } /************************************************************************* * Check if raster has enough data *************************************************************************/ nRasterHeaderLen = sizeof (GByte) + 4 * sizeof (GUInt16) + sizeof (GInt32) + 6 * sizeof (double); nBufferDataWithoutHeaderLen = strlen(pszHex +2*nRasterHeaderLen) / 2; pbyHexWkb = CPLHexToBinary(pszHex, &nLengthByWkbString); if (nRasterHeaderLen > nLengthByWkbString || nLengthByWkbString != nRasterHeaderLen + nBufferDataWithoutHeaderLen) { CPLError(CE_Failure, CPLE_ObjectNull, "Raster object is corrupted, not enough data"); return FALSE; } /************************************************************************* * Copy raster as class attribute, and transform it to binary *************************************************************************/ nLengthHexWkbString = strlen(pszHex); pszHexWkb = (char *) VSIMalloc(nLengthHexWkbString); if (pszHexWkb == NULL) { CPLError(CE_Failure, CPLE_ObjectNull, "Couldn't allocate memory for raster wrapper, aborting"); return FALSE; } memcpy(pszHexWkb, pszHex, nLengthHexWkbString * sizeof (GByte)); /*********************************************************************** * Get endianess. This is important, because we could need to swap * words if the data endianess is distinct from machine endianess ***********************************************************************/ memcpy(&byEndianess, pbyHexWkb, sizeof(GByte)); // We are going to use this pointer to move over the string pbyAuxPtr = pbyHexWkb + sizeof (GByte); /************************************************************************* * Parse HexWkb string in binary format and fill the rest of class fields *************************************************************************/ memcpy(&nVersion, pbyAuxPtr, sizeof (GUInt16)); if (byEndianess != byMachineEndianess) GDALSwapWords(&nVersion, sizeof (GUInt16), 1, sizeof (GUInt16)); pbyAuxPtr += sizeof (GUInt16); /** * Check WKT Raster version */ if (nVersion != WKT_RASTER_VERSION) { CPLError(CE_Failure, CPLE_NotSupported, "WKT Raster version not supported (%d). Supported raster\ version is %d\n", nVersion, WKT_RASTER_VERSION); return FALSE; }
CPLErr BTRasterBand::IWriteBlock( int nBlockXOff, CPL_UNUSED int nBlockYOff, void * pImage ) { CPLAssert( nBlockYOff == 0 ); const int nDataSize = GDALGetDataTypeSizeBytes( eDataType ); /* -------------------------------------------------------------------- */ /* Seek to profile. */ /* -------------------------------------------------------------------- */ if( VSIFSeekL( fpImage, 256 + nBlockXOff * nDataSize * nRasterYSize, SEEK_SET ) != 0 ) { CPLError( CE_Failure, CPLE_FileIO, ".bt Seek failed:%s", VSIStrerror( errno ) ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Allocate working buffer. */ /* -------------------------------------------------------------------- */ GByte *pabyWrkBlock = static_cast<GByte *>( CPLMalloc(nDataSize * nRasterYSize) ); /* -------------------------------------------------------------------- */ /* Vertical flip data into work buffer, since GDAL expects */ /* values from top to bottom, but in .bt they are bottom to */ /* top. */ /* -------------------------------------------------------------------- */ for( int i = 0; i < nRasterYSize; i++ ) { memcpy( pabyWrkBlock + (nRasterYSize - i - 1) * nDataSize, reinterpret_cast<GByte *>(pImage) + i * nDataSize, nDataSize ); } /* -------------------------------------------------------------------- */ /* Swap on MSB platforms. */ /* -------------------------------------------------------------------- */ #ifdef CPL_MSB GDALSwapWords( pabyWrkBlock, nDataSize, nRasterYSize, nDataSize ); #endif /* -------------------------------------------------------------------- */ /* Read the profile. */ /* -------------------------------------------------------------------- */ if( VSIFWriteL( pabyWrkBlock, nDataSize, nRasterYSize, fpImage ) != static_cast<size_t>( nRasterYSize ) ) { CPLFree( pabyWrkBlock ); CPLError( CE_Failure, CPLE_FileIO, ".bt Write failed:%s", VSIStrerror( errno ) ); return CE_Failure; } CPLFree( pabyWrkBlock ); return CE_None; }
GDALDataset * SRTMHGTDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** /* papszOptions*/, GDALProgressFunc pfnProgress, void * pProgressData ) { /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ const int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "SRTMHGT driver does not support source dataset with zero band.\n"); return nullptr; } else if (nBands != 1) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "SRTMHGT driver only uses the first band of the dataset.\n"); if (bStrict) return nullptr; } /* -------------------------------------------------------------------- */ /* Checks the input SRS */ /* -------------------------------------------------------------------- */ OGRSpatialReference ogrsr_input; ogrsr_input.importFromWkt(poSrcDS->GetProjectionRef()); OGRSpatialReference ogrsr_wgs84; ogrsr_wgs84.SetWellKnownGeogCS( "WGS84" ); if ( ogrsr_input.IsSameGeogCS(&ogrsr_wgs84) == FALSE) { CPLError( CE_Warning, CPLE_AppDefined, "The source projection coordinate system is %s. Only WGS 84 " "is supported.\nThe SRTMHGT driver will generate a file as " "if the source was WGS 84 projection coordinate system.", poSrcDS->GetProjectionRef() ); } /* -------------------------------------------------------------------- */ /* Work out the LL origin. */ /* -------------------------------------------------------------------- */ double adfGeoTransform[6]; if (poSrcDS->GetGeoTransform( adfGeoTransform ) != CE_None) { CPLError( CE_Failure, CPLE_AppDefined, "Source image must have a geo transform matrix."); return nullptr; } const int nLLOriginLat = static_cast<int>( std::floor(adfGeoTransform[3] + poSrcDS->GetRasterYSize() * adfGeoTransform[5] + 0.5) ); int nLLOriginLong = static_cast<int>( std::floor(adfGeoTransform[0] + 0.5) ); if (std::abs(nLLOriginLat - ( adfGeoTransform[3] + (poSrcDS->GetRasterYSize() - 0.5 ) * adfGeoTransform[5] ) ) > 1e-10 || std::abs(nLLOriginLong - ( adfGeoTransform[0] + 0.5 * adfGeoTransform[1])) > 1e-10 ) { CPLError( CE_Warning, CPLE_AppDefined, "The corner coordinates of the source are not properly " "aligned on plain latitude/longitude boundaries."); } /* -------------------------------------------------------------------- */ /* Check image dimensions. */ /* -------------------------------------------------------------------- */ const int nXSize = poSrcDS->GetRasterXSize(); const int nYSize = poSrcDS->GetRasterYSize(); if (!((nXSize == 1201 && nYSize == 1201) || (nXSize == 3601 && nYSize == 3601) || (nXSize == 1801 && nYSize == 3601))) { CPLError( CE_Failure, CPLE_AppDefined, "Image dimensions should be 1201x1201, 3601x3601 or 1801x3601."); return nullptr; } /* -------------------------------------------------------------------- */ /* Check filename. */ /* -------------------------------------------------------------------- */ char expectedFileName[12]; CPLsnprintf(expectedFileName, sizeof(expectedFileName), "%c%02d%c%03d.HGT", (nLLOriginLat >= 0) ? 'N' : 'S', (nLLOriginLat >= 0) ? nLLOriginLat : -nLLOriginLat, (nLLOriginLong >= 0) ? 'E' : 'W', (nLLOriginLong >= 0) ? nLLOriginLong : -nLLOriginLong); if (!EQUAL(expectedFileName, CPLGetFilename(pszFilename))) { CPLError( CE_Warning, CPLE_AppDefined, "Expected output filename is %s.", expectedFileName); } /* -------------------------------------------------------------------- */ /* Write output file. */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(pszFilename, "wb"); if (fp == nullptr) { CPLError( CE_Failure, CPLE_FileIO, "Cannot create file %s", pszFilename ); return nullptr; } GInt16* panData = reinterpret_cast<GInt16 *>( CPLMalloc(sizeof(GInt16) * nXSize) ); GDALRasterBand* poSrcBand = poSrcDS->GetRasterBand(1); int bSrcBandHasNoData; double srcBandNoData = poSrcBand->GetNoDataValue(&bSrcBandHasNoData); for( int iY = 0; iY < nYSize; iY++ ) { if( poSrcBand->RasterIO( GF_Read, 0, iY, nXSize, 1, reinterpret_cast<void *>( panData ), nXSize, 1, GDT_Int16, 0, 0, nullptr ) != CE_None ) { VSIFCloseL(fp); CPLFree( panData ); return nullptr; } /* Translate nodata values */ if (bSrcBandHasNoData && srcBandNoData != SRTMHG_NODATA_VALUE) { for( int iX = 0; iX < nXSize; iX++ ) { if (panData[iX] == srcBandNoData) panData[iX] = SRTMHG_NODATA_VALUE; } } #ifdef CPL_LSB GDALSwapWords(panData, 2, nXSize, 2); #endif if( VSIFWriteL( panData,sizeof(GInt16) * nXSize,1,fp ) != 1) { CPLError( CE_Failure, CPLE_FileIO, "Failed to write line %d in SRTMHGT dataset.\n", iY ); VSIFCloseL(fp); CPLFree( panData ); return nullptr; } if( pfnProgress && !pfnProgress( (iY+1) / static_cast<double>( nYSize ), nullptr, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated CreateCopy()" ); VSIFCloseL(fp); CPLFree( panData ); return nullptr; } } CPLFree( panData ); VSIFCloseL(fp); /* -------------------------------------------------------------------- */ /* Reopen and copy missing information into a PAM file. */ /* -------------------------------------------------------------------- */ GDALPamDataset *poDS = reinterpret_cast<GDALPamDataset *>( GDALOpen( pszFilename, GA_ReadOnly ) ); if( poDS ) poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT); return poDS; }
CPLErr HF2RasterBand::IReadBlock( int nBlockXOff, int nLineYOff, void * pImage ) { HF2Dataset *poGDS = (HF2Dataset *) poDS; // NOTE: the use of nBlockXSize for the y dimensions is intended const int nXBlocks = DIV_ROUND_UP(nRasterXSize, nBlockXSize); const int nYBlocks = DIV_ROUND_UP(nRasterYSize, nBlockXSize); if (!poGDS->LoadBlockMap()) return CE_Failure; if (pafBlockData == NULL) { pafBlockData = (float*)VSIMalloc3(nXBlocks * sizeof(float), poGDS->nTileSize, poGDS->nTileSize); if (pafBlockData == NULL) return CE_Failure; } nLineYOff = nRasterYSize - 1 - nLineYOff; const int nBlockYOff = nLineYOff / nBlockXSize; const int nYOffInTile = nLineYOff % nBlockXSize; if (nBlockYOff != nLastBlockYOff) { nLastBlockYOff = nBlockYOff; memset(pafBlockData, 0, nXBlocks * sizeof(float) * nBlockXSize * nBlockXSize); /* 4 * nBlockXSize is the upper bound */ void* pabyData = CPLMalloc( 4 * nBlockXSize ); for(int nxoff = 0; nxoff < nXBlocks; nxoff++) { VSIFSeekL(poGDS->fp, poGDS->panBlockOffset[(nYBlocks - 1 - nBlockYOff) * nXBlocks + nxoff], SEEK_SET); float fScale, fOff; VSIFReadL(&fScale, 4, 1, poGDS->fp); VSIFReadL(&fOff, 4, 1, poGDS->fp); CPL_LSBPTR32(&fScale); CPL_LSBPTR32(&fOff); const int nTileWidth = MIN(nBlockXSize, nRasterXSize - nxoff * nBlockXSize); const int nTileHeight = MIN(nBlockXSize, nRasterYSize - nBlockYOff * nBlockXSize); for(int j=0;j<nTileHeight;j++) { GByte nWordSize; VSIFReadL(&nWordSize, 1, 1, poGDS->fp); if (nWordSize != 1 && nWordSize != 2 && nWordSize != 4) { CPLError(CE_Failure, CPLE_AppDefined, "Unexpected word size : %d", (int)nWordSize); break; } GInt32 nVal; VSIFReadL(&nVal, 4, 1, poGDS->fp); CPL_LSBPTR32(&nVal); if( VSIFReadL(pabyData, static_cast<size_t>(nWordSize * (nTileWidth - 1)), 1, poGDS->fp) != 1 ) { CPLError(CE_Failure, CPLE_FileIO, "File too short"); CPLFree(pabyData); return CE_Failure; } #if defined(CPL_MSB) if (nWordSize > 1) GDALSwapWords(pabyData, nWordSize, nTileWidth - 1, nWordSize); #endif double dfVal = nVal * (double)fScale + fOff; if( dfVal > std::numeric_limits<float>::max() ) dfVal = std::numeric_limits<float>::max(); else if( dfVal < std::numeric_limits<float>::min() ) dfVal = std::numeric_limits<float>::min(); pafBlockData[nxoff * nBlockXSize * nBlockXSize + j * nBlockXSize + 0] = static_cast<float>(dfVal); for(int i=1;i<nTileWidth;i++) { int nInc; if (nWordSize == 1) nInc = ((signed char*)pabyData)[i-1]; else if (nWordSize == 2) nInc = ((GInt16*)pabyData)[i-1]; else nInc = ((GInt32*)pabyData)[i-1]; if( (nInc >= 0 && nVal > INT_MAX - nInc) || (nInc == INT_MIN && nVal < 0) || (nInc < 0 && nVal < INT_MIN - nInc ) ) { CPLError(CE_Failure, CPLE_FileIO, "int32 overflow"); CPLFree(pabyData); return CE_Failure; } nVal += nInc; dfVal = nVal * (double)fScale + fOff; if( dfVal > std::numeric_limits<float>::max() ) dfVal = std::numeric_limits<float>::max(); else if( dfVal < std::numeric_limits<float>::min() ) dfVal = std::numeric_limits<float>::min(); pafBlockData[nxoff * nBlockXSize * nBlockXSize + j * nBlockXSize + i] = static_cast<float>(dfVal); } } } CPLFree(pabyData); } const int nTileWidth = MIN(nBlockXSize, nRasterXSize - nBlockXOff * nBlockXSize); memcpy(pImage, pafBlockData + nBlockXOff * nBlockXSize * nBlockXSize + nYOffInTile * nBlockXSize, nTileWidth * sizeof(float)); return CE_None; }
/***************************************************** * \brief Read a natural block of raster band data *****************************************************/ CPLErr PostGISRasterTileRasterBand::IReadBlock(CPL_UNUSED int nBlockXOff, CPL_UNUSED int nBlockYOff, void * pImage) { CPLString osCommand; PGresult * poResult = NULL; int nWKBLength = 0; int nPixelSize = GDALGetDataTypeSize(eDataType)/8; PostGISRasterTileDataset * poRTDS = (PostGISRasterTileDataset *)poDS; // Get by PKID if (poRTDS->poRDS->pszPrimaryKeyName) { osCommand.Printf("select st_band(%s, %d) from %s.%s where " "%s = '%s'", poRTDS->poRDS->pszColumn, nBand, poRTDS->poRDS->pszSchema, poRTDS->poRDS->pszTable, poRTDS->poRDS->pszPrimaryKeyName, poRTDS->pszPKID); } // Get by upperleft else { osCommand.Printf("select st_band(%s, %d) from %s.%s where " "abs(ST_UpperLeftX(%s) - %.8f) < 1e-8 and abs(ST_UpperLeftY(%s) - %.8f) < 1e-8", poRTDS->poRDS->pszColumn, nBand, poRTDS->poRDS->pszSchema, poRTDS->poRDS->pszTable, poRTDS->poRDS->pszColumn, poRTDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_X], poRTDS->poRDS->pszColumn, poRTDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_Y]); } poResult = PQexec(poRTDS->poRDS->poConn, osCommand.c_str()); #ifdef DEBUG_QUERY CPLDebug("PostGIS_Raster", "PostGISRasterTileRasterBand::IReadBlock(): " "Query = \"%s\" --> number of rows = %d", osCommand.c_str(), poResult ? PQntuples(poResult) : 0 ); #endif if (poResult == NULL || PQresultStatus(poResult) != PGRES_TUPLES_OK || PQntuples(poResult) <= 0) { if (poResult) PQclear(poResult); ReportError(CE_Failure, CPLE_AppDefined, "Error getting block of data (upperpixel = %f, %f)", poRTDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_X], poRTDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_Y]); return CE_Failure; } // TODO: Check this if (bIsOffline) { CPLError(CE_Failure, CPLE_AppDefined, "This raster has outdb " "storage. This feature isn't still available"); PQclear(poResult); return CE_Failure; } /* Copy only data size, without payload */ int nExpectedDataSize = nBlockXSize * nBlockYSize * nPixelSize; GByte * pbyData = CPLHexToBinary(PQgetvalue(poResult, 0, 0), &nWKBLength); int nExpectedWKBLength = RASTER_HEADER_SIZE + BAND_SIZE(nPixelSize, nExpectedDataSize); CPLErr eRet = CE_None; if( nWKBLength != nExpectedWKBLength ) { CPLDebug("PostGIS_Raster", "nWKBLength=%d, nExpectedWKBLength=%d", nWKBLength, nExpectedWKBLength ); eRet = CE_Failure; } else { GByte * pbyDataToRead = (GByte*)GET_BAND_DATA(pbyData,1, nPixelSize, nExpectedDataSize); // Do byte-swapping if necessary */ int bIsLittleEndian = (pbyData[0] == 1); #ifdef CPL_LSB int bSwap = !bIsLittleEndian; #else int bSwap = bIsLittleEndian; #endif if( bSwap && nPixelSize > 1 ) { GDALSwapWords( pbyDataToRead, nPixelSize, nBlockXSize * nBlockYSize, nPixelSize ); } memcpy(pImage, pbyDataToRead, nExpectedDataSize); } CPLFree(pbyData); PQclear(poResult); return eRet; }