gdi32: Remove an unneeded level of indentation.
[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
33     
34   * The palettes are stored in different formats:
35
36     - BITMAPCOREINFO: Array of RGBTRIPLE
37     - BITMAPINFO:     Array of RGBQUAD
38
39     
40   * There are even more DIB headers, but they all extend BITMAPINFOHEADER:
41     
42     - BITMAPV4HEADER: Introduced in Windows 95 / NT 4.0
43     - BITMAPV5HEADER: Introduced in Windows 98 / 2000
44     
45     If biCompression is BI_BITFIELDS, the color masks are at the same position
46     in all the headers (they start at bmiColors of BITMAPINFOHEADER), because
47     the new headers have structure members for the masks.
48
49
50   * You should never access the color table using the bmiColors member,
51     because the passed structure may have one of the extended headers
52     mentioned above. Use this to calculate the location:
53     
54     BITMAPINFO* info;
55     void* colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
56
57     
58   * More information:
59     Search for "Bitmap Structures" in MSDN
60 */
61
62 #include <stdarg.h>
63 #include <stdlib.h>
64 #include <string.h>
65 #include <assert.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  *           bitmap_info_size
77  *
78  * Return the size of the bitmap info structure including color table.
79  */
80 int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
81 {
82     unsigned int colors, size, masks = 0;
83
84     if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
85     {
86         const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
87         colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
88         return sizeof(BITMAPCOREHEADER) + colors *
89              ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
90     }
91     else  /* assume BITMAPINFOHEADER */
92     {
93         colors = get_dib_num_of_colors( info );
94         if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
95         size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
96         return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
97     }
98 }
99
100 /*******************************************************************************************
101  * Verify that the DIB parameters are valid.
102  */
103 static BOOL is_valid_dib_format( const BITMAPINFOHEADER *info, BOOL allow_compression )
104 {
105     if (info->biWidth <= 0) return FALSE;
106     if (info->biHeight == 0) return FALSE;
107
108     if (allow_compression && (info->biCompression == BI_RLE4 || info->biCompression == BI_RLE8))
109     {
110         if (info->biHeight < 0) return FALSE;
111         if (!info->biSizeImage) return FALSE;
112         return info->biBitCount == (info->biCompression == BI_RLE4 ? 4 : 8);
113     }
114
115     if (!info->biPlanes) return FALSE;
116
117     switch (info->biBitCount)
118     {
119     case 1:
120     case 4:
121     case 8:
122     case 24:
123         return (info->biCompression == BI_RGB);
124     case 16:
125     case 32:
126         return (info->biCompression == BI_BITFIELDS || info->biCompression == BI_RGB);
127     default:
128         return FALSE;
129     }
130 }
131
132 /*******************************************************************************************
133  *  Fill out a true BITMAPINFOHEADER from a variable sized BITMAPINFOHEADER / BITMAPCOREHEADER.
134  */
135 static BOOL bitmapinfoheader_from_user_bitmapinfo( BITMAPINFOHEADER *dst, const BITMAPINFOHEADER *info )
136 {
137     if (!info) return FALSE;
138
139     if (info->biSize == sizeof(BITMAPCOREHEADER))
140     {
141         const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
142         dst->biWidth         = core->bcWidth;
143         dst->biHeight        = core->bcHeight;
144         dst->biPlanes        = core->bcPlanes;
145         dst->biBitCount      = core->bcBitCount;
146         dst->biCompression   = BI_RGB;
147         dst->biXPelsPerMeter = 0;
148         dst->biYPelsPerMeter = 0;
149         dst->biClrUsed       = 0;
150         dst->biClrImportant  = 0;
151     }
152     else if (info->biSize >= sizeof(BITMAPINFOHEADER)) /* assume BITMAPINFOHEADER */
153     {
154         *dst = *info;
155     }
156     else
157     {
158         WARN( "(%u): unknown/wrong size for header\n", info->biSize );
159         return FALSE;
160     }
161
162     dst->biSize = sizeof(*dst);
163     if (dst->biCompression == BI_RGB || dst->biCompression == BI_BITFIELDS)
164         dst->biSizeImage = get_dib_image_size( (BITMAPINFO *)dst );
165     return TRUE;
166 }
167
168 /*******************************************************************************************
169  *  Fill out a true BITMAPINFO from a variable sized BITMAPINFO / BITMAPCOREINFO.
170  */
171 static BOOL bitmapinfo_from_user_bitmapinfo( BITMAPINFO *dst, const BITMAPINFO *info,
172                                              UINT coloruse, BOOL allow_compression )
173 {
174     void *src_colors;
175     unsigned int colors;
176
177     if (!bitmapinfoheader_from_user_bitmapinfo( &dst->bmiHeader, &info->bmiHeader )) return FALSE;
178     if (!is_valid_dib_format( &dst->bmiHeader, allow_compression )) return FALSE;
179
180     src_colors = (char *)info + info->bmiHeader.biSize;
181     colors = get_dib_num_of_colors( dst );
182
183     if (info->bmiHeader.biCompression == BI_BITFIELDS)
184     {
185         /* bitfields are always at bmiColors even in larger structures */
186         memcpy( dst->bmiColors, info->bmiColors, 3 * sizeof(DWORD) );
187     }
188     else if (colors)
189     {
190         if (coloruse == DIB_PAL_COLORS)
191             memcpy( dst->bmiColors, src_colors, colors * sizeof(WORD) );
192         else if (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER))
193             memcpy( dst->bmiColors, src_colors, colors * sizeof(RGBQUAD) );
194         else
195         {
196             unsigned int i;
197             RGBTRIPLE *triple = (RGBTRIPLE *)src_colors;
198             for (i = 0; i < colors; i++)
199             {
200                 dst->bmiColors[i].rgbRed      = triple[i].rgbtRed;
201                 dst->bmiColors[i].rgbGreen    = triple[i].rgbtGreen;
202                 dst->bmiColors[i].rgbBlue     = triple[i].rgbtBlue;
203                 dst->bmiColors[i].rgbReserved = 0;
204             }
205         }
206     }
207     return TRUE;
208 }
209
210 static int fill_color_table_from_palette( BITMAPINFO *info, DC *dc )
211 {
212     PALETTEENTRY palEntry[256];
213     int i, colors = get_dib_num_of_colors( info );
214
215     if (!colors) return 0;
216
217     memset( palEntry, 0, sizeof(palEntry) );
218     if (!GetPaletteEntries( dc->hPalette, 0, colors, palEntry ))
219         return 0;
220
221     for (i = 0; i < colors; i++)
222     {
223         info->bmiColors[i].rgbRed      = palEntry[i].peRed;
224         info->bmiColors[i].rgbGreen    = palEntry[i].peGreen;
225         info->bmiColors[i].rgbBlue     = palEntry[i].peBlue;
226         info->bmiColors[i].rgbReserved = 0;
227     }
228
229     return colors;
230 }
231
232 static void *get_pixel_ptr( const BITMAPINFO *info, void *bits, int x, int y )
233 {
234     const int width = info->bmiHeader.biWidth, height = info->bmiHeader.biHeight;
235     const int bpp = info->bmiHeader.biBitCount;
236
237     if (height > 0)
238         return (char *)bits + (height - y - 1) * get_dib_stride( width, bpp ) + x * bpp / 8;
239     else
240         return (char *)bits + y * get_dib_stride( width, bpp ) + x * bpp / 8;
241 }
242
243 static BOOL build_rle_bitmap( const BITMAPINFO *info, struct gdi_image_bits *bits, HRGN *clip )
244 {
245     int i = 0;
246     int left, right;
247     int x, y, width = info->bmiHeader.biWidth, height = info->bmiHeader.biHeight;
248     HRGN run = NULL;
249     BYTE skip, num, data;
250     BYTE *out_bits, *in_bits = bits->ptr;
251
252     *clip = NULL;
253
254     assert( info->bmiHeader.biBitCount == 4 || info->bmiHeader.biBitCount == 8 );
255
256     out_bits = HeapAlloc( GetProcessHeap(), 0, get_dib_image_size( info ) );
257     *clip = CreateRectRgn( 0, 0, 0, 0 );
258     run   = CreateRectRgn( 0, 0, 0, 0 );
259     if (!out_bits || !*clip || !run) goto fail;
260
261     x = left = right = 0;
262     y = height - 1;
263
264     while (i < info->bmiHeader.biSizeImage - 1)
265     {
266         num = in_bits[i];
267         data = in_bits[i + 1];
268         i += 2;
269
270         if (num)
271         {
272             if (x + num > width) num = width - x;
273             if (num)
274             {
275                 BYTE s = data, *out_ptr = get_pixel_ptr( info, out_bits, x, y );
276                 if (info->bmiHeader.biBitCount == 8)
277                     memset( out_ptr, s, num );
278                 else
279                 {
280                     if(x & 1)
281                     {
282                         s = ((s >> 4) & 0x0f) | ((s << 4) & 0xf0);
283                         *out_ptr = (*out_ptr & 0xf0) | (s & 0x0f);
284                         out_ptr++;
285                         x++;
286                         num--;
287                     }
288                     /* this will write one too many if num is odd, but that doesn't matter */
289                     if (num) memset( out_ptr, s, (num + 1) / 2 );
290                 }
291             }
292             x += num;
293             right = x;
294         }
295         else
296         {
297             if (data < 3)
298             {
299                 if(left != right)
300                 {
301                     SetRectRgn( run, left, y, right, y + 1 );
302                     CombineRgn( *clip, run, *clip, RGN_OR );
303                 }
304                 switch (data)
305                 {
306                 case 0: /* eol */
307                     left = right = x = 0;
308                     y--;
309                     if(y < 0) goto done;
310                     break;
311
312                 case 1: /* eod */
313                     goto done;
314
315                 case 2: /* delta */
316                     if (i >= info->bmiHeader.biSizeImage - 1) goto done;
317                     x += in_bits[i];
318                     if (x > width) x = width;
319                     left = right = x;
320                     y -= in_bits[i + 1];
321                     if(y < 0) goto done;
322                     i += 2;
323                 }
324             }
325             else /* data bytes of data */
326             {
327                 num = data;
328                 skip = (num * info->bmiHeader.biBitCount + 7) / 8;
329                 if (skip > info->bmiHeader.biSizeImage - i) goto done;
330                 skip = (skip + 1) & ~1;
331                 if (x + num > width) num = width - x;
332                 if (num)
333                 {
334                     BYTE *out_ptr = get_pixel_ptr( info, out_bits, x, y );
335                     if (info->bmiHeader.biBitCount == 8)
336                         memcpy( out_ptr, in_bits + i, num );
337                     else
338                     {
339                         if(x & 1)
340                         {
341                             const BYTE *in_ptr = in_bits + i;
342                             for ( ; num; num--, x++)
343                             {
344                                 if (x & 1)
345                                 {
346                                     *out_ptr = (*out_ptr & 0xf0) | ((*in_ptr >> 4) & 0x0f);
347                                     out_ptr++;
348                                 }
349                                 else
350                                     *out_ptr = (*in_ptr++ << 4) & 0xf0;
351                             }
352                         }
353                         else
354                             memcpy( out_ptr, in_bits + i, (num + 1) / 2);
355                     }
356                 }
357                 x += num;
358                 right = x;
359                 i += skip;
360             }
361         }
362     }
363
364 done:
365     DeleteObject( run );
366     if (bits->free) bits->free( bits );
367
368     bits->ptr     = out_bits;
369     bits->is_copy = TRUE;
370     bits->free    = free_heap_bits;
371
372     return TRUE;
373
374 fail:
375     if (run) DeleteObject( run );
376     if (*clip) DeleteObject( *clip );
377     HeapFree( GetProcessHeap(), 0, out_bits );
378     return FALSE;
379 }
380
381
382
383 /* nulldrv fallback implementation using SetDIBits/StretchBlt */
384 INT nulldrv_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT heightDst,
385                            INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits,
386                            const BITMAPINFO *info, UINT coloruse, DWORD rop )
387 {
388     DC *dc = get_nulldrv_dc( dev );
389     INT ret;
390     LONG height;
391     HBITMAP hBitmap;
392     HDC hdcMem;
393
394     /* make sure we have a real implementation for StretchBlt and PutImage */
395     if (GET_DC_PHYSDEV( dc, pStretchBlt ) == dev || GET_DC_PHYSDEV( dc, pPutImage ) == dev)
396         return 0;
397
398     height = info->bmiHeader.biHeight;
399
400     if (xSrc == 0 && ySrc == 0 && widthDst == widthSrc && heightDst == heightSrc &&
401         info->bmiHeader.biCompression == BI_RGB)
402     {
403         /* Windows appears to have a fast case optimization
404          * that uses the wrong origin for top-down DIBs */
405         if (height < 0 && heightSrc < abs(height)) ySrc = abs(height) - heightSrc;
406
407         if (xDst == 0 && yDst == 0 && info->bmiHeader.biCompression == BI_RGB && rop == SRCCOPY)
408         {
409             BITMAP bm;
410             hBitmap = GetCurrentObject( dev->hdc, OBJ_BITMAP );
411             if (GetObjectW( hBitmap, sizeof(bm), &bm ) &&
412                 bm.bmWidth == widthSrc && bm.bmHeight == heightSrc &&
413                 bm.bmBitsPixel == info->bmiHeader.biBitCount && bm.bmPlanes == 1)
414             {
415                 /* fast path */
416                 return SetDIBits( dev->hdc, hBitmap, 0, abs( height ), bits, info, coloruse );
417             }
418         }
419     }
420
421     hdcMem = CreateCompatibleDC( dev->hdc );
422     hBitmap = CreateCompatibleBitmap( dev->hdc, info->bmiHeader.biWidth, height );
423     SelectObject( hdcMem, hBitmap );
424     if (coloruse == DIB_PAL_COLORS)
425         SelectPalette( hdcMem, GetCurrentObject( dev->hdc, OBJ_PAL ), FALSE );
426
427     if (info->bmiHeader.biCompression == BI_RLE4 || info->bmiHeader.biCompression == BI_RLE8)
428     {
429         /* when RLE compression is used, there may be some gaps (ie the DIB doesn't
430          * contain all the rectangle described in bmiHeader, but only part of it.
431          * This mean that those undescribed pixels must be left untouched.
432          * So, we first copy on a memory bitmap the current content of the
433          * destination rectangle, blit the DIB bits on top of it - hence leaving
434          * the gaps untouched -, and blitting the rectangle back.
435          * This insure that gaps are untouched on the destination rectangle
436          */
437         StretchBlt( hdcMem, xSrc, abs(height) - heightSrc - ySrc, widthSrc, heightSrc,
438                     dev->hdc, xDst, yDst, widthDst, heightDst, rop );
439     }
440     ret = SetDIBits( hdcMem, hBitmap, 0, abs( height ), bits, info, coloruse );
441     if (ret) StretchBlt( dev->hdc, xDst, yDst, widthDst, heightDst,
442                          hdcMem, xSrc, abs(height) - heightSrc - ySrc, widthSrc, heightSrc, rop );
443     DeleteDC( hdcMem );
444     DeleteObject( hBitmap );
445     return ret;
446 }
447
448 /***********************************************************************
449  *           StretchDIBits   (GDI32.@)
450  */
451 INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst, INT heightDst,
452                          INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits,
453                          const BITMAPINFO *bmi, UINT coloruse, DWORD rop )
454 {
455     char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
456     BITMAPINFO *info = (BITMAPINFO *)buffer;
457     DC *dc;
458     INT ret = 0;
459
460     if (!bits) return 0;
461     if (!bitmapinfo_from_user_bitmapinfo( info, bmi, coloruse, TRUE ))
462     {
463         SetLastError( ERROR_INVALID_PARAMETER );
464         return 0;
465     }
466
467     if ((dc = get_dc_ptr( hdc )))
468     {
469         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pStretchDIBits );
470         update_dc( dc );
471         ret = physdev->funcs->pStretchDIBits( physdev, xDst, yDst, widthDst, heightDst,
472                                               xSrc, ySrc, widthSrc, heightSrc, bits, info, coloruse, rop );
473         release_dc_ptr( dc );
474     }
475     return ret;
476 }
477
478
479 /******************************************************************************
480  * SetDIBits [GDI32.@]
481  *
482  * Sets pixels in a bitmap using colors from DIB.
483  *
484  * PARAMS
485  *    hdc       [I] Handle to device context
486  *    hbitmap   [I] Handle to bitmap
487  *    startscan [I] Starting scan line
488  *    lines     [I] Number of scan lines
489  *    bits      [I] Array of bitmap bits
490  *    info      [I] Address of structure with data
491  *    coloruse  [I] Type of color indexes to use
492  *
493  * RETURNS
494  *    Success: Number of scan lines copied
495  *    Failure: 0
496  */
497 INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
498                       UINT lines, LPCVOID bits, const BITMAPINFO *info,
499                       UINT coloruse )
500 {
501     DC *dc = get_dc_ptr( hdc );
502     BOOL delete_hdc = FALSE;
503     PHYSDEV physdev;
504     BITMAPOBJ *bitmap;
505     char src_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
506     BITMAPINFO *src_info = (BITMAPINFO *)src_bmibuf;
507     char dst_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
508     BITMAPINFO *dst_info = (BITMAPINFO *)dst_bmibuf;
509     INT result = 0;
510     DWORD err;
511     struct gdi_image_bits src_bits;
512     struct bitblt_coords src, dst;
513     INT src_to_dst_offset;
514     HRGN clip = 0;
515     const struct gdi_dc_funcs *funcs;
516
517     if (!bitmapinfo_from_user_bitmapinfo( src_info, info, coloruse, TRUE ))
518     {
519         SetLastError( ERROR_INVALID_PARAMETER );
520         return 0;
521     }
522
523     src_bits.ptr = (void *)bits;
524     src_bits.is_copy = FALSE;
525     src_bits.free = NULL;
526     src_bits.param = NULL;
527
528     if (coloruse == DIB_RGB_COLORS && !dc)
529     {
530         hdc = CreateCompatibleDC(0);
531         dc = get_dc_ptr( hdc );
532         delete_hdc = TRUE;
533     }
534
535     if (!dc) return 0;
536
537     update_dc( dc );
538
539     if (!(bitmap = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
540     {
541         release_dc_ptr( dc );
542         if (delete_hdc) DeleteDC(hdc);
543         return 0;
544     }
545
546     if (coloruse == DIB_PAL_COLORS)
547         if (!fill_color_table_from_palette( src_info, dc )) goto done;
548
549     if (src_info->bmiHeader.biCompression == BI_RLE4 || src_info->bmiHeader.biCompression == BI_RLE8)
550     {
551         if (lines == 0) goto done;
552         else lines = src_info->bmiHeader.biHeight;
553         startscan = 0;
554
555         if (!build_rle_bitmap( src_info, &src_bits, &clip )) goto done;
556     }
557
558     dst.visrect.left   = 0;
559     dst.visrect.top    = 0;
560     dst.visrect.right  = bitmap->bitmap.bmWidth;
561     dst.visrect.bottom = bitmap->bitmap.bmHeight;
562
563     src.visrect.left   = 0;
564     src.visrect.top    = 0;
565     src.visrect.right  = src_info->bmiHeader.biWidth;
566     src.visrect.bottom = abs( src_info->bmiHeader.biHeight );
567
568     if (src_info->bmiHeader.biHeight > 0)
569     {
570         src_to_dst_offset = -startscan;
571         lines = min( lines, src.visrect.bottom - startscan );
572         if (lines < src.visrect.bottom) src.visrect.top = src.visrect.bottom - lines;
573     }
574     else
575     {
576         src_to_dst_offset = src.visrect.bottom - lines - startscan;
577         /* Unlike the bottom-up case, Windows doesn't limit lines. */
578         if (lines < src.visrect.bottom) src.visrect.bottom = lines;
579     }
580
581     /* Hack to ensure we don't get the nulldrv if the bmp hasn't been selected
582        into a dc yet */
583     physdev = GET_DC_PHYSDEV( dc, pCreateBitmap );
584     if (!BITMAP_SetOwnerDC( hbitmap, physdev )) goto done;
585
586     funcs = get_bitmap_funcs( bitmap );
587
588     result = lines;
589
590     offset_rect( &src.visrect, 0, src_to_dst_offset );
591     if (!intersect_rect( &dst.visrect, &src.visrect, &dst.visrect )) goto done;
592     src.visrect = dst.visrect;
593     offset_rect( &src.visrect, 0, -src_to_dst_offset );
594
595     src.x      = src.visrect.left;
596     src.y      = src.visrect.top;
597     src.width  = src.visrect.right - src.visrect.left;
598     src.height = src.visrect.bottom - src.visrect.top;
599
600     dst.x      = dst.visrect.left;
601     dst.y      = dst.visrect.top;
602     dst.width  = dst.visrect.right - dst.visrect.left;
603     dst.height = dst.visrect.bottom - dst.visrect.top;
604
605     memcpy( dst_info, src_info, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ));
606
607     err = funcs->pPutImage( NULL, hbitmap, clip, dst_info, &src_bits, &src, &dst, 0 );
608     if (err == ERROR_BAD_FORMAT)
609     {
610         void *ptr;
611
612         dst_info->bmiHeader.biWidth = dst.width;
613         ptr = HeapAlloc( GetProcessHeap(), 0, get_dib_image_size( dst_info ));
614         if (ptr)
615         {
616             err = convert_bitmapinfo( src_info, src_bits.ptr, &src, dst_info, ptr );
617             if (src_bits.free) src_bits.free( &src_bits );
618             src_bits.ptr = ptr;
619             src_bits.is_copy = TRUE;
620             src_bits.free = free_heap_bits;
621             if (!err)
622                 err = funcs->pPutImage( NULL, hbitmap, clip, dst_info, &src_bits, &src, &dst, 0 );
623         }
624         else err = ERROR_OUTOFMEMORY;
625     }
626     if(err) result = 0;
627
628 done:
629     if (src_bits.free) src_bits.free( &src_bits );
630     if (clip) DeleteObject( clip );
631     GDI_ReleaseObj( hbitmap );
632     release_dc_ptr( dc );
633     if (delete_hdc) DeleteDC(hdc);
634     return result;
635 }
636
637
638 /***********************************************************************
639  *           SetDIBitsToDevice   (GDI32.@)
640  */
641 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
642                            DWORD cy, INT xSrc, INT ySrc, UINT startscan,
643                            UINT lines, LPCVOID bits, const BITMAPINFO *bmi,
644                            UINT coloruse )
645 {
646     char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
647     BITMAPINFO *info = (BITMAPINFO *)buffer;
648     INT ret = 0;
649     DC *dc;
650
651     if (!bits) return 0;
652     if (!bitmapinfo_from_user_bitmapinfo( info, bmi, coloruse, TRUE ))
653     {
654         SetLastError( ERROR_INVALID_PARAMETER );
655         return 0;
656     }
657
658     if ((dc = get_dc_ptr( hdc )))
659     {
660         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDIBitsToDevice );
661         update_dc( dc );
662         ret = physdev->funcs->pSetDIBitsToDevice( physdev, xDest, yDest, cx, cy, xSrc,
663                                                   ySrc, startscan, lines, bits, info, coloruse );
664         release_dc_ptr( dc );
665     }
666     return ret;
667 }
668
669 /***********************************************************************
670  *           SetDIBColorTable    (GDI32.@)
671  */
672 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUAD *colors )
673 {
674     DC * dc;
675     UINT result = 0;
676     BITMAPOBJ * bitmap;
677
678     if (!(dc = get_dc_ptr( hdc ))) return 0;
679
680     if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
681     {
682         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDIBColorTable );
683
684         /* Check if currently selected bitmap is a DIB */
685         if (bitmap->color_table)
686         {
687             if (startpos < bitmap->nb_colors)
688             {
689                 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
690                 memcpy(bitmap->color_table + startpos, colors, entries * sizeof(RGBQUAD));
691                 result = entries;
692             }
693         }
694         GDI_ReleaseObj( dc->hBitmap );
695         physdev->funcs->pSetDIBColorTable( physdev, startpos, entries, colors );
696     }
697     release_dc_ptr( dc );
698     return result;
699 }
700
701
702 /***********************************************************************
703  *           GetDIBColorTable    (GDI32.@)
704  */
705 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
706 {
707     DC * dc;
708     BITMAPOBJ *bitmap;
709     UINT result = 0;
710
711     if (!(dc = get_dc_ptr( hdc ))) return 0;
712
713     if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
714     {
715         /* Check if currently selected bitmap is a DIB */
716         if (bitmap->color_table)
717         {
718             if (startpos < bitmap->nb_colors)
719             {
720                 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
721                 memcpy(colors, bitmap->color_table + startpos, entries * sizeof(RGBQUAD));
722                 result = entries;
723             }
724         }
725         GDI_ReleaseObj( dc->hBitmap );
726     }
727     release_dc_ptr( dc );
728     return result;
729 }
730
731 static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
732 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
733     { 0x00, 0x00, 0x00, 0x00 },
734     { 0x00, 0x00, 0x80, 0x00 },
735     { 0x00, 0x80, 0x00, 0x00 },
736     { 0x00, 0x80, 0x80, 0x00 },
737     { 0x80, 0x00, 0x00, 0x00 },
738     { 0x80, 0x00, 0x80, 0x00 },
739     { 0x80, 0x80, 0x00, 0x00 },
740     { 0xc0, 0xc0, 0xc0, 0x00 },
741     { 0xc0, 0xdc, 0xc0, 0x00 },
742     { 0xf0, 0xca, 0xa6, 0x00 },
743     { 0xf0, 0xfb, 0xff, 0x00 },
744     { 0xa4, 0xa0, 0xa0, 0x00 },
745     { 0x80, 0x80, 0x80, 0x00 },
746     { 0x00, 0x00, 0xff, 0x00 },
747     { 0x00, 0xff, 0x00, 0x00 },
748     { 0x00, 0xff, 0xff, 0x00 },
749     { 0xff, 0x00, 0x00, 0x00 },
750     { 0xff, 0x00, 0xff, 0x00 },
751     { 0xff, 0xff, 0x00, 0x00 },
752     { 0xff, 0xff, 0xff, 0x00 }
753 };
754
755 static const DWORD bit_fields_888[3] = {0xff0000, 0x00ff00, 0x0000ff};
756 static const DWORD bit_fields_565[3] = {0xf800, 0x07e0, 0x001f};
757 static const DWORD bit_fields_555[3] = {0x7c00, 0x03e0, 0x001f};
758
759 static int fill_query_info( BITMAPINFO *info, BITMAPOBJ *bmp )
760 {
761     BITMAPINFOHEADER header;
762
763     header.biSize   = info->bmiHeader.biSize; /* Ensure we don't overwrite the original size when we copy back */
764     header.biWidth  = bmp->bitmap.bmWidth;
765     header.biHeight = bmp->bitmap.bmHeight;
766     header.biPlanes = 1;
767
768     if (bmp->dib)
769     {
770         header.biBitCount = bmp->dib->dsBm.bmBitsPixel;
771         switch (bmp->dib->dsBm.bmBitsPixel)
772         {
773         case 16:
774         case 32:
775             header.biCompression = BI_BITFIELDS;
776             break;
777         default:
778             header.biCompression = BI_RGB;
779             break;
780         }
781     }
782     else
783     {
784         header.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB;
785         header.biBitCount = bmp->bitmap.bmBitsPixel;
786     }
787
788     header.biSizeImage = get_dib_image_size( (BITMAPINFO *)&header );
789     header.biXPelsPerMeter = 0;
790     header.biYPelsPerMeter = 0;
791     header.biClrUsed       = 0;
792     header.biClrImportant  = 0;
793
794     if ( info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER) )
795     {
796         BITMAPCOREHEADER *coreheader = (BITMAPCOREHEADER *)info;
797
798         coreheader->bcWidth    = header.biWidth;
799         coreheader->bcHeight   = header.biHeight;
800         coreheader->bcPlanes   = header.biPlanes;
801         coreheader->bcBitCount = header.biBitCount;
802     }
803     else
804         info->bmiHeader = header;
805
806     return abs(bmp->bitmap.bmHeight);
807 }
808
809 /************************************************************************
810  *      copy_color_info
811  *
812  * Copy BITMAPINFO color information where dst may be a BITMAPCOREINFO.
813  */
814 static void copy_color_info(BITMAPINFO *dst, const BITMAPINFO *src, UINT coloruse)
815 {
816     unsigned int colors = get_dib_num_of_colors( src );
817     RGBQUAD *src_colors = (RGBQUAD *)((char *)src + src->bmiHeader.biSize);
818
819     assert( src->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) );
820
821     if (dst->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
822     {
823         BITMAPCOREINFO *core = (BITMAPCOREINFO *)dst;
824         if (coloruse == DIB_PAL_COLORS)
825             memcpy( core->bmciColors, src_colors, colors * sizeof(WORD) );
826         else
827         {
828             unsigned int i;
829             for (i = 0; i < colors; i++)
830             {
831                 core->bmciColors[i].rgbtRed   = src_colors[i].rgbRed;
832                 core->bmciColors[i].rgbtGreen = src_colors[i].rgbGreen;
833                 core->bmciColors[i].rgbtBlue  = src_colors[i].rgbBlue;
834             }
835         }
836     }
837     else
838     {
839         dst->bmiHeader.biClrUsed   = src->bmiHeader.biClrUsed;
840         dst->bmiHeader.biSizeImage = src->bmiHeader.biSizeImage;
841
842         if (src->bmiHeader.biCompression == BI_BITFIELDS)
843             /* bitfields are always at bmiColors even in larger structures */
844             memcpy( dst->bmiColors, src->bmiColors, 3 * sizeof(DWORD) );
845         else if (colors)
846         {
847             void *colorptr = (char *)dst + dst->bmiHeader.biSize;
848             unsigned int size;
849
850             if (coloruse == DIB_PAL_COLORS)
851                 size = colors * sizeof(WORD);
852             else
853                 size = colors * sizeof(RGBQUAD);
854             memcpy( colorptr, src_colors, size );
855         }
856     }
857 }
858
859 static void fill_default_color_table( BITMAPINFO *info )
860 {
861     int i;
862
863     switch (info->bmiHeader.biBitCount)
864     {
865     case 1:
866         info->bmiColors[0].rgbRed = info->bmiColors[0].rgbGreen = info->bmiColors[0].rgbBlue = 0;
867         info->bmiColors[0].rgbReserved = 0;
868         info->bmiColors[1].rgbRed = info->bmiColors[1].rgbGreen = info->bmiColors[1].rgbBlue = 0xff;
869         info->bmiColors[1].rgbReserved = 0;
870         break;
871
872     case 4:
873         /* The EGA palette is the first and last 8 colours of the default palette
874            with the innermost pair swapped */
875         memcpy(info->bmiColors,     DefLogPaletteQuads,      7 * sizeof(RGBQUAD));
876         memcpy(info->bmiColors + 7, DefLogPaletteQuads + 12, 1 * sizeof(RGBQUAD));
877         memcpy(info->bmiColors + 8, DefLogPaletteQuads +  7, 1 * sizeof(RGBQUAD));
878         memcpy(info->bmiColors + 9, DefLogPaletteQuads + 13, 7 * sizeof(RGBQUAD));
879         break;
880
881     case 8:
882         memcpy(info->bmiColors, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
883         memcpy(info->bmiColors + 246, DefLogPaletteQuads + 10, 10 * sizeof(RGBQUAD));
884         for (i = 10; i < 246; i++)
885         {
886             info->bmiColors[i].rgbRed      = (i & 0x07) << 5;
887             info->bmiColors[i].rgbGreen    = (i & 0x38) << 2;
888             info->bmiColors[i].rgbBlue     =  i & 0xc0;
889             info->bmiColors[i].rgbReserved = 0;
890         }
891         break;
892
893     default:
894         ERR("called with bitcount %d\n", info->bmiHeader.biBitCount);
895     }
896 }
897
898 /******************************************************************************
899  * GetDIBits [GDI32.@]
900  *
901  * Retrieves bits of bitmap and copies to buffer.
902  *
903  * RETURNS
904  *    Success: Number of scan lines copied from bitmap
905  *    Failure: 0
906  */
907 INT WINAPI GetDIBits(
908     HDC hdc,         /* [in]  Handle to device context */
909     HBITMAP hbitmap, /* [in]  Handle to bitmap */
910     UINT startscan,  /* [in]  First scan line to set in dest bitmap */
911     UINT lines,      /* [in]  Number of scan lines to copy */
912     LPVOID bits,       /* [out] Address of array for bitmap bits */
913     BITMAPINFO * info, /* [out] Address of structure with bitmap data */
914     UINT coloruse)   /* [in]  RGB or palette index */
915 {
916     DC * dc;
917     BITMAPOBJ * bmp;
918     int i, dst_to_src_offset, ret = 0;
919     DWORD err;
920     char dst_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
921     BITMAPINFO *dst_info = (BITMAPINFO *)dst_bmibuf;
922     char src_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
923     BITMAPINFO *src_info = (BITMAPINFO *)src_bmibuf;
924     const struct gdi_dc_funcs *funcs;
925     struct gdi_image_bits src_bits;
926     struct bitblt_coords src, dst;
927     BOOL empty_rect = FALSE;
928
929     /* Since info may be a BITMAPCOREINFO or any of the larger BITMAPINFO structures, we'll use our
930        own copy and transfer the colour info back at the end */
931     if (!bitmapinfoheader_from_user_bitmapinfo( &dst_info->bmiHeader, &info->bmiHeader )) return 0;
932     dst_info->bmiHeader.biClrUsed = 0;
933     dst_info->bmiHeader.biClrImportant = 0;
934
935     if (!(dc = get_dc_ptr( hdc )))
936     {
937         SetLastError( ERROR_INVALID_PARAMETER );
938         return 0;
939     }
940     update_dc( dc );
941     if (!(bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
942     {
943         release_dc_ptr( dc );
944         return 0;
945     }
946
947     funcs = get_bitmap_funcs( bmp );
948
949     if (dst_info->bmiHeader.biBitCount == 0) /* query bitmap info only */
950     {
951         ret = fill_query_info( info, bmp );
952         goto done;
953     }
954
955     src.visrect.left   = 0;
956     src.visrect.top    = 0;
957     src.visrect.right  = bmp->bitmap.bmWidth;
958     src.visrect.bottom = bmp->bitmap.bmHeight;
959
960     dst.visrect.left   = 0;
961     dst.visrect.top    = 0;
962     dst.visrect.right  = dst_info->bmiHeader.biWidth;
963     dst.visrect.bottom = abs( dst_info->bmiHeader.biHeight );
964
965     if (lines == 0 || startscan >= dst.visrect.bottom)
966         bits = NULL;
967
968     if (bits)
969     {
970         if (dst_info->bmiHeader.biHeight > 0)
971         {
972             dst_to_src_offset = -startscan;
973             lines = min( lines, dst.visrect.bottom - startscan );
974             if (lines < dst.visrect.bottom) dst.visrect.top = dst.visrect.bottom - lines;
975         }
976         else
977         {
978             dst_to_src_offset = dst.visrect.bottom - lines - startscan;
979             if (dst_to_src_offset < 0)
980             {
981                 dst_to_src_offset = 0;
982                 lines = dst.visrect.bottom - startscan;
983             }
984             if (lines < dst.visrect.bottom) dst.visrect.bottom = lines;
985         }
986
987         offset_rect( &dst.visrect, 0, dst_to_src_offset );
988         empty_rect = !intersect_rect( &src.visrect, &src.visrect, &dst.visrect );
989         dst.visrect = src.visrect;
990         offset_rect( &dst.visrect, 0, -dst_to_src_offset );
991
992         if (dst_info->bmiHeader.biHeight > 0)
993         {
994             if (dst.visrect.bottom < dst_info->bmiHeader.biHeight)
995             {
996                 int pad_lines = min( dst_info->bmiHeader.biHeight - dst.visrect.bottom, lines );
997                 int pad_bytes = pad_lines * get_dib_stride( dst_info->bmiHeader.biWidth, dst_info->bmiHeader.biBitCount );
998                 memset( bits, 0, pad_bytes );
999                 bits = (char *)bits + pad_bytes;
1000             }
1001         }
1002         else
1003         {
1004             if (dst.visrect.bottom < lines)
1005             {
1006                 int pad_lines = lines - dst.visrect.bottom;
1007                 int stride = get_dib_stride( dst_info->bmiHeader.biWidth, dst_info->bmiHeader.biBitCount );
1008                 int pad_bytes = pad_lines * stride;
1009                 memset( (char *)bits + dst.visrect.bottom * stride, 0, pad_bytes );
1010             }
1011         }
1012
1013         if (empty_rect) bits = NULL;
1014
1015         src.x      = src.visrect.left;
1016         src.y      = src.visrect.top;
1017         src.width  = src.visrect.right - src.visrect.left;
1018         src.height = src.visrect.bottom - src.visrect.top;
1019
1020         lines = src.height;
1021     }
1022
1023     err = funcs->pGetImage( NULL, hbitmap, src_info, bits ? &src_bits : NULL, bits ? &src : NULL );
1024
1025     if (err) goto done;
1026
1027     /* fill out the src colour table, if it needs one */
1028     if (src_info->bmiHeader.biBitCount <= 8 && src_info->bmiHeader.biClrUsed == 0)
1029     {
1030         fill_default_color_table( src_info );
1031         src_info->bmiHeader.biClrUsed = 1 << src_info->bmiHeader.biBitCount;
1032     }
1033
1034     /* if the src and dst are the same depth, copy the colour info across */
1035     if (dst_info->bmiHeader.biBitCount == src_info->bmiHeader.biBitCount && coloruse == DIB_RGB_COLORS )
1036     {
1037         switch (src_info->bmiHeader.biBitCount)
1038         {
1039         case 16:
1040             if (src_info->bmiHeader.biCompression == BI_RGB)
1041             {
1042                 src_info->bmiHeader.biCompression = BI_BITFIELDS;
1043                 memcpy( src_info->bmiColors, bit_fields_555, sizeof(bit_fields_555) );
1044             }
1045             break;
1046         case 32:
1047             if (src_info->bmiHeader.biCompression == BI_RGB)
1048             {
1049                 src_info->bmiHeader.biCompression = BI_BITFIELDS;
1050                 memcpy( src_info->bmiColors, bit_fields_888, sizeof(bit_fields_888) );
1051             }
1052             break;
1053         }
1054         src_info->bmiHeader.biSizeImage = get_dib_image_size( dst_info );
1055         copy_color_info( dst_info, src_info, coloruse );
1056     }
1057     else if (dst_info->bmiHeader.biBitCount <= 8) /* otherwise construct a default colour table for the dst, if needed */
1058     {
1059         if( coloruse == DIB_PAL_COLORS )
1060         {
1061             if (!fill_color_table_from_palette( dst_info, dc )) goto done;
1062         }
1063         else
1064         {
1065             fill_default_color_table( dst_info );
1066         }
1067     }
1068
1069     if (bits)
1070     {
1071         if(dst_info->bmiHeader.biHeight > 0)
1072             dst_info->bmiHeader.biHeight = src.height;
1073         else
1074             dst_info->bmiHeader.biHeight = -src.height;
1075
1076         convert_bitmapinfo( src_info, src_bits.ptr, &src, dst_info, bits );
1077         if (src_bits.free) src_bits.free( &src_bits );
1078         ret = lines;
1079     }
1080     else
1081         ret = empty_rect ? FALSE : TRUE;
1082
1083     if (coloruse == DIB_PAL_COLORS)
1084     {
1085         WORD *index = (WORD *)dst_info->bmiColors;
1086         int colors = get_dib_num_of_colors( dst_info );
1087         for (i = 0; i < colors; i++, index++)
1088             *index = i;
1089     }
1090
1091     copy_color_info( info, dst_info, coloruse );
1092
1093 done:
1094     release_dc_ptr( dc );
1095     GDI_ReleaseObj( hbitmap );
1096     return ret;
1097 }
1098
1099
1100 /***********************************************************************
1101  *           CreateDIBitmap    (GDI32.@)
1102  *
1103  * Creates a DDB (device dependent bitmap) from a DIB.
1104  * The DDB will have the same color depth as the reference DC.
1105  */
1106 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
1107                             DWORD init, LPCVOID bits, const BITMAPINFO *data,
1108                             UINT coloruse )
1109 {
1110     BITMAPINFOHEADER info;
1111     HBITMAP handle;
1112     LONG height;
1113
1114     if (!bitmapinfoheader_from_user_bitmapinfo( &info, header )) return 0;
1115     if (info.biCompression == BI_JPEG || info.biCompression == BI_PNG) return 0;
1116     if (info.biWidth < 0) return 0;
1117
1118     /* Top-down DIBs have a negative height */
1119     height = abs( info.biHeight );
1120
1121     TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1122           hdc, header, init, bits, data, coloruse, info.biWidth, info.biHeight,
1123           info.biBitCount, info.biCompression);
1124
1125     if (hdc == NULL)
1126         handle = CreateBitmap( info.biWidth, height, 1, 1, NULL );
1127     else
1128         handle = CreateCompatibleBitmap( hdc, info.biWidth, height );
1129
1130     if (handle)
1131     {
1132         if (init & CBM_INIT)
1133         {
1134             if (SetDIBits( hdc, handle, 0, height, bits, data, coloruse ) == 0)
1135             {
1136                 DeleteObject( handle );
1137                 handle = 0;
1138             }
1139         }
1140     }
1141
1142     return handle;
1143 }
1144
1145 /* Copy/synthesize RGB palette from BITMAPINFO */
1146 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1147 {
1148     unsigned int colors, i;
1149
1150     colors = get_dib_num_of_colors( info );
1151     if (!(bmp->color_table = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1152     bmp->nb_colors = colors;
1153
1154     if (coloruse == DIB_RGB_COLORS)
1155     {
1156         memcpy( bmp->color_table, info->bmiColors, colors * sizeof(RGBQUAD));
1157     }
1158     else
1159     {
1160         PALETTEENTRY entries[256];
1161         const WORD *index = (const WORD *)info->bmiColors;
1162         UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1163
1164         for (i = 0; i < colors; i++, index++)
1165         {
1166             PALETTEENTRY *entry = &entries[*index % count];
1167             bmp->color_table[i].rgbRed = entry->peRed;
1168             bmp->color_table[i].rgbGreen = entry->peGreen;
1169             bmp->color_table[i].rgbBlue = entry->peBlue;
1170             bmp->color_table[i].rgbReserved = 0;
1171         }
1172     }
1173 }
1174
1175 /***********************************************************************
1176  *           CreateDIBSection    (GDI32.@)
1177  */
1178 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1179                                 VOID **bits, HANDLE section, DWORD offset)
1180 {
1181     char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1182     BITMAPINFO *info = (BITMAPINFO *)buffer;
1183     HBITMAP ret = 0;
1184     DC *dc;
1185     BOOL bDesktopDC = FALSE;
1186     DIBSECTION *dib;
1187     BITMAPOBJ *bmp;
1188     void *mapBits = NULL;
1189
1190     if (bits) *bits = NULL;
1191     if (!bitmapinfo_from_user_bitmapinfo( info, bmi, usage, FALSE )) return 0;
1192     if (info->bmiHeader.biPlanes != 1)
1193     {
1194         if (info->bmiHeader.biPlanes * info->bmiHeader.biBitCount > 16) return 0;
1195         WARN( "%u planes not properly supported\n", info->bmiHeader.biPlanes );
1196     }
1197
1198     if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1199
1200     TRACE("format (%d,%d), planes %d, bpp %d, %s, size %d %s\n",
1201           info->bmiHeader.biWidth, info->bmiHeader.biHeight,
1202           info->bmiHeader.biPlanes, info->bmiHeader.biBitCount,
1203           info->bmiHeader.biCompression == BI_BITFIELDS? "BI_BITFIELDS" : "BI_RGB",
1204           info->bmiHeader.biSizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1205
1206     dib->dsBm.bmType       = 0;
1207     dib->dsBm.bmWidth      = info->bmiHeader.biWidth;
1208     dib->dsBm.bmHeight     = abs( info->bmiHeader.biHeight );
1209     dib->dsBm.bmWidthBytes = get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
1210     dib->dsBm.bmPlanes     = info->bmiHeader.biPlanes;
1211     dib->dsBm.bmBitsPixel  = info->bmiHeader.biBitCount;
1212     dib->dsBm.bmBits       = NULL;
1213     dib->dsBmih            = info->bmiHeader;
1214
1215     /* set number of entries in bmi.bmiColors table */
1216     if( info->bmiHeader.biBitCount <= 8 )
1217         dib->dsBmih.biClrUsed = 1 << info->bmiHeader.biBitCount;
1218
1219     /* set dsBitfields values */
1220     if (info->bmiHeader.biBitCount == 16 && info->bmiHeader.biCompression == BI_RGB)
1221     {
1222         dib->dsBmih.biCompression = BI_BITFIELDS;
1223         dib->dsBitfields[0] = 0x7c00;
1224         dib->dsBitfields[1] = 0x03e0;
1225         dib->dsBitfields[2] = 0x001f;
1226     }
1227     else if (info->bmiHeader.biCompression == BI_BITFIELDS)
1228     {
1229         dib->dsBitfields[0] =  *(const DWORD *)bmi->bmiColors;
1230         dib->dsBitfields[1] =  *((const DWORD *)bmi->bmiColors + 1);
1231         dib->dsBitfields[2] =  *((const DWORD *)bmi->bmiColors + 2);
1232         if (!dib->dsBitfields[0] || !dib->dsBitfields[1] || !dib->dsBitfields[2]) goto error;
1233     }
1234     else dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1235
1236     /* get storage location for DIB bits */
1237
1238     if (section)
1239     {
1240         SYSTEM_INFO SystemInfo;
1241         DWORD mapOffset;
1242         INT mapSize;
1243
1244         GetSystemInfo( &SystemInfo );
1245         mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1246         mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1247         mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1248         if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1249     }
1250     else
1251     {
1252         offset = 0;
1253         dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1254                                          MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1255     }
1256     dib->dshSection = section;
1257     dib->dsOffset = offset;
1258
1259     if (!dib->dsBm.bmBits)
1260     {
1261         HeapFree( GetProcessHeap(), 0, dib );
1262         return 0;
1263     }
1264
1265     /* If the reference hdc is null, take the desktop dc */
1266     if (hdc == 0)
1267     {
1268         hdc = CreateCompatibleDC(0);
1269         bDesktopDC = TRUE;
1270     }
1271
1272     if (!(dc = get_dc_ptr( hdc ))) goto error;
1273
1274     /* create Device Dependent Bitmap and add DIB pointer */
1275     ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1276                         (info->bmiHeader.biBitCount == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1277
1278     if (ret && ((bmp = GDI_GetObjPtr(ret, OBJ_BITMAP))))
1279     {
1280         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pCreateDIBSection );
1281         bmp->dib = dib;
1282         bmp->funcs = physdev->funcs;
1283         /* create local copy of DIB palette */
1284         if (info->bmiHeader.biBitCount <= 8) DIB_CopyColorTable( dc, bmp, usage, info );
1285         GDI_ReleaseObj( ret );
1286
1287         if (!physdev->funcs->pCreateDIBSection( physdev, ret, info, usage ))
1288         {
1289             DeleteObject( ret );
1290             ret = 0;
1291         }
1292     }
1293
1294     release_dc_ptr( dc );
1295     if (bDesktopDC) DeleteDC( hdc );
1296     if (ret && bits) *bits = dib->dsBm.bmBits;
1297     return ret;
1298
1299 error:
1300     if (bDesktopDC) DeleteDC( hdc );
1301     if (section) UnmapViewOfFile( mapBits );
1302     else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1303     HeapFree( GetProcessHeap(), 0, dib );
1304     return 0;
1305 }