1*6f7f8ab0SZhong Yang #include "stdafx.h" 2*6f7f8ab0SZhong Yang #include "GaussBlur.h" 3*6f7f8ab0SZhong Yang 4*6f7f8ab0SZhong Yang 5*6f7f8ab0SZhong Yang CGaussBlur::CGaussBlur() 6*6f7f8ab0SZhong Yang { 7*6f7f8ab0SZhong Yang } 8*6f7f8ab0SZhong Yang 9*6f7f8ab0SZhong Yang 10*6f7f8ab0SZhong Yang CGaussBlur::~CGaussBlur() 11*6f7f8ab0SZhong Yang { 12*6f7f8ab0SZhong Yang if (m_pTempl != NULL) 13*6f7f8ab0SZhong Yang free(m_pTempl); 14*6f7f8ab0SZhong Yang } 15*6f7f8ab0SZhong Yang 16*6f7f8ab0SZhong Yang void CGaussBlur::SetSigma(double sigma) 17*6f7f8ab0SZhong Yang { 18*6f7f8ab0SZhong Yang int i; 19*6f7f8ab0SZhong Yang m_sigma = sigma; 20*6f7f8ab0SZhong Yang m_r = (int)(m_sigma * 3 + 0.5); 21*6f7f8ab0SZhong Yang if (m_r <= 0) m_r = 1; 22*6f7f8ab0SZhong Yang 23*6f7f8ab0SZhong Yang //����ģ�� 24*6f7f8ab0SZhong Yang LPVOID pOldTempl = m_pTempl; 25*6f7f8ab0SZhong Yang m_pTempl = (double*)realloc(m_pTempl, sizeof(double) * (m_r + 1)); 26*6f7f8ab0SZhong Yang 27*6f7f8ab0SZhong Yang //����ʧ�ܣ� 28*6f7f8ab0SZhong Yang if (m_pTempl == NULL) 29*6f7f8ab0SZhong Yang { 30*6f7f8ab0SZhong Yang if (pOldTempl != NULL) 31*6f7f8ab0SZhong Yang free(pOldTempl); 32*6f7f8ab0SZhong Yang 33*6f7f8ab0SZhong Yang return; 34*6f7f8ab0SZhong Yang } 35*6f7f8ab0SZhong Yang 36*6f7f8ab0SZhong Yang //���� p[0] �Ҷ�ֵΪ1 ��ģ���� 37*6f7f8ab0SZhong Yang double k1 = (double)((-0.5) / (m_sigma * m_sigma)); 38*6f7f8ab0SZhong Yang for (i = 0; i <= m_r; i++) 39*6f7f8ab0SZhong Yang m_pTempl[i] = exp(k1 * i * i); 40*6f7f8ab0SZhong Yang 41*6f7f8ab0SZhong Yang //����ģ���Ȩ�ܺ� 42*6f7f8ab0SZhong Yang double sum = m_pTempl[0]; 43*6f7f8ab0SZhong Yang for (i = 1; i <= m_r; i++) 44*6f7f8ab0SZhong Yang { 45*6f7f8ab0SZhong Yang sum += (m_pTempl[i] * 2); 46*6f7f8ab0SZhong Yang } 47*6f7f8ab0SZhong Yang 48*6f7f8ab0SZhong Yang //��һ�� 49*6f7f8ab0SZhong Yang sum = (double)(1.0 / sum); //ȡ���� 50*6f7f8ab0SZhong Yang for (i = 0; i <= m_r; i++) 51*6f7f8ab0SZhong Yang m_pTempl[i] *= sum; 52*6f7f8ab0SZhong Yang } 53*6f7f8ab0SZhong Yang 54*6f7f8ab0SZhong Yang void CGaussBlur::Reset() 55*6f7f8ab0SZhong Yang { 56*6f7f8ab0SZhong Yang m_r = -1; 57*6f7f8ab0SZhong Yang m_sigma = (double)(-1.0); 58*6f7f8ab0SZhong Yang if (m_pTempl != NULL) 59*6f7f8ab0SZhong Yang { 60*6f7f8ab0SZhong Yang free(m_pTempl); 61*6f7f8ab0SZhong Yang m_pTempl = NULL; 62*6f7f8ab0SZhong Yang } 63*6f7f8ab0SZhong Yang } 64*6f7f8ab0SZhong Yang 65*6f7f8ab0SZhong Yang void CGaussBlur::DoGaussBlur(const CImage & image_src, CImage & image_dest) 66*6f7f8ab0SZhong Yang { 67*6f7f8ab0SZhong Yang if (image_src.IsNull()) 68*6f7f8ab0SZhong Yang return; 69*6f7f8ab0SZhong Yang int width = image_src.GetWidth(); 70*6f7f8ab0SZhong Yang int height = image_src.GetHeight(); 71*6f7f8ab0SZhong Yang int bpp = image_src.GetBPP(); 72*6f7f8ab0SZhong Yang if (!image_dest.IsNull()) 73*6f7f8ab0SZhong Yang image_dest.Destroy(); 74*6f7f8ab0SZhong Yang image_dest.Create(width, height, bpp); 75*6f7f8ab0SZhong Yang Filter(image_src.GetPixelAddress(0, height - 1), image_dest.GetPixelAddress(0, height - 1), width, height, bpp); 76*6f7f8ab0SZhong Yang } 77*6f7f8ab0SZhong Yang 78*6f7f8ab0SZhong Yang bool CGaussBlur::Filter(LPCVOID pSrc, LPVOID pDest, int width, int height, int bpp) 79*6f7f8ab0SZhong Yang { 80*6f7f8ab0SZhong Yang if (pSrc == NULL || pDest == NULL) 81*6f7f8ab0SZhong Yang return false; 82*6f7f8ab0SZhong Yang 83*6f7f8ab0SZhong Yang //ֻ�ܴ��� 8, 24�� 32 bpp 84*6f7f8ab0SZhong Yang if (bpp != 24 && bpp != 8 && bpp != 32) 85*6f7f8ab0SZhong Yang return false; 86*6f7f8ab0SZhong Yang 87*6f7f8ab0SZhong Yang if (m_r < 0 || m_pTempl == NULL) 88*6f7f8ab0SZhong Yang return false; 89*6f7f8ab0SZhong Yang 90*6f7f8ab0SZhong Yang int absHeight = (height >= 0) ? height : (-height); 91*6f7f8ab0SZhong Yang int stride = (width * bpp + 31) / 32 * 4; 92*6f7f8ab0SZhong Yang int pixelSize = bpp / 8; 93*6f7f8ab0SZhong Yang 94*6f7f8ab0SZhong Yang //���뻺�������洢�м��� 95*6f7f8ab0SZhong Yang LPVOID pTemp = malloc(stride * absHeight); 96*6f7f8ab0SZhong Yang if (pTemp == NULL) 97*6f7f8ab0SZhong Yang return false; 98*6f7f8ab0SZhong Yang 99*6f7f8ab0SZhong Yang CGaussBlurThreadParams params; 100*6f7f8ab0SZhong Yang 101*6f7f8ab0SZhong Yang params.pSrc = (LPBYTE)pSrc; 102*6f7f8ab0SZhong Yang params.pDest = (LPBYTE)pTemp; 103*6f7f8ab0SZhong Yang params.width = width; 104*6f7f8ab0SZhong Yang params.height = absHeight; 105*6f7f8ab0SZhong Yang params.stride = stride; 106*6f7f8ab0SZhong Yang params.pixelSize = pixelSize; 107*6f7f8ab0SZhong Yang params.r = m_r; 108*6f7f8ab0SZhong Yang params.pTempl = m_pTempl; 109*6f7f8ab0SZhong Yang params.rowBegin = 0; 110*6f7f8ab0SZhong Yang params.rowEnd = absHeight; 111*6f7f8ab0SZhong Yang params.bHorz = true; 112*6f7f8ab0SZhong Yang 113*6f7f8ab0SZhong Yang if (bpp == 8) 114*6f7f8ab0SZhong Yang GaussBlurThreadProc8(¶ms); 115*6f7f8ab0SZhong Yang else 116*6f7f8ab0SZhong Yang GaussBlurThreadProc24(¶ms); 117*6f7f8ab0SZhong Yang 118*6f7f8ab0SZhong Yang 119*6f7f8ab0SZhong Yang params.pSrc = (LPBYTE)pTemp; 120*6f7f8ab0SZhong Yang params.pDest = (LPBYTE)pDest; 121*6f7f8ab0SZhong Yang params.bHorz = false; 122*6f7f8ab0SZhong Yang 123*6f7f8ab0SZhong Yang if (bpp == 8) 124*6f7f8ab0SZhong Yang GaussBlurThreadProc8(¶ms); 125*6f7f8ab0SZhong Yang else 126*6f7f8ab0SZhong Yang GaussBlurThreadProc24(¶ms); 127*6f7f8ab0SZhong Yang 128*6f7f8ab0SZhong Yang free(pTemp); 129*6f7f8ab0SZhong Yang return true; 130*6f7f8ab0SZhong Yang } 131*6f7f8ab0SZhong Yang 132*6f7f8ab0SZhong Yang DWORD CGaussBlur::GaussBlurThreadProc8(LPVOID lpParameters) 133*6f7f8ab0SZhong Yang { 134*6f7f8ab0SZhong Yang CGaussBlurThreadParams *pInfo = (CGaussBlurThreadParams*)lpParameters; 135*6f7f8ab0SZhong Yang 136*6f7f8ab0SZhong Yang double result; 137*6f7f8ab0SZhong Yang int row, col, subRow, subCol, MaxVal, x, x1; 138*6f7f8ab0SZhong Yang LPINT pSubVal, pRefVal; 139*6f7f8ab0SZhong Yang 140*6f7f8ab0SZhong Yang if (pInfo->bHorz) 141*6f7f8ab0SZhong Yang { 142*6f7f8ab0SZhong Yang //ˮƽ���� 143*6f7f8ab0SZhong Yang pSubVal = &subCol; 144*6f7f8ab0SZhong Yang pRefVal = &col; 145*6f7f8ab0SZhong Yang MaxVal = pInfo->width - 1; 146*6f7f8ab0SZhong Yang } 147*6f7f8ab0SZhong Yang else 148*6f7f8ab0SZhong Yang { 149*6f7f8ab0SZhong Yang //��ֱ���� 150*6f7f8ab0SZhong Yang pSubVal = &subRow; 151*6f7f8ab0SZhong Yang pRefVal = &row; 152*6f7f8ab0SZhong Yang MaxVal = pInfo->height - 1; 153*6f7f8ab0SZhong Yang } 154*6f7f8ab0SZhong Yang 155*6f7f8ab0SZhong Yang LPBYTE pSrcPixel = NULL; 156*6f7f8ab0SZhong Yang LPBYTE pDestPixel = NULL; 157*6f7f8ab0SZhong Yang 158*6f7f8ab0SZhong Yang for (row = pInfo->rowBegin; row < pInfo->rowEnd; ++row) 159*6f7f8ab0SZhong Yang { 160*6f7f8ab0SZhong Yang for (col = 0; col < pInfo->width; ++col) 161*6f7f8ab0SZhong Yang { 162*6f7f8ab0SZhong Yang pDestPixel = pInfo->pDest + pInfo->stride * row + col; 163*6f7f8ab0SZhong Yang 164*6f7f8ab0SZhong Yang result = 0; 165*6f7f8ab0SZhong Yang 166*6f7f8ab0SZhong Yang subRow = row; 167*6f7f8ab0SZhong Yang subCol = col; 168*6f7f8ab0SZhong Yang 169*6f7f8ab0SZhong Yang for (x = -pInfo->r; x <= pInfo->r; x++) 170*6f7f8ab0SZhong Yang { 171*6f7f8ab0SZhong Yang //�߽紦�� 172*6f7f8ab0SZhong Yang x1 = (x >= 0) ? x : (-x); 173*6f7f8ab0SZhong Yang *pSubVal = *pRefVal + x; 174*6f7f8ab0SZhong Yang if (*pSubVal < 0) *pSubVal = 0; 175*6f7f8ab0SZhong Yang else if (*pSubVal > MaxVal) *pSubVal = MaxVal; 176*6f7f8ab0SZhong Yang 177*6f7f8ab0SZhong Yang pSrcPixel = pInfo->pSrc + pInfo->stride * subRow + subCol; 178*6f7f8ab0SZhong Yang 179*6f7f8ab0SZhong Yang result += *pSrcPixel * pInfo->pTempl[x1]; 180*6f7f8ab0SZhong Yang } 181*6f7f8ab0SZhong Yang *pDestPixel = (BYTE)result; 182*6f7f8ab0SZhong Yang } 183*6f7f8ab0SZhong Yang } 184*6f7f8ab0SZhong Yang return 0; 185*6f7f8ab0SZhong Yang } 186*6f7f8ab0SZhong Yang 187*6f7f8ab0SZhong Yang DWORD CGaussBlur::GaussBlurThreadProc24(LPVOID lpParameters) 188*6f7f8ab0SZhong Yang { 189*6f7f8ab0SZhong Yang CGaussBlurThreadParams *pInfo = (CGaussBlurThreadParams*)lpParameters; 190*6f7f8ab0SZhong Yang 191*6f7f8ab0SZhong Yang double result[3]; 192*6f7f8ab0SZhong Yang int row, col, subRow, subCol, MaxVal, x, x1; 193*6f7f8ab0SZhong Yang LPINT pSubVal, pRefVal; 194*6f7f8ab0SZhong Yang 195*6f7f8ab0SZhong Yang if (pInfo->bHorz) 196*6f7f8ab0SZhong Yang { 197*6f7f8ab0SZhong Yang //ˮƽ���� 198*6f7f8ab0SZhong Yang pSubVal = &subCol; 199*6f7f8ab0SZhong Yang pRefVal = &col; 200*6f7f8ab0SZhong Yang MaxVal = pInfo->width - 1; 201*6f7f8ab0SZhong Yang } 202*6f7f8ab0SZhong Yang else 203*6f7f8ab0SZhong Yang { 204*6f7f8ab0SZhong Yang //��ֱ���� 205*6f7f8ab0SZhong Yang pSubVal = &subRow; 206*6f7f8ab0SZhong Yang pRefVal = &row; 207*6f7f8ab0SZhong Yang MaxVal = pInfo->height - 1; 208*6f7f8ab0SZhong Yang } 209*6f7f8ab0SZhong Yang 210*6f7f8ab0SZhong Yang LPBYTE pSrcPixel = NULL; 211*6f7f8ab0SZhong Yang LPBYTE pDestPixel = NULL; 212*6f7f8ab0SZhong Yang 213*6f7f8ab0SZhong Yang for (row = pInfo->rowBegin; row < pInfo->rowEnd; ++row) 214*6f7f8ab0SZhong Yang { 215*6f7f8ab0SZhong Yang for (col = 0; col < pInfo->width; ++col) 216*6f7f8ab0SZhong Yang { 217*6f7f8ab0SZhong Yang pDestPixel = pInfo->pDest + pInfo->stride * row + pInfo->pixelSize * col; 218*6f7f8ab0SZhong Yang 219*6f7f8ab0SZhong Yang result[0] = 0; 220*6f7f8ab0SZhong Yang result[1] = 0; 221*6f7f8ab0SZhong Yang result[2] = 0; 222*6f7f8ab0SZhong Yang 223*6f7f8ab0SZhong Yang subRow = row; 224*6f7f8ab0SZhong Yang subCol = col; 225*6f7f8ab0SZhong Yang 226*6f7f8ab0SZhong Yang for (x = -pInfo->r; x <= pInfo->r; x++) 227*6f7f8ab0SZhong Yang { 228*6f7f8ab0SZhong Yang x1 = (x >= 0) ? x : (-x); 229*6f7f8ab0SZhong Yang *pSubVal = *pRefVal + x; 230*6f7f8ab0SZhong Yang 231*6f7f8ab0SZhong Yang //�߽紦��Photoshop ���õ��Ƿ���1�� 232*6f7f8ab0SZhong Yang //����1��ȡ��Ե���أ�ͼ���Ե�������ڲ���ɢ���� 233*6f7f8ab0SZhong Yang if (*pSubVal < 0) *pSubVal = 0; 234*6f7f8ab0SZhong Yang else if (*pSubVal > MaxVal) *pSubVal = MaxVal; 235*6f7f8ab0SZhong Yang 236*6f7f8ab0SZhong Yang //����2��ȡ��ǰ���أ�ʹ��Խ����ͼ���Ե�ĵط�Խ������ 237*6f7f8ab0SZhong Yang /* 238*6f7f8ab0SZhong Yang if(*pSubVal < 0 || *pSubVal > MaxVal) 239*6f7f8ab0SZhong Yang *pSubVal = *pRefVal; 240*6f7f8ab0SZhong Yang */ 241*6f7f8ab0SZhong Yang 242*6f7f8ab0SZhong Yang pSrcPixel = pInfo->pSrc + pInfo->stride * subRow + pInfo->pixelSize * subCol; 243*6f7f8ab0SZhong Yang 244*6f7f8ab0SZhong Yang result[0] += pSrcPixel[0] * pInfo->pTempl[x1]; 245*6f7f8ab0SZhong Yang result[1] += pSrcPixel[1] * pInfo->pTempl[x1]; 246*6f7f8ab0SZhong Yang result[2] += pSrcPixel[2] * pInfo->pTempl[x1]; 247*6f7f8ab0SZhong Yang } 248*6f7f8ab0SZhong Yang pDestPixel[0] = (BYTE)result[0]; 249*6f7f8ab0SZhong Yang pDestPixel[1] = (BYTE)result[1]; 250*6f7f8ab0SZhong Yang pDestPixel[2] = (BYTE)result[2]; 251*6f7f8ab0SZhong Yang } 252*6f7f8ab0SZhong Yang } 253*6f7f8ab0SZhong Yang return 0; 254*6f7f8ab0SZhong Yang } 255