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