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

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

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

~ [ 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.