SourceXtractorPlusPlus 0.21
SourceXtractor++, the next generation SExtractor
Loading...
Searching...
No Matches
BufferedImage.cpp
Go to the documentation of this file.
1
22
23namespace SourceXtractor {
24
25template<typename T>
29
30
31template<typename T>
36
37
38template<typename T>
40 return "BufferedImage(" + m_source->getRepr() + ")";
41}
42
43
44template<typename T>
46 return m_source->getWidth();
47}
48
49
50template<typename T>
52 return m_source->getHeight();
53}
54
55
56template<typename T>
57std::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();
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
101template<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
122template class BufferedImage<unsigned int>;
123template class BufferedImage<int>;
124template 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
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)
T max(T... args)
T min(T... args)
T move(T... args)