2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <X11/extensions/XShm.h>
26 # ifdef HAVE_SYS_SHM_H
29 # ifdef HAVE_SYS_IPC_H
32 #endif /* defined(HAVE_LIBXXSHM) */
41 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
44 WINE_DECLARE_DEBUG_CHANNEL(x11drv);
46 static int ximageDepthTable[32];
48 /* This structure holds the arguments for DIB_SetImageBits() */
51 X11DRV_PDEVICE *physDev;
54 PALETTEENTRY *palentry;
76 } X11DRV_DIB_IMAGEBITS_DESCR;
81 RLE_EOL = 0, /* End of line */
82 RLE_END = 1, /* End of bitmap */
83 RLE_DELTA = 2 /* Delta */
86 /***********************************************************************
87 * X11DRV_DIB_GetXImageWidthBytes
89 * Return the width of an X image in bytes
91 inline static int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
93 if (!depth || depth > 32) goto error;
95 if (!ximageDepthTable[depth-1])
97 XImage *testimage = XCreateImage( gdi_display, visual, depth,
98 ZPixmap, 0, NULL, 1, 1, 32, 20 );
101 ximageDepthTable[depth-1] = testimage->bits_per_pixel;
102 XDestroyImage( testimage );
104 else ximageDepthTable[depth-1] = -1;
106 if (ximageDepthTable[depth-1] != -1)
107 return (4 * ((width * ximageDepthTable[depth-1] + 31) / 32));
110 WARN( "(%d): Unsupported depth\n", depth );
115 /***********************************************************************
116 * X11DRV_DIB_GetDIBWidthBytes
118 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
120 static int X11DRV_DIB_GetDIBWidthBytes( int width, int depth )
126 case 1: words = (width + 31) / 32; break;
127 case 4: words = (width + 7) / 8; break;
128 case 8: words = (width + 3) / 4; break;
130 case 16: words = (width + 1) / 2; break;
131 case 24: words = (width * 3 + 3) / 4; break;
133 WARN("(%d): Unsupported depth\n", depth );
142 /***********************************************************************
143 * X11DRV_DIB_BitmapInfoSize
145 * Return the size of the bitmap info structure including color table.
147 int X11DRV_DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse )
151 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
153 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
154 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
155 return sizeof(BITMAPCOREHEADER) + colors *
156 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
158 else /* assume BITMAPINFOHEADER */
160 colors = info->bmiHeader.biClrUsed;
161 if (!colors && (info->bmiHeader.biBitCount <= 8))
162 colors = 1 << info->bmiHeader.biBitCount;
163 return sizeof(BITMAPINFOHEADER) + colors *
164 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
169 /***********************************************************************
170 * X11DRV_DIB_CreateXImage
174 XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth )
180 width_bytes = X11DRV_DIB_GetXImageWidthBytes( width, depth );
181 image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0,
182 calloc( height, width_bytes ),
183 width, height, 32, width_bytes );
189 /***********************************************************************
192 * Get the info from a bitmap header.
193 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
195 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
196 int *height, WORD *bpp, WORD *compr )
198 if (header->biSize == sizeof(BITMAPCOREHEADER))
200 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
201 *width = core->bcWidth;
202 *height = core->bcHeight;
203 *bpp = core->bcBitCount;
207 if (header->biSize >= sizeof(BITMAPINFOHEADER))
209 *width = header->biWidth;
210 *height = header->biHeight;
211 *bpp = header->biBitCount;
212 *compr = header->biCompression;
215 ERR("(%ld): unknown/wrong size for header\n", header->biSize );
220 /***********************************************************************
221 * X11DRV_DIB_GenColorMap
223 * Fills the color map of a bitmap palette. Should not be called
224 * for a >8-bit deep bitmap.
226 int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
227 WORD coloruse, WORD depth, BOOL quads,
228 const void *colorPtr, int start, int end )
232 if (coloruse == DIB_RGB_COLORS)
234 int max = 1 << depth;
236 if (end > max) end = max;
240 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
242 if (depth == 1) /* Monochrome */
243 for (i = start; i < end; i++, rgb++)
244 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
245 rgb->rgbBlue > 255*3/2);
247 for (i = start; i < end; i++, rgb++)
248 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbRed,
254 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
256 if (depth == 1) /* Monochrome */
257 for (i = start; i < end; i++, rgb++)
258 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
259 rgb->rgbtBlue > 255*3/2);
261 for (i = start; i < end; i++, rgb++)
262 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbtRed,
267 else /* DIB_PAL_COLORS */
270 WORD * index = (WORD *)colorPtr;
272 for (i = start; i < end; i++, index++)
273 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(*index) );
275 for (i = start; i < end; i++)
276 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(i) );
283 /***********************************************************************
284 * X11DRV_DIB_BuildColorMap
286 * Build the color map from the bitmap palette. Should not be called
287 * for a >8-bit deep bitmap.
289 int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
290 const BITMAPINFO *info, int *nColors )
294 const void *colorPtr;
297 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
299 colors = info->bmiHeader.biClrUsed;
300 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
301 colorPtr = info->bmiColors;
303 else /* assume BITMAPCOREINFO */
305 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
306 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
311 ERR("called with >256 colors!\n");
315 /* just so CopyDIBSection doesn't have to create an identity palette */
316 if (coloruse == (WORD)-1) colorPtr = NULL;
318 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
319 colors * sizeof(int) )))
323 return X11DRV_DIB_GenColorMap( physDev, colorMapping, coloruse, depth,
324 isInfo, colorPtr, 0, colors);
328 /***********************************************************************
329 * X11DRV_DIB_MapColor
331 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
335 if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
338 for (color = 0; color < nPhysMap; color++)
339 if (physMap[color] == phys)
342 WARN("Strange color %08x\n", phys);
347 /*********************************************************************
348 * X11DRV_DIB_GetNearestIndex
350 * Helper for X11DRV_DIB_GetDIBits.
351 * Returns the nearest colour table index for a given RGB.
352 * Nearest is defined by minimizing the sum of the squares.
354 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
356 INT i, best = -1, diff, bestdiff = -1;
359 for(color = colormap, i = 0; i < numColors; color++, i++) {
360 diff = (r - color->rgbRed) * (r - color->rgbRed) +
361 (g - color->rgbGreen) * (g - color->rgbGreen) +
362 (b - color->rgbBlue) * (b - color->rgbBlue);
365 if(best == -1 || diff < bestdiff) {
372 /*********************************************************************
373 * X11DRV_DIB_MaskToShift
375 * Helper for X11DRV_DIB_GetDIBits.
376 * Returns the by how many bits to shift a given color so that it is
377 * in the proper position.
379 INT X11DRV_DIB_MaskToShift(DWORD mask)
387 while ((mask&1)==0) {
394 /***********************************************************************
395 * X11DRV_DIB_SetImageBits_1
397 * SetDIBits for a 1-bit deep DIB.
399 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
400 DWORD srcwidth, DWORD dstwidth, int left,
401 int *colors, XImage *bmpImage, DWORD linebytes)
410 srcbits = srcbits + linebytes * (lines - 1);
411 linebytes = -linebytes;
414 if ((extra = (left & 7)) != 0) {
418 srcbits += left >> 3;
420 /* ==== pal 1 dib -> any bmp format ==== */
421 for (h = lines-1; h >=0; h--) {
423 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
424 for (i = dstwidth/8, x = left; i > 0; i--) {
426 XPutPixel( bmpImage, x++, h, colors[ srcval >> 7] );
427 XPutPixel( bmpImage, x++, h, colors[(srcval >> 6) & 1] );
428 XPutPixel( bmpImage, x++, h, colors[(srcval >> 5) & 1] );
429 XPutPixel( bmpImage, x++, h, colors[(srcval >> 4) & 1] );
430 XPutPixel( bmpImage, x++, h, colors[(srcval >> 3) & 1] );
431 XPutPixel( bmpImage, x++, h, colors[(srcval >> 2) & 1] );
432 XPutPixel( bmpImage, x++, h, colors[(srcval >> 1) & 1] );
433 XPutPixel( bmpImage, x++, h, colors[ srcval & 1] );
437 switch (dstwidth & 7)
439 case 7: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
440 case 6: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
441 case 5: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
442 case 4: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
443 case 3: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
444 case 2: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
445 case 1: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]);
448 srcbits += linebytes;
452 /***********************************************************************
453 * X11DRV_DIB_GetImageBits_1
455 * GetDIBits for a 1-bit deep DIB.
457 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
458 DWORD dstwidth, DWORD srcwidth,
459 RGBQUAD *colors, PALETTEENTRY *srccolors,
460 XImage *bmpImage, DWORD linebytes )
467 dstbits = dstbits + linebytes * (lines - 1);
468 linebytes = -linebytes;
471 switch (bmpImage->depth)
475 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
476 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
479 for (h=lines-1; h>=0; h--) {
483 for (x=0; x<dstwidth; x++) {
485 srcval=srccolors[XGetPixel(bmpImage, x, h)];
486 dstval|=(X11DRV_DIB_GetNearestIndex
490 srcval.peBlue) << (7 - (x & 7)));
496 if ((dstwidth&7)!=0) {
499 dstbits += linebytes;
507 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
508 /* ==== pal 8 bmp -> pal 1 dib ==== */
510 const BYTE* srcpixel;
513 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
515 for (h=0; h<lines; h++) {
520 for (x=0; x<dstwidth; x++) {
522 srcval=srccolors[(int)*srcpixel++];
523 dstval|=(X11DRV_DIB_GetNearestIndex
527 srcval.peBlue) << (7-(x&7)) );
533 if ((dstwidth&7)!=0) {
536 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
537 dstbits += linebytes;
548 const WORD* srcpixel;
551 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
553 if (bmpImage->green_mask==0x03e0) {
554 if (bmpImage->red_mask==0x7c00) {
555 /* ==== rgb 555 bmp -> pal 1 dib ==== */
556 for (h=0; h<lines; h++) {
561 for (x=0; x<dstwidth; x++) {
564 dstval|=(X11DRV_DIB_GetNearestIndex
566 ((srcval >> 7) & 0xf8) | /* r */
567 ((srcval >> 12) & 0x07),
568 ((srcval >> 2) & 0xf8) | /* g */
569 ((srcval >> 7) & 0x07),
570 ((srcval << 3) & 0xf8) | /* b */
571 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
577 if ((dstwidth&7)!=0) {
580 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
581 dstbits += linebytes;
583 } else if (bmpImage->blue_mask==0x7c00) {
584 /* ==== bgr 555 bmp -> pal 1 dib ==== */
585 for (h=0; h<lines; h++) {
590 for (x=0; x<dstwidth; x++) {
593 dstval|=(X11DRV_DIB_GetNearestIndex
595 ((srcval << 3) & 0xf8) | /* r */
596 ((srcval >> 2) & 0x07),
597 ((srcval >> 2) & 0xf8) | /* g */
598 ((srcval >> 7) & 0x07),
599 ((srcval >> 7) & 0xf8) | /* b */
600 ((srcval >> 12) & 0x07) ) << (7-(x&7)) );
606 if ((dstwidth&7)!=0) {
609 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
610 dstbits += linebytes;
615 } else if (bmpImage->green_mask==0x07e0) {
616 if (bmpImage->red_mask==0xf800) {
617 /* ==== rgb 565 bmp -> pal 1 dib ==== */
618 for (h=0; h<lines; h++) {
623 for (x=0; x<dstwidth; x++) {
626 dstval|=(X11DRV_DIB_GetNearestIndex
628 ((srcval >> 8) & 0xf8) | /* r */
629 ((srcval >> 13) & 0x07),
630 ((srcval >> 3) & 0xfc) | /* g */
631 ((srcval >> 9) & 0x03),
632 ((srcval << 3) & 0xf8) | /* b */
633 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
639 if ((dstwidth&7)!=0) {
642 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
643 dstbits += linebytes;
645 } else if (bmpImage->blue_mask==0xf800) {
646 /* ==== bgr 565 bmp -> pal 1 dib ==== */
647 for (h=0; h<lines; h++) {
652 for (x=0; x<dstwidth; x++) {
655 dstval|=(X11DRV_DIB_GetNearestIndex
657 ((srcval << 3) & 0xf8) | /* r */
658 ((srcval >> 2) & 0x07),
659 ((srcval >> 3) & 0xfc) | /* g */
660 ((srcval >> 9) & 0x03),
661 ((srcval >> 8) & 0xf8) | /* b */
662 ((srcval >> 13) & 0x07) ) << (7-(x&7)) );
668 if ((dstwidth&7)!=0) {
671 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
672 dstbits += linebytes;
691 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
692 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
694 if (bmpImage->green_mask!=0x00ff00 ||
695 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
697 } else if (bmpImage->blue_mask==0xff) {
698 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
699 for (h=0; h<lines; h++) {
704 for (x=0; x<dstwidth; x++) {
705 dstval|=(X11DRV_DIB_GetNearestIndex
709 srcbyte[0]) << (7-(x&7)) );
710 srcbyte+=bytes_per_pixel;
716 if ((dstwidth&7)!=0) {
719 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
720 dstbits += linebytes;
723 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
724 for (h=0; h<lines; h++) {
729 for (x=0; x<dstwidth; x++) {
730 dstval|=(X11DRV_DIB_GetNearestIndex
734 srcbyte[2]) << (7-(x&7)) );
735 srcbyte+=bytes_per_pixel;
741 if ((dstwidth&7)!=0) {
744 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
745 dstbits += linebytes;
755 unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
757 /* ==== any bmp format -> pal 1 dib ==== */
758 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
759 bmpImage->bits_per_pixel, bmpImage->red_mask,
760 bmpImage->green_mask, bmpImage->blue_mask );
762 for (h=lines-1; h>=0; h--) {
766 for (x=0; x<dstwidth; x++) {
767 dstval|=(XGetPixel( bmpImage, x, h) >= white) << (7 - (x&7));
773 if ((dstwidth&7)!=0) {
776 dstbits += linebytes;
783 /***********************************************************************
784 * X11DRV_DIB_SetImageBits_4
786 * SetDIBits for a 4-bit deep DIB.
788 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
789 DWORD srcwidth, DWORD dstwidth, int left,
790 int *colors, XImage *bmpImage, DWORD linebytes)
798 srcbits = srcbits + linebytes * (lines - 1);
799 linebytes = -linebytes;
806 srcbits += left >> 1;
808 /* ==== pal 4 dib -> any bmp format ==== */
809 for (h = lines-1; h >= 0; h--) {
811 for (i = dstwidth/2, x = left; i > 0; i--) {
812 BYTE srcval=*srcbyte++;
813 XPutPixel( bmpImage, x++, h, colors[srcval >> 4] );
814 XPutPixel( bmpImage, x++, h, colors[srcval & 0x0f] );
817 XPutPixel( bmpImage, x, h, colors[*srcbyte >> 4] );
818 srcbits += linebytes;
824 /***********************************************************************
825 * X11DRV_DIB_GetImageBits_4
827 * GetDIBits for a 4-bit deep DIB.
829 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
830 DWORD srcwidth, DWORD dstwidth,
831 RGBQUAD *colors, PALETTEENTRY *srccolors,
832 XImage *bmpImage, DWORD linebytes )
841 dstbits = dstbits + ( linebytes * (lines-1) );
842 linebytes = -linebytes;
847 switch (bmpImage->depth) {
850 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
851 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
854 for (h = lines-1; h >= 0; h--) {
858 for (x = 0; x < dstwidth; x++) {
860 srcval=srccolors[XGetPixel(bmpImage, x, h)];
861 dstval|=(X11DRV_DIB_GetNearestIndex
865 srcval.peBlue) << (4-((x&1)<<2)));
871 if ((dstwidth&1)!=0) {
874 dstbits += linebytes;
882 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
883 /* ==== pal 8 bmp -> pal 4 dib ==== */
885 const BYTE *srcpixel;
888 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
889 for (h=0; h<lines; h++) {
894 for (x=0; x<dstwidth; x++) {
896 srcval = srccolors[(int)*srcpixel++];
897 dstval|=(X11DRV_DIB_GetNearestIndex
901 srcval.peBlue) << (4*(1-(x&1))) );
907 if ((dstwidth&1)!=0) {
910 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
911 dstbits += linebytes;
922 const WORD* srcpixel;
925 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
927 if (bmpImage->green_mask==0x03e0) {
928 if (bmpImage->red_mask==0x7c00) {
929 /* ==== rgb 555 bmp -> pal 4 dib ==== */
930 for (h=0; h<lines; h++) {
935 for (x=0; x<dstwidth; x++) {
938 dstval|=(X11DRV_DIB_GetNearestIndex
940 ((srcval >> 7) & 0xf8) | /* r */
941 ((srcval >> 12) & 0x07),
942 ((srcval >> 2) & 0xf8) | /* g */
943 ((srcval >> 7) & 0x07),
944 ((srcval << 3) & 0xf8) | /* b */
945 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
951 if ((dstwidth&1)!=0) {
954 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
955 dstbits += linebytes;
957 } else if (bmpImage->blue_mask==0x7c00) {
958 /* ==== bgr 555 bmp -> pal 4 dib ==== */
959 for (h=0; h<lines; h++) {
964 for (x=0; x<dstwidth; x++) {
967 dstval|=(X11DRV_DIB_GetNearestIndex
969 ((srcval << 3) & 0xf8) | /* r */
970 ((srcval >> 2) & 0x07),
971 ((srcval >> 2) & 0xf8) | /* g */
972 ((srcval >> 7) & 0x07),
973 ((srcval >> 7) & 0xf8) | /* b */
974 ((srcval >> 12) & 0x07) ) << ((1-(x&1))<<2) );
980 if ((dstwidth&1)!=0) {
983 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
984 dstbits += linebytes;
989 } else if (bmpImage->green_mask==0x07e0) {
990 if (bmpImage->red_mask==0xf800) {
991 /* ==== rgb 565 bmp -> pal 4 dib ==== */
992 for (h=0; h<lines; h++) {
997 for (x=0; x<dstwidth; x++) {
1000 dstval|=(X11DRV_DIB_GetNearestIndex
1002 ((srcval >> 8) & 0xf8) | /* r */
1003 ((srcval >> 13) & 0x07),
1004 ((srcval >> 3) & 0xfc) | /* g */
1005 ((srcval >> 9) & 0x03),
1006 ((srcval << 3) & 0xf8) | /* b */
1007 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
1013 if ((dstwidth&1)!=0) {
1016 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1017 dstbits += linebytes;
1019 } else if (bmpImage->blue_mask==0xf800) {
1020 /* ==== bgr 565 bmp -> pal 4 dib ==== */
1021 for (h=0; h<lines; h++) {
1026 for (x=0; x<dstwidth; x++) {
1029 dstval|=(X11DRV_DIB_GetNearestIndex
1031 ((srcval << 3) & 0xf8) | /* r */
1032 ((srcval >> 2) & 0x07),
1033 ((srcval >> 3) & 0xfc) | /* g */
1034 ((srcval >> 9) & 0x03),
1035 ((srcval >> 8) & 0xf8) | /* b */
1036 ((srcval >> 13) & 0x07) ) << ((1-(x&1))<<2) );
1042 if ((dstwidth&1)!=0) {
1045 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1046 dstbits += linebytes;
1058 if (bmpImage->bits_per_pixel==24) {
1059 const void* srcbits;
1060 const BYTE *srcbyte;
1063 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1065 if (bmpImage->green_mask!=0x00ff00 ||
1066 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1068 } else if (bmpImage->blue_mask==0xff) {
1069 /* ==== rgb 888 bmp -> pal 4 dib ==== */
1070 for (h=0; h<lines; h++) {
1073 for (x=0; x<dstwidth/2; x++) {
1074 /* Do 2 pixels at a time */
1075 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1080 X11DRV_DIB_GetNearestIndex
1088 /* And the the odd pixel */
1089 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1095 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1096 dstbits += linebytes;
1099 /* ==== bgr 888 bmp -> pal 4 dib ==== */
1100 for (h=0; h<lines; h++) {
1103 for (x=0; x<dstwidth/2; x++) {
1104 /* Do 2 pixels at a time */
1105 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1110 X11DRV_DIB_GetNearestIndex
1118 /* And the the odd pixel */
1119 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1125 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1126 dstbits += linebytes;
1135 const void* srcbits;
1136 const BYTE *srcbyte;
1139 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1141 if (bmpImage->green_mask!=0x00ff00 ||
1142 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1144 } else if (bmpImage->blue_mask==0xff) {
1145 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
1146 for (h=0; h<lines; h++) {
1149 for (x=0; x<dstwidth/2; x++) {
1150 /* Do 2 pixels at a time */
1151 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1156 X11DRV_DIB_GetNearestIndex
1164 /* And the the odd pixel */
1165 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1171 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1172 dstbits += linebytes;
1175 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
1176 for (h=0; h<lines; h++) {
1179 for (x=0; x<dstwidth/2; x++) {
1180 /* Do 2 pixels at a time */
1181 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1186 X11DRV_DIB_GetNearestIndex
1194 /* And the the odd pixel */
1195 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1201 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1202 dstbits += linebytes;
1213 /* ==== any bmp format -> pal 4 dib ==== */
1214 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
1215 bmpImage->bits_per_pixel, bmpImage->red_mask,
1216 bmpImage->green_mask, bmpImage->blue_mask );
1217 for (h=lines-1; h>=0; h--) {
1219 for (x=0; x<(dstwidth & ~1); x+=2) {
1220 *dstbyte++=(X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4) |
1221 X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x+1, h), 0);
1224 *dstbyte=(X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4);
1226 dstbits += linebytes;
1233 /***********************************************************************
1234 * X11DRV_DIB_SetImageBits_RLE4
1236 * SetDIBits for a 4-bit deep compressed DIB.
1238 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
1239 DWORD width, DWORD dstwidth,
1240 int left, int *colors,
1244 int y = lines - 1, c, length;
1245 const BYTE *begin = bits;
1250 if (length) { /* encoded */
1253 if (x >= width) break;
1254 XPutPixel(bmpImage, x++, y, colors[c >> 4]);
1255 if (!length--) break;
1256 if (x >= width) break;
1257 XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
1276 default: /* absolute */
1279 if (x < width) XPutPixel(bmpImage, x++, y, colors[c >> 4]);
1280 if (!length--) break;
1281 if (x < width) XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
1283 if ((bits - begin) & 1)
1292 /***********************************************************************
1293 * X11DRV_DIB_SetImageBits_8
1295 * SetDIBits for an 8-bit deep DIB.
1297 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
1298 DWORD srcwidth, DWORD dstwidth, int left,
1299 const int *colors, XImage *bmpImage,
1304 const BYTE* srcbyte;
1310 srcbits = srcbits + linebytes * (lines-1);
1311 linebytes = -linebytes;
1316 switch (bmpImage->depth) {
1319 #if defined(__i386__) && defined(__GNUC__)
1320 /* Some X servers might have 32 bit/ 16bit deep pixel */
1321 if (lines && dstwidth && (bmpImage->bits_per_pixel == 16) &&
1322 (ImageByteOrder(gdi_display)==LSBFirst) )
1324 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
1325 /* FIXME: Does this really handle all these cases correctly? */
1326 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
1327 for (h = lines ; h--; ) {
1328 int _cl1,_cl2; /* temp outputs for asm below */
1329 /* Borrowed from DirectDraw */
1330 __asm__ __volatile__(
1335 " movw (%%edx,%%eax,4),%%ax\n"
1337 " xor %%eax,%%eax\n"
1339 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
1344 :"eax", "cc", "memory"
1346 srcbyte = (srcbits += linebytes);
1347 dstbits -= bmpImage->bytes_per_line;
1355 #if defined(__i386__) && defined(__GNUC__)
1356 if (lines && dstwidth && (bmpImage->bits_per_pixel == 32) &&
1357 (ImageByteOrder(gdi_display)==LSBFirst) )
1359 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
1360 /* FIXME: Does this really handle both cases correctly? */
1361 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
1362 for (h = lines ; h--; ) {
1363 int _cl1,_cl2; /* temp outputs for asm below */
1364 /* Borrowed from DirectDraw */
1365 __asm__ __volatile__(
1370 " movl (%%edx,%%eax,4),%%eax\n"
1372 " xor %%eax,%%eax\n"
1374 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
1379 :"eax", "cc", "memory"
1381 srcbyte = (srcbits += linebytes);
1382 dstbits -= bmpImage->bytes_per_line;
1389 break; /* use slow generic case below */
1392 /* ==== pal 8 dib -> any bmp format ==== */
1393 for (h=lines-1; h>=0; h--) {
1394 for (x=left; x<dstwidth+left; x++) {
1395 XPutPixel(bmpImage, x, h, colors[*srcbyte++]);
1397 srcbyte = (srcbits += linebytes);
1401 /***********************************************************************
1402 * X11DRV_DIB_GetImageBits_8
1404 * GetDIBits for an 8-bit deep DIB.
1406 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
1407 DWORD srcwidth, DWORD dstwidth,
1408 RGBQUAD *colors, PALETTEENTRY *srccolors,
1409 XImage *bmpImage, DWORD linebytes )
1418 dstbits = dstbits + ( linebytes * (lines-1) );
1419 linebytes = -linebytes;
1424 * This condition is true when GetImageBits has been called by
1425 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
1426 * 256 colormaps, so we'll just use for for GetDIBits calls.
1427 * (In somes cases, in a updateDIBSection, the returned colors are bad too)
1429 if (!srccolors) goto updatesection;
1431 switch (bmpImage->depth) {
1434 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1436 /* ==== pal 1 bmp -> pal 8 dib ==== */
1437 /* ==== pal 4 bmp -> pal 8 dib ==== */
1438 for (h=lines-1; h>=0; h--) {
1440 for (x=0; x<dstwidth; x++) {
1441 PALETTEENTRY srcval;
1442 srcval=srccolors[XGetPixel(bmpImage, x, h)];
1443 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
1448 dstbits += linebytes;
1456 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1457 /* ==== pal 8 bmp -> pal 8 dib ==== */
1458 const void* srcbits;
1459 const BYTE* srcpixel;
1461 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1462 for (h=0; h<lines; h++) {
1465 for (x = 0; x < dstwidth; x++) {
1466 PALETTEENTRY srcval;
1467 srcval=srccolors[(int)*srcpixel++];
1468 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
1473 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1474 dstbits += linebytes;
1484 const void* srcbits;
1485 const WORD* srcpixel;
1488 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1490 if (bmpImage->green_mask==0x03e0) {
1491 if (bmpImage->red_mask==0x7c00) {
1492 /* ==== rgb 555 bmp -> pal 8 dib ==== */
1493 for (h=0; h<lines; h++) {
1496 for (x=0; x<dstwidth; x++) {
1499 *dstbyte++=X11DRV_DIB_GetNearestIndex
1501 ((srcval >> 7) & 0xf8) | /* r */
1502 ((srcval >> 12) & 0x07),
1503 ((srcval >> 2) & 0xf8) | /* g */
1504 ((srcval >> 7) & 0x07),
1505 ((srcval << 3) & 0xf8) | /* b */
1506 ((srcval >> 2) & 0x07) );
1508 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1509 dstbits += linebytes;
1511 } else if (bmpImage->blue_mask==0x7c00) {
1512 /* ==== bgr 555 bmp -> pal 8 dib ==== */
1513 for (h=0; h<lines; h++) {
1516 for (x=0; x<dstwidth; x++) {
1519 *dstbyte++=X11DRV_DIB_GetNearestIndex
1521 ((srcval << 3) & 0xf8) | /* r */
1522 ((srcval >> 2) & 0x07),
1523 ((srcval >> 2) & 0xf8) | /* g */
1524 ((srcval >> 7) & 0x07),
1525 ((srcval >> 7) & 0xf8) | /* b */
1526 ((srcval >> 12) & 0x07) );
1528 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1529 dstbits += linebytes;
1534 } else if (bmpImage->green_mask==0x07e0) {
1535 if (bmpImage->red_mask==0xf800) {
1536 /* ==== rgb 565 bmp -> pal 8 dib ==== */
1537 for (h=0; h<lines; h++) {
1540 for (x=0; x<dstwidth; x++) {
1543 *dstbyte++=X11DRV_DIB_GetNearestIndex
1545 ((srcval >> 8) & 0xf8) | /* r */
1546 ((srcval >> 13) & 0x07),
1547 ((srcval >> 3) & 0xfc) | /* g */
1548 ((srcval >> 9) & 0x03),
1549 ((srcval << 3) & 0xf8) | /* b */
1550 ((srcval >> 2) & 0x07) );
1552 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1553 dstbits += linebytes;
1555 } else if (bmpImage->blue_mask==0xf800) {
1556 /* ==== bgr 565 bmp -> pal 8 dib ==== */
1557 for (h=0; h<lines; h++) {
1560 for (x=0; x<dstwidth; x++) {
1563 *dstbyte++=X11DRV_DIB_GetNearestIndex
1565 ((srcval << 3) & 0xf8) | /* r */
1566 ((srcval >> 2) & 0x07),
1567 ((srcval >> 3) & 0xfc) | /* g */
1568 ((srcval >> 9) & 0x03),
1569 ((srcval >> 8) & 0xf8) | /* b */
1570 ((srcval >> 13) & 0x07) );
1572 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1573 dstbits += linebytes;
1587 const void* srcbits;
1588 const BYTE *srcbyte;
1590 int bytes_per_pixel;
1592 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1593 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
1595 if (bmpImage->green_mask!=0x00ff00 ||
1596 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1598 } else if (bmpImage->blue_mask==0xff) {
1599 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
1600 for (h=0; h<lines; h++) {
1603 for (x=0; x<dstwidth; x++) {
1604 *dstbyte++=X11DRV_DIB_GetNearestIndex
1609 srcbyte+=bytes_per_pixel;
1611 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1612 dstbits += linebytes;
1615 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
1616 for (h=0; h<lines; h++) {
1619 for (x=0; x<dstwidth; x++) {
1620 *dstbyte++=X11DRV_DIB_GetNearestIndex
1625 srcbyte+=bytes_per_pixel;
1627 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1628 dstbits += linebytes;
1636 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
1637 bmpImage->depth, bmpImage->red_mask,
1638 bmpImage->green_mask, bmpImage->blue_mask );
1640 /* ==== any bmp format -> pal 8 dib ==== */
1641 for (h=lines-1; h>=0; h--) {
1643 for (x=0; x<dstwidth; x++) {
1644 *dstbyte=X11DRV_DIB_MapColor
1646 XGetPixel(bmpImage, x, h), *dstbyte);
1649 dstbits += linebytes;
1655 /***********************************************************************
1656 * X11DRV_DIB_SetImageBits_RLE8
1658 * SetDIBits for an 8-bit deep compressed DIB.
1660 * This function rewritten 941113 by James Youngman. WINE blew out when I
1661 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1663 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1664 * 'End of bitmap' escape code. This code is very much laxer in what it
1665 * allows to end the expansion. Possibly too lax. See the note by
1666 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1667 * bitmap should end with RleEnd, but on the other hand, software exists
1668 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1671 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1672 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1675 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
1676 DWORD width, DWORD dstwidth,
1677 int left, int *colors,
1680 unsigned int x; /* X-position on each line. Increases. */
1681 int y; /* Line #. Starts at lines-1, decreases */
1682 const BYTE *pIn = bits; /* Pointer to current position in bits */
1683 BYTE length; /* The length pf a run */
1684 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
1687 * Note that the bitmap data is stored by Windows starting at the
1688 * bottom line of the bitmap and going upwards. Within each line,
1689 * the data is stored left-to-right. That's the reason why line
1690 * goes from lines-1 to 0. [JAY]
1700 * If the length byte is not zero (which is the escape value),
1701 * We have a run of length pixels all the same colour. The colour
1702 * index is stored next.
1704 * If the length byte is zero, we need to read the next byte to
1705 * know what to do. [JAY]
1710 * [Run-Length] Encoded mode
1712 int color = colors[*pIn++];
1713 while (length-- && x < dstwidth) XPutPixel(bmpImage, x++, y, color);
1718 * Escape codes (may be an absolute sequence though)
1720 escape_code = (*pIn++);
1729 /* Not all RLE8 bitmaps end with this code. For
1730 * example, Paint Shop Pro produces some that don't.
1731 * That's (I think) what caused the previous
1732 * implementation to fail. [JAY]
1741 default: /* switch to absolute mode */
1742 length = escape_code;
1745 int color = colors[*pIn++];
1751 XPutPixel(bmpImage, x++, y, color);
1754 * If you think for a moment you'll realise that the
1755 * only time we could ever possibly read an odd
1756 * number of bytes is when there is a 0x00 (escape),
1757 * a value >0x02 (absolute mode) and then an odd-
1758 * length run. Therefore this is the only place we
1759 * need to worry about it. Everywhere else the
1760 * bytes are always read in pairs. [JAY]
1762 if (escape_code & 1) pIn++; /* Throw away the pad byte. */
1764 } /* switch (escape_code) : Escape sequence */
1770 /***********************************************************************
1771 * X11DRV_DIB_SetImageBits_16
1773 * SetDIBits for a 16-bit deep DIB.
1775 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
1776 DWORD srcwidth, DWORD dstwidth, int left,
1777 X11DRV_PDEVICE *physDev, DWORD rSrc, DWORD gSrc, DWORD bSrc,
1778 XImage *bmpImage, DWORD linebytes )
1782 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_byteswap;
1787 srcbits = srcbits + ( linebytes * (lines-1));
1788 linebytes = -linebytes;
1791 switch (bmpImage->depth)
1798 srcbits=srcbits+left*2;
1799 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
1801 if (bmpImage->green_mask==0x03e0) {
1802 if (gSrc==bmpImage->green_mask) {
1803 if (rSrc==bmpImage->red_mask) {
1804 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
1805 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
1806 convs->Convert_5x5_asis
1809 dstbits,-bmpImage->bytes_per_line);
1810 } else if (rSrc==bmpImage->blue_mask) {
1811 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
1812 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
1813 convs->Convert_555_reverse
1816 dstbits,-bmpImage->bytes_per_line);
1819 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
1820 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
1821 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
1822 convs->Convert_565_to_555_asis
1825 dstbits,-bmpImage->bytes_per_line);
1827 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
1828 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
1829 convs->Convert_565_to_555_reverse
1832 dstbits,-bmpImage->bytes_per_line);
1835 } else if (bmpImage->green_mask==0x07e0) {
1836 if (gSrc==bmpImage->green_mask) {
1837 if (rSrc==bmpImage->red_mask) {
1838 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
1839 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
1840 convs->Convert_5x5_asis
1843 dstbits,-bmpImage->bytes_per_line);
1845 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
1846 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
1847 convs->Convert_565_reverse
1850 dstbits,-bmpImage->bytes_per_line);
1853 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
1854 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
1855 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
1856 convs->Convert_555_to_565_asis
1859 dstbits,-bmpImage->bytes_per_line);
1861 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
1862 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
1863 convs->Convert_555_to_565_reverse
1866 dstbits,-bmpImage->bytes_per_line);
1876 if (bmpImage->bits_per_pixel==24) {
1879 srcbits=srcbits+left*2;
1880 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
1882 if (bmpImage->green_mask!=0x00ff00 ||
1883 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1885 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
1886 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
1888 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
1889 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
1890 convs->Convert_555_to_888_asis
1893 dstbits,-bmpImage->bytes_per_line);
1895 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
1896 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
1897 convs->Convert_565_to_888_asis
1900 dstbits,-bmpImage->bytes_per_line);
1904 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
1905 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
1906 convs->Convert_555_to_888_reverse
1909 dstbits,-bmpImage->bytes_per_line);
1911 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
1912 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
1913 convs->Convert_565_to_888_reverse
1916 dstbits,-bmpImage->bytes_per_line);
1927 srcbits=srcbits+left*2;
1928 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
1930 if (bmpImage->green_mask!=0x00ff00 ||
1931 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1933 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
1934 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
1936 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
1937 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
1938 convs->Convert_555_to_0888_asis
1941 dstbits,-bmpImage->bytes_per_line);
1943 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
1944 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
1945 convs->Convert_565_to_0888_asis
1948 dstbits,-bmpImage->bytes_per_line);
1952 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
1953 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
1954 convs->Convert_555_to_0888_reverse
1957 dstbits,-bmpImage->bytes_per_line);
1959 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
1960 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
1961 convs->Convert_565_to_0888_reverse
1964 dstbits,-bmpImage->bytes_per_line);
1972 WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
1973 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
1974 bmpImage->green_mask, bmpImage->blue_mask );
1980 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
1981 const WORD* srcpixel;
1982 int rShift1,gShift1,bShift1;
1983 int rShift2,gShift2,bShift2;
1986 /* Set color scaling values */
1987 rShift1=16+X11DRV_DIB_MaskToShift(rSrc)-3;
1988 gShift1=16+X11DRV_DIB_MaskToShift(gSrc)-3;
1989 bShift1=16+X11DRV_DIB_MaskToShift(bSrc)-3;
1994 /* Green has 5 bits, like the others */
1998 /* Green has 6 bits, not 5. Compensate. */
2007 /* We could split it into four separate cases to optimize
2008 * but it is probably not worth it.
2010 for (h=lines-1; h>=0; h--) {
2011 srcpixel=(const WORD*)srcbits;
2012 for (x=left; x<dstwidth+left; x++) {
2014 BYTE red,green,blue;
2015 srcval=*srcpixel++ << 16;
2016 red= ((srcval >> rShift1) & 0xf8) |
2017 ((srcval >> rShift2) & 0x07);
2018 green=((srcval >> gShift1) & gMask1) |
2019 ((srcval >> gShift2) & gMask2);
2020 blue= ((srcval >> bShift1) & 0xf8) |
2021 ((srcval >> bShift2) & 0x07);
2022 XPutPixel(bmpImage, x, h,
2023 X11DRV_PALETTE_ToPhysical
2024 (physDev, RGB(red,green,blue)));
2026 srcbits += linebytes;
2034 /***********************************************************************
2035 * X11DRV_DIB_GetImageBits_16
2037 * GetDIBits for an 16-bit deep DIB.
2039 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
2040 DWORD dstwidth, DWORD srcwidth,
2041 PALETTEENTRY *srccolors,
2042 DWORD rDst, DWORD gDst, DWORD bDst,
2043 XImage *bmpImage, DWORD dibpitch )
2047 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_byteswap;
2049 DWORD linebytes = dibpitch;
2054 dstbits = dstbits + ( linebytes * (lines-1));
2055 linebytes = -linebytes;
2058 switch (bmpImage->depth)
2063 const char* srcbits;
2065 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2067 if (bmpImage->green_mask==0x03e0) {
2068 if (gDst==bmpImage->green_mask) {
2069 if (rDst==bmpImage->red_mask) {
2070 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
2071 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
2072 convs->Convert_5x5_asis
2074 srcbits,-bmpImage->bytes_per_line,
2077 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
2078 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
2079 convs->Convert_555_reverse
2081 srcbits,-bmpImage->bytes_per_line,
2085 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
2086 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
2087 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
2088 convs->Convert_555_to_565_asis
2090 srcbits,-bmpImage->bytes_per_line,
2093 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
2094 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
2095 convs->Convert_555_to_565_reverse
2097 srcbits,-bmpImage->bytes_per_line,
2101 } else if (bmpImage->green_mask==0x07e0) {
2102 if (gDst==bmpImage->green_mask) {
2103 if (rDst == bmpImage->red_mask) {
2104 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
2105 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
2106 convs->Convert_5x5_asis
2108 srcbits,-bmpImage->bytes_per_line,
2111 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
2112 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
2113 convs->Convert_565_reverse
2115 srcbits,-bmpImage->bytes_per_line,
2119 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
2120 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
2121 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
2122 convs->Convert_565_to_555_asis
2124 srcbits,-bmpImage->bytes_per_line,
2127 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
2128 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
2129 convs->Convert_565_to_555_reverse
2131 srcbits,-bmpImage->bytes_per_line,
2142 if (bmpImage->bits_per_pixel == 24) {
2143 const char* srcbits;
2145 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2147 if (bmpImage->green_mask!=0x00ff00 ||
2148 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2150 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
2151 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
2153 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
2154 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
2155 convs->Convert_888_to_555_asis
2157 srcbits,-bmpImage->bytes_per_line,
2160 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2161 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2162 convs->Convert_888_to_565_asis
2164 srcbits,-bmpImage->bytes_per_line,
2169 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
2170 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
2171 convs->Convert_888_to_555_reverse
2173 srcbits,-bmpImage->bytes_per_line,
2176 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
2177 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
2178 convs->Convert_888_to_565_reverse
2180 srcbits,-bmpImage->bytes_per_line,
2190 const char* srcbits;
2192 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2194 if (bmpImage->green_mask!=0x00ff00 ||
2195 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2197 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
2198 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
2200 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
2201 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
2202 convs->Convert_0888_to_555_asis
2204 srcbits,-bmpImage->bytes_per_line,
2207 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
2208 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
2209 convs->Convert_0888_to_565_asis
2211 srcbits,-bmpImage->bytes_per_line,
2216 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
2217 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
2218 convs->Convert_0888_to_555_reverse
2220 srcbits,-bmpImage->bytes_per_line,
2223 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
2224 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
2225 convs->Convert_0888_to_565_reverse
2227 srcbits,-bmpImage->bytes_per_line,
2236 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2237 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
2238 int rShift,gShift,bShift;
2241 /* Shift everything 16 bits left so that all shifts are >0,
2242 * even for BGR DIBs. Then a single >> 16 will bring everything
2245 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
2246 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
2247 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
2249 /* 6 bits for the green */
2255 for (h = lines - 1; h >= 0; h--) {
2256 dstpixel=(LPWORD)dstbits;
2257 for (x = 0; x < dstwidth; x++) {
2258 PALETTEENTRY srcval;
2260 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2261 dstval=((srcval.peRed << rShift) & rDst) |
2262 ((srcval.peGreen << gShift) & gDst) |
2263 ((srcval.peBlue << bShift) & bDst);
2264 *dstpixel++=dstval >> 16;
2266 dstbits += linebytes;
2274 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2275 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
2276 int rShift,gShift,bShift;
2277 const BYTE* srcbits;
2278 const BYTE* srcpixel;
2281 /* Shift everything 16 bits left so that all shifts are >0,
2282 * even for BGR DIBs. Then a single >> 16 will bring everything
2285 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
2286 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
2287 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
2289 /* 6 bits for the green */
2295 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2296 for (h=0; h<lines; h++) {
2298 dstpixel=(LPWORD)dstbits;
2299 for (x = 0; x < dstwidth; x++) {
2300 PALETTEENTRY srcval;
2302 srcval=srccolors[(int)*srcpixel++];
2303 dstval=((srcval.peRed << rShift) & rDst) |
2304 ((srcval.peGreen << gShift) & gDst) |
2305 ((srcval.peBlue << bShift) & bDst);
2306 *dstpixel++=dstval >> 16;
2308 srcbits -= bmpImage->bytes_per_line;
2309 dstbits += linebytes;
2319 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
2320 int rShift,gShift,bShift;
2323 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
2324 bmpImage->depth, bmpImage->red_mask,
2325 bmpImage->green_mask, bmpImage->blue_mask,
2328 /* Shift everything 16 bits left so that all shifts are >0,
2329 * even for BGR DIBs. Then a single >> 16 will bring everything
2332 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
2333 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
2334 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
2336 /* 6 bits for the green */
2342 for (h = lines - 1; h >= 0; h--) {
2343 dstpixel=(LPWORD)dstbits;
2344 for (x = 0; x < dstwidth; x++) {
2347 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
2348 dstval=((GetRValue(srcval) << rShift) & rDst) |
2349 ((GetGValue(srcval) << gShift) & gDst) |
2350 ((GetBValue(srcval) << bShift) & bDst);
2351 *dstpixel++=dstval >> 16;
2353 dstbits += linebytes;
2361 /***********************************************************************
2362 * X11DRV_DIB_SetImageBits_24
2364 * SetDIBits for a 24-bit deep DIB.
2366 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
2367 DWORD srcwidth, DWORD dstwidth, int left,
2368 X11DRV_PDEVICE *physDev,
2369 DWORD rSrc, DWORD gSrc, DWORD bSrc,
2370 XImage *bmpImage, DWORD linebytes )
2374 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_byteswap;
2379 srcbits = srcbits + linebytes * (lines - 1);
2380 linebytes = -linebytes;
2383 switch (bmpImage->depth)
2386 if (bmpImage->bits_per_pixel==24) {
2389 srcbits=srcbits+left*3;
2390 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
2392 if (bmpImage->green_mask!=0x00ff00 ||
2393 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2395 } else if (rSrc==bmpImage->red_mask) {
2396 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
2397 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
2398 convs->Convert_888_asis
2401 dstbits,-bmpImage->bytes_per_line);
2403 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
2404 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
2405 convs->Convert_888_reverse
2408 dstbits,-bmpImage->bytes_per_line);
2418 srcbits=srcbits+left*3;
2419 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2421 if (bmpImage->green_mask!=0x00ff00 ||
2422 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2424 } else if (rSrc==bmpImage->red_mask) {
2425 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
2426 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
2427 convs->Convert_888_to_0888_asis
2430 dstbits,-bmpImage->bytes_per_line);
2432 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
2433 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
2434 convs->Convert_888_to_0888_reverse
2437 dstbits,-bmpImage->bytes_per_line);
2447 srcbits=srcbits+left*3;
2448 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2450 if (bmpImage->green_mask==0x03e0) {
2451 if ((rSrc==0xff0000 && bmpImage->red_mask==0x7f00) ||
2452 (bSrc==0xff0000 && bmpImage->blue_mask==0x7f00)) {
2453 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
2454 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
2455 convs->Convert_888_to_555_asis
2458 dstbits,-bmpImage->bytes_per_line);
2459 } else if ((rSrc==0xff && bmpImage->red_mask==0x7f00) ||
2460 (bSrc==0xff && bmpImage->blue_mask==0x7f00)) {
2461 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
2462 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
2463 convs->Convert_888_to_555_reverse
2466 dstbits,-bmpImage->bytes_per_line);
2470 } else if (bmpImage->green_mask==0x07e0) {
2471 if ((rSrc==0xff0000 && bmpImage->red_mask==0xf800) ||
2472 (bSrc==0xff0000 && bmpImage->blue_mask==0xf800)) {
2473 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
2474 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
2475 convs->Convert_888_to_565_asis
2478 dstbits,-bmpImage->bytes_per_line);
2479 } else if ((rSrc==0xff && bmpImage->red_mask==0xf800) ||
2480 (bSrc==0xff && bmpImage->blue_mask==0xf800)) {
2481 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
2482 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
2483 convs->Convert_888_to_565_reverse
2486 dstbits,-bmpImage->bytes_per_line);
2498 WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2499 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
2500 bmpImage->green_mask, bmpImage->blue_mask );
2506 /* ==== rgb 888 dib -> any bmp bormat ==== */
2507 const BYTE* srcbyte;
2509 /* Windows only supports one 24bpp DIB format: RGB888 */
2511 for (h = lines - 1; h >= 0; h--) {
2512 srcbyte=(const BYTE*)srcbits;
2513 for (x = left; x < dstwidth+left; x++) {
2514 XPutPixel(bmpImage, x, h,
2515 X11DRV_PALETTE_ToPhysical
2516 (physDev, RGB(srcbyte[2], srcbyte[1], srcbyte[0])));
2519 srcbits += linebytes;
2527 /***********************************************************************
2528 * X11DRV_DIB_GetImageBits_24
2530 * GetDIBits for an 24-bit deep DIB.
2532 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
2533 DWORD dstwidth, DWORD srcwidth,
2534 PALETTEENTRY *srccolors,
2535 DWORD rDst, DWORD gDst, DWORD bDst,
2536 XImage *bmpImage, DWORD linebytes )
2540 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_byteswap;
2545 dstbits = dstbits + ( linebytes * (lines-1) );
2546 linebytes = -linebytes;
2549 switch (bmpImage->depth)
2552 if (bmpImage->bits_per_pixel==24) {
2553 const char* srcbits;
2555 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2557 if (bmpImage->green_mask!=0x00ff00 ||
2558 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2560 } else if (rDst==bmpImage->red_mask) {
2561 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
2562 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
2563 convs->Convert_888_asis
2565 srcbits,-bmpImage->bytes_per_line,
2568 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
2569 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
2570 convs->Convert_888_reverse
2572 srcbits,-bmpImage->bytes_per_line,
2581 const char* srcbits;
2583 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2585 if (bmpImage->green_mask!=0x00ff00 ||
2586 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2588 } else if (rDst==bmpImage->red_mask) {
2589 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
2590 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
2591 convs->Convert_0888_to_888_asis
2593 srcbits,-bmpImage->bytes_per_line,
2596 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
2597 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
2598 convs->Convert_0888_to_888_reverse
2600 srcbits,-bmpImage->bytes_per_line,
2609 const char* srcbits;
2611 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2613 if (bmpImage->green_mask==0x03e0) {
2614 if ((rDst==0xff0000 && bmpImage->red_mask==0x7f00) ||
2615 (bDst==0xff0000 && bmpImage->blue_mask==0x7f00)) {
2616 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
2617 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
2618 convs->Convert_555_to_888_asis
2620 srcbits,-bmpImage->bytes_per_line,
2622 } else if ((rDst==0xff && bmpImage->red_mask==0x7f00) ||
2623 (bDst==0xff && bmpImage->blue_mask==0x7f00)) {
2624 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
2625 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
2626 convs->Convert_555_to_888_reverse
2628 srcbits,-bmpImage->bytes_per_line,
2633 } else if (bmpImage->green_mask==0x07e0) {
2634 if ((rDst==0xff0000 && bmpImage->red_mask==0xf800) ||
2635 (bDst==0xff0000 && bmpImage->blue_mask==0xf800)) {
2636 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
2637 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
2638 convs->Convert_565_to_888_asis
2640 srcbits,-bmpImage->bytes_per_line,
2642 } else if ((rDst==0xff && bmpImage->red_mask==0xf800) ||
2643 (bDst==0xff && bmpImage->blue_mask==0xf800)) {
2644 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
2645 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
2646 convs->Convert_565_to_888_reverse
2648 srcbits,-bmpImage->bytes_per_line,
2661 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2662 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
2665 /* Windows only supports one 24bpp DIB format: rgb 888 */
2666 for (h = lines - 1; h >= 0; h--) {
2668 for (x = 0; x < dstwidth; x++) {
2669 PALETTEENTRY srcval;
2670 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2671 dstbyte[0]=srcval.peBlue;
2672 dstbyte[1]=srcval.peGreen;
2673 dstbyte[2]=srcval.peRed;
2676 dstbits += linebytes;
2684 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors) {
2685 /* ==== pal 8 bmp -> rgb 888 dib ==== */
2686 const void* srcbits;
2687 const BYTE* srcpixel;
2690 /* Windows only supports one 24bpp DIB format: rgb 888 */
2691 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2692 for (h = lines - 1; h >= 0; h--) {
2695 for (x = 0; x < dstwidth; x++ ) {
2696 PALETTEENTRY srcval;
2697 srcval=srccolors[(int)*srcpixel++];
2698 dstbyte[0]=srcval.peBlue;
2699 dstbyte[1]=srcval.peGreen;
2700 dstbyte[2]=srcval.peRed;
2703 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2704 dstbits += linebytes;
2714 /* ==== any bmp format -> 888 dib ==== */
2717 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
2718 bmpImage->depth, bmpImage->red_mask,
2719 bmpImage->green_mask, bmpImage->blue_mask,
2722 /* Windows only supports one 24bpp DIB format: rgb 888 */
2723 for (h = lines - 1; h >= 0; h--) {
2725 for (x = 0; x < dstwidth; x++) {
2726 COLORREF srcval=X11DRV_PALETTE_ToLogical
2727 (XGetPixel( bmpImage, x, h ));
2728 dstbyte[0]=GetBValue(srcval);
2729 dstbyte[1]=GetGValue(srcval);
2730 dstbyte[2]=GetRValue(srcval);
2733 dstbits += linebytes;
2741 /***********************************************************************
2742 * X11DRV_DIB_SetImageBits_32
2744 * SetDIBits for a 32-bit deep DIB.
2746 static void X11DRV_DIB_SetImageBits_32(int lines, const BYTE *srcbits,
2747 DWORD srcwidth, DWORD dstwidth, int left,
2748 X11DRV_PDEVICE *physDev,
2749 DWORD rSrc, DWORD gSrc, DWORD bSrc,
2755 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_byteswap;
2760 srcbits = srcbits + ( linebytes * (lines-1) );
2761 linebytes = -linebytes;
2764 ptr = (DWORD *) srcbits + left;
2766 switch (bmpImage->depth)
2769 if (bmpImage->bits_per_pixel==24) {
2772 srcbits=srcbits+left*4;
2773 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
2775 if (rSrc==bmpImage->red_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->blue_mask) {
2776 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
2777 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
2778 convs->Convert_0888_to_888_asis
2781 dstbits,-bmpImage->bytes_per_line);
2782 } else if (bmpImage->green_mask!=0x00ff00 ||
2783 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2785 /* the tests below assume sane bmpImage masks */
2786 } else if (rSrc==bmpImage->blue_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->red_mask) {
2787 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
2788 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
2789 convs->Convert_0888_to_888_reverse
2792 dstbits,-bmpImage->bytes_per_line);
2793 } else if (bmpImage->blue_mask==0xff) {
2794 /* ==== any 0888 dib -> rgb 888 bmp ==== */
2795 convs->Convert_any0888_to_rgb888
2799 dstbits,-bmpImage->bytes_per_line);
2801 /* ==== any 0888 dib -> bgr 888 bmp ==== */
2802 convs->Convert_any0888_to_bgr888
2806 dstbits,-bmpImage->bytes_per_line);
2816 srcbits=srcbits+left*4;
2817 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2819 if (gSrc==bmpImage->green_mask) {
2820 if (rSrc==bmpImage->red_mask && bSrc==bmpImage->blue_mask) {
2821 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
2822 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
2823 convs->Convert_0888_asis
2826 dstbits,-bmpImage->bytes_per_line);
2827 } else if (bmpImage->green_mask!=0x00ff00 ||
2828 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2830 /* the tests below assume sane bmpImage masks */
2831 } else if (rSrc==bmpImage->blue_mask && bSrc==bmpImage->red_mask) {
2832 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
2833 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
2834 convs->Convert_0888_reverse
2837 dstbits,-bmpImage->bytes_per_line);
2839 /* ==== any 0888 dib -> any 0888 bmp ==== */
2840 convs->Convert_0888_any
2844 dstbits,-bmpImage->bytes_per_line,
2845 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
2847 } else if (bmpImage->green_mask!=0x00ff00 ||
2848 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2850 /* the tests below assume sane bmpImage masks */
2852 /* ==== any 0888 dib -> any 0888 bmp ==== */
2853 convs->Convert_0888_any
2857 dstbits,-bmpImage->bytes_per_line,
2858 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
2868 srcbits=srcbits+left*4;
2869 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2871 if (rSrc==0xff0000 && gSrc==0x00ff00 && bSrc==0x0000ff) {
2872 if (bmpImage->green_mask==0x03e0) {
2873 if (bmpImage->red_mask==0x7f00) {
2874 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
2875 convs->Convert_0888_to_555_asis
2878 dstbits,-bmpImage->bytes_per_line);
2879 } else if (bmpImage->blue_mask==0x7f00) {
2880 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
2881 convs->Convert_0888_to_555_reverse
2884 dstbits,-bmpImage->bytes_per_line);
2888 } else if (bmpImage->green_mask==0x07e0) {
2889 if (bmpImage->red_mask==0xf800) {
2890 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
2891 convs->Convert_0888_to_565_asis
2894 dstbits,-bmpImage->bytes_per_line);
2895 } else if (bmpImage->blue_mask==0xf800) {
2896 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
2897 convs->Convert_0888_to_565_reverse
2900 dstbits,-bmpImage->bytes_per_line);
2907 } else if (rSrc==0x0000ff && gSrc==0x00ff00 && bSrc==0xff0000) {
2908 if (bmpImage->green_mask==0x03e0) {
2909 if (bmpImage->blue_mask==0x7f00) {
2910 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
2911 convs->Convert_0888_to_555_asis
2914 dstbits,-bmpImage->bytes_per_line);
2915 } else if (bmpImage->red_mask==0x7f00) {
2916 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
2917 convs->Convert_0888_to_555_reverse
2920 dstbits,-bmpImage->bytes_per_line);
2924 } else if (bmpImage->green_mask==0x07e0) {
2925 if (bmpImage->blue_mask==0xf800) {
2926 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
2927 convs->Convert_0888_to_565_asis
2930 dstbits,-bmpImage->bytes_per_line);
2931 } else if (bmpImage->red_mask==0xf800) {
2932 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
2933 convs->Convert_0888_to_565_reverse
2936 dstbits,-bmpImage->bytes_per_line);
2944 if (bmpImage->green_mask==0x03e0 &&
2945 (bmpImage->red_mask==0x7f00 ||
2946 bmpImage->blue_mask==0x7f00)) {
2947 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
2948 convs->Convert_any0888_to_5x5
2952 dstbits,-bmpImage->bytes_per_line,
2953 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
2954 } else if (bmpImage->green_mask==0x07e0 &&
2955 (bmpImage->red_mask==0xf800 ||
2956 bmpImage->blue_mask==0xf800)) {
2957 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
2958 convs->Convert_any0888_to_5x5
2962 dstbits,-bmpImage->bytes_per_line,
2963 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
2973 WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2974 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
2975 bmpImage->green_mask, bmpImage->blue_mask );
2981 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
2982 const DWORD* srcpixel;
2983 int rShift,gShift,bShift;
2985 rShift=X11DRV_DIB_MaskToShift(rSrc);
2986 gShift=X11DRV_DIB_MaskToShift(gSrc);
2987 bShift=X11DRV_DIB_MaskToShift(bSrc);
2989 for (h = lines - 1; h >= 0; h--) {
2990 srcpixel=(const DWORD*)srcbits;
2991 for (x = left; x < dstwidth+left; x++) {
2993 BYTE red,green,blue;
2994 srcvalue=*srcpixel++;
2995 red= (srcvalue >> rShift) & 0xff;
2996 green=(srcvalue >> gShift) & 0xff;
2997 blue= (srcvalue >> bShift) & 0xff;
2998 XPutPixel(bmpImage, x, h, X11DRV_PALETTE_ToPhysical
2999 (physDev, RGB(red,green,blue)));
3001 srcbits += linebytes;
3009 /***********************************************************************
3010 * X11DRV_DIB_GetImageBits_32
3012 * GetDIBits for an 32-bit deep DIB.
3014 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
3015 DWORD dstwidth, DWORD srcwidth,
3016 PALETTEENTRY *srccolors,
3017 DWORD rDst, DWORD gDst, DWORD bDst,
3018 XImage *bmpImage, DWORD linebytes )
3023 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_byteswap;
3028 dstbits = dstbits + ( linebytes * (lines-1) );
3029 linebytes = -linebytes;
3034 switch (bmpImage->depth)
3037 if (bmpImage->bits_per_pixel==24) {
3038 const void* srcbits;
3040 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3042 if (rDst==bmpImage->red_mask && gDst==bmpImage->green_mask && bDst==bmpImage->blue_mask) {
3043 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3044 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3045 convs->Convert_888_to_0888_asis
3047 srcbits,-bmpImage->bytes_per_line,
3049 } else if (bmpImage->green_mask!=0x00ff00 ||
3050 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3052 /* the tests below assume sane bmpImage masks */
3053 } else if (rDst==bmpImage->blue_mask && gDst==bmpImage->green_mask && bDst==bmpImage->red_mask) {
3054 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3055 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3056 convs->Convert_888_to_0888_reverse
3058 srcbits,-bmpImage->bytes_per_line,
3060 } else if (bmpImage->blue_mask==0xff) {
3061 /* ==== rgb 888 bmp -> any 0888 dib ==== */
3062 convs->Convert_rgb888_to_any0888
3064 srcbits,-bmpImage->bytes_per_line,
3068 /* ==== bgr 888 bmp -> any 0888 dib ==== */
3069 convs->Convert_bgr888_to_any0888
3071 srcbits,-bmpImage->bytes_per_line,
3081 const char* srcbits;
3083 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3085 if (gDst==bmpImage->green_mask) {
3086 if (rDst==bmpImage->red_mask && bDst==bmpImage->blue_mask) {
3087 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
3088 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
3089 convs->Convert_0888_asis
3091 srcbits,-bmpImage->bytes_per_line,
3093 } else if (bmpImage->green_mask!=0x00ff00 ||
3094 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3096 /* the tests below assume sane bmpImage masks */
3097 } else if (rDst==bmpImage->blue_mask && bDst==bmpImage->red_mask) {
3098 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
3099 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
3100 convs->Convert_0888_reverse
3102 srcbits,-bmpImage->bytes_per_line,
3105 /* ==== any 0888 bmp -> any 0888 dib ==== */
3106 convs->Convert_0888_any
3108 srcbits,-bmpImage->bytes_per_line,
3109 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3113 } else if (bmpImage->green_mask!=0x00ff00 ||
3114 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3116 /* the tests below assume sane bmpImage masks */
3118 /* ==== any 0888 bmp -> any 0888 dib ==== */
3119 convs->Convert_0888_any
3121 srcbits,-bmpImage->bytes_per_line,
3122 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3132 const char* srcbits;
3134 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3136 if (rDst==0xff0000 && gDst==0x00ff00 && bDst==0x0000ff) {
3137 if (bmpImage->green_mask==0x03e0) {
3138 if (bmpImage->red_mask==0x7f00) {
3139 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
3140 convs->Convert_555_to_0888_asis
3142 srcbits,-bmpImage->bytes_per_line,
3144 } else if (bmpImage->blue_mask==0x7f00) {
3145 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
3146 convs->Convert_555_to_0888_reverse
3148 srcbits,-bmpImage->bytes_per_line,
3153 } else if (bmpImage->green_mask==0x07e0) {
3154 if (bmpImage->red_mask==0xf800) {
3155 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
3156 convs->Convert_565_to_0888_asis
3158 srcbits,-bmpImage->bytes_per_line,
3160 } else if (bmpImage->blue_mask==0xf800) {
3161 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
3162 convs->Convert_565_to_0888_reverse
3164 srcbits,-bmpImage->bytes_per_line,
3172 } else if (rDst==0x0000ff && gDst==0x00ff00 && bDst==0xff0000) {
3173 if (bmpImage->green_mask==0x03e0) {
3174 if (bmpImage->blue_mask==0x7f00) {
3175 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
3176 convs->Convert_555_to_0888_asis
3178 srcbits,-bmpImage->bytes_per_line,
3180 } else if (bmpImage->red_mask==0x7f00) {
3181 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
3182 convs->Convert_555_to_0888_reverse
3184 srcbits,-bmpImage->bytes_per_line,
3189 } else if (bmpImage->green_mask==0x07e0) {
3190 if (bmpImage->blue_mask==0xf800) {
3191 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
3192 convs->Convert_565_to_0888_asis
3194 srcbits,-bmpImage->bytes_per_line,
3196 } else if (bmpImage->red_mask==0xf800) {
3197 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
3198 convs->Convert_565_to_0888_reverse
3200 srcbits,-bmpImage->bytes_per_line,
3209 if (bmpImage->green_mask==0x03e0 &&
3210 (bmpImage->red_mask==0x7f00 ||
3211 bmpImage->blue_mask==0x7f00)) {
3212 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
3213 convs->Convert_5x5_to_any0888
3215 srcbits,-bmpImage->bytes_per_line,
3216 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3219 } else if (bmpImage->green_mask==0x07e0 &&
3220 (bmpImage->red_mask==0xf800 ||
3221 bmpImage->blue_mask==0xf800)) {
3222 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
3223 convs->Convert_5x5_to_any0888
3225 srcbits,-bmpImage->bytes_per_line,
3226 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3238 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3239 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
3240 int rShift,gShift,bShift;
3243 rShift=X11DRV_DIB_MaskToShift(rDst);
3244 gShift=X11DRV_DIB_MaskToShift(gDst);
3245 bShift=X11DRV_DIB_MaskToShift(bDst);
3246 for (h = lines - 1; h >= 0; h--) {
3247 dstpixel=(DWORD*)dstbits;
3248 for (x = 0; x < dstwidth; x++) {
3249 PALETTEENTRY srcval;
3250 srcval = srccolors[XGetPixel(bmpImage, x, h)];
3251 *dstpixel++=(srcval.peRed << rShift) |
3252 (srcval.peGreen << gShift) |
3253 (srcval.peBlue << bShift);
3255 dstbits += linebytes;
3263 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3264 /* ==== pal 8 bmp -> any 0888 dib ==== */
3265 int rShift,gShift,bShift;
3266 const void* srcbits;
3267 const BYTE* srcpixel;
3270 rShift=X11DRV_DIB_MaskToShift(rDst);
3271 gShift=X11DRV_DIB_MaskToShift(gDst);
3272 bShift=X11DRV_DIB_MaskToShift(bDst);
3273 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3274 for (h = lines - 1; h >= 0; h--) {
3276 dstpixel=(DWORD*)dstbits;
3277 for (x = 0; x < dstwidth; x++) {
3278 PALETTEENTRY srcval;
3279 srcval=srccolors[(int)*srcpixel++];
3280 *dstpixel++=(srcval.peRed << rShift) |
3281 (srcval.peGreen << gShift) |
3282 (srcval.peBlue << bShift);
3284 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
3285 dstbits += linebytes;
3295 /* ==== any bmp format -> any 0888 dib ==== */
3296 int rShift,gShift,bShift;
3299 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
3300 bmpImage->depth, bmpImage->red_mask,
3301 bmpImage->green_mask, bmpImage->blue_mask,
3304 rShift=X11DRV_DIB_MaskToShift(rDst);
3305 gShift=X11DRV_DIB_MaskToShift(gDst);
3306 bShift=X11DRV_DIB_MaskToShift(bDst);
3307 for (h = lines - 1; h >= 0; h--) {
3308 dstpixel=(DWORD*)dstbits;
3309 for (x = 0; x < dstwidth; x++) {
3311 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
3312 *dstpixel++=(GetRValue(srcval) << rShift) |
3313 (GetGValue(srcval) << gShift) |
3314 (GetBValue(srcval) << bShift);
3316 dstbits += linebytes;
3323 /***********************************************************************
3324 * X11DRV_DIB_SetImageBits
3326 * Transfer the bits to an X image.
3327 * Helper function for SetDIBits() and SetDIBitsToDevice().
3329 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
3331 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
3336 bmpImage = descr->image;
3338 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
3339 descr->infoWidth, lines, 32, 0 );
3340 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
3341 if(bmpImage->data == NULL) {
3342 ERR("Out of memory!\n");
3343 XDestroyImage( bmpImage );
3344 wine_tsx11_unlock();
3349 TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
3350 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
3351 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
3352 bmpImage->depth,bmpImage->bits_per_pixel,
3353 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
3355 /* Transfer the pixels */
3356 switch(descr->infoBpp)
3359 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
3360 descr->width, descr->xSrc, (int *)(descr->colorMap),
3361 bmpImage, descr->dibpitch );
3364 if (descr->compression) {
3365 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
3366 descr->width, descr->height, AllPlanes, ZPixmap,
3367 bmpImage, descr->xSrc, descr->ySrc );
3369 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
3370 descr->infoWidth, descr->width,
3371 descr->xSrc, (int *)(descr->colorMap),
3374 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
3375 descr->infoWidth, descr->width,
3376 descr->xSrc, (int*)(descr->colorMap),
3377 bmpImage, descr->dibpitch );
3380 if (descr->compression) {
3381 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
3382 descr->width, descr->height, AllPlanes, ZPixmap,
3383 bmpImage, descr->xSrc, descr->ySrc );
3384 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
3385 descr->infoWidth, descr->width,
3386 descr->xSrc, (int *)(descr->colorMap),
3389 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
3390 descr->infoWidth, descr->width,
3391 descr->xSrc, (int *)(descr->colorMap),
3392 bmpImage, descr->dibpitch );
3396 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
3397 descr->infoWidth, descr->width,
3398 descr->xSrc, descr->physDev,
3399 descr->rMask, descr->gMask, descr->bMask,
3400 bmpImage, descr->dibpitch);
3403 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
3404 descr->infoWidth, descr->width,
3405 descr->xSrc, descr->physDev,
3406 descr->rMask, descr->gMask, descr->bMask,
3407 bmpImage, descr->dibpitch);
3410 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
3411 descr->infoWidth, descr->width,
3412 descr->xSrc, descr->physDev,
3413 descr->rMask, descr->gMask, descr->bMask,
3414 bmpImage, descr->dibpitch);
3417 WARN("(%d): Invalid depth\n", descr->infoBpp );
3421 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
3422 descr->drawable, descr->gc, bmpImage,
3423 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
3424 descr->width, descr->height);
3425 #ifdef HAVE_LIBXXSHM
3428 XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
3429 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
3430 descr->width, descr->height, FALSE );
3431 XSync( gdi_display, 0 );
3435 XPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
3436 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
3437 descr->width, descr->height );
3439 if (!descr->image) XDestroyImage( bmpImage );
3440 wine_tsx11_unlock();
3444 /***********************************************************************
3445 * X11DRV_DIB_GetImageBits
3447 * Transfer the bits from an X image.
3449 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
3451 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
3456 bmpImage = descr->image;
3458 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
3459 descr->infoWidth, lines, 32, 0 );
3460 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
3461 if(bmpImage->data == NULL) {
3462 ERR("Out of memory!\n");
3463 XDestroyImage( bmpImage );
3464 wine_tsx11_unlock();
3469 #ifdef HAVE_LIBXXSHM
3472 int saveRed, saveGreen, saveBlue;
3474 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
3475 gdi_display, descr->drawable, bmpImage,
3476 descr->xSrc, descr->ySrc, AllPlanes);
3478 /* We must save and restore the bmpImage's masks in order
3479 * to preserve them across the call to XShmGetImage, which
3480 * decides to eleminate them since it doesn't happen to know
3481 * what the format of the image is supposed to be, even though
3483 saveRed = bmpImage->red_mask;
3484 saveBlue= bmpImage->blue_mask;
3485 saveGreen = bmpImage->green_mask;
3487 XShmGetImage( gdi_display, descr->drawable, bmpImage,
3488 descr->xSrc, descr->ySrc, AllPlanes);
3490 bmpImage->red_mask = saveRed;
3491 bmpImage->blue_mask = saveBlue;
3492 bmpImage->green_mask = saveGreen;
3495 #endif /* HAVE_LIBXXSHM */
3497 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
3498 gdi_display, descr->drawable, descr->xSrc, descr->ySrc, descr->width,
3499 lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
3500 XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc,
3501 descr->width, lines, AllPlanes, ZPixmap,
3502 bmpImage, descr->xDest, descr->yDest );
3505 TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
3506 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
3507 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
3508 bmpImage->depth,bmpImage->bits_per_pixel,
3509 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
3510 /* Transfer the pixels */
3511 switch(descr->infoBpp)
3514 X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
3515 descr->infoWidth, descr->width,
3516 descr->colorMap, descr->palentry,
3517 bmpImage, descr->dibpitch );
3521 if (descr->compression) {
3522 FIXME("Compression not yet supported!\n");
3523 if(descr->sizeImage < X11DRV_DIB_GetDIBWidthBytes( descr->infoWidth, 4 ) * abs(descr->lines))
3526 X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
3527 descr->infoWidth, descr->width,
3528 descr->colorMap, descr->palentry,
3529 bmpImage, descr->dibpitch );
3532 if (descr->compression) {
3533 FIXME("Compression not yet supported!\n");
3534 if(descr->sizeImage < X11DRV_DIB_GetDIBWidthBytes( descr->infoWidth, 8 ) * abs(descr->lines))
3537 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
3538 descr->infoWidth, descr->width,
3539 descr->colorMap, descr->palentry,
3540 bmpImage, descr->dibpitch );
3544 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
3545 descr->infoWidth,descr->width,
3547 descr->rMask, descr->gMask, descr->bMask,
3548 bmpImage, descr->dibpitch );
3552 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
3553 descr->infoWidth,descr->width,
3555 descr->rMask, descr->gMask, descr->bMask,
3556 bmpImage, descr->dibpitch);
3560 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
3561 descr->infoWidth, descr->width,
3563 descr->rMask, descr->gMask, descr->bMask,
3564 bmpImage, descr->dibpitch);
3568 WARN("(%d): Invalid depth\n", descr->infoBpp );
3572 if (!descr->image) XDestroyImage( bmpImage );
3573 wine_tsx11_unlock();
3577 /*************************************************************************
3578 * X11DRV_SetDIBitsToDevice
3581 INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWORD cx,
3582 DWORD cy, INT xSrc, INT ySrc,
3583 UINT startscan, UINT lines, LPCVOID bits,
3584 const BITMAPINFO *info, UINT coloruse )
3586 X11DRV_DIB_IMAGEBITS_DESCR descr;
3593 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
3594 &descr.infoBpp, &descr.compression ) == -1)
3596 top_down = (height < 0);
3597 if (top_down) height = -height;
3601 LPtoDP(physDev->hdc, &pt, 1);
3603 if (!lines || (startscan >= height)) return 0;
3604 if (!top_down && startscan + lines > height) lines = height - startscan;
3606 /* make xSrc,ySrc point to the upper-left corner, not the lower-left one,
3607 * and clamp all values to fit inside [startscan,startscan+lines]
3609 if (ySrc + cy <= startscan + lines)
3611 UINT y = startscan + lines - (ySrc + cy);
3612 if (ySrc < startscan) cy -= (startscan - ySrc);
3615 /* avoid getting unnecessary lines */
3617 if (y >= lines) return 0;
3622 if (y >= lines) return lines;
3623 ySrc = y; /* need to get all lines in top down mode */
3628 if (ySrc >= startscan + lines) return lines;
3629 pt.y += ySrc + cy - (startscan + lines);
3630 cy = startscan + lines - ySrc;
3632 if (cy > lines) cy = lines;
3634 if (xSrc >= width) return lines;
3635 if (xSrc + cx >= width) cx = width - xSrc;
3636 if (!cx || !cy) return lines;
3638 X11DRV_SetupGCForText( physDev ); /* To have the correct colors */
3640 XSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[GetROP2(physDev->hdc) - 1]);
3641 wine_tsx11_unlock();
3643 switch (descr.infoBpp)
3648 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
3649 coloruse == DIB_PAL_COLORS ? physDev : NULL, coloruse,
3650 physDev->depth, info, &descr.nColorMap );
3651 if (!descr.colorMap) return 0;
3652 descr.rMask = descr.gMask = descr.bMask = 0;
3656 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
3657 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
3658 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
3664 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
3665 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
3666 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
3671 descr.physDev = physDev;
3674 descr.palentry = NULL;
3675 descr.lines = top_down ? -lines : lines;
3676 descr.infoWidth = width;
3677 descr.depth = physDev->depth;
3678 descr.drawable = physDev->drawable;
3679 descr.gc = physDev->gc;
3682 descr.xDest = physDev->org.x + pt.x;
3683 descr.yDest = physDev->org.y + pt.y;
3686 descr.useShm = FALSE;
3687 descr.dibpitch = ((width * descr.infoBpp + 31) &~31) / 8;
3689 result = X11DRV_DIB_SetImageBits( &descr );
3691 if (descr.infoBpp <= 8)
3692 HeapFree(GetProcessHeap(), 0, descr.colorMap);
3696 /***********************************************************************
3697 * SetDIBits (X11DRV.@)
3699 INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
3700 UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse )
3702 X11DRV_DIB_IMAGEBITS_DESCR descr;
3704 int height, tmpheight;
3707 descr.physDev = physDev;
3709 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
3710 &descr.infoBpp, &descr.compression ) == -1)
3714 if (height < 0) height = -height;
3715 if (!lines || (startscan >= height))
3718 if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
3720 if (startscan + lines > height) lines = height - startscan;
3722 switch (descr.infoBpp)
3727 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
3728 coloruse == DIB_PAL_COLORS ? descr.physDev : NULL, coloruse,
3729 bmp->bitmap.bmBitsPixel,
3730 info, &descr.nColorMap );
3731 if (!descr.colorMap)
3733 GDI_ReleaseObj( hbitmap );
3736 descr.rMask = descr.gMask = descr.bMask = 0;
3740 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
3741 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
3742 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
3748 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
3749 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
3750 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
3759 descr.palentry = NULL;
3760 descr.lines = tmpheight >= 0 ? lines : -lines;
3761 descr.depth = bmp->bitmap.bmBitsPixel;
3762 descr.drawable = (Pixmap)bmp->physBitmap;
3763 descr.gc = BITMAP_GC(bmp);
3767 descr.yDest = height - startscan - lines;
3768 descr.width = bmp->bitmap.bmWidth;
3769 descr.height = lines;
3770 descr.useShm = FALSE;
3771 descr.dibpitch = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
3772 X11DRV_DIB_Lock(bmp, DIB_Status_GdiMod, FALSE);
3773 result = X11DRV_DIB_SetImageBits( &descr );
3774 X11DRV_DIB_Unlock(bmp, TRUE);
3776 if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);
3778 GDI_ReleaseObj( hbitmap );
3782 /***********************************************************************
3783 * GetDIBits (X11DRV.@)
3785 INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan, UINT lines,
3786 LPVOID bits, BITMAPINFO *info, UINT coloruse )
3788 X11DRV_DIBSECTION *dib;
3789 X11DRV_DIB_IMAGEBITS_DESCR descr;
3790 PALETTEENTRY palette[256];
3794 GetPaletteEntries( GetCurrentObject( physDev->hdc, OBJ_PAL ), 0, 256, palette );
3796 if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
3798 dib = (X11DRV_DIBSECTION *) bmp->dib;
3800 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
3801 lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
3802 (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
3805 if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
3807 height = info->bmiHeader.biHeight;
3808 if (height < 0) height = -height;
3809 if( lines > height ) lines = height;
3810 /* Top-down images have a negative biHeight, the scanlines of theses images
3811 * were inverted in X11DRV_DIB_GetImageBits_xx
3812 * To prevent this we simply change the sign of lines
3813 * (the number of scan lines to copy).
3814 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3816 if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
3818 if( startscan >= bmp->bitmap.bmHeight )
3824 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
3825 &descr.infoBpp, &descr.compression ) == -1)
3831 descr.colorMap = NULL;
3833 switch (descr.infoBpp)
3838 descr.rMask= descr.gMask = descr.bMask = 0;
3839 if(coloruse == DIB_RGB_COLORS)
3840 descr.colorMap = info->bmiColors;
3842 int num_colors = 1 << descr.infoBpp, i;
3845 WORD *index = (WORD*)info->bmiColors;
3846 descr.colorMap = rgb = HeapAlloc(GetProcessHeap(), 0, num_colors * sizeof(RGBQUAD));
3847 for(i = 0; i < num_colors; i++, rgb++, index++) {
3848 colref = X11DRV_PALETTE_ToLogical(X11DRV_PALETTE_ToPhysical(physDev, PALETTEINDEX(*index)));
3849 rgb->rgbRed = GetRValue(colref);
3850 rgb->rgbGreen = GetGValue(colref);
3851 rgb->rgbBlue = GetBValue(colref);
3852 rgb->rgbReserved = 0;
3858 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
3859 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
3860 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
3864 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
3865 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
3866 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
3870 descr.physDev = physDev;
3871 descr.palentry = palette;
3874 descr.lines = lines;
3875 descr.depth = bmp->bitmap.bmBitsPixel;
3876 descr.drawable = (Pixmap)bmp->physBitmap;
3877 descr.gc = BITMAP_GC(bmp);
3878 descr.width = bmp->bitmap.bmWidth;
3879 descr.height = bmp->bitmap.bmHeight;
3883 descr.sizeImage = info->bmiHeader.biSizeImage;
3885 if (descr.lines > 0)
3887 descr.ySrc = (descr.height-1) - (startscan + (lines-1));
3891 descr.ySrc = startscan;
3893 #ifdef HAVE_LIBXXSHM
3894 descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
3896 descr.useShm = FALSE;
3898 descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
3899 : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
3901 X11DRV_DIB_Lock(bmp, DIB_Status_GdiMod, FALSE);
3902 X11DRV_DIB_GetImageBits( &descr );
3903 X11DRV_DIB_Unlock(bmp, TRUE);
3905 if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
3906 info->bmiHeader.biSizeImage = X11DRV_DIB_GetDIBWidthBytes( info->bmiHeader.biWidth,
3907 info->bmiHeader.biBitCount )
3908 * abs( info->bmiHeader.biHeight );
3910 if (descr.compression == BI_BITFIELDS)
3912 *(DWORD *)info->bmiColors = descr.rMask;
3913 *((DWORD *)info->bmiColors+1) = descr.gMask;
3914 *((DWORD *)info->bmiColors+2) = descr.bMask;
3918 /* if RLE or JPEG compression were supported,
3919 * this line would be invalid. */
3920 info->bmiHeader.biCompression = 0;
3923 if(descr.colorMap && descr.colorMap != info->bmiColors)
3924 HeapFree(GetProcessHeap(), 0, descr.colorMap);
3926 GDI_ReleaseObj( hbitmap );
3930 /***********************************************************************
3931 * DIB_DoProtectDIBSection
3933 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
3937 DIBSECTION *dib = bmp->dib;
3938 INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
3939 : -dib->dsBm.bmHeight;
3941 /* use the biSizeImage data as the memory size only if we're dealing with a
3942 compressed image where the value is set. Otherwise, calculate based on
3944 if (dib->dsBmih.biSizeImage &&
3945 (dib->dsBmih.biCompression == BI_RLE4 || dib->dsBmih.biCompression == BI_RLE8))
3946 totalSize = dib->dsBmih.biSizeImage;
3948 totalSize = dib->dsBm.bmWidthBytes * effHeight;
3950 VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
3951 TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
3954 /***********************************************************************
3955 * X11DRV_DIB_DoUpdateDIBSection
3957 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
3958 void *colorMap, int nColorMap,
3960 DWORD xSrc, DWORD ySrc,
3961 DWORD xDest, DWORD yDest,
3962 DWORD width, DWORD height)
3964 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3965 X11DRV_DIB_IMAGEBITS_DESCR descr;
3967 if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
3968 &descr.infoBpp, &descr.compression ) == -1)
3971 descr.physDev = NULL;
3972 descr.palentry = NULL;
3973 descr.image = dib->image;
3974 descr.colorMap = colorMap;
3975 descr.nColorMap = nColorMap;
3976 descr.bits = dib->dibSection.dsBm.bmBits;
3977 descr.depth = bmp->bitmap.bmBitsPixel;
3979 switch (descr.infoBpp)
3984 descr.rMask = descr.gMask = descr.bMask = 0;
3988 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
3989 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
3990 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
3995 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff0000;
3996 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x00ff00;
3997 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x0000ff;
4002 descr.drawable = dest;
4003 descr.gc = BITMAP_GC(bmp);
4006 descr.xDest = xDest;
4007 descr.yDest = yDest;
4008 descr.width = width;
4009 descr.height = height;
4010 descr.sizeImage = 0;
4012 #ifdef HAVE_LIBXXSHM
4013 descr.useShm = (dib->shminfo.shmid != -1);
4015 descr.useShm = FALSE;
4017 descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
4021 TRACE("Copying from Pixmap to DIB bits\n");
4022 X11DRV_DIB_GetImageBits( &descr );
4026 TRACE("Copying from DIB bits to Pixmap\n");
4027 X11DRV_DIB_SetImageBits( &descr );
4031 /***********************************************************************
4032 * X11DRV_DIB_CopyDIBSection
4034 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
4035 DWORD xSrc, DWORD ySrc, DWORD xDest, DWORD yDest,
4036 DWORD width, DWORD height)
4040 int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE;
4042 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", physDevSrc->hdc, physDevDst->hdc,
4043 xSrc, ySrc, xDest, yDest, width, height);
4044 /* this function is meant as an optimization for BitBlt,
4045 * not to be called otherwise */
4046 if (GetObjectType( physDevSrc->hdc ) != OBJ_MEMDC) {
4047 ERR("called for non-memory source DC!?\n");
4051 hBitmap = GetCurrentObject( physDevSrc->hdc, OBJ_BITMAP );
4052 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC );
4053 if (!(bmp && bmp->dib)) {
4054 ERR("called for non-DIBSection!?\n");
4055 GDI_ReleaseObj( hBitmap );
4058 /* while BitBlt should already have made sure we only get
4059 * positive values, we should check for oversize values */
4060 if ((xSrc < bmp->bitmap.bmWidth) &&
4061 (ySrc < bmp->bitmap.bmHeight)) {
4062 if (xSrc + width > bmp->bitmap.bmWidth)
4063 width = bmp->bitmap.bmWidth - xSrc;
4064 if (ySrc + height > bmp->bitmap.bmHeight)
4065 height = bmp->bitmap.bmHeight - ySrc;
4066 /* if the source bitmap is 8bpp or less, we're supposed to use the
4067 * DC's palette for color conversion (not the DIB color table) */
4068 if (bmp->dib->dsBm.bmBitsPixel <= 8) {
4069 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4070 HPALETTE hPalette = GetCurrentObject( physDevSrc->hdc, OBJ_PAL );
4071 if (!hPalette || (hPalette == GetStockObject(DEFAULT_PALETTE))) {
4072 /* HACK: no palette has been set in the source DC,
4073 * use the DIB colormap instead - this is necessary in some
4074 * cases since we need to do depth conversion in some places
4075 * where real Windows can just copy data straight over */
4076 colorMap = dib->colorMap;
4077 nColorMap = dib->nColorMap;
4079 colorMap = X11DRV_DIB_BuildColorMap( physDevSrc, (WORD)-1,
4080 bmp->dib->dsBm.bmBitsPixel,
4081 (BITMAPINFO*)&(bmp->dib->dsBmih),
4083 if (colorMap) aColorMap = TRUE;
4086 /* perform the copy */
4087 X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap,
4088 physDevDst->drawable, xSrc, ySrc,
4089 physDevDst->org.x + xDest, physDevDst->org.y + yDest,
4091 /* free color mapping */
4093 HeapFree(GetProcessHeap(), 0, colorMap);
4095 GDI_ReleaseObj( hBitmap );
4098 /***********************************************************************
4099 * X11DRV_DIB_DoUpdateDIBSection
4101 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
4103 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4104 X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap,
4105 (Drawable)bmp->physBitmap, 0, 0, 0, 0,
4106 bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
4109 /***********************************************************************
4110 * X11DRV_DIB_FaultHandler
4112 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
4117 bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
4118 if (!bmp) return FALSE;
4120 state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
4121 if (state != DIB_Status_InSync) {
4122 /* no way to tell whether app needs read or write yet,
4124 X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
4126 /* hm, apparently the app must have write access */
4127 X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
4129 X11DRV_DIB_Unlock(bmp, TRUE);
4131 GDI_ReleaseObj( (HBITMAP)res );
4135 /***********************************************************************
4138 INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
4140 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4141 INT ret = DIB_Status_None;
4144 EnterCriticalSection(&(dib->lock));
4147 case DIB_Status_GdiMod:
4148 /* GDI access - request to draw on pixmap */
4149 switch (dib->status)
4152 case DIB_Status_None:
4153 dib->p_status = DIB_Status_GdiMod;
4154 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
4157 case DIB_Status_GdiMod:
4158 TRACE("GdiMod requested in status GdiMod\n" );
4161 case DIB_Status_InSync:
4162 TRACE("GdiMod requested in status InSync\n" );
4163 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
4164 dib->status = DIB_Status_GdiMod;
4165 dib->p_status = DIB_Status_InSync;
4168 case DIB_Status_AuxMod:
4169 TRACE("GdiMod requested in status AuxMod\n" );
4170 if (lossy) dib->status = DIB_Status_GdiMod;
4171 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
4172 dib->p_status = DIB_Status_AuxMod;
4173 if (dib->status != DIB_Status_AppMod) {
4174 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
4177 /* fall through if copy_aux() had to change to AppMod state */
4179 case DIB_Status_AppMod:
4180 TRACE("GdiMod requested in status AppMod\n" );
4182 /* make it readonly to avoid app changing data while we copy */
4183 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4184 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
4186 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
4187 dib->p_status = DIB_Status_AppMod;
4188 dib->status = DIB_Status_GdiMod;
4193 case DIB_Status_InSync:
4194 /* App access - request access to read DIB surface */
4195 /* (typically called from signal handler) */
4196 switch (dib->status)
4199 case DIB_Status_None:
4200 /* shouldn't happen from signal handler */
4203 case DIB_Status_AuxMod:
4204 TRACE("InSync requested in status AuxMod\n" );
4205 if (lossy) dib->status = DIB_Status_InSync;
4207 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4208 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
4210 if (dib->status != DIB_Status_GdiMod) {
4211 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4214 /* fall through if copy_aux() had to change to GdiMod state */
4216 case DIB_Status_GdiMod:
4217 TRACE("InSync requested in status GdiMod\n" );
4219 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4220 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
4222 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4223 dib->status = DIB_Status_InSync;
4226 case DIB_Status_InSync:
4227 TRACE("InSync requested in status InSync\n" );
4228 /* shouldn't happen from signal handler */
4231 case DIB_Status_AppMod:
4232 TRACE("InSync requested in status AppMod\n" );
4233 /* no reason to do anything here, and this
4234 * shouldn't happen from signal handler */
4239 case DIB_Status_AppMod:
4240 /* App access - request access to write DIB surface */
4241 /* (typically called from signal handler) */
4242 switch (dib->status)
4245 case DIB_Status_None:
4246 /* shouldn't happen from signal handler */
4249 case DIB_Status_AuxMod:
4250 TRACE("AppMod requested in status AuxMod\n" );
4251 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4252 if (lossy) dib->status = DIB_Status_AppMod;
4253 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
4254 if (dib->status != DIB_Status_GdiMod)
4256 /* fall through if copy_aux() had to change to GdiMod state */
4258 case DIB_Status_GdiMod:
4259 TRACE("AppMod requested in status GdiMod\n" );
4260 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4261 if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
4262 dib->status = DIB_Status_AppMod;
4265 case DIB_Status_InSync:
4266 TRACE("AppMod requested in status InSync\n" );
4267 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4268 dib->status = DIB_Status_AppMod;
4271 case DIB_Status_AppMod:
4272 TRACE("AppMod requested in status AppMod\n" );
4273 /* shouldn't happen from signal handler */
4278 case DIB_Status_AuxMod:
4279 if (dib->status == DIB_Status_None) {
4280 dib->p_status = req;
4282 if (dib->status != DIB_Status_AuxMod)
4283 dib->p_status = dib->status;
4284 dib->status = DIB_Status_AuxMod;
4287 /* it is up to the caller to do the copy/conversion, probably
4288 * using the return value to decide where to copy from */
4290 LeaveCriticalSection(&(dib->lock));
4295 /***********************************************************************
4298 INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
4300 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4301 INT ret = DIB_Status_None;
4304 TRACE("Locking %p from thread %04lx\n", bmp, GetCurrentThreadId());
4305 EnterCriticalSection(&(dib->lock));
4307 if (req != DIB_Status_None)
4308 X11DRV_DIB_Coerce(bmp, req, lossy);
4313 /***********************************************************************
4316 void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
4318 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4321 switch (dib->status)
4324 case DIB_Status_None:
4325 /* in case anyone is wondering, this is the "signal handler doesn't
4326 * work" case, where we always have to be ready for app access */
4328 switch (dib->p_status)
4330 case DIB_Status_AuxMod:
4331 TRACE("Unlocking and syncing from AuxMod\n" );
4332 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
4333 if (dib->status != DIB_Status_None) {
4334 dib->p_status = dib->status;
4335 dib->status = DIB_Status_None;
4337 if (dib->p_status != DIB_Status_GdiMod)
4339 /* fall through if copy_aux() had to change to GdiMod state */
4341 case DIB_Status_GdiMod:
4342 TRACE("Unlocking and syncing from GdiMod\n" );
4343 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
4347 TRACE("Unlocking without needing to sync\n" );
4351 else TRACE("Unlocking with no changes\n");
4352 dib->p_status = DIB_Status_None;
4355 case DIB_Status_GdiMod:
4356 TRACE("Unlocking in status GdiMod\n" );
4357 /* DIB was protected in Coerce */
4359 /* no commit, revert to InSync if applicable */
4360 if ((dib->p_status == DIB_Status_InSync) ||
4361 (dib->p_status == DIB_Status_AppMod)) {
4362 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4363 dib->status = DIB_Status_InSync;
4368 case DIB_Status_InSync:
4369 TRACE("Unlocking in status InSync\n" );
4370 /* DIB was already protected in Coerce */
4373 case DIB_Status_AppMod:
4374 TRACE("Unlocking in status AppMod\n" );
4375 /* DIB was already protected in Coerce */
4376 /* this case is ordinary only called from the signal handler,
4377 * so we don't bother to check for !commit */
4380 case DIB_Status_AuxMod:
4381 TRACE("Unlocking in status AuxMod\n" );
4383 /* DIB may need protection now */
4384 if ((dib->p_status == DIB_Status_InSync) ||
4385 (dib->p_status == DIB_Status_AppMod))
4386 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
4388 /* no commit, revert to previous state */
4389 if (dib->p_status != DIB_Status_None)
4390 dib->status = dib->p_status;
4391 /* no protections changed */
4393 dib->p_status = DIB_Status_None;
4396 LeaveCriticalSection(&(dib->lock));
4397 TRACE("Unlocked %p\n", bmp);
4401 /***********************************************************************
4402 * X11DRV_CoerceDIBSection2
4404 INT X11DRV_CoerceDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
4409 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4410 if (!bmp) return DIB_Status_None;
4411 ret = X11DRV_DIB_Coerce(bmp, req, lossy);
4412 GDI_ReleaseObj( hBmp );
4416 /***********************************************************************
4417 * X11DRV_LockDIBSection2
4419 INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
4424 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4425 if (!bmp) return DIB_Status_None;
4426 ret = X11DRV_DIB_Lock(bmp, req, lossy);
4427 GDI_ReleaseObj( hBmp );
4431 /***********************************************************************
4432 * X11DRV_UnlockDIBSection2
4434 void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
4438 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4440 X11DRV_DIB_Unlock(bmp, commit);
4441 GDI_ReleaseObj( hBmp );
4444 /***********************************************************************
4445 * X11DRV_CoerceDIBSection
4447 INT X11DRV_CoerceDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
4449 if (!physDev) return DIB_Status_None;
4450 return X11DRV_CoerceDIBSection2( GetCurrentObject( physDev->hdc, OBJ_BITMAP ), req, lossy );
4453 /***********************************************************************
4454 * X11DRV_LockDIBSection
4456 INT X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
4458 if (!physDev) return DIB_Status_None;
4459 if (GetObjectType( physDev->hdc ) != OBJ_MEMDC) return DIB_Status_None;
4461 return X11DRV_LockDIBSection2( GetCurrentObject( physDev->hdc, OBJ_BITMAP ), req, lossy );
4464 /***********************************************************************
4465 * X11DRV_UnlockDIBSection
4467 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE *physDev, BOOL commit)
4469 if (!physDev) return;
4470 if (GetObjectType( physDev->hdc ) != OBJ_MEMDC) return;
4472 X11DRV_UnlockDIBSection2( GetCurrentObject( physDev->hdc, OBJ_BITMAP ), commit );
4476 #ifdef HAVE_LIBXXSHM
4477 /***********************************************************************
4478 * X11DRV_XShmErrorHandler
4481 static int XShmErrorHandler( Display *dpy, XErrorEvent *event, void *arg )
4483 return 1; /* FIXME: should check event contents */
4486 /***********************************************************************
4487 * X11DRV_XShmCreateImage
4490 static XImage *X11DRV_XShmCreateImage( int width, int height, int bpp,
4491 XShmSegmentInfo* shminfo)
4495 image = XShmCreateImage(gdi_display, visual, bpp, ZPixmap, NULL, shminfo, width, height);
4498 shminfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height,
4500 if( shminfo->shmid != -1 )
4502 shminfo->shmaddr = image->data = shmat(shminfo->shmid, 0, 0);
4503 if( shminfo->shmaddr != (char*)-1 )
4507 shminfo->readOnly = FALSE;
4508 X11DRV_expect_error( gdi_display, XShmErrorHandler, NULL );
4509 ok = (XShmAttach( gdi_display, shminfo ) != 0);
4510 XSync( gdi_display, False );
4511 if (X11DRV_check_error()) ok = FALSE;
4514 shmctl(shminfo->shmid, IPC_RMID, 0);
4515 return image; /* Success! */
4517 /* An error occurred */
4518 shmdt(shminfo->shmaddr);
4520 shmctl(shminfo->shmid, IPC_RMID, 0);
4522 XFlush(gdi_display);
4523 XDestroyImage(image);
4528 #endif /* HAVE_LIBXXSHM */
4531 /***********************************************************************
4532 * X11DRV_DIB_CreateDIBSection
4534 HBITMAP X11DRV_DIB_CreateDIBSection(
4535 X11DRV_PDEVICE *physDev, const BITMAPINFO *bmi, UINT usage,
4536 VOID **bits, HANDLE section,
4537 DWORD offset, DWORD ovr_pitch)
4540 BITMAPOBJ *bmp = NULL;
4541 X11DRV_DIBSECTION *dib = NULL;
4542 int *colorMap = NULL;
4545 /* Fill BITMAP32 structure with DIB data */
4546 const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
4547 INT effHeight, totalSize;
4549 LPVOID mapBits = NULL;
4551 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
4552 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
4553 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
4555 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
4557 bm.bmWidth = bi->biWidth;
4558 bm.bmHeight = effHeight;
4559 bm.bmWidthBytes = ovr_pitch ? ovr_pitch : X11DRV_DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
4560 bm.bmPlanes = bi->biPlanes;
4561 bm.bmBitsPixel = bi->biBitCount;
4564 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
4565 we're dealing with a compressed bitmap. Otherwise, use width * height. */
4566 if (bi->biSizeImage && (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8))
4567 totalSize = bi->biSizeImage;
4569 totalSize = bm.bmWidthBytes * effHeight;
4573 SYSTEM_INFO SystemInfo;
4577 GetSystemInfo( &SystemInfo );
4578 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
4579 mapSize = totalSize + (offset - mapOffset);
4580 mapBits = MapViewOfFile( section,
4581 FILE_MAP_ALL_ACCESS,
4585 bm.bmBits = (char *)mapBits + (offset - mapOffset);
4587 else if (ovr_pitch && offset)
4588 bm.bmBits = (LPVOID) offset;
4591 bm.bmBits = VirtualAlloc(NULL, totalSize,
4592 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
4595 /* Create Color Map */
4596 if (bm.bmBits && bm.bmBitsPixel <= 8)
4597 colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? physDev : NULL,
4598 usage, bm.bmBitsPixel, bmi, &nColorMap );
4600 /* Allocate Memory for DIB and fill structure */
4602 dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
4605 dib->dibSection.dsBm = bm;
4606 dib->dibSection.dsBmih = *bi;
4607 dib->dibSection.dsBmih.biSizeImage = totalSize;
4609 /* Set dsBitfields values */
4610 if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
4612 dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
4614 else switch( bi->biBitCount )
4618 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
4619 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
4620 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
4625 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff0000;
4626 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x00ff00;
4627 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x0000ff;
4630 dib->dibSection.dshSection = section;
4631 dib->dibSection.dsOffset = offset;
4633 dib->status = DIB_Status_None;
4634 dib->nColorMap = nColorMap;
4635 dib->colorMap = colorMap;
4638 /* Create Device Dependent Bitmap and add DIB pointer */
4641 res = CreateDIBitmap(physDev->hdc, bi, 0, NULL, bmi, usage);
4644 bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
4645 if (bmp) bmp->dib = (DIBSECTION *) dib;
4653 #ifdef HAVE_LIBXXSHM
4654 if (XShmQueryExtension(gdi_display) &&
4655 (dib->image = X11DRV_XShmCreateImage( bm.bmWidth, effHeight,
4656 bmp->bitmap.bmBitsPixel, &dib->shminfo )) )
4658 ; /* Created Image */
4660 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
4661 dib->shminfo.shmid = -1;
4664 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
4666 wine_tsx11_unlock();
4669 /* Clean up in case of errors */
4670 if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
4672 TRACE("got an error res=%p, bmp=%p, dib=%p, bm.bmBits=%p\n",
4673 res, bmp, dib, bm.bmBits);
4677 UnmapViewOfFile(mapBits), bm.bmBits = NULL;
4679 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
4682 if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
4683 if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
4684 if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
4685 if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
4686 if (res) { DeleteObject(res); res = 0; }
4690 extern BOOL VIRTUAL_SetFaultHandler(LPCVOID addr, BOOL (*proc)(LPVOID, LPCVOID), LPVOID arg);
4691 /* Install fault handler, if possible */
4692 InitializeCriticalSection(&(dib->lock));
4693 if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
4695 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4696 if (dib) dib->status = DIB_Status_AppMod;
4700 /* Return BITMAP handle and storage location */
4701 if (bmp) GDI_ReleaseObj(res);
4702 if (bm.bmBits && bits) *bits = bm.bmBits;
4706 /***********************************************************************
4707 * X11DRV_DIB_DeleteDIBSection
4709 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
4711 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4716 #ifdef HAVE_LIBXXSHM
4717 if (dib->shminfo.shmid != -1)
4719 XShmDetach (gdi_display, &(dib->shminfo));
4720 XDestroyImage (dib->image);
4721 shmdt (dib->shminfo.shmaddr);
4722 dib->shminfo.shmid = -1;
4726 XDestroyImage( dib->image );
4727 wine_tsx11_unlock();
4731 HeapFree(GetProcessHeap(), 0, dib->colorMap);
4733 DeleteCriticalSection(&(dib->lock));
4736 /***********************************************************************
4737 * SetDIBColorTable (X11DRV.@)
4739 UINT X11DRV_SetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, const RGBQUAD *colors )
4742 X11DRV_DIBSECTION *dib;
4744 HBITMAP hBitmap = GetCurrentObject( physDev->hdc, OBJ_BITMAP );
4746 if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC ))) return 0;
4747 dib = (X11DRV_DIBSECTION *) bmp->dib;
4749 if (dib && dib->colorMap) {
4750 UINT end = count + start;
4751 if (end > dib->nColorMap) end = dib->nColorMap;
4753 * Changing color table might change the mapping between
4754 * DIB colors and X11 colors and thus alter the visible state
4755 * of the bitmap object.
4757 X11DRV_DIB_Lock(bmp, DIB_Status_AppMod, FALSE);
4758 X11DRV_DIB_GenColorMap( physDev, dib->colorMap, DIB_RGB_COLORS,
4759 dib->dibSection.dsBm.bmBitsPixel,
4760 TRUE, colors, start, end );
4761 X11DRV_DIB_Unlock(bmp, TRUE);
4764 GDI_ReleaseObj( hBitmap );
4768 /***********************************************************************
4769 * GetDIBColorTable (X11DRV.@)
4771 UINT X11DRV_GetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, RGBQUAD *colors )
4774 X11DRV_DIBSECTION *dib;
4776 HBITMAP hBitmap = GetCurrentObject( physDev->hdc, OBJ_BITMAP );
4778 if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC ))) return 0;
4779 dib = (X11DRV_DIBSECTION *) bmp->dib;
4781 if (dib && dib->colorMap) {
4782 UINT i, end = count + start;
4783 if (end > dib->nColorMap) end = dib->nColorMap;
4784 for (i = start; i < end; i++,colors++) {
4785 COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] );
4786 colors->rgbBlue = GetBValue(col);
4787 colors->rgbGreen = GetGValue(col);
4788 colors->rgbRed = GetRValue(col);
4789 colors->rgbReserved = 0;
4793 GDI_ReleaseObj( hBitmap );
4799 /***********************************************************************
4800 * X11DRV_DIB_CreateDIBFromBitmap
4802 * Allocates a packed DIB and copies the bitmap data into it.
4804 HGLOBAL X11DRV_DIB_CreateDIBFromBitmap(HDC hdc, HBITMAP hBmp)
4809 LPBITMAPINFOHEADER pbmiHeader;
4810 unsigned int cDataSize, cPackedSize, OffsetBits;
4813 if (!GetObjectW( hBmp, sizeof(bmp), &bmp )) return 0;
4816 * A packed DIB contains a BITMAPINFO structure followed immediately by
4817 * an optional color palette and the pixel data.
4820 /* Calculate the size of the packed DIB */
4821 cDataSize = X11DRV_DIB_GetDIBWidthBytes( bmp.bmWidth, bmp.bmBitsPixel ) * abs( bmp.bmHeight );
4822 cPackedSize = sizeof(BITMAPINFOHEADER)
4823 + ( (bmp.bmBitsPixel <= 8) ? (sizeof(RGBQUAD) * (1 << bmp.bmBitsPixel)) : 0 )
4825 /* Get the offset to the bits */
4826 OffsetBits = cPackedSize - cDataSize;
4828 /* Allocate the packed DIB */
4829 TRACE("\tAllocating packed DIB of size %d\n", cPackedSize);
4830 hPackedDIB = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE /*| GMEM_ZEROINIT*/,
4834 WARN("Could not allocate packed DIB!\n");
4838 /* A packed DIB starts with a BITMAPINFOHEADER */
4839 pPackedDIB = GlobalLock(hPackedDIB);
4840 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
4842 /* Init the BITMAPINFOHEADER */
4843 pbmiHeader->biSize = sizeof(BITMAPINFOHEADER);
4844 pbmiHeader->biWidth = bmp.bmWidth;
4845 pbmiHeader->biHeight = bmp.bmHeight;
4846 pbmiHeader->biPlanes = 1;
4847 pbmiHeader->biBitCount = bmp.bmBitsPixel;
4848 pbmiHeader->biCompression = BI_RGB;
4849 pbmiHeader->biSizeImage = 0;
4850 pbmiHeader->biXPelsPerMeter = pbmiHeader->biYPelsPerMeter = 0;
4851 pbmiHeader->biClrUsed = 0;
4852 pbmiHeader->biClrImportant = 0;
4854 /* Retrieve the DIB bits from the bitmap and fill in the
4855 * DIB color table if present */
4857 nLinesCopied = GetDIBits(hdc, /* Handle to device context */
4858 hBmp, /* Handle to bitmap */
4859 0, /* First scan line to set in dest bitmap */
4860 bmp.bmHeight, /* Number of scan lines to copy */
4861 pPackedDIB + OffsetBits, /* [out] Address of array for bitmap bits */
4862 (LPBITMAPINFO) pbmiHeader, /* [out] Address of BITMAPINFO structure */
4863 0); /* RGB or palette index */
4864 GlobalUnlock(hPackedDIB);
4866 /* Cleanup if GetDIBits failed */
4867 if (nLinesCopied != bmp.bmHeight)
4869 TRACE("\tGetDIBits returned %d. Actual lines=%d\n", nLinesCopied, bmp.bmHeight);
4870 GlobalFree(hPackedDIB);
4877 /**************************************************************************
4878 * X11DRV_DIB_CreateDIBFromPixmap
4880 * Allocates a packed DIB and copies the Pixmap data into it.
4881 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
4883 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
4886 BITMAPOBJ *pBmp = NULL;
4887 HGLOBAL hPackedDIB = 0;
4889 /* Allocates an HBITMAP which references the Pixmap passed to us */
4890 hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(hdc, pixmap);
4893 TRACE("\tCould not create bitmap header for Pixmap\n");
4898 * Create a packed DIB from the Pixmap wrapper bitmap created above.
4899 * A packed DIB contains a BITMAPINFO structure followed immediately by
4900 * an optional color palette and the pixel data.
4902 hPackedDIB = X11DRV_DIB_CreateDIBFromBitmap(hdc, hBmp);
4904 /* Get a pointer to the BITMAPOBJ structure */
4905 pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4907 /* We can now get rid of the HBITMAP wrapper we created earlier.
4908 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
4912 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
4913 pBmp->physBitmap = NULL;
4916 GDI_ReleaseObj( hBmp );
4920 TRACE("\tReturning packed DIB %p\n", hPackedDIB);
4925 /**************************************************************************
4926 * X11DRV_DIB_CreatePixmapFromDIB
4928 * Creates a Pixmap from a packed DIB
4930 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
4932 Pixmap pixmap = None;
4934 BITMAPOBJ *pBmp = NULL;
4935 LPBYTE pPackedDIB = NULL;
4936 LPBITMAPINFO pbmi = NULL;
4937 LPBITMAPINFOHEADER pbmiHeader = NULL;
4938 LPBYTE pbits = NULL;
4940 /* Get a pointer to the packed DIB's data */
4941 pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
4942 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
4943 pbmi = (LPBITMAPINFO)pPackedDIB;
4944 pbits = (LPBYTE)(pPackedDIB
4945 + X11DRV_DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
4947 /* Create a DDB from the DIB */
4949 hBmp = CreateDIBitmap(hdc,
4956 GlobalUnlock(hPackedDIB);
4958 TRACE("CreateDIBitmap returned %p\n", hBmp);
4960 /* Retrieve the internal Pixmap from the DDB */
4962 pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4964 pixmap = (Pixmap)pBmp->physBitmap;
4965 /* clear the physBitmap so that we can steal its pixmap */
4966 pBmp->physBitmap = NULL;
4969 /* Delete the DDB we created earlier now that we have stolen its pixmap */
4970 GDI_ReleaseObj( hBmp );
4973 TRACE("\tReturning Pixmap %ld\n", pixmap);