ntdll: Initialize pointers to NULL (Coverity).
[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 (!bits) return 0;
368
369     if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
370
371     if(dc->funcs->pSetDIBitsToDevice)
372         ret = dc->funcs->pSetDIBitsToDevice( dc->physDev, xDest, yDest, cx, cy, xSrc,
373                                              ySrc, startscan, lines, bits,
374                                              info, coloruse );
375     else {
376         FIXME("unimplemented on hdc %p\n", hdc);
377         ret = 0;
378     }
379
380     GDI_ReleaseObj( hdc );
381     return ret;
382 }
383
384 /***********************************************************************
385  *           SetDIBColorTable    (GDI32.@)
386  */
387 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUAD *colors )
388 {
389     DC * dc;
390     UINT result = 0;
391     BITMAPOBJ * bitmap;
392
393     if (!(dc = DC_GetDCPtr( hdc ))) return 0;
394
395     if ((bitmap = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC )))
396     {
397         /* Check if currently selected bitmap is a DIB */
398         if (bitmap->color_table)
399         {
400             if (startpos < bitmap->nb_colors)
401             {
402                 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
403                 memcpy(bitmap->color_table + startpos, colors, entries * sizeof(RGBQUAD));
404                 result = entries;
405             }
406         }
407         GDI_ReleaseObj( dc->hBitmap );
408     }
409
410     if (dc->funcs->pSetDIBColorTable)
411         dc->funcs->pSetDIBColorTable(dc->physDev, startpos, entries, colors);
412
413     GDI_ReleaseObj( hdc );
414     return result;
415 }
416
417
418 /***********************************************************************
419  *           GetDIBColorTable    (GDI32.@)
420  */
421 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
422 {
423     DC * dc;
424     UINT result = 0;
425
426     if (!(dc = DC_GetDCPtr( hdc ))) return 0;
427
428     if (dc->funcs->pGetDIBColorTable)
429         result = dc->funcs->pGetDIBColorTable(dc->physDev, startpos, entries, colors);
430     else
431     {
432         BITMAPOBJ *bitmap = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
433         if (bitmap)
434         {
435             /* Check if currently selected bitmap is a DIB */
436             if (bitmap->color_table)
437             {
438                 if (startpos < bitmap->nb_colors)
439                 {
440                     if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
441                     memcpy(colors, bitmap->color_table + startpos, entries * sizeof(RGBQUAD));
442                     result = entries;
443                 }
444             }
445             GDI_ReleaseObj( dc->hBitmap );
446         }
447     }
448     GDI_ReleaseObj( hdc );
449     return result;
450 }
451
452 /* FIXME the following two structs should be combined with __sysPalTemplate in
453    objects/color.c - this should happen after de-X11-ing both of these
454    files.
455    NB. RGBQUAD and PALETTEENTRY have different orderings of red, green
456    and blue - sigh */
457
458 static const RGBQUAD EGAColorsQuads[16] = {
459 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
460     { 0x00, 0x00, 0x00, 0x00 },
461     { 0x00, 0x00, 0x80, 0x00 },
462     { 0x00, 0x80, 0x00, 0x00 },
463     { 0x00, 0x80, 0x80, 0x00 },
464     { 0x80, 0x00, 0x00, 0x00 },
465     { 0x80, 0x00, 0x80, 0x00 },
466     { 0x80, 0x80, 0x00, 0x00 },
467     { 0x80, 0x80, 0x80, 0x00 },
468     { 0xc0, 0xc0, 0xc0, 0x00 },
469     { 0x00, 0x00, 0xff, 0x00 },
470     { 0x00, 0xff, 0x00, 0x00 },
471     { 0x00, 0xff, 0xff, 0x00 },
472     { 0xff, 0x00, 0x00, 0x00 },
473     { 0xff, 0x00, 0xff, 0x00 },
474     { 0xff, 0xff, 0x00, 0x00 },
475     { 0xff, 0xff, 0xff, 0x00 }
476 };
477
478 static const RGBTRIPLE EGAColorsTriples[16] = {
479 /* rgbBlue, rgbGreen, rgbRed */
480     { 0x00, 0x00, 0x00 },
481     { 0x00, 0x00, 0x80 },
482     { 0x00, 0x80, 0x00 },
483     { 0x00, 0x80, 0x80 },
484     { 0x80, 0x00, 0x00 },
485     { 0x80, 0x00, 0x80 },
486     { 0x80, 0x80, 0x00 },
487     { 0x80, 0x80, 0x80 },
488     { 0xc0, 0xc0, 0xc0 },
489     { 0x00, 0x00, 0xff },
490     { 0x00, 0xff, 0x00 },
491     { 0x00, 0xff, 0xff },
492     { 0xff, 0x00, 0x00 } ,
493     { 0xff, 0x00, 0xff },
494     { 0xff, 0xff, 0x00 },
495     { 0xff, 0xff, 0xff }
496 };
497
498 static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
499 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
500     { 0x00, 0x00, 0x00, 0x00 },
501     { 0x00, 0x00, 0x80, 0x00 },
502     { 0x00, 0x80, 0x00, 0x00 },
503     { 0x00, 0x80, 0x80, 0x00 },
504     { 0x80, 0x00, 0x00, 0x00 },
505     { 0x80, 0x00, 0x80, 0x00 },
506     { 0x80, 0x80, 0x00, 0x00 },
507     { 0xc0, 0xc0, 0xc0, 0x00 },
508     { 0xc0, 0xdc, 0xc0, 0x00 },
509     { 0xf0, 0xca, 0xa6, 0x00 },
510     { 0xf0, 0xfb, 0xff, 0x00 },
511     { 0xa4, 0xa0, 0xa0, 0x00 },
512     { 0x80, 0x80, 0x80, 0x00 },
513     { 0x00, 0x00, 0xf0, 0x00 },
514     { 0x00, 0xff, 0x00, 0x00 },
515     { 0x00, 0xff, 0xff, 0x00 },
516     { 0xff, 0x00, 0x00, 0x00 },
517     { 0xff, 0x00, 0xff, 0x00 },
518     { 0xff, 0xff, 0x00, 0x00 },
519     { 0xff, 0xff, 0xff, 0x00 }
520 };
521
522 static const RGBTRIPLE DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
523 /* rgbBlue, rgbGreen, rgbRed */
524     { 0x00, 0x00, 0x00 },
525     { 0x00, 0x00, 0x80 },
526     { 0x00, 0x80, 0x00 },
527     { 0x00, 0x80, 0x80 },
528     { 0x80, 0x00, 0x00 },
529     { 0x80, 0x00, 0x80 },
530     { 0x80, 0x80, 0x00 },
531     { 0xc0, 0xc0, 0xc0 },
532     { 0xc0, 0xdc, 0xc0 },
533     { 0xf0, 0xca, 0xa6 },
534     { 0xf0, 0xfb, 0xff },
535     { 0xa4, 0xa0, 0xa0 },
536     { 0x80, 0x80, 0x80 },
537     { 0x00, 0x00, 0xf0 },
538     { 0x00, 0xff, 0x00 },
539     { 0x00, 0xff, 0xff },
540     { 0xff, 0x00, 0x00 },
541     { 0xff, 0x00, 0xff },
542     { 0xff, 0xff, 0x00 },
543     { 0xff, 0xff, 0xff}
544 };
545
546
547 /******************************************************************************
548  * GetDIBits [GDI32.@]
549  *
550  * Retrieves bits of bitmap and copies to buffer.
551  *
552  * RETURNS
553  *    Success: Number of scan lines copied from bitmap
554  *    Failure: 0
555  *
556  * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_87eb.asp
557  */
558 INT WINAPI GetDIBits(
559     HDC hdc,         /* [in]  Handle to device context */
560     HBITMAP hbitmap, /* [in]  Handle to bitmap */
561     UINT startscan,  /* [in]  First scan line to set in dest bitmap */
562     UINT lines,      /* [in]  Number of scan lines to copy */
563     LPVOID bits,       /* [out] Address of array for bitmap bits */
564     BITMAPINFO * info, /* [out] Address of structure with bitmap data */
565     UINT coloruse)   /* [in]  RGB or palette index */
566 {
567     DC * dc;
568     BITMAPOBJ * bmp;
569     int i;
570     int bitmap_type;
571     BOOL core_header;
572     LONG width;
573     LONG height;
574     WORD planes, bpp;
575     DWORD compr, size;
576     void* colorPtr;
577     RGBTRIPLE* rgbTriples;
578     RGBQUAD* rgbQuads;
579
580     if (!info) return 0;
581
582     bitmap_type = DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size);
583     if (bitmap_type == -1)
584     {
585         ERR("Invalid bitmap format\n");
586         return 0;
587     }
588     core_header = (bitmap_type == 0);
589     if (!(dc = DC_GetDCUpdate( hdc )))
590     {
591         SetLastError( ERROR_INVALID_PARAMETER );
592         return 0;
593     }
594     if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
595     {
596         GDI_ReleaseObj( hdc );
597         return 0;
598     }
599
600     colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
601     rgbTriples = (RGBTRIPLE *) colorPtr;
602     rgbQuads = (RGBQUAD *) colorPtr;
603
604     /* Transfer color info */
605
606     if (bpp <= 8 && bpp > 0)
607     {
608         if (!core_header) info->bmiHeader.biClrUsed = 0;
609
610         /* If the bitmap object already has a dib section at the
611            same color depth then get the color map from it */
612         if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == bpp) {
613             if(coloruse == DIB_RGB_COLORS) {
614                 unsigned int colors = min( bmp->nb_colors, 1 << bpp );
615
616                 if (core_header)
617                 {
618                     /* Convert the color table (RGBQUAD to RGBTRIPLE) */
619                     RGBTRIPLE* index = rgbTriples;
620
621                     for (i=0; i < colors; i++, index++)
622                     {
623                         index->rgbtRed   = bmp->color_table[i].rgbRed;
624                         index->rgbtGreen = bmp->color_table[i].rgbGreen;
625                         index->rgbtBlue  = bmp->color_table[i].rgbBlue;
626                     }
627                 }
628                 else
629                 {
630                     if (colors != 1 << bpp) info->bmiHeader.biClrUsed = colors;
631                     memcpy(colorPtr, bmp->color_table, colors * sizeof(RGBQUAD));
632                 }
633             }
634             else {
635                 WORD *index = colorPtr;
636                 for(i = 0; i < 1 << info->bmiHeader.biBitCount; i++, index++)
637                     *index = i;
638             }
639         }
640         else {
641             if(bpp >= bmp->bitmap.bmBitsPixel) {
642                 /* Generate the color map from the selected palette */
643                 PALETTEENTRY palEntry[256];
644
645                 memset( palEntry, 0, sizeof(palEntry) );
646                 if (!GetPaletteEntries( dc->hPalette, 0, 1 << bmp->bitmap.bmBitsPixel, palEntry ))
647                 {
648                     GDI_ReleaseObj( hdc );
649                     GDI_ReleaseObj( hbitmap );
650                     return 0;
651                 }
652                 for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++) {
653                     if (coloruse == DIB_RGB_COLORS) {
654                         if (core_header)
655                         {
656                             rgbTriples[i].rgbtRed   = palEntry[i].peRed;
657                             rgbTriples[i].rgbtGreen = palEntry[i].peGreen;
658                             rgbTriples[i].rgbtBlue  = palEntry[i].peBlue;
659                         }
660                         else
661                         {
662                             rgbQuads[i].rgbRed      = palEntry[i].peRed;
663                             rgbQuads[i].rgbGreen    = palEntry[i].peGreen;
664                             rgbQuads[i].rgbBlue     = palEntry[i].peBlue;
665                             rgbQuads[i].rgbReserved = 0;
666                         }
667                     }
668                     else ((WORD *)colorPtr)[i] = (WORD)i;
669                 }
670             } else {
671                 switch (bpp) {
672                 case 1:
673                     if (core_header)
674                     {
675                         rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
676                             rgbTriples[0].rgbtBlue = 0;
677                         rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
678                             rgbTriples[1].rgbtBlue = 0xff;
679                     }
680                     else
681                     {    
682                         rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
683                             rgbQuads[0].rgbBlue = 0;
684                         rgbQuads[0].rgbReserved = 0;
685                         rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
686                             rgbQuads[1].rgbBlue = 0xff;
687                         rgbQuads[1].rgbReserved = 0;
688                     }
689                     break;
690
691                 case 4:
692                     if (core_header)
693                         memcpy(colorPtr, EGAColorsTriples, sizeof(EGAColorsTriples));
694                     else
695                         memcpy(colorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
696
697                     break;
698
699                 case 8:
700                     {
701                         if (core_header)
702                         {
703                             INT r, g, b;
704                             RGBTRIPLE *color;
705
706                             memcpy(rgbTriples, DefLogPaletteTriples,
707                                        10 * sizeof(RGBTRIPLE));
708                             memcpy(rgbTriples + 246, DefLogPaletteTriples + 10,
709                                        10 * sizeof(RGBTRIPLE));
710                             color = rgbTriples + 10;
711                             for(r = 0; r <= 5; r++) /* FIXME */
712                                 for(g = 0; g <= 5; g++)
713                                     for(b = 0; b <= 5; b++) {
714                                         color->rgbtRed =   (r * 0xff) / 5;
715                                         color->rgbtGreen = (g * 0xff) / 5;
716                                         color->rgbtBlue =  (b * 0xff) / 5;
717                                         color++;
718                                     }
719                         }
720                         else
721                         {
722                             INT r, g, b;
723                             RGBQUAD *color;
724
725                             memcpy(rgbQuads, DefLogPaletteQuads,
726                                        10 * sizeof(RGBQUAD));
727                             memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
728                                    10 * sizeof(RGBQUAD));
729                             color = rgbQuads + 10;
730                             for(r = 0; r <= 5; r++) /* FIXME */
731                                 for(g = 0; g <= 5; g++)
732                                     for(b = 0; b <= 5; b++) {
733                                         color->rgbRed =   (r * 0xff) / 5;
734                                         color->rgbGreen = (g * 0xff) / 5;
735                                         color->rgbBlue =  (b * 0xff) / 5;
736                                         color->rgbReserved = 0;
737                                         color++;
738                                     }
739                         }
740                     }
741                 }
742             }
743         }
744     }
745
746     if (bits && lines)
747     {
748         /* If the bitmap object already have a dib section that contains image data, get the bits from it */
749         if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
750         {
751             /*FIXME: Only RGB dibs supported for now */
752             unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb = bmp->dib->dsBm.bmWidthBytes;
753             unsigned int dstwidth = width;
754             int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
755             LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
756             unsigned int x, y, width, widthb;
757
758             if ((height < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
759             {
760                 dbits = (LPBYTE)bits + (dstwidthb * (lines-1));
761                 dstwidthb = -dstwidthb;
762             }
763
764             switch( bpp ) {
765
766             case 15:
767             case 16: /* 16 bpp dstDIB */
768                 {
769                     LPWORD dstbits = (LPWORD)dbits;
770                     WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
771
772                     /* FIXME: BI_BITFIELDS not supported yet */
773
774                     switch(bmp->dib->dsBm.bmBitsPixel) {
775
776                     case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
777                         {
778                             widthb = min(srcwidthb, abs(dstwidthb));
779                             /* FIXME: BI_BITFIELDS not supported yet */
780                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
781                                 memcpy(dbits, sbits, widthb);
782                         }
783                         break;
784
785                     case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
786                         {
787                             LPBYTE srcbits = sbits;
788
789                             width = min(srcwidth, dstwidth);
790                             for( y = 0; y < lines; y++) {
791                                 for( x = 0; x < width; x++, srcbits += 3)
792                                     *dstbits++ = ((srcbits[0] >> 3) & bmask) |
793                                                  (((WORD)srcbits[1] << 2) & gmask) |
794                                                  (((WORD)srcbits[2] << 7) & rmask);
795
796                                 dstbits = (LPWORD)(dbits+=dstwidthb);
797                                 srcbits = (sbits += srcwidthb);
798                             }
799                         }
800                         break;
801
802                     case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
803                         {
804                             LPDWORD srcbits = (LPDWORD)sbits;
805                             DWORD val;
806
807                             width = min(srcwidth, dstwidth);
808                             for( y = 0; y < lines; y++) {
809                                 for( x = 0; x < width; x++ ) {
810                                     val = *srcbits++;
811                                     *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
812                                                        ((val >> 9) & rmask));
813                                 }
814                                 dstbits = (LPWORD)(dbits+=dstwidthb);
815                                 srcbits = (LPDWORD)(sbits+=srcwidthb);
816                             }
817                         }
818                         break;
819
820                     default: /* ? bit bmp -> 16 bit DIB */
821                         FIXME("15/16 bit DIB %d bit bitmap\n",
822                         bmp->bitmap.bmBitsPixel);
823                         break;
824                     }
825                 }
826                 break;
827
828             case 24: /* 24 bpp dstDIB */
829                 {
830                     LPBYTE dstbits = dbits;
831
832                     switch(bmp->dib->dsBm.bmBitsPixel) {
833
834                     case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
835                         {
836                             LPWORD srcbits = (LPWORD)sbits;
837                             WORD val;
838
839                             width = min(srcwidth, dstwidth);
840                             /* FIXME: BI_BITFIELDS not supported yet */
841                             for( y = 0; y < lines; y++) {
842                                 for( x = 0; x < width; x++ ) {
843                                     val = *srcbits++;
844                                     *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
845                                     *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
846                                     *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
847                                 }
848                                 dstbits = (LPBYTE)(dbits+=dstwidthb);
849                                 srcbits = (LPWORD)(sbits+=srcwidthb);
850                             }
851                         }
852                         break;
853
854                     case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
855                         {
856                             widthb = min(srcwidthb, abs(dstwidthb));
857                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
858                                 memcpy(dbits, sbits, widthb);
859                         }
860                         break;
861
862                     case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
863                         {
864                             LPBYTE srcbits = (LPBYTE)sbits;
865
866                             width = min(srcwidth, dstwidth);
867                             for( y = 0; y < lines; y++) {
868                                 for( x = 0; x < width; x++, srcbits++ ) {
869                                     *dstbits++ = *srcbits++;
870                                     *dstbits++ = *srcbits++;
871                                     *dstbits++ = *srcbits++;
872                                 }
873                                 dstbits=(LPBYTE)(dbits+=dstwidthb);
874                                 srcbits = (LPBYTE)(sbits+=srcwidthb);
875                             }
876                         }
877                         break;
878
879                     default: /* ? bit bmp -> 24 bit DIB */
880                         FIXME("24 bit DIB %d bit bitmap\n",
881                               bmp->bitmap.bmBitsPixel);
882                         break;
883                     }
884                 }
885                 break;
886
887             case 32: /* 32 bpp dstDIB */
888                 {
889                     LPDWORD dstbits = (LPDWORD)dbits;
890
891                     /* FIXME: BI_BITFIELDS not supported yet */
892
893                     switch(bmp->dib->dsBm.bmBitsPixel) {
894                         case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
895                         {
896                             LPWORD srcbits = (LPWORD)sbits;
897                             DWORD val;
898
899                             width = min(srcwidth, dstwidth);
900                             /* FIXME: BI_BITFIELDS not supported yet */
901                             for( y = 0; y < lines; y++) {
902                                 for( x = 0; x < width; x++ ) {
903                                     val = (DWORD)*srcbits++;
904                                     *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
905                                                  ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
906                                                  ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
907                                 }
908                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
909                                 srcbits=(LPWORD)(sbits+=srcwidthb);
910                             }
911                         }
912                         break;
913
914                     case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
915                         {
916                             LPBYTE srcbits = sbits;
917
918                             width = min(srcwidth, dstwidth);
919                             for( y = 0; y < lines; y++) {
920                                 for( x = 0; x < width; x++, srcbits+=3 )
921                                     *dstbits++ =  srcbits[0] |
922                                                  (srcbits[1] <<  8) |
923                                                  (srcbits[2] << 16);
924                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
925                                 srcbits=(sbits+=srcwidthb);
926                             }
927                         }
928                         break;
929
930                     case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
931                         {
932                             widthb = min(srcwidthb, abs(dstwidthb));
933                             /* FIXME: BI_BITFIELDS not supported yet */
934                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
935                                 memcpy(dbits, sbits, widthb);
936                             }
937                         }
938                         break;
939
940                     default: /* ? bit bmp -> 32 bit DIB */
941                         FIXME("32 bit DIB %d bit bitmap\n",
942                         bmp->bitmap.bmBitsPixel);
943                         break;
944                     }
945                 }
946                 break;
947
948             default: /* ? bit DIB */
949                 FIXME("Unsupported DIB depth %d\n", info->bmiHeader.biBitCount);
950                 break;
951             }
952         }
953         /* Otherwise, get bits from the XImage */
954         else
955         {
956             if (!bmp->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) lines = 0;
957             else
958             {
959                 if (bmp->funcs && bmp->funcs->pGetDIBits)
960                     lines = bmp->funcs->pGetDIBits( dc->physDev, hbitmap, startscan,
961                                                     lines, bits, info, coloruse );
962                 else
963                     lines = 0;  /* FIXME: should copy from bmp->bitmap.bmBits */
964             }
965         }
966     }
967     else
968     {
969         /* fill in struct members */
970
971         if (bpp == 0)
972         {
973             if (core_header)
974             {
975                 BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
976                 coreheader->bcWidth = bmp->bitmap.bmWidth;
977                 coreheader->bcHeight = bmp->bitmap.bmHeight;
978                 coreheader->bcPlanes = 1;
979                 coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
980             }
981             else
982             {
983                 info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
984                 info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
985                 info->bmiHeader.biPlanes = 1;
986                 info->bmiHeader.biSizeImage =
987                                  DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
988                                                        bmp->bitmap.bmHeight,
989                                                        bmp->bitmap.bmBitsPixel );
990                 switch(bmp->bitmap.bmBitsPixel)
991                 {
992                 case 15:
993                     info->bmiHeader.biBitCount = 16;
994                     info->bmiHeader.biCompression = BI_RGB;
995                     break;
996                     
997                 case 16:
998                     info->bmiHeader.biBitCount = 16;
999                     info->bmiHeader.biCompression = BI_BITFIELDS;
1000                     ((PDWORD)info->bmiColors)[0] = 0xf800;
1001                     ((PDWORD)info->bmiColors)[1] = 0x07e0;
1002                     ((PDWORD)info->bmiColors)[2] = 0x001f;
1003                     break;
1004     
1005                 default:
1006                     info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
1007                     info->bmiHeader.biCompression = BI_RGB;
1008                     break;
1009                 }
1010                 info->bmiHeader.biXPelsPerMeter = 0;
1011                 info->bmiHeader.biYPelsPerMeter = 0;
1012                 info->bmiHeader.biClrUsed = 0;
1013                 info->bmiHeader.biClrImportant = 0;
1014                 
1015                 /* Windows 2000 doesn't touch the additional struct members if
1016                    it's a BITMAPV4HEADER or a BITMAPV5HEADER */
1017             }
1018             lines = abs(bmp->bitmap.bmHeight);
1019         }
1020         else
1021         {
1022             /* The knowledge base article Q81498 ("DIBs and Their Uses") states that
1023                if bits == NULL and bpp != 0, only biSizeImage and the color table are
1024                filled in. */
1025             if (!core_header)
1026             {
1027                 /* FIXME: biSizeImage should be calculated according to the selected
1028                           compression algorithm if biCompression != BI_RGB */
1029                 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp );
1030             }
1031             lines = abs(height);
1032         }
1033     }
1034
1035     if (!core_header)
1036     {
1037         TRACE("biSizeImage = %d, ", info->bmiHeader.biSizeImage);
1038     }
1039     TRACE("biWidth = %d, biHeight = %d\n", width, height);
1040
1041     GDI_ReleaseObj( hdc );
1042     GDI_ReleaseObj( hbitmap );
1043     return lines;
1044 }
1045
1046
1047 /***********************************************************************
1048  *           CreateDIBitmap    (GDI32.@)
1049  *
1050  * Creates a DDB (device dependent bitmap) from a DIB.
1051  * The DDB will have the same color depth as the reference DC.
1052  */
1053 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
1054                             DWORD init, LPCVOID bits, const BITMAPINFO *data,
1055                             UINT coloruse )
1056 {
1057     HBITMAP handle;
1058     LONG width;
1059     LONG height;
1060     WORD planes, bpp;
1061     DWORD compr, size;
1062     DC *dc;
1063
1064     if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &size ) == -1) return 0;
1065     
1066     if (width < 0)
1067     {
1068         TRACE("Bitmap has a negative width\n");
1069         return 0;
1070     }
1071     
1072     /* Top-down DIBs have a negative height */
1073     if (height < 0) height = -height;
1074
1075     TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1076            hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
1077     
1078     if (hdc == NULL)
1079         handle = CreateBitmap( width, height, 1, 1, NULL );
1080     else
1081         handle = CreateCompatibleBitmap( hdc, width, height );
1082
1083     if (handle)
1084     {
1085         if (init == CBM_INIT) SetDIBits( hdc, handle, 0, height, bits, data, coloruse );
1086
1087         else if (hdc && ((dc = DC_GetDCPtr( hdc )) != NULL) )
1088         {
1089             if (!BITMAP_SetOwnerDC( handle, dc ))
1090             {
1091                 DeleteObject( handle );
1092                 handle = 0;
1093             }
1094             GDI_ReleaseObj( hdc );
1095         }
1096     }
1097
1098     return handle;
1099 }
1100
1101 /***********************************************************************
1102  *           CreateDIBSection    (GDI.489)
1103  */
1104 HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, const BITMAPINFO *bmi, UINT16 usage,
1105                                      SEGPTR *bits16, HANDLE section, DWORD offset)
1106 {
1107     LPVOID bits32;
1108     HBITMAP hbitmap;
1109
1110     hbitmap = CreateDIBSection( HDC_32(hdc), bmi, usage, &bits32, section, offset );
1111     if (hbitmap)
1112     {
1113         BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(hbitmap, BITMAP_MAGIC);
1114         if (bmp && bmp->dib && bits32)
1115         {
1116             const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
1117             LONG width, height;
1118             WORD planes, bpp;
1119             DWORD compr, size;
1120             INT width_bytes;
1121             WORD count, sel;
1122             int i;
1123
1124             DIB_GetBitmapInfo(bi, &width, &height, &planes, &bpp, &compr, &size);
1125
1126             height = height >= 0 ? height : -height;
1127             width_bytes = DIB_GetDIBWidthBytes(width, bpp);
1128
1129             if (!size || (compr != BI_RLE4 && compr != BI_RLE8)) size = width_bytes * height;
1130
1131             /* calculate number of sel's needed for size with 64K steps */
1132             count = (size + 0xffff) / 0x10000;
1133             sel = AllocSelectorArray16(count);
1134
1135             for (i = 0; i < count; i++)
1136             {
1137                 SetSelectorBase(sel + (i << __AHSHIFT), (DWORD)bits32 + i * 0x10000);
1138                 SetSelectorLimit16(sel + (i << __AHSHIFT), size - 1); /* yep, limit is correct */
1139                 size -= 0x10000;
1140             }
1141             bmp->segptr_bits = MAKESEGPTR( sel, 0 );
1142             if (bits16) *bits16 = bmp->segptr_bits;
1143         }
1144         if (bmp) GDI_ReleaseObj( hbitmap );
1145     }
1146     return HBITMAP_16(hbitmap);
1147 }
1148
1149 /* Copy/synthetize RGB palette from BITMAPINFO. Ripped from dlls/winex11.drv/dib.c */
1150 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1151 {
1152     RGBQUAD *colorTable;
1153     unsigned int colors;
1154     int i;
1155     BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
1156
1157     if (core_info)
1158     {
1159         colors = 1 << ((const BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
1160     }
1161     else
1162     {
1163         colors = info->bmiHeader.biClrUsed;
1164         if (!colors) colors = 1 << info->bmiHeader.biBitCount;
1165     }
1166
1167     if (colors > 256) {
1168         ERR("called with >256 colors!\n");
1169         return;
1170     }
1171
1172     if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1173
1174     if(coloruse == DIB_RGB_COLORS)
1175     {
1176         if (core_info)
1177         {
1178            /* Convert RGBTRIPLEs to RGBQUADs */
1179            for (i=0; i < colors; i++)
1180            {
1181                colorTable[i].rgbRed   = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
1182                colorTable[i].rgbGreen = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
1183                colorTable[i].rgbBlue  = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
1184                colorTable[i].rgbReserved = 0;
1185            }
1186         }
1187         else
1188         {
1189             memcpy(colorTable, (const BYTE*) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
1190         }
1191     }
1192     else
1193     {
1194         PALETTEENTRY entries[256];
1195         const WORD *index = (const WORD*) ((const BYTE*) info + (WORD) info->bmiHeader.biSize);
1196         UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1197
1198         for (i = 0; i < colors; i++, index++)
1199         {
1200             PALETTEENTRY *entry = &entries[*index % count];
1201             colorTable[i].rgbRed = entry->peRed;
1202             colorTable[i].rgbGreen = entry->peGreen;
1203             colorTable[i].rgbBlue = entry->peBlue;
1204             colorTable[i].rgbReserved = 0;
1205         }
1206     }
1207     bmp->color_table = colorTable;
1208     bmp->nb_colors = colors;
1209 }
1210
1211 /***********************************************************************
1212  *           CreateDIBSection    (GDI32.@)
1213  */
1214 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1215                                 VOID **bits, HANDLE section, DWORD offset)
1216 {
1217     HBITMAP ret = 0;
1218     DC *dc;
1219     BOOL bDesktopDC = FALSE;
1220     DIBSECTION *dib;
1221     BITMAPOBJ *bmp;
1222     int bitmap_type;
1223     LONG width, height;
1224     WORD planes, bpp;
1225     DWORD compression, sizeImage;
1226     void *mapBits = NULL;
1227
1228     if (((bitmap_type = DIB_GetBitmapInfo( &bmi->bmiHeader, &width, &height,
1229                                            &planes, &bpp, &compression, &sizeImage )) == -1))
1230         return 0;
1231
1232     if (compression != BI_RGB && compression != BI_BITFIELDS)
1233     {
1234         TRACE("can't create a compressed (%u) dibsection\n", compression);
1235         return 0;
1236     }
1237
1238     if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1239
1240     TRACE("format (%d,%d), planes %d, bpp %d, size %d, %s\n",
1241           width, height, planes, bpp, sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1242
1243     dib->dsBm.bmType       = 0;
1244     dib->dsBm.bmWidth      = width;
1245     dib->dsBm.bmHeight     = height >= 0 ? height : -height;
1246     dib->dsBm.bmWidthBytes = DIB_GetDIBWidthBytes(width, bpp);
1247     dib->dsBm.bmPlanes     = planes;
1248     dib->dsBm.bmBitsPixel  = bpp;
1249     dib->dsBm.bmBits       = NULL;
1250
1251     if (!bitmap_type)  /* core header */
1252     {
1253         /* convert the BITMAPCOREHEADER to a BITMAPINFOHEADER */
1254         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1255         dib->dsBmih.biWidth = width;
1256         dib->dsBmih.biHeight = height;
1257         dib->dsBmih.biPlanes = planes;
1258         dib->dsBmih.biBitCount = bpp;
1259         dib->dsBmih.biCompression = compression;
1260         dib->dsBmih.biXPelsPerMeter = 0;
1261         dib->dsBmih.biYPelsPerMeter = 0;
1262         dib->dsBmih.biClrUsed = 0;
1263         dib->dsBmih.biClrImportant = 0;
1264     }
1265     else
1266     {
1267         /* truncate extended bitmap headers (BITMAPV4HEADER etc.) */
1268         dib->dsBmih = bmi->bmiHeader;
1269         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1270     }
1271
1272     /* set number of entries in bmi.bmiColors table */
1273     if( bpp <= 8 )
1274         dib->dsBmih.biClrUsed = 1 << bpp;
1275
1276     dib->dsBmih.biSizeImage = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
1277
1278     /* set dsBitfields values */
1279     if (usage == DIB_PAL_COLORS || bpp <= 8)
1280     {
1281         dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1282     }
1283     else switch( bpp )
1284     {
1285     case 15:
1286     case 16:
1287         dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors       : 0x7c00;
1288         dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x03e0;
1289         dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x001f;
1290         break;
1291     case 24:
1292     case 32:
1293         dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors       : 0xff0000;
1294         dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x00ff00;
1295         dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x0000ff;
1296         break;
1297     }
1298
1299     /* get storage location for DIB bits */
1300
1301     if (section)
1302     {
1303         SYSTEM_INFO SystemInfo;
1304         DWORD mapOffset;
1305         INT mapSize;
1306
1307         GetSystemInfo( &SystemInfo );
1308         mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1309         mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1310         mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1311         if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1312     }
1313     else
1314     {
1315         offset = 0;
1316         dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1317                                          MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1318     }
1319     dib->dshSection = section;
1320     dib->dsOffset = offset;
1321
1322     if (!dib->dsBm.bmBits)
1323     {
1324         HeapFree( GetProcessHeap(), 0, dib );
1325         return 0;
1326     }
1327
1328     /* If the reference hdc is null, take the desktop dc */
1329     if (hdc == 0)
1330     {
1331         hdc = CreateCompatibleDC(0);
1332         bDesktopDC = TRUE;
1333     }
1334
1335     if (!(dc = DC_GetDCPtr( hdc ))) goto error;
1336
1337     /* create Device Dependent Bitmap and add DIB pointer */
1338     ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1339                         (bpp == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1340
1341     if (ret && ((bmp = GDI_GetObjPtr(ret, BITMAP_MAGIC))))
1342     {
1343         bmp->dib = dib;
1344         bmp->funcs = dc->funcs;
1345         /* create local copy of DIB palette */
1346         if (bpp <= 8) DIB_CopyColorTable( dc, bmp, usage, bmi );
1347         GDI_ReleaseObj( ret );
1348
1349         if (dc->funcs->pCreateDIBSection)
1350         {
1351             if (!dc->funcs->pCreateDIBSection(dc->physDev, ret, bmi, usage))
1352             {
1353                 DeleteObject( ret );
1354                 ret = 0;
1355             }
1356         }
1357     }
1358
1359     GDI_ReleaseObj(hdc);
1360     if (bDesktopDC) DeleteDC( hdc );
1361     if (ret && bits) *bits = dib->dsBm.bmBits;
1362     return ret;
1363
1364 error:
1365     if (bDesktopDC) DeleteDC( hdc );
1366     if (section) UnmapViewOfFile( mapBits );
1367     else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1368     HeapFree( GetProcessHeap(), 0, dib );
1369     return 0;
1370 }