2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <X11/extensions/XShm.h>
26 # ifdef HAVE_SYS_SHM_H
29 # ifdef HAVE_SYS_IPC_H
32 #endif /* defined(HAVE_LIBXXSHM) */
41 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(bitmap
);
44 WINE_DECLARE_DEBUG_CHANNEL(x11drv
);
46 static int ximageDepthTable
[32];
48 /* This structure holds the arguments for DIB_SetImageBits() */
51 X11DRV_PDEVICE
*physDev
;
54 PALETTEENTRY
*palentry
;
75 } X11DRV_DIB_IMAGEBITS_DESCR
;
80 RLE_EOL
= 0, /* End of line */
81 RLE_END
= 1, /* End of bitmap */
82 RLE_DELTA
= 2 /* Delta */
85 /***********************************************************************
86 * X11DRV_DIB_GetXImageWidthBytes
88 * Return the width of an X image in bytes
90 inline static int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
92 if (!depth
|| depth
> 32) goto error
;
94 if (!ximageDepthTable
[depth
-1])
96 XImage
*testimage
= XCreateImage( gdi_display
, visual
, depth
,
97 ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
100 ximageDepthTable
[depth
-1] = testimage
->bits_per_pixel
;
101 XDestroyImage( testimage
);
103 else ximageDepthTable
[depth
-1] = -1;
105 if (ximageDepthTable
[depth
-1] != -1)
106 return (4 * ((width
* ximageDepthTable
[depth
-1] + 31) / 32));
109 WARN( "(%d): Unsupported depth\n", depth
);
114 /***********************************************************************
115 * X11DRV_DIB_GetDIBWidthBytes
117 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
119 static int X11DRV_DIB_GetDIBWidthBytes( int width
, int depth
)
125 case 1: words
= (width
+ 31) / 32; break;
126 case 4: words
= (width
+ 7) / 8; break;
127 case 8: words
= (width
+ 3) / 4; break;
129 case 16: words
= (width
+ 1) / 2; break;
130 case 24: words
= (width
* 3 + 3) / 4; break;
132 WARN("(%d): Unsupported depth\n", depth
);
141 /***********************************************************************
142 * X11DRV_DIB_BitmapInfoSize
144 * Return the size of the bitmap info structure including color table.
146 int X11DRV_DIB_BitmapInfoSize( const BITMAPINFO
* info
, WORD coloruse
)
150 if (info
->bmiHeader
.biSize
== sizeof(BITMAPCOREHEADER
))
152 BITMAPCOREHEADER
*core
= (BITMAPCOREHEADER
*)info
;
153 colors
= (core
->bcBitCount
<= 8) ? 1 << core
->bcBitCount
: 0;
154 return sizeof(BITMAPCOREHEADER
) + colors
*
155 ((coloruse
== DIB_RGB_COLORS
) ? sizeof(RGBTRIPLE
) : sizeof(WORD
));
157 else /* assume BITMAPINFOHEADER */
159 colors
= info
->bmiHeader
.biClrUsed
;
160 if (!colors
&& (info
->bmiHeader
.biBitCount
<= 8))
161 colors
= 1 << info
->bmiHeader
.biBitCount
;
162 return sizeof(BITMAPINFOHEADER
) + colors
*
163 ((coloruse
== DIB_RGB_COLORS
) ? sizeof(RGBQUAD
) : sizeof(WORD
));
168 /***********************************************************************
169 * X11DRV_DIB_CreateXImage
173 XImage
*X11DRV_DIB_CreateXImage( int width
, int height
, int depth
)
179 width_bytes
= X11DRV_DIB_GetXImageWidthBytes( width
, depth
);
180 image
= XCreateImage( gdi_display
, visual
, depth
, ZPixmap
, 0,
181 calloc( height
, width_bytes
),
182 width
, height
, 32, width_bytes
);
188 /***********************************************************************
191 * Get the info from a bitmap header.
192 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
194 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER
*header
, DWORD
*width
,
195 int *height
, WORD
*bpp
, WORD
*compr
)
197 if (header
->biSize
== sizeof(BITMAPCOREHEADER
))
199 BITMAPCOREHEADER
*core
= (BITMAPCOREHEADER
*)header
;
200 *width
= core
->bcWidth
;
201 *height
= core
->bcHeight
;
202 *bpp
= core
->bcBitCount
;
206 if (header
->biSize
>= sizeof(BITMAPINFOHEADER
))
208 *width
= header
->biWidth
;
209 *height
= header
->biHeight
;
210 *bpp
= header
->biBitCount
;
211 *compr
= header
->biCompression
;
214 ERR("(%ld): unknown/wrong size for header\n", header
->biSize
);
219 /***********************************************************************
220 * X11DRV_DIB_GenColorMap
222 * Fills the color map of a bitmap palette. Should not be called
223 * for a >8-bit deep bitmap.
225 int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE
*physDev
, int *colorMapping
,
226 WORD coloruse
, WORD depth
, BOOL quads
,
227 const void *colorPtr
, int start
, int end
)
231 if (coloruse
== DIB_RGB_COLORS
)
233 int max
= 1 << depth
;
235 if (end
> max
) end
= max
;
239 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
241 if (depth
== 1) /* Monochrome */
242 for (i
= start
; i
< end
; i
++, rgb
++)
243 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
244 rgb
->rgbBlue
> 255*3/2);
246 for (i
= start
; i
< end
; i
++, rgb
++)
247 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, RGB(rgb
->rgbRed
,
253 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
255 if (depth
== 1) /* Monochrome */
256 for (i
= start
; i
< end
; i
++, rgb
++)
257 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
258 rgb
->rgbtBlue
> 255*3/2);
260 for (i
= start
; i
< end
; i
++, rgb
++)
261 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, RGB(rgb
->rgbtRed
,
266 else /* DIB_PAL_COLORS */
269 WORD
* index
= (WORD
*)colorPtr
;
271 for (i
= start
; i
< end
; i
++, index
++)
272 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, PALETTEINDEX(*index
) );
274 for (i
= start
; i
< end
; i
++)
275 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, PALETTEINDEX(i
) );
282 /***********************************************************************
283 * X11DRV_DIB_BuildColorMap
285 * Build the color map from the bitmap palette. Should not be called
286 * for a >8-bit deep bitmap.
288 int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE
*physDev
, WORD coloruse
, WORD depth
,
289 const BITMAPINFO
*info
, int *nColors
)
293 const void *colorPtr
;
296 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
298 colors
= info
->bmiHeader
.biClrUsed
;
299 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
300 colorPtr
= info
->bmiColors
;
302 else /* assume BITMAPCOREINFO */
304 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
305 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
310 ERR("called with >256 colors!\n");
314 /* just so CopyDIBSection doesn't have to create an identity palette */
315 if (coloruse
== (WORD
)-1) colorPtr
= NULL
;
317 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
318 colors
* sizeof(int) )))
322 return X11DRV_DIB_GenColorMap( physDev
, colorMapping
, coloruse
, depth
,
323 isInfo
, colorPtr
, 0, colors
);
327 /***********************************************************************
328 * X11DRV_DIB_MapColor
330 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
, int oldcol
)
334 if ((oldcol
< nPhysMap
) && (physMap
[oldcol
] == phys
))
337 for (color
= 0; color
< nPhysMap
; color
++)
338 if (physMap
[color
] == phys
)
341 WARN("Strange color %08x\n", phys
);
346 /*********************************************************************
347 * X11DRV_DIB_GetNearestIndex
349 * Helper for X11DRV_DIB_GetDIBits.
350 * Returns the nearest colour table index for a given RGB.
351 * Nearest is defined by minimizing the sum of the squares.
353 static INT
X11DRV_DIB_GetNearestIndex(RGBQUAD
*colormap
, int numColors
, BYTE r
, BYTE g
, BYTE b
)
355 INT i
, best
= -1, diff
, bestdiff
= -1;
358 for(color
= colormap
, i
= 0; i
< numColors
; color
++, i
++) {
359 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
360 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
361 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
364 if(best
== -1 || diff
< bestdiff
) {
371 /*********************************************************************
372 * X11DRV_DIB_MaskToShift
374 * Helper for X11DRV_DIB_GetDIBits.
375 * Returns the by how many bits to shift a given color so that it is
376 * in the proper position.
378 INT
X11DRV_DIB_MaskToShift(DWORD mask
)
386 while ((mask
&1)==0) {
393 /***********************************************************************
394 * X11DRV_DIB_SetImageBits_1
396 * SetDIBits for a 1-bit deep DIB.
398 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
399 DWORD srcwidth
, DWORD dstwidth
, int left
,
400 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
409 srcbits
= srcbits
+ linebytes
* (lines
- 1);
410 linebytes
= -linebytes
;
413 if ((extra
= (left
& 7)) != 0) {
417 srcbits
+= left
>> 3;
419 /* ==== pal 1 dib -> any bmp format ==== */
420 for (h
= lines
-1; h
>=0; h
--) {
422 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
423 for (i
= dstwidth
/8, x
= left
; i
> 0; i
--) {
425 XPutPixel( bmpImage
, x
++, h
, colors
[ srcval
>> 7] );
426 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 6) & 1] );
427 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 5) & 1] );
428 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 4) & 1] );
429 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 3) & 1] );
430 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 2) & 1] );
431 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 1) & 1] );
432 XPutPixel( bmpImage
, x
++, h
, colors
[ srcval
& 1] );
436 switch (dstwidth
& 7)
438 case 7: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
439 case 6: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
440 case 5: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
441 case 4: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
442 case 3: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
443 case 2: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
444 case 1: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]);
447 srcbits
+= linebytes
;
451 /***********************************************************************
452 * X11DRV_DIB_GetImageBits_1
454 * GetDIBits for a 1-bit deep DIB.
456 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
457 DWORD dstwidth
, DWORD srcwidth
,
458 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
459 XImage
*bmpImage
, DWORD linebytes
)
466 dstbits
= dstbits
+ linebytes
* (lines
- 1);
467 linebytes
= -linebytes
;
470 switch (bmpImage
->depth
)
474 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
475 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
478 for (h
=lines
-1; h
>=0; h
--) {
482 for (x
=0; x
<dstwidth
; x
++) {
484 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
485 dstval
|=(X11DRV_DIB_GetNearestIndex
489 srcval
.peBlue
) << (7 - (x
& 7)));
495 if ((dstwidth
&7)!=0) {
498 dstbits
+= linebytes
;
506 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
507 /* ==== pal 8 bmp -> pal 1 dib ==== */
509 const BYTE
* srcpixel
;
512 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
514 for (h
=0; h
<lines
; h
++) {
519 for (x
=0; x
<dstwidth
; x
++) {
521 srcval
=srccolors
[(int)*srcpixel
++];
522 dstval
|=(X11DRV_DIB_GetNearestIndex
526 srcval
.peBlue
) << (7-(x
&7)) );
532 if ((dstwidth
&7)!=0) {
535 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
536 dstbits
+= linebytes
;
547 const WORD
* srcpixel
;
550 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
552 if (bmpImage
->green_mask
==0x03e0) {
553 if (bmpImage
->red_mask
==0x7c00) {
554 /* ==== rgb 555 bmp -> pal 1 dib ==== */
555 for (h
=0; h
<lines
; h
++) {
560 for (x
=0; x
<dstwidth
; x
++) {
563 dstval
|=(X11DRV_DIB_GetNearestIndex
565 ((srcval
>> 7) & 0xf8) | /* r */
566 ((srcval
>> 12) & 0x07),
567 ((srcval
>> 2) & 0xf8) | /* g */
568 ((srcval
>> 7) & 0x07),
569 ((srcval
<< 3) & 0xf8) | /* b */
570 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
576 if ((dstwidth
&7)!=0) {
579 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
580 dstbits
+= linebytes
;
582 } else if (bmpImage
->blue_mask
==0x7c00) {
583 /* ==== bgr 555 bmp -> pal 1 dib ==== */
584 for (h
=0; h
<lines
; h
++) {
589 for (x
=0; x
<dstwidth
; x
++) {
592 dstval
|=(X11DRV_DIB_GetNearestIndex
594 ((srcval
<< 3) & 0xf8) | /* r */
595 ((srcval
>> 2) & 0x07),
596 ((srcval
>> 2) & 0xf8) | /* g */
597 ((srcval
>> 7) & 0x07),
598 ((srcval
>> 7) & 0xf8) | /* b */
599 ((srcval
>> 12) & 0x07) ) << (7-(x
&7)) );
605 if ((dstwidth
&7)!=0) {
608 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
609 dstbits
+= linebytes
;
614 } else if (bmpImage
->green_mask
==0x07e0) {
615 if (bmpImage
->red_mask
==0xf800) {
616 /* ==== rgb 565 bmp -> pal 1 dib ==== */
617 for (h
=0; h
<lines
; h
++) {
622 for (x
=0; x
<dstwidth
; x
++) {
625 dstval
|=(X11DRV_DIB_GetNearestIndex
627 ((srcval
>> 8) & 0xf8) | /* r */
628 ((srcval
>> 13) & 0x07),
629 ((srcval
>> 3) & 0xfc) | /* g */
630 ((srcval
>> 9) & 0x03),
631 ((srcval
<< 3) & 0xf8) | /* b */
632 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
638 if ((dstwidth
&7)!=0) {
641 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
642 dstbits
+= linebytes
;
644 } else if (bmpImage
->blue_mask
==0xf800) {
645 /* ==== bgr 565 bmp -> pal 1 dib ==== */
646 for (h
=0; h
<lines
; h
++) {
651 for (x
=0; x
<dstwidth
; x
++) {
654 dstval
|=(X11DRV_DIB_GetNearestIndex
656 ((srcval
<< 3) & 0xf8) | /* r */
657 ((srcval
>> 2) & 0x07),
658 ((srcval
>> 3) & 0xfc) | /* g */
659 ((srcval
>> 9) & 0x03),
660 ((srcval
>> 8) & 0xf8) | /* b */
661 ((srcval
>> 13) & 0x07) ) << (7-(x
&7)) );
667 if ((dstwidth
&7)!=0) {
670 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
671 dstbits
+= linebytes
;
690 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
691 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
693 if (bmpImage
->green_mask
!=0x00ff00 ||
694 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
696 } else if (bmpImage
->blue_mask
==0xff) {
697 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
698 for (h
=0; h
<lines
; h
++) {
703 for (x
=0; x
<dstwidth
; x
++) {
704 dstval
|=(X11DRV_DIB_GetNearestIndex
708 srcbyte
[0]) << (7-(x
&7)) );
709 srcbyte
+=bytes_per_pixel
;
715 if ((dstwidth
&7)!=0) {
718 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
719 dstbits
+= linebytes
;
722 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
723 for (h
=0; h
<lines
; h
++) {
728 for (x
=0; x
<dstwidth
; x
++) {
729 dstval
|=(X11DRV_DIB_GetNearestIndex
733 srcbyte
[2]) << (7-(x
&7)) );
734 srcbyte
+=bytes_per_pixel
;
740 if ((dstwidth
&7)!=0) {
743 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
744 dstbits
+= linebytes
;
754 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
756 /* ==== any bmp format -> pal 1 dib ==== */
757 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
758 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
759 bmpImage
->green_mask
, bmpImage
->blue_mask
);
761 for (h
=lines
-1; h
>=0; h
--) {
765 for (x
=0; x
<dstwidth
; x
++) {
766 dstval
|=(XGetPixel( bmpImage
, x
, h
) >= white
) << (7 - (x
&7));
772 if ((dstwidth
&7)!=0) {
775 dstbits
+= linebytes
;
782 /***********************************************************************
783 * X11DRV_DIB_SetImageBits_4
785 * SetDIBits for a 4-bit deep DIB.
787 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
788 DWORD srcwidth
, DWORD dstwidth
, int left
,
789 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
797 srcbits
= srcbits
+ linebytes
* (lines
- 1);
798 linebytes
= -linebytes
;
805 srcbits
+= left
>> 1;
807 /* ==== pal 4 dib -> any bmp format ==== */
808 for (h
= lines
-1; h
>= 0; h
--) {
810 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
811 BYTE srcval
=*srcbyte
++;
812 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
>> 4] );
813 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
& 0x0f] );
816 XPutPixel( bmpImage
, x
, h
, colors
[*srcbyte
>> 4] );
817 srcbits
+= linebytes
;
823 /***********************************************************************
824 * X11DRV_DIB_GetImageBits_4
826 * GetDIBits for a 4-bit deep DIB.
828 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
829 DWORD srcwidth
, DWORD dstwidth
,
830 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
831 XImage
*bmpImage
, DWORD linebytes
)
840 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
841 linebytes
= -linebytes
;
846 switch (bmpImage
->depth
) {
849 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
850 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
853 for (h
= lines
-1; h
>= 0; h
--) {
857 for (x
= 0; x
< dstwidth
; x
++) {
859 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
860 dstval
|=(X11DRV_DIB_GetNearestIndex
864 srcval
.peBlue
) << (4-((x
&1)<<2)));
870 if ((dstwidth
&1)!=0) {
873 dstbits
+= linebytes
;
881 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
882 /* ==== pal 8 bmp -> pal 4 dib ==== */
884 const BYTE
*srcpixel
;
887 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
888 for (h
=0; h
<lines
; h
++) {
893 for (x
=0; x
<dstwidth
; x
++) {
895 srcval
= srccolors
[(int)*srcpixel
++];
896 dstval
|=(X11DRV_DIB_GetNearestIndex
900 srcval
.peBlue
) << (4*(1-(x
&1))) );
906 if ((dstwidth
&1)!=0) {
909 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
910 dstbits
+= linebytes
;
921 const WORD
* srcpixel
;
924 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
926 if (bmpImage
->green_mask
==0x03e0) {
927 if (bmpImage
->red_mask
==0x7c00) {
928 /* ==== rgb 555 bmp -> pal 4 dib ==== */
929 for (h
=0; h
<lines
; h
++) {
934 for (x
=0; x
<dstwidth
; x
++) {
937 dstval
|=(X11DRV_DIB_GetNearestIndex
939 ((srcval
>> 7) & 0xf8) | /* r */
940 ((srcval
>> 12) & 0x07),
941 ((srcval
>> 2) & 0xf8) | /* g */
942 ((srcval
>> 7) & 0x07),
943 ((srcval
<< 3) & 0xf8) | /* b */
944 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
950 if ((dstwidth
&1)!=0) {
953 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
954 dstbits
+= linebytes
;
956 } else if (bmpImage
->blue_mask
==0x7c00) {
957 /* ==== bgr 555 bmp -> pal 4 dib ==== */
958 for (h
=0; h
<lines
; h
++) {
963 for (x
=0; x
<dstwidth
; x
++) {
966 dstval
|=(X11DRV_DIB_GetNearestIndex
968 ((srcval
<< 3) & 0xf8) | /* r */
969 ((srcval
>> 2) & 0x07),
970 ((srcval
>> 2) & 0xf8) | /* g */
971 ((srcval
>> 7) & 0x07),
972 ((srcval
>> 7) & 0xf8) | /* b */
973 ((srcval
>> 12) & 0x07) ) << ((1-(x
&1))<<2) );
979 if ((dstwidth
&1)!=0) {
982 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
983 dstbits
+= linebytes
;
988 } else if (bmpImage
->green_mask
==0x07e0) {
989 if (bmpImage
->red_mask
==0xf800) {
990 /* ==== rgb 565 bmp -> pal 4 dib ==== */
991 for (h
=0; h
<lines
; h
++) {
996 for (x
=0; x
<dstwidth
; x
++) {
999 dstval
|=(X11DRV_DIB_GetNearestIndex
1001 ((srcval
>> 8) & 0xf8) | /* r */
1002 ((srcval
>> 13) & 0x07),
1003 ((srcval
>> 3) & 0xfc) | /* g */
1004 ((srcval
>> 9) & 0x03),
1005 ((srcval
<< 3) & 0xf8) | /* b */
1006 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
1012 if ((dstwidth
&1)!=0) {
1015 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1016 dstbits
+= linebytes
;
1018 } else if (bmpImage
->blue_mask
==0xf800) {
1019 /* ==== bgr 565 bmp -> pal 4 dib ==== */
1020 for (h
=0; h
<lines
; h
++) {
1025 for (x
=0; x
<dstwidth
; x
++) {
1028 dstval
|=(X11DRV_DIB_GetNearestIndex
1030 ((srcval
<< 3) & 0xf8) | /* r */
1031 ((srcval
>> 2) & 0x07),
1032 ((srcval
>> 3) & 0xfc) | /* g */
1033 ((srcval
>> 9) & 0x03),
1034 ((srcval
>> 8) & 0xf8) | /* b */
1035 ((srcval
>> 13) & 0x07) ) << ((1-(x
&1))<<2) );
1041 if ((dstwidth
&1)!=0) {
1044 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1045 dstbits
+= linebytes
;
1057 if (bmpImage
->bits_per_pixel
==24) {
1058 const void* srcbits
;
1059 const BYTE
*srcbyte
;
1062 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1064 if (bmpImage
->green_mask
!=0x00ff00 ||
1065 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1067 } else if (bmpImage
->blue_mask
==0xff) {
1068 /* ==== rgb 888 bmp -> pal 4 dib ==== */
1069 for (h
=0; h
<lines
; h
++) {
1072 for (x
=0; x
<dstwidth
/2; x
++) {
1073 /* Do 2 pixels at a time */
1074 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1079 X11DRV_DIB_GetNearestIndex
1087 /* And the the odd pixel */
1088 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1094 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1095 dstbits
+= linebytes
;
1098 /* ==== bgr 888 bmp -> pal 4 dib ==== */
1099 for (h
=0; h
<lines
; h
++) {
1102 for (x
=0; x
<dstwidth
/2; x
++) {
1103 /* Do 2 pixels at a time */
1104 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1109 X11DRV_DIB_GetNearestIndex
1117 /* And the the odd pixel */
1118 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1124 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1125 dstbits
+= linebytes
;
1134 const void* srcbits
;
1135 const BYTE
*srcbyte
;
1138 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1140 if (bmpImage
->green_mask
!=0x00ff00 ||
1141 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1143 } else if (bmpImage
->blue_mask
==0xff) {
1144 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
1145 for (h
=0; h
<lines
; h
++) {
1148 for (x
=0; x
<dstwidth
/2; x
++) {
1149 /* Do 2 pixels at a time */
1150 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1155 X11DRV_DIB_GetNearestIndex
1163 /* And the the odd pixel */
1164 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1170 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1171 dstbits
+= linebytes
;
1174 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
1175 for (h
=0; h
<lines
; h
++) {
1178 for (x
=0; x
<dstwidth
/2; x
++) {
1179 /* Do 2 pixels at a time */
1180 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1185 X11DRV_DIB_GetNearestIndex
1193 /* And the the odd pixel */
1194 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
1200 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1201 dstbits
+= linebytes
;
1212 /* ==== any bmp format -> pal 4 dib ==== */
1213 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
1214 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
1215 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1216 for (h
=lines
-1; h
>=0; h
--) {
1218 for (x
=0; x
<(dstwidth
& ~1); x
+=2) {
1219 *dstbyte
++=(X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4) |
1220 X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
+1, h
), 0);
1223 *dstbyte
=(X11DRV_DIB_MapColor((int *)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4);
1225 dstbits
+= linebytes
;
1232 /***********************************************************************
1233 * X11DRV_DIB_SetImageBits_RLE4
1235 * SetDIBits for a 4-bit deep compressed DIB.
1237 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
1238 DWORD width
, DWORD dstwidth
,
1239 int left
, int *colors
,
1242 int x
= 0, y
= lines
- 1, c
, length
;
1243 const BYTE
*begin
= bits
;
1248 if (length
) { /* encoded */
1251 if (x
>= width
) break;
1252 XPutPixel(bmpImage
, x
++, y
, colors
[c
>> 4]);
1253 if (!length
--) break;
1254 if (x
>= width
) break;
1255 XPutPixel(bmpImage
, x
++, y
, colors
[c
& 0xf]);
1274 default: /* absolute */
1277 if (x
< width
) XPutPixel(bmpImage
, x
++, y
, colors
[c
>> 4]);
1278 if (!length
--) break;
1279 if (x
< width
) XPutPixel(bmpImage
, x
++, y
, colors
[c
& 0xf]);
1281 if ((bits
- begin
) & 1)
1290 /***********************************************************************
1291 * X11DRV_DIB_SetImageBits_8
1293 * SetDIBits for an 8-bit deep DIB.
1295 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
1296 DWORD srcwidth
, DWORD dstwidth
, int left
,
1297 const int *colors
, XImage
*bmpImage
,
1302 const BYTE
* srcbyte
;
1308 srcbits
= srcbits
+ linebytes
* (lines
-1);
1309 linebytes
= -linebytes
;
1314 switch (bmpImage
->depth
) {
1317 #if defined(__i386__) && defined(__GNUC__)
1318 /* Some X servers might have 32 bit/ 16bit deep pixel */
1319 if (lines
&& dstwidth
&& (bmpImage
->bits_per_pixel
== 16) &&
1320 (ImageByteOrder(gdi_display
)==LSBFirst
) )
1322 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
1323 /* FIXME: Does this really handle all these cases correctly? */
1324 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
1325 for (h
= lines
; h
--; ) {
1326 int _cl1
,_cl2
; /* temp outputs for asm below */
1327 /* Borrowed from DirectDraw */
1328 __asm__
__volatile__(
1333 " movw (%%edx,%%eax,4),%%ax\n"
1335 " xor %%eax,%%eax\n"
1337 :"=S" (srcbyte
), "=D" (_cl1
), "=c" (_cl2
)
1342 :"eax", "cc", "memory"
1344 srcbyte
= (srcbits
+= linebytes
);
1345 dstbits
-= bmpImage
->bytes_per_line
;
1353 #if defined(__i386__) && defined(__GNUC__)
1354 if (lines
&& dstwidth
&& (bmpImage
->bits_per_pixel
== 32) &&
1355 (ImageByteOrder(gdi_display
)==LSBFirst
) )
1357 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
1358 /* FIXME: Does this really handle both cases correctly? */
1359 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
1360 for (h
= lines
; h
--; ) {
1361 int _cl1
,_cl2
; /* temp outputs for asm below */
1362 /* Borrowed from DirectDraw */
1363 __asm__
__volatile__(
1368 " movl (%%edx,%%eax,4),%%eax\n"
1370 " xor %%eax,%%eax\n"
1372 :"=S" (srcbyte
), "=D" (_cl1
), "=c" (_cl2
)
1377 :"eax", "cc", "memory"
1379 srcbyte
= (srcbits
+= linebytes
);
1380 dstbits
-= bmpImage
->bytes_per_line
;
1387 break; /* use slow generic case below */
1390 /* ==== pal 8 dib -> any bmp format ==== */
1391 for (h
=lines
-1; h
>=0; h
--) {
1392 for (x
=left
; x
<dstwidth
+left
; x
++) {
1393 XPutPixel(bmpImage
, x
, h
, colors
[*srcbyte
++]);
1395 srcbyte
= (srcbits
+= linebytes
);
1399 /***********************************************************************
1400 * X11DRV_DIB_GetImageBits_8
1402 * GetDIBits for an 8-bit deep DIB.
1404 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
1405 DWORD srcwidth
, DWORD dstwidth
,
1406 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
1407 XImage
*bmpImage
, DWORD linebytes
)
1416 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
1417 linebytes
= -linebytes
;
1422 * This condition is true when GetImageBits has been called by
1423 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
1424 * 256 colormaps, so we'll just use for for GetDIBits calls.
1425 * (In somes cases, in a updateDIBSection, the returned colors are bad too)
1427 if (!srccolors
) goto updatesection
;
1429 switch (bmpImage
->depth
) {
1432 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
1434 /* ==== pal 1 bmp -> pal 8 dib ==== */
1435 /* ==== pal 4 bmp -> pal 8 dib ==== */
1436 for (h
=lines
-1; h
>=0; h
--) {
1438 for (x
=0; x
<dstwidth
; x
++) {
1439 PALETTEENTRY srcval
;
1440 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
1441 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
1446 dstbits
+= linebytes
;
1454 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
1455 /* ==== pal 8 bmp -> pal 8 dib ==== */
1456 const void* srcbits
;
1457 const BYTE
* srcpixel
;
1459 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1460 for (h
=0; h
<lines
; h
++) {
1463 for (x
= 0; x
< dstwidth
; x
++) {
1464 PALETTEENTRY srcval
;
1465 srcval
=srccolors
[(int)*srcpixel
++];
1466 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
1471 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1472 dstbits
+= linebytes
;
1482 const void* srcbits
;
1483 const WORD
* srcpixel
;
1486 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1488 if (bmpImage
->green_mask
==0x03e0) {
1489 if (bmpImage
->red_mask
==0x7c00) {
1490 /* ==== rgb 555 bmp -> pal 8 dib ==== */
1491 for (h
=0; h
<lines
; h
++) {
1494 for (x
=0; x
<dstwidth
; x
++) {
1497 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1499 ((srcval
>> 7) & 0xf8) | /* r */
1500 ((srcval
>> 12) & 0x07),
1501 ((srcval
>> 2) & 0xf8) | /* g */
1502 ((srcval
>> 7) & 0x07),
1503 ((srcval
<< 3) & 0xf8) | /* b */
1504 ((srcval
>> 2) & 0x07) );
1506 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1507 dstbits
+= linebytes
;
1509 } else if (bmpImage
->blue_mask
==0x7c00) {
1510 /* ==== bgr 555 bmp -> pal 8 dib ==== */
1511 for (h
=0; h
<lines
; h
++) {
1514 for (x
=0; x
<dstwidth
; x
++) {
1517 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1519 ((srcval
<< 3) & 0xf8) | /* r */
1520 ((srcval
>> 2) & 0x07),
1521 ((srcval
>> 2) & 0xf8) | /* g */
1522 ((srcval
>> 7) & 0x07),
1523 ((srcval
>> 7) & 0xf8) | /* b */
1524 ((srcval
>> 12) & 0x07) );
1526 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1527 dstbits
+= linebytes
;
1532 } else if (bmpImage
->green_mask
==0x07e0) {
1533 if (bmpImage
->red_mask
==0xf800) {
1534 /* ==== rgb 565 bmp -> pal 8 dib ==== */
1535 for (h
=0; h
<lines
; h
++) {
1538 for (x
=0; x
<dstwidth
; x
++) {
1541 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1543 ((srcval
>> 8) & 0xf8) | /* r */
1544 ((srcval
>> 13) & 0x07),
1545 ((srcval
>> 3) & 0xfc) | /* g */
1546 ((srcval
>> 9) & 0x03),
1547 ((srcval
<< 3) & 0xf8) | /* b */
1548 ((srcval
>> 2) & 0x07) );
1550 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1551 dstbits
+= linebytes
;
1553 } else if (bmpImage
->blue_mask
==0xf800) {
1554 /* ==== bgr 565 bmp -> pal 8 dib ==== */
1555 for (h
=0; h
<lines
; h
++) {
1558 for (x
=0; x
<dstwidth
; x
++) {
1561 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1563 ((srcval
<< 3) & 0xf8) | /* r */
1564 ((srcval
>> 2) & 0x07),
1565 ((srcval
>> 3) & 0xfc) | /* g */
1566 ((srcval
>> 9) & 0x03),
1567 ((srcval
>> 8) & 0xf8) | /* b */
1568 ((srcval
>> 13) & 0x07) );
1570 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1571 dstbits
+= linebytes
;
1585 const void* srcbits
;
1586 const BYTE
*srcbyte
;
1588 int bytes_per_pixel
;
1590 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1591 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
1593 if (bmpImage
->green_mask
!=0x00ff00 ||
1594 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1596 } else if (bmpImage
->blue_mask
==0xff) {
1597 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
1598 for (h
=0; h
<lines
; h
++) {
1601 for (x
=0; x
<dstwidth
; x
++) {
1602 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1607 srcbyte
+=bytes_per_pixel
;
1609 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1610 dstbits
+= linebytes
;
1613 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
1614 for (h
=0; h
<lines
; h
++) {
1617 for (x
=0; x
<dstwidth
; x
++) {
1618 *dstbyte
++=X11DRV_DIB_GetNearestIndex
1623 srcbyte
+=bytes_per_pixel
;
1625 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1626 dstbits
+= linebytes
;
1634 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
1635 bmpImage
->depth
, bmpImage
->red_mask
,
1636 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1638 /* ==== any bmp format -> pal 8 dib ==== */
1639 for (h
=lines
-1; h
>=0; h
--) {
1641 for (x
=0; x
<dstwidth
; x
++) {
1642 *dstbyte
=X11DRV_DIB_MapColor
1644 XGetPixel(bmpImage
, x
, h
), *dstbyte
);
1647 dstbits
+= linebytes
;
1653 /***********************************************************************
1654 * X11DRV_DIB_SetImageBits_RLE8
1656 * SetDIBits for an 8-bit deep compressed DIB.
1658 * This function rewritten 941113 by James Youngman. WINE blew out when I
1659 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1661 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1662 * 'End of bitmap' escape code. This code is very much laxer in what it
1663 * allows to end the expansion. Possibly too lax. See the note by
1664 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1665 * bitmap should end with RleEnd, but on the other hand, software exists
1666 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1669 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1670 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1673 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
1674 DWORD width
, DWORD dstwidth
,
1675 int left
, int *colors
,
1678 int x
; /* X-positon on each line. Increases. */
1679 int y
; /* Line #. Starts at lines-1, decreases */
1680 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
1681 BYTE length
; /* The length pf a run */
1682 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
1685 * Note that the bitmap data is stored by Windows starting at the
1686 * bottom line of the bitmap and going upwards. Within each line,
1687 * the data is stored left-to-right. That's the reason why line
1688 * goes from lines-1 to 0. [JAY]
1698 * If the length byte is not zero (which is the escape value),
1699 * We have a run of length pixels all the same colour. The colour
1700 * index is stored next.
1702 * If the length byte is zero, we need to read the next byte to
1703 * know what to do. [JAY]
1708 * [Run-Length] Encoded mode
1710 int color
= colors
[*pIn
++];
1711 while (length
-- && x
< dstwidth
) XPutPixel(bmpImage
, x
++, y
, color
);
1716 * Escape codes (may be an absolute sequence though)
1718 escape_code
= (*pIn
++);
1727 /* Not all RLE8 bitmaps end with this code. For
1728 * example, Paint Shop Pro produces some that don't.
1729 * That's (I think) what caused the previous
1730 * implementation to fail. [JAY]
1739 default: /* switch to absolute mode */
1740 length
= escape_code
;
1743 int color
= colors
[*pIn
++];
1749 XPutPixel(bmpImage
, x
++, y
, color
);
1752 * If you think for a moment you'll realise that the
1753 * only time we could ever possibly read an odd
1754 * number of bytes is when there is a 0x00 (escape),
1755 * a value >0x02 (absolute mode) and then an odd-
1756 * length run. Therefore this is the only place we
1757 * need to worry about it. Everywhere else the
1758 * bytes are always read in pairs. [JAY]
1760 if (escape_code
& 1) pIn
++; /* Throw away the pad byte. */
1762 } /* switch (escape_code) : Escape sequence */
1768 /***********************************************************************
1769 * X11DRV_DIB_SetImageBits_16
1771 * SetDIBits for a 16-bit deep DIB.
1773 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
1774 DWORD srcwidth
, DWORD dstwidth
, int left
,
1775 X11DRV_PDEVICE
*physDev
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
1776 XImage
*bmpImage
, DWORD linebytes
)
1780 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
1785 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
1786 linebytes
= -linebytes
;
1789 switch (bmpImage
->depth
)
1796 srcbits
=srcbits
+left
*2;
1797 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
1799 if (bmpImage
->green_mask
==0x03e0) {
1800 if (gSrc
==bmpImage
->green_mask
) {
1801 if (rSrc
==bmpImage
->red_mask
) {
1802 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
1803 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
1804 convs
->Convert_5x5_asis
1807 dstbits
,-bmpImage
->bytes_per_line
);
1808 } else if (rSrc
==bmpImage
->blue_mask
) {
1809 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
1810 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
1811 convs
->Convert_555_reverse
1814 dstbits
,-bmpImage
->bytes_per_line
);
1817 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
1818 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
1819 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
1820 convs
->Convert_565_to_555_asis
1823 dstbits
,-bmpImage
->bytes_per_line
);
1825 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
1826 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
1827 convs
->Convert_565_to_555_reverse
1830 dstbits
,-bmpImage
->bytes_per_line
);
1833 } else if (bmpImage
->green_mask
==0x07e0) {
1834 if (gSrc
==bmpImage
->green_mask
) {
1835 if (rSrc
==bmpImage
->red_mask
) {
1836 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
1837 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
1838 convs
->Convert_5x5_asis
1841 dstbits
,-bmpImage
->bytes_per_line
);
1843 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
1844 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
1845 convs
->Convert_565_reverse
1848 dstbits
,-bmpImage
->bytes_per_line
);
1851 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
1852 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
1853 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
1854 convs
->Convert_555_to_565_asis
1857 dstbits
,-bmpImage
->bytes_per_line
);
1859 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
1860 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
1861 convs
->Convert_555_to_565_reverse
1864 dstbits
,-bmpImage
->bytes_per_line
);
1874 if (bmpImage
->bits_per_pixel
==24) {
1877 srcbits
=srcbits
+left
*2;
1878 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
1880 if (bmpImage
->green_mask
!=0x00ff00 ||
1881 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1883 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
1884 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
1886 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
1887 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
1888 convs
->Convert_555_to_888_asis
1891 dstbits
,-bmpImage
->bytes_per_line
);
1893 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
1894 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
1895 convs
->Convert_565_to_888_asis
1898 dstbits
,-bmpImage
->bytes_per_line
);
1902 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
1903 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
1904 convs
->Convert_555_to_888_reverse
1907 dstbits
,-bmpImage
->bytes_per_line
);
1909 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
1910 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
1911 convs
->Convert_565_to_888_reverse
1914 dstbits
,-bmpImage
->bytes_per_line
);
1925 srcbits
=srcbits
+left
*2;
1926 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
1928 if (bmpImage
->green_mask
!=0x00ff00 ||
1929 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1931 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
1932 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
1934 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
1935 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
1936 convs
->Convert_555_to_0888_asis
1939 dstbits
,-bmpImage
->bytes_per_line
);
1941 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
1942 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
1943 convs
->Convert_565_to_0888_asis
1946 dstbits
,-bmpImage
->bytes_per_line
);
1950 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
1951 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
1952 convs
->Convert_555_to_0888_reverse
1955 dstbits
,-bmpImage
->bytes_per_line
);
1957 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
1958 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
1959 convs
->Convert_565_to_0888_reverse
1962 dstbits
,-bmpImage
->bytes_per_line
);
1970 WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
1971 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
1972 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1978 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
1979 const WORD
* srcpixel
;
1980 int rShift1
,gShift1
,bShift1
;
1981 int rShift2
,gShift2
,bShift2
;
1984 /* Set color scaling values */
1985 rShift1
=16+X11DRV_DIB_MaskToShift(rSrc
)-3;
1986 gShift1
=16+X11DRV_DIB_MaskToShift(gSrc
)-3;
1987 bShift1
=16+X11DRV_DIB_MaskToShift(bSrc
)-3;
1992 /* Green has 5 bits, like the others */
1996 /* Green has 6 bits, not 5. Compensate. */
2005 /* We could split it into four separate cases to optimize
2006 * but it is probably not worth it.
2008 for (h
=lines
-1; h
>=0; h
--) {
2009 srcpixel
=(const WORD
*)srcbits
;
2010 for (x
=left
; x
<dstwidth
+left
; x
++) {
2012 BYTE red
,green
,blue
;
2013 srcval
=*srcpixel
++ << 16;
2014 red
= ((srcval
>> rShift1
) & 0xf8) |
2015 ((srcval
>> rShift2
) & 0x07);
2016 green
=((srcval
>> gShift1
) & gMask1
) |
2017 ((srcval
>> gShift2
) & gMask2
);
2018 blue
= ((srcval
>> bShift1
) & 0xf8) |
2019 ((srcval
>> bShift2
) & 0x07);
2020 XPutPixel(bmpImage
, x
, h
,
2021 X11DRV_PALETTE_ToPhysical
2022 (physDev
, RGB(red
,green
,blue
)));
2024 srcbits
+= linebytes
;
2032 /***********************************************************************
2033 * X11DRV_DIB_GetImageBits_16
2035 * GetDIBits for an 16-bit deep DIB.
2037 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*dstbits
,
2038 DWORD dstwidth
, DWORD srcwidth
,
2039 PALETTEENTRY
*srccolors
,
2040 DWORD rDst
, DWORD gDst
, DWORD bDst
,
2041 XImage
*bmpImage
, DWORD dibpitch
)
2045 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
2047 DWORD linebytes
= dibpitch
;
2052 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
2053 linebytes
= -linebytes
;
2056 switch (bmpImage
->depth
)
2061 const char* srcbits
;
2063 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2065 if (bmpImage
->green_mask
==0x03e0) {
2066 if (gDst
==bmpImage
->green_mask
) {
2067 if (rDst
==bmpImage
->red_mask
) {
2068 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
2069 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
2070 convs
->Convert_5x5_asis
2072 srcbits
,-bmpImage
->bytes_per_line
,
2075 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
2076 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
2077 convs
->Convert_555_reverse
2079 srcbits
,-bmpImage
->bytes_per_line
,
2083 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
2084 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
2085 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
2086 convs
->Convert_555_to_565_asis
2088 srcbits
,-bmpImage
->bytes_per_line
,
2091 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
2092 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
2093 convs
->Convert_555_to_565_reverse
2095 srcbits
,-bmpImage
->bytes_per_line
,
2099 } else if (bmpImage
->green_mask
==0x07e0) {
2100 if (gDst
==bmpImage
->green_mask
) {
2101 if (rDst
== bmpImage
->red_mask
) {
2102 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
2103 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
2104 convs
->Convert_5x5_asis
2106 srcbits
,-bmpImage
->bytes_per_line
,
2109 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
2110 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
2111 convs
->Convert_565_reverse
2113 srcbits
,-bmpImage
->bytes_per_line
,
2117 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
2118 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
2119 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
2120 convs
->Convert_565_to_555_asis
2122 srcbits
,-bmpImage
->bytes_per_line
,
2125 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
2126 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
2127 convs
->Convert_565_to_555_reverse
2129 srcbits
,-bmpImage
->bytes_per_line
,
2140 if (bmpImage
->bits_per_pixel
== 24) {
2141 const char* srcbits
;
2143 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2145 if (bmpImage
->green_mask
!=0x00ff00 ||
2146 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2148 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
2149 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
2151 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
2152 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
2153 convs
->Convert_888_to_555_asis
2155 srcbits
,-bmpImage
->bytes_per_line
,
2158 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2159 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2160 convs
->Convert_888_to_565_asis
2162 srcbits
,-bmpImage
->bytes_per_line
,
2167 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
2168 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
2169 convs
->Convert_888_to_555_reverse
2171 srcbits
,-bmpImage
->bytes_per_line
,
2174 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
2175 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
2176 convs
->Convert_888_to_565_reverse
2178 srcbits
,-bmpImage
->bytes_per_line
,
2188 const char* srcbits
;
2190 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2192 if (bmpImage
->green_mask
!=0x00ff00 ||
2193 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2195 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
2196 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
2198 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
2199 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
2200 convs
->Convert_0888_to_555_asis
2202 srcbits
,-bmpImage
->bytes_per_line
,
2205 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
2206 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
2207 convs
->Convert_0888_to_565_asis
2209 srcbits
,-bmpImage
->bytes_per_line
,
2214 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
2215 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
2216 convs
->Convert_0888_to_555_reverse
2218 srcbits
,-bmpImage
->bytes_per_line
,
2221 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
2222 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
2223 convs
->Convert_0888_to_565_reverse
2225 srcbits
,-bmpImage
->bytes_per_line
,
2234 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2235 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
2236 int rShift
,gShift
,bShift
;
2239 /* Shift everything 16 bits left so that all shifts are >0,
2240 * even for BGR DIBs. Then a single >> 16 will bring everything
2243 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2244 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2245 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2247 /* 6 bits for the green */
2253 for (h
= lines
- 1; h
>= 0; h
--) {
2254 dstpixel
=(LPWORD
)dstbits
;
2255 for (x
= 0; x
< dstwidth
; x
++) {
2256 PALETTEENTRY srcval
;
2258 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2259 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
2260 ((srcval
.peGreen
<< gShift
) & gDst
) |
2261 ((srcval
.peBlue
<< bShift
) & bDst
);
2262 *dstpixel
++=dstval
>> 16;
2264 dstbits
+= linebytes
;
2272 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2273 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
2274 int rShift
,gShift
,bShift
;
2275 const BYTE
* srcbits
;
2276 const BYTE
* srcpixel
;
2279 /* Shift everything 16 bits left so that all shifts are >0,
2280 * even for BGR DIBs. Then a single >> 16 will bring everything
2283 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2284 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2285 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2287 /* 6 bits for the green */
2293 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2294 for (h
=0; h
<lines
; h
++) {
2296 dstpixel
=(LPWORD
)dstbits
;
2297 for (x
= 0; x
< dstwidth
; x
++) {
2298 PALETTEENTRY srcval
;
2300 srcval
=srccolors
[(int)*srcpixel
++];
2301 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
2302 ((srcval
.peGreen
<< gShift
) & gDst
) |
2303 ((srcval
.peBlue
<< bShift
) & bDst
);
2304 *dstpixel
++=dstval
>> 16;
2306 srcbits
-= bmpImage
->bytes_per_line
;
2307 dstbits
+= linebytes
;
2317 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
2318 int rShift
,gShift
,bShift
;
2321 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
2322 bmpImage
->depth
, bmpImage
->red_mask
,
2323 bmpImage
->green_mask
, bmpImage
->blue_mask
,
2326 /* Shift everything 16 bits left so that all shifts are >0,
2327 * even for BGR DIBs. Then a single >> 16 will bring everything
2330 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
2331 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
2332 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
2334 /* 6 bits for the green */
2340 for (h
= lines
- 1; h
>= 0; h
--) {
2341 dstpixel
=(LPWORD
)dstbits
;
2342 for (x
= 0; x
< dstwidth
; x
++) {
2345 srcval
=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage
, x
, h
));
2346 dstval
=((GetRValue(srcval
) << rShift
) & rDst
) |
2347 ((GetGValue(srcval
) << gShift
) & gDst
) |
2348 ((GetBValue(srcval
) << bShift
) & bDst
);
2349 *dstpixel
++=dstval
>> 16;
2351 dstbits
+= linebytes
;
2359 /***********************************************************************
2360 * X11DRV_DIB_SetImageBits_24
2362 * SetDIBits for a 24-bit deep DIB.
2364 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
2365 DWORD srcwidth
, DWORD dstwidth
, int left
,
2366 X11DRV_PDEVICE
*physDev
,
2367 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
2368 XImage
*bmpImage
, DWORD linebytes
)
2372 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
2377 srcbits
= srcbits
+ linebytes
* (lines
- 1);
2378 linebytes
= -linebytes
;
2381 switch (bmpImage
->depth
)
2384 if (bmpImage
->bits_per_pixel
==24) {
2387 srcbits
=srcbits
+left
*3;
2388 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
2390 if (bmpImage
->green_mask
!=0x00ff00 ||
2391 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2393 } else if (rSrc
==bmpImage
->red_mask
) {
2394 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
2395 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
2396 convs
->Convert_888_asis
2399 dstbits
,-bmpImage
->bytes_per_line
);
2401 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
2402 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
2403 convs
->Convert_888_reverse
2406 dstbits
,-bmpImage
->bytes_per_line
);
2416 srcbits
=srcbits
+left
*3;
2417 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
2419 if (bmpImage
->green_mask
!=0x00ff00 ||
2420 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2422 } else if (rSrc
==bmpImage
->red_mask
) {
2423 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
2424 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
2425 convs
->Convert_888_to_0888_asis
2428 dstbits
,-bmpImage
->bytes_per_line
);
2430 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
2431 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
2432 convs
->Convert_888_to_0888_reverse
2435 dstbits
,-bmpImage
->bytes_per_line
);
2445 srcbits
=srcbits
+left
*3;
2446 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2448 if (bmpImage
->green_mask
==0x03e0) {
2449 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
2450 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
2451 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
2452 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
2453 convs
->Convert_888_to_555_asis
2456 dstbits
,-bmpImage
->bytes_per_line
);
2457 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0x7f00) ||
2458 (bSrc
==0xff && bmpImage
->blue_mask
==0x7f00)) {
2459 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
2460 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
2461 convs
->Convert_888_to_555_reverse
2464 dstbits
,-bmpImage
->bytes_per_line
);
2468 } else if (bmpImage
->green_mask
==0x07e0) {
2469 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
2470 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
2471 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
2472 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
2473 convs
->Convert_888_to_565_asis
2476 dstbits
,-bmpImage
->bytes_per_line
);
2477 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0xf800) ||
2478 (bSrc
==0xff && bmpImage
->blue_mask
==0xf800)) {
2479 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
2480 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
2481 convs
->Convert_888_to_565_reverse
2484 dstbits
,-bmpImage
->bytes_per_line
);
2496 WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2497 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
2498 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2504 /* ==== rgb 888 dib -> any bmp bormat ==== */
2505 const BYTE
* srcbyte
;
2507 /* Windows only supports one 24bpp DIB format: RGB888 */
2509 for (h
= lines
- 1; h
>= 0; h
--) {
2510 srcbyte
=(const BYTE
*)srcbits
;
2511 for (x
= left
; x
< dstwidth
+left
; x
++) {
2512 XPutPixel(bmpImage
, x
, h
,
2513 X11DRV_PALETTE_ToPhysical
2514 (physDev
, RGB(srcbyte
[2], srcbyte
[1], srcbyte
[0])));
2517 srcbits
+= linebytes
;
2525 /***********************************************************************
2526 * X11DRV_DIB_GetImageBits_24
2528 * GetDIBits for an 24-bit deep DIB.
2530 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*dstbits
,
2531 DWORD dstwidth
, DWORD srcwidth
,
2532 PALETTEENTRY
*srccolors
,
2533 DWORD rDst
, DWORD gDst
, DWORD bDst
,
2534 XImage
*bmpImage
, DWORD linebytes
)
2538 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
2543 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2544 linebytes
= -linebytes
;
2547 switch (bmpImage
->depth
)
2550 if (bmpImage
->bits_per_pixel
==24) {
2551 const char* srcbits
;
2553 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2555 if (bmpImage
->green_mask
!=0x00ff00 ||
2556 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2558 } else if (rDst
==bmpImage
->red_mask
) {
2559 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
2560 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
2561 convs
->Convert_888_asis
2563 srcbits
,-bmpImage
->bytes_per_line
,
2566 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
2567 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
2568 convs
->Convert_888_reverse
2570 srcbits
,-bmpImage
->bytes_per_line
,
2579 const char* srcbits
;
2581 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2583 if (bmpImage
->green_mask
!=0x00ff00 ||
2584 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2586 } else if (rDst
==bmpImage
->red_mask
) {
2587 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
2588 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
2589 convs
->Convert_0888_to_888_asis
2591 srcbits
,-bmpImage
->bytes_per_line
,
2594 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
2595 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
2596 convs
->Convert_0888_to_888_reverse
2598 srcbits
,-bmpImage
->bytes_per_line
,
2607 const char* srcbits
;
2609 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2611 if (bmpImage
->green_mask
==0x03e0) {
2612 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
2613 (bDst
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
2614 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
2615 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
2616 convs
->Convert_555_to_888_asis
2618 srcbits
,-bmpImage
->bytes_per_line
,
2620 } else if ((rDst
==0xff && bmpImage
->red_mask
==0x7f00) ||
2621 (bDst
==0xff && bmpImage
->blue_mask
==0x7f00)) {
2622 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
2623 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
2624 convs
->Convert_555_to_888_reverse
2626 srcbits
,-bmpImage
->bytes_per_line
,
2631 } else if (bmpImage
->green_mask
==0x07e0) {
2632 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
2633 (bDst
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
2634 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
2635 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
2636 convs
->Convert_565_to_888_asis
2638 srcbits
,-bmpImage
->bytes_per_line
,
2640 } else if ((rDst
==0xff && bmpImage
->red_mask
==0xf800) ||
2641 (bDst
==0xff && bmpImage
->blue_mask
==0xf800)) {
2642 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
2643 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
2644 convs
->Convert_565_to_888_reverse
2646 srcbits
,-bmpImage
->bytes_per_line
,
2659 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2660 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
2663 /* Windows only supports one 24bpp DIB format: rgb 888 */
2664 for (h
= lines
- 1; h
>= 0; h
--) {
2666 for (x
= 0; x
< dstwidth
; x
++) {
2667 PALETTEENTRY srcval
;
2668 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2669 dstbyte
[0]=srcval
.peBlue
;
2670 dstbyte
[1]=srcval
.peGreen
;
2671 dstbyte
[2]=srcval
.peRed
;
2674 dstbits
+= linebytes
;
2682 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
== 0 && srccolors
) {
2683 /* ==== pal 8 bmp -> rgb 888 dib ==== */
2684 const void* srcbits
;
2685 const BYTE
* srcpixel
;
2688 /* Windows only supports one 24bpp DIB format: rgb 888 */
2689 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2690 for (h
= lines
- 1; h
>= 0; h
--) {
2693 for (x
= 0; x
< dstwidth
; x
++ ) {
2694 PALETTEENTRY srcval
;
2695 srcval
=srccolors
[(int)*srcpixel
++];
2696 dstbyte
[0]=srcval
.peBlue
;
2697 dstbyte
[1]=srcval
.peGreen
;
2698 dstbyte
[2]=srcval
.peRed
;
2701 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2702 dstbits
+= linebytes
;
2712 /* ==== any bmp format -> 888 dib ==== */
2715 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
2716 bmpImage
->depth
, bmpImage
->red_mask
,
2717 bmpImage
->green_mask
, bmpImage
->blue_mask
,
2720 /* Windows only supports one 24bpp DIB format: rgb 888 */
2721 for (h
= lines
- 1; h
>= 0; h
--) {
2723 for (x
= 0; x
< dstwidth
; x
++) {
2724 COLORREF srcval
=X11DRV_PALETTE_ToLogical
2725 (XGetPixel( bmpImage
, x
, h
));
2726 dstbyte
[0]=GetBValue(srcval
);
2727 dstbyte
[1]=GetGValue(srcval
);
2728 dstbyte
[2]=GetRValue(srcval
);
2731 dstbits
+= linebytes
;
2739 /***********************************************************************
2740 * X11DRV_DIB_SetImageBits_32
2742 * SetDIBits for a 32-bit deep DIB.
2744 static void X11DRV_DIB_SetImageBits_32(int lines
, const BYTE
*srcbits
,
2745 DWORD srcwidth
, DWORD dstwidth
, int left
,
2746 X11DRV_PDEVICE
*physDev
,
2747 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
2753 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_dst_byteswap
;
2758 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
2759 linebytes
= -linebytes
;
2762 ptr
= (DWORD
*) srcbits
+ left
;
2764 switch (bmpImage
->depth
)
2767 if (bmpImage
->bits_per_pixel
==24) {
2770 srcbits
=srcbits
+left
*4;
2771 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
2773 if (rSrc
==bmpImage
->red_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->blue_mask
) {
2774 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
2775 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
2776 convs
->Convert_0888_to_888_asis
2779 dstbits
,-bmpImage
->bytes_per_line
);
2780 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2781 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2783 /* the tests below assume sane bmpImage masks */
2784 } else if (rSrc
==bmpImage
->blue_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->red_mask
) {
2785 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
2786 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
2787 convs
->Convert_0888_to_888_reverse
2790 dstbits
,-bmpImage
->bytes_per_line
);
2791 } else if (bmpImage
->blue_mask
==0xff) {
2792 /* ==== any 0888 dib -> rgb 888 bmp ==== */
2793 convs
->Convert_any0888_to_rgb888
2797 dstbits
,-bmpImage
->bytes_per_line
);
2799 /* ==== any 0888 dib -> bgr 888 bmp ==== */
2800 convs
->Convert_any0888_to_bgr888
2804 dstbits
,-bmpImage
->bytes_per_line
);
2814 srcbits
=srcbits
+left
*4;
2815 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
2817 if (gSrc
==bmpImage
->green_mask
) {
2818 if (rSrc
==bmpImage
->red_mask
&& bSrc
==bmpImage
->blue_mask
) {
2819 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
2820 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
2821 convs
->Convert_0888_asis
2824 dstbits
,-bmpImage
->bytes_per_line
);
2825 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2826 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2828 /* the tests below assume sane bmpImage masks */
2829 } else if (rSrc
==bmpImage
->blue_mask
&& bSrc
==bmpImage
->red_mask
) {
2830 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
2831 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
2832 convs
->Convert_0888_reverse
2835 dstbits
,-bmpImage
->bytes_per_line
);
2837 /* ==== any 0888 dib -> any 0888 bmp ==== */
2838 convs
->Convert_0888_any
2842 dstbits
,-bmpImage
->bytes_per_line
,
2843 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2845 } else if (bmpImage
->green_mask
!=0x00ff00 ||
2846 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2848 /* the tests below assume sane bmpImage masks */
2850 /* ==== any 0888 dib -> any 0888 bmp ==== */
2851 convs
->Convert_0888_any
2855 dstbits
,-bmpImage
->bytes_per_line
,
2856 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2866 srcbits
=srcbits
+left
*4;
2867 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2869 if (rSrc
==0xff0000 && gSrc
==0x00ff00 && bSrc
==0x0000ff) {
2870 if (bmpImage
->green_mask
==0x03e0) {
2871 if (bmpImage
->red_mask
==0x7f00) {
2872 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
2873 convs
->Convert_0888_to_555_asis
2876 dstbits
,-bmpImage
->bytes_per_line
);
2877 } else if (bmpImage
->blue_mask
==0x7f00) {
2878 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
2879 convs
->Convert_0888_to_555_reverse
2882 dstbits
,-bmpImage
->bytes_per_line
);
2886 } else if (bmpImage
->green_mask
==0x07e0) {
2887 if (bmpImage
->red_mask
==0xf800) {
2888 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
2889 convs
->Convert_0888_to_565_asis
2892 dstbits
,-bmpImage
->bytes_per_line
);
2893 } else if (bmpImage
->blue_mask
==0xf800) {
2894 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
2895 convs
->Convert_0888_to_565_reverse
2898 dstbits
,-bmpImage
->bytes_per_line
);
2905 } else if (rSrc
==0x0000ff && gSrc
==0x00ff00 && bSrc
==0xff0000) {
2906 if (bmpImage
->green_mask
==0x03e0) {
2907 if (bmpImage
->blue_mask
==0x7f00) {
2908 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
2909 convs
->Convert_0888_to_555_asis
2912 dstbits
,-bmpImage
->bytes_per_line
);
2913 } else if (bmpImage
->red_mask
==0x7f00) {
2914 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
2915 convs
->Convert_0888_to_555_reverse
2918 dstbits
,-bmpImage
->bytes_per_line
);
2922 } else if (bmpImage
->green_mask
==0x07e0) {
2923 if (bmpImage
->blue_mask
==0xf800) {
2924 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
2925 convs
->Convert_0888_to_565_asis
2928 dstbits
,-bmpImage
->bytes_per_line
);
2929 } else if (bmpImage
->red_mask
==0xf800) {
2930 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
2931 convs
->Convert_0888_to_565_reverse
2934 dstbits
,-bmpImage
->bytes_per_line
);
2942 if (bmpImage
->green_mask
==0x03e0 &&
2943 (bmpImage
->red_mask
==0x7f00 ||
2944 bmpImage
->blue_mask
==0x7f00)) {
2945 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
2946 convs
->Convert_any0888_to_5x5
2950 dstbits
,-bmpImage
->bytes_per_line
,
2951 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2952 } else if (bmpImage
->green_mask
==0x07e0 &&
2953 (bmpImage
->red_mask
==0xf800 ||
2954 bmpImage
->blue_mask
==0xf800)) {
2955 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
2956 convs
->Convert_any0888_to_5x5
2960 dstbits
,-bmpImage
->bytes_per_line
,
2961 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
2971 WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2972 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
2973 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2979 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
2980 const DWORD
* srcpixel
;
2981 int rShift
,gShift
,bShift
;
2983 rShift
=X11DRV_DIB_MaskToShift(rSrc
);
2984 gShift
=X11DRV_DIB_MaskToShift(gSrc
);
2985 bShift
=X11DRV_DIB_MaskToShift(bSrc
);
2987 for (h
= lines
- 1; h
>= 0; h
--) {
2988 srcpixel
=(const DWORD
*)srcbits
;
2989 for (x
= left
; x
< dstwidth
+left
; x
++) {
2991 BYTE red
,green
,blue
;
2992 srcvalue
=*srcpixel
++;
2993 red
= (srcvalue
>> rShift
) & 0xff;
2994 green
=(srcvalue
>> gShift
) & 0xff;
2995 blue
= (srcvalue
>> bShift
) & 0xff;
2996 XPutPixel(bmpImage
, x
, h
, X11DRV_PALETTE_ToPhysical
2997 (physDev
, RGB(red
,green
,blue
)));
2999 srcbits
+= linebytes
;
3007 /***********************************************************************
3008 * X11DRV_DIB_GetImageBits_32
3010 * GetDIBits for an 32-bit deep DIB.
3012 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*dstbits
,
3013 DWORD dstwidth
, DWORD srcwidth
,
3014 PALETTEENTRY
*srccolors
,
3015 DWORD rDst
, DWORD gDst
, DWORD bDst
,
3016 XImage
*bmpImage
, DWORD linebytes
)
3021 const dib_conversions
*convs
= (bmpImage
->byte_order
== LSBFirst
) ? &dib_normal
: &dib_src_byteswap
;
3026 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
3027 linebytes
= -linebytes
;
3032 switch (bmpImage
->depth
)
3035 if (bmpImage
->bits_per_pixel
==24) {
3036 const void* srcbits
;
3038 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3040 if (rDst
==bmpImage
->red_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->blue_mask
) {
3041 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3042 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3043 convs
->Convert_888_to_0888_asis
3045 srcbits
,-bmpImage
->bytes_per_line
,
3047 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3048 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3050 /* the tests below assume sane bmpImage masks */
3051 } else if (rDst
==bmpImage
->blue_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->red_mask
) {
3052 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3053 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3054 convs
->Convert_888_to_0888_reverse
3056 srcbits
,-bmpImage
->bytes_per_line
,
3058 } else if (bmpImage
->blue_mask
==0xff) {
3059 /* ==== rgb 888 bmp -> any 0888 dib ==== */
3060 convs
->Convert_rgb888_to_any0888
3062 srcbits
,-bmpImage
->bytes_per_line
,
3066 /* ==== bgr 888 bmp -> any 0888 dib ==== */
3067 convs
->Convert_bgr888_to_any0888
3069 srcbits
,-bmpImage
->bytes_per_line
,
3079 const char* srcbits
;
3081 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3083 if (gDst
==bmpImage
->green_mask
) {
3084 if (rDst
==bmpImage
->red_mask
&& bDst
==bmpImage
->blue_mask
) {
3085 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
3086 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
3087 convs
->Convert_0888_asis
3089 srcbits
,-bmpImage
->bytes_per_line
,
3091 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3092 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3094 /* the tests below assume sane bmpImage masks */
3095 } else if (rDst
==bmpImage
->blue_mask
&& bDst
==bmpImage
->red_mask
) {
3096 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
3097 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
3098 convs
->Convert_0888_reverse
3100 srcbits
,-bmpImage
->bytes_per_line
,
3103 /* ==== any 0888 bmp -> any 0888 dib ==== */
3104 convs
->Convert_0888_any
3106 srcbits
,-bmpImage
->bytes_per_line
,
3107 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3111 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3112 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3114 /* the tests below assume sane bmpImage masks */
3116 /* ==== any 0888 bmp -> any 0888 dib ==== */
3117 convs
->Convert_0888_any
3119 srcbits
,-bmpImage
->bytes_per_line
,
3120 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3130 const char* srcbits
;
3132 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3134 if (rDst
==0xff0000 && gDst
==0x00ff00 && bDst
==0x0000ff) {
3135 if (bmpImage
->green_mask
==0x03e0) {
3136 if (bmpImage
->red_mask
==0x7f00) {
3137 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
3138 convs
->Convert_555_to_0888_asis
3140 srcbits
,-bmpImage
->bytes_per_line
,
3142 } else if (bmpImage
->blue_mask
==0x7f00) {
3143 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
3144 convs
->Convert_555_to_0888_reverse
3146 srcbits
,-bmpImage
->bytes_per_line
,
3151 } else if (bmpImage
->green_mask
==0x07e0) {
3152 if (bmpImage
->red_mask
==0xf800) {
3153 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
3154 convs
->Convert_565_to_0888_asis
3156 srcbits
,-bmpImage
->bytes_per_line
,
3158 } else if (bmpImage
->blue_mask
==0xf800) {
3159 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
3160 convs
->Convert_565_to_0888_reverse
3162 srcbits
,-bmpImage
->bytes_per_line
,
3170 } else if (rDst
==0x0000ff && gDst
==0x00ff00 && bDst
==0xff0000) {
3171 if (bmpImage
->green_mask
==0x03e0) {
3172 if (bmpImage
->blue_mask
==0x7f00) {
3173 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
3174 convs
->Convert_555_to_0888_asis
3176 srcbits
,-bmpImage
->bytes_per_line
,
3178 } else if (bmpImage
->red_mask
==0x7f00) {
3179 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
3180 convs
->Convert_555_to_0888_reverse
3182 srcbits
,-bmpImage
->bytes_per_line
,
3187 } else if (bmpImage
->green_mask
==0x07e0) {
3188 if (bmpImage
->blue_mask
==0xf800) {
3189 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
3190 convs
->Convert_565_to_0888_asis
3192 srcbits
,-bmpImage
->bytes_per_line
,
3194 } else if (bmpImage
->red_mask
==0xf800) {
3195 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
3196 convs
->Convert_565_to_0888_reverse
3198 srcbits
,-bmpImage
->bytes_per_line
,
3207 if (bmpImage
->green_mask
==0x03e0 &&
3208 (bmpImage
->red_mask
==0x7f00 ||
3209 bmpImage
->blue_mask
==0x7f00)) {
3210 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
3211 convs
->Convert_5x5_to_any0888
3213 srcbits
,-bmpImage
->bytes_per_line
,
3214 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3217 } else if (bmpImage
->green_mask
==0x07e0 &&
3218 (bmpImage
->red_mask
==0xf800 ||
3219 bmpImage
->blue_mask
==0xf800)) {
3220 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
3221 convs
->Convert_5x5_to_any0888
3223 srcbits
,-bmpImage
->bytes_per_line
,
3224 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
3236 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3237 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
3238 int rShift
,gShift
,bShift
;
3241 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3242 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3243 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3244 for (h
= lines
- 1; h
>= 0; h
--) {
3245 dstpixel
=(DWORD
*)dstbits
;
3246 for (x
= 0; x
< dstwidth
; x
++) {
3247 PALETTEENTRY srcval
;
3248 srcval
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
3249 *dstpixel
++=(srcval
.peRed
<< rShift
) |
3250 (srcval
.peGreen
<< gShift
) |
3251 (srcval
.peBlue
<< bShift
);
3253 dstbits
+= linebytes
;
3261 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3262 /* ==== pal 8 bmp -> any 0888 dib ==== */
3263 int rShift
,gShift
,bShift
;
3264 const void* srcbits
;
3265 const BYTE
* srcpixel
;
3268 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3269 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3270 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3271 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3272 for (h
= lines
- 1; h
>= 0; h
--) {
3274 dstpixel
=(DWORD
*)dstbits
;
3275 for (x
= 0; x
< dstwidth
; x
++) {
3276 PALETTEENTRY srcval
;
3277 srcval
=srccolors
[(int)*srcpixel
++];
3278 *dstpixel
++=(srcval
.peRed
<< rShift
) |
3279 (srcval
.peGreen
<< gShift
) |
3280 (srcval
.peBlue
<< bShift
);
3282 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
3283 dstbits
+= linebytes
;
3293 /* ==== any bmp format -> any 0888 dib ==== */
3294 int rShift
,gShift
,bShift
;
3297 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
3298 bmpImage
->depth
, bmpImage
->red_mask
,
3299 bmpImage
->green_mask
, bmpImage
->blue_mask
,
3302 rShift
=X11DRV_DIB_MaskToShift(rDst
);
3303 gShift
=X11DRV_DIB_MaskToShift(gDst
);
3304 bShift
=X11DRV_DIB_MaskToShift(bDst
);
3305 for (h
= lines
- 1; h
>= 0; h
--) {
3306 dstpixel
=(DWORD
*)dstbits
;
3307 for (x
= 0; x
< dstwidth
; x
++) {
3309 srcval
=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage
, x
, h
));
3310 *dstpixel
++=(GetRValue(srcval
) << rShift
) |
3311 (GetGValue(srcval
) << gShift
) |
3312 (GetBValue(srcval
) << bShift
);
3314 dstbits
+= linebytes
;
3321 /***********************************************************************
3322 * X11DRV_DIB_SetImageBits
3324 * Transfer the bits to an X image.
3325 * Helper function for SetDIBits() and SetDIBitsToDevice().
3327 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
3329 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
3334 bmpImage
= descr
->image
;
3336 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
3337 descr
->infoWidth
, lines
, 32, 0 );
3338 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
3339 if(bmpImage
->data
== NULL
) {
3340 ERR("Out of memory!\n");
3341 XDestroyImage( bmpImage
);
3342 wine_tsx11_unlock();
3347 TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
3348 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
3349 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
3350 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
3351 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
3353 /* Transfer the pixels */
3354 switch(descr
->infoBpp
)
3357 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
3358 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
3359 bmpImage
, descr
->dibpitch
);
3362 if (descr
->compression
) {
3363 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
3364 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
3365 bmpImage
, descr
->xSrc
, descr
->ySrc
);
3367 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
3368 descr
->infoWidth
, descr
->width
,
3369 descr
->xSrc
, (int *)(descr
->colorMap
),
3372 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
3373 descr
->infoWidth
, descr
->width
,
3374 descr
->xSrc
, (int*)(descr
->colorMap
),
3375 bmpImage
, descr
->dibpitch
);
3378 if (descr
->compression
) {
3379 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
3380 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
3381 bmpImage
, descr
->xSrc
, descr
->ySrc
);
3382 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
3383 descr
->infoWidth
, descr
->width
,
3384 descr
->xSrc
, (int *)(descr
->colorMap
),
3387 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
3388 descr
->infoWidth
, descr
->width
,
3389 descr
->xSrc
, (int *)(descr
->colorMap
),
3390 bmpImage
, descr
->dibpitch
);
3394 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
3395 descr
->infoWidth
, descr
->width
,
3396 descr
->xSrc
, descr
->physDev
,
3397 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3398 bmpImage
, descr
->dibpitch
);
3401 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
3402 descr
->infoWidth
, descr
->width
,
3403 descr
->xSrc
, descr
->physDev
,
3404 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3405 bmpImage
, descr
->dibpitch
);
3408 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
3409 descr
->infoWidth
, descr
->width
,
3410 descr
->xSrc
, descr
->physDev
,
3411 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3412 bmpImage
, descr
->dibpitch
);
3415 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
3419 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
3420 descr
->drawable
, descr
->gc
, bmpImage
,
3421 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3422 descr
->width
, descr
->height
);
3423 #ifdef HAVE_LIBXXSHM
3426 XShmPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
3427 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3428 descr
->width
, descr
->height
, FALSE
);
3429 XSync( gdi_display
, 0 );
3433 XPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
3434 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
3435 descr
->width
, descr
->height
);
3437 if (!descr
->image
) XDestroyImage( bmpImage
);
3438 wine_tsx11_unlock();
3442 /***********************************************************************
3443 * X11DRV_DIB_GetImageBits
3445 * Transfer the bits from an X image.
3447 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
3449 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
3454 bmpImage
= descr
->image
;
3456 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
3457 descr
->infoWidth
, lines
, 32, 0 );
3458 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
3459 if(bmpImage
->data
== NULL
) {
3460 ERR("Out of memory!\n");
3461 XDestroyImage( bmpImage
);
3462 wine_tsx11_unlock();
3467 #ifdef HAVE_LIBXXSHM
3470 int saveRed
, saveGreen
, saveBlue
;
3472 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
3473 gdi_display
, descr
->drawable
, bmpImage
,
3474 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
3476 /* We must save and restore the bmpImage's masks in order
3477 * to preserve them across the call to XShmGetImage, which
3478 * decides to eleminate them since it doesn't happen to know
3479 * what the format of the image is supposed to be, even though
3481 saveRed
= bmpImage
->red_mask
;
3482 saveBlue
= bmpImage
->blue_mask
;
3483 saveGreen
= bmpImage
->green_mask
;
3485 XShmGetImage( gdi_display
, descr
->drawable
, bmpImage
,
3486 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
3488 bmpImage
->red_mask
= saveRed
;
3489 bmpImage
->blue_mask
= saveBlue
;
3490 bmpImage
->green_mask
= saveGreen
;
3493 #endif /* HAVE_LIBXXSHM */
3495 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
3496 gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
, descr
->width
,
3497 lines
, AllPlanes
, ZPixmap
, bmpImage
, descr
->xDest
, descr
->yDest
);
3498 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
,
3499 descr
->width
, lines
, AllPlanes
, ZPixmap
,
3500 bmpImage
, descr
->xDest
, descr
->yDest
);
3503 TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
3504 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
3505 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
3506 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
3507 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
3508 /* Transfer the pixels */
3509 switch(descr
->infoBpp
)
3512 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
3513 descr
->infoWidth
, descr
->width
,
3514 descr
->colorMap
, descr
->palentry
,
3515 bmpImage
, descr
->dibpitch
);
3519 if (descr
->compression
)
3520 FIXME("Compression not yet supported!\n");
3522 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
3523 descr
->infoWidth
, descr
->width
,
3524 descr
->colorMap
, descr
->palentry
,
3525 bmpImage
, descr
->dibpitch
);
3529 if (descr
->compression
)
3530 FIXME("Compression not yet supported!\n");
3532 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
3533 descr
->infoWidth
, descr
->width
,
3534 descr
->colorMap
, descr
->palentry
,
3535 bmpImage
, descr
->dibpitch
);
3539 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
3540 descr
->infoWidth
,descr
->width
,
3542 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3543 bmpImage
, descr
->dibpitch
);
3547 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
3548 descr
->infoWidth
,descr
->width
,
3550 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3551 bmpImage
, descr
->dibpitch
);
3555 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
3556 descr
->infoWidth
, descr
->width
,
3558 descr
->rMask
, descr
->gMask
, descr
->bMask
,
3559 bmpImage
, descr
->dibpitch
);
3563 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
3567 if (!descr
->image
) XDestroyImage( bmpImage
);
3568 wine_tsx11_unlock();
3572 /*************************************************************************
3573 * X11DRV_SetDIBitsToDevice
3576 INT
X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE
*physDev
, INT xDest
, INT yDest
, DWORD cx
,
3577 DWORD cy
, INT xSrc
, INT ySrc
,
3578 UINT startscan
, UINT lines
, LPCVOID bits
,
3579 const BITMAPINFO
*info
, UINT coloruse
)
3581 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3588 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
3589 &descr
.infoBpp
, &descr
.compression
) == -1)
3591 top_down
= (height
< 0);
3592 if (top_down
) height
= -height
;
3596 LPtoDP(physDev
->hdc
, &pt
, 1);
3598 if (!lines
|| (startscan
>= height
)) return 0;
3599 if (!top_down
&& startscan
+ lines
> height
) lines
= height
- startscan
;
3601 /* make xSrc,ySrc point to the upper-left corner, not the lower-left one,
3602 * and clamp all values to fit inside [startscan,startscan+lines]
3604 if (ySrc
+ cy
<= startscan
+ lines
)
3606 INT y
= startscan
+ lines
- (ySrc
+ cy
);
3607 if (ySrc
< startscan
) cy
-= (startscan
- ySrc
);
3610 /* avoid getting unnecessary lines */
3612 if (y
>= lines
) return 0;
3617 if (y
>= lines
) return lines
;
3618 ySrc
= y
; /* need to get all lines in top down mode */
3623 if (ySrc
>= startscan
+ lines
) return lines
;
3624 pt
.y
+= ySrc
+ cy
- (startscan
+ lines
);
3625 cy
= startscan
+ lines
- ySrc
;
3627 if (cy
> lines
) cy
= lines
;
3629 if (xSrc
>= width
) return lines
;
3630 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
3631 if (!cx
|| !cy
) return lines
;
3633 X11DRV_SetupGCForText( physDev
); /* To have the correct colors */
3635 XSetFunction(gdi_display
, physDev
->gc
, X11DRV_XROPfunction
[GetROP2(physDev
->hdc
) - 1]);
3636 wine_tsx11_unlock();
3638 switch (descr
.infoBpp
)
3643 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
3644 coloruse
== DIB_PAL_COLORS
? physDev
: NULL
, coloruse
,
3645 physDev
->depth
, info
, &descr
.nColorMap
);
3646 if (!descr
.colorMap
) return 0;
3647 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3651 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
3652 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
3653 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
3659 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
3660 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
3661 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
3666 descr
.physDev
= physDev
;
3669 descr
.palentry
= NULL
;
3670 descr
.lines
= top_down
? -lines
: lines
;
3671 descr
.infoWidth
= width
;
3672 descr
.depth
= physDev
->depth
;
3673 descr
.drawable
= physDev
->drawable
;
3674 descr
.gc
= physDev
->gc
;
3677 descr
.xDest
= physDev
->org
.x
+ pt
.x
;
3678 descr
.yDest
= physDev
->org
.y
+ pt
.y
;
3681 descr
.useShm
= FALSE
;
3682 descr
.dibpitch
= ((width
* descr
.infoBpp
+ 31) &~31) / 8;
3684 result
= X11DRV_DIB_SetImageBits( &descr
);
3686 if (descr
.infoBpp
<= 8)
3687 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
3691 /***********************************************************************
3692 * SetDIBits (X11DRV.@)
3694 INT
X11DRV_SetDIBits( X11DRV_PDEVICE
*physDev
, HBITMAP hbitmap
, UINT startscan
,
3695 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
, UINT coloruse
)
3697 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3699 int height
, tmpheight
;
3702 descr
.physDev
= physDev
;
3704 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
3705 &descr
.infoBpp
, &descr
.compression
) == -1)
3709 if (height
< 0) height
= -height
;
3710 if (!lines
|| (startscan
>= height
))
3713 if (!(bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
))) return 0;
3715 if (startscan
+ lines
> height
) lines
= height
- startscan
;
3717 switch (descr
.infoBpp
)
3722 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
3723 coloruse
== DIB_PAL_COLORS
? descr
.physDev
: NULL
, coloruse
,
3724 bmp
->bitmap
.bmBitsPixel
,
3725 info
, &descr
.nColorMap
);
3726 if (!descr
.colorMap
)
3728 GDI_ReleaseObj( hbitmap
);
3731 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3735 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
3736 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
3737 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
3743 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
3744 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
3745 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
3754 descr
.palentry
= NULL
;
3755 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
3756 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3757 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
3758 descr
.gc
= BITMAP_GC(bmp
);
3762 descr
.yDest
= height
- startscan
- lines
;
3763 descr
.width
= bmp
->bitmap
.bmWidth
;
3764 descr
.height
= lines
;
3765 descr
.useShm
= FALSE
;
3766 descr
.dibpitch
= ((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8;
3767 X11DRV_DIB_Lock(bmp
, DIB_Status_GdiMod
, FALSE
);
3768 result
= X11DRV_DIB_SetImageBits( &descr
);
3769 X11DRV_DIB_Unlock(bmp
, TRUE
);
3771 if (descr
.colorMap
) HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
3773 GDI_ReleaseObj( hbitmap
);
3777 /***********************************************************************
3778 * GetDIBits (X11DRV.@)
3780 INT
X11DRV_GetDIBits( X11DRV_PDEVICE
*physDev
, HBITMAP hbitmap
, UINT startscan
, UINT lines
,
3781 LPVOID bits
, BITMAPINFO
*info
, UINT coloruse
)
3783 X11DRV_DIBSECTION
*dib
;
3784 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3785 PALETTEENTRY palette
[256];
3789 GetPaletteEntries( GetCurrentObject( physDev
->hdc
, OBJ_PAL
), 0, 256, palette
);
3791 if (!(bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
))) return 0;
3793 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3795 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
3796 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
3797 (int)info
->bmiHeader
.biWidth
, (int)info
->bmiHeader
.biHeight
,
3800 if( lines
> bmp
->bitmap
.bmHeight
) lines
= bmp
->bitmap
.bmHeight
;
3802 height
= info
->bmiHeader
.biHeight
;
3803 if (height
< 0) height
= -height
;
3804 if( lines
> height
) lines
= height
;
3805 /* Top-down images have a negative biHeight, the scanlines of theses images
3806 * were inverted in X11DRV_DIB_GetImageBits_xx
3807 * To prevent this we simply change the sign of lines
3808 * (the number of scan lines to copy).
3809 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3811 if( info
->bmiHeader
.biHeight
< 0 && lines
> 0) lines
= -lines
;
3813 if( startscan
>= bmp
->bitmap
.bmHeight
)
3819 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &descr
.lines
,
3820 &descr
.infoBpp
, &descr
.compression
) == -1)
3826 switch (descr
.infoBpp
)
3831 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3835 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
3836 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
3837 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
3841 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
3842 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
3843 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
3847 descr
.physDev
= physDev
;
3848 descr
.palentry
= palette
;
3851 descr
.lines
= lines
;
3852 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3853 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
3854 descr
.gc
= BITMAP_GC(bmp
);
3855 descr
.width
= bmp
->bitmap
.bmWidth
;
3856 descr
.height
= bmp
->bitmap
.bmHeight
;
3857 descr
.colorMap
= info
->bmiColors
;
3862 if (descr
.lines
> 0)
3864 descr
.ySrc
= (descr
.height
-1) - (startscan
+ (lines
-1));
3868 descr
.ySrc
= startscan
;
3870 #ifdef HAVE_LIBXXSHM
3871 descr
.useShm
= dib
? (dib
->shminfo
.shmid
!= -1) : FALSE
;
3873 descr
.useShm
= FALSE
;
3875 descr
.dibpitch
= dib
? (dib
->dibSection
.dsBm
.bmWidthBytes
)
3876 : (((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8);
3878 X11DRV_DIB_Lock(bmp
, DIB_Status_GdiMod
, FALSE
);
3879 X11DRV_DIB_GetImageBits( &descr
);
3880 X11DRV_DIB_Unlock(bmp
, TRUE
);
3882 if(info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
3883 info
->bmiHeader
.biSizeImage
= X11DRV_DIB_GetDIBWidthBytes( info
->bmiHeader
.biWidth
,
3884 info
->bmiHeader
.biBitCount
)
3885 * abs( info
->bmiHeader
.biHeight
);
3887 if (descr
.compression
== BI_BITFIELDS
)
3889 *(DWORD
*)info
->bmiColors
= descr
.rMask
;
3890 *((DWORD
*)info
->bmiColors
+1) = descr
.gMask
;
3891 *((DWORD
*)info
->bmiColors
+2) = descr
.bMask
;
3895 /* if RLE or JPEG compression were supported,
3896 * this line would be invalid. */
3897 info
->bmiHeader
.biCompression
= 0;
3901 GDI_ReleaseObj( hbitmap
);
3905 /***********************************************************************
3906 * DIB_DoProtectDIBSection
3908 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
3910 DIBSECTION
*dib
= bmp
->dib
;
3911 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
3912 : -dib
->dsBm
.bmHeight
;
3913 /* use the biSizeImage data as the memory size only if we're dealing with a
3914 compressed image where the value is set. Otherwise, calculate based on
3916 INT totalSize
= dib
->dsBmih
.biSizeImage
&& dib
->dsBmih
.biCompression
!= BI_RGB
3917 ? dib
->dsBmih
.biSizeImage
3918 : dib
->dsBm
.bmWidthBytes
* effHeight
;
3921 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
3922 TRACE("Changed protection from %ld to %ld\n", old_prot
, new_prot
);
3925 /***********************************************************************
3926 * X11DRV_DIB_DoUpdateDIBSection
3928 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
,
3929 void *colorMap
, int nColorMap
,
3931 DWORD xSrc
, DWORD ySrc
,
3932 DWORD xDest
, DWORD yDest
,
3933 DWORD width
, DWORD height
)
3935 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3936 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3938 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, &descr
.lines
,
3939 &descr
.infoBpp
, &descr
.compression
) == -1)
3942 descr
.physDev
= NULL
;
3943 descr
.palentry
= NULL
;
3944 descr
.image
= dib
->image
;
3945 descr
.colorMap
= colorMap
;
3946 descr
.nColorMap
= nColorMap
;
3947 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
3948 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3950 switch (descr
.infoBpp
)
3955 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3959 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0x7c00;
3960 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x03e0;
3961 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x001f;
3966 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0xff0000;
3967 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x00ff00;
3968 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x0000ff;
3973 descr
.drawable
= dest
;
3974 descr
.gc
= BITMAP_GC(bmp
);
3977 descr
.xDest
= xDest
;
3978 descr
.yDest
= yDest
;
3979 descr
.width
= width
;
3980 descr
.height
= height
;
3981 #ifdef HAVE_LIBXXSHM
3982 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
3984 descr
.useShm
= FALSE
;
3986 descr
.dibpitch
= dib
->dibSection
.dsBm
.bmWidthBytes
;
3990 TRACE("Copying from Pixmap to DIB bits\n");
3991 X11DRV_DIB_GetImageBits( &descr
);
3995 TRACE("Copying from DIB bits to Pixmap\n");
3996 X11DRV_DIB_SetImageBits( &descr
);
4000 /***********************************************************************
4001 * X11DRV_DIB_CopyDIBSection
4003 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE
*physDevSrc
, X11DRV_PDEVICE
*physDevDst
,
4004 DWORD xSrc
, DWORD ySrc
, DWORD xDest
, DWORD yDest
,
4005 DWORD width
, DWORD height
)
4009 int nColorMap
= 0, *colorMap
= NULL
, aColorMap
= FALSE
;
4011 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", physDevSrc
->hdc
, physDevDst
->hdc
,
4012 xSrc
, ySrc
, xDest
, yDest
, width
, height
);
4013 /* this function is meant as an optimization for BitBlt,
4014 * not to be called otherwise */
4015 if (GetObjectType( physDevSrc
->hdc
) != OBJ_MEMDC
) {
4016 ERR("called for non-memory source DC!?\n");
4020 hBitmap
= GetCurrentObject( physDevSrc
->hdc
, OBJ_BITMAP
);
4021 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBitmap
, BITMAP_MAGIC
);
4022 if (!(bmp
&& bmp
->dib
)) {
4023 ERR("called for non-DIBSection!?\n");
4024 GDI_ReleaseObj( hBitmap
);
4027 /* while BitBlt should already have made sure we only get
4028 * positive values, we should check for oversize values */
4029 if ((xSrc
< bmp
->bitmap
.bmWidth
) &&
4030 (ySrc
< bmp
->bitmap
.bmHeight
)) {
4031 if (xSrc
+ width
> bmp
->bitmap
.bmWidth
)
4032 width
= bmp
->bitmap
.bmWidth
- xSrc
;
4033 if (ySrc
+ height
> bmp
->bitmap
.bmHeight
)
4034 height
= bmp
->bitmap
.bmHeight
- ySrc
;
4035 /* if the source bitmap is 8bpp or less, we're supposed to use the
4036 * DC's palette for color conversion (not the DIB color table) */
4037 if (bmp
->dib
->dsBm
.bmBitsPixel
<= 8) {
4038 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4039 HPALETTE hPalette
= GetCurrentObject( physDevSrc
->hdc
, OBJ_PAL
);
4040 if (!hPalette
|| (hPalette
== GetStockObject(DEFAULT_PALETTE
))) {
4041 /* HACK: no palette has been set in the source DC,
4042 * use the DIB colormap instead - this is necessary in some
4043 * cases since we need to do depth conversion in some places
4044 * where real Windows can just copy data straight over */
4045 colorMap
= dib
->colorMap
;
4046 nColorMap
= dib
->nColorMap
;
4048 colorMap
= X11DRV_DIB_BuildColorMap( physDevSrc
, (WORD
)-1,
4049 bmp
->dib
->dsBm
.bmBitsPixel
,
4050 (BITMAPINFO
*)&(bmp
->dib
->dsBmih
),
4052 if (colorMap
) aColorMap
= TRUE
;
4055 /* perform the copy */
4056 X11DRV_DIB_DoCopyDIBSection(bmp
, FALSE
, colorMap
, nColorMap
,
4057 physDevDst
->drawable
, xSrc
, ySrc
,
4058 physDevDst
->org
.x
+ xDest
, physDevDst
->org
.y
+ yDest
,
4060 /* free color mapping */
4062 HeapFree(GetProcessHeap(), 0, colorMap
);
4064 GDI_ReleaseObj( hBitmap
);
4067 /***********************************************************************
4068 * X11DRV_DIB_DoUpdateDIBSection
4070 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
4072 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4073 X11DRV_DIB_DoCopyDIBSection(bmp
, toDIB
, dib
->colorMap
, dib
->nColorMap
,
4074 (Drawable
)bmp
->physBitmap
, 0, 0, 0, 0,
4075 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
4078 /***********************************************************************
4079 * X11DRV_DIB_FaultHandler
4081 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
4086 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
4087 if (!bmp
) return FALSE
;
4089 state
= X11DRV_DIB_Lock(bmp
, DIB_Status_None
, FALSE
);
4090 if (state
!= DIB_Status_InSync
) {
4091 /* no way to tell whether app needs read or write yet,
4093 X11DRV_DIB_Coerce(bmp
, DIB_Status_InSync
, FALSE
);
4095 /* hm, apparently the app must have write access */
4096 X11DRV_DIB_Coerce(bmp
, DIB_Status_AppMod
, FALSE
);
4098 X11DRV_DIB_Unlock(bmp
, TRUE
);
4100 GDI_ReleaseObj( (HBITMAP
)res
);
4104 /***********************************************************************
4107 INT
X11DRV_DIB_Coerce(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
4109 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4110 INT ret
= DIB_Status_None
;
4113 EnterCriticalSection(&(dib
->lock
));
4116 case DIB_Status_GdiMod
:
4117 /* GDI access - request to draw on pixmap */
4118 switch (dib
->status
)
4121 case DIB_Status_None
:
4122 dib
->p_status
= DIB_Status_GdiMod
;
4123 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
4126 case DIB_Status_GdiMod
:
4127 TRACE("GdiMod requested in status GdiMod\n" );
4130 case DIB_Status_InSync
:
4131 TRACE("GdiMod requested in status InSync\n" );
4132 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
4133 dib
->status
= DIB_Status_GdiMod
;
4134 dib
->p_status
= DIB_Status_InSync
;
4137 case DIB_Status_AuxMod
:
4138 TRACE("GdiMod requested in status AuxMod\n" );
4139 if (lossy
) dib
->status
= DIB_Status_GdiMod
;
4140 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_GdiMod
);
4141 dib
->p_status
= DIB_Status_AuxMod
;
4142 if (dib
->status
!= DIB_Status_AppMod
) {
4143 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
4146 /* fall through if copy_aux() had to change to AppMod state */
4148 case DIB_Status_AppMod
:
4149 TRACE("GdiMod requested in status AppMod\n" );
4151 /* make it readonly to avoid app changing data while we copy */
4152 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4153 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
4155 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
4156 dib
->p_status
= DIB_Status_AppMod
;
4157 dib
->status
= DIB_Status_GdiMod
;
4162 case DIB_Status_InSync
:
4163 /* App access - request access to read DIB surface */
4164 /* (typically called from signal handler) */
4165 switch (dib
->status
)
4168 case DIB_Status_None
:
4169 /* shouldn't happen from signal handler */
4172 case DIB_Status_AuxMod
:
4173 TRACE("InSync requested in status AuxMod\n" );
4174 if (lossy
) dib
->status
= DIB_Status_InSync
;
4176 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4177 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_InSync
);
4179 if (dib
->status
!= DIB_Status_GdiMod
) {
4180 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4183 /* fall through if copy_aux() had to change to GdiMod state */
4185 case DIB_Status_GdiMod
:
4186 TRACE("InSync requested in status GdiMod\n" );
4188 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4189 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
4191 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4192 dib
->status
= DIB_Status_InSync
;
4195 case DIB_Status_InSync
:
4196 TRACE("InSync requested in status InSync\n" );
4197 /* shouldn't happen from signal handler */
4200 case DIB_Status_AppMod
:
4201 TRACE("InSync requested in status AppMod\n" );
4202 /* no reason to do anything here, and this
4203 * shouldn't happen from signal handler */
4208 case DIB_Status_AppMod
:
4209 /* App access - request access to write DIB surface */
4210 /* (typically called from signal handler) */
4211 switch (dib
->status
)
4214 case DIB_Status_None
:
4215 /* shouldn't happen from signal handler */
4218 case DIB_Status_AuxMod
:
4219 TRACE("AppMod requested in status AuxMod\n" );
4220 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4221 if (lossy
) dib
->status
= DIB_Status_AppMod
;
4222 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
4223 if (dib
->status
!= DIB_Status_GdiMod
)
4225 /* fall through if copy_aux() had to change to GdiMod state */
4227 case DIB_Status_GdiMod
:
4228 TRACE("AppMod requested in status GdiMod\n" );
4229 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4230 if (!lossy
) X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
4231 dib
->status
= DIB_Status_AppMod
;
4234 case DIB_Status_InSync
:
4235 TRACE("AppMod requested in status InSync\n" );
4236 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4237 dib
->status
= DIB_Status_AppMod
;
4240 case DIB_Status_AppMod
:
4241 TRACE("AppMod requested in status AppMod\n" );
4242 /* shouldn't happen from signal handler */
4247 case DIB_Status_AuxMod
:
4248 if (dib
->status
== DIB_Status_None
) {
4249 dib
->p_status
= req
;
4251 if (dib
->status
!= DIB_Status_AuxMod
)
4252 dib
->p_status
= dib
->status
;
4253 dib
->status
= DIB_Status_AuxMod
;
4256 /* it is up to the caller to do the copy/conversion, probably
4257 * using the return value to decide where to copy from */
4259 LeaveCriticalSection(&(dib
->lock
));
4264 /***********************************************************************
4267 INT
X11DRV_DIB_Lock(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
4269 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4270 INT ret
= DIB_Status_None
;
4273 TRACE("Locking %p from thread %04lx\n", bmp
, GetCurrentThreadId());
4274 EnterCriticalSection(&(dib
->lock
));
4276 if (req
!= DIB_Status_None
)
4277 X11DRV_DIB_Coerce(bmp
, req
, lossy
);
4282 /***********************************************************************
4285 void X11DRV_DIB_Unlock(BITMAPOBJ
*bmp
, BOOL commit
)
4287 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4290 switch (dib
->status
)
4293 case DIB_Status_None
:
4294 /* in case anyone is wondering, this is the "signal handler doesn't
4295 * work" case, where we always have to be ready for app access */
4297 switch (dib
->p_status
)
4299 case DIB_Status_AuxMod
:
4300 TRACE("Unlocking and syncing from AuxMod\n" );
4301 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
4302 if (dib
->status
!= DIB_Status_None
) {
4303 dib
->p_status
= dib
->status
;
4304 dib
->status
= DIB_Status_None
;
4306 if (dib
->p_status
!= DIB_Status_GdiMod
)
4308 /* fall through if copy_aux() had to change to GdiMod state */
4310 case DIB_Status_GdiMod
:
4311 TRACE("Unlocking and syncing from GdiMod\n" );
4312 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
4316 TRACE("Unlocking without needing to sync\n" );
4320 else TRACE("Unlocking with no changes\n");
4321 dib
->p_status
= DIB_Status_None
;
4324 case DIB_Status_GdiMod
:
4325 TRACE("Unlocking in status GdiMod\n" );
4326 /* DIB was protected in Coerce */
4328 /* no commit, revert to InSync if applicable */
4329 if ((dib
->p_status
== DIB_Status_InSync
) ||
4330 (dib
->p_status
== DIB_Status_AppMod
)) {
4331 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
4332 dib
->status
= DIB_Status_InSync
;
4337 case DIB_Status_InSync
:
4338 TRACE("Unlocking in status InSync\n" );
4339 /* DIB was already protected in Coerce */
4342 case DIB_Status_AppMod
:
4343 TRACE("Unlocking in status AppMod\n" );
4344 /* DIB was already protected in Coerce */
4345 /* this case is ordinary only called from the signal handler,
4346 * so we don't bother to check for !commit */
4349 case DIB_Status_AuxMod
:
4350 TRACE("Unlocking in status AuxMod\n" );
4352 /* DIB may need protection now */
4353 if ((dib
->p_status
== DIB_Status_InSync
) ||
4354 (dib
->p_status
== DIB_Status_AppMod
))
4355 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
4357 /* no commit, revert to previous state */
4358 if (dib
->p_status
!= DIB_Status_None
)
4359 dib
->status
= dib
->p_status
;
4360 /* no protections changed */
4362 dib
->p_status
= DIB_Status_None
;
4365 LeaveCriticalSection(&(dib
->lock
));
4366 TRACE("Unlocked %p\n", bmp
);
4370 /***********************************************************************
4371 * X11DRV_CoerceDIBSection2
4373 INT
X11DRV_CoerceDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
4378 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4379 if (!bmp
) return DIB_Status_None
;
4380 ret
= X11DRV_DIB_Coerce(bmp
, req
, lossy
);
4381 GDI_ReleaseObj( hBmp
);
4385 /***********************************************************************
4386 * X11DRV_LockDIBSection2
4388 INT
X11DRV_LockDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
4393 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4394 if (!bmp
) return DIB_Status_None
;
4395 ret
= X11DRV_DIB_Lock(bmp
, req
, lossy
);
4396 GDI_ReleaseObj( hBmp
);
4400 /***********************************************************************
4401 * X11DRV_UnlockDIBSection2
4403 void X11DRV_UnlockDIBSection2(HBITMAP hBmp
, BOOL commit
)
4407 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4409 X11DRV_DIB_Unlock(bmp
, commit
);
4410 GDI_ReleaseObj( hBmp
);
4413 /***********************************************************************
4414 * X11DRV_CoerceDIBSection
4416 INT
X11DRV_CoerceDIBSection(X11DRV_PDEVICE
*physDev
, INT req
, BOOL lossy
)
4418 if (!physDev
) return DIB_Status_None
;
4419 return X11DRV_CoerceDIBSection2( GetCurrentObject( physDev
->hdc
, OBJ_BITMAP
), req
, lossy
);
4422 /***********************************************************************
4423 * X11DRV_LockDIBSection
4425 INT
X11DRV_LockDIBSection(X11DRV_PDEVICE
*physDev
, INT req
, BOOL lossy
)
4427 if (!physDev
) return DIB_Status_None
;
4428 if (GetObjectType( physDev
->hdc
) != OBJ_MEMDC
) return DIB_Status_None
;
4430 return X11DRV_LockDIBSection2( GetCurrentObject( physDev
->hdc
, OBJ_BITMAP
), req
, lossy
);
4433 /***********************************************************************
4434 * X11DRV_UnlockDIBSection
4436 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE
*physDev
, BOOL commit
)
4438 if (!physDev
) return;
4439 if (GetObjectType( physDev
->hdc
) != OBJ_MEMDC
) return;
4441 X11DRV_UnlockDIBSection2( GetCurrentObject( physDev
->hdc
, OBJ_BITMAP
), commit
);
4445 #ifdef HAVE_LIBXXSHM
4446 /***********************************************************************
4447 * X11DRV_XShmErrorHandler
4450 static int XShmErrorHandler( Display
*dpy
, XErrorEvent
*event
, void *arg
)
4452 return 1; /* FIXME: should check event contents */
4455 /***********************************************************************
4456 * X11DRV_XShmCreateImage
4459 static XImage
*X11DRV_XShmCreateImage( int width
, int height
, int bpp
,
4460 XShmSegmentInfo
* shminfo
)
4464 image
= XShmCreateImage(gdi_display
, visual
, bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
4467 shminfo
->shmid
= shmget(IPC_PRIVATE
, image
->bytes_per_line
* height
,
4469 if( shminfo
->shmid
!= -1 )
4471 shminfo
->shmaddr
= image
->data
= shmat(shminfo
->shmid
, 0, 0);
4472 if( shminfo
->shmaddr
!= (char*)-1 )
4476 shminfo
->readOnly
= FALSE
;
4477 X11DRV_expect_error( gdi_display
, XShmErrorHandler
, NULL
);
4478 ok
= (XShmAttach( gdi_display
, shminfo
) != 0);
4479 XSync( gdi_display
, False
);
4480 if (X11DRV_check_error()) ok
= FALSE
;
4483 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
4484 return image
; /* Success! */
4486 /* An error occurred */
4487 shmdt(shminfo
->shmaddr
);
4489 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
4491 XFlush(gdi_display
);
4492 XDestroyImage(image
);
4497 #endif /* HAVE_LIBXXSHM */
4500 /***********************************************************************
4501 * X11DRV_DIB_CreateDIBSection
4503 HBITMAP
X11DRV_DIB_CreateDIBSection(
4504 X11DRV_PDEVICE
*physDev
, BITMAPINFO
*bmi
, UINT usage
,
4505 LPVOID
*bits
, HANDLE section
,
4506 DWORD offset
, DWORD ovr_pitch
)
4509 BITMAPOBJ
*bmp
= NULL
;
4510 X11DRV_DIBSECTION
*dib
= NULL
;
4511 int *colorMap
= NULL
;
4514 /* Fill BITMAP32 structure with DIB data */
4515 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
4516 INT effHeight
, totalSize
;
4518 LPVOID mapBits
= NULL
;
4520 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
4521 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
4522 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
4524 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
4526 bm
.bmWidth
= bi
->biWidth
;
4527 bm
.bmHeight
= effHeight
;
4528 bm
.bmWidthBytes
= ovr_pitch
? ovr_pitch
: X11DRV_DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
4529 bm
.bmPlanes
= bi
->biPlanes
;
4530 bm
.bmBitsPixel
= bi
->biBitCount
;
4533 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
4534 we're dealing with a compressed bitmap. Otherwise, use width * height. */
4535 totalSize
= bi
->biSizeImage
&& bi
->biCompression
!= BI_RGB
4536 ? bi
->biSizeImage
: bm
.bmWidthBytes
* effHeight
;
4540 SYSTEM_INFO SystemInfo
;
4544 GetSystemInfo( &SystemInfo
);
4545 mapOffset
= offset
- (offset
% SystemInfo
.dwAllocationGranularity
);
4546 mapSize
= totalSize
+ (offset
- mapOffset
);
4547 mapBits
= MapViewOfFile( section
,
4548 FILE_MAP_ALL_ACCESS
,
4552 bm
.bmBits
= (char *)mapBits
+ (offset
- mapOffset
);
4554 else if (ovr_pitch
&& offset
)
4555 bm
.bmBits
= (LPVOID
) offset
;
4558 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
4559 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
4562 /* Create Color Map */
4563 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8)
4564 colorMap
= X11DRV_DIB_BuildColorMap( usage
== DIB_PAL_COLORS
? physDev
: NULL
,
4565 usage
, bm
.bmBitsPixel
, bmi
, &nColorMap
);
4567 /* Allocate Memory for DIB and fill structure */
4569 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
4572 dib
->dibSection
.dsBm
= bm
;
4573 dib
->dibSection
.dsBmih
= *bi
;
4574 dib
->dibSection
.dsBmih
.biSizeImage
= totalSize
;
4576 /* Set dsBitfields values */
4577 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
4579 dib
->dibSection
.dsBitfields
[0] = dib
->dibSection
.dsBitfields
[1] = dib
->dibSection
.dsBitfields
[2] = 0;
4581 else switch( bi
->biBitCount
)
4585 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
4586 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
4587 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f;
4592 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff0000;
4593 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x00ff00;
4594 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x0000ff;
4597 dib
->dibSection
.dshSection
= section
;
4598 dib
->dibSection
.dsOffset
= offset
;
4600 dib
->status
= DIB_Status_None
;
4601 dib
->nColorMap
= nColorMap
;
4602 dib
->colorMap
= colorMap
;
4605 /* Create Device Dependent Bitmap and add DIB pointer */
4608 res
= CreateDIBitmap(physDev
->hdc
, bi
, 0, NULL
, bmi
, usage
);
4611 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
4612 if (bmp
) bmp
->dib
= (DIBSECTION
*) dib
;
4620 #ifdef HAVE_LIBXXSHM
4621 if (XShmQueryExtension(gdi_display
) &&
4622 (dib
->image
= X11DRV_XShmCreateImage( bm
.bmWidth
, effHeight
,
4623 bmp
->bitmap
.bmBitsPixel
, &dib
->shminfo
)) )
4625 ; /* Created Image */
4627 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
4628 dib
->shminfo
.shmid
= -1;
4631 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
4633 wine_tsx11_unlock();
4636 /* Clean up in case of errors */
4637 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
4639 TRACE("got an error res=%p, bmp=%p, dib=%p, bm.bmBits=%p\n",
4640 res
, bmp
, dib
, bm
.bmBits
);
4644 UnmapViewOfFile(mapBits
), bm
.bmBits
= NULL
;
4646 VirtualFree(bm
.bmBits
, 0L, MEM_RELEASE
), bm
.bmBits
= NULL
;
4649 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
4650 if (colorMap
) { HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
; }
4651 if (dib
) { HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
; }
4652 if (bmp
) { GDI_ReleaseObj(res
); bmp
= NULL
; }
4653 if (res
) { DeleteObject(res
); res
= 0; }
4657 extern BOOL
VIRTUAL_SetFaultHandler(LPCVOID addr
, BOOL (*proc
)(LPVOID
, LPCVOID
), LPVOID arg
);
4658 /* Install fault handler, if possible */
4659 InitializeCriticalSection(&(dib
->lock
));
4660 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
4662 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
4663 if (dib
) dib
->status
= DIB_Status_AppMod
;
4667 /* Return BITMAP handle and storage location */
4668 if (bmp
) GDI_ReleaseObj(res
);
4669 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
4673 /***********************************************************************
4674 * X11DRV_DIB_DeleteDIBSection
4676 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
4678 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4683 #ifdef HAVE_LIBXXSHM
4684 if (dib
->shminfo
.shmid
!= -1)
4686 XShmDetach (gdi_display
, &(dib
->shminfo
));
4687 XDestroyImage (dib
->image
);
4688 shmdt (dib
->shminfo
.shmaddr
);
4689 dib
->shminfo
.shmid
= -1;
4693 XDestroyImage( dib
->image
);
4694 wine_tsx11_unlock();
4698 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
4700 DeleteCriticalSection(&(dib
->lock
));
4703 /***********************************************************************
4704 * SetDIBColorTable (X11DRV.@)
4706 UINT
X11DRV_SetDIBColorTable( X11DRV_PDEVICE
*physDev
, UINT start
, UINT count
, const RGBQUAD
*colors
)
4709 X11DRV_DIBSECTION
*dib
;
4711 HBITMAP hBitmap
= GetCurrentObject( physDev
->hdc
, OBJ_BITMAP
);
4713 if (!(bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBitmap
, BITMAP_MAGIC
))) return 0;
4714 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4716 if (dib
&& dib
->colorMap
) {
4717 UINT end
= count
+ start
;
4718 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
4720 * Changing color table might change the mapping between
4721 * DIB colors and X11 colors and thus alter the visible state
4722 * of the bitmap object.
4724 X11DRV_DIB_Lock(bmp
, DIB_Status_AppMod
, FALSE
);
4725 X11DRV_DIB_GenColorMap( physDev
, dib
->colorMap
, DIB_RGB_COLORS
,
4726 dib
->dibSection
.dsBm
.bmBitsPixel
,
4727 TRUE
, colors
, start
, end
);
4728 X11DRV_DIB_Unlock(bmp
, TRUE
);
4731 GDI_ReleaseObj( hBitmap
);
4735 /***********************************************************************
4736 * GetDIBColorTable (X11DRV.@)
4738 UINT
X11DRV_GetDIBColorTable( X11DRV_PDEVICE
*physDev
, UINT start
, UINT count
, RGBQUAD
*colors
)
4741 X11DRV_DIBSECTION
*dib
;
4743 HBITMAP hBitmap
= GetCurrentObject( physDev
->hdc
, OBJ_BITMAP
);
4745 if (!(bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBitmap
, BITMAP_MAGIC
))) return 0;
4746 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4748 if (dib
&& dib
->colorMap
) {
4749 UINT i
, end
= count
+ start
;
4750 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
4751 for (i
= start
; i
< end
; i
++,colors
++) {
4752 COLORREF col
= X11DRV_PALETTE_ToLogical( dib
->colorMap
[i
] );
4753 colors
->rgbBlue
= GetBValue(col
);
4754 colors
->rgbGreen
= GetGValue(col
);
4755 colors
->rgbRed
= GetRValue(col
);
4756 colors
->rgbReserved
= 0;
4760 GDI_ReleaseObj( hBitmap
);
4766 /***********************************************************************
4767 * X11DRV_DIB_CreateDIBFromBitmap
4769 * Allocates a packed DIB and copies the bitmap data into it.
4771 HGLOBAL
X11DRV_DIB_CreateDIBFromBitmap(HDC hdc
, HBITMAP hBmp
)
4776 LPBITMAPINFOHEADER pbmiHeader
;
4777 unsigned int cDataSize
, cPackedSize
, OffsetBits
, nLinesCopied
;
4779 if (!GetObjectW( hBmp
, sizeof(bmp
), &bmp
)) return 0;
4782 * A packed DIB contains a BITMAPINFO structure followed immediately by
4783 * an optional color palette and the pixel data.
4786 /* Calculate the size of the packed DIB */
4787 cDataSize
= X11DRV_DIB_GetDIBWidthBytes( bmp
.bmWidth
, bmp
.bmBitsPixel
) * abs( bmp
.bmHeight
);
4788 cPackedSize
= sizeof(BITMAPINFOHEADER
)
4789 + ( (bmp
.bmBitsPixel
<= 8) ? (sizeof(RGBQUAD
) * (1 << bmp
.bmBitsPixel
)) : 0 )
4791 /* Get the offset to the bits */
4792 OffsetBits
= cPackedSize
- cDataSize
;
4794 /* Allocate the packed DIB */
4795 TRACE("\tAllocating packed DIB of size %d\n", cPackedSize
);
4796 hPackedDIB
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_DDESHARE
/*| GMEM_ZEROINIT*/,
4800 WARN("Could not allocate packed DIB!\n");
4804 /* A packed DIB starts with a BITMAPINFOHEADER */
4805 pPackedDIB
= GlobalLock(hPackedDIB
);
4806 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
4808 /* Init the BITMAPINFOHEADER */
4809 pbmiHeader
->biSize
= sizeof(BITMAPINFOHEADER
);
4810 pbmiHeader
->biWidth
= bmp
.bmWidth
;
4811 pbmiHeader
->biHeight
= bmp
.bmHeight
;
4812 pbmiHeader
->biPlanes
= 1;
4813 pbmiHeader
->biBitCount
= bmp
.bmBitsPixel
;
4814 pbmiHeader
->biCompression
= BI_RGB
;
4815 pbmiHeader
->biSizeImage
= 0;
4816 pbmiHeader
->biXPelsPerMeter
= pbmiHeader
->biYPelsPerMeter
= 0;
4817 pbmiHeader
->biClrUsed
= 0;
4818 pbmiHeader
->biClrImportant
= 0;
4820 /* Retrieve the DIB bits from the bitmap and fill in the
4821 * DIB color table if present */
4823 nLinesCopied
= GetDIBits(hdc
, /* Handle to device context */
4824 hBmp
, /* Handle to bitmap */
4825 0, /* First scan line to set in dest bitmap */
4826 bmp
.bmHeight
, /* Number of scan lines to copy */
4827 pPackedDIB
+ OffsetBits
, /* [out] Address of array for bitmap bits */
4828 (LPBITMAPINFO
) pbmiHeader
, /* [out] Address of BITMAPINFO structure */
4829 0); /* RGB or palette index */
4830 GlobalUnlock(hPackedDIB
);
4832 /* Cleanup if GetDIBits failed */
4833 if (nLinesCopied
!= bmp
.bmHeight
)
4835 TRACE("\tGetDIBits returned %d. Actual lines=%d\n", nLinesCopied
, bmp
.bmHeight
);
4836 GlobalFree(hPackedDIB
);
4843 /**************************************************************************
4844 * X11DRV_DIB_CreateDIBFromPixmap
4846 * Allocates a packed DIB and copies the Pixmap data into it.
4847 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
4849 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
, BOOL bDeletePixmap
)
4852 BITMAPOBJ
*pBmp
= NULL
;
4853 HGLOBAL hPackedDIB
= 0;
4855 /* Allocates an HBITMAP which references the Pixmap passed to us */
4856 hBmp
= X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(hdc
, pixmap
);
4859 TRACE("\tCould not create bitmap header for Pixmap\n");
4864 * Create a packed DIB from the Pixmap wrapper bitmap created above.
4865 * A packed DIB contains a BITMAPINFO structure followed immediately by
4866 * an optional color palette and the pixel data.
4868 hPackedDIB
= X11DRV_DIB_CreateDIBFromBitmap(hdc
, hBmp
);
4870 /* Get a pointer to the BITMAPOBJ structure */
4871 pBmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4873 /* We can now get rid of the HBITMAP wrapper we created earlier.
4874 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
4878 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
4879 pBmp
->physBitmap
= NULL
;
4882 GDI_ReleaseObj( hBmp
);
4886 TRACE("\tReturning packed DIB %p\n", hPackedDIB
);
4891 /**************************************************************************
4892 * X11DRV_DIB_CreatePixmapFromDIB
4894 * Creates a Pixmap from a packed DIB
4896 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
4898 Pixmap pixmap
= None
;
4900 BITMAPOBJ
*pBmp
= NULL
;
4901 LPBYTE pPackedDIB
= NULL
;
4902 LPBITMAPINFO pbmi
= NULL
;
4903 LPBITMAPINFOHEADER pbmiHeader
= NULL
;
4904 LPBYTE pbits
= NULL
;
4906 /* Get a pointer to the packed DIB's data */
4907 pPackedDIB
= (LPBYTE
)GlobalLock(hPackedDIB
);
4908 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
4909 pbmi
= (LPBITMAPINFO
)pPackedDIB
;
4910 pbits
= (LPBYTE
)(pPackedDIB
4911 + X11DRV_DIB_BitmapInfoSize( (LPBITMAPINFO
)pbmiHeader
, DIB_RGB_COLORS
));
4913 /* Create a DDB from the DIB */
4915 hBmp
= CreateDIBitmap(hdc
,
4922 GlobalUnlock(hPackedDIB
);
4924 TRACE("CreateDIBitmap returned %p\n", hBmp
);
4926 /* Retrieve the internal Pixmap from the DDB */
4928 pBmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
4930 pixmap
= (Pixmap
)pBmp
->physBitmap
;
4931 /* clear the physBitmap so that we can steal its pixmap */
4932 pBmp
->physBitmap
= NULL
;
4935 /* Delete the DDB we created earlier now that we have stolen its pixmap */
4936 GDI_ReleaseObj( hBmp
);
4939 TRACE("\tReturning Pixmap %ld\n", pixmap
);