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