Reduced fragment size.
[wine/multimedia.git] / objects / dib.c
blob917b8499f1e5a9b139be73472a9c2599480c96e2
1 /*
2 * GDI device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
6 */
8 #include "bitmap.h"
9 #include "callback.h"
10 #include "dc.h"
11 #include "debug.h"
12 #include "monitor.h"
13 #include "palette.h"
15 /***********************************************************************
16 * DIB_GetDIBWidthBytes
18 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
19 * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
21 int DIB_GetDIBWidthBytes( int width, int depth )
23 int words;
25 switch(depth)
27 case 1: words = (width + 31) / 32; break;
28 case 4: words = (width + 7) / 8; break;
29 case 8: words = (width + 3) / 4; break;
30 case 15:
31 case 16: words = (width + 1) / 2; break;
32 case 24: words = (width * 3 + 3)/4; break;
34 default:
35 WARN(bitmap, "(%d): Unsupported depth\n", depth );
36 /* fall through */
37 case 32:
38 words = width;
40 return 4 * words;
44 /***********************************************************************
45 * DIB_BitmapInfoSize
47 * Return the size of the bitmap info structure including color table.
49 int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse )
51 int colors;
53 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
55 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
56 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
57 return sizeof(BITMAPCOREHEADER) + colors *
58 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
60 else /* assume BITMAPINFOHEADER */
62 colors = info->bmiHeader.biClrUsed;
63 if (!colors && (info->bmiHeader.biBitCount <= 8))
64 colors = 1 << info->bmiHeader.biBitCount;
65 return sizeof(BITMAPINFOHEADER) + colors *
66 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
71 /***********************************************************************
72 * DIB_GetBitmapInfo
74 * Get the info from a bitmap header.
75 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
77 int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
78 int *height, WORD *bpp, WORD *compr )
80 if (header->biSize == sizeof(BITMAPINFOHEADER))
82 *width = header->biWidth;
83 *height = header->biHeight;
84 *bpp = header->biBitCount;
85 *compr = header->biCompression;
86 return 1;
88 if (header->biSize == sizeof(BITMAPCOREHEADER))
90 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
91 *width = core->bcWidth;
92 *height = core->bcHeight;
93 *bpp = core->bcBitCount;
94 *compr = 0;
95 return 0;
97 WARN(bitmap, "(%ld): wrong size for header\n", header->biSize );
98 return -1;
102 /***********************************************************************
103 * StretchDIBits16 (GDI.439)
105 INT16 WINAPI StretchDIBits16(HDC16 hdc, INT16 xDst, INT16 yDst, INT16 widthDst,
106 INT16 heightDst, INT16 xSrc, INT16 ySrc, INT16 widthSrc,
107 INT16 heightSrc, const VOID *bits,
108 const BITMAPINFO *info, UINT16 wUsage, DWORD dwRop )
110 return (INT16)StretchDIBits( hdc, xDst, yDst, widthDst, heightDst,
111 xSrc, ySrc, widthSrc, heightSrc, bits,
112 info, wUsage, dwRop );
116 /***********************************************************************
117 * StretchDIBits32 (GDI32.351)
119 INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
120 INT heightDst, INT xSrc, INT ySrc, INT widthSrc,
121 INT heightSrc, const void *bits,
122 const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
124 DC *dc = DC_GetDCPtr( hdc );
125 if(!dc) return FALSE;
127 if(dc->funcs->pStretchDIBits)
128 return dc->funcs->pStretchDIBits(dc, xDst, yDst, widthDst,
129 heightDst, xSrc, ySrc, widthSrc,
130 heightSrc, bits, info, wUsage,
131 dwRop);
132 else { /* use StretchBlt32 */
133 HBITMAP hBitmap, hOldBitmap;
134 HDC hdcMem;
136 hBitmap = CreateDIBitmap( hdc, &info->bmiHeader, CBM_INIT,
137 bits, info, wUsage );
138 hdcMem = CreateCompatibleDC( hdc );
139 hOldBitmap = SelectObject( hdcMem, hBitmap );
140 /* Origin for DIBitmap is bottom left ! */
141 StretchBlt( hdc, xDst, yDst, widthDst, heightDst,
142 hdcMem, xSrc, info->bmiHeader.biHeight - heightSrc - ySrc,
143 widthSrc, heightSrc, dwRop );
144 SelectObject( hdcMem, hOldBitmap );
145 DeleteDC( hdcMem );
146 DeleteObject( hBitmap );
147 return heightSrc;
152 /***********************************************************************
153 * SetDIBits16 (GDI.440)
155 INT16 WINAPI SetDIBits16( HDC16 hdc, HBITMAP16 hbitmap, UINT16 startscan,
156 UINT16 lines, LPCVOID bits, const BITMAPINFO *info,
157 UINT16 coloruse )
159 return SetDIBits( hdc, hbitmap, startscan, lines, bits, info, coloruse );
163 /******************************************************************************
164 * SetDIBits32 [GDI32.312] Sets pixels in a bitmap using colors from DIB
166 * PARAMS
167 * hdc [I] Handle to device context
168 * hbitmap [I] Handle to bitmap
169 * startscan [I] Starting scan line
170 * lines [I] Number of scan lines
171 * bits [I] Array of bitmap bits
172 * info [I] Address of structure with data
173 * coloruse [I] Type of color indexes to use
175 * RETURNS
176 * Success: Number of scan lines copied
177 * Failure: 0
179 INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
180 UINT lines, LPCVOID bits, const BITMAPINFO *info,
181 UINT coloruse )
183 DC *dc;
184 BITMAPOBJ *bitmap;
185 INT result;
187 /* Check parameters */
188 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
189 if (!dc)
191 dc = (DC *) GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
192 if (!dc) return 0;
195 if (!(bitmap = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
197 GDI_HEAP_UNLOCK( hdc );
198 return 0;
201 result = BITMAP_Driver->pSetDIBits(bitmap, dc, startscan,
202 lines, bits, info,
203 coloruse, hbitmap);
205 GDI_HEAP_UNLOCK( hdc );
206 GDI_HEAP_UNLOCK( hbitmap );
208 return result;
212 /***********************************************************************
213 * SetDIBitsToDevice16 (GDI.443)
215 INT16 WINAPI SetDIBitsToDevice16(HDC16 hdc, INT16 xDest, INT16 yDest, INT16 cx,
216 INT16 cy, INT16 xSrc, INT16 ySrc, UINT16 startscan,
217 UINT16 lines, LPCVOID bits, const BITMAPINFO *info,
218 UINT16 coloruse )
220 return SetDIBitsToDevice( hdc, xDest, yDest, cx, cy, xSrc, ySrc,
221 startscan, lines, bits, info, coloruse );
225 /***********************************************************************
226 * SetDIBitsToDevice32 (GDI32.313)
228 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
229 DWORD cy, INT xSrc, INT ySrc, UINT startscan,
230 UINT lines, LPCVOID bits, const BITMAPINFO *info,
231 UINT coloruse )
233 INT ret;
234 DC *dc;
236 if (!(dc = DC_GetDCPtr( hdc ))) return 0;
238 if(dc->funcs->pSetDIBitsToDevice)
239 ret = dc->funcs->pSetDIBitsToDevice( dc, xDest, yDest, cx, cy, xSrc,
240 ySrc, startscan, lines, bits,
241 info, coloruse );
242 else {
243 FIXME(bitmap, "unimplemented on hdc %08x\n", hdc);
244 ret = 0;
247 GDI_HEAP_UNLOCK( hdc );
248 return ret;
251 /***********************************************************************
252 * SetDIBColorTable16 (GDI.602)
254 UINT16 WINAPI SetDIBColorTable16( HDC16 hdc, UINT16 startpos, UINT16 entries,
255 RGBQUAD *colors )
257 return SetDIBColorTable( hdc, startpos, entries, colors );
260 /***********************************************************************
261 * SetDIBColorTable32 (GDI32.311)
263 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries,
264 RGBQUAD *colors )
266 DC * dc;
267 PALETTEENTRY * palEntry;
268 PALETTEOBJ * palette;
269 RGBQUAD *end;
271 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
272 if (!dc)
274 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
275 if (!dc) return 0;
278 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
280 return 0;
283 /* Transfer color info */
285 if (dc->w.bitsPerPixel <= 8) {
286 palEntry = palette->logpalette.palPalEntry + startpos;
287 if (startpos + entries > (1 << dc->w.bitsPerPixel)) {
288 entries = (1 << dc->w.bitsPerPixel) - startpos;
290 for (end = colors + entries; colors < end; palEntry++, colors++)
292 palEntry->peRed = colors->rgbRed;
293 palEntry->peGreen = colors->rgbGreen;
294 palEntry->peBlue = colors->rgbBlue;
296 } else {
297 entries = 0;
299 GDI_HEAP_UNLOCK( dc->w.hPalette );
300 return entries;
303 /***********************************************************************
304 * GetDIBColorTable16 (GDI.603)
306 UINT16 WINAPI GetDIBColorTable16( HDC16 hdc, UINT16 startpos, UINT16 entries,
307 RGBQUAD *colors )
309 return GetDIBColorTable( hdc, startpos, entries, colors );
312 /***********************************************************************
313 * GetDIBColorTable32 (GDI32.169)
315 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries,
316 RGBQUAD *colors )
318 DC * dc;
319 PALETTEENTRY * palEntry;
320 PALETTEOBJ * palette;
321 RGBQUAD *end;
323 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
324 if (!dc)
326 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
327 if (!dc) return 0;
330 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
332 return 0;
335 /* Transfer color info */
337 if (dc->w.bitsPerPixel <= 8) {
338 palEntry = palette->logpalette.palPalEntry + startpos;
339 if (startpos + entries > (1 << dc->w.bitsPerPixel)) {
340 entries = (1 << dc->w.bitsPerPixel) - startpos;
342 for (end = colors + entries; colors < end; palEntry++, colors++)
344 colors->rgbRed = palEntry->peRed;
345 colors->rgbGreen = palEntry->peGreen;
346 colors->rgbBlue = palEntry->peBlue;
347 colors->rgbReserved = 0;
349 } else {
350 entries = 0;
352 GDI_HEAP_UNLOCK( dc->w.hPalette );
353 return entries;
356 /* FIXME the following two structs should be combined with __sysPalTemplate in
357 objects/color.c - this should happen after de-X11-ing both of these
358 files.
359 NB. RGBQUAD and PALETTENTRY have different orderings of red, green
360 and blue - sigh */
362 static RGBQUAD EGAColors[16] = {
363 /* rgbBlue, rgbGreen, rgbRed, rgbReserverd */
364 { 0x00, 0x00, 0x00, 0x00 },
365 { 0x00, 0x00, 0x80, 0x00 },
366 { 0x00, 0x80, 0x00, 0x00 },
367 { 0x00, 0x80, 0x80, 0x00 },
368 { 0x80, 0x00, 0x00, 0x00 },
369 { 0x80, 0x00, 0x80, 0x00 },
370 { 0x80, 0x80, 0x00, 0x00 },
371 { 0x80, 0x80, 0x80, 0x00 },
372 { 0xc0, 0xc0, 0xc0, 0x00 },
373 { 0x00, 0x00, 0xff, 0x00 },
374 { 0x00, 0xff, 0x00, 0x00 },
375 { 0x00, 0xff, 0xff, 0x00 },
376 { 0xff, 0x00, 0x00, 0x00 },
377 { 0xff, 0x00, 0xff, 0x00 },
378 { 0xff, 0xff, 0x00, 0x00 },
379 { 0xff, 0xff, 0xff, 0x00 }
383 static RGBQUAD DefLogPalette[20] = { /* Copy of Default Logical Palette */
384 /* rgbBlue, rgbGreen, rgbRed, rgbReserverd */
385 { 0x00, 0x00, 0x00, 0x00 },
386 { 0x00, 0x00, 0x80, 0x00 },
387 { 0x00, 0x80, 0x00, 0x00 },
388 { 0x00, 0x80, 0x80, 0x00 },
389 { 0x80, 0x00, 0x00, 0x00 },
390 { 0x80, 0x00, 0x80, 0x00 },
391 { 0x80, 0x80, 0x00, 0x00 },
392 { 0xc0, 0xc0, 0xc0, 0x00 },
393 { 0xc0, 0xdc, 0xc0, 0x00 },
394 { 0xf0, 0xca, 0xa6, 0x00 },
395 { 0xf0, 0xfb, 0xff, 0x00 },
396 { 0xa4, 0xa0, 0xa0, 0x00 },
397 { 0x80, 0x80, 0x80, 0x00 },
398 { 0x00, 0x00, 0xf0, 0x00 },
399 { 0x00, 0xff, 0x00, 0x00 },
400 { 0x00, 0xff, 0xff, 0x00 },
401 { 0xff, 0x00, 0x00, 0x00 },
402 { 0xff, 0x00, 0xff, 0x00 },
403 { 0xff, 0xff, 0x00, 0x00 },
404 { 0xff, 0xff, 0xff, 0x00 }
407 /***********************************************************************
408 * GetDIBits16 (GDI.441)
410 INT16 WINAPI GetDIBits16( HDC16 hdc, HBITMAP16 hbitmap, UINT16 startscan,
411 UINT16 lines, LPVOID bits, BITMAPINFO * info,
412 UINT16 coloruse )
414 return GetDIBits( hdc, hbitmap, startscan, lines, bits, info, coloruse );
418 /******************************************************************************
419 * GetDIBits32 [GDI32.170] Retrieves bits of bitmap and copies to buffer
421 * RETURNS
422 * Success: Number of scan lines copied from bitmap
423 * Failure: 0
425 * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/func/src/f30_14.htm
427 INT WINAPI GetDIBits(
428 HDC hdc, /* [in] Handle to device context */
429 HBITMAP hbitmap, /* [in] Handle to bitmap */
430 UINT startscan, /* [in] First scan line to set in dest bitmap */
431 UINT lines, /* [in] Number of scan lines to copy */
432 LPVOID bits, /* [out] Address of array for bitmap bits */
433 BITMAPINFO * info, /* [out] Address of structure with bitmap data */
434 UINT coloruse) /* [in] RGB or palette index */
436 DC * dc;
437 BITMAPOBJ * bmp;
438 PALETTEENTRY * palEntry;
439 PALETTEOBJ * palette;
440 int i;
442 if (!lines) return 0;
443 if (!info) return 0;
444 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
445 if (!dc)
447 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
448 if (!dc) return 0;
450 if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
452 GDI_HEAP_UNLOCK( hdc );
453 return 0;
455 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
457 GDI_HEAP_UNLOCK( hdc );
458 GDI_HEAP_UNLOCK( hbitmap );
459 return 0;
462 /* Transfer color info */
464 if (info->bmiHeader.biBitCount <= 8 && info->bmiHeader.biBitCount > 0 ) {
466 info->bmiHeader.biClrUsed = 0;
468 if(info->bmiHeader.biBitCount >= bmp->bitmap.bmBitsPixel) {
469 palEntry = palette->logpalette.palPalEntry;
470 for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++, palEntry++) {
471 if (coloruse == DIB_RGB_COLORS) {
472 info->bmiColors[i].rgbRed = palEntry->peRed;
473 info->bmiColors[i].rgbGreen = palEntry->peGreen;
474 info->bmiColors[i].rgbBlue = palEntry->peBlue;
475 info->bmiColors[i].rgbReserved = 0;
477 else ((WORD *)info->bmiColors)[i] = (WORD)i;
479 } else {
480 switch (info->bmiHeader.biBitCount) {
481 case 1:
482 info->bmiColors[0].rgbRed = info->bmiColors[0].rgbGreen =
483 info->bmiColors[0].rgbBlue = 0;
484 info->bmiColors[0].rgbReserved = 0;
485 info->bmiColors[1].rgbRed = info->bmiColors[1].rgbGreen =
486 info->bmiColors[1].rgbBlue = 0xff;
487 info->bmiColors[1].rgbReserved = 0;
488 break;
490 case 4:
491 memcpy(info->bmiColors, EGAColors, sizeof(EGAColors));
492 break;
494 case 8:
496 INT r, g, b;
497 RGBQUAD *color;
499 memcpy(info->bmiColors, DefLogPalette,
500 10 * sizeof(RGBQUAD));
501 memcpy(info->bmiColors + 246, DefLogPalette + 10,
502 10 * sizeof(RGBQUAD));
503 color = info->bmiColors + 10;
504 for(r = 0; r <= 5; r++) /* FIXME */
505 for(g = 0; g <= 5; g++)
506 for(b = 0; b <= 5; b++) {
507 color->rgbRed = (r * 0xff) / 5;
508 color->rgbGreen = (g * 0xff) / 5;
509 color->rgbBlue = (b * 0xff) / 5;
510 color->rgbReserved = 0;
511 color++;
518 GDI_HEAP_UNLOCK( dc->w.hPalette );
520 if (bits)
522 if(!BITMAP_Driver->pGetDIBits(bmp, dc, startscan, lines, bits, info, coloruse, hbitmap))
524 GDI_HEAP_UNLOCK( hdc );
525 GDI_HEAP_UNLOCK( hbitmap );
527 return FALSE;
530 else if( info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
532 /* fill in struct members */
534 if( info->bmiHeader.biBitCount == 0)
536 info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
537 info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
538 info->bmiHeader.biPlanes = 1;
539 info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
540 info->bmiHeader.biSizeImage = bmp->bitmap.bmHeight *
541 DIB_GetDIBWidthBytes( bmp->bitmap.bmWidth,
542 bmp->bitmap.bmBitsPixel );
543 info->bmiHeader.biCompression = 0;
545 else
547 info->bmiHeader.biSizeImage = info->bmiHeader.biHeight *
548 DIB_GetDIBWidthBytes( info->bmiHeader.biWidth,
549 info->bmiHeader.biBitCount );
553 TRACE(bitmap, "biSizeImage = %ld, biWidth = %ld, biHeight = %ld\n",
554 info->bmiHeader.biSizeImage, info->bmiHeader.biWidth,
555 info->bmiHeader.biHeight);
557 GDI_HEAP_UNLOCK( hdc );
558 GDI_HEAP_UNLOCK( hbitmap );
560 return lines;
564 /***********************************************************************
565 * CreateDIBitmap16 (GDI.442)
567 HBITMAP16 WINAPI CreateDIBitmap16( HDC16 hdc, const BITMAPINFOHEADER * header,
568 DWORD init, LPCVOID bits, const BITMAPINFO * data,
569 UINT16 coloruse )
571 return CreateDIBitmap( hdc, header, init, bits, data, coloruse );
575 /***********************************************************************
576 * CreateDIBitmap32 (GDI32.37)
578 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
579 DWORD init, LPCVOID bits, const BITMAPINFO *data,
580 UINT coloruse )
582 HBITMAP handle;
583 BOOL fColor;
584 DWORD width;
585 int height;
586 WORD bpp;
587 WORD compr;
589 if (DIB_GetBitmapInfo( header, &width, &height, &bpp, &compr ) == -1) return 0;
590 if (height < 0) height = -height;
592 /* Check if we should create a monochrome or color bitmap. */
593 /* We create a monochrome bitmap only if it has exactly 2 */
594 /* colors, which are either black or white, nothing else. */
595 /* In all other cases, we create a color bitmap. */
597 if (bpp != 1) fColor = TRUE;
598 else if ((coloruse != DIB_RGB_COLORS) ||
599 (init != CBM_INIT) || !data) fColor = FALSE;
600 else
602 if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
604 RGBQUAD *rgb = data->bmiColors;
605 DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
606 if ((col == RGB(0,0,0)) || (col == RGB(0xff,0xff,0xff)))
608 rgb++;
609 col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
610 fColor = ((col != RGB(0,0,0)) && (col != RGB(0xff,0xff,0xff)));
612 else fColor = TRUE;
614 else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
616 RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
617 DWORD col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
618 if ((col == RGB(0,0,0)) || (col == RGB(0xff,0xff,0xff)))
620 rgb++;
621 col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
622 fColor = ((col != RGB(0,0,0)) && (col != RGB(0xff,0xff,0xff)));
624 else fColor = TRUE;
626 else
628 WARN(bitmap, "(%ld): wrong size for data\n",
629 data->bmiHeader.biSize );
630 return 0;
634 /* Now create the bitmap */
636 handle = fColor ? CreateBitmap( width, height, 1, MONITOR_GetDepth(&MONITOR_PrimaryMonitor), NULL ) :
637 CreateBitmap( width, height, 1, 1, NULL );
638 if (!handle) return 0;
640 if (init == CBM_INIT)
641 SetDIBits( hdc, handle, 0, height, bits, data, coloruse );
642 return handle;
645 /***********************************************************************
646 * CreateDIBSection16 (GDI.489)
648 HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, BITMAPINFO *bmi, UINT16 usage,
649 SEGPTR *bits, HANDLE section,
650 DWORD offset)
652 HBITMAP16 hbitmap;
653 DC *dc = (DC *) GDI_GetObjPtr(hdc, DC_MAGIC);
654 if(!dc) dc = (DC *) GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
655 if(!dc) return (HBITMAP16) NULL;
657 hbitmap = dc->funcs->pCreateDIBSection16(dc, bmi, usage, bits, section, offset);
659 GDI_HEAP_UNLOCK(hdc);
661 return hbitmap;
664 /***********************************************************************
665 * CreateDIBSection32 (GDI32.36)
667 HBITMAP WINAPI CreateDIBSection(HDC hdc, BITMAPINFO *bmi, UINT usage,
668 LPVOID *bits, HANDLE section,
669 DWORD offset)
671 HBITMAP hbitmap;
672 DC *dc = (DC *) GDI_GetObjPtr(hdc, DC_MAGIC);
673 if(!dc) dc = (DC *) GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
674 if(!dc) return (HBITMAP) NULL;
676 hbitmap = dc->funcs->pCreateDIBSection(dc, bmi, usage, bits, section, offset);
678 GDI_HEAP_UNLOCK(hdc);
680 return hbitmap;
683 /***********************************************************************
684 * DIB_DeleteDIBSection
686 void DIB_DeleteDIBSection( BITMAPOBJ *bmp )
688 if (bmp && bmp->dib)
690 DIBSECTION *dib = bmp->dib;
692 if (dib->dsBm.bmBits)
694 if (dib->dshSection)
695 UnmapViewOfFile(dib->dsBm.bmBits);
696 else
697 VirtualFree(dib->dsBm.bmBits, MEM_RELEASE, 0L);
700 BITMAP_Driver->pDeleteDIBSection(bmp);
702 HeapFree(GetProcessHeap(), 0, dib);
703 bmp->dib = NULL;
707 /***********************************************************************
708 * DIB_FixColorsToLoadflags
710 * Change color table entries when LR_LOADTRANSPARENT or LR_LOADMAP3DCOLORS
711 * are in loadflags
713 void DIB_FixColorsToLoadflags(BITMAPINFO * bmi, UINT loadflags, BYTE pix)
715 int colors;
716 COLORREF c_W, c_S, c_F, c_L, c_C;
717 int incr,i;
718 RGBQUAD *ptr;
720 if (bmi->bmiHeader.biBitCount > 8) return;
721 if (bmi->bmiHeader.biSize == sizeof(BITMAPINFOHEADER)) incr = 4;
722 else if (bmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) incr = 3;
723 else {
724 WARN(bitmap, "Wrong bitmap header size!\n");
725 return;
727 colors = bmi->bmiHeader.biClrUsed;
728 if (!colors && (bmi->bmiHeader.biBitCount <= 8))
729 colors = 1 << bmi->bmiHeader.biBitCount;
730 c_W = GetSysColor(COLOR_WINDOW);
731 c_S = GetSysColor(COLOR_3DSHADOW);
732 c_F = GetSysColor(COLOR_3DFACE);
733 c_L = GetSysColor(COLOR_3DLIGHT);
734 if (loadflags & LR_LOADTRANSPARENT) {
735 switch (bmi->bmiHeader.biBitCount) {
736 case 1: pix = pix >> 7; break;
737 case 4: pix = pix >> 4; break;
738 case 8: break;
739 default:
740 WARN(bitmap, "(%d): Unsupported depth\n", bmi->bmiHeader.biBitCount);
741 return;
743 if (pix >= colors) {
744 WARN(bitmap, "pixel has color index greater than biClrUsed!\n");
745 return;
747 if (loadflags & LR_LOADMAP3DCOLORS) c_W = c_F;
748 ptr = (RGBQUAD*)((char*)bmi->bmiColors+pix*incr);
749 ptr->rgbBlue = GetBValue(c_W);
750 ptr->rgbGreen = GetGValue(c_W);
751 ptr->rgbRed = GetRValue(c_W);
753 if (loadflags & LR_LOADMAP3DCOLORS)
754 for (i=0; i<colors; i++) {
755 ptr = (RGBQUAD*)((char*)bmi->bmiColors+i*incr);
756 c_C = RGB(ptr->rgbRed, ptr->rgbGreen, ptr->rgbBlue);
757 if (c_C == RGB(128, 128, 128)) {
758 ptr->rgbRed = GetRValue(c_S);
759 ptr->rgbGreen = GetGValue(c_S);
760 ptr->rgbBlue = GetBValue(c_S);
761 } else if (c_C == RGB(192, 192, 192)) {
762 ptr->rgbRed = GetRValue(c_F);
763 ptr->rgbGreen = GetGValue(c_F);
764 ptr->rgbBlue = GetBValue(c_F);
765 } else if (c_C == RGB(223, 223, 223)) {
766 ptr->rgbRed = GetRValue(c_L);
767 ptr->rgbGreen = GetGValue(c_L);
768 ptr->rgbBlue = GetBValue(c_L);