29 #ifndef GDAL_CACHED_PIXEL_ACCESSOR_INCLUDED
30 #define GDAL_CACHED_PIXEL_ACCESSOR_INCLUDED
51 template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT = 4>
58 std::vector<Type> m_data{};
61 bool m_bModified =
false;
64 int m_nCachedTileCount = 0;
65 std::array<CachedTile, CACHED_TILE_COUNT> m_aCachedTiles{};
67 bool LoadTile(
int nTileX,
int nTileY);
68 bool FlushTile(
int iSlot);
70 Type GetSlowPath(
int nTileX,
int nTileY,
int nXInTile,
int nYInTile,
72 bool SetSlowPath(
int nTileX,
int nTileY,
int nXInTile,
int nYInTile,
89 Type
Get(
int nX,
int nY,
bool *pbSuccess =
nullptr);
90 bool Set(
int nX,
int nY, Type val);
112 template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
127 template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
129 CACHED_TILE_COUNT>::~GDALCachedPixelAccessor()
147 template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
149 int nX,
int nY,
bool *pbSuccess)
151 const int nTileX = nX / TILE_SIZE;
152 const int nTileY = nY / TILE_SIZE;
153 const int nXInTile = nX % TILE_SIZE;
154 const int nYInTile = nY % TILE_SIZE;
155 if (m_aCachedTiles[0].m_nTileX == nTileX &&
156 m_aCachedTiles[0].m_nTileY == nTileY)
160 return m_aCachedTiles[0].m_data[nYInTile * TILE_SIZE + nXInTile];
162 return GetSlowPath(nTileX, nTileY, nXInTile, nYInTile, pbSuccess);
169 template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
171 int nTileX,
int nTileY,
int nXInTile,
int nYInTile,
bool *pbSuccess)
173 for (
int i = 1; i < m_nCachedTileCount; ++i)
175 const auto &cachedTile = m_aCachedTiles[i];
176 if (cachedTile.m_nTileX == nTileX && cachedTile.m_nTileY == nTileY)
178 const auto ret = cachedTile.m_data[nYInTile * TILE_SIZE + nXInTile];
179 CachedTile tmp = std::move(m_aCachedTiles[i]);
180 for (
int j = i; j >= 1; --j)
181 m_aCachedTiles[j] = std::move(m_aCachedTiles[j - 1]);
182 m_aCachedTiles[0] = std::move(tmp);
188 if (!LoadTile(nTileX, nTileY))
196 return m_aCachedTiles[0].m_data[nYInTile * TILE_SIZE + nXInTile];
219 template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
224 const int nTileX = nX / TILE_SIZE;
225 const int nTileY = nY / TILE_SIZE;
226 const int nXInTile = nX % TILE_SIZE;
227 const int nYInTile = nY % TILE_SIZE;
228 if (m_aCachedTiles[0].m_nTileX == nTileX &&
229 m_aCachedTiles[0].m_nTileY == nTileY)
231 m_aCachedTiles[0].m_data[nYInTile * TILE_SIZE + nXInTile] = val;
232 m_aCachedTiles[0].m_bModified =
true;
235 return SetSlowPath(nTileX, nTileY, nXInTile, nYInTile, val);
242 template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
244 int nTileX,
int nTileY,
int nXInTile,
int nYInTile, Type val)
246 for (
int i = 1; i < m_nCachedTileCount; ++i)
248 auto &cachedTile = m_aCachedTiles[i];
249 if (cachedTile.m_nTileX == nTileX && cachedTile.m_nTileY == nTileY)
251 cachedTile.m_data[nYInTile * TILE_SIZE + nXInTile] = val;
252 cachedTile.m_bModified =
true;
255 CachedTile tmp = std::move(m_aCachedTiles[i]);
256 for (
int j = i; j >= 1; --j)
257 m_aCachedTiles[j] = std::move(m_aCachedTiles[j - 1]);
258 m_aCachedTiles[0] = std::move(tmp);
263 if (!LoadTile(nTileX, nTileY))
267 m_aCachedTiles[0].m_data[nYInTile * TILE_SIZE + nXInTile] = val;
268 m_aCachedTiles[0].m_bModified =
true;
280 template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
284 for (
int i = 0; i < m_nCachedTileCount; ++i)
288 m_aCachedTiles[i].m_nTileX = -1;
289 m_aCachedTiles[i].m_nTileY = -1;
300 template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
302 CACHED_TILE_COUNT>::ResetModifiedFlag()
304 for (
int i = 0; i < m_nCachedTileCount; ++i)
306 m_aCachedTiles[i].m_bModified =
false;
315 template <
class T>
struct GDALCachedPixelAccessorGetDataType
319 template <>
struct GDALCachedPixelAccessorGetDataType<
GByte>
324 template <>
struct GDALCachedPixelAccessorGetDataType<
GInt8>
329 template <>
struct GDALCachedPixelAccessorGetDataType<
GUInt16>
334 template <>
struct GDALCachedPixelAccessorGetDataType<
GInt16>
339 template <>
struct GDALCachedPixelAccessorGetDataType<
GUInt32>
344 template <>
struct GDALCachedPixelAccessorGetDataType<
GInt32>
348 #if SIZEOF_UNSIGNED_LONG == 8
350 template <>
struct GDALCachedPixelAccessorGetDataType<unsigned long>
355 template <>
struct GDALCachedPixelAccessorGetDataType<long>
360 template <>
struct GDALCachedPixelAccessorGetDataType<
GUInt64>
365 template <>
struct GDALCachedPixelAccessorGetDataType<
GInt64>
370 template <>
struct GDALCachedPixelAccessorGetDataType<float>
375 template <>
struct GDALCachedPixelAccessorGetDataType<double>
386 template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
388 int nTileX,
int nTileY)
390 if (m_nCachedTileCount == CACHED_TILE_COUNT)
392 if (!FlushTile(CACHED_TILE_COUNT - 1))
394 CachedTile tmp = std::move(m_aCachedTiles[CACHED_TILE_COUNT - 1]);
395 for (
int i = CACHED_TILE_COUNT - 1; i >= 1; --i)
396 m_aCachedTiles[i] = std::move(m_aCachedTiles[i - 1]);
397 m_aCachedTiles[0] = std::move(tmp);
401 if (m_nCachedTileCount > 0)
402 std::swap(m_aCachedTiles[0], m_aCachedTiles[m_nCachedTileCount]);
403 m_aCachedTiles[0].m_data.resize(TILE_SIZE * TILE_SIZE);
404 m_nCachedTileCount++;
408 CPLDebug(
"GDAL",
"Load tile(%d, %d) of band %d of dataset %s",
409 nTileX, nTileY, m_poBand->GetBand(),
410 m_poBand->GetDataset() ? m_poBand->GetDataset()->GetDescription() :
"(unknown)");
412 CPLAssert(!m_aCachedTiles[0].m_bModified);
413 const int nXOff = nTileX * TILE_SIZE;
414 const int nYOff = nTileY * TILE_SIZE;
415 const int nReqXSize = std::min(m_poBand->GetXSize() - nXOff, TILE_SIZE);
416 const int nReqYSize = std::min(m_poBand->GetYSize() - nYOff, TILE_SIZE);
417 if (m_poBand->RasterIO(
418 GF_Read, nXOff, nYOff, nReqXSize, nReqYSize,
419 m_aCachedTiles[0].m_data.data(), nReqXSize, nReqYSize,
420 GDALCachedPixelAccessorGetDataType<Type>::DataType,
sizeof(Type),
421 TILE_SIZE *
sizeof(Type),
nullptr) != CE_None)
423 m_aCachedTiles[0].m_nTileX = -1;
424 m_aCachedTiles[0].m_nTileY = -1;
427 m_aCachedTiles[0].m_nTileX = nTileX;
428 m_aCachedTiles[0].m_nTileY = nTileY;
436 template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
440 if (!m_aCachedTiles[iSlot].m_bModified)
443 m_aCachedTiles[iSlot].m_bModified =
false;
444 const int nXOff = m_aCachedTiles[iSlot].m_nTileX * TILE_SIZE;
445 const int nYOff = m_aCachedTiles[iSlot].m_nTileY * TILE_SIZE;
446 const int nReqXSize = std::min(m_poBand->GetXSize() - nXOff, TILE_SIZE);
447 const int nReqYSize = std::min(m_poBand->GetYSize() - nYOff, TILE_SIZE);
448 return m_poBand->RasterIO(
449 GF_Write, nXOff, nYOff, nReqXSize, nReqYSize,
450 m_aCachedTiles[iSlot].m_data.data(), nReqXSize, nReqYSize,
451 GDALCachedPixelAccessorGetDataType<Type>::DataType,
sizeof(Type),
452 TILE_SIZE *
sizeof(Type),
nullptr) == CE_None;
Class to have reasonably fast random pixel access to a raster band, when accessing multiple pixels th...
Definition: gdalcachedpixelaccessor.h:53
bool Set(int nX, int nY, Type val)
Set the value of a pixel.
Definition: gdalcachedpixelaccessor.h:221
bool FlushCache()
Flush content of modified tiles and drop caches.
Definition: gdalcachedpixelaccessor.h:281
void SetBand(GDALRasterBand *poBand)
Assign the raster band if not known at construction time.
Definition: gdalcachedpixelaccessor.h:84
void ResetModifiedFlag()
Reset the modified flag for cached tiles.
Definition: gdalcachedpixelaccessor.h:302
Type Get(int nX, int nY, bool *pbSuccess=nullptr)
Get the value of a pixel.
Definition: gdalcachedpixelaccessor.h:148
~GDALCachedPixelAccessor()
Destructor.
Definition: gdalcachedpixelaccessor.h:129
A single raster band (or channel).
Definition: gdal_priv.h:1504
CPL error handling services.
#define CPLAssert(expr)
Assert on an expression.
Definition: cpl_error.h:225
void CPLDebug(const char *, const char *,...)
Display a debugging message.
Definition: cpl_error.cpp:747
short GInt16
Int16 type.
Definition: cpl_port.h:181
GIntBig GInt64
Signed 64 bit integer type.
Definition: cpl_port.h:236
unsigned int GUInt32
Unsigned int32 type.
Definition: cpl_port.h:177
GUIntBig GUInt64
Unsigned 64 bit integer type.
Definition: cpl_port.h:238
unsigned short GUInt16
Unsigned int16 type.
Definition: cpl_port.h:183
unsigned char GByte
Unsigned byte type.
Definition: cpl_port.h:185
int GInt32
Int32 type.
Definition: cpl_port.h:175
signed char GInt8
Signed int8 type.
Definition: cpl_port.h:187
GDALDataType
Definition: gdal.h:64
@ GDT_UInt32
Definition: gdal.h:70
@ GDT_UInt64
Definition: gdal.h:72
@ GDT_Int64
Definition: gdal.h:73
@ GDT_Byte
Definition: gdal.h:66
@ GDT_Int8
Definition: gdal.h:67
@ GDT_Float64
Definition: gdal.h:75
@ GDT_UInt16
Definition: gdal.h:68
@ GDT_Int16
Definition: gdal.h:69
@ GDT_Int32
Definition: gdal.h:71
@ GDT_Float32
Definition: gdal.h:74
@ GF_Write
Definition: gdal.h:134
@ GF_Read
Definition: gdal.h:133