SourceXtractorPlusPlus  0.16
Please provide a description of the project.
BufferedImage.cpp
Go to the documentation of this file.
1 
22 
23 namespace SourceXtractor {
24 
25 template<typename T>
27  std::shared_ptr<TileManager> tile_manager)
28  : m_source(source), m_tile_manager(tile_manager) {}
29 
30 
31 template<typename T>
33  std::shared_ptr<TileManager> tile_manager) {
34  return std::shared_ptr<BufferedImage<T>>(new BufferedImage<T>(source, tile_manager));
35 }
36 
37 
38 template<typename T>
40  return "BufferedImage(" + m_source->getRepr() + ")";
41 }
42 
43 
44 template<typename T>
46  return m_source->getWidth();
47 }
48 
49 
50 template<typename T>
52  return m_source->getHeight();
53 }
54 
55 
56 template<typename T>
57 std::shared_ptr<ImageChunk<T>> BufferedImage<T>::getChunk(int x, int y, int width, int height) const {
58  int tile_width = m_tile_manager->getTileWidth();
59  int tile_height = m_tile_manager->getTileHeight();
60  int tile_offset_x = x % tile_width;
61  int tile_offset_y = y % tile_height;
62 
63  // When the chunk does *not* cross boundaries, we can just use the memory hold by the single tile
64  if (tile_offset_x + width <= tile_width && tile_offset_y + height <= tile_height) {
65  // the tile image is going to be kept in memory as long as the chunk exists, but it could be unloaded
66  // from TileManager and even reloaded again, wasting memory,
67  // however image chunks are normally short lived so it's probably OK
68  auto tile = std::dynamic_pointer_cast<ImageTileWithType<T>>(m_tile_manager->getTileForPixel(x, y, m_source));
69  assert(tile != nullptr);
70 
71  // The tile may be smaller than tile_width x tile_height if the image is smaller, or does not divide neatly!
72  auto image = tile->getImage();
73  return image->getChunk(tile_offset_x, tile_offset_y, width, height);
74  }
75  else {
76  // If the chunk cross boundaries, we can't just use the memory from within a tile, so we need to copy
77  // To avoid the overhead of calling getValue() - which uses a thread local - we do the full thing here
78  // Also, instead of iterating on the pixel coordinates, to avoid asking several times for the same tile,
79  // iterate over the tiles
80  std::vector<T> data(width * height);
81  int tile_w = m_tile_manager->getTileWidth();
82  int tile_h = m_tile_manager->getTileHeight();
83 
84  int tile_start_x = x / tile_w * tile_w;
85  int tile_start_y = y / tile_h * tile_h;
86  int tile_end_x = (x + width - 1) / tile_w * tile_w;
87  int tile_end_y = (y + height - 1) / tile_h * tile_h;
88 
89  for (int iy = tile_start_y; iy <= tile_end_y; iy += tile_h) {
90  for (int ix = tile_start_x; ix <= tile_end_x; ix += tile_w) {
91  auto tile = std::dynamic_pointer_cast<ImageTileWithType<T>>(m_tile_manager->getTileForPixel(ix, iy, m_source));
92  copyOverlappingPixels(*tile, data, x, y, width, height, tile_w, tile_h);
93  }
94  }
95 
96  return UniversalImageChunk<T>::create(std::move(data), width, height);
97  }
98 }
99 
100 
101 template<typename T>
103  int x, int y, int w, int h,
104  int tile_w, int tile_h) const {
105  int start_x = std::max(tile.getPosX(), x);
106  int start_y = std::max(tile.getPosY(), y);
107  int end_x = std::min(tile.getPosX() + tile_w, x + w);
108  int end_y = std::min(tile.getPosY() + tile_h, y + h);
109  int off_x = start_x - x;
110  int off_y = start_y - y;
111 
112  for (int data_y = off_y, img_y = start_y; img_y < end_y; ++data_y, ++img_y) {
113  for (int data_x = off_x, img_x = start_x; img_x < end_x; ++data_x, ++img_x) {
114  tile.getValue(img_x, img_y, output[data_x + data_y * w]);
115  }
116  }
117 }
118 
119 
122 template class BufferedImage<unsigned int>;
123 template class BufferedImage<int>;
124 template class BufferedImage<double>;
125 
126 
127 } // end namespace SourceXtractor
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > x
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > y
void copyOverlappingPixels(const ImageTileWithType< T > &tile, std::vector< T > &output, int x, int y, int w, int h, int tile_w, int tile_h) const
static std::shared_ptr< BufferedImage< T > > create(std::shared_ptr< const ImageSource > source, std::shared_ptr< TileManager > tile_manager=TileManager::getInstance())
std::string getRepr() const override
Get a string identifying this image in a human readable manner.
int getWidth() const override
Returns the width of the image in pixels.
int getHeight() const override
Returns the height of the image in pixels.
BufferedImage(std::shared_ptr< const ImageSource > source, std::shared_ptr< TileManager > tile_manager)
std::shared_ptr< ImageChunk< T > > getChunk(int x, int y, int width, int height) const override
void getValue(int x, int y, float &value) const override
Definition: ImageTile.h:194
static std::shared_ptr< UniversalImageChunk< T > > create(Args &&... args)
Definition: ImageChunk.h:142
T max(T... args)
T min(T... args)
T move(T... args)