jpayne@69: /* jpayne@69: * tkImgPhoto.h -- jpayne@69: * jpayne@69: * Declarations for images of type "photo" for Tk. jpayne@69: * jpayne@69: * Copyright (c) 1994 The Australian National University. jpayne@69: * Copyright (c) 1994-1997 Sun Microsystems, Inc. jpayne@69: * Copyright (c) 2002-2008 Donal K. Fellows jpayne@69: * Copyright (c) 2003 ActiveState Corporation. jpayne@69: * jpayne@69: * See the file "license.terms" for information on usage and redistribution of jpayne@69: * this file, and for a DISCLAIMER OF ALL WARRANTIES. jpayne@69: * jpayne@69: * Author: Paul Mackerras (paulus@cs.anu.edu.au), jpayne@69: * Department of Computer Science, jpayne@69: * Australian National University. jpayne@69: */ jpayne@69: jpayne@69: #include "tkInt.h" jpayne@69: #ifdef _WIN32 jpayne@69: #include "tkWinInt.h" jpayne@69: #elif defined(__CYGWIN__) jpayne@69: #include "tkUnixInt.h" jpayne@69: #endif jpayne@69: jpayne@69: /* jpayne@69: * Forward declarations of the structures we define. jpayne@69: */ jpayne@69: jpayne@69: #define PhotoModel PhotoMaster jpayne@69: typedef struct ColorTableId ColorTableId; jpayne@69: typedef struct ColorTable ColorTable; jpayne@69: typedef struct PhotoInstance PhotoInstance; jpayne@69: typedef struct PhotoMaster PhotoMaster; jpayne@69: jpayne@69: /* jpayne@69: * A signed 8-bit integral type. If chars are unsigned and the compiler isn't jpayne@69: * an ANSI one, then we have to use short instead (which wastes space) to get jpayne@69: * signed behavior. jpayne@69: */ jpayne@69: jpayne@69: #if defined(__STDC__) || defined(_AIX) jpayne@69: typedef signed char schar; jpayne@69: #else jpayne@69: # ifndef __CHAR_UNSIGNED__ jpayne@69: typedef char schar; jpayne@69: # else jpayne@69: typedef short schar; jpayne@69: # endif jpayne@69: #endif jpayne@69: jpayne@69: /* jpayne@69: * An unsigned 32-bit integral type, used for pixel values. We use int rather jpayne@69: * than long here to accommodate those systems where longs are 64 bits. jpayne@69: */ jpayne@69: jpayne@69: typedef unsigned int pixel; jpayne@69: jpayne@69: /* jpayne@69: * The maximum number of pixels to transmit to the server in a single jpayne@69: * XPutImage call. jpayne@69: */ jpayne@69: jpayne@69: #define MAX_PIXELS 65536 jpayne@69: jpayne@69: /* jpayne@69: * The set of colors required to display a photo image in a window depends on: jpayne@69: * - the visual used by the window jpayne@69: * - the palette, which specifies how many levels of each primary color to jpayne@69: * use, and jpayne@69: * - the gamma value for the image. jpayne@69: * jpayne@69: * Pixel values allocated for specific colors are valid only for the colormap jpayne@69: * in which they were allocated. Sets of pixel values allocated for displaying jpayne@69: * photos are re-used in other windows if possible, that is, if the display, jpayne@69: * colormap, palette and gamma values match. A hash table is used to locate jpayne@69: * these sets of pixel values, using the following data structure as key: jpayne@69: */ jpayne@69: jpayne@69: struct ColorTableId { jpayne@69: Display *display; /* Qualifies the colormap resource ID. */ jpayne@69: Colormap colormap; /* Colormap that the windows are using. */ jpayne@69: double gamma; /* Gamma exponent value for images. */ jpayne@69: Tk_Uid palette; /* Specifies how many shades of each primary jpayne@69: * we want to allocate. */ jpayne@69: }; jpayne@69: jpayne@69: /* jpayne@69: * For a particular (display, colormap, palette, gamma) combination, a data jpayne@69: * structure of the following type is used to store the allocated pixel values jpayne@69: * and other information: jpayne@69: */ jpayne@69: jpayne@69: struct ColorTable { jpayne@69: ColorTableId id; /* Information used in selecting this color jpayne@69: * table. */ jpayne@69: int flags; /* See below. */ jpayne@69: int refCount; /* Number of instances using this map. */ jpayne@69: int liveRefCount; /* Number of instances which are actually in jpayne@69: * use, using this map. */ jpayne@69: int numColors; /* Number of colors allocated for this map. */ jpayne@69: jpayne@69: XVisualInfo visualInfo; /* Information about the visual for windows jpayne@69: * using this color table. */ jpayne@69: jpayne@69: pixel redValues[256]; /* Maps 8-bit values of red intensity to a jpayne@69: * pixel value or index in pixelMap. */ jpayne@69: pixel greenValues[256]; /* Ditto for green intensity. */ jpayne@69: pixel blueValues[256]; /* Ditto for blue intensity. */ jpayne@69: unsigned long *pixelMap; /* Actual pixel values allocated. */ jpayne@69: jpayne@69: unsigned char colorQuant[3][256]; jpayne@69: /* Maps 8-bit intensities to quantized jpayne@69: * intensities. The first index is 0 for red, jpayne@69: * 1 for green, 2 for blue. */ jpayne@69: }; jpayne@69: jpayne@69: /* jpayne@69: * Bit definitions for the flags field of a ColorTable. jpayne@69: * BLACK_AND_WHITE: 1 means only black and white colors are jpayne@69: * available. jpayne@69: * COLOR_WINDOW: 1 means a full 3-D color cube has been jpayne@69: * allocated. jpayne@69: * DISPOSE_PENDING: 1 means a call to DisposeColorTable has been jpayne@69: * scheduled as an idle handler, but it hasn't jpayne@69: * been invoked yet. jpayne@69: * MAP_COLORS: 1 means pixel values should be mapped through jpayne@69: * pixelMap. jpayne@69: */ jpayne@69: jpayne@69: #ifdef COLOR_WINDOW jpayne@69: #undef COLOR_WINDOW jpayne@69: #endif jpayne@69: jpayne@69: #define BLACK_AND_WHITE 1 jpayne@69: #define COLOR_WINDOW 2 jpayne@69: #define DISPOSE_PENDING 4 jpayne@69: #define MAP_COLORS 8 jpayne@69: jpayne@69: /* jpayne@69: * Definition of the data associated with each photo image model. jpayne@69: */ jpayne@69: jpayne@69: struct PhotoMaster { jpayne@69: Tk_ImageMaster tkMaster; /* Tk's token for image model. NULL means the jpayne@69: * image is being deleted. */ jpayne@69: Tcl_Interp *interp; /* Interpreter associated with the application jpayne@69: * using this image. */ jpayne@69: Tcl_Command imageCmd; /* Token for image command (used to delete it jpayne@69: * when the image goes away). NULL means the jpayne@69: * image command has already been deleted. */ jpayne@69: int flags; /* Sundry flags, defined below. */ jpayne@69: int width, height; /* Dimensions of image. */ jpayne@69: int userWidth, userHeight; /* User-declared image dimensions. */ jpayne@69: Tk_Uid palette; /* User-specified default palette for jpayne@69: * instances of this image. */ jpayne@69: double gamma; /* Display gamma value to correct for. */ jpayne@69: char *fileString; /* Name of file to read into image. */ jpayne@69: Tcl_Obj *dataString; /* Object to use as contents of image. */ jpayne@69: Tcl_Obj *format; /* User-specified format of data in image file jpayne@69: * or string value. */ jpayne@69: unsigned char *pix32; /* Local storage for 32-bit image. */ jpayne@69: int ditherX, ditherY; /* Location of first incorrectly dithered jpayne@69: * pixel in image. */ jpayne@69: TkRegion validRegion; /* Tk region indicating which parts of the jpayne@69: * image have valid image data. */ jpayne@69: PhotoInstance *instancePtr; /* First in the list of instances associated jpayne@69: * with this model. */ jpayne@69: }; jpayne@69: jpayne@69: /* jpayne@69: * Bit definitions for the flags field of a PhotoMaster. jpayne@69: * COLOR_IMAGE: 1 means that the image has different color jpayne@69: * components. jpayne@69: * IMAGE_CHANGED: 1 means that the instances of this image need jpayne@69: * to be redithered. jpayne@69: * COMPLEX_ALPHA: 1 means that the instances of this image have jpayne@69: * alpha values that aren't 0 or 255, and so need jpayne@69: * the copy-merge-replace renderer . jpayne@69: */ jpayne@69: jpayne@69: #define COLOR_IMAGE 1 jpayne@69: #define IMAGE_CHANGED 2 jpayne@69: #define COMPLEX_ALPHA 4 jpayne@69: jpayne@69: /* jpayne@69: * Flag to OR with the compositing rule to indicate that the source, despite jpayne@69: * having an alpha channel, has simple alpha. jpayne@69: */ jpayne@69: jpayne@69: #define SOURCE_IS_SIMPLE_ALPHA_PHOTO 0x10000000 jpayne@69: jpayne@69: /* jpayne@69: * The following data structure represents all of the instances of a photo jpayne@69: * image in windows on a given screen that are using the same colormap. jpayne@69: */ jpayne@69: jpayne@69: struct PhotoInstance { jpayne@69: PhotoMaster *masterPtr; /* Pointer to model for image. */ jpayne@69: Display *display; /* Display for windows using this instance. */ jpayne@69: Colormap colormap; /* The image may only be used in windows with jpayne@69: * this particular colormap. */ jpayne@69: PhotoInstance *nextPtr; /* Pointer to the next instance in the list of jpayne@69: * instances associated with this model. */ jpayne@69: int refCount; /* Number of instances using this structure. */ jpayne@69: Tk_Uid palette; /* Palette for these particular instances. */ jpayne@69: double gamma; /* Gamma value for these instances. */ jpayne@69: Tk_Uid defaultPalette; /* Default palette to use if a palette is not jpayne@69: * specified for the model. */ jpayne@69: ColorTable *colorTablePtr; /* Pointer to information about colors jpayne@69: * allocated for image display in windows like jpayne@69: * this one. */ jpayne@69: Pixmap pixels; /* X pixmap containing dithered image. */ jpayne@69: int width, height; /* Dimensions of the pixmap. */ jpayne@69: schar *error; /* Error image, used in dithering. */ jpayne@69: XImage *imagePtr; /* Image structure for converted pixels. */ jpayne@69: XVisualInfo visualInfo; /* Information about the visual that these jpayne@69: * windows are using. */ jpayne@69: GC gc; /* Graphics context for writing images to the jpayne@69: * pixmap. */ jpayne@69: }; jpayne@69: jpayne@69: /* jpayne@69: * Implementation of the Porter-Duff Source-Over compositing rule. jpayne@69: */ jpayne@69: jpayne@69: #define PD_SRC_OVER(srcColor, srcAlpha, dstColor, dstAlpha) \ jpayne@69: (srcColor*srcAlpha/255) + dstAlpha*(255-srcAlpha)/255*dstColor/255 jpayne@69: #define PD_SRC_OVER_ALPHA(srcAlpha, dstAlpha) \ jpayne@69: (srcAlpha + (255-srcAlpha)*dstAlpha/255) jpayne@69: jpayne@69: #undef MIN jpayne@69: #define MIN(a, b) ((a) < (b)? (a): (b)) jpayne@69: #undef MAX jpayne@69: #define MAX(a, b) ((a) > (b)? (a): (b)) jpayne@69: jpayne@69: /* jpayne@69: * Declarations of functions shared between the different parts of the jpayne@69: * photo image implementation. jpayne@69: */ jpayne@69: jpayne@69: MODULE_SCOPE void TkImgPhotoConfigureInstance( jpayne@69: PhotoInstance *instancePtr); jpayne@69: MODULE_SCOPE void TkImgDisposeInstance(ClientData clientData); jpayne@69: MODULE_SCOPE void TkImgPhotoInstanceSetSize(PhotoInstance *instancePtr); jpayne@69: MODULE_SCOPE ClientData TkImgPhotoGet(Tk_Window tkwin, ClientData clientData); jpayne@69: MODULE_SCOPE void TkImgDitherInstance(PhotoInstance *instancePtr, int x, jpayne@69: int y, int width, int height); jpayne@69: MODULE_SCOPE void TkImgPhotoDisplay(ClientData clientData, jpayne@69: Display *display, Drawable drawable, jpayne@69: int imageX, int imageY, int width, int height, jpayne@69: int drawableX, int drawableY); jpayne@69: MODULE_SCOPE void TkImgPhotoFree(ClientData clientData, jpayne@69: Display *display); jpayne@69: MODULE_SCOPE void TkImgResetDither(PhotoInstance *instancePtr); jpayne@69: jpayne@69: /* jpayne@69: * Local Variables: jpayne@69: * mode: c jpayne@69: * c-basic-offset: 4 jpayne@69: * fill-column: 78 jpayne@69: * End: jpayne@69: */