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