2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <X11/extensions/XShm.h>
26 # ifdef HAVE_SYS_SHM_H
29 # ifdef HAVE_SYS_IPC_H
32 #endif /* defined(HAVE_LIBXXSHM) */
39 #include "wine/debug.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(bitmap
);
45 WINE_DECLARE_DEBUG_CHANNEL(x11drv
);
47 static int ximageDepthTable
[32];
49 /* This structure holds the arguments for DIB_SetImageBits() */
52 X11DRV_PDEVICE
*physDev
;
55 PALETTEENTRY
*palentry
;
76 } X11DRV_DIB_IMAGEBITS_DESCR
;
81 RLE_EOL
= 0, /* End of line */
82 RLE_END
= 1, /* End of bitmap */
83 RLE_DELTA
= 2 /* Delta */
86 /***********************************************************************
87 * X11DRV_DIB_GetXImageWidthBytes
89 * Return the width of an X image in bytes
91 inline static int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
93 if (!depth
|| depth
> 32) goto error
;
95 if (!ximageDepthTable
[depth
-1])
97 XImage
*testimage
= XCreateImage( gdi_display
, visual
, depth
,
98 ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
101 ximageDepthTable
[depth
-1] = testimage
->bits_per_pixel
;
102 XDestroyImage( testimage
);
104 else ximageDepthTable
[depth
-1] = -1;
106 if (ximageDepthTable
[depth
-1] != -1)
107 return (4 * ((width
* ximageDepthTable
[depth
-1] + 31) / 32));
110 WARN( "(%d): Unsupported depth\n", depth
);
115 /***********************************************************************
116 * X11DRV_DIB_CreateXImage
120 XImage
*X11DRV_DIB_CreateXImage( int width
, int height
, int depth
)
126 width_bytes
= X11DRV_DIB_GetXImageWidthBytes( width
, depth
);
127 image
= XCreateImage( gdi_display
, visual
, depth
, ZPixmap
, 0,
128 calloc( height
, width_bytes
),
129 width
, height
, 32, width_bytes
);
135 /***********************************************************************
138 * Get the info from a bitmap header.
139 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
141 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER
*header
, DWORD
*width
,
142 int *height
, WORD
*bpp
, WORD
*compr
)
144 if (header
->biSize
== sizeof(BITMAPCOREHEADER
))
146 BITMAPCOREHEADER
*core
= (BITMAPCOREHEADER
*)header
;
147 *width
= core
->bcWidth
;
148 *height
= core
->bcHeight
;
149 *bpp
= core
->bcBitCount
;
153 if (header
->biSize
>= sizeof(BITMAPINFOHEADER
))
155 *width
= header
->biWidth
;
156 *height
= header
->biHeight
;
157 *bpp
= header
->biBitCount
;
158 *compr
= header
->biCompression
;
161 ERR("(%ld): unknown/wrong size for header\n", header
->biSize
);
166 /***********************************************************************
167 * X11DRV_DIB_GenColorMap
169 * Fills the color map of a bitmap palette. Should not be called
170 * for a >8-bit deep bitmap.
172 int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE
*physDev
, int *colorMapping
,
173 WORD coloruse
, WORD depth
, BOOL quads
,
174 const void *colorPtr
, int start
, int end
)
178 if (coloruse
== DIB_RGB_COLORS
)
180 int max
= 1 << depth
;
182 if (end
> max
) end
= max
;
186 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
188 if (depth
== 1) /* Monochrome */
189 for (i
= start
; i
< end
; i
++, rgb
++)
190 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
191 rgb
->rgbBlue
> 255*3/2);
193 for (i
= start
; i
< end
; i
++, rgb
++)
194 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, RGB(rgb
->rgbRed
,
200 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
202 if (depth
== 1) /* Monochrome */
203 for (i
= start
; i
< end
; i
++, rgb
++)
204 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
205 rgb
->rgbtBlue
> 255*3/2);
207 for (i
= start
; i
< end
; i
++, rgb
++)
208 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, RGB(rgb
->rgbtRed
,
213 else /* DIB_PAL_COLORS */
216 WORD
* index
= (WORD
*)colorPtr
;
218 for (i
= start
; i
< end
; i
++, index
++)
219 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, PALETTEINDEX(*index
) );
221 for (i
= start
; i
< end
; i
++)
222 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, PALETTEINDEX(i
) );
229 /***********************************************************************
230 * X11DRV_DIB_BuildColorMap
232 * Build the color map from the bitmap palette. Should not be called
233 * for a >8-bit deep bitmap.
235 int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE
*physDev
, WORD coloruse
, WORD depth
,
236 const BITMAPINFO
*info
, int *nColors
)
240 const void *colorPtr
;
243 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
245 colors
= info
->bmiHeader
.biClrUsed
;
246 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
247 colorPtr
= info
->bmiColors
;
249 else /* assume BITMAPCOREINFO */
251 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
252 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
257 ERR("called with >256 colors!\n");
261 /* just so CopyDIBSection doesn't have to create an identity palette */
262 if (coloruse
== (WORD
)-1) colorPtr
= NULL
;
264 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
265 colors
* sizeof(int) )))
269 return X11DRV_DIB_GenColorMap( physDev
, colorMapping
, coloruse
, depth
,
270 isInfo
, colorPtr
, 0, colors
);
274 /***********************************************************************
275 * X11DRV_DIB_MapColor
277 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
, int oldcol
)
281 if ((oldcol
< nPhysMap
) && (physMap
[oldcol
] == phys
))
284 for (color
= 0; color
< nPhysMap
; color
++)
285 if (physMap
[color
] == phys
)
288 WARN("Strange color %08x\n", phys
);
293 /*********************************************************************
294 * X11DRV_DIB_GetNearestIndex
296 * Helper for X11DRV_DIB_GetDIBits.
297 * Returns the nearest colour table index for a given RGB.
298 * Nearest is defined by minimizing the sum of the squares.
300 static INT
X11DRV_DIB_GetNearestIndex(RGBQUAD
*colormap
, int numColors
, BYTE r
, BYTE g
, BYTE b
)
302 INT i
, best
= -1, diff
, bestdiff
= -1;
305 for(color
= colormap
, i
= 0; i
< numColors
; color
++, i
++) {
306 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
307 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
308 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
311 if(best
== -1 || diff
< bestdiff
) {
318 /*********************************************************************
319 * X11DRV_DIB_MaskToShift
321 * Helper for X11DRV_DIB_GetDIBits.
322 * Returns the by how many bits to shift a given color so that it is
323 * in the proper position.
325 static INT
X11DRV_DIB_MaskToShift(DWORD mask
)
333 while ((mask
&1)==0) {
340 /***********************************************************************
341 * X11DRV_DIB_Convert_any_asis
343 * All X11DRV_DIB_Convert_Xxx functions take at least the following
346 * This is the width in pixel of the surface to copy. This may be less
347 * than the full width of the image.
349 * The number of lines to copy. This may be less than the full height
350 * of the image. This is always >0.
352 * Points to the first byte containing data to be copied. If the source
353 * surface starts are coordinates (x,y) then this is:
354 * image_ptr+x*bytes_pre_pixel+y*bytes_per_line
355 * (with further adjustments for top-down/bottom-up images)
357 * This is the number of bytes per line. It may be >0 or <0 depending on
358 * whether this is a top-down or bottom-up image.
360 * Same as srcbits but for the destination
362 * Same as srclinebytes but for the destination.
365 * - The supported Dib formats are: pal1, pal4, pal8, rgb555, bgr555,
366 * rgb565, bgr565, rgb888 and any 32bit (0888) format.
367 * The supported XImage (Bmp) formats are: pal1, pal4, pal8,
368 * rgb555, bgr555, rgb565, bgr565, rgb888, bgr888, rgb0888, bgr0888.
369 * - Rgb formats are those for which the masks are such that:
370 * red_mask > green_mask > blue_mask
371 * - Bgr formats are those for which the masks sort in the other direction.
372 * - Many conversion functions handle both rgb->bgr and bgr->rgb conversions
373 * so the comments use h, g, l to mean respectively the source color in the
374 * high bits, the green, and the source color in the low bits.
376 static void X11DRV_DIB_Convert_any_asis(int width
, int height
,
378 const void* srcbits
, int srclinebytes
,
379 void* dstbits
, int dstlinebytes
)
383 width
*=bytes_per_pixel
;
384 for (y
=0; y
<height
; y
++) {
385 memcpy(dstbits
, srcbits
, width
);
386 srcbits
= (char*)srcbits
+ srclinebytes
;
387 dstbits
= (char*)dstbits
+ dstlinebytes
;
395 static void X11DRV_DIB_Convert_555_reverse(int width
, int height
,
396 const void* srcbits
, int srclinebytes
,
397 void* dstbits
, int dstlinebytes
)
399 const DWORD
* srcpixel
;
403 for (y
=0; y
<height
; y
++) {
406 for (x
=0; x
<width
/2; x
++) {
407 /* Do 2 pixels at a time */
410 *dstpixel
++=((srcval
<< 10) & 0x7c007c00) | /* h */
411 ( srcval
& 0x03e003e0) | /* g */
412 ((srcval
>> 10) & 0x001f001f); /* l */
415 /* And the the odd pixel */
417 srcval
=*((WORD
*)srcpixel
);
418 *((WORD
*)dstpixel
)=((srcval
<< 10) & 0x7c00) | /* h */
419 ( srcval
& 0x03e0) | /* g */
420 ((srcval
>> 10) & 0x001f); /* l */
422 srcbits
= (char*)srcbits
+ srclinebytes
;
423 dstbits
= (char*)dstbits
+ dstlinebytes
;
427 static void X11DRV_DIB_Convert_555_to_565_asis(int width
, int height
,
428 const void* srcbits
, int srclinebytes
,
429 void* dstbits
, int dstlinebytes
)
431 const DWORD
* srcpixel
;
435 for (y
=0; y
<height
; y
++) {
438 for (x
=0; x
<width
/2; x
++) {
439 /* Do 2 pixels at a time */
442 *dstpixel
++=((srcval
<< 1) & 0xffc0ffc0) | /* h, g */
443 ((srcval
>> 4) & 0x00200020) | /* g - 1 bit */
444 ( srcval
& 0x001f001f); /* l */
447 /* And the the odd pixel */
449 srcval
=*((WORD
*)srcpixel
);
450 *((WORD
*)dstpixel
)=((srcval
<< 1) & 0xffc0) | /* h, g */
451 ((srcval
>> 4) & 0x0020) | /* g - 1 bit */
452 (srcval
& 0x001f); /* l */
454 srcbits
= (char*)srcbits
+ srclinebytes
;
455 dstbits
= (char*)dstbits
+ dstlinebytes
;
459 static void X11DRV_DIB_Convert_555_to_565_reverse(int width
, int height
,
460 const void* srcbits
, int srclinebytes
,
461 void* dstbits
, int dstlinebytes
)
463 const DWORD
* srcpixel
;
467 for (y
=0; y
<height
; y
++) {
470 for (x
=0; x
<width
/2; x
++) {
471 /* Do 2 pixels at a time */
474 *dstpixel
++=((srcval
>> 10) & 0x001f001f) | /* h */
475 ((srcval
<< 1) & 0x07c007c0) | /* g */
476 ((srcval
>> 4) & 0x00200020) | /* g - 1 bit */
477 ((srcval
<< 11) & 0xf800f800); /* l */
480 /* And the the odd pixel */
482 srcval
=*((WORD
*)srcpixel
);
483 *((WORD
*)dstpixel
)=((srcval
>> 10) & 0x001f) | /* h */
484 ((srcval
<< 1) & 0x07c0) | /* g */
485 ((srcval
>> 4) & 0x0020) | /* g - 1 bit */
486 ((srcval
<< 11) & 0xf800); /* l */
488 srcbits
= (char*)srcbits
+ srclinebytes
;
489 dstbits
= (char*)dstbits
+ dstlinebytes
;
493 static void X11DRV_DIB_Convert_555_to_888_asis(int width
, int height
,
494 const void* srcbits
, int srclinebytes
,
495 void* dstbits
, int dstlinebytes
)
497 const WORD
* srcpixel
;
501 for (y
=0; y
<height
; y
++) {
504 for (x
=0; x
<width
; x
++) {
507 dstpixel
[0]=((srcval
<< 3) & 0xf8) | /* l */
508 ((srcval
>> 2) & 0x07); /* l - 3 bits */
509 dstpixel
[1]=((srcval
>> 2) & 0xf8) | /* g */
510 ((srcval
>> 7) & 0x07); /* g - 3 bits */
511 dstpixel
[2]=((srcval
>> 7) & 0xf8) | /* h */
512 ((srcval
>> 12) & 0x07); /* h - 3 bits */
515 srcbits
= (char*)srcbits
+ srclinebytes
;
516 dstbits
= (char*)dstbits
+ dstlinebytes
;
520 static void X11DRV_DIB_Convert_555_to_888_reverse(int width
, int height
,
521 const void* srcbits
, int srclinebytes
,
522 void* dstbits
, int dstlinebytes
)
524 const WORD
* srcpixel
;
528 for (y
=0; y
<height
; y
++) {
531 for (x
=0; x
<width
; x
++) {
534 dstpixel
[0]=((srcval
>> 7) & 0xf8) | /* h */
535 ((srcval
>> 12) & 0x07); /* h - 3 bits */
536 dstpixel
[1]=((srcval
>> 2) & 0xf8) | /* g */
537 ((srcval
>> 7) & 0x07); /* g - 3 bits */
538 dstpixel
[2]=((srcval
<< 3) & 0xf8) | /* l */
539 ((srcval
>> 2) & 0x07); /* l - 3 bits */
542 srcbits
= (char*)srcbits
+ srclinebytes
;
543 dstbits
= (char*)dstbits
+ dstlinebytes
;
547 static void X11DRV_DIB_Convert_555_to_0888_asis(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
<< 9) & 0xf80000) | /* h */
562 ((srcval
<< 4) & 0x070000) | /* h - 3 bits */
563 ((srcval
<< 6) & 0x00f800) | /* g */
564 ((srcval
<< 1) & 0x000700) | /* g - 3 bits */
565 ((srcval
<< 3) & 0x0000f8) | /* l */
566 ((srcval
>> 2) & 0x000007); /* l - 3 bits */
568 srcbits
= (char*)srcbits
+ srclinebytes
;
569 dstbits
= (char*)dstbits
+ dstlinebytes
;
573 static void X11DRV_DIB_Convert_555_to_0888_reverse(int width
, int height
,
574 const void* srcbits
, int srclinebytes
,
575 void* dstbits
, int dstlinebytes
)
577 const WORD
* srcpixel
;
581 for (y
=0; y
<height
; y
++) {
584 for (x
=0; x
<width
; x
++) {
587 *dstpixel
++=((srcval
>> 7) & 0x0000f8) | /* h */
588 ((srcval
>> 12) & 0x000007) | /* h - 3 bits */
589 ((srcval
<< 6) & 0x00f800) | /* g */
590 ((srcval
<< 1) & 0x000700) | /* g - 3 bits */
591 ((srcval
<< 19) & 0xf80000) | /* l */
592 ((srcval
<< 14) & 0x070000); /* l - 3 bits */
594 srcbits
= (char*)srcbits
+ srclinebytes
;
595 dstbits
= (char*)dstbits
+ dstlinebytes
;
599 static void X11DRV_DIB_Convert_5x5_to_any0888(int width
, int height
,
600 const void* srcbits
, int srclinebytes
,
601 WORD rsrc
, WORD gsrc
, WORD bsrc
,
602 void* dstbits
, int dstlinebytes
,
603 DWORD rdst
, DWORD gdst
, DWORD bdst
)
605 int rRightShift1
,gRightShift1
,bRightShift1
;
606 int rRightShift2
,gRightShift2
,bRightShift2
;
608 int rLeftShift
,gLeftShift
,bLeftShift
;
609 const WORD
* srcpixel
;
613 /* Note, the source pixel value is shifted left by 16 bits so that
614 * we know we will always have to shift right to extract the components.
616 rRightShift1
=16+X11DRV_DIB_MaskToShift(rsrc
)-3;
617 gRightShift1
=16+X11DRV_DIB_MaskToShift(gsrc
)-3;
618 bRightShift1
=16+X11DRV_DIB_MaskToShift(bsrc
)-3;
619 rRightShift2
=rRightShift1
+5;
620 gRightShift2
=gRightShift1
+5;
621 bRightShift2
=bRightShift1
+5;
623 /* Green has 5 bits, like the others */
627 /* Green has 6 bits, not 5. Compensate. */
634 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
635 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
636 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
638 for (y
=0; y
<height
; y
++) {
641 for (x
=0; x
<width
; x
++) {
644 srcval
=*srcpixel
++ << 16;
645 red
= ((srcval
>> rRightShift1
) & 0xf8) |
646 ((srcval
>> rRightShift2
) & 0x07);
647 green
=((srcval
>> gRightShift1
) & gMask1
) |
648 ((srcval
>> gRightShift2
) & gMask2
);
649 blue
= ((srcval
>> bRightShift1
) & 0xf8) |
650 ((srcval
>> bRightShift2
) & 0x07);
651 *dstpixel
++=(red
<< rLeftShift
) |
652 (green
<< gLeftShift
) |
653 (blue
<< bLeftShift
);
655 srcbits
= (char*)srcbits
+ srclinebytes
;
656 dstbits
= (char*)dstbits
+ dstlinebytes
;
661 * 16 bits conversions
664 static void X11DRV_DIB_Convert_565_reverse(int width
, int height
,
665 const void* srcbits
, int srclinebytes
,
666 void* dstbits
, int dstlinebytes
)
668 const DWORD
* srcpixel
;
672 for (y
=0; y
<height
; y
++) {
675 for (x
=0; x
<width
/2; x
++) {
676 /* Do 2 pixels at a time */
679 *dstpixel
++=((srcval
<< 11) & 0xf800f800) | /* h */
680 ( srcval
& 0x07e007e0) | /* g */
681 ((srcval
>> 11) & 0x001f001f); /* l */
684 /* And the the odd pixel */
686 srcval
=*((WORD
*)srcpixel
);
687 *((WORD
*)dstpixel
)=((srcval
<< 11) & 0xf800) | /* h */
688 ( srcval
& 0x07e0) | /* g */
689 ((srcval
>> 11) & 0x001f); /* l */
691 srcbits
= (char*)srcbits
+ srclinebytes
;
692 dstbits
= (char*)dstbits
+ dstlinebytes
;
696 static void X11DRV_DIB_Convert_565_to_555_asis(int width
, int height
,
697 const void* srcbits
, int srclinebytes
,
698 void* dstbits
, int dstlinebytes
)
700 const DWORD
* srcpixel
;
704 for (y
=0; y
<height
; y
++) {
707 for (x
=0; x
<width
/2; x
++) {
708 /* Do 2 pixels at a time */
711 *dstpixel
++=((srcval
>> 1) & 0x7fe07fe0) | /* h, g */
712 ( srcval
& 0x001f001f); /* l */
715 /* And the the odd pixel */
717 srcval
=*((WORD
*)srcpixel
);
718 *((WORD
*)dstpixel
)=((srcval
>> 1) & 0x7fe0) | /* h, g */
719 ( srcval
& 0x001f); /* l */
721 srcbits
= (char*)srcbits
+ srclinebytes
;
722 dstbits
= (char*)dstbits
+ dstlinebytes
;
726 static void X11DRV_DIB_Convert_565_to_555_reverse(int width
, int height
,
727 const void* srcbits
, int srclinebytes
,
728 void* dstbits
, int dstlinebytes
)
730 const DWORD
* srcpixel
;
734 for (y
=0; y
<height
; y
++) {
737 for (x
=0; x
<width
/2; x
++) {
738 /* Do 2 pixels at a time */
741 *dstpixel
++=((srcval
>> 11) & 0x001f001f) | /* h */
742 ((srcval
>> 1) & 0x03e003e0) | /* g */
743 ((srcval
<< 10) & 0x7c007c00); /* l */
746 /* And the the odd pixel */
748 srcval
=*((WORD
*)srcpixel
);
749 *((WORD
*)dstpixel
)=((srcval
>> 11) & 0x001f) | /* h */
750 ((srcval
>> 1) & 0x03e0) | /* g */
751 ((srcval
<< 10) & 0x7c00); /* l */
753 srcbits
= (char*)srcbits
+ srclinebytes
;
754 dstbits
= (char*)dstbits
+ dstlinebytes
;
758 static void X11DRV_DIB_Convert_565_to_888_asis(int width
, int height
,
759 const void* srcbits
, int srclinebytes
,
760 void* dstbits
, int dstlinebytes
)
762 const WORD
* srcpixel
;
766 for (y
=0; y
<height
; y
++) {
769 for (x
=0; x
<width
; x
++) {
772 dstpixel
[0]=((srcval
<< 3) & 0xf8) | /* l */
773 ((srcval
>> 2) & 0x07); /* l - 3 bits */
774 dstpixel
[1]=((srcval
>> 3) & 0xfc) | /* g */
775 ((srcval
>> 9) & 0x03); /* g - 2 bits */
776 dstpixel
[2]=((srcval
>> 8) & 0xf8) | /* h */
777 ((srcval
>> 13) & 0x07); /* h - 3 bits */
780 srcbits
= (char*)srcbits
+ srclinebytes
;
781 dstbits
= (char*)dstbits
+ dstlinebytes
;
785 static void X11DRV_DIB_Convert_565_to_888_reverse(int width
, int height
,
786 const void* srcbits
, int srclinebytes
,
787 void* dstbits
, int dstlinebytes
)
789 const WORD
* srcpixel
;
793 for (y
=0; y
<height
; y
++) {
796 for (x
=0; x
<width
; x
++) {
799 dstpixel
[0]=((srcval
>> 8) & 0xf8) | /* h */
800 ((srcval
>> 13) & 0x07); /* h - 3 bits */
801 dstpixel
[1]=((srcval
>> 3) & 0xfc) | /* g */
802 ((srcval
>> 9) & 0x03); /* g - 2 bits */
803 dstpixel
[2]=((srcval
<< 3) & 0xf8) | /* l */
804 ((srcval
>> 2) & 0x07); /* l - 3 bits */
807 srcbits
= (char*)srcbits
+ srclinebytes
;
808 dstbits
= (char*)dstbits
+ dstlinebytes
;
812 static void X11DRV_DIB_Convert_565_to_0888_asis(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) & 0xf80000) | /* h */
827 ((srcval
<< 3) & 0x070000) | /* h - 3 bits */
828 ((srcval
<< 5) & 0x00fc00) | /* g */
829 ((srcval
>> 1) & 0x000300) | /* g - 2 bits */
830 ((srcval
<< 3) & 0x0000f8) | /* l */
831 ((srcval
>> 2) & 0x000007); /* l - 3 bits */
833 srcbits
= (char*)srcbits
+ srclinebytes
;
834 dstbits
= (char*)dstbits
+ dstlinebytes
;
838 static void X11DRV_DIB_Convert_565_to_0888_reverse(int width
, int height
,
839 const void* srcbits
, int srclinebytes
,
840 void* dstbits
, int dstlinebytes
)
842 const WORD
* srcpixel
;
846 for (y
=0; y
<height
; y
++) {
849 for (x
=0; x
<width
; x
++) {
852 *dstpixel
++=((srcval
>> 8) & 0x0000f8) | /* h */
853 ((srcval
>> 13) & 0x000007) | /* h - 3 bits */
854 ((srcval
<< 5) & 0x00fc00) | /* g */
855 ((srcval
>> 1) & 0x000300) | /* g - 2 bits */
856 ((srcval
<< 19) & 0xf80000) | /* l */
857 ((srcval
<< 14) & 0x070000); /* l - 3 bits */
859 srcbits
= (char*)srcbits
+ srclinebytes
;
860 dstbits
= (char*)dstbits
+ dstlinebytes
;
868 static void X11DRV_DIB_Convert_888_reverse(int width
, int height
,
869 const void* srcbits
, int srclinebytes
,
870 void* dstbits
, int dstlinebytes
)
872 const BYTE
* srcpixel
;
876 for (y
=0; y
<height
; y
++) {
879 for (x
=0; x
<width
; x
++) {
880 dstpixel
[0]=srcpixel
[2];
881 dstpixel
[1]=srcpixel
[1];
882 dstpixel
[2]=srcpixel
[0];
886 srcbits
= (char*)srcbits
+ srclinebytes
;
887 dstbits
= (char*)dstbits
+ dstlinebytes
;
891 static void X11DRV_DIB_Convert_888_to_555_asis(int width
, int height
,
892 const void* srcbits
, int srclinebytes
,
893 void* dstbits
, int dstlinebytes
)
895 const DWORD
* srcpixel
;
903 for (y
=0; y
<height
; y
++) {
906 for (x
=0; x
<width
; x
++) {
907 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
908 DWORD srcval1
,srcval2
;
910 dstpixel
[0]=((srcval1
>> 3) & 0x001f) | /* l1 */
911 ((srcval1
>> 6) & 0x03e0) | /* g1 */
912 ((srcval1
>> 9) & 0x7c00); /* h1 */
914 dstpixel
[1]=((srcval1
>> 27) & 0x001f) | /* l2 */
915 ((srcval2
<< 2) & 0x03e0) | /* g2 */
916 ((srcval2
>> 1) & 0x7c00); /* h2 */
918 dstpixel
[2]=((srcval2
>> 19) & 0x001f) | /* l3 */
919 ((srcval2
>> 22) & 0x03e0) | /* g3 */
920 ((srcval1
<< 7) & 0x7c00); /* h3 */
921 dstpixel
[3]=((srcval1
>> 11) & 0x001f) | /* l4 */
922 ((srcval1
>> 14) & 0x03e0) | /* g4 */
923 ((srcval1
>> 17) & 0x7c00); /* h4 */
927 /* And now up to 3 odd pixels */
928 srcbyte
=(LPBYTE
)srcpixel
;
929 for (x
=0; x
<oddwidth
; x
++) {
931 dstval
=((srcbyte
[0] >> 3) & 0x001f); /* l */
932 dstval
|=((srcbyte
[1] << 2) & 0x03e0); /* g */
933 dstval
|=((srcbyte
[2] << 7) & 0x7c00); /* h */
937 srcbits
= (char*)srcbits
+ srclinebytes
;
938 dstbits
= (char*)dstbits
+ dstlinebytes
;
942 static void X11DRV_DIB_Convert_888_to_555_reverse(int width
, int height
,
943 const void* srcbits
, int srclinebytes
,
944 void* dstbits
, int dstlinebytes
)
946 const DWORD
* srcpixel
;
954 for (y
=0; y
<height
; y
++) {
957 for (x
=0; x
<width
; x
++) {
958 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
959 DWORD srcval1
,srcval2
;
961 dstpixel
[0]=((srcval1
<< 7) & 0x7c00) | /* l1 */
962 ((srcval1
>> 6) & 0x03e0) | /* g1 */
963 ((srcval1
>> 19) & 0x001f); /* h1 */
965 dstpixel
[1]=((srcval1
>> 17) & 0x7c00) | /* l2 */
966 ((srcval2
<< 2) & 0x03e0) | /* g2 */
967 ((srcval2
>> 11) & 0x001f); /* h2 */
969 dstpixel
[2]=((srcval2
>> 9) & 0x7c00) | /* l3 */
970 ((srcval2
>> 22) & 0x03e0) | /* g3 */
971 ((srcval1
>> 3) & 0x001f); /* h3 */
972 dstpixel
[3]=((srcval1
>> 1) & 0x7c00) | /* l4 */
973 ((srcval1
>> 14) & 0x03e0) | /* g4 */
974 ((srcval1
>> 27) & 0x001f); /* h4 */
978 /* And now up to 3 odd pixels */
979 srcbyte
=(LPBYTE
)srcpixel
;
980 for (x
=0; x
<oddwidth
; x
++) {
982 dstval
=((srcbyte
[0] << 7) & 0x7c00); /* l */
983 dstval
|=((srcbyte
[1] << 2) & 0x03e0); /* g */
984 dstval
|=((srcbyte
[2] >> 3) & 0x001f); /* h */
988 srcbits
= (char*)srcbits
+ srclinebytes
;
989 dstbits
= (char*)dstbits
+ dstlinebytes
;
993 static void X11DRV_DIB_Convert_888_to_565_asis(int width
, int height
,
994 const void* srcbits
, int srclinebytes
,
995 void* dstbits
, int dstlinebytes
)
997 const DWORD
* srcpixel
;
1005 for (y
=0; y
<height
; y
++) {
1008 for (x
=0; x
<width
; x
++) {
1009 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
1010 DWORD srcval1
,srcval2
;
1011 srcval1
=srcpixel
[0];
1012 dstpixel
[0]=((srcval1
>> 3) & 0x001f) | /* l1 */
1013 ((srcval1
>> 5) & 0x07e0) | /* g1 */
1014 ((srcval1
>> 8) & 0xf800); /* h1 */
1015 srcval2
=srcpixel
[1];
1016 dstpixel
[1]=((srcval1
>> 27) & 0x001f) | /* l2 */
1017 ((srcval2
<< 3) & 0x07e0) | /* g2 */
1018 ( srcval2
& 0xf800); /* h2 */
1019 srcval1
=srcpixel
[2];
1020 dstpixel
[2]=((srcval2
>> 19) & 0x001f) | /* l3 */
1021 ((srcval2
>> 21) & 0x07e0) | /* g3 */
1022 ((srcval1
<< 8) & 0xf800); /* h3 */
1023 dstpixel
[3]=((srcval1
>> 11) & 0x001f) | /* l4 */
1024 ((srcval1
>> 13) & 0x07e0) | /* g4 */
1025 ((srcval1
>> 16) & 0xf800); /* h4 */
1029 /* And now up to 3 odd pixels */
1030 srcbyte
=(LPBYTE
)srcpixel
;
1031 for (x
=0; x
<oddwidth
; x
++) {
1033 dstval
=((srcbyte
[0] >> 3) & 0x001f); /* l */
1034 dstval
|=((srcbyte
[1] << 3) & 0x07e0); /* g */
1035 dstval
|=((srcbyte
[2] << 8) & 0xf800); /* h */
1039 srcbits
= (char*)srcbits
+ srclinebytes
;
1040 dstbits
= (char*)dstbits
+ dstlinebytes
;
1044 static void X11DRV_DIB_Convert_888_to_565_reverse(int width
, int height
,
1045 const void* srcbits
, int srclinebytes
,
1046 void* dstbits
, int dstlinebytes
)
1048 const DWORD
* srcpixel
;
1049 const BYTE
* srcbyte
;
1056 for (y
=0; y
<height
; y
++) {
1059 for (x
=0; x
<width
; x
++) {
1060 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
1061 DWORD srcval1
,srcval2
;
1062 srcval1
=srcpixel
[0];
1063 dstpixel
[0]=((srcval1
<< 8) & 0xf800) | /* l1 */
1064 ((srcval1
>> 5) & 0x07e0) | /* g1 */
1065 ((srcval1
>> 19) & 0x001f); /* h1 */
1066 srcval2
=srcpixel
[1];
1067 dstpixel
[1]=((srcval1
>> 16) & 0xf800) | /* l2 */
1068 ((srcval2
<< 3) & 0x07e0) | /* g2 */
1069 ((srcval2
>> 11) & 0x001f); /* h2 */
1070 srcval1
=srcpixel
[2];
1071 dstpixel
[2]=((srcval2
>> 8) & 0xf800) | /* l3 */
1072 ((srcval2
>> 21) & 0x07e0) | /* g3 */
1073 ((srcval1
>> 3) & 0x001f); /* h3 */
1074 dstpixel
[3]=(srcval1
& 0xf800) | /* l4 */
1075 ((srcval1
>> 13) & 0x07e0) | /* g4 */
1076 ((srcval1
>> 27) & 0x001f); /* h4 */
1080 /* And now up to 3 odd pixels */
1081 srcbyte
=(LPBYTE
)srcpixel
;
1082 for (x
=0; x
<oddwidth
; x
++) {
1084 dstval
=((srcbyte
[0] << 8) & 0xf800); /* l */
1085 dstval
|=((srcbyte
[1] << 3) & 0x07e0); /* g */
1086 dstval
|=((srcbyte
[2] >> 3) & 0x001f); /* h */
1090 srcbits
= (char*)srcbits
+ srclinebytes
;
1091 dstbits
= (char*)dstbits
+ dstlinebytes
;
1095 static void X11DRV_DIB_Convert_888_to_0888_asis(int width
, int height
,
1096 const void* srcbits
, int srclinebytes
,
1097 void* dstbits
, int dstlinebytes
)
1099 const DWORD
* srcpixel
;
1106 for (y
=0; y
<height
; y
++) {
1109 for (x
=0; x
<width
; x
++) {
1110 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1111 DWORD srcval1
,srcval2
;
1112 srcval1
=srcpixel
[0];
1113 dstpixel
[0]=( srcval1
& 0x00ffffff); /* h1, g1, l1 */
1114 srcval2
=srcpixel
[1];
1115 dstpixel
[1]=( srcval1
>> 24) | /* l2 */
1116 ((srcval2
<< 8) & 0x00ffff00); /* h2, g2 */
1117 srcval1
=srcpixel
[2];
1118 dstpixel
[2]=( srcval2
>> 16) | /* g3, l3 */
1119 ((srcval1
<< 16) & 0x00ff0000); /* h3 */
1120 dstpixel
[3]=( srcval1
>> 8); /* h4, g4, l4 */
1124 /* And now up to 3 odd pixels */
1125 for (x
=0; x
<oddwidth
; x
++) {
1128 srcpixel
=(LPDWORD
)(((char*)srcpixel
)+3);
1129 *dstpixel
++=( srcval
& 0x00ffffff); /* h, g, l */
1131 srcbits
= (char*)srcbits
+ srclinebytes
;
1132 dstbits
= (char*)dstbits
+ dstlinebytes
;
1136 static void X11DRV_DIB_Convert_888_to_0888_reverse(int width
, int height
,
1137 const void* srcbits
, int srclinebytes
,
1138 void* dstbits
, int dstlinebytes
)
1140 const DWORD
* srcpixel
;
1147 for (y
=0; y
<height
; y
++) {
1150 for (x
=0; x
<width
; x
++) {
1151 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1152 DWORD srcval1
,srcval2
;
1154 srcval1
=srcpixel
[0];
1155 dstpixel
[0]=((srcval1
>> 16) & 0x0000ff) | /* h1 */
1156 ( srcval1
& 0x00ff00) | /* g1 */
1157 ((srcval1
<< 16) & 0xff0000); /* l1 */
1158 srcval2
=srcpixel
[1];
1159 dstpixel
[1]=((srcval1
>> 8) & 0xff0000) | /* l2 */
1160 ((srcval2
<< 8) & 0x00ff00) | /* g2 */
1161 ((srcval2
>> 8) & 0x0000ff); /* h2 */
1162 srcval1
=srcpixel
[2];
1163 dstpixel
[2]=( srcval2
& 0xff0000) | /* l3 */
1164 ((srcval2
>> 16) & 0x00ff00) | /* g3 */
1165 ( srcval1
& 0x0000ff); /* h3 */
1166 dstpixel
[3]=((srcval1
>> 24) & 0x0000ff) | /* h4 */
1167 ((srcval1
>> 8) & 0x00ff00) | /* g4 */
1168 ((srcval1
<< 8) & 0xff0000); /* l4 */
1172 /* And now up to 3 odd pixels */
1173 for (x
=0; x
<oddwidth
; x
++) {
1176 srcpixel
=(LPDWORD
)(((char*)srcpixel
)+3);
1177 *dstpixel
++=((srcval
>> 16) & 0x0000ff) | /* h */
1178 ( srcval
& 0x00ff00) | /* g */
1179 ((srcval
<< 16) & 0xff0000); /* l */
1181 srcbits
= (char*)srcbits
+ srclinebytes
;
1182 dstbits
= (char*)dstbits
+ dstlinebytes
;
1186 static void X11DRV_DIB_Convert_rgb888_to_any0888(int width
, int height
,
1187 const void* srcbits
, int srclinebytes
,
1188 void* dstbits
, int dstlinebytes
,
1189 DWORD rdst
, DWORD gdst
, DWORD bdst
)
1191 int rLeftShift
,gLeftShift
,bLeftShift
;
1192 const BYTE
* srcpixel
;
1196 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
1197 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
1198 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
1199 for (y
=0; y
<height
; y
++) {
1202 for (x
=0; x
<width
; x
++) {
1203 *dstpixel
++=(srcpixel
[0] << bLeftShift
) | /* b */
1204 (srcpixel
[1] << gLeftShift
) | /* g */
1205 (srcpixel
[2] << rLeftShift
); /* r */
1208 srcbits
= (char*)srcbits
+ srclinebytes
;
1209 dstbits
= (char*)dstbits
+ dstlinebytes
;
1213 static void X11DRV_DIB_Convert_bgr888_to_any0888(int width
, int height
,
1214 const void* srcbits
, int srclinebytes
,
1215 void* dstbits
, int dstlinebytes
,
1216 DWORD rdst
, DWORD gdst
, DWORD bdst
)
1218 int rLeftShift
,gLeftShift
,bLeftShift
;
1219 const BYTE
* srcpixel
;
1223 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
1224 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
1225 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
1226 for (y
=0; y
<height
; y
++) {
1229 for (x
=0; x
<width
; x
++) {
1230 *dstpixel
++=(srcpixel
[0] << rLeftShift
) | /* r */
1231 (srcpixel
[1] << gLeftShift
) | /* g */
1232 (srcpixel
[2] << bLeftShift
); /* b */
1235 srcbits
= (char*)srcbits
+ srclinebytes
;
1236 dstbits
= (char*)dstbits
+ dstlinebytes
;
1241 * 32 bit conversions
1244 static void X11DRV_DIB_Convert_0888_reverse(int width
, int height
,
1245 const void* srcbits
, int srclinebytes
,
1246 void* dstbits
, int dstlinebytes
)
1248 const DWORD
* srcpixel
;
1252 for (y
=0; y
<height
; y
++) {
1255 for (x
=0; x
<width
; x
++) {
1258 *dstpixel
++=((srcval
<< 16) & 0x00ff0000) | /* h */
1259 ( srcval
& 0x0000ff00) | /* g */
1260 ((srcval
>> 16) & 0x000000ff); /* l */
1262 srcbits
= (char*)srcbits
+ srclinebytes
;
1263 dstbits
= (char*)dstbits
+ dstlinebytes
;
1267 static void X11DRV_DIB_Convert_0888_any(int width
, int height
,
1268 const void* srcbits
, int srclinebytes
,
1269 DWORD rsrc
, DWORD gsrc
, DWORD bsrc
,
1270 void* dstbits
, int dstlinebytes
,
1271 DWORD rdst
, DWORD gdst
, DWORD bdst
)
1273 int rRightShift
,gRightShift
,bRightShift
;
1274 int rLeftShift
,gLeftShift
,bLeftShift
;
1275 const DWORD
* srcpixel
;
1279 rRightShift
=X11DRV_DIB_MaskToShift(rsrc
);
1280 gRightShift
=X11DRV_DIB_MaskToShift(gsrc
);
1281 bRightShift
=X11DRV_DIB_MaskToShift(bsrc
);
1282 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
1283 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
1284 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
1285 for (y
=0; y
<height
; y
++) {
1288 for (x
=0; x
<width
; x
++) {
1291 *dstpixel
++=(((srcval
>> rRightShift
) & 0xff) << rLeftShift
) |
1292 (((srcval
>> gRightShift
) & 0xff) << gLeftShift
) |
1293 (((srcval
>> bRightShift
) & 0xff) << bLeftShift
);
1295 srcbits
= (char*)srcbits
+ srclinebytes
;
1296 dstbits
= (char*)dstbits
+ dstlinebytes
;
1300 static void X11DRV_DIB_Convert_0888_to_555_asis(int width
, int height
,
1301 const void* srcbits
, int srclinebytes
,
1302 void* dstbits
, int dstlinebytes
)
1304 const DWORD
* srcpixel
;
1308 for (y
=0; y
<height
; y
++) {
1311 for (x
=0; x
<width
; x
++) {
1314 *dstpixel
++=((srcval
>> 9) & 0x7c00) | /* h */
1315 ((srcval
>> 6) & 0x03e0) | /* g */
1316 ((srcval
>> 3) & 0x001f); /* l */
1318 srcbits
= (char*)srcbits
+ srclinebytes
;
1319 dstbits
= (char*)dstbits
+ dstlinebytes
;
1323 static void X11DRV_DIB_Convert_0888_to_555_reverse(int width
, int height
,
1324 const void* srcbits
, int srclinebytes
,
1325 void* dstbits
, int dstlinebytes
)
1327 const DWORD
* srcpixel
;
1331 for (y
=0; y
<height
; y
++) {
1334 for (x
=0; x
<width
; x
++) {
1337 *dstpixel
++=((srcval
>> 19) & 0x001f) | /* h */
1338 ((srcval
>> 6) & 0x03e0) | /* g */
1339 ((srcval
<< 7) & 0x7c00); /* l */
1341 srcbits
= (char*)srcbits
+ srclinebytes
;
1342 dstbits
= (char*)dstbits
+ dstlinebytes
;
1346 static void X11DRV_DIB_Convert_0888_to_565_asis(int width
, int height
,
1347 const void* srcbits
, int srclinebytes
,
1348 void* dstbits
, int dstlinebytes
)
1350 const DWORD
* srcpixel
;
1354 for (y
=0; y
<height
; y
++) {
1357 for (x
=0; x
<width
; x
++) {
1360 *dstpixel
++=((srcval
>> 8) & 0xf800) | /* h */
1361 ((srcval
>> 5) & 0x07e0) | /* g */
1362 ((srcval
>> 3) & 0x001f); /* l */
1364 srcbits
= (char*)srcbits
+ srclinebytes
;
1365 dstbits
= (char*)dstbits
+ dstlinebytes
;
1369 static void X11DRV_DIB_Convert_0888_to_565_reverse(int width
, int height
,
1370 const void* srcbits
, int srclinebytes
,
1371 void* dstbits
, int dstlinebytes
)
1373 const DWORD
* srcpixel
;
1377 for (y
=0; y
<height
; y
++) {
1380 for (x
=0; x
<width
; x
++) {
1383 *dstpixel
++=((srcval
>> 19) & 0x001f) | /* h */
1384 ((srcval
>> 5) & 0x07e0) | /* g */
1385 ((srcval
<< 8) & 0xf800); /* l */
1387 srcbits
= (char*)srcbits
+ srclinebytes
;
1388 dstbits
= (char*)dstbits
+ dstlinebytes
;
1392 static void X11DRV_DIB_Convert_any0888_to_5x5(int width
, int height
,
1393 const void* srcbits
, int srclinebytes
,
1394 DWORD rsrc
, DWORD gsrc
, DWORD bsrc
,
1395 void* dstbits
, int dstlinebytes
,
1396 WORD rdst
, WORD gdst
, WORD bdst
)
1398 int rRightShift
,gRightShift
,bRightShift
;
1399 int rLeftShift
,gLeftShift
,bLeftShift
;
1400 const DWORD
* srcpixel
;
1404 /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel
1405 * contains 0x11223344.
1406 * - first we shift 0x11223344 right by rRightShift to bring the most
1407 * significant bits of the red components in the bottom 5 (or 6) bits
1409 * - then we remove non red bits by anding with the modified rdst (0x1f)
1411 * - finally shift these bits left by rLeftShift so that they end up in
1415 rRightShift
=X11DRV_DIB_MaskToShift(rsrc
)+3;
1416 gRightShift
=X11DRV_DIB_MaskToShift(gsrc
);
1417 gRightShift
+=(gdst
==0x07e0?2:3);
1418 bRightShift
=X11DRV_DIB_MaskToShift(bsrc
)+3;
1420 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
1421 rdst
=rdst
>> rLeftShift
;
1422 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
1423 gdst
=gdst
>> gLeftShift
;
1424 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
1425 bdst
=bdst
>> bLeftShift
;
1427 for (y
=0; y
<height
; y
++) {
1430 for (x
=0; x
<width
; x
++) {
1433 *dstpixel
++=(((srcval
>> rRightShift
) & rdst
) << rLeftShift
) |
1434 (((srcval
>> gRightShift
) & gdst
) << gLeftShift
) |
1435 (((srcval
>> bRightShift
) & bdst
) << bLeftShift
);
1437 srcbits
= (char*)srcbits
+ srclinebytes
;
1438 dstbits
= (char*)dstbits
+ dstlinebytes
;
1442 static void X11DRV_DIB_Convert_0888_to_888_asis(int width
, int height
,
1443 const void* srcbits
, int srclinebytes
,
1444 void* dstbits
, int dstlinebytes
)
1446 const DWORD
* srcpixel
;
1454 for (y
=0; y
<height
; y
++) {
1457 for (x
=0; x
<width
; x
++) {
1458 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1460 srcval
=((*srcpixel
++) & 0x00ffffff); /* h1, g1, l1*/
1461 *dstpixel
++=srcval
| ((*srcpixel
) << 24); /* h2 */
1462 srcval
=((*srcpixel
++ >> 8 ) & 0x0000ffff); /* g2, l2 */
1463 *dstpixel
++=srcval
| ((*srcpixel
) << 16); /* h3, g3 */
1464 srcval
=((*srcpixel
++ >> 16) & 0x000000ff); /* l3 */
1465 *dstpixel
++=srcval
| ((*srcpixel
++) << 8); /* h4, g4, l4 */
1467 /* And now up to 3 odd pixels */
1468 dstbyte
=(BYTE
*)dstpixel
;
1469 for (x
=0; x
<oddwidth
; x
++) {
1472 *((WORD
*)dstbyte
)++=srcval
; /* h, g */
1473 *dstbyte
++=srcval
>> 16; /* l */
1475 srcbits
= (char*)srcbits
+ srclinebytes
;
1476 dstbits
= (char*)dstbits
+ dstlinebytes
;
1480 static void X11DRV_DIB_Convert_0888_to_888_reverse(int width
, int height
,
1481 const void* srcbits
, int srclinebytes
,
1482 void* dstbits
, int dstlinebytes
)
1484 const DWORD
* srcpixel
;
1492 for (y
=0; y
<height
; y
++) {
1495 for (x
=0; x
<width
; x
++) {
1496 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1497 DWORD srcval1
,srcval2
;
1498 srcval1
=*srcpixel
++;
1499 srcval2
= ((srcval1
>> 16) & 0x000000ff) | /* h1 */
1500 ( srcval1
& 0x0000ff00) | /* g1 */
1501 ((srcval1
<< 16) & 0x00ff0000); /* l1 */
1502 srcval1
=*srcpixel
++;
1503 *dstpixel
++=srcval2
|
1504 ((srcval1
<< 8) & 0xff000000); /* h2 */
1505 srcval2
= ((srcval1
>> 8) & 0x000000ff) | /* g2 */
1506 ((srcval1
<< 8) & 0x0000ff00); /* l2 */
1507 srcval1
=*srcpixel
++;
1508 *dstpixel
++=srcval2
|
1509 ( srcval1
& 0x00ff0000) | /* h3 */
1510 ((srcval1
<< 16) & 0xff000000); /* g3 */
1511 srcval2
= ( srcval1
& 0x000000ff); /* l3 */
1512 srcval1
=*srcpixel
++;
1513 *dstpixel
++=srcval2
|
1514 ((srcval1
>> 8) & 0x0000ff00) | /* h4 */
1515 ((srcval1
<< 8) & 0x00ff0000) | /* g4 */
1516 ( srcval1
<< 24); /* l4 */
1518 /* And now up to 3 odd pixels */
1519 dstbyte
=(BYTE
*)dstpixel
;
1520 for (x
=0; x
<oddwidth
; x
++) {
1523 *((WORD
*)dstbyte
)++=((srcval
>> 16) & 0x00ff) | /* h */
1524 (srcval
& 0xff00); /* g */
1525 *dstbyte
++=srcval
; /* l */
1527 srcbits
= (char*)srcbits
+ srclinebytes
;
1528 dstbits
= (char*)dstbits
+ dstlinebytes
;
1532 static void X11DRV_DIB_Convert_any0888_to_rgb888(int width
, int height
,
1533 const void* srcbits
, int srclinebytes
,
1534 DWORD rsrc
, DWORD gsrc
, DWORD bsrc
,
1535 void* dstbits
, int dstlinebytes
)
1537 int rRightShift
,gRightShift
,bRightShift
;
1538 const DWORD
* srcpixel
;
1542 rRightShift
=X11DRV_DIB_MaskToShift(rsrc
);
1543 gRightShift
=X11DRV_DIB_MaskToShift(gsrc
);
1544 bRightShift
=X11DRV_DIB_MaskToShift(bsrc
);
1545 for (y
=0; y
<height
; y
++) {
1548 for (x
=0; x
<width
; x
++) {
1551 dstpixel
[0]=(srcval
>> bRightShift
); /* b */
1552 dstpixel
[1]=(srcval
>> gRightShift
); /* g */
1553 dstpixel
[2]=(srcval
>> rRightShift
); /* r */
1556 srcbits
= (char*)srcbits
+ srclinebytes
;
1557 dstbits
= (char*)dstbits
+ dstlinebytes
;
1561 static void X11DRV_DIB_Convert_any0888_to_bgr888(int width
, int height
,
1562 const void* srcbits
, int srclinebytes
,
1563 DWORD rsrc
, DWORD gsrc
, DWORD bsrc
,
1564 void* dstbits
, int dstlinebytes
)
1566 int rRightShift
,gRightShift
,bRightShift
;
1567 const DWORD
* srcpixel
;
1571 rRightShift
=X11DRV_DIB_MaskToShift(rsrc
);
1572 gRightShift
=X11DRV_DIB_MaskToShift(gsrc
);
1573 bRightShift
=X11DRV_DIB_MaskToShift(bsrc
);
1574 for (y
=0; y
<height
; y
++) {
1577 for (x
=0; x
<width
; x
++) {
1580 dstpixel
[0]=(srcval
>> rRightShift
); /* r */
1581 dstpixel
[1]=(srcval
>> gRightShift
); /* g */
1582 dstpixel
[2]=(srcval
>> bRightShift
); /* b */
1585 srcbits
= (char*)srcbits
+ srclinebytes
;
1586 dstbits
= (char*)dstbits
+ dstlinebytes
;
1590 /***********************************************************************
1591 * X11DRV_DIB_SetImageBits_1
1593 * SetDIBits for a 1-bit deep DIB.
1595 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
1596 DWORD srcwidth
, DWORD dstwidth
, int left
,
1597 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
1600 const BYTE
* srcbyte
;
1606 srcbits
= srcbits
+ linebytes
* (lines
- 1);
1607 linebytes
= -linebytes
;
1610 if ((extra
= (left
& 7)) != 0) {
1614 srcbits
+= left
>> 3;
1616 /* ==== pal 1 dib -> any bmp format ==== */
1617 for (h
= lines
-1; h
>=0; h
--) {
1619 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
1620 for (i
= dstwidth
/8, x
= left
; i
> 0; i
--) {
1622 XPutPixel( bmpImage
, x
++, h
, colors
[ srcval
>> 7] );
1623 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 6) & 1] );
1624 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 5) & 1] );
1625 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 4) & 1] );
1626 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 3) & 1] );
1627 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 2) & 1] );
1628 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 1) & 1] );
1629 XPutPixel( bmpImage
, x
++, h
, colors
[ srcval
& 1] );
1632 switch (dstwidth
& 7)
1634 case 7: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1635 case 6: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1636 case 5: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1637 case 4: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1638 case 3: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1639 case 2: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1640 case 1: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]);
1642 srcbits
+= linebytes
;
1646 /***********************************************************************
1647 * X11DRV_DIB_GetImageBits_1
1649 * GetDIBits for a 1-bit deep DIB.
1651 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
1652 DWORD dstwidth
, DWORD srcwidth
,
1653 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
1654 XImage
*bmpImage
, DWORD linebytes
)
1661 dstbits
= dstbits
+ linebytes
* (lines
- 1);
1662 linebytes
= -linebytes
;
1665 switch (bmpImage
->depth
)
1669 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
1670 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
1673 for (h
=lines
-1; h
>=0; h
--) {
1677 for (x
=0; x
<dstwidth
; x
++) {
1678 PALETTEENTRY srcval
;
1679 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
1680 dstval
|=(X11DRV_DIB_GetNearestIndex
1684 srcval
.peBlue
) << (7 - (x
& 7)));
1690 if ((dstwidth
&7)!=0) {
1693 dstbits
+= linebytes
;
1701 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
1702 /* ==== pal 8 bmp -> pal 1 dib ==== */
1703 const void* srcbits
;
1704 const BYTE
* srcpixel
;
1707 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1709 for (h
=0; h
<lines
; h
++) {
1714 for (x
=0; x
<dstwidth
; x
++) {
1715 PALETTEENTRY srcval
;
1716 srcval
=srccolors
[(int)*srcpixel
++];
1717 dstval
|=(X11DRV_DIB_GetNearestIndex
1721 srcval
.peBlue
) << (7-(x
&7)) );
1727 if ((dstwidth
&7)!=0) {
1730 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1731 dstbits
+= linebytes
;
1741 const void* srcbits
;
1742 const WORD
* srcpixel
;
1745 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1747 if (bmpImage
->green_mask
==0x03e0) {
1748 if (bmpImage
->red_mask
==0x7c00) {
1749 /* ==== rgb 555 bmp -> pal 1 dib ==== */
1750 for (h
=0; h
<lines
; h
++) {
1755 for (x
=0; x
<dstwidth
; x
++) {
1758 dstval
|=(X11DRV_DIB_GetNearestIndex
1760 ((srcval
>> 7) & 0xf8) | /* r */
1761 ((srcval
>> 12) & 0x07),
1762 ((srcval
>> 2) & 0xf8) | /* g */
1763 ((srcval
>> 7) & 0x07),
1764 ((srcval
<< 3) & 0xf8) | /* b */
1765 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
1771 if ((dstwidth
&7)!=0) {
1774 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1775 dstbits
+= linebytes
;
1777 } else if (bmpImage
->blue_mask
==0x7c00) {
1778 /* ==== bgr 555 bmp -> pal 1 dib ==== */
1779 for (h
=0; h
<lines
; h
++) {
1784 for (x
=0; x
<dstwidth
; x
++) {
1787 dstval
|=(X11DRV_DIB_GetNearestIndex
1789 ((srcval
<< 3) & 0xf8) | /* r */
1790 ((srcval
>> 2) & 0x07),
1791 ((srcval
>> 2) & 0xf8) | /* g */
1792 ((srcval
>> 7) & 0x07),
1793 ((srcval
>> 7) & 0xf8) | /* b */
1794 ((srcval
>> 12) & 0x07) ) << (7-(x
&7)) );
1800 if ((dstwidth
&7)!=0) {
1803 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1804 dstbits
+= linebytes
;
1809 } else if (bmpImage
->green_mask
==0x07e0) {
1810 if (bmpImage
->red_mask
==0xf800) {
1811 /* ==== rgb 565 bmp -> pal 1 dib ==== */
1812 for (h
=0; h
<lines
; h
++) {
1817 for (x
=0; x
<dstwidth
; x
++) {
1820 dstval
|=(X11DRV_DIB_GetNearestIndex
1822 ((srcval
>> 8) & 0xf8) | /* r */
1823 ((srcval
>> 13) & 0x07),
1824 ((srcval
>> 3) & 0xfc) | /* g */
1825 ((srcval
>> 9) & 0x03),
1826 ((srcval
<< 3) & 0xf8) | /* b */
1827 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
1833 if ((dstwidth
&7)!=0) {
1836 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1837 dstbits
+= linebytes
;
1839 } else if (bmpImage
->blue_mask
==0xf800) {
1840 /* ==== bgr 565 bmp -> pal 1 dib ==== */
1841 for (h
=0; h
<lines
; h
++) {
1846 for (x
=0; x
<dstwidth
; x
++) {
1849 dstval
|=(X11DRV_DIB_GetNearestIndex
1851 ((srcval
<< 3) & 0xf8) | /* r */
1852 ((srcval
>> 2) & 0x07),
1853 ((srcval
>> 3) & 0xfc) | /* g */
1854 ((srcval
>> 9) & 0x03),
1855 ((srcval
>> 8) & 0xf8) | /* b */
1856 ((srcval
>> 13) & 0x07) ) << (7-(x
&7)) );
1862 if ((dstwidth
&7)!=0) {
1865 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1866 dstbits
+= linebytes
;
1880 const void* srcbits
;
1881 const BYTE
*srcbyte
;
1883 int bytes_per_pixel
;
1885 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1886 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
1888 if (bmpImage
->green_mask
!=0x00ff00 ||
1889 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1891 } else if (bmpImage
->blue_mask
==0xff) {
1892 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
1893 for (h
=0; h
<lines
; h
++) {
1898 for (x
=0; x
<dstwidth
; x
++) {
1899 dstval
|=(X11DRV_DIB_GetNearestIndex
1903 srcbyte
[0]) << (7-(x
&7)) );
1904 srcbyte
+=bytes_per_pixel
;
1910 if ((dstwidth
&7)!=0) {
1913 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1914 dstbits
+= linebytes
;
1917 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
1918 for (h
=0; h
<lines
; h
++) {
1923 for (x
=0; x
<dstwidth
; x
++) {
1924 dstval
|=(X11DRV_DIB_GetNearestIndex
1928 srcbyte
[2]) << (7-(x
&7)) );
1929 srcbyte
+=bytes_per_pixel
;
1935 if ((dstwidth
&7)!=0) {
1938 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1939 dstbits
+= linebytes
;
1949 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
1951 /* ==== any bmp format -> pal 1 dib ==== */
1952 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
1953 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
1954 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1956 for (h
=lines
-1; h
>=0; h
--) {
1960 for (x
=0; x
<dstwidth
; x
++) {
1961 dstval
|=(XGetPixel( bmpImage
, x
, h
) >= white
) << (7 - (x
&7));
1967 if ((dstwidth
&7)!=0) {
1970 dstbits
+= linebytes
;
1977 /***********************************************************************
1978 * X11DRV_DIB_SetImageBits_4
1980 * SetDIBits for a 4-bit deep DIB.
1982 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
1983 DWORD srcwidth
, DWORD dstwidth
, int left
,
1984 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
1987 const BYTE
* srcbyte
;
1992 srcbits
= srcbits
+ linebytes
* (lines
- 1);
1993 linebytes
= -linebytes
;
2000 srcbits
+= left
>> 1;
2002 /* ==== pal 4 dib -> any bmp format ==== */
2003 for (h
= lines
-1; h
>= 0; h
--) {
2005 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
2006 BYTE srcval
=*srcbyte
++;
2007 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
>> 4] );
2008 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
& 0x0f] );
2011 XPutPixel( bmpImage
, x
, h
, colors
[*srcbyte
>> 4] );
2012 srcbits
+= linebytes
;
2018 /***********************************************************************
2019 * X11DRV_DIB_GetImageBits_4
2021 * GetDIBits for a 4-bit deep DIB.
2023 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
2024 DWORD srcwidth
, DWORD dstwidth
,
2025 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
2026 XImage
*bmpImage
, DWORD linebytes
)
2035 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2036 linebytes
= -linebytes
;
2041 switch (bmpImage
->depth
) {
2044 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2045 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
2048 for (h
= lines
-1; h
>= 0; h
--) {
2052 for (x
= 0; x
< dstwidth
; x
++) {
2053 PALETTEENTRY srcval
;
2054 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2055 dstval
|=(X11DRV_DIB_GetNearestIndex
2059 srcval
.peBlue
) << (4-((x
&1)<<2)));
2065 if ((dstwidth
&1)!=0) {
2068 dstbits
+= linebytes
;
2076 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2077 /* ==== pal 8 bmp -> pal 4 dib ==== */
2078 const void* srcbits
;
2079 const BYTE
*srcpixel
;
2082 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2083 for (h
=0; h
<lines
; h
++) {
2088 for (x
=0; x
<dstwidth
; x
++) {
2089 PALETTEENTRY srcval
;
2090 srcval
= srccolors
[(int)*srcpixel
++];
2091 dstval
|=(X11DRV_DIB_GetNearestIndex
2095 srcval
.peBlue
) << (4*(1-(x
&1))) );
2101 if ((dstwidth
&1)!=0) {
2104 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2105 dstbits
+= linebytes
;
2115 const void* srcbits
;
2116 const WORD
* srcpixel
;
2119 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2121 if (bmpImage
->green_mask
==0x03e0) {
2122 if (bmpImage
->red_mask
==0x7c00) {
2123 /* ==== rgb 555 bmp -> pal 4 dib ==== */
2124 for (h
=0; h
<lines
; h
++) {
2129 for (x
=0; x
<dstwidth
; x
++) {
2132 dstval
|=(X11DRV_DIB_GetNearestIndex
2134 ((srcval
>> 7) & 0xf8) | /* r */
2135 ((srcval
>> 12) & 0x07),
2136 ((srcval
>> 2) & 0xf8) | /* g */
2137 ((srcval
>> 7) & 0x07),
2138 ((srcval
<< 3) & 0xf8) | /* b */
2139 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
2145 if ((dstwidth
&1)!=0) {
2148 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2149 dstbits
+= linebytes
;
2151 } else if (bmpImage
->blue_mask
==0x7c00) {
2152 /* ==== bgr 555 bmp -> pal 4 dib ==== */
2153 for (h
=0; h
<lines
; h
++) {
2158 for (x
=0; x
<dstwidth
; x
++) {
2161 dstval
|=(X11DRV_DIB_GetNearestIndex
2163 ((srcval
<< 3) & 0xf8) | /* r */
2164 ((srcval
>> 2) & 0x07),
2165 ((srcval
>> 2) & 0xf8) | /* g */
2166 ((srcval
>> 7) & 0x07),
2167 ((srcval
>> 7) & 0xf8) | /* b */
2168 ((srcval
>> 12) & 0x07) ) << ((1-(x
&1))<<2) );
2174 if ((dstwidth
&1)!=0) {
2177 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2178 dstbits
+= linebytes
;
2183 } else if (bmpImage
->green_mask
==0x07e0) {
2184 if (bmpImage
->red_mask
==0xf800) {
2185 /* ==== rgb 565 bmp -> pal 4 dib ==== */
2186 for (h
=0; h
<lines
; h
++) {
2191 for (x
=0; x
<dstwidth
; x
++) {
2194 dstval
|=(X11DRV_DIB_GetNearestIndex
2196 ((srcval
>> 8) & 0xf8) | /* r */
2197 ((srcval
>> 13) & 0x07),
2198 ((srcval
>> 3) & 0xfc) | /* g */
2199 ((srcval
>> 9) & 0x03),
2200 ((srcval
<< 3) & 0xf8) | /* b */
2201 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
2207 if ((dstwidth
&1)!=0) {
2210 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2211 dstbits
+= linebytes
;
2213 } else if (bmpImage
->blue_mask
==0xf800) {
2214 /* ==== bgr 565 bmp -> pal 4 dib ==== */
2215 for (h
=0; h
<lines
; h
++) {
2220 for (x
=0; x
<dstwidth
; x
++) {
2223 dstval
|=(X11DRV_DIB_GetNearestIndex
2225 ((srcval
<< 3) & 0xf8) | /* r */
2226 ((srcval
>> 2) & 0x07),
2227 ((srcval
>> 3) & 0xfc) | /* g */
2228 ((srcval
>> 9) & 0x03),
2229 ((srcval
>> 8) & 0xf8) | /* b */
2230 ((srcval
>> 13) & 0x07) ) << ((1-(x
&1))<<2) );
2236 if ((dstwidth
&1)!=0) {
2239 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2240 dstbits
+= linebytes
;
2252 if (bmpImage
->bits_per_pixel
==24) {
2253 const void* srcbits
;
2254 const BYTE
*srcbyte
;
2257 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2259 if (bmpImage
->green_mask
!=0x00ff00 ||
2260 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2262 } else if (bmpImage
->blue_mask
==0xff) {
2263 /* ==== rgb 888 bmp -> pal 4 dib ==== */
2264 for (h
=0; h
<lines
; h
++) {
2267 for (x
=0; x
<dstwidth
/2; x
++) {
2268 /* Do 2 pixels at a time */
2269 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2274 X11DRV_DIB_GetNearestIndex
2282 /* And the the odd pixel */
2283 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2289 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2290 dstbits
+= linebytes
;
2293 /* ==== bgr 888 bmp -> pal 4 dib ==== */
2294 for (h
=0; h
<lines
; h
++) {
2297 for (x
=0; x
<dstwidth
/2; x
++) {
2298 /* Do 2 pixels at a time */
2299 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2304 X11DRV_DIB_GetNearestIndex
2312 /* And the the odd pixel */
2313 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2319 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2320 dstbits
+= linebytes
;
2329 const void* srcbits
;
2330 const BYTE
*srcbyte
;
2333 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2335 if (bmpImage
->green_mask
!=0x00ff00 ||
2336 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2338 } else if (bmpImage
->blue_mask
==0xff) {
2339 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
2340 for (h
=0; h
<lines
; h
++) {
2343 for (x
=0; x
<dstwidth
/2; x
++) {
2344 /* Do 2 pixels at a time */
2345 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2350 X11DRV_DIB_GetNearestIndex
2358 /* And the the odd pixel */
2359 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2365 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2366 dstbits
+= linebytes
;
2369 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
2370 for (h
=0; h
<lines
; h
++) {
2373 for (x
=0; x
<dstwidth
/2; x
++) {
2374 /* Do 2 pixels at a time */
2375 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2380 X11DRV_DIB_GetNearestIndex
2388 /* And the the odd pixel */
2389 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2395 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2396 dstbits
+= linebytes
;
2407 /* ==== any bmp format -> pal 4 dib ==== */
2408 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
2409 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
2410 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2411 for (h
=lines
-1; h
>=0; h
--) {
2413 for (x
=0; x
<(dstwidth
& ~1); x
+=2) {
2414 *dstbyte
++=(X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4) |
2415 X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
+1, h
), 0);
2418 *dstbyte
=(X11DRV_DIB_MapColor((int *)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4);
2420 dstbits
+= linebytes
;
2427 /***********************************************************************
2428 * X11DRV_DIB_SetImageBits_RLE4
2430 * SetDIBits for a 4-bit deep compressed DIB.
2432 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
2433 DWORD width
, DWORD dstwidth
,
2434 int left
, int *colors
,
2437 int x
= 0, y
= lines
- 1, c
, length
;
2438 const BYTE
*begin
= bits
;
2443 if (length
) { /* encoded */
2446 if (x
>= width
) break;
2447 XPutPixel(bmpImage
, x
++, y
, colors
[c
>> 4]);
2448 if (!length
--) break;
2449 if (x
>= width
) break;
2450 XPutPixel(bmpImage
, x
++, y
, colors
[c
& 0xf]);
2469 default: /* absolute */
2472 if (x
< width
) XPutPixel(bmpImage
, x
++, y
, colors
[c
>> 4]);
2473 if (!length
--) break;
2474 if (x
< width
) XPutPixel(bmpImage
, x
++, y
, colors
[c
& 0xf]);
2476 if ((bits
- begin
) & 1)
2485 /***********************************************************************
2486 * X11DRV_DIB_SetImageBits_8
2488 * SetDIBits for an 8-bit deep DIB.
2490 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
2491 DWORD srcwidth
, DWORD dstwidth
, int left
,
2492 const int *colors
, XImage
*bmpImage
,
2497 const BYTE
* srcbyte
;
2503 srcbits
= srcbits
+ linebytes
* (lines
-1);
2504 linebytes
= -linebytes
;
2509 switch (bmpImage
->depth
) {
2512 #if defined(__i386__) && defined(__GNUC__)
2513 /* Some X servers might have 32 bit/ 16bit deep pixel */
2514 if (lines
&& dstwidth
&& (bmpImage
->bits_per_pixel
== 16) &&
2515 (ImageByteOrder(gdi_display
)==LSBFirst
) )
2517 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2518 /* FIXME: Does this really handle all these cases correctly? */
2519 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
2520 for (h
= lines
; h
--; ) {
2521 int _cl1
,_cl2
; /* temp outputs for asm below */
2522 /* Borrowed from DirectDraw */
2523 __asm__
__volatile__(
2528 " movw (%%edx,%%eax,4),%%ax\n"
2530 " xor %%eax,%%eax\n"
2532 :"=S" (srcbyte
), "=D" (_cl1
), "=c" (_cl2
)
2537 :"eax", "cc", "memory"
2539 srcbyte
= (srcbits
+= linebytes
);
2540 dstbits
-= bmpImage
->bytes_per_line
;
2548 #if defined(__i386__) && defined(__GNUC__)
2549 if (lines
&& dstwidth
&& (bmpImage
->bits_per_pixel
== 32) &&
2550 (ImageByteOrder(gdi_display
)==LSBFirst
) )
2552 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
2553 /* FIXME: Does this really handle both cases correctly? */
2554 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
2555 for (h
= lines
; h
--; ) {
2556 int _cl1
,_cl2
; /* temp outputs for asm below */
2557 /* Borrowed from DirectDraw */
2558 __asm__
__volatile__(
2563 " movl (%%edx,%%eax,4),%%eax\n"
2565 " xor %%eax,%%eax\n"
2567 :"=S" (srcbyte
), "=D" (_cl1
), "=c" (_cl2
)
2572 :"eax", "cc", "memory"
2574 srcbyte
= (srcbits
+= linebytes
);
2575 dstbits
-= bmpImage
->bytes_per_line
;
2582 break; /* use slow generic case below */
2585 /* ==== pal 8 dib -> any bmp format ==== */
2586 for (h
=lines
-1; h
>=0; h
--) {
2587 for (x
=left
; x
<dstwidth
+left
; x
++) {
2588 XPutPixel(bmpImage
, x
, h
, colors
[*srcbyte
++]);
2590 srcbyte
= (srcbits
+= linebytes
);
2594 /***********************************************************************
2595 * X11DRV_DIB_GetImageBits_8
2597 * GetDIBits for an 8-bit deep DIB.
2599 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
2600 DWORD srcwidth
, DWORD dstwidth
,
2601 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
2602 XImage
*bmpImage
, DWORD linebytes
)
2611 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2612 linebytes
= -linebytes
;
2617 * This condition is true when GetImageBits has been called by
2618 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
2619 * 256 colormaps, so we'll just use for for GetDIBits calls.
2620 * (In somes cases, in a updateDIBSection, the returned colors are bad too)
2622 if (!srccolors
) goto updatesection
;
2624 switch (bmpImage
->depth
) {
2627 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2629 /* ==== pal 1 bmp -> pal 8 dib ==== */
2630 /* ==== pal 4 bmp -> pal 8 dib ==== */
2631 for (h
=lines
-1; h
>=0; h
--) {
2633 for (x
=0; x
<dstwidth
; x
++) {
2634 PALETTEENTRY srcval
;
2635 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2636 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
2641 dstbits
+= linebytes
;
2649 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2650 /* ==== pal 8 bmp -> pal 8 dib ==== */
2651 const void* srcbits
;
2652 const BYTE
* srcpixel
;
2654 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2655 for (h
=0; h
<lines
; h
++) {
2658 for (x
= 0; x
< dstwidth
; x
++) {
2659 PALETTEENTRY srcval
;
2660 srcval
=srccolors
[(int)*srcpixel
++];
2661 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
2666 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2667 dstbits
+= linebytes
;
2677 const void* srcbits
;
2678 const WORD
* srcpixel
;
2681 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2683 if (bmpImage
->green_mask
==0x03e0) {
2684 if (bmpImage
->red_mask
==0x7c00) {
2685 /* ==== rgb 555 bmp -> pal 8 dib ==== */
2686 for (h
=0; h
<lines
; h
++) {
2689 for (x
=0; x
<dstwidth
; x
++) {
2692 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2694 ((srcval
>> 7) & 0xf8) | /* r */
2695 ((srcval
>> 12) & 0x07),
2696 ((srcval
>> 2) & 0xf8) | /* g */
2697 ((srcval
>> 7) & 0x07),
2698 ((srcval
<< 3) & 0xf8) | /* b */
2699 ((srcval
>> 2) & 0x07) );
2701 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2702 dstbits
+= linebytes
;
2704 } else if (bmpImage
->blue_mask
==0x7c00) {
2705 /* ==== bgr 555 bmp -> pal 8 dib ==== */
2706 for (h
=0; h
<lines
; h
++) {
2709 for (x
=0; x
<dstwidth
; x
++) {
2712 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2714 ((srcval
<< 3) & 0xf8) | /* r */
2715 ((srcval
>> 2) & 0x07),
2716 ((srcval
>> 2) & 0xf8) | /* g */
2717 ((srcval
>> 7) & 0x07),
2718 ((srcval
>> 7) & 0xf8) | /* b */
2719 ((srcval
>> 12) & 0x07) );
2721 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2722 dstbits
+= linebytes
;
2727 } else if (bmpImage
->green_mask
==0x07e0) {
2728 if (bmpImage
->red_mask
==0xf800) {
2729 /* ==== rgb 565 bmp -> pal 8 dib ==== */
2730 for (h
=0; h
<lines
; h
++) {
2733 for (x
=0; x
<dstwidth
; x
++) {
2736 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2738 ((srcval
>> 8) & 0xf8) | /* r */
2739 ((srcval
>> 13) & 0x07),
2740 ((srcval
>> 3) & 0xfc) | /* g */
2741 ((srcval
>> 9) & 0x03),
2742 ((srcval
<< 3) & 0xf8) | /* b */
2743 ((srcval
>> 2) & 0x07) );
2745 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2746 dstbits
+= linebytes
;
2748 } else if (bmpImage
->blue_mask
==0xf800) {
2749 /* ==== bgr 565 bmp -> pal 8 dib ==== */
2750 for (h
=0; h
<lines
; h
++) {
2753 for (x
=0; x
<dstwidth
; x
++) {
2756 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2758 ((srcval
<< 3) & 0xf8) | /* r */
2759 ((srcval
>> 2) & 0x07),
2760 ((srcval
>> 3) & 0xfc) | /* g */
2761 ((srcval
>> 9) & 0x03),
2762 ((srcval
>> 8) & 0xf8) | /* b */
2763 ((srcval
>> 13) & 0x07) );
2765 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2766 dstbits
+= linebytes
;
2780 const void* srcbits
;
2781 const BYTE
*srcbyte
;
2783 int bytes_per_pixel
;
2785 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2786 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
2788 if (bmpImage
->green_mask
!=0x00ff00 ||
2789 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2791 } else if (bmpImage
->blue_mask
==0xff) {
2792 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
2793 for (h
=0; h
<lines
; h
++) {
2796 for (x
=0; x
<dstwidth
; x
++) {
2797 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2802 srcbyte
+=bytes_per_pixel
;
2804 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2805 dstbits
+= linebytes
;
2808 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
2809 for (h
=0; h
<lines
; h
++) {
2812 for (x
=0; x
<dstwidth
; x
++) {
2813 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2818 srcbyte
+=bytes_per_pixel
;
2820 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2821 dstbits
+= linebytes
;
2829 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
2830 bmpImage
->depth
, bmpImage
->red_mask
,
2831 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2833 /* ==== any bmp format -> pal 8 dib ==== */
2834 for (h
=lines
-1; h
>=0; h
--) {
2836 for (x
=0; x
<dstwidth
; x
++) {
2837 *dstbyte
=X11DRV_DIB_MapColor
2839 XGetPixel(bmpImage
, x
, h
), *dstbyte
);
2842 dstbits
+= linebytes
;
2848 /***********************************************************************
2849 * X11DRV_DIB_SetImageBits_RLE8
2851 * SetDIBits for an 8-bit deep compressed DIB.
2853 * This function rewritten 941113 by James Youngman. WINE blew out when I
2854 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
2856 * This was because the algorithm assumed that all RLE8 bitmaps end with the
2857 * 'End of bitmap' escape code. This code is very much laxer in what it
2858 * allows to end the expansion. Possibly too lax. See the note by
2859 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
2860 * bitmap should end with RleEnd, but on the other hand, software exists
2861 * that produces ones that don't and Windows 3.1 doesn't complain a bit
2864 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
2865 * James A. Youngman <mbcstjy@afs.man.ac.uk>
2868 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
2869 DWORD width
, DWORD dstwidth
,
2870 int left
, int *colors
,
2873 int x
; /* X-positon on each line. Increases. */
2874 int y
; /* Line #. Starts at lines-1, decreases */
2875 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
2876 BYTE length
; /* The length pf a run */
2877 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
2880 * Note that the bitmap data is stored by Windows starting at the
2881 * bottom line of the bitmap and going upwards. Within each line,
2882 * the data is stored left-to-right. That's the reason why line
2883 * goes from lines-1 to 0. [JAY]
2893 * If the length byte is not zero (which is the escape value),
2894 * We have a run of length pixels all the same colour. The colour
2895 * index is stored next.
2897 * If the length byte is zero, we need to read the next byte to
2898 * know what to do. [JAY]
2903 * [Run-Length] Encoded mode
2905 int color
= colors
[*pIn
++];
2906 while (length
-- && x
< dstwidth
) XPutPixel(bmpImage
, x
++, y
, color
);
2911 * Escape codes (may be an absolute sequence though)
2913 escape_code
= (*pIn
++);
2922 /* Not all RLE8 bitmaps end with this code. For
2923 * example, Paint Shop Pro produces some that don't.
2924 * That's (I think) what caused the previous
2925 * implementation to fail. [JAY]
2934 default: /* switch to absolute mode */
2935 length
= escape_code
;
2938 int color
= colors
[*pIn
++];
2944 XPutPixel(bmpImage
, x
++, y
, color
);
2947 * If you think for a moment you'll realise that the
2948 * only time we could ever possibly read an odd
2949 * number of bytes is when there is a 0x00 (escape),
2950 * a value >0x02 (absolute mode) and then an odd-
2951 * length run. Therefore this is the only place we
2952 * need to worry about it. Everywhere else the
2953 * bytes are always read in pairs. [JAY]
2955 if (escape_code
& 1) pIn
++; /* Throw away the pad byte. */
2957 } /* switch (escape_code) : Escape sequence */
2963 /***********************************************************************
2964 * X11DRV_DIB_SetImageBits_16
2966 * SetDIBits for a 16-bit deep DIB.
2968 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
2969 DWORD srcwidth
, DWORD dstwidth
, int left
,
2970 X11DRV_PDEVICE
*physDev
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
2971 XImage
*bmpImage
, DWORD linebytes
)
2979 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
2980 linebytes
= -linebytes
;
2983 switch (bmpImage
->depth
)
2990 srcbits
=srcbits
+left
*2;
2991 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2993 if (bmpImage
->green_mask
==0x03e0) {
2994 if (gSrc
==bmpImage
->green_mask
) {
2995 if (rSrc
==bmpImage
->red_mask
) {
2996 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
2997 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
2998 X11DRV_DIB_Convert_any_asis
3001 dstbits
,-bmpImage
->bytes_per_line
);
3002 } else if (rSrc
==bmpImage
->blue_mask
) {
3003 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
3004 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
3005 X11DRV_DIB_Convert_555_reverse
3008 dstbits
,-bmpImage
->bytes_per_line
);
3011 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
3012 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
3013 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
3014 X11DRV_DIB_Convert_565_to_555_asis
3017 dstbits
,-bmpImage
->bytes_per_line
);
3019 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
3020 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
3021 X11DRV_DIB_Convert_565_to_555_reverse
3024 dstbits
,-bmpImage
->bytes_per_line
);
3027 } else if (bmpImage
->green_mask
==0x07e0) {
3028 if (gSrc
==bmpImage
->green_mask
) {
3029 if (rSrc
==bmpImage
->red_mask
) {
3030 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
3031 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
3032 X11DRV_DIB_Convert_any_asis
3035 dstbits
,-bmpImage
->bytes_per_line
);
3037 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
3038 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
3039 X11DRV_DIB_Convert_565_reverse
3042 dstbits
,-bmpImage
->bytes_per_line
);
3045 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
3046 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
3047 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
3048 X11DRV_DIB_Convert_555_to_565_asis
3051 dstbits
,-bmpImage
->bytes_per_line
);
3053 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
3054 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
3055 X11DRV_DIB_Convert_555_to_565_reverse
3058 dstbits
,-bmpImage
->bytes_per_line
);
3068 if (bmpImage
->bits_per_pixel
==24) {
3071 srcbits
=srcbits
+left
*2;
3072 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
3074 if (bmpImage
->green_mask
!=0x00ff00 ||
3075 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3077 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
3078 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
3080 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
3081 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
3082 X11DRV_DIB_Convert_555_to_888_asis
3085 dstbits
,-bmpImage
->bytes_per_line
);
3087 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
3088 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
3089 X11DRV_DIB_Convert_565_to_888_asis
3092 dstbits
,-bmpImage
->bytes_per_line
);
3096 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
3097 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
3098 X11DRV_DIB_Convert_555_to_888_reverse
3101 dstbits
,-bmpImage
->bytes_per_line
);
3103 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
3104 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
3105 X11DRV_DIB_Convert_565_to_888_reverse
3108 dstbits
,-bmpImage
->bytes_per_line
);
3119 srcbits
=srcbits
+left
*2;
3120 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
3122 if (bmpImage
->green_mask
!=0x00ff00 ||
3123 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3125 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
3126 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
3128 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
3129 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
3130 X11DRV_DIB_Convert_555_to_0888_asis
3133 dstbits
,-bmpImage
->bytes_per_line
);
3135 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
3136 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
3137 X11DRV_DIB_Convert_565_to_0888_asis
3140 dstbits
,-bmpImage
->bytes_per_line
);
3144 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
3145 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
3146 X11DRV_DIB_Convert_555_to_0888_reverse
3149 dstbits
,-bmpImage
->bytes_per_line
);
3151 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
3152 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
3153 X11DRV_DIB_Convert_565_to_0888_reverse
3156 dstbits
,-bmpImage
->bytes_per_line
);
3164 WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3165 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
3166 bmpImage
->green_mask
, bmpImage
->blue_mask
);
3172 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
3173 const WORD
* srcpixel
;
3174 int rShift1
,gShift1
,bShift1
;
3175 int rShift2
,gShift2
,bShift2
;
3178 /* Set color scaling values */
3179 rShift1
=16+X11DRV_DIB_MaskToShift(rSrc
)-3;
3180 gShift1
=16+X11DRV_DIB_MaskToShift(gSrc
)-3;
3181 bShift1
=16+X11DRV_DIB_MaskToShift(bSrc
)-3;
3186 /* Green has 5 bits, like the others */
3190 /* Green has 6 bits, not 5. Compensate. */
3199 /* We could split it into four separate cases to optimize
3200 * but it is probably not worth it.
3202 for (h
=lines
-1; h
>=0; h
--) {
3203 srcpixel
=(const WORD
*)srcbits
;
3204 for (x
=left
; x
<dstwidth
+left
; x
++) {
3206 BYTE red
,green
,blue
;
3207 srcval
=*srcpixel
++ << 16;
3208 red
= ((srcval
>> rShift1
) & 0xf8) |
3209 ((srcval
>> rShift2
) & 0x07);
3210 green
=((srcval
>> gShift1
) & gMask1
) |
3211 ((srcval
>> gShift2
) & gMask2
);
3212 blue
= ((srcval
>> bShift1
) & 0xf8) |
3213 ((srcval
>> bShift2
) & 0x07);
3214 XPutPixel(bmpImage
, x
, h
,
3215 X11DRV_PALETTE_ToPhysical
3216 (physDev
, RGB(red
,green
,blue
)));
3218 srcbits
+= linebytes
;
3226 /***********************************************************************
3227 * X11DRV_DIB_GetImageBits_16
3229 * GetDIBits for an 16-bit deep DIB.
3231 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*dstbits
,
3232 DWORD dstwidth
, DWORD srcwidth
,
3233 PALETTEENTRY
*srccolors
,
3234 DWORD rDst
, DWORD gDst
, DWORD bDst
,
3235 XImage
*bmpImage
, DWORD dibpitch
)
3240 DWORD linebytes
= dibpitch
;
3245 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
3246 linebytes
= -linebytes
;
3249 switch (bmpImage
->depth
)
3254 const char* srcbits
;
3256 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3258 if (bmpImage
->green_mask
==0x03e0) {
3259 if (gDst
==bmpImage
->green_mask
) {
3260 if (rDst
==bmpImage
->red_mask
) {
3261 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
3262 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
3263 X11DRV_DIB_Convert_any_asis
3265 srcbits
,-bmpImage
->bytes_per_line
,
3268 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
3269 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
3270 X11DRV_DIB_Convert_555_reverse
3272 srcbits
,-bmpImage
->bytes_per_line
,
3276 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
3277 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
3278 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
3279 X11DRV_DIB_Convert_555_to_565_asis
3281 srcbits
,-bmpImage
->bytes_per_line
,
3284 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
3285 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
3286 X11DRV_DIB_Convert_555_to_565_reverse
3288 srcbits
,-bmpImage
->bytes_per_line
,
3292 } else if (bmpImage
->green_mask
==0x07e0) {
3293 if (gDst
==bmpImage
->green_mask
) {
3294 if (rDst
== bmpImage
->red_mask
) {
3295 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
3296 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
3297 X11DRV_DIB_Convert_any_asis
3299 srcbits
,-bmpImage
->bytes_per_line
,
3302 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
3303 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
3304 X11DRV_DIB_Convert_565_reverse
3306 srcbits
,-bmpImage
->bytes_per_line
,
3310 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
3311 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
3312 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
3313 X11DRV_DIB_Convert_565_to_555_asis
3315 srcbits
,-bmpImage
->bytes_per_line
,
3318 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
3319 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
3320 X11DRV_DIB_Convert_565_to_555_reverse
3322 srcbits
,-bmpImage
->bytes_per_line
,
3333 if (bmpImage
->bits_per_pixel
== 24) {
3334 const char* srcbits
;
3336 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3338 if (bmpImage
->green_mask
!=0x00ff00 ||
3339 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3341 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
3342 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
3344 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
3345 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
3346 X11DRV_DIB_Convert_888_to_555_asis
3348 srcbits
,-bmpImage
->bytes_per_line
,
3351 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
3352 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
3353 X11DRV_DIB_Convert_888_to_565_asis
3355 srcbits
,-bmpImage
->bytes_per_line
,
3360 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
3361 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
3362 X11DRV_DIB_Convert_888_to_555_reverse
3364 srcbits
,-bmpImage
->bytes_per_line
,
3367 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
3368 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
3369 X11DRV_DIB_Convert_888_to_565_reverse
3371 srcbits
,-bmpImage
->bytes_per_line
,
3381 const char* srcbits
;
3383 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3385 if (bmpImage
->green_mask
!=0x00ff00 ||
3386 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3388 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
3389 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
3391 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
3392 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
3393 X11DRV_DIB_Convert_0888_to_555_asis
3395 srcbits
,-bmpImage
->bytes_per_line
,
3398 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
3399 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
3400 X11DRV_DIB_Convert_0888_to_565_asis
3402 srcbits
,-bmpImage
->bytes_per_line
,
3407 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
3408 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
3409 X11DRV_DIB_Convert_0888_to_555_reverse
3411 srcbits
,-bmpImage
->bytes_per_line
,
3414 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
3415 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
3416 X11DRV_DIB_Convert_0888_to_565_reverse
3418 srcbits
,-bmpImage
->bytes_per_line
,
3427 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3428 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
3429 int rShift
,gShift
,bShift
;
3432 /* Shift everything 16 bits left so that all shifts are >0,
3433 * even for BGR DIBs. Then a single >> 16 will bring everything
3436 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
3437 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
3438 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
3440 /* 6 bits for the green */
3446 for (h
= lines
- 1; h
>= 0; h
--) {
3447 dstpixel
=(LPWORD
)dstbits
;
3448 for (x
= 0; x
< dstwidth
; x
++) {
3449 PALETTEENTRY srcval
;
3451 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
3452 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
3453 ((srcval
.peGreen
<< gShift
) & gDst
) |
3454 ((srcval
.peBlue
<< bShift
) & bDst
);
3455 *dstpixel
++=dstval
>> 16;
3457 dstbits
+= linebytes
;
3465 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3466 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
3467 int rShift
,gShift
,bShift
;
3468 const BYTE
* srcbits
;
3469 const BYTE
* srcpixel
;
3472 /* Shift everything 16 bits left so that all shifts are >0,
3473 * even for BGR DIBs. Then a single >> 16 will bring everything
3476 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
3477 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
3478 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
3480 /* 6 bits for the green */
3486 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3487 for (h
=0; h
<lines
; h
++) {
3489 dstpixel
=(LPWORD
)dstbits
;
3490 for (x
= 0; x
< dstwidth
; x
++) {
3491 PALETTEENTRY srcval
;
3493 srcval
=srccolors
[(int)*srcpixel
++];
3494 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
3495 ((srcval
.peGreen
<< gShift
) & gDst
) |
3496 ((srcval
.peBlue
<< bShift
) & bDst
);
3497 *dstpixel
++=dstval
>> 16;
3499 srcbits
-= bmpImage
->bytes_per_line
;
3500 dstbits
+= linebytes
;
3510 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
3511 int rShift
,gShift
,bShift
;
3514 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
3515 bmpImage
->depth
, bmpImage
->red_mask
,
3516 bmpImage
->green_mask
, bmpImage
->blue_mask
,
3519 /* Shift everything 16 bits left so that all shifts are >0,
3520 * even for BGR DIBs. Then a single >> 16 will bring everything
3523 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
3524 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
3525 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
3527 /* 6 bits for the green */
3533 for (h
= lines
- 1; h
>= 0; h
--) {
3534 dstpixel
=(LPWORD
)dstbits
;
3535 for (x
= 0; x
< dstwidth
; x
++) {
3538 srcval
=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage
, x
, h
));
3539 dstval
=((GetRValue(srcval
) << rShift
) & rDst
) |
3540 ((GetGValue(srcval
) << gShift
) & gDst
) |
3541 ((GetBValue(srcval
) << bShift
) & bDst
);
3542 *dstpixel
++=dstval
>> 16;
3544 dstbits
+= linebytes
;
3552 /***********************************************************************
3553 * X11DRV_DIB_SetImageBits_24
3555 * SetDIBits for a 24-bit deep DIB.
3557 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
3558 DWORD srcwidth
, DWORD dstwidth
, int left
,
3559 X11DRV_PDEVICE
*physDev
,
3560 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
3561 XImage
*bmpImage
, DWORD linebytes
)
3569 srcbits
= srcbits
+ linebytes
* (lines
- 1);
3570 linebytes
= -linebytes
;
3573 switch (bmpImage
->depth
)
3576 if (bmpImage
->bits_per_pixel
==24) {
3579 srcbits
=srcbits
+left
*3;
3580 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
3582 if (bmpImage
->green_mask
!=0x00ff00 ||
3583 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3585 } else if (rSrc
==bmpImage
->red_mask
) {
3586 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
3587 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
3588 X11DRV_DIB_Convert_any_asis
3591 dstbits
,-bmpImage
->bytes_per_line
);
3593 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
3594 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
3595 X11DRV_DIB_Convert_888_reverse
3598 dstbits
,-bmpImage
->bytes_per_line
);
3608 srcbits
=srcbits
+left
*3;
3609 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
3611 if (bmpImage
->green_mask
!=0x00ff00 ||
3612 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3614 } else if (rSrc
==bmpImage
->red_mask
) {
3615 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
3616 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
3617 X11DRV_DIB_Convert_888_to_0888_asis
3620 dstbits
,-bmpImage
->bytes_per_line
);
3622 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
3623 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
3624 X11DRV_DIB_Convert_888_to_0888_reverse
3627 dstbits
,-bmpImage
->bytes_per_line
);
3637 srcbits
=srcbits
+left
*3;
3638 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
3640 if (bmpImage
->green_mask
==0x03e0) {
3641 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
3642 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
3643 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
3644 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
3645 X11DRV_DIB_Convert_888_to_555_asis
3648 dstbits
,-bmpImage
->bytes_per_line
);
3649 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0x7f00) ||
3650 (bSrc
==0xff && bmpImage
->blue_mask
==0x7f00)) {
3651 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
3652 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
3653 X11DRV_DIB_Convert_888_to_555_reverse
3656 dstbits
,-bmpImage
->bytes_per_line
);
3660 } else if (bmpImage
->green_mask
==0x07e0) {
3661 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
3662 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
3663 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
3664 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
3665 X11DRV_DIB_Convert_888_to_565_asis
3668 dstbits
,-bmpImage
->bytes_per_line
);
3669 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0xf800) ||
3670 (bSrc
==0xff && bmpImage
->blue_mask
==0xf800)) {
3671 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
3672 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
3673 X11DRV_DIB_Convert_888_to_565_reverse
3676 dstbits
,-bmpImage
->bytes_per_line
);
3688 WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3689 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
3690 bmpImage
->green_mask
, bmpImage
->blue_mask
);
3696 /* ==== rgb 888 dib -> any bmp bormat ==== */
3697 const BYTE
* srcbyte
;
3699 /* Windows only supports one 24bpp DIB format: RGB888 */
3701 for (h
= lines
- 1; h
>= 0; h
--) {
3702 srcbyte
=(const BYTE
*)srcbits
;
3703 for (x
= left
; x
< dstwidth
+left
; x
++) {
3704 XPutPixel(bmpImage
, x
, h
,
3705 X11DRV_PALETTE_ToPhysical
3706 (physDev
, RGB(srcbyte
[2], srcbyte
[1], srcbyte
[0])));
3709 srcbits
+= linebytes
;
3717 /***********************************************************************
3718 * X11DRV_DIB_GetImageBits_24
3720 * GetDIBits for an 24-bit deep DIB.
3722 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*dstbits
,
3723 DWORD dstwidth
, DWORD srcwidth
,
3724 PALETTEENTRY
*srccolors
,
3725 DWORD rDst
, DWORD gDst
, DWORD bDst
,
3726 XImage
*bmpImage
, DWORD linebytes
)
3734 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
3735 linebytes
= -linebytes
;
3738 switch (bmpImage
->depth
)
3741 if (bmpImage
->bits_per_pixel
==24) {
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 888 dib ==== */
3751 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
3752 X11DRV_DIB_Convert_any_asis
3754 srcbits
,-bmpImage
->bytes_per_line
,
3757 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
3758 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
3759 X11DRV_DIB_Convert_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
!=0x00ff00 ||
3775 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3777 } else if (rDst
==bmpImage
->red_mask
) {
3778 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3779 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3780 X11DRV_DIB_Convert_0888_to_888_asis
3782 srcbits
,-bmpImage
->bytes_per_line
,
3785 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3786 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3787 X11DRV_DIB_Convert_0888_to_888_reverse
3789 srcbits
,-bmpImage
->bytes_per_line
,
3798 const char* srcbits
;
3800 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3802 if (bmpImage
->green_mask
==0x03e0) {
3803 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
3804 (bDst
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
3805 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
3806 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
3807 X11DRV_DIB_Convert_555_to_888_asis
3809 srcbits
,-bmpImage
->bytes_per_line
,
3811 } else if ((rDst
==0xff && bmpImage
->red_mask
==0x7f00) ||
3812 (bDst
==0xff && bmpImage
->blue_mask
==0x7f00)) {
3813 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
3814 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
3815 X11DRV_DIB_Convert_555_to_888_reverse
3817 srcbits
,-bmpImage
->bytes_per_line
,
3822 } else if (bmpImage
->green_mask
==0x07e0) {
3823 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
3824 (bDst
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
3825 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
3826 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
3827 X11DRV_DIB_Convert_565_to_888_asis
3829 srcbits
,-bmpImage
->bytes_per_line
,
3831 } else if ((rDst
==0xff && bmpImage
->red_mask
==0xf800) ||
3832 (bDst
==0xff && bmpImage
->blue_mask
==0xf800)) {
3833 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
3834 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
3835 X11DRV_DIB_Convert_565_to_888_reverse
3837 srcbits
,-bmpImage
->bytes_per_line
,
3850 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3851 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
3854 /* Windows only supports one 24bpp DIB format: rgb 888 */
3855 for (h
= lines
- 1; h
>= 0; h
--) {
3857 for (x
= 0; x
< dstwidth
; x
++) {
3858 PALETTEENTRY srcval
;
3859 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
3860 dstbyte
[0]=srcval
.peBlue
;
3861 dstbyte
[1]=srcval
.peGreen
;
3862 dstbyte
[2]=srcval
.peRed
;
3865 dstbits
+= linebytes
;
3873 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
== 0 && srccolors
) {
3874 /* ==== pal 8 bmp -> rgb 888 dib ==== */
3875 const void* srcbits
;
3876 const BYTE
* srcpixel
;
3879 /* Windows only supports one 24bpp DIB format: rgb 888 */
3880 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3881 for (h
= lines
- 1; h
>= 0; h
--) {
3884 for (x
= 0; x
< dstwidth
; x
++ ) {
3885 PALETTEENTRY srcval
;
3886 srcval
=srccolors
[(int)*srcpixel
++];
3887 dstbyte
[0]=srcval
.peBlue
;
3888 dstbyte
[1]=srcval
.peGreen
;
3889 dstbyte
[2]=srcval
.peRed
;
3892 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
3893 dstbits
+= linebytes
;
3903 /* ==== any bmp format -> 888 dib ==== */
3906 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
3907 bmpImage
->depth
, bmpImage
->red_mask
,
3908 bmpImage
->green_mask
, bmpImage
->blue_mask
,
3911 /* Windows only supports one 24bpp DIB format: rgb 888 */
3912 for (h
= lines
- 1; h
>= 0; h
--) {
3914 for (x
= 0; x
< dstwidth
; x
++) {
3915 COLORREF srcval
=X11DRV_PALETTE_ToLogical
3916 (XGetPixel( bmpImage
, x
, h
));
3917 dstbyte
[0]=GetBValue(srcval
);
3918 dstbyte
[1]=GetGValue(srcval
);
3919 dstbyte
[2]=GetRValue(srcval
);
3922 dstbits
+= linebytes
;
3930 /***********************************************************************
3931 * X11DRV_DIB_SetImageBits_32
3933 * SetDIBits for a 32-bit deep DIB.
3935 static void X11DRV_DIB_SetImageBits_32(int lines
, const BYTE
*srcbits
,
3936 DWORD srcwidth
, DWORD dstwidth
, int left
,
3937 X11DRV_PDEVICE
*physDev
,
3938 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
3948 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
3949 linebytes
= -linebytes
;
3952 ptr
= (DWORD
*) srcbits
+ left
;
3954 switch (bmpImage
->depth
)
3957 if (bmpImage
->bits_per_pixel
==24) {
3960 srcbits
=srcbits
+left
*4;
3961 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
3963 if (rSrc
==bmpImage
->red_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->blue_mask
) {
3964 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
3965 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
3966 X11DRV_DIB_Convert_0888_to_888_asis
3969 dstbits
,-bmpImage
->bytes_per_line
);
3970 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3971 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3973 /* the tests below assume sane bmpImage masks */
3974 } else if (rSrc
==bmpImage
->blue_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->red_mask
) {
3975 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
3976 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
3977 X11DRV_DIB_Convert_0888_to_888_reverse
3980 dstbits
,-bmpImage
->bytes_per_line
);
3981 } else if (bmpImage
->blue_mask
==0xff) {
3982 /* ==== any 0888 dib -> rgb 888 bmp ==== */
3983 X11DRV_DIB_Convert_any0888_to_rgb888
3987 dstbits
,-bmpImage
->bytes_per_line
);
3989 /* ==== any 0888 dib -> bgr 888 bmp ==== */
3990 X11DRV_DIB_Convert_any0888_to_bgr888
3994 dstbits
,-bmpImage
->bytes_per_line
);
4004 srcbits
=srcbits
+left
*4;
4005 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
4007 if (gSrc
==bmpImage
->green_mask
) {
4008 if (rSrc
==bmpImage
->red_mask
&& bSrc
==bmpImage
->blue_mask
) {
4009 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
4010 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
4011 X11DRV_DIB_Convert_any_asis
4014 dstbits
,-bmpImage
->bytes_per_line
);
4015 } else if (bmpImage
->green_mask
!=0x00ff00 ||
4016 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
4018 /* the tests below assume sane bmpImage masks */
4019 } else if (rSrc
==bmpImage
->blue_mask
&& bSrc
==bmpImage
->red_mask
) {
4020 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
4021 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
4022 X11DRV_DIB_Convert_0888_reverse
4025 dstbits
,-bmpImage
->bytes_per_line
);
4027 /* ==== any 0888 dib -> any 0888 bmp ==== */
4028 X11DRV_DIB_Convert_0888_any
4032 dstbits
,-bmpImage
->bytes_per_line
,
4033 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4035 } else if (bmpImage
->green_mask
!=0x00ff00 ||
4036 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
4038 /* the tests below assume sane bmpImage masks */
4040 /* ==== any 0888 dib -> any 0888 bmp ==== */
4041 X11DRV_DIB_Convert_0888_any
4045 dstbits
,-bmpImage
->bytes_per_line
,
4046 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4056 srcbits
=srcbits
+left
*4;
4057 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
4059 if (rSrc
==0xff0000 && gSrc
==0x00ff00 && bSrc
==0x0000ff) {
4060 if (bmpImage
->green_mask
==0x03e0) {
4061 if (bmpImage
->red_mask
==0x7f00) {
4062 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
4063 X11DRV_DIB_Convert_0888_to_555_asis
4066 dstbits
,-bmpImage
->bytes_per_line
);
4067 } else if (bmpImage
->blue_mask
==0x7f00) {
4068 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
4069 X11DRV_DIB_Convert_0888_to_555_reverse
4072 dstbits
,-bmpImage
->bytes_per_line
);
4076 } else if (bmpImage
->green_mask
==0x07e0) {
4077 if (bmpImage
->red_mask
==0xf800) {
4078 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
4079 X11DRV_DIB_Convert_0888_to_565_asis
4082 dstbits
,-bmpImage
->bytes_per_line
);
4083 } else if (bmpImage
->blue_mask
==0xf800) {
4084 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
4085 X11DRV_DIB_Convert_0888_to_565_reverse
4088 dstbits
,-bmpImage
->bytes_per_line
);
4095 } else if (rSrc
==0x0000ff && gSrc
==0x00ff00 && bSrc
==0xff0000) {
4096 if (bmpImage
->green_mask
==0x03e0) {
4097 if (bmpImage
->blue_mask
==0x7f00) {
4098 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
4099 X11DRV_DIB_Convert_0888_to_555_asis
4102 dstbits
,-bmpImage
->bytes_per_line
);
4103 } else if (bmpImage
->red_mask
==0x7f00) {
4104 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
4105 X11DRV_DIB_Convert_0888_to_555_reverse
4108 dstbits
,-bmpImage
->bytes_per_line
);
4112 } else if (bmpImage
->green_mask
==0x07e0) {
4113 if (bmpImage
->blue_mask
==0xf800) {
4114 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
4115 X11DRV_DIB_Convert_0888_to_565_asis
4118 dstbits
,-bmpImage
->bytes_per_line
);
4119 } else if (bmpImage
->red_mask
==0xf800) {
4120 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
4121 X11DRV_DIB_Convert_0888_to_565_reverse
4124 dstbits
,-bmpImage
->bytes_per_line
);
4132 if (bmpImage
->green_mask
==0x03e0 &&
4133 (bmpImage
->red_mask
==0x7f00 ||
4134 bmpImage
->blue_mask
==0x7f00)) {
4135 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
4136 X11DRV_DIB_Convert_any0888_to_5x5
4140 dstbits
,-bmpImage
->bytes_per_line
,
4141 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4142 } else if (bmpImage
->green_mask
==0x07e0 &&
4143 (bmpImage
->red_mask
==0xf800 ||
4144 bmpImage
->blue_mask
==0xf800)) {
4145 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
4146 X11DRV_DIB_Convert_any0888_to_5x5
4150 dstbits
,-bmpImage
->bytes_per_line
,
4151 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4161 WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
4162 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
4163 bmpImage
->green_mask
, bmpImage
->blue_mask
);
4169 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
4170 const DWORD
* srcpixel
;
4171 int rShift
,gShift
,bShift
;
4173 rShift
=X11DRV_DIB_MaskToShift(rSrc
);
4174 gShift
=X11DRV_DIB_MaskToShift(gSrc
);
4175 bShift
=X11DRV_DIB_MaskToShift(bSrc
);
4177 for (h
= lines
- 1; h
>= 0; h
--) {
4178 srcpixel
=(const DWORD
*)srcbits
;
4179 for (x
= left
; x
< dstwidth
+left
; x
++) {
4181 BYTE red
,green
,blue
;
4182 srcvalue
=*srcpixel
++;
4183 red
= (srcvalue
>> rShift
) & 0xff;
4184 green
=(srcvalue
>> gShift
) & 0xff;
4185 blue
= (srcvalue
>> bShift
) & 0xff;
4186 XPutPixel(bmpImage
, x
, h
, X11DRV_PALETTE_ToPhysical
4187 (physDev
, RGB(red
,green
,blue
)));
4189 srcbits
+= linebytes
;
4197 /***********************************************************************
4198 * X11DRV_DIB_GetImageBits_32
4200 * GetDIBits for an 32-bit deep DIB.
4202 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*dstbits
,
4203 DWORD dstwidth
, DWORD srcwidth
,
4204 PALETTEENTRY
*srccolors
,
4205 DWORD rDst
, DWORD gDst
, DWORD bDst
,
4206 XImage
*bmpImage
, DWORD linebytes
)
4215 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
4216 linebytes
= -linebytes
;
4221 switch (bmpImage
->depth
)
4224 if (bmpImage
->bits_per_pixel
==24) {
4225 const void* srcbits
;
4227 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
4229 if (rDst
==bmpImage
->red_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->blue_mask
) {
4230 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
4231 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
4232 X11DRV_DIB_Convert_888_to_0888_asis
4234 srcbits
,-bmpImage
->bytes_per_line
,
4236 } else if (bmpImage
->green_mask
!=0x00ff00 ||
4237 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
4239 /* the tests below assume sane bmpImage masks */
4240 } else if (rDst
==bmpImage
->blue_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->red_mask
) {
4241 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
4242 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
4243 X11DRV_DIB_Convert_888_to_0888_reverse
4245 srcbits
,-bmpImage
->bytes_per_line
,
4247 } else if (bmpImage
->blue_mask
==0xff) {
4248 /* ==== rgb 888 bmp -> any 0888 dib ==== */
4249 X11DRV_DIB_Convert_rgb888_to_any0888
4251 srcbits
,-bmpImage
->bytes_per_line
,
4255 /* ==== bgr 888 bmp -> any 0888 dib ==== */
4256 X11DRV_DIB_Convert_bgr888_to_any0888
4258 srcbits
,-bmpImage
->bytes_per_line
,
4268 const char* srcbits
;
4270 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
4272 if (gDst
==bmpImage
->green_mask
) {
4273 if (rDst
==bmpImage
->red_mask
&& bDst
==bmpImage
->blue_mask
) {
4274 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
4275 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
4276 X11DRV_DIB_Convert_any_asis
4278 srcbits
,-bmpImage
->bytes_per_line
,
4280 } else if (bmpImage
->green_mask
!=0x00ff00 ||
4281 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
4283 /* the tests below assume sane bmpImage masks */
4284 } else if (rDst
==bmpImage
->blue_mask
&& bDst
==bmpImage
->red_mask
) {
4285 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
4286 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
4287 X11DRV_DIB_Convert_0888_reverse
4289 srcbits
,-bmpImage
->bytes_per_line
,
4292 /* ==== any 0888 bmp -> any 0888 dib ==== */
4293 X11DRV_DIB_Convert_0888_any
4295 srcbits
,-bmpImage
->bytes_per_line
,
4296 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
4300 } else if (bmpImage
->green_mask
!=0x00ff00 ||
4301 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
4303 /* the tests below assume sane bmpImage masks */
4305 /* ==== any 0888 bmp -> any 0888 dib ==== */
4306 X11DRV_DIB_Convert_0888_any
4308 srcbits
,-bmpImage
->bytes_per_line
,
4309 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
4319 const char* srcbits
;
4321 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
4323 if (rDst
==0xff0000 && gDst
==0x00ff00 && bDst
==0x0000ff) {
4324 if (bmpImage
->green_mask
==0x03e0) {
4325 if (bmpImage
->red_mask
==0x7f00) {
4326 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
4327 X11DRV_DIB_Convert_555_to_0888_asis
4329 srcbits
,-bmpImage
->bytes_per_line
,
4331 } else if (bmpImage
->blue_mask
==0x7f00) {
4332 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
4333 X11DRV_DIB_Convert_555_to_0888_reverse
4335 srcbits
,-bmpImage
->bytes_per_line
,
4340 } else if (bmpImage
->green_mask
==0x07e0) {
4341 if (bmpImage
->red_mask
==0xf800) {
4342 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
4343 X11DRV_DIB_Convert_565_to_0888_asis
4345 srcbits
,-bmpImage
->bytes_per_line
,
4347 } else if (bmpImage
->blue_mask
==0xf800) {
4348 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
4349 X11DRV_DIB_Convert_565_to_0888_reverse
4351 srcbits
,-bmpImage
->bytes_per_line
,
4359 } else if (rDst
==0x0000ff && gDst
==0x00ff00 && bDst
==0xff0000) {
4360 if (bmpImage
->green_mask
==0x03e0) {
4361 if (bmpImage
->blue_mask
==0x7f00) {
4362 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
4363 X11DRV_DIB_Convert_555_to_0888_asis
4365 srcbits
,-bmpImage
->bytes_per_line
,
4367 } else if (bmpImage
->red_mask
==0x7f00) {
4368 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
4369 X11DRV_DIB_Convert_555_to_0888_reverse
4371 srcbits
,-bmpImage
->bytes_per_line
,
4376 } else if (bmpImage
->green_mask
==0x07e0) {
4377 if (bmpImage
->blue_mask
==0xf800) {
4378 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
4379 X11DRV_DIB_Convert_565_to_0888_asis
4381 srcbits
,-bmpImage
->bytes_per_line
,
4383 } else if (bmpImage
->red_mask
==0xf800) {
4384 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
4385 X11DRV_DIB_Convert_565_to_0888_reverse
4387 srcbits
,-bmpImage
->bytes_per_line
,
4396 if (bmpImage
->green_mask
==0x03e0 &&
4397 (bmpImage
->red_mask
==0x7f00 ||
4398 bmpImage
->blue_mask
==0x7f00)) {
4399 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
4400 X11DRV_DIB_Convert_5x5_to_any0888
4402 srcbits
,-bmpImage
->bytes_per_line
,
4403 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
4406 } else if (bmpImage
->green_mask
==0x07e0 &&
4407 (bmpImage
->red_mask
==0xf800 ||
4408 bmpImage
->blue_mask
==0xf800)) {
4409 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
4410 X11DRV_DIB_Convert_5x5_to_any0888
4412 srcbits
,-bmpImage
->bytes_per_line
,
4413 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
4425 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
4426 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
4427 int rShift
,gShift
,bShift
;
4430 rShift
=X11DRV_DIB_MaskToShift(rDst
);
4431 gShift
=X11DRV_DIB_MaskToShift(gDst
);
4432 bShift
=X11DRV_DIB_MaskToShift(bDst
);
4433 for (h
= lines
- 1; h
>= 0; h
--) {
4434 dstpixel
=(DWORD
*)dstbits
;
4435 for (x
= 0; x
< dstwidth
; x
++) {
4436 PALETTEENTRY srcval
;
4437 srcval
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
4438 *dstpixel
++=(srcval
.peRed
<< rShift
) |
4439 (srcval
.peGreen
<< gShift
) |
4440 (srcval
.peBlue
<< bShift
);
4442 dstbits
+= linebytes
;
4450 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
4451 /* ==== pal 8 bmp -> any 0888 dib ==== */
4452 int rShift
,gShift
,bShift
;
4453 const void* srcbits
;
4454 const BYTE
* srcpixel
;
4457 rShift
=X11DRV_DIB_MaskToShift(rDst
);
4458 gShift
=X11DRV_DIB_MaskToShift(gDst
);
4459 bShift
=X11DRV_DIB_MaskToShift(bDst
);
4460 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
4461 for (h
= lines
- 1; h
>= 0; h
--) {
4463 dstpixel
=(DWORD
*)dstbits
;
4464 for (x
= 0; x
< dstwidth
; x
++) {
4465 PALETTEENTRY srcval
;
4466 srcval
=srccolors
[(int)*srcpixel
++];
4467 *dstpixel
++=(srcval
.peRed
<< rShift
) |
4468 (srcval
.peGreen
<< gShift
) |
4469 (srcval
.peBlue
<< bShift
);
4471 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
4472 dstbits
+= linebytes
;
4482 /* ==== any bmp format -> any 0888 dib ==== */
4483 int rShift
,gShift
,bShift
;
4486 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
4487 bmpImage
->depth
, bmpImage
->red_mask
,
4488 bmpImage
->green_mask
, bmpImage
->blue_mask
,
4491 rShift
=X11DRV_DIB_MaskToShift(rDst
);
4492 gShift
=X11DRV_DIB_MaskToShift(gDst
);
4493 bShift
=X11DRV_DIB_MaskToShift(bDst
);
4494 for (h
= lines
- 1; h
>= 0; h
--) {
4495 dstpixel
=(DWORD
*)dstbits
;
4496 for (x
= 0; x
< dstwidth
; x
++) {
4498 srcval
=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage
, x
, h
));
4499 *dstpixel
++=(GetRValue(srcval
) << rShift
) |
4500 (GetGValue(srcval
) << gShift
) |
4501 (GetBValue(srcval
) << bShift
);
4503 dstbits
+= linebytes
;
4510 /***********************************************************************
4511 * X11DRV_DIB_SetImageBits
4513 * Transfer the bits to an X image.
4514 * Helper function for SetDIBits() and SetDIBitsToDevice().
4516 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
4518 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
4523 bmpImage
= descr
->image
;
4525 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
4526 descr
->infoWidth
, lines
, 32, 0 );
4527 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
4528 if(bmpImage
->data
== NULL
) {
4529 ERR("Out of memory!\n");
4530 XDestroyImage( bmpImage
);
4531 wine_tsx11_unlock();
4536 TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
4537 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
4538 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
4539 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
4540 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4542 /* Transfer the pixels */
4543 switch(descr
->infoBpp
)
4546 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
4547 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
4548 bmpImage
, descr
->dibpitch
);
4551 if (descr
->compression
) {
4552 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
4553 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
4554 bmpImage
, descr
->xSrc
, descr
->ySrc
);
4556 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
4557 descr
->infoWidth
, descr
->width
,
4558 descr
->xSrc
, (int *)(descr
->colorMap
),
4561 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
4562 descr
->infoWidth
, descr
->width
,
4563 descr
->xSrc
, (int*)(descr
->colorMap
),
4564 bmpImage
, descr
->dibpitch
);
4567 if (descr
->compression
) {
4568 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
4569 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
4570 bmpImage
, descr
->xSrc
, descr
->ySrc
);
4571 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
4572 descr
->infoWidth
, descr
->width
,
4573 descr
->xSrc
, (int *)(descr
->colorMap
),
4576 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
4577 descr
->infoWidth
, descr
->width
,
4578 descr
->xSrc
, (int *)(descr
->colorMap
),
4579 bmpImage
, descr
->dibpitch
);
4583 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
4584 descr
->infoWidth
, descr
->width
,
4585 descr
->xSrc
, descr
->physDev
,
4586 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4587 bmpImage
, descr
->dibpitch
);
4590 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
4591 descr
->infoWidth
, descr
->width
,
4592 descr
->xSrc
, descr
->physDev
,
4593 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4594 bmpImage
, descr
->dibpitch
);
4597 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
4598 descr
->infoWidth
, descr
->width
,
4599 descr
->xSrc
, descr
->physDev
,
4600 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4601 bmpImage
, descr
->dibpitch
);
4604 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
4608 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
4609 descr
->drawable
, descr
->gc
, bmpImage
,
4610 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
4611 descr
->width
, descr
->height
);
4612 #ifdef HAVE_LIBXXSHM
4615 XShmPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
4616 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
4617 descr
->width
, descr
->height
, FALSE
);
4618 XSync( gdi_display
, 0 );
4622 XPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
4623 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
4624 descr
->width
, descr
->height
);
4626 if (!descr
->image
) XDestroyImage( bmpImage
);
4627 wine_tsx11_unlock();
4631 /***********************************************************************
4632 * X11DRV_DIB_GetImageBits
4634 * Transfer the bits from an X image.
4636 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
4638 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
4643 bmpImage
= descr
->image
;
4645 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
4646 descr
->infoWidth
, lines
, 32, 0 );
4647 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
4648 if(bmpImage
->data
== NULL
) {
4649 ERR("Out of memory!\n");
4650 XDestroyImage( bmpImage
);
4651 wine_tsx11_unlock();
4656 #ifdef HAVE_LIBXXSHM
4659 int saveRed
, saveGreen
, saveBlue
;
4661 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
4662 gdi_display
, descr
->drawable
, bmpImage
,
4663 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
4665 /* We must save and restore the bmpImage's masks in order
4666 * to preserve them across the call to XShmGetImage, which
4667 * decides to eleminate them since it doesn't happen to know
4668 * what the format of the image is supposed to be, even though
4670 saveRed
= bmpImage
->red_mask
;
4671 saveBlue
= bmpImage
->blue_mask
;
4672 saveGreen
= bmpImage
->green_mask
;
4674 XShmGetImage( gdi_display
, descr
->drawable
, bmpImage
,
4675 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
4677 bmpImage
->red_mask
= saveRed
;
4678 bmpImage
->blue_mask
= saveBlue
;
4679 bmpImage
->green_mask
= saveGreen
;
4682 #endif /* HAVE_LIBXXSHM */
4684 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
4685 gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
, descr
->width
,
4686 lines
, AllPlanes
, ZPixmap
, bmpImage
, descr
->xDest
, descr
->yDest
);
4687 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
,
4688 descr
->width
, lines
, AllPlanes
, ZPixmap
,
4689 bmpImage
, descr
->xDest
, descr
->yDest
);
4692 TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
4693 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
4694 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
4695 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
4696 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4697 /* Transfer the pixels */
4698 switch(descr
->infoBpp
)
4701 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
4702 descr
->infoWidth
, descr
->width
,
4703 descr
->colorMap
, descr
->palentry
,
4704 bmpImage
, descr
->dibpitch
);
4708 if (descr
->compression
)
4709 FIXME("Compression not yet supported!\n");
4711 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
4712 descr
->infoWidth
, descr
->width
,
4713 descr
->colorMap
, descr
->palentry
,
4714 bmpImage
, descr
->dibpitch
);
4718 if (descr
->compression
)
4719 FIXME("Compression not yet supported!\n");
4721 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
4722 descr
->infoWidth
, descr
->width
,
4723 descr
->colorMap
, descr
->palentry
,
4724 bmpImage
, descr
->dibpitch
);
4728 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
4729 descr
->infoWidth
,descr
->width
,
4731 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4732 bmpImage
, descr
->dibpitch
);
4736 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
4737 descr
->infoWidth
,descr
->width
,
4739 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4740 bmpImage
, descr
->dibpitch
);
4744 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
4745 descr
->infoWidth
, descr
->width
,
4747 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4748 bmpImage
, descr
->dibpitch
);
4752 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
4756 if (!descr
->image
) XDestroyImage( bmpImage
);
4757 wine_tsx11_unlock();
4761 /*************************************************************************
4762 * X11DRV_SetDIBitsToDevice
4765 INT
X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE
*physDev
, INT xDest
, INT yDest
, DWORD cx
,
4766 DWORD cy
, INT xSrc
, INT ySrc
,
4767 UINT startscan
, UINT lines
, LPCVOID bits
,
4768 const BITMAPINFO
*info
, UINT coloruse
)
4770 X11DRV_DIB_IMAGEBITS_DESCR descr
;
4776 DC
*dc
= physDev
->dc
;
4778 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
4779 &descr
.infoBpp
, &descr
.compression
) == -1)
4781 top_down
= (height
< 0);
4782 if (top_down
) height
= -height
;
4786 LPtoDP(physDev
->hdc
, &pt
, 1);
4788 if (!lines
|| (startscan
>= height
)) return 0;
4789 if (!top_down
&& startscan
+ lines
> height
) lines
= height
- startscan
;
4791 /* make xSrc,ySrc point to the upper-left corner, not the lower-left one,
4792 * and clamp all values to fit inside [startscan,startscan+lines]
4794 if (ySrc
+ cy
<= startscan
+ lines
)
4796 INT y
= startscan
+ lines
- (ySrc
+ cy
);
4797 if (ySrc
< startscan
) cy
-= (startscan
- ySrc
);
4800 /* avoid getting unnecessary lines */
4802 if (y
>= lines
) return 0;
4807 if (y
>= lines
) return lines
;
4808 ySrc
= y
; /* need to get all lines in top down mode */
4813 if (ySrc
>= startscan
+ lines
) return lines
;
4814 pt
.y
+= ySrc
+ cy
- (startscan
+ lines
);
4815 cy
= startscan
+ lines
- ySrc
;
4817 if (cy
> lines
) cy
= lines
;
4819 if (xSrc
>= width
) return lines
;
4820 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
4821 if (!cx
|| !cy
) return lines
;
4823 X11DRV_SetupGCForText( physDev
); /* To have the correct colors */
4824 TSXSetFunction(gdi_display
, physDev
->gc
, X11DRV_XROPfunction
[dc
->ROPmode
-1]);
4826 switch (descr
.infoBpp
)
4831 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
4832 coloruse
== DIB_PAL_COLORS
? physDev
: NULL
, coloruse
,
4833 dc
->bitsPerPixel
, info
, &descr
.nColorMap
);
4834 if (!descr
.colorMap
) return 0;
4835 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
4839 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
4840 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
4841 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
4847 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
4848 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
4849 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
4854 descr
.physDev
= physDev
;
4857 descr
.palentry
= NULL
;
4858 descr
.lines
= top_down
? -lines
: lines
;
4859 descr
.infoWidth
= width
;
4860 descr
.depth
= dc
->bitsPerPixel
;
4861 descr
.drawable
= physDev
->drawable
;
4862 descr
.gc
= physDev
->gc
;
4865 descr
.xDest
= physDev
->org
.x
+ pt
.x
;
4866 descr
.yDest
= physDev
->org
.y
+ pt
.y
;
4869 descr
.useShm
= FALSE
;
4870 descr
.dibpitch
= ((width
* descr
.infoBpp
+ 31) &~31) / 8;
4872 result
= X11DRV_DIB_SetImageBits( &descr
);
4874 if (descr
.infoBpp
<= 8)
4875 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
4879 /***********************************************************************
4880 * SetDIBits (X11DRV.@)
4882 INT
X11DRV_SetDIBits( X11DRV_PDEVICE
*physDev
, HBITMAP hbitmap
, UINT startscan
,
4883 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
, UINT coloruse
)
4885 X11DRV_DIB_IMAGEBITS_DESCR descr
;
4887 int height
, tmpheight
;
4890 descr
.physDev
= physDev
;
4892 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
4893 &descr
.infoBpp
, &descr
.compression
) == -1)
4897 if (height
< 0) height
= -height
;
4898 if (!lines
|| (startscan
>= height
))
4901 if (!(bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
))) return 0;
4903 if (startscan
+ lines
> height
) lines
= height
- startscan
;
4905 switch (descr
.infoBpp
)
4910 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
4911 coloruse
== DIB_PAL_COLORS
? descr
.physDev
: NULL
, coloruse
,
4912 bmp
->bitmap
.bmBitsPixel
,
4913 info
, &descr
.nColorMap
);
4914 if (!descr
.colorMap
)
4916 GDI_ReleaseObj( hbitmap
);
4919 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
4923 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
4924 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
4925 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
4931 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
4932 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
4933 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
4942 descr
.palentry
= NULL
;
4943 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
4944 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
4945 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
4946 descr
.gc
= BITMAP_GC(bmp
);
4950 descr
.yDest
= height
- startscan
- lines
;
4951 descr
.width
= bmp
->bitmap
.bmWidth
;
4952 descr
.height
= lines
;
4953 descr
.useShm
= FALSE
;
4954 descr
.dibpitch
= ((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8;
4955 X11DRV_DIB_Lock(bmp
, DIB_Status_GdiMod
, FALSE
);
4956 result
= X11DRV_DIB_SetImageBits( &descr
);
4957 X11DRV_DIB_Unlock(bmp
, TRUE
);
4959 if (descr
.colorMap
) HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
4961 GDI_ReleaseObj( hbitmap
);
4965 /***********************************************************************
4966 * GetDIBits (X11DRV.@)
4968 INT
X11DRV_GetDIBits( X11DRV_PDEVICE
*physDev
, HBITMAP hbitmap
, UINT startscan
, UINT lines
,
4969 LPVOID bits
, BITMAPINFO
*info
, UINT coloruse
)
4971 X11DRV_DIBSECTION
*dib
;
4972 X11DRV_DIB_IMAGEBITS_DESCR descr
;
4973 PALETTEOBJ
* palette
;
4976 DC
*dc
= physDev
->dc
;
4978 if (!(palette
= (PALETTEOBJ
*)GDI_GetObjPtr( dc
->hPalette
, PALETTE_MAGIC
)))
4980 if (!(bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
)))
4982 GDI_ReleaseObj( dc
->hPalette
);
4985 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4987 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
4988 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
4989 (int)info
->bmiHeader
.biWidth
, (int)info
->bmiHeader
.biHeight
,
4992 if( lines
> bmp
->bitmap
.bmHeight
) lines
= bmp
->bitmap
.bmHeight
;
4994 height
= info
->bmiHeader
.biHeight
;
4995 if (height
< 0) height
= -height
;
4996 if( lines
> height
) lines
= height
;
4997 /* Top-down images have a negative biHeight, the scanlines of theses images
4998 * were inverted in X11DRV_DIB_GetImageBits_xx
4999 * To prevent this we simply change the sign of lines
5000 * (the number of scan lines to copy).
5001 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
5003 if( info
->bmiHeader
.biHeight
< 0 && lines
> 0) lines
= -lines
;
5005 if( startscan
>= bmp
->bitmap
.bmHeight
)
5011 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &descr
.lines
,
5012 &descr
.infoBpp
, &descr
.compression
) == -1)
5018 switch (descr
.infoBpp
)
5023 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
5027 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
5028 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
5029 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
5033 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
5034 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
5035 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
5039 descr
.physDev
= physDev
;
5040 descr
.palentry
= palette
->logpalette
.palPalEntry
;
5043 descr
.lines
= lines
;
5044 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
5045 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
5046 descr
.gc
= BITMAP_GC(bmp
);
5047 descr
.width
= bmp
->bitmap
.bmWidth
;
5048 descr
.height
= bmp
->bitmap
.bmHeight
;
5049 descr
.colorMap
= info
->bmiColors
;
5054 if (descr
.lines
> 0)
5056 descr
.ySrc
= (descr
.height
-1) - (startscan
+ (lines
-1));
5060 descr
.ySrc
= startscan
;
5062 #ifdef HAVE_LIBXXSHM
5063 descr
.useShm
= dib
? (dib
->shminfo
.shmid
!= -1) : FALSE
;
5065 descr
.useShm
= FALSE
;
5067 descr
.dibpitch
= dib
? (dib
->dibSection
.dsBm
.bmWidthBytes
)
5068 : (((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8);
5070 X11DRV_DIB_Lock(bmp
, DIB_Status_GdiMod
, FALSE
);
5071 X11DRV_DIB_GetImageBits( &descr
);
5072 X11DRV_DIB_Unlock(bmp
, TRUE
);
5074 if(info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
5075 info
->bmiHeader
.biSizeImage
= DIB_GetDIBImageBytes(
5076 info
->bmiHeader
.biWidth
,
5077 info
->bmiHeader
.biHeight
,
5078 info
->bmiHeader
.biBitCount
);
5080 if (descr
.compression
== BI_BITFIELDS
)
5082 *(DWORD
*)info
->bmiColors
= descr
.rMask
;
5083 *((DWORD
*)info
->bmiColors
+1) = descr
.gMask
;
5084 *((DWORD
*)info
->bmiColors
+2) = descr
.bMask
;
5088 /* if RLE or JPEG compression were supported,
5089 * this line would be invalid. */
5090 info
->bmiHeader
.biCompression
= 0;
5094 GDI_ReleaseObj( dc
->hPalette
);
5095 GDI_ReleaseObj( hbitmap
);
5099 /***********************************************************************
5100 * DIB_DoProtectDIBSection
5102 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
5104 DIBSECTION
*dib
= bmp
->dib
;
5105 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
5106 : -dib
->dsBm
.bmHeight
;
5107 /* use the biSizeImage data as the memory size only if we're dealing with a
5108 compressed image where the value is set. Otherwise, calculate based on
5110 INT totalSize
= dib
->dsBmih
.biSizeImage
&& dib
->dsBmih
.biCompression
!= BI_RGB
5111 ? dib
->dsBmih
.biSizeImage
5112 : dib
->dsBm
.bmWidthBytes
* effHeight
;
5115 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
5116 TRACE("Changed protection from %ld to %ld\n", old_prot
, new_prot
);
5119 /***********************************************************************
5120 * X11DRV_DIB_DoUpdateDIBSection
5122 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
,
5123 void *colorMap
, int nColorMap
,
5125 DWORD xSrc
, DWORD ySrc
,
5126 DWORD xDest
, DWORD yDest
,
5127 DWORD width
, DWORD height
)
5129 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5130 X11DRV_DIB_IMAGEBITS_DESCR descr
;
5132 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, &descr
.lines
,
5133 &descr
.infoBpp
, &descr
.compression
) == -1)
5136 descr
.physDev
= NULL
;
5137 descr
.palentry
= NULL
;
5138 descr
.image
= dib
->image
;
5139 descr
.colorMap
= colorMap
;
5140 descr
.nColorMap
= nColorMap
;
5141 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
5142 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
5144 switch (descr
.infoBpp
)
5149 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
5153 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0x7c00;
5154 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x03e0;
5155 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x001f;
5160 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0xff0000;
5161 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x00ff00;
5162 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x0000ff;
5167 descr
.drawable
= dest
;
5168 descr
.gc
= BITMAP_GC(bmp
);
5171 descr
.xDest
= xDest
;
5172 descr
.yDest
= yDest
;
5173 descr
.width
= width
;
5174 descr
.height
= height
;
5175 #ifdef HAVE_LIBXXSHM
5176 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
5178 descr
.useShm
= FALSE
;
5180 descr
.dibpitch
= dib
->dibSection
.dsBm
.bmWidthBytes
;
5184 TRACE("Copying from Pixmap to DIB bits\n");
5185 X11DRV_DIB_GetImageBits( &descr
);
5189 TRACE("Copying from DIB bits to Pixmap\n");
5190 X11DRV_DIB_SetImageBits( &descr
);
5194 /***********************************************************************
5195 * X11DRV_DIB_CopyDIBSection
5197 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE
*physDevSrc
, X11DRV_PDEVICE
*physDevDst
,
5198 DWORD xSrc
, DWORD ySrc
, DWORD xDest
, DWORD yDest
,
5199 DWORD width
, DWORD height
)
5202 DC
*dcSrc
= physDevSrc
->dc
;
5203 DC
*dcDst
= physDevDst
->dc
;
5204 int nColorMap
= 0, *colorMap
= NULL
, aColorMap
= FALSE
;
5206 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc
, dcDst
,
5207 xSrc
, ySrc
, xDest
, yDest
, width
, height
);
5208 /* this function is meant as an optimization for BitBlt,
5209 * not to be called otherwise */
5210 if (!(dcSrc
->flags
& DC_MEMORY
)) {
5211 ERR("called for non-memory source DC!?\n");
5215 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( dcSrc
->hBitmap
, BITMAP_MAGIC
);
5216 if (!(bmp
&& bmp
->dib
)) {
5217 ERR("called for non-DIBSection!?\n");
5218 GDI_ReleaseObj( dcSrc
->hBitmap
);
5221 /* while BitBlt should already have made sure we only get
5222 * positive values, we should check for oversize values */
5223 if ((xSrc
< bmp
->bitmap
.bmWidth
) &&
5224 (ySrc
< bmp
->bitmap
.bmHeight
)) {
5225 if (xSrc
+ width
> bmp
->bitmap
.bmWidth
)
5226 width
= bmp
->bitmap
.bmWidth
- xSrc
;
5227 if (ySrc
+ height
> bmp
->bitmap
.bmHeight
)
5228 height
= bmp
->bitmap
.bmHeight
- ySrc
;
5229 /* if the source bitmap is 8bpp or less, we're supposed to use the
5230 * DC's palette for color conversion (not the DIB color table) */
5231 if (bmp
->dib
->dsBm
.bmBitsPixel
<= 8) {
5232 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5233 if ((!dcSrc
->hPalette
) ||
5234 (dcSrc
->hPalette
== GetStockObject(DEFAULT_PALETTE
))) {
5235 /* HACK: no palette has been set in the source DC,
5236 * use the DIB colormap instead - this is necessary in some
5237 * cases since we need to do depth conversion in some places
5238 * where real Windows can just copy data straight over */
5239 colorMap
= dib
->colorMap
;
5240 nColorMap
= dib
->nColorMap
;
5242 colorMap
= X11DRV_DIB_BuildColorMap( physDevSrc
, (WORD
)-1,
5243 bmp
->dib
->dsBm
.bmBitsPixel
,
5244 (BITMAPINFO
*)&(bmp
->dib
->dsBmih
),
5246 if (colorMap
) aColorMap
= TRUE
;
5249 /* perform the copy */
5250 X11DRV_DIB_DoCopyDIBSection(bmp
, FALSE
, colorMap
, nColorMap
,
5251 physDevDst
->drawable
, xSrc
, ySrc
,
5252 physDevDst
->org
.x
+ xDest
, physDevDst
->org
.y
+ yDest
,
5254 /* free color mapping */
5256 HeapFree(GetProcessHeap(), 0, colorMap
);
5258 GDI_ReleaseObj( dcSrc
->hBitmap
);
5261 /***********************************************************************
5262 * X11DRV_DIB_DoUpdateDIBSection
5264 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
5266 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5267 X11DRV_DIB_DoCopyDIBSection(bmp
, toDIB
, dib
->colorMap
, dib
->nColorMap
,
5268 (Drawable
)bmp
->physBitmap
, 0, 0, 0, 0,
5269 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
5272 /***********************************************************************
5273 * X11DRV_DIB_FaultHandler
5275 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
5280 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
5281 if (!bmp
) return FALSE
;
5283 state
= X11DRV_DIB_Lock(bmp
, DIB_Status_None
, FALSE
);
5284 if (state
!= DIB_Status_InSync
) {
5285 /* no way to tell whether app needs read or write yet,
5287 X11DRV_DIB_Coerce(bmp
, DIB_Status_InSync
, FALSE
);
5289 /* hm, apparently the app must have write access */
5290 X11DRV_DIB_Coerce(bmp
, DIB_Status_AppMod
, FALSE
);
5292 X11DRV_DIB_Unlock(bmp
, TRUE
);
5294 GDI_ReleaseObj( (HBITMAP
)res
);
5298 /***********************************************************************
5301 INT
X11DRV_DIB_Coerce(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
5303 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5304 INT ret
= DIB_Status_None
;
5307 EnterCriticalSection(&(dib
->lock
));
5310 case DIB_Status_GdiMod
:
5311 /* GDI access - request to draw on pixmap */
5312 switch (dib
->status
)
5315 case DIB_Status_None
:
5316 dib
->p_status
= DIB_Status_GdiMod
;
5317 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
5320 case DIB_Status_GdiMod
:
5321 TRACE("GdiMod requested in status GdiMod\n" );
5324 case DIB_Status_InSync
:
5325 TRACE("GdiMod requested in status InSync\n" );
5326 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
5327 dib
->status
= DIB_Status_GdiMod
;
5328 dib
->p_status
= DIB_Status_InSync
;
5331 case DIB_Status_AuxMod
:
5332 TRACE("GdiMod requested in status AuxMod\n" );
5333 if (lossy
) dib
->status
= DIB_Status_GdiMod
;
5334 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_GdiMod
);
5335 dib
->p_status
= DIB_Status_AuxMod
;
5336 if (dib
->status
!= DIB_Status_AppMod
) {
5337 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
5340 /* fall through if copy_aux() had to change to AppMod state */
5342 case DIB_Status_AppMod
:
5343 TRACE("GdiMod requested in status AppMod\n" );
5345 /* make it readonly to avoid app changing data while we copy */
5346 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5347 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
5349 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
5350 dib
->p_status
= DIB_Status_AppMod
;
5351 dib
->status
= DIB_Status_GdiMod
;
5356 case DIB_Status_InSync
:
5357 /* App access - request access to read DIB surface */
5358 /* (typically called from signal handler) */
5359 switch (dib
->status
)
5362 case DIB_Status_None
:
5363 /* shouldn't happen from signal handler */
5366 case DIB_Status_AuxMod
:
5367 TRACE("InSync requested in status AuxMod\n" );
5368 if (lossy
) dib
->status
= DIB_Status_InSync
;
5370 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5371 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_InSync
);
5373 if (dib
->status
!= DIB_Status_GdiMod
) {
5374 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5377 /* fall through if copy_aux() had to change to GdiMod state */
5379 case DIB_Status_GdiMod
:
5380 TRACE("InSync requested in status GdiMod\n" );
5382 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5383 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
5385 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5386 dib
->status
= DIB_Status_InSync
;
5389 case DIB_Status_InSync
:
5390 TRACE("InSync requested in status InSync\n" );
5391 /* shouldn't happen from signal handler */
5394 case DIB_Status_AppMod
:
5395 TRACE("InSync requested in status AppMod\n" );
5396 /* no reason to do anything here, and this
5397 * shouldn't happen from signal handler */
5402 case DIB_Status_AppMod
:
5403 /* App access - request access to write DIB surface */
5404 /* (typically called from signal handler) */
5405 switch (dib
->status
)
5408 case DIB_Status_None
:
5409 /* shouldn't happen from signal handler */
5412 case DIB_Status_AuxMod
:
5413 TRACE("AppMod requested in status AuxMod\n" );
5414 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5415 if (lossy
) dib
->status
= DIB_Status_AppMod
;
5416 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
5417 if (dib
->status
!= DIB_Status_GdiMod
)
5419 /* fall through if copy_aux() had to change to GdiMod state */
5421 case DIB_Status_GdiMod
:
5422 TRACE("AppMod requested in status GdiMod\n" );
5423 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5424 if (!lossy
) X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
5425 dib
->status
= DIB_Status_AppMod
;
5428 case DIB_Status_InSync
:
5429 TRACE("AppMod requested in status InSync\n" );
5430 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5431 dib
->status
= DIB_Status_AppMod
;
5434 case DIB_Status_AppMod
:
5435 TRACE("AppMod requested in status AppMod\n" );
5436 /* shouldn't happen from signal handler */
5441 case DIB_Status_AuxMod
:
5442 if (dib
->status
== DIB_Status_None
) {
5443 dib
->p_status
= req
;
5445 if (dib
->status
!= DIB_Status_AuxMod
)
5446 dib
->p_status
= dib
->status
;
5447 dib
->status
= DIB_Status_AuxMod
;
5450 /* it is up to the caller to do the copy/conversion, probably
5451 * using the return value to decide where to copy from */
5453 LeaveCriticalSection(&(dib
->lock
));
5458 /***********************************************************************
5461 INT
X11DRV_DIB_Lock(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
5463 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5464 INT ret
= DIB_Status_None
;
5467 TRACE("Locking %p from thread %08lx\n", bmp
, GetCurrentThreadId());
5468 EnterCriticalSection(&(dib
->lock
));
5470 if (req
!= DIB_Status_None
)
5471 X11DRV_DIB_Coerce(bmp
, req
, lossy
);
5476 /***********************************************************************
5479 void X11DRV_DIB_Unlock(BITMAPOBJ
*bmp
, BOOL commit
)
5481 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5484 switch (dib
->status
)
5487 case DIB_Status_None
:
5488 /* in case anyone is wondering, this is the "signal handler doesn't
5489 * work" case, where we always have to be ready for app access */
5491 switch (dib
->p_status
)
5493 case DIB_Status_AuxMod
:
5494 TRACE("Unlocking and syncing from AuxMod\n" );
5495 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
5496 if (dib
->status
!= DIB_Status_None
) {
5497 dib
->p_status
= dib
->status
;
5498 dib
->status
= DIB_Status_None
;
5500 if (dib
->p_status
!= DIB_Status_GdiMod
)
5502 /* fall through if copy_aux() had to change to GdiMod state */
5504 case DIB_Status_GdiMod
:
5505 TRACE("Unlocking and syncing from GdiMod\n" );
5506 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
5510 TRACE("Unlocking without needing to sync\n" );
5514 else TRACE("Unlocking with no changes\n");
5515 dib
->p_status
= DIB_Status_None
;
5518 case DIB_Status_GdiMod
:
5519 TRACE("Unlocking in status GdiMod\n" );
5520 /* DIB was protected in Coerce */
5522 /* no commit, revert to InSync if applicable */
5523 if ((dib
->p_status
== DIB_Status_InSync
) ||
5524 (dib
->p_status
== DIB_Status_AppMod
)) {
5525 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5526 dib
->status
= DIB_Status_InSync
;
5531 case DIB_Status_InSync
:
5532 TRACE("Unlocking in status InSync\n" );
5533 /* DIB was already protected in Coerce */
5536 case DIB_Status_AppMod
:
5537 TRACE("Unlocking in status AppMod\n" );
5538 /* DIB was already protected in Coerce */
5539 /* this case is ordinary only called from the signal handler,
5540 * so we don't bother to check for !commit */
5543 case DIB_Status_AuxMod
:
5544 TRACE("Unlocking in status AuxMod\n" );
5546 /* DIB may need protection now */
5547 if ((dib
->p_status
== DIB_Status_InSync
) ||
5548 (dib
->p_status
== DIB_Status_AppMod
))
5549 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
5551 /* no commit, revert to previous state */
5552 if (dib
->p_status
!= DIB_Status_None
)
5553 dib
->status
= dib
->p_status
;
5554 /* no protections changed */
5556 dib
->p_status
= DIB_Status_None
;
5559 LeaveCriticalSection(&(dib
->lock
));
5560 TRACE("Unlocked %p\n", bmp
);
5564 /***********************************************************************
5565 * X11DRV_CoerceDIBSection2
5567 INT
X11DRV_CoerceDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
5572 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5573 if (!bmp
) return DIB_Status_None
;
5574 ret
= X11DRV_DIB_Coerce(bmp
, req
, lossy
);
5575 GDI_ReleaseObj( hBmp
);
5579 /***********************************************************************
5580 * X11DRV_LockDIBSection2
5582 INT
X11DRV_LockDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
5587 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5588 if (!bmp
) return DIB_Status_None
;
5589 ret
= X11DRV_DIB_Lock(bmp
, req
, lossy
);
5590 GDI_ReleaseObj( hBmp
);
5594 /***********************************************************************
5595 * X11DRV_UnlockDIBSection2
5597 void X11DRV_UnlockDIBSection2(HBITMAP hBmp
, BOOL commit
)
5601 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5603 X11DRV_DIB_Unlock(bmp
, commit
);
5604 GDI_ReleaseObj( hBmp
);
5607 /***********************************************************************
5608 * X11DRV_CoerceDIBSection
5610 INT
X11DRV_CoerceDIBSection(X11DRV_PDEVICE
*physDev
, INT req
, BOOL lossy
)
5612 if (!physDev
) return DIB_Status_None
;
5613 return X11DRV_CoerceDIBSection2( physDev
->dc
->hBitmap
, req
, lossy
);
5616 /***********************************************************************
5617 * X11DRV_LockDIBSection
5619 INT
X11DRV_LockDIBSection(X11DRV_PDEVICE
*physDev
, INT req
, BOOL lossy
)
5621 if (!physDev
) return DIB_Status_None
;
5622 if (!(physDev
->dc
->flags
& DC_MEMORY
)) return DIB_Status_None
;
5624 return X11DRV_LockDIBSection2( physDev
->dc
->hBitmap
, req
, lossy
);
5627 /***********************************************************************
5628 * X11DRV_UnlockDIBSection
5630 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE
*physDev
, BOOL commit
)
5632 if (!physDev
) return;
5633 if (!(physDev
->dc
->flags
& DC_MEMORY
)) return;
5635 X11DRV_UnlockDIBSection2( physDev
->dc
->hBitmap
, commit
);
5639 #ifdef HAVE_LIBXXSHM
5640 /***********************************************************************
5641 * X11DRV_XShmErrorHandler
5644 static int XShmErrorHandler( Display
*dpy
, XErrorEvent
*event
, void *arg
)
5646 return 1; /* FIXME: should check event contents */
5649 /***********************************************************************
5650 * X11DRV_XShmCreateImage
5653 static XImage
*X11DRV_XShmCreateImage( int width
, int height
, int bpp
,
5654 XShmSegmentInfo
* shminfo
)
5658 image
= XShmCreateImage(gdi_display
, visual
, bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
5661 shminfo
->shmid
= shmget(IPC_PRIVATE
, image
->bytes_per_line
* height
,
5663 if( shminfo
->shmid
!= -1 )
5665 shminfo
->shmaddr
= image
->data
= shmat(shminfo
->shmid
, 0, 0);
5666 if( shminfo
->shmaddr
!= (char*)-1 )
5670 shminfo
->readOnly
= FALSE
;
5671 X11DRV_expect_error( gdi_display
, XShmErrorHandler
, NULL
);
5672 ok
= (XShmAttach( gdi_display
, shminfo
) != 0);
5673 if (X11DRV_check_error()) ok
= FALSE
;
5676 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
5677 return image
; /* Success! */
5679 /* An error occured */
5680 shmdt(shminfo
->shmaddr
);
5682 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
5684 XFlush(gdi_display
);
5685 XDestroyImage(image
);
5690 #endif /* HAVE_LIBXXSHM */
5693 /***********************************************************************
5694 * X11DRV_DIB_CreateDIBSection
5696 HBITMAP
X11DRV_DIB_CreateDIBSection(
5697 X11DRV_PDEVICE
*physDev
, BITMAPINFO
*bmi
, UINT usage
,
5698 LPVOID
*bits
, HANDLE section
,
5699 DWORD offset
, DWORD ovr_pitch
)
5702 BITMAPOBJ
*bmp
= NULL
;
5703 X11DRV_DIBSECTION
*dib
= NULL
;
5704 int *colorMap
= NULL
;
5707 /* Fill BITMAP32 structure with DIB data */
5708 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
5709 INT effHeight
, totalSize
;
5711 LPVOID mapBits
= NULL
;
5713 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
5714 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
5715 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
5717 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
5719 bm
.bmWidth
= bi
->biWidth
;
5720 bm
.bmHeight
= effHeight
;
5721 bm
.bmWidthBytes
= ovr_pitch
? ovr_pitch
5722 : DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
5723 bm
.bmPlanes
= bi
->biPlanes
;
5724 bm
.bmBitsPixel
= bi
->biBitCount
;
5727 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
5728 we're dealing with a compressed bitmap. Otherwise, use width * height. */
5729 totalSize
= bi
->biSizeImage
&& bi
->biCompression
!= BI_RGB
5730 ? bi
->biSizeImage
: bm
.bmWidthBytes
* effHeight
;
5734 SYSTEM_INFO SystemInfo
;
5738 GetSystemInfo( &SystemInfo
);
5739 mapOffset
= offset
- (offset
% SystemInfo
.dwAllocationGranularity
);
5740 mapSize
= totalSize
+ (offset
- mapOffset
);
5741 mapBits
= MapViewOfFile( section
,
5742 FILE_MAP_ALL_ACCESS
,
5746 bm
.bmBits
= (char *)mapBits
+ (offset
- mapOffset
);
5748 else if (ovr_pitch
&& offset
)
5749 bm
.bmBits
= (LPVOID
) offset
;
5752 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
5753 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
5756 /* Create Color Map */
5757 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8)
5758 colorMap
= X11DRV_DIB_BuildColorMap( usage
== DIB_PAL_COLORS
? physDev
: NULL
,
5759 usage
, bm
.bmBitsPixel
, bmi
, &nColorMap
);
5761 /* Allocate Memory for DIB and fill structure */
5763 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
5766 dib
->dibSection
.dsBm
= bm
;
5767 dib
->dibSection
.dsBmih
= *bi
;
5768 dib
->dibSection
.dsBmih
.biSizeImage
= totalSize
;
5770 /* Set dsBitfields values */
5771 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
5773 dib
->dibSection
.dsBitfields
[0] = dib
->dibSection
.dsBitfields
[1] = dib
->dibSection
.dsBitfields
[2] = 0;
5775 else switch( bi
->biBitCount
)
5779 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
5780 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
5781 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f;
5786 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff0000;
5787 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x00ff00;
5788 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x0000ff;
5791 dib
->dibSection
.dshSection
= section
;
5792 dib
->dibSection
.dsOffset
= offset
;
5794 dib
->status
= DIB_Status_None
;
5795 dib
->nColorMap
= nColorMap
;
5796 dib
->colorMap
= colorMap
;
5799 /* Create Device Dependent Bitmap and add DIB pointer */
5802 res
= CreateDIBitmap(physDev
->hdc
, bi
, 0, NULL
, bmi
, usage
);
5805 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
5806 if (bmp
) bmp
->dib
= (DIBSECTION
*) dib
;
5814 #ifdef HAVE_LIBXXSHM
5815 if (XShmQueryExtension(gdi_display
) &&
5816 (dib
->image
= X11DRV_XShmCreateImage( bm
.bmWidth
, effHeight
,
5817 bmp
->bitmap
.bmBitsPixel
, &dib
->shminfo
)) )
5819 ; /* Created Image */
5821 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
5822 dib
->shminfo
.shmid
= -1;
5825 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
5827 wine_tsx11_unlock();
5830 /* Clean up in case of errors */
5831 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
5833 TRACE("got an error res=%p, bmp=%p, dib=%p, bm.bmBits=%p\n",
5834 res
, bmp
, dib
, bm
.bmBits
);
5838 UnmapViewOfFile(mapBits
), bm
.bmBits
= NULL
;
5840 VirtualFree(bm
.bmBits
, 0L, MEM_RELEASE
), bm
.bmBits
= NULL
;
5843 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
5844 if (colorMap
) { HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
; }
5845 if (dib
) { HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
; }
5846 if (bmp
) { GDI_ReleaseObj(res
); bmp
= NULL
; }
5847 if (res
) { DeleteObject(res
); res
= 0; }
5851 /* Install fault handler, if possible */
5852 InitializeCriticalSection(&(dib
->lock
));
5853 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
5855 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5856 if (dib
) dib
->status
= DIB_Status_AppMod
;
5860 /* Return BITMAP handle and storage location */
5861 if (bmp
) GDI_ReleaseObj(res
);
5862 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
5866 /***********************************************************************
5867 * X11DRV_DIB_DeleteDIBSection
5869 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
5871 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5876 #ifdef HAVE_LIBXXSHM
5877 if (dib
->shminfo
.shmid
!= -1)
5879 XShmDetach (gdi_display
, &(dib
->shminfo
));
5880 XDestroyImage (dib
->image
);
5881 shmdt (dib
->shminfo
.shmaddr
);
5882 dib
->shminfo
.shmid
= -1;
5886 XDestroyImage( dib
->image
);
5887 wine_tsx11_unlock();
5891 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
5893 DeleteCriticalSection(&(dib
->lock
));
5896 /***********************************************************************
5897 * SetDIBColorTable (X11DRV.@)
5899 UINT
X11DRV_SetDIBColorTable( X11DRV_PDEVICE
*physDev
, UINT start
, UINT count
, const RGBQUAD
*colors
)
5902 X11DRV_DIBSECTION
*dib
;
5905 if (!(bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( physDev
->dc
->hBitmap
, BITMAP_MAGIC
))) return 0;
5906 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5908 if (dib
&& dib
->colorMap
) {
5909 UINT end
= count
+ start
;
5910 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
5912 * Changing color table might change the mapping between
5913 * DIB colors and X11 colors and thus alter the visible state
5914 * of the bitmap object.
5916 X11DRV_DIB_Lock(bmp
, DIB_Status_AppMod
, FALSE
);
5917 X11DRV_DIB_GenColorMap( physDev
, dib
->colorMap
, DIB_RGB_COLORS
,
5918 dib
->dibSection
.dsBm
.bmBitsPixel
,
5919 TRUE
, colors
, start
, end
);
5920 X11DRV_DIB_Unlock(bmp
, TRUE
);
5923 GDI_ReleaseObj( physDev
->dc
->hBitmap
);
5927 /***********************************************************************
5928 * GetDIBColorTable (X11DRV.@)
5930 UINT
X11DRV_GetDIBColorTable( X11DRV_PDEVICE
*physDev
, UINT start
, UINT count
, RGBQUAD
*colors
)
5933 X11DRV_DIBSECTION
*dib
;
5936 if (!(bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( physDev
->dc
->hBitmap
, BITMAP_MAGIC
))) return 0;
5937 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5939 if (dib
&& dib
->colorMap
) {
5940 UINT i
, end
= count
+ start
;
5941 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
5942 for (i
= start
; i
< end
; i
++,colors
++) {
5943 COLORREF col
= X11DRV_PALETTE_ToLogical( dib
->colorMap
[i
] );
5944 colors
->rgbBlue
= GetBValue(col
);
5945 colors
->rgbGreen
= GetGValue(col
);
5946 colors
->rgbRed
= GetRValue(col
);
5947 colors
->rgbReserved
= 0;
5951 GDI_ReleaseObj( physDev
->dc
->hBitmap
);
5956 /**************************************************************************
5957 * X11DRV_DIB_CreateDIBFromPixmap
5959 * Allocates a packed DIB and copies the Pixmap data into it.
5960 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
5962 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
, BOOL bDeletePixmap
)
5965 BITMAPOBJ
*pBmp
= NULL
;
5966 HGLOBAL hPackedDIB
= 0;
5968 /* Allocates an HBITMAP which references the Pixmap passed to us */
5969 hBmp
= X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap
);
5972 TRACE("\tCould not create bitmap header for Pixmap\n");
5977 * Create a packed DIB from the Pixmap wrapper bitmap created above.
5978 * A packed DIB contains a BITMAPINFO structure followed immediately by
5979 * an optional color palette and the pixel data.
5981 hPackedDIB
= DIB_CreateDIBFromBitmap(hdc
, hBmp
);
5983 /* Get a pointer to the BITMAPOBJ structure */
5984 pBmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5986 /* We can now get rid of the HBITMAP wrapper we created earlier.
5987 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
5991 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
5992 pBmp
->physBitmap
= NULL
;
5995 GDI_ReleaseObj( hBmp
);
5999 TRACE("\tReturning packed DIB %p\n", hPackedDIB
);
6004 /**************************************************************************
6005 * X11DRV_DIB_CreatePixmapFromDIB
6007 * Creates a Pixmap from a packed DIB
6009 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
6011 Pixmap pixmap
= None
;
6013 BITMAPOBJ
*pBmp
= NULL
;
6014 LPBYTE pPackedDIB
= NULL
;
6015 LPBITMAPINFO pbmi
= NULL
;
6016 LPBITMAPINFOHEADER pbmiHeader
= NULL
;
6017 LPBYTE pbits
= NULL
;
6019 /* Get a pointer to the packed DIB's data */
6020 pPackedDIB
= (LPBYTE
)GlobalLock(hPackedDIB
);
6021 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
6022 pbmi
= (LPBITMAPINFO
)pPackedDIB
;
6023 pbits
= (LPBYTE
)(pPackedDIB
6024 + DIB_BitmapInfoSize( (LPBITMAPINFO
)pbmiHeader
, DIB_RGB_COLORS
));
6026 /* Create a DDB from the DIB */
6028 hBmp
= CreateDIBitmap(hdc
,
6035 GlobalUnlock(hPackedDIB
);
6037 TRACE("CreateDIBitmap returned %p\n", hBmp
);
6039 /* Retrieve the internal Pixmap from the DDB */
6041 pBmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
6043 pixmap
= (Pixmap
)pBmp
->physBitmap
;
6044 /* clear the physBitmap so that we can steal its pixmap */
6045 pBmp
->physBitmap
= NULL
;
6048 /* Delete the DDB we created earlier now that we have stolen its pixmap */
6049 GDI_ReleaseObj( hBmp
);
6052 TRACE("\tReturning Pixmap %ld\n", pixmap
);