push 421a6d0d1068c98851feb4eb01bb0e754f615ce9
[wine/hacks.git] / dlls / gdi32 / dib.c
blob9be02d825109ad419dd296a591b9f848458711ab
1 /*
2 * GDI device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
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.
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.
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
22 Important information:
24 * Current Windows versions support two different DIB structures:
26 - BITMAPCOREINFO / BITMAPCOREHEADER (legacy structures; used in OS/2)
27 - BITMAPINFO / BITMAPINFOHEADER
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.
35 * The palettes are stored in different formats:
37 - BITMAPCOREINFO: Array of RGBTRIPLE
38 - BITMAPINFO: Array of RGBQUAD
41 * There are even more DIB headers, but they all extend BITMAPINFOHEADER:
43 - BITMAPV4HEADER: Introduced in Windows 95 / NT 4.0
44 - BITMAPV5HEADER: Introduced in Windows 98 / 2000
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.
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:
55 BITMAPINFO* info;
56 void* colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
59 * More information:
60 Search for "Bitmap Structures" in MSDN
63 #include <stdarg.h>
64 #include <stdlib.h>
65 #include <string.h>
67 #include "windef.h"
68 #include "winbase.h"
69 #include "wownt32.h"
70 #include "gdi_private.h"
71 #include "wine/debug.h"
73 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
77 Some of the following helper functions are duplicated in
78 dlls/x11drv/dib.c
81 /***********************************************************************
82 * DIB_GetDIBWidthBytes
84 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
85 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_87eb.asp
87 int DIB_GetDIBWidthBytes( int width, int depth )
89 int words;
91 switch(depth)
93 case 1: words = (width + 31) / 32; break;
94 case 4: words = (width + 7) / 8; break;
95 case 8: words = (width + 3) / 4; break;
96 case 15:
97 case 16: words = (width + 1) / 2; break;
98 case 24: words = (width * 3 + 3)/4; break;
100 default:
101 WARN("(%d): Unsupported depth\n", depth );
102 /* fall through */
103 case 32:
104 words = width;
106 return 4 * words;
109 /***********************************************************************
110 * DIB_GetDIBImageBytes
112 * Return the number of bytes used to hold the image in a DIB bitmap.
114 int DIB_GetDIBImageBytes( int width, int height, int depth )
116 return DIB_GetDIBWidthBytes( width, depth ) * abs( height );
120 /***********************************************************************
121 * DIB_BitmapInfoSize
123 * Return the size of the bitmap info structure including color table.
125 int DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse )
127 int colors;
129 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
131 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
132 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
133 return sizeof(BITMAPCOREHEADER) + colors *
134 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
136 else /* assume BITMAPINFOHEADER */
138 colors = info->bmiHeader.biClrUsed;
139 if (colors > 256) colors = 256;
140 if (!colors && (info->bmiHeader.biBitCount <= 8))
141 colors = 1 << info->bmiHeader.biBitCount;
142 return sizeof(BITMAPINFOHEADER) + colors *
143 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
148 /***********************************************************************
149 * DIB_GetBitmapInfo
151 * Get the info from a bitmap header.
152 * Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error.
154 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
155 LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size )
157 if (header->biSize == sizeof(BITMAPCOREHEADER))
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;
168 if (header->biSize >= sizeof(BITMAPINFOHEADER)) /* assume BITMAPINFOHEADER */
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;
178 ERR("(%d): unknown/wrong size for header\n", header->biSize );
179 return -1;
183 /***********************************************************************
184 * StretchDIBits (GDI32.@)
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 )
191 DC *dc;
193 if (!bits || !info)
194 return 0;
196 dc = DC_GetDCUpdate( hdc );
197 if(!dc) return FALSE;
199 if(dc->funcs->pStretchDIBits)
201 heightSrc = dc->funcs->pStretchDIBits(dc->physDev, xDst, yDst, widthDst,
202 heightDst, xSrc, ySrc, widthSrc,
203 heightSrc, bits, info, wUsage, dwRop);
204 DC_ReleaseDCPtr( dc );
206 else /* use StretchBlt */
208 HBITMAP hBitmap, hOldBitmap;
209 HPALETTE hpal = NULL;
210 HDC hdcMem;
211 LONG height;
212 LONG width;
213 WORD planes, bpp;
214 DWORD compr, size;
216 DC_ReleaseDCPtr( dc );
218 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size ) == -1)
220 ERR("Invalid bitmap\n");
221 return 0;
224 if (width < 0)
226 ERR("Bitmap has a negative width\n");
227 return 0;
230 hdcMem = CreateCompatibleDC( hdc );
231 hBitmap = CreateCompatibleBitmap(hdc, width, height);
232 hOldBitmap = SelectObject( hdcMem, hBitmap );
233 if(wUsage == DIB_PAL_COLORS)
235 hpal = GetCurrentObject(hdc, OBJ_PAL);
236 hpal = SelectPalette(hdcMem, hpal, FALSE);
239 if (info->bmiHeader.biCompression == BI_RLE4 ||
240 info->bmiHeader.biCompression == BI_RLE8) {
242 /* when RLE compression is used, there may be some gaps (ie the DIB doesn't
243 * contain all the rectangle described in bmiHeader, but only part of it.
244 * This mean that those undescribed pixels must be left untouched.
245 * So, we first copy on a memory bitmap the current content of the
246 * destination rectangle, blit the DIB bits on top of it - hence leaving
247 * the gaps untouched -, and blitting the rectangle back.
248 * This insure that gaps are untouched on the destination rectangle
249 * Not doing so leads to trashed images (the gaps contain what was on the
250 * memory bitmap => generally black or garbage)
251 * Unfortunately, RLE DIBs without gaps will be slowed down. But this is
252 * another speed vs correctness issue. Anyway, if speed is needed, then the
253 * pStretchDIBits function shall be implemented.
254 * ericP (2000/09/09)
257 /* copy existing bitmap from destination dc */
258 StretchBlt( hdcMem, xSrc, abs(height) - heightSrc - ySrc,
259 widthSrc, heightSrc, hdc, xDst, yDst, widthDst, heightDst,
260 dwRop );
263 SetDIBits(hdcMem, hBitmap, 0, height, bits, info, wUsage);
265 /* Origin for DIBitmap may be bottom left (positive biHeight) or top
266 left (negative biHeight) */
267 StretchBlt( hdc, xDst, yDst, widthDst, heightDst,
268 hdcMem, xSrc, abs(height) - heightSrc - ySrc,
269 widthSrc, heightSrc, dwRop );
270 if(hpal)
271 SelectPalette(hdcMem, hpal, FALSE);
272 SelectObject( hdcMem, hOldBitmap );
273 DeleteDC( hdcMem );
274 DeleteObject( hBitmap );
276 return heightSrc;
280 /******************************************************************************
281 * SetDIBits [GDI32.@]
283 * Sets pixels in a bitmap using colors from DIB.
285 * PARAMS
286 * hdc [I] Handle to device context
287 * hbitmap [I] Handle to bitmap
288 * startscan [I] Starting scan line
289 * lines [I] Number of scan lines
290 * bits [I] Array of bitmap bits
291 * info [I] Address of structure with data
292 * coloruse [I] Type of color indexes to use
294 * RETURNS
295 * Success: Number of scan lines copied
296 * Failure: 0
298 INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
299 UINT lines, LPCVOID bits, const BITMAPINFO *info,
300 UINT coloruse )
302 DC *dc;
303 BITMAPOBJ *bitmap;
304 INT result = 0;
306 if (!(dc = DC_GetDCUpdate( hdc )))
308 if (coloruse == DIB_RGB_COLORS) FIXME( "shouldn't require a DC for DIB_RGB_COLORS\n" );
309 return 0;
312 if (!(bitmap = GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
314 DC_ReleaseDCPtr( dc );
315 return 0;
318 if (!bitmap->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) goto done;
320 if (bitmap->funcs && bitmap->funcs->pSetDIBits)
321 result = bitmap->funcs->pSetDIBits( dc->physDev, hbitmap, startscan, lines,
322 bits, info, coloruse );
323 else
324 result = lines;
326 done:
327 GDI_ReleaseObj( hbitmap );
328 DC_ReleaseDCPtr( dc );
329 return result;
333 /***********************************************************************
334 * SetDIBitsToDevice (GDI32.@)
336 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
337 DWORD cy, INT xSrc, INT ySrc, UINT startscan,
338 UINT lines, LPCVOID bits, const BITMAPINFO *info,
339 UINT coloruse )
341 INT ret;
342 DC *dc;
344 if (!bits) return 0;
346 if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
348 if(dc->funcs->pSetDIBitsToDevice)
349 ret = dc->funcs->pSetDIBitsToDevice( dc->physDev, xDest, yDest, cx, cy, xSrc,
350 ySrc, startscan, lines, bits,
351 info, coloruse );
352 else {
353 FIXME("unimplemented on hdc %p\n", hdc);
354 ret = 0;
357 DC_ReleaseDCPtr( dc );
358 return ret;
361 /***********************************************************************
362 * SetDIBColorTable (GDI32.@)
364 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUAD *colors )
366 DC * dc;
367 UINT result = 0;
368 BITMAPOBJ * bitmap;
370 if (!(dc = DC_GetDCPtr( hdc ))) return 0;
372 if ((bitmap = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC )))
374 /* Check if currently selected bitmap is a DIB */
375 if (bitmap->color_table)
377 if (startpos < bitmap->nb_colors)
379 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
380 memcpy(bitmap->color_table + startpos, colors, entries * sizeof(RGBQUAD));
381 result = entries;
384 GDI_ReleaseObj( dc->hBitmap );
387 if (dc->funcs->pSetDIBColorTable)
388 dc->funcs->pSetDIBColorTable(dc->physDev, startpos, entries, colors);
390 DC_ReleaseDCPtr( dc );
391 return result;
395 /***********************************************************************
396 * GetDIBColorTable (GDI32.@)
398 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
400 DC * dc;
401 UINT result = 0;
403 if (!(dc = DC_GetDCPtr( hdc ))) return 0;
405 if (dc->funcs->pGetDIBColorTable)
406 result = dc->funcs->pGetDIBColorTable(dc->physDev, startpos, entries, colors);
407 else
409 BITMAPOBJ *bitmap = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
410 if (bitmap)
412 /* Check if currently selected bitmap is a DIB */
413 if (bitmap->color_table)
415 if (startpos < bitmap->nb_colors)
417 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
418 memcpy(colors, bitmap->color_table + startpos, entries * sizeof(RGBQUAD));
419 result = entries;
422 GDI_ReleaseObj( dc->hBitmap );
425 DC_ReleaseDCPtr( dc );
426 return result;
429 /* FIXME the following two structs should be combined with __sysPalTemplate in
430 objects/color.c - this should happen after de-X11-ing both of these
431 files.
432 NB. RGBQUAD and PALETTEENTRY have different orderings of red, green
433 and blue - sigh */
435 static const RGBQUAD EGAColorsQuads[16] = {
436 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
437 { 0x00, 0x00, 0x00, 0x00 },
438 { 0x00, 0x00, 0x80, 0x00 },
439 { 0x00, 0x80, 0x00, 0x00 },
440 { 0x00, 0x80, 0x80, 0x00 },
441 { 0x80, 0x00, 0x00, 0x00 },
442 { 0x80, 0x00, 0x80, 0x00 },
443 { 0x80, 0x80, 0x00, 0x00 },
444 { 0x80, 0x80, 0x80, 0x00 },
445 { 0xc0, 0xc0, 0xc0, 0x00 },
446 { 0x00, 0x00, 0xff, 0x00 },
447 { 0x00, 0xff, 0x00, 0x00 },
448 { 0x00, 0xff, 0xff, 0x00 },
449 { 0xff, 0x00, 0x00, 0x00 },
450 { 0xff, 0x00, 0xff, 0x00 },
451 { 0xff, 0xff, 0x00, 0x00 },
452 { 0xff, 0xff, 0xff, 0x00 }
455 static const RGBTRIPLE EGAColorsTriples[16] = {
456 /* rgbBlue, rgbGreen, rgbRed */
457 { 0x00, 0x00, 0x00 },
458 { 0x00, 0x00, 0x80 },
459 { 0x00, 0x80, 0x00 },
460 { 0x00, 0x80, 0x80 },
461 { 0x80, 0x00, 0x00 },
462 { 0x80, 0x00, 0x80 },
463 { 0x80, 0x80, 0x00 },
464 { 0x80, 0x80, 0x80 },
465 { 0xc0, 0xc0, 0xc0 },
466 { 0x00, 0x00, 0xff },
467 { 0x00, 0xff, 0x00 },
468 { 0x00, 0xff, 0xff },
469 { 0xff, 0x00, 0x00 } ,
470 { 0xff, 0x00, 0xff },
471 { 0xff, 0xff, 0x00 },
472 { 0xff, 0xff, 0xff }
475 static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
476 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
477 { 0x00, 0x00, 0x00, 0x00 },
478 { 0x00, 0x00, 0x80, 0x00 },
479 { 0x00, 0x80, 0x00, 0x00 },
480 { 0x00, 0x80, 0x80, 0x00 },
481 { 0x80, 0x00, 0x00, 0x00 },
482 { 0x80, 0x00, 0x80, 0x00 },
483 { 0x80, 0x80, 0x00, 0x00 },
484 { 0xc0, 0xc0, 0xc0, 0x00 },
485 { 0xc0, 0xdc, 0xc0, 0x00 },
486 { 0xf0, 0xca, 0xa6, 0x00 },
487 { 0xf0, 0xfb, 0xff, 0x00 },
488 { 0xa4, 0xa0, 0xa0, 0x00 },
489 { 0x80, 0x80, 0x80, 0x00 },
490 { 0x00, 0x00, 0xf0, 0x00 },
491 { 0x00, 0xff, 0x00, 0x00 },
492 { 0x00, 0xff, 0xff, 0x00 },
493 { 0xff, 0x00, 0x00, 0x00 },
494 { 0xff, 0x00, 0xff, 0x00 },
495 { 0xff, 0xff, 0x00, 0x00 },
496 { 0xff, 0xff, 0xff, 0x00 }
499 static const RGBTRIPLE DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
500 /* rgbBlue, rgbGreen, rgbRed */
501 { 0x00, 0x00, 0x00 },
502 { 0x00, 0x00, 0x80 },
503 { 0x00, 0x80, 0x00 },
504 { 0x00, 0x80, 0x80 },
505 { 0x80, 0x00, 0x00 },
506 { 0x80, 0x00, 0x80 },
507 { 0x80, 0x80, 0x00 },
508 { 0xc0, 0xc0, 0xc0 },
509 { 0xc0, 0xdc, 0xc0 },
510 { 0xf0, 0xca, 0xa6 },
511 { 0xf0, 0xfb, 0xff },
512 { 0xa4, 0xa0, 0xa0 },
513 { 0x80, 0x80, 0x80 },
514 { 0x00, 0x00, 0xf0 },
515 { 0x00, 0xff, 0x00 },
516 { 0x00, 0xff, 0xff },
517 { 0xff, 0x00, 0x00 },
518 { 0xff, 0x00, 0xff },
519 { 0xff, 0xff, 0x00 },
520 { 0xff, 0xff, 0xff}
524 /******************************************************************************
525 * GetDIBits [GDI32.@]
527 * Retrieves bits of bitmap and copies to buffer.
529 * RETURNS
530 * Success: Number of scan lines copied from bitmap
531 * Failure: 0
533 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_87eb.asp
535 INT WINAPI GetDIBits(
536 HDC hdc, /* [in] Handle to device context */
537 HBITMAP hbitmap, /* [in] Handle to bitmap */
538 UINT startscan, /* [in] First scan line to set in dest bitmap */
539 UINT lines, /* [in] Number of scan lines to copy */
540 LPVOID bits, /* [out] Address of array for bitmap bits */
541 BITMAPINFO * info, /* [out] Address of structure with bitmap data */
542 UINT coloruse) /* [in] RGB or palette index */
544 DC * dc;
545 BITMAPOBJ * bmp;
546 int i;
547 int bitmap_type;
548 BOOL core_header;
549 LONG width;
550 LONG height;
551 WORD planes, bpp;
552 DWORD compr, size;
553 void* colorPtr;
554 RGBTRIPLE* rgbTriples;
555 RGBQUAD* rgbQuads;
557 if (!info) return 0;
559 bitmap_type = DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size);
560 if (bitmap_type == -1)
562 ERR("Invalid bitmap format\n");
563 return 0;
565 core_header = (bitmap_type == 0);
566 if (!(dc = DC_GetDCUpdate( hdc )))
568 SetLastError( ERROR_INVALID_PARAMETER );
569 return 0;
571 if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
573 DC_ReleaseDCPtr( dc );
574 return 0;
577 colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
578 rgbTriples = (RGBTRIPLE *) colorPtr;
579 rgbQuads = (RGBQUAD *) colorPtr;
581 /* Transfer color info */
583 if (bpp <= 8 && bpp > 0)
585 if (!core_header) info->bmiHeader.biClrUsed = 0;
587 /* If the bitmap object already has a dib section at the
588 same color depth then get the color map from it */
589 if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == bpp) {
590 if(coloruse == DIB_RGB_COLORS) {
591 unsigned int colors = min( bmp->nb_colors, 1 << bpp );
593 if (core_header)
595 /* Convert the color table (RGBQUAD to RGBTRIPLE) */
596 RGBTRIPLE* index = rgbTriples;
598 for (i=0; i < colors; i++, index++)
600 index->rgbtRed = bmp->color_table[i].rgbRed;
601 index->rgbtGreen = bmp->color_table[i].rgbGreen;
602 index->rgbtBlue = bmp->color_table[i].rgbBlue;
605 else
607 if (colors != 1 << bpp) info->bmiHeader.biClrUsed = colors;
608 memcpy(colorPtr, bmp->color_table, colors * sizeof(RGBQUAD));
611 else {
612 WORD *index = colorPtr;
613 for(i = 0; i < 1 << info->bmiHeader.biBitCount; i++, index++)
614 *index = i;
617 else {
618 if(bpp >= bmp->bitmap.bmBitsPixel) {
619 /* Generate the color map from the selected palette */
620 PALETTEENTRY palEntry[256];
622 memset( palEntry, 0, sizeof(palEntry) );
623 if (!GetPaletteEntries( dc->hPalette, 0, 1 << bmp->bitmap.bmBitsPixel, palEntry ))
625 DC_ReleaseDCPtr( dc );
626 GDI_ReleaseObj( hbitmap );
627 return 0;
629 for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++) {
630 if (coloruse == DIB_RGB_COLORS) {
631 if (core_header)
633 rgbTriples[i].rgbtRed = palEntry[i].peRed;
634 rgbTriples[i].rgbtGreen = palEntry[i].peGreen;
635 rgbTriples[i].rgbtBlue = palEntry[i].peBlue;
637 else
639 rgbQuads[i].rgbRed = palEntry[i].peRed;
640 rgbQuads[i].rgbGreen = palEntry[i].peGreen;
641 rgbQuads[i].rgbBlue = palEntry[i].peBlue;
642 rgbQuads[i].rgbReserved = 0;
645 else ((WORD *)colorPtr)[i] = (WORD)i;
647 } else {
648 switch (bpp) {
649 case 1:
650 if (core_header)
652 rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
653 rgbTriples[0].rgbtBlue = 0;
654 rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
655 rgbTriples[1].rgbtBlue = 0xff;
657 else
659 rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
660 rgbQuads[0].rgbBlue = 0;
661 rgbQuads[0].rgbReserved = 0;
662 rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
663 rgbQuads[1].rgbBlue = 0xff;
664 rgbQuads[1].rgbReserved = 0;
666 break;
668 case 4:
669 if (core_header)
670 memcpy(colorPtr, EGAColorsTriples, sizeof(EGAColorsTriples));
671 else
672 memcpy(colorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
674 break;
676 case 8:
678 if (core_header)
680 INT r, g, b;
681 RGBTRIPLE *color;
683 memcpy(rgbTriples, DefLogPaletteTriples,
684 10 * sizeof(RGBTRIPLE));
685 memcpy(rgbTriples + 246, DefLogPaletteTriples + 10,
686 10 * sizeof(RGBTRIPLE));
687 color = rgbTriples + 10;
688 for(r = 0; r <= 5; r++) /* FIXME */
689 for(g = 0; g <= 5; g++)
690 for(b = 0; b <= 5; b++) {
691 color->rgbtRed = (r * 0xff) / 5;
692 color->rgbtGreen = (g * 0xff) / 5;
693 color->rgbtBlue = (b * 0xff) / 5;
694 color++;
697 else
699 INT r, g, b;
700 RGBQUAD *color;
702 memcpy(rgbQuads, DefLogPaletteQuads,
703 10 * sizeof(RGBQUAD));
704 memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
705 10 * sizeof(RGBQUAD));
706 color = rgbQuads + 10;
707 for(r = 0; r <= 5; r++) /* FIXME */
708 for(g = 0; g <= 5; g++)
709 for(b = 0; b <= 5; b++) {
710 color->rgbRed = (r * 0xff) / 5;
711 color->rgbGreen = (g * 0xff) / 5;
712 color->rgbBlue = (b * 0xff) / 5;
713 color->rgbReserved = 0;
714 color++;
723 if (bits && lines)
725 /* If the bitmap object already have a dib section that contains image data, get the bits from it */
726 if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
728 /*FIXME: Only RGB dibs supported for now */
729 unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb = bmp->dib->dsBm.bmWidthBytes;
730 unsigned int dstwidth = width;
731 int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
732 LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
733 unsigned int x, y, width, widthb;
735 if ((height < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
737 dbits = (LPBYTE)bits + (dstwidthb * (lines-1));
738 dstwidthb = -dstwidthb;
741 switch( bpp ) {
743 case 15:
744 case 16: /* 16 bpp dstDIB */
746 LPWORD dstbits = (LPWORD)dbits;
747 WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
749 /* FIXME: BI_BITFIELDS not supported yet */
751 switch(bmp->dib->dsBm.bmBitsPixel) {
753 case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
755 widthb = min(srcwidthb, abs(dstwidthb));
756 /* FIXME: BI_BITFIELDS not supported yet */
757 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
758 memcpy(dbits, sbits, widthb);
760 break;
762 case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
764 LPBYTE srcbits = sbits;
766 width = min(srcwidth, dstwidth);
767 for( y = 0; y < lines; y++) {
768 for( x = 0; x < width; x++, srcbits += 3)
769 *dstbits++ = ((srcbits[0] >> 3) & bmask) |
770 (((WORD)srcbits[1] << 2) & gmask) |
771 (((WORD)srcbits[2] << 7) & rmask);
773 dstbits = (LPWORD)(dbits+=dstwidthb);
774 srcbits = (sbits += srcwidthb);
777 break;
779 case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
781 LPDWORD srcbits = (LPDWORD)sbits;
782 DWORD val;
784 width = min(srcwidth, dstwidth);
785 for( y = 0; y < lines; y++) {
786 for( x = 0; x < width; x++ ) {
787 val = *srcbits++;
788 *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
789 ((val >> 9) & rmask));
791 dstbits = (LPWORD)(dbits+=dstwidthb);
792 srcbits = (LPDWORD)(sbits+=srcwidthb);
795 break;
797 default: /* ? bit bmp -> 16 bit DIB */
798 FIXME("15/16 bit DIB %d bit bitmap\n",
799 bmp->bitmap.bmBitsPixel);
800 break;
803 break;
805 case 24: /* 24 bpp dstDIB */
807 LPBYTE dstbits = dbits;
809 switch(bmp->dib->dsBm.bmBitsPixel) {
811 case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
813 LPWORD srcbits = (LPWORD)sbits;
814 WORD val;
816 width = min(srcwidth, dstwidth);
817 /* FIXME: BI_BITFIELDS not supported yet */
818 for( y = 0; y < lines; y++) {
819 for( x = 0; x < width; x++ ) {
820 val = *srcbits++;
821 *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
822 *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
823 *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
825 dstbits = (LPBYTE)(dbits+=dstwidthb);
826 srcbits = (LPWORD)(sbits+=srcwidthb);
829 break;
831 case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
833 widthb = min(srcwidthb, abs(dstwidthb));
834 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
835 memcpy(dbits, sbits, widthb);
837 break;
839 case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
841 LPBYTE srcbits = (LPBYTE)sbits;
843 width = min(srcwidth, dstwidth);
844 for( y = 0; y < lines; y++) {
845 for( x = 0; x < width; x++, srcbits++ ) {
846 *dstbits++ = *srcbits++;
847 *dstbits++ = *srcbits++;
848 *dstbits++ = *srcbits++;
850 dstbits=(LPBYTE)(dbits+=dstwidthb);
851 srcbits = (LPBYTE)(sbits+=srcwidthb);
854 break;
856 default: /* ? bit bmp -> 24 bit DIB */
857 FIXME("24 bit DIB %d bit bitmap\n",
858 bmp->bitmap.bmBitsPixel);
859 break;
862 break;
864 case 32: /* 32 bpp dstDIB */
866 LPDWORD dstbits = (LPDWORD)dbits;
868 /* FIXME: BI_BITFIELDS not supported yet */
870 switch(bmp->dib->dsBm.bmBitsPixel) {
871 case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
873 LPWORD srcbits = (LPWORD)sbits;
874 DWORD val;
876 width = min(srcwidth, dstwidth);
877 /* FIXME: BI_BITFIELDS not supported yet */
878 for( y = 0; y < lines; y++) {
879 for( x = 0; x < width; x++ ) {
880 val = (DWORD)*srcbits++;
881 *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
882 ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
883 ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
885 dstbits=(LPDWORD)(dbits+=dstwidthb);
886 srcbits=(LPWORD)(sbits+=srcwidthb);
889 break;
891 case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
893 LPBYTE srcbits = sbits;
895 width = min(srcwidth, dstwidth);
896 for( y = 0; y < lines; y++) {
897 for( x = 0; x < width; x++, srcbits+=3 )
898 *dstbits++ = srcbits[0] |
899 (srcbits[1] << 8) |
900 (srcbits[2] << 16);
901 dstbits=(LPDWORD)(dbits+=dstwidthb);
902 srcbits=(sbits+=srcwidthb);
905 break;
907 case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
909 widthb = min(srcwidthb, abs(dstwidthb));
910 /* FIXME: BI_BITFIELDS not supported yet */
911 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
912 memcpy(dbits, sbits, widthb);
915 break;
917 default: /* ? bit bmp -> 32 bit DIB */
918 FIXME("32 bit DIB %d bit bitmap\n",
919 bmp->bitmap.bmBitsPixel);
920 break;
923 break;
925 default: /* ? bit DIB */
926 FIXME("Unsupported DIB depth %d\n", info->bmiHeader.biBitCount);
927 break;
930 /* Otherwise, get bits from the XImage */
931 else
933 if (!bmp->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) lines = 0;
934 else
936 if (bmp->funcs && bmp->funcs->pGetDIBits)
937 lines = bmp->funcs->pGetDIBits( dc->physDev, hbitmap, startscan,
938 lines, bits, info, coloruse );
939 else
940 lines = 0; /* FIXME: should copy from bmp->bitmap.bmBits */
944 else
946 /* fill in struct members */
948 if (bpp == 0)
950 if (core_header)
952 BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
953 coreheader->bcWidth = bmp->bitmap.bmWidth;
954 coreheader->bcHeight = bmp->bitmap.bmHeight;
955 coreheader->bcPlanes = 1;
956 coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
958 else
960 info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
961 info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
962 info->bmiHeader.biPlanes = 1;
963 info->bmiHeader.biSizeImage =
964 DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
965 bmp->bitmap.bmHeight,
966 bmp->bitmap.bmBitsPixel );
967 switch(bmp->bitmap.bmBitsPixel)
969 case 15:
970 info->bmiHeader.biBitCount = 16;
971 info->bmiHeader.biCompression = BI_RGB;
972 break;
974 case 16:
975 if (bits)
977 /* Add color only when bits is given, as per MSDN */
978 ((PDWORD)info->bmiColors)[0] = 0xf800;
979 ((PDWORD)info->bmiColors)[1] = 0x07e0;
980 ((PDWORD)info->bmiColors)[2] = 0x001f;
982 info->bmiHeader.biBitCount = 16;
983 info->bmiHeader.biCompression = BI_BITFIELDS;
984 break;
986 default:
987 info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
988 info->bmiHeader.biCompression = BI_RGB;
989 break;
991 info->bmiHeader.biXPelsPerMeter = 0;
992 info->bmiHeader.biYPelsPerMeter = 0;
993 info->bmiHeader.biClrUsed = 0;
994 info->bmiHeader.biClrImportant = 0;
996 /* Windows 2000 doesn't touch the additional struct members if
997 it's a BITMAPV4HEADER or a BITMAPV5HEADER */
999 lines = abs(bmp->bitmap.bmHeight);
1001 else
1003 /* The knowledge base article Q81498 ("DIBs and Their Uses") states that
1004 if bits == NULL and bpp != 0, only biSizeImage and the color table are
1005 filled in. */
1006 if (!core_header)
1008 /* FIXME: biSizeImage should be calculated according to the selected
1009 compression algorithm if biCompression != BI_RGB */
1010 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp );
1012 lines = abs(height);
1016 if (!core_header)
1018 TRACE("biSizeImage = %d, ", info->bmiHeader.biSizeImage);
1020 TRACE("biWidth = %d, biHeight = %d\n", width, height);
1022 DC_ReleaseDCPtr( dc );
1023 GDI_ReleaseObj( hbitmap );
1024 return lines;
1028 /***********************************************************************
1029 * CreateDIBitmap (GDI32.@)
1031 * Creates a DDB (device dependent bitmap) from a DIB.
1032 * The DDB will have the same color depth as the reference DC.
1034 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
1035 DWORD init, LPCVOID bits, const BITMAPINFO *data,
1036 UINT coloruse )
1038 HBITMAP handle;
1039 LONG width;
1040 LONG height;
1041 WORD planes, bpp;
1042 DWORD compr, size;
1043 DC *dc;
1045 if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &size ) == -1) return 0;
1047 if (width < 0)
1049 TRACE("Bitmap has a negative width\n");
1050 return 0;
1053 /* Top-down DIBs have a negative height */
1054 if (height < 0) height = -height;
1056 TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1057 hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
1059 if (hdc == NULL)
1060 handle = CreateBitmap( width, height, 1, 1, NULL );
1061 else
1062 handle = CreateCompatibleBitmap( hdc, width, height );
1064 if (handle)
1066 if (init == CBM_INIT) SetDIBits( hdc, handle, 0, height, bits, data, coloruse );
1068 else if (hdc && ((dc = DC_GetDCPtr( hdc )) != NULL) )
1070 if (!BITMAP_SetOwnerDC( handle, dc ))
1072 DeleteObject( handle );
1073 handle = 0;
1075 DC_ReleaseDCPtr( dc );
1079 return handle;
1082 /***********************************************************************
1083 * CreateDIBSection (GDI.489)
1085 HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, const BITMAPINFO *bmi, UINT16 usage,
1086 SEGPTR *bits16, HANDLE section, DWORD offset)
1088 LPVOID bits32;
1089 HBITMAP hbitmap;
1091 hbitmap = CreateDIBSection( HDC_32(hdc), bmi, usage, &bits32, section, offset );
1092 if (hbitmap)
1094 BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(hbitmap, BITMAP_MAGIC);
1095 if (bmp && bmp->dib && bits32)
1097 const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
1098 LONG width, height;
1099 WORD planes, bpp;
1100 DWORD compr, size;
1101 INT width_bytes;
1102 WORD count, sel;
1103 int i;
1105 DIB_GetBitmapInfo(bi, &width, &height, &planes, &bpp, &compr, &size);
1107 height = height >= 0 ? height : -height;
1108 width_bytes = DIB_GetDIBWidthBytes(width, bpp);
1110 if (!size || (compr != BI_RLE4 && compr != BI_RLE8)) size = width_bytes * height;
1112 /* calculate number of sel's needed for size with 64K steps */
1113 count = (size + 0xffff) / 0x10000;
1114 sel = AllocSelectorArray16(count);
1116 for (i = 0; i < count; i++)
1118 SetSelectorBase(sel + (i << __AHSHIFT), (DWORD)bits32 + i * 0x10000);
1119 SetSelectorLimit16(sel + (i << __AHSHIFT), size - 1); /* yep, limit is correct */
1120 size -= 0x10000;
1122 bmp->segptr_bits = MAKESEGPTR( sel, 0 );
1123 if (bits16) *bits16 = bmp->segptr_bits;
1125 if (bmp) GDI_ReleaseObj( hbitmap );
1127 return HBITMAP_16(hbitmap);
1130 /* Copy/synthetize RGB palette from BITMAPINFO. Ripped from dlls/winex11.drv/dib.c */
1131 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1133 RGBQUAD *colorTable;
1134 unsigned int colors;
1135 int i;
1136 BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
1138 if (core_info)
1140 colors = 1 << ((const BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
1142 else
1144 colors = info->bmiHeader.biClrUsed;
1145 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
1148 if (colors > 256) {
1149 ERR("called with >256 colors!\n");
1150 return;
1153 if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1155 if(coloruse == DIB_RGB_COLORS)
1157 if (core_info)
1159 /* Convert RGBTRIPLEs to RGBQUADs */
1160 for (i=0; i < colors; i++)
1162 colorTable[i].rgbRed = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
1163 colorTable[i].rgbGreen = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
1164 colorTable[i].rgbBlue = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
1165 colorTable[i].rgbReserved = 0;
1168 else
1170 memcpy(colorTable, (const BYTE*) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
1173 else
1175 PALETTEENTRY entries[256];
1176 const WORD *index = (const WORD*) ((const BYTE*) info + (WORD) info->bmiHeader.biSize);
1177 UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1179 for (i = 0; i < colors; i++, index++)
1181 PALETTEENTRY *entry = &entries[*index % count];
1182 colorTable[i].rgbRed = entry->peRed;
1183 colorTable[i].rgbGreen = entry->peGreen;
1184 colorTable[i].rgbBlue = entry->peBlue;
1185 colorTable[i].rgbReserved = 0;
1188 bmp->color_table = colorTable;
1189 bmp->nb_colors = colors;
1192 /***********************************************************************
1193 * CreateDIBSection (GDI32.@)
1195 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1196 VOID **bits, HANDLE section, DWORD offset)
1198 HBITMAP ret = 0;
1199 DC *dc;
1200 BOOL bDesktopDC = FALSE;
1201 DIBSECTION *dib;
1202 BITMAPOBJ *bmp;
1203 int bitmap_type;
1204 LONG width, height;
1205 WORD planes, bpp;
1206 DWORD compression, sizeImage;
1207 void *mapBits = NULL;
1209 if (((bitmap_type = DIB_GetBitmapInfo( &bmi->bmiHeader, &width, &height,
1210 &planes, &bpp, &compression, &sizeImage )) == -1))
1211 return 0;
1213 if (compression != BI_RGB && compression != BI_BITFIELDS)
1215 TRACE("can't create a compressed (%u) dibsection\n", compression);
1216 return 0;
1219 if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1221 TRACE("format (%d,%d), planes %d, bpp %d, size %d, %s\n",
1222 width, height, planes, bpp, sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1224 dib->dsBm.bmType = 0;
1225 dib->dsBm.bmWidth = width;
1226 dib->dsBm.bmHeight = height >= 0 ? height : -height;
1227 dib->dsBm.bmWidthBytes = DIB_GetDIBWidthBytes(width, bpp);
1228 dib->dsBm.bmPlanes = planes;
1229 dib->dsBm.bmBitsPixel = bpp;
1230 dib->dsBm.bmBits = NULL;
1232 if (!bitmap_type) /* core header */
1234 /* convert the BITMAPCOREHEADER to a BITMAPINFOHEADER */
1235 dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1236 dib->dsBmih.biWidth = width;
1237 dib->dsBmih.biHeight = height;
1238 dib->dsBmih.biPlanes = planes;
1239 dib->dsBmih.biBitCount = bpp;
1240 dib->dsBmih.biCompression = compression;
1241 dib->dsBmih.biXPelsPerMeter = 0;
1242 dib->dsBmih.biYPelsPerMeter = 0;
1243 dib->dsBmih.biClrUsed = 0;
1244 dib->dsBmih.biClrImportant = 0;
1246 else
1248 /* truncate extended bitmap headers (BITMAPV4HEADER etc.) */
1249 dib->dsBmih = bmi->bmiHeader;
1250 dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1253 /* set number of entries in bmi.bmiColors table */
1254 if( bpp <= 8 )
1255 dib->dsBmih.biClrUsed = 1 << bpp;
1257 dib->dsBmih.biSizeImage = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
1259 /* set dsBitfields values */
1260 if (usage == DIB_PAL_COLORS || bpp <= 8)
1262 dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1264 else switch( bpp )
1266 case 15:
1267 case 16:
1268 dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors : 0x7c00;
1269 dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x03e0;
1270 dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x001f;
1271 break;
1272 case 24:
1273 case 32:
1274 dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors : 0xff0000;
1275 dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x00ff00;
1276 dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x0000ff;
1277 break;
1280 /* get storage location for DIB bits */
1282 if (section)
1284 SYSTEM_INFO SystemInfo;
1285 DWORD mapOffset;
1286 INT mapSize;
1288 GetSystemInfo( &SystemInfo );
1289 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1290 mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1291 mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1292 if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1294 else
1296 offset = 0;
1297 dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1298 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1300 dib->dshSection = section;
1301 dib->dsOffset = offset;
1303 if (!dib->dsBm.bmBits)
1305 HeapFree( GetProcessHeap(), 0, dib );
1306 return 0;
1309 /* If the reference hdc is null, take the desktop dc */
1310 if (hdc == 0)
1312 hdc = CreateCompatibleDC(0);
1313 bDesktopDC = TRUE;
1316 if (!(dc = DC_GetDCPtr( hdc ))) goto error;
1318 /* create Device Dependent Bitmap and add DIB pointer */
1319 ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1320 (bpp == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1322 if (ret && ((bmp = GDI_GetObjPtr(ret, BITMAP_MAGIC))))
1324 bmp->dib = dib;
1325 bmp->funcs = dc->funcs;
1326 /* create local copy of DIB palette */
1327 if (bpp <= 8) DIB_CopyColorTable( dc, bmp, usage, bmi );
1328 GDI_ReleaseObj( ret );
1330 if (dc->funcs->pCreateDIBSection)
1332 if (!dc->funcs->pCreateDIBSection(dc->physDev, ret, bmi, usage))
1334 DeleteObject( ret );
1335 ret = 0;
1340 DC_ReleaseDCPtr( dc );
1341 if (bDesktopDC) DeleteDC( hdc );
1342 if (ret && bits) *bits = dib->dsBm.bmBits;
1343 return ret;
1345 error:
1346 if (bDesktopDC) DeleteDC( hdc );
1347 if (section) UnmapViewOfFile( mapBits );
1348 else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1349 HeapFree( GetProcessHeap(), 0, dib );
1350 return 0;