2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
17 static int bitmapDepthTable
[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
18 static int ximageDepthTable
[] = { 0, 0, 0, 0, 0, 0, 0 };
20 /***********************************************************************
23 BOOL32
X11DRV_DIB_Init(void)
28 for( i
= 0; bitmapDepthTable
[i
]; i
++ )
30 testimage
= TSXCreateImage(display
, DefaultVisualOfScreen(screen
),
31 bitmapDepthTable
[i
], ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
32 if( testimage
) ximageDepthTable
[i
] = testimage
->bits_per_pixel
;
34 TSXDestroyImage(testimage
);
40 /***********************************************************************
41 * X11DRV_DIB_GetXImageWidthBytes
43 * Return the width of an X image in bytes
45 int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
49 if (!ximageDepthTable
[0]) {
52 for( i
= 0; bitmapDepthTable
[i
] ; i
++ )
53 if( bitmapDepthTable
[i
] == depth
)
54 return (4 * ((width
* ximageDepthTable
[i
] + 31)/32));
56 WARN(bitmap
, "(%d): Unsupported depth\n", depth
);
60 /***********************************************************************
61 * X11DRV_DIB_BuildColorMap
63 * Build the color map from the bitmap palette. Should not be called
64 * for a >8-bit deep bitmap.
66 int *X11DRV_DIB_BuildColorMap( DC
*dc
, WORD coloruse
, WORD depth
,
67 const BITMAPINFO
*info
, int *nColors
)
74 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
76 colors
= info
->bmiHeader
.biClrUsed
;
77 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
78 colorPtr
= (WORD
*)info
->bmiColors
;
80 else /* assume BITMAPCOREINFO */
82 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
83 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
88 ERR(bitmap
, "called with >256 colors!\n");
92 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
93 colors
* sizeof(int) )))
96 if (coloruse
== DIB_RGB_COLORS
)
100 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
102 if (depth
== 1) /* Monochrome */
103 for (i
= 0; i
< colors
; i
++, rgb
++)
104 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
105 rgb
->rgbBlue
> 255*3/2);
107 for (i
= 0; i
< colors
; i
++, rgb
++)
108 colorMapping
[i
] = COLOR_ToPhysical( dc
, RGB(rgb
->rgbRed
,
114 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
116 if (depth
== 1) /* Monochrome */
117 for (i
= 0; i
< colors
; i
++, rgb
++)
118 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
119 rgb
->rgbtBlue
> 255*3/2);
121 for (i
= 0; i
< colors
; i
++, rgb
++)
122 colorMapping
[i
] = COLOR_ToPhysical( dc
, RGB(rgb
->rgbtRed
,
127 else /* DIB_PAL_COLORS */
129 for (i
= 0; i
< colors
; i
++, colorPtr
++)
130 colorMapping
[i
] = COLOR_ToPhysical( dc
, PALETTEINDEX(*colorPtr
) );
138 /***********************************************************************
139 * X11DRV_DIB_MapColor
141 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
)
145 for (color
= 0; color
< nPhysMap
; color
++)
146 if (physMap
[color
] == phys
)
149 WARN(bitmap
, "Strange color %08x\n", phys
);
155 /***********************************************************************
156 * X11DRV_DIB_SetImageBits_1_Line
158 * Handles a single line of 1 bit data.
160 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth
, int left
, int *colors
,
161 XImage
*bmpImage
, int h
, const BYTE
*bits
)
166 dstwidth
+= left
; bits
+= left
>> 3;
168 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
169 for (i
= dstwidth
/8, x
= left
&~7; (i
> 0); i
--)
172 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
173 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 6) & 1] );
174 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 5) & 1] );
175 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 4) & 1] );
176 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 3) & 1] );
177 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 2) & 1] );
178 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 1) & 1] );
179 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 1] );
184 case 7: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
185 case 6: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
186 case 5: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
187 case 4: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
188 case 3: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
189 case 2: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
190 case 1: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
194 /***********************************************************************
195 * X11DRV_DIB_SetImageBits_1
197 * SetDIBits for a 1-bit deep DIB.
199 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
200 DWORD srcwidth
, DWORD dstwidth
, int left
,
201 int *colors
, XImage
*bmpImage
)
206 DWORD linebytes
= ((srcwidth
+ 31) & ~31) / 8;
209 for (h
= lines
-1; h
>=0; h
--) {
210 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
212 srcbits
+= linebytes
;
216 for (h
= 0; h
< lines
; h
++) {
217 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
219 srcbits
+= linebytes
;
225 /***********************************************************************
226 * X11DRV_DIB_SetImageBits_4
228 * SetDIBits for a 4-bit deep DIB.
230 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
231 DWORD srcwidth
, DWORD dstwidth
, int left
,
232 int *colors
, XImage
*bmpImage
)
236 const BYTE
*bits
= srcbits
+ (left
>> 1);
239 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
243 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
245 for (h
= lines
-1; h
>= 0; h
--) {
246 for (i
= dstwidth
/2, x
= left
&~1; i
> 0; i
--) {
248 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
249 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
251 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
252 srcbits
+= linebytes
;
253 bits
= srcbits
+ (left
>> 1);
257 for (h
= 0; h
< lines
; h
++) {
258 for (i
= dstwidth
/2, x
= left
&~1; i
> 0; i
--) {
260 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
261 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
263 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
264 srcbits
+= linebytes
;
265 bits
= srcbits
+ (left
>> 1);
272 /***********************************************************************
273 * X11DRV_DIB_GetImageBits_4
275 * GetDIBits for a 4-bit deep DIB.
277 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*srcbits
,
278 DWORD srcwidth
, DWORD dstwidth
, int left
,
279 int *colors
, int nColors
, XImage
*bmpImage
)
283 BYTE
*bits
= srcbits
+ (left
>> 1);
286 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
290 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
292 for (h
= lines
-1; h
>= 0; h
--) {
293 for (i
= dstwidth
/2, x
= left
&~1; i
> 0; i
--) {
294 *bits
++ = (X11DRV_DIB_MapColor( colors
, nColors
,
295 XGetPixel( bmpImage
, x
++, h
)) << 4)
296 | (X11DRV_DIB_MapColor( colors
, nColors
,
297 XGetPixel( bmpImage
, x
++, h
)) & 0x0f);
300 *bits
= (X11DRV_DIB_MapColor( colors
, nColors
,
301 XGetPixel( bmpImage
, x
++, h
)) << 4);
302 srcbits
+= linebytes
;
303 bits
= srcbits
+ (left
>> 1);
307 for (h
= 0; h
< lines
; h
++) {
308 for (i
= dstwidth
/2, x
= left
&~1; i
> 0; i
--) {
309 *bits
++ = (X11DRV_DIB_MapColor( colors
, nColors
,
310 XGetPixel( bmpImage
, x
++, h
))
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);
324 #define check_xy(x,y) \
331 /***********************************************************************
332 * X11DRV_DIB_SetImageBits_RLE4
334 * SetDIBits for a 4-bit deep compressed DIB.
336 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
, DWORD width
,
337 DWORD dstwidth
, int left
, int *colors
, XImage
*bmpImage
)
339 int x
= 0, c
, length
;
340 const BYTE
*begin
= bits
;
342 dstwidth
+= left
; /* FIXME: avoid putting x<left pixels */
345 while ((int)lines
>= 0)
348 if (length
) { /* encoded */
351 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>> 4]);
355 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
367 case 1: /* eopicture */
375 default: /* absolute */
378 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>> 4]);
382 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
386 if ((bits
- begin
) & 1)
396 /***********************************************************************
397 * X11DRV_DIB_SetImageBits_8
399 * SetDIBits for an 8-bit deep DIB.
401 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
402 DWORD srcwidth
, DWORD dstwidth
, int left
,
403 int *colors
, XImage
*bmpImage
)
407 const BYTE
*bits
= srcbits
+ left
;
409 /* align to 32 bit */
410 DWORD linebytes
= (srcwidth
+ 3) & ~3;
415 for (h
= lines
- 1; h
>= 0; h
--) {
416 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
417 XPutPixel( bmpImage
, x
, h
, colors
[*bits
] );
419 bits
= (srcbits
+= linebytes
) + left
;
423 for (h
= 0; h
< lines
; h
++) {
424 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
425 XPutPixel( bmpImage
, x
, h
, colors
[*bits
] );
427 bits
= (srcbits
+= linebytes
) + left
;
432 /***********************************************************************
433 * X11DRV_DIB_GetImageBits_8
435 * GetDIBits for an 8-bit deep DIB.
437 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*srcbits
,
438 DWORD srcwidth
, DWORD dstwidth
, int left
,
439 int *colors
, int nColors
, XImage
*bmpImage
)
443 BYTE
*bits
= srcbits
+ left
;
445 /* align to 32 bit */
446 DWORD linebytes
= (srcwidth
+ 3) & ~3;
451 for (h
= lines
- 1; h
>= 0; h
--) {
452 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
453 if ( XGetPixel( bmpImage
, x
, h
) != colors
[*bits
] )
454 *bits
= X11DRV_DIB_MapColor( colors
, nColors
,
455 XGetPixel( bmpImage
, x
, h
) );
457 bits
= (srcbits
+= linebytes
) + left
;
461 for (h
= 0; h
< lines
; h
++) {
462 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
463 if ( XGetPixel( bmpImage
, x
, h
) != colors
[*bits
] )
464 *bits
= X11DRV_DIB_MapColor( colors
, nColors
,
465 XGetPixel( bmpImage
, x
, h
) );
467 bits
= (srcbits
+= linebytes
) + left
;
472 /***********************************************************************
473 * X11DRV_DIB_SetImageBits_RLE8
475 * SetDIBits for an 8-bit deep compressed DIB.
477 * This function rewritten 941113 by James Youngman. WINE blew out when I
478 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
480 * This was because the algorithm assumed that all RLE8 bitmaps end with the
481 * 'End of bitmap' escape code. This code is very much laxer in what it
482 * allows to end the expansion. Possibly too lax. See the note by
483 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
484 * bitmap should end with RleEnd, but on the other hand, software exists
485 * that produces ones that don't and Windows 3.1 doesn't complain a bit
488 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
489 * James A. Youngman <mbcstjy@afs.man.ac.uk>
493 enum Rle8_EscapeCodes
496 * Apologies for polluting your file's namespace...
498 RleEol
= 0, /* End of line */
499 RleEnd
= 1, /* End of bitmap */
500 RleDelta
= 2 /* Delta */
503 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
504 DWORD width
, DWORD dstwidth
,
505 int left
, int *colors
,
508 int x
; /* X-positon on each line. Increases. */
509 int line
; /* Line #. Starts at lines-1, decreases */
510 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
511 BYTE length
; /* The length pf a run */
512 BYTE color_index
; /* index into colors[] as read from bits */
513 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
514 int color
; /* value of colour[color_index] */
516 if (lines
== 0) /* Let's hope this doesn't happen. */
519 dstwidth
+= left
; /* FIXME: avoid putting x<left pixels */
522 * Note that the bitmap data is stored by Windows starting at the
523 * bottom line of the bitmap and going upwards. Within each line,
524 * the data is stored left-to-right. That's the reason why line
525 * goes from lines-1 to 0. [JAY]
535 * If the length byte is not zero (which is the escape value),
536 * We have a run of length pixels all the same colour. The colour
537 * index is stored next.
539 * If the length byte is zero, we need to read the next byte to
540 * know what to do. [JAY]
545 * [Run-Length] Encoded mode
547 color_index
= (*pIn
++); /* Get the colour index. */
548 color
= colors
[color_index
];
551 XPutPixel(bmpImage
, x
++, line
, color
);
556 * Escape codes (may be an absolute sequence though)
558 escape_code
= (*pIn
++);
561 case RleEol
: /* =0, end of line */
568 case RleEnd
: /* =1, end of bitmap */
571 * Not all RLE8 bitmaps end with this
572 * code. For example, Paint Shop Pro
573 * produces some that don't. That's (I think)
574 * what caused the previous implementation to
577 line
=-1; /* Cause exit from do loop. */
581 case RleDelta
: /* =2, a delta */
584 * Note that deltaing to line 0
585 * will cause an exit from the loop,
586 * which may not be what is intended.
587 * The fact that there is a delta in the bits
588 * almost certainly implies that there is data
589 * to follow. You may feel that we should
590 * jump to the top of the loop to avoid exiting
593 * TODO: Decide what to do here in that case. [JAY]
599 TRACE(bitmap
, "Delta to last line of bitmap "
600 "(wrongly?) causes loop exit\n");
605 default: /* >2, switch to absolute mode */
610 length
= escape_code
;
613 color_index
= (*pIn
++);
614 XPutPixel(bmpImage
, x
++, line
,
615 colors
[color_index
]);
619 * If you think for a moment you'll realise that the
620 * only time we could ever possibly read an odd
621 * number of bytes is when there is a 0x00 (escape),
622 * a value >0x02 (absolute mode) and then an odd-
623 * length run. Therefore this is the only place we
624 * need to worry about it. Everywhere else the
625 * bytes are always read in pairs. [JAY]
628 pIn
++; /* Throw away the pad byte. */
631 } /* switch (escape_code) : Escape sequence */
632 } /* process either an encoded sequence or an escape sequence */
634 /* We expect to come here more than once per line. */
635 } while (line
>= 0); /* Do this until the bitmap is filled */
638 * Everybody comes here at the end.
639 * Check how we exited the loop and print a message if it's a bit odd.
642 if ( (*(pIn
-2) != 0/*escape*/) || (*(pIn
-1)!= RleEnd
) )
644 TRACE(bitmap
, "End-of-bitmap "
645 "without (strictly) proper escape code. Last two "
646 "bytes were: %02X %02X.\n",
653 /***********************************************************************
654 * X11DRV_DIB_SetImageBits_16
656 * SetDIBits for a 16-bit deep DIB.
658 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
659 DWORD srcwidth
, DWORD dstwidth
, int left
,
660 DC
*dc
, XImage
*bmpImage
)
668 /* align to 32 bit */
669 DWORD linebytes
= (srcwidth
* 2 + 3) & ~3;
673 ptr
= (LPWORD
) srcbits
+ left
;
675 for (h
= lines
- 1; h
>= 0; h
--) {
676 for (x
= left
; x
< dstwidth
; x
++, ptr
++) {
678 r
= (BYTE
) ((val
& 0x7c00) >> 7);
679 g
= (BYTE
) ((val
& 0x03e0) >> 2);
680 b
= (BYTE
) ((val
& 0x001f) << 3);
681 XPutPixel( bmpImage
, x
, h
,
682 COLOR_ToPhysical(dc
, RGB(r
,g
,b
)) );
684 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
688 for (h
= 0; h
< lines
; h
++) {
689 for (x
= left
; x
< dstwidth
; x
++, ptr
++) {
691 r
= (BYTE
) ((val
& 0x7c00) >> 7);
692 g
= (BYTE
) ((val
& 0x03e0) >> 2);
693 b
= (BYTE
) ((val
& 0x001f) << 3);
694 XPutPixel( bmpImage
, x
, h
,
695 COLOR_ToPhysical(dc
, RGB(r
,g
,b
)) );
697 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
703 /***********************************************************************
704 * X11DRV_DIB_GetImageBits_16
706 * GetDIBits for an 16-bit deep DIB.
708 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*srcbits
,
709 DWORD srcwidth
, DWORD dstwidth
, int left
,
717 /* align to 32 bit */
718 DWORD linebytes
= (srcwidth
* 2 + 3) & ~3;
722 ptr
= (LPWORD
) srcbits
+ left
;
724 for (h
= lines
- 1; h
>= 0; h
--)
726 for (x
= left
; x
< dstwidth
; x
++, ptr
++)
728 COLORREF pixel
= COLOR_ToLogical( XGetPixel( bmpImage
, x
, h
) );
729 r
= (BYTE
) GetRValue(pixel
);
730 g
= (BYTE
) GetGValue(pixel
);
731 b
= (BYTE
) GetBValue(pixel
);
732 *ptr
= ( ((r
<< 7) & 0x7c00) | ((g
<< 2) & 0x03e0) | ((b
>> 3) & 0x001f) );
734 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
738 for (h
= 0; h
< lines
; h
++)
740 for (x
= left
; x
< dstwidth
; x
++, ptr
++)
742 COLORREF pixel
= COLOR_ToLogical( XGetPixel( bmpImage
, x
, h
) );
743 r
= (BYTE
) GetRValue(pixel
);
744 g
= (BYTE
) GetGValue(pixel
);
745 b
= (BYTE
) GetBValue(pixel
);
746 *ptr
= ( ((r
<< 7) & 0x7c00) | ((g
<< 2) & 0x03e0) | ((b
>> 3) & 0x001f) );
749 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
756 /***********************************************************************
757 * X11DRV_DIB_SetImageBits_24
759 * SetDIBits for a 24-bit deep DIB.
761 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
762 DWORD srcwidth
, DWORD dstwidth
, int left
,
763 DC
*dc
, XImage
*bmpImage
)
766 const BYTE
*bits
= srcbits
+ left
* 3;
769 /* align to 32 bit */
770 DWORD linebytes
= (srcwidth
* 3 + 3) & ~3;
774 /* "bits" order is reversed for some reason */
777 for (h
= lines
- 1; h
>= 0; h
--) {
778 for (x
= left
; x
< dstwidth
; x
++, bits
+= 3) {
779 XPutPixel( bmpImage
, x
, h
,
780 COLOR_ToPhysical(dc
, RGB(bits
[2],bits
[1],bits
[0])));
782 bits
= (srcbits
+= linebytes
) + left
* 3;
786 for (h
= 0; h
< lines
; h
++) {
787 for (x
= left
; x
< dstwidth
; x
++, bits
+= 3) {
788 XPutPixel( bmpImage
, x
, h
,
789 COLOR_ToPhysical(dc
, RGB(bits
[2],bits
[1],bits
[0])));
791 bits
= (srcbits
+= linebytes
) + left
* 3;
797 /***********************************************************************
798 * X11DRV_DIB_GetImageBits_24
800 * GetDIBits for an 24-bit deep DIB.
802 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*srcbits
,
803 DWORD srcwidth
, DWORD dstwidth
, int left
,
808 BYTE
*bits
= srcbits
+ (left
* 3);
810 /* align to 32 bit */
811 DWORD linebytes
= (srcwidth
* 3 + 3) & ~3;
816 for (h
= lines
- 1; h
>= 0; h
--)
818 for (x
= left
; x
< dstwidth
; x
++, bits
+= 3)
820 COLORREF pixel
= COLOR_ToLogical( XGetPixel( bmpImage
, x
, h
) );
821 bits
[0] = GetRValue(pixel
);
822 bits
[1] = GetGValue(pixel
);
823 bits
[2] = GetBValue(pixel
);
825 bits
= (srcbits
+= linebytes
) + (left
* 3);
829 for (h
= 0; h
< lines
; h
++)
831 for (x
= left
; x
< dstwidth
; x
++, bits
+= 3)
833 COLORREF pixel
= COLOR_ToLogical( XGetPixel( bmpImage
, x
, h
) );
834 bits
[0] = GetRValue(pixel
);
835 bits
[1] = GetGValue(pixel
);
836 bits
[2] = GetBValue(pixel
);
839 bits
= (srcbits
+= linebytes
) + (left
* 3);
845 /***********************************************************************
846 * X11DRV_DIB_SetImageBits_32
848 * SetDIBits for a 32-bit deep DIB.
850 static void X11DRV_DIB_SetImageBits_32( int lines
, const BYTE
*srcbits
,
851 DWORD srcwidth
, DWORD dstwidth
, int left
,
852 DC
*dc
, XImage
*bmpImage
)
855 const BYTE
*bits
= srcbits
+ left
* 4;
858 DWORD linebytes
= (srcwidth
* 4);
863 for (h
= lines
- 1; h
>= 0; h
--) {
864 for (x
= left
; x
< dstwidth
; x
++, bits
+= 4) {
865 XPutPixel( bmpImage
, x
, h
,
866 COLOR_ToPhysical(dc
, RGB(bits
[2],bits
[1],bits
[0])));
868 bits
= (srcbits
+= linebytes
) + left
* 4;
872 for (h
= 0; h
< lines
; h
++) {
873 for (x
= left
; x
< dstwidth
; x
++, bits
+= 4) {
874 XPutPixel( bmpImage
, x
, h
,
875 COLOR_ToPhysical(dc
, RGB(bits
[2],bits
[1],bits
[0])));
877 bits
= (srcbits
+= linebytes
) + left
* 4;
883 /***********************************************************************
884 * X11DRV_DIB_GetImageBits_32
886 * GetDIBits for an 32-bit deep DIB.
888 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*srcbits
,
889 DWORD srcwidth
, DWORD dstwidth
, int left
,
894 BYTE
*bits
= srcbits
+ (left
* 4);
896 /* align to 32 bit */
897 DWORD linebytes
= (srcwidth
* 4);
902 for (h
= lines
- 1; h
>= 0; h
--)
904 for (x
= left
; x
< dstwidth
; x
++, bits
+= 4)
906 COLORREF pixel
= COLOR_ToLogical( XGetPixel( bmpImage
, x
, h
) );
907 bits
[0] = GetRValue(pixel
);
908 bits
[1] = GetGValue(pixel
);
909 bits
[2] = GetBValue(pixel
);
911 bits
= (srcbits
+= linebytes
) + (left
* 4);
915 for (h
= 0; h
< lines
; h
++)
917 for (x
= left
; x
< dstwidth
; x
++, bits
+= 4)
919 COLORREF pixel
= COLOR_ToLogical( XGetPixel( bmpImage
, x
, h
) );
920 bits
[0] = GetRValue(pixel
);
921 bits
[1] = GetGValue(pixel
);
922 bits
[2] = GetBValue(pixel
);
925 bits
= (srcbits
+= linebytes
) + (left
* 4);
931 /***********************************************************************
932 * X11DRV_DIB_SetImageBits
934 * Transfer the bits to an X image.
935 * Helper function for SetDIBits() and SetDIBitsToDevice().
936 * The Xlib critical section must be entered before calling this function.
938 int X11DRV_DIB_SetImageBits( const DIB_SETIMAGEBITS_DESCR
*descr
)
940 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
943 if ( descr
->dc
&& descr
->dc
->w
.flags
& DC_DIRTY
)
944 CLIPPING_UpdateGCRegion( descr
->dc
);
947 bmpImage
= descr
->image
;
949 XCREATEIMAGE( bmpImage
, descr
->infoWidth
, lines
, descr
->depth
);
951 /* Transfer the pixels */
952 switch(descr
->infoBpp
)
955 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
956 descr
->width
, descr
->xSrc
, descr
->colorMap
,
960 if (descr
->compression
)
961 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
962 descr
->infoWidth
, descr
->width
,
963 descr
->xSrc
, descr
->colorMap
,
966 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
967 descr
->infoWidth
, descr
->width
,
968 descr
->xSrc
, descr
->colorMap
,
972 if (descr
->compression
)
973 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
974 descr
->infoWidth
, descr
->width
,
976 descr
->colorMap
, bmpImage
);
978 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
979 descr
->infoWidth
, descr
->width
,
980 descr
->xSrc
, descr
->colorMap
,
985 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
986 descr
->infoWidth
, descr
->width
,
987 descr
->xSrc
, descr
->dc
, bmpImage
);
990 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
991 descr
->infoWidth
, descr
->width
,
992 descr
->xSrc
, descr
->dc
, bmpImage
);
995 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
996 descr
->infoWidth
, descr
->width
,
997 descr
->xSrc
, descr
->dc
, bmpImage
);
1000 WARN(bitmap
, "(%d): Invalid depth\n", descr
->infoBpp
);
1004 XPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
1005 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
1006 descr
->width
, descr
->height
);
1008 if (!descr
->image
) XDestroyImage( bmpImage
);
1012 /***********************************************************************
1013 * X11DRV_DIB_GetImageBits
1015 * Transfer the bits from an X image.
1016 * The Xlib critical section must be entered before calling this function.
1018 int X11DRV_DIB_GetImageBits( const DIB_SETIMAGEBITS_DESCR
*descr
)
1020 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
1024 bmpImage
= descr
->image
;
1026 XCREATEIMAGE( bmpImage
, descr
->infoWidth
, lines
, descr
->depth
);
1028 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
1029 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
1030 bmpImage
, descr
->xSrc
, descr
->ySrc
);
1032 /* Transfer the pixels */
1033 switch(descr
->infoBpp
)
1036 FIXME(bitmap
, "Depth 1 not yet supported!\n");
1040 if (descr
->compression
)
1041 FIXME(bitmap
, "Compression not yet supported!\n");
1043 X11DRV_DIB_GetImageBits_4( descr
->lines
,
1044 (LPVOID
)descr
->bits
, descr
->infoWidth
,
1045 descr
->width
, descr
->xSrc
,
1046 descr
->colorMap
, descr
->nColorMap
,
1051 if (descr
->compression
)
1052 FIXME(bitmap
, "Compression not yet supported!\n");
1054 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
1055 descr
->infoWidth
, descr
->width
,
1056 descr
->xSrc
, descr
->colorMap
,
1057 descr
->nColorMap
, bmpImage
);
1062 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
1064 descr
->width
, descr
->xSrc
, bmpImage
);
1068 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
1070 descr
->width
, descr
->xSrc
, bmpImage
);
1074 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
1076 descr
->width
, descr
->xSrc
, bmpImage
);
1080 WARN(bitmap
, "(%d): Invalid depth\n", descr
->infoBpp
);
1084 if (!descr
->image
) XDestroyImage( bmpImage
);
1088 /*************************************************************************
1089 * X11DRV_SetDIBitsToDevice
1092 INT32
X11DRV_SetDIBitsToDevice( DC
*dc
, INT32 xDest
, INT32 yDest
, DWORD cx
,
1093 DWORD cy
, INT32 xSrc
, INT32 ySrc
,
1094 UINT32 startscan
, UINT32 lines
, LPCVOID bits
,
1095 const BITMAPINFO
*info
, UINT32 coloruse
)
1097 DIB_SETIMAGEBITS_DESCR descr
;
1098 DWORD width
, oldcy
= cy
;
1100 int height
, tmpheight
;
1103 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
1104 &descr
.infoBpp
, &descr
.compression
) == -1)
1107 if (height
< 0) height
= -height
;
1108 if (!lines
|| (startscan
>= height
)) return 0;
1109 if (startscan
+ lines
> height
) lines
= height
- startscan
;
1110 if (ySrc
< startscan
) ySrc
= startscan
;
1111 else if (ySrc
>= startscan
+ lines
) return 0;
1112 if (xSrc
>= width
) return 0;
1113 if (ySrc
+ cy
>= startscan
+ lines
) cy
= startscan
+ lines
- ySrc
;
1114 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
1115 if (!cx
|| !cy
) return 0;
1117 DC_SetupGCForText( dc
); /* To have the correct colors */
1118 TSXSetFunction( display
, dc
->u
.x
.gc
, DC_XROPfunction
[dc
->w
.ROPmode
-1] );
1120 if (descr
.infoBpp
<= 8)
1122 descr
.colorMap
= X11DRV_DIB_BuildColorMap( dc
, coloruse
,
1124 info
, &descr
.nColorMap
);
1125 if (!descr
.colorMap
)
1132 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
1133 descr
.infoWidth
= width
;
1134 descr
.depth
= dc
->w
.bitsPerPixel
;
1135 descr
.drawable
= dc
->u
.x
.drawable
;
1136 descr
.gc
= dc
->u
.x
.gc
;
1138 descr
.ySrc
= tmpheight
>= 0 ? lines
-(ySrc
-startscan
)-cy
+(oldcy
-cy
)
1140 descr
.xDest
= dc
->w
.DCOrgX
+ XLPTODP( dc
, xDest
);
1141 descr
.yDest
= dc
->w
.DCOrgY
+ YLPTODP( dc
, yDest
) +
1142 (tmpheight
>= 0 ? oldcy
-cy
: 0);
1146 EnterCriticalSection( &X11DRV_CritSection
);
1147 result
= CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
1148 LeaveCriticalSection( &X11DRV_CritSection
);
1150 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);