TuttleOFX  1
transform_pixels_progress.hpp
Go to the documentation of this file.
00001 #ifndef _TERRY_ALGORITHM_TRANSFORM_PIXELS_PROGRESS_HPP_
00002 #define _TERRY_ALGORITHM_TRANSFORM_PIXELS_PROGRESS_HPP_
00003 
00004 #include <boost/gil/gil_config.hpp>
00005 #include <boost/gil/gil_concept.hpp>
00006 #include <boost/gil/color_base_algorithm.hpp>
00007 #include <boost/gil/image_view.hpp>
00008 #include <boost/gil/image_view_factory.hpp>
00009 #include <boost/gil/bit_aligned_pixel_iterator.hpp>
00010 
00011 namespace terry {
00012 namespace algorithm {
00013 
00014 //////////////////////////////////////////////////////////////////////////////////////
00015 ///
00016 /// transform_pixels
00017 ///
00018 //////////////////////////////////////////////////////////////////////////////////////
00019 
00020 /// \defgroup ImageViewSTLAlgorithmsTransformPixels transform_pixels
00021 /// \ingroup ImageViewSTLAlgorithms
00022 /// \brief std::transform for image views
00023 
00024 /// \ingroup ImageViewSTLAlgorithmsTransformPixels
00025 /// \brief std::transform for image views
00026 template <typename View, typename F, typename Progress>
00027 GIL_FORCEINLINE
00028 F transform_pixels_progress( const View& dst, F& fun, Progress& p )
00029 {
00030         for( std::ptrdiff_t y = 0; y < dst.height(); ++y )
00031         {
00032                 typename View::x_iterator dstIt = dst.row_begin( y );
00033                 for( std::ptrdiff_t x = 0; x < dst.width(); ++x )
00034                         fun( dstIt[x] );
00035                 if( p.progressForward( dst.width() ) )
00036                         return fun;
00037         }
00038         return fun;
00039 }
00040 template <typename View, typename F, typename Progress>
00041 GIL_FORCEINLINE
00042 F transform_pixels_progress( const View& dst, const F& fun, Progress& p )
00043 {
00044         for( std::ptrdiff_t y = 0; y < dst.height(); ++y )
00045         {
00046                 typename View::x_iterator dstIt = dst.row_begin( y );
00047                 for( std::ptrdiff_t x = 0; x < dst.width(); ++x )
00048                         fun( dstIt[x] );
00049                 if( p.progressForward( dst.width() ) )
00050                         return fun;
00051         }
00052         return fun;
00053 }
00054 
00055 /// \ingroup ImageViewSTLAlgorithmsTransformPixels
00056 /// \brief std::transform for image views
00057 template <typename View1, typename View2, typename F, typename Progress>
00058 GIL_FORCEINLINE
00059 F transform_pixels_progress( const View1& src, const View2& dst, F& fun, Progress& p )
00060 {
00061         assert( src.dimensions() == dst.dimensions() );
00062         for( std::ptrdiff_t y = 0; y < src.height(); ++y )
00063         {
00064                 typename View1::x_iterator srcIt = src.row_begin( y );
00065                 typename View2::x_iterator dstIt = dst.row_begin( y );
00066                 for( std::ptrdiff_t x = 0; x < src.width(); ++x )
00067                         dstIt[x] = fun( srcIt[x] );
00068                 if( p.progressForward( dst.width() ) )
00069                         return fun;
00070         }
00071         return fun;
00072 }
00073 
00074 template <typename View1, typename View2, typename F, typename Progress>
00075 GIL_FORCEINLINE
00076 F transform_pixels_progress( const View1& src, const View2& dst, const F& fun, Progress& p )
00077 {
00078         assert( src.dimensions() == dst.dimensions() );
00079         for( std::ptrdiff_t y = 0; y < src.height(); ++y )
00080         {
00081                 typename View1::x_iterator srcIt = src.row_begin( y );
00082                 typename View2::x_iterator dstIt = dst.row_begin( y );
00083                 for( std::ptrdiff_t x = 0; x < src.width(); ++x )
00084                         dstIt[x] = fun( srcIt[x] );
00085                 if( p.progressForward( dst.width() ) )
00086                         return fun;
00087         }
00088         return fun;
00089 }
00090 
00091 /// \ingroup ImageViewSTLAlgorithmsTransformPixels
00092 /// \brief transform_pixels with two sources
00093 template <typename View1, typename View2, typename View3, typename F, typename Progress>
00094 GIL_FORCEINLINE
00095 F transform_pixels_progress( const View1& src1, const View2& src2, const View3& dst, F& fun, Progress& p )
00096 {
00097         assert( src1.dimensions() == dst.dimensions() );
00098         assert( src2.dimensions() == dst.dimensions() );
00099         for( std::ptrdiff_t y = 0; y < dst.height(); ++y )
00100         {
00101                 typename View1::x_iterator srcIt1 = src1.row_begin( y );
00102                 typename View2::x_iterator srcIt2 = src2.row_begin( y );
00103                 typename View3::x_iterator dstIt  = dst.row_begin( y );
00104                 for( std::ptrdiff_t x = 0; x < dst.width(); ++x )
00105                         dstIt[x] = fun( srcIt1[x], srcIt2[x] );
00106                 if( p.progressForward( dst.width() ) )
00107                         return fun;
00108         }
00109         return fun;
00110 }
00111 
00112 template <typename View1, typename View2, typename View3, typename F, typename Progress>
00113 GIL_FORCEINLINE
00114 F transform_pixels_progress( const View1& src1, const View2& src2, const View3& dst, const F& fun, Progress& p )
00115 {
00116         assert( src1.dimensions() == dst.dimensions() );
00117         assert( src2.dimensions() == dst.dimensions() );
00118         for( std::ptrdiff_t y = 0; y < dst.height(); ++y )
00119         {
00120                 typename View1::x_iterator srcIt1 = src1.row_begin( y );
00121                 typename View2::x_iterator srcIt2 = src2.row_begin( y );
00122                 typename View3::x_iterator dstIt  = dst.row_begin( y );
00123                 for( std::ptrdiff_t x = 0; x < dst.width(); ++x )
00124                         dstIt[x] = fun( srcIt1[x], srcIt2[x] );
00125                 if( p.progressForward( dst.width() ) )
00126                         return fun;
00127         }
00128         return fun;
00129 }
00130 
00131 /// \ingroup ImageViewSTLAlgorithmsTransformPixels
00132 /// \brief transform_pixels with two sources
00133 template <typename View1, typename View2, typename View3, typename View4, typename F, typename Progress>
00134 GIL_FORCEINLINE
00135 F transform_pixels_progress( const View1& src1, const View2& src2, const View3& src3, const View4& dst, F& fun, Progress& p )
00136 {
00137         assert( src1.dimensions() == dst.dimensions() );
00138         assert( src2.dimensions() == dst.dimensions() );
00139         assert( src3.dimensions() == dst.dimensions() );
00140         for( std::ptrdiff_t y = 0; y < dst.height(); ++y )
00141         {
00142                 typename View1::x_iterator srcIt1 = src1.row_begin( y );
00143                 typename View2::x_iterator srcIt2 = src2.row_begin( y );
00144                 typename View3::x_iterator srcIt3 = src3.row_begin( y );
00145                 typename View4::x_iterator dstIt  = dst.row_begin( y );
00146                 for( std::ptrdiff_t x = 0; x < dst.width(); ++x )
00147                         dstIt[x] = fun( srcIt1[x], srcIt2[x], srcIt3[x] );
00148                 if( p.progressForward( dst.width() ) )
00149                         return fun;
00150         }
00151         return fun;
00152 }
00153 
00154 template <typename View1, typename View2, typename View3, typename View4, typename F, typename Progress>
00155 GIL_FORCEINLINE
00156 F transform_pixels_progress( const View1& src1, const View2& src2, const View3& src3, const View4& dst, const F& fun, Progress& p )
00157 {
00158         assert( src1.dimensions() == dst.dimensions() );
00159         assert( src2.dimensions() == dst.dimensions() );
00160         assert( src3.dimensions() == dst.dimensions() );
00161         for( std::ptrdiff_t y = 0; y < dst.height(); ++y )
00162         {
00163                 typename View1::x_iterator srcIt1 = src1.row_begin( y );
00164                 typename View2::x_iterator srcIt2 = src2.row_begin( y );
00165                 typename View3::x_iterator srcIt3 = src3.row_begin( y );
00166                 typename View4::x_iterator dstIt  = dst.row_begin( y );
00167                 for( std::ptrdiff_t x = 0; x < dst.width(); ++x )
00168                         dstIt[x] = fun( srcIt1[x], srcIt2[x], srcIt3[x] );
00169                 if( p.progressForward( dst.width() ) )
00170                         return fun;
00171         }
00172         return fun;
00173 }
00174 
00175 
00176 //////////////////////////////////////////////////////////////////////////////////////
00177 ///
00178 /// transform_pixels_locator
00179 ///
00180 //////////////////////////////////////////////////////////////////////////////////////
00181 
00182 /// \defgroup ImageViewSTLAlgorithmsTransformPixelLocator transform_pixels_locator
00183 /// \ingroup ImageViewSTLAlgorithms
00184 /// \brief for image views (passes locators, instead of pixel references, to the function object)
00185 
00186 // 1 source/dest
00187 
00188 /// \ingroup ImageViewSTLAlgorithmsTransformPixels
00189 /// \brief std::transform for image views
00190 template <typename View, typename F, typename Progress>
00191 GIL_FORCEINLINE
00192 F transform_pixels_locator_progress( const View& dst, const Rect<std::ssize_t>& dstRod,
00193                                                                          const Rect<std::ssize_t>& renderWin, F& fun, Progress& p )
00194 {
00195         const std::ptrdiff_t renderWidth = renderWin.x2 - renderWin.x1;
00196         typename View::xy_locator dloc = dst.xy_at( renderWin.x1-dstRod.x1, renderWin.y1-dstRod.y1 );
00197         for( std::ptrdiff_t y = renderWin.y1; y < renderWin.y2; ++y )
00198         {
00199                 for( std::ptrdiff_t x = renderWin.x1;
00200                      x < renderWin.x2;
00201                      ++x, ++dloc.x() )
00202                 {
00203                         fun( dloc );
00204                 }
00205                 dloc.x() -= renderWidth; ++dloc.y();
00206                 if( p.progressForward( renderWidth ) )
00207                         return fun;
00208         }
00209         return fun;
00210 }
00211 
00212 /// \ingroup ImageViewSTLAlgorithmsTransformPixels
00213 /// \brief std::transform for image views
00214 template <typename View, typename F, typename Progress>
00215 GIL_FORCEINLINE
00216 F transform_pixels_locator_progress( const View& dst, const Rect<std::ssize_t>& dstRod,
00217                                                                          const Rect<std::ssize_t>& renderWin, const F& fun, Progress& p )
00218 {
00219         const std::ptrdiff_t renderWidth = renderWin.x2 - renderWin.x1;
00220         typename View::xy_locator dloc = dst.xy_at( renderWin.x1-dstRod.x1, renderWin.y1-dstRod.y1 );
00221         for( std::ptrdiff_t y = renderWin.y1; y < renderWin.y2; ++y )
00222         {
00223                 for( std::ptrdiff_t x = renderWin.x1;
00224                      x < renderWin.x2;
00225                      ++x, ++dloc.x() )
00226                 {
00227                         fun( dloc );
00228                 }
00229                 dloc.x() -= renderWidth; ++dloc.y();
00230                 if( p.progressForward( renderWidth ) )
00231                         return fun;
00232         }
00233         return fun;
00234 }
00235 
00236 // 1 source, 1 dest
00237 
00238 /// \ingroup ImageViewSTLAlgorithmsTransformPixels
00239 /// \brief std::transform for image views
00240 template <typename View, typename ViewDst, typename F, typename Progress>
00241 GIL_FORCEINLINE
00242 F transform_pixels_locator_progress( const View& src, const Rect<std::ssize_t>& srcRod,
00243                                                                          const ViewDst& dst, const Rect<std::ssize_t>& dstRod,
00244                                                                          const Rect<std::ssize_t>& renderWin, F& fun, Progress& p )
00245 {
00246         const std::ptrdiff_t renderWidth = renderWin.x2 - renderWin.x1;
00247         typename View::xy_locator sloc = src.xy_at( renderWin.x1-srcRod.x1, renderWin.y1-srcRod.y1 );
00248         for( std::ptrdiff_t y = renderWin.y1; y < renderWin.y2; ++y )
00249         {
00250                 typename ViewDst::x_iterator dstIt = dst.x_at( renderWin.x1-dstRod.x1, y-dstRod.y1 );
00251                 for( std::ptrdiff_t x = renderWin.x1;
00252                      x < renderWin.x2;
00253                      ++x, ++sloc.x(), ++dstIt )
00254                 {
00255                         *dstIt = fun( sloc );
00256                 }
00257                 sloc.x() -= renderWidth; ++sloc.y();
00258                 if( p.progressForward( renderWidth ) )
00259                         return fun;
00260         }
00261         return fun;
00262 }
00263 
00264 /// \ingroup ImageViewSTLAlgorithmsTransformPixels
00265 /// \brief std::transform for image views
00266 template <typename View, typename ViewDst, typename F, typename Progress>
00267 GIL_FORCEINLINE
00268 F transform_pixels_locator_progress( const View& src, const Rect<std::ssize_t>& srcRod,
00269                                                                          const ViewDst& dst, const Rect<std::ssize_t>& dstRod,
00270                                                                          const Rect<std::ssize_t>& renderWin, const F& fun, Progress& p )
00271 {
00272         const std::ptrdiff_t renderWidth = renderWin.x2 - renderWin.x1;
00273         typename View::xy_locator sloc = src.xy_at( renderWin.x1-srcRod.x1, renderWin.y1-srcRod.y1 );
00274         for( std::ptrdiff_t y = renderWin.y1; y < renderWin.y2; ++y )
00275         {
00276                 typename ViewDst::x_iterator dstIt = dst.x_at( renderWin.x1-dstRod.x1, y-dstRod.y1 );
00277                 for( std::ptrdiff_t x = renderWin.x1;
00278                      x < renderWin.x2;
00279                      ++x, ++sloc.x(), ++dstIt )
00280                 {
00281                         *dstIt = fun( sloc );
00282                 }
00283                 sloc.x() -= renderWidth; ++sloc.y();
00284                 if( p.progressForward( renderWidth ) )
00285                         return fun;
00286         }
00287         return fun;
00288 }
00289 
00290 // 2 sources, 1 dest
00291 
00292 /// \ingroup ImageViewSTLAlgorithmsTransformPixels
00293 /// \brief std::transform for image views
00294 template <typename View1, typename View2, typename ViewDst, typename F, typename Progress>
00295 GIL_FORCEINLINE
00296 F transform_pixels_locator_progress( const View1& src1, const Rect<std::ssize_t>& src1Rod,
00297                                                                          const View2& src2, const Rect<std::ssize_t>& src2Rod,
00298                                                                          const ViewDst& dst, const Rect<std::ssize_t>& dstRod,
00299                                                                          const Rect<std::ssize_t>& renderWin, F& fun, Progress& p )
00300 {
00301         const std::ptrdiff_t renderWidth = renderWin.x2 - renderWin.x1;
00302         typename View1::xy_locator s1loc = src1.xy_at( renderWin.x1-src1Rod.x1, renderWin.y1-src1Rod.y1 );
00303         typename View2::xy_locator s2loc = src2.xy_at( renderWin.x1-src2Rod.x1, renderWin.y1-src2Rod.y1 );
00304         for( std::ptrdiff_t y = renderWin.y1; y < renderWin.y2; ++y )
00305         {
00306                 typename ViewDst::x_iterator dstIt = dst.x_at( renderWin.x1-dstRod.x1, y-dstRod.y1 );
00307                 for( std::ptrdiff_t x = renderWin.x1;
00308                      x < renderWin.x2;
00309                      ++x, ++s1loc.x(), ++s2loc.x(), ++dstIt )
00310                 {
00311                         *dstIt = fun( s1loc, s2loc );
00312                 }
00313                 s1loc.x() -= renderWidth; ++s1loc.y();
00314                 s2loc.x() -= renderWidth; ++s2loc.y();
00315                 if( p.progressForward( renderWidth ) )
00316                         return fun;
00317         }
00318         return fun;
00319 }
00320 
00321 /// \ingroup ImageViewSTLAlgorithmsTransformPixels
00322 /// \brief std::transform for image views
00323 template <typename View1, typename View2, typename ViewDst, typename F, typename Progress>
00324 GIL_FORCEINLINE
00325 F transform_pixels_locator_progress( const View1& src1, const Rect<std::ssize_t>& src1Rod,
00326                                                                          const View2& src2, const Rect<std::ssize_t>& src2Rod,
00327                                                                          const ViewDst& dst, const Rect<std::ssize_t>& dstRod,
00328                                                                          const Rect<std::ssize_t>& renderWin, const F& fun, Progress& p )
00329 {
00330         const std::ptrdiff_t renderWidth = renderWin.x2 - renderWin.x1;
00331         typename View1::xy_locator s1loc = src1.xy_at( renderWin.x1-src1Rod.x1, renderWin.y1-src1Rod.y1 );
00332         typename View2::xy_locator s2loc = src2.xy_at( renderWin.x1-src2Rod.x1, renderWin.y1-src2Rod.y1 );
00333         for( std::ptrdiff_t y = renderWin.y1; y < renderWin.y2; ++y )
00334         {
00335                 typename ViewDst::x_iterator dstIt = dst.x_at( dstRod.x1, y-dstRod.y1 );
00336                 for( std::ptrdiff_t x = renderWin.x1;
00337                      x < renderWin.x2;
00338                      ++x, ++s1loc.x(), ++s2loc.x(), ++dstIt )
00339                 {
00340                         *dstIt = fun( s1loc, s2loc );
00341                 }
00342                 s1loc.x() -= renderWidth; ++s1loc.y();
00343                 s2loc.x() -= renderWidth; ++s2loc.y();
00344                 if( p.progressForward( renderWidth ) )
00345                         return fun;
00346         }
00347         return fun;
00348 }
00349 
00350 
00351 // 3 sources, 1 dest
00352 
00353 /// \ingroup ImageViewSTLAlgorithmsTransformPixels
00354 /// \brief std::transform for image views
00355 template <typename View1, typename View2, typename View3, typename ViewDst, typename F, typename Progress>
00356 GIL_FORCEINLINE
00357 F transform_pixels_locator_progress( const View1& src1, const Rect<std::ssize_t>& src1Rod,
00358                                                                          const View2& src2, const Rect<std::ssize_t>& src2Rod,
00359                                                                          const View2& src3, const Rect<std::ssize_t>& src3Rod,
00360                                                                          const ViewDst& dst, const Rect<std::ssize_t>& dstRod,
00361                                                                          const Rect<std::ssize_t>& renderWin, F& fun, Progress& p )
00362 {
00363         const std::ptrdiff_t renderWidth = renderWin.x2 - renderWin.x1;
00364         typename View1::xy_locator s1loc = src1.xy_at( renderWin.x1-src1Rod.x1, renderWin.y1-src1Rod.y1 );
00365         typename View2::xy_locator s2loc = src2.xy_at( renderWin.x1-src2Rod.x1, renderWin.y1-src2Rod.y1 );
00366         typename View3::xy_locator s3loc = src3.xy_at( renderWin.x1-src3Rod.x1, renderWin.y1-src3Rod.y1 );
00367         for( std::ptrdiff_t y = renderWin.y1; y < renderWin.y2; ++y )
00368         {
00369                 typename ViewDst::x_iterator dstIt = dst.x_at( dstRod.x1, y-dstRod.y1 );
00370                 for( std::ptrdiff_t x = renderWin.x1;
00371                      x < renderWin.x2;
00372                      ++x, ++s1loc.x(), ++s2loc.x(), ++s3loc.x(), ++dstIt )
00373                 {
00374                         *dstIt = fun( s1loc, s2loc, s3loc );
00375                 }
00376                 s1loc.x() -= renderWidth; ++s1loc.y();
00377                 s2loc.x() -= renderWidth; ++s2loc.y();
00378                 s3loc.x() -= renderWidth; ++s3loc.y();
00379                 if( p.progressForward( renderWidth ) )
00380                         return fun;
00381         }
00382         return fun;
00383 }
00384 
00385 /// \ingroup ImageViewSTLAlgorithmsTransformPixels
00386 /// \brief std::transform for image views
00387 template <typename View1, typename View2, typename View3, typename ViewDst, typename F, typename Progress>
00388 GIL_FORCEINLINE
00389 F transform_pixels_locator_progress( const View1& src1, const Rect<std::ssize_t>& src1Rod,
00390                                                                          const View2& src2, const Rect<std::ssize_t>& src2Rod,
00391                                                                          const View2& src3, const Rect<std::ssize_t>& src3Rod,
00392                                                                          const ViewDst& dst, const Rect<std::ssize_t>& dstRod,
00393                                                                          const Rect<std::ssize_t>& renderWin, const F& fun, Progress& p )
00394 {
00395         const std::ptrdiff_t renderWidth = renderWin.x2 - renderWin.x1;
00396         typename View1::xy_locator s1loc = src1.xy_at( renderWin.x1-src1Rod.x1, renderWin.y1-src1Rod.y1 );
00397         typename View2::xy_locator s2loc = src2.xy_at( renderWin.x1-src2Rod.x1, renderWin.y1-src2Rod.y1 );
00398         typename View3::xy_locator s3loc = src3.xy_at( renderWin.x1-src3Rod.x1, renderWin.y1-src3Rod.y1 );
00399         for( std::ptrdiff_t y = renderWin.y1; y < renderWin.y2; ++y )
00400         {
00401                 typename ViewDst::x_iterator dstIt = dst.x_at( dstRod.x1, y-dstRod.y1 );
00402                 for( std::ptrdiff_t x = renderWin.x1;
00403                      x < renderWin.x2;
00404                      ++x, ++s1loc.x(), ++s2loc.x(), ++s3loc.x(), ++dstIt )
00405                 {
00406                         *dstIt = fun( s1loc, s2loc, s3loc );
00407                 }
00408                 s1loc.x() -= renderWidth; ++s1loc.y();
00409                 s2loc.x() -= renderWidth; ++s2loc.y();
00410                 s3loc.x() -= renderWidth; ++s3loc.y();
00411                 if( p.progressForward( renderWidth ) )
00412                         return fun;
00413         }
00414         return fun;
00415 }
00416 
00417 
00418 
00419 
00420 }
00421 }
00422 
00423 #endif