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"
45 WINE_DEFAULT_DEBUG_CHANNEL(bitmap
);
46 WINE_DECLARE_DEBUG_CHANNEL(x11drv
);
48 static int ximageDepthTable
[32];
50 /* This structure holds the arguments for DIB_SetImageBits() */
53 X11DRV_PDEVICE
*physDev
;
56 PALETTEENTRY
*palentry
;
77 } X11DRV_DIB_IMAGEBITS_DESCR
;
82 RLE_EOL
= 0, /* End of line */
83 RLE_END
= 1, /* End of bitmap */
84 RLE_DELTA
= 2 /* Delta */
87 /***********************************************************************
88 * X11DRV_DIB_GetXImageWidthBytes
90 * Return the width of an X image in bytes
92 inline static int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
94 if (!depth
|| depth
> 32) goto error
;
96 if (!ximageDepthTable
[depth
-1])
98 XImage
*testimage
= XCreateImage( gdi_display
, visual
, depth
,
99 ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
102 ximageDepthTable
[depth
-1] = testimage
->bits_per_pixel
;
103 XDestroyImage( testimage
);
105 else ximageDepthTable
[depth
-1] = -1;
107 if (ximageDepthTable
[depth
-1] != -1)
108 return (4 * ((width
* ximageDepthTable
[depth
-1] + 31) / 32));
111 WARN( "(%d): Unsupported depth\n", depth
);
116 /***********************************************************************
117 * X11DRV_DIB_CreateXImage
121 XImage
*X11DRV_DIB_CreateXImage( int width
, int height
, int depth
)
127 width_bytes
= X11DRV_DIB_GetXImageWidthBytes( width
, depth
);
128 image
= XCreateImage( gdi_display
, visual
, depth
, ZPixmap
, 0,
129 calloc( height
, width_bytes
),
130 width
, height
, 32, width_bytes
);
136 /***********************************************************************
139 * Get the info from a bitmap header.
140 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
142 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER
*header
, DWORD
*width
,
143 int *height
, WORD
*bpp
, WORD
*compr
)
145 if (header
->biSize
== sizeof(BITMAPCOREHEADER
))
147 BITMAPCOREHEADER
*core
= (BITMAPCOREHEADER
*)header
;
148 *width
= core
->bcWidth
;
149 *height
= core
->bcHeight
;
150 *bpp
= core
->bcBitCount
;
154 if (header
->biSize
>= sizeof(BITMAPINFOHEADER
))
156 *width
= header
->biWidth
;
157 *height
= header
->biHeight
;
158 *bpp
= header
->biBitCount
;
159 *compr
= header
->biCompression
;
162 ERR("(%ld): unknown/wrong size for header\n", header
->biSize
);
167 /***********************************************************************
168 * X11DRV_DIB_GenColorMap
170 * Fills the color map of a bitmap palette. Should not be called
171 * for a >8-bit deep bitmap.
173 int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE
*physDev
, int *colorMapping
,
174 WORD coloruse
, WORD depth
, BOOL quads
,
175 const void *colorPtr
, int start
, int end
)
179 if (coloruse
== DIB_RGB_COLORS
)
181 int max
= 1 << depth
;
183 if (end
> max
) end
= max
;
187 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
189 if (depth
== 1) /* Monochrome */
190 for (i
= start
; i
< end
; i
++, rgb
++)
191 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
192 rgb
->rgbBlue
> 255*3/2);
194 for (i
= start
; i
< end
; i
++, rgb
++)
195 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, RGB(rgb
->rgbRed
,
201 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
203 if (depth
== 1) /* Monochrome */
204 for (i
= start
; i
< end
; i
++, rgb
++)
205 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
206 rgb
->rgbtBlue
> 255*3/2);
208 for (i
= start
; i
< end
; i
++, rgb
++)
209 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, RGB(rgb
->rgbtRed
,
214 else /* DIB_PAL_COLORS */
217 WORD
* index
= (WORD
*)colorPtr
;
219 for (i
= start
; i
< end
; i
++, index
++)
220 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, PALETTEINDEX(*index
) );
222 for (i
= start
; i
< end
; i
++)
223 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, PALETTEINDEX(i
) );
230 /***********************************************************************
231 * X11DRV_DIB_BuildColorMap
233 * Build the color map from the bitmap palette. Should not be called
234 * for a >8-bit deep bitmap.
236 int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE
*physDev
, WORD coloruse
, WORD depth
,
237 const BITMAPINFO
*info
, int *nColors
)
241 const void *colorPtr
;
244 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
246 colors
= info
->bmiHeader
.biClrUsed
;
247 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
248 colorPtr
= info
->bmiColors
;
250 else /* assume BITMAPCOREINFO */
252 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
253 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
258 ERR("called with >256 colors!\n");
262 /* just so CopyDIBSection doesn't have to create an identity palette */
263 if (coloruse
== (WORD
)-1) colorPtr
= NULL
;
265 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
266 colors
* sizeof(int) )))
270 return X11DRV_DIB_GenColorMap( physDev
, colorMapping
, coloruse
, depth
,
271 isInfo
, colorPtr
, 0, colors
);
275 /***********************************************************************
276 * X11DRV_DIB_MapColor
278 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
, int oldcol
)
282 if ((oldcol
< nPhysMap
) && (physMap
[oldcol
] == phys
))
285 for (color
= 0; color
< nPhysMap
; color
++)
286 if (physMap
[color
] == phys
)
289 WARN("Strange color %08x\n", phys
);
294 /*********************************************************************
295 * X11DRV_DIB_GetNearestIndex
297 * Helper for X11DRV_DIB_GetDIBits.
298 * Returns the nearest colour table index for a given RGB.
299 * Nearest is defined by minimizing the sum of the squares.
301 static INT
X11DRV_DIB_GetNearestIndex(RGBQUAD
*colormap
, int numColors
, BYTE r
, BYTE g
, BYTE b
)
303 INT i
, best
= -1, diff
, bestdiff
= -1;
306 for(color
= colormap
, i
= 0; i
< numColors
; color
++, i
++) {
307 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
308 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
309 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
312 if(best
== -1 || diff
< bestdiff
) {
319 /*********************************************************************
320 * X11DRV_DIB_MaskToShift
322 * Helper for X11DRV_DIB_GetDIBits.
323 * Returns the by how many bits to shift a given color so that it is
324 * in the proper position.
326 INT
X11DRV_DIB_MaskToShift(DWORD mask
)
334 while ((mask
&1)==0) {
341 /***********************************************************************
342 * X11DRV_DIB_SetImageBits_1
344 * SetDIBits for a 1-bit deep DIB.
346 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
347 DWORD srcwidth
, DWORD dstwidth
, int left
,
348 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
357 srcbits
= srcbits
+ linebytes
* (lines
- 1);
358 linebytes
= -linebytes
;
361 if ((extra
= (left
& 7)) != 0) {
365 srcbits
+= left
>> 3;
367 /* ==== pal 1 dib -> any bmp format ==== */
368 for (h
= lines
-1; h
>=0; h
--) {
370 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
371 for (i
= dstwidth
/8, x
= left
; i
> 0; i
--) {
373 XPutPixel( bmpImage
, x
++, h
, colors
[ srcval
>> 7] );
374 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 6) & 1] );
375 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 5) & 1] );
376 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 4) & 1] );
377 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 3) & 1] );
378 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 2) & 1] );
379 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 1) & 1] );
380 XPutPixel( bmpImage
, x
++, h
, colors
[ srcval
& 1] );
384 switch (dstwidth
& 7)
386 case 7: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
387 case 6: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
388 case 5: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
389 case 4: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
390 case 3: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
391 case 2: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
392 case 1: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]);
395 srcbits
+= linebytes
;
399 /***********************************************************************
400 * X11DRV_DIB_GetImageBits_1
402 * GetDIBits for a 1-bit deep DIB.
404 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
405 DWORD dstwidth
, DWORD srcwidth
,
406 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
407 XImage
*bmpImage
, DWORD linebytes
)
414 dstbits
= dstbits
+ linebytes
* (lines
- 1);
415 linebytes
= -linebytes
;
418 switch (bmpImage
->depth
)
422 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
423 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
426 for (h
=lines
-1; h
>=0; h
--) {
430 for (x
=0; x
<dstwidth
; x
++) {
432 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
433 dstval
|=(X11DRV_DIB_GetNearestIndex
437 srcval
.peBlue
) << (7 - (x
& 7)));
443 if ((dstwidth
&7)!=0) {
446 dstbits
+= linebytes
;
454 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
455 /* ==== pal 8 bmp -> pal 1 dib ==== */
457 const BYTE
* srcpixel
;
460 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
462 for (h
=0; h
<lines
; h
++) {
467 for (x
=0; x
<dstwidth
; x
++) {
469 srcval
=srccolors
[(int)*srcpixel
++];
470 dstval
|=(X11DRV_DIB_GetNearestIndex
474 srcval
.peBlue
) << (7-(x
&7)) );
480 if ((dstwidth
&7)!=0) {
483 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
484 dstbits
+= linebytes
;
495 const WORD
* srcpixel
;
498 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
500 if (bmpImage
->green_mask
==0x03e0) {
501 if (bmpImage
->red_mask
==0x7c00) {
502 /* ==== rgb 555 bmp -> pal 1 dib ==== */
503 for (h
=0; h
<lines
; h
++) {
508 for (x
=0; x
<dstwidth
; x
++) {
511 dstval
|=(X11DRV_DIB_GetNearestIndex
513 ((srcval
>> 7) & 0xf8) | /* r */
514 ((srcval
>> 12) & 0x07),
515 ((srcval
>> 2) & 0xf8) | /* g */
516 ((srcval
>> 7) & 0x07),
517 ((srcval
<< 3) & 0xf8) | /* b */
518 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
524 if ((dstwidth
&7)!=0) {
527 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
528 dstbits
+= linebytes
;
530 } else if (bmpImage
->blue_mask
==0x7c00) {
531 /* ==== bgr 555 bmp -> pal 1 dib ==== */
532 for (h
=0; h
<lines
; h
++) {
537 for (x
=0; x
<dstwidth
; x
++) {
540 dstval
|=(X11DRV_DIB_GetNearestIndex
542 ((srcval
<< 3) & 0xf8) | /* r */
543 ((srcval
>> 2) & 0x07),
544 ((srcval
>> 2) & 0xf8) | /* g */
545 ((srcval
>> 7) & 0x07),
546 ((srcval
>> 7) & 0xf8) | /* b */
547 ((srcval
>> 12) & 0x07) ) << (7-(x
&7)) );
553 if ((dstwidth
&7)!=0) {
556 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
557 dstbits
+= linebytes
;
562 } else if (bmpImage
->green_mask
==0x07e0) {
563 if (bmpImage
->red_mask
==0xf800) {
564 /* ==== rgb 565 bmp -> pal 1 dib ==== */
565 for (h
=0; h
<lines
; h
++) {
570 for (x
=0; x
<dstwidth
; x
++) {
573 dstval
|=(X11DRV_DIB_GetNearestIndex
575 ((srcval
>> 8) & 0xf8) | /* r */
576 ((srcval
>> 13) & 0x07),
577 ((srcval
>> 3) & 0xfc) | /* g */
578 ((srcval
>> 9) & 0x03),
579 ((srcval
<< 3) & 0xf8) | /* b */
580 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
586 if ((dstwidth
&7)!=0) {
589 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
590 dstbits
+= linebytes
;
592 } else if (bmpImage
->blue_mask
==0xf800) {
593 /* ==== bgr 565 bmp -> pal 1 dib ==== */
594 for (h
=0; h
<lines
; h
++) {
599 for (x
=0; x
<dstwidth
; x
++) {
602 dstval
|=(X11DRV_DIB_GetNearestIndex
604 ((srcval
<< 3) & 0xf8) | /* r */
605 ((srcval
>> 2) & 0x07),
606 ((srcval
>> 3) & 0xfc) | /* g */
607 ((srcval
>> 9) & 0x03),
608 ((srcval
>> 8) & 0xf8) | /* b */
609 ((srcval
>> 13) & 0x07) ) << (7-(x
&7)) );
615 if ((dstwidth
&7)!=0) {
618 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
619 dstbits
+= linebytes
;
638 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
639 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
641 if (bmpImage
->green_mask
!=0x00ff00 ||
642 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
644 } else if (bmpImage
->blue_mask
==0xff) {
645 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
646 for (h
=0; h
<lines
; h
++) {
651 for (x
=0; x
<dstwidth
; x
++) {
652 dstval
|=(X11DRV_DIB_GetNearestIndex
656 srcbyte
[0]) << (7-(x
&7)) );
657 srcbyte
+=bytes_per_pixel
;
663 if ((dstwidth
&7)!=0) {
666 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
667 dstbits
+= linebytes
;
670 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
671 for (h
=0; h
<lines
; h
++) {
676 for (x
=0; x
<dstwidth
; x
++) {
677 dstval
|=(X11DRV_DIB_GetNearestIndex
681 srcbyte
[2]) << (7-(x
&7)) );
682 srcbyte
+=bytes_per_pixel
;
688 if ((dstwidth
&7)!=0) {
691 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
692 dstbits
+= linebytes
;
702 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
704 /* ==== any bmp format -> pal 1 dib ==== */
705 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
706 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
707 bmpImage
->green_mask
, bmpImage
->blue_mask
);
709 for (h
=lines
-1; h
>=0; h
--) {
713 for (x
=0; x
<dstwidth
; x
++) {
714 dstval
|=(XGetPixel( bmpImage
, x
, h
) >= white
) << (7 - (x
&7));
720 if ((dstwidth
&7)!=0) {
723 dstbits
+= linebytes
;
730 /***********************************************************************
731 * X11DRV_DIB_SetImageBits_4
733 * SetDIBits for a 4-bit deep DIB.
735 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
736 DWORD srcwidth
, DWORD dstwidth
, int left
,
737 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
745 srcbits
= srcbits
+ linebytes
* (lines
- 1);
746 linebytes
= -linebytes
;
753 srcbits
+= left
>> 1;
755 /* ==== pal 4 dib -> any bmp format ==== */
756 for (h
= lines
-1; h
>= 0; h
--) {
758 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
759 BYTE srcval
=*srcbyte
++;
760 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
>> 4] );
761 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
& 0x0f] );
764 XPutPixel( bmpImage
, x
, h
, colors
[*srcbyte
>> 4] );
765 srcbits
+= linebytes
;
771 /***********************************************************************
772 * X11DRV_DIB_GetImageBits_4
774 * GetDIBits for a 4-bit deep DIB.
776 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
777 DWORD srcwidth
, DWORD dstwidth
,
778 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
779 XImage
*bmpImage
, DWORD linebytes
)
788 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
789 linebytes
= -linebytes
;
794 switch (bmpImage
->depth
) {
797 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
798 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
801 for (h
= lines
-1; h
>= 0; h
--) {
805 for (x
= 0; x
< dstwidth
; x
++) {
807 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
808 dstval
|=(X11DRV_DIB_GetNearestIndex
812 srcval
.peBlue
) << (4-((x
&1)<<2)));
818 if ((dstwidth
&1)!=0) {
821 dstbits
+= linebytes
;
829 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
830 /* ==== pal 8 bmp -> pal 4 dib ==== */
832 const BYTE
*srcpixel
;
835 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
836 for (h
=0; h
<lines
; h
++) {
841 for (x
=0; x
<dstwidth
; x
++) {
843 srcval
= srccolors
[(int)*srcpixel
++];
844 dstval
|=(X11DRV_DIB_GetNearestIndex
848 srcval
.peBlue
) << (4*(1-(x
&1))) );
854 if ((dstwidth
&1)!=0) {
857 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
858 dstbits
+= linebytes
;
869 const WORD
* srcpixel
;
872 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
874 if (bmpImage
->green_mask
==0x03e0) {
875 if (bmpImage
->red_mask
==0x7c00) {
876 /* ==== rgb 555 bmp -> pal 4 dib ==== */
877 for (h
=0; h
<lines
; h
++) {
882 for (x
=0; x
<dstwidth
; x
++) {
885 dstval
|=(X11DRV_DIB_GetNearestIndex
887 ((srcval
>> 7) & 0xf8) | /* r */
888 ((srcval
>> 12) & 0x07),
889 ((srcval
>> 2) & 0xf8) | /* g */
890 ((srcval
>> 7) & 0x07),
891 ((srcval
<< 3) & 0xf8) | /* b */
892 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
898 if ((dstwidth
&1)!=0) {
901 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
902 dstbits
+= linebytes
;
904 } else if (bmpImage
->blue_mask
==0x7c00) {
905 /* ==== bgr 555 bmp -> pal 4 dib ==== */
906 for (h
=0; h
<lines
; h
++) {
911 for (x
=0; x
<dstwidth
; x
++) {
914 dstval
|=(X11DRV_DIB_GetNearestIndex
916 ((srcval
<< 3) & 0xf8) | /* r */
917 ((srcval
>> 2) & 0x07),
918 ((srcval
>> 2) & 0xf8) | /* g */
919 ((srcval
>> 7) & 0x07),
920 ((srcval
>> 7) & 0xf8) | /* b */
921 ((srcval
>> 12) & 0x07) ) << ((1-(x
&1))<<2) );
927 if ((dstwidth
&1)!=0) {
930 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
931 dstbits
+= linebytes
;
936 } else if (bmpImage
->green_mask
==0x07e0) {
937 if (bmpImage
->red_mask
==0xf800) {
938 /* ==== rgb 565 bmp -> pal 4 dib ==== */
939 for (h
=0; h
<lines
; h
++) {
944 for (x
=0; x
<dstwidth
; x
++) {
947 dstval
|=(X11DRV_DIB_GetNearestIndex
949 ((srcval
>> 8) & 0xf8) | /* r */
950 ((srcval
>> 13) & 0x07),
951 ((srcval
>> 3) & 0xfc) | /* g */
952 ((srcval
>> 9) & 0x03),
953 ((srcval
<< 3) & 0xf8) | /* b */
954 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
960 if ((dstwidth
&1)!=0) {
963 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
964 dstbits
+= linebytes
;
966 } else if (bmpImage
->blue_mask
==0xf800) {
967 /* ==== bgr 565 bmp -> pal 4 dib ==== */
968 for (h
=0; h
<lines
; h
++) {
973 for (x
=0; x
<dstwidth
; x
++) {
976 dstval
|=(X11DRV_DIB_GetNearestIndex
978 ((srcval
<< 3) & 0xf8) | /* r */
979 ((srcval
>> 2) & 0x07),
980 ((srcval
>> 3) & 0xfc) | /* g */
981 ((srcval
>> 9) & 0x03),
982 ((srcval
>> 8) & 0xf8) | /* b */
983 ((srcval
>> 13) & 0x07) ) << ((1-(x
&1))<<2) );
989 if ((dstwidth
&1)!=0) {
992 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
993 dstbits
+= linebytes
;
1005 if (bmpImage
->bits_per_pixel
==24) {
1006 const void* srcbits
;
1007 const BYTE
*srcbyte
;
1010 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1012 if (bmpImage
->green_mask
!=0x00ff00 ||
1013 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1015 } else if (bmpImage
->blue_mask
==0xff) {
1016 /* ==== rgb 888 bmp -> pal 4 dib ==== */
1017 for (h
=0; h
<lines
; h
++) {
1020 for (x
=0; x
<dstwidth
/2; x
++) {
1021 /* Do 2 pixels at a time */
1022 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1027 X11DRV_DIB_GetNearestIndex
1035 /* And the the odd pixel */
1036 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1042 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1043 dstbits
+= linebytes
;
1046 /* ==== bgr 888 bmp -> pal 4 dib ==== */
1047 for (h
=0; h
<lines
; h
++) {
1050 for (x
=0; x
<dstwidth
/2; x
++) {
1051 /* Do 2 pixels at a time */
1052 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1057 X11DRV_DIB_GetNearestIndex
1065 /* And the the odd pixel */
1066 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1072 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1073 dstbits
+= linebytes
;
1082 const void* srcbits
;
1083 const BYTE
*srcbyte
;
1086 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1088 if (bmpImage
->green_mask
!=0x00ff00 ||
1089 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1091 } else if (bmpImage
->blue_mask
==0xff) {
1092 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
1093 for (h
=0; h
<lines
; h
++) {
1096 for (x
=0; x
<dstwidth
/2; x
++) {
1097 /* Do 2 pixels at a time */
1098 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1103 X11DRV_DIB_GetNearestIndex
1111 /* And the the odd pixel */
1112 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1118 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1119 dstbits
+= linebytes
;
1122 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
1123 for (h
=0; h
<lines
; h
++) {
1126 for (x
=0; x
<dstwidth
/2; x
++) {
1127 /* Do 2 pixels at a time */
1128 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1133 X11DRV_DIB_GetNearestIndex
1141 /* And the the odd pixel */
1142 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1148 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1149 dstbits
+= linebytes
;
1160 /* ==== any bmp format -> pal 4 dib ==== */
1161 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
1162 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
1163 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1164 for (h
=lines
-1; h
>=0; h
--) {
1166 for (x
=0; x
<(dstwidth
& ~1); x
+=2) {
1167 *dstbyte
++=(X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4) |
1168 X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
+1, h
), 0);
1171 *dstbyte
=(X11DRV_DIB_MapColor((int *)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4);
1173 dstbits
+= linebytes
;
1180 /***********************************************************************
1181 * X11DRV_DIB_SetImageBits_RLE4
1183 * SetDIBits for a 4-bit deep compressed DIB.
1185 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
1186 DWORD width
, DWORD dstwidth
,
1187 int left
, int *colors
,
1190 int x
= 0, y
= lines
- 1, c
, length
;
1191 const BYTE
*begin
= bits
;
1196 if (length
) { /* encoded */
1199 if (x
>= width
) break;
1200 XPutPixel(bmpImage
, x
++, y
, colors
[c
>> 4]);
1201 if (!length
--) break;
1202 if (x
>= width
) break;
1203 XPutPixel(bmpImage
, x
++, y
, colors
[c
& 0xf]);
1222 default: /* absolute */
1225 if (x
< width
) XPutPixel(bmpImage
, x
++, y
, colors
[c
>> 4]);
1226 if (!length
--) break;
1227 if (x
< width
) XPutPixel(bmpImage
, x
++, y
, colors
[c
& 0xf]);
1229 if ((bits
- begin
) & 1)
1238 /***********************************************************************
1239 * X11DRV_DIB_SetImageBits_8
1241 * SetDIBits for an 8-bit deep DIB.
1243 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
1244 DWORD srcwidth
, DWORD dstwidth
, int left
,
1245 const int *colors
, XImage
*bmpImage
,
1250 const BYTE
* srcbyte
;
1256 srcbits
= srcbits
+ linebytes
* (lines
-1);
1257 linebytes
= -linebytes
;
1262 switch (bmpImage
->depth
) {
1265 #if defined(__i386__) && defined(__GNUC__)
1266 /* Some X servers might have 32 bit/ 16bit deep pixel */
1267 if (lines
&& dstwidth
&& (bmpImage
->bits_per_pixel
== 16) &&
1268 (ImageByteOrder(gdi_display
)==LSBFirst
) )
1270 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
1271 /* FIXME: Does this really handle all these cases correctly? */
1272 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
1273 for (h
= lines
; h
--; ) {
1274 int _cl1
,_cl2
; /* temp outputs for asm below */
1275 /* Borrowed from DirectDraw */
1276 __asm__
__volatile__(
1281 " movw (%%edx,%%eax,4),%%ax\n"
1283 " xor %%eax,%%eax\n"
1285 :"=S" (srcbyte
), "=D" (_cl1
), "=c" (_cl2
)
1290 :"eax", "cc", "memory"
1292 srcbyte
= (srcbits
+= linebytes
);
1293 dstbits
-= bmpImage
->bytes_per_line
;
1301 #if defined(__i386__) && defined(__GNUC__)
1302 if (lines
&& dstwidth
&& (bmpImage
->bits_per_pixel
== 32) &&
1303 (ImageByteOrder(gdi_display
)==LSBFirst
) )
1305 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
1306 /* FIXME: Does this really handle both cases correctly? */
1307 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
1308 for (h
= lines
; h
--; ) {
1309 int _cl1
,_cl2
; /* temp outputs for asm below */
1310 /* Borrowed from DirectDraw */
1311 __asm__
__volatile__(
1316 " movl (%%edx,%%eax,4),%%eax\n"
1318 " xor %%eax,%%eax\n"
1320 :"=S" (srcbyte
), "=D" (_cl1
), "=c" (_cl2
)
1325 :"eax", "cc", "memory"
1327 srcbyte
= (srcbits
+= linebytes
);
1328 dstbits
-= bmpImage
->bytes_per_line
;
1335 break; /* use slow generic case below */
1338 /* ==== pal 8 dib -> any bmp format ==== */
1339 for (h
=lines
-1; h
>=0; h
--) {
1340 for (x
=left
; x
<dstwidth
+left
; x
++) {
1341 XPutPixel(bmpImage
, x
, h
, colors
[*srcbyte
++]);
1343 srcbyte
= (srcbits
+= linebytes
);
1347 /***********************************************************************
1348 * X11DRV_DIB_GetImageBits_8
1350 * GetDIBits for an 8-bit deep DIB.
1352 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
1353 DWORD srcwidth
, DWORD dstwidth
,
1354 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
1355 XImage
*bmpImage
, DWORD linebytes
)
1364 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
1365 linebytes
= -linebytes
;
1370 * This condition is true when GetImageBits has been called by
1371 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
1372 * 256 colormaps, so we'll just use for for GetDIBits calls.
1373 * (In somes cases, in a updateDIBSection, the returned colors are bad too)
1375 if (!srccolors
) goto updatesection
;
1377 switch (bmpImage
->depth
) {
1380 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
1382 /* ==== pal 1 bmp -> pal 8 dib ==== */
1383 /* ==== pal 4 bmp -> pal 8 dib ==== */
1384 for (h
=lines
-1; h
>=0; h
--) {
1386 for (x
=0; x
<dstwidth
; x
++) {
1387 PALETTEENTRY srcval
;
1388 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
1389 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
1394 dstbits
+= linebytes
;
1402 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
1403 /* ==== pal 8 bmp -> pal 8 dib ==== */
1404 const void* srcbits
;
1405 const BYTE
* srcpixel
;
1407 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1408 for (h
=0; h
<lines
; h
++) {
1411 for (x
= 0; x
< dstwidth
; x
++) {
1412 PALETTEENTRY srcval
;
1413 srcval
=srccolors
[(int)*srcpixel
++];
1414 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
1419 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1420 dstbits
+= linebytes
;
1430 const void* srcbits
;
1431 const WORD
* srcpixel
;
1434 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1436 if (bmpImage
->green_mask
==0x03e0) {
1437 if (bmpImage
->red_mask
==0x7c00) {
1438 /* ==== rgb 555 bmp -> pal 8 dib ==== */
1439 for (h
=0; h
<lines
; h
++) {
1442 for (x
=0; x
<dstwidth
; x
++) {
1445 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1447 ((srcval
>> 7) & 0xf8) | /* r */
1448 ((srcval
>> 12) & 0x07),
1449 ((srcval
>> 2) & 0xf8) | /* g */
1450 ((srcval
>> 7) & 0x07),
1451 ((srcval
<< 3) & 0xf8) | /* b */
1452 ((srcval
>> 2) & 0x07) );
1454 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1455 dstbits
+= linebytes
;
1457 } else if (bmpImage
->blue_mask
==0x7c00) {
1458 /* ==== bgr 555 bmp -> pal 8 dib ==== */
1459 for (h
=0; h
<lines
; h
++) {
1462 for (x
=0; x
<dstwidth
; x
++) {
1465 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1467 ((srcval
<< 3) & 0xf8) | /* r */
1468 ((srcval
>> 2) & 0x07),
1469 ((srcval
>> 2) & 0xf8) | /* g */
1470 ((srcval
>> 7) & 0x07),
1471 ((srcval
>> 7) & 0xf8) | /* b */
1472 ((srcval
>> 12) & 0x07) );
1474 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1475 dstbits
+= linebytes
;
1480 } else if (bmpImage
->green_mask
==0x07e0) {
1481 if (bmpImage
->red_mask
==0xf800) {
1482 /* ==== rgb 565 bmp -> pal 8 dib ==== */
1483 for (h
=0; h
<lines
; h
++) {
1486 for (x
=0; x
<dstwidth
; x
++) {
1489 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1491 ((srcval
>> 8) & 0xf8) | /* r */
1492 ((srcval
>> 13) & 0x07),
1493 ((srcval
>> 3) & 0xfc) | /* g */
1494 ((srcval
>> 9) & 0x03),
1495 ((srcval
<< 3) & 0xf8) | /* b */
1496 ((srcval
>> 2) & 0x07) );
1498 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1499 dstbits
+= linebytes
;
1501 } else if (bmpImage
->blue_mask
==0xf800) {
1502 /* ==== bgr 565 bmp -> pal 8 dib ==== */
1503 for (h
=0; h
<lines
; h
++) {
1506 for (x
=0; x
<dstwidth
; x
++) {
1509 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1511 ((srcval
<< 3) & 0xf8) | /* r */
1512 ((srcval
>> 2) & 0x07),
1513 ((srcval
>> 3) & 0xfc) | /* g */
1514 ((srcval
>> 9) & 0x03),
1515 ((srcval
>> 8) & 0xf8) | /* b */
1516 ((srcval
>> 13) & 0x07) );
1518 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1519 dstbits
+= linebytes
;
1533 const void* srcbits
;
1534 const BYTE
*srcbyte
;
1536 int bytes_per_pixel
;
1538 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1539 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
1541 if (bmpImage
->green_mask
!=0x00ff00 ||
1542 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1544 } else if (bmpImage
->blue_mask
==0xff) {
1545 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
1546 for (h
=0; h
<lines
; h
++) {
1549 for (x
=0; x
<dstwidth
; x
++) {
1550 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1555 srcbyte
+=bytes_per_pixel
;
1557 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1558 dstbits
+= linebytes
;
1561 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
1562 for (h
=0; h
<lines
; h
++) {
1565 for (x
=0; x
<dstwidth
; x
++) {
1566 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1571 srcbyte
+=bytes_per_pixel
;
1573 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1574 dstbits
+= linebytes
;
1582 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
1583 bmpImage
->depth
, bmpImage
->red_mask
,
1584 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1586 /* ==== any bmp format -> pal 8 dib ==== */
1587 for (h
=lines
-1; h
>=0; h
--) {
1589 for (x
=0; x
<dstwidth
; x
++) {
1590 *dstbyte
=X11DRV_DIB_MapColor
1592 XGetPixel(bmpImage
, x
, h
), *dstbyte
);
1595 dstbits
+= linebytes
;
1601 /***********************************************************************
1602 * X11DRV_DIB_SetImageBits_RLE8
1604 * SetDIBits for an 8-bit deep compressed DIB.
1606 * This function rewritten 941113 by James Youngman. WINE blew out when I
1607 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1609 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1610 * 'End of bitmap' escape code. This code is very much laxer in what it
1611 * allows to end the expansion. Possibly too lax. See the note by
1612 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1613 * bitmap should end with RleEnd, but on the other hand, software exists
1614 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1617 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1618 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1621 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
1622 DWORD width
, DWORD dstwidth
,
1623 int left
, int *colors
,
1626 int x
; /* X-positon on each line. Increases. */
1627 int y
; /* Line #. Starts at lines-1, decreases */
1628 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
1629 BYTE length
; /* The length pf a run */
1630 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
1633 * Note that the bitmap data is stored by Windows starting at the
1634 * bottom line of the bitmap and going upwards. Within each line,
1635 * the data is stored left-to-right. That's the reason why line
1636 * goes from lines-1 to 0. [JAY]
1646 * If the length byte is not zero (which is the escape value),
1647 * We have a run of length pixels all the same colour. The colour
1648 * index is stored next.
1650 * If the length byte is zero, we need to read the next byte to
1651 * know what to do. [JAY]
1656 * [Run-Length] Encoded mode
1658 int color
= colors
[*pIn
++];
1659 while (length
-- && x
< dstwidth
) XPutPixel(bmpImage
, x
++, y
, color
);
1664 * Escape codes (may be an absolute sequence though)
1666 escape_code
= (*pIn
++);
1675 /* Not all RLE8 bitmaps end with this code. For
1676 * example, Paint Shop Pro produces some that don't.
1677 * That's (I think) what caused the previous
1678 * implementation to fail. [JAY]
1687 default: /* switch to absolute mode */
1688 length
= escape_code
;
1691 int color
= colors
[*pIn
++];
1697 XPutPixel(bmpImage
, x
++, y
, color
);
1700 * If you think for a moment you'll realise that the
1701 * only time we could ever possibly read an odd
1702 * number of bytes is when there is a 0x00 (escape),
1703 * a value >0x02 (absolute mode) and then an odd-
1704 * length run. Therefore this is the only place we
1705 * need to worry about it. Everywhere else the
1706 * bytes are always read in pairs. [JAY]
1708 if (escape_code
& 1) pIn
++; /* Throw away the pad byte. */
1710 } /* switch (escape_code) : Escape sequence */
1716 /***********************************************************************
1717 * X11DRV_DIB_SetImageBits_16
1719 * SetDIBits for a 16-bit deep DIB.
1721 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
1722 DWORD srcwidth
, DWORD dstwidth
, int left
,
1723 X11DRV_PDEVICE
*physDev
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
1724 XImage
*bmpImage
, DWORD linebytes
)
1728 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
1733 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
1734 linebytes
= -linebytes
;
1737 switch (bmpImage
->depth
)
1744 srcbits
=srcbits
+left
*2;
1745 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
1747 if (bmpImage
->green_mask
==0x03e0) {
1748 if (gSrc
==bmpImage
->green_mask
) {
1749 if (rSrc
==bmpImage
->red_mask
) {
1750 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
1751 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
1752 convs
->Convert_5x5_asis
1755 dstbits
,-bmpImage
->bytes_per_line
);
1756 } else if (rSrc
==bmpImage
->blue_mask
) {
1757 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
1758 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
1759 convs
->Convert_555_reverse
1762 dstbits
,-bmpImage
->bytes_per_line
);
1765 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
1766 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
1767 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
1768 convs
->Convert_565_to_555_asis
1771 dstbits
,-bmpImage
->bytes_per_line
);
1773 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
1774 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
1775 convs
->Convert_565_to_555_reverse
1778 dstbits
,-bmpImage
->bytes_per_line
);
1781 } else if (bmpImage
->green_mask
==0x07e0) {
1782 if (gSrc
==bmpImage
->green_mask
) {
1783 if (rSrc
==bmpImage
->red_mask
) {
1784 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
1785 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
1786 convs
->Convert_5x5_asis
1789 dstbits
,-bmpImage
->bytes_per_line
);
1791 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
1792 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
1793 convs
->Convert_565_reverse
1796 dstbits
,-bmpImage
->bytes_per_line
);
1799 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
1800 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
1801 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
1802 convs
->Convert_555_to_565_asis
1805 dstbits
,-bmpImage
->bytes_per_line
);
1807 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
1808 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
1809 convs
->Convert_555_to_565_reverse
1812 dstbits
,-bmpImage
->bytes_per_line
);
1822 if (bmpImage
->bits_per_pixel
==24) {
1825 srcbits
=srcbits
+left
*2;
1826 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
1828 if (bmpImage
->green_mask
!=0x00ff00 ||
1829 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1831 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
1832 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
1834 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
1835 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
1836 convs
->Convert_555_to_888_asis
1839 dstbits
,-bmpImage
->bytes_per_line
);
1841 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
1842 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
1843 convs
->Convert_565_to_888_asis
1846 dstbits
,-bmpImage
->bytes_per_line
);
1850 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
1851 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
1852 convs
->Convert_555_to_888_reverse
1855 dstbits
,-bmpImage
->bytes_per_line
);
1857 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
1858 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
1859 convs
->Convert_565_to_888_reverse
1862 dstbits
,-bmpImage
->bytes_per_line
);
1873 srcbits
=srcbits
+left
*2;
1874 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
1876 if (bmpImage
->green_mask
!=0x00ff00 ||
1877 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1879 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
1880 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
1882 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
1883 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
1884 convs
->Convert_555_to_0888_asis
1887 dstbits
,-bmpImage
->bytes_per_line
);
1889 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
1890 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
1891 convs
->Convert_565_to_0888_asis
1894 dstbits
,-bmpImage
->bytes_per_line
);
1898 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
1899 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
1900 convs
->Convert_555_to_0888_reverse
1903 dstbits
,-bmpImage
->bytes_per_line
);
1905 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
1906 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
1907 convs
->Convert_565_to_0888_reverse
1910 dstbits
,-bmpImage
->bytes_per_line
);
1918 WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
1919 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
1920 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1926 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
1927 const WORD
* srcpixel
;
1928 int rShift1
,gShift1
,bShift1
;
1929 int rShift2
,gShift2
,bShift2
;
1932 /* Set color scaling values */
1933 rShift1
=16+X11DRV_DIB_MaskToShift(rSrc
)-3;
1934 gShift1
=16+X11DRV_DIB_MaskToShift(gSrc
)-3;
1935 bShift1
=16+X11DRV_DIB_MaskToShift(bSrc
)-3;
1940 /* Green has 5 bits, like the others */
1944 /* Green has 6 bits, not 5. Compensate. */
1953 /* We could split it into four separate cases to optimize
1954 * but it is probably not worth it.
1956 for (h
=lines
-1; h
>=0; h
--) {
1957 srcpixel
=(const WORD
*)srcbits
;
1958 for (x
=left
; x
<dstwidth
+left
; x
++) {
1960 BYTE red
,green
,blue
;
1961 srcval
=*srcpixel
++ << 16;
1962 red
= ((srcval
>> rShift1
) & 0xf8) |
1963 ((srcval
>> rShift2
) & 0x07);
1964 green
=((srcval
>> gShift1
) & gMask1
) |
1965 ((srcval
>> gShift2
) & gMask2
);
1966 blue
= ((srcval
>> bShift1
) & 0xf8) |
1967 ((srcval
>> bShift2
) & 0x07);
1968 XPutPixel(bmpImage
, x
, h
,
1969 X11DRV_PALETTE_ToPhysical
1970 (physDev
, RGB(red
,green
,blue
)));
1972 srcbits
+= linebytes
;
1980 /***********************************************************************
1981 * X11DRV_DIB_GetImageBits_16
1983 * GetDIBits for an 16-bit deep DIB.
1985 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*dstbits
,
1986 DWORD dstwidth
, DWORD srcwidth
,
1987 PALETTEENTRY
*srccolors
,
1988 DWORD rDst
, DWORD gDst
, DWORD bDst
,
1989 XImage
*bmpImage
, DWORD dibpitch
)
1993 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
1995 DWORD linebytes
= dibpitch
;
2000 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
2001 linebytes
= -linebytes
;
2004 switch (bmpImage
->depth
)
2009 const char* srcbits
;
2011 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2013 if (bmpImage
->green_mask
==0x03e0) {
2014 if (gDst
==bmpImage
->green_mask
) {
2015 if (rDst
==bmpImage
->red_mask
) {
2016 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
2017 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
2018 convs
->Convert_5x5_asis
2020 srcbits
,-bmpImage
->bytes_per_line
,
2023 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
2024 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
2025 convs
->Convert_555_reverse
2027 srcbits
,-bmpImage
->bytes_per_line
,
2031 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
2032 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
2033 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
2034 convs
->Convert_555_to_565_asis
2036 srcbits
,-bmpImage
->bytes_per_line
,
2039 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
2040 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
2041 convs
->Convert_555_to_565_reverse
2043 srcbits
,-bmpImage
->bytes_per_line
,
2047 } else if (bmpImage
->green_mask
==0x07e0) {
2048 if (gDst
==bmpImage
->green_mask
) {
2049 if (rDst
== bmpImage
->red_mask
) {
2050 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
2051 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
2052 convs
->Convert_5x5_asis
2054 srcbits
,-bmpImage
->bytes_per_line
,
2057 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
2058 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
2059 convs
->Convert_565_reverse
2061 srcbits
,-bmpImage
->bytes_per_line
,
2065 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
2066 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
2067 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
2068 convs
->Convert_565_to_555_asis
2070 srcbits
,-bmpImage
->bytes_per_line
,
2073 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
2074 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
2075 convs
->Convert_565_to_555_reverse
2077 srcbits
,-bmpImage
->bytes_per_line
,
2088 if (bmpImage
->bits_per_pixel
== 24) {
2089 const char* srcbits
;
2091 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2093 if (bmpImage
->green_mask
!=0x00ff00 ||
2094 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2096 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
2097 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
2099 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
2100 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
2101 convs
->Convert_888_to_555_asis
2103 srcbits
,-bmpImage
->bytes_per_line
,
2106 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2107 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2108 convs
->Convert_888_to_565_asis
2110 srcbits
,-bmpImage
->bytes_per_line
,
2115 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
2116 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
2117 convs
->Convert_888_to_555_reverse
2119 srcbits
,-bmpImage
->bytes_per_line
,
2122 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
2123 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
2124 convs
->Convert_888_to_565_reverse
2126 srcbits
,-bmpImage
->bytes_per_line
,
2136 const char* srcbits
;
2138 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2140 if (bmpImage
->green_mask
!=0x00ff00 ||
2141 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2143 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
2144 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
2146 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
2147 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
2148 convs
->Convert_0888_to_555_asis
2150 srcbits
,-bmpImage
->bytes_per_line
,
2153 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
2154 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
2155 convs
->Convert_0888_to_565_asis
2157 srcbits
,-bmpImage
->bytes_per_line
,
2162 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
2163 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
2164 convs
->Convert_0888_to_555_reverse
2166 srcbits
,-bmpImage
->bytes_per_line
,
2169 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
2170 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
2171 convs
->Convert_0888_to_565_reverse
2173 srcbits
,-bmpImage
->bytes_per_line
,
2182 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2183 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
2184 int rShift
,gShift
,bShift
;
2187 /* Shift everything 16 bits left so that all shifts are >0,
2188 * even for BGR DIBs. Then a single >> 16 will bring everything
2191 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2192 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2193 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2195 /* 6 bits for the green */
2201 for (h
= lines
- 1; h
>= 0; h
--) {
2202 dstpixel
=(LPWORD
)dstbits
;
2203 for (x
= 0; x
< dstwidth
; x
++) {
2204 PALETTEENTRY srcval
;
2206 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2207 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
2208 ((srcval
.peGreen
<< gShift
) & gDst
) |
2209 ((srcval
.peBlue
<< bShift
) & bDst
);
2210 *dstpixel
++=dstval
>> 16;
2212 dstbits
+= linebytes
;
2220 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2221 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
2222 int rShift
,gShift
,bShift
;
2223 const BYTE
* srcbits
;
2224 const BYTE
* srcpixel
;
2227 /* Shift everything 16 bits left so that all shifts are >0,
2228 * even for BGR DIBs. Then a single >> 16 will bring everything
2231 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2232 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2233 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2235 /* 6 bits for the green */
2241 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2242 for (h
=0; h
<lines
; h
++) {
2244 dstpixel
=(LPWORD
)dstbits
;
2245 for (x
= 0; x
< dstwidth
; x
++) {
2246 PALETTEENTRY srcval
;
2248 srcval
=srccolors
[(int)*srcpixel
++];
2249 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
2250 ((srcval
.peGreen
<< gShift
) & gDst
) |
2251 ((srcval
.peBlue
<< bShift
) & bDst
);
2252 *dstpixel
++=dstval
>> 16;
2254 srcbits
-= bmpImage
->bytes_per_line
;
2255 dstbits
+= linebytes
;
2265 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
2266 int rShift
,gShift
,bShift
;
2269 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
2270 bmpImage
->depth
, bmpImage
->red_mask
,
2271 bmpImage
->green_mask
, bmpImage
->blue_mask
,
2274 /* Shift everything 16 bits left so that all shifts are >0,
2275 * even for BGR DIBs. Then a single >> 16 will bring everything
2278 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2279 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2280 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2282 /* 6 bits for the green */
2288 for (h
= lines
- 1; h
>= 0; h
--) {
2289 dstpixel
=(LPWORD
)dstbits
;
2290 for (x
= 0; x
< dstwidth
; x
++) {
2293 srcval
=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage
, x
, h
));
2294 dstval
=((GetRValue(srcval
) << rShift
) & rDst
) |
2295 ((GetGValue(srcval
) << gShift
) & gDst
) |
2296 ((GetBValue(srcval
) << bShift
) & bDst
);
2297 *dstpixel
++=dstval
>> 16;
2299 dstbits
+= linebytes
;
2307 /***********************************************************************
2308 * X11DRV_DIB_SetImageBits_24
2310 * SetDIBits for a 24-bit deep DIB.
2312 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
2313 DWORD srcwidth
, DWORD dstwidth
, int left
,
2314 X11DRV_PDEVICE
*physDev
,
2315 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
2316 XImage
*bmpImage
, DWORD linebytes
)
2320 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
2325 srcbits
= srcbits
+ linebytes
* (lines
- 1);
2326 linebytes
= -linebytes
;
2329 switch (bmpImage
->depth
)
2332 if (bmpImage
->bits_per_pixel
==24) {
2335 srcbits
=srcbits
+left
*3;
2336 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
2338 if (bmpImage
->green_mask
!=0x00ff00 ||
2339 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2341 } else if (rSrc
==bmpImage
->red_mask
) {
2342 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
2343 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
2344 convs
->Convert_888_asis
2347 dstbits
,-bmpImage
->bytes_per_line
);
2349 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
2350 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
2351 convs
->Convert_888_reverse
2354 dstbits
,-bmpImage
->bytes_per_line
);
2364 srcbits
=srcbits
+left
*3;
2365 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
2367 if (bmpImage
->green_mask
!=0x00ff00 ||
2368 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2370 } else if (rSrc
==bmpImage
->red_mask
) {
2371 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
2372 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
2373 convs
->Convert_888_to_0888_asis
2376 dstbits
,-bmpImage
->bytes_per_line
);
2378 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
2379 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
2380 convs
->Convert_888_to_0888_reverse
2383 dstbits
,-bmpImage
->bytes_per_line
);
2393 srcbits
=srcbits
+left
*3;
2394 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2396 if (bmpImage
->green_mask
==0x03e0) {
2397 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
2398 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
2399 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
2400 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
2401 convs
->Convert_888_to_555_asis
2404 dstbits
,-bmpImage
->bytes_per_line
);
2405 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0x7f00) ||
2406 (bSrc
==0xff && bmpImage
->blue_mask
==0x7f00)) {
2407 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
2408 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
2409 convs
->Convert_888_to_555_reverse
2412 dstbits
,-bmpImage
->bytes_per_line
);
2416 } else if (bmpImage
->green_mask
==0x07e0) {
2417 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
2418 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
2419 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
2420 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
2421 convs
->Convert_888_to_565_asis
2424 dstbits
,-bmpImage
->bytes_per_line
);
2425 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0xf800) ||
2426 (bSrc
==0xff && bmpImage
->blue_mask
==0xf800)) {
2427 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
2428 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
2429 convs
->Convert_888_to_565_reverse
2432 dstbits
,-bmpImage
->bytes_per_line
);
2444 WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2445 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
2446 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2452 /* ==== rgb 888 dib -> any bmp bormat ==== */
2453 const BYTE
* srcbyte
;
2455 /* Windows only supports one 24bpp DIB format: RGB888 */
2457 for (h
= lines
- 1; h
>= 0; h
--) {
2458 srcbyte
=(const BYTE
*)srcbits
;
2459 for (x
= left
; x
< dstwidth
+left
; x
++) {
2460 XPutPixel(bmpImage
, x
, h
,
2461 X11DRV_PALETTE_ToPhysical
2462 (physDev
, RGB(srcbyte
[2], srcbyte
[1], srcbyte
[0])));
2465 srcbits
+= linebytes
;
2473 /***********************************************************************
2474 * X11DRV_DIB_GetImageBits_24
2476 * GetDIBits for an 24-bit deep DIB.
2478 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*dstbits
,
2479 DWORD dstwidth
, DWORD srcwidth
,
2480 PALETTEENTRY
*srccolors
,
2481 DWORD rDst
, DWORD gDst
, DWORD bDst
,
2482 XImage
*bmpImage
, DWORD linebytes
)
2486 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
2491 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2492 linebytes
= -linebytes
;
2495 switch (bmpImage
->depth
)
2498 if (bmpImage
->bits_per_pixel
==24) {
2499 const char* srcbits
;
2501 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2503 if (bmpImage
->green_mask
!=0x00ff00 ||
2504 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2506 } else if (rDst
==bmpImage
->red_mask
) {
2507 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
2508 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
2509 convs
->Convert_888_asis
2511 srcbits
,-bmpImage
->bytes_per_line
,
2514 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
2515 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
2516 convs
->Convert_888_reverse
2518 srcbits
,-bmpImage
->bytes_per_line
,
2527 const char* srcbits
;
2529 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2531 if (bmpImage
->green_mask
!=0x00ff00 ||
2532 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2534 } else if (rDst
==bmpImage
->red_mask
) {
2535 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
2536 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
2537 convs
->Convert_0888_to_888_asis
2539 srcbits
,-bmpImage
->bytes_per_line
,
2542 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
2543 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
2544 convs
->Convert_0888_to_888_reverse
2546 srcbits
,-bmpImage
->bytes_per_line
,
2555 const char* srcbits
;
2557 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2559 if (bmpImage
->green_mask
==0x03e0) {
2560 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
2561 (bDst
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
2562 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
2563 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
2564 convs
->Convert_555_to_888_asis
2566 srcbits
,-bmpImage
->bytes_per_line
,
2568 } else if ((rDst
==0xff && bmpImage
->red_mask
==0x7f00) ||
2569 (bDst
==0xff && bmpImage
->blue_mask
==0x7f00)) {
2570 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
2571 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
2572 convs
->Convert_555_to_888_reverse
2574 srcbits
,-bmpImage
->bytes_per_line
,
2579 } else if (bmpImage
->green_mask
==0x07e0) {
2580 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
2581 (bDst
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
2582 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
2583 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
2584 convs
->Convert_565_to_888_asis
2586 srcbits
,-bmpImage
->bytes_per_line
,
2588 } else if ((rDst
==0xff && bmpImage
->red_mask
==0xf800) ||
2589 (bDst
==0xff && bmpImage
->blue_mask
==0xf800)) {
2590 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
2591 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
2592 convs
->Convert_565_to_888_reverse
2594 srcbits
,-bmpImage
->bytes_per_line
,
2607 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2608 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
2611 /* Windows only supports one 24bpp DIB format: rgb 888 */
2612 for (h
= lines
- 1; h
>= 0; h
--) {
2614 for (x
= 0; x
< dstwidth
; x
++) {
2615 PALETTEENTRY srcval
;
2616 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2617 dstbyte
[0]=srcval
.peBlue
;
2618 dstbyte
[1]=srcval
.peGreen
;
2619 dstbyte
[2]=srcval
.peRed
;
2622 dstbits
+= linebytes
;
2630 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
== 0 && srccolors
) {
2631 /* ==== pal 8 bmp -> rgb 888 dib ==== */
2632 const void* srcbits
;
2633 const BYTE
* srcpixel
;
2636 /* Windows only supports one 24bpp DIB format: rgb 888 */
2637 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2638 for (h
= lines
- 1; h
>= 0; h
--) {
2641 for (x
= 0; x
< dstwidth
; x
++ ) {
2642 PALETTEENTRY srcval
;
2643 srcval
=srccolors
[(int)*srcpixel
++];
2644 dstbyte
[0]=srcval
.peBlue
;
2645 dstbyte
[1]=srcval
.peGreen
;
2646 dstbyte
[2]=srcval
.peRed
;
2649 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2650 dstbits
+= linebytes
;
2660 /* ==== any bmp format -> 888 dib ==== */
2663 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
2664 bmpImage
->depth
, bmpImage
->red_mask
,
2665 bmpImage
->green_mask
, bmpImage
->blue_mask
,
2668 /* Windows only supports one 24bpp DIB format: rgb 888 */
2669 for (h
= lines
- 1; h
>= 0; h
--) {
2671 for (x
= 0; x
< dstwidth
; x
++) {
2672 COLORREF srcval
=X11DRV_PALETTE_ToLogical
2673 (XGetPixel( bmpImage
, x
, h
));
2674 dstbyte
[0]=GetBValue(srcval
);
2675 dstbyte
[1]=GetGValue(srcval
);
2676 dstbyte
[2]=GetRValue(srcval
);
2679 dstbits
+= linebytes
;
2687 /***********************************************************************
2688 * X11DRV_DIB_SetImageBits_32
2690 * SetDIBits for a 32-bit deep DIB.
2692 static void X11DRV_DIB_SetImageBits_32(int lines
, const BYTE
*srcbits
,
2693 DWORD srcwidth
, DWORD dstwidth
, int left
,
2694 X11DRV_PDEVICE
*physDev
,
2695 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
2701 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
2706 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
2707 linebytes
= -linebytes
;
2710 ptr
= (DWORD
*) srcbits
+ left
;
2712 switch (bmpImage
->depth
)
2715 if (bmpImage
->bits_per_pixel
==24) {
2718 srcbits
=srcbits
+left
*4;
2719 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
2721 if (rSrc
==bmpImage
->red_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->blue_mask
) {
2722 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
2723 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
2724 convs
->Convert_0888_to_888_asis
2727 dstbits
,-bmpImage
->bytes_per_line
);
2728 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2729 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2731 /* the tests below assume sane bmpImage masks */
2732 } else if (rSrc
==bmpImage
->blue_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->red_mask
) {
2733 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
2734 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
2735 convs
->Convert_0888_to_888_reverse
2738 dstbits
,-bmpImage
->bytes_per_line
);
2739 } else if (bmpImage
->blue_mask
==0xff) {
2740 /* ==== any 0888 dib -> rgb 888 bmp ==== */
2741 convs
->Convert_any0888_to_rgb888
2745 dstbits
,-bmpImage
->bytes_per_line
);
2747 /* ==== any 0888 dib -> bgr 888 bmp ==== */
2748 convs
->Convert_any0888_to_bgr888
2752 dstbits
,-bmpImage
->bytes_per_line
);
2762 srcbits
=srcbits
+left
*4;
2763 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
2765 if (gSrc
==bmpImage
->green_mask
) {
2766 if (rSrc
==bmpImage
->red_mask
&& bSrc
==bmpImage
->blue_mask
) {
2767 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
2768 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
2769 convs
->Convert_0888_asis
2772 dstbits
,-bmpImage
->bytes_per_line
);
2773 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2774 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2776 /* the tests below assume sane bmpImage masks */
2777 } else if (rSrc
==bmpImage
->blue_mask
&& bSrc
==bmpImage
->red_mask
) {
2778 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
2779 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
2780 convs
->Convert_0888_reverse
2783 dstbits
,-bmpImage
->bytes_per_line
);
2785 /* ==== any 0888 dib -> any 0888 bmp ==== */
2786 convs
->Convert_0888_any
2790 dstbits
,-bmpImage
->bytes_per_line
,
2791 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2793 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2794 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2796 /* the tests below assume sane bmpImage masks */
2798 /* ==== any 0888 dib -> any 0888 bmp ==== */
2799 convs
->Convert_0888_any
2803 dstbits
,-bmpImage
->bytes_per_line
,
2804 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2814 srcbits
=srcbits
+left
*4;
2815 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2817 if (rSrc
==0xff0000 && gSrc
==0x00ff00 && bSrc
==0x0000ff) {
2818 if (bmpImage
->green_mask
==0x03e0) {
2819 if (bmpImage
->red_mask
==0x7f00) {
2820 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
2821 convs
->Convert_0888_to_555_asis
2824 dstbits
,-bmpImage
->bytes_per_line
);
2825 } else if (bmpImage
->blue_mask
==0x7f00) {
2826 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
2827 convs
->Convert_0888_to_555_reverse
2830 dstbits
,-bmpImage
->bytes_per_line
);
2834 } else if (bmpImage
->green_mask
==0x07e0) {
2835 if (bmpImage
->red_mask
==0xf800) {
2836 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
2837 convs
->Convert_0888_to_565_asis
2840 dstbits
,-bmpImage
->bytes_per_line
);
2841 } else if (bmpImage
->blue_mask
==0xf800) {
2842 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
2843 convs
->Convert_0888_to_565_reverse
2846 dstbits
,-bmpImage
->bytes_per_line
);
2853 } else if (rSrc
==0x0000ff && gSrc
==0x00ff00 && bSrc
==0xff0000) {
2854 if (bmpImage
->green_mask
==0x03e0) {
2855 if (bmpImage
->blue_mask
==0x7f00) {
2856 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
2857 convs
->Convert_0888_to_555_asis
2860 dstbits
,-bmpImage
->bytes_per_line
);
2861 } else if (bmpImage
->red_mask
==0x7f00) {
2862 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
2863 convs
->Convert_0888_to_555_reverse
2866 dstbits
,-bmpImage
->bytes_per_line
);
2870 } else if (bmpImage
->green_mask
==0x07e0) {
2871 if (bmpImage
->blue_mask
==0xf800) {
2872 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
2873 convs
->Convert_0888_to_565_asis
2876 dstbits
,-bmpImage
->bytes_per_line
);
2877 } else if (bmpImage
->red_mask
==0xf800) {
2878 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
2879 convs
->Convert_0888_to_565_reverse
2882 dstbits
,-bmpImage
->bytes_per_line
);
2890 if (bmpImage
->green_mask
==0x03e0 &&
2891 (bmpImage
->red_mask
==0x7f00 ||
2892 bmpImage
->blue_mask
==0x7f00)) {
2893 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
2894 convs
->Convert_any0888_to_5x5
2898 dstbits
,-bmpImage
->bytes_per_line
,
2899 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2900 } else if (bmpImage
->green_mask
==0x07e0 &&
2901 (bmpImage
->red_mask
==0xf800 ||
2902 bmpImage
->blue_mask
==0xf800)) {
2903 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
2904 convs
->Convert_any0888_to_5x5
2908 dstbits
,-bmpImage
->bytes_per_line
,
2909 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2919 WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2920 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
2921 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2927 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
2928 const DWORD
* srcpixel
;
2929 int rShift
,gShift
,bShift
;
2931 rShift
=X11DRV_DIB_MaskToShift(rSrc
);
2932 gShift
=X11DRV_DIB_MaskToShift(gSrc
);
2933 bShift
=X11DRV_DIB_MaskToShift(bSrc
);
2935 for (h
= lines
- 1; h
>= 0; h
--) {
2936 srcpixel
=(const DWORD
*)srcbits
;
2937 for (x
= left
; x
< dstwidth
+left
; x
++) {
2939 BYTE red
,green
,blue
;
2940 srcvalue
=*srcpixel
++;
2941 red
= (srcvalue
>> rShift
) & 0xff;
2942 green
=(srcvalue
>> gShift
) & 0xff;
2943 blue
= (srcvalue
>> bShift
) & 0xff;
2944 XPutPixel(bmpImage
, x
, h
, X11DRV_PALETTE_ToPhysical
2945 (physDev
, RGB(red
,green
,blue
)));
2947 srcbits
+= linebytes
;
2955 /***********************************************************************
2956 * X11DRV_DIB_GetImageBits_32
2958 * GetDIBits for an 32-bit deep DIB.
2960 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*dstbits
,
2961 DWORD dstwidth
, DWORD srcwidth
,
2962 PALETTEENTRY
*srccolors
,
2963 DWORD rDst
, DWORD gDst
, DWORD bDst
,
2964 XImage
*bmpImage
, DWORD linebytes
)
2969 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
2974 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2975 linebytes
= -linebytes
;
2980 switch (bmpImage
->depth
)
2983 if (bmpImage
->bits_per_pixel
==24) {
2984 const void* srcbits
;
2986 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2988 if (rDst
==bmpImage
->red_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->blue_mask
) {
2989 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
2990 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
2991 convs
->Convert_888_to_0888_asis
2993 srcbits
,-bmpImage
->bytes_per_line
,
2995 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2996 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2998 /* the tests below assume sane bmpImage masks */
2999 } else if (rDst
==bmpImage
->blue_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->red_mask
) {
3000 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3001 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3002 convs
->Convert_888_to_0888_reverse
3004 srcbits
,-bmpImage
->bytes_per_line
,
3006 } else if (bmpImage
->blue_mask
==0xff) {
3007 /* ==== rgb 888 bmp -> any 0888 dib ==== */
3008 convs
->Convert_rgb888_to_any0888
3010 srcbits
,-bmpImage
->bytes_per_line
,
3014 /* ==== bgr 888 bmp -> any 0888 dib ==== */
3015 convs
->Convert_bgr888_to_any0888
3017 srcbits
,-bmpImage
->bytes_per_line
,
3027 const char* srcbits
;
3029 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3031 if (gDst
==bmpImage
->green_mask
) {
3032 if (rDst
==bmpImage
->red_mask
&& bDst
==bmpImage
->blue_mask
) {
3033 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
3034 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
3035 convs
->Convert_0888_asis
3037 srcbits
,-bmpImage
->bytes_per_line
,
3039 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3040 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3042 /* the tests below assume sane bmpImage masks */
3043 } else if (rDst
==bmpImage
->blue_mask
&& bDst
==bmpImage
->red_mask
) {
3044 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
3045 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
3046 convs
->Convert_0888_reverse
3048 srcbits
,-bmpImage
->bytes_per_line
,
3051 /* ==== any 0888 bmp -> any 0888 dib ==== */
3052 convs
->Convert_0888_any
3054 srcbits
,-bmpImage
->bytes_per_line
,
3055 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3059 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3060 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3062 /* the tests below assume sane bmpImage masks */
3064 /* ==== any 0888 bmp -> any 0888 dib ==== */
3065 convs
->Convert_0888_any
3067 srcbits
,-bmpImage
->bytes_per_line
,
3068 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3078 const char* srcbits
;
3080 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3082 if (rDst
==0xff0000 && gDst
==0x00ff00 && bDst
==0x0000ff) {
3083 if (bmpImage
->green_mask
==0x03e0) {
3084 if (bmpImage
->red_mask
==0x7f00) {
3085 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
3086 convs
->Convert_555_to_0888_asis
3088 srcbits
,-bmpImage
->bytes_per_line
,
3090 } else if (bmpImage
->blue_mask
==0x7f00) {
3091 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
3092 convs
->Convert_555_to_0888_reverse
3094 srcbits
,-bmpImage
->bytes_per_line
,
3099 } else if (bmpImage
->green_mask
==0x07e0) {
3100 if (bmpImage
->red_mask
==0xf800) {
3101 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
3102 convs
->Convert_565_to_0888_asis
3104 srcbits
,-bmpImage
->bytes_per_line
,
3106 } else if (bmpImage
->blue_mask
==0xf800) {
3107 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
3108 convs
->Convert_565_to_0888_reverse
3110 srcbits
,-bmpImage
->bytes_per_line
,
3118 } else if (rDst
==0x0000ff && gDst
==0x00ff00 && bDst
==0xff0000) {
3119 if (bmpImage
->green_mask
==0x03e0) {
3120 if (bmpImage
->blue_mask
==0x7f00) {
3121 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
3122 convs
->Convert_555_to_0888_asis
3124 srcbits
,-bmpImage
->bytes_per_line
,
3126 } else if (bmpImage
->red_mask
==0x7f00) {
3127 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
3128 convs
->Convert_555_to_0888_reverse
3130 srcbits
,-bmpImage
->bytes_per_line
,
3135 } else if (bmpImage
->green_mask
==0x07e0) {
3136 if (bmpImage
->blue_mask
==0xf800) {
3137 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
3138 convs
->Convert_565_to_0888_asis
3140 srcbits
,-bmpImage
->bytes_per_line
,
3142 } else if (bmpImage
->red_mask
==0xf800) {
3143 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
3144 convs
->Convert_565_to_0888_reverse
3146 srcbits
,-bmpImage
->bytes_per_line
,
3155 if (bmpImage
->green_mask
==0x03e0 &&
3156 (bmpImage
->red_mask
==0x7f00 ||
3157 bmpImage
->blue_mask
==0x7f00)) {
3158 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
3159 convs
->Convert_5x5_to_any0888
3161 srcbits
,-bmpImage
->bytes_per_line
,
3162 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3165 } else if (bmpImage
->green_mask
==0x07e0 &&
3166 (bmpImage
->red_mask
==0xf800 ||
3167 bmpImage
->blue_mask
==0xf800)) {
3168 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
3169 convs
->Convert_5x5_to_any0888
3171 srcbits
,-bmpImage
->bytes_per_line
,
3172 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3184 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3185 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
3186 int rShift
,gShift
,bShift
;
3189 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3190 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3191 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3192 for (h
= lines
- 1; h
>= 0; h
--) {
3193 dstpixel
=(DWORD
*)dstbits
;
3194 for (x
= 0; x
< dstwidth
; x
++) {
3195 PALETTEENTRY srcval
;
3196 srcval
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
3197 *dstpixel
++=(srcval
.peRed
<< rShift
) |
3198 (srcval
.peGreen
<< gShift
) |
3199 (srcval
.peBlue
<< bShift
);
3201 dstbits
+= linebytes
;
3209 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3210 /* ==== pal 8 bmp -> any 0888 dib ==== */
3211 int rShift
,gShift
,bShift
;
3212 const void* srcbits
;
3213 const BYTE
* srcpixel
;
3216 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3217 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3218 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3219 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3220 for (h
= lines
- 1; h
>= 0; h
--) {
3222 dstpixel
=(DWORD
*)dstbits
;
3223 for (x
= 0; x
< dstwidth
; x
++) {
3224 PALETTEENTRY srcval
;
3225 srcval
=srccolors
[(int)*srcpixel
++];
3226 *dstpixel
++=(srcval
.peRed
<< rShift
) |
3227 (srcval
.peGreen
<< gShift
) |
3228 (srcval
.peBlue
<< bShift
);
3230 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
3231 dstbits
+= linebytes
;
3241 /* ==== any bmp format -> any 0888 dib ==== */
3242 int rShift
,gShift
,bShift
;
3245 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
3246 bmpImage
->depth
, bmpImage
->red_mask
,
3247 bmpImage
->green_mask
, bmpImage
->blue_mask
,
3250 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3251 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3252 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3253 for (h
= lines
- 1; h
>= 0; h
--) {
3254 dstpixel
=(DWORD
*)dstbits
;
3255 for (x
= 0; x
< dstwidth
; x
++) {
3257 srcval
=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage
, x
, h
));
3258 *dstpixel
++=(GetRValue(srcval
) << rShift
) |
3259 (GetGValue(srcval
) << gShift
) |
3260 (GetBValue(srcval
) << bShift
);
3262 dstbits
+= linebytes
;
3269 /***********************************************************************
3270 * X11DRV_DIB_SetImageBits
3272 * Transfer the bits to an X image.
3273 * Helper function for SetDIBits() and SetDIBitsToDevice().
3275 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
3277 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
3282 bmpImage
= descr
->image
;
3284 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
3285 descr
->infoWidth
, lines
, 32, 0 );
3286 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
3287 if(bmpImage
->data
== NULL
) {
3288 ERR("Out of memory!\n");
3289 XDestroyImage( bmpImage
);
3290 wine_tsx11_unlock();
3295 TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
3296 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
3297 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
3298 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
3299 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
3301 /* Transfer the pixels */
3302 switch(descr
->infoBpp
)
3305 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
3306 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
3307 bmpImage
, descr
->dibpitch
);
3310 if (descr
->compression
) {
3311 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
3312 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
3313 bmpImage
, descr
->xSrc
, descr
->ySrc
);
3315 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
3316 descr
->infoWidth
, descr
->width
,
3317 descr
->xSrc
, (int *)(descr
->colorMap
),
3320 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
3321 descr
->infoWidth
, descr
->width
,
3322 descr
->xSrc
, (int*)(descr
->colorMap
),
3323 bmpImage
, descr
->dibpitch
);
3326 if (descr
->compression
) {
3327 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
3328 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
3329 bmpImage
, descr
->xSrc
, descr
->ySrc
);
3330 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
3331 descr
->infoWidth
, descr
->width
,
3332 descr
->xSrc
, (int *)(descr
->colorMap
),
3335 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
3336 descr
->infoWidth
, descr
->width
,
3337 descr
->xSrc
, (int *)(descr
->colorMap
),
3338 bmpImage
, descr
->dibpitch
);
3342 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
3343 descr
->infoWidth
, descr
->width
,
3344 descr
->xSrc
, descr
->physDev
,
3345 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3346 bmpImage
, descr
->dibpitch
);
3349 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
3350 descr
->infoWidth
, descr
->width
,
3351 descr
->xSrc
, descr
->physDev
,
3352 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3353 bmpImage
, descr
->dibpitch
);
3356 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
3357 descr
->infoWidth
, descr
->width
,
3358 descr
->xSrc
, descr
->physDev
,
3359 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3360 bmpImage
, descr
->dibpitch
);
3363 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
3367 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
3368 descr
->drawable
, descr
->gc
, bmpImage
,
3369 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3370 descr
->width
, descr
->height
);
3371 #ifdef HAVE_LIBXXSHM
3374 XShmPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
3375 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3376 descr
->width
, descr
->height
, FALSE
);
3377 XSync( gdi_display
, 0 );
3381 XPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
3382 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3383 descr
->width
, descr
->height
);
3385 if (!descr
->image
) XDestroyImage( bmpImage
);
3386 wine_tsx11_unlock();
3390 /***********************************************************************
3391 * X11DRV_DIB_GetImageBits
3393 * Transfer the bits from an X image.
3395 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
3397 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
3402 bmpImage
= descr
->image
;
3404 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
3405 descr
->infoWidth
, lines
, 32, 0 );
3406 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
3407 if(bmpImage
->data
== NULL
) {
3408 ERR("Out of memory!\n");
3409 XDestroyImage( bmpImage
);
3410 wine_tsx11_unlock();
3415 #ifdef HAVE_LIBXXSHM
3418 int saveRed
, saveGreen
, saveBlue
;
3420 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
3421 gdi_display
, descr
->drawable
, bmpImage
,
3422 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
3424 /* We must save and restore the bmpImage's masks in order
3425 * to preserve them across the call to XShmGetImage, which
3426 * decides to eleminate them since it doesn't happen to know
3427 * what the format of the image is supposed to be, even though
3429 saveRed
= bmpImage
->red_mask
;
3430 saveBlue
= bmpImage
->blue_mask
;
3431 saveGreen
= bmpImage
->green_mask
;
3433 XShmGetImage( gdi_display
, descr
->drawable
, bmpImage
,
3434 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
3436 bmpImage
->red_mask
= saveRed
;
3437 bmpImage
->blue_mask
= saveBlue
;
3438 bmpImage
->green_mask
= saveGreen
;
3441 #endif /* HAVE_LIBXXSHM */
3443 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
3444 gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
, descr
->width
,
3445 lines
, AllPlanes
, ZPixmap
, bmpImage
, descr
->xDest
, descr
->yDest
);
3446 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
,
3447 descr
->width
, lines
, AllPlanes
, ZPixmap
,
3448 bmpImage
, descr
->xDest
, descr
->yDest
);
3451 TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
3452 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
3453 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
3454 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
3455 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
3456 /* Transfer the pixels */
3457 switch(descr
->infoBpp
)
3460 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
3461 descr
->infoWidth
, descr
->width
,
3462 descr
->colorMap
, descr
->palentry
,
3463 bmpImage
, descr
->dibpitch
);
3467 if (descr
->compression
)
3468 FIXME("Compression not yet supported!\n");
3470 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
3471 descr
->infoWidth
, descr
->width
,
3472 descr
->colorMap
, descr
->palentry
,
3473 bmpImage
, descr
->dibpitch
);
3477 if (descr
->compression
)
3478 FIXME("Compression not yet supported!\n");
3480 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
3481 descr
->infoWidth
, descr
->width
,
3482 descr
->colorMap
, descr
->palentry
,
3483 bmpImage
, descr
->dibpitch
);
3487 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
3488 descr
->infoWidth
,descr
->width
,
3490 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3491 bmpImage
, descr
->dibpitch
);
3495 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
3496 descr
->infoWidth
,descr
->width
,
3498 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3499 bmpImage
, descr
->dibpitch
);
3503 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
3504 descr
->infoWidth
, descr
->width
,
3506 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3507 bmpImage
, descr
->dibpitch
);
3511 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
3515 if (!descr
->image
) XDestroyImage( bmpImage
);
3516 wine_tsx11_unlock();
3520 /*************************************************************************
3521 * X11DRV_SetDIBitsToDevice
3524 INT
X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE
*physDev
, INT xDest
, INT yDest
, DWORD cx
,
3525 DWORD cy
, INT xSrc
, INT ySrc
,
3526 UINT startscan
, UINT lines
, LPCVOID bits
,
3527 const BITMAPINFO
*info
, UINT coloruse
)
3529 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3535 DC
*dc
= physDev
->dc
;
3537 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
3538 &descr
.infoBpp
, &descr
.compression
) == -1)
3540 top_down
= (height
< 0);
3541 if (top_down
) height
= -height
;
3545 LPtoDP(physDev
->hdc
, &pt
, 1);
3547 if (!lines
|| (startscan
>= height
)) return 0;
3548 if (!top_down
&& startscan
+ lines
> height
) lines
= height
- startscan
;
3550 /* make xSrc,ySrc point to the upper-left corner, not the lower-left one,
3551 * and clamp all values to fit inside [startscan,startscan+lines]
3553 if (ySrc
+ cy
<= startscan
+ lines
)
3555 INT y
= startscan
+ lines
- (ySrc
+ cy
);
3556 if (ySrc
< startscan
) cy
-= (startscan
- ySrc
);
3559 /* avoid getting unnecessary lines */
3561 if (y
>= lines
) return 0;
3566 if (y
>= lines
) return lines
;
3567 ySrc
= y
; /* need to get all lines in top down mode */
3572 if (ySrc
>= startscan
+ lines
) return lines
;
3573 pt
.y
+= ySrc
+ cy
- (startscan
+ lines
);
3574 cy
= startscan
+ lines
- ySrc
;
3576 if (cy
> lines
) cy
= lines
;
3578 if (xSrc
>= width
) return lines
;
3579 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
3580 if (!cx
|| !cy
) return lines
;
3582 X11DRV_SetupGCForText( physDev
); /* To have the correct colors */
3584 XSetFunction(gdi_display
, physDev
->gc
, X11DRV_XROPfunction
[dc
->ROPmode
-1]);
3585 wine_tsx11_unlock();
3587 switch (descr
.infoBpp
)
3592 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
3593 coloruse
== DIB_PAL_COLORS
? physDev
: NULL
, coloruse
,
3594 dc
->bitsPerPixel
, info
, &descr
.nColorMap
);
3595 if (!descr
.colorMap
) return 0;
3596 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3600 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
3601 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
3602 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
3608 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
3609 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
3610 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
3615 descr
.physDev
= physDev
;
3618 descr
.palentry
= NULL
;
3619 descr
.lines
= top_down
? -lines
: lines
;
3620 descr
.infoWidth
= width
;
3621 descr
.depth
= dc
->bitsPerPixel
;
3622 descr
.drawable
= physDev
->drawable
;
3623 descr
.gc
= physDev
->gc
;
3626 descr
.xDest
= physDev
->org
.x
+ pt
.x
;
3627 descr
.yDest
= physDev
->org
.y
+ pt
.y
;
3630 descr
.useShm
= FALSE
;
3631 descr
.dibpitch
= ((width
* descr
.infoBpp
+ 31) &~31) / 8;
3633 result
= X11DRV_DIB_SetImageBits( &descr
);
3635 if (descr
.infoBpp
<= 8)
3636 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
3640 /***********************************************************************
3641 * SetDIBits (X11DRV.@)
3643 INT
X11DRV_SetDIBits( X11DRV_PDEVICE
*physDev
, HBITMAP hbitmap
, UINT startscan
,
3644 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
, UINT coloruse
)
3646 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3648 int height
, tmpheight
;
3651 descr
.physDev
= physDev
;
3653 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
3654 &descr
.infoBpp
, &descr
.compression
) == -1)
3658 if (height
< 0) height
= -height
;
3659 if (!lines
|| (startscan
>= height
))
3662 if (!(bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
))) return 0;
3664 if (startscan
+ lines
> height
) lines
= height
- startscan
;
3666 switch (descr
.infoBpp
)
3671 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
3672 coloruse
== DIB_PAL_COLORS
? descr
.physDev
: NULL
, coloruse
,
3673 bmp
->bitmap
.bmBitsPixel
,
3674 info
, &descr
.nColorMap
);
3675 if (!descr
.colorMap
)
3677 GDI_ReleaseObj( hbitmap
);
3680 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3684 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
3685 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
3686 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
3692 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
3693 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
3694 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
3703 descr
.palentry
= NULL
;
3704 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
3705 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3706 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
3707 descr
.gc
= BITMAP_GC(bmp
);
3711 descr
.yDest
= height
- startscan
- lines
;
3712 descr
.width
= bmp
->bitmap
.bmWidth
;
3713 descr
.height
= lines
;
3714 descr
.useShm
= FALSE
;
3715 descr
.dibpitch
= ((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8;
3716 X11DRV_DIB_Lock(bmp
, DIB_Status_GdiMod
, FALSE
);
3717 result
= X11DRV_DIB_SetImageBits( &descr
);
3718 X11DRV_DIB_Unlock(bmp
, TRUE
);
3720 if (descr
.colorMap
) HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
3722 GDI_ReleaseObj( hbitmap
);
3726 /***********************************************************************
3727 * GetDIBits (X11DRV.@)
3729 INT
X11DRV_GetDIBits( X11DRV_PDEVICE
*physDev
, HBITMAP hbitmap
, UINT startscan
, UINT lines
,
3730 LPVOID bits
, BITMAPINFO
*info
, UINT coloruse
)
3732 X11DRV_DIBSECTION
*dib
;
3733 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3734 PALETTEOBJ
* palette
;
3737 DC
*dc
= physDev
->dc
;
3739 if (!(palette
= (PALETTEOBJ
*)GDI_GetObjPtr( dc
->hPalette
, PALETTE_MAGIC
)))
3741 if (!(bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
)))
3743 GDI_ReleaseObj( dc
->hPalette
);
3746 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3748 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
3749 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
3750 (int)info
->bmiHeader
.biWidth
, (int)info
->bmiHeader
.biHeight
,
3753 if( lines
> bmp
->bitmap
.bmHeight
) lines
= bmp
->bitmap
.bmHeight
;
3755 height
= info
->bmiHeader
.biHeight
;
3756 if (height
< 0) height
= -height
;
3757 if( lines
> height
) lines
= height
;
3758 /* Top-down images have a negative biHeight, the scanlines of theses images
3759 * were inverted in X11DRV_DIB_GetImageBits_xx
3760 * To prevent this we simply change the sign of lines
3761 * (the number of scan lines to copy).
3762 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3764 if( info
->bmiHeader
.biHeight
< 0 && lines
> 0) lines
= -lines
;
3766 if( startscan
>= bmp
->bitmap
.bmHeight
)
3772 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &descr
.lines
,
3773 &descr
.infoBpp
, &descr
.compression
) == -1)
3779 switch (descr
.infoBpp
)
3784 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3788 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
3789 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
3790 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
3794 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
3795 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
3796 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
3800 descr
.physDev
= physDev
;
3801 descr
.palentry
= palette
->logpalette
.palPalEntry
;
3804 descr
.lines
= lines
;
3805 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3806 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
3807 descr
.gc
= BITMAP_GC(bmp
);
3808 descr
.width
= bmp
->bitmap
.bmWidth
;
3809 descr
.height
= bmp
->bitmap
.bmHeight
;
3810 descr
.colorMap
= info
->bmiColors
;
3815 if (descr
.lines
> 0)
3817 descr
.ySrc
= (descr
.height
-1) - (startscan
+ (lines
-1));
3821 descr
.ySrc
= startscan
;
3823 #ifdef HAVE_LIBXXSHM
3824 descr
.useShm
= dib
? (dib
->shminfo
.shmid
!= -1) : FALSE
;
3826 descr
.useShm
= FALSE
;
3828 descr
.dibpitch
= dib
? (dib
->dibSection
.dsBm
.bmWidthBytes
)
3829 : (((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8);
3831 X11DRV_DIB_Lock(bmp
, DIB_Status_GdiMod
, FALSE
);
3832 X11DRV_DIB_GetImageBits( &descr
);
3833 X11DRV_DIB_Unlock(bmp
, TRUE
);
3835 if(info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
3836 info
->bmiHeader
.biSizeImage
= DIB_GetDIBImageBytes(
3837 info
->bmiHeader
.biWidth
,
3838 info
->bmiHeader
.biHeight
,
3839 info
->bmiHeader
.biBitCount
);
3841 if (descr
.compression
== BI_BITFIELDS
)
3843 *(DWORD
*)info
->bmiColors
= descr
.rMask
;
3844 *((DWORD
*)info
->bmiColors
+1) = descr
.gMask
;
3845 *((DWORD
*)info
->bmiColors
+2) = descr
.bMask
;
3849 /* if RLE or JPEG compression were supported,
3850 * this line would be invalid. */
3851 info
->bmiHeader
.biCompression
= 0;
3855 GDI_ReleaseObj( dc
->hPalette
);
3856 GDI_ReleaseObj( hbitmap
);
3860 /***********************************************************************
3861 * DIB_DoProtectDIBSection
3863 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
3865 DIBSECTION
*dib
= bmp
->dib
;
3866 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
3867 : -dib
->dsBm
.bmHeight
;
3868 /* use the biSizeImage data as the memory size only if we're dealing with a
3869 compressed image where the value is set. Otherwise, calculate based on
3871 INT totalSize
= dib
->dsBmih
.biSizeImage
&& dib
->dsBmih
.biCompression
!= BI_RGB
3872 ? dib
->dsBmih
.biSizeImage
3873 : dib
->dsBm
.bmWidthBytes
* effHeight
;
3876 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
3877 TRACE("Changed protection from %ld to %ld\n", old_prot
, new_prot
);
3880 /***********************************************************************
3881 * X11DRV_DIB_DoUpdateDIBSection
3883 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
,
3884 void *colorMap
, int nColorMap
,
3886 DWORD xSrc
, DWORD ySrc
,
3887 DWORD xDest
, DWORD yDest
,
3888 DWORD width
, DWORD height
)
3890 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3891 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3893 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, &descr
.lines
,
3894 &descr
.infoBpp
, &descr
.compression
) == -1)
3897 descr
.physDev
= NULL
;
3898 descr
.palentry
= NULL
;
3899 descr
.image
= dib
->image
;
3900 descr
.colorMap
= colorMap
;
3901 descr
.nColorMap
= nColorMap
;
3902 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
3903 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3905 switch (descr
.infoBpp
)
3910 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3914 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0x7c00;
3915 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x03e0;
3916 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x001f;
3921 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0xff0000;
3922 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x00ff00;
3923 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x0000ff;
3928 descr
.drawable
= dest
;
3929 descr
.gc
= BITMAP_GC(bmp
);
3932 descr
.xDest
= xDest
;
3933 descr
.yDest
= yDest
;
3934 descr
.width
= width
;
3935 descr
.height
= height
;
3936 #ifdef HAVE_LIBXXSHM
3937 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
3939 descr
.useShm
= FALSE
;
3941 descr
.dibpitch
= dib
->dibSection
.dsBm
.bmWidthBytes
;
3945 TRACE("Copying from Pixmap to DIB bits\n");
3946 X11DRV_DIB_GetImageBits( &descr
);
3950 TRACE("Copying from DIB bits to Pixmap\n");
3951 X11DRV_DIB_SetImageBits( &descr
);
3955 /***********************************************************************
3956 * X11DRV_DIB_CopyDIBSection
3958 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE
*physDevSrc
, X11DRV_PDEVICE
*physDevDst
,
3959 DWORD xSrc
, DWORD ySrc
, DWORD xDest
, DWORD yDest
,
3960 DWORD width
, DWORD height
)
3963 DC
*dcSrc
= physDevSrc
->dc
;
3964 DC
*dcDst
= physDevDst
->dc
;
3965 int nColorMap
= 0, *colorMap
= NULL
, aColorMap
= FALSE
;
3967 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc
, dcDst
,
3968 xSrc
, ySrc
, xDest
, yDest
, width
, height
);
3969 /* this function is meant as an optimization for BitBlt,
3970 * not to be called otherwise */
3971 if (GetObjectType( physDevSrc
->hdc
) != OBJ_MEMDC
) {
3972 ERR("called for non-memory source DC!?\n");
3976 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( dcSrc
->hBitmap
, BITMAP_MAGIC
);
3977 if (!(bmp
&& bmp
->dib
)) {
3978 ERR("called for non-DIBSection!?\n");
3979 GDI_ReleaseObj( dcSrc
->hBitmap
);
3982 /* while BitBlt should already have made sure we only get
3983 * positive values, we should check for oversize values */
3984 if ((xSrc
< bmp
->bitmap
.bmWidth
) &&
3985 (ySrc
< bmp
->bitmap
.bmHeight
)) {
3986 if (xSrc
+ width
> bmp
->bitmap
.bmWidth
)
3987 width
= bmp
->bitmap
.bmWidth
- xSrc
;
3988 if (ySrc
+ height
> bmp
->bitmap
.bmHeight
)
3989 height
= bmp
->bitmap
.bmHeight
- ySrc
;
3990 /* if the source bitmap is 8bpp or less, we're supposed to use the
3991 * DC's palette for color conversion (not the DIB color table) */
3992 if (bmp
->dib
->dsBm
.bmBitsPixel
<= 8) {
3993 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3994 if ((!dcSrc
->hPalette
) ||
3995 (dcSrc
->hPalette
== GetStockObject(DEFAULT_PALETTE
))) {
3996 /* HACK: no palette has been set in the source DC,
3997 * use the DIB colormap instead - this is necessary in some
3998 * cases since we need to do depth conversion in some places
3999 * where real Windows can just copy data straight over */
4000 colorMap
= dib
->colorMap
;
4001 nColorMap
= dib
->nColorMap
;
4003 colorMap
= X11DRV_DIB_BuildColorMap( physDevSrc
, (WORD
)-1,
4004 bmp
->dib
->dsBm
.bmBitsPixel
,
4005 (BITMAPINFO
*)&(bmp
->dib
->dsBmih
),
4007 if (colorMap
) aColorMap
= TRUE
;
4010 /* perform the copy */
4011 X11DRV_DIB_DoCopyDIBSection(bmp
, FALSE
, colorMap
, nColorMap
,
4012 physDevDst
->drawable
, xSrc
, ySrc
,
4013 physDevDst
->org
.x
+ xDest
, physDevDst
->org
.y
+ yDest
,
4015 /* free color mapping */
4017 HeapFree(GetProcessHeap(), 0, colorMap
);
4019 GDI_ReleaseObj( dcSrc
->hBitmap
);
4022 /***********************************************************************
4023 * X11DRV_DIB_DoUpdateDIBSection
4025 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
4027 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4028 X11DRV_DIB_DoCopyDIBSection(bmp
, toDIB
, dib
->colorMap
, dib
->nColorMap
,
4029 (Drawable
)bmp
->physBitmap
, 0, 0, 0, 0,
4030 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
4033 /***********************************************************************
4034 * X11DRV_DIB_FaultHandler
4036 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
4041 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
4042 if (!bmp
) return FALSE
;
4044 state
= X11DRV_DIB_Lock(bmp
, DIB_Status_None
, FALSE
);
4045 if (state
!= DIB_Status_InSync
) {
4046 /* no way to tell whether app needs read or write yet,
4048 X11DRV_DIB_Coerce(bmp
, DIB_Status_InSync
, FALSE
);
4050 /* hm, apparently the app must have write access */
4051 X11DRV_DIB_Coerce(bmp
, DIB_Status_AppMod
, FALSE
);
4053 X11DRV_DIB_Unlock(bmp
, TRUE
);
4055 GDI_ReleaseObj( (HBITMAP
)res
);
4059 /***********************************************************************
4062 INT
X11DRV_DIB_Coerce(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
4064 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4065 INT ret
= DIB_Status_None
;
4068 EnterCriticalSection(&(dib
->lock
));
4071 case DIB_Status_GdiMod
:
4072 /* GDI access - request to draw on pixmap */
4073 switch (dib
->status
)
4076 case DIB_Status_None
:
4077 dib
->p_status
= DIB_Status_GdiMod
;
4078 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
4081 case DIB_Status_GdiMod
:
4082 TRACE("GdiMod requested in status GdiMod\n" );
4085 case DIB_Status_InSync
:
4086 TRACE("GdiMod requested in status InSync\n" );
4087 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
4088 dib
->status
= DIB_Status_GdiMod
;
4089 dib
->p_status
= DIB_Status_InSync
;
4092 case DIB_Status_AuxMod
:
4093 TRACE("GdiMod requested in status AuxMod\n" );
4094 if (lossy
) dib
->status
= DIB_Status_GdiMod
;
4095 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_GdiMod
);
4096 dib
->p_status
= DIB_Status_AuxMod
;
4097 if (dib
->status
!= DIB_Status_AppMod
) {
4098 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
4101 /* fall through if copy_aux() had to change to AppMod state */
4103 case DIB_Status_AppMod
:
4104 TRACE("GdiMod requested in status AppMod\n" );
4106 /* make it readonly to avoid app changing data while we copy */
4107 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4108 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
4110 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
4111 dib
->p_status
= DIB_Status_AppMod
;
4112 dib
->status
= DIB_Status_GdiMod
;
4117 case DIB_Status_InSync
:
4118 /* App access - request access to read DIB surface */
4119 /* (typically called from signal handler) */
4120 switch (dib
->status
)
4123 case DIB_Status_None
:
4124 /* shouldn't happen from signal handler */
4127 case DIB_Status_AuxMod
:
4128 TRACE("InSync requested in status AuxMod\n" );
4129 if (lossy
) dib
->status
= DIB_Status_InSync
;
4131 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4132 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_InSync
);
4134 if (dib
->status
!= DIB_Status_GdiMod
) {
4135 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4138 /* fall through if copy_aux() had to change to GdiMod state */
4140 case DIB_Status_GdiMod
:
4141 TRACE("InSync requested in status GdiMod\n" );
4143 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4144 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
4146 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4147 dib
->status
= DIB_Status_InSync
;
4150 case DIB_Status_InSync
:
4151 TRACE("InSync requested in status InSync\n" );
4152 /* shouldn't happen from signal handler */
4155 case DIB_Status_AppMod
:
4156 TRACE("InSync requested in status AppMod\n" );
4157 /* no reason to do anything here, and this
4158 * shouldn't happen from signal handler */
4163 case DIB_Status_AppMod
:
4164 /* App access - request access to write DIB surface */
4165 /* (typically called from signal handler) */
4166 switch (dib
->status
)
4169 case DIB_Status_None
:
4170 /* shouldn't happen from signal handler */
4173 case DIB_Status_AuxMod
:
4174 TRACE("AppMod requested in status AuxMod\n" );
4175 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4176 if (lossy
) dib
->status
= DIB_Status_AppMod
;
4177 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
4178 if (dib
->status
!= DIB_Status_GdiMod
)
4180 /* fall through if copy_aux() had to change to GdiMod state */
4182 case DIB_Status_GdiMod
:
4183 TRACE("AppMod requested in status GdiMod\n" );
4184 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4185 if (!lossy
) X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
4186 dib
->status
= DIB_Status_AppMod
;
4189 case DIB_Status_InSync
:
4190 TRACE("AppMod requested in status InSync\n" );
4191 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4192 dib
->status
= DIB_Status_AppMod
;
4195 case DIB_Status_AppMod
:
4196 TRACE("AppMod requested in status AppMod\n" );
4197 /* shouldn't happen from signal handler */
4202 case DIB_Status_AuxMod
:
4203 if (dib
->status
== DIB_Status_None
) {
4204 dib
->p_status
= req
;
4206 if (dib
->status
!= DIB_Status_AuxMod
)
4207 dib
->p_status
= dib
->status
;
4208 dib
->status
= DIB_Status_AuxMod
;
4211 /* it is up to the caller to do the copy/conversion, probably
4212 * using the return value to decide where to copy from */
4214 LeaveCriticalSection(&(dib
->lock
));
4219 /***********************************************************************
4222 INT
X11DRV_DIB_Lock(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
4224 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4225 INT ret
= DIB_Status_None
;
4228 TRACE("Locking %p from thread %04lx\n", bmp
, GetCurrentThreadId());
4229 EnterCriticalSection(&(dib
->lock
));
4231 if (req
!= DIB_Status_None
)
4232 X11DRV_DIB_Coerce(bmp
, req
, lossy
);
4237 /***********************************************************************
4240 void X11DRV_DIB_Unlock(BITMAPOBJ
*bmp
, BOOL commit
)
4242 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4245 switch (dib
->status
)
4248 case DIB_Status_None
:
4249 /* in case anyone is wondering, this is the "signal handler doesn't
4250 * work" case, where we always have to be ready for app access */
4252 switch (dib
->p_status
)
4254 case DIB_Status_AuxMod
:
4255 TRACE("Unlocking and syncing from AuxMod\n" );
4256 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
4257 if (dib
->status
!= DIB_Status_None
) {
4258 dib
->p_status
= dib
->status
;
4259 dib
->status
= DIB_Status_None
;
4261 if (dib
->p_status
!= DIB_Status_GdiMod
)
4263 /* fall through if copy_aux() had to change to GdiMod state */
4265 case DIB_Status_GdiMod
:
4266 TRACE("Unlocking and syncing from GdiMod\n" );
4267 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
4271 TRACE("Unlocking without needing to sync\n" );
4275 else TRACE("Unlocking with no changes\n");
4276 dib
->p_status
= DIB_Status_None
;
4279 case DIB_Status_GdiMod
:
4280 TRACE("Unlocking in status GdiMod\n" );
4281 /* DIB was protected in Coerce */
4283 /* no commit, revert to InSync if applicable */
4284 if ((dib
->p_status
== DIB_Status_InSync
) ||
4285 (dib
->p_status
== DIB_Status_AppMod
)) {
4286 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4287 dib
->status
= DIB_Status_InSync
;
4292 case DIB_Status_InSync
:
4293 TRACE("Unlocking in status InSync\n" );
4294 /* DIB was already protected in Coerce */
4297 case DIB_Status_AppMod
:
4298 TRACE("Unlocking in status AppMod\n" );
4299 /* DIB was already protected in Coerce */
4300 /* this case is ordinary only called from the signal handler,
4301 * so we don't bother to check for !commit */
4304 case DIB_Status_AuxMod
:
4305 TRACE("Unlocking in status AuxMod\n" );
4307 /* DIB may need protection now */
4308 if ((dib
->p_status
== DIB_Status_InSync
) ||
4309 (dib
->p_status
== DIB_Status_AppMod
))
4310 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
4312 /* no commit, revert to previous state */
4313 if (dib
->p_status
!= DIB_Status_None
)
4314 dib
->status
= dib
->p_status
;
4315 /* no protections changed */
4317 dib
->p_status
= DIB_Status_None
;
4320 LeaveCriticalSection(&(dib
->lock
));
4321 TRACE("Unlocked %p\n", bmp
);
4325 /***********************************************************************
4326 * X11DRV_CoerceDIBSection2
4328 INT
X11DRV_CoerceDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
4333 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4334 if (!bmp
) return DIB_Status_None
;
4335 ret
= X11DRV_DIB_Coerce(bmp
, req
, lossy
);
4336 GDI_ReleaseObj( hBmp
);
4340 /***********************************************************************
4341 * X11DRV_LockDIBSection2
4343 INT
X11DRV_LockDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
4348 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4349 if (!bmp
) return DIB_Status_None
;
4350 ret
= X11DRV_DIB_Lock(bmp
, req
, lossy
);
4351 GDI_ReleaseObj( hBmp
);
4355 /***********************************************************************
4356 * X11DRV_UnlockDIBSection2
4358 void X11DRV_UnlockDIBSection2(HBITMAP hBmp
, BOOL commit
)
4362 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4364 X11DRV_DIB_Unlock(bmp
, commit
);
4365 GDI_ReleaseObj( hBmp
);
4368 /***********************************************************************
4369 * X11DRV_CoerceDIBSection
4371 INT
X11DRV_CoerceDIBSection(X11DRV_PDEVICE
*physDev
, INT req
, BOOL lossy
)
4373 if (!physDev
) return DIB_Status_None
;
4374 return X11DRV_CoerceDIBSection2( physDev
->dc
->hBitmap
, req
, lossy
);
4377 /***********************************************************************
4378 * X11DRV_LockDIBSection
4380 INT
X11DRV_LockDIBSection(X11DRV_PDEVICE
*physDev
, INT req
, BOOL lossy
)
4382 if (!physDev
) return DIB_Status_None
;
4383 if (GetObjectType( physDev
->hdc
) != OBJ_MEMDC
) return DIB_Status_None
;
4385 return X11DRV_LockDIBSection2( physDev
->dc
->hBitmap
, req
, lossy
);
4388 /***********************************************************************
4389 * X11DRV_UnlockDIBSection
4391 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE
*physDev
, BOOL commit
)
4393 if (!physDev
) return;
4394 if (GetObjectType( physDev
->hdc
) != OBJ_MEMDC
) return;
4396 X11DRV_UnlockDIBSection2( physDev
->dc
->hBitmap
, commit
);
4400 #ifdef HAVE_LIBXXSHM
4401 /***********************************************************************
4402 * X11DRV_XShmErrorHandler
4405 static int XShmErrorHandler( Display
*dpy
, XErrorEvent
*event
, void *arg
)
4407 return 1; /* FIXME: should check event contents */
4410 /***********************************************************************
4411 * X11DRV_XShmCreateImage
4414 static XImage
*X11DRV_XShmCreateImage( int width
, int height
, int bpp
,
4415 XShmSegmentInfo
* shminfo
)
4419 image
= XShmCreateImage(gdi_display
, visual
, bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
4422 shminfo
->shmid
= shmget(IPC_PRIVATE
, image
->bytes_per_line
* height
,
4424 if( shminfo
->shmid
!= -1 )
4426 shminfo
->shmaddr
= image
->data
= shmat(shminfo
->shmid
, 0, 0);
4427 if( shminfo
->shmaddr
!= (char*)-1 )
4431 shminfo
->readOnly
= FALSE
;
4432 X11DRV_expect_error( gdi_display
, XShmErrorHandler
, NULL
);
4433 ok
= (XShmAttach( gdi_display
, shminfo
) != 0);
4434 XSync( gdi_display
, False
);
4435 if (X11DRV_check_error()) ok
= FALSE
;
4438 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
4439 return image
; /* Success! */
4441 /* An error occurred */
4442 shmdt(shminfo
->shmaddr
);
4444 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
4446 XFlush(gdi_display
);
4447 XDestroyImage(image
);
4452 #endif /* HAVE_LIBXXSHM */
4455 /***********************************************************************
4456 * X11DRV_DIB_CreateDIBSection
4458 HBITMAP
X11DRV_DIB_CreateDIBSection(
4459 X11DRV_PDEVICE
*physDev
, BITMAPINFO
*bmi
, UINT usage
,
4460 LPVOID
*bits
, HANDLE section
,
4461 DWORD offset
, DWORD ovr_pitch
)
4464 BITMAPOBJ
*bmp
= NULL
;
4465 X11DRV_DIBSECTION
*dib
= NULL
;
4466 int *colorMap
= NULL
;
4469 /* Fill BITMAP32 structure with DIB data */
4470 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
4471 INT effHeight
, totalSize
;
4473 LPVOID mapBits
= NULL
;
4475 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
4476 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
4477 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
4479 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
4481 bm
.bmWidth
= bi
->biWidth
;
4482 bm
.bmHeight
= effHeight
;
4483 bm
.bmWidthBytes
= ovr_pitch
? ovr_pitch
4484 : DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
4485 bm
.bmPlanes
= bi
->biPlanes
;
4486 bm
.bmBitsPixel
= bi
->biBitCount
;
4489 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
4490 we're dealing with a compressed bitmap. Otherwise, use width * height. */
4491 totalSize
= bi
->biSizeImage
&& bi
->biCompression
!= BI_RGB
4492 ? bi
->biSizeImage
: bm
.bmWidthBytes
* effHeight
;
4496 SYSTEM_INFO SystemInfo
;
4500 GetSystemInfo( &SystemInfo
);
4501 mapOffset
= offset
- (offset
% SystemInfo
.dwAllocationGranularity
);
4502 mapSize
= totalSize
+ (offset
- mapOffset
);
4503 mapBits
= MapViewOfFile( section
,
4504 FILE_MAP_ALL_ACCESS
,
4508 bm
.bmBits
= (char *)mapBits
+ (offset
- mapOffset
);
4510 else if (ovr_pitch
&& offset
)
4511 bm
.bmBits
= (LPVOID
) offset
;
4514 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
4515 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
4518 /* Create Color Map */
4519 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8)
4520 colorMap
= X11DRV_DIB_BuildColorMap( usage
== DIB_PAL_COLORS
? physDev
: NULL
,
4521 usage
, bm
.bmBitsPixel
, bmi
, &nColorMap
);
4523 /* Allocate Memory for DIB and fill structure */
4525 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
4528 dib
->dibSection
.dsBm
= bm
;
4529 dib
->dibSection
.dsBmih
= *bi
;
4530 dib
->dibSection
.dsBmih
.biSizeImage
= totalSize
;
4532 /* Set dsBitfields values */
4533 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
4535 dib
->dibSection
.dsBitfields
[0] = dib
->dibSection
.dsBitfields
[1] = dib
->dibSection
.dsBitfields
[2] = 0;
4537 else switch( bi
->biBitCount
)
4541 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
4542 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
4543 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f;
4548 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff0000;
4549 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x00ff00;
4550 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x0000ff;
4553 dib
->dibSection
.dshSection
= section
;
4554 dib
->dibSection
.dsOffset
= offset
;
4556 dib
->status
= DIB_Status_None
;
4557 dib
->nColorMap
= nColorMap
;
4558 dib
->colorMap
= colorMap
;
4561 /* Create Device Dependent Bitmap and add DIB pointer */
4564 res
= CreateDIBitmap(physDev
->hdc
, bi
, 0, NULL
, bmi
, usage
);
4567 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
4568 if (bmp
) bmp
->dib
= (DIBSECTION
*) dib
;
4576 #ifdef HAVE_LIBXXSHM
4577 if (XShmQueryExtension(gdi_display
) &&
4578 (dib
->image
= X11DRV_XShmCreateImage( bm
.bmWidth
, effHeight
,
4579 bmp
->bitmap
.bmBitsPixel
, &dib
->shminfo
)) )
4581 ; /* Created Image */
4583 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
4584 dib
->shminfo
.shmid
= -1;
4587 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
4589 wine_tsx11_unlock();
4592 /* Clean up in case of errors */
4593 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
4595 TRACE("got an error res=%p, bmp=%p, dib=%p, bm.bmBits=%p\n",
4596 res
, bmp
, dib
, bm
.bmBits
);
4600 UnmapViewOfFile(mapBits
), bm
.bmBits
= NULL
;
4602 VirtualFree(bm
.bmBits
, 0L, MEM_RELEASE
), bm
.bmBits
= NULL
;
4605 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
4606 if (colorMap
) { HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
; }
4607 if (dib
) { HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
; }
4608 if (bmp
) { GDI_ReleaseObj(res
); bmp
= NULL
; }
4609 if (res
) { DeleteObject(res
); res
= 0; }
4613 extern BOOL
VIRTUAL_SetFaultHandler(LPCVOID addr
, BOOL (*proc
)(LPVOID
, LPCVOID
), LPVOID arg
);
4614 /* Install fault handler, if possible */
4615 InitializeCriticalSection(&(dib
->lock
));
4616 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
4618 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4619 if (dib
) dib
->status
= DIB_Status_AppMod
;
4623 /* Return BITMAP handle and storage location */
4624 if (bmp
) GDI_ReleaseObj(res
);
4625 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
4629 /***********************************************************************
4630 * X11DRV_DIB_DeleteDIBSection
4632 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
4634 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4639 #ifdef HAVE_LIBXXSHM
4640 if (dib
->shminfo
.shmid
!= -1)
4642 XShmDetach (gdi_display
, &(dib
->shminfo
));
4643 XDestroyImage (dib
->image
);
4644 shmdt (dib
->shminfo
.shmaddr
);
4645 dib
->shminfo
.shmid
= -1;
4649 XDestroyImage( dib
->image
);
4650 wine_tsx11_unlock();
4654 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
4656 DeleteCriticalSection(&(dib
->lock
));
4659 /***********************************************************************
4660 * SetDIBColorTable (X11DRV.@)
4662 UINT
X11DRV_SetDIBColorTable( X11DRV_PDEVICE
*physDev
, UINT start
, UINT count
, const RGBQUAD
*colors
)
4665 X11DRV_DIBSECTION
*dib
;
4668 if (!(bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( physDev
->dc
->hBitmap
, BITMAP_MAGIC
))) return 0;
4669 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4671 if (dib
&& dib
->colorMap
) {
4672 UINT end
= count
+ start
;
4673 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
4675 * Changing color table might change the mapping between
4676 * DIB colors and X11 colors and thus alter the visible state
4677 * of the bitmap object.
4679 X11DRV_DIB_Lock(bmp
, DIB_Status_AppMod
, FALSE
);
4680 X11DRV_DIB_GenColorMap( physDev
, dib
->colorMap
, DIB_RGB_COLORS
,
4681 dib
->dibSection
.dsBm
.bmBitsPixel
,
4682 TRUE
, colors
, start
, end
);
4683 X11DRV_DIB_Unlock(bmp
, TRUE
);
4686 GDI_ReleaseObj( physDev
->dc
->hBitmap
);
4690 /***********************************************************************
4691 * GetDIBColorTable (X11DRV.@)
4693 UINT
X11DRV_GetDIBColorTable( X11DRV_PDEVICE
*physDev
, UINT start
, UINT count
, RGBQUAD
*colors
)
4696 X11DRV_DIBSECTION
*dib
;
4699 if (!(bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( physDev
->dc
->hBitmap
, BITMAP_MAGIC
))) return 0;
4700 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4702 if (dib
&& dib
->colorMap
) {
4703 UINT i
, end
= count
+ start
;
4704 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
4705 for (i
= start
; i
< end
; i
++,colors
++) {
4706 COLORREF col
= X11DRV_PALETTE_ToLogical( dib
->colorMap
[i
] );
4707 colors
->rgbBlue
= GetBValue(col
);
4708 colors
->rgbGreen
= GetGValue(col
);
4709 colors
->rgbRed
= GetRValue(col
);
4710 colors
->rgbReserved
= 0;
4714 GDI_ReleaseObj( physDev
->dc
->hBitmap
);
4719 /**************************************************************************
4720 * X11DRV_DIB_CreateDIBFromPixmap
4722 * Allocates a packed DIB and copies the Pixmap data into it.
4723 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
4725 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
, BOOL bDeletePixmap
)
4728 BITMAPOBJ
*pBmp
= NULL
;
4729 HGLOBAL hPackedDIB
= 0;
4731 /* Allocates an HBITMAP which references the Pixmap passed to us */
4732 hBmp
= X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap
);
4735 TRACE("\tCould not create bitmap header for Pixmap\n");
4740 * Create a packed DIB from the Pixmap wrapper bitmap created above.
4741 * A packed DIB contains a BITMAPINFO structure followed immediately by
4742 * an optional color palette and the pixel data.
4744 hPackedDIB
= DIB_CreateDIBFromBitmap(hdc
, hBmp
);
4746 /* Get a pointer to the BITMAPOBJ structure */
4747 pBmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4749 /* We can now get rid of the HBITMAP wrapper we created earlier.
4750 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
4754 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
4755 pBmp
->physBitmap
= NULL
;
4758 GDI_ReleaseObj( hBmp
);
4762 TRACE("\tReturning packed DIB %p\n", hPackedDIB
);
4767 /**************************************************************************
4768 * X11DRV_DIB_CreatePixmapFromDIB
4770 * Creates a Pixmap from a packed DIB
4772 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
4774 Pixmap pixmap
= None
;
4776 BITMAPOBJ
*pBmp
= NULL
;
4777 LPBYTE pPackedDIB
= NULL
;
4778 LPBITMAPINFO pbmi
= NULL
;
4779 LPBITMAPINFOHEADER pbmiHeader
= NULL
;
4780 LPBYTE pbits
= NULL
;
4782 /* Get a pointer to the packed DIB's data */
4783 pPackedDIB
= (LPBYTE
)GlobalLock(hPackedDIB
);
4784 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
4785 pbmi
= (LPBITMAPINFO
)pPackedDIB
;
4786 pbits
= (LPBYTE
)(pPackedDIB
4787 + DIB_BitmapInfoSize( (LPBITMAPINFO
)pbmiHeader
, DIB_RGB_COLORS
));
4789 /* Create a DDB from the DIB */
4791 hBmp
= CreateDIBitmap(hdc
,
4798 GlobalUnlock(hPackedDIB
);
4800 TRACE("CreateDIBitmap returned %p\n", hBmp
);
4802 /* Retrieve the internal Pixmap from the DDB */
4804 pBmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4806 pixmap
= (Pixmap
)pBmp
->physBitmap
;
4807 /* clear the physBitmap so that we can steal its pixmap */
4808 pBmp
->physBitmap
= NULL
;
4811 /* Delete the DDB we created earlier now that we have stolen its pixmap */
4812 GDI_ReleaseObj( hBmp
);
4815 TRACE("\tReturning Pixmap %ld\n", pixmap
);