CPLErr GDALMRFRasterBand::FillBlock(int xblk, int yblk, void *buffer) { vector<GDALRasterBlock *> blocks; for (int i = 0; i < poDS->nBands; i++) { GDALRasterBand *b = poDS->GetRasterBand(i + 1); if (b->GetOverviewCount() && 0 != m_l) b = b->GetOverview(m_l - 1); // Get the other band blocks, keep them around until later if (b == this) { FillBlock(buffer); } else { GDALRasterBlock *poBlock = b->GetLockedBlockRef(xblk, yblk, 1); if (poBlock == nullptr) // Didn't get this block break; FillBlock(poBlock->GetDataRef()); blocks.push_back(poBlock); } } // Drop the locks for blocks we acquired for (int i = 0; i < int(blocks.size()); i++) blocks[i]->DropLock(); return CE_None; }
CPLErr GDALMRFRasterBand::RB(int xblk, int yblk, buf_mgr /*src*/, void *buffer) { vector<GDALRasterBlock *> blocks; for (int i = 0; i < poDS->nBands; i++) { GDALRasterBand *b = poDS->GetRasterBand(i+1); if (b->GetOverviewCount() && m_l) b = b->GetOverview(m_l-1); void *ob = buffer; // Get the other band blocks, keep them around until later if (b != this) { GDALRasterBlock *poBlock = b->GetLockedBlockRef(xblk, yblk, 1); if( poBlock == NULL ) break; ob = poBlock->GetDataRef(); blocks.push_back(poBlock); } // Just the right mix of templates and macros make deinterleaving tidy #define CpySI(T) cpy_stride_in<T> (ob, (T *)poDS->GetPBuffer() + i,\ blockSizeBytes()/sizeof(T), img.pagesize.c) // Page is already in poDS->pbuffer, not empty // There are only four cases, since only the real data type matters switch (GDALGetDataTypeSize(eDataType)/8) { case 1: CpySI(GByte); break; case 2: CpySI(GInt16); break; case 4: CpySI(GInt32); break; case 8: CpySI(GIntBig); break; } } #undef CpySI // Drop the locks we acquired for (int i=0; i < int(blocks.size()); i++) blocks[i]->DropLock(); return CE_None; }
CPLErr VRTWarpedDataset::ProcessBlock( int iBlockX, int iBlockY ) { if( poWarper == NULL ) return CE_Failure; const GDALWarpOptions *psWO = poWarper->GetOptions(); /* -------------------------------------------------------------------- */ /* Allocate block of memory large enough to hold all the bands */ /* for this block. */ /* -------------------------------------------------------------------- */ int iBand; GByte *pabyDstBuffer; int nDstBufferSize; int nWordSize = (GDALGetDataTypeSize(psWO->eWorkingDataType) / 8); // FIXME? : risk of overflow in multiplication if nBlockXSize or nBlockYSize are very large nDstBufferSize = nBlockXSize * nBlockYSize * psWO->nBandCount * nWordSize; pabyDstBuffer = (GByte *) VSIMalloc(nDstBufferSize); if( pabyDstBuffer == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory allocating %d byte buffer in VRTWarpedDataset::ProcessBlock()", nDstBufferSize ); return CE_Failure; } memset( pabyDstBuffer, 0, nDstBufferSize ); /* -------------------------------------------------------------------- */ /* Process INIT_DEST option to initialize the buffer prior to */ /* warping into it. */ /* NOTE:The following code is 99% similar in gdalwarpoperation.cpp and */ /* vrtwarped.cpp. Be careful to keep it in sync ! */ /* -------------------------------------------------------------------- */ const char *pszInitDest = CSLFetchNameValue( psWO->papszWarpOptions, "INIT_DEST" ); if( pszInitDest != NULL && !EQUAL(pszInitDest, "") ) { char **papszInitValues = CSLTokenizeStringComplex( pszInitDest, ",", FALSE, FALSE ); int nInitCount = CSLCount(papszInitValues); for( iBand = 0; iBand < psWO->nBandCount; iBand++ ) { double adfInitRealImag[2]; GByte *pBandData; int nBandSize = nBlockXSize * nBlockYSize * nWordSize; const char *pszBandInit = papszInitValues[MIN(iBand,nInitCount-1)]; if( EQUAL(pszBandInit,"NO_DATA") && psWO->padfDstNoDataReal != NULL ) { adfInitRealImag[0] = psWO->padfDstNoDataReal[iBand]; adfInitRealImag[1] = psWO->padfDstNoDataImag[iBand]; } else { CPLStringToComplex( pszBandInit, adfInitRealImag + 0, adfInitRealImag + 1); } pBandData = ((GByte *) pabyDstBuffer) + iBand * nBandSize; if( psWO->eWorkingDataType == GDT_Byte ) memset( pBandData, MAX(0,MIN(255,(int)adfInitRealImag[0])), nBandSize); else if( adfInitRealImag[0] == 0.0 && adfInitRealImag[1] == 0 ) { memset( pBandData, 0, nBandSize ); } else if( adfInitRealImag[1] == 0.0 ) { GDALCopyWords( &adfInitRealImag, GDT_Float64, 0, pBandData,psWO->eWorkingDataType,nWordSize, nBlockXSize * nBlockYSize ); } else { GDALCopyWords( &adfInitRealImag, GDT_CFloat64, 0, pBandData,psWO->eWorkingDataType,nWordSize, nBlockXSize * nBlockYSize ); } } CSLDestroy( papszInitValues ); } /* -------------------------------------------------------------------- */ /* Warp into this buffer. */ /* -------------------------------------------------------------------- */ CPLErr eErr; eErr = poWarper->WarpRegionToBuffer( iBlockX * nBlockXSize, iBlockY * nBlockYSize, nBlockXSize, nBlockYSize, pabyDstBuffer, psWO->eWorkingDataType ); if( eErr != CE_None ) { VSIFree( pabyDstBuffer ); return eErr; } /* -------------------------------------------------------------------- */ /* Copy out into cache blocks for each band. */ /* -------------------------------------------------------------------- */ for( iBand = 0; iBand < psWO->nBandCount; iBand++ ) { GDALRasterBand *poBand; GDALRasterBlock *poBlock; poBand = GetRasterBand(iBand+1); poBlock = poBand->GetLockedBlockRef( iBlockX, iBlockY, TRUE ); CPLAssert( poBlock != NULL && poBlock->GetDataRef() != NULL ); GDALCopyWords( pabyDstBuffer + iBand*nBlockXSize*nBlockYSize*nWordSize, psWO->eWorkingDataType, nWordSize, poBlock->GetDataRef(), poBlock->GetDataType(), GDALGetDataTypeSize(poBlock->GetDataType())/8, nBlockXSize * nBlockYSize ); poBlock->DropLock(); } VSIFree( pabyDstBuffer ); return CE_None; }