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).
34 * The palettes are stored in different formats:
36 - BITMAPCOREINFO: Array of RGBTRIPLE
37 - BITMAPINFO: Array of RGBQUAD
40 * There are even more DIB headers, but they all extend BITMAPINFOHEADER:
42 - BITMAPV4HEADER: Introduced in Windows 95 / NT 4.0
43 - BITMAPV5HEADER: Introduced in Windows 98 / 2000
45 If biCompression is BI_BITFIELDS, the color masks are at the same position
46 in all the headers (they start at bmiColors of BITMAPINFOHEADER), because
47 the new headers have structure members for the masks.
50 * You should never access the color table using the bmiColors member,
51 because the passed structure may have one of the extended headers
52 mentioned above. Use this to calculate the location:
55 void* colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
59 Search for "Bitmap Structures" in MSDN
69 #include "gdi_private.h"
70 #include "wine/debug.h"
72 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
75 /***********************************************************************
78 * Return the size of the bitmap info structure including color table.
80 int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
82 unsigned int colors, size, masks = 0;
84 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
86 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
87 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
88 return sizeof(BITMAPCOREHEADER) + colors *
89 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
91 else /* assume BITMAPINFOHEADER */
93 colors = get_dib_num_of_colors( info );
94 if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
95 size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
96 return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
100 /*******************************************************************************************
101 * Fill out a true BITMAPINFOHEADER from a variable sized BITMAPINFOHEADER / BITMAPCOREHEADER.
103 static BOOL bitmapinfoheader_from_user_bitmapinfo( BITMAPINFOHEADER *dst, const BITMAPINFOHEADER *info )
105 if (!info) return FALSE;
107 if (info->biSize == sizeof(BITMAPCOREHEADER))
109 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
110 dst->biWidth = core->bcWidth;
111 dst->biHeight = core->bcHeight;
112 dst->biPlanes = core->bcPlanes;
113 dst->biBitCount = core->bcBitCount;
114 dst->biCompression = BI_RGB;
115 dst->biXPelsPerMeter = 0;
116 dst->biYPelsPerMeter = 0;
118 dst->biClrImportant = 0;
120 else if (info->biSize >= sizeof(BITMAPINFOHEADER)) /* assume BITMAPINFOHEADER */
126 WARN( "(%u): unknown/wrong size for header\n", info->biSize );
130 dst->biSize = sizeof(*dst);
131 if (dst->biCompression == BI_RGB || dst->biCompression == BI_BITFIELDS)
132 dst->biSizeImage = get_dib_image_size( (BITMAPINFO *)dst );
136 /*******************************************************************************************
137 * Fill out a true BITMAPINFO from a variable sized BITMAPINFO / BITMAPCOREINFO.
139 static BOOL bitmapinfo_from_user_bitmapinfo( BITMAPINFO *dst, const BITMAPINFO *info, UINT coloruse )
144 if (!bitmapinfoheader_from_user_bitmapinfo( &dst->bmiHeader, &info->bmiHeader )) return FALSE;
146 src_colors = (char *)info + info->bmiHeader.biSize;
147 colors = get_dib_num_of_colors( dst );
149 if (info->bmiHeader.biCompression == BI_BITFIELDS)
151 /* bitfields are always at bmiColors even in larger structures */
152 memcpy( dst->bmiColors, info->bmiColors, 3 * sizeof(DWORD) );
156 if (coloruse == DIB_PAL_COLORS)
157 memcpy( dst->bmiColors, src_colors, colors * sizeof(WORD) );
158 else if (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER))
159 memcpy( dst->bmiColors, src_colors, colors * sizeof(RGBQUAD) );
163 RGBTRIPLE *triple = (RGBTRIPLE *)src_colors;
164 for (i = 0; i < colors; i++)
166 dst->bmiColors[i].rgbRed = triple[i].rgbtRed;
167 dst->bmiColors[i].rgbGreen = triple[i].rgbtGreen;
168 dst->bmiColors[i].rgbBlue = triple[i].rgbtBlue;
169 dst->bmiColors[i].rgbReserved = 0;
176 static int fill_color_table_from_palette( BITMAPINFO *info, DC *dc )
178 PALETTEENTRY palEntry[256];
179 int i, colors = get_dib_num_of_colors( info );
181 if (!colors) return 0;
183 memset( palEntry, 0, sizeof(palEntry) );
184 if (!GetPaletteEntries( dc->hPalette, 0, colors, palEntry ))
187 for (i = 0; i < colors; i++)
189 info->bmiColors[i].rgbRed = palEntry[i].peRed;
190 info->bmiColors[i].rgbGreen = palEntry[i].peGreen;
191 info->bmiColors[i].rgbBlue = palEntry[i].peBlue;
192 info->bmiColors[i].rgbReserved = 0;
198 static void *get_pixel_ptr( const BITMAPINFO *info, void *bits, int x, int y )
200 const int width = info->bmiHeader.biWidth, height = info->bmiHeader.biHeight;
201 const int bpp = info->bmiHeader.biBitCount;
204 return (char *)bits + (height - y - 1) * get_dib_stride( width, bpp ) + x * bpp / 8;
206 return (char *)bits + y * get_dib_stride( width, bpp ) + x * bpp / 8;
209 static BOOL build_rle_bitmap( const BITMAPINFO *info, struct gdi_image_bits *bits, HRGN *clip )
213 int x, y, width = info->bmiHeader.biWidth, height = info->bmiHeader.biHeight;
215 BYTE skip, num, data;
216 BYTE *out_bits, *in_bits = bits->ptr;
220 assert( info->bmiHeader.biBitCount == 4 || info->bmiHeader.biBitCount == 8 );
222 out_bits = HeapAlloc( GetProcessHeap(), 0, get_dib_image_size( info ) );
223 *clip = CreateRectRgn( 0, 0, 0, 0 );
224 run = CreateRectRgn( 0, 0, 0, 0 );
225 if (!out_bits || !*clip || !run) goto fail;
227 x = left = right = 0;
230 while (i < info->bmiHeader.biSizeImage - 1)
233 data = in_bits[i + 1];
238 if (x + num > width) num = width - x;
241 BYTE s = data, *out_ptr = get_pixel_ptr( info, out_bits, x, y );
242 if (info->bmiHeader.biBitCount == 8)
243 memset( out_ptr, s, num );
248 s = ((s >> 4) & 0x0f) | ((s << 4) & 0xf0);
249 *out_ptr = (*out_ptr & 0xf0) | (s & 0x0f);
254 /* this will write one too many if num is odd, but that doesn't matter */
255 if (num) memset( out_ptr, s, (num + 1) / 2 );
267 SetRectRgn( run, left, y, right, y + 1 );
268 CombineRgn( *clip, run, *clip, RGN_OR );
273 left = right = x = 0;
282 if (i >= info->bmiHeader.biSizeImage - 1) goto done;
284 if (x > width) x = width;
291 else /* data bytes of data */
294 skip = (num * info->bmiHeader.biBitCount + 7) / 8;
295 if (skip > info->bmiHeader.biSizeImage - i) goto done;
296 skip = (skip + 1) & ~1;
297 if (x + num > width) num = width - x;
300 BYTE *out_ptr = get_pixel_ptr( info, out_bits, x, y );
301 if (info->bmiHeader.biBitCount == 8)
302 memcpy( out_ptr, in_bits + i, num );
307 const BYTE *in_ptr = in_bits + i;
308 for ( ; num; num--, x++)
312 *out_ptr = (*out_ptr & 0xf0) | ((*in_ptr >> 4) & 0x0f);
316 *out_ptr = (*in_ptr++ << 4) & 0xf0;
320 memcpy( out_ptr, in_bits + i, (num + 1) / 2);
332 if (bits->free) bits->free( bits );
334 bits->ptr = out_bits;
335 bits->is_copy = TRUE;
336 bits->free = free_heap_bits;
341 if (run) DeleteObject( run );
342 if (*clip) DeleteObject( *clip );
343 HeapFree( GetProcessHeap(), 0, out_bits );
349 /* nulldrv fallback implementation using SetDIBits/StretchBlt */
350 INT nulldrv_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT heightDst,
351 INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits,
352 const BITMAPINFO *info, UINT coloruse, DWORD rop )
354 DC *dc = get_nulldrv_dc( dev );
360 /* make sure we have a real implementation for StretchBlt and PutImage */
361 if (GET_DC_PHYSDEV( dc, pStretchBlt ) == dev || GET_DC_PHYSDEV( dc, pPutImage ) == dev)
364 if (info->bmiHeader.biWidth < 0) return 0;
365 height = info->bmiHeader.biHeight;
367 if (xSrc == 0 && ySrc == 0 && widthDst == widthSrc && heightDst == heightSrc &&
368 info->bmiHeader.biCompression == BI_RGB)
370 /* Windows appears to have a fast case optimization
371 * that uses the wrong origin for top-down DIBs */
372 if (height < 0 && heightSrc < abs(height)) ySrc = abs(height) - heightSrc;
374 if (xDst == 0 && yDst == 0 && info->bmiHeader.biCompression == BI_RGB && rop == SRCCOPY)
377 hBitmap = GetCurrentObject( dev->hdc, OBJ_BITMAP );
378 if (GetObjectW( hBitmap, sizeof(bm), &bm ) &&
379 bm.bmWidth == widthSrc && bm.bmHeight == heightSrc &&
380 bm.bmBitsPixel == info->bmiHeader.biBitCount && bm.bmPlanes == 1)
383 return SetDIBits( dev->hdc, hBitmap, 0, abs( height ), bits, info, coloruse );
388 hdcMem = CreateCompatibleDC( dev->hdc );
389 hBitmap = CreateCompatibleBitmap( dev->hdc, info->bmiHeader.biWidth, height );
390 SelectObject( hdcMem, hBitmap );
391 if (coloruse == DIB_PAL_COLORS)
392 SelectPalette( hdcMem, GetCurrentObject( dev->hdc, OBJ_PAL ), FALSE );
394 if (info->bmiHeader.biCompression == BI_RLE4 || info->bmiHeader.biCompression == BI_RLE8)
396 /* when RLE compression is used, there may be some gaps (ie the DIB doesn't
397 * contain all the rectangle described in bmiHeader, but only part of it.
398 * This mean that those undescribed pixels must be left untouched.
399 * So, we first copy on a memory bitmap the current content of the
400 * destination rectangle, blit the DIB bits on top of it - hence leaving
401 * the gaps untouched -, and blitting the rectangle back.
402 * This insure that gaps are untouched on the destination rectangle
404 StretchBlt( hdcMem, xSrc, abs(height) - heightSrc - ySrc, widthSrc, heightSrc,
405 dev->hdc, xDst, yDst, widthDst, heightDst, rop );
407 ret = SetDIBits( hdcMem, hBitmap, 0, abs( height ), bits, info, coloruse );
408 if (ret) StretchBlt( dev->hdc, xDst, yDst, widthDst, heightDst,
409 hdcMem, xSrc, abs(height) - heightSrc - ySrc, widthSrc, heightSrc, rop );
411 DeleteObject( hBitmap );
415 /***********************************************************************
416 * StretchDIBits (GDI32.@)
418 INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst, INT heightDst,
419 INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, const void *bits,
420 const BITMAPINFO *bmi, UINT coloruse, DWORD rop )
422 char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
423 BITMAPINFO *info = (BITMAPINFO *)buffer;
428 if (!bitmapinfo_from_user_bitmapinfo( info, bmi, coloruse )) return 0;
430 if ((dc = get_dc_ptr( hdc )))
432 PHYSDEV physdev = GET_DC_PHYSDEV( dc, pStretchDIBits );
434 ret = physdev->funcs->pStretchDIBits( physdev, xDst, yDst, widthDst, heightDst,
435 xSrc, ySrc, widthSrc, heightSrc, bits, info, coloruse, rop );
436 release_dc_ptr( dc );
442 /******************************************************************************
443 * SetDIBits [GDI32.@]
445 * Sets pixels in a bitmap using colors from DIB.
448 * hdc [I] Handle to device context
449 * hbitmap [I] Handle to bitmap
450 * startscan [I] Starting scan line
451 * lines [I] Number of scan lines
452 * bits [I] Array of bitmap bits
453 * info [I] Address of structure with data
454 * coloruse [I] Type of color indexes to use
457 * Success: Number of scan lines copied
460 INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
461 UINT lines, LPCVOID bits, const BITMAPINFO *info,
464 DC *dc = get_dc_ptr( hdc );
465 BOOL delete_hdc = FALSE;
468 char src_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
469 BITMAPINFO *src_info = (BITMAPINFO *)src_bmibuf;
470 char dst_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
471 BITMAPINFO *dst_info = (BITMAPINFO *)dst_bmibuf;
474 struct gdi_image_bits src_bits;
475 struct bitblt_coords src, dst;
476 INT src_to_dst_offset;
478 const struct gdi_dc_funcs *funcs;
480 src_bits.ptr = (void *)bits;
481 src_bits.is_copy = FALSE;
482 src_bits.free = NULL;
483 src_bits.param = NULL;
485 if (coloruse == DIB_RGB_COLORS && !dc)
487 hdc = CreateCompatibleDC(0);
488 dc = get_dc_ptr( hdc );
496 if (!(bitmap = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
498 release_dc_ptr( dc );
499 if (delete_hdc) DeleteDC(hdc);
503 if (!bitmapinfo_from_user_bitmapinfo( src_info, info, coloruse )) goto done;
505 if (coloruse == DIB_PAL_COLORS)
506 if (!fill_color_table_from_palette( src_info, dc )) goto done;
508 if (src_info->bmiHeader.biCompression == BI_RLE4 || src_info->bmiHeader.biCompression == BI_RLE8)
510 if ( src_info->bmiHeader.biHeight < 0 ||
511 (src_info->bmiHeader.biCompression == BI_RLE4 && src_info->bmiHeader.biBitCount != 4) ||
512 (src_info->bmiHeader.biCompression == BI_RLE8 && src_info->bmiHeader.biBitCount != 8) )
514 SetLastError( ERROR_INVALID_PARAMETER );
518 if (lines == 0) goto done;
519 else lines = src_info->bmiHeader.biHeight;
522 if (!build_rle_bitmap( src_info, &src_bits, &clip )) goto done;
525 dst.visrect.left = 0;
527 dst.visrect.right = bitmap->bitmap.bmWidth;
528 dst.visrect.bottom = bitmap->bitmap.bmHeight;
530 src.visrect.left = 0;
532 src.visrect.right = src_info->bmiHeader.biWidth;
533 src.visrect.bottom = abs( src_info->bmiHeader.biHeight );
535 if (src_info->bmiHeader.biHeight > 0)
537 src_to_dst_offset = -startscan;
538 lines = min( lines, src.visrect.bottom - startscan );
539 if (lines < src.visrect.bottom) src.visrect.top = src.visrect.bottom - lines;
543 src_to_dst_offset = src.visrect.bottom - lines - startscan;
544 /* Unlike the bottom-up case, Windows doesn't limit lines. */
545 if (lines < src.visrect.bottom) src.visrect.bottom = lines;
548 /* Hack to ensure we don't get the nulldrv if the bmp hasn't been selected
550 physdev = GET_DC_PHYSDEV( dc, pCreateBitmap );
551 if (!BITMAP_SetOwnerDC( hbitmap, physdev )) goto done;
553 funcs = bitmap->funcs;
554 if (bitmap->dib) funcs = dc->dibdrv.dev.funcs;
558 offset_rect( &src.visrect, 0, src_to_dst_offset );
559 if (!intersect_rect( &dst.visrect, &src.visrect, &dst.visrect )) goto done;
560 src.visrect = dst.visrect;
561 offset_rect( &src.visrect, 0, -src_to_dst_offset );
563 src.x = src.visrect.left;
564 src.y = src.visrect.top;
565 src.width = src.visrect.right - src.visrect.left;
566 src.height = src.visrect.bottom - src.visrect.top;
568 dst.x = dst.visrect.left;
569 dst.y = dst.visrect.top;
570 dst.width = dst.visrect.right - dst.visrect.left;
571 dst.height = dst.visrect.bottom - dst.visrect.top;
573 memcpy( dst_info, src_info, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ));
575 err = funcs->pPutImage( NULL, hbitmap, clip, dst_info, &src_bits, &src, &dst, 0 );
576 if (err == ERROR_BAD_FORMAT)
580 dst_info->bmiHeader.biWidth = dst.width;
581 ptr = HeapAlloc( GetProcessHeap(), 0, get_dib_image_size( dst_info ));
584 err = convert_bitmapinfo( src_info, src_bits.ptr, &src, dst_info, ptr );
586 if (src_bits.free) src_bits.free( &src_bits );
588 src_bits.is_copy = TRUE;
589 src_bits.free = free_heap_bits;
591 err = funcs->pPutImage( NULL, hbitmap, clip, dst_info, &src_bits, &src, &dst, 0 );
594 else err = ERROR_OUTOFMEMORY;
599 if (src_bits.free) src_bits.free( &src_bits );
600 if (clip) DeleteObject( clip );
601 GDI_ReleaseObj( hbitmap );
602 release_dc_ptr( dc );
603 if (delete_hdc) DeleteDC(hdc);
608 /***********************************************************************
609 * SetDIBitsToDevice (GDI32.@)
611 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
612 DWORD cy, INT xSrc, INT ySrc, UINT startscan,
613 UINT lines, LPCVOID bits, const BITMAPINFO *bmi,
616 char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
617 BITMAPINFO *info = (BITMAPINFO *)buffer;
622 if (!bitmapinfo_from_user_bitmapinfo( info, bmi, coloruse )) return 0;
624 if ((dc = get_dc_ptr( hdc )))
626 PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDIBitsToDevice );
628 ret = physdev->funcs->pSetDIBitsToDevice( physdev, xDest, yDest, cx, cy, xSrc,
629 ySrc, startscan, lines, bits, info, coloruse );
630 release_dc_ptr( dc );
635 /***********************************************************************
636 * SetDIBColorTable (GDI32.@)
638 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUAD *colors )
644 if (!(dc = get_dc_ptr( hdc ))) return 0;
646 if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
648 PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDIBColorTable );
650 /* Check if currently selected bitmap is a DIB */
651 if (bitmap->color_table)
653 if (startpos < bitmap->nb_colors)
655 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
656 memcpy(bitmap->color_table + startpos, colors, entries * sizeof(RGBQUAD));
660 GDI_ReleaseObj( dc->hBitmap );
661 physdev->funcs->pSetDIBColorTable( physdev, startpos, entries, colors );
663 release_dc_ptr( dc );
668 /***********************************************************************
669 * GetDIBColorTable (GDI32.@)
671 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
677 if (!(dc = get_dc_ptr( hdc ))) return 0;
679 if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
681 /* Check if currently selected bitmap is a DIB */
682 if (bitmap->color_table)
684 if (startpos < bitmap->nb_colors)
686 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
687 memcpy(colors, bitmap->color_table + startpos, entries * sizeof(RGBQUAD));
691 GDI_ReleaseObj( dc->hBitmap );
693 release_dc_ptr( dc );
697 static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
698 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
699 { 0x00, 0x00, 0x00, 0x00 },
700 { 0x00, 0x00, 0x80, 0x00 },
701 { 0x00, 0x80, 0x00, 0x00 },
702 { 0x00, 0x80, 0x80, 0x00 },
703 { 0x80, 0x00, 0x00, 0x00 },
704 { 0x80, 0x00, 0x80, 0x00 },
705 { 0x80, 0x80, 0x00, 0x00 },
706 { 0xc0, 0xc0, 0xc0, 0x00 },
707 { 0xc0, 0xdc, 0xc0, 0x00 },
708 { 0xf0, 0xca, 0xa6, 0x00 },
709 { 0xf0, 0xfb, 0xff, 0x00 },
710 { 0xa4, 0xa0, 0xa0, 0x00 },
711 { 0x80, 0x80, 0x80, 0x00 },
712 { 0x00, 0x00, 0xff, 0x00 },
713 { 0x00, 0xff, 0x00, 0x00 },
714 { 0x00, 0xff, 0xff, 0x00 },
715 { 0xff, 0x00, 0x00, 0x00 },
716 { 0xff, 0x00, 0xff, 0x00 },
717 { 0xff, 0xff, 0x00, 0x00 },
718 { 0xff, 0xff, 0xff, 0x00 }
721 static const DWORD bit_fields_888[3] = {0xff0000, 0x00ff00, 0x0000ff};
722 static const DWORD bit_fields_565[3] = {0xf800, 0x07e0, 0x001f};
723 static const DWORD bit_fields_555[3] = {0x7c00, 0x03e0, 0x001f};
725 static int fill_query_info( BITMAPINFO *info, BITMAPOBJ *bmp )
727 BITMAPINFOHEADER header;
729 header.biSize = info->bmiHeader.biSize; /* Ensure we don't overwrite the original size when we copy back */
730 header.biWidth = bmp->bitmap.bmWidth;
731 header.biHeight = bmp->bitmap.bmHeight;
736 header.biBitCount = bmp->dib->dsBm.bmBitsPixel;
737 switch (bmp->dib->dsBm.bmBitsPixel)
741 header.biCompression = BI_BITFIELDS;
744 header.biCompression = BI_RGB;
750 header.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB;
751 header.biBitCount = bmp->bitmap.bmBitsPixel;
754 header.biSizeImage = get_dib_image_size( (BITMAPINFO *)&header );
755 header.biXPelsPerMeter = 0;
756 header.biYPelsPerMeter = 0;
757 header.biClrUsed = 0;
758 header.biClrImportant = 0;
760 if ( info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER) )
762 BITMAPCOREHEADER *coreheader = (BITMAPCOREHEADER *)info;
764 coreheader->bcWidth = header.biWidth;
765 coreheader->bcHeight = header.biHeight;
766 coreheader->bcPlanes = header.biPlanes;
767 coreheader->bcBitCount = header.biBitCount;
770 info->bmiHeader = header;
772 return abs(bmp->bitmap.bmHeight);
775 /************************************************************************
778 * Copy BITMAPINFO color information where dst may be a BITMAPCOREINFO.
780 static void copy_color_info(BITMAPINFO *dst, const BITMAPINFO *src, UINT coloruse)
782 unsigned int colors = get_dib_num_of_colors( src );
783 RGBQUAD *src_colors = (RGBQUAD *)((char *)src + src->bmiHeader.biSize);
785 assert( src->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) );
787 if (dst->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
789 BITMAPCOREINFO *core = (BITMAPCOREINFO *)dst;
790 if (coloruse == DIB_PAL_COLORS)
791 memcpy( core->bmciColors, src_colors, colors * sizeof(WORD) );
795 for (i = 0; i < colors; i++)
797 core->bmciColors[i].rgbtRed = src_colors[i].rgbRed;
798 core->bmciColors[i].rgbtGreen = src_colors[i].rgbGreen;
799 core->bmciColors[i].rgbtBlue = src_colors[i].rgbBlue;
805 dst->bmiHeader.biClrUsed = src->bmiHeader.biClrUsed;
806 dst->bmiHeader.biSizeImage = src->bmiHeader.biSizeImage;
808 if (src->bmiHeader.biCompression == BI_BITFIELDS)
809 /* bitfields are always at bmiColors even in larger structures */
810 memcpy( dst->bmiColors, src->bmiColors, 3 * sizeof(DWORD) );
813 void *colorptr = (char *)dst + dst->bmiHeader.biSize;
816 if (coloruse == DIB_PAL_COLORS)
817 size = colors * sizeof(WORD);
819 size = colors * sizeof(RGBQUAD);
820 memcpy( colorptr, src_colors, size );
825 static void fill_default_color_table( BITMAPINFO *info )
829 switch (info->bmiHeader.biBitCount)
832 info->bmiColors[0].rgbRed = info->bmiColors[0].rgbGreen = info->bmiColors[0].rgbBlue = 0;
833 info->bmiColors[0].rgbReserved = 0;
834 info->bmiColors[1].rgbRed = info->bmiColors[1].rgbGreen = info->bmiColors[1].rgbBlue = 0xff;
835 info->bmiColors[1].rgbReserved = 0;
839 /* The EGA palette is the first and last 8 colours of the default palette
840 with the innermost pair swapped */
841 memcpy(info->bmiColors, DefLogPaletteQuads, 7 * sizeof(RGBQUAD));
842 memcpy(info->bmiColors + 7, DefLogPaletteQuads + 12, 1 * sizeof(RGBQUAD));
843 memcpy(info->bmiColors + 8, DefLogPaletteQuads + 7, 1 * sizeof(RGBQUAD));
844 memcpy(info->bmiColors + 9, DefLogPaletteQuads + 13, 7 * sizeof(RGBQUAD));
848 memcpy(info->bmiColors, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
849 memcpy(info->bmiColors + 246, DefLogPaletteQuads + 10, 10 * sizeof(RGBQUAD));
850 for (i = 10; i < 246; i++)
852 info->bmiColors[i].rgbRed = (i & 0x07) << 5;
853 info->bmiColors[i].rgbGreen = (i & 0x38) << 2;
854 info->bmiColors[i].rgbBlue = i & 0xc0;
855 info->bmiColors[i].rgbReserved = 0;
860 ERR("called with bitcount %d\n", info->bmiHeader.biBitCount);
864 /******************************************************************************
865 * GetDIBits [GDI32.@]
867 * Retrieves bits of bitmap and copies to buffer.
870 * Success: Number of scan lines copied from bitmap
873 INT WINAPI GetDIBits(
874 HDC hdc, /* [in] Handle to device context */
875 HBITMAP hbitmap, /* [in] Handle to bitmap */
876 UINT startscan, /* [in] First scan line to set in dest bitmap */
877 UINT lines, /* [in] Number of scan lines to copy */
878 LPVOID bits, /* [out] Address of array for bitmap bits */
879 BITMAPINFO * info, /* [out] Address of structure with bitmap data */
880 UINT coloruse) /* [in] RGB or palette index */
884 int i, dst_to_src_offset, ret = 0;
886 char dst_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
887 BITMAPINFO *dst_info = (BITMAPINFO *)dst_bmibuf;
888 char src_bmibuf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
889 BITMAPINFO *src_info = (BITMAPINFO *)src_bmibuf;
890 const struct gdi_dc_funcs *funcs;
891 struct gdi_image_bits src_bits;
892 struct bitblt_coords src, dst;
893 BOOL empty_rect = FALSE;
895 /* Since info may be a BITMAPCOREINFO or any of the larger BITMAPINFO structures, we'll use our
896 own copy and transfer the colour info back at the end */
897 if (!bitmapinfoheader_from_user_bitmapinfo( &dst_info->bmiHeader, &info->bmiHeader )) return 0;
898 dst_info->bmiHeader.biClrUsed = 0;
899 dst_info->bmiHeader.biClrImportant = 0;
901 if (!(dc = get_dc_ptr( hdc )))
903 SetLastError( ERROR_INVALID_PARAMETER );
907 if (!(bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
909 release_dc_ptr( dc );
914 if (bmp->dib) funcs = dc->dibdrv.dev.funcs;
916 if (dst_info->bmiHeader.biBitCount == 0) /* query bitmap info only */
918 ret = fill_query_info( info, bmp );
922 src.visrect.left = 0;
924 src.visrect.right = bmp->bitmap.bmWidth;
925 src.visrect.bottom = bmp->bitmap.bmHeight;
927 dst.visrect.left = 0;
929 dst.visrect.right = dst_info->bmiHeader.biWidth;
930 dst.visrect.bottom = abs( dst_info->bmiHeader.biHeight );
932 if (lines == 0 || startscan >= dst.visrect.bottom)
937 if (dst_info->bmiHeader.biHeight > 0)
939 dst_to_src_offset = -startscan;
940 lines = min( lines, dst.visrect.bottom - startscan );
941 if (lines < dst.visrect.bottom) dst.visrect.top = dst.visrect.bottom - lines;
945 dst_to_src_offset = dst.visrect.bottom - lines - startscan;
946 if (dst_to_src_offset < 0)
948 dst_to_src_offset = 0;
949 lines = dst.visrect.bottom - startscan;
951 if (lines < dst.visrect.bottom) dst.visrect.bottom = lines;
954 offset_rect( &dst.visrect, 0, dst_to_src_offset );
955 empty_rect = !intersect_rect( &src.visrect, &src.visrect, &dst.visrect );
956 dst.visrect = src.visrect;
957 offset_rect( &dst.visrect, 0, -dst_to_src_offset );
959 if (dst_info->bmiHeader.biHeight > 0)
961 if (dst.visrect.bottom < dst_info->bmiHeader.biHeight)
963 int pad_lines = min( dst_info->bmiHeader.biHeight - dst.visrect.bottom, lines );
964 int pad_bytes = pad_lines * get_dib_stride( dst_info->bmiHeader.biWidth, dst_info->bmiHeader.biBitCount );
965 memset( bits, 0, pad_bytes );
966 bits = (char *)bits + pad_bytes;
971 if (dst.visrect.bottom < lines)
973 int pad_lines = lines - dst.visrect.bottom;
974 int stride = get_dib_stride( dst_info->bmiHeader.biWidth, dst_info->bmiHeader.biBitCount );
975 int pad_bytes = pad_lines * stride;
976 memset( (char *)bits + dst.visrect.bottom * stride, 0, pad_bytes );
980 if (empty_rect) bits = NULL;
982 src.x = src.visrect.left;
983 src.y = src.visrect.top;
984 src.width = src.visrect.right - src.visrect.left;
985 src.height = src.visrect.bottom - src.visrect.top;
990 err = funcs->pGetImage( NULL, hbitmap, src_info, bits ? &src_bits : NULL, bits ? &src : NULL );
994 /* fill out the src colour table, if it needs one */
995 if (src_info->bmiHeader.biBitCount <= 8 && src_info->bmiHeader.biClrUsed == 0)
997 fill_default_color_table( src_info );
998 src_info->bmiHeader.biClrUsed = 1 << src_info->bmiHeader.biBitCount;
1001 /* if the src and dst are the same depth, copy the colour info across */
1002 if (dst_info->bmiHeader.biBitCount == src_info->bmiHeader.biBitCount && coloruse == DIB_RGB_COLORS )
1004 switch (src_info->bmiHeader.biBitCount)
1007 if (src_info->bmiHeader.biCompression == BI_RGB)
1009 src_info->bmiHeader.biCompression = BI_BITFIELDS;
1010 memcpy( src_info->bmiColors, bit_fields_555, sizeof(bit_fields_555) );
1014 if (src_info->bmiHeader.biCompression == BI_RGB)
1016 src_info->bmiHeader.biCompression = BI_BITFIELDS;
1017 memcpy( src_info->bmiColors, bit_fields_888, sizeof(bit_fields_888) );
1021 src_info->bmiHeader.biSizeImage = get_dib_image_size( dst_info );
1022 copy_color_info( dst_info, src_info, coloruse );
1024 else if (dst_info->bmiHeader.biBitCount <= 8) /* otherwise construct a default colour table for the dst, if needed */
1026 if( coloruse == DIB_PAL_COLORS )
1028 if (!fill_color_table_from_palette( dst_info, dc )) goto done;
1032 fill_default_color_table( dst_info );
1038 if(dst_info->bmiHeader.biHeight > 0)
1039 dst_info->bmiHeader.biHeight = src.height;
1041 dst_info->bmiHeader.biHeight = -src.height;
1043 convert_bitmapinfo( src_info, src_bits.ptr, &src, dst_info, bits );
1044 if (src_bits.free) src_bits.free( &src_bits );
1048 ret = empty_rect ? FALSE : TRUE;
1050 if (coloruse == DIB_PAL_COLORS)
1052 WORD *index = (WORD *)dst_info->bmiColors;
1053 int colors = get_dib_num_of_colors( dst_info );
1054 for (i = 0; i < colors; i++, index++)
1058 copy_color_info( info, dst_info, coloruse );
1061 release_dc_ptr( dc );
1062 GDI_ReleaseObj( hbitmap );
1067 /***********************************************************************
1068 * CreateDIBitmap (GDI32.@)
1070 * Creates a DDB (device dependent bitmap) from a DIB.
1071 * The DDB will have the same color depth as the reference DC.
1073 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
1074 DWORD init, LPCVOID bits, const BITMAPINFO *data,
1077 BITMAPINFOHEADER info;
1081 if (!bitmapinfoheader_from_user_bitmapinfo( &info, header )) return 0;
1082 if (info.biWidth < 0) return 0;
1084 /* Top-down DIBs have a negative height */
1085 height = abs( info.biHeight );
1087 TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1088 hdc, header, init, bits, data, coloruse, info.biWidth, info.biHeight,
1089 info.biBitCount, info.biCompression);
1092 handle = CreateBitmap( info.biWidth, height, 1, 1, NULL );
1094 handle = CreateCompatibleBitmap( hdc, info.biWidth, height );
1098 if (init & CBM_INIT)
1100 if (SetDIBits( hdc, handle, 0, height, bits, data, coloruse ) == 0)
1102 DeleteObject( handle );
1111 /* Copy/synthesize RGB palette from BITMAPINFO */
1112 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1114 unsigned int colors, i;
1116 colors = get_dib_num_of_colors( info );
1117 if (!(bmp->color_table = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1118 bmp->nb_colors = colors;
1120 if (coloruse == DIB_RGB_COLORS)
1122 memcpy( bmp->color_table, info->bmiColors, colors * sizeof(RGBQUAD));
1126 PALETTEENTRY entries[256];
1127 const WORD *index = (const WORD *)info->bmiColors;
1128 UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1130 for (i = 0; i < colors; i++, index++)
1132 PALETTEENTRY *entry = &entries[*index % count];
1133 bmp->color_table[i].rgbRed = entry->peRed;
1134 bmp->color_table[i].rgbGreen = entry->peGreen;
1135 bmp->color_table[i].rgbBlue = entry->peBlue;
1136 bmp->color_table[i].rgbReserved = 0;
1141 /***********************************************************************
1142 * CreateDIBSection (GDI32.@)
1144 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1145 VOID **bits, HANDLE section, DWORD offset)
1147 char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
1148 BITMAPINFO *info = (BITMAPINFO *)buffer;
1151 BOOL bDesktopDC = FALSE;
1154 void *mapBits = NULL;
1156 if (bits) *bits = NULL;
1157 if (!bitmapinfo_from_user_bitmapinfo( info, bmi, usage )) return 0;
1159 switch (info->bmiHeader.biBitCount)
1163 if (info->bmiHeader.biCompression == BI_BITFIELDS) break;
1169 if (info->bmiHeader.biCompression == BI_RGB) break;
1172 WARN( "invalid %u bpp compression %u\n",
1173 info->bmiHeader.biBitCount, info->bmiHeader.biCompression );
1177 if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1179 TRACE("format (%d,%d), planes %d, bpp %d, %s, size %d %s\n",
1180 info->bmiHeader.biWidth, info->bmiHeader.biHeight,
1181 info->bmiHeader.biPlanes, info->bmiHeader.biBitCount,
1182 info->bmiHeader.biCompression == BI_BITFIELDS? "BI_BITFIELDS" : "BI_RGB",
1183 info->bmiHeader.biSizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1185 dib->dsBm.bmType = 0;
1186 dib->dsBm.bmWidth = info->bmiHeader.biWidth;
1187 dib->dsBm.bmHeight = abs( info->bmiHeader.biHeight );
1188 dib->dsBm.bmWidthBytes = get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
1189 dib->dsBm.bmPlanes = info->bmiHeader.biPlanes;
1190 dib->dsBm.bmBitsPixel = info->bmiHeader.biBitCount;
1191 dib->dsBm.bmBits = NULL;
1192 dib->dsBmih = info->bmiHeader;
1194 /* set number of entries in bmi.bmiColors table */
1195 if( info->bmiHeader.biBitCount <= 8 )
1196 dib->dsBmih.biClrUsed = 1 << info->bmiHeader.biBitCount;
1198 /* set dsBitfields values */
1199 dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1201 if (info->bmiHeader.biBitCount == 16 && info->bmiHeader.biCompression == BI_RGB)
1203 /* In this case Windows changes biCompression to BI_BITFIELDS,
1204 however for now we won't do this, as there are a lot
1205 of places where BI_BITFIELDS is currently unsupported. */
1207 /* dib->dsBmih.biCompression = compression = BI_BITFIELDS;*/
1208 dib->dsBitfields[0] = 0x7c00;
1209 dib->dsBitfields[1] = 0x03e0;
1210 dib->dsBitfields[2] = 0x001f;
1212 else if (info->bmiHeader.biCompression == BI_BITFIELDS)
1214 dib->dsBitfields[0] = *(const DWORD *)bmi->bmiColors;
1215 dib->dsBitfields[1] = *((const DWORD *)bmi->bmiColors + 1);
1216 dib->dsBitfields[2] = *((const DWORD *)bmi->bmiColors + 2);
1219 /* get storage location for DIB bits */
1223 SYSTEM_INFO SystemInfo;
1227 GetSystemInfo( &SystemInfo );
1228 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1229 mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1230 mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1231 if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1236 dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1237 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1239 dib->dshSection = section;
1240 dib->dsOffset = offset;
1242 if (!dib->dsBm.bmBits)
1244 HeapFree( GetProcessHeap(), 0, dib );
1248 /* If the reference hdc is null, take the desktop dc */
1251 hdc = CreateCompatibleDC(0);
1255 if (!(dc = get_dc_ptr( hdc ))) goto error;
1257 /* create Device Dependent Bitmap and add DIB pointer */
1258 ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1259 (info->bmiHeader.biBitCount == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1261 if (ret && ((bmp = GDI_GetObjPtr(ret, OBJ_BITMAP))))
1263 PHYSDEV physdev = GET_DC_PHYSDEV( dc, pCreateDIBSection );
1265 bmp->funcs = physdev->funcs;
1266 /* create local copy of DIB palette */
1267 if (info->bmiHeader.biBitCount <= 8) DIB_CopyColorTable( dc, bmp, usage, info );
1268 GDI_ReleaseObj( ret );
1270 if (!physdev->funcs->pCreateDIBSection( physdev, ret, info, usage ))
1272 DeleteObject( ret );
1277 release_dc_ptr( dc );
1278 if (bDesktopDC) DeleteDC( hdc );
1279 if (ret && bits) *bits = dib->dsBm.bmBits;
1283 if (bDesktopDC) DeleteDC( hdc );
1284 if (section) UnmapViewOfFile( mapBits );
1285 else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1286 HeapFree( GetProcessHeap(), 0, dib );