/*
 * GraphApp - Cross-Platform Graphics Programming Library.
 *
 * File: image.c -- cross-platform image type.
 * Platform: Neutral  Version: 2.40  Date: 1998/05/05
 *
 * Version: 2.30  Changes: Original version by Lachlan Patrick.
 * Version: 2.40  Changes: Faster drawing, image scaling and cropping.
 */

/* Copyright (C) 1993-1998 Lachlan Patrick

   This file is part of GraphApp, a cross-platform C graphics library.

   GraphApp is free software; you can redistribute it and/or modify it
   under the terms of the GNU Library General Public License.
   GraphApp is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY.

   See the file COPYLIB.TXT for details.
*/

/*
 *  Image
 *  -----
 *  An image is a platform-indepedent representation of a
 *  rectangular picture, in RGB colour format. There are two
 *  possible formats the picture can use: 8-bit indexed colour,
 *  and 32-bit true colour (RGB plus alpha channel).
 *
 *  An image in 8-bit format has the following properties:
 *    - depth is set to 8
 *    - pixels is an array of (width*height) bytes
 *    - cmapsize is set to a non-zero value
 *    - cmap is an array of cmapsize rgb values
 *
 *  An image in 32-bit format has the following properties:
 *    - depth is set to 32
 *    - pixels is an array of (width * height) rgb values
 *    - cmapsize is zero and cmap is NULL (an empty array)
 *
 *  Any other depth is deliberately not supported.
 *  Transparency is handled in the alpha channel of each rgb value
 *  (either inside the cmap, or in the pixels array itself).
 */

#include "internal.h"

/*
 *  Create a new image:
 */
image newimage(int width, int height, int depth)
{
    image img;

    if ((depth != 8) && (depth != 32))
	return NULL;

    img = create(struct imagedata);

    if (! img)
	return img;

    img->width  = width;
    img->height = height;

    if (depth == 8) {
	img->depth  = 8;
	img->pixels = array(width*height, GAbyte);
    }
    else {
	img->depth  = 32;
	img->pixels = (GAbyte *) array(width*height, rgb);
    }

    return img;
}

/*
 *  Make a new copy of an image:
 */
image copyimage(image img)
{
    image new_img;

    if (! img)
	return img;

    new_img = newimage(img->width, img->height, img->depth);
    setpixels(new_img, img->pixels);
    setpalette(new_img, img->cmapsize, img->cmap);

    return new_img;
}

/*
 *  Delete an image:
 */
void delimage(image img)
{
    if (img) {
	discard(img->cmap);
	discard(img->pixels);
	discard(img);
    }
}

/*
 *  Print an image:
 */
#if DEBUG
PROTECTED
void printimage(FILE *file, image img)
{
    int i;
    long w, h, n;

    fprintf(file, "Pixmap:\n");
    fprintf(file, " depth     = %d\n", img->depth);
    fprintf(file, " width     = %d\n", img->width);
    fprintf(file, " height    = %d\n", img->height);
    fprintf(file, " cmapsize = %d\n", img->cmapsize);
    fprintf(file, " cmap:\n");
    for (i=0; i < img->cmapsize; i++)
	fprintf(file, "  %-02.2X = %-08.8lX\n", i, img->cmap[i]);
    fprintf(file, " pixels:\n");
    for (h=0; h < img->height; h++) {
	fprintf(file, "  [");
	for (w=0; w < (img->width * img->depth / 8); w++) {
	    n = h * (img->width * img->depth / 8) + w;
	    fprintf(file, "%-02.2X", img->pixels[n]);
	}
	fprintf(file, "]\n");
    }
}
#endif

/*
 *  Discover the dimensions of the image:
 */

int imagedepth(image img)  { return ((img)?(img->depth):0);}
int imagewidth(image img)  { return ((img)?(img->width):0);}
int imageheight(image img) { return ((img)?(img->height):0);}

/*
 *  Change an image's pixels:
 */
void setpixels(image img, GAbyte pixels[])
{
    long i, length;

    if (! img)
	return;

    length = img->width * img->height;
    if (img->depth > 8)
	length = length * sizeof(rgb);

    for (i=0; i < length; i++)
	img->pixels[i] = pixels[i];
}

/*
 *  Return an image's pixel array:
 */
GAbyte * getpixels(image img)
{
    if (img)
	return img->pixels;
    else
	return NULL;
}

/*
 *  Change an image's cmap:
 */
void setpalette(image img, int cmapsize, rgb *cmap)
{
    int i;

    if (! img)
	return;

    discard(img->cmap);

    img->cmapsize = cmapsize;
    img->cmap = array(cmapsize, rgb);

    for (i=0; i < cmapsize; i++)
	img->cmap[i] = cmap[i];
}

/*
 *  Return information about an image's cmap:
 */
rgb * getpalette(image img)
{
    if (img)
	return img->cmap;
    else
	return NULL;
}

int getpalettesize(image img)
{
    if (img)
	return img->cmapsize;
    else
	return 0;
}

/*
 *  Try to generate an 8-bit version of an image:
 *  If there are less than 256 unique colours in a 32-bit
 *  image, this routine will return the corresponding
 *  indexed 8-bit image.
 *  Returns NULL if more than 256 colours are found.
 */
static image fast_find_cmap (image img)
{
    image new_img;
    long   i, j, length;
    rgb *  pixel32;
    GAbyte * pixel8;
    int    cmapsize, low, high, mid;
    rgb    col;
    rgb    cmap[256];

    pixel32 = (rgb *) img->pixels;

    /* the first colour goes into the cmap automatically: */
    length = img->width * img->height;
    cmapsize = 0;  mid = 0;

    for (i=0; i < length; i++)
    {
	col = *pixel32 ++;
	/* only allow one transparent colour in the cmap: */
	if (col & 0xF0000000UL)
	    col  = 0xFFFFFFFFUL;	/* transparent */
	else
	    col &= 0x00FFFFFFUL;	/* opaque */

	/* binary search the cmap: */
	low = 0;  high = cmapsize - 1;
	while (low <= high) {
	    mid = (low+high)/2;
	    if      (col < cmap[mid]) high = mid - 1;
	    else if (col > cmap[mid]) low  = mid + 1;
	    else break;
	}

	if (high < low) {
	    /* didn't find colour in cmap, insert it: */
	    if (cmapsize >= 256)
		return NULL;
	    for (j=cmapsize; j > low; j--)
		cmap[j] = cmap[j-1];
	    cmap[low] = col;
	    cmapsize ++;
	}
    }

    /* now create the 8-bit indexed image: */

    new_img = newimage(img->width, img->height, 8);
    if (! new_img)
	return new_img;
    setpalette(new_img, cmapsize, cmap);

    /* now convert each 32-bit pixel into an 8-bit pixel: */

    pixel32 = (rgb *) img->pixels;
    pixel8 = (GAbyte *) new_img->pixels;

    for (i=0; i < length; i++)
    {
	col = *pixel32 ++;

	/* only allow one transparent colour in the cmap: */
	if (col & 0xF0000000UL)
	    col  = 0xFFFFFFFFUL;	/* transparent */
	else
	    col &= 0x00FFFFFFUL;	/* opaque */

	/* binary search the cmap (the colour must be there): */
	low = 0;  high = cmapsize - 1;
	while (low <= high) {
	    mid = (low+high)/2;
	    if      (col < cmap[mid]) high = mid - 1;
	    else if (col > cmap[mid]) low  = mid + 1;
	    else break;
	}

	if (high < low) {
	    /* impossible situation */
	    delimage(new_img);
	    return NULL;
	}

	*pixel8 = mid;  pixel8 ++;
    }

    return new_img;
}

/*
 *  Try to generate an 8-bit version of an image:
 *  This routine will approximate a 32-bit image using a
 *  7x7x5 colour cube.
 *  If it runs out of memory, it returns NULL.
 */
static image fast_generate_cmap (image img)
{
    image new_img;
    long   i, length, col;
    int    r, g, b, value;
    rgb *  pixel32;
    GAbyte * pixel8;
    rgb    cmap[256];

    /* Generate the colour map: */

    for (r=0; r<7; r++)		/* 7x7x5 colour cube */
	for (g=0; g<7; g++)
	    for (b=0; b<5; b++)
		cmap [r*35 + g*5 + b] = rgb(r,g,b);

    for (i=0; i<9; i++)		/* greyscale ramp */
    {
	value = 255 * i / 8;
	cmap [254 - 8 + i] = rgb(value, value, value);
    }

    cmap [255] = 0xFFFFFFFFUL;	/* transparent */

    /* Generate the 8-bit indexed image: */

    new_img = newimage(img->width, img->height, 8);
    if (! new_img)
	return new_img;
    setpalette(new_img, 256, cmap);

    /* Translate the pixels from 32-bit to 8-bit: */

    length = img->width * img->height;
    pixel32 = (rgb *) img->pixels;
    pixel8 = (GAbyte *) new_img->pixels;

    for (i=0; i < length; i++) {
	col = *pixel32 ++;
	r = getred(col);
	g = getgreen(col);
	b = getblue(col);

	if (getalpha(col) > 0x7F)  /* transparent */
	    value = 255;

	else if ((r == g) && (r == b))	/* grey */
	{
	    r = (r + 16) / 32;
	    if (r == 0)
		value = 0;	/* black */
	    else
		value = 254 - 8 + r;
	}

	else	/* map to 7x7x5 colour cube */
	{
	    r = (r + 21) / 42;
	    g = (g + 21) / 42;
	    b = (b + 32) / 64;

	    value = r*35 + g*5 + b;
	}

	*pixel8 = value;  pixel8 ++;
    }

    return new_img;
}

/*
 *  Try to generate an 8-bit version of a 32-bit image:
 *  Return NULL on failure.
 */
image convert32to8 (image img)
{
    image new_img;

    if (! img)
	return img;

    if (img->depth <= 8)
	return copyimage(img);

    new_img = fast_find_cmap(img);
    if (! new_img)
	new_img = fast_generate_cmap(img);

    return new_img;
}

/*
 *  Try to generate a 32-bit version of an 8-bit image:
 *  Return NULL if there is no memory left.
 */
image convert8to32 (image img)
{
    image new_img;
    long i;
    rgb *pixel32;
    GAbyte *pixel8;
    GAbyte value;

    if (! img)
	return img;

    new_img = newimage(img->width, img->height, 32);
    if (! new_img)
	return new_img;

    pixel32 = (rgb *) new_img->pixels;
    pixel8 = (GAbyte *) img->pixels;

    for (i=img->width * img->height; i; i--) {
	value = *pixel8 ++;
	if (value >= img->cmapsize)
	    value = img->cmapsize - 1;
	*pixel32 ++ = img->cmap[value];
    }

    return new_img;
}

/*
 *  Sort an image's colour map, eliminating redudancies.
 *  This operation transforms an existing image.
 */

typedef int (*qsort_func)(const void *a, const void *b);

static int compare_freq(long *a, long *b)
{
    long freq_a, freq_b;
    int value_a, value_b;

    freq_a = (*a) >> 8;
    freq_b = (*b) >> 8;
    value_a = (*a) & 0x00FF;
    value_b = (*b) & 0x00FF;

    if (freq_a < freq_b)        return (+1);
    else if (freq_a > freq_b)   return (-1);
    else                        return (value_a - value_b);
}

void sortpalette(image img)
{
    long	i, j, length;
    int	old_value, new_value;
    rgb	col;
    int	new_size;
    long *	histogram;
    GAbyte *	translate;
    rgb *	new_cmap;

    if (! img)
	return;
    if (img->depth > 8)
	return;

    histogram = array(256, long);
    translate = array(256, GAbyte);

    /* Generate a colour histogram: */
    length = img->width * img->height;
    for (i=0; i < length; i++)
	histogram[img->pixels[i]] ++;

    /* Place colour indexes in low byte of histogram: */
    for (i=0; i < 256; i++) {
	histogram[i] <<= 8;
	histogram[i] |= i;
    }

    /* Sort the histogram in decreasing frequency order: */
    qsort(histogram, 256, sizeof(long), (qsort_func) compare_freq);

    /* Generate a colour translation table: */
    new_size = img->cmapsize;

    for (i=255; i >= 0; i--)
    {
	old_value = histogram[i] & 0x00FFL;
	new_value = i;
	col = img->cmap[i];

	/* coalesce identical colours in cmap */
	for (j=i-1; j >= 0; j--) {
	    if (img->cmap[j] == col)
		new_value = j;
	}

	translate[old_value] = new_value;

	/* find smallest useless colour */
	if ((histogram[i] >> 8) == 0)
	    new_size = i;
    }

    /* Generate a sorted colour map: */
    new_cmap = array(new_size, rgb);

    for (i=0; i < new_size; i++) {
	old_value = histogram[i] & 0x00FFL;
	new_value = i;
	new_cmap[new_value] = img->cmap[old_value];
    }

    /* Change the existing colour map: */
    img->cmapsize = new_size;
    for (i=0; i < new_size; i++)
	img->cmap[i] = new_cmap[i];
    discard(new_cmap);

    /* Translate the pixels to the new colour map: */
    for (i=0 ; i < length; i++)
	img->pixels[i] = translate[img->pixels[i]];

    /* Clean up and return new image: */
    discard(translate);
    discard(histogram);
}

#ifdef UNUSED
/*
 *  Load and save images (utility functions):
 */
static int string_ends_with(const char *name, const char *ending)
{
    int i, j, result;

    if (name == NULL)
	return (ending == NULL);

    result = 1;
    for (i=0; name[i]; )
	i = i + 1;
    for (j=0; ending[j]; )
	j = j + 1;
    while (result && (i >= 0) && (j >= 0)) {
	if (tolower(name[i]) != tolower(ending[j]))
	    result = 0;
	i = i - 1;
	j = j - 1;
    }
    if ((i == 0) && (j > 0))
	result = 0;
    return result;
}

static unsigned char read_hex_byte(FILE *file)
{
    int ch;
    int i, value;
    unsigned char result = 0;

    ch = 0;
    while (ch != EOF) {
	if ((ch = getc(file)) != '0') continue;
	if ((ch = getc(file)) != 'x') continue;

	for (i=0; i<2; i++) {
	    ch = getc(file);
	    if (isdigit(ch))
		value = ch - '0';
	    else if (isalpha(ch))
		value = tolower(ch) - 'a' + 10;
	    else
		return result;
	    result = (result << 4) | value;
	}
	break;
    }
    return result;
}

static unsigned long read_hex_long(FILE *file)
{
    int ch;
    int i, value;
    unsigned long result = 0;

    ch = 0;
    while (ch != EOF) {
	if ((ch = getc(file)) != '0') continue;
	if ((ch = getc(file)) != 'x') continue;

	for (i=0; i<8; i++) {
	    ch = getc(file);
	    if (isdigit(ch))
		value = ch - '0';
	    else if (isalpha(ch)) {
		ch = tolower(ch);
		if (ch > 'f')
		    return result;
		value = ch - 'a' + 10;
	    }
	    else
		return result;
	    result = (result << 4) | value;
	}
	break;
    }
    return result;
}

static const char * header_comment   = "/* GraphApp image type 1 */\n";
static const char * depth_comment    = "/* depth  = %d */\n";
static const char * width_comment    = "/* width  = %d */\n";
static const char * height_comment   = "/* height = %d */\n";
static const char * cmapsize_comment = "/* cmapsize = %d */\n";

static image load_header_image_file(FILE *file)
{
    char  line[100];
    long  i, size;
    int   width = 0, height = 0, depth = 8;
    int   cmapsize = 0;
    rgb * cmap = NULL;
    rgb  *pixel32;
    GAbyte *pixel8;
    image img = NULL;

    if (file == NULL)
	return NULL;

    if (fgets(line, sizeof(line)-2, file) == NULL)
	return NULL;
    if (strcmp(line, header_comment))
	return NULL;

    for (i=0; i<4; i++) {
	if (fgets(line, sizeof(line)-2, file) == NULL)
	    return NULL;
	if (! strncmp(line, depth_comment, 12))
	    depth = atoi(line+12);
	if (! strncmp(line, width_comment, 12))
	    width = atoi(line+12);
	if (! strncmp(line, height_comment, 12))
	    height = atoi(line+12);
	if (! strncmp(line, cmapsize_comment, 14))
	    cmapsize = atoi(line+14);
    }

    img = newimage(width, height, depth);
    if (img == NULL)
	return NULL;

    if (depth <= 8) {
	if (fgets(line, sizeof(line)-2, file) == NULL)
	    return NULL;
	if (strncmp(line, "rgb ", 4) != 0) {
	    delimage(img);
	    return NULL;
	}
	for (i=0; i<cmapsize; i++) {
	    append(cmap, read_hex_long(file));
	}
	if (fgets(line, sizeof(line)-2, file) == NULL)
	    return NULL;

	img->cmapsize = cmapsize;
	img->cmap = cmap;
    }

    pixel32 = (rgb *) img->pixels;
    pixel8  = img->pixels;
    size    = (long) width * height;

    if (fgets(line, sizeof(line)-2, file) == NULL)
	return NULL;

    if (depth <= 8) {
	for (i=0; i<size; i++)
	    pixel8[i] = read_hex_byte(file);
    }
    else {
	for (i=0; i<size; i++)
	    pixel32[i] = read_hex_long(file);
    }

    return img;
}

static void save_header_image_file(FILE *file, char *name, image img)
{
    long i, size;
    int width;
    rgb * pixel32;
    GAbyte *pixel8;

    if (file == NULL)
	return;
    if (img == NULL)
	return;

    fprintf(file, header_comment);
    fprintf(file, depth_comment,  img->depth);
    fprintf(file, width_comment,  img->width);
    fprintf(file, height_comment, img->height);
    fprintf(file, cmapsize_comment, img->cmapsize);

    if (img->depth <= 8) {
	fprintf(file, "rgb %s_cmap [] = {\n", name);
	for (i=0; i<img->cmapsize; i++)
	    fprintf(file, "\t0x%-8.8lXUL,\n", img->cmap[i]);
	fprintf(file, "};\n");
    }

    pixel32 = (rgb *) img->pixels;
    pixel8  = img->pixels;
    size    = (long) img->width * img->height;
    width   = img->width;

    if (img->depth <= 8) {
	fprintf(file, "byte %s_pixels [] = {", name);
	if (width > 12) width = 12;
	for (i=0; i<size; i++) {
	    if ((i%width) == 0)
		fprintf(file, "\n  ");
	    fprintf(file, "0x%-2.2X, ", pixel8[i]);
	}
	fprintf(file, "\n};\n");
    }
    else {
	fprintf(file, "rgb %s_pixels [] = {", name);
	if (width > 5) width = 5;
	for (i=0; i<size; i++) {
	    if ((i%width) == 0)
		fprintf(file, "\n  ");
	    fprintf(file, "0x%-8.8lXUL, ", pixel32[i]);
	}
	fprintf(file, "\n};\n");
    }

    fprintf(file, "imagedata %s_imagedata = {\n", name);
    fprintf(file, "\t%d,\t/* depth */\n",  img->depth);
    fprintf(file, "\t%d,\t/* width */\n",  img->width);
    fprintf(file, "\t%d,\t/* height */\n", img->height);
    fprintf(file, "\t%d,\t/* cmapsize */\n", img->cmapsize);
    if (img->depth <= 8) {
	fprintf(file, "\t%s_cmap,\n", name);
	fprintf(file, "\t%s_pixels\n", name);
    }
    else {
	fprintf(file, "\t(rgb *) 0\n");
	fprintf(file, "\t(byte *) %s_pixels\n", name);
    }
    fprintf(file, "};\n");
    fprintf(file, "image %s_image = & %s_imagedata;\n",
	    name, name);
    fprintf(file, "\n");
}

static image load_header_image(const char *filename)
{
    FILE *file;
    image img;

    file = fopen(filename, "rt");
    img = load_header_image_file(file);
    fclose(file);
    return img;
}

static char * base_file_name(const char *filename)
{
    char *name = NULL;
    int i, start, end;

    end = strlen(filename);
    while (filename[end] != '.')
	end--;
    for (start=end; start > 0; start--) {
	if ((filename[start] == '\\')
	    || (filename[start] == '/')
	    || (filename[start] == ':')) {
	    start ++;
	    break;
	}
    }
    for (i=start; i < end; i++)
	append(name, tolower(filename[i]));
    return name;
}

static void save_header_image(image img, const char *filename)
{
    FILE *file;
    char *name;

    file = fopen(filename, "wt");
    name = base_file_name(filename);
    save_header_image_file(file, name, img);
    discard(name);
    fclose(file);
}

/*
 *  Top-level functions for loading and saving images:
 */
image loadimage(const char *filename)
{
    if (string_ends_with(filename, ".gif"))
	return load_gif(filename);
    else if (string_ends_with(filename, ".h"))
	return load_header_image(filename);
    else if (string_ends_with(filename, ".img"))
	return load_header_image(filename);
    else
	return NULL;
}

void saveimage(image img, const char *filename)
{
    if (string_ends_with(filename, ".gif"))
	save_gif(img, filename);
    else if (string_ends_with(filename, ".h"))
	save_header_image(img, filename);
    else if (string_ends_with(filename, ".img"))
	save_header_image(img, filename);
}
#endif

/*
 *  Changing an rgb's value:
 */

rgb darker(rgb pixel)
{
    int r, g, b;

    if (getalpha(pixel) > 0x7F)
	return Transparent;

    r = getred(pixel);
    g = getgreen(pixel);
    b = getblue(pixel);

    return rgb((r+1)*3/4,(g+1)*3/4,(b+1)*3/4);
}

rgb brighter(rgb pixel)
{
    int r, g, b;

    if (getalpha(pixel) > 0x7F)
	return Transparent;

    r = getred(pixel);
    g = getgreen(pixel);
    b = getblue(pixel);

    r = (r) * 4 / 3; if (r > 255) r = 255;
    g = (g) * 4 / 3; if (g > 255) g = 255;
    b = (b) * 4 / 3; if (b > 255) b = 255;
    return rgb(r,g,b);
}

static rgb monochrome(rgb pixel)
{
    int min, max, g, b;

    if (getalpha(pixel) > 0x7F)
	return Transparent;

    max = min = getred(pixel);
    g = getgreen(pixel);
    if      (g < min) min = g;
    else if (g > max) max = g;
    b = getblue(pixel);
    if      (b < min) min = b;
    else if (b > max) max = b;

    if (min > 0xE0)	pixel = White;
    else if (max < 0x10)	pixel = Black;
    else if (max < 0x60)	pixel = Black;
    else if (max < 0xD0)	pixel = Black;
    else			pixel = White;

    return pixel;
}

static rgb greyscale(rgb pixel)
{
    int min, max, g, b;

    if (getalpha(pixel) > 0x7F)
	return Transparent;

    max = min = getred(pixel);
    g = getgreen(pixel);
    if      (g < min) min = g;
    else if (g > max) max = g;
    b = getblue(pixel);
    if      (b < min) min = b;
    else if (b > max) max = b;

    if (min > 0xE0)	pixel = White;
    else if (max < 0x10)	pixel = Black;
    else if (max < 0x60)	pixel = DarkGrey;
    else if (max < 0xD0)	pixel = Grey;
    else			pixel = LightGrey;

    return pixel;
}

/*
 *  Determine pixel values from an image:
 */

PROTECTED
rgb get_image_pixel(image img, int x, int y)
{
    int value;
    rgb pixel;

    if ((x < 0) || (x >= img->width))	return Transparent;
    if ((y < 0) || (y >= img->height))	return Transparent;

    if (img->depth <= 8) {
	value = img->pixels[y*img->width + x];
	pixel = img->cmap[value];
    } else {
	pixel = ((rgb *)(img->pixels))[y*img->width + x];
    }

    if (getalpha(pixel) > 0x7F) return Transparent;
    return (pixel & White);
}

PROTECTED
rgb get_monochrome_pixel(image img, int x, int y)
{
    return monochrome(get_image_pixel(img, x, y));
}

PROTECTED
rgb get_grey_pixel(image img, int x, int y)
{
    return greyscale(get_image_pixel(img, x, y));
}

/*
 *  Return an image scaled to a new width and/or height.
 *  The source rectangle sr can be used to crop the source image.
 *  The returned image should be deleted using del() when
 *  it is no longer needed.
 */

static void scale_8_bit_image(image dest, image src, rect dr, rect sr)
{
    int value;
    long x, y;
    long dx, dy, sx, sy;
    long dw, dh, sw, sh;
    GAbyte * src_pixels = src->pixels;
    GAbyte * dest_pixels = dest->pixels;

    dw = dest->width;
    dh = dest->height;
    sw = src->width;
    sh = src->height;

    for (y=0; y < dr.height; y++)
	for (x=0; x < dr.width; x++) {
	    sy = sr.y + y * sr.height / dr.height;
	    sx = sr.x + x * sr.width / dr.width;
	    if ((sx >= 0) && (sx < sw) && (sy >= 0) && (sy < sh))
		value = src_pixels [sy * sw + sx];
	    else
		value = 0;
	    dy = dr.y + y;
	    dx = dr.x + x;
	    if ((dx >= 0) && (dx < dw) && (dy >= 0) && (dy < dh))
		dest_pixels [dy * dw + dx] = value;
	}
}

static void scale_32_bit_image(image dest, image src, rect dr, rect sr)
{
    rgb value;
    long x, y;
    long dx, dy, sx, sy;
    long dw, dh, sw, sh;
    rgb * src_pixels = (rgb *) src->pixels;
    rgb * dest_pixels = (rgb *) dest->pixels;

    dw = dest->width;
    dh = dest->height;
    sw = src->width;
    sh = src->height;

    for (y=0; y < dr.height; y++)
	for (x=0; x < dr.width; x++) {
	    sy = sr.y + y * sr.height / dr.height;
	    sx = sr.x + x * sr.width / dr.width;
	    if ((sx >= 0) && (sx < sw) && (sy >= 0) && (sy < sh))
		value = src_pixels [sy * sw + sx];
	    else
		value = 0;
	    dy = dr.y + y;
	    dx = dr.x + x;
	    if ((dx >= 0) && (dx < dw) && (dy >= 0) && (dy < dh))
		dest_pixels [dy * dw + dx] = value;
	}
}

image scaleimage(image src, rect dr, rect sr)
{
    image dest;

    if (! src)
	return NULL;

    dest = newimage(dr.width, dr.height, src->depth);
    if (! dest)
	return NULL;

    if (src->depth == 8) {
	setpalette(dest, src->cmapsize, src->cmap);
	scale_8_bit_image(dest, src, dr, sr);
    }
    else if (src->depth == 32) {
	scale_32_bit_image(dest, src, dr, sr);
    }
    else {
	del(dest);
	dest = NULL;
    }

    return dest;
}

/*
 *  Functions for drawing an image:
 */

static int get_mono_pixval(image src, image dest, int x, int y)
{
    int i;
    rgb pixel = get_monochrome_pixel(src, x, y);

    for (i=0; i < dest->cmapsize; i++)
	if (pixel == dest->cmap[i])
	    return i;
    return dest->cmapsize - 1;
}

static int get_grey_pixval(image src, image dest, int x, int y)
{
    int i;
    rgb pixel = get_grey_pixel(src, x, y);

    for (i=0; i < dest->cmapsize; i++)
	if (pixel == dest->cmap[i])
	    return i;
    return dest->cmapsize - 1;
}

void drawmonochrome(image src, rect dr, rect sr)
{
    image dest;
    int x, y;
    rgb cmap[3] = {Black, White, Transparent};

    if (! src)
	return;

    dest = newimage(src->width, src->height, 8);
    setpalette(dest, 3, cmap);

    for (y=0; y < dest->height; y++)
	for (x=0; x < dest->width; x++)
	    dest->pixels[y * dest->width + x]
		= get_mono_pixval(src, dest, x, y);
    drawimage(dest, dr, sr);
    del(dest);
}

void drawgreyscale(image src, rect dr, rect sr)
{
    image dest;
    int x, y;
    rgb cmap[6] = {Black, DarkGrey, Grey, LightGrey, White, Transparent};

    if (! src)
	return;

    dest = newimage(src->width, src->height, 8);
    setpalette(dest, 6, cmap);

    for (y=0; y < dest->height; y++)
	for (x=0; x < dest->width; x++)
	    dest->pixels[y * dest->width + x]
		= get_grey_pixval(src, dest, x, y);
    drawimage(dest, dr, sr);
    del(dest);
}

void drawdarker(image src, rect dr, rect sr)
{
    image dest = NULL;
    int i, x, y;
    rgb *newcmap = NULL, *oldcmap = NULL;
    rgb *pixels;

    if (! src)
	return;

    if (src->depth == 8) {
	newcmap = array(src->cmapsize, rgb);
	for (i=0; i < src->cmapsize; i++)
	    newcmap[i] = darker(src->cmap[i]);
	oldcmap = src->cmap;
	src->cmap = newcmap;
	dest = src;
    }
    else if (src->depth == 32) {
	dest = newimage(src->width, src->height, src->depth);
	if (dest) {
	    pixels = (rgb *) dest->pixels;
	    for (y=0; y < dest->height; y++)
		for (x=0; x < dest->width; x++)
		    pixels[y * dest->width + x]
			= darker(get_image_pixel(src, x, y));
	} else {
	    dest = src;
	}
    }
    drawimage(dest, dr, sr);
    if (dest != src)
	del(dest);
    if (src->cmap == newcmap)
	src->cmap = oldcmap;
    discard(newcmap);
}

void drawbrighter(image src, rect dr, rect sr)
{
    image dest = NULL;
    int i, x, y;
    rgb *newcmap = NULL, *oldcmap = NULL;
    rgb *pixels;

    if (! src)
	return;

    if (src->depth == 8) {
	newcmap = array(src->cmapsize, rgb);
	for (i=0; i < src->cmapsize; i++)
	    newcmap[i] = brighter(src->cmap[i]);
	oldcmap = src->cmap;
	src->cmap = newcmap;
	dest = src;
    }
    else if (src->depth == 32) {
	dest = newimage(src->width, src->height, src->depth);
	if (dest) {
	    pixels = (rgb *) dest->pixels;
	    for (y=0; y < dest->height; y++)
		for (x=0; x < dest->width; x++)
		    pixels[y * dest->width + x]
			= brighter(get_image_pixel(src,x,y));
	} else {
	    dest = src;
	}
    }
    drawimage(dest, dr, sr);
    if (dest != src)
	del(dest);
    if (src->cmap == newcmap)
	src->cmap = oldcmap;
    discard(newcmap);
}
