xref: /MusicPlayer2/MusicPlayer2/GaussBlur.cpp (revision 6f7f8ab0d71659caea432b10ad57c6f4cae50827)
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(&params);
115*6f7f8ab0SZhong Yang 	else
116*6f7f8ab0SZhong Yang 		GaussBlurThreadProc24(&params);
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(&params);
125*6f7f8ab0SZhong Yang 	else
126*6f7f8ab0SZhong Yang 		GaussBlurThreadProc24(&params);
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