00001 #ifndef Impala_Core_Array_IntegrateReduce_h
00002 #define Impala_Core_Array_IntegrateReduce_h
00003
00004 #include "Core/Array/Arrays.h"
00005 #include "Core/Array/SetVal.h"
00006 #include "Core/Array/Pattern/PatSetBorder.h"
00007 #include "Core/Array/CheckBorderSize.h"
00008
00009 namespace Impala
00010 {
00011 namespace Core
00012 {
00013 namespace Array
00014 {
00015
00017 void
00018 IntegrateReduceLine(Array::Array2dScalarReal64*& dst,
00019 Array::Array2dScalarReal64* src, int n, int y)
00020 {
00021 double* srcPtr = src->CPB(0, y);
00022 double* dstPtr = dst->CPB(0, y/n);
00023 for(int x=0 ; x<src->CW()/n ; ++x)
00024 {
00025 double accu = 0;
00026 for(int i=0 ; i<n ; ++i)
00027 {
00028 accu += *srcPtr;
00029 ++srcPtr;
00030 }
00031 *dstPtr += accu;
00032 ++dstPtr;
00033 }
00034 }
00035
00038 void
00039 IntegrateReduce(Array::Array2dScalarReal64*& dst,
00040 Array::Array2dScalarReal64* src, int n)
00041 {
00042
00043 if(dst && (dst->CW() != src->CW()/n || dst->CH() != src->CH()/n))
00044 {
00045 delete dst;
00046 dst = 0;
00047 }
00048 if(dst == 0)
00049 dst = new Array::Array2dScalarReal64(src->CW()/n, src->CH()/n, 0, 0);
00050 SetVal(dst, 0);
00051 int y=0;
00052 while(y <= src->CH()-n)
00053 {
00054 for(int i=0 ; i<n ; ++i)
00055 {
00056 IntegrateReduceLine(dst, src, n, y);
00057 ++y;
00058 }
00059 }
00060 }
00061
00066 void
00067 IntegrateReduceLineWeighted(Array::Array2dScalarReal64*& dst,
00068 Array::Array2dScalarReal64* src,
00069 int n, int dstY, int srcY, double weight)
00070 {
00071 double* dstPtr = dst->CPB(0, dstY);
00072 for(int dstX=0 ; dstX<dst->CW() ; ++dstX)
00073 {
00074 double accu = 0;
00075 int srcX=dstX*n - 1;
00076 double* srcPtr = src->CPB(srcX, srcY);
00077 accu += 0.33 * *srcPtr++;
00078 accu += 0.67 * *srcPtr++;
00079 for(int i=1 ; i<n-1 ; ++i)
00080 {
00081 accu += *srcPtr++;
00082 }
00083 accu += 0.67 * *srcPtr++;
00084 accu += 0.33 * *srcPtr++;
00085 *dstPtr += weight * accu;
00086 ++dstPtr;
00087 }
00088 }
00089
00092 void
00093 IntegrateReduceWeighted(Array::Array2dScalarReal64*& dst,
00094 Array::Array2dScalarReal64* src, int n)
00095 {
00096
00097 if(dst && (dst->CW() != src->CW()/n || dst->CH() != src->CH()/n))
00098 {
00099 delete dst;
00100 dst = 0;
00101 }
00102 if(dst == 0)
00103 dst = new Array::Array2dScalarReal64(src->CW()/n, src->CH()/n, 0, 0);
00104 SetVal(dst, 0);
00105 Array::Array2dScalarReal64* bordered = CheckBorderSize(src, 1, 1);
00106 Pattern::PatSetBorder(bordered, 1, 1);
00107 for(int dstY=0 ; dstY<dst->CH() ; ++dstY)
00108 {
00109 int srcY = dstY*n;
00110 IntegrateReduceLineWeighted(dst, bordered, n, dstY, srcY-1, .33);
00111 IntegrateReduceLineWeighted(dst, bordered, n, dstY, srcY, .67);
00112 for(int i=1 ; i<n-1 ; ++i)
00113 IntegrateReduceLineWeighted(dst, bordered, n, dstY, srcY+i, 1.);
00114 IntegrateReduceLineWeighted(dst, bordered, n, dstY, srcY+n-1, .67);
00115 IntegrateReduceLineWeighted(dst, bordered, n, dstY, srcY+n, .33);
00116 }
00117 if(bordered != src)
00118 delete bordered;
00119 }
00120
00121
00122 }
00123 }
00124 }
00125
00126 #endif