2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
13 # ifdef HAVE_SYS_SHM_H
16 # ifdef HAVE_SYS_IPC_H
19 #endif /* defined(HAVE_LIBXXSHM) */
26 #include "debugtools.h"
31 DEFAULT_DEBUG_CHANNEL(bitmap
);
32 DECLARE_DEBUG_CHANNEL(x11drv
);
34 static int ximageDepthTable
[32];
37 static int XShmErrorFlag
= 0;
40 /* This structure holds the arguments for DIB_SetImageBits() */
46 PALETTEENTRY
*palentry
;
67 } X11DRV_DIB_IMAGEBITS_DESCR
;
72 RLE_EOL
= 0, /* End of line */
73 RLE_END
= 1, /* End of bitmap */
74 RLE_DELTA
= 2 /* Delta */
77 /***********************************************************************
78 * X11DRV_DIB_GetXImageWidthBytes
80 * Return the width of an X image in bytes
82 inline static int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
84 if (!depth
|| depth
> 32) goto error
;
86 if (!ximageDepthTable
[depth
-1])
88 XImage
*testimage
= XCreateImage( gdi_display
, visual
, depth
,
89 ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
92 ximageDepthTable
[depth
-1] = testimage
->bits_per_pixel
;
93 XDestroyImage( testimage
);
95 else ximageDepthTable
[depth
-1] = -1;
97 if (ximageDepthTable
[depth
-1] != -1)
98 return (4 * ((width
* ximageDepthTable
[depth
-1] + 31) / 32));
101 WARN( "(%d): Unsupported depth\n", depth
);
106 /***********************************************************************
107 * X11DRV_DIB_CreateXImage
111 XImage
*X11DRV_DIB_CreateXImage( int width
, int height
, int depth
)
117 width_bytes
= X11DRV_DIB_GetXImageWidthBytes( width
, depth
);
118 image
= XCreateImage( gdi_display
, visual
, depth
, ZPixmap
, 0,
119 calloc( height
, width_bytes
),
120 width
, height
, 32, width_bytes
);
126 /***********************************************************************
127 * X11DRV_DIB_GenColorMap
129 * Fills the color map of a bitmap palette. Should not be called
130 * for a >8-bit deep bitmap.
132 int *X11DRV_DIB_GenColorMap( DC
*dc
, int *colorMapping
,
133 WORD coloruse
, WORD depth
, BOOL quads
,
134 const void *colorPtr
, int start
, int end
)
138 if (coloruse
== DIB_RGB_COLORS
)
140 int max
= 1 << depth
;
142 if (end
> max
) end
= max
;
146 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
148 if (depth
== 1) /* Monochrome */
149 for (i
= start
; i
< end
; i
++, rgb
++)
150 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
151 rgb
->rgbBlue
> 255*3/2);
153 for (i
= start
; i
< end
; i
++, rgb
++)
154 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbRed
,
160 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
162 if (depth
== 1) /* Monochrome */
163 for (i
= start
; i
< end
; i
++, rgb
++)
164 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
165 rgb
->rgbtBlue
> 255*3/2);
167 for (i
= start
; i
< end
; i
++, rgb
++)
168 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, RGB(rgb
->rgbtRed
,
173 else /* DIB_PAL_COLORS */
176 WORD
* index
= (WORD
*)colorPtr
;
178 for (i
= start
; i
< end
; i
++, index
++)
179 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, PALETTEINDEX(*index
) );
181 for (i
= start
; i
< end
; i
++)
182 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( dc
, PALETTEINDEX(i
) );
189 /***********************************************************************
190 * X11DRV_DIB_BuildColorMap
192 * Build the color map from the bitmap palette. Should not be called
193 * for a >8-bit deep bitmap.
195 int *X11DRV_DIB_BuildColorMap( DC
*dc
, WORD coloruse
, WORD depth
,
196 const BITMAPINFO
*info
, int *nColors
)
200 const void *colorPtr
;
203 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
205 colors
= info
->bmiHeader
.biClrUsed
;
206 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
207 colorPtr
= info
->bmiColors
;
209 else /* assume BITMAPCOREINFO */
211 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
212 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
217 ERR("called with >256 colors!\n");
221 /* just so CopyDIBSection doesn't have to create an identity palette */
222 if (coloruse
== (WORD
)-1) colorPtr
= NULL
;
224 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
225 colors
* sizeof(int) )))
229 return X11DRV_DIB_GenColorMap( dc
, colorMapping
, coloruse
, depth
,
230 isInfo
, colorPtr
, 0, colors
);
234 /***********************************************************************
235 * X11DRV_DIB_MapColor
237 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
, int oldcol
)
241 if ((oldcol
< nPhysMap
) && (physMap
[oldcol
] == phys
))
244 for (color
= 0; color
< nPhysMap
; color
++)
245 if (physMap
[color
] == phys
)
248 WARN("Strange color %08x\n", phys
);
253 /*********************************************************************
254 * X11DRV_DIB_GetNearestIndex
256 * Helper for X11DRV_DIB_GetDIBits.
257 * Returns the nearest colour table index for a given RGB.
258 * Nearest is defined by minimizing the sum of the squares.
260 static INT
X11DRV_DIB_GetNearestIndex(RGBQUAD
*colormap
, int numColors
, BYTE r
, BYTE g
, BYTE b
)
262 INT i
, best
= -1, diff
, bestdiff
= -1;
265 for(color
= colormap
, i
= 0; i
< numColors
; color
++, i
++) {
266 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
267 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
268 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
271 if(best
== -1 || diff
< bestdiff
) {
278 /*********************************************************************
279 * X11DRV_DIB_MaskToShift
281 * Helper for X11DRV_DIB_GetDIBits.
282 * Returns the by how many bits to shift a given color so that it is
283 * in the proper position.
285 static INT
X11DRV_DIB_MaskToShift(DWORD mask
)
293 while ((mask
&1)==0) {
300 /***********************************************************************
301 * X11DRV_DIB_Convert_any_asis
303 * All X11DRV_DIB_Convert_Xxx functions take at least the following
306 * This is the width in pixel of the surface to copy. This may be less
307 * than the full width of the image.
309 * The number of lines to copy. This may be less than the full height
310 * of the image. This is always >0.
312 * Points to the first byte containing data to be copied. If the source
313 * surface starts are coordinates (x,y) then this is:
314 * image_ptr+x*bytes_pre_pixel+y*bytes_per_line
315 * (with further adjustments for top-down/bottom-up images)
317 * This is the number of bytes per line. It may be >0 or <0 depending on
318 * whether this is a top-down or bottom-up image.
320 * Same as srcbits but for the destination
322 * Same as srclinebytes but for the destination.
325 * - The supported Dib formats are: pal1, pal4, pal8, rgb555, bgr555,
326 * rgb565, bgr565, rgb888 and any 32bit (0888) format.
327 * The supported XImage (Bmp) formats are: pal1, pal4, pal8,
328 * rgb555, bgr555, rgb565, bgr565, rgb888, bgr888, rgb0888, bgr0888.
329 * - Rgb formats are those for which the masks are such that:
330 * red_mask > green_mask > blue_mask
331 * - Bgr formats are those for which the masks sort in the other direction.
332 * - Many conversion functions handle both rgb->bgr and bgr->rgb conversions
333 * so the comments use h, g, l to mean respectively the source color in the
334 * high bits, the green, and the source color in the low bits.
336 static void X11DRV_DIB_Convert_any_asis(int width
, int height
,
338 const void* srcbits
, int srclinebytes
,
339 void* dstbits
, int dstlinebytes
)
343 width
*=bytes_per_pixel
;
344 for (y
=0; y
<height
; y
++) {
345 memcpy(dstbits
, srcbits
, width
);
346 srcbits
+= srclinebytes
;
347 dstbits
+= dstlinebytes
;
355 static void X11DRV_DIB_Convert_555_reverse(int width
, int height
,
356 const void* srcbits
, int srclinebytes
,
357 void* dstbits
, int dstlinebytes
)
359 const DWORD
* srcpixel
;
363 for (y
=0; y
<height
; y
++) {
366 for (x
=0; x
<width
/2; x
++) {
367 /* Do 2 pixels at a time */
370 *dstpixel
++=((srcval
<< 10) & 0x7c007c00) | /* h */
371 ( srcval
& 0x03e003e0) | /* g */
372 ((srcval
>> 10) & 0x001f001f); /* l */
375 /* And the the odd pixel */
377 srcval
=*((WORD
*)srcpixel
);
378 *((WORD
*)dstpixel
)=((srcval
<< 10) & 0x7c00) | /* h */
379 ( srcval
& 0x03e0) | /* g */
380 ((srcval
>> 10) & 0x001f); /* l */
382 srcbits
+= srclinebytes
;
383 dstbits
+= dstlinebytes
;
387 static void X11DRV_DIB_Convert_555_to_565_asis(int width
, int height
,
388 const void* srcbits
, int srclinebytes
,
389 void* dstbits
, int dstlinebytes
)
391 const DWORD
* srcpixel
;
395 for (y
=0; y
<height
; y
++) {
398 for (x
=0; x
<width
/2; x
++) {
399 /* Do 2 pixels at a time */
402 *dstpixel
++=((srcval
<< 1) & 0xffc0ffc0) | /* h, g */
403 ((srcval
>> 4) & 0x00200020) | /* g - 1 bit */
404 ( srcval
& 0x001f001f); /* l */
407 /* And the the odd pixel */
409 srcval
=*((WORD
*)srcpixel
);
410 *((WORD
*)dstpixel
)=((srcval
<< 1) & 0xffc0) | /* h, g */
411 ((srcval
>> 4) & 0x0020) | /* g - 1 bit */
412 (srcval
& 0x001f); /* l */
414 srcbits
+= srclinebytes
;
415 dstbits
+= dstlinebytes
;
419 static void X11DRV_DIB_Convert_555_to_565_reverse(int width
, int height
,
420 const void* srcbits
, int srclinebytes
,
421 void* dstbits
, int dstlinebytes
)
423 const DWORD
* srcpixel
;
427 for (y
=0; y
<height
; y
++) {
430 for (x
=0; x
<width
/2; x
++) {
431 /* Do 2 pixels at a time */
434 *dstpixel
++=((srcval
>> 10) & 0x001f001f) | /* h */
435 ((srcval
<< 1) & 0x07c007c0) | /* g */
436 ((srcval
>> 4) & 0x00200020) | /* g - 1 bit */
437 ((srcval
<< 11) & 0xf800f800); /* l */
440 /* And the the odd pixel */
442 srcval
=*((WORD
*)srcpixel
);
443 *((WORD
*)dstpixel
)=((srcval
>> 10) & 0x001f) | /* h */
444 ((srcval
<< 1) & 0x07c0) | /* g */
445 ((srcval
>> 4) & 0x0020) | /* g - 1 bit */
446 ((srcval
<< 11) & 0xf800); /* l */
448 srcbits
+= srclinebytes
;
449 dstbits
+= dstlinebytes
;
453 static void X11DRV_DIB_Convert_555_to_888_asis(int width
, int height
,
454 const void* srcbits
, int srclinebytes
,
455 void* dstbits
, int dstlinebytes
)
457 const WORD
* srcpixel
;
461 for (y
=0; y
<height
; y
++) {
464 for (x
=0; x
<width
; x
++) {
467 dstpixel
[0]=((srcval
<< 3) & 0xf8) | /* l */
468 ((srcval
>> 2) & 0x07); /* l - 3 bits */
469 dstpixel
[1]=((srcval
>> 2) & 0xf8) | /* g */
470 ((srcval
>> 7) & 0x07); /* g - 3 bits */
471 dstpixel
[2]=((srcval
>> 7) & 0xf8) | /* h */
472 ((srcval
>> 12) & 0x07); /* h - 3 bits */
475 srcbits
+= srclinebytes
;
476 dstbits
+= dstlinebytes
;
480 static void X11DRV_DIB_Convert_555_to_888_reverse(int width
, int height
,
481 const void* srcbits
, int srclinebytes
,
482 void* dstbits
, int dstlinebytes
)
484 const WORD
* srcpixel
;
488 for (y
=0; y
<height
; y
++) {
491 for (x
=0; x
<width
; x
++) {
494 dstpixel
[0]=((srcval
>> 7) & 0xf8) | /* h */
495 ((srcval
>> 12) & 0x07); /* h - 3 bits */
496 dstpixel
[1]=((srcval
>> 2) & 0xf8) | /* g */
497 ((srcval
>> 7) & 0x07); /* g - 3 bits */
498 dstpixel
[2]=((srcval
<< 3) & 0xf8) | /* l */
499 ((srcval
>> 2) & 0x07); /* l - 3 bits */
502 srcbits
+= srclinebytes
;
503 dstbits
+= dstlinebytes
;
507 static void X11DRV_DIB_Convert_555_to_0888_asis(int width
, int height
,
508 const void* srcbits
, int srclinebytes
,
509 void* dstbits
, int dstlinebytes
)
511 const WORD
* srcpixel
;
515 for (y
=0; y
<height
; y
++) {
518 for (x
=0; x
<width
; x
++) {
521 *dstpixel
++=((srcval
<< 9) & 0xf80000) | /* h */
522 ((srcval
<< 4) & 0x070000) | /* h - 3 bits */
523 ((srcval
<< 6) & 0x00f800) | /* g */
524 ((srcval
<< 1) & 0x000700) | /* g - 3 bits */
525 ((srcval
<< 3) & 0x0000f8) | /* l */
526 ((srcval
>> 2) & 0x000007); /* l - 3 bits */
528 srcbits
+= srclinebytes
;
529 dstbits
+= dstlinebytes
;
533 static void X11DRV_DIB_Convert_555_to_0888_reverse(int width
, int height
,
534 const void* srcbits
, int srclinebytes
,
535 void* dstbits
, int dstlinebytes
)
537 const WORD
* srcpixel
;
541 for (y
=0; y
<height
; y
++) {
544 for (x
=0; x
<width
; x
++) {
547 *dstpixel
++=((srcval
>> 7) & 0x0000f8) | /* h */
548 ((srcval
>> 12) & 0x000007) | /* h - 3 bits */
549 ((srcval
<< 6) & 0x00f800) | /* g */
550 ((srcval
<< 1) & 0x000700) | /* g - 3 bits */
551 ((srcval
<< 19) & 0xf80000) | /* l */
552 ((srcval
<< 14) & 0x070000); /* l - 3 bits */
554 srcbits
+= srclinebytes
;
555 dstbits
+= dstlinebytes
;
559 static void X11DRV_DIB_Convert_5x5_to_any0888(int width
, int height
,
560 const void* srcbits
, int srclinebytes
,
561 WORD rsrc
, WORD gsrc
, WORD bsrc
,
562 void* dstbits
, int dstlinebytes
,
563 DWORD rdst
, DWORD gdst
, DWORD bdst
)
565 int rRightShift1
,gRightShift1
,bRightShift1
;
566 int rRightShift2
,gRightShift2
,bRightShift2
;
568 int rLeftShift
,gLeftShift
,bLeftShift
;
569 const WORD
* srcpixel
;
573 /* Note, the source pixel value is shifted left by 16 bits so that
574 * we know we will always have to shift right to extract the components.
576 rRightShift1
=16+X11DRV_DIB_MaskToShift(rsrc
)-3;
577 gRightShift1
=16+X11DRV_DIB_MaskToShift(gsrc
)-3;
578 bRightShift1
=16+X11DRV_DIB_MaskToShift(bsrc
)-3;
579 rRightShift2
=rRightShift1
+5;
580 gRightShift2
=gRightShift1
+5;
581 bRightShift2
=bRightShift1
+5;
583 /* Green has 5 bits, like the others */
587 /* Green has 6 bits, not 5. Compensate. */
594 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
595 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
596 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
598 for (y
=0; y
<height
; y
++) {
601 for (x
=0; x
<width
; x
++) {
604 srcval
=*srcpixel
++ << 16;
605 red
= ((srcval
>> rRightShift1
) & 0xf8) |
606 ((srcval
>> rRightShift2
) & 0x07);
607 green
=((srcval
>> gRightShift1
) & gMask1
) |
608 ((srcval
>> gRightShift2
) & gMask2
);
609 blue
= ((srcval
>> bRightShift1
) & 0xf8) |
610 ((srcval
>> bRightShift2
) & 0x07);
611 *dstpixel
++=(red
<< rLeftShift
) |
612 (green
<< gLeftShift
) |
613 (blue
<< bLeftShift
);
615 srcbits
+= srclinebytes
;
616 dstbits
+= dstlinebytes
;
621 * 16 bits conversions
624 static void X11DRV_DIB_Convert_565_reverse(int width
, int height
,
625 const void* srcbits
, int srclinebytes
,
626 void* dstbits
, int dstlinebytes
)
628 const DWORD
* srcpixel
;
632 for (y
=0; y
<height
; y
++) {
635 for (x
=0; x
<width
/2; x
++) {
636 /* Do 2 pixels at a time */
639 *dstpixel
++=((srcval
<< 11) & 0xf800f800) | /* h */
640 ( srcval
& 0x07e007e0) | /* g */
641 ((srcval
>> 11) & 0x001f001f); /* l */
644 /* And the the odd pixel */
646 srcval
=*((WORD
*)srcpixel
);
647 *((WORD
*)dstpixel
)=((srcval
<< 11) & 0xf800) | /* h */
648 ( srcval
& 0x07e0) | /* g */
649 ((srcval
>> 11) & 0x001f); /* l */
651 srcbits
+= srclinebytes
;
652 dstbits
+= dstlinebytes
;
656 static void X11DRV_DIB_Convert_565_to_555_asis(int width
, int height
,
657 const void* srcbits
, int srclinebytes
,
658 void* dstbits
, int dstlinebytes
)
660 const DWORD
* srcpixel
;
664 for (y
=0; y
<height
; y
++) {
667 for (x
=0; x
<width
/2; x
++) {
668 /* Do 2 pixels at a time */
671 *dstpixel
++=((srcval
>> 1) & 0x7fe07fe0) | /* h, g */
672 ( srcval
& 0x001f001f); /* l */
675 /* And the the odd pixel */
677 srcval
=*((WORD
*)srcpixel
);
678 *((WORD
*)dstpixel
)=((srcval
>> 1) & 0x7fe0) | /* h, g */
679 ( srcval
& 0x001f); /* l */
681 srcbits
+= srclinebytes
;
682 dstbits
+= dstlinebytes
;
686 static void X11DRV_DIB_Convert_565_to_555_reverse(int width
, int height
,
687 const void* srcbits
, int srclinebytes
,
688 void* dstbits
, int dstlinebytes
)
690 const DWORD
* srcpixel
;
694 for (y
=0; y
<height
; y
++) {
697 for (x
=0; x
<width
/2; x
++) {
698 /* Do 2 pixels at a time */
701 *dstpixel
++=((srcval
>> 11) & 0x001f001f) | /* h */
702 ((srcval
>> 1) & 0x03e003e0) | /* g */
703 ((srcval
<< 10) & 0x7c007c00); /* l */
706 /* And the the odd pixel */
708 srcval
=*((WORD
*)srcpixel
);
709 *((WORD
*)dstpixel
)=((srcval
>> 11) & 0x001f) | /* h */
710 ((srcval
>> 1) & 0x03e0) | /* g */
711 ((srcval
<< 10) & 0x7c00); /* l */
713 srcbits
+= srclinebytes
;
714 dstbits
+= dstlinebytes
;
718 static void X11DRV_DIB_Convert_565_to_888_asis(int width
, int height
,
719 const void* srcbits
, int srclinebytes
,
720 void* dstbits
, int dstlinebytes
)
722 const WORD
* srcpixel
;
726 for (y
=0; y
<height
; y
++) {
729 for (x
=0; x
<width
; x
++) {
732 dstpixel
[0]=((srcval
<< 3) & 0xf8) | /* l */
733 ((srcval
>> 2) & 0x07); /* l - 3 bits */
734 dstpixel
[1]=((srcval
>> 3) & 0xfc) | /* g */
735 ((srcval
>> 9) & 0x03); /* g - 2 bits */
736 dstpixel
[2]=((srcval
>> 8) & 0xf8) | /* h */
737 ((srcval
>> 13) & 0x07); /* h - 3 bits */
740 srcbits
+= srclinebytes
;
741 dstbits
+= dstlinebytes
;
745 static void X11DRV_DIB_Convert_565_to_888_reverse(int width
, int height
,
746 const void* srcbits
, int srclinebytes
,
747 void* dstbits
, int dstlinebytes
)
749 const WORD
* srcpixel
;
753 for (y
=0; y
<height
; y
++) {
756 for (x
=0; x
<width
; x
++) {
759 dstpixel
[0]=((srcval
>> 8) & 0xf8) | /* h */
760 ((srcval
>> 13) & 0x07); /* h - 3 bits */
761 dstpixel
[1]=((srcval
>> 3) & 0xfc) | /* g */
762 ((srcval
>> 9) & 0x03); /* g - 2 bits */
763 dstpixel
[2]=((srcval
<< 3) & 0xf8) | /* l */
764 ((srcval
>> 2) & 0x07); /* l - 3 bits */
767 srcbits
+= srclinebytes
;
768 dstbits
+= dstlinebytes
;
772 static void X11DRV_DIB_Convert_565_to_0888_asis(int width
, int height
,
773 const void* srcbits
, int srclinebytes
,
774 void* dstbits
, int dstlinebytes
)
776 const WORD
* srcpixel
;
780 for (y
=0; y
<height
; y
++) {
783 for (x
=0; x
<width
; x
++) {
786 *dstpixel
++=((srcval
<< 8) & 0xf80000) | /* h */
787 ((srcval
<< 3) & 0x070000) | /* h - 3 bits */
788 ((srcval
<< 5) & 0x00fc00) | /* g */
789 ((srcval
>> 1) & 0x000300) | /* g - 2 bits */
790 ((srcval
<< 3) & 0x0000f8) | /* l */
791 ((srcval
>> 2) & 0x000007); /* l - 3 bits */
793 srcbits
+= srclinebytes
;
794 dstbits
+= dstlinebytes
;
798 static void X11DRV_DIB_Convert_565_to_0888_reverse(int width
, int height
,
799 const void* srcbits
, int srclinebytes
,
800 void* dstbits
, int dstlinebytes
)
802 const WORD
* srcpixel
;
806 for (y
=0; y
<height
; y
++) {
809 for (x
=0; x
<width
; x
++) {
812 *dstpixel
++=((srcval
>> 8) & 0x0000f8) | /* h */
813 ((srcval
>> 13) & 0x000007) | /* h - 3 bits */
814 ((srcval
<< 5) & 0x00fc00) | /* g */
815 ((srcval
>> 1) & 0x000300) | /* g - 2 bits */
816 ((srcval
<< 19) & 0xf80000) | /* l */
817 ((srcval
<< 14) & 0x070000); /* l - 3 bits */
819 srcbits
+= srclinebytes
;
820 dstbits
+= dstlinebytes
;
828 static void X11DRV_DIB_Convert_888_reverse(int width
, int height
,
829 const void* srcbits
, int srclinebytes
,
830 void* dstbits
, int dstlinebytes
)
832 const BYTE
* srcpixel
;
836 for (y
=0; y
<height
; y
++) {
839 for (x
=0; x
<width
; x
++) {
840 dstpixel
[0]=srcpixel
[2];
841 dstpixel
[1]=srcpixel
[1];
842 dstpixel
[2]=srcpixel
[0];
846 srcbits
+= srclinebytes
;
847 dstbits
+= dstlinebytes
;
851 static void X11DRV_DIB_Convert_888_to_555_asis(int width
, int height
,
852 const void* srcbits
, int srclinebytes
,
853 void* dstbits
, int dstlinebytes
)
855 const DWORD
* srcpixel
;
863 for (y
=0; y
<height
; y
++) {
866 for (x
=0; x
<width
; x
++) {
867 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
868 DWORD srcval1
,srcval2
;
870 dstpixel
[0]=((srcval1
>> 3) & 0x001f) | /* l1 */
871 ((srcval1
>> 6) & 0x03e0) | /* g1 */
872 ((srcval1
>> 9) & 0x7c00); /* h1 */
874 dstpixel
[1]=((srcval1
>> 27) & 0x001f) | /* l2 */
875 ((srcval2
<< 2) & 0x03e0) | /* g2 */
876 ((srcval2
>> 1) & 0x7c00); /* h2 */
878 dstpixel
[2]=((srcval2
>> 19) & 0x001f) | /* l3 */
879 ((srcval2
>> 22) & 0x03e0) | /* g3 */
880 ((srcval1
<< 7) & 0x7c00); /* h3 */
881 dstpixel
[3]=((srcval1
>> 11) & 0x001f) | /* l4 */
882 ((srcval1
>> 14) & 0x03e0) | /* g4 */
883 ((srcval1
>> 17) & 0x7c00); /* h4 */
887 /* And now up to 3 odd pixels */
888 srcbyte
=(LPBYTE
)srcpixel
;
889 for (x
=0; x
<oddwidth
; x
++) {
891 dstval
=((srcbyte
[0] >> 3) & 0x001f); /* l */
892 dstval
|=((srcbyte
[1] << 2) & 0x03e0); /* g */
893 dstval
|=((srcbyte
[2] << 7) & 0x7c00); /* h */
897 srcbits
+= srclinebytes
;
898 dstbits
+= dstlinebytes
;
902 static void X11DRV_DIB_Convert_888_to_555_reverse(int width
, int height
,
903 const void* srcbits
, int srclinebytes
,
904 void* dstbits
, int dstlinebytes
)
906 const DWORD
* srcpixel
;
914 for (y
=0; y
<height
; y
++) {
917 for (x
=0; x
<width
; x
++) {
918 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
919 DWORD srcval1
,srcval2
;
921 dstpixel
[0]=((srcval1
<< 7) & 0x7c00) | /* l1 */
922 ((srcval1
>> 6) & 0x03e0) | /* g1 */
923 ((srcval1
>> 19) & 0x001f); /* h1 */
925 dstpixel
[1]=((srcval1
>> 17) & 0x7c00) | /* l2 */
926 ((srcval2
<< 2) & 0x03e0) | /* g2 */
927 ((srcval2
>> 11) & 0x001f); /* h2 */
929 dstpixel
[2]=((srcval2
>> 9) & 0x7c00) | /* l3 */
930 ((srcval2
>> 22) & 0x03e0) | /* g3 */
931 ((srcval1
>> 3) & 0x001f); /* h3 */
932 dstpixel
[3]=((srcval1
>> 1) & 0x7c00) | /* l4 */
933 ((srcval1
>> 14) & 0x03e0) | /* g4 */
934 ((srcval1
>> 27) & 0x001f); /* h4 */
938 /* And now up to 3 odd pixels */
939 srcbyte
=(LPBYTE
)srcpixel
;
940 for (x
=0; x
<oddwidth
; x
++) {
942 dstval
=((srcbyte
[0] << 7) & 0x7c00); /* l */
943 dstval
|=((srcbyte
[1] << 2) & 0x03e0); /* g */
944 dstval
|=((srcbyte
[2] >> 3) & 0x001f); /* h */
948 srcbits
+= srclinebytes
;
949 dstbits
+= dstlinebytes
;
953 static void X11DRV_DIB_Convert_888_to_565_asis(int width
, int height
,
954 const void* srcbits
, int srclinebytes
,
955 void* dstbits
, int dstlinebytes
)
957 const DWORD
* srcpixel
;
965 for (y
=0; y
<height
; y
++) {
968 for (x
=0; x
<width
; x
++) {
969 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
970 DWORD srcval1
,srcval2
;
972 dstpixel
[0]=((srcval1
>> 3) & 0x001f) | /* l1 */
973 ((srcval1
>> 5) & 0x07e0) | /* g1 */
974 ((srcval1
>> 8) & 0xf800); /* h1 */
976 dstpixel
[1]=((srcval1
>> 27) & 0x001f) | /* l2 */
977 ((srcval2
<< 3) & 0x07e0) | /* g2 */
978 ( srcval2
& 0xf800); /* h2 */
980 dstpixel
[2]=((srcval2
>> 19) & 0x001f) | /* l3 */
981 ((srcval2
>> 21) & 0x07e0) | /* g3 */
982 ((srcval1
<< 8) & 0xf800); /* h3 */
983 dstpixel
[3]=((srcval1
>> 11) & 0x001f) | /* l4 */
984 ((srcval1
>> 13) & 0x07e0) | /* g4 */
985 ((srcval1
>> 16) & 0xf800); /* h4 */
989 /* And now up to 3 odd pixels */
990 srcbyte
=(LPBYTE
)srcpixel
;
991 for (x
=0; x
<oddwidth
; x
++) {
993 dstval
=((srcbyte
[0] >> 3) & 0x001f); /* l */
994 dstval
|=((srcbyte
[1] << 3) & 0x07e0); /* g */
995 dstval
|=((srcbyte
[2] << 8) & 0xf800); /* h */
999 srcbits
+= srclinebytes
;
1000 dstbits
+= dstlinebytes
;
1004 static void X11DRV_DIB_Convert_888_to_565_reverse(int width
, int height
,
1005 const void* srcbits
, int srclinebytes
,
1006 void* dstbits
, int dstlinebytes
)
1008 const DWORD
* srcpixel
;
1009 const BYTE
* srcbyte
;
1016 for (y
=0; y
<height
; y
++) {
1019 for (x
=0; x
<width
; x
++) {
1020 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
1021 DWORD srcval1
,srcval2
;
1022 srcval1
=srcpixel
[0];
1023 dstpixel
[0]=((srcval1
<< 8) & 0xf800) | /* l1 */
1024 ((srcval1
>> 5) & 0x07e0) | /* g1 */
1025 ((srcval1
>> 19) & 0x001f); /* h1 */
1026 srcval2
=srcpixel
[1];
1027 dstpixel
[1]=((srcval1
>> 16) & 0xf800) | /* l2 */
1028 ((srcval2
<< 3) & 0x07e0) | /* g2 */
1029 ((srcval2
>> 11) & 0x001f); /* h2 */
1030 srcval1
=srcpixel
[2];
1031 dstpixel
[2]=((srcval2
>> 8) & 0xf800) | /* l3 */
1032 ((srcval2
>> 21) & 0x07e0) | /* g3 */
1033 ((srcval1
>> 3) & 0x001f); /* h3 */
1034 dstpixel
[3]=(srcval1
& 0xf800) | /* l4 */
1035 ((srcval1
>> 13) & 0x07e0) | /* g4 */
1036 ((srcval1
>> 27) & 0x001f); /* h4 */
1040 /* And now up to 3 odd pixels */
1041 srcbyte
=(LPBYTE
)srcpixel
;
1042 for (x
=0; x
<oddwidth
; x
++) {
1044 dstval
=((srcbyte
[0] << 8) & 0xf800); /* l */
1045 dstval
|=((srcbyte
[1] << 3) & 0x07e0); /* g */
1046 dstval
|=((srcbyte
[2] >> 3) & 0x001f); /* h */
1050 srcbits
+= srclinebytes
;
1051 dstbits
+= dstlinebytes
;
1055 static void X11DRV_DIB_Convert_888_to_0888_asis(int width
, int height
,
1056 const void* srcbits
, int srclinebytes
,
1057 void* dstbits
, int dstlinebytes
)
1059 const DWORD
* srcpixel
;
1066 for (y
=0; y
<height
; y
++) {
1069 for (x
=0; x
<width
; x
++) {
1070 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1071 DWORD srcval1
,srcval2
;
1072 srcval1
=srcpixel
[0];
1073 dstpixel
[0]=( srcval1
& 0x00ffffff); /* h1, g1, l1 */
1074 srcval2
=srcpixel
[1];
1075 dstpixel
[1]=( srcval1
>> 24) | /* l2 */
1076 ((srcval2
<< 8) & 0x00ffff00); /* h2, g2 */
1077 srcval1
=srcpixel
[2];
1078 dstpixel
[2]=( srcval2
>> 16) | /* g3, l3 */
1079 ((srcval1
<< 16) & 0x00ff0000); /* h3 */
1080 dstpixel
[3]=( srcval1
>> 8); /* h4, g4, l4 */
1084 /* And now up to 3 odd pixels */
1085 for (x
=0; x
<oddwidth
; x
++) {
1088 srcpixel
=(LPDWORD
)(((char*)srcpixel
)+3);
1089 *dstpixel
++=( srcval
& 0x00ffffff); /* h, g, l */
1091 srcbits
+= srclinebytes
;
1092 dstbits
+= dstlinebytes
;
1096 static void X11DRV_DIB_Convert_888_to_0888_reverse(int width
, int height
,
1097 const void* srcbits
, int srclinebytes
,
1098 void* dstbits
, int dstlinebytes
)
1100 const DWORD
* srcpixel
;
1107 for (y
=0; y
<height
; y
++) {
1110 for (x
=0; x
<width
; x
++) {
1111 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1112 DWORD srcval1
,srcval2
;
1114 srcval1
=srcpixel
[0];
1115 dstpixel
[0]=((srcval1
>> 16) & 0x0000ff) | /* h1 */
1116 ( srcval1
& 0x00ff00) | /* g1 */
1117 ((srcval1
<< 16) & 0xff0000); /* l1 */
1118 srcval2
=srcpixel
[1];
1119 dstpixel
[1]=((srcval1
>> 8) & 0xff0000) | /* l2 */
1120 ((srcval2
<< 8) & 0x00ff00) | /* g2 */
1121 ((srcval2
>> 8) & 0x0000ff); /* h2 */
1122 srcval1
=srcpixel
[2];
1123 dstpixel
[2]=( srcval2
& 0xff0000) | /* l3 */
1124 ((srcval2
>> 16) & 0x00ff00) | /* g3 */
1125 ( srcval1
& 0x0000ff); /* h3 */
1126 dstpixel
[3]=((srcval1
>> 24) & 0x0000ff) | /* h4 */
1127 ((srcval1
>> 8) & 0x00ff00) | /* g4 */
1128 ((srcval1
<< 8) & 0xff0000); /* l4 */
1132 /* And now up to 3 odd pixels */
1133 for (x
=0; x
<oddwidth
; x
++) {
1136 srcpixel
=(LPDWORD
)(((char*)srcpixel
)+3);
1137 *dstpixel
++=((srcval
>> 16) & 0x0000ff) | /* h */
1138 ( srcval
& 0x00ff00) | /* g */
1139 ((srcval
<< 16) & 0xff0000); /* l */
1141 srcbits
+= srclinebytes
;
1142 dstbits
+= dstlinebytes
;
1146 static void X11DRV_DIB_Convert_rgb888_to_any0888(int width
, int height
,
1147 const void* srcbits
, int srclinebytes
,
1148 void* dstbits
, int dstlinebytes
,
1149 DWORD rdst
, DWORD gdst
, DWORD bdst
)
1151 int rLeftShift
,gLeftShift
,bLeftShift
;
1152 const BYTE
* srcpixel
;
1156 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
1157 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
1158 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
1159 for (y
=0; y
<height
; y
++) {
1162 for (x
=0; x
<width
; x
++) {
1163 *dstpixel
++=(srcpixel
[0] << bLeftShift
) | /* b */
1164 (srcpixel
[1] << gLeftShift
) | /* g */
1165 (srcpixel
[2] << rLeftShift
); /* r */
1168 srcbits
+= srclinebytes
;
1169 dstbits
+= dstlinebytes
;
1173 static void X11DRV_DIB_Convert_bgr888_to_any0888(int width
, int height
,
1174 const void* srcbits
, int srclinebytes
,
1175 void* dstbits
, int dstlinebytes
,
1176 DWORD rdst
, DWORD gdst
, DWORD bdst
)
1178 int rLeftShift
,gLeftShift
,bLeftShift
;
1179 const BYTE
* srcpixel
;
1183 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
1184 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
1185 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
1186 for (y
=0; y
<height
; y
++) {
1189 for (x
=0; x
<width
; x
++) {
1190 *dstpixel
++=(srcpixel
[0] << rLeftShift
) | /* r */
1191 (srcpixel
[1] << gLeftShift
) | /* g */
1192 (srcpixel
[2] << bLeftShift
); /* b */
1195 srcbits
+= srclinebytes
;
1196 dstbits
+= dstlinebytes
;
1201 * 32 bit conversions
1204 static void X11DRV_DIB_Convert_0888_reverse(int width
, int height
,
1205 const void* srcbits
, int srclinebytes
,
1206 void* dstbits
, int dstlinebytes
)
1208 const DWORD
* srcpixel
;
1212 for (y
=0; y
<height
; y
++) {
1215 for (x
=0; x
<width
; x
++) {
1218 *dstpixel
++=((srcval
<< 16) & 0x00ff0000) | /* h */
1219 ( srcval
& 0x0000ff00) | /* g */
1220 ((srcval
>> 16) & 0x000000ff); /* l */
1222 srcbits
+= srclinebytes
;
1223 dstbits
+= dstlinebytes
;
1227 static void X11DRV_DIB_Convert_0888_any(int width
, int height
,
1228 const void* srcbits
, int srclinebytes
,
1229 DWORD rsrc
, DWORD gsrc
, DWORD bsrc
,
1230 void* dstbits
, int dstlinebytes
,
1231 DWORD rdst
, DWORD gdst
, DWORD bdst
)
1233 int rRightShift
,gRightShift
,bRightShift
;
1234 int rLeftShift
,gLeftShift
,bLeftShift
;
1235 const DWORD
* srcpixel
;
1239 rRightShift
=X11DRV_DIB_MaskToShift(rsrc
);
1240 gRightShift
=X11DRV_DIB_MaskToShift(gsrc
);
1241 bRightShift
=X11DRV_DIB_MaskToShift(bsrc
);
1242 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
1243 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
1244 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
1245 for (y
=0; y
<height
; y
++) {
1248 for (x
=0; x
<width
; x
++) {
1251 *dstpixel
++=(((srcval
>> rRightShift
) & 0xff) << rLeftShift
) |
1252 (((srcval
>> gRightShift
) & 0xff) << gLeftShift
) |
1253 (((srcval
>> bRightShift
) & 0xff) << bLeftShift
);
1255 srcbits
+= srclinebytes
;
1256 dstbits
+= dstlinebytes
;
1260 static void X11DRV_DIB_Convert_0888_to_555_asis(int width
, int height
,
1261 const void* srcbits
, int srclinebytes
,
1262 void* dstbits
, int dstlinebytes
)
1264 const DWORD
* srcpixel
;
1268 for (y
=0; y
<height
; y
++) {
1271 for (x
=0; x
<width
; x
++) {
1274 *dstpixel
++=((srcval
>> 9) & 0x7c00) | /* h */
1275 ((srcval
>> 6) & 0x03e0) | /* g */
1276 ((srcval
>> 3) & 0x001f); /* l */
1278 srcbits
+= srclinebytes
;
1279 dstbits
+= dstlinebytes
;
1283 static void X11DRV_DIB_Convert_0888_to_555_reverse(int width
, int height
,
1284 const void* srcbits
, int srclinebytes
,
1285 void* dstbits
, int dstlinebytes
)
1287 const DWORD
* srcpixel
;
1291 for (y
=0; y
<height
; y
++) {
1294 for (x
=0; x
<width
; x
++) {
1297 *dstpixel
++=((srcval
>> 19) & 0x001f) | /* h */
1298 ((srcval
>> 6) & 0x03e0) | /* g */
1299 ((srcval
<< 7) & 0x7c00); /* l */
1301 srcbits
+= srclinebytes
;
1302 dstbits
+= dstlinebytes
;
1306 static void X11DRV_DIB_Convert_0888_to_565_asis(int width
, int height
,
1307 const void* srcbits
, int srclinebytes
,
1308 void* dstbits
, int dstlinebytes
)
1310 const DWORD
* srcpixel
;
1314 for (y
=0; y
<height
; y
++) {
1317 for (x
=0; x
<width
; x
++) {
1320 *dstpixel
++=((srcval
>> 8) & 0xf800) | /* h */
1321 ((srcval
>> 5) & 0x07e0) | /* g */
1322 ((srcval
>> 3) & 0x001f); /* l */
1324 srcbits
+= srclinebytes
;
1325 dstbits
+= dstlinebytes
;
1329 static void X11DRV_DIB_Convert_0888_to_565_reverse(int width
, int height
,
1330 const void* srcbits
, int srclinebytes
,
1331 void* dstbits
, int dstlinebytes
)
1333 const DWORD
* srcpixel
;
1337 for (y
=0; y
<height
; y
++) {
1340 for (x
=0; x
<width
; x
++) {
1343 *dstpixel
++=((srcval
>> 19) & 0x001f) | /* h */
1344 ((srcval
>> 5) & 0x07e0) | /* g */
1345 ((srcval
<< 8) & 0xf800); /* l */
1347 srcbits
+= srclinebytes
;
1348 dstbits
+= dstlinebytes
;
1352 static void X11DRV_DIB_Convert_any0888_to_5x5(int width
, int height
,
1353 const void* srcbits
, int srclinebytes
,
1354 DWORD rsrc
, DWORD gsrc
, DWORD bsrc
,
1355 void* dstbits
, int dstlinebytes
,
1356 WORD rdst
, WORD gdst
, WORD bdst
)
1358 int rRightShift
,gRightShift
,bRightShift
;
1359 int rLeftShift
,gLeftShift
,bLeftShift
;
1360 const DWORD
* srcpixel
;
1364 /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel
1365 * contains 0x11223344.
1366 * - first we shift 0x11223344 right by rRightShift to bring the most
1367 * significant bits of the red components in the bottom 5 (or 6) bits
1369 * - then we remove non red bits by anding with the modified rdst (0x1f)
1371 * - finally shift these bits left by rLeftShift so that they end up in
1375 rRightShift
=X11DRV_DIB_MaskToShift(rsrc
)+3;
1376 gRightShift
=X11DRV_DIB_MaskToShift(gsrc
);
1377 gRightShift
+=(gdst
==0x07e0?2:3);
1378 bRightShift
=X11DRV_DIB_MaskToShift(bsrc
)+3;
1380 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
1381 rdst
=rdst
>> rLeftShift
;
1382 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
1383 gdst
=gdst
>> gLeftShift
;
1384 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
1385 bdst
=bdst
>> bLeftShift
;
1387 for (y
=0; y
<height
; y
++) {
1390 for (x
=0; x
<width
; x
++) {
1393 *dstpixel
++=(((srcval
>> rRightShift
) & rdst
) << rLeftShift
) |
1394 (((srcval
>> gRightShift
) & gdst
) << gLeftShift
) |
1395 (((srcval
>> bRightShift
) & bdst
) << bLeftShift
);
1397 srcbits
+= srclinebytes
;
1398 dstbits
+= dstlinebytes
;
1402 static void X11DRV_DIB_Convert_0888_to_888_asis(int width
, int height
,
1403 const void* srcbits
, int srclinebytes
,
1404 void* dstbits
, int dstlinebytes
)
1406 const DWORD
* srcpixel
;
1414 for (y
=0; y
<height
; y
++) {
1417 for (x
=0; x
<width
; x
++) {
1418 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1420 srcval
=((*srcpixel
++) & 0x00ffffff); /* h1, g1, l1*/
1421 *dstpixel
++=srcval
| ((*srcpixel
) << 24); /* h2 */
1422 srcval
=((*srcpixel
++ >> 8 ) & 0x0000ffff); /* g2, l2 */
1423 *dstpixel
++=srcval
| ((*srcpixel
) << 16); /* h3, g3 */
1424 srcval
=((*srcpixel
++ >> 16) & 0x000000ff); /* l3 */
1425 *dstpixel
++=srcval
| ((*srcpixel
++) << 8); /* h4, g4, l4 */
1427 /* And now up to 3 odd pixels */
1428 dstbyte
=(BYTE
*)dstpixel
;
1429 for (x
=0; x
<oddwidth
; x
++) {
1432 *((WORD
*)dstbyte
)++=srcval
; /* h, g */
1433 *dstbyte
++=srcval
>> 16; /* l */
1435 srcbits
+= srclinebytes
;
1436 dstbits
+= dstlinebytes
;
1440 static void X11DRV_DIB_Convert_0888_to_888_reverse(int width
, int height
,
1441 const void* srcbits
, int srclinebytes
,
1442 void* dstbits
, int dstlinebytes
)
1444 const DWORD
* srcpixel
;
1452 for (y
=0; y
<height
; y
++) {
1455 for (x
=0; x
<width
; x
++) {
1456 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1457 DWORD srcval1
,srcval2
;
1458 srcval1
=*srcpixel
++;
1459 srcval2
= ((srcval1
>> 16) & 0x000000ff) | /* h1 */
1460 ( srcval1
& 0x0000ff00) | /* g1 */
1461 ((srcval1
<< 16) & 0x00ff0000); /* l1 */
1462 srcval1
=*srcpixel
++;
1463 *dstpixel
++=srcval2
|
1464 ((srcval1
<< 8) & 0xff000000); /* h2 */
1465 srcval2
= ((srcval1
>> 8) & 0x000000ff) | /* g2 */
1466 ((srcval1
<< 8) & 0x0000ff00); /* l2 */
1467 srcval1
=*srcpixel
++;
1468 *dstpixel
++=srcval2
|
1469 ( srcval1
& 0x00ff0000) | /* h3 */
1470 ((srcval1
<< 16) & 0xff000000); /* g3 */
1471 srcval2
= ( srcval1
& 0x000000ff); /* l3 */
1472 srcval1
=*srcpixel
++;
1473 *dstpixel
++=srcval2
|
1474 ((srcval1
>> 8) & 0x0000ff00) | /* h4 */
1475 ((srcval1
<< 8) & 0x00ff0000) | /* g4 */
1476 ( srcval1
<< 24); /* l4 */
1478 /* And now up to 3 odd pixels */
1479 dstbyte
=(BYTE
*)dstpixel
;
1480 for (x
=0; x
<oddwidth
; x
++) {
1483 *((WORD
*)dstbyte
)++=((srcval
>> 16) & 0x00ff) | /* h */
1484 (srcval
& 0xff00); /* g */
1485 *dstbyte
++=srcval
; /* l */
1487 srcbits
+= srclinebytes
;
1488 dstbits
+= dstlinebytes
;
1492 static void X11DRV_DIB_Convert_any0888_to_rgb888(int width
, int height
,
1493 const void* srcbits
, int srclinebytes
,
1494 DWORD rsrc
, DWORD gsrc
, DWORD bsrc
,
1495 void* dstbits
, int dstlinebytes
)
1497 int rRightShift
,gRightShift
,bRightShift
;
1498 const DWORD
* srcpixel
;
1502 rRightShift
=X11DRV_DIB_MaskToShift(rsrc
);
1503 gRightShift
=X11DRV_DIB_MaskToShift(gsrc
);
1504 bRightShift
=X11DRV_DIB_MaskToShift(bsrc
);
1505 for (y
=0; y
<height
; y
++) {
1508 for (x
=0; x
<width
; x
++) {
1511 dstpixel
[0]=(srcval
>> bRightShift
); /* b */
1512 dstpixel
[1]=(srcval
>> gRightShift
); /* g */
1513 dstpixel
[2]=(srcval
>> rRightShift
); /* r */
1516 srcbits
+= srclinebytes
;
1517 dstbits
+= dstlinebytes
;
1521 static void X11DRV_DIB_Convert_any0888_to_bgr888(int width
, int height
,
1522 const void* srcbits
, int srclinebytes
,
1523 DWORD rsrc
, DWORD gsrc
, DWORD bsrc
,
1524 void* dstbits
, int dstlinebytes
)
1526 int rRightShift
,gRightShift
,bRightShift
;
1527 const DWORD
* srcpixel
;
1531 rRightShift
=X11DRV_DIB_MaskToShift(rsrc
);
1532 gRightShift
=X11DRV_DIB_MaskToShift(gsrc
);
1533 bRightShift
=X11DRV_DIB_MaskToShift(bsrc
);
1534 for (y
=0; y
<height
; y
++) {
1537 for (x
=0; x
<width
; x
++) {
1540 dstpixel
[0]=(srcval
>> rRightShift
); /* r */
1541 dstpixel
[1]=(srcval
>> gRightShift
); /* g */
1542 dstpixel
[2]=(srcval
>> bRightShift
); /* b */
1545 srcbits
+= srclinebytes
;
1546 dstbits
+= dstlinebytes
;
1550 /***********************************************************************
1551 * X11DRV_DIB_SetImageBits_1
1553 * SetDIBits for a 1-bit deep DIB.
1555 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
1556 DWORD srcwidth
, DWORD dstwidth
, int left
,
1557 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
1560 const BYTE
* srcbyte
;
1566 srcbits
= srcbits
+ linebytes
* (lines
- 1);
1567 linebytes
= -linebytes
;
1570 if ((extra
= (left
& 7)) != 0) {
1574 srcbits
+= left
>> 3;
1576 /* ==== pal 1 dib -> any bmp format ==== */
1577 for (h
= lines
-1; h
>=0; h
--) {
1579 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
1580 for (i
= dstwidth
/8, x
= left
; i
> 0; i
--) {
1582 XPutPixel( bmpImage
, x
++, h
, colors
[ srcval
>> 7] );
1583 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 6) & 1] );
1584 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 5) & 1] );
1585 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 4) & 1] );
1586 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 3) & 1] );
1587 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 2) & 1] );
1588 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 1) & 1] );
1589 XPutPixel( bmpImage
, x
++, h
, colors
[ srcval
& 1] );
1592 switch (dstwidth
& 7)
1594 case 7: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1595 case 6: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1596 case 5: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1597 case 4: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1598 case 3: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1599 case 2: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1600 case 1: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]);
1602 srcbits
+= linebytes
;
1606 /***********************************************************************
1607 * X11DRV_DIB_GetImageBits_1
1609 * GetDIBits for a 1-bit deep DIB.
1611 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
1612 DWORD dstwidth
, DWORD srcwidth
,
1613 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
1614 XImage
*bmpImage
, DWORD linebytes
)
1621 dstbits
= dstbits
+ linebytes
* (lines
- 1);
1622 linebytes
= -linebytes
;
1625 switch (bmpImage
->depth
)
1629 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
1630 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
1633 for (h
=lines
-1; h
>=0; h
--) {
1637 for (x
=0; x
<dstwidth
; x
++) {
1638 PALETTEENTRY srcval
;
1639 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
1640 dstval
|=(X11DRV_DIB_GetNearestIndex
1644 srcval
.peBlue
) << (7 - (x
& 7)));
1650 if ((dstwidth
&7)!=0) {
1653 dstbits
+= linebytes
;
1661 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
1662 /* ==== pal 8 bmp -> pal 1 dib ==== */
1663 const void* srcbits
;
1664 const BYTE
* srcpixel
;
1667 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1669 for (h
=0; h
<lines
; h
++) {
1674 for (x
=0; x
<dstwidth
; x
++) {
1675 PALETTEENTRY srcval
;
1676 srcval
=srccolors
[(int)*srcpixel
++];
1677 dstval
|=(X11DRV_DIB_GetNearestIndex
1681 srcval
.peBlue
) << (7-(x
&7)) );
1687 if ((dstwidth
&7)!=0) {
1690 srcbits
-= bmpImage
->bytes_per_line
;
1691 dstbits
+= linebytes
;
1701 const void* srcbits
;
1702 const WORD
* srcpixel
;
1705 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1707 if (bmpImage
->green_mask
==0x03e0) {
1708 if (bmpImage
->red_mask
==0x7c00) {
1709 /* ==== rgb 555 bmp -> pal 1 dib ==== */
1710 for (h
=0; h
<lines
; h
++) {
1715 for (x
=0; x
<dstwidth
; x
++) {
1718 dstval
|=(X11DRV_DIB_GetNearestIndex
1720 ((srcval
>> 7) & 0xf8) | /* r */
1721 ((srcval
>> 12) & 0x07),
1722 ((srcval
>> 2) & 0xf8) | /* g */
1723 ((srcval
>> 7) & 0x07),
1724 ((srcval
<< 3) & 0xf8) | /* b */
1725 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
1731 if ((dstwidth
&7)!=0) {
1734 srcbits
-= bmpImage
->bytes_per_line
;
1735 dstbits
+= linebytes
;
1737 } else if (bmpImage
->blue_mask
==0x7c00) {
1738 /* ==== bgr 555 bmp -> pal 1 dib ==== */
1739 for (h
=0; h
<lines
; h
++) {
1744 for (x
=0; x
<dstwidth
; x
++) {
1747 dstval
|=(X11DRV_DIB_GetNearestIndex
1749 ((srcval
<< 3) & 0xf8) | /* r */
1750 ((srcval
>> 2) & 0x07),
1751 ((srcval
>> 2) & 0xf8) | /* g */
1752 ((srcval
>> 7) & 0x07),
1753 ((srcval
>> 7) & 0xf8) | /* b */
1754 ((srcval
>> 12) & 0x07) ) << (7-(x
&7)) );
1760 if ((dstwidth
&7)!=0) {
1763 srcbits
-= bmpImage
->bytes_per_line
;
1764 dstbits
+= linebytes
;
1769 } else if (bmpImage
->green_mask
==0x07e0) {
1770 if (bmpImage
->red_mask
==0xf800) {
1771 /* ==== rgb 565 bmp -> pal 1 dib ==== */
1772 for (h
=0; h
<lines
; h
++) {
1777 for (x
=0; x
<dstwidth
; x
++) {
1780 dstval
|=(X11DRV_DIB_GetNearestIndex
1782 ((srcval
>> 8) & 0xf8) | /* r */
1783 ((srcval
>> 13) & 0x07),
1784 ((srcval
>> 3) & 0xfc) | /* g */
1785 ((srcval
>> 9) & 0x03),
1786 ((srcval
<< 3) & 0xf8) | /* b */
1787 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
1793 if ((dstwidth
&7)!=0) {
1796 srcbits
-= bmpImage
->bytes_per_line
;
1797 dstbits
+= linebytes
;
1799 } else if (bmpImage
->blue_mask
==0xf800) {
1800 /* ==== bgr 565 bmp -> pal 1 dib ==== */
1801 for (h
=0; h
<lines
; h
++) {
1806 for (x
=0; x
<dstwidth
; x
++) {
1809 dstval
|=(X11DRV_DIB_GetNearestIndex
1811 ((srcval
<< 3) & 0xf8) | /* r */
1812 ((srcval
>> 2) & 0x07),
1813 ((srcval
>> 3) & 0xfc) | /* g */
1814 ((srcval
>> 9) & 0x03),
1815 ((srcval
>> 8) & 0xf8) | /* b */
1816 ((srcval
>> 13) & 0x07) ) << (7-(x
&7)) );
1822 if ((dstwidth
&7)!=0) {
1825 srcbits
-= bmpImage
->bytes_per_line
;
1826 dstbits
+= linebytes
;
1840 const void* srcbits
;
1841 const BYTE
*srcbyte
;
1843 int bytes_per_pixel
;
1845 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1846 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
1848 if (bmpImage
->green_mask
!=0x00ff00 ||
1849 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1851 } else if (bmpImage
->blue_mask
==0xff) {
1852 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
1853 for (h
=0; h
<lines
; h
++) {
1858 for (x
=0; x
<dstwidth
; x
++) {
1859 dstval
|=(X11DRV_DIB_GetNearestIndex
1863 srcbyte
[0]) << (7-(x
&7)) );
1864 srcbyte
+=bytes_per_pixel
;
1870 if ((dstwidth
&7)!=0) {
1873 srcbits
-= bmpImage
->bytes_per_line
;
1874 dstbits
+= linebytes
;
1877 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
1878 for (h
=0; h
<lines
; h
++) {
1883 for (x
=0; x
<dstwidth
; x
++) {
1884 dstval
|=(X11DRV_DIB_GetNearestIndex
1888 srcbyte
[2]) << (7-(x
&7)) );
1889 srcbyte
+=bytes_per_pixel
;
1895 if ((dstwidth
&7)!=0) {
1898 srcbits
-= bmpImage
->bytes_per_line
;
1899 dstbits
+= linebytes
;
1909 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
1911 /* ==== any bmp format -> pal 1 dib ==== */
1912 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
1913 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
1914 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1916 for (h
=lines
-1; h
>=0; h
--) {
1920 for (x
=0; x
<dstwidth
; x
++) {
1921 dstval
|=(XGetPixel( bmpImage
, x
, h
) >= white
) << (7 - (x
&7));
1927 if ((dstwidth
&7)!=0) {
1930 dstbits
+= linebytes
;
1937 /***********************************************************************
1938 * X11DRV_DIB_SetImageBits_4
1940 * SetDIBits for a 4-bit deep DIB.
1942 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
1943 DWORD srcwidth
, DWORD dstwidth
, int left
,
1944 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
1947 const BYTE
* srcbyte
;
1952 srcbits
= srcbits
+ linebytes
* (lines
- 1);
1953 linebytes
= -linebytes
;
1960 srcbits
+= left
>> 1;
1962 /* ==== pal 4 dib -> any bmp format ==== */
1963 for (h
= lines
-1; h
>= 0; h
--) {
1965 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
1966 BYTE srcval
=*srcbyte
++;
1967 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
>> 4] );
1968 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
& 0x0f] );
1971 XPutPixel( bmpImage
, x
, h
, colors
[*srcbyte
>> 4] );
1972 srcbits
+= linebytes
;
1978 /***********************************************************************
1979 * X11DRV_DIB_GetImageBits_4
1981 * GetDIBits for a 4-bit deep DIB.
1983 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
1984 DWORD srcwidth
, DWORD dstwidth
,
1985 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
1986 XImage
*bmpImage
, DWORD linebytes
)
1995 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
1996 linebytes
= -linebytes
;
2001 switch (bmpImage
->depth
) {
2004 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2005 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
2008 for (h
= lines
-1; h
>= 0; h
--) {
2012 for (x
= 0; x
< dstwidth
; x
++) {
2013 PALETTEENTRY srcval
;
2014 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2015 dstval
|=(X11DRV_DIB_GetNearestIndex
2019 srcval
.peBlue
) << (4-((x
&1)<<2)));
2025 if ((dstwidth
&1)!=0) {
2028 dstbits
+= linebytes
;
2036 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2037 /* ==== pal 8 bmp -> pal 4 dib ==== */
2038 const void* srcbits
;
2039 const BYTE
*srcpixel
;
2042 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2043 for (h
=0; h
<lines
; h
++) {
2048 for (x
=0; x
<dstwidth
; x
++) {
2049 PALETTEENTRY srcval
;
2050 srcval
= srccolors
[(int)*srcpixel
++];
2051 dstval
|=(X11DRV_DIB_GetNearestIndex
2055 srcval
.peBlue
) << (4*(1-(x
&1))) );
2061 if ((dstwidth
&1)!=0) {
2064 srcbits
-= bmpImage
->bytes_per_line
;
2065 dstbits
+= linebytes
;
2075 const void* srcbits
;
2076 const WORD
* srcpixel
;
2079 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2081 if (bmpImage
->green_mask
==0x03e0) {
2082 if (bmpImage
->red_mask
==0x7c00) {
2083 /* ==== rgb 555 bmp -> pal 4 dib ==== */
2084 for (h
=0; h
<lines
; h
++) {
2089 for (x
=0; x
<dstwidth
; x
++) {
2092 dstval
|=(X11DRV_DIB_GetNearestIndex
2094 ((srcval
>> 7) & 0xf8) | /* r */
2095 ((srcval
>> 12) & 0x07),
2096 ((srcval
>> 2) & 0xf8) | /* g */
2097 ((srcval
>> 7) & 0x07),
2098 ((srcval
<< 3) & 0xf8) | /* b */
2099 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
2105 if ((dstwidth
&1)!=0) {
2108 srcbits
-= bmpImage
->bytes_per_line
;
2109 dstbits
+= linebytes
;
2111 } else if (bmpImage
->blue_mask
==0x7c00) {
2112 /* ==== bgr 555 bmp -> pal 4 dib ==== */
2113 for (h
=0; h
<lines
; h
++) {
2118 for (x
=0; x
<dstwidth
; x
++) {
2121 dstval
|=(X11DRV_DIB_GetNearestIndex
2123 ((srcval
<< 3) & 0xf8) | /* r */
2124 ((srcval
>> 2) & 0x07),
2125 ((srcval
>> 2) & 0xf8) | /* g */
2126 ((srcval
>> 7) & 0x07),
2127 ((srcval
>> 7) & 0xf8) | /* b */
2128 ((srcval
>> 12) & 0x07) ) << ((1-(x
&1))<<2) );
2134 if ((dstwidth
&1)!=0) {
2137 srcbits
-= bmpImage
->bytes_per_line
;
2138 dstbits
+= linebytes
;
2143 } else if (bmpImage
->green_mask
==0x07e0) {
2144 if (bmpImage
->red_mask
==0xf800) {
2145 /* ==== rgb 565 bmp -> pal 4 dib ==== */
2146 for (h
=0; h
<lines
; h
++) {
2151 for (x
=0; x
<dstwidth
; x
++) {
2154 dstval
|=(X11DRV_DIB_GetNearestIndex
2156 ((srcval
>> 8) & 0xf8) | /* r */
2157 ((srcval
>> 13) & 0x07),
2158 ((srcval
>> 3) & 0xfc) | /* g */
2159 ((srcval
>> 9) & 0x03),
2160 ((srcval
<< 3) & 0xf8) | /* b */
2161 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
2167 if ((dstwidth
&1)!=0) {
2170 srcbits
-= bmpImage
->bytes_per_line
;
2171 dstbits
+= linebytes
;
2173 } else if (bmpImage
->blue_mask
==0xf800) {
2174 /* ==== bgr 565 bmp -> pal 4 dib ==== */
2175 for (h
=0; h
<lines
; h
++) {
2180 for (x
=0; x
<dstwidth
; x
++) {
2183 dstval
|=(X11DRV_DIB_GetNearestIndex
2185 ((srcval
<< 3) & 0xf8) | /* r */
2186 ((srcval
>> 2) & 0x07),
2187 ((srcval
>> 3) & 0xfc) | /* g */
2188 ((srcval
>> 9) & 0x03),
2189 ((srcval
>> 8) & 0xf8) | /* b */
2190 ((srcval
>> 13) & 0x07) ) << ((1-(x
&1))<<2) );
2196 if ((dstwidth
&1)!=0) {
2199 srcbits
-= bmpImage
->bytes_per_line
;
2200 dstbits
+= linebytes
;
2212 if (bmpImage
->bits_per_pixel
==24) {
2213 const void* srcbits
;
2214 const BYTE
*srcbyte
;
2217 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2219 if (bmpImage
->green_mask
!=0x00ff00 ||
2220 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2222 } else if (bmpImage
->blue_mask
==0xff) {
2223 /* ==== rgb 888 bmp -> pal 4 dib ==== */
2224 for (h
=0; h
<lines
; h
++) {
2227 for (x
=0; x
<dstwidth
/2; x
++) {
2228 /* Do 2 pixels at a time */
2229 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2234 X11DRV_DIB_GetNearestIndex
2242 /* And the the odd pixel */
2243 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2249 srcbits
-= bmpImage
->bytes_per_line
;
2250 dstbits
+= linebytes
;
2253 /* ==== bgr 888 bmp -> pal 4 dib ==== */
2254 for (h
=0; h
<lines
; h
++) {
2257 for (x
=0; x
<dstwidth
/2; x
++) {
2258 /* Do 2 pixels at a time */
2259 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2264 X11DRV_DIB_GetNearestIndex
2272 /* And the the odd pixel */
2273 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2279 srcbits
-= bmpImage
->bytes_per_line
;
2280 dstbits
+= linebytes
;
2289 const void* srcbits
;
2290 const BYTE
*srcbyte
;
2293 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2295 if (bmpImage
->green_mask
!=0x00ff00 ||
2296 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2298 } else if (bmpImage
->blue_mask
==0xff) {
2299 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
2300 for (h
=0; h
<lines
; h
++) {
2303 for (x
=0; x
<dstwidth
/2; x
++) {
2304 /* Do 2 pixels at a time */
2305 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2310 X11DRV_DIB_GetNearestIndex
2318 /* And the the odd pixel */
2319 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2325 srcbits
-= bmpImage
->bytes_per_line
;
2326 dstbits
+= linebytes
;
2329 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
2330 for (h
=0; h
<lines
; h
++) {
2333 for (x
=0; x
<dstwidth
/2; x
++) {
2334 /* Do 2 pixels at a time */
2335 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2340 X11DRV_DIB_GetNearestIndex
2348 /* And the the odd pixel */
2349 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2355 srcbits
-= bmpImage
->bytes_per_line
;
2356 dstbits
+= linebytes
;
2367 /* ==== any bmp format -> pal 4 dib ==== */
2368 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
2369 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
2370 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2371 for (h
=lines
-1; h
>=0; h
--) {
2373 for (x
=0; x
<(dstwidth
& ~1); x
+=2) {
2374 *dstbyte
++=(X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4) |
2375 X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
+1, h
), 0);
2378 *dstbyte
=(X11DRV_DIB_MapColor((int *)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4);
2380 dstbits
+= linebytes
;
2387 /***********************************************************************
2388 * X11DRV_DIB_SetImageBits_RLE4
2390 * SetDIBits for a 4-bit deep compressed DIB.
2392 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
2393 DWORD width
, DWORD dstwidth
,
2394 int left
, int *colors
,
2397 int x
= 0, y
= lines
- 1, c
, length
;
2398 const BYTE
*begin
= bits
;
2403 if (length
) { /* encoded */
2406 if (x
>= width
) break;
2407 XPutPixel(bmpImage
, x
++, y
, colors
[c
>> 4]);
2408 if (!length
--) break;
2409 if (x
>= width
) break;
2410 XPutPixel(bmpImage
, x
++, y
, colors
[c
& 0xf]);
2429 default: /* absolute */
2432 if (x
< width
) XPutPixel(bmpImage
, x
++, y
, colors
[c
>> 4]);
2433 if (!length
--) break;
2434 if (x
< width
) XPutPixel(bmpImage
, x
++, y
, colors
[c
& 0xf]);
2436 if ((bits
- begin
) & 1)
2445 /***********************************************************************
2446 * X11DRV_DIB_SetImageBits_8
2448 * SetDIBits for an 8-bit deep DIB.
2450 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
2451 DWORD srcwidth
, DWORD dstwidth
, int left
,
2452 const int *colors
, XImage
*bmpImage
,
2457 const BYTE
* srcbyte
;
2463 srcbits
= srcbits
+ linebytes
* (lines
-1);
2464 linebytes
= -linebytes
;
2469 switch (bmpImage
->depth
) {
2472 #if defined(__i386__) && defined(__GNUC__)
2473 /* Some X servers might have 32 bit/ 16bit deep pixel */
2474 if (lines
&& dstwidth
&& (bmpImage
->bits_per_pixel
== 16))
2476 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2477 /* FIXME: Does this really handle all these cases correctly? */
2478 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
2479 for (h
= lines
; h
--; ) {
2480 int _cl1
,_cl2
; /* temp outputs for asm below */
2481 /* Borrowed from DirectDraw */
2482 __asm__
__volatile__(
2487 " movw (%%edx,%%eax,4),%%ax\n"
2489 " xor %%eax,%%eax\n"
2491 :"=S" (srcbyte
), "=D" (_cl1
), "=c" (_cl2
)
2496 :"eax", "cc", "memory"
2498 srcbyte
= (srcbits
+= linebytes
);
2499 dstbits
-= bmpImage
->bytes_per_line
;
2507 #if defined(__i386__) && defined(__GNUC__)
2508 if (lines
&& dstwidth
&& (bmpImage
->bits_per_pixel
== 32))
2510 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
2511 /* FIXME: Does this really handle both cases correctly? */
2512 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
2513 for (h
= lines
; h
--; ) {
2514 int _cl1
,_cl2
; /* temp outputs for asm below */
2515 /* Borrowed from DirectDraw */
2516 __asm__
__volatile__(
2521 " movl (%%edx,%%eax,4),%%eax\n"
2523 " xor %%eax,%%eax\n"
2525 :"=S" (srcbyte
), "=D" (_cl1
), "=c" (_cl2
)
2530 :"eax", "cc", "memory"
2532 srcbyte
= (srcbits
+= linebytes
);
2533 dstbits
-= bmpImage
->bytes_per_line
;
2540 break; /* use slow generic case below */
2543 /* ==== pal 8 dib -> any bmp format ==== */
2544 for (h
=lines
-1; h
>=0; h
--) {
2545 for (x
=left
; x
<dstwidth
+left
; x
++) {
2546 XPutPixel(bmpImage
, x
, h
, colors
[*srcbyte
++]);
2548 srcbyte
= (srcbits
+= linebytes
);
2552 /***********************************************************************
2553 * X11DRV_DIB_GetImageBits_8
2555 * GetDIBits for an 8-bit deep DIB.
2557 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
2558 DWORD srcwidth
, DWORD dstwidth
,
2559 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
2560 XImage
*bmpImage
, DWORD linebytes
)
2569 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2570 linebytes
= -linebytes
;
2575 * This condition is true when GetImageBits has been called by
2576 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
2577 * 256 colormaps, so we'll just use for for GetDIBits calls.
2578 * (In somes cases, in a updateDIBSection, the returned colors are bad too)
2580 if (!srccolors
) goto updatesection
;
2582 switch (bmpImage
->depth
) {
2585 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2587 /* ==== pal 1 bmp -> pal 8 dib ==== */
2588 /* ==== pal 4 bmp -> pal 8 dib ==== */
2589 for (h
=lines
-1; h
>=0; h
--) {
2591 for (x
=0; x
<dstwidth
; x
++) {
2592 PALETTEENTRY srcval
;
2593 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2594 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
2599 dstbits
+= linebytes
;
2607 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2608 /* ==== pal 8 bmp -> pal 8 dib ==== */
2609 const void* srcbits
;
2610 const BYTE
* srcpixel
;
2612 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2613 for (h
=0; h
<lines
; h
++) {
2616 for (x
= 0; x
< dstwidth
; x
++) {
2617 PALETTEENTRY srcval
;
2618 srcval
=srccolors
[(int)*srcpixel
++];
2619 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
2624 srcbits
-= bmpImage
->bytes_per_line
;
2625 dstbits
+= linebytes
;
2635 const void* srcbits
;
2636 const WORD
* srcpixel
;
2639 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2641 if (bmpImage
->green_mask
==0x03e0) {
2642 if (bmpImage
->red_mask
==0x7c00) {
2643 /* ==== rgb 555 bmp -> pal 8 dib ==== */
2644 for (h
=0; h
<lines
; h
++) {
2647 for (x
=0; x
<dstwidth
; x
++) {
2650 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2652 ((srcval
>> 7) & 0xf8) | /* r */
2653 ((srcval
>> 12) & 0x07),
2654 ((srcval
>> 2) & 0xf8) | /* g */
2655 ((srcval
>> 7) & 0x07),
2656 ((srcval
<< 3) & 0xf8) | /* b */
2657 ((srcval
>> 2) & 0x07) );
2659 srcbits
-= bmpImage
->bytes_per_line
;
2660 dstbits
+= linebytes
;
2662 } else if (bmpImage
->blue_mask
==0x7c00) {
2663 /* ==== bgr 555 bmp -> pal 8 dib ==== */
2664 for (h
=0; h
<lines
; h
++) {
2667 for (x
=0; x
<dstwidth
; x
++) {
2670 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2672 ((srcval
<< 3) & 0xf8) | /* r */
2673 ((srcval
>> 2) & 0x07),
2674 ((srcval
>> 2) & 0xf8) | /* g */
2675 ((srcval
>> 7) & 0x07),
2676 ((srcval
>> 7) & 0xf8) | /* b */
2677 ((srcval
>> 12) & 0x07) );
2679 srcbits
-= bmpImage
->bytes_per_line
;
2680 dstbits
+= linebytes
;
2685 } else if (bmpImage
->green_mask
==0x07e0) {
2686 if (bmpImage
->red_mask
==0xf800) {
2687 /* ==== rgb 565 bmp -> pal 8 dib ==== */
2688 for (h
=0; h
<lines
; h
++) {
2691 for (x
=0; x
<dstwidth
; x
++) {
2694 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2696 ((srcval
>> 8) & 0xf8) | /* r */
2697 ((srcval
>> 13) & 0x07),
2698 ((srcval
>> 3) & 0xfc) | /* g */
2699 ((srcval
>> 9) & 0x03),
2700 ((srcval
<< 3) & 0xf8) | /* b */
2701 ((srcval
>> 2) & 0x07) );
2703 srcbits
-= bmpImage
->bytes_per_line
;
2704 dstbits
+= linebytes
;
2706 } else if (bmpImage
->blue_mask
==0xf800) {
2707 /* ==== bgr 565 bmp -> pal 8 dib ==== */
2708 for (h
=0; h
<lines
; h
++) {
2711 for (x
=0; x
<dstwidth
; x
++) {
2714 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2716 ((srcval
<< 3) & 0xf8) | /* r */
2717 ((srcval
>> 2) & 0x07),
2718 ((srcval
>> 3) & 0xfc) | /* g */
2719 ((srcval
>> 9) & 0x03),
2720 ((srcval
>> 8) & 0xf8) | /* b */
2721 ((srcval
>> 13) & 0x07) );
2723 srcbits
-= bmpImage
->bytes_per_line
;
2724 dstbits
+= linebytes
;
2738 const void* srcbits
;
2739 const BYTE
*srcbyte
;
2741 int bytes_per_pixel
;
2743 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2744 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
2746 if (bmpImage
->green_mask
!=0x00ff00 ||
2747 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2749 } else if (bmpImage
->blue_mask
==0xff) {
2750 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
2751 for (h
=0; h
<lines
; h
++) {
2754 for (x
=0; x
<dstwidth
; x
++) {
2755 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2760 srcbyte
+=bytes_per_pixel
;
2762 srcbits
-= bmpImage
->bytes_per_line
;
2763 dstbits
+= linebytes
;
2766 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
2767 for (h
=0; h
<lines
; h
++) {
2770 for (x
=0; x
<dstwidth
; x
++) {
2771 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2776 srcbyte
+=bytes_per_pixel
;
2778 srcbits
-= bmpImage
->bytes_per_line
;
2779 dstbits
+= linebytes
;
2787 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
2788 bmpImage
->depth
, bmpImage
->red_mask
,
2789 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2791 /* ==== any bmp format -> pal 8 dib ==== */
2792 for (h
=lines
-1; h
>=0; h
--) {
2794 for (x
=0; x
<dstwidth
; x
++) {
2795 *dstbyte
=X11DRV_DIB_MapColor
2797 XGetPixel(bmpImage
, x
, h
), *dstbyte
);
2800 dstbits
+= linebytes
;
2806 /***********************************************************************
2807 * X11DRV_DIB_SetImageBits_RLE8
2809 * SetDIBits for an 8-bit deep compressed DIB.
2811 * This function rewritten 941113 by James Youngman. WINE blew out when I
2812 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
2814 * This was because the algorithm assumed that all RLE8 bitmaps end with the
2815 * 'End of bitmap' escape code. This code is very much laxer in what it
2816 * allows to end the expansion. Possibly too lax. See the note by
2817 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
2818 * bitmap should end with RleEnd, but on the other hand, software exists
2819 * that produces ones that don't and Windows 3.1 doesn't complain a bit
2822 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
2823 * James A. Youngman <mbcstjy@afs.man.ac.uk>
2826 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
2827 DWORD width
, DWORD dstwidth
,
2828 int left
, int *colors
,
2831 int x
; /* X-positon on each line. Increases. */
2832 int y
; /* Line #. Starts at lines-1, decreases */
2833 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
2834 BYTE length
; /* The length pf a run */
2835 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
2838 * Note that the bitmap data is stored by Windows starting at the
2839 * bottom line of the bitmap and going upwards. Within each line,
2840 * the data is stored left-to-right. That's the reason why line
2841 * goes from lines-1 to 0. [JAY]
2851 * If the length byte is not zero (which is the escape value),
2852 * We have a run of length pixels all the same colour. The colour
2853 * index is stored next.
2855 * If the length byte is zero, we need to read the next byte to
2856 * know what to do. [JAY]
2861 * [Run-Length] Encoded mode
2863 int color
= colors
[*pIn
++];
2864 while (length
-- && x
< dstwidth
) XPutPixel(bmpImage
, x
++, y
, color
);
2869 * Escape codes (may be an absolute sequence though)
2871 escape_code
= (*pIn
++);
2880 /* Not all RLE8 bitmaps end with this code. For
2881 * example, Paint Shop Pro produces some that don't.
2882 * That's (I think) what caused the previous
2883 * implementation to fail. [JAY]
2892 default: /* switch to absolute mode */
2893 length
= escape_code
;
2896 int color
= colors
[*pIn
++];
2902 XPutPixel(bmpImage
, x
++, y
, color
);
2905 * If you think for a moment you'll realise that the
2906 * only time we could ever possibly read an odd
2907 * number of bytes is when there is a 0x00 (escape),
2908 * a value >0x02 (absolute mode) and then an odd-
2909 * length run. Therefore this is the only place we
2910 * need to worry about it. Everywhere else the
2911 * bytes are always read in pairs. [JAY]
2913 if (escape_code
& 1) pIn
++; /* Throw away the pad byte. */
2915 } /* switch (escape_code) : Escape sequence */
2921 /***********************************************************************
2922 * X11DRV_DIB_SetImageBits_16
2924 * SetDIBits for a 16-bit deep DIB.
2926 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
2927 DWORD srcwidth
, DWORD dstwidth
, int left
,
2928 DC
*dc
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
2929 XImage
*bmpImage
, DWORD linebytes
)
2937 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
2938 linebytes
= -linebytes
;
2941 switch (bmpImage
->depth
)
2948 srcbits
=srcbits
+left
*2;
2949 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2951 if (bmpImage
->green_mask
==0x03e0) {
2952 if (gSrc
==bmpImage
->green_mask
) {
2953 if (rSrc
==bmpImage
->red_mask
) {
2954 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
2955 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
2956 X11DRV_DIB_Convert_any_asis
2959 dstbits
,-bmpImage
->bytes_per_line
);
2960 } else if (rSrc
==bmpImage
->blue_mask
) {
2961 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
2962 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
2963 X11DRV_DIB_Convert_555_reverse
2966 dstbits
,-bmpImage
->bytes_per_line
);
2969 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
2970 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
2971 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
2972 X11DRV_DIB_Convert_565_to_555_asis
2975 dstbits
,-bmpImage
->bytes_per_line
);
2977 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
2978 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
2979 X11DRV_DIB_Convert_565_to_555_reverse
2982 dstbits
,-bmpImage
->bytes_per_line
);
2985 } else if (bmpImage
->green_mask
==0x07e0) {
2986 if (gSrc
==bmpImage
->green_mask
) {
2987 if (rSrc
==bmpImage
->red_mask
) {
2988 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
2989 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
2990 X11DRV_DIB_Convert_any_asis
2993 dstbits
,-bmpImage
->bytes_per_line
);
2995 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
2996 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
2997 X11DRV_DIB_Convert_565_reverse
3000 dstbits
,-bmpImage
->bytes_per_line
);
3003 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
3004 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
3005 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
3006 X11DRV_DIB_Convert_555_to_565_asis
3009 dstbits
,-bmpImage
->bytes_per_line
);
3011 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
3012 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
3013 X11DRV_DIB_Convert_555_to_565_reverse
3016 dstbits
,-bmpImage
->bytes_per_line
);
3026 if (bmpImage
->bits_per_pixel
==24) {
3029 srcbits
=srcbits
+left
*2;
3030 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
3032 if (bmpImage
->green_mask
!=0x00ff00 ||
3033 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3035 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
3036 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
3038 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
3039 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
3040 X11DRV_DIB_Convert_555_to_888_asis
3043 dstbits
,-bmpImage
->bytes_per_line
);
3045 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
3046 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
3047 X11DRV_DIB_Convert_565_to_888_asis
3050 dstbits
,-bmpImage
->bytes_per_line
);
3054 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
3055 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
3056 X11DRV_DIB_Convert_555_to_888_reverse
3059 dstbits
,-bmpImage
->bytes_per_line
);
3061 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
3062 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
3063 X11DRV_DIB_Convert_565_to_888_reverse
3066 dstbits
,-bmpImage
->bytes_per_line
);
3077 srcbits
=srcbits
+left
*2;
3078 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
3080 if (bmpImage
->green_mask
!=0x00ff00 ||
3081 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3083 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
3084 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
3086 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
3087 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
3088 X11DRV_DIB_Convert_555_to_0888_asis
3091 dstbits
,-bmpImage
->bytes_per_line
);
3093 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
3094 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
3095 X11DRV_DIB_Convert_565_to_0888_asis
3098 dstbits
,-bmpImage
->bytes_per_line
);
3102 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
3103 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
3104 X11DRV_DIB_Convert_555_to_0888_reverse
3107 dstbits
,-bmpImage
->bytes_per_line
);
3109 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
3110 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
3111 X11DRV_DIB_Convert_565_to_0888_reverse
3114 dstbits
,-bmpImage
->bytes_per_line
);
3122 WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3123 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
3124 bmpImage
->green_mask
, bmpImage
->blue_mask
);
3130 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
3131 const WORD
* srcpixel
;
3132 int rShift1
,gShift1
,bShift1
;
3133 int rShift2
,gShift2
,bShift2
;
3136 /* Set color scaling values */
3137 rShift1
=16+X11DRV_DIB_MaskToShift(rSrc
)-3;
3138 gShift1
=16+X11DRV_DIB_MaskToShift(gSrc
)-3;
3139 bShift1
=16+X11DRV_DIB_MaskToShift(bSrc
)-3;
3144 /* Green has 5 bits, like the others */
3148 /* Green has 6 bits, not 5. Compensate. */
3157 /* We could split it into four separate cases to optimize
3158 * but it is probably not worth it.
3160 for (h
=lines
-1; h
>=0; h
--) {
3161 srcpixel
=(const WORD
*)srcbits
;
3162 for (x
=left
; x
<dstwidth
+left
; x
++) {
3164 BYTE red
,green
,blue
;
3165 srcval
=*srcpixel
++ << 16;
3166 red
= ((srcval
>> rShift1
) & 0xf8) |
3167 ((srcval
>> rShift2
) & 0x07);
3168 green
=((srcval
>> gShift1
) & gMask1
) |
3169 ((srcval
>> gShift2
) & gMask2
);
3170 blue
= ((srcval
>> bShift1
) & 0xf8) |
3171 ((srcval
>> bShift2
) & 0x07);
3172 XPutPixel(bmpImage
, x
, h
,
3173 X11DRV_PALETTE_ToPhysical
3174 (dc
, RGB(red
,green
,blue
)));
3176 srcbits
+= linebytes
;
3184 /***********************************************************************
3185 * X11DRV_DIB_GetImageBits_16
3187 * GetDIBits for an 16-bit deep DIB.
3189 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*dstbits
,
3190 DWORD dstwidth
, DWORD srcwidth
,
3191 PALETTEENTRY
*srccolors
,
3192 DWORD rDst
, DWORD gDst
, DWORD bDst
,
3193 XImage
*bmpImage
, DWORD dibpitch
)
3198 DWORD linebytes
= dibpitch
;
3203 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
3204 linebytes
= -linebytes
;
3207 switch (bmpImage
->depth
)
3212 const char* srcbits
;
3214 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3216 if (bmpImage
->green_mask
==0x03e0) {
3217 if (gDst
==bmpImage
->green_mask
) {
3218 if (rDst
==bmpImage
->red_mask
) {
3219 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
3220 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
3221 X11DRV_DIB_Convert_any_asis
3223 srcbits
,-bmpImage
->bytes_per_line
,
3226 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
3227 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
3228 X11DRV_DIB_Convert_555_reverse
3230 srcbits
,-bmpImage
->bytes_per_line
,
3234 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
3235 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
3236 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
3237 X11DRV_DIB_Convert_555_to_565_asis
3239 srcbits
,-bmpImage
->bytes_per_line
,
3242 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
3243 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
3244 X11DRV_DIB_Convert_555_to_565_reverse
3246 srcbits
,-bmpImage
->bytes_per_line
,
3250 } else if (bmpImage
->green_mask
==0x07e0) {
3251 if (gDst
==bmpImage
->green_mask
) {
3252 if (rDst
== bmpImage
->red_mask
) {
3253 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
3254 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
3255 X11DRV_DIB_Convert_any_asis
3257 srcbits
,-bmpImage
->bytes_per_line
,
3260 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
3261 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
3262 X11DRV_DIB_Convert_565_reverse
3264 srcbits
,-bmpImage
->bytes_per_line
,
3268 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
3269 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
3270 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
3271 X11DRV_DIB_Convert_565_to_555_asis
3273 srcbits
,-bmpImage
->bytes_per_line
,
3276 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
3277 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
3278 X11DRV_DIB_Convert_565_to_555_reverse
3280 srcbits
,-bmpImage
->bytes_per_line
,
3291 if (bmpImage
->bits_per_pixel
== 24) {
3292 const char* srcbits
;
3294 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3296 if (bmpImage
->green_mask
!=0x00ff00 ||
3297 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3299 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
3300 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
3302 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
3303 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
3304 X11DRV_DIB_Convert_888_to_555_asis
3306 srcbits
,-bmpImage
->bytes_per_line
,
3309 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
3310 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
3311 X11DRV_DIB_Convert_888_to_565_asis
3313 srcbits
,-bmpImage
->bytes_per_line
,
3318 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
3319 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
3320 X11DRV_DIB_Convert_888_to_555_reverse
3322 srcbits
,-bmpImage
->bytes_per_line
,
3325 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
3326 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
3327 X11DRV_DIB_Convert_888_to_565_reverse
3329 srcbits
,-bmpImage
->bytes_per_line
,
3339 const char* srcbits
;
3341 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3343 if (bmpImage
->green_mask
!=0x00ff00 ||
3344 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3346 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
3347 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
3349 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
3350 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
3351 X11DRV_DIB_Convert_0888_to_555_asis
3353 srcbits
,-bmpImage
->bytes_per_line
,
3356 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
3357 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
3358 X11DRV_DIB_Convert_0888_to_565_asis
3360 srcbits
,-bmpImage
->bytes_per_line
,
3365 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
3366 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
3367 X11DRV_DIB_Convert_0888_to_555_reverse
3369 srcbits
,-bmpImage
->bytes_per_line
,
3372 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
3373 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
3374 X11DRV_DIB_Convert_0888_to_565_reverse
3376 srcbits
,-bmpImage
->bytes_per_line
,
3385 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3386 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
3387 int rShift
,gShift
,bShift
;
3390 /* Shift everything 16 bits left so that all shifts are >0,
3391 * even for BGR DIBs. Then a single >> 16 will bring everything
3394 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
3395 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
3396 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
3398 /* 6 bits for the green */
3404 for (h
= lines
- 1; h
>= 0; h
--) {
3405 dstpixel
=(LPWORD
)dstbits
;
3406 for (x
= 0; x
< dstwidth
; x
++) {
3407 PALETTEENTRY srcval
;
3409 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
3410 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
3411 ((srcval
.peGreen
<< gShift
) & gDst
) |
3412 ((srcval
.peBlue
<< bShift
) & bDst
);
3413 *dstpixel
++=dstval
>> 16;
3415 dstbits
+= linebytes
;
3423 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3424 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
3425 int rShift
,gShift
,bShift
;
3426 const BYTE
* srcbits
;
3427 const BYTE
* srcpixel
;
3430 /* Shift everything 16 bits left so that all shifts are >0,
3431 * even for BGR DIBs. Then a single >> 16 will bring everything
3434 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
3435 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
3436 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
3438 /* 6 bits for the green */
3444 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3445 for (h
=0; h
<lines
; h
++) {
3447 dstpixel
=(LPWORD
)dstbits
;
3448 for (x
= 0; x
< dstwidth
; x
++) {
3449 PALETTEENTRY srcval
;
3451 srcval
=srccolors
[(int)*srcpixel
++];
3452 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
3453 ((srcval
.peGreen
<< gShift
) & gDst
) |
3454 ((srcval
.peBlue
<< bShift
) & bDst
);
3455 *dstpixel
++=dstval
>> 16;
3457 srcbits
-= bmpImage
->bytes_per_line
;
3458 dstbits
+= linebytes
;
3468 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
3469 int rShift
,gShift
,bShift
;
3472 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
3473 bmpImage
->depth
, bmpImage
->red_mask
,
3474 bmpImage
->green_mask
, bmpImage
->blue_mask
,
3477 /* Shift everything 16 bits left so that all shifts are >0,
3478 * even for BGR DIBs. Then a single >> 16 will bring everything
3481 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
3482 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
3483 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
3485 /* 6 bits for the green */
3491 for (h
= lines
- 1; h
>= 0; h
--) {
3492 dstpixel
=(LPWORD
)dstbits
;
3493 for (x
= 0; x
< dstwidth
; x
++) {
3496 srcval
=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage
, x
, h
));
3497 dstval
=((GetRValue(srcval
) << rShift
) & rDst
) |
3498 ((GetGValue(srcval
) << gShift
) & gDst
) |
3499 ((GetBValue(srcval
) << bShift
) & bDst
);
3500 *dstpixel
++=dstval
>> 16;
3502 dstbits
+= linebytes
;
3510 /***********************************************************************
3511 * X11DRV_DIB_SetImageBits_24
3513 * SetDIBits for a 24-bit deep DIB.
3515 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
3516 DWORD srcwidth
, DWORD dstwidth
, int left
,
3518 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
3519 XImage
*bmpImage
, DWORD linebytes
)
3527 srcbits
= srcbits
+ linebytes
* (lines
- 1);
3528 linebytes
= -linebytes
;
3531 switch (bmpImage
->depth
)
3534 if (bmpImage
->bits_per_pixel
==24) {
3537 srcbits
=srcbits
+left
*3;
3538 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
3540 if (bmpImage
->green_mask
!=0x00ff00 ||
3541 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3543 } else if (rSrc
==bmpImage
->red_mask
) {
3544 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
3545 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
3546 X11DRV_DIB_Convert_any_asis
3549 dstbits
,-bmpImage
->bytes_per_line
);
3551 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
3552 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
3553 X11DRV_DIB_Convert_888_reverse
3556 dstbits
,-bmpImage
->bytes_per_line
);
3566 srcbits
=srcbits
+left
*3;
3567 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
3569 if (bmpImage
->green_mask
!=0x00ff00 ||
3570 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3572 } else if (rSrc
==bmpImage
->red_mask
) {
3573 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
3574 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
3575 X11DRV_DIB_Convert_888_to_0888_asis
3578 dstbits
,-bmpImage
->bytes_per_line
);
3580 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
3581 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
3582 X11DRV_DIB_Convert_888_to_0888_reverse
3585 dstbits
,-bmpImage
->bytes_per_line
);
3595 srcbits
=srcbits
+left
*3;
3596 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
3598 if (bmpImage
->green_mask
==0x03e0) {
3599 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
3600 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
3601 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
3602 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
3603 X11DRV_DIB_Convert_888_to_555_asis
3606 dstbits
,-bmpImage
->bytes_per_line
);
3607 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0x7f00) ||
3608 (bSrc
==0xff && bmpImage
->blue_mask
==0x7f00)) {
3609 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
3610 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
3611 X11DRV_DIB_Convert_888_to_555_reverse
3614 dstbits
,-bmpImage
->bytes_per_line
);
3618 } else if (bmpImage
->green_mask
==0x07e0) {
3619 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
3620 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
3621 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
3622 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
3623 X11DRV_DIB_Convert_888_to_565_asis
3626 dstbits
,-bmpImage
->bytes_per_line
);
3627 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0xf800) ||
3628 (bSrc
==0xff && bmpImage
->blue_mask
==0xf800)) {
3629 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
3630 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
3631 X11DRV_DIB_Convert_888_to_565_reverse
3634 dstbits
,-bmpImage
->bytes_per_line
);
3646 WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3647 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
3648 bmpImage
->green_mask
, bmpImage
->blue_mask
);
3654 /* ==== rgb 888 dib -> any bmp bormat ==== */
3655 const BYTE
* srcbyte
;
3657 /* Windows only supports one 24bpp DIB format: RGB888 */
3659 for (h
= lines
- 1; h
>= 0; h
--) {
3660 srcbyte
=(const BYTE
*)srcbits
;
3661 for (x
= left
; x
< dstwidth
+left
; x
++) {
3662 XPutPixel(bmpImage
, x
, h
,
3663 X11DRV_PALETTE_ToPhysical
3664 (dc
, RGB(srcbyte
[2], srcbyte
[1], srcbyte
[0])));
3667 srcbits
+= linebytes
;
3675 /***********************************************************************
3676 * X11DRV_DIB_GetImageBits_24
3678 * GetDIBits for an 24-bit deep DIB.
3680 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*dstbits
,
3681 DWORD dstwidth
, DWORD srcwidth
,
3682 PALETTEENTRY
*srccolors
,
3683 DWORD rDst
, DWORD gDst
, DWORD bDst
,
3684 XImage
*bmpImage
, DWORD linebytes
)
3692 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
3693 linebytes
= -linebytes
;
3696 switch (bmpImage
->depth
)
3699 if (bmpImage
->bits_per_pixel
==24) {
3700 const char* srcbits
;
3702 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3704 if (bmpImage
->green_mask
!=0x00ff00 ||
3705 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3707 } else if (rDst
==bmpImage
->red_mask
) {
3708 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
3709 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
3710 X11DRV_DIB_Convert_any_asis
3712 srcbits
,-bmpImage
->bytes_per_line
,
3715 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
3716 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
3717 X11DRV_DIB_Convert_888_reverse
3719 srcbits
,-bmpImage
->bytes_per_line
,
3728 const char* srcbits
;
3730 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3732 if (bmpImage
->green_mask
!=0x00ff00 ||
3733 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3735 } else if (rDst
==bmpImage
->red_mask
) {
3736 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3737 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3738 X11DRV_DIB_Convert_0888_to_888_asis
3740 srcbits
,-bmpImage
->bytes_per_line
,
3743 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3744 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3745 X11DRV_DIB_Convert_0888_to_888_reverse
3747 srcbits
,-bmpImage
->bytes_per_line
,
3756 const char* srcbits
;
3758 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3760 if (bmpImage
->green_mask
==0x03e0) {
3761 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
3762 (bDst
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
3763 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
3764 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
3765 X11DRV_DIB_Convert_555_to_888_asis
3767 srcbits
,-bmpImage
->bytes_per_line
,
3769 } else if ((rDst
==0xff && bmpImage
->red_mask
==0x7f00) ||
3770 (bDst
==0xff && bmpImage
->blue_mask
==0x7f00)) {
3771 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
3772 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
3773 X11DRV_DIB_Convert_555_to_888_reverse
3775 srcbits
,-bmpImage
->bytes_per_line
,
3780 } else if (bmpImage
->green_mask
==0x07e0) {
3781 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
3782 (bDst
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
3783 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
3784 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
3785 X11DRV_DIB_Convert_565_to_888_asis
3787 srcbits
,-bmpImage
->bytes_per_line
,
3789 } else if ((rDst
==0xff && bmpImage
->red_mask
==0xf800) ||
3790 (bDst
==0xff && bmpImage
->blue_mask
==0xf800)) {
3791 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
3792 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
3793 X11DRV_DIB_Convert_565_to_888_reverse
3795 srcbits
,-bmpImage
->bytes_per_line
,
3808 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3809 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
3812 /* Windows only supports one 24bpp DIB format: rgb 888 */
3813 for (h
= lines
- 1; h
>= 0; h
--) {
3815 for (x
= 0; x
< dstwidth
; x
++) {
3816 PALETTEENTRY srcval
;
3817 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
3818 dstbyte
[0]=srcval
.peBlue
;
3819 dstbyte
[1]=srcval
.peGreen
;
3820 dstbyte
[2]=srcval
.peRed
;
3823 dstbits
+= linebytes
;
3831 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
== 0 && srccolors
) {
3832 /* ==== pal 8 bmp -> rgb 888 dib ==== */
3833 const void* srcbits
;
3834 const BYTE
* srcpixel
;
3837 /* Windows only supports one 24bpp DIB format: rgb 888 */
3838 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3839 for (h
= lines
- 1; h
>= 0; h
--) {
3842 for (x
= 0; x
< dstwidth
; x
++ ) {
3843 PALETTEENTRY srcval
;
3844 srcval
=srccolors
[(int)*srcpixel
++];
3845 dstbyte
[0]=srcval
.peBlue
;
3846 dstbyte
[1]=srcval
.peGreen
;
3847 dstbyte
[2]=srcval
.peRed
;
3850 srcbits
-= bmpImage
->bytes_per_line
;
3851 dstbits
+= linebytes
;
3861 /* ==== any bmp format -> 888 dib ==== */
3864 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
3865 bmpImage
->depth
, bmpImage
->red_mask
,
3866 bmpImage
->green_mask
, bmpImage
->blue_mask
,
3869 /* Windows only supports one 24bpp DIB format: rgb 888 */
3870 for (h
= lines
- 1; h
>= 0; h
--) {
3872 for (x
= 0; x
< dstwidth
; x
++) {
3873 COLORREF srcval
=X11DRV_PALETTE_ToLogical
3874 (XGetPixel( bmpImage
, x
, h
));
3875 dstbyte
[0]=GetBValue(srcval
);
3876 dstbyte
[1]=GetGValue(srcval
);
3877 dstbyte
[2]=GetRValue(srcval
);
3880 dstbits
+= linebytes
;
3888 /***********************************************************************
3889 * X11DRV_DIB_SetImageBits_32
3891 * SetDIBits for a 32-bit deep DIB.
3893 static void X11DRV_DIB_SetImageBits_32(int lines
, const BYTE
*srcbits
,
3894 DWORD srcwidth
, DWORD dstwidth
, int left
,
3896 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
3906 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
3907 linebytes
= -linebytes
;
3910 ptr
= (DWORD
*) srcbits
+ left
;
3912 switch (bmpImage
->depth
)
3915 if (bmpImage
->bits_per_pixel
==24) {
3918 srcbits
=srcbits
+left
*4;
3919 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
3921 if (rSrc
==bmpImage
->red_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->blue_mask
) {
3922 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
3923 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
3924 X11DRV_DIB_Convert_0888_to_888_asis
3927 dstbits
,-bmpImage
->bytes_per_line
);
3928 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3929 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3931 /* the tests below assume sane bmpImage masks */
3932 } else if (rSrc
==bmpImage
->blue_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->red_mask
) {
3933 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
3934 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
3935 X11DRV_DIB_Convert_0888_to_888_reverse
3938 dstbits
,-bmpImage
->bytes_per_line
);
3939 } else if (bmpImage
->blue_mask
==0xff) {
3940 /* ==== any 0888 dib -> rgb 888 bmp ==== */
3941 X11DRV_DIB_Convert_any0888_to_rgb888
3945 dstbits
,-bmpImage
->bytes_per_line
);
3947 /* ==== any 0888 dib -> bgr 888 bmp ==== */
3948 X11DRV_DIB_Convert_any0888_to_bgr888
3952 dstbits
,-bmpImage
->bytes_per_line
);
3962 srcbits
=srcbits
+left
*4;
3963 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
3965 if (gSrc
==bmpImage
->green_mask
) {
3966 if (rSrc
==bmpImage
->red_mask
&& bSrc
==bmpImage
->blue_mask
) {
3967 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
3968 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
3969 X11DRV_DIB_Convert_any_asis
3972 dstbits
,-bmpImage
->bytes_per_line
);
3973 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3974 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3976 /* the tests below assume sane bmpImage masks */
3977 } else if (rSrc
==bmpImage
->blue_mask
&& bSrc
==bmpImage
->red_mask
) {
3978 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
3979 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
3980 X11DRV_DIB_Convert_0888_reverse
3983 dstbits
,-bmpImage
->bytes_per_line
);
3985 /* ==== any 0888 dib -> any 0888 bmp ==== */
3986 X11DRV_DIB_Convert_0888_any
3990 dstbits
,-bmpImage
->bytes_per_line
,
3991 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
3993 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3994 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3996 /* the tests below assume sane bmpImage masks */
3998 /* ==== any 0888 dib -> any 0888 bmp ==== */
3999 X11DRV_DIB_Convert_0888_any
4003 dstbits
,-bmpImage
->bytes_per_line
,
4004 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4014 srcbits
=srcbits
+left
*4;
4015 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
4017 if (rSrc
==0xff0000 && gSrc
==0x00ff00 && bSrc
==0x0000ff) {
4018 if (bmpImage
->green_mask
==0x03e0) {
4019 if (bmpImage
->red_mask
==0x7f00) {
4020 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
4021 X11DRV_DIB_Convert_0888_to_555_asis
4024 dstbits
,-bmpImage
->bytes_per_line
);
4025 } else if (bmpImage
->blue_mask
==0x7f00) {
4026 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
4027 X11DRV_DIB_Convert_0888_to_555_reverse
4030 dstbits
,-bmpImage
->bytes_per_line
);
4034 } else if (bmpImage
->green_mask
==0x07e0) {
4035 if (bmpImage
->red_mask
==0xf800) {
4036 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
4037 X11DRV_DIB_Convert_0888_to_565_asis
4040 dstbits
,-bmpImage
->bytes_per_line
);
4041 } else if (bmpImage
->blue_mask
==0xf800) {
4042 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
4043 X11DRV_DIB_Convert_0888_to_565_reverse
4046 dstbits
,-bmpImage
->bytes_per_line
);
4053 } else if (rSrc
==0x0000ff && gSrc
==0x00ff00 && bSrc
==0xff0000) {
4054 if (bmpImage
->green_mask
==0x03e0) {
4055 if (bmpImage
->blue_mask
==0x7f00) {
4056 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
4057 X11DRV_DIB_Convert_0888_to_555_asis
4060 dstbits
,-bmpImage
->bytes_per_line
);
4061 } else if (bmpImage
->red_mask
==0x7f00) {
4062 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
4063 X11DRV_DIB_Convert_0888_to_555_reverse
4066 dstbits
,-bmpImage
->bytes_per_line
);
4070 } else if (bmpImage
->green_mask
==0x07e0) {
4071 if (bmpImage
->blue_mask
==0xf800) {
4072 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
4073 X11DRV_DIB_Convert_0888_to_565_asis
4076 dstbits
,-bmpImage
->bytes_per_line
);
4077 } else if (bmpImage
->red_mask
==0xf800) {
4078 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
4079 X11DRV_DIB_Convert_0888_to_565_reverse
4082 dstbits
,-bmpImage
->bytes_per_line
);
4090 if (bmpImage
->green_mask
==0x03e0 &&
4091 (bmpImage
->red_mask
==0x7f00 ||
4092 bmpImage
->blue_mask
==0x7f00)) {
4093 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
4094 X11DRV_DIB_Convert_any0888_to_5x5
4098 dstbits
,-bmpImage
->bytes_per_line
,
4099 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4100 } else if (bmpImage
->green_mask
==0x07e0 &&
4101 (bmpImage
->red_mask
==0xf800 ||
4102 bmpImage
->blue_mask
==0xf800)) {
4103 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
4104 X11DRV_DIB_Convert_any0888_to_5x5
4108 dstbits
,-bmpImage
->bytes_per_line
,
4109 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4119 WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
4120 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
4121 bmpImage
->green_mask
, bmpImage
->blue_mask
);
4127 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
4128 const DWORD
* srcpixel
;
4129 int rShift
,gShift
,bShift
;
4131 rShift
=X11DRV_DIB_MaskToShift(rSrc
);
4132 gShift
=X11DRV_DIB_MaskToShift(gSrc
);
4133 bShift
=X11DRV_DIB_MaskToShift(bSrc
);
4135 for (h
= lines
- 1; h
>= 0; h
--) {
4136 srcpixel
=(const DWORD
*)srcbits
;
4137 for (x
= left
; x
< dstwidth
+left
; x
++) {
4139 BYTE red
,green
,blue
;
4140 srcvalue
=*srcpixel
++;
4141 red
= (srcvalue
>> rShift
) & 0xff;
4142 green
=(srcvalue
>> gShift
) & 0xff;
4143 blue
= (srcvalue
>> bShift
) & 0xff;
4144 XPutPixel(bmpImage
, x
, h
, X11DRV_PALETTE_ToPhysical
4145 (dc
, RGB(red
,green
,blue
)));
4147 srcbits
+= linebytes
;
4155 /***********************************************************************
4156 * X11DRV_DIB_GetImageBits_32
4158 * GetDIBits for an 32-bit deep DIB.
4160 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*dstbits
,
4161 DWORD dstwidth
, DWORD srcwidth
,
4162 PALETTEENTRY
*srccolors
,
4163 DWORD rDst
, DWORD gDst
, DWORD bDst
,
4164 XImage
*bmpImage
, DWORD linebytes
)
4173 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
4174 linebytes
= -linebytes
;
4179 switch (bmpImage
->depth
)
4182 if (bmpImage
->bits_per_pixel
==24) {
4183 const void* srcbits
;
4185 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
4187 if (rDst
==bmpImage
->red_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->blue_mask
) {
4188 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
4189 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
4190 X11DRV_DIB_Convert_888_to_0888_asis
4192 srcbits
,-bmpImage
->bytes_per_line
,
4194 } else if (bmpImage
->green_mask
!=0x00ff00 ||
4195 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
4197 /* the tests below assume sane bmpImage masks */
4198 } else if (rDst
==bmpImage
->blue_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->red_mask
) {
4199 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
4200 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
4201 X11DRV_DIB_Convert_888_to_0888_reverse
4203 srcbits
,-bmpImage
->bytes_per_line
,
4205 } else if (bmpImage
->blue_mask
==0xff) {
4206 /* ==== rgb 888 bmp -> any 0888 dib ==== */
4207 X11DRV_DIB_Convert_rgb888_to_any0888
4209 srcbits
,-bmpImage
->bytes_per_line
,
4213 /* ==== bgr 888 bmp -> any 0888 dib ==== */
4214 X11DRV_DIB_Convert_bgr888_to_any0888
4216 srcbits
,-bmpImage
->bytes_per_line
,
4226 const char* srcbits
;
4228 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
4230 if (gDst
==bmpImage
->green_mask
) {
4231 if (rDst
==bmpImage
->red_mask
&& bDst
==bmpImage
->blue_mask
) {
4232 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
4233 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
4234 X11DRV_DIB_Convert_any_asis
4236 srcbits
,-bmpImage
->bytes_per_line
,
4238 } else if (bmpImage
->green_mask
!=0x00ff00 ||
4239 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
4241 /* the tests below assume sane bmpImage masks */
4242 } else if (rDst
==bmpImage
->blue_mask
&& bDst
==bmpImage
->red_mask
) {
4243 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
4244 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
4245 X11DRV_DIB_Convert_0888_reverse
4247 srcbits
,-bmpImage
->bytes_per_line
,
4250 /* ==== any 0888 bmp -> any 0888 dib ==== */
4251 X11DRV_DIB_Convert_0888_any
4253 srcbits
,-bmpImage
->bytes_per_line
,
4254 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
4258 } else if (bmpImage
->green_mask
!=0x00ff00 ||
4259 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
4261 /* the tests below assume sane bmpImage masks */
4263 /* ==== any 0888 bmp -> any 0888 dib ==== */
4264 X11DRV_DIB_Convert_0888_any
4266 srcbits
,-bmpImage
->bytes_per_line
,
4267 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
4277 const char* srcbits
;
4279 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
4281 if (rDst
==0xff0000 && gDst
==0x00ff00 && bDst
==0x0000ff) {
4282 if (bmpImage
->green_mask
==0x03e0) {
4283 if (bmpImage
->red_mask
==0x7f00) {
4284 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
4285 X11DRV_DIB_Convert_555_to_0888_asis
4287 srcbits
,-bmpImage
->bytes_per_line
,
4289 } else if (bmpImage
->blue_mask
==0x7f00) {
4290 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
4291 X11DRV_DIB_Convert_555_to_0888_reverse
4293 srcbits
,-bmpImage
->bytes_per_line
,
4298 } else if (bmpImage
->green_mask
==0x07e0) {
4299 if (bmpImage
->red_mask
==0xf800) {
4300 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
4301 X11DRV_DIB_Convert_565_to_0888_asis
4303 srcbits
,-bmpImage
->bytes_per_line
,
4305 } else if (bmpImage
->blue_mask
==0xf800) {
4306 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
4307 X11DRV_DIB_Convert_565_to_0888_reverse
4309 srcbits
,-bmpImage
->bytes_per_line
,
4317 } else if (rDst
==0x0000ff && gDst
==0x00ff00 && bDst
==0xff0000) {
4318 if (bmpImage
->green_mask
==0x03e0) {
4319 if (bmpImage
->blue_mask
==0x7f00) {
4320 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
4321 X11DRV_DIB_Convert_555_to_0888_asis
4323 srcbits
,-bmpImage
->bytes_per_line
,
4325 } else if (bmpImage
->red_mask
==0x7f00) {
4326 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
4327 X11DRV_DIB_Convert_555_to_0888_reverse
4329 srcbits
,-bmpImage
->bytes_per_line
,
4334 } else if (bmpImage
->green_mask
==0x07e0) {
4335 if (bmpImage
->blue_mask
==0xf800) {
4336 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
4337 X11DRV_DIB_Convert_565_to_0888_asis
4339 srcbits
,-bmpImage
->bytes_per_line
,
4341 } else if (bmpImage
->red_mask
==0xf800) {
4342 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
4343 X11DRV_DIB_Convert_565_to_0888_reverse
4345 srcbits
,-bmpImage
->bytes_per_line
,
4354 if (bmpImage
->green_mask
==0x03e0 &&
4355 (bmpImage
->red_mask
==0x7f00 ||
4356 bmpImage
->blue_mask
==0x7f00)) {
4357 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
4358 X11DRV_DIB_Convert_5x5_to_any0888
4360 srcbits
,-bmpImage
->bytes_per_line
,
4361 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
4364 } else if (bmpImage
->green_mask
==0x07e0 &&
4365 (bmpImage
->red_mask
==0xf800 ||
4366 bmpImage
->blue_mask
==0xf800)) {
4367 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
4368 X11DRV_DIB_Convert_5x5_to_any0888
4370 srcbits
,-bmpImage
->bytes_per_line
,
4371 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
4383 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
4384 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
4385 int rShift
,gShift
,bShift
;
4388 rShift
=X11DRV_DIB_MaskToShift(rDst
);
4389 gShift
=X11DRV_DIB_MaskToShift(gDst
);
4390 bShift
=X11DRV_DIB_MaskToShift(bDst
);
4391 for (h
= lines
- 1; h
>= 0; h
--) {
4392 dstpixel
=(DWORD
*)dstbits
;
4393 for (x
= 0; x
< dstwidth
; x
++) {
4394 PALETTEENTRY srcval
;
4395 srcval
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
4396 *dstpixel
++=(srcval
.peRed
<< rShift
) |
4397 (srcval
.peGreen
<< gShift
) |
4398 (srcval
.peBlue
<< bShift
);
4400 dstbits
+= linebytes
;
4408 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
4409 /* ==== pal 8 bmp -> any 0888 dib ==== */
4410 int rShift
,gShift
,bShift
;
4411 const void* srcbits
;
4412 const BYTE
* srcpixel
;
4415 rShift
=X11DRV_DIB_MaskToShift(rDst
);
4416 gShift
=X11DRV_DIB_MaskToShift(gDst
);
4417 bShift
=X11DRV_DIB_MaskToShift(bDst
);
4418 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
4419 for (h
= lines
- 1; h
>= 0; h
--) {
4421 dstpixel
=(DWORD
*)dstbits
;
4422 for (x
= 0; x
< dstwidth
; x
++) {
4423 PALETTEENTRY srcval
;
4424 srcval
=srccolors
[(int)*srcpixel
++];
4425 *dstpixel
++=(srcval
.peRed
<< rShift
) |
4426 (srcval
.peGreen
<< gShift
) |
4427 (srcval
.peBlue
<< bShift
);
4429 srcbits
-= bmpImage
->bytes_per_line
;
4430 dstbits
+= linebytes
;
4440 /* ==== any bmp format -> any 0888 dib ==== */
4441 int rShift
,gShift
,bShift
;
4444 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
4445 bmpImage
->depth
, bmpImage
->red_mask
,
4446 bmpImage
->green_mask
, bmpImage
->blue_mask
,
4449 rShift
=X11DRV_DIB_MaskToShift(rDst
);
4450 gShift
=X11DRV_DIB_MaskToShift(gDst
);
4451 bShift
=X11DRV_DIB_MaskToShift(bDst
);
4452 for (h
= lines
- 1; h
>= 0; h
--) {
4453 dstpixel
=(DWORD
*)dstbits
;
4454 for (x
= 0; x
< dstwidth
; x
++) {
4456 srcval
=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage
, x
, h
));
4457 *dstpixel
++=(GetRValue(srcval
) << rShift
) |
4458 (GetGValue(srcval
) << gShift
) |
4459 (GetBValue(srcval
) << bShift
);
4461 dstbits
+= linebytes
;
4468 /***********************************************************************
4469 * X11DRV_DIB_SetImageBits
4471 * Transfer the bits to an X image.
4472 * Helper function for SetDIBits() and SetDIBitsToDevice().
4474 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
4476 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
4481 bmpImage
= descr
->image
;
4483 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
4484 descr
->infoWidth
, lines
, 32, 0 );
4485 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
4486 if(bmpImage
->data
== NULL
) {
4487 ERR("Out of memory!\n");
4488 XDestroyImage( bmpImage
);
4489 wine_tsx11_unlock();
4494 TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
4495 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
4496 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
4497 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
4498 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4500 /* Transfer the pixels */
4501 switch(descr
->infoBpp
)
4504 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
4505 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
4506 bmpImage
, descr
->dibpitch
);
4509 if (descr
->compression
) {
4510 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
4511 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
4512 bmpImage
, descr
->xSrc
, descr
->ySrc
);
4514 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
4515 descr
->infoWidth
, descr
->width
,
4516 descr
->xSrc
, (int *)(descr
->colorMap
),
4519 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
4520 descr
->infoWidth
, descr
->width
,
4521 descr
->xSrc
, (int*)(descr
->colorMap
),
4522 bmpImage
, descr
->dibpitch
);
4525 if (descr
->compression
) {
4526 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
4527 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
4528 bmpImage
, descr
->xSrc
, descr
->ySrc
);
4529 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
4530 descr
->infoWidth
, descr
->width
,
4531 descr
->xSrc
, (int *)(descr
->colorMap
),
4534 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
4535 descr
->infoWidth
, descr
->width
,
4536 descr
->xSrc
, (int *)(descr
->colorMap
),
4537 bmpImage
, descr
->dibpitch
);
4541 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
4542 descr
->infoWidth
, descr
->width
,
4543 descr
->xSrc
, descr
->dc
,
4544 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4545 bmpImage
, descr
->dibpitch
);
4548 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
4549 descr
->infoWidth
, descr
->width
,
4550 descr
->xSrc
, descr
->dc
,
4551 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4552 bmpImage
, descr
->dibpitch
);
4555 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
4556 descr
->infoWidth
, descr
->width
,
4557 descr
->xSrc
, descr
->dc
,
4558 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4559 bmpImage
, descr
->dibpitch
);
4562 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
4566 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
4567 descr
->drawable
, descr
->gc
, bmpImage
,
4568 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
4569 descr
->width
, descr
->height
);
4570 #ifdef HAVE_LIBXXSHM
4573 XShmPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
4574 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
4575 descr
->width
, descr
->height
, FALSE
);
4576 XSync( gdi_display
, 0 );
4580 XPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
4581 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
4582 descr
->width
, descr
->height
);
4584 if (!descr
->image
) XDestroyImage( bmpImage
);
4585 wine_tsx11_unlock();
4589 /***********************************************************************
4590 * X11DRV_DIB_GetImageBits
4592 * Transfer the bits from an X image.
4594 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
4596 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
4601 bmpImage
= descr
->image
;
4603 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
4604 descr
->infoWidth
, lines
, 32, 0 );
4605 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
4606 if(bmpImage
->data
== NULL
) {
4607 ERR("Out of memory!\n");
4608 XDestroyImage( bmpImage
);
4609 wine_tsx11_unlock();
4616 int saveRed
, saveGreen
, saveBlue
;
4618 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
4619 gdi_display
, descr
->drawable
, bmpImage
,
4620 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
4622 /* We must save and restore the bmpImage's masks in order
4623 * to preserve them across the call to XShmGetImage, which
4624 * decides to eleminate them since it doesn't happen to know
4625 * what the format of the image is supposed to be, even though
4627 saveRed
= bmpImage
->red_mask
;
4628 saveBlue
= bmpImage
->blue_mask
;
4629 saveGreen
= bmpImage
->green_mask
;
4631 XShmGetImage( gdi_display
, descr
->drawable
, bmpImage
,
4632 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
4634 bmpImage
->red_mask
= saveRed
;
4635 bmpImage
->blue_mask
= saveBlue
;
4636 bmpImage
->green_mask
= saveGreen
;
4640 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
4641 gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
, descr
->width
,
4642 lines
, AllPlanes
, ZPixmap
, bmpImage
, descr
->xDest
, descr
->yDest
);
4643 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
,
4644 descr
->width
, lines
, AllPlanes
, ZPixmap
,
4645 bmpImage
, descr
->xDest
, descr
->yDest
);
4648 TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
4649 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
4650 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
4651 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
4652 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4653 /* Transfer the pixels */
4654 switch(descr
->infoBpp
)
4657 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
4658 descr
->infoWidth
, descr
->width
,
4659 descr
->colorMap
, descr
->palentry
,
4660 bmpImage
, descr
->dibpitch
);
4664 if (descr
->compression
)
4665 FIXME("Compression not yet supported!\n");
4667 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
4668 descr
->infoWidth
, descr
->width
,
4669 descr
->colorMap
, descr
->palentry
,
4670 bmpImage
, descr
->dibpitch
);
4674 if (descr
->compression
)
4675 FIXME("Compression not yet supported!\n");
4677 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
4678 descr
->infoWidth
, descr
->width
,
4679 descr
->colorMap
, descr
->palentry
,
4680 bmpImage
, descr
->dibpitch
);
4684 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
4685 descr
->infoWidth
,descr
->width
,
4687 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4688 bmpImage
, descr
->dibpitch
);
4692 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
4693 descr
->infoWidth
,descr
->width
,
4695 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4696 bmpImage
, descr
->dibpitch
);
4700 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
4701 descr
->infoWidth
, descr
->width
,
4703 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4704 bmpImage
, descr
->dibpitch
);
4708 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
4712 if (!descr
->image
) XDestroyImage( bmpImage
);
4713 wine_tsx11_unlock();
4717 /*************************************************************************
4718 * X11DRV_SetDIBitsToDevice
4721 INT
X11DRV_SetDIBitsToDevice( DC
*dc
, INT xDest
, INT yDest
, DWORD cx
,
4722 DWORD cy
, INT xSrc
, INT ySrc
,
4723 UINT startscan
, UINT lines
, LPCVOID bits
,
4724 const BITMAPINFO
*info
, UINT coloruse
)
4726 X11DRV_DIB_IMAGEBITS_DESCR descr
;
4727 DWORD width
, oldcy
= cy
;
4729 int height
, tmpheight
;
4730 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dc
->physDev
;
4733 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
4734 &descr
.infoBpp
, &descr
.compression
) == -1)
4737 if (height
< 0) height
= -height
;
4738 if (!lines
|| (startscan
>= height
)) return 0;
4739 if (startscan
+ lines
> height
) lines
= height
- startscan
;
4740 if (ySrc
< startscan
) ySrc
= startscan
;
4741 else if (ySrc
>= startscan
+ lines
) return 0;
4742 if (xSrc
>= width
) return 0;
4743 if (ySrc
+ cy
>= startscan
+ lines
) cy
= startscan
+ lines
- ySrc
;
4744 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
4745 if (!cx
|| !cy
) return 0;
4747 X11DRV_SetupGCForText( dc
); /* To have the correct colors */
4748 TSXSetFunction(gdi_display
, physDev
->gc
, X11DRV_XROPfunction
[dc
->ROPmode
-1]);
4750 switch (descr
.infoBpp
)
4755 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
4756 coloruse
== DIB_PAL_COLORS
? dc
: NULL
, coloruse
,
4757 dc
->bitsPerPixel
, info
, &descr
.nColorMap
);
4758 if (!descr
.colorMap
) return 0;
4759 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
4763 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
4764 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
4765 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
4771 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
4772 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
4773 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
4781 descr
.palentry
= NULL
;
4782 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
4783 descr
.infoWidth
= width
;
4784 descr
.depth
= dc
->bitsPerPixel
;
4785 descr
.drawable
= physDev
->drawable
;
4786 descr
.gc
= physDev
->gc
;
4788 descr
.ySrc
= tmpheight
>= 0 ? lines
-(ySrc
-startscan
)-cy
+(oldcy
-cy
)
4790 descr
.xDest
= dc
->DCOrgX
+ XLPTODP( dc
, xDest
);
4791 descr
.yDest
= dc
->DCOrgY
+ YLPTODP( dc
, yDest
) +
4792 (tmpheight
>= 0 ? oldcy
-cy
: 0);
4795 descr
.useShm
= FALSE
;
4796 descr
.dibpitch
= ((width
* descr
.infoBpp
+ 31) &~31) / 8;
4798 result
= X11DRV_DIB_SetImageBits( &descr
);
4800 if (descr
.infoBpp
<= 8)
4801 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
4805 /***********************************************************************
4806 * X11DRV_DIB_SetDIBits
4808 INT
X11DRV_DIB_SetDIBits(
4809 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
4810 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
,
4811 UINT coloruse
, HBITMAP hbitmap
)
4813 X11DRV_DIB_IMAGEBITS_DESCR descr
;
4814 int height
, tmpheight
;
4819 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
4820 &descr
.infoBpp
, &descr
.compression
) == -1)
4824 if (height
< 0) height
= -height
;
4825 if (!lines
|| (startscan
>= height
))
4828 if (startscan
+ lines
> height
) lines
= height
- startscan
;
4830 switch (descr
.infoBpp
)
4835 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
4836 coloruse
== DIB_PAL_COLORS
? descr
.dc
: NULL
, coloruse
,
4837 bmp
->bitmap
.bmBitsPixel
,
4838 info
, &descr
.nColorMap
);
4839 if (!descr
.colorMap
) return 0;
4840 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
4844 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
4845 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
4846 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
4852 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
4853 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
4854 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
4862 if(!bmp
->physBitmap
)
4863 X11DRV_CreateBitmap(hbitmap
);
4867 descr
.palentry
= NULL
;
4868 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
4869 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
4870 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
4871 descr
.gc
= BITMAP_GC(bmp
);
4875 descr
.yDest
= height
- startscan
- lines
;
4876 descr
.width
= bmp
->bitmap
.bmWidth
;
4877 descr
.height
= lines
;
4878 descr
.useShm
= FALSE
;
4879 descr
.dibpitch
= ((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8;
4880 result
= X11DRV_DIB_SetImageBits( &descr
);
4882 if (descr
.colorMap
) HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
4887 /***********************************************************************
4888 * X11DRV_DIB_GetDIBits
4890 INT
X11DRV_DIB_GetDIBits(
4891 BITMAPOBJ
*bmp
, DC
*dc
, UINT startscan
,
4892 UINT lines
, LPVOID bits
, BITMAPINFO
*info
,
4893 UINT coloruse
, HBITMAP hbitmap
)
4895 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4896 X11DRV_DIB_IMAGEBITS_DESCR descr
;
4897 PALETTEOBJ
* palette
;
4900 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
4901 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
4902 (int)info
->bmiHeader
.biWidth
, (int)info
->bmiHeader
.biHeight
,
4905 if (!(palette
= (PALETTEOBJ
*)GDI_GetObjPtr( dc
->hPalette
, PALETTE_MAGIC
)))
4908 if( lines
> bmp
->bitmap
.bmHeight
) lines
= bmp
->bitmap
.bmHeight
;
4910 height
= info
->bmiHeader
.biHeight
;
4911 if (height
< 0) height
= -height
;
4912 if( lines
> height
) lines
= height
;
4913 /* Top-down images have a negative biHeight, the scanlines of theses images
4914 * were inverted in X11DRV_DIB_GetImageBits_xx
4915 * To prevent this we simply change the sign of lines
4916 * (the number of scan lines to copy).
4917 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
4919 if( info
->bmiHeader
.biHeight
< 0 && lines
> 0) lines
= -lines
;
4921 if( startscan
>= bmp
->bitmap
.bmHeight
)
4927 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &descr
.lines
,
4928 &descr
.infoBpp
, &descr
.compression
) == -1)
4934 switch (descr
.infoBpp
)
4939 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
4943 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
4944 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
4945 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
4949 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
4950 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
4951 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
4956 if(!bmp
->physBitmap
)
4957 X11DRV_CreateBitmap(hbitmap
);
4961 descr
.palentry
= palette
->logpalette
.palPalEntry
;
4964 descr
.lines
= lines
;
4965 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
4966 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
4967 descr
.gc
= BITMAP_GC(bmp
);
4968 descr
.width
= bmp
->bitmap
.bmWidth
;
4969 descr
.height
= bmp
->bitmap
.bmHeight
;
4970 descr
.colorMap
= info
->bmiColors
;
4975 if (descr
.lines
> 0)
4977 descr
.ySrc
= (descr
.height
-1) - (startscan
+ (lines
-1));
4981 descr
.ySrc
= startscan
;
4983 #ifdef HAVE_LIBXXSHM
4984 descr
.useShm
= dib
? (dib
->shminfo
.shmid
!= -1) : FALSE
;
4986 descr
.useShm
= FALSE
;
4988 descr
.dibpitch
= dib
? (dib
->dibSection
.dsBm
.bmWidthBytes
)
4989 : (((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8);
4991 X11DRV_DIB_GetImageBits( &descr
);
4993 if(info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
4994 info
->bmiHeader
.biSizeImage
= DIB_GetDIBImageBytes(
4995 info
->bmiHeader
.biWidth
,
4996 info
->bmiHeader
.biHeight
,
4997 info
->bmiHeader
.biBitCount
);
4999 info
->bmiHeader
.biCompression
= 0;
5000 if (descr
.compression
== BI_BITFIELDS
)
5002 *(DWORD
*)info
->bmiColors
= descr
.rMask
;
5003 *((DWORD
*)info
->bmiColors
+1) = descr
.gMask
;
5004 *((DWORD
*)info
->bmiColors
+2) = descr
.bMask
;
5008 GDI_ReleaseObj( dc
->hPalette
);
5013 /***********************************************************************
5014 * DIB_DoProtectDIBSection
5016 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
5018 DIBSECTION
*dib
= bmp
->dib
;
5019 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
5020 : -dib
->dsBm
.bmHeight
;
5021 /* use the biSizeImage data as the memory size only if we're dealing with a
5022 compressed image where the value is set. Otherwise, calculate based on
5024 INT totalSize
= dib
->dsBmih
.biSizeImage
&& dib
->dsBmih
.biCompression
!= BI_RGB
5025 ? dib
->dsBmih
.biSizeImage
5026 : dib
->dsBm
.bmWidthBytes
* effHeight
;
5029 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
5030 TRACE("Changed protection from %ld to %ld\n", old_prot
, new_prot
);
5033 /***********************************************************************
5034 * X11DRV_DIB_DoUpdateDIBSection
5036 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
,
5037 void *colorMap
, int nColorMap
,
5039 DWORD xSrc
, DWORD ySrc
,
5040 DWORD xDest
, DWORD yDest
,
5041 DWORD width
, DWORD height
)
5043 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5044 X11DRV_DIB_IMAGEBITS_DESCR descr
;
5046 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, &descr
.lines
,
5047 &descr
.infoBpp
, &descr
.compression
) == -1)
5051 descr
.palentry
= NULL
;
5052 descr
.image
= dib
->image
;
5053 descr
.colorMap
= colorMap
;
5054 descr
.nColorMap
= nColorMap
;
5055 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
5056 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
5058 switch (descr
.infoBpp
)
5063 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
5067 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0x7c00;
5068 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x03e0;
5069 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x001f;
5074 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0xff0000;
5075 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x00ff00;
5076 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x0000ff;
5081 descr
.drawable
= dest
;
5082 descr
.gc
= BITMAP_GC(bmp
);
5085 descr
.xDest
= xDest
;
5086 descr
.yDest
= yDest
;
5087 descr
.width
= width
;
5088 descr
.height
= height
;
5089 #ifdef HAVE_LIBXXSHM
5090 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
5092 descr
.useShm
= FALSE
;
5094 descr
.dibpitch
= dib
->dibSection
.dsBm
.bmWidthBytes
;
5098 TRACE("Copying from Pixmap to DIB bits\n");
5099 X11DRV_DIB_GetImageBits( &descr
);
5103 TRACE("Copying from DIB bits to Pixmap\n");
5104 X11DRV_DIB_SetImageBits( &descr
);
5108 /***********************************************************************
5109 * X11DRV_DIB_CopyDIBSection
5111 void X11DRV_DIB_CopyDIBSection(DC
*dcSrc
, DC
*dcDst
,
5112 DWORD xSrc
, DWORD ySrc
,
5113 DWORD xDest
, DWORD yDest
,
5114 DWORD width
, DWORD height
)
5117 X11DRV_PDEVICE
*physDev
= (X11DRV_PDEVICE
*)dcDst
->physDev
;
5118 int nColorMap
= 0, *colorMap
= NULL
, aColorMap
= FALSE
;
5120 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc
, dcDst
,
5121 xSrc
, ySrc
, xDest
, yDest
, width
, height
);
5122 /* this function is meant as an optimization for BitBlt,
5123 * not to be called otherwise */
5124 if (!(dcSrc
->flags
& DC_MEMORY
)) {
5125 ERR("called for non-memory source DC!?\n");
5129 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( dcSrc
->hBitmap
, BITMAP_MAGIC
);
5130 if (!(bmp
&& bmp
->dib
)) {
5131 ERR("called for non-DIBSection!?\n");
5132 GDI_ReleaseObj( dcSrc
->hBitmap
);
5135 /* while BitBlt should already have made sure we only get
5136 * positive values, we should check for oversize values */
5137 if ((xSrc
< bmp
->bitmap
.bmWidth
) &&
5138 (ySrc
< bmp
->bitmap
.bmHeight
)) {
5139 if (xSrc
+ width
> bmp
->bitmap
.bmWidth
)
5140 width
= bmp
->bitmap
.bmWidth
- xSrc
;
5141 if (ySrc
+ height
> bmp
->bitmap
.bmHeight
)
5142 height
= bmp
->bitmap
.bmHeight
- ySrc
;
5143 /* if the source bitmap is 8bpp or less, we're supposed to use the
5144 * DC's palette for color conversion (not the DIB color table) */
5145 if (bmp
->dib
->dsBm
.bmBitsPixel
<= 8) {
5146 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5147 if ((!dcSrc
->hPalette
) ||
5148 (dcSrc
->hPalette
== GetStockObject(DEFAULT_PALETTE
))) {
5149 /* HACK: no palette has been set in the source DC,
5150 * use the DIB colormap instead - this is necessary in some
5151 * cases since we need to do depth conversion in some places
5152 * where real Windows can just copy data straight over */
5153 colorMap
= dib
->colorMap
;
5154 nColorMap
= dib
->nColorMap
;
5156 colorMap
= X11DRV_DIB_BuildColorMap( dcSrc
, (WORD
)-1,
5157 bmp
->dib
->dsBm
.bmBitsPixel
,
5158 (BITMAPINFO
*)&(bmp
->dib
->dsBmih
),
5160 if (colorMap
) aColorMap
= TRUE
;
5163 /* perform the copy */
5164 X11DRV_DIB_DoCopyDIBSection(bmp
, FALSE
, colorMap
, nColorMap
,
5165 physDev
->drawable
, xSrc
, ySrc
, xDest
, yDest
,
5167 /* free color mapping */
5169 HeapFree(GetProcessHeap(), 0, colorMap
);
5171 GDI_ReleaseObj( dcSrc
->hBitmap
);
5174 /***********************************************************************
5175 * X11DRV_DIB_DoUpdateDIBSection
5177 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
5179 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5180 X11DRV_DIB_DoCopyDIBSection(bmp
, toDIB
, dib
->colorMap
, dib
->nColorMap
,
5181 (Drawable
)bmp
->physBitmap
, 0, 0, 0, 0,
5182 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
5185 /***********************************************************************
5186 * X11DRV_DIB_FaultHandler
5188 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
5193 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
5194 if (!bmp
) return FALSE
;
5196 state
= X11DRV_DIB_Lock(bmp
, DIB_Status_None
, FALSE
);
5197 if (state
!= DIB_Status_InSync
) {
5198 /* no way to tell whether app needs read or write yet,
5200 X11DRV_DIB_Coerce(bmp
, DIB_Status_InSync
, FALSE
);
5202 /* hm, apparently the app must have write access */
5203 X11DRV_DIB_Coerce(bmp
, DIB_Status_AppMod
, FALSE
);
5205 X11DRV_DIB_Unlock(bmp
, TRUE
);
5207 GDI_ReleaseObj( (HBITMAP
)res
);
5211 /***********************************************************************
5214 INT
X11DRV_DIB_Coerce(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
5216 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5217 INT ret
= DIB_Status_None
;
5220 EnterCriticalSection(&(dib
->lock
));
5223 case DIB_Status_GdiMod
:
5224 /* GDI access - request to draw on pixmap */
5225 switch (dib
->status
)
5228 case DIB_Status_None
:
5229 dib
->p_status
= DIB_Status_GdiMod
;
5230 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
5233 case DIB_Status_GdiMod
:
5234 TRACE("GdiMod requested in status GdiMod\n" );
5237 case DIB_Status_InSync
:
5238 TRACE("GdiMod requested in status InSync\n" );
5239 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
5240 dib
->status
= DIB_Status_GdiMod
;
5241 dib
->p_status
= DIB_Status_InSync
;
5244 case DIB_Status_AuxMod
:
5245 TRACE("GdiMod requested in status AuxMod\n" );
5246 if (lossy
) dib
->status
= DIB_Status_GdiMod
;
5247 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_GdiMod
);
5248 dib
->p_status
= DIB_Status_AuxMod
;
5249 if (dib
->status
!= DIB_Status_AppMod
) {
5250 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
5253 /* fall through if copy_aux() had to change to AppMod state */
5255 case DIB_Status_AppMod
:
5256 TRACE("GdiMod requested in status AppMod\n" );
5258 /* make it readonly to avoid app changing data while we copy */
5259 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5260 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
5262 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
5263 dib
->p_status
= DIB_Status_AppMod
;
5264 dib
->status
= DIB_Status_GdiMod
;
5269 case DIB_Status_InSync
:
5270 /* App access - request access to read DIB surface */
5271 /* (typically called from signal handler) */
5272 switch (dib
->status
)
5275 case DIB_Status_None
:
5276 /* shouldn't happen from signal handler */
5279 case DIB_Status_AuxMod
:
5280 TRACE("InSync requested in status AuxMod\n" );
5281 if (lossy
) dib
->status
= DIB_Status_InSync
;
5283 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5284 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_InSync
);
5286 if (dib
->status
!= DIB_Status_GdiMod
) {
5287 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5290 /* fall through if copy_aux() had to change to GdiMod state */
5292 case DIB_Status_GdiMod
:
5293 TRACE("InSync requested in status GdiMod\n" );
5295 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5296 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
5298 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5299 dib
->status
= DIB_Status_InSync
;
5302 case DIB_Status_InSync
:
5303 TRACE("InSync requested in status InSync\n" );
5304 /* shouldn't happen from signal handler */
5307 case DIB_Status_AppMod
:
5308 TRACE("InSync requested in status AppMod\n" );
5309 /* no reason to do anything here, and this
5310 * shouldn't happen from signal handler */
5315 case DIB_Status_AppMod
:
5316 /* App access - request access to write DIB surface */
5317 /* (typically called from signal handler) */
5318 switch (dib
->status
)
5321 case DIB_Status_None
:
5322 /* shouldn't happen from signal handler */
5325 case DIB_Status_AuxMod
:
5326 TRACE("AppMod requested in status AuxMod\n" );
5327 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5328 if (lossy
) dib
->status
= DIB_Status_AppMod
;
5329 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
5330 if (dib
->status
!= DIB_Status_GdiMod
)
5332 /* fall through if copy_aux() had to change to GdiMod state */
5334 case DIB_Status_GdiMod
:
5335 TRACE("AppMod requested in status GdiMod\n" );
5336 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5337 if (!lossy
) X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
5338 dib
->status
= DIB_Status_AppMod
;
5341 case DIB_Status_InSync
:
5342 TRACE("AppMod requested in status InSync\n" );
5343 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5344 dib
->status
= DIB_Status_AppMod
;
5347 case DIB_Status_AppMod
:
5348 TRACE("AppMod requested in status AppMod\n" );
5349 /* shouldn't happen from signal handler */
5354 case DIB_Status_AuxMod
:
5355 if (dib
->status
== DIB_Status_None
) {
5356 dib
->p_status
= req
;
5358 if (dib
->status
!= DIB_Status_AuxMod
)
5359 dib
->p_status
= dib
->status
;
5360 dib
->status
= DIB_Status_AuxMod
;
5363 /* it is up to the caller to do the copy/conversion, probably
5364 * using the return value to decide where to copy from */
5366 LeaveCriticalSection(&(dib
->lock
));
5371 /***********************************************************************
5374 INT
X11DRV_DIB_Lock(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
5376 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5377 INT ret
= DIB_Status_None
;
5380 TRACE("Locking %p from thread %08lx\n", bmp
, GetCurrentThreadId());
5381 EnterCriticalSection(&(dib
->lock
));
5383 if (req
!= DIB_Status_None
)
5384 X11DRV_DIB_Coerce(bmp
, req
, lossy
);
5389 /***********************************************************************
5392 void X11DRV_DIB_Unlock(BITMAPOBJ
*bmp
, BOOL commit
)
5394 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5397 switch (dib
->status
)
5400 case DIB_Status_None
:
5401 /* in case anyone is wondering, this is the "signal handler doesn't
5402 * work" case, where we always have to be ready for app access */
5404 switch (dib
->p_status
)
5406 case DIB_Status_AuxMod
:
5407 TRACE("Unlocking and syncing from AuxMod\n" );
5408 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
5409 if (dib
->status
!= DIB_Status_None
) {
5410 dib
->p_status
= dib
->status
;
5411 dib
->status
= DIB_Status_None
;
5413 if (dib
->p_status
!= DIB_Status_GdiMod
)
5415 /* fall through if copy_aux() had to change to GdiMod state */
5417 case DIB_Status_GdiMod
:
5418 TRACE("Unlocking and syncing from GdiMod\n" );
5419 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
5423 TRACE("Unlocking without needing to sync\n" );
5427 else TRACE("Unlocking with no changes\n");
5428 dib
->p_status
= DIB_Status_None
;
5431 case DIB_Status_GdiMod
:
5432 TRACE("Unlocking in status GdiMod\n" );
5433 /* DIB was protected in Coerce */
5435 /* no commit, revert to InSync if applicable */
5436 if ((dib
->p_status
== DIB_Status_InSync
) ||
5437 (dib
->p_status
== DIB_Status_AppMod
)) {
5438 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5439 dib
->status
= DIB_Status_InSync
;
5444 case DIB_Status_InSync
:
5445 TRACE("Unlocking in status InSync\n" );
5446 /* DIB was already protected in Coerce */
5449 case DIB_Status_AppMod
:
5450 TRACE("Unlocking in status AppMod\n" );
5451 /* DIB was already protected in Coerce */
5452 /* this case is ordinary only called from the signal handler,
5453 * so we don't bother to check for !commit */
5456 case DIB_Status_AuxMod
:
5457 TRACE("Unlocking in status AuxMod\n" );
5459 /* DIB may need protection now */
5460 if ((dib
->p_status
== DIB_Status_InSync
) ||
5461 (dib
->p_status
== DIB_Status_AppMod
))
5462 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
5464 /* no commit, revert to previous state */
5465 if (dib
->p_status
!= DIB_Status_None
)
5466 dib
->status
= dib
->p_status
;
5467 /* no protections changed */
5469 dib
->p_status
= DIB_Status_None
;
5472 LeaveCriticalSection(&(dib
->lock
));
5473 TRACE("Unlocked %p\n", bmp
);
5477 /***********************************************************************
5478 * X11DRV_CoerceDIBSection2
5480 INT
X11DRV_CoerceDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
5485 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5486 if (!bmp
) return DIB_Status_None
;
5487 ret
= X11DRV_DIB_Coerce(bmp
, req
, lossy
);
5488 GDI_ReleaseObj( hBmp
);
5492 /***********************************************************************
5493 * X11DRV_LockDIBSection2
5495 INT
X11DRV_LockDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
5500 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5501 if (!bmp
) return DIB_Status_None
;
5502 ret
= X11DRV_DIB_Lock(bmp
, req
, lossy
);
5503 GDI_ReleaseObj( hBmp
);
5507 /***********************************************************************
5508 * X11DRV_UnlockDIBSection2
5510 void X11DRV_UnlockDIBSection2(HBITMAP hBmp
, BOOL commit
)
5514 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5516 X11DRV_DIB_Unlock(bmp
, commit
);
5517 GDI_ReleaseObj( hBmp
);
5520 /***********************************************************************
5521 * X11DRV_CoerceDIBSection
5523 INT
X11DRV_CoerceDIBSection(DC
*dc
, INT req
, BOOL lossy
)
5525 if (!dc
) return DIB_Status_None
;
5526 return X11DRV_CoerceDIBSection2( dc
->hBitmap
, req
, lossy
);
5529 /***********************************************************************
5530 * X11DRV_LockDIBSection
5532 INT
X11DRV_LockDIBSection(DC
*dc
, INT req
, BOOL lossy
)
5534 if (!dc
) return DIB_Status_None
;
5535 if (!(dc
->flags
& DC_MEMORY
)) return DIB_Status_None
;
5537 return X11DRV_LockDIBSection2( dc
->hBitmap
, req
, lossy
);
5540 /***********************************************************************
5541 * X11DRV_UnlockDIBSection
5543 void X11DRV_UnlockDIBSection(DC
*dc
, BOOL commit
)
5546 if (!(dc
->flags
& DC_MEMORY
)) return;
5548 X11DRV_UnlockDIBSection2( dc
->hBitmap
, commit
);
5552 #ifdef HAVE_LIBXXSHM
5553 /***********************************************************************
5554 * X11DRV_XShmErrorHandler
5557 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
)
5563 /***********************************************************************
5564 * X11DRV_XShmCreateImage
5567 static XImage
*X11DRV_XShmCreateImage( int width
, int height
, int bpp
,
5568 XShmSegmentInfo
* shminfo
)
5570 int (*WineXHandler
)(Display
*, XErrorEvent
*);
5574 image
= XShmCreateImage(gdi_display
, visual
, bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
5577 shminfo
->shmid
= shmget(IPC_PRIVATE
, image
->bytes_per_line
* height
,
5579 if( shminfo
->shmid
!= -1 )
5581 shminfo
->shmaddr
= image
->data
= shmat(shminfo
->shmid
, 0, 0);
5582 if( shminfo
->shmaddr
!= (char*)-1 )
5584 shminfo
->readOnly
= FALSE
;
5585 if( XShmAttach( gdi_display
, shminfo
) != 0)
5587 /* Reset the error flag */
5589 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
5590 XSync( gdi_display
, 0 );
5594 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
5596 XSetErrorHandler(WineXHandler
);
5597 wine_tsx11_unlock();
5598 return image
; /* Success! */
5600 /* An error occured */
5602 XSetErrorHandler(WineXHandler
);
5604 shmdt(shminfo
->shmaddr
);
5606 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
5608 XFlush(gdi_display
);
5609 XDestroyImage(image
);
5612 wine_tsx11_unlock();
5615 #endif /* HAVE_LIBXXSHM */
5618 /***********************************************************************
5619 * X11DRV_DIB_CreateDIBSection
5621 HBITMAP
X11DRV_DIB_CreateDIBSection(
5622 DC
*dc
, BITMAPINFO
*bmi
, UINT usage
,
5623 LPVOID
*bits
, HANDLE section
,
5624 DWORD offset
, DWORD ovr_pitch
)
5627 BITMAPOBJ
*bmp
= NULL
;
5628 X11DRV_DIBSECTION
*dib
= NULL
;
5629 int *colorMap
= NULL
;
5632 /* Fill BITMAP32 structure with DIB data */
5633 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
5634 INT effHeight
, totalSize
;
5636 LPVOID mapBits
= NULL
;
5638 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
5639 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
5640 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
5642 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
5644 bm
.bmWidth
= bi
->biWidth
;
5645 bm
.bmHeight
= effHeight
;
5646 bm
.bmWidthBytes
= ovr_pitch
? ovr_pitch
5647 : DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
5648 bm
.bmPlanes
= bi
->biPlanes
;
5649 bm
.bmBitsPixel
= bi
->biBitCount
;
5652 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
5653 we're dealing with a compressed bitmap. Otherwise, use width * height. */
5654 totalSize
= bi
->biSizeImage
&& bi
->biCompression
!= BI_RGB
5655 ? bi
->biSizeImage
: bm
.bmWidthBytes
* effHeight
;
5659 SYSTEM_INFO SystemInfo
;
5663 GetSystemInfo( &SystemInfo
);
5664 mapOffset
= offset
- (offset
% SystemInfo
.dwAllocationGranularity
);
5665 mapSize
= totalSize
+ (offset
- mapOffset
);
5666 mapBits
= MapViewOfFile( section
,
5667 FILE_MAP_ALL_ACCESS
,
5671 bm
.bmBits
= (char *)mapBits
+ (offset
- mapOffset
);
5673 else if (ovr_pitch
&& offset
)
5674 bm
.bmBits
= (LPVOID
) offset
;
5677 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
5678 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
5681 /* Create Color Map */
5682 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8)
5683 colorMap
= X11DRV_DIB_BuildColorMap( usage
== DIB_PAL_COLORS
? dc
: NULL
,
5684 usage
, bm
.bmBitsPixel
, bmi
, &nColorMap
);
5686 /* Allocate Memory for DIB and fill structure */
5688 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
5691 dib
->dibSection
.dsBm
= bm
;
5692 dib
->dibSection
.dsBmih
= *bi
;
5693 dib
->dibSection
.dsBmih
.biSizeImage
= totalSize
;
5695 /* Set dsBitfields values */
5696 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
5698 dib
->dibSection
.dsBitfields
[0] = dib
->dibSection
.dsBitfields
[1] = dib
->dibSection
.dsBitfields
[2] = 0;
5700 else switch( bi
->biBitCount
)
5704 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
5705 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
5706 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f;
5711 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff0000;
5712 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x00ff00;
5713 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x0000ff;
5716 dib
->dibSection
.dshSection
= section
;
5717 dib
->dibSection
.dsOffset
= offset
;
5719 dib
->status
= DIB_Status_None
;
5720 dib
->nColorMap
= nColorMap
;
5721 dib
->colorMap
= colorMap
;
5724 /* Create Device Dependent Bitmap and add DIB pointer */
5727 res
= CreateDIBitmap(dc
->hSelf
, bi
, 0, NULL
, bmi
, usage
);
5730 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
5733 bmp
->dib
= (DIBSECTION
*) dib
;
5735 if(!bmp
->physBitmap
)
5736 X11DRV_CreateBitmap(res
);
5744 #ifdef HAVE_LIBXXSHM
5745 if (TSXShmQueryExtension(gdi_display
) &&
5746 (dib
->image
= X11DRV_XShmCreateImage( bm
.bmWidth
, effHeight
,
5747 bmp
->bitmap
.bmBitsPixel
, &dib
->shminfo
)) )
5749 ; /* Created Image */
5751 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
5752 dib
->shminfo
.shmid
= -1;
5755 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
5759 /* Clean up in case of errors */
5760 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
5762 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
5763 res
, bmp
, dib
, bm
.bmBits
);
5767 UnmapViewOfFile(mapBits
), bm
.bmBits
= NULL
;
5769 VirtualFree(bm
.bmBits
, 0L, MEM_RELEASE
), bm
.bmBits
= NULL
;
5772 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
5773 if (colorMap
) { HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
; }
5774 if (dib
) { HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
; }
5775 if (bmp
) { GDI_ReleaseObj(res
); bmp
= NULL
; }
5776 if (res
) { DeleteObject(res
); res
= 0; }
5780 /* Install fault handler, if possible */
5781 InitializeCriticalSection(&(dib
->lock
));
5782 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
5784 if (section
|| offset
)
5786 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5787 if (dib
) dib
->status
= DIB_Status_AppMod
;
5791 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5792 if (dib
) dib
->status
= DIB_Status_InSync
;
5797 /* Return BITMAP handle and storage location */
5798 if (bmp
) GDI_ReleaseObj(res
);
5799 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
5803 /***********************************************************************
5804 * X11DRV_DIB_DeleteDIBSection
5806 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
5808 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5812 #ifdef HAVE_LIBXXSHM
5813 if (dib
->shminfo
.shmid
!= -1)
5815 TSXShmDetach (gdi_display
, &(dib
->shminfo
));
5816 XDestroyImage (dib
->image
);
5817 shmdt (dib
->shminfo
.shmaddr
);
5818 dib
->shminfo
.shmid
= -1;
5822 XDestroyImage( dib
->image
);
5826 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
5828 DeleteCriticalSection(&(dib
->lock
));
5831 /***********************************************************************
5832 * X11DRV_DIB_SetDIBColorTable
5834 UINT
X11DRV_DIB_SetDIBColorTable(BITMAPOBJ
*bmp
, DC
*dc
, UINT start
, UINT count
, const RGBQUAD
*colors
)
5836 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5838 if (dib
&& dib
->colorMap
) {
5839 UINT end
= count
+ start
;
5840 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
5842 * Changing color table might change the mapping between
5843 * DIB colors and X11 colors and thus alter the visible state
5844 * of the bitmap object.
5846 X11DRV_DIB_Lock(bmp
, DIB_Status_AppMod
, FALSE
);
5847 X11DRV_DIB_GenColorMap( dc
, dib
->colorMap
, DIB_RGB_COLORS
,
5848 dib
->dibSection
.dsBm
.bmBitsPixel
,
5849 TRUE
, colors
, start
, end
);
5850 X11DRV_DIB_Unlock(bmp
, TRUE
);
5856 /***********************************************************************
5857 * X11DRV_DIB_GetDIBColorTable
5859 UINT
X11DRV_DIB_GetDIBColorTable(BITMAPOBJ
*bmp
, DC
*dc
, UINT start
, UINT count
, RGBQUAD
*colors
)
5861 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5863 if (dib
&& dib
->colorMap
) {
5864 UINT i
, end
= count
+ start
;
5865 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
5866 for (i
= start
; i
< end
; i
++,colors
++) {
5867 COLORREF col
= X11DRV_PALETTE_ToLogical( dib
->colorMap
[i
] );
5868 colors
->rgbBlue
= GetBValue(col
);
5869 colors
->rgbGreen
= GetGValue(col
);
5870 colors
->rgbRed
= GetRValue(col
);
5871 colors
->rgbReserved
= 0;
5879 /**************************************************************************
5880 * X11DRV_DIB_CreateDIBFromPixmap
5882 * Allocates a packed DIB and copies the Pixmap data into it.
5883 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
5885 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
, BOOL bDeletePixmap
)
5888 BITMAPOBJ
*pBmp
= NULL
;
5889 HGLOBAL hPackedDIB
= 0;
5891 /* Allocates an HBITMAP which references the Pixmap passed to us */
5892 hBmp
= X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap
);
5895 TRACE("\tCould not create bitmap header for Pixmap\n");
5900 * Create a packed DIB from the Pixmap wrapper bitmap created above.
5901 * A packed DIB contains a BITMAPINFO structure followed immediately by
5902 * an optional color palette and the pixel data.
5904 hPackedDIB
= DIB_CreateDIBFromBitmap(hdc
, hBmp
);
5906 /* Get a pointer to the BITMAPOBJ structure */
5907 pBmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5909 /* We can now get rid of the HBITMAP wrapper we created earlier.
5910 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
5914 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
5915 pBmp
->physBitmap
= NULL
;
5918 GDI_ReleaseObj( hBmp
);
5922 TRACE("\tReturning packed DIB %x\n", hPackedDIB
);
5927 /**************************************************************************
5928 * X11DRV_DIB_CreatePixmapFromDIB
5930 * Creates a Pixmap from a packed DIB
5932 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
5934 Pixmap pixmap
= None
;
5936 BITMAPOBJ
*pBmp
= NULL
;
5937 LPBYTE pPackedDIB
= NULL
;
5938 LPBITMAPINFO pbmi
= NULL
;
5939 LPBITMAPINFOHEADER pbmiHeader
= NULL
;
5940 LPBYTE pbits
= NULL
;
5942 /* Get a pointer to the packed DIB's data */
5943 pPackedDIB
= (LPBYTE
)GlobalLock(hPackedDIB
);
5944 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
5945 pbmi
= (LPBITMAPINFO
)pPackedDIB
;
5946 pbits
= (LPBYTE
)(pPackedDIB
5947 + DIB_BitmapInfoSize( (LPBITMAPINFO
)pbmiHeader
, DIB_RGB_COLORS
));
5949 /* Create a DDB from the DIB */
5951 hBmp
= CreateDIBitmap(hdc
,
5958 GlobalUnlock(hPackedDIB
);
5960 TRACE("CreateDIBitmap returned %x\n", hBmp
);
5962 /* Retrieve the internal Pixmap from the DDB */
5964 pBmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5966 pixmap
= (Pixmap
)pBmp
->physBitmap
;
5967 /* clear the physBitmap so that we can steal its pixmap */
5968 pBmp
->physBitmap
= NULL
;
5971 /* Delete the DDB we created earlier now that we have stolen its pixmap */
5972 GDI_ReleaseObj( hBmp
);
5975 TRACE("\tReturning Pixmap %ld\n", pixmap
);