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