13#ifndef GDAL_CACHED_PIXEL_ACCESSOR_INCLUDED
14#define GDAL_CACHED_PIXEL_ACCESSOR_INCLUDED
35template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT = 4>
42 std::vector<Type> m_data{};
45 bool m_bModified =
false;
48 int m_nCachedTileCount = 0;
49 std::array<CachedTile, CACHED_TILE_COUNT> m_aCachedTiles{};
51 bool LoadTile(
int nTileX,
int nTileY);
52 bool FlushTile(
int iSlot);
54 Type GetSlowPath(
int nTileX,
int nTileY,
int nXInTile,
int nYInTile,
56 bool SetSlowPath(
int nTileX,
int nTileY,
int nXInTile,
int nYInTile,
73 Type
Get(
int nX,
int nY,
bool *pbSuccess =
nullptr);
74 bool Set(
int nX,
int nY, Type val);
96template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
111template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
113 CACHED_TILE_COUNT>::~GDALCachedPixelAccessor()
131template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
133 int nX,
int nY,
bool *pbSuccess)
135 const int nTileX = nX / TILE_SIZE;
136 const int nTileY = nY / TILE_SIZE;
137 const int nXInTile = nX % TILE_SIZE;
138 const int nYInTile = nY % TILE_SIZE;
139 if (m_aCachedTiles[0].m_nTileX == nTileX &&
140 m_aCachedTiles[0].m_nTileY == nTileY)
144 return m_aCachedTiles[0].m_data[nYInTile * TILE_SIZE + nXInTile];
146 return GetSlowPath(nTileX, nTileY, nXInTile, nYInTile, pbSuccess);
153template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
155 int nTileX,
int nTileY,
int nXInTile,
int nYInTile,
bool *pbSuccess)
157 for (
int i = 1; i < m_nCachedTileCount; ++i)
159 const auto &cachedTile = m_aCachedTiles[i];
160 if (cachedTile.m_nTileX == nTileX && cachedTile.m_nTileY == nTileY)
162 const auto ret = cachedTile.m_data[nYInTile * TILE_SIZE + nXInTile];
163 CachedTile tmp = std::move(m_aCachedTiles[i]);
164 for (
int j = i; j >= 1; --j)
165 m_aCachedTiles[j] = std::move(m_aCachedTiles[j - 1]);
166 m_aCachedTiles[0] = std::move(tmp);
172 if (!LoadTile(nTileX, nTileY))
180 return m_aCachedTiles[0].m_data[nYInTile * TILE_SIZE + nXInTile];
203template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
208 const int nTileX = nX / TILE_SIZE;
209 const int nTileY = nY / TILE_SIZE;
210 const int nXInTile = nX % TILE_SIZE;
211 const int nYInTile = nY % TILE_SIZE;
212 if (m_aCachedTiles[0].m_nTileX == nTileX &&
213 m_aCachedTiles[0].m_nTileY == nTileY)
215 m_aCachedTiles[0].m_data[nYInTile * TILE_SIZE + nXInTile] = val;
216 m_aCachedTiles[0].m_bModified =
true;
219 return SetSlowPath(nTileX, nTileY, nXInTile, nYInTile, val);
226template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
228 int nTileX,
int nTileY,
int nXInTile,
int nYInTile, Type val)
230 for (
int i = 1; i < m_nCachedTileCount; ++i)
232 auto &cachedTile = m_aCachedTiles[i];
233 if (cachedTile.m_nTileX == nTileX && cachedTile.m_nTileY == nTileY)
235 cachedTile.m_data[nYInTile * TILE_SIZE + nXInTile] = val;
236 cachedTile.m_bModified =
true;
239 CachedTile tmp = std::move(m_aCachedTiles[i]);
240 for (
int j = i; j >= 1; --j)
241 m_aCachedTiles[j] = std::move(m_aCachedTiles[j - 1]);
242 m_aCachedTiles[0] = std::move(tmp);
247 if (!LoadTile(nTileX, nTileY))
251 m_aCachedTiles[0].m_data[nYInTile * TILE_SIZE + nXInTile] = val;
252 m_aCachedTiles[0].m_bModified =
true;
264template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
268 for (
int i = 0; i < m_nCachedTileCount; ++i)
272 m_aCachedTiles[i].m_nTileX = -1;
273 m_aCachedTiles[i].m_nTileY = -1;
284template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
286 CACHED_TILE_COUNT>::ResetModifiedFlag()
288 for (
int i = 0; i < m_nCachedTileCount; ++i)
290 m_aCachedTiles[i].m_bModified =
false;
299template <
class T>
struct GDALCachedPixelAccessorGetDataType
303template <>
struct GDALCachedPixelAccessorGetDataType<
GByte>
308template <>
struct GDALCachedPixelAccessorGetDataType<
GInt8>
313template <>
struct GDALCachedPixelAccessorGetDataType<
GUInt16>
318template <>
struct GDALCachedPixelAccessorGetDataType<
GInt16>
323template <>
struct GDALCachedPixelAccessorGetDataType<
GUInt32>
328template <>
struct GDALCachedPixelAccessorGetDataType<
GInt32>
332#if SIZEOF_UNSIGNED_LONG == 8
334template <>
struct GDALCachedPixelAccessorGetDataType<unsigned long>
339template <>
struct GDALCachedPixelAccessorGetDataType<long>
344template <>
struct GDALCachedPixelAccessorGetDataType<
GUInt64>
349template <>
struct GDALCachedPixelAccessorGetDataType<
GInt64>
354template <>
struct GDALCachedPixelAccessorGetDataType<float>
359template <>
struct GDALCachedPixelAccessorGetDataType<double>
370template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
372 int nTileX,
int nTileY)
374 if (m_nCachedTileCount == CACHED_TILE_COUNT)
376 if (!FlushTile(CACHED_TILE_COUNT - 1))
378 CachedTile tmp = std::move(m_aCachedTiles[CACHED_TILE_COUNT - 1]);
379 for (
int i = CACHED_TILE_COUNT - 1; i >= 1; --i)
380 m_aCachedTiles[i] = std::move(m_aCachedTiles[i - 1]);
381 m_aCachedTiles[0] = std::move(tmp);
385 if (m_nCachedTileCount > 0)
386 std::swap(m_aCachedTiles[0], m_aCachedTiles[m_nCachedTileCount]);
387 m_aCachedTiles[0].m_data.resize(TILE_SIZE * TILE_SIZE);
388 m_nCachedTileCount++;
392 CPLDebug(
"GDAL",
"Load tile(%d, %d) of band %d of dataset %s",
393 nTileX, nTileY, m_poBand->GetBand(),
394 m_poBand->GetDataset() ? m_poBand->GetDataset()->GetDescription() :
"(unknown)");
396 CPLAssert(!m_aCachedTiles[0].m_bModified);
397 const int nXOff = nTileX * TILE_SIZE;
398 const int nYOff = nTileY * TILE_SIZE;
399 const int nReqXSize = std::min(m_poBand->GetXSize() - nXOff, TILE_SIZE);
400 const int nReqYSize = std::min(m_poBand->GetYSize() - nYOff, TILE_SIZE);
401 if (m_poBand->RasterIO(
402 GF_Read, nXOff, nYOff, nReqXSize, nReqYSize,
403 m_aCachedTiles[0].m_data.data(), nReqXSize, nReqYSize,
404 GDALCachedPixelAccessorGetDataType<Type>::DataType,
sizeof(Type),
405 TILE_SIZE *
sizeof(Type),
nullptr) != CE_None)
407 m_aCachedTiles[0].m_nTileX = -1;
408 m_aCachedTiles[0].m_nTileY = -1;
411 m_aCachedTiles[0].m_nTileX = nTileX;
412 m_aCachedTiles[0].m_nTileY = nTileY;
420template <
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
424 if (!m_aCachedTiles[iSlot].m_bModified)
427 m_aCachedTiles[iSlot].m_bModified =
false;
428 const int nXOff = m_aCachedTiles[iSlot].m_nTileX * TILE_SIZE;
429 const int nYOff = m_aCachedTiles[iSlot].m_nTileY * TILE_SIZE;
430 const int nReqXSize = std::min(m_poBand->GetXSize() - nXOff, TILE_SIZE);
431 const int nReqYSize = std::min(m_poBand->GetYSize() - nYOff, TILE_SIZE);
432 return m_poBand->RasterIO(
433 GF_Write, nXOff, nYOff, nReqXSize, nReqYSize,
434 m_aCachedTiles[iSlot].m_data.data(), nReqXSize, nReqYSize,
435 GDALCachedPixelAccessorGetDataType<Type>::DataType,
sizeof(Type),
436 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:37
bool Set(int nX, int nY, Type val)
Set the value of a pixel.
Definition: gdalcachedpixelaccessor.h:205
bool FlushCache()
Flush content of modified tiles and drop caches.
Definition: gdalcachedpixelaccessor.h:265
void SetBand(GDALRasterBand *poBand)
Assign the raster band if not known at construction time.
Definition: gdalcachedpixelaccessor.h:68
void ResetModifiedFlag()
Reset the modified flag for cached tiles.
Definition: gdalcachedpixelaccessor.h:286
Type Get(int nX, int nY, bool *pbSuccess=nullptr)
Get the value of a pixel.
Definition: gdalcachedpixelaccessor.h:132
~GDALCachedPixelAccessor()
Destructor.
Definition: gdalcachedpixelaccessor.h:113
A single raster band (or channel).
Definition: gdal_priv.h:1519
CPL error handling services.
#define CPLAssert(expr)
Assert on an expression.
Definition: cpl_error.h:209
void CPLDebug(const char *, const char *,...)
Display a debugging message.
Definition: cpl_error.cpp:731
short GInt16
Int16 type.
Definition: cpl_port.h:165
GIntBig GInt64
Signed 64 bit integer type.
Definition: cpl_port.h:220
unsigned int GUInt32
Unsigned int32 type.
Definition: cpl_port.h:161
GUIntBig GUInt64
Unsigned 64 bit integer type.
Definition: cpl_port.h:222
unsigned short GUInt16
Unsigned int16 type.
Definition: cpl_port.h:167
unsigned char GByte
Unsigned byte type.
Definition: cpl_port.h:169
int GInt32
Int32 type.
Definition: cpl_port.h:159
signed char GInt8
Signed int8 type.
Definition: cpl_port.h:171
GDALDataType
Definition: gdal.h:48
@ GDT_UInt32
Definition: gdal.h:54
@ GDT_UInt64
Definition: gdal.h:56
@ GDT_Int64
Definition: gdal.h:57
@ GDT_Byte
Definition: gdal.h:50
@ GDT_Int8
Definition: gdal.h:51
@ GDT_Float64
Definition: gdal.h:59
@ GDT_UInt16
Definition: gdal.h:52
@ GDT_Int16
Definition: gdal.h:53
@ GDT_Int32
Definition: gdal.h:55
@ GDT_Float32
Definition: gdal.h:58
@ GF_Write
Definition: gdal.h:119
@ GF_Read
Definition: gdal.h:118