2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
9 #ifndef X_DISPLAY_MISSING
23 static int bitmapDepthTable[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
24 static int ximageDepthTable[] = { 0, 0, 0, 0, 0, 0, 0 };
26 /***********************************************************************
29 BOOL32 X11DRV_DIB_Init(void)
34 for( i = 0; bitmapDepthTable[i]; i++ )
36 testimage = TSXCreateImage(display, DefaultVisualOfScreen(X11DRV_GetXScreen()),
37 bitmapDepthTable[i], ZPixmap, 0, NULL, 1, 1, 32, 20 );
38 if( testimage ) ximageDepthTable[i] = testimage->bits_per_pixel;
40 TSXDestroyImage(testimage);
46 /***********************************************************************
47 * X11DRV_DIB_GetXImageWidthBytes
49 * Return the width of an X image in bytes
51 int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
55 if (!ximageDepthTable[0]) {
58 for( i = 0; bitmapDepthTable[i] ; i++ )
59 if( bitmapDepthTable[i] == depth )
60 return (4 * ((width * ximageDepthTable[i] + 31)/32));
62 WARN(bitmap, "(%d): Unsupported depth\n", depth );
66 /***********************************************************************
67 * X11DRV_DIB_BuildColorMap
69 * Build the color map from the bitmap palette. Should not be called
70 * for a >8-bit deep bitmap.
72 int *X11DRV_DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth,
73 const BITMAPINFO *info, int *nColors )
80 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
82 colors = info->bmiHeader.biClrUsed;
83 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
84 colorPtr = (WORD *)info->bmiColors;
86 else /* assume BITMAPCOREINFO */
88 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
89 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
94 ERR(bitmap, "called with >256 colors!\n");
98 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
99 colors * sizeof(int) )))
102 if (coloruse == DIB_RGB_COLORS)
106 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
108 if (depth == 1) /* Monochrome */
109 for (i = 0; i < colors; i++, rgb++)
110 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
111 rgb->rgbBlue > 255*3/2);
113 for (i = 0; i < colors; i++, rgb++)
114 colorMapping[i] = COLOR_ToPhysical( dc, RGB(rgb->rgbRed,
120 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
122 if (depth == 1) /* Monochrome */
123 for (i = 0; i < colors; i++, rgb++)
124 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
125 rgb->rgbtBlue > 255*3/2);
127 for (i = 0; i < colors; i++, rgb++)
128 colorMapping[i] = COLOR_ToPhysical( dc, RGB(rgb->rgbtRed,
133 else /* DIB_PAL_COLORS */
135 for (i = 0; i < colors; i++, colorPtr++)
136 colorMapping[i] = COLOR_ToPhysical( dc, PALETTEINDEX(*colorPtr) );
144 /***********************************************************************
145 * X11DRV_DIB_MapColor
147 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys )
151 for (color = 0; color < nPhysMap; color++)
152 if (physMap[color] == phys)
155 WARN(bitmap, "Strange color %08x\n", phys);
161 /***********************************************************************
162 * X11DRV_DIB_SetImageBits_1_Line
164 * Handles a single line of 1 bit data.
166 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth, int left, int *colors,
167 XImage *bmpImage, int h, const BYTE *bits)
172 if((extra = (left & 7)) != 0) {
179 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
180 for (i = dstwidth/8, x = left; i > 0; i--)
183 XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
184 XPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] );
185 XPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] );
186 XPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] );
187 XPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] );
188 XPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] );
189 XPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] );
190 XPutPixel( bmpImage, x++, h, colors[pix & 1] );
195 case 7: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
196 case 6: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
197 case 5: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
198 case 4: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
199 case 3: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
200 case 2: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
201 case 1: XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
205 /***********************************************************************
206 * X11DRV_DIB_SetImageBits_1
208 * SetDIBits for a 1-bit deep DIB.
210 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
211 DWORD srcwidth, DWORD dstwidth, int left,
212 int *colors, XImage *bmpImage )
217 DWORD linebytes = ((srcwidth + 31) & ~31) / 8;
220 for (h = lines-1; h >=0; h--) {
221 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
223 srcbits += linebytes;
227 for (h = 0; h < lines; h++) {
228 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
230 srcbits += linebytes;
236 /***********************************************************************
237 * X11DRV_DIB_SetImageBits_4
239 * SetDIBits for a 4-bit deep DIB.
241 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
242 DWORD srcwidth, DWORD dstwidth, int left,
243 int *colors, XImage *bmpImage )
247 const BYTE *bits = srcbits + (left >> 1);
250 DWORD linebytes = ((srcwidth+7)&~7)/2;
258 for (h = lines-1; h >= 0; h--) {
259 for (i = dstwidth/2, x = left; i > 0; i--) {
261 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
262 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
264 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
265 srcbits += linebytes;
266 bits = srcbits + (left >> 1);
270 for (h = 0; h < lines; h++) {
271 for (i = dstwidth/2, x = left; i > 0; i--) {
273 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
274 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
276 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
277 srcbits += linebytes;
278 bits = srcbits + (left >> 1);
285 /***********************************************************************
286 * X11DRV_DIB_GetImageBits_4
288 * GetDIBits for a 4-bit deep DIB.
290 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *srcbits,
291 DWORD srcwidth, DWORD dstwidth, int left,
292 int *colors, int nColors, XImage *bmpImage )
296 BYTE *bits = srcbits + (left >> 1);
299 DWORD linebytes = ((srcwidth+7)&~7)/2;
306 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
308 for (h = lines-1; h >= 0; h--) {
309 for (i = dstwidth/2, x = left; i > 0; i--) {
310 *bits++ = (X11DRV_DIB_MapColor( colors, nColors,
311 XGetPixel( bmpImage, x++, h )) << 4)
312 | (X11DRV_DIB_MapColor( colors, nColors,
313 XGetPixel( bmpImage, x++, h )) & 0x0f);
316 *bits = (X11DRV_DIB_MapColor( colors, nColors,
317 XGetPixel( bmpImage, x++, h )) << 4);
318 srcbits += linebytes;
319 bits = srcbits + (left >> 1);
323 for (h = 0; h < lines; h++) {
324 for (i = dstwidth/2, x = left; i > 0; i--) {
325 *bits++ = (X11DRV_DIB_MapColor( colors, nColors,
326 XGetPixel( bmpImage, x++, h ))
328 | (X11DRV_DIB_MapColor( colors, nColors,
329 XGetPixel( bmpImage, x++, h )) & 0x0f);
332 *bits = (X11DRV_DIB_MapColor( colors, nColors,
333 XGetPixel( bmpImage, x++, h )) << 4);
334 srcbits += linebytes;
335 bits = srcbits + (left >> 1);
340 /***********************************************************************
341 * X11DRV_DIB_SetImageBits_RLE4
343 * SetDIBits for a 4-bit deep compressed DIB.
345 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
346 DWORD width, DWORD dstwidth,
347 int left, int *colors,
350 int x = 0, c, length;
351 const BYTE *begin = bits;
355 while ((int)lines >= 0) {
357 if (length) { /* encoded */
360 XPutPixel(bmpImage, x++, lines, colors[c >>4]);
368 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
384 case 1: /* eopicture */
390 FIXME(x11drv, "x-delta is too large?\n");
396 default: /* absolute */
399 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
407 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
415 if ((bits - begin) & 1)
424 /***********************************************************************
425 * X11DRV_DIB_SetImageBits_8
427 * SetDIBits for an 8-bit deep DIB.
429 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
430 DWORD srcwidth, DWORD dstwidth, int left,
431 int *colors, XImage *bmpImage )
435 const BYTE *bits = srcbits + left;
437 /* align to 32 bit */
438 DWORD linebytes = (srcwidth + 3) & ~3;
443 for (h = lines - 1; h >= 0; h--) {
444 for (x = left; x < dstwidth; x++, bits++) {
445 XPutPixel( bmpImage, x, h, colors[*bits] );
447 bits = (srcbits += linebytes) + left;
451 for (h = 0; h < lines; h++) {
452 for (x = left; x < dstwidth; x++, bits++) {
453 XPutPixel( bmpImage, x, h, colors[*bits] );
455 bits = (srcbits += linebytes) + left;
460 /***********************************************************************
461 * X11DRV_DIB_GetImageBits_8
463 * GetDIBits for an 8-bit deep DIB.
465 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *srcbits,
466 DWORD srcwidth, DWORD dstwidth, int left,
467 int *colors, int nColors, XImage *bmpImage )
471 BYTE *bits = srcbits + left;
473 /* align to 32 bit */
474 DWORD linebytes = (srcwidth + 3) & ~3;
479 for (h = lines - 1; h >= 0; h--) {
480 for (x = left; x < dstwidth; x++, bits++) {
481 if ( XGetPixel( bmpImage, x, h ) != colors[*bits] )
482 *bits = X11DRV_DIB_MapColor( colors, nColors,
483 XGetPixel( bmpImage, x, h ) );
485 bits = (srcbits += linebytes) + left;
489 for (h = 0; h < lines; h++) {
490 for (x = left; x < dstwidth; x++, bits++) {
491 if ( XGetPixel( bmpImage, x, h ) != colors[*bits] )
492 *bits = X11DRV_DIB_MapColor( colors, nColors,
493 XGetPixel( bmpImage, x, h ) );
495 bits = (srcbits += linebytes) + left;
500 /***********************************************************************
501 * X11DRV_DIB_SetImageBits_RLE8
503 * SetDIBits for an 8-bit deep compressed DIB.
505 * This function rewritten 941113 by James Youngman. WINE blew out when I
506 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
508 * This was because the algorithm assumed that all RLE8 bitmaps end with the
509 * 'End of bitmap' escape code. This code is very much laxer in what it
510 * allows to end the expansion. Possibly too lax. See the note by
511 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
512 * bitmap should end with RleEnd, but on the other hand, software exists
513 * that produces ones that don't and Windows 3.1 doesn't complain a bit
516 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
517 * James A. Youngman <mbcstjy@afs.man.ac.uk>
521 enum Rle8_EscapeCodes
524 * Apologies for polluting your file's namespace...
526 RleEol = 0, /* End of line */
527 RleEnd = 1, /* End of bitmap */
528 RleDelta = 2 /* Delta */
531 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
532 DWORD width, DWORD dstwidth,
533 int left, int *colors,
536 int x; /* X-positon on each line. Increases. */
537 int line; /* Line #. Starts at lines-1, decreases */
538 const BYTE *pIn = bits; /* Pointer to current position in bits */
539 BYTE length; /* The length pf a run */
540 BYTE color_index; /* index into colors[] as read from bits */
541 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
542 int color; /* value of colour[color_index] */
544 if (lines == 0) /* Let's hope this doesn't happen. */
548 * Note that the bitmap data is stored by Windows starting at the
549 * bottom line of the bitmap and going upwards. Within each line,
550 * the data is stored left-to-right. That's the reason why line
551 * goes from lines-1 to 0. [JAY]
561 * If the length byte is not zero (which is the escape value),
562 * We have a run of length pixels all the same colour. The colour
563 * index is stored next.
565 * If the length byte is zero, we need to read the next byte to
566 * know what to do. [JAY]
571 * [Run-Length] Encoded mode
573 color_index = (*pIn++); /* Get the colour index. */
574 color = colors[color_index];
577 XPutPixel(bmpImage, x++, line, color);
582 * Escape codes (may be an absolute sequence though)
584 escape_code = (*pIn++);
587 case RleEol: /* =0, end of line */
594 case RleEnd: /* =1, end of bitmap */
597 * Not all RLE8 bitmaps end with this
598 * code. For example, Paint Shop Pro
599 * produces some that don't. That's (I think)
600 * what caused the previous implementation to
603 line=-1; /* Cause exit from do loop. */
607 case RleDelta: /* =2, a delta */
610 * Note that deltaing to line 0
611 * will cause an exit from the loop,
612 * which may not be what is intended.
613 * The fact that there is a delta in the bits
614 * almost certainly implies that there is data
615 * to follow. You may feel that we should
616 * jump to the top of the loop to avoid exiting
619 * TODO: Decide what to do here in that case. [JAY]
625 TRACE(bitmap, "Delta to last line of bitmap "
626 "(wrongly?) causes loop exit\n");
631 default: /* >2, switch to absolute mode */
636 length = escape_code;
639 color_index = (*pIn++);
640 XPutPixel(bmpImage, x++, line,
641 colors[color_index]);
645 * If you think for a moment you'll realise that the
646 * only time we could ever possibly read an odd
647 * number of bytes is when there is a 0x00 (escape),
648 * a value >0x02 (absolute mode) and then an odd-
649 * length run. Therefore this is the only place we
650 * need to worry about it. Everywhere else the
651 * bytes are always read in pairs. [JAY]
654 pIn++; /* Throw away the pad byte. */
657 } /* switch (escape_code) : Escape sequence */
658 } /* process either an encoded sequence or an escape sequence */
660 /* We expect to come here more than once per line. */
661 } while (line >= 0); /* Do this until the bitmap is filled */
664 * Everybody comes here at the end.
665 * Check how we exited the loop and print a message if it's a bit odd.
668 if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) )
670 TRACE(bitmap, "End-of-bitmap "
671 "without (strictly) proper escape code. Last two "
672 "bytes were: %02X %02X.\n",
679 /***********************************************************************
680 * X11DRV_DIB_SetImageBits_16
682 * SetDIBits for a 16-bit deep DIB.
684 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
685 DWORD srcwidth, DWORD dstwidth, int left,
686 DC *dc, XImage *bmpImage )
694 /* align to 32 bit */
695 DWORD linebytes = (srcwidth * 2 + 3) & ~3;
699 ptr = (LPWORD) srcbits + left;
701 for (h = lines - 1; h >= 0; h--) {
702 for (x = left; x < dstwidth; x++, ptr++) {
704 r = (BYTE) ((val & 0x7c00) >> 7);
705 g = (BYTE) ((val & 0x03e0) >> 2);
706 b = (BYTE) ((val & 0x001f) << 3);
707 XPutPixel( bmpImage, x, h,
708 COLOR_ToPhysical(dc, RGB(r,g,b)) );
710 ptr = (LPWORD) (srcbits += linebytes) + left;
714 for (h = 0; h < lines; h++) {
715 for (x = left; x < dstwidth; x++, ptr++) {
717 r = (BYTE) ((val & 0x7c00) >> 7);
718 g = (BYTE) ((val & 0x03e0) >> 2);
719 b = (BYTE) ((val & 0x001f) << 3);
720 XPutPixel( bmpImage, x, h,
721 COLOR_ToPhysical(dc, RGB(r,g,b)) );
723 ptr = (LPWORD) (srcbits += linebytes) + left;
729 /***********************************************************************
730 * X11DRV_DIB_GetImageBits_16
732 * GetDIBits for an 16-bit deep DIB.
734 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *srcbits,
735 DWORD srcwidth, DWORD dstwidth, int left,
743 /* align to 32 bit */
744 DWORD linebytes = (srcwidth * 2 + 3) & ~3;
748 ptr = (LPWORD) srcbits + left;
750 for (h = lines - 1; h >= 0; h--)
752 for (x = left; x < dstwidth; x++, ptr++)
754 COLORREF pixel = COLOR_ToLogical( XGetPixel( bmpImage, x, h ) );
755 r = (BYTE) GetRValue(pixel);
756 g = (BYTE) GetGValue(pixel);
757 b = (BYTE) GetBValue(pixel);
758 *ptr = ( ((r << 7) & 0x7c00) | ((g << 2) & 0x03e0) | ((b >> 3) & 0x001f) );
760 ptr = (LPWORD) (srcbits += linebytes) + left;
764 for (h = 0; h < lines; h++)
766 for (x = left; x < dstwidth; x++, ptr++)
768 COLORREF pixel = COLOR_ToLogical( XGetPixel( bmpImage, x, h ) );
769 r = (BYTE) GetRValue(pixel);
770 g = (BYTE) GetGValue(pixel);
771 b = (BYTE) GetBValue(pixel);
772 *ptr = ( ((r << 7) & 0x7c00) | ((g << 2) & 0x03e0) | ((b >> 3) & 0x001f) );
775 ptr = (LPWORD) (srcbits += linebytes) + left;
782 /***********************************************************************
783 * X11DRV_DIB_SetImageBits_24
785 * SetDIBits for a 24-bit deep DIB.
787 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
788 DWORD srcwidth, DWORD dstwidth, int left,
789 DC *dc, XImage *bmpImage )
792 const BYTE *bits = srcbits + left * 3;
795 /* align to 32 bit */
796 DWORD linebytes = (srcwidth * 3 + 3) & ~3;
800 /* "bits" order is reversed for some reason */
803 for (h = lines - 1; h >= 0; h--) {
804 for (x = left; x < dstwidth; x++, bits += 3) {
805 XPutPixel( bmpImage, x, h,
806 COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
808 bits = (srcbits += linebytes) + left * 3;
812 for (h = 0; h < lines; h++) {
813 for (x = left; x < dstwidth; x++, bits += 3) {
814 XPutPixel( bmpImage, x, h,
815 COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
817 bits = (srcbits += linebytes) + left * 3;
823 /***********************************************************************
824 * X11DRV_DIB_GetImageBits_24
826 * GetDIBits for an 24-bit deep DIB.
828 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *srcbits,
829 DWORD srcwidth, DWORD dstwidth, int left,
834 BYTE *bits = srcbits + (left * 3);
836 /* align to 32 bit */
837 DWORD linebytes = (srcwidth * 3 + 3) & ~3;
842 for (h = lines - 1; h >= 0; h--)
844 for (x = left; x < dstwidth; x++, bits += 3)
846 COLORREF pixel = COLOR_ToLogical( XGetPixel( bmpImage, x, h ) );
847 bits[0] = GetRValue(pixel);
848 bits[1] = GetGValue(pixel);
849 bits[2] = GetBValue(pixel);
851 bits = (srcbits += linebytes) + (left * 3);
855 for (h = 0; h < lines; h++)
857 for (x = left; x < dstwidth; x++, bits += 3)
859 COLORREF pixel = COLOR_ToLogical( XGetPixel( bmpImage, x, h ) );
860 bits[0] = GetRValue(pixel);
861 bits[1] = GetGValue(pixel);
862 bits[2] = GetBValue(pixel);
865 bits = (srcbits += linebytes) + (left * 3);
871 /***********************************************************************
872 * X11DRV_DIB_SetImageBits_32
874 * SetDIBits for a 32-bit deep DIB.
876 static void X11DRV_DIB_SetImageBits_32( int lines, const BYTE *srcbits,
877 DWORD srcwidth, DWORD dstwidth, int left,
878 DC *dc, XImage *bmpImage )
881 const BYTE *bits = srcbits + left * 4;
884 DWORD linebytes = (srcwidth * 4);
889 for (h = lines - 1; h >= 0; h--) {
890 for (x = left; x < dstwidth; x++, bits += 4) {
891 XPutPixel( bmpImage, x, h,
892 COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
894 bits = (srcbits += linebytes) + left * 4;
898 for (h = 0; h < lines; h++) {
899 for (x = left; x < dstwidth; x++, bits += 4) {
900 XPutPixel( bmpImage, x, h,
901 COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
903 bits = (srcbits += linebytes) + left * 4;
909 /***********************************************************************
910 * X11DRV_DIB_GetImageBits_32
912 * GetDIBits for an 32-bit deep DIB.
914 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *srcbits,
915 DWORD srcwidth, DWORD dstwidth, int left,
920 BYTE *bits = srcbits + (left * 4);
922 /* align to 32 bit */
923 DWORD linebytes = (srcwidth * 4);
928 for (h = lines - 1; h >= 0; h--)
930 for (x = left; x < dstwidth; x++, bits += 4)
932 COLORREF pixel = COLOR_ToLogical( XGetPixel( bmpImage, x, h ) );
933 bits[0] = GetRValue(pixel);
934 bits[1] = GetGValue(pixel);
935 bits[2] = GetBValue(pixel);
937 bits = (srcbits += linebytes) + (left * 4);
941 for (h = 0; h < lines; h++)
943 for (x = left; x < dstwidth; x++, bits += 4)
945 COLORREF pixel = COLOR_ToLogical( XGetPixel( bmpImage, x, h ) );
946 bits[0] = GetRValue(pixel);
947 bits[1] = GetGValue(pixel);
948 bits[2] = GetBValue(pixel);
951 bits = (srcbits += linebytes) + (left * 4);
957 /***********************************************************************
958 * X11DRV_DIB_SetImageBits
960 * Transfer the bits to an X image.
961 * Helper function for SetDIBits() and SetDIBitsToDevice().
962 * The Xlib critical section must be entered before calling this function.
964 int X11DRV_DIB_SetImageBits( const DIB_SETIMAGEBITS_DESCR *descr )
966 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
969 if ( descr->dc && descr->dc->w.flags & DC_DIRTY )
970 CLIPPING_UpdateGCRegion( descr->dc );
973 bmpImage = descr->image;
975 bmpImage = XCreateImage( display,
976 DefaultVisualOfScreen(X11DRV_GetXScreen()),
977 descr->depth, ZPixmap, 0, NULL,
978 descr->infoWidth, lines, 32, 0 );
979 bmpImage->data = xcalloc( bmpImage->bytes_per_line * lines );
982 /* Transfer the pixels */
983 switch(descr->infoBpp)
986 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
987 descr->width, descr->xSrc, descr->colorMap,
991 if (descr->compression)
992 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
993 descr->infoWidth, descr->width,
994 descr->xSrc, descr->colorMap,
997 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
998 descr->infoWidth, descr->width,
999 descr->xSrc, descr->colorMap,
1003 if (descr->compression)
1004 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
1005 descr->infoWidth, descr->width,
1007 descr->colorMap, bmpImage );
1009 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
1010 descr->infoWidth, descr->width,
1011 descr->xSrc, descr->colorMap,
1016 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
1017 descr->infoWidth, descr->width,
1018 descr->xSrc, descr->dc, bmpImage);
1021 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
1022 descr->infoWidth, descr->width,
1023 descr->xSrc, descr->dc, bmpImage );
1026 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
1027 descr->infoWidth, descr->width,
1028 descr->xSrc, descr->dc, bmpImage);
1031 WARN(bitmap, "(%d): Invalid depth\n", descr->infoBpp );
1035 XPutImage( display, descr->drawable, descr->gc, bmpImage,
1036 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
1037 descr->width, descr->height );
1039 if (!descr->image) XDestroyImage( bmpImage );
1043 /***********************************************************************
1044 * X11DRV_DIB_GetImageBits
1046 * Transfer the bits from an X image.
1047 * The Xlib critical section must be entered before calling this function.
1049 int X11DRV_DIB_GetImageBits( const DIB_SETIMAGEBITS_DESCR *descr )
1051 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
1055 bmpImage = descr->image;
1057 bmpImage = XCreateImage( display,
1058 DefaultVisualOfScreen(X11DRV_GetXScreen()),
1059 descr->depth, ZPixmap, 0, NULL,
1060 descr->infoWidth, lines, 32, 0 );
1061 bmpImage->data = xcalloc( bmpImage->bytes_per_line * lines );
1064 XGetSubImage( display, descr->drawable, descr->xDest, descr->yDest,
1065 descr->width, descr->height, AllPlanes, ZPixmap,
1066 bmpImage, descr->xSrc, descr->ySrc );
1068 /* Transfer the pixels */
1069 switch(descr->infoBpp)
1072 FIXME(bitmap, "Depth 1 not yet supported!\n");
1076 if (descr->compression)
1077 FIXME(bitmap, "Compression not yet supported!\n");
1079 X11DRV_DIB_GetImageBits_4( descr->lines,
1080 (LPVOID)descr->bits, descr->infoWidth,
1081 descr->width, descr->xSrc,
1082 descr->colorMap, descr->nColorMap,
1087 if (descr->compression)
1088 FIXME(bitmap, "Compression not yet supported!\n");
1090 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
1091 descr->infoWidth, descr->width,
1092 descr->xSrc, descr->colorMap,
1093 descr->nColorMap, bmpImage );
1098 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
1100 descr->width, descr->xSrc, bmpImage );
1104 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
1106 descr->width, descr->xSrc, bmpImage );
1110 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
1112 descr->width, descr->xSrc, bmpImage );
1116 WARN(bitmap, "(%d): Invalid depth\n", descr->infoBpp );
1120 if (!descr->image) XDestroyImage( bmpImage );
1124 /*************************************************************************
1125 * X11DRV_SetDIBitsToDevice
1128 INT32 X11DRV_SetDIBitsToDevice( DC *dc, INT32 xDest, INT32 yDest, DWORD cx,
1129 DWORD cy, INT32 xSrc, INT32 ySrc,
1130 UINT32 startscan, UINT32 lines, LPCVOID bits,
1131 const BITMAPINFO *info, UINT32 coloruse )
1133 DIB_SETIMAGEBITS_DESCR descr;
1134 DWORD width, oldcy = cy;
1136 int height, tmpheight;
1137 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
1140 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
1141 &descr.infoBpp, &descr.compression ) == -1)
1144 if (height < 0) height = -height;
1145 if (!lines || (startscan >= height)) return 0;
1146 if (startscan + lines > height) lines = height - startscan;
1147 if (ySrc < startscan) ySrc = startscan;
1148 else if (ySrc >= startscan + lines) return 0;
1149 if (xSrc >= width) return 0;
1150 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
1151 if (xSrc + cx >= width) cx = width - xSrc;
1152 if (!cx || !cy) return 0;
1154 X11DRV_SetupGCForText( dc ); /* To have the correct colors */
1155 TSXSetFunction(display, physDev->gc, X11DRV_XROPfunction[dc->w.ROPmode-1]);
1157 if (descr.infoBpp <= 8)
1159 descr.colorMap = X11DRV_DIB_BuildColorMap( dc, coloruse,
1161 info, &descr.nColorMap );
1162 if (!descr.colorMap)
1169 descr.lines = tmpheight >= 0 ? lines : -lines;
1170 descr.infoWidth = width;
1171 descr.depth = dc->w.bitsPerPixel;
1172 descr.drawable = physDev->drawable;
1173 descr.gc = physDev->gc;
1175 descr.ySrc = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy)
1177 descr.xDest = dc->w.DCOrgX + XLPTODP( dc, xDest );
1178 descr.yDest = dc->w.DCOrgY + YLPTODP( dc, yDest ) +
1179 (tmpheight >= 0 ? oldcy-cy : 0);
1183 EnterCriticalSection( &X11DRV_CritSection );
1184 result = CALL_LARGE_STACK( X11DRV_DIB_SetImageBits, &descr );
1185 LeaveCriticalSection( &X11DRV_CritSection );
1187 HeapFree(GetProcessHeap(), 0, descr.colorMap);
1191 #endif /* !defined(X_DISPLAY_MISSING) */