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_GenColorMap
83 * Fills the color map of a bitmap palette. Should not be called
84 * for a >8-bit deep bitmap.
86 int *X11DRV_DIB_GenColorMap( DC
*dc
, int *colorMapping
,
87 WORD coloruse
, WORD depth
, BOOL quads
,
88 const void *colorPtr
, int start
, int end
)
92 if (coloruse
== DIB_RGB_COLORS
)
96 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
98 if (depth
== 1) /* Monochrome */
99 for (i
= start
; i
< end
; i
++, rgb
++)
100 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
101 rgb
->rgbBlue
> 255*3/2);
103 for (i
= start
; i
< end
; i
++, rgb
++)
104 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbRed
,
110 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
112 if (depth
== 1) /* Monochrome */
113 for (i
= start
; i
< end
; i
++, rgb
++)
114 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
115 rgb
->rgbtBlue
> 255*3/2);
117 for (i
= start
; i
< end
; i
++, rgb
++)
118 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbtRed
,
123 else /* DIB_PAL_COLORS */
125 WORD
* index
= (WORD
*)colorPtr
;
127 for (i
= start
; i
< end
; i
++, index
++)
128 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, PALETTEINDEX(*index
) );
134 /***********************************************************************
135 * X11DRV_DIB_BuildColorMap
137 * Build the color map from the bitmap palette. Should not be called
138 * for a >8-bit deep bitmap.
140 int *X11DRV_DIB_BuildColorMap( DC
*dc
, WORD coloruse
, WORD depth
,
141 const BITMAPINFO
*info
, int *nColors
)
148 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
150 colors
= info
->bmiHeader
.biClrUsed
;
151 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
152 colorPtr
= (WORD
*)info
->bmiColors
;
154 else /* assume BITMAPCOREINFO */
156 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
157 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
162 ERR("called with >256 colors!\n");
166 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
167 colors
* sizeof(int) )))
171 return X11DRV_DIB_GenColorMap( dc
, colorMapping
, coloruse
, depth
,
172 isInfo
, colorPtr
, 0, colors
);
176 /***********************************************************************
177 * X11DRV_DIB_MapColor
179 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
, int oldcol
)
183 if ((oldcol
< nPhysMap
) && (physMap
[oldcol
] == phys
))
186 for (color
= 0; color
< nPhysMap
; color
++)
187 if (physMap
[color
] == phys
)
190 WARN("Strange color %08x\n", phys
);
195 /*********************************************************************
196 * X11DRV_DIB_GetNearestIndex
198 * Helper for X11DRV_DIB_GetDIBits.
199 * Returns the nearest colour table index for a given RGB.
200 * Nearest is defined by minimizing the sum of the squares.
202 static INT
X11DRV_DIB_GetNearestIndex(RGBQUAD
*colormap
, int numColors
, BYTE r
, BYTE g
, BYTE b
)
204 INT i
, best
= -1, diff
, bestdiff
= -1;
207 for(color
= colormap
, i
= 0; i
< numColors
; color
++, i
++) {
208 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
209 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
210 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
213 if(best
== -1 || diff
< bestdiff
) {
221 /***********************************************************************
222 * X11DRV_DIB_SetImageBits_1_Line
224 * Handles a single line of 1 bit data.
226 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth
, int left
, int *colors
,
227 XImage
*bmpImage
, int h
, const BYTE
*bits
)
232 if((extra
= (left
& 7)) != 0) {
239 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
240 for (i
= dstwidth
/8, x
= left
; i
> 0; i
--)
243 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
244 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 6) & 1] );
245 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 5) & 1] );
246 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 4) & 1] );
247 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 3) & 1] );
248 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 2) & 1] );
249 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 1) & 1] );
250 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 1] );
255 case 7: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
256 case 6: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
257 case 5: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
258 case 4: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
259 case 3: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
260 case 2: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
261 case 1: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
265 /***********************************************************************
266 * X11DRV_DIB_SetImageBits_1
268 * SetDIBits for a 1-bit deep DIB.
270 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
271 DWORD srcwidth
, DWORD dstwidth
, int left
,
272 int *colors
, XImage
*bmpImage
)
277 DWORD linebytes
= ((srcwidth
+ 31) & ~31) / 8;
280 for (h
= lines
-1; h
>=0; h
--) {
281 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
283 srcbits
+= linebytes
;
287 for (h
= 0; h
< lines
; h
++) {
288 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
290 srcbits
+= linebytes
;
295 /***********************************************************************
296 * X11DRV_DIB_GetImageBits_1
298 * GetDIBits for a 1-bit deep DIB.
300 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
301 DWORD dstwidth
, DWORD srcwidth
,
302 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
310 DWORD linebytes
= ((dstwidth
+ 31) & ~31) / 8;
314 dstbits
= dstbits
+ linebytes
* (lines
- 1);
315 linebytes
= -linebytes
;
320 switch(bmpImage
->depth
) {
323 /* ==== monochrome bitmap to monochrome dib ==== */
325 /* ==== 4 colormap bitmap to monochrome dib ==== */
326 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
330 for (h
= lines
- 1; h
>= 0; h
--) {
331 for (x
= 0; x
< dstwidth
; x
++) {
332 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
333 if (!(x
&7)) *bits
= 0;
334 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2,
337 val
.peBlue
) << (7 - (x
& 7)));
338 if ((x
&7)==7) bits
++;
340 bits
= (dstbits
+= linebytes
);
343 else goto notsupported
;
348 /* ==== 8 colormap bitmap to monochrome dib ==== */
349 if ( bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
354 for( h
= lines
- 1; h
>= 0; h
-- ) {
355 srcpixel
= bmpImage
->data
+ (h
*bmpImage
->bytes_per_line
);
356 for( x
= 0; x
< dstwidth
; x
++ ) {
357 if (!(x
&7)) *bits
= 0;
358 val
= srccolors
[(int)*srcpixel
++];
359 *bits
|= ( X11DRV_DIB_GetNearestIndex(colors
, 2,
362 val
.peBlue
) << (7-(x
&7)) );
363 if ((x
&7)==7) bits
++;
365 bits
= (dstbits
+= linebytes
);
368 else goto notsupported
;
377 /* ==== 555 BGR bitmap to monochrome dib ==== */
378 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x1f)
380 for( h
= lines
- 1; h
>= 0; h
--) {
381 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
382 for( x
= 0; x
< dstwidth
; x
++) {
383 if (!(x
&7)) *bits
= 0;
385 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
386 ((val
>> 7) & 0xf8) |
388 ((val
>> 2) & 0xf8) |
390 ((val
<< 3) & 0xf8) |
391 ((val
>> 2) & 0x7) ) << (7-(x
&7)) );
392 if ((x
&7)==7) bits
++;
394 bits
= (dstbits
+= linebytes
);
397 /* ==== 555 RGB bitmap to monochrome dib ==== */
398 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
400 for( h
= lines
- 1; h
>= 0; h
--)
402 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
403 for( x
= 0; x
< dstwidth
; x
++) {
404 if (!(x
&1)) *bits
= 0;
406 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
407 ((val
<< 3) & 0xf8) |
409 ((val
>> 2) & 0xf8) |
411 ((val
>> 7) & 0xf8) |
412 ((val
>> 12) & 0x7) ) << (7-(x
&7)) );
413 if ((x
&7)==7) bits
++;
415 bits
= (dstbits
+= linebytes
);
418 else goto notsupported
;
427 /* ==== 565 BGR bitmap to monochrome dib ==== */
428 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
430 for( h
= lines
- 1; h
>= 0; h
--)
432 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
433 for( x
= 0; x
< dstwidth
; x
++) {
434 if (!(x
&7)) *bits
= 0;
436 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
437 ((val
>> 8) & 0xf8) |
439 ((val
>> 3) & 0xfc) |
441 ((val
<< 3) & 0xf8) |
442 ((val
>> 2) & 0x7) ) << (7-(x
&7)) );
443 if ((x
&7)==7) bits
++;
445 bits
= (dstbits
+= linebytes
);
448 /* ==== 565 RGB bitmap to monochrome dib ==== */
449 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
451 for( h
= lines
- 1; h
>= 0; h
--)
453 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
454 for( x
= 0; x
< dstwidth
; x
++) {
455 if (!(x
&7)) *bits
= 0;
457 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
458 ((val
<< 3) & 0xf8) |
460 ((val
>> 3) & 0xfc) |
462 ((val
>> 8) & 0xf8) |
463 ((val
>> 13) & 0x7) ) << (7-(x
&7)) );
464 if ((x
&7)==7) bits
++;
466 bits
= (dstbits
+= linebytes
);
469 else goto notsupported
;
478 /* ==== 24/32 BGR bitmap to monochrome dib ==== */
479 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
481 for (h
= lines
- 1; h
>= 0; h
--)
483 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
484 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4) {
485 if (!(x
&7)) *bits
= 0;
486 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2, srcpixel
[2] , srcpixel
[1], srcpixel
[0]) << (7-(x
&7)) );
487 if ((x
&7)==7) bits
++;
489 bits
= (dstbits
+= linebytes
);
492 /* ==== 24/32 RGB bitmap to monochrome dib ==== */
493 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
495 for (h
= lines
- 1; h
>= 0; h
--)
497 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
498 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4) {
499 if (!(x
& 7)) *bits
= 0;
500 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2, srcpixel
[0] , srcpixel
[1], srcpixel
[2]) << (7-(x
&7)) );
501 if ((x
& 7) == 7) bits
++;
503 bits
= (dstbits
+= linebytes
);
506 else goto notsupported
;
510 default: /* ? bit bmp -> monochrome DIB */
513 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
515 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
516 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
517 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
519 for( h
= lines
- 1; h
>= 0; h
-- ) {
520 for( x
= 0; x
< dstwidth
; x
++ ) {
521 if (!(x
&7)) *bits
= 0;
522 *bits
|= (XGetPixel( bmpImage
, x
, h
) >= white
)
524 if ((x
&7)==7) bits
++;
526 bits
= (dstbits
+= linebytes
);
533 /***********************************************************************
534 * X11DRV_DIB_SetImageBits_4
536 * SetDIBits for a 4-bit deep DIB.
538 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
539 DWORD srcwidth
, DWORD dstwidth
, int left
,
540 int *colors
, XImage
*bmpImage
)
544 const BYTE
*bits
= srcbits
+ (left
>> 1);
547 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
555 for (h
= lines
-1; h
>= 0; h
--) {
556 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
558 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
559 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
561 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
562 srcbits
+= linebytes
;
563 bits
= srcbits
+ (left
>> 1);
567 for (h
= 0; h
< lines
; h
++) {
568 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
570 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
571 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
573 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
574 srcbits
+= linebytes
;
575 bits
= srcbits
+ (left
>> 1);
582 /***********************************************************************
583 * X11DRV_DIB_GetImageBits_4
585 * GetDIBits for a 4-bit deep DIB.
587 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
588 DWORD srcwidth
, DWORD dstwidth
,
589 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
598 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
603 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
604 linebytes
= -linebytes
;
609 switch(bmpImage
->depth
) {
612 /* ==== monochrome bitmap to 4 colormap dib ==== */
614 /* ==== 4 colormap bitmap to 4 colormap dib ==== */
615 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
619 for (h
= lines
-1; h
>= 0; h
--) {
620 for (x
= 0; x
< dstwidth
; x
++) {
621 if (!(x
&1)) *bits
= 0;
622 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
623 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 16,
626 val
.peBlue
) << (4-((x
&1)<<2)));
627 if ((x
&1)==1) bits
++;
629 bits
= (dstbits
+= linebytes
);
632 else goto notsupported
;
637 /* ==== 8 colormap bitmap to 4 colormap dib ==== */
638 if ( bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
642 for( h
= lines
- 1; h
>= 0; h
-- ) {
643 srcpixel
= bmpImage
->data
+ (h
*bmpImage
->bytes_per_line
);
644 for( x
= 0; x
< dstwidth
; x
++ ) {
645 if (!(x
&1)) *bits
= 0;
646 val
= srccolors
[(int)*srcpixel
++];
647 *bits
|= ( X11DRV_DIB_GetNearestIndex(colors
, 16,
650 val
.peBlue
) << (4*(1-(x
&1))) );
651 if ((x
&1)==1) bits
++;
653 bits
= (dstbits
+= linebytes
);
656 else goto notsupported
;
665 /* ==== 555 BGR bitmap to 4 colormap dib ==== */
666 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x1f)
668 for( h
= lines
- 1; h
>= 0; h
--) {
669 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
670 for( x
= 0; x
< dstwidth
; x
++) {
671 if (!(x
&1)) *bits
= 0;
673 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
674 ((val
>> 7) & 0xf8) |
676 ((val
>> 2) & 0xf8) |
678 ((val
<< 3) & 0xf8) |
679 ((val
>> 2) & 0x7) ) << ((1-(x
&1))<<2) );
680 if ((x
&1)==1) bits
++;
682 bits
= (dstbits
+= linebytes
);
685 /* ==== 555 RGB bitmap to 4 colormap dib ==== */
686 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
688 for( h
= lines
- 1; h
>= 0; h
--)
690 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
691 for( x
= 0; x
< dstwidth
; x
++) {
692 if (!(x
&1)) *bits
= 0;
694 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
695 ((val
<< 3) & 0xf8) |
697 ((val
>> 2) & 0xfc) |
699 ((val
>> 7) & 0xf8) |
700 ((val
>> 12) & 0x7) ) << ((1-(x
&1))<<2) );
701 if ((x
&1)==1) bits
++;
703 bits
= (dstbits
+= linebytes
);
706 else goto notsupported
;
715 /* ==== 565 BGR bitmap to 4 colormap dib ==== */
716 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
718 for( h
= lines
- 1; h
>= 0; h
--)
720 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
721 for( x
= 0; x
< dstwidth
; x
++) {
722 if (!(x
&1)) *bits
= 0;
724 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
725 ((val
>> 8) & 0xf8) |
727 ((val
>> 3) & 0xfc) |
729 ((val
<< 3) & 0xf8) |
730 ((val
>> 2) & 0x7) ) << ((1-(x
&1))<<2) );
731 if ((x
&1)==1) bits
++;
733 bits
= (dstbits
+= linebytes
);
736 /* ==== 565 RGB bitmap to 4 colormap dib ==== */
737 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
739 for( h
= lines
- 1; h
>= 0; h
--)
741 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
742 for( x
= 0; x
< dstwidth
; x
++) {
743 if (!(x
&1)) *bits
= 0;
745 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
746 ((val
<< 3) & 0xf8) |
748 ((val
>> 3) & 0xfc) |
750 ((val
>> 8) & 0xf8) |
751 ((val
>> 13) & 0x7) ) << ((1-(x
&1))<<2) );
752 if ((x
&1)==1) bits
++;
754 bits
= (dstbits
+= linebytes
);
757 else goto notsupported
;
766 /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
767 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
769 for (h
= lines
- 1; h
>= 0; h
--)
771 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
772 for (x
= 0; x
< dstwidth
; x
+=2, srcpixel
+=8) /* 2 pixels at a time */
773 *bits
++ = (X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[2] , srcpixel
[1], srcpixel
[0]) << 4) |
774 X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[6] , srcpixel
[5], srcpixel
[4]);
775 bits
= (dstbits
+= linebytes
);
778 /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
779 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
781 for (h
= lines
- 1; h
>= 0; h
--)
783 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
784 for (x
= 0; x
< dstwidth
; x
+=2, srcpixel
+=8) /* 2 pixels at a time */
785 *bits
++ = (X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[0] , srcpixel
[1], srcpixel
[2]) << 4) |
786 X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[4] , srcpixel
[5], srcpixel
[6]);
787 bits
= (dstbits
+= linebytes
);
790 else goto notsupported
;
794 default: /* ? bit bmp -> 4 bit DIB */
796 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
797 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
798 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
799 for (h
= lines
-1; h
>= 0; h
--) {
800 for (x
= 0; x
< dstwidth
/2; x
++) {
801 *bits
++ = (X11DRV_DIB_MapColor((int *)colors
, 16,
802 XGetPixel( bmpImage
, x
++, h
), 0) << 4)
803 | (X11DRV_DIB_MapColor((int *)colors
, 16,
804 XGetPixel( bmpImage
, x
++, h
), 0) & 0x0f);
807 *bits
= (X11DRV_DIB_MapColor((int *)colors
, 16,
808 XGetPixel( bmpImage
, x
++, h
), 0) << 4);
809 bits
= (dstbits
+= linebytes
);
815 /***********************************************************************
816 * X11DRV_DIB_SetImageBits_RLE4
818 * SetDIBits for a 4-bit deep compressed DIB.
820 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
821 DWORD width
, DWORD dstwidth
,
822 int left
, int *colors
,
825 int x
= 0, c
, length
;
826 const BYTE
*begin
= bits
;
830 while ((int)lines
>= 0) {
832 if (length
) { /* encoded */
840 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>>4]);
848 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
859 case 1: /* eopicture */
865 FIXME_(x11drv
)("x-delta is too large?\n");
871 default: /* absolute */
879 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>> 4]);
887 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
890 if ((bits
- begin
) & 1)
899 /***********************************************************************
900 * X11DRV_DIB_SetImageBits_8
902 * SetDIBits for an 8-bit deep DIB.
904 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
905 DWORD srcwidth
, DWORD dstwidth
, int left
,
906 const int *colors
, XImage
*bmpImage
)
912 /* align to 32 bit */
913 DWORD linebytes
= (srcwidth
+ 3) & ~3;
920 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
921 linebytes
= -linebytes
;
924 bits
= srcbits
+ left
;
926 switch (bmpImage
->depth
) {
929 #if defined(__i386__) && defined(__GNUC__)
930 /* Some X servers might have 32 bit/ 16bit deep pixel */
931 if (lines
&& (dstwidth
!=left
) && (bmpImage
->bits_per_pixel
== 16))
933 for (h
= lines
; h
--; ) {
934 int _cl1
,_cl2
; /* temp outputs for asm below */
935 /* Borrowed from DirectDraw */
936 __asm__
__volatile__(
941 " movw (%%edx,%%eax,4),%%ax\n"
945 :"=S" (bits
), "=D" (_cl1
), "=c" (_cl2
)
947 "D" (bmpImage
->data
+h
*bmpImage
->bytes_per_line
+left
*2),
950 :"eax", "cc", "memory"
952 bits
= (srcbits
+= linebytes
) + left
;
959 break; /* use slow generic case below */
962 for (h
= lines
- 1; h
>= 0; h
--) {
963 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
964 color
= colors
[*bits
];
965 XPutPixel( bmpImage
, x
, h
, colors
[*bits
] );
967 bits
= (srcbits
+= linebytes
) + left
;
971 /***********************************************************************
972 * X11DRV_DIB_GetImageBits_8
974 * GetDIBits for an 8-bit deep DIB.
976 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
977 DWORD srcwidth
, DWORD dstwidth
,
978 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
985 /* align to 32 bit */
986 DWORD linebytes
= (srcwidth
+ 3) & ~3;
991 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
992 linebytes
= -linebytes
;
999 This condition is true when GetImageBits has been called by UpdateDIBSection.
1000 For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
1001 for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
1003 if (!srccolors
) goto updatesection
;
1005 switch(bmpImage
->depth
) {
1008 /* ==== monochrome bitmap to 8 colormap dib ==== */
1010 /* ==== 4 colormap bitmap to 8 colormap dib ==== */
1011 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1015 for (h
= lines
- 1; h
>= 0; h
--) {
1016 for (x
= 0; x
< dstwidth
; x
++) {
1017 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
1018 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256, val
.peRed
,
1019 val
.peGreen
, val
.peBlue
);
1021 bits
= (dstbits
+= linebytes
);
1024 else goto notsupported
;
1029 /* ==== 8 colormap bitmap to 8 colormap dib ==== */
1030 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1035 for (h
= lines
- 1; h
>= 0; h
--) {
1036 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1037 for (x
= 0; x
< dstwidth
; x
++) {
1038 val
= srccolors
[(int)*srcpixel
++];
1039 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256, val
.peRed
,
1040 val
.peGreen
, val
.peBlue
);
1042 bits
= (dstbits
+= linebytes
);
1045 else goto notsupported
;
1054 /* ==== 555 BGR bitmap to 8 colormap dib ==== */
1055 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
1057 for( h
= lines
- 1; h
>= 0; h
--)
1059 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1060 for( x
= 0; x
< dstwidth
; x
++ )
1063 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1064 ((val
>> 7) & 0xf8) |
1065 ((val
>> 12) & 0x7),
1066 ((val
>> 2) & 0xf8) |
1068 ((val
<< 3) & 0xf8) |
1069 ((val
>> 2) & 0x7) );
1071 bits
= (dstbits
+= linebytes
);
1074 /* ==== 555 RGB bitmap to 8 colormap dib ==== */
1075 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
1077 for( h
= lines
- 1; h
>= 0; h
--)
1079 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1080 for( x
= 0; x
< dstwidth
; x
++ )
1083 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1084 ((val
<< 3) & 0xf8) |
1086 ((val
>> 2) & 0xf8) |
1088 ((val
>> 7) & 0xf8) |
1089 ((val
>> 12) & 0x7) );
1091 bits
= (dstbits
+= linebytes
);
1094 else goto notsupported
;
1103 /* ==== 565 BGR bitmap to 8 colormap dib ==== */
1104 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
1106 for( h
= lines
- 1; h
>= 0; h
--)
1108 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1109 for( x
= 0; x
< dstwidth
; x
++ )
1112 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1113 ((val
>> 8) & 0xf8) |
1114 ((val
>> 13) & 0x7),
1115 ((val
>> 3) & 0xfc) |
1117 ((val
<< 3) & 0xf8) |
1118 ((val
>> 2) & 0x7) );
1120 bits
= (dstbits
+= linebytes
);
1123 /* ==== 565 RGB bitmap to 8 colormap dib ==== */
1124 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
1126 for( h
= lines
- 1; h
>= 0; h
--)
1128 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1129 for( x
= 0; x
< dstwidth
; x
++ )
1132 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1133 ((val
<< 3) & 0xf8) |
1135 ((val
>> 3) & 0x00fc) |
1137 ((val
>> 8) & 0x00f8) |
1138 ((val
>> 13) & 0x7) );
1140 bits
= (dstbits
+= linebytes
);
1143 else goto notsupported
;
1152 /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
1153 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1155 for (h
= lines
- 1; h
>= 0; h
--)
1157 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1158 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4)
1159 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256,
1160 srcpixel
[2] , srcpixel
[1], *srcpixel
);
1161 bits
= (dstbits
+= linebytes
);
1164 /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
1165 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1167 for (h
= lines
- 1; h
>= 0; h
--)
1169 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1170 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4)
1171 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256,
1172 *srcpixel
, srcpixel
[1], srcpixel
[2]);
1173 bits
= (dstbits
+= linebytes
);
1177 else goto notsupported
;
1181 default: /* ? bit bmp -> 8 bit DIB */
1183 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
1184 bmpImage
->depth
, (int)bmpImage
->red_mask
,
1185 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1187 for (h
= lines
- 1; h
>= 0; h
--) {
1188 for (x
= 0; x
< dstwidth
; x
++, bits
++) {
1189 *bits
= X11DRV_DIB_MapColor((int *)colors
, 256,
1190 XGetPixel( bmpImage
, x
, h
), *bits
);
1192 bits
= (dstbits
+= linebytes
);
1198 /***********************************************************************
1199 * X11DRV_DIB_SetImageBits_RLE8
1201 * SetDIBits for an 8-bit deep compressed DIB.
1203 * This function rewritten 941113 by James Youngman. WINE blew out when I
1204 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1206 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1207 * 'End of bitmap' escape code. This code is very much laxer in what it
1208 * allows to end the expansion. Possibly too lax. See the note by
1209 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1210 * bitmap should end with RleEnd, but on the other hand, software exists
1211 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1214 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1215 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1219 enum Rle8_EscapeCodes
1222 * Apologies for polluting your file's namespace...
1224 RleEol
= 0, /* End of line */
1225 RleEnd
= 1, /* End of bitmap */
1226 RleDelta
= 2 /* Delta */
1229 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
1230 DWORD width
, DWORD dstwidth
,
1231 int left
, int *colors
,
1234 int x
; /* X-positon on each line. Increases. */
1235 int line
; /* Line #. Starts at lines-1, decreases */
1236 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
1237 BYTE length
; /* The length pf a run */
1238 BYTE color_index
; /* index into colors[] as read from bits */
1239 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
1240 int color
; /* value of colour[color_index] */
1242 if (lines
== 0) /* Let's hope this doesn't happen. */
1246 * Note that the bitmap data is stored by Windows starting at the
1247 * bottom line of the bitmap and going upwards. Within each line,
1248 * the data is stored left-to-right. That's the reason why line
1249 * goes from lines-1 to 0. [JAY]
1259 * If the length byte is not zero (which is the escape value),
1260 * We have a run of length pixels all the same colour. The colour
1261 * index is stored next.
1263 * If the length byte is zero, we need to read the next byte to
1264 * know what to do. [JAY]
1269 * [Run-Length] Encoded mode
1271 color_index
= (*pIn
++); /* Get the colour index. */
1272 color
= colors
[color_index
];
1281 XPutPixel(bmpImage
, x
++, line
, color
);
1287 * Escape codes (may be an absolute sequence though)
1289 escape_code
= (*pIn
++);
1292 case RleEol
: /* =0, end of line */
1299 case RleEnd
: /* =1, end of bitmap */
1302 * Not all RLE8 bitmaps end with this
1303 * code. For example, Paint Shop Pro
1304 * produces some that don't. That's (I think)
1305 * what caused the previous implementation to
1308 line
=-1; /* Cause exit from do loop. */
1312 case RleDelta
: /* =2, a delta */
1315 * Note that deltaing to line 0
1316 * will cause an exit from the loop,
1317 * which may not be what is intended.
1318 * The fact that there is a delta in the bits
1319 * almost certainly implies that there is data
1320 * to follow. You may feel that we should
1321 * jump to the top of the loop to avoid exiting
1324 * TODO: Decide what to do here in that case. [JAY]
1330 TRACE("Delta to last line of bitmap "
1331 "(wrongly?) causes loop exit\n");
1336 default: /* >2, switch to absolute mode */
1341 length
= escape_code
;
1344 color_index
= (*pIn
++);
1350 XPutPixel(bmpImage
, x
++, line
,
1351 colors
[color_index
]);
1355 * If you think for a moment you'll realise that the
1356 * only time we could ever possibly read an odd
1357 * number of bytes is when there is a 0x00 (escape),
1358 * a value >0x02 (absolute mode) and then an odd-
1359 * length run. Therefore this is the only place we
1360 * need to worry about it. Everywhere else the
1361 * bytes are always read in pairs. [JAY]
1363 if (escape_code
& 1)
1364 pIn
++; /* Throw away the pad byte. */
1367 } /* switch (escape_code) : Escape sequence */
1368 } /* process either an encoded sequence or an escape sequence */
1370 /* We expect to come here more than once per line. */
1371 } while (line
>= 0); /* Do this until the bitmap is filled */
1374 * Everybody comes here at the end.
1375 * Check how we exited the loop and print a message if it's a bit odd.
1378 if ( (*(pIn
-2) != 0/*escape*/) || (*(pIn
-1)!= RleEnd
) )
1380 TRACE("End-of-bitmap without (strictly) proper escape code. Last two "
1381 "bytes were: %02X %02X.\n", (int)*(pIn
-2),(int)*(pIn
-1));
1386 /***********************************************************************
1387 * X11DRV_DIB_SetImageBits_16
1389 * SetDIBits for a 16-bit deep DIB.
1391 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
1392 DWORD srcwidth
, DWORD dstwidth
, int left
,
1393 DC
*dc
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
1399 /* align to 32 bit */
1400 DWORD linebytes
= (srcwidth
* 2 + 3) & ~3;
1405 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
1406 linebytes
= -linebytes
;
1409 switch ( bmpImage
->depth
)
1412 /* using same format as XImage */
1413 if (rSrc
== bmpImage
->red_mask
&& gSrc
== bmpImage
->green_mask
&& bSrc
== bmpImage
->blue_mask
)
1414 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+= linebytes
)
1415 memcpy ( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2, srcbits
+ left
*2, dstwidth
*2 );
1416 else /* We need to do a conversion from a 565 dib */
1418 LPDWORD dstpixel
, ptr
= (LPDWORD
)(srcbits
+ left
*2);
1420 int div
= dstwidth
% 2;
1422 for (h
= lines
- 1; h
>= 0; h
--) {
1423 dstpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1424 for (x
= 0; x
< dstwidth
/2; x
++) { /* Do 2 pixels at a time */
1426 *dstpixel
++ = ((val
>> 1) & 0x7fe07fe0) | (val
& 0x001f001f); /* Red & Green & Blue */
1428 if (div
!= 0) /* Odd width? */
1429 *dstpixel
= ((*(WORD
*)ptr
>> 1) & 0x7fe0) | (*(WORD
*)ptr
& 0x001f);
1430 ptr
= (LPDWORD
) ((srcbits
+= linebytes
) + left
*2);
1436 /* using same format as XImage */
1437 if (rSrc
== bmpImage
->red_mask
&& gSrc
== bmpImage
->green_mask
&& bSrc
== bmpImage
->blue_mask
)
1438 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+= linebytes
)
1439 memcpy ( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2, srcbits
+ left
*2, dstwidth
*2 );
1440 else /* We need to do a conversion from a 555 dib */
1442 LPDWORD dstpixel
, ptr
= (LPDWORD
)(srcbits
+ left
*2);
1444 int div
= dstwidth
% 2;
1446 for (h
= lines
- 1; h
>= 0; h
--) {
1447 dstpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1448 for (x
= 0; x
< dstwidth
/2; x
++) { /* Do 2 pixels at a time */
1450 *dstpixel
++ = ((val
<< 1) & 0xffc0ffc0) | ((val
>> 4) & 0x00200020) | /* Red & Green */
1451 (val
& 0x001f001f); /* Blue */
1453 if (div
!= 0) /* Odd width? */
1454 *dstpixel
= ((*(WORD
*)ptr
<< 1) & 0xffc0) | ((*(WORD
*)ptr
>> 4) & 0x0020)
1455 | (*(WORD
*)ptr
& 0x001f);
1456 ptr
= (LPDWORD
) ((srcbits
+= linebytes
) + left
*2);
1465 LPWORD ptr
= (LPWORD
)srcbits
+ left
;
1468 /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
1469 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1471 for (h
= lines
- 1; h
>= 0; h
--) {
1472 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1473 for (x
= 0; x
< dstwidth
; x
++) {
1476 *dstpixel
++ = ((val
<< 9) & 0xf80000) | ((val
<< 4) & 0x070000) | /* Red */
1477 ((val
<< 6) & 0x00f800) | ((val
<< 1) & 0x000700) | /* Green */
1478 ((val
<< 3) & 0x0000f8) | ((val
>> 2) & 0x000007); /* Blue */
1480 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1483 /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
1484 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1486 for (h
= lines
- 1; h
>= 0; h
--) {
1487 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1488 for (x
= 0; x
< dstwidth
; x
++) {
1491 *dstpixel
++ = ((val
>> 7) & 0x0000f8) | ((val
>> 12) & 0x000007) | /* Red */
1492 ((val
<< 6) & 0x00f800) | ((val
<< 1) & 0x000700) | /* Green */
1493 ((val
<< 19) & 0xf80000) | ((val
>> 14) & 0x070000); /* Blue */
1495 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1506 LPWORD ptr
= (LPWORD
)srcbits
+ left
;
1510 /* Set color scaling values */
1511 if ( rSrc
== 0x7c00 ) { sc1
= 7; sc2
= 2; } /* 555 dib */
1512 else { sc1
= 8; sc2
= 3; } /* 565 dib */
1514 for (h
= lines
- 1; h
>= 0; h
--) {
1515 for (x
= left
; x
< dstwidth
+left
; x
++) {
1517 XPutPixel( bmpImage
, x
, h
,
1518 X11DRV_PALETTE_ToPhysical(dc
, RGB(((val
& rSrc
) >> sc1
), /* Red */
1519 ((val
& gSrc
) >> sc2
), /* Green */
1520 ((val
& bSrc
) << 3)))); /* Blue */
1522 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
1528 FIXME("16 bit DIB %d bit bitmap\n", bmpImage
->bits_per_pixel
);
1535 /***********************************************************************
1536 * X11DRV_DIB_GetImageBits_16
1538 * GetDIBits for an 16-bit deep DIB.
1540 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*dstbits
,
1541 DWORD dstwidth
, DWORD srcwidth
,
1542 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
1547 /* align to 32 bit */
1548 DWORD linebytes
= (dstwidth
* 2 + 3) & ~3;
1553 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
1554 linebytes
= -linebytes
;
1557 switch ( bmpImage
->depth
)
1560 /* ==== 555 BGR bitmap to 555 BGR dib ==== */
1561 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
1562 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+= linebytes
)
1563 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, srcwidth
*2 );
1565 /* ==== 555 RGB bitmap to 555 BGR dib ==== */
1566 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
1568 LPDWORD srcpixel
, ptr
= (LPDWORD
)dstbits
;
1570 int div
= srcwidth
% 2;
1572 for (h
= lines
- 1; h
>= 0; h
--) {
1573 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1574 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1576 *ptr
++ = ((val
<< 10) & 0xf800f800) | (val
& 0x03e003e0) | /* Red & Green */
1577 ((val
>> 10) & 0x001f001f); /* Blue */
1579 if (div
!= 0) /* Odd width? */
1580 *ptr
= ((*(WORD
*)srcpixel
<< 1) & 0xffc0) | ((*(WORD
*)srcpixel
>> 4) & 0x0020) |
1581 (*(WORD
*)srcpixel
& 0x001f);
1582 ptr
= (LPDWORD
)(dstbits
+= linebytes
);
1585 else goto notsupported
;
1591 LPDWORD srcpixel
, ptr
= (LPDWORD
)dstbits
;
1593 int div
= srcwidth
% 2;
1595 /* ==== 565 BGR bitmap to 555 BGR dib ==== */
1596 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f )
1598 for (h
= lines
- 1; h
>= 0; h
--) {
1599 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1600 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1602 *ptr
++ = ((val
>> 1) & 0x7fe07fe0) | /* Red & Green */
1603 (val
& 0x001f001f); /* Blue */
1605 if (div
!= 0) /* Odd width? */
1606 *ptr
= ((*(WORD
*)srcpixel
>> 1) & 0x7fe0) | (*(WORD
*)srcpixel
& 0x001f);
1607 ptr
= (LPDWORD
) (dstbits
+= linebytes
);
1610 /* ==== 565 RGB bitmap to 555 BGR dib ==== */
1611 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
1613 for (h
= lines
- 1; h
>= 0; h
--) {
1614 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1615 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1617 *ptr
++ = ((val
<< 10) & 0x7c007c00) | ((val
>> 1) & 0x03e003e0) | /* Red & Green */
1618 ((val
>> 11) & 0x001f001f); /* Blue */
1620 if (div
!= 0) /* Odd width? */
1621 *ptr
= ((*(WORD
*)srcpixel
>> 1) & 0x7fe0) | (*(WORD
*)srcpixel
& 0x001f);
1622 ptr
= (LPDWORD
) (dstbits
+= linebytes
);
1625 else goto notsupported
;
1633 LPWORD ptr
= (LPWORD
)dstbits
;
1636 /* ==== 24/32 BGR bitmap to 555 BGR dib ==== */
1637 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1639 for (h
= lines
- 1; h
>= 0; h
--) {
1640 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1641 for (x
= 0; x
< srcwidth
; x
++, ptr
++) {
1643 *ptr
= ((val
>> 9) & 0x7c00) | /* Red */
1644 ((val
>> 6) & 0x03e0) | /* Green */
1645 ((val
>> 3) & 0x001f); /* Blue */
1647 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1650 /* ==== 24/32 RGB bitmap to 555 BGR dib ==== */
1651 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1653 for (h
= lines
- 1; h
>= 0; h
--) {
1654 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1655 for (x
= 0; x
< srcwidth
; x
++, ptr
++) {
1657 *ptr
= ((val
<< 7) & 0x7c00) | /* Red */
1658 ((val
>> 6) & 0x03e0) | /* Green */
1659 ((val
>> 19) & 0x001f); /* Blue */
1661 ptr
= (LPWORD
) (dstbits
+= linebytes
);
1664 else goto notsupported
;
1669 /* ==== monochrome bitmap to 16 BGR dib ==== */
1671 /* ==== 4 colormap bitmap to 16 BGR dib ==== */
1672 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1674 LPWORD ptr
= (LPWORD
)dstbits
;
1677 for (h
= lines
- 1; h
>= 0; h
--) {
1678 for (x
= 0; x
< dstwidth
; x
++) {
1679 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
1680 *ptr
++ = ((val
.peRed
<< 7) & 0x7c00) |
1681 ((val
.peGreen
<< 2) & 0x03e0) |
1682 ((val
.peBlue
>> 3) & 0x001f);
1684 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1687 else goto notsupported
;
1692 /* ==== 8 colormap bitmap to 16 BGR dib ==== */
1693 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1695 LPWORD ptr
= (LPWORD
)dstbits
;
1699 for (h
= lines
- 1; h
>= 0; h
--) {
1700 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1701 for (x
= 0; x
< dstwidth
; x
++) {
1702 val
= srccolors
[(int)*srcpixel
++];
1703 *ptr
++ = ((val
.peRed
<< 7) & 0x7c00) |
1704 ((val
.peGreen
<< 2) & 0x03e0) |
1705 ((val
.peBlue
>> 3) & 0x001f);
1707 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1710 else goto notsupported
;
1718 LPWORD ptr
= (LPWORD
)dstbits
;
1720 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 16 bit DIB\n",
1721 bmpImage
->depth
, (int)bmpImage
->red_mask
,
1722 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1723 for (h
= lines
- 1; h
>= 0; h
--)
1725 for (x
= 0; x
< dstwidth
; x
++, ptr
++)
1727 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
1728 r
= (BYTE
) GetRValue(pixel
);
1729 g
= (BYTE
) GetGValue(pixel
);
1730 b
= (BYTE
) GetBValue(pixel
);
1731 *ptr
= ( ((r
<< 7) & 0x7c00) | ((g
<< 2) & 0x03e0) | ((b
>> 3) & 0x001f) );
1733 ptr
= (LPWORD
) (dstbits
+= linebytes
);
1741 /***********************************************************************
1742 * X11DRV_DIB_SetImageBits_24
1744 * SetDIBits for a 24-bit deep DIB.
1746 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
1747 DWORD srcwidth
, DWORD dstwidth
, int left
,
1748 DC
*dc
, XImage
*bmpImage
)
1753 /* align to 32 bit */
1754 DWORD linebytes
= (srcwidth
* 3 + 3) & ~3;
1759 srcbits
= srcbits
+ linebytes
* (lines
- 1);
1760 linebytes
= -linebytes
;
1763 switch ( bmpImage
->depth
)
1767 if (bmpImage
->bits_per_pixel
== 24) {
1768 int dstlinebytes
= linebytes
;
1770 BYTE
*ptr
= (BYTE
*)(srcbits
+left
*3);
1772 if (dstlinebytes
< 0 ) dstlinebytes
= -dstlinebytes
;
1773 dstpixel
= bmpImage
->data
+ lines
*dstlinebytes
+ left
*3;
1774 for(h
= lines
; h
-- ; ) {
1775 dstpixel
-=dstlinebytes
;
1776 memcpy(dstpixel
,ptr
,dstwidth
*3);
1784 if( bmpImage
->blue_mask
== 0xff && bmpImage
->red_mask
== 0xff0000 ) /* packed BGR to unpacked BGR */
1786 DWORD
*dstpixel
, val
, buf
;
1787 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1789 int div
= dstwidth
% 4;
1792 for(h
= lines
- 1; h
>= 0; h
--)
1794 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
*bmpImage
->bytes_per_line
+ left
*4);
1796 for (x
= 0; x
< dstwidth
/4; x
++) { /* do 3 dwords source, 4 dwords dest at a time */
1798 *dstpixel
++ = buf
&0x00ffffff; /* b1, g1, r1 */
1799 val
= (buf
>> 24); /* b2 */
1801 *dstpixel
++ = (val
| (buf
<<8)) &0x00ffffff; /* g2, r2 */
1802 val
= (buf
>> 16); /* b3, g3 */
1804 *dstpixel
++ = (val
| (buf
<<16)) &0x00ffffff; /* r3 */
1805 *dstpixel
++ = (buf
>> 8); /* b4, g4, r4 */
1807 for ( divk
=div
, bits
=(BYTE
*)ptr
; divk
>0; divk
--, bits
+=3 ) /* do remainder */
1809 *dstpixel
++ = *(DWORD
*)bits
& 0x00ffffff; /* b, g, r */
1811 ptr
= (DWORD
*)((srcbits
+=linebytes
)+left
*3);
1814 else if( bmpImage
->blue_mask
== 0xff0000 && bmpImage
->red_mask
== 0xff ) /* packed BGR to unpacked RGB */
1816 DWORD
*dstpixel
, val
, buf
;
1817 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1819 int div
= dstwidth
% 4;
1822 for(h
= lines
- 1; h
>= 0; h
--)
1824 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
*bmpImage
->bytes_per_line
+ left
*4);
1826 for (x
= 0; x
< dstwidth
/4; x
++) { /* do 3 dwords source, 4 dwords dest at a time */
1828 *dstpixel
++ = ((buf
&0xff)<<16) | (buf
&0xff00) | ((buf
&0xff0000)>>16); /* b1, g1, r1 */
1829 val
= ((buf
&0xff000000)>>8); /* b2 */
1831 *dstpixel
++ = val
| ((buf
&0xff)<<8) | ((buf
&0xff00)>>8); /* g2, r2 */
1832 val
= (buf
&0xff0000) | ((buf
&0xff000000)>>16); /* b3, g3 */
1834 *dstpixel
++ = val
| (buf
&0xff); /* r3 */
1835 *dstpixel
++ = ((buf
&0xff00)<<8) | ((buf
&0xff0000)>>8) | (buf
>>24); /* b4, g4, r4 */
1837 for ( divk
=div
, bits
=(BYTE
*)ptr
; divk
>0; divk
--, bits
+=3 ) /* do remainder */
1839 buf
= *(DWORD
*)bits
;
1840 *dstpixel
++ = ((buf
&0xff)<<16) | (buf
&0xff00) | ((buf
&0xff0000)>>16); /* b, g, r */
1842 ptr
= (DWORD
*)((srcbits
+=linebytes
)+left
*3);
1852 if( bmpImage
->blue_mask
== 0x7c00 && bmpImage
->red_mask
== 0x1f ) /* BGR888 to RGB555 */
1854 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1857 int div
= dstwidth
% 4;
1860 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1861 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1862 for (x
= 0; x
< dstwidth
/4; x
++) {
1863 *dstpixel
++ = (WORD
)((((val
= *ptr
++) << 7) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 19) & 0x1f));
1864 *dstpixel
++ = (WORD
)(((val
>> 17) & 0x7c00) | (((val
= *ptr
++) << 2) & 0x03e0) | ((val
>> 11) & 0x1f));
1865 *dstpixel
++ = (WORD
)(((val
>> 9) & 0x07c00) | ((val
>> 22) & 0x03e0) | (((val
= *ptr
++) >> 3) & 0x1f));
1866 *dstpixel
++ = (WORD
)(((val
>> 1) & 0x07c00) | ((val
>> 14) & 0x03e0) | ((val
>> 27) & 0x1f));
1868 for (bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth not divisible by 4? */
1869 *dstpixel
++ = (((WORD
)bits
[0] << 7) & 0x07c00) |
1870 (((WORD
)bits
[1] << 2) & 0x03e0) |
1871 (((WORD
)bits
[2] >> 3) & 0x001f);
1872 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1875 else if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0x7c00 ) /* BGR888 to BGR555 */
1877 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1880 int div
= dstwidth
% 4;
1883 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1884 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1885 for (x
= 0; x
< dstwidth
/4; x
++) {
1886 *dstpixel
++ = (WORD
)((((val
= *ptr
++) >> 3) & 0x1f) | ((val
>> 6) & 0x03e0) | ((val
>> 9) & 0x7c00));
1887 *dstpixel
++ = (WORD
)(((val
>> 27) & 0x1f) | (((val
= *ptr
++) << 2) & 0x03e0) | ((val
>> 1) & 0x7c00));
1888 *dstpixel
++ = (WORD
)(((val
>> 19) & 0x1f) | ((val
>> 22) & 0x03e0) | (((val
= *ptr
++) << 7) & 0x7c00));
1889 *dstpixel
++ = (WORD
)(((val
>> 11) & 0x1f) | ((val
>> 14) & 0x03e0) | ((val
>> 17) & 0x7c00));
1891 for (bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth not divisible by 4? */
1892 *dstpixel
++ = (((WORD
)bits
[2] << 7) & 0x07c00) |
1893 (((WORD
)bits
[1] << 2) & 0x03e0) |
1894 (((WORD
)bits
[0] >> 3) & 0x001f);
1895 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1905 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1908 int div
= dstwidth
% 4;
1911 if( bmpImage
->blue_mask
== 0x001f && bmpImage
->red_mask
== 0xf800 ) /* BGR888 to BGR565 */
1913 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1914 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1915 for (x
= 0; x
< dstwidth
/4; x
++) {
1916 *dstpixel
++ = (WORD
)((((val
= *ptr
++) >> 3) & 0x1f) | ((val
>> 5) & 0x07e0) | ((val
>> 8) & 0xf800));
1917 *dstpixel
++ = (WORD
)(((val
>> 27) & 0x1f) | (((val
= *ptr
++) << 3) & 0x07e0) | ((val
) & 0xf800));
1918 *dstpixel
++ = (WORD
)(((val
>> 19) & 0x1f) | ((val
>> 21) & 0x07e0) | (((val
= *ptr
++) << 8) & 0xf800));
1919 *dstpixel
++ = (WORD
)(((val
>> 11) & 0x1f) | ((val
>> 13) & 0x07e0) | ((val
>> 16) & 0xf800));
1921 for ( bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth is not divisible by 4? */
1922 *dstpixel
++ = (((WORD
)bits
[2] << 8) & 0xf800) |
1923 (((WORD
)bits
[1] << 3) & 0x07e0) |
1924 (((WORD
)bits
[0] >> 3) & 0x001f);
1925 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1928 else if( bmpImage
->blue_mask
== 0xf800 && bmpImage
->red_mask
== 0x001f ) /* BGR888 to RGB565 */
1930 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1931 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1932 for (x
= 0; x
< dstwidth
/4; x
++) {
1933 *dstpixel
++ = (WORD
)((((val
= *ptr
++) << 8) & 0xf800) | ((val
>> 5) & 0x07e0) | ((val
>> 19) & 0x1f));
1934 *dstpixel
++ = (WORD
)(((val
>> 16) & 0xf800) | (((val
= *ptr
++) << 3) & 0x07e0) | ((val
>> 11) & 0x1f));
1935 *dstpixel
++ = (WORD
)(((val
>> 8) & 0xf800) | ((val
>> 21) & 0x07e0) | (((val
= *ptr
++) >> 3) & 0x1f));
1936 *dstpixel
++ = (WORD
)((val
& 0xf800) | ((val
>> 13) & 0x07e0) | ((val
>> 27) & 0x1f));
1938 for ( bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth is not divisible by 4? */
1939 *dstpixel
++ = (((WORD
)bits
[0] << 8) & 0xf800) |
1940 (((WORD
)bits
[1] << 3) & 0x07e0) |
1941 (((WORD
)bits
[2] >> 3) & 0x001f);
1942 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1954 LPBYTE bits
= (LPBYTE
)srcbits
+ left
*3;
1956 for (h
= lines
- 1; h
>= 0; h
--) {
1957 for (x
= left
; x
< dstwidth
+left
; x
++, bits
+=3)
1958 XPutPixel( bmpImage
, x
, h
,
1959 X11DRV_PALETTE_ToPhysical(dc
, RGB(bits
[2], bits
[1], bits
[0])));
1960 bits
= (LPBYTE
)(srcbits
+= linebytes
) + left
* 3;
1967 FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
1968 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
1969 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1975 /***********************************************************************
1976 * X11DRV_DIB_GetImageBits_24
1978 * GetDIBits for an 24-bit deep DIB.
1980 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*dstbits
,
1981 DWORD dstwidth
, DWORD srcwidth
,
1982 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
1987 /* align to 32 bit */
1988 DWORD linebytes
= (dstwidth
* 3 + 3) & ~3;
1993 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
1994 linebytes
= -linebytes
;
1997 switch ( bmpImage
->depth
)
2001 if (bmpImage
->bits_per_pixel
== 24) {
2002 int tocopy
= linebytes
;
2004 BYTE
*ptr
= (LPBYTE
)dstbits
;
2006 if (tocopy
< 0 ) tocopy
= -tocopy
;
2007 srcpixel
= bmpImage
->data
+ lines
*tocopy
;
2008 for(h
= lines
; h
-- ; ) {
2010 memcpy(ptr
,srcpixel
,tocopy
);
2011 ptr
= (LPBYTE
)(dstbits
+=linebytes
);
2018 DWORD
*srcpixel
, buf
;
2020 DWORD
*ptr
=(DWORD
*)dstbits
;
2021 int quotient
= dstwidth
/ 4;
2022 int remainder
= dstwidth
% 4;
2025 /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
2026 if( bmpImage
->blue_mask
== 0xff && bmpImage
->red_mask
== 0xff0000 )
2028 for(h
= lines
- 1; h
>= 0; h
--)
2030 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2032 for (x
= 0; x
< quotient
; x
++) { /* do 4 dwords source, 3 dwords dest at a time */
2033 buf
= ((*srcpixel
++)&0x00ffffff); /* b1, g1, r1*/
2034 *ptr
++ = buf
| ((*srcpixel
)<<24); /* b2 */
2035 buf
= ((*srcpixel
++>>8)&0x0000ffff); /* g2, r2 */
2036 *ptr
++ = buf
| ((*srcpixel
)<<16); /* b3, g3 */
2037 buf
= ((*srcpixel
++>>16)&0x000000ff); /* r3 */
2038 *ptr
++ = buf
| ((*srcpixel
++)<<8); /* b4, g4, r4 */
2040 for ( remk
=remainder
, bits
=(BYTE
*)ptr
; remk
>0; remk
--, bits
+=3 ) /* do remainder */
2043 *(WORD
*)bits
= buf
; /* b, g */
2044 *(bits
+2) = buf
>>16; /* r */
2046 ptr
= (DWORD
*)(dstbits
+=linebytes
);
2050 /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
2051 else if( bmpImage
->blue_mask
== 0xff0000 && bmpImage
->red_mask
== 0xff )
2053 for(h
= lines
- 1; h
>= 0; h
--)
2055 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2057 for (x
= 0; x
< quotient
; x
++) { /* do 4 dwords source, 3 dwords dest at a time */
2059 val
= ((buf
&0xff0000)>>16) | (buf
&0xff00) | ((buf
&0xff)<<16); /* b1, g1, r1 */
2061 *ptr
++ = val
| ((buf
&0xff0000)<<8); /* b2 */
2062 val
= ((buf
&0xff00)>>8) | ((buf
&0xff)<<8); /* g2, r2 */
2064 *ptr
++ = val
| (buf
&0xff0000) | ((buf
&0xff00)<<16); /* b3, g3 */
2065 val
= (buf
&0xff); /* r3 */
2067 *ptr
++ = val
| ((buf
&0xff0000)>>8) | ((buf
&0xff00)<<8) | (buf
<<24); /* b4, g4, r4 */
2069 for ( remk
=remainder
, bits
=(BYTE
*)ptr
; remk
>0; remk
--, bits
+=3 ) /* do remainder */
2072 *(WORD
*)bits
= (buf
&0xff00) | ((buf
&0xff0000)>>16) ; /* b, g */
2073 *(bits
+2) = buf
; /* r */
2075 ptr
= (DWORD
*)(dstbits
+=linebytes
);
2078 else goto notsupported
;
2085 LPBYTE bits
= dstbits
;
2088 /* ==== 555 BGR bitmap to 24 BGR dib ==== */
2089 if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0x7c00 )
2091 for (h
= lines
- 1; h
>= 0; h
--) {
2092 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2093 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2095 bits
[2] = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2096 bits
[1] = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07)); /*Green*/
2097 bits
[0] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2099 bits
= (dstbits
+= linebytes
);
2102 /* ==== 555 RGB bitmap to 24 RGB dib==== */
2103 else if( bmpImage
->blue_mask
== 0x7c00 && bmpImage
->red_mask
== 0x1f )
2105 for (h
= lines
- 1; h
>= 0; h
--) {
2106 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2107 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2109 bits
[0] = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2110 bits
[1] = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07)); /*Green*/
2111 bits
[2] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2113 bits
= (dstbits
+= linebytes
);
2116 else goto notsupported
;
2123 LPBYTE bits
= dstbits
;
2126 /* ==== 565 BGR bitmap to 24 BGR dib ==== */
2127 if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0xf800 )
2129 for (h
= lines
- 1; h
>= 0; h
--) {
2130 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2131 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2133 bits
[2] = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2134 bits
[1] = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2135 bits
[0] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2137 bits
= (dstbits
+= linebytes
);
2140 /* ==== 565 RGB bitmap to 24 BGR dib ==== */
2141 else if( bmpImage
->blue_mask
== 0xf800 && bmpImage
->red_mask
== 0x1f )
2143 for (h
= lines
- 1; h
>= 0; h
--) {
2144 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2145 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2147 bits
[0] = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2148 bits
[1] = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2149 bits
[2] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2151 bits
= (dstbits
+= linebytes
);
2154 else goto notsupported
;
2159 /* ==== monochrome bitmap to 24 BGR dib ==== */
2161 /* ==== 4 colormap bitmap to 24 BGR dib ==== */
2162 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2164 LPBYTE bits
= dstbits
;
2167 for (h
= lines
- 1; h
>= 0; h
--) {
2168 for (x
= 0; x
< dstwidth
; x
++) {
2169 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
2170 *bits
++ = val
.peBlue
;
2171 *bits
++ = val
.peGreen
;
2172 *bits
++ = val
.peRed
;
2174 bits
= (dstbits
+= linebytes
);
2177 else goto notsupported
;
2182 /* ==== 8 colormap bitmap to 24 BGR dib ==== */
2183 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
== 0 && srccolors
)
2186 LPBYTE bits
= dstbits
;
2189 for (h
= lines
- 1; h
>= 0; h
--) {
2190 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
2191 for (x
= 0; x
< dstwidth
; x
++ ) {
2192 val
= srccolors
[(int)*srcpixel
++];
2193 *bits
++ = val
.peBlue
; /*Blue*/
2194 *bits
++ = val
.peGreen
; /*Green*/
2195 *bits
++ = val
.peRed
; /*Red*/
2197 bits
= (dstbits
+= linebytes
);
2200 else goto notsupported
;
2207 LPBYTE bits
= dstbits
;
2209 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
2210 bmpImage
->depth
, (int)bmpImage
->red_mask
,
2211 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2212 for (h
= lines
- 1; h
>= 0; h
--)
2214 for (x
= 0; x
< dstwidth
; x
++, bits
+= 3)
2216 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
2217 bits
[0] = GetBValue(pixel
);
2218 bits
[1] = GetGValue(pixel
);
2219 bits
[2] = GetRValue(pixel
);
2221 bits
= (dstbits
+= linebytes
);
2229 /***********************************************************************
2230 * X11DRV_DIB_SetImageBits_32
2232 * SetDIBits for a 32-bit deep DIB.
2234 static void X11DRV_DIB_SetImageBits_32( int lines
, const BYTE
*srcbits
,
2235 DWORD srcwidth
, DWORD dstwidth
, int left
,
2236 DC
*dc
, XImage
*bmpImage
)
2241 DWORD linebytes
= (srcwidth
* 4);
2246 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
2247 linebytes
= -linebytes
;
2250 ptr
= (DWORD
*) srcbits
+ left
;
2252 switch ( bmpImage
->depth
)
2255 /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
2256 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff) {
2257 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+=linebytes
) {
2258 memcpy( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
, srcbits
+ left
*4, dstwidth
*4 );
2262 /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
2263 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
2267 for (h
= lines
- 1; h
>= 0; h
--) {
2268 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2269 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2270 *dstpixel
++ = ((*ptr
<< 16) & 0xff0000) | (*ptr
& 0xff00) | ((*ptr
>> 16) & 0xff);
2272 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2275 else goto notsupported
;
2280 /* ==== 32 BGR dib to 24 (888) BGR bitmap ==== */
2281 /* we need to check that source mask matches destination */
2285 ptr
= (DWORD
*) srcbits
+ left
;
2286 bptr
= bmpImage
->data
;
2288 for (h
= lines
- 1; h
>= 0; h
--) {
2289 for (x
= 0; x
< dstwidth
; x
++) {
2290 /* *ptr is a 32bit value */
2291 /* bptr points to first of 3 bytes */
2292 *bptr
++ = (*ptr
>> 16) & 0xff;
2293 *bptr
++ = (*ptr
>> 8) & 0xff;
2294 *bptr
++ = (*ptr
) & 0xff;
2297 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2303 /* ==== 32 BGR dib to 555 BGR bitmap ==== */
2304 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f) {
2307 for (h
= lines
- 1; h
>= 0; h
--) {
2308 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2309 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2310 *dstpixel
++ = (WORD
) (((*ptr
>> 9) & 0x7c00) | ((*ptr
>> 6) & 0x03e0) | ((*ptr
>> 3) & 0x001f));
2312 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2315 /* ==== 32 BGR dib to 555 RGB bitmap ==== */
2316 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
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
<< 7) & 0x7c00) | ((*ptr
>> 6) & 0x03e0) | ((*ptr
>> 19) & 0x001f));
2325 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2328 else goto notsupported
;
2333 /* ==== 32 BGR dib to 565 BGR bitmap ==== */
2334 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2338 for (h
= lines
- 1; h
>= 0; h
--) {
2339 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2340 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2341 *dstpixel
++ = (WORD
) (((*ptr
>> 8) & 0xf800) | ((*ptr
>> 5) & 0x07e0) | ((*ptr
>> 3) & 0x001f));
2343 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2346 /* ==== 32 BGR dib to 565 RGB bitmap ==== */
2347 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
2351 for (h
= lines
- 1; h
>= 0; h
--) {
2352 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2353 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2354 *dstpixel
++ = (WORD
) (((*ptr
<< 8) & 0xf800) | ((*ptr
>> 5) & 0x07e0) | ((*ptr
>> 19) & 0x001f));
2356 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2359 else goto notsupported
;
2367 LPBYTE bits
= (LPBYTE
)srcbits
+ left
*4;
2369 for (h
= lines
- 1; h
>= 0; h
--) {
2370 for (x
= left
; x
< dstwidth
+left
; x
++, bits
+= 4)
2371 XPutPixel( bmpImage
, x
, h
,
2372 X11DRV_PALETTE_ToPhysical(dc
, RGB( bits
[2], bits
[1], *bits
)));
2373 bits
= (LPBYTE
)(srcbits
+= linebytes
) + left
* 4;
2380 FIXME("32 bit DIB %d bit bitmap\n", bmpImage
->bits_per_pixel
);
2386 /***********************************************************************
2387 * X11DRV_DIB_GetImageBits_32
2389 * GetDIBits for an 32-bit deep DIB.
2391 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*dstbits
,
2392 DWORD dstwidth
, DWORD srcwidth
,
2393 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
2399 /* align to 32 bit */
2400 DWORD linebytes
= (srcwidth
* 4);
2401 DWORD copybytes
= linebytes
;
2406 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2407 linebytes
= -linebytes
;
2412 switch ( bmpImage
->depth
)
2415 /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
2416 if ( bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff )
2417 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+=linebytes
)
2418 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, copybytes
);
2420 /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
2421 else if ( bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000 )
2425 for (h
= lines
- 1; h
>= 0; h
--) {
2426 srcbits
= bmpImage
->data
+ h
* bmpImage
->bytes_per_line
;
2427 for (x
= 0; x
< dstwidth
; x
++, bits
+=4, srcbits
+=2) {
2428 *(bits
+ 2) = *srcbits
++;
2429 *(bits
+ 1) = *srcbits
++;
2432 bits
= (dstbits
+= linebytes
);
2435 else goto notsupported
;
2439 /* ==== 24 BGR bitmap to 32 (0888) BGR dib ==== */
2440 /* we need to check that source mask matches destination */
2446 srcpixel
= (DWORD
*) dstbits
;
2447 bptr
= bmpImage
->data
;
2449 for (h
= lines
- 1; h
>= 0; h
--) {
2450 for (x
= 0; x
< dstwidth
; x
++) {
2451 /* *srcpixel is a 32bit value */
2452 /* bptr points to first of 3 bytes */
2454 srcdata
= srcdata
<< 8 | *bptr
++;
2455 srcdata
= srcdata
<< 8 | *bptr
++;
2456 srcdata
= srcdata
<< 8 | *bptr
++;
2458 *srcpixel
++ = srcdata
;
2460 srcpixel
= (DWORD
*) (dstbits
+= linebytes
);
2470 /* ==== 555 BGR bitmap to 32 BGR dib ==== */
2471 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
2473 for (h
= lines
- 1; h
>= 0; h
--) {
2474 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2475 for (x
= 0; x
< dstwidth
; x
++, bits
+=2) {
2477 *bits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Blue*/
2478 *bits
++ = (BYTE
)(((val
>> 2) & 0xfc) | ((val
>> 8) & 0x03)); /*Green*/
2479 *bits
= (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2481 bits
= (dstbits
+= linebytes
);
2484 /* ==== 555 RGB bitmap to 32 BGR dib ==== */
2485 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
2487 for (h
= lines
- 1; h
>= 0; h
--) {
2488 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2489 for (x
= 0; x
< dstwidth
; x
++, bits
+=2) {
2491 *bits
++ = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07));/*Blue*/
2492 *bits
++ = (BYTE
)(((val
>> 2) & 0xfc) | ((val
>> 8) & 0x03)); /*Green*/
2493 *bits
= (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Red*/
2495 bits
= (dstbits
+= linebytes
);
2498 else goto notsupported
;
2507 /* ==== 565 BGR bitmap to 32 BGR dib ==== */
2508 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2510 for (h
= lines
- 1; h
>= 0; h
--) {
2511 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2512 for (x
= 0; x
< srcwidth
; x
++, bits
+=2) {
2514 *bits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Blue*/
2515 *bits
++ = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2516 *bits
= (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2518 bits
= (dstbits
+= linebytes
);
2521 /* ==== 565 RGB bitmap to 32 BGR dib ==== */
2522 else if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2524 for (h
= lines
- 1; h
>= 0; h
--) {
2525 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2526 for (x
= 0; x
< srcwidth
; x
++, bits
+=2) {
2528 *bits
++ = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07));/*Blue*/
2529 *bits
++ = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2530 *bits
= (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Red*/
2532 bits
= (dstbits
+= linebytes
);
2535 else goto notsupported
;
2540 /* ==== monochrome bitmap to 32 BGR dib ==== */
2542 /* ==== 4 colormap bitmap to 32 BGR dib ==== */
2543 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2547 for (h
= lines
- 1; h
>= 0; h
--) {
2548 for (x
= 0; x
< dstwidth
; x
++) {
2549 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
2550 *bits
++ = val
.peBlue
;
2551 *bits
++ = val
.peGreen
;
2552 *bits
++ = val
.peRed
;
2555 bits
= (dstbits
+= linebytes
);
2558 else goto notsupported
;
2563 /* ==== 8 colormap bitmap to 32 BGR dib ==== */
2564 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2569 for (h
= lines
- 1; h
>= 0; h
--) {
2570 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
2571 for (x
= 0; x
< dstwidth
; x
++) {
2572 val
= srccolors
[(int)*srcpixel
++];
2573 *bits
++ = val
.peBlue
; /*Blue*/
2574 *bits
++ = val
.peGreen
; /*Green*/
2575 *bits
++ = val
.peRed
; /*Red*/
2578 bits
= (dstbits
+= linebytes
);
2581 else goto notsupported
;
2586 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
2587 bmpImage
->depth
, (int)bmpImage
->red_mask
,
2588 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2589 for (h
= lines
- 1; h
>= 0; h
--)
2591 for (x
= 0; x
< dstwidth
; x
++, bits
+= 4)
2593 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
2594 bits
[0] = GetBValue(pixel
);
2595 bits
[1] = GetGValue(pixel
);
2596 bits
[2] = GetRValue(pixel
);
2598 bits
= (dstbits
+= linebytes
);
2604 /***********************************************************************
2605 * X11DRV_DIB_SetImageBits
2607 * Transfer the bits to an X image.
2608 * Helper function for SetDIBits() and SetDIBitsToDevice().
2609 * The Xlib critical section must be entered before calling this function.
2611 int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
2613 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
2617 bmpImage
= descr
->image
;
2619 bmpImage
= XCreateImage( display
, X11DRV_GetVisual(), descr
->depth
, ZPixmap
, 0, NULL
,
2620 descr
->infoWidth
, lines
, 32, 0 );
2621 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
2622 if(bmpImage
->data
== NULL
) {
2623 ERR("Out of memory!\n");
2624 XDestroyImage( bmpImage
);
2629 /* Transfer the pixels */
2630 switch(descr
->infoBpp
)
2633 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
2634 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
2638 if (descr
->compression
) {
2639 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2640 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2641 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2643 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
2644 descr
->infoWidth
, descr
->width
,
2645 descr
->xSrc
, (int *)(descr
->colorMap
),
2648 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
2649 descr
->infoWidth
, descr
->width
,
2650 descr
->xSrc
, (int*)(descr
->colorMap
),
2654 if (descr
->compression
) {
2655 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2656 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2657 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2658 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
2659 descr
->infoWidth
, descr
->width
,
2660 descr
->xSrc
, (int *)(descr
->colorMap
),
2663 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
2664 descr
->infoWidth
, descr
->width
,
2665 descr
->xSrc
, (int *)(descr
->colorMap
),
2670 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
2671 descr
->infoWidth
, descr
->width
,
2672 descr
->xSrc
, descr
->dc
,
2673 descr
->rMask
, descr
->gMask
, descr
->bMask
,
2677 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
2678 descr
->infoWidth
, descr
->width
,
2679 descr
->xSrc
, descr
->dc
, bmpImage
);
2682 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
2683 descr
->infoWidth
, descr
->width
,
2684 descr
->xSrc
, descr
->dc
,
2688 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
2694 XShmPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
2695 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2696 descr
->width
, descr
->height
, FALSE
);
2697 XSync( display
, 0 );
2700 XPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
2701 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2702 descr
->width
, descr
->height
);
2704 if (!descr
->image
) XDestroyImage( bmpImage
);
2708 /***********************************************************************
2709 * X11DRV_DIB_GetImageBits
2711 * Transfer the bits from an X image.
2712 * The Xlib critical section must be entered before calling this function.
2714 int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
2716 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
2720 bmpImage
= descr
->image
;
2722 bmpImage
= XCreateImage( display
, X11DRV_GetVisual(), descr
->depth
, ZPixmap
, 0, NULL
,
2723 descr
->infoWidth
, lines
, 32, 0 );
2724 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
2725 if(bmpImage
->data
== NULL
) {
2726 ERR("Out of memory!\n");
2727 XDestroyImage( bmpImage
);
2731 XGetSubImage( display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
,
2732 descr
->width
, lines
, AllPlanes
, ZPixmap
,
2733 bmpImage
, descr
->xDest
, descr
->yDest
);
2735 /* Transfer the pixels */
2736 switch(descr
->infoBpp
)
2739 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
2740 descr
->infoWidth
, descr
->width
,
2741 descr
->colorMap
, descr
->palentry
,
2746 if (descr
->compression
)
2747 FIXME("Compression not yet supported!\n");
2749 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
2750 descr
->infoWidth
, descr
->width
,
2751 descr
->colorMap
, descr
->palentry
,
2756 if (descr
->compression
)
2757 FIXME("Compression not yet supported!\n");
2759 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
2760 descr
->infoWidth
, descr
->width
,
2761 descr
->colorMap
, descr
->palentry
,
2766 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
2767 descr
->infoWidth
,descr
->width
,
2768 descr
->palentry
, bmpImage
);
2772 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
2773 descr
->infoWidth
,descr
->width
,
2774 descr
->palentry
, bmpImage
);
2778 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
2779 descr
->infoWidth
, descr
->width
,
2780 descr
->palentry
, bmpImage
);
2784 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
2788 if (!descr
->image
) XDestroyImage( bmpImage
);
2792 /*************************************************************************
2793 * X11DRV_SetDIBitsToDevice
2796 INT
X11DRV_SetDIBitsToDevice( DC
*dc
, INT xDest
, INT yDest
, DWORD cx
,
2797 DWORD cy
, INT xSrc
, INT ySrc
,
2798 UINT startscan
, UINT lines
, LPCVOID bits
,
2799 const BITMAPINFO
*info
, UINT coloruse
)
2801 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2802 DWORD width
, oldcy
= cy
;
2804 int height
, tmpheight
;
2805 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
2808 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
2809 &descr
.infoBpp
, &descr
.compression
) == -1)
2812 if (height
< 0) height
= -height
;
2813 if (!lines
|| (startscan
>= height
)) return 0;
2814 if (startscan
+ lines
> height
) lines
= height
- startscan
;
2815 if (ySrc
< startscan
) ySrc
= startscan
;
2816 else if (ySrc
>= startscan
+ lines
) return 0;
2817 if (xSrc
>= width
) return 0;
2818 if (ySrc
+ cy
>= startscan
+ lines
) cy
= startscan
+ lines
- ySrc
;
2819 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
2820 if (!cx
|| !cy
) return 0;
2822 X11DRV_SetupGCForText( dc
); /* To have the correct colors */
2823 TSXSetFunction(display
, physDev
->gc
, X11DRV_XROPfunction
[dc
->ROPmode
-1]);
2825 switch (descr
.infoBpp
)
2830 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
2831 coloruse
== DIB_PAL_COLORS
? dc
: NULL
, coloruse
,
2832 dc
->bitsPerPixel
, info
, &descr
.nColorMap
);
2833 if (!descr
.colorMap
) return 0;
2834 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2838 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2839 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2840 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2845 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2850 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2851 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2852 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2860 descr
.palentry
= NULL
;
2861 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
2862 descr
.infoWidth
= width
;
2863 descr
.depth
= dc
->bitsPerPixel
;
2864 descr
.drawable
= physDev
->drawable
;
2865 descr
.gc
= physDev
->gc
;
2867 descr
.ySrc
= tmpheight
>= 0 ? lines
-(ySrc
-startscan
)-cy
+(oldcy
-cy
)
2869 descr
.xDest
= dc
->DCOrgX
+ XLPTODP( dc
, xDest
);
2870 descr
.yDest
= dc
->DCOrgY
+ YLPTODP( dc
, yDest
) +
2871 (tmpheight
>= 0 ? oldcy
-cy
: 0);
2874 descr
.useShm
= FALSE
;
2876 EnterCriticalSection( &X11DRV_CritSection
);
2877 result
= CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
2878 LeaveCriticalSection( &X11DRV_CritSection
);
2880 if (descr
.infoBpp
<= 8)
2881 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
2885 /***********************************************************************
2886 * X11DRV_DIB_SetDIBits
2888 INT
X11DRV_DIB_SetDIBits(
2889 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
2890 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
,
2891 UINT coloruse
, HBITMAP hbitmap
)
2893 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2894 int height
, tmpheight
;
2899 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
2900 &descr
.infoBpp
, &descr
.compression
) == -1)
2904 if (height
< 0) height
= -height
;
2905 if (!lines
|| (startscan
>= height
))
2908 if (startscan
+ lines
> height
) lines
= height
- startscan
;
2910 switch (descr
.infoBpp
)
2915 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
2916 coloruse
== DIB_PAL_COLORS
? descr
.dc
: NULL
, coloruse
,
2917 bmp
->bitmap
.bmBitsPixel
,
2918 info
, &descr
.nColorMap
);
2919 if (!descr
.colorMap
) return 0;
2920 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2924 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2925 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2926 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2931 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2936 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2937 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2938 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2946 if(!bmp
->physBitmap
)
2947 X11DRV_CreateBitmap(hbitmap
);
2951 descr
.palentry
= NULL
;
2952 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
2953 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
2954 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
2955 descr
.gc
= BITMAP_GC(bmp
);
2959 descr
.yDest
= height
- startscan
- lines
;
2960 descr
.width
= bmp
->bitmap
.bmWidth
;
2961 descr
.height
= lines
;
2962 descr
.useShm
= FALSE
;
2964 EnterCriticalSection( &X11DRV_CritSection
);
2965 result
= CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
2966 LeaveCriticalSection( &X11DRV_CritSection
);
2968 if (descr
.colorMap
) HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
2973 /***********************************************************************
2974 * X11DRV_DIB_GetDIBits
2976 INT
X11DRV_DIB_GetDIBits(
2977 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
2978 UINT lines
, LPVOID bits
, BITMAPINFO
*info
,
2979 UINT coloruse
, HBITMAP hbitmap
)
2981 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
2982 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2983 PALETTEOBJ
* palette
;
2985 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
2986 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
2987 (int)info
->bmiHeader
.biWidth
, (int)info
->bmiHeader
.biHeight
,
2990 if (!(palette
= (PALETTEOBJ
*)GDI_GetObjPtr( dc
->hPalette
, PALETTE_MAGIC
)))
2993 if( lines
> info
->bmiHeader
.biHeight
) lines
= info
->bmiHeader
.biHeight
;
2994 /* Top-down images have a negative biHeight, the scanlines of theses images
2995 * were inverted in X11DRV_DIB_GetImageBits_xx
2996 * To prevent this we simply change the sign of lines
2997 * (the number of scan lines to copy).
2998 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3000 if( info
->bmiHeader
.biHeight
< 0 && lines
> 0) lines
= -lines
;
3002 if( startscan
>= bmp
->bitmap
.bmHeight
)
3008 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &descr
.lines
,
3009 &descr
.infoBpp
, &descr
.compression
) == -1)
3015 switch (descr
.infoBpp
)
3021 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3025 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
3026 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
3027 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
3031 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
3032 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
3033 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
3038 if(!bmp
->physBitmap
)
3039 X11DRV_CreateBitmap(hbitmap
);
3043 descr
.palentry
= palette
->logpalette
.palPalEntry
;
3046 descr
.lines
= lines
;
3047 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3048 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
3049 descr
.gc
= BITMAP_GC(bmp
);
3050 descr
.width
= bmp
->bitmap
.bmWidth
;
3051 descr
.height
= bmp
->bitmap
.bmHeight
;
3052 descr
.colorMap
= info
->bmiColors
;
3057 if (descr
.lines
> 0)
3059 descr
.ySrc
= (descr
.height
-1) - (startscan
+ (lines
-1));
3063 descr
.ySrc
= startscan
;
3067 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
3069 descr
.useShm
= FALSE
;
3071 EnterCriticalSection( &X11DRV_CritSection
);
3073 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits
, &descr
);
3075 LeaveCriticalSection( &X11DRV_CritSection
);
3077 if(info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
3078 info
->bmiHeader
.biSizeImage
= DIB_GetDIBImageBytes(
3079 info
->bmiHeader
.biWidth
,
3080 info
->bmiHeader
.biHeight
,
3081 info
->bmiHeader
.biBitCount
);
3083 info
->bmiHeader
.biCompression
= 0;
3086 GDI_ReleaseObj( dc
->hPalette
);
3091 /***********************************************************************
3092 * DIB_DoProtectDIBSection
3094 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
3096 DIBSECTION
*dib
= bmp
->dib
;
3097 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
3098 : -dib
->dsBm
.bmHeight
;
3099 /* use the biSizeImage data as the memory size only if we're dealing with a
3100 compressed image where the value is set. Otherwise, calculate based on
3102 INT totalSize
= dib
->dsBmih
.biSizeImage
&& dib
->dsBmih
.biCompression
!= BI_RGB
3103 ? dib
->dsBmih
.biSizeImage
3104 : dib
->dsBm
.bmWidthBytes
* effHeight
;
3107 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
3108 TRACE("Changed protection from %ld to %ld\n", old_prot
, new_prot
);
3111 /***********************************************************************
3112 * X11DRV_DIB_DoUpdateDIBSection
3114 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
3116 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3117 X11DRV_DIB_IMAGEBITS_DESCR descr
;
3119 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, &descr
.lines
,
3120 &descr
.infoBpp
, &descr
.compression
) == -1)
3124 descr
.palentry
= NULL
;
3125 descr
.image
= dib
->image
;
3126 descr
.colorMap
= (RGBQUAD
*)dib
->colorMap
;
3127 descr
.nColorMap
= dib
->nColorMap
;
3128 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
3129 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
3131 switch (descr
.infoBpp
)
3137 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
3141 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0x7c00;
3142 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x03e0;
3143 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x001f;
3147 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0xff;
3148 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0xff00;
3149 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0xff0000;
3154 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
3155 descr
.gc
= BITMAP_GC(bmp
);
3160 descr
.width
= bmp
->bitmap
.bmWidth
;
3161 descr
.height
= bmp
->bitmap
.bmHeight
;
3162 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
3166 TRACE("Copying from Pixmap to DIB bits\n");
3167 EnterCriticalSection( &X11DRV_CritSection
);
3168 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits
, &descr
);
3169 LeaveCriticalSection( &X11DRV_CritSection
);
3173 TRACE("Copying from DIB bits to Pixmap\n");
3174 EnterCriticalSection( &X11DRV_CritSection
);
3175 CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
3176 LeaveCriticalSection( &X11DRV_CritSection
);
3180 /***********************************************************************
3181 * X11DRV_DIB_FaultHandler
3183 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
3185 BOOL handled
= FALSE
;
3188 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
3189 if (!bmp
) return FALSE
;
3192 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3194 case X11DRV_DIB_GdiMod
:
3195 TRACE("called in status DIB_GdiMod\n" );
3196 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3197 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3198 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3199 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_InSync
;
3203 case X11DRV_DIB_InSync
:
3204 TRACE("called in status X11DRV_DIB_InSync\n" );
3205 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3206 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_AppMod
;
3210 case X11DRV_DIB_AppMod
:
3211 FIXME("called in status X11DRV_DIB_AppMod: this can't happen!\n" );
3214 case X11DRV_DIB_NoHandler
:
3215 FIXME("called in status DIB_NoHandler: this can't happen!\n" );
3219 GDI_ReleaseObj( (HBITMAP
)res
);
3223 /***********************************************************************
3224 * X11DRV_DIB_CmnUpdateDIBSection
3226 static void X11DRV_DIB_CmnUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
3229 if (!bmp
->dib
) return;
3233 /* Prepare for access to the DIB by GDI functions */
3235 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3238 case X11DRV_DIB_NoHandler
:
3239 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
3242 case X11DRV_DIB_GdiMod
:
3243 TRACE("fromDIB called in status X11DRV_DIB_GdiMod\n" );
3247 case X11DRV_DIB_InSync
:
3248 TRACE("fromDIB called in status X11DRV_DIB_InSync\n" );
3252 case X11DRV_DIB_AppMod
:
3253 TRACE("fromDIB called in status X11DRV_DIB_AppMod\n" );
3254 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
3255 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3256 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_InSync
;
3262 /* Acknowledge write access to the DIB by GDI functions */
3264 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3267 case X11DRV_DIB_NoHandler
:
3268 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3271 case X11DRV_DIB_GdiMod
:
3272 TRACE(" toDIB called in status X11DRV_DIB_GdiMod\n" );
3276 case X11DRV_DIB_InSync
:
3277 TRACE(" toDIB called in status X11DRV_DIB_InSync\n" );
3278 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
3279 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_GdiMod
;
3282 case X11DRV_DIB_AppMod
:
3283 FIXME(" toDIB called in status X11DRV_DIB_AppMod: "
3284 "this can't happen!\n" );
3290 /***********************************************************************
3291 * X11DRV_DIB_UpdateDIBSection2
3293 void X11DRV_DIB_UpdateDIBSection2(HBITMAP hbmp
, BOOL toDIB
)
3297 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hbmp
, BITMAP_MAGIC
);
3300 X11DRV_DIB_CmnUpdateDIBSection(bmp
, toDIB
);
3302 GDI_ReleaseObj(hbmp
);
3305 /***********************************************************************
3306 * X11DRV_DIB_UpdateDIBSection
3308 void X11DRV_DIB_UpdateDIBSection(DC
*dc
, BOOL toDIB
)
3310 /* Ensure this is a Compatible DC that has a DIB section selected */
3313 if (!(dc
->flags
& DC_MEMORY
)) return;
3315 X11DRV_DIB_UpdateDIBSection2(dc
->hBitmap
, toDIB
);
3318 /***********************************************************************
3319 * X11DRV_DIB_CreateDIBSection16
3321 HBITMAP16
X11DRV_DIB_CreateDIBSection16(
3322 DC
*dc
, BITMAPINFO
*bmi
, UINT16 usage
,
3323 SEGPTR
*bits
, HANDLE section
,
3324 DWORD offset
, DWORD ovr_pitch
)
3326 HBITMAP res
= X11DRV_DIB_CreateDIBSection(dc
, bmi
, usage
, NULL
,
3327 section
, offset
, ovr_pitch
);
3330 BITMAPOBJ
*bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
3331 if ( bmp
&& bmp
->dib
)
3333 DIBSECTION
*dib
= bmp
->dib
;
3334 INT height
= dib
->dsBm
.bmHeight
>= 0 ?
3335 dib
->dsBm
.bmHeight
: -dib
->dsBm
.bmHeight
;
3336 /* same as above - only use biSizeImage as the correct size if it a
3337 compressed image and it's currently non-zero. In other cases, use
3338 width * height as the value. */
3339 INT size
= dib
->dsBmih
.biSizeImage
&& dib
->dsBmih
.biCompression
!= BI_RGB
3340 ? dib
->dsBmih
.biSizeImage
3341 : dib
->dsBm
.bmWidthBytes
* height
;
3342 if ( dib
->dsBm
.bmBits
)
3344 ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
=
3345 SELECTOR_AllocBlock( dib
->dsBm
.bmBits
, size
, WINE_LDT_FLAGS_DATA
);
3347 TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
3348 dib
->dsBm
.bmBits
, size
, ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
,
3349 PTR_SEG_OFF_TO_SEGPTR(((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
, 0));
3351 *bits
= PTR_SEG_OFF_TO_SEGPTR( ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
, 0 );
3353 if (bmp
) GDI_ReleaseObj( res
);
3359 /***********************************************************************
3360 * X11DRV_XShmErrorHandler
3363 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
)
3369 /***********************************************************************
3370 * X11DRV_XShmCreateImage
3374 extern BOOL
X11DRV_XShmCreateImage(XImage
** image
, int width
, int height
, int bpp
,
3375 XShmSegmentInfo
* shminfo
)
3377 int (*WineXHandler
)(Display
*, XErrorEvent
*);
3379 *image
= TSXShmCreateImage(display
, X11DRV_GetVisual(), bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
3380 if( *image
!= NULL
)
3382 EnterCriticalSection( &X11DRV_CritSection
);
3383 shminfo
->shmid
= shmget(IPC_PRIVATE
, (*image
)->bytes_per_line
* height
,
3385 if( shminfo
->shmid
!= -1 )
3387 shminfo
->shmaddr
= (*image
)->data
= shmat(shminfo
->shmid
, 0, 0);
3388 if( shminfo
->shmaddr
!= (char*)-1 )
3390 shminfo
->readOnly
= FALSE
;
3391 if( TSXShmAttach( display
, shminfo
) != 0)
3393 /* Reset the error flag */
3395 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
3396 XSync( display
, 0 );
3400 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3402 XSetErrorHandler(WineXHandler
);
3403 LeaveCriticalSection( &X11DRV_CritSection
);
3405 return TRUE
; /* Success! */
3407 /* An error occured */
3409 XSetErrorHandler(WineXHandler
);
3411 shmdt(shminfo
->shmaddr
);
3413 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3416 XDestroyImage(*image
);
3417 LeaveCriticalSection( &X11DRV_CritSection
);
3425 /***********************************************************************
3426 * X11DRV_DIB_CreateDIBSection
3428 HBITMAP
X11DRV_DIB_CreateDIBSection(
3429 DC
*dc
, BITMAPINFO
*bmi
, UINT usage
,
3430 LPVOID
*bits
, HANDLE section
,
3431 DWORD offset
, DWORD ovr_pitch
)
3434 BITMAPOBJ
*bmp
= NULL
;
3435 X11DRV_DIBSECTION
*dib
= NULL
;
3436 int *colorMap
= NULL
;
3439 /* Fill BITMAP32 structure with DIB data */
3440 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
3441 INT effHeight
, totalSize
;
3444 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
3445 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
3446 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
3448 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
3450 bm
.bmWidth
= bi
->biWidth
;
3451 bm
.bmHeight
= effHeight
;
3452 bm
.bmWidthBytes
= ovr_pitch
? ovr_pitch
3453 : DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
3454 bm
.bmPlanes
= bi
->biPlanes
;
3455 bm
.bmBitsPixel
= bi
->biBitCount
;
3458 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
3459 we're dealing with a compressed bitmap. Otherwise, use width * height. */
3460 totalSize
= bi
->biSizeImage
&& bi
->biCompression
!= BI_RGB
3461 ? bi
->biSizeImage
: bm
.bmWidthBytes
* effHeight
;
3464 bm
.bmBits
= MapViewOfFile(section
, FILE_MAP_ALL_ACCESS
,
3465 0L, offset
, totalSize
);
3466 else if (ovr_pitch
&& offset
)
3467 bm
.bmBits
= (LPVOID
) offset
;
3470 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
3471 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
3474 /* Create Color Map */
3475 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8)
3476 colorMap
= X11DRV_DIB_BuildColorMap( usage
== DIB_PAL_COLORS
? dc
: NULL
,
3477 usage
, bm
.bmBitsPixel
, bmi
, &nColorMap
);
3479 /* Allocate Memory for DIB and fill structure */
3481 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
3484 dib
->dibSection
.dsBm
= bm
;
3485 dib
->dibSection
.dsBmih
= *bi
;
3486 dib
->dibSection
.dsBmih
.biSizeImage
= totalSize
;
3488 /* Set dsBitfields values */
3489 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
3491 dib
->dibSection
.dsBitfields
[0] = dib
->dibSection
.dsBitfields
[1] = dib
->dibSection
.dsBitfields
[2] = 0;
3493 else switch( bi
->biBitCount
)
3496 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
3497 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
3498 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f;
3502 dib
->dibSection
.dsBitfields
[0] = 0xff;
3503 dib
->dibSection
.dsBitfields
[1] = 0xff00;
3504 dib
->dibSection
.dsBitfields
[2] = 0xff0000;
3508 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff;
3509 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0xff00;
3510 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0xff0000;
3513 dib
->dibSection
.dshSection
= section
;
3514 dib
->dibSection
.dsOffset
= offset
;
3516 dib
->status
= X11DRV_DIB_NoHandler
;
3519 dib
->nColorMap
= nColorMap
;
3520 dib
->colorMap
= colorMap
;
3523 /* Create Device Dependent Bitmap and add DIB pointer */
3526 res
= CreateDIBitmap(dc
->hSelf
, bi
, 0, NULL
, bmi
, usage
);
3529 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
3532 bmp
->dib
= (DIBSECTION
*) dib
;
3534 if(!bmp
->physBitmap
)
3535 X11DRV_CreateBitmap(res
);
3543 if (TSXShmQueryExtension(display
) &&
3544 X11DRV_XShmCreateImage( &dib
->image
, bm
.bmWidth
, effHeight
,
3545 bmp
->bitmap
.bmBitsPixel
, &dib
->shminfo
) )
3547 ; /* Created Image */
3549 XCREATEIMAGE( dib
->image
, bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
3550 dib
->shminfo
.shmid
= -1;
3554 /* Clean up in case of errors */
3555 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
3557 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
3558 res
, bmp
, dib
, bm
.bmBits
);
3562 UnmapViewOfFile(bm
.bmBits
), bm
.bmBits
= NULL
;
3564 VirtualFree(bm
.bmBits
, 0L, MEM_RELEASE
), bm
.bmBits
= NULL
;
3567 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
3568 if (colorMap
) { HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
; }
3569 if (dib
) { HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
; }
3570 if (bmp
) { GDI_ReleaseObj(res
); bmp
= NULL
; }
3571 if (res
) { DeleteObject(res
); res
= 0; }
3574 /* Install fault handler, if possible */
3577 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
3579 if (section
|| offset
)
3581 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3582 if (dib
) dib
->status
= X11DRV_DIB_AppMod
;
3586 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3587 if (dib
) dib
->status
= X11DRV_DIB_InSync
;
3592 /* Return BITMAP handle and storage location */
3593 if (bmp
) GDI_ReleaseObj(res
);
3594 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
3598 /***********************************************************************
3599 * X11DRV_DIB_DeleteDIBSection
3601 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
3603 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3607 if (dib
->shminfo
.shmid
!= -1)
3609 TSXShmDetach (display
, &(dib
->shminfo
));
3610 XDestroyImage (dib
->image
);
3611 shmdt (dib
->shminfo
.shmaddr
);
3612 dib
->shminfo
.shmid
= -1;
3615 XDestroyImage( dib
->image
);
3619 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
3621 if (dib
->selector
) SELECTOR_FreeBlock( dib
->selector
);
3624 /***********************************************************************
3625 * X11DRV_DIB_SetDIBColorTable
3627 UINT
X11DRV_DIB_SetDIBColorTable(BITMAPOBJ
*bmp
, DC
*dc
, UINT start
, UINT count
, const RGBQUAD
*colors
)
3629 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3631 if (dib
&& dib
->colorMap
) {
3632 X11DRV_DIB_GenColorMap( dc
, dib
->colorMap
, DIB_RGB_COLORS
, dib
->dibSection
.dsBm
.bmBitsPixel
,
3633 TRUE
, colors
, start
, count
- start
);
3639 /***********************************************************************
3640 * X11DRV_DIB_GetDIBColorTable
3642 UINT
X11DRV_DIB_GetDIBColorTable(BITMAPOBJ
*bmp
, DC
*dc
, UINT start
, UINT count
, RGBQUAD
*colors
)
3644 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3646 if (dib
&& dib
->colorMap
) {
3647 int i
, end
= count
- start
;
3648 for (i
= start
; i
< end
; i
++,colors
++) {
3649 COLORREF col
= X11DRV_PALETTE_ToLogical( dib
->colorMap
[i
] );
3650 colors
->rgbBlue
= GetBValue(col
);
3651 colors
->rgbGreen
= GetGValue(col
);
3652 colors
->rgbRed
= GetRValue(col
);
3653 colors
->rgbReserved
= 0;
3661 /**************************************************************************
3662 * X11DRV_DIB_CreateDIBFromPixmap
3664 * Allocates a packed DIB and copies the Pixmap data into it.
3665 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
3667 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
, BOOL bDeletePixmap
)
3670 BITMAPOBJ
*pBmp
= NULL
;
3671 HGLOBAL hPackedDIB
= 0;
3673 /* Allocates an HBITMAP which references the Pixmap passed to us */
3674 hBmp
= X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap
);
3677 TRACE("\tCould not create bitmap header for Pixmap\n");
3682 * Create a packed DIB from the Pixmap wrapper bitmap created above.
3683 * A packed DIB contains a BITMAPINFO structure followed immediately by
3684 * an optional color palette and the pixel data.
3686 hPackedDIB
= DIB_CreateDIBFromBitmap(hdc
, hBmp
);
3688 /* Get a pointer to the BITMAPOBJ structure */
3689 pBmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3691 /* We can now get rid of the HBITMAP wrapper we created earlier.
3692 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
3696 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
3697 pBmp
->physBitmap
= NULL
;
3700 GDI_ReleaseObj( hBmp
);
3704 TRACE("\tReturning packed DIB %x\n", hPackedDIB
);
3709 /**************************************************************************
3710 * X11DRV_DIB_CreatePixmapFromDIB
3712 * Creates a Pixmap from a packed DIB
3714 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
3716 Pixmap pixmap
= None
;
3718 BITMAPOBJ
*pBmp
= NULL
;
3719 LPBYTE pPackedDIB
= NULL
;
3720 LPBITMAPINFO pbmi
= NULL
;
3721 LPBITMAPINFOHEADER pbmiHeader
= NULL
;
3722 LPBYTE pbits
= NULL
;
3724 /* Get a pointer to the packed DIB's data */
3725 pPackedDIB
= (LPBYTE
)GlobalLock(hPackedDIB
);
3726 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
3727 pbmi
= (LPBITMAPINFO
)pPackedDIB
;
3728 pbits
= (LPBYTE
)(pPackedDIB
3729 + DIB_BitmapInfoSize( (LPBITMAPINFO
)pbmiHeader
, DIB_RGB_COLORS
));
3731 /* Create a DDB from the DIB */
3733 hBmp
= CreateDIBitmap(hdc
,
3740 GlobalUnlock(hPackedDIB
);
3742 TRACE("CreateDIBitmap returned %x\n", hBmp
);
3744 /* Retrieve the internal Pixmap from the DDB */
3746 pBmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3748 pixmap
= (Pixmap
)pBmp
->physBitmap
;
3749 /* clear the physBitmap so that we can steal its pixmap */
3750 pBmp
->physBitmap
= NULL
;
3753 /* Delete the DDB we created earlier now that we have stolen its pixmap */
3754 GDI_ReleaseObj( hBmp
);
3757 TRACE("\tReturning Pixmap %ld\n", pixmap
);