CPLXMLNode * PamFindMatchingHistogram( CPLXMLNode *psSavedHistograms, double dfMin, double dfMax, int nBuckets, int bIncludeOutOfRange, int bApproxOK ) { if( psSavedHistograms == nullptr ) return nullptr; for( CPLXMLNode *psXMLHist = psSavedHistograms->psChild; psXMLHist != nullptr; psXMLHist = psXMLHist->psNext ) { if( psXMLHist->eType != CXT_Element || !EQUAL(psXMLHist->pszValue,"HistItem") ) continue; const double dfHistMin = CPLAtofM(CPLGetXMLValue( psXMLHist, "HistMin", "0")); const double dfHistMax = CPLAtofM(CPLGetXMLValue( psXMLHist, "HistMax", "0")); if( !(ARE_REAL_EQUAL(dfHistMin, dfMin) ) || !(ARE_REAL_EQUAL(dfHistMax, dfMax) ) || atoi(CPLGetXMLValue( psXMLHist, "BucketCount","0")) != nBuckets || !atoi(CPLGetXMLValue( psXMLHist, "IncludeOutOfRange","0")) != !bIncludeOutOfRange || (!bApproxOK && atoi(CPLGetXMLValue( psXMLHist, "Approximate","0"))) ) continue; return psXMLHist; } return nullptr; }
CPLErr GDALNoDataMaskBand::IReadBlock( int nXBlockOff, int nYBlockOff, void * pImage ) { GDALDataType eWrkDT = GDT_Unknown; /* -------------------------------------------------------------------- */ /* Decide on a working type. */ /* -------------------------------------------------------------------- */ switch( poParent->GetRasterDataType() ) { case GDT_Byte: eWrkDT = GDT_Byte; break; case GDT_UInt16: case GDT_UInt32: eWrkDT = GDT_UInt32; break; case GDT_Int16: case GDT_Int32: case GDT_CInt16: case GDT_CInt32: eWrkDT = GDT_Int32; break; case GDT_Float32: case GDT_CFloat32: eWrkDT = GDT_Float32; break; case GDT_Float64: case GDT_CFloat64: eWrkDT = GDT_Float64; break; default: CPLAssert( false ); eWrkDT = GDT_Float64; break; } /* -------------------------------------------------------------------- */ /* Read the image data. */ /* -------------------------------------------------------------------- */ // TODO(schwehr): pabySrc would probably be better as a void ptr. GByte *pabySrc = static_cast<GByte *>( VSI_MALLOC3_VERBOSE( GDALGetDataTypeSizeBytes(eWrkDT), nBlockXSize, nBlockYSize ) ); if (pabySrc == nullptr) { return CE_Failure; } int nXSizeRequest = nBlockXSize; if (nXBlockOff * nBlockXSize + nBlockXSize > nRasterXSize) nXSizeRequest = nRasterXSize - nXBlockOff * nBlockXSize; int nYSizeRequest = nBlockYSize; if (nYBlockOff * nBlockYSize + nBlockYSize > nRasterYSize) nYSizeRequest = nRasterYSize - nYBlockOff * nBlockYSize; if (nXSizeRequest != nBlockXSize || nYSizeRequest != nBlockYSize) { // memset the whole buffer to avoid Valgrind warnings in case RasterIO // fetches a partial block. memset( pabySrc, 0, GDALGetDataTypeSizeBytes(eWrkDT) * nBlockXSize * nBlockYSize ); } CPLErr eErr = poParent->RasterIO( GF_Read, nXBlockOff * nBlockXSize, nYBlockOff * nBlockYSize, nXSizeRequest, nYSizeRequest, pabySrc, nXSizeRequest, nYSizeRequest, eWrkDT, 0, nBlockXSize * GDALGetDataTypeSizeBytes(eWrkDT), nullptr ); if( eErr != CE_None ) { CPLFree(pabySrc); return eErr; } const bool bIsNoDataNan = CPLIsNan(dfNoDataValue) != 0; /* -------------------------------------------------------------------- */ /* Process different cases. */ /* -------------------------------------------------------------------- */ switch( eWrkDT ) { case GDT_Byte: { if( !GDALIsValueInRange<GByte>(dfNoDataValue) ) { memset(pImage, 255, nBlockXSize * nBlockYSize); } else { GByte byNoData = static_cast<GByte>( dfNoDataValue ); for( int i = 0; i < nBlockXSize * nBlockYSize; i++ ) { static_cast<GByte *>(pImage)[i] = pabySrc[i] == byNoData ? 0: 255; } } } break; case GDT_UInt32: { if( !GDALIsValueInRange<GUInt32>(dfNoDataValue) ) { memset(pImage, 255, nBlockXSize * nBlockYSize); } else { GUInt32 nNoData = static_cast<GUInt32>( dfNoDataValue ); for( int i = 0; i < nBlockXSize * nBlockYSize; i++ ) { static_cast<GByte *>(pImage)[i] = reinterpret_cast<GUInt32 *>(pabySrc)[i] == nNoData ? 0 : 255; } } } break; case GDT_Int32: { if( !GDALIsValueInRange<GInt32>(dfNoDataValue) ) { memset(pImage, 255, nBlockXSize * nBlockYSize); } else { GInt32 nNoData = static_cast<GInt32>( dfNoDataValue ); for( int i = 0; i < nBlockXSize * nBlockYSize; i++ ) { static_cast<GByte *>(pImage)[i] = reinterpret_cast<GInt32 *>(pabySrc)[i] == nNoData ? 0 : 255; } } } break; case GDT_Float32: { if( !bIsNoDataNan && !CPLIsInf(dfNoDataValue) && !GDALIsValueInRange<float>(dfNoDataValue) ) { memset(pImage, 255, nBlockXSize * nBlockYSize); } else { float fNoData = static_cast<float>( dfNoDataValue ); for( int i = 0; i < nBlockXSize * nBlockYSize; i++ ) { const float fVal = reinterpret_cast<float *>(pabySrc)[i]; if( bIsNoDataNan && CPLIsNan(fVal)) static_cast<GByte *>(pImage)[i] = 0; else if( ARE_REAL_EQUAL(fVal, fNoData) ) static_cast<GByte *>(pImage)[i] = 0; else static_cast<GByte *>(pImage)[i] = 255; } } } break; case GDT_Float64: { for( int i = 0; i < nBlockXSize * nBlockYSize; i++ ) { const double dfVal = reinterpret_cast<double *>(pabySrc)[i]; if( bIsNoDataNan && CPLIsNan(dfVal)) static_cast<GByte *>(pImage)[i] = 0; else if( ARE_REAL_EQUAL(dfVal, dfNoDataValue) ) static_cast<GByte *>(pImage)[i] = 0; else static_cast<GByte *>(pImage)[i] = 255; } } break; default: CPLAssert( false ); break; } CPLFree( pabySrc ); return CE_None; }
CPLErr GDALNoDataMaskBand::IReadBlock( int nXBlockOff, int nYBlockOff, void * pImage ) { GDALDataType eWrkDT; /* -------------------------------------------------------------------- */ /* Decide on a working type. */ /* -------------------------------------------------------------------- */ switch( poParent->GetRasterDataType() ) { case GDT_Byte: eWrkDT = GDT_Byte; break; case GDT_UInt16: case GDT_UInt32: eWrkDT = GDT_UInt32; break; case GDT_Int16: case GDT_Int32: case GDT_CInt16: case GDT_CInt32: eWrkDT = GDT_Int32; break; case GDT_Float32: case GDT_CFloat32: eWrkDT = GDT_Float32; break; case GDT_Float64: case GDT_CFloat64: eWrkDT = GDT_Float64; break; default: CPLAssert( FALSE ); eWrkDT = GDT_Float64; break; } /* -------------------------------------------------------------------- */ /* Read the image data. */ /* -------------------------------------------------------------------- */ GByte *pabySrc; CPLErr eErr; pabySrc = (GByte *) VSIMalloc3( GDALGetDataTypeSize(eWrkDT)/8, nBlockXSize, nBlockYSize ); if (pabySrc == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "GDALNoDataMaskBand::IReadBlock: Out of memory for buffer." ); return CE_Failure; } int nXSizeRequest = nBlockXSize; if (nXBlockOff * nBlockXSize + nBlockXSize > nRasterXSize) nXSizeRequest = nRasterXSize - nXBlockOff * nBlockXSize; int nYSizeRequest = nBlockYSize; if (nYBlockOff * nBlockYSize + nBlockYSize > nRasterYSize) nYSizeRequest = nRasterYSize - nYBlockOff * nBlockYSize; if (nXSizeRequest != nBlockXSize || nYSizeRequest != nBlockYSize) { /* memset the whole buffer to avoid Valgrind warnings in case we can't */ /* fetch a full block */ memset(pabySrc, 0, GDALGetDataTypeSize(eWrkDT)/8 * nBlockXSize * nBlockYSize ); } eErr = poParent->RasterIO( GF_Read, nXBlockOff * nBlockXSize, nYBlockOff * nBlockYSize, nXSizeRequest, nYSizeRequest, pabySrc, nXSizeRequest, nYSizeRequest, eWrkDT, 0, nBlockXSize * (GDALGetDataTypeSize(eWrkDT)/8), NULL ); if( eErr != CE_None ) { CPLFree(pabySrc); return eErr; } int bIsNoDataNan = CPLIsNan(dfNoDataValue); /* -------------------------------------------------------------------- */ /* Process different cases. */ /* -------------------------------------------------------------------- */ int i; switch( eWrkDT ) { case GDT_Byte: { GByte byNoData = (GByte) dfNoDataValue; for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- ) { if( pabySrc[i] == byNoData ) ((GByte *) pImage)[i] = 0; else ((GByte *) pImage)[i] = 255; } } break; case GDT_UInt32: { GUInt32 nNoData = (GUInt32) dfNoDataValue; for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- ) { if( ((GUInt32 *)pabySrc)[i] == nNoData ) ((GByte *) pImage)[i] = 0; else ((GByte *) pImage)[i] = 255; } } break; case GDT_Int32: { GInt32 nNoData = (GInt32) dfNoDataValue; for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- ) { if( ((GInt32 *)pabySrc)[i] == nNoData ) ((GByte *) pImage)[i] = 0; else ((GByte *) pImage)[i] = 255; } } break; case GDT_Float32: { float fNoData = (float) dfNoDataValue; for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- ) { float fVal =((float *)pabySrc)[i]; if( bIsNoDataNan && CPLIsNan(fVal)) ((GByte *) pImage)[i] = 0; else if( ARE_REAL_EQUAL(fVal, fNoData) ) ((GByte *) pImage)[i] = 0; else ((GByte *) pImage)[i] = 255; } } break; case GDT_Float64: { for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- ) { double dfVal =((double *)pabySrc)[i]; if( bIsNoDataNan && CPLIsNan(dfVal)) ((GByte *) pImage)[i] = 0; else if( ARE_REAL_EQUAL(dfVal, dfNoDataValue) ) ((GByte *) pImage)[i] = 0; else ((GByte *) pImage)[i] = 255; } } break; default: CPLAssert( FALSE ); break; } CPLFree( pabySrc ); return CE_None; }
static int GDALRPCGetDEMHeight( GDALRPCTransformInfo *psTransform, double dfX, double dfY, double* pdfDEMH ) { int bGotNoDataValue = FALSE; double dfNoDataValue = 0; int nRasterXSize = psTransform->poDS->GetRasterXSize(); int nRasterYSize = psTransform->poDS->GetRasterYSize(); dfNoDataValue = psTransform->poDS->GetRasterBand(1)->GetNoDataValue( &bGotNoDataValue ); int bands[1] = {1}; int dX = int(dfX); int dY = int(dfY); double dfDEMH(0); double dfDeltaX = dfX - dX; double dfDeltaY = dfY - dY; if(psTransform->eResampleAlg == DRA_Cubic) { int dXNew = dX - 1; int dYNew = dY - 1; if (!(dXNew >= 0 && dYNew >= 0 && dXNew + 4 <= nRasterXSize && dYNew + 4 <= nRasterYSize)) { return FALSE; } //cubic interpolation double adfElevData[16] = {0}; CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dXNew, dYNew, 4, 4, &adfElevData, 4, 4, GDT_Float64, 1, bands, 0, 0, 0); if(eErr != CE_None) { return FALSE; } double dfSumH(0), dfSumWeight(0); for ( int k_i = 0; k_i < 4; k_i++ ) { // Loop across the X axis for ( int k_j = 0; k_j < 4; k_j++ ) { // Calculate the weight for the specified pixel according // to the bicubic b-spline kernel we're using for // interpolation int dKernIndX = k_j - 1; int dKernIndY = k_i - 1; double dfPixelWeight = BiCubicKernel(dKernIndX - dfDeltaX) * BiCubicKernel(dKernIndY - dfDeltaY); // Create a sum of all values // adjusted for the pixel's calculated weight double dfElev = adfElevData[k_j + k_i * 4]; if( bGotNoDataValue && ARE_REAL_EQUAL(dfNoDataValue, dfElev) ) continue; dfSumH += dfElev * dfPixelWeight; dfSumWeight += dfPixelWeight; } } if( dfSumWeight == 0.0 ) { return FALSE; } dfDEMH = dfSumH / dfSumWeight; } else if(psTransform->eResampleAlg == DRA_Bilinear) { if (!(dX >= 0 && dY >= 0 && dX + 2 <= nRasterXSize && dY + 2 <= nRasterYSize)) { return FALSE; } //bilinear interpolation double adfElevData[4] = {0,0,0,0}; CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 2, 2, &adfElevData, 2, 2, GDT_Float64, 1, bands, 0, 0, 0); if(eErr != CE_None) { return FALSE; } if( bGotNoDataValue ) { // TODO: we could perhaps use a valid sample if there's one int bFoundNoDataElev = FALSE; for(int k_i=0; k_i<4; k_i++) { if( ARE_REAL_EQUAL(dfNoDataValue, adfElevData[k_i]) ) bFoundNoDataElev = TRUE; } if( bFoundNoDataElev ) { return FALSE; } } double dfDeltaX1 = 1.0 - dfDeltaX; double dfDeltaY1 = 1.0 - dfDeltaY; double dfXZ1 = adfElevData[0] * dfDeltaX1 + adfElevData[1] * dfDeltaX; double dfXZ2 = adfElevData[2] * dfDeltaX1 + adfElevData[3] * dfDeltaX; double dfYZ = dfXZ1 * dfDeltaY1 + dfXZ2 * dfDeltaY; dfDEMH = dfYZ; } else { if (!(dX >= 0 && dY >= 0 && dX < nRasterXSize && dY < nRasterYSize)) { return FALSE; } CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 1, 1, &dfDEMH, 1, 1, GDT_Float64, 1, bands, 0, 0, 0); if(eErr != CE_None || (bGotNoDataValue && ARE_REAL_EQUAL(dfNoDataValue, dfDEMH)) ) { return FALSE; } } *pdfDEMH = dfDEMH; return TRUE; }