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
69 #include "gdi_private.h"
70 #include "wine/debug.h"
72 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
76 Some of the following helper functions are duplicated in
80 /***********************************************************************
81 * DIB_GetDIBWidthBytes
83 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
85 int DIB_GetDIBWidthBytes( int width, int depth )
91 case 1: words = (width + 31) / 32; break;
92 case 4: words = (width + 7) / 8; break;
93 case 8: words = (width + 3) / 4; break;
95 case 16: words = (width + 1) / 2; break;
96 case 24: words = (width * 3 + 3)/4; break;
99 WARN("(%d): Unsupported depth\n", depth );
107 /***********************************************************************
108 * DIB_GetDIBImageBytes
110 * Return the number of bytes used to hold the image in a DIB bitmap.
112 int DIB_GetDIBImageBytes( int width, int height, int depth )
114 return DIB_GetDIBWidthBytes( width, depth ) * abs( height );
118 /***********************************************************************
121 * Return the size of the bitmap info structure including color table.
123 int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
125 unsigned int colors, size, masks = 0;
127 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
129 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
130 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
131 return sizeof(BITMAPCOREHEADER) + colors *
132 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
134 else /* assume BITMAPINFOHEADER */
136 colors = info->bmiHeader.biClrUsed;
137 if (colors > 256) colors = 256;
138 if (!colors && (info->bmiHeader.biBitCount <= 8))
139 colors = 1 << info->bmiHeader.biBitCount;
140 if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
141 size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
142 return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
147 /***********************************************************************
150 * Get the info from a bitmap header.
151 * Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error.
153 int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
154 LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size )
156 if (header->biSize == sizeof(BITMAPCOREHEADER))
158 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
159 *width = core->bcWidth;
160 *height = core->bcHeight;
161 *planes = core->bcPlanes;
162 *bpp = core->bcBitCount;
167 if (header->biSize >= sizeof(BITMAPINFOHEADER)) /* assume BITMAPINFOHEADER */
169 *width = header->biWidth;
170 *height = header->biHeight;
171 *planes = header->biPlanes;
172 *bpp = header->biBitCount;
173 *compr = header->biCompression;
174 *size = header->biSizeImage;
177 ERR("(%d): unknown/wrong size for header\n", header->biSize );
181 /* nulldrv fallback implementation using SetDIBits/StretchBlt */
182 INT CDECL nulldrv_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT heightDst,
183 INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits,
184 const BITMAPINFO *info, UINT coloruse, DWORD rop )
186 DC *dc = get_nulldrv_dc( dev );
194 /* make sure we have a real implementation for StretchBlt and SetDIBits */
195 if (GET_DC_PHYSDEV( dc, pStretchBlt ) == dev || GET_DC_PHYSDEV( dc, pSetDIBits ) == dev)
198 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size ) == -1)
201 if (width < 0) return 0;
203 if (xSrc == 0 && ySrc == 0 && widthDst == widthSrc && heightDst == heightSrc &&
204 info->bmiHeader.biCompression == BI_RGB)
206 /* Windows appears to have a fast case optimization
207 * that uses the wrong origin for top-down DIBs */
208 if (height < 0 && heightSrc < abs(height)) ySrc = abs(height) - heightSrc;
210 if (xDst == 0 && yDst == 0 && info->bmiHeader.biCompression == BI_RGB && rop == SRCCOPY)
213 hBitmap = GetCurrentObject( dev->hdc, OBJ_BITMAP );
214 if (GetObjectW( hBitmap, sizeof(bm), &bm ) &&
215 bm.bmWidth == widthSrc && bm.bmHeight == heightSrc &&
216 bm.bmBitsPixel == bpp && bm.bmPlanes == planes)
219 return SetDIBits( dev->hdc, hBitmap, 0, height, bits, info, coloruse );
224 hdcMem = CreateCompatibleDC( dev->hdc );
225 hBitmap = CreateCompatibleBitmap( dev->hdc, width, height );
226 SelectObject( hdcMem, hBitmap );
227 if (coloruse == DIB_PAL_COLORS)
228 SelectPalette( hdcMem, GetCurrentObject( dev->hdc, OBJ_PAL ), FALSE );
230 if (info->bmiHeader.biCompression == BI_RLE4 || info->bmiHeader.biCompression == BI_RLE8)
232 /* when RLE compression is used, there may be some gaps (ie the DIB doesn't
233 * contain all the rectangle described in bmiHeader, but only part of it.
234 * This mean that those undescribed pixels must be left untouched.
235 * So, we first copy on a memory bitmap the current content of the
236 * destination rectangle, blit the DIB bits on top of it - hence leaving
237 * the gaps untouched -, and blitting the rectangle back.
238 * This insure that gaps are untouched on the destination rectangle
240 StretchBlt( hdcMem, xSrc, abs(height) - heightSrc - ySrc, widthSrc, heightSrc,
241 dev->hdc, xDst, yDst, widthDst, heightDst, rop );
243 ret = SetDIBits( hdcMem, hBitmap, 0, height, bits, info, coloruse );
244 if (ret) StretchBlt( dev->hdc, xDst, yDst, widthDst, heightDst,
245 hdcMem, xSrc, abs(height) - heightSrc - ySrc, widthSrc, heightSrc, rop );
247 DeleteObject( hBitmap );
251 /***********************************************************************
252 * StretchDIBits (GDI32.@)
254 INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst, INT heightDst,
255 INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits,
256 const BITMAPINFO *info, UINT coloruse, DWORD rop )
261 if (!bits || !info) return 0;
263 if ((dc = get_dc_ptr( hdc )))
265 PHYSDEV physdev = GET_DC_PHYSDEV( dc, pStretchDIBits );
267 ret = physdev->funcs->pStretchDIBits( physdev, xDst, yDst, widthDst, heightDst,
268 xSrc, ySrc, widthSrc, heightSrc, bits, info, coloruse, rop );
269 release_dc_ptr( dc );
275 /******************************************************************************
276 * SetDIBits [GDI32.@]
278 * Sets pixels in a bitmap using colors from DIB.
281 * hdc [I] Handle to device context
282 * hbitmap [I] Handle to bitmap
283 * startscan [I] Starting scan line
284 * lines [I] Number of scan lines
285 * bits [I] Array of bitmap bits
286 * info [I] Address of structure with data
287 * coloruse [I] Type of color indexes to use
290 * Success: Number of scan lines copied
293 INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
294 UINT lines, LPCVOID bits, const BITMAPINFO *info,
297 DC *dc = get_dc_ptr( hdc );
298 BOOL delete_hdc = FALSE;
303 if (coloruse == DIB_RGB_COLORS && !dc)
305 hdc = CreateCompatibleDC(0);
306 dc = get_dc_ptr( hdc );
314 if (!(bitmap = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
316 release_dc_ptr( dc );
317 if (delete_hdc) DeleteDC(hdc);
321 physdev = GET_DC_PHYSDEV( dc, pSetDIBits );
322 if (BITMAP_SetOwnerDC( hbitmap, physdev ))
323 result = physdev->funcs->pSetDIBits( physdev, hbitmap, startscan, lines, bits, info, coloruse );
325 GDI_ReleaseObj( hbitmap );
326 release_dc_ptr( dc );
327 if (delete_hdc) DeleteDC(hdc);
332 /***********************************************************************
333 * SetDIBitsToDevice (GDI32.@)
335 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
336 DWORD cy, INT xSrc, INT ySrc, UINT startscan,
337 UINT lines, LPCVOID bits, const BITMAPINFO *info,
345 if ((dc = get_dc_ptr( hdc )))
347 PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDIBitsToDevice );
349 ret = physdev->funcs->pSetDIBitsToDevice( physdev, xDest, yDest, cx, cy, xSrc,
350 ySrc, startscan, lines, bits, info, coloruse );
351 release_dc_ptr( dc );
356 /***********************************************************************
357 * SetDIBColorTable (GDI32.@)
359 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUAD *colors )
365 if (!(dc = get_dc_ptr( hdc ))) return 0;
367 if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
369 PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDIBColorTable );
371 /* Check if currently selected bitmap is a DIB */
372 if (bitmap->color_table)
374 if (startpos < bitmap->nb_colors)
376 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
377 memcpy(bitmap->color_table + startpos, colors, entries * sizeof(RGBQUAD));
381 GDI_ReleaseObj( dc->hBitmap );
382 physdev->funcs->pSetDIBColorTable( physdev, startpos, entries, colors );
384 release_dc_ptr( dc );
389 /***********************************************************************
390 * GetDIBColorTable (GDI32.@)
392 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
398 if (!(dc = get_dc_ptr( hdc ))) return 0;
400 if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
402 /* Check if currently selected bitmap is a DIB */
403 if (bitmap->color_table)
405 if (startpos < bitmap->nb_colors)
407 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
408 memcpy(colors, bitmap->color_table + startpos, entries * sizeof(RGBQUAD));
412 GDI_ReleaseObj( dc->hBitmap );
414 release_dc_ptr( dc );
418 static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
419 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
420 { 0x00, 0x00, 0x00, 0x00 },
421 { 0x00, 0x00, 0x80, 0x00 },
422 { 0x00, 0x80, 0x00, 0x00 },
423 { 0x00, 0x80, 0x80, 0x00 },
424 { 0x80, 0x00, 0x00, 0x00 },
425 { 0x80, 0x00, 0x80, 0x00 },
426 { 0x80, 0x80, 0x00, 0x00 },
427 { 0xc0, 0xc0, 0xc0, 0x00 },
428 { 0xc0, 0xdc, 0xc0, 0x00 },
429 { 0xf0, 0xca, 0xa6, 0x00 },
430 { 0xf0, 0xfb, 0xff, 0x00 },
431 { 0xa4, 0xa0, 0xa0, 0x00 },
432 { 0x80, 0x80, 0x80, 0x00 },
433 { 0x00, 0x00, 0xff, 0x00 },
434 { 0x00, 0xff, 0x00, 0x00 },
435 { 0x00, 0xff, 0xff, 0x00 },
436 { 0xff, 0x00, 0x00, 0x00 },
437 { 0xff, 0x00, 0xff, 0x00 },
438 { 0xff, 0xff, 0x00, 0x00 },
439 { 0xff, 0xff, 0xff, 0x00 }
442 /******************************************************************************
443 * GetDIBits [GDI32.@]
445 * Retrieves bits of bitmap and copies to buffer.
448 * Success: Number of scan lines copied from bitmap
451 INT WINAPI GetDIBits(
452 HDC hdc, /* [in] Handle to device context */
453 HBITMAP hbitmap, /* [in] Handle to bitmap */
454 UINT startscan, /* [in] First scan line to set in dest bitmap */
455 UINT lines, /* [in] Number of scan lines to copy */
456 LPVOID bits, /* [out] Address of array for bitmap bits */
457 BITMAPINFO * info, /* [out] Address of structure with bitmap data */
458 UINT coloruse) /* [in] RGB or palette index */
470 RGBQUAD quad_buf[256];
471 RGBQUAD* rgbQuads = quad_buf;
475 bitmap_type = DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size);
476 if (bitmap_type == -1)
478 ERR("Invalid bitmap format\n");
481 core_header = (bitmap_type == 0);
482 if (!(dc = get_dc_ptr( hdc )))
484 SetLastError( ERROR_INVALID_PARAMETER );
488 if (!(bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
490 release_dc_ptr( dc );
494 colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
495 if(!core_header) rgbQuads = colorPtr;
497 /* Transfer color info */
501 case 0: /* query bitmap info only */
504 BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
505 coreheader->bcWidth = bmp->bitmap.bmWidth;
506 coreheader->bcHeight = bmp->bitmap.bmHeight;
507 coreheader->bcPlanes = 1;
508 coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
512 info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
513 info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
514 info->bmiHeader.biPlanes = 1;
515 info->bmiHeader.biSizeImage =
516 DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
517 bmp->bitmap.bmHeight,
518 bmp->bitmap.bmBitsPixel );
521 info->bmiHeader.biBitCount = bmp->dib->dsBm.bmBitsPixel;
522 switch (bmp->dib->dsBm.bmBitsPixel)
526 info->bmiHeader.biCompression = BI_BITFIELDS;
529 info->bmiHeader.biCompression = BI_RGB;
535 info->bmiHeader.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB;
536 info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
538 info->bmiHeader.biXPelsPerMeter = 0;
539 info->bmiHeader.biYPelsPerMeter = 0;
540 info->bmiHeader.biClrUsed = 0;
541 info->bmiHeader.biClrImportant = 0;
543 /* Windows 2000 doesn't touch the additional struct members if
544 it's a BITMAPV4HEADER or a BITMAPV5HEADER */
546 lines = abs(bmp->bitmap.bmHeight);
553 unsigned int colors = 1 << bpp;
555 if (!core_header) info->bmiHeader.biClrUsed = 0;
557 if (coloruse == DIB_PAL_COLORS)
559 WORD *index = colorPtr;
560 for (i = 0; i < colors; i++, index++)
566 /* If the bitmap object already has a dib section at the
567 same color depth then get the color map from it */
569 if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == bpp)
571 colors = min( colors, bmp->nb_colors );
573 if (!core_header && colors != 1 << bpp) info->bmiHeader.biClrUsed = colors;
575 memcpy(rgbQuads, bmp->color_table, colors * sizeof(RGBQUAD));
578 /* For color DDBs in native depth (mono DDBs always have a black/white palette):
579 Generate the color map from the selected palette */
581 else if (bpp > 1 && bpp == bmp->bitmap.bmBitsPixel)
583 PALETTEENTRY palEntry[256];
585 memset( palEntry, 0, sizeof(palEntry) );
586 if (!GetPaletteEntries( dc->hPalette, 0, colors, palEntry ))
588 release_dc_ptr( dc );
589 GDI_ReleaseObj( hbitmap );
592 for (i = 0; i < colors; i++)
594 rgbQuads[i].rgbRed = palEntry[i].peRed;
595 rgbQuads[i].rgbGreen = palEntry[i].peGreen;
596 rgbQuads[i].rgbBlue = palEntry[i].peBlue;
597 rgbQuads[i].rgbReserved = 0;
605 rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen = rgbQuads[0].rgbBlue = 0;
606 rgbQuads[0].rgbReserved = 0;
607 rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen = rgbQuads[1].rgbBlue = 0xff;
608 rgbQuads[1].rgbReserved = 0;
612 /* The EGA palette is the first and last 8 colours of the default palette
613 with the innermost pair swapped */
614 memcpy(rgbQuads, DefLogPaletteQuads, 7 * sizeof(RGBQUAD));
615 memcpy(rgbQuads + 7, DefLogPaletteQuads + 12, 1 * sizeof(RGBQUAD));
616 memcpy(rgbQuads + 8, DefLogPaletteQuads + 7, 1 * sizeof(RGBQUAD));
617 memcpy(rgbQuads + 9, DefLogPaletteQuads + 13, 7 * sizeof(RGBQUAD));
621 memcpy(rgbQuads, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
622 memcpy(rgbQuads + 246, DefLogPaletteQuads + 10, 10 * sizeof(RGBQUAD));
623 for (i = 10; i < 246; i++)
625 rgbQuads[i].rgbRed = (i & 0x07) << 5;
626 rgbQuads[i].rgbGreen = (i & 0x38) << 2;
627 rgbQuads[i].rgbBlue = i & 0xc0;
628 rgbQuads[i].rgbReserved = 0;
635 RGBTRIPLE *triple = (RGBTRIPLE *)colorPtr;
636 for (i = 0; i < colors; i++)
638 triple[i].rgbtRed = rgbQuads[i].rgbRed;
639 triple[i].rgbtGreen = rgbQuads[i].rgbGreen;
640 triple[i].rgbtBlue = rgbQuads[i].rgbBlue;
648 if (info->bmiHeader.biCompression == BI_BITFIELDS)
650 ((PDWORD)info->bmiColors)[0] = 0x7c00;
651 ((PDWORD)info->bmiColors)[1] = 0x03e0;
652 ((PDWORD)info->bmiColors)[2] = 0x001f;
657 if (info->bmiHeader.biCompression == BI_BITFIELDS)
661 if (bmp->dib->dsBmih.biCompression == BI_BITFIELDS)
662 memcpy( info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
665 ((PDWORD)info->bmiColors)[0] = 0x7c00;
666 ((PDWORD)info->bmiColors)[1] = 0x03e0;
667 ((PDWORD)info->bmiColors)[2] = 0x001f;
672 ((PDWORD)info->bmiColors)[0] = 0xf800;
673 ((PDWORD)info->bmiColors)[1] = 0x07e0;
674 ((PDWORD)info->bmiColors)[2] = 0x001f;
681 if (info->bmiHeader.biCompression == BI_BITFIELDS)
683 if (bmp->dib && bmp->dib->dsBmih.biCompression == BI_BITFIELDS)
684 memcpy( info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
687 ((PDWORD)info->bmiColors)[0] = 0xff0000;
688 ((PDWORD)info->bmiColors)[1] = 0x00ff00;
689 ((PDWORD)info->bmiColors)[2] = 0x0000ff;
697 /* If the bitmap object already have a dib section that contains image data, get the bits from it */
698 if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
700 /*FIXME: Only RGB dibs supported for now */
701 unsigned int srcwidth = bmp->dib->dsBm.bmWidth;
702 int srcwidthb = bmp->dib->dsBm.bmWidthBytes;
703 unsigned int dstwidth = width;
704 int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
705 LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
706 unsigned int x, y, width, widthb;
709 * If copying from a top-down source bitmap, move the source
710 * pointer to the end of the source bitmap and negate the width
711 * so that we copy the bits upside-down.
713 if (bmp->dib->dsBmih.biHeight < 0)
715 sbits += (srcwidthb * (int)(abs(bmp->dib->dsBmih.biHeight) - 2 * startscan - 1));
716 srcwidthb = -srcwidthb;
718 /*Same for the destination.*/
721 dbits = (LPBYTE)bits + (dstwidthb * (lines - 1));
722 dstwidthb = -dstwidthb;
727 case 16: /* 16 bpp dstDIB */
729 LPWORD dstbits = (LPWORD)dbits;
730 WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
732 /* FIXME: BI_BITFIELDS not supported yet */
734 switch(bmp->dib->dsBm.bmBitsPixel) {
736 case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
738 widthb = min(abs(srcwidthb), abs(dstwidthb));
739 /* FIXME: BI_BITFIELDS not supported yet */
740 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
741 memcpy(dbits, sbits, widthb);
745 case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
747 LPBYTE srcbits = sbits;
749 width = min(srcwidth, dstwidth);
750 for( y = 0; y < lines; y++) {
751 for( x = 0; x < width; x++, srcbits += 3)
752 *dstbits++ = ((srcbits[0] >> 3) & bmask) |
753 (((WORD)srcbits[1] << 2) & gmask) |
754 (((WORD)srcbits[2] << 7) & rmask);
756 dstbits = (LPWORD)(dbits+=dstwidthb);
757 srcbits = (sbits += srcwidthb);
762 case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
764 LPDWORD srcbits = (LPDWORD)sbits;
767 width = min(srcwidth, dstwidth);
768 for( y = 0; y < lines; y++) {
769 for( x = 0; x < width; x++ ) {
771 *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
772 ((val >> 9) & rmask));
774 dstbits = (LPWORD)(dbits+=dstwidthb);
775 srcbits = (LPDWORD)(sbits+=srcwidthb);
780 default: /* ? bit bmp -> 16 bit DIB */
781 FIXME("15/16 bit DIB %d bit bitmap\n",
782 bmp->bitmap.bmBitsPixel);
788 case 24: /* 24 bpp dstDIB */
790 LPBYTE dstbits = dbits;
792 switch(bmp->dib->dsBm.bmBitsPixel) {
794 case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
796 LPWORD srcbits = (LPWORD)sbits;
799 width = min(srcwidth, dstwidth);
800 /* FIXME: BI_BITFIELDS not supported yet */
801 for( y = 0; y < lines; y++) {
802 for( x = 0; x < width; x++ ) {
804 *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
805 *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
806 *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
808 dstbits = dbits+=dstwidthb;
809 srcbits = (LPWORD)(sbits+=srcwidthb);
814 case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
816 widthb = min(abs(srcwidthb), abs(dstwidthb));
817 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
818 memcpy(dbits, sbits, widthb);
822 case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
824 LPBYTE srcbits = sbits;
826 width = min(srcwidth, dstwidth);
827 for( y = 0; y < lines; y++) {
828 for( x = 0; x < width; x++, srcbits++ ) {
829 *dstbits++ = *srcbits++;
830 *dstbits++ = *srcbits++;
831 *dstbits++ = *srcbits++;
833 dstbits = dbits+=dstwidthb;
834 srcbits = sbits+=srcwidthb;
839 default: /* ? bit bmp -> 24 bit DIB */
840 FIXME("24 bit DIB %d bit bitmap\n",
841 bmp->bitmap.bmBitsPixel);
847 case 32: /* 32 bpp dstDIB */
849 LPDWORD dstbits = (LPDWORD)dbits;
851 /* FIXME: BI_BITFIELDS not supported yet */
853 switch(bmp->dib->dsBm.bmBitsPixel) {
854 case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
856 LPWORD srcbits = (LPWORD)sbits;
859 width = min(srcwidth, dstwidth);
860 /* FIXME: BI_BITFIELDS not supported yet */
861 for( y = 0; y < lines; y++) {
862 for( x = 0; x < width; x++ ) {
863 val = (DWORD)*srcbits++;
864 *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
865 ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
866 ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
868 dstbits=(LPDWORD)(dbits+=dstwidthb);
869 srcbits=(LPWORD)(sbits+=srcwidthb);
874 case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
876 LPBYTE srcbits = sbits;
878 width = min(srcwidth, dstwidth);
879 for( y = 0; y < lines; y++) {
880 for( x = 0; x < width; x++, srcbits+=3 )
881 *dstbits++ = srcbits[0] |
884 dstbits=(LPDWORD)(dbits+=dstwidthb);
885 srcbits=(sbits+=srcwidthb);
890 case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
892 widthb = min(abs(srcwidthb), abs(dstwidthb));
893 /* FIXME: BI_BITFIELDS not supported yet */
894 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
895 memcpy(dbits, sbits, widthb);
900 default: /* ? bit bmp -> 32 bit DIB */
901 FIXME("32 bit DIB %d bit bitmap\n",
902 bmp->bitmap.bmBitsPixel);
908 default: /* ? bit DIB */
909 FIXME("Unsupported DIB depth %d\n", info->bmiHeader.biBitCount);
913 /* Otherwise, get bits from the XImage */
916 PHYSDEV physdev = GET_DC_PHYSDEV( dc, pGetDIBits );
917 if (!BITMAP_SetOwnerDC( hbitmap, physdev )) lines = 0;
918 else lines = physdev->funcs->pGetDIBits( physdev, hbitmap, startscan,
919 lines, bits, info, coloruse );
922 else lines = abs(height);
924 /* The knowledge base article Q81498 ("DIBs and Their Uses") states that
925 if bits == NULL and bpp != 0, only biSizeImage and the color table are
929 /* FIXME: biSizeImage should be calculated according to the selected
930 compression algorithm if biCompression != BI_RGB */
931 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp );
932 TRACE("biSizeImage = %d, ", info->bmiHeader.biSizeImage);
934 TRACE("biWidth = %d, biHeight = %d\n", width, height);
937 release_dc_ptr( dc );
938 GDI_ReleaseObj( hbitmap );
943 /***********************************************************************
944 * CreateDIBitmap (GDI32.@)
946 * Creates a DDB (device dependent bitmap) from a DIB.
947 * The DDB will have the same color depth as the reference DC.
949 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
950 DWORD init, LPCVOID bits, const BITMAPINFO *data,
959 if (!header) return 0;
961 if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &size ) == -1) return 0;
965 TRACE("Bitmap has a negative width\n");
969 /* Top-down DIBs have a negative height */
970 if (height < 0) height = -height;
972 TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
973 hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
976 handle = CreateBitmap( width, height, 1, 1, NULL );
978 handle = CreateCompatibleBitmap( hdc, width, height );
984 if (SetDIBits( hdc, handle, 0, height, bits, data, coloruse ) == 0)
986 DeleteObject( handle );
995 /* Copy/synthesize RGB palette from BITMAPINFO. Ripped from dlls/winex11.drv/dib.c */
996 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
999 unsigned int colors, i;
1000 BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
1004 colors = 1 << ((const BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
1008 colors = info->bmiHeader.biClrUsed;
1009 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
1013 ERR("called with >256 colors!\n");
1017 if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1019 if(coloruse == DIB_RGB_COLORS)
1023 /* Convert RGBTRIPLEs to RGBQUADs */
1024 for (i=0; i < colors; i++)
1026 colorTable[i].rgbRed = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
1027 colorTable[i].rgbGreen = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
1028 colorTable[i].rgbBlue = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
1029 colorTable[i].rgbReserved = 0;
1034 memcpy(colorTable, (const BYTE*) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
1039 PALETTEENTRY entries[256];
1040 const WORD *index = (const WORD*) ((const BYTE*) info + (WORD) info->bmiHeader.biSize);
1041 UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1043 for (i = 0; i < colors; i++, index++)
1045 PALETTEENTRY *entry = &entries[*index % count];
1046 colorTable[i].rgbRed = entry->peRed;
1047 colorTable[i].rgbGreen = entry->peGreen;
1048 colorTable[i].rgbBlue = entry->peBlue;
1049 colorTable[i].rgbReserved = 0;
1052 bmp->color_table = colorTable;
1053 bmp->nb_colors = colors;
1056 /***********************************************************************
1057 * CreateDIBSection (GDI32.@)
1059 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1060 VOID **bits, HANDLE section, DWORD offset)
1064 BOOL bDesktopDC = FALSE;
1070 DWORD compression, sizeImage;
1071 void *mapBits = NULL;
1074 if(bits) *bits = NULL;
1078 if (((bitmap_type = DIB_GetBitmapInfo( &bmi->bmiHeader, &width, &height,
1079 &planes, &bpp, &compression, &sizeImage )) == -1))
1086 if (compression == BI_BITFIELDS) break;
1092 if (compression == BI_RGB) break;
1095 WARN( "invalid %u bpp compression %u\n", bpp, compression );
1099 if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1101 TRACE("format (%d,%d), planes %d, bpp %d, %s, size %d %s\n",
1102 width, height, planes, bpp, compression == BI_BITFIELDS? "BI_BITFIELDS" : "BI_RGB",
1103 sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1105 dib->dsBm.bmType = 0;
1106 dib->dsBm.bmWidth = width;
1107 dib->dsBm.bmHeight = height >= 0 ? height : -height;
1108 dib->dsBm.bmWidthBytes = DIB_GetDIBWidthBytes(width, bpp);
1109 dib->dsBm.bmPlanes = planes;
1110 dib->dsBm.bmBitsPixel = bpp;
1111 dib->dsBm.bmBits = NULL;
1113 if (!bitmap_type) /* core header */
1115 /* convert the BITMAPCOREHEADER to a BITMAPINFOHEADER */
1116 dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1117 dib->dsBmih.biWidth = width;
1118 dib->dsBmih.biHeight = height;
1119 dib->dsBmih.biPlanes = planes;
1120 dib->dsBmih.biBitCount = bpp;
1121 dib->dsBmih.biCompression = compression;
1122 dib->dsBmih.biXPelsPerMeter = 0;
1123 dib->dsBmih.biYPelsPerMeter = 0;
1124 dib->dsBmih.biClrUsed = 0;
1125 dib->dsBmih.biClrImportant = 0;
1129 /* truncate extended bitmap headers (BITMAPV4HEADER etc.) */
1130 dib->dsBmih = bmi->bmiHeader;
1131 dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1134 /* set number of entries in bmi.bmiColors table */
1136 dib->dsBmih.biClrUsed = 1 << bpp;
1138 dib->dsBmih.biSizeImage = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
1140 /* set dsBitfields values */
1141 dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1143 if((bpp == 15 || bpp == 16) && compression == BI_RGB)
1145 /* In this case Windows changes biCompression to BI_BITFIELDS,
1146 however for now we won't do this, as there are a lot
1147 of places where BI_BITFIELDS is currently unsupported. */
1149 /* dib->dsBmih.biCompression = compression = BI_BITFIELDS;*/
1150 dib->dsBitfields[0] = 0x7c00;
1151 dib->dsBitfields[1] = 0x03e0;
1152 dib->dsBitfields[2] = 0x001f;
1154 else if(compression == BI_BITFIELDS)
1156 dib->dsBitfields[0] = *(const DWORD *)bmi->bmiColors;
1157 dib->dsBitfields[1] = *((const DWORD *)bmi->bmiColors + 1);
1158 dib->dsBitfields[2] = *((const DWORD *)bmi->bmiColors + 2);
1161 /* get storage location for DIB bits */
1165 SYSTEM_INFO SystemInfo;
1169 GetSystemInfo( &SystemInfo );
1170 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1171 mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1172 mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1173 if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1178 dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1179 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1181 dib->dshSection = section;
1182 dib->dsOffset = offset;
1184 if (!dib->dsBm.bmBits)
1186 HeapFree( GetProcessHeap(), 0, dib );
1190 /* If the reference hdc is null, take the desktop dc */
1193 hdc = CreateCompatibleDC(0);
1197 if (!(dc = get_dc_ptr( hdc ))) goto error;
1199 /* create Device Dependent Bitmap and add DIB pointer */
1200 ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1201 (bpp == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1203 if (ret && ((bmp = GDI_GetObjPtr(ret, OBJ_BITMAP))))
1205 PHYSDEV physdev = GET_DC_PHYSDEV( dc, pCreateDIBSection );
1207 bmp->funcs = physdev->funcs;
1208 /* create local copy of DIB palette */
1209 if (bpp <= 8) DIB_CopyColorTable( dc, bmp, usage, bmi );
1210 GDI_ReleaseObj( ret );
1212 if (!physdev->funcs->pCreateDIBSection( physdev, ret, bmi, usage ))
1214 DeleteObject( ret );
1219 release_dc_ptr( dc );
1220 if (bDesktopDC) DeleteDC( hdc );
1221 if (ret && bits) *bits = dib->dsBm.bmBits;
1225 if (bDesktopDC) DeleteDC( hdc );
1226 if (section) UnmapViewOfFile( mapBits );
1227 else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1228 HeapFree( GetProcessHeap(), 0, dib );