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