2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
9 #ifndef X_DISPLAY_MISSING
21 #include "selectors.h"
23 #include "xmalloc.h" /* for XCREATEIMAGE macro */
25 DECLARE_DEBUG_CHANNEL(bitmap
)
26 DECLARE_DEBUG_CHANNEL(x11drv
)
28 static int bitmapDepthTable
[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
29 static int ximageDepthTable
[] = { 0, 0, 0, 0, 0, 0, 0 };
31 /***********************************************************************
34 BOOL
X11DRV_DIB_Init(void)
39 for( i
= 0; bitmapDepthTable
[i
]; i
++ )
41 testimage
= TSXCreateImage(display
, DefaultVisualOfScreen(X11DRV_GetXScreen()),
42 bitmapDepthTable
[i
], ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
43 if( testimage
) ximageDepthTable
[i
] = testimage
->bits_per_pixel
;
45 TSXDestroyImage(testimage
);
51 /***********************************************************************
52 * X11DRV_DIB_GetXImageWidthBytes
54 * Return the width of an X image in bytes
56 int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
60 if (!ximageDepthTable
[0]) {
63 for( i
= 0; bitmapDepthTable
[i
] ; i
++ )
64 if( bitmapDepthTable
[i
] == depth
)
65 return (4 * ((width
* ximageDepthTable
[i
] + 31)/32));
67 WARN(bitmap
, "(%d): Unsupported depth\n", depth
);
71 /***********************************************************************
72 * X11DRV_DIB_BuildColorMap
74 * Build the color map from the bitmap palette. Should not be called
75 * for a >8-bit deep bitmap.
77 int *X11DRV_DIB_BuildColorMap( DC
*dc
, WORD coloruse
, WORD depth
,
78 const BITMAPINFO
*info
, int *nColors
)
85 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
87 colors
= info
->bmiHeader
.biClrUsed
;
88 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
89 colorPtr
= (WORD
*)info
->bmiColors
;
91 else /* assume BITMAPCOREINFO */
93 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
94 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
99 ERR(bitmap
, "called with >256 colors!\n");
103 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
104 colors
* sizeof(int) )))
107 if (coloruse
== DIB_RGB_COLORS
)
111 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
113 if (depth
== 1) /* Monochrome */
114 for (i
= 0; i
< colors
; i
++, rgb
++)
115 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
116 rgb
->rgbBlue
> 255*3/2);
118 for (i
= 0; i
< colors
; i
++, rgb
++)
119 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbRed
,
125 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
127 if (depth
== 1) /* Monochrome */
128 for (i
= 0; i
< colors
; i
++, rgb
++)
129 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
130 rgb
->rgbtBlue
> 255*3/2);
132 for (i
= 0; i
< colors
; i
++, rgb
++)
133 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbtRed
,
138 else /* DIB_PAL_COLORS */
140 for (i
= 0; i
< colors
; i
++, colorPtr
++)
141 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, PALETTEINDEX(*colorPtr
) );
149 /***********************************************************************
150 * X11DRV_DIB_MapColor
152 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
)
156 for (color
= 0; color
< nPhysMap
; color
++)
157 if (physMap
[color
] == phys
)
160 WARN(bitmap
, "Strange color %08x\n", phys
);
166 /***********************************************************************
167 * X11DRV_DIB_SetImageBits_1_Line
169 * Handles a single line of 1 bit data.
171 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth
, int left
, int *colors
,
172 XImage
*bmpImage
, int h
, const BYTE
*bits
)
177 if((extra
= (left
& 7)) != 0) {
184 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
185 for (i
= dstwidth
/8, x
= left
; i
> 0; i
--)
188 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
189 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 6) & 1] );
190 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 5) & 1] );
191 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 4) & 1] );
192 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 3) & 1] );
193 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 2) & 1] );
194 XPutPixel( bmpImage
, x
++, h
, colors
[(pix
>> 1) & 1] );
195 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 1] );
200 case 7: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
201 case 6: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
202 case 5: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
203 case 4: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
204 case 3: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
205 case 2: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] ); pix
<<= 1;
206 case 1: XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 7] );
210 /***********************************************************************
211 * X11DRV_DIB_SetImageBits_1
213 * SetDIBits for a 1-bit deep DIB.
215 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
216 DWORD srcwidth
, DWORD dstwidth
, int left
,
217 int *colors
, XImage
*bmpImage
)
222 DWORD linebytes
= ((srcwidth
+ 31) & ~31) / 8;
225 for (h
= lines
-1; h
>=0; h
--) {
226 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
228 srcbits
+= linebytes
;
232 for (h
= 0; h
< lines
; h
++) {
233 X11DRV_DIB_SetImageBits_1_Line(dstwidth
, left
, colors
, bmpImage
, h
,
235 srcbits
+= linebytes
;
241 /***********************************************************************
242 * X11DRV_DIB_SetImageBits_4
244 * SetDIBits for a 4-bit deep DIB.
246 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
247 DWORD srcwidth
, DWORD dstwidth
, int left
,
248 int *colors
, XImage
*bmpImage
)
252 const BYTE
*bits
= srcbits
+ (left
>> 1);
255 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
263 for (h
= lines
-1; h
>= 0; h
--) {
264 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
266 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
267 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
269 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
270 srcbits
+= linebytes
;
271 bits
= srcbits
+ (left
>> 1);
275 for (h
= 0; h
< lines
; h
++) {
276 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
278 XPutPixel( bmpImage
, x
++, h
, colors
[pix
>> 4] );
279 XPutPixel( bmpImage
, x
++, h
, colors
[pix
& 0x0f] );
281 if (dstwidth
& 1) XPutPixel( bmpImage
, x
, h
, colors
[*bits
>> 4] );
282 srcbits
+= linebytes
;
283 bits
= srcbits
+ (left
>> 1);
290 /***********************************************************************
291 * X11DRV_DIB_GetImageBits_4
293 * GetDIBits for a 4-bit deep DIB.
295 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*srcbits
,
296 DWORD srcwidth
, DWORD dstwidth
, int left
,
297 int *colors
, int nColors
, XImage
*bmpImage
)
301 BYTE
*bits
= srcbits
+ (left
>> 1);
304 DWORD linebytes
= ((srcwidth
+7)&~7)/2;
311 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
313 for (h
= lines
-1; h
>= 0; h
--) {
314 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
315 *bits
++ = (X11DRV_DIB_MapColor( colors
, nColors
,
316 XGetPixel( bmpImage
, x
++, h
)) << 4)
317 | (X11DRV_DIB_MapColor( colors
, nColors
,
318 XGetPixel( bmpImage
, x
++, h
)) & 0x0f);
321 *bits
= (X11DRV_DIB_MapColor( colors
, nColors
,
322 XGetPixel( bmpImage
, x
++, h
)) << 4);
323 srcbits
+= linebytes
;
324 bits
= srcbits
+ (left
>> 1);
328 for (h
= 0; h
< lines
; h
++) {
329 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
330 *bits
++ = (X11DRV_DIB_MapColor( colors
, nColors
,
331 XGetPixel( bmpImage
, x
++, h
))
333 | (X11DRV_DIB_MapColor( colors
, nColors
,
334 XGetPixel( bmpImage
, x
++, h
)) & 0x0f);
337 *bits
= (X11DRV_DIB_MapColor( colors
, nColors
,
338 XGetPixel( bmpImage
, x
++, h
)) << 4);
339 srcbits
+= linebytes
;
340 bits
= srcbits
+ (left
>> 1);
345 /***********************************************************************
346 * X11DRV_DIB_SetImageBits_RLE4
348 * SetDIBits for a 4-bit deep compressed DIB.
350 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
351 DWORD width
, DWORD dstwidth
,
352 int left
, int *colors
,
355 int x
= 0, c
, length
;
356 const BYTE
*begin
= bits
;
360 while ((int)lines
>= 0) {
362 if (length
) { /* encoded */
370 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>>4]);
378 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
389 case 1: /* eopicture */
395 FIXME(x11drv
, "x-delta is too large?\n");
401 default: /* absolute */
409 XPutPixel(bmpImage
, x
++, lines
, colors
[c
>> 4]);
417 XPutPixel(bmpImage
, x
++, lines
, colors
[c
& 0xf]);
420 if ((bits
- begin
) & 1)
429 /***********************************************************************
430 * X11DRV_DIB_SetImageBits_8
432 * SetDIBits for an 8-bit deep DIB.
434 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
435 DWORD srcwidth
, DWORD dstwidth
, int left
,
436 int *colors
, XImage
*bmpImage
)
440 const BYTE
*bits
= srcbits
+ left
;
442 /* align to 32 bit */
443 DWORD linebytes
= (srcwidth
+ 3) & ~3;
448 for (h
= lines
- 1; h
>= 0; h
--) {
449 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
450 XPutPixel( bmpImage
, x
, h
, colors
[*bits
] );
452 bits
= (srcbits
+= linebytes
) + left
;
456 for (h
= 0; h
< lines
; h
++) {
457 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
458 XPutPixel( bmpImage
, x
, h
, colors
[*bits
] );
460 bits
= (srcbits
+= linebytes
) + left
;
465 /***********************************************************************
466 * X11DRV_DIB_GetImageBits_8
468 * GetDIBits for an 8-bit deep DIB.
470 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*srcbits
,
471 DWORD srcwidth
, DWORD dstwidth
, int left
,
472 int *colors
, int nColors
, XImage
*bmpImage
)
476 BYTE
*bits
= srcbits
+ left
;
478 /* align to 32 bit */
479 DWORD linebytes
= (srcwidth
+ 3) & ~3;
484 for (h
= lines
- 1; h
>= 0; h
--) {
485 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
486 if ( XGetPixel( bmpImage
, x
, h
) != colors
[*bits
] )
487 *bits
= X11DRV_DIB_MapColor( colors
, nColors
,
488 XGetPixel( bmpImage
, x
, h
) );
490 bits
= (srcbits
+= linebytes
) + left
;
494 for (h
= 0; h
< lines
; h
++) {
495 for (x
= left
; x
< dstwidth
; x
++, bits
++) {
496 if ( XGetPixel( bmpImage
, x
, h
) != colors
[*bits
] )
497 *bits
= X11DRV_DIB_MapColor( colors
, nColors
,
498 XGetPixel( bmpImage
, x
, h
) );
500 bits
= (srcbits
+= linebytes
) + left
;
505 /***********************************************************************
506 * X11DRV_DIB_SetImageBits_RLE8
508 * SetDIBits for an 8-bit deep compressed DIB.
510 * This function rewritten 941113 by James Youngman. WINE blew out when I
511 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
513 * This was because the algorithm assumed that all RLE8 bitmaps end with the
514 * 'End of bitmap' escape code. This code is very much laxer in what it
515 * allows to end the expansion. Possibly too lax. See the note by
516 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
517 * bitmap should end with RleEnd, but on the other hand, software exists
518 * that produces ones that don't and Windows 3.1 doesn't complain a bit
521 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
522 * James A. Youngman <mbcstjy@afs.man.ac.uk>
526 enum Rle8_EscapeCodes
529 * Apologies for polluting your file's namespace...
531 RleEol
= 0, /* End of line */
532 RleEnd
= 1, /* End of bitmap */
533 RleDelta
= 2 /* Delta */
536 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
537 DWORD width
, DWORD dstwidth
,
538 int left
, int *colors
,
541 int x
; /* X-positon on each line. Increases. */
542 int line
; /* Line #. Starts at lines-1, decreases */
543 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
544 BYTE length
; /* The length pf a run */
545 BYTE color_index
; /* index into colors[] as read from bits */
546 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
547 int color
; /* value of colour[color_index] */
549 if (lines
== 0) /* Let's hope this doesn't happen. */
553 * Note that the bitmap data is stored by Windows starting at the
554 * bottom line of the bitmap and going upwards. Within each line,
555 * the data is stored left-to-right. That's the reason why line
556 * goes from lines-1 to 0. [JAY]
566 * If the length byte is not zero (which is the escape value),
567 * We have a run of length pixels all the same colour. The colour
568 * index is stored next.
570 * If the length byte is zero, we need to read the next byte to
571 * know what to do. [JAY]
576 * [Run-Length] Encoded mode
578 color_index
= (*pIn
++); /* Get the colour index. */
579 color
= colors
[color_index
];
582 XPutPixel(bmpImage
, x
++, line
, color
);
587 * Escape codes (may be an absolute sequence though)
589 escape_code
= (*pIn
++);
592 case RleEol
: /* =0, end of line */
599 case RleEnd
: /* =1, end of bitmap */
602 * Not all RLE8 bitmaps end with this
603 * code. For example, Paint Shop Pro
604 * produces some that don't. That's (I think)
605 * what caused the previous implementation to
608 line
=-1; /* Cause exit from do loop. */
612 case RleDelta
: /* =2, a delta */
615 * Note that deltaing to line 0
616 * will cause an exit from the loop,
617 * which may not be what is intended.
618 * The fact that there is a delta in the bits
619 * almost certainly implies that there is data
620 * to follow. You may feel that we should
621 * jump to the top of the loop to avoid exiting
624 * TODO: Decide what to do here in that case. [JAY]
630 TRACE(bitmap
, "Delta to last line of bitmap "
631 "(wrongly?) causes loop exit\n");
636 default: /* >2, switch to absolute mode */
641 length
= escape_code
;
644 color_index
= (*pIn
++);
645 XPutPixel(bmpImage
, x
++, line
,
646 colors
[color_index
]);
650 * If you think for a moment you'll realise that the
651 * only time we could ever possibly read an odd
652 * number of bytes is when there is a 0x00 (escape),
653 * a value >0x02 (absolute mode) and then an odd-
654 * length run. Therefore this is the only place we
655 * need to worry about it. Everywhere else the
656 * bytes are always read in pairs. [JAY]
659 pIn
++; /* Throw away the pad byte. */
662 } /* switch (escape_code) : Escape sequence */
663 } /* process either an encoded sequence or an escape sequence */
665 /* We expect to come here more than once per line. */
666 } while (line
>= 0); /* Do this until the bitmap is filled */
669 * Everybody comes here at the end.
670 * Check how we exited the loop and print a message if it's a bit odd.
673 if ( (*(pIn
-2) != 0/*escape*/) || (*(pIn
-1)!= RleEnd
) )
675 TRACE(bitmap
, "End-of-bitmap "
676 "without (strictly) proper escape code. Last two "
677 "bytes were: %02X %02X.\n",
684 /***********************************************************************
685 * X11DRV_DIB_SetImageBits_16
687 * SetDIBits for a 16-bit deep DIB.
689 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
690 DWORD srcwidth
, DWORD dstwidth
, int left
,
691 DC
*dc
, XImage
*bmpImage
)
699 /* align to 32 bit */
700 DWORD linebytes
= (srcwidth
* 2 + 3) & ~3;
704 ptr
= (LPWORD
) srcbits
+ left
;
706 if (bmpImage
->format
== ZPixmap
)
708 unsigned short indA
, indB
, indC
, indD
;
711 switch (bmpImage
->bits_per_pixel
)
714 indA
= (bmpImage
->byte_order
== LSBFirst
) ? 1 : 0;
715 indB
= (indA
== 1) ? 0 : 1;
718 imageBits
= (BYTE
*)(bmpImage
->data
+ (lines
- 1)*bmpImage
->bytes_per_line
);
719 for (h
= lines
- 1; h
>= 0; h
--) {
720 for (x
= left
; x
< dstwidth
; x
++, ptr
++) {
722 imageBits
[(x
<< 1) + indA
] = (BYTE
)((val
>> 7) & 0x00ff);
723 imageBits
[(x
<< 1) + indB
] = (BYTE
)(((val
<< 1) & 0x00c0) | (val
& 0x001f));
725 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
726 imageBits
-= bmpImage
->bytes_per_line
;
730 imageBits
= (BYTE
*)bmpImage
->data
;
731 for (h
= 0; h
< lines
; h
++) {
732 for (x
= left
; x
< dstwidth
; x
++, ptr
++) {
734 imageBits
[(x
<< 1) + indA
] = (BYTE
)((val
>> 7) & 0x00ff);
735 imageBits
[(x
<< 1) + indB
] = (BYTE
)(((val
<< 1) & 0x00c0) | (val
& 0x001f));
737 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
738 imageBits
+= bmpImage
->bytes_per_line
;
744 indA
= (bmpImage
->byte_order
== LSBFirst
) ? 3 : 0;
745 indB
= (indA
== 3) ? 2 : 1;
746 indC
= (indB
== 2) ? 1 : 2;
747 indD
= (indC
== 1) ? 0 : 3;
750 imageBits
= (BYTE
*)(bmpImage
->data
+ (lines
- 1)*bmpImage
->bytes_per_line
);
751 for (h
= lines
- 1; h
>= 0; h
--) {
752 for (x
= left
; x
< dstwidth
; x
++, ptr
++) {
754 imageBits
[(x
<< 2) + indA
] = 0x00; /* a */
755 imageBits
[(x
<< 2) + indB
] = (BYTE
)(((val
>> 7) & 0x00f8) | ((val
>> 12) & 0x0007)); /* red */
756 imageBits
[(x
<< 2) + indC
] = (BYTE
)(((val
>> 2) & 0x00f8) | ((val
>> 7) & 0x0007)); /* green */
757 imageBits
[(x
<< 2) + indD
] = (BYTE
)(((val
<< 3) & 0x00f8) | ((val
>> 2) & 0x0007)); /* blue */
759 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
760 imageBits
-= bmpImage
->bytes_per_line
;
764 imageBits
= (BYTE
*)bmpImage
->data
;
765 for (h
= 0; h
< lines
; h
++) {
766 for (x
= left
; x
< dstwidth
; x
++, ptr
++) {
768 imageBits
[(x
<< 2) + indA
] = 0x00;
769 imageBits
[(x
<< 2) + indB
] = (BYTE
)(((val
>> 7) & 0x00f8) | ((val
>> 12) & 0x0007));
770 imageBits
[(x
<< 2) + indC
] = (BYTE
)(((val
>> 2) & 0x00f8) | ((val
>> 7) & 0x0007));
771 imageBits
[(x
<< 2) + indD
] = (BYTE
)(((val
<< 3) & 0x00f8) | ((val
>> 2) & 0x0007));
773 ptr
= (LPWORD
)(srcbits
+= linebytes
) + left
;
774 imageBits
+= bmpImage
->bytes_per_line
;
781 /* Not standard format or Not RGB */
783 for (h
= lines
- 1; h
>= 0; h
--) {
784 for (x
= left
; x
< dstwidth
; x
++, ptr
++) {
786 r
= (BYTE
) ((val
& 0x7c00) >> 7);
787 g
= (BYTE
) ((val
& 0x03e0) >> 2);
788 b
= (BYTE
) ((val
& 0x001f) << 3);
789 XPutPixel( bmpImage
, x
, h
,
790 X11DRV_PALETTE_ToPhysical(dc
, RGB(r
,g
,b
)) );
792 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
796 for (h
= 0; h
< lines
; h
++) {
797 for (x
= left
; x
< dstwidth
; x
++, ptr
++) {
799 r
= (BYTE
) ((val
& 0x7c00) >> 7);
800 g
= (BYTE
) ((val
& 0x03e0) >> 2);
801 b
= (BYTE
) ((val
& 0x001f) << 3);
802 XPutPixel( bmpImage
, x
, h
,
803 X11DRV_PALETTE_ToPhysical(dc
, RGB(r
,g
,b
)) );
805 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
811 /***********************************************************************
812 * X11DRV_DIB_GetImageBits_16
814 * GetDIBits for an 16-bit deep DIB.
816 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*srcbits
,
817 DWORD srcwidth
, DWORD dstwidth
, int left
,
825 /* align to 32 bit */
826 DWORD linebytes
= (srcwidth
* 2 + 3) & ~3;
830 ptr
= (LPWORD
) srcbits
+ left
;
832 for (h
= lines
- 1; h
>= 0; h
--)
834 for (x
= left
; x
< dstwidth
; x
++, ptr
++)
836 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
837 r
= (BYTE
) GetRValue(pixel
);
838 g
= (BYTE
) GetGValue(pixel
);
839 b
= (BYTE
) GetBValue(pixel
);
840 *ptr
= ( ((r
<< 7) & 0x7c00) | ((g
<< 2) & 0x03e0) | ((b
>> 3) & 0x001f) );
842 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
846 for (h
= 0; h
< lines
; h
++)
848 for (x
= left
; x
< dstwidth
; x
++, ptr
++)
850 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
851 r
= (BYTE
) GetRValue(pixel
);
852 g
= (BYTE
) GetGValue(pixel
);
853 b
= (BYTE
) GetBValue(pixel
);
854 *ptr
= ( ((r
<< 7) & 0x7c00) | ((g
<< 2) & 0x03e0) | ((b
>> 3) & 0x001f) );
857 ptr
= (LPWORD
) (srcbits
+= linebytes
) + left
;
864 /***********************************************************************
865 * X11DRV_DIB_SetImageBits_24
867 * SetDIBits for a 24-bit deep DIB.
869 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
870 DWORD srcwidth
, DWORD dstwidth
, int left
,
871 DC
*dc
, XImage
*bmpImage
)
874 const BYTE
*bits
= srcbits
+ left
* 3;
877 /* align to 32 bit */
878 DWORD linebytes
= (srcwidth
* 3 + 3) & ~3;
882 /* "bits" order is reversed for some reason */
884 if (bmpImage
->format
== ZPixmap
)
886 unsigned short indA
, indB
, indC
, indD
;
889 switch (bmpImage
->bits_per_pixel
)
892 indA
= (bmpImage
->byte_order
== LSBFirst
) ? 1 : 0;
893 indB
= (indA
== 1) ? 0 : 1;
896 imageBits
= (BYTE
*)(bmpImage
->data
+ (lines
- 1)*bmpImage
->bytes_per_line
);
897 for (h
= lines
- 1; h
>= 0; h
--) {
898 for (x
= left
; x
< dstwidth
; x
++, bits
+= 3) {
899 imageBits
[(x
<< 1) + indA
] = (bits
[0] & 0xf8) | ((bits
[1] >> 5) & 0x07);
900 imageBits
[(x
<< 1) + indB
] = ((bits
[1] << 3) & 0xc0) | ((bits
[2] >> 3) & 0x1f);
902 bits
= (srcbits
+= linebytes
) + left
* 3;
903 imageBits
-= bmpImage
->bytes_per_line
;
907 imageBits
= (BYTE
*)bmpImage
->data
;
908 for (h
= 0; h
< lines
; h
++) {
909 for (x
= left
; x
< dstwidth
; x
++, bits
+= 3) {
910 imageBits
[(x
<< 1) + indA
] = (bits
[0] & 0xf8) | ((bits
[1] >> 5) & 0x07);
911 imageBits
[(x
<< 1) + indB
] = ((bits
[1] << 3) & 0xc0) | ((bits
[2] >> 3) & 0x1f);
913 bits
= (srcbits
+= linebytes
) + left
* 3;
914 imageBits
+= bmpImage
->bytes_per_line
;
920 indA
= (bmpImage
->byte_order
== LSBFirst
) ? 3 : 0;
921 indB
= (indA
== 3) ? 2 : 1;
922 indC
= (indB
== 2) ? 1 : 2;
923 indD
= (indC
== 1) ? 0 : 3;
926 imageBits
= (BYTE
*)(bmpImage
->data
+ (lines
- 1)*bmpImage
->bytes_per_line
);
927 for (h
= lines
- 1; h
>= 0; h
--) {
928 for (x
= left
; x
< dstwidth
; x
++, bits
+= 3) {
929 imageBits
[(x
<< 2) + indA
] = 0x00; /*a*/
930 imageBits
[(x
<< 2) + indB
] = bits
[2]; /*red*/
931 imageBits
[(x
<< 2) + indC
] = bits
[1]; /*green*/
932 imageBits
[(x
<< 2) + indD
] = bits
[0]; /*blue*/
934 bits
= (srcbits
+= linebytes
) + left
* 3;
935 imageBits
-= bmpImage
->bytes_per_line
;
939 imageBits
= (BYTE
*)(bmpImage
->data
+ (lines
- 1)*bmpImage
->bytes_per_line
);
940 for (h
= 0; h
< lines
; h
++) {
941 for (x
= left
; x
< dstwidth
; x
++, bits
+= 3) {
942 imageBits
[(x
<< 2) + indA
] = 0x00;
943 imageBits
[(x
<< 2) + indB
] = bits
[2];
944 imageBits
[(x
<< 2) + indC
] = bits
[1];
945 imageBits
[(x
<< 2) + indD
] = bits
[0];
947 bits
= (srcbits
+= linebytes
) + left
* 3;
948 imageBits
+= bmpImage
->bytes_per_line
;
955 /* Not standard format or Not RGB */
957 for (h
= lines
- 1; h
>= 0; h
--) {
958 for (x
= left
; x
< dstwidth
; x
++, bits
+= 3) {
959 XPutPixel( bmpImage
, x
, h
,
960 X11DRV_PALETTE_ToPhysical(dc
, RGB(bits
[2],bits
[1],bits
[0])));
962 bits
= (srcbits
+= linebytes
) + left
* 3;
966 for (h
= 0; h
< lines
; h
++) {
967 for (x
= left
; x
< dstwidth
; x
++, bits
+= 3) {
968 XPutPixel( bmpImage
, x
, h
,
969 X11DRV_PALETTE_ToPhysical(dc
, RGB(bits
[2],bits
[1],bits
[0])));
971 bits
= (srcbits
+= linebytes
) + left
* 3;
977 /***********************************************************************
978 * X11DRV_DIB_GetImageBits_24
980 * GetDIBits for an 24-bit deep DIB.
982 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*srcbits
,
983 DWORD srcwidth
, DWORD dstwidth
, int left
,
988 BYTE
*bits
= srcbits
+ (left
* 3);
990 /* align to 32 bit */
991 DWORD linebytes
= (srcwidth
* 3 + 3) & ~3;
996 for (h
= lines
- 1; h
>= 0; h
--)
998 for (x
= left
; x
< dstwidth
; x
++, bits
+= 3)
1000 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
1001 bits
[0] = GetRValue(pixel
);
1002 bits
[1] = GetGValue(pixel
);
1003 bits
[2] = GetBValue(pixel
);
1005 bits
= (srcbits
+= linebytes
) + (left
* 3);
1009 for (h
= 0; h
< lines
; h
++)
1011 for (x
= left
; x
< dstwidth
; x
++, bits
+= 3)
1013 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
1014 bits
[0] = GetRValue(pixel
);
1015 bits
[1] = GetGValue(pixel
);
1016 bits
[2] = GetBValue(pixel
);
1019 bits
= (srcbits
+= linebytes
) + (left
* 3);
1025 /***********************************************************************
1026 * X11DRV_DIB_SetImageBits_32
1028 * SetDIBits for a 32-bit deep DIB.
1030 static void X11DRV_DIB_SetImageBits_32( int lines
, const BYTE
*srcbits
,
1031 DWORD srcwidth
, DWORD dstwidth
, int left
,
1032 DC
*dc
, XImage
*bmpImage
)
1035 const BYTE
*bits
= srcbits
+ left
* 4;
1038 DWORD linebytes
= (srcwidth
* 4);
1042 if (bmpImage
->format
== ZPixmap
)
1044 unsigned short indA
, indB
, indC
, indD
;
1047 switch (bmpImage
->bits_per_pixel
)
1050 indA
= (bmpImage
->byte_order
== LSBFirst
) ? 1 : 0;
1051 indB
= (indA
== 1) ? 0 : 1;
1054 imageBits
= (BYTE
*)(bmpImage
->data
+ (lines
- 1)*bmpImage
->bytes_per_line
);
1055 for (h
= lines
- 1; h
>= 0; h
--) {
1056 for (x
= left
; x
< dstwidth
; x
++, bits
+= 4) {
1057 imageBits
[(x
<< 1) + indA
] = (bits
[0] & 0xf8) | ((bits
[1] >> 5) & 0x07);
1058 imageBits
[(x
<< 1) + indB
] = ((bits
[1] << 3) & 0xc0) | ((bits
[2] >> 3) & 0x1f);
1060 bits
= (srcbits
+= linebytes
) + left
* 4;
1061 imageBits
-= bmpImage
->bytes_per_line
;
1065 imageBits
= (BYTE
*)bmpImage
->data
;
1066 for (h
= 0; h
< lines
; h
++) {
1067 for (x
= left
; x
< dstwidth
; x
++, bits
+= 4) {
1068 imageBits
[(x
<< 1) + indA
] = (bits
[0] & 0xf8) | ((bits
[1] >> 5) & 0x07);
1069 imageBits
[(x
<< 1) + indB
] = ((bits
[1] << 3) & 0xc0) | ((bits
[2] >> 3) & 0x1f);
1071 bits
= (srcbits
+= linebytes
) + left
* 4;
1072 imageBits
+= bmpImage
->bytes_per_line
;
1078 indA
= (bmpImage
->byte_order
== LSBFirst
) ? 3 : 0;
1079 indB
= (indA
== 3) ? 2 : 1;
1080 indC
= (indB
== 2) ? 1 : 2;
1081 indD
= (indC
== 1) ? 0 : 3;
1084 imageBits
= (BYTE
*)(bmpImage
->data
+ (lines
- 1)*bmpImage
->bytes_per_line
);
1085 for (h
= lines
- 1; h
>= 0; h
--) {
1086 for (x
= left
; x
< dstwidth
; x
++, bits
+= 4) {
1087 imageBits
[(x
<< 2) + indA
] = 0x00; /*a*/
1088 imageBits
[(x
<< 2) + indB
] = bits
[2]; /*red*/
1089 imageBits
[(x
<< 2) + indC
] = bits
[1]; /*green*/
1090 imageBits
[(x
<< 2) + indD
] = bits
[0]; /*blue*/
1092 bits
= (srcbits
+= linebytes
) + left
* 4;
1093 imageBits
-= bmpImage
->bytes_per_line
;
1097 imageBits
= (BYTE
*)(bmpImage
->data
+ (lines
- 1)*bmpImage
->bytes_per_line
);
1098 for (h
= 0; h
< lines
; h
++) {
1099 for (x
= left
; x
< dstwidth
; x
++, bits
+= 4) {
1100 imageBits
[(x
<< 2) + indA
] = 0x00;
1101 imageBits
[(x
<< 2) + indB
] = bits
[2];
1102 imageBits
[(x
<< 2) + indC
] = bits
[1];
1103 imageBits
[(x
<< 2) + indD
] = bits
[0];
1105 bits
= (srcbits
+= linebytes
) + left
* 4;
1106 imageBits
+= bmpImage
->bytes_per_line
;
1114 for (h
= lines
- 1; h
>= 0; h
--) {
1115 for (x
= left
; x
< dstwidth
; x
++, bits
+= 4) {
1116 XPutPixel( bmpImage
, x
, h
,
1117 X11DRV_PALETTE_ToPhysical(dc
, RGB(bits
[2],bits
[1],bits
[0])));
1119 bits
= (srcbits
+= linebytes
) + left
* 4;
1123 for (h
= 0; h
< lines
; h
++) {
1124 for (x
= left
; x
< dstwidth
; x
++, bits
+= 4) {
1125 XPutPixel( bmpImage
, x
, h
,
1126 X11DRV_PALETTE_ToPhysical(dc
, RGB(bits
[2],bits
[1],bits
[0])));
1128 bits
= (srcbits
+= linebytes
) + left
* 4;
1134 /***********************************************************************
1135 * X11DRV_DIB_GetImageBits_32
1137 * GetDIBits for an 32-bit deep DIB.
1139 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*srcbits
,
1140 DWORD srcwidth
, DWORD dstwidth
, int left
,
1145 BYTE
*bits
= srcbits
+ (left
* 4);
1147 /* align to 32 bit */
1148 DWORD linebytes
= (srcwidth
* 4);
1153 for (h
= lines
- 1; h
>= 0; h
--)
1155 for (x
= left
; x
< dstwidth
; x
++, bits
+= 4)
1157 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
1158 bits
[0] = GetRValue(pixel
);
1159 bits
[1] = GetGValue(pixel
);
1160 bits
[2] = GetBValue(pixel
);
1162 bits
= (srcbits
+= linebytes
) + (left
* 4);
1166 for (h
= 0; h
< lines
; h
++)
1168 for (x
= left
; x
< dstwidth
; x
++, bits
+= 4)
1170 COLORREF pixel
= X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage
, x
, h
) );
1171 bits
[0] = GetRValue(pixel
);
1172 bits
[1] = GetGValue(pixel
);
1173 bits
[2] = GetBValue(pixel
);
1176 bits
= (srcbits
+= linebytes
) + (left
* 4);
1182 /***********************************************************************
1183 * X11DRV_DIB_SetImageBits
1185 * Transfer the bits to an X image.
1186 * Helper function for SetDIBits() and SetDIBitsToDevice().
1187 * The Xlib critical section must be entered before calling this function.
1189 int X11DRV_DIB_SetImageBits( const X11DRV_DIB_SETIMAGEBITS_DESCR
*descr
)
1191 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
1194 if ( descr
->dc
&& descr
->dc
->w
.flags
& DC_DIRTY
)
1195 CLIPPING_UpdateGCRegion( descr
->dc
);
1198 bmpImage
= descr
->image
;
1200 bmpImage
= XCreateImage( display
,
1201 DefaultVisualOfScreen(X11DRV_GetXScreen()),
1202 descr
->depth
, ZPixmap
, 0, NULL
,
1203 descr
->infoWidth
, lines
, 32, 0 );
1204 bmpImage
->data
= xcalloc( bmpImage
->bytes_per_line
* lines
);
1207 /* Transfer the pixels */
1208 switch(descr
->infoBpp
)
1211 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
1212 descr
->width
, descr
->xSrc
, descr
->colorMap
,
1216 if (descr
->compression
)
1217 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
1218 descr
->infoWidth
, descr
->width
,
1219 descr
->xSrc
, descr
->colorMap
,
1222 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
1223 descr
->infoWidth
, descr
->width
,
1224 descr
->xSrc
, descr
->colorMap
,
1228 if (descr
->compression
)
1229 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
1230 descr
->infoWidth
, descr
->width
,
1232 descr
->colorMap
, bmpImage
);
1234 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
1235 descr
->infoWidth
, descr
->width
,
1236 descr
->xSrc
, descr
->colorMap
,
1241 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
1242 descr
->infoWidth
, descr
->width
,
1243 descr
->xSrc
, descr
->dc
, bmpImage
);
1246 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
1247 descr
->infoWidth
, descr
->width
,
1248 descr
->xSrc
, descr
->dc
, bmpImage
);
1251 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
1252 descr
->infoWidth
, descr
->width
,
1253 descr
->xSrc
, descr
->dc
, bmpImage
);
1256 WARN(bitmap
, "(%d): Invalid depth\n", descr
->infoBpp
);
1260 XPutImage( display
, descr
->drawable
, descr
->gc
, bmpImage
,
1261 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
1262 descr
->width
, descr
->height
);
1264 if (!descr
->image
) XDestroyImage( bmpImage
);
1268 /***********************************************************************
1269 * X11DRV_DIB_GetImageBits
1271 * Transfer the bits from an X image.
1272 * The Xlib critical section must be entered before calling this function.
1274 int X11DRV_DIB_GetImageBits( const X11DRV_DIB_SETIMAGEBITS_DESCR
*descr
)
1276 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
1280 bmpImage
= descr
->image
;
1282 bmpImage
= XCreateImage( display
,
1283 DefaultVisualOfScreen(X11DRV_GetXScreen()),
1284 descr
->depth
, ZPixmap
, 0, NULL
,
1285 descr
->infoWidth
, lines
, 32, 0 );
1286 bmpImage
->data
= xcalloc( bmpImage
->bytes_per_line
* lines
);
1289 XGetSubImage( display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
1290 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
1291 bmpImage
, descr
->xSrc
, descr
->ySrc
);
1293 /* Transfer the pixels */
1294 switch(descr
->infoBpp
)
1297 FIXME(bitmap
, "Depth 1 not yet supported!\n");
1301 if (descr
->compression
)
1302 FIXME(bitmap
, "Compression not yet supported!\n");
1304 X11DRV_DIB_GetImageBits_4( descr
->lines
,
1305 (LPVOID
)descr
->bits
, descr
->infoWidth
,
1306 descr
->width
, descr
->xSrc
,
1307 descr
->colorMap
, descr
->nColorMap
,
1312 if (descr
->compression
)
1313 FIXME(bitmap
, "Compression not yet supported!\n");
1315 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
1316 descr
->infoWidth
, descr
->width
,
1317 descr
->xSrc
, descr
->colorMap
,
1318 descr
->nColorMap
, bmpImage
);
1323 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
1325 descr
->width
, descr
->xSrc
, bmpImage
);
1329 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
1331 descr
->width
, descr
->xSrc
, bmpImage
);
1335 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
1337 descr
->width
, descr
->xSrc
, bmpImage
);
1341 WARN(bitmap
, "(%d): Invalid depth\n", descr
->infoBpp
);
1345 if (!descr
->image
) XDestroyImage( bmpImage
);
1349 /*************************************************************************
1350 * X11DRV_SetDIBitsToDevice
1353 INT
X11DRV_SetDIBitsToDevice( DC
*dc
, INT xDest
, INT yDest
, DWORD cx
,
1354 DWORD cy
, INT xSrc
, INT ySrc
,
1355 UINT startscan
, UINT lines
, LPCVOID bits
,
1356 const BITMAPINFO
*info
, UINT coloruse
)
1358 X11DRV_DIB_SETIMAGEBITS_DESCR descr
;
1359 DWORD width
, oldcy
= cy
;
1361 int height
, tmpheight
;
1362 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
1365 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
1366 &descr
.infoBpp
, &descr
.compression
) == -1)
1369 if (height
< 0) height
= -height
;
1370 if (!lines
|| (startscan
>= height
)) return 0;
1371 if (startscan
+ lines
> height
) lines
= height
- startscan
;
1372 if (ySrc
< startscan
) ySrc
= startscan
;
1373 else if (ySrc
>= startscan
+ lines
) return 0;
1374 if (xSrc
>= width
) return 0;
1375 if (ySrc
+ cy
>= startscan
+ lines
) cy
= startscan
+ lines
- ySrc
;
1376 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
1377 if (!cx
|| !cy
) return 0;
1379 X11DRV_SetupGCForText( dc
); /* To have the correct colors */
1380 TSXSetFunction(display
, physDev
->gc
, X11DRV_XROPfunction
[dc
->w
.ROPmode
-1]);
1382 if (descr
.infoBpp
<= 8)
1384 descr
.colorMap
= X11DRV_DIB_BuildColorMap( dc
, coloruse
,
1386 info
, &descr
.nColorMap
);
1387 if (!descr
.colorMap
)
1394 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
1395 descr
.infoWidth
= width
;
1396 descr
.depth
= dc
->w
.bitsPerPixel
;
1397 descr
.drawable
= physDev
->drawable
;
1398 descr
.gc
= physDev
->gc
;
1400 descr
.ySrc
= tmpheight
>= 0 ? lines
-(ySrc
-startscan
)-cy
+(oldcy
-cy
)
1402 descr
.xDest
= dc
->w
.DCOrgX
+ XLPTODP( dc
, xDest
);
1403 descr
.yDest
= dc
->w
.DCOrgY
+ YLPTODP( dc
, yDest
) +
1404 (tmpheight
>= 0 ? oldcy
-cy
: 0);
1408 EnterCriticalSection( &X11DRV_CritSection
);
1409 result
= CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
1410 LeaveCriticalSection( &X11DRV_CritSection
);
1412 if (descr
.infoBpp
<= 8)
1413 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
1417 /***********************************************************************
1418 * X11DRV_DIB_SetDIBits
1420 INT
X11DRV_DIB_SetDIBits(
1421 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
1422 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
,
1423 UINT coloruse
, HBITMAP hbitmap
)
1425 X11DRV_DIB_SETIMAGEBITS_DESCR descr
;
1426 X11DRV_PHYSBITMAP
*pbitmap
;
1427 int height
, tmpheight
;
1432 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
1433 &descr
.infoBpp
, &descr
.compression
) == -1)
1437 if (height
< 0) height
= -height
;
1438 if (!lines
|| (startscan
>= height
))
1441 if (startscan
+ lines
> height
) lines
= height
- startscan
;
1443 if (descr
.infoBpp
<= 8)
1445 descr
.colorMap
= X11DRV_DIB_BuildColorMap( descr
.dc
, coloruse
,
1446 bmp
->bitmap
.bmBitsPixel
,
1447 info
, &descr
.nColorMap
);
1448 if (!descr
.colorMap
)
1457 X11DRV_CreateBitmap(hbitmap
);
1459 pbitmap
= bmp
->DDBitmap
->physBitmap
;
1463 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
1464 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
1465 descr
.drawable
= pbitmap
->pixmap
;
1466 descr
.gc
= BITMAP_GC(bmp
);
1470 descr
.yDest
= height
- startscan
- lines
;
1471 descr
.width
= bmp
->bitmap
.bmWidth
;
1472 descr
.height
= lines
;
1474 EnterCriticalSection( &X11DRV_CritSection
);
1475 result
= CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
1476 LeaveCriticalSection( &X11DRV_CritSection
);
1478 if (descr
.colorMap
) HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
1484 /*********************************************************************
1485 * X11DRV_DIB_GetNearestIndex
1487 * Helper for X11DRV_DIB_GetDIBits.
1488 * Returns the nearest colour table index for a given RGB.
1489 * Nearest is defined by minimizing the sum of the squares.
1491 static INT
X11DRV_DIB_GetNearestIndex(BITMAPINFO
*info
, BYTE r
, BYTE g
, BYTE b
)
1493 INT i
, best
= -1, diff
, bestdiff
= -1;
1496 for(color
= info
->bmiColors
, i
= 0; i
< (1 << info
->bmiHeader
.biBitCount
);
1498 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
1499 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
1500 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
1503 if(best
== -1 || diff
< bestdiff
) {
1511 /***********************************************************************
1512 * X11DRV_DIB_GetDIBits
1514 INT
X11DRV_DIB_GetDIBits(
1515 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
1516 UINT lines
, LPVOID bits
, BITMAPINFO
*info
,
1517 UINT coloruse
, HBITMAP hbitmap
)
1521 PALETTEENTRY
* palEntry
;
1522 PALETTEOBJ
* palette
;
1523 BYTE
*bbits
= (BYTE
*)bits
, *linestart
;
1524 int dstwidth
, yend
, xend
= bmp
->bitmap
.bmWidth
;
1526 TRACE(bitmap
, "%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
1527 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
1528 (int)info
->bmiHeader
.biWidth
, (int)info
->bmiHeader
.biHeight
,
1531 if (!(palette
= (PALETTEOBJ
*)GDI_GetObjPtr( dc
->w
.hPalette
, PALETTE_MAGIC
)))
1534 /* adjust number of scanlines to copy */
1536 if( lines
> info
->bmiHeader
.biHeight
)
1537 lines
= info
->bmiHeader
.biHeight
;
1539 yend
= startscan
+ lines
;
1540 if( startscan
>= bmp
->bitmap
.bmHeight
)
1544 if( yend
> bmp
->bitmap
.bmHeight
) yend
= bmp
->bitmap
.bmHeight
;
1546 /* adjust scanline width */
1548 if(bmp
->bitmap
.bmWidth
> info
->bmiHeader
.biWidth
)
1549 xend
= info
->bmiHeader
.biWidth
;
1553 X11DRV_CreateBitmap(hbitmap
);
1555 dstwidth
= DIB_GetDIBWidthBytes( info
->bmiHeader
.biWidth
,
1556 info
->bmiHeader
.biBitCount
);
1558 EnterCriticalSection( &X11DRV_CritSection
);
1559 bmpImage
= (XImage
*)CALL_LARGE_STACK( X11DRV_BITMAP_GetXImage
, bmp
);
1562 switch( info
->bmiHeader
.biBitCount
) {
1564 case 1: /* 1 bit DIB */
1566 unsigned long white
= (1 << bmp
->bitmap
.bmBitsPixel
) - 1;
1568 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1569 for( x
= 0; x
< xend
; x
++ ) {
1570 if (!(x
&7)) *bbits
= 0;
1571 *bbits
|= (XGetPixel( bmpImage
, x
, y
) >= white
)
1573 if ((x
&7)==7) bbits
++;
1575 bbits
= (linestart
+= dstwidth
);
1581 case 4: /* 4 bit DIB */
1582 switch(bmp
->bitmap
.bmBitsPixel
) {
1584 case 1: /* 1/4 bit bmp -> 4 bit DIB */
1586 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1587 for( x
= 0; x
< xend
; x
++ ) {
1588 if (!(x
&1)) *bbits
= 0;
1589 *bbits
|= XGetPixel( bmpImage
, x
, y
)<<(4*(1-(x
&1)));
1590 if ((x
&1)==1) bbits
++;
1592 bbits
= (linestart
+= dstwidth
);
1596 case 8: /* 8 bit bmp -> 4 bit DIB */
1597 palEntry
= palette
->logpalette
.palPalEntry
;
1598 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1599 for( x
= 0; x
< xend
; x
++ ) {
1600 unsigned long pixel
= XGetPixel( bmpImage
, x
, y
);
1601 if (!(x
&1)) *bbits
= 0;
1602 *bbits
|= ( X11DRV_DIB_GetNearestIndex(info
,
1603 palEntry
[pixel
].peRed
,
1604 palEntry
[pixel
].peGreen
,
1605 palEntry
[pixel
].peBlue
)
1607 if ((x
&1)==1) bbits
++;
1609 bbits
= (linestart
+= dstwidth
);
1613 case 15: /* 15/16 bit bmp -> 4 bit DIB */
1615 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1616 for( x
= 0; x
< xend
; x
++ ) {
1617 unsigned long pixel
= XGetPixel( bmpImage
, x
, y
);
1618 if (!(x
&1)) *bbits
= 0;
1619 *bbits
|= ( X11DRV_DIB_GetNearestIndex(info
,
1620 ((pixel
<< 3) & 0xf8) |
1621 ((pixel
>> 2) & 0x7),
1622 ((pixel
>> 2) & 0xf8) |
1623 ((pixel
>> 7) & 0x7),
1624 ((pixel
>> 7) & 0xf8) |
1625 ((pixel
>> 12) & 0x7) )
1627 if ((x
&1)==1) bbits
++;
1629 bbits
= (linestart
+= dstwidth
);
1633 case 24: /* 24/32 bit bmp -> 4 bit DIB */
1635 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1636 for( x
= 0; x
< xend
; x
++ ) {
1637 unsigned long pixel
= XGetPixel( bmpImage
, x
, y
);
1638 if (!(x
&1)) *bbits
= 0;
1639 *bbits
|= ( X11DRV_DIB_GetNearestIndex( info
,
1640 (pixel
>> 16) & 0xff,
1641 (pixel
>> 8) & 0xff,
1644 if ((x
&1)==1) bbits
++;
1646 bbits
= (linestart
+= dstwidth
);
1650 default: /* ? bit bmp -> 4 bit DIB */
1651 FIXME(bitmap
, "4 bit DIB %d bit bitmap\n",
1652 bmp
->bitmap
.bmBitsPixel
);
1658 case 8: /* 8 bit DIB */
1659 switch(bmp
->bitmap
.bmBitsPixel
) {
1661 case 1: /* 1/4/8 bit bmp -> 8 bit DIB */
1664 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1665 for( x
= 0; x
< xend
; x
++ )
1666 *bbits
++ = XGetPixel( bmpImage
, x
, y
);
1667 bbits
= (linestart
+= dstwidth
);
1671 case 15: /* 15/16 bit bmp -> 8 bit DIB */
1673 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1674 for( x
= 0; x
< xend
; x
++ ) {
1675 unsigned long pixel
= XGetPixel( bmpImage
, x
, y
);
1676 *bbits
++ = X11DRV_DIB_GetNearestIndex( info
,
1677 ((pixel
<< 3) & 0xf8) |
1678 ((pixel
>> 2) & 0x7),
1679 ((pixel
>> 2) & 0xf8) |
1680 ((pixel
>> 7) & 0x7),
1681 ((pixel
>> 7) & 0xf8) |
1682 ((pixel
>> 12) & 0x7) );
1684 bbits
= (linestart
+= dstwidth
);
1688 case 24: /* 24/32 bit bmp -> 8 bit DIB */
1690 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1691 for( x
= 0; x
< xend
; x
++ ) {
1692 unsigned long pixel
= XGetPixel( bmpImage
, x
, y
);
1693 *bbits
++ = X11DRV_DIB_GetNearestIndex( info
,
1694 (pixel
>> 16) & 0xff,
1695 (pixel
>> 8) & 0xff,
1698 bbits
= (linestart
+= dstwidth
);
1702 default: /* ? bit bmp -> 8 bit DIB */
1703 FIXME(bitmap
, "8 bit DIB %d bit bitmap\n",
1704 bmp
->bitmap
.bmBitsPixel
);
1710 case 15: /* 15/16 bit DIB */
1712 switch(bmp
->bitmap
.bmBitsPixel
) {
1714 case 15: /* 15/16 bit bmp -> 16 bit DIB */
1716 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1717 for( x
= 0; x
< xend
; x
++ ) {
1718 unsigned long pixel
=XGetPixel( bmpImage
, x
, y
);
1719 *bbits
++ = pixel
& 0xff;
1720 *bbits
++ = (pixel
>> 8) & 0xff;
1722 bbits
= (linestart
+= dstwidth
);
1726 case 24: /* 24/32 bit bmp -> 16 bit DIB */
1728 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1729 for( x
= 0; x
< xend
; x
++ ) {
1730 unsigned long pixel
=XGetPixel( bmpImage
, x
, y
);
1731 *bbits
++ = ((pixel
>> 6) & 0xe0) |
1732 ((pixel
>> 3) & 0x1f);
1733 *bbits
++ = ((pixel
>> 17) & 0x7c) |
1734 ((pixel
>> 14) & 0x3);
1736 bbits
= (linestart
+= dstwidth
);
1740 case 1: /* 1/4/8 bit bmp -> 16 bit DIB */
1743 palEntry
= palette
->logpalette
.palPalEntry
;
1744 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1745 for( x
= 0; x
< xend
; x
++ ) {
1746 unsigned long pixel
=XGetPixel( bmpImage
, x
, y
);
1747 *bbits
++ = ((palEntry
[pixel
].peBlue
>> 3) & 0x1f) |
1748 ((palEntry
[pixel
].peGreen
<< 2) & 0xe0);
1749 *bbits
++ = ((palEntry
[pixel
].peGreen
>> 6) & 0x3) |
1750 ((palEntry
[pixel
].peRed
>> 1) & 0x7c);
1752 bbits
= (linestart
+= dstwidth
);
1756 default: /* ? bit bmp -> 16 bit DIB */
1757 FIXME(bitmap
, "15/16 bit DIB %d bit bitmap\n",
1758 bmp
->bitmap
.bmBitsPixel
);
1764 case 24: /* 24 bit DIB */
1765 switch(bmp
->bitmap
.bmBitsPixel
) {
1767 case 24: /* 24/32 bit bmp -> 24 bit DIB */
1769 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1770 for( x
= 0; x
< xend
; x
++ ) {
1771 unsigned long pixel
=XGetPixel( bmpImage
, x
, y
);
1772 *bbits
++ = (pixel
>>16) & 0xff;
1773 *bbits
++ = (pixel
>> 8) & 0xff;
1774 *bbits
++ = pixel
& 0xff;
1776 bbits
= (linestart
+= dstwidth
);
1780 case 15: /* 15/16 bit bmp -> 24 bit DIB */
1782 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1783 for( x
= 0; x
< xend
; x
++ ) {
1784 unsigned long pixel
=XGetPixel( bmpImage
, x
, y
);
1785 *bbits
++ = ((pixel
>> 7) & 0xf8) |
1786 ((pixel
>> 12) & 0x7);
1787 *bbits
++ = ((pixel
>> 2) & 0xf8) |
1788 ((pixel
>> 7) & 0x7);
1789 *bbits
++ = ((pixel
<< 3) & 0xf8) |
1790 ((pixel
>> 2) & 0x7);
1792 bbits
= (linestart
+= dstwidth
);
1796 case 1: /* 1/4/8 bit bmp -> 24 bit DIB */
1799 palEntry
= palette
->logpalette
.palPalEntry
;
1800 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1801 for( x
= 0; x
< xend
; x
++ ) {
1802 unsigned long pixel
=XGetPixel( bmpImage
, x
, y
);
1803 *bbits
++ = palEntry
[pixel
].peBlue
;
1804 *bbits
++ = palEntry
[pixel
].peGreen
;
1805 *bbits
++ = palEntry
[pixel
].peRed
;
1807 bbits
= (linestart
+= dstwidth
);
1811 default: /* ? bit bmp -> 24 bit DIB */
1812 FIXME(bitmap
, "24 bit DIB %d bit bitmap\n",
1813 bmp
->bitmap
.bmBitsPixel
);
1819 case 32: /* 32 bit DIB */
1820 switch(bmp
->bitmap
.bmBitsPixel
) {
1822 case 24: /* 24/32 bit bmp -> 32 bit DIB */
1824 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1825 for( x
= 0; x
< xend
; x
++ ) {
1826 unsigned long pixel
=XGetPixel( bmpImage
, x
, y
);
1827 *bbits
++ = (pixel
>>16) & 0xff;
1828 *bbits
++ = (pixel
>> 8) & 0xff;
1829 *bbits
++ = pixel
& 0xff;
1832 bbits
= (linestart
+= dstwidth
);
1836 case 15: /* 15/16 bit bmp -> 32 bit DIB */
1838 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1839 for( x
= 0; x
< xend
; x
++ ) {
1840 unsigned long pixel
=XGetPixel( bmpImage
, x
, y
);
1841 *bbits
++ = ((pixel
>> 7) & 0xf8) |
1842 ((pixel
>> 12) & 0x7);
1843 *bbits
++ = ((pixel
>> 2) & 0xf8) |
1844 ((pixel
>> 7) & 0x7);
1845 *bbits
++ = ((pixel
<< 3) & 0xf8) |
1846 ((pixel
>> 2) & 0x7);
1849 bbits
= (linestart
+= dstwidth
);
1853 case 1: /* 1/4/8 bit bmp -> 32 bit DIB */
1856 palEntry
= palette
->logpalette
.palPalEntry
;
1857 for( y
= yend
- 1; (int)y
>= (int)startscan
; y
-- ) {
1858 for( x
= 0; x
< xend
; x
++ ) {
1859 unsigned long pixel
=XGetPixel( bmpImage
, x
, y
);
1860 *bbits
++ = palEntry
[pixel
].peBlue
;
1861 *bbits
++ = palEntry
[pixel
].peGreen
;
1862 *bbits
++ = palEntry
[pixel
].peRed
;
1865 bbits
= (linestart
+= dstwidth
);
1869 default: /* ? bit bmp -> 32 bit DIB */
1870 FIXME(bitmap
, "32 bit DIB %d bit bitmap\n",
1871 bmp
->bitmap
.bmBitsPixel
);
1877 default: /* ? bit DIB */
1878 FIXME(bitmap
,"Unsupported DIB depth %d\n",
1879 info
->bmiHeader
.biBitCount
);
1883 XDestroyImage( bmpImage
);
1884 LeaveCriticalSection( &X11DRV_CritSection
);
1886 if(info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
1887 info
->bmiHeader
.biSizeImage
= DIB_GetDIBImageBytes(
1888 info
->bmiHeader
.biWidth
,
1889 info
->bmiHeader
.biHeight
,
1890 info
->bmiHeader
.biBitCount
);
1892 if(bbits
- (BYTE
*)bits
> info
->bmiHeader
.biSizeImage
)
1893 ERR(bitmap
, "Buffer overrun. Please investigate.\n");
1895 info
->bmiHeader
.biCompression
= 0;
1897 GDI_HEAP_UNLOCK( dc
->w
.hPalette
);
1902 /***********************************************************************
1903 * DIB_DoProtectDIBSection
1905 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
1907 DIBSECTION
*dib
= bmp
->dib
;
1908 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
1909 : -dib
->dsBm
.bmHeight
;
1910 INT totalSize
= dib
->dsBmih
.biSizeImage
? dib
->dsBmih
.biSizeImage
1911 : dib
->dsBm
.bmWidthBytes
* effHeight
;
1914 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
1915 TRACE(bitmap
, "Changed protection from %ld to %ld\n",
1916 old_prot
, new_prot
);
1919 /***********************************************************************
1920 * X11DRV_DIB_DoUpdateDIBSection
1922 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
1924 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
1925 X11DRV_DIB_SETIMAGEBITS_DESCR descr
;
1927 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, &descr
.lines
,
1928 &descr
.infoBpp
, &descr
.compression
) == -1)
1932 descr
.image
= dib
->image
;
1933 descr
.colorMap
= dib
->colorMap
;
1934 descr
.nColorMap
= dib
->nColorMap
;
1935 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
1936 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
1939 descr
.drawable
= ((X11DRV_PHYSBITMAP
*)bmp
->DDBitmap
->physBitmap
)->pixmap
;
1940 descr
.gc
= BITMAP_GC(bmp
);
1945 descr
.width
= bmp
->bitmap
.bmWidth
;
1946 descr
.height
= bmp
->bitmap
.bmHeight
;
1950 TRACE(bitmap
, "Copying from Pixmap to DIB bits\n");
1951 EnterCriticalSection( &X11DRV_CritSection
);
1952 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits
, &descr
);
1953 LeaveCriticalSection( &X11DRV_CritSection
);
1957 TRACE(bitmap
, "Copying from DIB bits to Pixmap\n");
1958 EnterCriticalSection( &X11DRV_CritSection
);
1959 CALL_LARGE_STACK( X11DRV_DIB_SetImageBits
, &descr
);
1960 LeaveCriticalSection( &X11DRV_CritSection
);
1964 /***********************************************************************
1965 * X11DRV_DIB_FaultHandler
1967 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
1969 BOOL handled
= FALSE
;
1972 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
1973 if (!bmp
) return FALSE
;
1976 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
1978 case X11DRV_DIB_GdiMod
:
1979 TRACE( bitmap
, "called in status DIB_GdiMod\n" );
1980 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
1981 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
1982 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
1983 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_InSync
;
1987 case X11DRV_DIB_InSync
:
1988 TRACE( bitmap
, "called in status X11DRV_DIB_InSync\n" );
1989 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
1990 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_AppMod
;
1994 case X11DRV_DIB_AppMod
:
1995 FIXME( bitmap
, "called in status X11DRV_DIB_AppMod: "
1996 "this can't happen!\n" );
1999 case X11DRV_DIB_NoHandler
:
2000 FIXME( bitmap
, "called in status DIB_NoHandler: "
2001 "this can't happen!\n" );
2005 GDI_HEAP_UNLOCK( (HBITMAP
)res
);
2009 /***********************************************************************
2010 * X11DRV_DIB_UpdateDIBSection
2012 void X11DRV_DIB_UpdateDIBSection(DC
*dc
, BOOL toDIB
)
2016 /* Ensure this is a Compatible DC that has a DIB section selected */
2019 if (!(dc
->w
.flags
& DC_MEMORY
)) return;
2021 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( dc
->w
.hBitmap
, BITMAP_MAGIC
);
2026 GDI_HEAP_UNLOCK(dc
->w
.hBitmap
);
2032 /* Prepare for access to the DIB by GDI functions */
2034 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
2037 case X11DRV_DIB_NoHandler
:
2038 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
2041 case X11DRV_DIB_GdiMod
:
2042 TRACE( bitmap
, "fromDIB called in status X11DRV_DIB_GdiMod\n" );
2046 case X11DRV_DIB_InSync
:
2047 TRACE( bitmap
, "fromDIB called in status X11DRV_DIB_InSync\n" );
2051 case X11DRV_DIB_AppMod
:
2052 TRACE( bitmap
, "fromDIB called in status X11DRV_DIB_AppMod\n" );
2053 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
2054 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
2055 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_InSync
;
2061 /* Acknowledge write access to the DIB by GDI functions */
2063 switch (((X11DRV_DIBSECTION
*) bmp
->dib
)->status
)
2066 case X11DRV_DIB_NoHandler
:
2067 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
2070 case X11DRV_DIB_GdiMod
:
2071 TRACE( bitmap
, " toDIB called in status X11DRV_DIB_GdiMod\n" );
2075 case X11DRV_DIB_InSync
:
2076 TRACE( bitmap
, " toDIB called in status X11DRV_DIB_InSync\n" );
2077 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
2078 ((X11DRV_DIBSECTION
*) bmp
->dib
)->status
= X11DRV_DIB_GdiMod
;
2081 case X11DRV_DIB_AppMod
:
2082 FIXME( bitmap
, " toDIB called in status X11DRV_DIB_AppMod: "
2083 "this can't happen!\n" );
2088 GDI_HEAP_UNLOCK(dc
->w
.hBitmap
);
2091 /***********************************************************************
2092 * X11DRV_DIB_CreateDIBSection16
2094 HBITMAP16
X11DRV_DIB_CreateDIBSection16(
2095 DC
*dc
, BITMAPINFO
*bmi
, UINT16 usage
,
2096 SEGPTR
*bits
, HANDLE section
,
2099 HBITMAP res
= X11DRV_DIB_CreateDIBSection(dc
, bmi
, usage
, NULL
,
2103 BITMAPOBJ
*bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
2104 if ( bmp
&& bmp
->dib
)
2106 DIBSECTION
*dib
= bmp
->dib
;
2107 INT height
= dib
->dsBm
.bmHeight
>= 0 ?
2108 dib
->dsBm
.bmHeight
: -dib
->dsBm
.bmHeight
;
2109 INT size
= dib
->dsBmih
.biSizeImage
?
2110 dib
->dsBmih
.biSizeImage
: dib
->dsBm
.bmWidthBytes
* height
;
2111 if ( dib
->dsBm
.bmBits
)
2113 ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
=
2114 SELECTOR_AllocBlock( dib
->dsBm
.bmBits
, size
,
2115 SEGMENT_DATA
, FALSE
, FALSE
);
2117 printf("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
2118 dib
->dsBm
.bmBits
, size
, ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
,
2119 PTR_SEG_OFF_TO_SEGPTR(((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
, 0));
2121 GDI_HEAP_UNLOCK( res
);
2124 *bits
= PTR_SEG_OFF_TO_SEGPTR( ((X11DRV_DIBSECTION
*) bmp
->dib
)->selector
, 0 );
2131 /***********************************************************************
2132 * X11DRV_DIB_CreateDIBSection
2134 HBITMAP
X11DRV_DIB_CreateDIBSection(
2135 DC
*dc
, BITMAPINFO
*bmi
, UINT usage
,
2136 LPVOID
*bits
, HANDLE section
,
2140 BITMAPOBJ
*bmp
= NULL
;
2141 X11DRV_DIBSECTION
*dib
= NULL
;
2142 int *colorMap
= NULL
;
2145 /* Fill BITMAP32 structure with DIB data */
2146 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
2147 INT effHeight
, totalSize
;
2150 TRACE(bitmap
, "format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
2151 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
2152 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
2155 bm
.bmWidth
= bi
->biWidth
;
2156 bm
.bmHeight
= bi
->biHeight
;
2157 bm
.bmWidthBytes
= DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
2158 bm
.bmPlanes
= bi
->biPlanes
;
2159 bm
.bmBitsPixel
= bi
->biBitCount
;
2162 /* Get storage location for DIB bits */
2163 effHeight
= bm
.bmHeight
>= 0 ? bm
.bmHeight
: -bm
.bmHeight
;
2164 totalSize
= bi
->biSizeImage
? bi
->biSizeImage
: bm
.bmWidthBytes
* effHeight
;
2167 bm
.bmBits
= MapViewOfFile(section
, FILE_MAP_ALL_ACCESS
,
2168 0L, offset
, totalSize
);
2170 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
2171 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
2173 /* Create Color Map */
2174 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8)
2177 colorMap
= X11DRV_DIB_BuildColorMap( dc
, usage
, bm
.bmBitsPixel
,
2181 /* Allocate Memory for DIB and fill structure */
2183 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
2186 dib
->dibSection
.dsBm
= bm
;
2187 dib
->dibSection
.dsBmih
= *bi
;
2188 /* FIXME: dib->dibSection.dsBitfields ??? */
2189 dib
->dibSection
.dshSection
= section
;
2190 dib
->dibSection
.dsOffset
= offset
;
2192 dib
->status
= X11DRV_DIB_NoHandler
;
2195 dib
->nColorMap
= nColorMap
;
2196 dib
->colorMap
= colorMap
;
2199 /* Create Device Dependent Bitmap and add DIB pointer */
2202 res
= CreateDIBitmap(dc
->hSelf
, bi
, 0, NULL
, bmi
, usage
);
2205 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
2208 bmp
->dib
= (DIBSECTION
*) dib
;
2211 X11DRV_CreateBitmap(res
);
2218 XCREATEIMAGE( dib
->image
, bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
2220 /* Clean up in case of errors */
2221 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
2223 TRACE(bitmap
, "got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
2224 res
, bmp
, dib
, bm
.bmBits
);
2228 UnmapViewOfFile(bm
.bmBits
), bm
.bmBits
= NULL
;
2230 VirtualFree(bm
.bmBits
, MEM_RELEASE
, 0L), bm
.bmBits
= NULL
;
2233 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
2234 if (colorMap
) { HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
; }
2235 if (dib
) { HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
; }
2236 if (res
) { DeleteObject(res
); res
= 0; }
2239 /* Install fault handler, if possible */
2242 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
2244 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
2245 if (dib
) dib
->status
= X11DRV_DIB_InSync
;
2249 /* Return BITMAP handle and storage location */
2250 if (res
) GDI_HEAP_UNLOCK(res
);
2251 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
2255 /***********************************************************************
2256 * X11DRV_DIB_DeleteDIBSection
2258 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
2260 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
2263 XDestroyImage( dib
->image
);
2266 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
2270 WORD count
= (GET_SEL_LIMIT( dib
->selector
) >> 16) + 1;
2271 SELECTOR_FreeBlock( dib
->selector
, count
);
2276 #endif /* !defined(X_DISPLAY_MISSING) */