#ifndef IMAGEBLUR_H
#define IMAGEBLUR_H

#include <QImage>

class ImageBlurUtility
{
public:
    //QImage存储数据的方式参考qrgb.h, 按AARRGGBB存
    //unsigned int4字节, 刚好存放rgba
    struct pixel_t
    {
        unsigned int rgba = 0;
        inline int r() const { return ((rgba >> 16) & 0xff); }
        inline int g() const { return ((rgba >> 8) & 0xff); }
        inline int b() const { return (rgba & 0xff); }
        inline int a() const { return rgba >> 24; }
        inline void Set(int r, int g, int b, int a)
        { rgba = ((a & 0xffu) << 24) | ((r & 0xffu) << 16) | ((g & 0xffu) << 8) | (b & 0xffu); }
    };
    //计算时用, 将整数的rgba值变为double类型来作计算, 最后再用qRound转回整数
    struct buff_t
    {
        double r, g, b, a;
        buff_t() : r(0.0), g(0.0), b(0.0), a(0.0) {}
        buff_t(const pixel_t &pixel):r(pixel.r()),g(pixel.g()),b(pixel.b()),a(pixel.a()) {}
        inline int Red() const { return qRound(r); }
        inline int Green() const { return qRound(g); }
        inline int Blue() const { return qRound(b); }
        inline int Alpha() const { return qRound(a); }
    };
    
public:
    template <typename T>
    static T Edge(T i, T x, T w);
public:
    static void Normalization(std::vector<double> &kernels);
};

class GaussBlur
{
public:
    static void Blur(QImage &image, int radius);
private:
    static std::vector<double> GetKernels(int radius);
};

#endif // IMAGEBLUR_H