2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
\r
4 * This file is part of CasparCG (www.casparcg.com).
\r
6 * CasparCG is free software: you can redistribute it and/or modify
\r
7 * it under the terms of the GNU General Public License as published by
\r
8 * the Free Software Foundation, either version 3 of the License, or
\r
9 * (at your option) any later version.
\r
11 * CasparCG is distributed in the hope that it will be useful,
\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 * GNU General Public License for more details.
\r
16 * You should have received a copy of the GNU General Public License
\r
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
\r
19 * Author: Helge Norberg, helge.norberg@svt.se
\r
24 #include <boost/iterator/filter_iterator.hpp>
\r
26 namespace caspar { namespace image {
\r
29 * A POD pixel with a compatible memory layout as a 8bit BGRA pixel (32bits in
\r
32 * Models the PackedPixel concept used by for example image_view. Also models
\r
33 * the RGBAPixel concept which does not care about the order between RGBA but
\r
34 * only requires that all 4 channel has accessors.
\r
43 bgra_pixel(uint8_t b = 0, uint8_t g = 0, uint8_t r = 0, uint8_t a = 0) : b_(b), g_(g), r_(r), a_(a) {}
\r
44 inline const uint8_t& b() const { return b_; }
\r
45 inline uint8_t& b() { return b_; }
\r
46 inline const uint8_t& g() const { return g_; }
\r
47 inline uint8_t& g() { return g_; }
\r
48 inline const uint8_t& r() const { return r_; }
\r
49 inline uint8_t& r() { return r_; }
\r
50 inline const uint8_t& a() const { return a_; }
\r
51 inline uint8_t& a() { return a_; }
\r
54 template<class PackedPixel> class image_sub_view;
\r
57 * An image view abstracting raw packed pixel data
\r
59 * This is only a view, it does not own the data.
\r
61 * Models the the ImageView concept.
\r
63 template<class PackedPixel>
\r
67 typedef PackedPixel pixel_type;
\r
69 image_view(void* raw_start, int width, int height)
\r
70 : begin_(static_cast<PackedPixel*>(raw_start))
\r
71 , end_(begin_ + (width * height))
\r
77 PackedPixel* begin()
\r
82 const PackedPixel* begin() const
\r
92 const PackedPixel* end() const
\r
97 template<class PackedPixelIter>
\r
98 inline PackedPixel* relative(PackedPixelIter to, int delta_x, int delta_y)
\r
100 auto pixel_distance = delta_x + width_ * delta_y;
\r
101 PackedPixel* to_address = &(*to);
\r
102 auto result = to_address + pixel_distance;
\r
104 if (result < begin_ || result >= end_)
\r
110 template<class PackedPixelIter>
\r
111 inline const PackedPixel* relative(PackedPixelIter to, int delta_x, int delta_y) const
\r
114 auto pixel_distance = delta_x + width_ * delta_y;
\r
115 const PackedPixel* to_address = &(*to);
\r
116 auto result = to_address + pixel_distance;
\r
118 /*if (delta_x != 0)
\r
120 auto actual_delta_y = result % width_
\r
123 if (result < begin_ || result >= end_)
\r
139 image_sub_view<PackedPixel> subview(int x, int y, int width, int height)
\r
141 return image_sub_view<PackedPixel>(*this, x, y, width, height);
\r
144 const image_sub_view<PackedPixel> subview(int x, int y, int width, int height) const
\r
146 return image_sub_view<PackedPixel>(*this, x, y, width, height);
\r
149 PackedPixel* begin_;
\r
155 template<class PackedPixel>
\r
156 class is_within_view
\r
159 is_within_view(const PackedPixel* begin, int width, int stride)
\r
163 , no_check_(width == stride)
\r
167 inline bool operator()(const PackedPixel& pixel) const
\r
172 const PackedPixel* position = &pixel;
\r
173 int distance_from_row_start = (position - begin_) % stride_;
\r
175 return distance_from_row_start < width_;
\r
178 const PackedPixel* begin_;
\r
184 template <class PackedPixel>
\r
185 struct image_stride_iterator : public boost::filter_iterator<is_within_view<PackedPixel>, PackedPixel*>
\r
187 image_stride_iterator(PackedPixel* begin, PackedPixel* end, int width, int stride)
\r
188 : boost::filter_iterator<is_within_view<PackedPixel>, PackedPixel*>::filter_iterator(
\r
189 is_within_view<PackedPixel>(begin, width, stride), begin, end)
\r
195 * A sub view created from an image_view.
\r
197 * This also models the ImageView concept.
\r
199 template<class PackedPixel>
\r
200 class image_sub_view
\r
203 typedef PackedPixel pixel_type;
\r
205 image_sub_view(image_view<PackedPixel>& root_view, int x, int y, int width, int height)
\r
206 : root_view_(root_view)
\r
207 , relative_to_root_x_(x)
\r
208 , relative_to_root_y_(y)
\r
211 , raw_begin_(root_view.relative(root_view.begin(), x, y))
\r
212 , raw_end_(root_view.relative(raw_begin_, width - 1, height_ - 1) + 1)
\r
216 image_stride_iterator<PackedPixel> begin()
\r
218 return image_stride_iterator<PackedPixel>(raw_begin_, raw_end_, width_, root_view_.width());
\r
221 image_stride_iterator<const PackedPixel> begin() const
\r
223 return image_stride_iterator<const PackedPixel>(raw_begin_, raw_end_, width_, root_view_.width());
\r
226 image_stride_iterator<PackedPixel> end()
\r
228 return image_stride_iterator<PackedPixel>(raw_end_, raw_end_, width_, root_view_.width());
\r
231 image_stride_iterator<const PackedPixel> end() const
\r
233 return image_stride_iterator<const PackedPixel>(raw_end_, raw_end_, width_, root_view_.width());
\r
236 template<class PackedPixelIter>
\r
237 PackedPixel* relative(PackedPixelIter to, int delta_x, int delta_y)
\r
239 return root_view_.relative(to, delta_x, delta_y);
\r
242 template<class PackedPixelIter>
\r
243 const PackedPixel* relative(PackedPixelIter to, int delta_x, int delta_y) const
\r
245 return root_view_.relative(to, delta_x, delta_y);
\r
258 image_sub_view<PackedPixel> subview(int x, int y, int width, int height)
\r
260 return root_view_.subview(relative_to_root_x_ + x, relative_to_root_y_ + y, width, height);
\r
263 const image_sub_view<PackedPixel> subview(int x, int y, int width, int height) const
\r
265 return root_view_.subview(relative_to_root_x_ + x, relative_to_root_y_ + y, width, height);
\r
268 image_view<PackedPixel> root_view_;
\r
269 int relative_to_root_x_;
\r
270 int relative_to_root_y_;
\r
273 PackedPixel* raw_begin_;
\r
274 PackedPixel* raw_end_;
\r