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