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