/* Image.c */
/* Paul Boersma, September 24, 2000 */

#include "Image.h"
#include "Matrix.h"

#include "oo_DESTROY.h"
#include "Image_def.h"
#include "oo_COPY.h"
#include "Image_def.h"
#include "oo_EQUAL.h"
#include "Image_def.h"
#include "oo_WRITE_ASCII.h"
#include "Image_def.h"
#include "oo_READ_ASCII.h"
#include "Image_def.h"
#include "oo_WRITE_BINARY.h"
#include "Image_def.h"
#include "oo_READ_BINARY.h"
#include "Image_def.h"
#include "oo_DESCRIPTION.h"
#include "Image_def.h"

static void info (I) {
	iam (Image);
	Melder_information ("xmin = %.8g\nxmax = %.8g\nymin = %.8g\nymax = %.8g\n"
		"Number of columns = %ld\nNumber of rows = %ld\n"
		"dx = %.8g (-> sample rate %.8g)\ndy = %.8g (-> sample rate %.8g)\n"
		"x1 = %.8g\ny1 = %.8g",
		my xmin, my xmax, my ymin, my ymax, my nx, my ny,
		my dx, 1 / my dx, my dy, 1 / my dy, my x1, my y1);
}

class_methods (Image, Sampled)
	class_method_local (Image, destroy)
	class_method_local (Image, copy)
	class_method_local (Image, equal)
	class_method_local (Image, writeAscii)
	class_method_local (Image, readAscii)
	class_method_local (Image, writeBinary)
	class_method_local (Image, readBinary)
	class_method_local (Image, description)
	class_method (info)
class_methods_end

int Image_init
	(I, double xmin, double xmax, long nx, double dx, double x1,
		 double ymin, double ymax, long ny, double dy, double y1)
{
	iam (Image);
	if (! Sampled_init (me, xmin, xmax, nx, dx, x1)) return 0;
	my ymin = ymin; my ymax = ymax; my ny = ny; my dy = dy; my y1 = y1;
	if (! (my z = NUMubmatrix (1, my ny, 1, my nx))) return 0;
	return 1;
}

Image Image_create
	(double xmin, double xmax, long nx, double dx, double x1,
	 double ymin, double ymax, long ny, double dy, double y1)
{
	Image me = new (Image);
	if (! me || ! Image_init (me, xmin, xmax, nx, dx, x1, ymin, ymax, ny, dy, y1)) forget (me);
	return me;
}

long Image_getWindowExtrema (I, long ixmin, long ixmax, long iymin, long iymax,
	unsigned char *minimum, unsigned char *maximum)
{
	iam (Image);
	long iy, ix;
	if (ixmin == 0) ixmin = 1;
	if (ixmax == 0) ixmax = my nx;
	if (iymin == 0) iymin = 1;
	if (iymax == 0) iymax = my ny;
	if (ixmin > ixmax || iymin > iymax) return 0;
	*minimum = *maximum = my z [iymin] [ixmin];
	for (iy = iymin; iy <= iymax; iy ++)
		for (ix = ixmin; ix <= ixmax; ix ++)
		{
			if (my z [iy] [ix] < *minimum) *minimum = my z [iy] [ix];
			if (my z [iy] [ix] > *maximum) *maximum = my z [iy] [ix];
		}
	return (ixmax - ixmin + 1) * (iymax - iymin + 1);
}

void Image_paint (I, Graphics g, double xmin, double xmax, double ymin, double ymax,
	unsigned char minimum, unsigned char maximum)
{
	iam (Image);
	long ixmin, ixmax, iymin, iymax;
	if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; }
	if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; }
	(void) Matrix_getWindowSamplesX (me, xmin - 0.49999 * my dx, xmax + 0.49999 * my dx,
		& ixmin, & ixmax);
	(void) Matrix_getWindowSamplesY (me, ymin - 0.49999 * my dy, ymax + 0.49999 * my dy,
		& iymin, & iymax);
	if (maximum <= minimum)
		(void) Image_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, & minimum, & maximum);
	if (maximum <= minimum) { minimum -= 1; maximum += 1; }
	Graphics_setInner (g);
	Graphics_setWindow (g, xmin, xmax, ymin, ymax);
	Graphics_image8 (g, my z,
		ixmin, ixmax, Matrix_columnToX (me, ixmin - 0.5), Matrix_columnToX (me, ixmax + 0.5),
		iymin, iymax, Matrix_rowToY (me, iymin - 0.5), Matrix_rowToY (me, iymax + 0.5),
		minimum, maximum);
	Graphics_rectangle (g, xmin, xmax, ymin, ymax);
	Graphics_unsetInner (g);
}

/* End of file Image.c */
