mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-26 09:56:17 +03:00
150 lines
4.5 KiB
Plaintext
150 lines
4.5 KiB
Plaintext
|
====================================================================
|
||
|
The PIL Bitmap Booster Patch
|
||
|
====================================================================
|
||
|
|
||
|
The pilbitmap booster patch greatly improves performance of the
|
||
|
ImageTk.BitmapImage constructor. Unfortunately, the design of Tk
|
||
|
doesn't allow us to do this from the tkImaging interface module, so
|
||
|
you have to patch the Tk sources.
|
||
|
|
||
|
Once installed, the ImageTk module will automatically detect this
|
||
|
patch.
|
||
|
|
||
|
(Note: this patch has been tested with Tk 8.0 on Win32 only, but it
|
||
|
should work just fine on other platforms as well).
|
||
|
|
||
|
1. To the beginning of TkGetBitmapData (in generic/tkImgBmap.c), add
|
||
|
the following stuff:
|
||
|
|
||
|
------------------------------------------------------------------------
|
||
|
int width, height, numBytes, hotX, hotY;
|
||
|
char *p, *end, *expandedFileName;
|
||
|
ParseInfo pi;
|
||
|
char *data = NULL;
|
||
|
Tcl_DString buffer;
|
||
|
|
||
|
/* ==================================================================== */
|
||
|
/* The pilbitmap booster patch -- patch section */
|
||
|
/* ==================================================================== */
|
||
|
|
||
|
char *PILGetBitmapData();
|
||
|
|
||
|
if (string) {
|
||
|
/* Is this a PIL bitmap reference? */
|
||
|
data = PILGetBitmapData(string, widthPtr, heightPtr, hotXPtr, hotYPtr);
|
||
|
if (data)
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
/* ==================================================================== */
|
||
|
|
||
|
pi.string = string;
|
||
|
if (string == NULL) {
|
||
|
if (Tcl_IsSafe(interp)) {
|
||
|
------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
2. Append the following to the same file (you may wish to include
|
||
|
Imaging.h instead of copying the struct declaration...)
|
||
|
|
||
|
------------------------------------------------------------------------
|
||
|
|
||
|
/* ==================================================================== */
|
||
|
/* The pilbitmap booster patch -- code section */
|
||
|
/* ==================================================================== */
|
||
|
|
||
|
/* Imaging declaration boldly copied from Imaging.h (!) */
|
||
|
|
||
|
typedef struct ImagingInstance *Imaging; /* a.k.a. ImagingImage :-) */
|
||
|
|
||
|
typedef unsigned char UINT8;
|
||
|
typedef int INT32;
|
||
|
|
||
|
struct ImagingInstance {
|
||
|
|
||
|
/* Format */
|
||
|
char mode[4+1]; /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK") */
|
||
|
int type; /* Always 0 in this version */
|
||
|
int depth; /* Always 8 in this version */
|
||
|
int bands; /* Number of bands (1, 3, or 4) */
|
||
|
int xsize; /* Image dimension. */
|
||
|
int ysize;
|
||
|
|
||
|
/* Colour palette (for "P" images only) */
|
||
|
void* palette;
|
||
|
|
||
|
/* Data pointers */
|
||
|
UINT8 **image8; /* Set for 8-bit image (pixelsize=1). */
|
||
|
INT32 **image32; /* Set for 32-bit image (pixelsize=4). */
|
||
|
|
||
|
/* Internals */
|
||
|
char **image; /* Actual raster data. */
|
||
|
char *block; /* Set if data is allocated in a single block. */
|
||
|
|
||
|
int pixelsize; /* Size of a pixel, in bytes (1 or 4) */
|
||
|
int linesize; /* Size of a line, in bytes (xsize * pixelsize) */
|
||
|
|
||
|
/* Virtual methods */
|
||
|
void (*im_delete)(Imaging *);
|
||
|
|
||
|
};
|
||
|
|
||
|
/* The pilbitmap booster patch allows you to pass PIL images to the
|
||
|
Tk bitmap decoder. Passing images this way is much more efficient
|
||
|
than using the "tobitmap" method. */
|
||
|
|
||
|
char *
|
||
|
PILGetBitmapData(string, widthPtr, heightPtr, hotXPtr, hotYPtr)
|
||
|
char *string;
|
||
|
int *widthPtr, *heightPtr;
|
||
|
int *hotXPtr, *hotYPtr;
|
||
|
{
|
||
|
char* data;
|
||
|
char* p;
|
||
|
int y;
|
||
|
Imaging im;
|
||
|
|
||
|
if (strncmp(string, "PIL:", 4) != 0)
|
||
|
return NULL;
|
||
|
|
||
|
im = (Imaging) atol(string + 4);
|
||
|
|
||
|
if (strcmp(im->mode, "1") != 0 && strcmp(im->mode, "L") != 0)
|
||
|
return NULL;
|
||
|
|
||
|
data = p = (char *) ckalloc((unsigned) ((im->xsize+7)/8) * im->ysize);
|
||
|
|
||
|
for (y = 0; y < im->ysize; y++) {
|
||
|
char* in = im->image8[y];
|
||
|
int i, m, b;
|
||
|
b = 0; m = 1;
|
||
|
for (i = 0; i < im->xsize; i++) {
|
||
|
if (in[i] != 0)
|
||
|
b |= m;
|
||
|
m <<= 1;
|
||
|
if (m == 256){
|
||
|
*p++ = b;
|
||
|
b = 0; m = 1;
|
||
|
}
|
||
|
}
|
||
|
if (m != 1)
|
||
|
*p++ = b;
|
||
|
}
|
||
|
|
||
|
*widthPtr = im->xsize;
|
||
|
*heightPtr = im->ysize;
|
||
|
*hotXPtr = -1;
|
||
|
*hotYPtr = -1;
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
/* ==================================================================== */
|
||
|
|
||
|
------------------------------------------------------------------------
|
||
|
|
||
|
3. Recompile Tk and relink the _tkinter module (where necessary).
|
||
|
|
||
|
====================================================================
|
||
|
Last updated: 97-05-17/fl
|