2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
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.
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.
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
25 #include <X11/extensions/XShm.h>
26 # ifdef HAVE_SYS_SHM_H
29 # ifdef HAVE_SYS_IPC_H
32 #endif /* defined(HAVE_LIBXXSHM) */
41 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(bitmap
);
44 WINE_DECLARE_DEBUG_CHANNEL(x11drv
);
46 static int ximageDepthTable
[32];
48 /* This structure holds the arguments for DIB_SetImageBits() */
51 X11DRV_PDEVICE
*physDev
;
54 PALETTEENTRY
*palentry
;
76 } X11DRV_DIB_IMAGEBITS_DESCR
;
81 RLE_EOL
= 0, /* End of line */
82 RLE_END
= 1, /* End of bitmap */
83 RLE_DELTA
= 2 /* Delta */
88 Some of the following helper functions are duplicated in
92 /***********************************************************************
93 * X11DRV_DIB_GetXImageWidthBytes
95 * Return the width of an X image in bytes
97 inline static int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
99 if (!depth
|| depth
> 32) goto error
;
101 if (!ximageDepthTable
[depth
-1])
103 XImage
*testimage
= XCreateImage( gdi_display
, visual
, depth
,
104 ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
107 ximageDepthTable
[depth
-1] = testimage
->bits_per_pixel
;
108 XDestroyImage( testimage
);
110 else ximageDepthTable
[depth
-1] = -1;
112 if (ximageDepthTable
[depth
-1] != -1)
113 return (4 * ((width
* ximageDepthTable
[depth
-1] + 31) / 32));
116 WARN( "(%d): Unsupported depth\n", depth
);
121 /***********************************************************************
122 * X11DRV_DIB_GetDIBWidthBytes
124 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
126 static int X11DRV_DIB_GetDIBWidthBytes( int width
, int depth
)
132 case 1: words
= (width
+ 31) / 32; break;
133 case 4: words
= (width
+ 7) / 8; break;
134 case 8: words
= (width
+ 3) / 4; break;
136 case 16: words
= (width
+ 1) / 2; break;
137 case 24: words
= (width
* 3 + 3) / 4; break;
139 WARN("(%d): Unsupported depth\n", depth
);
148 /***********************************************************************
149 * X11DRV_DIB_GetDIBImageBytes
151 * Return the number of bytes used to hold the image in a DIB bitmap.
153 static int X11DRV_DIB_GetDIBImageBytes( int width
, int height
, int depth
)
155 return X11DRV_DIB_GetDIBWidthBytes( width
, depth
) * abs( height
);
159 /***********************************************************************
160 * X11DRV_DIB_BitmapInfoSize
162 * Return the size of the bitmap info structure including color table.
164 int X11DRV_DIB_BitmapInfoSize( const BITMAPINFO
* info
, WORD coloruse
)
168 if (info
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
170 const BITMAPCOREHEADER
*core
= (const BITMAPCOREHEADER
*)info
;
171 colors
= (core
->bcBitCount
<= 8) ? 1 << core
->bcBitCount
: 0;
172 return sizeof(BITMAPCOREHEADER
) + colors
*
173 ((coloruse
== DIB_RGB_COLORS
) ? sizeof(RGBTRIPLE
) : sizeof(WORD
));
175 else /* assume BITMAPINFOHEADER */
177 colors
= info
->bmiHeader
.biClrUsed
;
178 if (!colors
&& (info
->bmiHeader
.biBitCount
<= 8))
179 colors
= 1 << info
->bmiHeader
.biBitCount
;
180 return sizeof(BITMAPINFOHEADER
) + colors
*
181 ((coloruse
== DIB_RGB_COLORS
) ? sizeof(RGBQUAD
) : sizeof(WORD
));
186 /***********************************************************************
187 * X11DRV_DIB_CreateXImage
191 XImage
*X11DRV_DIB_CreateXImage( int width
, int height
, int depth
)
197 width_bytes
= X11DRV_DIB_GetXImageWidthBytes( width
, depth
);
198 image
= XCreateImage( gdi_display
, visual
, depth
, ZPixmap
, 0,
199 calloc( height
, width_bytes
),
200 width
, height
, 32, width_bytes
);
206 /***********************************************************************
207 * DIB_GetBitmapInfoEx
209 * Get the info from a bitmap header.
210 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
212 static int DIB_GetBitmapInfoEx( const BITMAPINFOHEADER
*header
, LONG
*width
,
213 LONG
*height
, WORD
*planes
, WORD
*bpp
,
214 WORD
*compr
, DWORD
*size
)
216 if (header
->biSize
== sizeof(BITMAPCOREHEADER
))
218 const BITMAPCOREHEADER
*core
= (const BITMAPCOREHEADER
*)header
;
219 *width
= core
->bcWidth
;
220 *height
= core
->bcHeight
;
221 *planes
= core
->bcPlanes
;
222 *bpp
= core
->bcBitCount
;
227 if (header
->biSize
>= sizeof(BITMAPINFOHEADER
))
229 *width
= header
->biWidth
;
230 *height
= header
->biHeight
;
231 *planes
= header
->biPlanes
;
232 *bpp
= header
->biBitCount
;
233 *compr
= header
->biCompression
;
234 *size
= header
->biSizeImage
;
237 ERR("(%ld): unknown/wrong size for header\n", header
->biSize
);
242 /***********************************************************************
245 * Get the info from a bitmap header.
246 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
248 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER
*header
, LONG
*width
,
249 LONG
*height
, WORD
*bpp
, WORD
*compr
)
254 return DIB_GetBitmapInfoEx( header
, width
, height
, &planes
, bpp
, compr
, &size
);
258 /***********************************************************************
259 * X11DRV_DIB_GenColorMap
261 * Fills the color map of a bitmap palette. Should not be called
262 * for a >8-bit deep bitmap.
264 int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE
*physDev
, int *colorMapping
,
265 WORD coloruse
, WORD depth
, BOOL quads
,
266 const void *colorPtr
, int start
, int end
)
270 if (coloruse
== DIB_RGB_COLORS
)
274 const RGBQUAD
* rgb
= (const RGBQUAD
*)colorPtr
;
276 if (depth
== 1) /* Monochrome */
277 for (i
= start
; i
< end
; i
++, rgb
++)
278 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
279 rgb
->rgbBlue
> 255*3/2);
281 for (i
= start
; i
< end
; i
++, rgb
++)
282 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, RGB(rgb
->rgbRed
,
288 const RGBTRIPLE
* rgb
= (const RGBTRIPLE
*)colorPtr
;
290 if (depth
== 1) /* Monochrome */
291 for (i
= start
; i
< end
; i
++, rgb
++)
292 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
293 rgb
->rgbtBlue
> 255*3/2);
295 for (i
= start
; i
< end
; i
++, rgb
++)
296 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, RGB(rgb
->rgbtRed
,
301 else /* DIB_PAL_COLORS */
304 const WORD
* index
= (const WORD
*)colorPtr
;
306 for (i
= start
; i
< end
; i
++, index
++)
307 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, PALETTEINDEX(*index
) );
309 for (i
= start
; i
< end
; i
++)
310 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, PALETTEINDEX(i
) );
317 /***********************************************************************
318 * X11DRV_DIB_BuildColorMap
320 * Build the color map from the bitmap palette. Should not be called
321 * for a >8-bit deep bitmap.
323 int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE
*physDev
, WORD coloruse
, WORD depth
,
324 const BITMAPINFO
*info
, int *nColors
)
328 const void *colorPtr
;
331 isInfo
= info
->bmiHeader
.biSize
!= sizeof(BITMAPCOREHEADER
);
335 colors
= info
->bmiHeader
.biClrUsed
;
336 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
340 colors
= 1 << ((const BITMAPCOREHEADER
*)info
)->bcBitCount
;
343 colorPtr
= (const BYTE
*) info
+ (WORD
) info
->bmiHeader
.biSize
;
347 ERR("called with >256 colors!\n");
351 /* just so CopyDIBSection doesn't have to create an identity palette */
352 if (coloruse
== (WORD
)-1) colorPtr
= NULL
;
354 if (!(colorMapping
= HeapAlloc(GetProcessHeap(), 0, colors
* sizeof(int) )))
358 return X11DRV_DIB_GenColorMap( physDev
, colorMapping
, coloruse
, depth
,
359 isInfo
, colorPtr
, 0, colors
);
362 /***********************************************************************
363 * X11DRV_DIB_BuildColorTable
365 * Build the dib color table. This either keeps a copy of the bmiColors array if
366 * usage is DIB_RGB_COLORS, or looks up the palette indicies if usage is
368 * Should not be called for a >8-bit deep bitmap.
370 static RGBQUAD
*X11DRV_DIB_BuildColorTable( X11DRV_PDEVICE
*physDev
, WORD coloruse
, WORD depth
,
371 const BITMAPINFO
*info
)
376 BOOL core_info
= info
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
);
380 colors
= 1 << ((BITMAPCOREINFO
*) info
)->bmciHeader
.bcBitCount
;
384 colors
= info
->bmiHeader
.biClrUsed
;
385 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
389 ERR("called with >256 colors!\n");
393 if (!(colorTable
= HeapAlloc(GetProcessHeap(), 0, colors
* sizeof(RGBQUAD
) )))
396 if(coloruse
== DIB_RGB_COLORS
)
400 /* Convert RGBTRIPLEs to RGBQUADs */
401 for (i
=0; i
< colors
; i
++)
403 colorTable
[i
].rgbRed
= ((BITMAPCOREINFO
*) info
)->bmciColors
[i
].rgbtRed
;
404 colorTable
[i
].rgbGreen
= ((BITMAPCOREINFO
*) info
)->bmciColors
[i
].rgbtGreen
;
405 colorTable
[i
].rgbBlue
= ((BITMAPCOREINFO
*) info
)->bmciColors
[i
].rgbtBlue
;
406 colorTable
[i
].rgbReserved
= 0;
411 memcpy(colorTable
, (LPBYTE
) info
+ (WORD
) info
->bmiHeader
.biSize
, colors
* sizeof(RGBQUAD
));
416 HPALETTE hpal
= GetCurrentObject(physDev
->hdc
, OBJ_PAL
);
417 PALETTEENTRY pal_ents
[256];
418 WORD
*index
= (WORD
*) ((LPBYTE
) info
+ (WORD
) info
->bmiHeader
.biSize
);
420 GetPaletteEntries(hpal
, 0, 256, pal_ents
);
422 for(i
= 0; i
< colors
; i
++, index
++)
424 colorTable
[i
].rgbRed
= pal_ents
[*index
].peRed
;
425 colorTable
[i
].rgbGreen
= pal_ents
[*index
].peGreen
;
426 colorTable
[i
].rgbBlue
= pal_ents
[*index
].peBlue
;
427 colorTable
[i
].rgbReserved
= 0;
434 /***********************************************************************
435 * X11DRV_DIB_MapColor
437 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
, int oldcol
)
441 if ((oldcol
< nPhysMap
) && (physMap
[oldcol
] == phys
))
444 for (color
= 0; color
< nPhysMap
; color
++)
445 if (physMap
[color
] == phys
)
448 WARN("Strange color %08x\n", phys
);
453 /*********************************************************************
454 * X11DRV_DIB_GetNearestIndex
456 * Helper for X11DRV_DIB_GetDIBits.
457 * Returns the nearest colour table index for a given RGB.
458 * Nearest is defined by minimizing the sum of the squares.
460 static INT
X11DRV_DIB_GetNearestIndex(RGBQUAD
*colormap
, int numColors
, BYTE r
, BYTE g
, BYTE b
)
462 INT i
, best
= -1, diff
, bestdiff
= -1;
465 for(color
= colormap
, i
= 0; i
< numColors
; color
++, i
++) {
466 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
467 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
468 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
471 if(best
== -1 || diff
< bestdiff
) {
478 /*********************************************************************
479 * X11DRV_DIB_MaskToShift
481 * Helper for X11DRV_DIB_GetDIBits.
482 * Returns the by how many bits to shift a given color so that it is
483 * in the proper position.
485 INT
X11DRV_DIB_MaskToShift(DWORD mask
)
493 while ((mask
&1)==0) {
500 /***********************************************************************
501 * X11DRV_DIB_SetImageBits_1
503 * SetDIBits for a 1-bit deep DIB.
505 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
506 DWORD srcwidth
, DWORD dstwidth
, int left
,
507 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
516 srcbits
= srcbits
+ linebytes
* (lines
- 1);
517 linebytes
= -linebytes
;
520 if ((extra
= (left
& 7)) != 0) {
524 srcbits
+= left
>> 3;
525 width
= min(srcwidth
, dstwidth
);
527 /* ==== pal 1 dib -> any bmp format ==== */
528 for (h
= lines
-1; h
>=0; h
--) {
530 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
531 for (i
= width
/8, x
= left
; i
> 0; i
--) {
533 XPutPixel( bmpImage
, x
++, h
, colors
[ srcval
>> 7] );
534 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 6) & 1] );
535 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 5) & 1] );
536 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 4) & 1] );
537 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 3) & 1] );
538 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 2) & 1] );
539 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 1) & 1] );
540 XPutPixel( bmpImage
, x
++, h
, colors
[ srcval
& 1] );
546 case 7: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
547 case 6: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
548 case 5: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
549 case 4: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
550 case 3: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
551 case 2: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
552 case 1: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]);
555 srcbits
+= linebytes
;
559 /***********************************************************************
560 * X11DRV_DIB_GetImageBits_1
562 * GetDIBits for a 1-bit deep DIB.
564 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
565 DWORD dstwidth
, DWORD srcwidth
,
566 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
567 XImage
*bmpImage
, DWORD linebytes
)
570 int h
, width
= min(dstwidth
, srcwidth
);
574 dstbits
= dstbits
+ linebytes
* (lines
- 1);
575 linebytes
= -linebytes
;
578 switch (bmpImage
->depth
)
582 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
583 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
586 for (h
=lines
-1; h
>=0; h
--) {
590 for (x
=0; x
<width
; x
++) {
592 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
593 dstval
|=(X11DRV_DIB_GetNearestIndex
597 srcval
.peBlue
) << (7 - (x
& 7)));
606 dstbits
+= linebytes
;
614 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
615 /* ==== pal 8 bmp -> pal 1 dib ==== */
617 const BYTE
* srcpixel
;
620 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
622 for (h
=0; h
<lines
; h
++) {
627 for (x
=0; x
<width
; x
++) {
629 srcval
=srccolors
[(int)*srcpixel
++];
630 dstval
|=(X11DRV_DIB_GetNearestIndex
634 srcval
.peBlue
) << (7-(x
&7)) );
643 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
644 dstbits
+= linebytes
;
655 const WORD
* srcpixel
;
658 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
660 if (bmpImage
->green_mask
==0x03e0) {
661 if (bmpImage
->red_mask
==0x7c00) {
662 /* ==== rgb 555 bmp -> pal 1 dib ==== */
663 for (h
=0; h
<lines
; h
++) {
668 for (x
=0; x
<width
; x
++) {
671 dstval
|=(X11DRV_DIB_GetNearestIndex
673 ((srcval
>> 7) & 0xf8) | /* r */
674 ((srcval
>> 12) & 0x07),
675 ((srcval
>> 2) & 0xf8) | /* g */
676 ((srcval
>> 7) & 0x07),
677 ((srcval
<< 3) & 0xf8) | /* b */
678 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
687 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
688 dstbits
+= linebytes
;
690 } else if (bmpImage
->blue_mask
==0x7c00) {
691 /* ==== bgr 555 bmp -> pal 1 dib ==== */
692 for (h
=0; h
<lines
; h
++) {
697 for (x
=0; x
<width
; x
++) {
700 dstval
|=(X11DRV_DIB_GetNearestIndex
702 ((srcval
<< 3) & 0xf8) | /* r */
703 ((srcval
>> 2) & 0x07),
704 ((srcval
>> 2) & 0xf8) | /* g */
705 ((srcval
>> 7) & 0x07),
706 ((srcval
>> 7) & 0xf8) | /* b */
707 ((srcval
>> 12) & 0x07) ) << (7-(x
&7)) );
716 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
717 dstbits
+= linebytes
;
722 } else if (bmpImage
->green_mask
==0x07e0) {
723 if (bmpImage
->red_mask
==0xf800) {
724 /* ==== rgb 565 bmp -> pal 1 dib ==== */
725 for (h
=0; h
<lines
; h
++) {
730 for (x
=0; x
<width
; x
++) {
733 dstval
|=(X11DRV_DIB_GetNearestIndex
735 ((srcval
>> 8) & 0xf8) | /* r */
736 ((srcval
>> 13) & 0x07),
737 ((srcval
>> 3) & 0xfc) | /* g */
738 ((srcval
>> 9) & 0x03),
739 ((srcval
<< 3) & 0xf8) | /* b */
740 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
749 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
750 dstbits
+= linebytes
;
752 } else if (bmpImage
->blue_mask
==0xf800) {
753 /* ==== bgr 565 bmp -> pal 1 dib ==== */
754 for (h
=0; h
<lines
; h
++) {
759 for (x
=0; x
<width
; x
++) {
762 dstval
|=(X11DRV_DIB_GetNearestIndex
764 ((srcval
<< 3) & 0xf8) | /* r */
765 ((srcval
>> 2) & 0x07),
766 ((srcval
>> 3) & 0xfc) | /* g */
767 ((srcval
>> 9) & 0x03),
768 ((srcval
>> 8) & 0xf8) | /* b */
769 ((srcval
>> 13) & 0x07) ) << (7-(x
&7)) );
778 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
779 dstbits
+= linebytes
;
798 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
799 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
801 if (bmpImage
->green_mask
!=0x00ff00 ||
802 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
804 } else if (bmpImage
->blue_mask
==0xff) {
805 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
806 for (h
=0; h
<lines
; h
++) {
811 for (x
=0; x
<width
; x
++) {
812 dstval
|=(X11DRV_DIB_GetNearestIndex
816 srcbyte
[0]) << (7-(x
&7)) );
817 srcbyte
+=bytes_per_pixel
;
826 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
827 dstbits
+= linebytes
;
830 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
831 for (h
=0; h
<lines
; h
++) {
836 for (x
=0; x
<width
; x
++) {
837 dstval
|=(X11DRV_DIB_GetNearestIndex
841 srcbyte
[2]) << (7-(x
&7)) );
842 srcbyte
+=bytes_per_pixel
;
851 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
852 dstbits
+= linebytes
;
862 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
864 /* ==== any bmp format -> pal 1 dib ==== */
865 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
866 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
867 bmpImage
->green_mask
, bmpImage
->blue_mask
);
869 for (h
=lines
-1; h
>=0; h
--) {
873 for (x
=0; x
<width
; x
++) {
874 dstval
|=(XGetPixel( bmpImage
, x
, h
) >= white
) << (7 - (x
&7));
883 dstbits
+= linebytes
;
890 /***********************************************************************
891 * X11DRV_DIB_SetImageBits_4
893 * SetDIBits for a 4-bit deep DIB.
895 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
896 DWORD srcwidth
, DWORD dstwidth
, int left
,
897 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
905 srcbits
= srcbits
+ linebytes
* (lines
- 1);
906 linebytes
= -linebytes
;
913 srcbits
+= left
>> 1;
914 width
= min(srcwidth
, dstwidth
);
916 /* ==== pal 4 dib -> any bmp format ==== */
917 for (h
= lines
-1; h
>= 0; h
--) {
919 for (i
= width
/2, x
= left
; i
> 0; i
--) {
920 BYTE srcval
=*srcbyte
++;
921 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
>> 4] );
922 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
& 0x0f] );
925 XPutPixel( bmpImage
, x
, h
, colors
[*srcbyte
>> 4] );
926 srcbits
+= linebytes
;
932 /***********************************************************************
933 * X11DRV_DIB_GetImageBits_4
935 * GetDIBits for a 4-bit deep DIB.
937 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
938 DWORD srcwidth
, DWORD dstwidth
,
939 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
940 XImage
*bmpImage
, DWORD linebytes
)
943 int h
, width
= min(srcwidth
, dstwidth
);
949 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
950 linebytes
= -linebytes
;
955 switch (bmpImage
->depth
) {
958 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
959 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
962 for (h
= lines
-1; h
>= 0; h
--) {
966 for (x
= 0; x
< width
; x
++) {
968 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
969 dstval
|=(X11DRV_DIB_GetNearestIndex
973 srcval
.peBlue
) << (4-((x
&1)<<2)));
982 dstbits
+= linebytes
;
990 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
991 /* ==== pal 8 bmp -> pal 4 dib ==== */
993 const BYTE
*srcpixel
;
996 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
997 for (h
=0; h
<lines
; h
++) {
1002 for (x
=0; x
<width
; x
++) {
1003 PALETTEENTRY srcval
;
1004 srcval
= srccolors
[(int)*srcpixel
++];
1005 dstval
|=(X11DRV_DIB_GetNearestIndex
1009 srcval
.peBlue
) << (4*(1-(x
&1))) );
1018 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1019 dstbits
+= linebytes
;
1029 const void* srcbits
;
1030 const WORD
* srcpixel
;
1033 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1035 if (bmpImage
->green_mask
==0x03e0) {
1036 if (bmpImage
->red_mask
==0x7c00) {
1037 /* ==== rgb 555 bmp -> pal 4 dib ==== */
1038 for (h
=0; h
<lines
; h
++) {
1043 for (x
=0; x
<width
; x
++) {
1046 dstval
|=(X11DRV_DIB_GetNearestIndex
1048 ((srcval
>> 7) & 0xf8) | /* r */
1049 ((srcval
>> 12) & 0x07),
1050 ((srcval
>> 2) & 0xf8) | /* g */
1051 ((srcval
>> 7) & 0x07),
1052 ((srcval
<< 3) & 0xf8) | /* b */
1053 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
1062 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1063 dstbits
+= linebytes
;
1065 } else if (bmpImage
->blue_mask
==0x7c00) {
1066 /* ==== bgr 555 bmp -> pal 4 dib ==== */
1067 for (h
=0; h
<lines
; h
++) {
1072 for (x
=0; x
<width
; x
++) {
1075 dstval
|=(X11DRV_DIB_GetNearestIndex
1077 ((srcval
<< 3) & 0xf8) | /* r */
1078 ((srcval
>> 2) & 0x07),
1079 ((srcval
>> 2) & 0xf8) | /* g */
1080 ((srcval
>> 7) & 0x07),
1081 ((srcval
>> 7) & 0xf8) | /* b */
1082 ((srcval
>> 12) & 0x07) ) << ((1-(x
&1))<<2) );
1091 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1092 dstbits
+= linebytes
;
1097 } else if (bmpImage
->green_mask
==0x07e0) {
1098 if (bmpImage
->red_mask
==0xf800) {
1099 /* ==== rgb 565 bmp -> pal 4 dib ==== */
1100 for (h
=0; h
<lines
; h
++) {
1105 for (x
=0; x
<width
; x
++) {
1108 dstval
|=(X11DRV_DIB_GetNearestIndex
1110 ((srcval
>> 8) & 0xf8) | /* r */
1111 ((srcval
>> 13) & 0x07),
1112 ((srcval
>> 3) & 0xfc) | /* g */
1113 ((srcval
>> 9) & 0x03),
1114 ((srcval
<< 3) & 0xf8) | /* b */
1115 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
1124 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1125 dstbits
+= linebytes
;
1127 } else if (bmpImage
->blue_mask
==0xf800) {
1128 /* ==== bgr 565 bmp -> pal 4 dib ==== */
1129 for (h
=0; h
<lines
; h
++) {
1134 for (x
=0; x
<width
; x
++) {
1137 dstval
|=(X11DRV_DIB_GetNearestIndex
1139 ((srcval
<< 3) & 0xf8) | /* r */
1140 ((srcval
>> 2) & 0x07),
1141 ((srcval
>> 3) & 0xfc) | /* g */
1142 ((srcval
>> 9) & 0x03),
1143 ((srcval
>> 8) & 0xf8) | /* b */
1144 ((srcval
>> 13) & 0x07) ) << ((1-(x
&1))<<2) );
1153 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1154 dstbits
+= linebytes
;
1166 if (bmpImage
->bits_per_pixel
==24) {
1167 const void* srcbits
;
1168 const BYTE
*srcbyte
;
1171 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1173 if (bmpImage
->green_mask
!=0x00ff00 ||
1174 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1176 } else if (bmpImage
->blue_mask
==0xff) {
1177 /* ==== rgb 888 bmp -> pal 4 dib ==== */
1178 for (h
=0; h
<lines
; h
++) {
1181 for (x
=0; x
<width
/2; x
++) {
1182 /* Do 2 pixels at a time */
1183 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1188 X11DRV_DIB_GetNearestIndex
1196 /* And the the odd pixel */
1197 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1203 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1204 dstbits
+= linebytes
;
1207 /* ==== bgr 888 bmp -> pal 4 dib ==== */
1208 for (h
=0; h
<lines
; h
++) {
1211 for (x
=0; x
<width
/2; x
++) {
1212 /* Do 2 pixels at a time */
1213 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1218 X11DRV_DIB_GetNearestIndex
1226 /* And the the odd pixel */
1227 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1233 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1234 dstbits
+= linebytes
;
1243 const void* srcbits
;
1244 const BYTE
*srcbyte
;
1247 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1249 if (bmpImage
->green_mask
!=0x00ff00 ||
1250 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1252 } else if (bmpImage
->blue_mask
==0xff) {
1253 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
1254 for (h
=0; h
<lines
; h
++) {
1257 for (x
=0; x
<width
/2; x
++) {
1258 /* Do 2 pixels at a time */
1259 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1264 X11DRV_DIB_GetNearestIndex
1272 /* And the the odd pixel */
1273 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1279 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1280 dstbits
+= linebytes
;
1283 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
1284 for (h
=0; h
<lines
; h
++) {
1287 for (x
=0; x
<width
/2; x
++) {
1288 /* Do 2 pixels at a time */
1289 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1294 X11DRV_DIB_GetNearestIndex
1302 /* And the the odd pixel */
1303 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1309 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1310 dstbits
+= linebytes
;
1321 /* ==== any bmp format -> pal 4 dib ==== */
1322 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
1323 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
1324 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1325 for (h
=lines
-1; h
>=0; h
--) {
1327 for (x
=0; x
<(width
& ~1); x
+=2) {
1328 *dstbyte
++=(X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4) |
1329 X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
+1, h
), 0);
1332 *dstbyte
=(X11DRV_DIB_MapColor((int *)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4);
1334 dstbits
+= linebytes
;
1341 /***********************************************************************
1342 * X11DRV_DIB_SetImageBits_RLE4
1344 * SetDIBits for a 4-bit deep compressed DIB.
1346 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
1347 DWORD srcwidth
, DWORD dstwidth
,
1348 int left
, int *colors
,
1351 unsigned int x
= 0, width
= min(srcwidth
, dstwidth
);
1352 int y
= lines
- 1, c
, length
;
1353 const BYTE
*begin
= bits
;
1358 if (length
) { /* encoded */
1361 if (x
>= width
) break;
1362 XPutPixel(bmpImage
, x
++, y
, colors
[c
>> 4]);
1363 if (!length
--) break;
1364 if (x
>= width
) break;
1365 XPutPixel(bmpImage
, x
++, y
, colors
[c
& 0xf]);
1384 default: /* absolute */
1387 if (x
< width
) XPutPixel(bmpImage
, x
++, y
, colors
[c
>> 4]);
1388 if (!length
--) break;
1389 if (x
< width
) XPutPixel(bmpImage
, x
++, y
, colors
[c
& 0xf]);
1391 if ((bits
- begin
) & 1)
1400 /***********************************************************************
1401 * X11DRV_DIB_SetImageBits_8
1403 * SetDIBits for an 8-bit deep DIB.
1405 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
1406 DWORD srcwidth
, DWORD dstwidth
, int left
,
1407 const int *colors
, XImage
*bmpImage
,
1411 int h
, width
= min(srcwidth
, dstwidth
);
1412 const BYTE
* srcbyte
;
1418 srcbits
= srcbits
+ linebytes
* (lines
-1);
1419 linebytes
= -linebytes
;
1424 switch (bmpImage
->depth
) {
1427 #if defined(__i386__) && defined(__GNUC__)
1428 /* Some X servers might have 32 bit/ 16bit deep pixel */
1429 if (lines
&& width
&& (bmpImage
->bits_per_pixel
== 16) &&
1430 (ImageByteOrder(gdi_display
)==LSBFirst
) )
1432 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
1433 /* FIXME: Does this really handle all these cases correctly? */
1434 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
1435 for (h
= lines
; h
--; ) {
1436 int _cl1
,_cl2
; /* temp outputs for asm below */
1437 /* Borrowed from DirectDraw */
1438 __asm__
__volatile__(
1443 " movw (%%edx,%%eax,4),%%ax\n"
1445 " xor %%eax,%%eax\n"
1447 :"=S" (srcbyte
), "=D" (_cl1
), "=c" (_cl2
)
1452 :"eax", "cc", "memory"
1454 srcbyte
= (srcbits
+= linebytes
);
1455 dstbits
-= bmpImage
->bytes_per_line
;
1463 #if defined(__i386__) && defined(__GNUC__)
1464 if (lines
&& width
&& (bmpImage
->bits_per_pixel
== 32) &&
1465 (ImageByteOrder(gdi_display
)==LSBFirst
) )
1467 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
1468 /* FIXME: Does this really handle both cases correctly? */
1469 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
1470 for (h
= lines
; h
--; ) {
1471 int _cl1
,_cl2
; /* temp outputs for asm below */
1472 /* Borrowed from DirectDraw */
1473 __asm__
__volatile__(
1478 " movl (%%edx,%%eax,4),%%eax\n"
1480 " xor %%eax,%%eax\n"
1482 :"=S" (srcbyte
), "=D" (_cl1
), "=c" (_cl2
)
1487 :"eax", "cc", "memory"
1489 srcbyte
= (srcbits
+= linebytes
);
1490 dstbits
-= bmpImage
->bytes_per_line
;
1497 break; /* use slow generic case below */
1500 /* ==== pal 8 dib -> any bmp format ==== */
1501 for (h
=lines
-1; h
>=0; h
--) {
1502 for (x
=left
; x
<width
+left
; x
++) {
1503 XPutPixel(bmpImage
, x
, h
, colors
[*srcbyte
++]);
1505 srcbyte
= (srcbits
+= linebytes
);
1509 /***********************************************************************
1510 * X11DRV_DIB_GetImageBits_8
1512 * GetDIBits for an 8-bit deep DIB.
1514 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
1515 DWORD srcwidth
, DWORD dstwidth
,
1516 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
1517 XImage
*bmpImage
, DWORD linebytes
)
1520 int h
, width
= min(srcwidth
, dstwidth
);
1526 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
1527 linebytes
= -linebytes
;
1532 * This condition is true when GetImageBits has been called by
1533 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
1534 * 256 colormaps, so we'll just use for for GetDIBits calls.
1535 * (In somes cases, in a updateDIBSection, the returned colors are bad too)
1537 if (!srccolors
) goto updatesection
;
1539 switch (bmpImage
->depth
) {
1542 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
1544 /* ==== pal 1 bmp -> pal 8 dib ==== */
1545 /* ==== pal 4 bmp -> pal 8 dib ==== */
1546 for (h
=lines
-1; h
>=0; h
--) {
1548 for (x
=0; x
<width
; x
++) {
1549 PALETTEENTRY srcval
;
1550 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
1551 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
1556 dstbits
+= linebytes
;
1564 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
1565 /* ==== pal 8 bmp -> pal 8 dib ==== */
1566 const void* srcbits
;
1567 const BYTE
* srcpixel
;
1569 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1570 for (h
=0; h
<lines
; h
++) {
1573 for (x
= 0; x
< width
; x
++) {
1574 PALETTEENTRY srcval
;
1575 srcval
=srccolors
[(int)*srcpixel
++];
1576 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
1581 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1582 dstbits
+= linebytes
;
1592 const void* srcbits
;
1593 const WORD
* srcpixel
;
1596 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1598 if (bmpImage
->green_mask
==0x03e0) {
1599 if (bmpImage
->red_mask
==0x7c00) {
1600 /* ==== rgb 555 bmp -> pal 8 dib ==== */
1601 for (h
=0; h
<lines
; h
++) {
1604 for (x
=0; x
<width
; x
++) {
1607 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1609 ((srcval
>> 7) & 0xf8) | /* r */
1610 ((srcval
>> 12) & 0x07),
1611 ((srcval
>> 2) & 0xf8) | /* g */
1612 ((srcval
>> 7) & 0x07),
1613 ((srcval
<< 3) & 0xf8) | /* b */
1614 ((srcval
>> 2) & 0x07) );
1616 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1617 dstbits
+= linebytes
;
1619 } else if (bmpImage
->blue_mask
==0x7c00) {
1620 /* ==== bgr 555 bmp -> pal 8 dib ==== */
1621 for (h
=0; h
<lines
; h
++) {
1624 for (x
=0; x
<width
; x
++) {
1627 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1629 ((srcval
<< 3) & 0xf8) | /* r */
1630 ((srcval
>> 2) & 0x07),
1631 ((srcval
>> 2) & 0xf8) | /* g */
1632 ((srcval
>> 7) & 0x07),
1633 ((srcval
>> 7) & 0xf8) | /* b */
1634 ((srcval
>> 12) & 0x07) );
1636 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1637 dstbits
+= linebytes
;
1642 } else if (bmpImage
->green_mask
==0x07e0) {
1643 if (bmpImage
->red_mask
==0xf800) {
1644 /* ==== rgb 565 bmp -> pal 8 dib ==== */
1645 for (h
=0; h
<lines
; h
++) {
1648 for (x
=0; x
<width
; x
++) {
1651 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1653 ((srcval
>> 8) & 0xf8) | /* r */
1654 ((srcval
>> 13) & 0x07),
1655 ((srcval
>> 3) & 0xfc) | /* g */
1656 ((srcval
>> 9) & 0x03),
1657 ((srcval
<< 3) & 0xf8) | /* b */
1658 ((srcval
>> 2) & 0x07) );
1660 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1661 dstbits
+= linebytes
;
1663 } else if (bmpImage
->blue_mask
==0xf800) {
1664 /* ==== bgr 565 bmp -> pal 8 dib ==== */
1665 for (h
=0; h
<lines
; h
++) {
1668 for (x
=0; x
<width
; x
++) {
1671 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1673 ((srcval
<< 3) & 0xf8) | /* r */
1674 ((srcval
>> 2) & 0x07),
1675 ((srcval
>> 3) & 0xfc) | /* g */
1676 ((srcval
>> 9) & 0x03),
1677 ((srcval
>> 8) & 0xf8) | /* b */
1678 ((srcval
>> 13) & 0x07) );
1680 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1681 dstbits
+= linebytes
;
1695 const void* srcbits
;
1696 const BYTE
*srcbyte
;
1698 int bytes_per_pixel
;
1700 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1701 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
1703 if (bmpImage
->green_mask
!=0x00ff00 ||
1704 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1706 } else if (bmpImage
->blue_mask
==0xff) {
1707 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
1708 for (h
=0; h
<lines
; h
++) {
1711 for (x
=0; x
<width
; x
++) {
1712 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1717 srcbyte
+=bytes_per_pixel
;
1719 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1720 dstbits
+= linebytes
;
1723 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
1724 for (h
=0; h
<lines
; h
++) {
1727 for (x
=0; x
<width
; x
++) {
1728 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1733 srcbyte
+=bytes_per_pixel
;
1735 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
1736 dstbits
+= linebytes
;
1744 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
1745 bmpImage
->depth
, bmpImage
->red_mask
,
1746 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1748 /* ==== any bmp format -> pal 8 dib ==== */
1749 for (h
=lines
-1; h
>=0; h
--) {
1751 for (x
=0; x
<width
; x
++) {
1752 *dstbyte
=X11DRV_DIB_MapColor
1754 XGetPixel(bmpImage
, x
, h
), *dstbyte
);
1757 dstbits
+= linebytes
;
1763 /***********************************************************************
1764 * X11DRV_DIB_SetImageBits_RLE8
1766 * SetDIBits for an 8-bit deep compressed DIB.
1768 * This function rewritten 941113 by James Youngman. WINE blew out when I
1769 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1771 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1772 * 'End of bitmap' escape code. This code is very much laxer in what it
1773 * allows to end the expansion. Possibly too lax. See the note by
1774 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1775 * bitmap should end with RleEnd, but on the other hand, software exists
1776 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1779 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1780 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1783 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
1784 DWORD srcwidth
, DWORD dstwidth
,
1785 int left
, int *colors
,
1788 unsigned int x
; /* X-position on each line. Increases. */
1789 int y
; /* Line #. Starts at lines-1, decreases */
1790 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
1791 BYTE length
; /* The length pf a run */
1792 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
1795 * Note that the bitmap data is stored by Windows starting at the
1796 * bottom line of the bitmap and going upwards. Within each line,
1797 * the data is stored left-to-right. That's the reason why line
1798 * goes from lines-1 to 0. [JAY]
1808 * If the length byte is not zero (which is the escape value),
1809 * We have a run of length pixels all the same colour. The colour
1810 * index is stored next.
1812 * If the length byte is zero, we need to read the next byte to
1813 * know what to do. [JAY]
1818 * [Run-Length] Encoded mode
1820 int color
= colors
[*pIn
++];
1821 while (length
-- && x
< dstwidth
) XPutPixel(bmpImage
, x
++, y
, color
);
1826 * Escape codes (may be an absolute sequence though)
1828 escape_code
= (*pIn
++);
1837 /* Not all RLE8 bitmaps end with this code. For
1838 * example, Paint Shop Pro produces some that don't.
1839 * That's (I think) what caused the previous
1840 * implementation to fail. [JAY]
1849 default: /* switch to absolute mode */
1850 length
= escape_code
;
1853 int color
= colors
[*pIn
++];
1859 XPutPixel(bmpImage
, x
++, y
, color
);
1862 * If you think for a moment you'll realise that the
1863 * only time we could ever possibly read an odd
1864 * number of bytes is when there is a 0x00 (escape),
1865 * a value >0x02 (absolute mode) and then an odd-
1866 * length run. Therefore this is the only place we
1867 * need to worry about it. Everywhere else the
1868 * bytes are always read in pairs. [JAY]
1870 if (escape_code
& 1) pIn
++; /* Throw away the pad byte. */
1872 } /* switch (escape_code) : Escape sequence */
1878 /***********************************************************************
1879 * X11DRV_DIB_SetImageBits_16
1881 * SetDIBits for a 16-bit deep DIB.
1883 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
1884 DWORD srcwidth
, DWORD dstwidth
, int left
,
1885 X11DRV_PDEVICE
*physDev
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
1886 XImage
*bmpImage
, DWORD linebytes
)
1889 int h
, width
= min(srcwidth
, dstwidth
);
1890 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
1895 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
1896 linebytes
= -linebytes
;
1899 switch (bmpImage
->depth
)
1906 srcbits
=srcbits
+left
*2;
1907 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
1909 if (bmpImage
->green_mask
==0x03e0) {
1910 if (gSrc
==bmpImage
->green_mask
) {
1911 if (rSrc
==bmpImage
->red_mask
) {
1912 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
1913 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
1914 convs
->Convert_5x5_asis
1917 dstbits
,-bmpImage
->bytes_per_line
);
1918 } else if (rSrc
==bmpImage
->blue_mask
) {
1919 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
1920 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
1921 convs
->Convert_555_reverse
1924 dstbits
,-bmpImage
->bytes_per_line
);
1927 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
1928 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
1929 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
1930 convs
->Convert_565_to_555_asis
1933 dstbits
,-bmpImage
->bytes_per_line
);
1935 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
1936 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
1937 convs
->Convert_565_to_555_reverse
1940 dstbits
,-bmpImage
->bytes_per_line
);
1943 } else if (bmpImage
->green_mask
==0x07e0) {
1944 if (gSrc
==bmpImage
->green_mask
) {
1945 if (rSrc
==bmpImage
->red_mask
) {
1946 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
1947 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
1948 convs
->Convert_5x5_asis
1951 dstbits
,-bmpImage
->bytes_per_line
);
1953 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
1954 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
1955 convs
->Convert_565_reverse
1958 dstbits
,-bmpImage
->bytes_per_line
);
1961 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
1962 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
1963 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
1964 convs
->Convert_555_to_565_asis
1967 dstbits
,-bmpImage
->bytes_per_line
);
1969 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
1970 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
1971 convs
->Convert_555_to_565_reverse
1974 dstbits
,-bmpImage
->bytes_per_line
);
1984 if (bmpImage
->bits_per_pixel
==24) {
1987 srcbits
=srcbits
+left
*2;
1988 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
1990 if (bmpImage
->green_mask
!=0x00ff00 ||
1991 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1993 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
1994 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
1996 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
1997 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
1998 convs
->Convert_555_to_888_asis
2001 dstbits
,-bmpImage
->bytes_per_line
);
2003 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
2004 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
2005 convs
->Convert_565_to_888_asis
2008 dstbits
,-bmpImage
->bytes_per_line
);
2012 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
2013 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
2014 convs
->Convert_555_to_888_reverse
2017 dstbits
,-bmpImage
->bytes_per_line
);
2019 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
2020 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
2021 convs
->Convert_565_to_888_reverse
2024 dstbits
,-bmpImage
->bytes_per_line
);
2035 srcbits
=srcbits
+left
*2;
2036 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
2038 if (bmpImage
->green_mask
!=0x00ff00 ||
2039 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2041 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
2042 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
2044 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
2045 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
2046 convs
->Convert_555_to_0888_asis
2049 dstbits
,-bmpImage
->bytes_per_line
);
2051 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
2052 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
2053 convs
->Convert_565_to_0888_asis
2056 dstbits
,-bmpImage
->bytes_per_line
);
2060 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
2061 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
2062 convs
->Convert_555_to_0888_reverse
2065 dstbits
,-bmpImage
->bytes_per_line
);
2067 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
2068 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
2069 convs
->Convert_565_to_0888_reverse
2072 dstbits
,-bmpImage
->bytes_per_line
);
2080 WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2081 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
2082 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2088 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
2089 const WORD
* srcpixel
;
2090 int rShift1
,gShift1
,bShift1
;
2091 int rShift2
,gShift2
,bShift2
;
2094 /* Set color scaling values */
2095 rShift1
=16+X11DRV_DIB_MaskToShift(rSrc
)-3;
2096 gShift1
=16+X11DRV_DIB_MaskToShift(gSrc
)-3;
2097 bShift1
=16+X11DRV_DIB_MaskToShift(bSrc
)-3;
2102 /* Green has 5 bits, like the others */
2106 /* Green has 6 bits, not 5. Compensate. */
2115 /* We could split it into four separate cases to optimize
2116 * but it is probably not worth it.
2118 for (h
=lines
-1; h
>=0; h
--) {
2119 srcpixel
=(const WORD
*)srcbits
;
2120 for (x
=left
; x
<width
+left
; x
++) {
2122 BYTE red
,green
,blue
;
2123 srcval
=*srcpixel
++ << 16;
2124 red
= ((srcval
>> rShift1
) & 0xf8) |
2125 ((srcval
>> rShift2
) & 0x07);
2126 green
=((srcval
>> gShift1
) & gMask1
) |
2127 ((srcval
>> gShift2
) & gMask2
);
2128 blue
= ((srcval
>> bShift1
) & 0xf8) |
2129 ((srcval
>> bShift2
) & 0x07);
2130 XPutPixel(bmpImage
, x
, h
,
2131 X11DRV_PALETTE_ToPhysical
2132 (physDev
, RGB(red
,green
,blue
)));
2134 srcbits
+= linebytes
;
2142 /***********************************************************************
2143 * X11DRV_DIB_GetImageBits_16
2145 * GetDIBits for an 16-bit deep DIB.
2147 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*dstbits
,
2148 DWORD dstwidth
, DWORD srcwidth
,
2149 PALETTEENTRY
*srccolors
,
2150 DWORD rDst
, DWORD gDst
, DWORD bDst
,
2151 XImage
*bmpImage
, DWORD dibpitch
)
2154 int h
, width
= min(srcwidth
, dstwidth
);
2155 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
2157 DWORD linebytes
= dibpitch
;
2162 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
2163 linebytes
= -linebytes
;
2166 switch (bmpImage
->depth
)
2171 const char* srcbits
;
2173 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2175 if (bmpImage
->green_mask
==0x03e0) {
2176 if (gDst
==bmpImage
->green_mask
) {
2177 if (rDst
==bmpImage
->red_mask
) {
2178 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
2179 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
2180 convs
->Convert_5x5_asis
2182 srcbits
,-bmpImage
->bytes_per_line
,
2185 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
2186 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
2187 convs
->Convert_555_reverse
2189 srcbits
,-bmpImage
->bytes_per_line
,
2193 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
2194 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
2195 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
2196 convs
->Convert_555_to_565_asis
2198 srcbits
,-bmpImage
->bytes_per_line
,
2201 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
2202 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
2203 convs
->Convert_555_to_565_reverse
2205 srcbits
,-bmpImage
->bytes_per_line
,
2209 } else if (bmpImage
->green_mask
==0x07e0) {
2210 if (gDst
==bmpImage
->green_mask
) {
2211 if (rDst
== bmpImage
->red_mask
) {
2212 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
2213 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
2214 convs
->Convert_5x5_asis
2216 srcbits
,-bmpImage
->bytes_per_line
,
2219 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
2220 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
2221 convs
->Convert_565_reverse
2223 srcbits
,-bmpImage
->bytes_per_line
,
2227 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
2228 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
2229 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
2230 convs
->Convert_565_to_555_asis
2232 srcbits
,-bmpImage
->bytes_per_line
,
2235 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
2236 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
2237 convs
->Convert_565_to_555_reverse
2239 srcbits
,-bmpImage
->bytes_per_line
,
2250 if (bmpImage
->bits_per_pixel
== 24) {
2251 const char* srcbits
;
2253 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2255 if (bmpImage
->green_mask
!=0x00ff00 ||
2256 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2258 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
2259 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
2261 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
2262 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
2263 convs
->Convert_888_to_555_asis
2265 srcbits
,-bmpImage
->bytes_per_line
,
2268 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2269 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2270 convs
->Convert_888_to_565_asis
2272 srcbits
,-bmpImage
->bytes_per_line
,
2277 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
2278 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
2279 convs
->Convert_888_to_555_reverse
2281 srcbits
,-bmpImage
->bytes_per_line
,
2284 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
2285 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
2286 convs
->Convert_888_to_565_reverse
2288 srcbits
,-bmpImage
->bytes_per_line
,
2298 const char* srcbits
;
2300 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2302 if (bmpImage
->green_mask
!=0x00ff00 ||
2303 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2305 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
2306 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
2308 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
2309 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
2310 convs
->Convert_0888_to_555_asis
2312 srcbits
,-bmpImage
->bytes_per_line
,
2315 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
2316 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
2317 convs
->Convert_0888_to_565_asis
2319 srcbits
,-bmpImage
->bytes_per_line
,
2324 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
2325 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
2326 convs
->Convert_0888_to_555_reverse
2328 srcbits
,-bmpImage
->bytes_per_line
,
2331 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
2332 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
2333 convs
->Convert_0888_to_565_reverse
2335 srcbits
,-bmpImage
->bytes_per_line
,
2344 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2345 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
2346 int rShift
,gShift
,bShift
;
2349 /* Shift everything 16 bits left so that all shifts are >0,
2350 * even for BGR DIBs. Then a single >> 16 will bring everything
2353 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2354 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2355 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2357 /* 6 bits for the green */
2363 for (h
= lines
- 1; h
>= 0; h
--) {
2364 dstpixel
=(LPWORD
)dstbits
;
2365 for (x
= 0; x
< width
; x
++) {
2366 PALETTEENTRY srcval
;
2368 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2369 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
2370 ((srcval
.peGreen
<< gShift
) & gDst
) |
2371 ((srcval
.peBlue
<< bShift
) & bDst
);
2372 *dstpixel
++=dstval
>> 16;
2374 dstbits
+= linebytes
;
2382 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2383 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
2384 int rShift
,gShift
,bShift
;
2385 const BYTE
* srcbits
;
2386 const BYTE
* srcpixel
;
2389 /* Shift everything 16 bits left so that all shifts are >0,
2390 * even for BGR DIBs. Then a single >> 16 will bring everything
2393 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2394 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2395 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2397 /* 6 bits for the green */
2403 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2404 for (h
=0; h
<lines
; h
++) {
2406 dstpixel
=(LPWORD
)dstbits
;
2407 for (x
= 0; x
< width
; x
++) {
2408 PALETTEENTRY srcval
;
2410 srcval
=srccolors
[(int)*srcpixel
++];
2411 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
2412 ((srcval
.peGreen
<< gShift
) & gDst
) |
2413 ((srcval
.peBlue
<< bShift
) & bDst
);
2414 *dstpixel
++=dstval
>> 16;
2416 srcbits
-= bmpImage
->bytes_per_line
;
2417 dstbits
+= linebytes
;
2427 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
2428 int rShift
,gShift
,bShift
;
2431 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
2432 bmpImage
->depth
, bmpImage
->red_mask
,
2433 bmpImage
->green_mask
, bmpImage
->blue_mask
,
2436 /* Shift everything 16 bits left so that all shifts are >0,
2437 * even for BGR DIBs. Then a single >> 16 will bring everything
2440 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2441 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2442 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2444 /* 6 bits for the green */
2450 for (h
= lines
- 1; h
>= 0; h
--) {
2451 dstpixel
=(LPWORD
)dstbits
;
2452 for (x
= 0; x
< width
; x
++) {
2455 srcval
=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage
, x
, h
));
2456 dstval
=((GetRValue(srcval
) << rShift
) & rDst
) |
2457 ((GetGValue(srcval
) << gShift
) & gDst
) |
2458 ((GetBValue(srcval
) << bShift
) & bDst
);
2459 *dstpixel
++=dstval
>> 16;
2461 dstbits
+= linebytes
;
2469 /***********************************************************************
2470 * X11DRV_DIB_SetImageBits_24
2472 * SetDIBits for a 24-bit deep DIB.
2474 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
2475 DWORD srcwidth
, DWORD dstwidth
, int left
,
2476 X11DRV_PDEVICE
*physDev
,
2477 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
2478 XImage
*bmpImage
, DWORD linebytes
)
2481 int h
, width
= min(srcwidth
, dstwidth
);
2482 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
2487 srcbits
= srcbits
+ linebytes
* (lines
- 1);
2488 linebytes
= -linebytes
;
2491 switch (bmpImage
->depth
)
2494 if (bmpImage
->bits_per_pixel
==24) {
2497 srcbits
=srcbits
+left
*3;
2498 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
2500 if (bmpImage
->green_mask
!=0x00ff00 ||
2501 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2503 } else if (rSrc
==bmpImage
->red_mask
) {
2504 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
2505 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
2506 convs
->Convert_888_asis
2509 dstbits
,-bmpImage
->bytes_per_line
);
2511 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
2512 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
2513 convs
->Convert_888_reverse
2516 dstbits
,-bmpImage
->bytes_per_line
);
2526 srcbits
=srcbits
+left
*3;
2527 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
2529 if (bmpImage
->green_mask
!=0x00ff00 ||
2530 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2532 } else if (rSrc
==bmpImage
->red_mask
) {
2533 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
2534 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
2535 convs
->Convert_888_to_0888_asis
2538 dstbits
,-bmpImage
->bytes_per_line
);
2540 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
2541 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
2542 convs
->Convert_888_to_0888_reverse
2545 dstbits
,-bmpImage
->bytes_per_line
);
2555 srcbits
=srcbits
+left
*3;
2556 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2558 if (bmpImage
->green_mask
==0x03e0) {
2559 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
2560 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
2561 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
2562 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
2563 convs
->Convert_888_to_555_asis
2566 dstbits
,-bmpImage
->bytes_per_line
);
2567 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0x7f00) ||
2568 (bSrc
==0xff && bmpImage
->blue_mask
==0x7f00)) {
2569 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
2570 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
2571 convs
->Convert_888_to_555_reverse
2574 dstbits
,-bmpImage
->bytes_per_line
);
2578 } else if (bmpImage
->green_mask
==0x07e0) {
2579 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
2580 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
2581 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
2582 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
2583 convs
->Convert_888_to_565_asis
2586 dstbits
,-bmpImage
->bytes_per_line
);
2587 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0xf800) ||
2588 (bSrc
==0xff && bmpImage
->blue_mask
==0xf800)) {
2589 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
2590 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
2591 convs
->Convert_888_to_565_reverse
2594 dstbits
,-bmpImage
->bytes_per_line
);
2606 WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2607 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
2608 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2614 /* ==== rgb 888 dib -> any bmp bormat ==== */
2615 const BYTE
* srcbyte
;
2617 /* Windows only supports one 24bpp DIB format: RGB888 */
2619 for (h
= lines
- 1; h
>= 0; h
--) {
2620 srcbyte
=(const BYTE
*)srcbits
;
2621 for (x
= left
; x
< width
+left
; x
++) {
2622 XPutPixel(bmpImage
, x
, h
,
2623 X11DRV_PALETTE_ToPhysical
2624 (physDev
, RGB(srcbyte
[2], srcbyte
[1], srcbyte
[0])));
2627 srcbits
+= linebytes
;
2635 /***********************************************************************
2636 * X11DRV_DIB_GetImageBits_24
2638 * GetDIBits for an 24-bit deep DIB.
2640 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*dstbits
,
2641 DWORD dstwidth
, DWORD srcwidth
,
2642 PALETTEENTRY
*srccolors
,
2643 DWORD rDst
, DWORD gDst
, DWORD bDst
,
2644 XImage
*bmpImage
, DWORD linebytes
)
2647 int h
, width
= min(srcwidth
, dstwidth
);
2648 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
2653 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2654 linebytes
= -linebytes
;
2657 switch (bmpImage
->depth
)
2660 if (bmpImage
->bits_per_pixel
==24) {
2661 const char* srcbits
;
2663 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2665 if (bmpImage
->green_mask
!=0x00ff00 ||
2666 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2668 } else if (rDst
==bmpImage
->red_mask
) {
2669 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
2670 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
2671 convs
->Convert_888_asis
2673 srcbits
,-bmpImage
->bytes_per_line
,
2676 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
2677 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
2678 convs
->Convert_888_reverse
2680 srcbits
,-bmpImage
->bytes_per_line
,
2689 const char* srcbits
;
2691 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2693 if (bmpImage
->green_mask
!=0x00ff00 ||
2694 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2696 } else if (rDst
==bmpImage
->red_mask
) {
2697 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
2698 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
2699 convs
->Convert_0888_to_888_asis
2701 srcbits
,-bmpImage
->bytes_per_line
,
2704 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
2705 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
2706 convs
->Convert_0888_to_888_reverse
2708 srcbits
,-bmpImage
->bytes_per_line
,
2717 const char* srcbits
;
2719 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2721 if (bmpImage
->green_mask
==0x03e0) {
2722 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
2723 (bDst
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
2724 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
2725 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
2726 convs
->Convert_555_to_888_asis
2728 srcbits
,-bmpImage
->bytes_per_line
,
2730 } else if ((rDst
==0xff && bmpImage
->red_mask
==0x7f00) ||
2731 (bDst
==0xff && bmpImage
->blue_mask
==0x7f00)) {
2732 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
2733 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
2734 convs
->Convert_555_to_888_reverse
2736 srcbits
,-bmpImage
->bytes_per_line
,
2741 } else if (bmpImage
->green_mask
==0x07e0) {
2742 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
2743 (bDst
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
2744 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
2745 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
2746 convs
->Convert_565_to_888_asis
2748 srcbits
,-bmpImage
->bytes_per_line
,
2750 } else if ((rDst
==0xff && bmpImage
->red_mask
==0xf800) ||
2751 (bDst
==0xff && bmpImage
->blue_mask
==0xf800)) {
2752 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
2753 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
2754 convs
->Convert_565_to_888_reverse
2756 srcbits
,-bmpImage
->bytes_per_line
,
2769 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2770 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
2773 /* Windows only supports one 24bpp DIB format: rgb 888 */
2774 for (h
= lines
- 1; h
>= 0; h
--) {
2776 for (x
= 0; x
< width
; x
++) {
2777 PALETTEENTRY srcval
;
2778 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2779 dstbyte
[0]=srcval
.peBlue
;
2780 dstbyte
[1]=srcval
.peGreen
;
2781 dstbyte
[2]=srcval
.peRed
;
2784 dstbits
+= linebytes
;
2792 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
== 0 && srccolors
) {
2793 /* ==== pal 8 bmp -> rgb 888 dib ==== */
2794 const void* srcbits
;
2795 const BYTE
* srcpixel
;
2798 /* Windows only supports one 24bpp DIB format: rgb 888 */
2799 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2800 for (h
= lines
- 1; h
>= 0; h
--) {
2803 for (x
= 0; x
< width
; x
++ ) {
2804 PALETTEENTRY srcval
;
2805 srcval
=srccolors
[(int)*srcpixel
++];
2806 dstbyte
[0]=srcval
.peBlue
;
2807 dstbyte
[1]=srcval
.peGreen
;
2808 dstbyte
[2]=srcval
.peRed
;
2811 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
2812 dstbits
+= linebytes
;
2822 /* ==== any bmp format -> 888 dib ==== */
2825 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
2826 bmpImage
->depth
, bmpImage
->red_mask
,
2827 bmpImage
->green_mask
, bmpImage
->blue_mask
,
2830 /* Windows only supports one 24bpp DIB format: rgb 888 */
2831 for (h
= lines
- 1; h
>= 0; h
--) {
2833 for (x
= 0; x
< width
; x
++) {
2834 COLORREF srcval
=X11DRV_PALETTE_ToLogical
2835 (XGetPixel( bmpImage
, x
, h
));
2836 dstbyte
[0]=GetBValue(srcval
);
2837 dstbyte
[1]=GetGValue(srcval
);
2838 dstbyte
[2]=GetRValue(srcval
);
2841 dstbits
+= linebytes
;
2849 /***********************************************************************
2850 * X11DRV_DIB_SetImageBits_32
2852 * SetDIBits for a 32-bit deep DIB.
2854 static void X11DRV_DIB_SetImageBits_32(int lines
, const BYTE
*srcbits
,
2855 DWORD srcwidth
, DWORD dstwidth
, int left
,
2856 X11DRV_PDEVICE
*physDev
,
2857 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
2863 int h
, width
= min(srcwidth
, dstwidth
);
2864 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
2869 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
2870 linebytes
= -linebytes
;
2873 ptr
= (const DWORD
*) srcbits
+ left
;
2875 switch (bmpImage
->depth
)
2878 if (bmpImage
->bits_per_pixel
==24) {
2881 srcbits
=srcbits
+left
*4;
2882 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
2884 if (rSrc
==bmpImage
->red_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->blue_mask
) {
2885 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
2886 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
2887 convs
->Convert_0888_to_888_asis
2890 dstbits
,-bmpImage
->bytes_per_line
);
2891 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2892 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2894 /* the tests below assume sane bmpImage masks */
2895 } else if (rSrc
==bmpImage
->blue_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->red_mask
) {
2896 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
2897 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
2898 convs
->Convert_0888_to_888_reverse
2901 dstbits
,-bmpImage
->bytes_per_line
);
2902 } else if (bmpImage
->blue_mask
==0xff) {
2903 /* ==== any 0888 dib -> rgb 888 bmp ==== */
2904 convs
->Convert_any0888_to_rgb888
2908 dstbits
,-bmpImage
->bytes_per_line
);
2910 /* ==== any 0888 dib -> bgr 888 bmp ==== */
2911 convs
->Convert_any0888_to_bgr888
2915 dstbits
,-bmpImage
->bytes_per_line
);
2925 srcbits
=srcbits
+left
*4;
2926 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
2928 if (gSrc
==bmpImage
->green_mask
) {
2929 if (rSrc
==bmpImage
->red_mask
&& bSrc
==bmpImage
->blue_mask
) {
2930 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
2931 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
2932 convs
->Convert_0888_asis
2935 dstbits
,-bmpImage
->bytes_per_line
);
2936 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2937 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2939 /* the tests below assume sane bmpImage masks */
2940 } else if (rSrc
==bmpImage
->blue_mask
&& bSrc
==bmpImage
->red_mask
) {
2941 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
2942 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
2943 convs
->Convert_0888_reverse
2946 dstbits
,-bmpImage
->bytes_per_line
);
2948 /* ==== any 0888 dib -> any 0888 bmp ==== */
2949 convs
->Convert_0888_any
2953 dstbits
,-bmpImage
->bytes_per_line
,
2954 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2956 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2957 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2959 /* the tests below assume sane bmpImage masks */
2961 /* ==== any 0888 dib -> any 0888 bmp ==== */
2962 convs
->Convert_0888_any
2966 dstbits
,-bmpImage
->bytes_per_line
,
2967 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2977 srcbits
=srcbits
+left
*4;
2978 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2980 if (rSrc
==0xff0000 && gSrc
==0x00ff00 && bSrc
==0x0000ff) {
2981 if (bmpImage
->green_mask
==0x03e0) {
2982 if (bmpImage
->red_mask
==0x7f00) {
2983 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
2984 convs
->Convert_0888_to_555_asis
2987 dstbits
,-bmpImage
->bytes_per_line
);
2988 } else if (bmpImage
->blue_mask
==0x7f00) {
2989 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
2990 convs
->Convert_0888_to_555_reverse
2993 dstbits
,-bmpImage
->bytes_per_line
);
2997 } else if (bmpImage
->green_mask
==0x07e0) {
2998 if (bmpImage
->red_mask
==0xf800) {
2999 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
3000 convs
->Convert_0888_to_565_asis
3003 dstbits
,-bmpImage
->bytes_per_line
);
3004 } else if (bmpImage
->blue_mask
==0xf800) {
3005 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
3006 convs
->Convert_0888_to_565_reverse
3009 dstbits
,-bmpImage
->bytes_per_line
);
3016 } else if (rSrc
==0x0000ff && gSrc
==0x00ff00 && bSrc
==0xff0000) {
3017 if (bmpImage
->green_mask
==0x03e0) {
3018 if (bmpImage
->blue_mask
==0x7f00) {
3019 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
3020 convs
->Convert_0888_to_555_asis
3023 dstbits
,-bmpImage
->bytes_per_line
);
3024 } else if (bmpImage
->red_mask
==0x7f00) {
3025 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
3026 convs
->Convert_0888_to_555_reverse
3029 dstbits
,-bmpImage
->bytes_per_line
);
3033 } else if (bmpImage
->green_mask
==0x07e0) {
3034 if (bmpImage
->blue_mask
==0xf800) {
3035 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
3036 convs
->Convert_0888_to_565_asis
3039 dstbits
,-bmpImage
->bytes_per_line
);
3040 } else if (bmpImage
->red_mask
==0xf800) {
3041 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
3042 convs
->Convert_0888_to_565_reverse
3045 dstbits
,-bmpImage
->bytes_per_line
);
3053 if (bmpImage
->green_mask
==0x03e0 &&
3054 (bmpImage
->red_mask
==0x7f00 ||
3055 bmpImage
->blue_mask
==0x7f00)) {
3056 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
3057 convs
->Convert_any0888_to_5x5
3061 dstbits
,-bmpImage
->bytes_per_line
,
3062 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
3063 } else if (bmpImage
->green_mask
==0x07e0 &&
3064 (bmpImage
->red_mask
==0xf800 ||
3065 bmpImage
->blue_mask
==0xf800)) {
3066 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
3067 convs
->Convert_any0888_to_5x5
3071 dstbits
,-bmpImage
->bytes_per_line
,
3072 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
3082 WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3083 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
3084 bmpImage
->green_mask
, bmpImage
->blue_mask
);
3090 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
3091 const DWORD
* srcpixel
;
3092 int rShift
,gShift
,bShift
;
3094 rShift
=X11DRV_DIB_MaskToShift(rSrc
);
3095 gShift
=X11DRV_DIB_MaskToShift(gSrc
);
3096 bShift
=X11DRV_DIB_MaskToShift(bSrc
);
3098 for (h
= lines
- 1; h
>= 0; h
--) {
3099 srcpixel
=(const DWORD
*)srcbits
;
3100 for (x
= left
; x
< width
+left
; x
++) {
3102 BYTE red
,green
,blue
;
3103 srcvalue
=*srcpixel
++;
3104 red
= (srcvalue
>> rShift
) & 0xff;
3105 green
=(srcvalue
>> gShift
) & 0xff;
3106 blue
= (srcvalue
>> bShift
) & 0xff;
3107 XPutPixel(bmpImage
, x
, h
, X11DRV_PALETTE_ToPhysical
3108 (physDev
, RGB(red
,green
,blue
)));
3110 srcbits
+= linebytes
;
3118 /***********************************************************************
3119 * X11DRV_DIB_GetImageBits_32
3121 * GetDIBits for an 32-bit deep DIB.
3123 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*dstbits
,
3124 DWORD dstwidth
, DWORD srcwidth
,
3125 PALETTEENTRY
*srccolors
,
3126 DWORD rDst
, DWORD gDst
, DWORD bDst
,
3127 XImage
*bmpImage
, DWORD linebytes
)
3130 int h
, width
= min(srcwidth
, dstwidth
);
3132 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
3137 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
3138 linebytes
= -linebytes
;
3143 switch (bmpImage
->depth
)
3146 if (bmpImage
->bits_per_pixel
==24) {
3147 const void* srcbits
;
3149 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3151 if (rDst
==bmpImage
->red_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->blue_mask
) {
3152 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3153 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3154 convs
->Convert_888_to_0888_asis
3156 srcbits
,-bmpImage
->bytes_per_line
,
3158 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3159 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3161 /* the tests below assume sane bmpImage masks */
3162 } else if (rDst
==bmpImage
->blue_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->red_mask
) {
3163 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3164 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3165 convs
->Convert_888_to_0888_reverse
3167 srcbits
,-bmpImage
->bytes_per_line
,
3169 } else if (bmpImage
->blue_mask
==0xff) {
3170 /* ==== rgb 888 bmp -> any 0888 dib ==== */
3171 convs
->Convert_rgb888_to_any0888
3173 srcbits
,-bmpImage
->bytes_per_line
,
3177 /* ==== bgr 888 bmp -> any 0888 dib ==== */
3178 convs
->Convert_bgr888_to_any0888
3180 srcbits
,-bmpImage
->bytes_per_line
,
3190 const char* srcbits
;
3192 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3194 if (gDst
==bmpImage
->green_mask
) {
3195 if (rDst
==bmpImage
->red_mask
&& bDst
==bmpImage
->blue_mask
) {
3196 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
3197 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
3198 convs
->Convert_0888_asis
3200 srcbits
,-bmpImage
->bytes_per_line
,
3202 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3203 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3205 /* the tests below assume sane bmpImage masks */
3206 } else if (rDst
==bmpImage
->blue_mask
&& bDst
==bmpImage
->red_mask
) {
3207 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
3208 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
3209 convs
->Convert_0888_reverse
3211 srcbits
,-bmpImage
->bytes_per_line
,
3214 /* ==== any 0888 bmp -> any 0888 dib ==== */
3215 convs
->Convert_0888_any
3217 srcbits
,-bmpImage
->bytes_per_line
,
3218 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3222 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3223 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3225 /* the tests below assume sane bmpImage masks */
3227 /* ==== any 0888 bmp -> any 0888 dib ==== */
3228 convs
->Convert_0888_any
3230 srcbits
,-bmpImage
->bytes_per_line
,
3231 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3241 const char* srcbits
;
3243 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3245 if (rDst
==0xff0000 && gDst
==0x00ff00 && bDst
==0x0000ff) {
3246 if (bmpImage
->green_mask
==0x03e0) {
3247 if (bmpImage
->red_mask
==0x7f00) {
3248 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
3249 convs
->Convert_555_to_0888_asis
3251 srcbits
,-bmpImage
->bytes_per_line
,
3253 } else if (bmpImage
->blue_mask
==0x7f00) {
3254 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
3255 convs
->Convert_555_to_0888_reverse
3257 srcbits
,-bmpImage
->bytes_per_line
,
3262 } else if (bmpImage
->green_mask
==0x07e0) {
3263 if (bmpImage
->red_mask
==0xf800) {
3264 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
3265 convs
->Convert_565_to_0888_asis
3267 srcbits
,-bmpImage
->bytes_per_line
,
3269 } else if (bmpImage
->blue_mask
==0xf800) {
3270 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
3271 convs
->Convert_565_to_0888_reverse
3273 srcbits
,-bmpImage
->bytes_per_line
,
3281 } else if (rDst
==0x0000ff && gDst
==0x00ff00 && bDst
==0xff0000) {
3282 if (bmpImage
->green_mask
==0x03e0) {
3283 if (bmpImage
->blue_mask
==0x7f00) {
3284 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
3285 convs
->Convert_555_to_0888_asis
3287 srcbits
,-bmpImage
->bytes_per_line
,
3289 } else if (bmpImage
->red_mask
==0x7f00) {
3290 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
3291 convs
->Convert_555_to_0888_reverse
3293 srcbits
,-bmpImage
->bytes_per_line
,
3298 } else if (bmpImage
->green_mask
==0x07e0) {
3299 if (bmpImage
->blue_mask
==0xf800) {
3300 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
3301 convs
->Convert_565_to_0888_asis
3303 srcbits
,-bmpImage
->bytes_per_line
,
3305 } else if (bmpImage
->red_mask
==0xf800) {
3306 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
3307 convs
->Convert_565_to_0888_reverse
3309 srcbits
,-bmpImage
->bytes_per_line
,
3318 if (bmpImage
->green_mask
==0x03e0 &&
3319 (bmpImage
->red_mask
==0x7f00 ||
3320 bmpImage
->blue_mask
==0x7f00)) {
3321 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
3322 convs
->Convert_5x5_to_any0888
3324 srcbits
,-bmpImage
->bytes_per_line
,
3325 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3328 } else if (bmpImage
->green_mask
==0x07e0 &&
3329 (bmpImage
->red_mask
==0xf800 ||
3330 bmpImage
->blue_mask
==0xf800)) {
3331 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
3332 convs
->Convert_5x5_to_any0888
3334 srcbits
,-bmpImage
->bytes_per_line
,
3335 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3347 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3348 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
3349 int rShift
,gShift
,bShift
;
3352 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3353 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3354 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3355 for (h
= lines
- 1; h
>= 0; h
--) {
3356 dstpixel
=(DWORD
*)dstbits
;
3357 for (x
= 0; x
< width
; x
++) {
3358 PALETTEENTRY srcval
;
3359 srcval
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
3360 *dstpixel
++=(srcval
.peRed
<< rShift
) |
3361 (srcval
.peGreen
<< gShift
) |
3362 (srcval
.peBlue
<< bShift
);
3364 dstbits
+= linebytes
;
3372 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3373 /* ==== pal 8 bmp -> any 0888 dib ==== */
3374 int rShift
,gShift
,bShift
;
3375 const void* srcbits
;
3376 const BYTE
* srcpixel
;
3379 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3380 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3381 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3382 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3383 for (h
= lines
- 1; h
>= 0; h
--) {
3385 dstpixel
=(DWORD
*)dstbits
;
3386 for (x
= 0; x
< width
; x
++) {
3387 PALETTEENTRY srcval
;
3388 srcval
=srccolors
[(int)*srcpixel
++];
3389 *dstpixel
++=(srcval
.peRed
<< rShift
) |
3390 (srcval
.peGreen
<< gShift
) |
3391 (srcval
.peBlue
<< bShift
);
3393 srcbits
= (const char*)srcbits
- bmpImage
->bytes_per_line
;
3394 dstbits
+= linebytes
;
3404 /* ==== any bmp format -> any 0888 dib ==== */
3405 int rShift
,gShift
,bShift
;
3408 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
3409 bmpImage
->depth
, bmpImage
->red_mask
,
3410 bmpImage
->green_mask
, bmpImage
->blue_mask
,
3413 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3414 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3415 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3416 for (h
= lines
- 1; h
>= 0; h
--) {
3417 dstpixel
=(DWORD
*)dstbits
;
3418 for (x
= 0; x
< width
; x
++) {
3420 srcval
=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage
, x
, h
));
3421 *dstpixel
++=(GetRValue(srcval
) << rShift
) |
3422 (GetGValue(srcval
) << gShift
) |
3423 (GetBValue(srcval
) << bShift
);
3425 dstbits
+= linebytes
;
3432 /***********************************************************************
3433 * X11DRV_DIB_SetImageBits
3435 * Transfer the bits to an X image.
3436 * Helper function for SetDIBits() and SetDIBitsToDevice().
3438 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
3440 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
3445 bmpImage
= descr
->image
;
3447 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
3448 descr
->infoWidth
, lines
, 32, 0 );
3449 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
3450 if(bmpImage
->data
== NULL
) {
3451 ERR("Out of memory!\n");
3452 XDestroyImage( bmpImage
);
3453 wine_tsx11_unlock();
3458 TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
3459 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
3460 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
3461 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
3462 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
3464 /* Transfer the pixels */
3465 switch(descr
->infoBpp
)
3468 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
3469 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
3470 bmpImage
, descr
->dibpitch
);
3473 if (descr
->compression
) {
3474 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
3475 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
3476 bmpImage
, descr
->xSrc
, descr
->ySrc
);
3478 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
3479 descr
->infoWidth
, descr
->width
,
3480 descr
->xSrc
, (int *)(descr
->colorMap
),
3483 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
3484 descr
->infoWidth
, descr
->width
,
3485 descr
->xSrc
, (int*)(descr
->colorMap
),
3486 bmpImage
, descr
->dibpitch
);
3489 if (descr
->compression
) {
3490 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
3491 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
3492 bmpImage
, descr
->xSrc
, descr
->ySrc
);
3493 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
3494 descr
->infoWidth
, descr
->width
,
3495 descr
->xSrc
, (int *)(descr
->colorMap
),
3498 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
3499 descr
->infoWidth
, descr
->width
,
3500 descr
->xSrc
, (int *)(descr
->colorMap
),
3501 bmpImage
, descr
->dibpitch
);
3505 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
3506 descr
->infoWidth
, descr
->width
,
3507 descr
->xSrc
, descr
->physDev
,
3508 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3509 bmpImage
, descr
->dibpitch
);
3512 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
3513 descr
->infoWidth
, descr
->width
,
3514 descr
->xSrc
, descr
->physDev
,
3515 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3516 bmpImage
, descr
->dibpitch
);
3519 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
3520 descr
->infoWidth
, descr
->width
,
3521 descr
->xSrc
, descr
->physDev
,
3522 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3523 bmpImage
, descr
->dibpitch
);
3526 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
3530 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
3531 descr
->drawable
, descr
->gc
, bmpImage
,
3532 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3533 descr
->width
, descr
->height
);
3534 #ifdef HAVE_LIBXXSHM
3537 XShmPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
3538 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3539 descr
->width
, descr
->height
, FALSE
);
3540 XSync( gdi_display
, 0 );
3544 XPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
3545 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3546 descr
->width
, descr
->height
);
3548 if (!descr
->image
) XDestroyImage( bmpImage
);
3549 wine_tsx11_unlock();
3553 /***********************************************************************
3554 * X11DRV_DIB_GetImageBits
3556 * Transfer the bits from an X image.
3558 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
3560 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
3565 bmpImage
= descr
->image
;
3567 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
3568 descr
->infoWidth
, lines
, 32, 0 );
3569 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
3570 if(bmpImage
->data
== NULL
) {
3571 ERR("Out of memory!\n");
3572 XDestroyImage( bmpImage
);
3573 wine_tsx11_unlock();
3578 #ifdef HAVE_LIBXXSHM
3581 int saveRed
, saveGreen
, saveBlue
;
3583 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
3584 gdi_display
, descr
->drawable
, bmpImage
,
3585 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
3587 /* We must save and restore the bmpImage's masks in order
3588 * to preserve them across the call to XShmGetImage, which
3589 * decides to eleminate them since it doesn't happen to know
3590 * what the format of the image is supposed to be, even though
3592 saveRed
= bmpImage
->red_mask
;
3593 saveBlue
= bmpImage
->blue_mask
;
3594 saveGreen
= bmpImage
->green_mask
;
3596 XShmGetImage( gdi_display
, descr
->drawable
, bmpImage
,
3597 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
3599 bmpImage
->red_mask
= saveRed
;
3600 bmpImage
->blue_mask
= saveBlue
;
3601 bmpImage
->green_mask
= saveGreen
;
3604 #endif /* HAVE_LIBXXSHM */
3606 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
3607 gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
, descr
->width
,
3608 lines
, AllPlanes
, ZPixmap
, bmpImage
, descr
->xDest
, descr
->yDest
);
3609 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
,
3610 descr
->width
, lines
, AllPlanes
, ZPixmap
,
3611 bmpImage
, descr
->xDest
, descr
->yDest
);
3614 TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
3615 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
3616 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
3617 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
3618 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
3619 /* Transfer the pixels */
3620 switch(descr
->infoBpp
)
3623 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
3624 descr
->infoWidth
, descr
->width
,
3625 descr
->colorMap
, descr
->palentry
,
3626 bmpImage
, descr
->dibpitch
);
3630 if (descr
->compression
) {
3631 FIXME("Compression not yet supported!\n");
3632 if(descr
->sizeImage
< X11DRV_DIB_GetDIBWidthBytes( descr
->infoWidth
, 4 ) * abs(descr
->lines
))
3635 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
3636 descr
->infoWidth
, descr
->width
,
3637 descr
->colorMap
, descr
->palentry
,
3638 bmpImage
, descr
->dibpitch
);
3641 if (descr
->compression
) {
3642 FIXME("Compression not yet supported!\n");
3643 if(descr
->sizeImage
< X11DRV_DIB_GetDIBWidthBytes( descr
->infoWidth
, 8 ) * abs(descr
->lines
))
3646 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
3647 descr
->infoWidth
, descr
->width
,
3648 descr
->colorMap
, descr
->palentry
,
3649 bmpImage
, descr
->dibpitch
);
3653 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
3654 descr
->infoWidth
,descr
->width
,
3656 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3657 bmpImage
, descr
->dibpitch
);
3661 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
3662 descr
->infoWidth
,descr
->width
,
3664 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3665 bmpImage
, descr
->dibpitch
);
3669 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
3670 descr
->infoWidth
, descr
->width
,
3672 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3673 bmpImage
, descr
->dibpitch
);
3677 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
3681 if (!descr
->image
) XDestroyImage( bmpImage
);
3682 wine_tsx11_unlock();
3686 /*************************************************************************
3687 * X11DRV_SetDIBitsToDevice
3690 INT
X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE
*physDev
, INT xDest
, INT yDest
, DWORD cx
,
3691 DWORD cy
, INT xSrc
, INT ySrc
,
3692 UINT startscan
, UINT lines
, LPCVOID bits
,
3693 const BITMAPINFO
*info
, UINT coloruse
)
3695 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3702 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
3703 &descr
.infoBpp
, &descr
.compression
) == -1)
3706 top_down
= (height
< 0);
3707 if (top_down
) height
= -height
;
3711 LPtoDP(physDev
->hdc
, &pt
, 1);
3713 if (!lines
|| (startscan
>= height
)) return 0;
3714 if (!top_down
&& startscan
+ lines
> height
) lines
= height
- startscan
;
3716 /* make xSrc,ySrc point to the upper-left corner, not the lower-left one,
3717 * and clamp all values to fit inside [startscan,startscan+lines]
3719 if (ySrc
+ cy
<= startscan
+ lines
)
3721 UINT y
= startscan
+ lines
- (ySrc
+ cy
);
3722 if (ySrc
< startscan
) cy
-= (startscan
- ySrc
);
3725 /* avoid getting unnecessary lines */
3727 if (y
>= lines
) return 0;
3732 if (y
>= lines
) return lines
;
3733 ySrc
= y
; /* need to get all lines in top down mode */
3738 if (ySrc
>= startscan
+ lines
) return lines
;
3739 pt
.y
+= ySrc
+ cy
- (startscan
+ lines
);
3740 cy
= startscan
+ lines
- ySrc
;
3742 if (cy
> lines
) cy
= lines
;
3744 if (xSrc
>= width
) return lines
;
3745 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
3746 if (!cx
|| !cy
) return lines
;
3748 /* Update the pixmap from the DIB section */
3749 X11DRV_LockDIBSection(physDev
, DIB_Status_GdiMod
, FALSE
);
3751 X11DRV_SetupGCForText( physDev
); /* To have the correct colors */
3753 XSetFunction(gdi_display
, physDev
->gc
, X11DRV_XROPfunction
[GetROP2(physDev
->hdc
) - 1]);
3754 wine_tsx11_unlock();
3756 colorPtr
= (LPBYTE
) info
+ (WORD
) info
->bmiHeader
.biSize
;
3758 switch (descr
.infoBpp
)
3763 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
3764 coloruse
== DIB_PAL_COLORS
? physDev
: NULL
, coloruse
,
3765 physDev
->depth
, info
, &descr
.nColorMap
);
3766 if (!descr
.colorMap
) return 0;
3767 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3771 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
) : 0x7c00;
3772 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
+ 1) : 0x03e0;
3773 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
+ 2) : 0x001f;
3779 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
) : 0xff0000;
3780 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
+ 1) : 0x00ff00;
3781 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
+ 2) : 0x0000ff;
3786 descr
.physDev
= physDev
;
3789 descr
.palentry
= NULL
;
3790 descr
.lines
= top_down
? -lines
: lines
;
3791 descr
.infoWidth
= width
;
3792 descr
.depth
= physDev
->depth
;
3793 descr
.drawable
= physDev
->drawable
;
3794 descr
.gc
= physDev
->gc
;
3797 descr
.xDest
= physDev
->org
.x
+ pt
.x
;
3798 descr
.yDest
= physDev
->org
.y
+ pt
.y
;
3801 descr
.useShm
= FALSE
;
3802 descr
.dibpitch
= ((width
* descr
.infoBpp
+ 31) &~31) / 8;
3804 result
= X11DRV_DIB_SetImageBits( &descr
);
3806 if (descr
.infoBpp
<= 8)
3807 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
3809 /* Update the DIBSection of the pixmap */
3810 X11DRV_UnlockDIBSection(physDev
, TRUE
);
3815 /***********************************************************************
3816 * SetDIBits (X11DRV.@)
3818 INT
X11DRV_SetDIBits( X11DRV_PDEVICE
*physDev
, HBITMAP hbitmap
, UINT startscan
,
3819 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
, UINT coloruse
)
3821 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3823 LONG height
, tmpheight
;
3827 descr
.physDev
= physDev
;
3829 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
3830 &descr
.infoBpp
, &descr
.compression
) == -1)
3834 if (height
< 0) height
= -height
;
3835 if (!lines
|| (startscan
>= height
))
3838 if (!(bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
))) return 0;
3840 if (startscan
+ lines
> height
) lines
= height
- startscan
;
3842 colorPtr
= (LPBYTE
) info
+ (WORD
) info
->bmiHeader
.biSize
;
3844 switch (descr
.infoBpp
)
3849 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
3850 coloruse
== DIB_PAL_COLORS
? descr
.physDev
: NULL
, coloruse
,
3851 bmp
->bitmap
.bmBitsPixel
,
3852 info
, &descr
.nColorMap
);
3853 if (!descr
.colorMap
)
3855 GDI_ReleaseObj( hbitmap
);
3858 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3862 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
) : 0x7c00;
3863 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
+ 1) : 0x03e0;
3864 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
+ 2) : 0x001f;
3870 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
) : 0xff0000;
3871 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
+ 1) : 0x00ff00;
3872 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
+ 2) : 0x0000ff;
3881 descr
.palentry
= NULL
;
3882 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
3883 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3884 descr
.drawable
= X11DRV_get_pixmap( hbitmap
);
3885 descr
.gc
= BITMAP_GC(bmp
);
3889 descr
.yDest
= height
- startscan
- lines
;
3890 descr
.width
= bmp
->bitmap
.bmWidth
;
3891 descr
.height
= lines
;
3892 descr
.useShm
= FALSE
;
3893 descr
.dibpitch
= ((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8;
3894 X11DRV_DIB_Lock(bmp
, DIB_Status_GdiMod
, FALSE
);
3895 result
= X11DRV_DIB_SetImageBits( &descr
);
3896 X11DRV_DIB_Unlock(bmp
, TRUE
);
3898 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
3900 GDI_ReleaseObj( hbitmap
);
3904 /***********************************************************************
3905 * GetDIBits (X11DRV.@)
3907 INT
X11DRV_GetDIBits( X11DRV_PDEVICE
*physDev
, HBITMAP hbitmap
, UINT startscan
, UINT lines
,
3908 LPVOID bits
, BITMAPINFO
*info
, UINT coloruse
)
3910 X11DRV_DIBSECTION
*dib
;
3911 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3912 PALETTEENTRY palette
[256];
3920 GetPaletteEntries( GetCurrentObject( physDev
->hdc
, OBJ_PAL
), 0, 256, palette
);
3922 if (!(bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
))) return 0;
3924 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3926 bitmap_type
= DIB_GetBitmapInfo( (BITMAPINFOHEADER
*) info
, &descr
.infoWidth
, &tempHeight
, &descr
.infoBpp
, &descr
.compression
);
3927 descr
.lines
= tempHeight
;
3928 if (bitmap_type
== -1)
3930 ERR("Invalid bitmap\n");
3934 core_header
= (bitmap_type
== 0);
3935 colorPtr
= (LPBYTE
) info
+ (WORD
) info
->bmiHeader
.biSize
;
3937 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
3938 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
3939 (int)descr
.infoWidth
, descr
.lines
, startscan
);
3941 if( lines
> bmp
->bitmap
.bmHeight
) lines
= bmp
->bitmap
.bmHeight
;
3943 height
= descr
.lines
;
3944 if (height
< 0) height
= -height
;
3945 if( lines
> height
) lines
= height
;
3946 /* Top-down images have a negative biHeight, the scanlines of theses images
3947 * were inverted in X11DRV_DIB_GetImageBits_xx
3948 * To prevent this we simply change the sign of lines
3949 * (the number of scan lines to copy).
3950 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3952 if( descr
.lines
< 0 && lines
> 0) lines
= -lines
;
3954 if( startscan
>= bmp
->bitmap
.bmHeight
)
3960 descr
.colorMap
= NULL
;
3962 switch (descr
.infoBpp
)
3967 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3968 if(coloruse
== DIB_RGB_COLORS
)
3969 descr
.colorMap
= colorPtr
;
3971 int num_colors
= 1 << descr
.infoBpp
, i
;
3974 WORD
*index
= (WORD
*)colorPtr
;
3975 descr
.colorMap
= rgb
= HeapAlloc(GetProcessHeap(), 0, num_colors
* sizeof(RGBQUAD
));
3976 for(i
= 0; i
< num_colors
; i
++, rgb
++, index
++) {
3977 colref
= X11DRV_PALETTE_ToLogical(X11DRV_PALETTE_ToPhysical(physDev
, PALETTEINDEX(*index
)));
3978 rgb
->rgbRed
= GetRValue(colref
);
3979 rgb
->rgbGreen
= GetGValue(colref
);
3980 rgb
->rgbBlue
= GetBValue(colref
);
3981 rgb
->rgbReserved
= 0;
3987 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)colorPtr
) : 0x7c00;
3988 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)colorPtr
+ 1) : 0x03e0;
3989 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)colorPtr
+ 2) : 0x001f;
3993 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)colorPtr
) : 0xff0000;
3994 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)colorPtr
+ 1) : 0x00ff00;
3995 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)colorPtr
+ 2) : 0x0000ff;
3999 descr
.physDev
= physDev
;
4000 descr
.palentry
= palette
;
4003 descr
.lines
= lines
;
4004 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
4005 descr
.drawable
= X11DRV_get_pixmap( hbitmap
);
4006 descr
.gc
= BITMAP_GC(bmp
);
4007 descr
.width
= bmp
->bitmap
.bmWidth
;
4008 descr
.height
= bmp
->bitmap
.bmHeight
;
4012 descr
.sizeImage
= core_header
? 0 : info
->bmiHeader
.biSizeImage
;
4014 if (descr
.lines
> 0)
4016 descr
.ySrc
= (descr
.height
-1) - (startscan
+ (lines
-1));
4020 descr
.ySrc
= startscan
;
4022 #ifdef HAVE_LIBXXSHM
4023 descr
.useShm
= dib
? (dib
->shminfo
.shmid
!= -1) : FALSE
;
4025 descr
.useShm
= FALSE
;
4027 descr
.dibpitch
= dib
? (dib
->dibSection
.dsBm
.bmWidthBytes
)
4028 : (((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8);
4030 X11DRV_DIB_Lock(bmp
, DIB_Status_GdiMod
, FALSE
);
4031 X11DRV_DIB_GetImageBits( &descr
);
4032 X11DRV_DIB_Unlock(bmp
, TRUE
);
4034 if(!core_header
&& info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
4035 info
->bmiHeader
.biSizeImage
= X11DRV_DIB_GetDIBImageBytes( descr
.infoWidth
,
4039 if (descr
.compression
== BI_BITFIELDS
)
4041 *(DWORD
*) colorPtr
= descr
.rMask
;
4042 *((DWORD
*)colorPtr
+ 1) = descr
.gMask
;
4043 *((DWORD
*)colorPtr
+ 2) = descr
.bMask
;
4045 else if (!core_header
)
4047 /* if RLE or JPEG compression were supported,
4048 * this line would be invalid. */
4049 info
->bmiHeader
.biCompression
= 0;
4052 if(descr
.colorMap
&& descr
.colorMap
!= colorPtr
)
4053 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
4055 GDI_ReleaseObj( hbitmap
);
4059 /***********************************************************************
4060 * DIB_DoProtectDIBSection
4062 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
4066 DIBSECTION
*dib
= bmp
->dib
;
4067 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
4068 : -dib
->dsBm
.bmHeight
;
4070 /* use the biSizeImage data as the memory size only if we're dealing with a
4071 compressed image where the value is set. Otherwise, calculate based on
4073 if (dib
->dsBmih
.biSizeImage
&&
4074 (dib
->dsBmih
.biCompression
== BI_RLE4
|| dib
->dsBmih
.biCompression
== BI_RLE8
))
4075 totalSize
= dib
->dsBmih
.biSizeImage
;
4077 totalSize
= dib
->dsBm
.bmWidthBytes
* effHeight
;
4079 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
4080 TRACE("Changed protection from %ld to %ld\n", old_prot
, new_prot
);
4083 /***********************************************************************
4084 * X11DRV_DIB_DoUpdateDIBSection
4086 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
,
4087 void *colorMap
, int nColorMap
,
4089 DWORD xSrc
, DWORD ySrc
,
4090 DWORD xDest
, DWORD yDest
,
4091 DWORD width
, DWORD height
)
4093 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4094 X11DRV_DIB_IMAGEBITS_DESCR descr
;
4095 int identity
[2] = {0,1};
4097 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, (DWORD
*) &descr
.lines
,
4098 &descr
.infoBpp
, &descr
.compression
) == -1)
4101 descr
.physDev
= NULL
;
4102 descr
.palentry
= NULL
;
4103 descr
.image
= dib
->image
;
4104 descr
.colorMap
= colorMap
;
4105 descr
.nColorMap
= nColorMap
;
4106 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
4107 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
4109 if(descr
.infoBpp
== 1)
4110 descr
.colorMap
= (void*)identity
;
4112 switch (descr
.infoBpp
)
4117 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
4121 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0x7c00;
4122 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x03e0;
4123 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x001f;
4128 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0xff0000;
4129 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x00ff00;
4130 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x0000ff;
4135 descr
.drawable
= dest
;
4136 descr
.gc
= BITMAP_GC(bmp
);
4139 descr
.xDest
= xDest
;
4140 descr
.yDest
= yDest
;
4141 descr
.width
= width
;
4142 descr
.height
= height
;
4143 descr
.sizeImage
= 0;
4145 #ifdef HAVE_LIBXXSHM
4146 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
4148 descr
.useShm
= FALSE
;
4150 descr
.dibpitch
= dib
->dibSection
.dsBm
.bmWidthBytes
;
4154 TRACE("Copying from Pixmap to DIB bits\n");
4155 X11DRV_DIB_GetImageBits( &descr
);
4159 TRACE("Copying from DIB bits to Pixmap\n");
4160 X11DRV_DIB_SetImageBits( &descr
);
4164 /***********************************************************************
4165 * X11DRV_DIB_CopyDIBSection
4167 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE
*physDevSrc
, X11DRV_PDEVICE
*physDevDst
,
4168 DWORD xSrc
, DWORD ySrc
, DWORD xDest
, DWORD yDest
,
4169 DWORD width
, DWORD height
)
4173 int nColorMap
= 0, *colorMap
= NULL
, aColorMap
= FALSE
;
4175 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", physDevSrc
->hdc
, physDevDst
->hdc
,
4176 xSrc
, ySrc
, xDest
, yDest
, width
, height
);
4177 /* this function is meant as an optimization for BitBlt,
4178 * not to be called otherwise */
4179 if (GetObjectType( physDevSrc
->hdc
) != OBJ_MEMDC
) {
4180 ERR("called for non-memory source DC!?\n");
4184 hBitmap
= GetCurrentObject( physDevSrc
->hdc
, OBJ_BITMAP
);
4185 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBitmap
, BITMAP_MAGIC
);
4186 if (!(bmp
&& bmp
->dib
)) {
4187 ERR("called for non-DIBSection!?\n");
4188 GDI_ReleaseObj( hBitmap
);
4191 /* while BitBlt should already have made sure we only get
4192 * positive values, we should check for oversize values */
4193 if ((xSrc
< bmp
->bitmap
.bmWidth
) &&
4194 (ySrc
< bmp
->bitmap
.bmHeight
)) {
4195 if (xSrc
+ width
> bmp
->bitmap
.bmWidth
)
4196 width
= bmp
->bitmap
.bmWidth
- xSrc
;
4197 if (ySrc
+ height
> bmp
->bitmap
.bmHeight
)
4198 height
= bmp
->bitmap
.bmHeight
- ySrc
;
4199 /* if the source bitmap is 8bpp or less, we're supposed to use the
4200 * DC's palette for color conversion (not the DIB color table) */
4201 if (bmp
->dib
->dsBm
.bmBitsPixel
<= 8) {
4202 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4203 HPALETTE hPalette
= GetCurrentObject( physDevSrc
->hdc
, OBJ_PAL
);
4204 if (!hPalette
|| (hPalette
== GetStockObject(DEFAULT_PALETTE
))) {
4205 /* HACK: no palette has been set in the source DC,
4206 * use the DIB colormap instead - this is necessary in some
4207 * cases since we need to do depth conversion in some places
4208 * where real Windows can just copy data straight over */
4209 colorMap
= dib
->colorMap
;
4210 nColorMap
= dib
->nColorMap
;
4212 colorMap
= X11DRV_DIB_BuildColorMap( physDevSrc
, (WORD
)-1,
4213 bmp
->dib
->dsBm
.bmBitsPixel
,
4214 (BITMAPINFO
*)&(bmp
->dib
->dsBmih
),
4216 if (colorMap
) aColorMap
= TRUE
;
4219 /* perform the copy */
4220 X11DRV_DIB_DoCopyDIBSection(bmp
, FALSE
, colorMap
, nColorMap
,
4221 physDevDst
->drawable
, xSrc
, ySrc
,
4222 physDevDst
->org
.x
+ xDest
, physDevDst
->org
.y
+ yDest
,
4224 /* free color mapping */
4226 HeapFree(GetProcessHeap(), 0, colorMap
);
4228 GDI_ReleaseObj( hBitmap
);
4231 /***********************************************************************
4232 * X11DRV_DIB_DoUpdateDIBSection
4234 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
4236 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4237 X11DRV_DIB_DoCopyDIBSection(bmp
, toDIB
, dib
->colorMap
, dib
->nColorMap
,
4238 (Drawable
)bmp
->physBitmap
, 0, 0, 0, 0,
4239 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
4242 /***********************************************************************
4243 * X11DRV_DIB_FaultHandler
4245 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
4250 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
4251 if (!bmp
) return FALSE
;
4253 state
= X11DRV_DIB_Lock(bmp
, DIB_Status_None
, FALSE
);
4254 if (state
!= DIB_Status_InSync
) {
4255 /* no way to tell whether app needs read or write yet,
4257 X11DRV_DIB_Coerce(bmp
, DIB_Status_InSync
, FALSE
);
4259 /* hm, apparently the app must have write access */
4260 X11DRV_DIB_Coerce(bmp
, DIB_Status_AppMod
, FALSE
);
4262 X11DRV_DIB_Unlock(bmp
, TRUE
);
4264 GDI_ReleaseObj( (HBITMAP
)res
);
4268 /***********************************************************************
4271 INT
X11DRV_DIB_Coerce(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
4273 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4274 INT ret
= DIB_Status_None
;
4277 EnterCriticalSection(&(dib
->lock
));
4280 case DIB_Status_GdiMod
:
4281 /* GDI access - request to draw on pixmap */
4282 switch (dib
->status
)
4285 case DIB_Status_None
:
4286 dib
->p_status
= DIB_Status_GdiMod
;
4287 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
4290 case DIB_Status_GdiMod
:
4291 TRACE("GdiMod requested in status GdiMod\n" );
4292 dib
->p_status
= DIB_Status_GdiMod
;
4295 case DIB_Status_InSync
:
4296 TRACE("GdiMod requested in status InSync\n" );
4297 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
4298 dib
->status
= DIB_Status_GdiMod
;
4299 dib
->p_status
= DIB_Status_InSync
;
4302 case DIB_Status_AuxMod
:
4303 TRACE("GdiMod requested in status AuxMod\n" );
4304 if (lossy
) dib
->status
= DIB_Status_GdiMod
;
4305 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_GdiMod
);
4306 dib
->p_status
= DIB_Status_AuxMod
;
4307 if (dib
->status
!= DIB_Status_AppMod
) {
4308 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
4311 /* fall through if copy_aux() had to change to AppMod state */
4313 case DIB_Status_AppMod
:
4314 TRACE("GdiMod requested in status AppMod\n" );
4316 /* make it readonly to avoid app changing data while we copy */
4317 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4318 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
4320 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
4321 dib
->p_status
= DIB_Status_AppMod
;
4322 dib
->status
= DIB_Status_GdiMod
;
4327 case DIB_Status_InSync
:
4328 /* App access - request access to read DIB surface */
4329 /* (typically called from signal handler) */
4330 switch (dib
->status
)
4333 case DIB_Status_None
:
4334 /* shouldn't happen from signal handler */
4337 case DIB_Status_AuxMod
:
4338 TRACE("InSync requested in status AuxMod\n" );
4339 if (lossy
) dib
->status
= DIB_Status_InSync
;
4341 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4342 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_InSync
);
4344 if (dib
->status
!= DIB_Status_GdiMod
) {
4345 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4348 /* fall through if copy_aux() had to change to GdiMod state */
4350 case DIB_Status_GdiMod
:
4351 TRACE("InSync requested in status GdiMod\n" );
4353 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4354 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
4356 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4357 dib
->status
= DIB_Status_InSync
;
4360 case DIB_Status_InSync
:
4361 TRACE("InSync requested in status InSync\n" );
4362 /* shouldn't happen from signal handler */
4365 case DIB_Status_AppMod
:
4366 TRACE("InSync requested in status AppMod\n" );
4367 /* no reason to do anything here, and this
4368 * shouldn't happen from signal handler */
4373 case DIB_Status_AppMod
:
4374 /* App access - request access to write DIB surface */
4375 /* (typically called from signal handler) */
4376 switch (dib
->status
)
4379 case DIB_Status_None
:
4380 /* shouldn't happen from signal handler */
4383 case DIB_Status_AuxMod
:
4384 TRACE("AppMod requested in status AuxMod\n" );
4385 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4386 if (lossy
) dib
->status
= DIB_Status_AppMod
;
4387 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
4388 if (dib
->status
!= DIB_Status_GdiMod
)
4390 /* fall through if copy_aux() had to change to GdiMod state */
4392 case DIB_Status_GdiMod
:
4393 TRACE("AppMod requested in status GdiMod\n" );
4394 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4395 if (!lossy
) X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
4396 dib
->status
= DIB_Status_AppMod
;
4399 case DIB_Status_InSync
:
4400 TRACE("AppMod requested in status InSync\n" );
4401 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4402 dib
->status
= DIB_Status_AppMod
;
4405 case DIB_Status_AppMod
:
4406 TRACE("AppMod requested in status AppMod\n" );
4407 /* shouldn't happen from signal handler */
4412 case DIB_Status_AuxMod
:
4413 if (dib
->status
== DIB_Status_None
) {
4414 dib
->p_status
= req
;
4416 if (dib
->status
!= DIB_Status_AuxMod
)
4417 dib
->p_status
= dib
->status
;
4418 dib
->status
= DIB_Status_AuxMod
;
4421 /* it is up to the caller to do the copy/conversion, probably
4422 * using the return value to decide where to copy from */
4424 LeaveCriticalSection(&(dib
->lock
));
4429 /***********************************************************************
4432 INT
X11DRV_DIB_Lock(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
4434 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4435 INT ret
= DIB_Status_None
;
4438 TRACE("Locking %p from thread %04lx\n", bmp
, GetCurrentThreadId());
4439 EnterCriticalSection(&(dib
->lock
));
4441 if (req
!= DIB_Status_None
)
4442 X11DRV_DIB_Coerce(bmp
, req
, lossy
);
4447 /***********************************************************************
4450 void X11DRV_DIB_Unlock(BITMAPOBJ
*bmp
, BOOL commit
)
4452 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4455 switch (dib
->status
)
4458 case DIB_Status_None
:
4459 /* in case anyone is wondering, this is the "signal handler doesn't
4460 * work" case, where we always have to be ready for app access */
4462 switch (dib
->p_status
)
4464 case DIB_Status_AuxMod
:
4465 TRACE("Unlocking and syncing from AuxMod\n" );
4466 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
4467 if (dib
->status
!= DIB_Status_None
) {
4468 dib
->p_status
= dib
->status
;
4469 dib
->status
= DIB_Status_None
;
4471 if (dib
->p_status
!= DIB_Status_GdiMod
)
4473 /* fall through if copy_aux() had to change to GdiMod state */
4475 case DIB_Status_GdiMod
:
4476 TRACE("Unlocking and syncing from GdiMod\n" );
4477 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
4481 TRACE("Unlocking without needing to sync\n" );
4485 else TRACE("Unlocking with no changes\n");
4486 dib
->p_status
= DIB_Status_None
;
4489 case DIB_Status_GdiMod
:
4490 TRACE("Unlocking in status GdiMod\n" );
4491 /* DIB was protected in Coerce */
4493 /* no commit, revert to InSync if applicable */
4494 if ((dib
->p_status
== DIB_Status_InSync
) ||
4495 (dib
->p_status
== DIB_Status_AppMod
)) {
4496 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4497 dib
->status
= DIB_Status_InSync
;
4502 case DIB_Status_InSync
:
4503 TRACE("Unlocking in status InSync\n" );
4504 /* DIB was already protected in Coerce */
4507 case DIB_Status_AppMod
:
4508 TRACE("Unlocking in status AppMod\n" );
4509 /* DIB was already protected in Coerce */
4510 /* this case is ordinary only called from the signal handler,
4511 * so we don't bother to check for !commit */
4514 case DIB_Status_AuxMod
:
4515 TRACE("Unlocking in status AuxMod\n" );
4517 /* DIB may need protection now */
4518 if ((dib
->p_status
== DIB_Status_InSync
) ||
4519 (dib
->p_status
== DIB_Status_AppMod
))
4520 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
4522 /* no commit, revert to previous state */
4523 if (dib
->p_status
!= DIB_Status_None
)
4524 dib
->status
= dib
->p_status
;
4525 /* no protections changed */
4527 dib
->p_status
= DIB_Status_None
;
4530 LeaveCriticalSection(&(dib
->lock
));
4531 TRACE("Unlocked %p\n", bmp
);
4535 /***********************************************************************
4536 * X11DRV_CoerceDIBSection2
4538 INT
X11DRV_CoerceDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
4543 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4544 if (!bmp
) return DIB_Status_None
;
4545 ret
= X11DRV_DIB_Coerce(bmp
, req
, lossy
);
4546 GDI_ReleaseObj( hBmp
);
4550 /***********************************************************************
4551 * X11DRV_LockDIBSection2
4553 INT
X11DRV_LockDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
4558 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4559 if (!bmp
) return DIB_Status_None
;
4560 ret
= X11DRV_DIB_Lock(bmp
, req
, lossy
);
4561 GDI_ReleaseObj( hBmp
);
4565 /***********************************************************************
4566 * X11DRV_UnlockDIBSection2
4568 void X11DRV_UnlockDIBSection2(HBITMAP hBmp
, BOOL commit
)
4572 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4574 X11DRV_DIB_Unlock(bmp
, commit
);
4575 GDI_ReleaseObj( hBmp
);
4578 /***********************************************************************
4579 * X11DRV_CoerceDIBSection
4581 INT
X11DRV_CoerceDIBSection(X11DRV_PDEVICE
*physDev
, INT req
, BOOL lossy
)
4583 if (!physDev
) return DIB_Status_None
;
4584 return X11DRV_CoerceDIBSection2( GetCurrentObject( physDev
->hdc
, OBJ_BITMAP
), req
, lossy
);
4587 /***********************************************************************
4588 * X11DRV_LockDIBSection
4590 INT
X11DRV_LockDIBSection(X11DRV_PDEVICE
*physDev
, INT req
, BOOL lossy
)
4592 if (!physDev
) return DIB_Status_None
;
4593 if (GetObjectType( physDev
->hdc
) != OBJ_MEMDC
) return DIB_Status_None
;
4595 return X11DRV_LockDIBSection2( GetCurrentObject( physDev
->hdc
, OBJ_BITMAP
), req
, lossy
);
4598 /***********************************************************************
4599 * X11DRV_UnlockDIBSection
4601 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE
*physDev
, BOOL commit
)
4603 if (!physDev
) return;
4604 if (GetObjectType( physDev
->hdc
) != OBJ_MEMDC
) return;
4606 X11DRV_UnlockDIBSection2( GetCurrentObject( physDev
->hdc
, OBJ_BITMAP
), commit
);
4610 #ifdef HAVE_LIBXXSHM
4611 /***********************************************************************
4612 * X11DRV_XShmErrorHandler
4615 static int XShmErrorHandler( Display
*dpy
, XErrorEvent
*event
, void *arg
)
4617 return 1; /* FIXME: should check event contents */
4620 /***********************************************************************
4621 * X11DRV_XShmCreateImage
4624 static XImage
*X11DRV_XShmCreateImage( int width
, int height
, int bpp
,
4625 XShmSegmentInfo
* shminfo
)
4629 image
= XShmCreateImage(gdi_display
, visual
, bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
4632 shminfo
->shmid
= shmget(IPC_PRIVATE
, image
->bytes_per_line
* height
,
4634 if( shminfo
->shmid
!= -1 )
4636 shminfo
->shmaddr
= image
->data
= shmat(shminfo
->shmid
, 0, 0);
4637 if( shminfo
->shmaddr
!= (char*)-1 )
4641 shminfo
->readOnly
= FALSE
;
4642 X11DRV_expect_error( gdi_display
, XShmErrorHandler
, NULL
);
4643 ok
= (XShmAttach( gdi_display
, shminfo
) != 0);
4644 XSync( gdi_display
, False
);
4645 if (X11DRV_check_error()) ok
= FALSE
;
4648 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
4649 return image
; /* Success! */
4651 /* An error occurred */
4652 shmdt(shminfo
->shmaddr
);
4654 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
4656 XFlush(gdi_display
);
4657 XDestroyImage(image
);
4662 #endif /* HAVE_LIBXXSHM */
4665 /***********************************************************************
4666 * X11DRV_DIB_CreateDIBSection
4668 HBITMAP
X11DRV_DIB_CreateDIBSection(
4669 X11DRV_PDEVICE
*physDev
, const BITMAPINFO
*bmi
, UINT usage
,
4670 VOID
**bits
, HANDLE section
,
4671 DWORD offset
, DWORD ovr_pitch
)
4674 BITMAPOBJ
*bmp
= NULL
;
4675 X11DRV_DIBSECTION
*dib
= NULL
;
4676 int *colorMap
= NULL
;
4678 RGBQUAD
*colorTable
= NULL
;
4680 /* Fill BITMAP structure with DIB data */
4681 INT effHeight
, totalSize
;
4683 LPVOID mapBits
= NULL
;
4688 WORD planes
, bpp
, compression
;
4692 if (((bitmap_type
= DIB_GetBitmapInfoEx((BITMAPINFOHEADER
*) bmi
,
4693 &width
, &height
, &planes
, &bpp
, &compression
, &sizeImage
)) == -1))
4695 ERR("Invalid bitmap\n");
4698 core_header
= (bitmap_type
== 0);
4700 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, %s\n",
4701 width
, height
, planes
, bpp
,
4702 sizeImage
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
4704 effHeight
= height
>= 0 ? height
: -height
;
4707 bm
.bmHeight
= effHeight
;
4708 bm
.bmWidthBytes
= ovr_pitch
? ovr_pitch
: X11DRV_DIB_GetDIBWidthBytes(bm
.bmWidth
, bpp
);
4709 bm
.bmPlanes
= planes
;
4710 bm
.bmBitsPixel
= bpp
;
4713 /* Get storage location for DIB bits. Only use sizeImage if it's valid and
4714 we're dealing with a compressed bitmap. Otherwise, use width * height. */
4715 if (sizeImage
&& (compression
== BI_RLE4
|| compression
== BI_RLE8
))
4716 totalSize
= sizeImage
;
4718 totalSize
= bm
.bmWidthBytes
* effHeight
;
4722 SYSTEM_INFO SystemInfo
;
4726 GetSystemInfo( &SystemInfo
);
4727 mapOffset
= offset
- (offset
% SystemInfo
.dwAllocationGranularity
);
4728 mapSize
= totalSize
+ (offset
- mapOffset
);
4729 mapBits
= MapViewOfFile( section
,
4730 FILE_MAP_ALL_ACCESS
,
4734 bm
.bmBits
= (char *)mapBits
+ (offset
- mapOffset
);
4736 else if (ovr_pitch
&& offset
)
4737 bm
.bmBits
= (LPVOID
) offset
;
4740 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
4741 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
4744 /* Create Color Map */
4745 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8) {
4746 colorMap
= X11DRV_DIB_BuildColorMap( usage
== DIB_PAL_COLORS
? physDev
: NULL
,
4747 usage
, bm
.bmBitsPixel
, bmi
, &nColorMap
);
4748 colorTable
= X11DRV_DIB_BuildColorTable( physDev
, usage
, bm
.bmBitsPixel
, bmi
);
4750 /* Allocate Memory for DIB and fill structure */
4752 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
4755 dib
->dibSection
.dsBm
= bm
;
4759 /* Convert the BITMAPCOREHEADER to a BITMAPINFOHEADER.
4760 The structure is already filled with zeros */
4761 dib
->dibSection
.dsBmih
.biSize
= sizeof(BITMAPINFOHEADER
);
4762 dib
->dibSection
.dsBmih
.biWidth
= width
;
4763 dib
->dibSection
.dsBmih
.biHeight
= height
;
4764 dib
->dibSection
.dsBmih
.biPlanes
= planes
;
4765 dib
->dibSection
.dsBmih
.biBitCount
= bpp
;
4766 dib
->dibSection
.dsBmih
.biCompression
= compression
;
4770 /* Truncate extended bitmap headers (BITMAPV4HEADER etc.) */
4771 dib
->dibSection
.dsBmih
= *((BITMAPINFOHEADER
*) bmi
);
4772 dib
->dibSection
.dsBmih
.biSize
= sizeof(BITMAPINFOHEADER
);
4775 dib
->dibSection
.dsBmih
.biSizeImage
= totalSize
;
4776 colorPtr
= (LPBYTE
) bmi
+ (WORD
) bmi
->bmiHeader
.biSize
;
4778 /* Set dsBitfields values */
4779 if ( usage
== DIB_PAL_COLORS
|| bpp
<= 8)
4781 dib
->dibSection
.dsBitfields
[0] = dib
->dibSection
.dsBitfields
[1] = dib
->dibSection
.dsBitfields
[2] = 0;
4787 dib
->dibSection
.dsBitfields
[0] = (compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
) : 0x7c00;
4788 dib
->dibSection
.dsBitfields
[1] = (compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
+ 1) : 0x03e0;
4789 dib
->dibSection
.dsBitfields
[2] = (compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
+ 2) : 0x001f;
4794 dib
->dibSection
.dsBitfields
[0] = (compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
) : 0xff0000;
4795 dib
->dibSection
.dsBitfields
[1] = (compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
+ 1) : 0x00ff00;
4796 dib
->dibSection
.dsBitfields
[2] = (compression
== BI_BITFIELDS
) ? *((const DWORD
*)colorPtr
+ 2) : 0x0000ff;
4799 dib
->dibSection
.dshSection
= section
;
4800 dib
->dibSection
.dsOffset
= offset
;
4802 dib
->status
= DIB_Status_None
;
4803 dib
->nColorMap
= nColorMap
;
4804 dib
->colorMap
= colorMap
;
4805 dib
->colorTable
= colorTable
;
4808 /* Create Device Dependent Bitmap and add DIB pointer */
4811 int depth
= (bpp
== 1) ? 1 : GetDeviceCaps(physDev
->hdc
, BITSPIXEL
);
4812 res
= CreateBitmap(width
, effHeight
, 1, depth
, NULL
);
4816 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
4817 if (bmp
) bmp
->dib
= (DIBSECTION
*) dib
;
4825 #ifdef HAVE_LIBXXSHM
4826 if (XShmQueryExtension(gdi_display
) &&
4827 (dib
->image
= X11DRV_XShmCreateImage( bm
.bmWidth
, effHeight
,
4828 bmp
->bitmap
.bmBitsPixel
, &dib
->shminfo
)) )
4830 ; /* Created Image */
4832 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
4833 dib
->shminfo
.shmid
= -1;
4836 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
4838 wine_tsx11_unlock();
4841 /* Clean up in case of errors */
4842 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
4844 TRACE("got an error res=%p, bmp=%p, dib=%p, bm.bmBits=%p\n",
4845 res
, bmp
, dib
, bm
.bmBits
);
4849 UnmapViewOfFile(mapBits
), bm
.bmBits
= NULL
;
4851 VirtualFree(bm
.bmBits
, 0L, MEM_RELEASE
), bm
.bmBits
= NULL
;
4854 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
4855 HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
;
4856 HeapFree(GetProcessHeap(), 0, colorTable
); colorTable
= NULL
;
4857 HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
;
4858 if (bmp
) { GDI_ReleaseObj(res
); bmp
= NULL
; }
4859 if (res
) { DeleteObject(res
); res
= 0; }
4863 extern BOOL
VIRTUAL_SetFaultHandler(LPCVOID addr
, BOOL (*proc
)(LPVOID
, LPCVOID
), LPVOID arg
);
4864 /* Install fault handler, if possible */
4865 InitializeCriticalSection(&(dib
->lock
));
4866 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
4868 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4869 if (dib
) dib
->status
= DIB_Status_AppMod
;
4873 /* Return BITMAP handle and storage location */
4874 if (bmp
) GDI_ReleaseObj(res
);
4875 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
4879 /***********************************************************************
4880 * X11DRV_DIB_DeleteDIBSection
4882 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
4884 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4886 if (dib
->dibSection
.dshSection
)
4887 X11DRV_DIB_Coerce(bmp
, DIB_Status_InSync
, FALSE
);
4892 #ifdef HAVE_LIBXXSHM
4893 if (dib
->shminfo
.shmid
!= -1)
4895 XShmDetach (gdi_display
, &(dib
->shminfo
));
4896 XDestroyImage (dib
->image
);
4897 shmdt (dib
->shminfo
.shmaddr
);
4898 dib
->shminfo
.shmid
= -1;
4902 XDestroyImage( dib
->image
);
4903 wine_tsx11_unlock();
4906 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
4907 HeapFree(GetProcessHeap(), 0, dib
->colorTable
);
4909 DeleteCriticalSection(&(dib
->lock
));
4912 /***********************************************************************
4913 * SetDIBColorTable (X11DRV.@)
4915 UINT
X11DRV_SetDIBColorTable( X11DRV_PDEVICE
*physDev
, UINT start
, UINT count
, const RGBQUAD
*colors
)
4918 X11DRV_DIBSECTION
*dib
;
4920 HBITMAP hBitmap
= GetCurrentObject( physDev
->hdc
, OBJ_BITMAP
);
4922 if (!(bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBitmap
, BITMAP_MAGIC
))) return 0;
4923 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4925 if (dib
&& dib
->colorMap
&& start
< dib
->nColorMap
) {
4926 UINT end
= count
+ start
;
4927 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
4929 * Changing color table might change the mapping between
4930 * DIB colors and X11 colors and thus alter the visible state
4931 * of the bitmap object.
4933 X11DRV_DIB_Lock(bmp
, DIB_Status_AppMod
, FALSE
);
4934 memcpy(dib
->colorTable
+ start
, colors
, (end
- start
) * sizeof(RGBQUAD
));
4935 X11DRV_DIB_GenColorMap( physDev
, dib
->colorMap
, DIB_RGB_COLORS
,
4936 dib
->dibSection
.dsBm
.bmBitsPixel
,
4937 TRUE
, colors
, start
, end
);
4938 X11DRV_DIB_Unlock(bmp
, TRUE
);
4941 GDI_ReleaseObj( hBitmap
);
4945 /***********************************************************************
4946 * GetDIBColorTable (X11DRV.@)
4948 UINT
X11DRV_GetDIBColorTable( X11DRV_PDEVICE
*physDev
, UINT start
, UINT count
, RGBQUAD
*colors
)
4951 X11DRV_DIBSECTION
*dib
;
4953 HBITMAP hBitmap
= GetCurrentObject( physDev
->hdc
, OBJ_BITMAP
);
4955 if (!(bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBitmap
, BITMAP_MAGIC
))) return 0;
4956 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4958 if (dib
&& dib
->colorTable
&& start
< dib
->nColorMap
) {
4959 if (start
+ count
> dib
->nColorMap
) count
= dib
->nColorMap
- start
;
4960 memcpy(colors
, dib
->colorTable
+ start
, count
* sizeof(RGBQUAD
));
4963 GDI_ReleaseObj( hBitmap
);
4969 /***********************************************************************
4970 * X11DRV_DIB_CreateDIBFromBitmap
4972 * Allocates a packed DIB and copies the bitmap data into it.
4974 HGLOBAL
X11DRV_DIB_CreateDIBFromBitmap(HDC hdc
, HBITMAP hBmp
)
4979 LPBITMAPINFOHEADER pbmiHeader
;
4980 unsigned int cDataSize
, cPackedSize
, OffsetBits
;
4983 if (!GetObjectW( hBmp
, sizeof(bmp
), &bmp
)) return 0;
4986 * A packed DIB contains a BITMAPINFO structure followed immediately by
4987 * an optional color palette and the pixel data.
4990 /* Calculate the size of the packed DIB */
4991 cDataSize
= X11DRV_DIB_GetDIBWidthBytes( bmp
.bmWidth
, bmp
.bmBitsPixel
) * abs( bmp
.bmHeight
);
4992 cPackedSize
= sizeof(BITMAPINFOHEADER
)
4993 + ( (bmp
.bmBitsPixel
<= 8) ? (sizeof(RGBQUAD
) * (1 << bmp
.bmBitsPixel
)) : 0 )
4995 /* Get the offset to the bits */
4996 OffsetBits
= cPackedSize
- cDataSize
;
4998 /* Allocate the packed DIB */
4999 TRACE("\tAllocating packed DIB of size %d\n", cPackedSize
);
5000 hPackedDIB
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_DDESHARE
/*| GMEM_ZEROINIT*/,
5004 WARN("Could not allocate packed DIB!\n");
5008 /* A packed DIB starts with a BITMAPINFOHEADER */
5009 pPackedDIB
= GlobalLock(hPackedDIB
);
5010 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
5012 /* Init the BITMAPINFOHEADER */
5013 pbmiHeader
->biSize
= sizeof(BITMAPINFOHEADER
);
5014 pbmiHeader
->biWidth
= bmp
.bmWidth
;
5015 pbmiHeader
->biHeight
= bmp
.bmHeight
;
5016 pbmiHeader
->biPlanes
= 1;
5017 pbmiHeader
->biBitCount
= bmp
.bmBitsPixel
;
5018 pbmiHeader
->biCompression
= BI_RGB
;
5019 pbmiHeader
->biSizeImage
= 0;
5020 pbmiHeader
->biXPelsPerMeter
= pbmiHeader
->biYPelsPerMeter
= 0;
5021 pbmiHeader
->biClrUsed
= 0;
5022 pbmiHeader
->biClrImportant
= 0;
5024 /* Retrieve the DIB bits from the bitmap and fill in the
5025 * DIB color table if present */
5027 nLinesCopied
= GetDIBits(hdc
, /* Handle to device context */
5028 hBmp
, /* Handle to bitmap */
5029 0, /* First scan line to set in dest bitmap */
5030 bmp
.bmHeight
, /* Number of scan lines to copy */
5031 pPackedDIB
+ OffsetBits
, /* [out] Address of array for bitmap bits */
5032 (LPBITMAPINFO
) pbmiHeader
, /* [out] Address of BITMAPINFO structure */
5033 0); /* RGB or palette index */
5034 GlobalUnlock(hPackedDIB
);
5036 /* Cleanup if GetDIBits failed */
5037 if (nLinesCopied
!= bmp
.bmHeight
)
5039 TRACE("\tGetDIBits returned %d. Actual lines=%d\n", nLinesCopied
, bmp
.bmHeight
);
5040 GlobalFree(hPackedDIB
);
5047 /**************************************************************************
5048 * X11DRV_DIB_CreateDIBFromPixmap
5050 * Allocates a packed DIB and copies the Pixmap data into it.
5051 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
5053 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
, BOOL bDeletePixmap
)
5056 BITMAPOBJ
*pBmp
= NULL
;
5057 HGLOBAL hPackedDIB
= 0;
5059 /* Allocates an HBITMAP which references the Pixmap passed to us */
5060 hBmp
= X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(hdc
, pixmap
);
5063 TRACE("\tCould not create bitmap header for Pixmap\n");
5068 * Create a packed DIB from the Pixmap wrapper bitmap created above.
5069 * A packed DIB contains a BITMAPINFO structure followed immediately by
5070 * an optional color palette and the pixel data.
5072 hPackedDIB
= X11DRV_DIB_CreateDIBFromBitmap(hdc
, hBmp
);
5074 /* Get a pointer to the BITMAPOBJ structure */
5075 pBmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5077 /* We can now get rid of the HBITMAP wrapper we created earlier.
5078 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
5082 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
5083 X11DRV_set_pixmap( hBmp
, 0 );
5086 GDI_ReleaseObj( hBmp
);
5090 TRACE("\tReturning packed DIB %p\n", hPackedDIB
);
5095 /**************************************************************************
5096 * X11DRV_DIB_CreatePixmapFromDIB
5098 * Creates a Pixmap from a packed DIB
5100 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
5102 Pixmap pixmap
= None
;
5104 BITMAPOBJ
*pBmp
= NULL
;
5105 LPBYTE pPackedDIB
= NULL
;
5106 LPBITMAPINFO pbmi
= NULL
;
5107 LPBITMAPINFOHEADER pbmiHeader
= NULL
;
5108 LPBYTE pbits
= NULL
;
5110 /* Get a pointer to the packed DIB's data */
5111 pPackedDIB
= (LPBYTE
)GlobalLock(hPackedDIB
);
5112 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
5113 pbmi
= (LPBITMAPINFO
)pPackedDIB
;
5114 pbits
= (LPBYTE
)(pPackedDIB
5115 + X11DRV_DIB_BitmapInfoSize( (LPBITMAPINFO
)pbmiHeader
, DIB_RGB_COLORS
));
5117 /* Create a DDB from the DIB */
5119 hBmp
= CreateDIBitmap(hdc
,
5126 GlobalUnlock(hPackedDIB
);
5128 TRACE("CreateDIBitmap returned %p\n", hBmp
);
5130 /* Retrieve the internal Pixmap from the DDB */
5132 pBmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5134 /* clear the physBitmap so that we can steal its pixmap */
5135 pixmap
= X11DRV_set_pixmap( hBmp
, 0 );
5138 /* Delete the DDB we created earlier now that we have stolen its pixmap */
5139 GDI_ReleaseObj( hBmp
);
5142 TRACE("\tReturning Pixmap %ld\n", pixmap
);