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