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