00001 #ifndef Impala_Core_Array_Pattern_FuncGeometricOp_h
00002 #define Impala_Core_Array_Pattern_FuncGeometricOp_h
00003
00004 #include "Core/Array/Pattern/ArrayFunc.h"
00005 #include "Core/Array/Pattern/PtrFunc.h"
00006 #include "Core/Matrix/MatMulVec.h"
00007 #include "Core/Array/Element/E1Cast.h"
00008
00009 namespace Impala
00010 {
00011 namespace Core
00012 {
00013 namespace Array
00014 {
00015 namespace Pattern
00016 {
00017
00018
00019 template <class DstArrayT, class SrcArrayT>
00020 void
00021 FuncGeometricOp(DstArrayT* dst, SrcArrayT* src, Matrix::Mat* func,
00022 Geometry::GeoIntType gi, Element::Vec3Real64 translate,
00023 typename DstArrayT::ArithType background)
00024 {
00025 typedef typename DstArrayT::StorType DstStorT;
00026 typedef typename DstArrayT::ArithType DstArithT;
00027 typedef typename SrcArrayT::StorType SrcStorT;
00028 typedef typename SrcArrayT::ArithType SrcArithT;
00029
00030 Real64 srcWidth = ArrayCW(src);
00031 Real64 srcHeight = ArrayCH(src);
00032 Real64 maxSrcX = (gi == Geometry::LINEAR) ? srcWidth - 1 : srcWidth - 0.5;
00033 Real64 maxSrcY = (gi == Geometry::LINEAR) ? srcHeight - 1 : srcHeight - 0.5;
00034 int dstWidth = ArrayCW(dst);
00035 int dstHeight = ArrayCH(dst);
00036
00037 for (int y=0 ; y<dstHeight ; y++)
00038 {
00039 DstStorT* dstPtr = ArrayCPB(dst, 0, y);
00040 for (int x=0 ; x<dstWidth ; x++)
00041 {
00042 Element::Vec3Real64 vDst(x, y, 1);
00043 Element::Vec3Real64 vSrc = Matrix::MatMulVec(func, vDst + translate);
00044 Real64 srcXf = vSrc.X() / vSrc.Z();
00045 Real64 srcYf = vSrc.Y() / vSrc.Z();
00046
00047 DstArithT pixVal;
00048 if ((srcXf<0) || (srcXf>=maxSrcX) || (srcYf<0) || (srcYf>=maxSrcY))
00049 pixVal = background;
00050 else
00051 {
00052 if (gi == Geometry::LINEAR)
00053 {
00054 Int32 srcX = Int32(srcXf);
00055 Int32 srcY = Int32(srcYf);
00056 DstArithT alpha = Element::E1Cast(Real64(srcXf - srcX), DstArithT());
00057 DstArithT beta = Element::E1Cast(Real64(srcYf - srcY), DstArithT());
00058 SrcStorT* sPtr;
00059 sPtr = ArrayCPB(src, srcX, srcY);
00060 DstArithT v1 = PtrRead(sPtr, SrcArithT());
00061 sPtr += SrcArrayT::ElemSize();
00062 DstArithT v2 = PtrRead(sPtr, SrcArithT());
00063 sPtr = ArrayCPB(src, srcX, srcY+1);
00064 DstArithT v3 = PtrRead(sPtr, SrcArithT());
00065 sPtr += SrcArrayT::ElemSize();
00066 DstArithT v4 = PtrRead(sPtr, SrcArithT());
00067 pixVal = v1 + alpha*(v2-v1) + beta*(v3-v1)
00068 + alpha*beta*(v1-v2-v3+v4);
00069 }
00070 else
00071 {
00072 SrcStorT* sPtr = ArrayCPB(src, Int32(srcXf + 0.5),
00073 Int32(srcYf + 0.5));
00074 pixVal = PtrRead(sPtr, SrcArithT());
00075 }
00076 }
00077 PtrWrite(dstPtr, pixVal);
00078 dstPtr += DstArrayT::ElemSize();
00079 }
00080 }
00081 }
00082
00083 }
00084 }
00085 }
00086 }
00087
00088 #endif