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 CachedTile tmp = std::move(m_aCachedTiles[i]);
175 for(
int j = i; j >= 1; --j )
176 m_aCachedTiles[j] = std::move(m_aCachedTiles[j-1]);
177 m_aCachedTiles[0] = std::move(tmp);
183 if( !LoadTile(nTileX, nTileY) )
191 return m_aCachedTiles[0].m_data[nYInTile * TILE_SIZE + nXInTile];
214 template<
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
218 const int nTileX = nX / TILE_SIZE;
219 const int nTileY = nY / TILE_SIZE;
220 const int nXInTile = nX % TILE_SIZE;
221 const int nYInTile = nY % TILE_SIZE;
222 if( m_aCachedTiles[0].m_nTileX == nTileX &&
223 m_aCachedTiles[0].m_nTileY == nTileY )
225 m_aCachedTiles[0].m_data[nYInTile * TILE_SIZE + nXInTile] = val;
226 m_aCachedTiles[0].m_bModified =
true;
229 return SetSlowPath(nTileX, nTileY, nXInTile, nYInTile, val);
236 template<
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
238 int nTileX,
int nTileY,
int nXInTile,
int nYInTile, Type val)
240 for(
int i = 1; i < m_nCachedTileCount; ++i )
242 auto& cachedTile = m_aCachedTiles[i];
243 if( cachedTile.m_nTileX == nTileX &&
244 cachedTile.m_nTileY == nTileY )
246 cachedTile.m_data[nYInTile * TILE_SIZE + nXInTile] = val;
247 cachedTile.m_bModified =
true;
250 CachedTile tmp = std::move(m_aCachedTiles[i]);
251 for(
int j = i; j >= 1; --j )
252 m_aCachedTiles[j] = std::move(m_aCachedTiles[j-1]);
253 m_aCachedTiles[0] = std::move(tmp);
258 if( !LoadTile(nTileX, nTileY) )
262 m_aCachedTiles[0].m_data[nYInTile * TILE_SIZE + nXInTile] = val;
263 m_aCachedTiles[0].m_bModified =
true;
275 template<
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
279 for(
int i = 0; i < m_nCachedTileCount; ++i )
283 m_aCachedTiles[i].m_nTileX = -1;
284 m_aCachedTiles[i].m_nTileY = -1;
295 template<
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
298 for(
int i = 0; i < m_nCachedTileCount; ++i )
300 m_aCachedTiles[i].m_bModified =
false;
309 template<
class T>
struct GDALCachedPixelAccessorGetDataType {};
316 #if SIZEOF_UNSIGNED_LONG == 8
318 template<>
struct GDALCachedPixelAccessorGetDataType<unsigned long> {
static constexpr
GDALDataType DataType =
GDT_UInt64; };
319 template<>
struct GDALCachedPixelAccessorGetDataType<long > {
static constexpr
GDALDataType DataType =
GDT_Int64; };
323 template<>
struct GDALCachedPixelAccessorGetDataType<float> {
static constexpr
GDALDataType DataType =
GDT_Float32; };
324 template<>
struct GDALCachedPixelAccessorGetDataType<double> {
static constexpr
GDALDataType DataType =
GDT_Float64; };
331 template<
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
334 if( m_nCachedTileCount == CACHED_TILE_COUNT )
336 if( !FlushTile(CACHED_TILE_COUNT - 1) )
338 CachedTile tmp = std::move(m_aCachedTiles[CACHED_TILE_COUNT-1]);
339 for(
int i = CACHED_TILE_COUNT - 1; i >= 1; --i )
340 m_aCachedTiles[i] = std::move(m_aCachedTiles[i-1]);
341 m_aCachedTiles[0] = std::move(tmp);
345 if( m_nCachedTileCount > 0 )
346 std::swap(m_aCachedTiles[0], m_aCachedTiles[m_nCachedTileCount]);
347 m_aCachedTiles[0].m_data.resize(TILE_SIZE * TILE_SIZE);
348 m_nCachedTileCount ++;
352 CPLDebug(
"GDAL",
"Load tile(%d, %d) of band %d of dataset %s",
353 nTileX, nTileY, m_poBand->GetBand(),
354 m_poBand->GetDataset() ? m_poBand->GetDataset()->GetDescription() :
"(unknown)");
356 CPLAssert(!m_aCachedTiles[0].m_bModified);
357 const int nXOff = nTileX * TILE_SIZE;
358 const int nYOff = nTileY * TILE_SIZE;
359 const int nReqXSize = std::min(m_poBand->GetXSize() - nXOff, TILE_SIZE);
360 const int nReqYSize = std::min(m_poBand->GetYSize() - nYOff, TILE_SIZE);
361 if( m_poBand->RasterIO(
GF_Read, nXOff, nYOff, nReqXSize, nReqYSize,
362 m_aCachedTiles[0].m_data.data(),
363 nReqXSize, nReqYSize,
364 GDALCachedPixelAccessorGetDataType<Type>::DataType,
365 sizeof(Type), TILE_SIZE *
sizeof(Type),
366 nullptr) != CE_None )
368 m_aCachedTiles[0].m_nTileX = -1;
369 m_aCachedTiles[0].m_nTileY = -1;
372 m_aCachedTiles[0].m_nTileX = nTileX;
373 m_aCachedTiles[0].m_nTileY = nTileY;
381 template<
class Type,
int TILE_SIZE,
int CACHED_TILE_COUNT>
384 if( !m_aCachedTiles[iSlot].m_bModified )
387 m_aCachedTiles[iSlot].m_bModified =
false;
388 const int nXOff = m_aCachedTiles[iSlot].m_nTileX * TILE_SIZE;
389 const int nYOff = m_aCachedTiles[iSlot].m_nTileY * TILE_SIZE;
390 const int nReqXSize = std::min(m_poBand->GetXSize() - nXOff, TILE_SIZE);
391 const int nReqYSize = std::min(m_poBand->GetYSize() - nYOff, TILE_SIZE);
392 return m_poBand->RasterIO(
GF_Write, nXOff, nYOff, nReqXSize, nReqYSize,
393 m_aCachedTiles[iSlot].m_data.data(),
394 nReqXSize, nReqYSize,
395 GDALCachedPixelAccessorGetDataType<Type>::DataType,
396 sizeof(Type), TILE_SIZE *
sizeof(Type),
400 #endif // GDAL_PIXEL_ACCESSOR_INCLUDED