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
27 # ifdef HAVE_SYS_SHM_H
30 # ifdef HAVE_SYS_IPC_H
33 #endif /* defined(HAVE_LIBXXSHM) */
40 #include "wine/debug.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
46 WINE_DECLARE_DEBUG_CHANNEL(x11drv);
48 static int ximageDepthTable[32];
50 /* This structure holds the arguments for DIB_SetImageBits() */
53 X11DRV_PDEVICE *physDev;
56 PALETTEENTRY *palentry;
77 } X11DRV_DIB_IMAGEBITS_DESCR;
82 RLE_EOL = 0, /* End of line */
83 RLE_END = 1, /* End of bitmap */
84 RLE_DELTA = 2 /* Delta */
87 /***********************************************************************
88 * X11DRV_DIB_GetXImageWidthBytes
90 * Return the width of an X image in bytes
92 inline static int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
94 if (!depth || depth > 32) goto error;
96 if (!ximageDepthTable[depth-1])
98 XImage *testimage = XCreateImage( gdi_display, visual, depth,
99 ZPixmap, 0, NULL, 1, 1, 32, 20 );
102 ximageDepthTable[depth-1] = testimage->bits_per_pixel;
103 XDestroyImage( testimage );
105 else ximageDepthTable[depth-1] = -1;
107 if (ximageDepthTable[depth-1] != -1)
108 return (4 * ((width * ximageDepthTable[depth-1] + 31) / 32));
111 WARN( "(%d): Unsupported depth\n", depth );
116 /***********************************************************************
117 * X11DRV_DIB_CreateXImage
121 XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth )
127 width_bytes = X11DRV_DIB_GetXImageWidthBytes( width, depth );
128 image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0,
129 calloc( height, width_bytes ),
130 width, height, 32, width_bytes );
136 /***********************************************************************
137 * X11DRV_DIB_GenColorMap
139 * Fills the color map of a bitmap palette. Should not be called
140 * for a >8-bit deep bitmap.
142 int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
143 WORD coloruse, WORD depth, BOOL quads,
144 const void *colorPtr, int start, int end )
148 if (coloruse == DIB_RGB_COLORS)
150 int max = 1 << depth;
152 if (end > max) end = max;
156 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
158 if (depth == 1) /* Monochrome */
159 for (i = start; i < end; i++, rgb++)
160 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
161 rgb->rgbBlue > 255*3/2);
163 for (i = start; i < end; i++, rgb++)
164 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbRed,
170 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
172 if (depth == 1) /* Monochrome */
173 for (i = start; i < end; i++, rgb++)
174 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
175 rgb->rgbtBlue > 255*3/2);
177 for (i = start; i < end; i++, rgb++)
178 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, RGB(rgb->rgbtRed,
183 else /* DIB_PAL_COLORS */
186 WORD * index = (WORD *)colorPtr;
188 for (i = start; i < end; i++, index++)
189 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(*index) );
191 for (i = start; i < end; i++)
192 colorMapping[i] = X11DRV_PALETTE_ToPhysical( physDev, PALETTEINDEX(i) );
199 /***********************************************************************
200 * X11DRV_DIB_BuildColorMap
202 * Build the color map from the bitmap palette. Should not be called
203 * for a >8-bit deep bitmap.
205 int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
206 const BITMAPINFO *info, int *nColors )
210 const void *colorPtr;
213 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
215 colors = info->bmiHeader.biClrUsed;
216 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
217 colorPtr = info->bmiColors;
219 else /* assume BITMAPCOREINFO */
221 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
222 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
227 ERR("called with >256 colors!\n");
231 /* just so CopyDIBSection doesn't have to create an identity palette */
232 if (coloruse == (WORD)-1) colorPtr = NULL;
234 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
235 colors * sizeof(int) )))
239 return X11DRV_DIB_GenColorMap( physDev, colorMapping, coloruse, depth,
240 isInfo, colorPtr, 0, colors);
244 /***********************************************************************
245 * X11DRV_DIB_MapColor
247 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
251 if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
254 for (color = 0; color < nPhysMap; color++)
255 if (physMap[color] == phys)
258 WARN("Strange color %08x\n", phys);
263 /*********************************************************************
264 * X11DRV_DIB_GetNearestIndex
266 * Helper for X11DRV_DIB_GetDIBits.
267 * Returns the nearest colour table index for a given RGB.
268 * Nearest is defined by minimizing the sum of the squares.
270 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
272 INT i, best = -1, diff, bestdiff = -1;
275 for(color = colormap, i = 0; i < numColors; color++, i++) {
276 diff = (r - color->rgbRed) * (r - color->rgbRed) +
277 (g - color->rgbGreen) * (g - color->rgbGreen) +
278 (b - color->rgbBlue) * (b - color->rgbBlue);
281 if(best == -1 || diff < bestdiff) {
288 /*********************************************************************
289 * X11DRV_DIB_MaskToShift
291 * Helper for X11DRV_DIB_GetDIBits.
292 * Returns the by how many bits to shift a given color so that it is
293 * in the proper position.
295 static INT X11DRV_DIB_MaskToShift(DWORD mask)
303 while ((mask&1)==0) {
310 /***********************************************************************
311 * X11DRV_DIB_Convert_any_asis
313 * All X11DRV_DIB_Convert_Xxx functions take at least the following
316 * This is the width in pixel of the surface to copy. This may be less
317 * than the full width of the image.
319 * The number of lines to copy. This may be less than the full height
320 * of the image. This is always >0.
322 * Points to the first byte containing data to be copied. If the source
323 * surface starts are coordinates (x,y) then this is:
324 * image_ptr+x*bytes_pre_pixel+y*bytes_per_line
325 * (with further adjustments for top-down/bottom-up images)
327 * This is the number of bytes per line. It may be >0 or <0 depending on
328 * whether this is a top-down or bottom-up image.
330 * Same as srcbits but for the destination
332 * Same as srclinebytes but for the destination.
335 * - The supported Dib formats are: pal1, pal4, pal8, rgb555, bgr555,
336 * rgb565, bgr565, rgb888 and any 32bit (0888) format.
337 * The supported XImage (Bmp) formats are: pal1, pal4, pal8,
338 * rgb555, bgr555, rgb565, bgr565, rgb888, bgr888, rgb0888, bgr0888.
339 * - Rgb formats are those for which the masks are such that:
340 * red_mask > green_mask > blue_mask
341 * - Bgr formats are those for which the masks sort in the other direction.
342 * - Many conversion functions handle both rgb->bgr and bgr->rgb conversions
343 * so the comments use h, g, l to mean respectively the source color in the
344 * high bits, the green, and the source color in the low bits.
346 static void X11DRV_DIB_Convert_any_asis(int width, int height,
348 const void* srcbits, int srclinebytes,
349 void* dstbits, int dstlinebytes)
353 width*=bytes_per_pixel;
354 for (y=0; y<height; y++) {
355 memcpy(dstbits, srcbits, width);
356 srcbits += srclinebytes;
357 dstbits += dstlinebytes;
365 static void X11DRV_DIB_Convert_555_reverse(int width, int height,
366 const void* srcbits, int srclinebytes,
367 void* dstbits, int dstlinebytes)
369 const DWORD* srcpixel;
373 for (y=0; y<height; y++) {
376 for (x=0; x<width/2; x++) {
377 /* Do 2 pixels at a time */
380 *dstpixel++=((srcval << 10) & 0x7c007c00) | /* h */
381 ( srcval & 0x03e003e0) | /* g */
382 ((srcval >> 10) & 0x001f001f); /* l */
385 /* And the the odd pixel */
387 srcval=*((WORD*)srcpixel);
388 *((WORD*)dstpixel)=((srcval << 10) & 0x7c00) | /* h */
389 ( srcval & 0x03e0) | /* g */
390 ((srcval >> 10) & 0x001f); /* l */
392 srcbits += srclinebytes;
393 dstbits += dstlinebytes;
397 static void X11DRV_DIB_Convert_555_to_565_asis(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 << 1) & 0xffc0ffc0) | /* h, g */
413 ((srcval >> 4) & 0x00200020) | /* g - 1 bit */
414 ( srcval & 0x001f001f); /* l */
417 /* And the the odd pixel */
419 srcval=*((WORD*)srcpixel);
420 *((WORD*)dstpixel)=((srcval << 1) & 0xffc0) | /* h, g */
421 ((srcval >> 4) & 0x0020) | /* g - 1 bit */
422 (srcval & 0x001f); /* l */
424 srcbits += srclinebytes;
425 dstbits += dstlinebytes;
429 static void X11DRV_DIB_Convert_555_to_565_reverse(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 >> 10) & 0x001f001f) | /* h */
445 ((srcval << 1) & 0x07c007c0) | /* g */
446 ((srcval >> 4) & 0x00200020) | /* g - 1 bit */
447 ((srcval << 11) & 0xf800f800); /* l */
450 /* And the the odd pixel */
452 srcval=*((WORD*)srcpixel);
453 *((WORD*)dstpixel)=((srcval >> 10) & 0x001f) | /* h */
454 ((srcval << 1) & 0x07c0) | /* g */
455 ((srcval >> 4) & 0x0020) | /* g - 1 bit */
456 ((srcval << 11) & 0xf800); /* l */
458 srcbits += srclinebytes;
459 dstbits += dstlinebytes;
463 static void X11DRV_DIB_Convert_555_to_888_asis(int width, int height,
464 const void* srcbits, int srclinebytes,
465 void* dstbits, int dstlinebytes)
467 const WORD* srcpixel;
471 for (y=0; y<height; y++) {
474 for (x=0; x<width; x++) {
477 dstpixel[0]=((srcval << 3) & 0xf8) | /* l */
478 ((srcval >> 2) & 0x07); /* l - 3 bits */
479 dstpixel[1]=((srcval >> 2) & 0xf8) | /* g */
480 ((srcval >> 7) & 0x07); /* g - 3 bits */
481 dstpixel[2]=((srcval >> 7) & 0xf8) | /* h */
482 ((srcval >> 12) & 0x07); /* h - 3 bits */
485 srcbits += srclinebytes;
486 dstbits += dstlinebytes;
490 static void X11DRV_DIB_Convert_555_to_888_reverse(int width, int height,
491 const void* srcbits, int srclinebytes,
492 void* dstbits, int dstlinebytes)
494 const WORD* srcpixel;
498 for (y=0; y<height; y++) {
501 for (x=0; x<width; x++) {
504 dstpixel[0]=((srcval >> 7) & 0xf8) | /* h */
505 ((srcval >> 12) & 0x07); /* h - 3 bits */
506 dstpixel[1]=((srcval >> 2) & 0xf8) | /* g */
507 ((srcval >> 7) & 0x07); /* g - 3 bits */
508 dstpixel[2]=((srcval << 3) & 0xf8) | /* l */
509 ((srcval >> 2) & 0x07); /* l - 3 bits */
512 srcbits += srclinebytes;
513 dstbits += dstlinebytes;
517 static void X11DRV_DIB_Convert_555_to_0888_asis(int width, int height,
518 const void* srcbits, int srclinebytes,
519 void* dstbits, int dstlinebytes)
521 const WORD* srcpixel;
525 for (y=0; y<height; y++) {
528 for (x=0; x<width; x++) {
531 *dstpixel++=((srcval << 9) & 0xf80000) | /* h */
532 ((srcval << 4) & 0x070000) | /* h - 3 bits */
533 ((srcval << 6) & 0x00f800) | /* g */
534 ((srcval << 1) & 0x000700) | /* g - 3 bits */
535 ((srcval << 3) & 0x0000f8) | /* l */
536 ((srcval >> 2) & 0x000007); /* l - 3 bits */
538 srcbits += srclinebytes;
539 dstbits += dstlinebytes;
543 static void X11DRV_DIB_Convert_555_to_0888_reverse(int width, int height,
544 const void* srcbits, int srclinebytes,
545 void* dstbits, int dstlinebytes)
547 const WORD* srcpixel;
551 for (y=0; y<height; y++) {
554 for (x=0; x<width; x++) {
557 *dstpixel++=((srcval >> 7) & 0x0000f8) | /* h */
558 ((srcval >> 12) & 0x000007) | /* h - 3 bits */
559 ((srcval << 6) & 0x00f800) | /* g */
560 ((srcval << 1) & 0x000700) | /* g - 3 bits */
561 ((srcval << 19) & 0xf80000) | /* l */
562 ((srcval << 14) & 0x070000); /* l - 3 bits */
564 srcbits += srclinebytes;
565 dstbits += dstlinebytes;
569 static void X11DRV_DIB_Convert_5x5_to_any0888(int width, int height,
570 const void* srcbits, int srclinebytes,
571 WORD rsrc, WORD gsrc, WORD bsrc,
572 void* dstbits, int dstlinebytes,
573 DWORD rdst, DWORD gdst, DWORD bdst)
575 int rRightShift1,gRightShift1,bRightShift1;
576 int rRightShift2,gRightShift2,bRightShift2;
578 int rLeftShift,gLeftShift,bLeftShift;
579 const WORD* srcpixel;
583 /* Note, the source pixel value is shifted left by 16 bits so that
584 * we know we will always have to shift right to extract the components.
586 rRightShift1=16+X11DRV_DIB_MaskToShift(rsrc)-3;
587 gRightShift1=16+X11DRV_DIB_MaskToShift(gsrc)-3;
588 bRightShift1=16+X11DRV_DIB_MaskToShift(bsrc)-3;
589 rRightShift2=rRightShift1+5;
590 gRightShift2=gRightShift1+5;
591 bRightShift2=bRightShift1+5;
593 /* Green has 5 bits, like the others */
597 /* Green has 6 bits, not 5. Compensate. */
604 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
605 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
606 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
608 for (y=0; y<height; y++) {
611 for (x=0; x<width; x++) {
614 srcval=*srcpixel++ << 16;
615 red= ((srcval >> rRightShift1) & 0xf8) |
616 ((srcval >> rRightShift2) & 0x07);
617 green=((srcval >> gRightShift1) & gMask1) |
618 ((srcval >> gRightShift2) & gMask2);
619 blue= ((srcval >> bRightShift1) & 0xf8) |
620 ((srcval >> bRightShift2) & 0x07);
621 *dstpixel++=(red << rLeftShift) |
622 (green << gLeftShift) |
623 (blue << bLeftShift);
625 srcbits += srclinebytes;
626 dstbits += dstlinebytes;
631 * 16 bits conversions
634 static void X11DRV_DIB_Convert_565_reverse(int width, int height,
635 const void* srcbits, int srclinebytes,
636 void* dstbits, int dstlinebytes)
638 const DWORD* srcpixel;
642 for (y=0; y<height; y++) {
645 for (x=0; x<width/2; x++) {
646 /* Do 2 pixels at a time */
649 *dstpixel++=((srcval << 11) & 0xf800f800) | /* h */
650 ( srcval & 0x07e007e0) | /* g */
651 ((srcval >> 11) & 0x001f001f); /* l */
654 /* And the the odd pixel */
656 srcval=*((WORD*)srcpixel);
657 *((WORD*)dstpixel)=((srcval << 11) & 0xf800) | /* h */
658 ( srcval & 0x07e0) | /* g */
659 ((srcval >> 11) & 0x001f); /* l */
661 srcbits += srclinebytes;
662 dstbits += dstlinebytes;
666 static void X11DRV_DIB_Convert_565_to_555_asis(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 >> 1) & 0x7fe07fe0) | /* h, g */
682 ( srcval & 0x001f001f); /* l */
685 /* And the the odd pixel */
687 srcval=*((WORD*)srcpixel);
688 *((WORD*)dstpixel)=((srcval >> 1) & 0x7fe0) | /* h, g */
689 ( srcval & 0x001f); /* l */
691 srcbits += srclinebytes;
692 dstbits += dstlinebytes;
696 static void X11DRV_DIB_Convert_565_to_555_reverse(int width, int height,
697 const void* srcbits, int srclinebytes,
698 void* dstbits, int dstlinebytes)
700 const DWORD* srcpixel;
704 for (y=0; y<height; y++) {
707 for (x=0; x<width/2; x++) {
708 /* Do 2 pixels at a time */
711 *dstpixel++=((srcval >> 11) & 0x001f001f) | /* h */
712 ((srcval >> 1) & 0x03e003e0) | /* g */
713 ((srcval << 10) & 0x7c007c00); /* l */
716 /* And the the odd pixel */
718 srcval=*((WORD*)srcpixel);
719 *((WORD*)dstpixel)=((srcval >> 11) & 0x001f) | /* h */
720 ((srcval >> 1) & 0x03e0) | /* g */
721 ((srcval << 10) & 0x7c00); /* l */
723 srcbits += srclinebytes;
724 dstbits += dstlinebytes;
728 static void X11DRV_DIB_Convert_565_to_888_asis(int width, int height,
729 const void* srcbits, int srclinebytes,
730 void* dstbits, int dstlinebytes)
732 const WORD* srcpixel;
736 for (y=0; y<height; y++) {
739 for (x=0; x<width; x++) {
742 dstpixel[0]=((srcval << 3) & 0xf8) | /* l */
743 ((srcval >> 2) & 0x07); /* l - 3 bits */
744 dstpixel[1]=((srcval >> 3) & 0xfc) | /* g */
745 ((srcval >> 9) & 0x03); /* g - 2 bits */
746 dstpixel[2]=((srcval >> 8) & 0xf8) | /* h */
747 ((srcval >> 13) & 0x07); /* h - 3 bits */
750 srcbits += srclinebytes;
751 dstbits += dstlinebytes;
755 static void X11DRV_DIB_Convert_565_to_888_reverse(int width, int height,
756 const void* srcbits, int srclinebytes,
757 void* dstbits, int dstlinebytes)
759 const WORD* srcpixel;
763 for (y=0; y<height; y++) {
766 for (x=0; x<width; x++) {
769 dstpixel[0]=((srcval >> 8) & 0xf8) | /* h */
770 ((srcval >> 13) & 0x07); /* h - 3 bits */
771 dstpixel[1]=((srcval >> 3) & 0xfc) | /* g */
772 ((srcval >> 9) & 0x03); /* g - 2 bits */
773 dstpixel[2]=((srcval << 3) & 0xf8) | /* l */
774 ((srcval >> 2) & 0x07); /* l - 3 bits */
777 srcbits += srclinebytes;
778 dstbits += dstlinebytes;
782 static void X11DRV_DIB_Convert_565_to_0888_asis(int width, int height,
783 const void* srcbits, int srclinebytes,
784 void* dstbits, int dstlinebytes)
786 const WORD* srcpixel;
790 for (y=0; y<height; y++) {
793 for (x=0; x<width; x++) {
796 *dstpixel++=((srcval << 8) & 0xf80000) | /* h */
797 ((srcval << 3) & 0x070000) | /* h - 3 bits */
798 ((srcval << 5) & 0x00fc00) | /* g */
799 ((srcval >> 1) & 0x000300) | /* g - 2 bits */
800 ((srcval << 3) & 0x0000f8) | /* l */
801 ((srcval >> 2) & 0x000007); /* l - 3 bits */
803 srcbits += srclinebytes;
804 dstbits += dstlinebytes;
808 static void X11DRV_DIB_Convert_565_to_0888_reverse(int width, int height,
809 const void* srcbits, int srclinebytes,
810 void* dstbits, int dstlinebytes)
812 const WORD* srcpixel;
816 for (y=0; y<height; y++) {
819 for (x=0; x<width; x++) {
822 *dstpixel++=((srcval >> 8) & 0x0000f8) | /* h */
823 ((srcval >> 13) & 0x000007) | /* h - 3 bits */
824 ((srcval << 5) & 0x00fc00) | /* g */
825 ((srcval >> 1) & 0x000300) | /* g - 2 bits */
826 ((srcval << 19) & 0xf80000) | /* l */
827 ((srcval << 14) & 0x070000); /* l - 3 bits */
829 srcbits += srclinebytes;
830 dstbits += dstlinebytes;
838 static void X11DRV_DIB_Convert_888_reverse(int width, int height,
839 const void* srcbits, int srclinebytes,
840 void* dstbits, int dstlinebytes)
842 const BYTE* srcpixel;
846 for (y=0; y<height; y++) {
849 for (x=0; x<width; x++) {
850 dstpixel[0]=srcpixel[2];
851 dstpixel[1]=srcpixel[1];
852 dstpixel[2]=srcpixel[0];
856 srcbits += srclinebytes;
857 dstbits += dstlinebytes;
861 static void X11DRV_DIB_Convert_888_to_555_asis(int width, int height,
862 const void* srcbits, int srclinebytes,
863 void* dstbits, int dstlinebytes)
865 const DWORD* srcpixel;
873 for (y=0; y<height; y++) {
876 for (x=0; x<width; x++) {
877 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
878 DWORD srcval1,srcval2;
880 dstpixel[0]=((srcval1 >> 3) & 0x001f) | /* l1 */
881 ((srcval1 >> 6) & 0x03e0) | /* g1 */
882 ((srcval1 >> 9) & 0x7c00); /* h1 */
884 dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */
885 ((srcval2 << 2) & 0x03e0) | /* g2 */
886 ((srcval2 >> 1) & 0x7c00); /* h2 */
888 dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */
889 ((srcval2 >> 22) & 0x03e0) | /* g3 */
890 ((srcval1 << 7) & 0x7c00); /* h3 */
891 dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */
892 ((srcval1 >> 14) & 0x03e0) | /* g4 */
893 ((srcval1 >> 17) & 0x7c00); /* h4 */
897 /* And now up to 3 odd pixels */
898 srcbyte=(LPBYTE)srcpixel;
899 for (x=0; x<oddwidth; x++) {
901 dstval =((srcbyte[0] >> 3) & 0x001f); /* l */
902 dstval|=((srcbyte[1] << 2) & 0x03e0); /* g */
903 dstval|=((srcbyte[2] << 7) & 0x7c00); /* h */
907 srcbits += srclinebytes;
908 dstbits += dstlinebytes;
912 static void X11DRV_DIB_Convert_888_to_555_reverse(int width, int height,
913 const void* srcbits, int srclinebytes,
914 void* dstbits, int dstlinebytes)
916 const DWORD* srcpixel;
924 for (y=0; y<height; y++) {
927 for (x=0; x<width; x++) {
928 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
929 DWORD srcval1,srcval2;
931 dstpixel[0]=((srcval1 << 7) & 0x7c00) | /* l1 */
932 ((srcval1 >> 6) & 0x03e0) | /* g1 */
933 ((srcval1 >> 19) & 0x001f); /* h1 */
935 dstpixel[1]=((srcval1 >> 17) & 0x7c00) | /* l2 */
936 ((srcval2 << 2) & 0x03e0) | /* g2 */
937 ((srcval2 >> 11) & 0x001f); /* h2 */
939 dstpixel[2]=((srcval2 >> 9) & 0x7c00) | /* l3 */
940 ((srcval2 >> 22) & 0x03e0) | /* g3 */
941 ((srcval1 >> 3) & 0x001f); /* h3 */
942 dstpixel[3]=((srcval1 >> 1) & 0x7c00) | /* l4 */
943 ((srcval1 >> 14) & 0x03e0) | /* g4 */
944 ((srcval1 >> 27) & 0x001f); /* h4 */
948 /* And now up to 3 odd pixels */
949 srcbyte=(LPBYTE)srcpixel;
950 for (x=0; x<oddwidth; x++) {
952 dstval =((srcbyte[0] << 7) & 0x7c00); /* l */
953 dstval|=((srcbyte[1] << 2) & 0x03e0); /* g */
954 dstval|=((srcbyte[2] >> 3) & 0x001f); /* h */
958 srcbits += srclinebytes;
959 dstbits += dstlinebytes;
963 static void X11DRV_DIB_Convert_888_to_565_asis(int width, int height,
964 const void* srcbits, int srclinebytes,
965 void* dstbits, int dstlinebytes)
967 const DWORD* srcpixel;
975 for (y=0; y<height; y++) {
978 for (x=0; x<width; x++) {
979 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
980 DWORD srcval1,srcval2;
982 dstpixel[0]=((srcval1 >> 3) & 0x001f) | /* l1 */
983 ((srcval1 >> 5) & 0x07e0) | /* g1 */
984 ((srcval1 >> 8) & 0xf800); /* h1 */
986 dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */
987 ((srcval2 << 3) & 0x07e0) | /* g2 */
988 ( srcval2 & 0xf800); /* h2 */
990 dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */
991 ((srcval2 >> 21) & 0x07e0) | /* g3 */
992 ((srcval1 << 8) & 0xf800); /* h3 */
993 dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */
994 ((srcval1 >> 13) & 0x07e0) | /* g4 */
995 ((srcval1 >> 16) & 0xf800); /* h4 */
999 /* And now up to 3 odd pixels */
1000 srcbyte=(LPBYTE)srcpixel;
1001 for (x=0; x<oddwidth; x++) {
1003 dstval =((srcbyte[0] >> 3) & 0x001f); /* l */
1004 dstval|=((srcbyte[1] << 3) & 0x07e0); /* g */
1005 dstval|=((srcbyte[2] << 8) & 0xf800); /* h */
1009 srcbits += srclinebytes;
1010 dstbits += dstlinebytes;
1014 static void X11DRV_DIB_Convert_888_to_565_reverse(int width, int height,
1015 const void* srcbits, int srclinebytes,
1016 void* dstbits, int dstlinebytes)
1018 const DWORD* srcpixel;
1019 const BYTE* srcbyte;
1026 for (y=0; y<height; y++) {
1029 for (x=0; x<width; x++) {
1030 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
1031 DWORD srcval1,srcval2;
1032 srcval1=srcpixel[0];
1033 dstpixel[0]=((srcval1 << 8) & 0xf800) | /* l1 */
1034 ((srcval1 >> 5) & 0x07e0) | /* g1 */
1035 ((srcval1 >> 19) & 0x001f); /* h1 */
1036 srcval2=srcpixel[1];
1037 dstpixel[1]=((srcval1 >> 16) & 0xf800) | /* l2 */
1038 ((srcval2 << 3) & 0x07e0) | /* g2 */
1039 ((srcval2 >> 11) & 0x001f); /* h2 */
1040 srcval1=srcpixel[2];
1041 dstpixel[2]=((srcval2 >> 8) & 0xf800) | /* l3 */
1042 ((srcval2 >> 21) & 0x07e0) | /* g3 */
1043 ((srcval1 >> 3) & 0x001f); /* h3 */
1044 dstpixel[3]=(srcval1 & 0xf800) | /* l4 */
1045 ((srcval1 >> 13) & 0x07e0) | /* g4 */
1046 ((srcval1 >> 27) & 0x001f); /* h4 */
1050 /* And now up to 3 odd pixels */
1051 srcbyte=(LPBYTE)srcpixel;
1052 for (x=0; x<oddwidth; x++) {
1054 dstval =((srcbyte[0] << 8) & 0xf800); /* l */
1055 dstval|=((srcbyte[1] << 3) & 0x07e0); /* g */
1056 dstval|=((srcbyte[2] >> 3) & 0x001f); /* h */
1060 srcbits += srclinebytes;
1061 dstbits += dstlinebytes;
1065 static void X11DRV_DIB_Convert_888_to_0888_asis(int width, int height,
1066 const void* srcbits, int srclinebytes,
1067 void* dstbits, int dstlinebytes)
1069 const DWORD* srcpixel;
1076 for (y=0; y<height; y++) {
1079 for (x=0; x<width; x++) {
1080 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1081 DWORD srcval1,srcval2;
1082 srcval1=srcpixel[0];
1083 dstpixel[0]=( srcval1 & 0x00ffffff); /* h1, g1, l1 */
1084 srcval2=srcpixel[1];
1085 dstpixel[1]=( srcval1 >> 24) | /* l2 */
1086 ((srcval2 << 8) & 0x00ffff00); /* h2, g2 */
1087 srcval1=srcpixel[2];
1088 dstpixel[2]=( srcval2 >> 16) | /* g3, l3 */
1089 ((srcval1 << 16) & 0x00ff0000); /* h3 */
1090 dstpixel[3]=( srcval1 >> 8); /* h4, g4, l4 */
1094 /* And now up to 3 odd pixels */
1095 for (x=0; x<oddwidth; x++) {
1098 srcpixel=(LPDWORD)(((char*)srcpixel)+3);
1099 *dstpixel++=( srcval & 0x00ffffff); /* h, g, l */
1101 srcbits += srclinebytes;
1102 dstbits += dstlinebytes;
1106 static void X11DRV_DIB_Convert_888_to_0888_reverse(int width, int height,
1107 const void* srcbits, int srclinebytes,
1108 void* dstbits, int dstlinebytes)
1110 const DWORD* srcpixel;
1117 for (y=0; y<height; y++) {
1120 for (x=0; x<width; x++) {
1121 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1122 DWORD srcval1,srcval2;
1124 srcval1=srcpixel[0];
1125 dstpixel[0]=((srcval1 >> 16) & 0x0000ff) | /* h1 */
1126 ( srcval1 & 0x00ff00) | /* g1 */
1127 ((srcval1 << 16) & 0xff0000); /* l1 */
1128 srcval2=srcpixel[1];
1129 dstpixel[1]=((srcval1 >> 8) & 0xff0000) | /* l2 */
1130 ((srcval2 << 8) & 0x00ff00) | /* g2 */
1131 ((srcval2 >> 8) & 0x0000ff); /* h2 */
1132 srcval1=srcpixel[2];
1133 dstpixel[2]=( srcval2 & 0xff0000) | /* l3 */
1134 ((srcval2 >> 16) & 0x00ff00) | /* g3 */
1135 ( srcval1 & 0x0000ff); /* h3 */
1136 dstpixel[3]=((srcval1 >> 24) & 0x0000ff) | /* h4 */
1137 ((srcval1 >> 8) & 0x00ff00) | /* g4 */
1138 ((srcval1 << 8) & 0xff0000); /* l4 */
1142 /* And now up to 3 odd pixels */
1143 for (x=0; x<oddwidth; x++) {
1146 srcpixel=(LPDWORD)(((char*)srcpixel)+3);
1147 *dstpixel++=((srcval >> 16) & 0x0000ff) | /* h */
1148 ( srcval & 0x00ff00) | /* g */
1149 ((srcval << 16) & 0xff0000); /* l */
1151 srcbits += srclinebytes;
1152 dstbits += dstlinebytes;
1156 static void X11DRV_DIB_Convert_rgb888_to_any0888(int width, int height,
1157 const void* srcbits, int srclinebytes,
1158 void* dstbits, int dstlinebytes,
1159 DWORD rdst, DWORD gdst, DWORD bdst)
1161 int rLeftShift,gLeftShift,bLeftShift;
1162 const BYTE* srcpixel;
1166 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1167 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1168 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1169 for (y=0; y<height; y++) {
1172 for (x=0; x<width; x++) {
1173 *dstpixel++=(srcpixel[0] << bLeftShift) | /* b */
1174 (srcpixel[1] << gLeftShift) | /* g */
1175 (srcpixel[2] << rLeftShift); /* r */
1178 srcbits += srclinebytes;
1179 dstbits += dstlinebytes;
1183 static void X11DRV_DIB_Convert_bgr888_to_any0888(int width, int height,
1184 const void* srcbits, int srclinebytes,
1185 void* dstbits, int dstlinebytes,
1186 DWORD rdst, DWORD gdst, DWORD bdst)
1188 int rLeftShift,gLeftShift,bLeftShift;
1189 const BYTE* srcpixel;
1193 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1194 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1195 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1196 for (y=0; y<height; y++) {
1199 for (x=0; x<width; x++) {
1200 *dstpixel++=(srcpixel[0] << rLeftShift) | /* r */
1201 (srcpixel[1] << gLeftShift) | /* g */
1202 (srcpixel[2] << bLeftShift); /* b */
1205 srcbits += srclinebytes;
1206 dstbits += dstlinebytes;
1211 * 32 bit conversions
1214 static void X11DRV_DIB_Convert_0888_reverse(int width, int height,
1215 const void* srcbits, int srclinebytes,
1216 void* dstbits, int dstlinebytes)
1218 const DWORD* srcpixel;
1222 for (y=0; y<height; y++) {
1225 for (x=0; x<width; x++) {
1228 *dstpixel++=((srcval << 16) & 0x00ff0000) | /* h */
1229 ( srcval & 0x0000ff00) | /* g */
1230 ((srcval >> 16) & 0x000000ff); /* l */
1232 srcbits += srclinebytes;
1233 dstbits += dstlinebytes;
1237 static void X11DRV_DIB_Convert_0888_any(int width, int height,
1238 const void* srcbits, int srclinebytes,
1239 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1240 void* dstbits, int dstlinebytes,
1241 DWORD rdst, DWORD gdst, DWORD bdst)
1243 int rRightShift,gRightShift,bRightShift;
1244 int rLeftShift,gLeftShift,bLeftShift;
1245 const DWORD* srcpixel;
1249 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1250 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1251 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1252 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1253 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1254 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1255 for (y=0; y<height; y++) {
1258 for (x=0; x<width; x++) {
1261 *dstpixel++=(((srcval >> rRightShift) & 0xff) << rLeftShift) |
1262 (((srcval >> gRightShift) & 0xff) << gLeftShift) |
1263 (((srcval >> bRightShift) & 0xff) << bLeftShift);
1265 srcbits += srclinebytes;
1266 dstbits += dstlinebytes;
1270 static void X11DRV_DIB_Convert_0888_to_555_asis(int width, int height,
1271 const void* srcbits, int srclinebytes,
1272 void* dstbits, int dstlinebytes)
1274 const DWORD* srcpixel;
1278 for (y=0; y<height; y++) {
1281 for (x=0; x<width; x++) {
1284 *dstpixel++=((srcval >> 9) & 0x7c00) | /* h */
1285 ((srcval >> 6) & 0x03e0) | /* g */
1286 ((srcval >> 3) & 0x001f); /* l */
1288 srcbits += srclinebytes;
1289 dstbits += dstlinebytes;
1293 static void X11DRV_DIB_Convert_0888_to_555_reverse(int width, int height,
1294 const void* srcbits, int srclinebytes,
1295 void* dstbits, int dstlinebytes)
1297 const DWORD* srcpixel;
1301 for (y=0; y<height; y++) {
1304 for (x=0; x<width; x++) {
1307 *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1308 ((srcval >> 6) & 0x03e0) | /* g */
1309 ((srcval << 7) & 0x7c00); /* l */
1311 srcbits += srclinebytes;
1312 dstbits += dstlinebytes;
1316 static void X11DRV_DIB_Convert_0888_to_565_asis(int width, int height,
1317 const void* srcbits, int srclinebytes,
1318 void* dstbits, int dstlinebytes)
1320 const DWORD* srcpixel;
1324 for (y=0; y<height; y++) {
1327 for (x=0; x<width; x++) {
1330 *dstpixel++=((srcval >> 8) & 0xf800) | /* h */
1331 ((srcval >> 5) & 0x07e0) | /* g */
1332 ((srcval >> 3) & 0x001f); /* l */
1334 srcbits += srclinebytes;
1335 dstbits += dstlinebytes;
1339 static void X11DRV_DIB_Convert_0888_to_565_reverse(int width, int height,
1340 const void* srcbits, int srclinebytes,
1341 void* dstbits, int dstlinebytes)
1343 const DWORD* srcpixel;
1347 for (y=0; y<height; y++) {
1350 for (x=0; x<width; x++) {
1353 *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1354 ((srcval >> 5) & 0x07e0) | /* g */
1355 ((srcval << 8) & 0xf800); /* l */
1357 srcbits += srclinebytes;
1358 dstbits += dstlinebytes;
1362 static void X11DRV_DIB_Convert_any0888_to_5x5(int width, int height,
1363 const void* srcbits, int srclinebytes,
1364 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1365 void* dstbits, int dstlinebytes,
1366 WORD rdst, WORD gdst, WORD bdst)
1368 int rRightShift,gRightShift,bRightShift;
1369 int rLeftShift,gLeftShift,bLeftShift;
1370 const DWORD* srcpixel;
1374 /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel
1375 * contains 0x11223344.
1376 * - first we shift 0x11223344 right by rRightShift to bring the most
1377 * significant bits of the red components in the bottom 5 (or 6) bits
1379 * - then we remove non red bits by anding with the modified rdst (0x1f)
1381 * - finally shift these bits left by rLeftShift so that they end up in
1385 rRightShift=X11DRV_DIB_MaskToShift(rsrc)+3;
1386 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1387 gRightShift+=(gdst==0x07e0?2:3);
1388 bRightShift=X11DRV_DIB_MaskToShift(bsrc)+3;
1390 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1391 rdst=rdst >> rLeftShift;
1392 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1393 gdst=gdst >> gLeftShift;
1394 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1395 bdst=bdst >> bLeftShift;
1397 for (y=0; y<height; y++) {
1400 for (x=0; x<width; x++) {
1403 *dstpixel++=(((srcval >> rRightShift) & rdst) << rLeftShift) |
1404 (((srcval >> gRightShift) & gdst) << gLeftShift) |
1405 (((srcval >> bRightShift) & bdst) << bLeftShift);
1407 srcbits += srclinebytes;
1408 dstbits += dstlinebytes;
1412 static void X11DRV_DIB_Convert_0888_to_888_asis(int width, int height,
1413 const void* srcbits, int srclinebytes,
1414 void* dstbits, int dstlinebytes)
1416 const DWORD* srcpixel;
1424 for (y=0; y<height; y++) {
1427 for (x=0; x<width; x++) {
1428 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1430 srcval=((*srcpixel++) & 0x00ffffff); /* h1, g1, l1*/
1431 *dstpixel++=srcval | ((*srcpixel) << 24); /* h2 */
1432 srcval=((*srcpixel++ >> 8 ) & 0x0000ffff); /* g2, l2 */
1433 *dstpixel++=srcval | ((*srcpixel) << 16); /* h3, g3 */
1434 srcval=((*srcpixel++ >> 16) & 0x000000ff); /* l3 */
1435 *dstpixel++=srcval | ((*srcpixel++) << 8); /* h4, g4, l4 */
1437 /* And now up to 3 odd pixels */
1438 dstbyte=(BYTE*)dstpixel;
1439 for (x=0; x<oddwidth; x++) {
1442 *((WORD*)dstbyte)++=srcval; /* h, g */
1443 *dstbyte++=srcval >> 16; /* l */
1445 srcbits += srclinebytes;
1446 dstbits += dstlinebytes;
1450 static void X11DRV_DIB_Convert_0888_to_888_reverse(int width, int height,
1451 const void* srcbits, int srclinebytes,
1452 void* dstbits, int dstlinebytes)
1454 const DWORD* srcpixel;
1462 for (y=0; y<height; y++) {
1465 for (x=0; x<width; x++) {
1466 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1467 DWORD srcval1,srcval2;
1468 srcval1=*srcpixel++;
1469 srcval2= ((srcval1 >> 16) & 0x000000ff) | /* h1 */
1470 ( srcval1 & 0x0000ff00) | /* g1 */
1471 ((srcval1 << 16) & 0x00ff0000); /* l1 */
1472 srcval1=*srcpixel++;
1473 *dstpixel++=srcval2 |
1474 ((srcval1 << 8) & 0xff000000); /* h2 */
1475 srcval2= ((srcval1 >> 8) & 0x000000ff) | /* g2 */
1476 ((srcval1 << 8) & 0x0000ff00); /* l2 */
1477 srcval1=*srcpixel++;
1478 *dstpixel++=srcval2 |
1479 ( srcval1 & 0x00ff0000) | /* h3 */
1480 ((srcval1 << 16) & 0xff000000); /* g3 */
1481 srcval2= ( srcval1 & 0x000000ff); /* l3 */
1482 srcval1=*srcpixel++;
1483 *dstpixel++=srcval2 |
1484 ((srcval1 >> 8) & 0x0000ff00) | /* h4 */
1485 ((srcval1 << 8) & 0x00ff0000) | /* g4 */
1486 ( srcval1 << 24); /* l4 */
1488 /* And now up to 3 odd pixels */
1489 dstbyte=(BYTE*)dstpixel;
1490 for (x=0; x<oddwidth; x++) {
1493 *((WORD*)dstbyte)++=((srcval >> 16) & 0x00ff) | /* h */
1494 (srcval & 0xff00); /* g */
1495 *dstbyte++=srcval; /* l */
1497 srcbits += srclinebytes;
1498 dstbits += dstlinebytes;
1502 static void X11DRV_DIB_Convert_any0888_to_rgb888(int width, int height,
1503 const void* srcbits, int srclinebytes,
1504 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1505 void* dstbits, int dstlinebytes)
1507 int rRightShift,gRightShift,bRightShift;
1508 const DWORD* srcpixel;
1512 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1513 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1514 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1515 for (y=0; y<height; y++) {
1518 for (x=0; x<width; x++) {
1521 dstpixel[0]=(srcval >> bRightShift); /* b */
1522 dstpixel[1]=(srcval >> gRightShift); /* g */
1523 dstpixel[2]=(srcval >> rRightShift); /* r */
1526 srcbits += srclinebytes;
1527 dstbits += dstlinebytes;
1531 static void X11DRV_DIB_Convert_any0888_to_bgr888(int width, int height,
1532 const void* srcbits, int srclinebytes,
1533 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1534 void* dstbits, int dstlinebytes)
1536 int rRightShift,gRightShift,bRightShift;
1537 const DWORD* srcpixel;
1541 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1542 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1543 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1544 for (y=0; y<height; y++) {
1547 for (x=0; x<width; x++) {
1550 dstpixel[0]=(srcval >> rRightShift); /* r */
1551 dstpixel[1]=(srcval >> gRightShift); /* g */
1552 dstpixel[2]=(srcval >> bRightShift); /* b */
1555 srcbits += srclinebytes;
1556 dstbits += dstlinebytes;
1560 /***********************************************************************
1561 * X11DRV_DIB_SetImageBits_1
1563 * SetDIBits for a 1-bit deep DIB.
1565 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
1566 DWORD srcwidth, DWORD dstwidth, int left,
1567 int *colors, XImage *bmpImage, DWORD linebytes)
1570 const BYTE* srcbyte;
1576 srcbits = srcbits + linebytes * (lines - 1);
1577 linebytes = -linebytes;
1580 if ((extra = (left & 7)) != 0) {
1584 srcbits += left >> 3;
1586 /* ==== pal 1 dib -> any bmp format ==== */
1587 for (h = lines-1; h >=0; h--) {
1589 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
1590 for (i = dstwidth/8, x = left; i > 0; i--) {
1592 XPutPixel( bmpImage, x++, h, colors[ srcval >> 7] );
1593 XPutPixel( bmpImage, x++, h, colors[(srcval >> 6) & 1] );
1594 XPutPixel( bmpImage, x++, h, colors[(srcval >> 5) & 1] );
1595 XPutPixel( bmpImage, x++, h, colors[(srcval >> 4) & 1] );
1596 XPutPixel( bmpImage, x++, h, colors[(srcval >> 3) & 1] );
1597 XPutPixel( bmpImage, x++, h, colors[(srcval >> 2) & 1] );
1598 XPutPixel( bmpImage, x++, h, colors[(srcval >> 1) & 1] );
1599 XPutPixel( bmpImage, x++, h, colors[ srcval & 1] );
1602 switch (dstwidth & 7)
1604 case 7: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1605 case 6: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1606 case 5: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1607 case 4: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1608 case 3: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1609 case 2: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1610 case 1: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]);
1612 srcbits += linebytes;
1616 /***********************************************************************
1617 * X11DRV_DIB_GetImageBits_1
1619 * GetDIBits for a 1-bit deep DIB.
1621 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
1622 DWORD dstwidth, DWORD srcwidth,
1623 RGBQUAD *colors, PALETTEENTRY *srccolors,
1624 XImage *bmpImage, DWORD linebytes )
1631 dstbits = dstbits + linebytes * (lines - 1);
1632 linebytes = -linebytes;
1635 switch (bmpImage->depth)
1639 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1640 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
1643 for (h=lines-1; h>=0; h--) {
1647 for (x=0; x<dstwidth; x++) {
1648 PALETTEENTRY srcval;
1649 srcval=srccolors[XGetPixel(bmpImage, x, h)];
1650 dstval|=(X11DRV_DIB_GetNearestIndex
1654 srcval.peBlue) << (7 - (x & 7)));
1660 if ((dstwidth&7)!=0) {
1663 dstbits += linebytes;
1671 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1672 /* ==== pal 8 bmp -> pal 1 dib ==== */
1673 const void* srcbits;
1674 const BYTE* srcpixel;
1677 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1679 for (h=0; h<lines; h++) {
1684 for (x=0; x<dstwidth; x++) {
1685 PALETTEENTRY srcval;
1686 srcval=srccolors[(int)*srcpixel++];
1687 dstval|=(X11DRV_DIB_GetNearestIndex
1691 srcval.peBlue) << (7-(x&7)) );
1697 if ((dstwidth&7)!=0) {
1700 srcbits -= bmpImage->bytes_per_line;
1701 dstbits += linebytes;
1711 const void* srcbits;
1712 const WORD* srcpixel;
1715 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1717 if (bmpImage->green_mask==0x03e0) {
1718 if (bmpImage->red_mask==0x7c00) {
1719 /* ==== rgb 555 bmp -> pal 1 dib ==== */
1720 for (h=0; h<lines; h++) {
1725 for (x=0; x<dstwidth; x++) {
1728 dstval|=(X11DRV_DIB_GetNearestIndex
1730 ((srcval >> 7) & 0xf8) | /* r */
1731 ((srcval >> 12) & 0x07),
1732 ((srcval >> 2) & 0xf8) | /* g */
1733 ((srcval >> 7) & 0x07),
1734 ((srcval << 3) & 0xf8) | /* b */
1735 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
1741 if ((dstwidth&7)!=0) {
1744 srcbits -= bmpImage->bytes_per_line;
1745 dstbits += linebytes;
1747 } else if (bmpImage->blue_mask==0x7c00) {
1748 /* ==== bgr 555 bmp -> pal 1 dib ==== */
1749 for (h=0; h<lines; h++) {
1754 for (x=0; x<dstwidth; x++) {
1757 dstval|=(X11DRV_DIB_GetNearestIndex
1759 ((srcval << 3) & 0xf8) | /* r */
1760 ((srcval >> 2) & 0x07),
1761 ((srcval >> 2) & 0xf8) | /* g */
1762 ((srcval >> 7) & 0x07),
1763 ((srcval >> 7) & 0xf8) | /* b */
1764 ((srcval >> 12) & 0x07) ) << (7-(x&7)) );
1770 if ((dstwidth&7)!=0) {
1773 srcbits -= bmpImage->bytes_per_line;
1774 dstbits += linebytes;
1779 } else if (bmpImage->green_mask==0x07e0) {
1780 if (bmpImage->red_mask==0xf800) {
1781 /* ==== rgb 565 bmp -> pal 1 dib ==== */
1782 for (h=0; h<lines; h++) {
1787 for (x=0; x<dstwidth; x++) {
1790 dstval|=(X11DRV_DIB_GetNearestIndex
1792 ((srcval >> 8) & 0xf8) | /* r */
1793 ((srcval >> 13) & 0x07),
1794 ((srcval >> 3) & 0xfc) | /* g */
1795 ((srcval >> 9) & 0x03),
1796 ((srcval << 3) & 0xf8) | /* b */
1797 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
1803 if ((dstwidth&7)!=0) {
1806 srcbits -= bmpImage->bytes_per_line;
1807 dstbits += linebytes;
1809 } else if (bmpImage->blue_mask==0xf800) {
1810 /* ==== bgr 565 bmp -> pal 1 dib ==== */
1811 for (h=0; h<lines; h++) {
1816 for (x=0; x<dstwidth; x++) {
1819 dstval|=(X11DRV_DIB_GetNearestIndex
1821 ((srcval << 3) & 0xf8) | /* r */
1822 ((srcval >> 2) & 0x07),
1823 ((srcval >> 3) & 0xfc) | /* g */
1824 ((srcval >> 9) & 0x03),
1825 ((srcval >> 8) & 0xf8) | /* b */
1826 ((srcval >> 13) & 0x07) ) << (7-(x&7)) );
1832 if ((dstwidth&7)!=0) {
1835 srcbits -= bmpImage->bytes_per_line;
1836 dstbits += linebytes;
1850 const void* srcbits;
1851 const BYTE *srcbyte;
1853 int bytes_per_pixel;
1855 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1856 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
1858 if (bmpImage->green_mask!=0x00ff00 ||
1859 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1861 } else if (bmpImage->blue_mask==0xff) {
1862 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
1863 for (h=0; h<lines; h++) {
1868 for (x=0; x<dstwidth; x++) {
1869 dstval|=(X11DRV_DIB_GetNearestIndex
1873 srcbyte[0]) << (7-(x&7)) );
1874 srcbyte+=bytes_per_pixel;
1880 if ((dstwidth&7)!=0) {
1883 srcbits -= bmpImage->bytes_per_line;
1884 dstbits += linebytes;
1887 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
1888 for (h=0; h<lines; h++) {
1893 for (x=0; x<dstwidth; x++) {
1894 dstval|=(X11DRV_DIB_GetNearestIndex
1898 srcbyte[2]) << (7-(x&7)) );
1899 srcbyte+=bytes_per_pixel;
1905 if ((dstwidth&7)!=0) {
1908 srcbits -= bmpImage->bytes_per_line;
1909 dstbits += linebytes;
1919 unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
1921 /* ==== any bmp format -> pal 1 dib ==== */
1922 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
1923 bmpImage->bits_per_pixel, bmpImage->red_mask,
1924 bmpImage->green_mask, bmpImage->blue_mask );
1926 for (h=lines-1; h>=0; h--) {
1930 for (x=0; x<dstwidth; x++) {
1931 dstval|=(XGetPixel( bmpImage, x, h) >= white) << (7 - (x&7));
1937 if ((dstwidth&7)!=0) {
1940 dstbits += linebytes;
1947 /***********************************************************************
1948 * X11DRV_DIB_SetImageBits_4
1950 * SetDIBits for a 4-bit deep DIB.
1952 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
1953 DWORD srcwidth, DWORD dstwidth, int left,
1954 int *colors, XImage *bmpImage, DWORD linebytes)
1957 const BYTE* srcbyte;
1962 srcbits = srcbits + linebytes * (lines - 1);
1963 linebytes = -linebytes;
1970 srcbits += left >> 1;
1972 /* ==== pal 4 dib -> any bmp format ==== */
1973 for (h = lines-1; h >= 0; h--) {
1975 for (i = dstwidth/2, x = left; i > 0; i--) {
1976 BYTE srcval=*srcbyte++;
1977 XPutPixel( bmpImage, x++, h, colors[srcval >> 4] );
1978 XPutPixel( bmpImage, x++, h, colors[srcval & 0x0f] );
1981 XPutPixel( bmpImage, x, h, colors[*srcbyte >> 4] );
1982 srcbits += linebytes;
1988 /***********************************************************************
1989 * X11DRV_DIB_GetImageBits_4
1991 * GetDIBits for a 4-bit deep DIB.
1993 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
1994 DWORD srcwidth, DWORD dstwidth,
1995 RGBQUAD *colors, PALETTEENTRY *srccolors,
1996 XImage *bmpImage, DWORD linebytes )
2005 dstbits = dstbits + ( linebytes * (lines-1) );
2006 linebytes = -linebytes;
2011 switch (bmpImage->depth) {
2014 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2015 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
2018 for (h = lines-1; h >= 0; h--) {
2022 for (x = 0; x < dstwidth; x++) {
2023 PALETTEENTRY srcval;
2024 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2025 dstval|=(X11DRV_DIB_GetNearestIndex
2029 srcval.peBlue) << (4-((x&1)<<2)));
2035 if ((dstwidth&1)!=0) {
2038 dstbits += linebytes;
2046 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2047 /* ==== pal 8 bmp -> pal 4 dib ==== */
2048 const void* srcbits;
2049 const BYTE *srcpixel;
2052 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2053 for (h=0; h<lines; h++) {
2058 for (x=0; x<dstwidth; x++) {
2059 PALETTEENTRY srcval;
2060 srcval = srccolors[(int)*srcpixel++];
2061 dstval|=(X11DRV_DIB_GetNearestIndex
2065 srcval.peBlue) << (4*(1-(x&1))) );
2071 if ((dstwidth&1)!=0) {
2074 srcbits -= bmpImage->bytes_per_line;
2075 dstbits += linebytes;
2085 const void* srcbits;
2086 const WORD* srcpixel;
2089 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2091 if (bmpImage->green_mask==0x03e0) {
2092 if (bmpImage->red_mask==0x7c00) {
2093 /* ==== rgb 555 bmp -> pal 4 dib ==== */
2094 for (h=0; h<lines; h++) {
2099 for (x=0; x<dstwidth; x++) {
2102 dstval|=(X11DRV_DIB_GetNearestIndex
2104 ((srcval >> 7) & 0xf8) | /* r */
2105 ((srcval >> 12) & 0x07),
2106 ((srcval >> 2) & 0xf8) | /* g */
2107 ((srcval >> 7) & 0x07),
2108 ((srcval << 3) & 0xf8) | /* b */
2109 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
2115 if ((dstwidth&1)!=0) {
2118 srcbits -= bmpImage->bytes_per_line;
2119 dstbits += linebytes;
2121 } else if (bmpImage->blue_mask==0x7c00) {
2122 /* ==== bgr 555 bmp -> pal 4 dib ==== */
2123 for (h=0; h<lines; h++) {
2128 for (x=0; x<dstwidth; x++) {
2131 dstval|=(X11DRV_DIB_GetNearestIndex
2133 ((srcval << 3) & 0xf8) | /* r */
2134 ((srcval >> 2) & 0x07),
2135 ((srcval >> 2) & 0xf8) | /* g */
2136 ((srcval >> 7) & 0x07),
2137 ((srcval >> 7) & 0xf8) | /* b */
2138 ((srcval >> 12) & 0x07) ) << ((1-(x&1))<<2) );
2144 if ((dstwidth&1)!=0) {
2147 srcbits -= bmpImage->bytes_per_line;
2148 dstbits += linebytes;
2153 } else if (bmpImage->green_mask==0x07e0) {
2154 if (bmpImage->red_mask==0xf800) {
2155 /* ==== rgb 565 bmp -> pal 4 dib ==== */
2156 for (h=0; h<lines; h++) {
2161 for (x=0; x<dstwidth; x++) {
2164 dstval|=(X11DRV_DIB_GetNearestIndex
2166 ((srcval >> 8) & 0xf8) | /* r */
2167 ((srcval >> 13) & 0x07),
2168 ((srcval >> 3) & 0xfc) | /* g */
2169 ((srcval >> 9) & 0x03),
2170 ((srcval << 3) & 0xf8) | /* b */
2171 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
2177 if ((dstwidth&1)!=0) {
2180 srcbits -= bmpImage->bytes_per_line;
2181 dstbits += linebytes;
2183 } else if (bmpImage->blue_mask==0xf800) {
2184 /* ==== bgr 565 bmp -> pal 4 dib ==== */
2185 for (h=0; h<lines; h++) {
2190 for (x=0; x<dstwidth; x++) {
2193 dstval|=(X11DRV_DIB_GetNearestIndex
2195 ((srcval << 3) & 0xf8) | /* r */
2196 ((srcval >> 2) & 0x07),
2197 ((srcval >> 3) & 0xfc) | /* g */
2198 ((srcval >> 9) & 0x03),
2199 ((srcval >> 8) & 0xf8) | /* b */
2200 ((srcval >> 13) & 0x07) ) << ((1-(x&1))<<2) );
2206 if ((dstwidth&1)!=0) {
2209 srcbits -= bmpImage->bytes_per_line;
2210 dstbits += linebytes;
2222 if (bmpImage->bits_per_pixel==24) {
2223 const void* srcbits;
2224 const BYTE *srcbyte;
2227 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2229 if (bmpImage->green_mask!=0x00ff00 ||
2230 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2232 } else if (bmpImage->blue_mask==0xff) {
2233 /* ==== rgb 888 bmp -> pal 4 dib ==== */
2234 for (h=0; h<lines; h++) {
2237 for (x=0; x<dstwidth/2; x++) {
2238 /* Do 2 pixels at a time */
2239 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2244 X11DRV_DIB_GetNearestIndex
2252 /* And the the odd pixel */
2253 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2259 srcbits -= bmpImage->bytes_per_line;
2260 dstbits += linebytes;
2263 /* ==== bgr 888 bmp -> pal 4 dib ==== */
2264 for (h=0; h<lines; h++) {
2267 for (x=0; x<dstwidth/2; x++) {
2268 /* Do 2 pixels at a time */
2269 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2274 X11DRV_DIB_GetNearestIndex
2282 /* And the the odd pixel */
2283 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2289 srcbits -= bmpImage->bytes_per_line;
2290 dstbits += linebytes;
2299 const void* srcbits;
2300 const BYTE *srcbyte;
2303 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2305 if (bmpImage->green_mask!=0x00ff00 ||
2306 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2308 } else if (bmpImage->blue_mask==0xff) {
2309 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
2310 for (h=0; h<lines; h++) {
2313 for (x=0; x<dstwidth/2; x++) {
2314 /* Do 2 pixels at a time */
2315 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2320 X11DRV_DIB_GetNearestIndex
2328 /* And the the odd pixel */
2329 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2335 srcbits -= bmpImage->bytes_per_line;
2336 dstbits += linebytes;
2339 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
2340 for (h=0; h<lines; h++) {
2343 for (x=0; x<dstwidth/2; x++) {
2344 /* Do 2 pixels at a time */
2345 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2350 X11DRV_DIB_GetNearestIndex
2358 /* And the the odd pixel */
2359 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2365 srcbits -= bmpImage->bytes_per_line;
2366 dstbits += linebytes;
2377 /* ==== any bmp format -> pal 4 dib ==== */
2378 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
2379 bmpImage->bits_per_pixel, bmpImage->red_mask,
2380 bmpImage->green_mask, bmpImage->blue_mask );
2381 for (h=lines-1; h>=0; h--) {
2383 for (x=0; x<(dstwidth & ~1); x+=2) {
2384 *dstbyte++=(X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4) |
2385 X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x+1, h), 0);
2388 *dstbyte=(X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4);
2390 dstbits += linebytes;
2397 /***********************************************************************
2398 * X11DRV_DIB_SetImageBits_RLE4
2400 * SetDIBits for a 4-bit deep compressed DIB.
2402 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
2403 DWORD width, DWORD dstwidth,
2404 int left, int *colors,
2407 int x = 0, y = lines - 1, c, length;
2408 const BYTE *begin = bits;
2413 if (length) { /* encoded */
2416 if (x >= width) break;
2417 XPutPixel(bmpImage, x++, y, colors[c >> 4]);
2418 if (!length--) break;
2419 if (x >= width) break;
2420 XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
2439 default: /* absolute */
2442 if (x < width) XPutPixel(bmpImage, x++, y, colors[c >> 4]);
2443 if (!length--) break;
2444 if (x < width) XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
2446 if ((bits - begin) & 1)
2455 /***********************************************************************
2456 * X11DRV_DIB_SetImageBits_8
2458 * SetDIBits for an 8-bit deep DIB.
2460 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
2461 DWORD srcwidth, DWORD dstwidth, int left,
2462 const int *colors, XImage *bmpImage,
2467 const BYTE* srcbyte;
2473 srcbits = srcbits + linebytes * (lines-1);
2474 linebytes = -linebytes;
2479 switch (bmpImage->depth) {
2482 #if defined(__i386__) && defined(__GNUC__)
2483 /* Some X servers might have 32 bit/ 16bit deep pixel */
2484 if (lines && dstwidth && (bmpImage->bits_per_pixel == 16))
2486 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2487 /* FIXME: Does this really handle all these cases correctly? */
2488 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
2489 for (h = lines ; h--; ) {
2490 int _cl1,_cl2; /* temp outputs for asm below */
2491 /* Borrowed from DirectDraw */
2492 __asm__ __volatile__(
2497 " movw (%%edx,%%eax,4),%%ax\n"
2499 " xor %%eax,%%eax\n"
2501 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
2506 :"eax", "cc", "memory"
2508 srcbyte = (srcbits += linebytes);
2509 dstbits -= bmpImage->bytes_per_line;
2517 #if defined(__i386__) && defined(__GNUC__)
2518 if (lines && dstwidth && (bmpImage->bits_per_pixel == 32))
2520 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2521 /* FIXME: Does this really handle both cases correctly? */
2522 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
2523 for (h = lines ; h--; ) {
2524 int _cl1,_cl2; /* temp outputs for asm below */
2525 /* Borrowed from DirectDraw */
2526 __asm__ __volatile__(
2531 " movl (%%edx,%%eax,4),%%eax\n"
2533 " xor %%eax,%%eax\n"
2535 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
2540 :"eax", "cc", "memory"
2542 srcbyte = (srcbits += linebytes);
2543 dstbits -= bmpImage->bytes_per_line;
2550 break; /* use slow generic case below */
2553 /* ==== pal 8 dib -> any bmp format ==== */
2554 for (h=lines-1; h>=0; h--) {
2555 for (x=left; x<dstwidth+left; x++) {
2556 XPutPixel(bmpImage, x, h, colors[*srcbyte++]);
2558 srcbyte = (srcbits += linebytes);
2562 /***********************************************************************
2563 * X11DRV_DIB_GetImageBits_8
2565 * GetDIBits for an 8-bit deep DIB.
2567 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
2568 DWORD srcwidth, DWORD dstwidth,
2569 RGBQUAD *colors, PALETTEENTRY *srccolors,
2570 XImage *bmpImage, DWORD linebytes )
2579 dstbits = dstbits + ( linebytes * (lines-1) );
2580 linebytes = -linebytes;
2585 * This condition is true when GetImageBits has been called by
2586 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
2587 * 256 colormaps, so we'll just use for for GetDIBits calls.
2588 * (In somes cases, in a updateDIBSection, the returned colors are bad too)
2590 if (!srccolors) goto updatesection;
2592 switch (bmpImage->depth) {
2595 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2597 /* ==== pal 1 bmp -> pal 8 dib ==== */
2598 /* ==== pal 4 bmp -> pal 8 dib ==== */
2599 for (h=lines-1; h>=0; h--) {
2601 for (x=0; x<dstwidth; x++) {
2602 PALETTEENTRY srcval;
2603 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2604 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
2609 dstbits += linebytes;
2617 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2618 /* ==== pal 8 bmp -> pal 8 dib ==== */
2619 const void* srcbits;
2620 const BYTE* srcpixel;
2622 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2623 for (h=0; h<lines; h++) {
2626 for (x = 0; x < dstwidth; x++) {
2627 PALETTEENTRY srcval;
2628 srcval=srccolors[(int)*srcpixel++];
2629 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
2634 srcbits -= bmpImage->bytes_per_line;
2635 dstbits += linebytes;
2645 const void* srcbits;
2646 const WORD* srcpixel;
2649 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2651 if (bmpImage->green_mask==0x03e0) {
2652 if (bmpImage->red_mask==0x7c00) {
2653 /* ==== rgb 555 bmp -> pal 8 dib ==== */
2654 for (h=0; h<lines; h++) {
2657 for (x=0; x<dstwidth; x++) {
2660 *dstbyte++=X11DRV_DIB_GetNearestIndex
2662 ((srcval >> 7) & 0xf8) | /* r */
2663 ((srcval >> 12) & 0x07),
2664 ((srcval >> 2) & 0xf8) | /* g */
2665 ((srcval >> 7) & 0x07),
2666 ((srcval << 3) & 0xf8) | /* b */
2667 ((srcval >> 2) & 0x07) );
2669 srcbits -= bmpImage->bytes_per_line;
2670 dstbits += linebytes;
2672 } else if (bmpImage->blue_mask==0x7c00) {
2673 /* ==== bgr 555 bmp -> pal 8 dib ==== */
2674 for (h=0; h<lines; h++) {
2677 for (x=0; x<dstwidth; x++) {
2680 *dstbyte++=X11DRV_DIB_GetNearestIndex
2682 ((srcval << 3) & 0xf8) | /* r */
2683 ((srcval >> 2) & 0x07),
2684 ((srcval >> 2) & 0xf8) | /* g */
2685 ((srcval >> 7) & 0x07),
2686 ((srcval >> 7) & 0xf8) | /* b */
2687 ((srcval >> 12) & 0x07) );
2689 srcbits -= bmpImage->bytes_per_line;
2690 dstbits += linebytes;
2695 } else if (bmpImage->green_mask==0x07e0) {
2696 if (bmpImage->red_mask==0xf800) {
2697 /* ==== rgb 565 bmp -> pal 8 dib ==== */
2698 for (h=0; h<lines; h++) {
2701 for (x=0; x<dstwidth; x++) {
2704 *dstbyte++=X11DRV_DIB_GetNearestIndex
2706 ((srcval >> 8) & 0xf8) | /* r */
2707 ((srcval >> 13) & 0x07),
2708 ((srcval >> 3) & 0xfc) | /* g */
2709 ((srcval >> 9) & 0x03),
2710 ((srcval << 3) & 0xf8) | /* b */
2711 ((srcval >> 2) & 0x07) );
2713 srcbits -= bmpImage->bytes_per_line;
2714 dstbits += linebytes;
2716 } else if (bmpImage->blue_mask==0xf800) {
2717 /* ==== bgr 565 bmp -> pal 8 dib ==== */
2718 for (h=0; h<lines; h++) {
2721 for (x=0; x<dstwidth; x++) {
2724 *dstbyte++=X11DRV_DIB_GetNearestIndex
2726 ((srcval << 3) & 0xf8) | /* r */
2727 ((srcval >> 2) & 0x07),
2728 ((srcval >> 3) & 0xfc) | /* g */
2729 ((srcval >> 9) & 0x03),
2730 ((srcval >> 8) & 0xf8) | /* b */
2731 ((srcval >> 13) & 0x07) );
2733 srcbits -= bmpImage->bytes_per_line;
2734 dstbits += linebytes;
2748 const void* srcbits;
2749 const BYTE *srcbyte;
2751 int bytes_per_pixel;
2753 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2754 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
2756 if (bmpImage->green_mask!=0x00ff00 ||
2757 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2759 } else if (bmpImage->blue_mask==0xff) {
2760 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
2761 for (h=0; h<lines; h++) {
2764 for (x=0; x<dstwidth; x++) {
2765 *dstbyte++=X11DRV_DIB_GetNearestIndex
2770 srcbyte+=bytes_per_pixel;
2772 srcbits -= bmpImage->bytes_per_line;
2773 dstbits += linebytes;
2776 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
2777 for (h=0; h<lines; h++) {
2780 for (x=0; x<dstwidth; x++) {
2781 *dstbyte++=X11DRV_DIB_GetNearestIndex
2786 srcbyte+=bytes_per_pixel;
2788 srcbits -= bmpImage->bytes_per_line;
2789 dstbits += linebytes;
2797 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
2798 bmpImage->depth, bmpImage->red_mask,
2799 bmpImage->green_mask, bmpImage->blue_mask );
2801 /* ==== any bmp format -> pal 8 dib ==== */
2802 for (h=lines-1; h>=0; h--) {
2804 for (x=0; x<dstwidth; x++) {
2805 *dstbyte=X11DRV_DIB_MapColor
2807 XGetPixel(bmpImage, x, h), *dstbyte);
2810 dstbits += linebytes;
2816 /***********************************************************************
2817 * X11DRV_DIB_SetImageBits_RLE8
2819 * SetDIBits for an 8-bit deep compressed DIB.
2821 * This function rewritten 941113 by James Youngman. WINE blew out when I
2822 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
2824 * This was because the algorithm assumed that all RLE8 bitmaps end with the
2825 * 'End of bitmap' escape code. This code is very much laxer in what it
2826 * allows to end the expansion. Possibly too lax. See the note by
2827 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
2828 * bitmap should end with RleEnd, but on the other hand, software exists
2829 * that produces ones that don't and Windows 3.1 doesn't complain a bit
2832 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
2833 * James A. Youngman <mbcstjy@afs.man.ac.uk>
2836 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
2837 DWORD width, DWORD dstwidth,
2838 int left, int *colors,
2841 int x; /* X-positon on each line. Increases. */
2842 int y; /* Line #. Starts at lines-1, decreases */
2843 const BYTE *pIn = bits; /* Pointer to current position in bits */
2844 BYTE length; /* The length pf a run */
2845 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
2848 * Note that the bitmap data is stored by Windows starting at the
2849 * bottom line of the bitmap and going upwards. Within each line,
2850 * the data is stored left-to-right. That's the reason why line
2851 * goes from lines-1 to 0. [JAY]
2861 * If the length byte is not zero (which is the escape value),
2862 * We have a run of length pixels all the same colour. The colour
2863 * index is stored next.
2865 * If the length byte is zero, we need to read the next byte to
2866 * know what to do. [JAY]
2871 * [Run-Length] Encoded mode
2873 int color = colors[*pIn++];
2874 while (length-- && x < dstwidth) XPutPixel(bmpImage, x++, y, color);
2879 * Escape codes (may be an absolute sequence though)
2881 escape_code = (*pIn++);
2890 /* Not all RLE8 bitmaps end with this code. For
2891 * example, Paint Shop Pro produces some that don't.
2892 * That's (I think) what caused the previous
2893 * implementation to fail. [JAY]
2902 default: /* switch to absolute mode */
2903 length = escape_code;
2906 int color = colors[*pIn++];
2912 XPutPixel(bmpImage, x++, y, color);
2915 * If you think for a moment you'll realise that the
2916 * only time we could ever possibly read an odd
2917 * number of bytes is when there is a 0x00 (escape),
2918 * a value >0x02 (absolute mode) and then an odd-
2919 * length run. Therefore this is the only place we
2920 * need to worry about it. Everywhere else the
2921 * bytes are always read in pairs. [JAY]
2923 if (escape_code & 1) pIn++; /* Throw away the pad byte. */
2925 } /* switch (escape_code) : Escape sequence */
2931 /***********************************************************************
2932 * X11DRV_DIB_SetImageBits_16
2934 * SetDIBits for a 16-bit deep DIB.
2936 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
2937 DWORD srcwidth, DWORD dstwidth, int left,
2938 X11DRV_PDEVICE *physDev, DWORD rSrc, DWORD gSrc, DWORD bSrc,
2939 XImage *bmpImage, DWORD linebytes )
2947 srcbits = srcbits + ( linebytes * (lines-1));
2948 linebytes = -linebytes;
2951 switch (bmpImage->depth)
2958 srcbits=srcbits+left*2;
2959 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2961 if (bmpImage->green_mask==0x03e0) {
2962 if (gSrc==bmpImage->green_mask) {
2963 if (rSrc==bmpImage->red_mask) {
2964 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
2965 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
2966 X11DRV_DIB_Convert_any_asis
2969 dstbits,-bmpImage->bytes_per_line);
2970 } else if (rSrc==bmpImage->blue_mask) {
2971 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
2972 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
2973 X11DRV_DIB_Convert_555_reverse
2976 dstbits,-bmpImage->bytes_per_line);
2979 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
2980 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
2981 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
2982 X11DRV_DIB_Convert_565_to_555_asis
2985 dstbits,-bmpImage->bytes_per_line);
2987 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
2988 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
2989 X11DRV_DIB_Convert_565_to_555_reverse
2992 dstbits,-bmpImage->bytes_per_line);
2995 } else if (bmpImage->green_mask==0x07e0) {
2996 if (gSrc==bmpImage->green_mask) {
2997 if (rSrc==bmpImage->red_mask) {
2998 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
2999 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
3000 X11DRV_DIB_Convert_any_asis
3003 dstbits,-bmpImage->bytes_per_line);
3005 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
3006 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
3007 X11DRV_DIB_Convert_565_reverse
3010 dstbits,-bmpImage->bytes_per_line);
3013 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
3014 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
3015 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
3016 X11DRV_DIB_Convert_555_to_565_asis
3019 dstbits,-bmpImage->bytes_per_line);
3021 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
3022 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
3023 X11DRV_DIB_Convert_555_to_565_reverse
3026 dstbits,-bmpImage->bytes_per_line);
3036 if (bmpImage->bits_per_pixel==24) {
3039 srcbits=srcbits+left*2;
3040 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
3042 if (bmpImage->green_mask!=0x00ff00 ||
3043 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3045 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
3046 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
3048 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
3049 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
3050 X11DRV_DIB_Convert_555_to_888_asis
3053 dstbits,-bmpImage->bytes_per_line);
3055 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
3056 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
3057 X11DRV_DIB_Convert_565_to_888_asis
3060 dstbits,-bmpImage->bytes_per_line);
3064 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
3065 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
3066 X11DRV_DIB_Convert_555_to_888_reverse
3069 dstbits,-bmpImage->bytes_per_line);
3071 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
3072 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
3073 X11DRV_DIB_Convert_565_to_888_reverse
3076 dstbits,-bmpImage->bytes_per_line);
3087 srcbits=srcbits+left*2;
3088 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
3090 if (bmpImage->green_mask!=0x00ff00 ||
3091 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3093 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
3094 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
3096 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
3097 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
3098 X11DRV_DIB_Convert_555_to_0888_asis
3101 dstbits,-bmpImage->bytes_per_line);
3103 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
3104 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
3105 X11DRV_DIB_Convert_565_to_0888_asis
3108 dstbits,-bmpImage->bytes_per_line);
3112 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
3113 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
3114 X11DRV_DIB_Convert_555_to_0888_reverse
3117 dstbits,-bmpImage->bytes_per_line);
3119 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
3120 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
3121 X11DRV_DIB_Convert_565_to_0888_reverse
3124 dstbits,-bmpImage->bytes_per_line);
3132 WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3133 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
3134 bmpImage->green_mask, bmpImage->blue_mask );
3140 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
3141 const WORD* srcpixel;
3142 int rShift1,gShift1,bShift1;
3143 int rShift2,gShift2,bShift2;
3146 /* Set color scaling values */
3147 rShift1=16+X11DRV_DIB_MaskToShift(rSrc)-3;
3148 gShift1=16+X11DRV_DIB_MaskToShift(gSrc)-3;
3149 bShift1=16+X11DRV_DIB_MaskToShift(bSrc)-3;
3154 /* Green has 5 bits, like the others */
3158 /* Green has 6 bits, not 5. Compensate. */
3167 /* We could split it into four separate cases to optimize
3168 * but it is probably not worth it.
3170 for (h=lines-1; h>=0; h--) {
3171 srcpixel=(const WORD*)srcbits;
3172 for (x=left; x<dstwidth+left; x++) {
3174 BYTE red,green,blue;
3175 srcval=*srcpixel++ << 16;
3176 red= ((srcval >> rShift1) & 0xf8) |
3177 ((srcval >> rShift2) & 0x07);
3178 green=((srcval >> gShift1) & gMask1) |
3179 ((srcval >> gShift2) & gMask2);
3180 blue= ((srcval >> bShift1) & 0xf8) |
3181 ((srcval >> bShift2) & 0x07);
3182 XPutPixel(bmpImage, x, h,
3183 X11DRV_PALETTE_ToPhysical
3184 (physDev, RGB(red,green,blue)));
3186 srcbits += linebytes;
3194 /***********************************************************************
3195 * X11DRV_DIB_GetImageBits_16
3197 * GetDIBits for an 16-bit deep DIB.
3199 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
3200 DWORD dstwidth, DWORD srcwidth,
3201 PALETTEENTRY *srccolors,
3202 DWORD rDst, DWORD gDst, DWORD bDst,
3203 XImage *bmpImage, DWORD dibpitch )
3208 DWORD linebytes = dibpitch;
3213 dstbits = dstbits + ( linebytes * (lines-1));
3214 linebytes = -linebytes;
3217 switch (bmpImage->depth)
3222 const char* srcbits;
3224 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3226 if (bmpImage->green_mask==0x03e0) {
3227 if (gDst==bmpImage->green_mask) {
3228 if (rDst==bmpImage->red_mask) {
3229 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
3230 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
3231 X11DRV_DIB_Convert_any_asis
3233 srcbits,-bmpImage->bytes_per_line,
3236 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
3237 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
3238 X11DRV_DIB_Convert_555_reverse
3240 srcbits,-bmpImage->bytes_per_line,
3244 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
3245 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
3246 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
3247 X11DRV_DIB_Convert_555_to_565_asis
3249 srcbits,-bmpImage->bytes_per_line,
3252 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
3253 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
3254 X11DRV_DIB_Convert_555_to_565_reverse
3256 srcbits,-bmpImage->bytes_per_line,
3260 } else if (bmpImage->green_mask==0x07e0) {
3261 if (gDst==bmpImage->green_mask) {
3262 if (rDst == bmpImage->red_mask) {
3263 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
3264 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
3265 X11DRV_DIB_Convert_any_asis
3267 srcbits,-bmpImage->bytes_per_line,
3270 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
3271 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
3272 X11DRV_DIB_Convert_565_reverse
3274 srcbits,-bmpImage->bytes_per_line,
3278 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
3279 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
3280 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
3281 X11DRV_DIB_Convert_565_to_555_asis
3283 srcbits,-bmpImage->bytes_per_line,
3286 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
3287 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
3288 X11DRV_DIB_Convert_565_to_555_reverse
3290 srcbits,-bmpImage->bytes_per_line,
3301 if (bmpImage->bits_per_pixel == 24) {
3302 const char* srcbits;
3304 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3306 if (bmpImage->green_mask!=0x00ff00 ||
3307 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3309 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
3310 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
3312 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
3313 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
3314 X11DRV_DIB_Convert_888_to_555_asis
3316 srcbits,-bmpImage->bytes_per_line,
3319 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
3320 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
3321 X11DRV_DIB_Convert_888_to_565_asis
3323 srcbits,-bmpImage->bytes_per_line,
3328 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
3329 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
3330 X11DRV_DIB_Convert_888_to_555_reverse
3332 srcbits,-bmpImage->bytes_per_line,
3335 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
3336 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
3337 X11DRV_DIB_Convert_888_to_565_reverse
3339 srcbits,-bmpImage->bytes_per_line,
3349 const char* srcbits;
3351 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3353 if (bmpImage->green_mask!=0x00ff00 ||
3354 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3356 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
3357 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
3359 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
3360 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
3361 X11DRV_DIB_Convert_0888_to_555_asis
3363 srcbits,-bmpImage->bytes_per_line,
3366 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
3367 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
3368 X11DRV_DIB_Convert_0888_to_565_asis
3370 srcbits,-bmpImage->bytes_per_line,
3375 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
3376 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
3377 X11DRV_DIB_Convert_0888_to_555_reverse
3379 srcbits,-bmpImage->bytes_per_line,
3382 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
3383 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
3384 X11DRV_DIB_Convert_0888_to_565_reverse
3386 srcbits,-bmpImage->bytes_per_line,
3395 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3396 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
3397 int rShift,gShift,bShift;
3400 /* Shift everything 16 bits left so that all shifts are >0,
3401 * even for BGR DIBs. Then a single >> 16 will bring everything
3404 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
3405 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
3406 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
3408 /* 6 bits for the green */
3414 for (h = lines - 1; h >= 0; h--) {
3415 dstpixel=(LPWORD)dstbits;
3416 for (x = 0; x < dstwidth; x++) {
3417 PALETTEENTRY srcval;
3419 srcval=srccolors[XGetPixel(bmpImage, x, h)];
3420 dstval=((srcval.peRed << rShift) & rDst) |
3421 ((srcval.peGreen << gShift) & gDst) |
3422 ((srcval.peBlue << bShift) & bDst);
3423 *dstpixel++=dstval >> 16;
3425 dstbits += linebytes;
3433 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3434 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
3435 int rShift,gShift,bShift;
3436 const BYTE* srcbits;
3437 const BYTE* srcpixel;
3440 /* Shift everything 16 bits left so that all shifts are >0,
3441 * even for BGR DIBs. Then a single >> 16 will bring everything
3444 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
3445 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
3446 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
3448 /* 6 bits for the green */
3454 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3455 for (h=0; h<lines; h++) {
3457 dstpixel=(LPWORD)dstbits;
3458 for (x = 0; x < dstwidth; x++) {
3459 PALETTEENTRY srcval;
3461 srcval=srccolors[(int)*srcpixel++];
3462 dstval=((srcval.peRed << rShift) & rDst) |
3463 ((srcval.peGreen << gShift) & gDst) |
3464 ((srcval.peBlue << bShift) & bDst);
3465 *dstpixel++=dstval >> 16;
3467 srcbits -= bmpImage->bytes_per_line;
3468 dstbits += linebytes;
3478 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
3479 int rShift,gShift,bShift;
3482 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
3483 bmpImage->depth, bmpImage->red_mask,
3484 bmpImage->green_mask, bmpImage->blue_mask,
3487 /* Shift everything 16 bits left so that all shifts are >0,
3488 * even for BGR DIBs. Then a single >> 16 will bring everything
3491 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
3492 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
3493 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
3495 /* 6 bits for the green */
3501 for (h = lines - 1; h >= 0; h--) {
3502 dstpixel=(LPWORD)dstbits;
3503 for (x = 0; x < dstwidth; x++) {
3506 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
3507 dstval=((GetRValue(srcval) << rShift) & rDst) |
3508 ((GetGValue(srcval) << gShift) & gDst) |
3509 ((GetBValue(srcval) << bShift) & bDst);
3510 *dstpixel++=dstval >> 16;
3512 dstbits += linebytes;
3520 /***********************************************************************
3521 * X11DRV_DIB_SetImageBits_24
3523 * SetDIBits for a 24-bit deep DIB.
3525 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
3526 DWORD srcwidth, DWORD dstwidth, int left,
3527 X11DRV_PDEVICE *physDev,
3528 DWORD rSrc, DWORD gSrc, DWORD bSrc,
3529 XImage *bmpImage, DWORD linebytes )
3537 srcbits = srcbits + linebytes * (lines - 1);
3538 linebytes = -linebytes;
3541 switch (bmpImage->depth)
3544 if (bmpImage->bits_per_pixel==24) {
3547 srcbits=srcbits+left*3;
3548 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
3550 if (bmpImage->green_mask!=0x00ff00 ||
3551 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3553 } else if (rSrc==bmpImage->red_mask) {
3554 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
3555 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
3556 X11DRV_DIB_Convert_any_asis
3559 dstbits,-bmpImage->bytes_per_line);
3561 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
3562 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
3563 X11DRV_DIB_Convert_888_reverse
3566 dstbits,-bmpImage->bytes_per_line);
3576 srcbits=srcbits+left*3;
3577 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
3579 if (bmpImage->green_mask!=0x00ff00 ||
3580 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3582 } else if (rSrc==bmpImage->red_mask) {
3583 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
3584 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
3585 X11DRV_DIB_Convert_888_to_0888_asis
3588 dstbits,-bmpImage->bytes_per_line);
3590 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
3591 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
3592 X11DRV_DIB_Convert_888_to_0888_reverse
3595 dstbits,-bmpImage->bytes_per_line);
3605 srcbits=srcbits+left*3;
3606 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
3608 if (bmpImage->green_mask==0x03e0) {
3609 if ((rSrc==0xff0000 && bmpImage->red_mask==0x7f00) ||
3610 (bSrc==0xff0000 && bmpImage->blue_mask==0x7f00)) {
3611 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
3612 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
3613 X11DRV_DIB_Convert_888_to_555_asis
3616 dstbits,-bmpImage->bytes_per_line);
3617 } else if ((rSrc==0xff && bmpImage->red_mask==0x7f00) ||
3618 (bSrc==0xff && bmpImage->blue_mask==0x7f00)) {
3619 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
3620 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
3621 X11DRV_DIB_Convert_888_to_555_reverse
3624 dstbits,-bmpImage->bytes_per_line);
3628 } else if (bmpImage->green_mask==0x07e0) {
3629 if ((rSrc==0xff0000 && bmpImage->red_mask==0xf800) ||
3630 (bSrc==0xff0000 && bmpImage->blue_mask==0xf800)) {
3631 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
3632 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
3633 X11DRV_DIB_Convert_888_to_565_asis
3636 dstbits,-bmpImage->bytes_per_line);
3637 } else if ((rSrc==0xff && bmpImage->red_mask==0xf800) ||
3638 (bSrc==0xff && bmpImage->blue_mask==0xf800)) {
3639 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
3640 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
3641 X11DRV_DIB_Convert_888_to_565_reverse
3644 dstbits,-bmpImage->bytes_per_line);
3656 WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3657 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
3658 bmpImage->green_mask, bmpImage->blue_mask );
3664 /* ==== rgb 888 dib -> any bmp bormat ==== */
3665 const BYTE* srcbyte;
3667 /* Windows only supports one 24bpp DIB format: RGB888 */
3669 for (h = lines - 1; h >= 0; h--) {
3670 srcbyte=(const BYTE*)srcbits;
3671 for (x = left; x < dstwidth+left; x++) {
3672 XPutPixel(bmpImage, x, h,
3673 X11DRV_PALETTE_ToPhysical
3674 (physDev, RGB(srcbyte[2], srcbyte[1], srcbyte[0])));
3677 srcbits += linebytes;
3685 /***********************************************************************
3686 * X11DRV_DIB_GetImageBits_24
3688 * GetDIBits for an 24-bit deep DIB.
3690 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
3691 DWORD dstwidth, DWORD srcwidth,
3692 PALETTEENTRY *srccolors,
3693 DWORD rDst, DWORD gDst, DWORD bDst,
3694 XImage *bmpImage, DWORD linebytes )
3702 dstbits = dstbits + ( linebytes * (lines-1) );
3703 linebytes = -linebytes;
3706 switch (bmpImage->depth)
3709 if (bmpImage->bits_per_pixel==24) {
3710 const char* srcbits;
3712 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3714 if (bmpImage->green_mask!=0x00ff00 ||
3715 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3717 } else if (rDst==bmpImage->red_mask) {
3718 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
3719 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
3720 X11DRV_DIB_Convert_any_asis
3722 srcbits,-bmpImage->bytes_per_line,
3725 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
3726 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
3727 X11DRV_DIB_Convert_888_reverse
3729 srcbits,-bmpImage->bytes_per_line,
3738 const char* srcbits;
3740 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3742 if (bmpImage->green_mask!=0x00ff00 ||
3743 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3745 } else if (rDst==bmpImage->red_mask) {
3746 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3747 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3748 X11DRV_DIB_Convert_0888_to_888_asis
3750 srcbits,-bmpImage->bytes_per_line,
3753 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3754 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3755 X11DRV_DIB_Convert_0888_to_888_reverse
3757 srcbits,-bmpImage->bytes_per_line,
3766 const char* srcbits;
3768 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3770 if (bmpImage->green_mask==0x03e0) {
3771 if ((rDst==0xff0000 && bmpImage->red_mask==0x7f00) ||
3772 (bDst==0xff0000 && bmpImage->blue_mask==0x7f00)) {
3773 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
3774 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
3775 X11DRV_DIB_Convert_555_to_888_asis
3777 srcbits,-bmpImage->bytes_per_line,
3779 } else if ((rDst==0xff && bmpImage->red_mask==0x7f00) ||
3780 (bDst==0xff && bmpImage->blue_mask==0x7f00)) {
3781 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
3782 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
3783 X11DRV_DIB_Convert_555_to_888_reverse
3785 srcbits,-bmpImage->bytes_per_line,
3790 } else if (bmpImage->green_mask==0x07e0) {
3791 if ((rDst==0xff0000 && bmpImage->red_mask==0xf800) ||
3792 (bDst==0xff0000 && bmpImage->blue_mask==0xf800)) {
3793 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
3794 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
3795 X11DRV_DIB_Convert_565_to_888_asis
3797 srcbits,-bmpImage->bytes_per_line,
3799 } else if ((rDst==0xff && bmpImage->red_mask==0xf800) ||
3800 (bDst==0xff && bmpImage->blue_mask==0xf800)) {
3801 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
3802 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
3803 X11DRV_DIB_Convert_565_to_888_reverse
3805 srcbits,-bmpImage->bytes_per_line,
3818 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3819 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
3822 /* Windows only supports one 24bpp DIB format: rgb 888 */
3823 for (h = lines - 1; h >= 0; h--) {
3825 for (x = 0; x < dstwidth; x++) {
3826 PALETTEENTRY srcval;
3827 srcval=srccolors[XGetPixel(bmpImage, x, h)];
3828 dstbyte[0]=srcval.peBlue;
3829 dstbyte[1]=srcval.peGreen;
3830 dstbyte[2]=srcval.peRed;
3833 dstbits += linebytes;
3841 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors) {
3842 /* ==== pal 8 bmp -> rgb 888 dib ==== */
3843 const void* srcbits;
3844 const BYTE* srcpixel;
3847 /* Windows only supports one 24bpp DIB format: rgb 888 */
3848 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3849 for (h = lines - 1; h >= 0; h--) {
3852 for (x = 0; x < dstwidth; x++ ) {
3853 PALETTEENTRY srcval;
3854 srcval=srccolors[(int)*srcpixel++];
3855 dstbyte[0]=srcval.peBlue;
3856 dstbyte[1]=srcval.peGreen;
3857 dstbyte[2]=srcval.peRed;
3860 srcbits -= bmpImage->bytes_per_line;
3861 dstbits += linebytes;
3871 /* ==== any bmp format -> 888 dib ==== */
3874 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
3875 bmpImage->depth, bmpImage->red_mask,
3876 bmpImage->green_mask, bmpImage->blue_mask,
3879 /* Windows only supports one 24bpp DIB format: rgb 888 */
3880 for (h = lines - 1; h >= 0; h--) {
3882 for (x = 0; x < dstwidth; x++) {
3883 COLORREF srcval=X11DRV_PALETTE_ToLogical
3884 (XGetPixel( bmpImage, x, h ));
3885 dstbyte[0]=GetBValue(srcval);
3886 dstbyte[1]=GetGValue(srcval);
3887 dstbyte[2]=GetRValue(srcval);
3890 dstbits += linebytes;
3898 /***********************************************************************
3899 * X11DRV_DIB_SetImageBits_32
3901 * SetDIBits for a 32-bit deep DIB.
3903 static void X11DRV_DIB_SetImageBits_32(int lines, const BYTE *srcbits,
3904 DWORD srcwidth, DWORD dstwidth, int left,
3905 X11DRV_PDEVICE *physDev,
3906 DWORD rSrc, DWORD gSrc, DWORD bSrc,
3916 srcbits = srcbits + ( linebytes * (lines-1) );
3917 linebytes = -linebytes;
3920 ptr = (DWORD *) srcbits + left;
3922 switch (bmpImage->depth)
3925 if (bmpImage->bits_per_pixel==24) {
3928 srcbits=srcbits+left*4;
3929 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
3931 if (rSrc==bmpImage->red_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->blue_mask) {
3932 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
3933 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
3934 X11DRV_DIB_Convert_0888_to_888_asis
3937 dstbits,-bmpImage->bytes_per_line);
3938 } else if (bmpImage->green_mask!=0x00ff00 ||
3939 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3941 /* the tests below assume sane bmpImage masks */
3942 } else if (rSrc==bmpImage->blue_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->red_mask) {
3943 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
3944 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
3945 X11DRV_DIB_Convert_0888_to_888_reverse
3948 dstbits,-bmpImage->bytes_per_line);
3949 } else if (bmpImage->blue_mask==0xff) {
3950 /* ==== any 0888 dib -> rgb 888 bmp ==== */
3951 X11DRV_DIB_Convert_any0888_to_rgb888
3955 dstbits,-bmpImage->bytes_per_line);
3957 /* ==== any 0888 dib -> bgr 888 bmp ==== */
3958 X11DRV_DIB_Convert_any0888_to_bgr888
3962 dstbits,-bmpImage->bytes_per_line);
3972 srcbits=srcbits+left*4;
3973 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
3975 if (gSrc==bmpImage->green_mask) {
3976 if (rSrc==bmpImage->red_mask && bSrc==bmpImage->blue_mask) {
3977 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
3978 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
3979 X11DRV_DIB_Convert_any_asis
3982 dstbits,-bmpImage->bytes_per_line);
3983 } else if (bmpImage->green_mask!=0x00ff00 ||
3984 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3986 /* the tests below assume sane bmpImage masks */
3987 } else if (rSrc==bmpImage->blue_mask && bSrc==bmpImage->red_mask) {
3988 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
3989 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
3990 X11DRV_DIB_Convert_0888_reverse
3993 dstbits,-bmpImage->bytes_per_line);
3995 /* ==== any 0888 dib -> any 0888 bmp ==== */
3996 X11DRV_DIB_Convert_0888_any
4000 dstbits,-bmpImage->bytes_per_line,
4001 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4003 } else if (bmpImage->green_mask!=0x00ff00 ||
4004 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4006 /* the tests below assume sane bmpImage masks */
4008 /* ==== any 0888 dib -> any 0888 bmp ==== */
4009 X11DRV_DIB_Convert_0888_any
4013 dstbits,-bmpImage->bytes_per_line,
4014 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4024 srcbits=srcbits+left*4;
4025 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
4027 if (rSrc==0xff0000 && gSrc==0x00ff00 && bSrc==0x0000ff) {
4028 if (bmpImage->green_mask==0x03e0) {
4029 if (bmpImage->red_mask==0x7f00) {
4030 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
4031 X11DRV_DIB_Convert_0888_to_555_asis
4034 dstbits,-bmpImage->bytes_per_line);
4035 } else if (bmpImage->blue_mask==0x7f00) {
4036 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
4037 X11DRV_DIB_Convert_0888_to_555_reverse
4040 dstbits,-bmpImage->bytes_per_line);
4044 } else if (bmpImage->green_mask==0x07e0) {
4045 if (bmpImage->red_mask==0xf800) {
4046 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
4047 X11DRV_DIB_Convert_0888_to_565_asis
4050 dstbits,-bmpImage->bytes_per_line);
4051 } else if (bmpImage->blue_mask==0xf800) {
4052 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
4053 X11DRV_DIB_Convert_0888_to_565_reverse
4056 dstbits,-bmpImage->bytes_per_line);
4063 } else if (rSrc==0x0000ff && gSrc==0x00ff00 && bSrc==0xff0000) {
4064 if (bmpImage->green_mask==0x03e0) {
4065 if (bmpImage->blue_mask==0x7f00) {
4066 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
4067 X11DRV_DIB_Convert_0888_to_555_asis
4070 dstbits,-bmpImage->bytes_per_line);
4071 } else if (bmpImage->red_mask==0x7f00) {
4072 /* ==== bgr 0888 dib -> rgb 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->blue_mask==0xf800) {
4082 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
4083 X11DRV_DIB_Convert_0888_to_565_asis
4086 dstbits,-bmpImage->bytes_per_line);
4087 } else if (bmpImage->red_mask==0xf800) {
4088 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
4089 X11DRV_DIB_Convert_0888_to_565_reverse
4092 dstbits,-bmpImage->bytes_per_line);
4100 if (bmpImage->green_mask==0x03e0 &&
4101 (bmpImage->red_mask==0x7f00 ||
4102 bmpImage->blue_mask==0x7f00)) {
4103 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
4104 X11DRV_DIB_Convert_any0888_to_5x5
4108 dstbits,-bmpImage->bytes_per_line,
4109 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4110 } else if (bmpImage->green_mask==0x07e0 &&
4111 (bmpImage->red_mask==0xf800 ||
4112 bmpImage->blue_mask==0xf800)) {
4113 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
4114 X11DRV_DIB_Convert_any0888_to_5x5
4118 dstbits,-bmpImage->bytes_per_line,
4119 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4129 WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
4130 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
4131 bmpImage->green_mask, bmpImage->blue_mask );
4137 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
4138 const DWORD* srcpixel;
4139 int rShift,gShift,bShift;
4141 rShift=X11DRV_DIB_MaskToShift(rSrc);
4142 gShift=X11DRV_DIB_MaskToShift(gSrc);
4143 bShift=X11DRV_DIB_MaskToShift(bSrc);
4145 for (h = lines - 1; h >= 0; h--) {
4146 srcpixel=(const DWORD*)srcbits;
4147 for (x = left; x < dstwidth+left; x++) {
4149 BYTE red,green,blue;
4150 srcvalue=*srcpixel++;
4151 red= (srcvalue >> rShift) & 0xff;
4152 green=(srcvalue >> gShift) & 0xff;
4153 blue= (srcvalue >> bShift) & 0xff;
4154 XPutPixel(bmpImage, x, h, X11DRV_PALETTE_ToPhysical
4155 (physDev, RGB(red,green,blue)));
4157 srcbits += linebytes;
4165 /***********************************************************************
4166 * X11DRV_DIB_GetImageBits_32
4168 * GetDIBits for an 32-bit deep DIB.
4170 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
4171 DWORD dstwidth, DWORD srcwidth,
4172 PALETTEENTRY *srccolors,
4173 DWORD rDst, DWORD gDst, DWORD bDst,
4174 XImage *bmpImage, DWORD linebytes )
4183 dstbits = dstbits + ( linebytes * (lines-1) );
4184 linebytes = -linebytes;
4189 switch (bmpImage->depth)
4192 if (bmpImage->bits_per_pixel==24) {
4193 const void* srcbits;
4195 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4197 if (rDst==bmpImage->red_mask && gDst==bmpImage->green_mask && bDst==bmpImage->blue_mask) {
4198 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
4199 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
4200 X11DRV_DIB_Convert_888_to_0888_asis
4202 srcbits,-bmpImage->bytes_per_line,
4204 } else if (bmpImage->green_mask!=0x00ff00 ||
4205 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4207 /* the tests below assume sane bmpImage masks */
4208 } else if (rDst==bmpImage->blue_mask && gDst==bmpImage->green_mask && bDst==bmpImage->red_mask) {
4209 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
4210 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
4211 X11DRV_DIB_Convert_888_to_0888_reverse
4213 srcbits,-bmpImage->bytes_per_line,
4215 } else if (bmpImage->blue_mask==0xff) {
4216 /* ==== rgb 888 bmp -> any 0888 dib ==== */
4217 X11DRV_DIB_Convert_rgb888_to_any0888
4219 srcbits,-bmpImage->bytes_per_line,
4223 /* ==== bgr 888 bmp -> any 0888 dib ==== */
4224 X11DRV_DIB_Convert_bgr888_to_any0888
4226 srcbits,-bmpImage->bytes_per_line,
4236 const char* srcbits;
4238 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4240 if (gDst==bmpImage->green_mask) {
4241 if (rDst==bmpImage->red_mask && bDst==bmpImage->blue_mask) {
4242 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
4243 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
4244 X11DRV_DIB_Convert_any_asis
4246 srcbits,-bmpImage->bytes_per_line,
4248 } else if (bmpImage->green_mask!=0x00ff00 ||
4249 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4251 /* the tests below assume sane bmpImage masks */
4252 } else if (rDst==bmpImage->blue_mask && bDst==bmpImage->red_mask) {
4253 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
4254 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
4255 X11DRV_DIB_Convert_0888_reverse
4257 srcbits,-bmpImage->bytes_per_line,
4260 /* ==== any 0888 bmp -> any 0888 dib ==== */
4261 X11DRV_DIB_Convert_0888_any
4263 srcbits,-bmpImage->bytes_per_line,
4264 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4268 } else if (bmpImage->green_mask!=0x00ff00 ||
4269 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4271 /* the tests below assume sane bmpImage masks */
4273 /* ==== any 0888 bmp -> any 0888 dib ==== */
4274 X11DRV_DIB_Convert_0888_any
4276 srcbits,-bmpImage->bytes_per_line,
4277 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4287 const char* srcbits;
4289 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4291 if (rDst==0xff0000 && gDst==0x00ff00 && bDst==0x0000ff) {
4292 if (bmpImage->green_mask==0x03e0) {
4293 if (bmpImage->red_mask==0x7f00) {
4294 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
4295 X11DRV_DIB_Convert_555_to_0888_asis
4297 srcbits,-bmpImage->bytes_per_line,
4299 } else if (bmpImage->blue_mask==0x7f00) {
4300 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
4301 X11DRV_DIB_Convert_555_to_0888_reverse
4303 srcbits,-bmpImage->bytes_per_line,
4308 } else if (bmpImage->green_mask==0x07e0) {
4309 if (bmpImage->red_mask==0xf800) {
4310 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
4311 X11DRV_DIB_Convert_565_to_0888_asis
4313 srcbits,-bmpImage->bytes_per_line,
4315 } else if (bmpImage->blue_mask==0xf800) {
4316 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
4317 X11DRV_DIB_Convert_565_to_0888_reverse
4319 srcbits,-bmpImage->bytes_per_line,
4327 } else if (rDst==0x0000ff && gDst==0x00ff00 && bDst==0xff0000) {
4328 if (bmpImage->green_mask==0x03e0) {
4329 if (bmpImage->blue_mask==0x7f00) {
4330 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
4331 X11DRV_DIB_Convert_555_to_0888_asis
4333 srcbits,-bmpImage->bytes_per_line,
4335 } else if (bmpImage->red_mask==0x7f00) {
4336 /* ==== rgb 555 bmp -> bgr 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->blue_mask==0xf800) {
4346 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
4347 X11DRV_DIB_Convert_565_to_0888_asis
4349 srcbits,-bmpImage->bytes_per_line,
4351 } else if (bmpImage->red_mask==0xf800) {
4352 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
4353 X11DRV_DIB_Convert_565_to_0888_reverse
4355 srcbits,-bmpImage->bytes_per_line,
4364 if (bmpImage->green_mask==0x03e0 &&
4365 (bmpImage->red_mask==0x7f00 ||
4366 bmpImage->blue_mask==0x7f00)) {
4367 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
4368 X11DRV_DIB_Convert_5x5_to_any0888
4370 srcbits,-bmpImage->bytes_per_line,
4371 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4374 } else if (bmpImage->green_mask==0x07e0 &&
4375 (bmpImage->red_mask==0xf800 ||
4376 bmpImage->blue_mask==0xf800)) {
4377 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
4378 X11DRV_DIB_Convert_5x5_to_any0888
4380 srcbits,-bmpImage->bytes_per_line,
4381 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4393 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
4394 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
4395 int rShift,gShift,bShift;
4398 rShift=X11DRV_DIB_MaskToShift(rDst);
4399 gShift=X11DRV_DIB_MaskToShift(gDst);
4400 bShift=X11DRV_DIB_MaskToShift(bDst);
4401 for (h = lines - 1; h >= 0; h--) {
4402 dstpixel=(DWORD*)dstbits;
4403 for (x = 0; x < dstwidth; x++) {
4404 PALETTEENTRY srcval;
4405 srcval = srccolors[XGetPixel(bmpImage, x, h)];
4406 *dstpixel++=(srcval.peRed << rShift) |
4407 (srcval.peGreen << gShift) |
4408 (srcval.peBlue << bShift);
4410 dstbits += linebytes;
4418 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
4419 /* ==== pal 8 bmp -> any 0888 dib ==== */
4420 int rShift,gShift,bShift;
4421 const void* srcbits;
4422 const BYTE* srcpixel;
4425 rShift=X11DRV_DIB_MaskToShift(rDst);
4426 gShift=X11DRV_DIB_MaskToShift(gDst);
4427 bShift=X11DRV_DIB_MaskToShift(bDst);
4428 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4429 for (h = lines - 1; h >= 0; h--) {
4431 dstpixel=(DWORD*)dstbits;
4432 for (x = 0; x < dstwidth; x++) {
4433 PALETTEENTRY srcval;
4434 srcval=srccolors[(int)*srcpixel++];
4435 *dstpixel++=(srcval.peRed << rShift) |
4436 (srcval.peGreen << gShift) |
4437 (srcval.peBlue << bShift);
4439 srcbits -= bmpImage->bytes_per_line;
4440 dstbits += linebytes;
4450 /* ==== any bmp format -> any 0888 dib ==== */
4451 int rShift,gShift,bShift;
4454 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
4455 bmpImage->depth, bmpImage->red_mask,
4456 bmpImage->green_mask, bmpImage->blue_mask,
4459 rShift=X11DRV_DIB_MaskToShift(rDst);
4460 gShift=X11DRV_DIB_MaskToShift(gDst);
4461 bShift=X11DRV_DIB_MaskToShift(bDst);
4462 for (h = lines - 1; h >= 0; h--) {
4463 dstpixel=(DWORD*)dstbits;
4464 for (x = 0; x < dstwidth; x++) {
4466 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
4467 *dstpixel++=(GetRValue(srcval) << rShift) |
4468 (GetGValue(srcval) << gShift) |
4469 (GetBValue(srcval) << bShift);
4471 dstbits += linebytes;
4478 /***********************************************************************
4479 * X11DRV_DIB_SetImageBits
4481 * Transfer the bits to an X image.
4482 * Helper function for SetDIBits() and SetDIBitsToDevice().
4484 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
4486 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
4491 bmpImage = descr->image;
4493 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
4494 descr->infoWidth, lines, 32, 0 );
4495 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
4496 if(bmpImage->data == NULL) {
4497 ERR("Out of memory!\n");
4498 XDestroyImage( bmpImage );
4499 wine_tsx11_unlock();
4504 TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
4505 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
4506 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
4507 bmpImage->depth,bmpImage->bits_per_pixel,
4508 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4510 /* Transfer the pixels */
4511 switch(descr->infoBpp)
4514 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
4515 descr->width, descr->xSrc, (int *)(descr->colorMap),
4516 bmpImage, descr->dibpitch );
4519 if (descr->compression) {
4520 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
4521 descr->width, descr->height, AllPlanes, ZPixmap,
4522 bmpImage, descr->xSrc, descr->ySrc );
4524 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
4525 descr->infoWidth, descr->width,
4526 descr->xSrc, (int *)(descr->colorMap),
4529 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
4530 descr->infoWidth, descr->width,
4531 descr->xSrc, (int*)(descr->colorMap),
4532 bmpImage, descr->dibpitch );
4535 if (descr->compression) {
4536 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
4537 descr->width, descr->height, AllPlanes, ZPixmap,
4538 bmpImage, descr->xSrc, descr->ySrc );
4539 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
4540 descr->infoWidth, descr->width,
4541 descr->xSrc, (int *)(descr->colorMap),
4544 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
4545 descr->infoWidth, descr->width,
4546 descr->xSrc, (int *)(descr->colorMap),
4547 bmpImage, descr->dibpitch );
4551 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
4552 descr->infoWidth, descr->width,
4553 descr->xSrc, descr->physDev,
4554 descr->rMask, descr->gMask, descr->bMask,
4555 bmpImage, descr->dibpitch);
4558 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
4559 descr->infoWidth, descr->width,
4560 descr->xSrc, descr->physDev,
4561 descr->rMask, descr->gMask, descr->bMask,
4562 bmpImage, descr->dibpitch);
4565 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
4566 descr->infoWidth, descr->width,
4567 descr->xSrc, descr->physDev,
4568 descr->rMask, descr->gMask, descr->bMask,
4569 bmpImage, descr->dibpitch);
4572 WARN("(%d): Invalid depth\n", descr->infoBpp );
4576 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
4577 descr->drawable, descr->gc, bmpImage,
4578 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
4579 descr->width, descr->height);
4580 #ifdef HAVE_LIBXXSHM
4583 XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
4584 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
4585 descr->width, descr->height, FALSE );
4586 XSync( gdi_display, 0 );
4590 XPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
4591 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
4592 descr->width, descr->height );
4594 if (!descr->image) XDestroyImage( bmpImage );
4595 wine_tsx11_unlock();
4599 /***********************************************************************
4600 * X11DRV_DIB_GetImageBits
4602 * Transfer the bits from an X image.
4604 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
4606 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
4611 bmpImage = descr->image;
4613 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
4614 descr->infoWidth, lines, 32, 0 );
4615 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
4616 if(bmpImage->data == NULL) {
4617 ERR("Out of memory!\n");
4618 XDestroyImage( bmpImage );
4619 wine_tsx11_unlock();
4626 int saveRed, saveGreen, saveBlue;
4628 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
4629 gdi_display, descr->drawable, bmpImage,
4630 descr->xSrc, descr->ySrc, AllPlanes);
4632 /* We must save and restore the bmpImage's masks in order
4633 * to preserve them across the call to XShmGetImage, which
4634 * decides to eleminate them since it doesn't happen to know
4635 * what the format of the image is supposed to be, even though
4637 saveRed = bmpImage->red_mask;
4638 saveBlue= bmpImage->blue_mask;
4639 saveGreen = bmpImage->green_mask;
4641 XShmGetImage( gdi_display, descr->drawable, bmpImage,
4642 descr->xSrc, descr->ySrc, AllPlanes);
4644 bmpImage->red_mask = saveRed;
4645 bmpImage->blue_mask = saveBlue;
4646 bmpImage->green_mask = saveGreen;
4650 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
4651 gdi_display, descr->drawable, descr->xSrc, descr->ySrc, descr->width,
4652 lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
4653 XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc,
4654 descr->width, lines, AllPlanes, ZPixmap,
4655 bmpImage, descr->xDest, descr->yDest );
4658 TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
4659 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
4660 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
4661 bmpImage->depth,bmpImage->bits_per_pixel,
4662 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4663 /* Transfer the pixels */
4664 switch(descr->infoBpp)
4667 X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
4668 descr->infoWidth, descr->width,
4669 descr->colorMap, descr->palentry,
4670 bmpImage, descr->dibpitch );
4674 if (descr->compression)
4675 FIXME("Compression not yet supported!\n");
4677 X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
4678 descr->infoWidth, descr->width,
4679 descr->colorMap, descr->palentry,
4680 bmpImage, descr->dibpitch );
4684 if (descr->compression)
4685 FIXME("Compression not yet supported!\n");
4687 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
4688 descr->infoWidth, descr->width,
4689 descr->colorMap, descr->palentry,
4690 bmpImage, descr->dibpitch );
4694 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
4695 descr->infoWidth,descr->width,
4697 descr->rMask, descr->gMask, descr->bMask,
4698 bmpImage, descr->dibpitch );
4702 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
4703 descr->infoWidth,descr->width,
4705 descr->rMask, descr->gMask, descr->bMask,
4706 bmpImage, descr->dibpitch);
4710 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
4711 descr->infoWidth, descr->width,
4713 descr->rMask, descr->gMask, descr->bMask,
4714 bmpImage, descr->dibpitch);
4718 WARN("(%d): Invalid depth\n", descr->infoBpp );
4722 if (!descr->image) XDestroyImage( bmpImage );
4723 wine_tsx11_unlock();
4727 /*************************************************************************
4728 * X11DRV_SetDIBitsToDevice
4731 INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWORD cx,
4732 DWORD cy, INT xSrc, INT ySrc,
4733 UINT startscan, UINT lines, LPCVOID bits,
4734 const BITMAPINFO *info, UINT coloruse )
4736 X11DRV_DIB_IMAGEBITS_DESCR descr;
4737 DWORD width, oldcy = cy;
4739 int height, tmpheight;
4740 DC *dc = physDev->dc;
4742 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
4743 &descr.infoBpp, &descr.compression ) == -1)
4746 if (height < 0) height = -height;
4747 if (!lines || (startscan >= height)) return 0;
4748 if (startscan + lines > height) lines = height - startscan;
4749 if (ySrc < startscan) ySrc = startscan;
4750 else if (ySrc >= startscan + lines) return 0;
4751 if (xSrc >= width) return 0;
4752 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
4753 if (xSrc + cx >= width) cx = width - xSrc;
4754 if (!cx || !cy) return 0;
4756 X11DRV_SetupGCForText( physDev ); /* To have the correct colors */
4757 TSXSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[dc->ROPmode-1]);
4759 switch (descr.infoBpp)
4764 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
4765 coloruse == DIB_PAL_COLORS ? physDev : NULL, coloruse,
4766 dc->bitsPerPixel, info, &descr.nColorMap );
4767 if (!descr.colorMap) return 0;
4768 descr.rMask = descr.gMask = descr.bMask = 0;
4772 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
4773 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
4774 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
4780 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
4781 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
4782 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
4787 descr.physDev = physDev;
4790 descr.palentry = NULL;
4791 descr.lines = tmpheight >= 0 ? lines : -lines;
4792 descr.infoWidth = width;
4793 descr.depth = dc->bitsPerPixel;
4794 descr.drawable = physDev->drawable;
4795 descr.gc = physDev->gc;
4797 descr.ySrc = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy)
4799 descr.xDest = dc->DCOrgX + XLPTODP( dc, xDest );
4800 descr.yDest = dc->DCOrgY + YLPTODP( dc, yDest ) +
4801 (tmpheight >= 0 ? oldcy-cy : 0);
4804 descr.useShm = FALSE;
4805 descr.dibpitch = ((width * descr.infoBpp + 31) &~31) / 8;
4807 result = X11DRV_DIB_SetImageBits( &descr );
4809 if (descr.infoBpp <= 8)
4810 HeapFree(GetProcessHeap(), 0, descr.colorMap);
4814 /***********************************************************************
4815 * SetDIBits (X11DRV.@)
4817 INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
4818 UINT lines, LPCVOID bits, const BITMAPINFO *info, UINT coloruse )
4820 X11DRV_DIB_IMAGEBITS_DESCR descr;
4822 int height, tmpheight;
4825 descr.physDev = physDev;
4827 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
4828 &descr.infoBpp, &descr.compression ) == -1)
4832 if (height < 0) height = -height;
4833 if (!lines || (startscan >= height))
4836 if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
4838 if (startscan + lines > height) lines = height - startscan;
4840 switch (descr.infoBpp)
4845 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
4846 coloruse == DIB_PAL_COLORS ? descr.physDev : NULL, coloruse,
4847 bmp->bitmap.bmBitsPixel,
4848 info, &descr.nColorMap );
4849 if (!descr.colorMap)
4851 GDI_ReleaseObj( hbitmap );
4854 descr.rMask = descr.gMask = descr.bMask = 0;
4858 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
4859 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
4860 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
4866 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
4867 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
4868 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
4876 if(!bmp->physBitmap)
4877 X11DRV_CreateBitmap(hbitmap);
4881 descr.palentry = NULL;
4882 descr.lines = tmpheight >= 0 ? lines : -lines;
4883 descr.depth = bmp->bitmap.bmBitsPixel;
4884 descr.drawable = (Pixmap)bmp->physBitmap;
4885 descr.gc = BITMAP_GC(bmp);
4889 descr.yDest = height - startscan - lines;
4890 descr.width = bmp->bitmap.bmWidth;
4891 descr.height = lines;
4892 descr.useShm = FALSE;
4893 descr.dibpitch = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
4894 X11DRV_DIB_Lock(bmp, DIB_Status_GdiMod, FALSE);
4895 result = X11DRV_DIB_SetImageBits( &descr );
4896 X11DRV_DIB_Unlock(bmp, TRUE);
4898 if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);
4900 GDI_ReleaseObj( hbitmap );
4904 /***********************************************************************
4905 * GetDIBits (X11DRV.@)
4907 INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan, UINT lines,
4908 LPVOID bits, BITMAPINFO *info, UINT coloruse )
4910 X11DRV_DIBSECTION *dib;
4911 X11DRV_DIB_IMAGEBITS_DESCR descr;
4912 PALETTEOBJ * palette;
4915 DC *dc = physDev->dc;
4917 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC )))
4919 if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
4921 GDI_ReleaseObj( dc->hPalette );
4924 dib = (X11DRV_DIBSECTION *) bmp->dib;
4926 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
4927 lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
4928 (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
4931 if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
4933 height = info->bmiHeader.biHeight;
4934 if (height < 0) height = -height;
4935 if( lines > height ) lines = height;
4936 /* Top-down images have a negative biHeight, the scanlines of theses images
4937 * were inverted in X11DRV_DIB_GetImageBits_xx
4938 * To prevent this we simply change the sign of lines
4939 * (the number of scan lines to copy).
4940 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
4942 if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
4944 if( startscan >= bmp->bitmap.bmHeight )
4950 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
4951 &descr.infoBpp, &descr.compression ) == -1)
4957 switch (descr.infoBpp)
4962 descr.rMask= descr.gMask = descr.bMask = 0;
4966 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
4967 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
4968 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
4972 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
4973 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
4974 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
4979 if(!bmp->physBitmap)
4980 X11DRV_CreateBitmap(hbitmap);
4983 descr.physDev = physDev;
4984 descr.palentry = palette->logpalette.palPalEntry;
4987 descr.lines = lines;
4988 descr.depth = bmp->bitmap.bmBitsPixel;
4989 descr.drawable = (Pixmap)bmp->physBitmap;
4990 descr.gc = BITMAP_GC(bmp);
4991 descr.width = bmp->bitmap.bmWidth;
4992 descr.height = bmp->bitmap.bmHeight;
4993 descr.colorMap = info->bmiColors;
4998 if (descr.lines > 0)
5000 descr.ySrc = (descr.height-1) - (startscan + (lines-1));
5004 descr.ySrc = startscan;
5006 #ifdef HAVE_LIBXXSHM
5007 descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
5009 descr.useShm = FALSE;
5011 descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
5012 : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
5014 X11DRV_DIB_Lock(bmp, DIB_Status_GdiMod, FALSE);
5015 X11DRV_DIB_GetImageBits( &descr );
5016 X11DRV_DIB_Unlock(bmp, TRUE);
5018 if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
5019 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
5020 info->bmiHeader.biWidth,
5021 info->bmiHeader.biHeight,
5022 info->bmiHeader.biBitCount );
5024 info->bmiHeader.biCompression = 0;
5025 if (descr.compression == BI_BITFIELDS)
5027 *(DWORD *)info->bmiColors = descr.rMask;
5028 *((DWORD *)info->bmiColors+1) = descr.gMask;
5029 *((DWORD *)info->bmiColors+2) = descr.bMask;
5033 GDI_ReleaseObj( dc->hPalette );
5034 GDI_ReleaseObj( hbitmap );
5038 /***********************************************************************
5039 * DIB_DoProtectDIBSection
5041 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
5043 DIBSECTION *dib = bmp->dib;
5044 INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
5045 : -dib->dsBm.bmHeight;
5046 /* use the biSizeImage data as the memory size only if we're dealing with a
5047 compressed image where the value is set. Otherwise, calculate based on
5049 INT totalSize = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
5050 ? dib->dsBmih.biSizeImage
5051 : dib->dsBm.bmWidthBytes * effHeight;
5054 VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
5055 TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
5058 /***********************************************************************
5059 * X11DRV_DIB_DoUpdateDIBSection
5061 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
5062 void *colorMap, int nColorMap,
5064 DWORD xSrc, DWORD ySrc,
5065 DWORD xDest, DWORD yDest,
5066 DWORD width, DWORD height)
5068 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5069 X11DRV_DIB_IMAGEBITS_DESCR descr;
5071 if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
5072 &descr.infoBpp, &descr.compression ) == -1)
5075 descr.physDev = NULL;
5076 descr.palentry = NULL;
5077 descr.image = dib->image;
5078 descr.colorMap = colorMap;
5079 descr.nColorMap = nColorMap;
5080 descr.bits = dib->dibSection.dsBm.bmBits;
5081 descr.depth = bmp->bitmap.bmBitsPixel;
5083 switch (descr.infoBpp)
5088 descr.rMask = descr.gMask = descr.bMask = 0;
5092 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
5093 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
5094 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
5099 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff0000;
5100 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x00ff00;
5101 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x0000ff;
5106 descr.drawable = dest;
5107 descr.gc = BITMAP_GC(bmp);
5110 descr.xDest = xDest;
5111 descr.yDest = yDest;
5112 descr.width = width;
5113 descr.height = height;
5114 #ifdef HAVE_LIBXXSHM
5115 descr.useShm = (dib->shminfo.shmid != -1);
5117 descr.useShm = FALSE;
5119 descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
5123 TRACE("Copying from Pixmap to DIB bits\n");
5124 X11DRV_DIB_GetImageBits( &descr );
5128 TRACE("Copying from DIB bits to Pixmap\n");
5129 X11DRV_DIB_SetImageBits( &descr );
5133 /***********************************************************************
5134 * X11DRV_DIB_CopyDIBSection
5136 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
5137 DWORD xSrc, DWORD ySrc, DWORD xDest, DWORD yDest,
5138 DWORD width, DWORD height)
5141 DC *dcSrc = physDevSrc->dc;
5142 DC *dcDst = physDevDst->dc;
5143 int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE;
5145 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc, dcDst,
5146 xSrc, ySrc, xDest, yDest, width, height);
5147 /* this function is meant as an optimization for BitBlt,
5148 * not to be called otherwise */
5149 if (!(dcSrc->flags & DC_MEMORY)) {
5150 ERR("called for non-memory source DC!?\n");
5154 bmp = (BITMAPOBJ *)GDI_GetObjPtr( dcSrc->hBitmap, BITMAP_MAGIC );
5155 if (!(bmp && bmp->dib)) {
5156 ERR("called for non-DIBSection!?\n");
5157 GDI_ReleaseObj( dcSrc->hBitmap );
5160 /* while BitBlt should already have made sure we only get
5161 * positive values, we should check for oversize values */
5162 if ((xSrc < bmp->bitmap.bmWidth) &&
5163 (ySrc < bmp->bitmap.bmHeight)) {
5164 if (xSrc + width > bmp->bitmap.bmWidth)
5165 width = bmp->bitmap.bmWidth - xSrc;
5166 if (ySrc + height > bmp->bitmap.bmHeight)
5167 height = bmp->bitmap.bmHeight - ySrc;
5168 /* if the source bitmap is 8bpp or less, we're supposed to use the
5169 * DC's palette for color conversion (not the DIB color table) */
5170 if (bmp->dib->dsBm.bmBitsPixel <= 8) {
5171 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5172 if ((!dcSrc->hPalette) ||
5173 (dcSrc->hPalette == GetStockObject(DEFAULT_PALETTE))) {
5174 /* HACK: no palette has been set in the source DC,
5175 * use the DIB colormap instead - this is necessary in some
5176 * cases since we need to do depth conversion in some places
5177 * where real Windows can just copy data straight over */
5178 colorMap = dib->colorMap;
5179 nColorMap = dib->nColorMap;
5181 colorMap = X11DRV_DIB_BuildColorMap( physDevSrc, (WORD)-1,
5182 bmp->dib->dsBm.bmBitsPixel,
5183 (BITMAPINFO*)&(bmp->dib->dsBmih),
5185 if (colorMap) aColorMap = TRUE;
5188 /* perform the copy */
5189 X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap,
5190 physDevDst->drawable, xSrc, ySrc, xDest, yDest,
5192 /* free color mapping */
5194 HeapFree(GetProcessHeap(), 0, colorMap);
5196 GDI_ReleaseObj( dcSrc->hBitmap );
5199 /***********************************************************************
5200 * X11DRV_DIB_DoUpdateDIBSection
5202 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
5204 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5205 X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap,
5206 (Drawable)bmp->physBitmap, 0, 0, 0, 0,
5207 bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
5210 /***********************************************************************
5211 * X11DRV_DIB_FaultHandler
5213 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
5218 bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
5219 if (!bmp) return FALSE;
5221 state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
5222 if (state != DIB_Status_InSync) {
5223 /* no way to tell whether app needs read or write yet,
5225 X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
5227 /* hm, apparently the app must have write access */
5228 X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
5230 X11DRV_DIB_Unlock(bmp, TRUE);
5232 GDI_ReleaseObj( (HBITMAP)res );
5236 /***********************************************************************
5239 INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
5241 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5242 INT ret = DIB_Status_None;
5245 EnterCriticalSection(&(dib->lock));
5248 case DIB_Status_GdiMod:
5249 /* GDI access - request to draw on pixmap */
5250 switch (dib->status)
5253 case DIB_Status_None:
5254 dib->p_status = DIB_Status_GdiMod;
5255 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
5258 case DIB_Status_GdiMod:
5259 TRACE("GdiMod requested in status GdiMod\n" );
5262 case DIB_Status_InSync:
5263 TRACE("GdiMod requested in status InSync\n" );
5264 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5265 dib->status = DIB_Status_GdiMod;
5266 dib->p_status = DIB_Status_InSync;
5269 case DIB_Status_AuxMod:
5270 TRACE("GdiMod requested in status AuxMod\n" );
5271 if (lossy) dib->status = DIB_Status_GdiMod;
5272 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
5273 dib->p_status = DIB_Status_AuxMod;
5274 if (dib->status != DIB_Status_AppMod) {
5275 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5278 /* fall through if copy_aux() had to change to AppMod state */
5280 case DIB_Status_AppMod:
5281 TRACE("GdiMod requested in status AppMod\n" );
5283 /* make it readonly to avoid app changing data while we copy */
5284 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5285 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
5287 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5288 dib->p_status = DIB_Status_AppMod;
5289 dib->status = DIB_Status_GdiMod;
5294 case DIB_Status_InSync:
5295 /* App access - request access to read DIB surface */
5296 /* (typically called from signal handler) */
5297 switch (dib->status)
5300 case DIB_Status_None:
5301 /* shouldn't happen from signal handler */
5304 case DIB_Status_AuxMod:
5305 TRACE("InSync requested in status AuxMod\n" );
5306 if (lossy) dib->status = DIB_Status_InSync;
5308 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5309 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
5311 if (dib->status != DIB_Status_GdiMod) {
5312 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5315 /* fall through if copy_aux() had to change to GdiMod state */
5317 case DIB_Status_GdiMod:
5318 TRACE("InSync requested in status GdiMod\n" );
5320 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5321 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
5323 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5324 dib->status = DIB_Status_InSync;
5327 case DIB_Status_InSync:
5328 TRACE("InSync requested in status InSync\n" );
5329 /* shouldn't happen from signal handler */
5332 case DIB_Status_AppMod:
5333 TRACE("InSync requested in status AppMod\n" );
5334 /* no reason to do anything here, and this
5335 * shouldn't happen from signal handler */
5340 case DIB_Status_AppMod:
5341 /* App access - request access to write DIB surface */
5342 /* (typically called from signal handler) */
5343 switch (dib->status)
5346 case DIB_Status_None:
5347 /* shouldn't happen from signal handler */
5350 case DIB_Status_AuxMod:
5351 TRACE("AppMod requested in status AuxMod\n" );
5352 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5353 if (lossy) dib->status = DIB_Status_AppMod;
5354 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
5355 if (dib->status != DIB_Status_GdiMod)
5357 /* fall through if copy_aux() had to change to GdiMod state */
5359 case DIB_Status_GdiMod:
5360 TRACE("AppMod requested in status GdiMod\n" );
5361 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5362 if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
5363 dib->status = DIB_Status_AppMod;
5366 case DIB_Status_InSync:
5367 TRACE("AppMod requested in status InSync\n" );
5368 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5369 dib->status = DIB_Status_AppMod;
5372 case DIB_Status_AppMod:
5373 TRACE("AppMod requested in status AppMod\n" );
5374 /* shouldn't happen from signal handler */
5379 case DIB_Status_AuxMod:
5380 if (dib->status == DIB_Status_None) {
5381 dib->p_status = req;
5383 if (dib->status != DIB_Status_AuxMod)
5384 dib->p_status = dib->status;
5385 dib->status = DIB_Status_AuxMod;
5388 /* it is up to the caller to do the copy/conversion, probably
5389 * using the return value to decide where to copy from */
5391 LeaveCriticalSection(&(dib->lock));
5396 /***********************************************************************
5399 INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
5401 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5402 INT ret = DIB_Status_None;
5405 TRACE("Locking %p from thread %08lx\n", bmp, GetCurrentThreadId());
5406 EnterCriticalSection(&(dib->lock));
5408 if (req != DIB_Status_None)
5409 X11DRV_DIB_Coerce(bmp, req, lossy);
5414 /***********************************************************************
5417 void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
5419 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5422 switch (dib->status)
5425 case DIB_Status_None:
5426 /* in case anyone is wondering, this is the "signal handler doesn't
5427 * work" case, where we always have to be ready for app access */
5429 switch (dib->p_status)
5431 case DIB_Status_AuxMod:
5432 TRACE("Unlocking and syncing from AuxMod\n" );
5433 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
5434 if (dib->status != DIB_Status_None) {
5435 dib->p_status = dib->status;
5436 dib->status = DIB_Status_None;
5438 if (dib->p_status != DIB_Status_GdiMod)
5440 /* fall through if copy_aux() had to change to GdiMod state */
5442 case DIB_Status_GdiMod:
5443 TRACE("Unlocking and syncing from GdiMod\n" );
5444 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
5448 TRACE("Unlocking without needing to sync\n" );
5452 else TRACE("Unlocking with no changes\n");
5453 dib->p_status = DIB_Status_None;
5456 case DIB_Status_GdiMod:
5457 TRACE("Unlocking in status GdiMod\n" );
5458 /* DIB was protected in Coerce */
5460 /* no commit, revert to InSync if applicable */
5461 if ((dib->p_status == DIB_Status_InSync) ||
5462 (dib->p_status == DIB_Status_AppMod)) {
5463 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5464 dib->status = DIB_Status_InSync;
5469 case DIB_Status_InSync:
5470 TRACE("Unlocking in status InSync\n" );
5471 /* DIB was already protected in Coerce */
5474 case DIB_Status_AppMod:
5475 TRACE("Unlocking in status AppMod\n" );
5476 /* DIB was already protected in Coerce */
5477 /* this case is ordinary only called from the signal handler,
5478 * so we don't bother to check for !commit */
5481 case DIB_Status_AuxMod:
5482 TRACE("Unlocking in status AuxMod\n" );
5484 /* DIB may need protection now */
5485 if ((dib->p_status == DIB_Status_InSync) ||
5486 (dib->p_status == DIB_Status_AppMod))
5487 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5489 /* no commit, revert to previous state */
5490 if (dib->p_status != DIB_Status_None)
5491 dib->status = dib->p_status;
5492 /* no protections changed */
5494 dib->p_status = DIB_Status_None;
5497 LeaveCriticalSection(&(dib->lock));
5498 TRACE("Unlocked %p\n", bmp);
5502 /***********************************************************************
5503 * X11DRV_CoerceDIBSection2
5505 INT X11DRV_CoerceDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
5510 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5511 if (!bmp) return DIB_Status_None;
5512 ret = X11DRV_DIB_Coerce(bmp, req, lossy);
5513 GDI_ReleaseObj( hBmp );
5517 /***********************************************************************
5518 * X11DRV_LockDIBSection2
5520 INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
5525 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5526 if (!bmp) return DIB_Status_None;
5527 ret = X11DRV_DIB_Lock(bmp, req, lossy);
5528 GDI_ReleaseObj( hBmp );
5532 /***********************************************************************
5533 * X11DRV_UnlockDIBSection2
5535 void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
5539 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5541 X11DRV_DIB_Unlock(bmp, commit);
5542 GDI_ReleaseObj( hBmp );
5545 /***********************************************************************
5546 * X11DRV_CoerceDIBSection
5548 INT X11DRV_CoerceDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
5550 if (!physDev) return DIB_Status_None;
5551 return X11DRV_CoerceDIBSection2( physDev->dc->hBitmap, req, lossy );
5554 /***********************************************************************
5555 * X11DRV_LockDIBSection
5557 INT X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev, INT req, BOOL lossy)
5559 if (!physDev) return DIB_Status_None;
5560 if (!(physDev->dc->flags & DC_MEMORY)) return DIB_Status_None;
5562 return X11DRV_LockDIBSection2( physDev->dc->hBitmap, req, lossy );
5565 /***********************************************************************
5566 * X11DRV_UnlockDIBSection
5568 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE *physDev, BOOL commit)
5570 if (!physDev) return;
5571 if (!(physDev->dc->flags & DC_MEMORY)) return;
5573 X11DRV_UnlockDIBSection2( physDev->dc->hBitmap, commit );
5577 #ifdef HAVE_LIBXXSHM
5578 /***********************************************************************
5579 * X11DRV_XShmErrorHandler
5582 static int XShmErrorHandler( Display *dpy, XErrorEvent *event, void *arg )
5584 return 1; /* FIXME: should check event contents */
5587 /***********************************************************************
5588 * X11DRV_XShmCreateImage
5591 static XImage *X11DRV_XShmCreateImage( int width, int height, int bpp,
5592 XShmSegmentInfo* shminfo)
5597 image = XShmCreateImage(gdi_display, visual, bpp, ZPixmap, NULL, shminfo, width, height);
5600 shminfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height,
5602 if( shminfo->shmid != -1 )
5604 shminfo->shmaddr = image->data = shmat(shminfo->shmid, 0, 0);
5605 if( shminfo->shmaddr != (char*)-1 )
5609 shminfo->readOnly = FALSE;
5610 X11DRV_expect_error( gdi_display, XShmErrorHandler, NULL );
5611 ok = (XShmAttach( gdi_display, shminfo ) != 0);
5612 if (X11DRV_check_error()) ok = FALSE;
5615 shmctl(shminfo->shmid, IPC_RMID, 0);
5616 wine_tsx11_unlock();
5617 return image; /* Success! */
5619 /* An error occured */
5620 shmdt(shminfo->shmaddr);
5622 shmctl(shminfo->shmid, IPC_RMID, 0);
5624 XFlush(gdi_display);
5625 XDestroyImage(image);
5628 wine_tsx11_unlock();
5631 #endif /* HAVE_LIBXXSHM */
5634 /***********************************************************************
5635 * X11DRV_DIB_CreateDIBSection
5637 HBITMAP X11DRV_DIB_CreateDIBSection(
5638 X11DRV_PDEVICE *physDev, BITMAPINFO *bmi, UINT usage,
5639 LPVOID *bits, HANDLE section,
5640 DWORD offset, DWORD ovr_pitch)
5643 BITMAPOBJ *bmp = NULL;
5644 X11DRV_DIBSECTION *dib = NULL;
5645 int *colorMap = NULL;
5648 /* Fill BITMAP32 structure with DIB data */
5649 BITMAPINFOHEADER *bi = &bmi->bmiHeader;
5650 INT effHeight, totalSize;
5652 LPVOID mapBits = NULL;
5654 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
5655 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
5656 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
5658 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
5660 bm.bmWidth = bi->biWidth;
5661 bm.bmHeight = effHeight;
5662 bm.bmWidthBytes = ovr_pitch ? ovr_pitch
5663 : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
5664 bm.bmPlanes = bi->biPlanes;
5665 bm.bmBitsPixel = bi->biBitCount;
5668 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
5669 we're dealing with a compressed bitmap. Otherwise, use width * height. */
5670 totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
5671 ? bi->biSizeImage : bm.bmWidthBytes * effHeight;
5675 SYSTEM_INFO SystemInfo;
5679 GetSystemInfo( &SystemInfo );
5680 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
5681 mapSize = totalSize + (offset - mapOffset);
5682 mapBits = MapViewOfFile( section,
5683 FILE_MAP_ALL_ACCESS,
5687 bm.bmBits = (char *)mapBits + (offset - mapOffset);
5689 else if (ovr_pitch && offset)
5690 bm.bmBits = (LPVOID) offset;
5693 bm.bmBits = VirtualAlloc(NULL, totalSize,
5694 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
5697 /* Create Color Map */
5698 if (bm.bmBits && bm.bmBitsPixel <= 8)
5699 colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? physDev : NULL,
5700 usage, bm.bmBitsPixel, bmi, &nColorMap );
5702 /* Allocate Memory for DIB and fill structure */
5704 dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
5707 dib->dibSection.dsBm = bm;
5708 dib->dibSection.dsBmih = *bi;
5709 dib->dibSection.dsBmih.biSizeImage = totalSize;
5711 /* Set dsBitfields values */
5712 if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
5714 dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
5716 else switch( bi->biBitCount )
5720 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
5721 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
5722 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
5727 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff0000;
5728 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x00ff00;
5729 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x0000ff;
5732 dib->dibSection.dshSection = section;
5733 dib->dibSection.dsOffset = offset;
5735 dib->status = DIB_Status_None;
5736 dib->nColorMap = nColorMap;
5737 dib->colorMap = colorMap;
5740 /* Create Device Dependent Bitmap and add DIB pointer */
5743 res = CreateDIBitmap(physDev->hdc, bi, 0, NULL, bmi, usage);
5746 bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
5749 bmp->dib = (DIBSECTION *) dib;
5751 if(!bmp->physBitmap)
5752 X11DRV_CreateBitmap(res);
5760 #ifdef HAVE_LIBXXSHM
5761 if (TSXShmQueryExtension(gdi_display) &&
5762 (dib->image = X11DRV_XShmCreateImage( bm.bmWidth, effHeight,
5763 bmp->bitmap.bmBitsPixel, &dib->shminfo )) )
5765 ; /* Created Image */
5767 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
5768 dib->shminfo.shmid = -1;
5771 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
5775 /* Clean up in case of errors */
5776 if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
5778 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
5779 res, bmp, dib, bm.bmBits);
5783 UnmapViewOfFile(mapBits), bm.bmBits = NULL;
5785 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
5788 if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
5789 if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
5790 if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
5791 if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
5792 if (res) { DeleteObject(res); res = 0; }
5796 /* Install fault handler, if possible */
5797 InitializeCriticalSection(&(dib->lock));
5798 if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
5800 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5801 if (dib) dib->status = DIB_Status_AppMod;
5805 /* Return BITMAP handle and storage location */
5806 if (bmp) GDI_ReleaseObj(res);
5807 if (bm.bmBits && bits) *bits = bm.bmBits;
5811 /***********************************************************************
5812 * X11DRV_DIB_DeleteDIBSection
5814 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
5816 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5820 #ifdef HAVE_LIBXXSHM
5821 if (dib->shminfo.shmid != -1)
5823 TSXShmDetach (gdi_display, &(dib->shminfo));
5824 XDestroyImage (dib->image);
5825 shmdt (dib->shminfo.shmaddr);
5826 dib->shminfo.shmid = -1;
5830 XDestroyImage( dib->image );
5834 HeapFree(GetProcessHeap(), 0, dib->colorMap);
5836 DeleteCriticalSection(&(dib->lock));
5839 /***********************************************************************
5840 * SetDIBColorTable (X11DRV.@)
5842 UINT X11DRV_SetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, const RGBQUAD *colors )
5845 X11DRV_DIBSECTION *dib;
5848 if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( physDev->dc->hBitmap, BITMAP_MAGIC ))) return 0;
5849 dib = (X11DRV_DIBSECTION *) bmp->dib;
5851 if (dib && dib->colorMap) {
5852 UINT end = count + start;
5853 if (end > dib->nColorMap) end = dib->nColorMap;
5855 * Changing color table might change the mapping between
5856 * DIB colors and X11 colors and thus alter the visible state
5857 * of the bitmap object.
5859 X11DRV_DIB_Lock(bmp, DIB_Status_AppMod, FALSE);
5860 X11DRV_DIB_GenColorMap( physDev, dib->colorMap, DIB_RGB_COLORS,
5861 dib->dibSection.dsBm.bmBitsPixel,
5862 TRUE, colors, start, end );
5863 X11DRV_DIB_Unlock(bmp, TRUE);
5866 GDI_ReleaseObj( physDev->dc->hBitmap );
5870 /***********************************************************************
5871 * GetDIBColorTable (X11DRV.@)
5873 UINT X11DRV_GetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, RGBQUAD *colors )
5876 X11DRV_DIBSECTION *dib;
5879 if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( physDev->dc->hBitmap, BITMAP_MAGIC ))) return 0;
5880 dib = (X11DRV_DIBSECTION *) bmp->dib;
5882 if (dib && dib->colorMap) {
5883 UINT i, end = count + start;
5884 if (end > dib->nColorMap) end = dib->nColorMap;
5885 for (i = start; i < end; i++,colors++) {
5886 COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] );
5887 colors->rgbBlue = GetBValue(col);
5888 colors->rgbGreen = GetGValue(col);
5889 colors->rgbRed = GetRValue(col);
5890 colors->rgbReserved = 0;
5894 GDI_ReleaseObj( physDev->dc->hBitmap );
5899 /**************************************************************************
5900 * X11DRV_DIB_CreateDIBFromPixmap
5902 * Allocates a packed DIB and copies the Pixmap data into it.
5903 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
5905 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
5908 BITMAPOBJ *pBmp = NULL;
5909 HGLOBAL hPackedDIB = 0;
5911 /* Allocates an HBITMAP which references the Pixmap passed to us */
5912 hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap);
5915 TRACE("\tCould not create bitmap header for Pixmap\n");
5920 * Create a packed DIB from the Pixmap wrapper bitmap created above.
5921 * A packed DIB contains a BITMAPINFO structure followed immediately by
5922 * an optional color palette and the pixel data.
5924 hPackedDIB = DIB_CreateDIBFromBitmap(hdc, hBmp);
5926 /* Get a pointer to the BITMAPOBJ structure */
5927 pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5929 /* We can now get rid of the HBITMAP wrapper we created earlier.
5930 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
5934 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
5935 pBmp->physBitmap = NULL;
5938 GDI_ReleaseObj( hBmp );
5942 TRACE("\tReturning packed DIB %x\n", hPackedDIB);
5947 /**************************************************************************
5948 * X11DRV_DIB_CreatePixmapFromDIB
5950 * Creates a Pixmap from a packed DIB
5952 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
5954 Pixmap pixmap = None;
5956 BITMAPOBJ *pBmp = NULL;
5957 LPBYTE pPackedDIB = NULL;
5958 LPBITMAPINFO pbmi = NULL;
5959 LPBITMAPINFOHEADER pbmiHeader = NULL;
5960 LPBYTE pbits = NULL;
5962 /* Get a pointer to the packed DIB's data */
5963 pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
5964 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
5965 pbmi = (LPBITMAPINFO)pPackedDIB;
5966 pbits = (LPBYTE)(pPackedDIB
5967 + DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
5969 /* Create a DDB from the DIB */
5971 hBmp = CreateDIBitmap(hdc,
5978 GlobalUnlock(hPackedDIB);
5980 TRACE("CreateDIBitmap returned %x\n", hBmp);
5982 /* Retrieve the internal Pixmap from the DDB */
5984 pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5986 pixmap = (Pixmap)pBmp->physBitmap;
5987 /* clear the physBitmap so that we can steal its pixmap */
5988 pBmp->physBitmap = NULL;
5991 /* Delete the DDB we created earlier now that we have stolen its pixmap */
5992 GDI_ReleaseObj( hBmp );
5995 TRACE("\tReturning Pixmap %ld\n", pixmap);