~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/gdi32/dib.c

Version: ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * GDI device-independent bitmaps
  3  *
  4  * Copyright 1993,1994  Alexandre Julliard
  5  *
  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.
 10  *
 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.
 15  *
 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
 19  */
 20 
 21 /*
 22   Important information:
 23   
 24   * Current Windows versions support two different DIB structures:
 25 
 26     - BITMAPCOREINFO / BITMAPCOREHEADER (legacy structures; used in OS/2)
 27     - BITMAPINFO / BITMAPINFOHEADER
 28   
 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.
 33 
 34     
 35   * The palettes are stored in different formats:
 36 
 37     - BITMAPCOREINFO: Array of RGBTRIPLE
 38     - BITMAPINFO:     Array of RGBQUAD
 39 
 40     
 41   * There are even more DIB headers, but they all extend BITMAPINFOHEADER:
 42     
 43     - BITMAPV4HEADER: Introduced in Windows 95 / NT 4.0
 44     - BITMAPV5HEADER: Introduced in Windows 98 / 2000
 45     
 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.
 49 
 50 
 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:
 54     
 55     BITMAPINFO* info;
 56     void* colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
 57 
 58     
 59   * More information:
 60     Search for "Bitmap Structures" in MSDN
 61 */
 62 
 63 #include <stdarg.h>
 64 #include <stdlib.h>
 65 #include <string.h>
 66 
 67 #include "windef.h"
 68 #include "winbase.h"
 69 #include "gdi_private.h"
 70 #include "wine/debug.h"
 71 
 72 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
 73 
 74 
 75 /*
 76   Some of the following helper functions are duplicated in
 77   dlls/x11drv/dib.c
 78 */
 79 
 80 /***********************************************************************
 81  *           DIB_GetDIBWidthBytes
 82  *
 83  * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
 84  */
 85 int DIB_GetDIBWidthBytes( int width, int depth )
 86 {
 87     int words;
 88 
 89     switch(depth)
 90     {
 91         case 1:  words = (width + 31) / 32; break;
 92         case 4:  words = (width + 7) / 8; break;
 93         case 8:  words = (width + 3) / 4; break;
 94         case 15:
 95         case 16: words = (width + 1) / 2; break;
 96         case 24: words = (width * 3 + 3)/4; break;
 97 
 98         default:
 99             WARN("(%d): Unsupported depth\n", depth );
100         /* fall through */
101         case 32:
102                 words = width;
103     }
104     return 4 * words;
105 }
106 
107 /***********************************************************************
108  *           DIB_GetDIBImageBytes
109  *
110  * Return the number of bytes used to hold the image in a DIB bitmap.
111  */
112 int DIB_GetDIBImageBytes( int width, int height, int depth )
113 {
114     return DIB_GetDIBWidthBytes( width, depth ) * abs( height );
115 }
116 
117 
118 /***********************************************************************
119  *           bitmap_info_size
120  *
121  * Return the size of the bitmap info structure including color table.
122  */
123 int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
124 {
125     unsigned int colors, size, masks = 0;
126 
127     if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
128     {
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));
133     }
134     else  /* assume BITMAPINFOHEADER */
135     {
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));
143     }
144 }
145 
146 
147 /***********************************************************************
148  *           DIB_GetBitmapInfo
149  *
150  * Get the info from a bitmap header.
151  * Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error.
152  */
153 int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
154                        LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size )
155 {
156     if (header->biSize == sizeof(BITMAPCOREHEADER))
157     {
158         const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
159         *width  = core->bcWidth;
160         *height = core->bcHeight;
161         *planes = core->bcPlanes;
162         *bpp    = core->bcBitCount;
163         *compr  = 0;
164         *size   = 0;
165         return 0;
166     }
167     if (header->biSize >= sizeof(BITMAPINFOHEADER)) /* assume BITMAPINFOHEADER */
168     {
169         *width  = header->biWidth;
170         *height = header->biHeight;
171         *planes = header->biPlanes;
172         *bpp    = header->biBitCount;
173         *compr  = header->biCompression;
174         *size   = header->biSizeImage;
175         return 1;
176     }
177     ERR("(%d): unknown/wrong size for header\n", header->biSize );
178     return -1;
179 }
180 
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 )
185 {
186     DC *dc = get_nulldrv_dc( dev );
187     INT ret;
188     LONG width, height;
189     WORD planes, bpp;
190     DWORD compr, size;
191     HBITMAP hBitmap;
192     HDC hdcMem;
193 
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)
196         return 0;
197 
198     if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size ) == -1)
199         return 0;
200 
201     if (width < 0) return 0;
202 
203     if (xSrc == 0 && ySrc == 0 && widthDst == widthSrc && heightDst == heightSrc &&
204         info->bmiHeader.biCompression == BI_RGB)
205     {
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;
209 
210         if (xDst == 0 && yDst == 0 && info->bmiHeader.biCompression == BI_RGB && rop == SRCCOPY)
211         {
212             BITMAP bm;
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)
217             {
218                 /* fast path */
219                 return SetDIBits( dev->hdc, hBitmap, 0, height, bits, info, coloruse );
220             }
221         }
222     }
223 
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 );
229 
230     if (info->bmiHeader.biCompression == BI_RLE4 || info->bmiHeader.biCompression == BI_RLE8)
231     {
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
239          */
240         StretchBlt( hdcMem, xSrc, abs(height) - heightSrc - ySrc, widthSrc, heightSrc,
241                     dev->hdc, xDst, yDst, widthDst, heightDst, rop );
242     }
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 );
246     DeleteDC( hdcMem );
247     DeleteObject( hBitmap );
248     return ret;
249 }
250 
251 /***********************************************************************
252  *           StretchDIBits   (GDI32.@)
253  */
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 )
257 {
258     DC *dc;
259     INT ret = 0;
260 
261     if (!bits || !info) return 0;
262 
263     if ((dc = get_dc_ptr( hdc )))
264     {
265         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pStretchDIBits );
266         update_dc( dc );
267         ret = physdev->funcs->pStretchDIBits( physdev, xDst, yDst, widthDst, heightDst,
268                                               xSrc, ySrc, widthSrc, heightSrc, bits, info, coloruse, rop );
269         release_dc_ptr( dc );
270     }
271     return ret;
272 }
273 
274 
275 /******************************************************************************
276  * SetDIBits [GDI32.@]
277  *
278  * Sets pixels in a bitmap using colors from DIB.
279  *
280  * PARAMS
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
288  *
289  * RETURNS
290  *    Success: Number of scan lines copied
291  *    Failure: 0
292  */
293 INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
294                       UINT lines, LPCVOID bits, const BITMAPINFO *info,
295                       UINT coloruse )
296 {
297     DC *dc = get_dc_ptr( hdc );
298     BOOL delete_hdc = FALSE;
299     PHYSDEV physdev;
300     BITMAPOBJ *bitmap;
301     INT result = 0;
302 
303     if (coloruse == DIB_RGB_COLORS && !dc)
304     {
305         hdc = CreateCompatibleDC(0);
306         dc = get_dc_ptr( hdc );
307         delete_hdc = TRUE;
308     }
309 
310     if (!dc) return 0;
311 
312     update_dc( dc );
313 
314     if (!(bitmap = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
315     {
316         release_dc_ptr( dc );
317         if (delete_hdc) DeleteDC(hdc);
318         return 0;
319     }
320 
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 );
324 
325     GDI_ReleaseObj( hbitmap );
326     release_dc_ptr( dc );
327     if (delete_hdc) DeleteDC(hdc);
328     return result;
329 }
330 
331 
332 /***********************************************************************
333  *           SetDIBitsToDevice   (GDI32.@)
334  */
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,
338                            UINT coloruse )
339 {
340     INT ret = 0;
341     DC *dc;
342 
343     if (!bits) return 0;
344 
345     if ((dc = get_dc_ptr( hdc )))
346     {
347         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDIBitsToDevice );
348         update_dc( dc );
349         ret = physdev->funcs->pSetDIBitsToDevice( physdev, xDest, yDest, cx, cy, xSrc,
350                                                   ySrc, startscan, lines, bits, info, coloruse );
351         release_dc_ptr( dc );
352     }
353     return ret;
354 }
355 
356 /***********************************************************************
357  *           SetDIBColorTable    (GDI32.@)
358  */
359 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUAD *colors )
360 {
361     DC * dc;
362     UINT result = 0;
363     BITMAPOBJ * bitmap;
364 
365     if (!(dc = get_dc_ptr( hdc ))) return 0;
366 
367     if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
368     {
369         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDIBColorTable );
370 
371         /* Check if currently selected bitmap is a DIB */
372         if (bitmap->color_table)
373         {
374             if (startpos < bitmap->nb_colors)
375             {
376                 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
377                 memcpy(bitmap->color_table + startpos, colors, entries * sizeof(RGBQUAD));
378                 result = entries;
379             }
380         }
381         GDI_ReleaseObj( dc->hBitmap );
382         physdev->funcs->pSetDIBColorTable( physdev, startpos, entries, colors );
383     }
384     release_dc_ptr( dc );
385     return result;
386 }
387 
388 
389 /***********************************************************************
390  *           GetDIBColorTable    (GDI32.@)
391  */
392 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
393 {
394     DC * dc;
395     BITMAPOBJ *bitmap;
396     UINT result = 0;
397 
398     if (!(dc = get_dc_ptr( hdc ))) return 0;
399 
400     if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
401     {
402         /* Check if currently selected bitmap is a DIB */
403         if (bitmap->color_table)
404         {
405             if (startpos < bitmap->nb_colors)
406             {
407                 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
408                 memcpy(colors, bitmap->color_table + startpos, entries * sizeof(RGBQUAD));
409                 result = entries;
410             }
411         }
412         GDI_ReleaseObj( dc->hBitmap );
413     }
414     release_dc_ptr( dc );
415     return result;
416 }
417 
418 /* FIXME the following two structs should be combined with __sysPalTemplate in
419    objects/color.c - this should happen after de-X11-ing both of these
420    files.
421    NB. RGBQUAD and PALETTEENTRY have different orderings of red, green
422    and blue - sigh */
423 
424 static const RGBQUAD EGAColorsQuads[16] = {
425 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
426     { 0x00, 0x00, 0x00, 0x00 },
427     { 0x00, 0x00, 0x80, 0x00 },
428     { 0x00, 0x80, 0x00, 0x00 },
429     { 0x00, 0x80, 0x80, 0x00 },
430     { 0x80, 0x00, 0x00, 0x00 },
431     { 0x80, 0x00, 0x80, 0x00 },
432     { 0x80, 0x80, 0x00, 0x00 },
433     { 0x80, 0x80, 0x80, 0x00 },
434     { 0xc0, 0xc0, 0xc0, 0x00 },
435     { 0x00, 0x00, 0xff, 0x00 },
436     { 0x00, 0xff, 0x00, 0x00 },
437     { 0x00, 0xff, 0xff, 0x00 },
438     { 0xff, 0x00, 0x00, 0x00 },
439     { 0xff, 0x00, 0xff, 0x00 },
440     { 0xff, 0xff, 0x00, 0x00 },
441     { 0xff, 0xff, 0xff, 0x00 }
442 };
443 
444 static const RGBTRIPLE EGAColorsTriples[16] = {
445 /* rgbBlue, rgbGreen, rgbRed */
446     { 0x00, 0x00, 0x00 },
447     { 0x00, 0x00, 0x80 },
448     { 0x00, 0x80, 0x00 },
449     { 0x00, 0x80, 0x80 },
450     { 0x80, 0x00, 0x00 },
451     { 0x80, 0x00, 0x80 },
452     { 0x80, 0x80, 0x00 },
453     { 0x80, 0x80, 0x80 },
454     { 0xc0, 0xc0, 0xc0 },
455     { 0x00, 0x00, 0xff },
456     { 0x00, 0xff, 0x00 },
457     { 0x00, 0xff, 0xff },
458     { 0xff, 0x00, 0x00 } ,
459     { 0xff, 0x00, 0xff },
460     { 0xff, 0xff, 0x00 },
461     { 0xff, 0xff, 0xff }
462 };
463 
464 static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
465 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
466     { 0x00, 0x00, 0x00, 0x00 },
467     { 0x00, 0x00, 0x80, 0x00 },
468     { 0x00, 0x80, 0x00, 0x00 },
469     { 0x00, 0x80, 0x80, 0x00 },
470     { 0x80, 0x00, 0x00, 0x00 },
471     { 0x80, 0x00, 0x80, 0x00 },
472     { 0x80, 0x80, 0x00, 0x00 },
473     { 0xc0, 0xc0, 0xc0, 0x00 },
474     { 0xc0, 0xdc, 0xc0, 0x00 },
475     { 0xf0, 0xca, 0xa6, 0x00 },
476     { 0xf0, 0xfb, 0xff, 0x00 },
477     { 0xa4, 0xa0, 0xa0, 0x00 },
478     { 0x80, 0x80, 0x80, 0x00 },
479     { 0x00, 0x00, 0xf0, 0x00 },
480     { 0x00, 0xff, 0x00, 0x00 },
481     { 0x00, 0xff, 0xff, 0x00 },
482     { 0xff, 0x00, 0x00, 0x00 },
483     { 0xff, 0x00, 0xff, 0x00 },
484     { 0xff, 0xff, 0x00, 0x00 },
485     { 0xff, 0xff, 0xff, 0x00 }
486 };
487 
488 static const RGBTRIPLE DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
489 /* rgbBlue, rgbGreen, rgbRed */
490     { 0x00, 0x00, 0x00 },
491     { 0x00, 0x00, 0x80 },
492     { 0x00, 0x80, 0x00 },
493     { 0x00, 0x80, 0x80 },
494     { 0x80, 0x00, 0x00 },
495     { 0x80, 0x00, 0x80 },
496     { 0x80, 0x80, 0x00 },
497     { 0xc0, 0xc0, 0xc0 },
498     { 0xc0, 0xdc, 0xc0 },
499     { 0xf0, 0xca, 0xa6 },
500     { 0xf0, 0xfb, 0xff },
501     { 0xa4, 0xa0, 0xa0 },
502     { 0x80, 0x80, 0x80 },
503     { 0x00, 0x00, 0xf0 },
504     { 0x00, 0xff, 0x00 },
505     { 0x00, 0xff, 0xff },
506     { 0xff, 0x00, 0x00 },
507     { 0xff, 0x00, 0xff },
508     { 0xff, 0xff, 0x00 },
509     { 0xff, 0xff, 0xff}
510 };
511 
512 
513 /******************************************************************************
514  * GetDIBits [GDI32.@]
515  *
516  * Retrieves bits of bitmap and copies to buffer.
517  *
518  * RETURNS
519  *    Success: Number of scan lines copied from bitmap
520  *    Failure: 0
521  */
522 INT WINAPI GetDIBits(
523     HDC hdc,         /* [in]  Handle to device context */
524     HBITMAP hbitmap, /* [in]  Handle to bitmap */
525     UINT startscan,  /* [in]  First scan line to set in dest bitmap */
526     UINT lines,      /* [in]  Number of scan lines to copy */
527     LPVOID bits,       /* [out] Address of array for bitmap bits */
528     BITMAPINFO * info, /* [out] Address of structure with bitmap data */
529     UINT coloruse)   /* [in]  RGB or palette index */
530 {
531     DC * dc;
532     BITMAPOBJ * bmp;
533     int i;
534     int bitmap_type;
535     BOOL core_header;
536     LONG width;
537     LONG height;
538     WORD planes, bpp;
539     DWORD compr, size;
540     void* colorPtr;
541     RGBTRIPLE* rgbTriples;
542     RGBQUAD* rgbQuads;
543 
544     if (!info) return 0;
545 
546     bitmap_type = DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size);
547     if (bitmap_type == -1)
548     {
549         ERR("Invalid bitmap format\n");
550         return 0;
551     }
552     core_header = (bitmap_type == 0);
553     if (!(dc = get_dc_ptr( hdc )))
554     {
555         SetLastError( ERROR_INVALID_PARAMETER );
556         return 0;
557     }
558     update_dc( dc );
559     if (!(bmp = GDI_GetObjPtr( hbitmap, OBJ_BITMAP )))
560     {
561         release_dc_ptr( dc );
562         return 0;
563     }
564 
565     colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
566     rgbTriples = colorPtr;
567     rgbQuads = colorPtr;
568 
569     /* Transfer color info */
570 
571     switch (bpp)
572     {
573     case 0:  /* query bitmap info only */
574         if (core_header)
575         {
576             BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
577             coreheader->bcWidth = bmp->bitmap.bmWidth;
578             coreheader->bcHeight = bmp->bitmap.bmHeight;
579             coreheader->bcPlanes = 1;
580             coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
581         }
582         else
583         {
584             info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
585             info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
586             info->bmiHeader.biPlanes = 1;
587             info->bmiHeader.biSizeImage =
588                 DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
589                                       bmp->bitmap.bmHeight,
590                                       bmp->bitmap.bmBitsPixel );
591             if (bmp->dib)
592             {
593                 info->bmiHeader.biBitCount = bmp->dib->dsBm.bmBitsPixel;
594                 switch (bmp->dib->dsBm.bmBitsPixel)
595                 {
596                 case 16:
597                 case 32:
598                     info->bmiHeader.biCompression = BI_BITFIELDS;
599                     break;
600                 default:
601                     info->bmiHeader.biCompression = BI_RGB;
602                     break;
603                 }
604             }
605             else
606             {
607                 info->bmiHeader.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB;
608                 info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
609             }
610             info->bmiHeader.biXPelsPerMeter = 0;
611             info->bmiHeader.biYPelsPerMeter = 0;
612             info->bmiHeader.biClrUsed = 0;
613             info->bmiHeader.biClrImportant = 0;
614 
615             /* Windows 2000 doesn't touch the additional struct members if
616                it's a BITMAPV4HEADER or a BITMAPV5HEADER */
617         }
618         lines = abs(bmp->bitmap.bmHeight);
619         goto done;
620 
621     case 1:
622     case 4:
623     case 8:
624         if (!core_header) info->bmiHeader.biClrUsed = 0;
625 
626         /* If the bitmap object already has a dib section at the
627            same color depth then get the color map from it */
628         if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == bpp) {
629             if(coloruse == DIB_RGB_COLORS) {
630                 unsigned int colors = min( bmp->nb_colors, 1 << bpp );
631 
632                 if (core_header)
633                 {
634                     /* Convert the color table (RGBQUAD to RGBTRIPLE) */
635                     RGBTRIPLE* index = rgbTriples;
636 
637                     for (i=0; i < colors; i++, index++)
638                     {
639                         index->rgbtRed   = bmp->color_table[i].rgbRed;
640                         index->rgbtGreen = bmp->color_table[i].rgbGreen;
641                         index->rgbtBlue  = bmp->color_table[i].rgbBlue;
642                     }
643                 }
644                 else
645                 {
646                     if (colors != 1 << bpp) info->bmiHeader.biClrUsed = colors;
647                     memcpy(colorPtr, bmp->color_table, colors * sizeof(RGBQUAD));
648                 }
649             }
650             else {
651                 WORD *index = colorPtr;
652                 for(i = 0; i < 1 << info->bmiHeader.biBitCount; i++, index++)
653                     *index = i;
654             }
655         }
656         else {
657             if (coloruse == DIB_PAL_COLORS) {
658                 for (i = 0; i < (1 << bpp); i++)
659                     ((WORD *)colorPtr)[i] = (WORD)i;
660             }
661             else if(bpp > 1 && bpp == bmp->bitmap.bmBitsPixel) {
662                 /* For color DDBs in native depth (mono DDBs always have
663                    a black/white palette):
664                    Generate the color map from the selected palette */
665                 PALETTEENTRY palEntry[256];
666 
667                 memset( palEntry, 0, sizeof(palEntry) );
668                 if (!GetPaletteEntries( dc->hPalette, 0, 1 << bmp->bitmap.bmBitsPixel, palEntry ))
669                 {
670                     release_dc_ptr( dc );
671                     GDI_ReleaseObj( hbitmap );
672                     return 0;
673                 }
674                 for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++) {
675                     if (core_header)
676                     {
677                         rgbTriples[i].rgbtRed   = palEntry[i].peRed;
678                         rgbTriples[i].rgbtGreen = palEntry[i].peGreen;
679                         rgbTriples[i].rgbtBlue  = palEntry[i].peBlue;
680                     }
681                     else
682                     {
683                         rgbQuads[i].rgbRed      = palEntry[i].peRed;
684                         rgbQuads[i].rgbGreen    = palEntry[i].peGreen;
685                         rgbQuads[i].rgbBlue     = palEntry[i].peBlue;
686                         rgbQuads[i].rgbReserved = 0;
687                     }
688                 }
689             } else {
690                 switch (bpp) {
691                 case 1:
692                     if (core_header)
693                     {
694                         rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
695                             rgbTriples[0].rgbtBlue = 0;
696                         rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
697                             rgbTriples[1].rgbtBlue = 0xff;
698                     }
699                     else
700                     {    
701                         rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
702                             rgbQuads[0].rgbBlue = 0;
703                         rgbQuads[0].rgbReserved = 0;
704                         rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
705                             rgbQuads[1].rgbBlue = 0xff;
706                         rgbQuads[1].rgbReserved = 0;
707                     }
708                     break;
709 
710                 case 4:
711                     if (core_header)
712                         memcpy(colorPtr, EGAColorsTriples, sizeof(EGAColorsTriples));
713                     else
714                         memcpy(colorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
715 
716                     break;
717 
718                 case 8:
719                     {
720                         if (core_header)
721                         {
722                             INT r, g, b;
723                             RGBTRIPLE *color;
724 
725                             memcpy(rgbTriples, DefLogPaletteTriples,
726                                        10 * sizeof(RGBTRIPLE));
727                             memcpy(rgbTriples + 246, DefLogPaletteTriples + 10,
728                                        10 * sizeof(RGBTRIPLE));
729                             color = rgbTriples + 10;
730                             for(r = 0; r <= 5; r++) /* FIXME */
731                                 for(g = 0; g <= 5; g++)
732                                     for(b = 0; b <= 5; b++) {
733                                         color->rgbtRed =   (r * 0xff) / 5;
734                                         color->rgbtGreen = (g * 0xff) / 5;
735                                         color->rgbtBlue =  (b * 0xff) / 5;
736                                         color++;
737                                     }
738                         }
739                         else
740                         {
741                             INT r, g, b;
742                             RGBQUAD *color;
743 
744                             memcpy(rgbQuads, DefLogPaletteQuads,
745                                        10 * sizeof(RGBQUAD));
746                             memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
747                                    10 * sizeof(RGBQUAD));
748                             color = rgbQuads + 10;
749                             for(r = 0; r <= 5; r++) /* FIXME */
750                                 for(g = 0; g <= 5; g++)
751                                     for(b = 0; b <= 5; b++) {
752                                         color->rgbRed =   (r * 0xff) / 5;
753                                         color->rgbGreen = (g * 0xff) / 5;
754                                         color->rgbBlue =  (b * 0xff) / 5;
755                                         color->rgbReserved = 0;
756                                         color++;
757                                     }
758                         }
759                     }
760                 }
761             }
762         }
763         break;
764 
765     case 15:
766         if (info->bmiHeader.biCompression == BI_BITFIELDS)
767         {
768             ((PDWORD)info->bmiColors)[0] = 0x7c00;
769             ((PDWORD)info->bmiColors)[1] = 0x03e0;
770             ((PDWORD)info->bmiColors)[2] = 0x001f;
771         }
772         break;
773 
774     case 16:
775         if (info->bmiHeader.biCompression == BI_BITFIELDS)
776         {
777             if (bmp->dib)
778             {
779                 if (bmp->dib->dsBmih.biCompression == BI_BITFIELDS)
780                     memcpy( info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
781                 else
782                 {
783                     ((PDWORD)info->bmiColors)[0] = 0x7c00;
784                     ((PDWORD)info->bmiColors)[1] = 0x03e0;
785                     ((PDWORD)info->bmiColors)[2] = 0x001f;
786                 }
787             }
788             else
789             {
790                 ((PDWORD)info->bmiColors)[0] = 0xf800;
791                 ((PDWORD)info->bmiColors)[1] = 0x07e0;
792                 ((PDWORD)info->bmiColors)[2] = 0x001f;
793             }
794         }
795         break;
796 
797     case 24:
798     case 32:
799         if (info->bmiHeader.biCompression == BI_BITFIELDS)
800         {
801             if (bmp->dib && bmp->dib->dsBmih.biCompression == BI_BITFIELDS)
802                 memcpy( info->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD) );
803             else
804             {
805                 ((PDWORD)info->bmiColors)[0] = 0xff0000;
806                 ((PDWORD)info->bmiColors)[1] = 0x00ff00;
807                 ((PDWORD)info->bmiColors)[2] = 0x0000ff;
808             }
809         }
810         break;
811     }
812 
813     if (bits && lines)
814     {
815         /* If the bitmap object already have a dib section that contains image data, get the bits from it */
816         if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
817         {
818             /*FIXME: Only RGB dibs supported for now */
819             unsigned int srcwidth = bmp->dib->dsBm.bmWidth;
820             int srcwidthb = bmp->dib->dsBm.bmWidthBytes;
821             unsigned int dstwidth = width;
822             int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
823             LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
824             unsigned int x, y, width, widthb;
825 
826             /*
827              * If copying from a top-down source bitmap, move the source
828              * pointer to the end of the source bitmap and negate the width
829              * so that we copy the bits upside-down.
830              */
831             if (bmp->dib->dsBmih.biHeight < 0)
832             {
833                 sbits += (srcwidthb * (int)(abs(bmp->dib->dsBmih.biHeight) - 2 * startscan - 1));
834                 srcwidthb = -srcwidthb;
835             }
836             /*Same for the destination.*/
837             if (height < 0)
838             {
839                 dbits = (LPBYTE)bits + (dstwidthb * (lines - 1));
840                 dstwidthb = -dstwidthb;
841             }
842             switch( bpp ) {
843 
844             case 15:
845             case 16: /* 16 bpp dstDIB */
846                 {
847                     LPWORD dstbits = (LPWORD)dbits;
848                     WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
849 
850                     /* FIXME: BI_BITFIELDS not supported yet */
851 
852                     switch(bmp->dib->dsBm.bmBitsPixel) {
853 
854                     case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
855                         {
856                             widthb = min(abs(srcwidthb), abs(dstwidthb));
857                             /* FIXME: BI_BITFIELDS not supported yet */
858                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
859                                 memcpy(dbits, sbits, widthb);
860                         }
861                         break;
862 
863                     case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
864                         {
865                             LPBYTE srcbits = sbits;
866 
867                             width = min(srcwidth, dstwidth);
868                             for( y = 0; y < lines; y++) {
869                                 for( x = 0; x < width; x++, srcbits += 3)
870                                     *dstbits++ = ((srcbits[0] >> 3) & bmask) |
871                                                  (((WORD)srcbits[1] << 2) & gmask) |
872                                                  (((WORD)srcbits[2] << 7) & rmask);
873 
874                                 dstbits = (LPWORD)(dbits+=dstwidthb);
875                                 srcbits = (sbits += srcwidthb);
876                             }
877                         }
878                         break;
879 
880                     case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
881                         {
882                             LPDWORD srcbits = (LPDWORD)sbits;
883                             DWORD val;
884 
885                             width = min(srcwidth, dstwidth);
886                             for( y = 0; y < lines; y++) {
887                                 for( x = 0; x < width; x++ ) {
888                                     val = *srcbits++;
889                                     *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
890                                                        ((val >> 9) & rmask));
891                                 }
892                                 dstbits = (LPWORD)(dbits+=dstwidthb);
893                                 srcbits = (LPDWORD)(sbits+=srcwidthb);
894                             }
895                         }
896                         break;
897 
898                     default: /* ? bit bmp -> 16 bit DIB */
899                         FIXME("15/16 bit DIB %d bit bitmap\n",
900                         bmp->bitmap.bmBitsPixel);
901                         break;
902                     }
903                 }
904                 break;
905 
906             case 24: /* 24 bpp dstDIB */
907                 {
908                     LPBYTE dstbits = dbits;
909 
910                     switch(bmp->dib->dsBm.bmBitsPixel) {
911 
912                     case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
913                         {
914                             LPWORD srcbits = (LPWORD)sbits;
915                             WORD val;
916 
917                             width = min(srcwidth, dstwidth);
918                             /* FIXME: BI_BITFIELDS not supported yet */
919                             for( y = 0; y < lines; y++) {
920                                 for( x = 0; x < width; x++ ) {
921                                     val = *srcbits++;
922                                     *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
923                                     *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
924                                     *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
925                                 }
926                                 dstbits = dbits+=dstwidthb;
927                                 srcbits = (LPWORD)(sbits+=srcwidthb);
928                             }
929                         }
930                         break;
931 
932                     case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
933                         {
934                             widthb = min(abs(srcwidthb), abs(dstwidthb));
935                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
936                                 memcpy(dbits, sbits, widthb);
937                         }
938                         break;
939 
940                     case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
941                         {
942                             LPBYTE srcbits = sbits;
943 
944                             width = min(srcwidth, dstwidth);
945                             for( y = 0; y < lines; y++) {
946                                 for( x = 0; x < width; x++, srcbits++ ) {
947                                     *dstbits++ = *srcbits++;
948                                     *dstbits++ = *srcbits++;
949                                     *dstbits++ = *srcbits++;
950                                 }
951                                 dstbits = dbits+=dstwidthb;
952                                 srcbits = sbits+=srcwidthb;
953                             }
954                         }
955                         break;
956 
957                     default: /* ? bit bmp -> 24 bit DIB */
958                         FIXME("24 bit DIB %d bit bitmap\n",
959                               bmp->bitmap.bmBitsPixel);
960                         break;
961                     }
962                 }
963                 break;
964 
965             case 32: /* 32 bpp dstDIB */
966                 {
967                     LPDWORD dstbits = (LPDWORD)dbits;
968 
969                     /* FIXME: BI_BITFIELDS not supported yet */
970 
971                     switch(bmp->dib->dsBm.bmBitsPixel) {
972                         case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
973                         {
974                             LPWORD srcbits = (LPWORD)sbits;
975                             DWORD val;
976 
977                             width = min(srcwidth, dstwidth);
978                             /* FIXME: BI_BITFIELDS not supported yet */
979                             for( y = 0; y < lines; y++) {
980                                 for( x = 0; x < width; x++ ) {
981                                     val = (DWORD)*srcbits++;
982                                     *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
983                                                  ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
984                                                  ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
985                                 }
986                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
987                                 srcbits=(LPWORD)(sbits+=srcwidthb);
988                             }
989                         }
990                         break;
991 
992                     case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
993                         {
994                             LPBYTE srcbits = sbits;
995 
996                             width = min(srcwidth, dstwidth);
997                             for( y = 0; y < lines; y++) {
998                                 for( x = 0; x < width; x++, srcbits+=3 )
999                                     *dstbits++ =  srcbits[0] |
1000                                                  (srcbits[1] <<  8) |
1001                                                  (srcbits[2] << 16);
1002                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
1003                                 srcbits=(sbits+=srcwidthb);
1004                             }
1005                         }
1006                         break;
1007 
1008                     case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
1009                         {
1010                             widthb = min(abs(srcwidthb), abs(dstwidthb));
1011                             /* FIXME: BI_BITFIELDS not supported yet */
1012                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
1013                                 memcpy(dbits, sbits, widthb);
1014                             }
1015                         }
1016                         break;
1017 
1018                     default: /* ? bit bmp -> 32 bit DIB */
1019                         FIXME("32 bit DIB %d bit bitmap\n",
1020                         bmp->bitmap.bmBitsPixel);
1021                         break;
1022                     }
1023                 }
1024                 break;
1025 
1026             default: /* ? bit DIB */
1027                 FIXME("Unsupported DIB depth %d\n", info->bmiHeader.biBitCount);
1028                 break;
1029             }
1030         }
1031         /* Otherwise, get bits from the XImage */
1032         else
1033         {
1034             PHYSDEV physdev = GET_DC_PHYSDEV( dc, pGetDIBits );
1035             if (!BITMAP_SetOwnerDC( hbitmap, physdev )) lines = 0;
1036             else lines = physdev->funcs->pGetDIBits( physdev, hbitmap, startscan,
1037                                                      lines, bits, info, coloruse );
1038         }
1039     }
1040     else lines = abs(height);
1041 
1042     /* The knowledge base article Q81498 ("DIBs and Their Uses") states that
1043        if bits == NULL and bpp != 0, only biSizeImage and the color table are
1044        filled in. */
1045     if (!core_header)
1046     {
1047         /* FIXME: biSizeImage should be calculated according to the selected
1048            compression algorithm if biCompression != BI_RGB */
1049         info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp );
1050         TRACE("biSizeImage = %d, ", info->bmiHeader.biSizeImage);
1051     }
1052     TRACE("biWidth = %d, biHeight = %d\n", width, height);
1053 
1054 done:
1055     release_dc_ptr( dc );
1056     GDI_ReleaseObj( hbitmap );
1057     return lines;
1058 }
1059 
1060 
1061 /***********************************************************************
1062  *           CreateDIBitmap    (GDI32.@)
1063  *
1064  * Creates a DDB (device dependent bitmap) from a DIB.
1065  * The DDB will have the same color depth as the reference DC.
1066  */
1067 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
1068                             DWORD init, LPCVOID bits, const BITMAPINFO *data,
1069                             UINT coloruse )
1070 {
1071     HBITMAP handle;
1072     LONG width;
1073     LONG height;
1074     WORD planes, bpp;
1075     DWORD compr, size;
1076 
1077     if (!header) return 0;
1078 
1079     if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &size ) == -1) return 0;
1080     
1081     if (width < 0)
1082     {
1083         TRACE("Bitmap has a negative width\n");
1084         return 0;
1085     }
1086     
1087     /* Top-down DIBs have a negative height */
1088     if (height < 0) height = -height;
1089 
1090     TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1091            hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
1092     
1093     if (hdc == NULL)
1094         handle = CreateBitmap( width, height, 1, 1, NULL );
1095     else
1096         handle = CreateCompatibleBitmap( hdc, width, height );
1097 
1098     if (handle)
1099     {
1100         if (init & CBM_INIT)
1101         {
1102             if (SetDIBits( hdc, handle, 0, height, bits, data, coloruse ) == 0)
1103             {
1104                 DeleteObject( handle );
1105                 handle = 0;
1106             }
1107         }
1108     }
1109 
1110     return handle;
1111 }
1112 
1113 /* Copy/synthesize RGB palette from BITMAPINFO. Ripped from dlls/winex11.drv/dib.c */
1114 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1115 {
1116     RGBQUAD *colorTable;
1117     unsigned int colors, i;
1118     BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
1119 
1120     if (core_info)
1121     {
1122         colors = 1 << ((const BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
1123     }
1124     else
1125     {
1126         colors = info->bmiHeader.biClrUsed;
1127         if (!colors) colors = 1 << info->bmiHeader.biBitCount;
1128     }
1129 
1130     if (colors > 256) {
1131         ERR("called with >256 colors!\n");
1132         return;
1133     }
1134 
1135     if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1136 
1137     if(coloruse == DIB_RGB_COLORS)
1138     {
1139         if (core_info)
1140         {
1141            /* Convert RGBTRIPLEs to RGBQUADs */
1142            for (i=0; i < colors; i++)
1143            {
1144                colorTable[i].rgbRed   = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
1145                colorTable[i].rgbGreen = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
1146                colorTable[i].rgbBlue  = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
1147                colorTable[i].rgbReserved = 0;
1148            }
1149         }
1150         else
1151         {
1152             memcpy(colorTable, (const BYTE*) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
1153         }
1154     }
1155     else
1156     {
1157         PALETTEENTRY entries[256];
1158         const WORD *index = (const WORD*) ((const BYTE*) info + (WORD) info->bmiHeader.biSize);
1159         UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1160 
1161         for (i = 0; i < colors; i++, index++)
1162         {
1163             PALETTEENTRY *entry = &entries[*index % count];
1164             colorTable[i].rgbRed = entry->peRed;
1165             colorTable[i].rgbGreen = entry->peGreen;
1166             colorTable[i].rgbBlue = entry->peBlue;
1167             colorTable[i].rgbReserved = 0;
1168         }
1169     }
1170     bmp->color_table = colorTable;
1171     bmp->nb_colors = colors;
1172 }
1173 
1174 /***********************************************************************
1175  *           CreateDIBSection    (GDI32.@)
1176  */
1177 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1178                                 VOID **bits, HANDLE section, DWORD offset)
1179 {
1180     HBITMAP ret = 0;
1181     DC *dc;
1182     BOOL bDesktopDC = FALSE;
1183     DIBSECTION *dib;
1184     BITMAPOBJ *bmp;
1185     int bitmap_type;
1186     LONG width, height;
1187     WORD planes, bpp;
1188     DWORD compression, sizeImage;
1189     void *mapBits = NULL;
1190 
1191     if(!bmi){
1192         if(bits) *bits = NULL;
1193         return NULL;
1194     }
1195 
1196     if (((bitmap_type = DIB_GetBitmapInfo( &bmi->bmiHeader, &width, &height,
1197                                            &planes, &bpp, &compression, &sizeImage )) == -1))
1198         return 0;
1199 
1200     switch (bpp)
1201     {
1202     case 16:
1203     case 32:
1204         if (compression == BI_BITFIELDS) break;
1205         /* fall through */
1206     case 1:
1207     case 4:
1208     case 8:
1209     case 24:
1210         if (compression == BI_RGB) break;
1211         /* fall through */
1212     default:
1213         WARN( "invalid %u bpp compression %u\n", bpp, compression );
1214         return 0;
1215     }
1216 
1217     if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1218 
1219     TRACE("format (%d,%d), planes %d, bpp %d, %s, size %d %s\n",
1220           width, height, planes, bpp, compression == BI_BITFIELDS? "BI_BITFIELDS" : "BI_RGB",
1221           sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1222 
1223     dib->dsBm.bmType       = 0;
1224     dib->dsBm.bmWidth      = width;
1225     dib->dsBm.bmHeight     = height >= 0 ? height : -height;
1226     dib->dsBm.bmWidthBytes = DIB_GetDIBWidthBytes(width, bpp);
1227     dib->dsBm.bmPlanes     = planes;
1228     dib->dsBm.bmBitsPixel  = bpp;
1229     dib->dsBm.bmBits       = NULL;
1230 
1231     if (!bitmap_type)  /* core header */
1232     {
1233         /* convert the BITMAPCOREHEADER to a BITMAPINFOHEADER */
1234         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1235         dib->dsBmih.biWidth = width;
1236         dib->dsBmih.biHeight = height;
1237         dib->dsBmih.biPlanes = planes;
1238         dib->dsBmih.biBitCount = bpp;
1239         dib->dsBmih.biCompression = compression;
1240         dib->dsBmih.biXPelsPerMeter = 0;
1241         dib->dsBmih.biYPelsPerMeter = 0;
1242         dib->dsBmih.biClrUsed = 0;
1243         dib->dsBmih.biClrImportant = 0;
1244     }
1245     else
1246     {
1247         /* truncate extended bitmap headers (BITMAPV4HEADER etc.) */
1248         dib->dsBmih = bmi->bmiHeader;
1249         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1250     }
1251 
1252     /* set number of entries in bmi.bmiColors table */
1253     if( bpp <= 8 )
1254         dib->dsBmih.biClrUsed = 1 << bpp;
1255 
1256     dib->dsBmih.biSizeImage = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
1257 
1258     /* set dsBitfields values */
1259     dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1260 
1261     if((bpp == 15 || bpp == 16) && compression == BI_RGB)
1262     {
1263         /* In this case Windows changes biCompression to BI_BITFIELDS,
1264            however for now we won't do this, as there are a lot
1265            of places where BI_BITFIELDS is currently unsupported. */
1266 
1267         /* dib->dsBmih.biCompression = compression = BI_BITFIELDS;*/
1268         dib->dsBitfields[0] = 0x7c00;
1269         dib->dsBitfields[1] = 0x03e0;
1270         dib->dsBitfields[2] = 0x001f;
1271     }
1272     else if(compression == BI_BITFIELDS)
1273     {
1274         dib->dsBitfields[0] =  *(const DWORD *)bmi->bmiColors;
1275         dib->dsBitfields[1] =  *((const DWORD *)bmi->bmiColors + 1);
1276         dib->dsBitfields[2] =  *((const DWORD *)bmi->bmiColors + 2);
1277     }
1278 
1279     /* get storage location for DIB bits */
1280 
1281     if (section)
1282     {
1283         SYSTEM_INFO SystemInfo;
1284         DWORD mapOffset;
1285         INT mapSize;
1286 
1287         GetSystemInfo( &SystemInfo );
1288         mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1289         mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1290         mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1291         if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1292     }
1293     else
1294     {
1295         offset = 0;
1296         dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1297                                          MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1298     }
1299     dib->dshSection = section;
1300     dib->dsOffset = offset;
1301 
1302     if (!dib->dsBm.bmBits)
1303     {
1304         HeapFree( GetProcessHeap(), 0, dib );
1305         return 0;
1306     }
1307 
1308     /* If the reference hdc is null, take the desktop dc */
1309     if (hdc == 0)
1310     {
1311         hdc = CreateCompatibleDC(0);
1312         bDesktopDC = TRUE;
1313     }
1314 
1315     if (!(dc = get_dc_ptr( hdc ))) goto error;
1316 
1317     /* create Device Dependent Bitmap and add DIB pointer */
1318     ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1319                         (bpp == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1320 
1321     if (ret && ((bmp = GDI_GetObjPtr(ret, OBJ_BITMAP))))
1322     {
1323         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pCreateDIBSection );
1324         bmp->dib = dib;
1325         bmp->funcs = physdev->funcs;
1326         /* create local copy of DIB palette */
1327         if (bpp <= 8) DIB_CopyColorTable( dc, bmp, usage, bmi );
1328         GDI_ReleaseObj( ret );
1329 
1330         if (!physdev->funcs->pCreateDIBSection( physdev, ret, bmi, usage ))
1331         {
1332             DeleteObject( ret );
1333             ret = 0;
1334         }
1335     }
1336 
1337     release_dc_ptr( dc );
1338     if (bDesktopDC) DeleteDC( hdc );
1339     if (ret && bits) *bits = dib->dsBm.bmBits;
1340     return ret;
1341 
1342 error:
1343     if (bDesktopDC) DeleteDC( hdc );
1344     if (section) UnmapViewOfFile( mapBits );
1345     else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1346     HeapFree( GetProcessHeap(), 0, dib );
1347     return 0;
1348 }
1349 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.