void LuminosityAlgorithm::doAlgorithm(const RGBImage& input, IntensityImage& output)
{
	// Check image size
	if (input.getWidth() != output.getWidth() || input.getHeight() != output.getHeight()) {
		output.set(input.getWidth(), input.getHeight());
	}

	// Lunimosity Algorithm defined as
	// Gray = (Red * 0.2126 + Green * 0.7152 + Blue * 0.0722)
	for (int i = 0; i < input.getWidth()*input.getHeight(); i++) {
		RGB pixel = input.getPixel(i);
		output.setPixel(i, pixel.r * 0.2126 + pixel.g * 0.7152 + pixel.b * 0.0722);
	}
}
void safePixelDraw(RGBImage &image, const double dx, const double dy, const RGB color) {
	int x = (int) std::round(dx);
	int y = (int) std::round(dy);
	if (x > -1 && x < image.getWidth() && y > -1 && y < image.getHeight()) {
		image.setPixel(x, y, color);
	}
}
void HereBeDragons::ButRisingAtThyNameDothPointOutThee(RGBImage &image, const Point2D<double> start, const Point2D<double> end, const RGB color) {
	//Bresenham's line algorithm
	//http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#C.2B.2B


	double x1 = std::round(start.x);
	double y1 = std::round(start.y);
	double x2 = std::round(end.x);
	double y2 = std::round(end.y);

	const bool steep = (fabs(y2 - y1) > fabs(x2 - x1));
	if (steep) {
		std::swap(x1, y1);
		std::swap(x2, y2);
	}

	if (x1 > x2) {
		std::swap(x1, x2);
		std::swap(y1, y2);
	}

	const double dx = x2 - x1;
	const double dy = fabs(y2 - y1);

	double error = dx / 2.0f;
	const int ystep = (y1 < y2) ? 1 : -1;
	int y = (int)y1;

	const int maxX = (int)x2;

	for (int x = (int)x1; x<maxX; x++) {
		if (steep) {
			if (y > -1 && y < image.getWidth() && x > -1 && x < image.getHeight()) {
				image.setPixel(y, x, color);
			}
		} else {
			if (x > -1 && x < image.getWidth() && y > -1 && y < image.getHeight()) {
				image.setPixel(x, y, color);
			}
		}
		error -= dy;
		if (error < 0) {
			y += ystep;
			error += dx;
		}
	}
}
RGBImageStudent::RGBImageStudent(const RGBImage &other) : RGBImage(other.getWidth(), other.getHeight()), pixelMap(nullptr) {
	const int SIZE = other.getSize();
	if (SIZE > 0) {
		pixelMap = new RGB[SIZE];
		for (int i = 0; i < SIZE; i++) {
			pixelMap[i] = other.getPixel(i);
		}
	}
}
void RGBImageStudent::set(const RGBImage &other) {
	const int SIZE = other.getSize();
	RGBImage::set(other.getWidth(), other.getHeight());

	if (SIZE > 0) {
		delete[] pixelMap;
		pixelMap = new RGB[SIZE];
		for (int i = 0; i < SIZE; i++) {
			pixelMap[i] = other.getPixel(i);
		}
	}
}
void HereBeDragons::ToStandInThyAffairsFallByThySide(const RGBImage &src, cv::Mat &dst) {
	int w = src.getWidth();
	int h = src.getHeight();

	dst.create(h, w, CV_8UC3);

	for (int x = 0; x < dst.cols; x++) {
		for (int y = 0; y < dst.rows; y++) {
			RGB color = src.getPixel(x, y);
			dst.at<cv::Vec3b>(y, x) = cv::Vec3b(color.b, color.g, color.r);
		}
	}
}