2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <X11/extensions/XShm.h>
26 # ifdef HAVE_SYS_SHM_H
29 # ifdef HAVE_SYS_IPC_H
32 #endif /* defined(HAVE_LIBXXSHM) */
41 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
47 WINE_DECLARE_DEBUG_CHANNEL(x11drv);
49 static int ximageDepthTable[32];
51 /* This structure holds the arguments for DIB_SetImageBits() */
54 X11DRV_PDEVICE *physDev;
57 PALETTEENTRY *palentry;
78 } X11DRV_DIB_IMAGEBITS_DESCR;
83 RLE_EOL = 0, /* End of line */
84 RLE_END = 1, /* End of bitmap */
85 RLE_DELTA = 2 /* Delta */
88 /***********************************************************************
89 * X11DRV_DIB_GetXImageWidthBytes
91 * Return the width of an X image in bytes
93 inline static int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
95 if (!depth || depth > 32) goto error;
97 if (!ximageDepthTable[depth-1])
99 XImage *testimage = XCreateImage( gdi_display, visual, depth,
100 ZPixmap, 0, NULL, 1, 1, 32, 20 );
103 ximageDepthTable[depth-1] = testimage->bits_per_pixel;
104 XDestroyImage( testimage );
106 else ximageDepthTable[depth-1] = -1;
108 if (ximageDepthTable[depth-1] != -1)
109 return (4 * ((width * ximageDepthTable[depth-1] + 31) / 32));
112 WARN( "(%d): Unsupported depth\n", depth );
117 /***********************************************************************
118 * X11DRV_DIB_CreateXImage
122 XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth )
128 width_bytes = X11DRV_DIB_GetXImageWidthBytes( width, depth );
129 image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0,
130 calloc( height, width_bytes ),
131 width, height, 32, width_bytes );
137 /***********************************************************************
140 * Get the info from a bitmap header.
141 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
143 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
144 int *height, WORD *bpp, WORD *compr )
146 if (header->biSize == sizeof(BITMAPCOREHEADER))
148 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
149 *width = core->bcWidth;
150 *height = core->bcHeight;
151 *bpp = core->bcBitCount;
155 if (header->biSize >= sizeof(BITMAPINFOHEADER))
157 *width = header->biWidth;
158 *height = header->biHeight;
159 *bpp = header->biBitCount;
160 *compr = header->biCompression;
163 ERR("(%ld): unknown/wrong size for header\n", header->biSize );
168 /***********************************************************************
169 * X11DRV_DIB_GenColorMap
171 * Fills the color map of a bitmap palette. Should not be called
172 * for a >8-bit deep bitmap.
174 int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
175 WORD coloruse, WORD depth, BOOL quads,
176 const void *colorPtr, int start, int end )
180 if (coloruse == DIB_RGB_COLORS)
182 int max = 1 << depth;
184 if (end > max) end = max;
188 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
190 if (depth == 1) /* Monochrome */
191 for (i = start; i < end; i++, rgb++)
192 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
193 rgb->rgbBlue > 255*3/2);
195 for (i = start; i < end; i++, rgb++)
196 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbRed,
202 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
204 if (depth == 1) /* Monochrome */
205 for (i = start; i < end; i++, rgb++)
206 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
207 rgb->rgbtBlue > 255*3/2);
209 for (i = start; i < end; i++, rgb++)
210 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbtRed,
215 else /* DIB_PAL_COLORS */
218 WORD * index = (WORD *)colorPtr;
220 for (i = start; i < end; i++, index++)
221 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(*index) );
223 for (i = start; i < end; i++)
224 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(i) );
231 /***********************************************************************
232 * X11DRV_DIB_BuildColorMap
234 * Build the color map from the bitmap palette. Should not be called
235 * for a >8-bit deep bitmap.
237 int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
238 const BITMAPINFO *info, int *nColors )
242 const void *colorPtr;
245 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
247 colors = info->bmiHeader.biClrUsed;
248 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
249 colorPtr = info->bmiColors;
251 else /* assume BITMAPCOREINFO */
253 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
254 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
259 ERR("called with >256 colors!\n");
263 /* just so CopyDIBSection doesn't have to create an identity palette */
264 if (coloruse == (WORD)-1) colorPtr = NULL;
266 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
267 colors * sizeof(int) )))
271 return X11DRV_DIB_GenColorMap( physDev, colorMapping, coloruse, depth,
272 isInfo, colorPtr, 0, colors);
276 /***********************************************************************
277 * X11DRV_DIB_MapColor
279 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
283 if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
286 for (color = 0; color < nPhysMap; color++)
287 if (physMap[color] == phys)
290 WARN("Strange color %08x\n", phys);
295 /*********************************************************************
296 * X11DRV_DIB_GetNearestIndex
298 * Helper for X11DRV_DIB_GetDIBits.
299 * Returns the nearest colour table index for a given RGB.
300 * Nearest is defined by minimizing the sum of the squares.
302 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
304 INT i, best = -1, diff, bestdiff = -1;
307 for(color = colormap, i = 0; i < numColors; color++, i++) {
308 diff = (r - color->rgbRed) * (r - color->rgbRed) +
309 (g - color->rgbGreen) * (g - color->rgbGreen) +
310 (b - color->rgbBlue) * (b - color->rgbBlue);
313 if(best == -1 || diff < bestdiff) {
320 /*********************************************************************
321 * X11DRV_DIB_MaskToShift
323 * Helper for X11DRV_DIB_GetDIBits.
324 * Returns the by how many bits to shift a given color so that it is
325 * in the proper position.
327 static INT X11DRV_DIB_MaskToShift(DWORD mask)
335 while ((mask&1)==0) {
342 /***********************************************************************
343 * X11DRV_DIB_Convert_any_asis
345 * All X11DRV_DIB_Convert_Xxx functions take at least the following
348 * This is the width in pixel of the surface to copy. This may be less
349 * than the full width of the image.
351 * The number of lines to copy. This may be less than the full height
352 * of the image. This is always >0.
354 * Points to the first byte containing data to be copied. If the source
355 * surface starts are coordinates (x,y) then this is:
356 * image_ptr+x*bytes_pre_pixel+y*bytes_per_line
357 * (with further adjustments for top-down/bottom-up images)
359 * This is the number of bytes per line. It may be >0 or <0 depending on
360 * whether this is a top-down or bottom-up image.
362 * Same as srcbits but for the destination
364 * Same as srclinebytes but for the destination.
367 * - The supported Dib formats are: pal1, pal4, pal8, rgb555, bgr555,
368 * rgb565, bgr565, rgb888 and any 32bit (0888) format.
369 * The supported XImage (Bmp) formats are: pal1, pal4, pal8,
370 * rgb555, bgr555, rgb565, bgr565, rgb888, bgr888, rgb0888, bgr0888.
371 * - Rgb formats are those for which the masks are such that:
372 * red_mask > green_mask > blue_mask
373 * - Bgr formats are those for which the masks sort in the other direction.
374 * - Many conversion functions handle both rgb->bgr and bgr->rgb conversions
375 * so the comments use h, g, l to mean respectively the source color in the
376 * high bits, the green, and the source color in the low bits.
378 static void X11DRV_DIB_Convert_any_asis(int width, int height,
380 const void* srcbits, int srclinebytes,
381 void* dstbits, int dstlinebytes)
385 width*=bytes_per_pixel;
386 for (y=0; y<height; y++) {
387 memcpy(dstbits, srcbits, width);
388 srcbits = (char*)srcbits + srclinebytes;
389 dstbits = (char*)dstbits + dstlinebytes;
397 static void X11DRV_DIB_Convert_555_reverse(int width, int height,
398 const void* srcbits, int srclinebytes,
399 void* dstbits, int dstlinebytes)
401 const DWORD* srcpixel;
405 for (y=0; y<height; y++) {
408 for (x=0; x<width/2; x++) {
409 /* Do 2 pixels at a time */
412 *dstpixel++=((srcval << 10) & 0x7c007c00) | /* h */
413 ( srcval & 0x03e003e0) | /* g */
414 ((srcval >> 10) & 0x001f001f); /* l */
417 /* And the the odd pixel */
419 srcval=*((WORD*)srcpixel);
420 *((WORD*)dstpixel)=((srcval << 10) & 0x7c00) | /* h */
421 ( srcval & 0x03e0) | /* g */
422 ((srcval >> 10) & 0x001f); /* l */
424 srcbits = (char*)srcbits + srclinebytes;
425 dstbits = (char*)dstbits + dstlinebytes;
429 static void X11DRV_DIB_Convert_555_to_565_asis(int width, int height,
430 const void* srcbits, int srclinebytes,
431 void* dstbits, int dstlinebytes)
433 const DWORD* srcpixel;
437 for (y=0; y<height; y++) {
440 for (x=0; x<width/2; x++) {
441 /* Do 2 pixels at a time */
444 *dstpixel++=((srcval << 1) & 0xffc0ffc0) | /* h, g */
445 ((srcval >> 4) & 0x00200020) | /* g - 1 bit */
446 ( srcval & 0x001f001f); /* l */
449 /* And the the odd pixel */
451 srcval=*((WORD*)srcpixel);
452 *((WORD*)dstpixel)=((srcval << 1) & 0xffc0) | /* h, g */
453 ((srcval >> 4) & 0x0020) | /* g - 1 bit */
454 (srcval & 0x001f); /* l */
456 srcbits = (char*)srcbits + srclinebytes;
457 dstbits = (char*)dstbits + dstlinebytes;
461 static void X11DRV_DIB_Convert_555_to_565_reverse(int width, int height,
462 const void* srcbits, int srclinebytes,
463 void* dstbits, int dstlinebytes)
465 const DWORD* srcpixel;
469 for (y=0; y<height; y++) {
472 for (x=0; x<width/2; x++) {
473 /* Do 2 pixels at a time */
476 *dstpixel++=((srcval >> 10) & 0x001f001f) | /* h */
477 ((srcval << 1) & 0x07c007c0) | /* g */
478 ((srcval >> 4) & 0x00200020) | /* g - 1 bit */
479 ((srcval << 11) & 0xf800f800); /* l */
482 /* And the the odd pixel */
484 srcval=*((WORD*)srcpixel);
485 *((WORD*)dstpixel)=((srcval >> 10) & 0x001f) | /* h */
486 ((srcval << 1) & 0x07c0) | /* g */
487 ((srcval >> 4) & 0x0020) | /* g - 1 bit */
488 ((srcval << 11) & 0xf800); /* l */
490 srcbits = (char*)srcbits + srclinebytes;
491 dstbits = (char*)dstbits + dstlinebytes;
495 static void X11DRV_DIB_Convert_555_to_888_asis(int width, int height,
496 const void* srcbits, int srclinebytes,
497 void* dstbits, int dstlinebytes)
499 const WORD* srcpixel;
503 for (y=0; y<height; y++) {
506 for (x=0; x<width; x++) {
509 dstpixel[0]=((srcval << 3) & 0xf8) | /* l */
510 ((srcval >> 2) & 0x07); /* l - 3 bits */
511 dstpixel[1]=((srcval >> 2) & 0xf8) | /* g */
512 ((srcval >> 7) & 0x07); /* g - 3 bits */
513 dstpixel[2]=((srcval >> 7) & 0xf8) | /* h */
514 ((srcval >> 12) & 0x07); /* h - 3 bits */
517 srcbits = (char*)srcbits + srclinebytes;
518 dstbits = (char*)dstbits + dstlinebytes;
522 static void X11DRV_DIB_Convert_555_to_888_reverse(int width, int height,
523 const void* srcbits, int srclinebytes,
524 void* dstbits, int dstlinebytes)
526 const WORD* srcpixel;
530 for (y=0; y<height; y++) {
533 for (x=0; x<width; x++) {
536 dstpixel[0]=((srcval >> 7) & 0xf8) | /* h */
537 ((srcval >> 12) & 0x07); /* h - 3 bits */
538 dstpixel[1]=((srcval >> 2) & 0xf8) | /* g */
539 ((srcval >> 7) & 0x07); /* g - 3 bits */
540 dstpixel[2]=((srcval << 3) & 0xf8) | /* l */
541 ((srcval >> 2) & 0x07); /* l - 3 bits */
544 srcbits = (char*)srcbits + srclinebytes;
545 dstbits = (char*)dstbits + dstlinebytes;
549 static void X11DRV_DIB_Convert_555_to_0888_asis(int width, int height,
550 const void* srcbits, int srclinebytes,
551 void* dstbits, int dstlinebytes)
553 const WORD* srcpixel;
557 for (y=0; y<height; y++) {
560 for (x=0; x<width; x++) {
563 *dstpixel++=((srcval << 9) & 0xf80000) | /* h */
564 ((srcval << 4) & 0x070000) | /* h - 3 bits */
565 ((srcval << 6) & 0x00f800) | /* g */
566 ((srcval << 1) & 0x000700) | /* g - 3 bits */
567 ((srcval << 3) & 0x0000f8) | /* l */
568 ((srcval >> 2) & 0x000007); /* l - 3 bits */
570 srcbits = (char*)srcbits + srclinebytes;
571 dstbits = (char*)dstbits + dstlinebytes;
575 static void X11DRV_DIB_Convert_555_to_0888_reverse(int width, int height,
576 const void* srcbits, int srclinebytes,
577 void* dstbits, int dstlinebytes)
579 const WORD* srcpixel;
583 for (y=0; y<height; y++) {
586 for (x=0; x<width; x++) {
589 *dstpixel++=((srcval >> 7) & 0x0000f8) | /* h */
590 ((srcval >> 12) & 0x000007) | /* h - 3 bits */
591 ((srcval << 6) & 0x00f800) | /* g */
592 ((srcval << 1) & 0x000700) | /* g - 3 bits */
593 ((srcval << 19) & 0xf80000) | /* l */
594 ((srcval << 14) & 0x070000); /* l - 3 bits */
596 srcbits = (char*)srcbits + srclinebytes;
597 dstbits = (char*)dstbits + dstlinebytes;
601 static void X11DRV_DIB_Convert_5x5_to_any0888(int width, int height,
602 const void* srcbits, int srclinebytes,
603 WORD rsrc, WORD gsrc, WORD bsrc,
604 void* dstbits, int dstlinebytes,
605 DWORD rdst, DWORD gdst, DWORD bdst)
607 int rRightShift1,gRightShift1,bRightShift1;
608 int rRightShift2,gRightShift2,bRightShift2;
610 int rLeftShift,gLeftShift,bLeftShift;
611 const WORD* srcpixel;
615 /* Note, the source pixel value is shifted left by 16 bits so that
616 * we know we will always have to shift right to extract the components.
618 rRightShift1=16+X11DRV_DIB_MaskToShift(rsrc)-3;
619 gRightShift1=16+X11DRV_DIB_MaskToShift(gsrc)-3;
620 bRightShift1=16+X11DRV_DIB_MaskToShift(bsrc)-3;
621 rRightShift2=rRightShift1+5;
622 gRightShift2=gRightShift1+5;
623 bRightShift2=bRightShift1+5;
625 /* Green has 5 bits, like the others */
629 /* Green has 6 bits, not 5. Compensate. */
636 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
637 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
638 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
640 for (y=0; y<height; y++) {
643 for (x=0; x<width; x++) {
646 srcval=*srcpixel++ << 16;
647 red= ((srcval >> rRightShift1) & 0xf8) |
648 ((srcval >> rRightShift2) & 0x07);
649 green=((srcval >> gRightShift1) & gMask1) |
650 ((srcval >> gRightShift2) & gMask2);
651 blue= ((srcval >> bRightShift1) & 0xf8) |
652 ((srcval >> bRightShift2) & 0x07);
653 *dstpixel++=(red << rLeftShift) |
654 (green << gLeftShift) |
655 (blue << bLeftShift);
657 srcbits = (char*)srcbits + srclinebytes;
658 dstbits = (char*)dstbits + dstlinebytes;
663 * 16 bits conversions
666 static void X11DRV_DIB_Convert_565_reverse(int width, int height,
667 const void* srcbits, int srclinebytes,
668 void* dstbits, int dstlinebytes)
670 const DWORD* srcpixel;
674 for (y=0; y<height; y++) {
677 for (x=0; x<width/2; x++) {
678 /* Do 2 pixels at a time */
681 *dstpixel++=((srcval << 11) & 0xf800f800) | /* h */
682 ( srcval & 0x07e007e0) | /* g */
683 ((srcval >> 11) & 0x001f001f); /* l */
686 /* And the the odd pixel */
688 srcval=*((WORD*)srcpixel);
689 *((WORD*)dstpixel)=((srcval << 11) & 0xf800) | /* h */
690 ( srcval & 0x07e0) | /* g */
691 ((srcval >> 11) & 0x001f); /* l */
693 srcbits = (char*)srcbits + srclinebytes;
694 dstbits = (char*)dstbits + dstlinebytes;
698 static void X11DRV_DIB_Convert_565_to_555_asis(int width, int height,
699 const void* srcbits, int srclinebytes,
700 void* dstbits, int dstlinebytes)
702 const DWORD* srcpixel;
706 for (y=0; y<height; y++) {
709 for (x=0; x<width/2; x++) {
710 /* Do 2 pixels at a time */
713 *dstpixel++=((srcval >> 1) & 0x7fe07fe0) | /* h, g */
714 ( srcval & 0x001f001f); /* l */
717 /* And the the odd pixel */
719 srcval=*((WORD*)srcpixel);
720 *((WORD*)dstpixel)=((srcval >> 1) & 0x7fe0) | /* h, g */
721 ( srcval & 0x001f); /* l */
723 srcbits = (char*)srcbits + srclinebytes;
724 dstbits = (char*)dstbits + dstlinebytes;
728 static void X11DRV_DIB_Convert_565_to_555_reverse(int width, int height,
729 const void* srcbits, int srclinebytes,
730 void* dstbits, int dstlinebytes)
732 const DWORD* srcpixel;
736 for (y=0; y<height; y++) {
739 for (x=0; x<width/2; x++) {
740 /* Do 2 pixels at a time */
743 *dstpixel++=((srcval >> 11) & 0x001f001f) | /* h */
744 ((srcval >> 1) & 0x03e003e0) | /* g */
745 ((srcval << 10) & 0x7c007c00); /* l */
748 /* And the the odd pixel */
750 srcval=*((WORD*)srcpixel);
751 *((WORD*)dstpixel)=((srcval >> 11) & 0x001f) | /* h */
752 ((srcval >> 1) & 0x03e0) | /* g */
753 ((srcval << 10) & 0x7c00); /* l */
755 srcbits = (char*)srcbits + srclinebytes;
756 dstbits = (char*)dstbits + dstlinebytes;
760 static void X11DRV_DIB_Convert_565_to_888_asis(int width, int height,
761 const void* srcbits, int srclinebytes,
762 void* dstbits, int dstlinebytes)
764 const WORD* srcpixel;
768 for (y=0; y<height; y++) {
771 for (x=0; x<width; x++) {
774 dstpixel[0]=((srcval << 3) & 0xf8) | /* l */
775 ((srcval >> 2) & 0x07); /* l - 3 bits */
776 dstpixel[1]=((srcval >> 3) & 0xfc) | /* g */
777 ((srcval >> 9) & 0x03); /* g - 2 bits */
778 dstpixel[2]=((srcval >> 8) & 0xf8) | /* h */
779 ((srcval >> 13) & 0x07); /* h - 3 bits */
782 srcbits = (char*)srcbits + srclinebytes;
783 dstbits = (char*)dstbits + dstlinebytes;
787 static void X11DRV_DIB_Convert_565_to_888_reverse(int width, int height,
788 const void* srcbits, int srclinebytes,
789 void* dstbits, int dstlinebytes)
791 const WORD* srcpixel;
795 for (y=0; y<height; y++) {
798 for (x=0; x<width; x++) {
801 dstpixel[0]=((srcval >> 8) & 0xf8) | /* h */
802 ((srcval >> 13) & 0x07); /* h - 3 bits */
803 dstpixel[1]=((srcval >> 3) & 0xfc) | /* g */
804 ((srcval >> 9) & 0x03); /* g - 2 bits */
805 dstpixel[2]=((srcval << 3) & 0xf8) | /* l */
806 ((srcval >> 2) & 0x07); /* l - 3 bits */
809 srcbits = (char*)srcbits + srclinebytes;
810 dstbits = (char*)dstbits + dstlinebytes;
814 static void X11DRV_DIB_Convert_565_to_0888_asis(int width, int height,
815 const void* srcbits, int srclinebytes,
816 void* dstbits, int dstlinebytes)
818 const WORD* srcpixel;
822 for (y=0; y<height; y++) {
825 for (x=0; x<width; x++) {
828 *dstpixel++=((srcval << 8) & 0xf80000) | /* h */
829 ((srcval << 3) & 0x070000) | /* h - 3 bits */
830 ((srcval << 5) & 0x00fc00) | /* g */
831 ((srcval >> 1) & 0x000300) | /* g - 2 bits */
832 ((srcval << 3) & 0x0000f8) | /* l */
833 ((srcval >> 2) & 0x000007); /* l - 3 bits */
835 srcbits = (char*)srcbits + srclinebytes;
836 dstbits = (char*)dstbits + dstlinebytes;
840 static void X11DRV_DIB_Convert_565_to_0888_reverse(int width, int height,
841 const void* srcbits, int srclinebytes,
842 void* dstbits, int dstlinebytes)
844 const WORD* srcpixel;
848 for (y=0; y<height; y++) {
851 for (x=0; x<width; x++) {
854 *dstpixel++=((srcval >> 8) & 0x0000f8) | /* h */
855 ((srcval >> 13) & 0x000007) | /* h - 3 bits */
856 ((srcval << 5) & 0x00fc00) | /* g */
857 ((srcval >> 1) & 0x000300) | /* g - 2 bits */
858 ((srcval << 19) & 0xf80000) | /* l */
859 ((srcval << 14) & 0x070000); /* l - 3 bits */
861 srcbits = (char*)srcbits + srclinebytes;
862 dstbits = (char*)dstbits + dstlinebytes;
870 static void X11DRV_DIB_Convert_888_reverse(int width, int height,
871 const void* srcbits, int srclinebytes,
872 void* dstbits, int dstlinebytes)
874 const BYTE* srcpixel;
878 for (y=0; y<height; y++) {
881 for (x=0; x<width; x++) {
882 dstpixel[0]=srcpixel[2];
883 dstpixel[1]=srcpixel[1];
884 dstpixel[2]=srcpixel[0];
888 srcbits = (char*)srcbits + srclinebytes;
889 dstbits = (char*)dstbits + dstlinebytes;
893 static void X11DRV_DIB_Convert_888_to_555_asis(int width, int height,
894 const void* srcbits, int srclinebytes,
895 void* dstbits, int dstlinebytes)
897 const DWORD* srcpixel;
905 for (y=0; y<height; y++) {
908 for (x=0; x<width; x++) {
909 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
910 DWORD srcval1,srcval2;
912 dstpixel[0]=((srcval1 >> 3) & 0x001f) | /* l1 */
913 ((srcval1 >> 6) & 0x03e0) | /* g1 */
914 ((srcval1 >> 9) & 0x7c00); /* h1 */
916 dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */
917 ((srcval2 << 2) & 0x03e0) | /* g2 */
918 ((srcval2 >> 1) & 0x7c00); /* h2 */
920 dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */
921 ((srcval2 >> 22) & 0x03e0) | /* g3 */
922 ((srcval1 << 7) & 0x7c00); /* h3 */
923 dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */
924 ((srcval1 >> 14) & 0x03e0) | /* g4 */
925 ((srcval1 >> 17) & 0x7c00); /* h4 */
929 /* And now up to 3 odd pixels */
930 srcbyte=(LPBYTE)srcpixel;
931 for (x=0; x<oddwidth; x++) {
933 dstval =((srcbyte[0] >> 3) & 0x001f); /* l */
934 dstval|=((srcbyte[1] << 2) & 0x03e0); /* g */
935 dstval|=((srcbyte[2] << 7) & 0x7c00); /* h */
939 srcbits = (char*)srcbits + srclinebytes;
940 dstbits = (char*)dstbits + dstlinebytes;
944 static void X11DRV_DIB_Convert_888_to_555_reverse(int width, int height,
945 const void* srcbits, int srclinebytes,
946 void* dstbits, int dstlinebytes)
948 const DWORD* srcpixel;
956 for (y=0; y<height; y++) {
959 for (x=0; x<width; x++) {
960 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
961 DWORD srcval1,srcval2;
963 dstpixel[0]=((srcval1 << 7) & 0x7c00) | /* l1 */
964 ((srcval1 >> 6) & 0x03e0) | /* g1 */
965 ((srcval1 >> 19) & 0x001f); /* h1 */
967 dstpixel[1]=((srcval1 >> 17) & 0x7c00) | /* l2 */
968 ((srcval2 << 2) & 0x03e0) | /* g2 */
969 ((srcval2 >> 11) & 0x001f); /* h2 */
971 dstpixel[2]=((srcval2 >> 9) & 0x7c00) | /* l3 */
972 ((srcval2 >> 22) & 0x03e0) | /* g3 */
973 ((srcval1 >> 3) & 0x001f); /* h3 */
974 dstpixel[3]=((srcval1 >> 1) & 0x7c00) | /* l4 */
975 ((srcval1 >> 14) & 0x03e0) | /* g4 */
976 ((srcval1 >> 27) & 0x001f); /* h4 */
980 /* And now up to 3 odd pixels */
981 srcbyte=(LPBYTE)srcpixel;
982 for (x=0; x<oddwidth; x++) {
984 dstval =((srcbyte[0] << 7) & 0x7c00); /* l */
985 dstval|=((srcbyte[1] << 2) & 0x03e0); /* g */
986 dstval|=((srcbyte[2] >> 3) & 0x001f); /* h */
990 srcbits = (char*)srcbits + srclinebytes;
991 dstbits = (char*)dstbits + dstlinebytes;
995 static void X11DRV_DIB_Convert_888_to_565_asis(int width, int height,
996 const void* srcbits, int srclinebytes,
997 void* dstbits, int dstlinebytes)
999 const DWORD* srcpixel;
1000 const BYTE* srcbyte;
1007 for (y=0; y<height; y++) {
1010 for (x=0; x<width; x++) {
1011 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
1012 DWORD srcval1,srcval2;
1013 srcval1=srcpixel[0];
1014 dstpixel[0]=((srcval1 >> 3) & 0x001f) | /* l1 */
1015 ((srcval1 >> 5) & 0x07e0) | /* g1 */
1016 ((srcval1 >> 8) & 0xf800); /* h1 */
1017 srcval2=srcpixel[1];
1018 dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */
1019 ((srcval2 << 3) & 0x07e0) | /* g2 */
1020 ( srcval2 & 0xf800); /* h2 */
1021 srcval1=srcpixel[2];
1022 dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */
1023 ((srcval2 >> 21) & 0x07e0) | /* g3 */
1024 ((srcval1 << 8) & 0xf800); /* h3 */
1025 dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */
1026 ((srcval1 >> 13) & 0x07e0) | /* g4 */
1027 ((srcval1 >> 16) & 0xf800); /* h4 */
1031 /* And now up to 3 odd pixels */
1032 srcbyte=(LPBYTE)srcpixel;
1033 for (x=0; x<oddwidth; x++) {
1035 dstval =((srcbyte[0] >> 3) & 0x001f); /* l */
1036 dstval|=((srcbyte[1] << 3) & 0x07e0); /* g */
1037 dstval|=((srcbyte[2] << 8) & 0xf800); /* h */
1041 srcbits = (char*)srcbits + srclinebytes;
1042 dstbits = (char*)dstbits + dstlinebytes;
1046 static void X11DRV_DIB_Convert_888_to_565_reverse(int width, int height,
1047 const void* srcbits, int srclinebytes,
1048 void* dstbits, int dstlinebytes)
1050 const DWORD* srcpixel;
1051 const BYTE* srcbyte;
1058 for (y=0; y<height; y++) {
1061 for (x=0; x<width; x++) {
1062 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
1063 DWORD srcval1,srcval2;
1064 srcval1=srcpixel[0];
1065 dstpixel[0]=((srcval1 << 8) & 0xf800) | /* l1 */
1066 ((srcval1 >> 5) & 0x07e0) | /* g1 */
1067 ((srcval1 >> 19) & 0x001f); /* h1 */
1068 srcval2=srcpixel[1];
1069 dstpixel[1]=((srcval1 >> 16) & 0xf800) | /* l2 */
1070 ((srcval2 << 3) & 0x07e0) | /* g2 */
1071 ((srcval2 >> 11) & 0x001f); /* h2 */
1072 srcval1=srcpixel[2];
1073 dstpixel[2]=((srcval2 >> 8) & 0xf800) | /* l3 */
1074 ((srcval2 >> 21) & 0x07e0) | /* g3 */
1075 ((srcval1 >> 3) & 0x001f); /* h3 */
1076 dstpixel[3]=(srcval1 & 0xf800) | /* l4 */
1077 ((srcval1 >> 13) & 0x07e0) | /* g4 */
1078 ((srcval1 >> 27) & 0x001f); /* h4 */
1082 /* And now up to 3 odd pixels */
1083 srcbyte=(LPBYTE)srcpixel;
1084 for (x=0; x<oddwidth; x++) {
1086 dstval =((srcbyte[0] << 8) & 0xf800); /* l */
1087 dstval|=((srcbyte[1] << 3) & 0x07e0); /* g */
1088 dstval|=((srcbyte[2] >> 3) & 0x001f); /* h */
1092 srcbits = (char*)srcbits + srclinebytes;
1093 dstbits = (char*)dstbits + dstlinebytes;
1097 static void X11DRV_DIB_Convert_888_to_0888_asis(int width, int height,
1098 const void* srcbits, int srclinebytes,
1099 void* dstbits, int dstlinebytes)
1101 const DWORD* srcpixel;
1108 for (y=0; y<height; y++) {
1111 for (x=0; x<width; x++) {
1112 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1113 DWORD srcval1,srcval2;
1114 srcval1=srcpixel[0];
1115 dstpixel[0]=( srcval1 & 0x00ffffff); /* h1, g1, l1 */
1116 srcval2=srcpixel[1];
1117 dstpixel[1]=( srcval1 >> 24) | /* l2 */
1118 ((srcval2 << 8) & 0x00ffff00); /* h2, g2 */
1119 srcval1=srcpixel[2];
1120 dstpixel[2]=( srcval2 >> 16) | /* g3, l3 */
1121 ((srcval1 << 16) & 0x00ff0000); /* h3 */
1122 dstpixel[3]=( srcval1 >> 8); /* h4, g4, l4 */
1126 /* And now up to 3 odd pixels */
1127 for (x=0; x<oddwidth; x++) {
1130 srcpixel=(LPDWORD)(((char*)srcpixel)+3);
1131 *dstpixel++=( srcval & 0x00ffffff); /* h, g, l */
1133 srcbits = (char*)srcbits + srclinebytes;
1134 dstbits = (char*)dstbits + dstlinebytes;
1138 static void X11DRV_DIB_Convert_888_to_0888_reverse(int width, int height,
1139 const void* srcbits, int srclinebytes,
1140 void* dstbits, int dstlinebytes)
1142 const DWORD* srcpixel;
1149 for (y=0; y<height; y++) {
1152 for (x=0; x<width; x++) {
1153 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1154 DWORD srcval1,srcval2;
1156 srcval1=srcpixel[0];
1157 dstpixel[0]=((srcval1 >> 16) & 0x0000ff) | /* h1 */
1158 ( srcval1 & 0x00ff00) | /* g1 */
1159 ((srcval1 << 16) & 0xff0000); /* l1 */
1160 srcval2=srcpixel[1];
1161 dstpixel[1]=((srcval1 >> 8) & 0xff0000) | /* l2 */
1162 ((srcval2 << 8) & 0x00ff00) | /* g2 */
1163 ((srcval2 >> 8) & 0x0000ff); /* h2 */
1164 srcval1=srcpixel[2];
1165 dstpixel[2]=( srcval2 & 0xff0000) | /* l3 */
1166 ((srcval2 >> 16) & 0x00ff00) | /* g3 */
1167 ( srcval1 & 0x0000ff); /* h3 */
1168 dstpixel[3]=((srcval1 >> 24) & 0x0000ff) | /* h4 */
1169 ((srcval1 >> 8) & 0x00ff00) | /* g4 */
1170 ((srcval1 << 8) & 0xff0000); /* l4 */
1174 /* And now up to 3 odd pixels */
1175 for (x=0; x<oddwidth; x++) {
1178 srcpixel=(LPDWORD)(((char*)srcpixel)+3);
1179 *dstpixel++=((srcval >> 16) & 0x0000ff) | /* h */
1180 ( srcval & 0x00ff00) | /* g */
1181 ((srcval << 16) & 0xff0000); /* l */
1183 srcbits = (char*)srcbits + srclinebytes;
1184 dstbits = (char*)dstbits + dstlinebytes;
1188 static void X11DRV_DIB_Convert_rgb888_to_any0888(int width, int height,
1189 const void* srcbits, int srclinebytes,
1190 void* dstbits, int dstlinebytes,
1191 DWORD rdst, DWORD gdst, DWORD bdst)
1193 int rLeftShift,gLeftShift,bLeftShift;
1194 const BYTE* srcpixel;
1198 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1199 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1200 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1201 for (y=0; y<height; y++) {
1204 for (x=0; x<width; x++) {
1205 *dstpixel++=(srcpixel[0] << bLeftShift) | /* b */
1206 (srcpixel[1] << gLeftShift) | /* g */
1207 (srcpixel[2] << rLeftShift); /* r */
1210 srcbits = (char*)srcbits + srclinebytes;
1211 dstbits = (char*)dstbits + dstlinebytes;
1215 static void X11DRV_DIB_Convert_bgr888_to_any0888(int width, int height,
1216 const void* srcbits, int srclinebytes,
1217 void* dstbits, int dstlinebytes,
1218 DWORD rdst, DWORD gdst, DWORD bdst)
1220 int rLeftShift,gLeftShift,bLeftShift;
1221 const BYTE* srcpixel;
1225 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1226 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1227 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1228 for (y=0; y<height; y++) {
1231 for (x=0; x<width; x++) {
1232 *dstpixel++=(srcpixel[0] << rLeftShift) | /* r */
1233 (srcpixel[1] << gLeftShift) | /* g */
1234 (srcpixel[2] << bLeftShift); /* b */
1237 srcbits = (char*)srcbits + srclinebytes;
1238 dstbits = (char*)dstbits + dstlinebytes;
1243 * 32 bit conversions
1246 static void X11DRV_DIB_Convert_0888_reverse(int width, int height,
1247 const void* srcbits, int srclinebytes,
1248 void* dstbits, int dstlinebytes)
1250 const DWORD* srcpixel;
1254 for (y=0; y<height; y++) {
1257 for (x=0; x<width; x++) {
1260 *dstpixel++=((srcval << 16) & 0x00ff0000) | /* h */
1261 ( srcval & 0x0000ff00) | /* g */
1262 ((srcval >> 16) & 0x000000ff); /* l */
1264 srcbits = (char*)srcbits + srclinebytes;
1265 dstbits = (char*)dstbits + dstlinebytes;
1269 static void X11DRV_DIB_Convert_0888_any(int width, int height,
1270 const void* srcbits, int srclinebytes,
1271 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1272 void* dstbits, int dstlinebytes,
1273 DWORD rdst, DWORD gdst, DWORD bdst)
1275 int rRightShift,gRightShift,bRightShift;
1276 int rLeftShift,gLeftShift,bLeftShift;
1277 const DWORD* srcpixel;
1281 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1282 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1283 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1284 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1285 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1286 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1287 for (y=0; y<height; y++) {
1290 for (x=0; x<width; x++) {
1293 *dstpixel++=(((srcval >> rRightShift) & 0xff) << rLeftShift) |
1294 (((srcval >> gRightShift) & 0xff) << gLeftShift) |
1295 (((srcval >> bRightShift) & 0xff) << bLeftShift);
1297 srcbits = (char*)srcbits + srclinebytes;
1298 dstbits = (char*)dstbits + dstlinebytes;
1302 static void X11DRV_DIB_Convert_0888_to_555_asis(int width, int height,
1303 const void* srcbits, int srclinebytes,
1304 void* dstbits, int dstlinebytes)
1306 const DWORD* srcpixel;
1310 for (y=0; y<height; y++) {
1313 for (x=0; x<width; x++) {
1316 *dstpixel++=((srcval >> 9) & 0x7c00) | /* h */
1317 ((srcval >> 6) & 0x03e0) | /* g */
1318 ((srcval >> 3) & 0x001f); /* l */
1320 srcbits = (char*)srcbits + srclinebytes;
1321 dstbits = (char*)dstbits + dstlinebytes;
1325 static void X11DRV_DIB_Convert_0888_to_555_reverse(int width, int height,
1326 const void* srcbits, int srclinebytes,
1327 void* dstbits, int dstlinebytes)
1329 const DWORD* srcpixel;
1333 for (y=0; y<height; y++) {
1336 for (x=0; x<width; x++) {
1339 *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1340 ((srcval >> 6) & 0x03e0) | /* g */
1341 ((srcval << 7) & 0x7c00); /* l */
1343 srcbits = (char*)srcbits + srclinebytes;
1344 dstbits = (char*)dstbits + dstlinebytes;
1348 static void X11DRV_DIB_Convert_0888_to_565_asis(int width, int height,
1349 const void* srcbits, int srclinebytes,
1350 void* dstbits, int dstlinebytes)
1352 const DWORD* srcpixel;
1356 for (y=0; y<height; y++) {
1359 for (x=0; x<width; x++) {
1362 *dstpixel++=((srcval >> 8) & 0xf800) | /* h */
1363 ((srcval >> 5) & 0x07e0) | /* g */
1364 ((srcval >> 3) & 0x001f); /* l */
1366 srcbits = (char*)srcbits + srclinebytes;
1367 dstbits = (char*)dstbits + dstlinebytes;
1371 static void X11DRV_DIB_Convert_0888_to_565_reverse(int width, int height,
1372 const void* srcbits, int srclinebytes,
1373 void* dstbits, int dstlinebytes)
1375 const DWORD* srcpixel;
1379 for (y=0; y<height; y++) {
1382 for (x=0; x<width; x++) {
1385 *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1386 ((srcval >> 5) & 0x07e0) | /* g */
1387 ((srcval << 8) & 0xf800); /* l */
1389 srcbits = (char*)srcbits + srclinebytes;
1390 dstbits = (char*)dstbits + dstlinebytes;
1394 static void X11DRV_DIB_Convert_any0888_to_5x5(int width, int height,
1395 const void* srcbits, int srclinebytes,
1396 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1397 void* dstbits, int dstlinebytes,
1398 WORD rdst, WORD gdst, WORD bdst)
1400 int rRightShift,gRightShift,bRightShift;
1401 int rLeftShift,gLeftShift,bLeftShift;
1402 const DWORD* srcpixel;
1406 /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel
1407 * contains 0x11223344.
1408 * - first we shift 0x11223344 right by rRightShift to bring the most
1409 * significant bits of the red components in the bottom 5 (or 6) bits
1411 * - then we remove non red bits by anding with the modified rdst (0x1f)
1413 * - finally shift these bits left by rLeftShift so that they end up in
1417 rRightShift=X11DRV_DIB_MaskToShift(rsrc)+3;
1418 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1419 gRightShift+=(gdst==0x07e0?2:3);
1420 bRightShift=X11DRV_DIB_MaskToShift(bsrc)+3;
1422 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1423 rdst=rdst >> rLeftShift;
1424 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1425 gdst=gdst >> gLeftShift;
1426 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1427 bdst=bdst >> bLeftShift;
1429 for (y=0; y<height; y++) {
1432 for (x=0; x<width; x++) {
1435 *dstpixel++=(((srcval >> rRightShift) & rdst) << rLeftShift) |
1436 (((srcval >> gRightShift) & gdst) << gLeftShift) |
1437 (((srcval >> bRightShift) & bdst) << bLeftShift);
1439 srcbits = (char*)srcbits + srclinebytes;
1440 dstbits = (char*)dstbits + dstlinebytes;
1444 static void X11DRV_DIB_Convert_0888_to_888_asis(int width, int height,
1445 const void* srcbits, int srclinebytes,
1446 void* dstbits, int dstlinebytes)
1448 const DWORD* srcpixel;
1456 for (y=0; y<height; y++) {
1459 for (x=0; x<width; x++) {
1460 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1462 srcval=((*srcpixel++) & 0x00ffffff); /* h1, g1, l1*/
1463 *dstpixel++=srcval | ((*srcpixel) << 24); /* h2 */
1464 srcval=((*srcpixel++ >> 8 ) & 0x0000ffff); /* g2, l2 */
1465 *dstpixel++=srcval | ((*srcpixel) << 16); /* h3, g3 */
1466 srcval=((*srcpixel++ >> 16) & 0x000000ff); /* l3 */
1467 *dstpixel++=srcval | ((*srcpixel++) << 8); /* h4, g4, l4 */
1469 /* And now up to 3 odd pixels */
1470 dstbyte=(BYTE*)dstpixel;
1471 for (x=0; x<oddwidth; x++) {
1474 *((WORD*)dstbyte)++=srcval; /* h, g */
1475 *dstbyte++=srcval >> 16; /* l */
1477 srcbits = (char*)srcbits + srclinebytes;
1478 dstbits = (char*)dstbits + dstlinebytes;
1482 static void X11DRV_DIB_Convert_0888_to_888_reverse(int width, int height,
1483 const void* srcbits, int srclinebytes,
1484 void* dstbits, int dstlinebytes)
1486 const DWORD* srcpixel;
1494 for (y=0; y<height; y++) {
1497 for (x=0; x<width; x++) {
1498 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1499 DWORD srcval1,srcval2;
1500 srcval1=*srcpixel++;
1501 srcval2= ((srcval1 >> 16) & 0x000000ff) | /* h1 */
1502 ( srcval1 & 0x0000ff00) | /* g1 */
1503 ((srcval1 << 16) & 0x00ff0000); /* l1 */
1504 srcval1=*srcpixel++;
1505 *dstpixel++=srcval2 |
1506 ((srcval1 << 8) & 0xff000000); /* h2 */
1507 srcval2= ((srcval1 >> 8) & 0x000000ff) | /* g2 */
1508 ((srcval1 << 8) & 0x0000ff00); /* l2 */
1509 srcval1=*srcpixel++;
1510 *dstpixel++=srcval2 |
1511 ( srcval1 & 0x00ff0000) | /* h3 */
1512 ((srcval1 << 16) & 0xff000000); /* g3 */
1513 srcval2= ( srcval1 & 0x000000ff); /* l3 */
1514 srcval1=*srcpixel++;
1515 *dstpixel++=srcval2 |
1516 ((srcval1 >> 8) & 0x0000ff00) | /* h4 */
1517 ((srcval1 << 8) & 0x00ff0000) | /* g4 */
1518 ( srcval1 << 24); /* l4 */
1520 /* And now up to 3 odd pixels */
1521 dstbyte=(BYTE*)dstpixel;
1522 for (x=0; x<oddwidth; x++) {
1525 *((WORD*)dstbyte)++=((srcval >> 16) & 0x00ff) | /* h */
1526 (srcval & 0xff00); /* g */
1527 *dstbyte++=srcval; /* l */
1529 srcbits = (char*)srcbits + srclinebytes;
1530 dstbits = (char*)dstbits + dstlinebytes;
1534 static void X11DRV_DIB_Convert_any0888_to_rgb888(int width, int height,
1535 const void* srcbits, int srclinebytes,
1536 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1537 void* dstbits, int dstlinebytes)
1539 int rRightShift,gRightShift,bRightShift;
1540 const DWORD* srcpixel;
1544 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1545 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1546 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1547 for (y=0; y<height; y++) {
1550 for (x=0; x<width; x++) {
1553 dstpixel[0]=(srcval >> bRightShift); /* b */
1554 dstpixel[1]=(srcval >> gRightShift); /* g */
1555 dstpixel[2]=(srcval >> rRightShift); /* r */
1558 srcbits = (char*)srcbits + srclinebytes;
1559 dstbits = (char*)dstbits + dstlinebytes;
1563 static void X11DRV_DIB_Convert_any0888_to_bgr888(int width, int height,
1564 const void* srcbits, int srclinebytes,
1565 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1566 void* dstbits, int dstlinebytes)
1568 int rRightShift,gRightShift,bRightShift;
1569 const DWORD* srcpixel;
1573 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1574 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1575 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1576 for (y=0; y<height; y++) {
1579 for (x=0; x<width; x++) {
1582 dstpixel[0]=(srcval >> rRightShift); /* r */
1583 dstpixel[1]=(srcval >> gRightShift); /* g */
1584 dstpixel[2]=(srcval >> bRightShift); /* b */
1587 srcbits = (char*)srcbits + srclinebytes;
1588 dstbits = (char*)dstbits + dstlinebytes;
1592 /***********************************************************************
1593 * X11DRV_DIB_SetImageBits_1
1595 * SetDIBits for a 1-bit deep DIB.
1597 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
1598 DWORD srcwidth, DWORD dstwidth, int left,
1599 int *colors, XImage *bmpImage, DWORD linebytes)
1602 const BYTE* srcbyte;
1608 srcbits = srcbits + linebytes * (lines - 1);
1609 linebytes = -linebytes;
1612 if ((extra = (left & 7)) != 0) {
1616 srcbits += left >> 3;
1618 /* ==== pal 1 dib -> any bmp format ==== */
1619 for (h = lines-1; h >=0; h--) {
1621 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
1622 for (i = dstwidth/8, x = left; i > 0; i--) {
1624 XPutPixel( bmpImage, x++, h, colors[ srcval >> 7] );
1625 XPutPixel( bmpImage, x++, h, colors[(srcval >> 6) & 1] );
1626 XPutPixel( bmpImage, x++, h, colors[(srcval >> 5) & 1] );
1627 XPutPixel( bmpImage, x++, h, colors[(srcval >> 4) & 1] );
1628 XPutPixel( bmpImage, x++, h, colors[(srcval >> 3) & 1] );
1629 XPutPixel( bmpImage, x++, h, colors[(srcval >> 2) & 1] );
1630 XPutPixel( bmpImage, x++, h, colors[(srcval >> 1) & 1] );
1631 XPutPixel( bmpImage, x++, h, colors[ srcval & 1] );
1635 switch (dstwidth & 7)
1637 case 7: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1638 case 6: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1639 case 5: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1640 case 4: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1641 case 3: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1642 case 2: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1643 case 1: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]);
1646 srcbits += linebytes;
1650 /***********************************************************************
1651 * X11DRV_DIB_GetImageBits_1
1653 * GetDIBits for a 1-bit deep DIB.
1655 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
1656 DWORD dstwidth, DWORD srcwidth,
1657 RGBQUAD *colors, PALETTEENTRY *srccolors,
1658 XImage *bmpImage, DWORD linebytes )
1665 dstbits = dstbits + linebytes * (lines - 1);
1666 linebytes = -linebytes;
1669 switch (bmpImage->depth)
1673 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1674 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
1677 for (h=lines-1; h>=0; h--) {
1681 for (x=0; x<dstwidth; x++) {
1682 PALETTEENTRY srcval;
1683 srcval=srccolors[XGetPixel(bmpImage, x, h)];
1684 dstval|=(X11DRV_DIB_GetNearestIndex
1688 srcval.peBlue) << (7 - (x & 7)));
1694 if ((dstwidth&7)!=0) {
1697 dstbits += linebytes;
1705 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1706 /* ==== pal 8 bmp -> pal 1 dib ==== */
1707 const void* srcbits;
1708 const BYTE* srcpixel;
1711 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1713 for (h=0; h<lines; h++) {
1718 for (x=0; x<dstwidth; x++) {
1719 PALETTEENTRY srcval;
1720 srcval=srccolors[(int)*srcpixel++];
1721 dstval|=(X11DRV_DIB_GetNearestIndex
1725 srcval.peBlue) << (7-(x&7)) );
1731 if ((dstwidth&7)!=0) {
1734 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1735 dstbits += linebytes;
1745 const void* srcbits;
1746 const WORD* srcpixel;
1749 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1751 if (bmpImage->green_mask==0x03e0) {
1752 if (bmpImage->red_mask==0x7c00) {
1753 /* ==== rgb 555 bmp -> pal 1 dib ==== */
1754 for (h=0; h<lines; h++) {
1759 for (x=0; x<dstwidth; x++) {
1762 dstval|=(X11DRV_DIB_GetNearestIndex
1764 ((srcval >> 7) & 0xf8) | /* r */
1765 ((srcval >> 12) & 0x07),
1766 ((srcval >> 2) & 0xf8) | /* g */
1767 ((srcval >> 7) & 0x07),
1768 ((srcval << 3) & 0xf8) | /* b */
1769 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
1775 if ((dstwidth&7)!=0) {
1778 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1779 dstbits += linebytes;
1781 } else if (bmpImage->blue_mask==0x7c00) {
1782 /* ==== bgr 555 bmp -> pal 1 dib ==== */
1783 for (h=0; h<lines; h++) {
1788 for (x=0; x<dstwidth; x++) {
1791 dstval|=(X11DRV_DIB_GetNearestIndex
1793 ((srcval << 3) & 0xf8) | /* r */
1794 ((srcval >> 2) & 0x07),
1795 ((srcval >> 2) & 0xf8) | /* g */
1796 ((srcval >> 7) & 0x07),
1797 ((srcval >> 7) & 0xf8) | /* b */
1798 ((srcval >> 12) & 0x07) ) << (7-(x&7)) );
1804 if ((dstwidth&7)!=0) {
1807 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1808 dstbits += linebytes;
1813 } else if (bmpImage->green_mask==0x07e0) {
1814 if (bmpImage->red_mask==0xf800) {
1815 /* ==== rgb 565 bmp -> pal 1 dib ==== */
1816 for (h=0; h<lines; h++) {
1821 for (x=0; x<dstwidth; x++) {
1824 dstval|=(X11DRV_DIB_GetNearestIndex
1826 ((srcval >> 8) & 0xf8) | /* r */
1827 ((srcval >> 13) & 0x07),
1828 ((srcval >> 3) & 0xfc) | /* g */
1829 ((srcval >> 9) & 0x03),
1830 ((srcval << 3) & 0xf8) | /* b */
1831 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
1837 if ((dstwidth&7)!=0) {
1840 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1841 dstbits += linebytes;
1843 } else if (bmpImage->blue_mask==0xf800) {
1844 /* ==== bgr 565 bmp -> pal 1 dib ==== */
1845 for (h=0; h<lines; h++) {
1850 for (x=0; x<dstwidth; x++) {
1853 dstval|=(X11DRV_DIB_GetNearestIndex
1855 ((srcval << 3) & 0xf8) | /* r */
1856 ((srcval >> 2) & 0x07),
1857 ((srcval >> 3) & 0xfc) | /* g */
1858 ((srcval >> 9) & 0x03),
1859 ((srcval >> 8) & 0xf8) | /* b */
1860 ((srcval >> 13) & 0x07) ) << (7-(x&7)) );
1866 if ((dstwidth&7)!=0) {
1869 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1870 dstbits += linebytes;
1884 const void* srcbits;
1885 const BYTE *srcbyte;
1887 int bytes_per_pixel;
1889 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1890 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
1892 if (bmpImage->green_mask!=0x00ff00 ||
1893 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1895 } else if (bmpImage->blue_mask==0xff) {
1896 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
1897 for (h=0; h<lines; h++) {
1902 for (x=0; x<dstwidth; x++) {
1903 dstval|=(X11DRV_DIB_GetNearestIndex
1907 srcbyte[0]) << (7-(x&7)) );
1908 srcbyte+=bytes_per_pixel;
1914 if ((dstwidth&7)!=0) {
1917 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1918 dstbits += linebytes;
1921 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
1922 for (h=0; h<lines; h++) {
1927 for (x=0; x<dstwidth; x++) {
1928 dstval|=(X11DRV_DIB_GetNearestIndex
1932 srcbyte[2]) << (7-(x&7)) );
1933 srcbyte+=bytes_per_pixel;
1939 if ((dstwidth&7)!=0) {
1942 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
1943 dstbits += linebytes;
1953 unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
1955 /* ==== any bmp format -> pal 1 dib ==== */
1956 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
1957 bmpImage->bits_per_pixel, bmpImage->red_mask,
1958 bmpImage->green_mask, bmpImage->blue_mask );
1960 for (h=lines-1; h>=0; h--) {
1964 for (x=0; x<dstwidth; x++) {
1965 dstval|=(XGetPixel( bmpImage, x, h) >= white) << (7 - (x&7));
1971 if ((dstwidth&7)!=0) {
1974 dstbits += linebytes;
1981 /***********************************************************************
1982 * X11DRV_DIB_SetImageBits_4
1984 * SetDIBits for a 4-bit deep DIB.
1986 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
1987 DWORD srcwidth, DWORD dstwidth, int left,
1988 int *colors, XImage *bmpImage, DWORD linebytes)
1991 const BYTE* srcbyte;
1996 srcbits = srcbits + linebytes * (lines - 1);
1997 linebytes = -linebytes;
2004 srcbits += left >> 1;
2006 /* ==== pal 4 dib -> any bmp format ==== */
2007 for (h = lines-1; h >= 0; h--) {
2009 for (i = dstwidth/2, x = left; i > 0; i--) {
2010 BYTE srcval=*srcbyte++;
2011 XPutPixel( bmpImage, x++, h, colors[srcval >> 4] );
2012 XPutPixel( bmpImage, x++, h, colors[srcval & 0x0f] );
2015 XPutPixel( bmpImage, x, h, colors[*srcbyte >> 4] );
2016 srcbits += linebytes;
2022 /***********************************************************************
2023 * X11DRV_DIB_GetImageBits_4
2025 * GetDIBits for a 4-bit deep DIB.
2027 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
2028 DWORD srcwidth, DWORD dstwidth,
2029 RGBQUAD *colors, PALETTEENTRY *srccolors,
2030 XImage *bmpImage, DWORD linebytes )
2039 dstbits = dstbits + ( linebytes * (lines-1) );
2040 linebytes = -linebytes;
2045 switch (bmpImage->depth) {
2048 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2049 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
2052 for (h = lines-1; h >= 0; h--) {
2056 for (x = 0; x < dstwidth; x++) {
2057 PALETTEENTRY srcval;
2058 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2059 dstval|=(X11DRV_DIB_GetNearestIndex
2063 srcval.peBlue) << (4-((x&1)<<2)));
2069 if ((dstwidth&1)!=0) {
2072 dstbits += linebytes;
2080 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2081 /* ==== pal 8 bmp -> pal 4 dib ==== */
2082 const void* srcbits;
2083 const BYTE *srcpixel;
2086 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2087 for (h=0; h<lines; h++) {
2092 for (x=0; x<dstwidth; x++) {
2093 PALETTEENTRY srcval;
2094 srcval = srccolors[(int)*srcpixel++];
2095 dstval|=(X11DRV_DIB_GetNearestIndex
2099 srcval.peBlue) << (4*(1-(x&1))) );
2105 if ((dstwidth&1)!=0) {
2108 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2109 dstbits += linebytes;
2119 const void* srcbits;
2120 const WORD* srcpixel;
2123 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2125 if (bmpImage->green_mask==0x03e0) {
2126 if (bmpImage->red_mask==0x7c00) {
2127 /* ==== rgb 555 bmp -> pal 4 dib ==== */
2128 for (h=0; h<lines; h++) {
2133 for (x=0; x<dstwidth; x++) {
2136 dstval|=(X11DRV_DIB_GetNearestIndex
2138 ((srcval >> 7) & 0xf8) | /* r */
2139 ((srcval >> 12) & 0x07),
2140 ((srcval >> 2) & 0xf8) | /* g */
2141 ((srcval >> 7) & 0x07),
2142 ((srcval << 3) & 0xf8) | /* b */
2143 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
2149 if ((dstwidth&1)!=0) {
2152 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2153 dstbits += linebytes;
2155 } else if (bmpImage->blue_mask==0x7c00) {
2156 /* ==== bgr 555 bmp -> pal 4 dib ==== */
2157 for (h=0; h<lines; h++) {
2162 for (x=0; x<dstwidth; x++) {
2165 dstval|=(X11DRV_DIB_GetNearestIndex
2167 ((srcval << 3) & 0xf8) | /* r */
2168 ((srcval >> 2) & 0x07),
2169 ((srcval >> 2) & 0xf8) | /* g */
2170 ((srcval >> 7) & 0x07),
2171 ((srcval >> 7) & 0xf8) | /* b */
2172 ((srcval >> 12) & 0x07) ) << ((1-(x&1))<<2) );
2178 if ((dstwidth&1)!=0) {
2181 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2182 dstbits += linebytes;
2187 } else if (bmpImage->green_mask==0x07e0) {
2188 if (bmpImage->red_mask==0xf800) {
2189 /* ==== rgb 565 bmp -> pal 4 dib ==== */
2190 for (h=0; h<lines; h++) {
2195 for (x=0; x<dstwidth; x++) {
2198 dstval|=(X11DRV_DIB_GetNearestIndex
2200 ((srcval >> 8) & 0xf8) | /* r */
2201 ((srcval >> 13) & 0x07),
2202 ((srcval >> 3) & 0xfc) | /* g */
2203 ((srcval >> 9) & 0x03),
2204 ((srcval << 3) & 0xf8) | /* b */
2205 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
2211 if ((dstwidth&1)!=0) {
2214 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2215 dstbits += linebytes;
2217 } else if (bmpImage->blue_mask==0xf800) {
2218 /* ==== bgr 565 bmp -> pal 4 dib ==== */
2219 for (h=0; h<lines; h++) {
2224 for (x=0; x<dstwidth; x++) {
2227 dstval|=(X11DRV_DIB_GetNearestIndex
2229 ((srcval << 3) & 0xf8) | /* r */
2230 ((srcval >> 2) & 0x07),
2231 ((srcval >> 3) & 0xfc) | /* g */
2232 ((srcval >> 9) & 0x03),
2233 ((srcval >> 8) & 0xf8) | /* b */
2234 ((srcval >> 13) & 0x07) ) << ((1-(x&1))<<2) );
2240 if ((dstwidth&1)!=0) {
2243 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2244 dstbits += linebytes;
2256 if (bmpImage->bits_per_pixel==24) {
2257 const void* srcbits;
2258 const BYTE *srcbyte;
2261 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2263 if (bmpImage->green_mask!=0x00ff00 ||
2264 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2266 } else if (bmpImage->blue_mask==0xff) {
2267 /* ==== rgb 888 bmp -> pal 4 dib ==== */
2268 for (h=0; h<lines; h++) {
2271 for (x=0; x<dstwidth/2; x++) {
2272 /* Do 2 pixels at a time */
2273 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2278 X11DRV_DIB_GetNearestIndex
2286 /* And the the odd pixel */
2287 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2293 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2294 dstbits += linebytes;
2297 /* ==== bgr 888 bmp -> pal 4 dib ==== */
2298 for (h=0; h<lines; h++) {
2301 for (x=0; x<dstwidth/2; x++) {
2302 /* Do 2 pixels at a time */
2303 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2308 X11DRV_DIB_GetNearestIndex
2316 /* And the the odd pixel */
2317 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2323 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2324 dstbits += linebytes;
2333 const void* srcbits;
2334 const BYTE *srcbyte;
2337 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2339 if (bmpImage->green_mask!=0x00ff00 ||
2340 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2342 } else if (bmpImage->blue_mask==0xff) {
2343 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
2344 for (h=0; h<lines; h++) {
2347 for (x=0; x<dstwidth/2; x++) {
2348 /* Do 2 pixels at a time */
2349 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2354 X11DRV_DIB_GetNearestIndex
2362 /* And the the odd pixel */
2363 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2369 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2370 dstbits += linebytes;
2373 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
2374 for (h=0; h<lines; h++) {
2377 for (x=0; x<dstwidth/2; x++) {
2378 /* Do 2 pixels at a time */
2379 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2384 X11DRV_DIB_GetNearestIndex
2392 /* And the the odd pixel */
2393 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2399 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2400 dstbits += linebytes;
2411 /* ==== any bmp format -> pal 4 dib ==== */
2412 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
2413 bmpImage->bits_per_pixel, bmpImage->red_mask,
2414 bmpImage->green_mask, bmpImage->blue_mask );
2415 for (h=lines-1; h>=0; h--) {
2417 for (x=0; x<(dstwidth & ~1); x+=2) {
2418 *dstbyte++=(X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4) |
2419 X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x+1, h), 0);
2422 *dstbyte=(X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4);
2424 dstbits += linebytes;
2431 /***********************************************************************
2432 * X11DRV_DIB_SetImageBits_RLE4
2434 * SetDIBits for a 4-bit deep compressed DIB.
2436 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
2437 DWORD width, DWORD dstwidth,
2438 int left, int *colors,
2441 int x = 0, y = lines - 1, c, length;
2442 const BYTE *begin = bits;
2447 if (length) { /* encoded */
2450 if (x >= width) break;
2451 XPutPixel(bmpImage, x++, y, colors[c >> 4]);
2452 if (!length--) break;
2453 if (x >= width) break;
2454 XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
2473 default: /* absolute */
2476 if (x < width) XPutPixel(bmpImage, x++, y, colors[c >> 4]);
2477 if (!length--) break;
2478 if (x < width) XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
2480 if ((bits - begin) & 1)
2489 /***********************************************************************
2490 * X11DRV_DIB_SetImageBits_8
2492 * SetDIBits for an 8-bit deep DIB.
2494 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
2495 DWORD srcwidth, DWORD dstwidth, int left,
2496 const int *colors, XImage *bmpImage,
2501 const BYTE* srcbyte;
2507 srcbits = srcbits + linebytes * (lines-1);
2508 linebytes = -linebytes;
2513 switch (bmpImage->depth) {
2516 #if defined(__i386__) && defined(__GNUC__)
2517 /* Some X servers might have 32 bit/ 16bit deep pixel */
2518 if (lines && dstwidth && (bmpImage->bits_per_pixel == 16) &&
2519 (ImageByteOrder(gdi_display)==LSBFirst) )
2521 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2522 /* FIXME: Does this really handle all these cases correctly? */
2523 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
2524 for (h = lines ; h--; ) {
2525 int _cl1,_cl2; /* temp outputs for asm below */
2526 /* Borrowed from DirectDraw */
2527 __asm__ __volatile__(
2532 " movw (%%edx,%%eax,4),%%ax\n"
2534 " xor %%eax,%%eax\n"
2536 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
2541 :"eax", "cc", "memory"
2543 srcbyte = (srcbits += linebytes);
2544 dstbits -= bmpImage->bytes_per_line;
2552 #if defined(__i386__) && defined(__GNUC__)
2553 if (lines && dstwidth && (bmpImage->bits_per_pixel == 32) &&
2554 (ImageByteOrder(gdi_display)==LSBFirst) )
2556 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2557 /* FIXME: Does this really handle both cases correctly? */
2558 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
2559 for (h = lines ; h--; ) {
2560 int _cl1,_cl2; /* temp outputs for asm below */
2561 /* Borrowed from DirectDraw */
2562 __asm__ __volatile__(
2567 " movl (%%edx,%%eax,4),%%eax\n"
2569 " xor %%eax,%%eax\n"
2571 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
2576 :"eax", "cc", "memory"
2578 srcbyte = (srcbits += linebytes);
2579 dstbits -= bmpImage->bytes_per_line;
2586 break; /* use slow generic case below */
2589 /* ==== pal 8 dib -> any bmp format ==== */
2590 for (h=lines-1; h>=0; h--) {
2591 for (x=left; x<dstwidth+left; x++) {
2592 XPutPixel(bmpImage, x, h, colors[*srcbyte++]);
2594 srcbyte = (srcbits += linebytes);
2598 /***********************************************************************
2599 * X11DRV_DIB_GetImageBits_8
2601 * GetDIBits for an 8-bit deep DIB.
2603 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
2604 DWORD srcwidth, DWORD dstwidth,
2605 RGBQUAD *colors, PALETTEENTRY *srccolors,
2606 XImage *bmpImage, DWORD linebytes )
2615 dstbits = dstbits + ( linebytes * (lines-1) );
2616 linebytes = -linebytes;
2621 * This condition is true when GetImageBits has been called by
2622 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
2623 * 256 colormaps, so we'll just use for for GetDIBits calls.
2624 * (In somes cases, in a updateDIBSection, the returned colors are bad too)
2626 if (!srccolors) goto updatesection;
2628 switch (bmpImage->depth) {
2631 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2633 /* ==== pal 1 bmp -> pal 8 dib ==== */
2634 /* ==== pal 4 bmp -> pal 8 dib ==== */
2635 for (h=lines-1; h>=0; h--) {
2637 for (x=0; x<dstwidth; x++) {
2638 PALETTEENTRY srcval;
2639 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2640 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
2645 dstbits += linebytes;
2653 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2654 /* ==== pal 8 bmp -> pal 8 dib ==== */
2655 const void* srcbits;
2656 const BYTE* srcpixel;
2658 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2659 for (h=0; h<lines; h++) {
2662 for (x = 0; x < dstwidth; x++) {
2663 PALETTEENTRY srcval;
2664 srcval=srccolors[(int)*srcpixel++];
2665 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
2670 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2671 dstbits += linebytes;
2681 const void* srcbits;
2682 const WORD* srcpixel;
2685 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2687 if (bmpImage->green_mask==0x03e0) {
2688 if (bmpImage->red_mask==0x7c00) {
2689 /* ==== rgb 555 bmp -> pal 8 dib ==== */
2690 for (h=0; h<lines; h++) {
2693 for (x=0; x<dstwidth; x++) {
2696 *dstbyte++=X11DRV_DIB_GetNearestIndex
2698 ((srcval >> 7) & 0xf8) | /* r */
2699 ((srcval >> 12) & 0x07),
2700 ((srcval >> 2) & 0xf8) | /* g */
2701 ((srcval >> 7) & 0x07),
2702 ((srcval << 3) & 0xf8) | /* b */
2703 ((srcval >> 2) & 0x07) );
2705 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2706 dstbits += linebytes;
2708 } else if (bmpImage->blue_mask==0x7c00) {
2709 /* ==== bgr 555 bmp -> pal 8 dib ==== */
2710 for (h=0; h<lines; h++) {
2713 for (x=0; x<dstwidth; x++) {
2716 *dstbyte++=X11DRV_DIB_GetNearestIndex
2718 ((srcval << 3) & 0xf8) | /* r */
2719 ((srcval >> 2) & 0x07),
2720 ((srcval >> 2) & 0xf8) | /* g */
2721 ((srcval >> 7) & 0x07),
2722 ((srcval >> 7) & 0xf8) | /* b */
2723 ((srcval >> 12) & 0x07) );
2725 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2726 dstbits += linebytes;
2731 } else if (bmpImage->green_mask==0x07e0) {
2732 if (bmpImage->red_mask==0xf800) {
2733 /* ==== rgb 565 bmp -> pal 8 dib ==== */
2734 for (h=0; h<lines; h++) {
2737 for (x=0; x<dstwidth; x++) {
2740 *dstbyte++=X11DRV_DIB_GetNearestIndex
2742 ((srcval >> 8) & 0xf8) | /* r */
2743 ((srcval >> 13) & 0x07),
2744 ((srcval >> 3) & 0xfc) | /* g */
2745 ((srcval >> 9) & 0x03),
2746 ((srcval << 3) & 0xf8) | /* b */
2747 ((srcval >> 2) & 0x07) );
2749 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2750 dstbits += linebytes;
2752 } else if (bmpImage->blue_mask==0xf800) {
2753 /* ==== bgr 565 bmp -> pal 8 dib ==== */
2754 for (h=0; h<lines; h++) {
2757 for (x=0; x<dstwidth; x++) {
2760 *dstbyte++=X11DRV_DIB_GetNearestIndex
2762 ((srcval << 3) & 0xf8) | /* r */
2763 ((srcval >> 2) & 0x07),
2764 ((srcval >> 3) & 0xfc) | /* g */
2765 ((srcval >> 9) & 0x03),
2766 ((srcval >> 8) & 0xf8) | /* b */
2767 ((srcval >> 13) & 0x07) );
2769 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2770 dstbits += linebytes;
2784 const void* srcbits;
2785 const BYTE *srcbyte;
2787 int bytes_per_pixel;
2789 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2790 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
2792 if (bmpImage->green_mask!=0x00ff00 ||
2793 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2795 } else if (bmpImage->blue_mask==0xff) {
2796 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
2797 for (h=0; h<lines; h++) {
2800 for (x=0; x<dstwidth; x++) {
2801 *dstbyte++=X11DRV_DIB_GetNearestIndex
2806 srcbyte+=bytes_per_pixel;
2808 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2809 dstbits += linebytes;
2812 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
2813 for (h=0; h<lines; h++) {
2816 for (x=0; x<dstwidth; x++) {
2817 *dstbyte++=X11DRV_DIB_GetNearestIndex
2822 srcbyte+=bytes_per_pixel;
2824 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
2825 dstbits += linebytes;
2833 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
2834 bmpImage->depth, bmpImage->red_mask,
2835 bmpImage->green_mask, bmpImage->blue_mask );
2837 /* ==== any bmp format -> pal 8 dib ==== */
2838 for (h=lines-1; h>=0; h--) {
2840 for (x=0; x<dstwidth; x++) {
2841 *dstbyte=X11DRV_DIB_MapColor
2843 XGetPixel(bmpImage, x, h), *dstbyte);
2846 dstbits += linebytes;
2852 /***********************************************************************
2853 * X11DRV_DIB_SetImageBits_RLE8
2855 * SetDIBits for an 8-bit deep compressed DIB.
2857 * This function rewritten 941113 by James Youngman. WINE blew out when I
2858 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
2860 * This was because the algorithm assumed that all RLE8 bitmaps end with the
2861 * 'End of bitmap' escape code. This code is very much laxer in what it
2862 * allows to end the expansion. Possibly too lax. See the note by
2863 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
2864 * bitmap should end with RleEnd, but on the other hand, software exists
2865 * that produces ones that don't and Windows 3.1 doesn't complain a bit
2868 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
2869 * James A. Youngman <mbcstjy@afs.man.ac.uk>
2872 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
2873 DWORD width, DWORD dstwidth,
2874 int left, int *colors,
2877 int x; /* X-positon on each line. Increases. */
2878 int y; /* Line #. Starts at lines-1, decreases */
2879 const BYTE *pIn = bits; /* Pointer to current position in bits */
2880 BYTE length; /* The length pf a run */
2881 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
2884 * Note that the bitmap data is stored by Windows starting at the
2885 * bottom line of the bitmap and going upwards. Within each line,
2886 * the data is stored left-to-right. That's the reason why line
2887 * goes from lines-1 to 0. [JAY]
2897 * If the length byte is not zero (which is the escape value),
2898 * We have a run of length pixels all the same colour. The colour
2899 * index is stored next.
2901 * If the length byte is zero, we need to read the next byte to
2902 * know what to do. [JAY]
2907 * [Run-Length] Encoded mode
2909 int color = colors[*pIn++];
2910 while (length-- && x < dstwidth) XPutPixel(bmpImage, x++, y, color);
2915 * Escape codes (may be an absolute sequence though)
2917 escape_code = (*pIn++);
2926 /* Not all RLE8 bitmaps end with this code. For
2927 * example, Paint Shop Pro produces some that don't.
2928 * That's (I think) what caused the previous
2929 * implementation to fail. [JAY]
2938 default: /* switch to absolute mode */
2939 length = escape_code;
2942 int color = colors[*pIn++];
2948 XPutPixel(bmpImage, x++, y, color);
2951 * If you think for a moment you'll realise that the
2952 * only time we could ever possibly read an odd
2953 * number of bytes is when there is a 0x00 (escape),
2954 * a value >0x02 (absolute mode) and then an odd-
2955 * length run. Therefore this is the only place we
2956 * need to worry about it. Everywhere else the
2957 * bytes are always read in pairs. [JAY]
2959 if (escape_code & 1) pIn++; /* Throw away the pad byte. */
2961 } /* switch (escape_code) : Escape sequence */
2967 /***********************************************************************
2968 * X11DRV_DIB_SetImageBits_16
2970 * SetDIBits for a 16-bit deep DIB.
2972 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
2973 DWORD srcwidth, DWORD dstwidth, int left,
2974 X11DRV_PDEVICE *physDev, DWORD rSrc, DWORD gSrc, DWORD bSrc,
2975 XImage *bmpImage, DWORD linebytes )
2983 srcbits = srcbits + ( linebytes * (lines-1));
2984 linebytes = -linebytes;
2987 switch (bmpImage->depth)
2994 srcbits=srcbits+left*2;
2995 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2997 if (bmpImage->green_mask==0x03e0) {
2998 if (gSrc==bmpImage->green_mask) {
2999 if (rSrc==bmpImage->red_mask) {
3000 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
3001 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
3002 X11DRV_DIB_Convert_any_asis
3005 dstbits,-bmpImage->bytes_per_line);
3006 } else if (rSrc==bmpImage->blue_mask) {
3007 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
3008 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
3009 X11DRV_DIB_Convert_555_reverse
3012 dstbits,-bmpImage->bytes_per_line);
3015 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
3016 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
3017 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
3018 X11DRV_DIB_Convert_565_to_555_asis
3021 dstbits,-bmpImage->bytes_per_line);
3023 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
3024 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
3025 X11DRV_DIB_Convert_565_to_555_reverse
3028 dstbits,-bmpImage->bytes_per_line);
3031 } else if (bmpImage->green_mask==0x07e0) {
3032 if (gSrc==bmpImage->green_mask) {
3033 if (rSrc==bmpImage->red_mask) {
3034 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
3035 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
3036 X11DRV_DIB_Convert_any_asis
3039 dstbits,-bmpImage->bytes_per_line);
3041 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
3042 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
3043 X11DRV_DIB_Convert_565_reverse
3046 dstbits,-bmpImage->bytes_per_line);
3049 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
3050 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
3051 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
3052 X11DRV_DIB_Convert_555_to_565_asis
3055 dstbits,-bmpImage->bytes_per_line);
3057 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
3058 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
3059 X11DRV_DIB_Convert_555_to_565_reverse
3062 dstbits,-bmpImage->bytes_per_line);
3072 if (bmpImage->bits_per_pixel==24) {
3075 srcbits=srcbits+left*2;
3076 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
3078 if (bmpImage->green_mask!=0x00ff00 ||
3079 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3081 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
3082 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
3084 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
3085 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
3086 X11DRV_DIB_Convert_555_to_888_asis
3089 dstbits,-bmpImage->bytes_per_line);
3091 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
3092 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
3093 X11DRV_DIB_Convert_565_to_888_asis
3096 dstbits,-bmpImage->bytes_per_line);
3100 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
3101 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
3102 X11DRV_DIB_Convert_555_to_888_reverse
3105 dstbits,-bmpImage->bytes_per_line);
3107 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
3108 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
3109 X11DRV_DIB_Convert_565_to_888_reverse
3112 dstbits,-bmpImage->bytes_per_line);
3123 srcbits=srcbits+left*2;
3124 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
3126 if (bmpImage->green_mask!=0x00ff00 ||
3127 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3129 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
3130 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
3132 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
3133 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
3134 X11DRV_DIB_Convert_555_to_0888_asis
3137 dstbits,-bmpImage->bytes_per_line);
3139 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
3140 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
3141 X11DRV_DIB_Convert_565_to_0888_asis
3144 dstbits,-bmpImage->bytes_per_line);
3148 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
3149 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
3150 X11DRV_DIB_Convert_555_to_0888_reverse
3153 dstbits,-bmpImage->bytes_per_line);
3155 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
3156 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
3157 X11DRV_DIB_Convert_565_to_0888_reverse
3160 dstbits,-bmpImage->bytes_per_line);
3168 WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3169 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
3170 bmpImage->green_mask, bmpImage->blue_mask );
3176 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
3177 const WORD* srcpixel;
3178 int rShift1,gShift1,bShift1;
3179 int rShift2,gShift2,bShift2;
3182 /* Set color scaling values */
3183 rShift1=16+X11DRV_DIB_MaskToShift(rSrc)-3;
3184 gShift1=16+X11DRV_DIB_MaskToShift(gSrc)-3;
3185 bShift1=16+X11DRV_DIB_MaskToShift(bSrc)-3;
3190 /* Green has 5 bits, like the others */
3194 /* Green has 6 bits, not 5. Compensate. */
3203 /* We could split it into four separate cases to optimize
3204 * but it is probably not worth it.
3206 for (h=lines-1; h>=0; h--) {
3207 srcpixel=(const WORD*)srcbits;
3208 for (x=left; x<dstwidth+left; x++) {
3210 BYTE red,green,blue;
3211 srcval=*srcpixel++ << 16;
3212 red= ((srcval >> rShift1) & 0xf8) |
3213 ((srcval >> rShift2) & 0x07);
3214 green=((srcval >> gShift1) & gMask1) |
3215 ((srcval >> gShift2) & gMask2);
3216 blue= ((srcval >> bShift1) & 0xf8) |
3217 ((srcval >> bShift2) & 0x07);
3218 XPutPixel(bmpImage, x, h,
3219 X11DRV_PALETTE_ToPhysical
3220 (physDev, RGB(red,green,blue)));
3222 srcbits += linebytes;
3230 /***********************************************************************
3231 * X11DRV_DIB_GetImageBits_16
3233 * GetDIBits for an 16-bit deep DIB.
3235 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
3236 DWORD dstwidth, DWORD srcwidth,
3237 PALETTEENTRY *srccolors,
3238 DWORD rDst, DWORD gDst, DWORD bDst,
3239 XImage *bmpImage, DWORD dibpitch )
3244 DWORD linebytes = dibpitch;
3249 dstbits = dstbits + ( linebytes * (lines-1));
3250 linebytes = -linebytes;
3253 switch (bmpImage->depth)
3258 const char* srcbits;
3260 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3262 if (bmpImage->green_mask==0x03e0) {
3263 if (gDst==bmpImage->green_mask) {
3264 if (rDst==bmpImage->red_mask) {
3265 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
3266 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
3267 X11DRV_DIB_Convert_any_asis
3269 srcbits,-bmpImage->bytes_per_line,
3272 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
3273 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
3274 X11DRV_DIB_Convert_555_reverse
3276 srcbits,-bmpImage->bytes_per_line,
3280 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
3281 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
3282 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
3283 X11DRV_DIB_Convert_555_to_565_asis
3285 srcbits,-bmpImage->bytes_per_line,
3288 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
3289 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
3290 X11DRV_DIB_Convert_555_to_565_reverse
3292 srcbits,-bmpImage->bytes_per_line,
3296 } else if (bmpImage->green_mask==0x07e0) {
3297 if (gDst==bmpImage->green_mask) {
3298 if (rDst == bmpImage->red_mask) {
3299 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
3300 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
3301 X11DRV_DIB_Convert_any_asis
3303 srcbits,-bmpImage->bytes_per_line,
3306 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
3307 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
3308 X11DRV_DIB_Convert_565_reverse
3310 srcbits,-bmpImage->bytes_per_line,
3314 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
3315 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
3316 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
3317 X11DRV_DIB_Convert_565_to_555_asis
3319 srcbits,-bmpImage->bytes_per_line,
3322 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
3323 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
3324 X11DRV_DIB_Convert_565_to_555_reverse
3326 srcbits,-bmpImage->bytes_per_line,
3337 if (bmpImage->bits_per_pixel == 24) {
3338 const char* srcbits;
3340 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3342 if (bmpImage->green_mask!=0x00ff00 ||
3343 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3345 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
3346 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
3348 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
3349 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
3350 X11DRV_DIB_Convert_888_to_555_asis
3352 srcbits,-bmpImage->bytes_per_line,
3355 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
3356 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
3357 X11DRV_DIB_Convert_888_to_565_asis
3359 srcbits,-bmpImage->bytes_per_line,
3364 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
3365 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
3366 X11DRV_DIB_Convert_888_to_555_reverse
3368 srcbits,-bmpImage->bytes_per_line,
3371 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
3372 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
3373 X11DRV_DIB_Convert_888_to_565_reverse
3375 srcbits,-bmpImage->bytes_per_line,
3385 const char* srcbits;
3387 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3389 if (bmpImage->green_mask!=0x00ff00 ||
3390 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3392 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
3393 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
3395 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
3396 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
3397 X11DRV_DIB_Convert_0888_to_555_asis
3399 srcbits,-bmpImage->bytes_per_line,
3402 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
3403 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
3404 X11DRV_DIB_Convert_0888_to_565_asis
3406 srcbits,-bmpImage->bytes_per_line,
3411 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
3412 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
3413 X11DRV_DIB_Convert_0888_to_555_reverse
3415 srcbits,-bmpImage->bytes_per_line,
3418 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
3419 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
3420 X11DRV_DIB_Convert_0888_to_565_reverse
3422 srcbits,-bmpImage->bytes_per_line,
3431 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3432 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
3433 int rShift,gShift,bShift;
3436 /* Shift everything 16 bits left so that all shifts are >0,
3437 * even for BGR DIBs. Then a single >> 16 will bring everything
3440 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
3441 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
3442 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
3444 /* 6 bits for the green */
3450 for (h = lines - 1; h >= 0; h--) {
3451 dstpixel=(LPWORD)dstbits;
3452 for (x = 0; x < dstwidth; x++) {
3453 PALETTEENTRY srcval;
3455 srcval=srccolors[XGetPixel(bmpImage, x, h)];
3456 dstval=((srcval.peRed << rShift) & rDst) |
3457 ((srcval.peGreen << gShift) & gDst) |
3458 ((srcval.peBlue << bShift) & bDst);
3459 *dstpixel++=dstval >> 16;
3461 dstbits += linebytes;
3469 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3470 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
3471 int rShift,gShift,bShift;
3472 const BYTE* srcbits;
3473 const BYTE* srcpixel;
3476 /* Shift everything 16 bits left so that all shifts are >0,
3477 * even for BGR DIBs. Then a single >> 16 will bring everything
3480 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
3481 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
3482 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
3484 /* 6 bits for the green */
3490 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3491 for (h=0; h<lines; h++) {
3493 dstpixel=(LPWORD)dstbits;
3494 for (x = 0; x < dstwidth; x++) {
3495 PALETTEENTRY srcval;
3497 srcval=srccolors[(int)*srcpixel++];
3498 dstval=((srcval.peRed << rShift) & rDst) |
3499 ((srcval.peGreen << gShift) & gDst) |
3500 ((srcval.peBlue << bShift) & bDst);
3501 *dstpixel++=dstval >> 16;
3503 srcbits -= bmpImage->bytes_per_line;
3504 dstbits += linebytes;
3514 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
3515 int rShift,gShift,bShift;
3518 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
3519 bmpImage->depth, bmpImage->red_mask,
3520 bmpImage->green_mask, bmpImage->blue_mask,
3523 /* Shift everything 16 bits left so that all shifts are >0,
3524 * even for BGR DIBs. Then a single >> 16 will bring everything
3527 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
3528 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
3529 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
3531 /* 6 bits for the green */
3537 for (h = lines - 1; h >= 0; h--) {
3538 dstpixel=(LPWORD)dstbits;
3539 for (x = 0; x < dstwidth; x++) {
3542 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
3543 dstval=((GetRValue(srcval) << rShift) & rDst) |
3544 ((GetGValue(srcval) << gShift) & gDst) |
3545 ((GetBValue(srcval) << bShift) & bDst);
3546 *dstpixel++=dstval >> 16;
3548 dstbits += linebytes;
3556 /***********************************************************************
3557 * X11DRV_DIB_SetImageBits_24
3559 * SetDIBits for a 24-bit deep DIB.
3561 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
3562 DWORD srcwidth, DWORD dstwidth, int left,
3563 X11DRV_PDEVICE *physDev,
3564 DWORD rSrc, DWORD gSrc, DWORD bSrc,
3565 XImage *bmpImage, DWORD linebytes )
3573 srcbits = srcbits + linebytes * (lines - 1);
3574 linebytes = -linebytes;
3577 switch (bmpImage->depth)
3580 if (bmpImage->bits_per_pixel==24) {
3583 srcbits=srcbits+left*3;
3584 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
3586 if (bmpImage->green_mask!=0x00ff00 ||
3587 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3589 } else if (rSrc==bmpImage->red_mask) {
3590 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
3591 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
3592 X11DRV_DIB_Convert_any_asis
3595 dstbits,-bmpImage->bytes_per_line);
3597 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
3598 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
3599 X11DRV_DIB_Convert_888_reverse
3602 dstbits,-bmpImage->bytes_per_line);
3612 srcbits=srcbits+left*3;
3613 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
3615 if (bmpImage->green_mask!=0x00ff00 ||
3616 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3618 } else if (rSrc==bmpImage->red_mask) {
3619 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
3620 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
3621 X11DRV_DIB_Convert_888_to_0888_asis
3624 dstbits,-bmpImage->bytes_per_line);
3626 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
3627 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
3628 X11DRV_DIB_Convert_888_to_0888_reverse
3631 dstbits,-bmpImage->bytes_per_line);
3641 srcbits=srcbits+left*3;
3642 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
3644 if (bmpImage->green_mask==0x03e0) {
3645 if ((rSrc==0xff0000 && bmpImage->red_mask==0x7f00) ||
3646 (bSrc==0xff0000 && bmpImage->blue_mask==0x7f00)) {
3647 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
3648 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
3649 X11DRV_DIB_Convert_888_to_555_asis
3652 dstbits,-bmpImage->bytes_per_line);
3653 } else if ((rSrc==0xff && bmpImage->red_mask==0x7f00) ||
3654 (bSrc==0xff && bmpImage->blue_mask==0x7f00)) {
3655 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
3656 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
3657 X11DRV_DIB_Convert_888_to_555_reverse
3660 dstbits,-bmpImage->bytes_per_line);
3664 } else if (bmpImage->green_mask==0x07e0) {
3665 if ((rSrc==0xff0000 && bmpImage->red_mask==0xf800) ||
3666 (bSrc==0xff0000 && bmpImage->blue_mask==0xf800)) {
3667 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
3668 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
3669 X11DRV_DIB_Convert_888_to_565_asis
3672 dstbits,-bmpImage->bytes_per_line);
3673 } else if ((rSrc==0xff && bmpImage->red_mask==0xf800) ||
3674 (bSrc==0xff && bmpImage->blue_mask==0xf800)) {
3675 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
3676 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
3677 X11DRV_DIB_Convert_888_to_565_reverse
3680 dstbits,-bmpImage->bytes_per_line);
3692 WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3693 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
3694 bmpImage->green_mask, bmpImage->blue_mask );
3700 /* ==== rgb 888 dib -> any bmp bormat ==== */
3701 const BYTE* srcbyte;
3703 /* Windows only supports one 24bpp DIB format: RGB888 */
3705 for (h = lines - 1; h >= 0; h--) {
3706 srcbyte=(const BYTE*)srcbits;
3707 for (x = left; x < dstwidth+left; x++) {
3708 XPutPixel(bmpImage, x, h,
3709 X11DRV_PALETTE_ToPhysical
3710 (physDev, RGB(srcbyte[2], srcbyte[1], srcbyte[0])));
3713 srcbits += linebytes;
3721 /***********************************************************************
3722 * X11DRV_DIB_GetImageBits_24
3724 * GetDIBits for an 24-bit deep DIB.
3726 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
3727 DWORD dstwidth, DWORD srcwidth,
3728 PALETTEENTRY *srccolors,
3729 DWORD rDst, DWORD gDst, DWORD bDst,
3730 XImage *bmpImage, DWORD linebytes )
3738 dstbits = dstbits + ( linebytes * (lines-1) );
3739 linebytes = -linebytes;
3742 switch (bmpImage->depth)
3745 if (bmpImage->bits_per_pixel==24) {
3746 const char* srcbits;
3748 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3750 if (bmpImage->green_mask!=0x00ff00 ||
3751 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3753 } else if (rDst==bmpImage->red_mask) {
3754 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
3755 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
3756 X11DRV_DIB_Convert_any_asis
3758 srcbits,-bmpImage->bytes_per_line,
3761 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
3762 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
3763 X11DRV_DIB_Convert_888_reverse
3765 srcbits,-bmpImage->bytes_per_line,
3774 const char* srcbits;
3776 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3778 if (bmpImage->green_mask!=0x00ff00 ||
3779 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3781 } else if (rDst==bmpImage->red_mask) {
3782 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3783 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3784 X11DRV_DIB_Convert_0888_to_888_asis
3786 srcbits,-bmpImage->bytes_per_line,
3789 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3790 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3791 X11DRV_DIB_Convert_0888_to_888_reverse
3793 srcbits,-bmpImage->bytes_per_line,
3802 const char* srcbits;
3804 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3806 if (bmpImage->green_mask==0x03e0) {
3807 if ((rDst==0xff0000 && bmpImage->red_mask==0x7f00) ||
3808 (bDst==0xff0000 && bmpImage->blue_mask==0x7f00)) {
3809 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
3810 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
3811 X11DRV_DIB_Convert_555_to_888_asis
3813 srcbits,-bmpImage->bytes_per_line,
3815 } else if ((rDst==0xff && bmpImage->red_mask==0x7f00) ||
3816 (bDst==0xff && bmpImage->blue_mask==0x7f00)) {
3817 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
3818 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
3819 X11DRV_DIB_Convert_555_to_888_reverse
3821 srcbits,-bmpImage->bytes_per_line,
3826 } else if (bmpImage->green_mask==0x07e0) {
3827 if ((rDst==0xff0000 && bmpImage->red_mask==0xf800) ||
3828 (bDst==0xff0000 && bmpImage->blue_mask==0xf800)) {
3829 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
3830 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
3831 X11DRV_DIB_Convert_565_to_888_asis
3833 srcbits,-bmpImage->bytes_per_line,
3835 } else if ((rDst==0xff && bmpImage->red_mask==0xf800) ||
3836 (bDst==0xff && bmpImage->blue_mask==0xf800)) {
3837 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
3838 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
3839 X11DRV_DIB_Convert_565_to_888_reverse
3841 srcbits,-bmpImage->bytes_per_line,
3854 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3855 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
3858 /* Windows only supports one 24bpp DIB format: rgb 888 */
3859 for (h = lines - 1; h >= 0; h--) {
3861 for (x = 0; x < dstwidth; x++) {
3862 PALETTEENTRY srcval;
3863 srcval=srccolors[XGetPixel(bmpImage, x, h)];
3864 dstbyte[0]=srcval.peBlue;
3865 dstbyte[1]=srcval.peGreen;
3866 dstbyte[2]=srcval.peRed;
3869 dstbits += linebytes;
3877 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors) {
3878 /* ==== pal 8 bmp -> rgb 888 dib ==== */
3879 const void* srcbits;
3880 const BYTE* srcpixel;
3883 /* Windows only supports one 24bpp DIB format: rgb 888 */
3884 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3885 for (h = lines - 1; h >= 0; h--) {
3888 for (x = 0; x < dstwidth; x++ ) {
3889 PALETTEENTRY srcval;
3890 srcval=srccolors[(int)*srcpixel++];
3891 dstbyte[0]=srcval.peBlue;
3892 dstbyte[1]=srcval.peGreen;
3893 dstbyte[2]=srcval.peRed;
3896 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
3897 dstbits += linebytes;
3907 /* ==== any bmp format -> 888 dib ==== */
3910 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
3911 bmpImage->depth, bmpImage->red_mask,
3912 bmpImage->green_mask, bmpImage->blue_mask,
3915 /* Windows only supports one 24bpp DIB format: rgb 888 */
3916 for (h = lines - 1; h >= 0; h--) {
3918 for (x = 0; x < dstwidth; x++) {
3919 COLORREF srcval=X11DRV_PALETTE_ToLogical
3920 (XGetPixel( bmpImage, x, h ));
3921 dstbyte[0]=GetBValue(srcval);
3922 dstbyte[1]=GetGValue(srcval);
3923 dstbyte[2]=GetRValue(srcval);
3926 dstbits += linebytes;
3934 /***********************************************************************
3935 * X11DRV_DIB_SetImageBits_32
3937 * SetDIBits for a 32-bit deep DIB.
3939 static void X11DRV_DIB_SetImageBits_32(int lines, const BYTE *srcbits,
3940 DWORD srcwidth, DWORD dstwidth, int left,
3941 X11DRV_PDEVICE *physDev,
3942 DWORD rSrc, DWORD gSrc, DWORD bSrc,
3952 srcbits = srcbits + ( linebytes * (lines-1) );
3953 linebytes = -linebytes;
3956 ptr = (DWORD *) srcbits + left;
3958 switch (bmpImage->depth)
3961 if (bmpImage->bits_per_pixel==24) {
3964 srcbits=srcbits+left*4;
3965 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
3967 if (rSrc==bmpImage->red_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->blue_mask) {
3968 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
3969 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
3970 X11DRV_DIB_Convert_0888_to_888_asis
3973 dstbits,-bmpImage->bytes_per_line);
3974 } else if (bmpImage->green_mask!=0x00ff00 ||
3975 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3977 /* the tests below assume sane bmpImage masks */
3978 } else if (rSrc==bmpImage->blue_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->red_mask) {
3979 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
3980 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
3981 X11DRV_DIB_Convert_0888_to_888_reverse
3984 dstbits,-bmpImage->bytes_per_line);
3985 } else if (bmpImage->blue_mask==0xff) {
3986 /* ==== any 0888 dib -> rgb 888 bmp ==== */
3987 X11DRV_DIB_Convert_any0888_to_rgb888
3991 dstbits,-bmpImage->bytes_per_line);
3993 /* ==== any 0888 dib -> bgr 888 bmp ==== */
3994 X11DRV_DIB_Convert_any0888_to_bgr888
3998 dstbits,-bmpImage->bytes_per_line);
4008 srcbits=srcbits+left*4;
4009 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
4011 if (gSrc==bmpImage->green_mask) {
4012 if (rSrc==bmpImage->red_mask && bSrc==bmpImage->blue_mask) {
4013 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
4014 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
4015 X11DRV_DIB_Convert_any_asis
4018 dstbits,-bmpImage->bytes_per_line);
4019 } else if (bmpImage->green_mask!=0x00ff00 ||
4020 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4022 /* the tests below assume sane bmpImage masks */
4023 } else if (rSrc==bmpImage->blue_mask && bSrc==bmpImage->red_mask) {
4024 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
4025 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
4026 X11DRV_DIB_Convert_0888_reverse
4029 dstbits,-bmpImage->bytes_per_line);
4031 /* ==== any 0888 dib -> any 0888 bmp ==== */
4032 X11DRV_DIB_Convert_0888_any
4036 dstbits,-bmpImage->bytes_per_line,
4037 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4039 } else if (bmpImage->green_mask!=0x00ff00 ||
4040 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4042 /* the tests below assume sane bmpImage masks */
4044 /* ==== any 0888 dib -> any 0888 bmp ==== */
4045 X11DRV_DIB_Convert_0888_any
4049 dstbits,-bmpImage->bytes_per_line,
4050 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4060 srcbits=srcbits+left*4;
4061 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
4063 if (rSrc==0xff0000 && gSrc==0x00ff00 && bSrc==0x0000ff) {
4064 if (bmpImage->green_mask==0x03e0) {
4065 if (bmpImage->red_mask==0x7f00) {
4066 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
4067 X11DRV_DIB_Convert_0888_to_555_asis
4070 dstbits,-bmpImage->bytes_per_line);
4071 } else if (bmpImage->blue_mask==0x7f00) {
4072 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
4073 X11DRV_DIB_Convert_0888_to_555_reverse
4076 dstbits,-bmpImage->bytes_per_line);
4080 } else if (bmpImage->green_mask==0x07e0) {
4081 if (bmpImage->red_mask==0xf800) {
4082 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
4083 X11DRV_DIB_Convert_0888_to_565_asis
4086 dstbits,-bmpImage->bytes_per_line);
4087 } else if (bmpImage->blue_mask==0xf800) {
4088 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
4089 X11DRV_DIB_Convert_0888_to_565_reverse
4092 dstbits,-bmpImage->bytes_per_line);
4099 } else if (rSrc==0x0000ff && gSrc==0x00ff00 && bSrc==0xff0000) {
4100 if (bmpImage->green_mask==0x03e0) {
4101 if (bmpImage->blue_mask==0x7f00) {
4102 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
4103 X11DRV_DIB_Convert_0888_to_555_asis
4106 dstbits,-bmpImage->bytes_per_line);
4107 } else if (bmpImage->red_mask==0x7f00) {
4108 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
4109 X11DRV_DIB_Convert_0888_to_555_reverse
4112 dstbits,-bmpImage->bytes_per_line);
4116 } else if (bmpImage->green_mask==0x07e0) {
4117 if (bmpImage->blue_mask==0xf800) {
4118 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
4119 X11DRV_DIB_Convert_0888_to_565_asis
4122 dstbits,-bmpImage->bytes_per_line);
4123 } else if (bmpImage->red_mask==0xf800) {
4124 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
4125 X11DRV_DIB_Convert_0888_to_565_reverse
4128 dstbits,-bmpImage->bytes_per_line);
4136 if (bmpImage->green_mask==0x03e0 &&
4137 (bmpImage->red_mask==0x7f00 ||
4138 bmpImage->blue_mask==0x7f00)) {
4139 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
4140 X11DRV_DIB_Convert_any0888_to_5x5
4144 dstbits,-bmpImage->bytes_per_line,
4145 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4146 } else if (bmpImage->green_mask==0x07e0 &&
4147 (bmpImage->red_mask==0xf800 ||
4148 bmpImage->blue_mask==0xf800)) {
4149 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
4150 X11DRV_DIB_Convert_any0888_to_5x5
4154 dstbits,-bmpImage->bytes_per_line,
4155 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4165 WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
4166 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
4167 bmpImage->green_mask, bmpImage->blue_mask );
4173 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
4174 const DWORD* srcpixel;
4175 int rShift,gShift,bShift;
4177 rShift=X11DRV_DIB_MaskToShift(rSrc);
4178 gShift=X11DRV_DIB_MaskToShift(gSrc);
4179 bShift=X11DRV_DIB_MaskToShift(bSrc);
4181 for (h = lines - 1; h >= 0; h--) {
4182 srcpixel=(const DWORD*)srcbits;
4183 for (x = left; x < dstwidth+left; x++) {
4185 BYTE red,green,blue;
4186 srcvalue=*srcpixel++;
4187 red= (srcvalue >> rShift) & 0xff;
4188 green=(srcvalue >> gShift) & 0xff;
4189 blue= (srcvalue >> bShift) & 0xff;
4190 XPutPixel(bmpImage, x, h, X11DRV_PALETTE_ToPhysical
4191 (physDev, RGB(red,green,blue)));
4193 srcbits += linebytes;
4201 /***********************************************************************
4202 * X11DRV_DIB_GetImageBits_32
4204 * GetDIBits for an 32-bit deep DIB.
4206 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
4207 DWORD dstwidth, DWORD srcwidth,
4208 PALETTEENTRY *srccolors,
4209 DWORD rDst, DWORD gDst, DWORD bDst,
4210 XImage *bmpImage, DWORD linebytes )
4219 dstbits = dstbits + ( linebytes * (lines-1) );
4220 linebytes = -linebytes;
4225 switch (bmpImage->depth)
4228 if (bmpImage->bits_per_pixel==24) {
4229 const void* srcbits;
4231 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4233 if (rDst==bmpImage->red_mask && gDst==bmpImage->green_mask && bDst==bmpImage->blue_mask) {
4234 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
4235 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
4236 X11DRV_DIB_Convert_888_to_0888_asis
4238 srcbits,-bmpImage->bytes_per_line,
4240 } else if (bmpImage->green_mask!=0x00ff00 ||
4241 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4243 /* the tests below assume sane bmpImage masks */
4244 } else if (rDst==bmpImage->blue_mask && gDst==bmpImage->green_mask && bDst==bmpImage->red_mask) {
4245 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
4246 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
4247 X11DRV_DIB_Convert_888_to_0888_reverse
4249 srcbits,-bmpImage->bytes_per_line,
4251 } else if (bmpImage->blue_mask==0xff) {
4252 /* ==== rgb 888 bmp -> any 0888 dib ==== */
4253 X11DRV_DIB_Convert_rgb888_to_any0888
4255 srcbits,-bmpImage->bytes_per_line,
4259 /* ==== bgr 888 bmp -> any 0888 dib ==== */
4260 X11DRV_DIB_Convert_bgr888_to_any0888
4262 srcbits,-bmpImage->bytes_per_line,
4272 const char* srcbits;
4274 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4276 if (gDst==bmpImage->green_mask) {
4277 if (rDst==bmpImage->red_mask && bDst==bmpImage->blue_mask) {
4278 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
4279 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
4280 X11DRV_DIB_Convert_any_asis
4282 srcbits,-bmpImage->bytes_per_line,
4284 } else if (bmpImage->green_mask!=0x00ff00 ||
4285 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4287 /* the tests below assume sane bmpImage masks */
4288 } else if (rDst==bmpImage->blue_mask && bDst==bmpImage->red_mask) {
4289 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
4290 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
4291 X11DRV_DIB_Convert_0888_reverse
4293 srcbits,-bmpImage->bytes_per_line,
4296 /* ==== any 0888 bmp -> any 0888 dib ==== */
4297 X11DRV_DIB_Convert_0888_any
4299 srcbits,-bmpImage->bytes_per_line,
4300 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4304 } else if (bmpImage->green_mask!=0x00ff00 ||
4305 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4307 /* the tests below assume sane bmpImage masks */
4309 /* ==== any 0888 bmp -> any 0888 dib ==== */
4310 X11DRV_DIB_Convert_0888_any
4312 srcbits,-bmpImage->bytes_per_line,
4313 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4323 const char* srcbits;
4325 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4327 if (rDst==0xff0000 && gDst==0x00ff00 && bDst==0x0000ff) {
4328 if (bmpImage->green_mask==0x03e0) {
4329 if (bmpImage->red_mask==0x7f00) {
4330 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
4331 X11DRV_DIB_Convert_555_to_0888_asis
4333 srcbits,-bmpImage->bytes_per_line,
4335 } else if (bmpImage->blue_mask==0x7f00) {
4336 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
4337 X11DRV_DIB_Convert_555_to_0888_reverse
4339 srcbits,-bmpImage->bytes_per_line,
4344 } else if (bmpImage->green_mask==0x07e0) {
4345 if (bmpImage->red_mask==0xf800) {
4346 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
4347 X11DRV_DIB_Convert_565_to_0888_asis
4349 srcbits,-bmpImage->bytes_per_line,
4351 } else if (bmpImage->blue_mask==0xf800) {
4352 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
4353 X11DRV_DIB_Convert_565_to_0888_reverse
4355 srcbits,-bmpImage->bytes_per_line,
4363 } else if (rDst==0x0000ff && gDst==0x00ff00 && bDst==0xff0000) {
4364 if (bmpImage->green_mask==0x03e0) {
4365 if (bmpImage->blue_mask==0x7f00) {
4366 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
4367 X11DRV_DIB_Convert_555_to_0888_asis
4369 srcbits,-bmpImage->bytes_per_line,
4371 } else if (bmpImage->red_mask==0x7f00) {
4372 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
4373 X11DRV_DIB_Convert_555_to_0888_reverse
4375 srcbits,-bmpImage->bytes_per_line,
4380 } else if (bmpImage->green_mask==0x07e0) {
4381 if (bmpImage->blue_mask==0xf800) {
4382 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
4383 X11DRV_DIB_Convert_565_to_0888_asis
4385 srcbits,-bmpImage->bytes_per_line,
4387 } else if (bmpImage->red_mask==0xf800) {
4388 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
4389 X11DRV_DIB_Convert_565_to_0888_reverse
4391 srcbits,-bmpImage->bytes_per_line,
4400 if (bmpImage->green_mask==0x03e0 &&
4401 (bmpImage->red_mask==0x7f00 ||
4402 bmpImage->blue_mask==0x7f00)) {
4403 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
4404 X11DRV_DIB_Convert_5x5_to_any0888
4406 srcbits,-bmpImage->bytes_per_line,
4407 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4410 } else if (bmpImage->green_mask==0x07e0 &&
4411 (bmpImage->red_mask==0xf800 ||
4412 bmpImage->blue_mask==0xf800)) {
4413 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
4414 X11DRV_DIB_Convert_5x5_to_any0888
4416 srcbits,-bmpImage->bytes_per_line,
4417 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4429 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
4430 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
4431 int rShift,gShift,bShift;
4434 rShift=X11DRV_DIB_MaskToShift(rDst);
4435 gShift=X11DRV_DIB_MaskToShift(gDst);
4436 bShift=X11DRV_DIB_MaskToShift(bDst);
4437 for (h = lines - 1; h >= 0; h--) {
4438 dstpixel=(DWORD*)dstbits;
4439 for (x = 0; x < dstwidth; x++) {
4440 PALETTEENTRY srcval;
4441 srcval = srccolors[XGetPixel(bmpImage, x, h)];
4442 *dstpixel++=(srcval.peRed << rShift) |
4443 (srcval.peGreen << gShift) |
4444 (srcval.peBlue << bShift);
4446 dstbits += linebytes;
4454 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
4455 /* ==== pal 8 bmp -> any 0888 dib ==== */
4456 int rShift,gShift,bShift;
4457 const void* srcbits;
4458 const BYTE* srcpixel;
4461 rShift=X11DRV_DIB_MaskToShift(rDst);
4462 gShift=X11DRV_DIB_MaskToShift(gDst);
4463 bShift=X11DRV_DIB_MaskToShift(bDst);
4464 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4465 for (h = lines - 1; h >= 0; h--) {
4467 dstpixel=(DWORD*)dstbits;
4468 for (x = 0; x < dstwidth; x++) {
4469 PALETTEENTRY srcval;
4470 srcval=srccolors[(int)*srcpixel++];
4471 *dstpixel++=(srcval.peRed << rShift) |
4472 (srcval.peGreen << gShift) |
4473 (srcval.peBlue << bShift);
4475 srcbits = (char*)srcbits - bmpImage->bytes_per_line;
4476 dstbits += linebytes;
4486 /* ==== any bmp format -> any 0888 dib ==== */
4487 int rShift,gShift,bShift;
4490 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
4491 bmpImage->depth, bmpImage->red_mask,
4492 bmpImage->green_mask, bmpImage->blue_mask,
4495 rShift=X11DRV_DIB_MaskToShift(rDst);
4496 gShift=X11DRV_DIB_MaskToShift(gDst);
4497 bShift=X11DRV_DIB_MaskToShift(bDst);
4498 for (h = lines - 1; h >= 0; h--) {
4499 dstpixel=(DWORD*)dstbits;
4500 for (x = 0; x < dstwidth; x++) {
4502 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
4503 *dstpixel++=(GetRValue(srcval) << rShift) |
4504 (GetGValue(srcval) << gShift) |
4505 (GetBValue(srcval) << bShift);
4507 dstbits += linebytes;
4514 /***********************************************************************
4515 * X11DRV_DIB_SetImageBits
4517 * Transfer the bits to an X image.
4518 * Helper function for SetDIBits() and SetDIBitsToDevice().
4520 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
4522 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
4527 bmpImage = descr->image;
4529 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
4530 descr->infoWidth, lines, 32, 0 );
4531 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
4532 if(bmpImage->data == NULL) {
4533 ERR("Out of memory!\n");
4534 XDestroyImage( bmpImage );
4535 wine_tsx11_unlock();
4540 TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
4541 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
4542 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
4543 bmpImage->depth,bmpImage->bits_per_pixel,
4544 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4546 /* Transfer the pixels */
4547 switch(descr->infoBpp)
4550 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
4551 descr->width, descr->xSrc, (int *)(descr->colorMap),
4552 bmpImage, descr->dibpitch );
4555 if (descr->compression) {
4556 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
4557 descr->width, descr->height, AllPlanes, ZPixmap,
4558 bmpImage, descr->xSrc, descr->ySrc );
4560 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
4561 descr->infoWidth, descr->width,
4562 descr->xSrc, (int *)(descr->colorMap),
4565 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
4566 descr->infoWidth, descr->width,
4567 descr->xSrc, (int*)(descr->colorMap),
4568 bmpImage, descr->dibpitch );
4571 if (descr->compression) {
4572 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
4573 descr->width, descr->height, AllPlanes, ZPixmap,
4574 bmpImage, descr->xSrc, descr->ySrc );
4575 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
4576 descr->infoWidth, descr->width,
4577 descr->xSrc, (int *)(descr->colorMap),
4580 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
4581 descr->infoWidth, descr->width,
4582 descr->xSrc, (int *)(descr->colorMap),
4583 bmpImage, descr->dibpitch );
4587 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
4588 descr->infoWidth, descr->width,
4589 descr->xSrc, descr->physDev,
4590 descr->rMask, descr->gMask, descr->bMask,
4591 bmpImage, descr->dibpitch);
4594 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
4595 descr->infoWidth, descr->width,
4596 descr->xSrc, descr->physDev,
4597 descr->rMask, descr->gMask, descr->bMask,
4598 bmpImage, descr->dibpitch);
4601 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
4602 descr->infoWidth, descr->width,
4603 descr->xSrc, descr->physDev,
4604 descr->rMask, descr->gMask, descr->bMask,
4605 bmpImage, descr->dibpitch);
4608 WARN("(%d): Invalid depth\n", descr->infoBpp );
4612 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
4613 descr->drawable, descr->gc, bmpImage,
4614 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
4615 descr->width, descr->height);
4616 #ifdef HAVE_LIBXXSHM
4619 XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
4620 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
4621 descr->width, descr->height, FALSE );
4622 XSync( gdi_display, 0 );
4626 XPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
4627 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
4628 descr->width, descr->height );
4630 if (!descr->image) XDestroyImage( bmpImage );
4631 wine_tsx11_unlock();
4635 /***********************************************************************
4636 * X11DRV_DIB_GetImageBits
4638 * Transfer the bits from an X image.
4640 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
4642 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
4647 bmpImage = descr->image;
4649 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
4650 descr->infoWidth, lines, 32, 0 );
4651 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
4652 if(bmpImage->data == NULL) {
4653 ERR("Out of memory!\n");
4654 XDestroyImage( bmpImage );
4655 wine_tsx11_unlock();
4660 #ifdef HAVE_LIBXXSHM
4663 int saveRed, saveGreen, saveBlue;
4665 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
4666 gdi_display, descr->drawable, bmpImage,
4667 descr->xSrc, descr->ySrc, AllPlanes);
4669 /* We must save and restore the bmpImage's masks in order
4670 * to preserve them across the call to XShmGetImage, which
4671 * decides to eleminate them since it doesn't happen to know
4672 * what the format of the image is supposed to be, even though
4674 saveRed = bmpImage->red_mask;
4675 saveBlue= bmpImage->blue_mask;
4676 saveGreen = bmpImage->green_mask;
4678 XShmGetImage( gdi_display, descr->drawable, bmpImage,
4679 descr->xSrc, descr->ySrc, AllPlanes);
4681 bmpImage->red_mask = saveRed;
4682 bmpImage->blue_mask = saveBlue;
4683 bmpImage->green_mask = saveGreen;
4686 #endif /* HAVE_LIBXXSHM */
4688 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
4689 gdi_display, descr->drawable, descr->xSrc, descr->ySrc, descr->width,
4690 lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
4691 XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc,
4692 descr->width, lines, AllPlanes, ZPixmap,
4693 bmpImage, descr->xDest, descr->yDest );
4696 TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
4697 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
4698 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
4699 bmpImage->depth,bmpImage->bits_per_pixel,
4700 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4701 /* Transfer the pixels */
4702 switch(descr->infoBpp)
4705 X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
4706 descr->infoWidth, descr->width,
4707 descr->colorMap, descr->palentry,
4708 bmpImage, descr->dibpitch );
4712 if (descr->compression)
4713 FIXME("Compression not yet supported!\n");
4715 X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
4716 descr->infoWidth, descr->width,
4717 descr->colorMap, descr->palentry,
4718 bmpImage, descr->dibpitch );
4722 if (descr->compression)
4723 FIXME("Compression not yet supported!\n");
4725 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
4726 descr->infoWidth, descr->width,
4727 descr->colorMap, descr->palentry,
4728 bmpImage, descr->dibpitch );
4732 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
4733 descr->infoWidth,descr->width,
4735 descr->rMask, descr->gMask, descr->bMask,
4736 bmpImage, descr->dibpitch );
4740 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
4741 descr->infoWidth,descr->width,
4743 descr->rMask, descr->gMask, descr->bMask,
4744 bmpImage, descr->dibpitch);
4748 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
4749 descr->infoWidth, descr->width,
4751 descr->rMask, descr->gMask, descr->bMask,
4752 bmpImage, descr->dibpitch);
4756 WARN("(%d): Invalid depth\n", descr->infoBpp );
4760 if (!descr->image) XDestroyImage( bmpImage );
4761 wine_tsx11_unlock();
4765 /*************************************************************************
4766 * X11DRV_SetDIBitsToDevice
4769 INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWORD cx,
4770 DWORD cy, INT xSrc, INT ySrc,
4771 UINT startscan, UINT lines, LPCVOID bits,
4772 const BITMAPINFO *info, UINT coloruse )
4774 X11DRV_DIB_IMAGEBITS_DESCR descr;
4780 DC *dc = physDev->dc;
4782 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
4783 &descr.infoBpp, &descr.compression ) == -1)
4785 top_down = (height < 0);
4786 if (top_down) height = -height;
4790 LPtoDP(physDev->hdc, &pt, 1);
4792 if (!lines || (startscan >= height)) return 0;
4793 if (!top_down && startscan + lines > height) lines = height - startscan;
4795 /* make xSrc,ySrc point to the upper-left corner, not the lower-left one,
4796 * and clamp all values to fit inside [startscan,startscan+lines]
4798 if (ySrc + cy <= startscan + lines)
4800 INT y = startscan + lines - (ySrc + cy);
4801 if (ySrc < startscan) cy -= (startscan - ySrc);
4804 /* avoid getting unnecessary lines */
4806 if (y >= lines) return 0;
4811 if (y >= lines) return lines;
4812 ySrc = y; /* need to get all lines in top down mode */
4817 if (ySrc >= startscan + lines) return lines;
4818 pt.y += ySrc + cy - (startscan + lines);
4819 cy = startscan + lines - ySrc;
4821 if (cy > lines) cy = lines;
4823 if (xSrc >= width) return lines;
4824 if (xSrc + cx >= width) cx = width - xSrc;
4825 if (!cx || !cy) return lines;
4827 X11DRV_SetupGCForText( physDev ); /* To have the correct colors */
4828 TSXSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[dc->ROPmode-1]);
4830 switch (descr.infoBpp)
4835 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
4836 coloruse == DIB_PAL_COLORS ? physDev : NULL, coloruse,
4837 dc->bitsPerPixel, info, &descr.nColorMap );
4838 if (!descr.colorMap) return 0;
4839 descr.rMask = descr.gMask = descr.bMask = 0;
4843 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
4844 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
4845 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
4851 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
4852 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
4853 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
4858 descr.physDev = physDev;
4861 descr.palentry = NULL;
4862 descr.lines = top_down ? -lines : lines;
4863 descr.infoWidth = width;
4864 descr.depth = dc->bitsPerPixel;
4865 descr.drawable = physDev->drawable;
4866 descr.gc = physDev->gc;
4869 descr.xDest = physDev->org.x + pt.x;
4870 descr.yDest = physDev->org.y + pt.y;
4873 descr.useShm = FALSE;
4874 descr.dibpitch = ((width * descr.infoBpp + 31) &~31) / 8;
4876 result = X11DRV_DIB_SetImageBits( &descr );
4878 if (descr.infoBpp <= 8)
4879 HeapFree(GetProcessHeap(), 0, descr.colorMap);
4883 /***********************************************************************
4884 * SetDIBits (X11DRV.@)
4886 INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
4887 UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse )
4889 X11DRV_DIB_IMAGEBITS_DESCR descr;
4891 int height, tmpheight;
4894 descr.physDev = physDev;
4896 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
4897 &descr.infoBpp, &descr.compression ) == -1)
4901 if (height < 0) height = -height;
4902 if (!lines || (startscan >= height))
4905 if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
4907 if (startscan + lines > height) lines = height - startscan;
4909 switch (descr.infoBpp)
4914 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
4915 coloruse == DIB_PAL_COLORS ? descr.physDev : NULL, coloruse,
4916 bmp->bitmap.bmBitsPixel,
4917 info, &descr.nColorMap );
4918 if (!descr.colorMap)
4920 GDI_ReleaseObj( hbitmap );
4923 descr.rMask = descr.gMask = descr.bMask = 0;
4927 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
4928 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
4929 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
4935 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
4936 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
4937 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
4946 descr.palentry = NULL;
4947 descr.lines = tmpheight >= 0 ? lines : -lines;
4948 descr.depth = bmp->bitmap.bmBitsPixel;
4949 descr.drawable = (Pixmap)bmp->physBitmap;
4950 descr.gc = BITMAP_GC(bmp);
4954 descr.yDest = height - startscan - lines;
4955 descr.width = bmp->bitmap.bmWidth;
4956 descr.height = lines;
4957 descr.useShm = FALSE;
4958 descr.dibpitch = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
4959 X11DRV_DIB_Lock(bmp, DIB_Status_GdiMod, FALSE);
4960 result = X11DRV_DIB_SetImageBits( &descr );
4961 X11DRV_DIB_Unlock(bmp, TRUE);
4963 if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);
4965 GDI_ReleaseObj( hbitmap );
4969 /***********************************************************************
4970 * GetDIBits (X11DRV.@)
4972 INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan, UINT lines,
4973 LPVOID bits, BITMAPINFO *info, UINT coloruse )
4975 X11DRV_DIBSECTION *dib;
4976 X11DRV_DIB_IMAGEBITS_DESCR descr;
4977 PALETTEOBJ * palette;
4980 DC *dc = physDev->dc;
4982 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC )))
4984 if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
4986 GDI_ReleaseObj( dc->hPalette );
4989 dib = (X11DRV_DIBSECTION *) bmp->dib;
4991 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
4992 lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
4993 (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
4996 if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
4998 height = info->bmiHeader.biHeight;
4999 if (height < 0) height = -height;
5000 if( lines > height ) lines = height;
5001 /* Top-down images have a negative biHeight, the scanlines of theses images
5002 * were inverted in X11DRV_DIB_GetImageBits_xx
5003 * To prevent this we simply change the sign of lines
5004 * (the number of scan lines to copy).
5005 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
5007 if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
5009 if( startscan >= bmp->bitmap.bmHeight )
5015 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
5016 &descr.infoBpp, &descr.compression ) == -1)
5022 switch (descr.infoBpp)
5027 descr.rMask= descr.gMask = descr.bMask = 0;
5031 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
5032 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
5033 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
5037 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
5038 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
5039 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
5043 descr.physDev = physDev;
5044 descr.palentry = palette->logpalette.palPalEntry;
5047 descr.lines = lines;
5048 descr.depth = bmp->bitmap.bmBitsPixel;
5049 descr.drawable = (Pixmap)bmp->physBitmap;
5050 descr.gc = BITMAP_GC(bmp);
5051 descr.width = bmp->bitmap.bmWidth;
5052 descr.height = bmp->bitmap.bmHeight;
5053 descr.colorMap = info->bmiColors;
5058 if (descr.lines > 0)
5060 descr.ySrc = (descr.height-1) - (startscan + (lines-1));
5064 descr.ySrc = startscan;
5066 #ifdef HAVE_LIBXXSHM
5067 descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
5069 descr.useShm = FALSE;
5071 descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
5072 : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
5074 X11DRV_DIB_Lock(bmp, DIB_Status_GdiMod, FALSE);
5075 X11DRV_DIB_GetImageBits( &descr );
5076 X11DRV_DIB_Unlock(bmp, TRUE);
5078 if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
5079 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
5080 info->bmiHeader.biWidth,
5081 info->bmiHeader.biHeight,
5082 info->bmiHeader.biBitCount );
5084 if (descr.compression == BI_BITFIELDS)
5086 *(DWORD *)info->bmiColors = descr.rMask;
5087 *((DWORD *)info->bmiColors+1) = descr.gMask;
5088 *((DWORD *)info->bmiColors+2) = descr.bMask;
5092 /* if RLE or JPEG compression were supported,
5093 * this line would be invalid. */
5094 info->bmiHeader.biCompression = 0;
5098 GDI_ReleaseObj( dc->hPalette );
5099 GDI_ReleaseObj( hbitmap );
5103 /***********************************************************************
5104 * DIB_DoProtectDIBSection
5106 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
5108 DIBSECTION *dib = bmp->dib;
5109 INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
5110 : -dib->dsBm.bmHeight;
5111 /* use the biSizeImage data as the memory size only if we're dealing with a
5112 compressed image where the value is set. Otherwise, calculate based on
5114 INT totalSize = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
5115 ? dib->dsBmih.biSizeImage
5116 : dib->dsBm.bmWidthBytes * effHeight;
5119 VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
5120 TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
5123 /***********************************************************************
5124 * X11DRV_DIB_DoUpdateDIBSection
5126 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
5127 void *colorMap, int nColorMap,
5129 DWORD xSrc, DWORD ySrc,
5130 DWORD xDest, DWORD yDest,
5131 DWORD width, DWORD height)
5133 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5134 X11DRV_DIB_IMAGEBITS_DESCR descr;
5136 if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
5137 &descr.infoBpp, &descr.compression ) == -1)
5140 descr.physDev = NULL;
5141 descr.palentry = NULL;
5142 descr.image = dib->image;
5143 descr.colorMap = colorMap;
5144 descr.nColorMap = nColorMap;
5145 descr.bits = dib->dibSection.dsBm.bmBits;
5146 descr.depth = bmp->bitmap.bmBitsPixel;
5148 switch (descr.infoBpp)
5153 descr.rMask = descr.gMask = descr.bMask = 0;
5157 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
5158 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
5159 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
5164 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff0000;
5165 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x00ff00;
5166 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x0000ff;
5171 descr.drawable = dest;
5172 descr.gc = BITMAP_GC(bmp);
5175 descr.xDest = xDest;
5176 descr.yDest = yDest;
5177 descr.width = width;
5178 descr.height = height;
5179 #ifdef HAVE_LIBXXSHM
5180 descr.useShm = (dib->shminfo.shmid != -1);
5182 descr.useShm = FALSE;
5184 descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
5188 TRACE("Copying from Pixmap to DIB bits\n");
5189 X11DRV_DIB_GetImageBits( &descr );
5193 TRACE("Copying from DIB bits to Pixmap\n");
5194 X11DRV_DIB_SetImageBits( &descr );
5198 /***********************************************************************
5199 * X11DRV_DIB_CopyDIBSection
5201 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
5202 DWORD xSrc, DWORD ySrc, DWORD xDest, DWORD yDest,
5203 DWORD width, DWORD height)
5206 DC *dcSrc = physDevSrc->dc;
5207 DC *dcDst = physDevDst->dc;
5208 int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE;
5210 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc, dcDst,
5211 xSrc, ySrc, xDest, yDest, width, height);
5212 /* this function is meant as an optimization for BitBlt,
5213 * not to be called otherwise */
5214 if (GetObjectType( physDevSrc->hdc ) != OBJ_MEMDC) {
5215 ERR("called for non-memory source DC!?\n");
5219 bmp = (BITMAPOBJ *)GDI_GetObjPtr( dcSrc->hBitmap, BITMAP_MAGIC );
5220 if (!(bmp && bmp->dib)) {
5221 ERR("called for non-DIBSection!?\n");
5222 GDI_ReleaseObj( dcSrc->hBitmap );
5225 /* while BitBlt should already have made sure we only get
5226 * positive values, we should check for oversize values */
5227 if ((xSrc < bmp->bitmap.bmWidth) &&
5228 (ySrc < bmp->bitmap.bmHeight)) {
5229 if (xSrc + width > bmp->bitmap.bmWidth)
5230 width = bmp->bitmap.bmWidth - xSrc;
5231 if (ySrc + height > bmp->bitmap.bmHeight)
5232 height = bmp->bitmap.bmHeight - ySrc;
5233 /* if the source bitmap is 8bpp or less, we're supposed to use the
5234 * DC's palette for color conversion (not the DIB color table) */
5235 if (bmp->dib->dsBm.bmBitsPixel <= 8) {
5236 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5237 if ((!dcSrc->hPalette) ||
5238 (dcSrc->hPalette == GetStockObject(DEFAULT_PALETTE))) {
5239 /* HACK: no palette has been set in the source DC,
5240 * use the DIB colormap instead - this is necessary in some
5241 * cases since we need to do depth conversion in some places
5242 * where real Windows can just copy data straight over */
5243 colorMap = dib->colorMap;
5244 nColorMap = dib->nColorMap;
5246 colorMap = X11DRV_DIB_BuildColorMap( physDevSrc, (WORD)-1,
5247 bmp->dib->dsBm.bmBitsPixel,
5248 (BITMAPINFO*)&(bmp->dib->dsBmih),
5250 if (colorMap) aColorMap = TRUE;
5253 /* perform the copy */
5254 X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap,
5255 physDevDst->drawable, xSrc, ySrc,
5256 physDevDst->org.x + xDest, physDevDst->org.y + yDest,
5258 /* free color mapping */
5260 HeapFree(GetProcessHeap(), 0, colorMap);
5262 GDI_ReleaseObj( dcSrc->hBitmap );
5265 /***********************************************************************
5266 * X11DRV_DIB_DoUpdateDIBSection
5268 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
5270 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5271 X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap,
5272 (Drawable)bmp->physBitmap, 0, 0, 0, 0,
5273 bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
5276 /***********************************************************************
5277 * X11DRV_DIB_FaultHandler
5279 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
5284 bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
5285 if (!bmp) return FALSE;
5287 state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
5288 if (state != DIB_Status_InSync) {
5289 /* no way to tell whether app needs read or write yet,
5291 X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
5293 /* hm, apparently the app must have write access */
5294 X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
5296 X11DRV_DIB_Unlock(bmp, TRUE);
5298 GDI_ReleaseObj( (HBITMAP)res );
5302 /***********************************************************************
5305 INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
5307 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5308 INT ret = DIB_Status_None;
5311 EnterCriticalSection(&(dib->lock));
5314 case DIB_Status_GdiMod:
5315 /* GDI access - request to draw on pixmap */
5316 switch (dib->status)
5319 case DIB_Status_None:
5320 dib->p_status = DIB_Status_GdiMod;
5321 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
5324 case DIB_Status_GdiMod:
5325 TRACE("GdiMod requested in status GdiMod\n" );
5328 case DIB_Status_InSync:
5329 TRACE("GdiMod requested in status InSync\n" );
5330 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5331 dib->status = DIB_Status_GdiMod;
5332 dib->p_status = DIB_Status_InSync;
5335 case DIB_Status_AuxMod:
5336 TRACE("GdiMod requested in status AuxMod\n" );
5337 if (lossy) dib->status = DIB_Status_GdiMod;
5338 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
5339 dib->p_status = DIB_Status_AuxMod;
5340 if (dib->status != DIB_Status_AppMod) {
5341 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5344 /* fall through if copy_aux() had to change to AppMod state */
5346 case DIB_Status_AppMod:
5347 TRACE("GdiMod requested in status AppMod\n" );
5349 /* make it readonly to avoid app changing data while we copy */
5350 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5351 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
5353 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5354 dib->p_status = DIB_Status_AppMod;
5355 dib->status = DIB_Status_GdiMod;
5360 case DIB_Status_InSync:
5361 /* App access - request access to read DIB surface */
5362 /* (typically called from signal handler) */
5363 switch (dib->status)
5366 case DIB_Status_None:
5367 /* shouldn't happen from signal handler */
5370 case DIB_Status_AuxMod:
5371 TRACE("InSync requested in status AuxMod\n" );
5372 if (lossy) dib->status = DIB_Status_InSync;
5374 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5375 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
5377 if (dib->status != DIB_Status_GdiMod) {
5378 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5381 /* fall through if copy_aux() had to change to GdiMod state */
5383 case DIB_Status_GdiMod:
5384 TRACE("InSync requested in status GdiMod\n" );
5386 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5387 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
5389 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5390 dib->status = DIB_Status_InSync;
5393 case DIB_Status_InSync:
5394 TRACE("InSync requested in status InSync\n" );
5395 /* shouldn't happen from signal handler */
5398 case DIB_Status_AppMod:
5399 TRACE("InSync requested in status AppMod\n" );
5400 /* no reason to do anything here, and this
5401 * shouldn't happen from signal handler */
5406 case DIB_Status_AppMod:
5407 /* App access - request access to write DIB surface */
5408 /* (typically called from signal handler) */
5409 switch (dib->status)
5412 case DIB_Status_None:
5413 /* shouldn't happen from signal handler */
5416 case DIB_Status_AuxMod:
5417 TRACE("AppMod requested in status AuxMod\n" );
5418 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5419 if (lossy) dib->status = DIB_Status_AppMod;
5420 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
5421 if (dib->status != DIB_Status_GdiMod)
5423 /* fall through if copy_aux() had to change to GdiMod state */
5425 case DIB_Status_GdiMod:
5426 TRACE("AppMod requested in status GdiMod\n" );
5427 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5428 if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
5429 dib->status = DIB_Status_AppMod;
5432 case DIB_Status_InSync:
5433 TRACE("AppMod requested in status InSync\n" );
5434 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5435 dib->status = DIB_Status_AppMod;
5438 case DIB_Status_AppMod:
5439 TRACE("AppMod requested in status AppMod\n" );
5440 /* shouldn't happen from signal handler */
5445 case DIB_Status_AuxMod:
5446 if (dib->status == DIB_Status_None) {
5447 dib->p_status = req;
5449 if (dib->status != DIB_Status_AuxMod)
5450 dib->p_status = dib->status;
5451 dib->status = DIB_Status_AuxMod;
5454 /* it is up to the caller to do the copy/conversion, probably
5455 * using the return value to decide where to copy from */
5457 LeaveCriticalSection(&(dib->lock));
5462 /***********************************************************************
5465 INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
5467 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5468 INT ret = DIB_Status_None;
5471 TRACE("Locking %p from thread %04lx\n", bmp, GetCurrentThreadId());
5472 EnterCriticalSection(&(dib->lock));
5474 if (req != DIB_Status_None)
5475 X11DRV_DIB_Coerce(bmp, req, lossy);
5480 /***********************************************************************
5483 void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
5485 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5488 switch (dib->status)
5491 case DIB_Status_None:
5492 /* in case anyone is wondering, this is the "signal handler doesn't
5493 * work" case, where we always have to be ready for app access */
5495 switch (dib->p_status)
5497 case DIB_Status_AuxMod:
5498 TRACE("Unlocking and syncing from AuxMod\n" );
5499 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
5500 if (dib->status != DIB_Status_None) {
5501 dib->p_status = dib->status;
5502 dib->status = DIB_Status_None;
5504 if (dib->p_status != DIB_Status_GdiMod)
5506 /* fall through if copy_aux() had to change to GdiMod state */
5508 case DIB_Status_GdiMod:
5509 TRACE("Unlocking and syncing from GdiMod\n" );
5510 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
5514 TRACE("Unlocking without needing to sync\n" );
5518 else TRACE("Unlocking with no changes\n");
5519 dib->p_status = DIB_Status_None;
5522 case DIB_Status_GdiMod:
5523 TRACE("Unlocking in status GdiMod\n" );
5524 /* DIB was protected in Coerce */
5526 /* no commit, revert to InSync if applicable */
5527 if ((dib->p_status == DIB_Status_InSync) ||
5528 (dib->p_status == DIB_Status_AppMod)) {
5529 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5530 dib->status = DIB_Status_InSync;
5535 case DIB_Status_InSync:
5536 TRACE("Unlocking in status InSync\n" );
5537 /* DIB was already protected in Coerce */
5540 case DIB_Status_AppMod:
5541 TRACE("Unlocking in status AppMod\n" );
5542 /* DIB was already protected in Coerce */
5543 /* this case is ordinary only called from the signal handler,
5544 * so we don't bother to check for !commit */
5547 case DIB_Status_AuxMod:
5548 TRACE("Unlocking in status AuxMod\n" );
5550 /* DIB may need protection now */
5551 if ((dib->p_status == DIB_Status_InSync) ||
5552 (dib->p_status == DIB_Status_AppMod))
5553 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5555 /* no commit, revert to previous state */
5556 if (dib->p_status != DIB_Status_None)
5557 dib->status = dib->p_status;
5558 /* no protections changed */
5560 dib->p_status = DIB_Status_None;
5563 LeaveCriticalSection(&(dib->lock));
5564 TRACE("Unlocked %p\n", bmp);
5568 /***********************************************************************
5569 * X11DRV_CoerceDIBSection2
5571 INT X11DRV_CoerceDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
5576 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5577 if (!bmp) return DIB_Status_None;
5578 ret = X11DRV_DIB_Coerce(bmp, req, lossy);
5579 GDI_ReleaseObj( hBmp );
5583 /***********************************************************************
5584 * X11DRV_LockDIBSection2
5586 INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
5591 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5592 if (!bmp) return DIB_Status_None;
5593 ret = X11DRV_DIB_Lock(bmp, req, lossy);
5594 GDI_ReleaseObj( hBmp );
5598 /***********************************************************************
5599 * X11DRV_UnlockDIBSection2
5601 void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
5605 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5607 X11DRV_DIB_Unlock(bmp, commit);
5608 GDI_ReleaseObj( hBmp );
5611 /***********************************************************************
5612 * X11DRV_CoerceDIBSection
5614 INT X11DRV_CoerceDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
5616 if (!physDev) return DIB_Status_None;
5617 return X11DRV_CoerceDIBSection2( physDev->dc->hBitmap, req, lossy );
5620 /***********************************************************************
5621 * X11DRV_LockDIBSection
5623 INT X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
5625 if (!physDev) return DIB_Status_None;
5626 if (GetObjectType( physDev->hdc ) != OBJ_MEMDC) return DIB_Status_None;
5628 return X11DRV_LockDIBSection2( physDev->dc->hBitmap, req, lossy );
5631 /***********************************************************************
5632 * X11DRV_UnlockDIBSection
5634 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE *physDev, BOOL commit)
5636 if (!physDev) return;
5637 if (GetObjectType( physDev->hdc ) != OBJ_MEMDC) return;
5639 X11DRV_UnlockDIBSection2( physDev->dc->hBitmap, commit );
5643 #ifdef HAVE_LIBXXSHM
5644 /***********************************************************************
5645 * X11DRV_XShmErrorHandler
5648 static int XShmErrorHandler( Display *dpy, XErrorEvent *event, void *arg )
5650 return 1; /* FIXME: should check event contents */
5653 /***********************************************************************
5654 * X11DRV_XShmCreateImage
5657 static XImage *X11DRV_XShmCreateImage( int width, int height, int bpp,
5658 XShmSegmentInfo* shminfo)
5662 image = XShmCreateImage(gdi_display, visual, bpp, ZPixmap, NULL, shminfo, width, height);
5665 shminfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height,
5667 if( shminfo->shmid != -1 )
5669 shminfo->shmaddr = image->data = shmat(shminfo->shmid, 0, 0);
5670 if( shminfo->shmaddr != (char*)-1 )
5674 shminfo->readOnly = FALSE;
5675 X11DRV_expect_error( gdi_display, XShmErrorHandler, NULL );
5676 ok = (XShmAttach( gdi_display, shminfo ) != 0);
5677 if (X11DRV_check_error()) ok = FALSE;
5680 shmctl(shminfo->shmid, IPC_RMID, 0);
5681 return image; /* Success! */
5683 /* An error occurred */
5684 shmdt(shminfo->shmaddr);
5686 shmctl(shminfo->shmid, IPC_RMID, 0);
5688 XFlush(gdi_display);
5689 XDestroyImage(image);
5694 #endif /* HAVE_LIBXXSHM */
5697 /***********************************************************************
5698 * X11DRV_DIB_CreateDIBSection
5700 HBITMAP X11DRV_DIB_CreateDIBSection(
5701 X11DRV_PDEVICE *physDev, BITMAPINFO *bmi, UINT usage,
5702 LPVOID *bits, HANDLE section,
5703 DWORD offset, DWORD ovr_pitch)
5706 BITMAPOBJ *bmp = NULL;
5707 X11DRV_DIBSECTION *dib = NULL;
5708 int *colorMap = NULL;
5711 /* Fill BITMAP32 structure with DIB data */
5712 BITMAPINFOHEADER *bi = &bmi->bmiHeader;
5713 INT effHeight, totalSize;
5715 LPVOID mapBits = NULL;
5717 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
5718 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
5719 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
5721 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
5723 bm.bmWidth = bi->biWidth;
5724 bm.bmHeight = effHeight;
5725 bm.bmWidthBytes = ovr_pitch ? ovr_pitch
5726 : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
5727 bm.bmPlanes = bi->biPlanes;
5728 bm.bmBitsPixel = bi->biBitCount;
5731 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
5732 we're dealing with a compressed bitmap. Otherwise, use width * height. */
5733 totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
5734 ? bi->biSizeImage : bm.bmWidthBytes * effHeight;
5738 SYSTEM_INFO SystemInfo;
5742 GetSystemInfo( &SystemInfo );
5743 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
5744 mapSize = totalSize + (offset - mapOffset);
5745 mapBits = MapViewOfFile( section,
5746 FILE_MAP_ALL_ACCESS,
5750 bm.bmBits = (char *)mapBits + (offset - mapOffset);
5752 else if (ovr_pitch && offset)
5753 bm.bmBits = (LPVOID) offset;
5756 bm.bmBits = VirtualAlloc(NULL, totalSize,
5757 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
5760 /* Create Color Map */
5761 if (bm.bmBits && bm.bmBitsPixel <= 8)
5762 colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? physDev : NULL,
5763 usage, bm.bmBitsPixel, bmi, &nColorMap );
5765 /* Allocate Memory for DIB and fill structure */
5767 dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
5770 dib->dibSection.dsBm = bm;
5771 dib->dibSection.dsBmih = *bi;
5772 dib->dibSection.dsBmih.biSizeImage = totalSize;
5774 /* Set dsBitfields values */
5775 if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
5777 dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
5779 else switch( bi->biBitCount )
5783 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
5784 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
5785 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
5790 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff0000;
5791 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x00ff00;
5792 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x0000ff;
5795 dib->dibSection.dshSection = section;
5796 dib->dibSection.dsOffset = offset;
5798 dib->status = DIB_Status_None;
5799 dib->nColorMap = nColorMap;
5800 dib->colorMap = colorMap;
5803 /* Create Device Dependent Bitmap and add DIB pointer */
5806 res = CreateDIBitmap(physDev->hdc, bi, 0, NULL, bmi, usage);
5809 bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
5810 if (bmp) bmp->dib = (DIBSECTION *) dib;
5818 #ifdef HAVE_LIBXXSHM
5819 if (XShmQueryExtension(gdi_display) &&
5820 (dib->image = X11DRV_XShmCreateImage( bm.bmWidth, effHeight,
5821 bmp->bitmap.bmBitsPixel, &dib->shminfo )) )
5823 ; /* Created Image */
5825 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
5826 dib->shminfo.shmid = -1;
5829 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
5831 wine_tsx11_unlock();
5834 /* Clean up in case of errors */
5835 if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
5837 TRACE("got an error res=%p, bmp=%p, dib=%p, bm.bmBits=%p\n",
5838 res, bmp, dib, bm.bmBits);
5842 UnmapViewOfFile(mapBits), bm.bmBits = NULL;
5844 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
5847 if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
5848 if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
5849 if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
5850 if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
5851 if (res) { DeleteObject(res); res = 0; }
5855 /* Install fault handler, if possible */
5856 InitializeCriticalSection(&(dib->lock));
5857 if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
5859 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5860 if (dib) dib->status = DIB_Status_AppMod;
5864 /* Return BITMAP handle and storage location */
5865 if (bmp) GDI_ReleaseObj(res);
5866 if (bm.bmBits && bits) *bits = bm.bmBits;
5870 /***********************************************************************
5871 * X11DRV_DIB_DeleteDIBSection
5873 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
5875 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5880 #ifdef HAVE_LIBXXSHM
5881 if (dib->shminfo.shmid != -1)
5883 XShmDetach (gdi_display, &(dib->shminfo));
5884 XDestroyImage (dib->image);
5885 shmdt (dib->shminfo.shmaddr);
5886 dib->shminfo.shmid = -1;
5890 XDestroyImage( dib->image );
5891 wine_tsx11_unlock();
5895 HeapFree(GetProcessHeap(), 0, dib->colorMap);
5897 DeleteCriticalSection(&(dib->lock));
5900 /***********************************************************************
5901 * SetDIBColorTable (X11DRV.@)
5903 UINT X11DRV_SetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, const RGBQUAD *colors )
5906 X11DRV_DIBSECTION *dib;
5909 if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( physDev->dc->hBitmap, BITMAP_MAGIC ))) return 0;
5910 dib = (X11DRV_DIBSECTION *) bmp->dib;
5912 if (dib && dib->colorMap) {
5913 UINT end = count + start;
5914 if (end > dib->nColorMap) end = dib->nColorMap;
5916 * Changing color table might change the mapping between
5917 * DIB colors and X11 colors and thus alter the visible state
5918 * of the bitmap object.
5920 X11DRV_DIB_Lock(bmp, DIB_Status_AppMod, FALSE);
5921 X11DRV_DIB_GenColorMap( physDev, dib->colorMap, DIB_RGB_COLORS,
5922 dib->dibSection.dsBm.bmBitsPixel,
5923 TRUE, colors, start, end );
5924 X11DRV_DIB_Unlock(bmp, TRUE);
5927 GDI_ReleaseObj( physDev->dc->hBitmap );
5931 /***********************************************************************
5932 * GetDIBColorTable (X11DRV.@)
5934 UINT X11DRV_GetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, RGBQUAD *colors )
5937 X11DRV_DIBSECTION *dib;
5940 if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( physDev->dc->hBitmap, BITMAP_MAGIC ))) return 0;
5941 dib = (X11DRV_DIBSECTION *) bmp->dib;
5943 if (dib && dib->colorMap) {
5944 UINT i, end = count + start;
5945 if (end > dib->nColorMap) end = dib->nColorMap;
5946 for (i = start; i < end; i++,colors++) {
5947 COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] );
5948 colors->rgbBlue = GetBValue(col);
5949 colors->rgbGreen = GetGValue(col);
5950 colors->rgbRed = GetRValue(col);
5951 colors->rgbReserved = 0;
5955 GDI_ReleaseObj( physDev->dc->hBitmap );
5960 /**************************************************************************
5961 * X11DRV_DIB_CreateDIBFromPixmap
5963 * Allocates a packed DIB and copies the Pixmap data into it.
5964 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
5966 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
5969 BITMAPOBJ *pBmp = NULL;
5970 HGLOBAL hPackedDIB = 0;
5972 /* Allocates an HBITMAP which references the Pixmap passed to us */
5973 hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap);
5976 TRACE("\tCould not create bitmap header for Pixmap\n");
5981 * Create a packed DIB from the Pixmap wrapper bitmap created above.
5982 * A packed DIB contains a BITMAPINFO structure followed immediately by
5983 * an optional color palette and the pixel data.
5985 hPackedDIB = DIB_CreateDIBFromBitmap(hdc, hBmp);
5987 /* Get a pointer to the BITMAPOBJ structure */
5988 pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5990 /* We can now get rid of the HBITMAP wrapper we created earlier.
5991 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
5995 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
5996 pBmp->physBitmap = NULL;
5999 GDI_ReleaseObj( hBmp );
6003 TRACE("\tReturning packed DIB %p\n", hPackedDIB);
6008 /**************************************************************************
6009 * X11DRV_DIB_CreatePixmapFromDIB
6011 * Creates a Pixmap from a packed DIB
6013 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
6015 Pixmap pixmap = None;
6017 BITMAPOBJ *pBmp = NULL;
6018 LPBYTE pPackedDIB = NULL;
6019 LPBITMAPINFO pbmi = NULL;
6020 LPBITMAPINFOHEADER pbmiHeader = NULL;
6021 LPBYTE pbits = NULL;
6023 /* Get a pointer to the packed DIB's data */
6024 pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
6025 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
6026 pbmi = (LPBITMAPINFO)pPackedDIB;
6027 pbits = (LPBYTE)(pPackedDIB
6028 + DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
6030 /* Create a DDB from the DIB */
6032 hBmp = CreateDIBitmap(hdc,
6039 GlobalUnlock(hPackedDIB);
6041 TRACE("CreateDIBitmap returned %p\n", hBmp);
6043 /* Retrieve the internal Pixmap from the DDB */
6045 pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
6047 pixmap = (Pixmap)pBmp->physBitmap;
6048 /* clear the physBitmap so that we can steal its pixmap */
6049 pBmp->physBitmap = NULL;
6052 /* Delete the DDB we created earlier now that we have stolen its pixmap */
6053 GDI_ReleaseObj( hBmp );
6056 TRACE("\tReturning Pixmap %ld\n", pixmap);