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