2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
9 #ifndef X_DISPLAY_MISSING
23 static int bitmapDepthTable
[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
24 static int ximageDepthTable
[] = { 0, 0, 0, 0, 0, 0, 0 };
26 /***********************************************************************
29 BOOL
X11DRV_DIB_Init(void)
34 for( i
= 0; bitmapDepthTable
[i
]; i
++ )
36 testimage
= TSXCreateImage(display
, DefaultVisualOfScreen(X11DRV_GetXScreen()),
37 bitmapDepthTable
[i
], ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
38 if( testimage
) ximageDepthTable
[i
] = testimage
->bits_per_pixel
;
40 TSXDestroyImage(testimage
);
46 /***********************************************************************
47 * X11DRV_DIB_GetXImageWidthBytes
49 * Return the width of an X image in bytes
51 int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
55 if (!ximageDepthTable
[0]) {
58 for( i
= 0; bitmapDepthTable
[i
] ; i
++ )
59 if( bitmapDepthTable
[i
] == depth
)
60 return (4 * ((width
* ximageDepthTable
[i
] + 31)/32));
62 WARN(bitmap
, "(%d): Unsupported depth\n", depth
);
66 /***********************************************************************
67 * X11DRV_DIB_BuildColorMap
69 * Build the color map from the bitmap palette. Should not be called
70 * for a >8-bit deep bitmap.
72 int *X11DRV_DIB_BuildColorMap( DC
*dc
, WORD coloruse
, WORD depth
,
73 const BITMAPINFO
*info
, int *nColors
)
80 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
82 colors
= info
->bmiHeader
.biClrUsed
;
83 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
84 colorPtr
= (WORD
*)info
->bmiColors
;
86 else /* assume BITMAPCOREINFO */
88 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
89 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
94 ERR(bitmap
, "called with >256 colors!\n");
98 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
99 colors
* sizeof(int) )))
102 if (coloruse
== DIB_RGB_COLORS
)
106 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
108 if (depth
== 1) /* Monochrome */
109 for (i
= 0; i
< colors
; i
++, rgb
++)
110 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
111 rgb
->rgbBlue
> 255*3/2);
113 for (i
= 0; i
< colors
; i
++, rgb
++)
114 colorMapping
[i
] = COLOR_ToPhysical( dc
, RGB(rgb
->rgbRed
,
120 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
122 if (depth
== 1) /* Monochrome */
123 for (i
= 0; i
< colors
; i
++, rgb
++)
124 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
125 rgb
->rgbtBlue
> 255*3/2);
127 for (i
= 0; i
< colors
; i
++, rgb
++)
128 colorMapping
[i
] = COLOR_ToPhysical( dc
, RGB(rgb
->rgbtRed
,
133 else /* DIB_PAL_COLORS */
135 for (i
= 0; i
< colors
; i
++, colorPtr
++)
136 colorMapping
[i
] = COLOR_ToPhysical( dc
, PALETTEINDEX(*colorPtr
) );
144 /***********************************************************************
145 * X11DRV_DIB_MapColor
147 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
)
151 for (color
= 0; color
< nPhysMap
; color
++)
152 if (physMap
[color
] == phys
)
155 WARN(bitmap
, "Strange color %08x\n", phys
);
161 /***********************************************************************
162 * X11DRV_DIB_SetImageBits_1_Line
164 * Handles a single line of 1 bit data.
166 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth
, int left
, int *colors
,
167 XImage
*bmpImage
, int h
, const BYTE
*bits
)
172 if((extra
= (left
& 7)) != 0) {
179 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
180 for (i
= dstwidth
/8, x
= left
; i
> 0; i
--)
183 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
184 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 6) & 1] );
185 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 5) & 1] );
186 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 4) & 1] );
187 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 3) & 1] );
188 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 2) & 1] );
189 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 1) & 1] );
190 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 1] );
195 case 7: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
196 case 6: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
197 case 5: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
198 case 4: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
199 case 3: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
200 case 2: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
201 case 1: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
205 /***********************************************************************
206 * X11DRV_DIB_SetImageBits_1
208 * SetDIBits for a 1-bit deep DIB.
210 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
211 DWORD srcwidth
, DWORD dstwidth
, int left
,
212 int *colors
, XImage
*bmpImage
)
217 DWORD linebytes
= ((srcwidth
+ 31) & ~31) / 8;
220 for (h
= lines
-1; h
>=0; h
--) {
221 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
223 srcbits
+= linebytes
;
227 for (h
= 0; h
< lines
; h
++) {
228 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
230 srcbits
+= linebytes
;
236 /***********************************************************************
237 * X11DRV_DIB_SetImageBits_4
239 * SetDIBits for a 4-bit deep DIB.
241 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
242 DWORD srcwidth
, DWORD dstwidth
, int left
,
243 int *colors
, XImage
*bmpImage
)
247 const BYTE
*bits
= srcbits
+ (left
>> 1);
250 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
258 for (h
= lines
-1; h
>= 0; h
--) {
259 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
261 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
262 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
264 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
265 srcbits
+= linebytes
;
266 bits
= srcbits
+ (left
>> 1);
270 for (h
= 0; h
< lines
; h
++) {
271 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
273 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
274 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
276 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
277 srcbits
+= linebytes
;
278 bits
= srcbits
+ (left
>> 1);
285 /***********************************************************************
286 * X11DRV_DIB_GetImageBits_4
288 * GetDIBits for a 4-bit deep DIB.
290 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*srcbits
,
291 DWORD srcwidth
, DWORD dstwidth
, int left
,
292 int *colors
, int nColors
, XImage
*bmpImage
)
296 BYTE
*bits
= srcbits
+ (left
>> 1);
299 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
306 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
308 for (h
= lines
-1; h
>= 0; h
--) {
309 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
310 *bits
++ = (X11DRV_DIB_MapColor( colors
, nColors
,
311 XGetPixel( bmpImage
, x
++, h
)) << 4)
312 | (X11DRV_DIB_MapColor( colors
, nColors
,
313 XGetPixel( bmpImage
, x
++, h
)) & 0x0f);
316 *bits
= (X11DRV_DIB_MapColor( colors
, nColors
,
317 XGetPixel( bmpImage
, x
++, h
)) << 4);
318 srcbits
+= linebytes
;
319 bits
= srcbits
+ (left
>> 1);
323 for (h
= 0; h
< lines
; h
++) {
324 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
325 *bits
++ = (X11DRV_DIB_MapColor( colors
, nColors
,
326 XGetPixel( bmpImage
, x
++, h
))
328 | (X11DRV_DIB_MapColor( colors
, nColors
,
329 XGetPixel( bmpImage
, x
++, h
)) & 0x0f);
332 *bits
= (X11DRV_DIB_MapColor( colors
, nColors
,
333 XGetPixel( bmpImage
, x
++, h
)) << 4);
334 srcbits
+= linebytes
;
335 bits
= srcbits
+ (left
>> 1);
340 /***********************************************************************
341 * X11DRV_DIB_SetImageBits_RLE4
343 * SetDIBits for a 4-bit deep compressed DIB.
345 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
346 DWORD width
, DWORD dstwidth
,
347 int left
, int *colors
,
350 int x
= 0, c
, length
;
351 const BYTE
*begin
= bits
;
355 while ((int)lines
>= 0) {
357 if (length
) { /* encoded */
365 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>>4]);
373 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
384 case 1: /* eopicture */
390 FIXME(x11drv
, "x-delta is too large?\n");
396 default: /* absolute */
404 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>> 4]);
412 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
415 if ((bits
- begin
) & 1)
424 /***********************************************************************
425 * X11DRV_DIB_SetImageBits_8
427 * SetDIBits for an 8-bit deep DIB.
429 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
430 DWORD srcwidth
, DWORD dstwidth
, int left
,
431 int *colors
, XImage
*bmpImage
)
435 const BYTE
*bits
= srcbits
+ left
;
437 /* align to 32 bit */
438 DWORD linebytes
= (srcwidth
+ 3) & ~3;
443 for (h
= lines
- 1; h
>= 0; h
--) {
444 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
445 XPutPixel( bmpImage
, x
, h
, colors
[*bits
] );
447 bits
= (srcbits
+= linebytes
) + left
;
451 for (h
= 0; h
< lines
; h
++) {
452 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
453 XPutPixel( bmpImage
, x
, h
, colors
[*bits
] );
455 bits
= (srcbits
+= linebytes
) + left
;
460 /***********************************************************************
461 * X11DRV_DIB_GetImageBits_8
463 * GetDIBits for an 8-bit deep DIB.
465 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*srcbits
,
466 DWORD srcwidth
, DWORD dstwidth
, int left
,
467 int *colors
, int nColors
, XImage
*bmpImage
)
471 BYTE
*bits
= srcbits
+ left
;
473 /* align to 32 bit */
474 DWORD linebytes
= (srcwidth
+ 3) & ~3;
479 for (h
= lines
- 1; h
>= 0; h
--) {
480 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
481 if ( XGetPixel( bmpImage
, x
, h
) != colors
[*bits
] )
482 *bits
= X11DRV_DIB_MapColor( colors
, nColors
,
483 XGetPixel( bmpImage
, x
, h
) );
485 bits
= (srcbits
+= linebytes
) + left
;
489 for (h
= 0; h
< lines
; h
++) {
490 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
491 if ( XGetPixel( bmpImage
, x
, h
) != colors
[*bits
] )
492 *bits
= X11DRV_DIB_MapColor( colors
, nColors
,
493 XGetPixel( bmpImage
, x
, h
) );
495 bits
= (srcbits
+= linebytes
) + left
;
500 /***********************************************************************
501 * X11DRV_DIB_SetImageBits_RLE8
503 * SetDIBits for an 8-bit deep compressed DIB.
505 * This function rewritten 941113 by James Youngman. WINE blew out when I
506 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
508 * This was because the algorithm assumed that all RLE8 bitmaps end with the
509 * 'End of bitmap' escape code. This code is very much laxer in what it
510 * allows to end the expansion. Possibly too lax. See the note by
511 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
512 * bitmap should end with RleEnd, but on the other hand, software exists
513 * that produces ones that don't and Windows 3.1 doesn't complain a bit
516 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
517 * James A. Youngman <mbcstjy@afs.man.ac.uk>
521 enum Rle8_EscapeCodes
524 * Apologies for polluting your file's namespace...
526 RleEol
= 0, /* End of line */
527 RleEnd
= 1, /* End of bitmap */
528 RleDelta
= 2 /* Delta */
531 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
532 DWORD width
, DWORD dstwidth
,
533 int left
, int *colors
,
536 int x
; /* X-positon on each line. Increases. */
537 int line
; /* Line #. Starts at lines-1, decreases */
538 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
539 BYTE length
; /* The length pf a run */
540 BYTE color_index
; /* index into colors[] as read from bits */
541 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
542 int color
; /* value of colour[color_index] */
544 if (lines
== 0) /* Let's hope this doesn't happen. */
548 * Note that the bitmap data is stored by Windows starting at the
549 * bottom line of the bitmap and going upwards. Within each line,
550 * the data is stored left-to-right. That's the reason why line
551 * goes from lines-1 to 0. [JAY]
561 * If the length byte is not zero (which is the escape value),
562 * We have a run of length pixels all the same colour. The colour
563 * index is stored next.
565 * If the length byte is zero, we need to read the next byte to
566 * know what to do. [JAY]
571 * [Run-Length] Encoded mode
573 color_index
= (*pIn
++); /* Get the colour index. */
574 color
= colors
[color_index
];
577 XPutPixel(bmpImage
, x
++, line
, color
);
582 * Escape codes (may be an absolute sequence though)
584 escape_code
= (*pIn
++);
587 case RleEol
: /* =0, end of line */
594 case RleEnd
: /* =1, end of bitmap */
597 * Not all RLE8 bitmaps end with this
598 * code. For example, Paint Shop Pro
599 * produces some that don't. That's (I think)
600 * what caused the previous implementation to
603 line
=-1; /* Cause exit from do loop. */
607 case RleDelta
: /* =2, a delta */
610 * Note that deltaing to line 0
611 * will cause an exit from the loop,
612 * which may not be what is intended.
613 * The fact that there is a delta in the bits
614 * almost certainly implies that there is data
615 * to follow. You may feel that we should
616 * jump to the top of the loop to avoid exiting
619 * TODO: Decide what to do here in that case. [JAY]
625 TRACE(bitmap
, "Delta to last line of bitmap "
626 "(wrongly?) causes loop exit\n");
631 default: /* >2, switch to absolute mode */
636 length
= escape_code
;
639 color_index
= (*pIn
++);
640 XPutPixel(bmpImage
, x
++, line
,
641 colors
[color_index
]);
645 * If you think for a moment you'll realise that the
646 * only time we could ever possibly read an odd
647 * number of bytes is when there is a 0x00 (escape),
648 * a value >0x02 (absolute mode) and then an odd-
649 * length run. Therefore this is the only place we
650 * need to worry about it. Everywhere else the
651 * bytes are always read in pairs. [JAY]
654 pIn
++; /* Throw away the pad byte. */
657 } /* switch (escape_code) : Escape sequence */
658 } /* process either an encoded sequence or an escape sequence */
660 /* We expect to come here more than once per line. */
661 } while (line
>= 0); /* Do this until the bitmap is filled */
664 * Everybody comes here at the end.
665 * Check how we exited the loop and print a message if it's a bit odd.
668 if ( (*(pIn
-2) != 0/*escape*/) || (*(pIn
-1)!= RleEnd
) )
670 TRACE(bitmap
, "End-of-bitmap "
671 "without (strictly) proper escape code. Last two "
672 "bytes were: %02X %02X.\n",
679 /***********************************************************************
680 * X11DRV_DIB_SetImageBits_16
682 * SetDIBits for a 16-bit deep DIB.
684 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
685 DWORD srcwidth
, DWORD dstwidth
, int left
,
686 DC
*dc
, XImage
*bmpImage
)
694 /* align to 32 bit */
695 DWORD linebytes
= (srcwidth
* 2 + 3) & ~3;
699 ptr
= (LPWORD
) srcbits
+ left
;
701 for (h
= lines
- 1; h
>= 0; h
--) {
702 for (x
= left
; x
< dstwidth
; x
++, ptr
++) {
704 r
= (BYTE
) ((val
& 0x7c00) >> 7);
705 g
= (BYTE
) ((val
& 0x03e0) >> 2);
706 b
= (BYTE
) ((val
& 0x001f) << 3);
707 XPutPixel( bmpImage
, x
, h
,
708 COLOR_ToPhysical(dc
, RGB(r
,g
,b
)) );
710 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
714 for (h
= 0; h
< lines
; h
++) {
715 for (x
= left
; x
< dstwidth
; x
++, ptr
++) {
717 r
= (BYTE
) ((val
& 0x7c00) >> 7);
718 g
= (BYTE
) ((val
& 0x03e0) >> 2);
719 b
= (BYTE
) ((val
& 0x001f) << 3);
720 XPutPixel( bmpImage
, x
, h
,
721 COLOR_ToPhysical(dc
, RGB(r
,g
,b
)) );
723 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
729 /***********************************************************************
730 * X11DRV_DIB_GetImageBits_16
732 * GetDIBits for an 16-bit deep DIB.
734 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*srcbits
,
735 DWORD srcwidth
, DWORD dstwidth
, int left
,
743 /* align to 32 bit */
744 DWORD linebytes
= (srcwidth
* 2 + 3) & ~3;
748 ptr
= (LPWORD
) srcbits
+ left
;
750 for (h
= lines
- 1; h
>= 0; h
--)
752 for (x
= left
; x
< dstwidth
; x
++, ptr
++)
754 COLORREF pixel
= COLOR_ToLogical( XGetPixel( bmpImage
, x
, h
) );
755 r
= (BYTE
) GetRValue(pixel
);
756 g
= (BYTE
) GetGValue(pixel
);
757 b
= (BYTE
) GetBValue(pixel
);
758 *ptr
= ( ((r
<< 7) & 0x7c00) | ((g
<< 2) & 0x03e0) | ((b
>> 3) & 0x001f) );
760 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
764 for (h
= 0; h
< lines
; h
++)
766 for (x
= left
; x
< dstwidth
; x
++, ptr
++)
768 COLORREF pixel
= COLOR_ToLogical( XGetPixel( bmpImage
, x
, h
) );
769 r
= (BYTE
) GetRValue(pixel
);
770 g
= (BYTE
) GetGValue(pixel
);
771 b
= (BYTE
) GetBValue(pixel
);
772 *ptr
= ( ((r
<< 7) & 0x7c00) | ((g
<< 2) & 0x03e0) | ((b
>> 3) & 0x001f) );
775 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
782 /***********************************************************************
783 * X11DRV_DIB_SetImageBits_24
785 * SetDIBits for a 24-bit deep DIB.
787 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
788 DWORD srcwidth
, DWORD dstwidth
, int left
,
789 DC
*dc
, XImage
*bmpImage
)
792 const BYTE
*bits
= srcbits
+ left
* 3;
795 /* align to 32 bit */
796 DWORD linebytes
= (srcwidth
* 3 + 3) & ~3;
800 /* "bits" order is reversed for some reason */
803 for (h
= lines
- 1; h
>= 0; h
--) {
804 for (x
= left
; x
< dstwidth
; x
++, bits
+= 3) {
805 XPutPixel( bmpImage
, x
, h
,
806 COLOR_ToPhysical(dc
, RGB(bits
[2],bits
[1],bits
[0])));
808 bits
= (srcbits
+= linebytes
) + left
* 3;
812 for (h
= 0; h
< lines
; h
++) {
813 for (x
= left
; x
< dstwidth
; x
++, bits
+= 3) {
814 XPutPixel( bmpImage
, x
, h
,
815 COLOR_ToPhysical(dc
, RGB(bits
[2],bits
[1],bits
[0])));
817 bits
= (srcbits
+= linebytes
) + left
* 3;
823 /***********************************************************************
824 * X11DRV_DIB_GetImageBits_24
826 * GetDIBits for an 24-bit deep DIB.
828 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*srcbits
,
829 DWORD srcwidth
, DWORD dstwidth
, int left
,
834 BYTE
*bits
= srcbits
+ (left
* 3);
836 /* align to 32 bit */
837 DWORD linebytes
= (srcwidth
* 3 + 3) & ~3;
842 for (h
= lines
- 1; h
>= 0; h
--)
844 for (x
= left
; x
< dstwidth
; x
++, bits
+= 3)
846 COLORREF pixel
= COLOR_ToLogical( XGetPixel( bmpImage
, x
, h
) );
847 bits
[0] = GetRValue(pixel
);
848 bits
[1] = GetGValue(pixel
);
849 bits
[2] = GetBValue(pixel
);
851 bits
= (srcbits
+= linebytes
) + (left
* 3);
855 for (h
= 0; h
< lines
; h
++)
857 for (x
= left
; x
< dstwidth
; x
++, bits
+= 3)
859 COLORREF pixel
= COLOR_ToLogical( XGetPixel( bmpImage
, x
, h
) );
860 bits
[0] = GetRValue(pixel
);
861 bits
[1] = GetGValue(pixel
);
862 bits
[2] = GetBValue(pixel
);
865 bits
= (srcbits
+= linebytes
) + (left
* 3);
871 /***********************************************************************
872 * X11DRV_DIB_SetImageBits_32
874 * SetDIBits for a 32-bit deep DIB.
876 static void X11DRV_DIB_SetImageBits_32( int lines
, const BYTE
*srcbits
,
877 DWORD srcwidth
, DWORD dstwidth
, int left
,
878 DC
*dc
, XImage
*bmpImage
)
881 const BYTE
*bits
= srcbits
+ left
* 4;
884 DWORD linebytes
= (srcwidth
* 4);
889 for (h
= lines
- 1; h
>= 0; h
--) {
890 for (x
= left
; x
< dstwidth
; x
++, bits
+= 4) {
891 XPutPixel( bmpImage
, x
, h
,
892 COLOR_ToPhysical(dc
, RGB(bits
[2],bits
[1],bits
[0])));
894 bits
= (srcbits
+= linebytes
) + left
* 4;
898 for (h
= 0; h
< lines
; h
++) {
899 for (x
= left
; x
< dstwidth
; x
++, bits
+= 4) {
900 XPutPixel( bmpImage
, x
, h
,
901 COLOR_ToPhysical(dc
, RGB(bits
[2],bits
[1],bits
[0])));
903 bits
= (srcbits
+= linebytes
) + left
* 4;
909 /***********************************************************************
910 * X11DRV_DIB_GetImageBits_32
912 * GetDIBits for an 32-bit deep DIB.
914 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*srcbits
,
915 DWORD srcwidth
, DWORD dstwidth
, int left
,
920 BYTE
*bits
= srcbits
+ (left
* 4);
922 /* align to 32 bit */
923 DWORD linebytes
= (srcwidth
* 4);
928 for (h
= lines
- 1; h
>= 0; h
--)
930 for (x
= left
; x
< dstwidth
; x
++, bits
+= 4)
932 COLORREF pixel
= COLOR_ToLogical( XGetPixel( bmpImage
, x
, h
) );
933 bits
[0] = GetRValue(pixel
);
934 bits
[1] = GetGValue(pixel
);
935 bits
[2] = GetBValue(pixel
);
937 bits
= (srcbits
+= linebytes
) + (left
* 4);
941 for (h
= 0; h
< lines
; h
++)
943 for (x
= left
; x
< dstwidth
; x
++, bits
+= 4)
945 COLORREF pixel
= COLOR_ToLogical( XGetPixel( bmpImage
, x
, h
) );
946 bits
[0] = GetRValue(pixel
);
947 bits
[1] = GetGValue(pixel
);
948 bits
[2] = GetBValue(pixel
);
951 bits
= (srcbits
+= linebytes
) + (left
* 4);
957 /***********************************************************************
958 * X11DRV_DIB_SetImageBits
960 * Transfer the bits to an X image.
961 * Helper function for SetDIBits() and SetDIBitsToDevice().
962 * The Xlib critical section must be entered before calling this function.
964 int X11DRV_DIB_SetImageBits( const DIB_SETIMAGEBITS_DESCR
*descr
)
966 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
969 if ( descr
->dc
&& descr
->dc
->w
.flags
& DC_DIRTY
)
970 CLIPPING_UpdateGCRegion( descr
->dc
);
973 bmpImage
= descr
->image
;
975 bmpImage
= XCreateImage( display
,
976 DefaultVisualOfScreen(X11DRV_GetXScreen()),
977 descr
->depth
, ZPixmap
, 0, NULL
,
978 descr
->infoWidth
, lines
, 32, 0 );
979 bmpImage
->data
= xcalloc( bmpImage
->bytes_per_line
* lines
);
982 /* Transfer the pixels */
983 switch(descr
->infoBpp
)
986 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
987 descr
->width
, descr
->xSrc
, descr
->colorMap
,
991 if (descr
->compression
)
992 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
993 descr
->infoWidth
, descr
->width
,
994 descr
->xSrc
, descr
->colorMap
,
997 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
998 descr
->infoWidth
, descr
->width
,
999 descr
->xSrc
, descr
->colorMap
,
1003 if (descr
->compression
)
1004 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
1005 descr
->infoWidth
, descr
->width
,
1007 descr
->colorMap
, bmpImage
);
1009 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
1010 descr
->infoWidth
, descr
->width
,
1011 descr
->xSrc
, descr
->colorMap
,
1016 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
1017 descr
->infoWidth
, descr
->width
,
1018 descr
->xSrc
, descr
->dc
, bmpImage
);
1021 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
1022 descr
->infoWidth
, descr
->width
,
1023 descr
->xSrc
, descr
->dc
, bmpImage
);
1026 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
1027 descr
->infoWidth
, descr
->width
,
1028 descr
->xSrc
, descr
->dc
, bmpImage
);
1031 WARN(bitmap
, "(%d): Invalid depth\n", descr
->infoBpp
);
1035 XPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
1036 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
1037 descr
->width
, descr
->height
);
1039 if (!descr
->image
) XDestroyImage( bmpImage
);
1043 /***********************************************************************
1044 * X11DRV_DIB_GetImageBits
1046 * Transfer the bits from an X image.
1047 * The Xlib critical section must be entered before calling this function.
1049 int X11DRV_DIB_GetImageBits( const DIB_SETIMAGEBITS_DESCR
*descr
)
1051 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
1055 bmpImage
= descr
->image
;
1057 bmpImage
= XCreateImage( display
,
1058 DefaultVisualOfScreen(X11DRV_GetXScreen()),
1059 descr
->depth
, ZPixmap
, 0, NULL
,
1060 descr
->infoWidth
, lines
, 32, 0 );
1061 bmpImage
->data
= xcalloc( bmpImage
->bytes_per_line
* lines
);
1064 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
1065 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
1066 bmpImage
, descr
->xSrc
, descr
->ySrc
);
1068 /* Transfer the pixels */
1069 switch(descr
->infoBpp
)
1072 FIXME(bitmap
, "Depth 1 not yet supported!\n");
1076 if (descr
->compression
)
1077 FIXME(bitmap
, "Compression not yet supported!\n");
1079 X11DRV_DIB_GetImageBits_4( descr
->lines
,
1080 (LPVOID
)descr
->bits
, descr
->infoWidth
,
1081 descr
->width
, descr
->xSrc
,
1082 descr
->colorMap
, descr
->nColorMap
,
1087 if (descr
->compression
)
1088 FIXME(bitmap
, "Compression not yet supported!\n");
1090 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
1091 descr
->infoWidth
, descr
->width
,
1092 descr
->xSrc
, descr
->colorMap
,
1093 descr
->nColorMap
, bmpImage
);
1098 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
1100 descr
->width
, descr
->xSrc
, bmpImage
);
1104 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
1106 descr
->width
, descr
->xSrc
, bmpImage
);
1110 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
1112 descr
->width
, descr
->xSrc
, bmpImage
);
1116 WARN(bitmap
, "(%d): Invalid depth\n", descr
->infoBpp
);
1120 if (!descr
->image
) XDestroyImage( bmpImage
);
1124 /*************************************************************************
1125 * X11DRV_SetDIBitsToDevice
1128 INT
X11DRV_SetDIBitsToDevice( DC
*dc
, INT xDest
, INT yDest
, DWORD cx
,
1129 DWORD cy
, INT xSrc
, INT ySrc
,
1130 UINT startscan
, UINT lines
, LPCVOID bits
,
1131 const BITMAPINFO
*info
, UINT coloruse
)
1133 DIB_SETIMAGEBITS_DESCR descr
;
1134 DWORD width
, oldcy
= cy
;
1136 int height
, tmpheight
;
1137 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
1140 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
1141 &descr
.infoBpp
, &descr
.compression
) == -1)
1144 if (height
< 0) height
= -height
;
1145 if (!lines
|| (startscan
>= height
)) return 0;
1146 if (startscan
+ lines
> height
) lines
= height
- startscan
;
1147 if (ySrc
< startscan
) ySrc
= startscan
;
1148 else if (ySrc
>= startscan
+ lines
) return 0;
1149 if (xSrc
>= width
) return 0;
1150 if (ySrc
+ cy
>= startscan
+ lines
) cy
= startscan
+ lines
- ySrc
;
1151 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
1152 if (!cx
|| !cy
) return 0;
1154 X11DRV_SetupGCForText( dc
); /* To have the correct colors */
1155 TSXSetFunction(display
, physDev
->gc
, X11DRV_XROPfunction
[dc
->w
.ROPmode
-1]);
1157 if (descr
.infoBpp
<= 8)
1159 descr
.colorMap
= X11DRV_DIB_BuildColorMap( dc
, coloruse
,
1161 info
, &descr
.nColorMap
);
1162 if (!descr
.colorMap
)
1169 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
1170 descr
.infoWidth
= width
;
1171 descr
.depth
= dc
->w
.bitsPerPixel
;
1172 descr
.drawable
= physDev
->drawable
;
1173 descr
.gc
= physDev
->gc
;
1175 descr
.ySrc
= tmpheight
>= 0 ? lines
-(ySrc
-startscan
)-cy
+(oldcy
-cy
)
1177 descr
.xDest
= dc
->w
.DCOrgX
+ XLPTODP( dc
, xDest
);
1178 descr
.yDest
= dc
->w
.DCOrgY
+ YLPTODP( dc
, yDest
) +
1179 (tmpheight
>= 0 ? oldcy
-cy
: 0);
1183 EnterCriticalSection( &X11DRV_CritSection
);
1184 result
= CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
1185 LeaveCriticalSection( &X11DRV_CritSection
);
1187 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
1191 #endif /* !defined(X_DISPLAY_MISSING) */