/*
 * rbcImage.h --
 *
 *      TODO: Description
 *
 * Copyright (c) 2009 Samuel Green, Nicholas Hudson, Stanton Sievers, Jarrod Stormo
 * All rights reserved.
 *
 * See "license.terms" for details.
 */

#include <X11/Xutil.h>
#ifndef WIN32
#include <X11/Xproto.h>
#endif

#ifndef _RBCIMAGE
#define _RBCIMAGE

#define DIV255(i) ((((i) + 1) + (((i) + 1) >> 8) ) >> 8)

#define GAMMA	(1.0)

#define ROTATE_0	0
#define ROTATE_90	1
#define ROTATE_180	2
#define ROTATE_270	3

/*
 *----------------------------------------------------------------------
 *
 * Pix32 --
 *
 *      A union representing either a pixel as a RGB triplet or a
 *	single word value.
 *
 *----------------------------------------------------------------------
 */
typedef union {
    unsigned int value;		/* Lookup table address */
    struct RGBA {
	unsigned char red;	/* Red intensity 0..255 */
	unsigned char green;	/* Green intensity 0.255 */
	unsigned char blue;	/* Blue intensity 0..255 */
	unsigned char alpha;	/* Alpha-channel for compositing. 0..255 */
    } rgba;
    unsigned char channel[4];
} Pix32;

#define Red	rgba.red
#define Blue	rgba.blue
#define Green	rgba.green
#define Alpha	rgba.alpha


typedef struct {
    XColor exact, best;
    double error;
    unsigned int freq;
    int allocated;
    int index;
} ColorInfo;


/*
 *----------------------------------------------------------------------
 *
 * ColorTable --
 *
 *	For colormap-ed visuals, this structure contains color lookup
 *	information needed to translate RGB triplets to pixel indices.
 *
 *	This structure isn't needed for TrueColor or Monochrome visuals.
 *
 *	DirectColor:
 *		Pixel values for each color channel
 *	StaticColor, PsuedoColor, StaticGray, and GrayScale:
 *		Red represents the 8-bit color. Green and Blue pixel
 *		values are unused.
 *
 *----------------------------------------------------------------------
 */
typedef struct ColorTableStruct {
    double outputGamma;		/* Gamma correction value */
    Display *display;		/* Display of colortable. Used to free
				 * colors allocated. */
    XVisualInfo visualInfo;	/* Visual information for window displaying
				 * the image. */
    Colormap colorMap;		/* Colormap used.  This may be the default
				 * colormap, or an allocated private map. */
    int flags;
    unsigned int red[256], green[256], blue[256];

    /* Array of allocated pixels in colormap */
    ColorInfo colorInfo[256];
    ColorInfo *sortedColors[256];

    int nUsedColors, nFreeColors;
    int nPixels;		/* Number of colors in the quantized image */
    unsigned long int pixelValues[256];

    unsigned int *lut;		/* Color lookup table. Used to collect
				 * frequencies of colors and later
				 * colormap indices */
} *ColorTable;

#define PRIVATE_COLORMAP	1
#define RGBIndex(r,g,b) (((r)<<10) + ((r)<<6) + (r) + ((g) << 5) + (g) + (b))

/*
 *----------------------------------------------------------------------
 *
 * Rbc_ColorImage --
 *
 *      The structure below represents a color image.  Each pixel
 *	occupies a 32-bit word of memory: one byte for each of the
 *	red, green, and blue color intensities, and another for
 *	alpha-channel image compositing (e.g. transparency).
 *
 *----------------------------------------------------------------------
 */
typedef struct ColorImage {
    int width, height;		/* Dimensions of the image */
    Pix32 *bits;		/* Array of pixels representing the image. */
} *Rbc_ColorImage;

/*
 * Rbc_ColorImage is supposed to be an opaque type.
 * Use the macros below to access its members.
 */
#define Rbc_ColorImageHeight(c)	((c)->height)
#define Rbc_ColorImageWidth(c)	((c)->width)
#define Rbc_ColorImageBits(c)	((c)->bits)
#define Rbc_ColorImagePixel(c, x, y) ((c)->bits + ((c)->width * (y)) + (x))

/*
 *----------------------------------------------------------------------
 *
 * ResampleFilterProc --
 *
 *      A function implementing a 1-D filter.
 *
 *----------------------------------------------------------------------
 */
typedef double (ResampleFilterProc) (double value);

/*
 *----------------------------------------------------------------------
 *
 * ResampleFilter --
 *
 *      Contains information about a 1-D filter (its support and
 *	the procedure implementing the filter).
 *
 *----------------------------------------------------------------------
 */
typedef struct {
    char *name;			/* Name of the filter */
    ResampleFilterProc *proc;	/* 1-D filter procedure. */
    double support;		/* Width of 1-D filter */
} ResampleFilter;

extern ResampleFilter *rbcBoxFilterPtr; /* The ubiquitous box filter */

/*
 *----------------------------------------------------------------------
 *
 * Filter2D --
 *
 *      Defines a convolution mask for a 2-D filter.  Used to smooth or
 *	enhance images.
 *
 *----------------------------------------------------------------------
 */
typedef struct {
    double support;		/* Radius of filter */
    double sum, scale;		/* Sum of kernel */
    double *kernel;		/* Array of values (malloc-ed) representing
				 * the discrete 2-D filter. */
} Filter2D;

/* Prototypes of image routines */

void Rbc_ColorImageToGreyscale (Rbc_ColorImage image);

void Rbc_ColorImageToPhoto (Tcl_Interp *interp, Rbc_ColorImage image,
					Tk_PhotoHandle photo);

Pixmap Rbc_ColorImageToPixmap (Tcl_Interp *interp,
	Tk_Window tkwin, Rbc_ColorImage image, ColorTable *colorTablePtr);

Rbc_ColorImage Rbc_ConvolveColorImage (
	    Rbc_ColorImage srcImage, Filter2D *filter);

Rbc_ColorImage Rbc_CreateColorImage (int width,int height);

Rbc_ColorImage Rbc_DrawableToColorImage (Tk_Window tkwin,
	Drawable drawable, int x, int y, int width, int height,
	double inputGamma);

int Rbc_GetResampleFilterFromObj (Tcl_Interp *interp, Tcl_Obj *filterObj,
	ResampleFilter **filterPtrPtr);

void Rbc_FreeColorImage (Rbc_ColorImage image);

#if HAVE_JPEG
Rbc_ColorImage Rbc_JPEGToColorImage (Tcl_Interp *interp,
	char *fileName);
#endif

Rbc_ColorImage Rbc_PhotoToColorImage (
	    Tk_PhotoHandle photo);

Rbc_ColorImage Rbc_PhotoRegionToColorImage (
	    Tk_PhotoHandle photo, int x, int y, int width, int height);

int Rbc_QuantizeColorImage (Rbc_ColorImage src,
					Rbc_ColorImage dest, int nColors);

Rbc_ColorImage Rbc_ResampleColorImage (Rbc_ColorImage image,
	int destWidth, int destHeight, ResampleFilter *horzFilterPtr,
	ResampleFilter *vertFilterPtr);

void Rbc_ResamplePhoto (Tcl_Interp *interp, Tk_PhotoHandle srcPhoto,
				    int x, int y, int width, int height, Tk_PhotoHandle destPhoto,
				    ResampleFilter *horzFilterPtr, ResampleFilter *vertFilterPtr);

Rbc_ColorImage Rbc_ResizeColorImage (Rbc_ColorImage src,
	int x, int y, int width, int height, int destWidth, int destHeight);

Rbc_ColorImage Rbc_ResizeColorSubimage (Rbc_ColorImage src,
	int x, int y, int width, int height, int destWidth, int destHeight);

Rbc_ColorImage Rbc_RotateColorImage (Rbc_ColorImage image,
	double theta);

void Rbc_ResizePhoto (Tcl_Interp *interp, Tk_PhotoHandle srcPhoto, int x, int y,
				  int width, int height, Tk_PhotoHandle destPhoto);

int Rbc_SnapPhoto (Tcl_Interp *interp, Tk_Window tkwin,
			       Drawable drawable, int x, int y, int width, int height, int destWidth,
			       int destHeight, char *photoName, double inputGamma);

Region2D *Rbc_SetRegion (int x, int y, int width,
				     int height, Region2D *regionPtr);

ColorTable Rbc_CreateColorTable (Tk_Window tkwin);

ColorTable Rbc_DirectColorTable (Tcl_Interp *interp,
	Tk_Window tkwin, Rbc_ColorImage image);

ColorTable Rbc_PseudoColorTable (Tcl_Interp *interp,
	Tk_Window tkwin, Rbc_ColorImage image);

void Rbc_FreeColorTable (ColorTable colorTable);

/* Missing routines from the Tk photo C API */

int Tk_ImageIsDeleted (Tk_Image tkImage);
Tk_ImageMaster Tk_ImageGetMaster (Tk_Image tkImage);
Tk_ImageType *Tk_ImageGetType (Tk_Image tkImage);
Pixmap Tk_ImageGetPhotoPixmap (Tk_Image photoImage);
GC Tk_ImageGetPhotoGC (Tk_Image photoImage);

const char *Rbc_NameOfImage (Tk_Image tkImage);
Tk_Image Rbc_CreateTemporaryImage (Tcl_Interp *interp,
	Tk_Window tkwin, ClientData clientData);
int Rbc_DestroyTemporaryImage (Tcl_Interp *interp,
	Tk_Image tkImage);

GC Rbc_GetBitmapGC (Tk_Window tkwin);
Pixmap Rbc_PhotoImageMask (Tk_Window tkwin,
				       Tk_PhotoImageBlock src);

Pixmap Rbc_RotateBitmap (Tk_Window tkwin, Pixmap bitmap,
				     int width, int height, double theta, int *widthPtr, int *heightPtr);

Pixmap Rbc_ScaleBitmap (Tk_Window tkwin, Pixmap srcBitmap,
				    int srcWidth, int srcHeight, int scaledWidth, int scaledHeight);

Pixmap Rbc_ScaleRotateBitmapRegion (Tk_Window tkwin,
	Pixmap srcBitmap, unsigned int srcWidth, unsigned int srcHeight,
	int regionX, int regionY, unsigned int regionWidth,
	unsigned int regionHeight, unsigned int virtWidth,
	unsigned int virtHeight, double theta);

#endif /* _RBCIMAGE */
