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
- commit
- 454b4d2672f3
- parent
- 64f9636f4d92
- branch
- default
- tags
- pil-117-20090317, pil-117a1-20090317
Don't try to open files twice if plugins are already loaded.
1 |
770a9717f387
|
==================================================================== |
2 |
770a9717f387
|
The PIL Bitmap Booster Patch |
3 |
770a9717f387
|
==================================================================== |
4 |
770a9717f387
|
|
5 |
770a9717f387
|
The pilbitmap booster patch greatly improves performance of the |
6 |
770a9717f387
|
ImageTk.BitmapImage constructor. Unfortunately, the design of Tk |
7 |
770a9717f387
|
doesn't allow us to do this from the tkImaging interface module, so |
8 |
770a9717f387
|
you have to patch the Tk sources. |
9 |
770a9717f387
|
|
10 |
770a9717f387
|
Once installed, the ImageTk module will automatically detect this |
11 |
770a9717f387
|
patch. |
12 |
770a9717f387
|
|
13 |
770a9717f387
|
(Note: this patch has been tested with Tk 8.0 on Win32 only, but it |
14 |
770a9717f387
|
should work just fine on other platforms as well). |
15 |
770a9717f387
|
|
16 |
770a9717f387
|
1. To the beginning of TkGetBitmapData (in generic/tkImgBmap.c), add |
17 |
770a9717f387
|
the following stuff: |
18 |
770a9717f387
|
|
19 |
770a9717f387
|
------------------------------------------------------------------------ |
20 |
770a9717f387
|
int width, height, numBytes, hotX, hotY; |
21 |
770a9717f387
|
char *p, *end, *expandedFileName; |
22 |
770a9717f387
|
ParseInfo pi; |
23 |
770a9717f387
|
char *data = NULL; |
24 |
770a9717f387
|
Tcl_DString buffer; |
25 |
770a9717f387
|
|
26 |
770a9717f387
|
/* ==================================================================== */ |
27 |
770a9717f387
|
/* The pilbitmap booster patch -- patch section */ |
28 |
770a9717f387
|
/* ==================================================================== */ |
29 |
770a9717f387
|
|
30 |
770a9717f387
|
char *PILGetBitmapData(); |
31 |
770a9717f387
|
|
32 |
770a9717f387
|
if (string) { |
33 |
770a9717f387
|
/* Is this a PIL bitmap reference? */ |
34 |
770a9717f387
|
data = PILGetBitmapData(string, widthPtr, heightPtr, hotXPtr, hotYPtr); |
35 |
770a9717f387
|
if (data) |
36 |
770a9717f387
|
return data; |
37 |
770a9717f387
|
} |
38 |
770a9717f387
|
|
39 |
770a9717f387
|
/* ==================================================================== */ |
40 |
770a9717f387
|
|
41 |
770a9717f387
|
pi.string = string; |
42 |
770a9717f387
|
if (string == NULL) { |
43 |
770a9717f387
|
if (Tcl_IsSafe(interp)) { |
44 |
770a9717f387
|
------------------------------------------------------------------------ |
45 |
770a9717f387
|
|
46 |
770a9717f387
|
|
47 |
770a9717f387
|
2. Append the following to the same file (you may wish to include |
48 |
770a9717f387
|
Imaging.h instead of copying the struct declaration...) |
49 |
770a9717f387
|
|
50 |
770a9717f387
|
------------------------------------------------------------------------ |
51 |
770a9717f387
|
|
52 |
770a9717f387
|
/* ==================================================================== */ |
53 |
770a9717f387
|
/* The pilbitmap booster patch -- code section */ |
54 |
770a9717f387
|
/* ==================================================================== */ |
55 |
770a9717f387
|
|
56 |
770a9717f387
|
/* Imaging declaration boldly copied from Imaging.h (!) */ |
57 |
770a9717f387
|
|
58 |
770a9717f387
|
typedef struct ImagingInstance *Imaging; /* a.k.a. ImagingImage :-) */ |
59 |
770a9717f387
|
|
60 |
770a9717f387
|
typedef unsigned char UINT8; |
61 |
770a9717f387
|
typedef int INT32; |
62 |
770a9717f387
|
|
63 |
770a9717f387
|
struct ImagingInstance { |
64 |
770a9717f387
|
|
65 |
770a9717f387
|
/* Format */ |
66 |
770a9717f387
|
char mode[4+1]; /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK") */ |
67 |
770a9717f387
|
int type; /* Always 0 in this version */ |
68 |
770a9717f387
|
int depth; /* Always 8 in this version */ |
69 |
770a9717f387
|
int bands; /* Number of bands (1, 3, or 4) */ |
70 |
770a9717f387
|
int xsize; /* Image dimension. */ |
71 |
770a9717f387
|
int ysize; |
72 |
770a9717f387
|
|
73 |
770a9717f387
|
/* Colour palette (for "P" images only) */ |
74 |
770a9717f387
|
void* palette; |
75 |
770a9717f387
|
|
76 |
770a9717f387
|
/* Data pointers */ |
77 |
770a9717f387
|
UINT8 **image8; /* Set for 8-bit image (pixelsize=1). */ |
78 |
770a9717f387
|
INT32 **image32; /* Set for 32-bit image (pixelsize=4). */ |
79 |
770a9717f387
|
|
80 |
770a9717f387
|
/* Internals */ |
81 |
770a9717f387
|
char **image; /* Actual raster data. */ |
82 |
770a9717f387
|
char *block; /* Set if data is allocated in a single block. */ |
83 |
770a9717f387
|
|
84 |
770a9717f387
|
int pixelsize; /* Size of a pixel, in bytes (1 or 4) */ |
85 |
770a9717f387
|
int linesize; /* Size of a line, in bytes (xsize * pixelsize) */ |
86 |
770a9717f387
|
|
87 |
770a9717f387
|
/* Virtual methods */ |
88 |
770a9717f387
|
void (*im_delete)(Imaging *); |
89 |
770a9717f387
|
|
90 |
770a9717f387
|
}; |
91 |
770a9717f387
|
|
92 |
770a9717f387
|
/* The pilbitmap booster patch allows you to pass PIL images to the |
93 |
770a9717f387
|
Tk bitmap decoder. Passing images this way is much more efficient |
94 |
770a9717f387
|
than using the "tobitmap" method. */ |
95 |
770a9717f387
|
|
96 |
770a9717f387
|
char * |
97 |
770a9717f387
|
PILGetBitmapData(string, widthPtr, heightPtr, hotXPtr, hotYPtr) |
98 |
770a9717f387
|
char *string; |
99 |
770a9717f387
|
int *widthPtr, *heightPtr; |
100 |
770a9717f387
|
int *hotXPtr, *hotYPtr; |
101 |
770a9717f387
|
{ |
102 |
770a9717f387
|
char* data; |
103 |
770a9717f387
|
char* p; |
104 |
770a9717f387
|
int y; |
105 |
770a9717f387
|
Imaging im; |
106 |
770a9717f387
|
|
107 |
770a9717f387
|
if (strncmp(string, "PIL:", 4) != 0) |
108 |
770a9717f387
|
return NULL; |
109 |
770a9717f387
|
|
110 |
770a9717f387
|
im = (Imaging) atol(string + 4); |
111 |
770a9717f387
|
|
112 |
770a9717f387
|
if (strcmp(im->mode, "1") != 0 && strcmp(im->mode, "L") != 0) |
113 |
770a9717f387
|
return NULL; |
114 |
770a9717f387
|
|
115 |
770a9717f387
|
data = p = (char *) ckalloc((unsigned) ((im->xsize+7)/8) * im->ysize); |
116 |
770a9717f387
|
|
117 |
770a9717f387
|
for (y = 0; y < im->ysize; y++) { |
118 |
770a9717f387
|
char* in = im->image8[y]; |
119 |
770a9717f387
|
int i, m, b; |
120 |
770a9717f387
|
b = 0; m = 1; |
121 |
770a9717f387
|
for (i = 0; i < im->xsize; i++) { |
122 |
770a9717f387
|
if (in[i] != 0) |
123 |
770a9717f387
|
b |= m; |
124 |
770a9717f387
|
m <<= 1; |
125 |
770a9717f387
|
if (m == 256){ |
126 |
770a9717f387
|
*p++ = b; |
127 |
770a9717f387
|
b = 0; m = 1; |
128 |
770a9717f387
|
} |
129 |
770a9717f387
|
} |
130 |
770a9717f387
|
if (m != 1) |
131 |
770a9717f387
|
*p++ = b; |
132 |
770a9717f387
|
} |
133 |
770a9717f387
|
|
134 |
770a9717f387
|
*widthPtr = im->xsize; |
135 |
770a9717f387
|
*heightPtr = im->ysize; |
136 |
770a9717f387
|
*hotXPtr = -1; |
137 |
770a9717f387
|
*hotYPtr = -1; |
138 |
770a9717f387
|
|
139 |
770a9717f387
|
return data; |
140 |
770a9717f387
|
} |
141 |
770a9717f387
|
|
142 |
770a9717f387
|
/* ==================================================================== */ |
143 |
770a9717f387
|
|
144 |
770a9717f387
|
------------------------------------------------------------------------ |
145 |
770a9717f387
|
|
146 |
770a9717f387
|
3. Recompile Tk and relink the _tkinter module (where necessary). |
147 |
770a9717f387
|
|
148 |
770a9717f387
|
==================================================================== |
149 |
770a9717f387
|
Last updated: 97-05-17/fl |