dmcompos: Replaced && 0xff by & 0xff.
[wine] / dlls / gdi32 / dib.c
1 /*
2  * GDI device-independent bitmaps
3  *
4  * Copyright 1993,1994  Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 /*
22   Important information:
23   
24   * Current Windows versions support two different DIB structures:
25
26     - BITMAPCOREINFO / BITMAPCOREHEADER (legacy structures; used in OS/2)
27     - BITMAPINFO / BITMAPINFOHEADER
28   
29     Most Windows API functions taking a BITMAPINFO* / BITMAPINFOHEADER* also
30     accept the old "core" structures, and so must WINE.
31     You can distinguish them by looking at the first member (bcSize/biSize),
32     or use the internal function DIB_GetBitmapInfo.
33
34     
35   * The palettes are stored in different formats:
36
37     - BITMAPCOREINFO: Array of RGBTRIPLE
38     - BITMAPINFO:     Array of RGBQUAD
39
40     
41   * There are even more DIB headers, but they all extend BITMAPINFOHEADER:
42     
43     - BITMAPV4HEADER: Introduced in Windows 95 / NT 4.0
44     - BITMAPV5HEADER: Introduced in Windows 98 / 2000
45     
46     If biCompression is BI_BITFIELDS, the color masks are at the same position
47     in all the headers (they start at bmiColors of BITMAPINFOHEADER), because
48     the new headers have structure members for the masks.
49
50
51   * You should never access the color table using the bmiColors member,
52     because the passed structure may have one of the extended headers
53     mentioned above. Use this to calculate the location:
54     
55     BITMAPINFO* info;
56     void* colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
57
58     
59   * More information:
60     Search for "Bitmap Structures" in MSDN
61 */
62
63 #include <stdarg.h>
64 #include <stdlib.h>
65 #include <string.h>
66
67 #include "windef.h"
68 #include "winbase.h"
69 #include "gdi.h"
70 #include "wownt32.h"
71 #include "gdi_private.h"
72 #include "wine/debug.h"
73
74 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
75
76
77 /*
78   Some of the following helper functions are duplicated in
79   dlls/x11drv/dib.c
80 */
81
82 /***********************************************************************
83  *           DIB_GetDIBWidthBytes
84  *
85  * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
86  * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_87eb.asp
87  */
88 int DIB_GetDIBWidthBytes( int width, int depth )
89 {
90     int words;
91
92     switch(depth)
93     {
94         case 1:  words = (width + 31) / 32; break;
95         case 4:  words = (width + 7) / 8; break;
96         case 8:  words = (width + 3) / 4; break;
97         case 15:
98         case 16: words = (width + 1) / 2; break;
99         case 24: words = (width * 3 + 3)/4; break;
100
101         default:
102             WARN("(%d): Unsupported depth\n", depth );
103         /* fall through */
104         case 32:
105                 words = width;
106     }
107     return 4 * words;
108 }
109
110 /***********************************************************************
111  *           DIB_GetDIBImageBytes
112  *
113  * Return the number of bytes used to hold the image in a DIB bitmap.
114  */
115 int DIB_GetDIBImageBytes( int width, int height, int depth )
116 {
117     return DIB_GetDIBWidthBytes( width, depth ) * abs( height );
118 }
119
120
121 /***********************************************************************
122  *           DIB_BitmapInfoSize
123  *
124  * Return the size of the bitmap info structure including color table.
125  */
126 int DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse )
127 {
128     int colors;
129
130     if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
131     {
132         const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
133         colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
134         return sizeof(BITMAPCOREHEADER) + colors *
135              ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
136     }
137     else  /* assume BITMAPINFOHEADER */
138     {
139         colors = info->bmiHeader.biClrUsed;
140         if (colors > 256) colors = 256;
141         if (!colors && (info->bmiHeader.biBitCount <= 8))
142             colors = 1 << info->bmiHeader.biBitCount;
143         return sizeof(BITMAPINFOHEADER) + colors *
144                ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
145     }
146 }
147
148
149 /***********************************************************************
150  *           DIB_GetBitmapInfo
151  *
152  * Get the info from a bitmap header.
153  * Return 1 for INFOHEADER, 0 for COREHEADER,
154  * 4 for V4HEADER, 5 for V5HEADER, -1 for error.
155  */
156 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
157                               LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size )
158 {
159     if (header->biSize == sizeof(BITMAPINFOHEADER))
160     {
161         *width  = header->biWidth;
162         *height = header->biHeight;
163         *planes = header->biPlanes;
164         *bpp    = header->biBitCount;
165         *compr  = header->biCompression;
166         *size   = header->biSizeImage;
167         return 1;
168     }
169     if (header->biSize == sizeof(BITMAPCOREHEADER))
170     {
171         const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
172         *width  = core->bcWidth;
173         *height = core->bcHeight;
174         *planes = core->bcPlanes;
175         *bpp    = core->bcBitCount;
176         *compr  = 0;
177         *size   = 0;
178         return 0;
179     }
180     if (header->biSize == sizeof(BITMAPV4HEADER))
181     {
182         const BITMAPV4HEADER *v4hdr = (const BITMAPV4HEADER *)header;
183         *width  = v4hdr->bV4Width;
184         *height = v4hdr->bV4Height;
185         *planes = v4hdr->bV4Planes;
186         *bpp    = v4hdr->bV4BitCount;
187         *compr  = v4hdr->bV4V4Compression;
188         *size   = v4hdr->bV4SizeImage;
189         return 4;
190     }
191     if (header->biSize == sizeof(BITMAPV5HEADER))
192     {
193         const BITMAPV5HEADER *v5hdr = (const BITMAPV5HEADER *)header;
194         *width  = v5hdr->bV5Width;
195         *height = v5hdr->bV5Height;
196         *planes = v5hdr->bV5Planes;
197         *bpp    = v5hdr->bV5BitCount;
198         *compr  = v5hdr->bV5Compression;
199         *size   = v5hdr->bV5SizeImage;
200         return 5;
201     }
202     ERR("(%d): unknown/wrong size for header\n", header->biSize );
203     return -1;
204 }
205
206
207 /***********************************************************************
208  *           StretchDIBits   (GDI32.@)
209  */
210 INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
211                        INT heightDst, INT xSrc, INT ySrc, INT widthSrc,
212                        INT heightSrc, const void *bits,
213                        const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
214 {
215     DC *dc;
216
217     if (!bits || !info)
218         return 0;
219
220     dc = DC_GetDCUpdate( hdc );
221     if(!dc) return FALSE;
222
223     if(dc->funcs->pStretchDIBits)
224     {
225         heightSrc = dc->funcs->pStretchDIBits(dc->physDev, xDst, yDst, widthDst,
226                                               heightDst, xSrc, ySrc, widthSrc,
227                                               heightSrc, bits, info, wUsage, dwRop);
228         GDI_ReleaseObj( hdc );
229     }
230     else /* use StretchBlt */
231     {
232         HBITMAP hBitmap, hOldBitmap;
233         HPALETTE hpal = NULL;
234         HDC hdcMem;
235         LONG height;
236         LONG width;
237         WORD planes, bpp;
238         DWORD compr, size;
239
240         GDI_ReleaseObj( hdc );
241
242         if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size ) == -1)
243         {
244             ERR("Invalid bitmap\n");
245             return 0;
246         }
247
248         if (width < 0)
249         {
250             ERR("Bitmap has a negative width\n");
251             return 0;
252         }
253
254         hdcMem = CreateCompatibleDC( hdc );
255         hBitmap = CreateCompatibleBitmap(hdc, width, height);
256         hOldBitmap = SelectObject( hdcMem, hBitmap );
257         if(wUsage == DIB_PAL_COLORS)
258         {
259             hpal = GetCurrentObject(hdc, OBJ_PAL);
260             hpal = SelectPalette(hdcMem, hpal, FALSE);
261         }
262
263         if (info->bmiHeader.biCompression == BI_RLE4 ||
264             info->bmiHeader.biCompression == BI_RLE8) {
265
266            /* when RLE compression is used, there may be some gaps (ie the DIB doesn't
267             * contain all the rectangle described in bmiHeader, but only part of it.
268             * This mean that those undescribed pixels must be left untouched.
269             * So, we first copy on a memory bitmap the current content of the
270             * destination rectangle, blit the DIB bits on top of it - hence leaving
271             * the gaps untouched -, and blitting the rectangle back.
272             * This insure that gaps are untouched on the destination rectangle
273             * Not doing so leads to trashed images (the gaps contain what was on the
274             * memory bitmap => generally black or garbage)
275             * Unfortunately, RLE DIBs without gaps will be slowed down. But this is
276             * another speed vs correctness issue. Anyway, if speed is needed, then the
277             * pStretchDIBits function shall be implemented.
278             * ericP (2000/09/09)
279             */
280
281             /* copy existing bitmap from destination dc */
282             StretchBlt( hdcMem, xSrc, abs(height) - heightSrc - ySrc,
283                         widthSrc, heightSrc, hdc, xDst, yDst, widthDst, heightDst,
284                         dwRop );
285         }
286
287         SetDIBits(hdcMem, hBitmap, 0, height, bits, info, wUsage);
288
289         /* Origin for DIBitmap may be bottom left (positive biHeight) or top
290            left (negative biHeight) */
291         StretchBlt( hdc, xDst, yDst, widthDst, heightDst,
292                     hdcMem, xSrc, abs(height) - heightSrc - ySrc,
293                     widthSrc, heightSrc, dwRop );
294         if(hpal)
295             SelectPalette(hdcMem, hpal, FALSE);
296         SelectObject( hdcMem, hOldBitmap );
297         DeleteDC( hdcMem );
298         DeleteObject( hBitmap );
299     }
300     return heightSrc;
301 }
302
303
304 /******************************************************************************
305  * SetDIBits [GDI32.@]
306  *
307  * Sets pixels in a bitmap using colors from DIB.
308  *
309  * PARAMS
310  *    hdc       [I] Handle to device context
311  *    hbitmap   [I] Handle to bitmap
312  *    startscan [I] Starting scan line
313  *    lines     [I] Number of scan lines
314  *    bits      [I] Array of bitmap bits
315  *    info      [I] Address of structure with data
316  *    coloruse  [I] Type of color indexes to use
317  *
318  * RETURNS
319  *    Success: Number of scan lines copied
320  *    Failure: 0
321  */
322 INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
323                       UINT lines, LPCVOID bits, const BITMAPINFO *info,
324                       UINT coloruse )
325 {
326     DC *dc;
327     BITMAPOBJ *bitmap;
328     INT result = 0;
329
330     if (!(dc = DC_GetDCUpdate( hdc )))
331     {
332         if (coloruse == DIB_RGB_COLORS) FIXME( "shouldn't require a DC for DIB_RGB_COLORS\n" );
333         return 0;
334     }
335
336     if (!(bitmap = GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
337     {
338         GDI_ReleaseObj( hdc );
339         return 0;
340     }
341
342     if (!bitmap->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) goto done;
343
344     if (bitmap->funcs && bitmap->funcs->pSetDIBits)
345         result = bitmap->funcs->pSetDIBits( dc->physDev, hbitmap, startscan, lines,
346                                             bits, info, coloruse );
347     else
348         result = lines;
349
350  done:
351     GDI_ReleaseObj( hbitmap );
352     GDI_ReleaseObj( hdc );
353     return result;
354 }
355
356
357 /***********************************************************************
358  *           SetDIBitsToDevice   (GDI32.@)
359  */
360 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
361                            DWORD cy, INT xSrc, INT ySrc, UINT startscan,
362                            UINT lines, LPCVOID bits, const BITMAPINFO *info,
363                            UINT coloruse )
364 {
365     INT ret;
366     DC *dc;
367
368     if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
369
370     if(dc->funcs->pSetDIBitsToDevice)
371         ret = dc->funcs->pSetDIBitsToDevice( dc->physDev, xDest, yDest, cx, cy, xSrc,
372                                              ySrc, startscan, lines, bits,
373                                              info, coloruse );
374     else {
375         FIXME("unimplemented on hdc %p\n", hdc);
376         ret = 0;
377     }
378
379     GDI_ReleaseObj( hdc );
380     return ret;
381 }
382
383 /***********************************************************************
384  *           SetDIBColorTable    (GDI32.@)
385  */
386 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUAD *colors )
387 {
388     DC * dc;
389     UINT result = 0;
390     BITMAPOBJ * bitmap;
391
392     if (!(dc = DC_GetDCPtr( hdc ))) return 0;
393
394     if ((bitmap = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC )))
395     {
396         /* Check if currently selected bitmap is a DIB */
397         if (bitmap->color_table)
398         {
399             if (startpos < bitmap->nb_colors)
400             {
401                 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
402                 memcpy(bitmap->color_table + startpos, colors, entries * sizeof(RGBQUAD));
403                 result = entries;
404             }
405         }
406         GDI_ReleaseObj( dc->hBitmap );
407     }
408
409     if (dc->funcs->pSetDIBColorTable)
410         dc->funcs->pSetDIBColorTable(dc->physDev, startpos, entries, colors);
411
412     GDI_ReleaseObj( hdc );
413     return result;
414 }
415
416
417 /***********************************************************************
418  *           GetDIBColorTable    (GDI32.@)
419  */
420 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
421 {
422     DC * dc;
423     UINT result = 0;
424
425     if (!(dc = DC_GetDCPtr( hdc ))) return 0;
426
427     if (dc->funcs->pGetDIBColorTable)
428         result = dc->funcs->pGetDIBColorTable(dc->physDev, startpos, entries, colors);
429     else
430     {
431         BITMAPOBJ *bitmap = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
432         if (bitmap)
433         {
434             /* Check if currently selected bitmap is a DIB */
435             if (bitmap->color_table)
436             {
437                 if (startpos < bitmap->nb_colors)
438                 {
439                     if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
440                     memcpy(colors, bitmap->color_table + startpos, entries * sizeof(RGBQUAD));
441                     result = entries;
442                 }
443             }
444             GDI_ReleaseObj( dc->hBitmap );
445         }
446     }
447     GDI_ReleaseObj( hdc );
448     return result;
449 }
450
451 /* FIXME the following two structs should be combined with __sysPalTemplate in
452    objects/color.c - this should happen after de-X11-ing both of these
453    files.
454    NB. RGBQUAD and PALETTEENTRY have different orderings of red, green
455    and blue - sigh */
456
457 static const RGBQUAD EGAColorsQuads[16] = {
458 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
459     { 0x00, 0x00, 0x00, 0x00 },
460     { 0x00, 0x00, 0x80, 0x00 },
461     { 0x00, 0x80, 0x00, 0x00 },
462     { 0x00, 0x80, 0x80, 0x00 },
463     { 0x80, 0x00, 0x00, 0x00 },
464     { 0x80, 0x00, 0x80, 0x00 },
465     { 0x80, 0x80, 0x00, 0x00 },
466     { 0x80, 0x80, 0x80, 0x00 },
467     { 0xc0, 0xc0, 0xc0, 0x00 },
468     { 0x00, 0x00, 0xff, 0x00 },
469     { 0x00, 0xff, 0x00, 0x00 },
470     { 0x00, 0xff, 0xff, 0x00 },
471     { 0xff, 0x00, 0x00, 0x00 },
472     { 0xff, 0x00, 0xff, 0x00 },
473     { 0xff, 0xff, 0x00, 0x00 },
474     { 0xff, 0xff, 0xff, 0x00 }
475 };
476
477 static const RGBTRIPLE EGAColorsTriples[16] = {
478 /* rgbBlue, rgbGreen, rgbRed */
479     { 0x00, 0x00, 0x00 },
480     { 0x00, 0x00, 0x80 },
481     { 0x00, 0x80, 0x00 },
482     { 0x00, 0x80, 0x80 },
483     { 0x80, 0x00, 0x00 },
484     { 0x80, 0x00, 0x80 },
485     { 0x80, 0x80, 0x00 },
486     { 0x80, 0x80, 0x80 },
487     { 0xc0, 0xc0, 0xc0 },
488     { 0x00, 0x00, 0xff },
489     { 0x00, 0xff, 0x00 },
490     { 0x00, 0xff, 0xff },
491     { 0xff, 0x00, 0x00 } ,
492     { 0xff, 0x00, 0xff },
493     { 0xff, 0xff, 0x00 },
494     { 0xff, 0xff, 0xff }
495 };
496
497 static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
498 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
499     { 0x00, 0x00, 0x00, 0x00 },
500     { 0x00, 0x00, 0x80, 0x00 },
501     { 0x00, 0x80, 0x00, 0x00 },
502     { 0x00, 0x80, 0x80, 0x00 },
503     { 0x80, 0x00, 0x00, 0x00 },
504     { 0x80, 0x00, 0x80, 0x00 },
505     { 0x80, 0x80, 0x00, 0x00 },
506     { 0xc0, 0xc0, 0xc0, 0x00 },
507     { 0xc0, 0xdc, 0xc0, 0x00 },
508     { 0xf0, 0xca, 0xa6, 0x00 },
509     { 0xf0, 0xfb, 0xff, 0x00 },
510     { 0xa4, 0xa0, 0xa0, 0x00 },
511     { 0x80, 0x80, 0x80, 0x00 },
512     { 0x00, 0x00, 0xf0, 0x00 },
513     { 0x00, 0xff, 0x00, 0x00 },
514     { 0x00, 0xff, 0xff, 0x00 },
515     { 0xff, 0x00, 0x00, 0x00 },
516     { 0xff, 0x00, 0xff, 0x00 },
517     { 0xff, 0xff, 0x00, 0x00 },
518     { 0xff, 0xff, 0xff, 0x00 }
519 };
520
521 static const RGBTRIPLE DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
522 /* rgbBlue, rgbGreen, rgbRed */
523     { 0x00, 0x00, 0x00 },
524     { 0x00, 0x00, 0x80 },
525     { 0x00, 0x80, 0x00 },
526     { 0x00, 0x80, 0x80 },
527     { 0x80, 0x00, 0x00 },
528     { 0x80, 0x00, 0x80 },
529     { 0x80, 0x80, 0x00 },
530     { 0xc0, 0xc0, 0xc0 },
531     { 0xc0, 0xdc, 0xc0 },
532     { 0xf0, 0xca, 0xa6 },
533     { 0xf0, 0xfb, 0xff },
534     { 0xa4, 0xa0, 0xa0 },
535     { 0x80, 0x80, 0x80 },
536     { 0x00, 0x00, 0xf0 },
537     { 0x00, 0xff, 0x00 },
538     { 0x00, 0xff, 0xff },
539     { 0xff, 0x00, 0x00 },
540     { 0xff, 0x00, 0xff },
541     { 0xff, 0xff, 0x00 },
542     { 0xff, 0xff, 0xff}
543 };
544
545
546 /******************************************************************************
547  * GetDIBits [GDI32.@]
548  *
549  * Retrieves bits of bitmap and copies to buffer.
550  *
551  * RETURNS
552  *    Success: Number of scan lines copied from bitmap
553  *    Failure: 0
554  *
555  * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_87eb.asp
556  */
557 INT WINAPI GetDIBits(
558     HDC hdc,         /* [in]  Handle to device context */
559     HBITMAP hbitmap, /* [in]  Handle to bitmap */
560     UINT startscan,  /* [in]  First scan line to set in dest bitmap */
561     UINT lines,      /* [in]  Number of scan lines to copy */
562     LPVOID bits,       /* [out] Address of array for bitmap bits */
563     BITMAPINFO * info, /* [out] Address of structure with bitmap data */
564     UINT coloruse)   /* [in]  RGB or palette index */
565 {
566     DC * dc;
567     BITMAPOBJ * bmp;
568     int i;
569     int bitmap_type;
570     BOOL core_header;
571     LONG width;
572     LONG height;
573     WORD planes, bpp;
574     DWORD compr, size;
575     void* colorPtr;
576     RGBTRIPLE* rgbTriples;
577     RGBQUAD* rgbQuads;
578
579     if (!info) return 0;
580
581     bitmap_type = DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size);
582     if (bitmap_type == -1)
583     {
584         ERR("Invalid bitmap format\n");
585         return 0;
586     }
587     core_header = (bitmap_type == 0);
588     if (!(dc = DC_GetDCUpdate( hdc )))
589     {
590         return 0;
591     }
592     if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
593     {
594         GDI_ReleaseObj( hdc );
595         return 0;
596     }
597
598     colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
599     rgbTriples = (RGBTRIPLE *) colorPtr;
600     rgbQuads = (RGBQUAD *) colorPtr;
601
602     /* Transfer color info */
603
604     if (bpp <= 8 && bpp > 0)
605     {
606         if (!core_header) info->bmiHeader.biClrUsed = 0;
607
608         /* If the bitmap object already has a dib section at the
609            same color depth then get the color map from it */
610         if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == bpp) {
611             if(coloruse == DIB_RGB_COLORS) {
612                 unsigned int colors = min( bmp->nb_colors, 1 << bpp );
613
614                 if (core_header)
615                 {
616                     /* Convert the color table (RGBQUAD to RGBTRIPLE) */
617                     RGBTRIPLE* index = rgbTriples;
618
619                     for (i=0; i < colors; i++, index++)
620                     {
621                         index->rgbtRed   = bmp->color_table[i].rgbRed;
622                         index->rgbtGreen = bmp->color_table[i].rgbGreen;
623                         index->rgbtBlue  = bmp->color_table[i].rgbBlue;
624                     }
625                 }
626                 else
627                 {
628                     if (colors != 1 << bpp) info->bmiHeader.biClrUsed = colors;
629                     memcpy(colorPtr, bmp->color_table, colors * sizeof(RGBQUAD));
630                 }
631             }
632             else {
633                 WORD *index = colorPtr;
634                 for(i = 0; i < 1 << info->bmiHeader.biBitCount; i++, index++)
635                     *index = i;
636             }
637         }
638         else {
639             if(bpp >= bmp->bitmap.bmBitsPixel) {
640                 /* Generate the color map from the selected palette */
641                 PALETTEENTRY * palEntry;
642                 PALETTEOBJ * palette;
643                 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC ))) {
644                     GDI_ReleaseObj( hdc );
645                     GDI_ReleaseObj( hbitmap );
646                     return 0;
647                 }
648                 palEntry = palette->logpalette.palPalEntry;
649                 for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++, palEntry++) {
650                     if (coloruse == DIB_RGB_COLORS) {
651                         if (core_header)
652                         {
653                             rgbTriples[i].rgbtRed   = palEntry->peRed;
654                             rgbTriples[i].rgbtGreen = palEntry->peGreen;
655                             rgbTriples[i].rgbtBlue  = palEntry->peBlue;
656                         }
657                         else
658                         {
659                             rgbQuads[i].rgbRed      = palEntry->peRed;
660                             rgbQuads[i].rgbGreen    = palEntry->peGreen;
661                             rgbQuads[i].rgbBlue     = palEntry->peBlue;
662                             rgbQuads[i].rgbReserved = 0;
663                         }
664                     }
665                     else ((WORD *)colorPtr)[i] = (WORD)i;
666                 }
667                 GDI_ReleaseObj( dc->hPalette );
668             } else {
669                 switch (bpp) {
670                 case 1:
671                     if (core_header)
672                     {
673                         rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
674                             rgbTriples[0].rgbtBlue = 0;
675                         rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
676                             rgbTriples[1].rgbtBlue = 0xff;
677                     }
678                     else
679                     {    
680                         rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
681                             rgbQuads[0].rgbBlue = 0;
682                         rgbQuads[0].rgbReserved = 0;
683                         rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
684                             rgbQuads[1].rgbBlue = 0xff;
685                         rgbQuads[1].rgbReserved = 0;
686                     }
687                     break;
688
689                 case 4:
690                     if (core_header)
691                         memcpy(colorPtr, EGAColorsTriples, sizeof(EGAColorsTriples));
692                     else
693                         memcpy(colorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
694
695                     break;
696
697                 case 8:
698                     {
699                         if (core_header)
700                         {
701                             INT r, g, b;
702                             RGBTRIPLE *color;
703
704                             memcpy(rgbTriples, DefLogPaletteTriples,
705                                        10 * sizeof(RGBTRIPLE));
706                             memcpy(rgbTriples + 246, DefLogPaletteTriples + 10,
707                                        10 * sizeof(RGBTRIPLE));
708                             color = rgbTriples + 10;
709                             for(r = 0; r <= 5; r++) /* FIXME */
710                                 for(g = 0; g <= 5; g++)
711                                     for(b = 0; b <= 5; b++) {
712                                         color->rgbtRed =   (r * 0xff) / 5;
713                                         color->rgbtGreen = (g * 0xff) / 5;
714                                         color->rgbtBlue =  (b * 0xff) / 5;
715                                         color++;
716                                     }
717                         }
718                         else
719                         {
720                             INT r, g, b;
721                             RGBQUAD *color;
722
723                             memcpy(rgbQuads, DefLogPaletteQuads,
724                                        10 * sizeof(RGBQUAD));
725                             memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
726                                    10 * sizeof(RGBQUAD));
727                             color = rgbQuads + 10;
728                             for(r = 0; r <= 5; r++) /* FIXME */
729                                 for(g = 0; g <= 5; g++)
730                                     for(b = 0; b <= 5; b++) {
731                                         color->rgbRed =   (r * 0xff) / 5;
732                                         color->rgbGreen = (g * 0xff) / 5;
733                                         color->rgbBlue =  (b * 0xff) / 5;
734                                         color->rgbReserved = 0;
735                                         color++;
736                                     }
737                         }
738                     }
739                 }
740             }
741         }
742     }
743
744     if (bits && lines)
745     {
746         /* If the bitmap object already have a dib section that contains image data, get the bits from it */
747         if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
748         {
749             /*FIXME: Only RGB dibs supported for now */
750             unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb = bmp->dib->dsBm.bmWidthBytes;
751             unsigned int dstwidth = width;
752             int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
753             LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
754             unsigned int x, y, width, widthb;
755
756             if ((height < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
757             {
758                 dbits = (LPBYTE)bits + (dstwidthb * (lines-1));
759                 dstwidthb = -dstwidthb;
760             }
761
762             switch( bpp ) {
763
764             case 15:
765             case 16: /* 16 bpp dstDIB */
766                 {
767                     LPWORD dstbits = (LPWORD)dbits;
768                     WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
769
770                     /* FIXME: BI_BITFIELDS not supported yet */
771
772                     switch(bmp->dib->dsBm.bmBitsPixel) {
773
774                     case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
775                         {
776                             widthb = min(srcwidthb, abs(dstwidthb));
777                             /* FIXME: BI_BITFIELDS not supported yet */
778                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
779                                 memcpy(dbits, sbits, widthb);
780                         }
781                         break;
782
783                     case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
784                         {
785                             LPBYTE srcbits = sbits;
786
787                             width = min(srcwidth, dstwidth);
788                             for( y = 0; y < lines; y++) {
789                                 for( x = 0; x < width; x++, srcbits += 3)
790                                     *dstbits++ = ((srcbits[0] >> 3) & bmask) |
791                                                  (((WORD)srcbits[1] << 2) & gmask) |
792                                                  (((WORD)srcbits[2] << 7) & rmask);
793
794                                 dstbits = (LPWORD)(dbits+=dstwidthb);
795                                 srcbits = (sbits += srcwidthb);
796                             }
797                         }
798                         break;
799
800                     case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
801                         {
802                             LPDWORD srcbits = (LPDWORD)sbits;
803                             DWORD val;
804
805                             width = min(srcwidth, dstwidth);
806                             for( y = 0; y < lines; y++) {
807                                 for( x = 0; x < width; x++ ) {
808                                     val = *srcbits++;
809                                     *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
810                                                        ((val >> 9) & rmask));
811                                 }
812                                 dstbits = (LPWORD)(dbits+=dstwidthb);
813                                 srcbits = (LPDWORD)(sbits+=srcwidthb);
814                             }
815                         }
816                         break;
817
818                     default: /* ? bit bmp -> 16 bit DIB */
819                         FIXME("15/16 bit DIB %d bit bitmap\n",
820                         bmp->bitmap.bmBitsPixel);
821                         break;
822                     }
823                 }
824                 break;
825
826             case 24: /* 24 bpp dstDIB */
827                 {
828                     LPBYTE dstbits = dbits;
829
830                     switch(bmp->dib->dsBm.bmBitsPixel) {
831
832                     case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
833                         {
834                             LPWORD srcbits = (LPWORD)sbits;
835                             WORD val;
836
837                             width = min(srcwidth, dstwidth);
838                             /* FIXME: BI_BITFIELDS not supported yet */
839                             for( y = 0; y < lines; y++) {
840                                 for( x = 0; x < width; x++ ) {
841                                     val = *srcbits++;
842                                     *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
843                                     *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
844                                     *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
845                                 }
846                                 dstbits = (LPBYTE)(dbits+=dstwidthb);
847                                 srcbits = (LPWORD)(sbits+=srcwidthb);
848                             }
849                         }
850                         break;
851
852                     case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
853                         {
854                             widthb = min(srcwidthb, abs(dstwidthb));
855                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
856                                 memcpy(dbits, sbits, widthb);
857                         }
858                         break;
859
860                     case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
861                         {
862                             LPBYTE srcbits = (LPBYTE)sbits;
863
864                             width = min(srcwidth, dstwidth);
865                             for( y = 0; y < lines; y++) {
866                                 for( x = 0; x < width; x++, srcbits++ ) {
867                                     *dstbits++ = *srcbits++;
868                                     *dstbits++ = *srcbits++;
869                                     *dstbits++ = *srcbits++;
870                                 }
871                                 dstbits=(LPBYTE)(dbits+=dstwidthb);
872                                 srcbits = (LPBYTE)(sbits+=srcwidthb);
873                             }
874                         }
875                         break;
876
877                     default: /* ? bit bmp -> 24 bit DIB */
878                         FIXME("24 bit DIB %d bit bitmap\n",
879                               bmp->bitmap.bmBitsPixel);
880                         break;
881                     }
882                 }
883                 break;
884
885             case 32: /* 32 bpp dstDIB */
886                 {
887                     LPDWORD dstbits = (LPDWORD)dbits;
888
889                     /* FIXME: BI_BITFIELDS not supported yet */
890
891                     switch(bmp->dib->dsBm.bmBitsPixel) {
892                         case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
893                         {
894                             LPWORD srcbits = (LPWORD)sbits;
895                             DWORD val;
896
897                             width = min(srcwidth, dstwidth);
898                             /* FIXME: BI_BITFIELDS not supported yet */
899                             for( y = 0; y < lines; y++) {
900                                 for( x = 0; x < width; x++ ) {
901                                     val = (DWORD)*srcbits++;
902                                     *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
903                                                  ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
904                                                  ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
905                                 }
906                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
907                                 srcbits=(LPWORD)(sbits+=srcwidthb);
908                             }
909                         }
910                         break;
911
912                     case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
913                         {
914                             LPBYTE srcbits = sbits;
915
916                             width = min(srcwidth, dstwidth);
917                             for( y = 0; y < lines; y++) {
918                                 for( x = 0; x < width; x++, srcbits+=3 )
919                                     *dstbits++ =  srcbits[0] |
920                                                  (srcbits[1] <<  8) |
921                                                  (srcbits[2] << 16);
922                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
923                                 srcbits=(sbits+=srcwidthb);
924                             }
925                         }
926                         break;
927
928                     case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
929                         {
930                             widthb = min(srcwidthb, abs(dstwidthb));
931                             /* FIXME: BI_BITFIELDS not supported yet */
932                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
933                                 memcpy(dbits, sbits, widthb);
934                             }
935                         }
936                         break;
937
938                     default: /* ? bit bmp -> 32 bit DIB */
939                         FIXME("32 bit DIB %d bit bitmap\n",
940                         bmp->bitmap.bmBitsPixel);
941                         break;
942                     }
943                 }
944                 break;
945
946             default: /* ? bit DIB */
947                 FIXME("Unsupported DIB depth %d\n", info->bmiHeader.biBitCount);
948                 break;
949             }
950         }
951         /* Otherwise, get bits from the XImage */
952         else
953         {
954             if (!bmp->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) lines = 0;
955             else
956             {
957                 if (bmp->funcs && bmp->funcs->pGetDIBits)
958                     lines = bmp->funcs->pGetDIBits( dc->physDev, hbitmap, startscan,
959                                                     lines, bits, info, coloruse );
960                 else
961                     lines = 0;  /* FIXME: should copy from bmp->bitmap.bmBits */
962             }
963         }
964     }
965     else
966     {
967         /* fill in struct members */
968
969         if (bpp == 0)
970         {
971             if (core_header)
972             {
973                 BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
974                 coreheader->bcWidth = bmp->bitmap.bmWidth;
975                 coreheader->bcHeight = bmp->bitmap.bmHeight;
976                 coreheader->bcPlanes = 1;
977                 coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
978             }
979             else
980             {
981                 info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
982                 info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
983                 info->bmiHeader.biPlanes = 1;
984                 info->bmiHeader.biSizeImage =
985                                  DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
986                                                        bmp->bitmap.bmHeight,
987                                                        bmp->bitmap.bmBitsPixel );
988                 switch(bmp->bitmap.bmBitsPixel)
989                 {
990                 case 15:
991                     info->bmiHeader.biBitCount = 16;
992                     info->bmiHeader.biCompression = BI_RGB;
993                     break;
994                     
995                 case 16:
996                     info->bmiHeader.biBitCount = 16;
997                     info->bmiHeader.biCompression = BI_BITFIELDS;
998                     ((PDWORD)info->bmiColors)[0] = 0xf800;
999                     ((PDWORD)info->bmiColors)[1] = 0x07e0;
1000                     ((PDWORD)info->bmiColors)[2] = 0x001f;
1001                     break;
1002     
1003                 default:
1004                     info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
1005                     info->bmiHeader.biCompression = BI_RGB;
1006                     break;
1007                 }
1008                 info->bmiHeader.biXPelsPerMeter = 0;
1009                 info->bmiHeader.biYPelsPerMeter = 0;
1010                 info->bmiHeader.biClrUsed = 0;
1011                 info->bmiHeader.biClrImportant = 0;
1012                 
1013                 /* Windows 2000 doesn't touch the additional struct members if
1014                    it's a BITMAPV4HEADER or a BITMAPV5HEADER */
1015             }
1016             lines = abs(bmp->bitmap.bmHeight);
1017         }
1018         else
1019         {
1020             /* The knowledge base article Q81498 ("DIBs and Their Uses") states that
1021                if bits == NULL and bpp != 0, only biSizeImage and the color table are
1022                filled in. */
1023             if (!core_header)
1024             {
1025                 /* FIXME: biSizeImage should be calculated according to the selected
1026                           compression algorithm if biCompression != BI_RGB */
1027                 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp );
1028             }
1029             lines = abs(height);
1030         }
1031     }
1032
1033     if (!core_header)
1034     {
1035         TRACE("biSizeImage = %d, ", info->bmiHeader.biSizeImage);
1036     }
1037     TRACE("biWidth = %d, biHeight = %d\n", width, height);
1038
1039     GDI_ReleaseObj( hdc );
1040     GDI_ReleaseObj( hbitmap );
1041     return lines;
1042 }
1043
1044
1045 /***********************************************************************
1046  *           CreateDIBitmap    (GDI32.@)
1047  *
1048  * Creates a DDB (device dependent bitmap) from a DIB.
1049  * The DDB will have the same color depth as the reference DC.
1050  */
1051 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
1052                             DWORD init, LPCVOID bits, const BITMAPINFO *data,
1053                             UINT coloruse )
1054 {
1055     HBITMAP handle;
1056     LONG width;
1057     LONG height;
1058     WORD planes, bpp;
1059     DWORD compr, size;
1060     DC *dc;
1061
1062     if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &size ) == -1) return 0;
1063     
1064     if (width < 0)
1065     {
1066         TRACE("Bitmap has a negative width\n");
1067         return 0;
1068     }
1069     
1070     /* Top-down DIBs have a negative height */
1071     if (height < 0) height = -height;
1072
1073     TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1074            hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
1075     
1076     if (hdc == NULL)
1077         handle = CreateBitmap( width, height, 1, 1, NULL );
1078     else
1079         handle = CreateCompatibleBitmap( hdc, width, height );
1080
1081     if (handle)
1082     {
1083         if (init == CBM_INIT) SetDIBits( hdc, handle, 0, height, bits, data, coloruse );
1084
1085         else if (hdc && ((dc = DC_GetDCPtr( hdc )) != NULL) )
1086         {
1087             if (!BITMAP_SetOwnerDC( handle, dc ))
1088             {
1089                 DeleteObject( handle );
1090                 handle = 0;
1091             }
1092             GDI_ReleaseObj( hdc );
1093         }
1094     }
1095
1096     return handle;
1097 }
1098
1099 /***********************************************************************
1100  *           CreateDIBSection    (GDI.489)
1101  */
1102 HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, const BITMAPINFO *bmi, UINT16 usage,
1103                                      SEGPTR *bits16, HANDLE section, DWORD offset)
1104 {
1105     LPVOID bits32;
1106     HBITMAP hbitmap;
1107
1108     hbitmap = CreateDIBSection( HDC_32(hdc), bmi, usage, &bits32, section, offset );
1109     if (hbitmap)
1110     {
1111         BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(hbitmap, BITMAP_MAGIC);
1112         if (bmp && bmp->dib && bits32)
1113         {
1114             const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
1115             LONG width, height;
1116             WORD planes, bpp;
1117             DWORD compr, size;
1118             INT width_bytes;
1119             WORD count, sel;
1120             int i;
1121
1122             DIB_GetBitmapInfo(bi, &width, &height, &planes, &bpp, &compr, &size);
1123
1124             height = height >= 0 ? height : -height;
1125             width_bytes = DIB_GetDIBWidthBytes(width, bpp);
1126
1127             if (!size || (compr != BI_RLE4 && compr != BI_RLE8)) size = width_bytes * height;
1128
1129             /* calculate number of sel's needed for size with 64K steps */
1130             count = (size + 0xffff) / 0x10000;
1131             sel = AllocSelectorArray16(count);
1132
1133             for (i = 0; i < count; i++)
1134             {
1135                 SetSelectorBase(sel + (i << __AHSHIFT), (DWORD)bits32 + i * 0x10000);
1136                 SetSelectorLimit16(sel + (i << __AHSHIFT), size - 1); /* yep, limit is correct */
1137                 size -= 0x10000;
1138             }
1139             bmp->segptr_bits = MAKESEGPTR( sel, 0 );
1140             if (bits16) *bits16 = bmp->segptr_bits;
1141         }
1142         if (bmp) GDI_ReleaseObj( hbitmap );
1143     }
1144     return HBITMAP_16(hbitmap);
1145 }
1146
1147 /* Copy/synthetize RGB palette from BITMAPINFO. Ripped from dlls/winex11.drv/dib.c */
1148 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1149 {
1150     RGBQUAD *colorTable;
1151     unsigned int colors;
1152     int i;
1153     BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
1154
1155     if (core_info)
1156     {
1157         colors = 1 << ((const BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
1158     }
1159     else
1160     {
1161         colors = info->bmiHeader.biClrUsed;
1162         if (!colors) colors = 1 << info->bmiHeader.biBitCount;
1163     }
1164
1165     if (colors > 256) {
1166         ERR("called with >256 colors!\n");
1167         return;
1168     }
1169
1170     if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1171
1172     if(coloruse == DIB_RGB_COLORS)
1173     {
1174         if (core_info)
1175         {
1176            /* Convert RGBTRIPLEs to RGBQUADs */
1177            for (i=0; i < colors; i++)
1178            {
1179                colorTable[i].rgbRed   = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
1180                colorTable[i].rgbGreen = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
1181                colorTable[i].rgbBlue  = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
1182                colorTable[i].rgbReserved = 0;
1183            }
1184         }
1185         else
1186         {
1187             memcpy(colorTable, (const BYTE*) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
1188         }
1189     }
1190     else
1191     {
1192         PALETTEOBJ *palette;
1193         const WORD *index = (const WORD*) ((const BYTE*) info + (WORD) info->bmiHeader.biSize);
1194
1195         if ((palette = GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC )))
1196         {
1197             UINT entries = palette->logpalette.palNumEntries;
1198             for (i = 0; i < colors; i++, index++)
1199             {
1200                 PALETTEENTRY *entry = &palette->logpalette.palPalEntry[*index % entries];
1201                 colorTable[i].rgbRed = entry->peRed;
1202                 colorTable[i].rgbGreen = entry->peGreen;
1203                 colorTable[i].rgbBlue = entry->peBlue;
1204                 colorTable[i].rgbReserved = 0;
1205             }
1206             GDI_ReleaseObj( dc->hPalette );
1207         }
1208     }
1209     bmp->color_table = colorTable;
1210     bmp->nb_colors = colors;
1211 }
1212
1213 /***********************************************************************
1214  *           CreateDIBSection    (GDI32.@)
1215  */
1216 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1217                                 VOID **bits, HANDLE section, DWORD offset)
1218 {
1219     HBITMAP ret = 0;
1220     DC *dc;
1221     BOOL bDesktopDC = FALSE;
1222     DIBSECTION *dib;
1223     BITMAPOBJ *bmp;
1224     int bitmap_type;
1225     LONG width, height;
1226     WORD planes, bpp;
1227     DWORD compression, sizeImage;
1228     void *mapBits = NULL;
1229
1230     if (((bitmap_type = DIB_GetBitmapInfo( &bmi->bmiHeader, &width, &height,
1231                                            &planes, &bpp, &compression, &sizeImage )) == -1))
1232         return 0;
1233
1234     if (compression != BI_RGB && compression != BI_BITFIELDS)
1235     {
1236         TRACE("can't create a compressed (%u) dibsection\n", compression);
1237         return 0;
1238     }
1239
1240     if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1241
1242     TRACE("format (%d,%d), planes %d, bpp %d, size %d, %s\n",
1243           width, height, planes, bpp, sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1244
1245     dib->dsBm.bmType       = 0;
1246     dib->dsBm.bmWidth      = width;
1247     dib->dsBm.bmHeight     = height >= 0 ? height : -height;
1248     dib->dsBm.bmWidthBytes = DIB_GetDIBWidthBytes(width, bpp);
1249     dib->dsBm.bmPlanes     = planes;
1250     dib->dsBm.bmBitsPixel  = bpp;
1251     dib->dsBm.bmBits       = NULL;
1252
1253     if (!bitmap_type)  /* core header */
1254     {
1255         /* convert the BITMAPCOREHEADER to a BITMAPINFOHEADER */
1256         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1257         dib->dsBmih.biWidth = width;
1258         dib->dsBmih.biHeight = height;
1259         dib->dsBmih.biPlanes = planes;
1260         dib->dsBmih.biBitCount = bpp;
1261         dib->dsBmih.biCompression = compression;
1262         dib->dsBmih.biXPelsPerMeter = 0;
1263         dib->dsBmih.biYPelsPerMeter = 0;
1264         dib->dsBmih.biClrUsed = 0;
1265         dib->dsBmih.biClrImportant = 0;
1266     }
1267     else
1268     {
1269         /* truncate extended bitmap headers (BITMAPV4HEADER etc.) */
1270         dib->dsBmih = bmi->bmiHeader;
1271         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1272     }
1273
1274     /* set number of entries in bmi.bmiColors table */
1275     if( bpp <= 8 )
1276         dib->dsBmih.biClrUsed = 1 << bpp;
1277
1278     dib->dsBmih.biSizeImage = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
1279
1280     /* set dsBitfields values */
1281     if (usage == DIB_PAL_COLORS || bpp <= 8)
1282     {
1283         dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1284     }
1285     else switch( bpp )
1286     {
1287     case 15:
1288     case 16:
1289         dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors       : 0x7c00;
1290         dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x03e0;
1291         dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x001f;
1292         break;
1293     case 24:
1294     case 32:
1295         dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors       : 0xff0000;
1296         dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x00ff00;
1297         dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x0000ff;
1298         break;
1299     }
1300
1301     /* get storage location for DIB bits */
1302
1303     if (section)
1304     {
1305         SYSTEM_INFO SystemInfo;
1306         DWORD mapOffset;
1307         INT mapSize;
1308
1309         GetSystemInfo( &SystemInfo );
1310         mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1311         mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1312         mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1313         if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1314     }
1315     else
1316     {
1317         offset = 0;
1318         dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1319                                          MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1320     }
1321     dib->dshSection = section;
1322     dib->dsOffset = offset;
1323
1324     if (!dib->dsBm.bmBits)
1325     {
1326         HeapFree( GetProcessHeap(), 0, dib );
1327         return 0;
1328     }
1329
1330     /* If the reference hdc is null, take the desktop dc */
1331     if (hdc == 0)
1332     {
1333         hdc = CreateCompatibleDC(0);
1334         bDesktopDC = TRUE;
1335     }
1336
1337     if (!(dc = DC_GetDCPtr( hdc ))) goto error;
1338
1339     /* create Device Dependent Bitmap and add DIB pointer */
1340     ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1341                         (bpp == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1342
1343     if (ret && ((bmp = GDI_GetObjPtr(ret, BITMAP_MAGIC))))
1344     {
1345         bmp->dib = dib;
1346         bmp->funcs = dc->funcs;
1347         /* create local copy of DIB palette */
1348         if (bpp <= 8) DIB_CopyColorTable( dc, bmp, usage, bmi );
1349         GDI_ReleaseObj( ret );
1350
1351         if (dc->funcs->pCreateDIBSection)
1352         {
1353             if (!dc->funcs->pCreateDIBSection(dc->physDev, ret, bmi, usage))
1354             {
1355                 DeleteObject( ret );
1356                 ret = 0;
1357             }
1358         }
1359     }
1360
1361     GDI_ReleaseObj(hdc);
1362     if (bDesktopDC) DeleteDC( hdc );
1363     if (ret && bits) *bits = dib->dsBm.bmBits;
1364     return ret;
1365
1366 error:
1367     if (bDesktopDC) DeleteDC( hdc );
1368     if (section) UnmapViewOfFile( mapBits );
1369     else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1370     HeapFree( GetProcessHeap(), 0, dib );
1371     return 0;
1372 }