2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
9 #ifndef X_DISPLAY_MISSING
16 # ifdef HAVE_SYS_SHM_H
19 # ifdef HAVE_SYS_IPC_H
22 #endif /* defined(HAVE_LIBXXSHM) */
28 #include "debugtools.h"
32 #include "selectors.h"
35 DEFAULT_DEBUG_CHANNEL(bitmap)
36 DECLARE_DEBUG_CHANNEL(x11drv)
38 static int bitmapDepthTable[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
39 static int ximageDepthTable[] = { 0, 0, 0, 0, 0, 0, 0 };
41 static int XShmErrorFlag = 0;
43 /***********************************************************************
46 BOOL X11DRV_DIB_Init(void)
51 for( i = 0; bitmapDepthTable[i]; i++ )
53 testimage = TSXCreateImage(display, X11DRV_GetVisual(),
54 bitmapDepthTable[i], ZPixmap, 0, NULL, 1, 1, 32, 20 );
55 if( testimage ) ximageDepthTable[i] = testimage->bits_per_pixel;
57 TSXDestroyImage(testimage);
63 /***********************************************************************
64 * X11DRV_DIB_GetXImageWidthBytes
66 * Return the width of an X image in bytes
68 int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
72 if (!ximageDepthTable[0]) {
75 for( i = 0; bitmapDepthTable[i] ; i++ )
76 if( bitmapDepthTable[i] == depth )
77 return (4 * ((width * ximageDepthTable[i] + 31)/32));
79 WARN("(%d): Unsupported depth\n", depth );
83 /***********************************************************************
84 * X11DRV_DIB_BuildColorMap
86 * Build the color map from the bitmap palette. Should not be called
87 * for a >8-bit deep bitmap.
89 int *X11DRV_DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth,
90 const BITMAPINFO *info, int *nColors )
97 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
99 colors = info->bmiHeader.biClrUsed;
100 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
101 colorPtr = (WORD *)info->bmiColors;
103 else /* assume BITMAPCOREINFO */
105 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
106 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
111 ERR("called with >256 colors!\n");
115 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
116 colors * sizeof(int) )))
119 if (coloruse == DIB_RGB_COLORS)
123 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
125 if (depth == 1) /* Monochrome */
126 for (i = 0; i < colors; i++, rgb++)
127 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
128 rgb->rgbBlue > 255*3/2);
130 for (i = 0; i < colors; i++, rgb++)
131 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbRed,
137 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
139 if (depth == 1) /* Monochrome */
140 for (i = 0; i < colors; i++, rgb++)
141 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
142 rgb->rgbtBlue > 255*3/2);
144 for (i = 0; i < colors; i++, rgb++)
145 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbtRed,
150 else /* DIB_PAL_COLORS */
152 for (i = 0; i < colors; i++, colorPtr++)
153 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(*colorPtr) );
161 /***********************************************************************
162 * X11DRV_DIB_MapColor
164 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys )
168 for (color = 0; color < nPhysMap; color++)
169 if (physMap[color] == phys)
172 WARN("Strange color %08x\n", phys);
177 /*********************************************************************
178 * X11DRV_DIB_GetNearestIndex
180 * Helper for X11DRV_DIB_GetDIBits.
181 * Returns the nearest colour table index for a given RGB.
182 * Nearest is defined by minimizing the sum of the squares.
184 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
186 INT i, best = -1, diff, bestdiff = -1;
189 for(color = colormap, i = 0; i < numColors; color++, i++) {
190 diff = (r - color->rgbRed) * (r - color->rgbRed) +
191 (g - color->rgbGreen) * (g - color->rgbGreen) +
192 (b - color->rgbBlue) * (b - color->rgbBlue);
195 if(best == -1 || diff < bestdiff) {
203 /***********************************************************************
204 * X11DRV_DIB_SetImageBits_1_Line
206 * Handles a single line of 1 bit data.
208 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth, int left, int *colors,
209 XImage *bmpImage, int h, const BYTE *bits)
214 if((extra = (left & 7)) != 0) {
221 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
222 for (i = dstwidth/8, x = left; i > 0; i--)
225 XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
226 XPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] );
227 XPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] );
228 XPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] );
229 XPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] );
230 XPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] );
231 XPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] );
232 XPutPixel( bmpImage, x++, h, colors[pix & 1] );
237 case 7: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
238 case 6: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
239 case 5: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
240 case 4: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
241 case 3: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
242 case 2: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
243 case 1: XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
247 /***********************************************************************
248 * X11DRV_DIB_SetImageBits_1
250 * SetDIBits for a 1-bit deep DIB.
252 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
253 DWORD srcwidth, DWORD dstwidth, int left,
254 int *colors, XImage *bmpImage )
259 DWORD linebytes = ((srcwidth + 31) & ~31) / 8;
262 for (h = lines-1; h >=0; h--) {
263 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
265 srcbits += linebytes;
269 for (h = 0; h < lines; h++) {
270 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
272 srcbits += linebytes;
277 /***********************************************************************
278 * X11DRV_DIB_GetImageBits_1
280 * GetDIBits for a 1-bit deep DIB.
282 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
283 DWORD dstwidth, DWORD srcwidth,
284 RGBQUAD *colors, PALETTEENTRY *srccolors,
292 DWORD linebytes = ((dstwidth + 31) & ~31) / 8;
296 dstbits = dstbits + linebytes * (lines - 1);
297 linebytes = -linebytes;
302 switch(bmpImage->depth) {
305 /* ==== monochrome bitmap to monochrome dib ==== */
307 /* ==== 4 colormap bitmap to monochrome dib ==== */
308 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
312 for (h = lines - 1; h >= 0; h--) {
313 for (x = 0; x < dstwidth; x++) {
314 val = srccolors[XGetPixel(bmpImage, x, h)];
315 if (!(x&7)) *bits = 0;
316 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2,
319 val.peBlue) << (7 - (x & 7)));
320 if ((x&7)==7) bits++;
322 bits = (dstbits += linebytes);
325 else goto notsupported;
330 /* ==== 8 colormap bitmap to monochrome dib ==== */
331 if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
336 for( h = lines- 1; h >= 0; h-- ) {
337 srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
338 for( x = 0; x < dstwidth; x++ ) {
339 if (!(x&7)) *bits = 0;
340 val = srccolors[(int)*srcpixel++];
341 *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 2,
344 val.peBlue) << (7-(x&7)) );
345 if ((x&7)==7) bits++;
347 bits = (dstbits += linebytes);
350 else goto notsupported;
359 /* ==== 555 BGR bitmap to monochrome dib ==== */
360 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
362 for( h = lines - 1; h >= 0; h--) {
363 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
364 for( x = 0; x < dstwidth; x++) {
365 if (!(x&7)) *bits = 0;
367 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
368 ((val >> 7) & 0xf8) |
370 ((val >> 2) & 0xf8) |
372 ((val << 3) & 0xf8) |
373 ((val >> 2) & 0x7) ) << (7-(x&7)) );
374 if ((x&7)==7) bits++;
376 bits = (dstbits += linebytes);
379 /* ==== 555 RGB bitmap to monochrome dib ==== */
380 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
382 for( h = lines - 1; h >= 0; h--)
384 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
385 for( x = 0; x < dstwidth; x++) {
386 if (!(x&1)) *bits = 0;
388 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
389 ((val << 3) & 0xf8) |
391 ((val >> 2) & 0xf8) |
393 ((val >> 7) & 0xf8) |
394 ((val >> 12) & 0x7) ) << (7-(x&7)) );
395 if ((x&7)==7) bits++;
397 bits = (dstbits += linebytes);
400 else goto notsupported;
409 /* ==== 565 BGR bitmap to monochrome dib ==== */
410 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
412 for( h = lines - 1; h >= 0; h--)
414 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
415 for( x = 0; x < dstwidth; x++) {
416 if (!(x&7)) *bits = 0;
418 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
419 ((val >> 8) & 0xf8) |
421 ((val >> 3) & 0xfc) |
423 ((val << 3) & 0xf8) |
424 ((val >> 2) & 0x7) ) << (7-(x&7)) );
425 if ((x&7)==7) bits++;
427 bits = (dstbits += linebytes);
430 /* ==== 565 RGB bitmap to monochrome dib ==== */
431 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
433 for( h = lines - 1; h >= 0; h--)
435 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
436 for( x = 0; x < dstwidth; x++) {
437 if (!(x&7)) *bits = 0;
439 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
440 ((val << 3) & 0xf8) |
442 ((val >> 3) & 0xfc) |
444 ((val >> 8) & 0xf8) |
445 ((val >> 13) & 0x7) ) << (7-(x&7)) );
446 if ((x&7)==7) bits++;
448 bits = (dstbits += linebytes);
451 else goto notsupported;
460 /* ==== 24/32 BGR bitmap to monochrome dib ==== */
461 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
463 for (h = lines - 1; h >= 0; h--)
465 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
466 for (x = 0; x < dstwidth; x++, srcpixel+=4) {
467 if (!(x&7)) *bits = 0;
468 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[2] , srcpixel[1], srcpixel[0]) << (7-(x&7)) );
469 if ((x&7)==7) bits++;
471 bits = (dstbits += linebytes);
474 /* ==== 24/32 RGB bitmap to monochrome dib ==== */
475 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
477 for (h = lines - 1; h >= 0; h--)
479 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
480 for (x = 0; x < dstwidth; x++, srcpixel+=4) {
481 if (!(x & 7)) *bits = 0;
482 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[0] , srcpixel[1], srcpixel[2]) << (7-(x&7)) );
483 if ((x & 7) == 7) bits++;
485 bits = (dstbits += linebytes);
488 else goto notsupported;
492 default: /* ? bit bmp -> monochrome DIB */
495 unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
497 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
498 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
499 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
501 for( h = lines - 1; h >= 0; h-- ) {
502 for( x = 0; x < dstwidth; x++ ) {
503 if (!(x&7)) *bits = 0;
504 *bits |= (XGetPixel( bmpImage, x, h) >= white)
506 if ((x&7)==7) bits++;
508 bits = (dstbits += linebytes);
515 /***********************************************************************
516 * X11DRV_DIB_SetImageBits_4
518 * SetDIBits for a 4-bit deep DIB.
520 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
521 DWORD srcwidth, DWORD dstwidth, int left,
522 int *colors, XImage *bmpImage )
526 const BYTE *bits = srcbits + (left >> 1);
529 DWORD linebytes = ((srcwidth+7)&~7)/2;
537 for (h = lines-1; h >= 0; h--) {
538 for (i = dstwidth/2, x = left; i > 0; i--) {
540 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
541 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
543 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
544 srcbits += linebytes;
545 bits = srcbits + (left >> 1);
549 for (h = 0; h < lines; h++) {
550 for (i = dstwidth/2, x = left; i > 0; i--) {
552 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
553 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
555 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
556 srcbits += linebytes;
557 bits = srcbits + (left >> 1);
564 /***********************************************************************
565 * X11DRV_DIB_GetImageBits_4
567 * GetDIBits for a 4-bit deep DIB.
569 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
570 DWORD srcwidth, DWORD dstwidth,
571 RGBQUAD *colors, PALETTEENTRY *srccolors,
580 DWORD linebytes = ((srcwidth+7)&~7)/2;
585 dstbits = dstbits + ( linebytes * (lines-1) );
586 linebytes = -linebytes;
591 switch(bmpImage->depth) {
594 /* ==== monochrome bitmap to 4 colormap dib ==== */
596 /* ==== 4 colormap bitmap to 4 colormap dib ==== */
597 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
601 for (h = lines-1; h >= 0; h--) {
602 for (x = 0; x < dstwidth; x++) {
603 if (!(x&1)) *bits = 0;
604 val = srccolors[XGetPixel(bmpImage, x, h)];
605 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 16,
608 val.peBlue) << (4-((x&1)<<2)));
609 if ((x&1)==1) bits++;
611 bits = (dstbits += linebytes);
614 else goto notsupported;
619 /* ==== 8 colormap bitmap to 4 colormap dib ==== */
620 if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
624 for( h = lines - 1; h >= 0; h-- ) {
625 srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
626 for( x = 0; x < dstwidth; x++ ) {
627 if (!(x&1)) *bits = 0;
628 val = srccolors[(int)*srcpixel++];
629 *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 16,
632 val.peBlue) << (4*(1-(x&1))) );
633 if ((x&1)==1) bits++;
635 bits = (dstbits += linebytes);
638 else goto notsupported;
647 /* ==== 555 BGR bitmap to 4 colormap dib ==== */
648 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
650 for( h = lines - 1; h >= 0; h--) {
651 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
652 for( x = 0; x < dstwidth; x++) {
653 if (!(x&1)) *bits = 0;
655 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
656 ((val >> 7) & 0xf8) |
658 ((val >> 2) & 0xf8) |
660 ((val << 3) & 0xf8) |
661 ((val >> 2) & 0x7) ) << ((1-(x&1))<<2) );
662 if ((x&1)==1) bits++;
664 bits = (dstbits += linebytes);
667 /* ==== 555 RGB bitmap to 4 colormap dib ==== */
668 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
670 for( h = lines - 1; h >= 0; h--)
672 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
673 for( x = 0; x < dstwidth; x++) {
674 if (!(x&1)) *bits = 0;
676 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
677 ((val << 3) & 0xf8) |
679 ((val >> 2) & 0xfc) |
681 ((val >> 7) & 0xf8) |
682 ((val >> 12) & 0x7) ) << ((1-(x&1))<<2) );
683 if ((x&1)==1) bits++;
685 bits = (dstbits += linebytes);
688 else goto notsupported;
697 /* ==== 565 BGR bitmap to 4 colormap dib ==== */
698 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
700 for( h = lines - 1; h >= 0; h--)
702 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
703 for( x = 0; x < dstwidth; x++) {
704 if (!(x&1)) *bits = 0;
706 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
707 ((val >> 8) & 0xf8) |
709 ((val >> 3) & 0xfc) |
711 ((val << 3) & 0xf8) |
712 ((val >> 2) & 0x7) ) << ((1-(x&1))<<2) );
713 if ((x&1)==1) bits++;
715 bits = (dstbits += linebytes);
718 /* ==== 565 RGB bitmap to 4 colormap dib ==== */
719 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
721 for( h = lines - 1; h >= 0; h--)
723 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
724 for( x = 0; x < dstwidth; x++) {
725 if (!(x&1)) *bits = 0;
727 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
728 ((val << 3) & 0xf8) |
730 ((val >> 3) & 0xfc) |
732 ((val >> 8) & 0xf8) |
733 ((val >> 13) & 0x7) ) << ((1-(x&1))<<2) );
734 if ((x&1)==1) bits++;
736 bits = (dstbits += linebytes);
739 else goto notsupported;
748 /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
749 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
751 for (h = lines - 1; h >= 0; h--)
753 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
754 for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
755 *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[2] , srcpixel[1], srcpixel[0]) << 4) |
756 X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[6] , srcpixel[5], srcpixel[4]);
757 bits = (dstbits += linebytes);
760 /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
761 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
763 for (h = lines - 1; h >= 0; h--)
765 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
766 for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
767 *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[0] , srcpixel[1], srcpixel[2]) << 4) |
768 X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[4] , srcpixel[5], srcpixel[6]);
769 bits = (dstbits += linebytes);
772 else goto notsupported;
776 default: /* ? bit bmp -> 4 bit DIB */
778 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
779 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
780 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
781 for (h = lines-1; h >= 0; h--) {
782 for (x = 0; x < dstwidth/2; x++) {
783 *bits++ = (X11DRV_DIB_MapColor((int *)colors, 16,
784 XGetPixel( bmpImage, x++, h )) << 4)
785 | (X11DRV_DIB_MapColor((int *)colors, 16,
786 XGetPixel( bmpImage, x++, h )) & 0x0f);
789 *bits = (X11DRV_DIB_MapColor((int *)colors, 16,
790 XGetPixel( bmpImage, x++, h )) << 4);
791 bits = (dstbits += linebytes);
797 /***********************************************************************
798 * X11DRV_DIB_SetImageBits_RLE4
800 * SetDIBits for a 4-bit deep compressed DIB.
802 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
803 DWORD width, DWORD dstwidth,
804 int left, int *colors,
807 int x = 0, c, length;
808 const BYTE *begin = bits;
812 while ((int)lines >= 0) {
814 if (length) { /* encoded */
822 XPutPixel(bmpImage, x++, lines, colors[c >>4]);
830 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
841 case 1: /* eopicture */
847 FIXME_(x11drv)("x-delta is too large?\n");
853 default: /* absolute */
861 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
869 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
872 if ((bits - begin) & 1)
881 /***********************************************************************
882 * X11DRV_DIB_SetImageBits_8
884 * SetDIBits for an 8-bit deep DIB.
886 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
887 DWORD srcwidth, DWORD dstwidth, int left,
888 int *colors, XImage *bmpImage )
894 /* align to 32 bit */
895 DWORD linebytes = (srcwidth + 3) & ~3;
902 srcbits = srcbits + ( linebytes * (lines-1) );
903 linebytes = -linebytes;
906 bits = srcbits + left;
908 for (h = lines - 1; h >= 0; h--) {
909 for (x = left; x < dstwidth; x++, bits++) {
910 color = colors[*bits];
911 XPutPixel( bmpImage, x, h, colors[*bits] );
913 bits = (srcbits += linebytes) + left;
917 /***********************************************************************
918 * X11DRV_DIB_GetImageBits_8
920 * GetDIBits for an 8-bit deep DIB.
922 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
923 DWORD srcwidth, DWORD dstwidth,
924 RGBQUAD *colors, PALETTEENTRY *srccolors,
931 /* align to 32 bit */
932 DWORD linebytes = (srcwidth + 3) & ~3;
937 dstbits = dstbits + ( linebytes * (lines-1) );
938 linebytes = -linebytes;
945 This condition is true when GetImageBits has been called by UpdateDIBSection.
946 For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
947 for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
949 if (!srccolors) goto updatesection;
951 switch(bmpImage->depth) {
954 /* ==== monochrome bitmap to 8 colormap dib ==== */
956 /* ==== 4 colormap bitmap to 8 colormap dib ==== */
957 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
961 for (h = lines - 1; h >= 0; h--) {
962 for (x = 0; x < dstwidth; x++) {
963 val = srccolors[XGetPixel(bmpImage, x, h)];
964 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed,
965 val.peGreen, val.peBlue);
967 bits = (dstbits += linebytes);
970 else goto notsupported;
975 /* ==== 8 colormap bitmap to 8 colormap dib ==== */
976 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
981 for (h = lines - 1; h >= 0; h--) {
982 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
983 for (x = 0; x < dstwidth; x++) {
984 val = srccolors[(int)*srcpixel++];
985 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed,
986 val.peGreen, val.peBlue);
988 bits = (dstbits += linebytes);
991 else goto notsupported;
1000 /* ==== 555 BGR bitmap to 8 colormap dib ==== */
1001 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
1003 for( h = lines - 1; h >= 0; h--)
1005 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1006 for( x = 0; x < dstwidth; x++ )
1009 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1010 ((val >> 7) & 0xf8) |
1011 ((val >> 12) & 0x7),
1012 ((val >> 2) & 0xf8) |
1014 ((val << 3) & 0xf8) |
1015 ((val >> 2) & 0x7) );
1017 bits = (dstbits += linebytes);
1020 /* ==== 555 RGB bitmap to 8 colormap dib ==== */
1021 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
1023 for( h = lines - 1; h >= 0; h--)
1025 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1026 for( x = 0; x < dstwidth; x++ )
1029 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1030 ((val << 3) & 0xf8) |
1032 ((val >> 2) & 0xf8) |
1034 ((val >> 7) & 0xf8) |
1035 ((val >> 12) & 0x7) );
1037 bits = (dstbits += linebytes);
1040 else goto notsupported;
1049 /* ==== 565 BGR bitmap to 8 colormap dib ==== */
1050 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
1052 for( h = lines - 1; h >= 0; h--)
1054 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1055 for( x = 0; x < dstwidth; x++ )
1058 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1059 ((val >> 8) & 0xf8) |
1060 ((val >> 13) & 0x7),
1061 ((val >> 3) & 0xfc) |
1063 ((val << 3) & 0xf8) |
1064 ((val >> 2) & 0x7) );
1066 bits = (dstbits += linebytes);
1069 /* ==== 565 RGB bitmap to 8 colormap dib ==== */
1070 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
1072 for( h = lines - 1; h >= 0; h--)
1074 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1075 for( x = 0; x < dstwidth; x++ )
1078 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1079 ((val << 3) & 0xf8) |
1081 ((val >> 3) & 0x00fc) |
1083 ((val >> 8) & 0x00f8) |
1084 ((val >> 13) & 0x7) );
1086 bits = (dstbits += linebytes);
1089 else goto notsupported;
1098 /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
1099 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1101 for (h = lines - 1; h >= 0; h--)
1103 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1104 for (x = 0; x < dstwidth; x++, srcpixel+=4)
1105 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256,
1106 srcpixel[2] , srcpixel[1], *srcpixel);
1107 bits = (dstbits += linebytes);
1110 /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
1111 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1113 for (h = lines - 1; h >= 0; h--)
1115 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1116 for (x = 0; x < dstwidth; x++, srcpixel+=4)
1117 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256,
1118 *srcpixel, srcpixel[1], srcpixel[2]);
1119 bits = (dstbits += linebytes);
1123 else goto notsupported;
1127 default: /* ? bit bmp -> 8 bit DIB */
1129 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
1130 bmpImage->depth, (int)bmpImage->red_mask,
1131 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
1133 for (h = lines - 1; h >= 0; h--) {
1134 for (x = 0; x < dstwidth; x++, bits++) {
1135 *bits = X11DRV_DIB_MapColor((int *)colors, 256,
1136 XGetPixel( bmpImage, x, h ) );
1138 bits = (dstbits += linebytes);
1144 /***********************************************************************
1145 * X11DRV_DIB_SetImageBits_RLE8
1147 * SetDIBits for an 8-bit deep compressed DIB.
1149 * This function rewritten 941113 by James Youngman. WINE blew out when I
1150 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1152 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1153 * 'End of bitmap' escape code. This code is very much laxer in what it
1154 * allows to end the expansion. Possibly too lax. See the note by
1155 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1156 * bitmap should end with RleEnd, but on the other hand, software exists
1157 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1160 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1161 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1165 enum Rle8_EscapeCodes
1168 * Apologies for polluting your file's namespace...
1170 RleEol = 0, /* End of line */
1171 RleEnd = 1, /* End of bitmap */
1172 RleDelta = 2 /* Delta */
1175 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
1176 DWORD width, DWORD dstwidth,
1177 int left, int *colors,
1180 int x; /* X-positon on each line. Increases. */
1181 int line; /* Line #. Starts at lines-1, decreases */
1182 const BYTE *pIn = bits; /* Pointer to current position in bits */
1183 BYTE length; /* The length pf a run */
1184 BYTE color_index; /* index into colors[] as read from bits */
1185 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
1186 int color; /* value of colour[color_index] */
1188 if (lines == 0) /* Let's hope this doesn't happen. */
1192 * Note that the bitmap data is stored by Windows starting at the
1193 * bottom line of the bitmap and going upwards. Within each line,
1194 * the data is stored left-to-right. That's the reason why line
1195 * goes from lines-1 to 0. [JAY]
1205 * If the length byte is not zero (which is the escape value),
1206 * We have a run of length pixels all the same colour. The colour
1207 * index is stored next.
1209 * If the length byte is zero, we need to read the next byte to
1210 * know what to do. [JAY]
1215 * [Run-Length] Encoded mode
1217 color_index = (*pIn++); /* Get the colour index. */
1218 color = colors[color_index];
1221 XPutPixel(bmpImage, x++, line, color);
1226 * Escape codes (may be an absolute sequence though)
1228 escape_code = (*pIn++);
1231 case RleEol: /* =0, end of line */
1238 case RleEnd: /* =1, end of bitmap */
1241 * Not all RLE8 bitmaps end with this
1242 * code. For example, Paint Shop Pro
1243 * produces some that don't. That's (I think)
1244 * what caused the previous implementation to
1247 line=-1; /* Cause exit from do loop. */
1251 case RleDelta: /* =2, a delta */
1254 * Note that deltaing to line 0
1255 * will cause an exit from the loop,
1256 * which may not be what is intended.
1257 * The fact that there is a delta in the bits
1258 * almost certainly implies that there is data
1259 * to follow. You may feel that we should
1260 * jump to the top of the loop to avoid exiting
1263 * TODO: Decide what to do here in that case. [JAY]
1269 TRACE("Delta to last line of bitmap "
1270 "(wrongly?) causes loop exit\n");
1275 default: /* >2, switch to absolute mode */
1280 length = escape_code;
1283 color_index = (*pIn++);
1284 XPutPixel(bmpImage, x++, line,
1285 colors[color_index]);
1289 * If you think for a moment you'll realise that the
1290 * only time we could ever possibly read an odd
1291 * number of bytes is when there is a 0x00 (escape),
1292 * a value >0x02 (absolute mode) and then an odd-
1293 * length run. Therefore this is the only place we
1294 * need to worry about it. Everywhere else the
1295 * bytes are always read in pairs. [JAY]
1297 if (escape_code & 1)
1298 pIn++; /* Throw away the pad byte. */
1301 } /* switch (escape_code) : Escape sequence */
1302 } /* process either an encoded sequence or an escape sequence */
1304 /* We expect to come here more than once per line. */
1305 } while (line >= 0); /* Do this until the bitmap is filled */
1308 * Everybody comes here at the end.
1309 * Check how we exited the loop and print a message if it's a bit odd.
1312 if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) )
1314 TRACE("End-of-bitmap without (strictly) proper escape code. Last two "
1315 "bytes were: %02X %02X.\n", (int)*(pIn-2),(int)*(pIn-1));
1320 /***********************************************************************
1321 * X11DRV_DIB_SetImageBits_16
1323 * SetDIBits for a 16-bit deep DIB.
1325 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
1326 DWORD srcwidth, DWORD dstwidth, int left,
1327 DC *dc, DWORD rSrc, DWORD gSrc, DWORD bSrc,
1333 /* align to 32 bit */
1334 DWORD linebytes = (srcwidth * 2 + 3) & ~3;
1339 srcbits = srcbits + ( linebytes * (lines-1));
1340 linebytes = -linebytes;
1343 switch ( bmpImage->depth )
1346 /* using same format as XImage */
1347 if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
1348 for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
1349 memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
1350 else /* We need to do a conversion from a 565 dib */
1352 LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
1354 int div = dstwidth % 2;
1356 for (h = lines - 1; h >= 0; h--) {
1357 dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1358 for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
1360 *dstpixel++ = ((val >> 1) & 0x7fe07fe0) | (val & 0x001f001f); /* Red & Green & Blue */
1362 if (div != 0) /* Odd width? */
1363 *dstpixel = ((*(WORD *)ptr >> 1) & 0x7fe0) | (*(WORD *)ptr & 0x001f);
1364 ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
1370 /* using same format as XImage */
1371 if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
1372 for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
1373 memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
1374 else /* We need to do a conversion from a 555 dib */
1376 LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
1378 int div = dstwidth % 2;
1380 for (h = lines - 1; h >= 0; h--) {
1381 dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1382 for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
1384 *dstpixel++ = ((val << 1) & 0xffc0ffc0) | ((val >> 4) & 0x00200020) | /* Red & Green */
1385 (val & 0x001f001f); /* Blue */
1387 if (div != 0) /* Odd width? */
1388 *dstpixel = ((*(WORD *)ptr << 1) & 0xffc0) | ((*(WORD *)ptr >> 4) & 0x0020)
1389 | (*(WORD *)ptr & 0x001f);
1390 ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
1399 LPWORD ptr = (LPWORD)srcbits + left;
1402 /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
1403 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1405 for (h = lines - 1; h >= 0; h--) {
1406 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1407 for (x = 0; x < dstwidth; x++) {
1410 *dstpixel++ = ((val << 9) & 0xf80000) | ((val << 4) & 0x070000) | /* Red */
1411 ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
1412 ((val << 3) & 0x0000f8) | ((val >> 2) & 0x000007); /* Blue */
1414 ptr = (LPWORD)(srcbits += linebytes) + left;
1417 /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
1418 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1420 for (h = lines - 1; h >= 0; h--) {
1421 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1422 for (x = 0; x < dstwidth; x++) {
1425 *dstpixel++ = ((val >> 7) & 0x0000f8) | ((val >> 12) & 0x000007) | /* Red */
1426 ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
1427 ((val << 19) & 0xf80000) | ((val >> 14) & 0x070000); /* Blue */
1429 ptr = (LPWORD)(srcbits += linebytes) + left;
1440 LPWORD ptr = (LPWORD)srcbits + left;
1444 /* Set color scaling values */
1445 if ( rSrc == 0x7c00 ) { sc1 = 7; sc2 = 2; } /* 555 dib */
1446 else { sc1 = 8; sc2 = 3; } /* 565 dib */
1448 for (h = lines - 1; h >= 0; h--) {
1449 for (x = left; x < dstwidth+left; x++) {
1451 XPutPixel( bmpImage, x, h,
1452 X11DRV_PALETTE_ToPhysical(dc, RGB(((val & rSrc) >> sc1), /* Red */
1453 ((val & gSrc) >> sc2), /* Green */
1454 ((val & bSrc) << 3)))); /* Blue */
1456 ptr = (LPWORD) (srcbits += linebytes) + left;
1462 FIXME("16 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
1469 /***********************************************************************
1470 * X11DRV_DIB_GetImageBits_16
1472 * GetDIBits for an 16-bit deep DIB.
1474 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
1475 DWORD dstwidth, DWORD srcwidth,
1476 PALETTEENTRY *srccolors, XImage *bmpImage )
1481 /* align to 32 bit */
1482 DWORD linebytes = (dstwidth * 2 + 3) & ~3;
1487 dstbits = dstbits + ( linebytes * (lines-1));
1488 linebytes = -linebytes;
1491 switch ( bmpImage->depth )
1494 /* ==== 555 BGR bitmap to 555 BGR dib ==== */
1495 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
1496 for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
1497 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
1499 /* ==== 555 RGB bitmap to 555 BGR dib ==== */
1500 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
1502 LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
1504 int div = srcwidth % 2;
1506 for (h = lines - 1; h >= 0; h--) {
1507 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1508 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1510 *ptr++ = ((val << 10) & 0xf800f800) | (val & 0x03e003e0) | /* Red & Green */
1511 ((val >> 10) & 0x001f001f); /* Blue */
1513 if (div != 0) /* Odd width? */
1514 *ptr = ((*(WORD *)srcpixel << 1) & 0xffc0) | ((*(WORD *)srcpixel >> 4) & 0x0020) |
1515 (*(WORD *)srcpixel & 0x001f);
1516 ptr = (LPDWORD)(dstbits += linebytes);
1519 else goto notsupported;
1525 LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
1527 int div = srcwidth % 2;
1529 /* ==== 565 BGR bitmap to 555 BGR dib ==== */
1530 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f )
1532 for (h = lines - 1; h >= 0; h--) {
1533 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1534 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1536 *ptr++ = ((val >> 1) & 0x7fe07fe0) | /* Red & Green */
1537 (val & 0x001f001f); /* Blue */
1539 if (div != 0) /* Odd width? */
1540 *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
1541 ptr = (LPDWORD) (dstbits += linebytes);
1544 /* ==== 565 RGB bitmap to 555 BGR dib ==== */
1545 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
1547 for (h = lines - 1; h >= 0; h--) {
1548 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1549 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1551 *ptr++ = ((val << 10) & 0x7c007c00) | ((val >> 1) & 0x03e003e0) | /* Red & Green */
1552 ((val >> 11) & 0x001f001f); /* Blue */
1554 if (div != 0) /* Odd width? */
1555 *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
1556 ptr = (LPDWORD) (dstbits += linebytes);
1559 else goto notsupported;
1567 LPWORD ptr = (LPWORD)dstbits;
1570 /* ==== 24/32 BGR bitmap to 555 BGR dib ==== */
1571 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1573 for (h = lines - 1; h >= 0; h--) {
1574 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1575 for (x = 0; x < srcwidth; x++, ptr++) {
1577 *ptr = ((val >> 9) & 0x7c00) | /* Red */
1578 ((val >> 6) & 0x03e0) | /* Green */
1579 ((val >> 3) & 0x001f); /* Blue */
1581 ptr = (LPWORD)(dstbits += linebytes);
1584 /* ==== 24/32 RGB bitmap to 555 BGR dib ==== */
1585 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1587 for (h = lines - 1; h >= 0; h--) {
1588 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1589 for (x = 0; x < srcwidth; x++, ptr++) {
1591 *ptr = ((val << 7) & 0x7c00) | /* Red */
1592 ((val >> 6) & 0x03e0) | /* Green */
1593 ((val >> 19) & 0x001f); /* Blue */
1595 ptr = (LPWORD) (dstbits += linebytes);
1598 else goto notsupported;
1603 /* ==== monochrome bitmap to 16 BGR dib ==== */
1605 /* ==== 4 colormap bitmap to 16 BGR dib ==== */
1606 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1608 LPWORD ptr = (LPWORD)dstbits;
1611 for (h = lines - 1; h >= 0; h--) {
1612 for (x = 0; x < dstwidth; x++) {
1613 val = srccolors[XGetPixel(bmpImage, x, h)];
1614 *ptr++ = ((val.peRed << 7) & 0x7c00) |
1615 ((val.peGreen << 2) & 0x03e0) |
1616 ((val.peBlue >> 3) & 0x001f);
1618 ptr = (LPWORD)(dstbits += linebytes);
1621 else goto notsupported;
1626 /* ==== 8 colormap bitmap to 16 BGR dib ==== */
1627 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1629 LPWORD ptr = (LPWORD)dstbits;
1633 for (h = lines - 1; h >= 0; h--) {
1634 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1635 for (x = 0; x < dstwidth; x++) {
1636 val = srccolors[(int)*srcpixel++];
1637 *ptr++ = ((val.peRed << 7) & 0x7c00) |
1638 ((val.peGreen << 2) & 0x03e0) |
1639 ((val.peBlue >> 3) & 0x001f);
1641 ptr = (LPWORD)(dstbits += linebytes);
1644 else goto notsupported;
1652 LPWORD ptr = (LPWORD)dstbits;
1654 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 16 bit DIB\n",
1655 bmpImage->depth, (int)bmpImage->red_mask,
1656 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
1657 for (h = lines - 1; h >= 0; h--)
1659 for (x = 0; x < dstwidth; x++, ptr++)
1661 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
1662 r = (BYTE) GetRValue(pixel);
1663 g = (BYTE) GetGValue(pixel);
1664 b = (BYTE) GetBValue(pixel);
1665 *ptr = ( ((r << 7) & 0x7c00) | ((g << 2) & 0x03e0) | ((b >> 3) & 0x001f) );
1667 ptr = (LPWORD) (dstbits += linebytes);
1675 /***********************************************************************
1676 * X11DRV_DIB_SetImageBits_24
1678 * SetDIBits for a 24-bit deep DIB.
1680 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
1681 DWORD srcwidth, DWORD dstwidth, int left,
1682 DC *dc, XImage *bmpImage )
1687 /* align to 32 bit */
1688 DWORD linebytes = (srcwidth * 3 + 3) & ~3;
1693 srcbits = srcbits + linebytes * (lines - 1);
1694 linebytes = -linebytes;
1697 switch ( bmpImage->depth )
1701 if (bmpImage->bits_per_pixel == 24) {
1702 int tocopy = linebytes;
1704 BYTE *ptr = (BYTE *)(srcbits+left*3);
1706 if (tocopy < 0 ) tocopy = -tocopy;
1707 dstpixel = bmpImage->data + lines*tocopy + left*3;
1708 for(h = lines ; h-- ; ) {
1710 memcpy(dstpixel,ptr,tocopy);
1718 if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 ) /* packed BGR to unpacked BGR */
1720 DWORD *dstpixel, val, buf;
1721 DWORD *ptr = (DWORD *)(srcbits + left*3);
1723 int div = dstwidth % 4;
1726 for(h = lines - 1; h >= 0; h--)
1728 dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);
1730 for (x = 0; x < dstwidth/4; x++) { /* do 3 dwords source, 4 dwords dest at a time */
1732 *dstpixel++ = buf&0x00ffffff; /* b1, g1, r1 */
1733 val = (buf >> 24); /* b2 */
1735 *dstpixel++ = (val | (buf<<8)) &0x00ffffff; /* g2, r2 */
1736 val = (buf >> 16); /* b3, g3 */
1738 *dstpixel++ = (val | (buf<<16)) &0x00ffffff; /* r3 */
1739 *dstpixel++ = (buf >> 8); /* b4, g4, r4 */
1741 for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
1743 *dstpixel++ = *(DWORD*)bits & 0x00ffffff; /* b, g, r */
1745 ptr = (DWORD*)((srcbits+=linebytes)+left*3);
1748 else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff ) /* packed BGR to unpacked RGB */
1750 DWORD *dstpixel, val, buf;
1751 DWORD *ptr = (DWORD *)(srcbits + left*3);
1753 int div = dstwidth % 4;
1756 for(h = lines - 1; h >= 0; h--)
1758 dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);
1760 for (x = 0; x < dstwidth/4; x++) { /* do 3 dwords source, 4 dwords dest at a time */
1762 *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16); /* b1, g1, r1 */
1763 val = ((buf&0xff000000)>>8); /* b2 */
1765 *dstpixel++ = val | ((buf&0xff)<<8) | ((buf&0xff00)>>8); /* g2, r2 */
1766 val = (buf&0xff0000) | ((buf&0xff000000)>>16); /* b3, g3 */
1768 *dstpixel++ = val | (buf&0xff); /* r3 */
1769 *dstpixel++ = ((buf&0xff00)<<8) | ((buf&0xff0000)>>8) | (buf>>24); /* b4, g4, r4 */
1771 for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
1773 buf = *(DWORD*)bits;
1774 *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16); /* b, g, r */
1776 ptr = (DWORD*)((srcbits+=linebytes)+left*3);
1786 if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f ) /* BGR888 to RGB555 */
1788 DWORD *ptr = (DWORD *)(srcbits + left*3), val;
1791 int div = dstwidth % 4;
1794 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1795 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1796 for (x = 0; x < dstwidth/4; x++) {
1797 *dstpixel++ = (WORD)((((val = *ptr++) << 7) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 19) & 0x1f));
1798 *dstpixel++ = (WORD)(((val >> 17) & 0x7c00) | (((val = *ptr++) << 2) & 0x03e0) | ((val >> 11) & 0x1f));
1799 *dstpixel++ = (WORD)(((val >> 9) & 0x07c00) | ((val >> 22) & 0x03e0) | (((val = *ptr++) >> 3) & 0x1f));
1800 *dstpixel++ = (WORD)(((val >> 1) & 0x07c00) | ((val >> 14) & 0x03e0) | ((val >> 27) & 0x1f));
1802 for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth not divisible by 4? */
1803 *dstpixel++ = (((WORD)bits[0] << 7) & 0x07c00) |
1804 (((WORD)bits[1] << 2) & 0x03e0) |
1805 (((WORD)bits[2] >> 3) & 0x001f);
1806 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1809 else if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 ) /* BGR888 to BGR555 */
1811 DWORD *ptr = (DWORD *)(srcbits + left*3), val;
1814 int div = dstwidth % 4;
1817 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1818 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1819 for (x = 0; x < dstwidth/4; x++) {
1820 *dstpixel++ = (WORD)((((val = *ptr++) >> 3) & 0x1f) | ((val >> 6) & 0x03e0) | ((val >> 9) & 0x7c00));
1821 *dstpixel++ = (WORD)(((val >> 27) & 0x1f) | (((val = *ptr++) << 2) & 0x03e0) | ((val >> 1) & 0x7c00));
1822 *dstpixel++ = (WORD)(((val >> 19) & 0x1f) | ((val >> 22) & 0x03e0) | (((val = *ptr++) << 7) & 0x7c00));
1823 *dstpixel++ = (WORD)(((val >> 11) & 0x1f) | ((val >> 14) & 0x03e0) | ((val >> 17) & 0x7c00));
1825 for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth not divisible by 4? */
1826 *dstpixel++ = (((WORD)bits[2] << 7) & 0x07c00) |
1827 (((WORD)bits[1] << 2) & 0x03e0) |
1828 (((WORD)bits[0] >> 3) & 0x001f);
1829 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1839 DWORD *ptr = (DWORD *)(srcbits + left*3), val;
1842 int div = dstwidth % 4;
1845 if( bmpImage->blue_mask == 0x001f && bmpImage->red_mask == 0xf800 ) /* BGR888 to BGR565 */
1847 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1848 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1849 for (x = 0; x < dstwidth/4; x++) {
1850 *dstpixel++ = (WORD)((((val = *ptr++) >> 3) & 0x1f) | ((val >> 5) & 0x07e0) | ((val >> 8) & 0xf800));
1851 *dstpixel++ = (WORD)(((val >> 27) & 0x1f) | (((val = *ptr++) << 3) & 0x07e0) | ((val) & 0xf800));
1852 *dstpixel++ = (WORD)(((val >> 19) & 0x1f) | ((val >> 21) & 0x07e0) | (((val = *ptr++) << 8) & 0xf800));
1853 *dstpixel++ = (WORD)(((val >> 11) & 0x1f) | ((val >> 13) & 0x07e0) | ((val >> 16) & 0xf800));
1855 for ( bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth is not divisible by 4? */
1856 *dstpixel++ = (((WORD)bits[2] << 8) & 0xf800) |
1857 (((WORD)bits[1] << 3) & 0x07e0) |
1858 (((WORD)bits[0] >> 3) & 0x001f);
1859 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1862 else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x001f ) /* BGR888 to RGB565 */
1864 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1865 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1866 for (x = 0; x < dstwidth/4; x++) {
1867 *dstpixel++ = (WORD)((((val = *ptr++) << 8) & 0xf800) | ((val >> 5) & 0x07e0) | ((val >> 19) & 0x1f));
1868 *dstpixel++ = (WORD)(((val >> 16) & 0xf800) | (((val = *ptr++) << 3) & 0x07e0) | ((val >> 11) & 0x1f));
1869 *dstpixel++ = (WORD)(((val >> 8) & 0xf800) | ((val >> 21) & 0x07e0) | (((val = *ptr++) >> 3) & 0x1f));
1870 *dstpixel++ = (WORD)((val & 0xf800) | ((val >> 13) & 0x07e0) | ((val >> 27) & 0x1f));
1872 for ( bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth is not divisible by 4? */
1873 *dstpixel++ = (((WORD)bits[0] << 8) & 0xf800) |
1874 (((WORD)bits[1] << 3) & 0x07e0) |
1875 (((WORD)bits[2] >> 3) & 0x001f);
1876 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1888 LPBYTE bits = (LPBYTE)srcbits + left*3;
1890 for (h = lines - 1; h >= 0; h--) {
1891 for (x = left; x < dstwidth+left; x++, bits+=3)
1892 XPutPixel( bmpImage, x, h,
1893 X11DRV_PALETTE_ToPhysical(dc, RGB(bits[2], bits[1], bits[0])));
1894 bits = (LPBYTE)(srcbits += linebytes) + left * 3;
1901 FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
1902 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
1903 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
1909 /***********************************************************************
1910 * X11DRV_DIB_GetImageBits_24
1912 * GetDIBits for an 24-bit deep DIB.
1914 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
1915 DWORD dstwidth, DWORD srcwidth,
1916 PALETTEENTRY *srccolors, XImage *bmpImage )
1921 /* align to 32 bit */
1922 DWORD linebytes = (dstwidth * 3 + 3) & ~3;
1927 dstbits = dstbits + ( linebytes * (lines-1) );
1928 linebytes = -linebytes;
1931 switch ( bmpImage->depth )
1935 if (bmpImage->bits_per_pixel == 24) {
1936 int tocopy = linebytes;
1938 BYTE *ptr = (LPBYTE)dstbits;
1940 if (tocopy < 0 ) tocopy = -tocopy;
1941 srcpixel = bmpImage->data + lines*tocopy;
1942 for(h = lines ; h-- ; ) {
1944 memcpy(ptr,srcpixel,tocopy);
1945 ptr = (LPBYTE)(dstbits+=linebytes);
1952 DWORD *srcpixel, buf;
1954 DWORD *ptr=(DWORD *)dstbits;
1955 int quotient = dstwidth / 4;
1956 int remainder = dstwidth % 4;
1959 /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
1960 if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 )
1962 for(h = lines - 1; h >= 0; h--)
1964 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1966 for (x = 0; x < quotient; x++) { /* do 4 dwords source, 3 dwords dest at a time*/
1967 buf = ((*srcpixel++)&0x00ffffff); /* b1, g1, r1*/
1968 *ptr++ = buf | ((*srcpixel)<<24); /* b2 */
1969 buf = ((*srcpixel++>>8)&0x0000ffff); /* g2, r2 */
1970 *ptr++ = buf | ((*srcpixel)<<16); /* b3, g3 */
1971 buf = ((*srcpixel++>>16)&0x000000ff); /* r3 */
1972 *ptr++ = buf | ((*srcpixel++)<<8); /* b4, g4, r4 */
1974 for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
1977 *(WORD*)bits = buf; /* b, g */
1978 *(bits+2) = buf>>16; /* r */
1980 ptr = (DWORD*)(dstbits+=linebytes);
1984 /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
1985 else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff )
1987 for(h = lines - 1; h >= 0; h--)
1989 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1991 for (x = 0; x < quotient; x++) { /* do 4 dwords source, 3 dwords dest at a time */
1993 val = ((buf&0xff0000)>>16) | (buf&0xff00) | ((buf&0xff)<<16); /* b1, g1, r1 */
1995 *ptr++ = val | ((buf&0xff0000)<<8); /* b2 */
1996 val = ((buf&0xff00)>>8) | ((buf&0xff)<<8); /* g2, r2 */
1998 *ptr++ = val | (buf&0xff0000) | ((buf&0xff00)<<16); /* b3, g3 */
1999 val = (buf&0xff); /* r3 */
2001 *ptr++ = val | ((buf&0xff0000)>>8) | ((buf&0xff00)<<8) | (buf<<24); /* b4, g4, r4 */
2003 for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
2006 *(WORD*)bits = (buf&0xff00) | ((buf&0xff0000)>>16) ; /* b, g */
2007 *(bits+2) = buf; /* r */
2009 ptr = (DWORD*)(dstbits+=linebytes);
2012 else goto notsupported;
2019 LPBYTE bits = dstbits;
2022 /* ==== 555 BGR bitmap to 24 BGR dib ==== */
2023 if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 )
2025 for (h = lines - 1; h >= 0; h--) {
2026 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2027 for (x = 0; x < srcwidth; x++, bits += 3) {
2029 bits[2] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2030 bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07)); /*Green*/
2031 bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2033 bits = (dstbits += linebytes);
2036 /* ==== 555 RGB bitmap to 24 RGB dib==== */
2037 else if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f )
2039 for (h = lines - 1; h >= 0; h--) {
2040 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2041 for (x = 0; x < srcwidth; x++, bits += 3) {
2043 bits[0] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2044 bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07)); /*Green*/
2045 bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2047 bits = (dstbits += linebytes);
2050 else goto notsupported;
2057 LPBYTE bits = dstbits;
2060 /* ==== 565 BGR bitmap to 24 BGR dib ==== */
2061 if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0xf800 )
2063 for (h = lines - 1; h >= 0; h--) {
2064 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2065 for (x = 0; x < srcwidth; x++, bits += 3) {
2067 bits[2] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2068 bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2069 bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2071 bits = (dstbits += linebytes);
2074 /* ==== 565 RGB bitmap to 24 BGR dib ==== */
2075 else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x1f )
2077 for (h = lines - 1; h >= 0; h--) {
2078 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2079 for (x = 0; x < srcwidth; x++, bits += 3) {
2081 bits[0] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2082 bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2083 bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2085 bits = (dstbits += linebytes);
2088 else goto notsupported;
2093 /* ==== monochrome bitmap to 24 BGR dib ==== */
2095 /* ==== 4 colormap bitmap to 24 BGR dib ==== */
2096 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2098 LPBYTE bits = dstbits;
2101 for (h = lines - 1; h >= 0; h--) {
2102 for (x = 0; x < dstwidth; x++) {
2103 val = srccolors[XGetPixel(bmpImage, x, h)];
2104 *bits++ = val.peBlue;
2105 *bits++ = val.peGreen;
2106 *bits++ = val.peRed;
2108 bits = (dstbits += linebytes);
2111 else goto notsupported;
2116 /* ==== 8 colormap bitmap to 24 BGR dib ==== */
2117 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors)
2120 LPBYTE bits = dstbits;
2123 for (h = lines - 1; h >= 0; h--) {
2124 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
2125 for (x = 0; x < dstwidth; x++ ) {
2126 val = srccolors[(int)*srcpixel++];
2127 *bits++ = val.peBlue; /*Blue*/
2128 *bits++ = val.peGreen; /*Green*/
2129 *bits++ = val.peRed; /*Red*/
2131 bits = (dstbits += linebytes);
2134 else goto notsupported;
2141 LPBYTE bits = dstbits;
2143 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
2144 bmpImage->depth, (int)bmpImage->red_mask,
2145 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2146 for (h = lines - 1; h >= 0; h--)
2148 for (x = 0; x < dstwidth; x++, bits += 3)
2150 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
2151 bits[0] = GetBValue(pixel);
2152 bits[1] = GetGValue(pixel);
2153 bits[2] = GetRValue(pixel);
2155 bits = (dstbits += linebytes);
2163 /***********************************************************************
2164 * X11DRV_DIB_SetImageBits_32
2166 * SetDIBits for a 32-bit deep DIB.
2168 static void X11DRV_DIB_SetImageBits_32( int lines, const BYTE *srcbits,
2169 DWORD srcwidth, DWORD dstwidth, int left,
2170 DC *dc, XImage *bmpImage )
2175 DWORD linebytes = (srcwidth * 4);
2180 srcbits = srcbits + ( linebytes * (lines-1) );
2181 linebytes = -linebytes;
2184 ptr = (DWORD *) srcbits + left;
2186 switch ( bmpImage->depth )
2190 /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
2191 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff) {
2192 for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
2193 memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
2197 /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
2198 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
2202 for (h = lines - 1; h >= 0; h--) {
2203 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2204 for (x = 0; x < dstwidth; x++, ptr++) {
2205 *dstpixel++ = ((*ptr << 16) & 0xff0000) | (*ptr & 0xff00) | ((*ptr >> 16) & 0xff);
2207 ptr = (DWORD *) (srcbits += linebytes) + left;
2210 else goto notsupported;
2215 /* ==== 32 BGR dib to 555 BGR bitmap ==== */
2216 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
2220 for (h = lines - 1; h >= 0; h--) {
2221 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2222 for (x = 0; x < dstwidth; x++, ptr++) {
2223 *dstpixel++ = (WORD) (((*ptr >> 9) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 3) & 0x001f));
2225 ptr = (DWORD *) (srcbits += linebytes) + left;
2228 /* ==== 32 BGR dib to 555 RGB bitmap ==== */
2229 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
2233 for (h = lines - 1; h >= 0; h--) {
2234 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2235 for (x = 0; x < dstwidth; x++, ptr++) {
2236 *dstpixel++ = (WORD) (((*ptr << 7) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 19) & 0x001f));
2238 ptr = (DWORD *) (srcbits += linebytes) + left;
2241 else goto notsupported;
2246 /* ==== 32 BGR dib to 565 BGR bitmap ==== */
2247 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2251 for (h = lines - 1; h >= 0; h--) {
2252 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2253 for (x = 0; x < dstwidth; x++, ptr++) {
2254 *dstpixel++ = (WORD) (((*ptr >> 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 3) & 0x001f));
2256 ptr = (DWORD *) (srcbits += linebytes) + left;
2259 /* ==== 32 BGR dib to 565 RGB bitmap ==== */
2260 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
2264 for (h = lines - 1; h >= 0; h--) {
2265 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2266 for (x = 0; x < dstwidth; x++, ptr++) {
2267 *dstpixel++ = (WORD) (((*ptr << 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 19) & 0x001f));
2269 ptr = (DWORD *) (srcbits += linebytes) + left;
2272 else goto notsupported;
2280 LPBYTE bits = (LPBYTE)srcbits + left*4;
2282 for (h = lines - 1; h >= 0; h--) {
2283 for (x = left; x < dstwidth+left; x++, bits += 4)
2284 XPutPixel( bmpImage, x, h,
2285 X11DRV_PALETTE_ToPhysical(dc, RGB( bits[2], bits[1], *bits )));
2286 bits = (LPBYTE)(srcbits += linebytes) + left * 4;
2293 FIXME("32 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
2299 /***********************************************************************
2300 * X11DRV_DIB_GetImageBits_32
2302 * GetDIBits for an 32-bit deep DIB.
2304 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
2305 DWORD dstwidth, DWORD srcwidth,
2306 PALETTEENTRY *srccolors, XImage *bmpImage )
2312 /* align to 32 bit */
2313 DWORD linebytes = (srcwidth * 4);
2314 DWORD copybytes = linebytes;
2319 dstbits = dstbits + ( linebytes * (lines-1) );
2320 linebytes = -linebytes;
2325 switch ( bmpImage->depth )
2329 /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
2330 if ( bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff )
2331 for (h = lines - 1; h >= 0; h--, dstbits+=linebytes)
2332 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, copybytes );
2334 /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
2335 else if ( bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000 )
2339 for (h = lines - 1; h >= 0; h--) {
2340 srcbits = bmpImage->data + h * bmpImage->bytes_per_line;
2341 for (x = 0; x < dstwidth; x++, bits+=4, srcbits+=2) {
2342 *(bits + 2) = *srcbits++;
2343 *(bits + 1) = *srcbits++;
2346 bits = (dstbits += linebytes);
2349 else goto notsupported;
2357 /* ==== 555 BGR bitmap to 32 BGR dib ==== */
2358 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
2360 for (h = lines - 1; h >= 0; h--) {
2361 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2362 for (x = 0; x < dstwidth; x++, bits+=2) {
2364 *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
2365 *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
2366 *bits = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2368 bits = (dstbits += linebytes);
2371 /* ==== 555 RGB bitmap to 32 BGR dib ==== */
2372 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
2374 for (h = lines - 1; h >= 0; h--) {
2375 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2376 for (x = 0; x < dstwidth; x++, bits+=2) {
2378 *bits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));/*Blue*/
2379 *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
2380 *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Red*/
2382 bits = (dstbits += linebytes);
2385 else goto notsupported;
2394 /* ==== 565 BGR bitmap to 32 BGR dib ==== */
2395 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2397 for (h = lines - 1; h >= 0; h--) {
2398 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2399 for (x = 0; x < srcwidth; x++, bits+=2) {
2401 *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
2402 *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2403 *bits = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2405 bits = (dstbits += linebytes);
2408 /* ==== 565 RGB bitmap to 32 BGR dib ==== */
2409 else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2411 for (h = lines - 1; h >= 0; h--) {
2412 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2413 for (x = 0; x < srcwidth; x++, bits+=2) {
2415 *bits++ = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));/*Blue*/
2416 *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2417 *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Red*/
2419 bits = (dstbits += linebytes);
2422 else goto notsupported;
2427 /* ==== monochrome bitmap to 32 BGR dib ==== */
2429 /* ==== 4 colormap bitmap to 32 BGR dib ==== */
2430 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2434 for (h = lines - 1; h >= 0; h--) {
2435 for (x = 0; x < dstwidth; x++) {
2436 val = srccolors[XGetPixel(bmpImage, x, h)];
2437 *bits++ = val.peBlue;
2438 *bits++ = val.peGreen;
2439 *bits++ = val.peRed;
2442 bits = (dstbits += linebytes);
2445 else goto notsupported;
2450 /* ==== 8 colormap bitmap to 32 BGR dib ==== */
2451 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2456 for (h = lines - 1; h >= 0; h--) {
2457 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
2458 for (x = 0; x < dstwidth; x++) {
2459 val = srccolors[(int)*srcpixel++];
2460 *bits++ = val.peBlue; /*Blue*/
2461 *bits++ = val.peGreen; /*Green*/
2462 *bits++ = val.peRed; /*Red*/
2465 bits = (dstbits += linebytes);
2468 else goto notsupported;
2473 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
2474 bmpImage->depth, (int)bmpImage->red_mask,
2475 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2476 for (h = lines - 1; h >= 0; h--)
2478 for (x = 0; x < dstwidth; x++, bits += 4)
2480 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
2481 bits[0] = GetBValue(pixel);
2482 bits[1] = GetGValue(pixel);
2483 bits[2] = GetRValue(pixel);
2485 bits = (dstbits += linebytes);
2491 /***********************************************************************
2492 * X11DRV_DIB_SetImageBits
2494 * Transfer the bits to an X image.
2495 * Helper function for SetDIBits() and SetDIBitsToDevice().
2496 * The Xlib critical section must be entered before calling this function.
2498 int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
2500 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
2503 if ( descr->dc && descr->dc->w.flags & DC_DIRTY )
2504 CLIPPING_UpdateGCRegion( descr->dc );
2507 bmpImage = descr->image;
2509 bmpImage = XCreateImage( display, X11DRV_GetVisual(), descr->depth, ZPixmap, 0, NULL,
2510 descr->infoWidth, lines, 32, 0 );
2511 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
2512 if(bmpImage->data == NULL) {
2513 ERR("Out of memory!");
2514 XDestroyImage( bmpImage );
2519 /* Transfer the pixels */
2520 switch(descr->infoBpp)
2523 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
2524 descr->width, descr->xSrc, (int *)(descr->colorMap),
2528 if (descr->compression) {
2529 XGetSubImage( display, descr->drawable, descr->xDest, descr->yDest,
2530 descr->width, descr->height, AllPlanes, ZPixmap,
2531 bmpImage, descr->xSrc, descr->ySrc );
2533 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
2534 descr->infoWidth, descr->width,
2535 descr->xSrc, (int *)(descr->colorMap),
2538 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
2539 descr->infoWidth, descr->width,
2540 descr->xSrc, (int*)(descr->colorMap),
2544 if (descr->compression) {
2545 XGetSubImage( display, descr->drawable, descr->xDest, descr->yDest,
2546 descr->width, descr->height, AllPlanes, ZPixmap,
2547 bmpImage, descr->xSrc, descr->ySrc );
2548 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
2549 descr->infoWidth, descr->width,
2550 descr->xSrc, (int *)(descr->colorMap),
2553 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
2554 descr->infoWidth, descr->width,
2555 descr->xSrc, (int *)(descr->colorMap),
2560 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
2561 descr->infoWidth, descr->width,
2562 descr->xSrc, descr->dc,
2563 descr->rMask, descr->gMask, descr->bMask,
2567 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
2568 descr->infoWidth, descr->width,
2569 descr->xSrc, descr->dc, bmpImage );
2572 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
2573 descr->infoWidth, descr->width,
2574 descr->xSrc, descr->dc,
2578 WARN("(%d): Invalid depth\n", descr->infoBpp );
2584 XShmPutImage( display, descr->drawable, descr->gc, bmpImage,
2585 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2586 descr->width, descr->height, FALSE );
2587 XSync( display, 0 );
2590 XPutImage( display, descr->drawable, descr->gc, bmpImage,
2591 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2592 descr->width, descr->height );
2594 if (!descr->image) XDestroyImage( bmpImage );
2598 /***********************************************************************
2599 * X11DRV_DIB_GetImageBits
2601 * Transfer the bits from an X image.
2602 * The Xlib critical section must be entered before calling this function.
2604 int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
2606 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
2610 bmpImage = descr->image;
2612 bmpImage = XCreateImage( display, X11DRV_GetVisual(), descr->depth, ZPixmap, 0, NULL,
2613 descr->infoWidth, lines, 32, 0 );
2614 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
2615 if(bmpImage->data == NULL) {
2616 ERR("Out of memory!");
2617 XDestroyImage( bmpImage );
2621 XGetSubImage( display, descr->drawable, descr->xDest, descr->yDest,
2622 descr->width, descr->height, AllPlanes, ZPixmap,
2623 bmpImage, descr->xSrc, descr->ySrc );
2625 /* Transfer the pixels */
2626 switch(descr->infoBpp)
2629 X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
2630 descr->infoWidth, descr->width,
2631 descr->colorMap, descr->palentry,
2636 if (descr->compression)
2637 FIXME("Compression not yet supported!\n");
2639 X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
2640 descr->infoWidth, descr->width,
2641 descr->colorMap, descr->palentry,
2646 if (descr->compression)
2647 FIXME("Compression not yet supported!\n");
2649 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
2650 descr->infoWidth, descr->width,
2651 descr->colorMap, descr->palentry,
2656 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
2657 descr->infoWidth,descr->width,
2658 descr->palentry, bmpImage );
2662 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
2663 descr->infoWidth,descr->width,
2664 descr->palentry, bmpImage );
2668 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
2669 descr->infoWidth, descr->width,
2670 descr->palentry, bmpImage );
2674 WARN("(%d): Invalid depth\n", descr->infoBpp );
2678 if (!descr->image) XDestroyImage( bmpImage );
2682 /*************************************************************************
2683 * X11DRV_SetDIBitsToDevice
2686 INT X11DRV_SetDIBitsToDevice( DC *dc, INT xDest, INT yDest, DWORD cx,
2687 DWORD cy, INT xSrc, INT ySrc,
2688 UINT startscan, UINT lines, LPCVOID bits,
2689 const BITMAPINFO *info, UINT coloruse )
2691 X11DRV_DIB_IMAGEBITS_DESCR descr;
2692 DWORD width, oldcy = cy;
2694 int height, tmpheight;
2695 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
2698 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
2699 &descr.infoBpp, &descr.compression ) == -1)
2702 if (height < 0) height = -height;
2703 if (!lines || (startscan >= height)) return 0;
2704 if (startscan + lines > height) lines = height - startscan;
2705 if (ySrc < startscan) ySrc = startscan;
2706 else if (ySrc >= startscan + lines) return 0;
2707 if (xSrc >= width) return 0;
2708 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
2709 if (xSrc + cx >= width) cx = width - xSrc;
2710 if (!cx || !cy) return 0;
2712 X11DRV_SetupGCForText( dc ); /* To have the correct colors */
2713 TSXSetFunction(display, physDev->gc, X11DRV_XROPfunction[dc->w.ROPmode-1]);
2715 switch (descr.infoBpp)
2720 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
2721 coloruse == DIB_PAL_COLORS ? dc : NULL, coloruse,
2722 dc->w.bitsPerPixel, info, &descr.nColorMap );
2723 if (!descr.colorMap) return 0;
2724 descr.rMask = descr.gMask = descr.bMask = 0;
2728 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
2729 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
2730 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
2735 descr.rMask = descr.gMask = descr.bMask = 0;
2740 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
2741 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
2742 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
2750 descr.palentry = NULL;
2751 descr.lines = tmpheight >= 0 ? lines : -lines;
2752 descr.infoWidth = width;
2753 descr.depth = dc->w.bitsPerPixel;
2754 descr.drawable = physDev->drawable;
2755 descr.gc = physDev->gc;
2757 descr.ySrc = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy)
2759 descr.xDest = dc->w.DCOrgX + XLPTODP( dc, xDest );
2760 descr.yDest = dc->w.DCOrgY + YLPTODP( dc, yDest ) +
2761 (tmpheight >= 0 ? oldcy-cy : 0);
2764 descr.useShm = FALSE;
2766 EnterCriticalSection( &X11DRV_CritSection );
2767 result = CALL_LARGE_STACK( X11DRV_DIB_SetImageBits, &descr );
2768 LeaveCriticalSection( &X11DRV_CritSection );
2770 if (descr.infoBpp <= 8)
2771 HeapFree(GetProcessHeap(), 0, descr.colorMap);
2775 /***********************************************************************
2776 * X11DRV_DIB_SetDIBits
2778 INT X11DRV_DIB_SetDIBits(
2779 BITMAPOBJ *bmp, DC *dc, UINT startscan,
2780 UINT lines, LPCVOID bits, const BITMAPINFO *info,
2781 UINT coloruse, HBITMAP hbitmap)
2783 X11DRV_DIB_IMAGEBITS_DESCR descr;
2784 int height, tmpheight;
2789 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
2790 &descr.infoBpp, &descr.compression ) == -1)
2794 if (height < 0) height = -height;
2795 if (!lines || (startscan >= height))
2798 if (startscan + lines > height) lines = height - startscan;
2800 switch (descr.infoBpp)
2805 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
2806 coloruse == DIB_PAL_COLORS ? descr.dc : NULL, coloruse,
2807 bmp->bitmap.bmBitsPixel,
2808 info, &descr.nColorMap );
2809 if (!descr.colorMap) return 0;
2810 descr.rMask = descr.gMask = descr.bMask = 0;
2814 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
2815 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
2816 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
2821 descr.rMask = descr.gMask = descr.bMask = 0;
2826 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
2827 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
2828 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
2836 if(!bmp->physBitmap)
2837 X11DRV_CreateBitmap(hbitmap);
2841 descr.palentry = NULL;
2842 descr.lines = tmpheight >= 0 ? lines : -lines;
2843 descr.depth = bmp->bitmap.bmBitsPixel;
2844 descr.drawable = (Pixmap)bmp->physBitmap;
2845 descr.gc = BITMAP_GC(bmp);
2849 descr.yDest = height - startscan - lines;
2850 descr.width = bmp->bitmap.bmWidth;
2851 descr.height = lines;
2852 descr.useShm = FALSE;
2854 EnterCriticalSection( &X11DRV_CritSection );
2855 result = CALL_LARGE_STACK( X11DRV_DIB_SetImageBits, &descr );
2856 LeaveCriticalSection( &X11DRV_CritSection );
2858 if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);
2863 /***********************************************************************
2864 * X11DRV_DIB_GetDIBits
2866 INT X11DRV_DIB_GetDIBits(
2867 BITMAPOBJ *bmp, DC *dc, UINT startscan,
2868 UINT lines, LPVOID bits, BITMAPINFO *info,
2869 UINT coloruse, HBITMAP hbitmap)
2871 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
2872 X11DRV_DIB_IMAGEBITS_DESCR descr;
2873 PALETTEOBJ * palette;
2875 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
2876 lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
2877 (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
2880 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
2883 if( lines > info->bmiHeader.biHeight ) lines = info->bmiHeader.biHeight;
2884 if( startscan >= bmp->bitmap.bmHeight ) return FALSE;
2886 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
2887 &descr.infoBpp, &descr.compression ) == -1)
2890 switch (descr.infoBpp)
2896 descr.rMask = descr.gMask = descr.bMask = 0;
2900 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
2901 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
2902 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
2906 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
2907 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
2908 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
2913 if(!bmp->physBitmap)
2914 X11DRV_CreateBitmap(hbitmap);
2918 descr.palentry = palette->logpalette.palPalEntry;
2920 descr.lines = lines;
2921 descr.depth = bmp->bitmap.bmBitsPixel;
2922 descr.drawable = (Pixmap)bmp->physBitmap;
2923 descr.gc = BITMAP_GC(bmp);
2925 descr.ySrc = startscan;
2928 descr.width = bmp->bitmap.bmWidth;
2929 descr.height = bmp->bitmap.bmHeight;
2930 descr.colorMap = info->bmiColors;
2933 descr.useShm = (dib->shminfo.shmid != -1);
2935 descr.useShm = FALSE;
2937 EnterCriticalSection( &X11DRV_CritSection );
2939 descr.image = (XImage *)CALL_LARGE_STACK( X11DRV_BITMAP_GetXImage, bmp );
2940 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits, &descr );
2942 LeaveCriticalSection( &X11DRV_CritSection );
2944 if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
2945 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
2946 info->bmiHeader.biWidth,
2947 info->bmiHeader.biHeight,
2948 info->bmiHeader.biBitCount );
2950 info->bmiHeader.biCompression = 0;
2952 GDI_HEAP_UNLOCK( dc->w.hPalette );
2957 /***********************************************************************
2958 * DIB_DoProtectDIBSection
2960 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
2962 DIBSECTION *dib = bmp->dib;
2963 INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
2964 : -dib->dsBm.bmHeight;
2965 INT totalSize = dib->dsBmih.biSizeImage? dib->dsBmih.biSizeImage
2966 : dib->dsBm.bmWidthBytes * effHeight;
2969 VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
2970 TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
2973 /***********************************************************************
2974 * X11DRV_DIB_DoUpdateDIBSection
2976 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
2978 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
2979 X11DRV_DIB_IMAGEBITS_DESCR descr;
2981 if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
2982 &descr.infoBpp, &descr.compression ) == -1)
2986 descr.palentry = NULL;
2987 descr.image = dib->image;
2988 descr.colorMap = (RGBQUAD *)dib->colorMap;
2989 descr.nColorMap = dib->nColorMap;
2990 descr.bits = dib->dibSection.dsBm.bmBits;
2991 descr.depth = bmp->bitmap.bmBitsPixel;
2993 switch (descr.infoBpp)
2999 descr.rMask = descr.gMask = descr.bMask = 0;
3003 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
3004 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
3005 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
3009 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff;
3010 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0xff00;
3011 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0xff0000;
3016 descr.drawable = (Pixmap)bmp->physBitmap;
3017 descr.gc = BITMAP_GC(bmp);
3022 descr.width = bmp->bitmap.bmWidth;
3023 descr.height = bmp->bitmap.bmHeight;
3024 descr.useShm = (dib->shminfo.shmid != -1);
3028 TRACE("Copying from Pixmap to DIB bits\n");
3029 EnterCriticalSection( &X11DRV_CritSection );
3030 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits, &descr );
3031 LeaveCriticalSection( &X11DRV_CritSection );
3035 TRACE("Copying from DIB bits to Pixmap\n");
3036 EnterCriticalSection( &X11DRV_CritSection );
3037 CALL_LARGE_STACK( X11DRV_DIB_SetImageBits, &descr );
3038 LeaveCriticalSection( &X11DRV_CritSection );
3042 /***********************************************************************
3043 * X11DRV_DIB_FaultHandler
3045 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
3047 BOOL handled = FALSE;
3050 bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
3051 if (!bmp) return FALSE;
3054 switch (((X11DRV_DIBSECTION *) bmp->dib)->status)
3056 case X11DRV_DIB_GdiMod:
3057 TRACE("called in status DIB_GdiMod\n" );
3058 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3059 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3060 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3061 ((X11DRV_DIBSECTION *) bmp->dib)->status = X11DRV_DIB_InSync;
3065 case X11DRV_DIB_InSync:
3066 TRACE("called in status X11DRV_DIB_InSync\n" );
3067 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3068 ((X11DRV_DIBSECTION *) bmp->dib)->status = X11DRV_DIB_AppMod;
3072 case X11DRV_DIB_AppMod:
3073 FIXME("called in status X11DRV_DIB_AppMod: this can't happen!\n" );
3076 case X11DRV_DIB_NoHandler:
3077 FIXME("called in status DIB_NoHandler: this can't happen!\n" );
3081 GDI_HEAP_UNLOCK( (HBITMAP)res );
3085 /***********************************************************************
3086 * X11DRV_DIB_UpdateDIBSection
3088 void X11DRV_DIB_UpdateDIBSection(DC *dc, BOOL toDIB)
3092 /* Ensure this is a Compatible DC that has a DIB section selected */
3095 if (!(dc->w.flags & DC_MEMORY)) return;
3097 bmp = (BITMAPOBJ *)GDI_GetObjPtr( dc->w.hBitmap, BITMAP_MAGIC );
3102 GDI_HEAP_UNLOCK(dc->w.hBitmap);
3108 /* Prepare for access to the DIB by GDI functions */
3110 switch (((X11DRV_DIBSECTION *) bmp->dib)->status)
3113 case X11DRV_DIB_NoHandler:
3114 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
3117 case X11DRV_DIB_GdiMod:
3118 TRACE("fromDIB called in status X11DRV_DIB_GdiMod\n" );
3122 case X11DRV_DIB_InSync:
3123 TRACE("fromDIB called in status X11DRV_DIB_InSync\n" );
3127 case X11DRV_DIB_AppMod:
3128 TRACE("fromDIB called in status X11DRV_DIB_AppMod\n" );
3129 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
3130 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3131 ((X11DRV_DIBSECTION *) bmp->dib)->status = X11DRV_DIB_InSync;
3137 /* Acknowledge write access to the DIB by GDI functions */
3139 switch (((X11DRV_DIBSECTION *) bmp->dib)->status)
3142 case X11DRV_DIB_NoHandler:
3143 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3146 case X11DRV_DIB_GdiMod:
3147 TRACE(" toDIB called in status X11DRV_DIB_GdiMod\n" );
3151 case X11DRV_DIB_InSync:
3152 TRACE(" toDIB called in status X11DRV_DIB_InSync\n" );
3153 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3154 ((X11DRV_DIBSECTION *) bmp->dib)->status = X11DRV_DIB_GdiMod;
3157 case X11DRV_DIB_AppMod:
3158 FIXME(" toDIB called in status X11DRV_DIB_AppMod: "
3159 "this can't happen!\n" );
3164 GDI_HEAP_UNLOCK(dc->w.hBitmap);
3167 /***********************************************************************
3168 * X11DRV_DIB_CreateDIBSection16
3170 HBITMAP16 X11DRV_DIB_CreateDIBSection16(
3171 DC *dc, BITMAPINFO *bmi, UINT16 usage,
3172 SEGPTR *bits, HANDLE section,
3175 HBITMAP res = X11DRV_DIB_CreateDIBSection(dc, bmi, usage, NULL,
3179 BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
3180 if ( bmp && bmp->dib )
3182 DIBSECTION *dib = bmp->dib;
3183 INT height = dib->dsBm.bmHeight >= 0 ?
3184 dib->dsBm.bmHeight : -dib->dsBm.bmHeight;
3185 INT size = dib->dsBmih.biSizeImage ?
3186 dib->dsBmih.biSizeImage : dib->dsBm.bmWidthBytes * height;
3187 if ( dib->dsBm.bmBits )
3189 ((X11DRV_DIBSECTION *) bmp->dib)->selector =
3190 SELECTOR_AllocBlock( dib->dsBm.bmBits, size,
3191 SEGMENT_DATA, FALSE, FALSE );
3193 TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
3194 dib->dsBm.bmBits, size, ((X11DRV_DIBSECTION *) bmp->dib)->selector,
3195 PTR_SEG_OFF_TO_SEGPTR(((X11DRV_DIBSECTION *) bmp->dib)->selector, 0));
3197 GDI_HEAP_UNLOCK( res );
3200 *bits = PTR_SEG_OFF_TO_SEGPTR( ((X11DRV_DIBSECTION *) bmp->dib)->selector, 0 );
3206 /***********************************************************************
3207 * X11DRV_XShmErrorHandler
3210 static int XShmErrorHandler(Display *dpy, XErrorEvent *event)
3216 /***********************************************************************
3217 * X11DRV_XShmCreateImage
3221 extern BOOL X11DRV_XShmCreateImage(XImage** image, int width, int height, int bpp,
3222 XShmSegmentInfo* shminfo)
3224 int (*WineXHandler)(Display *, XErrorEvent *);
3226 *image = TSXShmCreateImage(display, X11DRV_GetVisual(), bpp, ZPixmap, NULL, shminfo, width, height);
3227 if( *image != NULL )
3229 EnterCriticalSection( &X11DRV_CritSection );
3230 shminfo->shmid = shmget(IPC_PRIVATE, (*image)->bytes_per_line * height,
3232 if( shminfo->shmid != -1 )
3234 shminfo->shmaddr = (*image)->data = shmat(shminfo->shmid, 0, 0);
3235 if( shminfo->shmaddr != (char*)-1 )
3237 shminfo->readOnly = FALSE;
3238 if( TSXShmAttach( display, shminfo ) != 0)
3240 /* Reset the error flag */
3242 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3243 XSync( display, 0 );
3247 shmctl(shminfo->shmid, IPC_RMID, 0);
3249 XSetErrorHandler(WineXHandler);
3250 LeaveCriticalSection( &X11DRV_CritSection );
3252 return TRUE; /* Success! */
3254 /* An error occured */
3256 XSetErrorHandler(WineXHandler);
3258 shmdt(shminfo->shmaddr);
3260 shmctl(shminfo->shmid, IPC_RMID, 0);
3263 XDestroyImage(*image);
3264 LeaveCriticalSection( &X11DRV_CritSection );
3272 /***********************************************************************
3273 * X11DRV_DIB_CreateDIBSection
3275 HBITMAP X11DRV_DIB_CreateDIBSection(
3276 DC *dc, BITMAPINFO *bmi, UINT usage,
3277 LPVOID *bits, HANDLE section,
3281 BITMAPOBJ *bmp = NULL;
3282 X11DRV_DIBSECTION *dib = NULL;
3283 int *colorMap = NULL;
3286 /* Fill BITMAP32 structure with DIB data */
3287 BITMAPINFOHEADER *bi = &bmi->bmiHeader;
3288 INT effHeight, totalSize;
3291 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
3292 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
3293 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
3295 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
3297 bm.bmWidth = bi->biWidth;
3298 bm.bmHeight = effHeight;
3299 bm.bmWidthBytes = DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
3300 bm.bmPlanes = bi->biPlanes;
3301 bm.bmBitsPixel = bi->biBitCount;
3304 /* Get storage location for DIB bits */
3305 totalSize = bi->biSizeImage? bi->biSizeImage : bm.bmWidthBytes * effHeight;
3308 bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS,
3309 0L, offset, totalSize);
3311 bm.bmBits = VirtualAlloc(NULL, totalSize,
3312 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
3314 /* Create Color Map */
3315 if (bm.bmBits && bm.bmBitsPixel <= 8)
3316 colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? dc : NULL,
3317 usage, bm.bmBitsPixel, bmi, &nColorMap );
3319 /* Allocate Memory for DIB and fill structure */
3321 dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
3324 dib->dibSection.dsBm = bm;
3325 dib->dibSection.dsBmih = *bi;
3327 /* Set dsBitfields values */
3328 if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
3330 dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
3332 else switch( bi->biBitCount )
3335 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
3336 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
3337 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
3341 dib->dibSection.dsBitfields[0] = 0xff;
3342 dib->dibSection.dsBitfields[1] = 0xff00;
3343 dib->dibSection.dsBitfields[2] = 0xff0000;
3347 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff;
3348 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0xff00;
3349 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0xff0000;
3352 dib->dibSection.dshSection = section;
3353 dib->dibSection.dsOffset = offset;
3355 dib->status = X11DRV_DIB_NoHandler;
3358 dib->nColorMap = nColorMap;
3359 dib->colorMap = colorMap;
3362 /* Create Device Dependent Bitmap and add DIB pointer */
3365 res = CreateDIBitmap(dc->hSelf, bi, 0, NULL, bmi, usage);
3368 bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
3371 bmp->dib = (DIBSECTION *) dib;
3373 if(!bmp->physBitmap)
3374 X11DRV_CreateBitmap(res);
3382 if (TSXShmQueryExtension(display) &&
3383 X11DRV_XShmCreateImage( &dib->image, bm.bmWidth, effHeight,
3384 bmp->bitmap.bmBitsPixel, &dib->shminfo ) )
3386 ; /* Created Image */
3388 XCREATEIMAGE( dib->image, bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
3389 dib->shminfo.shmid = -1;
3393 /* Clean up in case of errors */
3394 if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
3396 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
3397 res, bmp, dib, bm.bmBits);
3401 UnmapViewOfFile(bm.bmBits), bm.bmBits = NULL;
3403 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
3406 if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
3407 if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
3408 if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
3409 if (res) { DeleteObject(res); res = 0; }
3412 /* Install fault handler, if possible */
3415 if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
3417 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3418 if (dib) dib->status = X11DRV_DIB_InSync;
3422 /* Return BITMAP handle and storage location */
3423 if (res) GDI_HEAP_UNLOCK(res);
3424 if (bm.bmBits && bits) *bits = bm.bmBits;
3428 /***********************************************************************
3429 * X11DRV_DIB_DeleteDIBSection
3431 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
3433 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3437 if (dib->shminfo.shmid != -1)
3439 TSXShmDetach (display, &(dib->shminfo));
3440 XDestroyImage (dib->image);
3441 shmdt (dib->shminfo.shmaddr);
3442 dib->shminfo.shmid = -1;
3445 XDestroyImage( dib->image );
3449 HeapFree(GetProcessHeap(), 0, dib->colorMap);
3453 WORD count = (GET_SEL_LIMIT( dib->selector ) >> 16) + 1;
3454 SELECTOR_FreeBlock( dib->selector, count );
3459 /**************************************************************************
3460 * X11DRV_DIB_CreateDIBFromPixmap
3462 * Allocates a packed DIB and copies the Pixmap data into it.
3463 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
3465 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
3468 BITMAPOBJ *pBmp = NULL;
3469 HGLOBAL hPackedDIB = 0;
3471 /* Allocates an HBITMAP which references the Pixmap passed to us */
3472 hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap);
3475 TRACE("\tCould not create bitmap header for Pixmap\n");
3480 * Create a packed DIB from the Pixmap wrapper bitmap created above.
3481 * A packed DIB contains a BITMAPINFO structure followed immediately by
3482 * an optional color palette and the pixel data.
3484 hPackedDIB = DIB_CreateDIBFromBitmap(hdc, hBmp);
3486 /* Get a pointer to the BITMAPOBJ structure */
3487 pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3489 /* We can now get rid of the HBITMAP wrapper we created earlier.
3490 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
3494 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
3495 pBmp->physBitmap = NULL;
3501 TRACE("\tReturning packed DIB %x\n", hPackedDIB);
3506 /**************************************************************************
3507 * X11DRV_DIB_CreatePixmapFromDIB
3509 * Creates a Pixmap from a packed DIB
3511 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
3513 Pixmap pixmap = None;
3515 BITMAPOBJ *pBmp = NULL;
3516 LPBYTE pPackedDIB = NULL;
3517 LPBITMAPINFO pbmi = NULL;
3518 LPBITMAPINFOHEADER pbmiHeader = NULL;
3519 LPBYTE pbits = NULL;
3521 /* Get a pointer to the packed DIB's data */
3522 pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
3523 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
3524 pbmi = (LPBITMAPINFO)pPackedDIB;
3525 pbits = (LPBYTE)(pPackedDIB
3526 + DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
3528 /* Create a DDB from the DIB */
3530 hBmp = CreateDIBitmap(hdc,
3537 GlobalUnlock(hPackedDIB);
3539 TRACE("CreateDIBitmap returned %x\n", hBmp);
3541 /* Retrieve the internal Pixmap from the DDB */
3543 pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3545 pixmap = (Pixmap)pBmp->physBitmap;
3546 /* clear the physBitmap so that we can steal its pixmap */
3547 pBmp->physBitmap = NULL;
3550 /* Delete the DDB we created earlier now that we have stolen its pixmap */
3553 TRACE("\tReturning Pixmap %ld\n", pixmap);
3557 #endif /* !defined(X_DISPLAY_MISSING) */