Go to the documentation of this file.00001
00002 #ifndef vidl_pixel_iterator_txx_
00003 #define vidl_pixel_iterator_txx_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "vidl_pixel_iterator.h"
00018 #include "vidl_color.h"
00019 #include <vxl_config.h>
00020 #include <vcl_cassert.h>
00021
00022
00023
00024
00025 template <vidl_pixel_arrangement AR>
00026 struct vidl_pixel_iterator_arrange_valid
00027 {
00028 enum { value = (AR == VIDL_PIXEL_ARRANGE_SINGLE) };
00029 };
00030
00031
00032
00033 template <vidl_pixel_arrangement AR, vidl_pixel_format FMT>
00034 class vidl_pixel_iterator_arranged
00035 {
00036 typedef typename vidl_pixel_traits_of<FMT>::type cmp_type;
00037 cmp_type * ptr_;
00038 public:
00039
00040 vidl_pixel_iterator_arranged(const vidl_frame& frame)
00041 : ptr_((cmp_type*)frame.data())
00042 {
00043 assert(frame.pixel_format() == FMT);
00044
00045 assert(vidl_pixel_traits_of<FMT>::bits_per_pixel%8 == 0);
00046 assert(vidl_pixel_traits_of<FMT>::arrangement() == VIDL_PIXEL_ARRANGE_SINGLE);
00047 }
00048
00049
00050 ~vidl_pixel_iterator_arranged() {}
00051
00052
00053 vidl_pixel_iterator_arranged<AR,FMT>& next()
00054 {
00055 ptr_ += vidl_pixel_traits_of<FMT>::bits_per_pixel/(sizeof(cmp_type)*8);
00056 return *this;
00057 }
00058
00059
00060 cmp_type operator () (unsigned int i) const
00061 {
00062 assert(i<vidl_pixel_traits_of<FMT>::num_channels);
00063 return vidl_color_component<FMT>::get(ptr_,i);
00064 }
00065
00066
00067 void get(cmp_type* data) const
00068 {
00069 vidl_color_component<FMT>::get_all(ptr_,data);
00070 }
00071
00072
00073 void set(const cmp_type* data)
00074 {
00075 vidl_color_component<FMT>::set_all(ptr_,data);
00076 }
00077 };
00078
00079
00080 #if VCL_CAN_DO_PARTIAL_SPECIALIZATION
00081
00082 template <>
00083 struct vidl_pixel_iterator_arrange_valid<VIDL_PIXEL_ARRANGE_PLANAR>
00084 {
00085 enum { value = true };
00086 };
00087
00088
00089
00090 template <vidl_pixel_format FMT>
00091 class vidl_pixel_iterator_arranged<VIDL_PIXEL_ARRANGE_PLANAR,FMT>
00092 {
00093 typedef typename vidl_pixel_traits_of<FMT>::type cmp_type;
00094 enum { csx = vidl_pixel_traits_of<FMT>::chroma_shift_x };
00095 enum { csy = vidl_pixel_traits_of<FMT>::chroma_shift_y };
00096 enum { x_mask = (1<<(csx+1))-1 };
00097 enum { y_mask = (1<<(csy+1))-1 };
00098 unsigned int line_size_;
00099 unsigned int line_cnt_;
00100 cmp_type * ptr_[vidl_pixel_traits_of<FMT>::num_channels];
00101
00102 vxl_byte step_x_, step_y_;
00103 public:
00104
00105 vidl_pixel_iterator_arranged(const vidl_frame& frame)
00106 : line_size_(frame.ni()), line_cnt_(0), step_x_(1), step_y_(1)
00107 {
00108 assert(frame.pixel_format() == FMT);
00109
00110 assert(vidl_pixel_traits_of<FMT>::arrangement() == VIDL_PIXEL_ARRANGE_PLANAR);
00111
00112 const unsigned size = frame.ni()*frame.nj();
00113
00114 ptr_[0] = (cmp_type*)frame.data();
00115 for (unsigned int i=1; i<vidl_pixel_traits_of<FMT>::num_channels; ++i) {
00116 if (i==1)
00117 ptr_[i] = ptr_[i-1] + size;
00118 else
00119 ptr_[i] = ptr_[i-1] + ((size>>csx)>>csy);
00120 }
00121 }
00122
00123
00124 ~vidl_pixel_iterator_arranged() {}
00125
00126
00127 vidl_pixel_iterator_arranged<VIDL_PIXEL_ARRANGE_PLANAR,FMT>& next()
00128 {
00129 ++ptr_[0];
00130 if (vidl_pixel_traits_of<FMT>::num_channels > 1) {
00131
00132 int chroma_step = ((step_x_&x_mask) == x_mask)?1:0;
00133 if (++line_cnt_ < line_size_) {
00134 step_x_ += 2;
00135 }
00136 else
00137 {
00138 line_cnt_ = 0;
00139 step_x_=1;
00140 chroma_step = 1;
00141
00142 if (!((step_y_&y_mask)==y_mask))
00143 chroma_step -= (line_size_>>csx);
00144 step_y_ += 2;
00145 }
00146 for (unsigned int i=1; i<vidl_pixel_traits_of<FMT>::num_channels; ++i) {
00147 ptr_[i] += chroma_step;
00148 }
00149 }
00150 return *this;
00151 }
00152
00153
00154 cmp_type operator () (unsigned int i) const
00155 {
00156 return *ptr_[i];
00157 }
00158
00159
00160 void get(cmp_type* data) const
00161 {
00162 for (unsigned int i=0; i<vidl_pixel_traits_of<FMT>::num_channels; ++i)
00163 data[i] = *ptr_[i];
00164 }
00165
00166
00167 void set(const cmp_type* data)
00168 {
00169 for (unsigned int i=0; i<vidl_pixel_traits_of<FMT>::num_channels; ++i)
00170 *ptr_[i] = data[i];
00171 }
00172 };
00173
00174
00175 template <>
00176 struct vidl_pixel_iterator_arrange_valid<VIDL_PIXEL_ARRANGE_PACKED>
00177 {
00178 enum { value = true };
00179 };
00180
00181
00182 template <vidl_pixel_format FMT>
00183 class vidl_pixel_iterator_arranged<VIDL_PIXEL_ARRANGE_PACKED,FMT>
00184 {
00185 typedef typename vidl_pixel_traits_of<FMT>::type cmp_type;
00186 cmp_type * ptr_;
00187 enum { macro_pix_size = 1<<vidl_pixel_traits_of<FMT>::chroma_shift_x };
00188 enum { pix_step_size = (vidl_pixel_traits_of<FMT>::bits_per_pixel
00189 <<vidl_pixel_traits_of<FMT>::chroma_shift_x)>>3 };
00190 vxl_byte mode_;
00191 public:
00192
00193
00194 vidl_pixel_iterator_arranged(const vidl_frame& frame)
00195 : ptr_((vxl_byte*)frame.data()), mode_(0)
00196 {
00197 }
00198
00199
00200 ~vidl_pixel_iterator_arranged() {}
00201
00202
00203 vidl_pixel_iterator_arranged<VIDL_PIXEL_ARRANGE_PACKED,FMT>& next()
00204 {
00205 mode_ = vxl_byte((mode_+1)%macro_pix_size);
00206 if (mode_==0)
00207 ptr_ += pix_step_size;
00208 return *this;
00209 }
00210
00211
00212 cmp_type operator () (unsigned int i) const
00213 {
00214 assert(i<vidl_pixel_traits_of<FMT>::num_channels);
00215 return ptr_[vidl_pixel_pack_of<FMT>::offset[mode_][i]];
00216 }
00217
00218
00219 void get(cmp_type* data) const
00220 {
00221 for (unsigned int i=0; i<vidl_pixel_traits_of<FMT>::num_channels; ++i)
00222 data[i] = ptr_[vidl_pixel_pack_of<FMT>::offset[mode_][i]];
00223 }
00224
00225
00226 void set(const cmp_type* data)
00227 {
00228 for (unsigned int i=0; i<vidl_pixel_traits_of<FMT>::num_channels; ++i)
00229 ptr_[vidl_pixel_pack_of<FMT>::offset[mode_][i]] = data[i];
00230 }
00231 };
00232
00233
00234 #endif
00235
00236
00237 template <vidl_pixel_format FMT>
00238 struct vidl_pixel_iterator_valid
00239 {
00240 enum { value = vidl_pixel_iterator_arrange_valid<
00241 vidl_pixel_arrangement(vidl_pixel_traits_of<FMT>::arrangement_idx) >::value };
00242 };
00243
00244
00245
00246
00247 template <vidl_pixel_format FMT>
00248 class vidl_pixel_iterator_of : public vidl_pixel_iterator
00249 {
00250 enum { arrangement = vidl_pixel_traits_of<FMT>::arrangement_idx };
00251 typedef vidl_pixel_iterator_arranged<vidl_pixel_arrangement(arrangement),FMT> arranged_itr;
00252 arranged_itr itr_;
00253 typedef typename vidl_pixel_traits_of<FMT>::type cmp_type;
00254 public:
00255
00256 vidl_pixel_iterator_of(const vidl_frame& frame) : itr_(frame) {}
00257
00258
00259 virtual ~vidl_pixel_iterator_of<FMT>() {}
00260
00261
00262 virtual vidl_pixel_format pixel_format() const
00263 { return FMT; }
00264
00265
00266 virtual vidl_pixel_iterator& operator++ ()
00267 { itr_.next(); return *this; }
00268
00269
00270 cmp_type operator () (unsigned int i) const
00271 { return itr_(i); }
00272
00273
00274 virtual void get_data(vxl_byte* data) const
00275 { itr_.get(reinterpret_cast<cmp_type*>(data)); }
00276
00277
00278 virtual void set_data(const vxl_byte* data)
00279 { itr_.set(reinterpret_cast<const cmp_type*>(data)); }
00280 };
00281
00282
00283
00284
00285
00286
00287
00288
00289 VCL_DEFINE_SPECIALIZATION
00290 struct vidl_pixel_iterator_valid<VIDL_PIXEL_FORMAT_MONO_1>
00291 { enum { value = true }; };
00292
00293 VCL_DEFINE_SPECIALIZATION
00294 class vidl_pixel_iterator_of<VIDL_PIXEL_FORMAT_MONO_1>
00295 : public vidl_pixel_iterator
00296 {
00297 vxl_byte bit_mask_;
00298 vxl_byte * ptr_;
00299 public:
00300
00301 vidl_pixel_iterator_of(const vidl_frame& frame)
00302 : bit_mask_(128), ptr_((vxl_byte*)frame.data())
00303 {
00304 assert(frame.pixel_format() == VIDL_PIXEL_FORMAT_MONO_1);
00305 }
00306
00307
00308 virtual ~vidl_pixel_iterator_of<VIDL_PIXEL_FORMAT_MONO_1>() {}
00309
00310
00311 virtual vidl_pixel_format pixel_format() const
00312 { return VIDL_PIXEL_FORMAT_MONO_1; }
00313
00314
00315 vidl_pixel_iterator_of<VIDL_PIXEL_FORMAT_MONO_1>& next()
00316 {
00317 bit_mask_ >>= 1;
00318 if (!bit_mask_) {
00319 bit_mask_ = 128;
00320 ++ptr_;
00321 }
00322
00323 return *this;
00324 }
00325
00326
00327 virtual vidl_pixel_iterator& operator++ ()
00328 {
00329 return this->next();
00330 }
00331
00332
00333 bool operator () (unsigned int i) const
00334 {
00335 assert(i==0);
00336 return (ptr_[0] & bit_mask_) != 0;
00337 }
00338
00339
00340 void get(bool* data) const
00341 {
00342 data[0] = (ptr_[0] & bit_mask_) != 0;
00343 }
00344
00345
00346 void set(const bool* data)
00347 {
00348 ptr_[0] &= ~bit_mask_ & (data[0]?bit_mask_:0);
00349 }
00350
00351
00352 virtual void get_data(vxl_byte* data) const
00353 {
00354 this->get(reinterpret_cast<bool*>(data));
00355 }
00356
00357
00358 virtual void set_data(const vxl_byte* data)
00359 {
00360 this->set(reinterpret_cast<const bool*>(data));
00361 }
00362 };
00363
00364
00365 #endif // vidl_pixel_iterator_txx_