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