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