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() */
57 X11DRV_PDEVICE
*physDev
;
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( X11DRV_PDEVICE
*physDev
, 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( physDev
, 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( physDev
, 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( physDev
, PALETTEINDEX(*index
) );
195 for (i
= start
; i
< end
; i
++)
196 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, 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( X11DRV_PDEVICE
*physDev
, 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( physDev
, 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 X11DRV_PDEVICE
*physDev
, 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 (physDev
, 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
,
3531 X11DRV_PDEVICE
*physDev
,
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 (physDev
, 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
,
3909 X11DRV_PDEVICE
*physDev
,
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 (physDev
, 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
->physDev
,
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
->physDev
,
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
->physDev
,
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( X11DRV_PDEVICE
*physDev
, 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 DC
*dc
= physDev
->dc
;
4746 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
4747 &descr
.infoBpp
, &descr
.compression
) == -1)
4750 if (height
< 0) height
= -height
;
4751 if (!lines
|| (startscan
>= height
)) return 0;
4752 if (startscan
+ lines
> height
) lines
= height
- startscan
;
4753 if (ySrc
< startscan
) ySrc
= startscan
;
4754 else if (ySrc
>= startscan
+ lines
) return 0;
4755 if (xSrc
>= width
) return 0;
4756 if (ySrc
+ cy
>= startscan
+ lines
) cy
= startscan
+ lines
- ySrc
;
4757 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
4758 if (!cx
|| !cy
) return 0;
4760 X11DRV_SetupGCForText( physDev
); /* To have the correct colors */
4761 TSXSetFunction(gdi_display
, physDev
->gc
, X11DRV_XROPfunction
[dc
->ROPmode
-1]);
4763 switch (descr
.infoBpp
)
4768 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
4769 coloruse
== DIB_PAL_COLORS
? physDev
: NULL
, coloruse
,
4770 dc
->bitsPerPixel
, info
, &descr
.nColorMap
);
4771 if (!descr
.colorMap
) return 0;
4772 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
4776 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
4777 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
4778 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
4784 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
4785 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
4786 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
4791 descr
.physDev
= physDev
;
4794 descr
.palentry
= NULL
;
4795 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
4796 descr
.infoWidth
= width
;
4797 descr
.depth
= dc
->bitsPerPixel
;
4798 descr
.drawable
= physDev
->drawable
;
4799 descr
.gc
= physDev
->gc
;
4801 descr
.ySrc
= tmpheight
>= 0 ? lines
-(ySrc
-startscan
)-cy
+(oldcy
-cy
)
4803 descr
.xDest
= dc
->DCOrgX
+ XLPTODP( dc
, xDest
);
4804 descr
.yDest
= dc
->DCOrgY
+ YLPTODP( dc
, yDest
) +
4805 (tmpheight
>= 0 ? oldcy
-cy
: 0);
4808 descr
.useShm
= FALSE
;
4809 descr
.dibpitch
= ((width
* descr
.infoBpp
+ 31) &~31) / 8;
4811 result
= X11DRV_DIB_SetImageBits( &descr
);
4813 if (descr
.infoBpp
<= 8)
4814 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
4818 /***********************************************************************
4819 * X11DRV_SetDIBits (X11DRV.@)
4821 INT
X11DRV_SetDIBits( X11DRV_PDEVICE
*physDev
, HBITMAP hbitmap
, UINT startscan
,
4822 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
, UINT coloruse
)
4824 X11DRV_DIB_IMAGEBITS_DESCR descr
;
4826 int height
, tmpheight
;
4829 descr
.physDev
= physDev
;
4831 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
4832 &descr
.infoBpp
, &descr
.compression
) == -1)
4836 if (height
< 0) height
= -height
;
4837 if (!lines
|| (startscan
>= height
))
4840 if (!(bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
))) return 0;
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
.physDev
: NULL
, coloruse
,
4851 bmp
->bitmap
.bmBitsPixel
,
4852 info
, &descr
.nColorMap
);
4853 if (!descr
.colorMap
)
4855 GDI_ReleaseObj( hbitmap
);
4858 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
4862 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
4863 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
4864 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
4870 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
4871 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
4872 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
4880 if(!bmp
->physBitmap
)
4881 X11DRV_CreateBitmap(hbitmap
);
4885 descr
.palentry
= NULL
;
4886 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
4887 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
4888 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
4889 descr
.gc
= BITMAP_GC(bmp
);
4893 descr
.yDest
= height
- startscan
- lines
;
4894 descr
.width
= bmp
->bitmap
.bmWidth
;
4895 descr
.height
= lines
;
4896 descr
.useShm
= FALSE
;
4897 descr
.dibpitch
= ((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8;
4898 result
= X11DRV_DIB_SetImageBits( &descr
);
4900 if (descr
.colorMap
) HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
4902 GDI_ReleaseObj( hbitmap
);
4906 /***********************************************************************
4907 * X11DRV_GetDIBits (X11DRV.@)
4909 INT
X11DRV_GetDIBits( X11DRV_PDEVICE
*physDev
, HBITMAP hbitmap
, UINT startscan
, UINT lines
,
4910 LPVOID bits
, BITMAPINFO
*info
, UINT coloruse
)
4912 X11DRV_DIBSECTION
*dib
;
4913 X11DRV_DIB_IMAGEBITS_DESCR descr
;
4914 PALETTEOBJ
* palette
;
4917 DC
*dc
= physDev
->dc
;
4919 if (!(palette
= (PALETTEOBJ
*)GDI_GetObjPtr( dc
->hPalette
, PALETTE_MAGIC
)))
4921 if (!(bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
)))
4923 GDI_ReleaseObj( dc
->hPalette
);
4926 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4928 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
4929 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
4930 (int)info
->bmiHeader
.biWidth
, (int)info
->bmiHeader
.biHeight
,
4933 if( lines
> bmp
->bitmap
.bmHeight
) lines
= bmp
->bitmap
.bmHeight
;
4935 height
= info
->bmiHeader
.biHeight
;
4936 if (height
< 0) height
= -height
;
4937 if( lines
> height
) lines
= height
;
4938 /* Top-down images have a negative biHeight, the scanlines of theses images
4939 * were inverted in X11DRV_DIB_GetImageBits_xx
4940 * To prevent this we simply change the sign of lines
4941 * (the number of scan lines to copy).
4942 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
4944 if( info
->bmiHeader
.biHeight
< 0 && lines
> 0) lines
= -lines
;
4946 if( startscan
>= bmp
->bitmap
.bmHeight
)
4952 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &descr
.lines
,
4953 &descr
.infoBpp
, &descr
.compression
) == -1)
4959 switch (descr
.infoBpp
)
4964 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
4968 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
4969 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
4970 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
4974 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
4975 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
4976 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
4981 if(!bmp
->physBitmap
)
4982 X11DRV_CreateBitmap(hbitmap
);
4985 descr
.physDev
= physDev
;
4986 descr
.palentry
= palette
->logpalette
.palPalEntry
;
4989 descr
.lines
= lines
;
4990 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
4991 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
4992 descr
.gc
= BITMAP_GC(bmp
);
4993 descr
.width
= bmp
->bitmap
.bmWidth
;
4994 descr
.height
= bmp
->bitmap
.bmHeight
;
4995 descr
.colorMap
= info
->bmiColors
;
5000 if (descr
.lines
> 0)
5002 descr
.ySrc
= (descr
.height
-1) - (startscan
+ (lines
-1));
5006 descr
.ySrc
= startscan
;
5008 #ifdef HAVE_LIBXXSHM
5009 descr
.useShm
= dib
? (dib
->shminfo
.shmid
!= -1) : FALSE
;
5011 descr
.useShm
= FALSE
;
5013 descr
.dibpitch
= dib
? (dib
->dibSection
.dsBm
.bmWidthBytes
)
5014 : (((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8);
5016 X11DRV_DIB_GetImageBits( &descr
);
5018 if(info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
5019 info
->bmiHeader
.biSizeImage
= DIB_GetDIBImageBytes(
5020 info
->bmiHeader
.biWidth
,
5021 info
->bmiHeader
.biHeight
,
5022 info
->bmiHeader
.biBitCount
);
5024 info
->bmiHeader
.biCompression
= 0;
5025 if (descr
.compression
== BI_BITFIELDS
)
5027 *(DWORD
*)info
->bmiColors
= descr
.rMask
;
5028 *((DWORD
*)info
->bmiColors
+1) = descr
.gMask
;
5029 *((DWORD
*)info
->bmiColors
+2) = descr
.bMask
;
5033 GDI_ReleaseObj( dc
->hPalette
);
5034 GDI_ReleaseObj( hbitmap
);
5038 /***********************************************************************
5039 * DIB_DoProtectDIBSection
5041 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
5043 DIBSECTION
*dib
= bmp
->dib
;
5044 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
5045 : -dib
->dsBm
.bmHeight
;
5046 /* use the biSizeImage data as the memory size only if we're dealing with a
5047 compressed image where the value is set. Otherwise, calculate based on
5049 INT totalSize
= dib
->dsBmih
.biSizeImage
&& dib
->dsBmih
.biCompression
!= BI_RGB
5050 ? dib
->dsBmih
.biSizeImage
5051 : dib
->dsBm
.bmWidthBytes
* effHeight
;
5054 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
5055 TRACE("Changed protection from %ld to %ld\n", old_prot
, new_prot
);
5058 /***********************************************************************
5059 * X11DRV_DIB_DoUpdateDIBSection
5061 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
,
5062 void *colorMap
, int nColorMap
,
5064 DWORD xSrc
, DWORD ySrc
,
5065 DWORD xDest
, DWORD yDest
,
5066 DWORD width
, DWORD height
)
5068 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5069 X11DRV_DIB_IMAGEBITS_DESCR descr
;
5071 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, &descr
.lines
,
5072 &descr
.infoBpp
, &descr
.compression
) == -1)
5075 descr
.physDev
= NULL
;
5076 descr
.palentry
= NULL
;
5077 descr
.image
= dib
->image
;
5078 descr
.colorMap
= colorMap
;
5079 descr
.nColorMap
= nColorMap
;
5080 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
5081 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
5083 switch (descr
.infoBpp
)
5088 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
5092 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0x7c00;
5093 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x03e0;
5094 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x001f;
5099 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0xff0000;
5100 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x00ff00;
5101 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x0000ff;
5106 descr
.drawable
= dest
;
5107 descr
.gc
= BITMAP_GC(bmp
);
5110 descr
.xDest
= xDest
;
5111 descr
.yDest
= yDest
;
5112 descr
.width
= width
;
5113 descr
.height
= height
;
5114 #ifdef HAVE_LIBXXSHM
5115 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
5117 descr
.useShm
= FALSE
;
5119 descr
.dibpitch
= dib
->dibSection
.dsBm
.bmWidthBytes
;
5123 TRACE("Copying from Pixmap to DIB bits\n");
5124 X11DRV_DIB_GetImageBits( &descr
);
5128 TRACE("Copying from DIB bits to Pixmap\n");
5129 X11DRV_DIB_SetImageBits( &descr
);
5133 /***********************************************************************
5134 * X11DRV_DIB_CopyDIBSection
5136 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE
*physDevSrc
, X11DRV_PDEVICE
*physDevDst
,
5137 DWORD xSrc
, DWORD ySrc
, DWORD xDest
, DWORD yDest
,
5138 DWORD width
, DWORD height
)
5141 DC
*dcSrc
= physDevSrc
->dc
;
5142 DC
*dcDst
= physDevDst
->dc
;
5143 int nColorMap
= 0, *colorMap
= NULL
, aColorMap
= FALSE
;
5145 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc
, dcDst
,
5146 xSrc
, ySrc
, xDest
, yDest
, width
, height
);
5147 /* this function is meant as an optimization for BitBlt,
5148 * not to be called otherwise */
5149 if (!(dcSrc
->flags
& DC_MEMORY
)) {
5150 ERR("called for non-memory source DC!?\n");
5154 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( dcSrc
->hBitmap
, BITMAP_MAGIC
);
5155 if (!(bmp
&& bmp
->dib
)) {
5156 ERR("called for non-DIBSection!?\n");
5157 GDI_ReleaseObj( dcSrc
->hBitmap
);
5160 /* while BitBlt should already have made sure we only get
5161 * positive values, we should check for oversize values */
5162 if ((xSrc
< bmp
->bitmap
.bmWidth
) &&
5163 (ySrc
< bmp
->bitmap
.bmHeight
)) {
5164 if (xSrc
+ width
> bmp
->bitmap
.bmWidth
)
5165 width
= bmp
->bitmap
.bmWidth
- xSrc
;
5166 if (ySrc
+ height
> bmp
->bitmap
.bmHeight
)
5167 height
= bmp
->bitmap
.bmHeight
- ySrc
;
5168 /* if the source bitmap is 8bpp or less, we're supposed to use the
5169 * DC's palette for color conversion (not the DIB color table) */
5170 if (bmp
->dib
->dsBm
.bmBitsPixel
<= 8) {
5171 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5172 if ((!dcSrc
->hPalette
) ||
5173 (dcSrc
->hPalette
== GetStockObject(DEFAULT_PALETTE
))) {
5174 /* HACK: no palette has been set in the source DC,
5175 * use the DIB colormap instead - this is necessary in some
5176 * cases since we need to do depth conversion in some places
5177 * where real Windows can just copy data straight over */
5178 colorMap
= dib
->colorMap
;
5179 nColorMap
= dib
->nColorMap
;
5181 colorMap
= X11DRV_DIB_BuildColorMap( physDevSrc
, (WORD
)-1,
5182 bmp
->dib
->dsBm
.bmBitsPixel
,
5183 (BITMAPINFO
*)&(bmp
->dib
->dsBmih
),
5185 if (colorMap
) aColorMap
= TRUE
;
5188 /* perform the copy */
5189 X11DRV_DIB_DoCopyDIBSection(bmp
, FALSE
, colorMap
, nColorMap
,
5190 physDevDst
->drawable
, xSrc
, ySrc
, xDest
, yDest
,
5192 /* free color mapping */
5194 HeapFree(GetProcessHeap(), 0, colorMap
);
5196 GDI_ReleaseObj( dcSrc
->hBitmap
);
5199 /***********************************************************************
5200 * X11DRV_DIB_DoUpdateDIBSection
5202 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
5204 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5205 X11DRV_DIB_DoCopyDIBSection(bmp
, toDIB
, dib
->colorMap
, dib
->nColorMap
,
5206 (Drawable
)bmp
->physBitmap
, 0, 0, 0, 0,
5207 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
5210 /***********************************************************************
5211 * X11DRV_DIB_FaultHandler
5213 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
5218 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
5219 if (!bmp
) return FALSE
;
5221 state
= X11DRV_DIB_Lock(bmp
, DIB_Status_None
, FALSE
);
5222 if (state
!= DIB_Status_InSync
) {
5223 /* no way to tell whether app needs read or write yet,
5225 X11DRV_DIB_Coerce(bmp
, DIB_Status_InSync
, FALSE
);
5227 /* hm, apparently the app must have write access */
5228 X11DRV_DIB_Coerce(bmp
, DIB_Status_AppMod
, FALSE
);
5230 X11DRV_DIB_Unlock(bmp
, TRUE
);
5232 GDI_ReleaseObj( (HBITMAP
)res
);
5236 /***********************************************************************
5239 INT
X11DRV_DIB_Coerce(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
5241 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5242 INT ret
= DIB_Status_None
;
5245 EnterCriticalSection(&(dib
->lock
));
5248 case DIB_Status_GdiMod
:
5249 /* GDI access - request to draw on pixmap */
5250 switch (dib
->status
)
5253 case DIB_Status_None
:
5254 dib
->p_status
= DIB_Status_GdiMod
;
5255 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
5258 case DIB_Status_GdiMod
:
5259 TRACE("GdiMod requested in status GdiMod\n" );
5262 case DIB_Status_InSync
:
5263 TRACE("GdiMod requested in status InSync\n" );
5264 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
5265 dib
->status
= DIB_Status_GdiMod
;
5266 dib
->p_status
= DIB_Status_InSync
;
5269 case DIB_Status_AuxMod
:
5270 TRACE("GdiMod requested in status AuxMod\n" );
5271 if (lossy
) dib
->status
= DIB_Status_GdiMod
;
5272 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_GdiMod
);
5273 dib
->p_status
= DIB_Status_AuxMod
;
5274 if (dib
->status
!= DIB_Status_AppMod
) {
5275 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
5278 /* fall through if copy_aux() had to change to AppMod state */
5280 case DIB_Status_AppMod
:
5281 TRACE("GdiMod requested in status AppMod\n" );
5283 /* make it readonly to avoid app changing data while we copy */
5284 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5285 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
5287 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
5288 dib
->p_status
= DIB_Status_AppMod
;
5289 dib
->status
= DIB_Status_GdiMod
;
5294 case DIB_Status_InSync
:
5295 /* App access - request access to read DIB surface */
5296 /* (typically called from signal handler) */
5297 switch (dib
->status
)
5300 case DIB_Status_None
:
5301 /* shouldn't happen from signal handler */
5304 case DIB_Status_AuxMod
:
5305 TRACE("InSync requested in status AuxMod\n" );
5306 if (lossy
) dib
->status
= DIB_Status_InSync
;
5308 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5309 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_InSync
);
5311 if (dib
->status
!= DIB_Status_GdiMod
) {
5312 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5315 /* fall through if copy_aux() had to change to GdiMod state */
5317 case DIB_Status_GdiMod
:
5318 TRACE("InSync requested in status GdiMod\n" );
5320 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5321 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
5323 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5324 dib
->status
= DIB_Status_InSync
;
5327 case DIB_Status_InSync
:
5328 TRACE("InSync requested in status InSync\n" );
5329 /* shouldn't happen from signal handler */
5332 case DIB_Status_AppMod
:
5333 TRACE("InSync requested in status AppMod\n" );
5334 /* no reason to do anything here, and this
5335 * shouldn't happen from signal handler */
5340 case DIB_Status_AppMod
:
5341 /* App access - request access to write DIB surface */
5342 /* (typically called from signal handler) */
5343 switch (dib
->status
)
5346 case DIB_Status_None
:
5347 /* shouldn't happen from signal handler */
5350 case DIB_Status_AuxMod
:
5351 TRACE("AppMod requested in status AuxMod\n" );
5352 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5353 if (lossy
) dib
->status
= DIB_Status_AppMod
;
5354 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
5355 if (dib
->status
!= DIB_Status_GdiMod
)
5357 /* fall through if copy_aux() had to change to GdiMod state */
5359 case DIB_Status_GdiMod
:
5360 TRACE("AppMod requested in status GdiMod\n" );
5361 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5362 if (!lossy
) X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
5363 dib
->status
= DIB_Status_AppMod
;
5366 case DIB_Status_InSync
:
5367 TRACE("AppMod requested in status InSync\n" );
5368 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5369 dib
->status
= DIB_Status_AppMod
;
5372 case DIB_Status_AppMod
:
5373 TRACE("AppMod requested in status AppMod\n" );
5374 /* shouldn't happen from signal handler */
5379 case DIB_Status_AuxMod
:
5380 if (dib
->status
== DIB_Status_None
) {
5381 dib
->p_status
= req
;
5383 if (dib
->status
!= DIB_Status_AuxMod
)
5384 dib
->p_status
= dib
->status
;
5385 dib
->status
= DIB_Status_AuxMod
;
5388 /* it is up to the caller to do the copy/conversion, probably
5389 * using the return value to decide where to copy from */
5391 LeaveCriticalSection(&(dib
->lock
));
5396 /***********************************************************************
5399 INT
X11DRV_DIB_Lock(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
5401 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5402 INT ret
= DIB_Status_None
;
5405 TRACE("Locking %p from thread %08lx\n", bmp
, GetCurrentThreadId());
5406 EnterCriticalSection(&(dib
->lock
));
5408 if (req
!= DIB_Status_None
)
5409 X11DRV_DIB_Coerce(bmp
, req
, lossy
);
5414 /***********************************************************************
5417 void X11DRV_DIB_Unlock(BITMAPOBJ
*bmp
, BOOL commit
)
5419 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5422 switch (dib
->status
)
5425 case DIB_Status_None
:
5426 /* in case anyone is wondering, this is the "signal handler doesn't
5427 * work" case, where we always have to be ready for app access */
5429 switch (dib
->p_status
)
5431 case DIB_Status_AuxMod
:
5432 TRACE("Unlocking and syncing from AuxMod\n" );
5433 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
5434 if (dib
->status
!= DIB_Status_None
) {
5435 dib
->p_status
= dib
->status
;
5436 dib
->status
= DIB_Status_None
;
5438 if (dib
->p_status
!= DIB_Status_GdiMod
)
5440 /* fall through if copy_aux() had to change to GdiMod state */
5442 case DIB_Status_GdiMod
:
5443 TRACE("Unlocking and syncing from GdiMod\n" );
5444 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
5448 TRACE("Unlocking without needing to sync\n" );
5452 else TRACE("Unlocking with no changes\n");
5453 dib
->p_status
= DIB_Status_None
;
5456 case DIB_Status_GdiMod
:
5457 TRACE("Unlocking in status GdiMod\n" );
5458 /* DIB was protected in Coerce */
5460 /* no commit, revert to InSync if applicable */
5461 if ((dib
->p_status
== DIB_Status_InSync
) ||
5462 (dib
->p_status
== DIB_Status_AppMod
)) {
5463 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5464 dib
->status
= DIB_Status_InSync
;
5469 case DIB_Status_InSync
:
5470 TRACE("Unlocking in status InSync\n" );
5471 /* DIB was already protected in Coerce */
5474 case DIB_Status_AppMod
:
5475 TRACE("Unlocking in status AppMod\n" );
5476 /* DIB was already protected in Coerce */
5477 /* this case is ordinary only called from the signal handler,
5478 * so we don't bother to check for !commit */
5481 case DIB_Status_AuxMod
:
5482 TRACE("Unlocking in status AuxMod\n" );
5484 /* DIB may need protection now */
5485 if ((dib
->p_status
== DIB_Status_InSync
) ||
5486 (dib
->p_status
== DIB_Status_AppMod
))
5487 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
5489 /* no commit, revert to previous state */
5490 if (dib
->p_status
!= DIB_Status_None
)
5491 dib
->status
= dib
->p_status
;
5492 /* no protections changed */
5494 dib
->p_status
= DIB_Status_None
;
5497 LeaveCriticalSection(&(dib
->lock
));
5498 TRACE("Unlocked %p\n", bmp
);
5502 /***********************************************************************
5503 * X11DRV_CoerceDIBSection2
5505 INT
X11DRV_CoerceDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
5510 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5511 if (!bmp
) return DIB_Status_None
;
5512 ret
= X11DRV_DIB_Coerce(bmp
, req
, lossy
);
5513 GDI_ReleaseObj( hBmp
);
5517 /***********************************************************************
5518 * X11DRV_LockDIBSection2
5520 INT
X11DRV_LockDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
5525 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5526 if (!bmp
) return DIB_Status_None
;
5527 ret
= X11DRV_DIB_Lock(bmp
, req
, lossy
);
5528 GDI_ReleaseObj( hBmp
);
5532 /***********************************************************************
5533 * X11DRV_UnlockDIBSection2
5535 void X11DRV_UnlockDIBSection2(HBITMAP hBmp
, BOOL commit
)
5539 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5541 X11DRV_DIB_Unlock(bmp
, commit
);
5542 GDI_ReleaseObj( hBmp
);
5545 /***********************************************************************
5546 * X11DRV_CoerceDIBSection
5548 INT
X11DRV_CoerceDIBSection(X11DRV_PDEVICE
*physDev
, INT req
, BOOL lossy
)
5550 if (!physDev
) return DIB_Status_None
;
5551 return X11DRV_CoerceDIBSection2( physDev
->dc
->hBitmap
, req
, lossy
);
5554 /***********************************************************************
5555 * X11DRV_LockDIBSection
5557 INT
X11DRV_LockDIBSection(X11DRV_PDEVICE
*physDev
, INT req
, BOOL lossy
)
5559 if (!physDev
) return DIB_Status_None
;
5560 if (!(physDev
->dc
->flags
& DC_MEMORY
)) return DIB_Status_None
;
5562 return X11DRV_LockDIBSection2( physDev
->dc
->hBitmap
, req
, lossy
);
5565 /***********************************************************************
5566 * X11DRV_UnlockDIBSection
5568 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE
*physDev
, BOOL commit
)
5570 if (!physDev
) return;
5571 if (!(physDev
->dc
->flags
& DC_MEMORY
)) return;
5573 X11DRV_UnlockDIBSection2( physDev
->dc
->hBitmap
, commit
);
5577 #ifdef HAVE_LIBXXSHM
5578 /***********************************************************************
5579 * X11DRV_XShmErrorHandler
5582 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
)
5588 /***********************************************************************
5589 * X11DRV_XShmCreateImage
5592 static XImage
*X11DRV_XShmCreateImage( int width
, int height
, int bpp
,
5593 XShmSegmentInfo
* shminfo
)
5595 int (*WineXHandler
)(Display
*, XErrorEvent
*);
5599 image
= XShmCreateImage(gdi_display
, visual
, bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
5602 shminfo
->shmid
= shmget(IPC_PRIVATE
, image
->bytes_per_line
* height
,
5604 if( shminfo
->shmid
!= -1 )
5606 shminfo
->shmaddr
= image
->data
= shmat(shminfo
->shmid
, 0, 0);
5607 if( shminfo
->shmaddr
!= (char*)-1 )
5609 shminfo
->readOnly
= FALSE
;
5610 if( XShmAttach( gdi_display
, shminfo
) != 0)
5612 /* Reset the error flag */
5614 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
5615 XSync( gdi_display
, 0 );
5619 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
5621 XSetErrorHandler(WineXHandler
);
5622 wine_tsx11_unlock();
5623 return image
; /* Success! */
5625 /* An error occurred */
5627 XSetErrorHandler(WineXHandler
);
5629 shmdt(shminfo
->shmaddr
);
5631 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
5633 XFlush(gdi_display
);
5634 XDestroyImage(image
);
5637 wine_tsx11_unlock();
5640 #endif /* HAVE_LIBXXSHM */
5643 /***********************************************************************
5644 * X11DRV_DIB_CreateDIBSection
5646 HBITMAP
X11DRV_DIB_CreateDIBSection(
5647 X11DRV_PDEVICE
*physDev
, BITMAPINFO
*bmi
, UINT usage
,
5648 LPVOID
*bits
, HANDLE section
,
5649 DWORD offset
, DWORD ovr_pitch
)
5652 BITMAPOBJ
*bmp
= NULL
;
5653 X11DRV_DIBSECTION
*dib
= NULL
;
5654 int *colorMap
= NULL
;
5657 /* Fill BITMAP32 structure with DIB data */
5658 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
5659 INT effHeight
, totalSize
;
5661 LPVOID mapBits
= NULL
;
5663 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
5664 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
5665 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
5667 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
5669 bm
.bmWidth
= bi
->biWidth
;
5670 bm
.bmHeight
= effHeight
;
5671 bm
.bmWidthBytes
= ovr_pitch
? ovr_pitch
5672 : DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
5673 bm
.bmPlanes
= bi
->biPlanes
;
5674 bm
.bmBitsPixel
= bi
->biBitCount
;
5677 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
5678 we're dealing with a compressed bitmap. Otherwise, use width * height. */
5679 totalSize
= bi
->biSizeImage
&& bi
->biCompression
!= BI_RGB
5680 ? bi
->biSizeImage
: bm
.bmWidthBytes
* effHeight
;
5684 SYSTEM_INFO SystemInfo
;
5688 GetSystemInfo( &SystemInfo
);
5689 mapOffset
= offset
- (offset
% SystemInfo
.dwAllocationGranularity
);
5690 mapSize
= totalSize
+ (offset
- mapOffset
);
5691 mapBits
= MapViewOfFile( section
,
5692 FILE_MAP_ALL_ACCESS
,
5696 bm
.bmBits
= (char *)mapBits
+ (offset
- mapOffset
);
5698 else if (ovr_pitch
&& offset
)
5699 bm
.bmBits
= (LPVOID
) offset
;
5702 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
5703 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
5706 /* Create Color Map */
5707 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8)
5708 colorMap
= X11DRV_DIB_BuildColorMap( usage
== DIB_PAL_COLORS
? physDev
: NULL
,
5709 usage
, bm
.bmBitsPixel
, bmi
, &nColorMap
);
5711 /* Allocate Memory for DIB and fill structure */
5713 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
5716 dib
->dibSection
.dsBm
= bm
;
5717 dib
->dibSection
.dsBmih
= *bi
;
5718 dib
->dibSection
.dsBmih
.biSizeImage
= totalSize
;
5720 /* Set dsBitfields values */
5721 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
5723 dib
->dibSection
.dsBitfields
[0] = dib
->dibSection
.dsBitfields
[1] = dib
->dibSection
.dsBitfields
[2] = 0;
5725 else switch( bi
->biBitCount
)
5729 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
5730 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
5731 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f;
5736 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff0000;
5737 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x00ff00;
5738 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x0000ff;
5741 dib
->dibSection
.dshSection
= section
;
5742 dib
->dibSection
.dsOffset
= offset
;
5744 dib
->status
= DIB_Status_None
;
5745 dib
->nColorMap
= nColorMap
;
5746 dib
->colorMap
= colorMap
;
5749 /* Create Device Dependent Bitmap and add DIB pointer */
5752 res
= CreateDIBitmap(physDev
->hdc
, bi
, 0, NULL
, bmi
, usage
);
5755 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
5758 bmp
->dib
= (DIBSECTION
*) dib
;
5760 if(!bmp
->physBitmap
)
5761 X11DRV_CreateBitmap(res
);
5769 #ifdef HAVE_LIBXXSHM
5770 if (TSXShmQueryExtension(gdi_display
) &&
5771 (dib
->image
= X11DRV_XShmCreateImage( bm
.bmWidth
, effHeight
,
5772 bmp
->bitmap
.bmBitsPixel
, &dib
->shminfo
)) )
5774 ; /* Created Image */
5776 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
5777 dib
->shminfo
.shmid
= -1;
5780 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
5784 /* Clean up in case of errors */
5785 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
5787 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
5788 res
, bmp
, dib
, bm
.bmBits
);
5792 UnmapViewOfFile(mapBits
), bm
.bmBits
= NULL
;
5794 VirtualFree(bm
.bmBits
, 0L, MEM_RELEASE
), bm
.bmBits
= NULL
;
5797 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
5798 if (colorMap
) { HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
; }
5799 if (dib
) { HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
; }
5800 if (bmp
) { GDI_ReleaseObj(res
); bmp
= NULL
; }
5801 if (res
) { DeleteObject(res
); res
= 0; }
5805 /* Install fault handler, if possible */
5806 InitializeCriticalSection(&(dib
->lock
));
5807 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
5809 if (section
|| offset
)
5811 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5812 if (dib
) dib
->status
= DIB_Status_AppMod
;
5816 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5817 if (dib
) dib
->status
= DIB_Status_InSync
;
5822 /* Return BITMAP handle and storage location */
5823 if (bmp
) GDI_ReleaseObj(res
);
5824 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
5828 /***********************************************************************
5829 * X11DRV_DIB_DeleteDIBSection
5831 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
5833 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5837 #ifdef HAVE_LIBXXSHM
5838 if (dib
->shminfo
.shmid
!= -1)
5840 TSXShmDetach (gdi_display
, &(dib
->shminfo
));
5841 XDestroyImage (dib
->image
);
5842 shmdt (dib
->shminfo
.shmaddr
);
5843 dib
->shminfo
.shmid
= -1;
5847 XDestroyImage( dib
->image
);
5851 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
5853 DeleteCriticalSection(&(dib
->lock
));
5856 /***********************************************************************
5857 * X11DRV_SetDIBColorTable (X11DRV.@)
5859 UINT
X11DRV_SetDIBColorTable( X11DRV_PDEVICE
*physDev
, UINT start
, UINT count
, const RGBQUAD
*colors
)
5862 X11DRV_DIBSECTION
*dib
;
5865 if (!(bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( physDev
->dc
->hBitmap
, BITMAP_MAGIC
))) return 0;
5866 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5868 if (dib
&& dib
->colorMap
) {
5869 UINT end
= count
+ start
;
5870 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
5872 * Changing color table might change the mapping between
5873 * DIB colors and X11 colors and thus alter the visible state
5874 * of the bitmap object.
5876 X11DRV_DIB_Lock(bmp
, DIB_Status_AppMod
, FALSE
);
5877 X11DRV_DIB_GenColorMap( physDev
, dib
->colorMap
, DIB_RGB_COLORS
,
5878 dib
->dibSection
.dsBm
.bmBitsPixel
,
5879 TRUE
, colors
, start
, end
);
5880 X11DRV_DIB_Unlock(bmp
, TRUE
);
5883 GDI_ReleaseObj( physDev
->dc
->hBitmap
);
5887 /***********************************************************************
5888 * X11DRV_GetDIBColorTable (X11DRV.@)
5890 UINT
X11DRV_GetDIBColorTable( X11DRV_PDEVICE
*physDev
, UINT start
, UINT count
, RGBQUAD
*colors
)
5893 X11DRV_DIBSECTION
*dib
;
5896 if (!(bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( physDev
->dc
->hBitmap
, BITMAP_MAGIC
))) return 0;
5897 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5899 if (dib
&& dib
->colorMap
) {
5900 UINT i
, end
= count
+ start
;
5901 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
5902 for (i
= start
; i
< end
; i
++,colors
++) {
5903 COLORREF col
= X11DRV_PALETTE_ToLogical( dib
->colorMap
[i
] );
5904 colors
->rgbBlue
= GetBValue(col
);
5905 colors
->rgbGreen
= GetGValue(col
);
5906 colors
->rgbRed
= GetRValue(col
);
5907 colors
->rgbReserved
= 0;
5911 GDI_ReleaseObj( physDev
->dc
->hBitmap
);
5916 /**************************************************************************
5917 * X11DRV_DIB_CreateDIBFromPixmap
5919 * Allocates a packed DIB and copies the Pixmap data into it.
5920 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
5922 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
, BOOL bDeletePixmap
)
5925 BITMAPOBJ
*pBmp
= NULL
;
5926 HGLOBAL hPackedDIB
= 0;
5928 /* Allocates an HBITMAP which references the Pixmap passed to us */
5929 hBmp
= X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap
);
5932 TRACE("\tCould not create bitmap header for Pixmap\n");
5937 * Create a packed DIB from the Pixmap wrapper bitmap created above.
5938 * A packed DIB contains a BITMAPINFO structure followed immediately by
5939 * an optional color palette and the pixel data.
5941 hPackedDIB
= DIB_CreateDIBFromBitmap(hdc
, hBmp
);
5943 /* Get a pointer to the BITMAPOBJ structure */
5944 pBmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5946 /* We can now get rid of the HBITMAP wrapper we created earlier.
5947 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
5951 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
5952 pBmp
->physBitmap
= NULL
;
5955 GDI_ReleaseObj( hBmp
);
5959 TRACE("\tReturning packed DIB %x\n", hPackedDIB
);
5964 /**************************************************************************
5965 * X11DRV_DIB_CreatePixmapFromDIB
5967 * Creates a Pixmap from a packed DIB
5969 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
5971 Pixmap pixmap
= None
;
5973 BITMAPOBJ
*pBmp
= NULL
;
5974 LPBYTE pPackedDIB
= NULL
;
5975 LPBITMAPINFO pbmi
= NULL
;
5976 LPBITMAPINFOHEADER pbmiHeader
= NULL
;
5977 LPBYTE pbits
= NULL
;
5979 /* Get a pointer to the packed DIB's data */
5980 pPackedDIB
= (LPBYTE
)GlobalLock(hPackedDIB
);
5981 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
5982 pbmi
= (LPBITMAPINFO
)pPackedDIB
;
5983 pbits
= (LPBYTE
)(pPackedDIB
5984 + DIB_BitmapInfoSize( (LPBITMAPINFO
)pbmiHeader
, DIB_RGB_COLORS
));
5986 /* Create a DDB from the DIB */
5988 hBmp
= CreateDIBitmap(hdc
,
5995 GlobalUnlock(hPackedDIB
);
5997 TRACE("CreateDIBitmap returned %x\n", hBmp
);
5999 /* Retrieve the internal Pixmap from the DDB */
6001 pBmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
6003 pixmap
= (Pixmap
)pBmp
->physBitmap
;
6004 /* clear the physBitmap so that we can steal its pixmap */
6005 pBmp
->physBitmap
= NULL
;
6008 /* Delete the DDB we created earlier now that we have stolen its pixmap */
6009 GDI_ReleaseObj( hBmp
);
6012 TRACE("\tReturning Pixmap %ld\n", pixmap
);