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