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