2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
9 #ifndef X_DISPLAY_MISSING
16 # ifdef HAVE_SYS_SHM_H
19 # ifdef HAVE_SYS_IPC_H
22 #endif /* defined(HAVE_LIBXXSHM) */
27 #include "debugtools.h"
31 #include "selectors.h"
33 #include "xmalloc.h" /* for XCREATEIMAGE macro */
35 DEFAULT_DEBUG_CHANNEL(bitmap
)
36 DECLARE_DEBUG_CHANNEL(x11drv
)
38 static int bitmapDepthTable
[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
39 static int ximageDepthTable
[] = { 0, 0, 0, 0, 0, 0, 0 };
41 static int XShmErrorFlag
= 0;
43 /***********************************************************************
46 BOOL
X11DRV_DIB_Init(void)
51 for( i
= 0; bitmapDepthTable
[i
]; i
++ )
53 testimage
= TSXCreateImage(display
, DefaultVisualOfScreen(X11DRV_GetXScreen()),
54 bitmapDepthTable
[i
], ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
55 if( testimage
) ximageDepthTable
[i
] = testimage
->bits_per_pixel
;
57 TSXDestroyImage(testimage
);
63 /***********************************************************************
64 * X11DRV_DIB_GetXImageWidthBytes
66 * Return the width of an X image in bytes
68 int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
72 if (!ximageDepthTable
[0]) {
75 for( i
= 0; bitmapDepthTable
[i
] ; i
++ )
76 if( bitmapDepthTable
[i
] == depth
)
77 return (4 * ((width
* ximageDepthTable
[i
] + 31)/32));
79 WARN("(%d): Unsupported depth\n", depth
);
83 /***********************************************************************
84 * X11DRV_DIB_BuildColorMap
86 * Build the color map from the bitmap palette. Should not be called
87 * for a >8-bit deep bitmap.
89 int *X11DRV_DIB_BuildColorMap( DC
*dc
, WORD coloruse
, WORD depth
,
90 const BITMAPINFO
*info
, int *nColors
)
97 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
99 colors
= info
->bmiHeader
.biClrUsed
;
100 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
101 colorPtr
= (WORD
*)info
->bmiColors
;
103 else /* assume BITMAPCOREINFO */
105 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
106 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
111 ERR("called with >256 colors!\n");
115 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
116 colors
* sizeof(int) )))
119 if (coloruse
== DIB_RGB_COLORS
)
123 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
125 if (depth
== 1) /* Monochrome */
126 for (i
= 0; i
< colors
; i
++, rgb
++)
127 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
128 rgb
->rgbBlue
> 255*3/2);
130 for (i
= 0; i
< colors
; i
++, rgb
++)
131 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbRed
,
137 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
139 if (depth
== 1) /* Monochrome */
140 for (i
= 0; i
< colors
; i
++, rgb
++)
141 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
142 rgb
->rgbtBlue
> 255*3/2);
144 for (i
= 0; i
< colors
; i
++, rgb
++)
145 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbtRed
,
150 else /* DIB_PAL_COLORS */
152 for (i
= 0; i
< colors
; i
++, colorPtr
++)
153 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, PALETTEINDEX(*colorPtr
) );
161 /***********************************************************************
162 * X11DRV_DIB_MapColor
164 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
)
168 for (color
= 0; color
< nPhysMap
; color
++)
169 if (physMap
[color
] == phys
)
172 WARN("Strange color %08x\n", phys
);
177 /*********************************************************************
178 * X11DRV_DIB_GetNearestIndex
180 * Helper for X11DRV_DIB_GetDIBits.
181 * Returns the nearest colour table index for a given RGB.
182 * Nearest is defined by minimizing the sum of the squares.
184 static INT
X11DRV_DIB_GetNearestIndex(RGBQUAD
*colormap
, int numColors
, BYTE r
, BYTE g
, BYTE b
)
186 INT i
, best
= -1, diff
, bestdiff
= -1;
189 for(color
= colormap
, i
= 0; i
< numColors
; color
++, i
++) {
190 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
191 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
192 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
195 if(best
== -1 || diff
< bestdiff
) {
203 /***********************************************************************
204 * X11DRV_DIB_SetImageBits_1_Line
206 * Handles a single line of 1 bit data.
208 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth
, int left
, int *colors
,
209 XImage
*bmpImage
, int h
, const BYTE
*bits
)
214 if((extra
= (left
& 7)) != 0) {
221 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
222 for (i
= dstwidth
/8, x
= left
; i
> 0; i
--)
225 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
226 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 6) & 1] );
227 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 5) & 1] );
228 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 4) & 1] );
229 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 3) & 1] );
230 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 2) & 1] );
231 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 1) & 1] );
232 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 1] );
237 case 7: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
238 case 6: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
239 case 5: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
240 case 4: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
241 case 3: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
242 case 2: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
243 case 1: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
247 /***********************************************************************
248 * X11DRV_DIB_SetImageBits_1
250 * SetDIBits for a 1-bit deep DIB.
252 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
253 DWORD srcwidth
, DWORD dstwidth
, int left
,
254 int *colors
, XImage
*bmpImage
)
259 DWORD linebytes
= ((srcwidth
+ 31) & ~31) / 8;
262 for (h
= lines
-1; h
>=0; h
--) {
263 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
265 srcbits
+= linebytes
;
269 for (h
= 0; h
< lines
; h
++) {
270 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
272 srcbits
+= linebytes
;
277 /***********************************************************************
278 * X11DRV_DIB_GetImageBits_1
280 * GetDIBits for a 1-bit deep DIB.
282 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
283 DWORD dstwidth
, DWORD srcwidth
,
284 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
292 DWORD linebytes
= ((dstwidth
+ 31) & ~31) / 8;
296 dstbits
= dstbits
+ linebytes
* (lines
- 1);
297 linebytes
= -linebytes
;
302 switch(bmpImage
->depth
) {
305 /* ==== monochrome bitmap to monochrome dib ==== */
307 /* ==== 4 colormap bitmap to monochrome dib ==== */
308 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
312 for (h
= lines
- 1; h
>= 0; h
--) {
313 for (x
= 0; x
< dstwidth
; x
++) {
314 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
315 if (!(x
&7)) *bits
= 0;
316 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2,
319 val
.peBlue
) << (7 - (x
& 7)));
320 if ((x
&7)==7) bits
++;
322 bits
= (dstbits
+= linebytes
);
325 else goto notsupported
;
330 /* ==== 8 colormap bitmap to monochrome dib ==== */
331 if ( bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
336 for( h
= lines
- 1; h
>= 0; h
-- ) {
337 srcpixel
= bmpImage
->data
+ (h
*bmpImage
->bytes_per_line
);
338 for( x
= 0; x
< dstwidth
; x
++ ) {
339 if (!(x
&7)) *bits
= 0;
340 val
= srccolors
[(int)*srcpixel
++];
341 *bits
|= ( X11DRV_DIB_GetNearestIndex(colors
, 2,
344 val
.peBlue
) << (7-(x
&7)) );
345 if ((x
&7)==7) bits
++;
347 bits
= (dstbits
+= linebytes
);
350 else goto notsupported
;
359 /* ==== 555 BGR bitmap to monochrome dib ==== */
360 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x1f)
362 for( h
= lines
- 1; h
>= 0; h
--) {
363 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
364 for( x
= 0; x
< dstwidth
; x
++) {
365 if (!(x
&7)) *bits
= 0;
367 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
368 ((val
>> 7) & 0xf8) |
370 ((val
>> 2) & 0xf8) |
372 ((val
<< 3) & 0xf8) |
373 ((val
>> 2) & 0x7) ) << (7-(x
&7)) );
374 if ((x
&7)==7) bits
++;
376 bits
= (dstbits
+= linebytes
);
379 /* ==== 555 RGB bitmap to monochrome dib ==== */
380 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
382 for( h
= lines
- 1; h
>= 0; h
--)
384 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
385 for( x
= 0; x
< dstwidth
; x
++) {
386 if (!(x
&1)) *bits
= 0;
388 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
389 ((val
<< 3) & 0xf8) |
391 ((val
>> 2) & 0xf8) |
393 ((val
>> 7) & 0xf8) |
394 ((val
>> 12) & 0x7) ) << (7-(x
&7)) );
395 if ((x
&7)==7) bits
++;
397 bits
= (dstbits
+= linebytes
);
400 else goto notsupported
;
409 /* ==== 565 BGR bitmap to monochrome dib ==== */
410 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
412 for( h
= lines
- 1; h
>= 0; h
--)
414 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
415 for( x
= 0; x
< dstwidth
; x
++) {
416 if (!(x
&7)) *bits
= 0;
418 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
419 ((val
>> 8) & 0xf8) |
421 ((val
>> 3) & 0xfc) |
423 ((val
<< 3) & 0xf8) |
424 ((val
>> 2) & 0x7) ) << (7-(x
&7)) );
425 if ((x
&7)==7) bits
++;
427 bits
= (dstbits
+= linebytes
);
430 /* ==== 565 RGB bitmap to monochrome dib ==== */
431 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
433 for( h
= lines
- 1; h
>= 0; h
--)
435 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
436 for( x
= 0; x
< dstwidth
; x
++) {
437 if (!(x
&7)) *bits
= 0;
439 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 2,
440 ((val
<< 3) & 0xf8) |
442 ((val
>> 3) & 0xfc) |
444 ((val
>> 8) & 0xf8) |
445 ((val
>> 13) & 0x7) ) << (7-(x
&7)) );
446 if ((x
&7)==7) bits
++;
448 bits
= (dstbits
+= linebytes
);
451 else goto notsupported
;
460 /* ==== 24/32 BGR bitmap to monochrome dib ==== */
461 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
463 for (h
= lines
- 1; h
>= 0; h
--)
465 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
466 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4) {
467 if (!(x
&7)) *bits
= 0;
468 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2, srcpixel
[2] , srcpixel
[1], srcpixel
[0]) << (7-(x
&7)) );
469 if ((x
&7)==7) bits
++;
471 bits
= (dstbits
+= linebytes
);
474 /* ==== 24/32 RGB bitmap to monochrome dib ==== */
475 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
477 for (h
= lines
- 1; h
>= 0; h
--)
479 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
480 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4) {
481 if (!(x
& 7)) *bits
= 0;
482 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 2, srcpixel
[0] , srcpixel
[1], srcpixel
[2]) << (7-(x
&7)) );
483 if ((x
& 7) == 7) bits
++;
485 bits
= (dstbits
+= linebytes
);
488 else goto notsupported
;
492 default: /* ? bit bmp -> monochrome DIB */
495 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
497 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
498 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
499 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
501 for( h
= lines
- 1; h
>= 0; h
-- ) {
502 for( x
= 0; x
< dstwidth
; x
++ ) {
503 if (!(x
&7)) *bits
= 0;
504 *bits
|= (XGetPixel( bmpImage
, x
, h
) >= white
)
506 if ((x
&7)==7) bits
++;
508 bits
= (dstbits
+= linebytes
);
515 /***********************************************************************
516 * X11DRV_DIB_SetImageBits_4
518 * SetDIBits for a 4-bit deep DIB.
520 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
521 DWORD srcwidth
, DWORD dstwidth
, int left
,
522 int *colors
, XImage
*bmpImage
)
526 const BYTE
*bits
= srcbits
+ (left
>> 1);
529 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
537 for (h
= lines
-1; h
>= 0; h
--) {
538 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
540 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
541 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
543 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
544 srcbits
+= linebytes
;
545 bits
= srcbits
+ (left
>> 1);
549 for (h
= 0; h
< lines
; h
++) {
550 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
552 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
553 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
555 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
556 srcbits
+= linebytes
;
557 bits
= srcbits
+ (left
>> 1);
564 /***********************************************************************
565 * X11DRV_DIB_GetImageBits_4
567 * GetDIBits for a 4-bit deep DIB.
569 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
570 DWORD srcwidth
, DWORD dstwidth
,
571 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
580 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
585 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
586 linebytes
= -linebytes
;
591 switch(bmpImage
->depth
) {
594 /* ==== monochrome bitmap to 4 colormap dib ==== */
596 /* ==== 4 colormap bitmap to 4 colormap dib ==== */
597 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
601 for (h
= lines
-1; h
>= 0; h
--) {
602 for (x
= 0; x
< dstwidth
; x
++) {
603 if (!(x
&1)) *bits
= 0;
604 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
605 *bits
|= (X11DRV_DIB_GetNearestIndex(colors
, 16,
608 val
.peBlue
) << (4-((x
&1)<<2)));
609 if ((x
&1)==1) bits
++;
611 bits
= (dstbits
+= linebytes
);
614 else goto notsupported
;
619 /* ==== 8 colormap bitmap to 4 colormap dib ==== */
620 if ( bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
624 for( h
= lines
- 1; h
>= 0; h
-- ) {
625 srcpixel
= bmpImage
->data
+ (h
*bmpImage
->bytes_per_line
);
626 for( x
= 0; x
< dstwidth
; x
++ ) {
627 if (!(x
&1)) *bits
= 0;
628 val
= srccolors
[(int)*srcpixel
++];
629 *bits
|= ( X11DRV_DIB_GetNearestIndex(colors
, 16,
632 val
.peBlue
) << (4*(1-(x
&1))) );
633 if ((x
&1)==1) bits
++;
635 bits
= (dstbits
+= linebytes
);
638 else goto notsupported
;
647 /* ==== 555 BGR bitmap to 4 colormap dib ==== */
648 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x1f)
650 for( h
= lines
- 1; h
>= 0; h
--) {
651 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
652 for( x
= 0; x
< dstwidth
; x
++) {
653 if (!(x
&1)) *bits
= 0;
655 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
656 ((val
>> 7) & 0xf8) |
658 ((val
>> 2) & 0xf8) |
660 ((val
<< 3) & 0xf8) |
661 ((val
>> 2) & 0x7) ) << ((1-(x
&1))<<2) );
662 if ((x
&1)==1) bits
++;
664 bits
= (dstbits
+= linebytes
);
667 /* ==== 555 RGB bitmap to 4 colormap dib ==== */
668 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
670 for( h
= lines
- 1; h
>= 0; h
--)
672 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
673 for( x
= 0; x
< dstwidth
; x
++) {
674 if (!(x
&1)) *bits
= 0;
676 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
677 ((val
<< 3) & 0xf8) |
679 ((val
>> 2) & 0xfc) |
681 ((val
>> 7) & 0xf8) |
682 ((val
>> 12) & 0x7) ) << ((1-(x
&1))<<2) );
683 if ((x
&1)==1) bits
++;
685 bits
= (dstbits
+= linebytes
);
688 else goto notsupported
;
697 /* ==== 565 BGR bitmap to 4 colormap dib ==== */
698 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
700 for( h
= lines
- 1; h
>= 0; h
--)
702 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
703 for( x
= 0; x
< dstwidth
; x
++) {
704 if (!(x
&1)) *bits
= 0;
706 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
707 ((val
>> 8) & 0xf8) |
709 ((val
>> 3) & 0xfc) |
711 ((val
<< 3) & 0xf8) |
712 ((val
>> 2) & 0x7) ) << ((1-(x
&1))<<2) );
713 if ((x
&1)==1) bits
++;
715 bits
= (dstbits
+= linebytes
);
718 /* ==== 565 RGB bitmap to 4 colormap dib ==== */
719 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
721 for( h
= lines
- 1; h
>= 0; h
--)
723 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
724 for( x
= 0; x
< dstwidth
; x
++) {
725 if (!(x
&1)) *bits
= 0;
727 *bits
|= (X11DRV_DIB_GetNearestIndex( colors
, 16,
728 ((val
<< 3) & 0xf8) |
730 ((val
>> 3) & 0xfc) |
732 ((val
>> 8) & 0xf8) |
733 ((val
>> 13) & 0x7) ) << ((1-(x
&1))<<2) );
734 if ((x
&1)==1) bits
++;
736 bits
= (dstbits
+= linebytes
);
739 else goto notsupported
;
748 /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
749 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
751 for (h
= lines
- 1; h
>= 0; h
--)
753 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
754 for (x
= 0; x
< dstwidth
; x
+=2, srcpixel
+=8) /* 2 pixels at a time */
755 *bits
++ = (X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[2] , srcpixel
[1], srcpixel
[0]) << 4) |
756 X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[6] , srcpixel
[5], srcpixel
[4]);
757 bits
= (dstbits
+= linebytes
);
760 /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
761 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
763 for (h
= lines
- 1; h
>= 0; h
--)
765 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
766 for (x
= 0; x
< dstwidth
; x
+=2, srcpixel
+=8) /* 2 pixels at a time */
767 *bits
++ = (X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[0] , srcpixel
[1], srcpixel
[2]) << 4) |
768 X11DRV_DIB_GetNearestIndex(colors
, 16, srcpixel
[4] , srcpixel
[5], srcpixel
[6]);
769 bits
= (dstbits
+= linebytes
);
772 else goto notsupported
;
776 default: /* ? bit bmp -> 4 bit DIB */
778 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
779 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
780 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
781 for (h
= lines
-1; h
>= 0; h
--) {
782 for (x
= 0; x
< dstwidth
/2; x
++) {
783 *bits
++ = (X11DRV_DIB_MapColor((int *)colors
, 16,
784 XGetPixel( bmpImage
, x
++, h
)) << 4)
785 | (X11DRV_DIB_MapColor((int *)colors
, 16,
786 XGetPixel( bmpImage
, x
++, h
)) & 0x0f);
789 *bits
= (X11DRV_DIB_MapColor((int *)colors
, 16,
790 XGetPixel( bmpImage
, x
++, h
)) << 4);
791 bits
= (dstbits
+= linebytes
);
797 /***********************************************************************
798 * X11DRV_DIB_SetImageBits_RLE4
800 * SetDIBits for a 4-bit deep compressed DIB.
802 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
803 DWORD width
, DWORD dstwidth
,
804 int left
, int *colors
,
807 int x
= 0, c
, length
;
808 const BYTE
*begin
= bits
;
812 while ((int)lines
>= 0) {
814 if (length
) { /* encoded */
822 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>>4]);
830 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
841 case 1: /* eopicture */
847 FIXME_(x11drv
)("x-delta is too large?\n");
853 default: /* absolute */
861 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>> 4]);
869 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
872 if ((bits
- begin
) & 1)
881 /***********************************************************************
882 * X11DRV_DIB_SetImageBits_8
884 * SetDIBits for an 8-bit deep DIB.
886 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
887 DWORD srcwidth
, DWORD dstwidth
, int left
,
888 int *colors
, XImage
*bmpImage
)
894 /* align to 32 bit */
895 DWORD linebytes
= (srcwidth
+ 3) & ~3;
902 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
903 linebytes
= -linebytes
;
906 bits
= srcbits
+ left
;
908 for (h
= lines
- 1; h
>= 0; h
--) {
909 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
910 color
= colors
[*bits
];
911 XPutPixel( bmpImage
, x
, h
, colors
[*bits
] );
913 bits
= (srcbits
+= linebytes
) + left
;
917 /***********************************************************************
918 * X11DRV_DIB_GetImageBits_8
920 * GetDIBits for an 8-bit deep DIB.
922 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
923 DWORD srcwidth
, DWORD dstwidth
,
924 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
931 /* align to 32 bit */
932 DWORD linebytes
= (srcwidth
+ 3) & ~3;
937 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
938 linebytes
= -linebytes
;
945 This condition is true when GetImageBits has been called by UpdateDIBSection.
946 For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
947 for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
949 if (!srccolors
) goto updatesection
;
951 switch(bmpImage
->depth
) {
954 /* ==== monochrome bitmap to 8 colormap dib ==== */
956 /* ==== 4 colormap bitmap to 8 colormap dib ==== */
957 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
961 for (h
= lines
- 1; h
>= 0; h
--) {
962 for (x
= 0; x
< dstwidth
; x
++) {
963 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
964 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256, val
.peRed
,
965 val
.peGreen
, val
.peBlue
);
967 bits
= (dstbits
+= linebytes
);
970 else goto notsupported
;
975 /* ==== 8 colormap bitmap to 8 colormap dib ==== */
976 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
981 for (h
= lines
- 1; h
>= 0; h
--) {
982 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
983 for (x
= 0; x
< dstwidth
; x
++) {
984 val
= srccolors
[(int)*srcpixel
++];
985 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256, val
.peRed
,
986 val
.peGreen
, val
.peBlue
);
988 bits
= (dstbits
+= linebytes
);
991 else goto notsupported
;
1000 /* ==== 555 BGR bitmap to 8 colormap dib ==== */
1001 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
1003 for( h
= lines
- 1; h
>= 0; h
--)
1005 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1006 for( x
= 0; x
< dstwidth
; x
++ )
1009 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1010 ((val
>> 7) & 0xf8) |
1011 ((val
>> 12) & 0x7),
1012 ((val
>> 2) & 0xf8) |
1014 ((val
<< 3) & 0xf8) |
1015 ((val
>> 2) & 0x7) );
1017 bits
= (dstbits
+= linebytes
);
1020 /* ==== 555 RGB bitmap to 8 colormap dib ==== */
1021 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
1023 for( h
= lines
- 1; h
>= 0; h
--)
1025 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1026 for( x
= 0; x
< dstwidth
; x
++ )
1029 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1030 ((val
<< 3) & 0xf8) |
1032 ((val
>> 2) & 0xf8) |
1034 ((val
>> 7) & 0xf8) |
1035 ((val
>> 12) & 0x7) );
1037 bits
= (dstbits
+= linebytes
);
1040 else goto notsupported
;
1049 /* ==== 565 BGR bitmap to 8 colormap dib ==== */
1050 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
1052 for( h
= lines
- 1; h
>= 0; h
--)
1054 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1055 for( x
= 0; x
< dstwidth
; x
++ )
1058 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1059 ((val
>> 8) & 0xf8) |
1060 ((val
>> 13) & 0x7),
1061 ((val
>> 3) & 0xfc) |
1063 ((val
<< 3) & 0xf8) |
1064 ((val
>> 2) & 0x7) );
1066 bits
= (dstbits
+= linebytes
);
1069 /* ==== 565 RGB bitmap to 8 colormap dib ==== */
1070 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
1072 for( h
= lines
- 1; h
>= 0; h
--)
1074 srcpixel
= (LPWORD
)(bmpImage
->data
+ h
*bmpImage
->bytes_per_line
);
1075 for( x
= 0; x
< dstwidth
; x
++ )
1078 *bits
++ = X11DRV_DIB_GetNearestIndex( colors
, 256,
1079 ((val
<< 3) & 0xf8) |
1081 ((val
>> 3) & 0x00fc) |
1083 ((val
>> 8) & 0x00f8) |
1084 ((val
>> 13) & 0x7) );
1086 bits
= (dstbits
+= linebytes
);
1089 else goto notsupported
;
1098 /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
1099 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1101 for (h
= lines
- 1; h
>= 0; h
--)
1103 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1104 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4)
1105 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256,
1106 srcpixel
[2] , srcpixel
[1], *srcpixel
);
1107 bits
= (dstbits
+= linebytes
);
1110 /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
1111 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1113 for (h
= lines
- 1; h
>= 0; h
--)
1115 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1116 for (x
= 0; x
< dstwidth
; x
++, srcpixel
+=4)
1117 *bits
++ = X11DRV_DIB_GetNearestIndex(colors
, 256,
1118 *srcpixel
, srcpixel
[1], srcpixel
[2]);
1119 bits
= (dstbits
+= linebytes
);
1123 else goto notsupported
;
1127 default: /* ? bit bmp -> 8 bit DIB */
1129 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
1130 bmpImage
->depth
, (int)bmpImage
->red_mask
,
1131 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1133 for (h
= lines
- 1; h
>= 0; h
--) {
1134 for (x
= 0; x
< dstwidth
; x
++, bits
++) {
1135 *bits
= X11DRV_DIB_MapColor((int *)colors
, 256,
1136 XGetPixel( bmpImage
, x
, h
) );
1138 bits
= (dstbits
+= linebytes
);
1144 /***********************************************************************
1145 * X11DRV_DIB_SetImageBits_RLE8
1147 * SetDIBits for an 8-bit deep compressed DIB.
1149 * This function rewritten 941113 by James Youngman. WINE blew out when I
1150 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1152 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1153 * 'End of bitmap' escape code. This code is very much laxer in what it
1154 * allows to end the expansion. Possibly too lax. See the note by
1155 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1156 * bitmap should end with RleEnd, but on the other hand, software exists
1157 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1160 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1161 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1165 enum Rle8_EscapeCodes
1168 * Apologies for polluting your file's namespace...
1170 RleEol
= 0, /* End of line */
1171 RleEnd
= 1, /* End of bitmap */
1172 RleDelta
= 2 /* Delta */
1175 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
1176 DWORD width
, DWORD dstwidth
,
1177 int left
, int *colors
,
1180 int x
; /* X-positon on each line. Increases. */
1181 int line
; /* Line #. Starts at lines-1, decreases */
1182 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
1183 BYTE length
; /* The length pf a run */
1184 BYTE color_index
; /* index into colors[] as read from bits */
1185 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
1186 int color
; /* value of colour[color_index] */
1188 if (lines
== 0) /* Let's hope this doesn't happen. */
1192 * Note that the bitmap data is stored by Windows starting at the
1193 * bottom line of the bitmap and going upwards. Within each line,
1194 * the data is stored left-to-right. That's the reason why line
1195 * goes from lines-1 to 0. [JAY]
1205 * If the length byte is not zero (which is the escape value),
1206 * We have a run of length pixels all the same colour. The colour
1207 * index is stored next.
1209 * If the length byte is zero, we need to read the next byte to
1210 * know what to do. [JAY]
1215 * [Run-Length] Encoded mode
1217 color_index
= (*pIn
++); /* Get the colour index. */
1218 color
= colors
[color_index
];
1221 XPutPixel(bmpImage
, x
++, line
, color
);
1226 * Escape codes (may be an absolute sequence though)
1228 escape_code
= (*pIn
++);
1231 case RleEol
: /* =0, end of line */
1238 case RleEnd
: /* =1, end of bitmap */
1241 * Not all RLE8 bitmaps end with this
1242 * code. For example, Paint Shop Pro
1243 * produces some that don't. That's (I think)
1244 * what caused the previous implementation to
1247 line
=-1; /* Cause exit from do loop. */
1251 case RleDelta
: /* =2, a delta */
1254 * Note that deltaing to line 0
1255 * will cause an exit from the loop,
1256 * which may not be what is intended.
1257 * The fact that there is a delta in the bits
1258 * almost certainly implies that there is data
1259 * to follow. You may feel that we should
1260 * jump to the top of the loop to avoid exiting
1263 * TODO: Decide what to do here in that case. [JAY]
1269 TRACE("Delta to last line of bitmap "
1270 "(wrongly?) causes loop exit\n");
1275 default: /* >2, switch to absolute mode */
1280 length
= escape_code
;
1283 color_index
= (*pIn
++);
1284 XPutPixel(bmpImage
, x
++, line
,
1285 colors
[color_index
]);
1289 * If you think for a moment you'll realise that the
1290 * only time we could ever possibly read an odd
1291 * number of bytes is when there is a 0x00 (escape),
1292 * a value >0x02 (absolute mode) and then an odd-
1293 * length run. Therefore this is the only place we
1294 * need to worry about it. Everywhere else the
1295 * bytes are always read in pairs. [JAY]
1297 if (escape_code
& 1)
1298 pIn
++; /* Throw away the pad byte. */
1301 } /* switch (escape_code) : Escape sequence */
1302 } /* process either an encoded sequence or an escape sequence */
1304 /* We expect to come here more than once per line. */
1305 } while (line
>= 0); /* Do this until the bitmap is filled */
1308 * Everybody comes here at the end.
1309 * Check how we exited the loop and print a message if it's a bit odd.
1312 if ( (*(pIn
-2) != 0/*escape*/) || (*(pIn
-1)!= RleEnd
) )
1314 TRACE("End-of-bitmap without (strictly) proper escape code. Last two "
1315 "bytes were: %02X %02X.\n", (int)*(pIn
-2),(int)*(pIn
-1));
1320 /***********************************************************************
1321 * X11DRV_DIB_SetImageBits_16
1323 * SetDIBits for a 16-bit deep DIB.
1325 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
1326 DWORD srcwidth
, DWORD dstwidth
, int left
,
1327 DC
*dc
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
1333 /* align to 32 bit */
1334 DWORD linebytes
= (srcwidth
* 2 + 3) & ~3;
1339 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
1340 linebytes
= -linebytes
;
1343 switch ( bmpImage
->depth
)
1346 /* using same format as XImage */
1347 if (rSrc
== bmpImage
->red_mask
&& gSrc
== bmpImage
->green_mask
&& bSrc
== bmpImage
->blue_mask
)
1348 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+= linebytes
)
1349 memcpy ( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2, srcbits
+ left
*2, dstwidth
*2 );
1350 else /* We need to do a conversion from a 565 dib */
1352 LPDWORD dstpixel
, ptr
= (LPDWORD
)(srcbits
+ left
*2);
1354 int div
= dstwidth
% 2;
1356 for (h
= lines
- 1; h
>= 0; h
--) {
1357 dstpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1358 for (x
= 0; x
< dstwidth
/2; x
++) { /* Do 2 pixels at a time */
1360 *dstpixel
++ = ((val
>> 1) & 0x7fe07fe0) | (val
& 0x001f001f); /* Red & Green & Blue */
1362 if (div
!= 0) /* Odd width? */
1363 *dstpixel
= ((*(WORD
*)ptr
>> 1) & 0x7fe0) | (*(WORD
*)ptr
& 0x001f);
1364 ptr
= (LPDWORD
) ((srcbits
+= linebytes
) + left
*2);
1370 /* using same format as XImage */
1371 if (rSrc
== bmpImage
->red_mask
&& gSrc
== bmpImage
->green_mask
&& bSrc
== bmpImage
->blue_mask
)
1372 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+= linebytes
)
1373 memcpy ( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2, srcbits
+ left
*2, dstwidth
*2 );
1374 else /* We need to do a conversion from a 555 dib */
1376 LPDWORD dstpixel
, ptr
= (LPDWORD
)(srcbits
+ left
*2);
1378 int div
= dstwidth
% 2;
1380 for (h
= lines
- 1; h
>= 0; h
--) {
1381 dstpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1382 for (x
= 0; x
< dstwidth
/2; x
++) { /* Do 2 pixels at a time */
1384 *dstpixel
++ = ((val
<< 1) & 0xffc0ffc0) | ((val
>> 4) & 0x00200020) | /* Red & Green */
1385 (val
& 0x001f001f); /* Blue */
1387 if (div
!= 0) /* Odd width? */
1388 *dstpixel
= ((*(WORD
*)ptr
<< 1) & 0xffc0) | ((*(WORD
*)ptr
>> 4) & 0x0020)
1389 | (*(WORD
*)ptr
& 0x001f);
1390 ptr
= (LPDWORD
) ((srcbits
+= linebytes
) + left
*2);
1399 LPWORD ptr
= (LPWORD
)srcbits
+ left
;
1402 /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
1403 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1405 for (h
= lines
- 1; h
>= 0; h
--) {
1406 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1407 for (x
= 0; x
< dstwidth
; x
++) {
1410 *dstpixel
++ = ((val
<< 9) & 0xf80000) | ((val
<< 4) & 0x070000) | /* Red */
1411 ((val
<< 6) & 0x00f800) | ((val
<< 1) & 0x000700) | /* Green */
1412 ((val
<< 3) & 0x0000f8) | ((val
>> 2) & 0x000007); /* Blue */
1414 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1417 /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
1418 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1420 for (h
= lines
- 1; h
>= 0; h
--) {
1421 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*4);
1422 for (x
= 0; x
< dstwidth
; x
++) {
1425 *dstpixel
++ = ((val
>> 7) & 0x0000f8) | ((val
>> 12) & 0x000007) | /* Red */
1426 ((val
<< 6) & 0x00f800) | ((val
<< 1) & 0x000700) | /* Green */
1427 ((val
<< 19) & 0xf80000) | ((val
>> 14) & 0x070000); /* Blue */
1429 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
1440 LPWORD ptr
= (LPWORD
)srcbits
+ left
;
1444 /* Set color scaling values */
1445 if ( rSrc
== 0x7c00 ) { sc1
= 7; sc2
= 2; } /* 555 dib */
1446 else { sc1
= 8; sc2
= 3; } /* 565 dib */
1448 for (h
= lines
- 1; h
>= 0; h
--) {
1449 for (x
= left
; x
< dstwidth
+left
; x
++) {
1451 XPutPixel( bmpImage
, x
, h
,
1452 X11DRV_PALETTE_ToPhysical(dc
, RGB(((val
& rSrc
) >> sc1
), /* Red */
1453 ((val
& gSrc
) >> sc2
), /* Green */
1454 ((val
& bSrc
) << 3)))); /* Blue */
1456 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
1462 FIXME("16 bit DIB %d bit bitmap\n", bmpImage
->bits_per_pixel
);
1469 /***********************************************************************
1470 * X11DRV_DIB_GetImageBits_16
1472 * GetDIBits for an 16-bit deep DIB.
1474 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*dstbits
,
1475 DWORD dstwidth
, DWORD srcwidth
,
1476 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
1481 /* align to 32 bit */
1482 DWORD linebytes
= (dstwidth
* 2 + 3) & ~3;
1487 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
1488 linebytes
= -linebytes
;
1491 switch ( bmpImage
->depth
)
1494 /* ==== 555 BGR bitmap to 555 BGR dib ==== */
1495 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
1496 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+= linebytes
)
1497 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, srcwidth
*2 );
1499 /* ==== 555 RGB bitmap to 555 BGR dib ==== */
1500 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
1502 LPDWORD srcpixel
, ptr
= (LPDWORD
)dstbits
;
1504 int div
= srcwidth
% 2;
1506 for (h
= lines
- 1; h
>= 0; h
--) {
1507 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1508 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1510 *ptr
++ = ((val
<< 10) & 0xf800f800) | (val
& 0x03e003e0) | /* Red & Green */
1511 ((val
>> 10) & 0x001f001f); /* Blue */
1513 if (div
!= 0) /* Odd width? */
1514 *ptr
= ((*(WORD
*)srcpixel
<< 1) & 0xffc0) | ((*(WORD
*)srcpixel
>> 4) & 0x0020) |
1515 (*(WORD
*)srcpixel
& 0x001f);
1516 ptr
= (LPDWORD
)(dstbits
+= linebytes
);
1519 else goto notsupported
;
1525 LPDWORD srcpixel
, ptr
= (LPDWORD
)dstbits
;
1527 int div
= srcwidth
% 2;
1529 /* ==== 565 BGR bitmap to 555 BGR dib ==== */
1530 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f )
1532 for (h
= lines
- 1; h
>= 0; h
--) {
1533 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1534 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1536 *ptr
++ = ((val
>> 1) & 0x7fe07fe0) | /* Red & Green */
1537 (val
& 0x001f001f); /* Blue */
1539 if (div
!= 0) /* Odd width? */
1540 *ptr
= ((*(WORD
*)srcpixel
>> 1) & 0x7fe0) | (*(WORD
*)srcpixel
& 0x001f);
1541 ptr
= (LPDWORD
) (dstbits
+= linebytes
);
1544 /* ==== 565 RGB bitmap to 555 BGR dib ==== */
1545 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
1547 for (h
= lines
- 1; h
>= 0; h
--) {
1548 srcpixel
= (LPDWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1549 for (x
= 0; x
< srcwidth
/2; x
++) { /* Do 2 pixels at a time */
1551 *ptr
++ = ((val
<< 10) & 0x7c007c00) | ((val
>> 1) & 0x03e003e0) | /* Red & Green */
1552 ((val
>> 11) & 0x001f001f); /* Blue */
1554 if (div
!= 0) /* Odd width? */
1555 *ptr
= ((*(WORD
*)srcpixel
>> 1) & 0x7fe0) | (*(WORD
*)srcpixel
& 0x001f);
1556 ptr
= (LPDWORD
) (dstbits
+= linebytes
);
1559 else goto notsupported
;
1567 LPWORD ptr
= (LPWORD
)dstbits
;
1570 /* ==== 24/32 BGR bitmap to 555 BGR dib ==== */
1571 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff)
1573 for (h
= lines
- 1; h
>= 0; h
--) {
1574 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1575 for (x
= 0; x
< srcwidth
; x
++, ptr
++) {
1577 *ptr
= ((val
>> 9) & 0x7c00) | /* Red */
1578 ((val
>> 6) & 0x03e0) | /* Green */
1579 ((val
>> 3) & 0x001f); /* Blue */
1581 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1584 /* ==== 24/32 RGB bitmap to 555 BGR dib ==== */
1585 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
1587 for (h
= lines
- 1; h
>= 0; h
--) {
1588 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1589 for (x
= 0; x
< srcwidth
; x
++, ptr
++) {
1591 *ptr
= ((val
<< 7) & 0x7c00) | /* Red */
1592 ((val
>> 6) & 0x03e0) | /* Green */
1593 ((val
>> 19) & 0x001f); /* Blue */
1595 ptr
= (LPWORD
) (dstbits
+= linebytes
);
1598 else goto notsupported
;
1603 /* ==== monochrome bitmap to 16 BGR dib ==== */
1605 /* ==== 4 colormap bitmap to 16 BGR dib ==== */
1606 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1608 LPWORD ptr
= (LPWORD
)dstbits
;
1611 for (h
= lines
- 1; h
>= 0; h
--) {
1612 for (x
= 0; x
< dstwidth
; x
++) {
1613 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
1614 *ptr
++ = ((val
.peRed
<< 7) & 0x7c00) |
1615 ((val
.peGreen
<< 2) & 0x03e0) |
1616 ((val
.peBlue
>> 3) & 0x001f);
1618 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1621 else goto notsupported
;
1626 /* ==== 8 colormap bitmap to 16 BGR dib ==== */
1627 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
1629 LPWORD ptr
= (LPWORD
)dstbits
;
1633 for (h
= lines
- 1; h
>= 0; h
--) {
1634 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
1635 for (x
= 0; x
< dstwidth
; x
++) {
1636 val
= srccolors
[(int)*srcpixel
++];
1637 *ptr
++ = ((val
.peRed
<< 7) & 0x7c00) |
1638 ((val
.peGreen
<< 2) & 0x03e0) |
1639 ((val
.peBlue
>> 3) & 0x001f);
1641 ptr
= (LPWORD
)(dstbits
+= linebytes
);
1644 else goto notsupported
;
1652 LPWORD ptr
= (LPWORD
)dstbits
;
1654 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 16 bit DIB\n",
1655 bmpImage
->depth
, (int)bmpImage
->red_mask
,
1656 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1657 for (h
= lines
- 1; h
>= 0; h
--)
1659 for (x
= 0; x
< dstwidth
; x
++, ptr
++)
1661 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
1662 r
= (BYTE
) GetRValue(pixel
);
1663 g
= (BYTE
) GetGValue(pixel
);
1664 b
= (BYTE
) GetBValue(pixel
);
1665 *ptr
= ( ((r
<< 7) & 0x7c00) | ((g
<< 2) & 0x03e0) | ((b
>> 3) & 0x001f) );
1667 ptr
= (LPWORD
) (dstbits
+= linebytes
);
1675 /***********************************************************************
1676 * X11DRV_DIB_SetImageBits_24
1678 * SetDIBits for a 24-bit deep DIB.
1680 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
1681 DWORD srcwidth
, DWORD dstwidth
, int left
,
1682 DC
*dc
, XImage
*bmpImage
)
1687 /* align to 32 bit */
1688 DWORD linebytes
= (srcwidth
* 3 + 3) & ~3;
1693 srcbits
= srcbits
+ linebytes
* (lines
- 1);
1694 linebytes
= -linebytes
;
1697 switch ( bmpImage
->depth
)
1702 if( bmpImage
->blue_mask
== 0xff && bmpImage
->red_mask
== 0xff0000 ) /* packed BGR to unpacked BGR */
1704 DWORD
*dstpixel
, val
, buf
;
1705 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1707 int div
= dstwidth
% 4;
1710 for(h
= lines
- 1; h
>= 0; h
--)
1712 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
*bmpImage
->bytes_per_line
+ left
*4);
1714 for (x
= 0; x
< dstwidth
/4; x
++) { /* do 3 dwords source, 4 dwords dest at a time */
1716 *dstpixel
++ = buf
&0x00ffffff; /* b1, g1, r1 */
1717 val
= (buf
>> 24); /* b2 */
1719 *dstpixel
++ = (val
| (buf
<<8)) &0x00ffffff; /* g2, r2 */
1720 val
= (buf
>> 16); /* b3, g3 */
1722 *dstpixel
++ = (val
| (buf
<<16)) &0x00ffffff; /* r3 */
1723 *dstpixel
++ = (buf
>> 8); /* b4, g4, r4 */
1725 for ( divk
=div
, bits
=(BYTE
*)ptr
; divk
>0; divk
--, bits
+=3 ) /* do remainder */
1727 *dstpixel
++ = *(DWORD
*)bits
& 0x00ffffff; /* b, g, r */
1729 ptr
= (DWORD
*)((srcbits
+=linebytes
)+left
*3);
1732 else if( bmpImage
->blue_mask
== 0xff0000 && bmpImage
->red_mask
== 0xff ) /* packed BGR to unpacked RGB */
1734 DWORD
*dstpixel
, val
, buf
;
1735 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3);
1737 int div
= dstwidth
% 4;
1740 for(h
= lines
- 1; h
>= 0; h
--)
1742 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
*bmpImage
->bytes_per_line
+ left
*4);
1744 for (x
= 0; x
< dstwidth
/4; x
++) { /* do 3 dwords source, 4 dwords dest at a time */
1746 *dstpixel
++ = ((buf
&0xff)<<16) | (buf
&0xff00) | ((buf
&0xff0000)>>16); /* b1, g1, r1 */
1747 val
= ((buf
&0xff000000)>>8); /* b2 */
1749 *dstpixel
++ = val
| ((buf
&0xff)<<8) | ((buf
&0xff00)>>8); /* g2, r2 */
1750 val
= (buf
&0xff0000) | ((buf
&0xff000000)>>16); /* b3, g3 */
1752 *dstpixel
++ = val
| (buf
&0xff); /* r3 */
1753 *dstpixel
++ = ((buf
&0xff00)<<8) | ((buf
&0xff0000)>>8) | (buf
>>24); /* b4, g4, r4 */
1755 for ( divk
=div
, bits
=(BYTE
*)ptr
; divk
>0; divk
--, bits
+=3 ) /* do remainder */
1757 buf
= *(DWORD
*)bits
;
1758 *dstpixel
++ = ((buf
&0xff)<<16) | (buf
&0xff00) | ((buf
&0xff0000)>>16); /* b, g, r */
1760 ptr
= (DWORD
*)((srcbits
+=linebytes
)+left
*3);
1770 if( bmpImage
->blue_mask
== 0x7c00 && bmpImage
->red_mask
== 0x1f ) /* BGR888 to RGB555 */
1772 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1775 int div
= dstwidth
% 4;
1778 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1779 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1780 for (x
= 0; x
< dstwidth
/4; x
++) {
1781 *dstpixel
++ = (WORD
)((((val
= *ptr
++) << 7) & 0x7c00) | ((val
>> 6) & 0x03e0) | ((val
>> 19) & 0x1f));
1782 *dstpixel
++ = (WORD
)(((val
>> 17) & 0x7c00) | (((val
= *ptr
++) << 2) & 0x03e0) | ((val
>> 11) & 0x1f));
1783 *dstpixel
++ = (WORD
)(((val
>> 9) & 0x07c00) | ((val
>> 22) & 0x03e0) | (((val
= *ptr
++) >> 3) & 0x1f));
1784 *dstpixel
++ = (WORD
)(((val
>> 1) & 0x07c00) | ((val
>> 14) & 0x03e0) | ((val
>> 27) & 0x1f));
1786 for (bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth not divisible by 4? */
1787 *dstpixel
++ = (((WORD
)bits
[0] << 7) & 0x07c00) |
1788 (((WORD
)bits
[1] << 2) & 0x03e0) |
1789 (((WORD
)bits
[2] >> 3) & 0x001f);
1790 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1793 else if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0x7c00 ) /* BGR888 to BGR555 */
1795 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1798 int div
= dstwidth
% 4;
1801 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1802 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1803 for (x
= 0; x
< dstwidth
/4; x
++) {
1804 *dstpixel
++ = (WORD
)((((val
= *ptr
++) >> 3) & 0x1f) | ((val
>> 6) & 0x03e0) | ((val
>> 9) & 0x7c00));
1805 *dstpixel
++ = (WORD
)(((val
>> 27) & 0x1f) | (((val
= *ptr
++) << 2) & 0x03e0) | ((val
>> 1) & 0x7c00));
1806 *dstpixel
++ = (WORD
)(((val
>> 19) & 0x1f) | ((val
>> 22) & 0x03e0) | (((val
= *ptr
++) << 7) & 0x7c00));
1807 *dstpixel
++ = (WORD
)(((val
>> 11) & 0x1f) | ((val
>> 14) & 0x03e0) | ((val
>> 17) & 0x7c00));
1809 for (bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth not divisible by 4? */
1810 *dstpixel
++ = (((WORD
)bits
[2] << 7) & 0x07c00) |
1811 (((WORD
)bits
[1] << 2) & 0x03e0) |
1812 (((WORD
)bits
[0] >> 3) & 0x001f);
1813 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1823 DWORD
*ptr
= (DWORD
*)(srcbits
+ left
*3), val
;
1826 int div
= dstwidth
% 4;
1829 if( bmpImage
->blue_mask
== 0x001f && bmpImage
->red_mask
== 0xf800 ) /* BGR888 to BGR565 */
1831 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1832 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1833 for (x
= 0; x
< dstwidth
/4; x
++) {
1834 *dstpixel
++ = (WORD
)((((val
= *ptr
++) >> 3) & 0x1f) | ((val
>> 5) & 0x07e0) | ((val
>> 8) & 0xf800));
1835 *dstpixel
++ = (WORD
)(((val
>> 27) & 0x1f) | (((val
= *ptr
++) << 3) & 0x07e0) | ((val
) & 0xf800));
1836 *dstpixel
++ = (WORD
)(((val
>> 19) & 0x1f) | ((val
>> 21) & 0x07e0) | (((val
= *ptr
++) << 8) & 0xf800));
1837 *dstpixel
++ = (WORD
)(((val
>> 11) & 0x1f) | ((val
>> 13) & 0x07e0) | ((val
>> 16) & 0xf800));
1839 for ( bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth is not divisible by 4? */
1840 *dstpixel
++ = (((WORD
)bits
[2] << 8) & 0xf800) |
1841 (((WORD
)bits
[1] << 3) & 0x07e0) |
1842 (((WORD
)bits
[0] >> 3) & 0x001f);
1843 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1846 else if( bmpImage
->blue_mask
== 0xf800 && bmpImage
->red_mask
== 0x001f ) /* BGR888 to RGB565 */
1848 for (h
= lines
- 1; h
>= 0; h
--) { /* Do 4 pixels at a time */
1849 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
+ left
*2);
1850 for (x
= 0; x
< dstwidth
/4; x
++) {
1851 *dstpixel
++ = (WORD
)((((val
= *ptr
++) << 8) & 0xf800) | ((val
>> 5) & 0x07e0) | ((val
>> 19) & 0x1f));
1852 *dstpixel
++ = (WORD
)(((val
>> 16) & 0xf800) | (((val
= *ptr
++) << 3) & 0x07e0) | ((val
>> 11) & 0x1f));
1853 *dstpixel
++ = (WORD
)(((val
>> 8) & 0xf800) | ((val
>> 21) & 0x07e0) | (((val
= *ptr
++) >> 3) & 0x1f));
1854 *dstpixel
++ = (WORD
)((val
& 0xf800) | ((val
>> 13) & 0x07e0) | ((val
>> 27) & 0x1f));
1856 for ( bits
= (LPBYTE
)ptr
, divk
=div
; divk
> 0; divk
--, bits
+=3) /* dstwidth is not divisible by 4? */
1857 *dstpixel
++ = (((WORD
)bits
[0] << 8) & 0xf800) |
1858 (((WORD
)bits
[1] << 3) & 0x07e0) |
1859 (((WORD
)bits
[2] >> 3) & 0x001f);
1860 ptr
= (DWORD
*)((srcbits
+= linebytes
) + left
* 3);
1872 LPBYTE bits
= (LPBYTE
)srcbits
+ left
*3;
1874 for (h
= lines
- 1; h
>= 0; h
--) {
1875 for (x
= left
; x
< dstwidth
+left
; x
++, bits
+=3)
1876 XPutPixel( bmpImage
, x
, h
,
1877 X11DRV_PALETTE_ToPhysical(dc
, RGB(bits
[2], bits
[1], bits
[0])));
1878 bits
= (LPBYTE
)(srcbits
+= linebytes
) + left
* 3;
1885 FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
1886 bmpImage
->bits_per_pixel
, (int)bmpImage
->red_mask
,
1887 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
1893 /***********************************************************************
1894 * X11DRV_DIB_GetImageBits_24
1896 * GetDIBits for an 24-bit deep DIB.
1898 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*dstbits
,
1899 DWORD dstwidth
, DWORD srcwidth
,
1900 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
1905 /* align to 32 bit */
1906 DWORD linebytes
= (dstwidth
* 3 + 3) & ~3;
1911 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
1912 linebytes
= -linebytes
;
1915 switch ( bmpImage
->depth
)
1920 DWORD
*srcpixel
, buf
;
1922 DWORD
*ptr
=(DWORD
*)dstbits
;
1923 int quotient
= dstwidth
/ 4;
1924 int remainder
= dstwidth
% 4;
1927 /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
1928 if( bmpImage
->blue_mask
== 0xff && bmpImage
->red_mask
== 0xff0000 )
1930 for(h
= lines
- 1; h
>= 0; h
--)
1932 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1934 for (x
= 0; x
< quotient
; x
++) { /* do 4 dwords source, 3 dwords dest at a time*/
1935 buf
= ((*srcpixel
++)&0x00ffffff); /* b1, g1, r1*/
1936 *ptr
++ = buf
| ((*srcpixel
)<<24); /* b2 */
1937 buf
= ((*srcpixel
++>>8)&0x0000ffff); /* g2, r2 */
1938 *ptr
++ = buf
| ((*srcpixel
)<<16); /* b3, g3 */
1939 buf
= ((*srcpixel
++>>16)&0x000000ff); /* r3 */
1940 *ptr
++ = buf
| ((*srcpixel
++)<<8); /* b4, g4, r4 */
1942 for ( remk
=remainder
, bits
=(BYTE
*)ptr
; remk
>0; remk
--, bits
+=3 ) /* do remainder */
1945 *(WORD
*)bits
= buf
; /* b, g */
1946 *(bits
+2) = buf
>>16; /* r */
1948 ptr
= (DWORD
*)(dstbits
+=linebytes
);
1952 /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
1953 else if( bmpImage
->blue_mask
== 0xff0000 && bmpImage
->red_mask
== 0xff )
1955 for(h
= lines
- 1; h
>= 0; h
--)
1957 srcpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1959 for (x
= 0; x
< quotient
; x
++) { /* do 4 dwords source, 3 dwords dest at a time */
1961 val
= ((buf
&0xff0000)>>16) | (buf
&0xff00) | ((buf
&0xff)<<16); /* b1, g1, r1 */
1963 *ptr
++ = val
| ((buf
&0xff0000)<<8); /* b2 */
1964 val
= ((buf
&0xff00)>>8) | ((buf
&0xff)<<8); /* g2, r2 */
1966 *ptr
++ = val
| (buf
&0xff0000) | ((buf
&0xff00)<<16); /* b3, g3 */
1967 val
= (buf
&0xff); /* r3 */
1969 *ptr
++ = val
| ((buf
&0xff0000)>>8) | ((buf
&0xff00)<<8) | (buf
<<24); /* b4, g4, r4 */
1971 for ( remk
=remainder
, bits
=(BYTE
*)ptr
; remk
>0; remk
--, bits
+=3 ) /* do remainder */
1974 *(WORD
*)bits
= (buf
&0xff00) | ((buf
&0xff0000)>>16) ; /* b, g */
1975 *(bits
+2) = buf
; /* r */
1977 ptr
= (DWORD
*)(dstbits
+=linebytes
);
1980 else goto notsupported
;
1987 LPBYTE bits
= dstbits
;
1990 /* ==== 555 BGR bitmap to 24 BGR dib ==== */
1991 if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0x7c00 )
1993 for (h
= lines
- 1; h
>= 0; h
--) {
1994 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
1995 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
1997 bits
[2] = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
1998 bits
[1] = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07)); /*Green*/
1999 bits
[0] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2001 bits
= (dstbits
+= linebytes
);
2004 /* ==== 555 RGB bitmap to 24 RGB dib==== */
2005 else if( bmpImage
->blue_mask
== 0x7c00 && bmpImage
->red_mask
== 0x1f )
2007 for (h
= lines
- 1; h
>= 0; h
--) {
2008 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2009 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2011 bits
[0] = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2012 bits
[1] = (BYTE
)(((val
>> 2) & 0xf8) | ((val
>> 7) & 0x07)); /*Green*/
2013 bits
[2] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2015 bits
= (dstbits
+= linebytes
);
2018 else goto notsupported
;
2025 LPBYTE bits
= dstbits
;
2028 /* ==== 565 BGR bitmap to 24 BGR dib ==== */
2029 if( bmpImage
->blue_mask
== 0x1f && bmpImage
->red_mask
== 0xf800 )
2031 for (h
= lines
- 1; h
>= 0; h
--) {
2032 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2033 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2035 bits
[2] = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2036 bits
[1] = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2037 bits
[0] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2039 bits
= (dstbits
+= linebytes
);
2042 /* ==== 565 RGB bitmap to 24 BGR dib ==== */
2043 else if( bmpImage
->blue_mask
== 0xf800 && bmpImage
->red_mask
== 0x1f )
2045 for (h
= lines
- 1; h
>= 0; h
--) {
2046 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2047 for (x
= 0; x
< srcwidth
; x
++, bits
+= 3) {
2049 bits
[0] = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2050 bits
[1] = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2051 bits
[2] = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x07)); /*Blue*/
2053 bits
= (dstbits
+= linebytes
);
2056 else goto notsupported
;
2061 /* ==== monochrome bitmap to 24 BGR dib ==== */
2063 /* ==== 4 colormap bitmap to 24 BGR dib ==== */
2064 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2066 LPBYTE bits
= dstbits
;
2069 for (h
= lines
- 1; h
>= 0; h
--) {
2070 for (x
= 0; x
< dstwidth
; x
++) {
2071 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
2072 *bits
++ = val
.peBlue
;
2073 *bits
++ = val
.peGreen
;
2074 *bits
++ = val
.peRed
;
2076 bits
= (dstbits
+= linebytes
);
2079 else goto notsupported
;
2084 /* ==== 8 colormap bitmap to 24 BGR dib ==== */
2085 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
== 0 && srccolors
)
2088 LPBYTE bits
= dstbits
;
2091 for (h
= lines
- 1; h
>= 0; h
--) {
2092 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
2093 for (x
= 0; x
< dstwidth
; x
++ ) {
2094 val
= srccolors
[(int)*srcpixel
++];
2095 *bits
++ = val
.peBlue
; /*Blue*/
2096 *bits
++ = val
.peGreen
; /*Green*/
2097 *bits
++ = val
.peRed
; /*Red*/
2099 bits
= (dstbits
+= linebytes
);
2102 else goto notsupported
;
2109 LPBYTE bits
= dstbits
;
2111 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
2112 bmpImage
->depth
, (int)bmpImage
->red_mask
,
2113 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2114 for (h
= lines
- 1; h
>= 0; h
--)
2116 for (x
= 0; x
< dstwidth
; x
++, bits
+= 3)
2118 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
2119 bits
[0] = GetBValue(pixel
);
2120 bits
[1] = GetGValue(pixel
);
2121 bits
[2] = GetRValue(pixel
);
2123 bits
= (dstbits
+= linebytes
);
2131 /***********************************************************************
2132 * X11DRV_DIB_SetImageBits_32
2134 * SetDIBits for a 32-bit deep DIB.
2136 static void X11DRV_DIB_SetImageBits_32( int lines
, const BYTE
*srcbits
,
2137 DWORD srcwidth
, DWORD dstwidth
, int left
,
2138 DC
*dc
, XImage
*bmpImage
)
2143 DWORD linebytes
= (srcwidth
* 4);
2148 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
2149 linebytes
= -linebytes
;
2152 ptr
= (DWORD
*) srcbits
+ left
;
2154 switch ( bmpImage
->depth
)
2158 /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
2159 if (bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff) {
2160 for (h
= lines
- 1; h
>= 0; h
--, srcbits
+=linebytes
) {
2161 memcpy( bmpImage
->data
+ h
* bmpImage
->bytes_per_line
, srcbits
+ left
*4, dstwidth
*4 );
2165 /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
2166 else if (bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000)
2170 for (h
= lines
- 1; h
>= 0; h
--) {
2171 dstpixel
= (DWORD
*) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2172 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2173 *dstpixel
++ = ((*ptr
<< 16) & 0xff0000) | (*ptr
& 0xff00) | ((*ptr
>> 16) & 0xff);
2175 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2178 else goto notsupported
;
2183 /* ==== 32 BGR dib to 555 BGR bitmap ==== */
2184 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
2188 for (h
= lines
- 1; h
>= 0; h
--) {
2189 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2190 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2191 *dstpixel
++ = (WORD
) (((*ptr
>> 9) & 0x7c00) | ((*ptr
>> 6) & 0x03e0) | ((*ptr
>> 3) & 0x001f));
2193 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2196 /* ==== 32 BGR dib to 555 RGB bitmap ==== */
2197 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
2201 for (h
= lines
- 1; h
>= 0; h
--) {
2202 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2203 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2204 *dstpixel
++ = (WORD
) (((*ptr
<< 7) & 0x7c00) | ((*ptr
>> 6) & 0x03e0) | ((*ptr
>> 19) & 0x001f));
2206 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2209 else goto notsupported
;
2214 /* ==== 32 BGR dib to 565 BGR bitmap ==== */
2215 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2219 for (h
= lines
- 1; h
>= 0; h
--) {
2220 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2221 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2222 *dstpixel
++ = (WORD
) (((*ptr
>> 8) & 0xf800) | ((*ptr
>> 5) & 0x07e0) | ((*ptr
>> 3) & 0x001f));
2224 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2227 /* ==== 32 BGR dib to 565 RGB bitmap ==== */
2228 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0xf800)
2232 for (h
= lines
- 1; h
>= 0; h
--) {
2233 dstpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2234 for (x
= 0; x
< dstwidth
; x
++, ptr
++) {
2235 *dstpixel
++ = (WORD
) (((*ptr
<< 8) & 0xf800) | ((*ptr
>> 5) & 0x07e0) | ((*ptr
>> 19) & 0x001f));
2237 ptr
= (DWORD
*) (srcbits
+= linebytes
) + left
;
2240 else goto notsupported
;
2248 LPBYTE bits
= (LPBYTE
)srcbits
+ left
*4;
2250 for (h
= lines
- 1; h
>= 0; h
--) {
2251 for (x
= left
; x
< dstwidth
+left
; x
++, bits
+= 4)
2252 XPutPixel( bmpImage
, x
, h
,
2253 X11DRV_PALETTE_ToPhysical(dc
, RGB( bits
[2], bits
[1], *bits
)));
2254 bits
= (LPBYTE
)(srcbits
+= linebytes
) + left
* 4;
2261 FIXME("32 bit DIB %d bit bitmap\n", bmpImage
->bits_per_pixel
);
2267 /***********************************************************************
2268 * X11DRV_DIB_GetImageBits_32
2270 * GetDIBits for an 32-bit deep DIB.
2272 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*dstbits
,
2273 DWORD dstwidth
, DWORD srcwidth
,
2274 PALETTEENTRY
*srccolors
, XImage
*bmpImage
)
2280 /* align to 32 bit */
2281 DWORD linebytes
= (srcwidth
* 4);
2282 DWORD copybytes
= linebytes
;
2287 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2288 linebytes
= -linebytes
;
2293 switch ( bmpImage
->depth
)
2297 /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
2298 if ( bmpImage
->red_mask
== 0xff0000 && bmpImage
->blue_mask
== 0xff )
2299 for (h
= lines
- 1; h
>= 0; h
--, dstbits
+=linebytes
)
2300 memcpy( dstbits
, bmpImage
->data
+ h
*bmpImage
->bytes_per_line
, copybytes
);
2302 /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
2303 else if ( bmpImage
->red_mask
== 0xff && bmpImage
->blue_mask
== 0xff0000 )
2307 for (h
= lines
- 1; h
>= 0; h
--) {
2308 srcbits
= bmpImage
->data
+ h
* bmpImage
->bytes_per_line
;
2309 for (x
= 0; x
< dstwidth
; x
++, bits
+=4, srcbits
+=2) {
2310 *(bits
+ 2) = *srcbits
++;
2311 *(bits
+ 1) = *srcbits
++;
2314 bits
= (dstbits
+= linebytes
);
2317 else goto notsupported
;
2325 /* ==== 555 BGR bitmap to 32 BGR dib ==== */
2326 if (bmpImage
->red_mask
== 0x7c00 && bmpImage
->blue_mask
== 0x001f)
2328 for (h
= lines
- 1; h
>= 0; h
--) {
2329 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2330 for (x
= 0; x
< dstwidth
; x
++, bits
+=2) {
2332 *bits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Blue*/
2333 *bits
++ = (BYTE
)(((val
>> 2) & 0xfc) | ((val
>> 8) & 0x03)); /*Green*/
2334 *bits
= (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07)); /*Red*/
2336 bits
= (dstbits
+= linebytes
);
2339 /* ==== 555 RGB bitmap to 32 BGR dib ==== */
2340 else if (bmpImage
->red_mask
== 0x001f && bmpImage
->blue_mask
== 0x7c00)
2342 for (h
= lines
- 1; h
>= 0; h
--) {
2343 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2344 for (x
= 0; x
< dstwidth
; x
++, bits
+=2) {
2346 *bits
++ = (BYTE
)(((val
>> 7) & 0xf8) | ((val
>> 12) & 0x07));/*Blue*/
2347 *bits
++ = (BYTE
)(((val
>> 2) & 0xfc) | ((val
>> 8) & 0x03)); /*Green*/
2348 *bits
= (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Red*/
2350 bits
= (dstbits
+= linebytes
);
2353 else goto notsupported
;
2362 /* ==== 565 BGR bitmap to 32 BGR dib ==== */
2363 if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2365 for (h
= lines
- 1; h
>= 0; h
--) {
2366 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2367 for (x
= 0; x
< srcwidth
; x
++, bits
+=2) {
2369 *bits
++ = (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Blue*/
2370 *bits
++ = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2371 *bits
= (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07)); /*Red*/
2373 bits
= (dstbits
+= linebytes
);
2376 /* ==== 565 RGB bitmap to 32 BGR dib ==== */
2377 else if (bmpImage
->red_mask
== 0xf800 && bmpImage
->blue_mask
== 0x001f)
2379 for (h
= lines
- 1; h
>= 0; h
--) {
2380 srcpixel
= (LPWORD
) (bmpImage
->data
+ h
* bmpImage
->bytes_per_line
);
2381 for (x
= 0; x
< srcwidth
; x
++, bits
+=2) {
2383 *bits
++ = (BYTE
)(((val
>> 8) & 0xf8) | ((val
>> 13) & 0x07));/*Blue*/
2384 *bits
++ = (BYTE
)(((val
>> 3) & 0xfc) | ((val
>> 9) & 0x03)); /*Green*/
2385 *bits
= (BYTE
)(((val
<< 3) & 0xf8) | ((val
>> 2) & 0x03)); /*Red*/
2387 bits
= (dstbits
+= linebytes
);
2390 else goto notsupported
;
2395 /* ==== monochrome bitmap to 32 BGR dib ==== */
2397 /* ==== 4 colormap bitmap to 32 BGR dib ==== */
2398 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2402 for (h
= lines
- 1; h
>= 0; h
--) {
2403 for (x
= 0; x
< dstwidth
; x
++) {
2404 val
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
2405 *bits
++ = val
.peBlue
;
2406 *bits
++ = val
.peGreen
;
2407 *bits
++ = val
.peRed
;
2410 bits
= (dstbits
+= linebytes
);
2413 else goto notsupported
;
2418 /* ==== 8 colormap bitmap to 32 BGR dib ==== */
2419 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
)
2424 for (h
= lines
- 1; h
>= 0; h
--) {
2425 srcpixel
= bmpImage
->data
+ h
*bmpImage
->bytes_per_line
;
2426 for (x
= 0; x
< dstwidth
; x
++) {
2427 val
= srccolors
[(int)*srcpixel
++];
2428 *bits
++ = val
.peBlue
; /*Blue*/
2429 *bits
++ = val
.peGreen
; /*Green*/
2430 *bits
++ = val
.peRed
; /*Red*/
2433 bits
= (dstbits
+= linebytes
);
2436 else goto notsupported
;
2441 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
2442 bmpImage
->depth
, (int)bmpImage
->red_mask
,
2443 (int)bmpImage
->green_mask
, (int)bmpImage
->blue_mask
);
2444 for (h
= lines
- 1; h
>= 0; h
--)
2446 for (x
= 0; x
< dstwidth
; x
++, bits
+= 4)
2448 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
2449 bits
[0] = GetBValue(pixel
);
2450 bits
[1] = GetGValue(pixel
);
2451 bits
[2] = GetRValue(pixel
);
2453 bits
= (dstbits
+= linebytes
);
2459 /***********************************************************************
2460 * X11DRV_DIB_SetImageBits
2462 * Transfer the bits to an X image.
2463 * Helper function for SetDIBits() and SetDIBitsToDevice().
2464 * The Xlib critical section must be entered before calling this function.
2466 int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
2468 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
2471 if ( descr
->dc
&& descr
->dc
->w
.flags
& DC_DIRTY
)
2472 CLIPPING_UpdateGCRegion( descr
->dc
);
2475 bmpImage
= descr
->image
;
2477 bmpImage
= XCreateImage( display
,
2478 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2479 descr
->depth
, ZPixmap
, 0, NULL
,
2480 descr
->infoWidth
, lines
, 32, 0 );
2481 bmpImage
->data
= xcalloc( bmpImage
->bytes_per_line
* lines
);
2484 /* Transfer the pixels */
2485 switch(descr
->infoBpp
)
2488 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
2489 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
2493 if (descr
->compression
) {
2494 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2495 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2496 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2498 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
2499 descr
->infoWidth
, descr
->width
,
2500 descr
->xSrc
, (int *)(descr
->colorMap
),
2503 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
2504 descr
->infoWidth
, descr
->width
,
2505 descr
->xSrc
, (int*)(descr
->colorMap
),
2509 if (descr
->compression
) {
2510 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2511 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2512 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2513 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
2514 descr
->infoWidth
, descr
->width
,
2515 descr
->xSrc
, (int *)(descr
->colorMap
),
2518 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
2519 descr
->infoWidth
, descr
->width
,
2520 descr
->xSrc
, (int *)(descr
->colorMap
),
2525 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
2526 descr
->infoWidth
, descr
->width
,
2527 descr
->xSrc
, descr
->dc
,
2528 descr
->rMask
, descr
->gMask
, descr
->bMask
,
2532 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
2533 descr
->infoWidth
, descr
->width
,
2534 descr
->xSrc
, descr
->dc
, bmpImage
);
2537 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
2538 descr
->infoWidth
, descr
->width
,
2539 descr
->xSrc
, descr
->dc
,
2543 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
2549 XShmPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
2550 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2551 descr
->width
, descr
->height
, FALSE
);
2552 XSync( display
, 0 );
2555 XPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
2556 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
2557 descr
->width
, descr
->height
);
2559 if (!descr
->image
) XDestroyImage( bmpImage
);
2563 /***********************************************************************
2564 * X11DRV_DIB_GetImageBits
2566 * Transfer the bits from an X image.
2567 * The Xlib critical section must be entered before calling this function.
2569 int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
2571 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
2575 bmpImage
= descr
->image
;
2577 bmpImage
= XCreateImage( display
,
2578 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2579 descr
->depth
, ZPixmap
, 0, NULL
,
2580 descr
->infoWidth
, lines
, 32, 0 );
2581 bmpImage
->data
= xcalloc( bmpImage
->bytes_per_line
* lines
);
2584 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
2585 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
2586 bmpImage
, descr
->xSrc
, descr
->ySrc
);
2588 /* Transfer the pixels */
2589 switch(descr
->infoBpp
)
2592 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
2593 descr
->infoWidth
, descr
->width
,
2594 descr
->colorMap
, descr
->palentry
,
2599 if (descr
->compression
)
2600 FIXME("Compression not yet supported!\n");
2602 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
2603 descr
->infoWidth
, descr
->width
,
2604 descr
->colorMap
, descr
->palentry
,
2609 if (descr
->compression
)
2610 FIXME("Compression not yet supported!\n");
2612 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
2613 descr
->infoWidth
, descr
->width
,
2614 descr
->colorMap
, descr
->palentry
,
2619 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
2620 descr
->infoWidth
,descr
->width
,
2621 descr
->palentry
, bmpImage
);
2625 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
2626 descr
->infoWidth
,descr
->width
,
2627 descr
->palentry
, bmpImage
);
2631 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
2632 descr
->infoWidth
, descr
->width
,
2633 descr
->palentry
, bmpImage
);
2637 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
2641 if (!descr
->image
) XDestroyImage( bmpImage
);
2645 /*************************************************************************
2646 * X11DRV_SetDIBitsToDevice
2649 INT
X11DRV_SetDIBitsToDevice( DC
*dc
, INT xDest
, INT yDest
, DWORD cx
,
2650 DWORD cy
, INT xSrc
, INT ySrc
,
2651 UINT startscan
, UINT lines
, LPCVOID bits
,
2652 const BITMAPINFO
*info
, UINT coloruse
)
2654 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2655 DWORD width
, oldcy
= cy
;
2657 int height
, tmpheight
;
2658 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
2661 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
2662 &descr
.infoBpp
, &descr
.compression
) == -1)
2665 if (height
< 0) height
= -height
;
2666 if (!lines
|| (startscan
>= height
)) return 0;
2667 if (startscan
+ lines
> height
) lines
= height
- startscan
;
2668 if (ySrc
< startscan
) ySrc
= startscan
;
2669 else if (ySrc
>= startscan
+ lines
) return 0;
2670 if (xSrc
>= width
) return 0;
2671 if (ySrc
+ cy
>= startscan
+ lines
) cy
= startscan
+ lines
- ySrc
;
2672 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
2673 if (!cx
|| !cy
) return 0;
2675 X11DRV_SetupGCForText( dc
); /* To have the correct colors */
2676 TSXSetFunction(display
, physDev
->gc
, X11DRV_XROPfunction
[dc
->w
.ROPmode
-1]);
2678 switch (descr
.infoBpp
)
2683 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
2684 coloruse
== DIB_PAL_COLORS
? dc
: NULL
, coloruse
,
2685 dc
->w
.bitsPerPixel
, info
, &descr
.nColorMap
);
2686 if (!descr
.colorMap
) return 0;
2687 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2691 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2692 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2693 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2698 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2703 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2704 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2705 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2713 descr
.palentry
= NULL
;
2714 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
2715 descr
.infoWidth
= width
;
2716 descr
.depth
= dc
->w
.bitsPerPixel
;
2717 descr
.drawable
= physDev
->drawable
;
2718 descr
.gc
= physDev
->gc
;
2720 descr
.ySrc
= tmpheight
>= 0 ? lines
-(ySrc
-startscan
)-cy
+(oldcy
-cy
)
2722 descr
.xDest
= dc
->w
.DCOrgX
+ XLPTODP( dc
, xDest
);
2723 descr
.yDest
= dc
->w
.DCOrgY
+ YLPTODP( dc
, yDest
) +
2724 (tmpheight
>= 0 ? oldcy
-cy
: 0);
2727 descr
.useShm
= FALSE
;
2729 EnterCriticalSection( &X11DRV_CritSection
);
2730 result
= CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
2731 LeaveCriticalSection( &X11DRV_CritSection
);
2733 if (descr
.infoBpp
<= 8)
2734 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
2738 /***********************************************************************
2739 * X11DRV_DIB_SetDIBits
2741 INT
X11DRV_DIB_SetDIBits(
2742 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
2743 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
,
2744 UINT coloruse
, HBITMAP hbitmap
)
2746 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2747 X11DRV_PHYSBITMAP
*pbitmap
;
2748 int height
, tmpheight
;
2753 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
2754 &descr
.infoBpp
, &descr
.compression
) == -1)
2758 if (height
< 0) height
= -height
;
2759 if (!lines
|| (startscan
>= height
))
2762 if (startscan
+ lines
> height
) lines
= height
- startscan
;
2764 switch (descr
.infoBpp
)
2769 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
2770 coloruse
== DIB_PAL_COLORS
? descr
.dc
: NULL
, coloruse
,
2771 bmp
->bitmap
.bmBitsPixel
,
2772 info
, &descr
.nColorMap
);
2773 if (!descr
.colorMap
) return 0;
2774 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2778 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2779 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2780 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2785 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2790 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2791 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2792 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2801 X11DRV_CreateBitmap(hbitmap
);
2803 pbitmap
= bmp
->DDBitmap
->physBitmap
;
2807 descr
.palentry
= NULL
;
2808 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
2809 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
2810 descr
.drawable
= pbitmap
->pixmap
;
2811 descr
.gc
= BITMAP_GC(bmp
);
2815 descr
.yDest
= height
- startscan
- lines
;
2816 descr
.width
= bmp
->bitmap
.bmWidth
;
2817 descr
.height
= lines
;
2818 descr
.useShm
= FALSE
;
2820 EnterCriticalSection( &X11DRV_CritSection
);
2821 result
= CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
2822 LeaveCriticalSection( &X11DRV_CritSection
);
2824 if (descr
.colorMap
) HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
2829 /***********************************************************************
2830 * X11DRV_DIB_GetDIBits
2832 INT
X11DRV_DIB_GetDIBits(
2833 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
2834 UINT lines
, LPVOID bits
, BITMAPINFO
*info
,
2835 UINT coloruse
, HBITMAP hbitmap
)
2837 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
2838 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2839 X11DRV_PHYSBITMAP
*pbitmap
;
2840 PALETTEOBJ
* palette
;
2842 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
2843 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
2844 (int)info
->bmiHeader
.biWidth
, (int)info
->bmiHeader
.biHeight
,
2847 if (!(palette
= (PALETTEOBJ
*)GDI_GetObjPtr( dc
->w
.hPalette
, PALETTE_MAGIC
)))
2850 if( lines
> info
->bmiHeader
.biHeight
) lines
= info
->bmiHeader
.biHeight
;
2851 if( startscan
>= bmp
->bitmap
.bmHeight
) return FALSE
;
2853 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &descr
.lines
,
2854 &descr
.infoBpp
, &descr
.compression
) == -1)
2857 switch (descr
.infoBpp
)
2863 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2867 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
2868 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
2869 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
2873 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
2874 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0xff00;
2875 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0xff;
2881 X11DRV_CreateBitmap(hbitmap
);
2883 pbitmap
= bmp
->DDBitmap
->physBitmap
;
2886 descr
.palentry
= palette
->logpalette
.palPalEntry
;
2888 descr
.lines
= lines
;
2889 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
2890 descr
.drawable
= pbitmap
->pixmap
;
2891 descr
.gc
= BITMAP_GC(bmp
);
2893 descr
.ySrc
= startscan
;
2896 descr
.width
= bmp
->bitmap
.bmWidth
;
2897 descr
.height
= bmp
->bitmap
.bmHeight
;
2898 descr
.colorMap
= info
->bmiColors
;
2901 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
2903 descr
.useShm
= FALSE
;
2905 EnterCriticalSection( &X11DRV_CritSection
);
2907 descr
.image
= (XImage
*)CALL_LARGE_STACK( X11DRV_BITMAP_GetXImage
, bmp
);
2908 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits
, &descr
);
2910 LeaveCriticalSection( &X11DRV_CritSection
);
2912 if(info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
2913 info
->bmiHeader
.biSizeImage
= DIB_GetDIBImageBytes(
2914 info
->bmiHeader
.biWidth
,
2915 info
->bmiHeader
.biHeight
,
2916 info
->bmiHeader
.biBitCount
);
2918 info
->bmiHeader
.biCompression
= 0;
2920 GDI_HEAP_UNLOCK( dc
->w
.hPalette
);
2925 /***********************************************************************
2926 * DIB_DoProtectDIBSection
2928 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
2930 DIBSECTION
*dib
= bmp
->dib
;
2931 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
2932 : -dib
->dsBm
.bmHeight
;
2933 INT totalSize
= dib
->dsBmih
.biSizeImage
? dib
->dsBmih
.biSizeImage
2934 : dib
->dsBm
.bmWidthBytes
* effHeight
;
2937 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
2938 TRACE("Changed protection from %ld to %ld\n", old_prot
, new_prot
);
2941 /***********************************************************************
2942 * X11DRV_DIB_DoUpdateDIBSection
2944 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
2946 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
2947 X11DRV_DIB_IMAGEBITS_DESCR descr
;
2949 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, &descr
.lines
,
2950 &descr
.infoBpp
, &descr
.compression
) == -1)
2954 descr
.palentry
= NULL
;
2955 descr
.image
= dib
->image
;
2956 descr
.colorMap
= (RGBQUAD
*)dib
->colorMap
;
2957 descr
.nColorMap
= dib
->nColorMap
;
2958 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
2959 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
2961 switch (descr
.infoBpp
)
2967 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
2971 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0x7c00;
2972 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x03e0;
2973 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x001f;
2977 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0xff;
2978 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0xff00;
2979 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0xff0000;
2984 descr
.drawable
= ((X11DRV_PHYSBITMAP
*)bmp
->DDBitmap
->physBitmap
)->pixmap
;
2985 descr
.gc
= BITMAP_GC(bmp
);
2990 descr
.width
= bmp
->bitmap
.bmWidth
;
2991 descr
.height
= bmp
->bitmap
.bmHeight
;
2992 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
2996 TRACE("Copying from Pixmap to DIB bits\n");
2997 EnterCriticalSection( &X11DRV_CritSection
);
2998 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits
, &descr
);
2999 LeaveCriticalSection( &X11DRV_CritSection
);
3003 TRACE("Copying from DIB bits to Pixmap\n");
3004 EnterCriticalSection( &X11DRV_CritSection
);
3005 CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
3006 LeaveCriticalSection( &X11DRV_CritSection
);
3010 /***********************************************************************
3011 * X11DRV_DIB_FaultHandler
3013 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
3015 BOOL handled
= FALSE
;
3018 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
3019 if (!bmp
) return FALSE
;
3022 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3024 case X11DRV_DIB_GdiMod
:
3025 TRACE("called in status DIB_GdiMod\n" );
3026 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3027 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3028 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3029 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_InSync
;
3033 case X11DRV_DIB_InSync
:
3034 TRACE("called in status X11DRV_DIB_InSync\n" );
3035 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
3036 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_AppMod
;
3040 case X11DRV_DIB_AppMod
:
3041 FIXME("called in status X11DRV_DIB_AppMod: this can't happen!\n" );
3044 case X11DRV_DIB_NoHandler
:
3045 FIXME("called in status DIB_NoHandler: this can't happen!\n" );
3049 GDI_HEAP_UNLOCK( (HBITMAP
)res
);
3053 /***********************************************************************
3054 * X11DRV_DIB_UpdateDIBSection
3056 void X11DRV_DIB_UpdateDIBSection(DC
*dc
, BOOL toDIB
)
3060 /* Ensure this is a Compatible DC that has a DIB section selected */
3063 if (!(dc
->w
.flags
& DC_MEMORY
)) return;
3065 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( dc
->w
.hBitmap
, BITMAP_MAGIC
);
3070 GDI_HEAP_UNLOCK(dc
->w
.hBitmap
);
3076 /* Prepare for access to the DIB by GDI functions */
3078 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3081 case X11DRV_DIB_NoHandler
:
3082 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
3085 case X11DRV_DIB_GdiMod
:
3086 TRACE("fromDIB called in status X11DRV_DIB_GdiMod\n" );
3090 case X11DRV_DIB_InSync
:
3091 TRACE("fromDIB called in status X11DRV_DIB_InSync\n" );
3095 case X11DRV_DIB_AppMod
:
3096 TRACE("fromDIB called in status X11DRV_DIB_AppMod\n" );
3097 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
3098 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3099 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_InSync
;
3105 /* Acknowledge write access to the DIB by GDI functions */
3107 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
3110 case X11DRV_DIB_NoHandler
:
3111 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
3114 case X11DRV_DIB_GdiMod
:
3115 TRACE(" toDIB called in status X11DRV_DIB_GdiMod\n" );
3119 case X11DRV_DIB_InSync
:
3120 TRACE(" toDIB called in status X11DRV_DIB_InSync\n" );
3121 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
3122 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_GdiMod
;
3125 case X11DRV_DIB_AppMod
:
3126 FIXME(" toDIB called in status X11DRV_DIB_AppMod: "
3127 "this can't happen!\n" );
3132 GDI_HEAP_UNLOCK(dc
->w
.hBitmap
);
3135 /***********************************************************************
3136 * X11DRV_DIB_CreateDIBSection16
3138 HBITMAP16
X11DRV_DIB_CreateDIBSection16(
3139 DC
*dc
, BITMAPINFO
*bmi
, UINT16 usage
,
3140 SEGPTR
*bits
, HANDLE section
,
3143 HBITMAP res
= X11DRV_DIB_CreateDIBSection(dc
, bmi
, usage
, NULL
,
3147 BITMAPOBJ
*bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
3148 if ( bmp
&& bmp
->dib
)
3150 DIBSECTION
*dib
= bmp
->dib
;
3151 INT height
= dib
->dsBm
.bmHeight
>= 0 ?
3152 dib
->dsBm
.bmHeight
: -dib
->dsBm
.bmHeight
;
3153 INT size
= dib
->dsBmih
.biSizeImage
?
3154 dib
->dsBmih
.biSizeImage
: dib
->dsBm
.bmWidthBytes
* height
;
3155 if ( dib
->dsBm
.bmBits
)
3157 ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
=
3158 SELECTOR_AllocBlock( dib
->dsBm
.bmBits
, size
,
3159 SEGMENT_DATA
, FALSE
, FALSE
);
3161 TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
3162 dib
->dsBm
.bmBits
, size
, ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
,
3163 PTR_SEG_OFF_TO_SEGPTR(((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
, 0));
3165 GDI_HEAP_UNLOCK( res
);
3168 *bits
= PTR_SEG_OFF_TO_SEGPTR( ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
, 0 );
3174 /***********************************************************************
3175 * X11DRV_XShmErrorHandler
3178 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
)
3184 /***********************************************************************
3185 * X11DRV_XShmCreateImage
3189 extern BOOL
X11DRV_XShmCreateImage(XImage
** image
, int width
, int height
, int bpp
,
3190 XShmSegmentInfo
* shminfo
)
3192 int (*WineXHandler
)(Display
*, XErrorEvent
*);
3194 *image
= TSXShmCreateImage(display
, DefaultVisualOfScreen(X11DRV_GetXScreen()),
3195 bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
3196 if( *image
!= NULL
)
3198 EnterCriticalSection( &X11DRV_CritSection
);
3199 shminfo
->shmid
= shmget(IPC_PRIVATE
, (*image
)->bytes_per_line
* height
,
3201 if( shminfo
->shmid
!= -1 )
3203 shminfo
->shmaddr
= (*image
)->data
= shmat(shminfo
->shmid
, 0, 0);
3204 if( shminfo
->shmaddr
!= (char*)-1 )
3206 shminfo
->readOnly
= FALSE
;
3207 if( TSXShmAttach( display
, shminfo
) != 0)
3209 /* Reset the error flag */
3211 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
3212 XSync( display
, 0 );
3216 XSetErrorHandler(WineXHandler
);
3217 LeaveCriticalSection( &X11DRV_CritSection
);
3219 return TRUE
; /* Success! */
3221 /* An error occured */
3223 XSetErrorHandler(WineXHandler
);
3225 shmdt(shminfo
->shmaddr
);
3227 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
3230 XDestroyImage(*image
);
3231 LeaveCriticalSection( &X11DRV_CritSection
);
3239 /***********************************************************************
3240 * X11DRV_DIB_CreateDIBSection
3242 HBITMAP
X11DRV_DIB_CreateDIBSection(
3243 DC
*dc
, BITMAPINFO
*bmi
, UINT usage
,
3244 LPVOID
*bits
, HANDLE section
,
3248 BITMAPOBJ
*bmp
= NULL
;
3249 X11DRV_DIBSECTION
*dib
= NULL
;
3250 int *colorMap
= NULL
;
3253 /* Fill BITMAP32 structure with DIB data */
3254 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
3255 INT effHeight
, totalSize
;
3258 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
3259 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
3260 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
3262 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
3264 bm
.bmWidth
= bi
->biWidth
;
3265 bm
.bmHeight
= effHeight
;
3266 bm
.bmWidthBytes
= DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
3267 bm
.bmPlanes
= bi
->biPlanes
;
3268 bm
.bmBitsPixel
= bi
->biBitCount
;
3271 /* Get storage location for DIB bits */
3272 totalSize
= bi
->biSizeImage
? bi
->biSizeImage
: bm
.bmWidthBytes
* effHeight
;
3275 bm
.bmBits
= MapViewOfFile(section
, FILE_MAP_ALL_ACCESS
,
3276 0L, offset
, totalSize
);
3278 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
3279 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
3281 /* Create Color Map */
3282 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8)
3283 colorMap
= X11DRV_DIB_BuildColorMap( usage
== DIB_PAL_COLORS
? dc
: NULL
,
3284 usage
, bm
.bmBitsPixel
, bmi
, &nColorMap
);
3286 /* Allocate Memory for DIB and fill structure */
3288 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
3291 dib
->dibSection
.dsBm
= bm
;
3292 dib
->dibSection
.dsBmih
= *bi
;
3294 /* Set dsBitfields values */
3295 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
3297 dib
->dibSection
.dsBitfields
[0] = dib
->dibSection
.dsBitfields
[1] = dib
->dibSection
.dsBitfields
[2] = 0;
3299 else switch( bi
->biBitCount
)
3302 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
3303 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
3304 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f;
3308 dib
->dibSection
.dsBitfields
[0] = 0xff;
3309 dib
->dibSection
.dsBitfields
[1] = 0xff00;
3310 dib
->dibSection
.dsBitfields
[2] = 0xff0000;
3314 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff;
3315 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0xff00;
3316 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0xff0000;
3319 dib
->dibSection
.dshSection
= section
;
3320 dib
->dibSection
.dsOffset
= offset
;
3322 dib
->status
= X11DRV_DIB_NoHandler
;
3325 dib
->nColorMap
= nColorMap
;
3326 dib
->colorMap
= colorMap
;
3329 /* Create Device Dependent Bitmap and add DIB pointer */
3332 res
= CreateDIBitmap(dc
->hSelf
, bi
, 0, NULL
, bmi
, usage
);
3335 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
3338 bmp
->dib
= (DIBSECTION
*) dib
;
3341 X11DRV_CreateBitmap(res
);
3349 if (TSXShmQueryExtension(display
) &&
3350 X11DRV_XShmCreateImage( &dib
->image
, bm
.bmWidth
, effHeight
,
3351 bmp
->bitmap
.bmBitsPixel
, &dib
->shminfo
) )
3353 ; /* Created Image */
3355 XCREATEIMAGE( dib
->image
, bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
3356 dib
->shminfo
.shmid
= -1;
3360 /* Clean up in case of errors */
3361 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
3363 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
3364 res
, bmp
, dib
, bm
.bmBits
);
3368 UnmapViewOfFile(bm
.bmBits
), bm
.bmBits
= NULL
;
3370 VirtualFree(bm
.bmBits
, 0L, MEM_RELEASE
), bm
.bmBits
= NULL
;
3373 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
3374 if (colorMap
) { HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
; }
3375 if (dib
) { HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
; }
3376 if (res
) { DeleteObject(res
); res
= 0; }
3379 /* Install fault handler, if possible */
3382 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
3384 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
3385 if (dib
) dib
->status
= X11DRV_DIB_InSync
;
3389 /* Return BITMAP handle and storage location */
3390 if (res
) GDI_HEAP_UNLOCK(res
);
3391 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
3395 /***********************************************************************
3396 * X11DRV_DIB_DeleteDIBSection
3398 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
3400 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
3404 if (dib
->shminfo
.shmid
!= -1)
3406 TSXShmDetach (display
, &(dib
->shminfo
));
3407 XDestroyImage (dib
->image
);
3408 shmdt (dib
->shminfo
.shmaddr
);
3409 shmctl (dib
->shminfo
.shmid
, IPC_RMID
, 0);
3410 dib
->shminfo
.shmid
= -1;
3413 XDestroyImage( dib
->image
);
3417 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
3421 WORD count
= (GET_SEL_LIMIT( dib
->selector
) >> 16) + 1;
3422 SELECTOR_FreeBlock( dib
->selector
, count
);
3427 /**************************************************************************
3428 * X11DRV_DIB_CreateDIBFromPixmap
3430 * Allocates a packed DIB and copies the Pixmap data into it.
3431 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
3433 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
, BOOL bDeletePixmap
)
3436 BITMAPOBJ
*pBmp
= NULL
;
3437 HGLOBAL hPackedDIB
= 0;
3439 /* Allocates an HBITMAP which references the Pixmap passed to us */
3440 hBmp
= X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap
);
3443 TRACE("\tCould not create bitmap header for Pixmap\n");
3448 * Create a packed DIB from the Pixmap wrapper bitmap created above.
3449 * A packed DIB contains a BITMAPINFO structure followed immediately by
3450 * an optional color palette and the pixel data.
3452 hPackedDIB
= DIB_CreateDIBFromBitmap(hdc
, hBmp
);
3454 /* Get a pointer to the BITMAPOBJ structure */
3455 pBmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3457 /* We can now get rid of the HBITMAP wrapper we created earlier.
3458 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
3462 /* Manually free the DDBitmap internals to prevent the Pixmap
3463 * from being deleted by DeleteObject.
3465 HeapFree( GetProcessHeap(), 0, pBmp
->DDBitmap
->physBitmap
);
3466 HeapFree( GetProcessHeap(), 0, pBmp
->DDBitmap
);
3467 pBmp
->DDBitmap
= NULL
;
3472 TRACE("\tReturning packed DIB %x\n", hPackedDIB
);
3477 /**************************************************************************
3478 * X11DRV_DIB_CreatePixmapFromDIB
3480 * Creates a Pixmap from a packed DIB
3482 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
3484 Pixmap pixmap
= None
;
3486 BITMAPOBJ
*pBmp
= NULL
;
3487 LPBYTE pPackedDIB
= NULL
;
3488 LPBITMAPINFO pbmi
= NULL
;
3489 LPBITMAPINFOHEADER pbmiHeader
= NULL
;
3490 LPBYTE pbits
= NULL
;
3492 /* Get a pointer to the packed DIB's data */
3493 pPackedDIB
= (LPBYTE
)GlobalLock(hPackedDIB
);
3494 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
3495 pbmi
= (LPBITMAPINFO
)pPackedDIB
;
3496 pbits
= (LPBYTE
)(pPackedDIB
3497 + DIB_BitmapInfoSize( (LPBITMAPINFO
)pbmiHeader
, DIB_RGB_COLORS
));
3499 /* Create a DDB from the DIB */
3501 hBmp
= CreateDIBitmap(hdc
,
3508 GlobalUnlock(hPackedDIB
);
3510 TRACE("CreateDIBitmap returned %x\n", hBmp
);
3512 /* Retrieve the internal Pixmap from the DDB */
3514 pBmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
3516 if (pBmp
->DDBitmap
&& pBmp
->DDBitmap
->physBitmap
)
3518 pixmap
= ((X11DRV_PHYSBITMAP
*)(pBmp
->DDBitmap
->physBitmap
))->pixmap
;
3520 TRACE("NULL Pixmap in DDBitmap->physBitmap!\n");
3522 /* Manually free the BITMAPOBJ internals so that we can steal its pixmap */
3523 HeapFree( GetProcessHeap(), 0, pBmp
->DDBitmap
->physBitmap
);
3524 HeapFree( GetProcessHeap(), 0, pBmp
->DDBitmap
);
3525 pBmp
->DDBitmap
= NULL
; /* Its not a DDB anymore */
3528 /* Delete the DDB we created earlier now that we have stolen its pixmap */
3531 TRACE("\tReturning Pixmap %ld\n", pixmap
);
3535 #endif /* !defined(X_DISPLAY_MISSING) */