2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
17 static int bitmapDepthTable[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
18 static int ximageDepthTable[] = { 0, 0, 0, 0, 0, 0, 0 };
20 /***********************************************************************
23 BOOL32 X11DRV_DIB_Init(void)
28 for( i = 0; bitmapDepthTable[i]; i++ )
30 testimage = TSXCreateImage(display, DefaultVisualOfScreen(screen),
31 bitmapDepthTable[i], ZPixmap, 0, NULL, 1, 1, 32, 20 );
32 if( testimage ) ximageDepthTable[i] = testimage->bits_per_pixel;
34 TSXDestroyImage(testimage);
40 /***********************************************************************
41 * X11DRV_DIB_GetXImageWidthBytes
43 * Return the width of an X image in bytes
45 int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
49 if (!ximageDepthTable[0]) {
52 for( i = 0; bitmapDepthTable[i] ; i++ )
53 if( bitmapDepthTable[i] == depth )
54 return (4 * ((width * ximageDepthTable[i] + 31)/32));
56 WARN(bitmap, "(%d): Unsupported depth\n", depth );
60 /***********************************************************************
61 * X11DRV_DIB_BuildColorMap
63 * Build the color map from the bitmap palette. Should not be called
64 * for a >8-bit deep bitmap.
66 int *X11DRV_DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth,
67 const BITMAPINFO *info, int *nColors )
74 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
76 colors = info->bmiHeader.biClrUsed;
77 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
78 colorPtr = (WORD *)info->bmiColors;
80 else /* assume BITMAPCOREINFO */
82 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
83 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
88 ERR(bitmap, "called with >256 colors!\n");
92 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
93 colors * sizeof(int) )))
96 if (coloruse == DIB_RGB_COLORS)
100 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
102 if (depth == 1) /* Monochrome */
103 for (i = 0; i < colors; i++, rgb++)
104 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
105 rgb->rgbBlue > 255*3/2);
107 for (i = 0; i < colors; i++, rgb++)
108 colorMapping[i] = COLOR_ToPhysical( dc, RGB(rgb->rgbRed,
114 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
116 if (depth == 1) /* Monochrome */
117 for (i = 0; i < colors; i++, rgb++)
118 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
119 rgb->rgbtBlue > 255*3/2);
121 for (i = 0; i < colors; i++, rgb++)
122 colorMapping[i] = COLOR_ToPhysical( dc, RGB(rgb->rgbtRed,
127 else /* DIB_PAL_COLORS */
129 for (i = 0; i < colors; i++, colorPtr++)
130 colorMapping[i] = COLOR_ToPhysical( dc, PALETTEINDEX(*colorPtr) );
138 /***********************************************************************
139 * X11DRV_DIB_MapColor
141 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys )
145 for (color = 0; color < nPhysMap; color++)
146 if (physMap[color] == phys)
149 WARN(bitmap, "Strange color %08x\n", phys);
155 /***********************************************************************
156 * X11DRV_DIB_SetImageBits_1_Line
158 * Handles a single line of 1 bit data.
160 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth, int left, int *colors,
161 XImage *bmpImage, int h, const BYTE *bits)
166 dstwidth += left; bits += left >> 3;
168 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
169 for (i = dstwidth/8, x = left&~7; (i > 0); i--)
172 XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
173 XPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] );
174 XPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] );
175 XPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] );
176 XPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] );
177 XPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] );
178 XPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] );
179 XPutPixel( bmpImage, x++, h, colors[pix & 1] );
184 case 7: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
185 case 6: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
186 case 5: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
187 case 4: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
188 case 3: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
189 case 2: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
190 case 1: XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
194 /***********************************************************************
195 * X11DRV_DIB_SetImageBits_1
197 * SetDIBits for a 1-bit deep DIB.
199 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
200 DWORD srcwidth, DWORD dstwidth, int left,
201 int *colors, XImage *bmpImage )
206 DWORD linebytes = ((srcwidth + 31) & ~31) / 8;
209 for (h = lines-1; h >=0; h--) {
210 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
212 srcbits += linebytes;
216 for (h = 0; h < lines; h++) {
217 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
219 srcbits += linebytes;
225 /***********************************************************************
226 * X11DRV_DIB_SetImageBits_4
228 * SetDIBits for a 4-bit deep DIB.
230 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
231 DWORD srcwidth, DWORD dstwidth, int left,
232 int *colors, XImage *bmpImage )
236 const BYTE *bits = srcbits + (left >> 1);
239 DWORD linebytes = ((srcwidth+7)&~7)/2;
243 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
245 for (h = lines-1; h >= 0; h--) {
246 for (i = dstwidth/2, x = left&~1; i > 0; i--) {
248 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
249 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
251 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
252 srcbits += linebytes;
253 bits = srcbits + (left >> 1);
257 for (h = 0; h < lines; h++) {
258 for (i = dstwidth/2, x = left&~1; i > 0; i--) {
260 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
261 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
263 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
264 srcbits += linebytes;
265 bits = srcbits + (left >> 1);
272 /***********************************************************************
273 * X11DRV_DIB_GetImageBits_4
275 * GetDIBits for a 4-bit deep DIB.
277 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *srcbits,
278 DWORD srcwidth, DWORD dstwidth, int left,
279 int *colors, int nColors, XImage *bmpImage )
283 BYTE *bits = srcbits + (left >> 1);
286 DWORD linebytes = ((srcwidth+7)&~7)/2;
290 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
292 for (h = lines-1; h >= 0; h--) {
293 for (i = dstwidth/2, x = left&~1; i > 0; i--) {
294 *bits++ = (X11DRV_DIB_MapColor( colors, nColors,
295 XGetPixel( bmpImage, x++, h )) << 4)
296 | (X11DRV_DIB_MapColor( colors, nColors,
297 XGetPixel( bmpImage, x++, h )) & 0x0f);
300 *bits = (X11DRV_DIB_MapColor( colors, nColors,
301 XGetPixel( bmpImage, x++, h )) << 4);
302 srcbits += linebytes;
303 bits = srcbits + (left >> 1);
307 for (h = 0; h < lines; h++) {
308 for (i = dstwidth/2, x = left&~1; i > 0; i--) {
309 *bits++ = (X11DRV_DIB_MapColor( colors, nColors,
310 XGetPixel( bmpImage, x++, h ))
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);
324 #define check_xy(x,y) \
331 /***********************************************************************
332 * X11DRV_DIB_SetImageBits_RLE4
334 * SetDIBits for a 4-bit deep compressed DIB.
336 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits, DWORD width,
337 DWORD dstwidth, int left, int *colors, XImage *bmpImage )
339 int x = 0, c, length;
340 const BYTE *begin = bits;
342 dstwidth += left; /* FIXME: avoid putting x<left pixels */
345 while ((int)lines >= 0)
348 if (length) { /* encoded */
351 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
355 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
367 case 1: /* eopicture */
375 default: /* absolute */
378 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
382 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
386 if ((bits - begin) & 1)
396 /***********************************************************************
397 * X11DRV_DIB_SetImageBits_8
399 * SetDIBits for an 8-bit deep DIB.
401 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
402 DWORD srcwidth, DWORD dstwidth, int left,
403 int *colors, XImage *bmpImage )
407 const BYTE *bits = srcbits + left;
409 /* align to 32 bit */
410 DWORD linebytes = (srcwidth + 3) & ~3;
415 for (h = lines - 1; h >= 0; h--) {
416 for (x = left; x < dstwidth; x++, bits++) {
417 XPutPixel( bmpImage, x, h, colors[*bits] );
419 bits = (srcbits += linebytes) + left;
423 for (h = 0; h < lines; h++) {
424 for (x = left; x < dstwidth; x++, bits++) {
425 XPutPixel( bmpImage, x, h, colors[*bits] );
427 bits = (srcbits += linebytes) + left;
432 /***********************************************************************
433 * X11DRV_DIB_GetImageBits_8
435 * GetDIBits for an 8-bit deep DIB.
437 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *srcbits,
438 DWORD srcwidth, DWORD dstwidth, int left,
439 int *colors, int nColors, XImage *bmpImage )
443 BYTE *bits = srcbits + left;
445 /* align to 32 bit */
446 DWORD linebytes = (srcwidth + 3) & ~3;
451 for (h = lines - 1; h >= 0; h--) {
452 for (x = left; x < dstwidth; x++, bits++) {
453 if ( XGetPixel( bmpImage, x, h ) != colors[*bits] )
454 *bits = X11DRV_DIB_MapColor( colors, nColors,
455 XGetPixel( bmpImage, x, h ) );
457 bits = (srcbits += linebytes) + left;
461 for (h = 0; h < lines; h++) {
462 for (x = left; x < dstwidth; x++, bits++) {
463 if ( XGetPixel( bmpImage, x, h ) != colors[*bits] )
464 *bits = X11DRV_DIB_MapColor( colors, nColors,
465 XGetPixel( bmpImage, x, h ) );
467 bits = (srcbits += linebytes) + left;
472 /***********************************************************************
473 * X11DRV_DIB_SetImageBits_RLE8
475 * SetDIBits for an 8-bit deep compressed DIB.
477 * This function rewritten 941113 by James Youngman. WINE blew out when I
478 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
480 * This was because the algorithm assumed that all RLE8 bitmaps end with the
481 * 'End of bitmap' escape code. This code is very much laxer in what it
482 * allows to end the expansion. Possibly too lax. See the note by
483 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
484 * bitmap should end with RleEnd, but on the other hand, software exists
485 * that produces ones that don't and Windows 3.1 doesn't complain a bit
488 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
489 * James A. Youngman <mbcstjy@afs.man.ac.uk>
493 enum Rle8_EscapeCodes
496 * Apologies for polluting your file's namespace...
498 RleEol = 0, /* End of line */
499 RleEnd = 1, /* End of bitmap */
500 RleDelta = 2 /* Delta */
503 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
504 DWORD width, DWORD dstwidth,
505 int left, int *colors,
508 int x; /* X-positon on each line. Increases. */
509 int line; /* Line #. Starts at lines-1, decreases */
510 const BYTE *pIn = bits; /* Pointer to current position in bits */
511 BYTE length; /* The length pf a run */
512 BYTE color_index; /* index into colors[] as read from bits */
513 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
514 int color; /* value of colour[color_index] */
516 if (lines == 0) /* Let's hope this doesn't happen. */
519 dstwidth += left; /* FIXME: avoid putting x<left pixels */
522 * Note that the bitmap data is stored by Windows starting at the
523 * bottom line of the bitmap and going upwards. Within each line,
524 * the data is stored left-to-right. That's the reason why line
525 * goes from lines-1 to 0. [JAY]
535 * If the length byte is not zero (which is the escape value),
536 * We have a run of length pixels all the same colour. The colour
537 * index is stored next.
539 * If the length byte is zero, we need to read the next byte to
540 * know what to do. [JAY]
545 * [Run-Length] Encoded mode
547 color_index = (*pIn++); /* Get the colour index. */
548 color = colors[color_index];
551 XPutPixel(bmpImage, x++, line, color);
556 * Escape codes (may be an absolute sequence though)
558 escape_code = (*pIn++);
561 case RleEol: /* =0, end of line */
568 case RleEnd: /* =1, end of bitmap */
571 * Not all RLE8 bitmaps end with this
572 * code. For example, Paint Shop Pro
573 * produces some that don't. That's (I think)
574 * what caused the previous implementation to
577 line=-1; /* Cause exit from do loop. */
581 case RleDelta: /* =2, a delta */
584 * Note that deltaing to line 0
585 * will cause an exit from the loop,
586 * which may not be what is intended.
587 * The fact that there is a delta in the bits
588 * almost certainly implies that there is data
589 * to follow. You may feel that we should
590 * jump to the top of the loop to avoid exiting
593 * TODO: Decide what to do here in that case. [JAY]
599 TRACE(bitmap, "Delta to last line of bitmap "
600 "(wrongly?) causes loop exit\n");
605 default: /* >2, switch to absolute mode */
610 length = escape_code;
613 color_index = (*pIn++);
614 XPutPixel(bmpImage, x++, line,
615 colors[color_index]);
619 * If you think for a moment you'll realise that the
620 * only time we could ever possibly read an odd
621 * number of bytes is when there is a 0x00 (escape),
622 * a value >0x02 (absolute mode) and then an odd-
623 * length run. Therefore this is the only place we
624 * need to worry about it. Everywhere else the
625 * bytes are always read in pairs. [JAY]
628 pIn++; /* Throw away the pad byte. */
631 } /* switch (escape_code) : Escape sequence */
632 } /* process either an encoded sequence or an escape sequence */
634 /* We expect to come here more than once per line. */
635 } while (line >= 0); /* Do this until the bitmap is filled */
638 * Everybody comes here at the end.
639 * Check how we exited the loop and print a message if it's a bit odd.
642 if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) )
644 TRACE(bitmap, "End-of-bitmap "
645 "without (strictly) proper escape code. Last two "
646 "bytes were: %02X %02X.\n",
653 /***********************************************************************
654 * X11DRV_DIB_SetImageBits_16
656 * SetDIBits for a 16-bit deep DIB.
658 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
659 DWORD srcwidth, DWORD dstwidth, int left,
660 DC *dc, XImage *bmpImage )
668 /* align to 32 bit */
669 DWORD linebytes = (srcwidth * 2 + 3) & ~3;
673 ptr = (LPWORD) srcbits + left;
675 for (h = lines - 1; h >= 0; h--) {
676 for (x = left; x < dstwidth; x++, ptr++) {
678 r = (BYTE) ((val & 0x7c00) >> 7);
679 g = (BYTE) ((val & 0x03e0) >> 2);
680 b = (BYTE) ((val & 0x001f) << 3);
681 XPutPixel( bmpImage, x, h,
682 COLOR_ToPhysical(dc, RGB(r,g,b)) );
684 ptr = (LPWORD) (srcbits += linebytes) + left;
688 for (h = 0; h < lines; h++) {
689 for (x = left; x < dstwidth; x++, ptr++) {
691 r = (BYTE) ((val & 0x7c00) >> 7);
692 g = (BYTE) ((val & 0x03e0) >> 2);
693 b = (BYTE) ((val & 0x001f) << 3);
694 XPutPixel( bmpImage, x, h,
695 COLOR_ToPhysical(dc, RGB(r,g,b)) );
697 ptr = (LPWORD) (srcbits += linebytes) + left;
703 /***********************************************************************
704 * X11DRV_DIB_GetImageBits_16
706 * GetDIBits for an 16-bit deep DIB.
708 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *srcbits,
709 DWORD srcwidth, DWORD dstwidth, int left,
717 /* align to 32 bit */
718 DWORD linebytes = (srcwidth * 2 + 3) & ~3;
722 ptr = (LPWORD) srcbits + left;
724 for (h = lines - 1; h >= 0; h--)
726 for (x = left; x < dstwidth; x++, ptr++)
728 COLORREF pixel = COLOR_ToLogical( XGetPixel( bmpImage, x, h ) );
729 r = (BYTE) GetRValue(pixel);
730 g = (BYTE) GetGValue(pixel);
731 b = (BYTE) GetBValue(pixel);
732 *ptr = ( ((r << 7) & 0x7c00) | ((g << 2) & 0x03e0) | ((b >> 3) & 0x001f) );
734 ptr = (LPWORD) (srcbits += linebytes) + left;
738 for (h = 0; h < lines; h++)
740 for (x = left; x < dstwidth; x++, ptr++)
742 COLORREF pixel = COLOR_ToLogical( XGetPixel( bmpImage, x, h ) );
743 r = (BYTE) GetRValue(pixel);
744 g = (BYTE) GetGValue(pixel);
745 b = (BYTE) GetBValue(pixel);
746 *ptr = ( ((r << 7) & 0x7c00) | ((g << 2) & 0x03e0) | ((b >> 3) & 0x001f) );
749 ptr = (LPWORD) (srcbits += linebytes) + left;
756 /***********************************************************************
757 * X11DRV_DIB_SetImageBits_24
759 * SetDIBits for a 24-bit deep DIB.
761 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
762 DWORD srcwidth, DWORD dstwidth, int left,
763 DC *dc, XImage *bmpImage )
766 const BYTE *bits = srcbits + left * 3;
769 /* align to 32 bit */
770 DWORD linebytes = (srcwidth * 3 + 3) & ~3;
774 /* "bits" order is reversed for some reason */
777 for (h = lines - 1; h >= 0; h--) {
778 for (x = left; x < dstwidth; x++, bits += 3) {
779 XPutPixel( bmpImage, x, h,
780 COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
782 bits = (srcbits += linebytes) + left * 3;
786 for (h = 0; h < lines; h++) {
787 for (x = left; x < dstwidth; x++, bits += 3) {
788 XPutPixel( bmpImage, x, h,
789 COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
791 bits = (srcbits += linebytes) + left * 3;
797 /***********************************************************************
798 * X11DRV_DIB_GetImageBits_24
800 * GetDIBits for an 24-bit deep DIB.
802 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *srcbits,
803 DWORD srcwidth, DWORD dstwidth, int left,
808 BYTE *bits = srcbits + (left * 3);
810 /* align to 32 bit */
811 DWORD linebytes = (srcwidth * 3 + 3) & ~3;
816 for (h = lines - 1; h >= 0; h--)
818 for (x = left; x < dstwidth; x++, bits += 3)
820 COLORREF pixel = COLOR_ToLogical( XGetPixel( bmpImage, x, h ) );
821 bits[0] = GetRValue(pixel);
822 bits[1] = GetGValue(pixel);
823 bits[2] = GetBValue(pixel);
825 bits = (srcbits += linebytes) + (left * 3);
829 for (h = 0; h < lines; h++)
831 for (x = left; x < dstwidth; x++, bits += 3)
833 COLORREF pixel = COLOR_ToLogical( XGetPixel( bmpImage, x, h ) );
834 bits[0] = GetRValue(pixel);
835 bits[1] = GetGValue(pixel);
836 bits[2] = GetBValue(pixel);
839 bits = (srcbits += linebytes) + (left * 3);
845 /***********************************************************************
846 * X11DRV_DIB_SetImageBits_32
848 * SetDIBits for a 32-bit deep DIB.
850 static void X11DRV_DIB_SetImageBits_32( int lines, const BYTE *srcbits,
851 DWORD srcwidth, DWORD dstwidth, int left,
852 DC *dc, XImage *bmpImage )
855 const BYTE *bits = srcbits + left * 4;
858 DWORD linebytes = (srcwidth * 4);
863 for (h = lines - 1; h >= 0; h--) {
864 for (x = left; x < dstwidth; x++, bits += 4) {
865 XPutPixel( bmpImage, x, h,
866 COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
868 bits = (srcbits += linebytes) + left * 4;
872 for (h = 0; h < lines; h++) {
873 for (x = left; x < dstwidth; x++, bits += 4) {
874 XPutPixel( bmpImage, x, h,
875 COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
877 bits = (srcbits += linebytes) + left * 4;
883 /***********************************************************************
884 * X11DRV_DIB_GetImageBits_32
886 * GetDIBits for an 32-bit deep DIB.
888 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *srcbits,
889 DWORD srcwidth, DWORD dstwidth, int left,
894 BYTE *bits = srcbits + (left * 4);
896 /* align to 32 bit */
897 DWORD linebytes = (srcwidth * 4);
902 for (h = lines - 1; h >= 0; h--)
904 for (x = left; x < dstwidth; x++, bits += 4)
906 COLORREF pixel = COLOR_ToLogical( XGetPixel( bmpImage, x, h ) );
907 bits[0] = GetRValue(pixel);
908 bits[1] = GetGValue(pixel);
909 bits[2] = GetBValue(pixel);
911 bits = (srcbits += linebytes) + (left * 4);
915 for (h = 0; h < lines; h++)
917 for (x = left; x < dstwidth; x++, bits += 4)
919 COLORREF pixel = COLOR_ToLogical( XGetPixel( bmpImage, x, h ) );
920 bits[0] = GetRValue(pixel);
921 bits[1] = GetGValue(pixel);
922 bits[2] = GetBValue(pixel);
925 bits = (srcbits += linebytes) + (left * 4);
931 /***********************************************************************
932 * X11DRV_DIB_SetImageBits
934 * Transfer the bits to an X image.
935 * Helper function for SetDIBits() and SetDIBitsToDevice().
936 * The Xlib critical section must be entered before calling this function.
938 int X11DRV_DIB_SetImageBits( const DIB_SETIMAGEBITS_DESCR *descr )
940 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
943 if ( descr->dc && descr->dc->w.flags & DC_DIRTY )
944 CLIPPING_UpdateGCRegion( descr->dc );
947 bmpImage = descr->image;
949 XCREATEIMAGE( bmpImage, descr->infoWidth, lines, descr->depth );
951 /* Transfer the pixels */
952 switch(descr->infoBpp)
955 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
956 descr->width, descr->xSrc, descr->colorMap,
960 if (descr->compression)
961 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
962 descr->infoWidth, descr->width,
963 descr->xSrc, descr->colorMap,
966 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
967 descr->infoWidth, descr->width,
968 descr->xSrc, descr->colorMap,
972 if (descr->compression)
973 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
974 descr->infoWidth, descr->width,
976 descr->colorMap, bmpImage );
978 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
979 descr->infoWidth, descr->width,
980 descr->xSrc, descr->colorMap,
985 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
986 descr->infoWidth, descr->width,
987 descr->xSrc, descr->dc, bmpImage);
990 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
991 descr->infoWidth, descr->width,
992 descr->xSrc, descr->dc, bmpImage );
995 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
996 descr->infoWidth, descr->width,
997 descr->xSrc, descr->dc, bmpImage);
1000 WARN(bitmap, "(%d): Invalid depth\n", descr->infoBpp );
1004 XPutImage( display, descr->drawable, descr->gc, bmpImage,
1005 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
1006 descr->width, descr->height );
1008 if (!descr->image) XDestroyImage( bmpImage );
1012 /***********************************************************************
1013 * X11DRV_DIB_GetImageBits
1015 * Transfer the bits from an X image.
1016 * The Xlib critical section must be entered before calling this function.
1018 int X11DRV_DIB_GetImageBits( const DIB_SETIMAGEBITS_DESCR *descr )
1020 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
1024 bmpImage = descr->image;
1026 XCREATEIMAGE( bmpImage, descr->infoWidth, lines, descr->depth );
1028 XGetSubImage( display, descr->drawable, descr->xDest, descr->yDest,
1029 descr->width, descr->height, AllPlanes, ZPixmap,
1030 bmpImage, descr->xSrc, descr->ySrc );
1032 /* Transfer the pixels */
1033 switch(descr->infoBpp)
1036 FIXME(bitmap, "Depth 1 not yet supported!\n");
1040 if (descr->compression)
1041 FIXME(bitmap, "Compression not yet supported!\n");
1043 X11DRV_DIB_GetImageBits_4( descr->lines,
1044 (LPVOID)descr->bits, descr->infoWidth,
1045 descr->width, descr->xSrc,
1046 descr->colorMap, descr->nColorMap,
1051 if (descr->compression)
1052 FIXME(bitmap, "Compression not yet supported!\n");
1054 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
1055 descr->infoWidth, descr->width,
1056 descr->xSrc, descr->colorMap,
1057 descr->nColorMap, bmpImage );
1062 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
1064 descr->width, descr->xSrc, bmpImage );
1068 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
1070 descr->width, descr->xSrc, bmpImage );
1074 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
1076 descr->width, descr->xSrc, bmpImage );
1080 WARN(bitmap, "(%d): Invalid depth\n", descr->infoBpp );
1084 if (!descr->image) XDestroyImage( bmpImage );
1088 /*************************************************************************
1089 * X11DRV_SetDIBitsToDevice
1092 INT32 X11DRV_SetDIBitsToDevice( DC *dc, INT32 xDest, INT32 yDest, DWORD cx,
1093 DWORD cy, INT32 xSrc, INT32 ySrc,
1094 UINT32 startscan, UINT32 lines, LPCVOID bits,
1095 const BITMAPINFO *info, UINT32 coloruse )
1097 DIB_SETIMAGEBITS_DESCR descr;
1098 DWORD width, oldcy = cy;
1100 int height, tmpheight;
1103 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
1104 &descr.infoBpp, &descr.compression ) == -1)
1107 if (height < 0) height = -height;
1108 if (!lines || (startscan >= height)) return 0;
1109 if (startscan + lines > height) lines = height - startscan;
1110 if (ySrc < startscan) ySrc = startscan;
1111 else if (ySrc >= startscan + lines) return 0;
1112 if (xSrc >= width) return 0;
1113 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
1114 if (xSrc + cx >= width) cx = width - xSrc;
1115 if (!cx || !cy) return 0;
1117 X11DRV_SetupGCForText( dc ); /* To have the correct colors */
1118 TSXSetFunction(display, dc->u.x.gc, X11DRV_XROPfunction[dc->w.ROPmode-1]);
1120 if (descr.infoBpp <= 8)
1122 descr.colorMap = X11DRV_DIB_BuildColorMap( dc, coloruse,
1124 info, &descr.nColorMap );
1125 if (!descr.colorMap)
1132 descr.lines = tmpheight >= 0 ? lines : -lines;
1133 descr.infoWidth = width;
1134 descr.depth = dc->w.bitsPerPixel;
1135 descr.drawable = dc->u.x.drawable;
1136 descr.gc = dc->u.x.gc;
1138 descr.ySrc = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy)
1140 descr.xDest = dc->w.DCOrgX + XLPTODP( dc, xDest );
1141 descr.yDest = dc->w.DCOrgY + YLPTODP( dc, yDest ) +
1142 (tmpheight >= 0 ? oldcy-cy : 0);
1146 EnterCriticalSection( &X11DRV_CritSection );
1147 result = CALL_LARGE_STACK( X11DRV_DIB_SetImageBits, &descr );
1148 LeaveCriticalSection( &X11DRV_CritSection );
1150 HeapFree(GetProcessHeap(), 0, descr.colorMap);