
/* autopano-sift, Automatic panorama image creation
 * Copyright (C) 2004 -- Sebastian Nowozin
 *
 * This program is free software released under the GNU General Public
 * License, which is included in this software package (doc/LICENSE).
 */

/* GUIImage-Drawing.cs
 *
 * Thin wrapper around the BasicDrawingInterface to allow operation with only
 * the System.Drawing namespace's functions. This is to drop the Gtk#
 * dependency for the command line tools generatekeys.exe and autopano.exe.
 */

using System;
using System.Drawing;
using System.Drawing.Drawing2D;


public class DisplayImage : BasicImagingInterface
{
	public override int Width {
		get {
			return (bm.Width);
		}
	}
	public override int Height {
		get {
			return (bm.Height);
		}
	}

	private Bitmap bm;

	private DisplayImage ()
	{
	}

	public DisplayImage (string filename)
	{
		bm = new Bitmap (filename);
	}

	private DisplayImage (Bitmap bm)
	{
		this.bm = bm;
	}

	public override double ScaleWithin (int dim)
	{
		if (Width <= dim && Height <= dim)
			return (1.0);

		float xScale = ((float) dim / Width);
		float yScale = ((float) dim / Height);
		float smallestScale = xScale <= yScale ? xScale : yScale;

		// Scale image.
		// XXX: under Mono this produces ugly nearest-neighbour sampled
		// versions, so stay away from using Mono with this code (yet).
		Bitmap bmScaled = new Bitmap ((int) (Width * smallestScale + 0.5F),
			(int) (Height * smallestScale + 0.5F));
		Graphics gr = Graphics.FromImage (bmScaled);
		gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
		gr.DrawImage (bm, new RectangleF (0.0F, 0.0F,
			Width * smallestScale, Height * smallestScale));

		bm = bmScaled;

		return (smallestScale);
	}

	/** Carve a part out of the image, where (x1, y1) is the lower top
	 * rectangle with the given width and height.
	 *
	 * Return the carved copy of the image.
	 */
	public DisplayImage Carve (int x1, int y1, int width, int height)
	{
		Rectangle cr = new Rectangle (x1, y1, width, height);

		Bitmap carved = bm.Clone (cr, bm.PixelFormat);
		//carved.Save ("test.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);

		return (new DisplayImage (carved));
	}

	public void Save (string filename)
	{
		bm.Save (filename, System.Drawing.Imaging.ImageFormat.Jpeg);
	}

	public override ImageMap ConvertToImageMap (IPixelConverter pconv)
	{
		if (pconv == null)
			pconv = new CanonicalPixelConverter ();

		ImageMap res = new ImageMap (Width, Height);

		// This code is quite slow, but I found no quick way to convert and
		// access the raw image data at always the same format. So, fix it or
		// stick with it. At least it looks elegant ;-)
		for (int y = 0 ; y < Height ; ++y) {
			for (int x = 0 ; x < Width ; ++x) {
				Color col = bm.GetPixel (x, y);

				res[x, y] = pconv.Convert (col.R, col.G, col.B);
			}
		}

		return (res);
	}
}


