I try to compile code for Gaussian Blur from Librow article 9. When compile, I get these errors:

‘Buffer’ was not declared in this scope (gaussianblur.cpp, line 139)
‘Buffer’ was not declared in this scope (gaussianblur.cpp, line 158)
‘Buffer’ was not declared in this scope (gaussianblur.cpp, line 167)
‘Buffer’ was not declared in this scope (gaussianblur.cpp, line 185
‘Buffer’ was not declared in this scope (gaussianblur.h, line 72)
‘Size’ was not declared in this scope (gaussianblur.cpp, line 145)
‘Size’ was not declared in this scope (gaussianblur.cpp, line 158)
‘Size’ was not declared in this scope (gaussianblur.cpp, line 163)
‘Size’ was not declared in this scope (gaussianblur.cpp, line 183)
class ‘TGaussianBlur<T>::CExtension’ does not have any field named ‘Buffer’ (gaussianblur.h, line 70)

As far as I understand, Buffer should be inherited in CExtension. Don't understand where is a problem.

Thanks!

gaussianblur.h
Code: C++
Code:
#include <stdio.h>

#ifndef _GAUSSIANBLUR_H_
#define _GAUSSIANBLUR_H_

template <class T = double> class TGaussianBlur
{
public:
    //   1D GAUSSIAN BLUR
    //     pSignal - input signal;
    //     pResult - output signal, NULL for inplace processing
    //     N       - length of the signal
    //     W       - window size, odd positive number
    bool Filter(T *pSignal, T *pResult, unsigned int N, unsigned int W) const;

    //   2D GAUSSIAN BLUR
    //     pImage  - input image
    //     pResult - output image, NULL for inplace processing
    //     N       - width of the image
    //     M       - height of the image
    //     W       - window size, odd positive number
    bool Filter(T *pImage, T *pResult, unsigned int N, unsigned int M, unsigned int W) const;

protected:
    //   Internal auxiliary structure - data array size descriptor
    struct CSize
    {
        unsigned int x;   //   Array width
        unsigned int y;   //   Array height

        //   Default constructor
        CSize(): x(0), y(0) {}
        //   Constructor with initialization
        CSize(unsigned int _x, unsigned int _y): x(_x), y(_y) {}

        //   Initialization
        void Set(unsigned int _x, unsigned int _y) { x = _x; y = _y; }
        //   Area
        unsigned int Area() const { return x * y; }
    };

    //   Internal auxiliary structure - array descriptor
    struct CArray
    {
        CSize Size;   //   Array size
        T *Buffer;    //   Element buffer

        //   Default constructor
        CArray(): Buffer(NULL) {}
        //   Constructors with initialization
        CArray(T *_Buffer, const CSize &_Size): Buffer(_Buffer), Size(_Size) {}
        CArray(T *_Buffer, unsigned int _N): Buffer(_Buffer), Size(_N, 1) {}
    };

    //   Internal auxiliary structure - array extension descriptor
    struct CExtension: public CArray
    {
        unsigned int Margin;   //   Extension margins

        enum EMode {ModeHorizontal, ModeVertical};

        //   Default cosntructor
        CExtension(): Buffer(0), Margin(0), Mode(ModeHorizontal) {}
        //   Destructor
        ~CExtension() { if (Buffer) delete[] Buffer; }

        //   Mode setting
        void SetMode(EMode _Mode) { Mode = _Mode; }
        //   Extension memory allocation
        bool Allocate(unsigned int _N, unsigned int _W) { return _Allocate(CSize(_N, 1), _W >> 1); }
        bool Allocate(const CSize &_Size, unsigned int _W) { return _Allocate(_Size, _W >> 1); }
        //   Pasting data into extension from data array
        void Paste(const T * _Start);
        //   Extension
        void Extend();

    protected:
        EMode Mode;   //   Current mode

        //   Extension memory allocation
        bool _Allocate(const CSize &_Size, unsigned int _Margin);
    };

    //   Internal auxiliary structure - filter window descriptor
    struct CWindow
    {
        double *Weights;   //   Window weights
        unsigned int Size;   //   Window size

        //   Default constructor
        CWindow(): Weights(NULL), Size(0), Correction(.5 - double(T(.5))) {}
        //   Destructor
        ~CWindow() { if (Weights) delete[] Weights; }

        //   Filter window creation
        bool Create(unsigned int _Size);

        //   FILTER WINDOW APPLICATION
        //     _Element - start element in signal/image
        T Apply(const T *_Element) const
        {
            //   Apply filter - calculate weighted mean
            double Sum = 0.;
            const double *WeightIter = Weights;
            const T *ElIter = _Element;
            const double *const End = Weights + Size;
            while (WeightIter < End)
                Sum += *(WeightIter++) * double(*(ElIter++));
            return T(Sum + Correction);
        }

    protected:
        const double Correction;
    };

    //   Internal auxiliary functions - check input data consistency
    bool Consistent(const T *_Image, const CSize &_Size, unsigned int _W) const { return  _Image && _Size.x && _Size.y && _W && _Size.x > (_W >> 1) && _Size.y > (_W >> 1) && _W & 1; }
    bool Consistent(const T *_Signal, unsigned int _N, unsigned int _W) const { return  _Signal && _N && _W && _N > (_W >> 1) && _W & 1; }
};
//   Include implementation file
#include "gaussianblur.cpp"

#endif



gaussianblur.cpp
Code: C++
Code:
#ifndef _GAUSSIANBLUR_CPP_
#define _GAUSSIANBLUR_CPP_

//   Include declaration file
#include "gaussianblur.h"
//   Include math library
#include <math.h>

//   1D GAUSSIAN BLUR
//     pSignal - input signal;
//     pResult - output signal, NULL for inplace processing
//     N       - length of the signal
//     W       - window size, odd positive number
template <class T> bool TGaussianBlur<T>::Filter(T *pSignal, T *pResult, unsigned int N, unsigned int W) const
{
    //   Check input data cosnsitency
    if (!Consistent(pSignal, N, W))
        return false;
    //   Allocate extension
    CExtension Extension;
    if (!Extension.Allocate(N, W))
        return false;
    //   Create signal descriptor
    const CArray Signal(pSignal, N);
    //   Paste signal into extension
    Extension.Paste(Signal.Buffer);
    //   Extend signal
    Extension.Extend();
    //   Create filter window
    CWindow Window;
    if (!Window.Create(W))
        return false;
    //   Extension iterator
    const T *ExtIter = Extension.Buffer;
    //   Extension stop position
    const T *const ExtStop = Extension.Buffer + Extension.Size.x;
    //   Result iterator
    T *ResIter = pResult ? pResult : pSignal;
    //   Filter - apply to every element
    while (ExtIter < ExtStop)
        *(ResIter++) = Window.Apply(ExtIter++);
    //   Succeeded
    return true;
}

//   2D GAUSSIAN BLUR
//     pImage  - input image
//     pResult - output image, NULL for inplace processing
//     N       - width of the image
//     M       - height of the image
//     W       - window size
template <class T> bool TGaussianBlur<T>::Filter(T *pImage, T *pResult, unsigned int N, unsigned int M, unsigned int W) const
{
    //   Check input data consistency
    if (!Consistent(pImage, CSize(N, M), W))
        return false;
    //   Allocate extension
    CExtension Extension;
    if (!Extension.Allocate(CSize(N, M), W))
        return false;
    //   Create image descriptor
    CArray Image(pImage, CSize(N, M));
    //   Create filter window
    CWindow Window;
    if (!Window.Create(W))
        return false;
    //   Stop postion
    const T * ExtStop = Extension.Buffer + Extension.Size.x;
    //   Result iterator
    T *ResIter = pResult ? pResult : pImage;
    //   Image iterator
    const T *ImIter = Image.Buffer;
    //   Image stop position
    const T * ImStop = Image.Buffer + Image.Size.Area();
    //   Filter line by line
    while (ImIter < ImStop)
    {
        //   Paste image line into extension
        Extension.Paste(ImIter);
        //   Extend image line
        Extension.Extend();
        //   Extension iterator
        const T *ExtIter = Extension.Buffer;
        //   Apply filter to every pixel of the line
        while (ExtIter < ExtStop)
            *(ResIter++) = Window.Apply(ExtIter++);
        //   Move to the next line
        ImIter += Image.Size.x;
    }
    //   Initialize image descriptor with filter result
    Image.Buffer = pResult ? pResult : pImage;
    //   Set vertical extension mode
    Extension.SetMode(CExtension::ModeVertical);
    //   Extension stop position
    ExtStop = Extension.Buffer + Extension.Size.y;
    //   Result column iterator
    T *ResColumnIter = pResult ? pResult : pImage;
    //   Image iterator
    ImIter = Image.Buffer;
    //   Image stop position
    ImStop = Image.Buffer + Image.Size.x;
    //   Filter column by column
    while (ImIter < ImStop)
    {
        //   Paste image column into extension
        Extension.Paste(ImIter++);
        //   Extend image column
        Extension.Extend();
        //   Extension iterator
        const T *ExtIter = Extension.Buffer;
        //   Result pixel iterator
        ResIter = ResColumnIter;
        //   Apply fitler to every pixel of the column
        while (ExtIter < ExtStop)
        {
            *ResIter = Window.Apply(ExtIter++);
            ResIter += Image.Size.x;
        }
        //   Move to the next column
        ++ResColumnIter;
    }
    //   Succeeded
    return true;
}

//   EXTENSION MEMORY ALLOCATION
//     _Size   - signal/image size
//     _Margin - extension margins
template <class T> bool TGaussianBlur<T>::CExtension::_Allocate(const CSize &_Size, unsigned int _Margin)
{
    //   Allocate extension buffer
    Buffer = new T[(_Size.x > _Size.y ? _Size.x : _Size.y) + (_Margin << 1)];
    //   Check buffer allocation
    if (!Buffer)
        //   Buffer allocation failed
        return false;
    //   Initialize size descriptors
    Size = _Size;
    Margin = _Margin;
    //   Succeeded
    return true;
}

//   PASTING DATA LINE/COLUMN INTO EXTENSION FROM DATA ARRAY
//     _Start - start postion in image/signal to paste from
template <class T> void TGaussianBlur<T>::CExtension::Paste(const T *const _Start)
{
    if (Mode == ModeHorizontal)
    {
        //   Paste line
        memcpy(Buffer + Margin, _Start, Size.x * sizeof(T));
    }
    else
    {
        //   Stop position
        const T *const Stop = _Start + Size.Area();
        //   Array iterator
        const T *ArrIter = _Start;
        //   Extension iterator
        T *ExtIter = Buffer + Margin;
        //   Paste array column element by element
        while (ArrIter < Stop)
        {
            //   Copy line
            *(ExtIter++) = *ArrIter;
            //   Jump to the next line
            ArrIter += Size.x;
        }
    }
}

//   EXTENSION CREATION
template <class T> void TGaussianBlur<T>::CExtension::Extend()
{
    //   Line size
    const unsigned int Line = Mode == ModeHorizontal ? Size.x : Size.y;
    //   Stop position
    const T *const Stop = Buffer - 1;
    //   Left extension iterator
    T *ExtLeft = Buffer + Margin - 1;
    //   Left array iterator
    const T *ArrLeft = ExtLeft + 2;
    //   Right extension iterator
    T *ExtRight = ExtLeft + Line + 1;
    //   Left array iterator
    const T *ArrRight = ExtRight - 2;
    //   Create extension line element by element
    while (ExtLeft > Stop)
    {
        //   Left extension
        *(ExtLeft--) = *(ArrLeft++);
        //   Right extension
        *(ExtRight++) = *(ArrRight--);
    }
}

//   FILTER WINDOW CREATION
//     _Size - window size
template <class T> bool TGaussianBlur<T>::CWindow::Create(unsigned int _Size)
{
    //   Allocate window buffer
    Weights = new double[_Size];
    //   Check allocation
    if (!Weights)
        //   Window buffer allocation failed
        return false;
    //   Set window size
    Size = _Size;
    //   Window half
    const unsigned int Half = Size >> 1;
    //   Central weight
    Weights[Half] = 1.;
    //   The rest of weights
    for (unsigned int Weight = 1; Weight < Half + 1; ++Weight)
    {
        //   Support point
        const double x = 3.* double(Weight) / double(Half);
        //   Corresponding symmetric weights
        Weights[Half - Weight] = Weights[Half + Weight] = exp(-x * x / 2.);
    }
    //   Weight sum
    double k = 0.;
    for (unsigned int Weight = 0; Weight < Size; ++Weight)
        k += Weights[Weight];
    //   Weight scaling
    for (unsigned int Weight = 0; Weight < Size; ++Weight)
        Weights[Weight] /= k;
    //   Succeeded
    return true;
}

#endif

Last edited by shabbir; 7Jun2009 at 07:35.. Reason: Code blocks