crypt32: Add additional path for Solaris 11 Express.
[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 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 static int fill_query_info( BITMAPINFO *info, BITMAPOBJ *bmp )
448 {
449     BITMAPINFOHEADER header;
450
451     header.biSize   = info->bmiHeader.biSize; /* Ensure we don't overwrite the original size when we copy back */
452     header.biWidth  = bmp->bitmap.bmWidth;
453     header.biHeight = bmp->bitmap.bmHeight;
454     header.biPlanes = 1;
455
456     if (bmp->dib)
457     {
458         header.biBitCount = bmp->dib->dsBm.bmBitsPixel;
459         switch (bmp->dib->dsBm.bmBitsPixel)
460         {
461         case 16:
462         case 32:
463             header.biCompression = BI_BITFIELDS;
464             break;
465         default:
466             header.biCompression = BI_RGB;
467             break;
468         }
469     }
470     else
471     {
472         header.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB;
473         header.biBitCount = bmp->bitmap.bmBitsPixel;
474     }
475
476     header.biSizeImage = DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
477                                                bmp->bitmap.bmHeight,
478                                                bmp->bitmap.bmBitsPixel );
479     header.biXPelsPerMeter = 0;
480     header.biYPelsPerMeter = 0;
481     header.biClrUsed       = 0;
482     header.biClrImportant  = 0;
483
484     if ( info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER) )
485     {
486         BITMAPCOREHEADER *coreheader = (BITMAPCOREHEADER *)info;
487
488         coreheader->bcWidth    = header.biWidth;
489         coreheader->bcHeight   = header.biHeight;
490         coreheader->bcPlanes   = header.biPlanes;
491         coreheader->bcBitCount = header.biBitCount;
492     }
493     else
494         info->bmiHeader = header;
495
496     return abs(bmp->bitmap.bmHeight);
497 }
498
499 /************************************************************************
500  *      copy_color_info
501  *
502  * Copy BITMAPINFO color information where dst may be a BITMAPCOREINFO.
503  */
504 static void copy_color_info(BITMAPINFO *dst, const BITMAPINFO *src, UINT coloruse)
505 {
506     unsigned int colors = src->bmiHeader.biBitCount > 8 ? 0 : 1 << src->bmiHeader.biBitCount;
507     RGBQUAD *src_colors = (RGBQUAD *)((char *)src + src->bmiHeader.biSize);
508
509     assert( src->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) );
510
511     if (src->bmiHeader.biClrUsed) colors = src->bmiHeader.biClrUsed;
512
513     if (dst->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
514     {
515         BITMAPCOREINFO *core = (BITMAPCOREINFO *)dst;
516         if (coloruse == DIB_PAL_COLORS)
517             memcpy( core->bmciColors, src_colors, colors * sizeof(WORD) );
518         else
519         {
520             unsigned int i;
521             for (i = 0; i < colors; i++)
522             {
523                 core->bmciColors[i].rgbtRed   = src_colors[i].rgbRed;
524                 core->bmciColors[i].rgbtGreen = src_colors[i].rgbGreen;
525                 core->bmciColors[i].rgbtBlue  = src_colors[i].rgbBlue;
526             }
527         }
528     }
529     else
530     {
531         dst->bmiHeader.biClrUsed   = src->bmiHeader.biClrUsed;
532         dst->bmiHeader.biSizeImage = src->bmiHeader.biSizeImage;
533
534         if (src->bmiHeader.biCompression == BI_BITFIELDS)
535             /* bitfields are always at bmiColors even in larger structures */
536             memcpy( dst->bmiColors, src->bmiColors, 3 * sizeof(DWORD) );
537         else if (colors)
538         {
539             void *colorptr = (char *)dst + dst->bmiHeader.biSize;
540             unsigned int size;
541
542             if (coloruse == DIB_PAL_COLORS)
543                 size = colors * sizeof(WORD);
544             else
545                 size = colors * sizeof(RGBQUAD);
546             memcpy( colorptr, src_colors, size );
547         }
548     }
549 }
550
551 /******************************************************************************
552  * GetDIBits [GDI32.@]
553  *
554  * Retrieves bits of bitmap and copies to buffer.
555  *
556  * RETURNS
557  *    Success: Number of scan lines copied from bitmap
558  *    Failure: 0
559  */
560 INT WINAPI GetDIBits(
561     HDC hdc,         /* [in]  Handle to device context */
562     HBITMAP hbitmap, /* [in]  Handle to bitmap */
563     UINT startscan,  /* [in]  First scan line to set in dest bitmap */
564     UINT lines,      /* [in]  Number of scan lines to copy */
565     LPVOID bits,       /* [out] Address of array for bitmap bits */
566     BITMAPINFO * info, /* [out] Address of structure with bitmap data */
567     UINT coloruse)   /* [in]  RGB or palette index */
568 {
569     DC * dc;
570     BITMAPOBJ * bmp;
571     int i;
572     int bitmap_type;
573     LONG width;
574     LONG height;
575     WORD planes, bpp;
576     DWORD compr, size;
577     char dst_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
578     BITMAPINFO *dst_info = (BITMAPINFO *)dst_bmibuf;
579
580     if (!info) return 0;
581
582     bitmap_type = DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size);
583     if (bitmap_type == -1)
584     {
585         ERR("Invalid bitmap format\n");
586         return 0;
587     }
588     if (!(dc = get_dc_ptr( hdc )))
589     {
590         SetLastError( ERROR_INVALID_PARAMETER );
591         return 0;
592     }
593     update_dc( dc );
594     if (!(bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
595     {
596         release_dc_ptr( dc );
597         return 0;
598     }
599
600
601     if (bpp == 0) /* query bitmap info only */
602     {
603         lines = fill_query_info( info, bmp );
604         goto done;
605     }
606
607     /* Since info may be a BITMAPCOREINFO or any of the larger BITMAPINFO structures, we'll use our
608        own copy and transfer the colour info back at the end */
609
610     dst_info->bmiHeader.biSize          = sizeof(dst_info->bmiHeader);
611     dst_info->bmiHeader.biWidth         = width;
612     dst_info->bmiHeader.biHeight        = height;
613     dst_info->bmiHeader.biPlanes        = planes;
614     dst_info->bmiHeader.biBitCount      = bpp;
615     dst_info->bmiHeader.biCompression   = compr;
616     dst_info->bmiHeader.biSizeImage     = DIB_GetDIBImageBytes( width, height, bpp );
617     dst_info->bmiHeader.biXPelsPerMeter = 0;
618     dst_info->bmiHeader.biYPelsPerMeter = 0;
619     dst_info->bmiHeader.biClrUsed       = 0;
620     dst_info->bmiHeader.biClrImportant  = 0;
621
622     switch (bpp)
623     {
624     case 1:
625     case 4:
626     case 8:
627     {
628         unsigned int colors = 1 << bpp;
629
630         if (coloruse == DIB_PAL_COLORS)
631         {
632             WORD *index = (WORD*)dst_info->bmiColors;
633             for (i = 0; i < colors; i++, index++)
634                 *index = i;
635         }
636
637         /* If the bitmap object is a dib section at the
638            same color depth then get the color map from it */
639         else if (bmp->dib && bpp == bmp->dib->dsBm.bmBitsPixel)
640         {
641             colors = min( colors, bmp->nb_colors );
642             if (colors != 1 << bpp) dst_info->bmiHeader.biClrUsed = colors;
643             memcpy( dst_info->bmiColors, bmp->color_table, colors * sizeof(RGBQUAD) );
644         }
645
646         /* For color DDBs in native depth (mono DDBs always have a black/white palette):
647            Generate the color map from the selected palette */
648
649         else if (bpp > 1 && bpp == bmp->bitmap.bmBitsPixel)
650         {
651             PALETTEENTRY palEntry[256];
652
653             memset( palEntry, 0, sizeof(palEntry) );
654             if (!GetPaletteEntries( dc->hPalette, 0, colors, palEntry ))
655             {
656                 lines = 0;
657                 goto done;
658             }
659
660             for (i = 0; i < colors; i++)
661             {
662                 dst_info->bmiColors[i].rgbRed      = palEntry[i].peRed;
663                 dst_info->bmiColors[i].rgbGreen    = palEntry[i].peGreen;
664                 dst_info->bmiColors[i].rgbBlue     = palEntry[i].peBlue;
665                 dst_info->bmiColors[i].rgbReserved = 0;
666             }
667         }
668         else
669         {
670             switch (bpp)
671             {
672             case 1:
673                 dst_info->bmiColors[0].rgbRed = dst_info->bmiColors[0].rgbGreen = dst_info->bmiColors[0].rgbBlue = 0;
674                 dst_info->bmiColors[0].rgbReserved = 0;
675                 dst_info->bmiColors[1].rgbRed = dst_info->bmiColors[1].rgbGreen = dst_info->bmiColors[1].rgbBlue = 0xff;
676                 dst_info->bmiColors[1].rgbReserved = 0;
677                 break;
678
679             case 4:
680                 /* The EGA palette is the first and last 8 colours of the default palette
681                    with the innermost pair swapped */
682                 memcpy(dst_info->bmiColors,     DefLogPaletteQuads,      7 * sizeof(RGBQUAD));
683                 memcpy(dst_info->bmiColors + 7, DefLogPaletteQuads + 12, 1 * sizeof(RGBQUAD));
684                 memcpy(dst_info->bmiColors + 8, DefLogPaletteQuads +  7, 1 * sizeof(RGBQUAD));
685                 memcpy(dst_info->bmiColors + 9, DefLogPaletteQuads + 13, 7 * sizeof(RGBQUAD));
686                 break;
687
688             case 8:
689                 memcpy(dst_info->bmiColors, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
690                 memcpy(dst_info->bmiColors + 246, DefLogPaletteQuads + 10, 10 * sizeof(RGBQUAD));
691                 for (i = 10; i < 246; i++)
692                 {
693                     dst_info->bmiColors[i].rgbRed      = (i & 0x07) << 5;
694                     dst_info->bmiColors[i].rgbGreen    = (i & 0x38) << 2;
695                     dst_info->bmiColors[i].rgbBlue     =  i & 0xc0;
696                     dst_info->bmiColors[i].rgbReserved = 0;
697                 }
698             }
699         }
700         break;
701     }
702
703     case 15:
704         if (dst_info->bmiHeader.biCompression == BI_BITFIELDS)
705             memcpy( dst_info->bmiColors, bit_fields_555, sizeof(bit_fields_555) );
706         break;
707
708     case 16:
709         if (dst_info->bmiHeader.biCompression == BI_BITFIELDS)
710         {
711             if (bmp->dib)
712             {
713                 if (bmp->dib->dsBmih.biCompression == BI_BITFIELDS && bmp->dib->dsBmih.biBitCount == bpp)
714                     memcpy( dst_info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
715                 else
716                     memcpy( dst_info->bmiColors, bit_fields_555, sizeof(bit_fields_555) );
717             }
718             else
719                 memcpy( dst_info->bmiColors, bit_fields_565, sizeof(bit_fields_565) );
720         }
721         break;
722
723     case 24:
724     case 32:
725         if (dst_info->bmiHeader.biCompression == BI_BITFIELDS)
726         {
727             if (bmp->dib && bmp->dib->dsBmih.biCompression == BI_BITFIELDS && bmp->dib->dsBmih.biBitCount == bpp)
728                 memcpy( dst_info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
729             else
730                 memcpy( dst_info->bmiColors, bit_fields_888, sizeof(bit_fields_888) );
731         }
732         break;
733     }
734
735     if (bits && lines)
736     {
737         /* If the bitmap object already have a dib section that contains image data, get the bits from it */
738         if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
739         {
740             /*FIXME: Only RGB dibs supported for now */
741             unsigned int srcwidth = bmp->dib->dsBm.bmWidth;
742             int srcwidthb = bmp->dib->dsBm.bmWidthBytes;
743             unsigned int dstwidth = width;
744             int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
745             LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
746             unsigned int x, y, width, widthb;
747
748             /*
749              * If copying from a top-down source bitmap, move the source
750              * pointer to the end of the source bitmap and negate the width
751              * so that we copy the bits upside-down.
752              */
753             if (bmp->dib->dsBmih.biHeight < 0)
754             {
755                 sbits += (srcwidthb * (int)(abs(bmp->dib->dsBmih.biHeight) - 2 * startscan - 1));
756                 srcwidthb = -srcwidthb;
757             }
758             /*Same for the destination.*/
759             if (height < 0)
760             {
761                 dbits = (LPBYTE)bits + (dstwidthb * (lines - 1));
762                 dstwidthb = -dstwidthb;
763             }
764             switch( bpp ) {
765
766             case 15:
767             case 16: /* 16 bpp dstDIB */
768                 {
769                     LPWORD dstbits = (LPWORD)dbits;
770                     WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
771
772                     /* FIXME: BI_BITFIELDS not supported yet */
773
774                     switch(bmp->dib->dsBm.bmBitsPixel) {
775
776                     case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
777                         {
778                             widthb = min(abs(srcwidthb), abs(dstwidthb));
779                             /* FIXME: BI_BITFIELDS not supported yet */
780                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
781                                 memcpy(dbits, sbits, widthb);
782                         }
783                         break;
784
785                     case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
786                         {
787                             LPBYTE srcbits = sbits;
788
789                             width = min(srcwidth, dstwidth);
790                             for( y = 0; y < lines; y++) {
791                                 for( x = 0; x < width; x++, srcbits += 3)
792                                     *dstbits++ = ((srcbits[0] >> 3) & bmask) |
793                                                  (((WORD)srcbits[1] << 2) & gmask) |
794                                                  (((WORD)srcbits[2] << 7) & rmask);
795
796                                 dstbits = (LPWORD)(dbits+=dstwidthb);
797                                 srcbits = (sbits += srcwidthb);
798                             }
799                         }
800                         break;
801
802                     case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
803                         {
804                             LPDWORD srcbits = (LPDWORD)sbits;
805                             DWORD val;
806
807                             width = min(srcwidth, dstwidth);
808                             for( y = 0; y < lines; y++) {
809                                 for( x = 0; x < width; x++ ) {
810                                     val = *srcbits++;
811                                     *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
812                                                        ((val >> 9) & rmask));
813                                 }
814                                 dstbits = (LPWORD)(dbits+=dstwidthb);
815                                 srcbits = (LPDWORD)(sbits+=srcwidthb);
816                             }
817                         }
818                         break;
819
820                     default: /* ? bit bmp -> 16 bit DIB */
821                         FIXME("15/16 bit DIB %d bit bitmap\n",
822                         bmp->bitmap.bmBitsPixel);
823                         break;
824                     }
825                 }
826                 break;
827
828             case 24: /* 24 bpp dstDIB */
829                 {
830                     LPBYTE dstbits = dbits;
831
832                     switch(bmp->dib->dsBm.bmBitsPixel) {
833
834                     case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
835                         {
836                             LPWORD srcbits = (LPWORD)sbits;
837                             WORD val;
838
839                             width = min(srcwidth, dstwidth);
840                             /* FIXME: BI_BITFIELDS not supported yet */
841                             for( y = 0; y < lines; y++) {
842                                 for( x = 0; x < width; x++ ) {
843                                     val = *srcbits++;
844                                     *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
845                                     *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
846                                     *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
847                                 }
848                                 dstbits = dbits+=dstwidthb;
849                                 srcbits = (LPWORD)(sbits+=srcwidthb);
850                             }
851                         }
852                         break;
853
854                     case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
855                         {
856                             widthb = min(abs(srcwidthb), abs(dstwidthb));
857                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
858                                 memcpy(dbits, sbits, widthb);
859                         }
860                         break;
861
862                     case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
863                         {
864                             LPBYTE srcbits = sbits;
865
866                             width = min(srcwidth, dstwidth);
867                             for( y = 0; y < lines; y++) {
868                                 for( x = 0; x < width; x++, srcbits++ ) {
869                                     *dstbits++ = *srcbits++;
870                                     *dstbits++ = *srcbits++;
871                                     *dstbits++ = *srcbits++;
872                                 }
873                                 dstbits = dbits+=dstwidthb;
874                                 srcbits = sbits+=srcwidthb;
875                             }
876                         }
877                         break;
878
879                     default: /* ? bit bmp -> 24 bit DIB */
880                         FIXME("24 bit DIB %d bit bitmap\n",
881                               bmp->bitmap.bmBitsPixel);
882                         break;
883                     }
884                 }
885                 break;
886
887             case 32: /* 32 bpp dstDIB */
888                 {
889                     LPDWORD dstbits = (LPDWORD)dbits;
890
891                     /* FIXME: BI_BITFIELDS not supported yet */
892
893                     switch(bmp->dib->dsBm.bmBitsPixel) {
894                         case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
895                         {
896                             LPWORD srcbits = (LPWORD)sbits;
897                             DWORD val;
898
899                             width = min(srcwidth, dstwidth);
900                             /* FIXME: BI_BITFIELDS not supported yet */
901                             for( y = 0; y < lines; y++) {
902                                 for( x = 0; x < width; x++ ) {
903                                     val = (DWORD)*srcbits++;
904                                     *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
905                                                  ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
906                                                  ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
907                                 }
908                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
909                                 srcbits=(LPWORD)(sbits+=srcwidthb);
910                             }
911                         }
912                         break;
913
914                     case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
915                         {
916                             LPBYTE srcbits = sbits;
917
918                             width = min(srcwidth, dstwidth);
919                             for( y = 0; y < lines; y++) {
920                                 for( x = 0; x < width; x++, srcbits+=3 )
921                                     *dstbits++ =  srcbits[0] |
922                                                  (srcbits[1] <<  8) |
923                                                  (srcbits[2] << 16);
924                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
925                                 srcbits=(sbits+=srcwidthb);
926                             }
927                         }
928                         break;
929
930                     case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
931                         {
932                             widthb = min(abs(srcwidthb), abs(dstwidthb));
933                             /* FIXME: BI_BITFIELDS not supported yet */
934                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
935                                 memcpy(dbits, sbits, widthb);
936                             }
937                         }
938                         break;
939
940                     default: /* ? bit bmp -> 32 bit DIB */
941                         FIXME("32 bit DIB %d bit bitmap\n",
942                         bmp->bitmap.bmBitsPixel);
943                         break;
944                     }
945                 }
946                 break;
947
948             default: /* ? bit DIB */
949                 FIXME("Unsupported DIB depth %d\n", dst_info->bmiHeader.biBitCount);
950                 break;
951             }
952         }
953         /* Otherwise, get bits from the XImage */
954         else
955         {
956             PHYSDEV physdev = GET_DC_PHYSDEV( dc, pGetDIBits );
957             if (!BITMAP_SetOwnerDC( hbitmap, physdev )) lines = 0;
958             else lines = physdev->funcs->pGetDIBits( physdev, hbitmap, startscan,
959                                                      lines, bits, dst_info, coloruse );
960         }
961     }
962     else lines = abs(height);
963
964     copy_color_info( info, dst_info, coloruse );
965
966 done:
967     release_dc_ptr( dc );
968     GDI_ReleaseObj( hbitmap );
969     return lines;
970 }
971
972
973 /***********************************************************************
974  *           CreateDIBitmap    (GDI32.@)
975  *
976  * Creates a DDB (device dependent bitmap) from a DIB.
977  * The DDB will have the same color depth as the reference DC.
978  */
979 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
980                             DWORD init, LPCVOID bits, const BITMAPINFO *data,
981                             UINT coloruse )
982 {
983     HBITMAP handle;
984     LONG width;
985     LONG height;
986     WORD planes, bpp;
987     DWORD compr, size;
988
989     if (!header) return 0;
990
991     if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &size ) == -1) return 0;
992     
993     if (width < 0)
994     {
995         TRACE("Bitmap has a negative width\n");
996         return 0;
997     }
998     
999     /* Top-down DIBs have a negative height */
1000     if (height < 0) height = -height;
1001
1002     TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1003            hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
1004     
1005     if (hdc == NULL)
1006         handle = CreateBitmap( width, height, 1, 1, NULL );
1007     else
1008         handle = CreateCompatibleBitmap( hdc, width, height );
1009
1010     if (handle)
1011     {
1012         if (init & CBM_INIT)
1013         {
1014             if (SetDIBits( hdc, handle, 0, height, bits, data, coloruse ) == 0)
1015             {
1016                 DeleteObject( handle );
1017                 handle = 0;
1018             }
1019         }
1020     }
1021
1022     return handle;
1023 }
1024
1025 /* Copy/synthesize RGB palette from BITMAPINFO. Ripped from dlls/winex11.drv/dib.c */
1026 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1027 {
1028     RGBQUAD *colorTable;
1029     unsigned int colors, i;
1030     BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
1031
1032     if (core_info)
1033     {
1034         colors = 1 << ((const BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
1035     }
1036     else
1037     {
1038         colors = info->bmiHeader.biClrUsed;
1039         if (!colors) colors = 1 << info->bmiHeader.biBitCount;
1040     }
1041
1042     if (colors > 256) {
1043         ERR("called with >256 colors!\n");
1044         return;
1045     }
1046
1047     if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1048
1049     if(coloruse == DIB_RGB_COLORS)
1050     {
1051         if (core_info)
1052         {
1053            /* Convert RGBTRIPLEs to RGBQUADs */
1054            for (i=0; i < colors; i++)
1055            {
1056                colorTable[i].rgbRed   = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
1057                colorTable[i].rgbGreen = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
1058                colorTable[i].rgbBlue  = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
1059                colorTable[i].rgbReserved = 0;
1060            }
1061         }
1062         else
1063         {
1064             memcpy(colorTable, (const BYTE*) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
1065         }
1066     }
1067     else
1068     {
1069         PALETTEENTRY entries[256];
1070         const WORD *index = (const WORD*) ((const BYTE*) info + (WORD) info->bmiHeader.biSize);
1071         UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1072
1073         for (i = 0; i < colors; i++, index++)
1074         {
1075             PALETTEENTRY *entry = &entries[*index % count];
1076             colorTable[i].rgbRed = entry->peRed;
1077             colorTable[i].rgbGreen = entry->peGreen;
1078             colorTable[i].rgbBlue = entry->peBlue;
1079             colorTable[i].rgbReserved = 0;
1080         }
1081     }
1082     bmp->color_table = colorTable;
1083     bmp->nb_colors = colors;
1084 }
1085
1086 /***********************************************************************
1087  *           CreateDIBSection    (GDI32.@)
1088  */
1089 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1090                                 VOID **bits, HANDLE section, DWORD offset)
1091 {
1092     HBITMAP ret = 0;
1093     DC *dc;
1094     BOOL bDesktopDC = FALSE;
1095     DIBSECTION *dib;
1096     BITMAPOBJ *bmp;
1097     int bitmap_type;
1098     LONG width, height;
1099     WORD planes, bpp;
1100     DWORD compression, sizeImage;
1101     void *mapBits = NULL;
1102
1103     if(!bmi){
1104         if(bits) *bits = NULL;
1105         return NULL;
1106     }
1107
1108     if (((bitmap_type = DIB_GetBitmapInfo( &bmi->bmiHeader, &width, &height,
1109                                            &planes, &bpp, &compression, &sizeImage )) == -1))
1110         return 0;
1111
1112     switch (bpp)
1113     {
1114     case 16:
1115     case 32:
1116         if (compression == BI_BITFIELDS) break;
1117         /* fall through */
1118     case 1:
1119     case 4:
1120     case 8:
1121     case 24:
1122         if (compression == BI_RGB) break;
1123         /* fall through */
1124     default:
1125         WARN( "invalid %u bpp compression %u\n", bpp, compression );
1126         return 0;
1127     }
1128
1129     if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1130
1131     TRACE("format (%d,%d), planes %d, bpp %d, %s, size %d %s\n",
1132           width, height, planes, bpp, compression == BI_BITFIELDS? "BI_BITFIELDS" : "BI_RGB",
1133           sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1134
1135     dib->dsBm.bmType       = 0;
1136     dib->dsBm.bmWidth      = width;
1137     dib->dsBm.bmHeight     = height >= 0 ? height : -height;
1138     dib->dsBm.bmWidthBytes = DIB_GetDIBWidthBytes(width, bpp);
1139     dib->dsBm.bmPlanes     = planes;
1140     dib->dsBm.bmBitsPixel  = bpp;
1141     dib->dsBm.bmBits       = NULL;
1142
1143     if (!bitmap_type)  /* core header */
1144     {
1145         /* convert the BITMAPCOREHEADER to a BITMAPINFOHEADER */
1146         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1147         dib->dsBmih.biWidth = width;
1148         dib->dsBmih.biHeight = height;
1149         dib->dsBmih.biPlanes = planes;
1150         dib->dsBmih.biBitCount = bpp;
1151         dib->dsBmih.biCompression = compression;
1152         dib->dsBmih.biXPelsPerMeter = 0;
1153         dib->dsBmih.biYPelsPerMeter = 0;
1154         dib->dsBmih.biClrUsed = 0;
1155         dib->dsBmih.biClrImportant = 0;
1156     }
1157     else
1158     {
1159         /* truncate extended bitmap headers (BITMAPV4HEADER etc.) */
1160         dib->dsBmih = bmi->bmiHeader;
1161         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1162     }
1163
1164     /* set number of entries in bmi.bmiColors table */
1165     if( bpp <= 8 )
1166         dib->dsBmih.biClrUsed = 1 << bpp;
1167
1168     dib->dsBmih.biSizeImage = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
1169
1170     /* set dsBitfields values */
1171     dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1172
1173     if((bpp == 15 || bpp == 16) && compression == BI_RGB)
1174     {
1175         /* In this case Windows changes biCompression to BI_BITFIELDS,
1176            however for now we won't do this, as there are a lot
1177            of places where BI_BITFIELDS is currently unsupported. */
1178
1179         /* dib->dsBmih.biCompression = compression = BI_BITFIELDS;*/
1180         dib->dsBitfields[0] = 0x7c00;
1181         dib->dsBitfields[1] = 0x03e0;
1182         dib->dsBitfields[2] = 0x001f;
1183     }
1184     else if(compression == BI_BITFIELDS)
1185     {
1186         dib->dsBitfields[0] =  *(const DWORD *)bmi->bmiColors;
1187         dib->dsBitfields[1] =  *((const DWORD *)bmi->bmiColors + 1);
1188         dib->dsBitfields[2] =  *((const DWORD *)bmi->bmiColors + 2);
1189     }
1190
1191     /* get storage location for DIB bits */
1192
1193     if (section)
1194     {
1195         SYSTEM_INFO SystemInfo;
1196         DWORD mapOffset;
1197         INT mapSize;
1198
1199         GetSystemInfo( &SystemInfo );
1200         mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1201         mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1202         mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1203         if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1204     }
1205     else
1206     {
1207         offset = 0;
1208         dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1209                                          MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1210     }
1211     dib->dshSection = section;
1212     dib->dsOffset = offset;
1213
1214     if (!dib->dsBm.bmBits)
1215     {
1216         HeapFree( GetProcessHeap(), 0, dib );
1217         return 0;
1218     }
1219
1220     /* If the reference hdc is null, take the desktop dc */
1221     if (hdc == 0)
1222     {
1223         hdc = CreateCompatibleDC(0);
1224         bDesktopDC = TRUE;
1225     }
1226
1227     if (!(dc = get_dc_ptr( hdc ))) goto error;
1228
1229     /* create Device Dependent Bitmap and add DIB pointer */
1230     ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1231                         (bpp == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1232
1233     if (ret && ((bmp = GDI_GetObjPtr(ret, OBJ_BITMAP))))
1234     {
1235         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pCreateDIBSection );
1236         bmp->dib = dib;
1237         bmp->funcs = physdev->funcs;
1238         /* create local copy of DIB palette */
1239         if (bpp <= 8) DIB_CopyColorTable( dc, bmp, usage, bmi );
1240         GDI_ReleaseObj( ret );
1241
1242         if (!physdev->funcs->pCreateDIBSection( physdev, ret, bmi, usage ))
1243         {
1244             DeleteObject( ret );
1245             ret = 0;
1246         }
1247     }
1248
1249     release_dc_ptr( dc );
1250     if (bDesktopDC) DeleteDC( hdc );
1251     if (ret && bits) *bits = dib->dsBm.bmBits;
1252     return ret;
1253
1254 error:
1255     if (bDesktopDC) DeleteDC( hdc );
1256     if (section) UnmapViewOfFile( mapBits );
1257     else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1258     HeapFree( GetProcessHeap(), 0, dib );
1259     return 0;
1260 }