2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 # ifdef HAVE_SYS_SHM_H
30 # ifdef HAVE_SYS_IPC_H
33 #endif /* defined(HAVE_LIBXXSHM) */
40 #include "wine/debug.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(bitmap
);
46 WINE_DECLARE_DEBUG_CHANNEL(x11drv
);
48 static int ximageDepthTable
[32];
50 /* This structure holds the arguments for DIB_SetImageBits() */
53 X11DRV_PDEVICE
*physDev
;
56 PALETTEENTRY
*palentry
;
77 } X11DRV_DIB_IMAGEBITS_DESCR
;
82 RLE_EOL
= 0, /* End of line */
83 RLE_END
= 1, /* End of bitmap */
84 RLE_DELTA
= 2 /* Delta */
87 /***********************************************************************
88 * X11DRV_DIB_GetXImageWidthBytes
90 * Return the width of an X image in bytes
92 inline static int X11DRV_DIB_GetXImageWidthBytes( int width
, int depth
)
94 if (!depth
|| depth
> 32) goto error
;
96 if (!ximageDepthTable
[depth
-1])
98 XImage
*testimage
= XCreateImage( gdi_display
, visual
, depth
,
99 ZPixmap
, 0, NULL
, 1, 1, 32, 20 );
102 ximageDepthTable
[depth
-1] = testimage
->bits_per_pixel
;
103 XDestroyImage( testimage
);
105 else ximageDepthTable
[depth
-1] = -1;
107 if (ximageDepthTable
[depth
-1] != -1)
108 return (4 * ((width
* ximageDepthTable
[depth
-1] + 31) / 32));
111 WARN( "(%d): Unsupported depth\n", depth
);
116 /***********************************************************************
117 * X11DRV_DIB_CreateXImage
121 XImage
*X11DRV_DIB_CreateXImage( int width
, int height
, int depth
)
127 width_bytes
= X11DRV_DIB_GetXImageWidthBytes( width
, depth
);
128 image
= XCreateImage( gdi_display
, visual
, depth
, ZPixmap
, 0,
129 calloc( height
, width_bytes
),
130 width
, height
, 32, width_bytes
);
136 /***********************************************************************
137 * X11DRV_DIB_GenColorMap
139 * Fills the color map of a bitmap palette. Should not be called
140 * for a >8-bit deep bitmap.
142 int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE
*physDev
, int *colorMapping
,
143 WORD coloruse
, WORD depth
, BOOL quads
,
144 const void *colorPtr
, int start
, int end
)
148 if (coloruse
== DIB_RGB_COLORS
)
150 int max
= 1 << depth
;
152 if (end
> max
) end
= max
;
156 RGBQUAD
* rgb
= (RGBQUAD
*)colorPtr
;
158 if (depth
== 1) /* Monochrome */
159 for (i
= start
; i
< end
; i
++, rgb
++)
160 colorMapping
[i
] = (rgb
->rgbRed
+ rgb
->rgbGreen
+
161 rgb
->rgbBlue
> 255*3/2);
163 for (i
= start
; i
< end
; i
++, rgb
++)
164 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, RGB(rgb
->rgbRed
,
170 RGBTRIPLE
* rgb
= (RGBTRIPLE
*)colorPtr
;
172 if (depth
== 1) /* Monochrome */
173 for (i
= start
; i
< end
; i
++, rgb
++)
174 colorMapping
[i
] = (rgb
->rgbtRed
+ rgb
->rgbtGreen
+
175 rgb
->rgbtBlue
> 255*3/2);
177 for (i
= start
; i
< end
; i
++, rgb
++)
178 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, RGB(rgb
->rgbtRed
,
183 else /* DIB_PAL_COLORS */
186 WORD
* index
= (WORD
*)colorPtr
;
188 for (i
= start
; i
< end
; i
++, index
++)
189 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, PALETTEINDEX(*index
) );
191 for (i
= start
; i
< end
; i
++)
192 colorMapping
[i
] = X11DRV_PALETTE_ToPhysical( physDev
, PALETTEINDEX(i
) );
199 /***********************************************************************
200 * X11DRV_DIB_BuildColorMap
202 * Build the color map from the bitmap palette. Should not be called
203 * for a >8-bit deep bitmap.
205 int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE
*physDev
, WORD coloruse
, WORD depth
,
206 const BITMAPINFO
*info
, int *nColors
)
210 const void *colorPtr
;
213 if ((isInfo
= (info
->bmiHeader
.biSize
== sizeof(BITMAPINFOHEADER
))))
215 colors
= info
->bmiHeader
.biClrUsed
;
216 if (!colors
) colors
= 1 << info
->bmiHeader
.biBitCount
;
217 colorPtr
= info
->bmiColors
;
219 else /* assume BITMAPCOREINFO */
221 colors
= 1 << ((BITMAPCOREHEADER
*)&info
->bmiHeader
)->bcBitCount
;
222 colorPtr
= (WORD
*)((BITMAPCOREINFO
*)info
)->bmciColors
;
227 ERR("called with >256 colors!\n");
231 /* just so CopyDIBSection doesn't have to create an identity palette */
232 if (coloruse
== (WORD
)-1) colorPtr
= NULL
;
234 if (!(colorMapping
= (int *)HeapAlloc(GetProcessHeap(), 0,
235 colors
* sizeof(int) )))
239 return X11DRV_DIB_GenColorMap( physDev
, colorMapping
, coloruse
, depth
,
240 isInfo
, colorPtr
, 0, colors
);
244 /***********************************************************************
245 * X11DRV_DIB_MapColor
247 int X11DRV_DIB_MapColor( int *physMap
, int nPhysMap
, int phys
, int oldcol
)
251 if ((oldcol
< nPhysMap
) && (physMap
[oldcol
] == phys
))
254 for (color
= 0; color
< nPhysMap
; color
++)
255 if (physMap
[color
] == phys
)
258 WARN("Strange color %08x\n", phys
);
263 /*********************************************************************
264 * X11DRV_DIB_GetNearestIndex
266 * Helper for X11DRV_DIB_GetDIBits.
267 * Returns the nearest colour table index for a given RGB.
268 * Nearest is defined by minimizing the sum of the squares.
270 static INT
X11DRV_DIB_GetNearestIndex(RGBQUAD
*colormap
, int numColors
, BYTE r
, BYTE g
, BYTE b
)
272 INT i
, best
= -1, diff
, bestdiff
= -1;
275 for(color
= colormap
, i
= 0; i
< numColors
; color
++, i
++) {
276 diff
= (r
- color
->rgbRed
) * (r
- color
->rgbRed
) +
277 (g
- color
->rgbGreen
) * (g
- color
->rgbGreen
) +
278 (b
- color
->rgbBlue
) * (b
- color
->rgbBlue
);
281 if(best
== -1 || diff
< bestdiff
) {
288 /*********************************************************************
289 * X11DRV_DIB_MaskToShift
291 * Helper for X11DRV_DIB_GetDIBits.
292 * Returns the by how many bits to shift a given color so that it is
293 * in the proper position.
295 static INT
X11DRV_DIB_MaskToShift(DWORD mask
)
303 while ((mask
&1)==0) {
310 /***********************************************************************
311 * X11DRV_DIB_Convert_any_asis
313 * All X11DRV_DIB_Convert_Xxx functions take at least the following
316 * This is the width in pixel of the surface to copy. This may be less
317 * than the full width of the image.
319 * The number of lines to copy. This may be less than the full height
320 * of the image. This is always >0.
322 * Points to the first byte containing data to be copied. If the source
323 * surface starts are coordinates (x,y) then this is:
324 * image_ptr+x*bytes_pre_pixel+y*bytes_per_line
325 * (with further adjustments for top-down/bottom-up images)
327 * This is the number of bytes per line. It may be >0 or <0 depending on
328 * whether this is a top-down or bottom-up image.
330 * Same as srcbits but for the destination
332 * Same as srclinebytes but for the destination.
335 * - The supported Dib formats are: pal1, pal4, pal8, rgb555, bgr555,
336 * rgb565, bgr565, rgb888 and any 32bit (0888) format.
337 * The supported XImage (Bmp) formats are: pal1, pal4, pal8,
338 * rgb555, bgr555, rgb565, bgr565, rgb888, bgr888, rgb0888, bgr0888.
339 * - Rgb formats are those for which the masks are such that:
340 * red_mask > green_mask > blue_mask
341 * - Bgr formats are those for which the masks sort in the other direction.
342 * - Many conversion functions handle both rgb->bgr and bgr->rgb conversions
343 * so the comments use h, g, l to mean respectively the source color in the
344 * high bits, the green, and the source color in the low bits.
346 static void X11DRV_DIB_Convert_any_asis(int width
, int height
,
348 const void* srcbits
, int srclinebytes
,
349 void* dstbits
, int dstlinebytes
)
353 width
*=bytes_per_pixel
;
354 for (y
=0; y
<height
; y
++) {
355 memcpy(dstbits
, srcbits
, width
);
356 srcbits
= (char*)srcbits
+ srclinebytes
;
357 dstbits
= (char*)dstbits
+ dstlinebytes
;
365 static void X11DRV_DIB_Convert_555_reverse(int width
, int height
,
366 const void* srcbits
, int srclinebytes
,
367 void* dstbits
, int dstlinebytes
)
369 const DWORD
* srcpixel
;
373 for (y
=0; y
<height
; y
++) {
376 for (x
=0; x
<width
/2; x
++) {
377 /* Do 2 pixels at a time */
380 *dstpixel
++=((srcval
<< 10) & 0x7c007c00) | /* h */
381 ( srcval
& 0x03e003e0) | /* g */
382 ((srcval
>> 10) & 0x001f001f); /* l */
385 /* And the the odd pixel */
387 srcval
=*((WORD
*)srcpixel
);
388 *((WORD
*)dstpixel
)=((srcval
<< 10) & 0x7c00) | /* h */
389 ( srcval
& 0x03e0) | /* g */
390 ((srcval
>> 10) & 0x001f); /* l */
392 srcbits
= (char*)srcbits
+ srclinebytes
;
393 dstbits
= (char*)dstbits
+ dstlinebytes
;
397 static void X11DRV_DIB_Convert_555_to_565_asis(int width
, int height
,
398 const void* srcbits
, int srclinebytes
,
399 void* dstbits
, int dstlinebytes
)
401 const DWORD
* srcpixel
;
405 for (y
=0; y
<height
; y
++) {
408 for (x
=0; x
<width
/2; x
++) {
409 /* Do 2 pixels at a time */
412 *dstpixel
++=((srcval
<< 1) & 0xffc0ffc0) | /* h, g */
413 ((srcval
>> 4) & 0x00200020) | /* g - 1 bit */
414 ( srcval
& 0x001f001f); /* l */
417 /* And the the odd pixel */
419 srcval
=*((WORD
*)srcpixel
);
420 *((WORD
*)dstpixel
)=((srcval
<< 1) & 0xffc0) | /* h, g */
421 ((srcval
>> 4) & 0x0020) | /* g - 1 bit */
422 (srcval
& 0x001f); /* l */
424 srcbits
= (char*)srcbits
+ srclinebytes
;
425 dstbits
= (char*)dstbits
+ dstlinebytes
;
429 static void X11DRV_DIB_Convert_555_to_565_reverse(int width
, int height
,
430 const void* srcbits
, int srclinebytes
,
431 void* dstbits
, int dstlinebytes
)
433 const DWORD
* srcpixel
;
437 for (y
=0; y
<height
; y
++) {
440 for (x
=0; x
<width
/2; x
++) {
441 /* Do 2 pixels at a time */
444 *dstpixel
++=((srcval
>> 10) & 0x001f001f) | /* h */
445 ((srcval
<< 1) & 0x07c007c0) | /* g */
446 ((srcval
>> 4) & 0x00200020) | /* g - 1 bit */
447 ((srcval
<< 11) & 0xf800f800); /* l */
450 /* And the the odd pixel */
452 srcval
=*((WORD
*)srcpixel
);
453 *((WORD
*)dstpixel
)=((srcval
>> 10) & 0x001f) | /* h */
454 ((srcval
<< 1) & 0x07c0) | /* g */
455 ((srcval
>> 4) & 0x0020) | /* g - 1 bit */
456 ((srcval
<< 11) & 0xf800); /* l */
458 srcbits
= (char*)srcbits
+ srclinebytes
;
459 dstbits
= (char*)dstbits
+ dstlinebytes
;
463 static void X11DRV_DIB_Convert_555_to_888_asis(int width
, int height
,
464 const void* srcbits
, int srclinebytes
,
465 void* dstbits
, int dstlinebytes
)
467 const WORD
* srcpixel
;
471 for (y
=0; y
<height
; y
++) {
474 for (x
=0; x
<width
; x
++) {
477 dstpixel
[0]=((srcval
<< 3) & 0xf8) | /* l */
478 ((srcval
>> 2) & 0x07); /* l - 3 bits */
479 dstpixel
[1]=((srcval
>> 2) & 0xf8) | /* g */
480 ((srcval
>> 7) & 0x07); /* g - 3 bits */
481 dstpixel
[2]=((srcval
>> 7) & 0xf8) | /* h */
482 ((srcval
>> 12) & 0x07); /* h - 3 bits */
485 srcbits
= (char*)srcbits
+ srclinebytes
;
486 dstbits
= (char*)dstbits
+ dstlinebytes
;
490 static void X11DRV_DIB_Convert_555_to_888_reverse(int width
, int height
,
491 const void* srcbits
, int srclinebytes
,
492 void* dstbits
, int dstlinebytes
)
494 const WORD
* srcpixel
;
498 for (y
=0; y
<height
; y
++) {
501 for (x
=0; x
<width
; x
++) {
504 dstpixel
[0]=((srcval
>> 7) & 0xf8) | /* h */
505 ((srcval
>> 12) & 0x07); /* h - 3 bits */
506 dstpixel
[1]=((srcval
>> 2) & 0xf8) | /* g */
507 ((srcval
>> 7) & 0x07); /* g - 3 bits */
508 dstpixel
[2]=((srcval
<< 3) & 0xf8) | /* l */
509 ((srcval
>> 2) & 0x07); /* l - 3 bits */
512 srcbits
= (char*)srcbits
+ srclinebytes
;
513 dstbits
= (char*)dstbits
+ dstlinebytes
;
517 static void X11DRV_DIB_Convert_555_to_0888_asis(int width
, int height
,
518 const void* srcbits
, int srclinebytes
,
519 void* dstbits
, int dstlinebytes
)
521 const WORD
* srcpixel
;
525 for (y
=0; y
<height
; y
++) {
528 for (x
=0; x
<width
; x
++) {
531 *dstpixel
++=((srcval
<< 9) & 0xf80000) | /* h */
532 ((srcval
<< 4) & 0x070000) | /* h - 3 bits */
533 ((srcval
<< 6) & 0x00f800) | /* g */
534 ((srcval
<< 1) & 0x000700) | /* g - 3 bits */
535 ((srcval
<< 3) & 0x0000f8) | /* l */
536 ((srcval
>> 2) & 0x000007); /* l - 3 bits */
538 srcbits
= (char*)srcbits
+ srclinebytes
;
539 dstbits
= (char*)dstbits
+ dstlinebytes
;
543 static void X11DRV_DIB_Convert_555_to_0888_reverse(int width
, int height
,
544 const void* srcbits
, int srclinebytes
,
545 void* dstbits
, int dstlinebytes
)
547 const WORD
* srcpixel
;
551 for (y
=0; y
<height
; y
++) {
554 for (x
=0; x
<width
; x
++) {
557 *dstpixel
++=((srcval
>> 7) & 0x0000f8) | /* h */
558 ((srcval
>> 12) & 0x000007) | /* h - 3 bits */
559 ((srcval
<< 6) & 0x00f800) | /* g */
560 ((srcval
<< 1) & 0x000700) | /* g - 3 bits */
561 ((srcval
<< 19) & 0xf80000) | /* l */
562 ((srcval
<< 14) & 0x070000); /* l - 3 bits */
564 srcbits
= (char*)srcbits
+ srclinebytes
;
565 dstbits
= (char*)dstbits
+ dstlinebytes
;
569 static void X11DRV_DIB_Convert_5x5_to_any0888(int width
, int height
,
570 const void* srcbits
, int srclinebytes
,
571 WORD rsrc
, WORD gsrc
, WORD bsrc
,
572 void* dstbits
, int dstlinebytes
,
573 DWORD rdst
, DWORD gdst
, DWORD bdst
)
575 int rRightShift1
,gRightShift1
,bRightShift1
;
576 int rRightShift2
,gRightShift2
,bRightShift2
;
578 int rLeftShift
,gLeftShift
,bLeftShift
;
579 const WORD
* srcpixel
;
583 /* Note, the source pixel value is shifted left by 16 bits so that
584 * we know we will always have to shift right to extract the components.
586 rRightShift1
=16+X11DRV_DIB_MaskToShift(rsrc
)-3;
587 gRightShift1
=16+X11DRV_DIB_MaskToShift(gsrc
)-3;
588 bRightShift1
=16+X11DRV_DIB_MaskToShift(bsrc
)-3;
589 rRightShift2
=rRightShift1
+5;
590 gRightShift2
=gRightShift1
+5;
591 bRightShift2
=bRightShift1
+5;
593 /* Green has 5 bits, like the others */
597 /* Green has 6 bits, not 5. Compensate. */
604 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
605 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
606 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
608 for (y
=0; y
<height
; y
++) {
611 for (x
=0; x
<width
; x
++) {
614 srcval
=*srcpixel
++ << 16;
615 red
= ((srcval
>> rRightShift1
) & 0xf8) |
616 ((srcval
>> rRightShift2
) & 0x07);
617 green
=((srcval
>> gRightShift1
) & gMask1
) |
618 ((srcval
>> gRightShift2
) & gMask2
);
619 blue
= ((srcval
>> bRightShift1
) & 0xf8) |
620 ((srcval
>> bRightShift2
) & 0x07);
621 *dstpixel
++=(red
<< rLeftShift
) |
622 (green
<< gLeftShift
) |
623 (blue
<< bLeftShift
);
625 srcbits
= (char*)srcbits
+ srclinebytes
;
626 dstbits
= (char*)dstbits
+ dstlinebytes
;
631 * 16 bits conversions
634 static void X11DRV_DIB_Convert_565_reverse(int width
, int height
,
635 const void* srcbits
, int srclinebytes
,
636 void* dstbits
, int dstlinebytes
)
638 const DWORD
* srcpixel
;
642 for (y
=0; y
<height
; y
++) {
645 for (x
=0; x
<width
/2; x
++) {
646 /* Do 2 pixels at a time */
649 *dstpixel
++=((srcval
<< 11) & 0xf800f800) | /* h */
650 ( srcval
& 0x07e007e0) | /* g */
651 ((srcval
>> 11) & 0x001f001f); /* l */
654 /* And the the odd pixel */
656 srcval
=*((WORD
*)srcpixel
);
657 *((WORD
*)dstpixel
)=((srcval
<< 11) & 0xf800) | /* h */
658 ( srcval
& 0x07e0) | /* g */
659 ((srcval
>> 11) & 0x001f); /* l */
661 srcbits
= (char*)srcbits
+ srclinebytes
;
662 dstbits
= (char*)dstbits
+ dstlinebytes
;
666 static void X11DRV_DIB_Convert_565_to_555_asis(int width
, int height
,
667 const void* srcbits
, int srclinebytes
,
668 void* dstbits
, int dstlinebytes
)
670 const DWORD
* srcpixel
;
674 for (y
=0; y
<height
; y
++) {
677 for (x
=0; x
<width
/2; x
++) {
678 /* Do 2 pixels at a time */
681 *dstpixel
++=((srcval
>> 1) & 0x7fe07fe0) | /* h, g */
682 ( srcval
& 0x001f001f); /* l */
685 /* And the the odd pixel */
687 srcval
=*((WORD
*)srcpixel
);
688 *((WORD
*)dstpixel
)=((srcval
>> 1) & 0x7fe0) | /* h, g */
689 ( srcval
& 0x001f); /* l */
691 srcbits
= (char*)srcbits
+ srclinebytes
;
692 dstbits
= (char*)dstbits
+ dstlinebytes
;
696 static void X11DRV_DIB_Convert_565_to_555_reverse(int width
, int height
,
697 const void* srcbits
, int srclinebytes
,
698 void* dstbits
, int dstlinebytes
)
700 const DWORD
* srcpixel
;
704 for (y
=0; y
<height
; y
++) {
707 for (x
=0; x
<width
/2; x
++) {
708 /* Do 2 pixels at a time */
711 *dstpixel
++=((srcval
>> 11) & 0x001f001f) | /* h */
712 ((srcval
>> 1) & 0x03e003e0) | /* g */
713 ((srcval
<< 10) & 0x7c007c00); /* l */
716 /* And the the odd pixel */
718 srcval
=*((WORD
*)srcpixel
);
719 *((WORD
*)dstpixel
)=((srcval
>> 11) & 0x001f) | /* h */
720 ((srcval
>> 1) & 0x03e0) | /* g */
721 ((srcval
<< 10) & 0x7c00); /* l */
723 srcbits
= (char*)srcbits
+ srclinebytes
;
724 dstbits
= (char*)dstbits
+ dstlinebytes
;
728 static void X11DRV_DIB_Convert_565_to_888_asis(int width
, int height
,
729 const void* srcbits
, int srclinebytes
,
730 void* dstbits
, int dstlinebytes
)
732 const WORD
* srcpixel
;
736 for (y
=0; y
<height
; y
++) {
739 for (x
=0; x
<width
; x
++) {
742 dstpixel
[0]=((srcval
<< 3) & 0xf8) | /* l */
743 ((srcval
>> 2) & 0x07); /* l - 3 bits */
744 dstpixel
[1]=((srcval
>> 3) & 0xfc) | /* g */
745 ((srcval
>> 9) & 0x03); /* g - 2 bits */
746 dstpixel
[2]=((srcval
>> 8) & 0xf8) | /* h */
747 ((srcval
>> 13) & 0x07); /* h - 3 bits */
750 srcbits
= (char*)srcbits
+ srclinebytes
;
751 dstbits
= (char*)dstbits
+ dstlinebytes
;
755 static void X11DRV_DIB_Convert_565_to_888_reverse(int width
, int height
,
756 const void* srcbits
, int srclinebytes
,
757 void* dstbits
, int dstlinebytes
)
759 const WORD
* srcpixel
;
763 for (y
=0; y
<height
; y
++) {
766 for (x
=0; x
<width
; x
++) {
769 dstpixel
[0]=((srcval
>> 8) & 0xf8) | /* h */
770 ((srcval
>> 13) & 0x07); /* h - 3 bits */
771 dstpixel
[1]=((srcval
>> 3) & 0xfc) | /* g */
772 ((srcval
>> 9) & 0x03); /* g - 2 bits */
773 dstpixel
[2]=((srcval
<< 3) & 0xf8) | /* l */
774 ((srcval
>> 2) & 0x07); /* l - 3 bits */
777 srcbits
= (char*)srcbits
+ srclinebytes
;
778 dstbits
= (char*)dstbits
+ dstlinebytes
;
782 static void X11DRV_DIB_Convert_565_to_0888_asis(int width
, int height
,
783 const void* srcbits
, int srclinebytes
,
784 void* dstbits
, int dstlinebytes
)
786 const WORD
* srcpixel
;
790 for (y
=0; y
<height
; y
++) {
793 for (x
=0; x
<width
; x
++) {
796 *dstpixel
++=((srcval
<< 8) & 0xf80000) | /* h */
797 ((srcval
<< 3) & 0x070000) | /* h - 3 bits */
798 ((srcval
<< 5) & 0x00fc00) | /* g */
799 ((srcval
>> 1) & 0x000300) | /* g - 2 bits */
800 ((srcval
<< 3) & 0x0000f8) | /* l */
801 ((srcval
>> 2) & 0x000007); /* l - 3 bits */
803 srcbits
= (char*)srcbits
+ srclinebytes
;
804 dstbits
= (char*)dstbits
+ dstlinebytes
;
808 static void X11DRV_DIB_Convert_565_to_0888_reverse(int width
, int height
,
809 const void* srcbits
, int srclinebytes
,
810 void* dstbits
, int dstlinebytes
)
812 const WORD
* srcpixel
;
816 for (y
=0; y
<height
; y
++) {
819 for (x
=0; x
<width
; x
++) {
822 *dstpixel
++=((srcval
>> 8) & 0x0000f8) | /* h */
823 ((srcval
>> 13) & 0x000007) | /* h - 3 bits */
824 ((srcval
<< 5) & 0x00fc00) | /* g */
825 ((srcval
>> 1) & 0x000300) | /* g - 2 bits */
826 ((srcval
<< 19) & 0xf80000) | /* l */
827 ((srcval
<< 14) & 0x070000); /* l - 3 bits */
829 srcbits
= (char*)srcbits
+ srclinebytes
;
830 dstbits
= (char*)dstbits
+ dstlinebytes
;
838 static void X11DRV_DIB_Convert_888_reverse(int width
, int height
,
839 const void* srcbits
, int srclinebytes
,
840 void* dstbits
, int dstlinebytes
)
842 const BYTE
* srcpixel
;
846 for (y
=0; y
<height
; y
++) {
849 for (x
=0; x
<width
; x
++) {
850 dstpixel
[0]=srcpixel
[2];
851 dstpixel
[1]=srcpixel
[1];
852 dstpixel
[2]=srcpixel
[0];
856 srcbits
= (char*)srcbits
+ srclinebytes
;
857 dstbits
= (char*)dstbits
+ dstlinebytes
;
861 static void X11DRV_DIB_Convert_888_to_555_asis(int width
, int height
,
862 const void* srcbits
, int srclinebytes
,
863 void* dstbits
, int dstlinebytes
)
865 const DWORD
* srcpixel
;
873 for (y
=0; y
<height
; y
++) {
876 for (x
=0; x
<width
; x
++) {
877 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
878 DWORD srcval1
,srcval2
;
880 dstpixel
[0]=((srcval1
>> 3) & 0x001f) | /* l1 */
881 ((srcval1
>> 6) & 0x03e0) | /* g1 */
882 ((srcval1
>> 9) & 0x7c00); /* h1 */
884 dstpixel
[1]=((srcval1
>> 27) & 0x001f) | /* l2 */
885 ((srcval2
<< 2) & 0x03e0) | /* g2 */
886 ((srcval2
>> 1) & 0x7c00); /* h2 */
888 dstpixel
[2]=((srcval2
>> 19) & 0x001f) | /* l3 */
889 ((srcval2
>> 22) & 0x03e0) | /* g3 */
890 ((srcval1
<< 7) & 0x7c00); /* h3 */
891 dstpixel
[3]=((srcval1
>> 11) & 0x001f) | /* l4 */
892 ((srcval1
>> 14) & 0x03e0) | /* g4 */
893 ((srcval1
>> 17) & 0x7c00); /* h4 */
897 /* And now up to 3 odd pixels */
898 srcbyte
=(LPBYTE
)srcpixel
;
899 for (x
=0; x
<oddwidth
; x
++) {
901 dstval
=((srcbyte
[0] >> 3) & 0x001f); /* l */
902 dstval
|=((srcbyte
[1] << 2) & 0x03e0); /* g */
903 dstval
|=((srcbyte
[2] << 7) & 0x7c00); /* h */
907 srcbits
= (char*)srcbits
+ srclinebytes
;
908 dstbits
= (char*)dstbits
+ dstlinebytes
;
912 static void X11DRV_DIB_Convert_888_to_555_reverse(int width
, int height
,
913 const void* srcbits
, int srclinebytes
,
914 void* dstbits
, int dstlinebytes
)
916 const DWORD
* srcpixel
;
924 for (y
=0; y
<height
; y
++) {
927 for (x
=0; x
<width
; x
++) {
928 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
929 DWORD srcval1
,srcval2
;
931 dstpixel
[0]=((srcval1
<< 7) & 0x7c00) | /* l1 */
932 ((srcval1
>> 6) & 0x03e0) | /* g1 */
933 ((srcval1
>> 19) & 0x001f); /* h1 */
935 dstpixel
[1]=((srcval1
>> 17) & 0x7c00) | /* l2 */
936 ((srcval2
<< 2) & 0x03e0) | /* g2 */
937 ((srcval2
>> 11) & 0x001f); /* h2 */
939 dstpixel
[2]=((srcval2
>> 9) & 0x7c00) | /* l3 */
940 ((srcval2
>> 22) & 0x03e0) | /* g3 */
941 ((srcval1
>> 3) & 0x001f); /* h3 */
942 dstpixel
[3]=((srcval1
>> 1) & 0x7c00) | /* l4 */
943 ((srcval1
>> 14) & 0x03e0) | /* g4 */
944 ((srcval1
>> 27) & 0x001f); /* h4 */
948 /* And now up to 3 odd pixels */
949 srcbyte
=(LPBYTE
)srcpixel
;
950 for (x
=0; x
<oddwidth
; x
++) {
952 dstval
=((srcbyte
[0] << 7) & 0x7c00); /* l */
953 dstval
|=((srcbyte
[1] << 2) & 0x03e0); /* g */
954 dstval
|=((srcbyte
[2] >> 3) & 0x001f); /* h */
958 srcbits
= (char*)srcbits
+ srclinebytes
;
959 dstbits
= (char*)dstbits
+ dstlinebytes
;
963 static void X11DRV_DIB_Convert_888_to_565_asis(int width
, int height
,
964 const void* srcbits
, int srclinebytes
,
965 void* dstbits
, int dstlinebytes
)
967 const DWORD
* srcpixel
;
975 for (y
=0; y
<height
; y
++) {
978 for (x
=0; x
<width
; x
++) {
979 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
980 DWORD srcval1
,srcval2
;
982 dstpixel
[0]=((srcval1
>> 3) & 0x001f) | /* l1 */
983 ((srcval1
>> 5) & 0x07e0) | /* g1 */
984 ((srcval1
>> 8) & 0xf800); /* h1 */
986 dstpixel
[1]=((srcval1
>> 27) & 0x001f) | /* l2 */
987 ((srcval2
<< 3) & 0x07e0) | /* g2 */
988 ( srcval2
& 0xf800); /* h2 */
990 dstpixel
[2]=((srcval2
>> 19) & 0x001f) | /* l3 */
991 ((srcval2
>> 21) & 0x07e0) | /* g3 */
992 ((srcval1
<< 8) & 0xf800); /* h3 */
993 dstpixel
[3]=((srcval1
>> 11) & 0x001f) | /* l4 */
994 ((srcval1
>> 13) & 0x07e0) | /* g4 */
995 ((srcval1
>> 16) & 0xf800); /* h4 */
999 /* And now up to 3 odd pixels */
1000 srcbyte
=(LPBYTE
)srcpixel
;
1001 for (x
=0; x
<oddwidth
; x
++) {
1003 dstval
=((srcbyte
[0] >> 3) & 0x001f); /* l */
1004 dstval
|=((srcbyte
[1] << 3) & 0x07e0); /* g */
1005 dstval
|=((srcbyte
[2] << 8) & 0xf800); /* h */
1009 srcbits
= (char*)srcbits
+ srclinebytes
;
1010 dstbits
= (char*)dstbits
+ dstlinebytes
;
1014 static void X11DRV_DIB_Convert_888_to_565_reverse(int width
, int height
,
1015 const void* srcbits
, int srclinebytes
,
1016 void* dstbits
, int dstlinebytes
)
1018 const DWORD
* srcpixel
;
1019 const BYTE
* srcbyte
;
1026 for (y
=0; y
<height
; y
++) {
1029 for (x
=0; x
<width
; x
++) {
1030 /* Do 4 pixels at a time: 3 dwords in and 4 words out */
1031 DWORD srcval1
,srcval2
;
1032 srcval1
=srcpixel
[0];
1033 dstpixel
[0]=((srcval1
<< 8) & 0xf800) | /* l1 */
1034 ((srcval1
>> 5) & 0x07e0) | /* g1 */
1035 ((srcval1
>> 19) & 0x001f); /* h1 */
1036 srcval2
=srcpixel
[1];
1037 dstpixel
[1]=((srcval1
>> 16) & 0xf800) | /* l2 */
1038 ((srcval2
<< 3) & 0x07e0) | /* g2 */
1039 ((srcval2
>> 11) & 0x001f); /* h2 */
1040 srcval1
=srcpixel
[2];
1041 dstpixel
[2]=((srcval2
>> 8) & 0xf800) | /* l3 */
1042 ((srcval2
>> 21) & 0x07e0) | /* g3 */
1043 ((srcval1
>> 3) & 0x001f); /* h3 */
1044 dstpixel
[3]=(srcval1
& 0xf800) | /* l4 */
1045 ((srcval1
>> 13) & 0x07e0) | /* g4 */
1046 ((srcval1
>> 27) & 0x001f); /* h4 */
1050 /* And now up to 3 odd pixels */
1051 srcbyte
=(LPBYTE
)srcpixel
;
1052 for (x
=0; x
<oddwidth
; x
++) {
1054 dstval
=((srcbyte
[0] << 8) & 0xf800); /* l */
1055 dstval
|=((srcbyte
[1] << 3) & 0x07e0); /* g */
1056 dstval
|=((srcbyte
[2] >> 3) & 0x001f); /* h */
1060 srcbits
= (char*)srcbits
+ srclinebytes
;
1061 dstbits
= (char*)dstbits
+ dstlinebytes
;
1065 static void X11DRV_DIB_Convert_888_to_0888_asis(int width
, int height
,
1066 const void* srcbits
, int srclinebytes
,
1067 void* dstbits
, int dstlinebytes
)
1069 const DWORD
* srcpixel
;
1076 for (y
=0; y
<height
; y
++) {
1079 for (x
=0; x
<width
; x
++) {
1080 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1081 DWORD srcval1
,srcval2
;
1082 srcval1
=srcpixel
[0];
1083 dstpixel
[0]=( srcval1
& 0x00ffffff); /* h1, g1, l1 */
1084 srcval2
=srcpixel
[1];
1085 dstpixel
[1]=( srcval1
>> 24) | /* l2 */
1086 ((srcval2
<< 8) & 0x00ffff00); /* h2, g2 */
1087 srcval1
=srcpixel
[2];
1088 dstpixel
[2]=( srcval2
>> 16) | /* g3, l3 */
1089 ((srcval1
<< 16) & 0x00ff0000); /* h3 */
1090 dstpixel
[3]=( srcval1
>> 8); /* h4, g4, l4 */
1094 /* And now up to 3 odd pixels */
1095 for (x
=0; x
<oddwidth
; x
++) {
1098 srcpixel
=(LPDWORD
)(((char*)srcpixel
)+3);
1099 *dstpixel
++=( srcval
& 0x00ffffff); /* h, g, l */
1101 srcbits
= (char*)srcbits
+ srclinebytes
;
1102 dstbits
= (char*)dstbits
+ dstlinebytes
;
1106 static void X11DRV_DIB_Convert_888_to_0888_reverse(int width
, int height
,
1107 const void* srcbits
, int srclinebytes
,
1108 void* dstbits
, int dstlinebytes
)
1110 const DWORD
* srcpixel
;
1117 for (y
=0; y
<height
; y
++) {
1120 for (x
=0; x
<width
; x
++) {
1121 /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
1122 DWORD srcval1
,srcval2
;
1124 srcval1
=srcpixel
[0];
1125 dstpixel
[0]=((srcval1
>> 16) & 0x0000ff) | /* h1 */
1126 ( srcval1
& 0x00ff00) | /* g1 */
1127 ((srcval1
<< 16) & 0xff0000); /* l1 */
1128 srcval2
=srcpixel
[1];
1129 dstpixel
[1]=((srcval1
>> 8) & 0xff0000) | /* l2 */
1130 ((srcval2
<< 8) & 0x00ff00) | /* g2 */
1131 ((srcval2
>> 8) & 0x0000ff); /* h2 */
1132 srcval1
=srcpixel
[2];
1133 dstpixel
[2]=( srcval2
& 0xff0000) | /* l3 */
1134 ((srcval2
>> 16) & 0x00ff00) | /* g3 */
1135 ( srcval1
& 0x0000ff); /* h3 */
1136 dstpixel
[3]=((srcval1
>> 24) & 0x0000ff) | /* h4 */
1137 ((srcval1
>> 8) & 0x00ff00) | /* g4 */
1138 ((srcval1
<< 8) & 0xff0000); /* l4 */
1142 /* And now up to 3 odd pixels */
1143 for (x
=0; x
<oddwidth
; x
++) {
1146 srcpixel
=(LPDWORD
)(((char*)srcpixel
)+3);
1147 *dstpixel
++=((srcval
>> 16) & 0x0000ff) | /* h */
1148 ( srcval
& 0x00ff00) | /* g */
1149 ((srcval
<< 16) & 0xff0000); /* l */
1151 srcbits
= (char*)srcbits
+ srclinebytes
;
1152 dstbits
= (char*)dstbits
+ dstlinebytes
;
1156 static void X11DRV_DIB_Convert_rgb888_to_any0888(int width
, int height
,
1157 const void* srcbits
, int srclinebytes
,
1158 void* dstbits
, int dstlinebytes
,
1159 DWORD rdst
, DWORD gdst
, DWORD bdst
)
1161 int rLeftShift
,gLeftShift
,bLeftShift
;
1162 const BYTE
* srcpixel
;
1166 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
1167 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
1168 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
1169 for (y
=0; y
<height
; y
++) {
1172 for (x
=0; x
<width
; x
++) {
1173 *dstpixel
++=(srcpixel
[0] << bLeftShift
) | /* b */
1174 (srcpixel
[1] << gLeftShift
) | /* g */
1175 (srcpixel
[2] << rLeftShift
); /* r */
1178 srcbits
= (char*)srcbits
+ srclinebytes
;
1179 dstbits
= (char*)dstbits
+ dstlinebytes
;
1183 static void X11DRV_DIB_Convert_bgr888_to_any0888(int width
, int height
,
1184 const void* srcbits
, int srclinebytes
,
1185 void* dstbits
, int dstlinebytes
,
1186 DWORD rdst
, DWORD gdst
, DWORD bdst
)
1188 int rLeftShift
,gLeftShift
,bLeftShift
;
1189 const BYTE
* srcpixel
;
1193 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
1194 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
1195 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
1196 for (y
=0; y
<height
; y
++) {
1199 for (x
=0; x
<width
; x
++) {
1200 *dstpixel
++=(srcpixel
[0] << rLeftShift
) | /* r */
1201 (srcpixel
[1] << gLeftShift
) | /* g */
1202 (srcpixel
[2] << bLeftShift
); /* b */
1205 srcbits
= (char*)srcbits
+ srclinebytes
;
1206 dstbits
= (char*)dstbits
+ dstlinebytes
;
1211 * 32 bit conversions
1214 static void X11DRV_DIB_Convert_0888_reverse(int width
, int height
,
1215 const void* srcbits
, int srclinebytes
,
1216 void* dstbits
, int dstlinebytes
)
1218 const DWORD
* srcpixel
;
1222 for (y
=0; y
<height
; y
++) {
1225 for (x
=0; x
<width
; x
++) {
1228 *dstpixel
++=((srcval
<< 16) & 0x00ff0000) | /* h */
1229 ( srcval
& 0x0000ff00) | /* g */
1230 ((srcval
>> 16) & 0x000000ff); /* l */
1232 srcbits
= (char*)srcbits
+ srclinebytes
;
1233 dstbits
= (char*)dstbits
+ dstlinebytes
;
1237 static void X11DRV_DIB_Convert_0888_any(int width
, int height
,
1238 const void* srcbits
, int srclinebytes
,
1239 DWORD rsrc
, DWORD gsrc
, DWORD bsrc
,
1240 void* dstbits
, int dstlinebytes
,
1241 DWORD rdst
, DWORD gdst
, DWORD bdst
)
1243 int rRightShift
,gRightShift
,bRightShift
;
1244 int rLeftShift
,gLeftShift
,bLeftShift
;
1245 const DWORD
* srcpixel
;
1249 rRightShift
=X11DRV_DIB_MaskToShift(rsrc
);
1250 gRightShift
=X11DRV_DIB_MaskToShift(gsrc
);
1251 bRightShift
=X11DRV_DIB_MaskToShift(bsrc
);
1252 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
1253 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
1254 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
1255 for (y
=0; y
<height
; y
++) {
1258 for (x
=0; x
<width
; x
++) {
1261 *dstpixel
++=(((srcval
>> rRightShift
) & 0xff) << rLeftShift
) |
1262 (((srcval
>> gRightShift
) & 0xff) << gLeftShift
) |
1263 (((srcval
>> bRightShift
) & 0xff) << bLeftShift
);
1265 srcbits
= (char*)srcbits
+ srclinebytes
;
1266 dstbits
= (char*)dstbits
+ dstlinebytes
;
1270 static void X11DRV_DIB_Convert_0888_to_555_asis(int width
, int height
,
1271 const void* srcbits
, int srclinebytes
,
1272 void* dstbits
, int dstlinebytes
)
1274 const DWORD
* srcpixel
;
1278 for (y
=0; y
<height
; y
++) {
1281 for (x
=0; x
<width
; x
++) {
1284 *dstpixel
++=((srcval
>> 9) & 0x7c00) | /* h */
1285 ((srcval
>> 6) & 0x03e0) | /* g */
1286 ((srcval
>> 3) & 0x001f); /* l */
1288 srcbits
= (char*)srcbits
+ srclinebytes
;
1289 dstbits
= (char*)dstbits
+ dstlinebytes
;
1293 static void X11DRV_DIB_Convert_0888_to_555_reverse(int width
, int height
,
1294 const void* srcbits
, int srclinebytes
,
1295 void* dstbits
, int dstlinebytes
)
1297 const DWORD
* srcpixel
;
1301 for (y
=0; y
<height
; y
++) {
1304 for (x
=0; x
<width
; x
++) {
1307 *dstpixel
++=((srcval
>> 19) & 0x001f) | /* h */
1308 ((srcval
>> 6) & 0x03e0) | /* g */
1309 ((srcval
<< 7) & 0x7c00); /* l */
1311 srcbits
= (char*)srcbits
+ srclinebytes
;
1312 dstbits
= (char*)dstbits
+ dstlinebytes
;
1316 static void X11DRV_DIB_Convert_0888_to_565_asis(int width
, int height
,
1317 const void* srcbits
, int srclinebytes
,
1318 void* dstbits
, int dstlinebytes
)
1320 const DWORD
* srcpixel
;
1324 for (y
=0; y
<height
; y
++) {
1327 for (x
=0; x
<width
; x
++) {
1330 *dstpixel
++=((srcval
>> 8) & 0xf800) | /* h */
1331 ((srcval
>> 5) & 0x07e0) | /* g */
1332 ((srcval
>> 3) & 0x001f); /* l */
1334 srcbits
= (char*)srcbits
+ srclinebytes
;
1335 dstbits
= (char*)dstbits
+ dstlinebytes
;
1339 static void X11DRV_DIB_Convert_0888_to_565_reverse(int width
, int height
,
1340 const void* srcbits
, int srclinebytes
,
1341 void* dstbits
, int dstlinebytes
)
1343 const DWORD
* srcpixel
;
1347 for (y
=0; y
<height
; y
++) {
1350 for (x
=0; x
<width
; x
++) {
1353 *dstpixel
++=((srcval
>> 19) & 0x001f) | /* h */
1354 ((srcval
>> 5) & 0x07e0) | /* g */
1355 ((srcval
<< 8) & 0xf800); /* l */
1357 srcbits
= (char*)srcbits
+ srclinebytes
;
1358 dstbits
= (char*)dstbits
+ dstlinebytes
;
1362 static void X11DRV_DIB_Convert_any0888_to_5x5(int width
, int height
,
1363 const void* srcbits
, int srclinebytes
,
1364 DWORD rsrc
, DWORD gsrc
, DWORD bsrc
,
1365 void* dstbits
, int dstlinebytes
,
1366 WORD rdst
, WORD gdst
, WORD bdst
)
1368 int rRightShift
,gRightShift
,bRightShift
;
1369 int rLeftShift
,gLeftShift
,bLeftShift
;
1370 const DWORD
* srcpixel
;
1374 /* Here is how we proceed. Assume we have rsrc=0x0000ff00 and our pixel
1375 * contains 0x11223344.
1376 * - first we shift 0x11223344 right by rRightShift to bring the most
1377 * significant bits of the red components in the bottom 5 (or 6) bits
1379 * - then we remove non red bits by anding with the modified rdst (0x1f)
1381 * - finally shift these bits left by rLeftShift so that they end up in
1385 rRightShift
=X11DRV_DIB_MaskToShift(rsrc
)+3;
1386 gRightShift
=X11DRV_DIB_MaskToShift(gsrc
);
1387 gRightShift
+=(gdst
==0x07e0?2:3);
1388 bRightShift
=X11DRV_DIB_MaskToShift(bsrc
)+3;
1390 rLeftShift
=X11DRV_DIB_MaskToShift(rdst
);
1391 rdst
=rdst
>> rLeftShift
;
1392 gLeftShift
=X11DRV_DIB_MaskToShift(gdst
);
1393 gdst
=gdst
>> gLeftShift
;
1394 bLeftShift
=X11DRV_DIB_MaskToShift(bdst
);
1395 bdst
=bdst
>> bLeftShift
;
1397 for (y
=0; y
<height
; y
++) {
1400 for (x
=0; x
<width
; x
++) {
1403 *dstpixel
++=(((srcval
>> rRightShift
) & rdst
) << rLeftShift
) |
1404 (((srcval
>> gRightShift
) & gdst
) << gLeftShift
) |
1405 (((srcval
>> bRightShift
) & bdst
) << bLeftShift
);
1407 srcbits
= (char*)srcbits
+ srclinebytes
;
1408 dstbits
= (char*)dstbits
+ dstlinebytes
;
1412 static void X11DRV_DIB_Convert_0888_to_888_asis(int width
, int height
,
1413 const void* srcbits
, int srclinebytes
,
1414 void* dstbits
, int dstlinebytes
)
1416 const DWORD
* srcpixel
;
1424 for (y
=0; y
<height
; y
++) {
1427 for (x
=0; x
<width
; x
++) {
1428 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1430 srcval
=((*srcpixel
++) & 0x00ffffff); /* h1, g1, l1*/
1431 *dstpixel
++=srcval
| ((*srcpixel
) << 24); /* h2 */
1432 srcval
=((*srcpixel
++ >> 8 ) & 0x0000ffff); /* g2, l2 */
1433 *dstpixel
++=srcval
| ((*srcpixel
) << 16); /* h3, g3 */
1434 srcval
=((*srcpixel
++ >> 16) & 0x000000ff); /* l3 */
1435 *dstpixel
++=srcval
| ((*srcpixel
++) << 8); /* h4, g4, l4 */
1437 /* And now up to 3 odd pixels */
1438 dstbyte
=(BYTE
*)dstpixel
;
1439 for (x
=0; x
<oddwidth
; x
++) {
1442 *((WORD
*)dstbyte
)++=srcval
; /* h, g */
1443 *dstbyte
++=srcval
>> 16; /* l */
1445 srcbits
= (char*)srcbits
+ srclinebytes
;
1446 dstbits
= (char*)dstbits
+ dstlinebytes
;
1450 static void X11DRV_DIB_Convert_0888_to_888_reverse(int width
, int height
,
1451 const void* srcbits
, int srclinebytes
,
1452 void* dstbits
, int dstlinebytes
)
1454 const DWORD
* srcpixel
;
1462 for (y
=0; y
<height
; y
++) {
1465 for (x
=0; x
<width
; x
++) {
1466 /* Do 4 pixels at a time: 4 dwords in and 3 dwords out */
1467 DWORD srcval1
,srcval2
;
1468 srcval1
=*srcpixel
++;
1469 srcval2
= ((srcval1
>> 16) & 0x000000ff) | /* h1 */
1470 ( srcval1
& 0x0000ff00) | /* g1 */
1471 ((srcval1
<< 16) & 0x00ff0000); /* l1 */
1472 srcval1
=*srcpixel
++;
1473 *dstpixel
++=srcval2
|
1474 ((srcval1
<< 8) & 0xff000000); /* h2 */
1475 srcval2
= ((srcval1
>> 8) & 0x000000ff) | /* g2 */
1476 ((srcval1
<< 8) & 0x0000ff00); /* l2 */
1477 srcval1
=*srcpixel
++;
1478 *dstpixel
++=srcval2
|
1479 ( srcval1
& 0x00ff0000) | /* h3 */
1480 ((srcval1
<< 16) & 0xff000000); /* g3 */
1481 srcval2
= ( srcval1
& 0x000000ff); /* l3 */
1482 srcval1
=*srcpixel
++;
1483 *dstpixel
++=srcval2
|
1484 ((srcval1
>> 8) & 0x0000ff00) | /* h4 */
1485 ((srcval1
<< 8) & 0x00ff0000) | /* g4 */
1486 ( srcval1
<< 24); /* l4 */
1488 /* And now up to 3 odd pixels */
1489 dstbyte
=(BYTE
*)dstpixel
;
1490 for (x
=0; x
<oddwidth
; x
++) {
1493 *((WORD
*)dstbyte
)++=((srcval
>> 16) & 0x00ff) | /* h */
1494 (srcval
& 0xff00); /* g */
1495 *dstbyte
++=srcval
; /* l */
1497 srcbits
= (char*)srcbits
+ srclinebytes
;
1498 dstbits
= (char*)dstbits
+ dstlinebytes
;
1502 static void X11DRV_DIB_Convert_any0888_to_rgb888(int width
, int height
,
1503 const void* srcbits
, int srclinebytes
,
1504 DWORD rsrc
, DWORD gsrc
, DWORD bsrc
,
1505 void* dstbits
, int dstlinebytes
)
1507 int rRightShift
,gRightShift
,bRightShift
;
1508 const DWORD
* srcpixel
;
1512 rRightShift
=X11DRV_DIB_MaskToShift(rsrc
);
1513 gRightShift
=X11DRV_DIB_MaskToShift(gsrc
);
1514 bRightShift
=X11DRV_DIB_MaskToShift(bsrc
);
1515 for (y
=0; y
<height
; y
++) {
1518 for (x
=0; x
<width
; x
++) {
1521 dstpixel
[0]=(srcval
>> bRightShift
); /* b */
1522 dstpixel
[1]=(srcval
>> gRightShift
); /* g */
1523 dstpixel
[2]=(srcval
>> rRightShift
); /* r */
1526 srcbits
= (char*)srcbits
+ srclinebytes
;
1527 dstbits
= (char*)dstbits
+ dstlinebytes
;
1531 static void X11DRV_DIB_Convert_any0888_to_bgr888(int width
, int height
,
1532 const void* srcbits
, int srclinebytes
,
1533 DWORD rsrc
, DWORD gsrc
, DWORD bsrc
,
1534 void* dstbits
, int dstlinebytes
)
1536 int rRightShift
,gRightShift
,bRightShift
;
1537 const DWORD
* srcpixel
;
1541 rRightShift
=X11DRV_DIB_MaskToShift(rsrc
);
1542 gRightShift
=X11DRV_DIB_MaskToShift(gsrc
);
1543 bRightShift
=X11DRV_DIB_MaskToShift(bsrc
);
1544 for (y
=0; y
<height
; y
++) {
1547 for (x
=0; x
<width
; x
++) {
1550 dstpixel
[0]=(srcval
>> rRightShift
); /* r */
1551 dstpixel
[1]=(srcval
>> gRightShift
); /* g */
1552 dstpixel
[2]=(srcval
>> bRightShift
); /* b */
1555 srcbits
= (char*)srcbits
+ srclinebytes
;
1556 dstbits
= (char*)dstbits
+ dstlinebytes
;
1560 /***********************************************************************
1561 * X11DRV_DIB_SetImageBits_1
1563 * SetDIBits for a 1-bit deep DIB.
1565 static void X11DRV_DIB_SetImageBits_1( int lines
, const BYTE
*srcbits
,
1566 DWORD srcwidth
, DWORD dstwidth
, int left
,
1567 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
1570 const BYTE
* srcbyte
;
1576 srcbits
= srcbits
+ linebytes
* (lines
- 1);
1577 linebytes
= -linebytes
;
1580 if ((extra
= (left
& 7)) != 0) {
1584 srcbits
+= left
>> 3;
1586 /* ==== pal 1 dib -> any bmp format ==== */
1587 for (h
= lines
-1; h
>=0; h
--) {
1589 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
1590 for (i
= dstwidth
/8, x
= left
; i
> 0; i
--) {
1592 XPutPixel( bmpImage
, x
++, h
, colors
[ srcval
>> 7] );
1593 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 6) & 1] );
1594 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 5) & 1] );
1595 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 4) & 1] );
1596 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 3) & 1] );
1597 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 2) & 1] );
1598 XPutPixel( bmpImage
, x
++, h
, colors
[(srcval
>> 1) & 1] );
1599 XPutPixel( bmpImage
, x
++, h
, colors
[ srcval
& 1] );
1602 switch (dstwidth
& 7)
1604 case 7: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1605 case 6: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1606 case 5: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1607 case 4: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1608 case 3: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1609 case 2: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]); srcval
<<=1;
1610 case 1: XPutPixel(bmpImage
, x
++, h
, colors
[srcval
>> 7]);
1612 srcbits
+= linebytes
;
1616 /***********************************************************************
1617 * X11DRV_DIB_GetImageBits_1
1619 * GetDIBits for a 1-bit deep DIB.
1621 static void X11DRV_DIB_GetImageBits_1( int lines
, BYTE
*dstbits
,
1622 DWORD dstwidth
, DWORD srcwidth
,
1623 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
1624 XImage
*bmpImage
, DWORD linebytes
)
1631 dstbits
= dstbits
+ linebytes
* (lines
- 1);
1632 linebytes
= -linebytes
;
1635 switch (bmpImage
->depth
)
1639 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
1640 /* ==== pal 1 or 4 bmp -> pal 1 dib ==== */
1643 for (h
=lines
-1; h
>=0; h
--) {
1647 for (x
=0; x
<dstwidth
; x
++) {
1648 PALETTEENTRY srcval
;
1649 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
1650 dstval
|=(X11DRV_DIB_GetNearestIndex
1654 srcval
.peBlue
) << (7 - (x
& 7)));
1660 if ((dstwidth
&7)!=0) {
1663 dstbits
+= linebytes
;
1671 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
1672 /* ==== pal 8 bmp -> pal 1 dib ==== */
1673 const void* srcbits
;
1674 const BYTE
* srcpixel
;
1677 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1679 for (h
=0; h
<lines
; h
++) {
1684 for (x
=0; x
<dstwidth
; x
++) {
1685 PALETTEENTRY srcval
;
1686 srcval
=srccolors
[(int)*srcpixel
++];
1687 dstval
|=(X11DRV_DIB_GetNearestIndex
1691 srcval
.peBlue
) << (7-(x
&7)) );
1697 if ((dstwidth
&7)!=0) {
1700 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1701 dstbits
+= linebytes
;
1711 const void* srcbits
;
1712 const WORD
* srcpixel
;
1715 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1717 if (bmpImage
->green_mask
==0x03e0) {
1718 if (bmpImage
->red_mask
==0x7c00) {
1719 /* ==== rgb 555 bmp -> pal 1 dib ==== */
1720 for (h
=0; h
<lines
; h
++) {
1725 for (x
=0; x
<dstwidth
; x
++) {
1728 dstval
|=(X11DRV_DIB_GetNearestIndex
1730 ((srcval
>> 7) & 0xf8) | /* r */
1731 ((srcval
>> 12) & 0x07),
1732 ((srcval
>> 2) & 0xf8) | /* g */
1733 ((srcval
>> 7) & 0x07),
1734 ((srcval
<< 3) & 0xf8) | /* b */
1735 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
1741 if ((dstwidth
&7)!=0) {
1744 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1745 dstbits
+= linebytes
;
1747 } else if (bmpImage
->blue_mask
==0x7c00) {
1748 /* ==== bgr 555 bmp -> pal 1 dib ==== */
1749 for (h
=0; h
<lines
; h
++) {
1754 for (x
=0; x
<dstwidth
; x
++) {
1757 dstval
|=(X11DRV_DIB_GetNearestIndex
1759 ((srcval
<< 3) & 0xf8) | /* r */
1760 ((srcval
>> 2) & 0x07),
1761 ((srcval
>> 2) & 0xf8) | /* g */
1762 ((srcval
>> 7) & 0x07),
1763 ((srcval
>> 7) & 0xf8) | /* b */
1764 ((srcval
>> 12) & 0x07) ) << (7-(x
&7)) );
1770 if ((dstwidth
&7)!=0) {
1773 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1774 dstbits
+= linebytes
;
1779 } else if (bmpImage
->green_mask
==0x07e0) {
1780 if (bmpImage
->red_mask
==0xf800) {
1781 /* ==== rgb 565 bmp -> pal 1 dib ==== */
1782 for (h
=0; h
<lines
; h
++) {
1787 for (x
=0; x
<dstwidth
; x
++) {
1790 dstval
|=(X11DRV_DIB_GetNearestIndex
1792 ((srcval
>> 8) & 0xf8) | /* r */
1793 ((srcval
>> 13) & 0x07),
1794 ((srcval
>> 3) & 0xfc) | /* g */
1795 ((srcval
>> 9) & 0x03),
1796 ((srcval
<< 3) & 0xf8) | /* b */
1797 ((srcval
>> 2) & 0x07) ) << (7-(x
&7)) );
1803 if ((dstwidth
&7)!=0) {
1806 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1807 dstbits
+= linebytes
;
1809 } else if (bmpImage
->blue_mask
==0xf800) {
1810 /* ==== bgr 565 bmp -> pal 1 dib ==== */
1811 for (h
=0; h
<lines
; h
++) {
1816 for (x
=0; x
<dstwidth
; x
++) {
1819 dstval
|=(X11DRV_DIB_GetNearestIndex
1821 ((srcval
<< 3) & 0xf8) | /* r */
1822 ((srcval
>> 2) & 0x07),
1823 ((srcval
>> 3) & 0xfc) | /* g */
1824 ((srcval
>> 9) & 0x03),
1825 ((srcval
>> 8) & 0xf8) | /* b */
1826 ((srcval
>> 13) & 0x07) ) << (7-(x
&7)) );
1832 if ((dstwidth
&7)!=0) {
1835 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1836 dstbits
+= linebytes
;
1850 const void* srcbits
;
1851 const BYTE
*srcbyte
;
1853 int bytes_per_pixel
;
1855 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
1856 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
1858 if (bmpImage
->green_mask
!=0x00ff00 ||
1859 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
1861 } else if (bmpImage
->blue_mask
==0xff) {
1862 /* ==== rgb 888 or 0888 bmp -> pal 1 dib ==== */
1863 for (h
=0; h
<lines
; h
++) {
1868 for (x
=0; x
<dstwidth
; x
++) {
1869 dstval
|=(X11DRV_DIB_GetNearestIndex
1873 srcbyte
[0]) << (7-(x
&7)) );
1874 srcbyte
+=bytes_per_pixel
;
1880 if ((dstwidth
&7)!=0) {
1883 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1884 dstbits
+= linebytes
;
1887 /* ==== bgr 888 or 0888 bmp -> pal 1 dib ==== */
1888 for (h
=0; h
<lines
; h
++) {
1893 for (x
=0; x
<dstwidth
; x
++) {
1894 dstval
|=(X11DRV_DIB_GetNearestIndex
1898 srcbyte
[2]) << (7-(x
&7)) );
1899 srcbyte
+=bytes_per_pixel
;
1905 if ((dstwidth
&7)!=0) {
1908 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
1909 dstbits
+= linebytes
;
1919 unsigned long white
= (1 << bmpImage
->bits_per_pixel
) - 1;
1921 /* ==== any bmp format -> pal 1 dib ==== */
1922 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 1 bit DIB\n",
1923 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
1924 bmpImage
->green_mask
, bmpImage
->blue_mask
);
1926 for (h
=lines
-1; h
>=0; h
--) {
1930 for (x
=0; x
<dstwidth
; x
++) {
1931 dstval
|=(XGetPixel( bmpImage
, x
, h
) >= white
) << (7 - (x
&7));
1937 if ((dstwidth
&7)!=0) {
1940 dstbits
+= linebytes
;
1947 /***********************************************************************
1948 * X11DRV_DIB_SetImageBits_4
1950 * SetDIBits for a 4-bit deep DIB.
1952 static void X11DRV_DIB_SetImageBits_4( int lines
, const BYTE
*srcbits
,
1953 DWORD srcwidth
, DWORD dstwidth
, int left
,
1954 int *colors
, XImage
*bmpImage
, DWORD linebytes
)
1957 const BYTE
* srcbyte
;
1962 srcbits
= srcbits
+ linebytes
* (lines
- 1);
1963 linebytes
= -linebytes
;
1970 srcbits
+= left
>> 1;
1972 /* ==== pal 4 dib -> any bmp format ==== */
1973 for (h
= lines
-1; h
>= 0; h
--) {
1975 for (i
= dstwidth
/2, x
= left
; i
> 0; i
--) {
1976 BYTE srcval
=*srcbyte
++;
1977 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
>> 4] );
1978 XPutPixel( bmpImage
, x
++, h
, colors
[srcval
& 0x0f] );
1981 XPutPixel( bmpImage
, x
, h
, colors
[*srcbyte
>> 4] );
1982 srcbits
+= linebytes
;
1988 /***********************************************************************
1989 * X11DRV_DIB_GetImageBits_4
1991 * GetDIBits for a 4-bit deep DIB.
1993 static void X11DRV_DIB_GetImageBits_4( int lines
, BYTE
*dstbits
,
1994 DWORD srcwidth
, DWORD dstwidth
,
1995 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
1996 XImage
*bmpImage
, DWORD linebytes
)
2005 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2006 linebytes
= -linebytes
;
2011 switch (bmpImage
->depth
) {
2014 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2015 /* ==== pal 1 or 4 bmp -> pal 4 dib ==== */
2018 for (h
= lines
-1; h
>= 0; h
--) {
2022 for (x
= 0; x
< dstwidth
; x
++) {
2023 PALETTEENTRY srcval
;
2024 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2025 dstval
|=(X11DRV_DIB_GetNearestIndex
2029 srcval
.peBlue
) << (4-((x
&1)<<2)));
2035 if ((dstwidth
&1)!=0) {
2038 dstbits
+= linebytes
;
2046 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2047 /* ==== pal 8 bmp -> pal 4 dib ==== */
2048 const void* srcbits
;
2049 const BYTE
*srcpixel
;
2052 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2053 for (h
=0; h
<lines
; h
++) {
2058 for (x
=0; x
<dstwidth
; x
++) {
2059 PALETTEENTRY srcval
;
2060 srcval
= srccolors
[(int)*srcpixel
++];
2061 dstval
|=(X11DRV_DIB_GetNearestIndex
2065 srcval
.peBlue
) << (4*(1-(x
&1))) );
2071 if ((dstwidth
&1)!=0) {
2074 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2075 dstbits
+= linebytes
;
2085 const void* srcbits
;
2086 const WORD
* srcpixel
;
2089 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2091 if (bmpImage
->green_mask
==0x03e0) {
2092 if (bmpImage
->red_mask
==0x7c00) {
2093 /* ==== rgb 555 bmp -> pal 4 dib ==== */
2094 for (h
=0; h
<lines
; h
++) {
2099 for (x
=0; x
<dstwidth
; x
++) {
2102 dstval
|=(X11DRV_DIB_GetNearestIndex
2104 ((srcval
>> 7) & 0xf8) | /* r */
2105 ((srcval
>> 12) & 0x07),
2106 ((srcval
>> 2) & 0xf8) | /* g */
2107 ((srcval
>> 7) & 0x07),
2108 ((srcval
<< 3) & 0xf8) | /* b */
2109 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
2115 if ((dstwidth
&1)!=0) {
2118 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2119 dstbits
+= linebytes
;
2121 } else if (bmpImage
->blue_mask
==0x7c00) {
2122 /* ==== bgr 555 bmp -> pal 4 dib ==== */
2123 for (h
=0; h
<lines
; h
++) {
2128 for (x
=0; x
<dstwidth
; x
++) {
2131 dstval
|=(X11DRV_DIB_GetNearestIndex
2133 ((srcval
<< 3) & 0xf8) | /* r */
2134 ((srcval
>> 2) & 0x07),
2135 ((srcval
>> 2) & 0xf8) | /* g */
2136 ((srcval
>> 7) & 0x07),
2137 ((srcval
>> 7) & 0xf8) | /* b */
2138 ((srcval
>> 12) & 0x07) ) << ((1-(x
&1))<<2) );
2144 if ((dstwidth
&1)!=0) {
2147 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2148 dstbits
+= linebytes
;
2153 } else if (bmpImage
->green_mask
==0x07e0) {
2154 if (bmpImage
->red_mask
==0xf800) {
2155 /* ==== rgb 565 bmp -> pal 4 dib ==== */
2156 for (h
=0; h
<lines
; h
++) {
2161 for (x
=0; x
<dstwidth
; x
++) {
2164 dstval
|=(X11DRV_DIB_GetNearestIndex
2166 ((srcval
>> 8) & 0xf8) | /* r */
2167 ((srcval
>> 13) & 0x07),
2168 ((srcval
>> 3) & 0xfc) | /* g */
2169 ((srcval
>> 9) & 0x03),
2170 ((srcval
<< 3) & 0xf8) | /* b */
2171 ((srcval
>> 2) & 0x07) ) << ((1-(x
&1))<<2) );
2177 if ((dstwidth
&1)!=0) {
2180 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2181 dstbits
+= linebytes
;
2183 } else if (bmpImage
->blue_mask
==0xf800) {
2184 /* ==== bgr 565 bmp -> pal 4 dib ==== */
2185 for (h
=0; h
<lines
; h
++) {
2190 for (x
=0; x
<dstwidth
; x
++) {
2193 dstval
|=(X11DRV_DIB_GetNearestIndex
2195 ((srcval
<< 3) & 0xf8) | /* r */
2196 ((srcval
>> 2) & 0x07),
2197 ((srcval
>> 3) & 0xfc) | /* g */
2198 ((srcval
>> 9) & 0x03),
2199 ((srcval
>> 8) & 0xf8) | /* b */
2200 ((srcval
>> 13) & 0x07) ) << ((1-(x
&1))<<2) );
2206 if ((dstwidth
&1)!=0) {
2209 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2210 dstbits
+= linebytes
;
2222 if (bmpImage
->bits_per_pixel
==24) {
2223 const void* srcbits
;
2224 const BYTE
*srcbyte
;
2227 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2229 if (bmpImage
->green_mask
!=0x00ff00 ||
2230 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2232 } else if (bmpImage
->blue_mask
==0xff) {
2233 /* ==== rgb 888 bmp -> pal 4 dib ==== */
2234 for (h
=0; h
<lines
; h
++) {
2237 for (x
=0; x
<dstwidth
/2; x
++) {
2238 /* Do 2 pixels at a time */
2239 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2244 X11DRV_DIB_GetNearestIndex
2252 /* And the the odd pixel */
2253 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2259 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2260 dstbits
+= linebytes
;
2263 /* ==== bgr 888 bmp -> pal 4 dib ==== */
2264 for (h
=0; h
<lines
; h
++) {
2267 for (x
=0; x
<dstwidth
/2; x
++) {
2268 /* Do 2 pixels at a time */
2269 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2274 X11DRV_DIB_GetNearestIndex
2282 /* And the the odd pixel */
2283 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2289 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2290 dstbits
+= linebytes
;
2299 const void* srcbits
;
2300 const BYTE
*srcbyte
;
2303 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2305 if (bmpImage
->green_mask
!=0x00ff00 ||
2306 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2308 } else if (bmpImage
->blue_mask
==0xff) {
2309 /* ==== rgb 0888 bmp -> pal 4 dib ==== */
2310 for (h
=0; h
<lines
; h
++) {
2313 for (x
=0; x
<dstwidth
/2; x
++) {
2314 /* Do 2 pixels at a time */
2315 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2320 X11DRV_DIB_GetNearestIndex
2328 /* And the the odd pixel */
2329 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2335 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2336 dstbits
+= linebytes
;
2339 /* ==== bgr 0888 bmp -> pal 4 dib ==== */
2340 for (h
=0; h
<lines
; h
++) {
2343 for (x
=0; x
<dstwidth
/2; x
++) {
2344 /* Do 2 pixels at a time */
2345 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2350 X11DRV_DIB_GetNearestIndex
2358 /* And the the odd pixel */
2359 *dstbyte
++=(X11DRV_DIB_GetNearestIndex
2365 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2366 dstbits
+= linebytes
;
2377 /* ==== any bmp format -> pal 4 dib ==== */
2378 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 4 bit DIB\n",
2379 bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
2380 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2381 for (h
=lines
-1; h
>=0; h
--) {
2383 for (x
=0; x
<(dstwidth
& ~1); x
+=2) {
2384 *dstbyte
++=(X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4) |
2385 X11DRV_DIB_MapColor((int*)colors
, 16, XGetPixel(bmpImage
, x
+1, h
), 0);
2388 *dstbyte
=(X11DRV_DIB_MapColor((int *)colors
, 16, XGetPixel(bmpImage
, x
, h
), 0) << 4);
2390 dstbits
+= linebytes
;
2397 /***********************************************************************
2398 * X11DRV_DIB_SetImageBits_RLE4
2400 * SetDIBits for a 4-bit deep compressed DIB.
2402 static void X11DRV_DIB_SetImageBits_RLE4( int lines
, const BYTE
*bits
,
2403 DWORD width
, DWORD dstwidth
,
2404 int left
, int *colors
,
2407 int x
= 0, y
= lines
- 1, c
, length
;
2408 const BYTE
*begin
= bits
;
2413 if (length
) { /* encoded */
2416 if (x
>= width
) break;
2417 XPutPixel(bmpImage
, x
++, y
, colors
[c
>> 4]);
2418 if (!length
--) break;
2419 if (x
>= width
) break;
2420 XPutPixel(bmpImage
, x
++, y
, colors
[c
& 0xf]);
2439 default: /* absolute */
2442 if (x
< width
) XPutPixel(bmpImage
, x
++, y
, colors
[c
>> 4]);
2443 if (!length
--) break;
2444 if (x
< width
) XPutPixel(bmpImage
, x
++, y
, colors
[c
& 0xf]);
2446 if ((bits
- begin
) & 1)
2455 /***********************************************************************
2456 * X11DRV_DIB_SetImageBits_8
2458 * SetDIBits for an 8-bit deep DIB.
2460 static void X11DRV_DIB_SetImageBits_8( int lines
, const BYTE
*srcbits
,
2461 DWORD srcwidth
, DWORD dstwidth
, int left
,
2462 const int *colors
, XImage
*bmpImage
,
2467 const BYTE
* srcbyte
;
2473 srcbits
= srcbits
+ linebytes
* (lines
-1);
2474 linebytes
= -linebytes
;
2479 switch (bmpImage
->depth
) {
2482 #if defined(__i386__) && defined(__GNUC__)
2483 /* Some X servers might have 32 bit/ 16bit deep pixel */
2484 if (lines
&& dstwidth
&& (bmpImage
->bits_per_pixel
== 16) &&
2485 (ImageByteOrder(gdi_display
)==LSBFirst
) )
2487 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2488 /* FIXME: Does this really handle all these cases correctly? */
2489 /* ==== pal 8 dib -> rgb or bgr 555 or 565 bmp ==== */
2490 for (h
= lines
; h
--; ) {
2491 int _cl1
,_cl2
; /* temp outputs for asm below */
2492 /* Borrowed from DirectDraw */
2493 __asm__
__volatile__(
2498 " movw (%%edx,%%eax,4),%%ax\n"
2500 " xor %%eax,%%eax\n"
2502 :"=S" (srcbyte
), "=D" (_cl1
), "=c" (_cl2
)
2507 :"eax", "cc", "memory"
2509 srcbyte
= (srcbits
+= linebytes
);
2510 dstbits
-= bmpImage
->bytes_per_line
;
2518 #if defined(__i386__) && defined(__GNUC__)
2519 if (lines
&& dstwidth
&& (bmpImage
->bits_per_pixel
== 32) &&
2520 (ImageByteOrder(gdi_display
)==LSBFirst
) )
2522 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
2523 /* FIXME: Does this really handle both cases correctly? */
2524 /* ==== pal 8 dib -> rgb or bgr 0888 bmp ==== */
2525 for (h
= lines
; h
--; ) {
2526 int _cl1
,_cl2
; /* temp outputs for asm below */
2527 /* Borrowed from DirectDraw */
2528 __asm__
__volatile__(
2533 " movl (%%edx,%%eax,4),%%eax\n"
2535 " xor %%eax,%%eax\n"
2537 :"=S" (srcbyte
), "=D" (_cl1
), "=c" (_cl2
)
2542 :"eax", "cc", "memory"
2544 srcbyte
= (srcbits
+= linebytes
);
2545 dstbits
-= bmpImage
->bytes_per_line
;
2552 break; /* use slow generic case below */
2555 /* ==== pal 8 dib -> any bmp format ==== */
2556 for (h
=lines
-1; h
>=0; h
--) {
2557 for (x
=left
; x
<dstwidth
+left
; x
++) {
2558 XPutPixel(bmpImage
, x
, h
, colors
[*srcbyte
++]);
2560 srcbyte
= (srcbits
+= linebytes
);
2564 /***********************************************************************
2565 * X11DRV_DIB_GetImageBits_8
2567 * GetDIBits for an 8-bit deep DIB.
2569 static void X11DRV_DIB_GetImageBits_8( int lines
, BYTE
*dstbits
,
2570 DWORD srcwidth
, DWORD dstwidth
,
2571 RGBQUAD
*colors
, PALETTEENTRY
*srccolors
,
2572 XImage
*bmpImage
, DWORD linebytes
)
2581 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
2582 linebytes
= -linebytes
;
2587 * This condition is true when GetImageBits has been called by
2588 * UpdateDIBSection. For now, GetNearestIndex is too slow to support
2589 * 256 colormaps, so we'll just use for for GetDIBits calls.
2590 * (In somes cases, in a updateDIBSection, the returned colors are bad too)
2592 if (!srccolors
) goto updatesection
;
2594 switch (bmpImage
->depth
) {
2597 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2599 /* ==== pal 1 bmp -> pal 8 dib ==== */
2600 /* ==== pal 4 bmp -> pal 8 dib ==== */
2601 for (h
=lines
-1; h
>=0; h
--) {
2603 for (x
=0; x
<dstwidth
; x
++) {
2604 PALETTEENTRY srcval
;
2605 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
2606 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
2611 dstbits
+= linebytes
;
2619 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
2620 /* ==== pal 8 bmp -> pal 8 dib ==== */
2621 const void* srcbits
;
2622 const BYTE
* srcpixel
;
2624 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2625 for (h
=0; h
<lines
; h
++) {
2628 for (x
= 0; x
< dstwidth
; x
++) {
2629 PALETTEENTRY srcval
;
2630 srcval
=srccolors
[(int)*srcpixel
++];
2631 *dstbyte
++=X11DRV_DIB_GetNearestIndex(colors
, 256,
2636 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2637 dstbits
+= linebytes
;
2647 const void* srcbits
;
2648 const WORD
* srcpixel
;
2651 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2653 if (bmpImage
->green_mask
==0x03e0) {
2654 if (bmpImage
->red_mask
==0x7c00) {
2655 /* ==== rgb 555 bmp -> pal 8 dib ==== */
2656 for (h
=0; h
<lines
; h
++) {
2659 for (x
=0; x
<dstwidth
; x
++) {
2662 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2664 ((srcval
>> 7) & 0xf8) | /* r */
2665 ((srcval
>> 12) & 0x07),
2666 ((srcval
>> 2) & 0xf8) | /* g */
2667 ((srcval
>> 7) & 0x07),
2668 ((srcval
<< 3) & 0xf8) | /* b */
2669 ((srcval
>> 2) & 0x07) );
2671 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2672 dstbits
+= linebytes
;
2674 } else if (bmpImage
->blue_mask
==0x7c00) {
2675 /* ==== bgr 555 bmp -> pal 8 dib ==== */
2676 for (h
=0; h
<lines
; h
++) {
2679 for (x
=0; x
<dstwidth
; x
++) {
2682 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2684 ((srcval
<< 3) & 0xf8) | /* r */
2685 ((srcval
>> 2) & 0x07),
2686 ((srcval
>> 2) & 0xf8) | /* g */
2687 ((srcval
>> 7) & 0x07),
2688 ((srcval
>> 7) & 0xf8) | /* b */
2689 ((srcval
>> 12) & 0x07) );
2691 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2692 dstbits
+= linebytes
;
2697 } else if (bmpImage
->green_mask
==0x07e0) {
2698 if (bmpImage
->red_mask
==0xf800) {
2699 /* ==== rgb 565 bmp -> pal 8 dib ==== */
2700 for (h
=0; h
<lines
; h
++) {
2703 for (x
=0; x
<dstwidth
; x
++) {
2706 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2708 ((srcval
>> 8) & 0xf8) | /* r */
2709 ((srcval
>> 13) & 0x07),
2710 ((srcval
>> 3) & 0xfc) | /* g */
2711 ((srcval
>> 9) & 0x03),
2712 ((srcval
<< 3) & 0xf8) | /* b */
2713 ((srcval
>> 2) & 0x07) );
2715 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2716 dstbits
+= linebytes
;
2718 } else if (bmpImage
->blue_mask
==0xf800) {
2719 /* ==== bgr 565 bmp -> pal 8 dib ==== */
2720 for (h
=0; h
<lines
; h
++) {
2723 for (x
=0; x
<dstwidth
; x
++) {
2726 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2728 ((srcval
<< 3) & 0xf8) | /* r */
2729 ((srcval
>> 2) & 0x07),
2730 ((srcval
>> 3) & 0xfc) | /* g */
2731 ((srcval
>> 9) & 0x03),
2732 ((srcval
>> 8) & 0xf8) | /* b */
2733 ((srcval
>> 13) & 0x07) );
2735 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2736 dstbits
+= linebytes
;
2750 const void* srcbits
;
2751 const BYTE
*srcbyte
;
2753 int bytes_per_pixel
;
2755 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
2756 bytes_per_pixel
=(bmpImage
->bits_per_pixel
==24?3:4);
2758 if (bmpImage
->green_mask
!=0x00ff00 ||
2759 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
2761 } else if (bmpImage
->blue_mask
==0xff) {
2762 /* ==== rgb 888 or 0888 bmp -> pal 8 dib ==== */
2763 for (h
=0; h
<lines
; h
++) {
2766 for (x
=0; x
<dstwidth
; x
++) {
2767 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2772 srcbyte
+=bytes_per_pixel
;
2774 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2775 dstbits
+= linebytes
;
2778 /* ==== bgr 888 or 0888 bmp -> pal 8 dib ==== */
2779 for (h
=0; h
<lines
; h
++) {
2782 for (x
=0; x
<dstwidth
; x
++) {
2783 *dstbyte
++=X11DRV_DIB_GetNearestIndex
2788 srcbyte
+=bytes_per_pixel
;
2790 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
2791 dstbits
+= linebytes
;
2799 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 8 bit DIB\n",
2800 bmpImage
->depth
, bmpImage
->red_mask
,
2801 bmpImage
->green_mask
, bmpImage
->blue_mask
);
2803 /* ==== any bmp format -> pal 8 dib ==== */
2804 for (h
=lines
-1; h
>=0; h
--) {
2806 for (x
=0; x
<dstwidth
; x
++) {
2807 *dstbyte
=X11DRV_DIB_MapColor
2809 XGetPixel(bmpImage
, x
, h
), *dstbyte
);
2812 dstbits
+= linebytes
;
2818 /***********************************************************************
2819 * X11DRV_DIB_SetImageBits_RLE8
2821 * SetDIBits for an 8-bit deep compressed DIB.
2823 * This function rewritten 941113 by James Youngman. WINE blew out when I
2824 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
2826 * This was because the algorithm assumed that all RLE8 bitmaps end with the
2827 * 'End of bitmap' escape code. This code is very much laxer in what it
2828 * allows to end the expansion. Possibly too lax. See the note by
2829 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
2830 * bitmap should end with RleEnd, but on the other hand, software exists
2831 * that produces ones that don't and Windows 3.1 doesn't complain a bit
2834 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
2835 * James A. Youngman <mbcstjy@afs.man.ac.uk>
2838 static void X11DRV_DIB_SetImageBits_RLE8( int lines
, const BYTE
*bits
,
2839 DWORD width
, DWORD dstwidth
,
2840 int left
, int *colors
,
2843 int x
; /* X-positon on each line. Increases. */
2844 int y
; /* Line #. Starts at lines-1, decreases */
2845 const BYTE
*pIn
= bits
; /* Pointer to current position in bits */
2846 BYTE length
; /* The length pf a run */
2847 BYTE escape_code
; /* See enum Rle8_EscapeCodes.*/
2850 * Note that the bitmap data is stored by Windows starting at the
2851 * bottom line of the bitmap and going upwards. Within each line,
2852 * the data is stored left-to-right. That's the reason why line
2853 * goes from lines-1 to 0. [JAY]
2863 * If the length byte is not zero (which is the escape value),
2864 * We have a run of length pixels all the same colour. The colour
2865 * index is stored next.
2867 * If the length byte is zero, we need to read the next byte to
2868 * know what to do. [JAY]
2873 * [Run-Length] Encoded mode
2875 int color
= colors
[*pIn
++];
2876 while (length
-- && x
< dstwidth
) XPutPixel(bmpImage
, x
++, y
, color
);
2881 * Escape codes (may be an absolute sequence though)
2883 escape_code
= (*pIn
++);
2892 /* Not all RLE8 bitmaps end with this code. For
2893 * example, Paint Shop Pro produces some that don't.
2894 * That's (I think) what caused the previous
2895 * implementation to fail. [JAY]
2904 default: /* switch to absolute mode */
2905 length
= escape_code
;
2908 int color
= colors
[*pIn
++];
2914 XPutPixel(bmpImage
, x
++, y
, color
);
2917 * If you think for a moment you'll realise that the
2918 * only time we could ever possibly read an odd
2919 * number of bytes is when there is a 0x00 (escape),
2920 * a value >0x02 (absolute mode) and then an odd-
2921 * length run. Therefore this is the only place we
2922 * need to worry about it. Everywhere else the
2923 * bytes are always read in pairs. [JAY]
2925 if (escape_code
& 1) pIn
++; /* Throw away the pad byte. */
2927 } /* switch (escape_code) : Escape sequence */
2933 /***********************************************************************
2934 * X11DRV_DIB_SetImageBits_16
2936 * SetDIBits for a 16-bit deep DIB.
2938 static void X11DRV_DIB_SetImageBits_16( int lines
, const BYTE
*srcbits
,
2939 DWORD srcwidth
, DWORD dstwidth
, int left
,
2940 X11DRV_PDEVICE
*physDev
, DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
2941 XImage
*bmpImage
, DWORD linebytes
)
2949 srcbits
= srcbits
+ ( linebytes
* (lines
-1));
2950 linebytes
= -linebytes
;
2953 switch (bmpImage
->depth
)
2960 srcbits
=srcbits
+left
*2;
2961 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
2963 if (bmpImage
->green_mask
==0x03e0) {
2964 if (gSrc
==bmpImage
->green_mask
) {
2965 if (rSrc
==bmpImage
->red_mask
) {
2966 /* ==== rgb 555 dib -> rgb 555 bmp ==== */
2967 /* ==== bgr 555 dib -> bgr 555 bmp ==== */
2968 X11DRV_DIB_Convert_any_asis
2971 dstbits
,-bmpImage
->bytes_per_line
);
2972 } else if (rSrc
==bmpImage
->blue_mask
) {
2973 /* ==== rgb 555 dib -> bgr 555 bmp ==== */
2974 /* ==== bgr 555 dib -> rgb 555 bmp ==== */
2975 X11DRV_DIB_Convert_555_reverse
2978 dstbits
,-bmpImage
->bytes_per_line
);
2981 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
2982 /* ==== rgb 565 dib -> rgb 555 bmp ==== */
2983 /* ==== bgr 565 dib -> bgr 555 bmp ==== */
2984 X11DRV_DIB_Convert_565_to_555_asis
2987 dstbits
,-bmpImage
->bytes_per_line
);
2989 /* ==== rgb 565 dib -> bgr 555 bmp ==== */
2990 /* ==== bgr 565 dib -> rgb 555 bmp ==== */
2991 X11DRV_DIB_Convert_565_to_555_reverse
2994 dstbits
,-bmpImage
->bytes_per_line
);
2997 } else if (bmpImage
->green_mask
==0x07e0) {
2998 if (gSrc
==bmpImage
->green_mask
) {
2999 if (rSrc
==bmpImage
->red_mask
) {
3000 /* ==== rgb 565 dib -> rgb 565 bmp ==== */
3001 /* ==== bgr 565 dib -> bgr 565 bmp ==== */
3002 X11DRV_DIB_Convert_any_asis
3005 dstbits
,-bmpImage
->bytes_per_line
);
3007 /* ==== rgb 565 dib -> bgr 565 bmp ==== */
3008 /* ==== bgr 565 dib -> rgb 565 bmp ==== */
3009 X11DRV_DIB_Convert_565_reverse
3012 dstbits
,-bmpImage
->bytes_per_line
);
3015 if (rSrc
==bmpImage
->red_mask
|| bSrc
==bmpImage
->blue_mask
) {
3016 /* ==== rgb 555 dib -> rgb 565 bmp ==== */
3017 /* ==== bgr 555 dib -> bgr 565 bmp ==== */
3018 X11DRV_DIB_Convert_555_to_565_asis
3021 dstbits
,-bmpImage
->bytes_per_line
);
3023 /* ==== rgb 555 dib -> bgr 565 bmp ==== */
3024 /* ==== bgr 555 dib -> rgb 565 bmp ==== */
3025 X11DRV_DIB_Convert_555_to_565_reverse
3028 dstbits
,-bmpImage
->bytes_per_line
);
3038 if (bmpImage
->bits_per_pixel
==24) {
3041 srcbits
=srcbits
+left
*2;
3042 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
3044 if (bmpImage
->green_mask
!=0x00ff00 ||
3045 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3047 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
3048 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
3050 /* ==== rgb 555 dib -> rgb 888 bmp ==== */
3051 /* ==== bgr 555 dib -> bgr 888 bmp ==== */
3052 X11DRV_DIB_Convert_555_to_888_asis
3055 dstbits
,-bmpImage
->bytes_per_line
);
3057 /* ==== rgb 565 dib -> rgb 888 bmp ==== */
3058 /* ==== bgr 565 dib -> bgr 888 bmp ==== */
3059 X11DRV_DIB_Convert_565_to_888_asis
3062 dstbits
,-bmpImage
->bytes_per_line
);
3066 /* ==== rgb 555 dib -> bgr 888 bmp ==== */
3067 /* ==== bgr 555 dib -> rgb 888 bmp ==== */
3068 X11DRV_DIB_Convert_555_to_888_reverse
3071 dstbits
,-bmpImage
->bytes_per_line
);
3073 /* ==== rgb 565 dib -> bgr 888 bmp ==== */
3074 /* ==== bgr 565 dib -> rgb 888 bmp ==== */
3075 X11DRV_DIB_Convert_565_to_888_reverse
3078 dstbits
,-bmpImage
->bytes_per_line
);
3089 srcbits
=srcbits
+left
*2;
3090 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
3092 if (bmpImage
->green_mask
!=0x00ff00 ||
3093 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3095 } else if ((rSrc
==0x1f && bmpImage
->red_mask
==0xff) ||
3096 (bSrc
==0x1f && bmpImage
->blue_mask
==0xff)) {
3098 /* ==== rgb 555 dib -> rgb 0888 bmp ==== */
3099 /* ==== bgr 555 dib -> bgr 0888 bmp ==== */
3100 X11DRV_DIB_Convert_555_to_0888_asis
3103 dstbits
,-bmpImage
->bytes_per_line
);
3105 /* ==== rgb 565 dib -> rgb 0888 bmp ==== */
3106 /* ==== bgr 565 dib -> bgr 0888 bmp ==== */
3107 X11DRV_DIB_Convert_565_to_0888_asis
3110 dstbits
,-bmpImage
->bytes_per_line
);
3114 /* ==== rgb 555 dib -> bgr 0888 bmp ==== */
3115 /* ==== bgr 555 dib -> rgb 0888 bmp ==== */
3116 X11DRV_DIB_Convert_555_to_0888_reverse
3119 dstbits
,-bmpImage
->bytes_per_line
);
3121 /* ==== rgb 565 dib -> bgr 0888 bmp ==== */
3122 /* ==== bgr 565 dib -> rgb 0888 bmp ==== */
3123 X11DRV_DIB_Convert_565_to_0888_reverse
3126 dstbits
,-bmpImage
->bytes_per_line
);
3134 WARN("from 16 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3135 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
3136 bmpImage
->green_mask
, bmpImage
->blue_mask
);
3142 /* ==== rgb or bgr 555 or 565 dib -> pal 1, 4 or 8 ==== */
3143 const WORD
* srcpixel
;
3144 int rShift1
,gShift1
,bShift1
;
3145 int rShift2
,gShift2
,bShift2
;
3148 /* Set color scaling values */
3149 rShift1
=16+X11DRV_DIB_MaskToShift(rSrc
)-3;
3150 gShift1
=16+X11DRV_DIB_MaskToShift(gSrc
)-3;
3151 bShift1
=16+X11DRV_DIB_MaskToShift(bSrc
)-3;
3156 /* Green has 5 bits, like the others */
3160 /* Green has 6 bits, not 5. Compensate. */
3169 /* We could split it into four separate cases to optimize
3170 * but it is probably not worth it.
3172 for (h
=lines
-1; h
>=0; h
--) {
3173 srcpixel
=(const WORD
*)srcbits
;
3174 for (x
=left
; x
<dstwidth
+left
; x
++) {
3176 BYTE red
,green
,blue
;
3177 srcval
=*srcpixel
++ << 16;
3178 red
= ((srcval
>> rShift1
) & 0xf8) |
3179 ((srcval
>> rShift2
) & 0x07);
3180 green
=((srcval
>> gShift1
) & gMask1
) |
3181 ((srcval
>> gShift2
) & gMask2
);
3182 blue
= ((srcval
>> bShift1
) & 0xf8) |
3183 ((srcval
>> bShift2
) & 0x07);
3184 XPutPixel(bmpImage
, x
, h
,
3185 X11DRV_PALETTE_ToPhysical
3186 (physDev
, RGB(red
,green
,blue
)));
3188 srcbits
+= linebytes
;
3196 /***********************************************************************
3197 * X11DRV_DIB_GetImageBits_16
3199 * GetDIBits for an 16-bit deep DIB.
3201 static void X11DRV_DIB_GetImageBits_16( int lines
, BYTE
*dstbits
,
3202 DWORD dstwidth
, DWORD srcwidth
,
3203 PALETTEENTRY
*srccolors
,
3204 DWORD rDst
, DWORD gDst
, DWORD bDst
,
3205 XImage
*bmpImage
, DWORD dibpitch
)
3210 DWORD linebytes
= dibpitch
;
3215 dstbits
= dstbits
+ ( linebytes
* (lines
-1));
3216 linebytes
= -linebytes
;
3219 switch (bmpImage
->depth
)
3224 const char* srcbits
;
3226 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3228 if (bmpImage
->green_mask
==0x03e0) {
3229 if (gDst
==bmpImage
->green_mask
) {
3230 if (rDst
==bmpImage
->red_mask
) {
3231 /* ==== rgb 555 bmp -> rgb 555 dib ==== */
3232 /* ==== bgr 555 bmp -> bgr 555 dib ==== */
3233 X11DRV_DIB_Convert_any_asis
3235 srcbits
,-bmpImage
->bytes_per_line
,
3238 /* ==== rgb 555 bmp -> bgr 555 dib ==== */
3239 /* ==== bgr 555 bmp -> rgb 555 dib ==== */
3240 X11DRV_DIB_Convert_555_reverse
3242 srcbits
,-bmpImage
->bytes_per_line
,
3246 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
3247 /* ==== rgb 555 bmp -> rgb 565 dib ==== */
3248 /* ==== bgr 555 bmp -> bgr 565 dib ==== */
3249 X11DRV_DIB_Convert_555_to_565_asis
3251 srcbits
,-bmpImage
->bytes_per_line
,
3254 /* ==== rgb 555 bmp -> bgr 565 dib ==== */
3255 /* ==== bgr 555 bmp -> rgb 565 dib ==== */
3256 X11DRV_DIB_Convert_555_to_565_reverse
3258 srcbits
,-bmpImage
->bytes_per_line
,
3262 } else if (bmpImage
->green_mask
==0x07e0) {
3263 if (gDst
==bmpImage
->green_mask
) {
3264 if (rDst
== bmpImage
->red_mask
) {
3265 /* ==== rgb 565 bmp -> rgb 565 dib ==== */
3266 /* ==== bgr 565 bmp -> bgr 565 dib ==== */
3267 X11DRV_DIB_Convert_any_asis
3269 srcbits
,-bmpImage
->bytes_per_line
,
3272 /* ==== rgb 565 bmp -> bgr 565 dib ==== */
3273 /* ==== bgr 565 bmp -> rgb 565 dib ==== */
3274 X11DRV_DIB_Convert_565_reverse
3276 srcbits
,-bmpImage
->bytes_per_line
,
3280 if (rDst
==bmpImage
->red_mask
|| bDst
==bmpImage
->blue_mask
) {
3281 /* ==== rgb 565 bmp -> rgb 555 dib ==== */
3282 /* ==== bgr 565 bmp -> bgr 555 dib ==== */
3283 X11DRV_DIB_Convert_565_to_555_asis
3285 srcbits
,-bmpImage
->bytes_per_line
,
3288 /* ==== rgb 565 bmp -> bgr 555 dib ==== */
3289 /* ==== bgr 565 bmp -> rgb 555 dib ==== */
3290 X11DRV_DIB_Convert_565_to_555_reverse
3292 srcbits
,-bmpImage
->bytes_per_line
,
3303 if (bmpImage
->bits_per_pixel
== 24) {
3304 const char* srcbits
;
3306 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3308 if (bmpImage
->green_mask
!=0x00ff00 ||
3309 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3311 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
3312 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
3314 /* ==== rgb 888 bmp -> rgb 555 dib ==== */
3315 /* ==== bgr 888 bmp -> bgr 555 dib ==== */
3316 X11DRV_DIB_Convert_888_to_555_asis
3318 srcbits
,-bmpImage
->bytes_per_line
,
3321 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
3322 /* ==== rgb 888 bmp -> rgb 565 dib ==== */
3323 X11DRV_DIB_Convert_888_to_565_asis
3325 srcbits
,-bmpImage
->bytes_per_line
,
3330 /* ==== rgb 888 bmp -> bgr 555 dib ==== */
3331 /* ==== bgr 888 bmp -> rgb 555 dib ==== */
3332 X11DRV_DIB_Convert_888_to_555_reverse
3334 srcbits
,-bmpImage
->bytes_per_line
,
3337 /* ==== rgb 888 bmp -> bgr 565 dib ==== */
3338 /* ==== bgr 888 bmp -> rgb 565 dib ==== */
3339 X11DRV_DIB_Convert_888_to_565_reverse
3341 srcbits
,-bmpImage
->bytes_per_line
,
3351 const char* srcbits
;
3353 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3355 if (bmpImage
->green_mask
!=0x00ff00 ||
3356 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3358 } else if ((rDst
==0x1f && bmpImage
->red_mask
==0xff) ||
3359 (bDst
==0x1f && bmpImage
->blue_mask
==0xff)) {
3361 /* ==== rgb 0888 bmp -> rgb 555 dib ==== */
3362 /* ==== bgr 0888 bmp -> bgr 555 dib ==== */
3363 X11DRV_DIB_Convert_0888_to_555_asis
3365 srcbits
,-bmpImage
->bytes_per_line
,
3368 /* ==== rgb 0888 bmp -> rgb 565 dib ==== */
3369 /* ==== bgr 0888 bmp -> bgr 565 dib ==== */
3370 X11DRV_DIB_Convert_0888_to_565_asis
3372 srcbits
,-bmpImage
->bytes_per_line
,
3377 /* ==== rgb 0888 bmp -> bgr 555 dib ==== */
3378 /* ==== bgr 0888 bmp -> rgb 555 dib ==== */
3379 X11DRV_DIB_Convert_0888_to_555_reverse
3381 srcbits
,-bmpImage
->bytes_per_line
,
3384 /* ==== rgb 0888 bmp -> bgr 565 dib ==== */
3385 /* ==== bgr 0888 bmp -> rgb 565 dib ==== */
3386 X11DRV_DIB_Convert_0888_to_565_reverse
3388 srcbits
,-bmpImage
->bytes_per_line
,
3397 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3398 /* ==== pal 1 or 4 bmp -> rgb or bgr 555 or 565 dib ==== */
3399 int rShift
,gShift
,bShift
;
3402 /* Shift everything 16 bits left so that all shifts are >0,
3403 * even for BGR DIBs. Then a single >> 16 will bring everything
3406 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
3407 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
3408 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
3410 /* 6 bits for the green */
3416 for (h
= lines
- 1; h
>= 0; h
--) {
3417 dstpixel
=(LPWORD
)dstbits
;
3418 for (x
= 0; x
< dstwidth
; x
++) {
3419 PALETTEENTRY srcval
;
3421 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
3422 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
3423 ((srcval
.peGreen
<< gShift
) & gDst
) |
3424 ((srcval
.peBlue
<< bShift
) & bDst
);
3425 *dstpixel
++=dstval
>> 16;
3427 dstbits
+= linebytes
;
3435 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3436 /* ==== pal 8 bmp -> rgb or bgr 555 or 565 dib ==== */
3437 int rShift
,gShift
,bShift
;
3438 const BYTE
* srcbits
;
3439 const BYTE
* srcpixel
;
3442 /* Shift everything 16 bits left so that all shifts are >0,
3443 * even for BGR DIBs. Then a single >> 16 will bring everything
3446 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
3447 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
3448 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
3450 /* 6 bits for the green */
3456 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3457 for (h
=0; h
<lines
; h
++) {
3459 dstpixel
=(LPWORD
)dstbits
;
3460 for (x
= 0; x
< dstwidth
; x
++) {
3461 PALETTEENTRY srcval
;
3463 srcval
=srccolors
[(int)*srcpixel
++];
3464 dstval
=((srcval
.peRed
<< rShift
) & rDst
) |
3465 ((srcval
.peGreen
<< gShift
) & gDst
) |
3466 ((srcval
.peBlue
<< bShift
) & bDst
);
3467 *dstpixel
++=dstval
>> 16;
3469 srcbits
-= bmpImage
->bytes_per_line
;
3470 dstbits
+= linebytes
;
3480 /* ==== any bmp format -> rgb or bgr 555 or 565 dib ==== */
3481 int rShift
,gShift
,bShift
;
3484 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 16 bit DIB (%lx,%lx,%lx)\n",
3485 bmpImage
->depth
, bmpImage
->red_mask
,
3486 bmpImage
->green_mask
, bmpImage
->blue_mask
,
3489 /* Shift everything 16 bits left so that all shifts are >0,
3490 * even for BGR DIBs. Then a single >> 16 will bring everything
3493 rShift
=16+X11DRV_DIB_MaskToShift(rDst
)-3;
3494 gShift
=16+X11DRV_DIB_MaskToShift(gDst
)-3;
3495 bShift
=16+X11DRV_DIB_MaskToShift(bDst
)-3;
3497 /* 6 bits for the green */
3503 for (h
= lines
- 1; h
>= 0; h
--) {
3504 dstpixel
=(LPWORD
)dstbits
;
3505 for (x
= 0; x
< dstwidth
; x
++) {
3508 srcval
=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage
, x
, h
));
3509 dstval
=((GetRValue(srcval
) << rShift
) & rDst
) |
3510 ((GetGValue(srcval
) << gShift
) & gDst
) |
3511 ((GetBValue(srcval
) << bShift
) & bDst
);
3512 *dstpixel
++=dstval
>> 16;
3514 dstbits
+= linebytes
;
3522 /***********************************************************************
3523 * X11DRV_DIB_SetImageBits_24
3525 * SetDIBits for a 24-bit deep DIB.
3527 static void X11DRV_DIB_SetImageBits_24( int lines
, const BYTE
*srcbits
,
3528 DWORD srcwidth
, DWORD dstwidth
, int left
,
3529 X11DRV_PDEVICE
*physDev
,
3530 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
3531 XImage
*bmpImage
, DWORD linebytes
)
3539 srcbits
= srcbits
+ linebytes
* (lines
- 1);
3540 linebytes
= -linebytes
;
3543 switch (bmpImage
->depth
)
3546 if (bmpImage
->bits_per_pixel
==24) {
3549 srcbits
=srcbits
+left
*3;
3550 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
3552 if (bmpImage
->green_mask
!=0x00ff00 ||
3553 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3555 } else if (rSrc
==bmpImage
->red_mask
) {
3556 /* ==== rgb 888 dib -> rgb 888 bmp ==== */
3557 /* ==== bgr 888 dib -> bgr 888 bmp ==== */
3558 X11DRV_DIB_Convert_any_asis
3561 dstbits
,-bmpImage
->bytes_per_line
);
3563 /* ==== rgb 888 dib -> bgr 888 bmp ==== */
3564 /* ==== bgr 888 dib -> rgb 888 bmp ==== */
3565 X11DRV_DIB_Convert_888_reverse
3568 dstbits
,-bmpImage
->bytes_per_line
);
3578 srcbits
=srcbits
+left
*3;
3579 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
3581 if (bmpImage
->green_mask
!=0x00ff00 ||
3582 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3584 } else if (rSrc
==bmpImage
->red_mask
) {
3585 /* ==== rgb 888 dib -> rgb 0888 bmp ==== */
3586 /* ==== bgr 888 dib -> bgr 0888 bmp ==== */
3587 X11DRV_DIB_Convert_888_to_0888_asis
3590 dstbits
,-bmpImage
->bytes_per_line
);
3592 /* ==== rgb 888 dib -> bgr 0888 bmp ==== */
3593 /* ==== bgr 888 dib -> rgb 0888 bmp ==== */
3594 X11DRV_DIB_Convert_888_to_0888_reverse
3597 dstbits
,-bmpImage
->bytes_per_line
);
3607 srcbits
=srcbits
+left
*3;
3608 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
3610 if (bmpImage
->green_mask
==0x03e0) {
3611 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
3612 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
3613 /* ==== rgb 888 dib -> rgb 555 bmp ==== */
3614 /* ==== bgr 888 dib -> bgr 555 bmp ==== */
3615 X11DRV_DIB_Convert_888_to_555_asis
3618 dstbits
,-bmpImage
->bytes_per_line
);
3619 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0x7f00) ||
3620 (bSrc
==0xff && bmpImage
->blue_mask
==0x7f00)) {
3621 /* ==== rgb 888 dib -> bgr 555 bmp ==== */
3622 /* ==== bgr 888 dib -> rgb 555 bmp ==== */
3623 X11DRV_DIB_Convert_888_to_555_reverse
3626 dstbits
,-bmpImage
->bytes_per_line
);
3630 } else if (bmpImage
->green_mask
==0x07e0) {
3631 if ((rSrc
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
3632 (bSrc
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
3633 /* ==== rgb 888 dib -> rgb 565 bmp ==== */
3634 /* ==== bgr 888 dib -> bgr 565 bmp ==== */
3635 X11DRV_DIB_Convert_888_to_565_asis
3638 dstbits
,-bmpImage
->bytes_per_line
);
3639 } else if ((rSrc
==0xff && bmpImage
->red_mask
==0xf800) ||
3640 (bSrc
==0xff && bmpImage
->blue_mask
==0xf800)) {
3641 /* ==== rgb 888 dib -> bgr 565 bmp ==== */
3642 /* ==== bgr 888 dib -> rgb 565 bmp ==== */
3643 X11DRV_DIB_Convert_888_to_565_reverse
3646 dstbits
,-bmpImage
->bytes_per_line
);
3658 WARN("from 24 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
3659 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
3660 bmpImage
->green_mask
, bmpImage
->blue_mask
);
3666 /* ==== rgb 888 dib -> any bmp bormat ==== */
3667 const BYTE
* srcbyte
;
3669 /* Windows only supports one 24bpp DIB format: RGB888 */
3671 for (h
= lines
- 1; h
>= 0; h
--) {
3672 srcbyte
=(const BYTE
*)srcbits
;
3673 for (x
= left
; x
< dstwidth
+left
; x
++) {
3674 XPutPixel(bmpImage
, x
, h
,
3675 X11DRV_PALETTE_ToPhysical
3676 (physDev
, RGB(srcbyte
[2], srcbyte
[1], srcbyte
[0])));
3679 srcbits
+= linebytes
;
3687 /***********************************************************************
3688 * X11DRV_DIB_GetImageBits_24
3690 * GetDIBits for an 24-bit deep DIB.
3692 static void X11DRV_DIB_GetImageBits_24( int lines
, BYTE
*dstbits
,
3693 DWORD dstwidth
, DWORD srcwidth
,
3694 PALETTEENTRY
*srccolors
,
3695 DWORD rDst
, DWORD gDst
, DWORD bDst
,
3696 XImage
*bmpImage
, DWORD linebytes
)
3704 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
3705 linebytes
= -linebytes
;
3708 switch (bmpImage
->depth
)
3711 if (bmpImage
->bits_per_pixel
==24) {
3712 const char* srcbits
;
3714 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3716 if (bmpImage
->green_mask
!=0x00ff00 ||
3717 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3719 } else if (rDst
==bmpImage
->red_mask
) {
3720 /* ==== rgb 888 bmp -> rgb 888 dib ==== */
3721 /* ==== bgr 888 bmp -> bgr 888 dib ==== */
3722 X11DRV_DIB_Convert_any_asis
3724 srcbits
,-bmpImage
->bytes_per_line
,
3727 /* ==== rgb 888 bmp -> bgr 888 dib ==== */
3728 /* ==== bgr 888 bmp -> rgb 888 dib ==== */
3729 X11DRV_DIB_Convert_888_reverse
3731 srcbits
,-bmpImage
->bytes_per_line
,
3740 const char* srcbits
;
3742 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3744 if (bmpImage
->green_mask
!=0x00ff00 ||
3745 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3747 } else if (rDst
==bmpImage
->red_mask
) {
3748 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
3749 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
3750 X11DRV_DIB_Convert_0888_to_888_asis
3752 srcbits
,-bmpImage
->bytes_per_line
,
3755 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
3756 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
3757 X11DRV_DIB_Convert_0888_to_888_reverse
3759 srcbits
,-bmpImage
->bytes_per_line
,
3768 const char* srcbits
;
3770 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3772 if (bmpImage
->green_mask
==0x03e0) {
3773 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0x7f00) ||
3774 (bDst
==0xff0000 && bmpImage
->blue_mask
==0x7f00)) {
3775 /* ==== rgb 555 bmp -> rgb 888 dib ==== */
3776 /* ==== bgr 555 bmp -> bgr 888 dib ==== */
3777 X11DRV_DIB_Convert_555_to_888_asis
3779 srcbits
,-bmpImage
->bytes_per_line
,
3781 } else if ((rDst
==0xff && bmpImage
->red_mask
==0x7f00) ||
3782 (bDst
==0xff && bmpImage
->blue_mask
==0x7f00)) {
3783 /* ==== rgb 555 bmp -> bgr 888 dib ==== */
3784 /* ==== bgr 555 bmp -> rgb 888 dib ==== */
3785 X11DRV_DIB_Convert_555_to_888_reverse
3787 srcbits
,-bmpImage
->bytes_per_line
,
3792 } else if (bmpImage
->green_mask
==0x07e0) {
3793 if ((rDst
==0xff0000 && bmpImage
->red_mask
==0xf800) ||
3794 (bDst
==0xff0000 && bmpImage
->blue_mask
==0xf800)) {
3795 /* ==== rgb 565 bmp -> rgb 888 dib ==== */
3796 /* ==== bgr 565 bmp -> bgr 888 dib ==== */
3797 X11DRV_DIB_Convert_565_to_888_asis
3799 srcbits
,-bmpImage
->bytes_per_line
,
3801 } else if ((rDst
==0xff && bmpImage
->red_mask
==0xf800) ||
3802 (bDst
==0xff && bmpImage
->blue_mask
==0xf800)) {
3803 /* ==== rgb 565 bmp -> bgr 888 dib ==== */
3804 /* ==== bgr 565 bmp -> rgb 888 dib ==== */
3805 X11DRV_DIB_Convert_565_to_888_reverse
3807 srcbits
,-bmpImage
->bytes_per_line
,
3820 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
3821 /* ==== pal 1 or 4 bmp -> rgb 888 dib ==== */
3824 /* Windows only supports one 24bpp DIB format: rgb 888 */
3825 for (h
= lines
- 1; h
>= 0; h
--) {
3827 for (x
= 0; x
< dstwidth
; x
++) {
3828 PALETTEENTRY srcval
;
3829 srcval
=srccolors
[XGetPixel(bmpImage
, x
, h
)];
3830 dstbyte
[0]=srcval
.peBlue
;
3831 dstbyte
[1]=srcval
.peGreen
;
3832 dstbyte
[2]=srcval
.peRed
;
3835 dstbits
+= linebytes
;
3843 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
== 0 && srccolors
) {
3844 /* ==== pal 8 bmp -> rgb 888 dib ==== */
3845 const void* srcbits
;
3846 const BYTE
* srcpixel
;
3849 /* Windows only supports one 24bpp DIB format: rgb 888 */
3850 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
3851 for (h
= lines
- 1; h
>= 0; h
--) {
3854 for (x
= 0; x
< dstwidth
; x
++ ) {
3855 PALETTEENTRY srcval
;
3856 srcval
=srccolors
[(int)*srcpixel
++];
3857 dstbyte
[0]=srcval
.peBlue
;
3858 dstbyte
[1]=srcval
.peGreen
;
3859 dstbyte
[2]=srcval
.peRed
;
3862 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
3863 dstbits
+= linebytes
;
3873 /* ==== any bmp format -> 888 dib ==== */
3876 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 24 bit DIB (%lx,%lx,%lx)\n",
3877 bmpImage
->depth
, bmpImage
->red_mask
,
3878 bmpImage
->green_mask
, bmpImage
->blue_mask
,
3881 /* Windows only supports one 24bpp DIB format: rgb 888 */
3882 for (h
= lines
- 1; h
>= 0; h
--) {
3884 for (x
= 0; x
< dstwidth
; x
++) {
3885 COLORREF srcval
=X11DRV_PALETTE_ToLogical
3886 (XGetPixel( bmpImage
, x
, h
));
3887 dstbyte
[0]=GetBValue(srcval
);
3888 dstbyte
[1]=GetGValue(srcval
);
3889 dstbyte
[2]=GetRValue(srcval
);
3892 dstbits
+= linebytes
;
3900 /***********************************************************************
3901 * X11DRV_DIB_SetImageBits_32
3903 * SetDIBits for a 32-bit deep DIB.
3905 static void X11DRV_DIB_SetImageBits_32(int lines
, const BYTE
*srcbits
,
3906 DWORD srcwidth
, DWORD dstwidth
, int left
,
3907 X11DRV_PDEVICE
*physDev
,
3908 DWORD rSrc
, DWORD gSrc
, DWORD bSrc
,
3918 srcbits
= srcbits
+ ( linebytes
* (lines
-1) );
3919 linebytes
= -linebytes
;
3922 ptr
= (DWORD
*) srcbits
+ left
;
3924 switch (bmpImage
->depth
)
3927 if (bmpImage
->bits_per_pixel
==24) {
3930 srcbits
=srcbits
+left
*4;
3931 dstbits
=bmpImage
->data
+left
*3+(lines
-1)*bmpImage
->bytes_per_line
;
3933 if (rSrc
==bmpImage
->red_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->blue_mask
) {
3934 /* ==== rgb 0888 dib -> rgb 888 bmp ==== */
3935 /* ==== bgr 0888 dib -> bgr 888 bmp ==== */
3936 X11DRV_DIB_Convert_0888_to_888_asis
3939 dstbits
,-bmpImage
->bytes_per_line
);
3940 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3941 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3943 /* the tests below assume sane bmpImage masks */
3944 } else if (rSrc
==bmpImage
->blue_mask
&& gSrc
==bmpImage
->green_mask
&& bSrc
==bmpImage
->red_mask
) {
3945 /* ==== rgb 0888 dib -> bgr 888 bmp ==== */
3946 /* ==== bgr 0888 dib -> rgb 888 bmp ==== */
3947 X11DRV_DIB_Convert_0888_to_888_reverse
3950 dstbits
,-bmpImage
->bytes_per_line
);
3951 } else if (bmpImage
->blue_mask
==0xff) {
3952 /* ==== any 0888 dib -> rgb 888 bmp ==== */
3953 X11DRV_DIB_Convert_any0888_to_rgb888
3957 dstbits
,-bmpImage
->bytes_per_line
);
3959 /* ==== any 0888 dib -> bgr 888 bmp ==== */
3960 X11DRV_DIB_Convert_any0888_to_bgr888
3964 dstbits
,-bmpImage
->bytes_per_line
);
3974 srcbits
=srcbits
+left
*4;
3975 dstbits
=bmpImage
->data
+left
*4+(lines
-1)*bmpImage
->bytes_per_line
;
3977 if (gSrc
==bmpImage
->green_mask
) {
3978 if (rSrc
==bmpImage
->red_mask
&& bSrc
==bmpImage
->blue_mask
) {
3979 /* ==== rgb 0888 dib -> rgb 0888 bmp ==== */
3980 /* ==== bgr 0888 dib -> bgr 0888 bmp ==== */
3981 X11DRV_DIB_Convert_any_asis
3984 dstbits
,-bmpImage
->bytes_per_line
);
3985 } else if (bmpImage
->green_mask
!=0x00ff00 ||
3986 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
3988 /* the tests below assume sane bmpImage masks */
3989 } else if (rSrc
==bmpImage
->blue_mask
&& bSrc
==bmpImage
->red_mask
) {
3990 /* ==== rgb 0888 dib -> bgr 0888 bmp ==== */
3991 /* ==== bgr 0888 dib -> rgb 0888 bmp ==== */
3992 X11DRV_DIB_Convert_0888_reverse
3995 dstbits
,-bmpImage
->bytes_per_line
);
3997 /* ==== any 0888 dib -> any 0888 bmp ==== */
3998 X11DRV_DIB_Convert_0888_any
4002 dstbits
,-bmpImage
->bytes_per_line
,
4003 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4005 } else if (bmpImage
->green_mask
!=0x00ff00 ||
4006 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
4008 /* the tests below assume sane bmpImage masks */
4010 /* ==== any 0888 dib -> any 0888 bmp ==== */
4011 X11DRV_DIB_Convert_0888_any
4015 dstbits
,-bmpImage
->bytes_per_line
,
4016 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4026 srcbits
=srcbits
+left
*4;
4027 dstbits
=bmpImage
->data
+left
*2+(lines
-1)*bmpImage
->bytes_per_line
;
4029 if (rSrc
==0xff0000 && gSrc
==0x00ff00 && bSrc
==0x0000ff) {
4030 if (bmpImage
->green_mask
==0x03e0) {
4031 if (bmpImage
->red_mask
==0x7f00) {
4032 /* ==== rgb 0888 dib -> rgb 555 bmp ==== */
4033 X11DRV_DIB_Convert_0888_to_555_asis
4036 dstbits
,-bmpImage
->bytes_per_line
);
4037 } else if (bmpImage
->blue_mask
==0x7f00) {
4038 /* ==== rgb 0888 dib -> bgr 555 bmp ==== */
4039 X11DRV_DIB_Convert_0888_to_555_reverse
4042 dstbits
,-bmpImage
->bytes_per_line
);
4046 } else if (bmpImage
->green_mask
==0x07e0) {
4047 if (bmpImage
->red_mask
==0xf800) {
4048 /* ==== rgb 0888 dib -> rgb 565 bmp ==== */
4049 X11DRV_DIB_Convert_0888_to_565_asis
4052 dstbits
,-bmpImage
->bytes_per_line
);
4053 } else if (bmpImage
->blue_mask
==0xf800) {
4054 /* ==== rgb 0888 dib -> bgr 565 bmp ==== */
4055 X11DRV_DIB_Convert_0888_to_565_reverse
4058 dstbits
,-bmpImage
->bytes_per_line
);
4065 } else if (rSrc
==0x0000ff && gSrc
==0x00ff00 && bSrc
==0xff0000) {
4066 if (bmpImage
->green_mask
==0x03e0) {
4067 if (bmpImage
->blue_mask
==0x7f00) {
4068 /* ==== bgr 0888 dib -> bgr 555 bmp ==== */
4069 X11DRV_DIB_Convert_0888_to_555_asis
4072 dstbits
,-bmpImage
->bytes_per_line
);
4073 } else if (bmpImage
->red_mask
==0x7f00) {
4074 /* ==== bgr 0888 dib -> rgb 555 bmp ==== */
4075 X11DRV_DIB_Convert_0888_to_555_reverse
4078 dstbits
,-bmpImage
->bytes_per_line
);
4082 } else if (bmpImage
->green_mask
==0x07e0) {
4083 if (bmpImage
->blue_mask
==0xf800) {
4084 /* ==== bgr 0888 dib -> bgr 565 bmp ==== */
4085 X11DRV_DIB_Convert_0888_to_565_asis
4088 dstbits
,-bmpImage
->bytes_per_line
);
4089 } else if (bmpImage
->red_mask
==0xf800) {
4090 /* ==== bgr 0888 dib -> rgb 565 bmp ==== */
4091 X11DRV_DIB_Convert_0888_to_565_reverse
4094 dstbits
,-bmpImage
->bytes_per_line
);
4102 if (bmpImage
->green_mask
==0x03e0 &&
4103 (bmpImage
->red_mask
==0x7f00 ||
4104 bmpImage
->blue_mask
==0x7f00)) {
4105 /* ==== any 0888 dib -> rgb or bgr 555 bmp ==== */
4106 X11DRV_DIB_Convert_any0888_to_5x5
4110 dstbits
,-bmpImage
->bytes_per_line
,
4111 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4112 } else if (bmpImage
->green_mask
==0x07e0 &&
4113 (bmpImage
->red_mask
==0xf800 ||
4114 bmpImage
->blue_mask
==0xf800)) {
4115 /* ==== any 0888 dib -> rgb or bgr 565 bmp ==== */
4116 X11DRV_DIB_Convert_any0888_to_5x5
4120 dstbits
,-bmpImage
->bytes_per_line
,
4121 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4131 WARN("from 32 bit DIB (%lx,%lx,%lx) to unknown %d bit bitmap (%lx,%lx,%lx)\n",
4132 rSrc
, gSrc
, bSrc
, bmpImage
->bits_per_pixel
, bmpImage
->red_mask
,
4133 bmpImage
->green_mask
, bmpImage
->blue_mask
);
4139 /* ==== any 0888 dib -> pal 1, 4 or 8 bmp ==== */
4140 const DWORD
* srcpixel
;
4141 int rShift
,gShift
,bShift
;
4143 rShift
=X11DRV_DIB_MaskToShift(rSrc
);
4144 gShift
=X11DRV_DIB_MaskToShift(gSrc
);
4145 bShift
=X11DRV_DIB_MaskToShift(bSrc
);
4147 for (h
= lines
- 1; h
>= 0; h
--) {
4148 srcpixel
=(const DWORD
*)srcbits
;
4149 for (x
= left
; x
< dstwidth
+left
; x
++) {
4151 BYTE red
,green
,blue
;
4152 srcvalue
=*srcpixel
++;
4153 red
= (srcvalue
>> rShift
) & 0xff;
4154 green
=(srcvalue
>> gShift
) & 0xff;
4155 blue
= (srcvalue
>> bShift
) & 0xff;
4156 XPutPixel(bmpImage
, x
, h
, X11DRV_PALETTE_ToPhysical
4157 (physDev
, RGB(red
,green
,blue
)));
4159 srcbits
+= linebytes
;
4167 /***********************************************************************
4168 * X11DRV_DIB_GetImageBits_32
4170 * GetDIBits for an 32-bit deep DIB.
4172 static void X11DRV_DIB_GetImageBits_32( int lines
, BYTE
*dstbits
,
4173 DWORD dstwidth
, DWORD srcwidth
,
4174 PALETTEENTRY
*srccolors
,
4175 DWORD rDst
, DWORD gDst
, DWORD bDst
,
4176 XImage
*bmpImage
, DWORD linebytes
)
4185 dstbits
= dstbits
+ ( linebytes
* (lines
-1) );
4186 linebytes
= -linebytes
;
4191 switch (bmpImage
->depth
)
4194 if (bmpImage
->bits_per_pixel
==24) {
4195 const void* srcbits
;
4197 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
4199 if (rDst
==bmpImage
->red_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->blue_mask
) {
4200 /* ==== rgb 888 bmp -> rgb 0888 dib ==== */
4201 /* ==== bgr 888 bmp -> bgr 0888 dib ==== */
4202 X11DRV_DIB_Convert_888_to_0888_asis
4204 srcbits
,-bmpImage
->bytes_per_line
,
4206 } else if (bmpImage
->green_mask
!=0x00ff00 ||
4207 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
4209 /* the tests below assume sane bmpImage masks */
4210 } else if (rDst
==bmpImage
->blue_mask
&& gDst
==bmpImage
->green_mask
&& bDst
==bmpImage
->red_mask
) {
4211 /* ==== rgb 888 bmp -> bgr 0888 dib ==== */
4212 /* ==== bgr 888 bmp -> rgb 0888 dib ==== */
4213 X11DRV_DIB_Convert_888_to_0888_reverse
4215 srcbits
,-bmpImage
->bytes_per_line
,
4217 } else if (bmpImage
->blue_mask
==0xff) {
4218 /* ==== rgb 888 bmp -> any 0888 dib ==== */
4219 X11DRV_DIB_Convert_rgb888_to_any0888
4221 srcbits
,-bmpImage
->bytes_per_line
,
4225 /* ==== bgr 888 bmp -> any 0888 dib ==== */
4226 X11DRV_DIB_Convert_bgr888_to_any0888
4228 srcbits
,-bmpImage
->bytes_per_line
,
4238 const char* srcbits
;
4240 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
4242 if (gDst
==bmpImage
->green_mask
) {
4243 if (rDst
==bmpImage
->red_mask
&& bDst
==bmpImage
->blue_mask
) {
4244 /* ==== rgb 0888 bmp -> rgb 0888 dib ==== */
4245 /* ==== bgr 0888 bmp -> bgr 0888 dib ==== */
4246 X11DRV_DIB_Convert_any_asis
4248 srcbits
,-bmpImage
->bytes_per_line
,
4250 } else if (bmpImage
->green_mask
!=0x00ff00 ||
4251 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
4253 /* the tests below assume sane bmpImage masks */
4254 } else if (rDst
==bmpImage
->blue_mask
&& bDst
==bmpImage
->red_mask
) {
4255 /* ==== rgb 0888 bmp -> bgr 0888 dib ==== */
4256 /* ==== bgr 0888 bmp -> rgb 0888 dib ==== */
4257 X11DRV_DIB_Convert_0888_reverse
4259 srcbits
,-bmpImage
->bytes_per_line
,
4262 /* ==== any 0888 bmp -> any 0888 dib ==== */
4263 X11DRV_DIB_Convert_0888_any
4265 srcbits
,-bmpImage
->bytes_per_line
,
4266 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
4270 } else if (bmpImage
->green_mask
!=0x00ff00 ||
4271 (bmpImage
->red_mask
|bmpImage
->blue_mask
)!=0xff00ff) {
4273 /* the tests below assume sane bmpImage masks */
4275 /* ==== any 0888 bmp -> any 0888 dib ==== */
4276 X11DRV_DIB_Convert_0888_any
4278 srcbits
,-bmpImage
->bytes_per_line
,
4279 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
4289 const char* srcbits
;
4291 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
4293 if (rDst
==0xff0000 && gDst
==0x00ff00 && bDst
==0x0000ff) {
4294 if (bmpImage
->green_mask
==0x03e0) {
4295 if (bmpImage
->red_mask
==0x7f00) {
4296 /* ==== rgb 555 bmp -> rgb 0888 dib ==== */
4297 X11DRV_DIB_Convert_555_to_0888_asis
4299 srcbits
,-bmpImage
->bytes_per_line
,
4301 } else if (bmpImage
->blue_mask
==0x7f00) {
4302 /* ==== bgr 555 bmp -> rgb 0888 dib ==== */
4303 X11DRV_DIB_Convert_555_to_0888_reverse
4305 srcbits
,-bmpImage
->bytes_per_line
,
4310 } else if (bmpImage
->green_mask
==0x07e0) {
4311 if (bmpImage
->red_mask
==0xf800) {
4312 /* ==== rgb 565 bmp -> rgb 0888 dib ==== */
4313 X11DRV_DIB_Convert_565_to_0888_asis
4315 srcbits
,-bmpImage
->bytes_per_line
,
4317 } else if (bmpImage
->blue_mask
==0xf800) {
4318 /* ==== bgr 565 bmp -> rgb 0888 dib ==== */
4319 X11DRV_DIB_Convert_565_to_0888_reverse
4321 srcbits
,-bmpImage
->bytes_per_line
,
4329 } else if (rDst
==0x0000ff && gDst
==0x00ff00 && bDst
==0xff0000) {
4330 if (bmpImage
->green_mask
==0x03e0) {
4331 if (bmpImage
->blue_mask
==0x7f00) {
4332 /* ==== bgr 555 bmp -> bgr 0888 dib ==== */
4333 X11DRV_DIB_Convert_555_to_0888_asis
4335 srcbits
,-bmpImage
->bytes_per_line
,
4337 } else if (bmpImage
->red_mask
==0x7f00) {
4338 /* ==== rgb 555 bmp -> bgr 0888 dib ==== */
4339 X11DRV_DIB_Convert_555_to_0888_reverse
4341 srcbits
,-bmpImage
->bytes_per_line
,
4346 } else if (bmpImage
->green_mask
==0x07e0) {
4347 if (bmpImage
->blue_mask
==0xf800) {
4348 /* ==== bgr 565 bmp -> bgr 0888 dib ==== */
4349 X11DRV_DIB_Convert_565_to_0888_asis
4351 srcbits
,-bmpImage
->bytes_per_line
,
4353 } else if (bmpImage
->red_mask
==0xf800) {
4354 /* ==== rgb 565 bmp -> bgr 0888 dib ==== */
4355 X11DRV_DIB_Convert_565_to_0888_reverse
4357 srcbits
,-bmpImage
->bytes_per_line
,
4366 if (bmpImage
->green_mask
==0x03e0 &&
4367 (bmpImage
->red_mask
==0x7f00 ||
4368 bmpImage
->blue_mask
==0x7f00)) {
4369 /* ==== rgb or bgr 555 bmp -> any 0888 dib ==== */
4370 X11DRV_DIB_Convert_5x5_to_any0888
4372 srcbits
,-bmpImage
->bytes_per_line
,
4373 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
4376 } else if (bmpImage
->green_mask
==0x07e0 &&
4377 (bmpImage
->red_mask
==0xf800 ||
4378 bmpImage
->blue_mask
==0xf800)) {
4379 /* ==== rgb or bgr 565 bmp -> any 0888 dib ==== */
4380 X11DRV_DIB_Convert_5x5_to_any0888
4382 srcbits
,-bmpImage
->bytes_per_line
,
4383 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
,
4395 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
4396 /* ==== pal 1 or 4 bmp -> any 0888 dib ==== */
4397 int rShift
,gShift
,bShift
;
4400 rShift
=X11DRV_DIB_MaskToShift(rDst
);
4401 gShift
=X11DRV_DIB_MaskToShift(gDst
);
4402 bShift
=X11DRV_DIB_MaskToShift(bDst
);
4403 for (h
= lines
- 1; h
>= 0; h
--) {
4404 dstpixel
=(DWORD
*)dstbits
;
4405 for (x
= 0; x
< dstwidth
; x
++) {
4406 PALETTEENTRY srcval
;
4407 srcval
= srccolors
[XGetPixel(bmpImage
, x
, h
)];
4408 *dstpixel
++=(srcval
.peRed
<< rShift
) |
4409 (srcval
.peGreen
<< gShift
) |
4410 (srcval
.peBlue
<< bShift
);
4412 dstbits
+= linebytes
;
4420 if (bmpImage
->red_mask
==0 && bmpImage
->green_mask
==0 && bmpImage
->blue_mask
==0 && srccolors
) {
4421 /* ==== pal 8 bmp -> any 0888 dib ==== */
4422 int rShift
,gShift
,bShift
;
4423 const void* srcbits
;
4424 const BYTE
* srcpixel
;
4427 rShift
=X11DRV_DIB_MaskToShift(rDst
);
4428 gShift
=X11DRV_DIB_MaskToShift(gDst
);
4429 bShift
=X11DRV_DIB_MaskToShift(bDst
);
4430 srcbits
=bmpImage
->data
+(lines
-1)*bmpImage
->bytes_per_line
;
4431 for (h
= lines
- 1; h
>= 0; h
--) {
4433 dstpixel
=(DWORD
*)dstbits
;
4434 for (x
= 0; x
< dstwidth
; x
++) {
4435 PALETTEENTRY srcval
;
4436 srcval
=srccolors
[(int)*srcpixel
++];
4437 *dstpixel
++=(srcval
.peRed
<< rShift
) |
4438 (srcval
.peGreen
<< gShift
) |
4439 (srcval
.peBlue
<< bShift
);
4441 srcbits
= (char*)srcbits
- bmpImage
->bytes_per_line
;
4442 dstbits
+= linebytes
;
4452 /* ==== any bmp format -> any 0888 dib ==== */
4453 int rShift
,gShift
,bShift
;
4456 WARN("from unknown %d bit bitmap (%lx,%lx,%lx) to 32 bit DIB (%lx,%lx,%lx)\n",
4457 bmpImage
->depth
, bmpImage
->red_mask
,
4458 bmpImage
->green_mask
, bmpImage
->blue_mask
,
4461 rShift
=X11DRV_DIB_MaskToShift(rDst
);
4462 gShift
=X11DRV_DIB_MaskToShift(gDst
);
4463 bShift
=X11DRV_DIB_MaskToShift(bDst
);
4464 for (h
= lines
- 1; h
>= 0; h
--) {
4465 dstpixel
=(DWORD
*)dstbits
;
4466 for (x
= 0; x
< dstwidth
; x
++) {
4468 srcval
=X11DRV_PALETTE_ToLogical(XGetPixel(bmpImage
, x
, h
));
4469 *dstpixel
++=(GetRValue(srcval
) << rShift
) |
4470 (GetGValue(srcval
) << gShift
) |
4471 (GetBValue(srcval
) << bShift
);
4473 dstbits
+= linebytes
;
4480 /***********************************************************************
4481 * X11DRV_DIB_SetImageBits
4483 * Transfer the bits to an X image.
4484 * Helper function for SetDIBits() and SetDIBitsToDevice().
4486 static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
4488 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
4493 bmpImage
= descr
->image
;
4495 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
4496 descr
->infoWidth
, lines
, 32, 0 );
4497 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
4498 if(bmpImage
->data
== NULL
) {
4499 ERR("Out of memory!\n");
4500 XDestroyImage( bmpImage
);
4501 wine_tsx11_unlock();
4506 TRACE("Dib: depth=%d r=%lx g=%lx b=%lx\n",
4507 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
4508 TRACE("Bmp: depth=%d/%d r=%lx g=%lx b=%lx\n",
4509 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
4510 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4512 /* Transfer the pixels */
4513 switch(descr
->infoBpp
)
4516 X11DRV_DIB_SetImageBits_1( descr
->lines
, descr
->bits
, descr
->infoWidth
,
4517 descr
->width
, descr
->xSrc
, (int *)(descr
->colorMap
),
4518 bmpImage
, descr
->dibpitch
);
4521 if (descr
->compression
) {
4522 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
4523 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
4524 bmpImage
, descr
->xSrc
, descr
->ySrc
);
4526 X11DRV_DIB_SetImageBits_RLE4( descr
->lines
, descr
->bits
,
4527 descr
->infoWidth
, descr
->width
,
4528 descr
->xSrc
, (int *)(descr
->colorMap
),
4531 X11DRV_DIB_SetImageBits_4( descr
->lines
, descr
->bits
,
4532 descr
->infoWidth
, descr
->width
,
4533 descr
->xSrc
, (int*)(descr
->colorMap
),
4534 bmpImage
, descr
->dibpitch
);
4537 if (descr
->compression
) {
4538 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xDest
, descr
->yDest
,
4539 descr
->width
, descr
->height
, AllPlanes
, ZPixmap
,
4540 bmpImage
, descr
->xSrc
, descr
->ySrc
);
4541 X11DRV_DIB_SetImageBits_RLE8( descr
->lines
, descr
->bits
,
4542 descr
->infoWidth
, descr
->width
,
4543 descr
->xSrc
, (int *)(descr
->colorMap
),
4546 X11DRV_DIB_SetImageBits_8( descr
->lines
, descr
->bits
,
4547 descr
->infoWidth
, descr
->width
,
4548 descr
->xSrc
, (int *)(descr
->colorMap
),
4549 bmpImage
, descr
->dibpitch
);
4553 X11DRV_DIB_SetImageBits_16( descr
->lines
, descr
->bits
,
4554 descr
->infoWidth
, descr
->width
,
4555 descr
->xSrc
, descr
->physDev
,
4556 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4557 bmpImage
, descr
->dibpitch
);
4560 X11DRV_DIB_SetImageBits_24( descr
->lines
, descr
->bits
,
4561 descr
->infoWidth
, descr
->width
,
4562 descr
->xSrc
, descr
->physDev
,
4563 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4564 bmpImage
, descr
->dibpitch
);
4567 X11DRV_DIB_SetImageBits_32( descr
->lines
, descr
->bits
,
4568 descr
->infoWidth
, descr
->width
,
4569 descr
->xSrc
, descr
->physDev
,
4570 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4571 bmpImage
, descr
->dibpitch
);
4574 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
4578 TRACE("XPutImage(%ld,%p,%p,%d,%d,%d,%d,%d,%d)\n",
4579 descr
->drawable
, descr
->gc
, bmpImage
,
4580 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
4581 descr
->width
, descr
->height
);
4582 #ifdef HAVE_LIBXXSHM
4585 XShmPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
4586 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
4587 descr
->width
, descr
->height
, FALSE
);
4588 XSync( gdi_display
, 0 );
4592 XPutImage( gdi_display
, descr
->drawable
, descr
->gc
, bmpImage
,
4593 descr
->xSrc
, descr
->ySrc
, descr
->xDest
, descr
->yDest
,
4594 descr
->width
, descr
->height
);
4596 if (!descr
->image
) XDestroyImage( bmpImage
);
4597 wine_tsx11_unlock();
4601 /***********************************************************************
4602 * X11DRV_DIB_GetImageBits
4604 * Transfer the bits from an X image.
4606 static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR
*descr
)
4608 int lines
= descr
->lines
>= 0 ? descr
->lines
: -descr
->lines
;
4613 bmpImage
= descr
->image
;
4615 bmpImage
= XCreateImage( gdi_display
, visual
, descr
->depth
, ZPixmap
, 0, NULL
,
4616 descr
->infoWidth
, lines
, 32, 0 );
4617 bmpImage
->data
= calloc( lines
, bmpImage
->bytes_per_line
);
4618 if(bmpImage
->data
== NULL
) {
4619 ERR("Out of memory!\n");
4620 XDestroyImage( bmpImage
);
4621 wine_tsx11_unlock();
4628 int saveRed
, saveGreen
, saveBlue
;
4630 TRACE("XShmGetImage(%p, %ld, %p, %d, %d, %ld)\n",
4631 gdi_display
, descr
->drawable
, bmpImage
,
4632 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
4634 /* We must save and restore the bmpImage's masks in order
4635 * to preserve them across the call to XShmGetImage, which
4636 * decides to eleminate them since it doesn't happen to know
4637 * what the format of the image is supposed to be, even though
4639 saveRed
= bmpImage
->red_mask
;
4640 saveBlue
= bmpImage
->blue_mask
;
4641 saveGreen
= bmpImage
->green_mask
;
4643 XShmGetImage( gdi_display
, descr
->drawable
, bmpImage
,
4644 descr
->xSrc
, descr
->ySrc
, AllPlanes
);
4646 bmpImage
->red_mask
= saveRed
;
4647 bmpImage
->blue_mask
= saveBlue
;
4648 bmpImage
->green_mask
= saveGreen
;
4652 TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
4653 gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
, descr
->width
,
4654 lines
, AllPlanes
, ZPixmap
, bmpImage
, descr
->xDest
, descr
->yDest
);
4655 XGetSubImage( gdi_display
, descr
->drawable
, descr
->xSrc
, descr
->ySrc
,
4656 descr
->width
, lines
, AllPlanes
, ZPixmap
,
4657 bmpImage
, descr
->xDest
, descr
->yDest
);
4660 TRACE("Dib: depth=%2d r=%lx g=%lx b=%lx\n",
4661 descr
->infoBpp
,descr
->rMask
,descr
->gMask
,descr
->bMask
);
4662 TRACE("Bmp: depth=%2d/%2d r=%lx g=%lx b=%lx\n",
4663 bmpImage
->depth
,bmpImage
->bits_per_pixel
,
4664 bmpImage
->red_mask
,bmpImage
->green_mask
,bmpImage
->blue_mask
);
4665 /* Transfer the pixels */
4666 switch(descr
->infoBpp
)
4669 X11DRV_DIB_GetImageBits_1( descr
->lines
,(LPVOID
)descr
->bits
,
4670 descr
->infoWidth
, descr
->width
,
4671 descr
->colorMap
, descr
->palentry
,
4672 bmpImage
, descr
->dibpitch
);
4676 if (descr
->compression
)
4677 FIXME("Compression not yet supported!\n");
4679 X11DRV_DIB_GetImageBits_4( descr
->lines
,(LPVOID
)descr
->bits
,
4680 descr
->infoWidth
, descr
->width
,
4681 descr
->colorMap
, descr
->palentry
,
4682 bmpImage
, descr
->dibpitch
);
4686 if (descr
->compression
)
4687 FIXME("Compression not yet supported!\n");
4689 X11DRV_DIB_GetImageBits_8( descr
->lines
, (LPVOID
)descr
->bits
,
4690 descr
->infoWidth
, descr
->width
,
4691 descr
->colorMap
, descr
->palentry
,
4692 bmpImage
, descr
->dibpitch
);
4696 X11DRV_DIB_GetImageBits_16( descr
->lines
, (LPVOID
)descr
->bits
,
4697 descr
->infoWidth
,descr
->width
,
4699 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4700 bmpImage
, descr
->dibpitch
);
4704 X11DRV_DIB_GetImageBits_24( descr
->lines
, (LPVOID
)descr
->bits
,
4705 descr
->infoWidth
,descr
->width
,
4707 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4708 bmpImage
, descr
->dibpitch
);
4712 X11DRV_DIB_GetImageBits_32( descr
->lines
, (LPVOID
)descr
->bits
,
4713 descr
->infoWidth
, descr
->width
,
4715 descr
->rMask
, descr
->gMask
, descr
->bMask
,
4716 bmpImage
, descr
->dibpitch
);
4720 WARN("(%d): Invalid depth\n", descr
->infoBpp
);
4724 if (!descr
->image
) XDestroyImage( bmpImage
);
4725 wine_tsx11_unlock();
4729 /*************************************************************************
4730 * X11DRV_SetDIBitsToDevice
4733 INT
X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE
*physDev
, INT xDest
, INT yDest
, DWORD cx
,
4734 DWORD cy
, INT xSrc
, INT ySrc
,
4735 UINT startscan
, UINT lines
, LPCVOID bits
,
4736 const BITMAPINFO
*info
, UINT coloruse
)
4738 X11DRV_DIB_IMAGEBITS_DESCR descr
;
4744 DC
*dc
= physDev
->dc
;
4746 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &width
, &height
,
4747 &descr
.infoBpp
, &descr
.compression
) == -1)
4749 top_down
= (height
< 0);
4750 if (top_down
) height
= -height
;
4754 LPtoDP(physDev
->hdc
, &pt
, 1);
4756 if (!lines
|| (startscan
>= height
)) return 0;
4757 if (!top_down
&& startscan
+ lines
> height
) lines
= height
- startscan
;
4759 /* make xSrc,ySrc point to the upper-left corner, not the lower-left one,
4760 * and clamp all values to fit inside [startscan,startscan+lines]
4762 if (ySrc
+ cy
<= startscan
+ lines
)
4764 INT y
= startscan
+ lines
- (ySrc
+ cy
);
4765 if (ySrc
< startscan
) cy
-= (startscan
- ySrc
);
4768 /* avoid getting unnecessary lines */
4770 if (y
>= lines
) return 0;
4775 if (y
>= lines
) return lines
;
4776 ySrc
= y
; /* need to get all lines in top down mode */
4781 if (ySrc
>= startscan
+ lines
) return lines
;
4782 pt
.y
+= ySrc
+ cy
- (startscan
+ lines
);
4783 cy
= startscan
+ lines
- ySrc
;
4785 if (cy
> lines
) cy
= lines
;
4787 if (xSrc
>= width
) return lines
;
4788 if (xSrc
+ cx
>= width
) cx
= width
- xSrc
;
4789 if (!cx
|| !cy
) return lines
;
4791 X11DRV_SetupGCForText( physDev
); /* To have the correct colors */
4792 TSXSetFunction(gdi_display
, physDev
->gc
, X11DRV_XROPfunction
[dc
->ROPmode
-1]);
4794 switch (descr
.infoBpp
)
4799 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
4800 coloruse
== DIB_PAL_COLORS
? physDev
: NULL
, coloruse
,
4801 dc
->bitsPerPixel
, info
, &descr
.nColorMap
);
4802 if (!descr
.colorMap
) return 0;
4803 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
4807 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
4808 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
4809 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
4815 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
4816 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
4817 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
4822 descr
.physDev
= physDev
;
4825 descr
.palentry
= NULL
;
4826 descr
.lines
= top_down
? -lines
: lines
;
4827 descr
.infoWidth
= width
;
4828 descr
.depth
= dc
->bitsPerPixel
;
4829 descr
.drawable
= physDev
->drawable
;
4830 descr
.gc
= physDev
->gc
;
4833 descr
.xDest
= physDev
->org
.x
+ pt
.x
;
4834 descr
.yDest
= physDev
->org
.y
+ pt
.y
;
4837 descr
.useShm
= FALSE
;
4838 descr
.dibpitch
= ((width
* descr
.infoBpp
+ 31) &~31) / 8;
4840 result
= X11DRV_DIB_SetImageBits( &descr
);
4842 if (descr
.infoBpp
<= 8)
4843 HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
4847 /***********************************************************************
4848 * SetDIBits (X11DRV.@)
4850 INT
X11DRV_SetDIBits( X11DRV_PDEVICE
*physDev
, HBITMAP hbitmap
, UINT startscan
,
4851 UINT lines
, LPCVOID bits
, const BITMAPINFO
*info
, UINT coloruse
)
4853 X11DRV_DIB_IMAGEBITS_DESCR descr
;
4855 int height
, tmpheight
;
4858 descr
.physDev
= physDev
;
4860 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &height
,
4861 &descr
.infoBpp
, &descr
.compression
) == -1)
4865 if (height
< 0) height
= -height
;
4866 if (!lines
|| (startscan
>= height
))
4869 if (!(bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
))) return 0;
4871 if (startscan
+ lines
> height
) lines
= height
- startscan
;
4873 switch (descr
.infoBpp
)
4878 descr
.colorMap
= (RGBQUAD
*)X11DRV_DIB_BuildColorMap(
4879 coloruse
== DIB_PAL_COLORS
? descr
.physDev
: NULL
, coloruse
,
4880 bmp
->bitmap
.bmBitsPixel
,
4881 info
, &descr
.nColorMap
);
4882 if (!descr
.colorMap
)
4884 GDI_ReleaseObj( hbitmap
);
4887 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
4891 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
4892 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
4893 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
4899 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
4900 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
4901 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
4910 descr
.palentry
= NULL
;
4911 descr
.lines
= tmpheight
>= 0 ? lines
: -lines
;
4912 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
4913 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
4914 descr
.gc
= BITMAP_GC(bmp
);
4918 descr
.yDest
= height
- startscan
- lines
;
4919 descr
.width
= bmp
->bitmap
.bmWidth
;
4920 descr
.height
= lines
;
4921 descr
.useShm
= FALSE
;
4922 descr
.dibpitch
= ((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8;
4923 X11DRV_DIB_Lock(bmp
, DIB_Status_GdiMod
, FALSE
);
4924 result
= X11DRV_DIB_SetImageBits( &descr
);
4925 X11DRV_DIB_Unlock(bmp
, TRUE
);
4927 if (descr
.colorMap
) HeapFree(GetProcessHeap(), 0, descr
.colorMap
);
4929 GDI_ReleaseObj( hbitmap
);
4933 /***********************************************************************
4934 * GetDIBits (X11DRV.@)
4936 INT
X11DRV_GetDIBits( X11DRV_PDEVICE
*physDev
, HBITMAP hbitmap
, UINT startscan
, UINT lines
,
4937 LPVOID bits
, BITMAPINFO
*info
, UINT coloruse
)
4939 X11DRV_DIBSECTION
*dib
;
4940 X11DRV_DIB_IMAGEBITS_DESCR descr
;
4941 PALETTEOBJ
* palette
;
4944 DC
*dc
= physDev
->dc
;
4946 if (!(palette
= (PALETTEOBJ
*)GDI_GetObjPtr( dc
->hPalette
, PALETTE_MAGIC
)))
4948 if (!(bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
)))
4950 GDI_ReleaseObj( dc
->hPalette
);
4953 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
4955 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
4956 lines
, bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
,
4957 (int)info
->bmiHeader
.biWidth
, (int)info
->bmiHeader
.biHeight
,
4960 if( lines
> bmp
->bitmap
.bmHeight
) lines
= bmp
->bitmap
.bmHeight
;
4962 height
= info
->bmiHeader
.biHeight
;
4963 if (height
< 0) height
= -height
;
4964 if( lines
> height
) lines
= height
;
4965 /* Top-down images have a negative biHeight, the scanlines of theses images
4966 * were inverted in X11DRV_DIB_GetImageBits_xx
4967 * To prevent this we simply change the sign of lines
4968 * (the number of scan lines to copy).
4969 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
4971 if( info
->bmiHeader
.biHeight
< 0 && lines
> 0) lines
= -lines
;
4973 if( startscan
>= bmp
->bitmap
.bmHeight
)
4979 if (DIB_GetBitmapInfo( &info
->bmiHeader
, &descr
.infoWidth
, &descr
.lines
,
4980 &descr
.infoBpp
, &descr
.compression
) == -1)
4986 switch (descr
.infoBpp
)
4991 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
4995 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0x7c00;
4996 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x03e0;
4997 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x001f;
5001 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? *(DWORD
*)info
->bmiColors
: 0xff0000;
5002 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 1) : 0x00ff00;
5003 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? *((DWORD
*)info
->bmiColors
+ 2) : 0x0000ff;
5007 descr
.physDev
= physDev
;
5008 descr
.palentry
= palette
->logpalette
.palPalEntry
;
5011 descr
.lines
= lines
;
5012 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
5013 descr
.drawable
= (Pixmap
)bmp
->physBitmap
;
5014 descr
.gc
= BITMAP_GC(bmp
);
5015 descr
.width
= bmp
->bitmap
.bmWidth
;
5016 descr
.height
= bmp
->bitmap
.bmHeight
;
5017 descr
.colorMap
= info
->bmiColors
;
5022 if (descr
.lines
> 0)
5024 descr
.ySrc
= (descr
.height
-1) - (startscan
+ (lines
-1));
5028 descr
.ySrc
= startscan
;
5030 #ifdef HAVE_LIBXXSHM
5031 descr
.useShm
= dib
? (dib
->shminfo
.shmid
!= -1) : FALSE
;
5033 descr
.useShm
= FALSE
;
5035 descr
.dibpitch
= dib
? (dib
->dibSection
.dsBm
.bmWidthBytes
)
5036 : (((descr
.infoWidth
* descr
.infoBpp
+ 31) &~31) / 8);
5038 X11DRV_DIB_Lock(bmp
, DIB_Status_GdiMod
, FALSE
);
5039 X11DRV_DIB_GetImageBits( &descr
);
5040 X11DRV_DIB_Unlock(bmp
, TRUE
);
5042 if(info
->bmiHeader
.biSizeImage
== 0) /* Fill in biSizeImage */
5043 info
->bmiHeader
.biSizeImage
= DIB_GetDIBImageBytes(
5044 info
->bmiHeader
.biWidth
,
5045 info
->bmiHeader
.biHeight
,
5046 info
->bmiHeader
.biBitCount
);
5048 if (descr
.compression
== BI_BITFIELDS
)
5050 *(DWORD
*)info
->bmiColors
= descr
.rMask
;
5051 *((DWORD
*)info
->bmiColors
+1) = descr
.gMask
;
5052 *((DWORD
*)info
->bmiColors
+2) = descr
.bMask
;
5056 /* if RLE or JPEG compression were supported,
5057 * this line would be invalid. */
5058 info
->bmiHeader
.biCompression
= 0;
5062 GDI_ReleaseObj( dc
->hPalette
);
5063 GDI_ReleaseObj( hbitmap
);
5067 /***********************************************************************
5068 * DIB_DoProtectDIBSection
5070 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ
*bmp
, DWORD new_prot
)
5072 DIBSECTION
*dib
= bmp
->dib
;
5073 INT effHeight
= dib
->dsBm
.bmHeight
>= 0? dib
->dsBm
.bmHeight
5074 : -dib
->dsBm
.bmHeight
;
5075 /* use the biSizeImage data as the memory size only if we're dealing with a
5076 compressed image where the value is set. Otherwise, calculate based on
5078 INT totalSize
= dib
->dsBmih
.biSizeImage
&& dib
->dsBmih
.biCompression
!= BI_RGB
5079 ? dib
->dsBmih
.biSizeImage
5080 : dib
->dsBm
.bmWidthBytes
* effHeight
;
5083 VirtualProtect(dib
->dsBm
.bmBits
, totalSize
, new_prot
, &old_prot
);
5084 TRACE("Changed protection from %ld to %ld\n", old_prot
, new_prot
);
5087 /***********************************************************************
5088 * X11DRV_DIB_DoUpdateDIBSection
5090 static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
,
5091 void *colorMap
, int nColorMap
,
5093 DWORD xSrc
, DWORD ySrc
,
5094 DWORD xDest
, DWORD yDest
,
5095 DWORD width
, DWORD height
)
5097 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5098 X11DRV_DIB_IMAGEBITS_DESCR descr
;
5100 if (DIB_GetBitmapInfo( &dib
->dibSection
.dsBmih
, &descr
.infoWidth
, &descr
.lines
,
5101 &descr
.infoBpp
, &descr
.compression
) == -1)
5104 descr
.physDev
= NULL
;
5105 descr
.palentry
= NULL
;
5106 descr
.image
= dib
->image
;
5107 descr
.colorMap
= colorMap
;
5108 descr
.nColorMap
= nColorMap
;
5109 descr
.bits
= dib
->dibSection
.dsBm
.bmBits
;
5110 descr
.depth
= bmp
->bitmap
.bmBitsPixel
;
5112 switch (descr
.infoBpp
)
5117 descr
.rMask
= descr
.gMask
= descr
.bMask
= 0;
5121 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0x7c00;
5122 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x03e0;
5123 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x001f;
5128 descr
.rMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[0] : 0xff0000;
5129 descr
.gMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[1] : 0x00ff00;
5130 descr
.bMask
= (descr
.compression
== BI_BITFIELDS
) ? dib
->dibSection
.dsBitfields
[2] : 0x0000ff;
5135 descr
.drawable
= dest
;
5136 descr
.gc
= BITMAP_GC(bmp
);
5139 descr
.xDest
= xDest
;
5140 descr
.yDest
= yDest
;
5141 descr
.width
= width
;
5142 descr
.height
= height
;
5143 #ifdef HAVE_LIBXXSHM
5144 descr
.useShm
= (dib
->shminfo
.shmid
!= -1);
5146 descr
.useShm
= FALSE
;
5148 descr
.dibpitch
= dib
->dibSection
.dsBm
.bmWidthBytes
;
5152 TRACE("Copying from Pixmap to DIB bits\n");
5153 X11DRV_DIB_GetImageBits( &descr
);
5157 TRACE("Copying from DIB bits to Pixmap\n");
5158 X11DRV_DIB_SetImageBits( &descr
);
5162 /***********************************************************************
5163 * X11DRV_DIB_CopyDIBSection
5165 void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE
*physDevSrc
, X11DRV_PDEVICE
*physDevDst
,
5166 DWORD xSrc
, DWORD ySrc
, DWORD xDest
, DWORD yDest
,
5167 DWORD width
, DWORD height
)
5170 DC
*dcSrc
= physDevSrc
->dc
;
5171 DC
*dcDst
= physDevDst
->dc
;
5172 int nColorMap
= 0, *colorMap
= NULL
, aColorMap
= FALSE
;
5174 TRACE("(%p,%p,%ld,%ld,%ld,%ld,%ld,%ld)\n", dcSrc
, dcDst
,
5175 xSrc
, ySrc
, xDest
, yDest
, width
, height
);
5176 /* this function is meant as an optimization for BitBlt,
5177 * not to be called otherwise */
5178 if (!(dcSrc
->flags
& DC_MEMORY
)) {
5179 ERR("called for non-memory source DC!?\n");
5183 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( dcSrc
->hBitmap
, BITMAP_MAGIC
);
5184 if (!(bmp
&& bmp
->dib
)) {
5185 ERR("called for non-DIBSection!?\n");
5186 GDI_ReleaseObj( dcSrc
->hBitmap
);
5189 /* while BitBlt should already have made sure we only get
5190 * positive values, we should check for oversize values */
5191 if ((xSrc
< bmp
->bitmap
.bmWidth
) &&
5192 (ySrc
< bmp
->bitmap
.bmHeight
)) {
5193 if (xSrc
+ width
> bmp
->bitmap
.bmWidth
)
5194 width
= bmp
->bitmap
.bmWidth
- xSrc
;
5195 if (ySrc
+ height
> bmp
->bitmap
.bmHeight
)
5196 height
= bmp
->bitmap
.bmHeight
- ySrc
;
5197 /* if the source bitmap is 8bpp or less, we're supposed to use the
5198 * DC's palette for color conversion (not the DIB color table) */
5199 if (bmp
->dib
->dsBm
.bmBitsPixel
<= 8) {
5200 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5201 if ((!dcSrc
->hPalette
) ||
5202 (dcSrc
->hPalette
== GetStockObject(DEFAULT_PALETTE
))) {
5203 /* HACK: no palette has been set in the source DC,
5204 * use the DIB colormap instead - this is necessary in some
5205 * cases since we need to do depth conversion in some places
5206 * where real Windows can just copy data straight over */
5207 colorMap
= dib
->colorMap
;
5208 nColorMap
= dib
->nColorMap
;
5210 colorMap
= X11DRV_DIB_BuildColorMap( physDevSrc
, (WORD
)-1,
5211 bmp
->dib
->dsBm
.bmBitsPixel
,
5212 (BITMAPINFO
*)&(bmp
->dib
->dsBmih
),
5214 if (colorMap
) aColorMap
= TRUE
;
5217 /* perform the copy */
5218 X11DRV_DIB_DoCopyDIBSection(bmp
, FALSE
, colorMap
, nColorMap
,
5219 physDevDst
->drawable
, xSrc
, ySrc
,
5220 physDevDst
->org
.x
+ xDest
, physDevDst
->org
.y
+ yDest
,
5222 /* free color mapping */
5224 HeapFree(GetProcessHeap(), 0, colorMap
);
5226 GDI_ReleaseObj( dcSrc
->hBitmap
);
5229 /***********************************************************************
5230 * X11DRV_DIB_DoUpdateDIBSection
5232 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ
*bmp
, BOOL toDIB
)
5234 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5235 X11DRV_DIB_DoCopyDIBSection(bmp
, toDIB
, dib
->colorMap
, dib
->nColorMap
,
5236 (Drawable
)bmp
->physBitmap
, 0, 0, 0, 0,
5237 bmp
->bitmap
.bmWidth
, bmp
->bitmap
.bmHeight
);
5240 /***********************************************************************
5241 * X11DRV_DIB_FaultHandler
5243 static BOOL
X11DRV_DIB_FaultHandler( LPVOID res
, LPCVOID addr
)
5248 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( (HBITMAP
)res
, BITMAP_MAGIC
);
5249 if (!bmp
) return FALSE
;
5251 state
= X11DRV_DIB_Lock(bmp
, DIB_Status_None
, FALSE
);
5252 if (state
!= DIB_Status_InSync
) {
5253 /* no way to tell whether app needs read or write yet,
5255 X11DRV_DIB_Coerce(bmp
, DIB_Status_InSync
, FALSE
);
5257 /* hm, apparently the app must have write access */
5258 X11DRV_DIB_Coerce(bmp
, DIB_Status_AppMod
, FALSE
);
5260 X11DRV_DIB_Unlock(bmp
, TRUE
);
5262 GDI_ReleaseObj( (HBITMAP
)res
);
5266 /***********************************************************************
5269 INT
X11DRV_DIB_Coerce(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
5271 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5272 INT ret
= DIB_Status_None
;
5275 EnterCriticalSection(&(dib
->lock
));
5278 case DIB_Status_GdiMod
:
5279 /* GDI access - request to draw on pixmap */
5280 switch (dib
->status
)
5283 case DIB_Status_None
:
5284 dib
->p_status
= DIB_Status_GdiMod
;
5285 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
5288 case DIB_Status_GdiMod
:
5289 TRACE("GdiMod requested in status GdiMod\n" );
5292 case DIB_Status_InSync
:
5293 TRACE("GdiMod requested in status InSync\n" );
5294 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
5295 dib
->status
= DIB_Status_GdiMod
;
5296 dib
->p_status
= DIB_Status_InSync
;
5299 case DIB_Status_AuxMod
:
5300 TRACE("GdiMod requested in status AuxMod\n" );
5301 if (lossy
) dib
->status
= DIB_Status_GdiMod
;
5302 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_GdiMod
);
5303 dib
->p_status
= DIB_Status_AuxMod
;
5304 if (dib
->status
!= DIB_Status_AppMod
) {
5305 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
5308 /* fall through if copy_aux() had to change to AppMod state */
5310 case DIB_Status_AppMod
:
5311 TRACE("GdiMod requested in status AppMod\n" );
5313 /* make it readonly to avoid app changing data while we copy */
5314 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5315 X11DRV_DIB_DoUpdateDIBSection( bmp
, FALSE
);
5317 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
5318 dib
->p_status
= DIB_Status_AppMod
;
5319 dib
->status
= DIB_Status_GdiMod
;
5324 case DIB_Status_InSync
:
5325 /* App access - request access to read DIB surface */
5326 /* (typically called from signal handler) */
5327 switch (dib
->status
)
5330 case DIB_Status_None
:
5331 /* shouldn't happen from signal handler */
5334 case DIB_Status_AuxMod
:
5335 TRACE("InSync requested in status AuxMod\n" );
5336 if (lossy
) dib
->status
= DIB_Status_InSync
;
5338 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5339 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_InSync
);
5341 if (dib
->status
!= DIB_Status_GdiMod
) {
5342 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5345 /* fall through if copy_aux() had to change to GdiMod state */
5347 case DIB_Status_GdiMod
:
5348 TRACE("InSync requested in status GdiMod\n" );
5350 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5351 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
5353 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5354 dib
->status
= DIB_Status_InSync
;
5357 case DIB_Status_InSync
:
5358 TRACE("InSync requested in status InSync\n" );
5359 /* shouldn't happen from signal handler */
5362 case DIB_Status_AppMod
:
5363 TRACE("InSync requested in status AppMod\n" );
5364 /* no reason to do anything here, and this
5365 * shouldn't happen from signal handler */
5370 case DIB_Status_AppMod
:
5371 /* App access - request access to write DIB surface */
5372 /* (typically called from signal handler) */
5373 switch (dib
->status
)
5376 case DIB_Status_None
:
5377 /* shouldn't happen from signal handler */
5380 case DIB_Status_AuxMod
:
5381 TRACE("AppMod requested in status AuxMod\n" );
5382 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5383 if (lossy
) dib
->status
= DIB_Status_AppMod
;
5384 else (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
5385 if (dib
->status
!= DIB_Status_GdiMod
)
5387 /* fall through if copy_aux() had to change to GdiMod state */
5389 case DIB_Status_GdiMod
:
5390 TRACE("AppMod requested in status GdiMod\n" );
5391 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5392 if (!lossy
) X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
5393 dib
->status
= DIB_Status_AppMod
;
5396 case DIB_Status_InSync
:
5397 TRACE("AppMod requested in status InSync\n" );
5398 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5399 dib
->status
= DIB_Status_AppMod
;
5402 case DIB_Status_AppMod
:
5403 TRACE("AppMod requested in status AppMod\n" );
5404 /* shouldn't happen from signal handler */
5409 case DIB_Status_AuxMod
:
5410 if (dib
->status
== DIB_Status_None
) {
5411 dib
->p_status
= req
;
5413 if (dib
->status
!= DIB_Status_AuxMod
)
5414 dib
->p_status
= dib
->status
;
5415 dib
->status
= DIB_Status_AuxMod
;
5418 /* it is up to the caller to do the copy/conversion, probably
5419 * using the return value to decide where to copy from */
5421 LeaveCriticalSection(&(dib
->lock
));
5426 /***********************************************************************
5429 INT
X11DRV_DIB_Lock(BITMAPOBJ
*bmp
, INT req
, BOOL lossy
)
5431 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5432 INT ret
= DIB_Status_None
;
5435 TRACE("Locking %p from thread %08lx\n", bmp
, GetCurrentThreadId());
5436 EnterCriticalSection(&(dib
->lock
));
5438 if (req
!= DIB_Status_None
)
5439 X11DRV_DIB_Coerce(bmp
, req
, lossy
);
5444 /***********************************************************************
5447 void X11DRV_DIB_Unlock(BITMAPOBJ
*bmp
, BOOL commit
)
5449 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5452 switch (dib
->status
)
5455 case DIB_Status_None
:
5456 /* in case anyone is wondering, this is the "signal handler doesn't
5457 * work" case, where we always have to be ready for app access */
5459 switch (dib
->p_status
)
5461 case DIB_Status_AuxMod
:
5462 TRACE("Unlocking and syncing from AuxMod\n" );
5463 (*dib
->copy_aux
)(dib
->aux_ctx
, DIB_Status_AppMod
);
5464 if (dib
->status
!= DIB_Status_None
) {
5465 dib
->p_status
= dib
->status
;
5466 dib
->status
= DIB_Status_None
;
5468 if (dib
->p_status
!= DIB_Status_GdiMod
)
5470 /* fall through if copy_aux() had to change to GdiMod state */
5472 case DIB_Status_GdiMod
:
5473 TRACE("Unlocking and syncing from GdiMod\n" );
5474 X11DRV_DIB_DoUpdateDIBSection( bmp
, TRUE
);
5478 TRACE("Unlocking without needing to sync\n" );
5482 else TRACE("Unlocking with no changes\n");
5483 dib
->p_status
= DIB_Status_None
;
5486 case DIB_Status_GdiMod
:
5487 TRACE("Unlocking in status GdiMod\n" );
5488 /* DIB was protected in Coerce */
5490 /* no commit, revert to InSync if applicable */
5491 if ((dib
->p_status
== DIB_Status_InSync
) ||
5492 (dib
->p_status
== DIB_Status_AppMod
)) {
5493 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READONLY
);
5494 dib
->status
= DIB_Status_InSync
;
5499 case DIB_Status_InSync
:
5500 TRACE("Unlocking in status InSync\n" );
5501 /* DIB was already protected in Coerce */
5504 case DIB_Status_AppMod
:
5505 TRACE("Unlocking in status AppMod\n" );
5506 /* DIB was already protected in Coerce */
5507 /* this case is ordinary only called from the signal handler,
5508 * so we don't bother to check for !commit */
5511 case DIB_Status_AuxMod
:
5512 TRACE("Unlocking in status AuxMod\n" );
5514 /* DIB may need protection now */
5515 if ((dib
->p_status
== DIB_Status_InSync
) ||
5516 (dib
->p_status
== DIB_Status_AppMod
))
5517 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_NOACCESS
);
5519 /* no commit, revert to previous state */
5520 if (dib
->p_status
!= DIB_Status_None
)
5521 dib
->status
= dib
->p_status
;
5522 /* no protections changed */
5524 dib
->p_status
= DIB_Status_None
;
5527 LeaveCriticalSection(&(dib
->lock
));
5528 TRACE("Unlocked %p\n", bmp
);
5532 /***********************************************************************
5533 * X11DRV_CoerceDIBSection2
5535 INT
X11DRV_CoerceDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
5540 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5541 if (!bmp
) return DIB_Status_None
;
5542 ret
= X11DRV_DIB_Coerce(bmp
, req
, lossy
);
5543 GDI_ReleaseObj( hBmp
);
5547 /***********************************************************************
5548 * X11DRV_LockDIBSection2
5550 INT
X11DRV_LockDIBSection2(HBITMAP hBmp
, INT req
, BOOL lossy
)
5555 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5556 if (!bmp
) return DIB_Status_None
;
5557 ret
= X11DRV_DIB_Lock(bmp
, req
, lossy
);
5558 GDI_ReleaseObj( hBmp
);
5562 /***********************************************************************
5563 * X11DRV_UnlockDIBSection2
5565 void X11DRV_UnlockDIBSection2(HBITMAP hBmp
, BOOL commit
)
5569 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5571 X11DRV_DIB_Unlock(bmp
, commit
);
5572 GDI_ReleaseObj( hBmp
);
5575 /***********************************************************************
5576 * X11DRV_CoerceDIBSection
5578 INT
X11DRV_CoerceDIBSection(X11DRV_PDEVICE
*physDev
, INT req
, BOOL lossy
)
5580 if (!physDev
) return DIB_Status_None
;
5581 return X11DRV_CoerceDIBSection2( physDev
->dc
->hBitmap
, req
, lossy
);
5584 /***********************************************************************
5585 * X11DRV_LockDIBSection
5587 INT
X11DRV_LockDIBSection(X11DRV_PDEVICE
*physDev
, INT req
, BOOL lossy
)
5589 if (!physDev
) return DIB_Status_None
;
5590 if (!(physDev
->dc
->flags
& DC_MEMORY
)) return DIB_Status_None
;
5592 return X11DRV_LockDIBSection2( physDev
->dc
->hBitmap
, req
, lossy
);
5595 /***********************************************************************
5596 * X11DRV_UnlockDIBSection
5598 void X11DRV_UnlockDIBSection(X11DRV_PDEVICE
*physDev
, BOOL commit
)
5600 if (!physDev
) return;
5601 if (!(physDev
->dc
->flags
& DC_MEMORY
)) return;
5603 X11DRV_UnlockDIBSection2( physDev
->dc
->hBitmap
, commit
);
5607 #ifdef HAVE_LIBXXSHM
5608 /***********************************************************************
5609 * X11DRV_XShmErrorHandler
5612 static int XShmErrorHandler( Display
*dpy
, XErrorEvent
*event
, void *arg
)
5614 return 1; /* FIXME: should check event contents */
5617 /***********************************************************************
5618 * X11DRV_XShmCreateImage
5621 static XImage
*X11DRV_XShmCreateImage( int width
, int height
, int bpp
,
5622 XShmSegmentInfo
* shminfo
)
5627 image
= XShmCreateImage(gdi_display
, visual
, bpp
, ZPixmap
, NULL
, shminfo
, width
, height
);
5630 shminfo
->shmid
= shmget(IPC_PRIVATE
, image
->bytes_per_line
* height
,
5632 if( shminfo
->shmid
!= -1 )
5634 shminfo
->shmaddr
= image
->data
= shmat(shminfo
->shmid
, 0, 0);
5635 if( shminfo
->shmaddr
!= (char*)-1 )
5639 shminfo
->readOnly
= FALSE
;
5640 X11DRV_expect_error( gdi_display
, XShmErrorHandler
, NULL
);
5641 ok
= (XShmAttach( gdi_display
, shminfo
) != 0);
5642 if (X11DRV_check_error()) ok
= FALSE
;
5645 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
5646 wine_tsx11_unlock();
5647 return image
; /* Success! */
5649 /* An error occured */
5650 shmdt(shminfo
->shmaddr
);
5652 shmctl(shminfo
->shmid
, IPC_RMID
, 0);
5654 XFlush(gdi_display
);
5655 XDestroyImage(image
);
5658 wine_tsx11_unlock();
5661 #endif /* HAVE_LIBXXSHM */
5664 /***********************************************************************
5665 * X11DRV_DIB_CreateDIBSection
5667 HBITMAP
X11DRV_DIB_CreateDIBSection(
5668 X11DRV_PDEVICE
*physDev
, BITMAPINFO
*bmi
, UINT usage
,
5669 LPVOID
*bits
, HANDLE section
,
5670 DWORD offset
, DWORD ovr_pitch
)
5673 BITMAPOBJ
*bmp
= NULL
;
5674 X11DRV_DIBSECTION
*dib
= NULL
;
5675 int *colorMap
= NULL
;
5678 /* Fill BITMAP32 structure with DIB data */
5679 BITMAPINFOHEADER
*bi
= &bmi
->bmiHeader
;
5680 INT effHeight
, totalSize
;
5682 LPVOID mapBits
= NULL
;
5684 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
5685 bi
->biWidth
, bi
->biHeight
, bi
->biPlanes
, bi
->biBitCount
,
5686 bi
->biSizeImage
, bi
->biClrUsed
, usage
== DIB_PAL_COLORS
? "PAL" : "RGB");
5688 effHeight
= bi
->biHeight
>= 0 ? bi
->biHeight
: -bi
->biHeight
;
5690 bm
.bmWidth
= bi
->biWidth
;
5691 bm
.bmHeight
= effHeight
;
5692 bm
.bmWidthBytes
= ovr_pitch
? ovr_pitch
5693 : DIB_GetDIBWidthBytes(bm
.bmWidth
, bi
->biBitCount
);
5694 bm
.bmPlanes
= bi
->biPlanes
;
5695 bm
.bmBitsPixel
= bi
->biBitCount
;
5698 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
5699 we're dealing with a compressed bitmap. Otherwise, use width * height. */
5700 totalSize
= bi
->biSizeImage
&& bi
->biCompression
!= BI_RGB
5701 ? bi
->biSizeImage
: bm
.bmWidthBytes
* effHeight
;
5705 SYSTEM_INFO SystemInfo
;
5709 GetSystemInfo( &SystemInfo
);
5710 mapOffset
= offset
- (offset
% SystemInfo
.dwAllocationGranularity
);
5711 mapSize
= totalSize
+ (offset
- mapOffset
);
5712 mapBits
= MapViewOfFile( section
,
5713 FILE_MAP_ALL_ACCESS
,
5717 bm
.bmBits
= (char *)mapBits
+ (offset
- mapOffset
);
5719 else if (ovr_pitch
&& offset
)
5720 bm
.bmBits
= (LPVOID
) offset
;
5723 bm
.bmBits
= VirtualAlloc(NULL
, totalSize
,
5724 MEM_RESERVE
|MEM_COMMIT
, PAGE_READWRITE
);
5727 /* Create Color Map */
5728 if (bm
.bmBits
&& bm
.bmBitsPixel
<= 8)
5729 colorMap
= X11DRV_DIB_BuildColorMap( usage
== DIB_PAL_COLORS
? physDev
: NULL
,
5730 usage
, bm
.bmBitsPixel
, bmi
, &nColorMap
);
5732 /* Allocate Memory for DIB and fill structure */
5734 dib
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(X11DRV_DIBSECTION
));
5737 dib
->dibSection
.dsBm
= bm
;
5738 dib
->dibSection
.dsBmih
= *bi
;
5739 dib
->dibSection
.dsBmih
.biSizeImage
= totalSize
;
5741 /* Set dsBitfields values */
5742 if ( usage
== DIB_PAL_COLORS
|| bi
->biBitCount
<= 8)
5744 dib
->dibSection
.dsBitfields
[0] = dib
->dibSection
.dsBitfields
[1] = dib
->dibSection
.dsBitfields
[2] = 0;
5746 else switch( bi
->biBitCount
)
5750 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0x7c00;
5751 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x03e0;
5752 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x001f;
5757 dib
->dibSection
.dsBitfields
[0] = (bi
->biCompression
== BI_BITFIELDS
) ? *(DWORD
*)bmi
->bmiColors
: 0xff0000;
5758 dib
->dibSection
.dsBitfields
[1] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 1) : 0x00ff00;
5759 dib
->dibSection
.dsBitfields
[2] = (bi
->biCompression
== BI_BITFIELDS
) ? *((DWORD
*)bmi
->bmiColors
+ 2) : 0x0000ff;
5762 dib
->dibSection
.dshSection
= section
;
5763 dib
->dibSection
.dsOffset
= offset
;
5765 dib
->status
= DIB_Status_None
;
5766 dib
->nColorMap
= nColorMap
;
5767 dib
->colorMap
= colorMap
;
5770 /* Create Device Dependent Bitmap and add DIB pointer */
5773 res
= CreateDIBitmap(physDev
->hdc
, bi
, 0, NULL
, bmi
, usage
);
5776 bmp
= (BITMAPOBJ
*) GDI_GetObjPtr(res
, BITMAP_MAGIC
);
5777 if (bmp
) bmp
->dib
= (DIBSECTION
*) dib
;
5784 #ifdef HAVE_LIBXXSHM
5785 if (TSXShmQueryExtension(gdi_display
) &&
5786 (dib
->image
= X11DRV_XShmCreateImage( bm
.bmWidth
, effHeight
,
5787 bmp
->bitmap
.bmBitsPixel
, &dib
->shminfo
)) )
5789 ; /* Created Image */
5791 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
5792 dib
->shminfo
.shmid
= -1;
5795 dib
->image
= X11DRV_DIB_CreateXImage( bm
.bmWidth
, effHeight
, bmp
->bitmap
.bmBitsPixel
);
5799 /* Clean up in case of errors */
5800 if (!res
|| !bmp
|| !dib
|| !bm
.bmBits
|| (bm
.bmBitsPixel
<= 8 && !colorMap
))
5802 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
5803 res
, bmp
, dib
, bm
.bmBits
);
5807 UnmapViewOfFile(mapBits
), bm
.bmBits
= NULL
;
5809 VirtualFree(bm
.bmBits
, 0L, MEM_RELEASE
), bm
.bmBits
= NULL
;
5812 if (dib
&& dib
->image
) { XDestroyImage(dib
->image
); dib
->image
= NULL
; }
5813 if (colorMap
) { HeapFree(GetProcessHeap(), 0, colorMap
); colorMap
= NULL
; }
5814 if (dib
) { HeapFree(GetProcessHeap(), 0, dib
); dib
= NULL
; }
5815 if (bmp
) { GDI_ReleaseObj(res
); bmp
= NULL
; }
5816 if (res
) { DeleteObject(res
); res
= 0; }
5820 /* Install fault handler, if possible */
5821 InitializeCriticalSection(&(dib
->lock
));
5822 if (VIRTUAL_SetFaultHandler(bm
.bmBits
, X11DRV_DIB_FaultHandler
, (LPVOID
)res
))
5824 X11DRV_DIB_DoProtectDIBSection( bmp
, PAGE_READWRITE
);
5825 if (dib
) dib
->status
= DIB_Status_AppMod
;
5829 /* Return BITMAP handle and storage location */
5830 if (bmp
) GDI_ReleaseObj(res
);
5831 if (bm
.bmBits
&& bits
) *bits
= bm
.bmBits
;
5835 /***********************************************************************
5836 * X11DRV_DIB_DeleteDIBSection
5838 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ
*bmp
)
5840 X11DRV_DIBSECTION
*dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5844 #ifdef HAVE_LIBXXSHM
5845 if (dib
->shminfo
.shmid
!= -1)
5847 TSXShmDetach (gdi_display
, &(dib
->shminfo
));
5848 XDestroyImage (dib
->image
);
5849 shmdt (dib
->shminfo
.shmaddr
);
5850 dib
->shminfo
.shmid
= -1;
5854 XDestroyImage( dib
->image
);
5858 HeapFree(GetProcessHeap(), 0, dib
->colorMap
);
5860 DeleteCriticalSection(&(dib
->lock
));
5863 /***********************************************************************
5864 * SetDIBColorTable (X11DRV.@)
5866 UINT
X11DRV_SetDIBColorTable( X11DRV_PDEVICE
*physDev
, UINT start
, UINT count
, const RGBQUAD
*colors
)
5869 X11DRV_DIBSECTION
*dib
;
5872 if (!(bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( physDev
->dc
->hBitmap
, BITMAP_MAGIC
))) return 0;
5873 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5875 if (dib
&& dib
->colorMap
) {
5876 UINT end
= count
+ start
;
5877 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
5879 * Changing color table might change the mapping between
5880 * DIB colors and X11 colors and thus alter the visible state
5881 * of the bitmap object.
5883 X11DRV_DIB_Lock(bmp
, DIB_Status_AppMod
, FALSE
);
5884 X11DRV_DIB_GenColorMap( physDev
, dib
->colorMap
, DIB_RGB_COLORS
,
5885 dib
->dibSection
.dsBm
.bmBitsPixel
,
5886 TRUE
, colors
, start
, end
);
5887 X11DRV_DIB_Unlock(bmp
, TRUE
);
5890 GDI_ReleaseObj( physDev
->dc
->hBitmap
);
5894 /***********************************************************************
5895 * GetDIBColorTable (X11DRV.@)
5897 UINT
X11DRV_GetDIBColorTable( X11DRV_PDEVICE
*physDev
, UINT start
, UINT count
, RGBQUAD
*colors
)
5900 X11DRV_DIBSECTION
*dib
;
5903 if (!(bmp
= (BITMAPOBJ
*)GDI_GetObjPtr( physDev
->dc
->hBitmap
, BITMAP_MAGIC
))) return 0;
5904 dib
= (X11DRV_DIBSECTION
*) bmp
->dib
;
5906 if (dib
&& dib
->colorMap
) {
5907 UINT i
, end
= count
+ start
;
5908 if (end
> dib
->nColorMap
) end
= dib
->nColorMap
;
5909 for (i
= start
; i
< end
; i
++,colors
++) {
5910 COLORREF col
= X11DRV_PALETTE_ToLogical( dib
->colorMap
[i
] );
5911 colors
->rgbBlue
= GetBValue(col
);
5912 colors
->rgbGreen
= GetGValue(col
);
5913 colors
->rgbRed
= GetRValue(col
);
5914 colors
->rgbReserved
= 0;
5918 GDI_ReleaseObj( physDev
->dc
->hBitmap
);
5923 /**************************************************************************
5924 * X11DRV_DIB_CreateDIBFromPixmap
5926 * Allocates a packed DIB and copies the Pixmap data into it.
5927 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
5929 HGLOBAL
X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap
, HDC hdc
, BOOL bDeletePixmap
)
5932 BITMAPOBJ
*pBmp
= NULL
;
5933 HGLOBAL hPackedDIB
= 0;
5935 /* Allocates an HBITMAP which references the Pixmap passed to us */
5936 hBmp
= X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap
);
5939 TRACE("\tCould not create bitmap header for Pixmap\n");
5944 * Create a packed DIB from the Pixmap wrapper bitmap created above.
5945 * A packed DIB contains a BITMAPINFO structure followed immediately by
5946 * an optional color palette and the pixel data.
5948 hPackedDIB
= DIB_CreateDIBFromBitmap(hdc
, hBmp
);
5950 /* Get a pointer to the BITMAPOBJ structure */
5951 pBmp
= (BITMAPOBJ
*)GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
5953 /* We can now get rid of the HBITMAP wrapper we created earlier.
5954 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
5958 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
5959 pBmp
->physBitmap
= NULL
;
5962 GDI_ReleaseObj( hBmp
);
5966 TRACE("\tReturning packed DIB %x\n", hPackedDIB
);
5971 /**************************************************************************
5972 * X11DRV_DIB_CreatePixmapFromDIB
5974 * Creates a Pixmap from a packed DIB
5976 Pixmap
X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB
, HDC hdc
)
5978 Pixmap pixmap
= None
;
5980 BITMAPOBJ
*pBmp
= NULL
;
5981 LPBYTE pPackedDIB
= NULL
;
5982 LPBITMAPINFO pbmi
= NULL
;
5983 LPBITMAPINFOHEADER pbmiHeader
= NULL
;
5984 LPBYTE pbits
= NULL
;
5986 /* Get a pointer to the packed DIB's data */
5987 pPackedDIB
= (LPBYTE
)GlobalLock(hPackedDIB
);
5988 pbmiHeader
= (LPBITMAPINFOHEADER
)pPackedDIB
;
5989 pbmi
= (LPBITMAPINFO
)pPackedDIB
;
5990 pbits
= (LPBYTE
)(pPackedDIB
5991 + DIB_BitmapInfoSize( (LPBITMAPINFO
)pbmiHeader
, DIB_RGB_COLORS
));
5993 /* Create a DDB from the DIB */
5995 hBmp
= CreateDIBitmap(hdc
,
6002 GlobalUnlock(hPackedDIB
);
6004 TRACE("CreateDIBitmap returned %x\n", hBmp
);
6006 /* Retrieve the internal Pixmap from the DDB */
6008 pBmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hBmp
, BITMAP_MAGIC
);
6010 pixmap
= (Pixmap
)pBmp
->physBitmap
;
6011 /* clear the physBitmap so that we can steal its pixmap */
6012 pBmp
->physBitmap
= NULL
;
6015 /* Delete the DDB we created earlier now that we have stolen its pixmap */
6016 GDI_ReleaseObj( hBmp
);
6019 TRACE("\tReturning Pixmap %ld\n", pixmap
);