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