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