Fredrik Lundh is sharing code with you
Bitbucket is a code hosting site. Unlimited public and private repositories. Free for small teams.
Don't show this againpil-2009-raclette / Tk / pilbitmap.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | ====================================================================
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
|