mshtml: Implement IHTMLDOMNode previousSibling.
[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     PHYSDEV physdev;
345     BITMAPOBJ *bitmap;
346     INT result = 0;
347
348     if (coloruse == DIB_RGB_COLORS && !dc)
349     {
350         hdc = CreateCompatibleDC(0);
351         dc = get_dc_ptr( hdc );
352         delete_hdc = TRUE;
353     }
354
355     if (!dc) return 0;
356
357     update_dc( dc );
358
359     if (!(bitmap = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
360     {
361         release_dc_ptr( dc );
362         if (delete_hdc) DeleteDC(hdc);
363         return 0;
364     }
365
366     physdev = GET_DC_PHYSDEV( dc, pSetDIBits );
367     if (BITMAP_SetOwnerDC( hbitmap, physdev ))
368         result = physdev->funcs->pSetDIBits( physdev, hbitmap, startscan, lines, bits, info, coloruse );
369
370     GDI_ReleaseObj( hbitmap );
371     release_dc_ptr( dc );
372     if (delete_hdc) DeleteDC(hdc);
373     return result;
374 }
375
376
377 /***********************************************************************
378  *           SetDIBitsToDevice   (GDI32.@)
379  */
380 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
381                            DWORD cy, INT xSrc, INT ySrc, UINT startscan,
382                            UINT lines, LPCVOID bits, const BITMAPINFO *info,
383                            UINT coloruse )
384 {
385     INT ret = 0;
386     DC *dc;
387
388     if (!bits) return 0;
389
390     if ((dc = get_dc_ptr( hdc )))
391     {
392         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDIBitsToDevice );
393         update_dc( dc );
394         ret = physdev->funcs->pSetDIBitsToDevice( physdev, xDest, yDest, cx, cy, xSrc,
395                                                   ySrc, startscan, lines, bits, info, coloruse );
396         release_dc_ptr( dc );
397     }
398     return ret;
399 }
400
401 /***********************************************************************
402  *           SetDIBColorTable    (GDI32.@)
403  */
404 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUAD *colors )
405 {
406     DC * dc;
407     UINT result = 0;
408     BITMAPOBJ * bitmap;
409
410     if (!(dc = get_dc_ptr( hdc ))) return 0;
411
412     if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
413     {
414         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDIBColorTable );
415
416         /* Check if currently selected bitmap is a DIB */
417         if (bitmap->color_table)
418         {
419             if (startpos < bitmap->nb_colors)
420             {
421                 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
422                 memcpy(bitmap->color_table + startpos, colors, entries * sizeof(RGBQUAD));
423                 result = entries;
424             }
425         }
426         GDI_ReleaseObj( dc->hBitmap );
427         physdev->funcs->pSetDIBColorTable( physdev, startpos, entries, colors );
428     }
429     release_dc_ptr( dc );
430     return result;
431 }
432
433
434 /***********************************************************************
435  *           GetDIBColorTable    (GDI32.@)
436  */
437 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
438 {
439     DC * dc;
440     BITMAPOBJ *bitmap;
441     UINT result = 0;
442
443     if (!(dc = get_dc_ptr( hdc ))) return 0;
444
445     if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
446     {
447         /* Check if currently selected bitmap is a DIB */
448         if (bitmap->color_table)
449         {
450             if (startpos < bitmap->nb_colors)
451             {
452                 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
453                 memcpy(colors, bitmap->color_table + startpos, entries * sizeof(RGBQUAD));
454                 result = entries;
455             }
456         }
457         GDI_ReleaseObj( dc->hBitmap );
458     }
459     release_dc_ptr( dc );
460     return result;
461 }
462
463 /* FIXME the following two structs should be combined with __sysPalTemplate in
464    objects/color.c - this should happen after de-X11-ing both of these
465    files.
466    NB. RGBQUAD and PALETTEENTRY have different orderings of red, green
467    and blue - sigh */
468
469 static const RGBQUAD EGAColorsQuads[16] = {
470 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
471     { 0x00, 0x00, 0x00, 0x00 },
472     { 0x00, 0x00, 0x80, 0x00 },
473     { 0x00, 0x80, 0x00, 0x00 },
474     { 0x00, 0x80, 0x80, 0x00 },
475     { 0x80, 0x00, 0x00, 0x00 },
476     { 0x80, 0x00, 0x80, 0x00 },
477     { 0x80, 0x80, 0x00, 0x00 },
478     { 0x80, 0x80, 0x80, 0x00 },
479     { 0xc0, 0xc0, 0xc0, 0x00 },
480     { 0x00, 0x00, 0xff, 0x00 },
481     { 0x00, 0xff, 0x00, 0x00 },
482     { 0x00, 0xff, 0xff, 0x00 },
483     { 0xff, 0x00, 0x00, 0x00 },
484     { 0xff, 0x00, 0xff, 0x00 },
485     { 0xff, 0xff, 0x00, 0x00 },
486     { 0xff, 0xff, 0xff, 0x00 }
487 };
488
489 static const RGBTRIPLE EGAColorsTriples[16] = {
490 /* rgbBlue, rgbGreen, rgbRed */
491     { 0x00, 0x00, 0x00 },
492     { 0x00, 0x00, 0x80 },
493     { 0x00, 0x80, 0x00 },
494     { 0x00, 0x80, 0x80 },
495     { 0x80, 0x00, 0x00 },
496     { 0x80, 0x00, 0x80 },
497     { 0x80, 0x80, 0x00 },
498     { 0x80, 0x80, 0x80 },
499     { 0xc0, 0xc0, 0xc0 },
500     { 0x00, 0x00, 0xff },
501     { 0x00, 0xff, 0x00 },
502     { 0x00, 0xff, 0xff },
503     { 0xff, 0x00, 0x00 } ,
504     { 0xff, 0x00, 0xff },
505     { 0xff, 0xff, 0x00 },
506     { 0xff, 0xff, 0xff }
507 };
508
509 static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
510 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
511     { 0x00, 0x00, 0x00, 0x00 },
512     { 0x00, 0x00, 0x80, 0x00 },
513     { 0x00, 0x80, 0x00, 0x00 },
514     { 0x00, 0x80, 0x80, 0x00 },
515     { 0x80, 0x00, 0x00, 0x00 },
516     { 0x80, 0x00, 0x80, 0x00 },
517     { 0x80, 0x80, 0x00, 0x00 },
518     { 0xc0, 0xc0, 0xc0, 0x00 },
519     { 0xc0, 0xdc, 0xc0, 0x00 },
520     { 0xf0, 0xca, 0xa6, 0x00 },
521     { 0xf0, 0xfb, 0xff, 0x00 },
522     { 0xa4, 0xa0, 0xa0, 0x00 },
523     { 0x80, 0x80, 0x80, 0x00 },
524     { 0x00, 0x00, 0xf0, 0x00 },
525     { 0x00, 0xff, 0x00, 0x00 },
526     { 0x00, 0xff, 0xff, 0x00 },
527     { 0xff, 0x00, 0x00, 0x00 },
528     { 0xff, 0x00, 0xff, 0x00 },
529     { 0xff, 0xff, 0x00, 0x00 },
530     { 0xff, 0xff, 0xff, 0x00 }
531 };
532
533 static const RGBTRIPLE DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
534 /* rgbBlue, rgbGreen, rgbRed */
535     { 0x00, 0x00, 0x00 },
536     { 0x00, 0x00, 0x80 },
537     { 0x00, 0x80, 0x00 },
538     { 0x00, 0x80, 0x80 },
539     { 0x80, 0x00, 0x00 },
540     { 0x80, 0x00, 0x80 },
541     { 0x80, 0x80, 0x00 },
542     { 0xc0, 0xc0, 0xc0 },
543     { 0xc0, 0xdc, 0xc0 },
544     { 0xf0, 0xca, 0xa6 },
545     { 0xf0, 0xfb, 0xff },
546     { 0xa4, 0xa0, 0xa0 },
547     { 0x80, 0x80, 0x80 },
548     { 0x00, 0x00, 0xf0 },
549     { 0x00, 0xff, 0x00 },
550     { 0x00, 0xff, 0xff },
551     { 0xff, 0x00, 0x00 },
552     { 0xff, 0x00, 0xff },
553     { 0xff, 0xff, 0x00 },
554     { 0xff, 0xff, 0xff}
555 };
556
557
558 /******************************************************************************
559  * GetDIBits [GDI32.@]
560  *
561  * Retrieves bits of bitmap and copies to buffer.
562  *
563  * RETURNS
564  *    Success: Number of scan lines copied from bitmap
565  *    Failure: 0
566  */
567 INT WINAPI GetDIBits(
568     HDC hdc,         /* [in]  Handle to device context */
569     HBITMAP hbitmap, /* [in]  Handle to bitmap */
570     UINT startscan,  /* [in]  First scan line to set in dest bitmap */
571     UINT lines,      /* [in]  Number of scan lines to copy */
572     LPVOID bits,       /* [out] Address of array for bitmap bits */
573     BITMAPINFO * info, /* [out] Address of structure with bitmap data */
574     UINT coloruse)   /* [in]  RGB or palette index */
575 {
576     DC * dc;
577     BITMAPOBJ * bmp;
578     int i;
579     int bitmap_type;
580     BOOL core_header;
581     LONG width;
582     LONG height;
583     WORD planes, bpp;
584     DWORD compr, size;
585     void* colorPtr;
586     RGBTRIPLE* rgbTriples;
587     RGBQUAD* rgbQuads;
588
589     if (!info) return 0;
590
591     bitmap_type = DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size);
592     if (bitmap_type == -1)
593     {
594         ERR("Invalid bitmap format\n");
595         return 0;
596     }
597     core_header = (bitmap_type == 0);
598     if (!(dc = get_dc_ptr( hdc )))
599     {
600         SetLastError( ERROR_INVALID_PARAMETER );
601         return 0;
602     }
603     update_dc( dc );
604     if (!(bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
605     {
606         release_dc_ptr( dc );
607         return 0;
608     }
609
610     colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
611     rgbTriples = colorPtr;
612     rgbQuads = colorPtr;
613
614     /* Transfer color info */
615
616     switch (bpp)
617     {
618     case 0:  /* query bitmap info only */
619         if (core_header)
620         {
621             BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
622             coreheader->bcWidth = bmp->bitmap.bmWidth;
623             coreheader->bcHeight = bmp->bitmap.bmHeight;
624             coreheader->bcPlanes = 1;
625             coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
626         }
627         else
628         {
629             info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
630             info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
631             info->bmiHeader.biPlanes = 1;
632             info->bmiHeader.biSizeImage =
633                 DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
634                                       bmp->bitmap.bmHeight,
635                                       bmp->bitmap.bmBitsPixel );
636             if (bmp->dib)
637             {
638                 info->bmiHeader.biBitCount = bmp->dib->dsBm.bmBitsPixel;
639                 switch (bmp->dib->dsBm.bmBitsPixel)
640                 {
641                 case 16:
642                 case 32:
643                     info->bmiHeader.biCompression = BI_BITFIELDS;
644                     break;
645                 default:
646                     info->bmiHeader.biCompression = BI_RGB;
647                     break;
648                 }
649             }
650             else
651             {
652                 info->bmiHeader.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB;
653                 info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
654             }
655             info->bmiHeader.biXPelsPerMeter = 0;
656             info->bmiHeader.biYPelsPerMeter = 0;
657             info->bmiHeader.biClrUsed = 0;
658             info->bmiHeader.biClrImportant = 0;
659
660             /* Windows 2000 doesn't touch the additional struct members if
661                it's a BITMAPV4HEADER or a BITMAPV5HEADER */
662         }
663         lines = abs(bmp->bitmap.bmHeight);
664         goto done;
665
666     case 1:
667     case 4:
668     case 8:
669         if (!core_header) info->bmiHeader.biClrUsed = 0;
670
671         /* If the bitmap object already has a dib section at the
672            same color depth then get the color map from it */
673         if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == bpp) {
674             if(coloruse == DIB_RGB_COLORS) {
675                 unsigned int colors = min( bmp->nb_colors, 1 << bpp );
676
677                 if (core_header)
678                 {
679                     /* Convert the color table (RGBQUAD to RGBTRIPLE) */
680                     RGBTRIPLE* index = rgbTriples;
681
682                     for (i=0; i < colors; i++, index++)
683                     {
684                         index->rgbtRed   = bmp->color_table[i].rgbRed;
685                         index->rgbtGreen = bmp->color_table[i].rgbGreen;
686                         index->rgbtBlue  = bmp->color_table[i].rgbBlue;
687                     }
688                 }
689                 else
690                 {
691                     if (colors != 1 << bpp) info->bmiHeader.biClrUsed = colors;
692                     memcpy(colorPtr, bmp->color_table, colors * sizeof(RGBQUAD));
693                 }
694             }
695             else {
696                 WORD *index = colorPtr;
697                 for(i = 0; i < 1 << info->bmiHeader.biBitCount; i++, index++)
698                     *index = i;
699             }
700         }
701         else {
702             if (coloruse == DIB_PAL_COLORS) {
703                 for (i = 0; i < (1 << bpp); i++)
704                     ((WORD *)colorPtr)[i] = (WORD)i;
705             }
706             else if(bpp > 1 && bpp == bmp->bitmap.bmBitsPixel) {
707                 /* For color DDBs in native depth (mono DDBs always have
708                    a black/white palette):
709                    Generate the color map from the selected palette */
710                 PALETTEENTRY palEntry[256];
711
712                 memset( palEntry, 0, sizeof(palEntry) );
713                 if (!GetPaletteEntries( dc->hPalette, 0, 1 << bmp->bitmap.bmBitsPixel, palEntry ))
714                 {
715                     release_dc_ptr( dc );
716                     GDI_ReleaseObj( hbitmap );
717                     return 0;
718                 }
719                 for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++) {
720                     if (core_header)
721                     {
722                         rgbTriples[i].rgbtRed   = palEntry[i].peRed;
723                         rgbTriples[i].rgbtGreen = palEntry[i].peGreen;
724                         rgbTriples[i].rgbtBlue  = palEntry[i].peBlue;
725                     }
726                     else
727                     {
728                         rgbQuads[i].rgbRed      = palEntry[i].peRed;
729                         rgbQuads[i].rgbGreen    = palEntry[i].peGreen;
730                         rgbQuads[i].rgbBlue     = palEntry[i].peBlue;
731                         rgbQuads[i].rgbReserved = 0;
732                     }
733                 }
734             } else {
735                 switch (bpp) {
736                 case 1:
737                     if (core_header)
738                     {
739                         rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
740                             rgbTriples[0].rgbtBlue = 0;
741                         rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
742                             rgbTriples[1].rgbtBlue = 0xff;
743                     }
744                     else
745                     {    
746                         rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
747                             rgbQuads[0].rgbBlue = 0;
748                         rgbQuads[0].rgbReserved = 0;
749                         rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
750                             rgbQuads[1].rgbBlue = 0xff;
751                         rgbQuads[1].rgbReserved = 0;
752                     }
753                     break;
754
755                 case 4:
756                     if (core_header)
757                         memcpy(colorPtr, EGAColorsTriples, sizeof(EGAColorsTriples));
758                     else
759                         memcpy(colorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
760
761                     break;
762
763                 case 8:
764                     {
765                         if (core_header)
766                         {
767                             INT r, g, b;
768                             RGBTRIPLE *color;
769
770                             memcpy(rgbTriples, DefLogPaletteTriples,
771                                        10 * sizeof(RGBTRIPLE));
772                             memcpy(rgbTriples + 246, DefLogPaletteTriples + 10,
773                                        10 * sizeof(RGBTRIPLE));
774                             color = rgbTriples + 10;
775                             for(r = 0; r <= 5; r++) /* FIXME */
776                                 for(g = 0; g <= 5; g++)
777                                     for(b = 0; b <= 5; b++) {
778                                         color->rgbtRed =   (r * 0xff) / 5;
779                                         color->rgbtGreen = (g * 0xff) / 5;
780                                         color->rgbtBlue =  (b * 0xff) / 5;
781                                         color++;
782                                     }
783                         }
784                         else
785                         {
786                             INT r, g, b;
787                             RGBQUAD *color;
788
789                             memcpy(rgbQuads, DefLogPaletteQuads,
790                                        10 * sizeof(RGBQUAD));
791                             memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
792                                    10 * sizeof(RGBQUAD));
793                             color = rgbQuads + 10;
794                             for(r = 0; r <= 5; r++) /* FIXME */
795                                 for(g = 0; g <= 5; g++)
796                                     for(b = 0; b <= 5; b++) {
797                                         color->rgbRed =   (r * 0xff) / 5;
798                                         color->rgbGreen = (g * 0xff) / 5;
799                                         color->rgbBlue =  (b * 0xff) / 5;
800                                         color->rgbReserved = 0;
801                                         color++;
802                                     }
803                         }
804                     }
805                 }
806             }
807         }
808         break;
809
810     case 15:
811         if (info->bmiHeader.biCompression == BI_BITFIELDS)
812         {
813             ((PDWORD)info->bmiColors)[0] = 0x7c00;
814             ((PDWORD)info->bmiColors)[1] = 0x03e0;
815             ((PDWORD)info->bmiColors)[2] = 0x001f;
816         }
817         break;
818
819     case 16:
820         if (info->bmiHeader.biCompression == BI_BITFIELDS)
821         {
822             if (bmp->dib) memcpy( info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
823             else
824             {
825                 ((PDWORD)info->bmiColors)[0] = 0xf800;
826                 ((PDWORD)info->bmiColors)[1] = 0x07e0;
827                 ((PDWORD)info->bmiColors)[2] = 0x001f;
828             }
829         }
830         break;
831
832     case 24:
833     case 32:
834         if (info->bmiHeader.biCompression == BI_BITFIELDS)
835         {
836             if (bmp->dib) memcpy( info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
837             else
838             {
839                 ((PDWORD)info->bmiColors)[0] = 0xff0000;
840                 ((PDWORD)info->bmiColors)[1] = 0x00ff00;
841                 ((PDWORD)info->bmiColors)[2] = 0x0000ff;
842             }
843         }
844         break;
845     }
846
847     if (bits && lines)
848     {
849         /* If the bitmap object already have a dib section that contains image data, get the bits from it */
850         if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
851         {
852             /*FIXME: Only RGB dibs supported for now */
853             unsigned int srcwidth = bmp->dib->dsBm.bmWidth;
854             int srcwidthb = bmp->dib->dsBm.bmWidthBytes;
855             unsigned int dstwidth = width;
856             int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
857             LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
858             unsigned int x, y, width, widthb;
859
860             /*
861              * If copying from a top-down source bitmap, move the source
862              * pointer to the end of the source bitmap and negate the width
863              * so that we copy the bits upside-down.
864              */
865             if (bmp->dib->dsBmih.biHeight < 0)
866             {
867                 sbits += (srcwidthb * (int)(abs(bmp->dib->dsBmih.biHeight) - 2 * startscan - 1));
868                 srcwidthb = -srcwidthb;
869             }
870             /*Same for the destination.*/
871             if (height < 0)
872             {
873                 dbits = (LPBYTE)bits + (dstwidthb * (lines - 1));
874                 dstwidthb = -dstwidthb;
875             }
876             switch( bpp ) {
877
878             case 15:
879             case 16: /* 16 bpp dstDIB */
880                 {
881                     LPWORD dstbits = (LPWORD)dbits;
882                     WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
883
884                     /* FIXME: BI_BITFIELDS not supported yet */
885
886                     switch(bmp->dib->dsBm.bmBitsPixel) {
887
888                     case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
889                         {
890                             widthb = min(abs(srcwidthb), abs(dstwidthb));
891                             /* FIXME: BI_BITFIELDS not supported yet */
892                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
893                                 memcpy(dbits, sbits, widthb);
894                         }
895                         break;
896
897                     case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
898                         {
899                             LPBYTE srcbits = sbits;
900
901                             width = min(srcwidth, dstwidth);
902                             for( y = 0; y < lines; y++) {
903                                 for( x = 0; x < width; x++, srcbits += 3)
904                                     *dstbits++ = ((srcbits[0] >> 3) & bmask) |
905                                                  (((WORD)srcbits[1] << 2) & gmask) |
906                                                  (((WORD)srcbits[2] << 7) & rmask);
907
908                                 dstbits = (LPWORD)(dbits+=dstwidthb);
909                                 srcbits = (sbits += srcwidthb);
910                             }
911                         }
912                         break;
913
914                     case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
915                         {
916                             LPDWORD srcbits = (LPDWORD)sbits;
917                             DWORD val;
918
919                             width = min(srcwidth, dstwidth);
920                             for( y = 0; y < lines; y++) {
921                                 for( x = 0; x < width; x++ ) {
922                                     val = *srcbits++;
923                                     *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
924                                                        ((val >> 9) & rmask));
925                                 }
926                                 dstbits = (LPWORD)(dbits+=dstwidthb);
927                                 srcbits = (LPDWORD)(sbits+=srcwidthb);
928                             }
929                         }
930                         break;
931
932                     default: /* ? bit bmp -> 16 bit DIB */
933                         FIXME("15/16 bit DIB %d bit bitmap\n",
934                         bmp->bitmap.bmBitsPixel);
935                         break;
936                     }
937                 }
938                 break;
939
940             case 24: /* 24 bpp dstDIB */
941                 {
942                     LPBYTE dstbits = dbits;
943
944                     switch(bmp->dib->dsBm.bmBitsPixel) {
945
946                     case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
947                         {
948                             LPWORD srcbits = (LPWORD)sbits;
949                             WORD val;
950
951                             width = min(srcwidth, dstwidth);
952                             /* FIXME: BI_BITFIELDS not supported yet */
953                             for( y = 0; y < lines; y++) {
954                                 for( x = 0; x < width; x++ ) {
955                                     val = *srcbits++;
956                                     *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
957                                     *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
958                                     *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
959                                 }
960                                 dstbits = dbits+=dstwidthb;
961                                 srcbits = (LPWORD)(sbits+=srcwidthb);
962                             }
963                         }
964                         break;
965
966                     case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
967                         {
968                             widthb = min(abs(srcwidthb), abs(dstwidthb));
969                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
970                                 memcpy(dbits, sbits, widthb);
971                         }
972                         break;
973
974                     case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
975                         {
976                             LPBYTE srcbits = sbits;
977
978                             width = min(srcwidth, dstwidth);
979                             for( y = 0; y < lines; y++) {
980                                 for( x = 0; x < width; x++, srcbits++ ) {
981                                     *dstbits++ = *srcbits++;
982                                     *dstbits++ = *srcbits++;
983                                     *dstbits++ = *srcbits++;
984                                 }
985                                 dstbits = dbits+=dstwidthb;
986                                 srcbits = sbits+=srcwidthb;
987                             }
988                         }
989                         break;
990
991                     default: /* ? bit bmp -> 24 bit DIB */
992                         FIXME("24 bit DIB %d bit bitmap\n",
993                               bmp->bitmap.bmBitsPixel);
994                         break;
995                     }
996                 }
997                 break;
998
999             case 32: /* 32 bpp dstDIB */
1000                 {
1001                     LPDWORD dstbits = (LPDWORD)dbits;
1002
1003                     /* FIXME: BI_BITFIELDS not supported yet */
1004
1005                     switch(bmp->dib->dsBm.bmBitsPixel) {
1006                         case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
1007                         {
1008                             LPWORD srcbits = (LPWORD)sbits;
1009                             DWORD val;
1010
1011                             width = min(srcwidth, dstwidth);
1012                             /* FIXME: BI_BITFIELDS not supported yet */
1013                             for( y = 0; y < lines; y++) {
1014                                 for( x = 0; x < width; x++ ) {
1015                                     val = (DWORD)*srcbits++;
1016                                     *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
1017                                                  ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
1018                                                  ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
1019                                 }
1020                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
1021                                 srcbits=(LPWORD)(sbits+=srcwidthb);
1022                             }
1023                         }
1024                         break;
1025
1026                     case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
1027                         {
1028                             LPBYTE srcbits = sbits;
1029
1030                             width = min(srcwidth, dstwidth);
1031                             for( y = 0; y < lines; y++) {
1032                                 for( x = 0; x < width; x++, srcbits+=3 )
1033                                     *dstbits++ =  srcbits[0] |
1034                                                  (srcbits[1] <<  8) |
1035                                                  (srcbits[2] << 16);
1036                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
1037                                 srcbits=(sbits+=srcwidthb);
1038                             }
1039                         }
1040                         break;
1041
1042                     case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
1043                         {
1044                             widthb = min(abs(srcwidthb), abs(dstwidthb));
1045                             /* FIXME: BI_BITFIELDS not supported yet */
1046                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
1047                                 memcpy(dbits, sbits, widthb);
1048                             }
1049                         }
1050                         break;
1051
1052                     default: /* ? bit bmp -> 32 bit DIB */
1053                         FIXME("32 bit DIB %d bit bitmap\n",
1054                         bmp->bitmap.bmBitsPixel);
1055                         break;
1056                     }
1057                 }
1058                 break;
1059
1060             default: /* ? bit DIB */
1061                 FIXME("Unsupported DIB depth %d\n", info->bmiHeader.biBitCount);
1062                 break;
1063             }
1064         }
1065         /* Otherwise, get bits from the XImage */
1066         else
1067         {
1068             PHYSDEV physdev = GET_DC_PHYSDEV( dc, pGetDIBits );
1069             if (!BITMAP_SetOwnerDC( hbitmap, physdev )) lines = 0;
1070             else lines = physdev->funcs->pGetDIBits( physdev, hbitmap, startscan,
1071                                                      lines, bits, info, coloruse );
1072         }
1073     }
1074     else lines = abs(height);
1075
1076     /* The knowledge base article Q81498 ("DIBs and Their Uses") states that
1077        if bits == NULL and bpp != 0, only biSizeImage and the color table are
1078        filled in. */
1079     if (!core_header)
1080     {
1081         /* FIXME: biSizeImage should be calculated according to the selected
1082            compression algorithm if biCompression != BI_RGB */
1083         info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp );
1084         TRACE("biSizeImage = %d, ", info->bmiHeader.biSizeImage);
1085     }
1086     TRACE("biWidth = %d, biHeight = %d\n", width, height);
1087
1088 done:
1089     release_dc_ptr( dc );
1090     GDI_ReleaseObj( hbitmap );
1091     return lines;
1092 }
1093
1094
1095 /***********************************************************************
1096  *           CreateDIBitmap    (GDI32.@)
1097  *
1098  * Creates a DDB (device dependent bitmap) from a DIB.
1099  * The DDB will have the same color depth as the reference DC.
1100  */
1101 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
1102                             DWORD init, LPCVOID bits, const BITMAPINFO *data,
1103                             UINT coloruse )
1104 {
1105     HBITMAP handle;
1106     LONG width;
1107     LONG height;
1108     WORD planes, bpp;
1109     DWORD compr, size;
1110
1111     if (!header) return 0;
1112
1113     if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &size ) == -1) return 0;
1114     
1115     if (width < 0)
1116     {
1117         TRACE("Bitmap has a negative width\n");
1118         return 0;
1119     }
1120     
1121     /* Top-down DIBs have a negative height */
1122     if (height < 0) height = -height;
1123
1124     TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1125            hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
1126     
1127     if (hdc == NULL)
1128         handle = CreateBitmap( width, height, 1, 1, NULL );
1129     else
1130         handle = CreateCompatibleBitmap( hdc, width, height );
1131
1132     if (handle)
1133     {
1134         if (init & CBM_INIT)
1135         {
1136             if (SetDIBits( hdc, handle, 0, height, bits, data, coloruse ) == 0)
1137             {
1138                 DeleteObject( handle );
1139                 handle = 0;
1140             }
1141         }
1142     }
1143
1144     return handle;
1145 }
1146
1147 /* Copy/synthesize RGB palette from BITMAPINFO. Ripped from dlls/winex11.drv/dib.c */
1148 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1149 {
1150     RGBQUAD *colorTable;
1151     unsigned int colors, i;
1152     BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
1153
1154     if (core_info)
1155     {
1156         colors = 1 << ((const BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
1157     }
1158     else
1159     {
1160         colors = info->bmiHeader.biClrUsed;
1161         if (!colors) colors = 1 << info->bmiHeader.biBitCount;
1162     }
1163
1164     if (colors > 256) {
1165         ERR("called with >256 colors!\n");
1166         return;
1167     }
1168
1169     if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1170
1171     if(coloruse == DIB_RGB_COLORS)
1172     {
1173         if (core_info)
1174         {
1175            /* Convert RGBTRIPLEs to RGBQUADs */
1176            for (i=0; i < colors; i++)
1177            {
1178                colorTable[i].rgbRed   = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
1179                colorTable[i].rgbGreen = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
1180                colorTable[i].rgbBlue  = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
1181                colorTable[i].rgbReserved = 0;
1182            }
1183         }
1184         else
1185         {
1186             memcpy(colorTable, (const BYTE*) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
1187         }
1188     }
1189     else
1190     {
1191         PALETTEENTRY entries[256];
1192         const WORD *index = (const WORD*) ((const BYTE*) info + (WORD) info->bmiHeader.biSize);
1193         UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1194
1195         for (i = 0; i < colors; i++, index++)
1196         {
1197             PALETTEENTRY *entry = &entries[*index % count];
1198             colorTable[i].rgbRed = entry->peRed;
1199             colorTable[i].rgbGreen = entry->peGreen;
1200             colorTable[i].rgbBlue = entry->peBlue;
1201             colorTable[i].rgbReserved = 0;
1202         }
1203     }
1204     bmp->color_table = colorTable;
1205     bmp->nb_colors = colors;
1206 }
1207
1208 /***********************************************************************
1209  *           CreateDIBSection    (GDI32.@)
1210  */
1211 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1212                                 VOID **bits, HANDLE section, DWORD offset)
1213 {
1214     HBITMAP ret = 0;
1215     DC *dc;
1216     BOOL bDesktopDC = FALSE;
1217     DIBSECTION *dib;
1218     BITMAPOBJ *bmp;
1219     int bitmap_type;
1220     LONG width, height;
1221     WORD planes, bpp;
1222     DWORD compression, sizeImage;
1223     void *mapBits = NULL;
1224
1225     if(!bmi){
1226         if(bits) *bits = NULL;
1227         return NULL;
1228     }
1229
1230     if (((bitmap_type = DIB_GetBitmapInfo( &bmi->bmiHeader, &width, &height,
1231                                            &planes, &bpp, &compression, &sizeImage )) == -1))
1232         return 0;
1233
1234     switch (bpp)
1235     {
1236     case 16:
1237     case 32:
1238         if (compression == BI_BITFIELDS) break;
1239         /* fall through */
1240     case 1:
1241     case 4:
1242     case 8:
1243     case 24:
1244         if (compression == BI_RGB) break;
1245         /* fall through */
1246     default:
1247         WARN( "invalid %u bpp compression %u\n", bpp, compression );
1248         return 0;
1249     }
1250
1251     if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1252
1253     TRACE("format (%d,%d), planes %d, bpp %d, size %d, %s\n",
1254           width, height, planes, bpp, sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1255
1256     dib->dsBm.bmType       = 0;
1257     dib->dsBm.bmWidth      = width;
1258     dib->dsBm.bmHeight     = height >= 0 ? height : -height;
1259     dib->dsBm.bmWidthBytes = DIB_GetDIBWidthBytes(width, bpp);
1260     dib->dsBm.bmPlanes     = planes;
1261     dib->dsBm.bmBitsPixel  = bpp;
1262     dib->dsBm.bmBits       = NULL;
1263
1264     if (!bitmap_type)  /* core header */
1265     {
1266         /* convert the BITMAPCOREHEADER to a BITMAPINFOHEADER */
1267         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1268         dib->dsBmih.biWidth = width;
1269         dib->dsBmih.biHeight = height;
1270         dib->dsBmih.biPlanes = planes;
1271         dib->dsBmih.biBitCount = bpp;
1272         dib->dsBmih.biCompression = compression;
1273         dib->dsBmih.biXPelsPerMeter = 0;
1274         dib->dsBmih.biYPelsPerMeter = 0;
1275         dib->dsBmih.biClrUsed = 0;
1276         dib->dsBmih.biClrImportant = 0;
1277     }
1278     else
1279     {
1280         /* truncate extended bitmap headers (BITMAPV4HEADER etc.) */
1281         dib->dsBmih = bmi->bmiHeader;
1282         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1283     }
1284
1285     /* set number of entries in bmi.bmiColors table */
1286     if( bpp <= 8 )
1287         dib->dsBmih.biClrUsed = 1 << bpp;
1288
1289     dib->dsBmih.biSizeImage = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
1290
1291     /* set dsBitfields values */
1292     if (usage == DIB_PAL_COLORS || bpp <= 8)
1293     {
1294         dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1295     }
1296     else switch( bpp )
1297     {
1298     case 15:
1299     case 16:
1300         dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors       : 0x7c00;
1301         dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x03e0;
1302         dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x001f;
1303         break;
1304     case 24:
1305     case 32:
1306         dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors       : 0xff0000;
1307         dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x00ff00;
1308         dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x0000ff;
1309         break;
1310     }
1311
1312     /* get storage location for DIB bits */
1313
1314     if (section)
1315     {
1316         SYSTEM_INFO SystemInfo;
1317         DWORD mapOffset;
1318         INT mapSize;
1319
1320         GetSystemInfo( &SystemInfo );
1321         mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1322         mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1323         mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1324         if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1325     }
1326     else
1327     {
1328         offset = 0;
1329         dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1330                                          MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1331     }
1332     dib->dshSection = section;
1333     dib->dsOffset = offset;
1334
1335     if (!dib->dsBm.bmBits)
1336     {
1337         HeapFree( GetProcessHeap(), 0, dib );
1338         return 0;
1339     }
1340
1341     /* If the reference hdc is null, take the desktop dc */
1342     if (hdc == 0)
1343     {
1344         hdc = CreateCompatibleDC(0);
1345         bDesktopDC = TRUE;
1346     }
1347
1348     if (!(dc = get_dc_ptr( hdc ))) goto error;
1349
1350     /* create Device Dependent Bitmap and add DIB pointer */
1351     ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1352                         (bpp == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1353
1354     if (ret && ((bmp = GDI_GetObjPtr(ret, OBJ_BITMAP))))
1355     {
1356         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pCreateDIBSection );
1357         bmp->dib = dib;
1358         bmp->funcs = physdev->funcs;
1359         /* create local copy of DIB palette */
1360         if (bpp <= 8) DIB_CopyColorTable( dc, bmp, usage, bmi );
1361         GDI_ReleaseObj( ret );
1362
1363         if (!physdev->funcs->pCreateDIBSection( physdev, ret, bmi, usage ))
1364         {
1365             DeleteObject( ret );
1366             ret = 0;
1367         }
1368     }
1369
1370     release_dc_ptr( dc );
1371     if (bDesktopDC) DeleteDC( hdc );
1372     if (ret && bits) *bits = dib->dsBm.bmBits;
1373     return ret;
1374
1375 error:
1376     if (bDesktopDC) DeleteDC( hdc );
1377     if (section) UnmapViewOfFile( mapBits );
1378     else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1379     HeapFree( GetProcessHeap(), 0, dib );
1380     return 0;
1381 }