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