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