/*
 * 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, byte);
    }
    else {
	img->depth  = 32;
	img->pixels = (byte *) 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, byte 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:
 */
byte * 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;
    byte * 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 = (byte *) 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;
    byte * 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 = (byte *) 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;
    byte *pixel8;
    byte 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 = (byte *) 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;
    byte *	translate;
    rgb *	new_cmap;

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

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

    /* 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;
    byte *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;
    byte *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;
    byte * src_pixels = src->pixels;
    byte * 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);
}
