Release 950901
[wine] / objects / dib.c
1 /*
2  * GDI device-independent bitmaps
3  *
4  * Copyright 1993,1994  Alexandre Julliard
5  */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <X11/Xlib.h>
10 #include <X11/Xutil.h>
11 #include "dc.h"
12 #include "bitmap.h"
13 #include "callback.h"
14 #include "palette.h"
15 #include "icon.h"
16 #include "stackframe.h"
17 #include "stddebug.h"
18 #include "color.h"
19 #include "debug.h"
20
21
22 /***********************************************************************
23  *           DIB_GetImageWidthBytes
24  *
25  * Return the width of an X image in bytes
26  */
27 int DIB_GetImageWidthBytes( int width, int depth )
28 {
29     int words;
30
31     switch(depth)
32     {
33     case 1:  words = (width + 31) / 32; break;
34     case 4:  words = (width + 7) / 8; break;
35     case 8:  words = (width + 3) / 4; break;
36     case 15:
37     case 16: words = (width + 1) / 2; break;
38     case 24: words = width; break;
39     default:
40         fprintf(stderr, "DIB: unsupported depth %d.\n", depth );
41         exit(1);
42     }
43     return 4 * words;
44 }
45
46
47 /***********************************************************************
48  *           DIB_BitmapInfoSize
49  *
50  * Return the size of the bitmap info structure.
51  */
52 int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse )
53 {
54     int size = info->bmiHeader.biClrUsed;
55     if (!size && (info->bmiHeader.biBitCount != 24))
56         size = 1 << info->bmiHeader.biBitCount;
57     if (coloruse == DIB_RGB_COLORS) 
58         size = info->bmiHeader.biSize + size * sizeof(RGBQUAD);
59     else
60         size = info->bmiHeader.biSize + size * sizeof(WORD);
61     return size;
62 }
63
64
65 /***********************************************************************
66  *           DIB_DIBmpToImage
67  *
68  * Create an XImage pointing to the bitmap data.
69  */
70 static XImage *DIB_DIBmpToImage( BITMAPINFOHEADER * bmp, void * bmpData )
71 {
72     extern void _XInitImageFuncPtrs( XImage* );
73     XImage * image;
74
75     image = XCreateImage(display, DefaultVisualOfScreen( screen ),
76                          bmp->biBitCount, ZPixmap, 0, bmpData,
77                          bmp->biWidth, bmp->biHeight, 32,
78                          DIB_GetImageWidthBytes(bmp->biWidth,bmp->biBitCount));
79     if (!image) return 0;
80     image->byte_order = MSBFirst;
81     image->bitmap_bit_order = MSBFirst;
82     image->bitmap_unit = 16;
83     _XInitImageFuncPtrs(image);
84     return image;
85 }
86
87
88 /***********************************************************************
89  *           DIB_SetImageBits_1
90  *
91  * SetDIBits for a 1-bit deep DIB.
92  */
93 static void DIB_SetImageBits_1( WORD lines, BYTE *bits, WORD width,
94                                 int *colors, XImage *bmpImage )
95 {
96     WORD i, x;
97     BYTE pad, pix;
98
99     if (!(width & 31)) pad = 0;
100     else pad = ((32 - (width & 31)) + 7) / 8;
101
102     while (lines--)
103     {
104         for (i = width/8, x = 0; (i > 0); i--)
105         {
106             pix = *bits++;
107             XPutPixel( bmpImage, x++, lines, colors[pix >> 7] );
108             XPutPixel( bmpImage, x++, lines, colors[(pix >> 6) & 1] );
109             XPutPixel( bmpImage, x++, lines, colors[(pix >> 5) & 1] );
110             XPutPixel( bmpImage, x++, lines, colors[(pix >> 4) & 1] );
111             XPutPixel( bmpImage, x++, lines, colors[(pix >> 3) & 1] );
112             XPutPixel( bmpImage, x++, lines, colors[(pix >> 2) & 1] );
113             XPutPixel( bmpImage, x++, lines, colors[(pix >> 1) & 1] );
114             XPutPixel( bmpImage, x++, lines, colors[pix & 1] );
115         }
116         pix = *bits;
117         switch(width & 7)
118         {
119         case 7: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
120         case 6: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
121         case 5: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
122         case 4: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
123         case 3: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
124         case 2: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
125         case 1: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] );
126         }
127         bits += pad;
128     }
129 }
130
131
132 /***********************************************************************
133  *           DIB_SetImageBits_4
134  *
135  * SetDIBits for a 4-bit deep DIB.
136  */
137 static void DIB_SetImageBits_4( WORD lines, BYTE *bits, WORD width,
138                                 int *colors, XImage *bmpImage )
139 {
140     WORD i, x;
141     BYTE pad;
142
143     if (!(width & 7)) pad = 0;
144     else pad = ((8 - (width & 7)) + 1) / 2;
145
146     while (lines--)
147     {
148         for (i = width/2, x = 0; i > 0; i--)
149         {
150             BYTE pix = *bits++;
151             XPutPixel( bmpImage, x++, lines, colors[pix >> 4] );
152             XPutPixel( bmpImage, x++, lines, colors[pix & 0x0f] );
153         }
154         if (width & 1) XPutPixel( bmpImage, x, lines, colors[*bits >> 4] );
155         bits += pad;
156     }
157 }
158
159 #define check_xy(x,y) \
160         if (x > width) { \
161                 x = 0; \
162                 if (lines) \
163                         lines--; \
164         }
165
166 /***********************************************************************
167  *           DIB_SetImageBits_RLE4
168  *
169  * SetDIBits for a 4-bit deep compressed DIB.
170  */
171 static void DIB_SetImageBits_RLE4( WORD lines, BYTE *bits, WORD width,
172                                    int *colors, XImage *bmpImage )
173 {
174         int x = 0, c, length;
175         BYTE *begin = bits;
176
177         lines--;
178         while ((INT)lines >= 0)
179         {
180                 length = *bits++;
181                 if (length) {   /* encoded */
182                         c = *bits++;
183                         while (length--) {
184                                 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
185                                 check_xy(x, y);
186                                 if (length) {
187                                         length--;
188                                         XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
189                                         check_xy(x, y);
190                                 }
191                         }
192                 } else {
193                         length = *bits++;
194                         switch (length) {
195                                 case 0: /* eol */
196                                         x = 0;
197                                         lines--;
198                                         continue;
199
200                                 case 1: /* eopicture */
201                                         return;
202
203                                 case 2: /* delta */
204                                         x += *bits++;
205                                         lines -= *bits++;
206                                         continue;
207
208                                 default: /* absolute */
209                                         while (length--) {
210                                                 c = *bits++;
211                                                 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
212                                                 check_xy(x, y);
213                                                 if (length) {
214                                                         length--;
215                                                         XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
216                                                         check_xy(x, y);
217                                                 }
218                                         }
219                                         if ((bits - begin) & 1)
220                                                 bits++;
221                         }
222                 }
223         }
224 }
225
226 /***********************************************************************
227  *           DIB_SetImageBits_8
228  *
229  * SetDIBits for an 8-bit deep DIB.
230  */
231 static void DIB_SetImageBits_8( WORD lines, BYTE *bits, WORD width,
232                                 int *colors, XImage *bmpImage )
233 {
234     WORD x;
235     BYTE pad = (4 - (width & 3)) & 3;
236
237     while (lines--)
238     {
239         for (x = 0; x < width; x++)
240             XPutPixel( bmpImage, x, lines, colors[*bits++] );
241         bits += pad;
242     }
243 }
244
245 /***********************************************************************
246  *            DIB_SetImageBits_RLE8
247  *
248  * SetDIBits for an 8-bit deep compressed DIB.
249  *
250  * This function rewritten 941113 by James Youngman.  WINE blew out when I
251  * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.  
252  *
253  * This was because the algorithm assumed that all RLE8 bitmaps end with the  
254  * 'End of bitmap' escape code.  This code is very much laxer in what it
255  * allows to end the expansion.  Possibly too lax.  See the note by 
256  * case RleDelta.  BTW, MS's documentation implies that a correct RLE8
257  * bitmap should end with RleEnd, but on the other hand, software exists 
258  * that produces ones that don't and Windows 3.1 doesn't complain a bit
259  * about it.
260  *
261  * (No) apologies for my English spelling.  [Emacs users: c-indent-level=4].
262  *                      James A. Youngman <mbcstjy@afs.man.ac.uk>
263  *                                              [JAY]
264  */
265
266 enum Rle8_EscapeCodes           
267 {
268   /* 
269    * Apologies for polluting your file's namespace...
270    */
271   RleEol        = 0,            /* End of line */
272   RleEnd        = 1,            /* End of bitmap */
273   RleDelta      = 2             /* Delta */
274 };
275   
276 static void DIB_SetImageBits_RLE8(WORD lines, 
277                                   BYTE *bits, 
278                                   WORD width,
279                                   int *colors, 
280                                   XImage *bmpImage)
281 {
282     int x;                      /* X-positon on each line.  Increases. */
283     int line;                   /* Line #.  Starts at lines-1, decreases */
284     BYTE *pIn = bits;           /* Pointer to current position in bits */
285     BYTE length;                /* The length pf a run */
286     BYTE color_index;           /* index into colors[] as read from bits */
287     BYTE escape_code;           /* See enum Rle8_EscapeCodes.*/
288     WORD color;                 /* value of colour[color_index] */
289     
290     if (lines == 0)             /* Let's hope this doesn't happen. */
291       return;
292     
293     /*
294      * Note that the bitmap data is stored by Windows starting at the
295      * bottom line of the bitmap and going upwards.  Within each line,
296      * the data is stored left-to-right.  That's the reason why line
297      * goes from lines-1 to 0.                  [JAY]
298      */
299     
300     x = 0;
301     line = lines-1;
302     do
303       {
304           length = *pIn++;
305           
306           /* 
307            * If the length byte is not zero (which is the escape value),
308            * We have a run of length pixels all the same colour.  The colour 
309            * index is stored next. 
310            *
311            * If the length byte is zero, we need to read the next byte to
312            * know what to do.                   [JAY]
313            */
314           if (length != 0) 
315             {                                   
316                 /* 
317                  * [Run-Length] Encoded mode 
318                  */
319                 color_index = (*pIn++); /* Get the colour index. */
320                 color = colors[color_index];
321
322                 while(length--)
323                   XPutPixel(bmpImage, x++, line, color);
324             }
325           else 
326             {    
327                 /* 
328                  * Escape codes (may be an absolute sequence though)
329                  */
330                 escape_code = (*pIn++);
331                 switch(escape_code)
332                   {
333                     case RleEol: /* =0, end of line */
334                       {
335                           x = 0;  
336                           line--;  
337                           break;
338                       }
339                       
340                     case RleEnd: /* =1, end of bitmap */
341                       {
342                           /*
343                            * Not all RLE8 bitmaps end with this 
344                            * code.  For example, Paint Shop Pro 
345                            * produces some that don't.  That's (I think)
346                            * what caused the previous implementation to 
347                            * fail.                      [JAY]
348                            */
349                           line=0; /* Cause exit from do loop. */
350                           break;
351                       }
352                       
353                     case RleDelta: /* =2, a delta */
354                       {
355                           /* 
356                            * Note that deltaing to line 0 
357                            * will cause an exit from the loop, 
358                            * which may not be what is intended. 
359                            * The fact that there is a delta in the bits
360                            * almost certainly implies that there is data
361                            * to follow.  You may feel that we should 
362                            * jump to the top of the loop to avoid exiting
363                            * in this case.  
364                            *
365                            * TODO: Decide what to do here in that case. [JAY]
366                            */
367                           x     += (*pIn++); 
368                           line  -= (*pIn++);
369                           if (line == 0)
370                             {
371                               dprintf_bitmap(stddeb, 
372                                              "DIB_SetImageBits_RLE8(): "
373                                              "Delta to last line of bitmap "
374                                              "(wrongly?) causes loop exit\n");
375                             }
376                           break;
377                       }
378                       
379                     default:    /* >2, switch to absolute mode */
380                       {
381                           /* 
382                            * Absolute Mode 
383                            */
384                           length = escape_code;
385                           while(length--)
386                             {
387                                 color_index = (*pIn++);
388                                 XPutPixel(bmpImage, x++, line, 
389                                           colors[color_index]);
390                             }
391                           
392                           /*
393                            * If you think for a moment you'll realise that the
394                            * only time we could ever possibly read an odd
395                            * number of bytes is when there is a 0x00 (escape),
396                            * a value >0x02 (absolute mode) and then an odd-
397                            * length run.  Therefore this is the only place we
398                            * need to worry about it.  Everywhere else the
399                            * bytes are always read in pairs.  [JAY]
400                            */
401                           if (escape_code & 1) 
402                             pIn++; /* Throw away the pad byte. */
403                           break;
404                       }
405                   } /* switch (escape_code) : Escape sequence */
406             }  /* process either an encoded sequence or an escape sequence */
407           
408           /* We expect to come here more than once per line. */
409       } while (line > 0);  /* Do this until the bitmap is filled */
410     
411     /*
412      * Everybody comes here at the end.
413      * Check how we exited the loop and print a message if it's a bit odd.
414      *                                          [JAY]
415      */
416     if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) )
417       {
418         dprintf_bitmap(stddeb, "DIB_SetImageBits_RLE8(): End-of-bitmap "
419                        "without (strictly) proper escape code.  Last two "
420                        "bytes were: %02X %02X.\n",
421                        (int)*(pIn-2),
422                        (int)*(pIn-1));           
423       }
424 }  
425
426
427 /***********************************************************************
428  *           DIB_SetImageBits_24
429  *
430  * SetDIBits for a 24-bit deep DIB.
431  */
432 static void DIB_SetImageBits_24( WORD lines, BYTE *bits, WORD width,
433                                  DC *dc, XImage *bmpImage )
434 {
435     WORD x;
436     BYTE pad = (4 - ((width*3) & 3)) & 3;
437
438     while (lines--)
439     {
440         for (x = 0; x < width; x++, bits += 3)
441         {
442             XPutPixel( bmpImage, x, lines,
443                        COLOR_ToPhysical( dc, RGB(bits[0],bits[1],bits[2]) ));
444         }
445         bits += pad;
446     }
447 }
448
449
450 /***********************************************************************
451  *           DIB_SetImageBits
452  *
453  * Transfer the bits to an X image.
454  * Helper function for SetDIBits() and SetDIBitsToDevice().
455  */
456 static int DIB_SetImageBits( DC *dc, WORD lines, WORD depth, LPSTR bits,
457                              BITMAPINFO *info, WORD coloruse,
458                              Drawable drawable, GC gc, int xSrc, int ySrc,
459                              int xDest, int yDest, int width, int height )
460 {
461     int *colorMapping;
462     XImage *bmpImage;
463     int i, colors;
464
465       /* Build the color mapping table */
466
467     if (info->bmiHeader.biBitCount == 24) colorMapping = NULL;
468     else
469     {
470         colors = info->bmiHeader.biClrUsed;
471         if (!colors) colors = 1 << info->bmiHeader.biBitCount;
472         if (!(colorMapping = (int *)malloc( colors * sizeof(int) )))
473             return 0;
474         if (coloruse == DIB_RGB_COLORS)
475         {
476             RGBQUAD * rgbPtr = info->bmiColors;
477             for (i = 0; i < colors; i++, rgbPtr++)
478                 colorMapping[i] = COLOR_ToPhysical( dc, RGB(rgbPtr->rgbRed,
479                                                             rgbPtr->rgbGreen,
480                                                             rgbPtr->rgbBlue) );
481         }
482         else
483         {
484             WORD * index = (WORD *)info->bmiColors;
485             for (i = 0; i < colors; i++, index++)
486                 colorMapping[i] = COLOR_ToPhysical( dc, PALETTEINDEX(*index) );
487         }
488     }
489
490       /* Transfer the pixels */
491     XCREATEIMAGE(bmpImage, info->bmiHeader.biWidth, lines, depth );
492
493     switch(info->bmiHeader.biBitCount)
494     {
495     case 1:
496         DIB_SetImageBits_1( lines, bits, info->bmiHeader.biWidth,
497                             colorMapping, bmpImage );
498         break;
499     case 4:
500         if (info->bmiHeader.biCompression)
501                 DIB_SetImageBits_RLE4( lines, bits, info->bmiHeader.biWidth,
502                             colorMapping, bmpImage );
503         else    
504                 DIB_SetImageBits_4( lines, bits, info->bmiHeader.biWidth,
505                             colorMapping, bmpImage );
506         break;
507     case 8:
508         if (info->bmiHeader.biCompression)
509                 DIB_SetImageBits_RLE8( lines, bits, info->bmiHeader.biWidth,
510                             colorMapping, bmpImage );
511         else
512                 DIB_SetImageBits_8( lines, bits, info->bmiHeader.biWidth,
513                             colorMapping, bmpImage );
514         break;
515     case 24:
516         DIB_SetImageBits_24( lines, bits, info->bmiHeader.biWidth,
517                              dc, bmpImage );
518         break;
519     }
520     if (colorMapping) free(colorMapping);
521     XPutImage( display, drawable, gc, bmpImage, xSrc, ySrc,
522                xDest, yDest, width, height );
523     XDestroyImage( bmpImage );
524     return lines;
525 }
526
527
528 /***********************************************************************
529  *           StretchDIBits      (GDI.439)
530  */
531 int StretchDIBits( HDC hdc, 
532         WORD xDest, WORD yDest, WORD wDestWidth, WORD wDestHeight,
533         WORD xSrc, WORD ySrc, WORD wSrcWidth, WORD wSrcHeight,
534         LPSTR bits, LPBITMAPINFO info, WORD wUsage, DWORD dwRop )
535 {
536     HBITMAP hBitmap, hOldBitmap;
537     HDC hdcMem;
538
539     hBitmap = CreateDIBitmap( hdc, &info->bmiHeader, CBM_INIT,
540                               bits, info, wUsage );
541     hdcMem = CreateCompatibleDC( hdc );
542     hOldBitmap = SelectObject( hdcMem, hBitmap );
543     StretchBlt( hdc, xDest, yDest, wDestWidth, wDestHeight,
544                 hdcMem, xSrc, ySrc, wSrcWidth, wSrcHeight, dwRop );
545     SelectObject( hdcMem, hOldBitmap );
546     DeleteDC( hdcMem );
547     DeleteObject( hBitmap );
548     return wSrcHeight;
549 }
550
551 /***********************************************************************
552  *           SetDIBits    (GDI.440)
553  */
554 int SetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines,
555                LPSTR bits, BITMAPINFO * info, WORD coloruse )
556 {
557     DC * dc;
558     BITMAPOBJ * bmp;
559
560       /* Check parameters */
561
562     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
563     if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
564         return 0;
565     if (!lines || (startscan >= (WORD)info->bmiHeader.biHeight)) return 0;
566     if (startscan+lines > info->bmiHeader.biHeight)
567         lines = info->bmiHeader.biHeight - startscan;
568
569     return CallTo32_LargeStack( (int(*)())DIB_SetImageBits, 14,
570                                 dc, lines, bmp->bitmap.bmBitsPixel,
571                                 bits, info, coloruse, bmp->pixmap,
572                                 BITMAP_GC(bmp), 0, 0, 0, startscan,
573                                 bmp->bitmap.bmWidth, lines );
574 }
575
576
577 /***********************************************************************
578  *           SetDIBitsToDevice    (GDI.443)
579  */
580 int SetDIBitsToDevice( HDC hdc, short xDest, short yDest, WORD cx, WORD cy,
581                        WORD xSrc, WORD ySrc, WORD startscan, WORD lines,
582                        LPSTR bits, BITMAPINFO * info, WORD coloruse )
583 {
584     DC * dc;
585
586       /* Check parameters */
587
588     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
589     if (!lines || (startscan >= info->bmiHeader.biHeight)) return 0;
590     if (startscan+lines > info->bmiHeader.biHeight)
591         lines = info->bmiHeader.biHeight - startscan;
592     if (ySrc < startscan) ySrc = startscan;
593     else if (ySrc >= startscan+lines) return 0;
594     if (xSrc >= info->bmiHeader.biWidth) return 0;
595     if (ySrc+cy >= startscan+lines) cy = startscan + lines - ySrc;
596     if (xSrc+cx >= info->bmiHeader.biWidth) cx = info->bmiHeader.biWidth-xSrc;
597     if (!cx || !cy) return 0;
598
599     DC_SetupGCForText( dc );  /* To have the correct colors */
600     XSetFunction( display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] );
601     return CallTo32_LargeStack( (int(*)())DIB_SetImageBits, 14,
602                                 dc, lines, dc->w.bitsPerPixel, bits, info,
603                                 coloruse, dc->u.x.drawable, dc->u.x.gc,
604                                 xSrc, ySrc - startscan,
605                                 dc->w.DCOrgX + XLPTODP( dc, xDest ),
606                                 dc->w.DCOrgY + YLPTODP( dc, yDest ),
607                                 cx, cy );
608 }
609
610
611
612 /***********************************************************************
613  *           GetDIBits    (GDI.441)
614  */
615 int GetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines,
616                LPSTR bits, BITMAPINFO * info, WORD coloruse )
617 {
618     DC * dc;
619     BITMAPOBJ * bmp;
620     PALETTEENTRY * palEntry;
621     PALETTEOBJ * palette;
622     XImage * bmpImage, * dibImage;
623     int i, x, y;
624         
625     if (!lines) return 0;
626     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
627     if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
628         return 0;
629     if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
630         return 0;
631
632       /* Transfer color info */
633     
634     palEntry = palette->logpalette.palPalEntry;
635     for (i = 0; i < info->bmiHeader.biClrUsed; i++, palEntry++)
636     {
637         if (coloruse == DIB_RGB_COLORS)
638         {
639             info->bmiColors[i].rgbRed      = palEntry->peRed;
640             info->bmiColors[i].rgbGreen    = palEntry->peGreen;
641             info->bmiColors[i].rgbBlue     = palEntry->peBlue;
642             info->bmiColors[i].rgbReserved = 0;
643         }
644         else ((WORD *)info->bmiColors)[i] = (WORD)i;
645     }
646     
647       /* Transfer the pixels (very slow...) */
648
649     if (bits)
650     {   
651         bmpImage = (XImage *)CallTo32_LargeStack( (int (*)())XGetImage, 8, 
652                                display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth,
653                                bmp->bitmap.bmHeight, AllPlanes, ZPixmap );
654         dibImage = DIB_DIBmpToImage( &info->bmiHeader, bits );
655
656         for (y = 0; y < lines; y++)
657         {
658             for (x = 0; x < info->bmiHeader.biWidth; x++)
659             {
660                 XPutPixel( dibImage, x, y,
661                   XGetPixel(bmpImage, x, bmp->bitmap.bmHeight-startscan-y-1) );
662                 
663             }
664         }
665         
666         dibImage->data = NULL;
667         XDestroyImage( dibImage );
668         XDestroyImage( bmpImage );
669     }
670     info->bmiHeader.biCompression = 0;
671     return lines;
672 }
673
674
675 /***********************************************************************
676  *           CreateDIBitmap    (GDI.442)
677  */
678 HBITMAP CreateDIBitmap( HDC hdc, BITMAPINFOHEADER * header, DWORD init,
679                         LPSTR bits, BITMAPINFO * data, WORD coloruse )
680 {
681     HBITMAP handle;
682     
683     handle = CreateCompatibleBitmap( hdc, header->biWidth, header->biHeight );
684 /*    handle = CreateBitmap( header->biWidth, header->biHeight,
685                            1, header->biBitCount, NULL );
686 */
687     if (!handle) return 0;
688     if (init == CBM_INIT) SetDIBits( hdc, handle, 0, header->biHeight,
689                                     bits, data, coloruse );
690     return handle;
691 }
692
693 /***********************************************************************
694  *           DrawIcon    (USER.84)
695  */
696 BOOL DrawIcon(HDC hDC, short x, short y, HICON hIcon)
697 {
698     ICONALLOC   *lpico;
699     BITMAP      bm;
700     HBITMAP     hBitTemp;
701     HDC         hMemDC;
702     COLORREF    oldFg, oldBg;
703
704     oldFg = SetTextColor( hDC, RGB(0,0,0) );
705     oldBg = SetBkColor( hDC, RGB(255,255,255) );
706     dprintf_icon(stddeb,"DrawIcon(%04X, %d, %d, %04X) \n", hDC, x, y, hIcon);
707     if (hIcon == (HICON)NULL) return FALSE;
708     lpico = (ICONALLOC *)GlobalLock(hIcon);
709     GetObject(lpico->hBitmap, sizeof(BITMAP), (LPSTR)&bm);
710     hMemDC = CreateCompatibleDC(hDC);
711     if (lpico->hBitMask)
712     {
713         hBitTemp = SelectObject(hMemDC, lpico->hBitMask);
714         BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCAND);
715         SelectObject(hMemDC, lpico->hBitmap);
716         BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCINVERT);
717     }
718     else  /* no mask -> everything is masked; so use SRCCOPY as it's faster */
719     {
720         hBitTemp = SelectObject(hMemDC, lpico->hBitmap);
721         BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
722     }
723     SelectObject( hMemDC, hBitTemp );
724     DeleteDC(hMemDC);
725     GlobalUnlock( hIcon );
726     SetTextColor( hDC, oldFg );
727     SetBkColor( hDC, oldBg );
728     return TRUE;
729 }