~ [ 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 static 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 = (BITMAPOBJ *)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC )))
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 (!(dc = get_dc_ptr( hdc )))
340     {
341         if (coloruse == DIB_RGB_COLORS) FIXME( "shouldn't require a DC for DIB_RGB_COLORS\n" );
342         return 0;
343     }
344 
345     update_dc( dc );
346 
347     if (!(bitmap = GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
348     {
349         release_dc_ptr( dc );
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     return result;
369 }
370 
371 
372 /***********************************************************************
373  *           SetDIBitsToDevice   (GDI32.@)
374  */
375 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
376                            DWORD cy, INT xSrc, INT ySrc, UINT startscan,
377                            UINT lines, LPCVOID bits, const BITMAPINFO *info,
378                            UINT coloruse )
379 {
380     INT ret;
381     DC *dc;
382 
383     if (!bits) return 0;
384 
385     if (!(dc = get_dc_ptr( hdc ))) return 0;
386 
387     if(dc->funcs->pSetDIBitsToDevice)
388     {
389         update_dc( dc );
390         ret = dc->funcs->pSetDIBitsToDevice( dc->physDev, xDest, yDest, cx, cy, xSrc,
391                                              ySrc, startscan, lines, bits,
392                                              info, coloruse );
393     }
394     else {
395         FIXME("unimplemented on hdc %p\n", hdc);
396         ret = 0;
397     }
398 
399     release_dc_ptr( dc );
400     return ret;
401 }
402 
403 /***********************************************************************
404  *           SetDIBColorTable    (GDI32.@)
405  */
406 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUAD *colors )
407 {
408     DC * dc;
409     UINT result = 0;
410     BITMAPOBJ * bitmap;
411 
412     if (!(dc = get_dc_ptr( hdc ))) return 0;
413 
414     if ((bitmap = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC )))
415     {
416         /* Check if currently selected bitmap is a DIB */
417         if (bitmap->color_table)
418         {
419             if (startpos < bitmap->nb_colors)
420             {
421                 if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
422                 memcpy(bitmap->color_table + startpos, colors, entries * sizeof(RGBQUAD));
423                 result = entries;
424             }
425         }
426         GDI_ReleaseObj( dc->hBitmap );
427     }
428 
429     if (dc->funcs->pSetDIBColorTable)
430         dc->funcs->pSetDIBColorTable(dc->physDev, startpos, entries, colors);
431 
432     release_dc_ptr( dc );
433     return result;
434 }
435 
436 
437 /***********************************************************************
438  *           GetDIBColorTable    (GDI32.@)
439  */
440 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
441 {
442     DC * dc;
443     UINT result = 0;
444 
445     if (!(dc = get_dc_ptr( hdc ))) return 0;
446 
447     if (dc->funcs->pGetDIBColorTable)
448         result = dc->funcs->pGetDIBColorTable(dc->physDev, startpos, entries, colors);
449     else
450     {
451         BITMAPOBJ *bitmap = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
452         if (bitmap)
453         {
454             /* Check if currently selected bitmap is a DIB */
455             if (bitmap->color_table)
456             {
457                 if (startpos < bitmap->nb_colors)
458                 {
459                     if (startpos + entries > bitmap->nb_colors) entries = bitmap->nb_colors - startpos;
460                     memcpy(colors, bitmap->color_table + startpos, entries * sizeof(RGBQUAD));
461                     result = entries;
462                 }
463             }
464             GDI_ReleaseObj( dc->hBitmap );
465         }
466     }
467     release_dc_ptr( dc );
468     return result;
469 }
470 
471 /* FIXME the following two structs should be combined with __sysPalTemplate in
472    objects/color.c - this should happen after de-X11-ing both of these
473    files.
474    NB. RGBQUAD and PALETTEENTRY have different orderings of red, green
475    and blue - sigh */
476 
477 static const RGBQUAD EGAColorsQuads[16] = {
478 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
479     { 0x00, 0x00, 0x00, 0x00 },
480     { 0x00, 0x00, 0x80, 0x00 },
481     { 0x00, 0x80, 0x00, 0x00 },
482     { 0x00, 0x80, 0x80, 0x00 },
483     { 0x80, 0x00, 0x00, 0x00 },
484     { 0x80, 0x00, 0x80, 0x00 },
485     { 0x80, 0x80, 0x00, 0x00 },
486     { 0x80, 0x80, 0x80, 0x00 },
487     { 0xc0, 0xc0, 0xc0, 0x00 },
488     { 0x00, 0x00, 0xff, 0x00 },
489     { 0x00, 0xff, 0x00, 0x00 },
490     { 0x00, 0xff, 0xff, 0x00 },
491     { 0xff, 0x00, 0x00, 0x00 },
492     { 0xff, 0x00, 0xff, 0x00 },
493     { 0xff, 0xff, 0x00, 0x00 },
494     { 0xff, 0xff, 0xff, 0x00 }
495 };
496 
497 static const RGBTRIPLE EGAColorsTriples[16] = {
498 /* rgbBlue, rgbGreen, rgbRed */
499     { 0x00, 0x00, 0x00 },
500     { 0x00, 0x00, 0x80 },
501     { 0x00, 0x80, 0x00 },
502     { 0x00, 0x80, 0x80 },
503     { 0x80, 0x00, 0x00 },
504     { 0x80, 0x00, 0x80 },
505     { 0x80, 0x80, 0x00 },
506     { 0x80, 0x80, 0x80 },
507     { 0xc0, 0xc0, 0xc0 },
508     { 0x00, 0x00, 0xff },
509     { 0x00, 0xff, 0x00 },
510     { 0x00, 0xff, 0xff },
511     { 0xff, 0x00, 0x00 } ,
512     { 0xff, 0x00, 0xff },
513     { 0xff, 0xff, 0x00 },
514     { 0xff, 0xff, 0xff }
515 };
516 
517 static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
518 /* rgbBlue, rgbGreen, rgbRed, rgbReserved */
519     { 0x00, 0x00, 0x00, 0x00 },
520     { 0x00, 0x00, 0x80, 0x00 },
521     { 0x00, 0x80, 0x00, 0x00 },
522     { 0x00, 0x80, 0x80, 0x00 },
523     { 0x80, 0x00, 0x00, 0x00 },
524     { 0x80, 0x00, 0x80, 0x00 },
525     { 0x80, 0x80, 0x00, 0x00 },
526     { 0xc0, 0xc0, 0xc0, 0x00 },
527     { 0xc0, 0xdc, 0xc0, 0x00 },
528     { 0xf0, 0xca, 0xa6, 0x00 },
529     { 0xf0, 0xfb, 0xff, 0x00 },
530     { 0xa4, 0xa0, 0xa0, 0x00 },
531     { 0x80, 0x80, 0x80, 0x00 },
532     { 0x00, 0x00, 0xf0, 0x00 },
533     { 0x00, 0xff, 0x00, 0x00 },
534     { 0x00, 0xff, 0xff, 0x00 },
535     { 0xff, 0x00, 0x00, 0x00 },
536     { 0xff, 0x00, 0xff, 0x00 },
537     { 0xff, 0xff, 0x00, 0x00 },
538     { 0xff, 0xff, 0xff, 0x00 }
539 };
540 
541 static const RGBTRIPLE DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
542 /* rgbBlue, rgbGreen, rgbRed */
543     { 0x00, 0x00, 0x00 },
544     { 0x00, 0x00, 0x80 },
545     { 0x00, 0x80, 0x00 },
546     { 0x00, 0x80, 0x80 },
547     { 0x80, 0x00, 0x00 },
548     { 0x80, 0x00, 0x80 },
549     { 0x80, 0x80, 0x00 },
550     { 0xc0, 0xc0, 0xc0 },
551     { 0xc0, 0xdc, 0xc0 },
552     { 0xf0, 0xca, 0xa6 },
553     { 0xf0, 0xfb, 0xff },
554     { 0xa4, 0xa0, 0xa0 },
555     { 0x80, 0x80, 0x80 },
556     { 0x00, 0x00, 0xf0 },
557     { 0x00, 0xff, 0x00 },
558     { 0x00, 0xff, 0xff },
559     { 0xff, 0x00, 0x00 },
560     { 0xff, 0x00, 0xff },
561     { 0xff, 0xff, 0x00 },
562     { 0xff, 0xff, 0xff}
563 };
564 
565 
566 /******************************************************************************
567  * GetDIBits [GDI32.@]
568  *
569  * Retrieves bits of bitmap and copies to buffer.
570  *
571  * RETURNS
572  *    Success: Number of scan lines copied from bitmap
573  *    Failure: 0
574  */
575 INT WINAPI GetDIBits(
576     HDC hdc,         /* [in]  Handle to device context */
577     HBITMAP hbitmap, /* [in]  Handle to bitmap */
578     UINT startscan,  /* [in]  First scan line to set in dest bitmap */
579     UINT lines,      /* [in]  Number of scan lines to copy */
580     LPVOID bits,       /* [out] Address of array for bitmap bits */
581     BITMAPINFO * info, /* [out] Address of structure with bitmap data */
582     UINT coloruse)   /* [in]  RGB or palette index */
583 {
584     DC * dc;
585     BITMAPOBJ * bmp;
586     int i;
587     int bitmap_type;
588     BOOL core_header;
589     LONG width;
590     LONG height;
591     WORD planes, bpp;
592     DWORD compr, size;
593     void* colorPtr;
594     RGBTRIPLE* rgbTriples;
595     RGBQUAD* rgbQuads;
596 
597     if (!info) return 0;
598 
599     bitmap_type = DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &planes, &bpp, &compr, &size);
600     if (bitmap_type == -1)
601     {
602         ERR("Invalid bitmap format\n");
603         return 0;
604     }
605     core_header = (bitmap_type == 0);
606     if (!(dc = get_dc_ptr( hdc )))
607     {
608         SetLastError( ERROR_INVALID_PARAMETER );
609         return 0;
610     }
611     update_dc( dc );
612     if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
613     {
614         release_dc_ptr( dc );
615         return 0;
616     }
617 
618     colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
619     rgbTriples = (RGBTRIPLE *) colorPtr;
620     rgbQuads = (RGBQUAD *) colorPtr;
621 
622     /* Transfer color info */
623 
624     switch (bpp)
625     {
626     case 0:  /* query bitmap info only */
627         if (core_header)
628         {
629             BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
630             coreheader->bcWidth = bmp->bitmap.bmWidth;
631             coreheader->bcHeight = bmp->bitmap.bmHeight;
632             coreheader->bcPlanes = 1;
633             coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
634         }
635         else
636         {
637             info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
638             info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
639             info->bmiHeader.biPlanes = 1;
640             info->bmiHeader.biSizeImage =
641                 DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
642                                       bmp->bitmap.bmHeight,
643                                       bmp->bitmap.bmBitsPixel );
644             info->bmiHeader.biCompression = (bmp->bitmap.bmBitsPixel > 8) ? BI_BITFIELDS : BI_RGB;
645             switch(bmp->bitmap.bmBitsPixel)
646             {
647             case 15:
648                 info->bmiHeader.biBitCount = 16;
649                 break;
650             case 24:
651                 info->bmiHeader.biBitCount = 32;
652                 break;
653             default:
654                 info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
655                 break;
656             }
657             info->bmiHeader.biXPelsPerMeter = 0;
658             info->bmiHeader.biYPelsPerMeter = 0;
659             info->bmiHeader.biClrUsed = 0;
660             info->bmiHeader.biClrImportant = 0;
661 
662             /* Windows 2000 doesn't touch the additional struct members if
663                it's a BITMAPV4HEADER or a BITMAPV5HEADER */
664         }
665         lines = abs(bmp->bitmap.bmHeight);
666         goto done;
667 
668     case 1:
669     case 4:
670     case 8:
671         if (!core_header) info->bmiHeader.biClrUsed = 0;
672 
673         /* If the bitmap object already has a dib section at the
674            same color depth then get the color map from it */
675         if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == bpp) {
676             if(coloruse == DIB_RGB_COLORS) {
677                 unsigned int colors = min( bmp->nb_colors, 1 << bpp );
678 
679                 if (core_header)
680                 {
681                     /* Convert the color table (RGBQUAD to RGBTRIPLE) */
682                     RGBTRIPLE* index = rgbTriples;
683 
684                     for (i=0; i < colors; i++, index++)
685                     {
686                         index->rgbtRed   = bmp->color_table[i].rgbRed;
687                         index->rgbtGreen = bmp->color_table[i].rgbGreen;
688                         index->rgbtBlue  = bmp->color_table[i].rgbBlue;
689                     }
690                 }
691                 else
692                 {
693                     if (colors != 1 << bpp) info->bmiHeader.biClrUsed = colors;
694                     memcpy(colorPtr, bmp->color_table, colors * sizeof(RGBQUAD));
695                 }
696             }
697             else {
698                 WORD *index = colorPtr;
699                 for(i = 0; i < 1 << info->bmiHeader.biBitCount; i++, index++)
700                     *index = i;
701             }
702         }
703         else {
704             if (coloruse == DIB_PAL_COLORS) {
705                 for (i = 0; i < (1 << bpp); i++)
706                     ((WORD *)colorPtr)[i] = (WORD)i;
707             }
708             else if(bpp >= bmp->bitmap.bmBitsPixel) {
709                 /* Generate the color map from the selected palette */
710                 PALETTEENTRY palEntry[256];
711 
712                 memset( palEntry, 0, sizeof(palEntry) );
713                 if (!GetPaletteEntries( dc->hPalette, 0, 1 << bmp->bitmap.bmBitsPixel, palEntry ))
714                 {
715                     release_dc_ptr( dc );
716                     GDI_ReleaseObj( hbitmap );
717                     return 0;
718                 }
719                 for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++) {
720                     if (core_header)
721                     {
722                         rgbTriples[i].rgbtRed   = palEntry[i].peRed;
723                         rgbTriples[i].rgbtGreen = palEntry[i].peGreen;
724                         rgbTriples[i].rgbtBlue  = palEntry[i].peBlue;
725                     }
726                     else
727                     {
728                         rgbQuads[i].rgbRed      = palEntry[i].peRed;
729                         rgbQuads[i].rgbGreen    = palEntry[i].peGreen;
730                         rgbQuads[i].rgbBlue     = palEntry[i].peBlue;
731                         rgbQuads[i].rgbReserved = 0;
732                     }
733                 }
734             } else {
735                 switch (bpp) {
736                 case 1:
737                     if (core_header)
738                     {
739                         rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
740                             rgbTriples[0].rgbtBlue = 0;
741                         rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
742                             rgbTriples[1].rgbtBlue = 0xff;
743                     }
744                     else
745                     {    
746                         rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
747                             rgbQuads[0].rgbBlue = 0;
748                         rgbQuads[0].rgbReserved = 0;
749                         rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
750                             rgbQuads[1].rgbBlue = 0xff;
751                         rgbQuads[1].rgbReserved = 0;
752                     }
753                     break;
754 
755                 case 4:
756                     if (core_header)
757                         memcpy(colorPtr, EGAColorsTriples, sizeof(EGAColorsTriples));
758                     else
759                         memcpy(colorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
760 
761                     break;
762 
763                 case 8:
764                     {
765                         if (core_header)
766                         {
767                             INT r, g, b;
768                             RGBTRIPLE *color;
769 
770                             memcpy(rgbTriples, DefLogPaletteTriples,
771                                        10 * sizeof(RGBTRIPLE));
772                             memcpy(rgbTriples + 246, DefLogPaletteTriples + 10,
773                                        10 * sizeof(RGBTRIPLE));
774                             color = rgbTriples + 10;
775                             for(r = 0; r <= 5; r++) /* FIXME */
776                                 for(g = 0; g <= 5; g++)
777                                     for(b = 0; b <= 5; b++) {
778                                         color->rgbtRed =   (r * 0xff) / 5;
779                                         color->rgbtGreen = (g * 0xff) / 5;
780                                         color->rgbtBlue =  (b * 0xff) / 5;
781                                         color++;
782                                     }
783                         }
784                         else
785                         {
786                             INT r, g, b;
787                             RGBQUAD *color;
788 
789                             memcpy(rgbQuads, DefLogPaletteQuads,
790                                        10 * sizeof(RGBQUAD));
791                             memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
792                                    10 * sizeof(RGBQUAD));
793                             color = rgbQuads + 10;
794                             for(r = 0; r <= 5; r++) /* FIXME */
795                                 for(g = 0; g <= 5; g++)
796                                     for(b = 0; b <= 5; b++) {
797                                         color->rgbRed =   (r * 0xff) / 5;
798                                         color->rgbGreen = (g * 0xff) / 5;
799                                         color->rgbBlue =  (b * 0xff) / 5;
800                                         color->rgbReserved = 0;
801                                         color++;
802                                     }
803                         }
804                     }
805                 }
806             }
807         }
808         break;
809 
810     case 15:
811         if (info->bmiHeader.biCompression == BI_BITFIELDS)
812         {
813             ((PDWORD)info->bmiColors)[0] = 0x7c00;
814             ((PDWORD)info->bmiColors)[1] = 0x03e0;
815             ((PDWORD)info->bmiColors)[2] = 0x001f;
816         }
817         break;
818 
819     case 16:
820         if (info->bmiHeader.biCompression == BI_BITFIELDS)
821         {
822             ((PDWORD)info->bmiColors)[0] = 0xf800;
823             ((PDWORD)info->bmiColors)[1] = 0x07e0;
824             ((PDWORD)info->bmiColors)[2] = 0x001f;
825         }
826         break;
827 
828     case 24:
829     case 32:
830         if (info->bmiHeader.biCompression == BI_BITFIELDS)
831         {
832             ((PDWORD)info->bmiColors)[0] = 0xff0000;
833             ((PDWORD)info->bmiColors)[1] = 0x00ff00;
834             ((PDWORD)info->bmiColors)[2] = 0x0000ff;
835         }
836         break;
837     }
838 
839     if (bits && lines)
840     {
841         /* If the bitmap object already have a dib section that contains image data, get the bits from it */
842         if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
843         {
844             /*FIXME: Only RGB dibs supported for now */
845             unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb = bmp->dib->dsBm.bmWidthBytes;
846             unsigned int dstwidth = width;
847             int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
848             LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
849             unsigned int x, y, width, widthb;
850 
851             if ((height < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
852             {
853                 dbits = (LPBYTE)bits + (dstwidthb * (lines-1));
854                 dstwidthb = -dstwidthb;
855             }
856 
857             switch( bpp ) {
858 
859             case 15:
860             case 16: /* 16 bpp dstDIB */
861                 {
862                     LPWORD dstbits = (LPWORD)dbits;
863                     WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
864 
865                     /* FIXME: BI_BITFIELDS not supported yet */
866 
867                     switch(bmp->dib->dsBm.bmBitsPixel) {
868 
869                     case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
870                         {
871                             widthb = min(srcwidthb, abs(dstwidthb));
872                             /* FIXME: BI_BITFIELDS not supported yet */
873                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
874                                 memcpy(dbits, sbits, widthb);
875                         }
876                         break;
877 
878                     case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
879                         {
880                             LPBYTE srcbits = sbits;
881 
882                             width = min(srcwidth, dstwidth);
883                             for( y = 0; y < lines; y++) {
884                                 for( x = 0; x < width; x++, srcbits += 3)
885                                     *dstbits++ = ((srcbits[0] >> 3) & bmask) |
886                                                  (((WORD)srcbits[1] << 2) & gmask) |
887                                                  (((WORD)srcbits[2] << 7) & rmask);
888 
889                                 dstbits = (LPWORD)(dbits+=dstwidthb);
890                                 srcbits = (sbits += srcwidthb);
891                             }
892                         }
893                         break;
894 
895                     case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
896                         {
897                             LPDWORD srcbits = (LPDWORD)sbits;
898                             DWORD val;
899 
900                             width = min(srcwidth, dstwidth);
901                             for( y = 0; y < lines; y++) {
902                                 for( x = 0; x < width; x++ ) {
903                                     val = *srcbits++;
904                                     *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
905                                                        ((val >> 9) & rmask));
906                                 }
907                                 dstbits = (LPWORD)(dbits+=dstwidthb);
908                                 srcbits = (LPDWORD)(sbits+=srcwidthb);
909                             }
910                         }
911                         break;
912 
913                     default: /* ? bit bmp -> 16 bit DIB */
914                         FIXME("15/16 bit DIB %d bit bitmap\n",
915                         bmp->bitmap.bmBitsPixel);
916                         break;
917                     }
918                 }
919                 break;
920 
921             case 24: /* 24 bpp dstDIB */
922                 {
923                     LPBYTE dstbits = dbits;
924 
925                     switch(bmp->dib->dsBm.bmBitsPixel) {
926 
927                     case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
928                         {
929                             LPWORD srcbits = (LPWORD)sbits;
930                             WORD val;
931 
932                             width = min(srcwidth, dstwidth);
933                             /* FIXME: BI_BITFIELDS not supported yet */
934                             for( y = 0; y < lines; y++) {
935                                 for( x = 0; x < width; x++ ) {
936                                     val = *srcbits++;
937                                     *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
938                                     *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
939                                     *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
940                                 }
941                                 dstbits = dbits+=dstwidthb;
942                                 srcbits = (LPWORD)(sbits+=srcwidthb);
943                             }
944                         }
945                         break;
946 
947                     case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
948                         {
949                             widthb = min(srcwidthb, abs(dstwidthb));
950                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
951                                 memcpy(dbits, sbits, widthb);
952                         }
953                         break;
954 
955                     case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
956                         {
957                             LPBYTE srcbits = sbits;
958 
959                             width = min(srcwidth, dstwidth);
960                             for( y = 0; y < lines; y++) {
961                                 for( x = 0; x < width; x++, srcbits++ ) {
962                                     *dstbits++ = *srcbits++;
963                                     *dstbits++ = *srcbits++;
964                                     *dstbits++ = *srcbits++;
965                                 }
966                                 dstbits = dbits+=dstwidthb;
967                                 srcbits = sbits+=srcwidthb;
968                             }
969                         }
970                         break;
971 
972                     default: /* ? bit bmp -> 24 bit DIB */
973                         FIXME("24 bit DIB %d bit bitmap\n",
974                               bmp->bitmap.bmBitsPixel);
975                         break;
976                     }
977                 }
978                 break;
979 
980             case 32: /* 32 bpp dstDIB */
981                 {
982                     LPDWORD dstbits = (LPDWORD)dbits;
983 
984                     /* FIXME: BI_BITFIELDS not supported yet */
985 
986                     switch(bmp->dib->dsBm.bmBitsPixel) {
987                         case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
988                         {
989                             LPWORD srcbits = (LPWORD)sbits;
990                             DWORD val;
991 
992                             width = min(srcwidth, dstwidth);
993                             /* FIXME: BI_BITFIELDS not supported yet */
994                             for( y = 0; y < lines; y++) {
995                                 for( x = 0; x < width; x++ ) {
996                                     val = (DWORD)*srcbits++;
997                                     *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
998                                                  ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
999                                                  ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
1000                                 }
1001                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
1002                                 srcbits=(LPWORD)(sbits+=srcwidthb);
1003                             }
1004                         }
1005                         break;
1006 
1007                     case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
1008                         {
1009                             LPBYTE srcbits = sbits;
1010 
1011                             width = min(srcwidth, dstwidth);
1012                             for( y = 0; y < lines; y++) {
1013                                 for( x = 0; x < width; x++, srcbits+=3 )
1014                                     *dstbits++ =  srcbits[0] |
1015                                                  (srcbits[1] <<  8) |
1016                                                  (srcbits[2] << 16);
1017                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
1018                                 srcbits=(sbits+=srcwidthb);
1019                             }
1020                         }
1021                         break;
1022 
1023                     case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
1024                         {
1025                             widthb = min(srcwidthb, abs(dstwidthb));
1026                             /* FIXME: BI_BITFIELDS not supported yet */
1027                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
1028                                 memcpy(dbits, sbits, widthb);
1029                             }
1030                         }
1031                         break;
1032 
1033                     default: /* ? bit bmp -> 32 bit DIB */
1034                         FIXME("32 bit DIB %d bit bitmap\n",
1035                         bmp->bitmap.bmBitsPixel);
1036                         break;
1037                     }
1038                 }
1039                 break;
1040 
1041             default: /* ? bit DIB */
1042                 FIXME("Unsupported DIB depth %d\n", info->bmiHeader.biBitCount);
1043                 break;
1044             }
1045         }
1046         /* Otherwise, get bits from the XImage */
1047         else
1048         {
1049             if (!bmp->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) lines = 0;
1050             else
1051             {
1052                 if (bmp->funcs && bmp->funcs->pGetDIBits)
1053                     lines = bmp->funcs->pGetDIBits( dc->physDev, hbitmap, startscan,
1054                                                     lines, bits, info, coloruse );
1055                 else
1056                     lines = 0;  /* FIXME: should copy from bmp->bitmap.bmBits */
1057             }
1058         }
1059     }
1060     else lines = abs(height);
1061 
1062     /* The knowledge base article Q81498 ("DIBs and Their Uses") states that
1063        if bits == NULL and bpp != 0, only biSizeImage and the color table are
1064        filled in. */
1065     if (!core_header)
1066     {
1067         /* FIXME: biSizeImage should be calculated according to the selected
1068            compression algorithm if biCompression != BI_RGB */
1069         info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp );
1070         TRACE("biSizeImage = %d, ", info->bmiHeader.biSizeImage);
1071     }
1072     TRACE("biWidth = %d, biHeight = %d\n", width, height);
1073 
1074 done:
1075     release_dc_ptr( dc );
1076     GDI_ReleaseObj( hbitmap );
1077     return lines;
1078 }
1079 
1080 
1081 /***********************************************************************
1082  *           CreateDIBitmap    (GDI32.@)
1083  *
1084  * Creates a DDB (device dependent bitmap) from a DIB.
1085  * The DDB will have the same color depth as the reference DC.
1086  */
1087 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
1088                             DWORD init, LPCVOID bits, const BITMAPINFO *data,
1089                             UINT coloruse )
1090 {
1091     HBITMAP handle;
1092     LONG width;
1093     LONG height;
1094     WORD planes, bpp;
1095     DWORD compr, size;
1096     DC *dc;
1097 
1098     if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &size ) == -1) return 0;
1099     
1100     if (width < 0)
1101     {
1102         TRACE("Bitmap has a negative width\n");
1103         return 0;
1104     }
1105     
1106     /* Top-down DIBs have a negative height */
1107     if (height < 0) height = -height;
1108 
1109     TRACE("hdc=%p, header=%p, init=%u, bits=%p, data=%p, coloruse=%u (bitmap: width=%d, height=%d, bpp=%u, compr=%u)\n",
1110            hdc, header, init, bits, data, coloruse, width, height, bpp, compr);
1111     
1112     if (hdc == NULL)
1113         handle = CreateBitmap( width, height, 1, 1, NULL );
1114     else
1115         handle = CreateCompatibleBitmap( hdc, width, height );
1116 
1117     if (handle)
1118     {
1119         if (init == CBM_INIT) SetDIBits( hdc, handle, 0, height, bits, data, coloruse );
1120 
1121         else if (hdc && ((dc = get_dc_ptr( hdc )) != NULL) )
1122         {
1123             if (!BITMAP_SetOwnerDC( handle, dc ))
1124             {
1125                 DeleteObject( handle );
1126                 handle = 0;
1127             }
1128             release_dc_ptr( dc );
1129         }
1130     }
1131 
1132     return handle;
1133 }
1134 
1135 /***********************************************************************
1136  *           CreateDIBSection    (GDI.489)
1137  */
1138 HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, const BITMAPINFO *bmi, UINT16 usage,
1139                                      SEGPTR *bits16, HANDLE section, DWORD offset)
1140 {
1141     LPVOID bits32;
1142     HBITMAP hbitmap;
1143 
1144     hbitmap = CreateDIBSection( HDC_32(hdc), bmi, usage, &bits32, section, offset );
1145     if (hbitmap)
1146     {
1147         BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(hbitmap, BITMAP_MAGIC);
1148         if (bmp && bmp->dib && bits32)
1149         {
1150             const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
1151             LONG width, height;
1152             WORD planes, bpp;
1153             DWORD compr, size;
1154             INT width_bytes;
1155             WORD count, sel;
1156             int i;
1157 
1158             DIB_GetBitmapInfo(bi, &width, &height, &planes, &bpp, &compr, &size);
1159 
1160             height = height >= 0 ? height : -height;
1161             width_bytes = DIB_GetDIBWidthBytes(width, bpp);
1162 
1163             if (!size || (compr != BI_RLE4 && compr != BI_RLE8)) size = width_bytes * height;
1164 
1165             /* calculate number of sel's needed for size with 64K steps */
1166             count = (size + 0xffff) / 0x10000;
1167             sel = AllocSelectorArray16(count);
1168 
1169             for (i = 0; i < count; i++)
1170             {
1171                 SetSelectorBase(sel + (i << __AHSHIFT), (DWORD)bits32 + i * 0x10000);
1172                 SetSelectorLimit16(sel + (i << __AHSHIFT), size - 1); /* yep, limit is correct */
1173                 size -= 0x10000;
1174             }
1175             bmp->segptr_bits = MAKESEGPTR( sel, 0 );
1176             if (bits16) *bits16 = bmp->segptr_bits;
1177         }
1178         if (bmp) GDI_ReleaseObj( hbitmap );
1179     }
1180     return HBITMAP_16(hbitmap);
1181 }
1182 
1183 /* Copy/synthesize RGB palette from BITMAPINFO. Ripped from dlls/winex11.drv/dib.c */
1184 static void DIB_CopyColorTable( DC *dc, BITMAPOBJ *bmp, WORD coloruse, const BITMAPINFO *info )
1185 {
1186     RGBQUAD *colorTable;
1187     unsigned int colors;
1188     int i;
1189     BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
1190 
1191     if (core_info)
1192     {
1193         colors = 1 << ((const BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
1194     }
1195     else
1196     {
1197         colors = info->bmiHeader.biClrUsed;
1198         if (!colors) colors = 1 << info->bmiHeader.biBitCount;
1199     }
1200 
1201     if (colors > 256) {
1202         ERR("called with >256 colors!\n");
1203         return;
1204     }
1205 
1206     if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) ))) return;
1207 
1208     if(coloruse == DIB_RGB_COLORS)
1209     {
1210         if (core_info)
1211         {
1212            /* Convert RGBTRIPLEs to RGBQUADs */
1213            for (i=0; i < colors; i++)
1214            {
1215                colorTable[i].rgbRed   = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
1216                colorTable[i].rgbGreen = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
1217                colorTable[i].rgbBlue  = ((const BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
1218                colorTable[i].rgbReserved = 0;
1219            }
1220         }
1221         else
1222         {
1223             memcpy(colorTable, (const BYTE*) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
1224         }
1225     }
1226     else
1227     {
1228         PALETTEENTRY entries[256];
1229         const WORD *index = (const WORD*) ((const BYTE*) info + (WORD) info->bmiHeader.biSize);
1230         UINT count = GetPaletteEntries( dc->hPalette, 0, colors, entries );
1231 
1232         for (i = 0; i < colors; i++, index++)
1233         {
1234             PALETTEENTRY *entry = &entries[*index % count];
1235             colorTable[i].rgbRed = entry->peRed;
1236             colorTable[i].rgbGreen = entry->peGreen;
1237             colorTable[i].rgbBlue = entry->peBlue;
1238             colorTable[i].rgbReserved = 0;
1239         }
1240     }
1241     bmp->color_table = colorTable;
1242     bmp->nb_colors = colors;
1243 }
1244 
1245 /***********************************************************************
1246  *           CreateDIBSection    (GDI32.@)
1247  */
1248 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
1249                                 VOID **bits, HANDLE section, DWORD offset)
1250 {
1251     HBITMAP ret = 0;
1252     DC *dc;
1253     BOOL bDesktopDC = FALSE;
1254     DIBSECTION *dib;
1255     BITMAPOBJ *bmp;
1256     int bitmap_type;
1257     LONG width, height;
1258     WORD planes, bpp;
1259     DWORD compression, sizeImage;
1260     void *mapBits = NULL;
1261 
1262     if(!bmi){
1263         if(bits) *bits = NULL;
1264         return NULL;
1265     }
1266 
1267     if (((bitmap_type = DIB_GetBitmapInfo( &bmi->bmiHeader, &width, &height,
1268                                            &planes, &bpp, &compression, &sizeImage )) == -1))
1269         return 0;
1270 
1271     if (compression != BI_RGB && compression != BI_BITFIELDS)
1272     {
1273         TRACE("can't create a compressed (%u) dibsection\n", compression);
1274         return 0;
1275     }
1276 
1277     if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) return 0;
1278 
1279     TRACE("format (%d,%d), planes %d, bpp %d, size %d, %s\n",
1280           width, height, planes, bpp, sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
1281 
1282     dib->dsBm.bmType       = 0;
1283     dib->dsBm.bmWidth      = width;
1284     dib->dsBm.bmHeight     = height >= 0 ? height : -height;
1285     dib->dsBm.bmWidthBytes = DIB_GetDIBWidthBytes(width, bpp);
1286     dib->dsBm.bmPlanes     = planes;
1287     dib->dsBm.bmBitsPixel  = bpp;
1288     dib->dsBm.bmBits       = NULL;
1289 
1290     if (!bitmap_type)  /* core header */
1291     {
1292         /* convert the BITMAPCOREHEADER to a BITMAPINFOHEADER */
1293         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1294         dib->dsBmih.biWidth = width;
1295         dib->dsBmih.biHeight = height;
1296         dib->dsBmih.biPlanes = planes;
1297         dib->dsBmih.biBitCount = bpp;
1298         dib->dsBmih.biCompression = compression;
1299         dib->dsBmih.biXPelsPerMeter = 0;
1300         dib->dsBmih.biYPelsPerMeter = 0;
1301         dib->dsBmih.biClrUsed = 0;
1302         dib->dsBmih.biClrImportant = 0;
1303     }
1304     else
1305     {
1306         /* truncate extended bitmap headers (BITMAPV4HEADER etc.) */
1307         dib->dsBmih = bmi->bmiHeader;
1308         dib->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
1309     }
1310 
1311     /* set number of entries in bmi.bmiColors table */
1312     if( bpp <= 8 )
1313         dib->dsBmih.biClrUsed = 1 << bpp;
1314 
1315     dib->dsBmih.biSizeImage = dib->dsBm.bmWidthBytes * dib->dsBm.bmHeight;
1316 
1317     /* set dsBitfields values */
1318     if (usage == DIB_PAL_COLORS || bpp <= 8)
1319     {
1320         dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
1321     }
1322     else switch( bpp )
1323     {
1324     case 15:
1325     case 16:
1326         dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors       : 0x7c00;
1327         dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x03e0;
1328         dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x001f;
1329         break;
1330     case 24:
1331     case 32:
1332         dib->dsBitfields[0] = (compression == BI_BITFIELDS) ? *(const DWORD *)bmi->bmiColors       : 0xff0000;
1333         dib->dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 1) : 0x00ff00;
1334         dib->dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)bmi->bmiColors + 2) : 0x0000ff;
1335         break;
1336     }
1337 
1338     /* get storage location for DIB bits */
1339 
1340     if (section)
1341     {
1342         SYSTEM_INFO SystemInfo;
1343         DWORD mapOffset;
1344         INT mapSize;
1345 
1346         GetSystemInfo( &SystemInfo );
1347         mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
1348         mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset);
1349         mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
1350         if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
1351     }
1352     else
1353     {
1354         offset = 0;
1355         dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage,
1356                                          MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
1357     }
1358     dib->dshSection = section;
1359     dib->dsOffset = offset;
1360 
1361     if (!dib->dsBm.bmBits)
1362     {
1363         HeapFree( GetProcessHeap(), 0, dib );
1364         return 0;
1365     }
1366 
1367     /* If the reference hdc is null, take the desktop dc */
1368     if (hdc == 0)
1369     {
1370         hdc = CreateCompatibleDC(0);
1371         bDesktopDC = TRUE;
1372     }
1373 
1374     if (!(dc = get_dc_ptr( hdc ))) goto error;
1375 
1376     /* create Device Dependent Bitmap and add DIB pointer */
1377     ret = CreateBitmap( dib->dsBm.bmWidth, dib->dsBm.bmHeight, 1,
1378                         (bpp == 1) ? 1 : GetDeviceCaps(hdc, BITSPIXEL), NULL );
1379 
1380     if (ret && ((bmp = GDI_GetObjPtr(ret, BITMAP_MAGIC))))
1381     {
1382         bmp->dib = dib;
1383         bmp->funcs = dc->funcs;
1384         /* create local copy of DIB palette */
1385         if (bpp <= 8) DIB_CopyColorTable( dc, bmp, usage, bmi );
1386         GDI_ReleaseObj( ret );
1387 
1388         if (dc->funcs->pCreateDIBSection)
1389         {
1390             if (!dc->funcs->pCreateDIBSection(dc->physDev, ret, bmi, usage))
1391             {
1392                 DeleteObject( ret );
1393                 ret = 0;
1394             }
1395         }
1396     }
1397 
1398     release_dc_ptr( dc );
1399     if (bDesktopDC) DeleteDC( hdc );
1400     if (ret && bits) *bits = dib->dsBm.bmBits;
1401     return ret;
1402 
1403 error:
1404     if (bDesktopDC) DeleteDC( hdc );
1405     if (section) UnmapViewOfFile( mapBits );
1406     else if (!offset) VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE );
1407     HeapFree( GetProcessHeap(), 0, dib );
1408     return 0;
1409 }
1410 

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