int* SharpenFilter::highBoostSharpen() {
	int boostFactor = 1;
	int *blurPixels = new int[width * height];
	memcpy(blurPixels, pixels, width * height * sizeof(int));

	AverageSmoothFilter *smoothFilter = new AverageSmoothFilter(blurPixels, width, height);
	blurPixels = smoothFilter->procImage();

	int *edgePixels = new int[width * height];
	for (int i = 0; i < width * height; i++) {
		Color pixColor(pixels[i]);
		Color blurColor(blurPixels[i]);
		int edgeR = min(255, max(0, pixColor.R() - blurColor.R()));
		int edgeG = min(255, max(0, pixColor.G() - blurColor.G()));
		int edgeB = min(255, max(0, pixColor.B() - blurColor.B()));
		edgePixels[i] = RGB2Color(edgeR, edgeG, edgeB);
	}

	for (int i = 0; i < width * height; i++) {
		Color pixColor(pixels[i]);
		Color edgeColor(edgePixels[i]);
		int r = min(255, max(0, pixColor.R() + boostFactor * edgeColor.R()));
		int g = min(255, max(0, pixColor.G() + boostFactor * edgeColor.G()));
		int b = min(255, max(0, pixColor.B() + boostFactor * edgeColor.B()));
		pixels[i] = RGB2Color(r, g, b);
	}

	delete smoothFilter;
	delete [] edgePixels;

	return pixels;
}
int* SoftGlowFilter::procImage() {
	int *blurPixels = new int[this->width * this->height];
	memcpy(blurPixels, pixels, width * height * sizeof(int));

	GaussianBlurFilter *gaussianFilter = new GaussianBlurFilter(blurPixels, width, height, blurSigma);
	blurPixels = gaussianFilter->procImage();

	int originR = 0, originG = 0, originB = 0, originA = 0;
	int pixR = 0, pixG = 0, pixB = 0, pixA = 0;

	double factorA = 1;
	double factorB = 0.3;
	for (int row = 0; row < height; row++) {
		for (int col = 0; col < width; col++) {
			Color originColor(blurPixels[row * width + col]);
			originR = originColor.R();
			originG = originColor.G();
			originB = originColor.B();

			Color pixColor(pixels[row * width + col]);
			pixA = pixColor.alpha();
			pixR = pixColor.R();
			pixG = pixColor.G();
			pixB = pixColor.B();

			pixR = originR * factorA + pixR * factorB;
			pixG = originG * factorA + pixG * factorB;
			pixB = originB * factorA + pixB * factorB;
//			pixR = ((pixR < 128) ?
//					(2 * ((originR >> 1) + 64)) * ((float) pixR / 255) :
//					(255 - (2 * (255 - ((originR >> 1) + 64)) * (float) (255 - pixR) / 255)));
//
//			pixG = ((pixG < 128) ?
//					(2 * ((originG >> 1) + 64)) * ((float) pixG / 255) :
//					(255 - (2 * (255 - ((originG >> 1) + 64)) * (float) (255 - pixG) / 255)));
//			pixB = ((pixB < 128) ?
//					(2 * ((originB >> 1) + 64)) * ((float) pixB / 255) :
//					(255 - (2 * (255 - ((originB >> 1) + 64)) * (float) (255 - pixB) / 255)));

			pixR = min(255, max(pixR, 0));
			pixG = min(255, max(pixG, 0));
			pixB = min(255, max(pixB, 0));

			pixels[row * width + col] = ARGB2Color(pixA, pixR, pixG, pixB);
		}
	}

	delete gaussianFilter;
	return pixels;
}
int* SharpenFilter::procImage() {
	int pixR, pixG, pixB, newR, newG, newB, index;
	int laplacian[] = {0, -1, 0, -1, 4, -1, 0, -1, 0}; // 3 * 3 laplacian
	int maskSize = 3;
	int halfMaskSize = maskSize / 2;

	int *edgePixels = new int[width * height];
	memset(edgePixels, 0, width * height * sizeof(int));

	for (int i = halfMaskSize; i < height - halfMaskSize; i++)  {
		for (int k = halfMaskSize; k < width - halfMaskSize; k++)  {
			index = 0;
			newR = newG = newB = 0;
			for (int m = -halfMaskSize; m <= halfMaskSize; m++) {
				for (int n = -halfMaskSize; n <= halfMaskSize; n++) {

					Color pixColor(pixels[(i + n) * width + k + m]);
					pixR = pixColor.R();
					pixG = pixColor.G();
					pixB = pixColor.B();

					newR += pixR * laplacian[index];
					newG += pixG * laplacian[index];
					newB += pixB * laplacian[index];
					index++;
				}
			}

			newR = min(255, max(0, newR));
			newG = min(255, max(0, newG));
			newB = min(255, max(0, newB));

			edgePixels[i * width + k] = RGB2Color(newR, newG, newB);
		}
	}

	for (int i = 0; i < width * height; i++) {
		Color edgeColor(edgePixels[i]);
		Color originColor(pixels[i]);

		int r = min(255, max(0, edgeColor.R() + originColor.R()));
		int g = min(255, max(0, edgeColor.G() + originColor.G()));
		int b = min(255, max(0, edgeColor.B() + originColor.B()));

		pixels[i] = RGB2Color(r, g, b);
	}

	delete [] edgePixels;
	return pixels;
}