RawImage* MedianFilter::ProcessInput(CommandLineArgModel* arg, RawImage* image)
{
	MedianFilterModel* model = (MedianFilterModel*)arg->ParsedModel;

	if (model->Window == 1) return image;

	Rectangle roi = model->Roi;
	int padding = (model->Window - 1) / 2;
	int window = model->Window;

	RawImage* returnValue = NULL;

	if (padding > 1)
	{
		if (model->Y)
		{
			returnValue = image->Clone();

			for (int x = roi.X; x < roi.Right; x++)
				for (int y = roi.Y; y < roi.Bottom; y++)
					returnValue->SetPixel(x, y, image->GetAverage(x, y - padding, 1, window, roi));
			image = returnValue;
		}

		if (model->X)
		{
			returnValue = image->Clone();
			for (int x = roi.X; x < roi.Right; x++)
				for (int y = roi.Y; y < roi.Bottom; y++)
					returnValue->SetPixel(x, y, image->GetAverage(x - padding, y, window, 1, roi));
		}
	}

	return returnValue == NULL ? image : returnValue;
}
RawImage* ScaleFilter::scaleUp(double scale, RawImage* image)
{
	ImageSize size = image->GetSize();

	int newHeight = (int)round(size.Height * scale);
	int newWidth = (int)round(size.Width * scale);
	RawImage* returnValue = new RawImage(newWidth, newHeight);
	Rectangle roi = fromSize(size);
	double scaleDown = 1.0 / scale;

	for (int y = 0; y < newHeight; y++)
		for (int x = 0; x < newWidth; x++)
		{
			int sourceX = (int)round((double)x * scaleDown);
			int sourceY = (int)round((double)y * scaleDown);

			if (sourceX < roi.Width && sourceY < roi.Height)
				returnValue->SetPixel(x, y, image->GetPixel(sourceX, sourceY));
		}


	MedianFilterModel* model = new MedianFilterModel();
	model->hasRoi = true;
	model->Roi = fromSize(returnValue->GetSize());
	model->Window = (int)ceil(scale * 3.0);
	model->X = true;
	model->Y = true;

	CommandLineArgModel* command = new CommandLineArgModel();
	command->ParsedModel = model;

	return median->ProcessInput(command, returnValue);
}
RawImage* ScaleFilter::scaleDown(double scale, RawImage* image)
{
	ImageSize size = image->GetSize();

	int newHeight = (int)round((double)size.Height * scale);
	int newWidth = (int)round((double)size.Width * scale);
	RawImage* returnValue = new RawImage(newWidth, newHeight);
	Rectangle roi = fromSize(size);
	double scaleUp = 1.0 / scale;
	int scaleWindow = max((int)floor(scaleUp), 1);

	if (scaleWindow % 2 == 0) scaleWindow++;

	for (int y = 0; y < newHeight; y++)
		for (int x = 0; x < newWidth; x++)
		{
			int sourceX = (int)round((double)x * scaleUp);
			int sourceY = (int)round((double)y * scaleUp);

			returnValue->SetPixel(x, y, image->GetAverage(sourceX, sourceY, scaleWindow, scaleWindow, roi));
		}

	return returnValue;
}