wordpad: Allow objects & images to be added with native riched20.
[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     unsigned int colors, size, 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         size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
143         return size + colors * ((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 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, OBJ_BITMAP )))
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 = get_dc_ptr( hdc );
336     BOOL delete_hdc = FALSE;
337     BITMAPOBJ *bitmap;
338     INT result = 0;
339
340     if (coloruse == DIB_RGB_COLORS && !dc)
341     {
342         hdc = CreateCompatibleDC(0);
343         dc = get_dc_ptr( hdc );
344         delete_hdc = TRUE;
345     }
346
347     if (!dc) return 0;
348
349     update_dc( dc );
350
351     if (!(bitmap = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
352     {
353         release_dc_ptr( dc );
354         if (delete_hdc) DeleteDC(hdc);
355         return 0;
356     }
357
358     if (!bitmap->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) goto done;
359
360     result = lines;
361     if (bitmap->funcs)
362     {
363         if (bitmap->funcs != dc->funcs)
364             ERR( "not supported: DDB bitmap %p not belonging to device %p\n", hbitmap, hdc );
365         else if (dc->funcs->pSetDIBits)
366             result = dc->funcs->pSetDIBits( dc->physDev, hbitmap, startscan, lines,
367                                             bits, info, coloruse );
368     }
369
370  done:
371     GDI_ReleaseObj( hbitmap );
372     release_dc_ptr( dc );
373     if (delete_hdc) DeleteDC(hdc);
374     return result;
375 }
376
377
378 /***********************************************************************
379  *           SetDIBitsToDevice   (GDI32.@)
380  */
381 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
382                            DWORD cy, INT xSrc, INT ySrc, UINT startscan,
383                            UINT lines, LPCVOID bits, const BITMAPINFO *info,
384                            UINT coloruse )
385 {
386     INT ret;
387     DC *dc;
388
389     if (!bits) return 0;
390
391     if (!(dc = get_dc_ptr( hdc ))) return 0;
392
393     if(dc->funcs->pSetDIBitsToDevice)
394     {
395         update_dc( dc );
396         ret = dc->funcs->pSetDIBitsToDevice( dc->physDev, xDest, yDest, cx, cy, xSrc,
397                                              ySrc, startscan, lines, bits,
398                                              info, coloruse );
399     }
400     else {
401         FIXME("unimplemented on hdc %p\n", hdc);
402         ret = 0;
403     }
404
405     release_dc_ptr( dc );
406     return ret;
407 }
408
409 /***********************************************************************
410  *           SetDIBColorTable    (GDI32.@)
411  */
412 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUAD *colors )
413 {
414     DC * dc;
415     UINT result = 0;
416     BITMAPOBJ * bitmap;
417
418     if (!(dc = get_dc_ptr( hdc ))) return 0;
419
420     if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
421     {
422         /* Check if currently selected bitmap is a DIB */
423         if (bitmap->color_table)
424         {
425             if (startpos < bitmap->nb_colors)
426             {
427                 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
428                 memcpy(bitmap->color_table + startpos, colors, entries * sizeof(RGBQUAD));
429                 result = entries;
430             }
431         }
432         GDI_ReleaseObj( dc->hBitmap );
433     }
434
435     if (dc->funcs->pSetDIBColorTable)
436         dc->funcs->pSetDIBColorTable(dc->physDev, startpos, entries, colors);
437
438     release_dc_ptr( dc );
439     return result;
440 }
441
442
443 /***********************************************************************
444  *           GetDIBColorTable    (GDI32.@)
445  */
446 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
447 {
448     DC * dc;
449     UINT result = 0;
450
451     if (!(dc = get_dc_ptr( hdc ))) return 0;
452
453     if (dc->funcs->pGetDIBColorTable)
454         result = dc->funcs->pGetDIBColorTable(dc->physDev, startpos, entries, colors);
455     else
456     {
457         BITMAPOBJ *bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP );
458         if (bitmap)
459         {
460             /* Check if currently selected bitmap is a DIB */
461             if (bitmap->color_table)
462             {
463                 if (startpos < bitmap->nb_colors)
464                 {
465                     if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
466                     memcpy(colors, bitmap->color_table + startpos, entries * sizeof(RGBQUAD));
467                     result = entries;
468                 }
469             }
470             GDI_ReleaseObj( dc->hBitmap );
471         }
472     }
473     release_dc_ptr( dc );
474     return result;
475 }
476
477 /* FIXME the following two structs should be combined with __sysPalTemplate in
478    objects/color.c - this should happen after de-X11-ing both of these
479    files.
480    NB. RGBQUAD and PALETTEENTRY have different orderings of red, green
481    and blue - sigh */
482
483 static const RGBQUAD EGAColorsQuads[16] = {
484 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
485     { 0x00, 0x00, 0x00, 0x00 },
486     { 0x00, 0x00, 0x80, 0x00 },
487     { 0x00, 0x80, 0x00, 0x00 },
488     { 0x00, 0x80, 0x80, 0x00 },
489     { 0x80, 0x00, 0x00, 0x00 },
490     { 0x80, 0x00, 0x80, 0x00 },
491     { 0x80, 0x80, 0x00, 0x00 },
492     { 0x80, 0x80, 0x80, 0x00 },
493     { 0xc0, 0xc0, 0xc0, 0x00 },
494     { 0x00, 0x00, 0xff, 0x00 },
495     { 0x00, 0xff, 0x00, 0x00 },
496     { 0x00, 0xff, 0xff, 0x00 },
497     { 0xff, 0x00, 0x00, 0x00 },
498     { 0xff, 0x00, 0xff, 0x00 },
499     { 0xff, 0xff, 0x00, 0x00 },
500     { 0xff, 0xff, 0xff, 0x00 }
501 };
502
503 static const RGBTRIPLE EGAColorsTriples[16] = {
504 /* rgbBlue, rgbGreen, rgbRed */
505     { 0x00, 0x00, 0x00 },
506     { 0x00, 0x00, 0x80 },
507     { 0x00, 0x80, 0x00 },
508     { 0x00, 0x80, 0x80 },
509     { 0x80, 0x00, 0x00 },
510     { 0x80, 0x00, 0x80 },
511     { 0x80, 0x80, 0x00 },
512     { 0x80, 0x80, 0x80 },
513     { 0xc0, 0xc0, 0xc0 },
514     { 0x00, 0x00, 0xff },
515     { 0x00, 0xff, 0x00 },
516     { 0x00, 0xff, 0xff },
517     { 0xff, 0x00, 0x00 } ,
518     { 0xff, 0x00, 0xff },
519     { 0xff, 0xff, 0x00 },
520     { 0xff, 0xff, 0xff }
521 };
522
523 static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
524 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
525     { 0x00, 0x00, 0x00, 0x00 },
526     { 0x00, 0x00, 0x80, 0x00 },
527     { 0x00, 0x80, 0x00, 0x00 },
528     { 0x00, 0x80, 0x80, 0x00 },
529     { 0x80, 0x00, 0x00, 0x00 },
530     { 0x80, 0x00, 0x80, 0x00 },
531     { 0x80, 0x80, 0x00, 0x00 },
532     { 0xc0, 0xc0, 0xc0, 0x00 },
533     { 0xc0, 0xdc, 0xc0, 0x00 },
534     { 0xf0, 0xca, 0xa6, 0x00 },
535     { 0xf0, 0xfb, 0xff, 0x00 },
536     { 0xa4, 0xa0, 0xa0, 0x00 },
537     { 0x80, 0x80, 0x80, 0x00 },
538     { 0x00, 0x00, 0xf0, 0x00 },
539     { 0x00, 0xff, 0x00, 0x00 },
540     { 0x00, 0xff, 0xff, 0x00 },
541     { 0xff, 0x00, 0x00, 0x00 },
542     { 0xff, 0x00, 0xff, 0x00 },
543     { 0xff, 0xff, 0x00, 0x00 },
544     { 0xff, 0xff, 0xff, 0x00 }
545 };
546
547 static const RGBTRIPLE DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
548 /* rgbBlue, rgbGreen, rgbRed */
549     { 0x00, 0x00, 0x00 },
550     { 0x00, 0x00, 0x80 },
551     { 0x00, 0x80, 0x00 },
552     { 0x00, 0x80, 0x80 },
553     { 0x80, 0x00, 0x00 },
554     { 0x80, 0x00, 0x80 },
555     { 0x80, 0x80, 0x00 },
556     { 0xc0, 0xc0, 0xc0 },
557     { 0xc0, 0xdc, 0xc0 },
558     { 0xf0, 0xca, 0xa6 },
559     { 0xf0, 0xfb, 0xff },
560     { 0xa4, 0xa0, 0xa0 },
561     { 0x80, 0x80, 0x80 },
562     { 0x00, 0x00, 0xf0 },
563     { 0x00, 0xff, 0x00 },
564     { 0x00, 0xff, 0xff },
565     { 0xff, 0x00, 0x00 },
566     { 0xff, 0x00, 0xff },
567     { 0xff, 0xff, 0x00 },
568     { 0xff, 0xff, 0xff}
569 };
570
571
572 /******************************************************************************
573  * GetDIBits [GDI32.@]
574  *
575  * Retrieves bits of bitmap and copies to buffer.
576  *
577  * RETURNS
578  *    Success: Number of scan lines copied from bitmap
579  *    Failure: 0
580  */
581 INT WINAPI GetDIBits(
582     HDC hdc,         /* [in]  Handle to device context */
583     HBITMAP hbitmap, /* [in]  Handle to bitmap */
584     UINT startscan,  /* [in]  First scan line to set in dest bitmap */
585     UINT lines,      /* [in]  Number of scan lines to copy */
586     LPVOID bits,       /* [out] Address of array for bitmap bits */
587     BITMAPINFO * info, /* [out] Address of structure with bitmap data */
588     UINT coloruse)   /* [in]  RGB or palette index */
589 {
590     DC * dc;
591     BITMAPOBJ * bmp;
592     int i;
593     int bitmap_type;
594     BOOL core_header;
595     LONG width;
596     LONG height;
597     WORD planes, bpp;
598     DWORD compr, size;
599     void* colorPtr;
600     RGBTRIPLE* rgbTriples;
601     RGBQUAD* rgbQuads;
602
603     if (!info) return 0;
604
605     bitmap_type = DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size);
606     if (bitmap_type == -1)
607     {
608         ERR("Invalid bitmap format\n");
609         return 0;
610     }
611     core_header = (bitmap_type == 0);
612     if (!(dc = get_dc_ptr( hdc )))
613     {
614         SetLastError( ERROR_INVALID_PARAMETER );
615         return 0;
616     }
617     update_dc( dc );
618     if (!(bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
619     {
620         release_dc_ptr( dc );
621         return 0;
622     }
623
624     colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
625     rgbTriples = colorPtr;
626     rgbQuads = colorPtr;
627
628     /* Transfer color info */
629
630     switch (bpp)
631     {
632     case 0:  /* query bitmap info only */
633         if (core_header)
634         {
635             BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
636             coreheader->bcWidth = bmp->bitmap.bmWidth;
637             coreheader->bcHeight = bmp->bitmap.bmHeight;
638             coreheader->bcPlanes = 1;
639             coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
640         }
641         else
642         {
643             info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
644             info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
645             info->bmiHeader.biPlanes = 1;
646             info->bmiHeader.biSizeImage =
647                 DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
648                                       bmp->bitmap.bmHeight,
649                                       bmp->bitmap.bmBitsPixel );
650             if (bmp->dib)
651             {
652                 info->bmiHeader.biBitCount = bmp->dib->dsBm.bmBitsPixel;
653                 switch (bmp->dib->dsBm.bmBitsPixel)
654                 {
655                 case 16:
656                 case 32:
657                     info->bmiHeader.biCompression = BI_BITFIELDS;
658                     break;
659                 default:
660                     info->bmiHeader.biCompression = BI_RGB;
661                     break;
662                 }
663             }
664             else
665             {
666                 info->bmiHeader.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB;
667                 info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
668             }
669             info->bmiHeader.biXPelsPerMeter = 0;
670             info->bmiHeader.biYPelsPerMeter = 0;
671             info->bmiHeader.biClrUsed = 0;
672             info->bmiHeader.biClrImportant = 0;
673
674             /* Windows 2000 doesn't touch the additional struct members if
675                it's a BITMAPV4HEADER or a BITMAPV5HEADER */
676         }
677         lines = abs(bmp->bitmap.bmHeight);
678         goto done;
679
680     case 1:
681     case 4:
682     case 8:
683         if (!core_header) info->bmiHeader.biClrUsed = 0;
684
685         /* If the bitmap object already has a dib section at the
686            same color depth then get the color map from it */
687         if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == bpp) {
688             if(coloruse == DIB_RGB_COLORS) {
689                 unsigned int colors = min( bmp->nb_colors, 1 << bpp );
690
691                 if (core_header)
692                 {
693                     /* Convert the color table (RGBQUAD to RGBTRIPLE) */
694                     RGBTRIPLE* index = rgbTriples;
695
696                     for (i=0; i < colors; i++, index++)
697                     {
698                         index->rgbtRed   = bmp->color_table[i].rgbRed;
699                         index->rgbtGreen = bmp->color_table[i].rgbGreen;
700                         index->rgbtBlue  = bmp->color_table[i].rgbBlue;
701                     }
702                 }
703                 else
704                 {
705                     if (colors != 1 << bpp) info->bmiHeader.biClrUsed = colors;
706                     memcpy(colorPtr, bmp->color_table, colors * sizeof(RGBQUAD));
707                 }
708             }
709             else {
710                 WORD *index = colorPtr;
711                 for(i = 0; i < 1 << info->bmiHeader.biBitCount; i++, index++)
712                     *index = i;
713             }
714         }
715         else {
716             if (coloruse == DIB_PAL_COLORS) {
717                 for (i = 0; i < (1 << bpp); i++)
718                     ((WORD *)colorPtr)[i] = (WORD)i;
719             }
720             else if(bpp > 1 && bpp == bmp->bitmap.bmBitsPixel) {
721                 /* For color DDBs in native depth (mono DDBs always have
722                    a black/white palette):
723                    Generate the color map from the selected palette */
724                 PALETTEENTRY palEntry[256];
725
726                 memset( palEntry, 0, sizeof(palEntry) );
727                 if (!GetPaletteEntries( dc->hPalette, 0, 1 << bmp->bitmap.bmBitsPixel, palEntry ))
728                 {
729                     release_dc_ptr( dc );
730                     GDI_ReleaseObj( hbitmap );
731                     return 0;
732                 }
733                 for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++) {
734                     if (core_header)
735                     {
736                         rgbTriples[i].rgbtRed   = palEntry[i].peRed;
737                         rgbTriples[i].rgbtGreen = palEntry[i].peGreen;
738                         rgbTriples[i].rgbtBlue  = palEntry[i].peBlue;
739                     }
740                     else
741                     {
742                         rgbQuads[i].rgbRed      = palEntry[i].peRed;
743                         rgbQuads[i].rgbGreen    = palEntry[i].peGreen;
744                         rgbQuads[i].rgbBlue     = palEntry[i].peBlue;
745                         rgbQuads[i].rgbReserved = 0;
746                     }
747                 }
748             } else {
749                 switch (bpp) {
750                 case 1:
751                     if (core_header)
752                     {
753                         rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
754                             rgbTriples[0].rgbtBlue = 0;
755                         rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
756                             rgbTriples[1].rgbtBlue = 0xff;
757                     }
758                     else
759                     {    
760                         rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
761                             rgbQuads[0].rgbBlue = 0;
762                         rgbQuads[0].rgbReserved = 0;
763                         rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
764                             rgbQuads[1].rgbBlue = 0xff;
765                         rgbQuads[1].rgbReserved = 0;
766                     }
767                     break;
768
769                 case 4:
770                     if (core_header)
771                         memcpy(colorPtr, EGAColorsTriples, sizeof(EGAColorsTriples));
772                     else
773                         memcpy(colorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
774
775                     break;
776
777                 case 8:
778                     {
779                         if (core_header)
780                         {
781                             INT r, g, b;
782                             RGBTRIPLE *color;
783
784                             memcpy(rgbTriples, DefLogPaletteTriples,
785                                        10 * sizeof(RGBTRIPLE));
786                             memcpy(rgbTriples + 246, DefLogPaletteTriples + 10,
787                                        10 * sizeof(RGBTRIPLE));
788                             color = rgbTriples + 10;
789                             for(r = 0; r <= 5; r++) /* FIXME */
790                                 for(g = 0; g <= 5; g++)
791                                     for(b = 0; b <= 5; b++) {
792                                         color->rgbtRed =   (r * 0xff) / 5;
793                                         color->rgbtGreen = (g * 0xff) / 5;
794                                         color->rgbtBlue =  (b * 0xff) / 5;
795                                         color++;
796                                     }
797                         }
798                         else
799                         {
800                             INT r, g, b;
801                             RGBQUAD *color;
802
803                             memcpy(rgbQuads, DefLogPaletteQuads,
804                                        10 * sizeof(RGBQUAD));
805                             memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
806                                    10 * sizeof(RGBQUAD));
807                             color = rgbQuads + 10;
808                             for(r = 0; r <= 5; r++) /* FIXME */
809                                 for(g = 0; g <= 5; g++)
810                                     for(b = 0; b <= 5; b++) {
811                                         color->rgbRed =   (r * 0xff) / 5;
812                                         color->rgbGreen = (g * 0xff) / 5;
813                                         color->rgbBlue =  (b * 0xff) / 5;
814                                         color->rgbReserved = 0;
815                                         color++;
816                                     }
817                         }
818                     }
819                 }
820             }
821         }
822         break;
823
824     case 15:
825         if (info->bmiHeader.biCompression == BI_BITFIELDS)
826         {
827             ((PDWORD)info->bmiColors)[0] = 0x7c00;
828             ((PDWORD)info->bmiColors)[1] = 0x03e0;
829             ((PDWORD)info->bmiColors)[2] = 0x001f;
830         }
831         break;
832
833     case 16:
834         if (info->bmiHeader.biCompression == BI_BITFIELDS)
835         {
836             if (bmp->dib) memcpy( info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
837             else
838             {
839                 ((PDWORD)info->bmiColors)[0] = 0xf800;
840                 ((PDWORD)info->bmiColors)[1] = 0x07e0;
841                 ((PDWORD)info->bmiColors)[2] = 0x001f;
842             }
843         }
844         break;
845
846     case 24:
847     case 32:
848         if (info->bmiHeader.biCompression == BI_BITFIELDS)
849         {
850             if (bmp->dib) memcpy( info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
851             else
852             {
853                 ((PDWORD)info->bmiColors)[0] = 0xff0000;
854                 ((PDWORD)info->bmiColors)[1] = 0x00ff00;
855                 ((PDWORD)info->bmiColors)[2] = 0x0000ff;
856             }
857         }
858         break;
859     }
860
861     if (bits && lines)
862     {
863         /* If the bitmap object already have a dib section that contains image data, get the bits from it */
864         if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
865         {
866             /*FIXME: Only RGB dibs supported for now */
867             unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb = bmp->dib->dsBm.bmWidthBytes;
868             unsigned int dstwidth = width;
869             int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
870             LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
871             unsigned int x, y, width, widthb;
872
873             if ((height < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
874             {
875                 dbits = (LPBYTE)bits + (dstwidthb * (lines-1));
876                 dstwidthb = -dstwidthb;
877             }
878
879             switch( bpp ) {
880
881             case 15:
882             case 16: /* 16 bpp dstDIB */
883                 {
884                     LPWORD dstbits = (LPWORD)dbits;
885                     WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
886
887                     /* FIXME: BI_BITFIELDS not supported yet */
888
889                     switch(bmp->dib->dsBm.bmBitsPixel) {
890
891                     case 16: /* 16 bpp srcDIB -> 16 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                         break;
899
900                     case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
901                         {
902                             LPBYTE srcbits = sbits;
903
904                             width = min(srcwidth, dstwidth);
905                             for( y = 0; y < lines; y++) {
906                                 for( x = 0; x < width; x++, srcbits += 3)
907                                     *dstbits++ = ((srcbits[0] >> 3) & bmask) |
908                                                  (((WORD)srcbits[1] << 2) & gmask) |
909                                                  (((WORD)srcbits[2] << 7) & rmask);
910
911                                 dstbits = (LPWORD)(dbits+=dstwidthb);
912                                 srcbits = (sbits += srcwidthb);
913                             }
914                         }
915                         break;
916
917                     case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
918                         {
919                             LPDWORD srcbits = (LPDWORD)sbits;
920                             DWORD val;
921
922                             width = min(srcwidth, dstwidth);
923                             for( y = 0; y < lines; y++) {
924                                 for( x = 0; x < width; x++ ) {
925                                     val = *srcbits++;
926                                     *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
927                                                        ((val >> 9) & rmask));
928                                 }
929                                 dstbits = (LPWORD)(dbits+=dstwidthb);
930                                 srcbits = (LPDWORD)(sbits+=srcwidthb);
931                             }
932                         }
933                         break;
934
935                     default: /* ? bit bmp -> 16 bit DIB */
936                         FIXME("15/16 bit DIB %d bit bitmap\n",
937                         bmp->bitmap.bmBitsPixel);
938                         break;
939                     }
940                 }
941                 break;
942
943             case 24: /* 24 bpp dstDIB */
944                 {
945                     LPBYTE dstbits = dbits;
946
947                     switch(bmp->dib->dsBm.bmBitsPixel) {
948
949                     case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
950                         {
951                             LPWORD srcbits = (LPWORD)sbits;
952                             WORD val;
953
954                             width = min(srcwidth, dstwidth);
955                             /* FIXME: BI_BITFIELDS not supported yet */
956                             for( y = 0; y < lines; y++) {
957                                 for( x = 0; x < width; x++ ) {
958                                     val = *srcbits++;
959                                     *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
960                                     *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
961                                     *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
962                                 }
963                                 dstbits = dbits+=dstwidthb;
964                                 srcbits = (LPWORD)(sbits+=srcwidthb);
965                             }
966                         }
967                         break;
968
969                     case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
970                         {
971                             widthb = min(srcwidthb, abs(dstwidthb));
972                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
973                                 memcpy(dbits, sbits, widthb);
974                         }
975                         break;
976
977                     case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
978                         {
979                             LPBYTE srcbits = sbits;
980
981                             width = min(srcwidth, dstwidth);
982                             for( y = 0; y < lines; y++) {
983                                 for( x = 0; x < width; x++, srcbits++ ) {
984                                     *dstbits++ = *srcbits++;
985                                     *dstbits++ = *srcbits++;
986                                     *dstbits++ = *srcbits++;
987                                 }
988                                 dstbits = dbits+=dstwidthb;
989                                 srcbits = sbits+=srcwidthb;
990                             }
991                         }
992                         break;
993
994                     default: /* ? bit bmp -> 24 bit DIB */
995                         FIXME("24 bit DIB %d bit bitmap\n",
996                               bmp->bitmap.bmBitsPixel);
997                         break;
998                     }
999                 }
1000                 break;
1001
1002             case 32: /* 32 bpp dstDIB */
1003                 {
1004                     LPDWORD dstbits = (LPDWORD)dbits;
1005
1006                     /* FIXME: BI_BITFIELDS not supported yet */
1007
1008                     switch(bmp->dib->dsBm.bmBitsPixel) {
1009                         case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
1010                         {
1011                             LPWORD srcbits = (LPWORD)sbits;
1012                             DWORD val;
1013
1014                             width = min(srcwidth, dstwidth);
1015                             /* FIXME: BI_BITFIELDS not supported yet */
1016                             for( y = 0; y < lines; y++) {
1017                                 for( x = 0; x < width; x++ ) {
1018                                     val = (DWORD)*srcbits++;
1019                                     *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
1020                                                  ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
1021                                                  ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
1022                                 }
1023                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
1024                                 srcbits=(LPWORD)(sbits+=srcwidthb);
1025                             }
1026                         }
1027                         break;
1028
1029                     case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
1030                         {
1031                             LPBYTE srcbits = sbits;
1032
1033                             width = min(srcwidth, dstwidth);
1034                             for( y = 0; y < lines; y++) {
1035                                 for( x = 0; x < width; x++, srcbits+=3 )
1036                                     *dstbits++ =  srcbits[0] |
1037                                                  (srcbits[1] <<  8) |
1038                                                  (srcbits[2] << 16);
1039                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
1040                                 srcbits=(sbits+=srcwidthb);
1041                             }
1042                         }
1043                         break;
1044
1045                     case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
1046                         {
1047                             widthb = min(srcwidthb, abs(dstwidthb));
1048                             /* FIXME: BI_BITFIELDS not supported yet */
1049                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
1050                                 memcpy(dbits, sbits, widthb);
1051                             }
1052                         }
1053                         break;
1054
1055                     default: /* ? bit bmp -> 32 bit DIB */
1056                         FIXME("32 bit DIB %d bit bitmap\n",
1057                         bmp->bitmap.bmBitsPixel);
1058                         break;
1059                     }
1060                 }
1061                 break;
1062
1063             default: /* ? bit DIB */
1064                 FIXME("Unsupported DIB depth %d\n", info->bmiHeader.biBitCount);
1065                 break;
1066             }
1067         }
1068         /* Otherwise, get bits from the XImage */
1069         else
1070         {
1071             if (!bmp->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) lines = 0;
1072             else
1073             {
1074                 if (bmp->funcs && bmp->funcs->pGetDIBits)
1075                     lines = bmp->funcs->pGetDIBits( dc->physDev, hbitmap, startscan,
1076                                                     lines, bits, info, coloruse );
1077                 else
1078                     lines = 0;  /* FIXME: should copy from bmp->bitmap.bmBits */
1079             }
1080         }
1081     }
1082     else lines = abs(height);
1083
1084     /* The knowledge base article Q81498 ("DIBs and Their Uses") states that
1085        if bits == NULL and bpp != 0, only biSizeImage and the color table are
1086        filled in. */
1087     if (!core_header)
1088     {
1089         /* FIXME: biSizeImage should be calculated according to the selected
1090            compression algorithm if biCompression != BI_RGB */
1091         info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp );
1092         TRACE("biSizeImage = %d, ", info->bmiHeader.biSizeImage);
1093     }
1094     TRACE("biWidth = %d, biHeight = %d\n", width, height);
1095
1096 done:
1097     release_dc_ptr( dc );
1098     GDI_ReleaseObj( hbitmap );
1099     return lines;
1100 }
1101
1102
1103 /***********************************************************************
1104  *           CreateDIBitmap    (GDI32.@)
1105  *
1106  * Creates a DDB (device dependent bitmap) from a DIB.
1107  * The DDB will have the same color depth as the reference DC.
1108  */
1109 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
1110                             DWORD init, LPCVOID bits, const BITMAPINFO *data,
1111                             UINT coloruse )
1112 {
1113     HBITMAP handle;
1114     LONG width;
1115     LONG height;
1116     WORD planes, bpp;
1117     DWORD compr, size;
1118     DC *dc;
1119
1120     if (!header) return 0;
1121
1122     if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &size ) == -1) return 0;
1123     
1124     if (width < 0)
1125     {
1126         TRACE("Bitmap has a negative width\n");
1127         return 0;
1128     }
1129     
1130     /* Top-down DIBs have a negative height */
1131     if (height < 0) height = -height;
1132
1133     TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1134            hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
1135     
1136     if (hdc == NULL)
1137         handle = CreateBitmap( width, height, 1, 1, NULL );
1138     else
1139         handle = CreateCompatibleBitmap( hdc, width, height );
1140
1141     if (handle)
1142     {
1143         if (init & CBM_INIT)
1144         {
1145             if (SetDIBits( hdc, handle, 0, height, bits, data, coloruse ) == 0)
1146             {
1147                 DeleteObject( handle );
1148                 handle = 0;
1149             }
1150         }
1151
1152         else if (hdc && ((dc = get_dc_ptr( hdc )) != NULL) )
1153         {
1154             if (!BITMAP_SetOwnerDC( handle, dc ))
1155             {
1156                 DeleteObject( handle );
1157                 handle = 0;
1158             }
1159             release_dc_ptr( dc );
1160         }
1161     }
1162
1163     return handle;
1164 }
1165
1166 /* Copy/synthesize RGB palette from BITMAPINFO. Ripped from dlls/winex11.drv/dib.c */
1167 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1168 {
1169     RGBQUAD *colorTable;
1170     unsigned int colors, i;
1171     BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
1172
1173     if (core_info)
1174     {
1175         colors = 1 << ((const BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
1176     }
1177     else
1178     {
1179         colors = info->bmiHeader.biClrUsed;
1180         if (!colors) colors = 1 << info->bmiHeader.biBitCount;
1181     }
1182
1183     if (colors > 256) {
1184         ERR("called with >256 colors!\n");
1185         return;
1186     }
1187
1188     if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1189
1190     if(coloruse == DIB_RGB_COLORS)
1191     {
1192         if (core_info)
1193         {
1194            /* Convert RGBTRIPLEs to RGBQUADs */
1195            for (i=0; i < colors; i++)
1196            {
1197                colorTable[i].rgbRed   = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
1198                colorTable[i].rgbGreen = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
1199                colorTable[i].rgbBlue  = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
1200                colorTable[i].rgbReserved = 0;
1201            }
1202         }
1203         else
1204         {
1205             memcpy(colorTable, (const BYTE*) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
1206         }
1207     }
1208     else
1209     {
1210         PALETTEENTRY entries[256];
1211         const WORD *index = (const WORD*) ((const BYTE*) info + (WORD) info->bmiHeader.biSize);
1212         UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1213
1214         for (i = 0; i < colors; i++, index++)
1215         {
1216             PALETTEENTRY *entry = &entries[*index % count];
1217             colorTable[i].rgbRed = entry->peRed;
1218             colorTable[i].rgbGreen = entry->peGreen;
1219             colorTable[i].rgbBlue = entry->peBlue;
1220             colorTable[i].rgbReserved = 0;
1221         }
1222     }
1223     bmp->color_table = colorTable;
1224     bmp->nb_colors = colors;
1225 }
1226
1227 /***********************************************************************
1228  *           CreateDIBSection    (GDI32.@)
1229  */
1230 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1231                                 VOID **bits, HANDLE section, DWORD offset)
1232 {
1233     HBITMAP ret = 0;
1234     DC *dc;
1235     BOOL bDesktopDC = FALSE;
1236     DIBSECTION *dib;
1237     BITMAPOBJ *bmp;
1238     int bitmap_type;
1239     LONG width, height;
1240     WORD planes, bpp;
1241     DWORD compression, sizeImage;
1242     void *mapBits = NULL;
1243
1244     if(!bmi){
1245         if(bits) *bits = NULL;
1246         return NULL;
1247     }
1248
1249     if (((bitmap_type = DIB_GetBitmapInfo( &bmi->bmiHeader, &width, &height,
1250                                            &planes, &bpp, &compression, &sizeImage )) == -1))
1251         return 0;
1252
1253     switch (bpp)
1254     {
1255     case 16:
1256     case 32:
1257         if (compression == BI_BITFIELDS) break;
1258         /* fall through */
1259     case 1:
1260     case 4:
1261     case 8:
1262     case 24:
1263         if (compression == BI_RGB) break;
1264         /* fall through */
1265     default:
1266         WARN( "invalid %u bpp compression %u\n", bpp, compression );
1267         return 0;
1268     }
1269
1270     if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1271
1272     TRACE("format (%d,%d), planes %d, bpp %d, size %d, %s\n",
1273           width, height, planes, bpp, sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1274
1275     dib->dsBm.bmType       = 0;
1276     dib->dsBm.bmWidth      = width;
1277     dib->dsBm.bmHeight     = height >= 0 ? height : -height;
1278     dib->dsBm.bmWidthBytes = DIB_GetDIBWidthBytes(width, bpp);
1279     dib->dsBm.bmPlanes     = planes;
1280     dib->dsBm.bmBitsPixel  = bpp;
1281     dib->dsBm.bmBits       = NULL;
1282
1283     if (!bitmap_type)  /* core header */
1284     {
1285         /* convert the BITMAPCOREHEADER to a BITMAPINFOHEADER */
1286         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1287         dib->dsBmih.biWidth = width;
1288         dib->dsBmih.biHeight = height;
1289         dib->dsBmih.biPlanes = planes;
1290         dib->dsBmih.biBitCount = bpp;
1291         dib->dsBmih.biCompression = compression;
1292         dib->dsBmih.biXPelsPerMeter = 0;
1293         dib->dsBmih.biYPelsPerMeter = 0;
1294         dib->dsBmih.biClrUsed = 0;
1295         dib->dsBmih.biClrImportant = 0;
1296     }
1297     else
1298     {
1299         /* truncate extended bitmap headers (BITMAPV4HEADER etc.) */
1300         dib->dsBmih = bmi->bmiHeader;
1301         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1302     }
1303
1304     /* set number of entries in bmi.bmiColors table */
1305     if( bpp <= 8 )
1306         dib->dsBmih.biClrUsed = 1 << bpp;
1307
1308     dib->dsBmih.biSizeImage = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
1309
1310     /* set dsBitfields values */
1311     if (usage == DIB_PAL_COLORS || bpp <= 8)
1312     {
1313         dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1314     }
1315     else switch( bpp )
1316     {
1317     case 15:
1318     case 16:
1319         dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors       : 0x7c00;
1320         dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x03e0;
1321         dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x001f;
1322         break;
1323     case 24:
1324     case 32:
1325         dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors       : 0xff0000;
1326         dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x00ff00;
1327         dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x0000ff;
1328         break;
1329     }
1330
1331     /* get storage location for DIB bits */
1332
1333     if (section)
1334     {
1335         SYSTEM_INFO SystemInfo;
1336         DWORD mapOffset;
1337         INT mapSize;
1338
1339         GetSystemInfo( &SystemInfo );
1340         mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1341         mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1342         mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1343         if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1344     }
1345     else
1346     {
1347         offset = 0;
1348         dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1349                                          MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1350     }
1351     dib->dshSection = section;
1352     dib->dsOffset = offset;
1353
1354     if (!dib->dsBm.bmBits)
1355     {
1356         HeapFree( GetProcessHeap(), 0, dib );
1357         return 0;
1358     }
1359
1360     /* If the reference hdc is null, take the desktop dc */
1361     if (hdc == 0)
1362     {
1363         hdc = CreateCompatibleDC(0);
1364         bDesktopDC = TRUE;
1365     }
1366
1367     if (!(dc = get_dc_ptr( hdc ))) goto error;
1368
1369     /* create Device Dependent Bitmap and add DIB pointer */
1370     ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1371                         (bpp == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1372
1373     if (ret && ((bmp = GDI_GetObjPtr(ret, OBJ_BITMAP))))
1374     {
1375         bmp->dib = dib;
1376         bmp->funcs = dc->funcs;
1377         /* create local copy of DIB palette */
1378         if (bpp <= 8) DIB_CopyColorTable( dc, bmp, usage, bmi );
1379         GDI_ReleaseObj( ret );
1380
1381         if (dc->funcs->pCreateDIBSection)
1382         {
1383             if (!dc->funcs->pCreateDIBSection(dc->physDev, ret, bmi, usage))
1384             {
1385                 DeleteObject( ret );
1386                 ret = 0;
1387             }
1388         }
1389     }
1390
1391     release_dc_ptr( dc );
1392     if (bDesktopDC) DeleteDC( hdc );
1393     if (ret && bits) *bits = dib->dsBm.bmBits;
1394     return ret;
1395
1396 error:
1397     if (bDesktopDC) DeleteDC( hdc );
1398     if (section) UnmapViewOfFile( mapBits );
1399     else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1400     HeapFree( GetProcessHeap(), 0, dib );
1401     return 0;
1402 }