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:
56 void* colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
60 Search for "Bitmap Structures" in MSDN
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
81 /***********************************************************************
82 * DIB_GetDIBWidthBytes
84 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
86 int DIB_GetDIBWidthBytes( int width, int depth )
92 case 1: words = (width + 31) / 32; break;
93 case 4: words = (width + 7) / 8; break;
94 case 8: words = (width + 3) / 4; break;
96 case 16: words = (width + 1) / 2; break;
97 case 24: words = (width * 3 + 3)/4; break;
100 WARN("(%d): Unsupported depth\n", depth );
108 /***********************************************************************
109 * DIB_GetDIBImageBytes
111 * Return the number of bytes used to hold the image in a DIB bitmap.
113 int DIB_GetDIBImageBytes( int width, int height, int depth )
115 return DIB_GetDIBWidthBytes( width, depth ) * abs( height );
119 /***********************************************************************
122 * Return the size of the bitmap info structure including color table.
124 int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
126 unsigned int colors, size, masks = 0;
128 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
130 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
131 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
132 return sizeof(BITMAPCOREHEADER) + colors *
133 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
135 else /* assume BITMAPINFOHEADER */
137 colors = info->bmiHeader.biClrUsed;
138 if (colors > 256) colors = 256;
139 if (!colors && (info->bmiHeader.biBitCount <= 8))
140 colors = 1 << info->bmiHeader.biBitCount;
141 if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
142 size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
143 return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
148 /***********************************************************************
151 * Get the info from a bitmap header.
152 * Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error.
154 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;
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;
178 ERR("(%d): unknown/wrong size for header\n", header->biSize );
182 /* nulldrv fallback implementation using SetDIBits/StretchBlt */
183 INT nulldrv_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT heightDst,
184 INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits,
185 const BITMAPINFO *info, UINT coloruse, DWORD rop )
187 DC *dc = get_nulldrv_dc( dev );
195 /* make sure we have a real implementation for StretchBlt and SetDIBits */
196 if (GET_DC_PHYSDEV( dc, pStretchBlt ) == dev || GET_DC_PHYSDEV( dc, pSetDIBits ) == dev)
199 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size ) == -1)
202 if (width < 0) return 0;
204 if (xSrc == 0 && ySrc == 0 && widthDst == widthSrc && heightDst == heightSrc &&
205 info->bmiHeader.biCompression == BI_RGB)
207 /* Windows appears to have a fast case optimization
208 * that uses the wrong origin for top-down DIBs */
209 if (height < 0 && heightSrc < abs(height)) ySrc = abs(height) - heightSrc;
211 if (xDst == 0 && yDst == 0 && info->bmiHeader.biCompression == BI_RGB && rop == SRCCOPY)
214 hBitmap = GetCurrentObject( dev->hdc, OBJ_BITMAP );
215 if (GetObjectW( hBitmap, sizeof(bm), &bm ) &&
216 bm.bmWidth == widthSrc && bm.bmHeight == heightSrc &&
217 bm.bmBitsPixel == bpp && bm.bmPlanes == planes)
220 return SetDIBits( dev->hdc, hBitmap, 0, height, bits, info, coloruse );
225 hdcMem = CreateCompatibleDC( dev->hdc );
226 hBitmap = CreateCompatibleBitmap( dev->hdc, width, height );
227 SelectObject( hdcMem, hBitmap );
228 if (coloruse == DIB_PAL_COLORS)
229 SelectPalette( hdcMem, GetCurrentObject( dev->hdc, OBJ_PAL ), FALSE );
231 if (info->bmiHeader.biCompression == BI_RLE4 || info->bmiHeader.biCompression == BI_RLE8)
233 /* when RLE compression is used, there may be some gaps (ie the DIB doesn't
234 * contain all the rectangle described in bmiHeader, but only part of it.
235 * This mean that those undescribed pixels must be left untouched.
236 * So, we first copy on a memory bitmap the current content of the
237 * destination rectangle, blit the DIB bits on top of it - hence leaving
238 * the gaps untouched -, and blitting the rectangle back.
239 * This insure that gaps are untouched on the destination rectangle
241 StretchBlt( hdcMem, xSrc, abs(height) - heightSrc - ySrc, widthSrc, heightSrc,
242 dev->hdc, xDst, yDst, widthDst, heightDst, rop );
244 ret = SetDIBits( hdcMem, hBitmap, 0, height, bits, info, coloruse );
245 if (ret) StretchBlt( dev->hdc, xDst, yDst, widthDst, heightDst,
246 hdcMem, xSrc, abs(height) - heightSrc - ySrc, widthSrc, heightSrc, rop );
248 DeleteObject( hBitmap );
252 /***********************************************************************
253 * StretchDIBits (GDI32.@)
255 INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst, INT heightDst,
256 INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits,
257 const BITMAPINFO *info, UINT coloruse, DWORD rop )
262 if (!bits || !info) return 0;
264 if ((dc = get_dc_ptr( hdc )))
266 PHYSDEV physdev = GET_DC_PHYSDEV( dc, pStretchDIBits );
268 ret = physdev->funcs->pStretchDIBits( physdev, xDst, yDst, widthDst, heightDst,
269 xSrc, ySrc, widthSrc, heightSrc, bits, info, coloruse, rop );
270 release_dc_ptr( dc );
276 /******************************************************************************
277 * SetDIBits [GDI32.@]
279 * Sets pixels in a bitmap using colors from DIB.
282 * hdc [I] Handle to device context
283 * hbitmap [I] Handle to bitmap
284 * startscan [I] Starting scan line
285 * lines [I] Number of scan lines
286 * bits [I] Array of bitmap bits
287 * info [I] Address of structure with data
288 * coloruse [I] Type of color indexes to use
291 * Success: Number of scan lines copied
294 INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
295 UINT lines, LPCVOID bits, const BITMAPINFO *info,
298 DC *dc = get_dc_ptr( hdc );
299 BOOL delete_hdc = FALSE;
304 if (coloruse == DIB_RGB_COLORS && !dc)
306 hdc = CreateCompatibleDC(0);
307 dc = get_dc_ptr( hdc );
315 if (!(bitmap = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
317 release_dc_ptr( dc );
318 if (delete_hdc) DeleteDC(hdc);
322 physdev = GET_DC_PHYSDEV( dc, pSetDIBits );
323 if (BITMAP_SetOwnerDC( hbitmap, physdev ))
324 result = physdev->funcs->pSetDIBits( physdev, hbitmap, startscan, lines, bits, info, coloruse );
326 GDI_ReleaseObj( hbitmap );
327 release_dc_ptr( dc );
328 if (delete_hdc) DeleteDC(hdc);
333 /***********************************************************************
334 * SetDIBitsToDevice (GDI32.@)
336 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
337 DWORD cy, INT xSrc, INT ySrc, UINT startscan,
338 UINT lines, LPCVOID bits, const BITMAPINFO *info,
346 if ((dc = get_dc_ptr( hdc )))
348 PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDIBitsToDevice );
350 ret = physdev->funcs->pSetDIBitsToDevice( physdev, xDest, yDest, cx, cy, xSrc,
351 ySrc, startscan, lines, bits, info, coloruse );
352 release_dc_ptr( dc );
357 /***********************************************************************
358 * SetDIBColorTable (GDI32.@)
360 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUAD *colors )
366 if (!(dc = get_dc_ptr( hdc ))) return 0;
368 if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
370 PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDIBColorTable );
372 /* Check if currently selected bitmap is a DIB */
373 if (bitmap->color_table)
375 if (startpos < bitmap->nb_colors)
377 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
378 memcpy(bitmap->color_table + startpos, colors, entries * sizeof(RGBQUAD));
382 GDI_ReleaseObj( dc->hBitmap );
383 physdev->funcs->pSetDIBColorTable( physdev, startpos, entries, colors );
385 release_dc_ptr( dc );
390 /***********************************************************************
391 * GetDIBColorTable (GDI32.@)
393 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
399 if (!(dc = get_dc_ptr( hdc ))) return 0;
401 if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
403 /* Check if currently selected bitmap is a DIB */
404 if (bitmap->color_table)
406 if (startpos < bitmap->nb_colors)
408 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
409 memcpy(colors, bitmap->color_table + startpos, entries * sizeof(RGBQUAD));
413 GDI_ReleaseObj( dc->hBitmap );
415 release_dc_ptr( dc );
419 static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
420 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
421 { 0x00, 0x00, 0x00, 0x00 },
422 { 0x00, 0x00, 0x80, 0x00 },
423 { 0x00, 0x80, 0x00, 0x00 },
424 { 0x00, 0x80, 0x80, 0x00 },
425 { 0x80, 0x00, 0x00, 0x00 },
426 { 0x80, 0x00, 0x80, 0x00 },
427 { 0x80, 0x80, 0x00, 0x00 },
428 { 0xc0, 0xc0, 0xc0, 0x00 },
429 { 0xc0, 0xdc, 0xc0, 0x00 },
430 { 0xf0, 0xca, 0xa6, 0x00 },
431 { 0xf0, 0xfb, 0xff, 0x00 },
432 { 0xa4, 0xa0, 0xa0, 0x00 },
433 { 0x80, 0x80, 0x80, 0x00 },
434 { 0x00, 0x00, 0xff, 0x00 },
435 { 0x00, 0xff, 0x00, 0x00 },
436 { 0x00, 0xff, 0xff, 0x00 },
437 { 0xff, 0x00, 0x00, 0x00 },
438 { 0xff, 0x00, 0xff, 0x00 },
439 { 0xff, 0xff, 0x00, 0x00 },
440 { 0xff, 0xff, 0xff, 0x00 }
443 static const DWORD bit_fields_888[3] = {0xff0000, 0x00ff00, 0x0000ff};
444 static const DWORD bit_fields_565[3] = {0xf800, 0x07e0, 0x001f};
445 static const DWORD bit_fields_555[3] = {0x7c00, 0x03e0, 0x001f};
447 static int fill_query_info( BITMAPINFO *info, BITMAPOBJ *bmp )
449 BITMAPINFOHEADER header;
451 header.biSize = info->bmiHeader.biSize; /* Ensure we don't overwrite the original size when we copy back */
452 header.biWidth = bmp->bitmap.bmWidth;
453 header.biHeight = bmp->bitmap.bmHeight;
458 header.biBitCount = bmp->dib->dsBm.bmBitsPixel;
459 switch (bmp->dib->dsBm.bmBitsPixel)
463 header.biCompression = BI_BITFIELDS;
466 header.biCompression = BI_RGB;
472 header.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB;
473 header.biBitCount = bmp->bitmap.bmBitsPixel;
476 header.biSizeImage = DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
477 bmp->bitmap.bmHeight,
478 bmp->bitmap.bmBitsPixel );
479 header.biXPelsPerMeter = 0;
480 header.biYPelsPerMeter = 0;
481 header.biClrUsed = 0;
482 header.biClrImportant = 0;
484 if ( info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER) )
486 BITMAPCOREHEADER *coreheader = (BITMAPCOREHEADER *)info;
488 coreheader->bcWidth = header.biWidth;
489 coreheader->bcHeight = header.biHeight;
490 coreheader->bcPlanes = header.biPlanes;
491 coreheader->bcBitCount = header.biBitCount;
494 info->bmiHeader = header;
496 return abs(bmp->bitmap.bmHeight);
499 /************************************************************************
502 * Copy BITMAPINFO color information where dst may be a BITMAPCOREINFO.
504 static void copy_color_info(BITMAPINFO *dst, const BITMAPINFO *src, UINT coloruse)
506 unsigned int colors = src->bmiHeader.biBitCount > 8 ? 0 : 1 << src->bmiHeader.biBitCount;
507 RGBQUAD *src_colors = (RGBQUAD *)((char *)src + src->bmiHeader.biSize);
509 assert( src->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) );
511 if (src->bmiHeader.biClrUsed) colors = src->bmiHeader.biClrUsed;
513 if (dst->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
515 BITMAPCOREINFO *core = (BITMAPCOREINFO *)dst;
516 if (coloruse == DIB_PAL_COLORS)
517 memcpy( core->bmciColors, src_colors, colors * sizeof(WORD) );
521 for (i = 0; i < colors; i++)
523 core->bmciColors[i].rgbtRed = src_colors[i].rgbRed;
524 core->bmciColors[i].rgbtGreen = src_colors[i].rgbGreen;
525 core->bmciColors[i].rgbtBlue = src_colors[i].rgbBlue;
531 dst->bmiHeader.biClrUsed = src->bmiHeader.biClrUsed;
532 dst->bmiHeader.biSizeImage = src->bmiHeader.biSizeImage;
534 if (src->bmiHeader.biCompression == BI_BITFIELDS)
535 /* bitfields are always at bmiColors even in larger structures */
536 memcpy( dst->bmiColors, src->bmiColors, 3 * sizeof(DWORD) );
539 void *colorptr = (char *)dst + dst->bmiHeader.biSize;
542 if (coloruse == DIB_PAL_COLORS)
543 size = colors * sizeof(WORD);
545 size = colors * sizeof(RGBQUAD);
546 memcpy( colorptr, src_colors, size );
551 /******************************************************************************
552 * GetDIBits [GDI32.@]
554 * Retrieves bits of bitmap and copies to buffer.
557 * Success: Number of scan lines copied from bitmap
560 INT WINAPI GetDIBits(
561 HDC hdc, /* [in] Handle to device context */
562 HBITMAP hbitmap, /* [in] Handle to bitmap */
563 UINT startscan, /* [in] First scan line to set in dest bitmap */
564 UINT lines, /* [in] Number of scan lines to copy */
565 LPVOID bits, /* [out] Address of array for bitmap bits */
566 BITMAPINFO * info, /* [out] Address of structure with bitmap data */
567 UINT coloruse) /* [in] RGB or palette index */
577 char dst_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
578 BITMAPINFO *dst_info = (BITMAPINFO *)dst_bmibuf;
582 bitmap_type = DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size);
583 if (bitmap_type == -1)
585 ERR("Invalid bitmap format\n");
588 if (!(dc = get_dc_ptr( hdc )))
590 SetLastError( ERROR_INVALID_PARAMETER );
594 if (!(bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
596 release_dc_ptr( dc );
601 if (bpp == 0) /* query bitmap info only */
603 lines = fill_query_info( info, bmp );
607 /* Since info may be a BITMAPCOREINFO or any of the larger BITMAPINFO structures, we'll use our
608 own copy and transfer the colour info back at the end */
610 dst_info->bmiHeader.biSize = sizeof(dst_info->bmiHeader);
611 dst_info->bmiHeader.biWidth = width;
612 dst_info->bmiHeader.biHeight = height;
613 dst_info->bmiHeader.biPlanes = planes;
614 dst_info->bmiHeader.biBitCount = bpp;
615 dst_info->bmiHeader.biCompression = compr;
616 dst_info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp );
617 dst_info->bmiHeader.biXPelsPerMeter = 0;
618 dst_info->bmiHeader.biYPelsPerMeter = 0;
619 dst_info->bmiHeader.biClrUsed = 0;
620 dst_info->bmiHeader.biClrImportant = 0;
628 unsigned int colors = 1 << bpp;
630 if (coloruse == DIB_PAL_COLORS)
632 WORD *index = (WORD*)dst_info->bmiColors;
633 for (i = 0; i < colors; i++, index++)
637 /* If the bitmap object is a dib section at the
638 same color depth then get the color map from it */
639 else if (bmp->dib && bpp == bmp->dib->dsBm.bmBitsPixel)
641 colors = min( colors, bmp->nb_colors );
642 if (colors != 1 << bpp) dst_info->bmiHeader.biClrUsed = colors;
643 memcpy( dst_info->bmiColors, bmp->color_table, colors * sizeof(RGBQUAD) );
646 /* For color DDBs in native depth (mono DDBs always have a black/white palette):
647 Generate the color map from the selected palette */
649 else if (bpp > 1 && bpp == bmp->bitmap.bmBitsPixel)
651 PALETTEENTRY palEntry[256];
653 memset( palEntry, 0, sizeof(palEntry) );
654 if (!GetPaletteEntries( dc->hPalette, 0, colors, palEntry ))
660 for (i = 0; i < colors; i++)
662 dst_info->bmiColors[i].rgbRed = palEntry[i].peRed;
663 dst_info->bmiColors[i].rgbGreen = palEntry[i].peGreen;
664 dst_info->bmiColors[i].rgbBlue = palEntry[i].peBlue;
665 dst_info->bmiColors[i].rgbReserved = 0;
673 dst_info->bmiColors[0].rgbRed = dst_info->bmiColors[0].rgbGreen = dst_info->bmiColors[0].rgbBlue = 0;
674 dst_info->bmiColors[0].rgbReserved = 0;
675 dst_info->bmiColors[1].rgbRed = dst_info->bmiColors[1].rgbGreen = dst_info->bmiColors[1].rgbBlue = 0xff;
676 dst_info->bmiColors[1].rgbReserved = 0;
680 /* The EGA palette is the first and last 8 colours of the default palette
681 with the innermost pair swapped */
682 memcpy(dst_info->bmiColors, DefLogPaletteQuads, 7 * sizeof(RGBQUAD));
683 memcpy(dst_info->bmiColors + 7, DefLogPaletteQuads + 12, 1 * sizeof(RGBQUAD));
684 memcpy(dst_info->bmiColors + 8, DefLogPaletteQuads + 7, 1 * sizeof(RGBQUAD));
685 memcpy(dst_info->bmiColors + 9, DefLogPaletteQuads + 13, 7 * sizeof(RGBQUAD));
689 memcpy(dst_info->bmiColors, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
690 memcpy(dst_info->bmiColors + 246, DefLogPaletteQuads + 10, 10 * sizeof(RGBQUAD));
691 for (i = 10; i < 246; i++)
693 dst_info->bmiColors[i].rgbRed = (i & 0x07) << 5;
694 dst_info->bmiColors[i].rgbGreen = (i & 0x38) << 2;
695 dst_info->bmiColors[i].rgbBlue = i & 0xc0;
696 dst_info->bmiColors[i].rgbReserved = 0;
704 if (dst_info->bmiHeader.biCompression == BI_BITFIELDS)
705 memcpy( dst_info->bmiColors, bit_fields_555, sizeof(bit_fields_555) );
709 if (dst_info->bmiHeader.biCompression == BI_BITFIELDS)
713 if (bmp->dib->dsBmih.biCompression == BI_BITFIELDS && bmp->dib->dsBmih.biBitCount == bpp)
714 memcpy( dst_info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
716 memcpy( dst_info->bmiColors, bit_fields_555, sizeof(bit_fields_555) );
719 memcpy( dst_info->bmiColors, bit_fields_565, sizeof(bit_fields_565) );
725 if (dst_info->bmiHeader.biCompression == BI_BITFIELDS)
727 if (bmp->dib && bmp->dib->dsBmih.biCompression == BI_BITFIELDS && bmp->dib->dsBmih.biBitCount == bpp)
728 memcpy( dst_info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
730 memcpy( dst_info->bmiColors, bit_fields_888, sizeof(bit_fields_888) );
737 /* If the bitmap object already have a dib section that contains image data, get the bits from it */
738 if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
740 /*FIXME: Only RGB dibs supported for now */
741 unsigned int srcwidth = bmp->dib->dsBm.bmWidth;
742 int srcwidthb = bmp->dib->dsBm.bmWidthBytes;
743 unsigned int dstwidth = width;
744 int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
745 LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
746 unsigned int x, y, width, widthb;
749 * If copying from a top-down source bitmap, move the source
750 * pointer to the end of the source bitmap and negate the width
751 * so that we copy the bits upside-down.
753 if (bmp->dib->dsBmih.biHeight < 0)
755 sbits += (srcwidthb * (int)(abs(bmp->dib->dsBmih.biHeight) - 2 * startscan - 1));
756 srcwidthb = -srcwidthb;
758 /*Same for the destination.*/
761 dbits = (LPBYTE)bits + (dstwidthb * (lines - 1));
762 dstwidthb = -dstwidthb;
767 case 16: /* 16 bpp dstDIB */
769 LPWORD dstbits = (LPWORD)dbits;
770 WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
772 /* FIXME: BI_BITFIELDS not supported yet */
774 switch(bmp->dib->dsBm.bmBitsPixel) {
776 case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
778 widthb = min(abs(srcwidthb), abs(dstwidthb));
779 /* FIXME: BI_BITFIELDS not supported yet */
780 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
781 memcpy(dbits, sbits, widthb);
785 case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
787 LPBYTE srcbits = sbits;
789 width = min(srcwidth, dstwidth);
790 for( y = 0; y < lines; y++) {
791 for( x = 0; x < width; x++, srcbits += 3)
792 *dstbits++ = ((srcbits[0] >> 3) & bmask) |
793 (((WORD)srcbits[1] << 2) & gmask) |
794 (((WORD)srcbits[2] << 7) & rmask);
796 dstbits = (LPWORD)(dbits+=dstwidthb);
797 srcbits = (sbits += srcwidthb);
802 case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
804 LPDWORD srcbits = (LPDWORD)sbits;
807 width = min(srcwidth, dstwidth);
808 for( y = 0; y < lines; y++) {
809 for( x = 0; x < width; x++ ) {
811 *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
812 ((val >> 9) & rmask));
814 dstbits = (LPWORD)(dbits+=dstwidthb);
815 srcbits = (LPDWORD)(sbits+=srcwidthb);
820 default: /* ? bit bmp -> 16 bit DIB */
821 FIXME("15/16 bit DIB %d bit bitmap\n",
822 bmp->bitmap.bmBitsPixel);
828 case 24: /* 24 bpp dstDIB */
830 LPBYTE dstbits = dbits;
832 switch(bmp->dib->dsBm.bmBitsPixel) {
834 case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
836 LPWORD srcbits = (LPWORD)sbits;
839 width = min(srcwidth, dstwidth);
840 /* FIXME: BI_BITFIELDS not supported yet */
841 for( y = 0; y < lines; y++) {
842 for( x = 0; x < width; x++ ) {
844 *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
845 *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
846 *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
848 dstbits = dbits+=dstwidthb;
849 srcbits = (LPWORD)(sbits+=srcwidthb);
854 case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
856 widthb = min(abs(srcwidthb), abs(dstwidthb));
857 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
858 memcpy(dbits, sbits, widthb);
862 case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
864 LPBYTE srcbits = sbits;
866 width = min(srcwidth, dstwidth);
867 for( y = 0; y < lines; y++) {
868 for( x = 0; x < width; x++, srcbits++ ) {
869 *dstbits++ = *srcbits++;
870 *dstbits++ = *srcbits++;
871 *dstbits++ = *srcbits++;
873 dstbits = dbits+=dstwidthb;
874 srcbits = sbits+=srcwidthb;
879 default: /* ? bit bmp -> 24 bit DIB */
880 FIXME("24 bit DIB %d bit bitmap\n",
881 bmp->bitmap.bmBitsPixel);
887 case 32: /* 32 bpp dstDIB */
889 LPDWORD dstbits = (LPDWORD)dbits;
891 /* FIXME: BI_BITFIELDS not supported yet */
893 switch(bmp->dib->dsBm.bmBitsPixel) {
894 case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
896 LPWORD srcbits = (LPWORD)sbits;
899 width = min(srcwidth, dstwidth);
900 /* FIXME: BI_BITFIELDS not supported yet */
901 for( y = 0; y < lines; y++) {
902 for( x = 0; x < width; x++ ) {
903 val = (DWORD)*srcbits++;
904 *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
905 ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
906 ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
908 dstbits=(LPDWORD)(dbits+=dstwidthb);
909 srcbits=(LPWORD)(sbits+=srcwidthb);
914 case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
916 LPBYTE srcbits = sbits;
918 width = min(srcwidth, dstwidth);
919 for( y = 0; y < lines; y++) {
920 for( x = 0; x < width; x++, srcbits+=3 )
921 *dstbits++ = srcbits[0] |
924 dstbits=(LPDWORD)(dbits+=dstwidthb);
925 srcbits=(sbits+=srcwidthb);
930 case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
932 widthb = min(abs(srcwidthb), abs(dstwidthb));
933 /* FIXME: BI_BITFIELDS not supported yet */
934 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
935 memcpy(dbits, sbits, widthb);
940 default: /* ? bit bmp -> 32 bit DIB */
941 FIXME("32 bit DIB %d bit bitmap\n",
942 bmp->bitmap.bmBitsPixel);
948 default: /* ? bit DIB */
949 FIXME("Unsupported DIB depth %d\n", dst_info->bmiHeader.biBitCount);
953 /* Otherwise, get bits from the XImage */
956 PHYSDEV physdev = GET_DC_PHYSDEV( dc, pGetDIBits );
957 if (!BITMAP_SetOwnerDC( hbitmap, physdev )) lines = 0;
958 else lines = physdev->funcs->pGetDIBits( physdev, hbitmap, startscan,
959 lines, bits, dst_info, coloruse );
962 else lines = abs(height);
964 copy_color_info( info, dst_info, coloruse );
967 release_dc_ptr( dc );
968 GDI_ReleaseObj( hbitmap );
973 /***********************************************************************
974 * CreateDIBitmap (GDI32.@)
976 * Creates a DDB (device dependent bitmap) from a DIB.
977 * The DDB will have the same color depth as the reference DC.
979 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
980 DWORD init, LPCVOID bits, const BITMAPINFO *data,
989 if (!header) return 0;
991 if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &size ) == -1) return 0;
995 TRACE("Bitmap has a negative width\n");
999 /* Top-down DIBs have a negative height */
1000 if (height < 0) height = -height;
1002 TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1003 hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
1006 handle = CreateBitmap( width, height, 1, 1, NULL );
1008 handle = CreateCompatibleBitmap( hdc, width, height );
1012 if (init & CBM_INIT)
1014 if (SetDIBits( hdc, handle, 0, height, bits, data, coloruse ) == 0)
1016 DeleteObject( handle );
1025 /* Copy/synthesize RGB palette from BITMAPINFO. Ripped from dlls/winex11.drv/dib.c */
1026 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1028 RGBQUAD *colorTable;
1029 unsigned int colors, i;
1030 BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
1034 colors = 1 << ((const BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
1038 colors = info->bmiHeader.biClrUsed;
1039 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
1043 ERR("called with >256 colors!\n");
1047 if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1049 if(coloruse == DIB_RGB_COLORS)
1053 /* Convert RGBTRIPLEs to RGBQUADs */
1054 for (i=0; i < colors; i++)
1056 colorTable[i].rgbRed = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
1057 colorTable[i].rgbGreen = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
1058 colorTable[i].rgbBlue = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
1059 colorTable[i].rgbReserved = 0;
1064 memcpy(colorTable, (const BYTE*) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
1069 PALETTEENTRY entries[256];
1070 const WORD *index = (const WORD*) ((const BYTE*) info + (WORD) info->bmiHeader.biSize);
1071 UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1073 for (i = 0; i < colors; i++, index++)
1075 PALETTEENTRY *entry = &entries[*index % count];
1076 colorTable[i].rgbRed = entry->peRed;
1077 colorTable[i].rgbGreen = entry->peGreen;
1078 colorTable[i].rgbBlue = entry->peBlue;
1079 colorTable[i].rgbReserved = 0;
1082 bmp->color_table = colorTable;
1083 bmp->nb_colors = colors;
1086 /***********************************************************************
1087 * CreateDIBSection (GDI32.@)
1089 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1090 VOID **bits, HANDLE section, DWORD offset)
1094 BOOL bDesktopDC = FALSE;
1100 DWORD compression, sizeImage;
1101 void *mapBits = NULL;
1104 if(bits) *bits = NULL;
1108 if (((bitmap_type = DIB_GetBitmapInfo( &bmi->bmiHeader, &width, &height,
1109 &planes, &bpp, &compression, &sizeImage )) == -1))
1116 if (compression == BI_BITFIELDS) break;
1122 if (compression == BI_RGB) break;
1125 WARN( "invalid %u bpp compression %u\n", bpp, compression );
1129 if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1131 TRACE("format (%d,%d), planes %d, bpp %d, %s, size %d %s\n",
1132 width, height, planes, bpp, compression == BI_BITFIELDS? "BI_BITFIELDS" : "BI_RGB",
1133 sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1135 dib->dsBm.bmType = 0;
1136 dib->dsBm.bmWidth = width;
1137 dib->dsBm.bmHeight = height >= 0 ? height : -height;
1138 dib->dsBm.bmWidthBytes = DIB_GetDIBWidthBytes(width, bpp);
1139 dib->dsBm.bmPlanes = planes;
1140 dib->dsBm.bmBitsPixel = bpp;
1141 dib->dsBm.bmBits = NULL;
1143 if (!bitmap_type) /* core header */
1145 /* convert the BITMAPCOREHEADER to a BITMAPINFOHEADER */
1146 dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1147 dib->dsBmih.biWidth = width;
1148 dib->dsBmih.biHeight = height;
1149 dib->dsBmih.biPlanes = planes;
1150 dib->dsBmih.biBitCount = bpp;
1151 dib->dsBmih.biCompression = compression;
1152 dib->dsBmih.biXPelsPerMeter = 0;
1153 dib->dsBmih.biYPelsPerMeter = 0;
1154 dib->dsBmih.biClrUsed = 0;
1155 dib->dsBmih.biClrImportant = 0;
1159 /* truncate extended bitmap headers (BITMAPV4HEADER etc.) */
1160 dib->dsBmih = bmi->bmiHeader;
1161 dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1164 /* set number of entries in bmi.bmiColors table */
1166 dib->dsBmih.biClrUsed = 1 << bpp;
1168 dib->dsBmih.biSizeImage = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
1170 /* set dsBitfields values */
1171 dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1173 if((bpp == 15 || bpp == 16) && compression == BI_RGB)
1175 /* In this case Windows changes biCompression to BI_BITFIELDS,
1176 however for now we won't do this, as there are a lot
1177 of places where BI_BITFIELDS is currently unsupported. */
1179 /* dib->dsBmih.biCompression = compression = BI_BITFIELDS;*/
1180 dib->dsBitfields[0] = 0x7c00;
1181 dib->dsBitfields[1] = 0x03e0;
1182 dib->dsBitfields[2] = 0x001f;
1184 else if(compression == BI_BITFIELDS)
1186 dib->dsBitfields[0] = *(const DWORD *)bmi->bmiColors;
1187 dib->dsBitfields[1] = *((const DWORD *)bmi->bmiColors + 1);
1188 dib->dsBitfields[2] = *((const DWORD *)bmi->bmiColors + 2);
1191 /* get storage location for DIB bits */
1195 SYSTEM_INFO SystemInfo;
1199 GetSystemInfo( &SystemInfo );
1200 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1201 mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1202 mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1203 if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1208 dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1209 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1211 dib->dshSection = section;
1212 dib->dsOffset = offset;
1214 if (!dib->dsBm.bmBits)
1216 HeapFree( GetProcessHeap(), 0, dib );
1220 /* If the reference hdc is null, take the desktop dc */
1223 hdc = CreateCompatibleDC(0);
1227 if (!(dc = get_dc_ptr( hdc ))) goto error;
1229 /* create Device Dependent Bitmap and add DIB pointer */
1230 ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1231 (bpp == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1233 if (ret && ((bmp = GDI_GetObjPtr(ret, OBJ_BITMAP))))
1235 PHYSDEV physdev = GET_DC_PHYSDEV( dc, pCreateDIBSection );
1237 bmp->funcs = physdev->funcs;
1238 /* create local copy of DIB palette */
1239 if (bpp <= 8) DIB_CopyColorTable( dc, bmp, usage, bmi );
1240 GDI_ReleaseObj( ret );
1242 if (!physdev->funcs->pCreateDIBSection( physdev, ret, bmi, usage ))
1244 DeleteObject( ret );
1249 release_dc_ptr( dc );
1250 if (bDesktopDC) DeleteDC( hdc );
1251 if (ret && bits) *bits = dib->dsBm.bmBits;
1255 if (bDesktopDC) DeleteDC( hdc );
1256 if (section) UnmapViewOfFile( mapBits );
1257 else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1258 HeapFree( GetProcessHeap(), 0, dib );