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];
51 static int XShmErrorFlag = 0;
54 /* This structure holds the arguments for DIB_SetImageBits() */
60 PALETTEENTRY *palentry;
81 } X11DRV_DIB_IMAGEBITS_DESCR;
86 RLE_EOL = 0, /* End of line */
87 RLE_END = 1, /* End of bitmap */
88 RLE_DELTA = 2 /* Delta */
91 /***********************************************************************
92 * X11DRV_DIB_GetXImageWidthBytes
94 * Return the width of an X image in bytes
96 inline static int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
98 if (!depth || depth > 32) goto error;
100 if (!ximageDepthTable[depth-1])
102 XImage *testimage = XCreateImage( gdi_display, visual, depth,
103 ZPixmap, 0, NULL, 1, 1, 32, 20 );
106 ximageDepthTable[depth-1] = testimage->bits_per_pixel;
107 XDestroyImage( testimage );
109 else ximageDepthTable[depth-1] = -1;
111 if (ximageDepthTable[depth-1] != -1)
112 return (4 * ((width * ximageDepthTable[depth-1] + 31) / 32));
115 WARN( "(%d): Unsupported depth\n", depth );
120 /***********************************************************************
121 * X11DRV_DIB_CreateXImage
125 XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth )
131 width_bytes = X11DRV_DIB_GetXImageWidthBytes( width, depth );
132 image = XCreateImage( gdi_display, visual, depth, ZPixmap, 0,
133 calloc( height, width_bytes ),
134 width, height, 32, width_bytes );
140 /***********************************************************************
141 * X11DRV_DIB_GenColorMap
143 * Fills the color map of a bitmap palette. Should not be called
144 * for a >8-bit deep bitmap.
146 int *X11DRV_DIB_GenColorMap( DC *dc, int *colorMapping,
147 WORD coloruse, WORD depth, BOOL quads,
148 const void *colorPtr, int start, int end )
152 if (coloruse == DIB_RGB_COLORS)
154 int max = 1 << depth;
156 if (end > max) end = max;
160 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
162 if (depth == 1) /* Monochrome */
163 for (i = start; i < end; i++, rgb++)
164 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
165 rgb->rgbBlue > 255*3/2);
167 for (i = start; i < end; i++, rgb++)
168 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbRed,
174 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
176 if (depth == 1) /* Monochrome */
177 for (i = start; i < end; i++, rgb++)
178 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
179 rgb->rgbtBlue > 255*3/2);
181 for (i = start; i < end; i++, rgb++)
182 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbtRed,
187 else /* DIB_PAL_COLORS */
190 WORD * index = (WORD *)colorPtr;
192 for (i = start; i < end; i++, index++)
193 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(*index) );
195 for (i = start; i < end; i++)
196 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(i) );
203 /***********************************************************************
204 * X11DRV_DIB_BuildColorMap
206 * Build the color map from the bitmap palette. Should not be called
207 * for a >8-bit deep bitmap.
209 int *X11DRV_DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth,
210 const BITMAPINFO *info, int *nColors )
214 const void *colorPtr;
217 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
219 colors = info->bmiHeader.biClrUsed;
220 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
221 colorPtr = info->bmiColors;
223 else /* assume BITMAPCOREINFO */
225 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
226 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
231 ERR("called with >256 colors!\n");
235 /* just so CopyDIBSection doesn't have to create an identity palette */
236 if (coloruse == (WORD)-1) colorPtr = NULL;
238 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
239 colors * sizeof(int) )))
243 return X11DRV_DIB_GenColorMap( dc, colorMapping, coloruse, depth,
244 isInfo, colorPtr, 0, colors);
248 /***********************************************************************
249 * X11DRV_DIB_MapColor
251 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
255 if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
258 for (color = 0; color < nPhysMap; color++)
259 if (physMap[color] == phys)
262 WARN("Strange color %08x\n", phys);
267 /*********************************************************************
268 * X11DRV_DIB_GetNearestIndex
270 * Helper for X11DRV_DIB_GetDIBits.
271 * Returns the nearest colour table index for a given RGB.
272 * Nearest is defined by minimizing the sum of the squares.
274 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
276 INT i, best = -1, diff, bestdiff = -1;
279 for(color = colormap, i = 0; i < numColors; color++, i++) {
280 diff = (r - color->rgbRed) * (r - color->rgbRed) +
281 (g - color->rgbGreen) * (g - color->rgbGreen) +
282 (b - color->rgbBlue) * (b - color->rgbBlue);
285 if(best == -1 || diff < bestdiff) {
292 /*********************************************************************
293 * X11DRV_DIB_MaskToShift
295 * Helper for X11DRV_DIB_GetDIBits.
296 * Returns the by how many bits to shift a given color so that it is
297 * in the proper position.
299 static INT X11DRV_DIB_MaskToShift(DWORD mask)
307 while ((mask&1)==0) {
314 /***********************************************************************
315 * X11DRV_DIB_Convert_any_asis
317 * All X11DRV_DIB_Convert_Xxx functions take at least the following
320 * This is the width in pixel of the surface to copy. This may be less
321 * than the full width of the image.
323 * The number of lines to copy. This may be less than the full height
324 * of the image. This is always >0.
326 * Points to the first byte containing data to be copied. If the source
327 * surface starts are coordinates (x,y) then this is:
328 * image_ptr+x*bytes_pre_pixel+y*bytes_per_line
329 * (with further adjustments for top-down/bottom-up images)
331 * This is the number of bytes per line. It may be >0 or <0 depending on
332 * whether this is a top-down or bottom-up image.
334 * Same as srcbits but for the destination
336 * Same as srclinebytes but for the destination.
339 * - The supported Dib formats are: pal1, pal4, pal8, rgb555, bgr555,
340 * rgb565, bgr565, rgb888 and any 32bit (0888) format.
341 * The supported XImage (Bmp) formats are: pal1, pal4, pal8,
342 * rgb555, bgr555, rgb565, bgr565, rgb888, bgr888, rgb0888, bgr0888.
343 * - Rgb formats are those for which the masks are such that:
344 * red_mask > green_mask > blue_mask
345 * - Bgr formats are those for which the masks sort in the other direction.
346 * - Many conversion functions handle both rgb->bgr and bgr->rgb conversions
347 * so the comments use h, g, l to mean respectively the source color in the
348 * high bits, the green, and the source color in the low bits.
350 static void X11DRV_DIB_Convert_any_asis(int width, int height,
352 const void* srcbits, int srclinebytes,
353 void* dstbits, int dstlinebytes)
357 width*=bytes_per_pixel;
358 for (y=0; y<height; y++) {
359 memcpy(dstbits, srcbits, width);
360 srcbits += srclinebytes;
361 dstbits += dstlinebytes;
369 static void X11DRV_DIB_Convert_555_reverse(int width, int height,
370 const void* srcbits, int srclinebytes,
371 void* dstbits, int dstlinebytes)
373 const DWORD* srcpixel;
377 for (y=0; y<height; y++) {
380 for (x=0; x<width/2; x++) {
381 /* Do 2 pixels at a time */
384 *dstpixel++=((srcval << 10) & 0x7c007c00) | /* h */
385 ( srcval & 0x03e003e0) | /* g */
386 ((srcval >> 10) & 0x001f001f); /* l */
389 /* And the the odd pixel */
391 srcval=*((WORD*)srcpixel);
392 *((WORD*)dstpixel)=((srcval << 10) & 0x7c00) | /* h */
393 ( srcval & 0x03e0) | /* g */
394 ((srcval >> 10) & 0x001f); /* l */
396 srcbits += srclinebytes;
397 dstbits += dstlinebytes;
401 static void X11DRV_DIB_Convert_555_to_565_asis(int width, int height,
402 const void* srcbits, int srclinebytes,
403 void* dstbits, int dstlinebytes)
405 const DWORD* srcpixel;
409 for (y=0; y<height; y++) {
412 for (x=0; x<width/2; x++) {
413 /* Do 2 pixels at a time */
416 *dstpixel++=((srcval << 1) & 0xffc0ffc0) | /* h, g */
417 ((srcval >> 4) & 0x00200020) | /* g - 1 bit */
418 ( srcval & 0x001f001f); /* l */
421 /* And the the odd pixel */
423 srcval=*((WORD*)srcpixel);
424 *((WORD*)dstpixel)=((srcval << 1) & 0xffc0) | /* h, g */
425 ((srcval >> 4) & 0x0020) | /* g - 1 bit */
426 (srcval & 0x001f); /* l */
428 srcbits += srclinebytes;
429 dstbits += dstlinebytes;
433 static void X11DRV_DIB_Convert_555_to_565_reverse(int width, int height,
434 const void* srcbits, int srclinebytes,
435 void* dstbits, int dstlinebytes)
437 const DWORD* srcpixel;
441 for (y=0; y<height; y++) {
444 for (x=0; x<width/2; x++) {
445 /* Do 2 pixels at a time */
448 *dstpixel++=((srcval >> 10) & 0x001f001f) | /* h */
449 ((srcval << 1) & 0x07c007c0) | /* g */
450 ((srcval >> 4) & 0x00200020) | /* g - 1 bit */
451 ((srcval << 11) & 0xf800f800); /* l */
454 /* And the the odd pixel */
456 srcval=*((WORD*)srcpixel);
457 *((WORD*)dstpixel)=((srcval >> 10) & 0x001f) | /* h */
458 ((srcval << 1) & 0x07c0) | /* g */
459 ((srcval >> 4) & 0x0020) | /* g - 1 bit */
460 ((srcval << 11) & 0xf800); /* l */
462 srcbits += srclinebytes;
463 dstbits += dstlinebytes;
467 static void X11DRV_DIB_Convert_555_to_888_asis(int width, int height,
468 const void* srcbits, int srclinebytes,
469 void* dstbits, int dstlinebytes)
471 const WORD* srcpixel;
475 for (y=0; y<height; y++) {
478 for (x=0; x<width; x++) {
481 dstpixel[0]=((srcval << 3) & 0xf8) | /* l */
482 ((srcval >> 2) & 0x07); /* l - 3 bits */
483 dstpixel[1]=((srcval >> 2) & 0xf8) | /* g */
484 ((srcval >> 7) & 0x07); /* g - 3 bits */
485 dstpixel[2]=((srcval >> 7) & 0xf8) | /* h */
486 ((srcval >> 12) & 0x07); /* h - 3 bits */
489 srcbits += srclinebytes;
490 dstbits += dstlinebytes;
494 static void X11DRV_DIB_Convert_555_to_888_reverse(int width, int height,
495 const void* srcbits, int srclinebytes,
496 void* dstbits, int dstlinebytes)
498 const WORD* srcpixel;
502 for (y=0; y<height; y++) {
505 for (x=0; x<width; x++) {
508 dstpixel[0]=((srcval >> 7) & 0xf8) | /* h */
509 ((srcval >> 12) & 0x07); /* h - 3 bits */
510 dstpixel[1]=((srcval >> 2) & 0xf8) | /* g */
511 ((srcval >> 7) & 0x07); /* g - 3 bits */
512 dstpixel[2]=((srcval << 3) & 0xf8) | /* l */
513 ((srcval >> 2) & 0x07); /* l - 3 bits */
516 srcbits += srclinebytes;
517 dstbits += dstlinebytes;
521 static void X11DRV_DIB_Convert_555_to_0888_asis(int width, int height,
522 const void* srcbits, int srclinebytes,
523 void* dstbits, int dstlinebytes)
525 const WORD* srcpixel;
529 for (y=0; y<height; y++) {
532 for (x=0; x<width; x++) {
535 *dstpixel++=((srcval << 9) & 0xf80000) | /* h */
536 ((srcval << 4) & 0x070000) | /* h - 3 bits */
537 ((srcval << 6) & 0x00f800) | /* g */
538 ((srcval << 1) & 0x000700) | /* g - 3 bits */
539 ((srcval << 3) & 0x0000f8) | /* l */
540 ((srcval >> 2) & 0x000007); /* l - 3 bits */
542 srcbits += srclinebytes;
543 dstbits += dstlinebytes;
547 static void X11DRV_DIB_Convert_555_to_0888_reverse(int width, int height,
548 const void* srcbits, int srclinebytes,
549 void* dstbits, int dstlinebytes)
551 const WORD* srcpixel;
555 for (y=0; y<height; y++) {
558 for (x=0; x<width; x++) {
561 *dstpixel++=((srcval >> 7) & 0x0000f8) | /* h */
562 ((srcval >> 12) & 0x000007) | /* h - 3 bits */
563 ((srcval << 6) & 0x00f800) | /* g */
564 ((srcval << 1) & 0x000700) | /* g - 3 bits */
565 ((srcval << 19) & 0xf80000) | /* l */
566 ((srcval << 14) & 0x070000); /* l - 3 bits */
568 srcbits += srclinebytes;
569 dstbits += dstlinebytes;
573 static void X11DRV_DIB_Convert_5x5_to_any0888(int width, int height,
574 const void* srcbits, int srclinebytes,
575 WORD rsrc, WORD gsrc, WORD bsrc,
576 void* dstbits, int dstlinebytes,
577 DWORD rdst, DWORD gdst, DWORD bdst)
579 int rRightShift1,gRightShift1,bRightShift1;
580 int rRightShift2,gRightShift2,bRightShift2;
582 int rLeftShift,gLeftShift,bLeftShift;
583 const WORD* srcpixel;
587 /* Note, the source pixel value is shifted left by 16 bits so that
588 * we know we will always have to shift right to extract the components.
590 rRightShift1=16+X11DRV_DIB_MaskToShift(rsrc)-3;
591 gRightShift1=16+X11DRV_DIB_MaskToShift(gsrc)-3;
592 bRightShift1=16+X11DRV_DIB_MaskToShift(bsrc)-3;
593 rRightShift2=rRightShift1+5;
594 gRightShift2=gRightShift1+5;
595 bRightShift2=bRightShift1+5;
597 /* Green has 5 bits, like the others */
601 /* Green has 6 bits, not 5. Compensate. */
608 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
609 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
610 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
612 for (y=0; y<height; y++) {
615 for (x=0; x<width; x++) {
618 srcval=*srcpixel++ << 16;
619 red= ((srcval >> rRightShift1) & 0xf8) |
620 ((srcval >> rRightShift2) & 0x07);
621 green=((srcval >> gRightShift1) & gMask1) |
622 ((srcval >> gRightShift2) & gMask2);
623 blue= ((srcval >> bRightShift1) & 0xf8) |
624 ((srcval >> bRightShift2) & 0x07);
625 *dstpixel++=(red << rLeftShift) |
626 (green << gLeftShift) |
627 (blue << bLeftShift);
629 srcbits += srclinebytes;
630 dstbits += dstlinebytes;
635 * 16 bits conversions
638 static void X11DRV_DIB_Convert_565_reverse(int width, int height,
639 const void* srcbits, int srclinebytes,
640 void* dstbits, int dstlinebytes)
642 const DWORD* srcpixel;
646 for (y=0; y<height; y++) {
649 for (x=0; x<width/2; x++) {
650 /* Do 2 pixels at a time */
653 *dstpixel++=((srcval << 11) & 0xf800f800) | /* h */
654 ( srcval & 0x07e007e0) | /* g */
655 ((srcval >> 11) & 0x001f001f); /* l */
658 /* And the the odd pixel */
660 srcval=*((WORD*)srcpixel);
661 *((WORD*)dstpixel)=((srcval << 11) & 0xf800) | /* h */
662 ( srcval & 0x07e0) | /* g */
663 ((srcval >> 11) & 0x001f); /* l */
665 srcbits += srclinebytes;
666 dstbits += dstlinebytes;
670 static void X11DRV_DIB_Convert_565_to_555_asis(int width, int height,
671 const void* srcbits, int srclinebytes,
672 void* dstbits, int dstlinebytes)
674 const DWORD* srcpixel;
678 for (y=0; y<height; y++) {
681 for (x=0; x<width/2; x++) {
682 /* Do 2 pixels at a time */
685 *dstpixel++=((srcval >> 1) & 0x7fe07fe0) | /* h, g */
686 ( srcval & 0x001f001f); /* l */
689 /* And the the odd pixel */
691 srcval=*((WORD*)srcpixel);
692 *((WORD*)dstpixel)=((srcval >> 1) & 0x7fe0) | /* h, g */
693 ( srcval & 0x001f); /* l */
695 srcbits += srclinebytes;
696 dstbits += dstlinebytes;
700 static void X11DRV_DIB_Convert_565_to_555_reverse(int width, int height,
701 const void* srcbits, int srclinebytes,
702 void* dstbits, int dstlinebytes)
704 const DWORD* srcpixel;
708 for (y=0; y<height; y++) {
711 for (x=0; x<width/2; x++) {
712 /* Do 2 pixels at a time */
715 *dstpixel++=((srcval >> 11) & 0x001f001f) | /* h */
716 ((srcval >> 1) & 0x03e003e0) | /* g */
717 ((srcval << 10) & 0x7c007c00); /* l */
720 /* And the the odd pixel */
722 srcval=*((WORD*)srcpixel);
723 *((WORD*)dstpixel)=((srcval >> 11) & 0x001f) | /* h */
724 ((srcval >> 1) & 0x03e0) | /* g */
725 ((srcval << 10) & 0x7c00); /* l */
727 srcbits += srclinebytes;
728 dstbits += dstlinebytes;
732 static void X11DRV_DIB_Convert_565_to_888_asis(int width, int height,
733 const void* srcbits, int srclinebytes,
734 void* dstbits, int dstlinebytes)
736 const WORD* srcpixel;
740 for (y=0; y<height; y++) {
743 for (x=0; x<width; x++) {
746 dstpixel[0]=((srcval << 3) & 0xf8) | /* l */
747 ((srcval >> 2) & 0x07); /* l - 3 bits */
748 dstpixel[1]=((srcval >> 3) & 0xfc) | /* g */
749 ((srcval >> 9) & 0x03); /* g - 2 bits */
750 dstpixel[2]=((srcval >> 8) & 0xf8) | /* h */
751 ((srcval >> 13) & 0x07); /* h - 3 bits */
754 srcbits += srclinebytes;
755 dstbits += dstlinebytes;
759 static void X11DRV_DIB_Convert_565_to_888_reverse(int width, int height,
760 const void* srcbits, int srclinebytes,
761 void* dstbits, int dstlinebytes)
763 const WORD* srcpixel;
767 for (y=0; y<height; y++) {
770 for (x=0; x<width; x++) {
773 dstpixel[0]=((srcval >> 8) & 0xf8) | /* h */
774 ((srcval >> 13) & 0x07); /* h - 3 bits */
775 dstpixel[1]=((srcval >> 3) & 0xfc) | /* g */
776 ((srcval >> 9) & 0x03); /* g - 2 bits */
777 dstpixel[2]=((srcval << 3) & 0xf8) | /* l */
778 ((srcval >> 2) & 0x07); /* l - 3 bits */
781 srcbits += srclinebytes;
782 dstbits += dstlinebytes;
786 static void X11DRV_DIB_Convert_565_to_0888_asis(int width, int height,
787 const void* srcbits, int srclinebytes,
788 void* dstbits, int dstlinebytes)
790 const WORD* srcpixel;
794 for (y=0; y<height; y++) {
797 for (x=0; x<width; x++) {
800 *dstpixel++=((srcval << 8) & 0xf80000) | /* h */
801 ((srcval << 3) & 0x070000) | /* h - 3 bits */
802 ((srcval << 5) & 0x00fc00) | /* g */
803 ((srcval >> 1) & 0x000300) | /* g - 2 bits */
804 ((srcval << 3) & 0x0000f8) | /* l */
805 ((srcval >> 2) & 0x000007); /* l - 3 bits */
807 srcbits += srclinebytes;
808 dstbits += dstlinebytes;
812 static void X11DRV_DIB_Convert_565_to_0888_reverse(int width, int height,
813 const void* srcbits, int srclinebytes,
814 void* dstbits, int dstlinebytes)
816 const WORD* srcpixel;
820 for (y=0; y<height; y++) {
823 for (x=0; x<width; x++) {
826 *dstpixel++=((srcval >> 8) & 0x0000f8) | /* h */
827 ((srcval >> 13) & 0x000007) | /* h - 3 bits */
828 ((srcval << 5) & 0x00fc00) | /* g */
829 ((srcval >> 1) & 0x000300) | /* g - 2 bits */
830 ((srcval << 19) & 0xf80000) | /* l */
831 ((srcval << 14) & 0x070000); /* l - 3 bits */
833 srcbits += srclinebytes;
834 dstbits += dstlinebytes;
842 static void X11DRV_DIB_Convert_888_reverse(int width, int height,
843 const void* srcbits, int srclinebytes,
844 void* dstbits, int dstlinebytes)
846 const BYTE* srcpixel;
850 for (y=0; y<height; y++) {
853 for (x=0; x<width; x++) {
854 dstpixel[0]=srcpixel[2];
855 dstpixel[1]=srcpixel[1];
856 dstpixel[2]=srcpixel[0];
860 srcbits += srclinebytes;
861 dstbits += dstlinebytes;
865 static void X11DRV_DIB_Convert_888_to_555_asis(int width, int height,
866 const void* srcbits, int srclinebytes,
867 void* dstbits, int dstlinebytes)
869 const DWORD* srcpixel;
877 for (y=0; y<height; y++) {
880 for (x=0; x<width; x++) {
881 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
882 DWORD srcval1,srcval2;
884 dstpixel[0]=((srcval1 >> 3) & 0x001f) | /* l1 */
885 ((srcval1 >> 6) & 0x03e0) | /* g1 */
886 ((srcval1 >> 9) & 0x7c00); /* h1 */
888 dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */
889 ((srcval2 << 2) & 0x03e0) | /* g2 */
890 ((srcval2 >> 1) & 0x7c00); /* h2 */
892 dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */
893 ((srcval2 >> 22) & 0x03e0) | /* g3 */
894 ((srcval1 << 7) & 0x7c00); /* h3 */
895 dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */
896 ((srcval1 >> 14) & 0x03e0) | /* g4 */
897 ((srcval1 >> 17) & 0x7c00); /* h4 */
901 /* And now up to 3 odd pixels */
902 srcbyte=(LPBYTE)srcpixel;
903 for (x=0; x<oddwidth; x++) {
905 dstval =((srcbyte[0] >> 3) & 0x001f); /* l */
906 dstval|=((srcbyte[1] << 2) & 0x03e0); /* g */
907 dstval|=((srcbyte[2] << 7) & 0x7c00); /* h */
911 srcbits += srclinebytes;
912 dstbits += dstlinebytes;
916 static void X11DRV_DIB_Convert_888_to_555_reverse(int width, int height,
917 const void* srcbits, int srclinebytes,
918 void* dstbits, int dstlinebytes)
920 const DWORD* srcpixel;
928 for (y=0; y<height; y++) {
931 for (x=0; x<width; x++) {
932 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
933 DWORD srcval1,srcval2;
935 dstpixel[0]=((srcval1 << 7) & 0x7c00) | /* l1 */
936 ((srcval1 >> 6) & 0x03e0) | /* g1 */
937 ((srcval1 >> 19) & 0x001f); /* h1 */
939 dstpixel[1]=((srcval1 >> 17) & 0x7c00) | /* l2 */
940 ((srcval2 << 2) & 0x03e0) | /* g2 */
941 ((srcval2 >> 11) & 0x001f); /* h2 */
943 dstpixel[2]=((srcval2 >> 9) & 0x7c00) | /* l3 */
944 ((srcval2 >> 22) & 0x03e0) | /* g3 */
945 ((srcval1 >> 3) & 0x001f); /* h3 */
946 dstpixel[3]=((srcval1 >> 1) & 0x7c00) | /* l4 */
947 ((srcval1 >> 14) & 0x03e0) | /* g4 */
948 ((srcval1 >> 27) & 0x001f); /* h4 */
952 /* And now up to 3 odd pixels */
953 srcbyte=(LPBYTE)srcpixel;
954 for (x=0; x<oddwidth; x++) {
956 dstval =((srcbyte[0] << 7) & 0x7c00); /* l */
957 dstval|=((srcbyte[1] << 2) & 0x03e0); /* g */
958 dstval|=((srcbyte[2] >> 3) & 0x001f); /* h */
962 srcbits += srclinebytes;
963 dstbits += dstlinebytes;
967 static void X11DRV_DIB_Convert_888_to_565_asis(int width, int height,
968 const void* srcbits, int srclinebytes,
969 void* dstbits, int dstlinebytes)
971 const DWORD* srcpixel;
979 for (y=0; y<height; y++) {
982 for (x=0; x<width; x++) {
983 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
984 DWORD srcval1,srcval2;
986 dstpixel[0]=((srcval1 >> 3) & 0x001f) | /* l1 */
987 ((srcval1 >> 5) & 0x07e0) | /* g1 */
988 ((srcval1 >> 8) & 0xf800); /* h1 */
990 dstpixel[1]=((srcval1 >> 27) & 0x001f) | /* l2 */
991 ((srcval2 << 3) & 0x07e0) | /* g2 */
992 ( srcval2 & 0xf800); /* h2 */
994 dstpixel[2]=((srcval2 >> 19) & 0x001f) | /* l3 */
995 ((srcval2 >> 21) & 0x07e0) | /* g3 */
996 ((srcval1 << 8) & 0xf800); /* h3 */
997 dstpixel[3]=((srcval1 >> 11) & 0x001f) | /* l4 */
998 ((srcval1 >> 13) & 0x07e0) | /* g4 */
999 ((srcval1 >> 16) & 0xf800); /* h4 */
1003 /* And now up to 3 odd pixels */
1004 srcbyte=(LPBYTE)srcpixel;
1005 for (x=0; x<oddwidth; x++) {
1007 dstval =((srcbyte[0] >> 3) & 0x001f); /* l */
1008 dstval|=((srcbyte[1] << 3) & 0x07e0); /* g */
1009 dstval|=((srcbyte[2] << 8) & 0xf800); /* h */
1013 srcbits += srclinebytes;
1014 dstbits += dstlinebytes;
1018 static void X11DRV_DIB_Convert_888_to_565_reverse(int width, int height,
1019 const void* srcbits, int srclinebytes,
1020 void* dstbits, int dstlinebytes)
1022 const DWORD* srcpixel;
1023 const BYTE* srcbyte;
1030 for (y=0; y<height; y++) {
1033 for (x=0; x<width; x++) {
1034 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
1035 DWORD srcval1,srcval2;
1036 srcval1=srcpixel[0];
1037 dstpixel[0]=((srcval1 << 8) & 0xf800) | /* l1 */
1038 ((srcval1 >> 5) & 0x07e0) | /* g1 */
1039 ((srcval1 >> 19) & 0x001f); /* h1 */
1040 srcval2=srcpixel[1];
1041 dstpixel[1]=((srcval1 >> 16) & 0xf800) | /* l2 */
1042 ((srcval2 << 3) & 0x07e0) | /* g2 */
1043 ((srcval2 >> 11) & 0x001f); /* h2 */
1044 srcval1=srcpixel[2];
1045 dstpixel[2]=((srcval2 >> 8) & 0xf800) | /* l3 */
1046 ((srcval2 >> 21) & 0x07e0) | /* g3 */
1047 ((srcval1 >> 3) & 0x001f); /* h3 */
1048 dstpixel[3]=(srcval1 & 0xf800) | /* l4 */
1049 ((srcval1 >> 13) & 0x07e0) | /* g4 */
1050 ((srcval1 >> 27) & 0x001f); /* h4 */
1054 /* And now up to 3 odd pixels */
1055 srcbyte=(LPBYTE)srcpixel;
1056 for (x=0; x<oddwidth; x++) {
1058 dstval =((srcbyte[0] << 8) & 0xf800); /* l */
1059 dstval|=((srcbyte[1] << 3) & 0x07e0); /* g */
1060 dstval|=((srcbyte[2] >> 3) & 0x001f); /* h */
1064 srcbits += srclinebytes;
1065 dstbits += dstlinebytes;
1069 static void X11DRV_DIB_Convert_888_to_0888_asis(int width, int height,
1070 const void* srcbits, int srclinebytes,
1071 void* dstbits, int dstlinebytes)
1073 const DWORD* srcpixel;
1080 for (y=0; y<height; y++) {
1083 for (x=0; x<width; x++) {
1084 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1085 DWORD srcval1,srcval2;
1086 srcval1=srcpixel[0];
1087 dstpixel[0]=( srcval1 & 0x00ffffff); /* h1, g1, l1 */
1088 srcval2=srcpixel[1];
1089 dstpixel[1]=( srcval1 >> 24) | /* l2 */
1090 ((srcval2 << 8) & 0x00ffff00); /* h2, g2 */
1091 srcval1=srcpixel[2];
1092 dstpixel[2]=( srcval2 >> 16) | /* g3, l3 */
1093 ((srcval1 << 16) & 0x00ff0000); /* h3 */
1094 dstpixel[3]=( srcval1 >> 8); /* h4, g4, l4 */
1098 /* And now up to 3 odd pixels */
1099 for (x=0; x<oddwidth; x++) {
1102 srcpixel=(LPDWORD)(((char*)srcpixel)+3);
1103 *dstpixel++=( srcval & 0x00ffffff); /* h, g, l */
1105 srcbits += srclinebytes;
1106 dstbits += dstlinebytes;
1110 static void X11DRV_DIB_Convert_888_to_0888_reverse(int width, int height,
1111 const void* srcbits, int srclinebytes,
1112 void* dstbits, int dstlinebytes)
1114 const DWORD* srcpixel;
1121 for (y=0; y<height; y++) {
1124 for (x=0; x<width; x++) {
1125 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1126 DWORD srcval1,srcval2;
1128 srcval1=srcpixel[0];
1129 dstpixel[0]=((srcval1 >> 16) & 0x0000ff) | /* h1 */
1130 ( srcval1 & 0x00ff00) | /* g1 */
1131 ((srcval1 << 16) & 0xff0000); /* l1 */
1132 srcval2=srcpixel[1];
1133 dstpixel[1]=((srcval1 >> 8) & 0xff0000) | /* l2 */
1134 ((srcval2 << 8) & 0x00ff00) | /* g2 */
1135 ((srcval2 >> 8) & 0x0000ff); /* h2 */
1136 srcval1=srcpixel[2];
1137 dstpixel[2]=( srcval2 & 0xff0000) | /* l3 */
1138 ((srcval2 >> 16) & 0x00ff00) | /* g3 */
1139 ( srcval1 & 0x0000ff); /* h3 */
1140 dstpixel[3]=((srcval1 >> 24) & 0x0000ff) | /* h4 */
1141 ((srcval1 >> 8) & 0x00ff00) | /* g4 */
1142 ((srcval1 << 8) & 0xff0000); /* l4 */
1146 /* And now up to 3 odd pixels */
1147 for (x=0; x<oddwidth; x++) {
1150 srcpixel=(LPDWORD)(((char*)srcpixel)+3);
1151 *dstpixel++=((srcval >> 16) & 0x0000ff) | /* h */
1152 ( srcval & 0x00ff00) | /* g */
1153 ((srcval << 16) & 0xff0000); /* l */
1155 srcbits += srclinebytes;
1156 dstbits += dstlinebytes;
1160 static void X11DRV_DIB_Convert_rgb888_to_any0888(int width, int height,
1161 const void* srcbits, int srclinebytes,
1162 void* dstbits, int dstlinebytes,
1163 DWORD rdst, DWORD gdst, DWORD bdst)
1165 int rLeftShift,gLeftShift,bLeftShift;
1166 const BYTE* srcpixel;
1170 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1171 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1172 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1173 for (y=0; y<height; y++) {
1176 for (x=0; x<width; x++) {
1177 *dstpixel++=(srcpixel[0] << bLeftShift) | /* b */
1178 (srcpixel[1] << gLeftShift) | /* g */
1179 (srcpixel[2] << rLeftShift); /* r */
1182 srcbits += srclinebytes;
1183 dstbits += dstlinebytes;
1187 static void X11DRV_DIB_Convert_bgr888_to_any0888(int width, int height,
1188 const void* srcbits, int srclinebytes,
1189 void* dstbits, int dstlinebytes,
1190 DWORD rdst, DWORD gdst, DWORD bdst)
1192 int rLeftShift,gLeftShift,bLeftShift;
1193 const BYTE* srcpixel;
1197 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1198 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1199 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1200 for (y=0; y<height; y++) {
1203 for (x=0; x<width; x++) {
1204 *dstpixel++=(srcpixel[0] << rLeftShift) | /* r */
1205 (srcpixel[1] << gLeftShift) | /* g */
1206 (srcpixel[2] << bLeftShift); /* b */
1209 srcbits += srclinebytes;
1210 dstbits += dstlinebytes;
1215 * 32 bit conversions
1218 static void X11DRV_DIB_Convert_0888_reverse(int width, int height,
1219 const void* srcbits, int srclinebytes,
1220 void* dstbits, int dstlinebytes)
1222 const DWORD* srcpixel;
1226 for (y=0; y<height; y++) {
1229 for (x=0; x<width; x++) {
1232 *dstpixel++=((srcval << 16) & 0x00ff0000) | /* h */
1233 ( srcval & 0x0000ff00) | /* g */
1234 ((srcval >> 16) & 0x000000ff); /* l */
1236 srcbits += srclinebytes;
1237 dstbits += dstlinebytes;
1241 static void X11DRV_DIB_Convert_0888_any(int width, int height,
1242 const void* srcbits, int srclinebytes,
1243 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1244 void* dstbits, int dstlinebytes,
1245 DWORD rdst, DWORD gdst, DWORD bdst)
1247 int rRightShift,gRightShift,bRightShift;
1248 int rLeftShift,gLeftShift,bLeftShift;
1249 const DWORD* srcpixel;
1253 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1254 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1255 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1256 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1257 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1258 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1259 for (y=0; y<height; y++) {
1262 for (x=0; x<width; x++) {
1265 *dstpixel++=(((srcval >> rRightShift) & 0xff) << rLeftShift) |
1266 (((srcval >> gRightShift) & 0xff) << gLeftShift) |
1267 (((srcval >> bRightShift) & 0xff) << bLeftShift);
1269 srcbits += srclinebytes;
1270 dstbits += dstlinebytes;
1274 static void X11DRV_DIB_Convert_0888_to_555_asis(int width, int height,
1275 const void* srcbits, int srclinebytes,
1276 void* dstbits, int dstlinebytes)
1278 const DWORD* srcpixel;
1282 for (y=0; y<height; y++) {
1285 for (x=0; x<width; x++) {
1288 *dstpixel++=((srcval >> 9) & 0x7c00) | /* h */
1289 ((srcval >> 6) & 0x03e0) | /* g */
1290 ((srcval >> 3) & 0x001f); /* l */
1292 srcbits += srclinebytes;
1293 dstbits += dstlinebytes;
1297 static void X11DRV_DIB_Convert_0888_to_555_reverse(int width, int height,
1298 const void* srcbits, int srclinebytes,
1299 void* dstbits, int dstlinebytes)
1301 const DWORD* srcpixel;
1305 for (y=0; y<height; y++) {
1308 for (x=0; x<width; x++) {
1311 *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1312 ((srcval >> 6) & 0x03e0) | /* g */
1313 ((srcval << 7) & 0x7c00); /* l */
1315 srcbits += srclinebytes;
1316 dstbits += dstlinebytes;
1320 static void X11DRV_DIB_Convert_0888_to_565_asis(int width, int height,
1321 const void* srcbits, int srclinebytes,
1322 void* dstbits, int dstlinebytes)
1324 const DWORD* srcpixel;
1328 for (y=0; y<height; y++) {
1331 for (x=0; x<width; x++) {
1334 *dstpixel++=((srcval >> 8) & 0xf800) | /* h */
1335 ((srcval >> 5) & 0x07e0) | /* g */
1336 ((srcval >> 3) & 0x001f); /* l */
1338 srcbits += srclinebytes;
1339 dstbits += dstlinebytes;
1343 static void X11DRV_DIB_Convert_0888_to_565_reverse(int width, int height,
1344 const void* srcbits, int srclinebytes,
1345 void* dstbits, int dstlinebytes)
1347 const DWORD* srcpixel;
1351 for (y=0; y<height; y++) {
1354 for (x=0; x<width; x++) {
1357 *dstpixel++=((srcval >> 19) & 0x001f) | /* h */
1358 ((srcval >> 5) & 0x07e0) | /* g */
1359 ((srcval << 8) & 0xf800); /* l */
1361 srcbits += srclinebytes;
1362 dstbits += dstlinebytes;
1366 static void X11DRV_DIB_Convert_any0888_to_5x5(int width, int height,
1367 const void* srcbits, int srclinebytes,
1368 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1369 void* dstbits, int dstlinebytes,
1370 WORD rdst, WORD gdst, WORD bdst)
1372 int rRightShift,gRightShift,bRightShift;
1373 int rLeftShift,gLeftShift,bLeftShift;
1374 const DWORD* srcpixel;
1378 /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel
1379 * contains 0x11223344.
1380 * - first we shift 0x11223344 right by rRightShift to bring the most
1381 * significant bits of the red components in the bottom 5 (or 6) bits
1383 * - then we remove non red bits by anding with the modified rdst (0x1f)
1385 * - finally shift these bits left by rLeftShift so that they end up in
1389 rRightShift=X11DRV_DIB_MaskToShift(rsrc)+3;
1390 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1391 gRightShift+=(gdst==0x07e0?2:3);
1392 bRightShift=X11DRV_DIB_MaskToShift(bsrc)+3;
1394 rLeftShift=X11DRV_DIB_MaskToShift(rdst);
1395 rdst=rdst >> rLeftShift;
1396 gLeftShift=X11DRV_DIB_MaskToShift(gdst);
1397 gdst=gdst >> gLeftShift;
1398 bLeftShift=X11DRV_DIB_MaskToShift(bdst);
1399 bdst=bdst >> bLeftShift;
1401 for (y=0; y<height; y++) {
1404 for (x=0; x<width; x++) {
1407 *dstpixel++=(((srcval >> rRightShift) & rdst) << rLeftShift) |
1408 (((srcval >> gRightShift) & gdst) << gLeftShift) |
1409 (((srcval >> bRightShift) & bdst) << bLeftShift);
1411 srcbits += srclinebytes;
1412 dstbits += dstlinebytes;
1416 static void X11DRV_DIB_Convert_0888_to_888_asis(int width, int height,
1417 const void* srcbits, int srclinebytes,
1418 void* dstbits, int dstlinebytes)
1420 const DWORD* srcpixel;
1428 for (y=0; y<height; y++) {
1431 for (x=0; x<width; x++) {
1432 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1434 srcval=((*srcpixel++) & 0x00ffffff); /* h1, g1, l1*/
1435 *dstpixel++=srcval | ((*srcpixel) << 24); /* h2 */
1436 srcval=((*srcpixel++ >> 8 ) & 0x0000ffff); /* g2, l2 */
1437 *dstpixel++=srcval | ((*srcpixel) << 16); /* h3, g3 */
1438 srcval=((*srcpixel++ >> 16) & 0x000000ff); /* l3 */
1439 *dstpixel++=srcval | ((*srcpixel++) << 8); /* h4, g4, l4 */
1441 /* And now up to 3 odd pixels */
1442 dstbyte=(BYTE*)dstpixel;
1443 for (x=0; x<oddwidth; x++) {
1446 *((WORD*)dstbyte)++=srcval; /* h, g */
1447 *dstbyte++=srcval >> 16; /* l */
1449 srcbits += srclinebytes;
1450 dstbits += dstlinebytes;
1454 static void X11DRV_DIB_Convert_0888_to_888_reverse(int width, int height,
1455 const void* srcbits, int srclinebytes,
1456 void* dstbits, int dstlinebytes)
1458 const DWORD* srcpixel;
1466 for (y=0; y<height; y++) {
1469 for (x=0; x<width; x++) {
1470 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1471 DWORD srcval1,srcval2;
1472 srcval1=*srcpixel++;
1473 srcval2= ((srcval1 >> 16) & 0x000000ff) | /* h1 */
1474 ( srcval1 & 0x0000ff00) | /* g1 */
1475 ((srcval1 << 16) & 0x00ff0000); /* l1 */
1476 srcval1=*srcpixel++;
1477 *dstpixel++=srcval2 |
1478 ((srcval1 << 8) & 0xff000000); /* h2 */
1479 srcval2= ((srcval1 >> 8) & 0x000000ff) | /* g2 */
1480 ((srcval1 << 8) & 0x0000ff00); /* l2 */
1481 srcval1=*srcpixel++;
1482 *dstpixel++=srcval2 |
1483 ( srcval1 & 0x00ff0000) | /* h3 */
1484 ((srcval1 << 16) & 0xff000000); /* g3 */
1485 srcval2= ( srcval1 & 0x000000ff); /* l3 */
1486 srcval1=*srcpixel++;
1487 *dstpixel++=srcval2 |
1488 ((srcval1 >> 8) & 0x0000ff00) | /* h4 */
1489 ((srcval1 << 8) & 0x00ff0000) | /* g4 */
1490 ( srcval1 << 24); /* l4 */
1492 /* And now up to 3 odd pixels */
1493 dstbyte=(BYTE*)dstpixel;
1494 for (x=0; x<oddwidth; x++) {
1497 *((WORD*)dstbyte)++=((srcval >> 16) & 0x00ff) | /* h */
1498 (srcval & 0xff00); /* g */
1499 *dstbyte++=srcval; /* l */
1501 srcbits += srclinebytes;
1502 dstbits += dstlinebytes;
1506 static void X11DRV_DIB_Convert_any0888_to_rgb888(int width, int height,
1507 const void* srcbits, int srclinebytes,
1508 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1509 void* dstbits, int dstlinebytes)
1511 int rRightShift,gRightShift,bRightShift;
1512 const DWORD* srcpixel;
1516 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1517 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1518 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1519 for (y=0; y<height; y++) {
1522 for (x=0; x<width; x++) {
1525 dstpixel[0]=(srcval >> bRightShift); /* b */
1526 dstpixel[1]=(srcval >> gRightShift); /* g */
1527 dstpixel[2]=(srcval >> rRightShift); /* r */
1530 srcbits += srclinebytes;
1531 dstbits += dstlinebytes;
1535 static void X11DRV_DIB_Convert_any0888_to_bgr888(int width, int height,
1536 const void* srcbits, int srclinebytes,
1537 DWORD rsrc, DWORD gsrc, DWORD bsrc,
1538 void* dstbits, int dstlinebytes)
1540 int rRightShift,gRightShift,bRightShift;
1541 const DWORD* srcpixel;
1545 rRightShift=X11DRV_DIB_MaskToShift(rsrc);
1546 gRightShift=X11DRV_DIB_MaskToShift(gsrc);
1547 bRightShift=X11DRV_DIB_MaskToShift(bsrc);
1548 for (y=0; y<height; y++) {
1551 for (x=0; x<width; x++) {
1554 dstpixel[0]=(srcval >> rRightShift); /* r */
1555 dstpixel[1]=(srcval >> gRightShift); /* g */
1556 dstpixel[2]=(srcval >> bRightShift); /* b */
1559 srcbits += srclinebytes;
1560 dstbits += dstlinebytes;
1564 /***********************************************************************
1565 * X11DRV_DIB_SetImageBits_1
1567 * SetDIBits for a 1-bit deep DIB.
1569 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
1570 DWORD srcwidth, DWORD dstwidth, int left,
1571 int *colors, XImage *bmpImage, DWORD linebytes)
1574 const BYTE* srcbyte;
1580 srcbits = srcbits + linebytes * (lines - 1);
1581 linebytes = -linebytes;
1584 if ((extra = (left & 7)) != 0) {
1588 srcbits += left >> 3;
1590 /* ==== pal 1 dib -> any bmp format ==== */
1591 for (h = lines-1; h >=0; h--) {
1593 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
1594 for (i = dstwidth/8, x = left; i > 0; i--) {
1596 XPutPixel( bmpImage, x++, h, colors[ srcval >> 7] );
1597 XPutPixel( bmpImage, x++, h, colors[(srcval >> 6) & 1] );
1598 XPutPixel( bmpImage, x++, h, colors[(srcval >> 5) & 1] );
1599 XPutPixel( bmpImage, x++, h, colors[(srcval >> 4) & 1] );
1600 XPutPixel( bmpImage, x++, h, colors[(srcval >> 3) & 1] );
1601 XPutPixel( bmpImage, x++, h, colors[(srcval >> 2) & 1] );
1602 XPutPixel( bmpImage, x++, h, colors[(srcval >> 1) & 1] );
1603 XPutPixel( bmpImage, x++, h, colors[ srcval & 1] );
1606 switch (dstwidth & 7)
1608 case 7: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1609 case 6: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1610 case 5: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1611 case 4: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1612 case 3: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1613 case 2: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]); srcval<<=1;
1614 case 1: XPutPixel(bmpImage, x++, h, colors[srcval >> 7]);
1616 srcbits += linebytes;
1620 /***********************************************************************
1621 * X11DRV_DIB_GetImageBits_1
1623 * GetDIBits for a 1-bit deep DIB.
1625 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
1626 DWORD dstwidth, DWORD srcwidth,
1627 RGBQUAD *colors, PALETTEENTRY *srccolors,
1628 XImage *bmpImage, DWORD linebytes )
1635 dstbits = dstbits + linebytes * (lines - 1);
1636 linebytes = -linebytes;
1639 switch (bmpImage->depth)
1643 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1644 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
1647 for (h=lines-1; h>=0; h--) {
1651 for (x=0; x<dstwidth; x++) {
1652 PALETTEENTRY srcval;
1653 srcval=srccolors[XGetPixel(bmpImage, x, h)];
1654 dstval|=(X11DRV_DIB_GetNearestIndex
1658 srcval.peBlue) << (7 - (x & 7)));
1664 if ((dstwidth&7)!=0) {
1667 dstbits += linebytes;
1675 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
1676 /* ==== pal 8 bmp -> pal 1 dib ==== */
1677 const void* srcbits;
1678 const BYTE* srcpixel;
1681 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1683 for (h=0; h<lines; h++) {
1688 for (x=0; x<dstwidth; x++) {
1689 PALETTEENTRY srcval;
1690 srcval=srccolors[(int)*srcpixel++];
1691 dstval|=(X11DRV_DIB_GetNearestIndex
1695 srcval.peBlue) << (7-(x&7)) );
1701 if ((dstwidth&7)!=0) {
1704 srcbits -= bmpImage->bytes_per_line;
1705 dstbits += linebytes;
1715 const void* srcbits;
1716 const WORD* srcpixel;
1719 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1721 if (bmpImage->green_mask==0x03e0) {
1722 if (bmpImage->red_mask==0x7c00) {
1723 /* ==== rgb 555 bmp -> pal 1 dib ==== */
1724 for (h=0; h<lines; h++) {
1729 for (x=0; x<dstwidth; x++) {
1732 dstval|=(X11DRV_DIB_GetNearestIndex
1734 ((srcval >> 7) & 0xf8) | /* r */
1735 ((srcval >> 12) & 0x07),
1736 ((srcval >> 2) & 0xf8) | /* g */
1737 ((srcval >> 7) & 0x07),
1738 ((srcval << 3) & 0xf8) | /* b */
1739 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
1745 if ((dstwidth&7)!=0) {
1748 srcbits -= bmpImage->bytes_per_line;
1749 dstbits += linebytes;
1751 } else if (bmpImage->blue_mask==0x7c00) {
1752 /* ==== bgr 555 bmp -> pal 1 dib ==== */
1753 for (h=0; h<lines; h++) {
1758 for (x=0; x<dstwidth; x++) {
1761 dstval|=(X11DRV_DIB_GetNearestIndex
1763 ((srcval << 3) & 0xf8) | /* r */
1764 ((srcval >> 2) & 0x07),
1765 ((srcval >> 2) & 0xf8) | /* g */
1766 ((srcval >> 7) & 0x07),
1767 ((srcval >> 7) & 0xf8) | /* b */
1768 ((srcval >> 12) & 0x07) ) << (7-(x&7)) );
1774 if ((dstwidth&7)!=0) {
1777 srcbits -= bmpImage->bytes_per_line;
1778 dstbits += linebytes;
1783 } else if (bmpImage->green_mask==0x07e0) {
1784 if (bmpImage->red_mask==0xf800) {
1785 /* ==== rgb 565 bmp -> pal 1 dib ==== */
1786 for (h=0; h<lines; h++) {
1791 for (x=0; x<dstwidth; x++) {
1794 dstval|=(X11DRV_DIB_GetNearestIndex
1796 ((srcval >> 8) & 0xf8) | /* r */
1797 ((srcval >> 13) & 0x07),
1798 ((srcval >> 3) & 0xfc) | /* g */
1799 ((srcval >> 9) & 0x03),
1800 ((srcval << 3) & 0xf8) | /* b */
1801 ((srcval >> 2) & 0x07) ) << (7-(x&7)) );
1807 if ((dstwidth&7)!=0) {
1810 srcbits -= bmpImage->bytes_per_line;
1811 dstbits += linebytes;
1813 } else if (bmpImage->blue_mask==0xf800) {
1814 /* ==== bgr 565 bmp -> pal 1 dib ==== */
1815 for (h=0; h<lines; h++) {
1820 for (x=0; x<dstwidth; x++) {
1823 dstval|=(X11DRV_DIB_GetNearestIndex
1825 ((srcval << 3) & 0xf8) | /* r */
1826 ((srcval >> 2) & 0x07),
1827 ((srcval >> 3) & 0xfc) | /* g */
1828 ((srcval >> 9) & 0x03),
1829 ((srcval >> 8) & 0xf8) | /* b */
1830 ((srcval >> 13) & 0x07) ) << (7-(x&7)) );
1836 if ((dstwidth&7)!=0) {
1839 srcbits -= bmpImage->bytes_per_line;
1840 dstbits += linebytes;
1854 const void* srcbits;
1855 const BYTE *srcbyte;
1857 int bytes_per_pixel;
1859 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
1860 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
1862 if (bmpImage->green_mask!=0x00ff00 ||
1863 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
1865 } else if (bmpImage->blue_mask==0xff) {
1866 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
1867 for (h=0; h<lines; h++) {
1872 for (x=0; x<dstwidth; x++) {
1873 dstval|=(X11DRV_DIB_GetNearestIndex
1877 srcbyte[0]) << (7-(x&7)) );
1878 srcbyte+=bytes_per_pixel;
1884 if ((dstwidth&7)!=0) {
1887 srcbits -= bmpImage->bytes_per_line;
1888 dstbits += linebytes;
1891 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
1892 for (h=0; h<lines; h++) {
1897 for (x=0; x<dstwidth; x++) {
1898 dstval|=(X11DRV_DIB_GetNearestIndex
1902 srcbyte[2]) << (7-(x&7)) );
1903 srcbyte+=bytes_per_pixel;
1909 if ((dstwidth&7)!=0) {
1912 srcbits -= bmpImage->bytes_per_line;
1913 dstbits += linebytes;
1923 unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
1925 /* ==== any bmp format -> pal 1 dib ==== */
1926 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
1927 bmpImage->bits_per_pixel, bmpImage->red_mask,
1928 bmpImage->green_mask, bmpImage->blue_mask );
1930 for (h=lines-1; h>=0; h--) {
1934 for (x=0; x<dstwidth; x++) {
1935 dstval|=(XGetPixel( bmpImage, x, h) >= white) << (7 - (x&7));
1941 if ((dstwidth&7)!=0) {
1944 dstbits += linebytes;
1951 /***********************************************************************
1952 * X11DRV_DIB_SetImageBits_4
1954 * SetDIBits for a 4-bit deep DIB.
1956 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
1957 DWORD srcwidth, DWORD dstwidth, int left,
1958 int *colors, XImage *bmpImage, DWORD linebytes)
1961 const BYTE* srcbyte;
1966 srcbits = srcbits + linebytes * (lines - 1);
1967 linebytes = -linebytes;
1974 srcbits += left >> 1;
1976 /* ==== pal 4 dib -> any bmp format ==== */
1977 for (h = lines-1; h >= 0; h--) {
1979 for (i = dstwidth/2, x = left; i > 0; i--) {
1980 BYTE srcval=*srcbyte++;
1981 XPutPixel( bmpImage, x++, h, colors[srcval >> 4] );
1982 XPutPixel( bmpImage, x++, h, colors[srcval & 0x0f] );
1985 XPutPixel( bmpImage, x, h, colors[*srcbyte >> 4] );
1986 srcbits += linebytes;
1992 /***********************************************************************
1993 * X11DRV_DIB_GetImageBits_4
1995 * GetDIBits for a 4-bit deep DIB.
1997 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
1998 DWORD srcwidth, DWORD dstwidth,
1999 RGBQUAD *colors, PALETTEENTRY *srccolors,
2000 XImage *bmpImage, DWORD linebytes )
2009 dstbits = dstbits + ( linebytes * (lines-1) );
2010 linebytes = -linebytes;
2015 switch (bmpImage->depth) {
2018 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2019 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
2022 for (h = lines-1; h >= 0; h--) {
2026 for (x = 0; x < dstwidth; x++) {
2027 PALETTEENTRY srcval;
2028 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2029 dstval|=(X11DRV_DIB_GetNearestIndex
2033 srcval.peBlue) << (4-((x&1)<<2)));
2039 if ((dstwidth&1)!=0) {
2042 dstbits += linebytes;
2050 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2051 /* ==== pal 8 bmp -> pal 4 dib ==== */
2052 const void* srcbits;
2053 const BYTE *srcpixel;
2056 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2057 for (h=0; h<lines; h++) {
2062 for (x=0; x<dstwidth; x++) {
2063 PALETTEENTRY srcval;
2064 srcval = srccolors[(int)*srcpixel++];
2065 dstval|=(X11DRV_DIB_GetNearestIndex
2069 srcval.peBlue) << (4*(1-(x&1))) );
2075 if ((dstwidth&1)!=0) {
2078 srcbits -= bmpImage->bytes_per_line;
2079 dstbits += linebytes;
2089 const void* srcbits;
2090 const WORD* srcpixel;
2093 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2095 if (bmpImage->green_mask==0x03e0) {
2096 if (bmpImage->red_mask==0x7c00) {
2097 /* ==== rgb 555 bmp -> pal 4 dib ==== */
2098 for (h=0; h<lines; h++) {
2103 for (x=0; x<dstwidth; x++) {
2106 dstval|=(X11DRV_DIB_GetNearestIndex
2108 ((srcval >> 7) & 0xf8) | /* r */
2109 ((srcval >> 12) & 0x07),
2110 ((srcval >> 2) & 0xf8) | /* g */
2111 ((srcval >> 7) & 0x07),
2112 ((srcval << 3) & 0xf8) | /* b */
2113 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
2119 if ((dstwidth&1)!=0) {
2122 srcbits -= bmpImage->bytes_per_line;
2123 dstbits += linebytes;
2125 } else if (bmpImage->blue_mask==0x7c00) {
2126 /* ==== bgr 555 bmp -> pal 4 dib ==== */
2127 for (h=0; h<lines; h++) {
2132 for (x=0; x<dstwidth; x++) {
2135 dstval|=(X11DRV_DIB_GetNearestIndex
2137 ((srcval << 3) & 0xf8) | /* r */
2138 ((srcval >> 2) & 0x07),
2139 ((srcval >> 2) & 0xf8) | /* g */
2140 ((srcval >> 7) & 0x07),
2141 ((srcval >> 7) & 0xf8) | /* b */
2142 ((srcval >> 12) & 0x07) ) << ((1-(x&1))<<2) );
2148 if ((dstwidth&1)!=0) {
2151 srcbits -= bmpImage->bytes_per_line;
2152 dstbits += linebytes;
2157 } else if (bmpImage->green_mask==0x07e0) {
2158 if (bmpImage->red_mask==0xf800) {
2159 /* ==== rgb 565 bmp -> pal 4 dib ==== */
2160 for (h=0; h<lines; h++) {
2165 for (x=0; x<dstwidth; x++) {
2168 dstval|=(X11DRV_DIB_GetNearestIndex
2170 ((srcval >> 8) & 0xf8) | /* r */
2171 ((srcval >> 13) & 0x07),
2172 ((srcval >> 3) & 0xfc) | /* g */
2173 ((srcval >> 9) & 0x03),
2174 ((srcval << 3) & 0xf8) | /* b */
2175 ((srcval >> 2) & 0x07) ) << ((1-(x&1))<<2) );
2181 if ((dstwidth&1)!=0) {
2184 srcbits -= bmpImage->bytes_per_line;
2185 dstbits += linebytes;
2187 } else if (bmpImage->blue_mask==0xf800) {
2188 /* ==== bgr 565 bmp -> pal 4 dib ==== */
2189 for (h=0; h<lines; h++) {
2194 for (x=0; x<dstwidth; x++) {
2197 dstval|=(X11DRV_DIB_GetNearestIndex
2199 ((srcval << 3) & 0xf8) | /* r */
2200 ((srcval >> 2) & 0x07),
2201 ((srcval >> 3) & 0xfc) | /* g */
2202 ((srcval >> 9) & 0x03),
2203 ((srcval >> 8) & 0xf8) | /* b */
2204 ((srcval >> 13) & 0x07) ) << ((1-(x&1))<<2) );
2210 if ((dstwidth&1)!=0) {
2213 srcbits -= bmpImage->bytes_per_line;
2214 dstbits += linebytes;
2226 if (bmpImage->bits_per_pixel==24) {
2227 const void* srcbits;
2228 const BYTE *srcbyte;
2231 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2233 if (bmpImage->green_mask!=0x00ff00 ||
2234 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2236 } else if (bmpImage->blue_mask==0xff) {
2237 /* ==== rgb 888 bmp -> pal 4 dib ==== */
2238 for (h=0; h<lines; h++) {
2241 for (x=0; x<dstwidth/2; x++) {
2242 /* Do 2 pixels at a time */
2243 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2248 X11DRV_DIB_GetNearestIndex
2256 /* And the the odd pixel */
2257 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2263 srcbits -= bmpImage->bytes_per_line;
2264 dstbits += linebytes;
2267 /* ==== bgr 888 bmp -> pal 4 dib ==== */
2268 for (h=0; h<lines; h++) {
2271 for (x=0; x<dstwidth/2; x++) {
2272 /* Do 2 pixels at a time */
2273 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2278 X11DRV_DIB_GetNearestIndex
2286 /* And the the odd pixel */
2287 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2293 srcbits -= bmpImage->bytes_per_line;
2294 dstbits += linebytes;
2303 const void* srcbits;
2304 const BYTE *srcbyte;
2307 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2309 if (bmpImage->green_mask!=0x00ff00 ||
2310 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2312 } else if (bmpImage->blue_mask==0xff) {
2313 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
2314 for (h=0; h<lines; h++) {
2317 for (x=0; x<dstwidth/2; x++) {
2318 /* Do 2 pixels at a time */
2319 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2324 X11DRV_DIB_GetNearestIndex
2332 /* And the the odd pixel */
2333 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2339 srcbits -= bmpImage->bytes_per_line;
2340 dstbits += linebytes;
2343 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
2344 for (h=0; h<lines; h++) {
2347 for (x=0; x<dstwidth/2; x++) {
2348 /* Do 2 pixels at a time */
2349 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2354 X11DRV_DIB_GetNearestIndex
2362 /* And the the odd pixel */
2363 *dstbyte++=(X11DRV_DIB_GetNearestIndex
2369 srcbits -= bmpImage->bytes_per_line;
2370 dstbits += linebytes;
2381 /* ==== any bmp format -> pal 4 dib ==== */
2382 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
2383 bmpImage->bits_per_pixel, bmpImage->red_mask,
2384 bmpImage->green_mask, bmpImage->blue_mask );
2385 for (h=lines-1; h>=0; h--) {
2387 for (x=0; x<(dstwidth & ~1); x+=2) {
2388 *dstbyte++=(X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4) |
2389 X11DRV_DIB_MapColor((int*)colors, 16, XGetPixel(bmpImage, x+1, h), 0);
2392 *dstbyte=(X11DRV_DIB_MapColor((int *)colors, 16, XGetPixel(bmpImage, x, h), 0) << 4);
2394 dstbits += linebytes;
2401 /***********************************************************************
2402 * X11DRV_DIB_SetImageBits_RLE4
2404 * SetDIBits for a 4-bit deep compressed DIB.
2406 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
2407 DWORD width, DWORD dstwidth,
2408 int left, int *colors,
2411 int x = 0, y = lines - 1, c, length;
2412 const BYTE *begin = bits;
2417 if (length) { /* encoded */
2420 if (x >= width) break;
2421 XPutPixel(bmpImage, x++, y, colors[c >> 4]);
2422 if (!length--) break;
2423 if (x >= width) break;
2424 XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
2443 default: /* absolute */
2446 if (x < width) XPutPixel(bmpImage, x++, y, colors[c >> 4]);
2447 if (!length--) break;
2448 if (x < width) XPutPixel(bmpImage, x++, y, colors[c & 0xf]);
2450 if ((bits - begin) & 1)
2459 /***********************************************************************
2460 * X11DRV_DIB_SetImageBits_8
2462 * SetDIBits for an 8-bit deep DIB.
2464 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
2465 DWORD srcwidth, DWORD dstwidth, int left,
2466 const int *colors, XImage *bmpImage,
2471 const BYTE* srcbyte;
2477 srcbits = srcbits + linebytes * (lines-1);
2478 linebytes = -linebytes;
2483 switch (bmpImage->depth) {
2486 #if defined(__i386__) && defined(__GNUC__)
2487 /* Some X servers might have 32 bit/ 16bit deep pixel */
2488 if (lines && dstwidth && (bmpImage->bits_per_pixel == 16))
2490 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2491 /* FIXME: Does this really handle all these cases correctly? */
2492 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
2493 for (h = lines ; h--; ) {
2494 int _cl1,_cl2; /* temp outputs for asm below */
2495 /* Borrowed from DirectDraw */
2496 __asm__ __volatile__(
2501 " movw (%%edx,%%eax,4),%%ax\n"
2503 " xor %%eax,%%eax\n"
2505 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
2510 :"eax", "cc", "memory"
2512 srcbyte = (srcbits += linebytes);
2513 dstbits -= bmpImage->bytes_per_line;
2521 #if defined(__i386__) && defined(__GNUC__)
2522 if (lines && dstwidth && (bmpImage->bits_per_pixel == 32))
2524 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
2525 /* FIXME: Does this really handle both cases correctly? */
2526 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
2527 for (h = lines ; h--; ) {
2528 int _cl1,_cl2; /* temp outputs for asm below */
2529 /* Borrowed from DirectDraw */
2530 __asm__ __volatile__(
2535 " movl (%%edx,%%eax,4),%%eax\n"
2537 " xor %%eax,%%eax\n"
2539 :"=S" (srcbyte), "=D" (_cl1), "=c" (_cl2)
2544 :"eax", "cc", "memory"
2546 srcbyte = (srcbits += linebytes);
2547 dstbits -= bmpImage->bytes_per_line;
2554 break; /* use slow generic case below */
2557 /* ==== pal 8 dib -> any bmp format ==== */
2558 for (h=lines-1; h>=0; h--) {
2559 for (x=left; x<dstwidth+left; x++) {
2560 XPutPixel(bmpImage, x, h, colors[*srcbyte++]);
2562 srcbyte = (srcbits += linebytes);
2566 /***********************************************************************
2567 * X11DRV_DIB_GetImageBits_8
2569 * GetDIBits for an 8-bit deep DIB.
2571 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
2572 DWORD srcwidth, DWORD dstwidth,
2573 RGBQUAD *colors, PALETTEENTRY *srccolors,
2574 XImage *bmpImage, DWORD linebytes )
2583 dstbits = dstbits + ( linebytes * (lines-1) );
2584 linebytes = -linebytes;
2589 * This condition is true when GetImageBits has been called by
2590 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
2591 * 256 colormaps, so we'll just use for for GetDIBits calls.
2592 * (In somes cases, in a updateDIBSection, the returned colors are bad too)
2594 if (!srccolors) goto updatesection;
2596 switch (bmpImage->depth) {
2599 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2601 /* ==== pal 1 bmp -> pal 8 dib ==== */
2602 /* ==== pal 4 bmp -> pal 8 dib ==== */
2603 for (h=lines-1; h>=0; h--) {
2605 for (x=0; x<dstwidth; x++) {
2606 PALETTEENTRY srcval;
2607 srcval=srccolors[XGetPixel(bmpImage, x, h)];
2608 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
2613 dstbits += linebytes;
2621 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
2622 /* ==== pal 8 bmp -> pal 8 dib ==== */
2623 const void* srcbits;
2624 const BYTE* srcpixel;
2626 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2627 for (h=0; h<lines; h++) {
2630 for (x = 0; x < dstwidth; x++) {
2631 PALETTEENTRY srcval;
2632 srcval=srccolors[(int)*srcpixel++];
2633 *dstbyte++=X11DRV_DIB_GetNearestIndex(colors, 256,
2638 srcbits -= bmpImage->bytes_per_line;
2639 dstbits += linebytes;
2649 const void* srcbits;
2650 const WORD* srcpixel;
2653 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2655 if (bmpImage->green_mask==0x03e0) {
2656 if (bmpImage->red_mask==0x7c00) {
2657 /* ==== rgb 555 bmp -> pal 8 dib ==== */
2658 for (h=0; h<lines; h++) {
2661 for (x=0; x<dstwidth; x++) {
2664 *dstbyte++=X11DRV_DIB_GetNearestIndex
2666 ((srcval >> 7) & 0xf8) | /* r */
2667 ((srcval >> 12) & 0x07),
2668 ((srcval >> 2) & 0xf8) | /* g */
2669 ((srcval >> 7) & 0x07),
2670 ((srcval << 3) & 0xf8) | /* b */
2671 ((srcval >> 2) & 0x07) );
2673 srcbits -= bmpImage->bytes_per_line;
2674 dstbits += linebytes;
2676 } else if (bmpImage->blue_mask==0x7c00) {
2677 /* ==== bgr 555 bmp -> pal 8 dib ==== */
2678 for (h=0; h<lines; h++) {
2681 for (x=0; x<dstwidth; x++) {
2684 *dstbyte++=X11DRV_DIB_GetNearestIndex
2686 ((srcval << 3) & 0xf8) | /* r */
2687 ((srcval >> 2) & 0x07),
2688 ((srcval >> 2) & 0xf8) | /* g */
2689 ((srcval >> 7) & 0x07),
2690 ((srcval >> 7) & 0xf8) | /* b */
2691 ((srcval >> 12) & 0x07) );
2693 srcbits -= bmpImage->bytes_per_line;
2694 dstbits += linebytes;
2699 } else if (bmpImage->green_mask==0x07e0) {
2700 if (bmpImage->red_mask==0xf800) {
2701 /* ==== rgb 565 bmp -> pal 8 dib ==== */
2702 for (h=0; h<lines; h++) {
2705 for (x=0; x<dstwidth; x++) {
2708 *dstbyte++=X11DRV_DIB_GetNearestIndex
2710 ((srcval >> 8) & 0xf8) | /* r */
2711 ((srcval >> 13) & 0x07),
2712 ((srcval >> 3) & 0xfc) | /* g */
2713 ((srcval >> 9) & 0x03),
2714 ((srcval << 3) & 0xf8) | /* b */
2715 ((srcval >> 2) & 0x07) );
2717 srcbits -= bmpImage->bytes_per_line;
2718 dstbits += linebytes;
2720 } else if (bmpImage->blue_mask==0xf800) {
2721 /* ==== bgr 565 bmp -> pal 8 dib ==== */
2722 for (h=0; h<lines; h++) {
2725 for (x=0; x<dstwidth; x++) {
2728 *dstbyte++=X11DRV_DIB_GetNearestIndex
2730 ((srcval << 3) & 0xf8) | /* r */
2731 ((srcval >> 2) & 0x07),
2732 ((srcval >> 3) & 0xfc) | /* g */
2733 ((srcval >> 9) & 0x03),
2734 ((srcval >> 8) & 0xf8) | /* b */
2735 ((srcval >> 13) & 0x07) );
2737 srcbits -= bmpImage->bytes_per_line;
2738 dstbits += linebytes;
2752 const void* srcbits;
2753 const BYTE *srcbyte;
2755 int bytes_per_pixel;
2757 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
2758 bytes_per_pixel=(bmpImage->bits_per_pixel==24?3:4);
2760 if (bmpImage->green_mask!=0x00ff00 ||
2761 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
2763 } else if (bmpImage->blue_mask==0xff) {
2764 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
2765 for (h=0; h<lines; h++) {
2768 for (x=0; x<dstwidth; x++) {
2769 *dstbyte++=X11DRV_DIB_GetNearestIndex
2774 srcbyte+=bytes_per_pixel;
2776 srcbits -= bmpImage->bytes_per_line;
2777 dstbits += linebytes;
2780 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
2781 for (h=0; h<lines; h++) {
2784 for (x=0; x<dstwidth; x++) {
2785 *dstbyte++=X11DRV_DIB_GetNearestIndex
2790 srcbyte+=bytes_per_pixel;
2792 srcbits -= bmpImage->bytes_per_line;
2793 dstbits += linebytes;
2801 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
2802 bmpImage->depth, bmpImage->red_mask,
2803 bmpImage->green_mask, bmpImage->blue_mask );
2805 /* ==== any bmp format -> pal 8 dib ==== */
2806 for (h=lines-1; h>=0; h--) {
2808 for (x=0; x<dstwidth; x++) {
2809 *dstbyte=X11DRV_DIB_MapColor
2811 XGetPixel(bmpImage, x, h), *dstbyte);
2814 dstbits += linebytes;
2820 /***********************************************************************
2821 * X11DRV_DIB_SetImageBits_RLE8
2823 * SetDIBits for an 8-bit deep compressed DIB.
2825 * This function rewritten 941113 by James Youngman. WINE blew out when I
2826 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
2828 * This was because the algorithm assumed that all RLE8 bitmaps end with the
2829 * 'End of bitmap' escape code. This code is very much laxer in what it
2830 * allows to end the expansion. Possibly too lax. See the note by
2831 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
2832 * bitmap should end with RleEnd, but on the other hand, software exists
2833 * that produces ones that don't and Windows 3.1 doesn't complain a bit
2836 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
2837 * James A. Youngman <mbcstjy@afs.man.ac.uk>
2840 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
2841 DWORD width, DWORD dstwidth,
2842 int left, int *colors,
2845 int x; /* X-positon on each line. Increases. */
2846 int y; /* Line #. Starts at lines-1, decreases */
2847 const BYTE *pIn = bits; /* Pointer to current position in bits */
2848 BYTE length; /* The length pf a run */
2849 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
2852 * Note that the bitmap data is stored by Windows starting at the
2853 * bottom line of the bitmap and going upwards. Within each line,
2854 * the data is stored left-to-right. That's the reason why line
2855 * goes from lines-1 to 0. [JAY]
2865 * If the length byte is not zero (which is the escape value),
2866 * We have a run of length pixels all the same colour. The colour
2867 * index is stored next.
2869 * If the length byte is zero, we need to read the next byte to
2870 * know what to do. [JAY]
2875 * [Run-Length] Encoded mode
2877 int color = colors[*pIn++];
2878 while (length-- && x < dstwidth) XPutPixel(bmpImage, x++, y, color);
2883 * Escape codes (may be an absolute sequence though)
2885 escape_code = (*pIn++);
2894 /* Not all RLE8 bitmaps end with this code. For
2895 * example, Paint Shop Pro produces some that don't.
2896 * That's (I think) what caused the previous
2897 * implementation to fail. [JAY]
2906 default: /* switch to absolute mode */
2907 length = escape_code;
2910 int color = colors[*pIn++];
2916 XPutPixel(bmpImage, x++, y, color);
2919 * If you think for a moment you'll realise that the
2920 * only time we could ever possibly read an odd
2921 * number of bytes is when there is a 0x00 (escape),
2922 * a value >0x02 (absolute mode) and then an odd-
2923 * length run. Therefore this is the only place we
2924 * need to worry about it. Everywhere else the
2925 * bytes are always read in pairs. [JAY]
2927 if (escape_code & 1) pIn++; /* Throw away the pad byte. */
2929 } /* switch (escape_code) : Escape sequence */
2935 /***********************************************************************
2936 * X11DRV_DIB_SetImageBits_16
2938 * SetDIBits for a 16-bit deep DIB.
2940 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
2941 DWORD srcwidth, DWORD dstwidth, int left,
2942 DC *dc, DWORD rSrc, DWORD gSrc, DWORD bSrc,
2943 XImage *bmpImage, DWORD linebytes )
2951 srcbits = srcbits + ( linebytes * (lines-1));
2952 linebytes = -linebytes;
2955 switch (bmpImage->depth)
2962 srcbits=srcbits+left*2;
2963 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
2965 if (bmpImage->green_mask==0x03e0) {
2966 if (gSrc==bmpImage->green_mask) {
2967 if (rSrc==bmpImage->red_mask) {
2968 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
2969 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
2970 X11DRV_DIB_Convert_any_asis
2973 dstbits,-bmpImage->bytes_per_line);
2974 } else if (rSrc==bmpImage->blue_mask) {
2975 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
2976 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
2977 X11DRV_DIB_Convert_555_reverse
2980 dstbits,-bmpImage->bytes_per_line);
2983 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
2984 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
2985 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
2986 X11DRV_DIB_Convert_565_to_555_asis
2989 dstbits,-bmpImage->bytes_per_line);
2991 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
2992 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
2993 X11DRV_DIB_Convert_565_to_555_reverse
2996 dstbits,-bmpImage->bytes_per_line);
2999 } else if (bmpImage->green_mask==0x07e0) {
3000 if (gSrc==bmpImage->green_mask) {
3001 if (rSrc==bmpImage->red_mask) {
3002 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
3003 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
3004 X11DRV_DIB_Convert_any_asis
3007 dstbits,-bmpImage->bytes_per_line);
3009 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
3010 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
3011 X11DRV_DIB_Convert_565_reverse
3014 dstbits,-bmpImage->bytes_per_line);
3017 if (rSrc==bmpImage->red_mask || bSrc==bmpImage->blue_mask) {
3018 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
3019 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
3020 X11DRV_DIB_Convert_555_to_565_asis
3023 dstbits,-bmpImage->bytes_per_line);
3025 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
3026 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
3027 X11DRV_DIB_Convert_555_to_565_reverse
3030 dstbits,-bmpImage->bytes_per_line);
3040 if (bmpImage->bits_per_pixel==24) {
3043 srcbits=srcbits+left*2;
3044 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
3046 if (bmpImage->green_mask!=0x00ff00 ||
3047 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3049 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
3050 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
3052 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
3053 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
3054 X11DRV_DIB_Convert_555_to_888_asis
3057 dstbits,-bmpImage->bytes_per_line);
3059 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
3060 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
3061 X11DRV_DIB_Convert_565_to_888_asis
3064 dstbits,-bmpImage->bytes_per_line);
3068 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
3069 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
3070 X11DRV_DIB_Convert_555_to_888_reverse
3073 dstbits,-bmpImage->bytes_per_line);
3075 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
3076 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
3077 X11DRV_DIB_Convert_565_to_888_reverse
3080 dstbits,-bmpImage->bytes_per_line);
3091 srcbits=srcbits+left*2;
3092 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
3094 if (bmpImage->green_mask!=0x00ff00 ||
3095 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3097 } else if ((rSrc==0x1f && bmpImage->red_mask==0xff) ||
3098 (bSrc==0x1f && bmpImage->blue_mask==0xff)) {
3100 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
3101 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
3102 X11DRV_DIB_Convert_555_to_0888_asis
3105 dstbits,-bmpImage->bytes_per_line);
3107 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
3108 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
3109 X11DRV_DIB_Convert_565_to_0888_asis
3112 dstbits,-bmpImage->bytes_per_line);
3116 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
3117 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
3118 X11DRV_DIB_Convert_555_to_0888_reverse
3121 dstbits,-bmpImage->bytes_per_line);
3123 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
3124 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
3125 X11DRV_DIB_Convert_565_to_0888_reverse
3128 dstbits,-bmpImage->bytes_per_line);
3136 WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3137 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
3138 bmpImage->green_mask, bmpImage->blue_mask );
3144 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
3145 const WORD* srcpixel;
3146 int rShift1,gShift1,bShift1;
3147 int rShift2,gShift2,bShift2;
3150 /* Set color scaling values */
3151 rShift1=16+X11DRV_DIB_MaskToShift(rSrc)-3;
3152 gShift1=16+X11DRV_DIB_MaskToShift(gSrc)-3;
3153 bShift1=16+X11DRV_DIB_MaskToShift(bSrc)-3;
3158 /* Green has 5 bits, like the others */
3162 /* Green has 6 bits, not 5. Compensate. */
3171 /* We could split it into four separate cases to optimize
3172 * but it is probably not worth it.
3174 for (h=lines-1; h>=0; h--) {
3175 srcpixel=(const WORD*)srcbits;
3176 for (x=left; x<dstwidth+left; x++) {
3178 BYTE red,green,blue;
3179 srcval=*srcpixel++ << 16;
3180 red= ((srcval >> rShift1) & 0xf8) |
3181 ((srcval >> rShift2) & 0x07);
3182 green=((srcval >> gShift1) & gMask1) |
3183 ((srcval >> gShift2) & gMask2);
3184 blue= ((srcval >> bShift1) & 0xf8) |
3185 ((srcval >> bShift2) & 0x07);
3186 XPutPixel(bmpImage, x, h,
3187 X11DRV_PALETTE_ToPhysical
3188 (dc, RGB(red,green,blue)));
3190 srcbits += linebytes;
3198 /***********************************************************************
3199 * X11DRV_DIB_GetImageBits_16
3201 * GetDIBits for an 16-bit deep DIB.
3203 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
3204 DWORD dstwidth, DWORD srcwidth,
3205 PALETTEENTRY *srccolors,
3206 DWORD rDst, DWORD gDst, DWORD bDst,
3207 XImage *bmpImage, DWORD dibpitch )
3212 DWORD linebytes = dibpitch;
3217 dstbits = dstbits + ( linebytes * (lines-1));
3218 linebytes = -linebytes;
3221 switch (bmpImage->depth)
3226 const char* srcbits;
3228 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3230 if (bmpImage->green_mask==0x03e0) {
3231 if (gDst==bmpImage->green_mask) {
3232 if (rDst==bmpImage->red_mask) {
3233 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
3234 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
3235 X11DRV_DIB_Convert_any_asis
3237 srcbits,-bmpImage->bytes_per_line,
3240 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
3241 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
3242 X11DRV_DIB_Convert_555_reverse
3244 srcbits,-bmpImage->bytes_per_line,
3248 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
3249 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
3250 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
3251 X11DRV_DIB_Convert_555_to_565_asis
3253 srcbits,-bmpImage->bytes_per_line,
3256 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
3257 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
3258 X11DRV_DIB_Convert_555_to_565_reverse
3260 srcbits,-bmpImage->bytes_per_line,
3264 } else if (bmpImage->green_mask==0x07e0) {
3265 if (gDst==bmpImage->green_mask) {
3266 if (rDst == bmpImage->red_mask) {
3267 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
3268 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
3269 X11DRV_DIB_Convert_any_asis
3271 srcbits,-bmpImage->bytes_per_line,
3274 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
3275 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
3276 X11DRV_DIB_Convert_565_reverse
3278 srcbits,-bmpImage->bytes_per_line,
3282 if (rDst==bmpImage->red_mask || bDst==bmpImage->blue_mask) {
3283 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
3284 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
3285 X11DRV_DIB_Convert_565_to_555_asis
3287 srcbits,-bmpImage->bytes_per_line,
3290 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
3291 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
3292 X11DRV_DIB_Convert_565_to_555_reverse
3294 srcbits,-bmpImage->bytes_per_line,
3305 if (bmpImage->bits_per_pixel == 24) {
3306 const char* srcbits;
3308 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3310 if (bmpImage->green_mask!=0x00ff00 ||
3311 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3313 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
3314 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
3316 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
3317 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
3318 X11DRV_DIB_Convert_888_to_555_asis
3320 srcbits,-bmpImage->bytes_per_line,
3323 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
3324 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
3325 X11DRV_DIB_Convert_888_to_565_asis
3327 srcbits,-bmpImage->bytes_per_line,
3332 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
3333 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
3334 X11DRV_DIB_Convert_888_to_555_reverse
3336 srcbits,-bmpImage->bytes_per_line,
3339 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
3340 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
3341 X11DRV_DIB_Convert_888_to_565_reverse
3343 srcbits,-bmpImage->bytes_per_line,
3353 const char* srcbits;
3355 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3357 if (bmpImage->green_mask!=0x00ff00 ||
3358 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3360 } else if ((rDst==0x1f && bmpImage->red_mask==0xff) ||
3361 (bDst==0x1f && bmpImage->blue_mask==0xff)) {
3363 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
3364 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
3365 X11DRV_DIB_Convert_0888_to_555_asis
3367 srcbits,-bmpImage->bytes_per_line,
3370 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
3371 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
3372 X11DRV_DIB_Convert_0888_to_565_asis
3374 srcbits,-bmpImage->bytes_per_line,
3379 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
3380 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
3381 X11DRV_DIB_Convert_0888_to_555_reverse
3383 srcbits,-bmpImage->bytes_per_line,
3386 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
3387 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
3388 X11DRV_DIB_Convert_0888_to_565_reverse
3390 srcbits,-bmpImage->bytes_per_line,
3399 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3400 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
3401 int rShift,gShift,bShift;
3404 /* Shift everything 16 bits left so that all shifts are >0,
3405 * even for BGR DIBs. Then a single >> 16 will bring everything
3408 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
3409 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
3410 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
3412 /* 6 bits for the green */
3418 for (h = lines - 1; h >= 0; h--) {
3419 dstpixel=(LPWORD)dstbits;
3420 for (x = 0; x < dstwidth; x++) {
3421 PALETTEENTRY srcval;
3423 srcval=srccolors[XGetPixel(bmpImage, x, h)];
3424 dstval=((srcval.peRed << rShift) & rDst) |
3425 ((srcval.peGreen << gShift) & gDst) |
3426 ((srcval.peBlue << bShift) & bDst);
3427 *dstpixel++=dstval >> 16;
3429 dstbits += linebytes;
3437 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3438 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
3439 int rShift,gShift,bShift;
3440 const BYTE* srcbits;
3441 const BYTE* srcpixel;
3444 /* Shift everything 16 bits left so that all shifts are >0,
3445 * even for BGR DIBs. Then a single >> 16 will bring everything
3448 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
3449 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
3450 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
3452 /* 6 bits for the green */
3458 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3459 for (h=0; h<lines; h++) {
3461 dstpixel=(LPWORD)dstbits;
3462 for (x = 0; x < dstwidth; x++) {
3463 PALETTEENTRY srcval;
3465 srcval=srccolors[(int)*srcpixel++];
3466 dstval=((srcval.peRed << rShift) & rDst) |
3467 ((srcval.peGreen << gShift) & gDst) |
3468 ((srcval.peBlue << bShift) & bDst);
3469 *dstpixel++=dstval >> 16;
3471 srcbits -= bmpImage->bytes_per_line;
3472 dstbits += linebytes;
3482 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
3483 int rShift,gShift,bShift;
3486 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
3487 bmpImage->depth, bmpImage->red_mask,
3488 bmpImage->green_mask, bmpImage->blue_mask,
3491 /* Shift everything 16 bits left so that all shifts are >0,
3492 * even for BGR DIBs. Then a single >> 16 will bring everything
3495 rShift=16+X11DRV_DIB_MaskToShift(rDst)-3;
3496 gShift=16+X11DRV_DIB_MaskToShift(gDst)-3;
3497 bShift=16+X11DRV_DIB_MaskToShift(bDst)-3;
3499 /* 6 bits for the green */
3505 for (h = lines - 1; h >= 0; h--) {
3506 dstpixel=(LPWORD)dstbits;
3507 for (x = 0; x < dstwidth; x++) {
3510 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
3511 dstval=((GetRValue(srcval) << rShift) & rDst) |
3512 ((GetGValue(srcval) << gShift) & gDst) |
3513 ((GetBValue(srcval) << bShift) & bDst);
3514 *dstpixel++=dstval >> 16;
3516 dstbits += linebytes;
3524 /***********************************************************************
3525 * X11DRV_DIB_SetImageBits_24
3527 * SetDIBits for a 24-bit deep DIB.
3529 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
3530 DWORD srcwidth, DWORD dstwidth, int left,
3532 DWORD rSrc, DWORD gSrc, DWORD bSrc,
3533 XImage *bmpImage, DWORD linebytes )
3541 srcbits = srcbits + linebytes * (lines - 1);
3542 linebytes = -linebytes;
3545 switch (bmpImage->depth)
3548 if (bmpImage->bits_per_pixel==24) {
3551 srcbits=srcbits+left*3;
3552 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
3554 if (bmpImage->green_mask!=0x00ff00 ||
3555 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3557 } else if (rSrc==bmpImage->red_mask) {
3558 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
3559 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
3560 X11DRV_DIB_Convert_any_asis
3563 dstbits,-bmpImage->bytes_per_line);
3565 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
3566 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
3567 X11DRV_DIB_Convert_888_reverse
3570 dstbits,-bmpImage->bytes_per_line);
3580 srcbits=srcbits+left*3;
3581 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
3583 if (bmpImage->green_mask!=0x00ff00 ||
3584 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3586 } else if (rSrc==bmpImage->red_mask) {
3587 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
3588 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
3589 X11DRV_DIB_Convert_888_to_0888_asis
3592 dstbits,-bmpImage->bytes_per_line);
3594 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
3595 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
3596 X11DRV_DIB_Convert_888_to_0888_reverse
3599 dstbits,-bmpImage->bytes_per_line);
3609 srcbits=srcbits+left*3;
3610 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
3612 if (bmpImage->green_mask==0x03e0) {
3613 if ((rSrc==0xff0000 && bmpImage->red_mask==0x7f00) ||
3614 (bSrc==0xff0000 && bmpImage->blue_mask==0x7f00)) {
3615 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
3616 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
3617 X11DRV_DIB_Convert_888_to_555_asis
3620 dstbits,-bmpImage->bytes_per_line);
3621 } else if ((rSrc==0xff && bmpImage->red_mask==0x7f00) ||
3622 (bSrc==0xff && bmpImage->blue_mask==0x7f00)) {
3623 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
3624 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
3625 X11DRV_DIB_Convert_888_to_555_reverse
3628 dstbits,-bmpImage->bytes_per_line);
3632 } else if (bmpImage->green_mask==0x07e0) {
3633 if ((rSrc==0xff0000 && bmpImage->red_mask==0xf800) ||
3634 (bSrc==0xff0000 && bmpImage->blue_mask==0xf800)) {
3635 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
3636 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
3637 X11DRV_DIB_Convert_888_to_565_asis
3640 dstbits,-bmpImage->bytes_per_line);
3641 } else if ((rSrc==0xff && bmpImage->red_mask==0xf800) ||
3642 (bSrc==0xff && bmpImage->blue_mask==0xf800)) {
3643 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
3644 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
3645 X11DRV_DIB_Convert_888_to_565_reverse
3648 dstbits,-bmpImage->bytes_per_line);
3660 WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3661 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
3662 bmpImage->green_mask, bmpImage->blue_mask );
3668 /* ==== rgb 888 dib -> any bmp bormat ==== */
3669 const BYTE* srcbyte;
3671 /* Windows only supports one 24bpp DIB format: RGB888 */
3673 for (h = lines - 1; h >= 0; h--) {
3674 srcbyte=(const BYTE*)srcbits;
3675 for (x = left; x < dstwidth+left; x++) {
3676 XPutPixel(bmpImage, x, h,
3677 X11DRV_PALETTE_ToPhysical
3678 (dc, RGB(srcbyte[2], srcbyte[1], srcbyte[0])));
3681 srcbits += linebytes;
3689 /***********************************************************************
3690 * X11DRV_DIB_GetImageBits_24
3692 * GetDIBits for an 24-bit deep DIB.
3694 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
3695 DWORD dstwidth, DWORD srcwidth,
3696 PALETTEENTRY *srccolors,
3697 DWORD rDst, DWORD gDst, DWORD bDst,
3698 XImage *bmpImage, DWORD linebytes )
3706 dstbits = dstbits + ( linebytes * (lines-1) );
3707 linebytes = -linebytes;
3710 switch (bmpImage->depth)
3713 if (bmpImage->bits_per_pixel==24) {
3714 const char* srcbits;
3716 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3718 if (bmpImage->green_mask!=0x00ff00 ||
3719 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3721 } else if (rDst==bmpImage->red_mask) {
3722 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
3723 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
3724 X11DRV_DIB_Convert_any_asis
3726 srcbits,-bmpImage->bytes_per_line,
3729 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
3730 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
3731 X11DRV_DIB_Convert_888_reverse
3733 srcbits,-bmpImage->bytes_per_line,
3742 const char* srcbits;
3744 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3746 if (bmpImage->green_mask!=0x00ff00 ||
3747 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3749 } else if (rDst==bmpImage->red_mask) {
3750 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3751 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3752 X11DRV_DIB_Convert_0888_to_888_asis
3754 srcbits,-bmpImage->bytes_per_line,
3757 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3758 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3759 X11DRV_DIB_Convert_0888_to_888_reverse
3761 srcbits,-bmpImage->bytes_per_line,
3770 const char* srcbits;
3772 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3774 if (bmpImage->green_mask==0x03e0) {
3775 if ((rDst==0xff0000 && bmpImage->red_mask==0x7f00) ||
3776 (bDst==0xff0000 && bmpImage->blue_mask==0x7f00)) {
3777 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
3778 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
3779 X11DRV_DIB_Convert_555_to_888_asis
3781 srcbits,-bmpImage->bytes_per_line,
3783 } else if ((rDst==0xff && bmpImage->red_mask==0x7f00) ||
3784 (bDst==0xff && bmpImage->blue_mask==0x7f00)) {
3785 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
3786 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
3787 X11DRV_DIB_Convert_555_to_888_reverse
3789 srcbits,-bmpImage->bytes_per_line,
3794 } else if (bmpImage->green_mask==0x07e0) {
3795 if ((rDst==0xff0000 && bmpImage->red_mask==0xf800) ||
3796 (bDst==0xff0000 && bmpImage->blue_mask==0xf800)) {
3797 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
3798 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
3799 X11DRV_DIB_Convert_565_to_888_asis
3801 srcbits,-bmpImage->bytes_per_line,
3803 } else if ((rDst==0xff && bmpImage->red_mask==0xf800) ||
3804 (bDst==0xff && bmpImage->blue_mask==0xf800)) {
3805 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
3806 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
3807 X11DRV_DIB_Convert_565_to_888_reverse
3809 srcbits,-bmpImage->bytes_per_line,
3822 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
3823 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
3826 /* Windows only supports one 24bpp DIB format: rgb 888 */
3827 for (h = lines - 1; h >= 0; h--) {
3829 for (x = 0; x < dstwidth; x++) {
3830 PALETTEENTRY srcval;
3831 srcval=srccolors[XGetPixel(bmpImage, x, h)];
3832 dstbyte[0]=srcval.peBlue;
3833 dstbyte[1]=srcval.peGreen;
3834 dstbyte[2]=srcval.peRed;
3837 dstbits += linebytes;
3845 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors) {
3846 /* ==== pal 8 bmp -> rgb 888 dib ==== */
3847 const void* srcbits;
3848 const BYTE* srcpixel;
3851 /* Windows only supports one 24bpp DIB format: rgb 888 */
3852 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
3853 for (h = lines - 1; h >= 0; h--) {
3856 for (x = 0; x < dstwidth; x++ ) {
3857 PALETTEENTRY srcval;
3858 srcval=srccolors[(int)*srcpixel++];
3859 dstbyte[0]=srcval.peBlue;
3860 dstbyte[1]=srcval.peGreen;
3861 dstbyte[2]=srcval.peRed;
3864 srcbits -= bmpImage->bytes_per_line;
3865 dstbits += linebytes;
3875 /* ==== any bmp format -> 888 dib ==== */
3878 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
3879 bmpImage->depth, bmpImage->red_mask,
3880 bmpImage->green_mask, bmpImage->blue_mask,
3883 /* Windows only supports one 24bpp DIB format: rgb 888 */
3884 for (h = lines - 1; h >= 0; h--) {
3886 for (x = 0; x < dstwidth; x++) {
3887 COLORREF srcval=X11DRV_PALETTE_ToLogical
3888 (XGetPixel( bmpImage, x, h ));
3889 dstbyte[0]=GetBValue(srcval);
3890 dstbyte[1]=GetGValue(srcval);
3891 dstbyte[2]=GetRValue(srcval);
3894 dstbits += linebytes;
3902 /***********************************************************************
3903 * X11DRV_DIB_SetImageBits_32
3905 * SetDIBits for a 32-bit deep DIB.
3907 static void X11DRV_DIB_SetImageBits_32(int lines, const BYTE *srcbits,
3908 DWORD srcwidth, DWORD dstwidth, int left,
3910 DWORD rSrc, DWORD gSrc, DWORD bSrc,
3920 srcbits = srcbits + ( linebytes * (lines-1) );
3921 linebytes = -linebytes;
3924 ptr = (DWORD *) srcbits + left;
3926 switch (bmpImage->depth)
3929 if (bmpImage->bits_per_pixel==24) {
3932 srcbits=srcbits+left*4;
3933 dstbits=bmpImage->data+left*3+(lines-1)*bmpImage->bytes_per_line;
3935 if (rSrc==bmpImage->red_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->blue_mask) {
3936 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
3937 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
3938 X11DRV_DIB_Convert_0888_to_888_asis
3941 dstbits,-bmpImage->bytes_per_line);
3942 } else if (bmpImage->green_mask!=0x00ff00 ||
3943 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3945 /* the tests below assume sane bmpImage masks */
3946 } else if (rSrc==bmpImage->blue_mask && gSrc==bmpImage->green_mask && bSrc==bmpImage->red_mask) {
3947 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
3948 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
3949 X11DRV_DIB_Convert_0888_to_888_reverse
3952 dstbits,-bmpImage->bytes_per_line);
3953 } else if (bmpImage->blue_mask==0xff) {
3954 /* ==== any 0888 dib -> rgb 888 bmp ==== */
3955 X11DRV_DIB_Convert_any0888_to_rgb888
3959 dstbits,-bmpImage->bytes_per_line);
3961 /* ==== any 0888 dib -> bgr 888 bmp ==== */
3962 X11DRV_DIB_Convert_any0888_to_bgr888
3966 dstbits,-bmpImage->bytes_per_line);
3976 srcbits=srcbits+left*4;
3977 dstbits=bmpImage->data+left*4+(lines-1)*bmpImage->bytes_per_line;
3979 if (gSrc==bmpImage->green_mask) {
3980 if (rSrc==bmpImage->red_mask && bSrc==bmpImage->blue_mask) {
3981 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
3982 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
3983 X11DRV_DIB_Convert_any_asis
3986 dstbits,-bmpImage->bytes_per_line);
3987 } else if (bmpImage->green_mask!=0x00ff00 ||
3988 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
3990 /* the tests below assume sane bmpImage masks */
3991 } else if (rSrc==bmpImage->blue_mask && bSrc==bmpImage->red_mask) {
3992 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
3993 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
3994 X11DRV_DIB_Convert_0888_reverse
3997 dstbits,-bmpImage->bytes_per_line);
3999 /* ==== any 0888 dib -> any 0888 bmp ==== */
4000 X11DRV_DIB_Convert_0888_any
4004 dstbits,-bmpImage->bytes_per_line,
4005 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4007 } else if (bmpImage->green_mask!=0x00ff00 ||
4008 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4010 /* the tests below assume sane bmpImage masks */
4012 /* ==== any 0888 dib -> any 0888 bmp ==== */
4013 X11DRV_DIB_Convert_0888_any
4017 dstbits,-bmpImage->bytes_per_line,
4018 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4028 srcbits=srcbits+left*4;
4029 dstbits=bmpImage->data+left*2+(lines-1)*bmpImage->bytes_per_line;
4031 if (rSrc==0xff0000 && gSrc==0x00ff00 && bSrc==0x0000ff) {
4032 if (bmpImage->green_mask==0x03e0) {
4033 if (bmpImage->red_mask==0x7f00) {
4034 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
4035 X11DRV_DIB_Convert_0888_to_555_asis
4038 dstbits,-bmpImage->bytes_per_line);
4039 } else if (bmpImage->blue_mask==0x7f00) {
4040 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
4041 X11DRV_DIB_Convert_0888_to_555_reverse
4044 dstbits,-bmpImage->bytes_per_line);
4048 } else if (bmpImage->green_mask==0x07e0) {
4049 if (bmpImage->red_mask==0xf800) {
4050 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
4051 X11DRV_DIB_Convert_0888_to_565_asis
4054 dstbits,-bmpImage->bytes_per_line);
4055 } else if (bmpImage->blue_mask==0xf800) {
4056 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
4057 X11DRV_DIB_Convert_0888_to_565_reverse
4060 dstbits,-bmpImage->bytes_per_line);
4067 } else if (rSrc==0x0000ff && gSrc==0x00ff00 && bSrc==0xff0000) {
4068 if (bmpImage->green_mask==0x03e0) {
4069 if (bmpImage->blue_mask==0x7f00) {
4070 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
4071 X11DRV_DIB_Convert_0888_to_555_asis
4074 dstbits,-bmpImage->bytes_per_line);
4075 } else if (bmpImage->red_mask==0x7f00) {
4076 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
4077 X11DRV_DIB_Convert_0888_to_555_reverse
4080 dstbits,-bmpImage->bytes_per_line);
4084 } else if (bmpImage->green_mask==0x07e0) {
4085 if (bmpImage->blue_mask==0xf800) {
4086 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
4087 X11DRV_DIB_Convert_0888_to_565_asis
4090 dstbits,-bmpImage->bytes_per_line);
4091 } else if (bmpImage->red_mask==0xf800) {
4092 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
4093 X11DRV_DIB_Convert_0888_to_565_reverse
4096 dstbits,-bmpImage->bytes_per_line);
4104 if (bmpImage->green_mask==0x03e0 &&
4105 (bmpImage->red_mask==0x7f00 ||
4106 bmpImage->blue_mask==0x7f00)) {
4107 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
4108 X11DRV_DIB_Convert_any0888_to_5x5
4112 dstbits,-bmpImage->bytes_per_line,
4113 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4114 } else if (bmpImage->green_mask==0x07e0 &&
4115 (bmpImage->red_mask==0xf800 ||
4116 bmpImage->blue_mask==0xf800)) {
4117 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
4118 X11DRV_DIB_Convert_any0888_to_5x5
4122 dstbits,-bmpImage->bytes_per_line,
4123 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4133 WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
4134 rSrc, gSrc, bSrc, bmpImage->bits_per_pixel, bmpImage->red_mask,
4135 bmpImage->green_mask, bmpImage->blue_mask );
4141 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
4142 const DWORD* srcpixel;
4143 int rShift,gShift,bShift;
4145 rShift=X11DRV_DIB_MaskToShift(rSrc);
4146 gShift=X11DRV_DIB_MaskToShift(gSrc);
4147 bShift=X11DRV_DIB_MaskToShift(bSrc);
4149 for (h = lines - 1; h >= 0; h--) {
4150 srcpixel=(const DWORD*)srcbits;
4151 for (x = left; x < dstwidth+left; x++) {
4153 BYTE red,green,blue;
4154 srcvalue=*srcpixel++;
4155 red= (srcvalue >> rShift) & 0xff;
4156 green=(srcvalue >> gShift) & 0xff;
4157 blue= (srcvalue >> bShift) & 0xff;
4158 XPutPixel(bmpImage, x, h, X11DRV_PALETTE_ToPhysical
4159 (dc, RGB(red,green,blue)));
4161 srcbits += linebytes;
4169 /***********************************************************************
4170 * X11DRV_DIB_GetImageBits_32
4172 * GetDIBits for an 32-bit deep DIB.
4174 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
4175 DWORD dstwidth, DWORD srcwidth,
4176 PALETTEENTRY *srccolors,
4177 DWORD rDst, DWORD gDst, DWORD bDst,
4178 XImage *bmpImage, DWORD linebytes )
4187 dstbits = dstbits + ( linebytes * (lines-1) );
4188 linebytes = -linebytes;
4193 switch (bmpImage->depth)
4196 if (bmpImage->bits_per_pixel==24) {
4197 const void* srcbits;
4199 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4201 if (rDst==bmpImage->red_mask && gDst==bmpImage->green_mask && bDst==bmpImage->blue_mask) {
4202 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
4203 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
4204 X11DRV_DIB_Convert_888_to_0888_asis
4206 srcbits,-bmpImage->bytes_per_line,
4208 } else if (bmpImage->green_mask!=0x00ff00 ||
4209 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4211 /* the tests below assume sane bmpImage masks */
4212 } else if (rDst==bmpImage->blue_mask && gDst==bmpImage->green_mask && bDst==bmpImage->red_mask) {
4213 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
4214 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
4215 X11DRV_DIB_Convert_888_to_0888_reverse
4217 srcbits,-bmpImage->bytes_per_line,
4219 } else if (bmpImage->blue_mask==0xff) {
4220 /* ==== rgb 888 bmp -> any 0888 dib ==== */
4221 X11DRV_DIB_Convert_rgb888_to_any0888
4223 srcbits,-bmpImage->bytes_per_line,
4227 /* ==== bgr 888 bmp -> any 0888 dib ==== */
4228 X11DRV_DIB_Convert_bgr888_to_any0888
4230 srcbits,-bmpImage->bytes_per_line,
4240 const char* srcbits;
4242 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4244 if (gDst==bmpImage->green_mask) {
4245 if (rDst==bmpImage->red_mask && bDst==bmpImage->blue_mask) {
4246 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
4247 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
4248 X11DRV_DIB_Convert_any_asis
4250 srcbits,-bmpImage->bytes_per_line,
4252 } else if (bmpImage->green_mask!=0x00ff00 ||
4253 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4255 /* the tests below assume sane bmpImage masks */
4256 } else if (rDst==bmpImage->blue_mask && bDst==bmpImage->red_mask) {
4257 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
4258 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
4259 X11DRV_DIB_Convert_0888_reverse
4261 srcbits,-bmpImage->bytes_per_line,
4264 /* ==== any 0888 bmp -> any 0888 dib ==== */
4265 X11DRV_DIB_Convert_0888_any
4267 srcbits,-bmpImage->bytes_per_line,
4268 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4272 } else if (bmpImage->green_mask!=0x00ff00 ||
4273 (bmpImage->red_mask|bmpImage->blue_mask)!=0xff00ff) {
4275 /* the tests below assume sane bmpImage masks */
4277 /* ==== any 0888 bmp -> any 0888 dib ==== */
4278 X11DRV_DIB_Convert_0888_any
4280 srcbits,-bmpImage->bytes_per_line,
4281 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4291 const char* srcbits;
4293 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4295 if (rDst==0xff0000 && gDst==0x00ff00 && bDst==0x0000ff) {
4296 if (bmpImage->green_mask==0x03e0) {
4297 if (bmpImage->red_mask==0x7f00) {
4298 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
4299 X11DRV_DIB_Convert_555_to_0888_asis
4301 srcbits,-bmpImage->bytes_per_line,
4303 } else if (bmpImage->blue_mask==0x7f00) {
4304 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
4305 X11DRV_DIB_Convert_555_to_0888_reverse
4307 srcbits,-bmpImage->bytes_per_line,
4312 } else if (bmpImage->green_mask==0x07e0) {
4313 if (bmpImage->red_mask==0xf800) {
4314 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
4315 X11DRV_DIB_Convert_565_to_0888_asis
4317 srcbits,-bmpImage->bytes_per_line,
4319 } else if (bmpImage->blue_mask==0xf800) {
4320 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
4321 X11DRV_DIB_Convert_565_to_0888_reverse
4323 srcbits,-bmpImage->bytes_per_line,
4331 } else if (rDst==0x0000ff && gDst==0x00ff00 && bDst==0xff0000) {
4332 if (bmpImage->green_mask==0x03e0) {
4333 if (bmpImage->blue_mask==0x7f00) {
4334 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
4335 X11DRV_DIB_Convert_555_to_0888_asis
4337 srcbits,-bmpImage->bytes_per_line,
4339 } else if (bmpImage->red_mask==0x7f00) {
4340 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
4341 X11DRV_DIB_Convert_555_to_0888_reverse
4343 srcbits,-bmpImage->bytes_per_line,
4348 } else if (bmpImage->green_mask==0x07e0) {
4349 if (bmpImage->blue_mask==0xf800) {
4350 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
4351 X11DRV_DIB_Convert_565_to_0888_asis
4353 srcbits,-bmpImage->bytes_per_line,
4355 } else if (bmpImage->red_mask==0xf800) {
4356 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
4357 X11DRV_DIB_Convert_565_to_0888_reverse
4359 srcbits,-bmpImage->bytes_per_line,
4368 if (bmpImage->green_mask==0x03e0 &&
4369 (bmpImage->red_mask==0x7f00 ||
4370 bmpImage->blue_mask==0x7f00)) {
4371 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
4372 X11DRV_DIB_Convert_5x5_to_any0888
4374 srcbits,-bmpImage->bytes_per_line,
4375 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4378 } else if (bmpImage->green_mask==0x07e0 &&
4379 (bmpImage->red_mask==0xf800 ||
4380 bmpImage->blue_mask==0xf800)) {
4381 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
4382 X11DRV_DIB_Convert_5x5_to_any0888
4384 srcbits,-bmpImage->bytes_per_line,
4385 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask,
4397 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
4398 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
4399 int rShift,gShift,bShift;
4402 rShift=X11DRV_DIB_MaskToShift(rDst);
4403 gShift=X11DRV_DIB_MaskToShift(gDst);
4404 bShift=X11DRV_DIB_MaskToShift(bDst);
4405 for (h = lines - 1; h >= 0; h--) {
4406 dstpixel=(DWORD*)dstbits;
4407 for (x = 0; x < dstwidth; x++) {
4408 PALETTEENTRY srcval;
4409 srcval = srccolors[XGetPixel(bmpImage, x, h)];
4410 *dstpixel++=(srcval.peRed << rShift) |
4411 (srcval.peGreen << gShift) |
4412 (srcval.peBlue << bShift);
4414 dstbits += linebytes;
4422 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors) {
4423 /* ==== pal 8 bmp -> any 0888 dib ==== */
4424 int rShift,gShift,bShift;
4425 const void* srcbits;
4426 const BYTE* srcpixel;
4429 rShift=X11DRV_DIB_MaskToShift(rDst);
4430 gShift=X11DRV_DIB_MaskToShift(gDst);
4431 bShift=X11DRV_DIB_MaskToShift(bDst);
4432 srcbits=bmpImage->data+(lines-1)*bmpImage->bytes_per_line;
4433 for (h = lines - 1; h >= 0; h--) {
4435 dstpixel=(DWORD*)dstbits;
4436 for (x = 0; x < dstwidth; x++) {
4437 PALETTEENTRY srcval;
4438 srcval=srccolors[(int)*srcpixel++];
4439 *dstpixel++=(srcval.peRed << rShift) |
4440 (srcval.peGreen << gShift) |
4441 (srcval.peBlue << bShift);
4443 srcbits -= bmpImage->bytes_per_line;
4444 dstbits += linebytes;
4454 /* ==== any bmp format -> any 0888 dib ==== */
4455 int rShift,gShift,bShift;
4458 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
4459 bmpImage->depth, bmpImage->red_mask,
4460 bmpImage->green_mask, bmpImage->blue_mask,
4463 rShift=X11DRV_DIB_MaskToShift(rDst);
4464 gShift=X11DRV_DIB_MaskToShift(gDst);
4465 bShift=X11DRV_DIB_MaskToShift(bDst);
4466 for (h = lines - 1; h >= 0; h--) {
4467 dstpixel=(DWORD*)dstbits;
4468 for (x = 0; x < dstwidth; x++) {
4470 srcval=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage, x, h));
4471 *dstpixel++=(GetRValue(srcval) << rShift) |
4472 (GetGValue(srcval) << gShift) |
4473 (GetBValue(srcval) << bShift);
4475 dstbits += linebytes;
4482 /***********************************************************************
4483 * X11DRV_DIB_SetImageBits
4485 * Transfer the bits to an X image.
4486 * Helper function for SetDIBits() and SetDIBitsToDevice().
4488 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
4490 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
4495 bmpImage = descr->image;
4497 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
4498 descr->infoWidth, lines, 32, 0 );
4499 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
4500 if(bmpImage->data == NULL) {
4501 ERR("Out of memory!\n");
4502 XDestroyImage( bmpImage );
4503 wine_tsx11_unlock();
4508 TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
4509 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
4510 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
4511 bmpImage->depth,bmpImage->bits_per_pixel,
4512 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4514 /* Transfer the pixels */
4515 switch(descr->infoBpp)
4518 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
4519 descr->width, descr->xSrc, (int *)(descr->colorMap),
4520 bmpImage, descr->dibpitch );
4523 if (descr->compression) {
4524 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
4525 descr->width, descr->height, AllPlanes, ZPixmap,
4526 bmpImage, descr->xSrc, descr->ySrc );
4528 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
4529 descr->infoWidth, descr->width,
4530 descr->xSrc, (int *)(descr->colorMap),
4533 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
4534 descr->infoWidth, descr->width,
4535 descr->xSrc, (int*)(descr->colorMap),
4536 bmpImage, descr->dibpitch );
4539 if (descr->compression) {
4540 XGetSubImage( gdi_display, descr->drawable, descr->xDest, descr->yDest,
4541 descr->width, descr->height, AllPlanes, ZPixmap,
4542 bmpImage, descr->xSrc, descr->ySrc );
4543 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
4544 descr->infoWidth, descr->width,
4545 descr->xSrc, (int *)(descr->colorMap),
4548 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
4549 descr->infoWidth, descr->width,
4550 descr->xSrc, (int *)(descr->colorMap),
4551 bmpImage, descr->dibpitch );
4555 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
4556 descr->infoWidth, descr->width,
4557 descr->xSrc, descr->dc,
4558 descr->rMask, descr->gMask, descr->bMask,
4559 bmpImage, descr->dibpitch);
4562 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
4563 descr->infoWidth, descr->width,
4564 descr->xSrc, descr->dc,
4565 descr->rMask, descr->gMask, descr->bMask,
4566 bmpImage, descr->dibpitch);
4569 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
4570 descr->infoWidth, descr->width,
4571 descr->xSrc, descr->dc,
4572 descr->rMask, descr->gMask, descr->bMask,
4573 bmpImage, descr->dibpitch);
4576 WARN("(%d): Invalid depth\n", descr->infoBpp );
4580 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
4581 descr->drawable, descr->gc, bmpImage,
4582 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
4583 descr->width, descr->height);
4584 #ifdef HAVE_LIBXXSHM
4587 XShmPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
4588 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
4589 descr->width, descr->height, FALSE );
4590 XSync( gdi_display, 0 );
4594 XPutImage( gdi_display, descr->drawable, descr->gc, bmpImage,
4595 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
4596 descr->width, descr->height );
4598 if (!descr->image) XDestroyImage( bmpImage );
4599 wine_tsx11_unlock();
4603 /***********************************************************************
4604 * X11DRV_DIB_GetImageBits
4606 * Transfer the bits from an X image.
4608 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
4610 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
4615 bmpImage = descr->image;
4617 bmpImage = XCreateImage( gdi_display, visual, descr->depth, ZPixmap, 0, NULL,
4618 descr->infoWidth, lines, 32, 0 );
4619 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
4620 if(bmpImage->data == NULL) {
4621 ERR("Out of memory!\n");
4622 XDestroyImage( bmpImage );
4623 wine_tsx11_unlock();
4630 int saveRed, saveGreen, saveBlue;
4632 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
4633 gdi_display, descr->drawable, bmpImage,
4634 descr->xSrc, descr->ySrc, AllPlanes);
4636 /* We must save and restore the bmpImage's masks in order
4637 * to preserve them across the call to XShmGetImage, which
4638 * decides to eleminate them since it doesn't happen to know
4639 * what the format of the image is supposed to be, even though
4641 saveRed = bmpImage->red_mask;
4642 saveBlue= bmpImage->blue_mask;
4643 saveGreen = bmpImage->green_mask;
4645 XShmGetImage( gdi_display, descr->drawable, bmpImage,
4646 descr->xSrc, descr->ySrc, AllPlanes);
4648 bmpImage->red_mask = saveRed;
4649 bmpImage->blue_mask = saveBlue;
4650 bmpImage->green_mask = saveGreen;
4654 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
4655 gdi_display, descr->drawable, descr->xSrc, descr->ySrc, descr->width,
4656 lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
4657 XGetSubImage( gdi_display, descr->drawable, descr->xSrc, descr->ySrc,
4658 descr->width, lines, AllPlanes, ZPixmap,
4659 bmpImage, descr->xDest, descr->yDest );
4662 TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
4663 descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
4664 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
4665 bmpImage->depth,bmpImage->bits_per_pixel,
4666 bmpImage->red_mask,bmpImage->green_mask,bmpImage->blue_mask);
4667 /* Transfer the pixels */
4668 switch(descr->infoBpp)
4671 X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
4672 descr->infoWidth, descr->width,
4673 descr->colorMap, descr->palentry,
4674 bmpImage, descr->dibpitch );
4678 if (descr->compression)
4679 FIXME("Compression not yet supported!\n");
4681 X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
4682 descr->infoWidth, descr->width,
4683 descr->colorMap, descr->palentry,
4684 bmpImage, descr->dibpitch );
4688 if (descr->compression)
4689 FIXME("Compression not yet supported!\n");
4691 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
4692 descr->infoWidth, descr->width,
4693 descr->colorMap, descr->palentry,
4694 bmpImage, descr->dibpitch );
4698 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
4699 descr->infoWidth,descr->width,
4701 descr->rMask, descr->gMask, descr->bMask,
4702 bmpImage, descr->dibpitch );
4706 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
4707 descr->infoWidth,descr->width,
4709 descr->rMask, descr->gMask, descr->bMask,
4710 bmpImage, descr->dibpitch);
4714 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
4715 descr->infoWidth, descr->width,
4717 descr->rMask, descr->gMask, descr->bMask,
4718 bmpImage, descr->dibpitch);
4722 WARN("(%d): Invalid depth\n", descr->infoBpp );
4726 if (!descr->image) XDestroyImage( bmpImage );
4727 wine_tsx11_unlock();
4731 /*************************************************************************
4732 * X11DRV_SetDIBitsToDevice
4735 INT X11DRV_SetDIBitsToDevice( DC *dc, INT xDest, INT yDest, DWORD cx,
4736 DWORD cy, INT xSrc, INT ySrc,
4737 UINT startscan, UINT lines, LPCVOID bits,
4738 const BITMAPINFO *info, UINT coloruse )
4740 X11DRV_DIB_IMAGEBITS_DESCR descr;
4741 DWORD width, oldcy = cy;
4743 int height, tmpheight;
4744 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
4747 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
4748 &descr.infoBpp, &descr.compression ) == -1)
4751 if (height < 0) height = -height;
4752 if (!lines || (startscan >= height)) return 0;
4753 if (startscan + lines > height) lines = height - startscan;
4754 if (ySrc < startscan) ySrc = startscan;
4755 else if (ySrc >= startscan + lines) return 0;
4756 if (xSrc >= width) return 0;
4757 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
4758 if (xSrc + cx >= width) cx = width - xSrc;
4759 if (!cx || !cy) return 0;
4761 X11DRV_SetupGCForText( dc ); /* To have the correct colors */
4762 TSXSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[dc->ROPmode-1]);
4764 switch (descr.infoBpp)
4769 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
4770 coloruse == DIB_PAL_COLORS ? dc : NULL, coloruse,
4771 dc->bitsPerPixel, info, &descr.nColorMap );
4772 if (!descr.colorMap) return 0;
4773 descr.rMask = descr.gMask = descr.bMask = 0;
4777 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
4778 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
4779 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
4785 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
4786 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
4787 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
4795 descr.palentry = NULL;
4796 descr.lines = tmpheight >= 0 ? lines : -lines;
4797 descr.infoWidth = width;
4798 descr.depth = dc->bitsPerPixel;
4799 descr.drawable = physDev->drawable;
4800 descr.gc = physDev->gc;
4802 descr.ySrc = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy)
4804 descr.xDest = dc->DCOrgX + XLPTODP( dc, xDest );
4805 descr.yDest = dc->DCOrgY + YLPTODP( dc, yDest ) +
4806 (tmpheight >= 0 ? oldcy-cy : 0);
4809 descr.useShm = FALSE;
4810 descr.dibpitch = ((width * descr.infoBpp + 31) &~31) / 8;
4812 result = X11DRV_DIB_SetImageBits( &descr );
4814 if (descr.infoBpp <= 8)
4815 HeapFree(GetProcessHeap(), 0, descr.colorMap);
4819 /***********************************************************************
4820 * X11DRV_DIB_SetDIBits
4822 INT X11DRV_DIB_SetDIBits(
4823 BITMAPOBJ *bmp, DC *dc, UINT startscan,
4824 UINT lines, LPCVOID bits, const BITMAPINFO *info,
4825 UINT coloruse, HBITMAP hbitmap)
4827 X11DRV_DIB_IMAGEBITS_DESCR descr;
4828 int height, tmpheight;
4833 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
4834 &descr.infoBpp, &descr.compression ) == -1)
4838 if (height < 0) height = -height;
4839 if (!lines || (startscan >= height))
4842 if (startscan + lines > height) lines = height - startscan;
4844 switch (descr.infoBpp)
4849 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
4850 coloruse == DIB_PAL_COLORS ? descr.dc : NULL, coloruse,
4851 bmp->bitmap.bmBitsPixel,
4852 info, &descr.nColorMap );
4853 if (!descr.colorMap) return 0;
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 result = X11DRV_DIB_SetImageBits( &descr );
4896 if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);
4901 /***********************************************************************
4902 * X11DRV_DIB_GetDIBits
4904 INT X11DRV_DIB_GetDIBits(
4905 BITMAPOBJ *bmp, DC *dc, UINT startscan,
4906 UINT lines, LPVOID bits, BITMAPINFO *info,
4907 UINT coloruse, HBITMAP hbitmap)
4909 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
4910 X11DRV_DIB_IMAGEBITS_DESCR descr;
4911 PALETTEOBJ * palette;
4914 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
4915 lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
4916 (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
4919 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC )))
4922 if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
4924 height = info->bmiHeader.biHeight;
4925 if (height < 0) height = -height;
4926 if( lines > height ) lines = height;
4927 /* Top-down images have a negative biHeight, the scanlines of theses images
4928 * were inverted in X11DRV_DIB_GetImageBits_xx
4929 * To prevent this we simply change the sign of lines
4930 * (the number of scan lines to copy).
4931 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
4933 if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
4935 if( startscan >= bmp->bitmap.bmHeight )
4941 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
4942 &descr.infoBpp, &descr.compression ) == -1)
4948 switch (descr.infoBpp)
4953 descr.rMask= descr.gMask = descr.bMask = 0;
4957 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
4958 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
4959 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
4963 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
4964 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
4965 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
4970 if(!bmp->physBitmap)
4971 X11DRV_CreateBitmap(hbitmap);
4975 descr.palentry = palette->logpalette.palPalEntry;
4978 descr.lines = lines;
4979 descr.depth = bmp->bitmap.bmBitsPixel;
4980 descr.drawable = (Pixmap)bmp->physBitmap;
4981 descr.gc = BITMAP_GC(bmp);
4982 descr.width = bmp->bitmap.bmWidth;
4983 descr.height = bmp->bitmap.bmHeight;
4984 descr.colorMap = info->bmiColors;
4989 if (descr.lines > 0)
4991 descr.ySrc = (descr.height-1) - (startscan + (lines-1));
4995 descr.ySrc = startscan;
4997 #ifdef HAVE_LIBXXSHM
4998 descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
5000 descr.useShm = FALSE;
5002 descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
5003 : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
5005 X11DRV_DIB_GetImageBits( &descr );
5007 if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
5008 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
5009 info->bmiHeader.biWidth,
5010 info->bmiHeader.biHeight,
5011 info->bmiHeader.biBitCount );
5013 info->bmiHeader.biCompression = 0;
5014 if (descr.compression == BI_BITFIELDS)
5016 *(DWORD *)info->bmiColors = descr.rMask;
5017 *((DWORD *)info->bmiColors+1) = descr.gMask;
5018 *((DWORD *)info->bmiColors+2) = descr.bMask;
5022 GDI_ReleaseObj( dc->hPalette );
5027 /***********************************************************************
5028 * DIB_DoProtectDIBSection
5030 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
5032 DIBSECTION *dib = bmp->dib;
5033 INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
5034 : -dib->dsBm.bmHeight;
5035 /* use the biSizeImage data as the memory size only if we're dealing with a
5036 compressed image where the value is set. Otherwise, calculate based on
5038 INT totalSize = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
5039 ? dib->dsBmih.biSizeImage
5040 : dib->dsBm.bmWidthBytes * effHeight;
5043 VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
5044 TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
5047 /***********************************************************************
5048 * X11DRV_DIB_DoUpdateDIBSection
5050 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
5051 void *colorMap, int nColorMap,
5053 DWORD xSrc, DWORD ySrc,
5054 DWORD xDest, DWORD yDest,
5055 DWORD width, DWORD height)
5057 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5058 X11DRV_DIB_IMAGEBITS_DESCR descr;
5060 if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
5061 &descr.infoBpp, &descr.compression ) == -1)
5065 descr.palentry = NULL;
5066 descr.image = dib->image;
5067 descr.colorMap = colorMap;
5068 descr.nColorMap = nColorMap;
5069 descr.bits = dib->dibSection.dsBm.bmBits;
5070 descr.depth = bmp->bitmap.bmBitsPixel;
5072 switch (descr.infoBpp)
5077 descr.rMask = descr.gMask = descr.bMask = 0;
5081 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
5082 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
5083 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
5088 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff0000;
5089 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x00ff00;
5090 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x0000ff;
5095 descr.drawable = dest;
5096 descr.gc = BITMAP_GC(bmp);
5099 descr.xDest = xDest;
5100 descr.yDest = yDest;
5101 descr.width = width;
5102 descr.height = height;
5103 #ifdef HAVE_LIBXXSHM
5104 descr.useShm = (dib->shminfo.shmid != -1);
5106 descr.useShm = FALSE;
5108 descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
5112 TRACE("Copying from Pixmap to DIB bits\n");
5113 X11DRV_DIB_GetImageBits( &descr );
5117 TRACE("Copying from DIB bits to Pixmap\n");
5118 X11DRV_DIB_SetImageBits( &descr );
5122 /***********************************************************************
5123 * X11DRV_DIB_CopyDIBSection
5125 void X11DRV_DIB_CopyDIBSection(DC *dcSrc, DC *dcDst,
5126 DWORD xSrc, DWORD ySrc,
5127 DWORD xDest, DWORD yDest,
5128 DWORD width, DWORD height)
5131 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dcDst->physDev;
5132 int nColorMap = 0, *colorMap = NULL, aColorMap = FALSE;
5134 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc, dcDst,
5135 xSrc, ySrc, xDest, yDest, width, height);
5136 /* this function is meant as an optimization for BitBlt,
5137 * not to be called otherwise */
5138 if (!(dcSrc->flags & DC_MEMORY)) {
5139 ERR("called for non-memory source DC!?\n");
5143 bmp = (BITMAPOBJ *)GDI_GetObjPtr( dcSrc->hBitmap, BITMAP_MAGIC );
5144 if (!(bmp && bmp->dib)) {
5145 ERR("called for non-DIBSection!?\n");
5146 GDI_ReleaseObj( dcSrc->hBitmap );
5149 /* while BitBlt should already have made sure we only get
5150 * positive values, we should check for oversize values */
5151 if ((xSrc < bmp->bitmap.bmWidth) &&
5152 (ySrc < bmp->bitmap.bmHeight)) {
5153 if (xSrc + width > bmp->bitmap.bmWidth)
5154 width = bmp->bitmap.bmWidth - xSrc;
5155 if (ySrc + height > bmp->bitmap.bmHeight)
5156 height = bmp->bitmap.bmHeight - ySrc;
5157 /* if the source bitmap is 8bpp or less, we're supposed to use the
5158 * DC's palette for color conversion (not the DIB color table) */
5159 if (bmp->dib->dsBm.bmBitsPixel <= 8) {
5160 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5161 if ((!dcSrc->hPalette) ||
5162 (dcSrc->hPalette == GetStockObject(DEFAULT_PALETTE))) {
5163 /* HACK: no palette has been set in the source DC,
5164 * use the DIB colormap instead - this is necessary in some
5165 * cases since we need to do depth conversion in some places
5166 * where real Windows can just copy data straight over */
5167 colorMap = dib->colorMap;
5168 nColorMap = dib->nColorMap;
5170 colorMap = X11DRV_DIB_BuildColorMap( dcSrc, (WORD)-1,
5171 bmp->dib->dsBm.bmBitsPixel,
5172 (BITMAPINFO*)&(bmp->dib->dsBmih),
5174 if (colorMap) aColorMap = TRUE;
5177 /* perform the copy */
5178 X11DRV_DIB_DoCopyDIBSection(bmp, FALSE, colorMap, nColorMap,
5179 physDev->drawable, xSrc, ySrc, xDest, yDest,
5181 /* free color mapping */
5183 HeapFree(GetProcessHeap(), 0, colorMap);
5185 GDI_ReleaseObj( dcSrc->hBitmap );
5188 /***********************************************************************
5189 * X11DRV_DIB_DoUpdateDIBSection
5191 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
5193 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5194 X11DRV_DIB_DoCopyDIBSection(bmp, toDIB, dib->colorMap, dib->nColorMap,
5195 (Drawable)bmp->physBitmap, 0, 0, 0, 0,
5196 bmp->bitmap.bmWidth, bmp->bitmap.bmHeight);
5199 /***********************************************************************
5200 * X11DRV_DIB_FaultHandler
5202 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
5207 bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
5208 if (!bmp) return FALSE;
5210 state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
5211 if (state != DIB_Status_InSync) {
5212 /* no way to tell whether app needs read or write yet,
5214 X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
5216 /* hm, apparently the app must have write access */
5217 X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
5219 X11DRV_DIB_Unlock(bmp, TRUE);
5221 GDI_ReleaseObj( (HBITMAP)res );
5225 /***********************************************************************
5228 INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
5230 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5231 INT ret = DIB_Status_None;
5234 EnterCriticalSection(&(dib->lock));
5237 case DIB_Status_GdiMod:
5238 /* GDI access - request to draw on pixmap */
5239 switch (dib->status)
5242 case DIB_Status_None:
5243 dib->p_status = DIB_Status_GdiMod;
5244 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
5247 case DIB_Status_GdiMod:
5248 TRACE("GdiMod requested in status GdiMod\n" );
5251 case DIB_Status_InSync:
5252 TRACE("GdiMod requested in status InSync\n" );
5253 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5254 dib->status = DIB_Status_GdiMod;
5255 dib->p_status = DIB_Status_InSync;
5258 case DIB_Status_AuxMod:
5259 TRACE("GdiMod requested in status AuxMod\n" );
5260 if (lossy) dib->status = DIB_Status_GdiMod;
5261 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
5262 dib->p_status = DIB_Status_AuxMod;
5263 if (dib->status != DIB_Status_AppMod) {
5264 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5267 /* fall through if copy_aux() had to change to AppMod state */
5269 case DIB_Status_AppMod:
5270 TRACE("GdiMod requested in status AppMod\n" );
5272 /* make it readonly to avoid app changing data while we copy */
5273 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5274 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
5276 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5277 dib->p_status = DIB_Status_AppMod;
5278 dib->status = DIB_Status_GdiMod;
5283 case DIB_Status_InSync:
5284 /* App access - request access to read DIB surface */
5285 /* (typically called from signal handler) */
5286 switch (dib->status)
5289 case DIB_Status_None:
5290 /* shouldn't happen from signal handler */
5293 case DIB_Status_AuxMod:
5294 TRACE("InSync requested in status AuxMod\n" );
5295 if (lossy) dib->status = DIB_Status_InSync;
5297 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5298 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
5300 if (dib->status != DIB_Status_GdiMod) {
5301 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5304 /* fall through if copy_aux() had to change to GdiMod state */
5306 case DIB_Status_GdiMod:
5307 TRACE("InSync requested in status GdiMod\n" );
5309 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5310 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
5312 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5313 dib->status = DIB_Status_InSync;
5316 case DIB_Status_InSync:
5317 TRACE("InSync requested in status InSync\n" );
5318 /* shouldn't happen from signal handler */
5321 case DIB_Status_AppMod:
5322 TRACE("InSync requested in status AppMod\n" );
5323 /* no reason to do anything here, and this
5324 * shouldn't happen from signal handler */
5329 case DIB_Status_AppMod:
5330 /* App access - request access to write DIB surface */
5331 /* (typically called from signal handler) */
5332 switch (dib->status)
5335 case DIB_Status_None:
5336 /* shouldn't happen from signal handler */
5339 case DIB_Status_AuxMod:
5340 TRACE("AppMod requested in status AuxMod\n" );
5341 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5342 if (lossy) dib->status = DIB_Status_AppMod;
5343 else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
5344 if (dib->status != DIB_Status_GdiMod)
5346 /* fall through if copy_aux() had to change to GdiMod state */
5348 case DIB_Status_GdiMod:
5349 TRACE("AppMod requested in status GdiMod\n" );
5350 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5351 if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
5352 dib->status = DIB_Status_AppMod;
5355 case DIB_Status_InSync:
5356 TRACE("AppMod requested in status InSync\n" );
5357 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5358 dib->status = DIB_Status_AppMod;
5361 case DIB_Status_AppMod:
5362 TRACE("AppMod requested in status AppMod\n" );
5363 /* shouldn't happen from signal handler */
5368 case DIB_Status_AuxMod:
5369 if (dib->status == DIB_Status_None) {
5370 dib->p_status = req;
5372 if (dib->status != DIB_Status_AuxMod)
5373 dib->p_status = dib->status;
5374 dib->status = DIB_Status_AuxMod;
5377 /* it is up to the caller to do the copy/conversion, probably
5378 * using the return value to decide where to copy from */
5380 LeaveCriticalSection(&(dib->lock));
5385 /***********************************************************************
5388 INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
5390 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5391 INT ret = DIB_Status_None;
5394 TRACE("Locking %p from thread %08lx\n", bmp, GetCurrentThreadId());
5395 EnterCriticalSection(&(dib->lock));
5397 if (req != DIB_Status_None)
5398 X11DRV_DIB_Coerce(bmp, req, lossy);
5403 /***********************************************************************
5406 void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
5408 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5411 switch (dib->status)
5414 case DIB_Status_None:
5415 /* in case anyone is wondering, this is the "signal handler doesn't
5416 * work" case, where we always have to be ready for app access */
5418 switch (dib->p_status)
5420 case DIB_Status_AuxMod:
5421 TRACE("Unlocking and syncing from AuxMod\n" );
5422 (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
5423 if (dib->status != DIB_Status_None) {
5424 dib->p_status = dib->status;
5425 dib->status = DIB_Status_None;
5427 if (dib->p_status != DIB_Status_GdiMod)
5429 /* fall through if copy_aux() had to change to GdiMod state */
5431 case DIB_Status_GdiMod:
5432 TRACE("Unlocking and syncing from GdiMod\n" );
5433 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
5437 TRACE("Unlocking without needing to sync\n" );
5441 else TRACE("Unlocking with no changes\n");
5442 dib->p_status = DIB_Status_None;
5445 case DIB_Status_GdiMod:
5446 TRACE("Unlocking in status GdiMod\n" );
5447 /* DIB was protected in Coerce */
5449 /* no commit, revert to InSync if applicable */
5450 if ((dib->p_status == DIB_Status_InSync) ||
5451 (dib->p_status == DIB_Status_AppMod)) {
5452 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5453 dib->status = DIB_Status_InSync;
5458 case DIB_Status_InSync:
5459 TRACE("Unlocking in status InSync\n" );
5460 /* DIB was already protected in Coerce */
5463 case DIB_Status_AppMod:
5464 TRACE("Unlocking in status AppMod\n" );
5465 /* DIB was already protected in Coerce */
5466 /* this case is ordinary only called from the signal handler,
5467 * so we don't bother to check for !commit */
5470 case DIB_Status_AuxMod:
5471 TRACE("Unlocking in status AuxMod\n" );
5473 /* DIB may need protection now */
5474 if ((dib->p_status == DIB_Status_InSync) ||
5475 (dib->p_status == DIB_Status_AppMod))
5476 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
5478 /* no commit, revert to previous state */
5479 if (dib->p_status != DIB_Status_None)
5480 dib->status = dib->p_status;
5481 /* no protections changed */
5483 dib->p_status = DIB_Status_None;
5486 LeaveCriticalSection(&(dib->lock));
5487 TRACE("Unlocked %p\n", bmp);
5491 /***********************************************************************
5492 * X11DRV_CoerceDIBSection2
5494 INT X11DRV_CoerceDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
5499 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5500 if (!bmp) return DIB_Status_None;
5501 ret = X11DRV_DIB_Coerce(bmp, req, lossy);
5502 GDI_ReleaseObj( hBmp );
5506 /***********************************************************************
5507 * X11DRV_LockDIBSection2
5509 INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
5514 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5515 if (!bmp) return DIB_Status_None;
5516 ret = X11DRV_DIB_Lock(bmp, req, lossy);
5517 GDI_ReleaseObj( hBmp );
5521 /***********************************************************************
5522 * X11DRV_UnlockDIBSection2
5524 void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
5528 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5530 X11DRV_DIB_Unlock(bmp, commit);
5531 GDI_ReleaseObj( hBmp );
5534 /***********************************************************************
5535 * X11DRV_CoerceDIBSection
5537 INT X11DRV_CoerceDIBSection(DC *dc, INT req, BOOL lossy)
5539 if (!dc) return DIB_Status_None;
5540 return X11DRV_CoerceDIBSection2( dc->hBitmap, req, lossy );
5543 /***********************************************************************
5544 * X11DRV_LockDIBSection
5546 INT X11DRV_LockDIBSection(DC *dc, INT req, BOOL lossy)
5548 if (!dc) return DIB_Status_None;
5549 if (!(dc->flags & DC_MEMORY)) return DIB_Status_None;
5551 return X11DRV_LockDIBSection2( dc->hBitmap, req, lossy );
5554 /***********************************************************************
5555 * X11DRV_UnlockDIBSection
5557 void X11DRV_UnlockDIBSection(DC *dc, BOOL commit)
5560 if (!(dc->flags & DC_MEMORY)) return;
5562 X11DRV_UnlockDIBSection2( dc->hBitmap, commit );
5566 #ifdef HAVE_LIBXXSHM
5567 /***********************************************************************
5568 * X11DRV_XShmErrorHandler
5571 static int XShmErrorHandler(Display *dpy, XErrorEvent *event)
5577 /***********************************************************************
5578 * X11DRV_XShmCreateImage
5581 static XImage *X11DRV_XShmCreateImage( int width, int height, int bpp,
5582 XShmSegmentInfo* shminfo)
5584 int (*WineXHandler)(Display *, XErrorEvent *);
5588 image = XShmCreateImage(gdi_display, visual, bpp, ZPixmap, NULL, shminfo, width, height);
5591 shminfo->shmid = shmget(IPC_PRIVATE, image->bytes_per_line * height,
5593 if( shminfo->shmid != -1 )
5595 shminfo->shmaddr = image->data = shmat(shminfo->shmid, 0, 0);
5596 if( shminfo->shmaddr != (char*)-1 )
5598 shminfo->readOnly = FALSE;
5599 if( XShmAttach( gdi_display, shminfo ) != 0)
5601 /* Reset the error flag */
5603 WineXHandler = XSetErrorHandler(XShmErrorHandler);
5604 XSync( gdi_display, 0 );
5608 shmctl(shminfo->shmid, IPC_RMID, 0);
5610 XSetErrorHandler(WineXHandler);
5611 wine_tsx11_unlock();
5612 return image; /* Success! */
5614 /* An error occurred */
5616 XSetErrorHandler(WineXHandler);
5618 shmdt(shminfo->shmaddr);
5620 shmctl(shminfo->shmid, IPC_RMID, 0);
5622 XFlush(gdi_display);
5623 XDestroyImage(image);
5626 wine_tsx11_unlock();
5629 #endif /* HAVE_LIBXXSHM */
5632 /***********************************************************************
5633 * X11DRV_DIB_CreateDIBSection
5635 HBITMAP X11DRV_DIB_CreateDIBSection(
5636 DC *dc, BITMAPINFO *bmi, UINT usage,
5637 LPVOID *bits, HANDLE section,
5638 DWORD offset, DWORD ovr_pitch)
5641 BITMAPOBJ *bmp = NULL;
5642 X11DRV_DIBSECTION *dib = NULL;
5643 int *colorMap = NULL;
5646 /* Fill BITMAP32 structure with DIB data */
5647 BITMAPINFOHEADER *bi = &bmi->bmiHeader;
5648 INT effHeight, totalSize;
5650 LPVOID mapBits = NULL;
5652 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
5653 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
5654 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
5656 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
5658 bm.bmWidth = bi->biWidth;
5659 bm.bmHeight = effHeight;
5660 bm.bmWidthBytes = ovr_pitch ? ovr_pitch
5661 : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
5662 bm.bmPlanes = bi->biPlanes;
5663 bm.bmBitsPixel = bi->biBitCount;
5666 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
5667 we're dealing with a compressed bitmap. Otherwise, use width * height. */
5668 totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
5669 ? bi->biSizeImage : bm.bmWidthBytes * effHeight;
5673 SYSTEM_INFO SystemInfo;
5677 GetSystemInfo( &SystemInfo );
5678 mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
5679 mapSize = totalSize + (offset - mapOffset);
5680 mapBits = MapViewOfFile( section,
5681 FILE_MAP_ALL_ACCESS,
5685 bm.bmBits = (char *)mapBits + (offset - mapOffset);
5687 else if (ovr_pitch && offset)
5688 bm.bmBits = (LPVOID) offset;
5691 bm.bmBits = VirtualAlloc(NULL, totalSize,
5692 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
5695 /* Create Color Map */
5696 if (bm.bmBits && bm.bmBitsPixel <= 8)
5697 colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? dc : NULL,
5698 usage, bm.bmBitsPixel, bmi, &nColorMap );
5700 /* Allocate Memory for DIB and fill structure */
5702 dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
5705 dib->dibSection.dsBm = bm;
5706 dib->dibSection.dsBmih = *bi;
5707 dib->dibSection.dsBmih.biSizeImage = totalSize;
5709 /* Set dsBitfields values */
5710 if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
5712 dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
5714 else switch( bi->biBitCount )
5718 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
5719 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
5720 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
5725 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff0000;
5726 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x00ff00;
5727 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x0000ff;
5730 dib->dibSection.dshSection = section;
5731 dib->dibSection.dsOffset = offset;
5733 dib->status = DIB_Status_None;
5734 dib->nColorMap = nColorMap;
5735 dib->colorMap = colorMap;
5738 /* Create Device Dependent Bitmap and add DIB pointer */
5741 res = CreateDIBitmap(dc->hSelf, bi, 0, NULL, bmi, usage);
5744 bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
5747 bmp->dib = (DIBSECTION *) dib;
5749 if(!bmp->physBitmap)
5750 X11DRV_CreateBitmap(res);
5758 #ifdef HAVE_LIBXXSHM
5759 if (TSXShmQueryExtension(gdi_display) &&
5760 (dib->image = X11DRV_XShmCreateImage( bm.bmWidth, effHeight,
5761 bmp->bitmap.bmBitsPixel, &dib->shminfo )) )
5763 ; /* Created Image */
5765 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
5766 dib->shminfo.shmid = -1;
5769 dib->image = X11DRV_DIB_CreateXImage( bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
5773 /* Clean up in case of errors */
5774 if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
5776 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
5777 res, bmp, dib, bm.bmBits);
5781 UnmapViewOfFile(mapBits), bm.bmBits = NULL;
5783 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
5786 if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
5787 if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
5788 if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
5789 if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
5790 if (res) { DeleteObject(res); res = 0; }
5794 /* Install fault handler, if possible */
5795 InitializeCriticalSection(&(dib->lock));
5796 if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
5798 if (section || offset)
5800 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
5801 if (dib) dib->status = DIB_Status_AppMod;
5805 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
5806 if (dib) dib->status = DIB_Status_InSync;
5811 /* Return BITMAP handle and storage location */
5812 if (bmp) GDI_ReleaseObj(res);
5813 if (bm.bmBits && bits) *bits = bm.bmBits;
5817 /***********************************************************************
5818 * X11DRV_DIB_DeleteDIBSection
5820 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
5822 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5826 #ifdef HAVE_LIBXXSHM
5827 if (dib->shminfo.shmid != -1)
5829 TSXShmDetach (gdi_display, &(dib->shminfo));
5830 XDestroyImage (dib->image);
5831 shmdt (dib->shminfo.shmaddr);
5832 dib->shminfo.shmid = -1;
5836 XDestroyImage( dib->image );
5840 HeapFree(GetProcessHeap(), 0, dib->colorMap);
5842 DeleteCriticalSection(&(dib->lock));
5845 /***********************************************************************
5846 * X11DRV_DIB_SetDIBColorTable
5848 UINT X11DRV_DIB_SetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, const RGBQUAD *colors)
5850 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5852 if (dib && dib->colorMap) {
5853 UINT end = count + start;
5854 if (end > dib->nColorMap) end = dib->nColorMap;
5856 * Changing color table might change the mapping between
5857 * DIB colors and X11 colors and thus alter the visible state
5858 * of the bitmap object.
5860 X11DRV_DIB_Lock(bmp, DIB_Status_AppMod, FALSE);
5861 X11DRV_DIB_GenColorMap( dc, dib->colorMap, DIB_RGB_COLORS,
5862 dib->dibSection.dsBm.bmBitsPixel,
5863 TRUE, colors, start, end );
5864 X11DRV_DIB_Unlock(bmp, TRUE);
5870 /***********************************************************************
5871 * X11DRV_DIB_GetDIBColorTable
5873 UINT X11DRV_DIB_GetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, RGBQUAD *colors)
5875 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
5877 if (dib && dib->colorMap) {
5878 UINT i, end = count + start;
5879 if (end > dib->nColorMap) end = dib->nColorMap;
5880 for (i = start; i < end; i++,colors++) {
5881 COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] );
5882 colors->rgbBlue = GetBValue(col);
5883 colors->rgbGreen = GetGValue(col);
5884 colors->rgbRed = GetRValue(col);
5885 colors->rgbReserved = 0;
5893 /**************************************************************************
5894 * X11DRV_DIB_CreateDIBFromPixmap
5896 * Allocates a packed DIB and copies the Pixmap data into it.
5897 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
5899 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
5902 BITMAPOBJ *pBmp = NULL;
5903 HGLOBAL hPackedDIB = 0;
5905 /* Allocates an HBITMAP which references the Pixmap passed to us */
5906 hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap);
5909 TRACE("\tCould not create bitmap header for Pixmap\n");
5914 * Create a packed DIB from the Pixmap wrapper bitmap created above.
5915 * A packed DIB contains a BITMAPINFO structure followed immediately by
5916 * an optional color palette and the pixel data.
5918 hPackedDIB = DIB_CreateDIBFromBitmap(hdc, hBmp);
5920 /* Get a pointer to the BITMAPOBJ structure */
5921 pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5923 /* We can now get rid of the HBITMAP wrapper we created earlier.
5924 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
5928 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
5929 pBmp->physBitmap = NULL;
5932 GDI_ReleaseObj( hBmp );
5936 TRACE("\tReturning packed DIB %x\n", hPackedDIB);
5941 /**************************************************************************
5942 * X11DRV_DIB_CreatePixmapFromDIB
5944 * Creates a Pixmap from a packed DIB
5946 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
5948 Pixmap pixmap = None;
5950 BITMAPOBJ *pBmp = NULL;
5951 LPBYTE pPackedDIB = NULL;
5952 LPBITMAPINFO pbmi = NULL;
5953 LPBITMAPINFOHEADER pbmiHeader = NULL;
5954 LPBYTE pbits = NULL;
5956 /* Get a pointer to the packed DIB's data */
5957 pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
5958 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
5959 pbmi = (LPBITMAPINFO)pPackedDIB;
5960 pbits = (LPBYTE)(pPackedDIB
5961 + DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
5963 /* Create a DDB from the DIB */
5965 hBmp = CreateDIBitmap(hdc,
5972 GlobalUnlock(hPackedDIB);
5974 TRACE("CreateDIBitmap returned %x\n", hBmp);
5976 /* Retrieve the internal Pixmap from the DDB */
5978 pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
5980 pixmap = (Pixmap)pBmp->physBitmap;
5981 /* clear the physBitmap so that we can steal its pixmap */
5982 pBmp->physBitmap = NULL;
5985 /* Delete the DDB we created earlier now that we have stolen its pixmap */
5986 GDI_ReleaseObj( hBmp );
5989 TRACE("\tReturning Pixmap %ld\n", pixmap);