2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <X11/extensions/XShm.h>
26 # ifdef HAVE_SYS_SHM_H
29 # ifdef HAVE_SYS_IPC_H
32 #endif /* defined(HAVE_LIBXXSHM) */
41 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
44 WINE_DECLARE_DEBUG_CHANNEL(x11drv);
46 static int ximageDepthTable[32];
48 /* This structure holds the arguments for DIB_SetImageBits() */
51 X11DRV_PDEVICE *physDev;
54 PALETTEENTRY *palentry;
76 } X11DRV_DIB_IMAGEBITS_DESCR;
81 RLE_EOL = 0, /* End of line */
82 RLE_END = 1, /* End of bitmap */
83 RLE_DELTA = 2 /* Delta */
86 /***********************************************************************
87 * X11DRV_DIB_GetXImageWidthBytes
89 * Return the width of an X image in bytes
91 inline static int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
93 if (!depth || depth > 32) goto error;
95 if (!ximageDepthTable[depth-1])
97 XImage *testimage = XCreateImage( gdi_display, visual, depth,
98 ZPixmap, 0, NULL, 1, 1, 32, 20 );
101 ximageDepthTable[depth-1] = testimage->bits_per_pixel;
102 XDestroyImage( testimage );
104 else ximageDepthTable[depth-1] = -1;
106 if (ximageDepthTable[depth-1] != -1)
107 return (4 * ((width * ximageDepthTable[depth-1] + 31) / 32));
110 WARN( "(%d): Unsupported depth\n", depth );
115 /***********************************************************************
116 * X11DRV_DIB_GetDIBWidthBytes
118 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
120 static int X11DRV_DIB_GetDIBWidthBytes( int width, int depth )
126 case 1: words = (width + 31) / 32; break;
127 case 4: words = (width + 7) / 8; break;
128 case 8: words = (width + 3) / 4; break;
130 case 16: words = (width + 1) / 2; break;
131 case 24: words = (width * 3 + 3) / 4; break;
133 WARN("(%d): Unsupported depth\n", depth );
142 /***********************************************************************
143 * X11DRV_DIB_BitmapInfoSize
145 * Return the size of the bitmap info structure including color table.
147 int X11DRV_DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse )
151 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
153 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
154 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
155 return sizeof(BITMAPCOREHEADER) + colors *
156 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
158 else /* assume BITMAPINFOHEADER */
160 colors = info->bmiHeader.biClrUsed;
161 if (!colors && (info->bmiHeader.biBitCount <= 8))
162 colors = 1 << info->bmiHeader.biBitCount;
163 return sizeof(BITMAPINFOHEADER) + colors *
164 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
169 /***********************************************************************
170 * X11DRV_DIB_CreateXImage
174 XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth )
180 width_bytes = X11DRV_DIB_GetXImageWidthBytes( width, depth );
181 image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0,
182 calloc( height, width_bytes ),
183 width, height, 32, width_bytes );
189 /***********************************************************************
192 * Get the info from a bitmap header.
193 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
195 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
196 int *height, WORD *bpp, WORD *compr )
198 if (header->biSize == sizeof(BITMAPCOREHEADER))
200 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
201 *width = core->bcWidth;
202 *height = core->bcHeight;
203 *bpp = core->bcBitCount;
207 if (header->biSize >= sizeof(BITMAPINFOHEADER))
209 *width = header->biWidth;
210 *height = header->biHeight;
211 *bpp = header->biBitCount;
212 *compr = header->biCompression;
215 ERR("(%ld): unknown/wrong size for header\n", header->biSize );
220 /***********************************************************************
221 * X11DRV_DIB_GenColorMap
223 * Fills the color map of a bitmap palette. Should not be called
224 * for a >8-bit deep bitmap.
226 int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
227 WORD coloruse, WORD depth, BOOL quads,
228 const void *colorPtr, int start, int end )
232 if (coloruse == DIB_RGB_COLORS)
234 int max = 1 << depth;
236 if (end > max) end = max;
240 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
242 if (depth == 1) /* Monochrome */
243 for (i = start; i < end; i++, rgb++)
244 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
245 rgb->rgbBlue > 255*3/2);
247 for (i = start; i < end; i++, rgb++)
248 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbRed,
254 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
256 if (depth == 1) /* Monochrome */
257 for (i = start; i < end; i++, rgb++)
258 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
259 rgb->rgbtBlue > 255*3/2);
261 for (i = start; i < end; i++, rgb++)
262 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbtRed,
267 else /* DIB_PAL_COLORS */
270 WORD * index = (WORD *)colorPtr;
272 for (i = start; i < end; i++, index++)
273 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(*index) );
275 for (i = start; i < end; i++)
276 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(i) );
283 /***********************************************************************
284 * X11DRV_DIB_BuildColorMap
286 * Build the color map from the bitmap palette. Should not be called
287 * for a >8-bit deep bitmap.
289 int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
290 const BITMAPINFO *info, int *nColors )
294 const void *colorPtr;
297 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
299 colors = info->bmiHeader.biClrUsed;
300 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
301 colorPtr = info->bmiColors;
303 else /* assume BITMAPCOREINFO */
305 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
306 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
311 ERR("called with >256 colors!\n");
315 /* just so CopyDIBSection doesn't have to create an identity palette */
316 if (coloruse == (WORD)-1) colorPtr = NULL;
318 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
319 colors * sizeof(int) )))
323 return X11DRV_DIB_GenColorMap( physDev, colorMapping, coloruse, depth,
324 isInfo, colorPtr, 0, colors);
327 /***********************************************************************
328 * X11DRV_DIB_BuildColorTable
330 * Build the dib color table. This either keeps a copy of the bmiColors array if
331 * usage is DIB_RGB_COLORS, or looks up the palette indicies if usage is
333 * Should not be called for a >8-bit deep bitmap.
335 static RGBQUAD *X11DRV_DIB_BuildColorTable( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
336 const BITMAPINFO *info )
341 colors = info->bmiHeader.biClrUsed;
342 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
345 ERR("called with >256 colors!\n");
349 if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) )))
352 if(coloruse == DIB_RGB_COLORS)
353 memcpy(colorTable, info->bmiColors, colors * sizeof(RGBQUAD));
355 HPALETTE hpal = GetCurrentObject(physDev->hdc, OBJ_PAL);
356 PALETTEENTRY pal_ents[256];
359 GetPaletteEntries(hpal, 0, 256, pal_ents);
360 for(i = 0, index = (WORD*)info->bmiColors; i < colors; i++, index++) {
361 colorTable[i].rgbRed = pal_ents[*index].peRed;
362 colorTable[i].rgbGreen = pal_ents[*index].peGreen;
363 colorTable[i].rgbBlue = pal_ents[*index].peBlue;
364 colorTable[i].rgbReserved = 0;
371 /***********************************************************************
372 * X11DRV_DIB_MapColor
374 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
378 if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
381 for (color = 0; color < nPhysMap; color++)
382 if (physMap[color] == phys)
385 WARN("Strange color %08x\n", phys);
390 /*********************************************************************
391 * X11DRV_DIB_GetNearestIndex
393 * Helper for X11DRV_DIB_GetDIBits.
394 * Returns the nearest colour table index for a given RGB.
395 * Nearest is defined by minimizing the sum of the squares.
397 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
399 INT i, best = -1, diff, bestdiff = -1;
402 for(color = colormap, i = 0; i < numColors; color++, i++) {
403 diff = (r - color->rgbRed) * (r - color->rgbRed) +
404 (g - color->rgbGreen) * (g - color->rgbGreen) +
405 (b - color->rgbBlue) * (b - color->rgbBlue);
408 if(best == -1 || diff < bestdiff) {
415 /*********************************************************************
416 * X11DRV_DIB_MaskToShift
418 * Helper for X11DRV_DIB_GetDIBits.
419 * Returns the by how many bits to shift a given color so that it is
420 * in the proper position.
422 INT X11DRV_DIB_MaskToShift(DWORD mask)
430 while ((mask&1)==0) {
437 /***********************************************************************
438 * X11DRV_DIB_SetImageBits_1
440 * SetDIBits for a 1-bit deep DIB.
442 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
443 DWORD srcwidth, DWORD dstwidth, int left,
444 int *colors, XImage *bmpImage, DWORD linebytes)
453 srcbits = srcbits + linebytes * (lines - 1);
454 linebytes = -linebytes;
457 if ((extra = (left & 7)) != 0) {
461 srcbits += left >> 3;
462 width = min(srcwidth, dstwidth);
464 /* ==== pal 1 dib -> any bmp format ==== */
465 for (h = lines-1; h >=0; h--) {
467 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
468 for (i = width/8, x = left; i > 0; i--) {
470 XPutPixel( bmpImage, x++, h, colors[ srcval >> 7] );
471 XPutPixel( bmpImage, x++, h, colors[(srcval >> 6) & 1] );
472 XPutPixel( bmpImage, x++, h, colors[(srcval >> 5) & 1] );
473 XPutPixel( bmpImage, x++, h, colors[(srcval >> 4) & 1] );
474 XPutPixel( bmpImage, x++, h, colors[(srcval >> 3) & 1] );
475 XPutPixel( bmpImage, x++, h, colors[(srcval >> 2) & 1] );
476 XPutPixel( bmpImage, x++, h, colors[(srcval >> 1) & 1] );
477 XPutPixel( bmpImage, x++, h, colors[ srcval & 1] );
483 case 7: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
484 case 6: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
485 case 5: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
486 case 4: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
487 case 3: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
488 case 2: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
489 case 1: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]);
492 srcbits += linebytes;
496 /***********************************************************************
497 * X11DRV_DIB_GetImageBits_1
499 * GetDIBits for a 1-bit deep DIB.
501 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
502 DWORD dstwidth, DWORD srcwidth,
503 RGBQUAD *colors, PALETTEENTRY *srccolors,
504 XImage *bmpImage, DWORD linebytes )
507 int h, width = min(dstwidth, srcwidth);
511 dstbits = dstbits + linebytes * (lines - 1);
512 linebytes = -linebytes;
515 switch (bmpImage->depth)
519 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
520 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
523 for (h=lines-1; h>=0; h--) {
527 for (x=0; x<width; x++) {
529 srcval=srccolors[XGetPixel(bmpImage, x, h)];
530 dstval|=(X11DRV_DIB_GetNearestIndex
534 srcval.peBlue) << (7 - (x & 7)));
543 dstbits += linebytes;
551 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
552 /* ==== pal 8 bmp -> pal 1 dib ==== */
554 const BYTE* srcpixel;
557 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
559 for (h=0; h<lines; h++) {
564 for (x=0; x<width; x++) {
566 srcval=srccolors[(int)*srcpixel++];
567 dstval|=(X11DRV_DIB_GetNearestIndex
571 srcval.peBlue) << (7-(x&7)) );
580 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
581 dstbits += linebytes;
592 const WORD* srcpixel;
595 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
597 if (bmpImage->green_mask==0x03e0) {
598 if (bmpImage->red_mask==0x7c00) {
599 /* ==== rgb 555 bmp -> pal 1 dib ==== */
600 for (h=0; h<lines; h++) {
605 for (x=0; x<width; x++) {
608 dstval|=(X11DRV_DIB_GetNearestIndex
610 ((srcval >> 7) & 0xf8) | /* r */
611 ((srcval >> 12) & 0x07),
612 ((srcval >> 2) & 0xf8) | /* g */
613 ((srcval >> 7) & 0x07),
614 ((srcval << 3) & 0xf8) | /* b */
615 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
624 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
625 dstbits += linebytes;
627 } else if (bmpImage->blue_mask==0x7c00) {
628 /* ==== bgr 555 bmp -> pal 1 dib ==== */
629 for (h=0; h<lines; h++) {
634 for (x=0; x<width; x++) {
637 dstval|=(X11DRV_DIB_GetNearestIndex
639 ((srcval << 3) & 0xf8) | /* r */
640 ((srcval >> 2) & 0x07),
641 ((srcval >> 2) & 0xf8) | /* g */
642 ((srcval >> 7) & 0x07),
643 ((srcval >> 7) & 0xf8) | /* b */
644 ((srcval >> 12) & 0x07) ) << (7-(x&7)) );
653 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
654 dstbits += linebytes;
659 } else if (bmpImage->green_mask==0x07e0) {
660 if (bmpImage->red_mask==0xf800) {
661 /* ==== rgb 565 bmp -> pal 1 dib ==== */
662 for (h=0; h<lines; h++) {
667 for (x=0; x<width; x++) {
670 dstval|=(X11DRV_DIB_GetNearestIndex
672 ((srcval >> 8) & 0xf8) | /* r */
673 ((srcval >> 13) & 0x07),
674 ((srcval >> 3) & 0xfc) | /* g */
675 ((srcval >> 9) & 0x03),
676 ((srcval << 3) & 0xf8) | /* b */
677 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
686 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
687 dstbits += linebytes;
689 } else if (bmpImage->blue_mask==0xf800) {
690 /* ==== bgr 565 bmp -> pal 1 dib ==== */
691 for (h=0; h<lines; h++) {
696 for (x=0; x<width; x++) {
699 dstval|=(X11DRV_DIB_GetNearestIndex
701 ((srcval << 3) & 0xf8) | /* r */
702 ((srcval >> 2) & 0x07),
703 ((srcval >> 3) & 0xfc) | /* g */
704 ((srcval >> 9) & 0x03),
705 ((srcval >> 8) & 0xf8) | /* b */
706 ((srcval >> 13) & 0x07) ) << (7-(x&7)) );
715 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
716 dstbits += linebytes;
735 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
736 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
738 if (bmpImage->green_mask!=0x00ff00 ||
739 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
741 } else if (bmpImage->blue_mask==0xff) {
742 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
743 for (h=0; h<lines; h++) {
748 for (x=0; x<width; x++) {
749 dstval|=(X11DRV_DIB_GetNearestIndex
753 srcbyte[0]) << (7-(x&7)) );
754 srcbyte+=bytes_per_pixel;
763 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
764 dstbits += linebytes;
767 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
768 for (h=0; h<lines; h++) {
773 for (x=0; x<width; x++) {
774 dstval|=(X11DRV_DIB_GetNearestIndex
778 srcbyte[2]) << (7-(x&7)) );
779 srcbyte+=bytes_per_pixel;
788 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
789 dstbits += linebytes;
799 unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
801 /* ==== any bmp format -> pal 1 dib ==== */
802 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
803 bmpImage->bits_per_pixel, bmpImage->red_mask,
804 bmpImage->green_mask, bmpImage->blue_mask );
806 for (h=lines-1; h>=0; h--) {
810 for (x=0; x<width; x++) {
811 dstval|=(XGetPixel( bmpImage, x, h) >= white) << (7 - (x&7));
820 dstbits += linebytes;
827 /***********************************************************************
828 * X11DRV_DIB_SetImageBits_4
830 * SetDIBits for a 4-bit deep DIB.
832 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
833 DWORD srcwidth, DWORD dstwidth, int left,
834 int *colors, XImage *bmpImage, DWORD linebytes)
842 srcbits = srcbits + linebytes * (lines - 1);
843 linebytes = -linebytes;
850 srcbits += left >> 1;
851 width = min(srcwidth, dstwidth);
853 /* ==== pal 4 dib -> any bmp format ==== */
854 for (h = lines-1; h >= 0; h--) {
856 for (i = width/2, x = left; i > 0; i--) {
857 BYTE srcval=*srcbyte++;
858 XPutPixel( bmpImage, x++, h, colors[srcval >> 4] );
859 XPutPixel( bmpImage, x++, h, colors[srcval & 0x0f] );
862 XPutPixel( bmpImage, x, h, colors[*srcbyte >> 4] );
863 srcbits += linebytes;
869 /***********************************************************************
870 * X11DRV_DIB_GetImageBits_4
872 * GetDIBits for a 4-bit deep DIB.
874 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
875 DWORD srcwidth, DWORD dstwidth,
876 RGBQUAD *colors, PALETTEENTRY *srccolors,
877 XImage *bmpImage, DWORD linebytes )
880 int h, width = min(srcwidth, dstwidth);
886 dstbits = dstbits + ( linebytes * (lines-1) );
887 linebytes = -linebytes;
892 switch (bmpImage->depth) {
895 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
896 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
899 for (h = lines-1; h >= 0; h--) {
903 for (x = 0; x < width; x++) {
905 srcval=srccolors[XGetPixel(bmpImage, x, h)];
906 dstval|=(X11DRV_DIB_GetNearestIndex
910 srcval.peBlue) << (4-((x&1)<<2)));
919 dstbits += linebytes;
927 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
928 /* ==== pal 8 bmp -> pal 4 dib ==== */
930 const BYTE *srcpixel;
933 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
934 for (h=0; h<lines; h++) {
939 for (x=0; x<width; x++) {
941 srcval = srccolors[(int)*srcpixel++];
942 dstval|=(X11DRV_DIB_GetNearestIndex
946 srcval.peBlue) << (4*(1-(x&1))) );
955 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
956 dstbits += linebytes;
967 const WORD* srcpixel;
970 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
972 if (bmpImage->green_mask==0x03e0) {
973 if (bmpImage->red_mask==0x7c00) {
974 /* ==== rgb 555 bmp -> pal 4 dib ==== */
975 for (h=0; h<lines; h++) {
980 for (x=0; x<width; x++) {
983 dstval|=(X11DRV_DIB_GetNearestIndex
985 ((srcval >> 7) & 0xf8) | /* r */
986 ((srcval >> 12) & 0x07),
987 ((srcval >> 2) & 0xf8) | /* g */
988 ((srcval >> 7) & 0x07),
989 ((srcval << 3) & 0xf8) | /* b */
990 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
999 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1000 dstbits += linebytes;
1002 } else if (bmpImage->blue_mask==0x7c00) {
1003 /* ==== bgr 555 bmp -> pal 4 dib ==== */
1004 for (h=0; h<lines; h++) {
1009 for (x=0; x<width; x++) {
1012 dstval|=(X11DRV_DIB_GetNearestIndex
1014 ((srcval << 3) & 0xf8) | /* r */
1015 ((srcval >> 2) & 0x07),
1016 ((srcval >> 2) & 0xf8) | /* g */
1017 ((srcval >> 7) & 0x07),
1018 ((srcval >> 7) & 0xf8) | /* b */
1019 ((srcval >> 12) & 0x07) ) << ((1-(x&1))<<2) );
1028 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1029 dstbits += linebytes;
1034 } else if (bmpImage->green_mask==0x07e0) {
1035 if (bmpImage->red_mask==0xf800) {
1036 /* ==== rgb 565 bmp -> pal 4 dib ==== */
1037 for (h=0; h<lines; h++) {
1042 for (x=0; x<width; x++) {
1045 dstval|=(X11DRV_DIB_GetNearestIndex
1047 ((srcval >> 8) & 0xf8) | /* r */
1048 ((srcval >> 13) & 0x07),
1049 ((srcval >> 3) & 0xfc) | /* g */
1050 ((srcval >> 9) & 0x03),
1051 ((srcval << 3) & 0xf8) | /* b */
1052 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
1061 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1062 dstbits += linebytes;
1064 } else if (bmpImage->blue_mask==0xf800) {
1065 /* ==== bgr 565 bmp -> pal 4 dib ==== */
1066 for (h=0; h<lines; h++) {
1071 for (x=0; x<width; x++) {
1074 dstval|=(X11DRV_DIB_GetNearestIndex
1076 ((srcval << 3) & 0xf8) | /* r */
1077 ((srcval >> 2) & 0x07),
1078 ((srcval >> 3) & 0xfc) | /* g */
1079 ((srcval >> 9) & 0x03),
1080 ((srcval >> 8) & 0xf8) | /* b */
1081 ((srcval >> 13) & 0x07) ) << ((1-(x&1))<<2) );
1090 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1091 dstbits += linebytes;
1103 if (bmpImage->bits_per_pixel==24) {
1104 const void* srcbits;
1105 const BYTE *srcbyte;
1108 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1110 if (bmpImage->green_mask!=0x00ff00 ||
1111 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1113 } else if (bmpImage->blue_mask==0xff) {
1114 /* ==== rgb 888 bmp -> pal 4 dib ==== */
1115 for (h=0; h<lines; h++) {
1118 for (x=0; x<width/2; x++) {
1119 /* Do 2 pixels at a time */
1120 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1125 X11DRV_DIB_GetNearestIndex
1133 /* And the the odd pixel */
1134 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1140 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1141 dstbits += linebytes;
1144 /* ==== bgr 888 bmp -> pal 4 dib ==== */
1145 for (h=0; h<lines; h++) {
1148 for (x=0; x<width/2; x++) {
1149 /* Do 2 pixels at a time */
1150 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1155 X11DRV_DIB_GetNearestIndex
1163 /* And the the odd pixel */
1164 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1170 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1171 dstbits += linebytes;
1180 const void* srcbits;
1181 const BYTE *srcbyte;
1184 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1186 if (bmpImage->green_mask!=0x00ff00 ||
1187 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1189 } else if (bmpImage->blue_mask==0xff) {
1190 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
1191 for (h=0; h<lines; h++) {
1194 for (x=0; x<width/2; x++) {
1195 /* Do 2 pixels at a time */
1196 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1201 X11DRV_DIB_GetNearestIndex
1209 /* And the the odd pixel */
1210 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1216 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1217 dstbits += linebytes;
1220 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
1221 for (h=0; h<lines; h++) {
1224 for (x=0; x<width/2; x++) {
1225 /* Do 2 pixels at a time */
1226 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1231 X11DRV_DIB_GetNearestIndex
1239 /* And the the odd pixel */
1240 *dstbyte++=(X11DRV_DIB_GetNearestIndex
1246 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1247 dstbits += linebytes;
1258 /* ==== any bmp format -> pal 4 dib ==== */
1259 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
1260 bmpImage->bits_per_pixel, bmpImage->red_mask,
1261 bmpImage->green_mask, bmpImage->blue_mask );
1262 for (h=lines-1; h>=0; h--) {
1264 for (x=0; x<(width & ~1); x+=2) {
1265 *dstbyte++=(X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4) |
1266 X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x+1, h), 0);
1269 *dstbyte=(X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4);
1271 dstbits += linebytes;
1278 /***********************************************************************
1279 * X11DRV_DIB_SetImageBits_RLE4
1281 * SetDIBits for a 4-bit deep compressed DIB.
1283 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
1284 DWORD srcwidth, DWORD dstwidth,
1285 int left, int *colors,
1288 unsigned int x = 0, width = min(srcwidth, dstwidth);
1289 int y = lines - 1, c, length;
1290 const BYTE *begin = bits;
1295 if (length) { /* encoded */
1298 if (x >= width) break;
1299 XPutPixel(bmpImage, x++, y, colors[c >> 4]);
1300 if (!length--) break;
1301 if (x >= width) break;
1302 XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
1321 default: /* absolute */
1324 if (x < width) XPutPixel(bmpImage, x++, y, colors[c >> 4]);
1325 if (!length--) break;
1326 if (x < width) XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
1328 if ((bits - begin) & 1)
1337 /***********************************************************************
1338 * X11DRV_DIB_SetImageBits_8
1340 * SetDIBits for an 8-bit deep DIB.
1342 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
1343 DWORD srcwidth, DWORD dstwidth, int left,
1344 const int *colors, XImage *bmpImage,
1348 int h, width = min(srcwidth, dstwidth);
1349 const BYTE* srcbyte;
1355 srcbits = srcbits + linebytes * (lines-1);
1356 linebytes = -linebytes;
1361 switch (bmpImage->depth) {
1364 #if defined(__i386__) && defined(__GNUC__)
1365 /* Some X servers might have 32 bit/ 16bit deep pixel */
1366 if (lines && width && (bmpImage->bits_per_pixel == 16) &&
1367 (ImageByteOrder(gdi_display)==LSBFirst) )
1369 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
1370 /* FIXME: Does this really handle all these cases correctly? */
1371 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
1372 for (h = lines ; h--; ) {
1373 int _cl1,_cl2; /* temp outputs for asm below */
1374 /* Borrowed from DirectDraw */
1375 __asm__ __volatile__(
1380 " movw (%%edx,%%eax,4),%%ax\n"
1382 " xor %%eax,%%eax\n"
1384 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
1389 :"eax", "cc", "memory"
1391 srcbyte = (srcbits += linebytes);
1392 dstbits -= bmpImage->bytes_per_line;
1400 #if defined(__i386__) && defined(__GNUC__)
1401 if (lines && width && (bmpImage->bits_per_pixel == 32) &&
1402 (ImageByteOrder(gdi_display)==LSBFirst) )
1404 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
1405 /* FIXME: Does this really handle both cases correctly? */
1406 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
1407 for (h = lines ; h--; ) {
1408 int _cl1,_cl2; /* temp outputs for asm below */
1409 /* Borrowed from DirectDraw */
1410 __asm__ __volatile__(
1415 " movl (%%edx,%%eax,4),%%eax\n"
1417 " xor %%eax,%%eax\n"
1419 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
1424 :"eax", "cc", "memory"
1426 srcbyte = (srcbits += linebytes);
1427 dstbits -= bmpImage->bytes_per_line;
1434 break; /* use slow generic case below */
1437 /* ==== pal 8 dib -> any bmp format ==== */
1438 for (h=lines-1; h>=0; h--) {
1439 for (x=left; x<width+left; x++) {
1440 XPutPixel(bmpImage, x, h, colors[*srcbyte++]);
1442 srcbyte = (srcbits += linebytes);
1446 /***********************************************************************
1447 * X11DRV_DIB_GetImageBits_8
1449 * GetDIBits for an 8-bit deep DIB.
1451 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
1452 DWORD srcwidth, DWORD dstwidth,
1453 RGBQUAD *colors, PALETTEENTRY *srccolors,
1454 XImage *bmpImage, DWORD linebytes )
1457 int h, width = min(srcwidth, dstwidth);
1463 dstbits = dstbits + ( linebytes * (lines-1) );
1464 linebytes = -linebytes;
1469 * This condition is true when GetImageBits has been called by
1470 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
1471 * 256 colormaps, so we'll just use for for GetDIBits calls.
1472 * (In somes cases, in a updateDIBSection, the returned colors are bad too)
1474 if (!srccolors) goto updatesection;
1476 switch (bmpImage->depth) {
1479 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1481 /* ==== pal 1 bmp -> pal 8 dib ==== */
1482 /* ==== pal 4 bmp -> pal 8 dib ==== */
1483 for (h=lines-1; h>=0; h--) {
1485 for (x=0; x<width; x++) {
1486 PALETTEENTRY srcval;
1487 srcval=srccolors[XGetPixel(bmpImage, x, h)];
1488 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
1493 dstbits += linebytes;
1501 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1502 /* ==== pal 8 bmp -> pal 8 dib ==== */
1503 const void* srcbits;
1504 const BYTE* srcpixel;
1506 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1507 for (h=0; h<lines; h++) {
1510 for (x = 0; x < width; x++) {
1511 PALETTEENTRY srcval;
1512 srcval=srccolors[(int)*srcpixel++];
1513 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
1518 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1519 dstbits += linebytes;
1529 const void* srcbits;
1530 const WORD* srcpixel;
1533 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1535 if (bmpImage->green_mask==0x03e0) {
1536 if (bmpImage->red_mask==0x7c00) {
1537 /* ==== rgb 555 bmp -> pal 8 dib ==== */
1538 for (h=0; h<lines; h++) {
1541 for (x=0; x<width; x++) {
1544 *dstbyte++=X11DRV_DIB_GetNearestIndex
1546 ((srcval >> 7) & 0xf8) | /* r */
1547 ((srcval >> 12) & 0x07),
1548 ((srcval >> 2) & 0xf8) | /* g */
1549 ((srcval >> 7) & 0x07),
1550 ((srcval << 3) & 0xf8) | /* b */
1551 ((srcval >> 2) & 0x07) );
1553 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1554 dstbits += linebytes;
1556 } else if (bmpImage->blue_mask==0x7c00) {
1557 /* ==== bgr 555 bmp -> pal 8 dib ==== */
1558 for (h=0; h<lines; h++) {
1561 for (x=0; x<width; x++) {
1564 *dstbyte++=X11DRV_DIB_GetNearestIndex
1566 ((srcval << 3) & 0xf8) | /* r */
1567 ((srcval >> 2) & 0x07),
1568 ((srcval >> 2) & 0xf8) | /* g */
1569 ((srcval >> 7) & 0x07),
1570 ((srcval >> 7) & 0xf8) | /* b */
1571 ((srcval >> 12) & 0x07) );
1573 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1574 dstbits += linebytes;
1579 } else if (bmpImage->green_mask==0x07e0) {
1580 if (bmpImage->red_mask==0xf800) {
1581 /* ==== rgb 565 bmp -> pal 8 dib ==== */
1582 for (h=0; h<lines; h++) {
1585 for (x=0; x<width; x++) {
1588 *dstbyte++=X11DRV_DIB_GetNearestIndex
1590 ((srcval >> 8) & 0xf8) | /* r */
1591 ((srcval >> 13) & 0x07),
1592 ((srcval >> 3) & 0xfc) | /* g */
1593 ((srcval >> 9) & 0x03),
1594 ((srcval << 3) & 0xf8) | /* b */
1595 ((srcval >> 2) & 0x07) );
1597 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1598 dstbits += linebytes;
1600 } else if (bmpImage->blue_mask==0xf800) {
1601 /* ==== bgr 565 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 << 3) & 0xf8) | /* r */
1611 ((srcval >> 2) & 0x07),
1612 ((srcval >> 3) & 0xfc) | /* g */
1613 ((srcval >> 9) & 0x03),
1614 ((srcval >> 8) & 0xf8) | /* b */
1615 ((srcval >> 13) & 0x07) );
1617 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1618 dstbits += linebytes;
1632 const void* srcbits;
1633 const BYTE *srcbyte;
1635 int bytes_per_pixel;
1637 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1638 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
1640 if (bmpImage->green_mask!=0x00ff00 ||
1641 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1643 } else if (bmpImage->blue_mask==0xff) {
1644 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
1645 for (h=0; h<lines; h++) {
1648 for (x=0; x<width; x++) {
1649 *dstbyte++=X11DRV_DIB_GetNearestIndex
1654 srcbyte+=bytes_per_pixel;
1656 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1657 dstbits += linebytes;
1660 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
1661 for (h=0; h<lines; h++) {
1664 for (x=0; x<width; x++) {
1665 *dstbyte++=X11DRV_DIB_GetNearestIndex
1670 srcbyte+=bytes_per_pixel;
1672 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1673 dstbits += linebytes;
1681 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
1682 bmpImage->depth, bmpImage->red_mask,
1683 bmpImage->green_mask, bmpImage->blue_mask );
1685 /* ==== any bmp format -> pal 8 dib ==== */
1686 for (h=lines-1; h>=0; h--) {
1688 for (x=0; x<width; x++) {
1689 *dstbyte=X11DRV_DIB_MapColor
1691 XGetPixel(bmpImage, x, h), *dstbyte);
1694 dstbits += linebytes;
1700 /***********************************************************************
1701 * X11DRV_DIB_SetImageBits_RLE8
1703 * SetDIBits for an 8-bit deep compressed DIB.
1705 * This function rewritten 941113 by James Youngman. WINE blew out when I
1706 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1708 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1709 * 'End of bitmap' escape code. This code is very much laxer in what it
1710 * allows to end the expansion. Possibly too lax. See the note by
1711 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1712 * bitmap should end with RleEnd, but on the other hand, software exists
1713 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1716 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1717 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1720 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
1721 DWORD srcwidth, DWORD dstwidth,
1722 int left, int *colors,
1725 unsigned int x; /* X-position on each line. Increases. */
1726 int y; /* Line #. Starts at lines-1, decreases */
1727 const BYTE *pIn = bits; /* Pointer to current position in bits */
1728 BYTE length; /* The length pf a run */
1729 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
1732 * Note that the bitmap data is stored by Windows starting at the
1733 * bottom line of the bitmap and going upwards. Within each line,
1734 * the data is stored left-to-right. That's the reason why line
1735 * goes from lines-1 to 0. [JAY]
1745 * If the length byte is not zero (which is the escape value),
1746 * We have a run of length pixels all the same colour. The colour
1747 * index is stored next.
1749 * If the length byte is zero, we need to read the next byte to
1750 * know what to do. [JAY]
1755 * [Run-Length] Encoded mode
1757 int color = colors[*pIn++];
1758 while (length-- && x < dstwidth) XPutPixel(bmpImage, x++, y, color);
1763 * Escape codes (may be an absolute sequence though)
1765 escape_code = (*pIn++);
1774 /* Not all RLE8 bitmaps end with this code. For
1775 * example, Paint Shop Pro produces some that don't.
1776 * That's (I think) what caused the previous
1777 * implementation to fail. [JAY]
1786 default: /* switch to absolute mode */
1787 length = escape_code;
1790 int color = colors[*pIn++];
1796 XPutPixel(bmpImage, x++, y, color);
1799 * If you think for a moment you'll realise that the
1800 * only time we could ever possibly read an odd
1801 * number of bytes is when there is a 0x00 (escape),
1802 * a value >0x02 (absolute mode) and then an odd-
1803 * length run. Therefore this is the only place we
1804 * need to worry about it. Everywhere else the
1805 * bytes are always read in pairs. [JAY]
1807 if (escape_code & 1) pIn++; /* Throw away the pad byte. */
1809 } /* switch (escape_code) : Escape sequence */
1815 /***********************************************************************
1816 * X11DRV_DIB_SetImageBits_16
1818 * SetDIBits for a 16-bit deep DIB.
1820 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
1821 DWORD srcwidth, DWORD dstwidth, int left,
1822 X11DRV_PDEVICE *physDev, DWORD rSrc, DWORD gSrc, DWORD bSrc,
1823 XImage *bmpImage, DWORD linebytes )
1826 int h, width = min(srcwidth, dstwidth);
1827 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_byteswap;
1832 srcbits = srcbits + ( linebytes * (lines-1));
1833 linebytes = -linebytes;
1836 switch (bmpImage->depth)
1843 srcbits=srcbits+left*2;
1844 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
1846 if (bmpImage->green_mask==0x03e0) {
1847 if (gSrc==bmpImage->green_mask) {
1848 if (rSrc==bmpImage->red_mask) {
1849 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
1850 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
1851 convs->Convert_5x5_asis
1854 dstbits,-bmpImage->bytes_per_line);
1855 } else if (rSrc==bmpImage->blue_mask) {
1856 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
1857 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
1858 convs->Convert_555_reverse
1861 dstbits,-bmpImage->bytes_per_line);
1864 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
1865 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
1866 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
1867 convs->Convert_565_to_555_asis
1870 dstbits,-bmpImage->bytes_per_line);
1872 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
1873 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
1874 convs->Convert_565_to_555_reverse
1877 dstbits,-bmpImage->bytes_per_line);
1880 } else if (bmpImage->green_mask==0x07e0) {
1881 if (gSrc==bmpImage->green_mask) {
1882 if (rSrc==bmpImage->red_mask) {
1883 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
1884 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
1885 convs->Convert_5x5_asis
1888 dstbits,-bmpImage->bytes_per_line);
1890 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
1891 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
1892 convs->Convert_565_reverse
1895 dstbits,-bmpImage->bytes_per_line);
1898 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
1899 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
1900 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
1901 convs->Convert_555_to_565_asis
1904 dstbits,-bmpImage->bytes_per_line);
1906 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
1907 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
1908 convs->Convert_555_to_565_reverse
1911 dstbits,-bmpImage->bytes_per_line);
1921 if (bmpImage->bits_per_pixel==24) {
1924 srcbits=srcbits+left*2;
1925 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
1927 if (bmpImage->green_mask!=0x00ff00 ||
1928 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1930 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
1931 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
1933 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
1934 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
1935 convs->Convert_555_to_888_asis
1938 dstbits,-bmpImage->bytes_per_line);
1940 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
1941 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
1942 convs->Convert_565_to_888_asis
1945 dstbits,-bmpImage->bytes_per_line);
1949 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
1950 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
1951 convs->Convert_555_to_888_reverse
1954 dstbits,-bmpImage->bytes_per_line);
1956 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
1957 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
1958 convs->Convert_565_to_888_reverse
1961 dstbits,-bmpImage->bytes_per_line);
1972 srcbits=srcbits+left*2;
1973 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
1975 if (bmpImage->green_mask!=0x00ff00 ||
1976 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1978 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
1979 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
1981 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
1982 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
1983 convs->Convert_555_to_0888_asis
1986 dstbits,-bmpImage->bytes_per_line);
1988 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
1989 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
1990 convs->Convert_565_to_0888_asis
1993 dstbits,-bmpImage->bytes_per_line);
1997 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
1998 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
1999 convs->Convert_555_to_0888_reverse
2002 dstbits,-bmpImage->bytes_per_line);
2004 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
2005 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
2006 convs->Convert_565_to_0888_reverse
2009 dstbits,-bmpImage->bytes_per_line);
2017 WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2018 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
2019 bmpImage->green_mask, bmpImage->blue_mask );
2025 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
2026 const WORD* srcpixel;
2027 int rShift1,gShift1,bShift1;
2028 int rShift2,gShift2,bShift2;
2031 /* Set color scaling values */
2032 rShift1=16+X11DRV_DIB_MaskToShift(rSrc)-3;
2033 gShift1=16+X11DRV_DIB_MaskToShift(gSrc)-3;
2034 bShift1=16+X11DRV_DIB_MaskToShift(bSrc)-3;
2039 /* Green has 5 bits, like the others */
2043 /* Green has 6 bits, not 5. Compensate. */
2052 /* We could split it into four separate cases to optimize
2053 * but it is probably not worth it.
2055 for (h=lines-1; h>=0; h--) {
2056 srcpixel=(const WORD*)srcbits;
2057 for (x=left; x<width+left; x++) {
2059 BYTE red,green,blue;
2060 srcval=*srcpixel++ << 16;
2061 red= ((srcval >> rShift1) & 0xf8) |
2062 ((srcval >> rShift2) & 0x07);
2063 green=((srcval >> gShift1) & gMask1) |
2064 ((srcval >> gShift2) & gMask2);
2065 blue= ((srcval >> bShift1) & 0xf8) |
2066 ((srcval >> bShift2) & 0x07);
2067 XPutPixel(bmpImage, x, h,
2068 X11DRV_PALETTE_ToPhysical
2069 (physDev, RGB(red,green,blue)));
2071 srcbits += linebytes;
2079 /***********************************************************************
2080 * X11DRV_DIB_GetImageBits_16
2082 * GetDIBits for an 16-bit deep DIB.
2084 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
2085 DWORD dstwidth, DWORD srcwidth,
2086 PALETTEENTRY *srccolors,
2087 DWORD rDst, DWORD gDst, DWORD bDst,
2088 XImage *bmpImage, DWORD dibpitch )
2091 int h, width = min(srcwidth, dstwidth);
2092 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_byteswap;
2094 DWORD linebytes = dibpitch;
2099 dstbits = dstbits + ( linebytes * (lines-1));
2100 linebytes = -linebytes;
2103 switch (bmpImage->depth)
2108 const char* srcbits;
2110 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2112 if (bmpImage->green_mask==0x03e0) {
2113 if (gDst==bmpImage->green_mask) {
2114 if (rDst==bmpImage->red_mask) {
2115 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
2116 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
2117 convs->Convert_5x5_asis
2119 srcbits,-bmpImage->bytes_per_line,
2122 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
2123 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
2124 convs->Convert_555_reverse
2126 srcbits,-bmpImage->bytes_per_line,
2130 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
2131 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
2132 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
2133 convs->Convert_555_to_565_asis
2135 srcbits,-bmpImage->bytes_per_line,
2138 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
2139 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
2140 convs->Convert_555_to_565_reverse
2142 srcbits,-bmpImage->bytes_per_line,
2146 } else if (bmpImage->green_mask==0x07e0) {
2147 if (gDst==bmpImage->green_mask) {
2148 if (rDst == bmpImage->red_mask) {
2149 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
2150 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
2151 convs->Convert_5x5_asis
2153 srcbits,-bmpImage->bytes_per_line,
2156 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
2157 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
2158 convs->Convert_565_reverse
2160 srcbits,-bmpImage->bytes_per_line,
2164 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
2165 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
2166 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
2167 convs->Convert_565_to_555_asis
2169 srcbits,-bmpImage->bytes_per_line,
2172 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
2173 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
2174 convs->Convert_565_to_555_reverse
2176 srcbits,-bmpImage->bytes_per_line,
2187 if (bmpImage->bits_per_pixel == 24) {
2188 const char* srcbits;
2190 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2192 if (bmpImage->green_mask!=0x00ff00 ||
2193 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2195 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
2196 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
2198 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
2199 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
2200 convs->Convert_888_to_555_asis
2202 srcbits,-bmpImage->bytes_per_line,
2205 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2206 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
2207 convs->Convert_888_to_565_asis
2209 srcbits,-bmpImage->bytes_per_line,
2214 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
2215 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
2216 convs->Convert_888_to_555_reverse
2218 srcbits,-bmpImage->bytes_per_line,
2221 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
2222 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
2223 convs->Convert_888_to_565_reverse
2225 srcbits,-bmpImage->bytes_per_line,
2235 const char* srcbits;
2237 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2239 if (bmpImage->green_mask!=0x00ff00 ||
2240 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2242 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
2243 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
2245 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
2246 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
2247 convs->Convert_0888_to_555_asis
2249 srcbits,-bmpImage->bytes_per_line,
2252 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
2253 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
2254 convs->Convert_0888_to_565_asis
2256 srcbits,-bmpImage->bytes_per_line,
2261 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
2262 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
2263 convs->Convert_0888_to_555_reverse
2265 srcbits,-bmpImage->bytes_per_line,
2268 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
2269 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
2270 convs->Convert_0888_to_565_reverse
2272 srcbits,-bmpImage->bytes_per_line,
2281 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2282 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
2283 int rShift,gShift,bShift;
2286 /* Shift everything 16 bits left so that all shifts are >0,
2287 * even for BGR DIBs. Then a single >> 16 will bring everything
2290 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
2291 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
2292 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
2294 /* 6 bits for the green */
2300 for (h = lines - 1; h >= 0; h--) {
2301 dstpixel=(LPWORD)dstbits;
2302 for (x = 0; x < width; x++) {
2303 PALETTEENTRY srcval;
2305 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2306 dstval=((srcval.peRed << rShift) & rDst) |
2307 ((srcval.peGreen << gShift) & gDst) |
2308 ((srcval.peBlue << bShift) & bDst);
2309 *dstpixel++=dstval >> 16;
2311 dstbits += linebytes;
2319 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2320 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
2321 int rShift,gShift,bShift;
2322 const BYTE* srcbits;
2323 const BYTE* srcpixel;
2326 /* Shift everything 16 bits left so that all shifts are >0,
2327 * even for BGR DIBs. Then a single >> 16 will bring everything
2330 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
2331 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
2332 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
2334 /* 6 bits for the green */
2340 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2341 for (h=0; h<lines; h++) {
2343 dstpixel=(LPWORD)dstbits;
2344 for (x = 0; x < width; x++) {
2345 PALETTEENTRY srcval;
2347 srcval=srccolors[(int)*srcpixel++];
2348 dstval=((srcval.peRed << rShift) & rDst) |
2349 ((srcval.peGreen << gShift) & gDst) |
2350 ((srcval.peBlue << bShift) & bDst);
2351 *dstpixel++=dstval >> 16;
2353 srcbits -= bmpImage->bytes_per_line;
2354 dstbits += linebytes;
2364 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
2365 int rShift,gShift,bShift;
2368 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
2369 bmpImage->depth, bmpImage->red_mask,
2370 bmpImage->green_mask, bmpImage->blue_mask,
2373 /* Shift everything 16 bits left so that all shifts are >0,
2374 * even for BGR DIBs. Then a single >> 16 will bring everything
2377 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
2378 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
2379 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
2381 /* 6 bits for the green */
2387 for (h = lines - 1; h >= 0; h--) {
2388 dstpixel=(LPWORD)dstbits;
2389 for (x = 0; x < width; x++) {
2392 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
2393 dstval=((GetRValue(srcval) << rShift) & rDst) |
2394 ((GetGValue(srcval) << gShift) & gDst) |
2395 ((GetBValue(srcval) << bShift) & bDst);
2396 *dstpixel++=dstval >> 16;
2398 dstbits += linebytes;
2406 /***********************************************************************
2407 * X11DRV_DIB_SetImageBits_24
2409 * SetDIBits for a 24-bit deep DIB.
2411 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
2412 DWORD srcwidth, DWORD dstwidth, int left,
2413 X11DRV_PDEVICE *physDev,
2414 DWORD rSrc, DWORD gSrc, DWORD bSrc,
2415 XImage *bmpImage, DWORD linebytes )
2418 int h, width = min(srcwidth, dstwidth);
2419 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_byteswap;
2424 srcbits = srcbits + linebytes * (lines - 1);
2425 linebytes = -linebytes;
2428 switch (bmpImage->depth)
2431 if (bmpImage->bits_per_pixel==24) {
2434 srcbits=srcbits+left*3;
2435 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
2437 if (bmpImage->green_mask!=0x00ff00 ||
2438 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2440 } else if (rSrc==bmpImage->red_mask) {
2441 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
2442 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
2443 convs->Convert_888_asis
2446 dstbits,-bmpImage->bytes_per_line);
2448 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
2449 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
2450 convs->Convert_888_reverse
2453 dstbits,-bmpImage->bytes_per_line);
2463 srcbits=srcbits+left*3;
2464 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2466 if (bmpImage->green_mask!=0x00ff00 ||
2467 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2469 } else if (rSrc==bmpImage->red_mask) {
2470 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
2471 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
2472 convs->Convert_888_to_0888_asis
2475 dstbits,-bmpImage->bytes_per_line);
2477 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
2478 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
2479 convs->Convert_888_to_0888_reverse
2482 dstbits,-bmpImage->bytes_per_line);
2492 srcbits=srcbits+left*3;
2493 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2495 if (bmpImage->green_mask==0x03e0) {
2496 if ((rSrc==0xff0000 && bmpImage->red_mask==0x7f00) ||
2497 (bSrc==0xff0000 && bmpImage->blue_mask==0x7f00)) {
2498 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
2499 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
2500 convs->Convert_888_to_555_asis
2503 dstbits,-bmpImage->bytes_per_line);
2504 } else if ((rSrc==0xff && bmpImage->red_mask==0x7f00) ||
2505 (bSrc==0xff && bmpImage->blue_mask==0x7f00)) {
2506 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
2507 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
2508 convs->Convert_888_to_555_reverse
2511 dstbits,-bmpImage->bytes_per_line);
2515 } else if (bmpImage->green_mask==0x07e0) {
2516 if ((rSrc==0xff0000 && bmpImage->red_mask==0xf800) ||
2517 (bSrc==0xff0000 && bmpImage->blue_mask==0xf800)) {
2518 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
2519 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
2520 convs->Convert_888_to_565_asis
2523 dstbits,-bmpImage->bytes_per_line);
2524 } else if ((rSrc==0xff && bmpImage->red_mask==0xf800) ||
2525 (bSrc==0xff && bmpImage->blue_mask==0xf800)) {
2526 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
2527 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
2528 convs->Convert_888_to_565_reverse
2531 dstbits,-bmpImage->bytes_per_line);
2543 WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
2544 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
2545 bmpImage->green_mask, bmpImage->blue_mask );
2551 /* ==== rgb 888 dib -> any bmp bormat ==== */
2552 const BYTE* srcbyte;
2554 /* Windows only supports one 24bpp DIB format: RGB888 */
2556 for (h = lines - 1; h >= 0; h--) {
2557 srcbyte=(const BYTE*)srcbits;
2558 for (x = left; x < width+left; x++) {
2559 XPutPixel(bmpImage, x, h,
2560 X11DRV_PALETTE_ToPhysical
2561 (physDev, RGB(srcbyte[2], srcbyte[1], srcbyte[0])));
2564 srcbits += linebytes;
2572 /***********************************************************************
2573 * X11DRV_DIB_GetImageBits_24
2575 * GetDIBits for an 24-bit deep DIB.
2577 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
2578 DWORD dstwidth, DWORD srcwidth,
2579 PALETTEENTRY *srccolors,
2580 DWORD rDst, DWORD gDst, DWORD bDst,
2581 XImage *bmpImage, DWORD linebytes )
2584 int h, width = min(srcwidth, dstwidth);
2585 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_byteswap;
2590 dstbits = dstbits + ( linebytes * (lines-1) );
2591 linebytes = -linebytes;
2594 switch (bmpImage->depth)
2597 if (bmpImage->bits_per_pixel==24) {
2598 const char* srcbits;
2600 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2602 if (bmpImage->green_mask!=0x00ff00 ||
2603 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2605 } else if (rDst==bmpImage->red_mask) {
2606 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
2607 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
2608 convs->Convert_888_asis
2610 srcbits,-bmpImage->bytes_per_line,
2613 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
2614 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
2615 convs->Convert_888_reverse
2617 srcbits,-bmpImage->bytes_per_line,
2626 const char* srcbits;
2628 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2630 if (bmpImage->green_mask!=0x00ff00 ||
2631 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2633 } else if (rDst==bmpImage->red_mask) {
2634 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
2635 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
2636 convs->Convert_0888_to_888_asis
2638 srcbits,-bmpImage->bytes_per_line,
2641 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
2642 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
2643 convs->Convert_0888_to_888_reverse
2645 srcbits,-bmpImage->bytes_per_line,
2654 const char* srcbits;
2656 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2658 if (bmpImage->green_mask==0x03e0) {
2659 if ((rDst==0xff0000 && bmpImage->red_mask==0x7f00) ||
2660 (bDst==0xff0000 && bmpImage->blue_mask==0x7f00)) {
2661 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
2662 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
2663 convs->Convert_555_to_888_asis
2665 srcbits,-bmpImage->bytes_per_line,
2667 } else if ((rDst==0xff && bmpImage->red_mask==0x7f00) ||
2668 (bDst==0xff && bmpImage->blue_mask==0x7f00)) {
2669 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
2670 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
2671 convs->Convert_555_to_888_reverse
2673 srcbits,-bmpImage->bytes_per_line,
2678 } else if (bmpImage->green_mask==0x07e0) {
2679 if ((rDst==0xff0000 && bmpImage->red_mask==0xf800) ||
2680 (bDst==0xff0000 && bmpImage->blue_mask==0xf800)) {
2681 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
2682 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
2683 convs->Convert_565_to_888_asis
2685 srcbits,-bmpImage->bytes_per_line,
2687 } else if ((rDst==0xff && bmpImage->red_mask==0xf800) ||
2688 (bDst==0xff && bmpImage->blue_mask==0xf800)) {
2689 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
2690 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
2691 convs->Convert_565_to_888_reverse
2693 srcbits,-bmpImage->bytes_per_line,
2706 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2707 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
2710 /* Windows only supports one 24bpp DIB format: rgb 888 */
2711 for (h = lines - 1; h >= 0; h--) {
2713 for (x = 0; x < width; x++) {
2714 PALETTEENTRY srcval;
2715 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2716 dstbyte[0]=srcval.peBlue;
2717 dstbyte[1]=srcval.peGreen;
2718 dstbyte[2]=srcval.peRed;
2721 dstbits += linebytes;
2729 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors) {
2730 /* ==== pal 8 bmp -> rgb 888 dib ==== */
2731 const void* srcbits;
2732 const BYTE* srcpixel;
2735 /* Windows only supports one 24bpp DIB format: rgb 888 */
2736 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2737 for (h = lines - 1; h >= 0; h--) {
2740 for (x = 0; x < width; x++ ) {
2741 PALETTEENTRY srcval;
2742 srcval=srccolors[(int)*srcpixel++];
2743 dstbyte[0]=srcval.peBlue;
2744 dstbyte[1]=srcval.peGreen;
2745 dstbyte[2]=srcval.peRed;
2748 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2749 dstbits += linebytes;
2759 /* ==== any bmp format -> 888 dib ==== */
2762 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
2763 bmpImage->depth, bmpImage->red_mask,
2764 bmpImage->green_mask, bmpImage->blue_mask,
2767 /* Windows only supports one 24bpp DIB format: rgb 888 */
2768 for (h = lines - 1; h >= 0; h--) {
2770 for (x = 0; x < width; x++) {
2771 COLORREF srcval=X11DRV_PALETTE_ToLogical
2772 (XGetPixel( bmpImage, x, h ));
2773 dstbyte[0]=GetBValue(srcval);
2774 dstbyte[1]=GetGValue(srcval);
2775 dstbyte[2]=GetRValue(srcval);
2778 dstbits += linebytes;
2786 /***********************************************************************
2787 * X11DRV_DIB_SetImageBits_32
2789 * SetDIBits for a 32-bit deep DIB.
2791 static void X11DRV_DIB_SetImageBits_32(int lines, const BYTE *srcbits,
2792 DWORD srcwidth, DWORD dstwidth, int left,
2793 X11DRV_PDEVICE *physDev,
2794 DWORD rSrc, DWORD gSrc, DWORD bSrc,
2799 int h, width = min(srcwidth, dstwidth);
2800 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_dst_byteswap;
2805 srcbits = srcbits + ( linebytes * (lines-1) );
2806 linebytes = -linebytes;
2809 ptr = (DWORD *) srcbits + left;
2811 switch (bmpImage->depth)
2814 if (bmpImage->bits_per_pixel==24) {
2817 srcbits=srcbits+left*4;
2818 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
2820 if (rSrc==bmpImage->red_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->blue_mask) {
2821 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
2822 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
2823 convs->Convert_0888_to_888_asis
2826 dstbits,-bmpImage->bytes_per_line);
2827 } else if (bmpImage->green_mask!=0x00ff00 ||
2828 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2830 /* the tests below assume sane bmpImage masks */
2831 } else if (rSrc==bmpImage->blue_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->red_mask) {
2832 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
2833 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
2834 convs->Convert_0888_to_888_reverse
2837 dstbits,-bmpImage->bytes_per_line);
2838 } else if (bmpImage->blue_mask==0xff) {
2839 /* ==== any 0888 dib -> rgb 888 bmp ==== */
2840 convs->Convert_any0888_to_rgb888
2844 dstbits,-bmpImage->bytes_per_line);
2846 /* ==== any 0888 dib -> bgr 888 bmp ==== */
2847 convs->Convert_any0888_to_bgr888
2851 dstbits,-bmpImage->bytes_per_line);
2861 srcbits=srcbits+left*4;
2862 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2864 if (gSrc==bmpImage->green_mask) {
2865 if (rSrc==bmpImage->red_mask && bSrc==bmpImage->blue_mask) {
2866 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
2867 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
2868 convs->Convert_0888_asis
2871 dstbits,-bmpImage->bytes_per_line);
2872 } else if (bmpImage->green_mask!=0x00ff00 ||
2873 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2875 /* the tests below assume sane bmpImage masks */
2876 } else if (rSrc==bmpImage->blue_mask && bSrc==bmpImage->red_mask) {
2877 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
2878 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
2879 convs->Convert_0888_reverse
2882 dstbits,-bmpImage->bytes_per_line);
2884 /* ==== any 0888 dib -> any 0888 bmp ==== */
2885 convs->Convert_0888_any
2889 dstbits,-bmpImage->bytes_per_line,
2890 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
2892 } else if (bmpImage->green_mask!=0x00ff00 ||
2893 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2895 /* the tests below assume sane bmpImage masks */
2897 /* ==== any 0888 dib -> any 0888 bmp ==== */
2898 convs->Convert_0888_any
2902 dstbits,-bmpImage->bytes_per_line,
2903 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
2913 srcbits=srcbits+left*4;
2914 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2916 if (rSrc==0xff0000 && gSrc==0x00ff00 && bSrc==0x0000ff) {
2917 if (bmpImage->green_mask==0x03e0) {
2918 if (bmpImage->red_mask==0x7f00) {
2919 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
2920 convs->Convert_0888_to_555_asis
2923 dstbits,-bmpImage->bytes_per_line);
2924 } else if (bmpImage->blue_mask==0x7f00) {
2925 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
2926 convs->Convert_0888_to_555_reverse
2929 dstbits,-bmpImage->bytes_per_line);
2933 } else if (bmpImage->green_mask==0x07e0) {
2934 if (bmpImage->red_mask==0xf800) {
2935 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
2936 convs->Convert_0888_to_565_asis
2939 dstbits,-bmpImage->bytes_per_line);
2940 } else if (bmpImage->blue_mask==0xf800) {
2941 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
2942 convs->Convert_0888_to_565_reverse
2945 dstbits,-bmpImage->bytes_per_line);
2952 } else if (rSrc==0x0000ff && gSrc==0x00ff00 && bSrc==0xff0000) {
2953 if (bmpImage->green_mask==0x03e0) {
2954 if (bmpImage->blue_mask==0x7f00) {
2955 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
2956 convs->Convert_0888_to_555_asis
2959 dstbits,-bmpImage->bytes_per_line);
2960 } else if (bmpImage->red_mask==0x7f00) {
2961 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
2962 convs->Convert_0888_to_555_reverse
2965 dstbits,-bmpImage->bytes_per_line);
2969 } else if (bmpImage->green_mask==0x07e0) {
2970 if (bmpImage->blue_mask==0xf800) {
2971 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
2972 convs->Convert_0888_to_565_asis
2975 dstbits,-bmpImage->bytes_per_line);
2976 } else if (bmpImage->red_mask==0xf800) {
2977 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
2978 convs->Convert_0888_to_565_reverse
2981 dstbits,-bmpImage->bytes_per_line);
2989 if (bmpImage->green_mask==0x03e0 &&
2990 (bmpImage->red_mask==0x7f00 ||
2991 bmpImage->blue_mask==0x7f00)) {
2992 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
2993 convs->Convert_any0888_to_5x5
2997 dstbits,-bmpImage->bytes_per_line,
2998 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
2999 } else if (bmpImage->green_mask==0x07e0 &&
3000 (bmpImage->red_mask==0xf800 ||
3001 bmpImage->blue_mask==0xf800)) {
3002 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
3003 convs->Convert_any0888_to_5x5
3007 dstbits,-bmpImage->bytes_per_line,
3008 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
3018 WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3019 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
3020 bmpImage->green_mask, bmpImage->blue_mask );
3026 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
3027 const DWORD* srcpixel;
3028 int rShift,gShift,bShift;
3030 rShift=X11DRV_DIB_MaskToShift(rSrc);
3031 gShift=X11DRV_DIB_MaskToShift(gSrc);
3032 bShift=X11DRV_DIB_MaskToShift(bSrc);
3034 for (h = lines - 1; h >= 0; h--) {
3035 srcpixel=(const DWORD*)srcbits;
3036 for (x = left; x < width+left; x++) {
3038 BYTE red,green,blue;
3039 srcvalue=*srcpixel++;
3040 red= (srcvalue >> rShift) & 0xff;
3041 green=(srcvalue >> gShift) & 0xff;
3042 blue= (srcvalue >> bShift) & 0xff;
3043 XPutPixel(bmpImage, x, h, X11DRV_PALETTE_ToPhysical
3044 (physDev, RGB(red,green,blue)));
3046 srcbits += linebytes;
3054 /***********************************************************************
3055 * X11DRV_DIB_GetImageBits_32
3057 * GetDIBits for an 32-bit deep DIB.
3059 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
3060 DWORD dstwidth, DWORD srcwidth,
3061 PALETTEENTRY *srccolors,
3062 DWORD rDst, DWORD gDst, DWORD bDst,
3063 XImage *bmpImage, DWORD linebytes )
3066 int h, width = min(srcwidth, dstwidth);
3068 const dib_conversions *convs = (bmpImage->byte_order == LSBFirst) ? &dib_normal : &dib_src_byteswap;
3073 dstbits = dstbits + ( linebytes * (lines-1) );
3074 linebytes = -linebytes;
3079 switch (bmpImage->depth)
3082 if (bmpImage->bits_per_pixel==24) {
3083 const void* srcbits;
3085 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3087 if (rDst==bmpImage->red_mask && gDst==bmpImage->green_mask && bDst==bmpImage->blue_mask) {
3088 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3089 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3090 convs->Convert_888_to_0888_asis
3092 srcbits,-bmpImage->bytes_per_line,
3094 } else if (bmpImage->green_mask!=0x00ff00 ||
3095 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3097 /* the tests below assume sane bmpImage masks */
3098 } else if (rDst==bmpImage->blue_mask && gDst==bmpImage->green_mask && bDst==bmpImage->red_mask) {
3099 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3100 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3101 convs->Convert_888_to_0888_reverse
3103 srcbits,-bmpImage->bytes_per_line,
3105 } else if (bmpImage->blue_mask==0xff) {
3106 /* ==== rgb 888 bmp -> any 0888 dib ==== */
3107 convs->Convert_rgb888_to_any0888
3109 srcbits,-bmpImage->bytes_per_line,
3113 /* ==== bgr 888 bmp -> any 0888 dib ==== */
3114 convs->Convert_bgr888_to_any0888
3116 srcbits,-bmpImage->bytes_per_line,
3126 const char* srcbits;
3128 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3130 if (gDst==bmpImage->green_mask) {
3131 if (rDst==bmpImage->red_mask && bDst==bmpImage->blue_mask) {
3132 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
3133 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
3134 convs->Convert_0888_asis
3136 srcbits,-bmpImage->bytes_per_line,
3138 } else if (bmpImage->green_mask!=0x00ff00 ||
3139 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3141 /* the tests below assume sane bmpImage masks */
3142 } else if (rDst==bmpImage->blue_mask && bDst==bmpImage->red_mask) {
3143 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
3144 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
3145 convs->Convert_0888_reverse
3147 srcbits,-bmpImage->bytes_per_line,
3150 /* ==== any 0888 bmp -> any 0888 dib ==== */
3151 convs->Convert_0888_any
3153 srcbits,-bmpImage->bytes_per_line,
3154 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3158 } else if (bmpImage->green_mask!=0x00ff00 ||
3159 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3161 /* the tests below assume sane bmpImage masks */
3163 /* ==== any 0888 bmp -> any 0888 dib ==== */
3164 convs->Convert_0888_any
3166 srcbits,-bmpImage->bytes_per_line,
3167 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3177 const char* srcbits;
3179 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3181 if (rDst==0xff0000 && gDst==0x00ff00 && bDst==0x0000ff) {
3182 if (bmpImage->green_mask==0x03e0) {
3183 if (bmpImage->red_mask==0x7f00) {
3184 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
3185 convs->Convert_555_to_0888_asis
3187 srcbits,-bmpImage->bytes_per_line,
3189 } else if (bmpImage->blue_mask==0x7f00) {
3190 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
3191 convs->Convert_555_to_0888_reverse
3193 srcbits,-bmpImage->bytes_per_line,
3198 } else if (bmpImage->green_mask==0x07e0) {
3199 if (bmpImage->red_mask==0xf800) {
3200 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
3201 convs->Convert_565_to_0888_asis
3203 srcbits,-bmpImage->bytes_per_line,
3205 } else if (bmpImage->blue_mask==0xf800) {
3206 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
3207 convs->Convert_565_to_0888_reverse
3209 srcbits,-bmpImage->bytes_per_line,
3217 } else if (rDst==0x0000ff && gDst==0x00ff00 && bDst==0xff0000) {
3218 if (bmpImage->green_mask==0x03e0) {
3219 if (bmpImage->blue_mask==0x7f00) {
3220 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
3221 convs->Convert_555_to_0888_asis
3223 srcbits,-bmpImage->bytes_per_line,
3225 } else if (bmpImage->red_mask==0x7f00) {
3226 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
3227 convs->Convert_555_to_0888_reverse
3229 srcbits,-bmpImage->bytes_per_line,
3234 } else if (bmpImage->green_mask==0x07e0) {
3235 if (bmpImage->blue_mask==0xf800) {
3236 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
3237 convs->Convert_565_to_0888_asis
3239 srcbits,-bmpImage->bytes_per_line,
3241 } else if (bmpImage->red_mask==0xf800) {
3242 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
3243 convs->Convert_565_to_0888_reverse
3245 srcbits,-bmpImage->bytes_per_line,
3254 if (bmpImage->green_mask==0x03e0 &&
3255 (bmpImage->red_mask==0x7f00 ||
3256 bmpImage->blue_mask==0x7f00)) {
3257 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
3258 convs->Convert_5x5_to_any0888
3260 srcbits,-bmpImage->bytes_per_line,
3261 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3264 } else if (bmpImage->green_mask==0x07e0 &&
3265 (bmpImage->red_mask==0xf800 ||
3266 bmpImage->blue_mask==0xf800)) {
3267 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
3268 convs->Convert_5x5_to_any0888
3270 srcbits,-bmpImage->bytes_per_line,
3271 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
3283 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3284 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
3285 int rShift,gShift,bShift;
3288 rShift=X11DRV_DIB_MaskToShift(rDst);
3289 gShift=X11DRV_DIB_MaskToShift(gDst);
3290 bShift=X11DRV_DIB_MaskToShift(bDst);
3291 for (h = lines - 1; h >= 0; h--) {
3292 dstpixel=(DWORD*)dstbits;
3293 for (x = 0; x < width; x++) {
3294 PALETTEENTRY srcval;
3295 srcval = srccolors[XGetPixel(bmpImage, x, h)];
3296 *dstpixel++=(srcval.peRed << rShift) |
3297 (srcval.peGreen << gShift) |
3298 (srcval.peBlue << bShift);
3300 dstbits += linebytes;
3308 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3309 /* ==== pal 8 bmp -> any 0888 dib ==== */
3310 int rShift,gShift,bShift;
3311 const void* srcbits;
3312 const BYTE* srcpixel;
3315 rShift=X11DRV_DIB_MaskToShift(rDst);
3316 gShift=X11DRV_DIB_MaskToShift(gDst);
3317 bShift=X11DRV_DIB_MaskToShift(bDst);
3318 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3319 for (h = lines - 1; h >= 0; h--) {
3321 dstpixel=(DWORD*)dstbits;
3322 for (x = 0; x < width; x++) {
3323 PALETTEENTRY srcval;
3324 srcval=srccolors[(int)*srcpixel++];
3325 *dstpixel++=(srcval.peRed << rShift) |
3326 (srcval.peGreen << gShift) |
3327 (srcval.peBlue << bShift);
3329 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
3330 dstbits += linebytes;
3340 /* ==== any bmp format -> any 0888 dib ==== */
3341 int rShift,gShift,bShift;
3344 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
3345 bmpImage->depth, bmpImage->red_mask,
3346 bmpImage->green_mask, bmpImage->blue_mask,
3349 rShift=X11DRV_DIB_MaskToShift(rDst);
3350 gShift=X11DRV_DIB_MaskToShift(gDst);
3351 bShift=X11DRV_DIB_MaskToShift(bDst);
3352 for (h = lines - 1; h >= 0; h--) {
3353 dstpixel=(DWORD*)dstbits;
3354 for (x = 0; x < width; x++) {
3356 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
3357 *dstpixel++=(GetRValue(srcval) << rShift) |
3358 (GetGValue(srcval) << gShift) |
3359 (GetBValue(srcval) << bShift);
3361 dstbits += linebytes;
3368 /***********************************************************************
3369 * X11DRV_DIB_SetImageBits
3371 * Transfer the bits to an X image.
3372 * Helper function for SetDIBits() and SetDIBitsToDevice().
3374 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
3376 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
3381 bmpImage = descr->image;
3383 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
3384 descr->infoWidth, lines, 32, 0 );
3385 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
3386 if(bmpImage->data == NULL) {
3387 ERR("Out of memory!\n");
3388 XDestroyImage( bmpImage );
3389 wine_tsx11_unlock();
3394 TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
3395 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
3396 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
3397 bmpImage->depth,bmpImage->bits_per_pixel,
3398 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
3400 /* Transfer the pixels */
3401 switch(descr->infoBpp)
3404 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
3405 descr->width, descr->xSrc, (int *)(descr->colorMap),
3406 bmpImage, descr->dibpitch );
3409 if (descr->compression) {
3410 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
3411 descr->width, descr->height, AllPlanes, ZPixmap,
3412 bmpImage, descr->xSrc, descr->ySrc );
3414 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
3415 descr->infoWidth, descr->width,
3416 descr->xSrc, (int *)(descr->colorMap),
3419 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
3420 descr->infoWidth, descr->width,
3421 descr->xSrc, (int*)(descr->colorMap),
3422 bmpImage, descr->dibpitch );
3425 if (descr->compression) {
3426 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
3427 descr->width, descr->height, AllPlanes, ZPixmap,
3428 bmpImage, descr->xSrc, descr->ySrc );
3429 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
3430 descr->infoWidth, descr->width,
3431 descr->xSrc, (int *)(descr->colorMap),
3434 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
3435 descr->infoWidth, descr->width,
3436 descr->xSrc, (int *)(descr->colorMap),
3437 bmpImage, descr->dibpitch );
3441 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
3442 descr->infoWidth, descr->width,
3443 descr->xSrc, descr->physDev,
3444 descr->rMask, descr->gMask, descr->bMask,
3445 bmpImage, descr->dibpitch);
3448 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
3449 descr->infoWidth, descr->width,
3450 descr->xSrc, descr->physDev,
3451 descr->rMask, descr->gMask, descr->bMask,
3452 bmpImage, descr->dibpitch);
3455 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
3456 descr->infoWidth, descr->width,
3457 descr->xSrc, descr->physDev,
3458 descr->rMask, descr->gMask, descr->bMask,
3459 bmpImage, descr->dibpitch);
3462 WARN("(%d): Invalid depth\n", descr->infoBpp );
3466 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
3467 descr->drawable, descr->gc, bmpImage,
3468 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
3469 descr->width, descr->height);
3470 #ifdef HAVE_LIBXXSHM
3473 XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
3474 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
3475 descr->width, descr->height, FALSE );
3476 XSync( gdi_display, 0 );
3480 XPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
3481 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
3482 descr->width, descr->height );
3484 if (!descr->image) XDestroyImage( bmpImage );
3485 wine_tsx11_unlock();
3489 /***********************************************************************
3490 * X11DRV_DIB_GetImageBits
3492 * Transfer the bits from an X image.
3494 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
3496 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
3501 bmpImage = descr->image;
3503 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
3504 descr->infoWidth, lines, 32, 0 );
3505 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
3506 if(bmpImage->data == NULL) {
3507 ERR("Out of memory!\n");
3508 XDestroyImage( bmpImage );
3509 wine_tsx11_unlock();
3514 #ifdef HAVE_LIBXXSHM
3517 int saveRed, saveGreen, saveBlue;
3519 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
3520 gdi_display, descr->drawable, bmpImage,
3521 descr->xSrc, descr->ySrc, AllPlanes);
3523 /* We must save and restore the bmpImage's masks in order
3524 * to preserve them across the call to XShmGetImage, which
3525 * decides to eleminate them since it doesn't happen to know
3526 * what the format of the image is supposed to be, even though
3528 saveRed = bmpImage->red_mask;
3529 saveBlue= bmpImage->blue_mask;
3530 saveGreen = bmpImage->green_mask;
3532 XShmGetImage( gdi_display, descr->drawable, bmpImage,
3533 descr->xSrc, descr->ySrc, AllPlanes);
3535 bmpImage->red_mask = saveRed;
3536 bmpImage->blue_mask = saveBlue;
3537 bmpImage->green_mask = saveGreen;
3540 #endif /* HAVE_LIBXXSHM */
3542 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
3543 gdi_display, descr->drawable, descr->xSrc, descr->ySrc, descr->width,
3544 lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
3545 XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc,
3546 descr->width, lines, AllPlanes, ZPixmap,
3547 bmpImage, descr->xDest, descr->yDest );
3550 TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
3551 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
3552 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
3553 bmpImage->depth,bmpImage->bits_per_pixel,
3554 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
3555 /* Transfer the pixels */
3556 switch(descr->infoBpp)
3559 X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
3560 descr->infoWidth, descr->width,
3561 descr->colorMap, descr->palentry,
3562 bmpImage, descr->dibpitch );
3566 if (descr->compression) {
3567 FIXME("Compression not yet supported!\n");
3568 if(descr->sizeImage < X11DRV_DIB_GetDIBWidthBytes( descr->infoWidth, 4 ) * abs(descr->lines))
3571 X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
3572 descr->infoWidth, descr->width,
3573 descr->colorMap, descr->palentry,
3574 bmpImage, descr->dibpitch );
3577 if (descr->compression) {
3578 FIXME("Compression not yet supported!\n");
3579 if(descr->sizeImage < X11DRV_DIB_GetDIBWidthBytes( descr->infoWidth, 8 ) * abs(descr->lines))
3582 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
3583 descr->infoWidth, descr->width,
3584 descr->colorMap, descr->palentry,
3585 bmpImage, descr->dibpitch );
3589 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
3590 descr->infoWidth,descr->width,
3592 descr->rMask, descr->gMask, descr->bMask,
3593 bmpImage, descr->dibpitch );
3597 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
3598 descr->infoWidth,descr->width,
3600 descr->rMask, descr->gMask, descr->bMask,
3601 bmpImage, descr->dibpitch);
3605 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
3606 descr->infoWidth, descr->width,
3608 descr->rMask, descr->gMask, descr->bMask,
3609 bmpImage, descr->dibpitch);
3613 WARN("(%d): Invalid depth\n", descr->infoBpp );
3617 if (!descr->image) XDestroyImage( bmpImage );
3618 wine_tsx11_unlock();
3622 /*************************************************************************
3623 * X11DRV_SetDIBitsToDevice
3626 INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWORD cx,
3627 DWORD cy, INT xSrc, INT ySrc,
3628 UINT startscan, UINT lines, LPCVOID bits,
3629 const BITMAPINFO *info, UINT coloruse )
3631 X11DRV_DIB_IMAGEBITS_DESCR descr;
3638 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
3639 &descr.infoBpp, &descr.compression ) == -1)
3641 top_down = (height < 0);
3642 if (top_down) height = -height;
3646 LPtoDP(physDev->hdc, &pt, 1);
3648 if (!lines || (startscan >= height)) return 0;
3649 if (!top_down && startscan + lines > height) lines = height - startscan;
3651 /* make xSrc,ySrc point to the upper-left corner, not the lower-left one,
3652 * and clamp all values to fit inside [startscan,startscan+lines]
3654 if (ySrc + cy <= startscan + lines)
3656 UINT y = startscan + lines - (ySrc + cy);
3657 if (ySrc < startscan) cy -= (startscan - ySrc);
3660 /* avoid getting unnecessary lines */
3662 if (y >= lines) return 0;
3667 if (y >= lines) return lines;
3668 ySrc = y; /* need to get all lines in top down mode */
3673 if (ySrc >= startscan + lines) return lines;
3674 pt.y += ySrc + cy - (startscan + lines);
3675 cy = startscan + lines - ySrc;
3677 if (cy > lines) cy = lines;
3679 if (xSrc >= width) return lines;
3680 if (xSrc + cx >= width) cx = width - xSrc;
3681 if (!cx || !cy) return lines;
3683 /* Update the pixmap from the DIB section */
3684 X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
3686 X11DRV_SetupGCForText( physDev ); /* To have the correct colors */
3688 XSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[GetROP2(physDev->hdc) - 1]);
3689 wine_tsx11_unlock();
3691 switch (descr.infoBpp)
3696 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
3697 coloruse == DIB_PAL_COLORS ? physDev : NULL, coloruse,
3698 physDev->depth, info, &descr.nColorMap );
3699 if (!descr.colorMap) return 0;
3700 descr.rMask = descr.gMask = descr.bMask = 0;
3704 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
3705 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
3706 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
3712 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
3713 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
3714 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
3719 descr.physDev = physDev;
3722 descr.palentry = NULL;
3723 descr.lines = top_down ? -lines : lines;
3724 descr.infoWidth = width;
3725 descr.depth = physDev->depth;
3726 descr.drawable = physDev->drawable;
3727 descr.gc = physDev->gc;
3730 descr.xDest = physDev->org.x + pt.x;
3731 descr.yDest = physDev->org.y + pt.y;
3734 descr.useShm = FALSE;
3735 descr.dibpitch = ((width * descr.infoBpp + 31) &~31) / 8;
3737 result = X11DRV_DIB_SetImageBits( &descr );
3739 if (descr.infoBpp <= 8)
3740 HeapFree(GetProcessHeap(), 0, descr.colorMap);
3742 /* Update the DIBSection of the pixmap */
3743 X11DRV_UnlockDIBSection(physDev, TRUE);
3748 /***********************************************************************
3749 * SetDIBits (X11DRV.@)
3751 INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
3752 UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse )
3754 X11DRV_DIB_IMAGEBITS_DESCR descr;
3756 int height, tmpheight;
3759 descr.physDev = physDev;
3761 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
3762 &descr.infoBpp, &descr.compression ) == -1)
3766 if (height < 0) height = -height;
3767 if (!lines || (startscan >= height))
3770 if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
3772 if (startscan + lines > height) lines = height - startscan;
3774 switch (descr.infoBpp)
3779 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
3780 coloruse == DIB_PAL_COLORS ? descr.physDev : NULL, coloruse,
3781 bmp->bitmap.bmBitsPixel,
3782 info, &descr.nColorMap );
3783 if (!descr.colorMap)
3785 GDI_ReleaseObj( hbitmap );
3788 descr.rMask = descr.gMask = descr.bMask = 0;
3792 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
3793 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
3794 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
3800 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
3801 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
3802 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
3811 descr.palentry = NULL;
3812 descr.lines = tmpheight >= 0 ? lines : -lines;
3813 descr.depth = bmp->bitmap.bmBitsPixel;
3814 descr.drawable = (Pixmap)bmp->physBitmap;
3815 descr.gc = BITMAP_GC(bmp);
3819 descr.yDest = height - startscan - lines;
3820 descr.width = bmp->bitmap.bmWidth;
3821 descr.height = lines;
3822 descr.useShm = FALSE;
3823 descr.dibpitch = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
3824 X11DRV_DIB_Lock(bmp, DIB_Status_GdiMod, FALSE);
3825 result = X11DRV_DIB_SetImageBits( &descr );
3826 X11DRV_DIB_Unlock(bmp, TRUE);
3828 if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);
3830 GDI_ReleaseObj( hbitmap );
3834 /***********************************************************************
3835 * GetDIBits (X11DRV.@)
3837 INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan, UINT lines,
3838 LPVOID bits, BITMAPINFO *info, UINT coloruse )
3840 X11DRV_DIBSECTION *dib;
3841 X11DRV_DIB_IMAGEBITS_DESCR descr;
3842 PALETTEENTRY palette[256];
3846 GetPaletteEntries( GetCurrentObject( physDev->hdc, OBJ_PAL ), 0, 256, palette );
3848 if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
3850 dib = (X11DRV_DIBSECTION *) bmp->dib;
3852 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
3853 lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
3854 (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
3857 if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
3859 height = info->bmiHeader.biHeight;
3860 if (height < 0) height = -height;
3861 if( lines > height ) lines = height;
3862 /* Top-down images have a negative biHeight, the scanlines of theses images
3863 * were inverted in X11DRV_DIB_GetImageBits_xx
3864 * To prevent this we simply change the sign of lines
3865 * (the number of scan lines to copy).
3866 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3868 if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
3870 if( startscan >= bmp->bitmap.bmHeight )
3876 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
3877 &descr.infoBpp, &descr.compression ) == -1)
3883 descr.colorMap = NULL;
3885 switch (descr.infoBpp)
3890 descr.rMask= descr.gMask = descr.bMask = 0;
3891 if(coloruse == DIB_RGB_COLORS)
3892 descr.colorMap = info->bmiColors;
3894 int num_colors = 1 << descr.infoBpp, i;
3897 WORD *index = (WORD*)info->bmiColors;
3898 descr.colorMap = rgb = HeapAlloc(GetProcessHeap(), 0, num_colors * sizeof(RGBQUAD));
3899 for(i = 0; i < num_colors; i++, rgb++, index++) {
3900 colref = X11DRV_PALETTE_ToLogical(X11DRV_PALETTE_ToPhysical(physDev, PALETTEINDEX(*index)));
3901 rgb->rgbRed = GetRValue(colref);
3902 rgb->rgbGreen = GetGValue(colref);
3903 rgb->rgbBlue = GetBValue(colref);
3904 rgb->rgbReserved = 0;
3910 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
3911 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
3912 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
3916 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
3917 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
3918 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
3922 descr.physDev = physDev;
3923 descr.palentry = palette;
3926 descr.lines = lines;
3927 descr.depth = bmp->bitmap.bmBitsPixel;
3928 descr.drawable = (Pixmap)bmp->physBitmap;
3929 descr.gc = BITMAP_GC(bmp);
3930 descr.width = bmp->bitmap.bmWidth;
3931 descr.height = bmp->bitmap.bmHeight;
3935 descr.sizeImage = info->bmiHeader.biSizeImage;
3937 if (descr.lines > 0)
3939 descr.ySrc = (descr.height-1) - (startscan + (lines-1));
3943 descr.ySrc = startscan;
3945 #ifdef HAVE_LIBXXSHM
3946 descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
3948 descr.useShm = FALSE;
3950 descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
3951 : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
3953 X11DRV_DIB_Lock(bmp, DIB_Status_GdiMod, FALSE);
3954 X11DRV_DIB_GetImageBits( &descr );
3955 X11DRV_DIB_Unlock(bmp, TRUE);
3957 if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
3958 info->bmiHeader.biSizeImage = X11DRV_DIB_GetDIBWidthBytes( info->bmiHeader.biWidth,
3959 info->bmiHeader.biBitCount )
3960 * abs( info->bmiHeader.biHeight );
3962 if (descr.compression == BI_BITFIELDS)
3964 *(DWORD *)info->bmiColors = descr.rMask;
3965 *((DWORD *)info->bmiColors+1) = descr.gMask;
3966 *((DWORD *)info->bmiColors+2) = descr.bMask;
3970 /* if RLE or JPEG compression were supported,
3971 * this line would be invalid. */
3972 info->bmiHeader.biCompression = 0;
3975 if(descr.colorMap && descr.colorMap != info->bmiColors)
3976 HeapFree(GetProcessHeap(), 0, descr.colorMap);
3978 GDI_ReleaseObj( hbitmap );
3982 /***********************************************************************
3983 * DIB_DoProtectDIBSection
3985 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
3989 DIBSECTION *dib = bmp->dib;
3990 INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
3991 : -dib->dsBm.bmHeight;
3993 /* use the biSizeImage data as the memory size only if we're dealing with a
3994 compressed image where the value is set. Otherwise, calculate based on
3996 if (dib->dsBmih.biSizeImage &&
3997 (dib->dsBmih.biCompression == BI_RLE4 || dib->dsBmih.biCompression == BI_RLE8))
3998 totalSize = dib->dsBmih.biSizeImage;
4000 totalSize = dib->dsBm.bmWidthBytes * effHeight;
4002 VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
4003 TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
4006 /***********************************************************************
4007 * X11DRV_DIB_DoUpdateDIBSection
4009 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
4010 void *colorMap, int nColorMap,
4012 DWORD xSrc, DWORD ySrc,
4013 DWORD xDest, DWORD yDest,
4014 DWORD width, DWORD height)
4016 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4017 X11DRV_DIB_IMAGEBITS_DESCR descr;
4018 int identity[2] = {0,1};
4020 if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
4021 &descr.infoBpp, &descr.compression ) == -1)
4024 descr.physDev = NULL;
4025 descr.palentry = NULL;
4026 descr.image = dib->image;
4027 descr.colorMap = colorMap;
4028 descr.nColorMap = nColorMap;
4029 descr.bits = dib->dibSection.dsBm.bmBits;
4030 descr.depth = bmp->bitmap.bmBitsPixel;
4032 if(descr.infoBpp == 1)
4033 descr.colorMap = (void*)identity;
4035 switch (descr.infoBpp)
4040 descr.rMask = descr.gMask = descr.bMask = 0;
4044 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
4045 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
4046 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
4051 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff0000;
4052 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x00ff00;
4053 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x0000ff;
4058 descr.drawable = dest;
4059 descr.gc = BITMAP_GC(bmp);
4062 descr.xDest = xDest;
4063 descr.yDest = yDest;
4064 descr.width = width;
4065 descr.height = height;
4066 descr.sizeImage = 0;
4068 #ifdef HAVE_LIBXXSHM
4069 descr.useShm = (dib->shminfo.shmid != -1);
4071 descr.useShm = FALSE;
4073 descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
4077 TRACE("Copying from Pixmap to DIB bits\n");
4078 X11DRV_DIB_GetImageBits( &descr );
4082 TRACE("Copying from DIB bits to Pixmap\n");
4083 X11DRV_DIB_SetImageBits( &descr );
4087 /***********************************************************************
4088 * X11DRV_DIB_CopyDIBSection
4090 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
4091 DWORD xSrc, DWORD ySrc, DWORD xDest, DWORD yDest,
4092 DWORD width, DWORD height)
4096 int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE;
4098 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", physDevSrc->hdc, physDevDst->hdc,
4099 xSrc, ySrc, xDest, yDest, width, height);
4100 /* this function is meant as an optimization for BitBlt,
4101 * not to be called otherwise */
4102 if (GetObjectType( physDevSrc->hdc ) != OBJ_MEMDC) {
4103 ERR("called for non-memory source DC!?\n");
4107 hBitmap = GetCurrentObject( physDevSrc->hdc, OBJ_BITMAP );
4108 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC );
4109 if (!(bmp && bmp->dib)) {
4110 ERR("called for non-DIBSection!?\n");
4111 GDI_ReleaseObj( hBitmap );
4114 /* while BitBlt should already have made sure we only get
4115 * positive values, we should check for oversize values */
4116 if ((xSrc < bmp->bitmap.bmWidth) &&
4117 (ySrc < bmp->bitmap.bmHeight)) {
4118 if (xSrc + width > bmp->bitmap.bmWidth)
4119 width = bmp->bitmap.bmWidth - xSrc;
4120 if (ySrc + height > bmp->bitmap.bmHeight)
4121 height = bmp->bitmap.bmHeight - ySrc;
4122 /* if the source bitmap is 8bpp or less, we're supposed to use the
4123 * DC's palette for color conversion (not the DIB color table) */
4124 if (bmp->dib->dsBm.bmBitsPixel <= 8) {
4125 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4126 HPALETTE hPalette = GetCurrentObject( physDevSrc->hdc, OBJ_PAL );
4127 if (!hPalette || (hPalette == GetStockObject(DEFAULT_PALETTE))) {
4128 /* HACK: no palette has been set in the source DC,
4129 * use the DIB colormap instead - this is necessary in some
4130 * cases since we need to do depth conversion in some places
4131 * where real Windows can just copy data straight over */
4132 colorMap = dib->colorMap;
4133 nColorMap = dib->nColorMap;
4135 colorMap = X11DRV_DIB_BuildColorMap( physDevSrc, (WORD)-1,
4136 bmp->dib->dsBm.bmBitsPixel,
4137 (BITMAPINFO*)&(bmp->dib->dsBmih),
4139 if (colorMap) aColorMap = TRUE;
4142 /* perform the copy */
4143 X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap,
4144 physDevDst->drawable, xSrc, ySrc,
4145 physDevDst->org.x + xDest, physDevDst->org.y + yDest,
4147 /* free color mapping */
4149 HeapFree(GetProcessHeap(), 0, colorMap);
4151 GDI_ReleaseObj( hBitmap );
4154 /***********************************************************************
4155 * X11DRV_DIB_DoUpdateDIBSection
4157 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
4159 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4160 X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap,
4161 (Drawable)bmp->physBitmap, 0, 0, 0, 0,
4162 bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
4165 /***********************************************************************
4166 * X11DRV_DIB_FaultHandler
4168 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
4173 bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
4174 if (!bmp) return FALSE;
4176 state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
4177 if (state != DIB_Status_InSync) {
4178 /* no way to tell whether app needs read or write yet,
4180 X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
4182 /* hm, apparently the app must have write access */
4183 X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
4185 X11DRV_DIB_Unlock(bmp, TRUE);
4187 GDI_ReleaseObj( (HBITMAP)res );
4191 /***********************************************************************
4194 INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
4196 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4197 INT ret = DIB_Status_None;
4200 EnterCriticalSection(&(dib->lock));
4203 case DIB_Status_GdiMod:
4204 /* GDI access - request to draw on pixmap */
4205 switch (dib->status)
4208 case DIB_Status_None:
4209 dib->p_status = DIB_Status_GdiMod;
4210 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
4213 case DIB_Status_GdiMod:
4214 TRACE("GdiMod requested in status GdiMod\n" );
4217 case DIB_Status_InSync:
4218 TRACE("GdiMod requested in status InSync\n" );
4219 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
4220 dib->status = DIB_Status_GdiMod;
4221 dib->p_status = DIB_Status_InSync;
4224 case DIB_Status_AuxMod:
4225 TRACE("GdiMod requested in status AuxMod\n" );
4226 if (lossy) dib->status = DIB_Status_GdiMod;
4227 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
4228 dib->p_status = DIB_Status_AuxMod;
4229 if (dib->status != DIB_Status_AppMod) {
4230 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
4233 /* fall through if copy_aux() had to change to AppMod state */
4235 case DIB_Status_AppMod:
4236 TRACE("GdiMod requested in status AppMod\n" );
4238 /* make it readonly to avoid app changing data while we copy */
4239 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4240 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
4242 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
4243 dib->p_status = DIB_Status_AppMod;
4244 dib->status = DIB_Status_GdiMod;
4249 case DIB_Status_InSync:
4250 /* App access - request access to read DIB surface */
4251 /* (typically called from signal handler) */
4252 switch (dib->status)
4255 case DIB_Status_None:
4256 /* shouldn't happen from signal handler */
4259 case DIB_Status_AuxMod:
4260 TRACE("InSync requested in status AuxMod\n" );
4261 if (lossy) dib->status = DIB_Status_InSync;
4263 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4264 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
4266 if (dib->status != DIB_Status_GdiMod) {
4267 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4270 /* fall through if copy_aux() had to change to GdiMod state */
4272 case DIB_Status_GdiMod:
4273 TRACE("InSync requested in status GdiMod\n" );
4275 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4276 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
4278 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4279 dib->status = DIB_Status_InSync;
4282 case DIB_Status_InSync:
4283 TRACE("InSync requested in status InSync\n" );
4284 /* shouldn't happen from signal handler */
4287 case DIB_Status_AppMod:
4288 TRACE("InSync requested in status AppMod\n" );
4289 /* no reason to do anything here, and this
4290 * shouldn't happen from signal handler */
4295 case DIB_Status_AppMod:
4296 /* App access - request access to write DIB surface */
4297 /* (typically called from signal handler) */
4298 switch (dib->status)
4301 case DIB_Status_None:
4302 /* shouldn't happen from signal handler */
4305 case DIB_Status_AuxMod:
4306 TRACE("AppMod requested in status AuxMod\n" );
4307 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4308 if (lossy) dib->status = DIB_Status_AppMod;
4309 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
4310 if (dib->status != DIB_Status_GdiMod)
4312 /* fall through if copy_aux() had to change to GdiMod state */
4314 case DIB_Status_GdiMod:
4315 TRACE("AppMod requested in status GdiMod\n" );
4316 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4317 if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
4318 dib->status = DIB_Status_AppMod;
4321 case DIB_Status_InSync:
4322 TRACE("AppMod requested in status InSync\n" );
4323 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4324 dib->status = DIB_Status_AppMod;
4327 case DIB_Status_AppMod:
4328 TRACE("AppMod requested in status AppMod\n" );
4329 /* shouldn't happen from signal handler */
4334 case DIB_Status_AuxMod:
4335 if (dib->status == DIB_Status_None) {
4336 dib->p_status = req;
4338 if (dib->status != DIB_Status_AuxMod)
4339 dib->p_status = dib->status;
4340 dib->status = DIB_Status_AuxMod;
4343 /* it is up to the caller to do the copy/conversion, probably
4344 * using the return value to decide where to copy from */
4346 LeaveCriticalSection(&(dib->lock));
4351 /***********************************************************************
4354 INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
4356 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4357 INT ret = DIB_Status_None;
4360 TRACE("Locking %p from thread %04lx\n", bmp, GetCurrentThreadId());
4361 EnterCriticalSection(&(dib->lock));
4363 if (req != DIB_Status_None)
4364 X11DRV_DIB_Coerce(bmp, req, lossy);
4369 /***********************************************************************
4372 void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
4374 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4377 switch (dib->status)
4380 case DIB_Status_None:
4381 /* in case anyone is wondering, this is the "signal handler doesn't
4382 * work" case, where we always have to be ready for app access */
4384 switch (dib->p_status)
4386 case DIB_Status_AuxMod:
4387 TRACE("Unlocking and syncing from AuxMod\n" );
4388 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
4389 if (dib->status != DIB_Status_None) {
4390 dib->p_status = dib->status;
4391 dib->status = DIB_Status_None;
4393 if (dib->p_status != DIB_Status_GdiMod)
4395 /* fall through if copy_aux() had to change to GdiMod state */
4397 case DIB_Status_GdiMod:
4398 TRACE("Unlocking and syncing from GdiMod\n" );
4399 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
4403 TRACE("Unlocking without needing to sync\n" );
4407 else TRACE("Unlocking with no changes\n");
4408 dib->p_status = DIB_Status_None;
4411 case DIB_Status_GdiMod:
4412 TRACE("Unlocking in status GdiMod\n" );
4413 /* DIB was protected in Coerce */
4415 /* no commit, revert to InSync if applicable */
4416 if ((dib->p_status == DIB_Status_InSync) ||
4417 (dib->p_status == DIB_Status_AppMod)) {
4418 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
4419 dib->status = DIB_Status_InSync;
4424 case DIB_Status_InSync:
4425 TRACE("Unlocking in status InSync\n" );
4426 /* DIB was already protected in Coerce */
4429 case DIB_Status_AppMod:
4430 TRACE("Unlocking in status AppMod\n" );
4431 /* DIB was already protected in Coerce */
4432 /* this case is ordinary only called from the signal handler,
4433 * so we don't bother to check for !commit */
4436 case DIB_Status_AuxMod:
4437 TRACE("Unlocking in status AuxMod\n" );
4439 /* DIB may need protection now */
4440 if ((dib->p_status == DIB_Status_InSync) ||
4441 (dib->p_status == DIB_Status_AppMod))
4442 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
4444 /* no commit, revert to previous state */
4445 if (dib->p_status != DIB_Status_None)
4446 dib->status = dib->p_status;
4447 /* no protections changed */
4449 dib->p_status = DIB_Status_None;
4452 LeaveCriticalSection(&(dib->lock));
4453 TRACE("Unlocked %p\n", bmp);
4457 /***********************************************************************
4458 * X11DRV_CoerceDIBSection2
4460 INT X11DRV_CoerceDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
4465 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4466 if (!bmp) return DIB_Status_None;
4467 ret = X11DRV_DIB_Coerce(bmp, req, lossy);
4468 GDI_ReleaseObj( hBmp );
4472 /***********************************************************************
4473 * X11DRV_LockDIBSection2
4475 INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
4480 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4481 if (!bmp) return DIB_Status_None;
4482 ret = X11DRV_DIB_Lock(bmp, req, lossy);
4483 GDI_ReleaseObj( hBmp );
4487 /***********************************************************************
4488 * X11DRV_UnlockDIBSection2
4490 void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
4494 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4496 X11DRV_DIB_Unlock(bmp, commit);
4497 GDI_ReleaseObj( hBmp );
4500 /***********************************************************************
4501 * X11DRV_CoerceDIBSection
4503 INT X11DRV_CoerceDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
4505 if (!physDev) return DIB_Status_None;
4506 return X11DRV_CoerceDIBSection2( GetCurrentObject( physDev->hdc, OBJ_BITMAP ), req, lossy );
4509 /***********************************************************************
4510 * X11DRV_LockDIBSection
4512 INT X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
4514 if (!physDev) return DIB_Status_None;
4515 if (GetObjectType( physDev->hdc ) != OBJ_MEMDC) return DIB_Status_None;
4517 return X11DRV_LockDIBSection2( GetCurrentObject( physDev->hdc, OBJ_BITMAP ), req, lossy );
4520 /***********************************************************************
4521 * X11DRV_UnlockDIBSection
4523 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE *physDev, BOOL commit)
4525 if (!physDev) return;
4526 if (GetObjectType( physDev->hdc ) != OBJ_MEMDC) return;
4528 X11DRV_UnlockDIBSection2( GetCurrentObject( physDev->hdc, OBJ_BITMAP ), commit );
4532 #ifdef HAVE_LIBXXSHM
4533 /***********************************************************************
4534 * X11DRV_XShmErrorHandler
4537 static int XShmErrorHandler( Display *dpy, XErrorEvent *event, void *arg )
4539 return 1; /* FIXME: should check event contents */
4542 /***********************************************************************
4543 * X11DRV_XShmCreateImage
4546 static XImage *X11DRV_XShmCreateImage( int width, int height, int bpp,
4547 XShmSegmentInfo* shminfo)
4551 image = XShmCreateImage(gdi_display, visual, bpp, ZPixmap, NULL, shminfo, width, height);
4554 shminfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height,
4556 if( shminfo->shmid != -1 )
4558 shminfo->shmaddr = image->data = shmat(shminfo->shmid, 0, 0);
4559 if( shminfo->shmaddr != (char*)-1 )
4563 shminfo->readOnly = FALSE;
4564 X11DRV_expect_error( gdi_display, XShmErrorHandler, NULL );
4565 ok = (XShmAttach( gdi_display, shminfo ) != 0);
4566 XSync( gdi_display, False );
4567 if (X11DRV_check_error()) ok = FALSE;
4570 shmctl(shminfo->shmid, IPC_RMID, 0);
4571 return image; /* Success! */
4573 /* An error occurred */
4574 shmdt(shminfo->shmaddr);
4576 shmctl(shminfo->shmid, IPC_RMID, 0);
4578 XFlush(gdi_display);
4579 XDestroyImage(image);
4584 #endif /* HAVE_LIBXXSHM */
4587 /***********************************************************************
4588 * X11DRV_DIB_CreateDIBSection
4590 HBITMAP X11DRV_DIB_CreateDIBSection(
4591 X11DRV_PDEVICE *physDev, const BITMAPINFO *bmi, UINT usage,
4592 VOID **bits, HANDLE section,
4593 DWORD offset, DWORD ovr_pitch)
4596 BITMAPOBJ *bmp = NULL;
4597 X11DRV_DIBSECTION *dib = NULL;
4598 int *colorMap = NULL;
4600 RGBQUAD *colorTable = NULL;
4602 /* Fill BITMAP32 structure with DIB data */
4603 const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
4604 INT effHeight, totalSize;
4606 LPVOID mapBits = NULL;
4608 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
4609 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
4610 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
4612 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
4614 bm.bmWidth = bi->biWidth;
4615 bm.bmHeight = effHeight;
4616 bm.bmWidthBytes = ovr_pitch ? ovr_pitch : X11DRV_DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
4617 bm.bmPlanes = bi->biPlanes;
4618 bm.bmBitsPixel = bi->biBitCount;
4621 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
4622 we're dealing with a compressed bitmap. Otherwise, use width * height. */
4623 if (bi->biSizeImage && (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8))
4624 totalSize = bi->biSizeImage;
4626 totalSize = bm.bmWidthBytes * effHeight;
4630 SYSTEM_INFO SystemInfo;
4634 GetSystemInfo( &SystemInfo );
4635 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
4636 mapSize = totalSize + (offset - mapOffset);
4637 mapBits = MapViewOfFile( section,
4638 FILE_MAP_ALL_ACCESS,
4642 bm.bmBits = (char *)mapBits + (offset - mapOffset);
4644 else if (ovr_pitch && offset)
4645 bm.bmBits = (LPVOID) offset;
4648 bm.bmBits = VirtualAlloc(NULL, totalSize,
4649 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
4652 /* Create Color Map */
4653 if (bm.bmBits && bm.bmBitsPixel <= 8) {
4654 colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? physDev : NULL,
4655 usage, bm.bmBitsPixel, bmi, &nColorMap );
4656 colorTable = X11DRV_DIB_BuildColorTable( physDev, usage, bm.bmBitsPixel, bmi );
4658 /* Allocate Memory for DIB and fill structure */
4660 dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
4663 dib->dibSection.dsBm = bm;
4664 dib->dibSection.dsBmih = *bi;
4665 dib->dibSection.dsBmih.biSizeImage = totalSize;
4667 /* Set dsBitfields values */
4668 if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
4670 dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
4672 else switch( bi->biBitCount )
4676 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
4677 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
4678 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
4683 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff0000;
4684 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x00ff00;
4685 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x0000ff;
4688 dib->dibSection.dshSection = section;
4689 dib->dibSection.dsOffset = offset;
4691 dib->status = DIB_Status_None;
4692 dib->nColorMap = nColorMap;
4693 dib->colorMap = colorMap;
4694 dib->colorTable = colorTable;
4697 /* Create Device Dependent Bitmap and add DIB pointer */
4700 int depth = (bi->biBitCount == 1) ? 1 : GetDeviceCaps(physDev->hdc, BITSPIXEL);
4701 res = CreateBitmap(bi->biWidth, effHeight, 1, depth, NULL);
4705 bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
4706 if (bmp) bmp->dib = (DIBSECTION *) dib;
4714 #ifdef HAVE_LIBXXSHM
4715 if (XShmQueryExtension(gdi_display) &&
4716 (dib->image = X11DRV_XShmCreateImage( bm.bmWidth, effHeight,
4717 bmp->bitmap.bmBitsPixel, &dib->shminfo )) )
4719 ; /* Created Image */
4721 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
4722 dib->shminfo.shmid = -1;
4725 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
4727 wine_tsx11_unlock();
4730 /* Clean up in case of errors */
4731 if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
4733 TRACE("got an error res=%p, bmp=%p, dib=%p, bm.bmBits=%p\n",
4734 res, bmp, dib, bm.bmBits);
4738 UnmapViewOfFile(mapBits), bm.bmBits = NULL;
4740 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
4743 if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
4744 if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
4745 if (colorTable) { HeapFree(GetProcessHeap(), 0, colorTable); colorTable = NULL; }
4746 if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
4747 if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
4748 if (res) { DeleteObject(res); res = 0; }
4752 extern BOOL VIRTUAL_SetFaultHandler(LPCVOID addr, BOOL (*proc)(LPVOID, LPCVOID), LPVOID arg);
4753 /* Install fault handler, if possible */
4754 InitializeCriticalSection(&(dib->lock));
4755 if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
4757 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
4758 if (dib) dib->status = DIB_Status_AppMod;
4762 /* Return BITMAP handle and storage location */
4763 if (bmp) GDI_ReleaseObj(res);
4764 if (bm.bmBits && bits) *bits = bm.bmBits;
4768 /***********************************************************************
4769 * X11DRV_DIB_DeleteDIBSection
4771 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
4773 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4778 #ifdef HAVE_LIBXXSHM
4779 if (dib->shminfo.shmid != -1)
4781 XShmDetach (gdi_display, &(dib->shminfo));
4782 XDestroyImage (dib->image);
4783 shmdt (dib->shminfo.shmaddr);
4784 dib->shminfo.shmid = -1;
4788 XDestroyImage( dib->image );
4789 wine_tsx11_unlock();
4793 HeapFree(GetProcessHeap(), 0, dib->colorMap);
4794 if (dib->colorTable)
4795 HeapFree(GetProcessHeap(), 0, dib->colorTable);
4797 DeleteCriticalSection(&(dib->lock));
4800 /***********************************************************************
4801 * SetDIBColorTable (X11DRV.@)
4803 UINT X11DRV_SetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, const RGBQUAD *colors )
4806 X11DRV_DIBSECTION *dib;
4808 HBITMAP hBitmap = GetCurrentObject( physDev->hdc, OBJ_BITMAP );
4810 if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC ))) return 0;
4811 dib = (X11DRV_DIBSECTION *) bmp->dib;
4813 if (dib && dib->colorMap && start < dib->nColorMap) {
4814 UINT end = count + start;
4815 if (end > dib->nColorMap) end = dib->nColorMap;
4817 * Changing color table might change the mapping between
4818 * DIB colors and X11 colors and thus alter the visible state
4819 * of the bitmap object.
4821 X11DRV_DIB_Lock(bmp, DIB_Status_AppMod, FALSE);
4822 memcpy(dib->colorTable + start, colors, (end - start) * sizeof(RGBQUAD));
4823 X11DRV_DIB_GenColorMap( physDev, dib->colorMap, DIB_RGB_COLORS,
4824 dib->dibSection.dsBm.bmBitsPixel,
4825 TRUE, colors, start, end );
4826 X11DRV_DIB_Unlock(bmp, TRUE);
4829 GDI_ReleaseObj( hBitmap );
4833 /***********************************************************************
4834 * GetDIBColorTable (X11DRV.@)
4836 UINT X11DRV_GetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, RGBQUAD *colors )
4839 X11DRV_DIBSECTION *dib;
4841 HBITMAP hBitmap = GetCurrentObject( physDev->hdc, OBJ_BITMAP );
4843 if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC ))) return 0;
4844 dib = (X11DRV_DIBSECTION *) bmp->dib;
4846 if (dib && dib->colorTable && start < dib->nColorMap) {
4847 if (start + count > dib->nColorMap) count = dib->nColorMap - start;
4848 memcpy(colors, dib->colorTable + start, count * sizeof(RGBQUAD));
4851 GDI_ReleaseObj( hBitmap );
4857 /***********************************************************************
4858 * X11DRV_DIB_CreateDIBFromBitmap
4860 * Allocates a packed DIB and copies the bitmap data into it.
4862 HGLOBAL X11DRV_DIB_CreateDIBFromBitmap(HDC hdc, HBITMAP hBmp)
4867 LPBITMAPINFOHEADER pbmiHeader;
4868 unsigned int cDataSize, cPackedSize, OffsetBits;
4871 if (!GetObjectW( hBmp, sizeof(bmp), &bmp )) return 0;
4874 * A packed DIB contains a BITMAPINFO structure followed immediately by
4875 * an optional color palette and the pixel data.
4878 /* Calculate the size of the packed DIB */
4879 cDataSize = X11DRV_DIB_GetDIBWidthBytes( bmp.bmWidth, bmp.bmBitsPixel ) * abs( bmp.bmHeight );
4880 cPackedSize = sizeof(BITMAPINFOHEADER)
4881 + ( (bmp.bmBitsPixel <= 8) ? (sizeof(RGBQUAD) * (1 << bmp.bmBitsPixel)) : 0 )
4883 /* Get the offset to the bits */
4884 OffsetBits = cPackedSize - cDataSize;
4886 /* Allocate the packed DIB */
4887 TRACE("\tAllocating packed DIB of size %d\n", cPackedSize);
4888 hPackedDIB = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE /*| GMEM_ZEROINIT*/,
4892 WARN("Could not allocate packed DIB!\n");
4896 /* A packed DIB starts with a BITMAPINFOHEADER */
4897 pPackedDIB = GlobalLock(hPackedDIB);
4898 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
4900 /* Init the BITMAPINFOHEADER */
4901 pbmiHeader->biSize = sizeof(BITMAPINFOHEADER);
4902 pbmiHeader->biWidth = bmp.bmWidth;
4903 pbmiHeader->biHeight = bmp.bmHeight;
4904 pbmiHeader->biPlanes = 1;
4905 pbmiHeader->biBitCount = bmp.bmBitsPixel;
4906 pbmiHeader->biCompression = BI_RGB;
4907 pbmiHeader->biSizeImage = 0;
4908 pbmiHeader->biXPelsPerMeter = pbmiHeader->biYPelsPerMeter = 0;
4909 pbmiHeader->biClrUsed = 0;
4910 pbmiHeader->biClrImportant = 0;
4912 /* Retrieve the DIB bits from the bitmap and fill in the
4913 * DIB color table if present */
4915 nLinesCopied = GetDIBits(hdc, /* Handle to device context */
4916 hBmp, /* Handle to bitmap */
4917 0, /* First scan line to set in dest bitmap */
4918 bmp.bmHeight, /* Number of scan lines to copy */
4919 pPackedDIB + OffsetBits, /* [out] Address of array for bitmap bits */
4920 (LPBITMAPINFO) pbmiHeader, /* [out] Address of BITMAPINFO structure */
4921 0); /* RGB or palette index */
4922 GlobalUnlock(hPackedDIB);
4924 /* Cleanup if GetDIBits failed */
4925 if (nLinesCopied != bmp.bmHeight)
4927 TRACE("\tGetDIBits returned %d. Actual lines=%d\n", nLinesCopied, bmp.bmHeight);
4928 GlobalFree(hPackedDIB);
4935 /**************************************************************************
4936 * X11DRV_DIB_CreateDIBFromPixmap
4938 * Allocates a packed DIB and copies the Pixmap data into it.
4939 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
4941 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
4944 BITMAPOBJ *pBmp = NULL;
4945 HGLOBAL hPackedDIB = 0;
4947 /* Allocates an HBITMAP which references the Pixmap passed to us */
4948 hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(hdc, pixmap);
4951 TRACE("\tCould not create bitmap header for Pixmap\n");
4956 * Create a packed DIB from the Pixmap wrapper bitmap created above.
4957 * A packed DIB contains a BITMAPINFO structure followed immediately by
4958 * an optional color palette and the pixel data.
4960 hPackedDIB = X11DRV_DIB_CreateDIBFromBitmap(hdc, hBmp);
4962 /* Get a pointer to the BITMAPOBJ structure */
4963 pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
4965 /* We can now get rid of the HBITMAP wrapper we created earlier.
4966 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
4970 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
4971 pBmp->physBitmap = NULL;
4974 GDI_ReleaseObj( hBmp );
4978 TRACE("\tReturning packed DIB %p\n", hPackedDIB);
4983 /**************************************************************************
4984 * X11DRV_DIB_CreatePixmapFromDIB
4986 * Creates a Pixmap from a packed DIB
4988 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
4990 Pixmap pixmap = None;
4992 BITMAPOBJ *pBmp = NULL;
4993 LPBYTE pPackedDIB = NULL;
4994 LPBITMAPINFO pbmi = NULL;
4995 LPBITMAPINFOHEADER pbmiHeader = NULL;
4996 LPBYTE pbits = NULL;
4998 /* Get a pointer to the packed DIB's data */
4999 pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
5000 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
5001 pbmi = (LPBITMAPINFO)pPackedDIB;
5002 pbits = (LPBYTE)(pPackedDIB
5003 + X11DRV_DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
5005 /* Create a DDB from the DIB */
5007 hBmp = CreateDIBitmap(hdc,
5014 GlobalUnlock(hPackedDIB);
5016 TRACE("CreateDIBitmap returned %p\n", hBmp);
5018 /* Retrieve the internal Pixmap from the DDB */
5020 pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5022 pixmap = (Pixmap)pBmp->physBitmap;
5023 /* clear the physBitmap so that we can steal its pixmap */
5024 pBmp->physBitmap = NULL;
5027 /* Delete the DDB we created earlier now that we have stolen its pixmap */
5028 GDI_ReleaseObj( hBmp );
5031 TRACE("\tReturning Pixmap %ld\n", pixmap);