push f98ef5dce4886db1f9801e7c454145e1b633b4ff
[wine/hacks.git] / dlls / gdi32 / dib.c
blobac2c9b0eae539bead1b12242d67fa2c732543edf
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 if (!(dc = get_dc_ptr( hdc ))) return FALSE;
198 if(dc->funcs->pStretchDIBits)
200 update_dc( dc );
201 heightSrc = dc->funcs->pStretchDIBits(dc->physDev, xDst, yDst, widthDst,
202 heightDst, xSrc, ySrc, widthSrc,
203 heightSrc, bits, info, wUsage, dwRop);
204 release_dc_ptr( 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 release_dc_ptr( 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 = get_dc_ptr( hdc )))
308 if (coloruse == DIB_RGB_COLORS) FIXME( "shouldn't require a DC for DIB_RGB_COLORS\n" );
309 return 0;
312 update_dc( dc );
314 if (!(bitmap = GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
316 release_dc_ptr( dc );
317 return 0;
320 if (!bitmap->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) goto done;
322 result = lines;
323 if (bitmap->funcs)
325 if (bitmap->funcs != dc->funcs)
326 ERR( "not supported: DDB bitmap %p not belonging to device %p\n", hbitmap, hdc );
327 else if (dc->funcs->pSetDIBits)
328 result = dc->funcs->pSetDIBits( dc->physDev, hbitmap, startscan, lines,
329 bits, info, coloruse );
332 done:
333 GDI_ReleaseObj( hbitmap );
334 release_dc_ptr( dc );
335 return result;
339 /***********************************************************************
340 * SetDIBitsToDevice (GDI32.@)
342 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
343 DWORD cy, INT xSrc, INT ySrc, UINT startscan,
344 UINT lines, LPCVOID bits, const BITMAPINFO *info,
345 UINT coloruse )
347 INT ret;
348 DC *dc;
350 if (!bits) return 0;
352 if (!(dc = get_dc_ptr( hdc ))) return 0;
354 if(dc->funcs->pSetDIBitsToDevice)
356 update_dc( dc );
357 ret = dc->funcs->pSetDIBitsToDevice( dc->physDev, xDest, yDest, cx, cy, xSrc,
358 ySrc, startscan, lines, bits,
359 info, coloruse );
361 else {
362 FIXME("unimplemented on hdc %p\n", hdc);
363 ret = 0;
366 release_dc_ptr( dc );
367 return ret;
370 /***********************************************************************
371 * SetDIBColorTable (GDI32.@)
373 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUAD *colors )
375 DC * dc;
376 UINT result = 0;
377 BITMAPOBJ * bitmap;
379 if (!(dc = DC_GetDCPtr( hdc ))) return 0;
381 if ((bitmap = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC )))
383 /* Check if currently selected bitmap is a DIB */
384 if (bitmap->color_table)
386 if (startpos < bitmap->nb_colors)
388 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
389 memcpy(bitmap->color_table + startpos, colors, entries * sizeof(RGBQUAD));
390 result = entries;
393 GDI_ReleaseObj( dc->hBitmap );
396 if (dc->funcs->pSetDIBColorTable)
397 dc->funcs->pSetDIBColorTable(dc->physDev, startpos, entries, colors);
399 DC_ReleaseDCPtr( dc );
400 return result;
404 /***********************************************************************
405 * GetDIBColorTable (GDI32.@)
407 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
409 DC * dc;
410 UINT result = 0;
412 if (!(dc = DC_GetDCPtr( hdc ))) return 0;
414 if (dc->funcs->pGetDIBColorTable)
415 result = dc->funcs->pGetDIBColorTable(dc->physDev, startpos, entries, colors);
416 else
418 BITMAPOBJ *bitmap = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
419 if (bitmap)
421 /* Check if currently selected bitmap is a DIB */
422 if (bitmap->color_table)
424 if (startpos < bitmap->nb_colors)
426 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
427 memcpy(colors, bitmap->color_table + startpos, entries * sizeof(RGBQUAD));
428 result = entries;
431 GDI_ReleaseObj( dc->hBitmap );
434 DC_ReleaseDCPtr( dc );
435 return result;
438 /* FIXME the following two structs should be combined with __sysPalTemplate in
439 objects/color.c - this should happen after de-X11-ing both of these
440 files.
441 NB. RGBQUAD and PALETTEENTRY have different orderings of red, green
442 and blue - sigh */
444 static const RGBQUAD EGAColorsQuads[16] = {
445 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
446 { 0x00, 0x00, 0x00, 0x00 },
447 { 0x00, 0x00, 0x80, 0x00 },
448 { 0x00, 0x80, 0x00, 0x00 },
449 { 0x00, 0x80, 0x80, 0x00 },
450 { 0x80, 0x00, 0x00, 0x00 },
451 { 0x80, 0x00, 0x80, 0x00 },
452 { 0x80, 0x80, 0x00, 0x00 },
453 { 0x80, 0x80, 0x80, 0x00 },
454 { 0xc0, 0xc0, 0xc0, 0x00 },
455 { 0x00, 0x00, 0xff, 0x00 },
456 { 0x00, 0xff, 0x00, 0x00 },
457 { 0x00, 0xff, 0xff, 0x00 },
458 { 0xff, 0x00, 0x00, 0x00 },
459 { 0xff, 0x00, 0xff, 0x00 },
460 { 0xff, 0xff, 0x00, 0x00 },
461 { 0xff, 0xff, 0xff, 0x00 }
464 static const RGBTRIPLE EGAColorsTriples[16] = {
465 /* rgbBlue, rgbGreen, rgbRed */
466 { 0x00, 0x00, 0x00 },
467 { 0x00, 0x00, 0x80 },
468 { 0x00, 0x80, 0x00 },
469 { 0x00, 0x80, 0x80 },
470 { 0x80, 0x00, 0x00 },
471 { 0x80, 0x00, 0x80 },
472 { 0x80, 0x80, 0x00 },
473 { 0x80, 0x80, 0x80 },
474 { 0xc0, 0xc0, 0xc0 },
475 { 0x00, 0x00, 0xff },
476 { 0x00, 0xff, 0x00 },
477 { 0x00, 0xff, 0xff },
478 { 0xff, 0x00, 0x00 } ,
479 { 0xff, 0x00, 0xff },
480 { 0xff, 0xff, 0x00 },
481 { 0xff, 0xff, 0xff }
484 static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
485 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
486 { 0x00, 0x00, 0x00, 0x00 },
487 { 0x00, 0x00, 0x80, 0x00 },
488 { 0x00, 0x80, 0x00, 0x00 },
489 { 0x00, 0x80, 0x80, 0x00 },
490 { 0x80, 0x00, 0x00, 0x00 },
491 { 0x80, 0x00, 0x80, 0x00 },
492 { 0x80, 0x80, 0x00, 0x00 },
493 { 0xc0, 0xc0, 0xc0, 0x00 },
494 { 0xc0, 0xdc, 0xc0, 0x00 },
495 { 0xf0, 0xca, 0xa6, 0x00 },
496 { 0xf0, 0xfb, 0xff, 0x00 },
497 { 0xa4, 0xa0, 0xa0, 0x00 },
498 { 0x80, 0x80, 0x80, 0x00 },
499 { 0x00, 0x00, 0xf0, 0x00 },
500 { 0x00, 0xff, 0x00, 0x00 },
501 { 0x00, 0xff, 0xff, 0x00 },
502 { 0xff, 0x00, 0x00, 0x00 },
503 { 0xff, 0x00, 0xff, 0x00 },
504 { 0xff, 0xff, 0x00, 0x00 },
505 { 0xff, 0xff, 0xff, 0x00 }
508 static const RGBTRIPLE DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
509 /* rgbBlue, rgbGreen, rgbRed */
510 { 0x00, 0x00, 0x00 },
511 { 0x00, 0x00, 0x80 },
512 { 0x00, 0x80, 0x00 },
513 { 0x00, 0x80, 0x80 },
514 { 0x80, 0x00, 0x00 },
515 { 0x80, 0x00, 0x80 },
516 { 0x80, 0x80, 0x00 },
517 { 0xc0, 0xc0, 0xc0 },
518 { 0xc0, 0xdc, 0xc0 },
519 { 0xf0, 0xca, 0xa6 },
520 { 0xf0, 0xfb, 0xff },
521 { 0xa4, 0xa0, 0xa0 },
522 { 0x80, 0x80, 0x80 },
523 { 0x00, 0x00, 0xf0 },
524 { 0x00, 0xff, 0x00 },
525 { 0x00, 0xff, 0xff },
526 { 0xff, 0x00, 0x00 },
527 { 0xff, 0x00, 0xff },
528 { 0xff, 0xff, 0x00 },
529 { 0xff, 0xff, 0xff}
533 /******************************************************************************
534 * GetDIBits [GDI32.@]
536 * Retrieves bits of bitmap and copies to buffer.
538 * RETURNS
539 * Success: Number of scan lines copied from bitmap
540 * Failure: 0
542 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_87eb.asp
544 INT WINAPI GetDIBits(
545 HDC hdc, /* [in] Handle to device context */
546 HBITMAP hbitmap, /* [in] Handle to bitmap */
547 UINT startscan, /* [in] First scan line to set in dest bitmap */
548 UINT lines, /* [in] Number of scan lines to copy */
549 LPVOID bits, /* [out] Address of array for bitmap bits */
550 BITMAPINFO * info, /* [out] Address of structure with bitmap data */
551 UINT coloruse) /* [in] RGB or palette index */
553 DC * dc;
554 BITMAPOBJ * bmp;
555 int i;
556 int bitmap_type;
557 BOOL core_header;
558 LONG width;
559 LONG height;
560 WORD planes, bpp;
561 DWORD compr, size;
562 void* colorPtr;
563 RGBTRIPLE* rgbTriples;
564 RGBQUAD* rgbQuads;
566 if (!info) return 0;
568 bitmap_type = DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size);
569 if (bitmap_type == -1)
571 ERR("Invalid bitmap format\n");
572 return 0;
574 core_header = (bitmap_type == 0);
575 if (!(dc = get_dc_ptr( hdc )))
577 SetLastError( ERROR_INVALID_PARAMETER );
578 return 0;
580 update_dc( dc );
581 if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
583 release_dc_ptr( dc );
584 return 0;
587 colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
588 rgbTriples = (RGBTRIPLE *) colorPtr;
589 rgbQuads = (RGBQUAD *) colorPtr;
591 /* Transfer color info */
593 if (bpp <= 8 && bpp > 0)
595 if (!core_header) info->bmiHeader.biClrUsed = 0;
597 /* If the bitmap object already has a dib section at the
598 same color depth then get the color map from it */
599 if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == bpp) {
600 if(coloruse == DIB_RGB_COLORS) {
601 unsigned int colors = min( bmp->nb_colors, 1 << bpp );
603 if (core_header)
605 /* Convert the color table (RGBQUAD to RGBTRIPLE) */
606 RGBTRIPLE* index = rgbTriples;
608 for (i=0; i < colors; i++, index++)
610 index->rgbtRed = bmp->color_table[i].rgbRed;
611 index->rgbtGreen = bmp->color_table[i].rgbGreen;
612 index->rgbtBlue = bmp->color_table[i].rgbBlue;
615 else
617 if (colors != 1 << bpp) info->bmiHeader.biClrUsed = colors;
618 memcpy(colorPtr, bmp->color_table, colors * sizeof(RGBQUAD));
621 else {
622 WORD *index = colorPtr;
623 for(i = 0; i < 1 << info->bmiHeader.biBitCount; i++, index++)
624 *index = i;
627 else {
628 if(bpp >= bmp->bitmap.bmBitsPixel) {
629 /* Generate the color map from the selected palette */
630 PALETTEENTRY palEntry[256];
632 memset( palEntry, 0, sizeof(palEntry) );
633 if (!GetPaletteEntries( dc->hPalette, 0, 1 << bmp->bitmap.bmBitsPixel, palEntry ))
635 release_dc_ptr( dc );
636 GDI_ReleaseObj( hbitmap );
637 return 0;
639 for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++) {
640 if (coloruse == DIB_RGB_COLORS) {
641 if (core_header)
643 rgbTriples[i].rgbtRed = palEntry[i].peRed;
644 rgbTriples[i].rgbtGreen = palEntry[i].peGreen;
645 rgbTriples[i].rgbtBlue = palEntry[i].peBlue;
647 else
649 rgbQuads[i].rgbRed = palEntry[i].peRed;
650 rgbQuads[i].rgbGreen = palEntry[i].peGreen;
651 rgbQuads[i].rgbBlue = palEntry[i].peBlue;
652 rgbQuads[i].rgbReserved = 0;
655 else ((WORD *)colorPtr)[i] = (WORD)i;
657 } else {
658 switch (bpp) {
659 case 1:
660 if (core_header)
662 rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
663 rgbTriples[0].rgbtBlue = 0;
664 rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
665 rgbTriples[1].rgbtBlue = 0xff;
667 else
669 rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
670 rgbQuads[0].rgbBlue = 0;
671 rgbQuads[0].rgbReserved = 0;
672 rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
673 rgbQuads[1].rgbBlue = 0xff;
674 rgbQuads[1].rgbReserved = 0;
676 break;
678 case 4:
679 if (core_header)
680 memcpy(colorPtr, EGAColorsTriples, sizeof(EGAColorsTriples));
681 else
682 memcpy(colorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
684 break;
686 case 8:
688 if (core_header)
690 INT r, g, b;
691 RGBTRIPLE *color;
693 memcpy(rgbTriples, DefLogPaletteTriples,
694 10 * sizeof(RGBTRIPLE));
695 memcpy(rgbTriples + 246, DefLogPaletteTriples + 10,
696 10 * sizeof(RGBTRIPLE));
697 color = rgbTriples + 10;
698 for(r = 0; r <= 5; r++) /* FIXME */
699 for(g = 0; g <= 5; g++)
700 for(b = 0; b <= 5; b++) {
701 color->rgbtRed = (r * 0xff) / 5;
702 color->rgbtGreen = (g * 0xff) / 5;
703 color->rgbtBlue = (b * 0xff) / 5;
704 color++;
707 else
709 INT r, g, b;
710 RGBQUAD *color;
712 memcpy(rgbQuads, DefLogPaletteQuads,
713 10 * sizeof(RGBQUAD));
714 memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
715 10 * sizeof(RGBQUAD));
716 color = rgbQuads + 10;
717 for(r = 0; r <= 5; r++) /* FIXME */
718 for(g = 0; g <= 5; g++)
719 for(b = 0; b <= 5; b++) {
720 color->rgbRed = (r * 0xff) / 5;
721 color->rgbGreen = (g * 0xff) / 5;
722 color->rgbBlue = (b * 0xff) / 5;
723 color->rgbReserved = 0;
724 color++;
733 if (bits && lines)
735 /* If the bitmap object already have a dib section that contains image data, get the bits from it */
736 if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
738 /*FIXME: Only RGB dibs supported for now */
739 unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb = bmp->dib->dsBm.bmWidthBytes;
740 unsigned int dstwidth = width;
741 int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
742 LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
743 unsigned int x, y, width, widthb;
745 if ((height < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
747 dbits = (LPBYTE)bits + (dstwidthb * (lines-1));
748 dstwidthb = -dstwidthb;
751 switch( bpp ) {
753 case 15:
754 case 16: /* 16 bpp dstDIB */
756 LPWORD dstbits = (LPWORD)dbits;
757 WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
759 /* FIXME: BI_BITFIELDS not supported yet */
761 switch(bmp->dib->dsBm.bmBitsPixel) {
763 case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
765 widthb = min(srcwidthb, abs(dstwidthb));
766 /* FIXME: BI_BITFIELDS not supported yet */
767 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
768 memcpy(dbits, sbits, widthb);
770 break;
772 case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
774 LPBYTE srcbits = sbits;
776 width = min(srcwidth, dstwidth);
777 for( y = 0; y < lines; y++) {
778 for( x = 0; x < width; x++, srcbits += 3)
779 *dstbits++ = ((srcbits[0] >> 3) & bmask) |
780 (((WORD)srcbits[1] << 2) & gmask) |
781 (((WORD)srcbits[2] << 7) & rmask);
783 dstbits = (LPWORD)(dbits+=dstwidthb);
784 srcbits = (sbits += srcwidthb);
787 break;
789 case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
791 LPDWORD srcbits = (LPDWORD)sbits;
792 DWORD val;
794 width = min(srcwidth, dstwidth);
795 for( y = 0; y < lines; y++) {
796 for( x = 0; x < width; x++ ) {
797 val = *srcbits++;
798 *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
799 ((val >> 9) & rmask));
801 dstbits = (LPWORD)(dbits+=dstwidthb);
802 srcbits = (LPDWORD)(sbits+=srcwidthb);
805 break;
807 default: /* ? bit bmp -> 16 bit DIB */
808 FIXME("15/16 bit DIB %d bit bitmap\n",
809 bmp->bitmap.bmBitsPixel);
810 break;
813 break;
815 case 24: /* 24 bpp dstDIB */
817 LPBYTE dstbits = dbits;
819 switch(bmp->dib->dsBm.bmBitsPixel) {
821 case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
823 LPWORD srcbits = (LPWORD)sbits;
824 WORD val;
826 width = min(srcwidth, dstwidth);
827 /* FIXME: BI_BITFIELDS not supported yet */
828 for( y = 0; y < lines; y++) {
829 for( x = 0; x < width; x++ ) {
830 val = *srcbits++;
831 *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
832 *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
833 *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
835 dstbits = (LPBYTE)(dbits+=dstwidthb);
836 srcbits = (LPWORD)(sbits+=srcwidthb);
839 break;
841 case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
843 widthb = min(srcwidthb, abs(dstwidthb));
844 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
845 memcpy(dbits, sbits, widthb);
847 break;
849 case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
851 LPBYTE srcbits = (LPBYTE)sbits;
853 width = min(srcwidth, dstwidth);
854 for( y = 0; y < lines; y++) {
855 for( x = 0; x < width; x++, srcbits++ ) {
856 *dstbits++ = *srcbits++;
857 *dstbits++ = *srcbits++;
858 *dstbits++ = *srcbits++;
860 dstbits=(LPBYTE)(dbits+=dstwidthb);
861 srcbits = (LPBYTE)(sbits+=srcwidthb);
864 break;
866 default: /* ? bit bmp -> 24 bit DIB */
867 FIXME("24 bit DIB %d bit bitmap\n",
868 bmp->bitmap.bmBitsPixel);
869 break;
872 break;
874 case 32: /* 32 bpp dstDIB */
876 LPDWORD dstbits = (LPDWORD)dbits;
878 /* FIXME: BI_BITFIELDS not supported yet */
880 switch(bmp->dib->dsBm.bmBitsPixel) {
881 case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
883 LPWORD srcbits = (LPWORD)sbits;
884 DWORD val;
886 width = min(srcwidth, dstwidth);
887 /* FIXME: BI_BITFIELDS not supported yet */
888 for( y = 0; y < lines; y++) {
889 for( x = 0; x < width; x++ ) {
890 val = (DWORD)*srcbits++;
891 *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
892 ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
893 ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
895 dstbits=(LPDWORD)(dbits+=dstwidthb);
896 srcbits=(LPWORD)(sbits+=srcwidthb);
899 break;
901 case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
903 LPBYTE srcbits = sbits;
905 width = min(srcwidth, dstwidth);
906 for( y = 0; y < lines; y++) {
907 for( x = 0; x < width; x++, srcbits+=3 )
908 *dstbits++ = srcbits[0] |
909 (srcbits[1] << 8) |
910 (srcbits[2] << 16);
911 dstbits=(LPDWORD)(dbits+=dstwidthb);
912 srcbits=(sbits+=srcwidthb);
915 break;
917 case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
919 widthb = min(srcwidthb, abs(dstwidthb));
920 /* FIXME: BI_BITFIELDS not supported yet */
921 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
922 memcpy(dbits, sbits, widthb);
925 break;
927 default: /* ? bit bmp -> 32 bit DIB */
928 FIXME("32 bit DIB %d bit bitmap\n",
929 bmp->bitmap.bmBitsPixel);
930 break;
933 break;
935 default: /* ? bit DIB */
936 FIXME("Unsupported DIB depth %d\n", info->bmiHeader.biBitCount);
937 break;
940 /* Otherwise, get bits from the XImage */
941 else
943 if (!bmp->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) lines = 0;
944 else
946 if (bmp->funcs && bmp->funcs->pGetDIBits)
947 lines = bmp->funcs->pGetDIBits( dc->physDev, hbitmap, startscan,
948 lines, bits, info, coloruse );
949 else
950 lines = 0; /* FIXME: should copy from bmp->bitmap.bmBits */
954 else
956 /* fill in struct members */
958 if (bpp == 0)
960 if (core_header)
962 BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
963 coreheader->bcWidth = bmp->bitmap.bmWidth;
964 coreheader->bcHeight = bmp->bitmap.bmHeight;
965 coreheader->bcPlanes = 1;
966 coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
968 else
970 info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
971 info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
972 info->bmiHeader.biPlanes = 1;
973 info->bmiHeader.biSizeImage =
974 DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
975 bmp->bitmap.bmHeight,
976 bmp->bitmap.bmBitsPixel );
977 switch(bmp->bitmap.bmBitsPixel)
979 case 15:
980 info->bmiHeader.biBitCount = 16;
981 info->bmiHeader.biCompression = BI_RGB;
982 break;
984 case 16:
985 if (bits)
987 /* Add color only when bits is given, as per MSDN */
988 ((PDWORD)info->bmiColors)[0] = 0xf800;
989 ((PDWORD)info->bmiColors)[1] = 0x07e0;
990 ((PDWORD)info->bmiColors)[2] = 0x001f;
992 info->bmiHeader.biBitCount = 16;
993 info->bmiHeader.biCompression = BI_BITFIELDS;
994 break;
996 default:
997 info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
998 info->bmiHeader.biCompression = BI_RGB;
999 break;
1001 info->bmiHeader.biXPelsPerMeter = 0;
1002 info->bmiHeader.biYPelsPerMeter = 0;
1003 info->bmiHeader.biClrUsed = 0;
1004 info->bmiHeader.biClrImportant = 0;
1006 /* Windows 2000 doesn't touch the additional struct members if
1007 it's a BITMAPV4HEADER or a BITMAPV5HEADER */
1009 lines = abs(bmp->bitmap.bmHeight);
1011 else
1013 /* The knowledge base article Q81498 ("DIBs and Their Uses") states that
1014 if bits == NULL and bpp != 0, only biSizeImage and the color table are
1015 filled in. */
1016 if (!core_header)
1018 /* FIXME: biSizeImage should be calculated according to the selected
1019 compression algorithm if biCompression != BI_RGB */
1020 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp );
1022 lines = abs(height);
1026 if (!core_header)
1028 TRACE("biSizeImage = %d, ", info->bmiHeader.biSizeImage);
1030 TRACE("biWidth = %d, biHeight = %d\n", width, height);
1032 release_dc_ptr( dc );
1033 GDI_ReleaseObj( hbitmap );
1034 return lines;
1038 /***********************************************************************
1039 * CreateDIBitmap (GDI32.@)
1041 * Creates a DDB (device dependent bitmap) from a DIB.
1042 * The DDB will have the same color depth as the reference DC.
1044 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
1045 DWORD init, LPCVOID bits, const BITMAPINFO *data,
1046 UINT coloruse )
1048 HBITMAP handle;
1049 LONG width;
1050 LONG height;
1051 WORD planes, bpp;
1052 DWORD compr, size;
1053 DC *dc;
1055 if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &size ) == -1) return 0;
1057 if (width < 0)
1059 TRACE("Bitmap has a negative width\n");
1060 return 0;
1063 /* Top-down DIBs have a negative height */
1064 if (height < 0) height = -height;
1066 TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1067 hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
1069 if (hdc == NULL)
1070 handle = CreateBitmap( width, height, 1, 1, NULL );
1071 else
1072 handle = CreateCompatibleBitmap( hdc, width, height );
1074 if (handle)
1076 if (init == CBM_INIT) SetDIBits( hdc, handle, 0, height, bits, data, coloruse );
1078 else if (hdc && ((dc = DC_GetDCPtr( hdc )) != NULL) )
1080 if (!BITMAP_SetOwnerDC( handle, dc ))
1082 DeleteObject( handle );
1083 handle = 0;
1085 DC_ReleaseDCPtr( dc );
1089 return handle;
1092 /***********************************************************************
1093 * CreateDIBSection (GDI.489)
1095 HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, const BITMAPINFO *bmi, UINT16 usage,
1096 SEGPTR *bits16, HANDLE section, DWORD offset)
1098 LPVOID bits32;
1099 HBITMAP hbitmap;
1101 hbitmap = CreateDIBSection( HDC_32(hdc), bmi, usage, &bits32, section, offset );
1102 if (hbitmap)
1104 BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(hbitmap, BITMAP_MAGIC);
1105 if (bmp && bmp->dib && bits32)
1107 const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
1108 LONG width, height;
1109 WORD planes, bpp;
1110 DWORD compr, size;
1111 INT width_bytes;
1112 WORD count, sel;
1113 int i;
1115 DIB_GetBitmapInfo(bi, &width, &height, &planes, &bpp, &compr, &size);
1117 height = height >= 0 ? height : -height;
1118 width_bytes = DIB_GetDIBWidthBytes(width, bpp);
1120 if (!size || (compr != BI_RLE4 && compr != BI_RLE8)) size = width_bytes * height;
1122 /* calculate number of sel's needed for size with 64K steps */
1123 count = (size + 0xffff) / 0x10000;
1124 sel = AllocSelectorArray16(count);
1126 for (i = 0; i < count; i++)
1128 SetSelectorBase(sel + (i << __AHSHIFT), (DWORD)bits32 + i * 0x10000);
1129 SetSelectorLimit16(sel + (i << __AHSHIFT), size - 1); /* yep, limit is correct */
1130 size -= 0x10000;
1132 bmp->segptr_bits = MAKESEGPTR( sel, 0 );
1133 if (bits16) *bits16 = bmp->segptr_bits;
1135 if (bmp) GDI_ReleaseObj( hbitmap );
1137 return HBITMAP_16(hbitmap);
1140 /* Copy/synthetize RGB palette from BITMAPINFO. Ripped from dlls/winex11.drv/dib.c */
1141 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1143 RGBQUAD *colorTable;
1144 unsigned int colors;
1145 int i;
1146 BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
1148 if (core_info)
1150 colors = 1 << ((const BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
1152 else
1154 colors = info->bmiHeader.biClrUsed;
1155 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
1158 if (colors > 256) {
1159 ERR("called with >256 colors!\n");
1160 return;
1163 if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1165 if(coloruse == DIB_RGB_COLORS)
1167 if (core_info)
1169 /* Convert RGBTRIPLEs to RGBQUADs */
1170 for (i=0; i < colors; i++)
1172 colorTable[i].rgbRed = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
1173 colorTable[i].rgbGreen = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
1174 colorTable[i].rgbBlue = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
1175 colorTable[i].rgbReserved = 0;
1178 else
1180 memcpy(colorTable, (const BYTE*) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
1183 else
1185 PALETTEENTRY entries[256];
1186 const WORD *index = (const WORD*) ((const BYTE*) info + (WORD) info->bmiHeader.biSize);
1187 UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1189 for (i = 0; i < colors; i++, index++)
1191 PALETTEENTRY *entry = &entries[*index % count];
1192 colorTable[i].rgbRed = entry->peRed;
1193 colorTable[i].rgbGreen = entry->peGreen;
1194 colorTable[i].rgbBlue = entry->peBlue;
1195 colorTable[i].rgbReserved = 0;
1198 bmp->color_table = colorTable;
1199 bmp->nb_colors = colors;
1202 /***********************************************************************
1203 * CreateDIBSection (GDI32.@)
1205 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1206 VOID **bits, HANDLE section, DWORD offset)
1208 HBITMAP ret = 0;
1209 DC *dc;
1210 BOOL bDesktopDC = FALSE;
1211 DIBSECTION *dib;
1212 BITMAPOBJ *bmp;
1213 int bitmap_type;
1214 LONG width, height;
1215 WORD planes, bpp;
1216 DWORD compression, sizeImage;
1217 void *mapBits = NULL;
1219 if (((bitmap_type = DIB_GetBitmapInfo( &bmi->bmiHeader, &width, &height,
1220 &planes, &bpp, &compression, &sizeImage )) == -1))
1221 return 0;
1223 if (compression != BI_RGB && compression != BI_BITFIELDS)
1225 TRACE("can't create a compressed (%u) dibsection\n", compression);
1226 return 0;
1229 if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1231 TRACE("format (%d,%d), planes %d, bpp %d, size %d, %s\n",
1232 width, height, planes, bpp, sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1234 dib->dsBm.bmType = 0;
1235 dib->dsBm.bmWidth = width;
1236 dib->dsBm.bmHeight = height >= 0 ? height : -height;
1237 dib->dsBm.bmWidthBytes = DIB_GetDIBWidthBytes(width, bpp);
1238 dib->dsBm.bmPlanes = planes;
1239 dib->dsBm.bmBitsPixel = bpp;
1240 dib->dsBm.bmBits = NULL;
1242 if (!bitmap_type) /* core header */
1244 /* convert the BITMAPCOREHEADER to a BITMAPINFOHEADER */
1245 dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1246 dib->dsBmih.biWidth = width;
1247 dib->dsBmih.biHeight = height;
1248 dib->dsBmih.biPlanes = planes;
1249 dib->dsBmih.biBitCount = bpp;
1250 dib->dsBmih.biCompression = compression;
1251 dib->dsBmih.biXPelsPerMeter = 0;
1252 dib->dsBmih.biYPelsPerMeter = 0;
1253 dib->dsBmih.biClrUsed = 0;
1254 dib->dsBmih.biClrImportant = 0;
1256 else
1258 /* truncate extended bitmap headers (BITMAPV4HEADER etc.) */
1259 dib->dsBmih = bmi->bmiHeader;
1260 dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1263 /* set number of entries in bmi.bmiColors table */
1264 if( bpp <= 8 )
1265 dib->dsBmih.biClrUsed = 1 << bpp;
1267 dib->dsBmih.biSizeImage = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
1269 /* set dsBitfields values */
1270 if (usage == DIB_PAL_COLORS || bpp <= 8)
1272 dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1274 else switch( bpp )
1276 case 15:
1277 case 16:
1278 dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors : 0x7c00;
1279 dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x03e0;
1280 dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x001f;
1281 break;
1282 case 24:
1283 case 32:
1284 dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors : 0xff0000;
1285 dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x00ff00;
1286 dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x0000ff;
1287 break;
1290 /* get storage location for DIB bits */
1292 if (section)
1294 SYSTEM_INFO SystemInfo;
1295 DWORD mapOffset;
1296 INT mapSize;
1298 GetSystemInfo( &SystemInfo );
1299 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1300 mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1301 mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1302 if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1304 else
1306 offset = 0;
1307 dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1308 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1310 dib->dshSection = section;
1311 dib->dsOffset = offset;
1313 if (!dib->dsBm.bmBits)
1315 HeapFree( GetProcessHeap(), 0, dib );
1316 return 0;
1319 /* If the reference hdc is null, take the desktop dc */
1320 if (hdc == 0)
1322 hdc = CreateCompatibleDC(0);
1323 bDesktopDC = TRUE;
1326 if (!(dc = DC_GetDCPtr( hdc ))) goto error;
1328 /* create Device Dependent Bitmap and add DIB pointer */
1329 ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1330 (bpp == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1332 if (ret && ((bmp = GDI_GetObjPtr(ret, BITMAP_MAGIC))))
1334 bmp->dib = dib;
1335 bmp->funcs = dc->funcs;
1336 /* create local copy of DIB palette */
1337 if (bpp <= 8) DIB_CopyColorTable( dc, bmp, usage, bmi );
1338 GDI_ReleaseObj( ret );
1340 if (dc->funcs->pCreateDIBSection)
1342 if (!dc->funcs->pCreateDIBSection(dc->physDev, ret, bmi, usage))
1344 DeleteObject( ret );
1345 ret = 0;
1350 DC_ReleaseDCPtr( dc );
1351 if (bDesktopDC) DeleteDC( hdc );
1352 if (ret && bits) *bits = dib->dsBm.bmBits;
1353 return ret;
1355 error:
1356 if (bDesktopDC) DeleteDC( hdc );
1357 if (section) UnmapViewOfFile( mapBits );
1358 else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1359 HeapFree( GetProcessHeap(), 0, dib );
1360 return 0;