SourceXtractorPlusPlus  0.13
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<T>(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 
84  auto image = tile->getImage<T>();
85  const T *data_start = &(image->getData()[tile_offset_x +
86  tile_offset_y * image->getWidth()]);
87  return ImageChunk<T>::create(data_start, width, height, image->getWidth(), image);
88  }
89  else {
90  // If the chunk cross boundaries, we can't just use the memory from within a tile, so we need to copy
91  // To avoid the overhead of calling getValue() - which uses a thread local - we do the full thing here
92  // Also, instead of iterating on the pixel coordinates, to avoid asking several times for the same tile,
93  // iterate over the tiles
94  std::vector<T> data(width * height);
95  int tile_w = m_tile_manager->getTileWidth();
96  int tile_h = m_tile_manager->getTileHeight();
97 
98  int tile_start_x = x / tile_w * tile_w;
99  int tile_start_y = y / tile_h * tile_h;
100  int tile_end_x = (x + width - 1) / tile_w * tile_w;
101  int tile_end_y = (y + height - 1) / tile_h * tile_h;
102 
103  for (int iy = tile_start_y; iy <= tile_end_y; iy += tile_h) {
104  for (int ix = tile_start_x; ix <= tile_end_x; ix += tile_w) {
105  auto tile = m_tile_manager->getTileForPixel(ix, iy, m_source);
106  copyOverlappingPixels(*tile, data, x, y, width, height, tile_w, tile_h);
107  }
108  }
109 
110  return UniversalImageChunk<T>::create(std::move(data), width, height);
111  }
112 }
113 
114 
115 template<typename T>
117  int x, int y, int w, int h,
118  int tile_w, int tile_h) const {
119  int start_x = std::max(tile.getPosX(), x);
120  int start_y = std::max(tile.getPosY(), y);
121  int end_x = std::min(tile.getPosX() + tile_w, x + w);
122  int end_y = std::min(tile.getPosY() + tile_h, y + h);
123  int off_x = start_x - x;
124  int off_y = start_y - y;
125 
126  for (int data_y = off_y, img_y = start_y; img_y < end_y; ++data_y, ++img_y) {
127  for (int data_x = off_x, img_x = start_x; img_x < end_x; ++data_x, ++img_x) {
128  output[data_x + data_y * w] = tile.getValue<T>(img_x, img_y);
129  }
130  }
131 }
132 
133 
136 template class BufferedImage<unsigned int>;
137 template class BufferedImage<int>;
138 template class BufferedImage<double>;
139 
140 
141 } // end namespace SourceXtractor
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > x
void copyOverlappingPixels(const ImageTile &tile, std::vector< T > &output, int x, int y, int w, int h, int tile_w, int tile_h) const
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
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > y
int getPosX() const
Definition: ImageTile.h:56
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 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:132
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.
T getValue(int x, int y) const
Definition: ImageTile.h:75
std::string getRepr() const override
Get a string identifying this image in a human readable manner.
int getPosY() const
Definition: ImageTile.h:60
static std::shared_ptr< BufferedImage< T > > create(std::shared_ptr< const ImageSource > source, std::shared_ptr< TileManager > tile_manager=TileManager::getInstance())