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 */
88 Some of the following helper functions are duplicated in
92 /***********************************************************************
93 * X11DRV_DIB_GetXImageWidthBytes
95 * Return the width of an X image in bytes
97 inline static int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
99 if (!depth || depth > 32) goto error;
101 if (!ximageDepthTable[depth-1])
103 XImage *testimage = XCreateImage( gdi_display, visual, depth,
104 ZPixmap, 0, NULL, 1, 1, 32, 20 );
107 ximageDepthTable[depth-1] = testimage->bits_per_pixel;
108 XDestroyImage( testimage );
110 else ximageDepthTable[depth-1] = -1;
112 if (ximageDepthTable[depth-1] != -1)
113 return (4 * ((width * ximageDepthTable[depth-1] + 31) / 32));
116 WARN( "(%d): Unsupported depth\n", depth );
121 /***********************************************************************
122 * X11DRV_DIB_GetDIBWidthBytes
124 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
126 static int X11DRV_DIB_GetDIBWidthBytes( int width, int depth )
132 case 1: words = (width + 31) / 32; break;
133 case 4: words = (width + 7) / 8; break;
134 case 8: words = (width + 3) / 4; break;
136 case 16: words = (width + 1) / 2; break;
137 case 24: words = (width * 3 + 3) / 4; break;
139 WARN("(%d): Unsupported depth\n", depth );
148 /***********************************************************************
149 * X11DRV_DIB_GetDIBImageBytes
151 * Return the number of bytes used to hold the image in a DIB bitmap.
153 static int X11DRV_DIB_GetDIBImageBytes( int width, int height, int depth )
155 return X11DRV_DIB_GetDIBWidthBytes( width, depth ) * abs( height );
159 /***********************************************************************
160 * X11DRV_DIB_BitmapInfoSize
162 * Return the size of the bitmap info structure including color table.
164 int X11DRV_DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse )
168 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
170 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
171 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
172 return sizeof(BITMAPCOREHEADER) + colors *
173 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
175 else /* assume BITMAPINFOHEADER */
177 colors = info->bmiHeader.biClrUsed;
178 if (!colors && (info->bmiHeader.biBitCount <= 8))
179 colors = 1 << info->bmiHeader.biBitCount;
180 return sizeof(BITMAPINFOHEADER) + colors *
181 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
186 /***********************************************************************
187 * X11DRV_DIB_CreateXImage
191 XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth )
197 width_bytes = X11DRV_DIB_GetXImageWidthBytes( width, depth );
198 image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0,
199 calloc( height, width_bytes ),
200 width, height, 32, width_bytes );
206 /***********************************************************************
207 * DIB_GetBitmapInfoEx
209 * Get the info from a bitmap header.
210 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
212 static int DIB_GetBitmapInfoEx( const BITMAPINFOHEADER *header, LONG *width,
213 LONG *height, WORD *planes, WORD *bpp,
214 WORD *compr, DWORD *size )
216 if (header->biSize == sizeof(BITMAPCOREHEADER))
218 const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
219 *width = core->bcWidth;
220 *height = core->bcHeight;
221 *planes = core->bcPlanes;
222 *bpp = core->bcBitCount;
227 if (header->biSize >= sizeof(BITMAPINFOHEADER))
229 *width = header->biWidth;
230 *height = header->biHeight;
231 *planes = header->biPlanes;
232 *bpp = header->biBitCount;
233 *compr = header->biCompression;
234 *size = header->biSizeImage;
237 ERR("(%ld): unknown/wrong size for header\n", header->biSize );
242 /***********************************************************************
245 * Get the info from a bitmap header.
246 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
248 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
249 LONG *height, WORD *bpp, WORD *compr )
254 return DIB_GetBitmapInfoEx( header, width, height, &planes, bpp, compr, &size);
258 /***********************************************************************
259 * X11DRV_DIB_GenColorMap
261 * Fills the color map of a bitmap palette. Should not be called
262 * for a >8-bit deep bitmap.
264 int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
265 WORD coloruse, WORD depth, BOOL quads,
266 const void *colorPtr, int start, int end )
270 if (coloruse == DIB_RGB_COLORS)
274 const RGBQUAD * rgb = (const RGBQUAD *)colorPtr;
276 if (depth == 1) /* Monochrome */
277 for (i = start; i < end; i++, rgb++)
278 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
279 rgb->rgbBlue > 255*3/2);
281 for (i = start; i < end; i++, rgb++)
282 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbRed,
288 const RGBTRIPLE * rgb = (const RGBTRIPLE *)colorPtr;
290 if (depth == 1) /* Monochrome */
291 for (i = start; i < end; i++, rgb++)
292 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
293 rgb->rgbtBlue > 255*3/2);
295 for (i = start; i < end; i++, rgb++)
296 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbtRed,
301 else /* DIB_PAL_COLORS */
304 const WORD * index = (const WORD *)colorPtr;
306 for (i = start; i < end; i++, index++)
307 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(*index) );
309 for (i = start; i < end; i++)
310 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(i) );
317 /***********************************************************************
318 * X11DRV_DIB_BuildColorMap
320 * Build the color map from the bitmap palette. Should not be called
321 * for a >8-bit deep bitmap.
323 int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
324 const BITMAPINFO *info, int *nColors )
328 const void *colorPtr;
331 isInfo = info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER);
335 colors = info->bmiHeader.biClrUsed;
336 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
340 colors = 1 << ((const BITMAPCOREHEADER *)info)->bcBitCount;
343 colorPtr = (const BYTE*) info + (WORD) info->bmiHeader.biSize;
347 ERR("called with >256 colors!\n");
351 /* just so CopyDIBSection doesn't have to create an identity palette */
352 if (coloruse == (WORD)-1) colorPtr = NULL;
354 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
355 colors * sizeof(int) )))
359 return X11DRV_DIB_GenColorMap( physDev, colorMapping, coloruse, depth,
360 isInfo, colorPtr, 0, colors);
363 /***********************************************************************
364 * X11DRV_DIB_BuildColorTable
366 * Build the dib color table. This either keeps a copy of the bmiColors array if
367 * usage is DIB_RGB_COLORS, or looks up the palette indicies if usage is
369 * Should not be called for a >8-bit deep bitmap.
371 static RGBQUAD *X11DRV_DIB_BuildColorTable( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
372 const BITMAPINFO *info )
377 BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
381 colors = 1 << ((BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
385 colors = info->bmiHeader.biClrUsed;
386 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
390 ERR("called with >256 colors!\n");
394 if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) )))
397 if(coloruse == DIB_RGB_COLORS)
401 /* Convert RGBTRIPLEs to RGBQUADs */
402 for (i=0; i < colors; i++)
404 colorTable[i].rgbRed = ((BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
405 colorTable[i].rgbGreen = ((BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
406 colorTable[i].rgbBlue = ((BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
407 colorTable[i].rgbReserved = 0;
412 memcpy(colorTable, (LPBYTE) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
417 HPALETTE hpal = GetCurrentObject(physDev->hdc, OBJ_PAL);
418 PALETTEENTRY pal_ents[256];
419 WORD *index = (WORD*) ((LPBYTE) info + (WORD) info->bmiHeader.biSize);
421 GetPaletteEntries(hpal, 0, 256, pal_ents);
423 for(i = 0; i < colors; i++, index++)
425 colorTable[i].rgbRed = pal_ents[*index].peRed;
426 colorTable[i].rgbGreen = pal_ents[*index].peGreen;
427 colorTable[i].rgbBlue = pal_ents[*index].peBlue;
428 colorTable[i].rgbReserved = 0;
435 /***********************************************************************
436 * X11DRV_DIB_MapColor
438 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
442 if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
445 for (color = 0; color < nPhysMap; color++)
446 if (physMap[color] == phys)
449 WARN("Strange color %08x\n", phys);
454 /*********************************************************************
455 * X11DRV_DIB_GetNearestIndex
457 * Helper for X11DRV_DIB_GetDIBits.
458 * Returns the nearest colour table index for a given RGB.
459 * Nearest is defined by minimizing the sum of the squares.
461 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
463 INT i, best = -1, diff, bestdiff = -1;
466 for(color = colormap, i = 0; i < numColors; color++, i++) {
467 diff = (r - color->rgbRed) * (r - color->rgbRed) +
468 (g - color->rgbGreen) * (g - color->rgbGreen) +
469 (b - color->rgbBlue) * (b - color->rgbBlue);
472 if(best == -1 || diff < bestdiff) {
479 /*********************************************************************
480 * X11DRV_DIB_MaskToShift
482 * Helper for X11DRV_DIB_GetDIBits.
483 * Returns the by how many bits to shift a given color so that it is
484 * in the proper position.
486 INT X11DRV_DIB_MaskToShift(DWORD mask)
494 while ((mask&1)==0) {
501 /***********************************************************************
502 * X11DRV_DIB_SetImageBits_1
504 * SetDIBits for a 1-bit deep DIB.
506 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
507 DWORD srcwidth, DWORD dstwidth, int left,
508 int *colors, XImage *bmpImage, DWORD linebytes)
517 srcbits = srcbits + linebytes * (lines - 1);
518 linebytes = -linebytes;
521 if ((extra = (left & 7)) != 0) {
525 srcbits += left >> 3;
526 width = min(srcwidth, dstwidth);
528 /* ==== pal 1 dib -> any bmp format ==== */
529 for (h = lines-1; h >=0; h--) {
531 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
532 for (i = width/8, x = left; i > 0; i--) {
534 XPutPixel( bmpImage, x++, h, colors[ srcval >> 7] );
535 XPutPixel( bmpImage, x++, h, colors[(srcval >> 6) & 1] );
536 XPutPixel( bmpImage, x++, h, colors[(srcval >> 5) & 1] );
537 XPutPixel( bmpImage, x++, h, colors[(srcval >> 4) & 1] );
538 XPutPixel( bmpImage, x++, h, colors[(srcval >> 3) & 1] );
539 XPutPixel( bmpImage, x++, h, colors[(srcval >> 2) & 1] );
540 XPutPixel( bmpImage, x++, h, colors[(srcval >> 1) & 1] );
541 XPutPixel( bmpImage, x++, h, colors[ srcval & 1] );
547 case 7: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
548 case 6: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
549 case 5: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
550 case 4: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
551 case 3: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
552 case 2: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
553 case 1: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]);
556 srcbits += linebytes;
560 /***********************************************************************
561 * X11DRV_DIB_GetImageBits_1
563 * GetDIBits for a 1-bit deep DIB.
565 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
566 DWORD dstwidth, DWORD srcwidth,
567 RGBQUAD *colors, PALETTEENTRY *srccolors,
568 XImage *bmpImage, DWORD linebytes )
571 int h, width = min(dstwidth, srcwidth);
575 dstbits = dstbits + linebytes * (lines - 1);
576 linebytes = -linebytes;
579 switch (bmpImage->depth)
583 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
584 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
587 for (h=lines-1; h>=0; h--) {
591 for (x=0; x<width; x++) {
593 srcval=srccolors[XGetPixel(bmpImage, x, h)];
594 dstval|=(X11DRV_DIB_GetNearestIndex
598 srcval.peBlue) << (7 - (x & 7)));
607 dstbits += linebytes;
615 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
616 /* ==== pal 8 bmp -> pal 1 dib ==== */
618 const BYTE* srcpixel;
621 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
623 for (h=0; h<lines; h++) {
628 for (x=0; x<width; x++) {
630 srcval=srccolors[(int)*srcpixel++];
631 dstval|=(X11DRV_DIB_GetNearestIndex
635 srcval.peBlue) << (7-(x&7)) );
644 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
645 dstbits += linebytes;
656 const WORD* srcpixel;
659 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
661 if (bmpImage->green_mask==0x03e0) {
662 if (bmpImage->red_mask==0x7c00) {
663 /* ==== rgb 555 bmp -> pal 1 dib ==== */
664 for (h=0; h<lines; h++) {
669 for (x=0; x<width; x++) {
672 dstval|=(X11DRV_DIB_GetNearestIndex
674 ((srcval >> 7) & 0xf8) | /* r */
675 ((srcval >> 12) & 0x07),
676 ((srcval >> 2) & 0xf8) | /* g */
677 ((srcval >> 7) & 0x07),
678 ((srcval << 3) & 0xf8) | /* b */
679 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
688 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
689 dstbits += linebytes;
691 } else if (bmpImage->blue_mask==0x7c00) {
692 /* ==== bgr 555 bmp -> pal 1 dib ==== */
693 for (h=0; h<lines; h++) {
698 for (x=0; x<width; x++) {
701 dstval|=(X11DRV_DIB_GetNearestIndex
703 ((srcval << 3) & 0xf8) | /* r */
704 ((srcval >> 2) & 0x07),
705 ((srcval >> 2) & 0xf8) | /* g */
706 ((srcval >> 7) & 0x07),
707 ((srcval >> 7) & 0xf8) | /* b */
708 ((srcval >> 12) & 0x07) ) << (7-(x&7)) );
717 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
718 dstbits += linebytes;
723 } else if (bmpImage->green_mask==0x07e0) {
724 if (bmpImage->red_mask==0xf800) {
725 /* ==== rgb 565 bmp -> pal 1 dib ==== */
726 for (h=0; h<lines; h++) {
731 for (x=0; x<width; x++) {
734 dstval|=(X11DRV_DIB_GetNearestIndex
736 ((srcval >> 8) & 0xf8) | /* r */
737 ((srcval >> 13) & 0x07),
738 ((srcval >> 3) & 0xfc) | /* g */
739 ((srcval >> 9) & 0x03),
740 ((srcval << 3) & 0xf8) | /* b */
741 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
750 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
751 dstbits += linebytes;
753 } else if (bmpImage->blue_mask==0xf800) {
754 /* ==== bgr 565 bmp -> pal 1 dib ==== */
755 for (h=0; h<lines; h++) {
760 for (x=0; x<width; x++) {
763 dstval|=(X11DRV_DIB_GetNearestIndex
765 ((srcval << 3) & 0xf8) | /* r */
766 ((srcval >> 2) & 0x07),
767 ((srcval >> 3) & 0xfc) | /* g */
768 ((srcval >> 9) & 0x03),
769 ((srcval >> 8) & 0xf8) | /* b */
770 ((srcval >> 13) & 0x07) ) << (7-(x&7)) );
779 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
780 dstbits += linebytes;
799 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
800 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
802 if (bmpImage->green_mask!=0x00ff00 ||
803 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
805 } else if (bmpImage->blue_mask==0xff) {
806 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
807 for (h=0; h<lines; h++) {
812 for (x=0; x<width; x++) {
813 dstval|=(X11DRV_DIB_GetNearestIndex
817 srcbyte[0]) << (7-(x&7)) );
818 srcbyte+=bytes_per_pixel;
827 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
828 dstbits += linebytes;
831 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
832 for (h=0; h<lines; h++) {
837 for (x=0; x<width; x++) {
838 dstval|=(X11DRV_DIB_GetNearestIndex
842 srcbyte[2]) << (7-(x&7)) );
843 srcbyte+=bytes_per_pixel;
852 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
853 dstbits += linebytes;
863 unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
865 /* ==== any bmp format -> pal 1 dib ==== */
866 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
867 bmpImage->bits_per_pixel, bmpImage->red_mask,
868 bmpImage->green_mask, bmpImage->blue_mask );
870 for (h=lines-1; h>=0; h--) {
874 for (x=0; x<width; x++) {
875 dstval|=(XGetPixel( bmpImage, x, h) >= white) << (7 - (x&7));
884 dstbits += linebytes;
891 /***********************************************************************
892 * X11DRV_DIB_SetImageBits_4
894 * SetDIBits for a 4-bit deep DIB.
896 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
897 DWORD srcwidth, DWORD dstwidth, int left,
898 int *colors, XImage *bmpImage, DWORD linebytes)
906 srcbits = srcbits + linebytes * (lines - 1);
907 linebytes = -linebytes;
914 srcbits += left >> 1;
915 width = min(srcwidth, dstwidth);
917 /* ==== pal 4 dib -> any bmp format ==== */
918 for (h = lines-1; h >= 0; h--) {
920 for (i = width/2, x = left; i > 0; i--) {
921 BYTE srcval=*srcbyte++;
922 XPutPixel( bmpImage, x++, h, colors[srcval >> 4] );
923 XPutPixel( bmpImage, x++, h, colors[srcval & 0x0f] );
926 XPutPixel( bmpImage, x, h, colors[*srcbyte >> 4] );
927 srcbits += linebytes;
933 /***********************************************************************
934 * X11DRV_DIB_GetImageBits_4
936 * GetDIBits for a 4-bit deep DIB.
938 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
939 DWORD srcwidth, DWORD dstwidth,
940 RGBQUAD *colors, PALETTEENTRY *srccolors,
941 XImage *bmpImage, DWORD linebytes )
944 int h, width = min(srcwidth, dstwidth);
950 dstbits = dstbits + ( linebytes * (lines-1) );
951 linebytes = -linebytes;
956 switch (bmpImage->depth) {
959 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
960 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
963 for (h = lines-1; h >= 0; h--) {
967 for (x = 0; x < width; x++) {
969 srcval=srccolors[XGetPixel(bmpImage, x, h)];
970 dstval|=(X11DRV_DIB_GetNearestIndex
974 srcval.peBlue) << (4-((x&1)<<2)));
983 dstbits += linebytes;
991 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
992 /* ==== pal 8 bmp -> pal 4 dib ==== */
994 const BYTE *srcpixel;
997 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
998 for (h=0; h<lines; h++) {
1003 for (x=0; x<width; x++) {
1004 PALETTEENTRY srcval;
1005 srcval = srccolors[(int)*srcpixel++];
1006 dstval|=(X11DRV_DIB_GetNearestIndex
1010 srcval.peBlue) << (4*(1-(x&1))) );
1019 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1020 dstbits += linebytes;
1030 const void* srcbits;
1031 const WORD* srcpixel;
1034 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1036 if (bmpImage->green_mask==0x03e0) {
1037 if (bmpImage->red_mask==0x7c00) {
1038 /* ==== rgb 555 bmp -> pal 4 dib ==== */
1039 for (h=0; h<lines; h++) {
1044 for (x=0; x<width; x++) {
1047 dstval|=(X11DRV_DIB_GetNearestIndex
1049 ((srcval >> 7) & 0xf8) | /* r */
1050 ((srcval >> 12) & 0x07),
1051 ((srcval >> 2) & 0xf8) | /* g */
1052 ((srcval >> 7) & 0x07),
1053 ((srcval << 3) & 0xf8) | /* b */
1054 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
1063 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1064 dstbits += linebytes;
1066 } else if (bmpImage->blue_mask==0x7c00) {
1067 /* ==== bgr 555 bmp -> pal 4 dib ==== */
1068 for (h=0; h<lines; h++) {
1073 for (x=0; x<width; x++) {
1076 dstval|=(X11DRV_DIB_GetNearestIndex
1078 ((srcval << 3) & 0xf8) | /* r */
1079 ((srcval >> 2) & 0x07),
1080 ((srcval >> 2) & 0xf8) | /* g */
1081 ((srcval >> 7) & 0x07),
1082 ((srcval >> 7) & 0xf8) | /* b */
1083 ((srcval >> 12) & 0x07) ) << ((1-(x&1))<<2) );
1092 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1093 dstbits += linebytes;
1098 } else if (bmpImage->green_mask==0x07e0) {
1099 if (bmpImage->red_mask==0xf800) {
1100 /* ==== rgb 565 bmp -> pal 4 dib ==== */
1101 for (h=0; h<lines; h++) {
1106 for (x=0; x<width; x++) {
1109 dstval|=(X11DRV_DIB_GetNearestIndex
1111 ((srcval >> 8) & 0xf8) | /* r */
1112 ((srcval >> 13) & 0x07),
1113 ((srcval >> 3) & 0xfc) | /* g */
1114 ((srcval >> 9) & 0x03),
1115 ((srcval << 3) & 0xf8) | /* b */
1116 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
1125 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1126 dstbits += linebytes;
1128 } else if (bmpImage->blue_mask==0xf800) {
1129 /* ==== bgr 565 bmp -> pal 4 dib ==== */
1130 for (h=0; h<lines; h++) {
1135 for (x=0; x<width; x++) {
1138 dstval|=(X11DRV_DIB_GetNearestIndex
1140 ((srcval << 3) & 0xf8) | /* r */
1141 ((srcval >> 2) & 0x07),
1142 ((srcval >> 3) & 0xfc) | /* g */
1143 ((srcval >> 9) & 0x03),
1144 ((srcval >> 8) & 0xf8) | /* b */
1145 ((srcval >> 13) & 0x07) ) << ((1-(x&1))<<2) );
1154 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1155 dstbits += linebytes;
1167 if (bmpImage->bits_per_pixel==24) {
1168 const void* srcbits;
1169 const BYTE *srcbyte;
1172 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1174 if (bmpImage->green_mask!=0x00ff00 ||
1175 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1177 } else if (bmpImage->blue_mask==0xff) {
1178 /* ==== rgb 888 bmp -> pal 4 dib ==== */
1179 for (h=0; h<lines; h++) {
1182 for (x=0; x<width/2; x++) {
1183 /* Do 2 pixels at a time */
1184 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1189 X11DRV_DIB_GetNearestIndex
1197 /* And the the odd pixel */
1198 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1204 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1205 dstbits += linebytes;
1208 /* ==== bgr 888 bmp -> pal 4 dib ==== */
1209 for (h=0; h<lines; h++) {
1212 for (x=0; x<width/2; x++) {
1213 /* Do 2 pixels at a time */
1214 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1219 X11DRV_DIB_GetNearestIndex
1227 /* And the the odd pixel */
1228 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1234 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1235 dstbits += linebytes;
1244 const void* srcbits;
1245 const BYTE *srcbyte;
1248 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1250 if (bmpImage->green_mask!=0x00ff00 ||
1251 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1253 } else if (bmpImage->blue_mask==0xff) {
1254 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
1255 for (h=0; h<lines; h++) {
1258 for (x=0; x<width/2; x++) {
1259 /* Do 2 pixels at a time */
1260 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1265 X11DRV_DIB_GetNearestIndex
1273 /* And the the odd pixel */
1274 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1280 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1281 dstbits += linebytes;
1284 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
1285 for (h=0; h<lines; h++) {
1288 for (x=0; x<width/2; x++) {
1289 /* Do 2 pixels at a time */
1290 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1295 X11DRV_DIB_GetNearestIndex
1303 /* And the the odd pixel */
1304 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1310 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1311 dstbits += linebytes;
1322 /* ==== any bmp format -> pal 4 dib ==== */
1323 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
1324 bmpImage->bits_per_pixel, bmpImage->red_mask,
1325 bmpImage->green_mask, bmpImage->blue_mask );
1326 for (h=lines-1; h>=0; h--) {
1328 for (x=0; x<(width & ~1); x+=2) {
1329 *dstbyte++=(X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4) |
1330 X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x+1, h), 0);
1333 *dstbyte=(X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4);
1335 dstbits += linebytes;
1342 /***********************************************************************
1343 * X11DRV_DIB_SetImageBits_RLE4
1345 * SetDIBits for a 4-bit deep compressed DIB.
1347 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
1348 DWORD srcwidth, DWORD dstwidth,
1349 int left, int *colors,
1352 unsigned int x = 0, width = min(srcwidth, dstwidth);
1353 int y = lines - 1, c, length;
1354 const BYTE *begin = bits;
1359 if (length) { /* encoded */
1362 if (x >= width) break;
1363 XPutPixel(bmpImage, x++, y, colors[c >> 4]);
1364 if (!length--) break;
1365 if (x >= width) break;
1366 XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
1385 default: /* absolute */
1388 if (x < width) XPutPixel(bmpImage, x++, y, colors[c >> 4]);
1389 if (!length--) break;
1390 if (x < width) XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
1392 if ((bits - begin) & 1)
1401 /***********************************************************************
1402 * X11DRV_DIB_SetImageBits_8
1404 * SetDIBits for an 8-bit deep DIB.
1406 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
1407 DWORD srcwidth, DWORD dstwidth, int left,
1408 const int *colors, XImage *bmpImage,
1412 int h, width = min(srcwidth, dstwidth);
1413 const BYTE* srcbyte;
1419 srcbits = srcbits + linebytes * (lines-1);
1420 linebytes = -linebytes;
1425 switch (bmpImage->depth) {
1428 #if defined(__i386__) && defined(__GNUC__)
1429 /* Some X servers might have 32 bit/ 16bit deep pixel */
1430 if (lines && width && (bmpImage->bits_per_pixel == 16) &&
1431 (ImageByteOrder(gdi_display)==LSBFirst) )
1433 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
1434 /* FIXME: Does this really handle all these cases correctly? */
1435 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
1436 for (h = lines ; h--; ) {
1437 int _cl1,_cl2; /* temp outputs for asm below */
1438 /* Borrowed from DirectDraw */
1439 __asm__ __volatile__(
1444 " movw (%%edx,%%eax,4),%%ax\n"
1446 " xor %%eax,%%eax\n"
1448 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
1453 :"eax", "cc", "memory"
1455 srcbyte = (srcbits += linebytes);
1456 dstbits -= bmpImage->bytes_per_line;
1464 #if defined(__i386__) && defined(__GNUC__)
1465 if (lines && width && (bmpImage->bits_per_pixel == 32) &&
1466 (ImageByteOrder(gdi_display)==LSBFirst) )
1468 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
1469 /* FIXME: Does this really handle both cases correctly? */
1470 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
1471 for (h = lines ; h--; ) {
1472 int _cl1,_cl2; /* temp outputs for asm below */
1473 /* Borrowed from DirectDraw */
1474 __asm__ __volatile__(
1479 " movl (%%edx,%%eax,4),%%eax\n"
1481 " xor %%eax,%%eax\n"
1483 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
1488 :"eax", "cc", "memory"
1490 srcbyte = (srcbits += linebytes);
1491 dstbits -= bmpImage->bytes_per_line;
1498 break; /* use slow generic case below */
1501 /* ==== pal 8 dib -> any bmp format ==== */
1502 for (h=lines-1; h>=0; h--) {
1503 for (x=left; x<width+left; x++) {
1504 XPutPixel(bmpImage, x, h, colors[*srcbyte++]);
1506 srcbyte = (srcbits += linebytes);
1510 /***********************************************************************
1511 * X11DRV_DIB_GetImageBits_8
1513 * GetDIBits for an 8-bit deep DIB.
1515 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
1516 DWORD srcwidth, DWORD dstwidth,
1517 RGBQUAD *colors, PALETTEENTRY *srccolors,
1518 XImage *bmpImage, DWORD linebytes )
1521 int h, width = min(srcwidth, dstwidth);
1527 dstbits = dstbits + ( linebytes * (lines-1) );
1528 linebytes = -linebytes;
1533 * This condition is true when GetImageBits has been called by
1534 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
1535 * 256 colormaps, so we'll just use for for GetDIBits calls.
1536 * (In somes cases, in a updateDIBSection, the returned colors are bad too)
1538 if (!srccolors) goto updatesection;
1540 switch (bmpImage->depth) {
1543 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1545 /* ==== pal 1 bmp -> pal 8 dib ==== */
1546 /* ==== pal 4 bmp -> pal 8 dib ==== */
1547 for (h=lines-1; h>=0; h--) {
1549 for (x=0; x<width; x++) {
1550 PALETTEENTRY srcval;
1551 srcval=srccolors[XGetPixel(bmpImage, x, h)];
1552 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
1557 dstbits += linebytes;
1565 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1566 /* ==== pal 8 bmp -> pal 8 dib ==== */
1567 const void* srcbits;
1568 const BYTE* srcpixel;
1570 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1571 for (h=0; h<lines; h++) {
1574 for (x = 0; x < width; x++) {
1575 PALETTEENTRY srcval;
1576 srcval=srccolors[(int)*srcpixel++];
1577 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
1582 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1583 dstbits += linebytes;
1593 const void* srcbits;
1594 const WORD* srcpixel;
1597 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1599 if (bmpImage->green_mask==0x03e0) {
1600 if (bmpImage->red_mask==0x7c00) {
1601 /* ==== rgb 555 bmp -> pal 8 dib ==== */
1602 for (h=0; h<lines; h++) {
1605 for (x=0; x<width; x++) {
1608 *dstbyte++=X11DRV_DIB_GetNearestIndex
1610 ((srcval >> 7) & 0xf8) | /* r */
1611 ((srcval >> 12) & 0x07),
1612 ((srcval >> 2) & 0xf8) | /* g */
1613 ((srcval >> 7) & 0x07),
1614 ((srcval << 3) & 0xf8) | /* b */
1615 ((srcval >> 2) & 0x07) );
1617 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1618 dstbits += linebytes;
1620 } else if (bmpImage->blue_mask==0x7c00) {
1621 /* ==== bgr 555 bmp -> pal 8 dib ==== */
1622 for (h=0; h<lines; h++) {
1625 for (x=0; x<width; x++) {
1628 *dstbyte++=X11DRV_DIB_GetNearestIndex
1630 ((srcval << 3) & 0xf8) | /* r */
1631 ((srcval >> 2) & 0x07),
1632 ((srcval >> 2) & 0xf8) | /* g */
1633 ((srcval >> 7) & 0x07),
1634 ((srcval >> 7) & 0xf8) | /* b */
1635 ((srcval >> 12) & 0x07) );
1637 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1638 dstbits += linebytes;
1643 } else if (bmpImage->green_mask==0x07e0) {
1644 if (bmpImage->red_mask==0xf800) {
1645 /* ==== rgb 565 bmp -> pal 8 dib ==== */
1646 for (h=0; h<lines; h++) {
1649 for (x=0; x<width; x++) {
1652 *dstbyte++=X11DRV_DIB_GetNearestIndex
1654 ((srcval >> 8) & 0xf8) | /* r */
1655 ((srcval >> 13) & 0x07),
1656 ((srcval >> 3) & 0xfc) | /* g */
1657 ((srcval >> 9) & 0x03),
1658 ((srcval << 3) & 0xf8) | /* b */
1659 ((srcval >> 2) & 0x07) );
1661 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1662 dstbits += linebytes;
1664 } else if (bmpImage->blue_mask==0xf800) {
1665 /* ==== bgr 565 bmp -> pal 8 dib ==== */
1666 for (h=0; h<lines; h++) {
1669 for (x=0; x<width; x++) {
1672 *dstbyte++=X11DRV_DIB_GetNearestIndex
1674 ((srcval << 3) & 0xf8) | /* r */
1675 ((srcval >> 2) & 0x07),
1676 ((srcval >> 3) & 0xfc) | /* g */
1677 ((srcval >> 9) & 0x03),
1678 ((srcval >> 8) & 0xf8) | /* b */
1679 ((srcval >> 13) & 0x07) );
1681 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1682 dstbits += linebytes;
1696 const void* srcbits;
1697 const BYTE *srcbyte;
1699 int bytes_per_pixel;
1701 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1702 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
1704 if (bmpImage->green_mask!=0x00ff00 ||
1705 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1707 } else if (bmpImage->blue_mask==0xff) {
1708 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
1709 for (h=0; h<lines; h++) {
1712 for (x=0; x<width; x++) {
1713 *dstbyte++=X11DRV_DIB_GetNearestIndex
1718 srcbyte+=bytes_per_pixel;
1720 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1721 dstbits += linebytes;
1724 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
1725 for (h=0; h<lines; h++) {
1728 for (x=0; x<width; x++) {
1729 *dstbyte++=X11DRV_DIB_GetNearestIndex
1734 srcbyte+=bytes_per_pixel;
1736 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
1737 dstbits += linebytes;
1745 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
1746 bmpImage->depth, bmpImage->red_mask,
1747 bmpImage->green_mask, bmpImage->blue_mask );
1749 /* ==== any bmp format -> pal 8 dib ==== */
1750 for (h=lines-1; h>=0; h--) {
1752 for (x=0; x<width; x++) {
1753 *dstbyte=X11DRV_DIB_MapColor
1755 XGetPixel(bmpImage, x, h), *dstbyte);
1758 dstbits += linebytes;
1764 /***********************************************************************
1765 * X11DRV_DIB_SetImageBits_RLE8
1767 * SetDIBits for an 8-bit deep compressed DIB.
1769 * This function rewritten 941113 by James Youngman. WINE blew out when I
1770 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1772 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1773 * 'End of bitmap' escape code. This code is very much laxer in what it
1774 * allows to end the expansion. Possibly too lax. See the note by
1775 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1776 * bitmap should end with RleEnd, but on the other hand, software exists
1777 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1780 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1781 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1784 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
1785 DWORD srcwidth, DWORD dstwidth,
1786 int left, int *colors,
1789 unsigned int x; /* X-position on each line. Increases. */
1790 int y; /* Line #. Starts at lines-1, decreases */
1791 const BYTE *pIn = bits; /* Pointer to current position in bits */
1792 BYTE length; /* The length pf a run */
1793 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
1796 * Note that the bitmap data is stored by Windows starting at the
1797 * bottom line of the bitmap and going upwards. Within each line,
1798 * the data is stored left-to-right. That's the reason why line
1799 * goes from lines-1 to 0. [JAY]
1809 * If the length byte is not zero (which is the escape value),
1810 * We have a run of length pixels all the same colour. The colour
1811 * index is stored next.
1813 * If the length byte is zero, we need to read the next byte to
1814 * know what to do. [JAY]
1819 * [Run-Length] Encoded mode
1821 int color = colors[*pIn++];
1822 while (length-- && x < dstwidth) XPutPixel(bmpImage, x++, y, color);
1827 * Escape codes (may be an absolute sequence though)
1829 escape_code = (*pIn++);
1838 /* Not all RLE8 bitmaps end with this code. For
1839 * example, Paint Shop Pro produces some that don't.
1840 * That's (I think) what caused the previous
1841 * implementation to fail. [JAY]
1850 default: /* switch to absolute mode */
1851 length = escape_code;
1854 int color = colors[*pIn++];
1860 XPutPixel(bmpImage, x++, y, color);
1863 * If you think for a moment you'll realise that the
1864 * only time we could ever possibly read an odd
1865 * number of bytes is when there is a 0x00 (escape),
1866 * a value >0x02 (absolute mode) and then an odd-
1867 * length run. Therefore this is the only place we
1868 * need to worry about it. Everywhere else the
1869 * bytes are always read in pairs. [JAY]
1871 if (escape_code & 1) pIn++; /* Throw away the pad byte. */
1873 } /* switch (escape_code) : Escape sequence */
1879 /***********************************************************************
1880 * X11DRV_DIB_SetImageBits_16
1882 * SetDIBits for a 16-bit deep DIB.
1884 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
1885 DWORD srcwidth, DWORD dstwidth, int left,
1886 X11DRV_PDEVICE *physDev, DWORD rSrc, DWORD gSrc, DWORD bSrc,
1887 XImage *bmpImage, DWORD linebytes )
1890 int h, width = min(srcwidth, dstwidth);
1891 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_byteswap;
1896 srcbits = srcbits + ( linebytes * (lines-1));
1897 linebytes = -linebytes;
1900 switch (bmpImage->depth)
1907 srcbits=srcbits+left*2;
1908 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
1910 if (bmpImage->green_mask==0x03e0) {
1911 if (gSrc==bmpImage->green_mask) {
1912 if (rSrc==bmpImage->red_mask) {
1913 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
1914 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
1915 convs->Convert_5x5_asis
1918 dstbits,-bmpImage->bytes_per_line);
1919 } else if (rSrc==bmpImage->blue_mask) {
1920 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
1921 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
1922 convs->Convert_555_reverse
1925 dstbits,-bmpImage->bytes_per_line);
1928 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
1929 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
1930 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
1931 convs->Convert_565_to_555_asis
1934 dstbits,-bmpImage->bytes_per_line);
1936 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
1937 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
1938 convs->Convert_565_to_555_reverse
1941 dstbits,-bmpImage->bytes_per_line);
1944 } else if (bmpImage->green_mask==0x07e0) {
1945 if (gSrc==bmpImage->green_mask) {
1946 if (rSrc==bmpImage->red_mask) {
1947 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
1948 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
1949 convs->Convert_5x5_asis
1952 dstbits,-bmpImage->bytes_per_line);
1954 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
1955 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
1956 convs->Convert_565_reverse
1959 dstbits,-bmpImage->bytes_per_line);
1962 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
1963 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
1964 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
1965 convs->Convert_555_to_565_asis
1968 dstbits,-bmpImage->bytes_per_line);
1970 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
1971 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
1972 convs->Convert_555_to_565_reverse
1975 dstbits,-bmpImage->bytes_per_line);
1985 if (bmpImage->bits_per_pixel==24) {
1988 srcbits=srcbits+left*2;
1989 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
1991 if (bmpImage->green_mask!=0x00ff00 ||
1992 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1994 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
1995 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
1997 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
1998 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
1999 convs->Convert_555_to_888_asis
2002 dstbits,-bmpImage->bytes_per_line);
2004 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
2005 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
2006 convs->Convert_565_to_888_asis
2009 dstbits,-bmpImage->bytes_per_line);
2013 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
2014 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
2015 convs->Convert_555_to_888_reverse
2018 dstbits,-bmpImage->bytes_per_line);
2020 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
2021 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
2022 convs->Convert_565_to_888_reverse
2025 dstbits,-bmpImage->bytes_per_line);
2036 srcbits=srcbits+left*2;
2037 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2039 if (bmpImage->green_mask!=0x00ff00 ||
2040 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2042 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
2043 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
2045 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
2046 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
2047 convs->Convert_555_to_0888_asis
2050 dstbits,-bmpImage->bytes_per_line);
2052 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
2053 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
2054 convs->Convert_565_to_0888_asis
2057 dstbits,-bmpImage->bytes_per_line);
2061 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
2062 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
2063 convs->Convert_555_to_0888_reverse
2066 dstbits,-bmpImage->bytes_per_line);
2068 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
2069 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
2070 convs->Convert_565_to_0888_reverse
2073 dstbits,-bmpImage->bytes_per_line);
2081 WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2082 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
2083 bmpImage->green_mask, bmpImage->blue_mask );
2089 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
2090 const WORD* srcpixel;
2091 int rShift1,gShift1,bShift1;
2092 int rShift2,gShift2,bShift2;
2095 /* Set color scaling values */
2096 rShift1=16+X11DRV_DIB_MaskToShift(rSrc)-3;
2097 gShift1=16+X11DRV_DIB_MaskToShift(gSrc)-3;
2098 bShift1=16+X11DRV_DIB_MaskToShift(bSrc)-3;
2103 /* Green has 5 bits, like the others */
2107 /* Green has 6 bits, not 5. Compensate. */
2116 /* We could split it into four separate cases to optimize
2117 * but it is probably not worth it.
2119 for (h=lines-1; h>=0; h--) {
2120 srcpixel=(const WORD*)srcbits;
2121 for (x=left; x<width+left; x++) {
2123 BYTE red,green,blue;
2124 srcval=*srcpixel++ << 16;
2125 red= ((srcval >> rShift1) & 0xf8) |
2126 ((srcval >> rShift2) & 0x07);
2127 green=((srcval >> gShift1) & gMask1) |
2128 ((srcval >> gShift2) & gMask2);
2129 blue= ((srcval >> bShift1) & 0xf8) |
2130 ((srcval >> bShift2) & 0x07);
2131 XPutPixel(bmpImage, x, h,
2132 X11DRV_PALETTE_ToPhysical
2133 (physDev, RGB(red,green,blue)));
2135 srcbits += linebytes;
2143 /***********************************************************************
2144 * X11DRV_DIB_GetImageBits_16
2146 * GetDIBits for an 16-bit deep DIB.
2148 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
2149 DWORD dstwidth, DWORD srcwidth,
2150 PALETTEENTRY *srccolors,
2151 DWORD rDst, DWORD gDst, DWORD bDst,
2152 XImage *bmpImage, DWORD dibpitch )
2155 int h, width = min(srcwidth, dstwidth);
2156 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_byteswap;
2158 DWORD linebytes = dibpitch;
2163 dstbits = dstbits + ( linebytes * (lines-1));
2164 linebytes = -linebytes;
2167 switch (bmpImage->depth)
2172 const char* srcbits;
2174 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2176 if (bmpImage->green_mask==0x03e0) {
2177 if (gDst==bmpImage->green_mask) {
2178 if (rDst==bmpImage->red_mask) {
2179 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
2180 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
2181 convs->Convert_5x5_asis
2183 srcbits,-bmpImage->bytes_per_line,
2186 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
2187 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
2188 convs->Convert_555_reverse
2190 srcbits,-bmpImage->bytes_per_line,
2194 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
2195 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
2196 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
2197 convs->Convert_555_to_565_asis
2199 srcbits,-bmpImage->bytes_per_line,
2202 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
2203 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
2204 convs->Convert_555_to_565_reverse
2206 srcbits,-bmpImage->bytes_per_line,
2210 } else if (bmpImage->green_mask==0x07e0) {
2211 if (gDst==bmpImage->green_mask) {
2212 if (rDst == bmpImage->red_mask) {
2213 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
2214 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
2215 convs->Convert_5x5_asis
2217 srcbits,-bmpImage->bytes_per_line,
2220 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
2221 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
2222 convs->Convert_565_reverse
2224 srcbits,-bmpImage->bytes_per_line,
2228 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
2229 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
2230 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
2231 convs->Convert_565_to_555_asis
2233 srcbits,-bmpImage->bytes_per_line,
2236 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
2237 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
2238 convs->Convert_565_to_555_reverse
2240 srcbits,-bmpImage->bytes_per_line,
2251 if (bmpImage->bits_per_pixel == 24) {
2252 const char* srcbits;
2254 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2256 if (bmpImage->green_mask!=0x00ff00 ||
2257 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2259 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
2260 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
2262 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
2263 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
2264 convs->Convert_888_to_555_asis
2266 srcbits,-bmpImage->bytes_per_line,
2269 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2270 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2271 convs->Convert_888_to_565_asis
2273 srcbits,-bmpImage->bytes_per_line,
2278 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
2279 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
2280 convs->Convert_888_to_555_reverse
2282 srcbits,-bmpImage->bytes_per_line,
2285 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
2286 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
2287 convs->Convert_888_to_565_reverse
2289 srcbits,-bmpImage->bytes_per_line,
2299 const char* srcbits;
2301 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2303 if (bmpImage->green_mask!=0x00ff00 ||
2304 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2306 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
2307 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
2309 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
2310 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
2311 convs->Convert_0888_to_555_asis
2313 srcbits,-bmpImage->bytes_per_line,
2316 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
2317 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
2318 convs->Convert_0888_to_565_asis
2320 srcbits,-bmpImage->bytes_per_line,
2325 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
2326 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
2327 convs->Convert_0888_to_555_reverse
2329 srcbits,-bmpImage->bytes_per_line,
2332 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
2333 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
2334 convs->Convert_0888_to_565_reverse
2336 srcbits,-bmpImage->bytes_per_line,
2345 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2346 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
2347 int rShift,gShift,bShift;
2350 /* Shift everything 16 bits left so that all shifts are >0,
2351 * even for BGR DIBs. Then a single >> 16 will bring everything
2354 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
2355 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
2356 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
2358 /* 6 bits for the green */
2364 for (h = lines - 1; h >= 0; h--) {
2365 dstpixel=(LPWORD)dstbits;
2366 for (x = 0; x < width; x++) {
2367 PALETTEENTRY srcval;
2369 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2370 dstval=((srcval.peRed << rShift) & rDst) |
2371 ((srcval.peGreen << gShift) & gDst) |
2372 ((srcval.peBlue << bShift) & bDst);
2373 *dstpixel++=dstval >> 16;
2375 dstbits += linebytes;
2383 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2384 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
2385 int rShift,gShift,bShift;
2386 const BYTE* srcbits;
2387 const BYTE* srcpixel;
2390 /* Shift everything 16 bits left so that all shifts are >0,
2391 * even for BGR DIBs. Then a single >> 16 will bring everything
2394 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
2395 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
2396 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
2398 /* 6 bits for the green */
2404 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2405 for (h=0; h<lines; h++) {
2407 dstpixel=(LPWORD)dstbits;
2408 for (x = 0; x < width; x++) {
2409 PALETTEENTRY srcval;
2411 srcval=srccolors[(int)*srcpixel++];
2412 dstval=((srcval.peRed << rShift) & rDst) |
2413 ((srcval.peGreen << gShift) & gDst) |
2414 ((srcval.peBlue << bShift) & bDst);
2415 *dstpixel++=dstval >> 16;
2417 srcbits -= bmpImage->bytes_per_line;
2418 dstbits += linebytes;
2428 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
2429 int rShift,gShift,bShift;
2432 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
2433 bmpImage->depth, bmpImage->red_mask,
2434 bmpImage->green_mask, bmpImage->blue_mask,
2437 /* Shift everything 16 bits left so that all shifts are >0,
2438 * even for BGR DIBs. Then a single >> 16 will bring everything
2441 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
2442 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
2443 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
2445 /* 6 bits for the green */
2451 for (h = lines - 1; h >= 0; h--) {
2452 dstpixel=(LPWORD)dstbits;
2453 for (x = 0; x < width; x++) {
2456 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
2457 dstval=((GetRValue(srcval) << rShift) & rDst) |
2458 ((GetGValue(srcval) << gShift) & gDst) |
2459 ((GetBValue(srcval) << bShift) & bDst);
2460 *dstpixel++=dstval >> 16;
2462 dstbits += linebytes;
2470 /***********************************************************************
2471 * X11DRV_DIB_SetImageBits_24
2473 * SetDIBits for a 24-bit deep DIB.
2475 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
2476 DWORD srcwidth, DWORD dstwidth, int left,
2477 X11DRV_PDEVICE *physDev,
2478 DWORD rSrc, DWORD gSrc, DWORD bSrc,
2479 XImage *bmpImage, DWORD linebytes )
2482 int h, width = min(srcwidth, dstwidth);
2483 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_byteswap;
2488 srcbits = srcbits + linebytes * (lines - 1);
2489 linebytes = -linebytes;
2492 switch (bmpImage->depth)
2495 if (bmpImage->bits_per_pixel==24) {
2498 srcbits=srcbits+left*3;
2499 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
2501 if (bmpImage->green_mask!=0x00ff00 ||
2502 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2504 } else if (rSrc==bmpImage->red_mask) {
2505 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
2506 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
2507 convs->Convert_888_asis
2510 dstbits,-bmpImage->bytes_per_line);
2512 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
2513 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
2514 convs->Convert_888_reverse
2517 dstbits,-bmpImage->bytes_per_line);
2527 srcbits=srcbits+left*3;
2528 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2530 if (bmpImage->green_mask!=0x00ff00 ||
2531 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2533 } else if (rSrc==bmpImage->red_mask) {
2534 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
2535 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
2536 convs->Convert_888_to_0888_asis
2539 dstbits,-bmpImage->bytes_per_line);
2541 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
2542 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
2543 convs->Convert_888_to_0888_reverse
2546 dstbits,-bmpImage->bytes_per_line);
2556 srcbits=srcbits+left*3;
2557 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2559 if (bmpImage->green_mask==0x03e0) {
2560 if ((rSrc==0xff0000 && bmpImage->red_mask==0x7f00) ||
2561 (bSrc==0xff0000 && bmpImage->blue_mask==0x7f00)) {
2562 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
2563 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
2564 convs->Convert_888_to_555_asis
2567 dstbits,-bmpImage->bytes_per_line);
2568 } else if ((rSrc==0xff && bmpImage->red_mask==0x7f00) ||
2569 (bSrc==0xff && bmpImage->blue_mask==0x7f00)) {
2570 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
2571 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
2572 convs->Convert_888_to_555_reverse
2575 dstbits,-bmpImage->bytes_per_line);
2579 } else if (bmpImage->green_mask==0x07e0) {
2580 if ((rSrc==0xff0000 && bmpImage->red_mask==0xf800) ||
2581 (bSrc==0xff0000 && bmpImage->blue_mask==0xf800)) {
2582 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
2583 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
2584 convs->Convert_888_to_565_asis
2587 dstbits,-bmpImage->bytes_per_line);
2588 } else if ((rSrc==0xff && bmpImage->red_mask==0xf800) ||
2589 (bSrc==0xff && bmpImage->blue_mask==0xf800)) {
2590 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
2591 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
2592 convs->Convert_888_to_565_reverse
2595 dstbits,-bmpImage->bytes_per_line);
2607 WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2608 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
2609 bmpImage->green_mask, bmpImage->blue_mask );
2615 /* ==== rgb 888 dib -> any bmp bormat ==== */
2616 const BYTE* srcbyte;
2618 /* Windows only supports one 24bpp DIB format: RGB888 */
2620 for (h = lines - 1; h >= 0; h--) {
2621 srcbyte=(const BYTE*)srcbits;
2622 for (x = left; x < width+left; x++) {
2623 XPutPixel(bmpImage, x, h,
2624 X11DRV_PALETTE_ToPhysical
2625 (physDev, RGB(srcbyte[2], srcbyte[1], srcbyte[0])));
2628 srcbits += linebytes;
2636 /***********************************************************************
2637 * X11DRV_DIB_GetImageBits_24
2639 * GetDIBits for an 24-bit deep DIB.
2641 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
2642 DWORD dstwidth, DWORD srcwidth,
2643 PALETTEENTRY *srccolors,
2644 DWORD rDst, DWORD gDst, DWORD bDst,
2645 XImage *bmpImage, DWORD linebytes )
2648 int h, width = min(srcwidth, dstwidth);
2649 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_byteswap;
2654 dstbits = dstbits + ( linebytes * (lines-1) );
2655 linebytes = -linebytes;
2658 switch (bmpImage->depth)
2661 if (bmpImage->bits_per_pixel==24) {
2662 const char* srcbits;
2664 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2666 if (bmpImage->green_mask!=0x00ff00 ||
2667 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2669 } else if (rDst==bmpImage->red_mask) {
2670 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
2671 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
2672 convs->Convert_888_asis
2674 srcbits,-bmpImage->bytes_per_line,
2677 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
2678 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
2679 convs->Convert_888_reverse
2681 srcbits,-bmpImage->bytes_per_line,
2690 const char* srcbits;
2692 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2694 if (bmpImage->green_mask!=0x00ff00 ||
2695 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2697 } else if (rDst==bmpImage->red_mask) {
2698 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
2699 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
2700 convs->Convert_0888_to_888_asis
2702 srcbits,-bmpImage->bytes_per_line,
2705 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
2706 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
2707 convs->Convert_0888_to_888_reverse
2709 srcbits,-bmpImage->bytes_per_line,
2718 const char* srcbits;
2720 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2722 if (bmpImage->green_mask==0x03e0) {
2723 if ((rDst==0xff0000 && bmpImage->red_mask==0x7f00) ||
2724 (bDst==0xff0000 && bmpImage->blue_mask==0x7f00)) {
2725 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
2726 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
2727 convs->Convert_555_to_888_asis
2729 srcbits,-bmpImage->bytes_per_line,
2731 } else if ((rDst==0xff && bmpImage->red_mask==0x7f00) ||
2732 (bDst==0xff && bmpImage->blue_mask==0x7f00)) {
2733 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
2734 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
2735 convs->Convert_555_to_888_reverse
2737 srcbits,-bmpImage->bytes_per_line,
2742 } else if (bmpImage->green_mask==0x07e0) {
2743 if ((rDst==0xff0000 && bmpImage->red_mask==0xf800) ||
2744 (bDst==0xff0000 && bmpImage->blue_mask==0xf800)) {
2745 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
2746 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
2747 convs->Convert_565_to_888_asis
2749 srcbits,-bmpImage->bytes_per_line,
2751 } else if ((rDst==0xff && bmpImage->red_mask==0xf800) ||
2752 (bDst==0xff && bmpImage->blue_mask==0xf800)) {
2753 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
2754 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
2755 convs->Convert_565_to_888_reverse
2757 srcbits,-bmpImage->bytes_per_line,
2770 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2771 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
2774 /* Windows only supports one 24bpp DIB format: rgb 888 */
2775 for (h = lines - 1; h >= 0; h--) {
2777 for (x = 0; x < width; x++) {
2778 PALETTEENTRY srcval;
2779 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2780 dstbyte[0]=srcval.peBlue;
2781 dstbyte[1]=srcval.peGreen;
2782 dstbyte[2]=srcval.peRed;
2785 dstbits += linebytes;
2793 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors) {
2794 /* ==== pal 8 bmp -> rgb 888 dib ==== */
2795 const void* srcbits;
2796 const BYTE* srcpixel;
2799 /* Windows only supports one 24bpp DIB format: rgb 888 */
2800 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2801 for (h = lines - 1; h >= 0; h--) {
2804 for (x = 0; x < width; x++ ) {
2805 PALETTEENTRY srcval;
2806 srcval=srccolors[(int)*srcpixel++];
2807 dstbyte[0]=srcval.peBlue;
2808 dstbyte[1]=srcval.peGreen;
2809 dstbyte[2]=srcval.peRed;
2812 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
2813 dstbits += linebytes;
2823 /* ==== any bmp format -> 888 dib ==== */
2826 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
2827 bmpImage->depth, bmpImage->red_mask,
2828 bmpImage->green_mask, bmpImage->blue_mask,
2831 /* Windows only supports one 24bpp DIB format: rgb 888 */
2832 for (h = lines - 1; h >= 0; h--) {
2834 for (x = 0; x < width; x++) {
2835 COLORREF srcval=X11DRV_PALETTE_ToLogical
2836 (XGetPixel( bmpImage, x, h ));
2837 dstbyte[0]=GetBValue(srcval);
2838 dstbyte[1]=GetGValue(srcval);
2839 dstbyte[2]=GetRValue(srcval);
2842 dstbits += linebytes;
2850 /***********************************************************************
2851 * X11DRV_DIB_SetImageBits_32
2853 * SetDIBits for a 32-bit deep DIB.
2855 static void X11DRV_DIB_SetImageBits_32(int lines, const BYTE *srcbits,
2856 DWORD srcwidth, DWORD dstwidth, int left,
2857 X11DRV_PDEVICE *physDev,
2858 DWORD rSrc, DWORD gSrc, DWORD bSrc,
2864 int h, width = min(srcwidth, dstwidth);
2865 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_byteswap;
2870 srcbits = srcbits + ( linebytes * (lines-1) );
2871 linebytes = -linebytes;
2874 ptr = (const DWORD *) srcbits + left;
2876 switch (bmpImage->depth)
2879 if (bmpImage->bits_per_pixel==24) {
2882 srcbits=srcbits+left*4;
2883 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
2885 if (rSrc==bmpImage->red_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->blue_mask) {
2886 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
2887 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
2888 convs->Convert_0888_to_888_asis
2891 dstbits,-bmpImage->bytes_per_line);
2892 } else if (bmpImage->green_mask!=0x00ff00 ||
2893 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2895 /* the tests below assume sane bmpImage masks */
2896 } else if (rSrc==bmpImage->blue_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->red_mask) {
2897 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
2898 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
2899 convs->Convert_0888_to_888_reverse
2902 dstbits,-bmpImage->bytes_per_line);
2903 } else if (bmpImage->blue_mask==0xff) {
2904 /* ==== any 0888 dib -> rgb 888 bmp ==== */
2905 convs->Convert_any0888_to_rgb888
2909 dstbits,-bmpImage->bytes_per_line);
2911 /* ==== any 0888 dib -> bgr 888 bmp ==== */
2912 convs->Convert_any0888_to_bgr888
2916 dstbits,-bmpImage->bytes_per_line);
2926 srcbits=srcbits+left*4;
2927 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2929 if (gSrc==bmpImage->green_mask) {
2930 if (rSrc==bmpImage->red_mask && bSrc==bmpImage->blue_mask) {
2931 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
2932 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
2933 convs->Convert_0888_asis
2936 dstbits,-bmpImage->bytes_per_line);
2937 } else if (bmpImage->green_mask!=0x00ff00 ||
2938 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2940 /* the tests below assume sane bmpImage masks */
2941 } else if (rSrc==bmpImage->blue_mask && bSrc==bmpImage->red_mask) {
2942 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
2943 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
2944 convs->Convert_0888_reverse
2947 dstbits,-bmpImage->bytes_per_line);
2949 /* ==== any 0888 dib -> any 0888 bmp ==== */
2950 convs->Convert_0888_any
2954 dstbits,-bmpImage->bytes_per_line,
2955 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
2957 } else if (bmpImage->green_mask!=0x00ff00 ||
2958 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2960 /* the tests below assume sane bmpImage masks */
2962 /* ==== any 0888 dib -> any 0888 bmp ==== */
2963 convs->Convert_0888_any
2967 dstbits,-bmpImage->bytes_per_line,
2968 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
2978 srcbits=srcbits+left*4;
2979 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2981 if (rSrc==0xff0000 && gSrc==0x00ff00 && bSrc==0x0000ff) {
2982 if (bmpImage->green_mask==0x03e0) {
2983 if (bmpImage->red_mask==0x7f00) {
2984 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
2985 convs->Convert_0888_to_555_asis
2988 dstbits,-bmpImage->bytes_per_line);
2989 } else if (bmpImage->blue_mask==0x7f00) {
2990 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
2991 convs->Convert_0888_to_555_reverse
2994 dstbits,-bmpImage->bytes_per_line);
2998 } else if (bmpImage->green_mask==0x07e0) {
2999 if (bmpImage->red_mask==0xf800) {
3000 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
3001 convs->Convert_0888_to_565_asis
3004 dstbits,-bmpImage->bytes_per_line);
3005 } else if (bmpImage->blue_mask==0xf800) {
3006 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
3007 convs->Convert_0888_to_565_reverse
3010 dstbits,-bmpImage->bytes_per_line);
3017 } else if (rSrc==0x0000ff && gSrc==0x00ff00 && bSrc==0xff0000) {
3018 if (bmpImage->green_mask==0x03e0) {
3019 if (bmpImage->blue_mask==0x7f00) {
3020 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
3021 convs->Convert_0888_to_555_asis
3024 dstbits,-bmpImage->bytes_per_line);
3025 } else if (bmpImage->red_mask==0x7f00) {
3026 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
3027 convs->Convert_0888_to_555_reverse
3030 dstbits,-bmpImage->bytes_per_line);
3034 } else if (bmpImage->green_mask==0x07e0) {
3035 if (bmpImage->blue_mask==0xf800) {
3036 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
3037 convs->Convert_0888_to_565_asis
3040 dstbits,-bmpImage->bytes_per_line);
3041 } else if (bmpImage->red_mask==0xf800) {
3042 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
3043 convs->Convert_0888_to_565_reverse
3046 dstbits,-bmpImage->bytes_per_line);
3054 if (bmpImage->green_mask==0x03e0 &&
3055 (bmpImage->red_mask==0x7f00 ||
3056 bmpImage->blue_mask==0x7f00)) {
3057 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
3058 convs->Convert_any0888_to_5x5
3062 dstbits,-bmpImage->bytes_per_line,
3063 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
3064 } else if (bmpImage->green_mask==0x07e0 &&
3065 (bmpImage->red_mask==0xf800 ||
3066 bmpImage->blue_mask==0xf800)) {
3067 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
3068 convs->Convert_any0888_to_5x5
3072 dstbits,-bmpImage->bytes_per_line,
3073 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
3083 WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3084 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
3085 bmpImage->green_mask, bmpImage->blue_mask );
3091 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
3092 const DWORD* srcpixel;
3093 int rShift,gShift,bShift;
3095 rShift=X11DRV_DIB_MaskToShift(rSrc);
3096 gShift=X11DRV_DIB_MaskToShift(gSrc);
3097 bShift=X11DRV_DIB_MaskToShift(bSrc);
3099 for (h = lines - 1; h >= 0; h--) {
3100 srcpixel=(const DWORD*)srcbits;
3101 for (x = left; x < width+left; x++) {
3103 BYTE red,green,blue;
3104 srcvalue=*srcpixel++;
3105 red= (srcvalue >> rShift) & 0xff;
3106 green=(srcvalue >> gShift) & 0xff;
3107 blue= (srcvalue >> bShift) & 0xff;
3108 XPutPixel(bmpImage, x, h, X11DRV_PALETTE_ToPhysical
3109 (physDev, RGB(red,green,blue)));
3111 srcbits += linebytes;
3119 /***********************************************************************
3120 * X11DRV_DIB_GetImageBits_32
3122 * GetDIBits for an 32-bit deep DIB.
3124 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
3125 DWORD dstwidth, DWORD srcwidth,
3126 PALETTEENTRY *srccolors,
3127 DWORD rDst, DWORD gDst, DWORD bDst,
3128 XImage *bmpImage, DWORD linebytes )
3131 int h, width = min(srcwidth, dstwidth);
3133 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_byteswap;
3138 dstbits = dstbits + ( linebytes * (lines-1) );
3139 linebytes = -linebytes;
3144 switch (bmpImage->depth)
3147 if (bmpImage->bits_per_pixel==24) {
3148 const void* srcbits;
3150 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3152 if (rDst==bmpImage->red_mask && gDst==bmpImage->green_mask && bDst==bmpImage->blue_mask) {
3153 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3154 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3155 convs->Convert_888_to_0888_asis
3157 srcbits,-bmpImage->bytes_per_line,
3159 } else if (bmpImage->green_mask!=0x00ff00 ||
3160 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3162 /* the tests below assume sane bmpImage masks */
3163 } else if (rDst==bmpImage->blue_mask && gDst==bmpImage->green_mask && bDst==bmpImage->red_mask) {
3164 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3165 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3166 convs->Convert_888_to_0888_reverse
3168 srcbits,-bmpImage->bytes_per_line,
3170 } else if (bmpImage->blue_mask==0xff) {
3171 /* ==== rgb 888 bmp -> any 0888 dib ==== */
3172 convs->Convert_rgb888_to_any0888
3174 srcbits,-bmpImage->bytes_per_line,
3178 /* ==== bgr 888 bmp -> any 0888 dib ==== */
3179 convs->Convert_bgr888_to_any0888
3181 srcbits,-bmpImage->bytes_per_line,
3191 const char* srcbits;
3193 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3195 if (gDst==bmpImage->green_mask) {
3196 if (rDst==bmpImage->red_mask && bDst==bmpImage->blue_mask) {
3197 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
3198 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
3199 convs->Convert_0888_asis
3201 srcbits,-bmpImage->bytes_per_line,
3203 } else if (bmpImage->green_mask!=0x00ff00 ||
3204 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3206 /* the tests below assume sane bmpImage masks */
3207 } else if (rDst==bmpImage->blue_mask && bDst==bmpImage->red_mask) {
3208 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
3209 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
3210 convs->Convert_0888_reverse
3212 srcbits,-bmpImage->bytes_per_line,
3215 /* ==== any 0888 bmp -> any 0888 dib ==== */
3216 convs->Convert_0888_any
3218 srcbits,-bmpImage->bytes_per_line,
3219 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3223 } else if (bmpImage->green_mask!=0x00ff00 ||
3224 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3226 /* the tests below assume sane bmpImage masks */
3228 /* ==== any 0888 bmp -> any 0888 dib ==== */
3229 convs->Convert_0888_any
3231 srcbits,-bmpImage->bytes_per_line,
3232 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3242 const char* srcbits;
3244 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3246 if (rDst==0xff0000 && gDst==0x00ff00 && bDst==0x0000ff) {
3247 if (bmpImage->green_mask==0x03e0) {
3248 if (bmpImage->red_mask==0x7f00) {
3249 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
3250 convs->Convert_555_to_0888_asis
3252 srcbits,-bmpImage->bytes_per_line,
3254 } else if (bmpImage->blue_mask==0x7f00) {
3255 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
3256 convs->Convert_555_to_0888_reverse
3258 srcbits,-bmpImage->bytes_per_line,
3263 } else if (bmpImage->green_mask==0x07e0) {
3264 if (bmpImage->red_mask==0xf800) {
3265 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
3266 convs->Convert_565_to_0888_asis
3268 srcbits,-bmpImage->bytes_per_line,
3270 } else if (bmpImage->blue_mask==0xf800) {
3271 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
3272 convs->Convert_565_to_0888_reverse
3274 srcbits,-bmpImage->bytes_per_line,
3282 } else if (rDst==0x0000ff && gDst==0x00ff00 && bDst==0xff0000) {
3283 if (bmpImage->green_mask==0x03e0) {
3284 if (bmpImage->blue_mask==0x7f00) {
3285 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
3286 convs->Convert_555_to_0888_asis
3288 srcbits,-bmpImage->bytes_per_line,
3290 } else if (bmpImage->red_mask==0x7f00) {
3291 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
3292 convs->Convert_555_to_0888_reverse
3294 srcbits,-bmpImage->bytes_per_line,
3299 } else if (bmpImage->green_mask==0x07e0) {
3300 if (bmpImage->blue_mask==0xf800) {
3301 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
3302 convs->Convert_565_to_0888_asis
3304 srcbits,-bmpImage->bytes_per_line,
3306 } else if (bmpImage->red_mask==0xf800) {
3307 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
3308 convs->Convert_565_to_0888_reverse
3310 srcbits,-bmpImage->bytes_per_line,
3319 if (bmpImage->green_mask==0x03e0 &&
3320 (bmpImage->red_mask==0x7f00 ||
3321 bmpImage->blue_mask==0x7f00)) {
3322 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
3323 convs->Convert_5x5_to_any0888
3325 srcbits,-bmpImage->bytes_per_line,
3326 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3329 } else if (bmpImage->green_mask==0x07e0 &&
3330 (bmpImage->red_mask==0xf800 ||
3331 bmpImage->blue_mask==0xf800)) {
3332 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
3333 convs->Convert_5x5_to_any0888
3335 srcbits,-bmpImage->bytes_per_line,
3336 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3348 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3349 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
3350 int rShift,gShift,bShift;
3353 rShift=X11DRV_DIB_MaskToShift(rDst);
3354 gShift=X11DRV_DIB_MaskToShift(gDst);
3355 bShift=X11DRV_DIB_MaskToShift(bDst);
3356 for (h = lines - 1; h >= 0; h--) {
3357 dstpixel=(DWORD*)dstbits;
3358 for (x = 0; x < width; x++) {
3359 PALETTEENTRY srcval;
3360 srcval = srccolors[XGetPixel(bmpImage, x, h)];
3361 *dstpixel++=(srcval.peRed << rShift) |
3362 (srcval.peGreen << gShift) |
3363 (srcval.peBlue << bShift);
3365 dstbits += linebytes;
3373 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3374 /* ==== pal 8 bmp -> any 0888 dib ==== */
3375 int rShift,gShift,bShift;
3376 const void* srcbits;
3377 const BYTE* srcpixel;
3380 rShift=X11DRV_DIB_MaskToShift(rDst);
3381 gShift=X11DRV_DIB_MaskToShift(gDst);
3382 bShift=X11DRV_DIB_MaskToShift(bDst);
3383 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3384 for (h = lines - 1; h >= 0; h--) {
3386 dstpixel=(DWORD*)dstbits;
3387 for (x = 0; x < width; x++) {
3388 PALETTEENTRY srcval;
3389 srcval=srccolors[(int)*srcpixel++];
3390 *dstpixel++=(srcval.peRed << rShift) |
3391 (srcval.peGreen << gShift) |
3392 (srcval.peBlue << bShift);
3394 srcbits = (const char*)srcbits - bmpImage->bytes_per_line;
3395 dstbits += linebytes;
3405 /* ==== any bmp format -> any 0888 dib ==== */
3406 int rShift,gShift,bShift;
3409 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
3410 bmpImage->depth, bmpImage->red_mask,
3411 bmpImage->green_mask, bmpImage->blue_mask,
3414 rShift=X11DRV_DIB_MaskToShift(rDst);
3415 gShift=X11DRV_DIB_MaskToShift(gDst);
3416 bShift=X11DRV_DIB_MaskToShift(bDst);
3417 for (h = lines - 1; h >= 0; h--) {
3418 dstpixel=(DWORD*)dstbits;
3419 for (x = 0; x < width; x++) {
3421 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
3422 *dstpixel++=(GetRValue(srcval) << rShift) |
3423 (GetGValue(srcval) << gShift) |
3424 (GetBValue(srcval) << bShift);
3426 dstbits += linebytes;
3433 /***********************************************************************
3434 * X11DRV_DIB_SetImageBits
3436 * Transfer the bits to an X image.
3437 * Helper function for SetDIBits() and SetDIBitsToDevice().
3439 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
3441 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
3446 bmpImage = descr->image;
3448 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
3449 descr->infoWidth, lines, 32, 0 );
3450 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
3451 if(bmpImage->data == NULL) {
3452 ERR("Out of memory!\n");
3453 XDestroyImage( bmpImage );
3454 wine_tsx11_unlock();
3459 TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
3460 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
3461 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
3462 bmpImage->depth,bmpImage->bits_per_pixel,
3463 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
3465 /* Transfer the pixels */
3466 switch(descr->infoBpp)
3469 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
3470 descr->width, descr->xSrc, (int *)(descr->colorMap),
3471 bmpImage, descr->dibpitch );
3474 if (descr->compression) {
3475 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
3476 descr->width, descr->height, AllPlanes, ZPixmap,
3477 bmpImage, descr->xSrc, descr->ySrc );
3479 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
3480 descr->infoWidth, descr->width,
3481 descr->xSrc, (int *)(descr->colorMap),
3484 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
3485 descr->infoWidth, descr->width,
3486 descr->xSrc, (int*)(descr->colorMap),
3487 bmpImage, descr->dibpitch );
3490 if (descr->compression) {
3491 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
3492 descr->width, descr->height, AllPlanes, ZPixmap,
3493 bmpImage, descr->xSrc, descr->ySrc );
3494 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
3495 descr->infoWidth, descr->width,
3496 descr->xSrc, (int *)(descr->colorMap),
3499 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
3500 descr->infoWidth, descr->width,
3501 descr->xSrc, (int *)(descr->colorMap),
3502 bmpImage, descr->dibpitch );
3506 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
3507 descr->infoWidth, descr->width,
3508 descr->xSrc, descr->physDev,
3509 descr->rMask, descr->gMask, descr->bMask,
3510 bmpImage, descr->dibpitch);
3513 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
3514 descr->infoWidth, descr->width,
3515 descr->xSrc, descr->physDev,
3516 descr->rMask, descr->gMask, descr->bMask,
3517 bmpImage, descr->dibpitch);
3520 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
3521 descr->infoWidth, descr->width,
3522 descr->xSrc, descr->physDev,
3523 descr->rMask, descr->gMask, descr->bMask,
3524 bmpImage, descr->dibpitch);
3527 WARN("(%d): Invalid depth\n", descr->infoBpp );
3531 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
3532 descr->drawable, descr->gc, bmpImage,
3533 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
3534 descr->width, descr->height);
3535 #ifdef HAVE_LIBXXSHM
3538 XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
3539 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
3540 descr->width, descr->height, FALSE );
3541 XSync( gdi_display, 0 );
3545 XPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
3546 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
3547 descr->width, descr->height );
3549 if (!descr->image) XDestroyImage( bmpImage );
3550 wine_tsx11_unlock();
3554 /***********************************************************************
3555 * X11DRV_DIB_GetImageBits
3557 * Transfer the bits from an X image.
3559 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
3561 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
3566 bmpImage = descr->image;
3568 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
3569 descr->infoWidth, lines, 32, 0 );
3570 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
3571 if(bmpImage->data == NULL) {
3572 ERR("Out of memory!\n");
3573 XDestroyImage( bmpImage );
3574 wine_tsx11_unlock();
3579 #ifdef HAVE_LIBXXSHM
3582 int saveRed, saveGreen, saveBlue;
3584 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
3585 gdi_display, descr->drawable, bmpImage,
3586 descr->xSrc, descr->ySrc, AllPlanes);
3588 /* We must save and restore the bmpImage's masks in order
3589 * to preserve them across the call to XShmGetImage, which
3590 * decides to eleminate them since it doesn't happen to know
3591 * what the format of the image is supposed to be, even though
3593 saveRed = bmpImage->red_mask;
3594 saveBlue= bmpImage->blue_mask;
3595 saveGreen = bmpImage->green_mask;
3597 XShmGetImage( gdi_display, descr->drawable, bmpImage,
3598 descr->xSrc, descr->ySrc, AllPlanes);
3600 bmpImage->red_mask = saveRed;
3601 bmpImage->blue_mask = saveBlue;
3602 bmpImage->green_mask = saveGreen;
3605 #endif /* HAVE_LIBXXSHM */
3607 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
3608 gdi_display, descr->drawable, descr->xSrc, descr->ySrc, descr->width,
3609 lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
3610 XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc,
3611 descr->width, lines, AllPlanes, ZPixmap,
3612 bmpImage, descr->xDest, descr->yDest );
3615 TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
3616 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
3617 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
3618 bmpImage->depth,bmpImage->bits_per_pixel,
3619 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
3620 /* Transfer the pixels */
3621 switch(descr->infoBpp)
3624 X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
3625 descr->infoWidth, descr->width,
3626 descr->colorMap, descr->palentry,
3627 bmpImage, descr->dibpitch );
3631 if (descr->compression) {
3632 FIXME("Compression not yet supported!\n");
3633 if(descr->sizeImage < X11DRV_DIB_GetDIBWidthBytes( descr->infoWidth, 4 ) * abs(descr->lines))
3636 X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
3637 descr->infoWidth, descr->width,
3638 descr->colorMap, descr->palentry,
3639 bmpImage, descr->dibpitch );
3642 if (descr->compression) {
3643 FIXME("Compression not yet supported!\n");
3644 if(descr->sizeImage < X11DRV_DIB_GetDIBWidthBytes( descr->infoWidth, 8 ) * abs(descr->lines))
3647 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
3648 descr->infoWidth, descr->width,
3649 descr->colorMap, descr->palentry,
3650 bmpImage, descr->dibpitch );
3654 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
3655 descr->infoWidth,descr->width,
3657 descr->rMask, descr->gMask, descr->bMask,
3658 bmpImage, descr->dibpitch );
3662 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
3663 descr->infoWidth,descr->width,
3665 descr->rMask, descr->gMask, descr->bMask,
3666 bmpImage, descr->dibpitch);
3670 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
3671 descr->infoWidth, descr->width,
3673 descr->rMask, descr->gMask, descr->bMask,
3674 bmpImage, descr->dibpitch);
3678 WARN("(%d): Invalid depth\n", descr->infoBpp );
3682 if (!descr->image) XDestroyImage( bmpImage );
3683 wine_tsx11_unlock();
3687 /*************************************************************************
3688 * X11DRV_SetDIBitsToDevice
3691 INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWORD cx,
3692 DWORD cy, INT xSrc, INT ySrc,
3693 UINT startscan, UINT lines, LPCVOID bits,
3694 const BITMAPINFO *info, UINT coloruse )
3696 X11DRV_DIB_IMAGEBITS_DESCR descr;
3703 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
3704 &descr.infoBpp, &descr.compression ) == -1)
3707 top_down = (height < 0);
3708 if (top_down) height = -height;
3712 LPtoDP(physDev->hdc, &pt, 1);
3714 if (!lines || (startscan >= height)) return 0;
3715 if (!top_down && startscan + lines > height) lines = height - startscan;
3717 /* make xSrc,ySrc point to the upper-left corner, not the lower-left one,
3718 * and clamp all values to fit inside [startscan,startscan+lines]
3720 if (ySrc + cy <= startscan + lines)
3722 UINT y = startscan + lines - (ySrc + cy);
3723 if (ySrc < startscan) cy -= (startscan - ySrc);
3726 /* avoid getting unnecessary lines */
3728 if (y >= lines) return 0;
3733 if (y >= lines) return lines;
3734 ySrc = y; /* need to get all lines in top down mode */
3739 if (ySrc >= startscan + lines) return lines;
3740 pt.y += ySrc + cy - (startscan + lines);
3741 cy = startscan + lines - ySrc;
3743 if (cy > lines) cy = lines;
3745 if (xSrc >= width) return lines;
3746 if (xSrc + cx >= width) cx = width - xSrc;
3747 if (!cx || !cy) return lines;
3749 /* Update the pixmap from the DIB section */
3750 X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
3752 X11DRV_SetupGCForText( physDev ); /* To have the correct colors */
3754 XSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[GetROP2(physDev->hdc) - 1]);
3755 wine_tsx11_unlock();
3757 colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
3759 switch (descr.infoBpp)
3764 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
3765 coloruse == DIB_PAL_COLORS ? physDev : NULL, coloruse,
3766 physDev->depth, info, &descr.nColorMap );
3767 if (!descr.colorMap) return 0;
3768 descr.rMask = descr.gMask = descr.bMask = 0;
3772 descr.rMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr ) : 0x7c00;
3773 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr + 1) : 0x03e0;
3774 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr + 2) : 0x001f;
3780 descr.rMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr ) : 0xff0000;
3781 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr + 1) : 0x00ff00;
3782 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr + 2) : 0x0000ff;
3787 descr.physDev = physDev;
3790 descr.palentry = NULL;
3791 descr.lines = top_down ? -lines : lines;
3792 descr.infoWidth = width;
3793 descr.depth = physDev->depth;
3794 descr.drawable = physDev->drawable;
3795 descr.gc = physDev->gc;
3798 descr.xDest = physDev->org.x + pt.x;
3799 descr.yDest = physDev->org.y + pt.y;
3802 descr.useShm = FALSE;
3803 descr.dibpitch = ((width * descr.infoBpp + 31) &~31) / 8;
3805 result = X11DRV_DIB_SetImageBits( &descr );
3807 if (descr.infoBpp <= 8)
3808 HeapFree(GetProcessHeap(), 0, descr.colorMap);
3810 /* Update the DIBSection of the pixmap */
3811 X11DRV_UnlockDIBSection(physDev, TRUE);
3816 /***********************************************************************
3817 * SetDIBits (X11DRV.@)
3819 INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
3820 UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse )
3822 X11DRV_DIB_IMAGEBITS_DESCR descr;
3824 LONG height, tmpheight;
3828 descr.physDev = physDev;
3830 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
3831 &descr.infoBpp, &descr.compression ) == -1)
3835 if (height < 0) height = -height;
3836 if (!lines || (startscan >= height))
3839 if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
3841 if (startscan + lines > height) lines = height - startscan;
3843 colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
3845 switch (descr.infoBpp)
3850 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
3851 coloruse == DIB_PAL_COLORS ? descr.physDev : NULL, coloruse,
3852 bmp->bitmap.bmBitsPixel,
3853 info, &descr.nColorMap );
3854 if (!descr.colorMap)
3856 GDI_ReleaseObj( hbitmap );
3859 descr.rMask = descr.gMask = descr.bMask = 0;
3863 descr.rMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD*)colorPtr ) : 0x7c00;
3864 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD*)colorPtr + 1) : 0x03e0;
3865 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD*)colorPtr + 2) : 0x001f;
3871 descr.rMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD*)colorPtr ) : 0xff0000;
3872 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD*)colorPtr + 1) : 0x00ff00;
3873 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((const DWORD*)colorPtr + 2) : 0x0000ff;
3882 descr.palentry = NULL;
3883 descr.lines = tmpheight >= 0 ? lines : -lines;
3884 descr.depth = bmp->bitmap.bmBitsPixel;
3885 descr.drawable = (Pixmap)bmp->physBitmap;
3886 descr.gc = BITMAP_GC(bmp);
3890 descr.yDest = height - startscan - lines;
3891 descr.width = bmp->bitmap.bmWidth;
3892 descr.height = lines;
3893 descr.useShm = FALSE;
3894 descr.dibpitch = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
3895 X11DRV_DIB_Lock(bmp, DIB_Status_GdiMod, FALSE);
3896 result = X11DRV_DIB_SetImageBits( &descr );
3897 X11DRV_DIB_Unlock(bmp, TRUE);
3899 HeapFree(GetProcessHeap(), 0, descr.colorMap);
3901 GDI_ReleaseObj( hbitmap );
3905 /***********************************************************************
3906 * GetDIBits (X11DRV.@)
3908 INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan, UINT lines,
3909 LPVOID bits, BITMAPINFO *info, UINT coloruse )
3911 X11DRV_DIBSECTION *dib;
3912 X11DRV_DIB_IMAGEBITS_DESCR descr;
3913 PALETTEENTRY palette[256];
3921 GetPaletteEntries( GetCurrentObject( physDev->hdc, OBJ_PAL ), 0, 256, palette );
3923 if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
3925 dib = (X11DRV_DIBSECTION *) bmp->dib;
3927 bitmap_type = DIB_GetBitmapInfo( (BITMAPINFOHEADER*) info, &descr.infoWidth, &tempHeight, &descr.infoBpp, &descr.compression);
3928 descr.lines = tempHeight;
3929 if (bitmap_type == -1)
3931 ERR("Invalid bitmap\n");
3935 core_header = (bitmap_type == 0);
3936 colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
3938 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
3939 lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
3940 (int)descr.infoWidth, descr.lines, startscan);
3942 if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
3944 height = descr.lines;
3945 if (height < 0) height = -height;
3946 if( lines > height ) lines = height;
3947 /* Top-down images have a negative biHeight, the scanlines of theses images
3948 * were inverted in X11DRV_DIB_GetImageBits_xx
3949 * To prevent this we simply change the sign of lines
3950 * (the number of scan lines to copy).
3951 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3953 if( descr.lines < 0 && lines > 0) lines = -lines;
3955 if( startscan >= bmp->bitmap.bmHeight )
3961 descr.colorMap = NULL;
3963 switch (descr.infoBpp)
3968 descr.rMask= descr.gMask = descr.bMask = 0;
3969 if(coloruse == DIB_RGB_COLORS)
3970 descr.colorMap = colorPtr;
3972 int num_colors = 1 << descr.infoBpp, i;
3975 WORD *index = (WORD*)colorPtr;
3976 descr.colorMap = rgb = HeapAlloc(GetProcessHeap(), 0, num_colors * sizeof(RGBQUAD));
3977 for(i = 0; i < num_colors; i++, rgb++, index++) {
3978 colref = X11DRV_PALETTE_ToLogical(X11DRV_PALETTE_ToPhysical(physDev, PALETTEINDEX(*index)));
3979 rgb->rgbRed = GetRValue(colref);
3980 rgb->rgbGreen = GetGValue(colref);
3981 rgb->rgbBlue = GetBValue(colref);
3982 rgb->rgbReserved = 0;
3988 descr.rMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr ) : 0x7c00;
3989 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x03e0;
3990 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x001f;
3994 descr.rMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr ) : 0xff0000;
3995 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x00ff00;
3996 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x0000ff;
4000 descr.physDev = physDev;
4001 descr.palentry = palette;
4004 descr.lines = lines;
4005 descr.depth = bmp->bitmap.bmBitsPixel;
4006 descr.drawable = (Pixmap)bmp->physBitmap;
4007 descr.gc = BITMAP_GC(bmp);
4008 descr.width = bmp->bitmap.bmWidth;
4009 descr.height = bmp->bitmap.bmHeight;
4013 descr.sizeImage = core_header ? 0 : info->bmiHeader.biSizeImage;
4015 if (descr.lines > 0)
4017 descr.ySrc = (descr.height-1) - (startscan + (lines-1));
4021 descr.ySrc = startscan;
4023 #ifdef HAVE_LIBXXSHM
4024 descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
4026 descr.useShm = FALSE;
4028 descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
4029 : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
4031 X11DRV_DIB_Lock(bmp, DIB_Status_GdiMod, FALSE);
4032 X11DRV_DIB_GetImageBits( &descr );
4033 X11DRV_DIB_Unlock(bmp, TRUE);
4035 if(!core_header && info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
4036 info->bmiHeader.biSizeImage = X11DRV_DIB_GetDIBImageBytes( descr.infoWidth,
4040 if (descr.compression == BI_BITFIELDS)
4042 *(DWORD *) colorPtr = descr.rMask;
4043 *((DWORD *)colorPtr + 1) = descr.gMask;
4044 *((DWORD *)colorPtr + 2) = descr.bMask;
4046 else if (!core_header)
4048 /* if RLE or JPEG compression were supported,
4049 * this line would be invalid. */
4050 info->bmiHeader.biCompression = 0;
4053 if(descr.colorMap && descr.colorMap != colorPtr)
4054 HeapFree(GetProcessHeap(), 0, descr.colorMap);
4056 GDI_ReleaseObj( hbitmap );
4060 /***********************************************************************
4061 * DIB_DoProtectDIBSection
4063 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
4067 DIBSECTION *dib = bmp->dib;
4068 INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
4069 : -dib->dsBm.bmHeight;
4071 /* use the biSizeImage data as the memory size only if we're dealing with a
4072 compressed image where the value is set. Otherwise, calculate based on
4074 if (dib->dsBmih.biSizeImage &&
4075 (dib->dsBmih.biCompression == BI_RLE4 || dib->dsBmih.biCompression == BI_RLE8))
4076 totalSize = dib->dsBmih.biSizeImage;
4078 totalSize = dib->dsBm.bmWidthBytes * effHeight;
4080 VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
4081 TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
4084 /***********************************************************************
4085 * X11DRV_DIB_DoUpdateDIBSection
4087 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
4088 void *colorMap, int nColorMap,
4090 DWORD xSrc, DWORD ySrc,
4091 DWORD xDest, DWORD yDest,
4092 DWORD width, DWORD height)
4094 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4095 X11DRV_DIB_IMAGEBITS_DESCR descr;
4096 int identity[2] = {0,1};
4098 if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, (DWORD*) &descr.lines,
4099 &descr.infoBpp, &descr.compression ) == -1)
4102 descr.physDev = NULL;
4103 descr.palentry = NULL;
4104 descr.image = dib->image;
4105 descr.colorMap = colorMap;
4106 descr.nColorMap = nColorMap;
4107 descr.bits = dib->dibSection.dsBm.bmBits;
4108 descr.depth = bmp->bitmap.bmBitsPixel;
4110 if(descr.infoBpp == 1)
4111 descr.colorMap = (void*)identity;
4113 switch (descr.infoBpp)
4118 descr.rMask = descr.gMask = descr.bMask = 0;
4122 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
4123 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
4124 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
4129 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff0000;
4130 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x00ff00;
4131 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x0000ff;
4136 descr.drawable = dest;
4137 descr.gc = BITMAP_GC(bmp);
4140 descr.xDest = xDest;
4141 descr.yDest = yDest;
4142 descr.width = width;
4143 descr.height = height;
4144 descr.sizeImage = 0;
4146 #ifdef HAVE_LIBXXSHM
4147 descr.useShm = (dib->shminfo.shmid != -1);
4149 descr.useShm = FALSE;
4151 descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
4155 TRACE("Copying from Pixmap to DIB bits\n");
4156 X11DRV_DIB_GetImageBits( &descr );
4160 TRACE("Copying from DIB bits to Pixmap\n");
4161 X11DRV_DIB_SetImageBits( &descr );
4165 /***********************************************************************
4166 * X11DRV_DIB_CopyDIBSection
4168 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
4169 DWORD xSrc, DWORD ySrc, DWORD xDest, DWORD yDest,
4170 DWORD width, DWORD height)
4174 int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE;
4176 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", physDevSrc->hdc, physDevDst->hdc,
4177 xSrc, ySrc, xDest, yDest, width, height);
4178 /* this function is meant as an optimization for BitBlt,
4179 * not to be called otherwise */
4180 if (GetObjectType( physDevSrc->hdc ) != OBJ_MEMDC) {
4181 ERR("called for non-memory source DC!?\n");
4185 hBitmap = GetCurrentObject( physDevSrc->hdc, OBJ_BITMAP );
4186 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC );
4187 if (!(bmp && bmp->dib)) {
4188 ERR("called for non-DIBSection!?\n");
4189 GDI_ReleaseObj( hBitmap );
4192 /* while BitBlt should already have made sure we only get
4193 * positive values, we should check for oversize values */
4194 if ((xSrc < bmp->bitmap.bmWidth) &&
4195 (ySrc < bmp->bitmap.bmHeight)) {
4196 if (xSrc + width > bmp->bitmap.bmWidth)
4197 width = bmp->bitmap.bmWidth - xSrc;
4198 if (ySrc + height > bmp->bitmap.bmHeight)
4199 height = bmp->bitmap.bmHeight - ySrc;
4200 /* if the source bitmap is 8bpp or less, we're supposed to use the
4201 * DC's palette for color conversion (not the DIB color table) */
4202 if (bmp->dib->dsBm.bmBitsPixel <= 8) {
4203 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4204 HPALETTE hPalette = GetCurrentObject( physDevSrc->hdc, OBJ_PAL );
4205 if (!hPalette || (hPalette == GetStockObject(DEFAULT_PALETTE))) {
4206 /* HACK: no palette has been set in the source DC,
4207 * use the DIB colormap instead - this is necessary in some
4208 * cases since we need to do depth conversion in some places
4209 * where real Windows can just copy data straight over */
4210 colorMap = dib->colorMap;
4211 nColorMap = dib->nColorMap;
4213 colorMap = X11DRV_DIB_BuildColorMap( physDevSrc, (WORD)-1,
4214 bmp->dib->dsBm.bmBitsPixel,
4215 (BITMAPINFO*)&(bmp->dib->dsBmih),
4217 if (colorMap) aColorMap = TRUE;
4220 /* perform the copy */
4221 X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap,
4222 physDevDst->drawable, xSrc, ySrc,
4223 physDevDst->org.x + xDest, physDevDst->org.y + yDest,
4225 /* free color mapping */
4227 HeapFree(GetProcessHeap(), 0, colorMap);
4229 GDI_ReleaseObj( hBitmap );
4232 /***********************************************************************
4233 * X11DRV_DIB_DoUpdateDIBSection
4235 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
4237 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4238 X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap,
4239 (Drawable)bmp->physBitmap, 0, 0, 0, 0,
4240 bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
4243 /***********************************************************************
4244 * X11DRV_DIB_FaultHandler
4246 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
4251 bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
4252 if (!bmp) return FALSE;
4254 state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
4255 if (state != DIB_Status_InSync) {
4256 /* no way to tell whether app needs read or write yet,
4258 X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
4260 /* hm, apparently the app must have write access */
4261 X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
4263 X11DRV_DIB_Unlock(bmp, TRUE);
4265 GDI_ReleaseObj( (HBITMAP)res );
4269 /***********************************************************************
4272 INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
4274 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4275 INT ret = DIB_Status_None;
4278 EnterCriticalSection(&(dib->lock));
4281 case DIB_Status_GdiMod:
4282 /* GDI access - request to draw on pixmap */
4283 switch (dib->status)
4286 case DIB_Status_None:
4287 dib->p_status = DIB_Status_GdiMod;
4288 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
4291 case DIB_Status_GdiMod:
4292 TRACE("GdiMod requested in status GdiMod\n" );
4293 dib->p_status = DIB_Status_GdiMod;
4296 case DIB_Status_InSync:
4297 TRACE("GdiMod requested in status InSync\n" );
4298 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
4299 dib->status = DIB_Status_GdiMod;
4300 dib->p_status = DIB_Status_InSync;
4303 case DIB_Status_AuxMod:
4304 TRACE("GdiMod requested in status AuxMod\n" );
4305 if (lossy) dib->status = DIB_Status_GdiMod;
4306 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
4307 dib->p_status = DIB_Status_AuxMod;
4308 if (dib->status != DIB_Status_AppMod) {
4309 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
4312 /* fall through if copy_aux() had to change to AppMod state */
4314 case DIB_Status_AppMod:
4315 TRACE("GdiMod requested in status AppMod\n" );
4317 /* make it readonly to avoid app changing data while we copy */
4318 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4319 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
4321 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
4322 dib->p_status = DIB_Status_AppMod;
4323 dib->status = DIB_Status_GdiMod;
4328 case DIB_Status_InSync:
4329 /* App access - request access to read DIB surface */
4330 /* (typically called from signal handler) */
4331 switch (dib->status)
4334 case DIB_Status_None:
4335 /* shouldn't happen from signal handler */
4338 case DIB_Status_AuxMod:
4339 TRACE("InSync requested in status AuxMod\n" );
4340 if (lossy) dib->status = DIB_Status_InSync;
4342 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4343 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
4345 if (dib->status != DIB_Status_GdiMod) {
4346 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4349 /* fall through if copy_aux() had to change to GdiMod state */
4351 case DIB_Status_GdiMod:
4352 TRACE("InSync requested in status GdiMod\n" );
4354 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4355 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
4357 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4358 dib->status = DIB_Status_InSync;
4361 case DIB_Status_InSync:
4362 TRACE("InSync requested in status InSync\n" );
4363 /* shouldn't happen from signal handler */
4366 case DIB_Status_AppMod:
4367 TRACE("InSync requested in status AppMod\n" );
4368 /* no reason to do anything here, and this
4369 * shouldn't happen from signal handler */
4374 case DIB_Status_AppMod:
4375 /* App access - request access to write DIB surface */
4376 /* (typically called from signal handler) */
4377 switch (dib->status)
4380 case DIB_Status_None:
4381 /* shouldn't happen from signal handler */
4384 case DIB_Status_AuxMod:
4385 TRACE("AppMod requested in status AuxMod\n" );
4386 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4387 if (lossy) dib->status = DIB_Status_AppMod;
4388 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
4389 if (dib->status != DIB_Status_GdiMod)
4391 /* fall through if copy_aux() had to change to GdiMod state */
4393 case DIB_Status_GdiMod:
4394 TRACE("AppMod requested in status GdiMod\n" );
4395 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4396 if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
4397 dib->status = DIB_Status_AppMod;
4400 case DIB_Status_InSync:
4401 TRACE("AppMod requested in status InSync\n" );
4402 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4403 dib->status = DIB_Status_AppMod;
4406 case DIB_Status_AppMod:
4407 TRACE("AppMod requested in status AppMod\n" );
4408 /* shouldn't happen from signal handler */
4413 case DIB_Status_AuxMod:
4414 if (dib->status == DIB_Status_None) {
4415 dib->p_status = req;
4417 if (dib->status != DIB_Status_AuxMod)
4418 dib->p_status = dib->status;
4419 dib->status = DIB_Status_AuxMod;
4422 /* it is up to the caller to do the copy/conversion, probably
4423 * using the return value to decide where to copy from */
4425 LeaveCriticalSection(&(dib->lock));
4430 /***********************************************************************
4433 INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
4435 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4436 INT ret = DIB_Status_None;
4439 TRACE("Locking %p from thread %04lx\n", bmp, GetCurrentThreadId());
4440 EnterCriticalSection(&(dib->lock));
4442 if (req != DIB_Status_None)
4443 X11DRV_DIB_Coerce(bmp, req, lossy);
4448 /***********************************************************************
4451 void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
4453 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4456 switch (dib->status)
4459 case DIB_Status_None:
4460 /* in case anyone is wondering, this is the "signal handler doesn't
4461 * work" case, where we always have to be ready for app access */
4463 switch (dib->p_status)
4465 case DIB_Status_AuxMod:
4466 TRACE("Unlocking and syncing from AuxMod\n" );
4467 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
4468 if (dib->status != DIB_Status_None) {
4469 dib->p_status = dib->status;
4470 dib->status = DIB_Status_None;
4472 if (dib->p_status != DIB_Status_GdiMod)
4474 /* fall through if copy_aux() had to change to GdiMod state */
4476 case DIB_Status_GdiMod:
4477 TRACE("Unlocking and syncing from GdiMod\n" );
4478 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
4482 TRACE("Unlocking without needing to sync\n" );
4486 else TRACE("Unlocking with no changes\n");
4487 dib->p_status = DIB_Status_None;
4490 case DIB_Status_GdiMod:
4491 TRACE("Unlocking in status GdiMod\n" );
4492 /* DIB was protected in Coerce */
4494 /* no commit, revert to InSync if applicable */
4495 if ((dib->p_status == DIB_Status_InSync) ||
4496 (dib->p_status == DIB_Status_AppMod)) {
4497 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4498 dib->status = DIB_Status_InSync;
4503 case DIB_Status_InSync:
4504 TRACE("Unlocking in status InSync\n" );
4505 /* DIB was already protected in Coerce */
4508 case DIB_Status_AppMod:
4509 TRACE("Unlocking in status AppMod\n" );
4510 /* DIB was already protected in Coerce */
4511 /* this case is ordinary only called from the signal handler,
4512 * so we don't bother to check for !commit */
4515 case DIB_Status_AuxMod:
4516 TRACE("Unlocking in status AuxMod\n" );
4518 /* DIB may need protection now */
4519 if ((dib->p_status == DIB_Status_InSync) ||
4520 (dib->p_status == DIB_Status_AppMod))
4521 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
4523 /* no commit, revert to previous state */
4524 if (dib->p_status != DIB_Status_None)
4525 dib->status = dib->p_status;
4526 /* no protections changed */
4528 dib->p_status = DIB_Status_None;
4531 LeaveCriticalSection(&(dib->lock));
4532 TRACE("Unlocked %p\n", bmp);
4536 /***********************************************************************
4537 * X11DRV_CoerceDIBSection2
4539 INT X11DRV_CoerceDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
4544 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4545 if (!bmp) return DIB_Status_None;
4546 ret = X11DRV_DIB_Coerce(bmp, req, lossy);
4547 GDI_ReleaseObj( hBmp );
4551 /***********************************************************************
4552 * X11DRV_LockDIBSection2
4554 INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
4559 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4560 if (!bmp) return DIB_Status_None;
4561 ret = X11DRV_DIB_Lock(bmp, req, lossy);
4562 GDI_ReleaseObj( hBmp );
4566 /***********************************************************************
4567 * X11DRV_UnlockDIBSection2
4569 void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
4573 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4575 X11DRV_DIB_Unlock(bmp, commit);
4576 GDI_ReleaseObj( hBmp );
4579 /***********************************************************************
4580 * X11DRV_CoerceDIBSection
4582 INT X11DRV_CoerceDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
4584 if (!physDev) return DIB_Status_None;
4585 return X11DRV_CoerceDIBSection2( GetCurrentObject( physDev->hdc, OBJ_BITMAP ), req, lossy );
4588 /***********************************************************************
4589 * X11DRV_LockDIBSection
4591 INT X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
4593 if (!physDev) return DIB_Status_None;
4594 if (GetObjectType( physDev->hdc ) != OBJ_MEMDC) return DIB_Status_None;
4596 return X11DRV_LockDIBSection2( GetCurrentObject( physDev->hdc, OBJ_BITMAP ), req, lossy );
4599 /***********************************************************************
4600 * X11DRV_UnlockDIBSection
4602 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE *physDev, BOOL commit)
4604 if (!physDev) return;
4605 if (GetObjectType( physDev->hdc ) != OBJ_MEMDC) return;
4607 X11DRV_UnlockDIBSection2( GetCurrentObject( physDev->hdc, OBJ_BITMAP ), commit );
4611 #ifdef HAVE_LIBXXSHM
4612 /***********************************************************************
4613 * X11DRV_XShmErrorHandler
4616 static int XShmErrorHandler( Display *dpy, XErrorEvent *event, void *arg )
4618 return 1; /* FIXME: should check event contents */
4621 /***********************************************************************
4622 * X11DRV_XShmCreateImage
4625 static XImage *X11DRV_XShmCreateImage( int width, int height, int bpp,
4626 XShmSegmentInfo* shminfo)
4630 image = XShmCreateImage(gdi_display, visual, bpp, ZPixmap, NULL, shminfo, width, height);
4633 shminfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height,
4635 if( shminfo->shmid != -1 )
4637 shminfo->shmaddr = image->data = shmat(shminfo->shmid, 0, 0);
4638 if( shminfo->shmaddr != (char*)-1 )
4642 shminfo->readOnly = FALSE;
4643 X11DRV_expect_error( gdi_display, XShmErrorHandler, NULL );
4644 ok = (XShmAttach( gdi_display, shminfo ) != 0);
4645 XSync( gdi_display, False );
4646 if (X11DRV_check_error()) ok = FALSE;
4649 shmctl(shminfo->shmid, IPC_RMID, 0);
4650 return image; /* Success! */
4652 /* An error occurred */
4653 shmdt(shminfo->shmaddr);
4655 shmctl(shminfo->shmid, IPC_RMID, 0);
4657 XFlush(gdi_display);
4658 XDestroyImage(image);
4663 #endif /* HAVE_LIBXXSHM */
4666 /***********************************************************************
4667 * X11DRV_DIB_CreateDIBSection
4669 HBITMAP X11DRV_DIB_CreateDIBSection(
4670 X11DRV_PDEVICE *physDev, const BITMAPINFO *bmi, UINT usage,
4671 VOID **bits, HANDLE section,
4672 DWORD offset, DWORD ovr_pitch)
4675 BITMAPOBJ *bmp = NULL;
4676 X11DRV_DIBSECTION *dib = NULL;
4677 int *colorMap = NULL;
4679 RGBQUAD *colorTable = NULL;
4681 /* Fill BITMAP structure with DIB data */
4682 INT effHeight, totalSize;
4684 LPVOID mapBits = NULL;
4689 WORD planes, bpp, compression;
4693 if (((bitmap_type = DIB_GetBitmapInfoEx((BITMAPINFOHEADER*) bmi,
4694 &width, &height, &planes, &bpp, &compression, &sizeImage)) == -1))
4696 ERR("Invalid bitmap\n");
4699 core_header = (bitmap_type == 0);
4701 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, %s\n",
4702 width, height, planes, bpp,
4703 sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
4705 effHeight = height >= 0 ? height : -height;
4708 bm.bmHeight = effHeight;
4709 bm.bmWidthBytes = ovr_pitch ? ovr_pitch : X11DRV_DIB_GetDIBWidthBytes(bm.bmWidth, bpp);
4710 bm.bmPlanes = planes;
4711 bm.bmBitsPixel = bpp;
4714 /* Get storage location for DIB bits. Only use sizeImage if it's valid and
4715 we're dealing with a compressed bitmap. Otherwise, use width * height. */
4716 if (sizeImage && (compression == BI_RLE4 || compression == BI_RLE8))
4717 totalSize = sizeImage;
4719 totalSize = bm.bmWidthBytes * effHeight;
4723 SYSTEM_INFO SystemInfo;
4727 GetSystemInfo( &SystemInfo );
4728 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
4729 mapSize = totalSize + (offset - mapOffset);
4730 mapBits = MapViewOfFile( section,
4731 FILE_MAP_ALL_ACCESS,
4735 bm.bmBits = (char *)mapBits + (offset - mapOffset);
4737 else if (ovr_pitch && offset)
4738 bm.bmBits = (LPVOID) offset;
4741 bm.bmBits = VirtualAlloc(NULL, totalSize,
4742 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
4745 /* Create Color Map */
4746 if (bm.bmBits && bm.bmBitsPixel <= 8) {
4747 colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? physDev : NULL,
4748 usage, bm.bmBitsPixel, bmi, &nColorMap );
4749 colorTable = X11DRV_DIB_BuildColorTable( physDev, usage, bm.bmBitsPixel, bmi );
4751 /* Allocate Memory for DIB and fill structure */
4753 dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
4756 dib->dibSection.dsBm = bm;
4760 /* Convert the BITMAPCOREHEADER to a BITMAPINFOHEADER.
4761 The structure is already filled with zeros */
4762 dib->dibSection.dsBmih.biSize = sizeof(BITMAPINFOHEADER);
4763 dib->dibSection.dsBmih.biWidth = width;
4764 dib->dibSection.dsBmih.biHeight = height;
4765 dib->dibSection.dsBmih.biPlanes = planes;
4766 dib->dibSection.dsBmih.biBitCount = bpp;
4767 dib->dibSection.dsBmih.biCompression = compression;
4771 /* Truncate extended bitmap headers (BITMAPV4HEADER etc.) */
4772 dib->dibSection.dsBmih = *((BITMAPINFOHEADER*) bmi);
4773 dib->dibSection.dsBmih.biSize = sizeof(BITMAPINFOHEADER);
4776 dib->dibSection.dsBmih.biSizeImage = totalSize;
4777 colorPtr = (LPBYTE) bmi + (WORD) bmi->bmiHeader.biSize;
4779 /* Set dsBitfields values */
4780 if ( usage == DIB_PAL_COLORS || bpp <= 8)
4782 dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
4788 dib->dibSection.dsBitfields[0] = (compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr ) : 0x7c00;
4789 dib->dibSection.dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr + 1) : 0x03e0;
4790 dib->dibSection.dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr + 2) : 0x001f;
4795 dib->dibSection.dsBitfields[0] = (compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr ) : 0xff0000;
4796 dib->dibSection.dsBitfields[1] = (compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr + 1) : 0x00ff00;
4797 dib->dibSection.dsBitfields[2] = (compression == BI_BITFIELDS) ? *((const DWORD *)colorPtr + 2) : 0x0000ff;
4800 dib->dibSection.dshSection = section;
4801 dib->dibSection.dsOffset = offset;
4803 dib->status = DIB_Status_None;
4804 dib->nColorMap = nColorMap;
4805 dib->colorMap = colorMap;
4806 dib->colorTable = colorTable;
4809 /* Create Device Dependent Bitmap and add DIB pointer */
4812 int depth = (bpp == 1) ? 1 : GetDeviceCaps(physDev->hdc, BITSPIXEL);
4813 res = CreateBitmap(width, effHeight, 1, depth, NULL);
4817 bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
4818 if (bmp) bmp->dib = (DIBSECTION *) dib;
4826 #ifdef HAVE_LIBXXSHM
4827 if (XShmQueryExtension(gdi_display) &&
4828 (dib->image = X11DRV_XShmCreateImage( bm.bmWidth, effHeight,
4829 bmp->bitmap.bmBitsPixel, &dib->shminfo )) )
4831 ; /* Created Image */
4833 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
4834 dib->shminfo.shmid = -1;
4837 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
4839 wine_tsx11_unlock();
4842 /* Clean up in case of errors */
4843 if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
4845 TRACE("got an error res=%p, bmp=%p, dib=%p, bm.bmBits=%p\n",
4846 res, bmp, dib, bm.bmBits);
4850 UnmapViewOfFile(mapBits), bm.bmBits = NULL;
4852 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
4855 if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
4856 HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL;
4857 HeapFree(GetProcessHeap(), 0, colorTable); colorTable = NULL;
4858 HeapFree(GetProcessHeap(), 0, dib); dib = NULL;
4859 if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
4860 if (res) { DeleteObject(res); res = 0; }
4864 extern BOOL VIRTUAL_SetFaultHandler(LPCVOID addr, BOOL (*proc)(LPVOID, LPCVOID), LPVOID arg);
4865 /* Install fault handler, if possible */
4866 InitializeCriticalSection(&(dib->lock));
4867 if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
4869 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4870 if (dib) dib->status = DIB_Status_AppMod;
4874 /* Return BITMAP handle and storage location */
4875 if (bmp) GDI_ReleaseObj(res);
4876 if (bm.bmBits && bits) *bits = bm.bmBits;
4880 /***********************************************************************
4881 * X11DRV_DIB_DeleteDIBSection
4883 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
4885 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4887 if (dib->dibSection.dshSection)
4888 X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
4893 #ifdef HAVE_LIBXXSHM
4894 if (dib->shminfo.shmid != -1)
4896 XShmDetach (gdi_display, &(dib->shminfo));
4897 XDestroyImage (dib->image);
4898 shmdt (dib->shminfo.shmaddr);
4899 dib->shminfo.shmid = -1;
4903 XDestroyImage( dib->image );
4904 wine_tsx11_unlock();
4907 HeapFree(GetProcessHeap(), 0, dib->colorMap);
4908 HeapFree(GetProcessHeap(), 0, dib->colorTable);
4910 DeleteCriticalSection(&(dib->lock));
4913 /***********************************************************************
4914 * SetDIBColorTable (X11DRV.@)
4916 UINT X11DRV_SetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, const RGBQUAD *colors )
4919 X11DRV_DIBSECTION *dib;
4921 HBITMAP hBitmap = GetCurrentObject( physDev->hdc, OBJ_BITMAP );
4923 if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC ))) return 0;
4924 dib = (X11DRV_DIBSECTION *) bmp->dib;
4926 if (dib && dib->colorMap && start < dib->nColorMap) {
4927 UINT end = count + start;
4928 if (end > dib->nColorMap) end = dib->nColorMap;
4930 * Changing color table might change the mapping between
4931 * DIB colors and X11 colors and thus alter the visible state
4932 * of the bitmap object.
4934 X11DRV_DIB_Lock(bmp, DIB_Status_AppMod, FALSE);
4935 memcpy(dib->colorTable + start, colors, (end - start) * sizeof(RGBQUAD));
4936 X11DRV_DIB_GenColorMap( physDev, dib->colorMap, DIB_RGB_COLORS,
4937 dib->dibSection.dsBm.bmBitsPixel,
4938 TRUE, colors, start, end );
4939 X11DRV_DIB_Unlock(bmp, TRUE);
4942 GDI_ReleaseObj( hBitmap );
4946 /***********************************************************************
4947 * GetDIBColorTable (X11DRV.@)
4949 UINT X11DRV_GetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, RGBQUAD *colors )
4952 X11DRV_DIBSECTION *dib;
4954 HBITMAP hBitmap = GetCurrentObject( physDev->hdc, OBJ_BITMAP );
4956 if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC ))) return 0;
4957 dib = (X11DRV_DIBSECTION *) bmp->dib;
4959 if (dib && dib->colorTable && start < dib->nColorMap) {
4960 if (start + count > dib->nColorMap) count = dib->nColorMap - start;
4961 memcpy(colors, dib->colorTable + start, count * sizeof(RGBQUAD));
4964 GDI_ReleaseObj( hBitmap );
4970 /***********************************************************************
4971 * X11DRV_DIB_CreateDIBFromBitmap
4973 * Allocates a packed DIB and copies the bitmap data into it.
4975 HGLOBAL X11DRV_DIB_CreateDIBFromBitmap(HDC hdc, HBITMAP hBmp)
4980 LPBITMAPINFOHEADER pbmiHeader;
4981 unsigned int cDataSize, cPackedSize, OffsetBits;
4984 if (!GetObjectW( hBmp, sizeof(bmp), &bmp )) return 0;
4987 * A packed DIB contains a BITMAPINFO structure followed immediately by
4988 * an optional color palette and the pixel data.
4991 /* Calculate the size of the packed DIB */
4992 cDataSize = X11DRV_DIB_GetDIBWidthBytes( bmp.bmWidth, bmp.bmBitsPixel ) * abs( bmp.bmHeight );
4993 cPackedSize = sizeof(BITMAPINFOHEADER)
4994 + ( (bmp.bmBitsPixel <= 8) ? (sizeof(RGBQUAD) * (1 << bmp.bmBitsPixel)) : 0 )
4996 /* Get the offset to the bits */
4997 OffsetBits = cPackedSize - cDataSize;
4999 /* Allocate the packed DIB */
5000 TRACE("\tAllocating packed DIB of size %d\n", cPackedSize);
5001 hPackedDIB = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE /*| GMEM_ZEROINIT*/,
5005 WARN("Could not allocate packed DIB!\n");
5009 /* A packed DIB starts with a BITMAPINFOHEADER */
5010 pPackedDIB = GlobalLock(hPackedDIB);
5011 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
5013 /* Init the BITMAPINFOHEADER */
5014 pbmiHeader->biSize = sizeof(BITMAPINFOHEADER);
5015 pbmiHeader->biWidth = bmp.bmWidth;
5016 pbmiHeader->biHeight = bmp.bmHeight;
5017 pbmiHeader->biPlanes = 1;
5018 pbmiHeader->biBitCount = bmp.bmBitsPixel;
5019 pbmiHeader->biCompression = BI_RGB;
5020 pbmiHeader->biSizeImage = 0;
5021 pbmiHeader->biXPelsPerMeter = pbmiHeader->biYPelsPerMeter = 0;
5022 pbmiHeader->biClrUsed = 0;
5023 pbmiHeader->biClrImportant = 0;
5025 /* Retrieve the DIB bits from the bitmap and fill in the
5026 * DIB color table if present */
5028 nLinesCopied = GetDIBits(hdc, /* Handle to device context */
5029 hBmp, /* Handle to bitmap */
5030 0, /* First scan line to set in dest bitmap */
5031 bmp.bmHeight, /* Number of scan lines to copy */
5032 pPackedDIB + OffsetBits, /* [out] Address of array for bitmap bits */
5033 (LPBITMAPINFO) pbmiHeader, /* [out] Address of BITMAPINFO structure */
5034 0); /* RGB or palette index */
5035 GlobalUnlock(hPackedDIB);
5037 /* Cleanup if GetDIBits failed */
5038 if (nLinesCopied != bmp.bmHeight)
5040 TRACE("\tGetDIBits returned %d. Actual lines=%d\n", nLinesCopied, bmp.bmHeight);
5041 GlobalFree(hPackedDIB);
5048 /**************************************************************************
5049 * X11DRV_DIB_CreateDIBFromPixmap
5051 * Allocates a packed DIB and copies the Pixmap data into it.
5052 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
5054 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
5057 BITMAPOBJ *pBmp = NULL;
5058 HGLOBAL hPackedDIB = 0;
5060 /* Allocates an HBITMAP which references the Pixmap passed to us */
5061 hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(hdc, pixmap);
5064 TRACE("\tCould not create bitmap header for Pixmap\n");
5069 * Create a packed DIB from the Pixmap wrapper bitmap created above.
5070 * A packed DIB contains a BITMAPINFO structure followed immediately by
5071 * an optional color palette and the pixel data.
5073 hPackedDIB = X11DRV_DIB_CreateDIBFromBitmap(hdc, hBmp);
5075 /* Get a pointer to the BITMAPOBJ structure */
5076 pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5078 /* We can now get rid of the HBITMAP wrapper we created earlier.
5079 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
5083 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
5084 pBmp->physBitmap = NULL;
5087 GDI_ReleaseObj( hBmp );
5091 TRACE("\tReturning packed DIB %p\n", hPackedDIB);
5096 /**************************************************************************
5097 * X11DRV_DIB_CreatePixmapFromDIB
5099 * Creates a Pixmap from a packed DIB
5101 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
5103 Pixmap pixmap = None;
5105 BITMAPOBJ *pBmp = NULL;
5106 LPBYTE pPackedDIB = NULL;
5107 LPBITMAPINFO pbmi = NULL;
5108 LPBITMAPINFOHEADER pbmiHeader = NULL;
5109 LPBYTE pbits = NULL;
5111 /* Get a pointer to the packed DIB's data */
5112 pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
5113 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
5114 pbmi = (LPBITMAPINFO)pPackedDIB;
5115 pbits = (LPBYTE)(pPackedDIB
5116 + X11DRV_DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
5118 /* Create a DDB from the DIB */
5120 hBmp = CreateDIBitmap(hdc,
5127 GlobalUnlock(hPackedDIB);
5129 TRACE("CreateDIBitmap returned %p\n", hBmp);
5131 /* Retrieve the internal Pixmap from the DDB */
5133 pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5135 pixmap = (Pixmap)pBmp->physBitmap;
5136 /* clear the physBitmap so that we can steal its pixmap */
5137 pBmp->physBitmap = NULL;
5140 /* Delete the DDB we created earlier now that we have stolen its pixmap */
5141 GDI_ReleaseObj( hBmp );
5144 TRACE("\tReturning Pixmap %ld\n", pixmap);