1 // This is core/vidl/vidl_pixel_iterator.hxx 2 #ifndef vidl_pixel_iterator_hxx_ 3 #define vidl_pixel_iterator_hxx_ 4 //: 5 // \file 6 // \brief Templated definitions for pixel iterators 7 // 8 // \author Matt Leotta 9 // \date 3 Mar 2006 10 // 11 // This file contains the template definitions for pixel iterators 12 13 14 #include "vidl_pixel_iterator.h" 15 #include "vidl_color.h" 16 #include <vxl_config.h> 17 #include <cassert> 18 #ifdef _MSC_VER 19 # include <vcl_msvc_warnings.h> 20 #endif 21 22 //----------------------------------------------------------------------------- 23 24 25 template <vidl_pixel_arrangement AR> 26 struct vidl_pixel_iterator_arrange_valid 27 { 28 enum { value = (AR == VIDL_PIXEL_ARRANGE_SINGLE) }; 29 }; 30 31 32 //: The default pixel iterator for single arranged formats 33 template <vidl_pixel_arrangement AR, vidl_pixel_format FMT> 34 class vidl_pixel_iterator_arranged 35 { 36 typedef typename vidl_pixel_traits_of<FMT>::type cmp_type; 37 cmp_type * ptr_; 38 public: 39 //: Constructor vidl_pixel_iterator_arranged(const vidl_frame & frame)40 vidl_pixel_iterator_arranged(const vidl_frame& frame) 41 : ptr_((cmp_type*)frame.data()) 42 { 43 assert(frame.pixel_format() == FMT); 44 // The following should be a static asserts 45 assert(vidl_pixel_traits_of<FMT>::bits_per_pixel%8 == 0); 46 assert(vidl_pixel_traits_of<FMT>::arrangement() == VIDL_PIXEL_ARRANGE_SINGLE); 47 } 48 49 //: Destructor 50 ~vidl_pixel_iterator_arranged() = default; 51 52 //: Step to the next pixel next()53 vidl_pixel_iterator_arranged<AR,FMT>& next() 54 { 55 ptr_ += vidl_pixel_traits_of<FMT>::bits_per_pixel/(sizeof(cmp_type)*8); 56 return *this; 57 } 58 59 //: Access the data operator ()(unsigned int i) const60 cmp_type operator () (unsigned int i) const 61 { 62 assert(i<vidl_pixel_traits_of<FMT>::num_channels); 63 return vidl_color_component<FMT>::get(ptr_,i); 64 } 65 66 //: Access the entire pixel at once get(cmp_type * data) const67 void get(cmp_type* data) const 68 { 69 vidl_color_component<FMT>::get_all(ptr_,data); 70 } 71 72 //: write the entire pixel at once set(const cmp_type * data)73 void set(const cmp_type* data) 74 { 75 vidl_color_component<FMT>::set_all(ptr_,data); 76 } 77 }; 78 79 template <> 80 struct vidl_pixel_iterator_arrange_valid<VIDL_PIXEL_ARRANGE_PLANAR> 81 { 82 enum { value = true }; 83 }; 84 85 86 //: The default pixel iterator for planar arranged formats 87 template <vidl_pixel_format FMT> 88 class vidl_pixel_iterator_arranged<VIDL_PIXEL_ARRANGE_PLANAR,FMT> 89 { 90 typedef typename vidl_pixel_traits_of<FMT>::type cmp_type; 91 enum { csx = vidl_pixel_traits_of<FMT>::chroma_shift_x }; 92 enum { csy = vidl_pixel_traits_of<FMT>::chroma_shift_y }; 93 enum { x_mask = (1<<(csx+1))-1 }; // last csx+1 bits are 1 94 enum { y_mask = (1<<(csy+1))-1 }; // last csy+1 bits are 1 95 unsigned int line_size_; 96 unsigned int line_cnt_; 97 cmp_type * ptr_[vidl_pixel_traits_of<FMT>::num_channels]; 98 //: these act as fractional pixel counters 99 vxl_byte step_x_, step_y_; 100 public: 101 //: Constructor vidl_pixel_iterator_arranged(const vidl_frame & frame)102 vidl_pixel_iterator_arranged(const vidl_frame& frame) 103 : line_size_(frame.ni()), line_cnt_(0), step_x_(1), step_y_(1) 104 { 105 assert(frame.pixel_format() == FMT); 106 // The following should be a static asserts 107 assert(vidl_pixel_traits_of<FMT>::arrangement() == VIDL_PIXEL_ARRANGE_PLANAR); 108 109 const unsigned size = frame.ni()*frame.nj(); 110 111 ptr_[0] = (cmp_type*)frame.data(); 112 for (unsigned int i=1; i<vidl_pixel_traits_of<FMT>::num_channels; ++i) { 113 if (i==1) 114 ptr_[i] = ptr_[i-1] + size; 115 else 116 ptr_[i] = ptr_[i-1] + ((size>>csx)>>csy); 117 } 118 } 119 120 //: Destructor 121 ~vidl_pixel_iterator_arranged() = default; 122 123 //: Step to the next pixel next()124 vidl_pixel_iterator_arranged<VIDL_PIXEL_ARRANGE_PLANAR,FMT>& next() 125 { 126 ++ptr_[0]; 127 if (vidl_pixel_traits_of<FMT>::num_channels > 1) { 128 // step only if the last csx+1 bits of step_x_ are set 129 int chroma_step = ((step_x_&x_mask) == x_mask)?1:0; 130 if (++line_cnt_ < line_size_) { 131 step_x_ += 2; 132 } 133 else 134 { 135 line_cnt_ = 0; 136 step_x_=1; 137 chroma_step = 1; 138 // step back to start of row unless the last csy+1 bits of step_y_ are set 139 if (!((step_y_&y_mask)==y_mask)) 140 chroma_step -= (line_size_>>csx); 141 step_y_ += 2; 142 } 143 for (unsigned int i=1; i<vidl_pixel_traits_of<FMT>::num_channels; ++i) { 144 ptr_[i] += chroma_step; 145 } 146 } 147 return *this; 148 } 149 150 //: Access the data operator ()(unsigned int i) const151 cmp_type operator () (unsigned int i) const 152 { 153 return *ptr_[i]; 154 } 155 156 //: Access the entire pixel at once get(cmp_type * data) const157 void get(cmp_type* data) const 158 { 159 for (unsigned int i=0; i<vidl_pixel_traits_of<FMT>::num_channels; ++i) 160 data[i] = *ptr_[i]; 161 } 162 163 //: write the entire pixel at once set(const cmp_type * data)164 void set(const cmp_type* data) 165 { 166 for (unsigned int i=0; i<vidl_pixel_traits_of<FMT>::num_channels; ++i) 167 *ptr_[i] = data[i]; 168 } 169 }; 170 171 172 template <> 173 struct vidl_pixel_iterator_arrange_valid<VIDL_PIXEL_ARRANGE_PACKED> 174 { 175 enum { value = true }; 176 }; 177 178 //: The default pixel iterator for packed arranged formats 179 template <vidl_pixel_format FMT> 180 class vidl_pixel_iterator_arranged<VIDL_PIXEL_ARRANGE_PACKED,FMT> 181 { 182 typedef typename vidl_pixel_traits_of<FMT>::type cmp_type; 183 cmp_type * ptr_; 184 enum { macro_pix_size = 1<<vidl_pixel_traits_of<FMT>::chroma_shift_x }; 185 enum { pix_step_size = (vidl_pixel_traits_of<FMT>::bits_per_pixel 186 <<vidl_pixel_traits_of<FMT>::chroma_shift_x)>>3 }; 187 vxl_byte mode_; 188 public: 189 190 //: Constructor vidl_pixel_iterator_arranged(const vidl_frame & frame)191 vidl_pixel_iterator_arranged(const vidl_frame& frame) 192 : ptr_((vxl_byte*)frame.data()), mode_(0) 193 { 194 } 195 196 //: Destructor 197 ~vidl_pixel_iterator_arranged() = default; 198 199 //: Step to the next pixel next()200 vidl_pixel_iterator_arranged<VIDL_PIXEL_ARRANGE_PACKED,FMT>& next() 201 { 202 mode_ = vxl_byte((mode_+1)%macro_pix_size); 203 if (mode_==0) 204 ptr_ += pix_step_size; 205 return *this; 206 } 207 208 //: Access the data operator ()(unsigned int i) const209 cmp_type operator () (unsigned int i) const 210 { 211 assert(i<vidl_pixel_traits_of<FMT>::num_channels); 212 return ptr_[vidl_pixel_pack_of<FMT>::offset[mode_][i]]; 213 } 214 215 //: Access the entire pixel at once get(cmp_type * data) const216 void get(cmp_type* data) const 217 { 218 for (unsigned int i=0; i<vidl_pixel_traits_of<FMT>::num_channels; ++i) 219 data[i] = ptr_[vidl_pixel_pack_of<FMT>::offset[mode_][i]]; 220 } 221 222 //: write the entire pixel at once set(const cmp_type * data)223 void set(const cmp_type* data) 224 { 225 for (unsigned int i=0; i<vidl_pixel_traits_of<FMT>::num_channels; ++i) 226 ptr_[vidl_pixel_pack_of<FMT>::offset[mode_][i]] = data[i]; 227 } 228 }; 229 230 231 template <vidl_pixel_format FMT> 232 struct vidl_pixel_iterator_valid 233 { 234 enum { value = vidl_pixel_iterator_arrange_valid< 235 vidl_pixel_arrangement(vidl_pixel_traits_of<FMT>::arrangement_idx) >::value }; 236 }; 237 238 239 //: The default pixel iterator 240 // used for non-planar non-packed formats 241 template <vidl_pixel_format FMT> 242 class vidl_pixel_iterator_of : public vidl_pixel_iterator 243 { 244 enum { arrangement = vidl_pixel_traits_of<FMT>::arrangement_idx }; 245 typedef vidl_pixel_iterator_arranged<vidl_pixel_arrangement(arrangement),FMT> arranged_itr; 246 arranged_itr itr_; 247 typedef typename vidl_pixel_traits_of<FMT>::type cmp_type; 248 public: 249 //: Constructor vidl_pixel_iterator_of(const vidl_frame & frame)250 vidl_pixel_iterator_of(const vidl_frame& frame) : itr_(frame) {} 251 252 //: Destructor 253 ~vidl_pixel_iterator_of<FMT>() override = default; 254 255 //: Return the pixel format pixel_format() const256 vidl_pixel_format pixel_format() const override 257 { return FMT; } 258 259 //: Pre-increment: step to the next pixel operator ++()260 vidl_pixel_iterator& operator++ () override 261 { itr_.next(); return *this; } 262 263 //: Access the data operator ()(unsigned int i) const264 cmp_type operator () (unsigned int i) const 265 { return itr_(i); } 266 267 //: Copy the pixel data into a byte array get_data(vxl_byte * data) const268 void get_data(vxl_byte* data) const override 269 { itr_.get(reinterpret_cast<cmp_type*>(data)); } 270 271 //: Set the pixel data from a byte array set_data(const vxl_byte * data)272 void set_data(const vxl_byte* data) override 273 { itr_.set(reinterpret_cast<const cmp_type*>(data)); } 274 }; 275 276 277 //----------------------------------------------------------------------------- 278 // Custom Pixel Iterators 279 //----------------------------------------------------------------------------- 280 281 282 //: Iterator for monochrome boolean images 283 template <> 284 struct vidl_pixel_iterator_valid<VIDL_PIXEL_FORMAT_MONO_1> 285 { enum { value = true }; }; 286 287 template <> 288 class vidl_pixel_iterator_of<VIDL_PIXEL_FORMAT_MONO_1> 289 : public vidl_pixel_iterator 290 { 291 vxl_byte bit_mask_; 292 vxl_byte * ptr_; 293 public: 294 //: Constructor vidl_pixel_iterator_of(const vidl_frame & frame)295 vidl_pixel_iterator_of(const vidl_frame& frame) 296 : bit_mask_(128), ptr_((vxl_byte*)frame.data()) 297 { 298 assert(frame.pixel_format() == VIDL_PIXEL_FORMAT_MONO_1); 299 } 300 301 //: Destructor 302 ~vidl_pixel_iterator_of<VIDL_PIXEL_FORMAT_MONO_1>() override = default; 303 304 //: Return the pixel format pixel_format() const305 vidl_pixel_format pixel_format() const override 306 { return VIDL_PIXEL_FORMAT_MONO_1; } 307 308 //: Step to the next pixel next()309 vidl_pixel_iterator_of<VIDL_PIXEL_FORMAT_MONO_1>& next() 310 { 311 bit_mask_ >>= 1; 312 if (!bit_mask_) { 313 bit_mask_ = 128; 314 ++ptr_; 315 } 316 317 return *this; 318 } 319 320 //: Pre-increment: step to the next pixel operator ++()321 vidl_pixel_iterator& operator++ () override 322 { 323 return this->next(); 324 } 325 326 //: Access the data operator ()(unsigned int i) const327 bool operator () (unsigned int i) const 328 { 329 assert(i==0); 330 return (ptr_[0] & bit_mask_) != 0; 331 } 332 333 //: Access the entire pixel at once get(bool * data) const334 void get(bool* data) const 335 { 336 data[0] = (ptr_[0] & bit_mask_) != 0; 337 } 338 339 //: write the entire pixel at once set(const bool * data)340 void set(const bool* data) 341 { 342 ptr_[0] &= ~bit_mask_ & (data[0]?bit_mask_:0); 343 } 344 345 //: Copy the pixel data into a byte array get_data(vxl_byte * data) const346 void get_data(vxl_byte* data) const override 347 { 348 this->get(reinterpret_cast<bool*>(data)); 349 } 350 351 //: Set the pixel data from a byte array set_data(const vxl_byte * data)352 void set_data(const vxl_byte* data) override 353 { 354 this->set(reinterpret_cast<const bool*>(data)); 355 } 356 }; 357 358 359 #endif // vidl_pixel_iterator_hxx_ 360