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 occurred */
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);