include/opencv2/gpu/device/border_interpolate.hpp
Go to the documentation of this file.
00001 /*M///////////////////////////////////////////////////////////////////////////////////////
00002 //
00003 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
00004 //
00005 //  By downloading, copying, installing or using the software you agree to this license.
00006 //  If you do not agree to this license, do not download, install,
00007 //  copy or use the software.
00008 //
00009 //
00010 //                           License Agreement
00011 //                For Open Source Computer Vision Library
00012 //
00013 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
00014 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
00015 // Third party copyrights are property of their respective owners.
00016 //
00017 // Redistribution and use in source and binary forms, with or without modification,
00018 // are permitted provided that the following conditions are met:
00019 //
00020 //   * Redistribution's of source code must retain the above copyright notice,
00021 //     this list of conditions and the following disclaimer.
00022 //
00023 //   * Redistribution's in binary form must reproduce the above copyright notice,
00024 //     this list of conditions and the following disclaimer in the documentation
00025 //     and/or other materials provided with the distribution.
00026 //
00027 //   * The name of the copyright holders may not be used to endorse or promote products
00028 //     derived from this software without specific prior written permission.
00029 //
00030 // This software is provided by the copyright holders and contributors "as is" and
00031 // any express or bpied warranties, including, but not limited to, the bpied
00032 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00033 // In no event shall the Intel Corporation or contributors be liable for any direct,
00034 // indirect, incidental, special, exemplary, or consequential damages
00035 // (including, but not limited to, procurement of substitute goods or services;
00036 // loss of use, data, or profits; or business interruption) however caused
00037 // and on any theory of liability, whether in contract, strict liability,
00038 // or tort (including negligence or otherwise) arising in any way out of
00039 // the use of this software, even if advised of the possibility of such damage.
00040 //
00041 //M*/
00042 
00043 #ifndef __OPENCV_GPU_BORDER_INTERPOLATE_HPP__
00044 #define __OPENCV_GPU_BORDER_INTERPOLATE_HPP__
00045 
00046 #include "saturate_cast.hpp"
00047 #include "vec_traits.hpp"
00048 #include "vec_math.hpp"
00049 
00050 namespace cv { namespace gpu { namespace device
00051 {
00053     // BrdConstant
00054 
00055     template <typename D> struct BrdRowConstant
00056     {
00057         typedef D result_type;
00058 
00059         explicit __host__ __device__ __forceinline__ BrdRowConstant(int width_, const D& val_ = VecTraits<D>::all(0)) : width(width_), val(val_) {}
00060 
00061         template <typename T> __device__ __forceinline__ D at_low(int x, const T* data) const
00062         {
00063             return x >= 0 ? saturate_cast<D>(data[x]) : val;
00064         }
00065 
00066         template <typename T> __device__ __forceinline__ D at_high(int x, const T* data) const
00067         {
00068             return x < width ? saturate_cast<D>(data[x]) : val;
00069         }
00070 
00071         template <typename T> __device__ __forceinline__ D at(int x, const T* data) const
00072         {
00073             return (x >= 0 && x < width) ? saturate_cast<D>(data[x]) : val;
00074         }
00075 
00076         const int width;
00077         const D val;
00078     };
00079 
00080     template <typename D> struct BrdColConstant
00081     {
00082         typedef D result_type;
00083 
00084         explicit __host__ __device__ __forceinline__ BrdColConstant(int height_, const D& val_ = VecTraits<D>::all(0)) : height(height_), val(val_) {}
00085 
00086         template <typename T> __device__ __forceinline__ D at_low(int y, const T* data, size_t step) const
00087         {
00088             return y >= 0 ? saturate_cast<D>(*(const T*)((const char*)data + y * step)) : val;
00089         }
00090 
00091         template <typename T> __device__ __forceinline__ D at_high(int y, const T* data, size_t step) const
00092         {
00093             return y < height ? saturate_cast<D>(*(const T*)((const char*)data + y * step)) : val;
00094         }
00095 
00096         template <typename T> __device__ __forceinline__ D at(int y, const T* data, size_t step) const
00097         {
00098             return (y >= 0 && y < height) ? saturate_cast<D>(*(const T*)((const char*)data + y * step)) : val;
00099         }
00100 
00101         const int height;
00102         const D val;
00103     };
00104 
00105     template <typename D> struct BrdConstant
00106     {
00107         typedef D result_type;
00108 
00109         __host__ __device__ __forceinline__ BrdConstant(int height_, int width_, const D& val_ = VecTraits<D>::all(0)) : height(height_), width(width_), val(val_)
00110         {
00111         }
00112 
00113         template <typename T> __device__ __forceinline__ D at(int y, int x, const T* data, size_t step) const
00114         {
00115             return (x >= 0 && x < width && y >= 0 && y < height) ? saturate_cast<D>(((const T*)((const uchar*)data + y * step))[x]) : val;
00116         }
00117 
00118         template <typename Ptr2D> __device__ __forceinline__ D at(typename Ptr2D::index_type y, typename Ptr2D::index_type x, const Ptr2D& src) const
00119         {
00120             return (x >= 0 && x < width && y >= 0 && y < height) ? saturate_cast<D>(src(y, x)) : val;
00121         }
00122 
00123         const int height;
00124         const int width;
00125         const D val;
00126     };
00127 
00129     // BrdReplicate
00130 
00131     template <typename D> struct BrdRowReplicate
00132     {
00133         typedef D result_type;
00134 
00135         explicit __host__ __device__ __forceinline__ BrdRowReplicate(int width) : last_col(width - 1) {}
00136         template <typename U> __host__ __device__ __forceinline__ BrdRowReplicate(int width, U) : last_col(width - 1) {}
00137 
00138         __device__ __forceinline__ int idx_col_low(int x) const
00139         {
00140             return ::max(x, 0);
00141         }
00142 
00143         __device__ __forceinline__ int idx_col_high(int x) const
00144         {
00145             return ::min(x, last_col);
00146         }
00147 
00148         __device__ __forceinline__ int idx_col(int x) const
00149         {
00150             return idx_col_low(idx_col_high(x));
00151         }
00152 
00153         template <typename T> __device__ __forceinline__ D at_low(int x, const T* data) const
00154         {
00155             return saturate_cast<D>(data[idx_col_low(x)]);
00156         }
00157 
00158         template <typename T> __device__ __forceinline__ D at_high(int x, const T* data) const
00159         {
00160             return saturate_cast<D>(data[idx_col_high(x)]);
00161         }
00162 
00163         template <typename T> __device__ __forceinline__ D at(int x, const T* data) const
00164         {
00165             return saturate_cast<D>(data[idx_col(x)]);
00166         }
00167 
00168         const int last_col;
00169     };
00170 
00171     template <typename D> struct BrdColReplicate
00172     {
00173         typedef D result_type;
00174 
00175         explicit __host__ __device__ __forceinline__ BrdColReplicate(int height) : last_row(height - 1) {}
00176         template <typename U> __host__ __device__ __forceinline__ BrdColReplicate(int height, U) : last_row(height - 1) {}
00177 
00178         __device__ __forceinline__ int idx_row_low(int y) const
00179         {
00180             return ::max(y, 0);
00181         }
00182 
00183         __device__ __forceinline__ int idx_row_high(int y) const
00184         {
00185             return ::min(y, last_row);
00186         }
00187 
00188         __device__ __forceinline__ int idx_row(int y) const
00189         {
00190             return idx_row_low(idx_row_high(y));
00191         }
00192 
00193         template <typename T> __device__ __forceinline__ D at_low(int y, const T* data, size_t step) const
00194         {
00195             return saturate_cast<D>(*(const T*)((const char*)data + idx_row_low(y) * step));
00196         }
00197 
00198         template <typename T> __device__ __forceinline__ D at_high(int y, const T* data, size_t step) const
00199         {
00200             return saturate_cast<D>(*(const T*)((const char*)data + idx_row_high(y) * step));
00201         }
00202 
00203         template <typename T> __device__ __forceinline__ D at(int y, const T* data, size_t step) const
00204         {
00205             return saturate_cast<D>(*(const T*)((const char*)data + idx_row(y) * step));
00206         }
00207 
00208         const int last_row;
00209     };
00210 
00211     template <typename D> struct BrdReplicate
00212     {
00213         typedef D result_type;
00214 
00215         __host__ __device__ __forceinline__ BrdReplicate(int height, int width) : last_row(height - 1), last_col(width - 1) {}
00216         template <typename U> __host__ __device__ __forceinline__ BrdReplicate(int height, int width, U) : last_row(height - 1), last_col(width - 1) {}
00217 
00218         __device__ __forceinline__ int idx_row_low(int y) const
00219         {
00220             return ::max(y, 0);
00221         }
00222 
00223         __device__ __forceinline__ int idx_row_high(int y) const
00224         {
00225             return ::min(y, last_row);
00226         }
00227 
00228         __device__ __forceinline__ int idx_row(int y) const
00229         {
00230             return idx_row_low(idx_row_high(y));
00231         }
00232 
00233         __device__ __forceinline__ int idx_col_low(int x) const
00234         {
00235             return ::max(x, 0);
00236         }
00237 
00238         __device__ __forceinline__ int idx_col_high(int x) const
00239         {
00240             return ::min(x, last_col);
00241         }
00242 
00243         __device__ __forceinline__ int idx_col(int x) const
00244         {
00245             return idx_col_low(idx_col_high(x));
00246         }
00247 
00248         template <typename T> __device__ __forceinline__ D at(int y, int x, const T* data, size_t step) const
00249         {
00250             return saturate_cast<D>(((const T*)((const char*)data + idx_row(y) * step))[idx_col(x)]);
00251         }
00252 
00253         template <typename Ptr2D> __device__ __forceinline__ D at(typename Ptr2D::index_type y, typename Ptr2D::index_type x, const Ptr2D& src) const
00254         {
00255             return saturate_cast<D>(src(idx_row(y), idx_col(x)));
00256         }
00257 
00258         const int last_row;
00259         const int last_col;
00260     };
00261 
00263     // BrdReflect101
00264 
00265     template <typename D> struct BrdRowReflect101
00266     {
00267         typedef D result_type;
00268 
00269         explicit __host__ __device__ __forceinline__ BrdRowReflect101(int width) : last_col(width - 1) {}
00270         template <typename U> __host__ __device__ __forceinline__ BrdRowReflect101(int width, U) : last_col(width - 1) {}
00271 
00272         __device__ __forceinline__ int idx_col_low(int x) const
00273         {
00274             return ::abs(x) % (last_col + 1);
00275         }
00276 
00277         __device__ __forceinline__ int idx_col_high(int x) const
00278         {
00279             return ::abs(last_col - ::abs(last_col - x)) % (last_col + 1);
00280         }
00281 
00282         __device__ __forceinline__ int idx_col(int x) const
00283         {
00284             return idx_col_low(idx_col_high(x));
00285         }
00286 
00287         template <typename T> __device__ __forceinline__ D at_low(int x, const T* data) const
00288         {
00289             return saturate_cast<D>(data[idx_col_low(x)]);
00290         }
00291 
00292         template <typename T> __device__ __forceinline__ D at_high(int x, const T* data) const
00293         {
00294             return saturate_cast<D>(data[idx_col_high(x)]);
00295         }
00296 
00297         template <typename T> __device__ __forceinline__ D at(int x, const T* data) const
00298         {
00299             return saturate_cast<D>(data[idx_col(x)]);
00300         }
00301 
00302         const int last_col;
00303     };
00304 
00305     template <typename D> struct BrdColReflect101
00306     {
00307         typedef D result_type;
00308 
00309         explicit __host__ __device__ __forceinline__ BrdColReflect101(int height) : last_row(height - 1) {}
00310         template <typename U> __host__ __device__ __forceinline__ BrdColReflect101(int height, U) : last_row(height - 1) {}
00311 
00312         __device__ __forceinline__ int idx_row_low(int y) const
00313         {
00314             return ::abs(y) % (last_row + 1);
00315         }
00316 
00317         __device__ __forceinline__ int idx_row_high(int y) const
00318         {
00319             return ::abs(last_row - ::abs(last_row - y)) % (last_row + 1);
00320         }
00321 
00322         __device__ __forceinline__ int idx_row(int y) const
00323         {
00324             return idx_row_low(idx_row_high(y));
00325         }
00326 
00327         template <typename T> __device__ __forceinline__ D at_low(int y, const T* data, size_t step) const
00328         {
00329             return saturate_cast<D>(*(const D*)((const char*)data + idx_row_low(y) * step));
00330         }
00331 
00332         template <typename T> __device__ __forceinline__ D at_high(int y, const T* data, size_t step) const
00333         {
00334             return saturate_cast<D>(*(const D*)((const char*)data + idx_row_high(y) * step));
00335         }
00336 
00337         template <typename T> __device__ __forceinline__ D at(int y, const T* data, size_t step) const
00338         {
00339             return saturate_cast<D>(*(const D*)((const char*)data + idx_row(y) * step));
00340         }
00341 
00342         const int last_row;
00343     };
00344 
00345     template <typename D> struct BrdReflect101
00346     {
00347         typedef D result_type;
00348 
00349         __host__ __device__ __forceinline__ BrdReflect101(int height, int width) : last_row(height - 1), last_col(width - 1) {}
00350         template <typename U> __host__ __device__ __forceinline__ BrdReflect101(int height, int width, U) : last_row(height - 1), last_col(width - 1) {}
00351 
00352         __device__ __forceinline__ int idx_row_low(int y) const
00353         {
00354             return ::abs(y) % (last_row + 1);
00355         }
00356 
00357         __device__ __forceinline__ int idx_row_high(int y) const
00358         {
00359             return ::abs(last_row - ::abs(last_row - y)) % (last_row + 1);
00360         }
00361 
00362         __device__ __forceinline__ int idx_row(int y) const
00363         {
00364             return idx_row_low(idx_row_high(y));
00365         }
00366 
00367         __device__ __forceinline__ int idx_col_low(int x) const
00368         {
00369             return ::abs(x) % (last_col + 1);
00370         }
00371 
00372         __device__ __forceinline__ int idx_col_high(int x) const
00373         {
00374             return ::abs(last_col - ::abs(last_col - x)) % (last_col + 1);
00375         }
00376 
00377         __device__ __forceinline__ int idx_col(int x) const
00378         {
00379             return idx_col_low(idx_col_high(x));
00380         }
00381 
00382         template <typename T> __device__ __forceinline__ D at(int y, int x, const T* data, size_t step) const
00383         {
00384             return saturate_cast<D>(((const T*)((const char*)data + idx_row(y) * step))[idx_col(x)]);
00385         }
00386 
00387         template <typename Ptr2D> __device__ __forceinline__ D at(typename Ptr2D::index_type y, typename Ptr2D::index_type x, const Ptr2D& src) const
00388         {
00389             return saturate_cast<D>(src(idx_row(y), idx_col(x)));
00390         }
00391 
00392         const int last_row;
00393         const int last_col;
00394     };
00395 
00397     // BrdReflect
00398 
00399     template <typename D> struct BrdRowReflect
00400     {
00401         typedef D result_type;
00402 
00403         explicit __host__ __device__ __forceinline__ BrdRowReflect(int width) : last_col(width - 1) {}
00404         template <typename U> __host__ __device__ __forceinline__ BrdRowReflect(int width, U) : last_col(width - 1) {}
00405 
00406         __device__ __forceinline__ int idx_col_low(int x) const
00407         {
00408             return (::abs(x) - (x < 0)) % (last_col + 1);
00409         }
00410 
00411         __device__ __forceinline__ int idx_col_high(int x) const
00412         {
00413             return ::abs(last_col - ::abs(last_col - x) + (x > last_col)) % (last_col + 1);
00414         }
00415 
00416         __device__ __forceinline__ int idx_col(int x) const
00417         {
00418             return idx_col_high(::abs(x) - (x < 0));
00419         }
00420 
00421         template <typename T> __device__ __forceinline__ D at_low(int x, const T* data) const
00422         {
00423             return saturate_cast<D>(data[idx_col_low(x)]);
00424         }
00425 
00426         template <typename T> __device__ __forceinline__ D at_high(int x, const T* data) const
00427         {
00428             return saturate_cast<D>(data[idx_col_high(x)]);
00429         }
00430 
00431         template <typename T> __device__ __forceinline__ D at(int x, const T* data) const
00432         {
00433             return saturate_cast<D>(data[idx_col(x)]);
00434         }
00435 
00436         const int last_col;
00437     };
00438 
00439     template <typename D> struct BrdColReflect
00440     {
00441         typedef D result_type;
00442 
00443         explicit __host__ __device__ __forceinline__ BrdColReflect(int height) : last_row(height - 1) {}
00444         template <typename U> __host__ __device__ __forceinline__ BrdColReflect(int height, U) : last_row(height - 1) {}
00445 
00446         __device__ __forceinline__ int idx_row_low(int y) const
00447         {
00448             return (::abs(y) - (y < 0)) % (last_row + 1);
00449         }
00450 
00451         __device__ __forceinline__ int idx_row_high(int y) const
00452         {
00453             return ::abs(last_row - ::abs(last_row - y) + (y > last_row)) % (last_row + 1);
00454         }
00455 
00456         __device__ __forceinline__ int idx_row(int y) const
00457         {
00458             return idx_row_high(::abs(y) - (y < 0));
00459         }
00460 
00461         template <typename T> __device__ __forceinline__ D at_low(int y, const T* data, size_t step) const
00462         {
00463             return saturate_cast<D>(*(const D*)((const char*)data + idx_row_low(y) * step));
00464         }
00465 
00466         template <typename T> __device__ __forceinline__ D at_high(int y, const T* data, size_t step) const
00467         {
00468             return saturate_cast<D>(*(const D*)((const char*)data + idx_row_high(y) * step));
00469         }
00470 
00471         template <typename T> __device__ __forceinline__ D at(int y, const T* data, size_t step) const
00472         {
00473             return saturate_cast<D>(*(const D*)((const char*)data + idx_row(y) * step));
00474         }
00475 
00476         const int last_row;
00477     };
00478 
00479     template <typename D> struct BrdReflect
00480     {
00481         typedef D result_type;
00482 
00483         __host__ __device__ __forceinline__ BrdReflect(int height, int width) : last_row(height - 1), last_col(width - 1) {}
00484         template <typename U> __host__ __device__ __forceinline__ BrdReflect(int height, int width, U) : last_row(height - 1), last_col(width - 1) {}
00485 
00486         __device__ __forceinline__ int idx_row_low(int y) const
00487         {
00488             return (::abs(y) - (y < 0)) % (last_row + 1);
00489         }
00490 
00491         __device__ __forceinline__ int idx_row_high(int y) const
00492         {
00493             return /*::abs*/(last_row - ::abs(last_row - y) + (y > last_row)) /*% (last_row + 1)*/;
00494         }
00495 
00496         __device__ __forceinline__ int idx_row(int y) const
00497         {
00498             return idx_row_low(idx_row_high(y));
00499         }
00500 
00501         __device__ __forceinline__ int idx_col_low(int x) const
00502         {
00503             return (::abs(x) - (x < 0)) % (last_col + 1);
00504         }
00505 
00506         __device__ __forceinline__ int idx_col_high(int x) const
00507         {
00508             return (last_col - ::abs(last_col - x) + (x > last_col));
00509         }
00510 
00511         __device__ __forceinline__ int idx_col(int x) const
00512         {
00513             return idx_col_low(idx_col_high(x));
00514         }
00515 
00516         template <typename T> __device__ __forceinline__ D at(int y, int x, const T* data, size_t step) const
00517         {
00518             return saturate_cast<D>(((const T*)((const char*)data + idx_row(y) * step))[idx_col(x)]);
00519         }
00520 
00521         template <typename Ptr2D> __device__ __forceinline__ D at(typename Ptr2D::index_type y, typename Ptr2D::index_type x, const Ptr2D& src) const
00522         {
00523             return saturate_cast<D>(src(idx_row(y), idx_col(x)));
00524         }
00525 
00526         const int last_row;
00527         const int last_col;
00528     };
00529 
00531     // BrdWrap
00532 
00533     template <typename D> struct BrdRowWrap
00534     {
00535         typedef D result_type;
00536 
00537         explicit __host__ __device__ __forceinline__ BrdRowWrap(int width_) : width(width_) {}
00538         template <typename U> __host__ __device__ __forceinline__ BrdRowWrap(int width_, U) : width(width_) {}
00539 
00540         __device__ __forceinline__ int idx_col_low(int x) const
00541         {
00542             return (x >= 0) * x + (x < 0) * (x - ((x - width + 1) / width) * width);
00543         }
00544 
00545         __device__ __forceinline__ int idx_col_high(int x) const
00546         {
00547             return (x < width) * x + (x >= width) * (x % width);
00548         }
00549 
00550         __device__ __forceinline__ int idx_col(int x) const
00551         {
00552             return idx_col_high(idx_col_low(x));
00553         }
00554 
00555         template <typename T> __device__ __forceinline__ D at_low(int x, const T* data) const
00556         {
00557             return saturate_cast<D>(data[idx_col_low(x)]);
00558         }
00559 
00560         template <typename T> __device__ __forceinline__ D at_high(int x, const T* data) const
00561         {
00562             return saturate_cast<D>(data[idx_col_high(x)]);
00563         }
00564 
00565         template <typename T> __device__ __forceinline__ D at(int x, const T* data) const
00566         {
00567             return saturate_cast<D>(data[idx_col(x)]);
00568         }
00569 
00570         const int width;
00571     };
00572 
00573     template <typename D> struct BrdColWrap
00574     {
00575         typedef D result_type;
00576 
00577         explicit __host__ __device__ __forceinline__ BrdColWrap(int height_) : height(height_) {}
00578         template <typename U> __host__ __device__ __forceinline__ BrdColWrap(int height_, U) : height(height_) {}
00579 
00580         __device__ __forceinline__ int idx_row_low(int y) const
00581         {
00582             return (y >= 0) * y + (y < 0) * (y - ((y - height + 1) / height) * height);
00583         }
00584 
00585         __device__ __forceinline__ int idx_row_high(int y) const
00586         {
00587             return (y < height) * y + (y >= height) * (y % height);
00588         }
00589 
00590         __device__ __forceinline__ int idx_row(int y) const
00591         {
00592             return idx_row_high(idx_row_low(y));
00593         }
00594 
00595         template <typename T> __device__ __forceinline__ D at_low(int y, const T* data, size_t step) const
00596         {
00597             return saturate_cast<D>(*(const D*)((const char*)data + idx_row_low(y) * step));
00598         }
00599 
00600         template <typename T> __device__ __forceinline__ D at_high(int y, const T* data, size_t step) const
00601         {
00602             return saturate_cast<D>(*(const D*)((const char*)data + idx_row_high(y) * step));
00603         }
00604 
00605         template <typename T> __device__ __forceinline__ D at(int y, const T* data, size_t step) const
00606         {
00607             return saturate_cast<D>(*(const D*)((const char*)data + idx_row(y) * step));
00608         }
00609 
00610         const int height;
00611     };
00612 
00613     template <typename D> struct BrdWrap
00614     {
00615         typedef D result_type;
00616 
00617         __host__ __device__ __forceinline__ BrdWrap(int height_, int width_) :
00618             height(height_), width(width_)
00619         {
00620         }
00621         template <typename U>
00622         __host__ __device__ __forceinline__ BrdWrap(int height_, int width_, U) :
00623             height(height_), width(width_)
00624         {
00625         }
00626 
00627         __device__ __forceinline__ int idx_row_low(int y) const
00628         {
00629             return (y >= 0) * y + (y < 0) * (y - ((y - height + 1) / height) * height);
00630         }
00631 
00632         __device__ __forceinline__ int idx_row_high(int y) const
00633         {
00634             return (y < height) * y + (y >= height) * (y % height);
00635         }
00636 
00637         __device__ __forceinline__ int idx_row(int y) const
00638         {
00639             return idx_row_high(idx_row_low(y));
00640         }
00641 
00642         __device__ __forceinline__ int idx_col_low(int x) const
00643         {
00644             return (x >= 0) * x + (x < 0) * (x - ((x - width + 1) / width) * width);
00645         }
00646 
00647         __device__ __forceinline__ int idx_col_high(int x) const
00648         {
00649             return (x < width) * x + (x >= width) * (x % width);
00650         }
00651 
00652         __device__ __forceinline__ int idx_col(int x) const
00653         {
00654             return idx_col_high(idx_col_low(x));
00655         }
00656 
00657         template <typename T> __device__ __forceinline__ D at(int y, int x, const T* data, size_t step) const
00658         {
00659             return saturate_cast<D>(((const T*)((const char*)data + idx_row(y) * step))[idx_col(x)]);
00660         }
00661 
00662         template <typename Ptr2D> __device__ __forceinline__ D at(typename Ptr2D::index_type y, typename Ptr2D::index_type x, const Ptr2D& src) const
00663         {
00664             return saturate_cast<D>(src(idx_row(y), idx_col(x)));
00665         }
00666 
00667         const int height;
00668         const int width;
00669     };
00670 
00672     // BorderReader
00673 
00674     template <typename Ptr2D, typename B> struct BorderReader
00675     {
00676         typedef typename B::result_type elem_type;
00677         typedef typename Ptr2D::index_type index_type;
00678 
00679         __host__ __device__ __forceinline__ BorderReader(const Ptr2D& ptr_, const B& b_) : ptr(ptr_), b(b_) {}
00680 
00681         __device__ __forceinline__ elem_type operator ()(index_type y, index_type x) const
00682         {
00683             return b.at(y, x, ptr);
00684         }
00685 
00686         const Ptr2D ptr;
00687         const B b;
00688     };
00689 
00690     // under win32 there is some bug with templated types that passed as kernel parameters
00691     // with this specialization all works fine
00692     template <typename Ptr2D, typename D> struct BorderReader< Ptr2D, BrdConstant<D> >
00693     {
00694         typedef typename BrdConstant<D>::result_type elem_type;
00695         typedef typename Ptr2D::index_type index_type;
00696 
00697         __host__ __device__ __forceinline__ BorderReader(const Ptr2D& src_, const BrdConstant<D>& b) :
00698             src(src_), height(b.height), width(b.width), val(b.val)
00699         {
00700         }
00701 
00702         __device__ __forceinline__ D operator ()(index_type y, index_type x) const
00703         {
00704             return (x >= 0 && x < width && y >= 0 && y < height) ? saturate_cast<D>(src(y, x)) : val;
00705         }
00706 
00707         const Ptr2D src;
00708         const int height;
00709         const int width;
00710         const D val;
00711     };
00712 }}} // namespace cv { namespace gpu { namespace device
00713 
00714 #endif // __OPENCV_GPU_BORDER_INTERPOLATE_HPP__