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