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