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

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

Version: ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 19  */
 20 
 21 #include <stdarg.h>
 22 #include <stdlib.h>
 23 #include <string.h>
 24 
 25 #include "windef.h"
 26 #include "winbase.h"
 27 #include "gdi.h"
 28 #include "wownt32.h"
 29 #include "gdi_private.h"
 30 #include "wine/debug.h"
 31 
 32 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
 33 
 34 /***********************************************************************
 35  *           DIB_GetDIBWidthBytes
 36  *
 37  * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
 38  * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_87eb.asp
 39  */
 40 int DIB_GetDIBWidthBytes( int width, int depth )
 41 {
 42     int words;
 43 
 44     switch(depth)
 45     {
 46         case 1:  words = (width + 31) / 32; break;
 47         case 4:  words = (width + 7) / 8; break;
 48         case 8:  words = (width + 3) / 4; break;
 49         case 15:
 50         case 16: words = (width + 1) / 2; break;
 51         case 24: words = (width * 3 + 3)/4; break;
 52 
 53         default:
 54             WARN("(%d): Unsupported depth\n", depth );
 55         /* fall through */
 56         case 32:
 57                 words = width;
 58     }
 59     return 4 * words;
 60 }
 61 
 62 /***********************************************************************
 63  *           DIB_GetDIBImageBytes
 64  *
 65  * Return the number of bytes used to hold the image in a DIB bitmap.
 66  */
 67 int DIB_GetDIBImageBytes( int width, int height, int depth )
 68 {
 69     return DIB_GetDIBWidthBytes( width, depth ) * abs( height );
 70 }
 71 
 72 
 73 /***********************************************************************
 74  *           DIB_BitmapInfoSize
 75  *
 76  * Return the size of the bitmap info structure including color table.
 77  */
 78 int DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse )
 79 {
 80     int colors;
 81 
 82     if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
 83     {
 84         BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
 85         colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
 86         return sizeof(BITMAPCOREHEADER) + colors *
 87              ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
 88     }
 89     else  /* assume BITMAPINFOHEADER */
 90     {
 91         colors = info->bmiHeader.biClrUsed;
 92         if (!colors && (info->bmiHeader.biBitCount <= 8))
 93             colors = 1 << info->bmiHeader.biBitCount;
 94         return sizeof(BITMAPINFOHEADER) + colors *
 95                ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
 96     }
 97 }
 98 
 99 
100 /***********************************************************************
101  *           DIB_GetBitmapInfo
102  *
103  * Get the info from a bitmap header.
104  * Return 1 for INFOHEADER, 0 for COREHEADER,
105  * 4 for V4HEADER, 5 for V5HEADER, -1 for error.
106  */
107 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
108                               int *height, WORD *bpp, WORD *compr )
109 {
110     if (header->biSize == sizeof(BITMAPINFOHEADER))
111     {
112         *width  = header->biWidth;
113         *height = header->biHeight;
114         *bpp    = header->biBitCount;
115         *compr  = header->biCompression;
116         return 1;
117     }
118     if (header->biSize == sizeof(BITMAPCOREHEADER))
119     {
120         BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
121         *width  = core->bcWidth;
122         *height = core->bcHeight;
123         *bpp    = core->bcBitCount;
124         *compr  = 0;
125         return 0;
126     }
127     if (header->biSize == sizeof(BITMAPV4HEADER))
128     {
129         BITMAPV4HEADER *v4hdr = (BITMAPV4HEADER *)header;
130         *width  = v4hdr->bV4Width;
131         *height = v4hdr->bV4Height;
132         *bpp    = v4hdr->bV4BitCount;
133         *compr  = v4hdr->bV4V4Compression;
134         return 4;
135     }
136     if (header->biSize == sizeof(BITMAPV5HEADER))
137     {
138         BITMAPV5HEADER *v5hdr = (BITMAPV5HEADER *)header;
139         *width  = v5hdr->bV5Width;
140         *height = v5hdr->bV5Height;
141         *bpp    = v5hdr->bV5BitCount;
142         *compr  = v5hdr->bV5Compression;
143         return 5;
144     }
145     ERR("(%ld): unknown/wrong size for header\n", header->biSize );
146     return -1;
147 }
148 
149 
150 /***********************************************************************
151  *           StretchDIBits   (GDI32.@)
152  */
153 INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
154                        INT heightDst, INT xSrc, INT ySrc, INT widthSrc,
155                        INT heightSrc, const void *bits,
156                        const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
157 {
158     DC *dc;
159 
160     if (!bits || !info)
161         return 0;
162 
163     dc = DC_GetDCUpdate( hdc );
164     if(!dc) return FALSE;
165 
166     if(dc->funcs->pStretchDIBits)
167     {
168         heightSrc = dc->funcs->pStretchDIBits(dc->physDev, xDst, yDst, widthDst,
169                                               heightDst, xSrc, ySrc, widthSrc,
170                                               heightSrc, bits, info, wUsage, dwRop);
171         GDI_ReleaseObj( hdc );
172     }
173     else /* use StretchBlt */
174     {
175         HBITMAP hBitmap, hOldBitmap;
176         HPALETTE hpal = NULL;
177         HDC hdcMem;
178 
179         GDI_ReleaseObj( hdc );
180         hdcMem = CreateCompatibleDC( hdc );
181         hBitmap = CreateCompatibleBitmap(hdc, info->bmiHeader.biWidth,
182                                          info->bmiHeader.biHeight);
183         hOldBitmap = SelectObject( hdcMem, hBitmap );
184         if(wUsage == DIB_PAL_COLORS)
185         {
186             hpal = GetCurrentObject(hdc, OBJ_PAL);
187             hpal = SelectPalette(hdcMem, hpal, FALSE);
188         }
189 
190         if (info->bmiHeader.biCompression == BI_RLE4 ||
191             info->bmiHeader.biCompression == BI_RLE8) {
192 
193            /* when RLE compression is used, there may be some gaps (ie the DIB doesn't
194             * contain all the rectangle described in bmiHeader, but only part of it.
195             * This mean that those undescribed pixels must be left untouched.
196             * So, we first copy on a memory bitmap the current content of the
197             * destination rectangle, blit the DIB bits on top of it - hence leaving
198             * the gaps untouched -, and blitting the rectangle back.
199             * This insure that gaps are untouched on the destination rectangle
200             * Not doing so leads to trashed images (the gaps contain what was on the
201             * memory bitmap => generally black or garbage)
202             * Unfortunately, RLE DIBs without gaps will be slowed down. But this is
203             * another speed vs correctness issue. Anyway, if speed is needed, then the
204             * pStretchDIBits function shall be implemented.
205             * ericP (2000/09/09)
206             */
207 
208             /* copy existing bitmap from destination dc */
209             StretchBlt( hdcMem, xSrc, abs(info->bmiHeader.biHeight) - heightSrc - ySrc,
210                         widthSrc, heightSrc, hdc, xDst, yDst, widthDst, heightDst,
211                         dwRop );
212         }
213 
214         SetDIBits(hdcMem, hBitmap, 0, info->bmiHeader.biHeight, bits,
215                      info, wUsage);
216 
217         /* Origin for DIBitmap may be bottom left (positive biHeight) or top
218            left (negative biHeight) */
219         StretchBlt( hdc, xDst, yDst, widthDst, heightDst,
220                     hdcMem, xSrc, abs(info->bmiHeader.biHeight) - heightSrc - ySrc,
221                     widthSrc, heightSrc, dwRop );
222         if(hpal)
223             SelectPalette(hdcMem, hpal, FALSE);
224         SelectObject( hdcMem, hOldBitmap );
225         DeleteDC( hdcMem );
226         DeleteObject( hBitmap );
227     }
228     return heightSrc;
229 }
230 
231 
232 /******************************************************************************
233  * SetDIBits [GDI32.@]
234  *
235  * Sets pixels in a bitmap using colors from DIB.
236  *
237  * PARAMS
238  *    hdc       [I] Handle to device context
239  *    hbitmap   [I] Handle to bitmap
240  *    startscan [I] Starting scan line
241  *    lines     [I] Number of scan lines
242  *    bits      [I] Array of bitmap bits
243  *    info      [I] Address of structure with data
244  *    coloruse  [I] Type of color indexes to use
245  *
246  * RETURNS
247  *    Success: Number of scan lines copied
248  *    Failure: 0
249  */
250 INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
251                       UINT lines, LPCVOID bits, const BITMAPINFO *info,
252                       UINT coloruse )
253 {
254     DC *dc;
255     BITMAPOBJ *bitmap;
256     INT result = 0;
257 
258     if (!(bitmap = GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
259 
260     if (!(dc = DC_GetDCUpdate( hdc )))
261     {
262         if (coloruse == DIB_RGB_COLORS) FIXME( "shouldn't require a DC for DIB_RGB_COLORS\n" );
263         GDI_ReleaseObj( hbitmap );
264         return 0;
265     }
266 
267     if (!bitmap->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) goto done;
268 
269     if (bitmap->funcs && bitmap->funcs->pSetDIBits)
270         result = bitmap->funcs->pSetDIBits( dc->physDev, hbitmap, startscan, lines,
271                                             bits, info, coloruse );
272     else
273         result = lines;
274 
275  done:
276     GDI_ReleaseObj( hdc );
277     GDI_ReleaseObj( hbitmap );
278     return result;
279 }
280 
281 
282 /***********************************************************************
283  *           SetDIBitsToDevice   (GDI32.@)
284  */
285 INT WINAPI SetDIBitsToDevice(HDC hdc, INT xDest, INT yDest, DWORD cx,
286                            DWORD cy, INT xSrc, INT ySrc, UINT startscan,
287                            UINT lines, LPCVOID bits, const BITMAPINFO *info,
288                            UINT coloruse )
289 {
290     INT ret;
291     DC *dc;
292 
293     if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
294 
295     if(dc->funcs->pSetDIBitsToDevice)
296         ret = dc->funcs->pSetDIBitsToDevice( dc->physDev, xDest, yDest, cx, cy, xSrc,
297                                              ySrc, startscan, lines, bits,
298                                              info, coloruse );
299     else {
300         FIXME("unimplemented on hdc %p\n", hdc);
301         ret = 0;
302     }
303 
304     GDI_ReleaseObj( hdc );
305     return ret;
306 }
307 
308 /***********************************************************************
309  *           SetDIBColorTable    (GDI32.@)
310  */
311 UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
312 {
313     DC * dc;
314     UINT result = 0;
315 
316     if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
317 
318     if (dc->funcs->pSetDIBColorTable)
319         result = dc->funcs->pSetDIBColorTable(dc->physDev, startpos, entries, colors);
320 
321     GDI_ReleaseObj( hdc );
322     return result;
323 }
324 
325 
326 /***********************************************************************
327  *           GetDIBColorTable    (GDI32.@)
328  */
329 UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
330 {
331     DC * dc;
332     UINT result = 0;
333 
334     if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
335 
336     if (dc->funcs->pGetDIBColorTable)
337         result = dc->funcs->pGetDIBColorTable(dc->physDev, startpos, entries, colors);
338 
339     GDI_ReleaseObj( hdc );
340     return result;
341 }
342 
343 /* FIXME the following two structs should be combined with __sysPalTemplate in
344    objects/color.c - this should happen after de-X11-ing both of these
345    files.
346    NB. RGBQUAD and PALETTEENTRY have different orderings of red, green
347    and blue - sigh */
348 
349 static RGBQUAD EGAColors[16] = {
350 /* rgbBlue, rgbGreen, rgbRed, rgbReserverd */
351     { 0x00, 0x00, 0x00, 0x00 },
352     { 0x00, 0x00, 0x80, 0x00 },
353     { 0x00, 0x80, 0x00, 0x00 },
354     { 0x00, 0x80, 0x80, 0x00 },
355     { 0x80, 0x00, 0x00, 0x00 },
356     { 0x80, 0x00, 0x80, 0x00 },
357     { 0x80, 0x80, 0x00, 0x00 },
358     { 0x80, 0x80, 0x80, 0x00 },
359     { 0xc0, 0xc0, 0xc0, 0x00 },
360     { 0x00, 0x00, 0xff, 0x00 },
361     { 0x00, 0xff, 0x00, 0x00 },
362     { 0x00, 0xff, 0xff, 0x00 },
363     { 0xff, 0x00, 0x00, 0x00 },
364     { 0xff, 0x00, 0xff, 0x00 },
365     { 0xff, 0xff, 0x00, 0x00 },
366     { 0xff, 0xff, 0xff, 0x00 }
367 };
368 
369 
370 static RGBQUAD DefLogPalette[20] = { /* Copy of Default Logical Palette */
371 /* rgbBlue, rgbGreen, rgbRed, rgbReserverd */
372     { 0x00, 0x00, 0x00, 0x00 },
373     { 0x00, 0x00, 0x80, 0x00 },
374     { 0x00, 0x80, 0x00, 0x00 },
375     { 0x00, 0x80, 0x80, 0x00 },
376     { 0x80, 0x00, 0x00, 0x00 },
377     { 0x80, 0x00, 0x80, 0x00 },
378     { 0x80, 0x80, 0x00, 0x00 },
379     { 0xc0, 0xc0, 0xc0, 0x00 },
380     { 0xc0, 0xdc, 0xc0, 0x00 },
381     { 0xf0, 0xca, 0xa6, 0x00 },
382     { 0xf0, 0xfb, 0xff, 0x00 },
383     { 0xa4, 0xa0, 0xa0, 0x00 },
384     { 0x80, 0x80, 0x80, 0x00 },
385     { 0x00, 0x00, 0xf0, 0x00 },
386     { 0x00, 0xff, 0x00, 0x00 },
387     { 0x00, 0xff, 0xff, 0x00 },
388     { 0xff, 0x00, 0x00, 0x00 },
389     { 0xff, 0x00, 0xff, 0x00 },
390     { 0xff, 0xff, 0x00, 0x00 },
391     { 0xff, 0xff, 0xff, 0x00 }
392 };
393 
394 
395 /******************************************************************************
396  * GetDIBits [GDI32.@]
397  *
398  * Retrieves bits of bitmap and copies to buffer.
399  *
400  * RETURNS
401  *    Success: Number of scan lines copied from bitmap
402  *    Failure: 0
403  *
404  * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_87eb.asp
405  */
406 INT WINAPI GetDIBits(
407     HDC hdc,         /* [in]  Handle to device context */
408     HBITMAP hbitmap, /* [in]  Handle to bitmap */
409     UINT startscan,  /* [in]  First scan line to set in dest bitmap */
410     UINT lines,      /* [in]  Number of scan lines to copy */
411     LPVOID bits,       /* [out] Address of array for bitmap bits */
412     BITMAPINFO * info, /* [out] Address of structure with bitmap data */
413     UINT coloruse)   /* [in]  RGB or palette index */
414 {
415     DC * dc;
416     BITMAPOBJ * bmp;
417     int i;
418     HDC memdc;
419 
420     if (!info) return 0;
421     memdc = CreateCompatibleDC(hdc);
422     if (!(dc = DC_GetDCUpdate( hdc )))
423     {
424         DeleteDC(memdc);
425         return 0;
426     }
427     if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
428     {
429         GDI_ReleaseObj( hdc );
430         DeleteDC(memdc);
431         return 0;
432     }
433 
434     /* Transfer color info */
435 
436     if (info->bmiHeader.biBitCount <= 8 && info->bmiHeader.biBitCount > 0 ) {
437 
438         info->bmiHeader.biClrUsed = 0;
439 
440         /* If the bitmap object already has a dib section at the
441            same color depth then get the color map from it */
442         if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == info->bmiHeader.biBitCount) {
443             if(coloruse == DIB_RGB_COLORS) {
444                 HBITMAP oldbm;
445                 oldbm = SelectObject(memdc, hbitmap);
446                 GetDIBColorTable(memdc, 0, 1 << info->bmiHeader.biBitCount, info->bmiColors);
447                 SelectObject(memdc, oldbm);
448             }
449             else {
450                 WORD *index = (WORD*)info->bmiColors;
451                 int i;
452                 for(i = 0; i < 1 << info->bmiHeader.biBitCount; i++, index++)
453                     *index = i;
454             }
455         }
456         else {
457             if(info->bmiHeader.biBitCount >= bmp->bitmap.bmBitsPixel) {
458                 /* Generate the color map from the selected palette */
459                 PALETTEENTRY * palEntry;
460                 PALETTEOBJ * palette;
461                 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC ))) {
462                     GDI_ReleaseObj( hdc );
463                     GDI_ReleaseObj( hbitmap );
464                     DeleteDC(memdc);
465                     return 0;
466                 }
467                 palEntry = palette->logpalette.palPalEntry;
468                 for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++, palEntry++) {
469                     if (coloruse == DIB_RGB_COLORS) {
470                         info->bmiColors[i].rgbRed      = palEntry->peRed;
471                         info->bmiColors[i].rgbGreen    = palEntry->peGreen;
472                         info->bmiColors[i].rgbBlue     = palEntry->peBlue;
473                         info->bmiColors[i].rgbReserved = 0;
474                     }
475                     else ((WORD *)info->bmiColors)[i] = (WORD)i;
476                 }
477                 GDI_ReleaseObj( dc->hPalette );
478             } else {
479                 switch (info->bmiHeader.biBitCount) {
480                 case 1:
481                     info->bmiColors[0].rgbRed = info->bmiColors[0].rgbGreen =
482                         info->bmiColors[0].rgbBlue = 0;
483                     info->bmiColors[0].rgbReserved = 0;
484                     info->bmiColors[1].rgbRed = info->bmiColors[1].rgbGreen =
485                         info->bmiColors[1].rgbBlue = 0xff;
486                     info->bmiColors[1].rgbReserved = 0;
487                     break;
488 
489                 case 4:
490                     memcpy(info->bmiColors, EGAColors, sizeof(EGAColors));
491                     break;
492 
493                 case 8:
494                     {
495                         INT r, g, b;
496                         RGBQUAD *color;
497 
498                         memcpy(info->bmiColors, DefLogPalette,
499                                10 * sizeof(RGBQUAD));
500                         memcpy(info->bmiColors + 246, DefLogPalette + 10,
501                                10 * sizeof(RGBQUAD));
502                         color = info->bmiColors + 10;
503                         for(r = 0; r <= 5; r++) /* FIXME */
504                             for(g = 0; g <= 5; g++)
505                                 for(b = 0; b <= 5; b++) {
506                                     color->rgbRed =   (r * 0xff) / 5;
507                                     color->rgbGreen = (g * 0xff) / 5;
508                                     color->rgbBlue =  (b * 0xff) / 5;
509                                     color->rgbReserved = 0;
510                                     color++;
511                                 }
512                     }
513                 }
514             }
515         }
516     }
517 
518     if (bits && lines)
519     {
520         /* If the bitmap object already have a dib section that contains image data, get the bits from it */
521         if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && info->bmiHeader.biBitCount >= 15)
522         {
523             /*FIXME: Only RGB dibs supported for now */
524             unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb = bmp->dib->dsBm.bmWidthBytes;
525             unsigned int dstwidth = info->bmiHeader.biWidth;
526             int dstwidthb = DIB_GetDIBWidthBytes( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
527             LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
528             unsigned int x, y, width, widthb;
529 
530             if ((info->bmiHeader.biHeight < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
531             {
532                 dbits = (LPBYTE)bits + (dstwidthb * (lines-1));
533                 dstwidthb = -dstwidthb;
534             }
535 
536             switch( info->bmiHeader.biBitCount ) {
537 
538             case 15:
539             case 16: /* 16 bpp dstDIB */
540                 {
541                     LPWORD dstbits = (LPWORD)dbits;
542                     WORD rmask = 0x7c00, gmask= 0x03e0, bmask = 0x001f;
543 
544                     /* FIXME: BI_BITFIELDS not supported yet */
545 
546                     switch(bmp->dib->dsBm.bmBitsPixel) {
547 
548                     case 16: /* 16 bpp srcDIB -> 16 bpp dstDIB */
549                         {
550                             widthb = min(srcwidthb, abs(dstwidthb));
551                             /* FIXME: BI_BITFIELDS not supported yet */
552                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
553                                 memcpy(dbits, sbits, widthb);
554                         }
555                         break;
556 
557                     case 24: /* 24 bpp srcDIB -> 16 bpp dstDIB */
558                         {
559                             LPBYTE srcbits = sbits;
560 
561                             width = min(srcwidth, dstwidth);
562                             for( y = 0; y < lines; y++) {
563                                 for( x = 0; x < width; x++, srcbits += 3)
564                                     *dstbits++ = ((srcbits[0] >> 3) & bmask) |
565                                                  (((WORD)srcbits[1] << 2) & gmask) |
566                                                  (((WORD)srcbits[2] << 7) & rmask);
567 
568                                 dstbits = (LPWORD)(dbits+=dstwidthb);
569                                 srcbits = (sbits += srcwidthb);
570                             }
571                         }
572                         break;
573 
574                     case 32: /* 32 bpp srcDIB -> 16 bpp dstDIB */
575                         {
576                             LPDWORD srcbits = (LPDWORD)sbits;
577                             DWORD val;
578 
579                             width = min(srcwidth, dstwidth);
580                             for( y = 0; y < lines; y++) {
581                                 for( x = 0; x < width; x++ ) {
582                                     val = *srcbits++;
583                                     *dstbits++ = (WORD)(((val >> 3) & bmask) | ((val >> 6) & gmask) |
584                                                        ((val >> 9) & rmask));
585                                 }
586                                 dstbits = (LPWORD)(dbits+=dstwidthb);
587                                 srcbits = (LPDWORD)(sbits+=srcwidthb);
588                             }
589                         }
590                         break;
591 
592                     default: /* ? bit bmp -> 16 bit DIB */
593                         FIXME("15/16 bit DIB %d bit bitmap\n",
594                         bmp->bitmap.bmBitsPixel);
595                         break;
596                     }
597                 }
598                 break;
599 
600             case 24: /* 24 bpp dstDIB */
601                 {
602                     LPBYTE dstbits = dbits;
603 
604                     switch(bmp->dib->dsBm.bmBitsPixel) {
605 
606                     case 16: /* 16 bpp srcDIB -> 24 bpp dstDIB */
607                         {
608                             LPWORD srcbits = (LPWORD)sbits;
609                             WORD val;
610 
611                             width = min(srcwidth, dstwidth);
612                             /* FIXME: BI_BITFIELDS not supported yet */
613                             for( y = 0; y < lines; y++) {
614                                 for( x = 0; x < width; x++ ) {
615                                     val = *srcbits++;
616                                     *dstbits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07));
617                                     *dstbits++ = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07));
618                                     *dstbits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));
619                                 }
620                                 dstbits = (LPBYTE)(dbits+=dstwidthb);
621                                 srcbits = (LPWORD)(sbits+=srcwidthb);
622                             }
623                         }
624                         break;
625 
626                     case 24: /* 24 bpp srcDIB -> 24 bpp dstDIB */
627                         {
628                             widthb = min(srcwidthb, abs(dstwidthb));
629                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb)
630                                 memcpy(dbits, sbits, widthb);
631                         }
632                         break;
633 
634                     case 32: /* 32 bpp srcDIB -> 24 bpp dstDIB */
635                         {
636                             LPBYTE srcbits = (LPBYTE)sbits;
637 
638                             width = min(srcwidth, dstwidth);
639                             for( y = 0; y < lines; y++) {
640                                 for( x = 0; x < width; x++, srcbits++ ) {
641                                     *dstbits++ = *srcbits++;
642                                     *dstbits++ = *srcbits++;
643                                     *dstbits++ = *srcbits++;
644                                 }
645                                 dstbits=(LPBYTE)(dbits+=dstwidthb);
646                                 srcbits = (LPBYTE)(sbits+=srcwidthb);
647                             }
648                         }
649                         break;
650 
651                     default: /* ? bit bmp -> 24 bit DIB */
652                         FIXME("24 bit DIB %d bit bitmap\n",
653                               bmp->bitmap.bmBitsPixel);
654                         break;
655                     }
656                 }
657                 break;
658 
659             case 32: /* 32 bpp dstDIB */
660                 {
661                     LPDWORD dstbits = (LPDWORD)dbits;
662 
663                     /* FIXME: BI_BITFIELDS not supported yet */
664 
665                     switch(bmp->dib->dsBm.bmBitsPixel) {
666                         case 16: /* 16 bpp srcDIB -> 32 bpp dstDIB */
667                         {
668                             LPWORD srcbits = (LPWORD)sbits;
669                             DWORD val;
670 
671                             width = min(srcwidth, dstwidth);
672                             /* FIXME: BI_BITFIELDS not supported yet */
673                             for( y = 0; y < lines; y++) {
674                                 for( x = 0; x < width; x++ ) {
675                                     val = (DWORD)*srcbits++;
676                                     *dstbits++ = ((val << 3) & 0xf8) | ((val >> 2) & 0x07) |
677                                                  ((val << 6) & 0xf800) | ((val << 1) & 0x0700) |
678                                                  ((val << 9) & 0xf80000) | ((val << 4) & 0x070000);
679                                 }
680                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
681                                 srcbits=(LPWORD)(sbits+=srcwidthb);
682                             }
683                         }
684                         break;
685 
686                     case 24: /* 24 bpp srcDIB -> 32 bpp dstDIB */
687                         {
688                             LPBYTE srcbits = sbits;
689 
690                             width = min(srcwidth, dstwidth);
691                             for( y = 0; y < lines; y++) {
692                                 for( x = 0; x < width; x++, srcbits+=3 )
693                                     *dstbits++ = ((DWORD)*srcbits) & 0x00ffffff;
694                                 dstbits=(LPDWORD)(dbits+=dstwidthb);
695                                 srcbits=(sbits+=srcwidthb);
696                             }
697                         }
698                         break;
699 
700                     case 32: /* 32 bpp srcDIB -> 32 bpp dstDIB */
701                         {
702                             widthb = min(srcwidthb, abs(dstwidthb));
703                             /* FIXME: BI_BITFIELDS not supported yet */
704                             for (y = 0; y < lines; y++, dbits+=dstwidthb, sbits+=srcwidthb) {
705                                 memcpy(dbits, sbits, widthb);
706                             }
707                         }
708                         break;
709 
710                     default: /* ? bit bmp -> 32 bit DIB */
711                         FIXME("32 bit DIB %d bit bitmap\n",
712                         bmp->bitmap.bmBitsPixel);
713                         break;
714                     }
715                 }
716                 break;
717 
718             default: /* ? bit DIB */
719                 FIXME("Unsupported DIB depth %d\n", info->bmiHeader.biBitCount);
720                 break;
721             }
722         }
723         /* Otherwise, get bits from the XImage */
724         else
725         {
726             if (!bmp->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) lines = 0;
727             else
728             {
729                 if (bmp->funcs && bmp->funcs->pGetDIBits)
730                     lines = bmp->funcs->pGetDIBits( dc->physDev, hbitmap, startscan,
731                                                     lines, bits, info, coloruse );
732                 else
733                     lines = 0;  /* FIXME: should copy from bmp->bitmap.bmBits */
734             }
735         }
736     }
737     else if( info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
738     {
739         /* fill in struct members */
740 
741         if( info->bmiHeader.biBitCount == 0)
742         {
743             info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
744             info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
745             info->bmiHeader.biPlanes = 1;
746             info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
747             info->bmiHeader.biSizeImage =
748                              DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
749                                                    bmp->bitmap.bmHeight,
750                                                    bmp->bitmap.bmBitsPixel );
751             info->bmiHeader.biCompression = 0;
752         }
753         else
754         {
755             info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
756                                                info->bmiHeader.biWidth,
757                                                info->bmiHeader.biHeight,
758                                                info->bmiHeader.biBitCount );
759         }
760         lines = info->bmiHeader.biHeight;
761     }
762 
763     TRACE("biSizeImage = %ld, biWidth = %ld, biHeight = %ld\n",
764           info->bmiHeader.biSizeImage, info->bmiHeader.biWidth,
765           info->bmiHeader.biHeight);
766 
767     GDI_ReleaseObj( hdc );
768     GDI_ReleaseObj( hbitmap );
769     DeleteDC(memdc);
770     return lines;
771 }
772 
773 
774 /***********************************************************************
775  *           CreateDIBitmap    (GDI32.@)
776  *
777  * Creates a DDB (device dependent bitmap) from a DIB.
778  * The DDB will have the same color depth as the reference DC.
779  */
780 HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
781                             DWORD init, LPCVOID bits, const BITMAPINFO *data,
782                             UINT coloruse )
783 {
784     HBITMAP handle;
785     DWORD width;
786     int height;
787     WORD bpp;
788     WORD compr;
789     DC *dc;
790 
791     if (DIB_GetBitmapInfo( header, &width, &height, &bpp, &compr ) == -1) return 0;
792     if (height < 0) height = -height;
793 
794     if (hdc == NULL)
795         handle = CreateBitmap( width, height, 1, 1, NULL );
796     else
797         handle = CreateCompatibleBitmap( hdc, width, height );
798 
799     if (handle)
800     {
801         if (init == CBM_INIT) SetDIBits( hdc, handle, 0, height, bits, data, coloruse );
802 
803         else if (hdc && ((dc = DC_GetDCPtr( hdc )) != NULL) )
804         {
805             if (!BITMAP_SetOwnerDC( handle, dc ))
806             {
807                 DeleteObject( handle );
808                 handle = 0;
809             }
810             GDI_ReleaseObj( hdc );
811         }
812     }
813 
814     return handle;
815 }
816 
817 /***********************************************************************
818  *           CreateDIBSection    (GDI.489)
819  */
820 HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, const BITMAPINFO *bmi, UINT16 usage,
821                                      SEGPTR *bits16, HANDLE section, DWORD offset)
822 {
823     LPVOID bits32;
824     HBITMAP hbitmap;
825 
826     hbitmap = CreateDIBSection( HDC_32(hdc), bmi, usage, &bits32, section, offset );
827     if (hbitmap)
828     {
829         BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(hbitmap, BITMAP_MAGIC);
830         if (bmp && bmp->dib && bits32)
831         {
832             const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
833             INT height = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
834             INT width_bytes = DIB_GetDIBWidthBytes(bi->biWidth, bi->biBitCount);
835             INT size  = (bi->biSizeImage && bi->biCompression != BI_RGB) ?
836                          bi->biSizeImage : width_bytes * height;
837 
838             /* calculate number of sel's needed for size with 64K steps */
839             WORD count = (size + 0xffff) / 0x10000;
840             WORD sel = AllocSelectorArray16(count);
841             int i;
842 
843             for (i = 0; i < count; i++)
844             {
845                 SetSelectorBase(sel + (i << __AHSHIFT), (DWORD)bits32 + i * 0x10000);
846                 SetSelectorLimit16(sel + (i << __AHSHIFT), size - 1); /* yep, limit is correct */
847                 size -= 0x10000;
848             }
849             bmp->segptr_bits = MAKESEGPTR( sel, 0 );
850             if (bits16) *bits16 = bmp->segptr_bits;
851         }
852         if (bmp) GDI_ReleaseObj( hbitmap );
853     }
854     return HBITMAP_16(hbitmap);
855 }
856 
857 /***********************************************************************
858  *           DIB_CreateDIBSection
859  */
860 HBITMAP DIB_CreateDIBSection(HDC hdc, const BITMAPINFO *bmi, UINT usage,
861                              VOID **bits, HANDLE section,
862                              DWORD offset, DWORD ovr_pitch)
863 {
864     HBITMAP hbitmap = 0;
865     DC *dc;
866     BOOL bDesktopDC = FALSE;
867 
868     /* If the reference hdc is null, take the desktop dc */
869     if (hdc == 0)
870     {
871         hdc = CreateCompatibleDC(0);
872         bDesktopDC = TRUE;
873     }
874 
875     if ((dc = DC_GetDCPtr( hdc )))
876     {
877         if(dc->funcs->pCreateDIBSection)
878             hbitmap = dc->funcs->pCreateDIBSection(dc->physDev, bmi, usage, bits, section, offset, ovr_pitch);
879         GDI_ReleaseObj(hdc);
880     }
881 
882     if (bDesktopDC)
883       DeleteDC(hdc);
884 
885     return hbitmap;
886 }
887 
888 /***********************************************************************
889  *           CreateDIBSection    (GDI32.@)
890  */
891 HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
892                                 VOID **bits, HANDLE section,
893                                 DWORD offset)
894 {
895     return DIB_CreateDIBSection(hdc, bmi, usage, bits, section, offset, 0);
896 }
897 

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