quartz: Fix discontinuities in wave parser.
[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     if (bpp <= 8 && bpp > 0)
624     {
625         if (!core_header) info->bmiHeader.biClrUsed = 0;
626
627         /* If the bitmap object already has a dib section at the
628            same color depth then get the color map from it */
629         if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == bpp) {
630             if(coloruse == DIB_RGB_COLORS) {
631                 unsigned int colors = min( bmp->nb_colors, 1 << bpp );
632
633                 if (core_header)
634                 {
635                     /* Convert the color table (RGBQUAD to RGBTRIPLE) */
636                     RGBTRIPLE* index = rgbTriples;
637
638                     for (i=0; i < colors; i++, index++)
639                     {
640                         index->rgbtRed   = bmp->color_table[i].rgbRed;
641                         index->rgbtGreen = bmp->color_table[i].rgbGreen;
642                         index->rgbtBlue  = bmp->color_table[i].rgbBlue;
643                     }
644                 }
645                 else
646                 {
647                     if (colors != 1 << bpp) info->bmiHeader.biClrUsed = colors;
648                     memcpy(colorPtr, bmp->color_table, colors * sizeof(RGBQUAD));
649                 }
650             }
651             else {
652                 WORD *index = colorPtr;
653                 for(i = 0; i < 1 << info->bmiHeader.biBitCount; i++, index++)
654                     *index = i;
655             }
656         }
657         else {
658             if(bpp >= bmp->bitmap.bmBitsPixel) {
659                 /* Generate the color map from the selected palette */
660                 PALETTEENTRY palEntry[256];
661
662                 memset( palEntry, 0, sizeof(palEntry) );
663                 if (!GetPaletteEntries( dc->hPalette, 0, 1 << bmp->bitmap.bmBitsPixel, palEntry ))
664                 {
665                     release_dc_ptr( dc );
666                     GDI_ReleaseObj( hbitmap );
667                     return 0;
668                 }
669                 for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++) {
670                     if (coloruse == DIB_RGB_COLORS) {
671                         if (core_header)
672                         {
673                             rgbTriples[i].rgbtRed   = palEntry[i].peRed;
674                             rgbTriples[i].rgbtGreen = palEntry[i].peGreen;
675                             rgbTriples[i].rgbtBlue  = palEntry[i].peBlue;
676                         }
677                         else
678                         {
679                             rgbQuads[i].rgbRed      = palEntry[i].peRed;
680                             rgbQuads[i].rgbGreen    = palEntry[i].peGreen;
681                             rgbQuads[i].rgbBlue     = palEntry[i].peBlue;
682                             rgbQuads[i].rgbReserved = 0;
683                         }
684                     }
685                     else ((WORD *)colorPtr)[i] = (WORD)i;
686                 }
687             } else {
688                 switch (bpp) {
689                 case 1:
690                     if (core_header)
691                     {
692                         rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
693                             rgbTriples[0].rgbtBlue = 0;
694                         rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
695                             rgbTriples[1].rgbtBlue = 0xff;
696                     }
697                     else
698                     {    
699                         rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
700                             rgbQuads[0].rgbBlue = 0;
701                         rgbQuads[0].rgbReserved = 0;
702                         rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
703                             rgbQuads[1].rgbBlue = 0xff;
704                         rgbQuads[1].rgbReserved = 0;
705                     }
706                     break;
707
708                 case 4:
709                     if (core_header)
710                         memcpy(colorPtr, EGAColorsTriples, sizeof(EGAColorsTriples));
711                     else
712                         memcpy(colorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
713
714                     break;
715
716                 case 8:
717                     {
718                         if (core_header)
719                         {
720                             INT r, g, b;
721                             RGBTRIPLE *color;
722
723                             memcpy(rgbTriples, DefLogPaletteTriples,
724                                        10 * sizeof(RGBTRIPLE));
725                             memcpy(rgbTriples + 246, DefLogPaletteTriples + 10,
726                                        10 * sizeof(RGBTRIPLE));
727                             color = rgbTriples + 10;
728                             for(r = 0; r <= 5; r++) /* FIXME */
729                                 for(g = 0; g <= 5; g++)
730                                     for(b = 0; b <= 5; b++) {
731                                         color->rgbtRed =   (r * 0xff) / 5;
732                                         color->rgbtGreen = (g * 0xff) / 5;
733                                         color->rgbtBlue =  (b * 0xff) / 5;
734                                         color++;
735                                     }
736                         }
737                         else
738                         {
739                             INT r, g, b;
740                             RGBQUAD *color;
741
742                             memcpy(rgbQuads, DefLogPaletteQuads,
743                                        10 * sizeof(RGBQUAD));
744                             memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
745                                    10 * sizeof(RGBQUAD));
746                             color = rgbQuads + 10;
747                             for(r = 0; r <= 5; r++) /* FIXME */
748                                 for(g = 0; g <= 5; g++)
749                                     for(b = 0; b <= 5; b++) {
750                                         color->rgbRed =   (r * 0xff) / 5;
751                                         color->rgbGreen = (g * 0xff) / 5;
752                                         color->rgbBlue =  (b * 0xff) / 5;
753                                         color->rgbReserved = 0;
754                                         color++;
755                                     }
756                         }
757                     }
758                 }
759             }
760         }
761     }
762
763     if (bits && lines)
764     {
765         /* If the bitmap object already have a dib section that contains image data, get the bits from it */
766         if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
767         {
768             /*FIXME: Only RGB dibs supported for now */
769             unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb = bmp->dib->dsBm.bmWidthBytes;
770             unsigned int dstwidth = width;
771             int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
772             LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
773             unsigned int x, y, width, widthb;
774
775             if ((height < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
776             {
777                 dbits = (LPBYTE)bits + (dstwidthb * (lines-1));
778                 dstwidthb = -dstwidthb;
779             }
780
781             switch( bpp ) {
782
783             case 15:
784             case 16: /* 16 bpp dstDIB */
785                 {
786                     LPWORD dstbits = (LPWORD)dbits;
787                     WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
788
789                     /* FIXME: BI_BITFIELDS not supported yet */
790
791                     switch(bmp->dib->dsBm.bmBitsPixel) {
792
793                     case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
794                         {
795                             widthb = min(srcwidthb, abs(dstwidthb));
796                             /* FIXME: BI_BITFIELDS not supported yet */
797                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
798                                 memcpy(dbits, sbits, widthb);
799                         }
800                         break;
801
802                     case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
803                         {
804                             LPBYTE srcbits = sbits;
805
806                             width = min(srcwidth, dstwidth);
807                             for( y = 0; y < lines; y++) {
808                                 for( x = 0; x < width; x++, srcbits += 3)
809                                     *dstbits++ = ((srcbits[0] >> 3) & bmask) |
810                                                  (((WORD)srcbits[1] << 2) & gmask) |
811                                                  (((WORD)srcbits[2] << 7) & rmask);
812
813                                 dstbits = (LPWORD)(dbits+=dstwidthb);
814                                 srcbits = (sbits += srcwidthb);
815                             }
816                         }
817                         break;
818
819                     case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
820                         {
821                             LPDWORD srcbits = (LPDWORD)sbits;
822                             DWORD val;
823
824                             width = min(srcwidth, dstwidth);
825                             for( y = 0; y < lines; y++) {
826                                 for( x = 0; x < width; x++ ) {
827                                     val = *srcbits++;
828                                     *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
829                                                        ((val >> 9) & rmask));
830                                 }
831                                 dstbits = (LPWORD)(dbits+=dstwidthb);
832                                 srcbits = (LPDWORD)(sbits+=srcwidthb);
833                             }
834                         }
835                         break;
836
837                     default: /* ? bit bmp -> 16 bit DIB */
838                         FIXME("15/16 bit DIB %d bit bitmap\n",
839                         bmp->bitmap.bmBitsPixel);
840                         break;
841                     }
842                 }
843                 break;
844
845             case 24: /* 24 bpp dstDIB */
846                 {
847                     LPBYTE dstbits = dbits;
848
849                     switch(bmp->dib->dsBm.bmBitsPixel) {
850
851                     case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
852                         {
853                             LPWORD srcbits = (LPWORD)sbits;
854                             WORD val;
855
856                             width = min(srcwidth, dstwidth);
857                             /* FIXME: BI_BITFIELDS not supported yet */
858                             for( y = 0; y < lines; y++) {
859                                 for( x = 0; x < width; x++ ) {
860                                     val = *srcbits++;
861                                     *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
862                                     *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
863                                     *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
864                                 }
865                                 dstbits = dbits+=dstwidthb;
866                                 srcbits = (LPWORD)(sbits+=srcwidthb);
867                             }
868                         }
869                         break;
870
871                     case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
872                         {
873                             widthb = min(srcwidthb, abs(dstwidthb));
874                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
875                                 memcpy(dbits, sbits, widthb);
876                         }
877                         break;
878
879                     case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
880                         {
881                             LPBYTE srcbits = sbits;
882
883                             width = min(srcwidth, dstwidth);
884                             for( y = 0; y < lines; y++) {
885                                 for( x = 0; x < width; x++, srcbits++ ) {
886                                     *dstbits++ = *srcbits++;
887                                     *dstbits++ = *srcbits++;
888                                     *dstbits++ = *srcbits++;
889                                 }
890                                 dstbits = dbits+=dstwidthb;
891                                 srcbits = sbits+=srcwidthb;
892                             }
893                         }
894                         break;
895
896                     default: /* ? bit bmp -> 24 bit DIB */
897                         FIXME("24 bit DIB %d bit bitmap\n",
898                               bmp->bitmap.bmBitsPixel);
899                         break;
900                     }
901                 }
902                 break;
903
904             case 32: /* 32 bpp dstDIB */
905                 {
906                     LPDWORD dstbits = (LPDWORD)dbits;
907
908                     /* FIXME: BI_BITFIELDS not supported yet */
909
910                     switch(bmp->dib->dsBm.bmBitsPixel) {
911                         case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
912                         {
913                             LPWORD srcbits = (LPWORD)sbits;
914                             DWORD val;
915
916                             width = min(srcwidth, dstwidth);
917                             /* FIXME: BI_BITFIELDS not supported yet */
918                             for( y = 0; y < lines; y++) {
919                                 for( x = 0; x < width; x++ ) {
920                                     val = (DWORD)*srcbits++;
921                                     *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
922                                                  ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
923                                                  ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
924                                 }
925                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
926                                 srcbits=(LPWORD)(sbits+=srcwidthb);
927                             }
928                         }
929                         break;
930
931                     case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
932                         {
933                             LPBYTE srcbits = sbits;
934
935                             width = min(srcwidth, dstwidth);
936                             for( y = 0; y < lines; y++) {
937                                 for( x = 0; x < width; x++, srcbits+=3 )
938                                     *dstbits++ =  srcbits[0] |
939                                                  (srcbits[1] <<  8) |
940                                                  (srcbits[2] << 16);
941                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
942                                 srcbits=(sbits+=srcwidthb);
943                             }
944                         }
945                         break;
946
947                     case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
948                         {
949                             widthb = min(srcwidthb, abs(dstwidthb));
950                             /* FIXME: BI_BITFIELDS not supported yet */
951                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
952                                 memcpy(dbits, sbits, widthb);
953                             }
954                         }
955                         break;
956
957                     default: /* ? bit bmp -> 32 bit DIB */
958                         FIXME("32 bit DIB %d bit bitmap\n",
959                         bmp->bitmap.bmBitsPixel);
960                         break;
961                     }
962                 }
963                 break;
964
965             default: /* ? bit DIB */
966                 FIXME("Unsupported DIB depth %d\n", info->bmiHeader.biBitCount);
967                 break;
968             }
969         }
970         /* Otherwise, get bits from the XImage */
971         else
972         {
973             if (!bmp->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) lines = 0;
974             else
975             {
976                 if (bmp->funcs && bmp->funcs->pGetDIBits)
977                     lines = bmp->funcs->pGetDIBits( dc->physDev, hbitmap, startscan,
978                                                     lines, bits, info, coloruse );
979                 else
980                     lines = 0;  /* FIXME: should copy from bmp->bitmap.bmBits */
981             }
982         }
983     }
984     else
985     {
986         /* fill in struct members */
987
988         if (bpp == 0)
989         {
990             if (core_header)
991             {
992                 BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
993                 coreheader->bcWidth = bmp->bitmap.bmWidth;
994                 coreheader->bcHeight = bmp->bitmap.bmHeight;
995                 coreheader->bcPlanes = 1;
996                 coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
997             }
998             else
999             {
1000                 info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
1001                 info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
1002                 info->bmiHeader.biPlanes = 1;
1003                 info->bmiHeader.biSizeImage =
1004                                  DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
1005                                                        bmp->bitmap.bmHeight,
1006                                                        bmp->bitmap.bmBitsPixel );
1007                 switch(bmp->bitmap.bmBitsPixel)
1008                 {
1009                 case 15:
1010                     info->bmiHeader.biBitCount = 16;
1011                     info->bmiHeader.biCompression = BI_RGB;
1012                     break;
1013                     
1014                 case 16:
1015                     if (bits)
1016                     {
1017                         /* Add color only when bits is given, as per MSDN */
1018                         ((PDWORD)info->bmiColors)[0] = 0xf800;
1019                         ((PDWORD)info->bmiColors)[1] = 0x07e0;
1020                         ((PDWORD)info->bmiColors)[2] = 0x001f;
1021                     }
1022                     info->bmiHeader.biBitCount = 16;
1023                     info->bmiHeader.biCompression = BI_BITFIELDS;
1024                     break;
1025     
1026                 default:
1027                     info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
1028                     info->bmiHeader.biCompression = BI_RGB;
1029                     break;
1030                 }
1031                 info->bmiHeader.biXPelsPerMeter = 0;
1032                 info->bmiHeader.biYPelsPerMeter = 0;
1033                 info->bmiHeader.biClrUsed = 0;
1034                 info->bmiHeader.biClrImportant = 0;
1035                 
1036                 /* Windows 2000 doesn't touch the additional struct members if
1037                    it's a BITMAPV4HEADER or a BITMAPV5HEADER */
1038             }
1039             lines = abs(bmp->bitmap.bmHeight);
1040         }
1041         else
1042         {
1043             /* The knowledge base article Q81498 ("DIBs and Their Uses") states that
1044                if bits == NULL and bpp != 0, only biSizeImage and the color table are
1045                filled in. */
1046             if (!core_header)
1047             {
1048                 /* FIXME: biSizeImage should be calculated according to the selected
1049                           compression algorithm if biCompression != BI_RGB */
1050                 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp );
1051             }
1052             lines = abs(height);
1053         }
1054     }
1055
1056     if (!core_header)
1057     {
1058         TRACE("biSizeImage = %d, ", info->bmiHeader.biSizeImage);
1059     }
1060     TRACE("biWidth = %d, biHeight = %d\n", width, height);
1061
1062     release_dc_ptr( dc );
1063     GDI_ReleaseObj( hbitmap );
1064     return lines;
1065 }
1066
1067
1068 /***********************************************************************
1069  *           CreateDIBitmap    (GDI32.@)
1070  *
1071  * Creates a DDB (device dependent bitmap) from a DIB.
1072  * The DDB will have the same color depth as the reference DC.
1073  */
1074 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
1075                             DWORD init, LPCVOID bits, const BITMAPINFO *data,
1076                             UINT coloruse )
1077 {
1078     HBITMAP handle;
1079     LONG width;
1080     LONG height;
1081     WORD planes, bpp;
1082     DWORD compr, size;
1083     DC *dc;
1084
1085     if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &size ) == -1) return 0;
1086     
1087     if (width < 0)
1088     {
1089         TRACE("Bitmap has a negative width\n");
1090         return 0;
1091     }
1092     
1093     /* Top-down DIBs have a negative height */
1094     if (height < 0) height = -height;
1095
1096     TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1097            hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
1098     
1099     if (hdc == NULL)
1100         handle = CreateBitmap( width, height, 1, 1, NULL );
1101     else
1102         handle = CreateCompatibleBitmap( hdc, width, height );
1103
1104     if (handle)
1105     {
1106         if (init == CBM_INIT) SetDIBits( hdc, handle, 0, height, bits, data, coloruse );
1107
1108         else if (hdc && ((dc = get_dc_ptr( hdc )) != NULL) )
1109         {
1110             if (!BITMAP_SetOwnerDC( handle, dc ))
1111             {
1112                 DeleteObject( handle );
1113                 handle = 0;
1114             }
1115             release_dc_ptr( dc );
1116         }
1117     }
1118
1119     return handle;
1120 }
1121
1122 /***********************************************************************
1123  *           CreateDIBSection    (GDI.489)
1124  */
1125 HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, const BITMAPINFO *bmi, UINT16 usage,
1126                                      SEGPTR *bits16, HANDLE section, DWORD offset)
1127 {
1128     LPVOID bits32;
1129     HBITMAP hbitmap;
1130
1131     hbitmap = CreateDIBSection( HDC_32(hdc), bmi, usage, &bits32, section, offset );
1132     if (hbitmap)
1133     {
1134         BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(hbitmap, BITMAP_MAGIC);
1135         if (bmp && bmp->dib && bits32)
1136         {
1137             const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
1138             LONG width, height;
1139             WORD planes, bpp;
1140             DWORD compr, size;
1141             INT width_bytes;
1142             WORD count, sel;
1143             int i;
1144
1145             DIB_GetBitmapInfo(bi, &width, &height, &planes, &bpp, &compr, &size);
1146
1147             height = height >= 0 ? height : -height;
1148             width_bytes = DIB_GetDIBWidthBytes(width, bpp);
1149
1150             if (!size || (compr != BI_RLE4 && compr != BI_RLE8)) size = width_bytes * height;
1151
1152             /* calculate number of sel's needed for size with 64K steps */
1153             count = (size + 0xffff) / 0x10000;
1154             sel = AllocSelectorArray16(count);
1155
1156             for (i = 0; i < count; i++)
1157             {
1158                 SetSelectorBase(sel + (i << __AHSHIFT), (DWORD)bits32 + i * 0x10000);
1159                 SetSelectorLimit16(sel + (i << __AHSHIFT), size - 1); /* yep, limit is correct */
1160                 size -= 0x10000;
1161             }
1162             bmp->segptr_bits = MAKESEGPTR( sel, 0 );
1163             if (bits16) *bits16 = bmp->segptr_bits;
1164         }
1165         if (bmp) GDI_ReleaseObj( hbitmap );
1166     }
1167     return HBITMAP_16(hbitmap);
1168 }
1169
1170 /* Copy/synthesize RGB palette from BITMAPINFO. Ripped from dlls/winex11.drv/dib.c */
1171 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1172 {
1173     RGBQUAD *colorTable;
1174     unsigned int colors;
1175     int i;
1176     BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
1177
1178     if (core_info)
1179     {
1180         colors = 1 << ((const BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
1181     }
1182     else
1183     {
1184         colors = info->bmiHeader.biClrUsed;
1185         if (!colors) colors = 1 << info->bmiHeader.biBitCount;
1186     }
1187
1188     if (colors > 256) {
1189         ERR("called with >256 colors!\n");
1190         return;
1191     }
1192
1193     if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1194
1195     if(coloruse == DIB_RGB_COLORS)
1196     {
1197         if (core_info)
1198         {
1199            /* Convert RGBTRIPLEs to RGBQUADs */
1200            for (i=0; i < colors; i++)
1201            {
1202                colorTable[i].rgbRed   = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
1203                colorTable[i].rgbGreen = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
1204                colorTable[i].rgbBlue  = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
1205                colorTable[i].rgbReserved = 0;
1206            }
1207         }
1208         else
1209         {
1210             memcpy(colorTable, (const BYTE*) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
1211         }
1212     }
1213     else
1214     {
1215         PALETTEENTRY entries[256];
1216         const WORD *index = (const WORD*) ((const BYTE*) info + (WORD) info->bmiHeader.biSize);
1217         UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1218
1219         for (i = 0; i < colors; i++, index++)
1220         {
1221             PALETTEENTRY *entry = &entries[*index % count];
1222             colorTable[i].rgbRed = entry->peRed;
1223             colorTable[i].rgbGreen = entry->peGreen;
1224             colorTable[i].rgbBlue = entry->peBlue;
1225             colorTable[i].rgbReserved = 0;
1226         }
1227     }
1228     bmp->color_table = colorTable;
1229     bmp->nb_colors = colors;
1230 }
1231
1232 /***********************************************************************
1233  *           CreateDIBSection    (GDI32.@)
1234  */
1235 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1236                                 VOID **bits, HANDLE section, DWORD offset)
1237 {
1238     HBITMAP ret = 0;
1239     DC *dc;
1240     BOOL bDesktopDC = FALSE;
1241     DIBSECTION *dib;
1242     BITMAPOBJ *bmp;
1243     int bitmap_type;
1244     LONG width, height;
1245     WORD planes, bpp;
1246     DWORD compression, sizeImage;
1247     void *mapBits = NULL;
1248
1249     if (((bitmap_type = DIB_GetBitmapInfo( &bmi->bmiHeader, &width, &height,
1250                                            &planes, &bpp, &compression, &sizeImage )) == -1))
1251         return 0;
1252
1253     if (compression != BI_RGB && compression != BI_BITFIELDS)
1254     {
1255         TRACE("can't create a compressed (%u) dibsection\n", compression);
1256         return 0;
1257     }
1258
1259     if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1260
1261     TRACE("format (%d,%d), planes %d, bpp %d, size %d, %s\n",
1262           width, height, planes, bpp, sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1263
1264     dib->dsBm.bmType       = 0;
1265     dib->dsBm.bmWidth      = width;
1266     dib->dsBm.bmHeight     = height >= 0 ? height : -height;
1267     dib->dsBm.bmWidthBytes = DIB_GetDIBWidthBytes(width, bpp);
1268     dib->dsBm.bmPlanes     = planes;
1269     dib->dsBm.bmBitsPixel  = bpp;
1270     dib->dsBm.bmBits       = NULL;
1271
1272     if (!bitmap_type)  /* core header */
1273     {
1274         /* convert the BITMAPCOREHEADER to a BITMAPINFOHEADER */
1275         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1276         dib->dsBmih.biWidth = width;
1277         dib->dsBmih.biHeight = height;
1278         dib->dsBmih.biPlanes = planes;
1279         dib->dsBmih.biBitCount = bpp;
1280         dib->dsBmih.biCompression = compression;
1281         dib->dsBmih.biXPelsPerMeter = 0;
1282         dib->dsBmih.biYPelsPerMeter = 0;
1283         dib->dsBmih.biClrUsed = 0;
1284         dib->dsBmih.biClrImportant = 0;
1285     }
1286     else
1287     {
1288         /* truncate extended bitmap headers (BITMAPV4HEADER etc.) */
1289         dib->dsBmih = bmi->bmiHeader;
1290         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1291     }
1292
1293     /* set number of entries in bmi.bmiColors table */
1294     if( bpp <= 8 )
1295         dib->dsBmih.biClrUsed = 1 << bpp;
1296
1297     dib->dsBmih.biSizeImage = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
1298
1299     /* set dsBitfields values */
1300     if (usage == DIB_PAL_COLORS || bpp <= 8)
1301     {
1302         dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1303     }
1304     else switch( bpp )
1305     {
1306     case 15:
1307     case 16:
1308         dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors       : 0x7c00;
1309         dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x03e0;
1310         dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x001f;
1311         break;
1312     case 24:
1313     case 32:
1314         dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors       : 0xff0000;
1315         dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x00ff00;
1316         dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x0000ff;
1317         break;
1318     }
1319
1320     /* get storage location for DIB bits */
1321
1322     if (section)
1323     {
1324         SYSTEM_INFO SystemInfo;
1325         DWORD mapOffset;
1326         INT mapSize;
1327
1328         GetSystemInfo( &SystemInfo );
1329         mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1330         mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1331         mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1332         if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1333     }
1334     else
1335     {
1336         offset = 0;
1337         dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1338                                          MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1339     }
1340     dib->dshSection = section;
1341     dib->dsOffset = offset;
1342
1343     if (!dib->dsBm.bmBits)
1344     {
1345         HeapFree( GetProcessHeap(), 0, dib );
1346         return 0;
1347     }
1348
1349     /* If the reference hdc is null, take the desktop dc */
1350     if (hdc == 0)
1351     {
1352         hdc = CreateCompatibleDC(0);
1353         bDesktopDC = TRUE;
1354     }
1355
1356     if (!(dc = get_dc_ptr( hdc ))) goto error;
1357
1358     /* create Device Dependent Bitmap and add DIB pointer */
1359     ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1360                         (bpp == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1361
1362     if (ret && ((bmp = GDI_GetObjPtr(ret, BITMAP_MAGIC))))
1363     {
1364         bmp->dib = dib;
1365         bmp->funcs = dc->funcs;
1366         /* create local copy of DIB palette */
1367         if (bpp <= 8) DIB_CopyColorTable( dc, bmp, usage, bmi );
1368         GDI_ReleaseObj( ret );
1369
1370         if (dc->funcs->pCreateDIBSection)
1371         {
1372             if (!dc->funcs->pCreateDIBSection(dc->physDev, ret, bmi, usage))
1373             {
1374                 DeleteObject( ret );
1375                 ret = 0;
1376             }
1377         }
1378     }
1379
1380     release_dc_ptr( dc );
1381     if (bDesktopDC) DeleteDC( hdc );
1382     if (ret && bits) *bits = dib->dsBm.bmBits;
1383     return ret;
1384
1385 error:
1386     if (bDesktopDC) DeleteDC( hdc );
1387     if (section) UnmapViewOfFile( mapBits );
1388     else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1389     HeapFree( GetProcessHeap(), 0, dib );
1390     return 0;
1391 }