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