9 #include <aliceVision/image/Image.hpp>
10 #include <aliceVision/image/io.hpp>
11 #include <aliceVision/image/cache.hpp>
13 #include <aliceVision/panorama/boundingBox.hpp>
14 #include <aliceVision/system/Logger.hpp>
15 #include <aliceVision/types.hpp>
24 using RowType = std::vector<image::CachedTile::smart_pointer>;
27 bool createImage(std::shared_ptr<image::TileCacheManager> manager,
size_t width,
size_t height)
31 _tileSize = manager->getTileWidth();
35 int countHeight = int(ceil(
double(height) /
double(manager->getTileHeight())));
36 int countWidth = int(ceil(
double(width) /
double(manager->getTileWidth())));
38 _memoryWidth = countWidth * _tileSize;
39 _memoryHeight = countHeight * _tileSize;
41 for (
int i = 0; i < countHeight; i++)
43 int tile_height = manager->getTileHeight();
44 if (i == countHeight - 1)
46 tile_height = height - (i * tile_height);
49 std::vector<image::CachedTile::smart_pointer> row;
51 for (
int j = 0; j < countWidth; j++)
53 int tile_width = manager->getTileWidth();
54 if (j == countWidth - 1)
56 tile_width = width - (i * tile_width);
59 image::CachedTile::smart_pointer tile = manager->requireNewCachedTile<T>(tile_width, tile_height);
68 _tilesArray.push_back(row);
74 bool writeImage(
const std::string& path,
const image::EStorageDataType& storageDataType = image::EStorageDataType::Auto)
76 ALICEVISION_LOG_ERROR(
"incorrect template function");
80 template<
class UnaryFunction>
81 bool perPixelOperation(UnaryFunction f)
83 for (
int i = 0; i < _tilesArray.size(); i++)
85 RowType& row = _tilesArray[i];
87 for (
int j = 0; j < _tilesArray[i].size(); j++)
89 image::CachedTile::smart_pointer ptr = row[j];
100 T* data = (T*)ptr->getDataPointer();
102 std::transform(data, data + ptr->getTileWidth() * ptr->getTileHeight(), data, f);
109 template<
class T2,
class BinaryFunction>
112 if (other.getWidth() != _width || other.getHeight() != _height)
117 for (
int i = 0; i < _tilesArray.size(); i++)
119 RowType& row = _tilesArray[i];
120 RowType& rowOther = other.getTiles()[i];
122 for (
int j = 0; j < _tilesArray[i].size(); j++)
124 image::CachedTile::smart_pointer ptr = row[j];
130 image::CachedTile::smart_pointer ptrOther = rowOther[j];
141 if (!ptrOther->acquire())
146 T* data = (T*)ptr->getDataPointer();
147 T2* dataOther = (T2*)ptrOther->getDataPointer();
149 std::transform(data, data + ptr->getTileWidth() * ptr->getTileHeight(), dataOther, data, f);
158 if (source._memoryWidth != _memoryWidth)
160 if (source._memoryHeight != _memoryHeight)
162 if (source._tileSize != _tileSize)
165 for (
int i = 0; i < _tilesArray.size(); i++)
167 RowType& row = _tilesArray[i];
168 RowType& rowSource = source._tilesArray[i];
170 for (
int j = 0; j < _tilesArray[i].size(); j++)
172 image::CachedTile::smart_pointer ptr = row[j];
178 image::CachedTile::smart_pointer ptrSource = rowSource[j];
189 if (!ptrSource->acquire())
194 T* data = (T*)ptr->getDataPointer();
195 T* dataSource = (T*)ptrSource->getDataPointer();
197 std::memcpy(data, dataSource, _tileSize * _tileSize *
sizeof(T));
207 outputMemoryBb.left = 0;
208 outputMemoryBb.top = 0;
209 outputMemoryBb.width = _width;
210 outputMemoryBb.height = _height;
212 if (!outputBb.isInside(outputMemoryBb))
218 inputMemoryBb.left = 0;
219 inputMemoryBb.top = 0;
220 inputMemoryBb.width = input.
width();
221 inputMemoryBb.height = input.
height();
223 if (!inputBb.isInside(inputMemoryBb))
228 if (inputBb.width != outputBb.width)
233 if (inputBb.height != outputBb.height)
240 snapedBb.snapToGrid(_tileSize);
244 gridBb.left = snapedBb.left / _tileSize;
245 gridBb.top = snapedBb.top / _tileSize;
246 gridBb.width = snapedBb.width / _tileSize;
247 gridBb.height = snapedBb.height / _tileSize;
249 int delta_y = outputBb.top - snapedBb.top;
250 int delta_x = outputBb.left - snapedBb.left;
252 for (
int i = 0; i < gridBb.height; i++)
255 int ti = gridBb.top + i;
256 int oy = ti * _tileSize;
257 int sy = inputBb.top - delta_y + i * _tileSize;
259 RowType& row = _tilesArray[ti];
261 for (
int j = 0; j < gridBb.width; j++)
263 int tj = gridBb.left + j;
264 int ox = tj * _tileSize;
265 int sx = inputBb.left - delta_x + j * _tileSize;
267 image::CachedTile::smart_pointer ptr = row[tj];
278 T* data = (T*)ptr->getDataPointer();
280 for (
int y = 0; y < _tileSize; y++)
282 for (
int x = 0; x < _tileSize; x++)
284 if (sy + y < inputBb.top || sy + y > inputBb.getBottom())
286 if (sx + x < inputBb.left || sx + x > inputBb.getRight())
288 if (oy + y < outputBb.top || oy + y > outputBb.getBottom())
290 if (ox + x < outputBb.left || ox + x > outputBb.getRight())
293 data[y * _tileSize + x] = input(sy + y, sx + x);
307 thisBb.width = _width;
308 thisBb.height = _height;
310 if (!inputBb.isInside(thisBb))
316 outputMemoryBb.left = 0;
317 outputMemoryBb.top = 0;
318 outputMemoryBb.width = output.
width();
319 outputMemoryBb.height = output.
height();
321 if (!outputBb.isInside(outputMemoryBb))
326 if (inputBb.width != outputBb.width)
331 if (inputBb.height != outputBb.height)
337 snapedBb.snapToGrid(_tileSize);
340 gridBb.left = snapedBb.left / _tileSize;
341 gridBb.top = snapedBb.top / _tileSize;
342 gridBb.width = snapedBb.width / _tileSize;
343 gridBb.height = snapedBb.height / _tileSize;
345 int delta_y = inputBb.top - snapedBb.top;
346 int delta_x = inputBb.left - snapedBb.left;
348 for (
int i = 0; i < gridBb.height; i++)
350 int ti = gridBb.top + i;
351 int oy = ti * _tileSize;
352 int sy = outputBb.top - delta_y + i * _tileSize;
354 RowType& row = _tilesArray[ti];
356 for (
int j = 0; j < gridBb.width; j++)
358 int tj = gridBb.left + j;
359 int ox = tj * _tileSize;
360 int sx = outputBb.left - delta_x + j * _tileSize;
362 image::CachedTile::smart_pointer ptr = row[tj];
373 T* data = (T*)ptr->getDataPointer();
375 for (
int y = 0; y < _tileSize; y++)
377 for (
int x = 0; x < _tileSize; x++)
379 if (sy + y < outputBb.top || sy + y > outputBb.getBottom())
381 if (sx + x < outputBb.left || sx + x > outputBb.getRight())
383 if (oy + y < inputBb.top || oy + y > inputBb.getBottom())
385 if (ox + x < inputBb.left || ox + x > inputBb.getRight())
388 output(sy + y, sx + x) = data[y * _tileSize + x];
397 static bool getTileAsImage(
image::Image<T>& ret, image::CachedTile::smart_pointer tile)
404 if (!tile->acquire())
409 ret.
resize(tile->getTileWidth(), tile->getTileHeight());
410 T* data = (T*)tile->getDataPointer();
411 for (
int i = 0; i < tile->getTileHeight(); i++)
413 for (
int j = 0; j < tile->getTileWidth(); j++)
423 static bool setTileWithImage(image::CachedTile::smart_pointer tile,
const image::Image<T>& ret)
425 if (ret.
width() != tile->getTileWidth())
430 if (ret.
height() != tile->getTileHeight())
440 if (!tile->acquire())
445 T* data = (T*)tile->getDataPointer();
446 for (
int i = 0; i < tile->getTileHeight(); i++)
448 for (
int j = 0; j < tile->getTileWidth(); j++)
458 bool fill(
const T& val)
460 if (!perPixelOperation([val](T) -> T {
return val; }))
468 std::vector<RowType>& getTiles() {
return _tilesArray; }
470 int getWidth()
const {
return _width; }
472 int getHeight()
const {
return _height; }
474 int getTileSize()
const {
return _tileSize; }
483 std::vector<RowType> _tilesArray;