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