blob: 893ce6a9d846d4408b653de065f709e7923373a0 [file] [log] [blame]
Alexandre Julliard401710d1993-09-04 10:09:32 +00001/*
Alexandre Julliard3a5816f1994-12-27 14:11:53 +00002 * GDI device-independent bitmaps
Alexandre Julliard401710d1993-09-04 10:09:32 +00003 *
Alexandre Julliard3a5816f1994-12-27 14:11:53 +00004 * Copyright 1993,1994 Alexandre Julliard
Huw D M Davies91d16081998-11-06 11:03:00 +00005 *
Alexandre Julliard3a5816f1994-12-27 14:11:53 +00006 */
7
Alexandre Julliard908464d2000-11-01 03:11:12 +00008#include <stdlib.h>
James Juranf4d5fef2001-01-26 20:43:40 +00009#include <string.h>
Alexandre Julliard908464d2000-11-01 03:11:12 +000010
Michael Veksler92ae2191999-05-02 11:39:09 +000011#include "winbase.h"
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000012#include "bitmap.h"
Alexandre Julliarda2f2e011995-06-06 16:40:35 +000013#include "callback.h"
Alexandre Julliard2239abb2000-11-05 02:05:07 +000014#include "gdi.h"
Alexandre Julliard15657091999-05-23 10:25:25 +000015#include "debugtools.h"
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000016#include "palette.h"
Alexandre Julliard7ff1c411997-05-25 13:58:18 +000017
Alexandre Julliard946a4442000-07-30 13:50:27 +000018DEFAULT_DEBUG_CHANNEL(bitmap);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000019
Alexandre Julliard7ff1c411997-05-25 13:58:18 +000020/***********************************************************************
21 * DIB_GetDIBWidthBytes
22 *
23 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
24 * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
25 */
26int DIB_GetDIBWidthBytes( int width, int depth )
Alexandre Julliard234bc241994-12-10 13:02:28 +000027{
Alexandre Julliard3a5816f1994-12-27 14:11:53 +000028 int words;
29
30 switch(depth)
31 {
Alexandre Julliarddf2673b1997-03-29 17:20:20 +000032 case 1: words = (width + 31) / 32; break;
33 case 4: words = (width + 7) / 8; break;
34 case 8: words = (width + 3) / 4; break;
35 case 15:
36 case 16: words = (width + 1) / 2; break;
37 case 24: words = (width * 3 + 3)/4; break;
38
39 default:
Alexandre Julliard15657091999-05-23 10:25:25 +000040 WARN("(%d): Unsupported depth\n", depth );
Alexandre Julliarddf2673b1997-03-29 17:20:20 +000041 /* fall through */
42 case 32:
43 words = width;
Alexandre Julliard3a5816f1994-12-27 14:11:53 +000044 }
45 return 4 * words;
Alexandre Julliard234bc241994-12-10 13:02:28 +000046}
Alexandre Julliard401710d1993-09-04 10:09:32 +000047
Huw D M Davies608629b1999-04-18 12:07:00 +000048/***********************************************************************
49 * DIB_GetDIBImageBytes
50 *
51 * Return the number of bytes used to hold the image in a DIB bitmap.
52 */
53int DIB_GetDIBImageBytes( int width, int height, int depth )
54{
55 return DIB_GetDIBWidthBytes( width, depth ) * abs( height );
56}
57
Alexandre Julliard3a5816f1994-12-27 14:11:53 +000058
Alexandre Julliard401710d1993-09-04 10:09:32 +000059/***********************************************************************
60 * DIB_BitmapInfoSize
61 *
Alexandre Julliard7ff1c411997-05-25 13:58:18 +000062 * Return the size of the bitmap info structure including color table.
Alexandre Julliard401710d1993-09-04 10:09:32 +000063 */
Huw D M Davies56166a61999-04-19 16:45:24 +000064int DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse )
Alexandre Julliard401710d1993-09-04 10:09:32 +000065{
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000066 int colors;
67
68 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
69 {
70 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
Alexandre Julliard23946ad1997-06-16 17:43:53 +000071 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000072 return sizeof(BITMAPCOREHEADER) + colors *
73 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
74 }
75 else /* assume BITMAPINFOHEADER */
76 {
77 colors = info->bmiHeader.biClrUsed;
Alexandre Julliard23946ad1997-06-16 17:43:53 +000078 if (!colors && (info->bmiHeader.biBitCount <= 8))
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000079 colors = 1 << info->bmiHeader.biBitCount;
80 return sizeof(BITMAPINFOHEADER) + colors *
81 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
82 }
Alexandre Julliard401710d1993-09-04 10:09:32 +000083}
84
85
86/***********************************************************************
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000087 * DIB_GetBitmapInfo
88 *
89 * Get the info from a bitmap header.
90 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
91 */
Huw D M Davies87f87bf1998-10-28 09:53:53 +000092int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
Alexandre Julliarda845b881998-06-01 10:44:35 +000093 int *height, WORD *bpp, WORD *compr )
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000094{
95 if (header->biSize == sizeof(BITMAPINFOHEADER))
96 {
97 *width = header->biWidth;
98 *height = header->biHeight;
99 *bpp = header->biBitCount;
Alexandre Julliarda845b881998-06-01 10:44:35 +0000100 *compr = header->biCompression;
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000101 return 1;
102 }
103 if (header->biSize == sizeof(BITMAPCOREHEADER))
104 {
105 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
106 *width = core->bcWidth;
107 *height = core->bcHeight;
108 *bpp = core->bcBitCount;
Alexandre Julliarda845b881998-06-01 10:44:35 +0000109 *compr = 0;
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000110 return 0;
111 }
Alexandre Julliard15657091999-05-23 10:25:25 +0000112 WARN("(%ld): wrong size for header\n", header->biSize );
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000113 return -1;
114}
115
116
117/***********************************************************************
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000118 * StretchDIBits16 (GDI.439)
Alexandre Julliard2787be81995-05-22 18:23:01 +0000119 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000120INT16 WINAPI StretchDIBits16(HDC16 hdc, INT16 xDst, INT16 yDst, INT16 widthDst,
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000121 INT16 heightDst, INT16 xSrc, INT16 ySrc, INT16 widthSrc,
122 INT16 heightSrc, const VOID *bits,
123 const BITMAPINFO *info, UINT16 wUsage, DWORD dwRop )
Alexandre Julliard2787be81995-05-22 18:23:01 +0000124{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000125 return (INT16)StretchDIBits( hdc, xDst, yDst, widthDst, heightDst,
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000126 xSrc, ySrc, widthSrc, heightSrc, bits,
127 info, wUsage, dwRop );
128}
129
130
131/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000132 * StretchDIBits (GDI32.@)
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000133 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000134INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
135 INT heightDst, INT xSrc, INT ySrc, INT widthSrc,
136 INT heightSrc, const void *bits,
137 const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000138{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000139 DC *dc = DC_GetDCUpdate( hdc );
Huw D M Davies14c99d01998-10-24 10:44:05 +0000140 if(!dc) return FALSE;
Alexandre Julliardded30381995-07-06 17:18:27 +0000141
Huw D M Davies14c99d01998-10-24 10:44:05 +0000142 if(dc->funcs->pStretchDIBits)
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000143 heightSrc = dc->funcs->pStretchDIBits(dc, xDst, yDst, widthDst,
Huw D M Davies14c99d01998-10-24 10:44:05 +0000144 heightDst, xSrc, ySrc, widthSrc,
145 heightSrc, bits, info, wUsage,
146 dwRop);
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000147 else { /* use StretchBlt */
Alexandre Julliard54e47751999-10-13 16:16:23 +0000148 HBITMAP hBitmap, hOldBitmap;
149 HDC hdcMem;
Matthew J. Francised744e71999-10-24 17:28:23 +0000150
Alexandre Julliard54e47751999-10-13 16:16:23 +0000151 hdcMem = CreateCompatibleDC( hdc );
Eric Pouech26501592000-09-10 03:13:41 +0000152 if (info->bmiHeader.biCompression == BI_RLE4 ||
153 info->bmiHeader.biCompression == BI_RLE8) {
154
155 /* when RLE compression is used, there may be some gaps (ie the DIB doesn't
156 * contain all the rectangle described in bmiHeader, but only part of it.
157 * This mean that those undescribed pixels must be left untouched.
158 * So, we first copy on a memory bitmap the current content of the
159 * destination rectangle, blit the DIB bits on top of it - hence leaving
160 * the gaps untouched -, and blitting the rectangle back.
161 * This insure that gaps are untouched on the destination rectangle
162 * Not doing so leads to trashed images (the gaps contain what was on the
163 * memory bitmap => generally black or garbage)
164 * Unfortunately, RLE DIBs without gaps will be slowed down. But this is
165 * another speed vs correctness issue. Anyway, if speed is needed, then the
166 * pStretchDIBits function shall be implemented.
167 * ericP (2000/09/09)
168 */
169 hBitmap = CreateCompatibleBitmap(hdc, info->bmiHeader.biWidth,
170 info->bmiHeader.biHeight);
171 hOldBitmap = SelectObject( hdcMem, hBitmap );
172
173 /* copy existing bitmap from destination dc */
174 StretchBlt( hdcMem, xSrc, abs(info->bmiHeader.biHeight) - heightSrc - ySrc,
175 widthSrc, heightSrc, hdc, xDst, yDst, widthDst, heightDst,
176 dwRop );
177 SetDIBits(hdcMem, hBitmap, 0, info->bmiHeader.biHeight, bits,
178 info, DIB_RGB_COLORS);
179
180 } else {
181 hBitmap = CreateDIBitmap( hdc, &info->bmiHeader, CBM_INIT,
182 bits, info, wUsage );
183 hOldBitmap = SelectObject( hdcMem, hBitmap );
184 }
185
Matthew J. Francised744e71999-10-24 17:28:23 +0000186 /* Origin for DIBitmap may be bottom left (positive biHeight) or top
187 left (negative biHeight) */
Alexandre Julliard54e47751999-10-13 16:16:23 +0000188 StretchBlt( hdc, xDst, yDst, widthDst, heightDst,
Eric Pouech26501592000-09-10 03:13:41 +0000189 hdcMem, xSrc, abs(info->bmiHeader.biHeight) - heightSrc - ySrc,
190 widthSrc, heightSrc, dwRop );
Alexandre Julliard54e47751999-10-13 16:16:23 +0000191 SelectObject( hdcMem, hOldBitmap );
192 DeleteDC( hdcMem );
193 DeleteObject( hBitmap );
Huw D M Davies14c99d01998-10-24 10:44:05 +0000194 }
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000195 GDI_ReleaseObj( hdc );
196 return heightSrc;
Alexandre Julliard2787be81995-05-22 18:23:01 +0000197}
198
Alexandre Julliard54e47751999-10-13 16:16:23 +0000199
Alexandre Julliard2787be81995-05-22 18:23:01 +0000200/***********************************************************************
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000201 * SetDIBits16 (GDI.440)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000202 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000203INT16 WINAPI SetDIBits16( HDC16 hdc, HBITMAP16 hbitmap, UINT16 startscan,
204 UINT16 lines, LPCVOID bits, const BITMAPINFO *info,
205 UINT16 coloruse )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000206{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000207 return SetDIBits( hdc, hbitmap, startscan, lines, bits, info, coloruse );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000208}
209
210
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000211/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000212 * SetDIBits [GDI32.@] Sets pixels in a bitmap using colors from DIB
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000213 *
214 * PARAMS
215 * hdc [I] Handle to device context
216 * hbitmap [I] Handle to bitmap
217 * startscan [I] Starting scan line
218 * lines [I] Number of scan lines
219 * bits [I] Array of bitmap bits
220 * info [I] Address of structure with data
221 * coloruse [I] Type of color indexes to use
222 *
223 * RETURNS
224 * Success: Number of scan lines copied
225 * Failure: 0
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000226 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000227INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000228 UINT lines, LPCVOID bits, const BITMAPINFO *info,
229 UINT coloruse )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000230{
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000231 DC *dc;
232 BITMAPOBJ *bitmap;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000233 INT result;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000234
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000235 /* Check parameters */
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000236 if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000237
238 if (!(bitmap = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000239 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000240 GDI_ReleaseObj( hdc );
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000241 return 0;
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000242 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000243
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000244 result = BITMAP_Driver->pSetDIBits(bitmap, dc, startscan,
245 lines, bits, info,
246 coloruse, hbitmap);
Alexandre Julliarda845b881998-06-01 10:44:35 +0000247
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000248 GDI_ReleaseObj( hbitmap );
249 GDI_ReleaseObj( hdc );
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000250
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000251 return result;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000252}
Alexandre Julliard401710d1993-09-04 10:09:32 +0000253
Alexandre Julliard401710d1993-09-04 10:09:32 +0000254
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000255/***********************************************************************
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000256 * SetDIBitsToDevice16 (GDI.443)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000257 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000258INT16 WINAPI SetDIBitsToDevice16(HDC16 hdc, INT16 xDest, INT16 yDest, INT16 cx,
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000259 INT16 cy, INT16 xSrc, INT16 ySrc, UINT16 startscan,
260 UINT16 lines, LPCVOID bits, const BITMAPINFO *info,
261 UINT16 coloruse )
262{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000263 return SetDIBitsToDevice( hdc, xDest, yDest, cx, cy, xSrc, ySrc,
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000264 startscan, lines, bits, info, coloruse );
265}
266
267
268/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000269 * SetDIBitsToDevice (GDI32.@)
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000270 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000271INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
272 DWORD cy, INT xSrc, INT ySrc, UINT startscan,
273 UINT lines, LPCVOID bits, const BITMAPINFO *info,
274 UINT coloruse )
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000275{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000276 INT ret;
Huw D M Davies91d16081998-11-06 11:03:00 +0000277 DC *dc;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000278
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000279 if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000280
Huw D M Davies91d16081998-11-06 11:03:00 +0000281 if(dc->funcs->pSetDIBitsToDevice)
282 ret = dc->funcs->pSetDIBitsToDevice( dc, xDest, yDest, cx, cy, xSrc,
283 ySrc, startscan, lines, bits,
284 info, coloruse );
285 else {
Alexandre Julliard15657091999-05-23 10:25:25 +0000286 FIXME("unimplemented on hdc %08x\n", hdc);
Huw D M Davies91d16081998-11-06 11:03:00 +0000287 ret = 0;
Alexandre Julliarda845b881998-06-01 10:44:35 +0000288 }
Alexandre Julliard642d3131998-07-12 19:29:36 +0000289
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000290 GDI_ReleaseObj( hdc );
Huw D M Davies91d16081998-11-06 11:03:00 +0000291 return ret;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000292}
293
Alexandre Julliarde658d821997-11-30 17:45:40 +0000294/***********************************************************************
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000295 * SetDIBColorTable16 (GDI.602)
296 */
297UINT16 WINAPI SetDIBColorTable16( HDC16 hdc, UINT16 startpos, UINT16 entries,
298 RGBQUAD *colors )
299{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000300 return SetDIBColorTable( hdc, startpos, entries, colors );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000301}
302
303/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000304 * SetDIBColorTable (GDI32.@)
Alexandre Julliarde658d821997-11-30 17:45:40 +0000305 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000306UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries,
Alexandre Julliarde658d821997-11-30 17:45:40 +0000307 RGBQUAD *colors )
308{
309 DC * dc;
Ove Kaavena32ddc02000-11-25 21:42:00 +0000310 BITMAPOBJ * bmp;
311 UINT result;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000312
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000313 if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
Alexandre Julliarde658d821997-11-30 17:45:40 +0000314
Ove Kaavena32ddc02000-11-25 21:42:00 +0000315 if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC )))
Alexandre Julliarde658d821997-11-30 17:45:40 +0000316 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000317 GDI_ReleaseObj( hdc );
Alexandre Julliarde658d821997-11-30 17:45:40 +0000318 return 0;
319 }
320
Ove Kaavena32ddc02000-11-25 21:42:00 +0000321 result = BITMAP_Driver->pSetDIBColorTable(bmp, dc, startpos, entries, colors);
Gerard Patel9dd16f01999-08-15 16:38:07 +0000322
Ove Kaavena32ddc02000-11-25 21:42:00 +0000323 GDI_ReleaseObj( dc->hBitmap );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000324 GDI_ReleaseObj( hdc );
Ove Kaavena32ddc02000-11-25 21:42:00 +0000325 return result;
Alexandre Julliarde658d821997-11-30 17:45:40 +0000326}
327
328/***********************************************************************
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000329 * GetDIBColorTable16 (GDI.603)
330 */
331UINT16 WINAPI GetDIBColorTable16( HDC16 hdc, UINT16 startpos, UINT16 entries,
332 RGBQUAD *colors )
333{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000334 return GetDIBColorTable( hdc, startpos, entries, colors );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000335}
336
337/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000338 * GetDIBColorTable (GDI32.@)
Alexandre Julliarde658d821997-11-30 17:45:40 +0000339 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000340UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries,
Alexandre Julliarde658d821997-11-30 17:45:40 +0000341 RGBQUAD *colors )
342{
343 DC * dc;
Ove Kaavena32ddc02000-11-25 21:42:00 +0000344 BITMAPOBJ * bmp;
345 UINT result;
Alexandre Julliarde658d821997-11-30 17:45:40 +0000346
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000347 if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
Alexandre Julliarde658d821997-11-30 17:45:40 +0000348
Ove Kaavena32ddc02000-11-25 21:42:00 +0000349 if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC )))
Alexandre Julliarde658d821997-11-30 17:45:40 +0000350 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000351 GDI_ReleaseObj( hdc );
Alexandre Julliarde658d821997-11-30 17:45:40 +0000352 return 0;
353 }
354
Ove Kaavena32ddc02000-11-25 21:42:00 +0000355 result = BITMAP_Driver->pGetDIBColorTable(bmp, dc, startpos, entries, colors);
356
357 GDI_ReleaseObj( dc->hBitmap );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000358 GDI_ReleaseObj( hdc );
Ove Kaavena32ddc02000-11-25 21:42:00 +0000359 return result;
Alexandre Julliarde658d821997-11-30 17:45:40 +0000360}
Alexandre Julliard2787be81995-05-22 18:23:01 +0000361
Huw D M Daviescc3e5d71999-03-25 10:48:01 +0000362/* FIXME the following two structs should be combined with __sysPalTemplate in
363 objects/color.c - this should happen after de-X11-ing both of these
364 files.
365 NB. RGBQUAD and PALETTENTRY have different orderings of red, green
366 and blue - sigh */
367
368static RGBQUAD EGAColors[16] = {
369/* rgbBlue, rgbGreen, rgbRed, rgbReserverd */
370 { 0x00, 0x00, 0x00, 0x00 },
371 { 0x00, 0x00, 0x80, 0x00 },
372 { 0x00, 0x80, 0x00, 0x00 },
373 { 0x00, 0x80, 0x80, 0x00 },
374 { 0x80, 0x00, 0x00, 0x00 },
375 { 0x80, 0x00, 0x80, 0x00 },
376 { 0x80, 0x80, 0x00, 0x00 },
377 { 0x80, 0x80, 0x80, 0x00 },
378 { 0xc0, 0xc0, 0xc0, 0x00 },
379 { 0x00, 0x00, 0xff, 0x00 },
380 { 0x00, 0xff, 0x00, 0x00 },
381 { 0x00, 0xff, 0xff, 0x00 },
382 { 0xff, 0x00, 0x00, 0x00 },
383 { 0xff, 0x00, 0xff, 0x00 },
384 { 0xff, 0xff, 0x00, 0x00 },
385 { 0xff, 0xff, 0xff, 0x00 }
386};
387
388
389static RGBQUAD DefLogPalette[20] = { /* Copy of Default Logical Palette */
390/* rgbBlue, rgbGreen, rgbRed, rgbReserverd */
391 { 0x00, 0x00, 0x00, 0x00 },
392 { 0x00, 0x00, 0x80, 0x00 },
393 { 0x00, 0x80, 0x00, 0x00 },
394 { 0x00, 0x80, 0x80, 0x00 },
395 { 0x80, 0x00, 0x00, 0x00 },
396 { 0x80, 0x00, 0x80, 0x00 },
397 { 0x80, 0x80, 0x00, 0x00 },
398 { 0xc0, 0xc0, 0xc0, 0x00 },
399 { 0xc0, 0xdc, 0xc0, 0x00 },
400 { 0xf0, 0xca, 0xa6, 0x00 },
401 { 0xf0, 0xfb, 0xff, 0x00 },
402 { 0xa4, 0xa0, 0xa0, 0x00 },
403 { 0x80, 0x80, 0x80, 0x00 },
404 { 0x00, 0x00, 0xf0, 0x00 },
405 { 0x00, 0xff, 0x00, 0x00 },
406 { 0x00, 0xff, 0xff, 0x00 },
407 { 0xff, 0x00, 0x00, 0x00 },
408 { 0xff, 0x00, 0xff, 0x00 },
409 { 0xff, 0xff, 0x00, 0x00 },
410 { 0xff, 0xff, 0xff, 0x00 }
411};
412
Alexandre Julliard401710d1993-09-04 10:09:32 +0000413/***********************************************************************
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000414 * GetDIBits16 (GDI.441)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000415 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000416INT16 WINAPI GetDIBits16( HDC16 hdc, HBITMAP16 hbitmap, UINT16 startscan,
Zygo Blaxell1084b2c1999-02-09 14:13:12 +0000417 UINT16 lines, LPVOID bits, BITMAPINFO * info,
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000418 UINT16 coloruse )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000419{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000420 return GetDIBits( hdc, hbitmap, startscan, lines, bits, info, coloruse );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000421}
422
423
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000424/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000425 * GetDIBits [GDI32.@] Retrieves bits of bitmap and copies to buffer
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000426 *
427 * RETURNS
428 * Success: Number of scan lines copied from bitmap
429 * Failure: 0
Alexandre Julliard7ff1c411997-05-25 13:58:18 +0000430 *
431 * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/func/src/f30_14.htm
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000432 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000433INT WINAPI GetDIBits(
434 HDC hdc, /* [in] Handle to device context */
435 HBITMAP hbitmap, /* [in] Handle to bitmap */
436 UINT startscan, /* [in] First scan line to set in dest bitmap */
437 UINT lines, /* [in] Number of scan lines to copy */
Zygo Blaxell1084b2c1999-02-09 14:13:12 +0000438 LPVOID bits, /* [out] Address of array for bitmap bits */
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000439 BITMAPINFO * info, /* [out] Address of structure with bitmap data */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000440 UINT coloruse) /* [in] RGB or palette index */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000441{
442 DC * dc;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000443 BITMAPOBJ * bmp;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000444 PALETTEENTRY * palEntry;
445 PALETTEOBJ * palette;
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000446 int i;
Alexandre Julliarda845b881998-06-01 10:44:35 +0000447
Huw D M Daviescc3e5d71999-03-25 10:48:01 +0000448 if (!info) return 0;
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000449 if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000450 if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000451 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000452 GDI_ReleaseObj( hdc );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000453 return 0;
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000454 }
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000455 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC )))
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000456 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000457 GDI_ReleaseObj( hdc );
458 GDI_ReleaseObj( hbitmap );
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000459 return 0;
460 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000461
Huw D M Daviescc3e5d71999-03-25 10:48:01 +0000462 /* Transfer color info */
463
464 if (info->bmiHeader.biBitCount <= 8 && info->bmiHeader.biBitCount > 0 ) {
465
Eric Kohlc0112671998-11-15 18:10:11 +0000466 info->bmiHeader.biClrUsed = 0;
Huw D M Daviescc3e5d71999-03-25 10:48:01 +0000467
468 if(info->bmiHeader.biBitCount >= bmp->bitmap.bmBitsPixel) {
469 palEntry = palette->logpalette.palPalEntry;
470 for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++, palEntry++) {
471 if (coloruse == DIB_RGB_COLORS) {
472 info->bmiColors[i].rgbRed = palEntry->peRed;
473 info->bmiColors[i].rgbGreen = palEntry->peGreen;
474 info->bmiColors[i].rgbBlue = palEntry->peBlue;
475 info->bmiColors[i].rgbReserved = 0;
476 }
477 else ((WORD *)info->bmiColors)[i] = (WORD)i;
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000478 }
Huw D M Daviescc3e5d71999-03-25 10:48:01 +0000479 } else {
480 switch (info->bmiHeader.biBitCount) {
481 case 1:
482 info->bmiColors[0].rgbRed = info->bmiColors[0].rgbGreen =
483 info->bmiColors[0].rgbBlue = 0;
484 info->bmiColors[0].rgbReserved = 0;
485 info->bmiColors[1].rgbRed = info->bmiColors[1].rgbGreen =
486 info->bmiColors[1].rgbBlue = 0xff;
487 info->bmiColors[1].rgbReserved = 0;
488 break;
489
490 case 4:
491 memcpy(info->bmiColors, EGAColors, sizeof(EGAColors));
492 break;
493
494 case 8:
495 {
496 INT r, g, b;
497 RGBQUAD *color;
498
499 memcpy(info->bmiColors, DefLogPalette,
500 10 * sizeof(RGBQUAD));
501 memcpy(info->bmiColors + 246, DefLogPalette + 10,
502 10 * sizeof(RGBQUAD));
503 color = info->bmiColors + 10;
504 for(r = 0; r <= 5; r++) /* FIXME */
505 for(g = 0; g <= 5; g++)
506 for(b = 0; b <= 5; b++) {
507 color->rgbRed = (r * 0xff) / 5;
508 color->rgbGreen = (g * 0xff) / 5;
509 color->rgbBlue = (b * 0xff) / 5;
510 color->rgbReserved = 0;
511 color++;
512 }
513 }
514 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000515 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000516 }
Alexandre Julliarda845b881998-06-01 10:44:35 +0000517
Alexandre Julliard2239abb2000-11-05 02:05:07 +0000518 GDI_ReleaseObj( dc->hPalette );
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000519
Kai Morich9e9fc1b1999-09-13 15:13:24 +0000520 if (bits && lines)
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000521 {
Karl Lessard41875791999-09-03 16:49:17 +0000522 /* If the bitmap object already have a dib section that contains image data, get the bits from it*/
Karl Lessarddee464c1999-09-14 11:51:01 +0000523 if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && info->bmiHeader.biBitCount >= 15)
Karl Lessard41875791999-09-03 16:49:17 +0000524 {
525 /*FIXME: Only RGB dibs supported for now */
Joerg Mayer4d756402001-01-10 22:45:33 +0000526 unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb = bmp->dib->dsBm.bmWidthBytes;
Karl Lessard41875791999-09-03 16:49:17 +0000527 int dstwidthb = DIB_GetDIBWidthBytes( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
Patrik Stridvall0ee98cc2000-02-26 13:17:55 +0000528 LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
Joerg Mayer4d756402001-01-10 22:45:33 +0000529 unsigned int x, y;
Karl Lessard41875791999-09-03 16:49:17 +0000530
531 if ((info->bmiHeader.biHeight < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
532 {
Huw D M Davies1bb98601999-09-19 12:04:17 +0000533 dbits = (LPBYTE)bits + (dstwidthb * (lines-1));
Karl Lessard41875791999-09-03 16:49:17 +0000534 dstwidthb = -dstwidthb;
535 }
536
537 switch( info->bmiHeader.biBitCount ) {
538
Karl Lessarddee464c1999-09-14 11:51:01 +0000539 case 15:
Karl Lessard41875791999-09-03 16:49:17 +0000540 case 16: /* 16 bpp dstDIB */
541 {
542 LPWORD dstbits = (LPWORD)dbits;
543 WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
544
545 /* FIXME: BI_BITFIELDS not supported yet */
546
547 switch(bmp->dib->dsBm.bmBitsPixel) {
548
549 case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
550 {
551 /* FIXME: BI_BITFIELDS not supported yet */
552 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
553 memcpy(dbits, sbits, srcwidthb);
554 }
555 break;
556
557 case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
558 {
Huw D M Davies1bb98601999-09-19 12:04:17 +0000559 LPBYTE srcbits = sbits;
Karl Lessard41875791999-09-03 16:49:17 +0000560
561 for( y = 0; y < lines; y++) {
562 for( x = 0; x < srcwidth; x++ )
563 *dstbits++ = ((*srcbits++ >> 3) & bmask) |
564 (((WORD)*srcbits++ << 2) & gmask) |
565 (((WORD)*srcbits++ << 7) & rmask);
566 dstbits = (LPWORD)(dbits+=dstwidthb);
Huw D M Davies1bb98601999-09-19 12:04:17 +0000567 srcbits = (sbits += srcwidthb);
Karl Lessard41875791999-09-03 16:49:17 +0000568 }
569 }
570 break;
571
572 case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
573 {
574 LPDWORD srcbits = (LPDWORD)sbits;
575 DWORD val;
576
577 for( y = 0; y < lines; y++) {
578 for( x = 0; x < srcwidth; x++ ) {
579 val = *srcbits++;
Karl Lessardc73a1fd1999-09-19 14:15:41 +0000580 *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
581 ((val >> 9) & rmask));
Karl Lessard41875791999-09-03 16:49:17 +0000582 }
Huw D M Davies1bb98601999-09-19 12:04:17 +0000583 dstbits = (LPWORD)(dbits+=dstwidthb);
584 srcbits = (LPDWORD)(sbits+=srcwidthb);
Karl Lessard41875791999-09-03 16:49:17 +0000585 }
586 }
587 break;
588
589 default: /* ? bit bmp -> 16 bit DIB */
590 FIXME("15/16 bit DIB %d bit bitmap\n",
591 bmp->bitmap.bmBitsPixel);
592 break;
593 }
594 }
595 break;
596
597 case 24: /* 24 bpp dstDIB */
598 {
Huw D M Davies1bb98601999-09-19 12:04:17 +0000599 LPBYTE dstbits = dbits;
Karl Lessard41875791999-09-03 16:49:17 +0000600
601 switch(bmp->dib->dsBm.bmBitsPixel) {
602
603 case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
604 {
605 LPWORD srcbits = (LPWORD)sbits;
606 WORD val;
607
608 /* FIXME: BI_BITFIELDS not supported yet */
609 for( y = 0; y < lines; y++) {
610 for( x = 0; x < srcwidth; x++ ) {
611 val = *srcbits++;
Karl Lessard41875791999-09-03 16:49:17 +0000612 *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
Karl Lessardc73a1fd1999-09-19 14:15:41 +0000613 *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
614 *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
Karl Lessard41875791999-09-03 16:49:17 +0000615 }
Huw D M Davies1bb98601999-09-19 12:04:17 +0000616 dstbits = (LPBYTE)(dbits+=dstwidthb);
Karl Lessard41875791999-09-03 16:49:17 +0000617 srcbits = (LPWORD)(sbits+=srcwidthb);
618 }
619 }
620 break;
621
622 case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
623 {
624 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
625 memcpy(dbits, sbits, srcwidthb);
626 }
627 break;
628
629 case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
630 {
631 LPBYTE srcbits = (LPBYTE)sbits;
632
633 for( y = 0; y < lines; y++) {
634 for( x = 0; x < srcwidth; x++, srcbits++ ) {
635 *dstbits++ = *srcbits++;
636 *dstbits++ = *srcbits++;
637 *dstbits++ = *srcbits++;
638 }
639 dstbits=(LPBYTE)(dbits+=dstwidthb);
640 srcbits = (LPBYTE)(sbits+=srcwidthb);
641 }
642 }
643 break;
644
645 default: /* ? bit bmp -> 24 bit DIB */
646 FIXME("24 bit DIB %d bit bitmap\n",
647 bmp->bitmap.bmBitsPixel);
648 break;
649 }
650 }
651 break;
652
653 case 32: /* 32 bpp dstDIB */
654 {
655 LPDWORD dstbits = (LPDWORD)dbits;
Karl Lessard41875791999-09-03 16:49:17 +0000656
657 /* FIXME: BI_BITFIELDS not supported yet */
658
659 switch(bmp->dib->dsBm.bmBitsPixel) {
660 case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
661 {
662 LPWORD srcbits = (LPWORD)sbits;
663 DWORD val;
664
665 /* FIXME: BI_BITFIELDS not supported yet */
666 for( y = 0; y < lines; y++) {
667 for( x = 0; x < srcwidth; x++ ) {
668 val = (DWORD)*srcbits++;
Karl Lessardc73a1fd1999-09-19 14:15:41 +0000669 *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
Karl Lessard41875791999-09-03 16:49:17 +0000670 ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
Karl Lessardc73a1fd1999-09-19 14:15:41 +0000671 ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
Karl Lessard41875791999-09-03 16:49:17 +0000672 }
Huw D M Davies1bb98601999-09-19 12:04:17 +0000673 dstbits=(LPDWORD)(dbits+=dstwidthb);
674 srcbits=(LPWORD)(sbits+=srcwidthb);
Karl Lessard41875791999-09-03 16:49:17 +0000675 }
676 }
677 break;
678
679 case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
680 {
Huw D M Davies1bb98601999-09-19 12:04:17 +0000681 LPBYTE srcbits = sbits;
Karl Lessard41875791999-09-03 16:49:17 +0000682
683 for( y = 0; y < lines; y++) {
Karl Lessardc73a1fd1999-09-19 14:15:41 +0000684 for( x = 0; x < srcwidth; x++, srcbits+=3 )
685 *dstbits++ = ((DWORD)*srcbits) & 0x00ffffff;
Huw D M Davies1bb98601999-09-19 12:04:17 +0000686 dstbits=(LPDWORD)(dbits+=dstwidthb);
Karl Lessard41875791999-09-03 16:49:17 +0000687 srcbits=(sbits+=srcwidthb);
688 }
689 }
690 break;
691
692 case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
693 {
694 /* FIXME: BI_BITFIELDS not supported yet */
695 for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
696 memcpy(dbits, sbits, srcwidthb);
697 }
698 break;
699
700 default: /* ? bit bmp -> 16 bit DIB */
701 FIXME("15/16 bit DIB %d bit bitmap\n",
702 bmp->bitmap.bmBitsPixel);
703 break;
704 }
705 }
706 break;
707
708 default: /* ? bit DIB */
709 FIXME("Unsupported DIB depth %d\n", info->bmiHeader.biBitCount);
710 break;
711 }
712 }
713 /* Otherwise, get bits from the XImage */
714 else if(!BITMAP_Driver->pGetDIBits(bmp, dc, startscan, lines, bits, info, coloruse, hbitmap))
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000715 {
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000716 GDI_ReleaseObj( hdc );
717 GDI_ReleaseObj( hbitmap );
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000718
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000719 return 0;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000720 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000721 }
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000722 else if( info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
723 {
724 /* fill in struct members */
Huw D M Daviescc3e5d71999-03-25 10:48:01 +0000725
726 if( info->bmiHeader.biBitCount == 0)
727 {
728 info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
729 info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
730 info->bmiHeader.biPlanes = 1;
731 info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
Huw D M Davies608629b1999-04-18 12:07:00 +0000732 info->bmiHeader.biSizeImage =
733 DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
734 bmp->bitmap.bmHeight,
735 bmp->bitmap.bmBitsPixel );
Huw D M Daviescc3e5d71999-03-25 10:48:01 +0000736 info->bmiHeader.biCompression = 0;
737 }
738 else
739 {
Huw D M Davies608629b1999-04-18 12:07:00 +0000740 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
741 info->bmiHeader.biWidth,
742 info->bmiHeader.biHeight,
743 info->bmiHeader.biBitCount );
Huw D M Daviescc3e5d71999-03-25 10:48:01 +0000744 }
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000745 }
Huw D M Daviescc3e5d71999-03-25 10:48:01 +0000746
Alexandre Julliard15657091999-05-23 10:25:25 +0000747 TRACE("biSizeImage = %ld, biWidth = %ld, biHeight = %ld\n",
Huw D M Davies3da9ff31999-02-24 09:47:37 +0000748 info->bmiHeader.biSizeImage, info->bmiHeader.biWidth,
749 info->bmiHeader.biHeight);
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000750
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000751 GDI_ReleaseObj( hdc );
752 GDI_ReleaseObj( hbitmap );
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000753
Alexandre Julliard401710d1993-09-04 10:09:32 +0000754 return lines;
755}
756
757
758/***********************************************************************
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000759 * CreateDIBitmap16 (GDI.442)
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000760 * CreateDIBitmap16 (DISPLAY.442)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000761 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000762HBITMAP16 WINAPI CreateDIBitmap16( HDC16 hdc, const BITMAPINFOHEADER * header,
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000763 DWORD init, LPCVOID bits, const BITMAPINFO * data,
764 UINT16 coloruse )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000765{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000766 return CreateDIBitmap( hdc, header, init, bits, data, coloruse );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000767}
768
769
770/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000771 * CreateDIBitmap (GDI32.@)
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000772 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000773HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000774 DWORD init, LPCVOID bits, const BITMAPINFO *data,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000775 UINT coloruse )
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +0000776{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000777 HBITMAP handle;
778 BOOL fColor;
Alexandre Julliarde658d821997-11-30 17:45:40 +0000779 DWORD width;
780 int height;
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000781 WORD bpp;
Alexandre Julliarda845b881998-06-01 10:44:35 +0000782 WORD compr;
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000783
Alexandre Julliarda845b881998-06-01 10:44:35 +0000784 if (DIB_GetBitmapInfo( header, &width, &height, &bpp, &compr ) == -1) return 0;
Alexandre Julliarde658d821997-11-30 17:45:40 +0000785 if (height < 0) height = -height;
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000786
787 /* Check if we should create a monochrome or color bitmap. */
788 /* We create a monochrome bitmap only if it has exactly 2 */
Francois Boisvert3d696d91999-09-23 11:40:38 +0000789 /* colors, which are black followed by white, nothing else. */
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000790 /* In all other cases, we create a color bitmap. */
791
792 if (bpp != 1) fColor = TRUE;
793 else if ((coloruse != DIB_RGB_COLORS) ||
794 (init != CBM_INIT) || !data) fColor = FALSE;
795 else
796 {
797 if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
798 {
799 RGBQUAD *rgb = data->bmiColors;
800 DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
Francois Boisvert3d696d91999-09-23 11:40:38 +0000801
802 /* Check if the first color of the colormap is black */
803 if ((col == RGB(0,0,0)))
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000804 {
805 rgb++;
806 col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
Francois Boisvert3d696d91999-09-23 11:40:38 +0000807 /* If the second color is white, create a monochrome bitmap */
808 fColor = (col != RGB(0xff,0xff,0xff));
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000809 }
Francois Boisvert3d696d91999-09-23 11:40:38 +0000810 /* Note : If the first color of the colormap is white
811 followed by black, we have to create a color bitmap.
812 If we don't the white will be displayed in black later on!*/
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000813 else fColor = TRUE;
814 }
815 else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
816 {
817 RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
818 DWORD col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
Francois Boisvert3d696d91999-09-23 11:40:38 +0000819 if ((col == RGB(0,0,0)))
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000820 {
821 rgb++;
822 col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
Francois Boisvert3d696d91999-09-23 11:40:38 +0000823 fColor = (col != RGB(0xff,0xff,0xff));
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000824 }
825 else fColor = TRUE;
826 }
827 else
828 {
Alexandre Julliard15657091999-05-23 10:25:25 +0000829 WARN("(%ld): wrong size for data\n",
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000830 data->bmiHeader.biSize );
831 return 0;
832 }
833 }
834
835 /* Now create the bitmap */
836
Alexandre Julliard946a4442000-07-30 13:50:27 +0000837 if (fColor)
838 {
839 HDC tmpdc = CreateDCA( "DISPLAY", NULL, NULL, NULL );
840 handle = CreateCompatibleBitmap( tmpdc, width, height );
841 DeleteDC( tmpdc );
842 }
843 else handle = CreateBitmap( width, height, 1, 1, NULL );
844
Alexandre Julliard401710d1993-09-04 10:09:32 +0000845 if (!handle) return 0;
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000846
847 if (init == CBM_INIT)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000848 SetDIBits( hdc, handle, 0, height, bits, data, coloruse );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000849 return handle;
850}
Alexandre Julliard77b99181997-09-14 17:17:23 +0000851
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +0000852/***********************************************************************
853 * CreateDIBSection16 (GDI.489)
854 */
855HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, BITMAPINFO *bmi, UINT16 usage,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000856 SEGPTR *bits, HANDLE section,
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +0000857 DWORD offset)
858{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000859 HBITMAP16 hbitmap = 0;
Stephane Lussier23259ce2000-07-11 22:04:44 +0000860 DC *dc;
861 BOOL bDesktopDC = FALSE;
862
863 /* If the reference hdc is null, take the desktop dc */
864 if (hdc == 0)
865 {
866 hdc = CreateCompatibleDC(0);
867 bDesktopDC = TRUE;
868 }
869
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000870 if ((dc = DC_GetDCPtr( hdc )))
871 {
872 hbitmap = dc->funcs->pCreateDIBSection16(dc, bmi, usage, bits, section, offset, 0);
873 GDI_ReleaseObj(hdc);
874 }
Ove Kaaven8b9f3382000-04-29 16:47:07 +0000875
Stephane Lussier23259ce2000-07-11 22:04:44 +0000876 if (bDesktopDC)
877 DeleteDC(hdc);
878
Ove Kaaven8b9f3382000-04-29 16:47:07 +0000879 return hbitmap;
880}
881
882/***********************************************************************
883 * DIB_CreateDIBSection
884 */
885HBITMAP DIB_CreateDIBSection(HDC hdc, BITMAPINFO *bmi, UINT usage,
886 LPVOID *bits, HANDLE section,
887 DWORD offset, DWORD ovr_pitch)
888{
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000889 HBITMAP hbitmap = 0;
Stephane Lussier23259ce2000-07-11 22:04:44 +0000890 DC *dc;
891 BOOL bDesktopDC = FALSE;
892
893 /* If the reference hdc is null, take the desktop dc */
894 if (hdc == 0)
895 {
896 hdc = CreateCompatibleDC(0);
897 bDesktopDC = TRUE;
898 }
899
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000900 if ((dc = DC_GetDCPtr( hdc )))
901 {
902 hbitmap = dc->funcs->pCreateDIBSection(dc, bmi, usage, bits, section, offset, ovr_pitch);
903 GDI_ReleaseObj(hdc);
904 }
Ulrich Weigand4f85bad1999-02-09 15:30:22 +0000905
Stephane Lussier23259ce2000-07-11 22:04:44 +0000906 if (bDesktopDC)
907 DeleteDC(hdc);
908
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000909 return hbitmap;
Alexandre Julliard77b99181997-09-14 17:17:23 +0000910}
911
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +0000912/***********************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000913 * CreateDIBSection (GDI32.@)
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +0000914 */
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000915HBITMAP WINAPI CreateDIBSection(HDC hdc, BITMAPINFO *bmi, UINT usage,
916 LPVOID *bits, HANDLE section,
917 DWORD offset)
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +0000918{
Ove Kaaven8b9f3382000-04-29 16:47:07 +0000919 return DIB_CreateDIBSection(hdc, bmi, usage, bits, section, offset, 0);
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +0000920}
Alexandre Julliarda845b881998-06-01 10:44:35 +0000921
Alexandre Julliard642d3131998-07-12 19:29:36 +0000922/***********************************************************************
923 * DIB_DeleteDIBSection
924 */
925void DIB_DeleteDIBSection( BITMAPOBJ *bmp )
926{
927 if (bmp && bmp->dib)
928 {
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000929 DIBSECTION *dib = bmp->dib;
Alexandre Julliard642d3131998-07-12 19:29:36 +0000930
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000931 if (dib->dsBm.bmBits)
Jesper Skov5c3e4571998-11-01 19:27:22 +0000932 {
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000933 if (dib->dshSection)
James Abbatielloc559f3f2001-02-12 19:40:28 +0000934 {
935 SYSTEM_INFO SystemInfo;
936 GetSystemInfo( &SystemInfo );
937 UnmapViewOfFile( (char *)dib->dsBm.bmBits -
938 (dib->dsOffset % SystemInfo.dwAllocationGranularity) );
939 }
Ove Kaaven8b9f3382000-04-29 16:47:07 +0000940 else if (!dib->dsOffset)
Marcus Meissner718b0e42000-01-23 02:18:52 +0000941 VirtualFree(dib->dsBm.bmBits, 0L, MEM_RELEASE );
Jesper Skov5c3e4571998-11-01 19:27:22 +0000942 }
Alexandre Julliard642d3131998-07-12 19:29:36 +0000943
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000944 BITMAP_Driver->pDeleteDIBSection(bmp);
Ulrich Weigand4f85bad1999-02-09 15:30:22 +0000945
Alexandre Julliard642d3131998-07-12 19:29:36 +0000946 HeapFree(GetProcessHeap(), 0, dib);
947 bmp->dib = NULL;
948 }
949}
950
Turchanov Sergey9cd4df11998-10-18 13:39:41 +0000951/***********************************************************************
Noel Borthwickd05b7be1999-09-20 15:42:47 +0000952 * DIB_CreateDIBFromBitmap
953 * Allocates a packed DIB and copies the bitmap data into it.
954 */
955HGLOBAL DIB_CreateDIBFromBitmap(HDC hdc, HBITMAP hBmp)
956{
957 BITMAPOBJ *pBmp = NULL;
958 HGLOBAL hPackedDIB = 0;
959 LPBYTE pPackedDIB = NULL;
960 LPBITMAPINFOHEADER pbmiHeader = NULL;
961 unsigned int width, height, depth, cDataSize = 0, cPackedSize = 0,
962 OffsetBits = 0, nLinesCopied = 0;
963
964 /* Get a pointer to the BITMAPOBJ structure */
965 pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
Alexandre Julliard2a2321b2000-08-19 21:38:55 +0000966 if (!pBmp) return hPackedDIB;
Noel Borthwickd05b7be1999-09-20 15:42:47 +0000967
968 /* Get the bitmap dimensions */
969 width = pBmp->bitmap.bmWidth;
970 height = pBmp->bitmap.bmHeight;
971 depth = pBmp->bitmap.bmBitsPixel;
972
973 /*
974 * A packed DIB contains a BITMAPINFO structure followed immediately by
975 * an optional color palette and the pixel data.
976 */
977
978 /* Calculate the size of the packed DIB */
979 cDataSize = DIB_GetDIBImageBytes( width, height, depth );
980 cPackedSize = sizeof(BITMAPINFOHEADER)
981 + ( (depth <= 8) ? (sizeof(RGBQUAD) * (1 << depth)) : 0 )
982 + cDataSize;
983 /* Get the offset to the bits */
984 OffsetBits = cPackedSize - cDataSize;
985
986 /* Allocate the packed DIB */
987 TRACE("\tAllocating packed DIB of size %d\n", cPackedSize);
988 hPackedDIB = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE /*| GMEM_ZEROINIT*/,
989 cPackedSize );
990 if ( !hPackedDIB )
991 {
992 WARN("Could not allocate packed DIB!\n");
993 goto END;
994 }
995
996 /* A packed DIB starts with a BITMAPINFOHEADER */
997 pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
998 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
999
1000 /* Init the BITMAPINFOHEADER */
1001 pbmiHeader->biSize = sizeof(BITMAPINFOHEADER);
1002 pbmiHeader->biWidth = width;
1003 pbmiHeader->biHeight = height;
1004 pbmiHeader->biPlanes = 1;
1005 pbmiHeader->biBitCount = depth;
1006 pbmiHeader->biCompression = BI_RGB;
1007 pbmiHeader->biSizeImage = 0;
1008 pbmiHeader->biXPelsPerMeter = pbmiHeader->biYPelsPerMeter = 0;
1009 pbmiHeader->biClrUsed = 0;
1010 pbmiHeader->biClrImportant = 0;
1011
1012 /* Retrieve the DIB bits from the bitmap and fill in the
1013 * DIB color table if present */
1014
1015 nLinesCopied = GetDIBits(hdc, /* Handle to device context */
1016 hBmp, /* Handle to bitmap */
1017 0, /* First scan line to set in dest bitmap */
1018 height, /* Number of scan lines to copy */
1019 pPackedDIB + OffsetBits, /* [out] Address of array for bitmap bits */
1020 (LPBITMAPINFO) pbmiHeader, /* [out] Address of BITMAPINFO structure */
1021 0); /* RGB or palette index */
1022 GlobalUnlock(hPackedDIB);
1023
1024 /* Cleanup if GetDIBits failed */
1025 if (nLinesCopied != height)
1026 {
1027 TRACE("\tGetDIBits returned %d. Actual lines=%d\n", nLinesCopied, height);
1028 GlobalFree(hPackedDIB);
1029 hPackedDIB = 0;
1030 }
1031
1032END:
Alexandre Julliard2a2321b2000-08-19 21:38:55 +00001033 GDI_ReleaseObj( hBmp );
Noel Borthwickd05b7be1999-09-20 15:42:47 +00001034 return hPackedDIB;
1035}