2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
13 # ifdef HAVE_SYS_SHM_H
16 # ifdef HAVE_SYS_IPC_H
19 #endif /* defined(HAVE_LIBXXSHM) */
25 #include "debugtools.h"
29 #include "selectors.h"
32 DEFAULT_DEBUG_CHANNEL(bitmap
);
33 DECLARE_DEBUG_CHANNEL(x11drv
);
35 static int bitmapDepthTable
[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
36 static int ximageDepthTable
[] = { 0, 0, 0, 0, 0, 0, 0 };
38 static int XShmErrorFlag
= 0;
40 /***********************************************************************
43 BOOL
X11DRV_DIB_Init(void)
48 for( i
= 0; bitmapDepthTable
[i
]; i
++ )
50 testimage
= TSXCreateImage(display
, X11DRV_GetVisual(),
51 bitmapDepthTable
[i
], ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
52 if( testimage
) ximageDepthTable
[i
] = testimage
->bits_per_pixel
;
54 TSXDestroyImage(testimage
);
60 /***********************************************************************
61 * X11DRV_DIB_GetXImageWidthBytes
63 * Return the width of an X image in bytes
65 int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
69 if (!ximageDepthTable
[0]) {
72 for( i
= 0; bitmapDepthTable
[i
] ; i
++ )
73 if( bitmapDepthTable
[i
] == depth
)
74 return (4 * ((width
* ximageDepthTable
[i
] + 31)/32));
76 WARN("(%d): Unsupported depth\n", depth
);
80 /***********************************************************************
81 * X11DRV_DIB_BuildColorMap
83 * Build the color map from the bitmap palette. Should not be called
84 * for a >8-bit deep bitmap.
86 int *X11DRV_DIB_BuildColorMap( DC
*dc
, WORD coloruse
, WORD depth
,
87 const BITMAPINFO
*info
, int *nColors
)
94 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
96 colors
= info
->bmiHeader
.biClrUsed
;
97 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
98 colorPtr
= (WORD
*)info
->bmiColors
;
100 else /* assume BITMAPCOREINFO */
102 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
103 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
108 ERR("called with >256 colors!\n");
112 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
113 colors
* sizeof(int) )))
116 if (coloruse
== DIB_RGB_COLORS
)
120 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
122 if (depth
== 1) /* Monochrome */
123 for (i
= 0; i
< colors
; i
++, rgb
++)
124 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
125 rgb
->rgbBlue
> 255*3/2);
127 for (i
= 0; i
< colors
; i
++, rgb
++)
128 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbRed
,
134 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
136 if (depth
== 1) /* Monochrome */
137 for (i
= 0; i
< colors
; i
++, rgb
++)
138 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
139 rgb
->rgbtBlue
> 255*3/2);
141 for (i
= 0; i
< colors
; i
++, rgb
++)
142 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbtRed
,
147 else /* DIB_PAL_COLORS */
149 for (i
= 0; i
< colors
; i
++, colorPtr
++)
150 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, PALETTEINDEX(*colorPtr
) );
158 /***********************************************************************
159 * X11DRV_DIB_MapColor
161 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
, int oldcol
)
165 if ((oldcol
< nPhysMap
) && (physMap
[oldcol
] == phys
))
168 for (color
= 0; color
< nPhysMap
; color
++)
169 if (physMap
[color
] == phys
)
172 WARN("Strange color %08x\n", phys
);
177 /*********************************************************************
178 * X11DRV_DIB_GetNearestIndex
180 * Helper for X11DRV_DIB_GetDIBits.
181 * Returns the nearest colour table index for a given RGB.
182 * Nearest is defined by minimizing the sum of the squares.
184 static INT
X11DRV_DIB_GetNearestIndex(RGBQUAD
*colormap
, int numColors
, BYTE r
, BYTE g
, BYTE b
)
186 INT i
, best
= -1, diff
, bestdiff
= -1;
189 for(color
= colormap
, i
= 0; i
< numColors
; color
++, i
++) {
190 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
191 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
192 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
195 if(best
== -1 || diff
< bestdiff
) {
203 /***********************************************************************
204 * X11DRV_DIB_SetImageBits_1_Line
206 * Handles a single line of 1 bit data.
208 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth
, int left
, int *colors
,
209 XImage
*bmpImage
, int h
, const BYTE
*bits
)
214 if((extra
= (left
& 7)) != 0) {
221 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
222 for (i
= dstwidth
/8, x
= left
; i
> 0; i
--)
225 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
226 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 6) & 1] );
227 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 5) & 1] );
228 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 4) & 1] );
229 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 3) & 1] );
230 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 2) & 1] );
231 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 1) & 1] );
232 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 1] );
237 case 7: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
238 case 6: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
239 case 5: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
240 case 4: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
241 case 3: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
242 case 2: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
243 case 1: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
247 /***********************************************************************
248 * X11DRV_DIB_SetImageBits_1
250 * SetDIBits for a 1-bit deep DIB.
252 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
253 DWORD srcwidth
, DWORD dstwidth
, int left
,
254 int *colors
, XImage
*bmpImage
)
259 DWORD linebytes
= ((srcwidth
+ 31) & ~31) / 8;
262 for (h
= lines
-1; h
>=0; h
--) {
263 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
265 srcbits
+= linebytes
;
269 for (h
= 0; h
< lines
; h
++) {
270 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
272 srcbits
+= linebytes
;
277 /***********************************************************************
278 * X11DRV_DIB_GetImageBits_1
280 * GetDIBits for a 1-bit deep DIB.
282 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
283 DWORD dstwidth
, DWORD srcwidth
,
284 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
292 DWORD linebytes
= ((dstwidth
+ 31) & ~31) / 8;
296 dstbits
= dstbits
+ linebytes
* (lines
- 1);
297 linebytes
= -linebytes
;
302 switch(bmpImage
->depth
) {
305 /* ==== monochrome bitmap to monochrome dib ==== */
307 /* ==== 4 colormap bitmap to monochrome dib ==== */
308 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
312 for (h
= lines
- 1; h
>= 0; h
--) {
313 for (x
= 0; x
< dstwidth
; x
++) {
314 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
315 if (!(x
&7)) *bits
= 0;
316 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2,
319 val
.peBlue
) << (7 - (x
& 7)));
320 if ((x
&7)==7) bits
++;
322 bits
= (dstbits
+= linebytes
);
325 else goto notsupported
;
330 /* ==== 8 colormap bitmap to monochrome dib ==== */
331 if ( bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
336 for( h
= lines
- 1; h
>= 0; h
-- ) {
337 srcpixel
= bmpImage
->data
+ (h
*bmpImage
->bytes_per_line
);
338 for( x
= 0; x
< dstwidth
; x
++ ) {
339 if (!(x
&7)) *bits
= 0;
340 val
= srccolors
[(int)*srcpixel
++];
341 *bits
|= ( X11DRV_DIB_GetNearestIndex(colors
, 2,
344 val
.peBlue
) << (7-(x
&7)) );
345 if ((x
&7)==7) bits
++;
347 bits
= (dstbits
+= linebytes
);
350 else goto notsupported
;
359 /* ==== 555 BGR bitmap to monochrome dib ==== */
360 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x1f)
362 for( h
= lines
- 1; h
>= 0; h
--) {
363 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
364 for( x
= 0; x
< dstwidth
; x
++) {
365 if (!(x
&7)) *bits
= 0;
367 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
368 ((val
>> 7) & 0xf8) |
370 ((val
>> 2) & 0xf8) |
372 ((val
<< 3) & 0xf8) |
373 ((val
>> 2) & 0x7) ) << (7-(x
&7)) );
374 if ((x
&7)==7) bits
++;
376 bits
= (dstbits
+= linebytes
);
379 /* ==== 555 RGB bitmap to monochrome dib ==== */
380 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
382 for( h
= lines
- 1; h
>= 0; h
--)
384 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
385 for( x
= 0; x
< dstwidth
; x
++) {
386 if (!(x
&1)) *bits
= 0;
388 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
389 ((val
<< 3) & 0xf8) |
391 ((val
>> 2) & 0xf8) |
393 ((val
>> 7) & 0xf8) |
394 ((val
>> 12) & 0x7) ) << (7-(x
&7)) );
395 if ((x
&7)==7) bits
++;
397 bits
= (dstbits
+= linebytes
);
400 else goto notsupported
;
409 /* ==== 565 BGR bitmap to monochrome dib ==== */
410 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
412 for( h
= lines
- 1; h
>= 0; h
--)
414 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
415 for( x
= 0; x
< dstwidth
; x
++) {
416 if (!(x
&7)) *bits
= 0;
418 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
419 ((val
>> 8) & 0xf8) |
421 ((val
>> 3) & 0xfc) |
423 ((val
<< 3) & 0xf8) |
424 ((val
>> 2) & 0x7) ) << (7-(x
&7)) );
425 if ((x
&7)==7) bits
++;
427 bits
= (dstbits
+= linebytes
);
430 /* ==== 565 RGB bitmap to monochrome dib ==== */
431 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
433 for( h
= lines
- 1; h
>= 0; h
--)
435 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
436 for( x
= 0; x
< dstwidth
; x
++) {
437 if (!(x
&7)) *bits
= 0;
439 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
440 ((val
<< 3) & 0xf8) |
442 ((val
>> 3) & 0xfc) |
444 ((val
>> 8) & 0xf8) |
445 ((val
>> 13) & 0x7) ) << (7-(x
&7)) );
446 if ((x
&7)==7) bits
++;
448 bits
= (dstbits
+= linebytes
);
451 else goto notsupported
;
460 /* ==== 24/32 BGR bitmap to monochrome dib ==== */
461 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
463 for (h
= lines
- 1; h
>= 0; h
--)
465 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
466 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4) {
467 if (!(x
&7)) *bits
= 0;
468 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2, srcpixel
[2] , srcpixel
[1], srcpixel
[0]) << (7-(x
&7)) );
469 if ((x
&7)==7) bits
++;
471 bits
= (dstbits
+= linebytes
);
474 /* ==== 24/32 RGB bitmap to monochrome dib ==== */
475 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
477 for (h
= lines
- 1; h
>= 0; h
--)
479 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
480 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4) {
481 if (!(x
& 7)) *bits
= 0;
482 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2, srcpixel
[0] , srcpixel
[1], srcpixel
[2]) << (7-(x
&7)) );
483 if ((x
& 7) == 7) bits
++;
485 bits
= (dstbits
+= linebytes
);
488 else goto notsupported
;
492 default: /* ? bit bmp -> monochrome DIB */
495 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
497 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
498 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
499 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
501 for( h
= lines
- 1; h
>= 0; h
-- ) {
502 for( x
= 0; x
< dstwidth
; x
++ ) {
503 if (!(x
&7)) *bits
= 0;
504 *bits
|= (XGetPixel( bmpImage
, x
, h
) >= white
)
506 if ((x
&7)==7) bits
++;
508 bits
= (dstbits
+= linebytes
);
515 /***********************************************************************
516 * X11DRV_DIB_SetImageBits_4
518 * SetDIBits for a 4-bit deep DIB.
520 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
521 DWORD srcwidth
, DWORD dstwidth
, int left
,
522 int *colors
, XImage
*bmpImage
)
526 const BYTE
*bits
= srcbits
+ (left
>> 1);
529 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
537 for (h
= lines
-1; h
>= 0; h
--) {
538 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
540 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
541 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
543 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
544 srcbits
+= linebytes
;
545 bits
= srcbits
+ (left
>> 1);
549 for (h
= 0; h
< lines
; h
++) {
550 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
552 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
553 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
555 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
556 srcbits
+= linebytes
;
557 bits
= srcbits
+ (left
>> 1);
564 /***********************************************************************
565 * X11DRV_DIB_GetImageBits_4
567 * GetDIBits for a 4-bit deep DIB.
569 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
570 DWORD srcwidth
, DWORD dstwidth
,
571 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
580 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
585 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
586 linebytes
= -linebytes
;
591 switch(bmpImage
->depth
) {
594 /* ==== monochrome bitmap to 4 colormap dib ==== */
596 /* ==== 4 colormap bitmap to 4 colormap dib ==== */
597 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
601 for (h
= lines
-1; h
>= 0; h
--) {
602 for (x
= 0; x
< dstwidth
; x
++) {
603 if (!(x
&1)) *bits
= 0;
604 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
605 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 16,
608 val
.peBlue
) << (4-((x
&1)<<2)));
609 if ((x
&1)==1) bits
++;
611 bits
= (dstbits
+= linebytes
);
614 else goto notsupported
;
619 /* ==== 8 colormap bitmap to 4 colormap dib ==== */
620 if ( bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
624 for( h
= lines
- 1; h
>= 0; h
-- ) {
625 srcpixel
= bmpImage
->data
+ (h
*bmpImage
->bytes_per_line
);
626 for( x
= 0; x
< dstwidth
; x
++ ) {
627 if (!(x
&1)) *bits
= 0;
628 val
= srccolors
[(int)*srcpixel
++];
629 *bits
|= ( X11DRV_DIB_GetNearestIndex(colors
, 16,
632 val
.peBlue
) << (4*(1-(x
&1))) );
633 if ((x
&1)==1) bits
++;
635 bits
= (dstbits
+= linebytes
);
638 else goto notsupported
;
647 /* ==== 555 BGR bitmap to 4 colormap dib ==== */
648 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x1f)
650 for( h
= lines
- 1; h
>= 0; h
--) {
651 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
652 for( x
= 0; x
< dstwidth
; x
++) {
653 if (!(x
&1)) *bits
= 0;
655 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
656 ((val
>> 7) & 0xf8) |
658 ((val
>> 2) & 0xf8) |
660 ((val
<< 3) & 0xf8) |
661 ((val
>> 2) & 0x7) ) << ((1-(x
&1))<<2) );
662 if ((x
&1)==1) bits
++;
664 bits
= (dstbits
+= linebytes
);
667 /* ==== 555 RGB bitmap to 4 colormap dib ==== */
668 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
670 for( h
= lines
- 1; h
>= 0; h
--)
672 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
673 for( x
= 0; x
< dstwidth
; x
++) {
674 if (!(x
&1)) *bits
= 0;
676 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
677 ((val
<< 3) & 0xf8) |
679 ((val
>> 2) & 0xfc) |
681 ((val
>> 7) & 0xf8) |
682 ((val
>> 12) & 0x7) ) << ((1-(x
&1))<<2) );
683 if ((x
&1)==1) bits
++;
685 bits
= (dstbits
+= linebytes
);
688 else goto notsupported
;
697 /* ==== 565 BGR bitmap to 4 colormap dib ==== */
698 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
700 for( h
= lines
- 1; h
>= 0; h
--)
702 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
703 for( x
= 0; x
< dstwidth
; x
++) {
704 if (!(x
&1)) *bits
= 0;
706 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
707 ((val
>> 8) & 0xf8) |
709 ((val
>> 3) & 0xfc) |
711 ((val
<< 3) & 0xf8) |
712 ((val
>> 2) & 0x7) ) << ((1-(x
&1))<<2) );
713 if ((x
&1)==1) bits
++;
715 bits
= (dstbits
+= linebytes
);
718 /* ==== 565 RGB bitmap to 4 colormap dib ==== */
719 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
721 for( h
= lines
- 1; h
>= 0; h
--)
723 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
724 for( x
= 0; x
< dstwidth
; x
++) {
725 if (!(x
&1)) *bits
= 0;
727 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
728 ((val
<< 3) & 0xf8) |
730 ((val
>> 3) & 0xfc) |
732 ((val
>> 8) & 0xf8) |
733 ((val
>> 13) & 0x7) ) << ((1-(x
&1))<<2) );
734 if ((x
&1)==1) bits
++;
736 bits
= (dstbits
+= linebytes
);
739 else goto notsupported
;
748 /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
749 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
751 for (h
= lines
- 1; h
>= 0; h
--)
753 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
754 for (x
= 0; x
< dstwidth
; x
+=2, srcpixel
+=8) /* 2 pixels at a time */
755 *bits
++ = (X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[2] , srcpixel
[1], srcpixel
[0]) << 4) |
756 X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[6] , srcpixel
[5], srcpixel
[4]);
757 bits
= (dstbits
+= linebytes
);
760 /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
761 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
763 for (h
= lines
- 1; h
>= 0; h
--)
765 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
766 for (x
= 0; x
< dstwidth
; x
+=2, srcpixel
+=8) /* 2 pixels at a time */
767 *bits
++ = (X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[0] , srcpixel
[1], srcpixel
[2]) << 4) |
768 X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[4] , srcpixel
[5], srcpixel
[6]);
769 bits
= (dstbits
+= linebytes
);
772 else goto notsupported
;
776 default: /* ? bit bmp -> 4 bit DIB */
778 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
779 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
780 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
781 for (h
= lines
-1; h
>= 0; h
--) {
782 for (x
= 0; x
< dstwidth
/2; x
++) {
783 *bits
++ = (X11DRV_DIB_MapColor((int *)colors
, 16,
784 XGetPixel( bmpImage
, x
++, h
), 0) << 4)
785 | (X11DRV_DIB_MapColor((int *)colors
, 16,
786 XGetPixel( bmpImage
, x
++, h
), 0) & 0x0f);
789 *bits
= (X11DRV_DIB_MapColor((int *)colors
, 16,
790 XGetPixel( bmpImage
, x
++, h
), 0) << 4);
791 bits
= (dstbits
+= linebytes
);
797 /***********************************************************************
798 * X11DRV_DIB_SetImageBits_RLE4
800 * SetDIBits for a 4-bit deep compressed DIB.
802 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
803 DWORD width
, DWORD dstwidth
,
804 int left
, int *colors
,
807 int x
= 0, c
, length
;
808 const BYTE
*begin
= bits
;
812 while ((int)lines
>= 0) {
814 if (length
) { /* encoded */
822 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>>4]);
830 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
841 case 1: /* eopicture */
847 FIXME_(x11drv
)("x-delta is too large?\n");
853 default: /* absolute */
861 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>> 4]);
869 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
872 if ((bits
- begin
) & 1)
881 /***********************************************************************
882 * X11DRV_DIB_SetImageBits_8
884 * SetDIBits for an 8-bit deep DIB.
886 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
887 DWORD srcwidth
, DWORD dstwidth
, int left
,
888 const int *colors
, XImage
*bmpImage
)
894 /* align to 32 bit */
895 DWORD linebytes
= (srcwidth
+ 3) & ~3;
902 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
903 linebytes
= -linebytes
;
906 bits
= srcbits
+ left
;
908 switch (bmpImage
->depth
) {
911 #if defined(__i386__) && defined(__GNUC__)
912 /* Some X servers might have 32 bit/ 16bit deep pixel */
913 if (lines
&& (dstwidth
!=left
) && (bmpImage
->bits_per_pixel
== 16))
915 for (h
= lines
; h
--; ) {
916 int _cl1
,_cl2
; /* temp outputs for asm below */
917 /* Borrowed from DirectDraw */
918 __asm__
__volatile__(
923 " movw (%%edx,%%eax,4),%%ax\n"
927 :"=S" (bits
), "=D" (_cl1
), "=c" (_cl2
)
929 "D" (bmpImage
->data
+h
*bmpImage
->bytes_per_line
+left
*2),
932 :"eax", "cc", "memory"
934 bits
= (srcbits
+= linebytes
) + left
;
941 break; /* use slow generic case below */
944 for (h
= lines
- 1; h
>= 0; h
--) {
945 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
946 color
= colors
[*bits
];
947 XPutPixel( bmpImage
, x
, h
, colors
[*bits
] );
949 bits
= (srcbits
+= linebytes
) + left
;
953 /***********************************************************************
954 * X11DRV_DIB_GetImageBits_8
956 * GetDIBits for an 8-bit deep DIB.
958 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
959 DWORD srcwidth
, DWORD dstwidth
,
960 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
967 /* align to 32 bit */
968 DWORD linebytes
= (srcwidth
+ 3) & ~3;
973 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
974 linebytes
= -linebytes
;
981 This condition is true when GetImageBits has been called by UpdateDIBSection.
982 For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
983 for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
985 if (!srccolors
) goto updatesection
;
987 switch(bmpImage
->depth
) {
990 /* ==== monochrome bitmap to 8 colormap dib ==== */
992 /* ==== 4 colormap bitmap to 8 colormap dib ==== */
993 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
997 for (h
= lines
- 1; h
>= 0; h
--) {
998 for (x
= 0; x
< dstwidth
; x
++) {
999 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
1000 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256, val
.peRed
,
1001 val
.peGreen
, val
.peBlue
);
1003 bits
= (dstbits
+= linebytes
);
1006 else goto notsupported
;
1011 /* ==== 8 colormap bitmap to 8 colormap dib ==== */
1012 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1017 for (h
= lines
- 1; h
>= 0; h
--) {
1018 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1019 for (x
= 0; x
< dstwidth
; x
++) {
1020 val
= srccolors
[(int)*srcpixel
++];
1021 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256, val
.peRed
,
1022 val
.peGreen
, val
.peBlue
);
1024 bits
= (dstbits
+= linebytes
);
1027 else goto notsupported
;
1036 /* ==== 555 BGR bitmap to 8 colormap dib ==== */
1037 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
1039 for( h
= lines
- 1; h
>= 0; h
--)
1041 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1042 for( x
= 0; x
< dstwidth
; x
++ )
1045 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1046 ((val
>> 7) & 0xf8) |
1047 ((val
>> 12) & 0x7),
1048 ((val
>> 2) & 0xf8) |
1050 ((val
<< 3) & 0xf8) |
1051 ((val
>> 2) & 0x7) );
1053 bits
= (dstbits
+= linebytes
);
1056 /* ==== 555 RGB bitmap to 8 colormap dib ==== */
1057 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
1059 for( h
= lines
- 1; h
>= 0; h
--)
1061 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1062 for( x
= 0; x
< dstwidth
; x
++ )
1065 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1066 ((val
<< 3) & 0xf8) |
1068 ((val
>> 2) & 0xf8) |
1070 ((val
>> 7) & 0xf8) |
1071 ((val
>> 12) & 0x7) );
1073 bits
= (dstbits
+= linebytes
);
1076 else goto notsupported
;
1085 /* ==== 565 BGR bitmap to 8 colormap dib ==== */
1086 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
1088 for( h
= lines
- 1; h
>= 0; h
--)
1090 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1091 for( x
= 0; x
< dstwidth
; x
++ )
1094 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1095 ((val
>> 8) & 0xf8) |
1096 ((val
>> 13) & 0x7),
1097 ((val
>> 3) & 0xfc) |
1099 ((val
<< 3) & 0xf8) |
1100 ((val
>> 2) & 0x7) );
1102 bits
= (dstbits
+= linebytes
);
1105 /* ==== 565 RGB bitmap to 8 colormap dib ==== */
1106 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
1108 for( h
= lines
- 1; h
>= 0; h
--)
1110 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1111 for( x
= 0; x
< dstwidth
; x
++ )
1114 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1115 ((val
<< 3) & 0xf8) |
1117 ((val
>> 3) & 0x00fc) |
1119 ((val
>> 8) & 0x00f8) |
1120 ((val
>> 13) & 0x7) );
1122 bits
= (dstbits
+= linebytes
);
1125 else goto notsupported
;
1134 /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
1135 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1137 for (h
= lines
- 1; h
>= 0; h
--)
1139 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1140 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4)
1141 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256,
1142 srcpixel
[2] , srcpixel
[1], *srcpixel
);
1143 bits
= (dstbits
+= linebytes
);
1146 /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
1147 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1149 for (h
= lines
- 1; h
>= 0; h
--)
1151 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1152 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4)
1153 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256,
1154 *srcpixel
, srcpixel
[1], srcpixel
[2]);
1155 bits
= (dstbits
+= linebytes
);
1159 else goto notsupported
;
1163 default: /* ? bit bmp -> 8 bit DIB */
1165 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
1166 bmpImage
->depth
, (int)bmpImage
->red_mask
,
1167 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1169 for (h
= lines
- 1; h
>= 0; h
--) {
1170 for (x
= 0; x
< dstwidth
; x
++, bits
++) {
1171 *bits
= X11DRV_DIB_MapColor((int *)colors
, 256,
1172 XGetPixel( bmpImage
, x
, h
), *bits
);
1174 bits
= (dstbits
+= linebytes
);
1180 /***********************************************************************
1181 * X11DRV_DIB_SetImageBits_RLE8
1183 * SetDIBits for an 8-bit deep compressed DIB.
1185 * This function rewritten 941113 by James Youngman. WINE blew out when I
1186 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1188 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1189 * 'End of bitmap' escape code. This code is very much laxer in what it
1190 * allows to end the expansion. Possibly too lax. See the note by
1191 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1192 * bitmap should end with RleEnd, but on the other hand, software exists
1193 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1196 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1197 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1201 enum Rle8_EscapeCodes
1204 * Apologies for polluting your file's namespace...
1206 RleEol
= 0, /* End of line */
1207 RleEnd
= 1, /* End of bitmap */
1208 RleDelta
= 2 /* Delta */
1211 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
1212 DWORD width
, DWORD dstwidth
,
1213 int left
, int *colors
,
1216 int x
; /* X-positon on each line. Increases. */
1217 int line
; /* Line #. Starts at lines-1, decreases */
1218 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
1219 BYTE length
; /* The length pf a run */
1220 BYTE color_index
; /* index into colors[] as read from bits */
1221 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
1222 int color
; /* value of colour[color_index] */
1224 if (lines
== 0) /* Let's hope this doesn't happen. */
1228 * Note that the bitmap data is stored by Windows starting at the
1229 * bottom line of the bitmap and going upwards. Within each line,
1230 * the data is stored left-to-right. That's the reason why line
1231 * goes from lines-1 to 0. [JAY]
1241 * If the length byte is not zero (which is the escape value),
1242 * We have a run of length pixels all the same colour. The colour
1243 * index is stored next.
1245 * If the length byte is zero, we need to read the next byte to
1246 * know what to do. [JAY]
1251 * [Run-Length] Encoded mode
1253 color_index
= (*pIn
++); /* Get the colour index. */
1254 color
= colors
[color_index
];
1263 XPutPixel(bmpImage
, x
++, line
, color
);
1269 * Escape codes (may be an absolute sequence though)
1271 escape_code
= (*pIn
++);
1274 case RleEol
: /* =0, end of line */
1281 case RleEnd
: /* =1, end of bitmap */
1284 * Not all RLE8 bitmaps end with this
1285 * code. For example, Paint Shop Pro
1286 * produces some that don't. That's (I think)
1287 * what caused the previous implementation to
1290 line
=-1; /* Cause exit from do loop. */
1294 case RleDelta
: /* =2, a delta */
1297 * Note that deltaing to line 0
1298 * will cause an exit from the loop,
1299 * which may not be what is intended.
1300 * The fact that there is a delta in the bits
1301 * almost certainly implies that there is data
1302 * to follow. You may feel that we should
1303 * jump to the top of the loop to avoid exiting
1306 * TODO: Decide what to do here in that case. [JAY]
1312 TRACE("Delta to last line of bitmap "
1313 "(wrongly?) causes loop exit\n");
1318 default: /* >2, switch to absolute mode */
1323 length
= escape_code
;
1326 color_index
= (*pIn
++);
1332 XPutPixel(bmpImage
, x
++, line
,
1333 colors
[color_index
]);
1337 * If you think for a moment you'll realise that the
1338 * only time we could ever possibly read an odd
1339 * number of bytes is when there is a 0x00 (escape),
1340 * a value >0x02 (absolute mode) and then an odd-
1341 * length run. Therefore this is the only place we
1342 * need to worry about it. Everywhere else the
1343 * bytes are always read in pairs. [JAY]
1345 if (escape_code
& 1)
1346 pIn
++; /* Throw away the pad byte. */
1349 } /* switch (escape_code) : Escape sequence */
1350 } /* process either an encoded sequence or an escape sequence */
1352 /* We expect to come here more than once per line. */
1353 } while (line
>= 0); /* Do this until the bitmap is filled */
1356 * Everybody comes here at the end.
1357 * Check how we exited the loop and print a message if it's a bit odd.
1360 if ( (*(pIn
-2) != 0/*escape*/) || (*(pIn
-1)!= RleEnd
) )
1362 TRACE("End-of-bitmap without (strictly) proper escape code. Last two "
1363 "bytes were: %02X %02X.\n", (int)*(pIn
-2),(int)*(pIn
-1));
1368 /***********************************************************************
1369 * X11DRV_DIB_SetImageBits_16
1371 * SetDIBits for a 16-bit deep DIB.
1373 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
1374 DWORD srcwidth
, DWORD dstwidth
, int left
,
1375 DC
*dc
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
1381 /* align to 32 bit */
1382 DWORD linebytes
= (srcwidth
* 2 + 3) & ~3;
1387 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
1388 linebytes
= -linebytes
;
1391 switch ( bmpImage
->depth
)
1394 /* using same format as XImage */
1395 if (rSrc
== bmpImage
->red_mask
&& gSrc
== bmpImage
->green_mask
&& bSrc
== bmpImage
->blue_mask
)
1396 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+= linebytes
)
1397 memcpy ( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2, srcbits
+ left
*2, dstwidth
*2 );
1398 else /* We need to do a conversion from a 565 dib */
1400 LPDWORD dstpixel
, ptr
= (LPDWORD
)(srcbits
+ left
*2);
1402 int div
= dstwidth
% 2;
1404 for (h
= lines
- 1; h
>= 0; h
--) {
1405 dstpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1406 for (x
= 0; x
< dstwidth
/2; x
++) { /* Do 2 pixels at a time */
1408 *dstpixel
++ = ((val
>> 1) & 0x7fe07fe0) | (val
& 0x001f001f); /* Red & Green & Blue */
1410 if (div
!= 0) /* Odd width? */
1411 *dstpixel
= ((*(WORD
*)ptr
>> 1) & 0x7fe0) | (*(WORD
*)ptr
& 0x001f);
1412 ptr
= (LPDWORD
) ((srcbits
+= linebytes
) + left
*2);
1418 /* using same format as XImage */
1419 if (rSrc
== bmpImage
->red_mask
&& gSrc
== bmpImage
->green_mask
&& bSrc
== bmpImage
->blue_mask
)
1420 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+= linebytes
)
1421 memcpy ( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2, srcbits
+ left
*2, dstwidth
*2 );
1422 else /* We need to do a conversion from a 555 dib */
1424 LPDWORD dstpixel
, ptr
= (LPDWORD
)(srcbits
+ left
*2);
1426 int div
= dstwidth
% 2;
1428 for (h
= lines
- 1; h
>= 0; h
--) {
1429 dstpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1430 for (x
= 0; x
< dstwidth
/2; x
++) { /* Do 2 pixels at a time */
1432 *dstpixel
++ = ((val
<< 1) & 0xffc0ffc0) | ((val
>> 4) & 0x00200020) | /* Red & Green */
1433 (val
& 0x001f001f); /* Blue */
1435 if (div
!= 0) /* Odd width? */
1436 *dstpixel
= ((*(WORD
*)ptr
<< 1) & 0xffc0) | ((*(WORD
*)ptr
>> 4) & 0x0020)
1437 | (*(WORD
*)ptr
& 0x001f);
1438 ptr
= (LPDWORD
) ((srcbits
+= linebytes
) + left
*2);
1447 LPWORD ptr
= (LPWORD
)srcbits
+ left
;
1450 /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
1451 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1453 for (h
= lines
- 1; h
>= 0; h
--) {
1454 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1455 for (x
= 0; x
< dstwidth
; x
++) {
1458 *dstpixel
++ = ((val
<< 9) & 0xf80000) | ((val
<< 4) & 0x070000) | /* Red */
1459 ((val
<< 6) & 0x00f800) | ((val
<< 1) & 0x000700) | /* Green */
1460 ((val
<< 3) & 0x0000f8) | ((val
>> 2) & 0x000007); /* Blue */
1462 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1465 /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
1466 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1468 for (h
= lines
- 1; h
>= 0; h
--) {
1469 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1470 for (x
= 0; x
< dstwidth
; x
++) {
1473 *dstpixel
++ = ((val
>> 7) & 0x0000f8) | ((val
>> 12) & 0x000007) | /* Red */
1474 ((val
<< 6) & 0x00f800) | ((val
<< 1) & 0x000700) | /* Green */
1475 ((val
<< 19) & 0xf80000) | ((val
>> 14) & 0x070000); /* Blue */
1477 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1488 LPWORD ptr
= (LPWORD
)srcbits
+ left
;
1492 /* Set color scaling values */
1493 if ( rSrc
== 0x7c00 ) { sc1
= 7; sc2
= 2; } /* 555 dib */
1494 else { sc1
= 8; sc2
= 3; } /* 565 dib */
1496 for (h
= lines
- 1; h
>= 0; h
--) {
1497 for (x
= left
; x
< dstwidth
+left
; x
++) {
1499 XPutPixel( bmpImage
, x
, h
,
1500 X11DRV_PALETTE_ToPhysical(dc
, RGB(((val
& rSrc
) >> sc1
), /* Red */
1501 ((val
& gSrc
) >> sc2
), /* Green */
1502 ((val
& bSrc
) << 3)))); /* Blue */
1504 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
1510 FIXME("16 bit DIB %d bit bitmap\n", bmpImage
->bits_per_pixel
);
1517 /***********************************************************************
1518 * X11DRV_DIB_GetImageBits_16
1520 * GetDIBits for an 16-bit deep DIB.
1522 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*dstbits
,
1523 DWORD dstwidth
, DWORD srcwidth
,
1524 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
1529 /* align to 32 bit */
1530 DWORD linebytes
= (dstwidth
* 2 + 3) & ~3;
1535 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
1536 linebytes
= -linebytes
;
1539 switch ( bmpImage
->depth
)
1542 /* ==== 555 BGR bitmap to 555 BGR dib ==== */
1543 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
1544 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+= linebytes
)
1545 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, srcwidth
*2 );
1547 /* ==== 555 RGB bitmap to 555 BGR dib ==== */
1548 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
1550 LPDWORD srcpixel
, ptr
= (LPDWORD
)dstbits
;
1552 int div
= srcwidth
% 2;
1554 for (h
= lines
- 1; h
>= 0; h
--) {
1555 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1556 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1558 *ptr
++ = ((val
<< 10) & 0xf800f800) | (val
& 0x03e003e0) | /* Red & Green */
1559 ((val
>> 10) & 0x001f001f); /* Blue */
1561 if (div
!= 0) /* Odd width? */
1562 *ptr
= ((*(WORD
*)srcpixel
<< 1) & 0xffc0) | ((*(WORD
*)srcpixel
>> 4) & 0x0020) |
1563 (*(WORD
*)srcpixel
& 0x001f);
1564 ptr
= (LPDWORD
)(dstbits
+= linebytes
);
1567 else goto notsupported
;
1573 LPDWORD srcpixel
, ptr
= (LPDWORD
)dstbits
;
1575 int div
= srcwidth
% 2;
1577 /* ==== 565 BGR bitmap to 555 BGR dib ==== */
1578 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f )
1580 for (h
= lines
- 1; h
>= 0; h
--) {
1581 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1582 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1584 *ptr
++ = ((val
>> 1) & 0x7fe07fe0) | /* Red & Green */
1585 (val
& 0x001f001f); /* Blue */
1587 if (div
!= 0) /* Odd width? */
1588 *ptr
= ((*(WORD
*)srcpixel
>> 1) & 0x7fe0) | (*(WORD
*)srcpixel
& 0x001f);
1589 ptr
= (LPDWORD
) (dstbits
+= linebytes
);
1592 /* ==== 565 RGB bitmap to 555 BGR dib ==== */
1593 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
1595 for (h
= lines
- 1; h
>= 0; h
--) {
1596 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1597 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1599 *ptr
++ = ((val
<< 10) & 0x7c007c00) | ((val
>> 1) & 0x03e003e0) | /* Red & Green */
1600 ((val
>> 11) & 0x001f001f); /* Blue */
1602 if (div
!= 0) /* Odd width? */
1603 *ptr
= ((*(WORD
*)srcpixel
>> 1) & 0x7fe0) | (*(WORD
*)srcpixel
& 0x001f);
1604 ptr
= (LPDWORD
) (dstbits
+= linebytes
);
1607 else goto notsupported
;
1615 LPWORD ptr
= (LPWORD
)dstbits
;
1618 /* ==== 24/32 BGR bitmap to 555 BGR dib ==== */
1619 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1621 for (h
= lines
- 1; h
>= 0; h
--) {
1622 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1623 for (x
= 0; x
< srcwidth
; x
++, ptr
++) {
1625 *ptr
= ((val
>> 9) & 0x7c00) | /* Red */
1626 ((val
>> 6) & 0x03e0) | /* Green */
1627 ((val
>> 3) & 0x001f); /* Blue */
1629 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1632 /* ==== 24/32 RGB bitmap to 555 BGR dib ==== */
1633 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1635 for (h
= lines
- 1; h
>= 0; h
--) {
1636 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1637 for (x
= 0; x
< srcwidth
; x
++, ptr
++) {
1639 *ptr
= ((val
<< 7) & 0x7c00) | /* Red */
1640 ((val
>> 6) & 0x03e0) | /* Green */
1641 ((val
>> 19) & 0x001f); /* Blue */
1643 ptr
= (LPWORD
) (dstbits
+= linebytes
);
1646 else goto notsupported
;
1651 /* ==== monochrome bitmap to 16 BGR dib ==== */
1653 /* ==== 4 colormap bitmap to 16 BGR dib ==== */
1654 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1656 LPWORD ptr
= (LPWORD
)dstbits
;
1659 for (h
= lines
- 1; h
>= 0; h
--) {
1660 for (x
= 0; x
< dstwidth
; x
++) {
1661 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
1662 *ptr
++ = ((val
.peRed
<< 7) & 0x7c00) |
1663 ((val
.peGreen
<< 2) & 0x03e0) |
1664 ((val
.peBlue
>> 3) & 0x001f);
1666 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1669 else goto notsupported
;
1674 /* ==== 8 colormap bitmap to 16 BGR dib ==== */
1675 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1677 LPWORD ptr
= (LPWORD
)dstbits
;
1681 for (h
= lines
- 1; h
>= 0; h
--) {
1682 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1683 for (x
= 0; x
< dstwidth
; x
++) {
1684 val
= srccolors
[(int)*srcpixel
++];
1685 *ptr
++ = ((val
.peRed
<< 7) & 0x7c00) |
1686 ((val
.peGreen
<< 2) & 0x03e0) |
1687 ((val
.peBlue
>> 3) & 0x001f);
1689 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1692 else goto notsupported
;
1700 LPWORD ptr
= (LPWORD
)dstbits
;
1702 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 16 bit DIB\n",
1703 bmpImage
->depth
, (int)bmpImage
->red_mask
,
1704 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1705 for (h
= lines
- 1; h
>= 0; h
--)
1707 for (x
= 0; x
< dstwidth
; x
++, ptr
++)
1709 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
1710 r
= (BYTE
) GetRValue(pixel
);
1711 g
= (BYTE
) GetGValue(pixel
);
1712 b
= (BYTE
) GetBValue(pixel
);
1713 *ptr
= ( ((r
<< 7) & 0x7c00) | ((g
<< 2) & 0x03e0) | ((b
>> 3) & 0x001f) );
1715 ptr
= (LPWORD
) (dstbits
+= linebytes
);
1723 /***********************************************************************
1724 * X11DRV_DIB_SetImageBits_24
1726 * SetDIBits for a 24-bit deep DIB.
1728 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
1729 DWORD srcwidth
, DWORD dstwidth
, int left
,
1730 DC
*dc
, XImage
*bmpImage
)
1735 /* align to 32 bit */
1736 DWORD linebytes
= (srcwidth
* 3 + 3) & ~3;
1741 srcbits
= srcbits
+ linebytes
* (lines
- 1);
1742 linebytes
= -linebytes
;
1745 switch ( bmpImage
->depth
)
1749 if (bmpImage
->bits_per_pixel
== 24) {
1750 int dstlinebytes
= linebytes
;
1752 BYTE
*ptr
= (BYTE
*)(srcbits
+left
*3);
1754 if (dstlinebytes
< 0 ) dstlinebytes
= -dstlinebytes
;
1755 dstpixel
= bmpImage
->data
+ lines
*dstlinebytes
+ left
*3;
1756 for(h
= lines
; h
-- ; ) {
1757 dstpixel
-=dstlinebytes
;
1758 memcpy(dstpixel
,ptr
,dstwidth
*3);
1766 if( bmpImage
->blue_mask
== 0xff && bmpImage
->red_mask
== 0xff0000 ) /* packed BGR to unpacked BGR */
1768 DWORD
*dstpixel
, val
, buf
;
1769 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1771 int div
= dstwidth
% 4;
1774 for(h
= lines
- 1; h
>= 0; h
--)
1776 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
*bmpImage
->bytes_per_line
+ left
*4);
1778 for (x
= 0; x
< dstwidth
/4; x
++) { /* do 3 dwords source, 4 dwords dest at a time */
1780 *dstpixel
++ = buf
&0x00ffffff; /* b1, g1, r1 */
1781 val
= (buf
>> 24); /* b2 */
1783 *dstpixel
++ = (val
| (buf
<<8)) &0x00ffffff; /* g2, r2 */
1784 val
= (buf
>> 16); /* b3, g3 */
1786 *dstpixel
++ = (val
| (buf
<<16)) &0x00ffffff; /* r3 */
1787 *dstpixel
++ = (buf
>> 8); /* b4, g4, r4 */
1789 for ( divk
=div
, bits
=(BYTE
*)ptr
; divk
>0; divk
--, bits
+=3 ) /* do remainder */
1791 *dstpixel
++ = *(DWORD
*)bits
& 0x00ffffff; /* b, g, r */
1793 ptr
= (DWORD
*)((srcbits
+=linebytes
)+left
*3);
1796 else if( bmpImage
->blue_mask
== 0xff0000 && bmpImage
->red_mask
== 0xff ) /* packed BGR to unpacked RGB */
1798 DWORD
*dstpixel
, val
, buf
;
1799 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1801 int div
= dstwidth
% 4;
1804 for(h
= lines
- 1; h
>= 0; h
--)
1806 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
*bmpImage
->bytes_per_line
+ left
*4);
1808 for (x
= 0; x
< dstwidth
/4; x
++) { /* do 3 dwords source, 4 dwords dest at a time */
1810 *dstpixel
++ = ((buf
&0xff)<<16) | (buf
&0xff00) | ((buf
&0xff0000)>>16); /* b1, g1, r1 */
1811 val
= ((buf
&0xff000000)>>8); /* b2 */
1813 *dstpixel
++ = val
| ((buf
&0xff)<<8) | ((buf
&0xff00)>>8); /* g2, r2 */
1814 val
= (buf
&0xff0000) | ((buf
&0xff000000)>>16); /* b3, g3 */
1816 *dstpixel
++ = val
| (buf
&0xff); /* r3 */
1817 *dstpixel
++ = ((buf
&0xff00)<<8) | ((buf
&0xff0000)>>8) | (buf
>>24); /* b4, g4, r4 */
1819 for ( divk
=div
, bits
=(BYTE
*)ptr
; divk
>0; divk
--, bits
+=3 ) /* do remainder */
1821 buf
= *(DWORD
*)bits
;
1822 *dstpixel
++ = ((buf
&0xff)<<16) | (buf
&0xff00) | ((buf
&0xff0000)>>16); /* b, g, r */
1824 ptr
= (DWORD
*)((srcbits
+=linebytes
)+left
*3);
1834 if( bmpImage
->blue_mask
== 0x7c00 && bmpImage
->red_mask
== 0x1f ) /* BGR888 to RGB555 */
1836 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1839 int div
= dstwidth
% 4;
1842 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1843 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1844 for (x
= 0; x
< dstwidth
/4; x
++) {
1845 *dstpixel
++ = (WORD
)((((val
= *ptr
++) << 7) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 19) & 0x1f));
1846 *dstpixel
++ = (WORD
)(((val
>> 17) & 0x7c00) | (((val
= *ptr
++) << 2) & 0x03e0) | ((val
>> 11) & 0x1f));
1847 *dstpixel
++ = (WORD
)(((val
>> 9) & 0x07c00) | ((val
>> 22) & 0x03e0) | (((val
= *ptr
++) >> 3) & 0x1f));
1848 *dstpixel
++ = (WORD
)(((val
>> 1) & 0x07c00) | ((val
>> 14) & 0x03e0) | ((val
>> 27) & 0x1f));
1850 for (bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth not divisible by 4? */
1851 *dstpixel
++ = (((WORD
)bits
[0] << 7) & 0x07c00) |
1852 (((WORD
)bits
[1] << 2) & 0x03e0) |
1853 (((WORD
)bits
[2] >> 3) & 0x001f);
1854 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1857 else if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0x7c00 ) /* BGR888 to BGR555 */
1859 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1862 int div
= dstwidth
% 4;
1865 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1866 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1867 for (x
= 0; x
< dstwidth
/4; x
++) {
1868 *dstpixel
++ = (WORD
)((((val
= *ptr
++) >> 3) & 0x1f) | ((val
>> 6) & 0x03e0) | ((val
>> 9) & 0x7c00));
1869 *dstpixel
++ = (WORD
)(((val
>> 27) & 0x1f) | (((val
= *ptr
++) << 2) & 0x03e0) | ((val
>> 1) & 0x7c00));
1870 *dstpixel
++ = (WORD
)(((val
>> 19) & 0x1f) | ((val
>> 22) & 0x03e0) | (((val
= *ptr
++) << 7) & 0x7c00));
1871 *dstpixel
++ = (WORD
)(((val
>> 11) & 0x1f) | ((val
>> 14) & 0x03e0) | ((val
>> 17) & 0x7c00));
1873 for (bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth not divisible by 4? */
1874 *dstpixel
++ = (((WORD
)bits
[2] << 7) & 0x07c00) |
1875 (((WORD
)bits
[1] << 2) & 0x03e0) |
1876 (((WORD
)bits
[0] >> 3) & 0x001f);
1877 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1887 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1890 int div
= dstwidth
% 4;
1893 if( bmpImage
->blue_mask
== 0x001f && bmpImage
->red_mask
== 0xf800 ) /* BGR888 to BGR565 */
1895 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1896 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1897 for (x
= 0; x
< dstwidth
/4; x
++) {
1898 *dstpixel
++ = (WORD
)((((val
= *ptr
++) >> 3) & 0x1f) | ((val
>> 5) & 0x07e0) | ((val
>> 8) & 0xf800));
1899 *dstpixel
++ = (WORD
)(((val
>> 27) & 0x1f) | (((val
= *ptr
++) << 3) & 0x07e0) | ((val
) & 0xf800));
1900 *dstpixel
++ = (WORD
)(((val
>> 19) & 0x1f) | ((val
>> 21) & 0x07e0) | (((val
= *ptr
++) << 8) & 0xf800));
1901 *dstpixel
++ = (WORD
)(((val
>> 11) & 0x1f) | ((val
>> 13) & 0x07e0) | ((val
>> 16) & 0xf800));
1903 for ( bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth is not divisible by 4? */
1904 *dstpixel
++ = (((WORD
)bits
[2] << 8) & 0xf800) |
1905 (((WORD
)bits
[1] << 3) & 0x07e0) |
1906 (((WORD
)bits
[0] >> 3) & 0x001f);
1907 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1910 else if( bmpImage
->blue_mask
== 0xf800 && bmpImage
->red_mask
== 0x001f ) /* BGR888 to RGB565 */
1912 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1913 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1914 for (x
= 0; x
< dstwidth
/4; x
++) {
1915 *dstpixel
++ = (WORD
)((((val
= *ptr
++) << 8) & 0xf800) | ((val
>> 5) & 0x07e0) | ((val
>> 19) & 0x1f));
1916 *dstpixel
++ = (WORD
)(((val
>> 16) & 0xf800) | (((val
= *ptr
++) << 3) & 0x07e0) | ((val
>> 11) & 0x1f));
1917 *dstpixel
++ = (WORD
)(((val
>> 8) & 0xf800) | ((val
>> 21) & 0x07e0) | (((val
= *ptr
++) >> 3) & 0x1f));
1918 *dstpixel
++ = (WORD
)((val
& 0xf800) | ((val
>> 13) & 0x07e0) | ((val
>> 27) & 0x1f));
1920 for ( bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth is not divisible by 4? */
1921 *dstpixel
++ = (((WORD
)bits
[0] << 8) & 0xf800) |
1922 (((WORD
)bits
[1] << 3) & 0x07e0) |
1923 (((WORD
)bits
[2] >> 3) & 0x001f);
1924 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1936 LPBYTE bits
= (LPBYTE
)srcbits
+ left
*3;
1938 for (h
= lines
- 1; h
>= 0; h
--) {
1939 for (x
= left
; x
< dstwidth
+left
; x
++, bits
+=3)
1940 XPutPixel( bmpImage
, x
, h
,
1941 X11DRV_PALETTE_ToPhysical(dc
, RGB(bits
[2], bits
[1], bits
[0])));
1942 bits
= (LPBYTE
)(srcbits
+= linebytes
) + left
* 3;
1949 FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
1950 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
1951 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1957 /***********************************************************************
1958 * X11DRV_DIB_GetImageBits_24
1960 * GetDIBits for an 24-bit deep DIB.
1962 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*dstbits
,
1963 DWORD dstwidth
, DWORD srcwidth
,
1964 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
1969 /* align to 32 bit */
1970 DWORD linebytes
= (dstwidth
* 3 + 3) & ~3;
1975 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
1976 linebytes
= -linebytes
;
1979 switch ( bmpImage
->depth
)
1983 if (bmpImage
->bits_per_pixel
== 24) {
1984 int tocopy
= linebytes
;
1986 BYTE
*ptr
= (LPBYTE
)dstbits
;
1988 if (tocopy
< 0 ) tocopy
= -tocopy
;
1989 srcpixel
= bmpImage
->data
+ lines
*tocopy
;
1990 for(h
= lines
; h
-- ; ) {
1992 memcpy(ptr
,srcpixel
,tocopy
);
1993 ptr
= (LPBYTE
)(dstbits
+=linebytes
);
2000 DWORD
*srcpixel
, buf
;
2002 DWORD
*ptr
=(DWORD
*)dstbits
;
2003 int quotient
= dstwidth
/ 4;
2004 int remainder
= dstwidth
% 4;
2007 /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
2008 if( bmpImage
->blue_mask
== 0xff && bmpImage
->red_mask
== 0xff0000 )
2010 for(h
= lines
- 1; h
>= 0; h
--)
2012 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2014 for (x
= 0; x
< quotient
; x
++) { /* do 4 dwords source, 3 dwords dest at a time */
2015 buf
= ((*srcpixel
++)&0x00ffffff); /* b1, g1, r1*/
2016 *ptr
++ = buf
| ((*srcpixel
)<<24); /* b2 */
2017 buf
= ((*srcpixel
++>>8)&0x0000ffff); /* g2, r2 */
2018 *ptr
++ = buf
| ((*srcpixel
)<<16); /* b3, g3 */
2019 buf
= ((*srcpixel
++>>16)&0x000000ff); /* r3 */
2020 *ptr
++ = buf
| ((*srcpixel
++)<<8); /* b4, g4, r4 */
2022 for ( remk
=remainder
, bits
=(BYTE
*)ptr
; remk
>0; remk
--, bits
+=3 ) /* do remainder */
2025 *(WORD
*)bits
= buf
; /* b, g */
2026 *(bits
+2) = buf
>>16; /* r */
2028 ptr
= (DWORD
*)(dstbits
+=linebytes
);
2032 /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
2033 else if( bmpImage
->blue_mask
== 0xff0000 && bmpImage
->red_mask
== 0xff )
2035 for(h
= lines
- 1; h
>= 0; h
--)
2037 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2039 for (x
= 0; x
< quotient
; x
++) { /* do 4 dwords source, 3 dwords dest at a time */
2041 val
= ((buf
&0xff0000)>>16) | (buf
&0xff00) | ((buf
&0xff)<<16); /* b1, g1, r1 */
2043 *ptr
++ = val
| ((buf
&0xff0000)<<8); /* b2 */
2044 val
= ((buf
&0xff00)>>8) | ((buf
&0xff)<<8); /* g2, r2 */
2046 *ptr
++ = val
| (buf
&0xff0000) | ((buf
&0xff00)<<16); /* b3, g3 */
2047 val
= (buf
&0xff); /* r3 */
2049 *ptr
++ = val
| ((buf
&0xff0000)>>8) | ((buf
&0xff00)<<8) | (buf
<<24); /* b4, g4, r4 */
2051 for ( remk
=remainder
, bits
=(BYTE
*)ptr
; remk
>0; remk
--, bits
+=3 ) /* do remainder */
2054 *(WORD
*)bits
= (buf
&0xff00) | ((buf
&0xff0000)>>16) ; /* b, g */
2055 *(bits
+2) = buf
; /* r */
2057 ptr
= (DWORD
*)(dstbits
+=linebytes
);
2060 else goto notsupported
;
2067 LPBYTE bits
= dstbits
;
2070 /* ==== 555 BGR bitmap to 24 BGR dib ==== */
2071 if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0x7c00 )
2073 for (h
= lines
- 1; h
>= 0; h
--) {
2074 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2075 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2077 bits
[2] = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2078 bits
[1] = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07)); /*Green*/
2079 bits
[0] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2081 bits
= (dstbits
+= linebytes
);
2084 /* ==== 555 RGB bitmap to 24 RGB dib==== */
2085 else if( bmpImage
->blue_mask
== 0x7c00 && bmpImage
->red_mask
== 0x1f )
2087 for (h
= lines
- 1; h
>= 0; h
--) {
2088 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2089 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2091 bits
[0] = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2092 bits
[1] = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07)); /*Green*/
2093 bits
[2] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2095 bits
= (dstbits
+= linebytes
);
2098 else goto notsupported
;
2105 LPBYTE bits
= dstbits
;
2108 /* ==== 565 BGR bitmap to 24 BGR dib ==== */
2109 if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0xf800 )
2111 for (h
= lines
- 1; h
>= 0; h
--) {
2112 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2113 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2115 bits
[2] = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2116 bits
[1] = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2117 bits
[0] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2119 bits
= (dstbits
+= linebytes
);
2122 /* ==== 565 RGB bitmap to 24 BGR dib ==== */
2123 else if( bmpImage
->blue_mask
== 0xf800 && bmpImage
->red_mask
== 0x1f )
2125 for (h
= lines
- 1; h
>= 0; h
--) {
2126 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2127 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2129 bits
[0] = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2130 bits
[1] = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2131 bits
[2] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2133 bits
= (dstbits
+= linebytes
);
2136 else goto notsupported
;
2141 /* ==== monochrome bitmap to 24 BGR dib ==== */
2143 /* ==== 4 colormap bitmap to 24 BGR dib ==== */
2144 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2146 LPBYTE bits
= dstbits
;
2149 for (h
= lines
- 1; h
>= 0; h
--) {
2150 for (x
= 0; x
< dstwidth
; x
++) {
2151 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
2152 *bits
++ = val
.peBlue
;
2153 *bits
++ = val
.peGreen
;
2154 *bits
++ = val
.peRed
;
2156 bits
= (dstbits
+= linebytes
);
2159 else goto notsupported
;
2164 /* ==== 8 colormap bitmap to 24 BGR dib ==== */
2165 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
== 0 && srccolors
)
2168 LPBYTE bits
= dstbits
;
2171 for (h
= lines
- 1; h
>= 0; h
--) {
2172 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
2173 for (x
= 0; x
< dstwidth
; x
++ ) {
2174 val
= srccolors
[(int)*srcpixel
++];
2175 *bits
++ = val
.peBlue
; /*Blue*/
2176 *bits
++ = val
.peGreen
; /*Green*/
2177 *bits
++ = val
.peRed
; /*Red*/
2179 bits
= (dstbits
+= linebytes
);
2182 else goto notsupported
;
2189 LPBYTE bits
= dstbits
;
2191 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
2192 bmpImage
->depth
, (int)bmpImage
->red_mask
,
2193 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2194 for (h
= lines
- 1; h
>= 0; h
--)
2196 for (x
= 0; x
< dstwidth
; x
++, bits
+= 3)
2198 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
2199 bits
[0] = GetBValue(pixel
);
2200 bits
[1] = GetGValue(pixel
);
2201 bits
[2] = GetRValue(pixel
);
2203 bits
= (dstbits
+= linebytes
);
2211 /***********************************************************************
2212 * X11DRV_DIB_SetImageBits_32
2214 * SetDIBits for a 32-bit deep DIB.
2216 static void X11DRV_DIB_SetImageBits_32( int lines
, const BYTE
*srcbits
,
2217 DWORD srcwidth
, DWORD dstwidth
, int left
,
2218 DC
*dc
, XImage
*bmpImage
)
2223 DWORD linebytes
= (srcwidth
* 4);
2228 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
2229 linebytes
= -linebytes
;
2232 ptr
= (DWORD
*) srcbits
+ left
;
2234 switch ( bmpImage
->depth
)
2237 /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
2238 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff) {
2239 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+=linebytes
) {
2240 memcpy( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
, srcbits
+ left
*4, dstwidth
*4 );
2244 /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
2245 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
2249 for (h
= lines
- 1; h
>= 0; h
--) {
2250 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2251 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2252 *dstpixel
++ = ((*ptr
<< 16) & 0xff0000) | (*ptr
& 0xff00) | ((*ptr
>> 16) & 0xff);
2254 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2257 else goto notsupported
;
2262 /* ==== 32 BGR dib to 24 (888) BGR bitmap ==== */
2263 /* we need to check that source mask matches destination */
2267 ptr
= (DWORD
*) srcbits
+ left
;
2268 bptr
= bmpImage
->data
;
2270 for (h
= lines
- 1; h
>= 0; h
--) {
2271 for (x
= 0; x
< dstwidth
; x
++) {
2272 /* *ptr is a 32bit value */
2273 /* bptr points to first of 3 bytes */
2274 *bptr
++ = (*ptr
>> 16) & 0xff;
2275 *bptr
++ = (*ptr
>> 8) & 0xff;
2276 *bptr
++ = (*ptr
) & 0xff;
2279 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2285 /* ==== 32 BGR dib to 555 BGR bitmap ==== */
2286 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f) {
2289 for (h
= lines
- 1; h
>= 0; h
--) {
2290 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2291 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2292 *dstpixel
++ = (WORD
) (((*ptr
>> 9) & 0x7c00) | ((*ptr
>> 6) & 0x03e0) | ((*ptr
>> 3) & 0x001f));
2294 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2297 /* ==== 32 BGR dib to 555 RGB bitmap ==== */
2298 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
2302 for (h
= lines
- 1; h
>= 0; h
--) {
2303 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2304 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2305 *dstpixel
++ = (WORD
) (((*ptr
<< 7) & 0x7c00) | ((*ptr
>> 6) & 0x03e0) | ((*ptr
>> 19) & 0x001f));
2307 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2310 else goto notsupported
;
2315 /* ==== 32 BGR dib to 565 BGR bitmap ==== */
2316 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2320 for (h
= lines
- 1; h
>= 0; h
--) {
2321 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2322 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2323 *dstpixel
++ = (WORD
) (((*ptr
>> 8) & 0xf800) | ((*ptr
>> 5) & 0x07e0) | ((*ptr
>> 3) & 0x001f));
2325 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2328 /* ==== 32 BGR dib to 565 RGB bitmap ==== */
2329 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
2333 for (h
= lines
- 1; h
>= 0; h
--) {
2334 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2335 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2336 *dstpixel
++ = (WORD
) (((*ptr
<< 8) & 0xf800) | ((*ptr
>> 5) & 0x07e0) | ((*ptr
>> 19) & 0x001f));
2338 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2341 else goto notsupported
;
2349 LPBYTE bits
= (LPBYTE
)srcbits
+ left
*4;
2351 for (h
= lines
- 1; h
>= 0; h
--) {
2352 for (x
= left
; x
< dstwidth
+left
; x
++, bits
+= 4)
2353 XPutPixel( bmpImage
, x
, h
,
2354 X11DRV_PALETTE_ToPhysical(dc
, RGB( bits
[2], bits
[1], *bits
)));
2355 bits
= (LPBYTE
)(srcbits
+= linebytes
) + left
* 4;
2362 FIXME("32 bit DIB %d bit bitmap\n", bmpImage
->bits_per_pixel
);
2368 /***********************************************************************
2369 * X11DRV_DIB_GetImageBits_32
2371 * GetDIBits for an 32-bit deep DIB.
2373 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*dstbits
,
2374 DWORD dstwidth
, DWORD srcwidth
,
2375 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
2381 /* align to 32 bit */
2382 DWORD linebytes
= (srcwidth
* 4);
2383 DWORD copybytes
= linebytes
;
2388 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2389 linebytes
= -linebytes
;
2394 switch ( bmpImage
->depth
)
2397 /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
2398 if ( bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff )
2399 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+=linebytes
)
2400 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, copybytes
);
2402 /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
2403 else if ( bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000 )
2407 for (h
= lines
- 1; h
>= 0; h
--) {
2408 srcbits
= bmpImage
->data
+ h
* bmpImage
->bytes_per_line
;
2409 for (x
= 0; x
< dstwidth
; x
++, bits
+=4, srcbits
+=2) {
2410 *(bits
+ 2) = *srcbits
++;
2411 *(bits
+ 1) = *srcbits
++;
2414 bits
= (dstbits
+= linebytes
);
2417 else goto notsupported
;
2421 /* ==== 24 BGR bitmap to 32 (0888) BGR dib ==== */
2422 /* we need to check that source mask matches destination */
2428 srcpixel
= (DWORD
*) dstbits
;
2429 bptr
= bmpImage
->data
;
2431 for (h
= lines
- 1; h
>= 0; h
--) {
2432 for (x
= 0; x
< dstwidth
; x
++) {
2433 /* *srcpixel is a 32bit value */
2434 /* bptr points to first of 3 bytes */
2436 srcdata
= srcdata
<< 8 | *bptr
++;
2437 srcdata
= srcdata
<< 8 | *bptr
++;
2438 srcdata
= srcdata
<< 8 | *bptr
++;
2440 *srcpixel
++ = srcdata
;
2442 srcpixel
= (DWORD
*) (dstbits
+= linebytes
);
2452 /* ==== 555 BGR bitmap to 32 BGR dib ==== */
2453 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
2455 for (h
= lines
- 1; h
>= 0; h
--) {
2456 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2457 for (x
= 0; x
< dstwidth
; x
++, bits
+=2) {
2459 *bits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Blue*/
2460 *bits
++ = (BYTE
)(((val
>> 2) & 0xfc) | ((val
>> 8) & 0x03)); /*Green*/
2461 *bits
= (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2463 bits
= (dstbits
+= linebytes
);
2466 /* ==== 555 RGB bitmap to 32 BGR dib ==== */
2467 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
2469 for (h
= lines
- 1; h
>= 0; h
--) {
2470 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2471 for (x
= 0; x
< dstwidth
; x
++, bits
+=2) {
2473 *bits
++ = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07));/*Blue*/
2474 *bits
++ = (BYTE
)(((val
>> 2) & 0xfc) | ((val
>> 8) & 0x03)); /*Green*/
2475 *bits
= (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Red*/
2477 bits
= (dstbits
+= linebytes
);
2480 else goto notsupported
;
2489 /* ==== 565 BGR bitmap to 32 BGR dib ==== */
2490 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2492 for (h
= lines
- 1; h
>= 0; h
--) {
2493 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2494 for (x
= 0; x
< srcwidth
; x
++, bits
+=2) {
2496 *bits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Blue*/
2497 *bits
++ = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2498 *bits
= (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2500 bits
= (dstbits
+= linebytes
);
2503 /* ==== 565 RGB bitmap to 32 BGR dib ==== */
2504 else if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2506 for (h
= lines
- 1; h
>= 0; h
--) {
2507 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2508 for (x
= 0; x
< srcwidth
; x
++, bits
+=2) {
2510 *bits
++ = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07));/*Blue*/
2511 *bits
++ = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2512 *bits
= (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Red*/
2514 bits
= (dstbits
+= linebytes
);
2517 else goto notsupported
;
2522 /* ==== monochrome bitmap to 32 BGR dib ==== */
2524 /* ==== 4 colormap bitmap to 32 BGR dib ==== */
2525 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2529 for (h
= lines
- 1; h
>= 0; h
--) {
2530 for (x
= 0; x
< dstwidth
; x
++) {
2531 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
2532 *bits
++ = val
.peBlue
;
2533 *bits
++ = val
.peGreen
;
2534 *bits
++ = val
.peRed
;
2537 bits
= (dstbits
+= linebytes
);
2540 else goto notsupported
;
2545 /* ==== 8 colormap bitmap to 32 BGR dib ==== */
2546 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2551 for (h
= lines
- 1; h
>= 0; h
--) {
2552 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
2553 for (x
= 0; x
< dstwidth
; x
++) {
2554 val
= srccolors
[(int)*srcpixel
++];
2555 *bits
++ = val
.peBlue
; /*Blue*/
2556 *bits
++ = val
.peGreen
; /*Green*/
2557 *bits
++ = val
.peRed
; /*Red*/
2560 bits
= (dstbits
+= linebytes
);
2563 else goto notsupported
;
2568 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
2569 bmpImage
->depth
, (int)bmpImage
->red_mask
,
2570 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2571 for (h
= lines
- 1; h
>= 0; h
--)
2573 for (x
= 0; x
< dstwidth
; x
++, bits
+= 4)
2575 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
2576 bits
[0] = GetBValue(pixel
);
2577 bits
[1] = GetGValue(pixel
);
2578 bits
[2] = GetRValue(pixel
);
2580 bits
= (dstbits
+= linebytes
);
2586 /***********************************************************************
2587 * X11DRV_DIB_SetImageBits
2589 * Transfer the bits to an X image.
2590 * Helper function for SetDIBits() and SetDIBitsToDevice().
2591 * The Xlib critical section must be entered before calling this function.
2593 int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
2595 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
2599 bmpImage
= descr
->image
;
2601 bmpImage
= XCreateImage( display
, X11DRV_GetVisual(), descr
->depth
, ZPixmap
, 0, NULL
,
2602 descr
->infoWidth
, lines
, 32, 0 );
2603 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
2604 if(bmpImage
->data
== NULL
) {
2605 ERR("Out of memory!\n");
2606 XDestroyImage( bmpImage
);
2611 /* Transfer the pixels */
2612 switch(descr
->infoBpp
)
2615 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
2616 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
2620 if (descr
->compression
) {
2621 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2622 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2623 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2625 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
2626 descr
->infoWidth
, descr
->width
,
2627 descr
->xSrc
, (int *)(descr
->colorMap
),
2630 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
2631 descr
->infoWidth
, descr
->width
,
2632 descr
->xSrc
, (int*)(descr
->colorMap
),
2636 if (descr
->compression
) {
2637 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2638 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2639 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2640 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
2641 descr
->infoWidth
, descr
->width
,
2642 descr
->xSrc
, (int *)(descr
->colorMap
),
2645 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
2646 descr
->infoWidth
, descr
->width
,
2647 descr
->xSrc
, (int *)(descr
->colorMap
),
2652 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
2653 descr
->infoWidth
, descr
->width
,
2654 descr
->xSrc
, descr
->dc
,
2655 descr
->rMask
, descr
->gMask
, descr
->bMask
,
2659 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
2660 descr
->infoWidth
, descr
->width
,
2661 descr
->xSrc
, descr
->dc
, bmpImage
);
2664 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
2665 descr
->infoWidth
, descr
->width
,
2666 descr
->xSrc
, descr
->dc
,
2670 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
2676 XShmPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
2677 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2678 descr
->width
, descr
->height
, FALSE
);
2679 XSync( display
, 0 );
2682 XPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
2683 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2684 descr
->width
, descr
->height
);
2686 if (!descr
->image
) XDestroyImage( bmpImage
);
2690 /***********************************************************************
2691 * X11DRV_DIB_GetImageBits
2693 * Transfer the bits from an X image.
2694 * The Xlib critical section must be entered before calling this function.
2696 int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
2698 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
2702 bmpImage
= descr
->image
;
2704 bmpImage
= XCreateImage( display
, X11DRV_GetVisual(), descr
->depth
, ZPixmap
, 0, NULL
,
2705 descr
->infoWidth
, lines
, 32, 0 );
2706 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
2707 if(bmpImage
->data
== NULL
) {
2708 ERR("Out of memory!\n");
2709 XDestroyImage( bmpImage
);
2713 XGetSubImage( display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
,
2714 descr
->width
, lines
, AllPlanes
, ZPixmap
,
2715 bmpImage
, descr
->xDest
, descr
->yDest
);
2717 /* Transfer the pixels */
2718 switch(descr
->infoBpp
)
2721 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
2722 descr
->infoWidth
, descr
->width
,
2723 descr
->colorMap
, descr
->palentry
,
2728 if (descr
->compression
)
2729 FIXME("Compression not yet supported!\n");
2731 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
2732 descr
->infoWidth
, descr
->width
,
2733 descr
->colorMap
, descr
->palentry
,
2738 if (descr
->compression
)
2739 FIXME("Compression not yet supported!\n");
2741 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
2742 descr
->infoWidth
, descr
->width
,
2743 descr
->colorMap
, descr
->palentry
,
2748 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
2749 descr
->infoWidth
,descr
->width
,
2750 descr
->palentry
, bmpImage
);
2754 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
2755 descr
->infoWidth
,descr
->width
,
2756 descr
->palentry
, bmpImage
);
2760 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
2761 descr
->infoWidth
, descr
->width
,
2762 descr
->palentry
, bmpImage
);
2766 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
2770 if (!descr
->image
) XDestroyImage( bmpImage
);
2774 /*************************************************************************
2775 * X11DRV_SetDIBitsToDevice
2778 INT
X11DRV_SetDIBitsToDevice( DC
*dc
, INT xDest
, INT yDest
, DWORD cx
,
2779 DWORD cy
, INT xSrc
, INT ySrc
,
2780 UINT startscan
, UINT lines
, LPCVOID bits
,
2781 const BITMAPINFO
*info
, UINT coloruse
)
2783 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2784 DWORD width
, oldcy
= cy
;
2786 int height
, tmpheight
;
2787 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
2790 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
2791 &descr
.infoBpp
, &descr
.compression
) == -1)
2794 if (height
< 0) height
= -height
;
2795 if (!lines
|| (startscan
>= height
)) return 0;
2796 if (startscan
+ lines
> height
) lines
= height
- startscan
;
2797 if (ySrc
< startscan
) ySrc
= startscan
;
2798 else if (ySrc
>= startscan
+ lines
) return 0;
2799 if (xSrc
>= width
) return 0;
2800 if (ySrc
+ cy
>= startscan
+ lines
) cy
= startscan
+ lines
- ySrc
;
2801 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
2802 if (!cx
|| !cy
) return 0;
2804 X11DRV_SetupGCForText( dc
); /* To have the correct colors */
2805 TSXSetFunction(display
, physDev
->gc
, X11DRV_XROPfunction
[dc
->ROPmode
-1]);
2807 switch (descr
.infoBpp
)
2812 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
2813 coloruse
== DIB_PAL_COLORS
? dc
: NULL
, coloruse
,
2814 dc
->bitsPerPixel
, info
, &descr
.nColorMap
);
2815 if (!descr
.colorMap
) return 0;
2816 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2820 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2821 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2822 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2827 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2832 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2833 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2834 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2842 descr
.palentry
= NULL
;
2843 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
2844 descr
.infoWidth
= width
;
2845 descr
.depth
= dc
->bitsPerPixel
;
2846 descr
.drawable
= physDev
->drawable
;
2847 descr
.gc
= physDev
->gc
;
2849 descr
.ySrc
= tmpheight
>= 0 ? lines
-(ySrc
-startscan
)-cy
+(oldcy
-cy
)
2851 descr
.xDest
= dc
->DCOrgX
+ XLPTODP( dc
, xDest
);
2852 descr
.yDest
= dc
->DCOrgY
+ YLPTODP( dc
, yDest
) +
2853 (tmpheight
>= 0 ? oldcy
-cy
: 0);
2856 descr
.useShm
= FALSE
;
2858 EnterCriticalSection( &X11DRV_CritSection
);
2859 result
= CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
2860 LeaveCriticalSection( &X11DRV_CritSection
);
2862 if (descr
.infoBpp
<= 8)
2863 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
2867 /***********************************************************************
2868 * X11DRV_DIB_SetDIBits
2870 INT
X11DRV_DIB_SetDIBits(
2871 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
2872 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
,
2873 UINT coloruse
, HBITMAP hbitmap
)
2875 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2876 int height
, tmpheight
;
2881 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
2882 &descr
.infoBpp
, &descr
.compression
) == -1)
2886 if (height
< 0) height
= -height
;
2887 if (!lines
|| (startscan
>= height
))
2890 if (startscan
+ lines
> height
) lines
= height
- startscan
;
2892 switch (descr
.infoBpp
)
2897 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
2898 coloruse
== DIB_PAL_COLORS
? descr
.dc
: NULL
, coloruse
,
2899 bmp
->bitmap
.bmBitsPixel
,
2900 info
, &descr
.nColorMap
);
2901 if (!descr
.colorMap
) return 0;
2902 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2906 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2907 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2908 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2913 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2918 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2919 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2920 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2928 if(!bmp
->physBitmap
)
2929 X11DRV_CreateBitmap(hbitmap
);
2933 descr
.palentry
= NULL
;
2934 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
2935 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
2936 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
2937 descr
.gc
= BITMAP_GC(bmp
);
2941 descr
.yDest
= height
- startscan
- lines
;
2942 descr
.width
= bmp
->bitmap
.bmWidth
;
2943 descr
.height
= lines
;
2944 descr
.useShm
= FALSE
;
2946 EnterCriticalSection( &X11DRV_CritSection
);
2947 result
= CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
2948 LeaveCriticalSection( &X11DRV_CritSection
);
2950 if (descr
.colorMap
) HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
2955 /***********************************************************************
2956 * X11DRV_DIB_GetDIBits
2958 INT
X11DRV_DIB_GetDIBits(
2959 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
2960 UINT lines
, LPVOID bits
, BITMAPINFO
*info
,
2961 UINT coloruse
, HBITMAP hbitmap
)
2963 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
2964 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2965 PALETTEOBJ
* palette
;
2967 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
2968 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
2969 (int)info
->bmiHeader
.biWidth
, (int)info
->bmiHeader
.biHeight
,
2972 if (!(palette
= (PALETTEOBJ
*)GDI_GetObjPtr( dc
->hPalette
, PALETTE_MAGIC
)))
2975 if( lines
> info
->bmiHeader
.biHeight
) lines
= info
->bmiHeader
.biHeight
;
2976 /* Top-down images have a negative biHeight, the scanlines of theses images
2977 * were inverted in X11DRV_DIB_GetImageBits_xx
2978 * To prevent this we simply change the sign of lines
2979 * (the number of scan lines to copy).
2980 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
2982 if( info
->bmiHeader
.biHeight
< 0 && lines
> 0) lines
= -lines
;
2984 if( startscan
>= bmp
->bitmap
.bmHeight
)
2990 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &descr
.lines
,
2991 &descr
.infoBpp
, &descr
.compression
) == -1)
2997 switch (descr
.infoBpp
)
3003 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3007 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
3008 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
3009 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
3013 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
3014 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
3015 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
3020 if(!bmp
->physBitmap
)
3021 X11DRV_CreateBitmap(hbitmap
);
3025 descr
.palentry
= palette
->logpalette
.palPalEntry
;
3028 descr
.lines
= lines
;
3029 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3030 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
3031 descr
.gc
= BITMAP_GC(bmp
);
3032 descr
.width
= bmp
->bitmap
.bmWidth
;
3033 descr
.height
= bmp
->bitmap
.bmHeight
;
3034 descr
.colorMap
= info
->bmiColors
;
3039 if (descr
.lines
> 0)
3041 descr
.ySrc
= (descr
.height
-1) - (startscan
+ (lines
-1));
3045 descr
.ySrc
= startscan
;
3049 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
3051 descr
.useShm
= FALSE
;
3053 EnterCriticalSection( &X11DRV_CritSection
);
3055 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits
, &descr
);
3057 LeaveCriticalSection( &X11DRV_CritSection
);
3059 if(info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
3060 info
->bmiHeader
.biSizeImage
= DIB_GetDIBImageBytes(
3061 info
->bmiHeader
.biWidth
,
3062 info
->bmiHeader
.biHeight
,
3063 info
->bmiHeader
.biBitCount
);
3065 info
->bmiHeader
.biCompression
= 0;
3068 GDI_ReleaseObj( dc
->hPalette
);
3073 /***********************************************************************
3074 * DIB_DoProtectDIBSection
3076 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
3078 DIBSECTION
*dib
= bmp
->dib
;
3079 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
3080 : -dib
->dsBm
.bmHeight
;
3081 /* use the biSizeImage data as the memory size only if we're dealing with a
3082 compressed image where the value is set. Otherwise, calculate based on
3084 INT totalSize
= dib
->dsBmih
.biSizeImage
&& dib
->dsBmih
.biCompression
!= BI_RGB
3085 ? dib
->dsBmih
.biSizeImage
3086 : dib
->dsBm
.bmWidthBytes
* effHeight
;
3089 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
3090 TRACE("Changed protection from %ld to %ld\n", old_prot
, new_prot
);
3093 /***********************************************************************
3094 * X11DRV_DIB_DoUpdateDIBSection
3096 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
3098 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3099 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3101 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, &descr
.lines
,
3102 &descr
.infoBpp
, &descr
.compression
) == -1)
3106 descr
.palentry
= NULL
;
3107 descr
.image
= dib
->image
;
3108 descr
.colorMap
= (RGBQUAD
*)dib
->colorMap
;
3109 descr
.nColorMap
= dib
->nColorMap
;
3110 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
3111 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3113 switch (descr
.infoBpp
)
3119 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3123 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0x7c00;
3124 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x03e0;
3125 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x001f;
3129 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0xff;
3130 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0xff00;
3131 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0xff0000;
3136 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
3137 descr
.gc
= BITMAP_GC(bmp
);
3142 descr
.width
= bmp
->bitmap
.bmWidth
;
3143 descr
.height
= bmp
->bitmap
.bmHeight
;
3144 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
3148 TRACE("Copying from Pixmap to DIB bits\n");
3149 EnterCriticalSection( &X11DRV_CritSection
);
3150 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits
, &descr
);
3151 LeaveCriticalSection( &X11DRV_CritSection
);
3155 TRACE("Copying from DIB bits to Pixmap\n");
3156 EnterCriticalSection( &X11DRV_CritSection
);
3157 CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
3158 LeaveCriticalSection( &X11DRV_CritSection
);
3162 /***********************************************************************
3163 * X11DRV_DIB_FaultHandler
3165 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
3167 BOOL handled
= FALSE
;
3170 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
3171 if (!bmp
) return FALSE
;
3174 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3176 case X11DRV_DIB_GdiMod
:
3177 TRACE("called in status DIB_GdiMod\n" );
3178 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3179 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3180 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3181 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_InSync
;
3185 case X11DRV_DIB_InSync
:
3186 TRACE("called in status X11DRV_DIB_InSync\n" );
3187 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3188 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_AppMod
;
3192 case X11DRV_DIB_AppMod
:
3193 FIXME("called in status X11DRV_DIB_AppMod: this can't happen!\n" );
3196 case X11DRV_DIB_NoHandler
:
3197 FIXME("called in status DIB_NoHandler: this can't happen!\n" );
3201 GDI_ReleaseObj( (HBITMAP
)res
);
3205 /***********************************************************************
3206 * X11DRV_DIB_CmnUpdateDIBSection
3208 static void X11DRV_DIB_CmnUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
3211 if (!bmp
->dib
) return;
3215 /* Prepare for access to the DIB by GDI functions */
3217 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3220 case X11DRV_DIB_NoHandler
:
3221 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
3224 case X11DRV_DIB_GdiMod
:
3225 TRACE("fromDIB called in status X11DRV_DIB_GdiMod\n" );
3229 case X11DRV_DIB_InSync
:
3230 TRACE("fromDIB called in status X11DRV_DIB_InSync\n" );
3234 case X11DRV_DIB_AppMod
:
3235 TRACE("fromDIB called in status X11DRV_DIB_AppMod\n" );
3236 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
3237 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3238 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_InSync
;
3244 /* Acknowledge write access to the DIB by GDI functions */
3246 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3249 case X11DRV_DIB_NoHandler
:
3250 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3253 case X11DRV_DIB_GdiMod
:
3254 TRACE(" toDIB called in status X11DRV_DIB_GdiMod\n" );
3258 case X11DRV_DIB_InSync
:
3259 TRACE(" toDIB called in status X11DRV_DIB_InSync\n" );
3260 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
3261 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_GdiMod
;
3264 case X11DRV_DIB_AppMod
:
3265 FIXME(" toDIB called in status X11DRV_DIB_AppMod: "
3266 "this can't happen!\n" );
3272 /***********************************************************************
3273 * X11DRV_DIB_UpdateDIBSection2
3275 void X11DRV_DIB_UpdateDIBSection2(HBITMAP hbmp
, BOOL toDIB
)
3279 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hbmp
, BITMAP_MAGIC
);
3282 X11DRV_DIB_CmnUpdateDIBSection(bmp
, toDIB
);
3284 GDI_ReleaseObj(hbmp
);
3287 /***********************************************************************
3288 * X11DRV_DIB_UpdateDIBSection
3290 void X11DRV_DIB_UpdateDIBSection(DC
*dc
, BOOL toDIB
)
3292 /* Ensure this is a Compatible DC that has a DIB section selected */
3295 if (!(dc
->flags
& DC_MEMORY
)) return;
3297 X11DRV_DIB_UpdateDIBSection2(dc
->hBitmap
, toDIB
);
3300 /***********************************************************************
3301 * X11DRV_DIB_CreateDIBSection16
3303 HBITMAP16
X11DRV_DIB_CreateDIBSection16(
3304 DC
*dc
, BITMAPINFO
*bmi
, UINT16 usage
,
3305 SEGPTR
*bits
, HANDLE section
,
3306 DWORD offset
, DWORD ovr_pitch
)
3308 HBITMAP res
= X11DRV_DIB_CreateDIBSection(dc
, bmi
, usage
, NULL
,
3309 section
, offset
, ovr_pitch
);
3312 BITMAPOBJ
*bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
3313 if ( bmp
&& bmp
->dib
)
3315 DIBSECTION
*dib
= bmp
->dib
;
3316 INT height
= dib
->dsBm
.bmHeight
>= 0 ?
3317 dib
->dsBm
.bmHeight
: -dib
->dsBm
.bmHeight
;
3318 /* same as above - only use biSizeImage as the correct size if it a
3319 compressed image and it's currently non-zero. In other cases, use
3320 width * height as the value. */
3321 INT size
= dib
->dsBmih
.biSizeImage
&& dib
->dsBmih
.biCompression
!= BI_RGB
3322 ? dib
->dsBmih
.biSizeImage
3323 : dib
->dsBm
.bmWidthBytes
* height
;
3324 if ( dib
->dsBm
.bmBits
)
3326 ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
=
3327 SELECTOR_AllocBlock( dib
->dsBm
.bmBits
, size
, WINE_LDT_FLAGS_DATA
);
3329 TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
3330 dib
->dsBm
.bmBits
, size
, ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
,
3331 PTR_SEG_OFF_TO_SEGPTR(((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
, 0));
3333 *bits
= PTR_SEG_OFF_TO_SEGPTR( ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
, 0 );
3335 if (bmp
) GDI_ReleaseObj( res
);
3341 /***********************************************************************
3342 * X11DRV_XShmErrorHandler
3345 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
)
3351 /***********************************************************************
3352 * X11DRV_XShmCreateImage
3356 extern BOOL
X11DRV_XShmCreateImage(XImage
** image
, int width
, int height
, int bpp
,
3357 XShmSegmentInfo
* shminfo
)
3359 int (*WineXHandler
)(Display
*, XErrorEvent
*);
3361 *image
= TSXShmCreateImage(display
, X11DRV_GetVisual(), bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
3362 if( *image
!= NULL
)
3364 EnterCriticalSection( &X11DRV_CritSection
);
3365 shminfo
->shmid
= shmget(IPC_PRIVATE
, (*image
)->bytes_per_line
* height
,
3367 if( shminfo
->shmid
!= -1 )
3369 shminfo
->shmaddr
= (*image
)->data
= shmat(shminfo
->shmid
, 0, 0);
3370 if( shminfo
->shmaddr
!= (char*)-1 )
3372 shminfo
->readOnly
= FALSE
;
3373 if( TSXShmAttach( display
, shminfo
) != 0)
3375 /* Reset the error flag */
3377 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
3378 XSync( display
, 0 );
3382 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3384 XSetErrorHandler(WineXHandler
);
3385 LeaveCriticalSection( &X11DRV_CritSection
);
3387 return TRUE
; /* Success! */
3389 /* An error occured */
3391 XSetErrorHandler(WineXHandler
);
3393 shmdt(shminfo
->shmaddr
);
3395 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3398 XDestroyImage(*image
);
3399 LeaveCriticalSection( &X11DRV_CritSection
);
3407 /***********************************************************************
3408 * X11DRV_DIB_CreateDIBSection
3410 HBITMAP
X11DRV_DIB_CreateDIBSection(
3411 DC
*dc
, BITMAPINFO
*bmi
, UINT usage
,
3412 LPVOID
*bits
, HANDLE section
,
3413 DWORD offset
, DWORD ovr_pitch
)
3416 BITMAPOBJ
*bmp
= NULL
;
3417 X11DRV_DIBSECTION
*dib
= NULL
;
3418 int *colorMap
= NULL
;
3421 /* Fill BITMAP32 structure with DIB data */
3422 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
3423 INT effHeight
, totalSize
;
3426 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
3427 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
3428 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
3430 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
3432 bm
.bmWidth
= bi
->biWidth
;
3433 bm
.bmHeight
= effHeight
;
3434 bm
.bmWidthBytes
= ovr_pitch
? ovr_pitch
3435 : DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
3436 bm
.bmPlanes
= bi
->biPlanes
;
3437 bm
.bmBitsPixel
= bi
->biBitCount
;
3440 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
3441 we're dealing with a compressed bitmap. Otherwise, use width * height. */
3442 totalSize
= bi
->biSizeImage
&& bi
->biCompression
!= BI_RGB
3443 ? bi
->biSizeImage
: bm
.bmWidthBytes
* effHeight
;
3446 bm
.bmBits
= MapViewOfFile(section
, FILE_MAP_ALL_ACCESS
,
3447 0L, offset
, totalSize
);
3448 else if (ovr_pitch
&& offset
)
3449 bm
.bmBits
= (LPVOID
) offset
;
3452 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
3453 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
3456 /* Create Color Map */
3457 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8)
3458 colorMap
= X11DRV_DIB_BuildColorMap( usage
== DIB_PAL_COLORS
? dc
: NULL
,
3459 usage
, bm
.bmBitsPixel
, bmi
, &nColorMap
);
3461 /* Allocate Memory for DIB and fill structure */
3463 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
3466 dib
->dibSection
.dsBm
= bm
;
3467 dib
->dibSection
.dsBmih
= *bi
;
3468 dib
->dibSection
.dsBmih
.biSizeImage
= totalSize
;
3470 /* Set dsBitfields values */
3471 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
3473 dib
->dibSection
.dsBitfields
[0] = dib
->dibSection
.dsBitfields
[1] = dib
->dibSection
.dsBitfields
[2] = 0;
3475 else switch( bi
->biBitCount
)
3478 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
3479 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
3480 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f;
3484 dib
->dibSection
.dsBitfields
[0] = 0xff;
3485 dib
->dibSection
.dsBitfields
[1] = 0xff00;
3486 dib
->dibSection
.dsBitfields
[2] = 0xff0000;
3490 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff;
3491 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0xff00;
3492 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0xff0000;
3495 dib
->dibSection
.dshSection
= section
;
3496 dib
->dibSection
.dsOffset
= offset
;
3498 dib
->status
= X11DRV_DIB_NoHandler
;
3501 dib
->nColorMap
= nColorMap
;
3502 dib
->colorMap
= colorMap
;
3505 /* Create Device Dependent Bitmap and add DIB pointer */
3508 res
= CreateDIBitmap(dc
->hSelf
, bi
, 0, NULL
, bmi
, usage
);
3511 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
3514 bmp
->dib
= (DIBSECTION
*) dib
;
3516 if(!bmp
->physBitmap
)
3517 X11DRV_CreateBitmap(res
);
3525 if (TSXShmQueryExtension(display
) &&
3526 X11DRV_XShmCreateImage( &dib
->image
, bm
.bmWidth
, effHeight
,
3527 bmp
->bitmap
.bmBitsPixel
, &dib
->shminfo
) )
3529 ; /* Created Image */
3531 XCREATEIMAGE( dib
->image
, bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
3532 dib
->shminfo
.shmid
= -1;
3536 /* Clean up in case of errors */
3537 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
3539 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
3540 res
, bmp
, dib
, bm
.bmBits
);
3544 UnmapViewOfFile(bm
.bmBits
), bm
.bmBits
= NULL
;
3546 VirtualFree(bm
.bmBits
, 0L, MEM_RELEASE
), bm
.bmBits
= NULL
;
3549 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
3550 if (colorMap
) { HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
; }
3551 if (dib
) { HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
; }
3552 if (bmp
) { GDI_ReleaseObj(res
); bmp
= NULL
; }
3553 if (res
) { DeleteObject(res
); res
= 0; }
3556 /* Install fault handler, if possible */
3559 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
3561 if (section
|| offset
)
3563 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3564 if (dib
) dib
->status
= X11DRV_DIB_AppMod
;
3568 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3569 if (dib
) dib
->status
= X11DRV_DIB_InSync
;
3574 /* Return BITMAP handle and storage location */
3575 if (bmp
) GDI_ReleaseObj(res
);
3576 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
3580 /***********************************************************************
3581 * X11DRV_DIB_DeleteDIBSection
3583 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
3585 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3589 if (dib
->shminfo
.shmid
!= -1)
3591 TSXShmDetach (display
, &(dib
->shminfo
));
3592 XDestroyImage (dib
->image
);
3593 shmdt (dib
->shminfo
.shmaddr
);
3594 dib
->shminfo
.shmid
= -1;
3597 XDestroyImage( dib
->image
);
3601 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
3603 if (dib
->selector
) SELECTOR_FreeBlock( dib
->selector
);
3607 /**************************************************************************
3608 * X11DRV_DIB_CreateDIBFromPixmap
3610 * Allocates a packed DIB and copies the Pixmap data into it.
3611 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
3613 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
, BOOL bDeletePixmap
)
3616 BITMAPOBJ
*pBmp
= NULL
;
3617 HGLOBAL hPackedDIB
= 0;
3619 /* Allocates an HBITMAP which references the Pixmap passed to us */
3620 hBmp
= X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap
);
3623 TRACE("\tCould not create bitmap header for Pixmap\n");
3628 * Create a packed DIB from the Pixmap wrapper bitmap created above.
3629 * A packed DIB contains a BITMAPINFO structure followed immediately by
3630 * an optional color palette and the pixel data.
3632 hPackedDIB
= DIB_CreateDIBFromBitmap(hdc
, hBmp
);
3634 /* Get a pointer to the BITMAPOBJ structure */
3635 pBmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3637 /* We can now get rid of the HBITMAP wrapper we created earlier.
3638 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
3642 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
3643 pBmp
->physBitmap
= NULL
;
3646 GDI_ReleaseObj( hBmp
);
3650 TRACE("\tReturning packed DIB %x\n", hPackedDIB
);
3655 /**************************************************************************
3656 * X11DRV_DIB_CreatePixmapFromDIB
3658 * Creates a Pixmap from a packed DIB
3660 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
3662 Pixmap pixmap
= None
;
3664 BITMAPOBJ
*pBmp
= NULL
;
3665 LPBYTE pPackedDIB
= NULL
;
3666 LPBITMAPINFO pbmi
= NULL
;
3667 LPBITMAPINFOHEADER pbmiHeader
= NULL
;
3668 LPBYTE pbits
= NULL
;
3670 /* Get a pointer to the packed DIB's data */
3671 pPackedDIB
= (LPBYTE
)GlobalLock(hPackedDIB
);
3672 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
3673 pbmi
= (LPBITMAPINFO
)pPackedDIB
;
3674 pbits
= (LPBYTE
)(pPackedDIB
3675 + DIB_BitmapInfoSize( (LPBITMAPINFO
)pbmiHeader
, DIB_RGB_COLORS
));
3677 /* Create a DDB from the DIB */
3679 hBmp
= CreateDIBitmap(hdc
,
3686 GlobalUnlock(hPackedDIB
);
3688 TRACE("CreateDIBitmap returned %x\n", hBmp
);
3690 /* Retrieve the internal Pixmap from the DDB */
3692 pBmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3694 pixmap
= (Pixmap
)pBmp
->physBitmap
;
3695 /* clear the physBitmap so that we can steal its pixmap */
3696 pBmp
->physBitmap
= NULL
;
3699 /* Delete the DDB we created earlier now that we have stolen its pixmap */
3700 GDI_ReleaseObj( hBmp
);
3703 TRACE("\tReturning Pixmap %ld\n", pixmap
);