mshtml: Populate dynamic properties table in get_dynamic_data.
[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             {
618                 if (src_bits.free) src_bits.free( &src_bits );
619                 src_bits.ptr = ptr;
620                 src_bits.is_copy = TRUE;
621                 src_bits.free = free_heap_bits;
622                 if (!err)
623                     err = funcs->pPutImage( NULL, hbitmap, clip, dst_info, &src_bits, &src, &dst, 0 );
624             }
625         }
626         else err = ERROR_OUTOFMEMORY;
627     }
628     if(err) result = 0;
629
630 done:
631     if (src_bits.free) src_bits.free( &src_bits );
632     if (clip) DeleteObject( clip );
633     GDI_ReleaseObj( hbitmap );
634     release_dc_ptr( dc );
635     if (delete_hdc) DeleteDC(hdc);
636     return result;
637 }
638
639
640 /***********************************************************************
641  *           SetDIBitsToDevice   (GDI32.@)
642  */
643 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
644                            DWORD cy, INT xSrc, INT ySrc, UINT startscan,
645                            UINT lines, LPCVOID bits, const BITMAPINFO *bmi,
646                            UINT coloruse )
647 {
648     char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
649     BITMAPINFO *info = (BITMAPINFO *)buffer;
650     INT ret = 0;
651     DC *dc;
652
653     if (!bits) return 0;
654     if (!bitmapinfo_from_user_bitmapinfo( info, bmi, coloruse, TRUE ))
655     {
656         SetLastError( ERROR_INVALID_PARAMETER );
657         return 0;
658     }
659
660     if ((dc = get_dc_ptr( hdc )))
661     {
662         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDIBitsToDevice );
663         update_dc( dc );
664         ret = physdev->funcs->pSetDIBitsToDevice( physdev, xDest, yDest, cx, cy, xSrc,
665                                                   ySrc, startscan, lines, bits, info, coloruse );
666         release_dc_ptr( dc );
667     }
668     return ret;
669 }
670
671 /***********************************************************************
672  *           SetDIBColorTable    (GDI32.@)
673  */
674 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUAD *colors )
675 {
676     DC * dc;
677     UINT result = 0;
678     BITMAPOBJ * bitmap;
679
680     if (!(dc = get_dc_ptr( hdc ))) return 0;
681
682     if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
683     {
684         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDIBColorTable );
685
686         /* Check if currently selected bitmap is a DIB */
687         if (bitmap->color_table)
688         {
689             if (startpos < bitmap->nb_colors)
690             {
691                 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
692                 memcpy(bitmap->color_table + startpos, colors, entries * sizeof(RGBQUAD));
693                 result = entries;
694             }
695         }
696         GDI_ReleaseObj( dc->hBitmap );
697         physdev->funcs->pSetDIBColorTable( physdev, startpos, entries, colors );
698     }
699     release_dc_ptr( dc );
700     return result;
701 }
702
703
704 /***********************************************************************
705  *           GetDIBColorTable    (GDI32.@)
706  */
707 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
708 {
709     DC * dc;
710     BITMAPOBJ *bitmap;
711     UINT result = 0;
712
713     if (!(dc = get_dc_ptr( hdc ))) return 0;
714
715     if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
716     {
717         /* Check if currently selected bitmap is a DIB */
718         if (bitmap->color_table)
719         {
720             if (startpos < bitmap->nb_colors)
721             {
722                 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
723                 memcpy(colors, bitmap->color_table + startpos, entries * sizeof(RGBQUAD));
724                 result = entries;
725             }
726         }
727         GDI_ReleaseObj( dc->hBitmap );
728     }
729     release_dc_ptr( dc );
730     return result;
731 }
732
733 static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
734 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
735     { 0x00, 0x00, 0x00, 0x00 },
736     { 0x00, 0x00, 0x80, 0x00 },
737     { 0x00, 0x80, 0x00, 0x00 },
738     { 0x00, 0x80, 0x80, 0x00 },
739     { 0x80, 0x00, 0x00, 0x00 },
740     { 0x80, 0x00, 0x80, 0x00 },
741     { 0x80, 0x80, 0x00, 0x00 },
742     { 0xc0, 0xc0, 0xc0, 0x00 },
743     { 0xc0, 0xdc, 0xc0, 0x00 },
744     { 0xf0, 0xca, 0xa6, 0x00 },
745     { 0xf0, 0xfb, 0xff, 0x00 },
746     { 0xa4, 0xa0, 0xa0, 0x00 },
747     { 0x80, 0x80, 0x80, 0x00 },
748     { 0x00, 0x00, 0xff, 0x00 },
749     { 0x00, 0xff, 0x00, 0x00 },
750     { 0x00, 0xff, 0xff, 0x00 },
751     { 0xff, 0x00, 0x00, 0x00 },
752     { 0xff, 0x00, 0xff, 0x00 },
753     { 0xff, 0xff, 0x00, 0x00 },
754     { 0xff, 0xff, 0xff, 0x00 }
755 };
756
757 static const DWORD bit_fields_888[3] = {0xff0000, 0x00ff00, 0x0000ff};
758 static const DWORD bit_fields_565[3] = {0xf800, 0x07e0, 0x001f};
759 static const DWORD bit_fields_555[3] = {0x7c00, 0x03e0, 0x001f};
760
761 static int fill_query_info( BITMAPINFO *info, BITMAPOBJ *bmp )
762 {
763     BITMAPINFOHEADER header;
764
765     header.biSize   = info->bmiHeader.biSize; /* Ensure we don't overwrite the original size when we copy back */
766     header.biWidth  = bmp->bitmap.bmWidth;
767     header.biHeight = bmp->bitmap.bmHeight;
768     header.biPlanes = 1;
769
770     if (bmp->dib)
771     {
772         header.biBitCount = bmp->dib->dsBm.bmBitsPixel;
773         switch (bmp->dib->dsBm.bmBitsPixel)
774         {
775         case 16:
776         case 32:
777             header.biCompression = BI_BITFIELDS;
778             break;
779         default:
780             header.biCompression = BI_RGB;
781             break;
782         }
783     }
784     else
785     {
786         header.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB;
787         header.biBitCount = bmp->bitmap.bmBitsPixel;
788     }
789
790     header.biSizeImage = get_dib_image_size( (BITMAPINFO *)&header );
791     header.biXPelsPerMeter = 0;
792     header.biYPelsPerMeter = 0;
793     header.biClrUsed       = 0;
794     header.biClrImportant  = 0;
795
796     if ( info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER) )
797     {
798         BITMAPCOREHEADER *coreheader = (BITMAPCOREHEADER *)info;
799
800         coreheader->bcWidth    = header.biWidth;
801         coreheader->bcHeight   = header.biHeight;
802         coreheader->bcPlanes   = header.biPlanes;
803         coreheader->bcBitCount = header.biBitCount;
804     }
805     else
806         info->bmiHeader = header;
807
808     return abs(bmp->bitmap.bmHeight);
809 }
810
811 /************************************************************************
812  *      copy_color_info
813  *
814  * Copy BITMAPINFO color information where dst may be a BITMAPCOREINFO.
815  */
816 static void copy_color_info(BITMAPINFO *dst, const BITMAPINFO *src, UINT coloruse)
817 {
818     unsigned int colors = get_dib_num_of_colors( src );
819     RGBQUAD *src_colors = (RGBQUAD *)((char *)src + src->bmiHeader.biSize);
820
821     assert( src->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) );
822
823     if (dst->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
824     {
825         BITMAPCOREINFO *core = (BITMAPCOREINFO *)dst;
826         if (coloruse == DIB_PAL_COLORS)
827             memcpy( core->bmciColors, src_colors, colors * sizeof(WORD) );
828         else
829         {
830             unsigned int i;
831             for (i = 0; i < colors; i++)
832             {
833                 core->bmciColors[i].rgbtRed   = src_colors[i].rgbRed;
834                 core->bmciColors[i].rgbtGreen = src_colors[i].rgbGreen;
835                 core->bmciColors[i].rgbtBlue  = src_colors[i].rgbBlue;
836             }
837         }
838     }
839     else
840     {
841         dst->bmiHeader.biClrUsed   = src->bmiHeader.biClrUsed;
842         dst->bmiHeader.biSizeImage = src->bmiHeader.biSizeImage;
843
844         if (src->bmiHeader.biCompression == BI_BITFIELDS)
845             /* bitfields are always at bmiColors even in larger structures */
846             memcpy( dst->bmiColors, src->bmiColors, 3 * sizeof(DWORD) );
847         else if (colors)
848         {
849             void *colorptr = (char *)dst + dst->bmiHeader.biSize;
850             unsigned int size;
851
852             if (coloruse == DIB_PAL_COLORS)
853                 size = colors * sizeof(WORD);
854             else
855                 size = colors * sizeof(RGBQUAD);
856             memcpy( colorptr, src_colors, size );
857         }
858     }
859 }
860
861 static void fill_default_color_table( BITMAPINFO *info )
862 {
863     int i;
864
865     switch (info->bmiHeader.biBitCount)
866     {
867     case 1:
868         info->bmiColors[0].rgbRed = info->bmiColors[0].rgbGreen = info->bmiColors[0].rgbBlue = 0;
869         info->bmiColors[0].rgbReserved = 0;
870         info->bmiColors[1].rgbRed = info->bmiColors[1].rgbGreen = info->bmiColors[1].rgbBlue = 0xff;
871         info->bmiColors[1].rgbReserved = 0;
872         break;
873
874     case 4:
875         /* The EGA palette is the first and last 8 colours of the default palette
876            with the innermost pair swapped */
877         memcpy(info->bmiColors,     DefLogPaletteQuads,      7 * sizeof(RGBQUAD));
878         memcpy(info->bmiColors + 7, DefLogPaletteQuads + 12, 1 * sizeof(RGBQUAD));
879         memcpy(info->bmiColors + 8, DefLogPaletteQuads +  7, 1 * sizeof(RGBQUAD));
880         memcpy(info->bmiColors + 9, DefLogPaletteQuads + 13, 7 * sizeof(RGBQUAD));
881         break;
882
883     case 8:
884         memcpy(info->bmiColors, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
885         memcpy(info->bmiColors + 246, DefLogPaletteQuads + 10, 10 * sizeof(RGBQUAD));
886         for (i = 10; i < 246; i++)
887         {
888             info->bmiColors[i].rgbRed      = (i & 0x07) << 5;
889             info->bmiColors[i].rgbGreen    = (i & 0x38) << 2;
890             info->bmiColors[i].rgbBlue     =  i & 0xc0;
891             info->bmiColors[i].rgbReserved = 0;
892         }
893         break;
894
895     default:
896         ERR("called with bitcount %d\n", info->bmiHeader.biBitCount);
897     }
898 }
899
900 /******************************************************************************
901  * GetDIBits [GDI32.@]
902  *
903  * Retrieves bits of bitmap and copies to buffer.
904  *
905  * RETURNS
906  *    Success: Number of scan lines copied from bitmap
907  *    Failure: 0
908  */
909 INT WINAPI GetDIBits(
910     HDC hdc,         /* [in]  Handle to device context */
911     HBITMAP hbitmap, /* [in]  Handle to bitmap */
912     UINT startscan,  /* [in]  First scan line to set in dest bitmap */
913     UINT lines,      /* [in]  Number of scan lines to copy */
914     LPVOID bits,       /* [out] Address of array for bitmap bits */
915     BITMAPINFO * info, /* [out] Address of structure with bitmap data */
916     UINT coloruse)   /* [in]  RGB or palette index */
917 {
918     DC * dc;
919     BITMAPOBJ * bmp;
920     int i, dst_to_src_offset, ret = 0;
921     DWORD err;
922     char dst_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
923     BITMAPINFO *dst_info = (BITMAPINFO *)dst_bmibuf;
924     char src_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
925     BITMAPINFO *src_info = (BITMAPINFO *)src_bmibuf;
926     const struct gdi_dc_funcs *funcs;
927     struct gdi_image_bits src_bits;
928     struct bitblt_coords src, dst;
929     BOOL empty_rect = FALSE;
930
931     /* Since info may be a BITMAPCOREINFO or any of the larger BITMAPINFO structures, we'll use our
932        own copy and transfer the colour info back at the end */
933     if (!bitmapinfoheader_from_user_bitmapinfo( &dst_info->bmiHeader, &info->bmiHeader )) return 0;
934     dst_info->bmiHeader.biClrUsed = 0;
935     dst_info->bmiHeader.biClrImportant = 0;
936
937     if (!(dc = get_dc_ptr( hdc )))
938     {
939         SetLastError( ERROR_INVALID_PARAMETER );
940         return 0;
941     }
942     update_dc( dc );
943     if (!(bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
944     {
945         release_dc_ptr( dc );
946         return 0;
947     }
948
949     funcs = get_bitmap_funcs( bmp );
950
951     if (dst_info->bmiHeader.biBitCount == 0) /* query bitmap info only */
952     {
953         ret = fill_query_info( info, bmp );
954         goto done;
955     }
956
957     src.visrect.left   = 0;
958     src.visrect.top    = 0;
959     src.visrect.right  = bmp->bitmap.bmWidth;
960     src.visrect.bottom = bmp->bitmap.bmHeight;
961
962     dst.visrect.left   = 0;
963     dst.visrect.top    = 0;
964     dst.visrect.right  = dst_info->bmiHeader.biWidth;
965     dst.visrect.bottom = abs( dst_info->bmiHeader.biHeight );
966
967     if (lines == 0 || startscan >= dst.visrect.bottom)
968         bits = NULL;
969
970     if (bits)
971     {
972         if (dst_info->bmiHeader.biHeight > 0)
973         {
974             dst_to_src_offset = -startscan;
975             lines = min( lines, dst.visrect.bottom - startscan );
976             if (lines < dst.visrect.bottom) dst.visrect.top = dst.visrect.bottom - lines;
977         }
978         else
979         {
980             dst_to_src_offset = dst.visrect.bottom - lines - startscan;
981             if (dst_to_src_offset < 0)
982             {
983                 dst_to_src_offset = 0;
984                 lines = dst.visrect.bottom - startscan;
985             }
986             if (lines < dst.visrect.bottom) dst.visrect.bottom = lines;
987         }
988
989         offset_rect( &dst.visrect, 0, dst_to_src_offset );
990         empty_rect = !intersect_rect( &src.visrect, &src.visrect, &dst.visrect );
991         dst.visrect = src.visrect;
992         offset_rect( &dst.visrect, 0, -dst_to_src_offset );
993
994         if (dst_info->bmiHeader.biHeight > 0)
995         {
996             if (dst.visrect.bottom < dst_info->bmiHeader.biHeight)
997             {
998                 int pad_lines = min( dst_info->bmiHeader.biHeight - dst.visrect.bottom, lines );
999                 int pad_bytes = pad_lines * get_dib_stride( dst_info->bmiHeader.biWidth, dst_info->bmiHeader.biBitCount );
1000                 memset( bits, 0, pad_bytes );
1001                 bits = (char *)bits + pad_bytes;
1002             }
1003         }
1004         else
1005         {
1006             if (dst.visrect.bottom < lines)
1007             {
1008                 int pad_lines = lines - dst.visrect.bottom;
1009                 int stride = get_dib_stride( dst_info->bmiHeader.biWidth, dst_info->bmiHeader.biBitCount );
1010                 int pad_bytes = pad_lines * stride;
1011                 memset( (char *)bits + dst.visrect.bottom * stride, 0, pad_bytes );
1012             }
1013         }
1014
1015         if (empty_rect) bits = NULL;
1016
1017         src.x      = src.visrect.left;
1018         src.y      = src.visrect.top;
1019         src.width  = src.visrect.right - src.visrect.left;
1020         src.height = src.visrect.bottom - src.visrect.top;
1021
1022         lines = src.height;
1023     }
1024
1025     err = funcs->pGetImage( NULL, hbitmap, src_info, bits ? &src_bits : NULL, bits ? &src : NULL );
1026
1027     if (err) goto done;
1028
1029     /* fill out the src colour table, if it needs one */
1030     if (src_info->bmiHeader.biBitCount <= 8 && src_info->bmiHeader.biClrUsed == 0)
1031     {
1032         fill_default_color_table( src_info );
1033         src_info->bmiHeader.biClrUsed = 1 << src_info->bmiHeader.biBitCount;
1034     }
1035
1036     /* if the src and dst are the same depth, copy the colour info across */
1037     if (dst_info->bmiHeader.biBitCount == src_info->bmiHeader.biBitCount && coloruse == DIB_RGB_COLORS )
1038     {
1039         switch (src_info->bmiHeader.biBitCount)
1040         {
1041         case 16:
1042             if (src_info->bmiHeader.biCompression == BI_RGB)
1043             {
1044                 src_info->bmiHeader.biCompression = BI_BITFIELDS;
1045                 memcpy( src_info->bmiColors, bit_fields_555, sizeof(bit_fields_555) );
1046             }
1047             break;
1048         case 32:
1049             if (src_info->bmiHeader.biCompression == BI_RGB)
1050             {
1051                 src_info->bmiHeader.biCompression = BI_BITFIELDS;
1052                 memcpy( src_info->bmiColors, bit_fields_888, sizeof(bit_fields_888) );
1053             }
1054             break;
1055         }
1056         src_info->bmiHeader.biSizeImage = get_dib_image_size( dst_info );
1057         copy_color_info( dst_info, src_info, coloruse );
1058     }
1059     else if (dst_info->bmiHeader.biBitCount <= 8) /* otherwise construct a default colour table for the dst, if needed */
1060     {
1061         if( coloruse == DIB_PAL_COLORS )
1062         {
1063             if (!fill_color_table_from_palette( dst_info, dc )) goto done;
1064         }
1065         else
1066         {
1067             fill_default_color_table( dst_info );
1068         }
1069     }
1070
1071     if (bits)
1072     {
1073         if(dst_info->bmiHeader.biHeight > 0)
1074             dst_info->bmiHeader.biHeight = src.height;
1075         else
1076             dst_info->bmiHeader.biHeight = -src.height;
1077
1078         convert_bitmapinfo( src_info, src_bits.ptr, &src, dst_info, bits );
1079         if (src_bits.free) src_bits.free( &src_bits );
1080         ret = lines;
1081     }
1082     else
1083         ret = empty_rect ? FALSE : TRUE;
1084
1085     if (coloruse == DIB_PAL_COLORS)
1086     {
1087         WORD *index = (WORD *)dst_info->bmiColors;
1088         int colors = get_dib_num_of_colors( dst_info );
1089         for (i = 0; i < colors; i++, index++)
1090             *index = i;
1091     }
1092
1093     copy_color_info( info, dst_info, coloruse );
1094
1095 done:
1096     release_dc_ptr( dc );
1097     GDI_ReleaseObj( hbitmap );
1098     return ret;
1099 }
1100
1101
1102 /***********************************************************************
1103  *           CreateDIBitmap    (GDI32.@)
1104  *
1105  * Creates a DDB (device dependent bitmap) from a DIB.
1106  * The DDB will have the same color depth as the reference DC.
1107  */
1108 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
1109                             DWORD init, LPCVOID bits, const BITMAPINFO *data,
1110                             UINT coloruse )
1111 {
1112     BITMAPINFOHEADER info;
1113     HBITMAP handle;
1114     LONG height;
1115
1116     if (!bitmapinfoheader_from_user_bitmapinfo( &info, header )) return 0;
1117     if (info.biCompression == BI_JPEG || info.biCompression == BI_PNG) return 0;
1118     if (info.biWidth < 0) return 0;
1119
1120     /* Top-down DIBs have a negative height */
1121     height = abs( info.biHeight );
1122
1123     TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1124           hdc, header, init, bits, data, coloruse, info.biWidth, info.biHeight,
1125           info.biBitCount, info.biCompression);
1126
1127     if (hdc == NULL)
1128         handle = CreateBitmap( info.biWidth, height, 1, 1, NULL );
1129     else
1130         handle = CreateCompatibleBitmap( hdc, info.biWidth, height );
1131
1132     if (handle)
1133     {
1134         if (init & CBM_INIT)
1135         {
1136             if (SetDIBits( hdc, handle, 0, height, bits, data, coloruse ) == 0)
1137             {
1138                 DeleteObject( handle );
1139                 handle = 0;
1140             }
1141         }
1142     }
1143
1144     return handle;
1145 }
1146
1147 /* Copy/synthesize RGB palette from BITMAPINFO */
1148 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1149 {
1150     unsigned int colors, i;
1151
1152     colors = get_dib_num_of_colors( info );
1153     if (!(bmp->color_table = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1154     bmp->nb_colors = colors;
1155
1156     if (coloruse == DIB_RGB_COLORS)
1157     {
1158         memcpy( bmp->color_table, info->bmiColors, colors * sizeof(RGBQUAD));
1159     }
1160     else
1161     {
1162         PALETTEENTRY entries[256];
1163         const WORD *index = (const WORD *)info->bmiColors;
1164         UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1165
1166         for (i = 0; i < colors; i++, index++)
1167         {
1168             PALETTEENTRY *entry = &entries[*index % count];
1169             bmp->color_table[i].rgbRed = entry->peRed;
1170             bmp->color_table[i].rgbGreen = entry->peGreen;
1171             bmp->color_table[i].rgbBlue = entry->peBlue;
1172             bmp->color_table[i].rgbReserved = 0;
1173         }
1174     }
1175 }
1176
1177 /***********************************************************************
1178  *           CreateDIBSection    (GDI32.@)
1179  */
1180 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1181                                 VOID **bits, HANDLE section, DWORD offset)
1182 {
1183     char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1184     BITMAPINFO *info = (BITMAPINFO *)buffer;
1185     HBITMAP ret = 0;
1186     DC *dc;
1187     BOOL bDesktopDC = FALSE;
1188     DIBSECTION *dib;
1189     BITMAPOBJ *bmp;
1190     void *mapBits = NULL;
1191
1192     if (bits) *bits = NULL;
1193     if (!bitmapinfo_from_user_bitmapinfo( info, bmi, usage, FALSE )) return 0;
1194     if (info->bmiHeader.biPlanes != 1)
1195     {
1196         if (info->bmiHeader.biPlanes * info->bmiHeader.biBitCount > 16) return 0;
1197         WARN( "%u planes not properly supported\n", info->bmiHeader.biPlanes );
1198     }
1199
1200     if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1201
1202     TRACE("format (%d,%d), planes %d, bpp %d, %s, size %d %s\n",
1203           info->bmiHeader.biWidth, info->bmiHeader.biHeight,
1204           info->bmiHeader.biPlanes, info->bmiHeader.biBitCount,
1205           info->bmiHeader.biCompression == BI_BITFIELDS? "BI_BITFIELDS" : "BI_RGB",
1206           info->bmiHeader.biSizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1207
1208     dib->dsBm.bmType       = 0;
1209     dib->dsBm.bmWidth      = info->bmiHeader.biWidth;
1210     dib->dsBm.bmHeight     = abs( info->bmiHeader.biHeight );
1211     dib->dsBm.bmWidthBytes = get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
1212     dib->dsBm.bmPlanes     = info->bmiHeader.biPlanes;
1213     dib->dsBm.bmBitsPixel  = info->bmiHeader.biBitCount;
1214     dib->dsBm.bmBits       = NULL;
1215     dib->dsBmih            = info->bmiHeader;
1216
1217     /* set number of entries in bmi.bmiColors table */
1218     if( info->bmiHeader.biBitCount <= 8 )
1219         dib->dsBmih.biClrUsed = 1 << info->bmiHeader.biBitCount;
1220
1221     /* set dsBitfields values */
1222     if (info->bmiHeader.biBitCount == 16 && info->bmiHeader.biCompression == BI_RGB)
1223     {
1224         dib->dsBmih.biCompression = BI_BITFIELDS;
1225         dib->dsBitfields[0] = 0x7c00;
1226         dib->dsBitfields[1] = 0x03e0;
1227         dib->dsBitfields[2] = 0x001f;
1228     }
1229     else if (info->bmiHeader.biCompression == BI_BITFIELDS)
1230     {
1231         dib->dsBitfields[0] =  *(const DWORD *)bmi->bmiColors;
1232         dib->dsBitfields[1] =  *((const DWORD *)bmi->bmiColors + 1);
1233         dib->dsBitfields[2] =  *((const DWORD *)bmi->bmiColors + 2);
1234         if (!dib->dsBitfields[0] || !dib->dsBitfields[1] || !dib->dsBitfields[2]) goto error;
1235     }
1236     else dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1237
1238     /* get storage location for DIB bits */
1239
1240     if (section)
1241     {
1242         SYSTEM_INFO SystemInfo;
1243         DWORD mapOffset;
1244         INT mapSize;
1245
1246         GetSystemInfo( &SystemInfo );
1247         mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1248         mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1249         mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1250         if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1251     }
1252     else
1253     {
1254         offset = 0;
1255         dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1256                                          MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1257     }
1258     dib->dshSection = section;
1259     dib->dsOffset = offset;
1260
1261     if (!dib->dsBm.bmBits)
1262     {
1263         HeapFree( GetProcessHeap(), 0, dib );
1264         return 0;
1265     }
1266
1267     /* If the reference hdc is null, take the desktop dc */
1268     if (hdc == 0)
1269     {
1270         hdc = CreateCompatibleDC(0);
1271         bDesktopDC = TRUE;
1272     }
1273
1274     if (!(dc = get_dc_ptr( hdc ))) goto error;
1275
1276     /* create Device Dependent Bitmap and add DIB pointer */
1277     ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1278                         (info->bmiHeader.biBitCount == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1279
1280     if (ret && ((bmp = GDI_GetObjPtr(ret, OBJ_BITMAP))))
1281     {
1282         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pCreateDIBSection );
1283         bmp->dib = dib;
1284         bmp->funcs = physdev->funcs;
1285         /* create local copy of DIB palette */
1286         if (info->bmiHeader.biBitCount <= 8) DIB_CopyColorTable( dc, bmp, usage, info );
1287         GDI_ReleaseObj( ret );
1288
1289         if (!physdev->funcs->pCreateDIBSection( physdev, ret, info, usage ))
1290         {
1291             DeleteObject( ret );
1292             ret = 0;
1293         }
1294     }
1295
1296     release_dc_ptr( dc );
1297     if (bDesktopDC) DeleteDC( hdc );
1298     if (ret && bits) *bits = dib->dsBm.bmBits;
1299     return ret;
1300
1301 error:
1302     if (bDesktopDC) DeleteDC( hdc );
1303     if (section) UnmapViewOfFile( mapBits );
1304     else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1305     HeapFree( GetProcessHeap(), 0, dib );
1306     return 0;
1307 }