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 */
86 /***********************************************************************
87 * X11DRV_DIB_GetXImageWidthBytes
89 * Return the width of an X image in bytes
91 inline static int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
93 if (!depth
|| depth
> 32) goto error
;
95 if (!ximageDepthTable
[depth
-1])
97 XImage
*testimage
= XCreateImage( gdi_display
, visual
, depth
,
98 ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
101 ximageDepthTable
[depth
-1] = testimage
->bits_per_pixel
;
102 XDestroyImage( testimage
);
104 else ximageDepthTable
[depth
-1] = -1;
106 if (ximageDepthTable
[depth
-1] != -1)
107 return (4 * ((width
* ximageDepthTable
[depth
-1] + 31) / 32));
110 WARN( "(%d): Unsupported depth\n", depth
);
115 /***********************************************************************
116 * X11DRV_DIB_GetDIBWidthBytes
118 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
120 static int X11DRV_DIB_GetDIBWidthBytes( int width
, int depth
)
126 case 1: words
= (width
+ 31) / 32; break;
127 case 4: words
= (width
+ 7) / 8; break;
128 case 8: words
= (width
+ 3) / 4; break;
130 case 16: words
= (width
+ 1) / 2; break;
131 case 24: words
= (width
* 3 + 3) / 4; break;
133 WARN("(%d): Unsupported depth\n", depth
);
142 /***********************************************************************
143 * X11DRV_DIB_BitmapInfoSize
145 * Return the size of the bitmap info structure including color table.
147 int X11DRV_DIB_BitmapInfoSize( const BITMAPINFO
* info
, WORD coloruse
)
151 if (info
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
153 BITMAPCOREHEADER
*core
= (BITMAPCOREHEADER
*)info
;
154 colors
= (core
->bcBitCount
<= 8) ? 1 << core
->bcBitCount
: 0;
155 return sizeof(BITMAPCOREHEADER
) + colors
*
156 ((coloruse
== DIB_RGB_COLORS
) ? sizeof(RGBTRIPLE
) : sizeof(WORD
));
158 else /* assume BITMAPINFOHEADER */
160 colors
= info
->bmiHeader
.biClrUsed
;
161 if (!colors
&& (info
->bmiHeader
.biBitCount
<= 8))
162 colors
= 1 << info
->bmiHeader
.biBitCount
;
163 return sizeof(BITMAPINFOHEADER
) + colors
*
164 ((coloruse
== DIB_RGB_COLORS
) ? sizeof(RGBQUAD
) : sizeof(WORD
));
169 /***********************************************************************
170 * X11DRV_DIB_CreateXImage
174 XImage
*X11DRV_DIB_CreateXImage( int width
, int height
, int depth
)
180 width_bytes
= X11DRV_DIB_GetXImageWidthBytes( width
, depth
);
181 image
= XCreateImage( gdi_display
, visual
, depth
, ZPixmap
, 0,
182 calloc( height
, width_bytes
),
183 width
, height
, 32, width_bytes
);
189 /***********************************************************************
192 * Get the info from a bitmap header.
193 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
195 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER
*header
, DWORD
*width
,
196 int *height
, WORD
*bpp
, WORD
*compr
)
198 if (header
->biSize
== sizeof(BITMAPCOREHEADER
))
200 BITMAPCOREHEADER
*core
= (BITMAPCOREHEADER
*)header
;
201 *width
= core
->bcWidth
;
202 *height
= core
->bcHeight
;
203 *bpp
= core
->bcBitCount
;
207 if (header
->biSize
>= sizeof(BITMAPINFOHEADER
))
209 *width
= header
->biWidth
;
210 *height
= header
->biHeight
;
211 *bpp
= header
->biBitCount
;
212 *compr
= header
->biCompression
;
215 ERR("(%ld): unknown/wrong size for header\n", header
->biSize
);
220 /***********************************************************************
221 * X11DRV_DIB_GenColorMap
223 * Fills the color map of a bitmap palette. Should not be called
224 * for a >8-bit deep bitmap.
226 int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE
*physDev
, int *colorMapping
,
227 WORD coloruse
, WORD depth
, BOOL quads
,
228 const void *colorPtr
, int start
, int end
)
232 if (coloruse
== DIB_RGB_COLORS
)
234 int max
= 1 << depth
;
236 if (end
> max
) end
= max
;
240 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
242 if (depth
== 1) /* Monochrome */
243 for (i
= start
; i
< end
; i
++, rgb
++)
244 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
245 rgb
->rgbBlue
> 255*3/2);
247 for (i
= start
; i
< end
; i
++, rgb
++)
248 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, RGB(rgb
->rgbRed
,
254 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
256 if (depth
== 1) /* Monochrome */
257 for (i
= start
; i
< end
; i
++, rgb
++)
258 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
259 rgb
->rgbtBlue
> 255*3/2);
261 for (i
= start
; i
< end
; i
++, rgb
++)
262 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, RGB(rgb
->rgbtRed
,
267 else /* DIB_PAL_COLORS */
270 WORD
* index
= (WORD
*)colorPtr
;
272 for (i
= start
; i
< end
; i
++, index
++)
273 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, PALETTEINDEX(*index
) );
275 for (i
= start
; i
< end
; i
++)
276 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, PALETTEINDEX(i
) );
283 /***********************************************************************
284 * X11DRV_DIB_BuildColorMap
286 * Build the color map from the bitmap palette. Should not be called
287 * for a >8-bit deep bitmap.
289 int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE
*physDev
, WORD coloruse
, WORD depth
,
290 const BITMAPINFO
*info
, int *nColors
)
294 const void *colorPtr
;
297 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
299 colors
= info
->bmiHeader
.biClrUsed
;
300 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
301 colorPtr
= info
->bmiColors
;
303 else /* assume BITMAPCOREINFO */
305 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
306 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
311 ERR("called with >256 colors!\n");
315 /* just so CopyDIBSection doesn't have to create an identity palette */
316 if (coloruse
== (WORD
)-1) colorPtr
= NULL
;
318 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
319 colors
* sizeof(int) )))
323 return X11DRV_DIB_GenColorMap( physDev
, colorMapping
, coloruse
, depth
,
324 isInfo
, colorPtr
, 0, colors
);
328 /***********************************************************************
329 * X11DRV_DIB_MapColor
331 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
, int oldcol
)
335 if ((oldcol
< nPhysMap
) && (physMap
[oldcol
] == phys
))
338 for (color
= 0; color
< nPhysMap
; color
++)
339 if (physMap
[color
] == phys
)
342 WARN("Strange color %08x\n", phys
);
347 /*********************************************************************
348 * X11DRV_DIB_GetNearestIndex
350 * Helper for X11DRV_DIB_GetDIBits.
351 * Returns the nearest colour table index for a given RGB.
352 * Nearest is defined by minimizing the sum of the squares.
354 static INT
X11DRV_DIB_GetNearestIndex(RGBQUAD
*colormap
, int numColors
, BYTE r
, BYTE g
, BYTE b
)
356 INT i
, best
= -1, diff
, bestdiff
= -1;
359 for(color
= colormap
, i
= 0; i
< numColors
; color
++, i
++) {
360 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
361 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
362 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
365 if(best
== -1 || diff
< bestdiff
) {
372 /*********************************************************************
373 * X11DRV_DIB_MaskToShift
375 * Helper for X11DRV_DIB_GetDIBits.
376 * Returns the by how many bits to shift a given color so that it is
377 * in the proper position.
379 INT
X11DRV_DIB_MaskToShift(DWORD mask
)
387 while ((mask
&1)==0) {
394 /***********************************************************************
395 * X11DRV_DIB_SetImageBits_1
397 * SetDIBits for a 1-bit deep DIB.
399 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
400 DWORD srcwidth
, DWORD dstwidth
, int left
,
401 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
410 srcbits
= srcbits
+ linebytes
* (lines
- 1);
411 linebytes
= -linebytes
;
414 if ((extra
= (left
& 7)) != 0) {
418 srcbits
+= left
>> 3;
419 width
= min(srcwidth
, dstwidth
);
421 /* ==== pal 1 dib -> any bmp format ==== */
422 for (h
= lines
-1; h
>=0; h
--) {
424 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
425 for (i
= width
/8, x
= left
; i
> 0; i
--) {
427 XPutPixel( bmpImage
, x
++, h
, colors
[ srcval
>> 7] );
428 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 6) & 1] );
429 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 5) & 1] );
430 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 4) & 1] );
431 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 3) & 1] );
432 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 2) & 1] );
433 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 1) & 1] );
434 XPutPixel( bmpImage
, x
++, h
, colors
[ srcval
& 1] );
440 case 7: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
441 case 6: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
442 case 5: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
443 case 4: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
444 case 3: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
445 case 2: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
446 case 1: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]);
449 srcbits
+= linebytes
;
453 /***********************************************************************
454 * X11DRV_DIB_GetImageBits_1
456 * GetDIBits for a 1-bit deep DIB.
458 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
459 DWORD dstwidth
, DWORD srcwidth
,
460 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
461 XImage
*bmpImage
, DWORD linebytes
)
464 int h
, width
= min(dstwidth
, srcwidth
);
468 dstbits
= dstbits
+ linebytes
* (lines
- 1);
469 linebytes
= -linebytes
;
472 switch (bmpImage
->depth
)
476 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
477 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
480 for (h
=lines
-1; h
>=0; h
--) {
484 for (x
=0; x
<width
; x
++) {
486 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
487 dstval
|=(X11DRV_DIB_GetNearestIndex
491 srcval
.peBlue
) << (7 - (x
& 7)));
500 dstbits
+= linebytes
;
508 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
509 /* ==== pal 8 bmp -> pal 1 dib ==== */
511 const BYTE
* srcpixel
;
514 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
516 for (h
=0; h
<lines
; h
++) {
521 for (x
=0; x
<width
; x
++) {
523 srcval
=srccolors
[(int)*srcpixel
++];
524 dstval
|=(X11DRV_DIB_GetNearestIndex
528 srcval
.peBlue
) << (7-(x
&7)) );
537 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
538 dstbits
+= linebytes
;
549 const WORD
* srcpixel
;
552 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
554 if (bmpImage
->green_mask
==0x03e0) {
555 if (bmpImage
->red_mask
==0x7c00) {
556 /* ==== rgb 555 bmp -> pal 1 dib ==== */
557 for (h
=0; h
<lines
; h
++) {
562 for (x
=0; x
<width
; x
++) {
565 dstval
|=(X11DRV_DIB_GetNearestIndex
567 ((srcval
>> 7) & 0xf8) | /* r */
568 ((srcval
>> 12) & 0x07),
569 ((srcval
>> 2) & 0xf8) | /* g */
570 ((srcval
>> 7) & 0x07),
571 ((srcval
<< 3) & 0xf8) | /* b */
572 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
581 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
582 dstbits
+= linebytes
;
584 } else if (bmpImage
->blue_mask
==0x7c00) {
585 /* ==== bgr 555 bmp -> pal 1 dib ==== */
586 for (h
=0; h
<lines
; h
++) {
591 for (x
=0; x
<width
; x
++) {
594 dstval
|=(X11DRV_DIB_GetNearestIndex
596 ((srcval
<< 3) & 0xf8) | /* r */
597 ((srcval
>> 2) & 0x07),
598 ((srcval
>> 2) & 0xf8) | /* g */
599 ((srcval
>> 7) & 0x07),
600 ((srcval
>> 7) & 0xf8) | /* b */
601 ((srcval
>> 12) & 0x07) ) << (7-(x
&7)) );
610 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
611 dstbits
+= linebytes
;
616 } else if (bmpImage
->green_mask
==0x07e0) {
617 if (bmpImage
->red_mask
==0xf800) {
618 /* ==== rgb 565 bmp -> pal 1 dib ==== */
619 for (h
=0; h
<lines
; h
++) {
624 for (x
=0; x
<width
; x
++) {
627 dstval
|=(X11DRV_DIB_GetNearestIndex
629 ((srcval
>> 8) & 0xf8) | /* r */
630 ((srcval
>> 13) & 0x07),
631 ((srcval
>> 3) & 0xfc) | /* g */
632 ((srcval
>> 9) & 0x03),
633 ((srcval
<< 3) & 0xf8) | /* b */
634 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
643 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
644 dstbits
+= linebytes
;
646 } else if (bmpImage
->blue_mask
==0xf800) {
647 /* ==== bgr 565 bmp -> pal 1 dib ==== */
648 for (h
=0; h
<lines
; h
++) {
653 for (x
=0; x
<width
; x
++) {
656 dstval
|=(X11DRV_DIB_GetNearestIndex
658 ((srcval
<< 3) & 0xf8) | /* r */
659 ((srcval
>> 2) & 0x07),
660 ((srcval
>> 3) & 0xfc) | /* g */
661 ((srcval
>> 9) & 0x03),
662 ((srcval
>> 8) & 0xf8) | /* b */
663 ((srcval
>> 13) & 0x07) ) << (7-(x
&7)) );
672 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
673 dstbits
+= linebytes
;
692 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
693 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
695 if (bmpImage
->green_mask
!=0x00ff00 ||
696 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
698 } else if (bmpImage
->blue_mask
==0xff) {
699 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
700 for (h
=0; h
<lines
; h
++) {
705 for (x
=0; x
<width
; x
++) {
706 dstval
|=(X11DRV_DIB_GetNearestIndex
710 srcbyte
[0]) << (7-(x
&7)) );
711 srcbyte
+=bytes_per_pixel
;
720 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
721 dstbits
+= linebytes
;
724 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
725 for (h
=0; h
<lines
; h
++) {
730 for (x
=0; x
<width
; x
++) {
731 dstval
|=(X11DRV_DIB_GetNearestIndex
735 srcbyte
[2]) << (7-(x
&7)) );
736 srcbyte
+=bytes_per_pixel
;
745 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
746 dstbits
+= linebytes
;
756 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
758 /* ==== any bmp format -> pal 1 dib ==== */
759 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
760 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
761 bmpImage
->green_mask
, bmpImage
->blue_mask
);
763 for (h
=lines
-1; h
>=0; h
--) {
767 for (x
=0; x
<width
; x
++) {
768 dstval
|=(XGetPixel( bmpImage
, x
, h
) >= white
) << (7 - (x
&7));
777 dstbits
+= linebytes
;
784 /***********************************************************************
785 * X11DRV_DIB_SetImageBits_4
787 * SetDIBits for a 4-bit deep DIB.
789 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
790 DWORD srcwidth
, DWORD dstwidth
, int left
,
791 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
799 srcbits
= srcbits
+ linebytes
* (lines
- 1);
800 linebytes
= -linebytes
;
807 srcbits
+= left
>> 1;
808 width
= min(srcwidth
, dstwidth
);
810 /* ==== pal 4 dib -> any bmp format ==== */
811 for (h
= lines
-1; h
>= 0; h
--) {
813 for (i
= width
/2, x
= left
; i
> 0; i
--) {
814 BYTE srcval
=*srcbyte
++;
815 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
>> 4] );
816 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
& 0x0f] );
819 XPutPixel( bmpImage
, x
, h
, colors
[*srcbyte
>> 4] );
820 srcbits
+= linebytes
;
826 /***********************************************************************
827 * X11DRV_DIB_GetImageBits_4
829 * GetDIBits for a 4-bit deep DIB.
831 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
832 DWORD srcwidth
, DWORD dstwidth
,
833 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
834 XImage
*bmpImage
, DWORD linebytes
)
837 int h
, width
= min(srcwidth
, dstwidth
);
843 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
844 linebytes
= -linebytes
;
849 switch (bmpImage
->depth
) {
852 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
853 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
856 for (h
= lines
-1; h
>= 0; h
--) {
860 for (x
= 0; x
< width
; x
++) {
862 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
863 dstval
|=(X11DRV_DIB_GetNearestIndex
867 srcval
.peBlue
) << (4-((x
&1)<<2)));
876 dstbits
+= linebytes
;
884 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
885 /* ==== pal 8 bmp -> pal 4 dib ==== */
887 const BYTE
*srcpixel
;
890 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
891 for (h
=0; h
<lines
; h
++) {
896 for (x
=0; x
<width
; x
++) {
898 srcval
= srccolors
[(int)*srcpixel
++];
899 dstval
|=(X11DRV_DIB_GetNearestIndex
903 srcval
.peBlue
) << (4*(1-(x
&1))) );
912 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
913 dstbits
+= linebytes
;
924 const WORD
* srcpixel
;
927 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
929 if (bmpImage
->green_mask
==0x03e0) {
930 if (bmpImage
->red_mask
==0x7c00) {
931 /* ==== rgb 555 bmp -> pal 4 dib ==== */
932 for (h
=0; h
<lines
; h
++) {
937 for (x
=0; x
<width
; x
++) {
940 dstval
|=(X11DRV_DIB_GetNearestIndex
942 ((srcval
>> 7) & 0xf8) | /* r */
943 ((srcval
>> 12) & 0x07),
944 ((srcval
>> 2) & 0xf8) | /* g */
945 ((srcval
>> 7) & 0x07),
946 ((srcval
<< 3) & 0xf8) | /* b */
947 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
956 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
957 dstbits
+= linebytes
;
959 } else if (bmpImage
->blue_mask
==0x7c00) {
960 /* ==== bgr 555 bmp -> pal 4 dib ==== */
961 for (h
=0; h
<lines
; h
++) {
966 for (x
=0; x
<width
; x
++) {
969 dstval
|=(X11DRV_DIB_GetNearestIndex
971 ((srcval
<< 3) & 0xf8) | /* r */
972 ((srcval
>> 2) & 0x07),
973 ((srcval
>> 2) & 0xf8) | /* g */
974 ((srcval
>> 7) & 0x07),
975 ((srcval
>> 7) & 0xf8) | /* b */
976 ((srcval
>> 12) & 0x07) ) << ((1-(x
&1))<<2) );
985 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
986 dstbits
+= linebytes
;
991 } else if (bmpImage
->green_mask
==0x07e0) {
992 if (bmpImage
->red_mask
==0xf800) {
993 /* ==== rgb 565 bmp -> pal 4 dib ==== */
994 for (h
=0; h
<lines
; h
++) {
999 for (x
=0; x
<width
; x
++) {
1002 dstval
|=(X11DRV_DIB_GetNearestIndex
1004 ((srcval
>> 8) & 0xf8) | /* r */
1005 ((srcval
>> 13) & 0x07),
1006 ((srcval
>> 3) & 0xfc) | /* g */
1007 ((srcval
>> 9) & 0x03),
1008 ((srcval
<< 3) & 0xf8) | /* b */
1009 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
1018 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1019 dstbits
+= linebytes
;
1021 } else if (bmpImage
->blue_mask
==0xf800) {
1022 /* ==== bgr 565 bmp -> pal 4 dib ==== */
1023 for (h
=0; h
<lines
; h
++) {
1028 for (x
=0; x
<width
; x
++) {
1031 dstval
|=(X11DRV_DIB_GetNearestIndex
1033 ((srcval
<< 3) & 0xf8) | /* r */
1034 ((srcval
>> 2) & 0x07),
1035 ((srcval
>> 3) & 0xfc) | /* g */
1036 ((srcval
>> 9) & 0x03),
1037 ((srcval
>> 8) & 0xf8) | /* b */
1038 ((srcval
>> 13) & 0x07) ) << ((1-(x
&1))<<2) );
1047 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1048 dstbits
+= linebytes
;
1060 if (bmpImage
->bits_per_pixel
==24) {
1061 const void* srcbits
;
1062 const BYTE
*srcbyte
;
1065 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1067 if (bmpImage
->green_mask
!=0x00ff00 ||
1068 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1070 } else if (bmpImage
->blue_mask
==0xff) {
1071 /* ==== rgb 888 bmp -> pal 4 dib ==== */
1072 for (h
=0; h
<lines
; h
++) {
1075 for (x
=0; x
<width
/2; x
++) {
1076 /* Do 2 pixels at a time */
1077 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1082 X11DRV_DIB_GetNearestIndex
1090 /* And the the odd pixel */
1091 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1097 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1098 dstbits
+= linebytes
;
1101 /* ==== bgr 888 bmp -> pal 4 dib ==== */
1102 for (h
=0; h
<lines
; h
++) {
1105 for (x
=0; x
<width
/2; x
++) {
1106 /* Do 2 pixels at a time */
1107 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1112 X11DRV_DIB_GetNearestIndex
1120 /* And the the odd pixel */
1121 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1127 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1128 dstbits
+= linebytes
;
1137 const void* srcbits
;
1138 const BYTE
*srcbyte
;
1141 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1143 if (bmpImage
->green_mask
!=0x00ff00 ||
1144 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1146 } else if (bmpImage
->blue_mask
==0xff) {
1147 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
1148 for (h
=0; h
<lines
; h
++) {
1151 for (x
=0; x
<width
/2; x
++) {
1152 /* Do 2 pixels at a time */
1153 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1158 X11DRV_DIB_GetNearestIndex
1166 /* And the the odd pixel */
1167 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1173 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1174 dstbits
+= linebytes
;
1177 /* ==== bgr 0888 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
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1204 dstbits
+= linebytes
;
1215 /* ==== any bmp format -> pal 4 dib ==== */
1216 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
1217 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
1218 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1219 for (h
=lines
-1; h
>=0; h
--) {
1221 for (x
=0; x
<(width
& ~1); x
+=2) {
1222 *dstbyte
++=(X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4) |
1223 X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
+1, h
), 0);
1226 *dstbyte
=(X11DRV_DIB_MapColor((int *)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4);
1228 dstbits
+= linebytes
;
1235 /***********************************************************************
1236 * X11DRV_DIB_SetImageBits_RLE4
1238 * SetDIBits for a 4-bit deep compressed DIB.
1240 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
1241 DWORD srcwidth
, DWORD dstwidth
,
1242 int left
, int *colors
,
1245 unsigned int x
= 0, width
= min(srcwidth
, dstwidth
);
1246 int y
= lines
- 1, c
, length
;
1247 const BYTE
*begin
= bits
;
1252 if (length
) { /* encoded */
1255 if (x
>= width
) break;
1256 XPutPixel(bmpImage
, x
++, y
, colors
[c
>> 4]);
1257 if (!length
--) break;
1258 if (x
>= width
) break;
1259 XPutPixel(bmpImage
, x
++, y
, colors
[c
& 0xf]);
1278 default: /* absolute */
1281 if (x
< width
) XPutPixel(bmpImage
, x
++, y
, colors
[c
>> 4]);
1282 if (!length
--) break;
1283 if (x
< width
) XPutPixel(bmpImage
, x
++, y
, colors
[c
& 0xf]);
1285 if ((bits
- begin
) & 1)
1294 /***********************************************************************
1295 * X11DRV_DIB_SetImageBits_8
1297 * SetDIBits for an 8-bit deep DIB.
1299 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
1300 DWORD srcwidth
, DWORD dstwidth
, int left
,
1301 const int *colors
, XImage
*bmpImage
,
1305 int h
, width
= min(srcwidth
, dstwidth
);
1306 const BYTE
* srcbyte
;
1312 srcbits
= srcbits
+ linebytes
* (lines
-1);
1313 linebytes
= -linebytes
;
1318 switch (bmpImage
->depth
) {
1321 #if defined(__i386__) && defined(__GNUC__)
1322 /* Some X servers might have 32 bit/ 16bit deep pixel */
1323 if (lines
&& width
&& (bmpImage
->bits_per_pixel
== 16) &&
1324 (ImageByteOrder(gdi_display
)==LSBFirst
) )
1326 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
1327 /* FIXME: Does this really handle all these cases correctly? */
1328 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
1329 for (h
= lines
; h
--; ) {
1330 int _cl1
,_cl2
; /* temp outputs for asm below */
1331 /* Borrowed from DirectDraw */
1332 __asm__
__volatile__(
1337 " movw (%%edx,%%eax,4),%%ax\n"
1339 " xor %%eax,%%eax\n"
1341 :"=S" (srcbyte
), "=D" (_cl1
), "=c" (_cl2
)
1346 :"eax", "cc", "memory"
1348 srcbyte
= (srcbits
+= linebytes
);
1349 dstbits
-= bmpImage
->bytes_per_line
;
1357 #if defined(__i386__) && defined(__GNUC__)
1358 if (lines
&& width
&& (bmpImage
->bits_per_pixel
== 32) &&
1359 (ImageByteOrder(gdi_display
)==LSBFirst
) )
1361 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
1362 /* FIXME: Does this really handle both cases correctly? */
1363 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
1364 for (h
= lines
; h
--; ) {
1365 int _cl1
,_cl2
; /* temp outputs for asm below */
1366 /* Borrowed from DirectDraw */
1367 __asm__
__volatile__(
1372 " movl (%%edx,%%eax,4),%%eax\n"
1374 " xor %%eax,%%eax\n"
1376 :"=S" (srcbyte
), "=D" (_cl1
), "=c" (_cl2
)
1381 :"eax", "cc", "memory"
1383 srcbyte
= (srcbits
+= linebytes
);
1384 dstbits
-= bmpImage
->bytes_per_line
;
1391 break; /* use slow generic case below */
1394 /* ==== pal 8 dib -> any bmp format ==== */
1395 for (h
=lines
-1; h
>=0; h
--) {
1396 for (x
=left
; x
<width
+left
; x
++) {
1397 XPutPixel(bmpImage
, x
, h
, colors
[*srcbyte
++]);
1399 srcbyte
= (srcbits
+= linebytes
);
1403 /***********************************************************************
1404 * X11DRV_DIB_GetImageBits_8
1406 * GetDIBits for an 8-bit deep DIB.
1408 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
1409 DWORD srcwidth
, DWORD dstwidth
,
1410 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
1411 XImage
*bmpImage
, DWORD linebytes
)
1414 int h
, width
= min(srcwidth
, dstwidth
);
1420 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
1421 linebytes
= -linebytes
;
1426 * This condition is true when GetImageBits has been called by
1427 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
1428 * 256 colormaps, so we'll just use for for GetDIBits calls.
1429 * (In somes cases, in a updateDIBSection, the returned colors are bad too)
1431 if (!srccolors
) goto updatesection
;
1433 switch (bmpImage
->depth
) {
1436 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
1438 /* ==== pal 1 bmp -> pal 8 dib ==== */
1439 /* ==== pal 4 bmp -> pal 8 dib ==== */
1440 for (h
=lines
-1; h
>=0; h
--) {
1442 for (x
=0; x
<width
; x
++) {
1443 PALETTEENTRY srcval
;
1444 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
1445 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
1450 dstbits
+= linebytes
;
1458 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
1459 /* ==== pal 8 bmp -> pal 8 dib ==== */
1460 const void* srcbits
;
1461 const BYTE
* srcpixel
;
1463 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1464 for (h
=0; h
<lines
; h
++) {
1467 for (x
= 0; x
< width
; x
++) {
1468 PALETTEENTRY srcval
;
1469 srcval
=srccolors
[(int)*srcpixel
++];
1470 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
1475 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1476 dstbits
+= linebytes
;
1486 const void* srcbits
;
1487 const WORD
* srcpixel
;
1490 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1492 if (bmpImage
->green_mask
==0x03e0) {
1493 if (bmpImage
->red_mask
==0x7c00) {
1494 /* ==== rgb 555 bmp -> pal 8 dib ==== */
1495 for (h
=0; h
<lines
; h
++) {
1498 for (x
=0; x
<width
; x
++) {
1501 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1503 ((srcval
>> 7) & 0xf8) | /* r */
1504 ((srcval
>> 12) & 0x07),
1505 ((srcval
>> 2) & 0xf8) | /* g */
1506 ((srcval
>> 7) & 0x07),
1507 ((srcval
<< 3) & 0xf8) | /* b */
1508 ((srcval
>> 2) & 0x07) );
1510 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1511 dstbits
+= linebytes
;
1513 } else if (bmpImage
->blue_mask
==0x7c00) {
1514 /* ==== bgr 555 bmp -> pal 8 dib ==== */
1515 for (h
=0; h
<lines
; h
++) {
1518 for (x
=0; x
<width
; x
++) {
1521 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1523 ((srcval
<< 3) & 0xf8) | /* r */
1524 ((srcval
>> 2) & 0x07),
1525 ((srcval
>> 2) & 0xf8) | /* g */
1526 ((srcval
>> 7) & 0x07),
1527 ((srcval
>> 7) & 0xf8) | /* b */
1528 ((srcval
>> 12) & 0x07) );
1530 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1531 dstbits
+= linebytes
;
1536 } else if (bmpImage
->green_mask
==0x07e0) {
1537 if (bmpImage
->red_mask
==0xf800) {
1538 /* ==== rgb 565 bmp -> pal 8 dib ==== */
1539 for (h
=0; h
<lines
; h
++) {
1542 for (x
=0; x
<width
; x
++) {
1545 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1547 ((srcval
>> 8) & 0xf8) | /* r */
1548 ((srcval
>> 13) & 0x07),
1549 ((srcval
>> 3) & 0xfc) | /* g */
1550 ((srcval
>> 9) & 0x03),
1551 ((srcval
<< 3) & 0xf8) | /* b */
1552 ((srcval
>> 2) & 0x07) );
1554 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1555 dstbits
+= linebytes
;
1557 } else if (bmpImage
->blue_mask
==0xf800) {
1558 /* ==== bgr 565 bmp -> pal 8 dib ==== */
1559 for (h
=0; h
<lines
; h
++) {
1562 for (x
=0; x
<width
; x
++) {
1565 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1567 ((srcval
<< 3) & 0xf8) | /* r */
1568 ((srcval
>> 2) & 0x07),
1569 ((srcval
>> 3) & 0xfc) | /* g */
1570 ((srcval
>> 9) & 0x03),
1571 ((srcval
>> 8) & 0xf8) | /* b */
1572 ((srcval
>> 13) & 0x07) );
1574 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1575 dstbits
+= linebytes
;
1589 const void* srcbits
;
1590 const BYTE
*srcbyte
;
1592 int bytes_per_pixel
;
1594 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1595 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
1597 if (bmpImage
->green_mask
!=0x00ff00 ||
1598 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1600 } else if (bmpImage
->blue_mask
==0xff) {
1601 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
1602 for (h
=0; h
<lines
; h
++) {
1605 for (x
=0; x
<width
; x
++) {
1606 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1611 srcbyte
+=bytes_per_pixel
;
1613 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1614 dstbits
+= linebytes
;
1617 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
1618 for (h
=0; h
<lines
; h
++) {
1621 for (x
=0; x
<width
; x
++) {
1622 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1627 srcbyte
+=bytes_per_pixel
;
1629 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1630 dstbits
+= linebytes
;
1638 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
1639 bmpImage
->depth
, bmpImage
->red_mask
,
1640 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1642 /* ==== any bmp format -> pal 8 dib ==== */
1643 for (h
=lines
-1; h
>=0; h
--) {
1645 for (x
=0; x
<width
; x
++) {
1646 *dstbyte
=X11DRV_DIB_MapColor
1648 XGetPixel(bmpImage
, x
, h
), *dstbyte
);
1651 dstbits
+= linebytes
;
1657 /***********************************************************************
1658 * X11DRV_DIB_SetImageBits_RLE8
1660 * SetDIBits for an 8-bit deep compressed DIB.
1662 * This function rewritten 941113 by James Youngman. WINE blew out when I
1663 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1665 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1666 * 'End of bitmap' escape code. This code is very much laxer in what it
1667 * allows to end the expansion. Possibly too lax. See the note by
1668 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1669 * bitmap should end with RleEnd, but on the other hand, software exists
1670 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1673 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1674 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1677 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
1678 DWORD srcwidth
, DWORD dstwidth
,
1679 int left
, int *colors
,
1682 unsigned int x
; /* X-position on each line. Increases. */
1683 int y
; /* Line #. Starts at lines-1, decreases */
1684 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
1685 BYTE length
; /* The length pf a run */
1686 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
1689 * Note that the bitmap data is stored by Windows starting at the
1690 * bottom line of the bitmap and going upwards. Within each line,
1691 * the data is stored left-to-right. That's the reason why line
1692 * goes from lines-1 to 0. [JAY]
1702 * If the length byte is not zero (which is the escape value),
1703 * We have a run of length pixels all the same colour. The colour
1704 * index is stored next.
1706 * If the length byte is zero, we need to read the next byte to
1707 * know what to do. [JAY]
1712 * [Run-Length] Encoded mode
1714 int color
= colors
[*pIn
++];
1715 while (length
-- && x
< dstwidth
) XPutPixel(bmpImage
, x
++, y
, color
);
1720 * Escape codes (may be an absolute sequence though)
1722 escape_code
= (*pIn
++);
1731 /* Not all RLE8 bitmaps end with this code. For
1732 * example, Paint Shop Pro produces some that don't.
1733 * That's (I think) what caused the previous
1734 * implementation to fail. [JAY]
1743 default: /* switch to absolute mode */
1744 length
= escape_code
;
1747 int color
= colors
[*pIn
++];
1753 XPutPixel(bmpImage
, x
++, y
, color
);
1756 * If you think for a moment you'll realise that the
1757 * only time we could ever possibly read an odd
1758 * number of bytes is when there is a 0x00 (escape),
1759 * a value >0x02 (absolute mode) and then an odd-
1760 * length run. Therefore this is the only place we
1761 * need to worry about it. Everywhere else the
1762 * bytes are always read in pairs. [JAY]
1764 if (escape_code
& 1) pIn
++; /* Throw away the pad byte. */
1766 } /* switch (escape_code) : Escape sequence */
1772 /***********************************************************************
1773 * X11DRV_DIB_SetImageBits_16
1775 * SetDIBits for a 16-bit deep DIB.
1777 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
1778 DWORD srcwidth
, DWORD dstwidth
, int left
,
1779 X11DRV_PDEVICE
*physDev
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
1780 XImage
*bmpImage
, DWORD linebytes
)
1783 int h
, width
= min(srcwidth
, dstwidth
);
1784 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
1789 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
1790 linebytes
= -linebytes
;
1793 switch (bmpImage
->depth
)
1800 srcbits
=srcbits
+left
*2;
1801 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
1803 if (bmpImage
->green_mask
==0x03e0) {
1804 if (gSrc
==bmpImage
->green_mask
) {
1805 if (rSrc
==bmpImage
->red_mask
) {
1806 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
1807 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
1808 convs
->Convert_5x5_asis
1811 dstbits
,-bmpImage
->bytes_per_line
);
1812 } else if (rSrc
==bmpImage
->blue_mask
) {
1813 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
1814 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
1815 convs
->Convert_555_reverse
1818 dstbits
,-bmpImage
->bytes_per_line
);
1821 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
1822 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
1823 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
1824 convs
->Convert_565_to_555_asis
1827 dstbits
,-bmpImage
->bytes_per_line
);
1829 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
1830 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
1831 convs
->Convert_565_to_555_reverse
1834 dstbits
,-bmpImage
->bytes_per_line
);
1837 } else if (bmpImage
->green_mask
==0x07e0) {
1838 if (gSrc
==bmpImage
->green_mask
) {
1839 if (rSrc
==bmpImage
->red_mask
) {
1840 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
1841 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
1842 convs
->Convert_5x5_asis
1845 dstbits
,-bmpImage
->bytes_per_line
);
1847 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
1848 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
1849 convs
->Convert_565_reverse
1852 dstbits
,-bmpImage
->bytes_per_line
);
1855 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
1856 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
1857 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
1858 convs
->Convert_555_to_565_asis
1861 dstbits
,-bmpImage
->bytes_per_line
);
1863 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
1864 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
1865 convs
->Convert_555_to_565_reverse
1868 dstbits
,-bmpImage
->bytes_per_line
);
1878 if (bmpImage
->bits_per_pixel
==24) {
1881 srcbits
=srcbits
+left
*2;
1882 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
1884 if (bmpImage
->green_mask
!=0x00ff00 ||
1885 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1887 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
1888 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
1890 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
1891 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
1892 convs
->Convert_555_to_888_asis
1895 dstbits
,-bmpImage
->bytes_per_line
);
1897 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
1898 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
1899 convs
->Convert_565_to_888_asis
1902 dstbits
,-bmpImage
->bytes_per_line
);
1906 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
1907 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
1908 convs
->Convert_555_to_888_reverse
1911 dstbits
,-bmpImage
->bytes_per_line
);
1913 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
1914 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
1915 convs
->Convert_565_to_888_reverse
1918 dstbits
,-bmpImage
->bytes_per_line
);
1929 srcbits
=srcbits
+left
*2;
1930 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
1932 if (bmpImage
->green_mask
!=0x00ff00 ||
1933 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1935 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
1936 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
1938 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
1939 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
1940 convs
->Convert_555_to_0888_asis
1943 dstbits
,-bmpImage
->bytes_per_line
);
1945 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
1946 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
1947 convs
->Convert_565_to_0888_asis
1950 dstbits
,-bmpImage
->bytes_per_line
);
1954 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
1955 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
1956 convs
->Convert_555_to_0888_reverse
1959 dstbits
,-bmpImage
->bytes_per_line
);
1961 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
1962 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
1963 convs
->Convert_565_to_0888_reverse
1966 dstbits
,-bmpImage
->bytes_per_line
);
1974 WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
1975 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
1976 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1982 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
1983 const WORD
* srcpixel
;
1984 int rShift1
,gShift1
,bShift1
;
1985 int rShift2
,gShift2
,bShift2
;
1988 /* Set color scaling values */
1989 rShift1
=16+X11DRV_DIB_MaskToShift(rSrc
)-3;
1990 gShift1
=16+X11DRV_DIB_MaskToShift(gSrc
)-3;
1991 bShift1
=16+X11DRV_DIB_MaskToShift(bSrc
)-3;
1996 /* Green has 5 bits, like the others */
2000 /* Green has 6 bits, not 5. Compensate. */
2009 /* We could split it into four separate cases to optimize
2010 * but it is probably not worth it.
2012 for (h
=lines
-1; h
>=0; h
--) {
2013 srcpixel
=(const WORD
*)srcbits
;
2014 for (x
=left
; x
<width
+left
; x
++) {
2016 BYTE red
,green
,blue
;
2017 srcval
=*srcpixel
++ << 16;
2018 red
= ((srcval
>> rShift1
) & 0xf8) |
2019 ((srcval
>> rShift2
) & 0x07);
2020 green
=((srcval
>> gShift1
) & gMask1
) |
2021 ((srcval
>> gShift2
) & gMask2
);
2022 blue
= ((srcval
>> bShift1
) & 0xf8) |
2023 ((srcval
>> bShift2
) & 0x07);
2024 XPutPixel(bmpImage
, x
, h
,
2025 X11DRV_PALETTE_ToPhysical
2026 (physDev
, RGB(red
,green
,blue
)));
2028 srcbits
+= linebytes
;
2036 /***********************************************************************
2037 * X11DRV_DIB_GetImageBits_16
2039 * GetDIBits for an 16-bit deep DIB.
2041 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*dstbits
,
2042 DWORD dstwidth
, DWORD srcwidth
,
2043 PALETTEENTRY
*srccolors
,
2044 DWORD rDst
, DWORD gDst
, DWORD bDst
,
2045 XImage
*bmpImage
, DWORD dibpitch
)
2048 int h
, width
= min(srcwidth
, dstwidth
);
2049 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
2051 DWORD linebytes
= dibpitch
;
2056 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
2057 linebytes
= -linebytes
;
2060 switch (bmpImage
->depth
)
2065 const char* srcbits
;
2067 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2069 if (bmpImage
->green_mask
==0x03e0) {
2070 if (gDst
==bmpImage
->green_mask
) {
2071 if (rDst
==bmpImage
->red_mask
) {
2072 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
2073 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
2074 convs
->Convert_5x5_asis
2076 srcbits
,-bmpImage
->bytes_per_line
,
2079 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
2080 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
2081 convs
->Convert_555_reverse
2083 srcbits
,-bmpImage
->bytes_per_line
,
2087 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
2088 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
2089 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
2090 convs
->Convert_555_to_565_asis
2092 srcbits
,-bmpImage
->bytes_per_line
,
2095 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
2096 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
2097 convs
->Convert_555_to_565_reverse
2099 srcbits
,-bmpImage
->bytes_per_line
,
2103 } else if (bmpImage
->green_mask
==0x07e0) {
2104 if (gDst
==bmpImage
->green_mask
) {
2105 if (rDst
== bmpImage
->red_mask
) {
2106 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
2107 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
2108 convs
->Convert_5x5_asis
2110 srcbits
,-bmpImage
->bytes_per_line
,
2113 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
2114 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
2115 convs
->Convert_565_reverse
2117 srcbits
,-bmpImage
->bytes_per_line
,
2121 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
2122 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
2123 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
2124 convs
->Convert_565_to_555_asis
2126 srcbits
,-bmpImage
->bytes_per_line
,
2129 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
2130 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
2131 convs
->Convert_565_to_555_reverse
2133 srcbits
,-bmpImage
->bytes_per_line
,
2144 if (bmpImage
->bits_per_pixel
== 24) {
2145 const char* srcbits
;
2147 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2149 if (bmpImage
->green_mask
!=0x00ff00 ||
2150 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2152 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
2153 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
2155 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
2156 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
2157 convs
->Convert_888_to_555_asis
2159 srcbits
,-bmpImage
->bytes_per_line
,
2162 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2163 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2164 convs
->Convert_888_to_565_asis
2166 srcbits
,-bmpImage
->bytes_per_line
,
2171 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
2172 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
2173 convs
->Convert_888_to_555_reverse
2175 srcbits
,-bmpImage
->bytes_per_line
,
2178 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
2179 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
2180 convs
->Convert_888_to_565_reverse
2182 srcbits
,-bmpImage
->bytes_per_line
,
2192 const char* srcbits
;
2194 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2196 if (bmpImage
->green_mask
!=0x00ff00 ||
2197 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2199 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
2200 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
2202 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
2203 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
2204 convs
->Convert_0888_to_555_asis
2206 srcbits
,-bmpImage
->bytes_per_line
,
2209 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
2210 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
2211 convs
->Convert_0888_to_565_asis
2213 srcbits
,-bmpImage
->bytes_per_line
,
2218 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
2219 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
2220 convs
->Convert_0888_to_555_reverse
2222 srcbits
,-bmpImage
->bytes_per_line
,
2225 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
2226 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
2227 convs
->Convert_0888_to_565_reverse
2229 srcbits
,-bmpImage
->bytes_per_line
,
2238 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2239 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
2240 int rShift
,gShift
,bShift
;
2243 /* Shift everything 16 bits left so that all shifts are >0,
2244 * even for BGR DIBs. Then a single >> 16 will bring everything
2247 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2248 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2249 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2251 /* 6 bits for the green */
2257 for (h
= lines
- 1; h
>= 0; h
--) {
2258 dstpixel
=(LPWORD
)dstbits
;
2259 for (x
= 0; x
< width
; x
++) {
2260 PALETTEENTRY srcval
;
2262 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2263 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
2264 ((srcval
.peGreen
<< gShift
) & gDst
) |
2265 ((srcval
.peBlue
<< bShift
) & bDst
);
2266 *dstpixel
++=dstval
>> 16;
2268 dstbits
+= linebytes
;
2276 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2277 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
2278 int rShift
,gShift
,bShift
;
2279 const BYTE
* srcbits
;
2280 const BYTE
* srcpixel
;
2283 /* Shift everything 16 bits left so that all shifts are >0,
2284 * even for BGR DIBs. Then a single >> 16 will bring everything
2287 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2288 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2289 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2291 /* 6 bits for the green */
2297 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2298 for (h
=0; h
<lines
; h
++) {
2300 dstpixel
=(LPWORD
)dstbits
;
2301 for (x
= 0; x
< width
; x
++) {
2302 PALETTEENTRY srcval
;
2304 srcval
=srccolors
[(int)*srcpixel
++];
2305 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
2306 ((srcval
.peGreen
<< gShift
) & gDst
) |
2307 ((srcval
.peBlue
<< bShift
) & bDst
);
2308 *dstpixel
++=dstval
>> 16;
2310 srcbits
-= bmpImage
->bytes_per_line
;
2311 dstbits
+= linebytes
;
2321 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
2322 int rShift
,gShift
,bShift
;
2325 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
2326 bmpImage
->depth
, bmpImage
->red_mask
,
2327 bmpImage
->green_mask
, bmpImage
->blue_mask
,
2330 /* Shift everything 16 bits left so that all shifts are >0,
2331 * even for BGR DIBs. Then a single >> 16 will bring everything
2334 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2335 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2336 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2338 /* 6 bits for the green */
2344 for (h
= lines
- 1; h
>= 0; h
--) {
2345 dstpixel
=(LPWORD
)dstbits
;
2346 for (x
= 0; x
< width
; x
++) {
2349 srcval
=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage
, x
, h
));
2350 dstval
=((GetRValue(srcval
) << rShift
) & rDst
) |
2351 ((GetGValue(srcval
) << gShift
) & gDst
) |
2352 ((GetBValue(srcval
) << bShift
) & bDst
);
2353 *dstpixel
++=dstval
>> 16;
2355 dstbits
+= linebytes
;
2363 /***********************************************************************
2364 * X11DRV_DIB_SetImageBits_24
2366 * SetDIBits for a 24-bit deep DIB.
2368 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
2369 DWORD srcwidth
, DWORD dstwidth
, int left
,
2370 X11DRV_PDEVICE
*physDev
,
2371 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
2372 XImage
*bmpImage
, DWORD linebytes
)
2375 int h
, width
= min(srcwidth
, dstwidth
);
2376 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
2381 srcbits
= srcbits
+ linebytes
* (lines
- 1);
2382 linebytes
= -linebytes
;
2385 switch (bmpImage
->depth
)
2388 if (bmpImage
->bits_per_pixel
==24) {
2391 srcbits
=srcbits
+left
*3;
2392 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
2394 if (bmpImage
->green_mask
!=0x00ff00 ||
2395 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2397 } else if (rSrc
==bmpImage
->red_mask
) {
2398 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
2399 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
2400 convs
->Convert_888_asis
2403 dstbits
,-bmpImage
->bytes_per_line
);
2405 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
2406 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
2407 convs
->Convert_888_reverse
2410 dstbits
,-bmpImage
->bytes_per_line
);
2420 srcbits
=srcbits
+left
*3;
2421 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
2423 if (bmpImage
->green_mask
!=0x00ff00 ||
2424 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2426 } else if (rSrc
==bmpImage
->red_mask
) {
2427 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
2428 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
2429 convs
->Convert_888_to_0888_asis
2432 dstbits
,-bmpImage
->bytes_per_line
);
2434 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
2435 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
2436 convs
->Convert_888_to_0888_reverse
2439 dstbits
,-bmpImage
->bytes_per_line
);
2449 srcbits
=srcbits
+left
*3;
2450 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2452 if (bmpImage
->green_mask
==0x03e0) {
2453 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
2454 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
2455 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
2456 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
2457 convs
->Convert_888_to_555_asis
2460 dstbits
,-bmpImage
->bytes_per_line
);
2461 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0x7f00) ||
2462 (bSrc
==0xff && bmpImage
->blue_mask
==0x7f00)) {
2463 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
2464 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
2465 convs
->Convert_888_to_555_reverse
2468 dstbits
,-bmpImage
->bytes_per_line
);
2472 } else if (bmpImage
->green_mask
==0x07e0) {
2473 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
2474 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
2475 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
2476 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
2477 convs
->Convert_888_to_565_asis
2480 dstbits
,-bmpImage
->bytes_per_line
);
2481 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0xf800) ||
2482 (bSrc
==0xff && bmpImage
->blue_mask
==0xf800)) {
2483 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
2484 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
2485 convs
->Convert_888_to_565_reverse
2488 dstbits
,-bmpImage
->bytes_per_line
);
2500 WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2501 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
2502 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2508 /* ==== rgb 888 dib -> any bmp bormat ==== */
2509 const BYTE
* srcbyte
;
2511 /* Windows only supports one 24bpp DIB format: RGB888 */
2513 for (h
= lines
- 1; h
>= 0; h
--) {
2514 srcbyte
=(const BYTE
*)srcbits
;
2515 for (x
= left
; x
< width
+left
; x
++) {
2516 XPutPixel(bmpImage
, x
, h
,
2517 X11DRV_PALETTE_ToPhysical
2518 (physDev
, RGB(srcbyte
[2], srcbyte
[1], srcbyte
[0])));
2521 srcbits
+= linebytes
;
2529 /***********************************************************************
2530 * X11DRV_DIB_GetImageBits_24
2532 * GetDIBits for an 24-bit deep DIB.
2534 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*dstbits
,
2535 DWORD dstwidth
, DWORD srcwidth
,
2536 PALETTEENTRY
*srccolors
,
2537 DWORD rDst
, DWORD gDst
, DWORD bDst
,
2538 XImage
*bmpImage
, DWORD linebytes
)
2541 int h
, width
= min(srcwidth
, dstwidth
);
2542 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
2547 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2548 linebytes
= -linebytes
;
2551 switch (bmpImage
->depth
)
2554 if (bmpImage
->bits_per_pixel
==24) {
2555 const char* srcbits
;
2557 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2559 if (bmpImage
->green_mask
!=0x00ff00 ||
2560 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2562 } else if (rDst
==bmpImage
->red_mask
) {
2563 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
2564 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
2565 convs
->Convert_888_asis
2567 srcbits
,-bmpImage
->bytes_per_line
,
2570 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
2571 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
2572 convs
->Convert_888_reverse
2574 srcbits
,-bmpImage
->bytes_per_line
,
2583 const char* srcbits
;
2585 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2587 if (bmpImage
->green_mask
!=0x00ff00 ||
2588 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2590 } else if (rDst
==bmpImage
->red_mask
) {
2591 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
2592 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
2593 convs
->Convert_0888_to_888_asis
2595 srcbits
,-bmpImage
->bytes_per_line
,
2598 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
2599 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
2600 convs
->Convert_0888_to_888_reverse
2602 srcbits
,-bmpImage
->bytes_per_line
,
2611 const char* srcbits
;
2613 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2615 if (bmpImage
->green_mask
==0x03e0) {
2616 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
2617 (bDst
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
2618 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
2619 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
2620 convs
->Convert_555_to_888_asis
2622 srcbits
,-bmpImage
->bytes_per_line
,
2624 } else if ((rDst
==0xff && bmpImage
->red_mask
==0x7f00) ||
2625 (bDst
==0xff && bmpImage
->blue_mask
==0x7f00)) {
2626 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
2627 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
2628 convs
->Convert_555_to_888_reverse
2630 srcbits
,-bmpImage
->bytes_per_line
,
2635 } else if (bmpImage
->green_mask
==0x07e0) {
2636 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
2637 (bDst
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
2638 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
2639 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
2640 convs
->Convert_565_to_888_asis
2642 srcbits
,-bmpImage
->bytes_per_line
,
2644 } else if ((rDst
==0xff && bmpImage
->red_mask
==0xf800) ||
2645 (bDst
==0xff && bmpImage
->blue_mask
==0xf800)) {
2646 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
2647 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
2648 convs
->Convert_565_to_888_reverse
2650 srcbits
,-bmpImage
->bytes_per_line
,
2663 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2664 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
2667 /* Windows only supports one 24bpp DIB format: rgb 888 */
2668 for (h
= lines
- 1; h
>= 0; h
--) {
2670 for (x
= 0; x
< width
; x
++) {
2671 PALETTEENTRY srcval
;
2672 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2673 dstbyte
[0]=srcval
.peBlue
;
2674 dstbyte
[1]=srcval
.peGreen
;
2675 dstbyte
[2]=srcval
.peRed
;
2678 dstbits
+= linebytes
;
2686 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
== 0 && srccolors
) {
2687 /* ==== pal 8 bmp -> rgb 888 dib ==== */
2688 const void* srcbits
;
2689 const BYTE
* srcpixel
;
2692 /* Windows only supports one 24bpp DIB format: rgb 888 */
2693 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2694 for (h
= lines
- 1; h
>= 0; h
--) {
2697 for (x
= 0; x
< width
; x
++ ) {
2698 PALETTEENTRY srcval
;
2699 srcval
=srccolors
[(int)*srcpixel
++];
2700 dstbyte
[0]=srcval
.peBlue
;
2701 dstbyte
[1]=srcval
.peGreen
;
2702 dstbyte
[2]=srcval
.peRed
;
2705 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2706 dstbits
+= linebytes
;
2716 /* ==== any bmp format -> 888 dib ==== */
2719 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
2720 bmpImage
->depth
, bmpImage
->red_mask
,
2721 bmpImage
->green_mask
, bmpImage
->blue_mask
,
2724 /* Windows only supports one 24bpp DIB format: rgb 888 */
2725 for (h
= lines
- 1; h
>= 0; h
--) {
2727 for (x
= 0; x
< width
; x
++) {
2728 COLORREF srcval
=X11DRV_PALETTE_ToLogical
2729 (XGetPixel( bmpImage
, x
, h
));
2730 dstbyte
[0]=GetBValue(srcval
);
2731 dstbyte
[1]=GetGValue(srcval
);
2732 dstbyte
[2]=GetRValue(srcval
);
2735 dstbits
+= linebytes
;
2743 /***********************************************************************
2744 * X11DRV_DIB_SetImageBits_32
2746 * SetDIBits for a 32-bit deep DIB.
2748 static void X11DRV_DIB_SetImageBits_32(int lines
, const BYTE
*srcbits
,
2749 DWORD srcwidth
, DWORD dstwidth
, int left
,
2750 X11DRV_PDEVICE
*physDev
,
2751 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
2756 int h
, width
= min(srcwidth
, dstwidth
);
2757 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
2762 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
2763 linebytes
= -linebytes
;
2766 ptr
= (DWORD
*) srcbits
+ left
;
2768 switch (bmpImage
->depth
)
2771 if (bmpImage
->bits_per_pixel
==24) {
2774 srcbits
=srcbits
+left
*4;
2775 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
2777 if (rSrc
==bmpImage
->red_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->blue_mask
) {
2778 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
2779 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
2780 convs
->Convert_0888_to_888_asis
2783 dstbits
,-bmpImage
->bytes_per_line
);
2784 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2785 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2787 /* the tests below assume sane bmpImage masks */
2788 } else if (rSrc
==bmpImage
->blue_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->red_mask
) {
2789 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
2790 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
2791 convs
->Convert_0888_to_888_reverse
2794 dstbits
,-bmpImage
->bytes_per_line
);
2795 } else if (bmpImage
->blue_mask
==0xff) {
2796 /* ==== any 0888 dib -> rgb 888 bmp ==== */
2797 convs
->Convert_any0888_to_rgb888
2801 dstbits
,-bmpImage
->bytes_per_line
);
2803 /* ==== any 0888 dib -> bgr 888 bmp ==== */
2804 convs
->Convert_any0888_to_bgr888
2808 dstbits
,-bmpImage
->bytes_per_line
);
2818 srcbits
=srcbits
+left
*4;
2819 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
2821 if (gSrc
==bmpImage
->green_mask
) {
2822 if (rSrc
==bmpImage
->red_mask
&& bSrc
==bmpImage
->blue_mask
) {
2823 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
2824 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
2825 convs
->Convert_0888_asis
2828 dstbits
,-bmpImage
->bytes_per_line
);
2829 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2830 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2832 /* the tests below assume sane bmpImage masks */
2833 } else if (rSrc
==bmpImage
->blue_mask
&& bSrc
==bmpImage
->red_mask
) {
2834 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
2835 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
2836 convs
->Convert_0888_reverse
2839 dstbits
,-bmpImage
->bytes_per_line
);
2841 /* ==== any 0888 dib -> any 0888 bmp ==== */
2842 convs
->Convert_0888_any
2846 dstbits
,-bmpImage
->bytes_per_line
,
2847 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2849 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2850 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2852 /* the tests below assume sane bmpImage masks */
2854 /* ==== any 0888 dib -> any 0888 bmp ==== */
2855 convs
->Convert_0888_any
2859 dstbits
,-bmpImage
->bytes_per_line
,
2860 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2870 srcbits
=srcbits
+left
*4;
2871 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2873 if (rSrc
==0xff0000 && gSrc
==0x00ff00 && bSrc
==0x0000ff) {
2874 if (bmpImage
->green_mask
==0x03e0) {
2875 if (bmpImage
->red_mask
==0x7f00) {
2876 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
2877 convs
->Convert_0888_to_555_asis
2880 dstbits
,-bmpImage
->bytes_per_line
);
2881 } else if (bmpImage
->blue_mask
==0x7f00) {
2882 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
2883 convs
->Convert_0888_to_555_reverse
2886 dstbits
,-bmpImage
->bytes_per_line
);
2890 } else if (bmpImage
->green_mask
==0x07e0) {
2891 if (bmpImage
->red_mask
==0xf800) {
2892 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
2893 convs
->Convert_0888_to_565_asis
2896 dstbits
,-bmpImage
->bytes_per_line
);
2897 } else if (bmpImage
->blue_mask
==0xf800) {
2898 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
2899 convs
->Convert_0888_to_565_reverse
2902 dstbits
,-bmpImage
->bytes_per_line
);
2909 } else if (rSrc
==0x0000ff && gSrc
==0x00ff00 && bSrc
==0xff0000) {
2910 if (bmpImage
->green_mask
==0x03e0) {
2911 if (bmpImage
->blue_mask
==0x7f00) {
2912 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
2913 convs
->Convert_0888_to_555_asis
2916 dstbits
,-bmpImage
->bytes_per_line
);
2917 } else if (bmpImage
->red_mask
==0x7f00) {
2918 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
2919 convs
->Convert_0888_to_555_reverse
2922 dstbits
,-bmpImage
->bytes_per_line
);
2926 } else if (bmpImage
->green_mask
==0x07e0) {
2927 if (bmpImage
->blue_mask
==0xf800) {
2928 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
2929 convs
->Convert_0888_to_565_asis
2932 dstbits
,-bmpImage
->bytes_per_line
);
2933 } else if (bmpImage
->red_mask
==0xf800) {
2934 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
2935 convs
->Convert_0888_to_565_reverse
2938 dstbits
,-bmpImage
->bytes_per_line
);
2946 if (bmpImage
->green_mask
==0x03e0 &&
2947 (bmpImage
->red_mask
==0x7f00 ||
2948 bmpImage
->blue_mask
==0x7f00)) {
2949 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
2950 convs
->Convert_any0888_to_5x5
2954 dstbits
,-bmpImage
->bytes_per_line
,
2955 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2956 } else if (bmpImage
->green_mask
==0x07e0 &&
2957 (bmpImage
->red_mask
==0xf800 ||
2958 bmpImage
->blue_mask
==0xf800)) {
2959 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
2960 convs
->Convert_any0888_to_5x5
2964 dstbits
,-bmpImage
->bytes_per_line
,
2965 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2975 WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2976 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
2977 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2983 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
2984 const DWORD
* srcpixel
;
2985 int rShift
,gShift
,bShift
;
2987 rShift
=X11DRV_DIB_MaskToShift(rSrc
);
2988 gShift
=X11DRV_DIB_MaskToShift(gSrc
);
2989 bShift
=X11DRV_DIB_MaskToShift(bSrc
);
2991 for (h
= lines
- 1; h
>= 0; h
--) {
2992 srcpixel
=(const DWORD
*)srcbits
;
2993 for (x
= left
; x
< width
+left
; x
++) {
2995 BYTE red
,green
,blue
;
2996 srcvalue
=*srcpixel
++;
2997 red
= (srcvalue
>> rShift
) & 0xff;
2998 green
=(srcvalue
>> gShift
) & 0xff;
2999 blue
= (srcvalue
>> bShift
) & 0xff;
3000 XPutPixel(bmpImage
, x
, h
, X11DRV_PALETTE_ToPhysical
3001 (physDev
, RGB(red
,green
,blue
)));
3003 srcbits
+= linebytes
;
3011 /***********************************************************************
3012 * X11DRV_DIB_GetImageBits_32
3014 * GetDIBits for an 32-bit deep DIB.
3016 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*dstbits
,
3017 DWORD dstwidth
, DWORD srcwidth
,
3018 PALETTEENTRY
*srccolors
,
3019 DWORD rDst
, DWORD gDst
, DWORD bDst
,
3020 XImage
*bmpImage
, DWORD linebytes
)
3023 int h
, width
= min(srcwidth
, dstwidth
);
3025 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
3030 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
3031 linebytes
= -linebytes
;
3036 switch (bmpImage
->depth
)
3039 if (bmpImage
->bits_per_pixel
==24) {
3040 const void* srcbits
;
3042 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3044 if (rDst
==bmpImage
->red_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->blue_mask
) {
3045 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3046 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3047 convs
->Convert_888_to_0888_asis
3049 srcbits
,-bmpImage
->bytes_per_line
,
3051 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3052 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3054 /* the tests below assume sane bmpImage masks */
3055 } else if (rDst
==bmpImage
->blue_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->red_mask
) {
3056 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3057 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3058 convs
->Convert_888_to_0888_reverse
3060 srcbits
,-bmpImage
->bytes_per_line
,
3062 } else if (bmpImage
->blue_mask
==0xff) {
3063 /* ==== rgb 888 bmp -> any 0888 dib ==== */
3064 convs
->Convert_rgb888_to_any0888
3066 srcbits
,-bmpImage
->bytes_per_line
,
3070 /* ==== bgr 888 bmp -> any 0888 dib ==== */
3071 convs
->Convert_bgr888_to_any0888
3073 srcbits
,-bmpImage
->bytes_per_line
,
3083 const char* srcbits
;
3085 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3087 if (gDst
==bmpImage
->green_mask
) {
3088 if (rDst
==bmpImage
->red_mask
&& bDst
==bmpImage
->blue_mask
) {
3089 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
3090 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
3091 convs
->Convert_0888_asis
3093 srcbits
,-bmpImage
->bytes_per_line
,
3095 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3096 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3098 /* the tests below assume sane bmpImage masks */
3099 } else if (rDst
==bmpImage
->blue_mask
&& bDst
==bmpImage
->red_mask
) {
3100 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
3101 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
3102 convs
->Convert_0888_reverse
3104 srcbits
,-bmpImage
->bytes_per_line
,
3107 /* ==== any 0888 bmp -> any 0888 dib ==== */
3108 convs
->Convert_0888_any
3110 srcbits
,-bmpImage
->bytes_per_line
,
3111 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3115 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3116 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3118 /* the tests below assume sane bmpImage masks */
3120 /* ==== any 0888 bmp -> any 0888 dib ==== */
3121 convs
->Convert_0888_any
3123 srcbits
,-bmpImage
->bytes_per_line
,
3124 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3134 const char* srcbits
;
3136 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3138 if (rDst
==0xff0000 && gDst
==0x00ff00 && bDst
==0x0000ff) {
3139 if (bmpImage
->green_mask
==0x03e0) {
3140 if (bmpImage
->red_mask
==0x7f00) {
3141 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
3142 convs
->Convert_555_to_0888_asis
3144 srcbits
,-bmpImage
->bytes_per_line
,
3146 } else if (bmpImage
->blue_mask
==0x7f00) {
3147 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
3148 convs
->Convert_555_to_0888_reverse
3150 srcbits
,-bmpImage
->bytes_per_line
,
3155 } else if (bmpImage
->green_mask
==0x07e0) {
3156 if (bmpImage
->red_mask
==0xf800) {
3157 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
3158 convs
->Convert_565_to_0888_asis
3160 srcbits
,-bmpImage
->bytes_per_line
,
3162 } else if (bmpImage
->blue_mask
==0xf800) {
3163 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
3164 convs
->Convert_565_to_0888_reverse
3166 srcbits
,-bmpImage
->bytes_per_line
,
3174 } else if (rDst
==0x0000ff && gDst
==0x00ff00 && bDst
==0xff0000) {
3175 if (bmpImage
->green_mask
==0x03e0) {
3176 if (bmpImage
->blue_mask
==0x7f00) {
3177 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
3178 convs
->Convert_555_to_0888_asis
3180 srcbits
,-bmpImage
->bytes_per_line
,
3182 } else if (bmpImage
->red_mask
==0x7f00) {
3183 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
3184 convs
->Convert_555_to_0888_reverse
3186 srcbits
,-bmpImage
->bytes_per_line
,
3191 } else if (bmpImage
->green_mask
==0x07e0) {
3192 if (bmpImage
->blue_mask
==0xf800) {
3193 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
3194 convs
->Convert_565_to_0888_asis
3196 srcbits
,-bmpImage
->bytes_per_line
,
3198 } else if (bmpImage
->red_mask
==0xf800) {
3199 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
3200 convs
->Convert_565_to_0888_reverse
3202 srcbits
,-bmpImage
->bytes_per_line
,
3211 if (bmpImage
->green_mask
==0x03e0 &&
3212 (bmpImage
->red_mask
==0x7f00 ||
3213 bmpImage
->blue_mask
==0x7f00)) {
3214 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
3215 convs
->Convert_5x5_to_any0888
3217 srcbits
,-bmpImage
->bytes_per_line
,
3218 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3221 } else if (bmpImage
->green_mask
==0x07e0 &&
3222 (bmpImage
->red_mask
==0xf800 ||
3223 bmpImage
->blue_mask
==0xf800)) {
3224 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
3225 convs
->Convert_5x5_to_any0888
3227 srcbits
,-bmpImage
->bytes_per_line
,
3228 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3240 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3241 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
3242 int rShift
,gShift
,bShift
;
3245 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3246 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3247 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3248 for (h
= lines
- 1; h
>= 0; h
--) {
3249 dstpixel
=(DWORD
*)dstbits
;
3250 for (x
= 0; x
< width
; x
++) {
3251 PALETTEENTRY srcval
;
3252 srcval
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
3253 *dstpixel
++=(srcval
.peRed
<< rShift
) |
3254 (srcval
.peGreen
<< gShift
) |
3255 (srcval
.peBlue
<< bShift
);
3257 dstbits
+= linebytes
;
3265 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3266 /* ==== pal 8 bmp -> any 0888 dib ==== */
3267 int rShift
,gShift
,bShift
;
3268 const void* srcbits
;
3269 const BYTE
* srcpixel
;
3272 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3273 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3274 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3275 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3276 for (h
= lines
- 1; h
>= 0; h
--) {
3278 dstpixel
=(DWORD
*)dstbits
;
3279 for (x
= 0; x
< width
; x
++) {
3280 PALETTEENTRY srcval
;
3281 srcval
=srccolors
[(int)*srcpixel
++];
3282 *dstpixel
++=(srcval
.peRed
<< rShift
) |
3283 (srcval
.peGreen
<< gShift
) |
3284 (srcval
.peBlue
<< bShift
);
3286 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
3287 dstbits
+= linebytes
;
3297 /* ==== any bmp format -> any 0888 dib ==== */
3298 int rShift
,gShift
,bShift
;
3301 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
3302 bmpImage
->depth
, bmpImage
->red_mask
,
3303 bmpImage
->green_mask
, bmpImage
->blue_mask
,
3306 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3307 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3308 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3309 for (h
= lines
- 1; h
>= 0; h
--) {
3310 dstpixel
=(DWORD
*)dstbits
;
3311 for (x
= 0; x
< width
; x
++) {
3313 srcval
=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage
, x
, h
));
3314 *dstpixel
++=(GetRValue(srcval
) << rShift
) |
3315 (GetGValue(srcval
) << gShift
) |
3316 (GetBValue(srcval
) << bShift
);
3318 dstbits
+= linebytes
;
3325 /***********************************************************************
3326 * X11DRV_DIB_SetImageBits
3328 * Transfer the bits to an X image.
3329 * Helper function for SetDIBits() and SetDIBitsToDevice().
3331 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
3333 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
3338 bmpImage
= descr
->image
;
3340 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
3341 descr
->infoWidth
, lines
, 32, 0 );
3342 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
3343 if(bmpImage
->data
== NULL
) {
3344 ERR("Out of memory!\n");
3345 XDestroyImage( bmpImage
);
3346 wine_tsx11_unlock();
3351 TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
3352 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
3353 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
3354 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
3355 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
3357 /* Transfer the pixels */
3358 switch(descr
->infoBpp
)
3361 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
3362 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
3363 bmpImage
, descr
->dibpitch
);
3366 if (descr
->compression
) {
3367 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
3368 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
3369 bmpImage
, descr
->xSrc
, descr
->ySrc
);
3371 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
3372 descr
->infoWidth
, descr
->width
,
3373 descr
->xSrc
, (int *)(descr
->colorMap
),
3376 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
3377 descr
->infoWidth
, descr
->width
,
3378 descr
->xSrc
, (int*)(descr
->colorMap
),
3379 bmpImage
, descr
->dibpitch
);
3382 if (descr
->compression
) {
3383 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
3384 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
3385 bmpImage
, descr
->xSrc
, descr
->ySrc
);
3386 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
3387 descr
->infoWidth
, descr
->width
,
3388 descr
->xSrc
, (int *)(descr
->colorMap
),
3391 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
3392 descr
->infoWidth
, descr
->width
,
3393 descr
->xSrc
, (int *)(descr
->colorMap
),
3394 bmpImage
, descr
->dibpitch
);
3398 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
3399 descr
->infoWidth
, descr
->width
,
3400 descr
->xSrc
, descr
->physDev
,
3401 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3402 bmpImage
, descr
->dibpitch
);
3405 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
3406 descr
->infoWidth
, descr
->width
,
3407 descr
->xSrc
, descr
->physDev
,
3408 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3409 bmpImage
, descr
->dibpitch
);
3412 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
3413 descr
->infoWidth
, descr
->width
,
3414 descr
->xSrc
, descr
->physDev
,
3415 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3416 bmpImage
, descr
->dibpitch
);
3419 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
3423 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
3424 descr
->drawable
, descr
->gc
, bmpImage
,
3425 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3426 descr
->width
, descr
->height
);
3427 #ifdef HAVE_LIBXXSHM
3430 XShmPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
3431 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3432 descr
->width
, descr
->height
, FALSE
);
3433 XSync( gdi_display
, 0 );
3437 XPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
3438 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3439 descr
->width
, descr
->height
);
3441 if (!descr
->image
) XDestroyImage( bmpImage
);
3442 wine_tsx11_unlock();
3446 /***********************************************************************
3447 * X11DRV_DIB_GetImageBits
3449 * Transfer the bits from an X image.
3451 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
3453 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
3458 bmpImage
= descr
->image
;
3460 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
3461 descr
->infoWidth
, lines
, 32, 0 );
3462 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
3463 if(bmpImage
->data
== NULL
) {
3464 ERR("Out of memory!\n");
3465 XDestroyImage( bmpImage
);
3466 wine_tsx11_unlock();
3471 #ifdef HAVE_LIBXXSHM
3474 int saveRed
, saveGreen
, saveBlue
;
3476 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
3477 gdi_display
, descr
->drawable
, bmpImage
,
3478 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
3480 /* We must save and restore the bmpImage's masks in order
3481 * to preserve them across the call to XShmGetImage, which
3482 * decides to eleminate them since it doesn't happen to know
3483 * what the format of the image is supposed to be, even though
3485 saveRed
= bmpImage
->red_mask
;
3486 saveBlue
= bmpImage
->blue_mask
;
3487 saveGreen
= bmpImage
->green_mask
;
3489 XShmGetImage( gdi_display
, descr
->drawable
, bmpImage
,
3490 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
3492 bmpImage
->red_mask
= saveRed
;
3493 bmpImage
->blue_mask
= saveBlue
;
3494 bmpImage
->green_mask
= saveGreen
;
3497 #endif /* HAVE_LIBXXSHM */
3499 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
3500 gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
, descr
->width
,
3501 lines
, AllPlanes
, ZPixmap
, bmpImage
, descr
->xDest
, descr
->yDest
);
3502 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
,
3503 descr
->width
, lines
, AllPlanes
, ZPixmap
,
3504 bmpImage
, descr
->xDest
, descr
->yDest
);
3507 TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
3508 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
3509 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
3510 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
3511 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
3512 /* Transfer the pixels */
3513 switch(descr
->infoBpp
)
3516 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
3517 descr
->infoWidth
, descr
->width
,
3518 descr
->colorMap
, descr
->palentry
,
3519 bmpImage
, descr
->dibpitch
);
3523 if (descr
->compression
) {
3524 FIXME("Compression not yet supported!\n");
3525 if(descr
->sizeImage
< X11DRV_DIB_GetDIBWidthBytes( descr
->infoWidth
, 4 ) * abs(descr
->lines
))
3528 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
3529 descr
->infoWidth
, descr
->width
,
3530 descr
->colorMap
, descr
->palentry
,
3531 bmpImage
, descr
->dibpitch
);
3534 if (descr
->compression
) {
3535 FIXME("Compression not yet supported!\n");
3536 if(descr
->sizeImage
< X11DRV_DIB_GetDIBWidthBytes( descr
->infoWidth
, 8 ) * abs(descr
->lines
))
3539 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
3540 descr
->infoWidth
, descr
->width
,
3541 descr
->colorMap
, descr
->palentry
,
3542 bmpImage
, descr
->dibpitch
);
3546 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
3547 descr
->infoWidth
,descr
->width
,
3549 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3550 bmpImage
, descr
->dibpitch
);
3554 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
3555 descr
->infoWidth
,descr
->width
,
3557 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3558 bmpImage
, descr
->dibpitch
);
3562 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
3563 descr
->infoWidth
, descr
->width
,
3565 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3566 bmpImage
, descr
->dibpitch
);
3570 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
3574 if (!descr
->image
) XDestroyImage( bmpImage
);
3575 wine_tsx11_unlock();
3579 /*************************************************************************
3580 * X11DRV_SetDIBitsToDevice
3583 INT
X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE
*physDev
, INT xDest
, INT yDest
, DWORD cx
,
3584 DWORD cy
, INT xSrc
, INT ySrc
,
3585 UINT startscan
, UINT lines
, LPCVOID bits
,
3586 const BITMAPINFO
*info
, UINT coloruse
)
3588 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3595 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
3596 &descr
.infoBpp
, &descr
.compression
) == -1)
3598 top_down
= (height
< 0);
3599 if (top_down
) height
= -height
;
3603 LPtoDP(physDev
->hdc
, &pt
, 1);
3605 if (!lines
|| (startscan
>= height
)) return 0;
3606 if (!top_down
&& startscan
+ lines
> height
) lines
= height
- startscan
;
3608 /* make xSrc,ySrc point to the upper-left corner, not the lower-left one,
3609 * and clamp all values to fit inside [startscan,startscan+lines]
3611 if (ySrc
+ cy
<= startscan
+ lines
)
3613 UINT y
= startscan
+ lines
- (ySrc
+ cy
);
3614 if (ySrc
< startscan
) cy
-= (startscan
- ySrc
);
3617 /* avoid getting unnecessary lines */
3619 if (y
>= lines
) return 0;
3624 if (y
>= lines
) return lines
;
3625 ySrc
= y
; /* need to get all lines in top down mode */
3630 if (ySrc
>= startscan
+ lines
) return lines
;
3631 pt
.y
+= ySrc
+ cy
- (startscan
+ lines
);
3632 cy
= startscan
+ lines
- ySrc
;
3634 if (cy
> lines
) cy
= lines
;
3636 if (xSrc
>= width
) return lines
;
3637 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
3638 if (!cx
|| !cy
) return lines
;
3640 /* Update the pixmap from the DIB section */
3641 X11DRV_LockDIBSection(physDev
, DIB_Status_GdiMod
, FALSE
);
3643 X11DRV_SetupGCForText( physDev
); /* To have the correct colors */
3645 XSetFunction(gdi_display
, physDev
->gc
, X11DRV_XROPfunction
[GetROP2(physDev
->hdc
) - 1]);
3646 wine_tsx11_unlock();
3648 switch (descr
.infoBpp
)
3653 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
3654 coloruse
== DIB_PAL_COLORS
? physDev
: NULL
, coloruse
,
3655 physDev
->depth
, info
, &descr
.nColorMap
);
3656 if (!descr
.colorMap
) return 0;
3657 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3661 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
3662 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
3663 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
3669 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
3670 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
3671 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
3676 descr
.physDev
= physDev
;
3679 descr
.palentry
= NULL
;
3680 descr
.lines
= top_down
? -lines
: lines
;
3681 descr
.infoWidth
= width
;
3682 descr
.depth
= physDev
->depth
;
3683 descr
.drawable
= physDev
->drawable
;
3684 descr
.gc
= physDev
->gc
;
3687 descr
.xDest
= physDev
->org
.x
+ pt
.x
;
3688 descr
.yDest
= physDev
->org
.y
+ pt
.y
;
3691 descr
.useShm
= FALSE
;
3692 descr
.dibpitch
= ((width
* descr
.infoBpp
+ 31) &~31) / 8;
3694 result
= X11DRV_DIB_SetImageBits( &descr
);
3696 if (descr
.infoBpp
<= 8)
3697 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
3699 /* Update the DIBSection of the pixmap */
3700 X11DRV_UnlockDIBSection(physDev
, TRUE
);
3705 /***********************************************************************
3706 * SetDIBits (X11DRV.@)
3708 INT
X11DRV_SetDIBits( X11DRV_PDEVICE
*physDev
, HBITMAP hbitmap
, UINT startscan
,
3709 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
, UINT coloruse
)
3711 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3713 int height
, tmpheight
;
3716 descr
.physDev
= physDev
;
3718 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
3719 &descr
.infoBpp
, &descr
.compression
) == -1)
3723 if (height
< 0) height
= -height
;
3724 if (!lines
|| (startscan
>= height
))
3727 if (!(bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
))) return 0;
3729 if (startscan
+ lines
> height
) lines
= height
- startscan
;
3731 switch (descr
.infoBpp
)
3736 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
3737 coloruse
== DIB_PAL_COLORS
? descr
.physDev
: NULL
, coloruse
,
3738 bmp
->bitmap
.bmBitsPixel
,
3739 info
, &descr
.nColorMap
);
3740 if (!descr
.colorMap
)
3742 GDI_ReleaseObj( hbitmap
);
3745 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3749 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
3750 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
3751 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
3757 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
3758 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
3759 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
3768 descr
.palentry
= NULL
;
3769 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
3770 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3771 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
3772 descr
.gc
= BITMAP_GC(bmp
);
3776 descr
.yDest
= height
- startscan
- lines
;
3777 descr
.width
= bmp
->bitmap
.bmWidth
;
3778 descr
.height
= lines
;
3779 descr
.useShm
= FALSE
;
3780 descr
.dibpitch
= ((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8;
3781 X11DRV_DIB_Lock(bmp
, DIB_Status_GdiMod
, FALSE
);
3782 result
= X11DRV_DIB_SetImageBits( &descr
);
3783 X11DRV_DIB_Unlock(bmp
, TRUE
);
3785 if (descr
.colorMap
) HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
3787 GDI_ReleaseObj( hbitmap
);
3791 /***********************************************************************
3792 * GetDIBits (X11DRV.@)
3794 INT
X11DRV_GetDIBits( X11DRV_PDEVICE
*physDev
, HBITMAP hbitmap
, UINT startscan
, UINT lines
,
3795 LPVOID bits
, BITMAPINFO
*info
, UINT coloruse
)
3797 X11DRV_DIBSECTION
*dib
;
3798 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3799 PALETTEENTRY palette
[256];
3803 GetPaletteEntries( GetCurrentObject( physDev
->hdc
, OBJ_PAL
), 0, 256, palette
);
3805 if (!(bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
))) return 0;
3807 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3809 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
3810 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
3811 (int)info
->bmiHeader
.biWidth
, (int)info
->bmiHeader
.biHeight
,
3814 if( lines
> bmp
->bitmap
.bmHeight
) lines
= bmp
->bitmap
.bmHeight
;
3816 height
= info
->bmiHeader
.biHeight
;
3817 if (height
< 0) height
= -height
;
3818 if( lines
> height
) lines
= height
;
3819 /* Top-down images have a negative biHeight, the scanlines of theses images
3820 * were inverted in X11DRV_DIB_GetImageBits_xx
3821 * To prevent this we simply change the sign of lines
3822 * (the number of scan lines to copy).
3823 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3825 if( info
->bmiHeader
.biHeight
< 0 && lines
> 0) lines
= -lines
;
3827 if( startscan
>= bmp
->bitmap
.bmHeight
)
3833 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &descr
.lines
,
3834 &descr
.infoBpp
, &descr
.compression
) == -1)
3840 descr
.colorMap
= NULL
;
3842 switch (descr
.infoBpp
)
3847 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3848 if(coloruse
== DIB_RGB_COLORS
)
3849 descr
.colorMap
= info
->bmiColors
;
3851 int num_colors
= 1 << descr
.infoBpp
, i
;
3854 WORD
*index
= (WORD
*)info
->bmiColors
;
3855 descr
.colorMap
= rgb
= HeapAlloc(GetProcessHeap(), 0, num_colors
* sizeof(RGBQUAD
));
3856 for(i
= 0; i
< num_colors
; i
++, rgb
++, index
++) {
3857 colref
= X11DRV_PALETTE_ToLogical(X11DRV_PALETTE_ToPhysical(physDev
, PALETTEINDEX(*index
)));
3858 rgb
->rgbRed
= GetRValue(colref
);
3859 rgb
->rgbGreen
= GetGValue(colref
);
3860 rgb
->rgbBlue
= GetBValue(colref
);
3861 rgb
->rgbReserved
= 0;
3867 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
3868 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
3869 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
3873 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
3874 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
3875 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
3879 descr
.physDev
= physDev
;
3880 descr
.palentry
= palette
;
3883 descr
.lines
= lines
;
3884 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3885 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
3886 descr
.gc
= BITMAP_GC(bmp
);
3887 descr
.width
= bmp
->bitmap
.bmWidth
;
3888 descr
.height
= bmp
->bitmap
.bmHeight
;
3892 descr
.sizeImage
= info
->bmiHeader
.biSizeImage
;
3894 if (descr
.lines
> 0)
3896 descr
.ySrc
= (descr
.height
-1) - (startscan
+ (lines
-1));
3900 descr
.ySrc
= startscan
;
3902 #ifdef HAVE_LIBXXSHM
3903 descr
.useShm
= dib
? (dib
->shminfo
.shmid
!= -1) : FALSE
;
3905 descr
.useShm
= FALSE
;
3907 descr
.dibpitch
= dib
? (dib
->dibSection
.dsBm
.bmWidthBytes
)
3908 : (((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8);
3910 X11DRV_DIB_Lock(bmp
, DIB_Status_GdiMod
, FALSE
);
3911 X11DRV_DIB_GetImageBits( &descr
);
3912 X11DRV_DIB_Unlock(bmp
, TRUE
);
3914 if(info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
3915 info
->bmiHeader
.biSizeImage
= X11DRV_DIB_GetDIBWidthBytes( info
->bmiHeader
.biWidth
,
3916 info
->bmiHeader
.biBitCount
)
3917 * abs( info
->bmiHeader
.biHeight
);
3919 if (descr
.compression
== BI_BITFIELDS
)
3921 *(DWORD
*)info
->bmiColors
= descr
.rMask
;
3922 *((DWORD
*)info
->bmiColors
+1) = descr
.gMask
;
3923 *((DWORD
*)info
->bmiColors
+2) = descr
.bMask
;
3927 /* if RLE or JPEG compression were supported,
3928 * this line would be invalid. */
3929 info
->bmiHeader
.biCompression
= 0;
3932 if(descr
.colorMap
&& descr
.colorMap
!= info
->bmiColors
)
3933 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
3935 GDI_ReleaseObj( hbitmap
);
3939 /***********************************************************************
3940 * DIB_DoProtectDIBSection
3942 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
3946 DIBSECTION
*dib
= bmp
->dib
;
3947 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
3948 : -dib
->dsBm
.bmHeight
;
3950 /* use the biSizeImage data as the memory size only if we're dealing with a
3951 compressed image where the value is set. Otherwise, calculate based on
3953 if (dib
->dsBmih
.biSizeImage
&&
3954 (dib
->dsBmih
.biCompression
== BI_RLE4
|| dib
->dsBmih
.biCompression
== BI_RLE8
))
3955 totalSize
= dib
->dsBmih
.biSizeImage
;
3957 totalSize
= dib
->dsBm
.bmWidthBytes
* effHeight
;
3959 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
3960 TRACE("Changed protection from %ld to %ld\n", old_prot
, new_prot
);
3963 /***********************************************************************
3964 * X11DRV_DIB_DoUpdateDIBSection
3966 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
,
3967 void *colorMap
, int nColorMap
,
3969 DWORD xSrc
, DWORD ySrc
,
3970 DWORD xDest
, DWORD yDest
,
3971 DWORD width
, DWORD height
)
3973 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3974 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3976 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, &descr
.lines
,
3977 &descr
.infoBpp
, &descr
.compression
) == -1)
3980 descr
.physDev
= NULL
;
3981 descr
.palentry
= NULL
;
3982 descr
.image
= dib
->image
;
3983 descr
.colorMap
= colorMap
;
3984 descr
.nColorMap
= nColorMap
;
3985 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
3986 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3988 switch (descr
.infoBpp
)
3993 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3997 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0x7c00;
3998 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x03e0;
3999 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x001f;
4004 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0xff0000;
4005 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x00ff00;
4006 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x0000ff;
4011 descr
.drawable
= dest
;
4012 descr
.gc
= BITMAP_GC(bmp
);
4015 descr
.xDest
= xDest
;
4016 descr
.yDest
= yDest
;
4017 descr
.width
= width
;
4018 descr
.height
= height
;
4019 descr
.sizeImage
= 0;
4021 #ifdef HAVE_LIBXXSHM
4022 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
4024 descr
.useShm
= FALSE
;
4026 descr
.dibpitch
= dib
->dibSection
.dsBm
.bmWidthBytes
;
4030 TRACE("Copying from Pixmap to DIB bits\n");
4031 X11DRV_DIB_GetImageBits( &descr
);
4035 TRACE("Copying from DIB bits to Pixmap\n");
4036 X11DRV_DIB_SetImageBits( &descr
);
4040 /***********************************************************************
4041 * X11DRV_DIB_CopyDIBSection
4043 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE
*physDevSrc
, X11DRV_PDEVICE
*physDevDst
,
4044 DWORD xSrc
, DWORD ySrc
, DWORD xDest
, DWORD yDest
,
4045 DWORD width
, DWORD height
)
4049 int nColorMap
= 0, *colorMap
= NULL
, aColorMap
= FALSE
;
4051 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", physDevSrc
->hdc
, physDevDst
->hdc
,
4052 xSrc
, ySrc
, xDest
, yDest
, width
, height
);
4053 /* this function is meant as an optimization for BitBlt,
4054 * not to be called otherwise */
4055 if (GetObjectType( physDevSrc
->hdc
) != OBJ_MEMDC
) {
4056 ERR("called for non-memory source DC!?\n");
4060 hBitmap
= GetCurrentObject( physDevSrc
->hdc
, OBJ_BITMAP
);
4061 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBitmap
, BITMAP_MAGIC
);
4062 if (!(bmp
&& bmp
->dib
)) {
4063 ERR("called for non-DIBSection!?\n");
4064 GDI_ReleaseObj( hBitmap
);
4067 /* while BitBlt should already have made sure we only get
4068 * positive values, we should check for oversize values */
4069 if ((xSrc
< bmp
->bitmap
.bmWidth
) &&
4070 (ySrc
< bmp
->bitmap
.bmHeight
)) {
4071 if (xSrc
+ width
> bmp
->bitmap
.bmWidth
)
4072 width
= bmp
->bitmap
.bmWidth
- xSrc
;
4073 if (ySrc
+ height
> bmp
->bitmap
.bmHeight
)
4074 height
= bmp
->bitmap
.bmHeight
- ySrc
;
4075 /* if the source bitmap is 8bpp or less, we're supposed to use the
4076 * DC's palette for color conversion (not the DIB color table) */
4077 if (bmp
->dib
->dsBm
.bmBitsPixel
<= 8) {
4078 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4079 HPALETTE hPalette
= GetCurrentObject( physDevSrc
->hdc
, OBJ_PAL
);
4080 if (!hPalette
|| (hPalette
== GetStockObject(DEFAULT_PALETTE
))) {
4081 /* HACK: no palette has been set in the source DC,
4082 * use the DIB colormap instead - this is necessary in some
4083 * cases since we need to do depth conversion in some places
4084 * where real Windows can just copy data straight over */
4085 colorMap
= dib
->colorMap
;
4086 nColorMap
= dib
->nColorMap
;
4088 colorMap
= X11DRV_DIB_BuildColorMap( physDevSrc
, (WORD
)-1,
4089 bmp
->dib
->dsBm
.bmBitsPixel
,
4090 (BITMAPINFO
*)&(bmp
->dib
->dsBmih
),
4092 if (colorMap
) aColorMap
= TRUE
;
4095 /* perform the copy */
4096 X11DRV_DIB_DoCopyDIBSection(bmp
, FALSE
, colorMap
, nColorMap
,
4097 physDevDst
->drawable
, xSrc
, ySrc
,
4098 physDevDst
->org
.x
+ xDest
, physDevDst
->org
.y
+ yDest
,
4100 /* free color mapping */
4102 HeapFree(GetProcessHeap(), 0, colorMap
);
4104 GDI_ReleaseObj( hBitmap
);
4107 /***********************************************************************
4108 * X11DRV_DIB_DoUpdateDIBSection
4110 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
4112 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4113 X11DRV_DIB_DoCopyDIBSection(bmp
, toDIB
, dib
->colorMap
, dib
->nColorMap
,
4114 (Drawable
)bmp
->physBitmap
, 0, 0, 0, 0,
4115 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
4118 /***********************************************************************
4119 * X11DRV_DIB_FaultHandler
4121 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
4126 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
4127 if (!bmp
) return FALSE
;
4129 state
= X11DRV_DIB_Lock(bmp
, DIB_Status_None
, FALSE
);
4130 if (state
!= DIB_Status_InSync
) {
4131 /* no way to tell whether app needs read or write yet,
4133 X11DRV_DIB_Coerce(bmp
, DIB_Status_InSync
, FALSE
);
4135 /* hm, apparently the app must have write access */
4136 X11DRV_DIB_Coerce(bmp
, DIB_Status_AppMod
, FALSE
);
4138 X11DRV_DIB_Unlock(bmp
, TRUE
);
4140 GDI_ReleaseObj( (HBITMAP
)res
);
4144 /***********************************************************************
4147 INT
X11DRV_DIB_Coerce(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
4149 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4150 INT ret
= DIB_Status_None
;
4153 EnterCriticalSection(&(dib
->lock
));
4156 case DIB_Status_GdiMod
:
4157 /* GDI access - request to draw on pixmap */
4158 switch (dib
->status
)
4161 case DIB_Status_None
:
4162 dib
->p_status
= DIB_Status_GdiMod
;
4163 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
4166 case DIB_Status_GdiMod
:
4167 TRACE("GdiMod requested in status GdiMod\n" );
4170 case DIB_Status_InSync
:
4171 TRACE("GdiMod requested in status InSync\n" );
4172 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
4173 dib
->status
= DIB_Status_GdiMod
;
4174 dib
->p_status
= DIB_Status_InSync
;
4177 case DIB_Status_AuxMod
:
4178 TRACE("GdiMod requested in status AuxMod\n" );
4179 if (lossy
) dib
->status
= DIB_Status_GdiMod
;
4180 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_GdiMod
);
4181 dib
->p_status
= DIB_Status_AuxMod
;
4182 if (dib
->status
!= DIB_Status_AppMod
) {
4183 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
4186 /* fall through if copy_aux() had to change to AppMod state */
4188 case DIB_Status_AppMod
:
4189 TRACE("GdiMod requested in status AppMod\n" );
4191 /* make it readonly to avoid app changing data while we copy */
4192 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4193 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
4195 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
4196 dib
->p_status
= DIB_Status_AppMod
;
4197 dib
->status
= DIB_Status_GdiMod
;
4202 case DIB_Status_InSync
:
4203 /* App access - request access to read DIB surface */
4204 /* (typically called from signal handler) */
4205 switch (dib
->status
)
4208 case DIB_Status_None
:
4209 /* shouldn't happen from signal handler */
4212 case DIB_Status_AuxMod
:
4213 TRACE("InSync requested in status AuxMod\n" );
4214 if (lossy
) dib
->status
= DIB_Status_InSync
;
4216 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4217 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_InSync
);
4219 if (dib
->status
!= DIB_Status_GdiMod
) {
4220 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4223 /* fall through if copy_aux() had to change to GdiMod state */
4225 case DIB_Status_GdiMod
:
4226 TRACE("InSync requested in status GdiMod\n" );
4228 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4229 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
4231 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4232 dib
->status
= DIB_Status_InSync
;
4235 case DIB_Status_InSync
:
4236 TRACE("InSync requested in status InSync\n" );
4237 /* shouldn't happen from signal handler */
4240 case DIB_Status_AppMod
:
4241 TRACE("InSync requested in status AppMod\n" );
4242 /* no reason to do anything here, and this
4243 * shouldn't happen from signal handler */
4248 case DIB_Status_AppMod
:
4249 /* App access - request access to write DIB surface */
4250 /* (typically called from signal handler) */
4251 switch (dib
->status
)
4254 case DIB_Status_None
:
4255 /* shouldn't happen from signal handler */
4258 case DIB_Status_AuxMod
:
4259 TRACE("AppMod requested in status AuxMod\n" );
4260 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4261 if (lossy
) dib
->status
= DIB_Status_AppMod
;
4262 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
4263 if (dib
->status
!= DIB_Status_GdiMod
)
4265 /* fall through if copy_aux() had to change to GdiMod state */
4267 case DIB_Status_GdiMod
:
4268 TRACE("AppMod requested in status GdiMod\n" );
4269 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4270 if (!lossy
) X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
4271 dib
->status
= DIB_Status_AppMod
;
4274 case DIB_Status_InSync
:
4275 TRACE("AppMod requested in status InSync\n" );
4276 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4277 dib
->status
= DIB_Status_AppMod
;
4280 case DIB_Status_AppMod
:
4281 TRACE("AppMod requested in status AppMod\n" );
4282 /* shouldn't happen from signal handler */
4287 case DIB_Status_AuxMod
:
4288 if (dib
->status
== DIB_Status_None
) {
4289 dib
->p_status
= req
;
4291 if (dib
->status
!= DIB_Status_AuxMod
)
4292 dib
->p_status
= dib
->status
;
4293 dib
->status
= DIB_Status_AuxMod
;
4296 /* it is up to the caller to do the copy/conversion, probably
4297 * using the return value to decide where to copy from */
4299 LeaveCriticalSection(&(dib
->lock
));
4304 /***********************************************************************
4307 INT
X11DRV_DIB_Lock(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
4309 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4310 INT ret
= DIB_Status_None
;
4313 TRACE("Locking %p from thread %04lx\n", bmp
, GetCurrentThreadId());
4314 EnterCriticalSection(&(dib
->lock
));
4316 if (req
!= DIB_Status_None
)
4317 X11DRV_DIB_Coerce(bmp
, req
, lossy
);
4322 /***********************************************************************
4325 void X11DRV_DIB_Unlock(BITMAPOBJ
*bmp
, BOOL commit
)
4327 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4330 switch (dib
->status
)
4333 case DIB_Status_None
:
4334 /* in case anyone is wondering, this is the "signal handler doesn't
4335 * work" case, where we always have to be ready for app access */
4337 switch (dib
->p_status
)
4339 case DIB_Status_AuxMod
:
4340 TRACE("Unlocking and syncing from AuxMod\n" );
4341 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
4342 if (dib
->status
!= DIB_Status_None
) {
4343 dib
->p_status
= dib
->status
;
4344 dib
->status
= DIB_Status_None
;
4346 if (dib
->p_status
!= DIB_Status_GdiMod
)
4348 /* fall through if copy_aux() had to change to GdiMod state */
4350 case DIB_Status_GdiMod
:
4351 TRACE("Unlocking and syncing from GdiMod\n" );
4352 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
4356 TRACE("Unlocking without needing to sync\n" );
4360 else TRACE("Unlocking with no changes\n");
4361 dib
->p_status
= DIB_Status_None
;
4364 case DIB_Status_GdiMod
:
4365 TRACE("Unlocking in status GdiMod\n" );
4366 /* DIB was protected in Coerce */
4368 /* no commit, revert to InSync if applicable */
4369 if ((dib
->p_status
== DIB_Status_InSync
) ||
4370 (dib
->p_status
== DIB_Status_AppMod
)) {
4371 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4372 dib
->status
= DIB_Status_InSync
;
4377 case DIB_Status_InSync
:
4378 TRACE("Unlocking in status InSync\n" );
4379 /* DIB was already protected in Coerce */
4382 case DIB_Status_AppMod
:
4383 TRACE("Unlocking in status AppMod\n" );
4384 /* DIB was already protected in Coerce */
4385 /* this case is ordinary only called from the signal handler,
4386 * so we don't bother to check for !commit */
4389 case DIB_Status_AuxMod
:
4390 TRACE("Unlocking in status AuxMod\n" );
4392 /* DIB may need protection now */
4393 if ((dib
->p_status
== DIB_Status_InSync
) ||
4394 (dib
->p_status
== DIB_Status_AppMod
))
4395 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
4397 /* no commit, revert to previous state */
4398 if (dib
->p_status
!= DIB_Status_None
)
4399 dib
->status
= dib
->p_status
;
4400 /* no protections changed */
4402 dib
->p_status
= DIB_Status_None
;
4405 LeaveCriticalSection(&(dib
->lock
));
4406 TRACE("Unlocked %p\n", bmp
);
4410 /***********************************************************************
4411 * X11DRV_CoerceDIBSection2
4413 INT
X11DRV_CoerceDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
4418 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4419 if (!bmp
) return DIB_Status_None
;
4420 ret
= X11DRV_DIB_Coerce(bmp
, req
, lossy
);
4421 GDI_ReleaseObj( hBmp
);
4425 /***********************************************************************
4426 * X11DRV_LockDIBSection2
4428 INT
X11DRV_LockDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
4433 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4434 if (!bmp
) return DIB_Status_None
;
4435 ret
= X11DRV_DIB_Lock(bmp
, req
, lossy
);
4436 GDI_ReleaseObj( hBmp
);
4440 /***********************************************************************
4441 * X11DRV_UnlockDIBSection2
4443 void X11DRV_UnlockDIBSection2(HBITMAP hBmp
, BOOL commit
)
4447 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4449 X11DRV_DIB_Unlock(bmp
, commit
);
4450 GDI_ReleaseObj( hBmp
);
4453 /***********************************************************************
4454 * X11DRV_CoerceDIBSection
4456 INT
X11DRV_CoerceDIBSection(X11DRV_PDEVICE
*physDev
, INT req
, BOOL lossy
)
4458 if (!physDev
) return DIB_Status_None
;
4459 return X11DRV_CoerceDIBSection2( GetCurrentObject( physDev
->hdc
, OBJ_BITMAP
), req
, lossy
);
4462 /***********************************************************************
4463 * X11DRV_LockDIBSection
4465 INT
X11DRV_LockDIBSection(X11DRV_PDEVICE
*physDev
, INT req
, BOOL lossy
)
4467 if (!physDev
) return DIB_Status_None
;
4468 if (GetObjectType( physDev
->hdc
) != OBJ_MEMDC
) return DIB_Status_None
;
4470 return X11DRV_LockDIBSection2( GetCurrentObject( physDev
->hdc
, OBJ_BITMAP
), req
, lossy
);
4473 /***********************************************************************
4474 * X11DRV_UnlockDIBSection
4476 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE
*physDev
, BOOL commit
)
4478 if (!physDev
) return;
4479 if (GetObjectType( physDev
->hdc
) != OBJ_MEMDC
) return;
4481 X11DRV_UnlockDIBSection2( GetCurrentObject( physDev
->hdc
, OBJ_BITMAP
), commit
);
4485 #ifdef HAVE_LIBXXSHM
4486 /***********************************************************************
4487 * X11DRV_XShmErrorHandler
4490 static int XShmErrorHandler( Display
*dpy
, XErrorEvent
*event
, void *arg
)
4492 return 1; /* FIXME: should check event contents */
4495 /***********************************************************************
4496 * X11DRV_XShmCreateImage
4499 static XImage
*X11DRV_XShmCreateImage( int width
, int height
, int bpp
,
4500 XShmSegmentInfo
* shminfo
)
4504 image
= XShmCreateImage(gdi_display
, visual
, bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
4507 shminfo
->shmid
= shmget(IPC_PRIVATE
, image
->bytes_per_line
* height
,
4509 if( shminfo
->shmid
!= -1 )
4511 shminfo
->shmaddr
= image
->data
= shmat(shminfo
->shmid
, 0, 0);
4512 if( shminfo
->shmaddr
!= (char*)-1 )
4516 shminfo
->readOnly
= FALSE
;
4517 X11DRV_expect_error( gdi_display
, XShmErrorHandler
, NULL
);
4518 ok
= (XShmAttach( gdi_display
, shminfo
) != 0);
4519 XSync( gdi_display
, False
);
4520 if (X11DRV_check_error()) ok
= FALSE
;
4523 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
4524 return image
; /* Success! */
4526 /* An error occurred */
4527 shmdt(shminfo
->shmaddr
);
4529 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
4531 XFlush(gdi_display
);
4532 XDestroyImage(image
);
4537 #endif /* HAVE_LIBXXSHM */
4540 /***********************************************************************
4541 * X11DRV_DIB_CreateDIBSection
4543 HBITMAP
X11DRV_DIB_CreateDIBSection(
4544 X11DRV_PDEVICE
*physDev
, const BITMAPINFO
*bmi
, UINT usage
,
4545 VOID
**bits
, HANDLE section
,
4546 DWORD offset
, DWORD ovr_pitch
)
4549 BITMAPOBJ
*bmp
= NULL
;
4550 X11DRV_DIBSECTION
*dib
= NULL
;
4551 int *colorMap
= NULL
;
4554 /* Fill BITMAP32 structure with DIB data */
4555 const BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
4556 INT effHeight
, totalSize
;
4558 LPVOID mapBits
= NULL
;
4560 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
4561 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
4562 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
4564 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
4566 bm
.bmWidth
= bi
->biWidth
;
4567 bm
.bmHeight
= effHeight
;
4568 bm
.bmWidthBytes
= ovr_pitch
? ovr_pitch
: X11DRV_DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
4569 bm
.bmPlanes
= bi
->biPlanes
;
4570 bm
.bmBitsPixel
= bi
->biBitCount
;
4573 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
4574 we're dealing with a compressed bitmap. Otherwise, use width * height. */
4575 if (bi
->biSizeImage
&& (bi
->biCompression
== BI_RLE4
|| bi
->biCompression
== BI_RLE8
))
4576 totalSize
= bi
->biSizeImage
;
4578 totalSize
= bm
.bmWidthBytes
* effHeight
;
4582 SYSTEM_INFO SystemInfo
;
4586 GetSystemInfo( &SystemInfo
);
4587 mapOffset
= offset
- (offset
% SystemInfo
.dwAllocationGranularity
);
4588 mapSize
= totalSize
+ (offset
- mapOffset
);
4589 mapBits
= MapViewOfFile( section
,
4590 FILE_MAP_ALL_ACCESS
,
4594 bm
.bmBits
= (char *)mapBits
+ (offset
- mapOffset
);
4596 else if (ovr_pitch
&& offset
)
4597 bm
.bmBits
= (LPVOID
) offset
;
4600 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
4601 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
4604 /* Create Color Map */
4605 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8)
4606 colorMap
= X11DRV_DIB_BuildColorMap( usage
== DIB_PAL_COLORS
? physDev
: NULL
,
4607 usage
, bm
.bmBitsPixel
, bmi
, &nColorMap
);
4609 /* Allocate Memory for DIB and fill structure */
4611 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
4614 dib
->dibSection
.dsBm
= bm
;
4615 dib
->dibSection
.dsBmih
= *bi
;
4616 dib
->dibSection
.dsBmih
.biSizeImage
= totalSize
;
4618 /* Set dsBitfields values */
4619 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
4621 dib
->dibSection
.dsBitfields
[0] = dib
->dibSection
.dsBitfields
[1] = dib
->dibSection
.dsBitfields
[2] = 0;
4623 else switch( bi
->biBitCount
)
4627 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
4628 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
4629 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f;
4634 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff0000;
4635 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x00ff00;
4636 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x0000ff;
4639 dib
->dibSection
.dshSection
= section
;
4640 dib
->dibSection
.dsOffset
= offset
;
4642 dib
->status
= DIB_Status_None
;
4643 dib
->nColorMap
= nColorMap
;
4644 dib
->colorMap
= colorMap
;
4647 /* Create Device Dependent Bitmap and add DIB pointer */
4650 res
= CreateDIBitmap(physDev
->hdc
, bi
, 0, NULL
, bmi
, usage
);
4653 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
4654 if (bmp
) bmp
->dib
= (DIBSECTION
*) dib
;
4662 #ifdef HAVE_LIBXXSHM
4663 if (XShmQueryExtension(gdi_display
) &&
4664 (dib
->image
= X11DRV_XShmCreateImage( bm
.bmWidth
, effHeight
,
4665 bmp
->bitmap
.bmBitsPixel
, &dib
->shminfo
)) )
4667 ; /* Created Image */
4669 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
4670 dib
->shminfo
.shmid
= -1;
4673 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
4675 wine_tsx11_unlock();
4678 /* Clean up in case of errors */
4679 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
4681 TRACE("got an error res=%p, bmp=%p, dib=%p, bm.bmBits=%p\n",
4682 res
, bmp
, dib
, bm
.bmBits
);
4686 UnmapViewOfFile(mapBits
), bm
.bmBits
= NULL
;
4688 VirtualFree(bm
.bmBits
, 0L, MEM_RELEASE
), bm
.bmBits
= NULL
;
4691 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
4692 if (colorMap
) { HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
; }
4693 if (dib
) { HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
; }
4694 if (bmp
) { GDI_ReleaseObj(res
); bmp
= NULL
; }
4695 if (res
) { DeleteObject(res
); res
= 0; }
4699 extern BOOL
VIRTUAL_SetFaultHandler(LPCVOID addr
, BOOL (*proc
)(LPVOID
, LPCVOID
), LPVOID arg
);
4700 /* Install fault handler, if possible */
4701 InitializeCriticalSection(&(dib
->lock
));
4702 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
4704 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4705 if (dib
) dib
->status
= DIB_Status_AppMod
;
4709 /* Return BITMAP handle and storage location */
4710 if (bmp
) GDI_ReleaseObj(res
);
4711 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
4715 /***********************************************************************
4716 * X11DRV_DIB_DeleteDIBSection
4718 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
4720 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4725 #ifdef HAVE_LIBXXSHM
4726 if (dib
->shminfo
.shmid
!= -1)
4728 XShmDetach (gdi_display
, &(dib
->shminfo
));
4729 XDestroyImage (dib
->image
);
4730 shmdt (dib
->shminfo
.shmaddr
);
4731 dib
->shminfo
.shmid
= -1;
4735 XDestroyImage( dib
->image
);
4736 wine_tsx11_unlock();
4740 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
4742 DeleteCriticalSection(&(dib
->lock
));
4745 /***********************************************************************
4746 * SetDIBColorTable (X11DRV.@)
4748 UINT
X11DRV_SetDIBColorTable( X11DRV_PDEVICE
*physDev
, UINT start
, UINT count
, const RGBQUAD
*colors
)
4751 X11DRV_DIBSECTION
*dib
;
4753 HBITMAP hBitmap
= GetCurrentObject( physDev
->hdc
, OBJ_BITMAP
);
4755 if (!(bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBitmap
, BITMAP_MAGIC
))) return 0;
4756 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4758 if (dib
&& dib
->colorMap
) {
4759 UINT end
= count
+ start
;
4760 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
4762 * Changing color table might change the mapping between
4763 * DIB colors and X11 colors and thus alter the visible state
4764 * of the bitmap object.
4766 X11DRV_DIB_Lock(bmp
, DIB_Status_AppMod
, FALSE
);
4767 X11DRV_DIB_GenColorMap( physDev
, dib
->colorMap
, DIB_RGB_COLORS
,
4768 dib
->dibSection
.dsBm
.bmBitsPixel
,
4769 TRUE
, colors
, start
, end
);
4770 X11DRV_DIB_Unlock(bmp
, TRUE
);
4773 GDI_ReleaseObj( hBitmap
);
4777 /***********************************************************************
4778 * GetDIBColorTable (X11DRV.@)
4780 UINT
X11DRV_GetDIBColorTable( X11DRV_PDEVICE
*physDev
, UINT start
, UINT count
, RGBQUAD
*colors
)
4783 X11DRV_DIBSECTION
*dib
;
4785 HBITMAP hBitmap
= GetCurrentObject( physDev
->hdc
, OBJ_BITMAP
);
4787 if (!(bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBitmap
, BITMAP_MAGIC
))) return 0;
4788 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4790 if (dib
&& dib
->colorMap
) {
4791 UINT i
, end
= count
+ start
;
4792 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
4793 for (i
= start
; i
< end
; i
++,colors
++) {
4794 COLORREF col
= X11DRV_PALETTE_ToLogical( dib
->colorMap
[i
] );
4795 colors
->rgbBlue
= GetBValue(col
);
4796 colors
->rgbGreen
= GetGValue(col
);
4797 colors
->rgbRed
= GetRValue(col
);
4798 colors
->rgbReserved
= 0;
4802 GDI_ReleaseObj( hBitmap
);
4808 /***********************************************************************
4809 * X11DRV_DIB_CreateDIBFromBitmap
4811 * Allocates a packed DIB and copies the bitmap data into it.
4813 HGLOBAL
X11DRV_DIB_CreateDIBFromBitmap(HDC hdc
, HBITMAP hBmp
)
4818 LPBITMAPINFOHEADER pbmiHeader
;
4819 unsigned int cDataSize
, cPackedSize
, OffsetBits
;
4822 if (!GetObjectW( hBmp
, sizeof(bmp
), &bmp
)) return 0;
4825 * A packed DIB contains a BITMAPINFO structure followed immediately by
4826 * an optional color palette and the pixel data.
4829 /* Calculate the size of the packed DIB */
4830 cDataSize
= X11DRV_DIB_GetDIBWidthBytes( bmp
.bmWidth
, bmp
.bmBitsPixel
) * abs( bmp
.bmHeight
);
4831 cPackedSize
= sizeof(BITMAPINFOHEADER
)
4832 + ( (bmp
.bmBitsPixel
<= 8) ? (sizeof(RGBQUAD
) * (1 << bmp
.bmBitsPixel
)) : 0 )
4834 /* Get the offset to the bits */
4835 OffsetBits
= cPackedSize
- cDataSize
;
4837 /* Allocate the packed DIB */
4838 TRACE("\tAllocating packed DIB of size %d\n", cPackedSize
);
4839 hPackedDIB
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_DDESHARE
/*| GMEM_ZEROINIT*/,
4843 WARN("Could not allocate packed DIB!\n");
4847 /* A packed DIB starts with a BITMAPINFOHEADER */
4848 pPackedDIB
= GlobalLock(hPackedDIB
);
4849 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
4851 /* Init the BITMAPINFOHEADER */
4852 pbmiHeader
->biSize
= sizeof(BITMAPINFOHEADER
);
4853 pbmiHeader
->biWidth
= bmp
.bmWidth
;
4854 pbmiHeader
->biHeight
= bmp
.bmHeight
;
4855 pbmiHeader
->biPlanes
= 1;
4856 pbmiHeader
->biBitCount
= bmp
.bmBitsPixel
;
4857 pbmiHeader
->biCompression
= BI_RGB
;
4858 pbmiHeader
->biSizeImage
= 0;
4859 pbmiHeader
->biXPelsPerMeter
= pbmiHeader
->biYPelsPerMeter
= 0;
4860 pbmiHeader
->biClrUsed
= 0;
4861 pbmiHeader
->biClrImportant
= 0;
4863 /* Retrieve the DIB bits from the bitmap and fill in the
4864 * DIB color table if present */
4866 nLinesCopied
= GetDIBits(hdc
, /* Handle to device context */
4867 hBmp
, /* Handle to bitmap */
4868 0, /* First scan line to set in dest bitmap */
4869 bmp
.bmHeight
, /* Number of scan lines to copy */
4870 pPackedDIB
+ OffsetBits
, /* [out] Address of array for bitmap bits */
4871 (LPBITMAPINFO
) pbmiHeader
, /* [out] Address of BITMAPINFO structure */
4872 0); /* RGB or palette index */
4873 GlobalUnlock(hPackedDIB
);
4875 /* Cleanup if GetDIBits failed */
4876 if (nLinesCopied
!= bmp
.bmHeight
)
4878 TRACE("\tGetDIBits returned %d. Actual lines=%d\n", nLinesCopied
, bmp
.bmHeight
);
4879 GlobalFree(hPackedDIB
);
4886 /**************************************************************************
4887 * X11DRV_DIB_CreateDIBFromPixmap
4889 * Allocates a packed DIB and copies the Pixmap data into it.
4890 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
4892 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
, BOOL bDeletePixmap
)
4895 BITMAPOBJ
*pBmp
= NULL
;
4896 HGLOBAL hPackedDIB
= 0;
4898 /* Allocates an HBITMAP which references the Pixmap passed to us */
4899 hBmp
= X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(hdc
, pixmap
);
4902 TRACE("\tCould not create bitmap header for Pixmap\n");
4907 * Create a packed DIB from the Pixmap wrapper bitmap created above.
4908 * A packed DIB contains a BITMAPINFO structure followed immediately by
4909 * an optional color palette and the pixel data.
4911 hPackedDIB
= X11DRV_DIB_CreateDIBFromBitmap(hdc
, hBmp
);
4913 /* Get a pointer to the BITMAPOBJ structure */
4914 pBmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4916 /* We can now get rid of the HBITMAP wrapper we created earlier.
4917 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
4921 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
4922 pBmp
->physBitmap
= NULL
;
4925 GDI_ReleaseObj( hBmp
);
4929 TRACE("\tReturning packed DIB %p\n", hPackedDIB
);
4934 /**************************************************************************
4935 * X11DRV_DIB_CreatePixmapFromDIB
4937 * Creates a Pixmap from a packed DIB
4939 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
4941 Pixmap pixmap
= None
;
4943 BITMAPOBJ
*pBmp
= NULL
;
4944 LPBYTE pPackedDIB
= NULL
;
4945 LPBITMAPINFO pbmi
= NULL
;
4946 LPBITMAPINFOHEADER pbmiHeader
= NULL
;
4947 LPBYTE pbits
= NULL
;
4949 /* Get a pointer to the packed DIB's data */
4950 pPackedDIB
= (LPBYTE
)GlobalLock(hPackedDIB
);
4951 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
4952 pbmi
= (LPBITMAPINFO
)pPackedDIB
;
4953 pbits
= (LPBYTE
)(pPackedDIB
4954 + X11DRV_DIB_BitmapInfoSize( (LPBITMAPINFO
)pbmiHeader
, DIB_RGB_COLORS
));
4956 /* Create a DDB from the DIB */
4958 hBmp
= CreateDIBitmap(hdc
,
4965 GlobalUnlock(hPackedDIB
);
4967 TRACE("CreateDIBitmap returned %p\n", hBmp
);
4969 /* Retrieve the internal Pixmap from the DDB */
4971 pBmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4973 pixmap
= (Pixmap
)pBmp
->physBitmap
;
4974 /* clear the physBitmap so that we can steal its pixmap */
4975 pBmp
->physBitmap
= NULL
;
4978 /* Delete the DDB we created earlier now that we have stolen its pixmap */
4979 GDI_ReleaseObj( hBmp
);
4982 TRACE("\tReturning Pixmap %ld\n", pixmap
);