Reverse the order for deleting the items in resetcontent to correctly
[wine] / dlls / gdi / 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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
47   * You should never access the color table using the bmiColors member,
48     because the passed structure may have one of the extended headers
49     mentioned above. Use this to calculate the location:
50     
51     BITMAPINFO* info;
52     void* colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
53
54     
55   * More information:
56     Search for "Bitmap Structures" in MSDN
57 */
58
59 #include <stdarg.h>
60 #include <stdlib.h>
61 #include <string.h>
62
63 #include "windef.h"
64 #include "winbase.h"
65 #include "gdi.h"
66 #include "wownt32.h"
67 #include "gdi_private.h"
68 #include "wine/debug.h"
69
70 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
71
72
73 /*
74   Some of the following helper functions are duplicated in
75   dlls/x11drv/dib.c
76 */
77
78 /***********************************************************************
79  *           DIB_GetDIBWidthBytes
80  *
81  * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
82  * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_87eb.asp
83  */
84 int DIB_GetDIBWidthBytes( int width, int depth )
85 {
86     int words;
87
88     switch(depth)
89     {
90         case 1:  words = (width + 31) / 32; break;
91         case 4:  words = (width + 7) / 8; break;
92         case 8:  words = (width + 3) / 4; break;
93         case 15:
94         case 16: words = (width + 1) / 2; break;
95         case 24: words = (width * 3 + 3)/4; break;
96
97         default:
98             WARN("(%d): Unsupported depth\n", depth );
99         /* fall through */
100         case 32:
101                 words = width;
102     }
103     return 4 * words;
104 }
105
106 /***********************************************************************
107  *           DIB_GetDIBImageBytes
108  *
109  * Return the number of bytes used to hold the image in a DIB bitmap.
110  */
111 int DIB_GetDIBImageBytes( int width, int height, int depth )
112 {
113     return DIB_GetDIBWidthBytes( width, depth ) * abs( height );
114 }
115
116
117 /***********************************************************************
118  *           DIB_BitmapInfoSize
119  *
120  * Return the size of the bitmap info structure including color table.
121  */
122 int DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse )
123 {
124     int colors;
125
126     if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
127     {
128         BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
129         colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
130         return sizeof(BITMAPCOREHEADER) + colors *
131              ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
132     }
133     else  /* assume BITMAPINFOHEADER */
134     {
135         colors = info->bmiHeader.biClrUsed;
136         if (colors > 256) colors = 256;
137         if (!colors && (info->bmiHeader.biBitCount <= 8))
138             colors = 1 << info->bmiHeader.biBitCount;
139         return sizeof(BITMAPINFOHEADER) + colors *
140                ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
141     }
142 }
143
144
145 /***********************************************************************
146  *           DIB_GetBitmapInfo
147  *
148  * Get the info from a bitmap header.
149  * Return 1 for INFOHEADER, 0 for COREHEADER,
150  * 4 for V4HEADER, 5 for V5HEADER, -1 for error.
151  */
152 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
153                               LONG *height, WORD *bpp, DWORD *compr )
154 {
155     if (header->biSize == sizeof(BITMAPINFOHEADER))
156     {
157         *width  = header->biWidth;
158         *height = header->biHeight;
159         *bpp    = header->biBitCount;
160         *compr  = header->biCompression;
161         return 1;
162     }
163     if (header->biSize == sizeof(BITMAPCOREHEADER))
164     {
165         BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
166         *width  = core->bcWidth;
167         *height = core->bcHeight;
168         *bpp    = core->bcBitCount;
169         *compr  = 0;
170         return 0;
171     }
172     if (header->biSize == sizeof(BITMAPV4HEADER))
173     {
174         BITMAPV4HEADER *v4hdr = (BITMAPV4HEADER *)header;
175         *width  = v4hdr->bV4Width;
176         *height = v4hdr->bV4Height;
177         *bpp    = v4hdr->bV4BitCount;
178         *compr  = v4hdr->bV4V4Compression;
179         return 4;
180     }
181     if (header->biSize == sizeof(BITMAPV5HEADER))
182     {
183         BITMAPV5HEADER *v5hdr = (BITMAPV5HEADER *)header;
184         *width  = v5hdr->bV5Width;
185         *height = v5hdr->bV5Height;
186         *bpp    = v5hdr->bV5BitCount;
187         *compr  = v5hdr->bV5Compression;
188         return 5;
189     }
190     ERR("(%ld): unknown/wrong size for header\n", header->biSize );
191     return -1;
192 }
193
194
195 /***********************************************************************
196  *           StretchDIBits   (GDI32.@)
197  */
198 INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
199                        INT heightDst, INT xSrc, INT ySrc, INT widthSrc,
200                        INT heightSrc, const void *bits,
201                        const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
202 {
203     DC *dc;
204
205     if (!bits || !info)
206         return 0;
207
208     dc = DC_GetDCUpdate( hdc );
209     if(!dc) return FALSE;
210
211     if(dc->funcs->pStretchDIBits)
212     {
213         heightSrc = dc->funcs->pStretchDIBits(dc->physDev, xDst, yDst, widthDst,
214                                               heightDst, xSrc, ySrc, widthSrc,
215                                               heightSrc, bits, info, wUsage, dwRop);
216         GDI_ReleaseObj( hdc );
217     }
218     else /* use StretchBlt */
219     {
220         HBITMAP hBitmap, hOldBitmap;
221         HPALETTE hpal = NULL;
222         HDC hdcMem;
223         LONG height;
224         LONG width;
225         WORD bpp;
226         DWORD compr;
227
228         if (DIB_GetBitmapInfo( (BITMAPINFOHEADER*) info, &width, &height, &bpp, &compr ) == -1)
229         {
230             ERR("Invalid bitmap\n");
231             return 0;
232         }
233
234         if (width < 0)
235         {
236             ERR("Bitmap has a negative width\n");
237             return 0;
238         }
239
240         GDI_ReleaseObj( hdc );
241         hdcMem = CreateCompatibleDC( hdc );
242         hBitmap = CreateCompatibleBitmap(hdc, width, height);
243         hOldBitmap = SelectObject( hdcMem, hBitmap );
244         if(wUsage == DIB_PAL_COLORS)
245         {
246             hpal = GetCurrentObject(hdc, OBJ_PAL);
247             hpal = SelectPalette(hdcMem, hpal, FALSE);
248         }
249
250         if (info->bmiHeader.biCompression == BI_RLE4 ||
251             info->bmiHeader.biCompression == BI_RLE8) {
252
253            /* when RLE compression is used, there may be some gaps (ie the DIB doesn't
254             * contain all the rectangle described in bmiHeader, but only part of it.
255             * This mean that those undescribed pixels must be left untouched.
256             * So, we first copy on a memory bitmap the current content of the
257             * destination rectangle, blit the DIB bits on top of it - hence leaving
258             * the gaps untouched -, and blitting the rectangle back.
259             * This insure that gaps are untouched on the destination rectangle
260             * Not doing so leads to trashed images (the gaps contain what was on the
261             * memory bitmap => generally black or garbage)
262             * Unfortunately, RLE DIBs without gaps will be slowed down. But this is
263             * another speed vs correctness issue. Anyway, if speed is needed, then the
264             * pStretchDIBits function shall be implemented.
265             * ericP (2000/09/09)
266             */
267
268             /* copy existing bitmap from destination dc */
269             StretchBlt( hdcMem, xSrc, abs(height) - heightSrc - ySrc,
270                         widthSrc, heightSrc, hdc, xDst, yDst, widthDst, heightDst,
271                         dwRop );
272         }
273
274         SetDIBits(hdcMem, hBitmap, 0, height, bits, info, wUsage);
275
276         /* Origin for DIBitmap may be bottom left (positive biHeight) or top
277            left (negative biHeight) */
278         StretchBlt( hdc, xDst, yDst, widthDst, heightDst,
279                     hdcMem, xSrc, abs(height) - heightSrc - ySrc,
280                     widthSrc, heightSrc, dwRop );
281         if(hpal)
282             SelectPalette(hdcMem, hpal, FALSE);
283         SelectObject( hdcMem, hOldBitmap );
284         DeleteDC( hdcMem );
285         DeleteObject( hBitmap );
286     }
287     return heightSrc;
288 }
289
290
291 /******************************************************************************
292  * SetDIBits [GDI32.@]
293  *
294  * Sets pixels in a bitmap using colors from DIB.
295  *
296  * PARAMS
297  *    hdc       [I] Handle to device context
298  *    hbitmap   [I] Handle to bitmap
299  *    startscan [I] Starting scan line
300  *    lines     [I] Number of scan lines
301  *    bits      [I] Array of bitmap bits
302  *    info      [I] Address of structure with data
303  *    coloruse  [I] Type of color indexes to use
304  *
305  * RETURNS
306  *    Success: Number of scan lines copied
307  *    Failure: 0
308  */
309 INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
310                       UINT lines, LPCVOID bits, const BITMAPINFO *info,
311                       UINT coloruse )
312 {
313     DC *dc;
314     BITMAPOBJ *bitmap;
315     INT result = 0;
316
317     if (!(bitmap = GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
318
319     if (!(dc = DC_GetDCUpdate( hdc )))
320     {
321         if (coloruse == DIB_RGB_COLORS) FIXME( "shouldn't require a DC for DIB_RGB_COLORS\n" );
322         GDI_ReleaseObj( hbitmap );
323         return 0;
324     }
325
326     if (!bitmap->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) goto done;
327
328     if (bitmap->funcs && bitmap->funcs->pSetDIBits)
329         result = bitmap->funcs->pSetDIBits( dc->physDev, hbitmap, startscan, lines,
330                                             bits, info, coloruse );
331     else
332         result = lines;
333
334  done:
335     GDI_ReleaseObj( hdc );
336     GDI_ReleaseObj( hbitmap );
337     return result;
338 }
339
340
341 /***********************************************************************
342  *           SetDIBitsToDevice   (GDI32.@)
343  */
344 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
345                            DWORD cy, INT xSrc, INT ySrc, UINT startscan,
346                            UINT lines, LPCVOID bits, const BITMAPINFO *info,
347                            UINT coloruse )
348 {
349     INT ret;
350     DC *dc;
351
352     if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
353
354     if(dc->funcs->pSetDIBitsToDevice)
355         ret = dc->funcs->pSetDIBitsToDevice( dc->physDev, xDest, yDest, cx, cy, xSrc,
356                                              ySrc, startscan, lines, bits,
357                                              info, coloruse );
358     else {
359         FIXME("unimplemented on hdc %p\n", hdc);
360         ret = 0;
361     }
362
363     GDI_ReleaseObj( hdc );
364     return ret;
365 }
366
367 /***********************************************************************
368  *           SetDIBColorTable    (GDI32.@)
369  */
370 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUAD *colors )
371 {
372     DC * dc;
373     UINT result = 0;
374
375     if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
376
377     if (dc->funcs->pSetDIBColorTable)
378         result = dc->funcs->pSetDIBColorTable(dc->physDev, startpos, entries, colors);
379
380     GDI_ReleaseObj( hdc );
381     return result;
382 }
383
384
385 /***********************************************************************
386  *           GetDIBColorTable    (GDI32.@)
387  */
388 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
389 {
390     DC * dc;
391     UINT result = 0;
392
393     if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
394
395     if (dc->funcs->pGetDIBColorTable)
396         result = dc->funcs->pGetDIBColorTable(dc->physDev, startpos, entries, colors);
397
398     GDI_ReleaseObj( hdc );
399     return result;
400 }
401
402 /* FIXME the following two structs should be combined with __sysPalTemplate in
403    objects/color.c - this should happen after de-X11-ing both of these
404    files.
405    NB. RGBQUAD and PALETTEENTRY have different orderings of red, green
406    and blue - sigh */
407
408 static RGBQUAD EGAColorsQuads[16] = {
409 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
410     { 0x00, 0x00, 0x00, 0x00 },
411     { 0x00, 0x00, 0x80, 0x00 },
412     { 0x00, 0x80, 0x00, 0x00 },
413     { 0x00, 0x80, 0x80, 0x00 },
414     { 0x80, 0x00, 0x00, 0x00 },
415     { 0x80, 0x00, 0x80, 0x00 },
416     { 0x80, 0x80, 0x00, 0x00 },
417     { 0x80, 0x80, 0x80, 0x00 },
418     { 0xc0, 0xc0, 0xc0, 0x00 },
419     { 0x00, 0x00, 0xff, 0x00 },
420     { 0x00, 0xff, 0x00, 0x00 },
421     { 0x00, 0xff, 0xff, 0x00 },
422     { 0xff, 0x00, 0x00, 0x00 },
423     { 0xff, 0x00, 0xff, 0x00 },
424     { 0xff, 0xff, 0x00, 0x00 },
425     { 0xff, 0xff, 0xff, 0x00 }
426 };
427
428 static RGBTRIPLE EGAColorsTriples[16] = {
429 /* rgbBlue, rgbGreen, rgbRed */
430     { 0x00, 0x00, 0x00 },
431     { 0x00, 0x00, 0x80 },
432     { 0x00, 0x80, 0x00 },
433     { 0x00, 0x80, 0x80 },
434     { 0x80, 0x00, 0x00 },
435     { 0x80, 0x00, 0x80 },
436     { 0x80, 0x80, 0x00 },
437     { 0x80, 0x80, 0x80 },
438     { 0xc0, 0xc0, 0xc0 },
439     { 0x00, 0x00, 0xff },
440     { 0x00, 0xff, 0x00 },
441     { 0x00, 0xff, 0xff },
442     { 0xff, 0x00, 0x00 } ,
443     { 0xff, 0x00, 0xff },
444     { 0xff, 0xff, 0x00 },
445     { 0xff, 0xff, 0xff }
446 };
447
448 static RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
449 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
450     { 0x00, 0x00, 0x00, 0x00 },
451     { 0x00, 0x00, 0x80, 0x00 },
452     { 0x00, 0x80, 0x00, 0x00 },
453     { 0x00, 0x80, 0x80, 0x00 },
454     { 0x80, 0x00, 0x00, 0x00 },
455     { 0x80, 0x00, 0x80, 0x00 },
456     { 0x80, 0x80, 0x00, 0x00 },
457     { 0xc0, 0xc0, 0xc0, 0x00 },
458     { 0xc0, 0xdc, 0xc0, 0x00 },
459     { 0xf0, 0xca, 0xa6, 0x00 },
460     { 0xf0, 0xfb, 0xff, 0x00 },
461     { 0xa4, 0xa0, 0xa0, 0x00 },
462     { 0x80, 0x80, 0x80, 0x00 },
463     { 0x00, 0x00, 0xf0, 0x00 },
464     { 0x00, 0xff, 0x00, 0x00 },
465     { 0x00, 0xff, 0xff, 0x00 },
466     { 0xff, 0x00, 0x00, 0x00 },
467     { 0xff, 0x00, 0xff, 0x00 },
468     { 0xff, 0xff, 0x00, 0x00 },
469     { 0xff, 0xff, 0xff, 0x00 }
470 };
471
472 static RGBTRIPLE DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
473 /* rgbBlue, rgbGreen, rgbRed */
474     { 0x00, 0x00, 0x00 },
475     { 0x00, 0x00, 0x80 },
476     { 0x00, 0x80, 0x00 },
477     { 0x00, 0x80, 0x80 },
478     { 0x80, 0x00, 0x00 },
479     { 0x80, 0x00, 0x80 },
480     { 0x80, 0x80, 0x00 },
481     { 0xc0, 0xc0, 0xc0 },
482     { 0xc0, 0xdc, 0xc0 },
483     { 0xf0, 0xca, 0xa6 },
484     { 0xf0, 0xfb, 0xff },
485     { 0xa4, 0xa0, 0xa0 },
486     { 0x80, 0x80, 0x80 },
487     { 0x00, 0x00, 0xf0 },
488     { 0x00, 0xff, 0x00 },
489     { 0x00, 0xff, 0xff },
490     { 0xff, 0x00, 0x00 },
491     { 0xff, 0x00, 0xff },
492     { 0xff, 0xff, 0x00 },
493     { 0xff, 0xff, 0xff}
494 };
495
496
497 /******************************************************************************
498  * GetDIBits [GDI32.@]
499  *
500  * Retrieves bits of bitmap and copies to buffer.
501  *
502  * RETURNS
503  *    Success: Number of scan lines copied from bitmap
504  *    Failure: 0
505  *
506  * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_87eb.asp
507  */
508 INT WINAPI GetDIBits(
509     HDC hdc,         /* [in]  Handle to device context */
510     HBITMAP hbitmap, /* [in]  Handle to bitmap */
511     UINT startscan,  /* [in]  First scan line to set in dest bitmap */
512     UINT lines,      /* [in]  Number of scan lines to copy */
513     LPVOID bits,       /* [out] Address of array for bitmap bits */
514     BITMAPINFO * info, /* [out] Address of structure with bitmap data */
515     UINT coloruse)   /* [in]  RGB or palette index */
516 {
517     DC * dc;
518     BITMAPOBJ * bmp;
519     int i;
520     HDC memdc;
521     int bitmap_type;
522     BOOL core_header;
523     LONG width;
524     LONG height;
525     WORD bpp;
526     DWORD compr;
527     void* colorPtr;
528     RGBTRIPLE* rgbTriples;
529     RGBQUAD* rgbQuads;
530
531     if (!info) return 0;
532
533     bitmap_type = DIB_GetBitmapInfo( (BITMAPINFOHEADER*) info, &width, &height, &bpp, &compr);
534     if (bitmap_type == -1)
535     {
536         ERR("Invalid bitmap format\n");
537         return 0;
538     }
539     core_header = (bitmap_type == 0);
540     memdc = CreateCompatibleDC(hdc);
541     if (!(dc = DC_GetDCUpdate( hdc )))
542     {
543         DeleteDC(memdc);
544         return 0;
545     }
546     if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
547     {
548         GDI_ReleaseObj( hdc );
549         DeleteDC(memdc);
550         return 0;
551     }
552
553     colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
554     rgbTriples = (RGBTRIPLE *) colorPtr;
555     rgbQuads = (RGBQUAD *) colorPtr;
556
557     /* Transfer color info */
558
559     if (bpp <= 8 && bpp > 0)
560     {
561         if (!core_header) info->bmiHeader.biClrUsed = 0;
562
563         /* If the bitmap object already has a dib section at the
564            same color depth then get the color map from it */
565         if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == bpp) {
566             if(coloruse == DIB_RGB_COLORS) {
567                 HBITMAP oldbm = SelectObject(memdc, hbitmap);
568                 unsigned int colors = 1 << bpp;
569
570                 if (core_header)
571                 {
572                     /* Convert the color table (RGBQUAD to RGBTRIPLE) */                    
573                     RGBQUAD* buffer = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD));
574
575                     if (buffer)
576                     {
577                         RGBTRIPLE* index = rgbTriples;
578                         GetDIBColorTable(memdc, 0, colors, buffer);
579
580                         for (i=0; i < colors; i++, index++)
581                         {
582                             index->rgbtRed   = buffer[i].rgbRed;
583                             index->rgbtGreen = buffer[i].rgbGreen;
584                             index->rgbtBlue  = buffer[i].rgbBlue;
585                         }
586
587                         HeapFree(GetProcessHeap(), 0, buffer);
588                     }
589                 }
590                 else
591                 {
592                     GetDIBColorTable(memdc, 0, colors, colorPtr);
593                 }
594                 SelectObject(memdc, oldbm);
595             }
596             else {
597                 WORD *index = colorPtr;
598                 for(i = 0; i < 1 << info->bmiHeader.biBitCount; i++, index++)
599                     *index = i;
600             }
601         }
602         else {
603             if(bpp >= bmp->bitmap.bmBitsPixel) {
604                 /* Generate the color map from the selected palette */
605                 PALETTEENTRY * palEntry;
606                 PALETTEOBJ * palette;
607                 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC ))) {
608                     GDI_ReleaseObj( hdc );
609                     GDI_ReleaseObj( hbitmap );
610                     DeleteDC(memdc);
611                     return 0;
612                 }
613                 palEntry = palette->logpalette.palPalEntry;
614                 for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++, palEntry++) {
615                     if (coloruse == DIB_RGB_COLORS) {
616                         if (core_header)
617                         {
618                             rgbTriples[i].rgbtRed   = palEntry->peRed;
619                             rgbTriples[i].rgbtGreen = palEntry->peGreen;
620                             rgbTriples[i].rgbtBlue  = palEntry->peBlue;
621                         }
622                         else
623                         {
624                             rgbQuads[i].rgbRed      = palEntry->peRed;
625                             rgbQuads[i].rgbGreen    = palEntry->peGreen;
626                             rgbQuads[i].rgbBlue     = palEntry->peBlue;
627                             rgbQuads[i].rgbReserved = 0;
628                         }
629                     }
630                     else ((WORD *)colorPtr)[i] = (WORD)i;
631                 }
632                 GDI_ReleaseObj( dc->hPalette );
633             } else {
634                 switch (bpp) {
635                 case 1:
636                     if (core_header)
637                     {
638                         rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
639                             rgbTriples[0].rgbtBlue = 0;
640                         rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
641                             rgbTriples[1].rgbtBlue = 0xff;
642                     }
643                     else
644                     {    
645                         rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
646                             rgbQuads[0].rgbBlue = 0;
647                         rgbQuads[0].rgbReserved = 0;
648                         rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
649                             rgbQuads[1].rgbBlue = 0xff;
650                         rgbQuads[1].rgbReserved = 0;
651                     }
652                     break;
653
654                 case 4:
655                     if (core_header)
656                         memcpy(colorPtr, EGAColorsTriples, sizeof(EGAColorsTriples));
657                     else
658                         memcpy(colorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
659
660                     break;
661
662                 case 8:
663                     {
664                         if (core_header)
665                         {
666                             INT r, g, b;
667                             RGBTRIPLE *color;
668
669                             memcpy(rgbTriples, DefLogPaletteTriples,
670                                        10 * sizeof(RGBTRIPLE));
671                             memcpy(rgbTriples + 246, DefLogPaletteTriples + 10,
672                                        10 * sizeof(RGBTRIPLE));
673                             color = rgbTriples + 10;
674                             for(r = 0; r <= 5; r++) /* FIXME */
675                                 for(g = 0; g <= 5; g++)
676                                     for(b = 0; b <= 5; b++) {
677                                         color->rgbtRed =   (r * 0xff) / 5;
678                                         color->rgbtGreen = (g * 0xff) / 5;
679                                         color->rgbtBlue =  (b * 0xff) / 5;
680                                         color++;
681                                     }
682                         }
683                         else
684                         {
685                             INT r, g, b;
686                             RGBQUAD *color;
687
688                             memcpy(rgbQuads, DefLogPaletteQuads,
689                                        10 * sizeof(RGBQUAD));
690                             memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
691                                    10 * sizeof(RGBQUAD));
692                             color = rgbQuads + 10;
693                             for(r = 0; r <= 5; r++) /* FIXME */
694                                 for(g = 0; g <= 5; g++)
695                                     for(b = 0; b <= 5; b++) {
696                                         color->rgbRed =   (r * 0xff) / 5;
697                                         color->rgbGreen = (g * 0xff) / 5;
698                                         color->rgbBlue =  (b * 0xff) / 5;
699                                         color->rgbReserved = 0;
700                                         color++;
701                                     }
702                         }
703                     }
704                 }
705             }
706         }
707     }
708
709     if (bits && lines)
710     {
711         /* If the bitmap object already have a dib section that contains image data, get the bits from it */
712         if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
713         {
714             /*FIXME: Only RGB dibs supported for now */
715             unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb = bmp->dib->dsBm.bmWidthBytes;
716             unsigned int dstwidth = width;
717             int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
718             LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
719             unsigned int x, y, width, widthb;
720
721             if ((height < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
722             {
723                 dbits = (LPBYTE)bits + (dstwidthb * (lines-1));
724                 dstwidthb = -dstwidthb;
725             }
726
727             switch( bpp ) {
728
729             case 15:
730             case 16: /* 16 bpp dstDIB */
731                 {
732                     LPWORD dstbits = (LPWORD)dbits;
733                     WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
734
735                     /* FIXME: BI_BITFIELDS not supported yet */
736
737                     switch(bmp->dib->dsBm.bmBitsPixel) {
738
739                     case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
740                         {
741                             widthb = min(srcwidthb, abs(dstwidthb));
742                             /* FIXME: BI_BITFIELDS not supported yet */
743                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
744                                 memcpy(dbits, sbits, widthb);
745                         }
746                         break;
747
748                     case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
749                         {
750                             LPBYTE srcbits = sbits;
751
752                             width = min(srcwidth, dstwidth);
753                             for( y = 0; y < lines; y++) {
754                                 for( x = 0; x < width; x++, srcbits += 3)
755                                     *dstbits++ = ((srcbits[0] >> 3) & bmask) |
756                                                  (((WORD)srcbits[1] << 2) & gmask) |
757                                                  (((WORD)srcbits[2] << 7) & rmask);
758
759                                 dstbits = (LPWORD)(dbits+=dstwidthb);
760                                 srcbits = (sbits += srcwidthb);
761                             }
762                         }
763                         break;
764
765                     case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
766                         {
767                             LPDWORD srcbits = (LPDWORD)sbits;
768                             DWORD val;
769
770                             width = min(srcwidth, dstwidth);
771                             for( y = 0; y < lines; y++) {
772                                 for( x = 0; x < width; x++ ) {
773                                     val = *srcbits++;
774                                     *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
775                                                        ((val >> 9) & rmask));
776                                 }
777                                 dstbits = (LPWORD)(dbits+=dstwidthb);
778                                 srcbits = (LPDWORD)(sbits+=srcwidthb);
779                             }
780                         }
781                         break;
782
783                     default: /* ? bit bmp -> 16 bit DIB */
784                         FIXME("15/16 bit DIB %d bit bitmap\n",
785                         bmp->bitmap.bmBitsPixel);
786                         break;
787                     }
788                 }
789                 break;
790
791             case 24: /* 24 bpp dstDIB */
792                 {
793                     LPBYTE dstbits = dbits;
794
795                     switch(bmp->dib->dsBm.bmBitsPixel) {
796
797                     case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
798                         {
799                             LPWORD srcbits = (LPWORD)sbits;
800                             WORD val;
801
802                             width = min(srcwidth, dstwidth);
803                             /* FIXME: BI_BITFIELDS not supported yet */
804                             for( y = 0; y < lines; y++) {
805                                 for( x = 0; x < width; x++ ) {
806                                     val = *srcbits++;
807                                     *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
808                                     *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
809                                     *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
810                                 }
811                                 dstbits = (LPBYTE)(dbits+=dstwidthb);
812                                 srcbits = (LPWORD)(sbits+=srcwidthb);
813                             }
814                         }
815                         break;
816
817                     case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
818                         {
819                             widthb = min(srcwidthb, abs(dstwidthb));
820                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
821                                 memcpy(dbits, sbits, widthb);
822                         }
823                         break;
824
825                     case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
826                         {
827                             LPBYTE srcbits = (LPBYTE)sbits;
828
829                             width = min(srcwidth, dstwidth);
830                             for( y = 0; y < lines; y++) {
831                                 for( x = 0; x < width; x++, srcbits++ ) {
832                                     *dstbits++ = *srcbits++;
833                                     *dstbits++ = *srcbits++;
834                                     *dstbits++ = *srcbits++;
835                                 }
836                                 dstbits=(LPBYTE)(dbits+=dstwidthb);
837                                 srcbits = (LPBYTE)(sbits+=srcwidthb);
838                             }
839                         }
840                         break;
841
842                     default: /* ? bit bmp -> 24 bit DIB */
843                         FIXME("24 bit DIB %d bit bitmap\n",
844                               bmp->bitmap.bmBitsPixel);
845                         break;
846                     }
847                 }
848                 break;
849
850             case 32: /* 32 bpp dstDIB */
851                 {
852                     LPDWORD dstbits = (LPDWORD)dbits;
853
854                     /* FIXME: BI_BITFIELDS not supported yet */
855
856                     switch(bmp->dib->dsBm.bmBitsPixel) {
857                         case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
858                         {
859                             LPWORD srcbits = (LPWORD)sbits;
860                             DWORD val;
861
862                             width = min(srcwidth, dstwidth);
863                             /* FIXME: BI_BITFIELDS not supported yet */
864                             for( y = 0; y < lines; y++) {
865                                 for( x = 0; x < width; x++ ) {
866                                     val = (DWORD)*srcbits++;
867                                     *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
868                                                  ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
869                                                  ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
870                                 }
871                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
872                                 srcbits=(LPWORD)(sbits+=srcwidthb);
873                             }
874                         }
875                         break;
876
877                     case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
878                         {
879                             LPBYTE srcbits = sbits;
880
881                             width = min(srcwidth, dstwidth);
882                             for( y = 0; y < lines; y++) {
883                                 for( x = 0; x < width; x++, srcbits+=3 )
884                                     *dstbits++ = ((DWORD)*srcbits) & 0x00ffffff;
885                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
886                                 srcbits=(sbits+=srcwidthb);
887                             }
888                         }
889                         break;
890
891                     case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
892                         {
893                             widthb = min(srcwidthb, abs(dstwidthb));
894                             /* FIXME: BI_BITFIELDS not supported yet */
895                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
896                                 memcpy(dbits, sbits, widthb);
897                             }
898                         }
899                         break;
900
901                     default: /* ? bit bmp -> 32 bit DIB */
902                         FIXME("32 bit DIB %d bit bitmap\n",
903                         bmp->bitmap.bmBitsPixel);
904                         break;
905                     }
906                 }
907                 break;
908
909             default: /* ? bit DIB */
910                 FIXME("Unsupported DIB depth %d\n", info->bmiHeader.biBitCount);
911                 break;
912             }
913         }
914         /* Otherwise, get bits from the XImage */
915         else
916         {
917             if (!bmp->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) lines = 0;
918             else
919             {
920                 if (bmp->funcs && bmp->funcs->pGetDIBits)
921                     lines = bmp->funcs->pGetDIBits( dc->physDev, hbitmap, startscan,
922                                                     lines, bits, info, coloruse );
923                 else
924                     lines = 0;  /* FIXME: should copy from bmp->bitmap.bmBits */
925             }
926         }
927     }
928     else
929     {
930         /* fill in struct members */
931
932         if (bpp == 0)
933         {
934             if (core_header)
935             {
936                 BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
937                 coreheader->bcWidth = bmp->bitmap.bmWidth;
938                 coreheader->bcHeight = bmp->bitmap.bmHeight;
939                 coreheader->bcPlanes = 1;
940                 coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
941             }
942             else
943             {
944                 info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
945                 info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
946                 info->bmiHeader.biPlanes = 1;
947                 info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
948                 info->bmiHeader.biSizeImage =
949                                  DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
950                                                        bmp->bitmap.bmHeight,
951                                                        bmp->bitmap.bmBitsPixel );
952                 info->bmiHeader.biCompression = 0;
953             }
954             lines = abs(bmp->bitmap.bmHeight);
955         }
956     }
957
958     if (!core_header)
959     {
960         TRACE("biSizeImage = %ld, ", info->bmiHeader.biSizeImage);
961     }
962     TRACE("biWidth = %ld, biHeight = %ld\n", width, height);
963
964     GDI_ReleaseObj( hdc );
965     GDI_ReleaseObj( hbitmap );
966     DeleteDC(memdc);
967     return lines;
968 }
969
970
971 /***********************************************************************
972  *           CreateDIBitmap    (GDI32.@)
973  *
974  * Creates a DDB (device dependent bitmap) from a DIB.
975  * The DDB will have the same color depth as the reference DC.
976  */
977 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
978                             DWORD init, LPCVOID bits, const BITMAPINFO *data,
979                             UINT coloruse )
980 {
981     HBITMAP handle;
982     LONG width;
983     LONG height;
984     WORD bpp;
985     DWORD compr;
986     DC *dc;
987
988     if (DIB_GetBitmapInfo( header, &width, &height, &bpp, &compr ) == -1) return 0;
989     
990     if (width < 0)
991     {
992         TRACE("Bitmap has a negative width\n");
993         return 0;
994     }
995     
996     /* Top-down DIBs have a negative height */
997     if (height < 0) height = -height;
998
999     TRACE("hdc=%p, header=%p, init=%lu, bits=%p, data=%p, coloruse=%u (bitmap: width=%ld, height=%ld, bpp=%u, compr=%lu)\n",
1000            hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
1001     
1002     if (hdc == NULL)
1003         handle = CreateBitmap( width, height, 1, 1, NULL );
1004     else
1005         handle = CreateCompatibleBitmap( hdc, width, height );
1006
1007     if (handle)
1008     {
1009         if (init == CBM_INIT) SetDIBits( hdc, handle, 0, height, bits, data, coloruse );
1010
1011         else if (hdc && ((dc = DC_GetDCPtr( hdc )) != NULL) )
1012         {
1013             if (!BITMAP_SetOwnerDC( handle, dc ))
1014             {
1015                 DeleteObject( handle );
1016                 handle = 0;
1017             }
1018             GDI_ReleaseObj( hdc );
1019         }
1020     }
1021
1022     return handle;
1023 }
1024
1025 /***********************************************************************
1026  *           CreateDIBSection    (GDI.489)
1027  */
1028 HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, const BITMAPINFO *bmi, UINT16 usage,
1029                                      SEGPTR *bits16, HANDLE section, DWORD offset)
1030 {
1031     LPVOID bits32;
1032     HBITMAP hbitmap;
1033
1034     hbitmap = CreateDIBSection( HDC_32(hdc), bmi, usage, &bits32, section, offset );
1035     if (hbitmap)
1036     {
1037         BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(hbitmap, BITMAP_MAGIC);
1038         if (bmp && bmp->dib && bits32)
1039         {
1040             const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
1041             LONG width, height;
1042             WORD bpp;
1043             DWORD compr;
1044             BOOL core_header;
1045             INT width_bytes;
1046             INT size;
1047             WORD count, sel;
1048             int i;
1049
1050             core_header = (DIB_GetBitmapInfo(bi, &width, &height, &bpp, &compr) == 0);
1051
1052             height = height >= 0 ? height : -height;
1053             width_bytes = DIB_GetDIBWidthBytes(width, bpp);
1054             
1055             if (core_header)
1056             {
1057                 size = width_bytes * height;
1058             }
1059             else
1060             {
1061                 size = (bi->biSizeImage && compr != BI_RGB) ?
1062                         bi->biSizeImage : width_bytes * height;
1063             }
1064
1065             /* calculate number of sel's needed for size with 64K steps */
1066             count = (size + 0xffff) / 0x10000;
1067             sel = AllocSelectorArray16(count);
1068
1069             for (i = 0; i < count; i++)
1070             {
1071                 SetSelectorBase(sel + (i << __AHSHIFT), (DWORD)bits32 + i * 0x10000);
1072                 SetSelectorLimit16(sel + (i << __AHSHIFT), size - 1); /* yep, limit is correct */
1073                 size -= 0x10000;
1074             }
1075             bmp->segptr_bits = MAKESEGPTR( sel, 0 );
1076             if (bits16) *bits16 = bmp->segptr_bits;
1077         }
1078         if (bmp) GDI_ReleaseObj( hbitmap );
1079     }
1080     return HBITMAP_16(hbitmap);
1081 }
1082
1083 /***********************************************************************
1084  *           DIB_CreateDIBSection
1085  */
1086 HBITMAP DIB_CreateDIBSection(HDC hdc, const BITMAPINFO *bmi, UINT usage,
1087                              VOID **bits, HANDLE section,
1088                              DWORD offset, DWORD ovr_pitch)
1089 {
1090     HBITMAP hbitmap = 0;
1091     DC *dc;
1092     BOOL bDesktopDC = FALSE;
1093
1094     /* If the reference hdc is null, take the desktop dc */
1095     if (hdc == 0)
1096     {
1097         hdc = CreateCompatibleDC(0);
1098         bDesktopDC = TRUE;
1099     }
1100
1101     if ((dc = DC_GetDCPtr( hdc )))
1102     {
1103         if(dc->funcs->pCreateDIBSection)
1104             hbitmap = dc->funcs->pCreateDIBSection(dc->physDev, bmi, usage, bits, section, offset, ovr_pitch);
1105         GDI_ReleaseObj(hdc);
1106     }
1107
1108     if (bDesktopDC)
1109       DeleteDC(hdc);
1110
1111     return hbitmap;
1112 }
1113
1114 /***********************************************************************
1115  *           CreateDIBSection    (GDI32.@)
1116  */
1117 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1118                                 VOID **bits, HANDLE section,
1119                                 DWORD offset)
1120 {
1121     return DIB_CreateDIBSection(hdc, bmi, usage, bits, section, offset, 0);
1122 }