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