blob: 5091e60c2919a65697b7339f19d1eabe595ca43b [file] [log] [blame]
//-----------------------------------------------------------------------------
// ____ _
// | ___| | ___ _ _
// | ___| | / __)\ \/ /
// | | | |_| ___) | |
// |_| \___|\___)/_/\_\ Image Library
//
// 2006, Intel Corporation, licensed under Apache 2.0
//
// file : FlexFilter.h
// author : Scott Ettinger - scott.m.ettinger@intel.com
// description: FlexImage filter functions
//
// modified :
//-----------------------------------------------------------------------------
#ifndef FLEXFILTER_H
#define FLEXFILTER_H
#if defined(HAVE_CONFIG_H)
# include "config.h"
#endif
#include "FlexImage.h"
//1 channel filters are implemented separately from multi-channel for speed
//1D filter Row wise 1 channel any type data or kernel valid pixels only
template<class T, class T2>
bool FlexFilterRowV(FlexImage<T,1> &src, FlexImage<T,1> &dst, T2 *kernel, int kernelSize, bool allocate = true);
//1D filter Column wise 1 channel any type data or kernel valid pixels only
template<class T, class T2>
bool FlexFilterColumnV(FlexImage<T,1> &src, FlexImage<T,1> &dst, T2 *kernel, int kernelSize, bool allocate = true);
//2D Filter any type data or kernel valid pixels only
template<class T, class T2>
bool FlexFilter2DV(FlexImage<T,1> &src, FlexImage<T,1> &dst, T2 *kernel, int kWidth, int kHeight, bool allocate = true);
//Zero a 1 pixel border of the image
template<class T>
inline void ZeroBorder(FlexImage<T,1> &im);
//----------------------------- Implementation --------------------------------
//1D filter Row wise 1 channel any type data or kernel valid pixels only
template<class T, class T2>
bool FlexFilterRowV(FlexImage<T,1> &src, FlexImage<T,1> &dst, T2 *kernel, int kernelSize, bool allocate)
{
if(kernelSize % 2 == 0) //enforce odd length kernels
return false;
if(allocate)
dst.Reallocate(src.Size());
dst.Set((T)0);
int n = kernelSize / 2;
for(int y = 0; y < src.Height(); y++)
{ T *psrc = &src(n, y), *pdst = &dst(n, y);
for(int x = n; x < src.Width() - n; x++)
{ int k = 0;
T2 acc = 0;
for(int i = -n; i <= n; i++)
acc += (T2)(psrc[i] * kernel[k++]);
*pdst = (T)acc;
pdst++;
psrc++;
}
}
return true;
}
//1D filter Column wise 1 channel any type data or kernel valid pixels only
template<class T, class T2>
bool FlexFilterColumnV(FlexImage<T,1> &src, FlexImage<T,1> &dst, T2 *kernel, int kernelSize, bool allocate)
{
if(kernelSize % 2 == 0) //enforce odd length kernels
return false;
if(allocate)
dst.Reallocate(src.Size());
dst.Set((T)0);
int n = kernelSize / 2;
int sb = src.StepBytes();
for(int y = n; y < src.Height() - n; y++)
{ T *psrc = &src(0, y), *pdst = &dst(0, y);
for(int x = 0; x < src.Width(); x++)
{ int k = 0;
T2 acc = 0;
for(int i = -n; i <= n; i++)
acc += (T2)(*(T *)((char *)psrc + sb * i) * kernel[k++]);
*pdst = (T)acc;
pdst++;
psrc++;
}
}
return true;
}
//2D Filter any type data or kernel valid pixels only
template<class T, class T2>
bool FlexFilter2DV(FlexImage<T,1> &src, FlexImage<T,1> &dst, T2 *kernel, int kWidth, int kHeight, bool allocate)
{
if(kWidth % 2 == 0 || kHeight % 2 == 0)
return false;
if(allocate)
dst.Reallocate(src.Size());
dst.Set((T)0);
int nw = kWidth / 2, nh = kHeight / 2;
int sb = src.StepBytes();
for(int y = nh; y < src.Height() - nh; y++)
{ T *psrc = &src(nw, y - nh), *pdst = &dst(nw, y);
for(int x = nw; x < src.Width() - nw; x++)
{ int k = 0;
T *p = psrc++;
for(int j = -nh; j <= nh; j++)
{ for(int i = -nw; i <= nw; i++)
*pdst += p[i] * kernel[k++];
p = (T *)((char *)p + sb);
}
pdst++;
}
}
return true;
}
//Zero a 1 pixel border of the image
template<class T>
inline void ZeroBorder(FlexImage<T,1> &im)
{
T *p1 = &im(0,0), *p2 = &im(0,im.Height() - 1);
for(int i = 0; i < im.Width(); i++)
{ *(p1++) = 0;
*(p2++) = 0;
}
p1 = &im(0,0); p2 = &im(im.Width() - 1, 0);
for(int i = 0; i < im.Height(); i++)
{ *p1 = 0; *p2 = 0;
p1 = (T *)((Im8u *)p1 + im.StepBytes());
p2 = (T *)((Im8u *)p2 + im.StepBytes());
}
}
#endif