29 #ifndef GDAL_CACHED_PIXEL_ACCESSOR_INCLUDED
30 #define GDAL_CACHED_PIXEL_ACCESSOR_INCLUDED
57 std::vector<Type> m_data{};
60 bool m_bModified =
false;
63 int m_nCachedTileCount = 0;
64 std::array<CachedTile, CACHED_TILE_COUNT> m_aCachedTiles{};
66 bool LoadTile(
int nTileX,
int nTileY);
67 bool FlushTile(
int iSlot);
69 Type GetSlowPath(
int nTileX,
int nTileY,
70 int nXInTile,
int nYInTile,
72 bool SetSlowPath(
int nTileX,
int nTileY,
73 int nXInTile,
int nYInTile,
86 Type
Get(
int nX,
int nY,
bool* pbSuccess =
nullptr);
87 bool Set(
int nX,
int nY, Type val);
109 template<
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
122 template<
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
141 template<
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
145 const int nTileX = nX / TILE_SIZE;
146 const int nTileY = nY / TILE_SIZE;
147 const int nXInTile = nX % TILE_SIZE;
148 const int nYInTile = nY % TILE_SIZE;
149 if( m_aCachedTiles[0].m_nTileX == nTileX &&
150 m_aCachedTiles[0].m_nTileY == nTileY )
154 return m_aCachedTiles[0].m_data[nYInTile * TILE_SIZE + nXInTile];
156 return GetSlowPath(nTileX, nTileY, nXInTile, nYInTile, pbSuccess);
163 template<
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
165 int nTileX,
int nTileY,
int nXInTile,
int nYInTile,
bool* pbSuccess)
167 for(
int i = 1; i < m_nCachedTileCount; ++i )
169 const auto& cachedTile = m_aCachedTiles[i];
170 if( cachedTile.m_nTileX == nTileX &&
171 cachedTile.m_nTileY == nTileY )
173 const auto ret = cachedTile.m_data[nYInTile * TILE_SIZE + nXInTile];
174 std::swap(m_aCachedTiles[0], m_aCachedTiles[i]);
180 if( !LoadTile(nTileX, nTileY) )
188 return m_aCachedTiles[0].m_data[nYInTile * TILE_SIZE + nXInTile];
211 template<
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
215 const int nTileX = nX / TILE_SIZE;
216 const int nTileY = nY / TILE_SIZE;
217 const int nXInTile = nX % TILE_SIZE;
218 const int nYInTile = nY % TILE_SIZE;
219 if( m_aCachedTiles[0].m_nTileX == nTileX &&
220 m_aCachedTiles[0].m_nTileY == nTileY )
222 m_aCachedTiles[0].m_data[nYInTile * TILE_SIZE + nXInTile] = val;
223 m_aCachedTiles[0].m_bModified =
true;
226 return SetSlowPath(nTileX, nTileY, nXInTile, nYInTile, val);
233 template<
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
235 int nTileX,
int nTileY,
int nXInTile,
int nYInTile, Type val)
237 for(
int i = 1; i < m_nCachedTileCount; ++i )
239 auto& cachedTile = m_aCachedTiles[i];
240 if( cachedTile.m_nTileX == nTileX &&
241 cachedTile.m_nTileY == nTileY )
243 cachedTile.m_data[nYInTile * TILE_SIZE + nXInTile] = val;
244 cachedTile.m_bModified =
true;
246 std::swap(m_aCachedTiles[0], m_aCachedTiles[i]);
250 if( !LoadTile(nTileX, nTileY) )
254 m_aCachedTiles[0].m_data[nYInTile * TILE_SIZE + nXInTile] = val;
255 m_aCachedTiles[0].m_bModified =
true;
267 template<
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
271 for(
int i = 0; i < m_nCachedTileCount; ++i )
275 m_aCachedTiles[i].m_nTileX = -1;
276 m_aCachedTiles[i].m_nTileY = -1;
287 template<
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
290 for(
int i = 0; i < m_nCachedTileCount; ++i )
292 m_aCachedTiles[i].m_bModified =
false;
301 template<
class T>
struct GDALCachedPixelAccessorGetDataType {};
308 #if SIZEOF_UNSIGNED_LONG == 8
310 template<>
struct GDALCachedPixelAccessorGetDataType<unsigned long> {
static constexpr
GDALDataType DataType =
GDT_UInt64; };
311 template<>
struct GDALCachedPixelAccessorGetDataType<long > {
static constexpr
GDALDataType DataType =
GDT_Int64; };
315 template<>
struct GDALCachedPixelAccessorGetDataType<float> {
static constexpr
GDALDataType DataType =
GDT_Float32; };
316 template<>
struct GDALCachedPixelAccessorGetDataType<double> {
static constexpr
GDALDataType DataType =
GDT_Float64; };
323 template<
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
326 if( m_nCachedTileCount == CACHED_TILE_COUNT )
328 if( !FlushTile(CACHED_TILE_COUNT - 1) )
330 std::swap(m_aCachedTiles[0], m_aCachedTiles[CACHED_TILE_COUNT - 1]);
334 if( m_nCachedTileCount > 0 )
335 std::swap(m_aCachedTiles[0], m_aCachedTiles[m_nCachedTileCount]);
336 m_aCachedTiles[0].m_data.resize(TILE_SIZE * TILE_SIZE);
337 m_nCachedTileCount ++;
340 CPLAssert(!m_aCachedTiles[0].m_bModified);
341 const int nXOff = nTileX * TILE_SIZE;
342 const int nYOff = nTileY * TILE_SIZE;
343 const int nReqXSize = std::min(m_poBand->GetXSize() - nXOff, TILE_SIZE);
344 const int nReqYSize = std::min(m_poBand->GetYSize() - nYOff, TILE_SIZE);
345 if( m_poBand->RasterIO(
GF_Read, nXOff, nYOff, nReqXSize, nReqYSize,
346 m_aCachedTiles[0].m_data.data(),
347 nReqXSize, nReqYSize,
348 GDALCachedPixelAccessorGetDataType<Type>::DataType,
349 sizeof(Type), TILE_SIZE *
sizeof(Type),
350 nullptr) != CE_None )
352 m_aCachedTiles[0].m_nTileX = -1;
353 m_aCachedTiles[0].m_nTileY = -1;
356 m_aCachedTiles[0].m_nTileX = nTileX;
357 m_aCachedTiles[0].m_nTileY = nTileY;
365 template<
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
368 if( !m_aCachedTiles[iSlot].m_bModified )
371 m_aCachedTiles[iSlot].m_bModified =
false;
372 const int nXOff = m_aCachedTiles[iSlot].m_nTileX * TILE_SIZE;
373 const int nYOff = m_aCachedTiles[iSlot].m_nTileY * TILE_SIZE;
374 const int nReqXSize = std::min(m_poBand->GetXSize() - nXOff, TILE_SIZE);
375 const int nReqYSize = std::min(m_poBand->GetYSize() - nYOff, TILE_SIZE);
376 return m_poBand->RasterIO(
GF_Write, nXOff, nYOff, nReqXSize, nReqYSize,
377 m_aCachedTiles[iSlot].m_data.data(),
378 nReqXSize, nReqYSize,
379 GDALCachedPixelAccessorGetDataType<Type>::DataType,
380 sizeof(Type), TILE_SIZE *
sizeof(Type),
384 #endif // GDAL_PIXEL_ACCESSOR_INCLUDED