Skip to content

Commit

Permalink
VRTComplexSource::RasterIO(): speed-up pixel copy in more cases
Browse files Browse the repository at this point in the history
  • Loading branch information
rouault committed Sep 16, 2024
1 parent 47bc43b commit 99a17e5
Showing 1 changed file with 71 additions and 9 deletions.
80 changes: 71 additions & 9 deletions frmts/vrt/vrtsources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3080,6 +3080,52 @@ static inline bool hasZeroByte(uint32_t v)
return (((v)-0x01010101U) & ~(v)&0x80808080U) != 0;
}

/************************************************************************/
/* CopyWord() */
/************************************************************************/

template <class SrcType>
static void CopyWord(const SrcType *pSrcVal, GDALDataType eSrcType,
void *pDstVal, GDALDataType eDstType)
{
switch (eDstType)
{
case GDT_Byte:
GDALCopyWord(*pSrcVal, *static_cast<uint8_t *>(pDstVal));
break;
case GDT_Int8:
GDALCopyWord(*pSrcVal, *static_cast<int8_t *>(pDstVal));
break;
case GDT_UInt16:
GDALCopyWord(*pSrcVal, *static_cast<uint16_t *>(pDstVal));
break;
case GDT_Int16:
GDALCopyWord(*pSrcVal, *static_cast<int16_t *>(pDstVal));
break;
case GDT_UInt32:
GDALCopyWord(*pSrcVal, *static_cast<uint32_t *>(pDstVal));
break;
case GDT_Int32:
GDALCopyWord(*pSrcVal, *static_cast<int32_t *>(pDstVal));
break;
case GDT_UInt64:
GDALCopyWord(*pSrcVal, *static_cast<uint64_t *>(pDstVal));
break;
case GDT_Int64:
GDALCopyWord(*pSrcVal, *static_cast<int64_t *>(pDstVal));
break;
case GDT_Float32:
GDALCopyWord(*pSrcVal, *static_cast<float *>(pDstVal));
break;
case GDT_Float64:
GDALCopyWord(*pSrcVal, *static_cast<double *>(pDstVal));
break;
default:
GDALCopyWords(pSrcVal, eSrcType, 0, pDstVal, eDstType, 0, 1);
break;
}
}

/************************************************************************/
/* RasterIOProcessNoData() */
/************************************************************************/
Expand Down Expand Up @@ -3235,8 +3281,8 @@ CPLErr VRTComplexSource::RasterIOProcessNoData(
{
if (paSrcData[idxBuffer] != nNoDataValue)
{
GDALCopyWords(&paSrcData[idxBuffer], eSourceType, 0,
pDstLocation, eBufType, 0, 1);
CopyWord(&paSrcData[idxBuffer], eSourceType, pDstLocation,
eBufType);
}
}
}
Expand All @@ -3256,8 +3302,8 @@ CPLErr VRTComplexSource::RasterIOProcessNoData(
{
// Convert first to the VRTRasterBand data type
// to get its clamping, before outputting to buffer data type
GDALCopyWords(&paSrcData[idxBuffer], eSourceType, 0,
abyTemp, eVRTBandDataType, 0, 1);
CopyWord(&paSrcData[idxBuffer], eSourceType, abyTemp,
eVRTBandDataType);
GDALCopyWords(abyTemp, eVRTBandDataType, 0, pDstLocation,
eBufType, 0, 1);
}
Expand Down Expand Up @@ -3415,6 +3461,12 @@ CPLErr VRTComplexSource::RasterIOInternal(
/* Selectively copy into output buffer with nodata masking, */
/* and/or scaling. */
/* -------------------------------------------------------------------- */

const bool bTwoStepDataTypeConversion =
CPL_TO_BOOL(
GDALDataTypeIsConversionLossy(eWrkDataType, eVRTBandDataType)) &&
!CPL_TO_BOOL(GDALDataTypeIsConversionLossy(eVRTBandDataType, eBufType));

size_t idxBuffer = 0;
for (int iY = 0; iY < nOutYSize; iY++)
{
Expand Down Expand Up @@ -3551,18 +3603,28 @@ CPLErr VRTComplexSource::RasterIOInternal(
255.0f,
std::max(0.0f, static_cast<float>(afResult[0]) + 0.5f)));
}
else if (eBufType == eVRTBandDataType)
else if (!bTwoStepDataTypeConversion)
{
CopyWord<WorkingDT>(afResult, eWrkDataType, pDstLocation,
eBufType);
}
else if (eVRTBandDataType == GDT_Float32 && eBufType == GDT_Float64)
{
GDALCopyWords(afResult, eWrkDataType, 0, pDstLocation, eBufType,
0, 1);
// Particular case of the below 2-step conversion.
// Helps a bit for some geolocation based warping with Sentinel3
// data where the longitude/latitude arrays are Int32 bands,
// rescaled in VRT as Float32 and requested as Float64
float fVal;
GDALCopyWord(afResult[0], fVal);
*reinterpret_cast<double *>(pDstLocation) = fVal;
}
else
{
GByte abyTemp[2 * sizeof(double)];
// Convert first to the VRTRasterBand data type
// to get its clamping, before outputting to buffer data type
GDALCopyWords(afResult, eWrkDataType, 0, abyTemp,
eVRTBandDataType, 0, 1);
CopyWord<WorkingDT>(afResult, eWrkDataType, abyTemp,
eVRTBandDataType);
GDALCopyWords(abyTemp, eVRTBandDataType, 0, pDstLocation,
eBufType, 0, 1);
}
Expand Down

0 comments on commit 99a17e5

Please sign in to comment.