gdi32: Sanitize the DIB information for DIB pattern brushes.
[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 BITMAPINFO *copy_packed_dib( const BITMAPINFO *src_info, UINT usage )
1117 {
1118     char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1119     BITMAPINFO *ret, *info = (BITMAPINFO *)buffer;
1120     int info_size, image_size;
1121
1122     if (!bitmapinfo_from_user_bitmapinfo( info, src_info, usage, FALSE )) return NULL;
1123
1124     info_size = bitmap_info_size( info, usage );
1125     image_size = get_dib_image_size( info );
1126     if ((ret = HeapAlloc( GetProcessHeap(), 0, info_size + image_size )))
1127     {
1128         memcpy( ret, info, info_size );
1129         memcpy( (char *)ret + info_size, (char *)src_info + bitmap_info_size(src_info,usage), image_size );
1130     }
1131     return ret;
1132 }
1133
1134 /******************************************************************************
1135  * GetDIBits [GDI32.@]
1136  *
1137  * Retrieves bits of bitmap and copies to buffer.
1138  *
1139  * RETURNS
1140  *    Success: Number of scan lines copied from bitmap
1141  *    Failure: 0
1142  */
1143 INT WINAPI GetDIBits(
1144     HDC hdc,         /* [in]  Handle to device context */
1145     HBITMAP hbitmap, /* [in]  Handle to bitmap */
1146     UINT startscan,  /* [in]  First scan line to set in dest bitmap */
1147     UINT lines,      /* [in]  Number of scan lines to copy */
1148     LPVOID bits,       /* [out] Address of array for bitmap bits */
1149     BITMAPINFO * info, /* [out] Address of structure with bitmap data */
1150     UINT coloruse)   /* [in]  RGB or palette index */
1151 {
1152     DC * dc;
1153     BITMAPOBJ * bmp;
1154     int i, dst_to_src_offset, ret = 0;
1155     DWORD err;
1156     char dst_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1157     BITMAPINFO *dst_info = (BITMAPINFO *)dst_bmibuf;
1158     char src_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1159     BITMAPINFO *src_info = (BITMAPINFO *)src_bmibuf;
1160     const struct gdi_dc_funcs *funcs;
1161     struct gdi_image_bits src_bits;
1162     struct bitblt_coords src, dst;
1163     BOOL empty_rect = FALSE;
1164
1165     /* Since info may be a BITMAPCOREINFO or any of the larger BITMAPINFO structures, we'll use our
1166        own copy and transfer the colour info back at the end */
1167     if (!bitmapinfoheader_from_user_bitmapinfo( &dst_info->bmiHeader, &info->bmiHeader )) return 0;
1168     if (bits &&
1169         (dst_info->bmiHeader.biCompression == BI_JPEG || dst_info->bmiHeader.biCompression == BI_PNG))
1170         return 0;
1171     dst_info->bmiHeader.biClrUsed = 0;
1172     dst_info->bmiHeader.biClrImportant = 0;
1173
1174     if (!(dc = get_dc_ptr( hdc )))
1175     {
1176         SetLastError( ERROR_INVALID_PARAMETER );
1177         return 0;
1178     }
1179     update_dc( dc );
1180     if (!(bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
1181     {
1182         release_dc_ptr( dc );
1183         return 0;
1184     }
1185
1186     funcs = get_bitmap_funcs( bmp );
1187
1188     src.visrect.left   = 0;
1189     src.visrect.top    = 0;
1190     src.visrect.right  = bmp->bitmap.bmWidth;
1191     src.visrect.bottom = bmp->bitmap.bmHeight;
1192
1193     dst.visrect.left   = 0;
1194     dst.visrect.top    = 0;
1195     dst.visrect.right  = dst_info->bmiHeader.biWidth;
1196     dst.visrect.bottom = abs( dst_info->bmiHeader.biHeight );
1197
1198     if (lines == 0 || startscan >= dst.visrect.bottom)
1199         bits = NULL;
1200
1201     if (!bits && dst_info->bmiHeader.biBitCount == 0) /* query bitmap info only */
1202     {
1203         ret = fill_query_info( info, bmp );
1204         goto done;
1205     }
1206
1207     /* validate parameters */
1208
1209     if (dst_info->bmiHeader.biWidth <= 0) goto done;
1210     if (dst_info->bmiHeader.biHeight == 0) goto done;
1211
1212     switch (dst_info->bmiHeader.biCompression)
1213     {
1214     case BI_RLE4:
1215         if (dst_info->bmiHeader.biBitCount != 4) goto done;
1216         if (dst_info->bmiHeader.biHeight < 0) goto done;
1217         if (bits) goto done;  /* can't retrieve compressed bits */
1218         break;
1219     case BI_RLE8:
1220         if (dst_info->bmiHeader.biBitCount != 8) goto done;
1221         if (dst_info->bmiHeader.biHeight < 0) goto done;
1222         if (bits) goto done;  /* can't retrieve compressed bits */
1223         break;
1224     case BI_BITFIELDS:
1225         if (dst_info->bmiHeader.biBitCount != 16 && dst_info->bmiHeader.biBitCount != 32) goto done;
1226         /* fall through */
1227     case BI_RGB:
1228         if (lines && !dst_info->bmiHeader.biPlanes) goto done;
1229         if (dst_info->bmiHeader.biBitCount == 1) break;
1230         if (dst_info->bmiHeader.biBitCount == 4) break;
1231         if (dst_info->bmiHeader.biBitCount == 8) break;
1232         if (dst_info->bmiHeader.biBitCount == 16) break;
1233         if (dst_info->bmiHeader.biBitCount == 24) break;
1234         if (dst_info->bmiHeader.biBitCount == 32) break;
1235         /* fall through */
1236     default:
1237         goto done;
1238     }
1239
1240     if (bits)
1241     {
1242         if (dst_info->bmiHeader.biHeight > 0)
1243         {
1244             dst_to_src_offset = -startscan;
1245             lines = min( lines, dst.visrect.bottom - startscan );
1246             if (lines < dst.visrect.bottom) dst.visrect.top = dst.visrect.bottom - lines;
1247         }
1248         else
1249         {
1250             dst_to_src_offset = dst.visrect.bottom - lines - startscan;
1251             if (dst_to_src_offset < 0)
1252             {
1253                 dst_to_src_offset = 0;
1254                 lines = dst.visrect.bottom - startscan;
1255             }
1256             if (lines < dst.visrect.bottom) dst.visrect.bottom = lines;
1257         }
1258
1259         offset_rect( &dst.visrect, 0, dst_to_src_offset );
1260         empty_rect = !intersect_rect( &src.visrect, &src.visrect, &dst.visrect );
1261         dst.visrect = src.visrect;
1262         offset_rect( &dst.visrect, 0, -dst_to_src_offset );
1263
1264         if (dst_info->bmiHeader.biHeight > 0)
1265         {
1266             if (dst.visrect.bottom < dst_info->bmiHeader.biHeight)
1267             {
1268                 int pad_lines = min( dst_info->bmiHeader.biHeight - dst.visrect.bottom, lines );
1269                 int pad_bytes = pad_lines * get_dib_stride( dst_info->bmiHeader.biWidth, dst_info->bmiHeader.biBitCount );
1270                 memset( bits, 0, pad_bytes );
1271                 bits = (char *)bits + pad_bytes;
1272             }
1273         }
1274         else
1275         {
1276             if (dst.visrect.bottom < lines)
1277             {
1278                 int pad_lines = lines - dst.visrect.bottom;
1279                 int stride = get_dib_stride( dst_info->bmiHeader.biWidth, dst_info->bmiHeader.biBitCount );
1280                 int pad_bytes = pad_lines * stride;
1281                 memset( (char *)bits + dst.visrect.bottom * stride, 0, pad_bytes );
1282             }
1283         }
1284
1285         if (empty_rect) bits = NULL;
1286
1287         src.x      = src.visrect.left;
1288         src.y      = src.visrect.top;
1289         src.width  = src.visrect.right - src.visrect.left;
1290         src.height = src.visrect.bottom - src.visrect.top;
1291
1292         lines = src.height;
1293     }
1294
1295     err = funcs->pGetImage( NULL, hbitmap, src_info, bits ? &src_bits : NULL, bits ? &src : NULL );
1296
1297     if (err) goto done;
1298
1299     /* fill out the src colour table, if it needs one */
1300     if (src_info->bmiHeader.biBitCount <= 8 && src_info->bmiHeader.biClrUsed == 0)
1301         fill_default_color_table( src_info );
1302
1303     /* if the src and dst are the same depth, copy the colour info across */
1304     if (dst_info->bmiHeader.biBitCount == src_info->bmiHeader.biBitCount && coloruse == DIB_RGB_COLORS )
1305     {
1306         switch (src_info->bmiHeader.biBitCount)
1307         {
1308         case 16:
1309             if (src_info->bmiHeader.biCompression == BI_RGB)
1310             {
1311                 src_info->bmiHeader.biCompression = BI_BITFIELDS;
1312                 memcpy( src_info->bmiColors, bit_fields_555, sizeof(bit_fields_555) );
1313             }
1314             break;
1315         case 32:
1316             if (src_info->bmiHeader.biCompression == BI_RGB)
1317             {
1318                 src_info->bmiHeader.biCompression = BI_BITFIELDS;
1319                 memcpy( src_info->bmiColors, bit_fields_888, sizeof(bit_fields_888) );
1320             }
1321             break;
1322         }
1323         src_info->bmiHeader.biSizeImage = get_dib_image_size( dst_info );
1324         copy_color_info( dst_info, src_info, coloruse );
1325     }
1326     else if (dst_info->bmiHeader.biBitCount <= 8) /* otherwise construct a default colour table for the dst, if needed */
1327     {
1328         if( coloruse == DIB_PAL_COLORS )
1329         {
1330             if (!fill_color_table_from_palette( dst_info, hdc )) goto done;
1331         }
1332         else
1333         {
1334             fill_default_color_table( dst_info );
1335         }
1336     }
1337
1338     if (bits)
1339     {
1340         if(dst_info->bmiHeader.biHeight > 0)
1341             dst_info->bmiHeader.biHeight = src.height;
1342         else
1343             dst_info->bmiHeader.biHeight = -src.height;
1344
1345         convert_bitmapinfo( src_info, src_bits.ptr, &src, dst_info, bits, FALSE );
1346         if (src_bits.free) src_bits.free( &src_bits );
1347         ret = lines;
1348     }
1349     else
1350         ret = empty_rect ? FALSE : TRUE;
1351
1352     if (coloruse == DIB_PAL_COLORS)
1353     {
1354         WORD *index = (WORD *)dst_info->bmiColors;
1355         int colors = get_dib_num_of_colors( dst_info );
1356         for (i = 0; i < colors; i++, index++)
1357             *index = i;
1358     }
1359
1360     copy_color_info( info, dst_info, coloruse );
1361
1362 done:
1363     release_dc_ptr( dc );
1364     GDI_ReleaseObj( hbitmap );
1365     return ret;
1366 }
1367
1368
1369 /***********************************************************************
1370  *           CreateDIBitmap    (GDI32.@)
1371  *
1372  * Creates a DDB (device dependent bitmap) from a DIB.
1373  * The DDB will have the same color depth as the reference DC.
1374  */
1375 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
1376                             DWORD init, LPCVOID bits, const BITMAPINFO *data,
1377                             UINT coloruse )
1378 {
1379     BITMAPINFOHEADER info;
1380     HBITMAP handle;
1381     LONG height;
1382
1383     if (!bitmapinfoheader_from_user_bitmapinfo( &info, header )) return 0;
1384     if (info.biCompression == BI_JPEG || info.biCompression == BI_PNG) return 0;
1385     if (info.biWidth < 0) return 0;
1386
1387     /* Top-down DIBs have a negative height */
1388     height = abs( info.biHeight );
1389
1390     TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1391           hdc, header, init, bits, data, coloruse, info.biWidth, info.biHeight,
1392           info.biBitCount, info.biCompression);
1393
1394     if (hdc == NULL)
1395         handle = CreateBitmap( info.biWidth, height, 1, 1, NULL );
1396     else
1397         handle = CreateCompatibleBitmap( hdc, info.biWidth, height );
1398
1399     if (handle)
1400     {
1401         if (init & CBM_INIT)
1402         {
1403             if (SetDIBits( hdc, handle, 0, height, bits, data, coloruse ) == 0)
1404             {
1405                 DeleteObject( handle );
1406                 handle = 0;
1407             }
1408         }
1409     }
1410
1411     return handle;
1412 }
1413
1414 /* Copy/synthesize RGB palette from BITMAPINFO */
1415 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1416 {
1417     unsigned int colors, i;
1418
1419     colors = get_dib_num_of_colors( info );
1420     if (!(bmp->color_table = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1421     bmp->nb_colors = colors;
1422
1423     if (coloruse == DIB_RGB_COLORS)
1424     {
1425         memcpy( bmp->color_table, info->bmiColors, colors * sizeof(RGBQUAD));
1426     }
1427     else
1428     {
1429         PALETTEENTRY entries[256];
1430         const WORD *index = (const WORD *)info->bmiColors;
1431         UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1432
1433         for (i = 0; i < colors; i++, index++)
1434         {
1435             PALETTEENTRY *entry = &entries[*index % count];
1436             bmp->color_table[i].rgbRed = entry->peRed;
1437             bmp->color_table[i].rgbGreen = entry->peGreen;
1438             bmp->color_table[i].rgbBlue = entry->peBlue;
1439             bmp->color_table[i].rgbReserved = 0;
1440         }
1441     }
1442 }
1443
1444 /***********************************************************************
1445  *           CreateDIBSection    (GDI32.@)
1446  */
1447 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1448                                 VOID **bits, HANDLE section, DWORD offset)
1449 {
1450     char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1451     BITMAPINFO *info = (BITMAPINFO *)buffer;
1452     HBITMAP ret = 0;
1453     DC *dc;
1454     BOOL bDesktopDC = FALSE;
1455     DIBSECTION *dib;
1456     BITMAPOBJ *bmp;
1457     void *mapBits = NULL;
1458
1459     if (bits) *bits = NULL;
1460     if (!bitmapinfo_from_user_bitmapinfo( info, bmi, usage, FALSE )) return 0;
1461     if (info->bmiHeader.biPlanes != 1)
1462     {
1463         if (info->bmiHeader.biPlanes * info->bmiHeader.biBitCount > 16) return 0;
1464         WARN( "%u planes not properly supported\n", info->bmiHeader.biPlanes );
1465     }
1466
1467     if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1468
1469     TRACE("format (%d,%d), planes %d, bpp %d, %s, size %d %s\n",
1470           info->bmiHeader.biWidth, info->bmiHeader.biHeight,
1471           info->bmiHeader.biPlanes, info->bmiHeader.biBitCount,
1472           info->bmiHeader.biCompression == BI_BITFIELDS? "BI_BITFIELDS" : "BI_RGB",
1473           info->bmiHeader.biSizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1474
1475     dib->dsBm.bmType       = 0;
1476     dib->dsBm.bmWidth      = info->bmiHeader.biWidth;
1477     dib->dsBm.bmHeight     = abs( info->bmiHeader.biHeight );
1478     dib->dsBm.bmWidthBytes = get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
1479     dib->dsBm.bmPlanes     = info->bmiHeader.biPlanes;
1480     dib->dsBm.bmBitsPixel  = info->bmiHeader.biBitCount;
1481     dib->dsBm.bmBits       = NULL;
1482     dib->dsBmih            = info->bmiHeader;
1483
1484     /* set number of entries in bmi.bmiColors table */
1485     if( info->bmiHeader.biBitCount <= 8 )
1486         dib->dsBmih.biClrUsed = 1 << info->bmiHeader.biBitCount;
1487
1488     /* set dsBitfields values */
1489     if (info->bmiHeader.biBitCount == 16 && info->bmiHeader.biCompression == BI_RGB)
1490     {
1491         dib->dsBmih.biCompression = BI_BITFIELDS;
1492         dib->dsBitfields[0] = 0x7c00;
1493         dib->dsBitfields[1] = 0x03e0;
1494         dib->dsBitfields[2] = 0x001f;
1495     }
1496     else if (info->bmiHeader.biCompression == BI_BITFIELDS)
1497     {
1498         dib->dsBitfields[0] =  *(const DWORD *)bmi->bmiColors;
1499         dib->dsBitfields[1] =  *((const DWORD *)bmi->bmiColors + 1);
1500         dib->dsBitfields[2] =  *((const DWORD *)bmi->bmiColors + 2);
1501         if (!dib->dsBitfields[0] || !dib->dsBitfields[1] || !dib->dsBitfields[2]) goto error;
1502     }
1503     else dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1504
1505     /* get storage location for DIB bits */
1506
1507     if (section)
1508     {
1509         SYSTEM_INFO SystemInfo;
1510         DWORD mapOffset;
1511         INT mapSize;
1512
1513         GetSystemInfo( &SystemInfo );
1514         mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1515         mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1516         mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1517         if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1518     }
1519     else
1520     {
1521         offset = 0;
1522         dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1523                                          MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1524     }
1525     dib->dshSection = section;
1526     dib->dsOffset = offset;
1527
1528     if (!dib->dsBm.bmBits)
1529     {
1530         HeapFree( GetProcessHeap(), 0, dib );
1531         return 0;
1532     }
1533
1534     /* If the reference hdc is null, take the desktop dc */
1535     if (hdc == 0)
1536     {
1537         hdc = CreateCompatibleDC(0);
1538         bDesktopDC = TRUE;
1539     }
1540
1541     if (!(dc = get_dc_ptr( hdc ))) goto error;
1542
1543     /* create Device Dependent Bitmap and add DIB pointer */
1544     ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1545                         (info->bmiHeader.biBitCount == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1546
1547     if (ret && ((bmp = GDI_GetObjPtr(ret, OBJ_BITMAP))))
1548     {
1549         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pCreateDIBSection );
1550         bmp->dib = dib;
1551         bmp->funcs = physdev->funcs;
1552         /* create local copy of DIB palette */
1553         if (info->bmiHeader.biBitCount <= 8) DIB_CopyColorTable( dc, bmp, usage, info );
1554         GDI_ReleaseObj( ret );
1555
1556         if (!physdev->funcs->pCreateDIBSection( physdev, ret, info, usage ))
1557         {
1558             DeleteObject( ret );
1559             ret = 0;
1560         }
1561     }
1562
1563     release_dc_ptr( dc );
1564     if (bDesktopDC) DeleteDC( hdc );
1565     if (ret && bits) *bits = dib->dsBm.bmBits;
1566     return ret;
1567
1568 error:
1569     if (bDesktopDC) DeleteDC( hdc );
1570     if (section) UnmapViewOfFile( mapBits );
1571     else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1572     HeapFree( GetProcessHeap(), 0, dib );
1573     return 0;
1574 }