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