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
26 #include <X11/extensions/XShm.h>
27 # ifdef HAVE_SYS_SHM_H
30 # ifdef HAVE_SYS_IPC_H
33 #endif /* defined(HAVE_LIBXXSHM) */
40 #include "wine/debug.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
46 WINE_DECLARE_DEBUG_CHANNEL(x11drv);
48 static int ximageDepthTable[32];
50 /* This structure holds the arguments for DIB_SetImageBits() */
53 X11DRV_PDEVICE *physDev;
56 PALETTEENTRY *palentry;
77 } X11DRV_DIB_IMAGEBITS_DESCR;
82 RLE_EOL = 0, /* End of line */
83 RLE_END = 1, /* End of bitmap */
84 RLE_DELTA = 2 /* Delta */
87 /***********************************************************************
88 * X11DRV_DIB_GetXImageWidthBytes
90 * Return the width of an X image in bytes
92 inline static int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
94 if (!depth || depth > 32) goto error;
96 if (!ximageDepthTable[depth-1])
98 XImage *testimage = XCreateImage( gdi_display, visual, depth,
99 ZPixmap, 0, NULL, 1, 1, 32, 20 );
102 ximageDepthTable[depth-1] = testimage->bits_per_pixel;
103 XDestroyImage( testimage );
105 else ximageDepthTable[depth-1] = -1;
107 if (ximageDepthTable[depth-1] != -1)
108 return (4 * ((width * ximageDepthTable[depth-1] + 31) / 32));
111 WARN( "(%d): Unsupported depth\n", depth );
116 /***********************************************************************
117 * X11DRV_DIB_CreateXImage
121 XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth )
127 width_bytes = X11DRV_DIB_GetXImageWidthBytes( width, depth );
128 image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0,
129 calloc( height, width_bytes ),
130 width, height, 32, width_bytes );
136 /***********************************************************************
139 * Get the info from a bitmap header.
140 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
142 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
143 int *height, WORD *bpp, WORD *compr )
145 if (header->biSize == sizeof(BITMAPCOREHEADER))
147 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
148 *width = core->bcWidth;
149 *height = core->bcHeight;
150 *bpp = core->bcBitCount;
154 if (header->biSize >= sizeof(BITMAPINFOHEADER))
156 *width = header->biWidth;
157 *height = header->biHeight;
158 *bpp = header->biBitCount;
159 *compr = header->biCompression;
162 ERR("(%ld): unknown/wrong size for header\n", header->biSize );
167 /***********************************************************************
168 * X11DRV_DIB_GenColorMap
170 * Fills the color map of a bitmap palette. Should not be called
171 * for a >8-bit deep bitmap.
173 int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
174 WORD coloruse, WORD depth, BOOL quads,
175 const void *colorPtr, int start, int end )
179 if (coloruse == DIB_RGB_COLORS)
181 int max = 1 << depth;
183 if (end > max) end = max;
187 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
189 if (depth == 1) /* Monochrome */
190 for (i = start; i < end; i++, rgb++)
191 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
192 rgb->rgbBlue > 255*3/2);
194 for (i = start; i < end; i++, rgb++)
195 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbRed,
201 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
203 if (depth == 1) /* Monochrome */
204 for (i = start; i < end; i++, rgb++)
205 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
206 rgb->rgbtBlue > 255*3/2);
208 for (i = start; i < end; i++, rgb++)
209 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbtRed,
214 else /* DIB_PAL_COLORS */
217 WORD * index = (WORD *)colorPtr;
219 for (i = start; i < end; i++, index++)
220 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(*index) );
222 for (i = start; i < end; i++)
223 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(i) );
230 /***********************************************************************
231 * X11DRV_DIB_BuildColorMap
233 * Build the color map from the bitmap palette. Should not be called
234 * for a >8-bit deep bitmap.
236 int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
237 const BITMAPINFO *info, int *nColors )
241 const void *colorPtr;
244 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
246 colors = info->bmiHeader.biClrUsed;
247 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
248 colorPtr = info->bmiColors;
250 else /* assume BITMAPCOREINFO */
252 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
253 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
258 ERR("called with >256 colors!\n");
262 /* just so CopyDIBSection doesn't have to create an identity palette */
263 if (coloruse == (WORD)-1) colorPtr = NULL;
265 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
266 colors * sizeof(int) )))
270 return X11DRV_DIB_GenColorMap( physDev, colorMapping, coloruse, depth,
271 isInfo, colorPtr, 0, colors);
275 /***********************************************************************
276 * X11DRV_DIB_MapColor
278 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
282 if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
285 for (color = 0; color < nPhysMap; color++)
286 if (physMap[color] == phys)
289 WARN("Strange color %08x\n", phys);
294 /*********************************************************************
295 * X11DRV_DIB_GetNearestIndex
297 * Helper for X11DRV_DIB_GetDIBits.
298 * Returns the nearest colour table index for a given RGB.
299 * Nearest is defined by minimizing the sum of the squares.
301 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
303 INT i, best = -1, diff, bestdiff = -1;
306 for(color = colormap, i = 0; i < numColors; color++, i++) {
307 diff = (r - color->rgbRed) * (r - color->rgbRed) +
308 (g - color->rgbGreen) * (g - color->rgbGreen) +
309 (b - color->rgbBlue) * (b - color->rgbBlue);
312 if(best == -1 || diff < bestdiff) {
319 /*********************************************************************
320 * X11DRV_DIB_MaskToShift
322 * Helper for X11DRV_DIB_GetDIBits.
323 * Returns the by how many bits to shift a given color so that it is
324 * in the proper position.
326 static INT X11DRV_DIB_MaskToShift(DWORD mask)
334 while ((mask&1)==0) {
341 /***********************************************************************
342 * X11DRV_DIB_Convert_any_asis
344 * All X11DRV_DIB_Convert_Xxx functions take at least the following
347 * This is the width in pixel of the surface to copy. This may be less
348 * than the full width of the image.
350 * The number of lines to copy. This may be less than the full height
351 * of the image. This is always >0.
353 * Points to the first byte containing data to be copied. If the source
354 * surface starts are coordinates (x,y) then this is:
355 * image_ptr+x*bytes_pre_pixel+y*bytes_per_line
356 * (with further adjustments for top-down/bottom-up images)
358 * This is the number of bytes per line. It may be >0 or <0 depending on
359 * whether this is a top-down or bottom-up image.
361 * Same as srcbits but for the destination
363 * Same as srclinebytes but for the destination.
366 * - The supported Dib formats are: pal1, pal4, pal8, rgb555, bgr555,
367 * rgb565, bgr565, rgb888 and any 32bit (0888) format.
368 * The supported XImage (Bmp) formats are: pal1, pal4, pal8,
369 * rgb555, bgr555, rgb565, bgr565, rgb888, bgr888, rgb0888, bgr0888.
370 * - Rgb formats are those for which the masks are such that:
371 * red_mask > green_mask > blue_mask
372 * - Bgr formats are those for which the masks sort in the other direction.
373 * - Many conversion functions handle both rgb->bgr and bgr->rgb conversions
374 * so the comments use h, g, l to mean respectively the source color in the
375 * high bits, the green, and the source color in the low bits.
377 static void X11DRV_DIB_Convert_any_asis(int width, int height,
379 const void* srcbits, int srclinebytes,
380 void* dstbits, int dstlinebytes)
384 width*=bytes_per_pixel;
385 for (y=0; y<height; y++) {
386 memcpy(dstbits, srcbits, width);
387 srcbits = (char*)srcbits + srclinebytes;
388 dstbits = (char*)dstbits + dstlinebytes;
396 static void X11DRV_DIB_Convert_555_reverse(int width, int height,
397 const void* srcbits, int srclinebytes,
398 void* dstbits, int dstlinebytes)
400 const DWORD* srcpixel;
404 for (y=0; y<height; y++) {
407 for (x=0; x<width/2; x++) {
408 /* Do 2 pixels at a time */
411 *dstpixel++=((srcval << 10) & 0x7c007c00) | /* h */
412 ( srcval & 0x03e003e0) | /* g */
413 ((srcval >> 10) & 0x001f001f); /* l */
416 /* And the the odd pixel */
418 srcval=*((WORD*)srcpixel);
419 *((WORD*)dstpixel)=((srcval << 10) & 0x7c00) | /* h */
420 ( srcval & 0x03e0) | /* g */
421 ((srcval >> 10) & 0x001f); /* l */
423 srcbits = (char*)srcbits + srclinebytes;
424 dstbits = (char*)dstbits + dstlinebytes;
428 static void X11DRV_DIB_Convert_555_to_565_asis(int width, int height,
429 const void* srcbits, int srclinebytes,
430 void* dstbits, int dstlinebytes)
432 const DWORD* srcpixel;
436 for (y=0; y<height; y++) {
439 for (x=0; x<width/2; x++) {
440 /* Do 2 pixels at a time */
443 *dstpixel++=((srcval << 1) & 0xffc0ffc0) | /* h, g */
444 ((srcval >> 4) & 0x00200020) | /* g - 1 bit */
445 ( srcval & 0x001f001f); /* l */
448 /* And the the odd pixel */
450 srcval=*((WORD*)srcpixel);
451 *((WORD*)dstpixel)=((srcval << 1) & 0xffc0) | /* h, g */
452 ((srcval >> 4) & 0x0020) | /* g - 1 bit */
453 (srcval & 0x001f); /* l */
455 srcbits = (char*)srcbits + srclinebytes;
456 dstbits = (char*)dstbits + dstlinebytes;
460 static void X11DRV_DIB_Convert_555_to_565_reverse(int width, int height,
461 const void* srcbits, int srclinebytes,
462 void* dstbits, int dstlinebytes)
464 const DWORD* srcpixel;
468 for (y=0; y<height; y++) {
471 for (x=0; x<width/2; x++) {
472 /* Do 2 pixels at a time */
475 *dstpixel++=((srcval >> 10) & 0x001f001f) | /* h */
476 ((srcval << 1) & 0x07c007c0) | /* g */
477 ((srcval >> 4) & 0x00200020) | /* g - 1 bit */
478 ((srcval << 11) & 0xf800f800); /* l */
481 /* And the the odd pixel */
483 srcval=*((WORD*)srcpixel);
484 *((WORD*)dstpixel)=((srcval >> 10) & 0x001f) | /* h */
485 ((srcval << 1) & 0x07c0) | /* g */
486 ((srcval >> 4) & 0x0020) | /* g - 1 bit */
487 ((srcval << 11) & 0xf800); /* l */
489 srcbits = (char*)srcbits + srclinebytes;
490 dstbits = (char*)dstbits + dstlinebytes;
494 static void X11DRV_DIB_Convert_555_to_888_asis(int width, int height,
495 const void* srcbits, int srclinebytes,
496 void* dstbits, int dstlinebytes)
498 const WORD* srcpixel;
502 for (y=0; y<height; y++) {
505 for (x=0; x<width; x++) {
508 dstpixel[0]=((srcval << 3) & 0xf8) | /* l */
509 ((srcval >> 2) & 0x07); /* l - 3 bits */
510 dstpixel[1]=((srcval >> 2) & 0xf8) | /* g */
511 ((srcval >> 7) & 0x07); /* g - 3 bits */
512 dstpixel[2]=((srcval >> 7) & 0xf8) | /* h */
513 ((srcval >> 12) & 0x07); /* h - 3 bits */
516 srcbits = (char*)srcbits + srclinebytes;
517 dstbits = (char*)dstbits + dstlinebytes;
521 static void X11DRV_DIB_Convert_555_to_888_reverse(int width, int height,
522 const void* srcbits, int srclinebytes,
523 void* dstbits, int dstlinebytes)
525 const WORD* srcpixel;
529 for (y=0; y<height; y++) {
532 for (x=0; x<width; x++) {
535 dstpixel[0]=((srcval >> 7) & 0xf8) | /* h */
536 ((srcval >> 12) & 0x07); /* h - 3 bits */
537 dstpixel[1]=((srcval >> 2) & 0xf8) | /* g */
538 ((srcval >> 7) & 0x07); /* g - 3 bits */
539 dstpixel[2]=((srcval << 3) & 0xf8) | /* l */
540 ((srcval >> 2) & 0x07); /* l - 3 bits */
543 srcbits = (char*)srcbits + srclinebytes;
544 dstbits = (char*)dstbits + dstlinebytes;
548 static void X11DRV_DIB_Convert_555_to_0888_asis(int width, int height,
549 const void* srcbits, int srclinebytes,
550 void* dstbits, int dstlinebytes)
552 const WORD* srcpixel;
556 for (y=0; y<height; y++) {
559 for (x=0; x<width; x++) {
562 *dstpixel++=((srcval << 9) & 0xf80000) | /* h */
563 ((srcval << 4) & 0x070000) | /* h - 3 bits */
564 ((srcval << 6) & 0x00f800) | /* g */
565 ((srcval << 1) & 0x000700) | /* g - 3 bits */
566 ((srcval << 3) & 0x0000f8) | /* l */
567 ((srcval >> 2) & 0x000007); /* l - 3 bits */
569 srcbits = (char*)srcbits + srclinebytes;
570 dstbits = (char*)dstbits + dstlinebytes;
574 static void X11DRV_DIB_Convert_555_to_0888_reverse(int width, int height,
575 const void* srcbits, int srclinebytes,
576 void* dstbits, int dstlinebytes)
578 const WORD* srcpixel;
582 for (y=0; y<height; y++) {
585 for (x=0; x<width; x++) {
588 *dstpixel++=((srcval >> 7) & 0x0000f8) | /* h */
589 ((srcval >> 12) & 0x000007) | /* h - 3 bits */
590 ((srcval << 6) & 0x00f800) | /* g */
591 ((srcval << 1) & 0x000700) | /* g - 3 bits */
592 ((srcval << 19) & 0xf80000) | /* l */
593 ((srcval << 14) & 0x070000); /* l - 3 bits */
595 srcbits = (char*)srcbits + srclinebytes;
596 dstbits = (char*)dstbits + dstlinebytes;
600 static void X11DRV_DIB_Convert_5x5_to_any0888(int width, int height,
601 const void* srcbits, int srclinebytes,
602 WORD rsrc, WORD gsrc, WORD bsrc,
603 void* dstbits, int dstlinebytes,
604 DWORD rdst, DWORD gdst, DWORD bdst)
606 int rRightShift1,gRightShift1,bRightShift1;
607 int rRightShift2,gRightShift2,bRightShift2;
609 int rLeftShift,gLeftShift,bLeftShift;
610 const WORD* srcpixel;
614 /* Note, the source pixel value is shifted left by 16 bits so that
615 * we know we will always have to shift right to extract the components.
617 rRightShift1=16+X11DRV_DIB_MaskToShift(rsrc)-3;
618 gRightShift1=16+X11DRV_DIB_MaskToShift(gsrc)-3;
619 bRightShift1=16+X11DRV_DIB_MaskToShift(bsrc)-3;
620 rRightShift2=rRightShift1+5;
621 gRightShift2=gRightShift1+5;
622 bRightShift2=bRightShift1+5;
624 /* Green has 5 bits, like the others */
628 /* Green has 6 bits, not 5. Compensate. */
635 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
636 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
637 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
639 for (y=0; y<height; y++) {
642 for (x=0; x<width; x++) {
645 srcval=*srcpixel++ << 16;
646 red= ((srcval >> rRightShift1) & 0xf8) |
647 ((srcval >> rRightShift2) & 0x07);
648 green=((srcval >> gRightShift1) & gMask1) |
649 ((srcval >> gRightShift2) & gMask2);
650 blue= ((srcval >> bRightShift1) & 0xf8) |
651 ((srcval >> bRightShift2) & 0x07);
652 *dstpixel++=(red << rLeftShift) |
653 (green << gLeftShift) |
654 (blue << bLeftShift);
656 srcbits = (char*)srcbits + srclinebytes;
657 dstbits = (char*)dstbits + dstlinebytes;
662 * 16 bits conversions
665 static void X11DRV_DIB_Convert_565_reverse(int width, int height,
666 const void* srcbits, int srclinebytes,
667 void* dstbits, int dstlinebytes)
669 const DWORD* srcpixel;
673 for (y=0; y<height; y++) {
676 for (x=0; x<width/2; x++) {
677 /* Do 2 pixels at a time */
680 *dstpixel++=((srcval << 11) & 0xf800f800) | /* h */
681 ( srcval & 0x07e007e0) | /* g */
682 ((srcval >> 11) & 0x001f001f); /* l */
685 /* And the the odd pixel */
687 srcval=*((WORD*)srcpixel);
688 *((WORD*)dstpixel)=((srcval << 11) & 0xf800) | /* h */
689 ( srcval & 0x07e0) | /* g */
690 ((srcval >> 11) & 0x001f); /* l */
692 srcbits = (char*)srcbits + srclinebytes;
693 dstbits = (char*)dstbits + dstlinebytes;
697 static void X11DRV_DIB_Convert_565_to_555_asis(int width, int height,
698 const void* srcbits, int srclinebytes,
699 void* dstbits, int dstlinebytes)
701 const DWORD* srcpixel;
705 for (y=0; y<height; y++) {
708 for (x=0; x<width/2; x++) {
709 /* Do 2 pixels at a time */
712 *dstpixel++=((srcval >> 1) & 0x7fe07fe0) | /* h, g */
713 ( srcval & 0x001f001f); /* l */
716 /* And the the odd pixel */
718 srcval=*((WORD*)srcpixel);
719 *((WORD*)dstpixel)=((srcval >> 1) & 0x7fe0) | /* h, g */
720 ( srcval & 0x001f); /* l */
722 srcbits = (char*)srcbits + srclinebytes;
723 dstbits = (char*)dstbits + dstlinebytes;
727 static void X11DRV_DIB_Convert_565_to_555_reverse(int width, int height,
728 const void* srcbits, int srclinebytes,
729 void* dstbits, int dstlinebytes)
731 const DWORD* srcpixel;
735 for (y=0; y<height; y++) {
738 for (x=0; x<width/2; x++) {
739 /* Do 2 pixels at a time */
742 *dstpixel++=((srcval >> 11) & 0x001f001f) | /* h */
743 ((srcval >> 1) & 0x03e003e0) | /* g */
744 ((srcval << 10) & 0x7c007c00); /* l */
747 /* And the the odd pixel */
749 srcval=*((WORD*)srcpixel);
750 *((WORD*)dstpixel)=((srcval >> 11) & 0x001f) | /* h */
751 ((srcval >> 1) & 0x03e0) | /* g */
752 ((srcval << 10) & 0x7c00); /* l */
754 srcbits = (char*)srcbits + srclinebytes;
755 dstbits = (char*)dstbits + dstlinebytes;
759 static void X11DRV_DIB_Convert_565_to_888_asis(int width, int height,
760 const void* srcbits, int srclinebytes,
761 void* dstbits, int dstlinebytes)
763 const WORD* srcpixel;
767 for (y=0; y<height; y++) {
770 for (x=0; x<width; x++) {
773 dstpixel[0]=((srcval << 3) & 0xf8) | /* l */
774 ((srcval >> 2) & 0x07); /* l - 3 bits */
775 dstpixel[1]=((srcval >> 3) & 0xfc) | /* g */
776 ((srcval >> 9) & 0x03); /* g - 2 bits */
777 dstpixel[2]=((srcval >> 8) & 0xf8) | /* h */
778 ((srcval >> 13) & 0x07); /* h - 3 bits */
781 srcbits = (char*)srcbits + srclinebytes;
782 dstbits = (char*)dstbits + dstlinebytes;
786 static void X11DRV_DIB_Convert_565_to_888_reverse(int width, int height,
787 const void* srcbits, int srclinebytes,
788 void* dstbits, int dstlinebytes)
790 const WORD* srcpixel;
794 for (y=0; y<height; y++) {
797 for (x=0; x<width; x++) {
800 dstpixel[0]=((srcval >> 8) & 0xf8) | /* h */
801 ((srcval >> 13) & 0x07); /* h - 3 bits */
802 dstpixel[1]=((srcval >> 3) & 0xfc) | /* g */
803 ((srcval >> 9) & 0x03); /* g - 2 bits */
804 dstpixel[2]=((srcval << 3) & 0xf8) | /* l */
805 ((srcval >> 2) & 0x07); /* l - 3 bits */
808 srcbits = (char*)srcbits + srclinebytes;
809 dstbits = (char*)dstbits + dstlinebytes;
813 static void X11DRV_DIB_Convert_565_to_0888_asis(int width, int height,
814 const void* srcbits, int srclinebytes,
815 void* dstbits, int dstlinebytes)
817 const WORD* srcpixel;
821 for (y=0; y<height; y++) {
824 for (x=0; x<width; x++) {
827 *dstpixel++=((srcval << 8) & 0xf80000) | /* h */
828 ((srcval << 3) & 0x070000) | /* h - 3 bits */
829 ((srcval << 5) & 0x00fc00) | /* g */
830 ((srcval >> 1) & 0x000300) | /* g - 2 bits */
831 ((srcval << 3) & 0x0000f8) | /* l */
832 ((srcval >> 2) & 0x000007); /* l - 3 bits */
834 srcbits = (char*)srcbits + srclinebytes;
835 dstbits = (char*)dstbits + dstlinebytes;
839 static void X11DRV_DIB_Convert_565_to_0888_reverse(int width, int height,
840 const void* srcbits, int srclinebytes,
841 void* dstbits, int dstlinebytes)
843 const WORD* srcpixel;
847 for (y=0; y<height; y++) {
850 for (x=0; x<width; x++) {
853 *dstpixel++=((srcval >> 8) & 0x0000f8) | /* h */
854 ((srcval >> 13) & 0x000007) | /* h - 3 bits */
855 ((srcval << 5) & 0x00fc00) | /* g */
856 ((srcval >> 1) & 0x000300) | /* g - 2 bits */
857 ((srcval << 19) & 0xf80000) | /* l */
858 ((srcval << 14) & 0x070000); /* l - 3 bits */
860 srcbits = (char*)srcbits + srclinebytes;
861 dstbits = (char*)dstbits + dstlinebytes;
869 static void X11DRV_DIB_Convert_888_reverse(int width, int height,
870 const void* srcbits, int srclinebytes,
871 void* dstbits, int dstlinebytes)
873 const BYTE* srcpixel;
877 for (y=0; y<height; y++) {
880 for (x=0; x<width; x++) {
881 dstpixel[0]=srcpixel[2];
882 dstpixel[1]=srcpixel[1];
883 dstpixel[2]=srcpixel[0];
887 srcbits = (char*)srcbits + srclinebytes;
888 dstbits = (char*)dstbits + dstlinebytes;
892 static void X11DRV_DIB_Convert_888_to_555_asis(int width, int height,
893 const void* srcbits, int srclinebytes,
894 void* dstbits, int dstlinebytes)
896 const DWORD* srcpixel;
904 for (y=0; y<height; y++) {
907 for (x=0; x<width; x++) {
908 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
909 DWORD srcval1,srcval2;
911 dstpixel[0]=((srcval1 >> 3) & 0x001f) | /* l1 */
912 ((srcval1 >> 6) & 0x03e0) | /* g1 */
913 ((srcval1 >> 9) & 0x7c00); /* h1 */
915 dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */
916 ((srcval2 << 2) & 0x03e0) | /* g2 */
917 ((srcval2 >> 1) & 0x7c00); /* h2 */
919 dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */
920 ((srcval2 >> 22) & 0x03e0) | /* g3 */
921 ((srcval1 << 7) & 0x7c00); /* h3 */
922 dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */
923 ((srcval1 >> 14) & 0x03e0) | /* g4 */
924 ((srcval1 >> 17) & 0x7c00); /* h4 */
928 /* And now up to 3 odd pixels */
929 srcbyte=(LPBYTE)srcpixel;
930 for (x=0; x<oddwidth; x++) {
932 dstval =((srcbyte[0] >> 3) & 0x001f); /* l */
933 dstval|=((srcbyte[1] << 2) & 0x03e0); /* g */
934 dstval|=((srcbyte[2] << 7) & 0x7c00); /* h */
938 srcbits = (char*)srcbits + srclinebytes;
939 dstbits = (char*)dstbits + dstlinebytes;
943 static void X11DRV_DIB_Convert_888_to_555_reverse(int width, int height,
944 const void* srcbits, int srclinebytes,
945 void* dstbits, int dstlinebytes)
947 const DWORD* srcpixel;
955 for (y=0; y<height; y++) {
958 for (x=0; x<width; x++) {
959 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
960 DWORD srcval1,srcval2;
962 dstpixel[0]=((srcval1 << 7) & 0x7c00) | /* l1 */
963 ((srcval1 >> 6) & 0x03e0) | /* g1 */
964 ((srcval1 >> 19) & 0x001f); /* h1 */
966 dstpixel[1]=((srcval1 >> 17) & 0x7c00) | /* l2 */
967 ((srcval2 << 2) & 0x03e0) | /* g2 */
968 ((srcval2 >> 11) & 0x001f); /* h2 */
970 dstpixel[2]=((srcval2 >> 9) & 0x7c00) | /* l3 */
971 ((srcval2 >> 22) & 0x03e0) | /* g3 */
972 ((srcval1 >> 3) & 0x001f); /* h3 */
973 dstpixel[3]=((srcval1 >> 1) & 0x7c00) | /* l4 */
974 ((srcval1 >> 14) & 0x03e0) | /* g4 */
975 ((srcval1 >> 27) & 0x001f); /* h4 */
979 /* And now up to 3 odd pixels */
980 srcbyte=(LPBYTE)srcpixel;
981 for (x=0; x<oddwidth; x++) {
983 dstval =((srcbyte[0] << 7) & 0x7c00); /* l */
984 dstval|=((srcbyte[1] << 2) & 0x03e0); /* g */
985 dstval|=((srcbyte[2] >> 3) & 0x001f); /* h */
989 srcbits = (char*)srcbits + srclinebytes;
990 dstbits = (char*)dstbits + dstlinebytes;
994 static void X11DRV_DIB_Convert_888_to_565_asis(int width, int height,
995 const void* srcbits, int srclinebytes,
996 void* dstbits, int dstlinebytes)
998 const DWORD* srcpixel;
1006 for (y=0; y<height; y++) {
1009 for (x=0; x<width; x++) {
1010 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
1011 DWORD srcval1,srcval2;
1012 srcval1=srcpixel[0];
1013 dstpixel[0]=((srcval1 >> 3) & 0x001f) | /* l1 */
1014 ((srcval1 >> 5) & 0x07e0) | /* g1 */
1015 ((srcval1 >> 8) & 0xf800); /* h1 */
1016 srcval2=srcpixel[1];
1017 dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */
1018 ((srcval2 << 3) & 0x07e0) | /* g2 */
1019 ( srcval2 & 0xf800); /* h2 */
1020 srcval1=srcpixel[2];
1021 dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */
1022 ((srcval2 >> 21) & 0x07e0) | /* g3 */
1023 ((srcval1 << 8) & 0xf800); /* h3 */
1024 dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */
1025 ((srcval1 >> 13) & 0x07e0) | /* g4 */
1026 ((srcval1 >> 16) & 0xf800); /* h4 */
1030 /* And now up to 3 odd pixels */
1031 srcbyte=(LPBYTE)srcpixel;
1032 for (x=0; x<oddwidth; x++) {
1034 dstval =((srcbyte[0] >> 3) & 0x001f); /* l */
1035 dstval|=((srcbyte[1] << 3) & 0x07e0); /* g */
1036 dstval|=((srcbyte[2] << 8) & 0xf800); /* h */
1040 srcbits = (char*)srcbits + srclinebytes;
1041 dstbits = (char*)dstbits + dstlinebytes;
1045 static void X11DRV_DIB_Convert_888_to_565_reverse(int width, int height,
1046 const void* srcbits, int srclinebytes,
1047 void* dstbits, int dstlinebytes)
1049 const DWORD* srcpixel;
1050 const BYTE* srcbyte;
1057 for (y=0; y<height; y++) {
1060 for (x=0; x<width; x++) {
1061 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
1062 DWORD srcval1,srcval2;
1063 srcval1=srcpixel[0];
1064 dstpixel[0]=((srcval1 << 8) & 0xf800) | /* l1 */
1065 ((srcval1 >> 5) & 0x07e0) | /* g1 */
1066 ((srcval1 >> 19) & 0x001f); /* h1 */
1067 srcval2=srcpixel[1];
1068 dstpixel[1]=((srcval1 >> 16) & 0xf800) | /* l2 */
1069 ((srcval2 << 3) & 0x07e0) | /* g2 */
1070 ((srcval2 >> 11) & 0x001f); /* h2 */
1071 srcval1=srcpixel[2];
1072 dstpixel[2]=((srcval2 >> 8) & 0xf800) | /* l3 */
1073 ((srcval2 >> 21) & 0x07e0) | /* g3 */
1074 ((srcval1 >> 3) & 0x001f); /* h3 */
1075 dstpixel[3]=(srcval1 & 0xf800) | /* l4 */
1076 ((srcval1 >> 13) & 0x07e0) | /* g4 */
1077 ((srcval1 >> 27) & 0x001f); /* h4 */
1081 /* And now up to 3 odd pixels */
1082 srcbyte=(LPBYTE)srcpixel;
1083 for (x=0; x<oddwidth; x++) {
1085 dstval =((srcbyte[0] << 8) & 0xf800); /* l */
1086 dstval|=((srcbyte[1] << 3) & 0x07e0); /* g */
1087 dstval|=((srcbyte[2] >> 3) & 0x001f); /* h */
1091 srcbits = (char*)srcbits + srclinebytes;
1092 dstbits = (char*)dstbits + dstlinebytes;
1096 static void X11DRV_DIB_Convert_888_to_0888_asis(int width, int height,
1097 const void* srcbits, int srclinebytes,
1098 void* dstbits, int dstlinebytes)
1100 const DWORD* srcpixel;
1107 for (y=0; y<height; y++) {
1110 for (x=0; x<width; x++) {
1111 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1112 DWORD srcval1,srcval2;
1113 srcval1=srcpixel[0];
1114 dstpixel[0]=( srcval1 & 0x00ffffff); /* h1, g1, l1 */
1115 srcval2=srcpixel[1];
1116 dstpixel[1]=( srcval1 >> 24) | /* l2 */
1117 ((srcval2 << 8) & 0x00ffff00); /* h2, g2 */
1118 srcval1=srcpixel[2];
1119 dstpixel[2]=( srcval2 >> 16) | /* g3, l3 */
1120 ((srcval1 << 16) & 0x00ff0000); /* h3 */
1121 dstpixel[3]=( srcval1 >> 8); /* h4, g4, l4 */
1125 /* And now up to 3 odd pixels */
1126 for (x=0; x<oddwidth; x++) {
1129 srcpixel=(LPDWORD)(((char*)srcpixel)+3);
1130 *dstpixel++=( srcval & 0x00ffffff); /* h, g, l */
1132 srcbits = (char*)srcbits + srclinebytes;
1133 dstbits = (char*)dstbits + dstlinebytes;
1137 static void X11DRV_DIB_Convert_888_to_0888_reverse(int width, int height,
1138 const void* srcbits, int srclinebytes,
1139 void* dstbits, int dstlinebytes)
1141 const DWORD* srcpixel;
1148 for (y=0; y<height; y++) {
1151 for (x=0; x<width; x++) {
1152 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1153 DWORD srcval1,srcval2;
1155 srcval1=srcpixel[0];
1156 dstpixel[0]=((srcval1 >> 16) & 0x0000ff) | /* h1 */
1157 ( srcval1 & 0x00ff00) | /* g1 */
1158 ((srcval1 << 16) & 0xff0000); /* l1 */
1159 srcval2=srcpixel[1];
1160 dstpixel[1]=((srcval1 >> 8) & 0xff0000) | /* l2 */
1161 ((srcval2 << 8) & 0x00ff00) | /* g2 */
1162 ((srcval2 >> 8) & 0x0000ff); /* h2 */
1163 srcval1=srcpixel[2];
1164 dstpixel[2]=( srcval2 & 0xff0000) | /* l3 */
1165 ((srcval2 >> 16) & 0x00ff00) | /* g3 */
1166 ( srcval1 & 0x0000ff); /* h3 */
1167 dstpixel[3]=((srcval1 >> 24) & 0x0000ff) | /* h4 */
1168 ((srcval1 >> 8) & 0x00ff00) | /* g4 */
1169 ((srcval1 << 8) & 0xff0000); /* l4 */
1173 /* And now up to 3 odd pixels */
1174 for (x=0; x<oddwidth; x++) {
1177 srcpixel=(LPDWORD)(((char*)srcpixel)+3);
1178 *dstpixel++=((srcval >> 16) & 0x0000ff) | /* h */
1179 ( srcval & 0x00ff00) | /* g */
1180 ((srcval << 16) & 0xff0000); /* l */
1182 srcbits = (char*)srcbits + srclinebytes;
1183 dstbits = (char*)dstbits + dstlinebytes;
1187 static void X11DRV_DIB_Convert_rgb888_to_any0888(int width, int height,
1188 const void* srcbits, int srclinebytes,
1189 void* dstbits, int dstlinebytes,
1190 DWORD rdst, DWORD gdst, DWORD bdst)
1192 int rLeftShift,gLeftShift,bLeftShift;
1193 const BYTE* srcpixel;
1197 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1198 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1199 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1200 for (y=0; y<height; y++) {
1203 for (x=0; x<width; x++) {
1204 *dstpixel++=(srcpixel[0] << bLeftShift) | /* b */
1205 (srcpixel[1] << gLeftShift) | /* g */
1206 (srcpixel[2] << rLeftShift); /* r */
1209 srcbits = (char*)srcbits + srclinebytes;
1210 dstbits = (char*)dstbits + dstlinebytes;
1214 static void X11DRV_DIB_Convert_bgr888_to_any0888(int width, int height,
1215 const void* srcbits, int srclinebytes,
1216 void* dstbits, int dstlinebytes,
1217 DWORD rdst, DWORD gdst, DWORD bdst)
1219 int rLeftShift,gLeftShift,bLeftShift;
1220 const BYTE* srcpixel;
1224 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1225 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1226 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1227 for (y=0; y<height; y++) {
1230 for (x=0; x<width; x++) {
1231 *dstpixel++=(srcpixel[0] << rLeftShift) | /* r */
1232 (srcpixel[1] << gLeftShift) | /* g */
1233 (srcpixel[2] << bLeftShift); /* b */
1236 srcbits = (char*)srcbits + srclinebytes;
1237 dstbits = (char*)dstbits + dstlinebytes;
1242 * 32 bit conversions
1245 static void X11DRV_DIB_Convert_0888_reverse(int width, int height,
1246 const void* srcbits, int srclinebytes,
1247 void* dstbits, int dstlinebytes)
1249 const DWORD* srcpixel;
1253 for (y=0; y<height; y++) {
1256 for (x=0; x<width; x++) {
1259 *dstpixel++=((srcval << 16) & 0x00ff0000) | /* h */
1260 ( srcval & 0x0000ff00) | /* g */
1261 ((srcval >> 16) & 0x000000ff); /* l */
1263 srcbits = (char*)srcbits + srclinebytes;
1264 dstbits = (char*)dstbits + dstlinebytes;
1268 static void X11DRV_DIB_Convert_0888_any(int width, int height,
1269 const void* srcbits, int srclinebytes,
1270 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1271 void* dstbits, int dstlinebytes,
1272 DWORD rdst, DWORD gdst, DWORD bdst)
1274 int rRightShift,gRightShift,bRightShift;
1275 int rLeftShift,gLeftShift,bLeftShift;
1276 const DWORD* srcpixel;
1280 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1281 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1282 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1283 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1284 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1285 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1286 for (y=0; y<height; y++) {
1289 for (x=0; x<width; x++) {
1292 *dstpixel++=(((srcval >> rRightShift) & 0xff) << rLeftShift) |
1293 (((srcval >> gRightShift) & 0xff) << gLeftShift) |
1294 (((srcval >> bRightShift) & 0xff) << bLeftShift);
1296 srcbits = (char*)srcbits + srclinebytes;
1297 dstbits = (char*)dstbits + dstlinebytes;
1301 static void X11DRV_DIB_Convert_0888_to_555_asis(int width, int height,
1302 const void* srcbits, int srclinebytes,
1303 void* dstbits, int dstlinebytes)
1305 const DWORD* srcpixel;
1309 for (y=0; y<height; y++) {
1312 for (x=0; x<width; x++) {
1315 *dstpixel++=((srcval >> 9) & 0x7c00) | /* h */
1316 ((srcval >> 6) & 0x03e0) | /* g */
1317 ((srcval >> 3) & 0x001f); /* l */
1319 srcbits = (char*)srcbits + srclinebytes;
1320 dstbits = (char*)dstbits + dstlinebytes;
1324 static void X11DRV_DIB_Convert_0888_to_555_reverse(int width, int height,
1325 const void* srcbits, int srclinebytes,
1326 void* dstbits, int dstlinebytes)
1328 const DWORD* srcpixel;
1332 for (y=0; y<height; y++) {
1335 for (x=0; x<width; x++) {
1338 *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1339 ((srcval >> 6) & 0x03e0) | /* g */
1340 ((srcval << 7) & 0x7c00); /* l */
1342 srcbits = (char*)srcbits + srclinebytes;
1343 dstbits = (char*)dstbits + dstlinebytes;
1347 static void X11DRV_DIB_Convert_0888_to_565_asis(int width, int height,
1348 const void* srcbits, int srclinebytes,
1349 void* dstbits, int dstlinebytes)
1351 const DWORD* srcpixel;
1355 for (y=0; y<height; y++) {
1358 for (x=0; x<width; x++) {
1361 *dstpixel++=((srcval >> 8) & 0xf800) | /* h */
1362 ((srcval >> 5) & 0x07e0) | /* g */
1363 ((srcval >> 3) & 0x001f); /* l */
1365 srcbits = (char*)srcbits + srclinebytes;
1366 dstbits = (char*)dstbits + dstlinebytes;
1370 static void X11DRV_DIB_Convert_0888_to_565_reverse(int width, int height,
1371 const void* srcbits, int srclinebytes,
1372 void* dstbits, int dstlinebytes)
1374 const DWORD* srcpixel;
1378 for (y=0; y<height; y++) {
1381 for (x=0; x<width; x++) {
1384 *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1385 ((srcval >> 5) & 0x07e0) | /* g */
1386 ((srcval << 8) & 0xf800); /* l */
1388 srcbits = (char*)srcbits + srclinebytes;
1389 dstbits = (char*)dstbits + dstlinebytes;
1393 static void X11DRV_DIB_Convert_any0888_to_5x5(int width, int height,
1394 const void* srcbits, int srclinebytes,
1395 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1396 void* dstbits, int dstlinebytes,
1397 WORD rdst, WORD gdst, WORD bdst)
1399 int rRightShift,gRightShift,bRightShift;
1400 int rLeftShift,gLeftShift,bLeftShift;
1401 const DWORD* srcpixel;
1405 /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel
1406 * contains 0x11223344.
1407 * - first we shift 0x11223344 right by rRightShift to bring the most
1408 * significant bits of the red components in the bottom 5 (or 6) bits
1410 * - then we remove non red bits by anding with the modified rdst (0x1f)
1412 * - finally shift these bits left by rLeftShift so that they end up in
1416 rRightShift=X11DRV_DIB_MaskToShift(rsrc)+3;
1417 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1418 gRightShift+=(gdst==0x07e0?2:3);
1419 bRightShift=X11DRV_DIB_MaskToShift(bsrc)+3;
1421 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1422 rdst=rdst >> rLeftShift;
1423 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1424 gdst=gdst >> gLeftShift;
1425 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1426 bdst=bdst >> bLeftShift;
1428 for (y=0; y<height; y++) {
1431 for (x=0; x<width; x++) {
1434 *dstpixel++=(((srcval >> rRightShift) & rdst) << rLeftShift) |
1435 (((srcval >> gRightShift) & gdst) << gLeftShift) |
1436 (((srcval >> bRightShift) & bdst) << bLeftShift);
1438 srcbits = (char*)srcbits + srclinebytes;
1439 dstbits = (char*)dstbits + dstlinebytes;
1443 static void X11DRV_DIB_Convert_0888_to_888_asis(int width, int height,
1444 const void* srcbits, int srclinebytes,
1445 void* dstbits, int dstlinebytes)
1447 const DWORD* srcpixel;
1455 for (y=0; y<height; y++) {
1458 for (x=0; x<width; x++) {
1459 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1461 srcval=((*srcpixel++) & 0x00ffffff); /* h1, g1, l1*/
1462 *dstpixel++=srcval | ((*srcpixel) << 24); /* h2 */
1463 srcval=((*srcpixel++ >> 8 ) & 0x0000ffff); /* g2, l2 */
1464 *dstpixel++=srcval | ((*srcpixel) << 16); /* h3, g3 */
1465 srcval=((*srcpixel++ >> 16) & 0x000000ff); /* l3 */
1466 *dstpixel++=srcval | ((*srcpixel++) << 8); /* h4, g4, l4 */
1468 /* And now up to 3 odd pixels */
1469 dstbyte=(BYTE*)dstpixel;
1470 for (x=0; x<oddwidth; x++) {
1473 *((WORD*)dstbyte)++=srcval; /* h, g */
1474 *dstbyte++=srcval >> 16; /* l */
1476 srcbits = (char*)srcbits + srclinebytes;
1477 dstbits = (char*)dstbits + dstlinebytes;
1481 static void X11DRV_DIB_Convert_0888_to_888_reverse(int width, int height,
1482 const void* srcbits, int srclinebytes,
1483 void* dstbits, int dstlinebytes)
1485 const DWORD* srcpixel;
1493 for (y=0; y<height; y++) {
1496 for (x=0; x<width; x++) {
1497 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1498 DWORD srcval1,srcval2;
1499 srcval1=*srcpixel++;
1500 srcval2= ((srcval1 >> 16) & 0x000000ff) | /* h1 */
1501 ( srcval1 & 0x0000ff00) | /* g1 */
1502 ((srcval1 << 16) & 0x00ff0000); /* l1 */
1503 srcval1=*srcpixel++;
1504 *dstpixel++=srcval2 |
1505 ((srcval1 << 8) & 0xff000000); /* h2 */
1506 srcval2= ((srcval1 >> 8) & 0x000000ff) | /* g2 */
1507 ((srcval1 << 8) & 0x0000ff00); /* l2 */
1508 srcval1=*srcpixel++;
1509 *dstpixel++=srcval2 |
1510 ( srcval1 & 0x00ff0000) | /* h3 */
1511 ((srcval1 << 16) & 0xff000000); /* g3 */
1512 srcval2= ( srcval1 & 0x000000ff); /* l3 */
1513 srcval1=*srcpixel++;
1514 *dstpixel++=srcval2 |
1515 ((srcval1 >> 8) & 0x0000ff00) | /* h4 */
1516 ((srcval1 << 8) & 0x00ff0000) | /* g4 */
1517 ( srcval1 << 24); /* l4 */
1519 /* And now up to 3 odd pixels */
1520 dstbyte=(BYTE*)dstpixel;
1521 for (x=0; x<oddwidth; x++) {
1524 *((WORD*)dstbyte)++=((srcval >> 16) & 0x00ff) | /* h */
1525 (srcval & 0xff00); /* g */
1526 *dstbyte++=srcval; /* l */
1528 srcbits = (char*)srcbits + srclinebytes;
1529 dstbits = (char*)dstbits + dstlinebytes;
1533 static void X11DRV_DIB_Convert_any0888_to_rgb888(int width, int height,
1534 const void* srcbits, int srclinebytes,
1535 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1536 void* dstbits, int dstlinebytes)
1538 int rRightShift,gRightShift,bRightShift;
1539 const DWORD* srcpixel;
1543 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1544 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1545 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1546 for (y=0; y<height; y++) {
1549 for (x=0; x<width; x++) {
1552 dstpixel[0]=(srcval >> bRightShift); /* b */
1553 dstpixel[1]=(srcval >> gRightShift); /* g */
1554 dstpixel[2]=(srcval >> rRightShift); /* r */
1557 srcbits = (char*)srcbits + srclinebytes;
1558 dstbits = (char*)dstbits + dstlinebytes;
1562 static void X11DRV_DIB_Convert_any0888_to_bgr888(int width, int height,
1563 const void* srcbits, int srclinebytes,
1564 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1565 void* dstbits, int dstlinebytes)
1567 int rRightShift,gRightShift,bRightShift;
1568 const DWORD* srcpixel;
1572 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1573 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1574 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1575 for (y=0; y<height; y++) {
1578 for (x=0; x<width; x++) {
1581 dstpixel[0]=(srcval >> rRightShift); /* r */
1582 dstpixel[1]=(srcval >> gRightShift); /* g */
1583 dstpixel[2]=(srcval >> bRightShift); /* b */
1586 srcbits = (char*)srcbits + srclinebytes;
1587 dstbits = (char*)dstbits + dstlinebytes;
1591 /***********************************************************************
1592 * X11DRV_DIB_SetImageBits_1
1594 * SetDIBits for a 1-bit deep DIB.
1596 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
1597 DWORD srcwidth, DWORD dstwidth, int left,
1598 int *colors, XImage *bmpImage, DWORD linebytes)
1601 const BYTE* srcbyte;
1607 srcbits = srcbits + linebytes * (lines - 1);
1608 linebytes = -linebytes;
1611 if ((extra = (left & 7)) != 0) {
1615 srcbits += left >> 3;
1617 /* ==== pal 1 dib -> any bmp format ==== */
1618 for (h = lines-1; h >=0; h--) {
1620 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
1621 for (i = dstwidth/8, x = left; i > 0; i--) {
1623 XPutPixel( bmpImage, x++, h, colors[ srcval >> 7] );
1624 XPutPixel( bmpImage, x++, h, colors[(srcval >> 6) & 1] );
1625 XPutPixel( bmpImage, x++, h, colors[(srcval >> 5) & 1] );
1626 XPutPixel( bmpImage, x++, h, colors[(srcval >> 4) & 1] );
1627 XPutPixel( bmpImage, x++, h, colors[(srcval >> 3) & 1] );
1628 XPutPixel( bmpImage, x++, h, colors[(srcval >> 2) & 1] );
1629 XPutPixel( bmpImage, x++, h, colors[(srcval >> 1) & 1] );
1630 XPutPixel( bmpImage, x++, h, colors[ srcval & 1] );
1633 switch (dstwidth & 7)
1635 case 7: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1636 case 6: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1637 case 5: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1638 case 4: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1639 case 3: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1640 case 2: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1641 case 1: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]);
1643 srcbits += linebytes;
1647 /***********************************************************************
1648 * X11DRV_DIB_GetImageBits_1
1650 * GetDIBits for a 1-bit deep DIB.
1652 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
1653 DWORD dstwidth, DWORD srcwidth,
1654 RGBQUAD *colors, PALETTEENTRY *srccolors,
1655 XImage *bmpImage, DWORD linebytes )
1662 dstbits = dstbits + linebytes * (lines - 1);
1663 linebytes = -linebytes;
1666 switch (bmpImage->depth)
1670 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1671 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
1674 for (h=lines-1; h>=0; h--) {
1678 for (x=0; x<dstwidth; x++) {
1679 PALETTEENTRY srcval;
1680 srcval=srccolors[XGetPixel(bmpImage, x, h)];
1681 dstval|=(X11DRV_DIB_GetNearestIndex
1685 srcval.peBlue) << (7 - (x & 7)));
1691 if ((dstwidth&7)!=0) {
1694 dstbits += linebytes;
1702 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1703 /* ==== pal 8 bmp -> pal 1 dib ==== */
1704 const void* srcbits;
1705 const BYTE* srcpixel;
1708 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1710 for (h=0; h<lines; h++) {
1715 for (x=0; x<dstwidth; x++) {
1716 PALETTEENTRY srcval;
1717 srcval=srccolors[(int)*srcpixel++];
1718 dstval|=(X11DRV_DIB_GetNearestIndex
1722 srcval.peBlue) << (7-(x&7)) );
1728 if ((dstwidth&7)!=0) {
1731 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1732 dstbits += linebytes;
1742 const void* srcbits;
1743 const WORD* srcpixel;
1746 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1748 if (bmpImage->green_mask==0x03e0) {
1749 if (bmpImage->red_mask==0x7c00) {
1750 /* ==== rgb 555 bmp -> pal 1 dib ==== */
1751 for (h=0; h<lines; h++) {
1756 for (x=0; x<dstwidth; x++) {
1759 dstval|=(X11DRV_DIB_GetNearestIndex
1761 ((srcval >> 7) & 0xf8) | /* r */
1762 ((srcval >> 12) & 0x07),
1763 ((srcval >> 2) & 0xf8) | /* g */
1764 ((srcval >> 7) & 0x07),
1765 ((srcval << 3) & 0xf8) | /* b */
1766 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
1772 if ((dstwidth&7)!=0) {
1775 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1776 dstbits += linebytes;
1778 } else if (bmpImage->blue_mask==0x7c00) {
1779 /* ==== bgr 555 bmp -> pal 1 dib ==== */
1780 for (h=0; h<lines; h++) {
1785 for (x=0; x<dstwidth; x++) {
1788 dstval|=(X11DRV_DIB_GetNearestIndex
1790 ((srcval << 3) & 0xf8) | /* r */
1791 ((srcval >> 2) & 0x07),
1792 ((srcval >> 2) & 0xf8) | /* g */
1793 ((srcval >> 7) & 0x07),
1794 ((srcval >> 7) & 0xf8) | /* b */
1795 ((srcval >> 12) & 0x07) ) << (7-(x&7)) );
1801 if ((dstwidth&7)!=0) {
1804 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1805 dstbits += linebytes;
1810 } else if (bmpImage->green_mask==0x07e0) {
1811 if (bmpImage->red_mask==0xf800) {
1812 /* ==== rgb 565 bmp -> pal 1 dib ==== */
1813 for (h=0; h<lines; h++) {
1818 for (x=0; x<dstwidth; x++) {
1821 dstval|=(X11DRV_DIB_GetNearestIndex
1823 ((srcval >> 8) & 0xf8) | /* r */
1824 ((srcval >> 13) & 0x07),
1825 ((srcval >> 3) & 0xfc) | /* g */
1826 ((srcval >> 9) & 0x03),
1827 ((srcval << 3) & 0xf8) | /* b */
1828 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
1834 if ((dstwidth&7)!=0) {
1837 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1838 dstbits += linebytes;
1840 } else if (bmpImage->blue_mask==0xf800) {
1841 /* ==== bgr 565 bmp -> pal 1 dib ==== */
1842 for (h=0; h<lines; h++) {
1847 for (x=0; x<dstwidth; x++) {
1850 dstval|=(X11DRV_DIB_GetNearestIndex
1852 ((srcval << 3) & 0xf8) | /* r */
1853 ((srcval >> 2) & 0x07),
1854 ((srcval >> 3) & 0xfc) | /* g */
1855 ((srcval >> 9) & 0x03),
1856 ((srcval >> 8) & 0xf8) | /* b */
1857 ((srcval >> 13) & 0x07) ) << (7-(x&7)) );
1863 if ((dstwidth&7)!=0) {
1866 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1867 dstbits += linebytes;
1881 const void* srcbits;
1882 const BYTE *srcbyte;
1884 int bytes_per_pixel;
1886 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1887 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
1889 if (bmpImage->green_mask!=0x00ff00 ||
1890 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1892 } else if (bmpImage->blue_mask==0xff) {
1893 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
1894 for (h=0; h<lines; h++) {
1899 for (x=0; x<dstwidth; x++) {
1900 dstval|=(X11DRV_DIB_GetNearestIndex
1904 srcbyte[0]) << (7-(x&7)) );
1905 srcbyte+=bytes_per_pixel;
1911 if ((dstwidth&7)!=0) {
1914 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1915 dstbits += linebytes;
1918 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
1919 for (h=0; h<lines; h++) {
1924 for (x=0; x<dstwidth; x++) {
1925 dstval|=(X11DRV_DIB_GetNearestIndex
1929 srcbyte[2]) << (7-(x&7)) );
1930 srcbyte+=bytes_per_pixel;
1936 if ((dstwidth&7)!=0) {
1939 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1940 dstbits += linebytes;
1950 unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
1952 /* ==== any bmp format -> pal 1 dib ==== */
1953 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
1954 bmpImage->bits_per_pixel, bmpImage->red_mask,
1955 bmpImage->green_mask, bmpImage->blue_mask );
1957 for (h=lines-1; h>=0; h--) {
1961 for (x=0; x<dstwidth; x++) {
1962 dstval|=(XGetPixel( bmpImage, x, h) >= white) << (7 - (x&7));
1968 if ((dstwidth&7)!=0) {
1971 dstbits += linebytes;
1978 /***********************************************************************
1979 * X11DRV_DIB_SetImageBits_4
1981 * SetDIBits for a 4-bit deep DIB.
1983 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
1984 DWORD srcwidth, DWORD dstwidth, int left,
1985 int *colors, XImage *bmpImage, DWORD linebytes)
1988 const BYTE* srcbyte;
1993 srcbits = srcbits + linebytes * (lines - 1);
1994 linebytes = -linebytes;
2001 srcbits += left >> 1;
2003 /* ==== pal 4 dib -> any bmp format ==== */
2004 for (h = lines-1; h >= 0; h--) {
2006 for (i = dstwidth/2, x = left; i > 0; i--) {
2007 BYTE srcval=*srcbyte++;
2008 XPutPixel( bmpImage, x++, h, colors[srcval >> 4] );
2009 XPutPixel( bmpImage, x++, h, colors[srcval & 0x0f] );
2012 XPutPixel( bmpImage, x, h, colors[*srcbyte >> 4] );
2013 srcbits += linebytes;
2019 /***********************************************************************
2020 * X11DRV_DIB_GetImageBits_4
2022 * GetDIBits for a 4-bit deep DIB.
2024 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
2025 DWORD srcwidth, DWORD dstwidth,
2026 RGBQUAD *colors, PALETTEENTRY *srccolors,
2027 XImage *bmpImage, DWORD linebytes )
2036 dstbits = dstbits + ( linebytes * (lines-1) );
2037 linebytes = -linebytes;
2042 switch (bmpImage->depth) {
2045 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2046 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
2049 for (h = lines-1; h >= 0; h--) {
2053 for (x = 0; x < dstwidth; x++) {
2054 PALETTEENTRY srcval;
2055 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2056 dstval|=(X11DRV_DIB_GetNearestIndex
2060 srcval.peBlue) << (4-((x&1)<<2)));
2066 if ((dstwidth&1)!=0) {
2069 dstbits += linebytes;
2077 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2078 /* ==== pal 8 bmp -> pal 4 dib ==== */
2079 const void* srcbits;
2080 const BYTE *srcpixel;
2083 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2084 for (h=0; h<lines; h++) {
2089 for (x=0; x<dstwidth; x++) {
2090 PALETTEENTRY srcval;
2091 srcval = srccolors[(int)*srcpixel++];
2092 dstval|=(X11DRV_DIB_GetNearestIndex
2096 srcval.peBlue) << (4*(1-(x&1))) );
2102 if ((dstwidth&1)!=0) {
2105 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2106 dstbits += linebytes;
2116 const void* srcbits;
2117 const WORD* srcpixel;
2120 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2122 if (bmpImage->green_mask==0x03e0) {
2123 if (bmpImage->red_mask==0x7c00) {
2124 /* ==== rgb 555 bmp -> pal 4 dib ==== */
2125 for (h=0; h<lines; h++) {
2130 for (x=0; x<dstwidth; x++) {
2133 dstval|=(X11DRV_DIB_GetNearestIndex
2135 ((srcval >> 7) & 0xf8) | /* r */
2136 ((srcval >> 12) & 0x07),
2137 ((srcval >> 2) & 0xf8) | /* g */
2138 ((srcval >> 7) & 0x07),
2139 ((srcval << 3) & 0xf8) | /* b */
2140 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
2146 if ((dstwidth&1)!=0) {
2149 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2150 dstbits += linebytes;
2152 } else if (bmpImage->blue_mask==0x7c00) {
2153 /* ==== bgr 555 bmp -> pal 4 dib ==== */
2154 for (h=0; h<lines; h++) {
2159 for (x=0; x<dstwidth; x++) {
2162 dstval|=(X11DRV_DIB_GetNearestIndex
2164 ((srcval << 3) & 0xf8) | /* r */
2165 ((srcval >> 2) & 0x07),
2166 ((srcval >> 2) & 0xf8) | /* g */
2167 ((srcval >> 7) & 0x07),
2168 ((srcval >> 7) & 0xf8) | /* b */
2169 ((srcval >> 12) & 0x07) ) << ((1-(x&1))<<2) );
2175 if ((dstwidth&1)!=0) {
2178 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2179 dstbits += linebytes;
2184 } else if (bmpImage->green_mask==0x07e0) {
2185 if (bmpImage->red_mask==0xf800) {
2186 /* ==== rgb 565 bmp -> pal 4 dib ==== */
2187 for (h=0; h<lines; h++) {
2192 for (x=0; x<dstwidth; x++) {
2195 dstval|=(X11DRV_DIB_GetNearestIndex
2197 ((srcval >> 8) & 0xf8) | /* r */
2198 ((srcval >> 13) & 0x07),
2199 ((srcval >> 3) & 0xfc) | /* g */
2200 ((srcval >> 9) & 0x03),
2201 ((srcval << 3) & 0xf8) | /* b */
2202 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
2208 if ((dstwidth&1)!=0) {
2211 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2212 dstbits += linebytes;
2214 } else if (bmpImage->blue_mask==0xf800) {
2215 /* ==== bgr 565 bmp -> pal 4 dib ==== */
2216 for (h=0; h<lines; h++) {
2221 for (x=0; x<dstwidth; x++) {
2224 dstval|=(X11DRV_DIB_GetNearestIndex
2226 ((srcval << 3) & 0xf8) | /* r */
2227 ((srcval >> 2) & 0x07),
2228 ((srcval >> 3) & 0xfc) | /* g */
2229 ((srcval >> 9) & 0x03),
2230 ((srcval >> 8) & 0xf8) | /* b */
2231 ((srcval >> 13) & 0x07) ) << ((1-(x&1))<<2) );
2237 if ((dstwidth&1)!=0) {
2240 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2241 dstbits += linebytes;
2253 if (bmpImage->bits_per_pixel==24) {
2254 const void* srcbits;
2255 const BYTE *srcbyte;
2258 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2260 if (bmpImage->green_mask!=0x00ff00 ||
2261 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2263 } else if (bmpImage->blue_mask==0xff) {
2264 /* ==== rgb 888 bmp -> pal 4 dib ==== */
2265 for (h=0; h<lines; h++) {
2268 for (x=0; x<dstwidth/2; x++) {
2269 /* Do 2 pixels at a time */
2270 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2275 X11DRV_DIB_GetNearestIndex
2283 /* And the the odd pixel */
2284 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2290 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2291 dstbits += linebytes;
2294 /* ==== bgr 888 bmp -> pal 4 dib ==== */
2295 for (h=0; h<lines; h++) {
2298 for (x=0; x<dstwidth/2; x++) {
2299 /* Do 2 pixels at a time */
2300 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2305 X11DRV_DIB_GetNearestIndex
2313 /* And the the odd pixel */
2314 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2320 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2321 dstbits += linebytes;
2330 const void* srcbits;
2331 const BYTE *srcbyte;
2334 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2336 if (bmpImage->green_mask!=0x00ff00 ||
2337 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2339 } else if (bmpImage->blue_mask==0xff) {
2340 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
2341 for (h=0; h<lines; h++) {
2344 for (x=0; x<dstwidth/2; x++) {
2345 /* Do 2 pixels at a time */
2346 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2351 X11DRV_DIB_GetNearestIndex
2359 /* And the the odd pixel */
2360 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2366 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2367 dstbits += linebytes;
2370 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
2371 for (h=0; h<lines; h++) {
2374 for (x=0; x<dstwidth/2; x++) {
2375 /* Do 2 pixels at a time */
2376 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2381 X11DRV_DIB_GetNearestIndex
2389 /* And the the odd pixel */
2390 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2396 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2397 dstbits += linebytes;
2408 /* ==== any bmp format -> pal 4 dib ==== */
2409 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
2410 bmpImage->bits_per_pixel, bmpImage->red_mask,
2411 bmpImage->green_mask, bmpImage->blue_mask );
2412 for (h=lines-1; h>=0; h--) {
2414 for (x=0; x<(dstwidth & ~1); x+=2) {
2415 *dstbyte++=(X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4) |
2416 X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x+1, h), 0);
2419 *dstbyte=(X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4);
2421 dstbits += linebytes;
2428 /***********************************************************************
2429 * X11DRV_DIB_SetImageBits_RLE4
2431 * SetDIBits for a 4-bit deep compressed DIB.
2433 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
2434 DWORD width, DWORD dstwidth,
2435 int left, int *colors,
2438 int x = 0, y = lines - 1, c, length;
2439 const BYTE *begin = bits;
2444 if (length) { /* encoded */
2447 if (x >= width) break;
2448 XPutPixel(bmpImage, x++, y, colors[c >> 4]);
2449 if (!length--) break;
2450 if (x >= width) break;
2451 XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
2470 default: /* absolute */
2473 if (x < width) XPutPixel(bmpImage, x++, y, colors[c >> 4]);
2474 if (!length--) break;
2475 if (x < width) XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
2477 if ((bits - begin) & 1)
2486 /***********************************************************************
2487 * X11DRV_DIB_SetImageBits_8
2489 * SetDIBits for an 8-bit deep DIB.
2491 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
2492 DWORD srcwidth, DWORD dstwidth, int left,
2493 const int *colors, XImage *bmpImage,
2498 const BYTE* srcbyte;
2504 srcbits = srcbits + linebytes * (lines-1);
2505 linebytes = -linebytes;
2510 switch (bmpImage->depth) {
2513 #if defined(__i386__) && defined(__GNUC__)
2514 /* Some X servers might have 32 bit/ 16bit deep pixel */
2515 if (lines && dstwidth && (bmpImage->bits_per_pixel == 16) &&
2516 (ImageByteOrder(gdi_display)==LSBFirst) )
2518 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2519 /* FIXME: Does this really handle all these cases correctly? */
2520 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
2521 for (h = lines ; h--; ) {
2522 int _cl1,_cl2; /* temp outputs for asm below */
2523 /* Borrowed from DirectDraw */
2524 __asm__ __volatile__(
2529 " movw (%%edx,%%eax,4),%%ax\n"
2531 " xor %%eax,%%eax\n"
2533 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
2538 :"eax", "cc", "memory"
2540 srcbyte = (srcbits += linebytes);
2541 dstbits -= bmpImage->bytes_per_line;
2549 #if defined(__i386__) && defined(__GNUC__)
2550 if (lines && dstwidth && (bmpImage->bits_per_pixel == 32) &&
2551 (ImageByteOrder(gdi_display)==LSBFirst) )
2553 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2554 /* FIXME: Does this really handle both cases correctly? */
2555 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
2556 for (h = lines ; h--; ) {
2557 int _cl1,_cl2; /* temp outputs for asm below */
2558 /* Borrowed from DirectDraw */
2559 __asm__ __volatile__(
2564 " movl (%%edx,%%eax,4),%%eax\n"
2566 " xor %%eax,%%eax\n"
2568 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
2573 :"eax", "cc", "memory"
2575 srcbyte = (srcbits += linebytes);
2576 dstbits -= bmpImage->bytes_per_line;
2583 break; /* use slow generic case below */
2586 /* ==== pal 8 dib -> any bmp format ==== */
2587 for (h=lines-1; h>=0; h--) {
2588 for (x=left; x<dstwidth+left; x++) {
2589 XPutPixel(bmpImage, x, h, colors[*srcbyte++]);
2591 srcbyte = (srcbits += linebytes);
2595 /***********************************************************************
2596 * X11DRV_DIB_GetImageBits_8
2598 * GetDIBits for an 8-bit deep DIB.
2600 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
2601 DWORD srcwidth, DWORD dstwidth,
2602 RGBQUAD *colors, PALETTEENTRY *srccolors,
2603 XImage *bmpImage, DWORD linebytes )
2612 dstbits = dstbits + ( linebytes * (lines-1) );
2613 linebytes = -linebytes;
2618 * This condition is true when GetImageBits has been called by
2619 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
2620 * 256 colormaps, so we'll just use for for GetDIBits calls.
2621 * (In somes cases, in a updateDIBSection, the returned colors are bad too)
2623 if (!srccolors) goto updatesection;
2625 switch (bmpImage->depth) {
2628 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2630 /* ==== pal 1 bmp -> pal 8 dib ==== */
2631 /* ==== pal 4 bmp -> pal 8 dib ==== */
2632 for (h=lines-1; h>=0; h--) {
2634 for (x=0; x<dstwidth; x++) {
2635 PALETTEENTRY srcval;
2636 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2637 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
2642 dstbits += linebytes;
2650 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2651 /* ==== pal 8 bmp -> pal 8 dib ==== */
2652 const void* srcbits;
2653 const BYTE* srcpixel;
2655 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2656 for (h=0; h<lines; h++) {
2659 for (x = 0; x < dstwidth; x++) {
2660 PALETTEENTRY srcval;
2661 srcval=srccolors[(int)*srcpixel++];
2662 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
2667 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2668 dstbits += linebytes;
2678 const void* srcbits;
2679 const WORD* srcpixel;
2682 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2684 if (bmpImage->green_mask==0x03e0) {
2685 if (bmpImage->red_mask==0x7c00) {
2686 /* ==== rgb 555 bmp -> pal 8 dib ==== */
2687 for (h=0; h<lines; h++) {
2690 for (x=0; x<dstwidth; x++) {
2693 *dstbyte++=X11DRV_DIB_GetNearestIndex
2695 ((srcval >> 7) & 0xf8) | /* r */
2696 ((srcval >> 12) & 0x07),
2697 ((srcval >> 2) & 0xf8) | /* g */
2698 ((srcval >> 7) & 0x07),
2699 ((srcval << 3) & 0xf8) | /* b */
2700 ((srcval >> 2) & 0x07) );
2702 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2703 dstbits += linebytes;
2705 } else if (bmpImage->blue_mask==0x7c00) {
2706 /* ==== bgr 555 bmp -> pal 8 dib ==== */
2707 for (h=0; h<lines; h++) {
2710 for (x=0; x<dstwidth; x++) {
2713 *dstbyte++=X11DRV_DIB_GetNearestIndex
2715 ((srcval << 3) & 0xf8) | /* r */
2716 ((srcval >> 2) & 0x07),
2717 ((srcval >> 2) & 0xf8) | /* g */
2718 ((srcval >> 7) & 0x07),
2719 ((srcval >> 7) & 0xf8) | /* b */
2720 ((srcval >> 12) & 0x07) );
2722 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2723 dstbits += linebytes;
2728 } else if (bmpImage->green_mask==0x07e0) {
2729 if (bmpImage->red_mask==0xf800) {
2730 /* ==== rgb 565 bmp -> pal 8 dib ==== */
2731 for (h=0; h<lines; h++) {
2734 for (x=0; x<dstwidth; x++) {
2737 *dstbyte++=X11DRV_DIB_GetNearestIndex
2739 ((srcval >> 8) & 0xf8) | /* r */
2740 ((srcval >> 13) & 0x07),
2741 ((srcval >> 3) & 0xfc) | /* g */
2742 ((srcval >> 9) & 0x03),
2743 ((srcval << 3) & 0xf8) | /* b */
2744 ((srcval >> 2) & 0x07) );
2746 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2747 dstbits += linebytes;
2749 } else if (bmpImage->blue_mask==0xf800) {
2750 /* ==== bgr 565 bmp -> pal 8 dib ==== */
2751 for (h=0; h<lines; h++) {
2754 for (x=0; x<dstwidth; x++) {
2757 *dstbyte++=X11DRV_DIB_GetNearestIndex
2759 ((srcval << 3) & 0xf8) | /* r */
2760 ((srcval >> 2) & 0x07),
2761 ((srcval >> 3) & 0xfc) | /* g */
2762 ((srcval >> 9) & 0x03),
2763 ((srcval >> 8) & 0xf8) | /* b */
2764 ((srcval >> 13) & 0x07) );
2766 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2767 dstbits += linebytes;
2781 const void* srcbits;
2782 const BYTE *srcbyte;
2784 int bytes_per_pixel;
2786 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2787 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
2789 if (bmpImage->green_mask!=0x00ff00 ||
2790 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2792 } else if (bmpImage->blue_mask==0xff) {
2793 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
2794 for (h=0; h<lines; h++) {
2797 for (x=0; x<dstwidth; x++) {
2798 *dstbyte++=X11DRV_DIB_GetNearestIndex
2803 srcbyte+=bytes_per_pixel;
2805 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2806 dstbits += linebytes;
2809 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
2810 for (h=0; h<lines; h++) {
2813 for (x=0; x<dstwidth; x++) {
2814 *dstbyte++=X11DRV_DIB_GetNearestIndex
2819 srcbyte+=bytes_per_pixel;
2821 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2822 dstbits += linebytes;
2830 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
2831 bmpImage->depth, bmpImage->red_mask,
2832 bmpImage->green_mask, bmpImage->blue_mask );
2834 /* ==== any bmp format -> pal 8 dib ==== */
2835 for (h=lines-1; h>=0; h--) {
2837 for (x=0; x<dstwidth; x++) {
2838 *dstbyte=X11DRV_DIB_MapColor
2840 XGetPixel(bmpImage, x, h), *dstbyte);
2843 dstbits += linebytes;
2849 /***********************************************************************
2850 * X11DRV_DIB_SetImageBits_RLE8
2852 * SetDIBits for an 8-bit deep compressed DIB.
2854 * This function rewritten 941113 by James Youngman. WINE blew out when I
2855 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
2857 * This was because the algorithm assumed that all RLE8 bitmaps end with the
2858 * 'End of bitmap' escape code. This code is very much laxer in what it
2859 * allows to end the expansion. Possibly too lax. See the note by
2860 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
2861 * bitmap should end with RleEnd, but on the other hand, software exists
2862 * that produces ones that don't and Windows 3.1 doesn't complain a bit
2865 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
2866 * James A. Youngman <mbcstjy@afs.man.ac.uk>
2869 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
2870 DWORD width, DWORD dstwidth,
2871 int left, int *colors,
2874 int x; /* X-positon on each line. Increases. */
2875 int y; /* Line #. Starts at lines-1, decreases */
2876 const BYTE *pIn = bits; /* Pointer to current position in bits */
2877 BYTE length; /* The length pf a run */
2878 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
2881 * Note that the bitmap data is stored by Windows starting at the
2882 * bottom line of the bitmap and going upwards. Within each line,
2883 * the data is stored left-to-right. That's the reason why line
2884 * goes from lines-1 to 0. [JAY]
2894 * If the length byte is not zero (which is the escape value),
2895 * We have a run of length pixels all the same colour. The colour
2896 * index is stored next.
2898 * If the length byte is zero, we need to read the next byte to
2899 * know what to do. [JAY]
2904 * [Run-Length] Encoded mode
2906 int color = colors[*pIn++];
2907 while (length-- && x < dstwidth) XPutPixel(bmpImage, x++, y, color);
2912 * Escape codes (may be an absolute sequence though)
2914 escape_code = (*pIn++);
2923 /* Not all RLE8 bitmaps end with this code. For
2924 * example, Paint Shop Pro produces some that don't.
2925 * That's (I think) what caused the previous
2926 * implementation to fail. [JAY]
2935 default: /* switch to absolute mode */
2936 length = escape_code;
2939 int color = colors[*pIn++];
2945 XPutPixel(bmpImage, x++, y, color);
2948 * If you think for a moment you'll realise that the
2949 * only time we could ever possibly read an odd
2950 * number of bytes is when there is a 0x00 (escape),
2951 * a value >0x02 (absolute mode) and then an odd-
2952 * length run. Therefore this is the only place we
2953 * need to worry about it. Everywhere else the
2954 * bytes are always read in pairs. [JAY]
2956 if (escape_code & 1) pIn++; /* Throw away the pad byte. */
2958 } /* switch (escape_code) : Escape sequence */
2964 /***********************************************************************
2965 * X11DRV_DIB_SetImageBits_16
2967 * SetDIBits for a 16-bit deep DIB.
2969 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
2970 DWORD srcwidth, DWORD dstwidth, int left,
2971 X11DRV_PDEVICE *physDev, DWORD rSrc, DWORD gSrc, DWORD bSrc,
2972 XImage *bmpImage, DWORD linebytes )
2980 srcbits = srcbits + ( linebytes * (lines-1));
2981 linebytes = -linebytes;
2984 switch (bmpImage->depth)
2991 srcbits=srcbits+left*2;
2992 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2994 if (bmpImage->green_mask==0x03e0) {
2995 if (gSrc==bmpImage->green_mask) {
2996 if (rSrc==bmpImage->red_mask) {
2997 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
2998 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
2999 X11DRV_DIB_Convert_any_asis
3002 dstbits,-bmpImage->bytes_per_line);
3003 } else if (rSrc==bmpImage->blue_mask) {
3004 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
3005 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
3006 X11DRV_DIB_Convert_555_reverse
3009 dstbits,-bmpImage->bytes_per_line);
3012 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
3013 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
3014 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
3015 X11DRV_DIB_Convert_565_to_555_asis
3018 dstbits,-bmpImage->bytes_per_line);
3020 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
3021 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
3022 X11DRV_DIB_Convert_565_to_555_reverse
3025 dstbits,-bmpImage->bytes_per_line);
3028 } else if (bmpImage->green_mask==0x07e0) {
3029 if (gSrc==bmpImage->green_mask) {
3030 if (rSrc==bmpImage->red_mask) {
3031 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
3032 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
3033 X11DRV_DIB_Convert_any_asis
3036 dstbits,-bmpImage->bytes_per_line);
3038 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
3039 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
3040 X11DRV_DIB_Convert_565_reverse
3043 dstbits,-bmpImage->bytes_per_line);
3046 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
3047 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
3048 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
3049 X11DRV_DIB_Convert_555_to_565_asis
3052 dstbits,-bmpImage->bytes_per_line);
3054 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
3055 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
3056 X11DRV_DIB_Convert_555_to_565_reverse
3059 dstbits,-bmpImage->bytes_per_line);
3069 if (bmpImage->bits_per_pixel==24) {
3072 srcbits=srcbits+left*2;
3073 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
3075 if (bmpImage->green_mask!=0x00ff00 ||
3076 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3078 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
3079 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
3081 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
3082 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
3083 X11DRV_DIB_Convert_555_to_888_asis
3086 dstbits,-bmpImage->bytes_per_line);
3088 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
3089 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
3090 X11DRV_DIB_Convert_565_to_888_asis
3093 dstbits,-bmpImage->bytes_per_line);
3097 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
3098 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
3099 X11DRV_DIB_Convert_555_to_888_reverse
3102 dstbits,-bmpImage->bytes_per_line);
3104 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
3105 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
3106 X11DRV_DIB_Convert_565_to_888_reverse
3109 dstbits,-bmpImage->bytes_per_line);
3120 srcbits=srcbits+left*2;
3121 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
3123 if (bmpImage->green_mask!=0x00ff00 ||
3124 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3126 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
3127 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
3129 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
3130 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
3131 X11DRV_DIB_Convert_555_to_0888_asis
3134 dstbits,-bmpImage->bytes_per_line);
3136 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
3137 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
3138 X11DRV_DIB_Convert_565_to_0888_asis
3141 dstbits,-bmpImage->bytes_per_line);
3145 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
3146 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
3147 X11DRV_DIB_Convert_555_to_0888_reverse
3150 dstbits,-bmpImage->bytes_per_line);
3152 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
3153 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
3154 X11DRV_DIB_Convert_565_to_0888_reverse
3157 dstbits,-bmpImage->bytes_per_line);
3165 WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3166 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
3167 bmpImage->green_mask, bmpImage->blue_mask );
3173 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
3174 const WORD* srcpixel;
3175 int rShift1,gShift1,bShift1;
3176 int rShift2,gShift2,bShift2;
3179 /* Set color scaling values */
3180 rShift1=16+X11DRV_DIB_MaskToShift(rSrc)-3;
3181 gShift1=16+X11DRV_DIB_MaskToShift(gSrc)-3;
3182 bShift1=16+X11DRV_DIB_MaskToShift(bSrc)-3;
3187 /* Green has 5 bits, like the others */
3191 /* Green has 6 bits, not 5. Compensate. */
3200 /* We could split it into four separate cases to optimize
3201 * but it is probably not worth it.
3203 for (h=lines-1; h>=0; h--) {
3204 srcpixel=(const WORD*)srcbits;
3205 for (x=left; x<dstwidth+left; x++) {
3207 BYTE red,green,blue;
3208 srcval=*srcpixel++ << 16;
3209 red= ((srcval >> rShift1) & 0xf8) |
3210 ((srcval >> rShift2) & 0x07);
3211 green=((srcval >> gShift1) & gMask1) |
3212 ((srcval >> gShift2) & gMask2);
3213 blue= ((srcval >> bShift1) & 0xf8) |
3214 ((srcval >> bShift2) & 0x07);
3215 XPutPixel(bmpImage, x, h,
3216 X11DRV_PALETTE_ToPhysical
3217 (physDev, RGB(red,green,blue)));
3219 srcbits += linebytes;
3227 /***********************************************************************
3228 * X11DRV_DIB_GetImageBits_16
3230 * GetDIBits for an 16-bit deep DIB.
3232 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
3233 DWORD dstwidth, DWORD srcwidth,
3234 PALETTEENTRY *srccolors,
3235 DWORD rDst, DWORD gDst, DWORD bDst,
3236 XImage *bmpImage, DWORD dibpitch )
3241 DWORD linebytes = dibpitch;
3246 dstbits = dstbits + ( linebytes * (lines-1));
3247 linebytes = -linebytes;
3250 switch (bmpImage->depth)
3255 const char* srcbits;
3257 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3259 if (bmpImage->green_mask==0x03e0) {
3260 if (gDst==bmpImage->green_mask) {
3261 if (rDst==bmpImage->red_mask) {
3262 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
3263 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
3264 X11DRV_DIB_Convert_any_asis
3266 srcbits,-bmpImage->bytes_per_line,
3269 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
3270 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
3271 X11DRV_DIB_Convert_555_reverse
3273 srcbits,-bmpImage->bytes_per_line,
3277 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
3278 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
3279 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
3280 X11DRV_DIB_Convert_555_to_565_asis
3282 srcbits,-bmpImage->bytes_per_line,
3285 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
3286 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
3287 X11DRV_DIB_Convert_555_to_565_reverse
3289 srcbits,-bmpImage->bytes_per_line,
3293 } else if (bmpImage->green_mask==0x07e0) {
3294 if (gDst==bmpImage->green_mask) {
3295 if (rDst == bmpImage->red_mask) {
3296 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
3297 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
3298 X11DRV_DIB_Convert_any_asis
3300 srcbits,-bmpImage->bytes_per_line,
3303 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
3304 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
3305 X11DRV_DIB_Convert_565_reverse
3307 srcbits,-bmpImage->bytes_per_line,
3311 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
3312 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
3313 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
3314 X11DRV_DIB_Convert_565_to_555_asis
3316 srcbits,-bmpImage->bytes_per_line,
3319 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
3320 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
3321 X11DRV_DIB_Convert_565_to_555_reverse
3323 srcbits,-bmpImage->bytes_per_line,
3334 if (bmpImage->bits_per_pixel == 24) {
3335 const char* srcbits;
3337 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3339 if (bmpImage->green_mask!=0x00ff00 ||
3340 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3342 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
3343 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
3345 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
3346 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
3347 X11DRV_DIB_Convert_888_to_555_asis
3349 srcbits,-bmpImage->bytes_per_line,
3352 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
3353 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
3354 X11DRV_DIB_Convert_888_to_565_asis
3356 srcbits,-bmpImage->bytes_per_line,
3361 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
3362 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
3363 X11DRV_DIB_Convert_888_to_555_reverse
3365 srcbits,-bmpImage->bytes_per_line,
3368 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
3369 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
3370 X11DRV_DIB_Convert_888_to_565_reverse
3372 srcbits,-bmpImage->bytes_per_line,
3382 const char* srcbits;
3384 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3386 if (bmpImage->green_mask!=0x00ff00 ||
3387 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3389 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
3390 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
3392 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
3393 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
3394 X11DRV_DIB_Convert_0888_to_555_asis
3396 srcbits,-bmpImage->bytes_per_line,
3399 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
3400 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
3401 X11DRV_DIB_Convert_0888_to_565_asis
3403 srcbits,-bmpImage->bytes_per_line,
3408 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
3409 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
3410 X11DRV_DIB_Convert_0888_to_555_reverse
3412 srcbits,-bmpImage->bytes_per_line,
3415 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
3416 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
3417 X11DRV_DIB_Convert_0888_to_565_reverse
3419 srcbits,-bmpImage->bytes_per_line,
3428 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3429 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
3430 int rShift,gShift,bShift;
3433 /* Shift everything 16 bits left so that all shifts are >0,
3434 * even for BGR DIBs. Then a single >> 16 will bring everything
3437 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
3438 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
3439 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
3441 /* 6 bits for the green */
3447 for (h = lines - 1; h >= 0; h--) {
3448 dstpixel=(LPWORD)dstbits;
3449 for (x = 0; x < dstwidth; x++) {
3450 PALETTEENTRY srcval;
3452 srcval=srccolors[XGetPixel(bmpImage, x, h)];
3453 dstval=((srcval.peRed << rShift) & rDst) |
3454 ((srcval.peGreen << gShift) & gDst) |
3455 ((srcval.peBlue << bShift) & bDst);
3456 *dstpixel++=dstval >> 16;
3458 dstbits += linebytes;
3466 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3467 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
3468 int rShift,gShift,bShift;
3469 const BYTE* srcbits;
3470 const BYTE* srcpixel;
3473 /* Shift everything 16 bits left so that all shifts are >0,
3474 * even for BGR DIBs. Then a single >> 16 will bring everything
3477 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
3478 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
3479 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
3481 /* 6 bits for the green */
3487 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3488 for (h=0; h<lines; h++) {
3490 dstpixel=(LPWORD)dstbits;
3491 for (x = 0; x < dstwidth; x++) {
3492 PALETTEENTRY srcval;
3494 srcval=srccolors[(int)*srcpixel++];
3495 dstval=((srcval.peRed << rShift) & rDst) |
3496 ((srcval.peGreen << gShift) & gDst) |
3497 ((srcval.peBlue << bShift) & bDst);
3498 *dstpixel++=dstval >> 16;
3500 srcbits -= bmpImage->bytes_per_line;
3501 dstbits += linebytes;
3511 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
3512 int rShift,gShift,bShift;
3515 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
3516 bmpImage->depth, bmpImage->red_mask,
3517 bmpImage->green_mask, bmpImage->blue_mask,
3520 /* Shift everything 16 bits left so that all shifts are >0,
3521 * even for BGR DIBs. Then a single >> 16 will bring everything
3524 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
3525 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
3526 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
3528 /* 6 bits for the green */
3534 for (h = lines - 1; h >= 0; h--) {
3535 dstpixel=(LPWORD)dstbits;
3536 for (x = 0; x < dstwidth; x++) {
3539 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
3540 dstval=((GetRValue(srcval) << rShift) & rDst) |
3541 ((GetGValue(srcval) << gShift) & gDst) |
3542 ((GetBValue(srcval) << bShift) & bDst);
3543 *dstpixel++=dstval >> 16;
3545 dstbits += linebytes;
3553 /***********************************************************************
3554 * X11DRV_DIB_SetImageBits_24
3556 * SetDIBits for a 24-bit deep DIB.
3558 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
3559 DWORD srcwidth, DWORD dstwidth, int left,
3560 X11DRV_PDEVICE *physDev,
3561 DWORD rSrc, DWORD gSrc, DWORD bSrc,
3562 XImage *bmpImage, DWORD linebytes )
3570 srcbits = srcbits + linebytes * (lines - 1);
3571 linebytes = -linebytes;
3574 switch (bmpImage->depth)
3577 if (bmpImage->bits_per_pixel==24) {
3580 srcbits=srcbits+left*3;
3581 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
3583 if (bmpImage->green_mask!=0x00ff00 ||
3584 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3586 } else if (rSrc==bmpImage->red_mask) {
3587 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
3588 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
3589 X11DRV_DIB_Convert_any_asis
3592 dstbits,-bmpImage->bytes_per_line);
3594 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
3595 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
3596 X11DRV_DIB_Convert_888_reverse
3599 dstbits,-bmpImage->bytes_per_line);
3609 srcbits=srcbits+left*3;
3610 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
3612 if (bmpImage->green_mask!=0x00ff00 ||
3613 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3615 } else if (rSrc==bmpImage->red_mask) {
3616 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
3617 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
3618 X11DRV_DIB_Convert_888_to_0888_asis
3621 dstbits,-bmpImage->bytes_per_line);
3623 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
3624 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
3625 X11DRV_DIB_Convert_888_to_0888_reverse
3628 dstbits,-bmpImage->bytes_per_line);
3638 srcbits=srcbits+left*3;
3639 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
3641 if (bmpImage->green_mask==0x03e0) {
3642 if ((rSrc==0xff0000 && bmpImage->red_mask==0x7f00) ||
3643 (bSrc==0xff0000 && bmpImage->blue_mask==0x7f00)) {
3644 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
3645 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
3646 X11DRV_DIB_Convert_888_to_555_asis
3649 dstbits,-bmpImage->bytes_per_line);
3650 } else if ((rSrc==0xff && bmpImage->red_mask==0x7f00) ||
3651 (bSrc==0xff && bmpImage->blue_mask==0x7f00)) {
3652 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
3653 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
3654 X11DRV_DIB_Convert_888_to_555_reverse
3657 dstbits,-bmpImage->bytes_per_line);
3661 } else if (bmpImage->green_mask==0x07e0) {
3662 if ((rSrc==0xff0000 && bmpImage->red_mask==0xf800) ||
3663 (bSrc==0xff0000 && bmpImage->blue_mask==0xf800)) {
3664 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
3665 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
3666 X11DRV_DIB_Convert_888_to_565_asis
3669 dstbits,-bmpImage->bytes_per_line);
3670 } else if ((rSrc==0xff && bmpImage->red_mask==0xf800) ||
3671 (bSrc==0xff && bmpImage->blue_mask==0xf800)) {
3672 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
3673 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
3674 X11DRV_DIB_Convert_888_to_565_reverse
3677 dstbits,-bmpImage->bytes_per_line);
3689 WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3690 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
3691 bmpImage->green_mask, bmpImage->blue_mask );
3697 /* ==== rgb 888 dib -> any bmp bormat ==== */
3698 const BYTE* srcbyte;
3700 /* Windows only supports one 24bpp DIB format: RGB888 */
3702 for (h = lines - 1; h >= 0; h--) {
3703 srcbyte=(const BYTE*)srcbits;
3704 for (x = left; x < dstwidth+left; x++) {
3705 XPutPixel(bmpImage, x, h,
3706 X11DRV_PALETTE_ToPhysical
3707 (physDev, RGB(srcbyte[2], srcbyte[1], srcbyte[0])));
3710 srcbits += linebytes;
3718 /***********************************************************************
3719 * X11DRV_DIB_GetImageBits_24
3721 * GetDIBits for an 24-bit deep DIB.
3723 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
3724 DWORD dstwidth, DWORD srcwidth,
3725 PALETTEENTRY *srccolors,
3726 DWORD rDst, DWORD gDst, DWORD bDst,
3727 XImage *bmpImage, DWORD linebytes )
3735 dstbits = dstbits + ( linebytes * (lines-1) );
3736 linebytes = -linebytes;
3739 switch (bmpImage->depth)
3742 if (bmpImage->bits_per_pixel==24) {
3743 const char* srcbits;
3745 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3747 if (bmpImage->green_mask!=0x00ff00 ||
3748 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3750 } else if (rDst==bmpImage->red_mask) {
3751 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
3752 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
3753 X11DRV_DIB_Convert_any_asis
3755 srcbits,-bmpImage->bytes_per_line,
3758 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
3759 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
3760 X11DRV_DIB_Convert_888_reverse
3762 srcbits,-bmpImage->bytes_per_line,
3771 const char* srcbits;
3773 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3775 if (bmpImage->green_mask!=0x00ff00 ||
3776 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3778 } else if (rDst==bmpImage->red_mask) {
3779 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3780 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3781 X11DRV_DIB_Convert_0888_to_888_asis
3783 srcbits,-bmpImage->bytes_per_line,
3786 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3787 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3788 X11DRV_DIB_Convert_0888_to_888_reverse
3790 srcbits,-bmpImage->bytes_per_line,
3799 const char* srcbits;
3801 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3803 if (bmpImage->green_mask==0x03e0) {
3804 if ((rDst==0xff0000 && bmpImage->red_mask==0x7f00) ||
3805 (bDst==0xff0000 && bmpImage->blue_mask==0x7f00)) {
3806 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
3807 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
3808 X11DRV_DIB_Convert_555_to_888_asis
3810 srcbits,-bmpImage->bytes_per_line,
3812 } else if ((rDst==0xff && bmpImage->red_mask==0x7f00) ||
3813 (bDst==0xff && bmpImage->blue_mask==0x7f00)) {
3814 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
3815 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
3816 X11DRV_DIB_Convert_555_to_888_reverse
3818 srcbits,-bmpImage->bytes_per_line,
3823 } else if (bmpImage->green_mask==0x07e0) {
3824 if ((rDst==0xff0000 && bmpImage->red_mask==0xf800) ||
3825 (bDst==0xff0000 && bmpImage->blue_mask==0xf800)) {
3826 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
3827 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
3828 X11DRV_DIB_Convert_565_to_888_asis
3830 srcbits,-bmpImage->bytes_per_line,
3832 } else if ((rDst==0xff && bmpImage->red_mask==0xf800) ||
3833 (bDst==0xff && bmpImage->blue_mask==0xf800)) {
3834 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
3835 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
3836 X11DRV_DIB_Convert_565_to_888_reverse
3838 srcbits,-bmpImage->bytes_per_line,
3851 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3852 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
3855 /* Windows only supports one 24bpp DIB format: rgb 888 */
3856 for (h = lines - 1; h >= 0; h--) {
3858 for (x = 0; x < dstwidth; x++) {
3859 PALETTEENTRY srcval;
3860 srcval=srccolors[XGetPixel(bmpImage, x, h)];
3861 dstbyte[0]=srcval.peBlue;
3862 dstbyte[1]=srcval.peGreen;
3863 dstbyte[2]=srcval.peRed;
3866 dstbits += linebytes;
3874 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors) {
3875 /* ==== pal 8 bmp -> rgb 888 dib ==== */
3876 const void* srcbits;
3877 const BYTE* srcpixel;
3880 /* Windows only supports one 24bpp DIB format: rgb 888 */
3881 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3882 for (h = lines - 1; h >= 0; h--) {
3885 for (x = 0; x < dstwidth; x++ ) {
3886 PALETTEENTRY srcval;
3887 srcval=srccolors[(int)*srcpixel++];
3888 dstbyte[0]=srcval.peBlue;
3889 dstbyte[1]=srcval.peGreen;
3890 dstbyte[2]=srcval.peRed;
3893 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
3894 dstbits += linebytes;
3904 /* ==== any bmp format -> 888 dib ==== */
3907 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
3908 bmpImage->depth, bmpImage->red_mask,
3909 bmpImage->green_mask, bmpImage->blue_mask,
3912 /* Windows only supports one 24bpp DIB format: rgb 888 */
3913 for (h = lines - 1; h >= 0; h--) {
3915 for (x = 0; x < dstwidth; x++) {
3916 COLORREF srcval=X11DRV_PALETTE_ToLogical
3917 (XGetPixel( bmpImage, x, h ));
3918 dstbyte[0]=GetBValue(srcval);
3919 dstbyte[1]=GetGValue(srcval);
3920 dstbyte[2]=GetRValue(srcval);
3923 dstbits += linebytes;
3931 /***********************************************************************
3932 * X11DRV_DIB_SetImageBits_32
3934 * SetDIBits for a 32-bit deep DIB.
3936 static void X11DRV_DIB_SetImageBits_32(int lines, const BYTE *srcbits,
3937 DWORD srcwidth, DWORD dstwidth, int left,
3938 X11DRV_PDEVICE *physDev,
3939 DWORD rSrc, DWORD gSrc, DWORD bSrc,
3949 srcbits = srcbits + ( linebytes * (lines-1) );
3950 linebytes = -linebytes;
3953 ptr = (DWORD *) srcbits + left;
3955 switch (bmpImage->depth)
3958 if (bmpImage->bits_per_pixel==24) {
3961 srcbits=srcbits+left*4;
3962 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
3964 if (rSrc==bmpImage->red_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->blue_mask) {
3965 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
3966 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
3967 X11DRV_DIB_Convert_0888_to_888_asis
3970 dstbits,-bmpImage->bytes_per_line);
3971 } else if (bmpImage->green_mask!=0x00ff00 ||
3972 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3974 /* the tests below assume sane bmpImage masks */
3975 } else if (rSrc==bmpImage->blue_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->red_mask) {
3976 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
3977 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
3978 X11DRV_DIB_Convert_0888_to_888_reverse
3981 dstbits,-bmpImage->bytes_per_line);
3982 } else if (bmpImage->blue_mask==0xff) {
3983 /* ==== any 0888 dib -> rgb 888 bmp ==== */
3984 X11DRV_DIB_Convert_any0888_to_rgb888
3988 dstbits,-bmpImage->bytes_per_line);
3990 /* ==== any 0888 dib -> bgr 888 bmp ==== */
3991 X11DRV_DIB_Convert_any0888_to_bgr888
3995 dstbits,-bmpImage->bytes_per_line);
4005 srcbits=srcbits+left*4;
4006 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
4008 if (gSrc==bmpImage->green_mask) {
4009 if (rSrc==bmpImage->red_mask && bSrc==bmpImage->blue_mask) {
4010 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
4011 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
4012 X11DRV_DIB_Convert_any_asis
4015 dstbits,-bmpImage->bytes_per_line);
4016 } else if (bmpImage->green_mask!=0x00ff00 ||
4017 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4019 /* the tests below assume sane bmpImage masks */
4020 } else if (rSrc==bmpImage->blue_mask && bSrc==bmpImage->red_mask) {
4021 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
4022 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
4023 X11DRV_DIB_Convert_0888_reverse
4026 dstbits,-bmpImage->bytes_per_line);
4028 /* ==== any 0888 dib -> any 0888 bmp ==== */
4029 X11DRV_DIB_Convert_0888_any
4033 dstbits,-bmpImage->bytes_per_line,
4034 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4036 } else if (bmpImage->green_mask!=0x00ff00 ||
4037 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4039 /* the tests below assume sane bmpImage masks */
4041 /* ==== any 0888 dib -> any 0888 bmp ==== */
4042 X11DRV_DIB_Convert_0888_any
4046 dstbits,-bmpImage->bytes_per_line,
4047 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4057 srcbits=srcbits+left*4;
4058 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
4060 if (rSrc==0xff0000 && gSrc==0x00ff00 && bSrc==0x0000ff) {
4061 if (bmpImage->green_mask==0x03e0) {
4062 if (bmpImage->red_mask==0x7f00) {
4063 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
4064 X11DRV_DIB_Convert_0888_to_555_asis
4067 dstbits,-bmpImage->bytes_per_line);
4068 } else if (bmpImage->blue_mask==0x7f00) {
4069 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
4070 X11DRV_DIB_Convert_0888_to_555_reverse
4073 dstbits,-bmpImage->bytes_per_line);
4077 } else if (bmpImage->green_mask==0x07e0) {
4078 if (bmpImage->red_mask==0xf800) {
4079 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
4080 X11DRV_DIB_Convert_0888_to_565_asis
4083 dstbits,-bmpImage->bytes_per_line);
4084 } else if (bmpImage->blue_mask==0xf800) {
4085 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
4086 X11DRV_DIB_Convert_0888_to_565_reverse
4089 dstbits,-bmpImage->bytes_per_line);
4096 } else if (rSrc==0x0000ff && gSrc==0x00ff00 && bSrc==0xff0000) {
4097 if (bmpImage->green_mask==0x03e0) {
4098 if (bmpImage->blue_mask==0x7f00) {
4099 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
4100 X11DRV_DIB_Convert_0888_to_555_asis
4103 dstbits,-bmpImage->bytes_per_line);
4104 } else if (bmpImage->red_mask==0x7f00) {
4105 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
4106 X11DRV_DIB_Convert_0888_to_555_reverse
4109 dstbits,-bmpImage->bytes_per_line);
4113 } else if (bmpImage->green_mask==0x07e0) {
4114 if (bmpImage->blue_mask==0xf800) {
4115 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
4116 X11DRV_DIB_Convert_0888_to_565_asis
4119 dstbits,-bmpImage->bytes_per_line);
4120 } else if (bmpImage->red_mask==0xf800) {
4121 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
4122 X11DRV_DIB_Convert_0888_to_565_reverse
4125 dstbits,-bmpImage->bytes_per_line);
4133 if (bmpImage->green_mask==0x03e0 &&
4134 (bmpImage->red_mask==0x7f00 ||
4135 bmpImage->blue_mask==0x7f00)) {
4136 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
4137 X11DRV_DIB_Convert_any0888_to_5x5
4141 dstbits,-bmpImage->bytes_per_line,
4142 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4143 } else if (bmpImage->green_mask==0x07e0 &&
4144 (bmpImage->red_mask==0xf800 ||
4145 bmpImage->blue_mask==0xf800)) {
4146 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
4147 X11DRV_DIB_Convert_any0888_to_5x5
4151 dstbits,-bmpImage->bytes_per_line,
4152 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4162 WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
4163 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
4164 bmpImage->green_mask, bmpImage->blue_mask );
4170 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
4171 const DWORD* srcpixel;
4172 int rShift,gShift,bShift;
4174 rShift=X11DRV_DIB_MaskToShift(rSrc);
4175 gShift=X11DRV_DIB_MaskToShift(gSrc);
4176 bShift=X11DRV_DIB_MaskToShift(bSrc);
4178 for (h = lines - 1; h >= 0; h--) {
4179 srcpixel=(const DWORD*)srcbits;
4180 for (x = left; x < dstwidth+left; x++) {
4182 BYTE red,green,blue;
4183 srcvalue=*srcpixel++;
4184 red= (srcvalue >> rShift) & 0xff;
4185 green=(srcvalue >> gShift) & 0xff;
4186 blue= (srcvalue >> bShift) & 0xff;
4187 XPutPixel(bmpImage, x, h, X11DRV_PALETTE_ToPhysical
4188 (physDev, RGB(red,green,blue)));
4190 srcbits += linebytes;
4198 /***********************************************************************
4199 * X11DRV_DIB_GetImageBits_32
4201 * GetDIBits for an 32-bit deep DIB.
4203 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
4204 DWORD dstwidth, DWORD srcwidth,
4205 PALETTEENTRY *srccolors,
4206 DWORD rDst, DWORD gDst, DWORD bDst,
4207 XImage *bmpImage, DWORD linebytes )
4216 dstbits = dstbits + ( linebytes * (lines-1) );
4217 linebytes = -linebytes;
4222 switch (bmpImage->depth)
4225 if (bmpImage->bits_per_pixel==24) {
4226 const void* srcbits;
4228 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4230 if (rDst==bmpImage->red_mask && gDst==bmpImage->green_mask && bDst==bmpImage->blue_mask) {
4231 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
4232 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
4233 X11DRV_DIB_Convert_888_to_0888_asis
4235 srcbits,-bmpImage->bytes_per_line,
4237 } else if (bmpImage->green_mask!=0x00ff00 ||
4238 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4240 /* the tests below assume sane bmpImage masks */
4241 } else if (rDst==bmpImage->blue_mask && gDst==bmpImage->green_mask && bDst==bmpImage->red_mask) {
4242 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
4243 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
4244 X11DRV_DIB_Convert_888_to_0888_reverse
4246 srcbits,-bmpImage->bytes_per_line,
4248 } else if (bmpImage->blue_mask==0xff) {
4249 /* ==== rgb 888 bmp -> any 0888 dib ==== */
4250 X11DRV_DIB_Convert_rgb888_to_any0888
4252 srcbits,-bmpImage->bytes_per_line,
4256 /* ==== bgr 888 bmp -> any 0888 dib ==== */
4257 X11DRV_DIB_Convert_bgr888_to_any0888
4259 srcbits,-bmpImage->bytes_per_line,
4269 const char* srcbits;
4271 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4273 if (gDst==bmpImage->green_mask) {
4274 if (rDst==bmpImage->red_mask && bDst==bmpImage->blue_mask) {
4275 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
4276 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
4277 X11DRV_DIB_Convert_any_asis
4279 srcbits,-bmpImage->bytes_per_line,
4281 } else if (bmpImage->green_mask!=0x00ff00 ||
4282 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4284 /* the tests below assume sane bmpImage masks */
4285 } else if (rDst==bmpImage->blue_mask && bDst==bmpImage->red_mask) {
4286 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
4287 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
4288 X11DRV_DIB_Convert_0888_reverse
4290 srcbits,-bmpImage->bytes_per_line,
4293 /* ==== any 0888 bmp -> any 0888 dib ==== */
4294 X11DRV_DIB_Convert_0888_any
4296 srcbits,-bmpImage->bytes_per_line,
4297 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4301 } else if (bmpImage->green_mask!=0x00ff00 ||
4302 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4304 /* the tests below assume sane bmpImage masks */
4306 /* ==== any 0888 bmp -> any 0888 dib ==== */
4307 X11DRV_DIB_Convert_0888_any
4309 srcbits,-bmpImage->bytes_per_line,
4310 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4320 const char* srcbits;
4322 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4324 if (rDst==0xff0000 && gDst==0x00ff00 && bDst==0x0000ff) {
4325 if (bmpImage->green_mask==0x03e0) {
4326 if (bmpImage->red_mask==0x7f00) {
4327 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
4328 X11DRV_DIB_Convert_555_to_0888_asis
4330 srcbits,-bmpImage->bytes_per_line,
4332 } else if (bmpImage->blue_mask==0x7f00) {
4333 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
4334 X11DRV_DIB_Convert_555_to_0888_reverse
4336 srcbits,-bmpImage->bytes_per_line,
4341 } else if (bmpImage->green_mask==0x07e0) {
4342 if (bmpImage->red_mask==0xf800) {
4343 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
4344 X11DRV_DIB_Convert_565_to_0888_asis
4346 srcbits,-bmpImage->bytes_per_line,
4348 } else if (bmpImage->blue_mask==0xf800) {
4349 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
4350 X11DRV_DIB_Convert_565_to_0888_reverse
4352 srcbits,-bmpImage->bytes_per_line,
4360 } else if (rDst==0x0000ff && gDst==0x00ff00 && bDst==0xff0000) {
4361 if (bmpImage->green_mask==0x03e0) {
4362 if (bmpImage->blue_mask==0x7f00) {
4363 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
4364 X11DRV_DIB_Convert_555_to_0888_asis
4366 srcbits,-bmpImage->bytes_per_line,
4368 } else if (bmpImage->red_mask==0x7f00) {
4369 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
4370 X11DRV_DIB_Convert_555_to_0888_reverse
4372 srcbits,-bmpImage->bytes_per_line,
4377 } else if (bmpImage->green_mask==0x07e0) {
4378 if (bmpImage->blue_mask==0xf800) {
4379 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
4380 X11DRV_DIB_Convert_565_to_0888_asis
4382 srcbits,-bmpImage->bytes_per_line,
4384 } else if (bmpImage->red_mask==0xf800) {
4385 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
4386 X11DRV_DIB_Convert_565_to_0888_reverse
4388 srcbits,-bmpImage->bytes_per_line,
4397 if (bmpImage->green_mask==0x03e0 &&
4398 (bmpImage->red_mask==0x7f00 ||
4399 bmpImage->blue_mask==0x7f00)) {
4400 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
4401 X11DRV_DIB_Convert_5x5_to_any0888
4403 srcbits,-bmpImage->bytes_per_line,
4404 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4407 } else if (bmpImage->green_mask==0x07e0 &&
4408 (bmpImage->red_mask==0xf800 ||
4409 bmpImage->blue_mask==0xf800)) {
4410 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
4411 X11DRV_DIB_Convert_5x5_to_any0888
4413 srcbits,-bmpImage->bytes_per_line,
4414 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4426 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
4427 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
4428 int rShift,gShift,bShift;
4431 rShift=X11DRV_DIB_MaskToShift(rDst);
4432 gShift=X11DRV_DIB_MaskToShift(gDst);
4433 bShift=X11DRV_DIB_MaskToShift(bDst);
4434 for (h = lines - 1; h >= 0; h--) {
4435 dstpixel=(DWORD*)dstbits;
4436 for (x = 0; x < dstwidth; x++) {
4437 PALETTEENTRY srcval;
4438 srcval = srccolors[XGetPixel(bmpImage, x, h)];
4439 *dstpixel++=(srcval.peRed << rShift) |
4440 (srcval.peGreen << gShift) |
4441 (srcval.peBlue << bShift);
4443 dstbits += linebytes;
4451 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
4452 /* ==== pal 8 bmp -> any 0888 dib ==== */
4453 int rShift,gShift,bShift;
4454 const void* srcbits;
4455 const BYTE* srcpixel;
4458 rShift=X11DRV_DIB_MaskToShift(rDst);
4459 gShift=X11DRV_DIB_MaskToShift(gDst);
4460 bShift=X11DRV_DIB_MaskToShift(bDst);
4461 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4462 for (h = lines - 1; h >= 0; h--) {
4464 dstpixel=(DWORD*)dstbits;
4465 for (x = 0; x < dstwidth; x++) {
4466 PALETTEENTRY srcval;
4467 srcval=srccolors[(int)*srcpixel++];
4468 *dstpixel++=(srcval.peRed << rShift) |
4469 (srcval.peGreen << gShift) |
4470 (srcval.peBlue << bShift);
4472 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
4473 dstbits += linebytes;
4483 /* ==== any bmp format -> any 0888 dib ==== */
4484 int rShift,gShift,bShift;
4487 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
4488 bmpImage->depth, bmpImage->red_mask,
4489 bmpImage->green_mask, bmpImage->blue_mask,
4492 rShift=X11DRV_DIB_MaskToShift(rDst);
4493 gShift=X11DRV_DIB_MaskToShift(gDst);
4494 bShift=X11DRV_DIB_MaskToShift(bDst);
4495 for (h = lines - 1; h >= 0; h--) {
4496 dstpixel=(DWORD*)dstbits;
4497 for (x = 0; x < dstwidth; x++) {
4499 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
4500 *dstpixel++=(GetRValue(srcval) << rShift) |
4501 (GetGValue(srcval) << gShift) |
4502 (GetBValue(srcval) << bShift);
4504 dstbits += linebytes;
4511 /***********************************************************************
4512 * X11DRV_DIB_SetImageBits
4514 * Transfer the bits to an X image.
4515 * Helper function for SetDIBits() and SetDIBitsToDevice().
4517 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
4519 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
4524 bmpImage = descr->image;
4526 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
4527 descr->infoWidth, lines, 32, 0 );
4528 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
4529 if(bmpImage->data == NULL) {
4530 ERR("Out of memory!\n");
4531 XDestroyImage( bmpImage );
4532 wine_tsx11_unlock();
4537 TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
4538 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
4539 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
4540 bmpImage->depth,bmpImage->bits_per_pixel,
4541 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4543 /* Transfer the pixels */
4544 switch(descr->infoBpp)
4547 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
4548 descr->width, descr->xSrc, (int *)(descr->colorMap),
4549 bmpImage, descr->dibpitch );
4552 if (descr->compression) {
4553 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
4554 descr->width, descr->height, AllPlanes, ZPixmap,
4555 bmpImage, descr->xSrc, descr->ySrc );
4557 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
4558 descr->infoWidth, descr->width,
4559 descr->xSrc, (int *)(descr->colorMap),
4562 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
4563 descr->infoWidth, descr->width,
4564 descr->xSrc, (int*)(descr->colorMap),
4565 bmpImage, descr->dibpitch );
4568 if (descr->compression) {
4569 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
4570 descr->width, descr->height, AllPlanes, ZPixmap,
4571 bmpImage, descr->xSrc, descr->ySrc );
4572 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
4573 descr->infoWidth, descr->width,
4574 descr->xSrc, (int *)(descr->colorMap),
4577 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
4578 descr->infoWidth, descr->width,
4579 descr->xSrc, (int *)(descr->colorMap),
4580 bmpImage, descr->dibpitch );
4584 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
4585 descr->infoWidth, descr->width,
4586 descr->xSrc, descr->physDev,
4587 descr->rMask, descr->gMask, descr->bMask,
4588 bmpImage, descr->dibpitch);
4591 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
4592 descr->infoWidth, descr->width,
4593 descr->xSrc, descr->physDev,
4594 descr->rMask, descr->gMask, descr->bMask,
4595 bmpImage, descr->dibpitch);
4598 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
4599 descr->infoWidth, descr->width,
4600 descr->xSrc, descr->physDev,
4601 descr->rMask, descr->gMask, descr->bMask,
4602 bmpImage, descr->dibpitch);
4605 WARN("(%d): Invalid depth\n", descr->infoBpp );
4609 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
4610 descr->drawable, descr->gc, bmpImage,
4611 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
4612 descr->width, descr->height);
4613 #ifdef HAVE_LIBXXSHM
4616 XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
4617 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
4618 descr->width, descr->height, FALSE );
4619 XSync( gdi_display, 0 );
4623 XPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
4624 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
4625 descr->width, descr->height );
4627 if (!descr->image) XDestroyImage( bmpImage );
4628 wine_tsx11_unlock();
4632 /***********************************************************************
4633 * X11DRV_DIB_GetImageBits
4635 * Transfer the bits from an X image.
4637 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
4639 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
4644 bmpImage = descr->image;
4646 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
4647 descr->infoWidth, lines, 32, 0 );
4648 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
4649 if(bmpImage->data == NULL) {
4650 ERR("Out of memory!\n");
4651 XDestroyImage( bmpImage );
4652 wine_tsx11_unlock();
4659 int saveRed, saveGreen, saveBlue;
4661 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
4662 gdi_display, descr->drawable, bmpImage,
4663 descr->xSrc, descr->ySrc, AllPlanes);
4665 /* We must save and restore the bmpImage's masks in order
4666 * to preserve them across the call to XShmGetImage, which
4667 * decides to eleminate them since it doesn't happen to know
4668 * what the format of the image is supposed to be, even though
4670 saveRed = bmpImage->red_mask;
4671 saveBlue= bmpImage->blue_mask;
4672 saveGreen = bmpImage->green_mask;
4674 XShmGetImage( gdi_display, descr->drawable, bmpImage,
4675 descr->xSrc, descr->ySrc, AllPlanes);
4677 bmpImage->red_mask = saveRed;
4678 bmpImage->blue_mask = saveBlue;
4679 bmpImage->green_mask = saveGreen;
4683 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
4684 gdi_display, descr->drawable, descr->xSrc, descr->ySrc, descr->width,
4685 lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
4686 XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc,
4687 descr->width, lines, AllPlanes, ZPixmap,
4688 bmpImage, descr->xDest, descr->yDest );
4691 TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
4692 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
4693 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
4694 bmpImage->depth,bmpImage->bits_per_pixel,
4695 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4696 /* Transfer the pixels */
4697 switch(descr->infoBpp)
4700 X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
4701 descr->infoWidth, descr->width,
4702 descr->colorMap, descr->palentry,
4703 bmpImage, descr->dibpitch );
4707 if (descr->compression)
4708 FIXME("Compression not yet supported!\n");
4710 X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
4711 descr->infoWidth, descr->width,
4712 descr->colorMap, descr->palentry,
4713 bmpImage, descr->dibpitch );
4717 if (descr->compression)
4718 FIXME("Compression not yet supported!\n");
4720 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
4721 descr->infoWidth, descr->width,
4722 descr->colorMap, descr->palentry,
4723 bmpImage, descr->dibpitch );
4727 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
4728 descr->infoWidth,descr->width,
4730 descr->rMask, descr->gMask, descr->bMask,
4731 bmpImage, descr->dibpitch );
4735 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
4736 descr->infoWidth,descr->width,
4738 descr->rMask, descr->gMask, descr->bMask,
4739 bmpImage, descr->dibpitch);
4743 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
4744 descr->infoWidth, descr->width,
4746 descr->rMask, descr->gMask, descr->bMask,
4747 bmpImage, descr->dibpitch);
4751 WARN("(%d): Invalid depth\n", descr->infoBpp );
4755 if (!descr->image) XDestroyImage( bmpImage );
4756 wine_tsx11_unlock();
4760 /*************************************************************************
4761 * X11DRV_SetDIBitsToDevice
4764 INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWORD cx,
4765 DWORD cy, INT xSrc, INT ySrc,
4766 UINT startscan, UINT lines, LPCVOID bits,
4767 const BITMAPINFO *info, UINT coloruse )
4769 X11DRV_DIB_IMAGEBITS_DESCR descr;
4775 DC *dc = physDev->dc;
4777 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
4778 &descr.infoBpp, &descr.compression ) == -1)
4780 top_down = (height < 0);
4781 if (top_down) height = -height;
4785 LPtoDP(physDev->hdc, &pt, 1);
4787 if (!lines || (startscan >= height)) return 0;
4788 if (!top_down && startscan + lines > height) lines = height - startscan;
4790 /* make xSrc,ySrc point to the upper-left corner, not the lower-left one,
4791 * and clamp all values to fit inside [startscan,startscan+lines]
4793 if (ySrc + cy <= startscan + lines)
4795 INT y = startscan + lines - (ySrc + cy);
4796 if (ySrc < startscan) cy -= (startscan - ySrc);
4799 /* avoid getting unnecessary lines */
4801 if (y >= lines) return 0;
4806 if (y >= lines) return lines;
4807 ySrc = y; /* need to get all lines in top down mode */
4812 if (ySrc >= startscan + lines) return lines;
4813 pt.y += ySrc + cy - (startscan + lines);
4814 cy = startscan + lines - ySrc;
4816 if (cy > lines) cy = lines;
4818 if (xSrc >= width) return lines;
4819 if (xSrc + cx >= width) cx = width - xSrc;
4820 if (!cx || !cy) return lines;
4822 X11DRV_SetupGCForText( physDev ); /* To have the correct colors */
4823 TSXSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[dc->ROPmode-1]);
4825 switch (descr.infoBpp)
4830 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
4831 coloruse == DIB_PAL_COLORS ? physDev : NULL, coloruse,
4832 dc->bitsPerPixel, info, &descr.nColorMap );
4833 if (!descr.colorMap) return 0;
4834 descr.rMask = descr.gMask = descr.bMask = 0;
4838 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
4839 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
4840 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
4846 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
4847 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
4848 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
4853 descr.physDev = physDev;
4856 descr.palentry = NULL;
4857 descr.lines = top_down ? -lines : lines;
4858 descr.infoWidth = width;
4859 descr.depth = dc->bitsPerPixel;
4860 descr.drawable = physDev->drawable;
4861 descr.gc = physDev->gc;
4864 descr.xDest = physDev->org.x + pt.x;
4865 descr.yDest = physDev->org.y + pt.y;
4868 descr.useShm = FALSE;
4869 descr.dibpitch = ((width * descr.infoBpp + 31) &~31) / 8;
4871 result = X11DRV_DIB_SetImageBits( &descr );
4873 if (descr.infoBpp <= 8)
4874 HeapFree(GetProcessHeap(), 0, descr.colorMap);
4878 /***********************************************************************
4879 * SetDIBits (X11DRV.@)
4881 INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
4882 UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse )
4884 X11DRV_DIB_IMAGEBITS_DESCR descr;
4886 int height, tmpheight;
4889 descr.physDev = physDev;
4891 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
4892 &descr.infoBpp, &descr.compression ) == -1)
4896 if (height < 0) height = -height;
4897 if (!lines || (startscan >= height))
4900 if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
4902 if (startscan + lines > height) lines = height - startscan;
4904 switch (descr.infoBpp)
4909 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
4910 coloruse == DIB_PAL_COLORS ? descr.physDev : NULL, coloruse,
4911 bmp->bitmap.bmBitsPixel,
4912 info, &descr.nColorMap );
4913 if (!descr.colorMap)
4915 GDI_ReleaseObj( hbitmap );
4918 descr.rMask = descr.gMask = descr.bMask = 0;
4922 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
4923 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
4924 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
4930 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
4931 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
4932 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
4941 descr.palentry = NULL;
4942 descr.lines = tmpheight >= 0 ? lines : -lines;
4943 descr.depth = bmp->bitmap.bmBitsPixel;
4944 descr.drawable = (Pixmap)bmp->physBitmap;
4945 descr.gc = BITMAP_GC(bmp);
4949 descr.yDest = height - startscan - lines;
4950 descr.width = bmp->bitmap.bmWidth;
4951 descr.height = lines;
4952 descr.useShm = FALSE;
4953 descr.dibpitch = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
4954 X11DRV_DIB_Lock(bmp, DIB_Status_GdiMod, FALSE);
4955 result = X11DRV_DIB_SetImageBits( &descr );
4956 X11DRV_DIB_Unlock(bmp, TRUE);
4958 if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);
4960 GDI_ReleaseObj( hbitmap );
4964 /***********************************************************************
4965 * GetDIBits (X11DRV.@)
4967 INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan, UINT lines,
4968 LPVOID bits, BITMAPINFO *info, UINT coloruse )
4970 X11DRV_DIBSECTION *dib;
4971 X11DRV_DIB_IMAGEBITS_DESCR descr;
4972 PALETTEOBJ * palette;
4975 DC *dc = physDev->dc;
4977 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC )))
4979 if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
4981 GDI_ReleaseObj( dc->hPalette );
4984 dib = (X11DRV_DIBSECTION *) bmp->dib;
4986 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
4987 lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
4988 (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
4991 if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
4993 height = info->bmiHeader.biHeight;
4994 if (height < 0) height = -height;
4995 if( lines > height ) lines = height;
4996 /* Top-down images have a negative biHeight, the scanlines of theses images
4997 * were inverted in X11DRV_DIB_GetImageBits_xx
4998 * To prevent this we simply change the sign of lines
4999 * (the number of scan lines to copy).
5000 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
5002 if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
5004 if( startscan >= bmp->bitmap.bmHeight )
5010 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
5011 &descr.infoBpp, &descr.compression ) == -1)
5017 switch (descr.infoBpp)
5022 descr.rMask= descr.gMask = descr.bMask = 0;
5026 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
5027 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
5028 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
5032 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
5033 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
5034 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
5038 descr.physDev = physDev;
5039 descr.palentry = palette->logpalette.palPalEntry;
5042 descr.lines = lines;
5043 descr.depth = bmp->bitmap.bmBitsPixel;
5044 descr.drawable = (Pixmap)bmp->physBitmap;
5045 descr.gc = BITMAP_GC(bmp);
5046 descr.width = bmp->bitmap.bmWidth;
5047 descr.height = bmp->bitmap.bmHeight;
5048 descr.colorMap = info->bmiColors;
5053 if (descr.lines > 0)
5055 descr.ySrc = (descr.height-1) - (startscan + (lines-1));
5059 descr.ySrc = startscan;
5061 #ifdef HAVE_LIBXXSHM
5062 descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
5064 descr.useShm = FALSE;
5066 descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
5067 : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
5069 X11DRV_DIB_Lock(bmp, DIB_Status_GdiMod, FALSE);
5070 X11DRV_DIB_GetImageBits( &descr );
5071 X11DRV_DIB_Unlock(bmp, TRUE);
5073 if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
5074 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
5075 info->bmiHeader.biWidth,
5076 info->bmiHeader.biHeight,
5077 info->bmiHeader.biBitCount );
5079 if (descr.compression == BI_BITFIELDS)
5081 *(DWORD *)info->bmiColors = descr.rMask;
5082 *((DWORD *)info->bmiColors+1) = descr.gMask;
5083 *((DWORD *)info->bmiColors+2) = descr.bMask;
5087 /* if RLE or JPEG compression were supported,
5088 * this line would be invalid. */
5089 info->bmiHeader.biCompression = 0;
5093 GDI_ReleaseObj( dc->hPalette );
5094 GDI_ReleaseObj( hbitmap );
5098 /***********************************************************************
5099 * DIB_DoProtectDIBSection
5101 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
5103 DIBSECTION *dib = bmp->dib;
5104 INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
5105 : -dib->dsBm.bmHeight;
5106 /* use the biSizeImage data as the memory size only if we're dealing with a
5107 compressed image where the value is set. Otherwise, calculate based on
5109 INT totalSize = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
5110 ? dib->dsBmih.biSizeImage
5111 : dib->dsBm.bmWidthBytes * effHeight;
5114 VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
5115 TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
5118 /***********************************************************************
5119 * X11DRV_DIB_DoUpdateDIBSection
5121 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
5122 void *colorMap, int nColorMap,
5124 DWORD xSrc, DWORD ySrc,
5125 DWORD xDest, DWORD yDest,
5126 DWORD width, DWORD height)
5128 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5129 X11DRV_DIB_IMAGEBITS_DESCR descr;
5131 if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
5132 &descr.infoBpp, &descr.compression ) == -1)
5135 descr.physDev = NULL;
5136 descr.palentry = NULL;
5137 descr.image = dib->image;
5138 descr.colorMap = colorMap;
5139 descr.nColorMap = nColorMap;
5140 descr.bits = dib->dibSection.dsBm.bmBits;
5141 descr.depth = bmp->bitmap.bmBitsPixel;
5143 switch (descr.infoBpp)
5148 descr.rMask = descr.gMask = descr.bMask = 0;
5152 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
5153 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
5154 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
5159 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff0000;
5160 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x00ff00;
5161 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x0000ff;
5166 descr.drawable = dest;
5167 descr.gc = BITMAP_GC(bmp);
5170 descr.xDest = xDest;
5171 descr.yDest = yDest;
5172 descr.width = width;
5173 descr.height = height;
5174 #ifdef HAVE_LIBXXSHM
5175 descr.useShm = (dib->shminfo.shmid != -1);
5177 descr.useShm = FALSE;
5179 descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
5183 TRACE("Copying from Pixmap to DIB bits\n");
5184 X11DRV_DIB_GetImageBits( &descr );
5188 TRACE("Copying from DIB bits to Pixmap\n");
5189 X11DRV_DIB_SetImageBits( &descr );
5193 /***********************************************************************
5194 * X11DRV_DIB_CopyDIBSection
5196 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
5197 DWORD xSrc, DWORD ySrc, DWORD xDest, DWORD yDest,
5198 DWORD width, DWORD height)
5201 DC *dcSrc = physDevSrc->dc;
5202 DC *dcDst = physDevDst->dc;
5203 int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE;
5205 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc, dcDst,
5206 xSrc, ySrc, xDest, yDest, width, height);
5207 /* this function is meant as an optimization for BitBlt,
5208 * not to be called otherwise */
5209 if (!(dcSrc->flags & DC_MEMORY)) {
5210 ERR("called for non-memory source DC!?\n");
5214 bmp = (BITMAPOBJ *)GDI_GetObjPtr( dcSrc->hBitmap, BITMAP_MAGIC );
5215 if (!(bmp && bmp->dib)) {
5216 ERR("called for non-DIBSection!?\n");
5217 GDI_ReleaseObj( dcSrc->hBitmap );
5220 /* while BitBlt should already have made sure we only get
5221 * positive values, we should check for oversize values */
5222 if ((xSrc < bmp->bitmap.bmWidth) &&
5223 (ySrc < bmp->bitmap.bmHeight)) {
5224 if (xSrc + width > bmp->bitmap.bmWidth)
5225 width = bmp->bitmap.bmWidth - xSrc;
5226 if (ySrc + height > bmp->bitmap.bmHeight)
5227 height = bmp->bitmap.bmHeight - ySrc;
5228 /* if the source bitmap is 8bpp or less, we're supposed to use the
5229 * DC's palette for color conversion (not the DIB color table) */
5230 if (bmp->dib->dsBm.bmBitsPixel <= 8) {
5231 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5232 if ((!dcSrc->hPalette) ||
5233 (dcSrc->hPalette == GetStockObject(DEFAULT_PALETTE))) {
5234 /* HACK: no palette has been set in the source DC,
5235 * use the DIB colormap instead - this is necessary in some
5236 * cases since we need to do depth conversion in some places
5237 * where real Windows can just copy data straight over */
5238 colorMap = dib->colorMap;
5239 nColorMap = dib->nColorMap;
5241 colorMap = X11DRV_DIB_BuildColorMap( physDevSrc, (WORD)-1,
5242 bmp->dib->dsBm.bmBitsPixel,
5243 (BITMAPINFO*)&(bmp->dib->dsBmih),
5245 if (colorMap) aColorMap = TRUE;
5248 /* perform the copy */
5249 X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap,
5250 physDevDst->drawable, xSrc, ySrc,
5251 physDevDst->org.x + xDest, physDevDst->org.y + yDest,
5253 /* free color mapping */
5255 HeapFree(GetProcessHeap(), 0, colorMap);
5257 GDI_ReleaseObj( dcSrc->hBitmap );
5260 /***********************************************************************
5261 * X11DRV_DIB_DoUpdateDIBSection
5263 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
5265 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5266 X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap,
5267 (Drawable)bmp->physBitmap, 0, 0, 0, 0,
5268 bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
5271 /***********************************************************************
5272 * X11DRV_DIB_FaultHandler
5274 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
5279 bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
5280 if (!bmp) return FALSE;
5282 state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
5283 if (state != DIB_Status_InSync) {
5284 /* no way to tell whether app needs read or write yet,
5286 X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
5288 /* hm, apparently the app must have write access */
5289 X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
5291 X11DRV_DIB_Unlock(bmp, TRUE);
5293 GDI_ReleaseObj( (HBITMAP)res );
5297 /***********************************************************************
5300 INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
5302 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5303 INT ret = DIB_Status_None;
5306 EnterCriticalSection(&(dib->lock));
5309 case DIB_Status_GdiMod:
5310 /* GDI access - request to draw on pixmap */
5311 switch (dib->status)
5314 case DIB_Status_None:
5315 dib->p_status = DIB_Status_GdiMod;
5316 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
5319 case DIB_Status_GdiMod:
5320 TRACE("GdiMod requested in status GdiMod\n" );
5323 case DIB_Status_InSync:
5324 TRACE("GdiMod requested in status InSync\n" );
5325 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5326 dib->status = DIB_Status_GdiMod;
5327 dib->p_status = DIB_Status_InSync;
5330 case DIB_Status_AuxMod:
5331 TRACE("GdiMod requested in status AuxMod\n" );
5332 if (lossy) dib->status = DIB_Status_GdiMod;
5333 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
5334 dib->p_status = DIB_Status_AuxMod;
5335 if (dib->status != DIB_Status_AppMod) {
5336 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5339 /* fall through if copy_aux() had to change to AppMod state */
5341 case DIB_Status_AppMod:
5342 TRACE("GdiMod requested in status AppMod\n" );
5344 /* make it readonly to avoid app changing data while we copy */
5345 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5346 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
5348 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5349 dib->p_status = DIB_Status_AppMod;
5350 dib->status = DIB_Status_GdiMod;
5355 case DIB_Status_InSync:
5356 /* App access - request access to read DIB surface */
5357 /* (typically called from signal handler) */
5358 switch (dib->status)
5361 case DIB_Status_None:
5362 /* shouldn't happen from signal handler */
5365 case DIB_Status_AuxMod:
5366 TRACE("InSync requested in status AuxMod\n" );
5367 if (lossy) dib->status = DIB_Status_InSync;
5369 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5370 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
5372 if (dib->status != DIB_Status_GdiMod) {
5373 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5376 /* fall through if copy_aux() had to change to GdiMod state */
5378 case DIB_Status_GdiMod:
5379 TRACE("InSync requested in status GdiMod\n" );
5381 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5382 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
5384 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5385 dib->status = DIB_Status_InSync;
5388 case DIB_Status_InSync:
5389 TRACE("InSync requested in status InSync\n" );
5390 /* shouldn't happen from signal handler */
5393 case DIB_Status_AppMod:
5394 TRACE("InSync requested in status AppMod\n" );
5395 /* no reason to do anything here, and this
5396 * shouldn't happen from signal handler */
5401 case DIB_Status_AppMod:
5402 /* App access - request access to write DIB surface */
5403 /* (typically called from signal handler) */
5404 switch (dib->status)
5407 case DIB_Status_None:
5408 /* shouldn't happen from signal handler */
5411 case DIB_Status_AuxMod:
5412 TRACE("AppMod requested in status AuxMod\n" );
5413 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5414 if (lossy) dib->status = DIB_Status_AppMod;
5415 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
5416 if (dib->status != DIB_Status_GdiMod)
5418 /* fall through if copy_aux() had to change to GdiMod state */
5420 case DIB_Status_GdiMod:
5421 TRACE("AppMod requested in status GdiMod\n" );
5422 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5423 if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
5424 dib->status = DIB_Status_AppMod;
5427 case DIB_Status_InSync:
5428 TRACE("AppMod requested in status InSync\n" );
5429 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5430 dib->status = DIB_Status_AppMod;
5433 case DIB_Status_AppMod:
5434 TRACE("AppMod requested in status AppMod\n" );
5435 /* shouldn't happen from signal handler */
5440 case DIB_Status_AuxMod:
5441 if (dib->status == DIB_Status_None) {
5442 dib->p_status = req;
5444 if (dib->status != DIB_Status_AuxMod)
5445 dib->p_status = dib->status;
5446 dib->status = DIB_Status_AuxMod;
5449 /* it is up to the caller to do the copy/conversion, probably
5450 * using the return value to decide where to copy from */
5452 LeaveCriticalSection(&(dib->lock));
5457 /***********************************************************************
5460 INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
5462 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5463 INT ret = DIB_Status_None;
5466 TRACE("Locking %p from thread %08lx\n", bmp, GetCurrentThreadId());
5467 EnterCriticalSection(&(dib->lock));
5469 if (req != DIB_Status_None)
5470 X11DRV_DIB_Coerce(bmp, req, lossy);
5475 /***********************************************************************
5478 void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
5480 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5483 switch (dib->status)
5486 case DIB_Status_None:
5487 /* in case anyone is wondering, this is the "signal handler doesn't
5488 * work" case, where we always have to be ready for app access */
5490 switch (dib->p_status)
5492 case DIB_Status_AuxMod:
5493 TRACE("Unlocking and syncing from AuxMod\n" );
5494 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
5495 if (dib->status != DIB_Status_None) {
5496 dib->p_status = dib->status;
5497 dib->status = DIB_Status_None;
5499 if (dib->p_status != DIB_Status_GdiMod)
5501 /* fall through if copy_aux() had to change to GdiMod state */
5503 case DIB_Status_GdiMod:
5504 TRACE("Unlocking and syncing from GdiMod\n" );
5505 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
5509 TRACE("Unlocking without needing to sync\n" );
5513 else TRACE("Unlocking with no changes\n");
5514 dib->p_status = DIB_Status_None;
5517 case DIB_Status_GdiMod:
5518 TRACE("Unlocking in status GdiMod\n" );
5519 /* DIB was protected in Coerce */
5521 /* no commit, revert to InSync if applicable */
5522 if ((dib->p_status == DIB_Status_InSync) ||
5523 (dib->p_status == DIB_Status_AppMod)) {
5524 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5525 dib->status = DIB_Status_InSync;
5530 case DIB_Status_InSync:
5531 TRACE("Unlocking in status InSync\n" );
5532 /* DIB was already protected in Coerce */
5535 case DIB_Status_AppMod:
5536 TRACE("Unlocking in status AppMod\n" );
5537 /* DIB was already protected in Coerce */
5538 /* this case is ordinary only called from the signal handler,
5539 * so we don't bother to check for !commit */
5542 case DIB_Status_AuxMod:
5543 TRACE("Unlocking in status AuxMod\n" );
5545 /* DIB may need protection now */
5546 if ((dib->p_status == DIB_Status_InSync) ||
5547 (dib->p_status == DIB_Status_AppMod))
5548 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5550 /* no commit, revert to previous state */
5551 if (dib->p_status != DIB_Status_None)
5552 dib->status = dib->p_status;
5553 /* no protections changed */
5555 dib->p_status = DIB_Status_None;
5558 LeaveCriticalSection(&(dib->lock));
5559 TRACE("Unlocked %p\n", bmp);
5563 /***********************************************************************
5564 * X11DRV_CoerceDIBSection2
5566 INT X11DRV_CoerceDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
5571 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5572 if (!bmp) return DIB_Status_None;
5573 ret = X11DRV_DIB_Coerce(bmp, req, lossy);
5574 GDI_ReleaseObj( hBmp );
5578 /***********************************************************************
5579 * X11DRV_LockDIBSection2
5581 INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
5586 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5587 if (!bmp) return DIB_Status_None;
5588 ret = X11DRV_DIB_Lock(bmp, req, lossy);
5589 GDI_ReleaseObj( hBmp );
5593 /***********************************************************************
5594 * X11DRV_UnlockDIBSection2
5596 void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
5600 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5602 X11DRV_DIB_Unlock(bmp, commit);
5603 GDI_ReleaseObj( hBmp );
5606 /***********************************************************************
5607 * X11DRV_CoerceDIBSection
5609 INT X11DRV_CoerceDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
5611 if (!physDev) return DIB_Status_None;
5612 return X11DRV_CoerceDIBSection2( physDev->dc->hBitmap, req, lossy );
5615 /***********************************************************************
5616 * X11DRV_LockDIBSection
5618 INT X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
5620 if (!physDev) return DIB_Status_None;
5621 if (!(physDev->dc->flags & DC_MEMORY)) return DIB_Status_None;
5623 return X11DRV_LockDIBSection2( physDev->dc->hBitmap, req, lossy );
5626 /***********************************************************************
5627 * X11DRV_UnlockDIBSection
5629 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE *physDev, BOOL commit)
5631 if (!physDev) return;
5632 if (!(physDev->dc->flags & DC_MEMORY)) return;
5634 X11DRV_UnlockDIBSection2( physDev->dc->hBitmap, commit );
5638 #ifdef HAVE_LIBXXSHM
5639 /***********************************************************************
5640 * X11DRV_XShmErrorHandler
5643 static int XShmErrorHandler( Display *dpy, XErrorEvent *event, void *arg )
5645 return 1; /* FIXME: should check event contents */
5648 /***********************************************************************
5649 * X11DRV_XShmCreateImage
5652 static XImage *X11DRV_XShmCreateImage( int width, int height, int bpp,
5653 XShmSegmentInfo* shminfo)
5657 image = XShmCreateImage(gdi_display, visual, bpp, ZPixmap, NULL, shminfo, width, height);
5660 shminfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height,
5662 if( shminfo->shmid != -1 )
5664 shminfo->shmaddr = image->data = shmat(shminfo->shmid, 0, 0);
5665 if( shminfo->shmaddr != (char*)-1 )
5669 shminfo->readOnly = FALSE;
5670 X11DRV_expect_error( gdi_display, XShmErrorHandler, NULL );
5671 ok = (XShmAttach( gdi_display, shminfo ) != 0);
5672 if (X11DRV_check_error()) ok = FALSE;
5675 shmctl(shminfo->shmid, IPC_RMID, 0);
5676 return image; /* Success! */
5678 /* An error occured */
5679 shmdt(shminfo->shmaddr);
5681 shmctl(shminfo->shmid, IPC_RMID, 0);
5683 XFlush(gdi_display);
5684 XDestroyImage(image);
5689 #endif /* HAVE_LIBXXSHM */
5692 /***********************************************************************
5693 * X11DRV_DIB_CreateDIBSection
5695 HBITMAP X11DRV_DIB_CreateDIBSection(
5696 X11DRV_PDEVICE *physDev, BITMAPINFO *bmi, UINT usage,
5697 LPVOID *bits, HANDLE section,
5698 DWORD offset, DWORD ovr_pitch)
5701 BITMAPOBJ *bmp = NULL;
5702 X11DRV_DIBSECTION *dib = NULL;
5703 int *colorMap = NULL;
5706 /* Fill BITMAP32 structure with DIB data */
5707 BITMAPINFOHEADER *bi = &bmi->bmiHeader;
5708 INT effHeight, totalSize;
5710 LPVOID mapBits = NULL;
5712 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
5713 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
5714 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
5716 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
5718 bm.bmWidth = bi->biWidth;
5719 bm.bmHeight = effHeight;
5720 bm.bmWidthBytes = ovr_pitch ? ovr_pitch
5721 : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
5722 bm.bmPlanes = bi->biPlanes;
5723 bm.bmBitsPixel = bi->biBitCount;
5726 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
5727 we're dealing with a compressed bitmap. Otherwise, use width * height. */
5728 totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
5729 ? bi->biSizeImage : bm.bmWidthBytes * effHeight;
5733 SYSTEM_INFO SystemInfo;
5737 GetSystemInfo( &SystemInfo );
5738 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
5739 mapSize = totalSize + (offset - mapOffset);
5740 mapBits = MapViewOfFile( section,
5741 FILE_MAP_ALL_ACCESS,
5745 bm.bmBits = (char *)mapBits + (offset - mapOffset);
5747 else if (ovr_pitch && offset)
5748 bm.bmBits = (LPVOID) offset;
5751 bm.bmBits = VirtualAlloc(NULL, totalSize,
5752 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
5755 /* Create Color Map */
5756 if (bm.bmBits && bm.bmBitsPixel <= 8)
5757 colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? physDev : NULL,
5758 usage, bm.bmBitsPixel, bmi, &nColorMap );
5760 /* Allocate Memory for DIB and fill structure */
5762 dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
5765 dib->dibSection.dsBm = bm;
5766 dib->dibSection.dsBmih = *bi;
5767 dib->dibSection.dsBmih.biSizeImage = totalSize;
5769 /* Set dsBitfields values */
5770 if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
5772 dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
5774 else switch( bi->biBitCount )
5778 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
5779 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
5780 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
5785 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff0000;
5786 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x00ff00;
5787 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x0000ff;
5790 dib->dibSection.dshSection = section;
5791 dib->dibSection.dsOffset = offset;
5793 dib->status = DIB_Status_None;
5794 dib->nColorMap = nColorMap;
5795 dib->colorMap = colorMap;
5798 /* Create Device Dependent Bitmap and add DIB pointer */
5801 res = CreateDIBitmap(physDev->hdc, bi, 0, NULL, bmi, usage);
5804 bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
5805 if (bmp) bmp->dib = (DIBSECTION *) dib;
5813 #ifdef HAVE_LIBXXSHM
5814 if (XShmQueryExtension(gdi_display) &&
5815 (dib->image = X11DRV_XShmCreateImage( bm.bmWidth, effHeight,
5816 bmp->bitmap.bmBitsPixel, &dib->shminfo )) )
5818 ; /* Created Image */
5820 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
5821 dib->shminfo.shmid = -1;
5824 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
5826 wine_tsx11_unlock();
5829 /* Clean up in case of errors */
5830 if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
5832 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
5833 res, bmp, dib, bm.bmBits);
5837 UnmapViewOfFile(mapBits), bm.bmBits = NULL;
5839 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
5842 if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
5843 if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
5844 if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
5845 if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
5846 if (res) { DeleteObject(res); res = 0; }
5850 /* Install fault handler, if possible */
5851 InitializeCriticalSection(&(dib->lock));
5852 if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
5854 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5855 if (dib) dib->status = DIB_Status_AppMod;
5859 /* Return BITMAP handle and storage location */
5860 if (bmp) GDI_ReleaseObj(res);
5861 if (bm.bmBits && bits) *bits = bm.bmBits;
5865 /***********************************************************************
5866 * X11DRV_DIB_DeleteDIBSection
5868 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
5870 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5875 #ifdef HAVE_LIBXXSHM
5876 if (dib->shminfo.shmid != -1)
5878 XShmDetach (gdi_display, &(dib->shminfo));
5879 XDestroyImage (dib->image);
5880 shmdt (dib->shminfo.shmaddr);
5881 dib->shminfo.shmid = -1;
5885 XDestroyImage( dib->image );
5886 wine_tsx11_unlock();
5890 HeapFree(GetProcessHeap(), 0, dib->colorMap);
5892 DeleteCriticalSection(&(dib->lock));
5895 /***********************************************************************
5896 * SetDIBColorTable (X11DRV.@)
5898 UINT X11DRV_SetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, const RGBQUAD *colors )
5901 X11DRV_DIBSECTION *dib;
5904 if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( physDev->dc->hBitmap, BITMAP_MAGIC ))) return 0;
5905 dib = (X11DRV_DIBSECTION *) bmp->dib;
5907 if (dib && dib->colorMap) {
5908 UINT end = count + start;
5909 if (end > dib->nColorMap) end = dib->nColorMap;
5911 * Changing color table might change the mapping between
5912 * DIB colors and X11 colors and thus alter the visible state
5913 * of the bitmap object.
5915 X11DRV_DIB_Lock(bmp, DIB_Status_AppMod, FALSE);
5916 X11DRV_DIB_GenColorMap( physDev, dib->colorMap, DIB_RGB_COLORS,
5917 dib->dibSection.dsBm.bmBitsPixel,
5918 TRUE, colors, start, end );
5919 X11DRV_DIB_Unlock(bmp, TRUE);
5922 GDI_ReleaseObj( physDev->dc->hBitmap );
5926 /***********************************************************************
5927 * GetDIBColorTable (X11DRV.@)
5929 UINT X11DRV_GetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, RGBQUAD *colors )
5932 X11DRV_DIBSECTION *dib;
5935 if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( physDev->dc->hBitmap, BITMAP_MAGIC ))) return 0;
5936 dib = (X11DRV_DIBSECTION *) bmp->dib;
5938 if (dib && dib->colorMap) {
5939 UINT i, end = count + start;
5940 if (end > dib->nColorMap) end = dib->nColorMap;
5941 for (i = start; i < end; i++,colors++) {
5942 COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] );
5943 colors->rgbBlue = GetBValue(col);
5944 colors->rgbGreen = GetGValue(col);
5945 colors->rgbRed = GetRValue(col);
5946 colors->rgbReserved = 0;
5950 GDI_ReleaseObj( physDev->dc->hBitmap );
5955 /**************************************************************************
5956 * X11DRV_DIB_CreateDIBFromPixmap
5958 * Allocates a packed DIB and copies the Pixmap data into it.
5959 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
5961 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
5964 BITMAPOBJ *pBmp = NULL;
5965 HGLOBAL hPackedDIB = 0;
5967 /* Allocates an HBITMAP which references the Pixmap passed to us */
5968 hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap);
5971 TRACE("\tCould not create bitmap header for Pixmap\n");
5976 * Create a packed DIB from the Pixmap wrapper bitmap created above.
5977 * A packed DIB contains a BITMAPINFO structure followed immediately by
5978 * an optional color palette and the pixel data.
5980 hPackedDIB = DIB_CreateDIBFromBitmap(hdc, hBmp);
5982 /* Get a pointer to the BITMAPOBJ structure */
5983 pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5985 /* We can now get rid of the HBITMAP wrapper we created earlier.
5986 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
5990 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
5991 pBmp->physBitmap = NULL;
5994 GDI_ReleaseObj( hBmp );
5998 TRACE("\tReturning packed DIB %x\n", hPackedDIB);
6003 /**************************************************************************
6004 * X11DRV_DIB_CreatePixmapFromDIB
6006 * Creates a Pixmap from a packed DIB
6008 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
6010 Pixmap pixmap = None;
6012 BITMAPOBJ *pBmp = NULL;
6013 LPBYTE pPackedDIB = NULL;
6014 LPBITMAPINFO pbmi = NULL;
6015 LPBITMAPINFOHEADER pbmiHeader = NULL;
6016 LPBYTE pbits = NULL;
6018 /* Get a pointer to the packed DIB's data */
6019 pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
6020 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
6021 pbmi = (LPBITMAPINFO)pPackedDIB;
6022 pbits = (LPBYTE)(pPackedDIB
6023 + DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
6025 /* Create a DDB from the DIB */
6027 hBmp = CreateDIBitmap(hdc,
6034 GlobalUnlock(hPackedDIB);
6036 TRACE("CreateDIBitmap returned %x\n", hBmp);
6038 /* Retrieve the internal Pixmap from the DDB */
6040 pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
6042 pixmap = (Pixmap)pBmp->physBitmap;
6043 /* clear the physBitmap so that we can steal its pixmap */
6044 pBmp->physBitmap = NULL;
6047 /* Delete the DDB we created earlier now that we have stolen its pixmap */
6048 GDI_ReleaseObj( hBmp );
6051 TRACE("\tReturning Pixmap %ld\n", pixmap);