OSDN Git Service

7cbdfde903693bf8a652a56511c96f5a1eab58a1
[pf3gnuchains/pf3gnuchains3x.git] / tk / win / tkWinImage.c
1 /* 
2  * tkWinImage.c --
3  *
4  *      This file contains routines for manipulation full-color images.
5  *
6  * Copyright (c) 1995 Sun Microsystems, Inc.
7  *
8  * See the file "license.terms" for information on usage and redistribution
9  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10  *
11  * RCS: @(#) $Id$
12  */
13
14 #include "tkWinInt.h"
15
16 static int              DestroyImage _ANSI_ARGS_((XImage* data));
17 static unsigned long    ImageGetPixel _ANSI_ARGS_((XImage *image, int x, int y));
18 static int              PutPixel _ANSI_ARGS_((XImage *image, int x, int y,
19                             unsigned long pixel));
20 \f
21 /*
22  *----------------------------------------------------------------------
23  *
24  * DestroyImage --
25  *
26  *      This is a trivial wrapper around ckfree to make it possible to
27  *      pass ckfree as a pointer.
28  *
29  * Results:
30  *      None.
31  *
32  * Side effects:
33  *      Deallocates the image.
34  *
35  *----------------------------------------------------------------------
36  */
37
38 static int
39 DestroyImage(imagePtr)
40      XImage *imagePtr;          /* image to free */
41 {
42     if (imagePtr) {
43         if (imagePtr->data) {
44             ckfree((char*)imagePtr->data);
45         }
46         ckfree((char*)imagePtr);
47     }
48     return 0;
49 }
50 \f
51 /*
52  *----------------------------------------------------------------------
53  *
54  * ImageGetPixel --
55  *
56  *      Get a single pixel from an image.
57  *
58  * Results:
59  *      Returns the 32 bit pixel value.
60  *
61  * Side effects:
62  *      None.
63  *
64  *----------------------------------------------------------------------
65  */
66
67 static unsigned long
68 ImageGetPixel(image, x, y)
69     XImage *image;
70     int x, y;
71 {
72     unsigned long pixel = 0;
73     unsigned char *srcPtr = &(image->data[(y * image->bytes_per_line)
74             + ((x * image->bits_per_pixel) / NBBY)]);
75
76     switch (image->bits_per_pixel) {
77         case 32:
78         case 24:
79             pixel = RGB(srcPtr[2], srcPtr[1], srcPtr[0]);
80             break;
81         case 16:
82             pixel = RGB(((((WORD*)srcPtr)[0]) >> 7) & 0xf8,
83                     ((((WORD*)srcPtr)[0]) >> 2) & 0xf8,
84                     ((((WORD*)srcPtr)[0]) << 3) & 0xf8);
85             break;
86         case 8:
87             pixel = srcPtr[0];
88             break;
89         case 4:
90             pixel = ((x%2) ? (*srcPtr) : ((*srcPtr) >> 4)) & 0x0f;
91             break;
92         case 1:
93             pixel = ((*srcPtr) & (0x80 >> (x%8))) ? 1 : 0;
94             break;
95     }
96     return pixel;
97 }
98 \f
99 /*
100  *----------------------------------------------------------------------
101  *
102  * PutPixel --
103  *
104  *      Set a single pixel in an image.
105  *
106  * Results:
107  *      None.
108  *
109  * Side effects:
110  *      None.
111  *
112  *----------------------------------------------------------------------
113  */
114
115 static int
116 PutPixel(image, x, y, pixel)
117     XImage *image;
118     int x, y;
119     unsigned long pixel;
120 {
121     unsigned char *destPtr = &(image->data[(y * image->bytes_per_line)
122             + ((x * image->bits_per_pixel) / NBBY)]);
123
124     switch  (image->bits_per_pixel) {
125         case 32:
126             /*
127              * Pixel is DWORD: 0x00BBGGRR
128              */
129
130             destPtr[3] = 0;
131         case 24:
132             /*
133              * Pixel is triplet: 0xBBGGRR.
134              */
135
136             destPtr[0] = (unsigned char) GetBValue(pixel);
137             destPtr[1] = (unsigned char) GetGValue(pixel);
138             destPtr[2] = (unsigned char) GetRValue(pixel);
139             break;
140         case 16:
141             /*
142              * Pixel is WORD: 5-5-5 (R-G-B)
143              */
144
145             (*(WORD*)destPtr) = 
146                 ((GetRValue(pixel) & 0xf8) << 7)
147                 | ((GetGValue(pixel) & 0xf8) <<2)
148                 | ((GetBValue(pixel) & 0xf8) >> 3);
149             break;
150         case 8:
151             /*
152              * Pixel is 8-bit index into color table.
153              */
154
155             (*destPtr) = (unsigned char) pixel;
156             break;
157         case 4:
158             /*
159              * Pixel is 4-bit index in MSBFirst order.
160              */
161             if (x%2) {
162                 (*destPtr) = (unsigned char) (((*destPtr) & 0xf0)
163                     | (pixel & 0x0f));
164             } else {
165                 (*destPtr) = (unsigned char) (((*destPtr) & 0x0f)
166                     | ((pixel << 4) & 0xf0));
167             }
168             break;
169         case 1: {
170             /*
171              * Pixel is bit in MSBFirst order.
172              */
173
174             int mask = (0x80 >> (x%8));
175             if (pixel) {
176                 (*destPtr) |= mask;
177             } else {
178                 (*destPtr) &= ~mask;
179             }
180         }
181         break;
182     }
183     return 0;
184 }
185 \f
186 /*
187  *----------------------------------------------------------------------
188  *
189  * XCreateImage --
190  *
191  *      Allocates storage for a new XImage.
192  *
193  * Results:
194  *      Returns a newly allocated XImage.
195  *
196  * Side effects:
197  *      None.
198  *
199  *----------------------------------------------------------------------
200  */
201
202 XImage *
203 XCreateImage(display, visual, depth, format, offset, data, width, height,
204         bitmap_pad, bytes_per_line)
205     Display* display;
206     Visual* visual;
207     unsigned int depth;
208     int format;
209     int offset;
210     char* data;
211     unsigned int width;
212     unsigned int height;
213     int bitmap_pad;
214     int bytes_per_line;
215 {
216     XImage* imagePtr = (XImage *) ckalloc(sizeof(XImage));
217     imagePtr->width = width;
218     imagePtr->height = height;
219     imagePtr->xoffset = offset;
220     imagePtr->format = format;
221     imagePtr->data = data;
222     imagePtr->byte_order = LSBFirst;
223     imagePtr->bitmap_unit = 8;
224     imagePtr->bitmap_bit_order = MSBFirst;
225     imagePtr->bitmap_pad = bitmap_pad;
226     imagePtr->bits_per_pixel = depth;
227     imagePtr->depth = depth;
228
229     /*
230      * Under Windows, bitmap_pad must be on an LONG data-type boundary.
231      */
232
233 #define LONGBITS    (sizeof(LONG) * 8)
234
235     bitmap_pad = (bitmap_pad + LONGBITS - 1) / LONGBITS * LONGBITS;
236
237     /*
238      * Round to the nearest bitmap_pad boundary.
239      */
240
241     if (bytes_per_line) {
242         imagePtr->bytes_per_line = bytes_per_line;
243     } else {
244         imagePtr->bytes_per_line = (((depth * width)
245                 + (bitmap_pad - 1)) >> 3) & ~((bitmap_pad >> 3) - 1);
246     }
247
248     imagePtr->red_mask = 0;
249     imagePtr->green_mask = 0;
250     imagePtr->blue_mask = 0;
251
252     imagePtr->f.put_pixel = PutPixel;
253     imagePtr->f.get_pixel = ImageGetPixel;
254     imagePtr->f.destroy_image = DestroyImage;
255     imagePtr->f.create_image = NULL;
256     imagePtr->f.sub_image = NULL;
257     imagePtr->f.add_pixel = NULL;
258     
259     return imagePtr;
260 }
261 \f
262 /*
263  *----------------------------------------------------------------------
264  *
265  * XGetImage --
266  *
267  *      This function copies data from a pixmap or window into an
268  *      XImage.
269  *
270  * Results:
271  *      Returns a newly allocated image containing the data from the
272  *      given rectangle of the given drawable.
273  *
274  * Side effects:
275  *      None.
276  *
277  *----------------------------------------------------------------------
278  */
279
280 XImage *
281 XGetImage(display, d, x, y, width, height, plane_mask, format)
282     Display* display;
283     Drawable d;
284     int x;
285     int y;
286     unsigned int width;
287     unsigned int height;
288     unsigned long plane_mask;
289     int format;
290 {
291     TkWinDrawable *twdPtr = (TkWinDrawable *)d;
292     XImage *imagePtr;
293     HDC dc;
294     char infoBuf[sizeof(BITMAPINFO) + sizeof(RGBQUAD)];
295     BITMAPINFO *infoPtr = (BITMAPINFO*)infoBuf;
296
297     if ((twdPtr->type != TWD_BITMAP) || (twdPtr->bitmap.handle == NULL)
298             || (format != XYPixmap) || (plane_mask != 1)) {
299         panic("XGetImage: not implemented");
300     }
301
302
303     imagePtr = XCreateImage(display, NULL, 1, XYBitmap, 0, NULL,
304             width, height, 32, 0);
305     imagePtr->data = ckalloc(imagePtr->bytes_per_line * imagePtr->height);
306
307     dc = GetDC(NULL);
308
309     GetDIBits(dc, twdPtr->bitmap.handle, 0, height, NULL,
310             infoPtr, DIB_RGB_COLORS);
311
312     infoPtr->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
313     infoPtr->bmiHeader.biWidth = width;
314     infoPtr->bmiHeader.biHeight = -(LONG)height;
315     infoPtr->bmiHeader.biPlanes = 1;
316     infoPtr->bmiHeader.biBitCount = 1;
317     infoPtr->bmiHeader.biCompression = BI_RGB;
318     infoPtr->bmiHeader.biCompression = 0;
319     infoPtr->bmiHeader.biXPelsPerMeter = 0;
320     infoPtr->bmiHeader.biYPelsPerMeter = 0;
321     infoPtr->bmiHeader.biClrUsed = 0;
322     infoPtr->bmiHeader.biClrImportant = 0;
323
324     GetDIBits(dc, twdPtr->bitmap.handle, 0, height, imagePtr->data,
325             infoPtr, DIB_RGB_COLORS);
326     ReleaseDC(NULL, dc);
327
328     return imagePtr;
329 }
330