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 CDECL 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};
448 /************************************************************************
451 * Copy BITMAPINFO color information where dst may be a BITMAPCOREINFO.
453 static void copy_color_info(BITMAPINFO *dst, const BITMAPINFO *src, UINT coloruse)
455 unsigned int colors = src->bmiHeader.biBitCount > 8 ? 0 : 1 << src->bmiHeader.biBitCount;
456 RGBQUAD *src_colors = (RGBQUAD *)((char *)src + src->bmiHeader.biSize);
458 assert( src->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) );
460 if (src->bmiHeader.biClrUsed) colors = src->bmiHeader.biClrUsed;
462 if (dst->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
464 BITMAPCOREINFO *core = (BITMAPCOREINFO *)dst;
465 if (coloruse == DIB_PAL_COLORS)
466 memcpy( core->bmciColors, src_colors, colors * sizeof(WORD) );
470 for (i = 0; i < colors; i++)
472 core->bmciColors[i].rgbtRed = src_colors[i].rgbRed;
473 core->bmciColors[i].rgbtGreen = src_colors[i].rgbGreen;
474 core->bmciColors[i].rgbtBlue = src_colors[i].rgbBlue;
480 dst->bmiHeader.biClrUsed = src->bmiHeader.biClrUsed;
481 dst->bmiHeader.biSizeImage = src->bmiHeader.biSizeImage;
483 if (src->bmiHeader.biCompression == BI_BITFIELDS)
484 /* bitfields are always at bmiColors even in larger structures */
485 memcpy( dst->bmiColors, src->bmiColors, 3 * sizeof(DWORD) );
488 void *colorptr = (char *)dst + dst->bmiHeader.biSize;
491 if (coloruse == DIB_PAL_COLORS)
492 size = colors * sizeof(WORD);
494 size = colors * sizeof(RGBQUAD);
495 memcpy( colorptr, src_colors, size );
500 /******************************************************************************
501 * GetDIBits [GDI32.@]
503 * Retrieves bits of bitmap and copies to buffer.
506 * Success: Number of scan lines copied from bitmap
509 INT WINAPI GetDIBits(
510 HDC hdc, /* [in] Handle to device context */
511 HBITMAP hbitmap, /* [in] Handle to bitmap */
512 UINT startscan, /* [in] First scan line to set in dest bitmap */
513 UINT lines, /* [in] Number of scan lines to copy */
514 LPVOID bits, /* [out] Address of array for bitmap bits */
515 BITMAPINFO * info, /* [out] Address of structure with bitmap data */
516 UINT coloruse) /* [in] RGB or palette index */
527 char dst_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
528 BITMAPINFO *dst_info = (BITMAPINFO *)dst_bmibuf;
532 bitmap_type = DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size);
533 if (bitmap_type == -1)
535 ERR("Invalid bitmap format\n");
538 core_header = (bitmap_type == 0);
539 if (!(dc = get_dc_ptr( hdc )))
541 SetLastError( ERROR_INVALID_PARAMETER );
545 if (!(bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
547 release_dc_ptr( dc );
552 if (bpp == 0) /* query bitmap info only */
556 BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
557 coreheader->bcWidth = bmp->bitmap.bmWidth;
558 coreheader->bcHeight = bmp->bitmap.bmHeight;
559 coreheader->bcPlanes = 1;
560 coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
564 info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
565 info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
566 info->bmiHeader.biPlanes = 1;
567 info->bmiHeader.biSizeImage =
568 DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
569 bmp->bitmap.bmHeight,
570 bmp->bitmap.bmBitsPixel );
573 info->bmiHeader.biBitCount = bmp->dib->dsBm.bmBitsPixel;
574 switch (bmp->dib->dsBm.bmBitsPixel)
578 info->bmiHeader.biCompression = BI_BITFIELDS;
581 info->bmiHeader.biCompression = BI_RGB;
587 info->bmiHeader.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB;
588 info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
590 info->bmiHeader.biXPelsPerMeter = 0;
591 info->bmiHeader.biYPelsPerMeter = 0;
592 info->bmiHeader.biClrUsed = 0;
593 info->bmiHeader.biClrImportant = 0;
595 /* Windows 2000 doesn't touch the additional struct members if
596 it's a BITMAPV4HEADER or a BITMAPV5HEADER */
598 lines = abs(bmp->bitmap.bmHeight);
603 /* Since info may be a BITMAPCOREINFO or any of the larger BITMAPINFO structures, we'll use our
604 own copy and transfer the colour info back at the end */
606 dst_info->bmiHeader.biSize = sizeof(dst_info->bmiHeader);
607 dst_info->bmiHeader.biWidth = width;
608 dst_info->bmiHeader.biHeight = height;
609 dst_info->bmiHeader.biPlanes = planes;
610 dst_info->bmiHeader.biBitCount = bpp;
611 dst_info->bmiHeader.biCompression = compr;
612 dst_info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp );
613 dst_info->bmiHeader.biXPelsPerMeter = 0;
614 dst_info->bmiHeader.biYPelsPerMeter = 0;
615 dst_info->bmiHeader.biClrUsed = 0;
616 dst_info->bmiHeader.biClrImportant = 0;
624 unsigned int colors = 1 << bpp;
626 if (coloruse == DIB_PAL_COLORS)
628 WORD *index = (WORD*)dst_info->bmiColors;
629 for (i = 0; i < colors; i++, index++)
633 /* If the bitmap object is a dib section at the
634 same color depth then get the color map from it */
635 else if (bmp->dib && bpp == bmp->dib->dsBm.bmBitsPixel)
637 colors = min( colors, bmp->nb_colors );
638 if (colors != 1 << bpp) dst_info->bmiHeader.biClrUsed = colors;
639 memcpy( dst_info->bmiColors, bmp->color_table, colors * sizeof(RGBQUAD) );
642 /* For color DDBs in native depth (mono DDBs always have a black/white palette):
643 Generate the color map from the selected palette */
645 else if (bpp > 1 && bpp == bmp->bitmap.bmBitsPixel)
647 PALETTEENTRY palEntry[256];
649 memset( palEntry, 0, sizeof(palEntry) );
650 if (!GetPaletteEntries( dc->hPalette, 0, colors, palEntry ))
656 for (i = 0; i < colors; i++)
658 dst_info->bmiColors[i].rgbRed = palEntry[i].peRed;
659 dst_info->bmiColors[i].rgbGreen = palEntry[i].peGreen;
660 dst_info->bmiColors[i].rgbBlue = palEntry[i].peBlue;
661 dst_info->bmiColors[i].rgbReserved = 0;
669 dst_info->bmiColors[0].rgbRed = dst_info->bmiColors[0].rgbGreen = dst_info->bmiColors[0].rgbBlue = 0;
670 dst_info->bmiColors[0].rgbReserved = 0;
671 dst_info->bmiColors[1].rgbRed = dst_info->bmiColors[1].rgbGreen = dst_info->bmiColors[1].rgbBlue = 0xff;
672 dst_info->bmiColors[1].rgbReserved = 0;
676 /* The EGA palette is the first and last 8 colours of the default palette
677 with the innermost pair swapped */
678 memcpy(dst_info->bmiColors, DefLogPaletteQuads, 7 * sizeof(RGBQUAD));
679 memcpy(dst_info->bmiColors + 7, DefLogPaletteQuads + 12, 1 * sizeof(RGBQUAD));
680 memcpy(dst_info->bmiColors + 8, DefLogPaletteQuads + 7, 1 * sizeof(RGBQUAD));
681 memcpy(dst_info->bmiColors + 9, DefLogPaletteQuads + 13, 7 * sizeof(RGBQUAD));
685 memcpy(dst_info->bmiColors, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
686 memcpy(dst_info->bmiColors + 246, DefLogPaletteQuads + 10, 10 * sizeof(RGBQUAD));
687 for (i = 10; i < 246; i++)
689 dst_info->bmiColors[i].rgbRed = (i & 0x07) << 5;
690 dst_info->bmiColors[i].rgbGreen = (i & 0x38) << 2;
691 dst_info->bmiColors[i].rgbBlue = i & 0xc0;
692 dst_info->bmiColors[i].rgbReserved = 0;
700 if (dst_info->bmiHeader.biCompression == BI_BITFIELDS)
701 memcpy( dst_info->bmiColors, bit_fields_555, sizeof(bit_fields_555) );
705 if (dst_info->bmiHeader.biCompression == BI_BITFIELDS)
709 if (bmp->dib->dsBmih.biCompression == BI_BITFIELDS && bmp->dib->dsBmih.biBitCount == bpp)
710 memcpy( dst_info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
712 memcpy( dst_info->bmiColors, bit_fields_555, sizeof(bit_fields_555) );
715 memcpy( dst_info->bmiColors, bit_fields_565, sizeof(bit_fields_565) );
721 if (dst_info->bmiHeader.biCompression == BI_BITFIELDS)
723 if (bmp->dib && bmp->dib->dsBmih.biCompression == BI_BITFIELDS && bmp->dib->dsBmih.biBitCount == bpp)
724 memcpy( dst_info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
726 memcpy( dst_info->bmiColors, bit_fields_888, sizeof(bit_fields_888) );
733 /* If the bitmap object already have a dib section that contains image data, get the bits from it */
734 if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
736 /*FIXME: Only RGB dibs supported for now */
737 unsigned int srcwidth = bmp->dib->dsBm.bmWidth;
738 int srcwidthb = bmp->dib->dsBm.bmWidthBytes;
739 unsigned int dstwidth = width;
740 int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
741 LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
742 unsigned int x, y, width, widthb;
745 * If copying from a top-down source bitmap, move the source
746 * pointer to the end of the source bitmap and negate the width
747 * so that we copy the bits upside-down.
749 if (bmp->dib->dsBmih.biHeight < 0)
751 sbits += (srcwidthb * (int)(abs(bmp->dib->dsBmih.biHeight) - 2 * startscan - 1));
752 srcwidthb = -srcwidthb;
754 /*Same for the destination.*/
757 dbits = (LPBYTE)bits + (dstwidthb * (lines - 1));
758 dstwidthb = -dstwidthb;
763 case 16: /* 16 bpp dstDIB */
765 LPWORD dstbits = (LPWORD)dbits;
766 WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
768 /* FIXME: BI_BITFIELDS not supported yet */
770 switch(bmp->dib->dsBm.bmBitsPixel) {
772 case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
774 widthb = min(abs(srcwidthb), abs(dstwidthb));
775 /* FIXME: BI_BITFIELDS not supported yet */
776 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
777 memcpy(dbits, sbits, widthb);
781 case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
783 LPBYTE srcbits = sbits;
785 width = min(srcwidth, dstwidth);
786 for( y = 0; y < lines; y++) {
787 for( x = 0; x < width; x++, srcbits += 3)
788 *dstbits++ = ((srcbits[0] >> 3) & bmask) |
789 (((WORD)srcbits[1] << 2) & gmask) |
790 (((WORD)srcbits[2] << 7) & rmask);
792 dstbits = (LPWORD)(dbits+=dstwidthb);
793 srcbits = (sbits += srcwidthb);
798 case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
800 LPDWORD srcbits = (LPDWORD)sbits;
803 width = min(srcwidth, dstwidth);
804 for( y = 0; y < lines; y++) {
805 for( x = 0; x < width; x++ ) {
807 *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
808 ((val >> 9) & rmask));
810 dstbits = (LPWORD)(dbits+=dstwidthb);
811 srcbits = (LPDWORD)(sbits+=srcwidthb);
816 default: /* ? bit bmp -> 16 bit DIB */
817 FIXME("15/16 bit DIB %d bit bitmap\n",
818 bmp->bitmap.bmBitsPixel);
824 case 24: /* 24 bpp dstDIB */
826 LPBYTE dstbits = dbits;
828 switch(bmp->dib->dsBm.bmBitsPixel) {
830 case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
832 LPWORD srcbits = (LPWORD)sbits;
835 width = min(srcwidth, dstwidth);
836 /* FIXME: BI_BITFIELDS not supported yet */
837 for( y = 0; y < lines; y++) {
838 for( x = 0; x < width; x++ ) {
840 *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
841 *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
842 *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
844 dstbits = dbits+=dstwidthb;
845 srcbits = (LPWORD)(sbits+=srcwidthb);
850 case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
852 widthb = min(abs(srcwidthb), abs(dstwidthb));
853 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
854 memcpy(dbits, sbits, widthb);
858 case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
860 LPBYTE srcbits = sbits;
862 width = min(srcwidth, dstwidth);
863 for( y = 0; y < lines; y++) {
864 for( x = 0; x < width; x++, srcbits++ ) {
865 *dstbits++ = *srcbits++;
866 *dstbits++ = *srcbits++;
867 *dstbits++ = *srcbits++;
869 dstbits = dbits+=dstwidthb;
870 srcbits = sbits+=srcwidthb;
875 default: /* ? bit bmp -> 24 bit DIB */
876 FIXME("24 bit DIB %d bit bitmap\n",
877 bmp->bitmap.bmBitsPixel);
883 case 32: /* 32 bpp dstDIB */
885 LPDWORD dstbits = (LPDWORD)dbits;
887 /* FIXME: BI_BITFIELDS not supported yet */
889 switch(bmp->dib->dsBm.bmBitsPixel) {
890 case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
892 LPWORD srcbits = (LPWORD)sbits;
895 width = min(srcwidth, dstwidth);
896 /* FIXME: BI_BITFIELDS not supported yet */
897 for( y = 0; y < lines; y++) {
898 for( x = 0; x < width; x++ ) {
899 val = (DWORD)*srcbits++;
900 *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
901 ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
902 ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
904 dstbits=(LPDWORD)(dbits+=dstwidthb);
905 srcbits=(LPWORD)(sbits+=srcwidthb);
910 case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
912 LPBYTE srcbits = sbits;
914 width = min(srcwidth, dstwidth);
915 for( y = 0; y < lines; y++) {
916 for( x = 0; x < width; x++, srcbits+=3 )
917 *dstbits++ = srcbits[0] |
920 dstbits=(LPDWORD)(dbits+=dstwidthb);
921 srcbits=(sbits+=srcwidthb);
926 case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
928 widthb = min(abs(srcwidthb), abs(dstwidthb));
929 /* FIXME: BI_BITFIELDS not supported yet */
930 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
931 memcpy(dbits, sbits, widthb);
936 default: /* ? bit bmp -> 32 bit DIB */
937 FIXME("32 bit DIB %d bit bitmap\n",
938 bmp->bitmap.bmBitsPixel);
944 default: /* ? bit DIB */
945 FIXME("Unsupported DIB depth %d\n", dst_info->bmiHeader.biBitCount);
949 /* Otherwise, get bits from the XImage */
952 PHYSDEV physdev = GET_DC_PHYSDEV( dc, pGetDIBits );
953 if (!BITMAP_SetOwnerDC( hbitmap, physdev )) lines = 0;
954 else lines = physdev->funcs->pGetDIBits( physdev, hbitmap, startscan,
955 lines, bits, dst_info, coloruse );
958 else lines = abs(height);
960 copy_color_info( info, dst_info, coloruse );
963 release_dc_ptr( dc );
964 GDI_ReleaseObj( hbitmap );
969 /***********************************************************************
970 * CreateDIBitmap (GDI32.@)
972 * Creates a DDB (device dependent bitmap) from a DIB.
973 * The DDB will have the same color depth as the reference DC.
975 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
976 DWORD init, LPCVOID bits, const BITMAPINFO *data,
985 if (!header) return 0;
987 if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &size ) == -1) return 0;
991 TRACE("Bitmap has a negative width\n");
995 /* Top-down DIBs have a negative height */
996 if (height < 0) height = -height;
998 TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
999 hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
1002 handle = CreateBitmap( width, height, 1, 1, NULL );
1004 handle = CreateCompatibleBitmap( hdc, width, height );
1008 if (init & CBM_INIT)
1010 if (SetDIBits( hdc, handle, 0, height, bits, data, coloruse ) == 0)
1012 DeleteObject( handle );
1021 /* Copy/synthesize RGB palette from BITMAPINFO. Ripped from dlls/winex11.drv/dib.c */
1022 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1024 RGBQUAD *colorTable;
1025 unsigned int colors, i;
1026 BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
1030 colors = 1 << ((const BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
1034 colors = info->bmiHeader.biClrUsed;
1035 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
1039 ERR("called with >256 colors!\n");
1043 if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1045 if(coloruse == DIB_RGB_COLORS)
1049 /* Convert RGBTRIPLEs to RGBQUADs */
1050 for (i=0; i < colors; i++)
1052 colorTable[i].rgbRed = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
1053 colorTable[i].rgbGreen = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
1054 colorTable[i].rgbBlue = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
1055 colorTable[i].rgbReserved = 0;
1060 memcpy(colorTable, (const BYTE*) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
1065 PALETTEENTRY entries[256];
1066 const WORD *index = (const WORD*) ((const BYTE*) info + (WORD) info->bmiHeader.biSize);
1067 UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1069 for (i = 0; i < colors; i++, index++)
1071 PALETTEENTRY *entry = &entries[*index % count];
1072 colorTable[i].rgbRed = entry->peRed;
1073 colorTable[i].rgbGreen = entry->peGreen;
1074 colorTable[i].rgbBlue = entry->peBlue;
1075 colorTable[i].rgbReserved = 0;
1078 bmp->color_table = colorTable;
1079 bmp->nb_colors = colors;
1082 /***********************************************************************
1083 * CreateDIBSection (GDI32.@)
1085 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1086 VOID **bits, HANDLE section, DWORD offset)
1090 BOOL bDesktopDC = FALSE;
1096 DWORD compression, sizeImage;
1097 void *mapBits = NULL;
1100 if(bits) *bits = NULL;
1104 if (((bitmap_type = DIB_GetBitmapInfo( &bmi->bmiHeader, &width, &height,
1105 &planes, &bpp, &compression, &sizeImage )) == -1))
1112 if (compression == BI_BITFIELDS) break;
1118 if (compression == BI_RGB) break;
1121 WARN( "invalid %u bpp compression %u\n", bpp, compression );
1125 if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1127 TRACE("format (%d,%d), planes %d, bpp %d, %s, size %d %s\n",
1128 width, height, planes, bpp, compression == BI_BITFIELDS? "BI_BITFIELDS" : "BI_RGB",
1129 sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1131 dib->dsBm.bmType = 0;
1132 dib->dsBm.bmWidth = width;
1133 dib->dsBm.bmHeight = height >= 0 ? height : -height;
1134 dib->dsBm.bmWidthBytes = DIB_GetDIBWidthBytes(width, bpp);
1135 dib->dsBm.bmPlanes = planes;
1136 dib->dsBm.bmBitsPixel = bpp;
1137 dib->dsBm.bmBits = NULL;
1139 if (!bitmap_type) /* core header */
1141 /* convert the BITMAPCOREHEADER to a BITMAPINFOHEADER */
1142 dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1143 dib->dsBmih.biWidth = width;
1144 dib->dsBmih.biHeight = height;
1145 dib->dsBmih.biPlanes = planes;
1146 dib->dsBmih.biBitCount = bpp;
1147 dib->dsBmih.biCompression = compression;
1148 dib->dsBmih.biXPelsPerMeter = 0;
1149 dib->dsBmih.biYPelsPerMeter = 0;
1150 dib->dsBmih.biClrUsed = 0;
1151 dib->dsBmih.biClrImportant = 0;
1155 /* truncate extended bitmap headers (BITMAPV4HEADER etc.) */
1156 dib->dsBmih = bmi->bmiHeader;
1157 dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1160 /* set number of entries in bmi.bmiColors table */
1162 dib->dsBmih.biClrUsed = 1 << bpp;
1164 dib->dsBmih.biSizeImage = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
1166 /* set dsBitfields values */
1167 dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1169 if((bpp == 15 || bpp == 16) && compression == BI_RGB)
1171 /* In this case Windows changes biCompression to BI_BITFIELDS,
1172 however for now we won't do this, as there are a lot
1173 of places where BI_BITFIELDS is currently unsupported. */
1175 /* dib->dsBmih.biCompression = compression = BI_BITFIELDS;*/
1176 dib->dsBitfields[0] = 0x7c00;
1177 dib->dsBitfields[1] = 0x03e0;
1178 dib->dsBitfields[2] = 0x001f;
1180 else if(compression == BI_BITFIELDS)
1182 dib->dsBitfields[0] = *(const DWORD *)bmi->bmiColors;
1183 dib->dsBitfields[1] = *((const DWORD *)bmi->bmiColors + 1);
1184 dib->dsBitfields[2] = *((const DWORD *)bmi->bmiColors + 2);
1187 /* get storage location for DIB bits */
1191 SYSTEM_INFO SystemInfo;
1195 GetSystemInfo( &SystemInfo );
1196 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1197 mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1198 mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1199 if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1204 dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1205 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1207 dib->dshSection = section;
1208 dib->dsOffset = offset;
1210 if (!dib->dsBm.bmBits)
1212 HeapFree( GetProcessHeap(), 0, dib );
1216 /* If the reference hdc is null, take the desktop dc */
1219 hdc = CreateCompatibleDC(0);
1223 if (!(dc = get_dc_ptr( hdc ))) goto error;
1225 /* create Device Dependent Bitmap and add DIB pointer */
1226 ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1227 (bpp == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1229 if (ret && ((bmp = GDI_GetObjPtr(ret, OBJ_BITMAP))))
1231 PHYSDEV physdev = GET_DC_PHYSDEV( dc, pCreateDIBSection );
1233 bmp->funcs = physdev->funcs;
1234 /* create local copy of DIB palette */
1235 if (bpp <= 8) DIB_CopyColorTable( dc, bmp, usage, bmi );
1236 GDI_ReleaseObj( ret );
1238 if (!physdev->funcs->pCreateDIBSection( physdev, ret, bmi, usage ))
1240 DeleteObject( ret );
1245 release_dc_ptr( dc );
1246 if (bDesktopDC) DeleteDC( hdc );
1247 if (ret && bits) *bits = dib->dsBm.bmBits;
1251 if (bDesktopDC) DeleteDC( hdc );
1252 if (section) UnmapViewOfFile( mapBits );
1253 else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1254 HeapFree( GetProcessHeap(), 0, dib );