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)
142 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
144 if (depth == 1) /* Monochrome */
145 for (i = start; i < end; i++, rgb++)
146 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
147 rgb->rgbBlue > 255*3/2);
149 for (i = start; i < end; i++, rgb++)
150 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbRed,
156 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
158 if (depth == 1) /* Monochrome */
159 for (i = start; i < end; i++, rgb++)
160 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
161 rgb->rgbtBlue > 255*3/2);
163 for (i = start; i < end; i++, rgb++)
164 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbtRed,
169 else /* DIB_PAL_COLORS */
172 WORD * index = (WORD *)colorPtr;
174 for (i = start; i < end; i++, index++)
175 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(*index) );
177 for (i = start; i < end; i++)
178 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(i) );
185 /***********************************************************************
186 * X11DRV_DIB_BuildColorMap
188 * Build the color map from the bitmap palette. Should not be called
189 * for a >8-bit deep bitmap.
191 int *X11DRV_DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth,
192 const BITMAPINFO *info, int *nColors )
196 const void *colorPtr;
199 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
201 colors = info->bmiHeader.biClrUsed;
202 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
203 colorPtr = info->bmiColors;
205 else /* assume BITMAPCOREINFO */
207 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
208 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
213 ERR("called with >256 colors!\n");
217 /* just so CopyDIBSection doesn't have to create an identity palette */
218 if (coloruse == (WORD)-1) colorPtr = NULL;
220 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
221 colors * sizeof(int) )))
225 return X11DRV_DIB_GenColorMap( dc, colorMapping, coloruse, depth,
226 isInfo, colorPtr, 0, colors);
230 /***********************************************************************
231 * X11DRV_DIB_MapColor
233 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
237 if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
240 for (color = 0; color < nPhysMap; color++)
241 if (physMap[color] == phys)
244 WARN("Strange color %08x\n", phys);
249 /*********************************************************************
250 * X11DRV_DIB_GetNearestIndex
252 * Helper for X11DRV_DIB_GetDIBits.
253 * Returns the nearest colour table index for a given RGB.
254 * Nearest is defined by minimizing the sum of the squares.
256 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
258 INT i, best = -1, diff, bestdiff = -1;
261 for(color = colormap, i = 0; i < numColors; color++, i++) {
262 diff = (r - color->rgbRed) * (r - color->rgbRed) +
263 (g - color->rgbGreen) * (g - color->rgbGreen) +
264 (b - color->rgbBlue) * (b - color->rgbBlue);
267 if(best == -1 || diff < bestdiff) {
275 /***********************************************************************
276 * X11DRV_DIB_SetImageBits_1_Line
278 * Handles a single line of 1 bit data.
280 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth, int left, int *colors,
281 XImage *bmpImage, int h, const BYTE *bits)
286 if((extra = (left & 7)) != 0) {
293 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
294 for (i = dstwidth/8, x = left; i > 0; i--)
297 XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
298 XPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] );
299 XPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] );
300 XPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] );
301 XPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] );
302 XPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] );
303 XPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] );
304 XPutPixel( bmpImage, x++, h, colors[pix & 1] );
309 case 7: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
310 case 6: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
311 case 5: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
312 case 4: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
313 case 3: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
314 case 2: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
315 case 1: XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
319 /***********************************************************************
320 * X11DRV_DIB_SetImageBits_1
322 * SetDIBits for a 1-bit deep DIB.
324 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
325 DWORD srcwidth, DWORD dstwidth, int left,
326 int *colors, XImage *bmpImage, DWORD linebytes)
331 for (h = lines-1; h >=0; h--) {
332 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
334 srcbits += linebytes;
338 for (h = 0; h < lines; h++) {
339 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
341 srcbits += linebytes;
346 /***********************************************************************
347 * X11DRV_DIB_GetImageBits_1
349 * GetDIBits for a 1-bit deep DIB.
351 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
352 DWORD dstwidth, DWORD srcwidth,
353 RGBQUAD *colors, PALETTEENTRY *srccolors,
354 XImage *bmpImage, DWORD linebytes )
362 dstbits = dstbits + linebytes * (lines - 1);
363 linebytes = -linebytes;
368 switch(bmpImage->depth) {
371 /* ==== monochrome bitmap to monochrome dib ==== */
373 /* ==== 4 colormap bitmap to monochrome dib ==== */
374 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
378 for (h = lines - 1; h >= 0; h--) {
379 for (x = 0; x < dstwidth; x++) {
380 val = srccolors[XGetPixel(bmpImage, x, h)];
381 if (!(x&7)) *bits = 0;
382 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2,
385 val.peBlue) << (7 - (x & 7)));
386 if ((x&7)==7) bits++;
388 bits = (dstbits += linebytes);
391 else goto notsupported;
396 /* ==== 8 colormap bitmap to monochrome dib ==== */
397 if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
402 for( h = lines- 1; h >= 0; h-- ) {
403 srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
404 for( x = 0; x < dstwidth; x++ ) {
405 if (!(x&7)) *bits = 0;
406 val = srccolors[(int)*srcpixel++];
407 *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 2,
410 val.peBlue) << (7-(x&7)) );
411 if ((x&7)==7) bits++;
413 bits = (dstbits += linebytes);
416 else goto notsupported;
425 /* ==== 555 BGR bitmap to monochrome dib ==== */
426 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
428 for( h = lines - 1; h >= 0; h--) {
429 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
430 for( x = 0; x < dstwidth; x++) {
431 if (!(x&7)) *bits = 0;
433 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
434 ((val >> 7) & 0xf8) |
436 ((val >> 2) & 0xf8) |
438 ((val << 3) & 0xf8) |
439 ((val >> 2) & 0x7) ) << (7-(x&7)) );
440 if ((x&7)==7) bits++;
442 bits = (dstbits += linebytes);
445 /* ==== 555 RGB bitmap to monochrome dib ==== */
446 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
448 for( h = lines - 1; h >= 0; h--)
450 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
451 for( x = 0; x < dstwidth; x++) {
452 if (!(x&1)) *bits = 0;
454 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
455 ((val << 3) & 0xf8) |
457 ((val >> 2) & 0xf8) |
459 ((val >> 7) & 0xf8) |
460 ((val >> 12) & 0x7) ) << (7-(x&7)) );
461 if ((x&7)==7) bits++;
463 bits = (dstbits += linebytes);
466 else goto notsupported;
475 /* ==== 565 BGR bitmap to monochrome dib ==== */
476 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
478 for( h = lines - 1; h >= 0; h--)
480 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
481 for( x = 0; x < dstwidth; x++) {
482 if (!(x&7)) *bits = 0;
484 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
485 ((val >> 8) & 0xf8) |
487 ((val >> 3) & 0xfc) |
489 ((val << 3) & 0xf8) |
490 ((val >> 2) & 0x7) ) << (7-(x&7)) );
491 if ((x&7)==7) bits++;
493 bits = (dstbits += linebytes);
496 /* ==== 565 RGB bitmap to monochrome dib ==== */
497 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
499 for( h = lines - 1; h >= 0; h--)
501 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
502 for( x = 0; x < dstwidth; x++) {
503 if (!(x&7)) *bits = 0;
505 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
506 ((val << 3) & 0xf8) |
508 ((val >> 3) & 0xfc) |
510 ((val >> 8) & 0xf8) |
511 ((val >> 13) & 0x7) ) << (7-(x&7)) );
512 if ((x&7)==7) bits++;
514 bits = (dstbits += linebytes);
517 else goto notsupported;
526 /* ==== 24/32 BGR bitmap to monochrome dib ==== */
527 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
529 for (h = lines - 1; h >= 0; h--)
531 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
532 for (x = 0; x < dstwidth; x++, srcpixel+=4) {
533 if (!(x&7)) *bits = 0;
534 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[2] , srcpixel[1], srcpixel[0]) << (7-(x&7)) );
535 if ((x&7)==7) bits++;
537 bits = (dstbits += linebytes);
540 /* ==== 24/32 RGB bitmap to monochrome dib ==== */
541 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
543 for (h = lines - 1; h >= 0; h--)
545 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
546 for (x = 0; x < dstwidth; x++, srcpixel+=4) {
547 if (!(x & 7)) *bits = 0;
548 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[0] , srcpixel[1], srcpixel[2]) << (7-(x&7)) );
549 if ((x & 7) == 7) bits++;
551 bits = (dstbits += linebytes);
554 else goto notsupported;
558 default: /* ? bit bmp -> monochrome DIB */
561 unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
563 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
564 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
565 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
567 for( h = lines - 1; h >= 0; h-- ) {
568 for( x = 0; x < dstwidth; x++ ) {
569 if (!(x&7)) *bits = 0;
570 *bits |= (XGetPixel( bmpImage, x, h) >= white)
572 if ((x&7)==7) bits++;
574 bits = (dstbits += linebytes);
581 /***********************************************************************
582 * X11DRV_DIB_SetImageBits_4
584 * SetDIBits for a 4-bit deep DIB.
586 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
587 DWORD srcwidth, DWORD dstwidth, int left,
588 int *colors, XImage *bmpImage, DWORD linebytes)
592 const BYTE *bits = srcbits + (left >> 1);
600 for (h = lines-1; h >= 0; h--) {
601 for (i = dstwidth/2, x = left; i > 0; i--) {
603 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
604 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
606 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
607 srcbits += linebytes;
608 bits = srcbits + (left >> 1);
612 for (h = 0; h < lines; h++) {
613 for (i = dstwidth/2, x = left; i > 0; i--) {
615 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
616 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
618 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
619 srcbits += linebytes;
620 bits = srcbits + (left >> 1);
627 /***********************************************************************
628 * X11DRV_DIB_GetImageBits_4
630 * GetDIBits for a 4-bit deep DIB.
632 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
633 DWORD srcwidth, DWORD dstwidth,
634 RGBQUAD *colors, PALETTEENTRY *srccolors,
635 XImage *bmpImage, DWORD linebytes )
645 dstbits = dstbits + ( linebytes * (lines-1) );
646 linebytes = -linebytes;
651 switch(bmpImage->depth) {
654 /* ==== monochrome bitmap to 4 colormap dib ==== */
656 /* ==== 4 colormap bitmap to 4 colormap dib ==== */
657 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
661 for (h = lines-1; h >= 0; h--) {
662 for (x = 0; x < dstwidth; x++) {
663 if (!(x&1)) *bits = 0;
664 val = srccolors[XGetPixel(bmpImage, x, h)];
665 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 16,
668 val.peBlue) << (4-((x&1)<<2)));
669 if ((x&1)==1) bits++;
671 bits = (dstbits += linebytes);
674 else goto notsupported;
679 /* ==== 8 colormap bitmap to 4 colormap dib ==== */
680 if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
684 for( h = lines - 1; h >= 0; h-- ) {
685 srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
686 for( x = 0; x < dstwidth; x++ ) {
687 if (!(x&1)) *bits = 0;
688 val = srccolors[(int)*srcpixel++];
689 *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 16,
692 val.peBlue) << (4*(1-(x&1))) );
693 if ((x&1)==1) bits++;
695 bits = (dstbits += linebytes);
698 else goto notsupported;
707 /* ==== 555 BGR bitmap to 4 colormap dib ==== */
708 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
710 for( h = lines - 1; h >= 0; h--) {
711 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
712 for( x = 0; x < dstwidth; x++) {
713 if (!(x&1)) *bits = 0;
715 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
716 ((val >> 7) & 0xf8) |
718 ((val >> 2) & 0xf8) |
720 ((val << 3) & 0xf8) |
721 ((val >> 2) & 0x7) ) << ((1-(x&1))<<2) );
722 if ((x&1)==1) bits++;
724 bits = (dstbits += linebytes);
727 /* ==== 555 RGB bitmap to 4 colormap dib ==== */
728 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
730 for( h = lines - 1; h >= 0; h--)
732 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
733 for( x = 0; x < dstwidth; x++) {
734 if (!(x&1)) *bits = 0;
736 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
737 ((val << 3) & 0xf8) |
739 ((val >> 2) & 0xfc) |
741 ((val >> 7) & 0xf8) |
742 ((val >> 12) & 0x7) ) << ((1-(x&1))<<2) );
743 if ((x&1)==1) bits++;
745 bits = (dstbits += linebytes);
748 else goto notsupported;
757 /* ==== 565 BGR bitmap to 4 colormap dib ==== */
758 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
760 for( h = lines - 1; h >= 0; h--)
762 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
763 for( x = 0; x < dstwidth; x++) {
764 if (!(x&1)) *bits = 0;
766 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
767 ((val >> 8) & 0xf8) |
769 ((val >> 3) & 0xfc) |
771 ((val << 3) & 0xf8) |
772 ((val >> 2) & 0x7) ) << ((1-(x&1))<<2) );
773 if ((x&1)==1) bits++;
775 bits = (dstbits += linebytes);
778 /* ==== 565 RGB bitmap to 4 colormap dib ==== */
779 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
781 for( h = lines - 1; h >= 0; h--)
783 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
784 for( x = 0; x < dstwidth; x++) {
785 if (!(x&1)) *bits = 0;
787 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
788 ((val << 3) & 0xf8) |
790 ((val >> 3) & 0xfc) |
792 ((val >> 8) & 0xf8) |
793 ((val >> 13) & 0x7) ) << ((1-(x&1))<<2) );
794 if ((x&1)==1) bits++;
796 bits = (dstbits += linebytes);
799 else goto notsupported;
808 /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
809 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
811 for (h = lines - 1; h >= 0; h--)
813 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
814 for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
815 *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[2] , srcpixel[1], srcpixel[0]) << 4) |
816 X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[6] , srcpixel[5], srcpixel[4]);
817 bits = (dstbits += linebytes);
820 /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
821 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
823 for (h = lines - 1; h >= 0; h--)
825 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
826 for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
827 *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[0] , srcpixel[1], srcpixel[2]) << 4) |
828 X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[4] , srcpixel[5], srcpixel[6]);
829 bits = (dstbits += linebytes);
832 else goto notsupported;
836 default: /* ? bit bmp -> 4 bit DIB */
838 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
839 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
840 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
841 for (h = lines-1; h >= 0; h--) {
842 for (x = 0; x < dstwidth-1; x += 2)
844 *bits++ = (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x, h ), 0) << 4)
845 | (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x+1, h ), 0) & 0x0f);
848 *bits = (X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel( bmpImage, x, h ), 0) << 4);
849 bits = (dstbits += linebytes);
855 /***********************************************************************
856 * X11DRV_DIB_SetImageBits_RLE4
858 * SetDIBits for a 4-bit deep compressed DIB.
860 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
861 DWORD width, DWORD dstwidth,
862 int left, int *colors,
865 int x = 0, y = lines - 1, c, length;
866 const BYTE *begin = bits;
871 if (length) { /* encoded */
874 if (x >= width) break;
875 XPutPixel(bmpImage, x++, y, colors[c >> 4]);
876 if (!length--) break;
877 if (x >= width) break;
878 XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
897 default: /* absolute */
900 if (x < width) XPutPixel(bmpImage, x++, y, colors[c >> 4]);
901 if (!length--) break;
902 if (x < width) XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
904 if ((bits - begin) & 1)
913 /***********************************************************************
914 * X11DRV_DIB_SetImageBits_8
916 * SetDIBits for an 8-bit deep DIB.
918 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
919 DWORD srcwidth, DWORD dstwidth, int left,
920 const int *colors, XImage *bmpImage,
932 srcbits = srcbits + ( linebytes * (lines-1) );
933 linebytes = -linebytes;
936 bits = srcbits + left;
938 switch (bmpImage->depth) {
941 #if defined(__i386__) && defined(__GNUC__)
942 /* Some X servers might have 32 bit/ 16bit deep pixel */
943 if (lines && (dstwidth!=left) && (bmpImage->bits_per_pixel == 16))
945 for (h = lines ; h--; ) {
946 int _cl1,_cl2; /* temp outputs for asm below */
947 /* Borrowed from DirectDraw */
948 __asm__ __volatile__(
953 " movw (%%edx,%%eax,4),%%ax\n"
957 :"=S" (bits), "=D" (_cl1), "=c" (_cl2)
959 "D" (bmpImage->data+h*bmpImage->bytes_per_line+left*2),
962 :"eax", "cc", "memory"
964 bits = (srcbits += linebytes) + left;
971 #if defined(__i386__) && defined(__GNUC__)
972 if (lines && (dstwidth!=left) && (bmpImage->bits_per_pixel == 32))
974 for (h = lines ; h--; ) {
975 int _cl1,_cl2; /* temp outputs for asm below */
976 /* Borrowed from DirectDraw */
977 __asm__ __volatile__(
982 " movl (%%edx,%%eax,4),%%eax\n"
986 :"=S" (bits), "=D" (_cl1), "=c" (_cl2)
988 "D" (bmpImage->data+h*bmpImage->bytes_per_line+left*4),
991 :"eax", "cc", "memory"
993 bits = (srcbits += linebytes) + left;
1000 break; /* use slow generic case below */
1003 for (h = lines - 1; h >= 0; h--) {
1004 for (x = left; x < dstwidth; x++, bits++) {
1005 color = colors[*bits];
1006 XPutPixel( bmpImage, x, h, colors[*bits] );
1008 bits = (srcbits += linebytes) + left;
1012 /***********************************************************************
1013 * X11DRV_DIB_GetImageBits_8
1015 * GetDIBits for an 8-bit deep DIB.
1017 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
1018 DWORD srcwidth, DWORD dstwidth,
1019 RGBQUAD *colors, PALETTEENTRY *srccolors,
1020 XImage *bmpImage, DWORD linebytes )
1029 dstbits = dstbits + ( linebytes * (lines-1) );
1030 linebytes = -linebytes;
1037 This condition is true when GetImageBits has been called by UpdateDIBSection.
1038 For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
1039 for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
1041 if (!srccolors) goto updatesection;
1043 switch(bmpImage->depth) {
1046 /* ==== monochrome bitmap to 8 colormap dib ==== */
1048 /* ==== 4 colormap bitmap to 8 colormap dib ==== */
1049 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1053 for (h = lines - 1; h >= 0; h--) {
1054 for (x = 0; x < dstwidth; x++) {
1055 val = srccolors[XGetPixel(bmpImage, x, h)];
1056 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed,
1057 val.peGreen, val.peBlue);
1059 bits = (dstbits += linebytes);
1062 else goto notsupported;
1067 /* ==== 8 colormap bitmap to 8 colormap dib ==== */
1068 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1073 for (h = lines - 1; h >= 0; h--) {
1074 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1075 for (x = 0; x < dstwidth; x++) {
1076 val = srccolors[(int)*srcpixel++];
1077 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed,
1078 val.peGreen, val.peBlue);
1080 bits = (dstbits += linebytes);
1083 else goto notsupported;
1092 /* ==== 555 BGR bitmap to 8 colormap dib ==== */
1093 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
1095 for( h = lines - 1; h >= 0; h--)
1097 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1098 for( x = 0; x < dstwidth; x++ )
1101 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1102 ((val >> 7) & 0xf8) |
1103 ((val >> 12) & 0x7),
1104 ((val >> 2) & 0xf8) |
1106 ((val << 3) & 0xf8) |
1107 ((val >> 2) & 0x7) );
1109 bits = (dstbits += linebytes);
1112 /* ==== 555 RGB bitmap to 8 colormap dib ==== */
1113 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
1115 for( h = lines - 1; h >= 0; h--)
1117 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1118 for( x = 0; x < dstwidth; x++ )
1121 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1122 ((val << 3) & 0xf8) |
1124 ((val >> 2) & 0xf8) |
1126 ((val >> 7) & 0xf8) |
1127 ((val >> 12) & 0x7) );
1129 bits = (dstbits += linebytes);
1132 else goto notsupported;
1141 /* ==== 565 BGR bitmap to 8 colormap dib ==== */
1142 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
1144 for( h = lines - 1; h >= 0; h--)
1146 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1147 for( x = 0; x < dstwidth; x++ )
1150 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1151 ((val >> 8) & 0xf8) |
1152 ((val >> 13) & 0x7),
1153 ((val >> 3) & 0xfc) |
1155 ((val << 3) & 0xf8) |
1156 ((val >> 2) & 0x7) );
1158 bits = (dstbits += linebytes);
1161 /* ==== 565 RGB bitmap to 8 colormap dib ==== */
1162 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
1164 for( h = lines - 1; h >= 0; h--)
1166 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1167 for( x = 0; x < dstwidth; x++ )
1170 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1171 ((val << 3) & 0xf8) |
1173 ((val >> 3) & 0x00fc) |
1175 ((val >> 8) & 0x00f8) |
1176 ((val >> 13) & 0x7) );
1178 bits = (dstbits += linebytes);
1181 else goto notsupported;
1190 /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
1191 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1193 for (h = lines - 1; h >= 0; h--)
1195 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1196 for (x = 0; x < dstwidth; x++, srcpixel+=4)
1197 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256,
1198 srcpixel[2] , srcpixel[1], *srcpixel);
1199 bits = (dstbits += linebytes);
1202 /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
1203 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1205 for (h = lines - 1; h >= 0; h--)
1207 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1208 for (x = 0; x < dstwidth; x++, srcpixel+=4)
1209 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256,
1210 *srcpixel, srcpixel[1], srcpixel[2]);
1211 bits = (dstbits += linebytes);
1215 else goto notsupported;
1219 default: /* ? bit bmp -> 8 bit DIB */
1221 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
1222 bmpImage->depth, (int)bmpImage->red_mask,
1223 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
1225 for (h = lines - 1; h >= 0; h--) {
1226 for (x = 0; x < dstwidth; x++, bits++) {
1227 *bits = X11DRV_DIB_MapColor((int *)colors, 256,
1228 XGetPixel( bmpImage, x, h ), *bits);
1230 bits = (dstbits += linebytes);
1236 /***********************************************************************
1237 * X11DRV_DIB_SetImageBits_RLE8
1239 * SetDIBits for an 8-bit deep compressed DIB.
1241 * This function rewritten 941113 by James Youngman. WINE blew out when I
1242 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1244 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1245 * 'End of bitmap' escape code. This code is very much laxer in what it
1246 * allows to end the expansion. Possibly too lax. See the note by
1247 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1248 * bitmap should end with RleEnd, but on the other hand, software exists
1249 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1252 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1253 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1256 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
1257 DWORD width, DWORD dstwidth,
1258 int left, int *colors,
1261 int x; /* X-positon on each line. Increases. */
1262 int y; /* Line #. Starts at lines-1, decreases */
1263 const BYTE *pIn = bits; /* Pointer to current position in bits */
1264 BYTE length; /* The length pf a run */
1265 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
1268 * Note that the bitmap data is stored by Windows starting at the
1269 * bottom line of the bitmap and going upwards. Within each line,
1270 * the data is stored left-to-right. That's the reason why line
1271 * goes from lines-1 to 0. [JAY]
1281 * If the length byte is not zero (which is the escape value),
1282 * We have a run of length pixels all the same colour. The colour
1283 * index is stored next.
1285 * If the length byte is zero, we need to read the next byte to
1286 * know what to do. [JAY]
1291 * [Run-Length] Encoded mode
1293 int color = colors[*pIn++];
1294 while (length-- && x < dstwidth) XPutPixel(bmpImage, x++, y, color);
1299 * Escape codes (may be an absolute sequence though)
1301 escape_code = (*pIn++);
1310 /* Not all RLE8 bitmaps end with this code. For
1311 * example, Paint Shop Pro produces some that don't.
1312 * That's (I think) what caused the previous
1313 * implementation to fail. [JAY]
1322 default: /* switch to absolute mode */
1323 length = escape_code;
1326 int color = colors[*pIn++];
1332 XPutPixel(bmpImage, x++, y, color);
1335 * If you think for a moment you'll realise that the
1336 * only time we could ever possibly read an odd
1337 * number of bytes is when there is a 0x00 (escape),
1338 * a value >0x02 (absolute mode) and then an odd-
1339 * length run. Therefore this is the only place we
1340 * need to worry about it. Everywhere else the
1341 * bytes are always read in pairs. [JAY]
1343 if (escape_code & 1) pIn++; /* Throw away the pad byte. */
1345 } /* switch (escape_code) : Escape sequence */
1351 /***********************************************************************
1352 * X11DRV_DIB_SetImageBits_16
1354 * SetDIBits for a 16-bit deep DIB.
1356 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
1357 DWORD srcwidth, DWORD dstwidth, int left,
1358 DC *dc, DWORD rSrc, DWORD gSrc, DWORD bSrc,
1359 XImage *bmpImage, DWORD linebytes )
1367 srcbits = srcbits + ( linebytes * (lines-1));
1368 linebytes = -linebytes;
1371 switch ( bmpImage->depth )
1374 /* using same format as XImage */
1375 if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
1376 for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
1377 memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
1378 else /* We need to do a conversion from a 565 dib */
1380 LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
1382 int div = dstwidth % 2;
1384 for (h = lines - 1; h >= 0; h--) {
1385 dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1386 for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
1388 *dstpixel++ = ((val >> 1) & 0x7fe07fe0) | (val & 0x001f001f); /* Red & Green & Blue */
1390 if (div != 0) /* Odd width? */
1391 *dstpixel = ((*(WORD *)ptr >> 1) & 0x7fe0) | (*(WORD *)ptr & 0x001f);
1392 ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
1398 /* using same format as XImage */
1399 if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
1400 for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
1401 memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
1402 else /* We need to do a conversion from a 555 dib */
1404 LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
1406 int div = dstwidth % 2;
1408 for (h = lines - 1; h >= 0; h--) {
1409 dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1410 for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
1412 *dstpixel++ = ((val << 1) & 0xffc0ffc0) | ((val >> 4) & 0x00200020) | /* Red & Green */
1413 (val & 0x001f001f); /* Blue */
1415 if (div != 0) /* Odd width? */
1416 *dstpixel = ((*(WORD *)ptr << 1) & 0xffc0) | ((*(WORD *)ptr >> 4) & 0x0020)
1417 | (*(WORD *)ptr & 0x001f);
1418 ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
1427 LPWORD ptr = (LPWORD)srcbits + left;
1430 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1432 if ((rSrc == 0xF800) && (gSrc == 0x07E0) && (bSrc == 0x001F)) {
1433 /* ==== 555 RGB dib to 24/32 RGB bitmap ==== */
1434 for (h = lines - 1; h >= 0; h--) {
1435 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1436 for (x = 0; x < dstwidth; x++) {
1438 *dstpixel++ = ((val << 8) & 0xF80000) | /* Red */
1439 ((val << 5) & 0x00FC00) | /* Green */
1440 ((val << 3) & 0x0000FF); /* Blue */
1442 ptr = (LPWORD)(srcbits += linebytes) + left;
1445 /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
1446 for (h = lines - 1; h >= 0; h--) {
1447 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1448 for (x = 0; x < dstwidth; x++) {
1451 *dstpixel++ = ((val << 9) & 0xf80000) | ((val << 4) & 0x070000) | /* Red */
1452 ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
1453 ((val << 3) & 0x0000f8) | ((val >> 2) & 0x000007); /* Blue */
1455 ptr = (LPWORD)(srcbits += linebytes) + left;
1459 /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
1460 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1462 for (h = lines - 1; h >= 0; h--) {
1463 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1464 for (x = 0; x < dstwidth; x++) {
1467 *dstpixel++ = ((val >> 7) & 0x0000f8) | ((val >> 12) & 0x000007) | /* Red */
1468 ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
1469 ((val << 19) & 0xf80000) | ((val >> 14) & 0x070000); /* Blue */
1471 ptr = (LPWORD)(srcbits += linebytes) + left;
1482 LPWORD ptr = (LPWORD)srcbits + left;
1486 /* Set color scaling values */
1487 if ( rSrc == 0x7c00 ) { sc1 = 7; sc2 = 2; } /* 555 dib */
1488 else { sc1 = 8; sc2 = 3; } /* 565 dib */
1490 for (h = lines - 1; h >= 0; h--) {
1491 for (x = left; x < dstwidth+left; x++) {
1493 XPutPixel( bmpImage, x, h,
1494 X11DRV_PALETTE_ToPhysical(dc, RGB(((val & rSrc) >> sc1), /* Red */
1495 ((val & gSrc) >> sc2), /* Green */
1496 ((val & bSrc) << 3)))); /* Blue */
1498 ptr = (LPWORD) (srcbits += linebytes) + left;
1504 FIXME("16 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
1511 /***********************************************************************
1512 * X11DRV_DIB_GetImageBits_16
1514 * GetDIBits for an 16-bit deep DIB.
1516 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
1517 DWORD dstwidth, DWORD srcwidth,
1518 PALETTEENTRY *srccolors,
1519 DWORD rDst, DWORD gDst, DWORD bDst,
1520 XImage *bmpImage, DWORD dibpitch )
1525 DWORD linebytes = dibpitch;
1530 dstbits = dstbits + ( linebytes * (lines-1));
1531 linebytes = -linebytes;
1534 /* Set color scaling values */
1535 if ( rDst == 0x7c00 ) { rsc = 7; gsc = 2; } /* 555 dib */
1536 else { rsc = 8; gsc = 3; } /* 565 dib */
1538 switch ( bmpImage->depth )
1541 /* using same format as XImage */
1542 if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask)
1543 for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
1544 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
1545 /* reversed format (BGR <=> RGB) */
1546 else if (rDst == bmpImage->blue_mask && bDst == bmpImage->red_mask)
1548 LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
1550 int div = srcwidth % 2;
1552 for (h = lines - 1; h >= 0; h--) {
1553 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1554 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1556 *ptr++ = ((val << 10) & 0xf800f800) | (val & 0x03e003e0) | /* Red & Green */
1557 ((val >> 10) & 0x001f001f); /* Blue */
1559 if (div != 0) /* Odd width? */
1560 *ptr = ((*(WORD *)srcpixel << 1) & 0xffc0) | ((*(WORD *)srcpixel >> 4) & 0x0020) |
1561 (*(WORD *)srcpixel & 0x001f);
1562 ptr = (LPDWORD)(dstbits += linebytes);
1565 else goto notsupported;
1571 LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
1573 int div = srcwidth % 2;
1575 /* using same format as XImage */
1576 if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask)
1577 for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
1578 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
1579 /* ==== 565 BGR bitmap to 555 BGR dib ==== */
1580 else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f &&
1581 rDst == 0x7c00 && bDst == 0x001f)
1583 for (h = lines - 1; h >= 0; h--) {
1584 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1585 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1587 *ptr++ = ((val >> 1) & 0x7fe07fe0) | /* Red & Green */
1588 (val & 0x001f001f); /* Blue */
1590 if (div != 0) /* Odd width? */
1591 *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
1592 ptr = (LPDWORD) (dstbits += linebytes);
1595 /* ==== 565 RGB bitmap to 555 BGR dib ==== */
1596 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800 &&
1597 rDst == 0x7c00 && bDst == 0x001f)
1599 for (h = lines - 1; h >= 0; h--) {
1600 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1601 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1603 *ptr++ = ((val << 10) & 0x7c007c00) | ((val >> 1) & 0x03e003e0) | /* Red & Green */
1604 ((val >> 11) & 0x001f001f); /* Blue */
1606 if (div != 0) /* Odd width? */
1607 *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
1608 ptr = (LPDWORD) (dstbits += linebytes);
1611 else goto notsupported;
1619 LPWORD ptr = (LPWORD)dstbits;
1622 /* ==== 24/32 BGR bitmap ==== */
1623 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1625 int rsc2 = 16-rsc, gsc2 = 8-gsc;
1626 for (h = lines - 1; h >= 0; h--) {
1627 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1628 for (x = 0; x < srcwidth; x++, ptr++) {
1630 *ptr = ((val >> rsc2) & rDst) |
1631 ((val >> gsc2) & gDst) |
1632 ((val >> 3) & bDst);
1634 ptr = (LPWORD)(dstbits += linebytes);
1637 /* ==== 24/32 RGB bitmap ==== */
1638 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1641 for (h = lines - 1; h >= 0; h--) {
1642 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1643 for (x = 0; x < srcwidth; x++, ptr++) {
1645 *ptr = ((val << rsc) & rDst) |
1646 ((val >> gsc2) & gDst) |
1647 ((val >> 19) & bDst);
1649 ptr = (LPWORD) (dstbits += linebytes);
1652 else goto notsupported;
1657 /* ==== monochrome bitmap ==== */
1659 /* ==== 4 colormap bitmap ==== */
1660 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1662 LPWORD ptr = (LPWORD)dstbits;
1665 for (h = lines - 1; h >= 0; h--) {
1666 for (x = 0; x < dstwidth; x++) {
1667 val = srccolors[XGetPixel(bmpImage, x, h)];
1668 *ptr++ = ((val.peRed << rsc) & rDst) |
1669 ((val.peGreen << gsc) & gDst) |
1670 ((val.peBlue >> 3) & bDst);
1672 ptr = (LPWORD)(dstbits += linebytes);
1675 else goto notsupported;
1680 /* ==== 8 colormap bitmap ==== */
1681 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1683 LPWORD ptr = (LPWORD)dstbits;
1687 for (h = lines - 1; h >= 0; h--) {
1688 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1689 for (x = 0; x < dstwidth; x++) {
1690 val = srccolors[(int)*srcpixel++];
1691 *ptr++ = ((val.peRed << rsc) & rDst) |
1692 ((val.peGreen << gsc) & gDst) |
1693 ((val.peBlue >> 3) & bDst);
1695 ptr = (LPWORD)(dstbits += linebytes);
1698 else goto notsupported;
1706 LPWORD ptr = (LPWORD)dstbits;
1708 FIXME("from %d bit bitmap with mask R,G,B %lx,%lx,%lx to 16 bit DIB %lx,%lx,%lx\n",
1709 bmpImage->depth, bmpImage->red_mask,
1710 bmpImage->green_mask, bmpImage->blue_mask,
1713 for (h = lines - 1; h >= 0; h--)
1715 for (x = 0; x < dstwidth; x++, ptr++)
1717 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
1718 r = (BYTE) GetRValue(pixel);
1719 g = (BYTE) GetGValue(pixel);
1720 b = (BYTE) GetBValue(pixel);
1721 *ptr = ( ((r << rsc) & rDst) | ((g << gsc) & gDst) | ((b >> 3) & bDst) );
1723 ptr = (LPWORD) (dstbits += linebytes);
1731 /***********************************************************************
1732 * X11DRV_DIB_SetImageBits_24
1734 * SetDIBits for a 24-bit deep DIB.
1736 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
1737 DWORD srcwidth, DWORD dstwidth, int left,
1738 DC *dc, XImage *bmpImage, DWORD linebytes )
1746 srcbits = srcbits + linebytes * (lines - 1);
1747 linebytes = -linebytes;
1750 switch ( bmpImage->depth )
1754 if (bmpImage->bits_per_pixel == 24) {
1755 int dstlinebytes = linebytes;
1757 BYTE *ptr = (BYTE *)(srcbits+left*3);
1759 if (dstlinebytes < 0 ) dstlinebytes = -dstlinebytes;
1760 dstpixel = bmpImage->data + lines*dstlinebytes + left*3;
1761 for(h = lines ; h-- ; ) {
1762 dstpixel-=dstlinebytes;
1763 memcpy(dstpixel,ptr,dstwidth*3);
1771 if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 ) /* packed BGR to unpacked BGR */
1773 DWORD *dstpixel, val, buf;
1774 DWORD *ptr = (DWORD *)(srcbits + left*3);
1776 int div = dstwidth % 4;
1779 for(h = lines - 1; h >= 0; h--)
1781 dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);
1783 for (x = 0; x < dstwidth/4; x++) { /* do 3 dwords source, 4 dwords dest at a time */
1785 *dstpixel++ = buf&0x00ffffff; /* b1, g1, r1 */
1786 val = (buf >> 24); /* b2 */
1788 *dstpixel++ = (val | (buf<<8)) &0x00ffffff; /* g2, r2 */
1789 val = (buf >> 16); /* b3, g3 */
1791 *dstpixel++ = (val | (buf<<16)) &0x00ffffff; /* r3 */
1792 *dstpixel++ = (buf >> 8); /* b4, g4, r4 */
1794 for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
1796 *dstpixel++ = *(DWORD*)bits & 0x00ffffff; /* b, g, r */
1798 ptr = (DWORD*)((srcbits+=linebytes)+left*3);
1801 else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff ) /* packed BGR to unpacked RGB */
1803 DWORD *dstpixel, val, buf;
1804 DWORD *ptr = (DWORD *)(srcbits + left*3);
1806 int div = dstwidth % 4;
1809 for(h = lines - 1; h >= 0; h--)
1811 dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);
1813 for (x = 0; x < dstwidth/4; x++) { /* do 3 dwords source, 4 dwords dest at a time */
1815 *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16); /* b1, g1, r1 */
1816 val = ((buf&0xff000000)>>8); /* b2 */
1818 *dstpixel++ = val | ((buf&0xff)<<8) | ((buf&0xff00)>>8); /* g2, r2 */
1819 val = (buf&0xff0000) | ((buf&0xff000000)>>16); /* b3, g3 */
1821 *dstpixel++ = val | (buf&0xff); /* r3 */
1822 *dstpixel++ = ((buf&0xff00)<<8) | ((buf&0xff0000)>>8) | (buf>>24); /* b4, g4, r4 */
1824 for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
1826 buf = *(DWORD*)bits;
1827 *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16); /* b, g, r */
1829 ptr = (DWORD*)((srcbits+=linebytes)+left*3);
1839 if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f ) /* BGR888 to RGB555 */
1841 DWORD *ptr = (DWORD *)(srcbits + left*3);
1844 int div = dstwidth % 4;
1847 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1848 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1849 for (x = 0; x < dstwidth/4; x++, ptr += 3) {
1850 *dstpixel++ = ((ptr[0] << 7) & 0x7c00) | ((ptr[0] >> 6) & 0x03e0) | ((ptr[0] >> 19) & 0x1f);
1851 *dstpixel++ = ((ptr[0] >> 17) & 0x7c00) | ((ptr[1] << 2) & 0x03e0) | ((ptr[1] >> 11) & 0x1f);
1852 *dstpixel++ = ((ptr[1] >> 9) & 0x07c00) | ((ptr[1] >> 22) & 0x03e0) | ((ptr[2] >> 3) & 0x1f);
1853 *dstpixel++ = ((ptr[2] >> 1) & 0x07c00) | ((ptr[2] >> 14) & 0x03e0) | ((ptr[2] >> 27) & 0x1f);
1855 for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth not divisible by 4? */
1856 *dstpixel++ = (((WORD)bits[0] << 7) & 0x07c00) |
1857 (((WORD)bits[1] << 2) & 0x03e0) |
1858 (((WORD)bits[2] >> 3) & 0x001f);
1859 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1862 else if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 ) /* BGR888 to BGR555 */
1864 DWORD *ptr = (DWORD *)(srcbits + left*3);
1867 int div = dstwidth % 4;
1870 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1871 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1872 for (x = 0; x < dstwidth/4; x++, ptr += 3) {
1873 *dstpixel++ = ((ptr[0] >> 3) & 0x1f) | ((ptr[0] >> 6) & 0x03e0) | ((ptr[0] >> 9) & 0x7c00);
1874 *dstpixel++ = ((ptr[0] >> 27) & 0x1f) | ((ptr[1] << 2) & 0x03e0) | ((ptr[1] >> 1) & 0x7c00);
1875 *dstpixel++ = ((ptr[1] >> 19) & 0x1f) | ((ptr[1] >> 22) & 0x03e0) | ((ptr[2] << 7) & 0x7c00);
1876 *dstpixel++ = ((ptr[2] >> 11) & 0x1f) | ((ptr[2] >> 14) & 0x03e0) | ((ptr[2] >> 17) & 0x7c00);
1878 for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth not divisible by 4? */
1879 *dstpixel++ = (((WORD)bits[2] << 7) & 0x07c00) |
1880 (((WORD)bits[1] << 2) & 0x03e0) |
1881 (((WORD)bits[0] >> 3) & 0x001f);
1882 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1892 DWORD *ptr = (DWORD *)(srcbits + left*3);
1895 int div = dstwidth % 4;
1898 if( bmpImage->blue_mask == 0x001f && bmpImage->red_mask == 0xf800 ) /* BGR888 to BGR565 */
1900 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1901 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1902 for (x = 0; x < dstwidth/4; x++, ptr += 3) {
1903 *dstpixel++ = ((ptr[0] >> 3) & 0x1f) | ((ptr[0] >> 5) & 0x07e0) | ((ptr[0] >> 8) & 0xf800);
1904 *dstpixel++ = ((ptr[0] >> 27) & 0x1f) | ((ptr[1] << 3) & 0x07e0) | (ptr[1] & 0xf800);
1905 *dstpixel++ = ((ptr[1] >> 19) & 0x1f) | ((ptr[1] >> 21) & 0x07e0) | ((ptr[2] << 8) & 0xf800);
1906 *dstpixel++ = ((ptr[2] >> 11) & 0x1f) | ((ptr[2] >> 13) & 0x07e0) | ((ptr[2] >> 16) & 0xf800);
1908 for ( bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth is not divisible by 4? */
1909 *dstpixel++ = (((WORD)bits[2] << 8) & 0xf800) |
1910 (((WORD)bits[1] << 3) & 0x07e0) |
1911 (((WORD)bits[0] >> 3) & 0x001f);
1912 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1915 else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x001f ) /* BGR888 to RGB565 */
1917 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1918 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1919 for (x = 0; x < dstwidth/4; x++, ptr += 3) {
1920 *dstpixel++ = ((ptr[0] << 8) & 0xf800) | ((ptr[0] >> 5) & 0x07e0) | ((ptr[0] >> 19) & 0x1f);
1921 *dstpixel++ = ((ptr[0] >> 16) & 0xf800) | ((ptr[1] << 3) & 0x07e0) | ((ptr[1] >> 11) & 0x1f);
1922 *dstpixel++ = ((ptr[1] >> 8) & 0xf800) | ((ptr[1] >> 21) & 0x07e0) | ((ptr[2] >> 3) & 0x1f);
1923 *dstpixel++ = (ptr[2] & 0xf800) | ((ptr[2] >> 13) & 0x07e0) | ((ptr[2] >> 27) & 0x1f);
1925 for ( bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth is not divisible by 4? */
1926 *dstpixel++ = (((WORD)bits[0] << 8) & 0xf800) |
1927 (((WORD)bits[1] << 3) & 0x07e0) |
1928 (((WORD)bits[2] >> 3) & 0x001f);
1929 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1941 LPBYTE bits = (LPBYTE)srcbits + left*3;
1943 for (h = lines - 1; h >= 0; h--) {
1944 for (x = left; x < dstwidth+left; x++, bits+=3)
1945 XPutPixel( bmpImage, x, h,
1946 X11DRV_PALETTE_ToPhysical(dc, RGB(bits[2], bits[1], bits[0])));
1947 bits = (LPBYTE)(srcbits += linebytes) + left * 3;
1954 FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
1955 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
1956 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
1962 /***********************************************************************
1963 * X11DRV_DIB_GetImageBits_24
1965 * GetDIBits for an 24-bit deep DIB.
1967 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
1968 DWORD dstwidth, DWORD srcwidth,
1969 PALETTEENTRY *srccolors,
1970 XImage *bmpImage, DWORD linebytes )
1978 dstbits = dstbits + ( linebytes * (lines-1) );
1979 linebytes = -linebytes;
1982 switch ( bmpImage->depth )
1986 if (bmpImage->bits_per_pixel == 24) {
1987 int tocopy = linebytes;
1989 BYTE *ptr = (LPBYTE)dstbits;
1991 if (tocopy < 0 ) tocopy = -tocopy;
1992 srcpixel = bmpImage->data + lines*tocopy;
1993 for(h = lines ; h-- ; ) {
1995 memcpy(ptr,srcpixel,tocopy);
1996 ptr = (LPBYTE)(dstbits+=linebytes);
2003 DWORD *srcpixel, buf;
2005 DWORD *ptr=(DWORD *)dstbits;
2006 int quotient = dstwidth / 4;
2007 int remainder = dstwidth % 4;
2010 /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
2011 if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 )
2013 for(h = lines - 1; h >= 0; h--)
2015 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2017 for (x = 0; x < quotient; x++) { /* do 4 dwords source, 3 dwords dest at a time */
2018 buf = ((*srcpixel++)&0x00ffffff); /* b1, g1, r1*/
2019 *ptr++ = buf | ((*srcpixel)<<24); /* b2 */
2020 buf = ((*srcpixel++>>8)&0x0000ffff); /* g2, r2 */
2021 *ptr++ = buf | ((*srcpixel)<<16); /* b3, g3 */
2022 buf = ((*srcpixel++>>16)&0x000000ff); /* r3 */
2023 *ptr++ = buf | ((*srcpixel++)<<8); /* b4, g4, r4 */
2025 for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
2028 *(WORD*)bits = buf; /* b, g */
2029 *(bits+2) = buf>>16; /* r */
2031 ptr = (DWORD*)(dstbits+=linebytes);
2035 /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
2036 else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff )
2038 for(h = lines - 1; h >= 0; h--)
2040 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2042 for (x = 0; x < quotient; x++) { /* do 4 dwords source, 3 dwords dest at a time */
2044 val = ((buf&0xff0000)>>16) | (buf&0xff00) | ((buf&0xff)<<16); /* b1, g1, r1 */
2046 *ptr++ = val | ((buf&0xff0000)<<8); /* b2 */
2047 val = ((buf&0xff00)>>8) | ((buf&0xff)<<8); /* g2, r2 */
2049 *ptr++ = val | (buf&0xff0000) | ((buf&0xff00)<<16); /* b3, g3 */
2050 val = (buf&0xff); /* r3 */
2052 *ptr++ = val | ((buf&0xff0000)>>8) | ((buf&0xff00)<<8) | (buf<<24); /* b4, g4, r4 */
2054 for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
2057 *(WORD*)bits = (buf&0xff00) | ((buf&0xff0000)>>16) ; /* b, g */
2058 *(bits+2) = buf; /* r */
2060 ptr = (DWORD*)(dstbits+=linebytes);
2063 else goto notsupported;
2070 LPBYTE bits = dstbits;
2073 /* ==== 555 BGR bitmap to 24 BGR dib ==== */
2074 if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 )
2076 for (h = lines - 1; h >= 0; h--) {
2077 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2078 for (x = 0; x < srcwidth; x++, bits += 3) {
2080 bits[2] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2081 bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07)); /*Green*/
2082 bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2084 bits = (dstbits += linebytes);
2087 /* ==== 555 RGB bitmap to 24 RGB dib==== */
2088 else if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f )
2090 for (h = lines - 1; h >= 0; h--) {
2091 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2092 for (x = 0; x < srcwidth; x++, bits += 3) {
2094 bits[0] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2095 bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07)); /*Green*/
2096 bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2098 bits = (dstbits += linebytes);
2101 else goto notsupported;
2108 LPBYTE bits = dstbits;
2111 /* ==== 565 BGR bitmap to 24 BGR dib ==== */
2112 if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0xf800 )
2114 for (h = lines - 1; h >= 0; h--) {
2115 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2116 for (x = 0; x < srcwidth; x++, bits += 3) {
2118 bits[2] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2119 bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2120 bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2122 bits = (dstbits += linebytes);
2125 /* ==== 565 RGB bitmap to 24 BGR dib ==== */
2126 else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x1f )
2128 for (h = lines - 1; h >= 0; h--) {
2129 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2130 for (x = 0; x < srcwidth; x++, bits += 3) {
2132 bits[0] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2133 bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2134 bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2136 bits = (dstbits += linebytes);
2139 else goto notsupported;
2144 /* ==== monochrome bitmap to 24 BGR dib ==== */
2146 /* ==== 4 colormap bitmap to 24 BGR dib ==== */
2147 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2149 LPBYTE bits = dstbits;
2152 for (h = lines - 1; h >= 0; h--) {
2153 for (x = 0; x < dstwidth; x++) {
2154 val = srccolors[XGetPixel(bmpImage, x, h)];
2155 *bits++ = val.peBlue;
2156 *bits++ = val.peGreen;
2157 *bits++ = val.peRed;
2159 bits = (dstbits += linebytes);
2162 else goto notsupported;
2167 /* ==== 8 colormap bitmap to 24 BGR dib ==== */
2168 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors)
2171 LPBYTE bits = dstbits;
2174 for (h = lines - 1; h >= 0; h--) {
2175 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
2176 for (x = 0; x < dstwidth; x++ ) {
2177 val = srccolors[(int)*srcpixel++];
2178 *bits++ = val.peBlue; /*Blue*/
2179 *bits++ = val.peGreen; /*Green*/
2180 *bits++ = val.peRed; /*Red*/
2182 bits = (dstbits += linebytes);
2185 else goto notsupported;
2192 LPBYTE bits = dstbits;
2194 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
2195 bmpImage->depth, (int)bmpImage->red_mask,
2196 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2197 for (h = lines - 1; h >= 0; h--)
2199 for (x = 0; x < dstwidth; x++, bits += 3)
2201 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
2202 bits[0] = GetBValue(pixel);
2203 bits[1] = GetGValue(pixel);
2204 bits[2] = GetRValue(pixel);
2206 bits = (dstbits += linebytes);
2214 /***********************************************************************
2215 * X11DRV_DIB_SetImageBits_32
2217 * SetDIBits for a 32-bit deep DIB.
2219 static void X11DRV_DIB_SetImageBits_32( int lines, const BYTE *srcbits,
2220 DWORD srcwidth, DWORD dstwidth, int left,
2221 DC *dc, XImage *bmpImage,
2230 srcbits = srcbits + ( linebytes * (lines-1) );
2231 linebytes = -linebytes;
2234 ptr = (DWORD *) srcbits + left;
2236 switch ( bmpImage->depth )
2239 /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
2240 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff) {
2241 for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
2242 memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
2246 /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
2247 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
2251 for (h = lines - 1; h >= 0; h--) {
2252 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2253 for (x = 0; x < dstwidth; x++, ptr++) {
2254 *dstpixel++ = ((*ptr << 16) & 0xff0000) | (*ptr & 0xff00) | ((*ptr >> 16) & 0xff);
2256 ptr = (DWORD *) (srcbits += linebytes) + left;
2259 else goto notsupported;
2264 /* ==== 32 BGR dib to 24 (888) BGR bitmap ==== */
2265 /* we need to check that source mask matches destination */
2266 if (bmpImage->bits_per_pixel == 32)
2268 for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
2269 memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
2276 ptr = (DWORD *) srcbits + left;
2277 bptr = bmpImage->data;
2279 for (h = lines - 1; h >= 0; h--) {
2280 for (x = 0; x < dstwidth; x++) {
2281 /* *ptr is a 32bit value */
2282 /* bptr points to first of 3 bytes */
2283 *bptr++ = (*ptr >> 16) & 0xff;
2284 *bptr++ = (*ptr >> 8) & 0xff;
2285 *bptr++ = (*ptr ) & 0xff;
2288 ptr = (DWORD *) (srcbits += linebytes) + left;
2294 /* ==== 32 BGR dib to 555 BGR bitmap ==== */
2295 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f) {
2298 for (h = lines - 1; h >= 0; h--) {
2299 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2300 for (x = 0; x < dstwidth; x++, ptr++) {
2301 *dstpixel++ = (WORD) (((*ptr >> 9) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 3) & 0x001f));
2303 ptr = (DWORD *) (srcbits += linebytes) + left;
2306 /* ==== 32 BGR dib to 555 RGB bitmap ==== */
2307 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
2311 for (h = lines - 1; h >= 0; h--) {
2312 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2313 for (x = 0; x < dstwidth; x++, ptr++) {
2314 *dstpixel++ = (WORD) (((*ptr << 7) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 19) & 0x001f));
2316 ptr = (DWORD *) (srcbits += linebytes) + left;
2319 else goto notsupported;
2324 /* ==== 32 BGR dib to 565 BGR bitmap ==== */
2325 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2329 for (h = lines - 1; h >= 0; h--) {
2330 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2331 for (x = 0; x < dstwidth; x++, ptr++) {
2332 *dstpixel++ = (WORD) (((*ptr >> 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 3) & 0x001f));
2334 ptr = (DWORD *) (srcbits += linebytes) + left;
2337 /* ==== 32 BGR dib to 565 RGB bitmap ==== */
2338 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
2342 for (h = lines - 1; h >= 0; h--) {
2343 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2344 for (x = 0; x < dstwidth; x++, ptr++) {
2345 *dstpixel++ = (WORD) (((*ptr << 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 19) & 0x001f));
2347 ptr = (DWORD *) (srcbits += linebytes) + left;
2350 else goto notsupported;
2358 LPBYTE bits = (LPBYTE)srcbits + left*4;
2360 for (h = lines - 1; h >= 0; h--) {
2361 for (x = left; x < dstwidth+left; x++, bits += 4)
2362 XPutPixel( bmpImage, x, h,
2363 X11DRV_PALETTE_ToPhysical(dc, RGB( bits[2], bits[1], *bits )));
2364 bits = (LPBYTE)(srcbits += linebytes) + left * 4;
2371 FIXME("32 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
2377 /***********************************************************************
2378 * X11DRV_DIB_GetImageBits_32
2380 * GetDIBits for an 32-bit deep DIB.
2382 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
2383 DWORD dstwidth, DWORD srcwidth,
2384 PALETTEENTRY *srccolors,
2385 XImage *bmpImage, DWORD linebytes )
2391 DWORD copybytes = srcwidth * 4;
2396 dstbits = dstbits + ( linebytes * (lines-1) );
2397 linebytes = -linebytes;
2402 switch ( bmpImage->depth )
2405 /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
2406 if ( bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff )
2407 for (h = lines - 1; h >= 0; h--, dstbits+=linebytes)
2408 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, copybytes );
2410 /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
2411 else if ( bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000 )
2415 for (h = lines - 1; h >= 0; h--) {
2416 srcbits = bmpImage->data + h * bmpImage->bytes_per_line;
2417 for (x = 0; x < dstwidth; x++, bits+=4, srcbits+=2) {
2418 *(bits + 2) = *srcbits++;
2419 *(bits + 1) = *srcbits++;
2422 bits = (dstbits += linebytes);
2425 else goto notsupported;
2429 /* ==== 24 BGR bitmap to 32 (0888) BGR dib ==== */
2430 /* we need to check that source mask matches destination */
2436 srcpixel = (DWORD *) dstbits;
2437 bptr = bmpImage->data;
2439 for (h = lines - 1; h >= 0; h--) {
2440 for (x = 0; x < dstwidth; x++) {
2441 /* *srcpixel is a 32bit value */
2442 /* bptr points to first of 3 bytes */
2444 srcdata = srcdata << 8 | *bptr++;
2445 srcdata = srcdata << 8 | *bptr++;
2446 srcdata = srcdata << 8 | *bptr++;
2448 *srcpixel++ = srcdata;
2450 srcpixel = (DWORD *) (dstbits += linebytes);
2460 /* ==== 555 BGR bitmap to 32 BGR dib ==== */
2461 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
2463 for (h = lines - 1; h >= 0; h--) {
2464 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2465 for (x = 0; x < dstwidth; x++, bits+=2) {
2467 *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
2468 *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
2469 *bits = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2471 bits = (dstbits += linebytes);
2474 /* ==== 555 RGB bitmap to 32 BGR dib ==== */
2475 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
2477 for (h = lines - 1; h >= 0; h--) {
2478 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2479 for (x = 0; x < dstwidth; x++, bits+=2) {
2481 *bits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));/*Blue*/
2482 *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
2483 *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Red*/
2485 bits = (dstbits += linebytes);
2488 else goto notsupported;
2497 /* ==== 565 BGR bitmap to 32 BGR dib ==== */
2498 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2500 for (h = lines - 1; h >= 0; h--) {
2501 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2502 for (x = 0; x < srcwidth; x++, bits+=2) {
2504 *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
2505 *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2506 *bits = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2508 bits = (dstbits += linebytes);
2511 /* ==== 565 RGB bitmap to 32 BGR dib ==== */
2512 else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2514 for (h = lines - 1; h >= 0; h--) {
2515 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2516 for (x = 0; x < srcwidth; x++, bits+=2) {
2518 *bits++ = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));/*Blue*/
2519 *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2520 *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Red*/
2522 bits = (dstbits += linebytes);
2525 else goto notsupported;
2530 /* ==== monochrome bitmap to 32 BGR dib ==== */
2532 /* ==== 4 colormap bitmap to 32 BGR dib ==== */
2533 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2537 for (h = lines - 1; h >= 0; h--) {
2538 for (x = 0; x < dstwidth; x++) {
2539 val = srccolors[XGetPixel(bmpImage, x, h)];
2540 *bits++ = val.peBlue;
2541 *bits++ = val.peGreen;
2542 *bits++ = val.peRed;
2545 bits = (dstbits += linebytes);
2548 else goto notsupported;
2553 /* ==== 8 colormap bitmap to 32 BGR dib ==== */
2554 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2559 for (h = lines - 1; h >= 0; h--) {
2560 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
2561 for (x = 0; x < dstwidth; x++) {
2562 val = srccolors[(int)*srcpixel++];
2563 *bits++ = val.peBlue; /*Blue*/
2564 *bits++ = val.peGreen; /*Green*/
2565 *bits++ = val.peRed; /*Red*/
2568 bits = (dstbits += linebytes);
2571 else goto notsupported;
2576 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
2577 bmpImage->depth, (int)bmpImage->red_mask,
2578 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2579 for (h = lines - 1; h >= 0; h--)
2581 for (x = 0; x < dstwidth; x++, bits += 4)
2583 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
2584 bits[0] = GetBValue(pixel);
2585 bits[1] = GetGValue(pixel);
2586 bits[2] = GetRValue(pixel);
2588 bits = (dstbits += linebytes);
2594 /***********************************************************************
2595 * X11DRV_DIB_SetImageBits
2597 * Transfer the bits to an X image.
2598 * Helper function for SetDIBits() and SetDIBitsToDevice().
2600 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
2602 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
2607 bmpImage = descr->image;
2609 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
2610 descr->infoWidth, lines, 32, 0 );
2611 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
2612 if(bmpImage->data == NULL) {
2613 ERR("Out of memory!\n");
2614 XDestroyImage( bmpImage );
2615 wine_tsx11_unlock();
2620 /* Transfer the pixels */
2621 switch(descr->infoBpp)
2624 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
2625 descr->width, descr->xSrc, (int *)(descr->colorMap),
2626 bmpImage, descr->dibpitch );
2629 if (descr->compression) {
2630 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
2631 descr->width, descr->height, AllPlanes, ZPixmap,
2632 bmpImage, descr->xSrc, descr->ySrc );
2634 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
2635 descr->infoWidth, descr->width,
2636 descr->xSrc, (int *)(descr->colorMap),
2639 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
2640 descr->infoWidth, descr->width,
2641 descr->xSrc, (int*)(descr->colorMap),
2642 bmpImage, descr->dibpitch );
2645 if (descr->compression) {
2646 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
2647 descr->width, descr->height, AllPlanes, ZPixmap,
2648 bmpImage, descr->xSrc, descr->ySrc );
2649 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
2650 descr->infoWidth, descr->width,
2651 descr->xSrc, (int *)(descr->colorMap),
2654 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
2655 descr->infoWidth, descr->width,
2656 descr->xSrc, (int *)(descr->colorMap),
2657 bmpImage, descr->dibpitch );
2661 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
2662 descr->infoWidth, descr->width,
2663 descr->xSrc, descr->dc,
2664 descr->rMask, descr->gMask, descr->bMask,
2665 bmpImage, descr->dibpitch);
2668 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
2669 descr->infoWidth, descr->width,
2670 descr->xSrc, descr->dc, bmpImage,
2674 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
2675 descr->infoWidth, descr->width,
2676 descr->xSrc, descr->dc,
2677 bmpImage, descr->dibpitch);
2680 WARN("(%d): Invalid depth\n", descr->infoBpp );
2684 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
2685 descr->drawable, descr->gc, bmpImage,
2686 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2687 descr->width, descr->height);
2688 #ifdef HAVE_LIBXXSHM
2691 XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
2692 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2693 descr->width, descr->height, FALSE );
2694 XSync( gdi_display, 0 );
2698 XPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
2699 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2700 descr->width, descr->height );
2702 if (!descr->image) XDestroyImage( bmpImage );
2703 wine_tsx11_unlock();
2707 /***********************************************************************
2708 * X11DRV_DIB_GetImageBits
2710 * Transfer the bits from an X image.
2712 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
2714 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
2719 bmpImage = descr->image;
2721 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
2722 descr->infoWidth, lines, 32, 0 );
2723 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
2724 if(bmpImage->data == NULL) {
2725 ERR("Out of memory!\n");
2726 XDestroyImage( bmpImage );
2727 wine_tsx11_unlock();
2732 TRACE("XGetSubImage(%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
2733 descr->drawable, descr->xSrc, descr->ySrc, descr->width,
2734 lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
2735 XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc,
2736 descr->width, lines, AllPlanes, ZPixmap,
2737 bmpImage, descr->xDest, descr->yDest );
2739 /* Transfer the pixels */
2740 switch(descr->infoBpp)
2743 X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
2744 descr->infoWidth, descr->width,
2745 descr->colorMap, descr->palentry,
2746 bmpImage, descr->dibpitch );
2750 if (descr->compression)
2751 FIXME("Compression not yet supported!\n");
2753 X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
2754 descr->infoWidth, descr->width,
2755 descr->colorMap, descr->palentry,
2756 bmpImage, descr->dibpitch );
2760 if (descr->compression)
2761 FIXME("Compression not yet supported!\n");
2763 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
2764 descr->infoWidth, descr->width,
2765 descr->colorMap, descr->palentry,
2766 bmpImage, descr->dibpitch );
2770 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
2771 descr->infoWidth,descr->width,
2773 descr->rMask, descr->gMask, descr->bMask,
2774 bmpImage, descr->dibpitch );
2778 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
2779 descr->infoWidth,descr->width,
2780 descr->palentry, bmpImage, descr->dibpitch);
2784 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
2785 descr->infoWidth, descr->width,
2786 descr->palentry, bmpImage, descr->dibpitch);
2790 WARN("(%d): Invalid depth\n", descr->infoBpp );
2794 if (!descr->image) XDestroyImage( bmpImage );
2795 wine_tsx11_unlock();
2799 /*************************************************************************
2800 * X11DRV_SetDIBitsToDevice
2803 INT X11DRV_SetDIBitsToDevice( DC *dc, INT xDest, INT yDest, DWORD cx,
2804 DWORD cy, INT xSrc, INT ySrc,
2805 UINT startscan, UINT lines, LPCVOID bits,
2806 const BITMAPINFO *info, UINT coloruse )
2808 X11DRV_DIB_IMAGEBITS_DESCR descr;
2809 DWORD width, oldcy = cy;
2811 int height, tmpheight;
2812 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
2815 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
2816 &descr.infoBpp, &descr.compression ) == -1)
2819 if (height < 0) height = -height;
2820 if (!lines || (startscan >= height)) return 0;
2821 if (startscan + lines > height) lines = height - startscan;
2822 if (ySrc < startscan) ySrc = startscan;
2823 else if (ySrc >= startscan + lines) return 0;
2824 if (xSrc >= width) return 0;
2825 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
2826 if (xSrc + cx >= width) cx = width - xSrc;
2827 if (!cx || !cy) return 0;
2829 X11DRV_SetupGCForText( dc ); /* To have the correct colors */
2830 TSXSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[dc->ROPmode-1]);
2832 switch (descr.infoBpp)
2837 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
2838 coloruse == DIB_PAL_COLORS ? dc : NULL, coloruse,
2839 dc->bitsPerPixel, info, &descr.nColorMap );
2840 if (!descr.colorMap) return 0;
2841 descr.rMask = descr.gMask = descr.bMask = 0;
2845 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
2846 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
2847 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
2852 descr.rMask = descr.gMask = descr.bMask = 0;
2857 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
2858 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
2859 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
2867 descr.palentry = NULL;
2868 descr.lines = tmpheight >= 0 ? lines : -lines;
2869 descr.infoWidth = width;
2870 descr.depth = dc->bitsPerPixel;
2871 descr.drawable = physDev->drawable;
2872 descr.gc = physDev->gc;
2874 descr.ySrc = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy)
2876 descr.xDest = dc->DCOrgX + XLPTODP( dc, xDest );
2877 descr.yDest = dc->DCOrgY + YLPTODP( dc, yDest ) +
2878 (tmpheight >= 0 ? oldcy-cy : 0);
2881 descr.useShm = FALSE;
2882 descr.dibpitch = ((width * descr.infoBpp + 31) &~31) / 8;
2884 result = X11DRV_DIB_SetImageBits( &descr );
2886 if (descr.infoBpp <= 8)
2887 HeapFree(GetProcessHeap(), 0, descr.colorMap);
2891 /***********************************************************************
2892 * X11DRV_DIB_SetDIBits
2894 INT X11DRV_DIB_SetDIBits(
2895 BITMAPOBJ *bmp, DC *dc, UINT startscan,
2896 UINT lines, LPCVOID bits, const BITMAPINFO *info,
2897 UINT coloruse, HBITMAP hbitmap)
2899 X11DRV_DIB_IMAGEBITS_DESCR descr;
2900 int height, tmpheight;
2905 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
2906 &descr.infoBpp, &descr.compression ) == -1)
2910 if (height < 0) height = -height;
2911 if (!lines || (startscan >= height))
2914 if (startscan + lines > height) lines = height - startscan;
2916 switch (descr.infoBpp)
2921 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
2922 coloruse == DIB_PAL_COLORS ? descr.dc : NULL, coloruse,
2923 bmp->bitmap.bmBitsPixel,
2924 info, &descr.nColorMap );
2925 if (!descr.colorMap) return 0;
2926 descr.rMask = descr.gMask = descr.bMask = 0;
2930 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
2931 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
2932 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
2937 descr.rMask = descr.gMask = descr.bMask = 0;
2942 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
2943 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
2944 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
2952 if(!bmp->physBitmap)
2953 X11DRV_CreateBitmap(hbitmap);
2957 descr.palentry = NULL;
2958 descr.lines = tmpheight >= 0 ? lines : -lines;
2959 descr.depth = bmp->bitmap.bmBitsPixel;
2960 descr.drawable = (Pixmap)bmp->physBitmap;
2961 descr.gc = BITMAP_GC(bmp);
2965 descr.yDest = height - startscan - lines;
2966 descr.width = bmp->bitmap.bmWidth;
2967 descr.height = lines;
2968 descr.useShm = FALSE;
2969 descr.dibpitch = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
2970 result = X11DRV_DIB_SetImageBits( &descr );
2972 if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);
2977 /***********************************************************************
2978 * X11DRV_DIB_GetDIBits
2980 INT X11DRV_DIB_GetDIBits(
2981 BITMAPOBJ *bmp, DC *dc, UINT startscan,
2982 UINT lines, LPVOID bits, BITMAPINFO *info,
2983 UINT coloruse, HBITMAP hbitmap)
2985 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
2986 X11DRV_DIB_IMAGEBITS_DESCR descr;
2987 PALETTEOBJ * palette;
2990 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
2991 lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
2992 (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
2995 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC )))
2998 if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
3000 height = info->bmiHeader.biHeight;
3001 if (height < 0) height = -height;
3002 if( lines > height ) lines = height;
3003 /* Top-down images have a negative biHeight, the scanlines of theses images
3004 * were inverted in X11DRV_DIB_GetImageBits_xx
3005 * To prevent this we simply change the sign of lines
3006 * (the number of scan lines to copy).
3007 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3009 if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
3011 if( startscan >= bmp->bitmap.bmHeight )
3017 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
3018 &descr.infoBpp, &descr.compression ) == -1)
3024 switch (descr.infoBpp)
3030 descr.rMask = descr.gMask = descr.bMask = 0;
3034 descr.rMask = 0x7c00;
3035 descr.gMask = 0x03e0;
3036 descr.bMask = 0x001f;
3040 descr.rMask = 0xff0000;
3041 descr.gMask = 0xff00;
3047 if(!bmp->physBitmap)
3048 X11DRV_CreateBitmap(hbitmap);
3052 descr.palentry = palette->logpalette.palPalEntry;
3055 descr.lines = lines;
3056 descr.depth = bmp->bitmap.bmBitsPixel;
3057 descr.drawable = (Pixmap)bmp->physBitmap;
3058 descr.gc = BITMAP_GC(bmp);
3059 descr.width = bmp->bitmap.bmWidth;
3060 descr.height = bmp->bitmap.bmHeight;
3061 descr.colorMap = info->bmiColors;
3066 if (descr.lines > 0)
3068 descr.ySrc = (descr.height-1) - (startscan + (lines-1));
3072 descr.ySrc = startscan;
3074 #ifdef HAVE_LIBXXSHM
3075 descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
3077 descr.useShm = FALSE;
3079 descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
3080 : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
3082 X11DRV_DIB_GetImageBits( &descr );
3084 if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
3085 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
3086 info->bmiHeader.biWidth,
3087 info->bmiHeader.biHeight,
3088 info->bmiHeader.biBitCount );
3090 info->bmiHeader.biCompression = 0;
3091 if (descr.compression == BI_BITFIELDS)
3093 *(DWORD *)info->bmiColors = descr.rMask;
3094 *((DWORD *)info->bmiColors+1) = descr.gMask;
3095 *((DWORD *)info->bmiColors+2) = descr.bMask;
3099 GDI_ReleaseObj( dc->hPalette );
3104 /***********************************************************************
3105 * DIB_DoProtectDIBSection
3107 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
3109 DIBSECTION *dib = bmp->dib;
3110 INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
3111 : -dib->dsBm.bmHeight;
3112 /* use the biSizeImage data as the memory size only if we're dealing with a
3113 compressed image where the value is set. Otherwise, calculate based on
3115 INT totalSize = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
3116 ? dib->dsBmih.biSizeImage
3117 : dib->dsBm.bmWidthBytes * effHeight;
3120 VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
3121 TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
3124 /***********************************************************************
3125 * X11DRV_DIB_DoUpdateDIBSection
3127 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
3128 void *colorMap, int nColorMap,
3130 DWORD xSrc, DWORD ySrc,
3131 DWORD xDest, DWORD yDest,
3132 DWORD width, DWORD height)
3134 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3135 X11DRV_DIB_IMAGEBITS_DESCR descr;
3137 if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
3138 &descr.infoBpp, &descr.compression ) == -1)
3142 descr.palentry = NULL;
3143 descr.image = dib->image;
3144 descr.colorMap = colorMap;
3145 descr.nColorMap = nColorMap;
3146 descr.bits = dib->dibSection.dsBm.bmBits;
3147 descr.depth = bmp->bitmap.bmBitsPixel;
3149 switch (descr.infoBpp)
3155 descr.rMask = descr.gMask = descr.bMask = 0;
3159 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
3160 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
3161 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
3165 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff;
3166 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0xff00;
3167 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0xff0000;
3172 descr.drawable = dest;
3173 descr.gc = BITMAP_GC(bmp);
3176 descr.xDest = xDest;
3177 descr.yDest = yDest;
3178 descr.width = width;
3179 descr.height = height;
3180 #ifdef HAVE_LIBXXSHM
3181 descr.useShm = (dib->shminfo.shmid != -1);
3183 descr.useShm = FALSE;
3185 descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
3189 TRACE("Copying from Pixmap to DIB bits\n");
3190 X11DRV_DIB_GetImageBits( &descr );
3194 TRACE("Copying from DIB bits to Pixmap\n");
3195 X11DRV_DIB_SetImageBits( &descr );
3199 /***********************************************************************
3200 * X11DRV_DIB_CopyDIBSection
3202 void X11DRV_DIB_CopyDIBSection(DC *dcSrc, DC *dcDst,
3203 DWORD xSrc, DWORD ySrc,
3204 DWORD xDest, DWORD yDest,
3205 DWORD width, DWORD height)
3208 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dcDst->physDev;
3209 int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE;
3211 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc, dcDst,
3212 xSrc, ySrc, xDest, yDest, width, height);
3213 /* this function is meant as an optimization for BitBlt,
3214 * not to be called otherwise */
3215 if (!(dcSrc->flags & DC_MEMORY)) {
3216 ERR("called for non-memory source DC!?\n");
3220 bmp = (BITMAPOBJ *)GDI_GetObjPtr( dcSrc->hBitmap, BITMAP_MAGIC );
3221 if (!(bmp && bmp->dib)) {
3222 ERR("called for non-DIBSection!?\n");
3223 GDI_ReleaseObj( dcSrc->hBitmap );
3226 /* while BitBlt should already have made sure we only get
3227 * positive values, we should check for oversize values */
3228 if ((xSrc < bmp->bitmap.bmWidth) &&
3229 (ySrc < bmp->bitmap.bmHeight)) {
3230 if (xSrc + width > bmp->bitmap.bmWidth)
3231 width = bmp->bitmap.bmWidth - xSrc;
3232 if (ySrc + height > bmp->bitmap.bmHeight)
3233 height = bmp->bitmap.bmHeight - ySrc;
3234 /* if the source bitmap is 8bpp or less, we're supposed to use the
3235 * DC's palette for color conversion (not the DIB color table) */
3236 if (bmp->dib->dsBm.bmBitsPixel <= 8) {
3237 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3238 if ((!dcSrc->hPalette) ||
3239 (dcSrc->hPalette == GetStockObject(DEFAULT_PALETTE))) {
3240 /* HACK: no palette has been set in the source DC,
3241 * use the DIB colormap instead - this is necessary in some
3242 * cases since we need to do depth conversion in some places
3243 * where real Windows can just copy data straight over */
3244 colorMap = dib->colorMap;
3245 nColorMap = dib->nColorMap;
3247 colorMap = X11DRV_DIB_BuildColorMap( dcSrc, (WORD)-1,
3248 bmp->dib->dsBm.bmBitsPixel,
3249 (BITMAPINFO*)&(bmp->dib->dsBmih),
3251 if (colorMap) aColorMap = TRUE;
3254 /* perform the copy */
3255 X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap,
3256 physDev->drawable, xSrc, ySrc, xDest, yDest,
3258 /* free color mapping */
3260 HeapFree(GetProcessHeap(), 0, colorMap);
3262 GDI_ReleaseObj( dcSrc->hBitmap );
3265 /***********************************************************************
3266 * X11DRV_DIB_DoUpdateDIBSection
3268 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
3270 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3271 X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap,
3272 (Drawable)bmp->physBitmap, 0, 0, 0, 0,
3273 bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
3276 /***********************************************************************
3277 * X11DRV_DIB_FaultHandler
3279 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
3284 bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
3285 if (!bmp) return FALSE;
3287 state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
3288 if (state != DIB_Status_InSync) {
3289 /* no way to tell whether app needs read or write yet,
3291 X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
3293 /* hm, apparently the app must have write access */
3294 X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
3296 X11DRV_DIB_Unlock(bmp, TRUE);
3298 GDI_ReleaseObj( (HBITMAP)res );
3302 /***********************************************************************
3305 INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
3307 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3308 INT ret = DIB_Status_None;
3311 EnterCriticalSection(&(dib->lock));
3314 case DIB_Status_GdiMod:
3315 /* GDI access - request to draw on pixmap */
3316 switch (dib->status)
3319 case DIB_Status_None:
3320 dib->p_status = DIB_Status_GdiMod;
3321 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
3324 case DIB_Status_GdiMod:
3325 TRACE("GdiMod requested in status GdiMod\n" );
3328 case DIB_Status_InSync:
3329 TRACE("GdiMod requested in status InSync\n" );
3330 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3331 dib->status = DIB_Status_GdiMod;
3332 dib->p_status = DIB_Status_InSync;
3335 case DIB_Status_AuxMod:
3336 TRACE("GdiMod requested in status AuxMod\n" );
3337 if (lossy) dib->status = DIB_Status_GdiMod;
3338 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
3339 dib->p_status = DIB_Status_AuxMod;
3340 if (dib->status != DIB_Status_AppMod) {
3341 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3344 /* fall through if copy_aux() had to change to AppMod state */
3346 case DIB_Status_AppMod:
3347 TRACE("GdiMod requested in status AppMod\n" );
3349 /* make it readonly to avoid app changing data while we copy */
3350 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3351 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
3353 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3354 dib->p_status = DIB_Status_AppMod;
3355 dib->status = DIB_Status_GdiMod;
3360 case DIB_Status_InSync:
3361 /* App access - request access to read DIB surface */
3362 /* (typically called from signal handler) */
3363 switch (dib->status)
3366 case DIB_Status_None:
3367 /* shouldn't happen from signal handler */
3370 case DIB_Status_AuxMod:
3371 TRACE("InSync requested in status AuxMod\n" );
3372 if (lossy) dib->status = DIB_Status_InSync;
3374 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3375 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
3377 if (dib->status != DIB_Status_GdiMod) {
3378 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3381 /* fall through if copy_aux() had to change to GdiMod state */
3383 case DIB_Status_GdiMod:
3384 TRACE("InSync requested in status GdiMod\n" );
3386 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3387 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3389 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3390 dib->status = DIB_Status_InSync;
3393 case DIB_Status_InSync:
3394 TRACE("InSync requested in status InSync\n" );
3395 /* shouldn't happen from signal handler */
3398 case DIB_Status_AppMod:
3399 TRACE("InSync requested in status AppMod\n" );
3400 /* no reason to do anything here, and this
3401 * shouldn't happen from signal handler */
3406 case DIB_Status_AppMod:
3407 /* App access - request access to write DIB surface */
3408 /* (typically called from signal handler) */
3409 switch (dib->status)
3412 case DIB_Status_None:
3413 /* shouldn't happen from signal handler */
3416 case DIB_Status_AuxMod:
3417 TRACE("AppMod requested in status AuxMod\n" );
3418 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3419 if (lossy) dib->status = DIB_Status_AppMod;
3420 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
3421 if (dib->status != DIB_Status_GdiMod)
3423 /* fall through if copy_aux() had to change to GdiMod state */
3425 case DIB_Status_GdiMod:
3426 TRACE("AppMod requested in status GdiMod\n" );
3427 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3428 if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3429 dib->status = DIB_Status_AppMod;
3432 case DIB_Status_InSync:
3433 TRACE("AppMod requested in status InSync\n" );
3434 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3435 dib->status = DIB_Status_AppMod;
3438 case DIB_Status_AppMod:
3439 TRACE("AppMod requested in status AppMod\n" );
3440 /* shouldn't happen from signal handler */
3445 case DIB_Status_AuxMod:
3446 if (dib->status == DIB_Status_None) {
3447 dib->p_status = req;
3449 if (dib->status != DIB_Status_AuxMod)
3450 dib->p_status = dib->status;
3451 dib->status = DIB_Status_AuxMod;
3454 /* it is up to the caller to do the copy/conversion, probably
3455 * using the return value to decide where to copy from */
3457 LeaveCriticalSection(&(dib->lock));
3462 /***********************************************************************
3465 INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
3467 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3468 INT ret = DIB_Status_None;
3471 TRACE("Locking %p from thread %08lx\n", bmp, GetCurrentThreadId());
3472 EnterCriticalSection(&(dib->lock));
3474 if (req != DIB_Status_None)
3475 X11DRV_DIB_Coerce(bmp, req, lossy);
3480 /***********************************************************************
3483 void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
3485 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3488 switch (dib->status)
3491 case DIB_Status_None:
3492 /* in case anyone is wondering, this is the "signal handler doesn't
3493 * work" case, where we always have to be ready for app access */
3495 switch (dib->p_status)
3497 case DIB_Status_AuxMod:
3498 TRACE("Unlocking and syncing from AuxMod\n" );
3499 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
3500 if (dib->status != DIB_Status_None) {
3501 dib->p_status = dib->status;
3502 dib->status = DIB_Status_None;
3504 if (dib->p_status != DIB_Status_GdiMod)
3506 /* fall through if copy_aux() had to change to GdiMod state */
3508 case DIB_Status_GdiMod:
3509 TRACE("Unlocking and syncing from GdiMod\n" );
3510 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3514 TRACE("Unlocking without needing to sync\n" );
3518 else TRACE("Unlocking with no changes\n");
3519 dib->p_status = DIB_Status_None;
3522 case DIB_Status_GdiMod:
3523 TRACE("Unlocking in status GdiMod\n" );
3524 /* DIB was protected in Coerce */
3526 /* no commit, revert to InSync if applicable */
3527 if ((dib->p_status == DIB_Status_InSync) ||
3528 (dib->p_status == DIB_Status_AppMod)) {
3529 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3530 dib->status = DIB_Status_InSync;
3535 case DIB_Status_InSync:
3536 TRACE("Unlocking in status InSync\n" );
3537 /* DIB was already protected in Coerce */
3540 case DIB_Status_AppMod:
3541 TRACE("Unlocking in status AppMod\n" );
3542 /* DIB was already protected in Coerce */
3543 /* this case is ordinary only called from the signal handler,
3544 * so we don't bother to check for !commit */
3547 case DIB_Status_AuxMod:
3548 TRACE("Unlocking in status AuxMod\n" );
3550 /* DIB may need protection now */
3551 if ((dib->p_status == DIB_Status_InSync) ||
3552 (dib->p_status == DIB_Status_AppMod))
3553 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3555 /* no commit, revert to previous state */
3556 if (dib->p_status != DIB_Status_None)
3557 dib->status = dib->p_status;
3558 /* no protections changed */
3560 dib->p_status = DIB_Status_None;
3563 LeaveCriticalSection(&(dib->lock));
3564 TRACE("Unlocked %p\n", bmp);
3568 /***********************************************************************
3569 * X11DRV_CoerceDIBSection2
3571 INT X11DRV_CoerceDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
3576 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3577 if (!bmp) return DIB_Status_None;
3578 ret = X11DRV_DIB_Coerce(bmp, req, lossy);
3579 GDI_ReleaseObj( hBmp );
3583 /***********************************************************************
3584 * X11DRV_LockDIBSection2
3586 INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
3591 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3592 if (!bmp) return DIB_Status_None;
3593 ret = X11DRV_DIB_Lock(bmp, req, lossy);
3594 GDI_ReleaseObj( hBmp );
3598 /***********************************************************************
3599 * X11DRV_UnlockDIBSection2
3601 void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
3605 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3607 X11DRV_DIB_Unlock(bmp, commit);
3608 GDI_ReleaseObj( hBmp );
3611 /***********************************************************************
3612 * X11DRV_CoerceDIBSection
3614 INT X11DRV_CoerceDIBSection(DC *dc, INT req, BOOL lossy)
3616 if (!dc) return DIB_Status_None;
3617 return X11DRV_CoerceDIBSection2( dc->hBitmap, req, lossy );
3620 /***********************************************************************
3621 * X11DRV_LockDIBSection
3623 INT X11DRV_LockDIBSection(DC *dc, INT req, BOOL lossy)
3625 if (!dc) return DIB_Status_None;
3626 if (!(dc->flags & DC_MEMORY)) return DIB_Status_None;
3628 return X11DRV_LockDIBSection2( dc->hBitmap, req, lossy );
3631 /***********************************************************************
3632 * X11DRV_UnlockDIBSection
3634 void X11DRV_UnlockDIBSection(DC *dc, BOOL commit)
3637 if (!(dc->flags & DC_MEMORY)) return;
3639 X11DRV_UnlockDIBSection2( dc->hBitmap, commit );
3643 #ifdef HAVE_LIBXXSHM
3644 /***********************************************************************
3645 * X11DRV_XShmErrorHandler
3648 static int XShmErrorHandler(Display *dpy, XErrorEvent *event)
3654 /***********************************************************************
3655 * X11DRV_XShmCreateImage
3658 static XImage *X11DRV_XShmCreateImage( int width, int height, int bpp,
3659 XShmSegmentInfo* shminfo)
3661 int (*WineXHandler)(Display *, XErrorEvent *);
3665 image = XShmCreateImage(gdi_display, visual, bpp, ZPixmap, NULL, shminfo, width, height);
3668 shminfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height,
3670 if( shminfo->shmid != -1 )
3672 shminfo->shmaddr = image->data = shmat(shminfo->shmid, 0, 0);
3673 if( shminfo->shmaddr != (char*)-1 )
3675 shminfo->readOnly = FALSE;
3676 if( XShmAttach( gdi_display, shminfo ) != 0)
3678 /* Reset the error flag */
3680 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3681 XSync( gdi_display, 0 );
3685 shmctl(shminfo->shmid, IPC_RMID, 0);
3687 XSetErrorHandler(WineXHandler);
3688 wine_tsx11_unlock();
3689 return image; /* Success! */
3691 /* An error occured */
3693 XSetErrorHandler(WineXHandler);
3695 shmdt(shminfo->shmaddr);
3697 shmctl(shminfo->shmid, IPC_RMID, 0);
3699 XFlush(gdi_display);
3700 XDestroyImage(image);
3703 wine_tsx11_unlock();
3706 #endif /* HAVE_LIBXXSHM */
3709 /***********************************************************************
3710 * X11DRV_DIB_CreateDIBSection
3712 HBITMAP X11DRV_DIB_CreateDIBSection(
3713 DC *dc, BITMAPINFO *bmi, UINT usage,
3714 LPVOID *bits, HANDLE section,
3715 DWORD offset, DWORD ovr_pitch)
3718 BITMAPOBJ *bmp = NULL;
3719 X11DRV_DIBSECTION *dib = NULL;
3720 int *colorMap = NULL;
3723 /* Fill BITMAP32 structure with DIB data */
3724 BITMAPINFOHEADER *bi = &bmi->bmiHeader;
3725 INT effHeight, totalSize;
3727 LPVOID mapBits = NULL;
3729 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
3730 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
3731 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
3733 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
3735 bm.bmWidth = bi->biWidth;
3736 bm.bmHeight = effHeight;
3737 bm.bmWidthBytes = ovr_pitch ? ovr_pitch
3738 : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
3739 bm.bmPlanes = bi->biPlanes;
3740 bm.bmBitsPixel = bi->biBitCount;
3743 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
3744 we're dealing with a compressed bitmap. Otherwise, use width * height. */
3745 totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
3746 ? bi->biSizeImage : bm.bmWidthBytes * effHeight;
3750 SYSTEM_INFO SystemInfo;
3754 GetSystemInfo( &SystemInfo );
3755 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
3756 mapSize = totalSize + (offset - mapOffset);
3757 mapBits = MapViewOfFile( section,
3758 FILE_MAP_ALL_ACCESS,
3762 bm.bmBits = (char *)mapBits + (offset - mapOffset);
3764 else if (ovr_pitch && offset)
3765 bm.bmBits = (LPVOID) offset;
3768 bm.bmBits = VirtualAlloc(NULL, totalSize,
3769 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
3772 /* Create Color Map */
3773 if (bm.bmBits && bm.bmBitsPixel <= 8)
3774 colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? dc : NULL,
3775 usage, bm.bmBitsPixel, bmi, &nColorMap );
3777 /* Allocate Memory for DIB and fill structure */
3779 dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
3782 dib->dibSection.dsBm = bm;
3783 dib->dibSection.dsBmih = *bi;
3784 dib->dibSection.dsBmih.biSizeImage = totalSize;
3786 /* Set dsBitfields values */
3787 if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
3789 dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
3791 else switch( bi->biBitCount )
3794 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
3795 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
3796 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
3800 dib->dibSection.dsBitfields[0] = 0xff;
3801 dib->dibSection.dsBitfields[1] = 0xff00;
3802 dib->dibSection.dsBitfields[2] = 0xff0000;
3806 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff;
3807 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0xff00;
3808 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0xff0000;
3811 dib->dibSection.dshSection = section;
3812 dib->dibSection.dsOffset = offset;
3814 dib->status = DIB_Status_None;
3815 dib->nColorMap = nColorMap;
3816 dib->colorMap = colorMap;
3819 /* Create Device Dependent Bitmap and add DIB pointer */
3822 res = CreateDIBitmap(dc->hSelf, bi, 0, NULL, bmi, usage);
3825 bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
3828 bmp->dib = (DIBSECTION *) dib;
3830 if(!bmp->physBitmap)
3831 X11DRV_CreateBitmap(res);
3839 #ifdef HAVE_LIBXXSHM
3840 if (TSXShmQueryExtension(gdi_display) &&
3841 (dib->image = X11DRV_XShmCreateImage( bm.bmWidth, effHeight,
3842 bmp->bitmap.bmBitsPixel, &dib->shminfo )) )
3844 ; /* Created Image */
3846 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
3847 dib->shminfo.shmid = -1;
3850 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
3854 /* Clean up in case of errors */
3855 if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
3857 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
3858 res, bmp, dib, bm.bmBits);
3862 UnmapViewOfFile(mapBits), bm.bmBits = NULL;
3864 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
3867 if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
3868 if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
3869 if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
3870 if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
3871 if (res) { DeleteObject(res); res = 0; }
3875 /* Install fault handler, if possible */
3876 InitializeCriticalSection(&(dib->lock));
3877 if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
3879 if (section || offset)
3881 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3882 if (dib) dib->status = DIB_Status_AppMod;
3886 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3887 if (dib) dib->status = DIB_Status_InSync;
3892 /* Return BITMAP handle and storage location */
3893 if (bmp) GDI_ReleaseObj(res);
3894 if (bm.bmBits && bits) *bits = bm.bmBits;
3898 /***********************************************************************
3899 * X11DRV_DIB_DeleteDIBSection
3901 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
3903 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3907 #ifdef HAVE_LIBXXSHM
3908 if (dib->shminfo.shmid != -1)
3910 TSXShmDetach (gdi_display, &(dib->shminfo));
3911 XDestroyImage (dib->image);
3912 shmdt (dib->shminfo.shmaddr);
3913 dib->shminfo.shmid = -1;
3917 XDestroyImage( dib->image );
3921 HeapFree(GetProcessHeap(), 0, dib->colorMap);
3923 DeleteCriticalSection(&(dib->lock));
3926 /***********************************************************************
3927 * X11DRV_DIB_SetDIBColorTable
3929 UINT X11DRV_DIB_SetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, const RGBQUAD *colors)
3931 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3933 if (dib && dib->colorMap) {
3935 * Changing color table might change the mapping between
3936 * DIB colors and X11 colors and thus alter the visible state
3937 * of the bitmap object.
3939 X11DRV_DIB_Lock(bmp, DIB_Status_AppMod, FALSE);
3940 X11DRV_DIB_GenColorMap( dc, dib->colorMap, DIB_RGB_COLORS,
3941 dib->dibSection.dsBm.bmBitsPixel,
3942 TRUE, colors, start, count + start );
3943 X11DRV_DIB_Unlock(bmp, TRUE);
3949 /***********************************************************************
3950 * X11DRV_DIB_GetDIBColorTable
3952 UINT X11DRV_DIB_GetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, RGBQUAD *colors)
3954 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3956 if (dib && dib->colorMap) {
3957 int i, end = count + start;
3958 if (end > dib->nColorMap) end = dib->nColorMap;
3959 for (i = start; i < end; i++,colors++) {
3960 COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] );
3961 colors->rgbBlue = GetBValue(col);
3962 colors->rgbGreen = GetGValue(col);
3963 colors->rgbRed = GetRValue(col);
3964 colors->rgbReserved = 0;
3972 /**************************************************************************
3973 * X11DRV_DIB_CreateDIBFromPixmap
3975 * Allocates a packed DIB and copies the Pixmap data into it.
3976 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
3978 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
3981 BITMAPOBJ *pBmp = NULL;
3982 HGLOBAL hPackedDIB = 0;
3984 /* Allocates an HBITMAP which references the Pixmap passed to us */
3985 hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap);
3988 TRACE("\tCould not create bitmap header for Pixmap\n");
3993 * Create a packed DIB from the Pixmap wrapper bitmap created above.
3994 * A packed DIB contains a BITMAPINFO structure followed immediately by
3995 * an optional color palette and the pixel data.
3997 hPackedDIB = DIB_CreateDIBFromBitmap(hdc, hBmp);
3999 /* Get a pointer to the BITMAPOBJ structure */
4000 pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4002 /* We can now get rid of the HBITMAP wrapper we created earlier.
4003 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
4007 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
4008 pBmp->physBitmap = NULL;
4011 GDI_ReleaseObj( hBmp );
4015 TRACE("\tReturning packed DIB %x\n", hPackedDIB);
4020 /**************************************************************************
4021 * X11DRV_DIB_CreatePixmapFromDIB
4023 * Creates a Pixmap from a packed DIB
4025 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
4027 Pixmap pixmap = None;
4029 BITMAPOBJ *pBmp = NULL;
4030 LPBYTE pPackedDIB = NULL;
4031 LPBITMAPINFO pbmi = NULL;
4032 LPBITMAPINFOHEADER pbmiHeader = NULL;
4033 LPBYTE pbits = NULL;
4035 /* Get a pointer to the packed DIB's data */
4036 pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
4037 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
4038 pbmi = (LPBITMAPINFO)pPackedDIB;
4039 pbits = (LPBYTE)(pPackedDIB
4040 + DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
4042 /* Create a DDB from the DIB */
4044 hBmp = CreateDIBitmap(hdc,
4051 GlobalUnlock(hPackedDIB);
4053 TRACE("CreateDIBitmap returned %x\n", hBmp);
4055 /* Retrieve the internal Pixmap from the DDB */
4057 pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4059 pixmap = (Pixmap)pBmp->physBitmap;
4060 /* clear the physBitmap so that we can steal its pixmap */
4061 pBmp->physBitmap = NULL;
4064 /* Delete the DDB we created earlier now that we have stolen its pixmap */
4065 GDI_ReleaseObj( hBmp );
4068 TRACE("\tReturning Pixmap %ld\n", pixmap);