00001 #ifndef Impala_Core_Array_Trait_InOutBlocks_h
00002 #define Impala_Core_Array_Trait_InOutBlocks_h
00003
00004 #include "Core/Array/Pattern/Categories.h"
00005 #include "Core/Array/Element/E1Cast.h"
00006
00007 namespace Impala
00008 {
00009 namespace Core
00010 {
00011 namespace Array
00012 {
00013 namespace Trait
00014 {
00015
00016
00017 template<class ArrayT>
00018 class InOutBlocks
00019 {
00020 public:
00021 typedef Pattern::TagPixOpIn DirectionCategory;
00022 typedef Pattern::TagTransVar TransVarianceCategory;
00023 typedef Pattern::Tag1Phase PhaseCategory;
00024
00025 typedef typename ArrayT::ArithType ArithT;
00026
00027 InOutBlocks(int offsetX, int offsetY,
00028 int blockWidth, int blockHeight,
00029 int marginX, int marginY,
00030 ArithT borderVal, ArithT blockVal, ArithT blockValIncr,
00031 int maxNrBlocksX, int maxNrBlocksY,
00032 int imWidth, int imHeight)
00033 {
00034 mOffsetX = offsetX;
00035 mOffsetY = offsetY;
00036 mBlockWidth = blockWidth;
00037 mBlockHeight = blockHeight;
00038 mMarginX = marginX;
00039 mMarginY = marginY;
00040 mBigBlockWidth = blockWidth + marginX;
00041 mBigBlockHeight = blockHeight + marginY;
00042 mBorderVal = borderVal;
00043 mBlockVal = blockVal;
00044 mBlockValIncr = blockValIncr;
00045 mNrX = (imWidth - offsetX) / mBigBlockWidth;
00046 mNrY = (imHeight - offsetY) / mBigBlockHeight;
00047 if (mOffsetX + mNrX*mBigBlockWidth + blockWidth < imWidth)
00048 mNrX++;
00049 if (mOffsetY + mNrY*mBigBlockHeight + blockHeight < imHeight)
00050 mNrY++;
00051 if ((maxNrBlocksX != -1) && (mNrX > maxNrBlocksX))
00052 mNrX = maxNrBlocksX;
00053 if ((maxNrBlocksY != -1) && (mNrY > maxNrBlocksY))
00054 mNrY = maxNrBlocksY;
00055 }
00056
00057 const ArithT&
00058 DoIt(int x, int y)
00059 {
00060 if ((x < mOffsetX) || (y < mOffsetY))
00061 {
00062 return mBorderVal;
00063 }
00064 x -= mOffsetX;
00065 y -= mOffsetY;
00066 int blockX = x / mBigBlockWidth;
00067 int blockY = y / mBigBlockHeight;
00068 if ((blockX >= mNrX) || (blockY >= mNrY))
00069 return mBorderVal;
00070 int ox = x - blockX * mBigBlockWidth;
00071 int oy = y - blockY * mBigBlockHeight;
00072 if ((ox > mBlockWidth) || (oy > mBlockHeight))
00073 return mBorderVal;
00074 mRes = mBlockVal + Element::E1Cast(blockX + blockY*mNrX, ArithT()) * mBlockValIncr;
00075 return mRes;
00076 }
00077
00078 private:
00079
00080 int mOffsetX;
00081 int mOffsetY;
00082 int mBlockWidth;
00083 int mBlockHeight;
00084 int mMarginX;
00085 int mMarginY;
00086 int mBigBlockWidth;
00087 int mBigBlockHeight;
00088 ArithT mBorderVal;
00089 ArithT mBlockVal;
00090 ArithT mBlockValIncr;
00091 int mNrX;
00092 int mNrY;
00093 ArithT mRes;
00094
00095 };
00096
00097 }
00098 }
00099 }
00100 }
00101
00102 #endif