New debug scheme with explicit debug channels declaration.
[wine/hacks.git] / objects / dib.c
blob5d10b56decf75524691c7b384a17b4943b7a3a74
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 DEFAULT_DEBUG_CHANNEL(bitmap)
17 /***********************************************************************
18 * DIB_GetDIBWidthBytes
20 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
21 * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
23 int DIB_GetDIBWidthBytes( int width, int depth )
25 int words;
27 switch(depth)
29 case 1: words = (width + 31) / 32; break;
30 case 4: words = (width + 7) / 8; break;
31 case 8: words = (width + 3) / 4; break;
32 case 15:
33 case 16: words = (width + 1) / 2; break;
34 case 24: words = (width * 3 + 3)/4; break;
36 default:
37 WARN(bitmap, "(%d): Unsupported depth\n", depth );
38 /* fall through */
39 case 32:
40 words = width;
42 return 4 * words;
45 /***********************************************************************
46 * DIB_GetDIBImageBytes
48 * Return the number of bytes used to hold the image in a DIB bitmap.
50 int DIB_GetDIBImageBytes( int width, int height, int depth )
52 return DIB_GetDIBWidthBytes( width, depth ) * abs( height );
56 /***********************************************************************
57 * DIB_BitmapInfoSize
59 * Return the size of the bitmap info structure including color table.
61 int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse )
63 int colors;
65 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
67 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
68 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
69 return sizeof(BITMAPCOREHEADER) + colors *
70 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
72 else /* assume BITMAPINFOHEADER */
74 colors = info->bmiHeader.biClrUsed;
75 if (!colors && (info->bmiHeader.biBitCount <= 8))
76 colors = 1 << info->bmiHeader.biBitCount;
77 return sizeof(BITMAPINFOHEADER) + colors *
78 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
83 /***********************************************************************
84 * DIB_GetBitmapInfo
86 * Get the info from a bitmap header.
87 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
89 int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
90 int *height, WORD *bpp, WORD *compr )
92 if (header->biSize == sizeof(BITMAPINFOHEADER))
94 *width = header->biWidth;
95 *height = header->biHeight;
96 *bpp = header->biBitCount;
97 *compr = header->biCompression;
98 return 1;
100 if (header->biSize == sizeof(BITMAPCOREHEADER))
102 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
103 *width = core->bcWidth;
104 *height = core->bcHeight;
105 *bpp = core->bcBitCount;
106 *compr = 0;
107 return 0;
109 WARN(bitmap, "(%ld): wrong size for header\n", header->biSize );
110 return -1;
114 /***********************************************************************
115 * StretchDIBits16 (GDI.439)
117 INT16 WINAPI StretchDIBits16(HDC16 hdc, INT16 xDst, INT16 yDst, INT16 widthDst,
118 INT16 heightDst, INT16 xSrc, INT16 ySrc, INT16 widthSrc,
119 INT16 heightSrc, const VOID *bits,
120 const BITMAPINFO *info, UINT16 wUsage, DWORD dwRop )
122 return (INT16)StretchDIBits( hdc, xDst, yDst, widthDst, heightDst,
123 xSrc, ySrc, widthSrc, heightSrc, bits,
124 info, wUsage, dwRop );
128 /***********************************************************************
129 * StretchDIBits32 (GDI32.351)
131 INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
132 INT heightDst, INT xSrc, INT ySrc, INT widthSrc,
133 INT heightSrc, const void *bits,
134 const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
136 DC *dc = DC_GetDCPtr( hdc );
137 if(!dc) return FALSE;
139 if(dc->funcs->pStretchDIBits)
140 return dc->funcs->pStretchDIBits(dc, xDst, yDst, widthDst,
141 heightDst, xSrc, ySrc, widthSrc,
142 heightSrc, bits, info, wUsage,
143 dwRop);
144 else { /* use StretchBlt32 */
145 HBITMAP hBitmap, hOldBitmap;
146 HDC hdcMem;
148 hBitmap = CreateDIBitmap( hdc, &info->bmiHeader, CBM_INIT,
149 bits, info, wUsage );
150 hdcMem = CreateCompatibleDC( hdc );
151 hOldBitmap = SelectObject( hdcMem, hBitmap );
152 /* Origin for DIBitmap is bottom left ! */
153 StretchBlt( hdc, xDst, yDst, widthDst, heightDst,
154 hdcMem, xSrc, info->bmiHeader.biHeight - heightSrc - ySrc,
155 widthSrc, heightSrc, dwRop );
156 SelectObject( hdcMem, hOldBitmap );
157 DeleteDC( hdcMem );
158 DeleteObject( hBitmap );
159 return heightSrc;
164 /***********************************************************************
165 * SetDIBits16 (GDI.440)
167 INT16 WINAPI SetDIBits16( HDC16 hdc, HBITMAP16 hbitmap, UINT16 startscan,
168 UINT16 lines, LPCVOID bits, const BITMAPINFO *info,
169 UINT16 coloruse )
171 return SetDIBits( hdc, hbitmap, startscan, lines, bits, info, coloruse );
175 /******************************************************************************
176 * SetDIBits32 [GDI32.312] Sets pixels in a bitmap using colors from DIB
178 * PARAMS
179 * hdc [I] Handle to device context
180 * hbitmap [I] Handle to bitmap
181 * startscan [I] Starting scan line
182 * lines [I] Number of scan lines
183 * bits [I] Array of bitmap bits
184 * info [I] Address of structure with data
185 * coloruse [I] Type of color indexes to use
187 * RETURNS
188 * Success: Number of scan lines copied
189 * Failure: 0
191 INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
192 UINT lines, LPCVOID bits, const BITMAPINFO *info,
193 UINT coloruse )
195 DC *dc;
196 BITMAPOBJ *bitmap;
197 INT result;
199 /* Check parameters */
200 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
201 if (!dc)
203 dc = (DC *) GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
204 if (!dc) return 0;
207 if (!(bitmap = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
209 GDI_HEAP_UNLOCK( hdc );
210 return 0;
213 result = BITMAP_Driver->pSetDIBits(bitmap, dc, startscan,
214 lines, bits, info,
215 coloruse, hbitmap);
217 GDI_HEAP_UNLOCK( hdc );
218 GDI_HEAP_UNLOCK( hbitmap );
220 return result;
224 /***********************************************************************
225 * SetDIBitsToDevice16 (GDI.443)
227 INT16 WINAPI SetDIBitsToDevice16(HDC16 hdc, INT16 xDest, INT16 yDest, INT16 cx,
228 INT16 cy, INT16 xSrc, INT16 ySrc, UINT16 startscan,
229 UINT16 lines, LPCVOID bits, const BITMAPINFO *info,
230 UINT16 coloruse )
232 return SetDIBitsToDevice( hdc, xDest, yDest, cx, cy, xSrc, ySrc,
233 startscan, lines, bits, info, coloruse );
237 /***********************************************************************
238 * SetDIBitsToDevice32 (GDI32.313)
240 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
241 DWORD cy, INT xSrc, INT ySrc, UINT startscan,
242 UINT lines, LPCVOID bits, const BITMAPINFO *info,
243 UINT coloruse )
245 INT ret;
246 DC *dc;
248 if (!(dc = DC_GetDCPtr( hdc ))) return 0;
250 if(dc->funcs->pSetDIBitsToDevice)
251 ret = dc->funcs->pSetDIBitsToDevice( dc, xDest, yDest, cx, cy, xSrc,
252 ySrc, startscan, lines, bits,
253 info, coloruse );
254 else {
255 FIXME(bitmap, "unimplemented on hdc %08x\n", hdc);
256 ret = 0;
259 GDI_HEAP_UNLOCK( hdc );
260 return ret;
263 /***********************************************************************
264 * SetDIBColorTable16 (GDI.602)
266 UINT16 WINAPI SetDIBColorTable16( HDC16 hdc, UINT16 startpos, UINT16 entries,
267 RGBQUAD *colors )
269 return SetDIBColorTable( hdc, startpos, entries, colors );
272 /***********************************************************************
273 * SetDIBColorTable32 (GDI32.311)
275 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries,
276 RGBQUAD *colors )
278 DC * dc;
279 PALETTEENTRY * palEntry;
280 PALETTEOBJ * palette;
281 RGBQUAD *end;
283 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
284 if (!dc)
286 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
287 if (!dc) return 0;
290 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
292 return 0;
295 /* Transfer color info */
297 if (dc->w.bitsPerPixel <= 8) {
298 palEntry = palette->logpalette.palPalEntry + startpos;
299 if (startpos + entries > (1 << dc->w.bitsPerPixel)) {
300 entries = (1 << dc->w.bitsPerPixel) - startpos;
302 for (end = colors + entries; colors < end; palEntry++, colors++)
304 palEntry->peRed = colors->rgbRed;
305 palEntry->peGreen = colors->rgbGreen;
306 palEntry->peBlue = colors->rgbBlue;
308 } else {
309 entries = 0;
311 GDI_HEAP_UNLOCK( dc->w.hPalette );
312 return entries;
315 /***********************************************************************
316 * GetDIBColorTable16 (GDI.603)
318 UINT16 WINAPI GetDIBColorTable16( HDC16 hdc, UINT16 startpos, UINT16 entries,
319 RGBQUAD *colors )
321 return GetDIBColorTable( hdc, startpos, entries, colors );
324 /***********************************************************************
325 * GetDIBColorTable32 (GDI32.169)
327 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries,
328 RGBQUAD *colors )
330 DC * dc;
331 PALETTEENTRY * palEntry;
332 PALETTEOBJ * palette;
333 RGBQUAD *end;
335 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
336 if (!dc)
338 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
339 if (!dc) return 0;
342 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
344 return 0;
347 /* Transfer color info */
349 if (dc->w.bitsPerPixel <= 8) {
350 palEntry = palette->logpalette.palPalEntry + startpos;
351 if (startpos + entries > (1 << dc->w.bitsPerPixel)) {
352 entries = (1 << dc->w.bitsPerPixel) - startpos;
354 for (end = colors + entries; colors < end; palEntry++, colors++)
356 colors->rgbRed = palEntry->peRed;
357 colors->rgbGreen = palEntry->peGreen;
358 colors->rgbBlue = palEntry->peBlue;
359 colors->rgbReserved = 0;
361 } else {
362 entries = 0;
364 GDI_HEAP_UNLOCK( dc->w.hPalette );
365 return entries;
368 /* FIXME the following two structs should be combined with __sysPalTemplate in
369 objects/color.c - this should happen after de-X11-ing both of these
370 files.
371 NB. RGBQUAD and PALETTENTRY have different orderings of red, green
372 and blue - sigh */
374 static RGBQUAD EGAColors[16] = {
375 /* rgbBlue, rgbGreen, rgbRed, rgbReserverd */
376 { 0x00, 0x00, 0x00, 0x00 },
377 { 0x00, 0x00, 0x80, 0x00 },
378 { 0x00, 0x80, 0x00, 0x00 },
379 { 0x00, 0x80, 0x80, 0x00 },
380 { 0x80, 0x00, 0x00, 0x00 },
381 { 0x80, 0x00, 0x80, 0x00 },
382 { 0x80, 0x80, 0x00, 0x00 },
383 { 0x80, 0x80, 0x80, 0x00 },
384 { 0xc0, 0xc0, 0xc0, 0x00 },
385 { 0x00, 0x00, 0xff, 0x00 },
386 { 0x00, 0xff, 0x00, 0x00 },
387 { 0x00, 0xff, 0xff, 0x00 },
388 { 0xff, 0x00, 0x00, 0x00 },
389 { 0xff, 0x00, 0xff, 0x00 },
390 { 0xff, 0xff, 0x00, 0x00 },
391 { 0xff, 0xff, 0xff, 0x00 }
395 static RGBQUAD DefLogPalette[20] = { /* Copy of Default Logical Palette */
396 /* rgbBlue, rgbGreen, rgbRed, rgbReserverd */
397 { 0x00, 0x00, 0x00, 0x00 },
398 { 0x00, 0x00, 0x80, 0x00 },
399 { 0x00, 0x80, 0x00, 0x00 },
400 { 0x00, 0x80, 0x80, 0x00 },
401 { 0x80, 0x00, 0x00, 0x00 },
402 { 0x80, 0x00, 0x80, 0x00 },
403 { 0x80, 0x80, 0x00, 0x00 },
404 { 0xc0, 0xc0, 0xc0, 0x00 },
405 { 0xc0, 0xdc, 0xc0, 0x00 },
406 { 0xf0, 0xca, 0xa6, 0x00 },
407 { 0xf0, 0xfb, 0xff, 0x00 },
408 { 0xa4, 0xa0, 0xa0, 0x00 },
409 { 0x80, 0x80, 0x80, 0x00 },
410 { 0x00, 0x00, 0xf0, 0x00 },
411 { 0x00, 0xff, 0x00, 0x00 },
412 { 0x00, 0xff, 0xff, 0x00 },
413 { 0xff, 0x00, 0x00, 0x00 },
414 { 0xff, 0x00, 0xff, 0x00 },
415 { 0xff, 0xff, 0x00, 0x00 },
416 { 0xff, 0xff, 0xff, 0x00 }
419 /***********************************************************************
420 * GetDIBits16 (GDI.441)
422 INT16 WINAPI GetDIBits16( HDC16 hdc, HBITMAP16 hbitmap, UINT16 startscan,
423 UINT16 lines, LPVOID bits, BITMAPINFO * info,
424 UINT16 coloruse )
426 return GetDIBits( hdc, hbitmap, startscan, lines, bits, info, coloruse );
430 /******************************************************************************
431 * GetDIBits32 [GDI32.170] Retrieves bits of bitmap and copies to buffer
433 * RETURNS
434 * Success: Number of scan lines copied from bitmap
435 * Failure: 0
437 * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/func/src/f30_14.htm
439 INT WINAPI GetDIBits(
440 HDC hdc, /* [in] Handle to device context */
441 HBITMAP hbitmap, /* [in] Handle to bitmap */
442 UINT startscan, /* [in] First scan line to set in dest bitmap */
443 UINT lines, /* [in] Number of scan lines to copy */
444 LPVOID bits, /* [out] Address of array for bitmap bits */
445 BITMAPINFO * info, /* [out] Address of structure with bitmap data */
446 UINT coloruse) /* [in] RGB or palette index */
448 DC * dc;
449 BITMAPOBJ * bmp;
450 PALETTEENTRY * palEntry;
451 PALETTEOBJ * palette;
452 int i;
454 if (!lines) return 0;
455 if (!info) return 0;
456 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
457 if (!dc)
459 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
460 if (!dc) return 0;
462 if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
464 GDI_HEAP_UNLOCK( hdc );
465 return 0;
467 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
469 GDI_HEAP_UNLOCK( hdc );
470 GDI_HEAP_UNLOCK( hbitmap );
471 return 0;
474 /* Transfer color info */
476 if (info->bmiHeader.biBitCount <= 8 && info->bmiHeader.biBitCount > 0 ) {
478 info->bmiHeader.biClrUsed = 0;
480 if(info->bmiHeader.biBitCount >= bmp->bitmap.bmBitsPixel) {
481 palEntry = palette->logpalette.palPalEntry;
482 for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++, palEntry++) {
483 if (coloruse == DIB_RGB_COLORS) {
484 info->bmiColors[i].rgbRed = palEntry->peRed;
485 info->bmiColors[i].rgbGreen = palEntry->peGreen;
486 info->bmiColors[i].rgbBlue = palEntry->peBlue;
487 info->bmiColors[i].rgbReserved = 0;
489 else ((WORD *)info->bmiColors)[i] = (WORD)i;
491 } else {
492 switch (info->bmiHeader.biBitCount) {
493 case 1:
494 info->bmiColors[0].rgbRed = info->bmiColors[0].rgbGreen =
495 info->bmiColors[0].rgbBlue = 0;
496 info->bmiColors[0].rgbReserved = 0;
497 info->bmiColors[1].rgbRed = info->bmiColors[1].rgbGreen =
498 info->bmiColors[1].rgbBlue = 0xff;
499 info->bmiColors[1].rgbReserved = 0;
500 break;
502 case 4:
503 memcpy(info->bmiColors, EGAColors, sizeof(EGAColors));
504 break;
506 case 8:
508 INT r, g, b;
509 RGBQUAD *color;
511 memcpy(info->bmiColors, DefLogPalette,
512 10 * sizeof(RGBQUAD));
513 memcpy(info->bmiColors + 246, DefLogPalette + 10,
514 10 * sizeof(RGBQUAD));
515 color = info->bmiColors + 10;
516 for(r = 0; r <= 5; r++) /* FIXME */
517 for(g = 0; g <= 5; g++)
518 for(b = 0; b <= 5; b++) {
519 color->rgbRed = (r * 0xff) / 5;
520 color->rgbGreen = (g * 0xff) / 5;
521 color->rgbBlue = (b * 0xff) / 5;
522 color->rgbReserved = 0;
523 color++;
530 GDI_HEAP_UNLOCK( dc->w.hPalette );
532 if (bits)
534 if(!BITMAP_Driver->pGetDIBits(bmp, dc, startscan, lines, bits, info, coloruse, hbitmap))
536 GDI_HEAP_UNLOCK( hdc );
537 GDI_HEAP_UNLOCK( hbitmap );
539 return FALSE;
542 else if( info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
544 /* fill in struct members */
546 if( info->bmiHeader.biBitCount == 0)
548 info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
549 info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
550 info->bmiHeader.biPlanes = 1;
551 info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
552 info->bmiHeader.biSizeImage =
553 DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
554 bmp->bitmap.bmHeight,
555 bmp->bitmap.bmBitsPixel );
556 info->bmiHeader.biCompression = 0;
558 else
560 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
561 info->bmiHeader.biWidth,
562 info->bmiHeader.biHeight,
563 info->bmiHeader.biBitCount );
567 TRACE(bitmap, "biSizeImage = %ld, biWidth = %ld, biHeight = %ld\n",
568 info->bmiHeader.biSizeImage, info->bmiHeader.biWidth,
569 info->bmiHeader.biHeight);
571 GDI_HEAP_UNLOCK( hdc );
572 GDI_HEAP_UNLOCK( hbitmap );
574 return lines;
578 /***********************************************************************
579 * CreateDIBitmap16 (GDI.442)
581 HBITMAP16 WINAPI CreateDIBitmap16( HDC16 hdc, const BITMAPINFOHEADER * header,
582 DWORD init, LPCVOID bits, const BITMAPINFO * data,
583 UINT16 coloruse )
585 return CreateDIBitmap( hdc, header, init, bits, data, coloruse );
589 /***********************************************************************
590 * CreateDIBitmap32 (GDI32.37)
592 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
593 DWORD init, LPCVOID bits, const BITMAPINFO *data,
594 UINT coloruse )
596 HBITMAP handle;
597 BOOL fColor;
598 DWORD width;
599 int height;
600 WORD bpp;
601 WORD compr;
603 if (DIB_GetBitmapInfo( header, &width, &height, &bpp, &compr ) == -1) return 0;
604 if (height < 0) height = -height;
606 /* Check if we should create a monochrome or color bitmap. */
607 /* We create a monochrome bitmap only if it has exactly 2 */
608 /* colors, which are either black or white, nothing else. */
609 /* In all other cases, we create a color bitmap. */
611 if (bpp != 1) fColor = TRUE;
612 else if ((coloruse != DIB_RGB_COLORS) ||
613 (init != CBM_INIT) || !data) fColor = FALSE;
614 else
616 if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
618 RGBQUAD *rgb = data->bmiColors;
619 DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
620 if ((col == RGB(0,0,0)) || (col == RGB(0xff,0xff,0xff)))
622 rgb++;
623 col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
624 fColor = ((col != RGB(0,0,0)) && (col != RGB(0xff,0xff,0xff)));
626 else fColor = TRUE;
628 else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
630 RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
631 DWORD col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
632 if ((col == RGB(0,0,0)) || (col == RGB(0xff,0xff,0xff)))
634 rgb++;
635 col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
636 fColor = ((col != RGB(0,0,0)) && (col != RGB(0xff,0xff,0xff)));
638 else fColor = TRUE;
640 else
642 WARN(bitmap, "(%ld): wrong size for data\n",
643 data->bmiHeader.biSize );
644 return 0;
648 /* Now create the bitmap */
650 handle = fColor ? CreateBitmap( width, height, 1, MONITOR_GetDepth(&MONITOR_PrimaryMonitor), NULL ) :
651 CreateBitmap( width, height, 1, 1, NULL );
652 if (!handle) return 0;
654 if (init == CBM_INIT)
655 SetDIBits( hdc, handle, 0, height, bits, data, coloruse );
656 return handle;
659 /***********************************************************************
660 * CreateDIBSection16 (GDI.489)
662 HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, BITMAPINFO *bmi, UINT16 usage,
663 SEGPTR *bits, HANDLE section,
664 DWORD offset)
666 HBITMAP16 hbitmap;
667 DC *dc = (DC *) GDI_GetObjPtr(hdc, DC_MAGIC);
668 if(!dc) dc = (DC *) GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
669 if(!dc) return (HBITMAP16) NULL;
671 hbitmap = dc->funcs->pCreateDIBSection16(dc, bmi, usage, bits, section, offset);
673 GDI_HEAP_UNLOCK(hdc);
675 return hbitmap;
678 /***********************************************************************
679 * CreateDIBSection32 (GDI32.36)
681 HBITMAP WINAPI CreateDIBSection(HDC hdc, BITMAPINFO *bmi, UINT usage,
682 LPVOID *bits, HANDLE section,
683 DWORD offset)
685 HBITMAP hbitmap;
686 DC *dc = (DC *) GDI_GetObjPtr(hdc, DC_MAGIC);
687 if(!dc) dc = (DC *) GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
688 if(!dc) return (HBITMAP) NULL;
690 hbitmap = dc->funcs->pCreateDIBSection(dc, bmi, usage, bits, section, offset);
692 GDI_HEAP_UNLOCK(hdc);
694 return hbitmap;
697 /***********************************************************************
698 * DIB_DeleteDIBSection
700 void DIB_DeleteDIBSection( BITMAPOBJ *bmp )
702 if (bmp && bmp->dib)
704 DIBSECTION *dib = bmp->dib;
706 if (dib->dsBm.bmBits)
708 if (dib->dshSection)
709 UnmapViewOfFile(dib->dsBm.bmBits);
710 else
711 VirtualFree(dib->dsBm.bmBits, MEM_RELEASE, 0L);
714 BITMAP_Driver->pDeleteDIBSection(bmp);
716 HeapFree(GetProcessHeap(), 0, dib);
717 bmp->dib = NULL;
721 /***********************************************************************
722 * DIB_FixColorsToLoadflags
724 * Change color table entries when LR_LOADTRANSPARENT or LR_LOADMAP3DCOLORS
725 * are in loadflags
727 void DIB_FixColorsToLoadflags(BITMAPINFO * bmi, UINT loadflags, BYTE pix)
729 int colors;
730 COLORREF c_W, c_S, c_F, c_L, c_C;
731 int incr,i;
732 RGBQUAD *ptr;
734 if (bmi->bmiHeader.biBitCount > 8) return;
735 if (bmi->bmiHeader.biSize == sizeof(BITMAPINFOHEADER)) incr = 4;
736 else if (bmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) incr = 3;
737 else {
738 WARN(bitmap, "Wrong bitmap header size!\n");
739 return;
741 colors = bmi->bmiHeader.biClrUsed;
742 if (!colors && (bmi->bmiHeader.biBitCount <= 8))
743 colors = 1 << bmi->bmiHeader.biBitCount;
744 c_W = GetSysColor(COLOR_WINDOW);
745 c_S = GetSysColor(COLOR_3DSHADOW);
746 c_F = GetSysColor(COLOR_3DFACE);
747 c_L = GetSysColor(COLOR_3DLIGHT);
748 if (loadflags & LR_LOADTRANSPARENT) {
749 switch (bmi->bmiHeader.biBitCount) {
750 case 1: pix = pix >> 7; break;
751 case 4: pix = pix >> 4; break;
752 case 8: break;
753 default:
754 WARN(bitmap, "(%d): Unsupported depth\n", bmi->bmiHeader.biBitCount);
755 return;
757 if (pix >= colors) {
758 WARN(bitmap, "pixel has color index greater than biClrUsed!\n");
759 return;
761 if (loadflags & LR_LOADMAP3DCOLORS) c_W = c_F;
762 ptr = (RGBQUAD*)((char*)bmi->bmiColors+pix*incr);
763 ptr->rgbBlue = GetBValue(c_W);
764 ptr->rgbGreen = GetGValue(c_W);
765 ptr->rgbRed = GetRValue(c_W);
767 if (loadflags & LR_LOADMAP3DCOLORS)
768 for (i=0; i<colors; i++) {
769 ptr = (RGBQUAD*)((char*)bmi->bmiColors+i*incr);
770 c_C = RGB(ptr->rgbRed, ptr->rgbGreen, ptr->rgbBlue);
771 if (c_C == RGB(128, 128, 128)) {
772 ptr->rgbRed = GetRValue(c_S);
773 ptr->rgbGreen = GetGValue(c_S);
774 ptr->rgbBlue = GetBValue(c_S);
775 } else if (c_C == RGB(192, 192, 192)) {
776 ptr->rgbRed = GetRValue(c_F);
777 ptr->rgbGreen = GetGValue(c_F);
778 ptr->rgbBlue = GetBValue(c_F);
779 } else if (c_C == RGB(223, 223, 223)) {
780 ptr->rgbRed = GetRValue(c_L);
781 ptr->rgbGreen = GetGValue(c_L);
782 ptr->rgbBlue = GetBValue(c_L);