winealsa: Unify the checks for wBitsPerSample.
[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         if (info->bmiHeader.biClrUsed) colors = min( info->bmiHeader.biClrUsed, 256 );
94         else colors = info->bmiHeader.biBitCount > 8 ? 0 : 1 << info->bmiHeader.biBitCount;
95         if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
96         size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
97         return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
98     }
99 }
100
101 /*******************************************************************************************
102  * Verify that the DIB parameters are valid.
103  */
104 static BOOL is_valid_dib_format( const BITMAPINFOHEADER *info, BOOL allow_compression )
105 {
106     if (info->biWidth <= 0) return FALSE;
107     if (info->biHeight == 0) return FALSE;
108
109     if (allow_compression && (info->biCompression == BI_RLE4 || info->biCompression == BI_RLE8))
110     {
111         if (info->biHeight < 0) return FALSE;
112         if (!info->biSizeImage) return FALSE;
113         return info->biBitCount == (info->biCompression == BI_RLE4 ? 4 : 8);
114     }
115
116     if (!info->biPlanes) return FALSE;
117
118     switch (info->biBitCount)
119     {
120     case 1:
121     case 4:
122     case 8:
123     case 24:
124         return (info->biCompression == BI_RGB);
125     case 16:
126     case 32:
127         return (info->biCompression == BI_BITFIELDS || info->biCompression == BI_RGB);
128     default:
129         return FALSE;
130     }
131 }
132
133 /*******************************************************************************************
134  *  Fill out a true BITMAPINFOHEADER from a variable sized BITMAPINFOHEADER / BITMAPCOREHEADER.
135  */
136 static BOOL bitmapinfoheader_from_user_bitmapinfo( BITMAPINFOHEADER *dst, const BITMAPINFOHEADER *info )
137 {
138     if (!info) return FALSE;
139
140     if (info->biSize == sizeof(BITMAPCOREHEADER))
141     {
142         const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
143         dst->biWidth         = core->bcWidth;
144         dst->biHeight        = core->bcHeight;
145         dst->biPlanes        = core->bcPlanes;
146         dst->biBitCount      = core->bcBitCount;
147         dst->biCompression   = BI_RGB;
148         dst->biXPelsPerMeter = 0;
149         dst->biYPelsPerMeter = 0;
150         dst->biClrUsed       = 0;
151         dst->biClrImportant  = 0;
152     }
153     else if (info->biSize >= sizeof(BITMAPINFOHEADER)) /* assume BITMAPINFOHEADER */
154     {
155         *dst = *info;
156     }
157     else
158     {
159         WARN( "(%u): unknown/wrong size for header\n", info->biSize );
160         return FALSE;
161     }
162
163     dst->biSize = sizeof(*dst);
164     if (dst->biCompression == BI_RGB || dst->biCompression == BI_BITFIELDS)
165         dst->biSizeImage = get_dib_image_size( (BITMAPINFO *)dst );
166     return TRUE;
167 }
168
169 /*******************************************************************************************
170  *  Fill out a true BITMAPINFO from a variable sized BITMAPINFO / BITMAPCOREINFO.
171  *
172  * The resulting sanitized BITMAPINFO is guaranteed to have:
173  * - biSize set to sizeof(BITMAPINFOHEADER)
174  * - biSizeImage set to the actual image size even for non-compressed DIB
175  * - biClrUsed set to the size of the color table, and 0 only when there is no color table
176  * - color table present only for <= 8 bpp, always starts at info->bmiColors
177  */
178 static BOOL bitmapinfo_from_user_bitmapinfo( BITMAPINFO *dst, const BITMAPINFO *info,
179                                              UINT coloruse, BOOL allow_compression )
180 {
181     void *src_colors;
182
183     if (coloruse > DIB_PAL_COLORS + 1) return FALSE;  /* FIXME: handle DIB_PAL_COLORS+1 format */
184     if (!bitmapinfoheader_from_user_bitmapinfo( &dst->bmiHeader, &info->bmiHeader )) return FALSE;
185     if (!is_valid_dib_format( &dst->bmiHeader, allow_compression )) return FALSE;
186
187     src_colors = (char *)info + info->bmiHeader.biSize;
188
189     if (dst->bmiHeader.biCompression == BI_BITFIELDS)
190     {
191         /* bitfields are always at bmiColors even in larger structures */
192         memcpy( dst->bmiColors, info->bmiColors, 3 * sizeof(DWORD) );
193         dst->bmiHeader.biClrUsed = 0;
194     }
195     else if (dst->bmiHeader.biBitCount <= 8)
196     {
197         unsigned int colors = dst->bmiHeader.biClrUsed;
198         unsigned int max_colors = 1 << dst->bmiHeader.biBitCount;
199
200         if (!colors) colors = max_colors;
201         else colors = min( colors, max_colors );
202
203         if (coloruse == DIB_PAL_COLORS)
204         {
205             memcpy( dst->bmiColors, src_colors, colors * sizeof(WORD) );
206             max_colors = colors;
207         }
208         else if (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER))
209         {
210             memcpy( dst->bmiColors, src_colors, colors * sizeof(RGBQUAD) );
211         }
212         else
213         {
214             unsigned int i;
215             RGBTRIPLE *triple = (RGBTRIPLE *)src_colors;
216             for (i = 0; i < colors; i++)
217             {
218                 dst->bmiColors[i].rgbRed      = triple[i].rgbtRed;
219                 dst->bmiColors[i].rgbGreen    = triple[i].rgbtGreen;
220                 dst->bmiColors[i].rgbBlue     = triple[i].rgbtBlue;
221                 dst->bmiColors[i].rgbReserved = 0;
222             }
223         }
224         memset( dst->bmiColors + colors, 0, (max_colors - colors) * sizeof(RGBQUAD) );
225         dst->bmiHeader.biClrUsed = max_colors;
226     }
227     else dst->bmiHeader.biClrUsed = 0;
228
229     return TRUE;
230 }
231
232 static int fill_color_table_from_palette( BITMAPINFO *info, HDC hdc )
233 {
234     PALETTEENTRY palEntry[256];
235     HPALETTE palette = GetCurrentObject( hdc, OBJ_PAL );
236     int i, colors = 1 << info->bmiHeader.biBitCount;
237
238     info->bmiHeader.biClrUsed = colors;
239
240     if (!palette) return 0;
241
242     memset( palEntry, 0, sizeof(palEntry) );
243     if (!GetPaletteEntries( palette, 0, colors, palEntry ))
244         return 0;
245
246     for (i = 0; i < colors; i++)
247     {
248         info->bmiColors[i].rgbRed      = palEntry[i].peRed;
249         info->bmiColors[i].rgbGreen    = palEntry[i].peGreen;
250         info->bmiColors[i].rgbBlue     = palEntry[i].peBlue;
251         info->bmiColors[i].rgbReserved = 0;
252     }
253
254     return colors;
255 }
256
257 BOOL fill_color_table_from_pal_colors( BITMAPINFO *info, HDC hdc )
258 {
259     PALETTEENTRY entries[256];
260     RGBQUAD table[256];
261     HPALETTE palette;
262     const WORD *index = (const WORD *)info->bmiColors;
263     int i, count, colors = info->bmiHeader.biClrUsed;
264
265     if (!colors) return TRUE;
266     if (!(palette = GetCurrentObject( hdc, OBJ_PAL ))) return FALSE;
267     if (!(count = GetPaletteEntries( palette, 0, colors, entries ))) return FALSE;
268
269     for (i = 0; i < colors; i++, index++)
270     {
271         table[i].rgbRed   = entries[*index % count].peRed;
272         table[i].rgbGreen = entries[*index % count].peGreen;
273         table[i].rgbBlue  = entries[*index % count].peBlue;
274         table[i].rgbReserved = 0;
275     }
276     info->bmiHeader.biClrUsed = 1 << info->bmiHeader.biBitCount;
277     memcpy( info->bmiColors, table, colors * sizeof(RGBQUAD) );
278     memset( info->bmiColors + colors, 0, (info->bmiHeader.biClrUsed - colors) * sizeof(RGBQUAD) );
279     return TRUE;
280 }
281
282 static void *get_pixel_ptr( const BITMAPINFO *info, void *bits, int x, int y )
283 {
284     const int width = info->bmiHeader.biWidth, height = info->bmiHeader.biHeight;
285     const int bpp = info->bmiHeader.biBitCount;
286
287     if (height > 0)
288         return (char *)bits + (height - y - 1) * get_dib_stride( width, bpp ) + x * bpp / 8;
289     else
290         return (char *)bits + y * get_dib_stride( width, bpp ) + x * bpp / 8;
291 }
292
293 static BOOL build_rle_bitmap( const BITMAPINFO *info, struct gdi_image_bits *bits, HRGN *clip )
294 {
295     int i = 0;
296     int left, right;
297     int x, y, width = info->bmiHeader.biWidth, height = info->bmiHeader.biHeight;
298     HRGN run = NULL;
299     BYTE skip, num, data;
300     BYTE *out_bits, *in_bits = bits->ptr;
301
302     if (clip) *clip = NULL;
303
304     assert( info->bmiHeader.biBitCount == 4 || info->bmiHeader.biBitCount == 8 );
305
306     out_bits = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, get_dib_image_size( info ) );
307     if (!out_bits) goto fail;
308
309     if (clip)
310     {
311         *clip = CreateRectRgn( 0, 0, 0, 0 );
312         run   = CreateRectRgn( 0, 0, 0, 0 );
313         if (!*clip || !run) goto fail;
314     }
315
316     x = left = right = 0;
317     y = height - 1;
318
319     while (i < info->bmiHeader.biSizeImage - 1)
320     {
321         num = in_bits[i];
322         data = in_bits[i + 1];
323         i += 2;
324
325         if (num)
326         {
327             if (x + num > width) num = width - x;
328             if (num)
329             {
330                 BYTE s = data, *out_ptr = get_pixel_ptr( info, out_bits, x, y );
331                 if (info->bmiHeader.biBitCount == 8)
332                     memset( out_ptr, s, num );
333                 else
334                 {
335                     if(x & 1)
336                     {
337                         s = ((s >> 4) & 0x0f) | ((s << 4) & 0xf0);
338                         *out_ptr = (*out_ptr & 0xf0) | (s & 0x0f);
339                         out_ptr++;
340                         x++;
341                         num--;
342                     }
343                     /* this will write one too many if num is odd, but that doesn't matter */
344                     if (num) memset( out_ptr, s, (num + 1) / 2 );
345                 }
346             }
347             x += num;
348             right = x;
349         }
350         else
351         {
352             if (data < 3)
353             {
354                 if(left != right && clip)
355                 {
356                     SetRectRgn( run, left, y, right, y + 1 );
357                     CombineRgn( *clip, run, *clip, RGN_OR );
358                 }
359                 switch (data)
360                 {
361                 case 0: /* eol */
362                     left = right = x = 0;
363                     y--;
364                     if(y < 0) goto done;
365                     break;
366
367                 case 1: /* eod */
368                     goto done;
369
370                 case 2: /* delta */
371                     if (i >= info->bmiHeader.biSizeImage - 1) goto done;
372                     x += in_bits[i];
373                     if (x > width) x = width;
374                     left = right = x;
375                     y -= in_bits[i + 1];
376                     if(y < 0) goto done;
377                     i += 2;
378                 }
379             }
380             else /* data bytes of data */
381             {
382                 num = data;
383                 skip = (num * info->bmiHeader.biBitCount + 7) / 8;
384                 if (skip > info->bmiHeader.biSizeImage - i) goto done;
385                 skip = (skip + 1) & ~1;
386                 if (x + num > width) num = width - x;
387                 if (num)
388                 {
389                     BYTE *out_ptr = get_pixel_ptr( info, out_bits, x, y );
390                     if (info->bmiHeader.biBitCount == 8)
391                         memcpy( out_ptr, in_bits + i, num );
392                     else
393                     {
394                         if(x & 1)
395                         {
396                             const BYTE *in_ptr = in_bits + i;
397                             for ( ; num; num--, x++)
398                             {
399                                 if (x & 1)
400                                 {
401                                     *out_ptr = (*out_ptr & 0xf0) | ((*in_ptr >> 4) & 0x0f);
402                                     out_ptr++;
403                                 }
404                                 else
405                                     *out_ptr = (*in_ptr++ << 4) & 0xf0;
406                             }
407                         }
408                         else
409                             memcpy( out_ptr, in_bits + i, (num + 1) / 2);
410                     }
411                 }
412                 x += num;
413                 right = x;
414                 i += skip;
415             }
416         }
417     }
418
419 done:
420     if (run) DeleteObject( run );
421     if (bits->free) bits->free( bits );
422
423     bits->ptr     = out_bits;
424     bits->is_copy = TRUE;
425     bits->free    = free_heap_bits;
426
427     return TRUE;
428
429 fail:
430     if (run) DeleteObject( run );
431     if (clip && *clip) DeleteObject( *clip );
432     HeapFree( GetProcessHeap(), 0, out_bits );
433     return FALSE;
434 }
435
436
437
438 INT nulldrv_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT heightDst,
439                            INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits,
440                            BITMAPINFO *src_info, UINT coloruse, DWORD rop )
441 {
442     DC *dc = get_nulldrv_dc( dev );
443     char dst_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
444     BITMAPINFO *dst_info = (BITMAPINFO *)dst_buffer;
445     struct bitblt_coords src, dst;
446     struct gdi_image_bits src_bits;
447     DWORD err;
448     HRGN clip = NULL;
449     INT ret = 0;
450     INT height = abs( src_info->bmiHeader.biHeight );
451     BOOL top_down = src_info->bmiHeader.biHeight < 0, non_stretch_from_origin = FALSE;
452     RECT rect;
453
454     TRACE("%d %d %d %d <- %d %d %d %d rop %08x\n", xDst, yDst, widthDst, heightDst,
455           xSrc, ySrc, widthSrc, heightSrc, rop);
456
457     src_bits.ptr = (void*)bits;
458     src_bits.is_copy = FALSE;
459     src_bits.free = NULL;
460
461     if (coloruse == DIB_PAL_COLORS && !fill_color_table_from_pal_colors( src_info, dev->hdc )) return 0;
462
463     rect.left   = xDst;
464     rect.top    = yDst;
465     rect.right  = xDst + widthDst;
466     rect.bottom = yDst + heightDst;
467     LPtoDP( dc->hSelf, (POINT *)&rect, 2 );
468     dst.x      = rect.left;
469     dst.y      = rect.top;
470     dst.width  = rect.right - rect.left;
471     dst.height = rect.bottom - rect.top;
472
473     if (dc->layout & LAYOUT_RTL && rop & NOMIRRORBITMAP)
474     {
475         dst.x += dst.width;
476         dst.width = -dst.width;
477     }
478     rop &= ~NOMIRRORBITMAP;
479
480     src.x      = xSrc;
481     src.width  = widthSrc;
482     src.y      = ySrc;
483     src.height = heightSrc;
484
485     if (src.x == 0 && src.y == 0 && src.width == dst.width && src.height == dst.height)
486         non_stretch_from_origin = TRUE;
487
488     if (src_info->bmiHeader.biCompression == BI_RLE4 || src_info->bmiHeader.biCompression == BI_RLE8)
489     {
490         BOOL want_clip = non_stretch_from_origin && (rop == SRCCOPY);
491         if (!build_rle_bitmap( src_info, &src_bits, want_clip ? &clip : NULL )) return 0;
492     }
493
494     if (rop != SRCCOPY || non_stretch_from_origin)
495     {
496         if (dst.width == 1 && src.width > 1) src.width--;
497         if (dst.height == 1 && src.height > 1) src.height--;
498     }
499
500     if (rop != SRCCOPY)
501     {
502         if (dst.width < 0 && dst.width == src.width)
503         {
504             /* This is off-by-one, but that's what Windows does */
505             dst.x += dst.width;
506             src.x += src.width;
507             dst.width = -dst.width;
508             src.width = -src.width;
509         }
510         if (dst.height < 0 && dst.height == src.height)
511         {
512             dst.y += dst.height;
513             src.y += src.height;
514             dst.height = -dst.height;
515             src.height = -src.height;
516         }
517     }
518
519     if (!top_down || (rop == SRCCOPY && !non_stretch_from_origin)) src.y = height - src.y - src.height;
520
521     if (src.y >= height && src.y + src.height + 1 < height)
522         src.y = height - 1;
523     else if (src.y > 0 && src.y + src.height + 1 < 0)
524         src.y = -src.height - 1;
525
526     get_bounding_rect( &rect, src.x, src.y, src.width, src.height );
527
528     src.visrect.left   = 0;
529     src.visrect.right  = src_info->bmiHeader.biWidth;
530     src.visrect.top    = 0;
531     src.visrect.bottom = height;
532     if (!intersect_rect( &src.visrect, &src.visrect, &rect )) goto done;
533
534     get_bounding_rect( &rect, dst.x, dst.y, dst.width, dst.height );
535
536     if (!clip_visrect( dc, &dst.visrect, &rect )) goto done;
537
538     if (!intersect_vis_rectangles( &dst, &src )) goto done;
539
540     if (clip) OffsetRgn( clip, dst.x - src.x, dst.y - src.y );
541
542     dev = GET_DC_PHYSDEV( dc, pPutImage );
543     copy_bitmapinfo( dst_info, src_info );
544     err = dev->funcs->pPutImage( dev, 0, clip, dst_info, &src_bits, &src, &dst, rop );
545     if (err == ERROR_BAD_FORMAT)
546     {
547         /* 1-bpp destination without a color table requires a fake 1-entry table
548          * that contains only the background color */
549         if (dst_info->bmiHeader.biBitCount == 1 && !dst_info->bmiHeader.biClrUsed)
550         {
551             COLORREF color = GetBkColor( dev->hdc );
552             dst_info->bmiColors[0].rgbRed      = GetRValue( color );
553             dst_info->bmiColors[0].rgbGreen    = GetGValue( color );
554             dst_info->bmiColors[0].rgbBlue     = GetBValue( color );
555             dst_info->bmiColors[0].rgbReserved = 0;
556             dst_info->bmiHeader.biClrUsed = 1;
557         }
558
559         if (!(err = convert_bits( src_info, &src, dst_info, &src_bits, FALSE )))
560         {
561             /* get rid of the fake 1-bpp table */
562             if (dst_info->bmiHeader.biClrUsed == 1) dst_info->bmiHeader.biClrUsed = 0;
563             err = dev->funcs->pPutImage( dev, 0, clip, dst_info, &src_bits, &src, &dst, rop );
564         }
565     }
566
567     if (err == ERROR_TRANSFORM_NOT_SUPPORTED)
568     {
569         copy_bitmapinfo( src_info, dst_info );
570         err = stretch_bits( src_info, &src, dst_info, &dst, &src_bits, GetStretchBltMode( dev->hdc ) );
571         if (!err) err = dev->funcs->pPutImage( dev, 0, NULL, dst_info, &src_bits, &src, &dst, rop );
572     }
573     if (err) ret = 0;
574     else if (rop == SRCCOPY) ret = height;
575     else ret = src_info->bmiHeader.biHeight;
576
577 done:
578     if (src_bits.free) src_bits.free( &src_bits );
579     if (clip) DeleteObject( clip );
580     return ret;
581 }
582
583 /***********************************************************************
584  *           StretchDIBits   (GDI32.@)
585  */
586 INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst, INT heightDst,
587                          INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits,
588                          const BITMAPINFO *bmi, UINT coloruse, DWORD rop )
589 {
590     char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
591     BITMAPINFO *info = (BITMAPINFO *)buffer;
592     DC *dc;
593     INT ret = 0;
594
595     if (!bits) return 0;
596     if (!bitmapinfo_from_user_bitmapinfo( info, bmi, coloruse, TRUE ))
597     {
598         SetLastError( ERROR_INVALID_PARAMETER );
599         return 0;
600     }
601
602     if ((dc = get_dc_ptr( hdc )))
603     {
604         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pStretchDIBits );
605         update_dc( dc );
606         ret = physdev->funcs->pStretchDIBits( physdev, xDst, yDst, widthDst, heightDst,
607                                               xSrc, ySrc, widthSrc, heightSrc, bits, info, coloruse, rop );
608         release_dc_ptr( dc );
609     }
610     return ret;
611 }
612
613
614 /******************************************************************************
615  * SetDIBits [GDI32.@]
616  *
617  * Sets pixels in a bitmap using colors from DIB.
618  *
619  * PARAMS
620  *    hdc       [I] Handle to device context
621  *    hbitmap   [I] Handle to bitmap
622  *    startscan [I] Starting scan line
623  *    lines     [I] Number of scan lines
624  *    bits      [I] Array of bitmap bits
625  *    info      [I] Address of structure with data
626  *    coloruse  [I] Type of color indexes to use
627  *
628  * RETURNS
629  *    Success: Number of scan lines copied
630  *    Failure: 0
631  */
632 INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
633                       UINT lines, LPCVOID bits, const BITMAPINFO *info,
634                       UINT coloruse )
635 {
636     BITMAPOBJ *bitmap;
637     char src_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
638     BITMAPINFO *src_info = (BITMAPINFO *)src_bmibuf;
639     char dst_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
640     BITMAPINFO *dst_info = (BITMAPINFO *)dst_bmibuf;
641     INT result = 0;
642     DWORD err;
643     struct gdi_image_bits src_bits;
644     struct bitblt_coords src, dst;
645     INT src_to_dst_offset;
646     HRGN clip = 0;
647     const struct gdi_dc_funcs *funcs;
648
649     if (!bitmapinfo_from_user_bitmapinfo( src_info, info, coloruse, TRUE ) || coloruse > DIB_PAL_COLORS)
650     {
651         SetLastError( ERROR_INVALID_PARAMETER );
652         return 0;
653     }
654     if (src_info->bmiHeader.biCompression == BI_BITFIELDS)
655     {
656         DWORD *masks = (DWORD *)src_info->bmiColors;
657         if (!masks[0] || !masks[1] || !masks[2])
658         {
659             SetLastError( ERROR_INVALID_PARAMETER );
660             return 0;
661         }
662     }
663
664     src_bits.ptr = (void *)bits;
665     src_bits.is_copy = FALSE;
666     src_bits.free = NULL;
667     src_bits.param = NULL;
668
669     if (coloruse == DIB_PAL_COLORS && !fill_color_table_from_pal_colors( src_info, hdc )) return 0;
670
671     if (!(bitmap = GDI_GetObjPtr( hbitmap, OBJ_BITMAP ))) return 0;
672
673     if (src_info->bmiHeader.biCompression == BI_RLE4 || src_info->bmiHeader.biCompression == BI_RLE8)
674     {
675         if (lines == 0) goto done;
676         else lines = src_info->bmiHeader.biHeight;
677         startscan = 0;
678
679         if (!build_rle_bitmap( src_info, &src_bits, &clip )) goto done;
680     }
681
682     dst.visrect.left   = 0;
683     dst.visrect.top    = 0;
684     dst.visrect.right  = bitmap->bitmap.bmWidth;
685     dst.visrect.bottom = bitmap->bitmap.bmHeight;
686
687     src.visrect.left   = 0;
688     src.visrect.top    = 0;
689     src.visrect.right  = src_info->bmiHeader.biWidth;
690     src.visrect.bottom = abs( src_info->bmiHeader.biHeight );
691
692     if (src_info->bmiHeader.biHeight > 0)
693     {
694         src_to_dst_offset = -startscan;
695         lines = min( lines, src.visrect.bottom - startscan );
696         if (lines < src.visrect.bottom) src.visrect.top = src.visrect.bottom - lines;
697     }
698     else
699     {
700         src_to_dst_offset = src.visrect.bottom - lines - startscan;
701         /* Unlike the bottom-up case, Windows doesn't limit lines. */
702         if (lines < src.visrect.bottom) src.visrect.bottom = lines;
703     }
704
705     funcs = get_bitmap_funcs( bitmap );
706
707     result = lines;
708
709     offset_rect( &src.visrect, 0, src_to_dst_offset );
710     if (!intersect_rect( &dst.visrect, &src.visrect, &dst.visrect )) goto done;
711     src.visrect = dst.visrect;
712     offset_rect( &src.visrect, 0, -src_to_dst_offset );
713
714     src.x      = src.visrect.left;
715     src.y      = src.visrect.top;
716     src.width  = src.visrect.right - src.visrect.left;
717     src.height = src.visrect.bottom - src.visrect.top;
718
719     dst.x      = dst.visrect.left;
720     dst.y      = dst.visrect.top;
721     dst.width  = dst.visrect.right - dst.visrect.left;
722     dst.height = dst.visrect.bottom - dst.visrect.top;
723
724     copy_bitmapinfo( dst_info, src_info );
725
726     err = funcs->pPutImage( NULL, hbitmap, clip, dst_info, &src_bits, &src, &dst, 0 );
727     if (err == ERROR_BAD_FORMAT)
728     {
729         err = convert_bits( src_info, &src, dst_info, &src_bits, FALSE );
730         if (!err) err = funcs->pPutImage( NULL, hbitmap, clip, dst_info, &src_bits, &src, &dst, 0 );
731     }
732     if(err) result = 0;
733
734 done:
735     if (src_bits.free) src_bits.free( &src_bits );
736     if (clip) DeleteObject( clip );
737     GDI_ReleaseObj( hbitmap );
738     return result;
739 }
740
741
742 INT nulldrv_SetDIBitsToDevice( PHYSDEV dev, INT x_dst, INT y_dst, DWORD cx, DWORD cy,
743                                INT x_src, INT y_src, UINT startscan, UINT lines,
744                                const void *bits, BITMAPINFO *src_info, UINT coloruse )
745 {
746     DC *dc = get_nulldrv_dc( dev );
747     char dst_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
748     BITMAPINFO *dst_info = (BITMAPINFO *)dst_buffer;
749     struct bitblt_coords src, dst;
750     struct gdi_image_bits src_bits;
751     HRGN clip = 0;
752     DWORD err;
753     UINT height;
754     BOOL top_down;
755     POINT pt;
756     RECT rect;
757
758     top_down = (src_info->bmiHeader.biHeight < 0);
759     height = abs( src_info->bmiHeader.biHeight );
760
761     src_bits.ptr = (void *)bits;
762     src_bits.is_copy = FALSE;
763     src_bits.free = NULL;
764
765     if (!lines) return 0;
766     if (coloruse == DIB_PAL_COLORS && !fill_color_table_from_pal_colors( src_info, dev->hdc )) return 0;
767
768     if (src_info->bmiHeader.biCompression == BI_RLE4 || src_info->bmiHeader.biCompression == BI_RLE8)
769     {
770         startscan = 0;
771         lines = height;
772         src_info->bmiHeader.biWidth = x_src + cx;
773         src_info->bmiHeader.biHeight = y_src + cy;
774         if (src_info->bmiHeader.biWidth <= 0 || src_info->bmiHeader.biHeight <= 0) return 0;
775         src.x = x_src;
776         src.y = 0;
777         src.width = cx;
778         src.height = cy;
779         if (!build_rle_bitmap( src_info, &src_bits, &clip )) return 0;
780     }
781     else
782     {
783         if (startscan >= height) return 0;
784         if (!top_down && lines > height - startscan) lines = height - startscan;
785
786         /* map src to top-down coordinates with startscan as origin */
787         src.x = x_src;
788         src.y = startscan + lines - (y_src + cy);
789         src.width = cx;
790         src.height = cy;
791         if (src.y > 0)
792         {
793             if (!top_down)
794             {
795                 /* get rid of unnecessary lines */
796                 if (src.y >= lines) return 0;
797                 lines -= src.y;
798                 src.y = 0;
799             }
800             else if (src.y >= lines) return lines;
801         }
802         src_info->bmiHeader.biHeight = top_down ? -lines : lines;
803     }
804
805     src.visrect.left = src.x;
806     src.visrect.top = src.y;
807     src.visrect.right = src.x + cx;
808     src.visrect.bottom = src.y + cy;
809     rect.left = 0;
810     rect.top = 0;
811     rect.right = src_info->bmiHeader.biWidth;
812     rect.bottom = abs( src_info->bmiHeader.biHeight );
813     if (!intersect_rect( &src.visrect, &src.visrect, &rect ))
814     {
815         lines = 0;
816         goto done;
817     }
818
819     pt.x = x_dst;
820     pt.y = y_dst;
821     LPtoDP( dev->hdc, &pt, 1 );
822     dst.x = pt.x;
823     dst.y = pt.y;
824     dst.width = cx;
825     dst.height = cy;
826     if (GetLayout( dev->hdc ) & LAYOUT_RTL) dst.x -= cx - 1;
827
828     rect.left = dst.x;
829     rect.top = dst.y;
830     rect.right = dst.x + cx;
831     rect.bottom = dst.y + cy;
832     if (!clip_visrect( dc, &dst.visrect, &rect )) goto done;
833
834     offset_rect( &src.visrect, dst.x - src.x, dst.y - src.y );
835     intersect_rect( &rect, &src.visrect, &dst.visrect );
836     src.visrect = dst.visrect = rect;
837     offset_rect( &src.visrect, src.x - dst.x, src.y - dst.y );
838     if (is_rect_empty( &dst.visrect )) goto done;
839     if (clip) OffsetRgn( clip, dst.x - src.x, dst.y - src.y );
840
841     dev = GET_DC_PHYSDEV( dc, pPutImage );
842     copy_bitmapinfo( dst_info, src_info );
843     err = dev->funcs->pPutImage( dev, 0, clip, dst_info, &src_bits, &src, &dst, SRCCOPY );
844     if (err == ERROR_BAD_FORMAT)
845     {
846         err = convert_bits( src_info, &src, dst_info, &src_bits, FALSE );
847         if (!err) err = dev->funcs->pPutImage( dev, 0, clip, dst_info, &src_bits, &src, &dst, SRCCOPY );
848     }
849     if (err) lines = 0;
850
851 done:
852     if (src_bits.free) src_bits.free( &src_bits );
853     if (clip) DeleteObject( clip );
854     return lines;
855 }
856
857 /***********************************************************************
858  *           SetDIBitsToDevice   (GDI32.@)
859  */
860 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
861                            DWORD cy, INT xSrc, INT ySrc, UINT startscan,
862                            UINT lines, LPCVOID bits, const BITMAPINFO *bmi,
863                            UINT coloruse )
864 {
865     char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
866     BITMAPINFO *info = (BITMAPINFO *)buffer;
867     INT ret = 0;
868     DC *dc;
869
870     if (!bits) return 0;
871     if (!bitmapinfo_from_user_bitmapinfo( info, bmi, coloruse, TRUE ))
872     {
873         SetLastError( ERROR_INVALID_PARAMETER );
874         return 0;
875     }
876
877     if ((dc = get_dc_ptr( hdc )))
878     {
879         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDIBitsToDevice );
880         update_dc( dc );
881         ret = physdev->funcs->pSetDIBitsToDevice( physdev, xDest, yDest, cx, cy, xSrc,
882                                                   ySrc, startscan, lines, bits, info, coloruse );
883         release_dc_ptr( dc );
884     }
885     return ret;
886 }
887
888 /***********************************************************************
889  *           SetDIBColorTable    (GDI32.@)
890  */
891 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUAD *colors )
892 {
893     DC * dc;
894     UINT result = 0;
895     BITMAPOBJ * bitmap;
896
897     if (!(dc = get_dc_ptr( hdc ))) return 0;
898
899     if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
900     {
901         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDIBColorTable );
902
903         /* Check if currently selected bitmap is a DIB */
904         if (bitmap->color_table)
905         {
906             if (startpos < bitmap->dib->dsBmih.biClrUsed)
907             {
908                 result = min( entries, bitmap->dib->dsBmih.biClrUsed - startpos );
909                 memcpy(bitmap->color_table + startpos, colors, result * sizeof(RGBQUAD));
910             }
911         }
912         GDI_ReleaseObj( dc->hBitmap );
913         physdev->funcs->pSetDIBColorTable( physdev, startpos, entries, colors );
914     }
915     release_dc_ptr( dc );
916     return result;
917 }
918
919
920 /***********************************************************************
921  *           GetDIBColorTable    (GDI32.@)
922  */
923 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
924 {
925     DC * dc;
926     BITMAPOBJ *bitmap;
927     UINT result = 0;
928
929     if (!(dc = get_dc_ptr( hdc ))) return 0;
930
931     if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
932     {
933         /* Check if currently selected bitmap is a DIB */
934         if (bitmap->color_table)
935         {
936             if (startpos < bitmap->dib->dsBmih.biClrUsed)
937             {
938                 result = min( entries, bitmap->dib->dsBmih.biClrUsed - startpos );
939                 memcpy(colors, bitmap->color_table + startpos, result * sizeof(RGBQUAD));
940             }
941         }
942         GDI_ReleaseObj( dc->hBitmap );
943     }
944     release_dc_ptr( dc );
945     return result;
946 }
947
948 static const DWORD bit_fields_888[3] = {0xff0000, 0x00ff00, 0x0000ff};
949 static const DWORD bit_fields_565[3] = {0xf800, 0x07e0, 0x001f};
950 static const DWORD bit_fields_555[3] = {0x7c00, 0x03e0, 0x001f};
951
952 static int fill_query_info( BITMAPINFO *info, BITMAPOBJ *bmp )
953 {
954     BITMAPINFOHEADER header;
955
956     header.biSize   = info->bmiHeader.biSize; /* Ensure we don't overwrite the original size when we copy back */
957     header.biWidth  = bmp->bitmap.bmWidth;
958     header.biHeight = bmp->bitmap.bmHeight;
959     header.biPlanes = 1;
960
961     if (bmp->dib)
962     {
963         header.biBitCount = bmp->dib->dsBm.bmBitsPixel;
964         switch (bmp->dib->dsBm.bmBitsPixel)
965         {
966         case 16:
967         case 32:
968             header.biCompression = BI_BITFIELDS;
969             break;
970         default:
971             header.biCompression = BI_RGB;
972             break;
973         }
974     }
975     else
976     {
977         header.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB;
978         header.biBitCount = bmp->bitmap.bmBitsPixel;
979     }
980
981     header.biSizeImage = get_dib_image_size( (BITMAPINFO *)&header );
982     header.biXPelsPerMeter = 0;
983     header.biYPelsPerMeter = 0;
984     header.biClrUsed       = 0;
985     header.biClrImportant  = 0;
986
987     if ( info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER) )
988     {
989         BITMAPCOREHEADER *coreheader = (BITMAPCOREHEADER *)info;
990
991         coreheader->bcWidth    = header.biWidth;
992         coreheader->bcHeight   = header.biHeight;
993         coreheader->bcPlanes   = header.biPlanes;
994         coreheader->bcBitCount = header.biBitCount;
995     }
996     else
997         info->bmiHeader = header;
998
999     return abs(bmp->bitmap.bmHeight);
1000 }
1001
1002 /************************************************************************
1003  *      copy_color_info
1004  *
1005  * Copy BITMAPINFO color information where dst may be a BITMAPCOREINFO.
1006  */
1007 static void copy_color_info(BITMAPINFO *dst, const BITMAPINFO *src, UINT coloruse)
1008 {
1009     assert( src->bmiHeader.biSize == sizeof(BITMAPINFOHEADER) );
1010
1011     if (dst->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
1012     {
1013         BITMAPCOREINFO *core = (BITMAPCOREINFO *)dst;
1014         if (coloruse == DIB_PAL_COLORS)
1015             memcpy( core->bmciColors, src->bmiColors, src->bmiHeader.biClrUsed * sizeof(WORD) );
1016         else
1017         {
1018             unsigned int i;
1019             for (i = 0; i < src->bmiHeader.biClrUsed; i++)
1020             {
1021                 core->bmciColors[i].rgbtRed   = src->bmiColors[i].rgbRed;
1022                 core->bmciColors[i].rgbtGreen = src->bmiColors[i].rgbGreen;
1023                 core->bmciColors[i].rgbtBlue  = src->bmiColors[i].rgbBlue;
1024             }
1025         }
1026     }
1027     else
1028     {
1029         dst->bmiHeader.biClrUsed   = src->bmiHeader.biClrUsed;
1030         dst->bmiHeader.biSizeImage = src->bmiHeader.biSizeImage;
1031
1032         if (src->bmiHeader.biCompression == BI_BITFIELDS)
1033             /* bitfields are always at bmiColors even in larger structures */
1034             memcpy( dst->bmiColors, src->bmiColors, 3 * sizeof(DWORD) );
1035         else if (src->bmiHeader.biClrUsed)
1036         {
1037             void *colorptr = (char *)dst + dst->bmiHeader.biSize;
1038             unsigned int size;
1039
1040             if (coloruse == DIB_PAL_COLORS)
1041                 size = src->bmiHeader.biClrUsed * sizeof(WORD);
1042             else
1043                 size = src->bmiHeader.biClrUsed * sizeof(RGBQUAD);
1044             memcpy( colorptr, src->bmiColors, size );
1045         }
1046     }
1047 }
1048
1049 const RGBQUAD *get_default_color_table( int bpp )
1050 {
1051     static const RGBQUAD table_1[2] =
1052     {
1053         { 0x00, 0x00, 0x00 }, { 0xff, 0xff, 0xff }
1054     };
1055     static const RGBQUAD table_4[16] =
1056     {
1057         { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x80 }, { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x80 },
1058         { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x80 }, { 0x80, 0x80, 0x00 }, { 0x80, 0x80, 0x80 },
1059         { 0xc0, 0xc0, 0xc0 }, { 0x00, 0x00, 0xff }, { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0xff },
1060         { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0xff }, { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0xff },
1061     };
1062     static const RGBQUAD table_8[256] =
1063     {
1064         /* first and last 10 entries are the default system palette entries */
1065         { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x80 }, { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x80 },
1066         { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x80 }, { 0x80, 0x80, 0x00 }, { 0xc0, 0xc0, 0xc0 },
1067         { 0xc0, 0xdc, 0xc0 }, { 0xf0, 0xca, 0xa6 }, { 0x00, 0x20, 0x40 }, { 0x00, 0x20, 0x60 },
1068         { 0x00, 0x20, 0x80 }, { 0x00, 0x20, 0xa0 }, { 0x00, 0x20, 0xc0 }, { 0x00, 0x20, 0xe0 },
1069         { 0x00, 0x40, 0x00 }, { 0x00, 0x40, 0x20 }, { 0x00, 0x40, 0x40 }, { 0x00, 0x40, 0x60 },
1070         { 0x00, 0x40, 0x80 }, { 0x00, 0x40, 0xa0 }, { 0x00, 0x40, 0xc0 }, { 0x00, 0x40, 0xe0 },
1071         { 0x00, 0x60, 0x00 }, { 0x00, 0x60, 0x20 }, { 0x00, 0x60, 0x40 }, { 0x00, 0x60, 0x60 },
1072         { 0x00, 0x60, 0x80 }, { 0x00, 0x60, 0xa0 }, { 0x00, 0x60, 0xc0 }, { 0x00, 0x60, 0xe0 },
1073         { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x20 }, { 0x00, 0x80, 0x40 }, { 0x00, 0x80, 0x60 },
1074         { 0x00, 0x80, 0x80 }, { 0x00, 0x80, 0xa0 }, { 0x00, 0x80, 0xc0 }, { 0x00, 0x80, 0xe0 },
1075         { 0x00, 0xa0, 0x00 }, { 0x00, 0xa0, 0x20 }, { 0x00, 0xa0, 0x40 }, { 0x00, 0xa0, 0x60 },
1076         { 0x00, 0xa0, 0x80 }, { 0x00, 0xa0, 0xa0 }, { 0x00, 0xa0, 0xc0 }, { 0x00, 0xa0, 0xe0 },
1077         { 0x00, 0xc0, 0x00 }, { 0x00, 0xc0, 0x20 }, { 0x00, 0xc0, 0x40 }, { 0x00, 0xc0, 0x60 },
1078         { 0x00, 0xc0, 0x80 }, { 0x00, 0xc0, 0xa0 }, { 0x00, 0xc0, 0xc0 }, { 0x00, 0xc0, 0xe0 },
1079         { 0x00, 0xe0, 0x00 }, { 0x00, 0xe0, 0x20 }, { 0x00, 0xe0, 0x40 }, { 0x00, 0xe0, 0x60 },
1080         { 0x00, 0xe0, 0x80 }, { 0x00, 0xe0, 0xa0 }, { 0x00, 0xe0, 0xc0 }, { 0x00, 0xe0, 0xe0 },
1081         { 0x40, 0x00, 0x00 }, { 0x40, 0x00, 0x20 }, { 0x40, 0x00, 0x40 }, { 0x40, 0x00, 0x60 },
1082         { 0x40, 0x00, 0x80 }, { 0x40, 0x00, 0xa0 }, { 0x40, 0x00, 0xc0 }, { 0x40, 0x00, 0xe0 },
1083         { 0x40, 0x20, 0x00 }, { 0x40, 0x20, 0x20 }, { 0x40, 0x20, 0x40 }, { 0x40, 0x20, 0x60 },
1084         { 0x40, 0x20, 0x80 }, { 0x40, 0x20, 0xa0 }, { 0x40, 0x20, 0xc0 }, { 0x40, 0x20, 0xe0 },
1085         { 0x40, 0x40, 0x00 }, { 0x40, 0x40, 0x20 }, { 0x40, 0x40, 0x40 }, { 0x40, 0x40, 0x60 },
1086         { 0x40, 0x40, 0x80 }, { 0x40, 0x40, 0xa0 }, { 0x40, 0x40, 0xc0 }, { 0x40, 0x40, 0xe0 },
1087         { 0x40, 0x60, 0x00 }, { 0x40, 0x60, 0x20 }, { 0x40, 0x60, 0x40 }, { 0x40, 0x60, 0x60 },
1088         { 0x40, 0x60, 0x80 }, { 0x40, 0x60, 0xa0 }, { 0x40, 0x60, 0xc0 }, { 0x40, 0x60, 0xe0 },
1089         { 0x40, 0x80, 0x00 }, { 0x40, 0x80, 0x20 }, { 0x40, 0x80, 0x40 }, { 0x40, 0x80, 0x60 },
1090         { 0x40, 0x80, 0x80 }, { 0x40, 0x80, 0xa0 }, { 0x40, 0x80, 0xc0 }, { 0x40, 0x80, 0xe0 },
1091         { 0x40, 0xa0, 0x00 }, { 0x40, 0xa0, 0x20 }, { 0x40, 0xa0, 0x40 }, { 0x40, 0xa0, 0x60 },
1092         { 0x40, 0xa0, 0x80 }, { 0x40, 0xa0, 0xa0 }, { 0x40, 0xa0, 0xc0 }, { 0x40, 0xa0, 0xe0 },
1093         { 0x40, 0xc0, 0x00 }, { 0x40, 0xc0, 0x20 }, { 0x40, 0xc0, 0x40 }, { 0x40, 0xc0, 0x60 },
1094         { 0x40, 0xc0, 0x80 }, { 0x40, 0xc0, 0xa0 }, { 0x40, 0xc0, 0xc0 }, { 0x40, 0xc0, 0xe0 },
1095         { 0x40, 0xe0, 0x00 }, { 0x40, 0xe0, 0x20 }, { 0x40, 0xe0, 0x40 }, { 0x40, 0xe0, 0x60 },
1096         { 0x40, 0xe0, 0x80 }, { 0x40, 0xe0, 0xa0 }, { 0x40, 0xe0, 0xc0 }, { 0x40, 0xe0, 0xe0 },
1097         { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x20 }, { 0x80, 0x00, 0x40 }, { 0x80, 0x00, 0x60 },
1098         { 0x80, 0x00, 0x80 }, { 0x80, 0x00, 0xa0 }, { 0x80, 0x00, 0xc0 }, { 0x80, 0x00, 0xe0 },
1099         { 0x80, 0x20, 0x00 }, { 0x80, 0x20, 0x20 }, { 0x80, 0x20, 0x40 }, { 0x80, 0x20, 0x60 },
1100         { 0x80, 0x20, 0x80 }, { 0x80, 0x20, 0xa0 }, { 0x80, 0x20, 0xc0 }, { 0x80, 0x20, 0xe0 },
1101         { 0x80, 0x40, 0x00 }, { 0x80, 0x40, 0x20 }, { 0x80, 0x40, 0x40 }, { 0x80, 0x40, 0x60 },
1102         { 0x80, 0x40, 0x80 }, { 0x80, 0x40, 0xa0 }, { 0x80, 0x40, 0xc0 }, { 0x80, 0x40, 0xe0 },
1103         { 0x80, 0x60, 0x00 }, { 0x80, 0x60, 0x20 }, { 0x80, 0x60, 0x40 }, { 0x80, 0x60, 0x60 },
1104         { 0x80, 0x60, 0x80 }, { 0x80, 0x60, 0xa0 }, { 0x80, 0x60, 0xc0 }, { 0x80, 0x60, 0xe0 },
1105         { 0x80, 0x80, 0x00 }, { 0x80, 0x80, 0x20 }, { 0x80, 0x80, 0x40 }, { 0x80, 0x80, 0x60 },
1106         { 0x80, 0x80, 0x80 }, { 0x80, 0x80, 0xa0 }, { 0x80, 0x80, 0xc0 }, { 0x80, 0x80, 0xe0 },
1107         { 0x80, 0xa0, 0x00 }, { 0x80, 0xa0, 0x20 }, { 0x80, 0xa0, 0x40 }, { 0x80, 0xa0, 0x60 },
1108         { 0x80, 0xa0, 0x80 }, { 0x80, 0xa0, 0xa0 }, { 0x80, 0xa0, 0xc0 }, { 0x80, 0xa0, 0xe0 },
1109         { 0x80, 0xc0, 0x00 }, { 0x80, 0xc0, 0x20 }, { 0x80, 0xc0, 0x40 }, { 0x80, 0xc0, 0x60 },
1110         { 0x80, 0xc0, 0x80 }, { 0x80, 0xc0, 0xa0 }, { 0x80, 0xc0, 0xc0 }, { 0x80, 0xc0, 0xe0 },
1111         { 0x80, 0xe0, 0x00 }, { 0x80, 0xe0, 0x20 }, { 0x80, 0xe0, 0x40 }, { 0x80, 0xe0, 0x60 },
1112         { 0x80, 0xe0, 0x80 }, { 0x80, 0xe0, 0xa0 }, { 0x80, 0xe0, 0xc0 }, { 0x80, 0xe0, 0xe0 },
1113         { 0xc0, 0x00, 0x00 }, { 0xc0, 0x00, 0x20 }, { 0xc0, 0x00, 0x40 }, { 0xc0, 0x00, 0x60 },
1114         { 0xc0, 0x00, 0x80 }, { 0xc0, 0x00, 0xa0 }, { 0xc0, 0x00, 0xc0 }, { 0xc0, 0x00, 0xe0 },
1115         { 0xc0, 0x20, 0x00 }, { 0xc0, 0x20, 0x20 }, { 0xc0, 0x20, 0x40 }, { 0xc0, 0x20, 0x60 },
1116         { 0xc0, 0x20, 0x80 }, { 0xc0, 0x20, 0xa0 }, { 0xc0, 0x20, 0xc0 }, { 0xc0, 0x20, 0xe0 },
1117         { 0xc0, 0x40, 0x00 }, { 0xc0, 0x40, 0x20 }, { 0xc0, 0x40, 0x40 }, { 0xc0, 0x40, 0x60 },
1118         { 0xc0, 0x40, 0x80 }, { 0xc0, 0x40, 0xa0 }, { 0xc0, 0x40, 0xc0 }, { 0xc0, 0x40, 0xe0 },
1119         { 0xc0, 0x60, 0x00 }, { 0xc0, 0x60, 0x20 }, { 0xc0, 0x60, 0x40 }, { 0xc0, 0x60, 0x60 },
1120         { 0xc0, 0x60, 0x80 }, { 0xc0, 0x60, 0xa0 }, { 0xc0, 0x60, 0xc0 }, { 0xc0, 0x60, 0xe0 },
1121         { 0xc0, 0x80, 0x00 }, { 0xc0, 0x80, 0x20 }, { 0xc0, 0x80, 0x40 }, { 0xc0, 0x80, 0x60 },
1122         { 0xc0, 0x80, 0x80 }, { 0xc0, 0x80, 0xa0 }, { 0xc0, 0x80, 0xc0 }, { 0xc0, 0x80, 0xe0 },
1123         { 0xc0, 0xa0, 0x00 }, { 0xc0, 0xa0, 0x20 }, { 0xc0, 0xa0, 0x40 }, { 0xc0, 0xa0, 0x60 },
1124         { 0xc0, 0xa0, 0x80 }, { 0xc0, 0xa0, 0xa0 }, { 0xc0, 0xa0, 0xc0 }, { 0xc0, 0xa0, 0xe0 },
1125         { 0xc0, 0xc0, 0x00 }, { 0xc0, 0xc0, 0x20 }, { 0xc0, 0xc0, 0x40 }, { 0xc0, 0xc0, 0x60 },
1126         { 0xc0, 0xc0, 0x80 }, { 0xc0, 0xc0, 0xa0 }, { 0xf0, 0xfb, 0xff }, { 0xa4, 0xa0, 0xa0 },
1127         { 0x80, 0x80, 0x80 }, { 0x00, 0x00, 0xff }, { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0xff },
1128         { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0xff }, { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0xff },
1129     };
1130
1131     switch (bpp)
1132     {
1133     case 1: return table_1;
1134     case 4: return table_4;
1135     case 8: return table_8;
1136     default: return NULL;
1137     }
1138 }
1139
1140 void fill_default_color_table( BITMAPINFO *info )
1141 {
1142     info->bmiHeader.biClrUsed = 1 << info->bmiHeader.biBitCount;
1143     memcpy( info->bmiColors, get_default_color_table( info->bmiHeader.biBitCount ),
1144             info->bmiHeader.biClrUsed * sizeof(RGBQUAD) );
1145 }
1146
1147 void get_ddb_bitmapinfo( BITMAPOBJ *bmp, BITMAPINFO *info )
1148 {
1149     info->bmiHeader.biSize          = sizeof(info->bmiHeader);
1150     info->bmiHeader.biWidth         = bmp->bitmap.bmWidth;
1151     info->bmiHeader.biHeight        = -bmp->bitmap.bmHeight;
1152     info->bmiHeader.biPlanes        = 1;
1153     info->bmiHeader.biBitCount      = bmp->bitmap.bmBitsPixel;
1154     info->bmiHeader.biCompression   = BI_RGB;
1155     info->bmiHeader.biXPelsPerMeter = 0;
1156     info->bmiHeader.biYPelsPerMeter = 0;
1157     info->bmiHeader.biClrUsed       = 0;
1158     info->bmiHeader.biClrImportant  = 0;
1159 }
1160
1161 BITMAPINFO *copy_packed_dib( const BITMAPINFO *src_info, UINT usage )
1162 {
1163     char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1164     BITMAPINFO *ret, *info = (BITMAPINFO *)buffer;
1165     unsigned int info_size;
1166
1167     if (!bitmapinfo_from_user_bitmapinfo( info, src_info, usage, FALSE )) return NULL;
1168
1169     info_size = get_dib_info_size( info, usage );
1170     if ((ret = HeapAlloc( GetProcessHeap(), 0, info_size + info->bmiHeader.biSizeImage )))
1171     {
1172         memcpy( ret, info, info_size );
1173         memcpy( (char *)ret + info_size, (char *)src_info + bitmap_info_size( src_info, usage ),
1174                 info->bmiHeader.biSizeImage );
1175     }
1176     return ret;
1177 }
1178
1179 /******************************************************************************
1180  * GetDIBits [GDI32.@]
1181  *
1182  * Retrieves bits of bitmap and copies to buffer.
1183  *
1184  * RETURNS
1185  *    Success: Number of scan lines copied from bitmap
1186  *    Failure: 0
1187  */
1188 INT WINAPI GetDIBits(
1189     HDC hdc,         /* [in]  Handle to device context */
1190     HBITMAP hbitmap, /* [in]  Handle to bitmap */
1191     UINT startscan,  /* [in]  First scan line to set in dest bitmap */
1192     UINT lines,      /* [in]  Number of scan lines to copy */
1193     LPVOID bits,       /* [out] Address of array for bitmap bits */
1194     BITMAPINFO * info, /* [out] Address of structure with bitmap data */
1195     UINT coloruse)   /* [in]  RGB or palette index */
1196 {
1197     DC * dc;
1198     BITMAPOBJ * bmp;
1199     int i, dst_to_src_offset, ret = 0;
1200     DWORD err;
1201     char dst_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1202     BITMAPINFO *dst_info = (BITMAPINFO *)dst_bmibuf;
1203     char src_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1204     BITMAPINFO *src_info = (BITMAPINFO *)src_bmibuf;
1205     const struct gdi_dc_funcs *funcs;
1206     struct gdi_image_bits src_bits;
1207     struct bitblt_coords src, dst;
1208     BOOL empty_rect = FALSE;
1209
1210     /* Since info may be a BITMAPCOREINFO or any of the larger BITMAPINFO structures, we'll use our
1211        own copy and transfer the colour info back at the end */
1212     if (!bitmapinfoheader_from_user_bitmapinfo( &dst_info->bmiHeader, &info->bmiHeader )) return 0;
1213     if (coloruse > DIB_PAL_COLORS) return 0;
1214     if (bits &&
1215         (dst_info->bmiHeader.biCompression == BI_JPEG || dst_info->bmiHeader.biCompression == BI_PNG))
1216         return 0;
1217     dst_info->bmiHeader.biClrUsed = 0;
1218     dst_info->bmiHeader.biClrImportant = 0;
1219
1220     if (!(dc = get_dc_ptr( hdc )))
1221     {
1222         SetLastError( ERROR_INVALID_PARAMETER );
1223         return 0;
1224     }
1225     update_dc( dc );
1226     if (!(bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
1227     {
1228         release_dc_ptr( dc );
1229         return 0;
1230     }
1231
1232     funcs = get_bitmap_funcs( bmp );
1233
1234     src.visrect.left   = 0;
1235     src.visrect.top    = 0;
1236     src.visrect.right  = bmp->bitmap.bmWidth;
1237     src.visrect.bottom = bmp->bitmap.bmHeight;
1238
1239     dst.visrect.left   = 0;
1240     dst.visrect.top    = 0;
1241     dst.visrect.right  = dst_info->bmiHeader.biWidth;
1242     dst.visrect.bottom = abs( dst_info->bmiHeader.biHeight );
1243
1244     if (lines == 0 || startscan >= dst.visrect.bottom)
1245         bits = NULL;
1246
1247     if (!bits && dst_info->bmiHeader.biBitCount == 0) /* query bitmap info only */
1248     {
1249         ret = fill_query_info( info, bmp );
1250         goto done;
1251     }
1252
1253     /* validate parameters */
1254
1255     if (dst_info->bmiHeader.biWidth <= 0) goto done;
1256     if (dst_info->bmiHeader.biHeight == 0) goto done;
1257
1258     switch (dst_info->bmiHeader.biCompression)
1259     {
1260     case BI_RLE4:
1261         if (dst_info->bmiHeader.biBitCount != 4) goto done;
1262         if (dst_info->bmiHeader.biHeight < 0) goto done;
1263         if (bits) goto done;  /* can't retrieve compressed bits */
1264         break;
1265     case BI_RLE8:
1266         if (dst_info->bmiHeader.biBitCount != 8) goto done;
1267         if (dst_info->bmiHeader.biHeight < 0) goto done;
1268         if (bits) goto done;  /* can't retrieve compressed bits */
1269         break;
1270     case BI_BITFIELDS:
1271         if (dst_info->bmiHeader.biBitCount != 16 && dst_info->bmiHeader.biBitCount != 32) goto done;
1272         /* fall through */
1273     case BI_RGB:
1274         if (lines && !dst_info->bmiHeader.biPlanes) goto done;
1275         if (dst_info->bmiHeader.biBitCount == 1) break;
1276         if (dst_info->bmiHeader.biBitCount == 4) break;
1277         if (dst_info->bmiHeader.biBitCount == 8) break;
1278         if (dst_info->bmiHeader.biBitCount == 16) break;
1279         if (dst_info->bmiHeader.biBitCount == 24) break;
1280         if (dst_info->bmiHeader.biBitCount == 32) break;
1281         /* fall through */
1282     default:
1283         goto done;
1284     }
1285
1286     if (bits)
1287     {
1288         if (dst_info->bmiHeader.biHeight > 0)
1289         {
1290             dst_to_src_offset = -startscan;
1291             lines = min( lines, dst.visrect.bottom - startscan );
1292             if (lines < dst.visrect.bottom) dst.visrect.top = dst.visrect.bottom - lines;
1293         }
1294         else
1295         {
1296             dst_to_src_offset = dst.visrect.bottom - lines - startscan;
1297             if (dst_to_src_offset < 0)
1298             {
1299                 dst_to_src_offset = 0;
1300                 lines = dst.visrect.bottom - startscan;
1301             }
1302             if (lines < dst.visrect.bottom) dst.visrect.bottom = lines;
1303         }
1304
1305         offset_rect( &dst.visrect, 0, dst_to_src_offset );
1306         empty_rect = !intersect_rect( &src.visrect, &src.visrect, &dst.visrect );
1307         dst.visrect = src.visrect;
1308         offset_rect( &dst.visrect, 0, -dst_to_src_offset );
1309
1310         if (dst_info->bmiHeader.biHeight > 0)
1311         {
1312             if (dst.visrect.bottom < dst_info->bmiHeader.biHeight)
1313             {
1314                 int pad_lines = min( dst_info->bmiHeader.biHeight - dst.visrect.bottom, lines );
1315                 int pad_bytes = pad_lines * get_dib_stride( dst_info->bmiHeader.biWidth, dst_info->bmiHeader.biBitCount );
1316                 memset( bits, 0, pad_bytes );
1317                 bits = (char *)bits + pad_bytes;
1318             }
1319         }
1320         else
1321         {
1322             if (dst.visrect.bottom < lines)
1323             {
1324                 int pad_lines = lines - dst.visrect.bottom;
1325                 int stride = get_dib_stride( dst_info->bmiHeader.biWidth, dst_info->bmiHeader.biBitCount );
1326                 int pad_bytes = pad_lines * stride;
1327                 memset( (char *)bits + dst.visrect.bottom * stride, 0, pad_bytes );
1328             }
1329         }
1330
1331         if (empty_rect) bits = NULL;
1332
1333         src.x      = src.visrect.left;
1334         src.y      = src.visrect.top;
1335         src.width  = src.visrect.right - src.visrect.left;
1336         src.height = src.visrect.bottom - src.visrect.top;
1337
1338         lines = src.height;
1339     }
1340
1341     err = funcs->pGetImage( NULL, hbitmap, src_info, bits ? &src_bits : NULL, bits ? &src : NULL );
1342
1343     if (err) goto done;
1344
1345     /* fill out the src colour table, if it needs one */
1346     if (src_info->bmiHeader.biBitCount <= 8 && src_info->bmiHeader.biClrUsed == 0)
1347         fill_default_color_table( src_info );
1348
1349     /* if the src and dst are the same depth, copy the colour info across */
1350     if (dst_info->bmiHeader.biBitCount == src_info->bmiHeader.biBitCount && coloruse == DIB_RGB_COLORS )
1351     {
1352         switch (src_info->bmiHeader.biBitCount)
1353         {
1354         case 16:
1355             if (src_info->bmiHeader.biCompression == BI_RGB)
1356             {
1357                 src_info->bmiHeader.biCompression = BI_BITFIELDS;
1358                 memcpy( src_info->bmiColors, bit_fields_555, sizeof(bit_fields_555) );
1359             }
1360             break;
1361         case 32:
1362             if (src_info->bmiHeader.biCompression == BI_RGB)
1363             {
1364                 src_info->bmiHeader.biCompression = BI_BITFIELDS;
1365                 memcpy( src_info->bmiColors, bit_fields_888, sizeof(bit_fields_888) );
1366             }
1367             break;
1368         }
1369         src_info->bmiHeader.biSizeImage = get_dib_image_size( dst_info );
1370         copy_color_info( dst_info, src_info, coloruse );
1371     }
1372     else if (dst_info->bmiHeader.biBitCount <= 8) /* otherwise construct a default colour table for the dst, if needed */
1373     {
1374         if( coloruse == DIB_PAL_COLORS )
1375         {
1376             if (!fill_color_table_from_palette( dst_info, hdc )) goto done;
1377         }
1378         else
1379         {
1380             fill_default_color_table( dst_info );
1381         }
1382     }
1383
1384     if (bits)
1385     {
1386         if(dst_info->bmiHeader.biHeight > 0)
1387             dst_info->bmiHeader.biHeight = src.height;
1388         else
1389             dst_info->bmiHeader.biHeight = -src.height;
1390
1391         convert_bitmapinfo( src_info, src_bits.ptr, &src, dst_info, bits, FALSE );
1392         if (src_bits.free) src_bits.free( &src_bits );
1393         ret = lines;
1394     }
1395     else
1396         ret = empty_rect ? FALSE : TRUE;
1397
1398     if (coloruse == DIB_PAL_COLORS)
1399     {
1400         WORD *index = (WORD *)dst_info->bmiColors;
1401         for (i = 0; i < dst_info->bmiHeader.biClrUsed; i++, index++)
1402             *index = i;
1403     }
1404
1405     copy_color_info( info, dst_info, coloruse );
1406     if (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) info->bmiHeader.biClrUsed = 0;
1407
1408 done:
1409     release_dc_ptr( dc );
1410     GDI_ReleaseObj( hbitmap );
1411     return ret;
1412 }
1413
1414
1415 /***********************************************************************
1416  *           CreateDIBitmap    (GDI32.@)
1417  *
1418  * Creates a DDB (device dependent bitmap) from a DIB.
1419  * The DDB will have the same color depth as the reference DC.
1420  */
1421 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
1422                             DWORD init, LPCVOID bits, const BITMAPINFO *data,
1423                             UINT coloruse )
1424 {
1425     BITMAPINFOHEADER info;
1426     HBITMAP handle;
1427     LONG height;
1428
1429     if (!bitmapinfoheader_from_user_bitmapinfo( &info, header )) return 0;
1430     if (info.biCompression == BI_JPEG || info.biCompression == BI_PNG) return 0;
1431     if (coloruse > DIB_PAL_COLORS + 1) return 0;
1432     if (info.biWidth < 0) return 0;
1433
1434     /* Top-down DIBs have a negative height */
1435     height = abs( info.biHeight );
1436
1437     TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1438           hdc, header, init, bits, data, coloruse, info.biWidth, info.biHeight,
1439           info.biBitCount, info.biCompression);
1440
1441     if (hdc == NULL)
1442         handle = CreateBitmap( info.biWidth, height, 1, 1, NULL );
1443     else
1444         handle = CreateCompatibleBitmap( hdc, info.biWidth, height );
1445
1446     if (handle)
1447     {
1448         if (init & CBM_INIT)
1449         {
1450             if (SetDIBits( hdc, handle, 0, height, bits, data, coloruse ) == 0)
1451             {
1452                 DeleteObject( handle );
1453                 handle = 0;
1454             }
1455         }
1456     }
1457
1458     return handle;
1459 }
1460
1461
1462 /***********************************************************************
1463  *           CreateDIBSection    (GDI32.@)
1464  */
1465 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1466                                 VOID **bits, HANDLE section, DWORD offset)
1467 {
1468     char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1469     BITMAPINFO *info = (BITMAPINFO *)buffer;
1470     HBITMAP ret = 0;
1471     DC *dc;
1472     BOOL bDesktopDC = FALSE;
1473     DIBSECTION *dib;
1474     BITMAPOBJ *bmp;
1475     RGBQUAD *color_table = NULL;
1476     void *mapBits = NULL;
1477
1478     if (bits) *bits = NULL;
1479     if (!bitmapinfo_from_user_bitmapinfo( info, bmi, usage, FALSE )) return 0;
1480     if (usage > DIB_PAL_COLORS) return 0;
1481     if (info->bmiHeader.biPlanes != 1)
1482     {
1483         if (info->bmiHeader.biPlanes * info->bmiHeader.biBitCount > 16) return 0;
1484         WARN( "%u planes not properly supported\n", info->bmiHeader.biPlanes );
1485     }
1486
1487     if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1488
1489     TRACE("format (%d,%d), planes %d, bpp %d, %s, size %d %s\n",
1490           info->bmiHeader.biWidth, info->bmiHeader.biHeight,
1491           info->bmiHeader.biPlanes, info->bmiHeader.biBitCount,
1492           info->bmiHeader.biCompression == BI_BITFIELDS? "BI_BITFIELDS" : "BI_RGB",
1493           info->bmiHeader.biSizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1494
1495     dib->dsBm.bmType       = 0;
1496     dib->dsBm.bmWidth      = info->bmiHeader.biWidth;
1497     dib->dsBm.bmHeight     = abs( info->bmiHeader.biHeight );
1498     dib->dsBm.bmWidthBytes = get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
1499     dib->dsBm.bmPlanes     = info->bmiHeader.biPlanes;
1500     dib->dsBm.bmBitsPixel  = info->bmiHeader.biBitCount;
1501     dib->dsBm.bmBits       = NULL;
1502     dib->dsBmih            = info->bmiHeader;
1503
1504     if (info->bmiHeader.biBitCount <= 8)  /* build the color table */
1505     {
1506         if (usage == DIB_PAL_COLORS && !fill_color_table_from_pal_colors( info, hdc ))
1507             goto error;
1508         dib->dsBmih.biClrUsed = info->bmiHeader.biClrUsed;
1509         if (!(color_table = HeapAlloc( GetProcessHeap(), 0, dib->dsBmih.biClrUsed * sizeof(RGBQUAD) )))
1510             goto error;
1511         memcpy( color_table, info->bmiColors, dib->dsBmih.biClrUsed * sizeof(RGBQUAD) );
1512     }
1513
1514     /* set dsBitfields values */
1515     if (info->bmiHeader.biBitCount == 16 && info->bmiHeader.biCompression == BI_RGB)
1516     {
1517         dib->dsBmih.biCompression = BI_BITFIELDS;
1518         dib->dsBitfields[0] = 0x7c00;
1519         dib->dsBitfields[1] = 0x03e0;
1520         dib->dsBitfields[2] = 0x001f;
1521     }
1522     else if (info->bmiHeader.biCompression == BI_BITFIELDS)
1523     {
1524         if (usage == DIB_PAL_COLORS) goto error;
1525         dib->dsBitfields[0] =  *(const DWORD *)info->bmiColors;
1526         dib->dsBitfields[1] =  *((const DWORD *)info->bmiColors + 1);
1527         dib->dsBitfields[2] =  *((const DWORD *)info->bmiColors + 2);
1528         if (!dib->dsBitfields[0] || !dib->dsBitfields[1] || !dib->dsBitfields[2]) goto error;
1529     }
1530     else dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1531
1532     /* get storage location for DIB bits */
1533
1534     if (section)
1535     {
1536         SYSTEM_INFO SystemInfo;
1537         DWORD mapOffset;
1538         INT mapSize;
1539
1540         GetSystemInfo( &SystemInfo );
1541         mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1542         mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1543         mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1544         if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1545     }
1546     else
1547     {
1548         offset = 0;
1549         dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1550                                          MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1551     }
1552     dib->dshSection = section;
1553     dib->dsOffset = offset;
1554
1555     if (!dib->dsBm.bmBits) goto error;
1556
1557     /* If the reference hdc is null, take the desktop dc */
1558     if (hdc == 0)
1559     {
1560         hdc = CreateCompatibleDC(0);
1561         bDesktopDC = TRUE;
1562     }
1563
1564     if (!(dc = get_dc_ptr( hdc ))) goto error;
1565
1566     /* create Device Dependent Bitmap and add DIB pointer */
1567     ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1568                         (info->bmiHeader.biBitCount == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1569
1570     if (ret && ((bmp = GDI_GetObjPtr(ret, OBJ_BITMAP))))
1571     {
1572         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pCreateDIBSection );
1573         bmp->dib = dib;
1574         bmp->funcs = physdev->funcs;
1575         bmp->color_table = color_table;
1576         GDI_ReleaseObj( ret );
1577
1578         if (!physdev->funcs->pCreateDIBSection( physdev, ret, info, usage ))
1579         {
1580             DeleteObject( ret );
1581             ret = 0;
1582         }
1583     }
1584
1585     release_dc_ptr( dc );
1586     if (bDesktopDC) DeleteDC( hdc );
1587     if (ret && bits) *bits = dib->dsBm.bmBits;
1588     return ret;
1589
1590 error:
1591     if (bDesktopDC) DeleteDC( hdc );
1592     if (section) UnmapViewOfFile( mapBits );
1593     else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1594     HeapFree( GetProcessHeap(), 0, color_table );
1595     HeapFree( GetProcessHeap(), 0, dib );
1596     return 0;
1597 }