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