uxtheme: Mark internal symbols with hidden visibility.
[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)
778             {
779                 if (bmp->dib->dsBmih.biCompression == BI_BITFIELDS)
780                     memcpy( info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
781                 else
782                 {
783                     ((PDWORD)info->bmiColors)[0] = 0x7c00;
784                     ((PDWORD)info->bmiColors)[1] = 0x03e0;
785                     ((PDWORD)info->bmiColors)[2] = 0x001f;
786                 }
787             }
788             else
789             {
790                 ((PDWORD)info->bmiColors)[0] = 0xf800;
791                 ((PDWORD)info->bmiColors)[1] = 0x07e0;
792                 ((PDWORD)info->bmiColors)[2] = 0x001f;
793             }
794         }
795         break;
796
797     case 24:
798     case 32:
799         if (info->bmiHeader.biCompression == BI_BITFIELDS)
800         {
801             if (bmp->dib && bmp->dib->dsBmih.biCompression == BI_BITFIELDS)
802                 memcpy( info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
803             else
804             {
805                 ((PDWORD)info->bmiColors)[0] = 0xff0000;
806                 ((PDWORD)info->bmiColors)[1] = 0x00ff00;
807                 ((PDWORD)info->bmiColors)[2] = 0x0000ff;
808             }
809         }
810         break;
811     }
812
813     if (bits && lines)
814     {
815         /* If the bitmap object already have a dib section that contains image data, get the bits from it */
816         if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
817         {
818             /*FIXME: Only RGB dibs supported for now */
819             unsigned int srcwidth = bmp->dib->dsBm.bmWidth;
820             int srcwidthb = bmp->dib->dsBm.bmWidthBytes;
821             unsigned int dstwidth = width;
822             int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
823             LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
824             unsigned int x, y, width, widthb;
825
826             /*
827              * If copying from a top-down source bitmap, move the source
828              * pointer to the end of the source bitmap and negate the width
829              * so that we copy the bits upside-down.
830              */
831             if (bmp->dib->dsBmih.biHeight < 0)
832             {
833                 sbits += (srcwidthb * (int)(abs(bmp->dib->dsBmih.biHeight) - 2 * startscan - 1));
834                 srcwidthb = -srcwidthb;
835             }
836             /*Same for the destination.*/
837             if (height < 0)
838             {
839                 dbits = (LPBYTE)bits + (dstwidthb * (lines - 1));
840                 dstwidthb = -dstwidthb;
841             }
842             switch( bpp ) {
843
844             case 15:
845             case 16: /* 16 bpp dstDIB */
846                 {
847                     LPWORD dstbits = (LPWORD)dbits;
848                     WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
849
850                     /* FIXME: BI_BITFIELDS not supported yet */
851
852                     switch(bmp->dib->dsBm.bmBitsPixel) {
853
854                     case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
855                         {
856                             widthb = min(abs(srcwidthb), abs(dstwidthb));
857                             /* FIXME: BI_BITFIELDS not supported yet */
858                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
859                                 memcpy(dbits, sbits, widthb);
860                         }
861                         break;
862
863                     case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
864                         {
865                             LPBYTE srcbits = sbits;
866
867                             width = min(srcwidth, dstwidth);
868                             for( y = 0; y < lines; y++) {
869                                 for( x = 0; x < width; x++, srcbits += 3)
870                                     *dstbits++ = ((srcbits[0] >> 3) & bmask) |
871                                                  (((WORD)srcbits[1] << 2) & gmask) |
872                                                  (((WORD)srcbits[2] << 7) & rmask);
873
874                                 dstbits = (LPWORD)(dbits+=dstwidthb);
875                                 srcbits = (sbits += srcwidthb);
876                             }
877                         }
878                         break;
879
880                     case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
881                         {
882                             LPDWORD srcbits = (LPDWORD)sbits;
883                             DWORD val;
884
885                             width = min(srcwidth, dstwidth);
886                             for( y = 0; y < lines; y++) {
887                                 for( x = 0; x < width; x++ ) {
888                                     val = *srcbits++;
889                                     *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
890                                                        ((val >> 9) & rmask));
891                                 }
892                                 dstbits = (LPWORD)(dbits+=dstwidthb);
893                                 srcbits = (LPDWORD)(sbits+=srcwidthb);
894                             }
895                         }
896                         break;
897
898                     default: /* ? bit bmp -> 16 bit DIB */
899                         FIXME("15/16 bit DIB %d bit bitmap\n",
900                         bmp->bitmap.bmBitsPixel);
901                         break;
902                     }
903                 }
904                 break;
905
906             case 24: /* 24 bpp dstDIB */
907                 {
908                     LPBYTE dstbits = dbits;
909
910                     switch(bmp->dib->dsBm.bmBitsPixel) {
911
912                     case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
913                         {
914                             LPWORD srcbits = (LPWORD)sbits;
915                             WORD val;
916
917                             width = min(srcwidth, dstwidth);
918                             /* FIXME: BI_BITFIELDS not supported yet */
919                             for( y = 0; y < lines; y++) {
920                                 for( x = 0; x < width; x++ ) {
921                                     val = *srcbits++;
922                                     *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
923                                     *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
924                                     *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
925                                 }
926                                 dstbits = dbits+=dstwidthb;
927                                 srcbits = (LPWORD)(sbits+=srcwidthb);
928                             }
929                         }
930                         break;
931
932                     case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
933                         {
934                             widthb = min(abs(srcwidthb), abs(dstwidthb));
935                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
936                                 memcpy(dbits, sbits, widthb);
937                         }
938                         break;
939
940                     case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
941                         {
942                             LPBYTE srcbits = sbits;
943
944                             width = min(srcwidth, dstwidth);
945                             for( y = 0; y < lines; y++) {
946                                 for( x = 0; x < width; x++, srcbits++ ) {
947                                     *dstbits++ = *srcbits++;
948                                     *dstbits++ = *srcbits++;
949                                     *dstbits++ = *srcbits++;
950                                 }
951                                 dstbits = dbits+=dstwidthb;
952                                 srcbits = sbits+=srcwidthb;
953                             }
954                         }
955                         break;
956
957                     default: /* ? bit bmp -> 24 bit DIB */
958                         FIXME("24 bit DIB %d bit bitmap\n",
959                               bmp->bitmap.bmBitsPixel);
960                         break;
961                     }
962                 }
963                 break;
964
965             case 32: /* 32 bpp dstDIB */
966                 {
967                     LPDWORD dstbits = (LPDWORD)dbits;
968
969                     /* FIXME: BI_BITFIELDS not supported yet */
970
971                     switch(bmp->dib->dsBm.bmBitsPixel) {
972                         case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
973                         {
974                             LPWORD srcbits = (LPWORD)sbits;
975                             DWORD val;
976
977                             width = min(srcwidth, dstwidth);
978                             /* FIXME: BI_BITFIELDS not supported yet */
979                             for( y = 0; y < lines; y++) {
980                                 for( x = 0; x < width; x++ ) {
981                                     val = (DWORD)*srcbits++;
982                                     *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
983                                                  ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
984                                                  ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
985                                 }
986                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
987                                 srcbits=(LPWORD)(sbits+=srcwidthb);
988                             }
989                         }
990                         break;
991
992                     case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
993                         {
994                             LPBYTE srcbits = sbits;
995
996                             width = min(srcwidth, dstwidth);
997                             for( y = 0; y < lines; y++) {
998                                 for( x = 0; x < width; x++, srcbits+=3 )
999                                     *dstbits++ =  srcbits[0] |
1000                                                  (srcbits[1] <<  8) |
1001                                                  (srcbits[2] << 16);
1002                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
1003                                 srcbits=(sbits+=srcwidthb);
1004                             }
1005                         }
1006                         break;
1007
1008                     case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
1009                         {
1010                             widthb = min(abs(srcwidthb), abs(dstwidthb));
1011                             /* FIXME: BI_BITFIELDS not supported yet */
1012                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
1013                                 memcpy(dbits, sbits, widthb);
1014                             }
1015                         }
1016                         break;
1017
1018                     default: /* ? bit bmp -> 32 bit DIB */
1019                         FIXME("32 bit DIB %d bit bitmap\n",
1020                         bmp->bitmap.bmBitsPixel);
1021                         break;
1022                     }
1023                 }
1024                 break;
1025
1026             default: /* ? bit DIB */
1027                 FIXME("Unsupported DIB depth %d\n", info->bmiHeader.biBitCount);
1028                 break;
1029             }
1030         }
1031         /* Otherwise, get bits from the XImage */
1032         else
1033         {
1034             PHYSDEV physdev = GET_DC_PHYSDEV( dc, pGetDIBits );
1035             if (!BITMAP_SetOwnerDC( hbitmap, physdev )) lines = 0;
1036             else lines = physdev->funcs->pGetDIBits( physdev, hbitmap, startscan,
1037                                                      lines, bits, info, coloruse );
1038         }
1039     }
1040     else lines = abs(height);
1041
1042     /* The knowledge base article Q81498 ("DIBs and Their Uses") states that
1043        if bits == NULL and bpp != 0, only biSizeImage and the color table are
1044        filled in. */
1045     if (!core_header)
1046     {
1047         /* FIXME: biSizeImage should be calculated according to the selected
1048            compression algorithm if biCompression != BI_RGB */
1049         info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp );
1050         TRACE("biSizeImage = %d, ", info->bmiHeader.biSizeImage);
1051     }
1052     TRACE("biWidth = %d, biHeight = %d\n", width, height);
1053
1054 done:
1055     release_dc_ptr( dc );
1056     GDI_ReleaseObj( hbitmap );
1057     return lines;
1058 }
1059
1060
1061 /***********************************************************************
1062  *           CreateDIBitmap    (GDI32.@)
1063  *
1064  * Creates a DDB (device dependent bitmap) from a DIB.
1065  * The DDB will have the same color depth as the reference DC.
1066  */
1067 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
1068                             DWORD init, LPCVOID bits, const BITMAPINFO *data,
1069                             UINT coloruse )
1070 {
1071     HBITMAP handle;
1072     LONG width;
1073     LONG height;
1074     WORD planes, bpp;
1075     DWORD compr, size;
1076
1077     if (!header) return 0;
1078
1079     if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &size ) == -1) return 0;
1080     
1081     if (width < 0)
1082     {
1083         TRACE("Bitmap has a negative width\n");
1084         return 0;
1085     }
1086     
1087     /* Top-down DIBs have a negative height */
1088     if (height < 0) height = -height;
1089
1090     TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1091            hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
1092     
1093     if (hdc == NULL)
1094         handle = CreateBitmap( width, height, 1, 1, NULL );
1095     else
1096         handle = CreateCompatibleBitmap( hdc, width, height );
1097
1098     if (handle)
1099     {
1100         if (init & CBM_INIT)
1101         {
1102             if (SetDIBits( hdc, handle, 0, height, bits, data, coloruse ) == 0)
1103             {
1104                 DeleteObject( handle );
1105                 handle = 0;
1106             }
1107         }
1108     }
1109
1110     return handle;
1111 }
1112
1113 /* Copy/synthesize RGB palette from BITMAPINFO. Ripped from dlls/winex11.drv/dib.c */
1114 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1115 {
1116     RGBQUAD *colorTable;
1117     unsigned int colors, i;
1118     BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
1119
1120     if (core_info)
1121     {
1122         colors = 1 << ((const BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
1123     }
1124     else
1125     {
1126         colors = info->bmiHeader.biClrUsed;
1127         if (!colors) colors = 1 << info->bmiHeader.biBitCount;
1128     }
1129
1130     if (colors > 256) {
1131         ERR("called with >256 colors!\n");
1132         return;
1133     }
1134
1135     if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1136
1137     if(coloruse == DIB_RGB_COLORS)
1138     {
1139         if (core_info)
1140         {
1141            /* Convert RGBTRIPLEs to RGBQUADs */
1142            for (i=0; i < colors; i++)
1143            {
1144                colorTable[i].rgbRed   = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
1145                colorTable[i].rgbGreen = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
1146                colorTable[i].rgbBlue  = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
1147                colorTable[i].rgbReserved = 0;
1148            }
1149         }
1150         else
1151         {
1152             memcpy(colorTable, (const BYTE*) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
1153         }
1154     }
1155     else
1156     {
1157         PALETTEENTRY entries[256];
1158         const WORD *index = (const WORD*) ((const BYTE*) info + (WORD) info->bmiHeader.biSize);
1159         UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1160
1161         for (i = 0; i < colors; i++, index++)
1162         {
1163             PALETTEENTRY *entry = &entries[*index % count];
1164             colorTable[i].rgbRed = entry->peRed;
1165             colorTable[i].rgbGreen = entry->peGreen;
1166             colorTable[i].rgbBlue = entry->peBlue;
1167             colorTable[i].rgbReserved = 0;
1168         }
1169     }
1170     bmp->color_table = colorTable;
1171     bmp->nb_colors = colors;
1172 }
1173
1174 /***********************************************************************
1175  *           CreateDIBSection    (GDI32.@)
1176  */
1177 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1178                                 VOID **bits, HANDLE section, DWORD offset)
1179 {
1180     HBITMAP ret = 0;
1181     DC *dc;
1182     BOOL bDesktopDC = FALSE;
1183     DIBSECTION *dib;
1184     BITMAPOBJ *bmp;
1185     int bitmap_type;
1186     LONG width, height;
1187     WORD planes, bpp;
1188     DWORD compression, sizeImage;
1189     void *mapBits = NULL;
1190
1191     if(!bmi){
1192         if(bits) *bits = NULL;
1193         return NULL;
1194     }
1195
1196     if (((bitmap_type = DIB_GetBitmapInfo( &bmi->bmiHeader, &width, &height,
1197                                            &planes, &bpp, &compression, &sizeImage )) == -1))
1198         return 0;
1199
1200     switch (bpp)
1201     {
1202     case 16:
1203     case 32:
1204         if (compression == BI_BITFIELDS) break;
1205         /* fall through */
1206     case 1:
1207     case 4:
1208     case 8:
1209     case 24:
1210         if (compression == BI_RGB) break;
1211         /* fall through */
1212     default:
1213         WARN( "invalid %u bpp compression %u\n", bpp, compression );
1214         return 0;
1215     }
1216
1217     if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1218
1219     TRACE("format (%d,%d), planes %d, bpp %d, %s, size %d %s\n",
1220           width, height, planes, bpp, compression == BI_BITFIELDS? "BI_BITFIELDS" : "BI_RGB",
1221           sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1222
1223     dib->dsBm.bmType       = 0;
1224     dib->dsBm.bmWidth      = width;
1225     dib->dsBm.bmHeight     = height >= 0 ? height : -height;
1226     dib->dsBm.bmWidthBytes = DIB_GetDIBWidthBytes(width, bpp);
1227     dib->dsBm.bmPlanes     = planes;
1228     dib->dsBm.bmBitsPixel  = bpp;
1229     dib->dsBm.bmBits       = NULL;
1230
1231     if (!bitmap_type)  /* core header */
1232     {
1233         /* convert the BITMAPCOREHEADER to a BITMAPINFOHEADER */
1234         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1235         dib->dsBmih.biWidth = width;
1236         dib->dsBmih.biHeight = height;
1237         dib->dsBmih.biPlanes = planes;
1238         dib->dsBmih.biBitCount = bpp;
1239         dib->dsBmih.biCompression = compression;
1240         dib->dsBmih.biXPelsPerMeter = 0;
1241         dib->dsBmih.biYPelsPerMeter = 0;
1242         dib->dsBmih.biClrUsed = 0;
1243         dib->dsBmih.biClrImportant = 0;
1244     }
1245     else
1246     {
1247         /* truncate extended bitmap headers (BITMAPV4HEADER etc.) */
1248         dib->dsBmih = bmi->bmiHeader;
1249         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1250     }
1251
1252     /* set number of entries in bmi.bmiColors table */
1253     if( bpp <= 8 )
1254         dib->dsBmih.biClrUsed = 1 << bpp;
1255
1256     dib->dsBmih.biSizeImage = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
1257
1258     /* set dsBitfields values */
1259     dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1260
1261     if((bpp == 15 || bpp == 16) && compression == BI_RGB)
1262     {
1263         /* In this case Windows changes biCompression to BI_BITFIELDS,
1264            however for now we won't do this, as there are a lot
1265            of places where BI_BITFIELDS is currently unsupported. */
1266
1267         /* dib->dsBmih.biCompression = compression = BI_BITFIELDS;*/
1268         dib->dsBitfields[0] = 0x7c00;
1269         dib->dsBitfields[1] = 0x03e0;
1270         dib->dsBitfields[2] = 0x001f;
1271     }
1272     else if(compression == BI_BITFIELDS)
1273     {
1274         dib->dsBitfields[0] =  *(const DWORD *)bmi->bmiColors;
1275         dib->dsBitfields[1] =  *((const DWORD *)bmi->bmiColors + 1);
1276         dib->dsBitfields[2] =  *((const DWORD *)bmi->bmiColors + 2);
1277     }
1278
1279     /* get storage location for DIB bits */
1280
1281     if (section)
1282     {
1283         SYSTEM_INFO SystemInfo;
1284         DWORD mapOffset;
1285         INT mapSize;
1286
1287         GetSystemInfo( &SystemInfo );
1288         mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1289         mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1290         mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1291         if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1292     }
1293     else
1294     {
1295         offset = 0;
1296         dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1297                                          MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1298     }
1299     dib->dshSection = section;
1300     dib->dsOffset = offset;
1301
1302     if (!dib->dsBm.bmBits)
1303     {
1304         HeapFree( GetProcessHeap(), 0, dib );
1305         return 0;
1306     }
1307
1308     /* If the reference hdc is null, take the desktop dc */
1309     if (hdc == 0)
1310     {
1311         hdc = CreateCompatibleDC(0);
1312         bDesktopDC = TRUE;
1313     }
1314
1315     if (!(dc = get_dc_ptr( hdc ))) goto error;
1316
1317     /* create Device Dependent Bitmap and add DIB pointer */
1318     ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1319                         (bpp == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1320
1321     if (ret && ((bmp = GDI_GetObjPtr(ret, OBJ_BITMAP))))
1322     {
1323         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pCreateDIBSection );
1324         bmp->dib = dib;
1325         bmp->funcs = physdev->funcs;
1326         /* create local copy of DIB palette */
1327         if (bpp <= 8) DIB_CopyColorTable( dc, bmp, usage, bmi );
1328         GDI_ReleaseObj( ret );
1329
1330         if (!physdev->funcs->pCreateDIBSection( physdev, ret, bmi, usage ))
1331         {
1332             DeleteObject( ret );
1333             ret = 0;
1334         }
1335     }
1336
1337     release_dc_ptr( dc );
1338     if (bDesktopDC) DeleteDC( hdc );
1339     if (ret && bits) *bits = dib->dsBm.bmBits;
1340     return ret;
1341
1342 error:
1343     if (bDesktopDC) DeleteDC( hdc );
1344     if (section) UnmapViewOfFile( mapBits );
1345     else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1346     HeapFree( GetProcessHeap(), 0, dib );
1347     return 0;
1348 }