Release 980614
[wine] / objects / dib.c
1 /*
2  * GDI device-independent bitmaps
3  *
4  * Copyright 1993,1994  Alexandre Julliard
5  */
6
7 #include <stdlib.h>
8 #include "ts_xlib.h"
9 #include "ts_xutil.h"
10 #include "dc.h"
11 #include "bitmap.h"
12 #include "callback.h"
13 #include "palette.h"
14 #include "color.h"
15 #include "debug.h"
16
17 static int bitmapDepthTable[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
18 static int ximageDepthTable[] = { 0, 0, 0,  0,  0,  0,  0 };
19
20
21 /* This structure holds the arguments for DIB_SetImageBits() */
22 typedef struct
23 {
24     DC               *dc;
25     LPCVOID           bits;
26     int               lines;
27     DWORD             infoWidth;
28     WORD              depth;
29     WORD              infoBpp;
30     WORD              compression;
31     RGBQUAD          *colorMap;
32     int               nColorMap;
33     Drawable          drawable;
34     GC                gc;
35     int               xSrc;
36     int               ySrc;
37     int               xDest;
38     int               yDest;
39     int               width;
40     int               height;
41 } DIB_SETIMAGEBITS_DESCR;
42
43
44 /***********************************************************************
45  *           DIB_Init
46  */
47 BOOL32 DIB_Init(void)
48 {
49     int         i;
50     XImage*     testimage;
51
52     for( i = 0; bitmapDepthTable[i]; i++ )
53     {
54          testimage = TSXCreateImage(display, DefaultVisualOfScreen(screen),
55                          bitmapDepthTable[i], ZPixmap, 0, NULL, 1, 1, 32, 20 );
56          if( testimage ) ximageDepthTable[i] = testimage->bits_per_pixel;
57          else return FALSE;
58          TSXDestroyImage(testimage);
59     }
60     return TRUE;
61 }
62
63 /***********************************************************************
64  *           DIB_GetXImageWidthBytes
65  *
66  * Return the width of an X image in bytes
67  */
68 int DIB_GetXImageWidthBytes( int width, int depth )
69 {
70     int         i;
71
72     if (!ximageDepthTable[0]) {
73             DIB_Init();
74     }
75     for( i = 0; bitmapDepthTable[i] ; i++ )
76          if( bitmapDepthTable[i] == depth )
77              return (4 * ((width * ximageDepthTable[i] + 31)/32));
78     
79     WARN(bitmap, "(%d): Unsupported depth\n", depth );
80     return (4 * width);
81 }
82
83 /***********************************************************************
84  *           DIB_GetDIBWidthBytes
85  *
86  * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
87  * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
88  */
89 int DIB_GetDIBWidthBytes( int width, int depth )
90 {
91     int words;
92
93     switch(depth)
94     {
95         case 1:  words = (width + 31) / 32; break;
96         case 4:  words = (width + 7) / 8; break;
97         case 8:  words = (width + 3) / 4; break;
98         case 15:
99         case 16: words = (width + 1) / 2; break;
100         case 24: words = (width * 3 + 3)/4; break;
101
102         default:
103             WARN(bitmap, "(%d): Unsupported depth\n", depth );
104         /* fall through */
105         case 32:
106                 words = width;
107     }
108     return 4 * words;
109 }
110
111
112 /***********************************************************************
113  *           DIB_BitmapInfoSize
114  *
115  * Return the size of the bitmap info structure including color table.
116  */
117 int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse )
118 {
119     int colors;
120
121     if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
122     {
123         BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
124         colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
125         return sizeof(BITMAPCOREHEADER) + colors *
126              ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
127     }
128     else  /* assume BITMAPINFOHEADER */
129     {
130         colors = info->bmiHeader.biClrUsed;
131         if (!colors && (info->bmiHeader.biBitCount <= 8))
132             colors = 1 << info->bmiHeader.biBitCount;
133         return sizeof(BITMAPINFOHEADER) + colors *
134                ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
135     }
136 }
137
138
139 /***********************************************************************
140  *           DIB_GetBitmapInfo
141  *
142  * Get the info from a bitmap header.
143  * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
144  */
145 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
146                               int *height, WORD *bpp, WORD *compr )
147 {
148     if (header->biSize == sizeof(BITMAPINFOHEADER))
149     {
150         *width  = header->biWidth;
151         *height = header->biHeight;
152         *bpp    = header->biBitCount;
153         *compr  = header->biCompression;
154         return 1;
155     }
156     if (header->biSize == sizeof(BITMAPCOREHEADER))
157     {
158         BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
159         *width  = core->bcWidth;
160         *height = core->bcHeight;
161         *bpp    = core->bcBitCount;
162         *compr  = 0;
163         return 0;
164     }
165     WARN(bitmap, "(%ld): wrong size for header\n", header->biSize );
166     return -1;
167 }
168
169
170 /***********************************************************************
171  *           DIB_BuildColorMap
172  *
173  * Build the color map from the bitmap palette. Should not be called
174  * for a >8-bit deep bitmap.
175  */
176 static RGBQUAD *DIB_BuildColorMap( const BITMAPINFO *info, 
177                                    HPALETTE16 hPalette, int *nColors )
178 {
179     int i, colors;
180     BOOL32 isInfo;
181     WORD *colorPtr;
182     RGBQUAD *colorMapping;
183
184     if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
185     {
186         colors = info->bmiHeader.biClrUsed;
187         if (!colors) colors = 1 << info->bmiHeader.biBitCount;
188         colorPtr = (WORD *)info->bmiColors;
189     }
190     else  /* assume BITMAPCOREINFO */
191     {
192         colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
193         colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
194     }
195
196     if (colors > 256)
197     {
198         ERR(bitmap, "DIB_BuildColorMap called with >256 colors!\n");
199         return NULL;
200     }
201
202     if (!(colorMapping = (RGBQUAD *)HeapAlloc(GetProcessHeap(), 0,
203                                               colors * sizeof(RGBQUAD) ))) 
204         return NULL;
205
206     if (hPalette == 0) /* DIB_RGB_COLORS */
207     {
208         if (isInfo)
209         {
210             RGBQUAD * rgb = (RGBQUAD *)colorPtr;
211
212             for (i = 0; i < colors; i++, rgb++)
213                 colorMapping[i] = *rgb;
214         }
215         else
216         {
217             RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
218         
219             for (i = 0; i < colors; i++, rgb++)
220                 colorMapping[i].rgbRed   = rgb->rgbtRed,
221                 colorMapping[i].rgbGreen = rgb->rgbtGreen,
222                 colorMapping[i].rgbBlue  = rgb->rgbtBlue;
223         }
224     }
225     else  /* DIB_PAL_COLORS */
226     {
227         PALETTEOBJ *palPtr = (PALETTEOBJ *)GDI_GetObjPtr(hPalette, PALETTE_MAGIC);
228         if (!palPtr) 
229         {
230             HeapFree(GetProcessHeap(), 0, colorMapping);
231             return NULL;
232         }
233
234         for (i = 0; i < colors; i++, colorPtr++)
235             if (*colorPtr >= palPtr->logpalette.palNumEntries)
236             {
237                 colorMapping[i].rgbRed   = 0;
238                 colorMapping[i].rgbGreen = 0;
239                 colorMapping[i].rgbBlue  = 0;
240             }
241             else
242             {
243                 PALETTEENTRY *pe = palPtr->logpalette.palPalEntry + *colorPtr;
244                 colorMapping[i].rgbRed   = pe->peRed;
245                 colorMapping[i].rgbGreen = pe->peGreen;
246                 colorMapping[i].rgbBlue  = pe->peBlue;
247             }
248         
249         GDI_HEAP_UNLOCK(hPalette);
250     }
251
252     *nColors = colors;
253     return colorMapping;
254 }
255
256 /***********************************************************************
257  *           DIB_PhysicalColorMap
258  *
259  * Translate color map to physical colors
260  */
261 static int *DIB_PhysicalColorMap( DC *dc, int depth, 
262                                   RGBQUAD *colorMap, int nColorMap)
263 {
264     int *colorMapping, i;
265
266     if (!nColorMap) return NULL;
267     if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
268                                           nColorMap * sizeof(int) ))) return NULL;
269
270     if (depth == 1) /* Monochrome */
271         for (i = 0; i < nColorMap; i++, colorMap++)
272             colorMapping[i] = (colorMap->rgbRed + colorMap->rgbGreen + 
273                                colorMap->rgbBlue > 255*3/2);
274     else
275         for (i = 0; i < nColorMap; i++, colorMap++)
276             colorMapping[i] = COLOR_ToPhysical( dc, RGB(colorMap->rgbRed,
277                                                         colorMap->rgbGreen,
278                                                         colorMap->rgbBlue));
279     return colorMapping;
280 }
281
282 /***********************************************************************
283  *           DIB_SetImageBits_1_Line
284  *
285  * Handles a single line of 1 bit data.
286  */
287 static void DIB_SetImageBits_1_Line(DWORD dstwidth, int left, int *colors,
288                                     XImage *bmpImage, int h, const BYTE *bits)
289 {
290     BYTE pix;
291     DWORD i, x;
292
293     dstwidth += left; bits += left >> 3;
294
295     /* FIXME: should avoid putting x<left pixels (minor speed issue) */
296     for (i = dstwidth/8, x = left&~7; (i > 0); i--)
297     {
298         pix = *bits++;
299         XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
300         XPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] );
301         XPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] );
302         XPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] );
303         XPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] );
304         XPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] );
305         XPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] );
306         XPutPixel( bmpImage, x++, h, colors[pix & 1] );
307     }
308     pix = *bits;
309     switch(dstwidth & 7)
310     {
311     case 7: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
312     case 6: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
313     case 5: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
314     case 4: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
315     case 3: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
316     case 2: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
317     case 1: XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
318     }
319 }
320
321 /***********************************************************************
322  *           DIB_SetImageBits_1
323  *
324  * SetDIBits for a 1-bit deep DIB.
325  */
326 static void DIB_SetImageBits_1( int lines, const BYTE *srcbits,
327                                 DWORD srcwidth, DWORD dstwidth, int left,
328                                 int *colors, XImage *bmpImage )
329 {
330     int h;
331
332     /* 32 bit aligned */
333     DWORD linebytes = ((srcwidth + 31) & ~31) / 8;
334
335     if (lines > 0) {
336         for (h = lines-1; h >=0; h--) {
337             DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h, srcbits);
338             srcbits += linebytes;
339         }
340     } else {
341         lines = -lines;
342         for (h = 0; h < lines; h++) {
343             DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h, srcbits);
344             srcbits += linebytes;
345         }
346     }
347 }
348
349
350 /***********************************************************************
351  *           DIB_SetImageBits_4
352  *
353  * SetDIBits for a 4-bit deep DIB.
354  */
355 static void DIB_SetImageBits_4( int lines, const BYTE *srcbits,
356                                 DWORD srcwidth, DWORD dstwidth, int left,
357                                 int *colors, XImage *bmpImage )
358 {
359     DWORD i, x;
360     int h;
361     const BYTE *bits = srcbits + (left >> 1);
362   
363     /* 32 bit aligned */
364     DWORD linebytes = ((srcwidth+7)&~7)/2;
365
366     dstwidth += left;
367
368     /* FIXME: should avoid putting x<left pixels (minor speed issue) */
369     if (lines > 0) {
370         for (h = lines-1; h >= 0; h--) {
371             for (i = dstwidth/2, x = left&~1; i > 0; i--) {
372                 BYTE pix = *bits++;
373                 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
374                 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
375             }
376             if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
377             srcbits += linebytes;
378             bits         = srcbits + (left >> 1);
379         }
380     } else {
381         lines = -lines;
382         for (h = 0; h < lines; h++) {
383             for (i = dstwidth/2, x = left&~1; i > 0; i--) {
384                 BYTE pix = *bits++;
385                 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
386                 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
387             }
388             if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
389             srcbits += linebytes;
390             bits         = srcbits + (left >> 1);
391         }
392     }
393 }
394
395 #define check_xy(x,y) \
396         if (x > width) { \
397                 x = 0; \
398                 if (lines) \
399                         lines--; \
400         }
401
402 /***********************************************************************
403  *           DIB_SetImageBits_RLE4
404  *
405  * SetDIBits for a 4-bit deep compressed DIB.
406  */
407 static void DIB_SetImageBits_RLE4( int lines, const BYTE *bits, DWORD width,
408                                 DWORD dstwidth, int left, int *colors, XImage *bmpImage )
409 {
410         int x = 0, c, length;
411         const BYTE *begin = bits;
412
413         dstwidth += left; /* FIXME: avoid putting x<left pixels */
414
415         lines--;
416         while ((int)lines >= 0)
417         {
418                 length = *bits++;
419                 if (length) {   /* encoded */
420                         c = *bits++;
421                         while (length--) {
422                                 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
423                                 check_xy(x, y);
424                                 if (length) {
425                                         length--;
426                                         XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
427                                         check_xy(x, y);
428                                 }
429                         }
430                 } else {
431                         length = *bits++;
432                         switch (length) {
433                                 case 0: /* eol */
434                                         x = 0;
435                                         lines--;
436                                         continue;
437
438                                 case 1: /* eopicture */
439                                         return;
440
441                                 case 2: /* delta */
442                                         x += *bits++;
443                                         lines -= *bits++;
444                                         continue;
445
446                                 default: /* absolute */
447                                         while (length--) {
448                                                 c = *bits++;
449                                                 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
450                                                 check_xy(x, y);
451                                                 if (length) {
452                                                         length--;
453                                                         XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
454                                                         check_xy(x, y);
455                                                 }
456                                         }
457                                         if ((bits - begin) & 1)
458                                                 bits++;
459                         }
460                 }
461         }
462 }
463
464 /***********************************************************************
465  *           DIB_SetImageBits_8
466  *
467  * SetDIBits for an 8-bit deep DIB.
468  */
469 static void DIB_SetImageBits_8( int lines, const BYTE *srcbits,
470                                 DWORD srcwidth, DWORD dstwidth, int left,
471                                 int *colors, XImage *bmpImage )
472 {
473     DWORD x;
474     int h;
475     const BYTE *bits = srcbits + left;
476
477     /* align to 32 bit */
478     DWORD linebytes = (srcwidth + 3) & ~3;
479
480     dstwidth+=left;
481
482     if (lines > 0) {
483         for (h = lines - 1; h >= 0; h--) {
484             for (x = left; x < dstwidth; x++, bits++) {
485                 XPutPixel( bmpImage, x, h, colors[*bits] );
486             }
487             bits = (srcbits += linebytes) + left;
488         }
489     } else {
490         lines = -lines;
491         for (h = 0; h < lines; h++) {
492             for (x = left; x < dstwidth; x++, bits++) {
493                 XPutPixel( bmpImage, x, h, colors[*bits] );
494             }
495             bits = (srcbits += linebytes) + left;
496         }
497     }
498 }
499
500 /***********************************************************************
501  *            DIB_SetImageBits_RLE8
502  *
503  * SetDIBits for an 8-bit deep compressed DIB.
504  *
505  * This function rewritten 941113 by James Youngman.  WINE blew out when I
506  * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.  
507  *
508  * This was because the algorithm assumed that all RLE8 bitmaps end with the  
509  * 'End of bitmap' escape code.  This code is very much laxer in what it
510  * allows to end the expansion.  Possibly too lax.  See the note by 
511  * case RleDelta.  BTW, MS's documentation implies that a correct RLE8
512  * bitmap should end with RleEnd, but on the other hand, software exists 
513  * that produces ones that don't and Windows 3.1 doesn't complain a bit
514  * about it.
515  *
516  * (No) apologies for my English spelling.  [Emacs users: c-indent-level=4].
517  *                      James A. Youngman <mbcstjy@afs.man.ac.uk>
518  *                                              [JAY]
519  */
520
521 enum Rle8_EscapeCodes           
522 {
523   /* 
524    * Apologies for polluting your file's namespace...
525    */
526   RleEol        = 0,            /* End of line */
527   RleEnd        = 1,            /* End of bitmap */
528   RleDelta      = 2             /* Delta */
529 };
530   
531 static void DIB_SetImageBits_RLE8( int lines, const BYTE *bits, DWORD width,
532                                 DWORD dstwidth, int left, int *colors, XImage *bmpImage )
533 {
534     int x;                      /* X-positon on each line.  Increases. */
535     int line;                   /* Line #.  Starts at lines-1, decreases */
536     const BYTE *pIn = bits;     /* Pointer to current position in bits */
537     BYTE length;                /* The length pf a run */
538     BYTE color_index;           /* index into colors[] as read from bits */
539     BYTE escape_code;           /* See enum Rle8_EscapeCodes.*/
540     WORD color;                 /* value of colour[color_index] */
541     
542     if (lines == 0)             /* Let's hope this doesn't happen. */
543       return;
544     
545     dstwidth += left; /* FIXME: avoid putting x<left pixels */
546
547     /*
548      * Note that the bitmap data is stored by Windows starting at the
549      * bottom line of the bitmap and going upwards.  Within each line,
550      * the data is stored left-to-right.  That's the reason why line
551      * goes from lines-1 to 0.                  [JAY]
552      */
553     
554     x = 0;
555     line = lines-1;
556     do
557       {
558           length = *pIn++;
559           
560           /* 
561            * If the length byte is not zero (which is the escape value),
562            * We have a run of length pixels all the same colour.  The colour 
563            * index is stored next. 
564            *
565            * If the length byte is zero, we need to read the next byte to
566            * know what to do.                   [JAY]
567            */
568           if (length != 0) 
569             {                                   
570                 /* 
571                  * [Run-Length] Encoded mode 
572                  */
573                 color_index = (*pIn++); /* Get the colour index. */
574                 color = colors[color_index];
575
576                 while(length--)
577                   XPutPixel(bmpImage, x++, line, color);
578             }
579           else 
580             {    
581                 /* 
582                  * Escape codes (may be an absolute sequence though)
583                  */
584                 escape_code = (*pIn++);
585                 switch(escape_code)
586                   {
587                     case RleEol: /* =0, end of line */
588                       {
589                           x = 0;  
590                           line--;  
591                           break;
592                       }
593                       
594                     case RleEnd: /* =1, end of bitmap */
595                       {
596                           /*
597                            * Not all RLE8 bitmaps end with this 
598                            * code.  For example, Paint Shop Pro 
599                            * produces some that don't.  That's (I think)
600                            * what caused the previous implementation to 
601                            * fail.                      [JAY]
602                            */
603                           line=-1; /* Cause exit from do loop. */
604                           break;
605                       }
606                       
607                     case RleDelta: /* =2, a delta */
608                       {
609                           /* 
610                            * Note that deltaing to line 0 
611                            * will cause an exit from the loop, 
612                            * which may not be what is intended. 
613                            * The fact that there is a delta in the bits
614                            * almost certainly implies that there is data
615                            * to follow.  You may feel that we should 
616                            * jump to the top of the loop to avoid exiting
617                            * in this case.  
618                            *
619                            * TODO: Decide what to do here in that case. [JAY]
620                            */
621                           x     += (*pIn++); 
622                           line  -= (*pIn++);
623                           if (line == 0)
624                             {
625                               TRACE(bitmap, "Delta to last line of bitmap "
626                                            "(wrongly?) causes loop exit\n");
627                             }
628                           break;
629                       }
630                       
631                     default:    /* >2, switch to absolute mode */
632                       {
633                           /* 
634                            * Absolute Mode 
635                            */
636                           length = escape_code;
637                           while(length--)
638                             {
639                                 color_index = (*pIn++);
640                                 XPutPixel(bmpImage, x++, line, 
641                                           colors[color_index]);
642                             }
643                           
644                           /*
645                            * If you think for a moment you'll realise that the
646                            * only time we could ever possibly read an odd
647                            * number of bytes is when there is a 0x00 (escape),
648                            * a value >0x02 (absolute mode) and then an odd-
649                            * length run.  Therefore this is the only place we
650                            * need to worry about it.  Everywhere else the
651                            * bytes are always read in pairs.  [JAY]
652                            */
653                           if (escape_code & 1) 
654                             pIn++; /* Throw away the pad byte. */
655                           break;
656                       }
657                   } /* switch (escape_code) : Escape sequence */
658             }  /* process either an encoded sequence or an escape sequence */
659           
660           /* We expect to come here more than once per line. */
661       } while (line >= 0);  /* Do this until the bitmap is filled */
662     
663     /*
664      * Everybody comes here at the end.
665      * Check how we exited the loop and print a message if it's a bit odd.
666      *                                          [JAY]
667      */
668     if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) )
669       {
670         TRACE(bitmap, "End-of-bitmap "
671                        "without (strictly) proper escape code.  Last two "
672                        "bytes were: %02X %02X.\n",
673                        (int)*(pIn-2),
674                        (int)*(pIn-1));           
675       }
676 }  
677
678
679 /***********************************************************************
680  *           DIB_SetImageBits_16
681  *
682  * SetDIBits for a 16-bit deep DIB.
683  */
684 static void DIB_SetImageBits_16( int lines, const BYTE *srcbits,
685                                  DWORD srcwidth, DWORD dstwidth, int left,
686                                  DC *dc, XImage *bmpImage )
687 {
688     DWORD x;
689     LPWORD ptr;
690     WORD val;
691     int h;
692     BYTE r, g, b;
693   
694     /* align to 32 bit */
695     DWORD linebytes = (srcwidth * 2 + 3) & ~3;
696
697     dstwidth += left;
698
699     ptr = (LPWORD) srcbits + left;
700     if (lines > 0) {
701         for (h = lines - 1; h >= 0; h--) {
702             for (x = left; x < dstwidth; x++, ptr++) {
703                 val = *ptr;
704                 r = (BYTE) ((val & 0x7c00) >> 7);
705                 g = (BYTE) ((val & 0x03e0) >> 2);
706                 b = (BYTE) ((val & 0x001f) << 3);
707                 XPutPixel( bmpImage, x, h,
708                            COLOR_ToPhysical(dc, RGB(r,g,b)) );
709             }
710             ptr = (LPWORD) (srcbits += linebytes) + left;
711         }
712     } else {
713         lines = -lines;
714         for (h = 0; h < lines; h++) {
715             for (x = left; x < dstwidth; x++, ptr++) {
716                 val = *ptr;
717                 r = (BYTE) ((val & 0x7c00) >> 7);
718                 g = (BYTE) ((val & 0x03e0) >> 2);
719                 b = (BYTE) ((val & 0x001f) << 3);
720                 XPutPixel( bmpImage, x, h,
721                            COLOR_ToPhysical(dc, RGB(r,g,b)) );
722             }
723             ptr = (LPWORD) (srcbits += linebytes) + left;
724         }
725     }
726 }
727
728
729 /***********************************************************************
730  *           DIB_SetImageBits_24
731  *
732  * SetDIBits for a 24-bit deep DIB.
733  */
734 static void DIB_SetImageBits_24( int lines, const BYTE *srcbits,
735                                  DWORD srcwidth, DWORD dstwidth, int left,
736                                  DC *dc, XImage *bmpImage )
737 {
738     DWORD x;
739     const BYTE *bits = srcbits + left * 3;
740     int h;
741   
742     /* align to 32 bit */
743     DWORD linebytes = (srcwidth * 3 + 3) & ~3;
744
745     dstwidth += left;
746
747     /* "bits" order is reversed for some reason */
748
749     if (lines > 0) {
750         for (h = lines - 1; h >= 0; h--) {
751             for (x = left; x < dstwidth; x++, bits += 3) {
752                 XPutPixel( bmpImage, x, h, 
753                            COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
754             }
755             bits = (srcbits += linebytes) + left * 3;
756         }
757     } else {
758         lines = -lines;
759         for (h = 0; h < lines; h++) {
760             for (x = left; x < dstwidth; x++, bits += 3) {
761                 XPutPixel( bmpImage, x, h,
762                            COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
763             }
764             bits = (srcbits += linebytes) + left * 3;
765         }
766     }
767 }
768
769
770 /***********************************************************************
771  *           DIB_SetImageBits_32
772  *
773  * SetDIBits for a 32-bit deep DIB.
774  */
775 static void DIB_SetImageBits_32( int lines, const BYTE *srcbits,
776                                  DWORD srcwidth, DWORD dstwidth, int left,
777                                  DC *dc, XImage *bmpImage )
778 {
779     DWORD x;
780     const BYTE *bits = srcbits + left * 4;
781     int h;
782   
783     DWORD linebytes = (srcwidth * 4);
784
785     dstwidth += left;
786
787     if (lines > 0) {
788         for (h = lines - 1; h >= 0; h--) {
789             for (x = left; x < dstwidth; x++, bits += 4) {
790                 XPutPixel( bmpImage, x, h, 
791                            COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
792             }
793             bits = (srcbits += linebytes) + left * 4;
794         }
795     } else {
796         lines = -lines;
797         for (h = 0; h < lines; h++) {
798             for (x = left; x < dstwidth; x++, bits += 4) {
799                 XPutPixel( bmpImage, x, h,
800                            COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
801             }
802             bits = (srcbits += linebytes) + left * 4;
803         }
804     }
805 }
806
807
808 /***********************************************************************
809  *           DIB_SetImageBits
810  *
811  * Transfer the bits to an X image.
812  * Helper function for SetDIBits() and SetDIBitsToDevice().
813  * The Xlib critical section must be entered before calling this function.
814  */
815 static int DIB_SetImageBits( const DIB_SETIMAGEBITS_DESCR *descr )
816 {
817     int *colorMapping;
818     XImage *bmpImage;
819     int lines;
820
821       /* Translate the color mapping table */
822
823     if (descr->infoBpp > 8) colorMapping = NULL;
824     else if (!(colorMapping = DIB_PhysicalColorMap( descr->dc, descr->depth,
825                                                     descr->colorMap, descr->nColorMap )))
826         return 0;
827
828     if( descr->dc->w.flags & DC_DIRTY ) CLIPPING_UpdateGCRegion(descr->dc);
829
830       /* Transfer the pixels */
831     lines = descr->lines;
832     if (lines < 0) lines = -lines;
833     XCREATEIMAGE(bmpImage, descr->infoWidth, lines, descr->depth );
834
835     switch(descr->infoBpp)
836     {
837     case 1:
838         DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
839                             descr->width, descr->xSrc, colorMapping, bmpImage );
840         break;
841     case 4:
842         if (descr->compression) DIB_SetImageBits_RLE4( descr->lines, descr->bits,
843                                                 descr->infoWidth, descr->width, descr->xSrc,
844                                                 colorMapping, bmpImage );
845         else DIB_SetImageBits_4( descr->lines, descr->bits, descr->infoWidth,
846                                  descr->width, descr->xSrc, colorMapping, bmpImage );
847         break;
848     case 8:
849         if (descr->compression) DIB_SetImageBits_RLE8( descr->lines, descr->bits,
850                                                 descr->infoWidth, descr->width, descr->xSrc,
851                                                 colorMapping, bmpImage );
852         else DIB_SetImageBits_8( descr->lines, descr->bits, descr->infoWidth,
853                                  descr->width, descr->xSrc, colorMapping, bmpImage );
854         break;
855     case 15:
856     case 16:
857         DIB_SetImageBits_16( descr->lines, descr->bits, descr->infoWidth,
858                              descr->width, descr->xSrc, descr->dc, bmpImage);
859         break;
860     case 24:
861         DIB_SetImageBits_24( descr->lines, descr->bits, descr->infoWidth,
862                              descr->width, descr->xSrc, descr->dc, bmpImage );
863         break;
864     case 32:
865         DIB_SetImageBits_32( descr->lines, descr->bits, descr->infoWidth,
866                              descr->width, descr->xSrc, descr->dc, bmpImage);
867         break;
868     default:
869         WARN(bitmap, "(%d): Invalid depth\n", descr->infoBpp );
870         break;
871     }
872     if (colorMapping) HeapFree( GetProcessHeap(), 0, colorMapping );
873     XPutImage( display, descr->drawable, descr->gc, bmpImage,
874                descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
875                descr->width, descr->height );
876     XDestroyImage( bmpImage );
877     return lines;
878 }
879
880
881 /***********************************************************************
882  *           StretchDIBits16   (GDI.439)
883  */
884 INT16 WINAPI StretchDIBits16(HDC16 hdc, INT16 xDst, INT16 yDst, INT16 widthDst,
885                        INT16 heightDst, INT16 xSrc, INT16 ySrc, INT16 widthSrc,
886                        INT16 heightSrc, const VOID *bits,
887                        const BITMAPINFO *info, UINT16 wUsage, DWORD dwRop )
888 {
889     return (INT16)StretchDIBits32( hdc, xDst, yDst, widthDst, heightDst,
890                                    xSrc, ySrc, widthSrc, heightSrc, bits,
891                                    info, wUsage, dwRop );
892 }
893
894
895 /***********************************************************************
896  *           StretchDIBits32   (GDI32.351)
897  */
898 INT32 WINAPI StretchDIBits32(HDC32 hdc, INT32 xDst, INT32 yDst, INT32 widthDst,
899                        INT32 heightDst, INT32 xSrc, INT32 ySrc, INT32 widthSrc,
900                        INT32 heightSrc, const void *bits,
901                        const BITMAPINFO *info, UINT32 wUsage, DWORD dwRop )
902 {
903     HBITMAP32 hBitmap, hOldBitmap;
904     HDC32 hdcMem;
905
906     hBitmap = CreateDIBitmap32( hdc, &info->bmiHeader, CBM_INIT,
907                                 bits, info, wUsage );
908     hdcMem = CreateCompatibleDC32( hdc );
909     hOldBitmap = SelectObject32( hdcMem, hBitmap );
910     StretchBlt32( hdc, xDst, yDst, widthDst, heightDst,
911                   hdcMem, xSrc, ySrc, widthSrc, heightSrc, dwRop );
912     SelectObject32( hdcMem, hOldBitmap );
913     DeleteDC32( hdcMem );
914     DeleteObject32( hBitmap );
915     return heightSrc;
916 }
917
918
919 /***********************************************************************
920  *           SetDIBits16    (GDI.440)
921  */
922 INT16 WINAPI SetDIBits16( HDC16 hdc, HBITMAP16 hbitmap, UINT16 startscan,
923                           UINT16 lines, LPCVOID bits, const BITMAPINFO *info,
924                           UINT16 coloruse )
925 {
926     return SetDIBits32( hdc, hbitmap, startscan, lines, bits, info, coloruse );
927 }
928
929
930 /******************************************************************************
931  * SetDIBits32 [GDI32.312]  Sets pixels in a bitmap using colors from DIB
932  *
933  * PARAMS
934  *    hdc       [I] Handle to device context
935  *    hbitmap   [I] Handle to bitmap
936  *    startscan [I] Starting scan line
937  *    lines     [I] Number of scan lines
938  *    bits      [I] Array of bitmap bits
939  *    info      [I] Address of structure with data
940  *    coloruse  [I] Type of color indexes to use
941  *
942  * RETURNS
943  *    Success: Number of scan lines copied
944  *    Failure: 0
945  */
946 INT32 WINAPI SetDIBits32( HDC32 hdc, HBITMAP32 hbitmap, UINT32 startscan,
947                           UINT32 lines, LPCVOID bits, const BITMAPINFO *info,
948                           UINT32 coloruse )
949 {
950     DIB_SETIMAGEBITS_DESCR descr;
951     BITMAPOBJ * bmp;
952     int height, tmpheight;
953     INT32 result;
954
955       /* Check parameters */
956
957     descr.dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
958     if (!descr.dc) 
959     {
960         descr.dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
961         if (!descr.dc) return 0;
962     }
963     if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
964     {
965         GDI_HEAP_UNLOCK( hdc );
966         return 0;
967     }
968     if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
969                            &descr.infoBpp, &descr.compression ) == -1)
970     {
971         GDI_HEAP_UNLOCK( hbitmap );
972         GDI_HEAP_UNLOCK( hdc );
973         return 0;
974     }
975     tmpheight = height;
976     if (height < 0) height = -height;
977     if (!lines || (startscan >= height))
978     {
979         GDI_HEAP_UNLOCK( hbitmap );
980         GDI_HEAP_UNLOCK( hdc );
981         return 0;
982     }
983     if (startscan + lines > height) lines = height - startscan;
984
985     if (descr.infoBpp <= 8)
986     {
987         descr.colorMap = DIB_BuildColorMap( info, coloruse == DIB_PAL_COLORS?
988                                             descr.dc->w.hPalette : 0, 
989                                             &descr.nColorMap);
990
991         if (!descr.colorMap)
992         {
993             GDI_HEAP_UNLOCK( hbitmap );
994             GDI_HEAP_UNLOCK( hdc );
995             return 0;
996         } 
997     }
998
999
1000
1001     descr.bits      = bits;
1002     descr.lines     = tmpheight >= 0 ? lines : -lines;
1003     descr.depth     = bmp->bitmap.bmBitsPixel;
1004     descr.drawable  = bmp->pixmap;
1005     descr.gc        = BITMAP_GC(bmp);
1006     descr.xSrc      = 0;
1007     descr.ySrc      = 0;
1008     descr.xDest     = 0;
1009     descr.yDest     = height - startscan - lines;
1010     descr.width     = bmp->bitmap.bmWidth;
1011     descr.height    = lines;
1012
1013     EnterCriticalSection( &X11DRV_CritSection );
1014     result = CALL_LARGE_STACK( DIB_SetImageBits, &descr );
1015     LeaveCriticalSection( &X11DRV_CritSection );
1016
1017     HeapFree(GetProcessHeap(), 0, descr.colorMap);
1018
1019     GDI_HEAP_UNLOCK( hdc );
1020     GDI_HEAP_UNLOCK( hbitmap );
1021     return result;
1022 }
1023
1024
1025 /***********************************************************************
1026  *           SetDIBitsToDevice16    (GDI.443)
1027  */
1028 INT16 WINAPI SetDIBitsToDevice16(HDC16 hdc, INT16 xDest, INT16 yDest, INT16 cx,
1029                            INT16 cy, INT16 xSrc, INT16 ySrc, UINT16 startscan,
1030                            UINT16 lines, LPCVOID bits, const BITMAPINFO *info,
1031                            UINT16 coloruse )
1032 {
1033     return SetDIBitsToDevice32( hdc, xDest, yDest, cx, cy, xSrc, ySrc,
1034                                 startscan, lines, bits, info, coloruse );
1035 }
1036
1037
1038 /***********************************************************************
1039  *           SetDIBitsToDevice32   (GDI32.313)
1040  */
1041 INT32 WINAPI SetDIBitsToDevice32(HDC32 hdc, INT32 xDest, INT32 yDest, DWORD cx,
1042                            DWORD cy, INT32 xSrc, INT32 ySrc, UINT32 startscan,
1043                            UINT32 lines, LPCVOID bits, const BITMAPINFO *info,
1044                            UINT32 coloruse )
1045 {
1046     DIB_SETIMAGEBITS_DESCR descr;
1047     DC * dc;
1048     DWORD width, oldcy = cy;
1049     INT32 result;
1050     int height, tmpheight;
1051
1052       /* Check parameters */
1053
1054     dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1055     if (!dc) 
1056     {
1057         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
1058         if (!dc) return 0;
1059     }
1060     if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, 
1061                            &descr.infoBpp, &descr.compression ) == -1)
1062         return 0;
1063     tmpheight = height;
1064     if (height < 0) height = -height;
1065     if (!lines || (startscan >= height)) return 0;
1066     if (startscan + lines > height) lines = height - startscan;
1067     if (ySrc < startscan) ySrc = startscan;
1068     else if (ySrc >= startscan + lines) return 0;
1069     if (xSrc >= width) return 0;
1070     if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
1071     if (xSrc + cx >= width) cx = width - xSrc;
1072     if (!cx || !cy) return 0;
1073
1074     DC_SetupGCForText( dc );  /* To have the correct colors */
1075     TSXSetFunction( display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] );
1076
1077     descr.dc = dc;
1078     if (descr.infoBpp <= 8)
1079     {
1080         descr.colorMap = DIB_BuildColorMap( info, coloruse == DIB_PAL_COLORS?
1081                                             descr.dc->w.hPalette : 0, 
1082                                             &descr.nColorMap );
1083
1084         if (!descr.colorMap)
1085             return 0;
1086     }
1087     descr.bits      = bits;
1088     descr.lines     = tmpheight >= 0 ? lines : -lines;
1089     descr.infoWidth = width;
1090     descr.depth     = dc->w.bitsPerPixel;
1091     descr.drawable  = dc->u.x.drawable;
1092     descr.gc        = dc->u.x.gc;
1093     descr.xSrc      = xSrc;
1094     descr.ySrc      = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy) : ySrc - startscan;
1095     descr.xDest     = dc->w.DCOrgX + XLPTODP( dc, xDest );
1096     descr.yDest     = dc->w.DCOrgY + YLPTODP( dc, yDest ) + (tmpheight >= 0 ? oldcy-cy : 0);
1097     descr.width     = cx;
1098     descr.height    = cy;
1099
1100     EnterCriticalSection( &X11DRV_CritSection );
1101     result = CALL_LARGE_STACK( DIB_SetImageBits, &descr );
1102     LeaveCriticalSection( &X11DRV_CritSection );
1103
1104     HeapFree(GetProcessHeap(), 0, descr.colorMap);
1105     return result;
1106 }
1107
1108 /***********************************************************************
1109  *           SetDIBColorTable32    (GDI32.311)
1110  */
1111 UINT32 WINAPI SetDIBColorTable32( HDC32 hdc, UINT32 startpos, UINT32 entries,
1112                                   RGBQUAD *colors )
1113 {
1114     DC * dc;
1115     PALETTEENTRY * palEntry;
1116     PALETTEOBJ * palette;
1117     RGBQUAD *end;
1118
1119     dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1120     if (!dc) 
1121     {
1122         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
1123         if (!dc) return 0;
1124     }
1125
1126     if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
1127     {
1128         return 0;
1129     }
1130
1131     /* Transfer color info */
1132     
1133     if (dc->w.bitsPerPixel <= 8) {
1134         palEntry = palette->logpalette.palPalEntry + startpos;
1135         if (startpos + entries > (1 << dc->w.bitsPerPixel)) {
1136             entries = (1 << dc->w.bitsPerPixel) - startpos;
1137         }
1138         for (end = colors + entries; colors < end; palEntry++, colors++)
1139         {
1140             palEntry->peRed   = colors->rgbRed;
1141             palEntry->peGreen = colors->rgbGreen;
1142             palEntry->peBlue  = colors->rgbBlue;
1143         }
1144     } else {
1145         entries = 0;
1146     }
1147     GDI_HEAP_UNLOCK( dc->w.hPalette );
1148     return entries;
1149 }
1150
1151 /***********************************************************************
1152  *           GetDIBColorTable32    (GDI32.169)
1153  */
1154 UINT32 WINAPI GetDIBColorTable32( HDC32 hdc, UINT32 startpos, UINT32 entries,
1155                                   RGBQUAD *colors )
1156 {
1157     DC * dc;
1158     PALETTEENTRY * palEntry;
1159     PALETTEOBJ * palette;
1160     RGBQUAD *end;
1161
1162     dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1163     if (!dc) 
1164     {
1165         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
1166         if (!dc) return 0;
1167     }
1168
1169     if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
1170     {
1171         return 0;
1172     }
1173
1174     /* Transfer color info */
1175     
1176     if (dc->w.bitsPerPixel <= 8) {
1177         palEntry = palette->logpalette.palPalEntry + startpos;
1178         if (startpos + entries > (1 << dc->w.bitsPerPixel)) {
1179             entries = (1 << dc->w.bitsPerPixel) - startpos;
1180         }
1181         for (end = colors + entries; colors < end; palEntry++, colors++)
1182         {
1183             colors->rgbRed      = palEntry->peRed;
1184             colors->rgbGreen    = palEntry->peGreen;
1185             colors->rgbBlue     = palEntry->peBlue;
1186             colors->rgbReserved = 0;
1187         }
1188     } else {
1189         entries = 0;
1190     }
1191     GDI_HEAP_UNLOCK( dc->w.hPalette );
1192     return entries;
1193 }
1194
1195 /***********************************************************************
1196  *           GetDIBits16    (GDI.441)
1197  */
1198 INT16 WINAPI GetDIBits16( HDC16 hdc, HBITMAP16 hbitmap, UINT16 startscan,
1199                           UINT16 lines, LPSTR bits, BITMAPINFO * info,
1200                           UINT16 coloruse )
1201 {
1202     return GetDIBits32( hdc, hbitmap, startscan, lines, bits, info, coloruse );
1203 }
1204
1205
1206 /******************************************************************************
1207  * GetDIBits32 [GDI32.170]  Retrieves bits of bitmap and copies to buffer
1208  *
1209  * RETURNS
1210  *    Success: Number of scan lines copied from bitmap
1211  *    Failure: 0
1212  *
1213  * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/func/src/f30_14.htm
1214  */
1215 INT32 WINAPI GetDIBits32(
1216     HDC32 hdc,         /* [in]  Handle to device context */
1217     HBITMAP32 hbitmap, /* [in]  Handle to bitmap */
1218     UINT32 startscan,  /* [in]  First scan line to set in dest bitmap */
1219     UINT32 lines,      /* [in]  Number of scan lines to copy */
1220     LPSTR bits,        /* [out] Address of array for bitmap bits */
1221     BITMAPINFO * info, /* [out] Address of structure with bitmap data */
1222     UINT32 coloruse)   /* [in]  RGB or palette index */
1223 {
1224     DC * dc;
1225     BITMAPOBJ * bmp;
1226     PALETTEENTRY * palEntry;
1227     PALETTEOBJ * palette;
1228     XImage * bmpImage;
1229     int i, x, y;
1230
1231     if (!lines) return 0;
1232     dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1233     if (!dc) 
1234     {
1235         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
1236         if (!dc) return 0;
1237     }
1238     if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
1239         return 0;
1240     if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
1241     {
1242         GDI_HEAP_UNLOCK( hbitmap );
1243         return 0;
1244     }
1245
1246       /* Transfer color info */
1247     
1248     if (info->bmiHeader.biBitCount<=8) {
1249         palEntry = palette->logpalette.palPalEntry;
1250         for (i = 0; i < info->bmiHeader.biClrUsed; i++, palEntry++)
1251         {
1252             if (coloruse == DIB_RGB_COLORS)
1253             {
1254                 info->bmiColors[i].rgbRed      = palEntry->peRed;
1255                 info->bmiColors[i].rgbGreen    = palEntry->peGreen;
1256                 info->bmiColors[i].rgbBlue     = palEntry->peBlue;
1257                 info->bmiColors[i].rgbReserved = 0;
1258             }
1259             else ((WORD *)info->bmiColors)[i] = (WORD)i;
1260         }
1261     }
1262
1263     if (bits)
1264     {   
1265         BYTE*   bbits = bits;
1266         int     pad, yend, xend = bmp->bitmap.bmWidth;
1267
1268         TRACE(bitmap, "%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
1269                             lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
1270                             (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight, startscan );
1271
1272         /* adjust number of scanlines to copy */
1273
1274         if( lines > info->bmiHeader.biHeight ) lines = info->bmiHeader.biHeight;
1275         yend = startscan + lines;
1276         if( startscan >= bmp->bitmap.bmHeight ) 
1277         {
1278             GDI_HEAP_UNLOCK( hbitmap );
1279             GDI_HEAP_UNLOCK( dc->w.hPalette );
1280             return FALSE;
1281         }
1282         if( yend > bmp->bitmap.bmHeight ) yend = bmp->bitmap.bmHeight;
1283
1284         /* adjust scanline width */
1285
1286         pad = info->bmiHeader.biWidth - bmp->bitmap.bmWidth;
1287         if( pad < 0 ) 
1288         {
1289             /* bitmap is wider than DIB, copy only a part */
1290
1291             pad = 0;
1292             xend = info->bmiHeader.biWidth;
1293         }
1294
1295         EnterCriticalSection( &X11DRV_CritSection );
1296         bmpImage = (XImage *)CALL_LARGE_STACK( BITMAP_GetXImage, bmp );
1297
1298         switch( info->bmiHeader.biBitCount )
1299         {
1300            case 8:
1301                 /* pad up to 32 bit */
1302                 pad += (4 - (info->bmiHeader.biWidth & 3)) & 3;
1303                 for( y = yend - 1; (int)y >= (int)startscan; y-- )
1304                 {
1305                    for( x = 0; x < xend; x++ )
1306                         *bbits++ = XGetPixel( bmpImage, x, y );
1307                    bbits += pad;
1308                 }
1309                 break;
1310            case 1:
1311                 pad += ((32 - (info->bmiHeader.biWidth & 31)) / 8) & 3;
1312                 for( y = yend - 1; (int)y >= (int)startscan; y-- )
1313                 {
1314                    *bbits = 0;
1315                    for( x = 0; x < xend; x++ ) {
1316                         
1317                         *bbits |= XGetPixel( bmpImage, x, y)<<(7-(x&7));
1318                         if ((x&7)==7) {
1319                             bbits++;
1320                             *bbits=0;
1321                         }
1322                    }
1323                    bbits += pad;
1324                 }
1325                 break;
1326            case 4:
1327                 pad += ((8 - (info->bmiHeader.biWidth & 7)) / 2) & 3;
1328                 for( y = yend - 1; (int)y >= (int)startscan; y-- )
1329                 {
1330                    *bbits = 0;
1331                    for( x = 0; x < xend; x++ ) {
1332                         
1333                         *bbits |= XGetPixel( bmpImage, x, y)<<(4*(1-(x&1)));
1334                         if ((x&1)==1) {
1335                             bbits++;
1336                             *bbits=0;
1337                         }
1338                    }
1339                    bbits += pad;
1340                 }
1341                 break;
1342            case 15:
1343            case 16:
1344                 pad += (4 - ((info->bmiHeader.biWidth*2) & 3)) & 3;
1345                 for( y = yend - 1; (int)y >= (int)startscan; y-- )
1346                 {
1347                    *bbits = 0;
1348                    for( x = 0; x < xend; x++ ) {
1349                         unsigned long pixel=XGetPixel( bmpImage, x, y);
1350                         *bbits++ = pixel & 0xff;
1351                         *bbits++ = (pixel >> 8) & 0xff;
1352                    }
1353                    bbits += pad;
1354                 }
1355                 break;
1356            case 24:
1357                 pad += (4 - ((info->bmiHeader.biWidth*3) & 3)) & 3;
1358                 for( y = yend - 1; (int)y >= (int)startscan; y-- )
1359                 {
1360                    *bbits = 0;
1361                    for( x = 0; x < xend; x++ ) {
1362                         unsigned long pixel=XGetPixel( bmpImage, x, y);
1363                         *bbits++ = (pixel >>16) & 0xff;
1364                         *bbits++ = (pixel >> 8) & 0xff;
1365                         *bbits++ =  pixel       & 0xff;
1366                    }
1367                    bbits += pad;
1368                 }
1369                 break;
1370            case 32:
1371                 for( y = yend - 1; (int)y >= (int)startscan; y-- )
1372                 {
1373                    *bbits = 0;
1374                    for( x = 0; x < xend; x++ ) {
1375                         unsigned long pixel=XGetPixel( bmpImage, x, y);
1376                         *bbits++ = (pixel >>16) & 0xff;
1377                         *bbits++ = (pixel >> 8) & 0xff;
1378                         *bbits++ =  pixel       & 0xff;
1379                    }
1380                 }
1381                 break;
1382            default:
1383                 WARN(bitmap,"Unsupported depth %d\n",
1384                    info->bmiHeader.biBitCount);
1385                 break;
1386         }
1387
1388         XDestroyImage( bmpImage );
1389         LeaveCriticalSection( &X11DRV_CritSection );
1390
1391         info->bmiHeader.biCompression = 0;
1392     }
1393     else if( info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) ) 
1394     {
1395         /* fill in struct members */
1396         
1397         info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
1398         info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
1399         info->bmiHeader.biPlanes = 1;
1400         info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
1401         info->bmiHeader.biSizeImage = bmp->bitmap.bmHeight *
1402                              DIB_GetDIBWidthBytes( bmp->bitmap.bmWidth,
1403                                                    bmp->bitmap.bmBitsPixel );
1404         info->bmiHeader.biCompression = 0;
1405     }
1406
1407     GDI_HEAP_UNLOCK( hbitmap );
1408     GDI_HEAP_UNLOCK( dc->w.hPalette );
1409     return lines;
1410 }
1411
1412
1413 /***********************************************************************
1414  *           CreateDIBitmap16    (GDI.442)
1415  */
1416 HBITMAP16 WINAPI CreateDIBitmap16( HDC16 hdc, const BITMAPINFOHEADER * header,
1417                             DWORD init, LPCVOID bits, const BITMAPINFO * data,
1418                             UINT16 coloruse )
1419 {
1420     return CreateDIBitmap32( hdc, header, init, bits, data, coloruse );
1421 }
1422
1423
1424 /***********************************************************************
1425  *           CreateDIBitmap32    (GDI32.37)
1426  */
1427 HBITMAP32 WINAPI CreateDIBitmap32( HDC32 hdc, const BITMAPINFOHEADER *header,
1428                             DWORD init, LPCVOID bits, const BITMAPINFO *data,
1429                             UINT32 coloruse )
1430 {
1431     HBITMAP32 handle;
1432     BOOL32 fColor;
1433     DWORD width;
1434     int height;
1435     WORD bpp;
1436     WORD compr;
1437
1438     if (DIB_GetBitmapInfo( header, &width, &height, &bpp, &compr ) == -1) return 0;
1439     if (height < 0) height = -height;
1440
1441     /* Check if we should create a monochrome or color bitmap. */
1442     /* We create a monochrome bitmap only if it has exactly 2  */
1443     /* colors, which are either black or white, nothing else.  */
1444     /* In all other cases, we create a color bitmap.           */
1445
1446     if (bpp != 1) fColor = TRUE;
1447     else if ((coloruse != DIB_RGB_COLORS) ||
1448              (init != CBM_INIT) || !data) fColor = FALSE;
1449     else
1450     {
1451         if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
1452         {
1453             RGBQUAD *rgb = data->bmiColors;
1454             DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
1455             if ((col == RGB(0,0,0)) || (col == RGB(0xff,0xff,0xff)))
1456             {
1457                 rgb++;
1458                 col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
1459                 fColor = ((col != RGB(0,0,0)) && (col != RGB(0xff,0xff,0xff)));
1460             }
1461             else fColor = TRUE;
1462         }
1463         else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
1464         {
1465             RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
1466             DWORD col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
1467             if ((col == RGB(0,0,0)) || (col == RGB(0xff,0xff,0xff)))
1468             {
1469                 rgb++;
1470                 col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
1471                 fColor = ((col != RGB(0,0,0)) && (col != RGB(0xff,0xff,0xff)));
1472             }
1473             else fColor = TRUE;
1474         }
1475         else
1476         {
1477             WARN(bitmap, "(%ld): wrong size for data\n",
1478                      data->bmiHeader.biSize );
1479             return 0;
1480         }
1481     }
1482
1483     /* Now create the bitmap */
1484
1485     handle = fColor ? CreateBitmap32( width, height, 1, screenDepth, NULL ) :
1486                       CreateBitmap32( width, height, 1, 1, NULL );
1487     if (!handle) return 0;
1488
1489     if (init == CBM_INIT)
1490         SetDIBits32( hdc, handle, 0, height, bits, data, coloruse );
1491     return handle;
1492 }
1493
1494 /***********************************************************************
1495  *           CreateDIBSection16    (GDI.489)
1496  */
1497 HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, BITMAPINFO *bmi, UINT16 usage,
1498                                      LPVOID **bits, HANDLE16 section,
1499                                      DWORD offset)
1500 {
1501     return CreateDIBSection32(hdc, bmi, usage, bits, section, offset);
1502 }
1503
1504 /***********************************************************************
1505  *           CreateDIBSection32    (GDI32.36)
1506  */
1507 HBITMAP32 WINAPI CreateDIBSection32 (HDC32 hdc, BITMAPINFO *bmi, UINT32 usage,
1508                                      LPVOID **bits,HANDLE32 section,
1509                                      DWORD offset)
1510 {
1511     HBITMAP32 res = 0;
1512     BITMAPOBJ *bmp = NULL;
1513     DIBSECTION *dib = NULL;
1514     RGBQUAD *colorMap = NULL;
1515     int nColorMap;
1516
1517     /* Fill BITMAP32 structure with DIB data */
1518     BITMAPINFOHEADER *bi = &bmi->bmiHeader;
1519     BITMAP32 bm;
1520
1521     TRACE(bitmap, "format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
1522           bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
1523           bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1524
1525     if (bi->biCompression)
1526     {
1527         FIXME(bitmap, "Compression not implemented!\n");
1528         return 0;
1529     }
1530
1531     bm.bmType = 0;
1532     bm.bmWidth = bi->biWidth;
1533     bm.bmHeight = bi->biHeight;
1534     bm.bmWidthBytes = DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
1535     bm.bmPlanes = bi->biPlanes;
1536     bm.bmBitsPixel = bi->biBitCount;
1537     bm.bmBits = NULL;
1538
1539     /* Get storage location for DIB bits */
1540     if (section)
1541         FIXME(bitmap, "section != NULL not implemented!\n");    
1542     else
1543     {
1544         INT32 totalSize = bi->biSizeImage? bi->biSizeImage
1545                                          : bm.bmWidthBytes * bm.bmHeight;
1546
1547         bm.bmBits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, totalSize);
1548     }
1549
1550     /* Allocate Memory for DIB and fill structure */
1551     if (bm.bmBits)
1552         dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DIBSECTION));
1553     if (dib)
1554     {
1555         dib->dsBm = bm;
1556         dib->dsBmih = *bi;
1557         /* FIXME: dib->dsBitfields ??? */
1558         dib->dshSection = section;
1559         dib->dsOffset = offset;
1560     }
1561
1562     /* Create Color Map */
1563     if (dib && bm.bmBitsPixel <= 8)
1564     {
1565         HPALETTE16 hPalette = 0;
1566         if (usage == DIB_PAL_COLORS)
1567         {
1568             DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
1569             if (!dc) 
1570                 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
1571             if (dc)
1572             {
1573                 hPalette = dc->w.hPalette;
1574                 GDI_HEAP_UNLOCK(hdc);
1575             }
1576         }
1577         colorMap = DIB_BuildColorMap(bmi, hPalette, &nColorMap);
1578     }
1579
1580     /* Create Device Dependent Bitmap and add DIB/ColorMap info */
1581     if (dib) 
1582     {
1583        res = CreateDIBitmap32(hdc, bi, 0, NULL, bmi, usage);
1584        bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
1585        if (bmp)
1586        {
1587             bmp->dibSection = dib;
1588             bmp->colorMap   = colorMap;
1589             bmp->nColorMap  = nColorMap;
1590             GDI_HEAP_UNLOCK(res);
1591        }
1592     }
1593
1594     /* Clean up in case of errors */
1595     if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
1596     {
1597         if (bm.bmBits && section) 
1598             HeapFree(GetProcessHeap(), 0, bm.bmBits), bm.bmBits = NULL;
1599
1600         if (colorMap) HeapFree(GetProcessHeap(), 0, colorMap), colorMap = NULL;
1601         if (dib) HeapFree(GetProcessHeap(), 0, dib), dib = NULL;
1602         if (res) DeleteObject32(res), res = 0;
1603     }
1604
1605     /* Return BITMAP handle and storage location */
1606     if (bm.bmBits && bits) *bits = bm.bmBits;
1607     return res;
1608 }
1609
1610 /***********************************************************************
1611  *           DIB_UpdateDIBSection
1612  */
1613 void DIB_UpdateDIBSection( DC *dc, BOOL32 toDIB )
1614 {
1615     BITMAPOBJ *bmp;
1616     DIBSECTION *dib;
1617
1618     /* Ensure this is a Compatible DC that has a DIB section selected */
1619
1620     if (!dc) return;
1621     if (!(dc->w.flags & DC_MEMORY)) return;
1622
1623     bmp = (BITMAPOBJ *)GDI_GetObjPtr( dc->w.hBitmap, BITMAP_MAGIC );
1624     if (!bmp) return;
1625
1626     dib = bmp->dibSection;
1627     if (!dib)
1628     {
1629         GDI_HEAP_UNLOCK(dc->w.hBitmap);
1630         return;
1631     }
1632
1633   
1634     /* Copy Pixmap to bits */
1635     if (toDIB)
1636     {
1637         /* Expect colour corruption if you uncomment this. -MF */
1638 //        BITMAPINFO bi;
1639 //        bi.bmiHeader = dib->dsBmih;
1640 //        bi.bmiHeader.biClrUsed = 0; /* don't copy palette */
1641 //        TRACE(bitmap, "Copying from Pixmap to DIB bits\n");
1642 //        GetDIBits32( dc->hSelf, dc->w.hBitmap, 0, dib->dsBmih.biHeight,
1643 //                     dib->dsBm.bmBits, &bi, 0 );
1644     }
1645
1646     /* Copy bits to Pixmap */
1647     else
1648     {
1649         DIB_SETIMAGEBITS_DESCR descr;
1650
1651         TRACE(bitmap, "Copying from DIB bits to Pixmap\n"); 
1652         if (DIB_GetBitmapInfo( &dib->dsBmih, &descr.infoWidth, &descr.lines,
1653                                &descr.infoBpp, &descr.compression ) == -1)
1654         {
1655             GDI_HEAP_UNLOCK(dc->w.hBitmap);
1656             return;
1657         }
1658
1659         descr.dc        = dc;
1660         descr.colorMap  = bmp->colorMap;
1661         descr.nColorMap = bmp->nColorMap;
1662         descr.bits      = dib->dsBm.bmBits;
1663         descr.depth     = bmp->bitmap.bmBitsPixel;
1664         descr.drawable  = bmp->pixmap;
1665         descr.gc        = BITMAP_GC(bmp);
1666         descr.xSrc      = 0;
1667         descr.ySrc      = 0;
1668         descr.xDest     = 0;
1669         descr.yDest     = 0;
1670         descr.width     = bmp->bitmap.bmWidth;
1671         descr.height    = bmp->bitmap.bmHeight;
1672
1673         EnterCriticalSection( &X11DRV_CritSection );
1674         CALL_LARGE_STACK( DIB_SetImageBits, &descr );
1675         LeaveCriticalSection( &X11DRV_CritSection );
1676     }
1677
1678     GDI_HEAP_UNLOCK(dc->w.hBitmap);
1679 }
1680