gdi32: Remove unnecessary uses of wownt32.h.
[wine/multimedia.git] / dlls / gdi32 / dib.c
blob5067e494371444017912dde1f93249af8557c2f6
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 "gdi_private.h"
70 #include "wine/debug.h"
72 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
76 Some of the following helper functions are duplicated in
77 dlls/x11drv/dib.c
80 /***********************************************************************
81 * DIB_GetDIBWidthBytes
83 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
85 int DIB_GetDIBWidthBytes( int width, int depth )
87 int words;
89 switch(depth)
91 case 1: words = (width + 31) / 32; break;
92 case 4: words = (width + 7) / 8; break;
93 case 8: words = (width + 3) / 4; break;
94 case 15:
95 case 16: words = (width + 1) / 2; break;
96 case 24: words = (width * 3 + 3)/4; break;
98 default:
99 WARN("(%d): Unsupported depth\n", depth );
100 /* fall through */
101 case 32:
102 words = width;
104 return 4 * words;
107 /***********************************************************************
108 * DIB_GetDIBImageBytes
110 * Return the number of bytes used to hold the image in a DIB bitmap.
112 int DIB_GetDIBImageBytes( int width, int height, int depth )
114 return DIB_GetDIBWidthBytes( width, depth ) * abs( height );
118 /***********************************************************************
119 * bitmap_info_size
121 * Return the size of the bitmap info structure including color table.
123 int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
125 unsigned int colors, size, masks = 0;
127 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
129 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
130 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
131 return sizeof(BITMAPCOREHEADER) + colors *
132 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
134 else /* assume BITMAPINFOHEADER */
136 colors = info->bmiHeader.biClrUsed;
137 if (colors > 256) colors = 256;
138 if (!colors && (info->bmiHeader.biBitCount <= 8))
139 colors = 1 << info->bmiHeader.biBitCount;
140 if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
141 size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
142 return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
147 /***********************************************************************
148 * DIB_GetBitmapInfo
150 * Get the info from a bitmap header.
151 * Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error.
153 int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
154 LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size )
156 if (header->biSize == sizeof(BITMAPCOREHEADER))
158 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
159 *width = core->bcWidth;
160 *height = core->bcHeight;
161 *planes = core->bcPlanes;
162 *bpp = core->bcBitCount;
163 *compr = 0;
164 *size = 0;
165 return 0;
167 if (header->biSize >= sizeof(BITMAPINFOHEADER)) /* assume BITMAPINFOHEADER */
169 *width = header->biWidth;
170 *height = header->biHeight;
171 *planes = header->biPlanes;
172 *bpp = header->biBitCount;
173 *compr = header->biCompression;
174 *size = header->biSizeImage;
175 return 1;
177 ERR("(%d): unknown/wrong size for header\n", header->biSize );
178 return -1;
182 /***********************************************************************
183 * StretchDIBits (GDI32.@)
185 INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
186 INT heightDst, INT xSrc, INT ySrc, INT widthSrc,
187 INT heightSrc, const void *bits,
188 const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
190 DC *dc;
191 INT ret;
193 if (!bits || !info)
194 return 0;
196 if (!(dc = get_dc_ptr( hdc ))) return 0;
198 if(dc->funcs->pStretchDIBits)
200 update_dc( dc );
201 ret = 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 LONG height;
209 LONG width;
210 WORD planes, bpp;
211 DWORD compr, size;
212 HBITMAP hBitmap;
213 BOOL fastpath = FALSE;
215 release_dc_ptr( dc );
217 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size ) == -1)
219 ERR("Invalid bitmap\n");
220 return 0;
223 if (width < 0)
225 ERR("Bitmap has a negative width\n");
226 return 0;
229 if (xSrc == 0 && ySrc == 0 && widthDst == widthSrc && heightDst == heightSrc &&
230 info->bmiHeader.biCompression == BI_RGB)
232 /* Windows appears to have a fast case optimization
233 * that uses the wrong origin for top-down DIBs */
234 if (height < 0 && heightSrc < abs(height)) ySrc = abs(height) - heightSrc;
237 hBitmap = GetCurrentObject(hdc, OBJ_BITMAP);
239 if (xDst == 0 && yDst == 0 && xSrc == 0 && ySrc == 0 &&
240 widthDst == widthSrc && heightDst == heightSrc &&
241 info->bmiHeader.biCompression == BI_RGB &&
242 dwRop == SRCCOPY)
244 BITMAPOBJ *bmp;
245 if ((bmp = GDI_GetObjPtr( hBitmap, OBJ_BITMAP )))
247 if (bmp->bitmap.bmBitsPixel == bpp &&
248 bmp->bitmap.bmWidth == widthSrc &&
249 bmp->bitmap.bmHeight == heightSrc &&
250 bmp->bitmap.bmPlanes == planes)
251 fastpath = TRUE;
252 GDI_ReleaseObj( hBitmap );
256 if (fastpath)
258 /* fast path */
259 TRACE("using fast path\n");
260 ret = SetDIBits( hdc, hBitmap, 0, height, bits, info, wUsage);
262 else
264 /* slow path - need to use StretchBlt */
265 HBITMAP hOldBitmap;
266 HPALETTE hpal = NULL;
267 HDC hdcMem;
269 hdcMem = CreateCompatibleDC( hdc );
270 hBitmap = CreateCompatibleBitmap(hdc, width, height);
271 hOldBitmap = SelectObject( hdcMem, hBitmap );
272 if(wUsage == DIB_PAL_COLORS)
274 hpal = GetCurrentObject(hdc, OBJ_PAL);
275 hpal = SelectPalette(hdcMem, hpal, FALSE);
278 if (info->bmiHeader.biCompression == BI_RLE4 ||
279 info->bmiHeader.biCompression == BI_RLE8) {
281 /* when RLE compression is used, there may be some gaps (ie the DIB doesn't
282 * contain all the rectangle described in bmiHeader, but only part of it.
283 * This mean that those undescribed pixels must be left untouched.
284 * So, we first copy on a memory bitmap the current content of the
285 * destination rectangle, blit the DIB bits on top of it - hence leaving
286 * the gaps untouched -, and blitting the rectangle back.
287 * This insure that gaps are untouched on the destination rectangle
288 * Not doing so leads to trashed images (the gaps contain what was on the
289 * memory bitmap => generally black or garbage)
290 * Unfortunately, RLE DIBs without gaps will be slowed down. But this is
291 * another speed vs correctness issue. Anyway, if speed is needed, then the
292 * pStretchDIBits function shall be implemented.
293 * ericP (2000/09/09)
296 /* copy existing bitmap from destination dc */
297 StretchBlt( hdcMem, xSrc, abs(height) - heightSrc - ySrc,
298 widthSrc, heightSrc, hdc, xDst, yDst, widthDst, heightDst,
299 dwRop );
302 ret = SetDIBits(hdcMem, hBitmap, 0, height, bits, info, wUsage);
304 /* Origin for DIBitmap may be bottom left (positive biHeight) or top
305 left (negative biHeight) */
306 if (ret) StretchBlt( hdc, xDst, yDst, widthDst, heightDst,
307 hdcMem, xSrc, abs(height) - heightSrc - ySrc,
308 widthSrc, heightSrc, dwRop );
309 if(hpal)
310 SelectPalette(hdcMem, hpal, FALSE);
311 SelectObject( hdcMem, hOldBitmap );
312 DeleteDC( hdcMem );
313 DeleteObject( hBitmap );
316 return ret;
320 /******************************************************************************
321 * SetDIBits [GDI32.@]
323 * Sets pixels in a bitmap using colors from DIB.
325 * PARAMS
326 * hdc [I] Handle to device context
327 * hbitmap [I] Handle to bitmap
328 * startscan [I] Starting scan line
329 * lines [I] Number of scan lines
330 * bits [I] Array of bitmap bits
331 * info [I] Address of structure with data
332 * coloruse [I] Type of color indexes to use
334 * RETURNS
335 * Success: Number of scan lines copied
336 * Failure: 0
338 INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
339 UINT lines, LPCVOID bits, const BITMAPINFO *info,
340 UINT coloruse )
342 DC *dc = get_dc_ptr( hdc );
343 BOOL delete_hdc = FALSE;
344 BITMAPOBJ *bitmap;
345 INT result = 0;
347 if (coloruse == DIB_RGB_COLORS && !dc)
349 hdc = CreateCompatibleDC(0);
350 dc = get_dc_ptr( hdc );
351 delete_hdc = TRUE;
354 if (!dc) return 0;
356 update_dc( dc );
358 if (!(bitmap = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
360 release_dc_ptr( dc );
361 if (delete_hdc) DeleteDC(hdc);
362 return 0;
365 if (!bitmap->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) goto done;
367 result = lines;
368 if (bitmap->funcs)
370 if (bitmap->funcs != dc->funcs)
371 ERR( "not supported: DDB bitmap %p not belonging to device %p\n", hbitmap, hdc );
372 else if (dc->funcs->pSetDIBits)
373 result = dc->funcs->pSetDIBits( dc->physDev, hbitmap, startscan, lines,
374 bits, info, coloruse );
377 done:
378 GDI_ReleaseObj( hbitmap );
379 release_dc_ptr( dc );
380 if (delete_hdc) DeleteDC(hdc);
381 return result;
385 /***********************************************************************
386 * SetDIBitsToDevice (GDI32.@)
388 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
389 DWORD cy, INT xSrc, INT ySrc, UINT startscan,
390 UINT lines, LPCVOID bits, const BITMAPINFO *info,
391 UINT coloruse )
393 INT ret;
394 DC *dc;
396 if (!bits) return 0;
398 if (!(dc = get_dc_ptr( hdc ))) return 0;
400 if(dc->funcs->pSetDIBitsToDevice)
402 update_dc( dc );
403 ret = dc->funcs->pSetDIBitsToDevice( dc->physDev, xDest, yDest, cx, cy, xSrc,
404 ySrc, startscan, lines, bits,
405 info, coloruse );
407 else {
408 FIXME("unimplemented on hdc %p\n", hdc);
409 ret = 0;
412 release_dc_ptr( dc );
413 return ret;
416 /***********************************************************************
417 * SetDIBColorTable (GDI32.@)
419 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUAD *colors )
421 DC * dc;
422 UINT result = 0;
423 BITMAPOBJ * bitmap;
425 if (!(dc = get_dc_ptr( hdc ))) return 0;
427 if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
429 /* Check if currently selected bitmap is a DIB */
430 if (bitmap->color_table)
432 if (startpos < bitmap->nb_colors)
434 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
435 memcpy(bitmap->color_table + startpos, colors, entries * sizeof(RGBQUAD));
436 result = entries;
439 GDI_ReleaseObj( dc->hBitmap );
442 if (dc->funcs->pSetDIBColorTable)
443 dc->funcs->pSetDIBColorTable(dc->physDev, startpos, entries, colors);
445 release_dc_ptr( dc );
446 return result;
450 /***********************************************************************
451 * GetDIBColorTable (GDI32.@)
453 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
455 DC * dc;
456 UINT result = 0;
458 if (!(dc = get_dc_ptr( hdc ))) return 0;
460 if (dc->funcs->pGetDIBColorTable)
461 result = dc->funcs->pGetDIBColorTable(dc->physDev, startpos, entries, colors);
462 else
464 BITMAPOBJ *bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP );
465 if (bitmap)
467 /* Check if currently selected bitmap is a DIB */
468 if (bitmap->color_table)
470 if (startpos < bitmap->nb_colors)
472 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
473 memcpy(colors, bitmap->color_table + startpos, entries * sizeof(RGBQUAD));
474 result = entries;
477 GDI_ReleaseObj( dc->hBitmap );
480 release_dc_ptr( dc );
481 return result;
484 /* FIXME the following two structs should be combined with __sysPalTemplate in
485 objects/color.c - this should happen after de-X11-ing both of these
486 files.
487 NB. RGBQUAD and PALETTEENTRY have different orderings of red, green
488 and blue - sigh */
490 static const RGBQUAD EGAColorsQuads[16] = {
491 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
492 { 0x00, 0x00, 0x00, 0x00 },
493 { 0x00, 0x00, 0x80, 0x00 },
494 { 0x00, 0x80, 0x00, 0x00 },
495 { 0x00, 0x80, 0x80, 0x00 },
496 { 0x80, 0x00, 0x00, 0x00 },
497 { 0x80, 0x00, 0x80, 0x00 },
498 { 0x80, 0x80, 0x00, 0x00 },
499 { 0x80, 0x80, 0x80, 0x00 },
500 { 0xc0, 0xc0, 0xc0, 0x00 },
501 { 0x00, 0x00, 0xff, 0x00 },
502 { 0x00, 0xff, 0x00, 0x00 },
503 { 0x00, 0xff, 0xff, 0x00 },
504 { 0xff, 0x00, 0x00, 0x00 },
505 { 0xff, 0x00, 0xff, 0x00 },
506 { 0xff, 0xff, 0x00, 0x00 },
507 { 0xff, 0xff, 0xff, 0x00 }
510 static const RGBTRIPLE EGAColorsTriples[16] = {
511 /* rgbBlue, rgbGreen, rgbRed */
512 { 0x00, 0x00, 0x00 },
513 { 0x00, 0x00, 0x80 },
514 { 0x00, 0x80, 0x00 },
515 { 0x00, 0x80, 0x80 },
516 { 0x80, 0x00, 0x00 },
517 { 0x80, 0x00, 0x80 },
518 { 0x80, 0x80, 0x00 },
519 { 0x80, 0x80, 0x80 },
520 { 0xc0, 0xc0, 0xc0 },
521 { 0x00, 0x00, 0xff },
522 { 0x00, 0xff, 0x00 },
523 { 0x00, 0xff, 0xff },
524 { 0xff, 0x00, 0x00 } ,
525 { 0xff, 0x00, 0xff },
526 { 0xff, 0xff, 0x00 },
527 { 0xff, 0xff, 0xff }
530 static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
531 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
532 { 0x00, 0x00, 0x00, 0x00 },
533 { 0x00, 0x00, 0x80, 0x00 },
534 { 0x00, 0x80, 0x00, 0x00 },
535 { 0x00, 0x80, 0x80, 0x00 },
536 { 0x80, 0x00, 0x00, 0x00 },
537 { 0x80, 0x00, 0x80, 0x00 },
538 { 0x80, 0x80, 0x00, 0x00 },
539 { 0xc0, 0xc0, 0xc0, 0x00 },
540 { 0xc0, 0xdc, 0xc0, 0x00 },
541 { 0xf0, 0xca, 0xa6, 0x00 },
542 { 0xf0, 0xfb, 0xff, 0x00 },
543 { 0xa4, 0xa0, 0xa0, 0x00 },
544 { 0x80, 0x80, 0x80, 0x00 },
545 { 0x00, 0x00, 0xf0, 0x00 },
546 { 0x00, 0xff, 0x00, 0x00 },
547 { 0x00, 0xff, 0xff, 0x00 },
548 { 0xff, 0x00, 0x00, 0x00 },
549 { 0xff, 0x00, 0xff, 0x00 },
550 { 0xff, 0xff, 0x00, 0x00 },
551 { 0xff, 0xff, 0xff, 0x00 }
554 static const RGBTRIPLE DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
555 /* rgbBlue, rgbGreen, rgbRed */
556 { 0x00, 0x00, 0x00 },
557 { 0x00, 0x00, 0x80 },
558 { 0x00, 0x80, 0x00 },
559 { 0x00, 0x80, 0x80 },
560 { 0x80, 0x00, 0x00 },
561 { 0x80, 0x00, 0x80 },
562 { 0x80, 0x80, 0x00 },
563 { 0xc0, 0xc0, 0xc0 },
564 { 0xc0, 0xdc, 0xc0 },
565 { 0xf0, 0xca, 0xa6 },
566 { 0xf0, 0xfb, 0xff },
567 { 0xa4, 0xa0, 0xa0 },
568 { 0x80, 0x80, 0x80 },
569 { 0x00, 0x00, 0xf0 },
570 { 0x00, 0xff, 0x00 },
571 { 0x00, 0xff, 0xff },
572 { 0xff, 0x00, 0x00 },
573 { 0xff, 0x00, 0xff },
574 { 0xff, 0xff, 0x00 },
575 { 0xff, 0xff, 0xff}
579 /******************************************************************************
580 * GetDIBits [GDI32.@]
582 * Retrieves bits of bitmap and copies to buffer.
584 * RETURNS
585 * Success: Number of scan lines copied from bitmap
586 * Failure: 0
588 INT WINAPI GetDIBits(
589 HDC hdc, /* [in] Handle to device context */
590 HBITMAP hbitmap, /* [in] Handle to bitmap */
591 UINT startscan, /* [in] First scan line to set in dest bitmap */
592 UINT lines, /* [in] Number of scan lines to copy */
593 LPVOID bits, /* [out] Address of array for bitmap bits */
594 BITMAPINFO * info, /* [out] Address of structure with bitmap data */
595 UINT coloruse) /* [in] RGB or palette index */
597 DC * dc;
598 BITMAPOBJ * bmp;
599 int i;
600 int bitmap_type;
601 BOOL core_header;
602 LONG width;
603 LONG height;
604 WORD planes, bpp;
605 DWORD compr, size;
606 void* colorPtr;
607 RGBTRIPLE* rgbTriples;
608 RGBQUAD* rgbQuads;
610 if (!info) return 0;
612 bitmap_type = DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size);
613 if (bitmap_type == -1)
615 ERR("Invalid bitmap format\n");
616 return 0;
618 core_header = (bitmap_type == 0);
619 if (!(dc = get_dc_ptr( hdc )))
621 SetLastError( ERROR_INVALID_PARAMETER );
622 return 0;
624 update_dc( dc );
625 if (!(bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
627 release_dc_ptr( dc );
628 return 0;
631 colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
632 rgbTriples = colorPtr;
633 rgbQuads = colorPtr;
635 /* Transfer color info */
637 switch (bpp)
639 case 0: /* query bitmap info only */
640 if (core_header)
642 BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
643 coreheader->bcWidth = bmp->bitmap.bmWidth;
644 coreheader->bcHeight = bmp->bitmap.bmHeight;
645 coreheader->bcPlanes = 1;
646 coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
648 else
650 info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
651 info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
652 info->bmiHeader.biPlanes = 1;
653 info->bmiHeader.biSizeImage =
654 DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
655 bmp->bitmap.bmHeight,
656 bmp->bitmap.bmBitsPixel );
657 if (bmp->dib)
659 info->bmiHeader.biBitCount = bmp->dib->dsBm.bmBitsPixel;
660 switch (bmp->dib->dsBm.bmBitsPixel)
662 case 16:
663 case 32:
664 info->bmiHeader.biCompression = BI_BITFIELDS;
665 break;
666 default:
667 info->bmiHeader.biCompression = BI_RGB;
668 break;
671 else
673 info->bmiHeader.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB;
674 info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
676 info->bmiHeader.biXPelsPerMeter = 0;
677 info->bmiHeader.biYPelsPerMeter = 0;
678 info->bmiHeader.biClrUsed = 0;
679 info->bmiHeader.biClrImportant = 0;
681 /* Windows 2000 doesn't touch the additional struct members if
682 it's a BITMAPV4HEADER or a BITMAPV5HEADER */
684 lines = abs(bmp->bitmap.bmHeight);
685 goto done;
687 case 1:
688 case 4:
689 case 8:
690 if (!core_header) info->bmiHeader.biClrUsed = 0;
692 /* If the bitmap object already has a dib section at the
693 same color depth then get the color map from it */
694 if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == bpp) {
695 if(coloruse == DIB_RGB_COLORS) {
696 unsigned int colors = min( bmp->nb_colors, 1 << bpp );
698 if (core_header)
700 /* Convert the color table (RGBQUAD to RGBTRIPLE) */
701 RGBTRIPLE* index = rgbTriples;
703 for (i=0; i < colors; i++, index++)
705 index->rgbtRed = bmp->color_table[i].rgbRed;
706 index->rgbtGreen = bmp->color_table[i].rgbGreen;
707 index->rgbtBlue = bmp->color_table[i].rgbBlue;
710 else
712 if (colors != 1 << bpp) info->bmiHeader.biClrUsed = colors;
713 memcpy(colorPtr, bmp->color_table, colors * sizeof(RGBQUAD));
716 else {
717 WORD *index = colorPtr;
718 for(i = 0; i < 1 << info->bmiHeader.biBitCount; i++, index++)
719 *index = i;
722 else {
723 if (coloruse == DIB_PAL_COLORS) {
724 for (i = 0; i < (1 << bpp); i++)
725 ((WORD *)colorPtr)[i] = (WORD)i;
727 else if(bpp > 1 && bpp == bmp->bitmap.bmBitsPixel) {
728 /* For color DDBs in native depth (mono DDBs always have
729 a black/white palette):
730 Generate the color map from the selected palette */
731 PALETTEENTRY palEntry[256];
733 memset( palEntry, 0, sizeof(palEntry) );
734 if (!GetPaletteEntries( dc->hPalette, 0, 1 << bmp->bitmap.bmBitsPixel, palEntry ))
736 release_dc_ptr( dc );
737 GDI_ReleaseObj( hbitmap );
738 return 0;
740 for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++) {
741 if (core_header)
743 rgbTriples[i].rgbtRed = palEntry[i].peRed;
744 rgbTriples[i].rgbtGreen = palEntry[i].peGreen;
745 rgbTriples[i].rgbtBlue = palEntry[i].peBlue;
747 else
749 rgbQuads[i].rgbRed = palEntry[i].peRed;
750 rgbQuads[i].rgbGreen = palEntry[i].peGreen;
751 rgbQuads[i].rgbBlue = palEntry[i].peBlue;
752 rgbQuads[i].rgbReserved = 0;
755 } else {
756 switch (bpp) {
757 case 1:
758 if (core_header)
760 rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
761 rgbTriples[0].rgbtBlue = 0;
762 rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
763 rgbTriples[1].rgbtBlue = 0xff;
765 else
767 rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
768 rgbQuads[0].rgbBlue = 0;
769 rgbQuads[0].rgbReserved = 0;
770 rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
771 rgbQuads[1].rgbBlue = 0xff;
772 rgbQuads[1].rgbReserved = 0;
774 break;
776 case 4:
777 if (core_header)
778 memcpy(colorPtr, EGAColorsTriples, sizeof(EGAColorsTriples));
779 else
780 memcpy(colorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
782 break;
784 case 8:
786 if (core_header)
788 INT r, g, b;
789 RGBTRIPLE *color;
791 memcpy(rgbTriples, DefLogPaletteTriples,
792 10 * sizeof(RGBTRIPLE));
793 memcpy(rgbTriples + 246, DefLogPaletteTriples + 10,
794 10 * sizeof(RGBTRIPLE));
795 color = rgbTriples + 10;
796 for(r = 0; r <= 5; r++) /* FIXME */
797 for(g = 0; g <= 5; g++)
798 for(b = 0; b <= 5; b++) {
799 color->rgbtRed = (r * 0xff) / 5;
800 color->rgbtGreen = (g * 0xff) / 5;
801 color->rgbtBlue = (b * 0xff) / 5;
802 color++;
805 else
807 INT r, g, b;
808 RGBQUAD *color;
810 memcpy(rgbQuads, DefLogPaletteQuads,
811 10 * sizeof(RGBQUAD));
812 memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
813 10 * sizeof(RGBQUAD));
814 color = rgbQuads + 10;
815 for(r = 0; r <= 5; r++) /* FIXME */
816 for(g = 0; g <= 5; g++)
817 for(b = 0; b <= 5; b++) {
818 color->rgbRed = (r * 0xff) / 5;
819 color->rgbGreen = (g * 0xff) / 5;
820 color->rgbBlue = (b * 0xff) / 5;
821 color->rgbReserved = 0;
822 color++;
829 break;
831 case 15:
832 if (info->bmiHeader.biCompression == BI_BITFIELDS)
834 ((PDWORD)info->bmiColors)[0] = 0x7c00;
835 ((PDWORD)info->bmiColors)[1] = 0x03e0;
836 ((PDWORD)info->bmiColors)[2] = 0x001f;
838 break;
840 case 16:
841 if (info->bmiHeader.biCompression == BI_BITFIELDS)
843 if (bmp->dib) memcpy( info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
844 else
846 ((PDWORD)info->bmiColors)[0] = 0xf800;
847 ((PDWORD)info->bmiColors)[1] = 0x07e0;
848 ((PDWORD)info->bmiColors)[2] = 0x001f;
851 break;
853 case 24:
854 case 32:
855 if (info->bmiHeader.biCompression == BI_BITFIELDS)
857 if (bmp->dib) memcpy( info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
858 else
860 ((PDWORD)info->bmiColors)[0] = 0xff0000;
861 ((PDWORD)info->bmiColors)[1] = 0x00ff00;
862 ((PDWORD)info->bmiColors)[2] = 0x0000ff;
865 break;
868 if (bits && lines)
870 /* If the bitmap object already have a dib section that contains image data, get the bits from it */
871 if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
873 /*FIXME: Only RGB dibs supported for now */
874 unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb = bmp->dib->dsBm.bmWidthBytes;
875 unsigned int dstwidth = width;
876 int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
877 LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
878 unsigned int x, y, width, widthb;
880 if ((height < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
882 dbits = (LPBYTE)bits + (dstwidthb * (lines-1));
883 dstwidthb = -dstwidthb;
886 switch( bpp ) {
888 case 15:
889 case 16: /* 16 bpp dstDIB */
891 LPWORD dstbits = (LPWORD)dbits;
892 WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
894 /* FIXME: BI_BITFIELDS not supported yet */
896 switch(bmp->dib->dsBm.bmBitsPixel) {
898 case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
900 widthb = min(srcwidthb, abs(dstwidthb));
901 /* FIXME: BI_BITFIELDS not supported yet */
902 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
903 memcpy(dbits, sbits, widthb);
905 break;
907 case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
909 LPBYTE srcbits = sbits;
911 width = min(srcwidth, dstwidth);
912 for( y = 0; y < lines; y++) {
913 for( x = 0; x < width; x++, srcbits += 3)
914 *dstbits++ = ((srcbits[0] >> 3) & bmask) |
915 (((WORD)srcbits[1] << 2) & gmask) |
916 (((WORD)srcbits[2] << 7) & rmask);
918 dstbits = (LPWORD)(dbits+=dstwidthb);
919 srcbits = (sbits += srcwidthb);
922 break;
924 case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
926 LPDWORD srcbits = (LPDWORD)sbits;
927 DWORD val;
929 width = min(srcwidth, dstwidth);
930 for( y = 0; y < lines; y++) {
931 for( x = 0; x < width; x++ ) {
932 val = *srcbits++;
933 *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
934 ((val >> 9) & rmask));
936 dstbits = (LPWORD)(dbits+=dstwidthb);
937 srcbits = (LPDWORD)(sbits+=srcwidthb);
940 break;
942 default: /* ? bit bmp -> 16 bit DIB */
943 FIXME("15/16 bit DIB %d bit bitmap\n",
944 bmp->bitmap.bmBitsPixel);
945 break;
948 break;
950 case 24: /* 24 bpp dstDIB */
952 LPBYTE dstbits = dbits;
954 switch(bmp->dib->dsBm.bmBitsPixel) {
956 case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
958 LPWORD srcbits = (LPWORD)sbits;
959 WORD val;
961 width = min(srcwidth, dstwidth);
962 /* FIXME: BI_BITFIELDS not supported yet */
963 for( y = 0; y < lines; y++) {
964 for( x = 0; x < width; x++ ) {
965 val = *srcbits++;
966 *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
967 *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
968 *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
970 dstbits = dbits+=dstwidthb;
971 srcbits = (LPWORD)(sbits+=srcwidthb);
974 break;
976 case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
978 widthb = min(srcwidthb, abs(dstwidthb));
979 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
980 memcpy(dbits, sbits, widthb);
982 break;
984 case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
986 LPBYTE srcbits = sbits;
988 width = min(srcwidth, dstwidth);
989 for( y = 0; y < lines; y++) {
990 for( x = 0; x < width; x++, srcbits++ ) {
991 *dstbits++ = *srcbits++;
992 *dstbits++ = *srcbits++;
993 *dstbits++ = *srcbits++;
995 dstbits = dbits+=dstwidthb;
996 srcbits = sbits+=srcwidthb;
999 break;
1001 default: /* ? bit bmp -> 24 bit DIB */
1002 FIXME("24 bit DIB %d bit bitmap\n",
1003 bmp->bitmap.bmBitsPixel);
1004 break;
1007 break;
1009 case 32: /* 32 bpp dstDIB */
1011 LPDWORD dstbits = (LPDWORD)dbits;
1013 /* FIXME: BI_BITFIELDS not supported yet */
1015 switch(bmp->dib->dsBm.bmBitsPixel) {
1016 case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
1018 LPWORD srcbits = (LPWORD)sbits;
1019 DWORD val;
1021 width = min(srcwidth, dstwidth);
1022 /* FIXME: BI_BITFIELDS not supported yet */
1023 for( y = 0; y < lines; y++) {
1024 for( x = 0; x < width; x++ ) {
1025 val = (DWORD)*srcbits++;
1026 *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
1027 ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
1028 ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
1030 dstbits=(LPDWORD)(dbits+=dstwidthb);
1031 srcbits=(LPWORD)(sbits+=srcwidthb);
1034 break;
1036 case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
1038 LPBYTE srcbits = sbits;
1040 width = min(srcwidth, dstwidth);
1041 for( y = 0; y < lines; y++) {
1042 for( x = 0; x < width; x++, srcbits+=3 )
1043 *dstbits++ = srcbits[0] |
1044 (srcbits[1] << 8) |
1045 (srcbits[2] << 16);
1046 dstbits=(LPDWORD)(dbits+=dstwidthb);
1047 srcbits=(sbits+=srcwidthb);
1050 break;
1052 case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
1054 widthb = min(srcwidthb, abs(dstwidthb));
1055 /* FIXME: BI_BITFIELDS not supported yet */
1056 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
1057 memcpy(dbits, sbits, widthb);
1060 break;
1062 default: /* ? bit bmp -> 32 bit DIB */
1063 FIXME("32 bit DIB %d bit bitmap\n",
1064 bmp->bitmap.bmBitsPixel);
1065 break;
1068 break;
1070 default: /* ? bit DIB */
1071 FIXME("Unsupported DIB depth %d\n", info->bmiHeader.biBitCount);
1072 break;
1075 /* Otherwise, get bits from the XImage */
1076 else
1078 if (!bmp->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) lines = 0;
1079 else
1081 if (bmp->funcs && bmp->funcs->pGetDIBits)
1082 lines = bmp->funcs->pGetDIBits( dc->physDev, hbitmap, startscan,
1083 lines, bits, info, coloruse );
1084 else
1085 lines = 0; /* FIXME: should copy from bmp->bitmap.bmBits */
1089 else lines = abs(height);
1091 /* The knowledge base article Q81498 ("DIBs and Their Uses") states that
1092 if bits == NULL and bpp != 0, only biSizeImage and the color table are
1093 filled in. */
1094 if (!core_header)
1096 /* FIXME: biSizeImage should be calculated according to the selected
1097 compression algorithm if biCompression != BI_RGB */
1098 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp );
1099 TRACE("biSizeImage = %d, ", info->bmiHeader.biSizeImage);
1101 TRACE("biWidth = %d, biHeight = %d\n", width, height);
1103 done:
1104 release_dc_ptr( dc );
1105 GDI_ReleaseObj( hbitmap );
1106 return lines;
1110 /***********************************************************************
1111 * CreateDIBitmap (GDI32.@)
1113 * Creates a DDB (device dependent bitmap) from a DIB.
1114 * The DDB will have the same color depth as the reference DC.
1116 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
1117 DWORD init, LPCVOID bits, const BITMAPINFO *data,
1118 UINT coloruse )
1120 HBITMAP handle;
1121 LONG width;
1122 LONG height;
1123 WORD planes, bpp;
1124 DWORD compr, size;
1125 DC *dc;
1127 if (!header) return 0;
1129 if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &size ) == -1) return 0;
1131 if (width < 0)
1133 TRACE("Bitmap has a negative width\n");
1134 return 0;
1137 /* Top-down DIBs have a negative height */
1138 if (height < 0) height = -height;
1140 TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1141 hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
1143 if (hdc == NULL)
1144 handle = CreateBitmap( width, height, 1, 1, NULL );
1145 else
1146 handle = CreateCompatibleBitmap( hdc, width, height );
1148 if (handle)
1150 if (init & CBM_INIT)
1152 if (SetDIBits( hdc, handle, 0, height, bits, data, coloruse ) == 0)
1154 DeleteObject( handle );
1155 handle = 0;
1159 else if (hdc && ((dc = get_dc_ptr( hdc )) != NULL) )
1161 if (!BITMAP_SetOwnerDC( handle, dc ))
1163 DeleteObject( handle );
1164 handle = 0;
1166 release_dc_ptr( dc );
1170 return handle;
1173 /* Copy/synthesize RGB palette from BITMAPINFO. Ripped from dlls/winex11.drv/dib.c */
1174 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1176 RGBQUAD *colorTable;
1177 unsigned int colors, i;
1178 BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
1180 if (core_info)
1182 colors = 1 << ((const BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
1184 else
1186 colors = info->bmiHeader.biClrUsed;
1187 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
1190 if (colors > 256) {
1191 ERR("called with >256 colors!\n");
1192 return;
1195 if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1197 if(coloruse == DIB_RGB_COLORS)
1199 if (core_info)
1201 /* Convert RGBTRIPLEs to RGBQUADs */
1202 for (i=0; i < colors; i++)
1204 colorTable[i].rgbRed = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
1205 colorTable[i].rgbGreen = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
1206 colorTable[i].rgbBlue = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
1207 colorTable[i].rgbReserved = 0;
1210 else
1212 memcpy(colorTable, (const BYTE*) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
1215 else
1217 PALETTEENTRY entries[256];
1218 const WORD *index = (const WORD*) ((const BYTE*) info + (WORD) info->bmiHeader.biSize);
1219 UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1221 for (i = 0; i < colors; i++, index++)
1223 PALETTEENTRY *entry = &entries[*index % count];
1224 colorTable[i].rgbRed = entry->peRed;
1225 colorTable[i].rgbGreen = entry->peGreen;
1226 colorTable[i].rgbBlue = entry->peBlue;
1227 colorTable[i].rgbReserved = 0;
1230 bmp->color_table = colorTable;
1231 bmp->nb_colors = colors;
1234 /***********************************************************************
1235 * CreateDIBSection (GDI32.@)
1237 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1238 VOID **bits, HANDLE section, DWORD offset)
1240 HBITMAP ret = 0;
1241 DC *dc;
1242 BOOL bDesktopDC = FALSE;
1243 DIBSECTION *dib;
1244 BITMAPOBJ *bmp;
1245 int bitmap_type;
1246 LONG width, height;
1247 WORD planes, bpp;
1248 DWORD compression, sizeImage;
1249 void *mapBits = NULL;
1251 if(!bmi){
1252 if(bits) *bits = NULL;
1253 return NULL;
1256 if (((bitmap_type = DIB_GetBitmapInfo( &bmi->bmiHeader, &width, &height,
1257 &planes, &bpp, &compression, &sizeImage )) == -1))
1258 return 0;
1260 switch (bpp)
1262 case 16:
1263 case 32:
1264 if (compression == BI_BITFIELDS) break;
1265 /* fall through */
1266 case 1:
1267 case 4:
1268 case 8:
1269 case 24:
1270 if (compression == BI_RGB) break;
1271 /* fall through */
1272 default:
1273 WARN( "invalid %u bpp compression %u\n", bpp, compression );
1274 return 0;
1277 if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1279 TRACE("format (%d,%d), planes %d, bpp %d, size %d, %s\n",
1280 width, height, planes, bpp, sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1282 dib->dsBm.bmType = 0;
1283 dib->dsBm.bmWidth = width;
1284 dib->dsBm.bmHeight = height >= 0 ? height : -height;
1285 dib->dsBm.bmWidthBytes = DIB_GetDIBWidthBytes(width, bpp);
1286 dib->dsBm.bmPlanes = planes;
1287 dib->dsBm.bmBitsPixel = bpp;
1288 dib->dsBm.bmBits = NULL;
1290 if (!bitmap_type) /* core header */
1292 /* convert the BITMAPCOREHEADER to a BITMAPINFOHEADER */
1293 dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1294 dib->dsBmih.biWidth = width;
1295 dib->dsBmih.biHeight = height;
1296 dib->dsBmih.biPlanes = planes;
1297 dib->dsBmih.biBitCount = bpp;
1298 dib->dsBmih.biCompression = compression;
1299 dib->dsBmih.biXPelsPerMeter = 0;
1300 dib->dsBmih.biYPelsPerMeter = 0;
1301 dib->dsBmih.biClrUsed = 0;
1302 dib->dsBmih.biClrImportant = 0;
1304 else
1306 /* truncate extended bitmap headers (BITMAPV4HEADER etc.) */
1307 dib->dsBmih = bmi->bmiHeader;
1308 dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1311 /* set number of entries in bmi.bmiColors table */
1312 if( bpp <= 8 )
1313 dib->dsBmih.biClrUsed = 1 << bpp;
1315 dib->dsBmih.biSizeImage = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
1317 /* set dsBitfields values */
1318 if (usage == DIB_PAL_COLORS || bpp <= 8)
1320 dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1322 else switch( bpp )
1324 case 15:
1325 case 16:
1326 dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors : 0x7c00;
1327 dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x03e0;
1328 dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x001f;
1329 break;
1330 case 24:
1331 case 32:
1332 dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors : 0xff0000;
1333 dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x00ff00;
1334 dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x0000ff;
1335 break;
1338 /* get storage location for DIB bits */
1340 if (section)
1342 SYSTEM_INFO SystemInfo;
1343 DWORD mapOffset;
1344 INT mapSize;
1346 GetSystemInfo( &SystemInfo );
1347 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1348 mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1349 mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1350 if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1352 else
1354 offset = 0;
1355 dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1356 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1358 dib->dshSection = section;
1359 dib->dsOffset = offset;
1361 if (!dib->dsBm.bmBits)
1363 HeapFree( GetProcessHeap(), 0, dib );
1364 return 0;
1367 /* If the reference hdc is null, take the desktop dc */
1368 if (hdc == 0)
1370 hdc = CreateCompatibleDC(0);
1371 bDesktopDC = TRUE;
1374 if (!(dc = get_dc_ptr( hdc ))) goto error;
1376 /* create Device Dependent Bitmap and add DIB pointer */
1377 ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1378 (bpp == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1380 if (ret && ((bmp = GDI_GetObjPtr(ret, OBJ_BITMAP))))
1382 bmp->dib = dib;
1383 bmp->funcs = dc->funcs;
1384 /* create local copy of DIB palette */
1385 if (bpp <= 8) DIB_CopyColorTable( dc, bmp, usage, bmi );
1386 GDI_ReleaseObj( ret );
1388 if (dc->funcs->pCreateDIBSection)
1390 if (!dc->funcs->pCreateDIBSection(dc->physDev, ret, bmi, usage))
1392 DeleteObject( ret );
1393 ret = 0;
1398 release_dc_ptr( dc );
1399 if (bDesktopDC) DeleteDC( hdc );
1400 if (ret && bits) *bits = dib->dsBm.bmBits;
1401 return ret;
1403 error:
1404 if (bDesktopDC) DeleteDC( hdc );
1405 if (section) UnmapViewOfFile( mapBits );
1406 else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1407 HeapFree( GetProcessHeap(), 0, dib );
1408 return 0;