2 * X11DRV device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
13 # ifdef HAVE_SYS_SHM_H
16 # ifdef HAVE_SYS_IPC_H
19 #endif /* defined(HAVE_LIBXXSHM) */
25 #include "debugtools.h"
29 #include "selectors.h"
32 DEFAULT_DEBUG_CHANNEL(bitmap);
33 DECLARE_DEBUG_CHANNEL(x11drv);
35 static int bitmapDepthTable[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
36 static int ximageDepthTable[] = { 0, 0, 0, 0, 0, 0, 0 };
38 static int XShmErrorFlag = 0;
40 /***********************************************************************
43 BOOL X11DRV_DIB_Init(void)
48 for( i = 0; bitmapDepthTable[i]; i++ )
50 testimage = TSXCreateImage(display, X11DRV_GetVisual(),
51 bitmapDepthTable[i], ZPixmap, 0, NULL, 1, 1, 32, 20 );
52 if( testimage ) ximageDepthTable[i] = testimage->bits_per_pixel;
54 TSXDestroyImage(testimage);
60 /***********************************************************************
61 * X11DRV_DIB_GetXImageWidthBytes
63 * Return the width of an X image in bytes
65 int X11DRV_DIB_GetXImageWidthBytes( int width, int depth )
69 if (!ximageDepthTable[0]) {
72 for( i = 0; bitmapDepthTable[i] ; i++ )
73 if( bitmapDepthTable[i] == depth )
74 return (4 * ((width * ximageDepthTable[i] + 31)/32));
76 WARN("(%d): Unsupported depth\n", depth );
80 /***********************************************************************
81 * X11DRV_DIB_GenColorMap
83 * Fills the color map of a bitmap palette. Should not be called
84 * for a >8-bit deep bitmap.
86 int *X11DRV_DIB_GenColorMap( DC *dc, int *colorMapping,
87 WORD coloruse, WORD depth, BOOL quads,
88 const void *colorPtr, int start, int end )
92 if (coloruse == DIB_RGB_COLORS)
96 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
98 if (depth == 1) /* Monochrome */
99 for (i = start; i < end; i++, rgb++)
100 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
101 rgb->rgbBlue > 255*3/2);
103 for (i = start; i < end; i++, rgb++)
104 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbRed,
110 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
112 if (depth == 1) /* Monochrome */
113 for (i = start; i < end; i++, rgb++)
114 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
115 rgb->rgbtBlue > 255*3/2);
117 for (i = start; i < end; i++, rgb++)
118 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, RGB(rgb->rgbtRed,
123 else /* DIB_PAL_COLORS */
125 WORD * index = (WORD *)colorPtr;
127 for (i = start; i < end; i++, index++)
128 colorMapping[i] = X11DRV_PALETTE_ToPhysical( dc, PALETTEINDEX(*index) );
134 /***********************************************************************
135 * X11DRV_DIB_BuildColorMap
137 * Build the color map from the bitmap palette. Should not be called
138 * for a >8-bit deep bitmap.
140 int *X11DRV_DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth,
141 const BITMAPINFO *info, int *nColors )
148 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
150 colors = info->bmiHeader.biClrUsed;
151 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
152 colorPtr = (WORD *)info->bmiColors;
154 else /* assume BITMAPCOREINFO */
156 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
157 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
162 ERR("called with >256 colors!\n");
166 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
167 colors * sizeof(int) )))
171 return X11DRV_DIB_GenColorMap( dc, colorMapping, coloruse, depth,
172 isInfo, colorPtr, 0, colors);
176 /***********************************************************************
177 * X11DRV_DIB_MapColor
179 int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
183 if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
186 for (color = 0; color < nPhysMap; color++)
187 if (physMap[color] == phys)
190 WARN("Strange color %08x\n", phys);
195 /*********************************************************************
196 * X11DRV_DIB_GetNearestIndex
198 * Helper for X11DRV_DIB_GetDIBits.
199 * Returns the nearest colour table index for a given RGB.
200 * Nearest is defined by minimizing the sum of the squares.
202 static INT X11DRV_DIB_GetNearestIndex(RGBQUAD *colormap, int numColors, BYTE r, BYTE g, BYTE b)
204 INT i, best = -1, diff, bestdiff = -1;
207 for(color = colormap, i = 0; i < numColors; color++, i++) {
208 diff = (r - color->rgbRed) * (r - color->rgbRed) +
209 (g - color->rgbGreen) * (g - color->rgbGreen) +
210 (b - color->rgbBlue) * (b - color->rgbBlue);
213 if(best == -1 || diff < bestdiff) {
221 /***********************************************************************
222 * X11DRV_DIB_SetImageBits_1_Line
224 * Handles a single line of 1 bit data.
226 static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth, int left, int *colors,
227 XImage *bmpImage, int h, const BYTE *bits)
232 if((extra = (left & 7)) != 0) {
239 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
240 for (i = dstwidth/8, x = left; i > 0; i--)
243 XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
244 XPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] );
245 XPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] );
246 XPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] );
247 XPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] );
248 XPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] );
249 XPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] );
250 XPutPixel( bmpImage, x++, h, colors[pix & 1] );
255 case 7: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
256 case 6: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
257 case 5: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
258 case 4: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
259 case 3: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
260 case 2: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
261 case 1: XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
265 /***********************************************************************
266 * X11DRV_DIB_SetImageBits_1
268 * SetDIBits for a 1-bit deep DIB.
270 static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
271 DWORD srcwidth, DWORD dstwidth, int left,
272 int *colors, XImage *bmpImage )
277 DWORD linebytes = ((srcwidth + 31) & ~31) / 8;
280 for (h = lines-1; h >=0; h--) {
281 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
283 srcbits += linebytes;
287 for (h = 0; h < lines; h++) {
288 X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
290 srcbits += linebytes;
295 /***********************************************************************
296 * X11DRV_DIB_GetImageBits_1
298 * GetDIBits for a 1-bit deep DIB.
300 static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
301 DWORD dstwidth, DWORD srcwidth,
302 RGBQUAD *colors, PALETTEENTRY *srccolors,
310 DWORD linebytes = ((dstwidth + 31) & ~31) / 8;
314 dstbits = dstbits + linebytes * (lines - 1);
315 linebytes = -linebytes;
320 switch(bmpImage->depth) {
323 /* ==== monochrome bitmap to monochrome dib ==== */
325 /* ==== 4 colormap bitmap to monochrome dib ==== */
326 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
330 for (h = lines - 1; h >= 0; h--) {
331 for (x = 0; x < dstwidth; x++) {
332 val = srccolors[XGetPixel(bmpImage, x, h)];
333 if (!(x&7)) *bits = 0;
334 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2,
337 val.peBlue) << (7 - (x & 7)));
338 if ((x&7)==7) bits++;
340 bits = (dstbits += linebytes);
343 else goto notsupported;
348 /* ==== 8 colormap bitmap to monochrome dib ==== */
349 if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
354 for( h = lines- 1; h >= 0; h-- ) {
355 srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
356 for( x = 0; x < dstwidth; x++ ) {
357 if (!(x&7)) *bits = 0;
358 val = srccolors[(int)*srcpixel++];
359 *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 2,
362 val.peBlue) << (7-(x&7)) );
363 if ((x&7)==7) bits++;
365 bits = (dstbits += linebytes);
368 else goto notsupported;
377 /* ==== 555 BGR bitmap to monochrome dib ==== */
378 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
380 for( h = lines - 1; h >= 0; h--) {
381 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
382 for( x = 0; x < dstwidth; x++) {
383 if (!(x&7)) *bits = 0;
385 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
386 ((val >> 7) & 0xf8) |
388 ((val >> 2) & 0xf8) |
390 ((val << 3) & 0xf8) |
391 ((val >> 2) & 0x7) ) << (7-(x&7)) );
392 if ((x&7)==7) bits++;
394 bits = (dstbits += linebytes);
397 /* ==== 555 RGB bitmap to monochrome dib ==== */
398 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
400 for( h = lines - 1; h >= 0; h--)
402 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
403 for( x = 0; x < dstwidth; x++) {
404 if (!(x&1)) *bits = 0;
406 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
407 ((val << 3) & 0xf8) |
409 ((val >> 2) & 0xf8) |
411 ((val >> 7) & 0xf8) |
412 ((val >> 12) & 0x7) ) << (7-(x&7)) );
413 if ((x&7)==7) bits++;
415 bits = (dstbits += linebytes);
418 else goto notsupported;
427 /* ==== 565 BGR bitmap to monochrome dib ==== */
428 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
430 for( h = lines - 1; h >= 0; h--)
432 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
433 for( x = 0; x < dstwidth; x++) {
434 if (!(x&7)) *bits = 0;
436 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
437 ((val >> 8) & 0xf8) |
439 ((val >> 3) & 0xfc) |
441 ((val << 3) & 0xf8) |
442 ((val >> 2) & 0x7) ) << (7-(x&7)) );
443 if ((x&7)==7) bits++;
445 bits = (dstbits += linebytes);
448 /* ==== 565 RGB bitmap to monochrome dib ==== */
449 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
451 for( h = lines - 1; h >= 0; h--)
453 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
454 for( x = 0; x < dstwidth; x++) {
455 if (!(x&7)) *bits = 0;
457 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 2,
458 ((val << 3) & 0xf8) |
460 ((val >> 3) & 0xfc) |
462 ((val >> 8) & 0xf8) |
463 ((val >> 13) & 0x7) ) << (7-(x&7)) );
464 if ((x&7)==7) bits++;
466 bits = (dstbits += linebytes);
469 else goto notsupported;
478 /* ==== 24/32 BGR bitmap to monochrome dib ==== */
479 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
481 for (h = lines - 1; h >= 0; h--)
483 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
484 for (x = 0; x < dstwidth; x++, srcpixel+=4) {
485 if (!(x&7)) *bits = 0;
486 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[2] , srcpixel[1], srcpixel[0]) << (7-(x&7)) );
487 if ((x&7)==7) bits++;
489 bits = (dstbits += linebytes);
492 /* ==== 24/32 RGB bitmap to monochrome dib ==== */
493 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
495 for (h = lines - 1; h >= 0; h--)
497 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
498 for (x = 0; x < dstwidth; x++, srcpixel+=4) {
499 if (!(x & 7)) *bits = 0;
500 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 2, srcpixel[0] , srcpixel[1], srcpixel[2]) << (7-(x&7)) );
501 if ((x & 7) == 7) bits++;
503 bits = (dstbits += linebytes);
506 else goto notsupported;
510 default: /* ? bit bmp -> monochrome DIB */
513 unsigned long white = (1 << bmpImage->bits_per_pixel) - 1;
515 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 1 bit DIB\n",
516 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
517 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
519 for( h = lines - 1; h >= 0; h-- ) {
520 for( x = 0; x < dstwidth; x++ ) {
521 if (!(x&7)) *bits = 0;
522 *bits |= (XGetPixel( bmpImage, x, h) >= white)
524 if ((x&7)==7) bits++;
526 bits = (dstbits += linebytes);
533 /***********************************************************************
534 * X11DRV_DIB_SetImageBits_4
536 * SetDIBits for a 4-bit deep DIB.
538 static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
539 DWORD srcwidth, DWORD dstwidth, int left,
540 int *colors, XImage *bmpImage )
544 const BYTE *bits = srcbits + (left >> 1);
547 DWORD linebytes = ((srcwidth+7)&~7)/2;
555 for (h = lines-1; h >= 0; h--) {
556 for (i = dstwidth/2, x = left; i > 0; i--) {
558 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
559 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
561 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
562 srcbits += linebytes;
563 bits = srcbits + (left >> 1);
567 for (h = 0; h < lines; h++) {
568 for (i = dstwidth/2, x = left; i > 0; i--) {
570 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
571 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
573 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
574 srcbits += linebytes;
575 bits = srcbits + (left >> 1);
582 /***********************************************************************
583 * X11DRV_DIB_GetImageBits_4
585 * GetDIBits for a 4-bit deep DIB.
587 static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
588 DWORD srcwidth, DWORD dstwidth,
589 RGBQUAD *colors, PALETTEENTRY *srccolors,
598 DWORD linebytes = ((srcwidth+7)&~7)/2;
603 dstbits = dstbits + ( linebytes * (lines-1) );
604 linebytes = -linebytes;
609 switch(bmpImage->depth) {
612 /* ==== monochrome bitmap to 4 colormap dib ==== */
614 /* ==== 4 colormap bitmap to 4 colormap dib ==== */
615 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
619 for (h = lines-1; h >= 0; h--) {
620 for (x = 0; x < dstwidth; x++) {
621 if (!(x&1)) *bits = 0;
622 val = srccolors[XGetPixel(bmpImage, x, h)];
623 *bits |= (X11DRV_DIB_GetNearestIndex(colors, 16,
626 val.peBlue) << (4-((x&1)<<2)));
627 if ((x&1)==1) bits++;
629 bits = (dstbits += linebytes);
632 else goto notsupported;
637 /* ==== 8 colormap bitmap to 4 colormap dib ==== */
638 if ( bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
642 for( h = lines - 1; h >= 0; h-- ) {
643 srcpixel = bmpImage->data + (h*bmpImage->bytes_per_line);
644 for( x = 0; x < dstwidth; x++ ) {
645 if (!(x&1)) *bits = 0;
646 val = srccolors[(int)*srcpixel++];
647 *bits |= ( X11DRV_DIB_GetNearestIndex(colors, 16,
650 val.peBlue) << (4*(1-(x&1))) );
651 if ((x&1)==1) bits++;
653 bits = (dstbits += linebytes);
656 else goto notsupported;
665 /* ==== 555 BGR bitmap to 4 colormap dib ==== */
666 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x1f)
668 for( h = lines - 1; h >= 0; h--) {
669 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
670 for( x = 0; x < dstwidth; x++) {
671 if (!(x&1)) *bits = 0;
673 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
674 ((val >> 7) & 0xf8) |
676 ((val >> 2) & 0xf8) |
678 ((val << 3) & 0xf8) |
679 ((val >> 2) & 0x7) ) << ((1-(x&1))<<2) );
680 if ((x&1)==1) bits++;
682 bits = (dstbits += linebytes);
685 /* ==== 555 RGB bitmap to 4 colormap dib ==== */
686 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
688 for( h = lines - 1; h >= 0; h--)
690 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
691 for( x = 0; x < dstwidth; x++) {
692 if (!(x&1)) *bits = 0;
694 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
695 ((val << 3) & 0xf8) |
697 ((val >> 2) & 0xfc) |
699 ((val >> 7) & 0xf8) |
700 ((val >> 12) & 0x7) ) << ((1-(x&1))<<2) );
701 if ((x&1)==1) bits++;
703 bits = (dstbits += linebytes);
706 else goto notsupported;
715 /* ==== 565 BGR bitmap to 4 colormap dib ==== */
716 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
718 for( h = lines - 1; h >= 0; h--)
720 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
721 for( x = 0; x < dstwidth; x++) {
722 if (!(x&1)) *bits = 0;
724 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
725 ((val >> 8) & 0xf8) |
727 ((val >> 3) & 0xfc) |
729 ((val << 3) & 0xf8) |
730 ((val >> 2) & 0x7) ) << ((1-(x&1))<<2) );
731 if ((x&1)==1) bits++;
733 bits = (dstbits += linebytes);
736 /* ==== 565 RGB bitmap to 4 colormap dib ==== */
737 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
739 for( h = lines - 1; h >= 0; h--)
741 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
742 for( x = 0; x < dstwidth; x++) {
743 if (!(x&1)) *bits = 0;
745 *bits |= (X11DRV_DIB_GetNearestIndex( colors, 16,
746 ((val << 3) & 0xf8) |
748 ((val >> 3) & 0xfc) |
750 ((val >> 8) & 0xf8) |
751 ((val >> 13) & 0x7) ) << ((1-(x&1))<<2) );
752 if ((x&1)==1) bits++;
754 bits = (dstbits += linebytes);
757 else goto notsupported;
766 /* ==== 24/32 BGR bitmap to 4 colormap dib ==== */
767 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
769 for (h = lines - 1; h >= 0; h--)
771 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
772 for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
773 *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[2] , srcpixel[1], srcpixel[0]) << 4) |
774 X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[6] , srcpixel[5], srcpixel[4]);
775 bits = (dstbits += linebytes);
778 /* ==== 24/32 RGB bitmap to 4 colormap dib ==== */
779 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
781 for (h = lines - 1; h >= 0; h--)
783 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
784 for (x = 0; x < dstwidth; x+=2, srcpixel+=8) /* 2 pixels at a time */
785 *bits++ = (X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[0] , srcpixel[1], srcpixel[2]) << 4) |
786 X11DRV_DIB_GetNearestIndex(colors, 16, srcpixel[4] , srcpixel[5], srcpixel[6]);
787 bits = (dstbits += linebytes);
790 else goto notsupported;
794 default: /* ? bit bmp -> 4 bit DIB */
796 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 4 bit DIB\n",
797 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
798 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
799 for (h = lines-1; h >= 0; h--) {
800 for (x = 0; x < dstwidth/2; x++) {
801 *bits++ = (X11DRV_DIB_MapColor((int *)colors, 16,
802 XGetPixel( bmpImage, x++, h ), 0) << 4)
803 | (X11DRV_DIB_MapColor((int *)colors, 16,
804 XGetPixel( bmpImage, x++, h ), 0) & 0x0f);
807 *bits = (X11DRV_DIB_MapColor((int *)colors, 16,
808 XGetPixel( bmpImage, x++, h ), 0) << 4);
809 bits = (dstbits += linebytes);
815 /***********************************************************************
816 * X11DRV_DIB_SetImageBits_RLE4
818 * SetDIBits for a 4-bit deep compressed DIB.
820 static void X11DRV_DIB_SetImageBits_RLE4( int lines, const BYTE *bits,
821 DWORD width, DWORD dstwidth,
822 int left, int *colors,
825 int x = 0, c, length;
826 const BYTE *begin = bits;
830 while ((int)lines >= 0) {
832 if (length) { /* encoded */
840 XPutPixel(bmpImage, x++, lines, colors[c >>4]);
848 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
859 case 1: /* eopicture */
865 FIXME_(x11drv)("x-delta is too large?\n");
871 default: /* absolute */
879 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
887 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
890 if ((bits - begin) & 1)
899 /***********************************************************************
900 * X11DRV_DIB_SetImageBits_8
902 * SetDIBits for an 8-bit deep DIB.
904 static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
905 DWORD srcwidth, DWORD dstwidth, int left,
906 const int *colors, XImage *bmpImage )
912 /* align to 32 bit */
913 DWORD linebytes = (srcwidth + 3) & ~3;
920 srcbits = srcbits + ( linebytes * (lines-1) );
921 linebytes = -linebytes;
924 bits = srcbits + left;
926 switch (bmpImage->depth) {
929 #if defined(__i386__) && defined(__GNUC__)
930 /* Some X servers might have 32 bit/ 16bit deep pixel */
931 if (lines && (dstwidth!=left) && (bmpImage->bits_per_pixel == 16))
933 for (h = lines ; h--; ) {
934 int _cl1,_cl2; /* temp outputs for asm below */
935 /* Borrowed from DirectDraw */
936 __asm__ __volatile__(
941 " movw (%%edx,%%eax,4),%%ax\n"
945 :"=S" (bits), "=D" (_cl1), "=c" (_cl2)
947 "D" (bmpImage->data+h*bmpImage->bytes_per_line+left*2),
950 :"eax", "cc", "memory"
952 bits = (srcbits += linebytes) + left;
959 break; /* use slow generic case below */
962 for (h = lines - 1; h >= 0; h--) {
963 for (x = left; x < dstwidth; x++, bits++) {
964 color = colors[*bits];
965 XPutPixel( bmpImage, x, h, colors[*bits] );
967 bits = (srcbits += linebytes) + left;
971 /***********************************************************************
972 * X11DRV_DIB_GetImageBits_8
974 * GetDIBits for an 8-bit deep DIB.
976 static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
977 DWORD srcwidth, DWORD dstwidth,
978 RGBQUAD *colors, PALETTEENTRY *srccolors,
985 /* align to 32 bit */
986 DWORD linebytes = (srcwidth + 3) & ~3;
991 dstbits = dstbits + ( linebytes * (lines-1) );
992 linebytes = -linebytes;
999 This condition is true when GetImageBits has been called by UpdateDIBSection.
1000 For now, GetNearestIndex is too slow to support 256 colormaps, so we'll just use for
1001 for GetDIBits calls. (In somes cases, in a updateDIBSection, the returned colors are bad too)
1003 if (!srccolors) goto updatesection;
1005 switch(bmpImage->depth) {
1008 /* ==== monochrome bitmap to 8 colormap dib ==== */
1010 /* ==== 4 colormap bitmap to 8 colormap dib ==== */
1011 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1015 for (h = lines - 1; h >= 0; h--) {
1016 for (x = 0; x < dstwidth; x++) {
1017 val = srccolors[XGetPixel(bmpImage, x, h)];
1018 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed,
1019 val.peGreen, val.peBlue);
1021 bits = (dstbits += linebytes);
1024 else goto notsupported;
1029 /* ==== 8 colormap bitmap to 8 colormap dib ==== */
1030 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1035 for (h = lines - 1; h >= 0; h--) {
1036 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1037 for (x = 0; x < dstwidth; x++) {
1038 val = srccolors[(int)*srcpixel++];
1039 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256, val.peRed,
1040 val.peGreen, val.peBlue);
1042 bits = (dstbits += linebytes);
1045 else goto notsupported;
1054 /* ==== 555 BGR bitmap to 8 colormap dib ==== */
1055 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
1057 for( h = lines - 1; h >= 0; h--)
1059 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1060 for( x = 0; x < dstwidth; x++ )
1063 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1064 ((val >> 7) & 0xf8) |
1065 ((val >> 12) & 0x7),
1066 ((val >> 2) & 0xf8) |
1068 ((val << 3) & 0xf8) |
1069 ((val >> 2) & 0x7) );
1071 bits = (dstbits += linebytes);
1074 /* ==== 555 RGB bitmap to 8 colormap dib ==== */
1075 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
1077 for( h = lines - 1; h >= 0; h--)
1079 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1080 for( x = 0; x < dstwidth; x++ )
1083 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1084 ((val << 3) & 0xf8) |
1086 ((val >> 2) & 0xf8) |
1088 ((val >> 7) & 0xf8) |
1089 ((val >> 12) & 0x7) );
1091 bits = (dstbits += linebytes);
1094 else goto notsupported;
1103 /* ==== 565 BGR bitmap to 8 colormap dib ==== */
1104 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
1106 for( h = lines - 1; h >= 0; h--)
1108 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1109 for( x = 0; x < dstwidth; x++ )
1112 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1113 ((val >> 8) & 0xf8) |
1114 ((val >> 13) & 0x7),
1115 ((val >> 3) & 0xfc) |
1117 ((val << 3) & 0xf8) |
1118 ((val >> 2) & 0x7) );
1120 bits = (dstbits += linebytes);
1123 /* ==== 565 RGB bitmap to 8 colormap dib ==== */
1124 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
1126 for( h = lines - 1; h >= 0; h--)
1128 srcpixel = (LPWORD)(bmpImage->data + h*bmpImage->bytes_per_line);
1129 for( x = 0; x < dstwidth; x++ )
1132 *bits++ = X11DRV_DIB_GetNearestIndex( colors, 256,
1133 ((val << 3) & 0xf8) |
1135 ((val >> 3) & 0x00fc) |
1137 ((val >> 8) & 0x00f8) |
1138 ((val >> 13) & 0x7) );
1140 bits = (dstbits += linebytes);
1143 else goto notsupported;
1152 /* ==== 24/32 BGR bitmap to 8 colormap dib ==== */
1153 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1155 for (h = lines - 1; h >= 0; h--)
1157 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1158 for (x = 0; x < dstwidth; x++, srcpixel+=4)
1159 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256,
1160 srcpixel[2] , srcpixel[1], *srcpixel);
1161 bits = (dstbits += linebytes);
1164 /* ==== 24/32 RGB bitmap to 8 colormap dib ==== */
1165 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1167 for (h = lines - 1; h >= 0; h--)
1169 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1170 for (x = 0; x < dstwidth; x++, srcpixel+=4)
1171 *bits++ = X11DRV_DIB_GetNearestIndex(colors, 256,
1172 *srcpixel, srcpixel[1], srcpixel[2]);
1173 bits = (dstbits += linebytes);
1177 else goto notsupported;
1181 default: /* ? bit bmp -> 8 bit DIB */
1183 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 8 bit DIB\n",
1184 bmpImage->depth, (int)bmpImage->red_mask,
1185 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
1187 for (h = lines - 1; h >= 0; h--) {
1188 for (x = 0; x < dstwidth; x++, bits++) {
1189 *bits = X11DRV_DIB_MapColor((int *)colors, 256,
1190 XGetPixel( bmpImage, x, h ), *bits);
1192 bits = (dstbits += linebytes);
1198 /***********************************************************************
1199 * X11DRV_DIB_SetImageBits_RLE8
1201 * SetDIBits for an 8-bit deep compressed DIB.
1203 * This function rewritten 941113 by James Youngman. WINE blew out when I
1204 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
1206 * This was because the algorithm assumed that all RLE8 bitmaps end with the
1207 * 'End of bitmap' escape code. This code is very much laxer in what it
1208 * allows to end the expansion. Possibly too lax. See the note by
1209 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
1210 * bitmap should end with RleEnd, but on the other hand, software exists
1211 * that produces ones that don't and Windows 3.1 doesn't complain a bit
1214 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
1215 * James A. Youngman <mbcstjy@afs.man.ac.uk>
1219 enum Rle8_EscapeCodes
1222 * Apologies for polluting your file's namespace...
1224 RleEol = 0, /* End of line */
1225 RleEnd = 1, /* End of bitmap */
1226 RleDelta = 2 /* Delta */
1229 static void X11DRV_DIB_SetImageBits_RLE8( int lines, const BYTE *bits,
1230 DWORD width, DWORD dstwidth,
1231 int left, int *colors,
1234 int x; /* X-positon on each line. Increases. */
1235 int line; /* Line #. Starts at lines-1, decreases */
1236 const BYTE *pIn = bits; /* Pointer to current position in bits */
1237 BYTE length; /* The length pf a run */
1238 BYTE color_index; /* index into colors[] as read from bits */
1239 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
1240 int color; /* value of colour[color_index] */
1242 if (lines == 0) /* Let's hope this doesn't happen. */
1246 * Note that the bitmap data is stored by Windows starting at the
1247 * bottom line of the bitmap and going upwards. Within each line,
1248 * the data is stored left-to-right. That's the reason why line
1249 * goes from lines-1 to 0. [JAY]
1259 * If the length byte is not zero (which is the escape value),
1260 * We have a run of length pixels all the same colour. The colour
1261 * index is stored next.
1263 * If the length byte is zero, we need to read the next byte to
1264 * know what to do. [JAY]
1269 * [Run-Length] Encoded mode
1271 color_index = (*pIn++); /* Get the colour index. */
1272 color = colors[color_index];
1281 XPutPixel(bmpImage, x++, line, color);
1287 * Escape codes (may be an absolute sequence though)
1289 escape_code = (*pIn++);
1292 case RleEol: /* =0, end of line */
1299 case RleEnd: /* =1, end of bitmap */
1302 * Not all RLE8 bitmaps end with this
1303 * code. For example, Paint Shop Pro
1304 * produces some that don't. That's (I think)
1305 * what caused the previous implementation to
1308 line=-1; /* Cause exit from do loop. */
1312 case RleDelta: /* =2, a delta */
1315 * Note that deltaing to line 0
1316 * will cause an exit from the loop,
1317 * which may not be what is intended.
1318 * The fact that there is a delta in the bits
1319 * almost certainly implies that there is data
1320 * to follow. You may feel that we should
1321 * jump to the top of the loop to avoid exiting
1324 * TODO: Decide what to do here in that case. [JAY]
1330 TRACE("Delta to last line of bitmap "
1331 "(wrongly?) causes loop exit\n");
1336 default: /* >2, switch to absolute mode */
1341 length = escape_code;
1344 color_index = (*pIn++);
1350 XPutPixel(bmpImage, x++, line,
1351 colors[color_index]);
1355 * If you think for a moment you'll realise that the
1356 * only time we could ever possibly read an odd
1357 * number of bytes is when there is a 0x00 (escape),
1358 * a value >0x02 (absolute mode) and then an odd-
1359 * length run. Therefore this is the only place we
1360 * need to worry about it. Everywhere else the
1361 * bytes are always read in pairs. [JAY]
1363 if (escape_code & 1)
1364 pIn++; /* Throw away the pad byte. */
1367 } /* switch (escape_code) : Escape sequence */
1368 } /* process either an encoded sequence or an escape sequence */
1370 /* We expect to come here more than once per line. */
1371 } while (line >= 0); /* Do this until the bitmap is filled */
1374 * Everybody comes here at the end.
1375 * Check how we exited the loop and print a message if it's a bit odd.
1378 if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) )
1380 TRACE("End-of-bitmap without (strictly) proper escape code. Last two "
1381 "bytes were: %02X %02X.\n", (int)*(pIn-2),(int)*(pIn-1));
1386 /***********************************************************************
1387 * X11DRV_DIB_SetImageBits_16
1389 * SetDIBits for a 16-bit deep DIB.
1391 static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
1392 DWORD srcwidth, DWORD dstwidth, int left,
1393 DC *dc, DWORD rSrc, DWORD gSrc, DWORD bSrc,
1399 /* align to 32 bit */
1400 DWORD linebytes = (srcwidth * 2 + 3) & ~3;
1405 srcbits = srcbits + ( linebytes * (lines-1));
1406 linebytes = -linebytes;
1409 switch ( bmpImage->depth )
1412 /* using same format as XImage */
1413 if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
1414 for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
1415 memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
1416 else /* We need to do a conversion from a 565 dib */
1418 LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
1420 int div = dstwidth % 2;
1422 for (h = lines - 1; h >= 0; h--) {
1423 dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1424 for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
1426 *dstpixel++ = ((val >> 1) & 0x7fe07fe0) | (val & 0x001f001f); /* Red & Green & Blue */
1428 if (div != 0) /* Odd width? */
1429 *dstpixel = ((*(WORD *)ptr >> 1) & 0x7fe0) | (*(WORD *)ptr & 0x001f);
1430 ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
1436 /* using same format as XImage */
1437 if (rSrc == bmpImage->red_mask && gSrc == bmpImage->green_mask && bSrc == bmpImage->blue_mask)
1438 for (h = lines - 1; h >= 0; h--, srcbits += linebytes)
1439 memcpy ( bmpImage->data + h * bmpImage->bytes_per_line + left*2, srcbits + left*2, dstwidth*2 );
1440 else /* We need to do a conversion from a 555 dib */
1442 LPDWORD dstpixel, ptr = (LPDWORD)(srcbits + left*2);
1444 int div = dstwidth % 2;
1446 for (h = lines - 1; h >= 0; h--) {
1447 dstpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1448 for (x = 0; x < dstwidth/2; x++) { /* Do 2 pixels at a time */
1450 *dstpixel++ = ((val << 1) & 0xffc0ffc0) | ((val >> 4) & 0x00200020) | /* Red & Green */
1451 (val & 0x001f001f); /* Blue */
1453 if (div != 0) /* Odd width? */
1454 *dstpixel = ((*(WORD *)ptr << 1) & 0xffc0) | ((*(WORD *)ptr >> 4) & 0x0020)
1455 | (*(WORD *)ptr & 0x001f);
1456 ptr = (LPDWORD) ((srcbits += linebytes) + left*2);
1465 LPWORD ptr = (LPWORD)srcbits + left;
1468 /* ==== 555 BGR dib to 24/32 BGR bitmap ==== */
1469 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1471 for (h = lines - 1; h >= 0; h--) {
1472 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1473 for (x = 0; x < dstwidth; x++) {
1476 *dstpixel++ = ((val << 9) & 0xf80000) | ((val << 4) & 0x070000) | /* Red */
1477 ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
1478 ((val << 3) & 0x0000f8) | ((val >> 2) & 0x000007); /* Blue */
1480 ptr = (LPWORD)(srcbits += linebytes) + left;
1483 /* ==== 555 BGR dib to 24/32 RGB bitmap ==== */
1484 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1486 for (h = lines - 1; h >= 0; h--) {
1487 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line + left*4);
1488 for (x = 0; x < dstwidth; x++) {
1491 *dstpixel++ = ((val >> 7) & 0x0000f8) | ((val >> 12) & 0x000007) | /* Red */
1492 ((val << 6) & 0x00f800) | ((val << 1) & 0x000700) | /* Green */
1493 ((val << 19) & 0xf80000) | ((val >> 14) & 0x070000); /* Blue */
1495 ptr = (LPWORD)(srcbits += linebytes) + left;
1506 LPWORD ptr = (LPWORD)srcbits + left;
1510 /* Set color scaling values */
1511 if ( rSrc == 0x7c00 ) { sc1 = 7; sc2 = 2; } /* 555 dib */
1512 else { sc1 = 8; sc2 = 3; } /* 565 dib */
1514 for (h = lines - 1; h >= 0; h--) {
1515 for (x = left; x < dstwidth+left; x++) {
1517 XPutPixel( bmpImage, x, h,
1518 X11DRV_PALETTE_ToPhysical(dc, RGB(((val & rSrc) >> sc1), /* Red */
1519 ((val & gSrc) >> sc2), /* Green */
1520 ((val & bSrc) << 3)))); /* Blue */
1522 ptr = (LPWORD) (srcbits += linebytes) + left;
1528 FIXME("16 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
1535 /***********************************************************************
1536 * X11DRV_DIB_GetImageBits_16
1538 * GetDIBits for an 16-bit deep DIB.
1540 static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
1541 DWORD dstwidth, DWORD srcwidth,
1542 PALETTEENTRY *srccolors,
1543 DWORD rDst, DWORD gDst, DWORD bDst,
1549 /* align to 32 bit */
1550 DWORD linebytes = (dstwidth * 2 + 3) & ~3;
1555 dstbits = dstbits + ( linebytes * (lines-1));
1556 linebytes = -linebytes;
1559 /* Set color scaling values */
1560 if ( rDst == 0x7c00 ) { rsc = 7; gsc = 2; } /* 555 dib */
1561 else { rsc = 8; gsc = 3; } /* 565 dib */
1563 switch ( bmpImage->depth )
1566 /* using same format as XImage */
1567 if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask)
1568 for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
1569 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
1570 /* reversed format (BGR <=> RGB) */
1571 else if (rDst == bmpImage->blue_mask && bDst == bmpImage->red_mask)
1573 LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
1575 int div = srcwidth % 2;
1577 for (h = lines - 1; h >= 0; h--) {
1578 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1579 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1581 *ptr++ = ((val << 10) & 0xf800f800) | (val & 0x03e003e0) | /* Red & Green */
1582 ((val >> 10) & 0x001f001f); /* Blue */
1584 if (div != 0) /* Odd width? */
1585 *ptr = ((*(WORD *)srcpixel << 1) & 0xffc0) | ((*(WORD *)srcpixel >> 4) & 0x0020) |
1586 (*(WORD *)srcpixel & 0x001f);
1587 ptr = (LPDWORD)(dstbits += linebytes);
1590 else goto notsupported;
1596 LPDWORD srcpixel, ptr = (LPDWORD)dstbits;
1598 int div = srcwidth % 2;
1600 /* using same format as XImage */
1601 if (rDst == bmpImage->red_mask && bDst == bmpImage->blue_mask)
1602 for (h = lines - 1; h >= 0; h--, dstbits += linebytes)
1603 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, srcwidth*2 );
1604 /* ==== 565 BGR bitmap to 555 BGR dib ==== */
1605 else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f &&
1606 rDst == 0x7c00 && bDst == 0x001f)
1608 for (h = lines - 1; h >= 0; h--) {
1609 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1610 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1612 *ptr++ = ((val >> 1) & 0x7fe07fe0) | /* Red & Green */
1613 (val & 0x001f001f); /* Blue */
1615 if (div != 0) /* Odd width? */
1616 *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
1617 ptr = (LPDWORD) (dstbits += linebytes);
1620 /* ==== 565 RGB bitmap to 555 BGR dib ==== */
1621 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800 &&
1622 rDst == 0x7c00 && bDst == 0x001f)
1624 for (h = lines - 1; h >= 0; h--) {
1625 srcpixel = (LPDWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
1626 for (x = 0; x < srcwidth/2; x++) { /* Do 2 pixels at a time */
1628 *ptr++ = ((val << 10) & 0x7c007c00) | ((val >> 1) & 0x03e003e0) | /* Red & Green */
1629 ((val >> 11) & 0x001f001f); /* Blue */
1631 if (div != 0) /* Odd width? */
1632 *ptr = ((*(WORD *)srcpixel >> 1) & 0x7fe0) | (*(WORD *)srcpixel & 0x001f);
1633 ptr = (LPDWORD) (dstbits += linebytes);
1636 else goto notsupported;
1644 LPWORD ptr = (LPWORD)dstbits;
1647 /* ==== 24/32 BGR bitmap ==== */
1648 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff)
1650 int rsc2 = 16-rsc, gsc2 = 8-gsc;
1651 for (h = lines - 1; h >= 0; h--) {
1652 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1653 for (x = 0; x < srcwidth; x++, ptr++) {
1655 *ptr = ((val >> rsc2) & rDst) |
1656 ((val >> gsc2) & gDst) |
1657 ((val >> 3) & bDst);
1659 ptr = (LPWORD)(dstbits += linebytes);
1662 /* ==== 24/32 RGB bitmap ==== */
1663 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
1666 for (h = lines - 1; h >= 0; h--) {
1667 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
1668 for (x = 0; x < srcwidth; x++, ptr++) {
1670 *ptr = ((val << rsc) & rDst) |
1671 ((val >> gsc2) & gDst) |
1672 ((val >> 19) & bDst);
1674 ptr = (LPWORD) (dstbits += linebytes);
1677 else goto notsupported;
1682 /* ==== monochrome bitmap ==== */
1684 /* ==== 4 colormap bitmap ==== */
1685 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1687 LPWORD ptr = (LPWORD)dstbits;
1690 for (h = lines - 1; h >= 0; h--) {
1691 for (x = 0; x < dstwidth; x++) {
1692 val = srccolors[XGetPixel(bmpImage, x, h)];
1693 *ptr++ = ((val.peRed << rsc) & rDst) |
1694 ((val.peGreen << gsc) & gDst) |
1695 ((val.peBlue >> 3) & bDst);
1697 ptr = (LPWORD)(dstbits += linebytes);
1700 else goto notsupported;
1705 /* ==== 8 colormap bitmap ==== */
1706 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
1708 LPWORD ptr = (LPWORD)dstbits;
1712 for (h = lines - 1; h >= 0; h--) {
1713 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
1714 for (x = 0; x < dstwidth; x++) {
1715 val = srccolors[(int)*srcpixel++];
1716 *ptr++ = ((val.peRed << rsc) & rDst) |
1717 ((val.peGreen << gsc) & gDst) |
1718 ((val.peBlue >> 3) & bDst);
1720 ptr = (LPWORD)(dstbits += linebytes);
1723 else goto notsupported;
1731 LPWORD ptr = (LPWORD)dstbits;
1733 FIXME("from %d bit bitmap with mask R,G,B %lx,%lx,%lx to 16 bit DIB %lx,%lx,%lx\n",
1734 bmpImage->depth, bmpImage->red_mask,
1735 bmpImage->green_mask, bmpImage->blue_mask,
1738 for (h = lines - 1; h >= 0; h--)
1740 for (x = 0; x < dstwidth; x++, ptr++)
1742 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
1743 r = (BYTE) GetRValue(pixel);
1744 g = (BYTE) GetGValue(pixel);
1745 b = (BYTE) GetBValue(pixel);
1746 *ptr = ( ((r << rsc) & rDst) | ((g << gsc) & gDst) | ((b >> 3) & bDst) );
1748 ptr = (LPWORD) (dstbits += linebytes);
1756 /***********************************************************************
1757 * X11DRV_DIB_SetImageBits_24
1759 * SetDIBits for a 24-bit deep DIB.
1761 static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
1762 DWORD srcwidth, DWORD dstwidth, int left,
1763 DC *dc, XImage *bmpImage )
1768 /* align to 32 bit */
1769 DWORD linebytes = (srcwidth * 3 + 3) & ~3;
1774 srcbits = srcbits + linebytes * (lines - 1);
1775 linebytes = -linebytes;
1778 switch ( bmpImage->depth )
1782 if (bmpImage->bits_per_pixel == 24) {
1783 int dstlinebytes = linebytes;
1785 BYTE *ptr = (BYTE *)(srcbits+left*3);
1787 if (dstlinebytes < 0 ) dstlinebytes = -dstlinebytes;
1788 dstpixel = bmpImage->data + lines*dstlinebytes + left*3;
1789 for(h = lines ; h-- ; ) {
1790 dstpixel-=dstlinebytes;
1791 memcpy(dstpixel,ptr,dstwidth*3);
1799 if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 ) /* packed BGR to unpacked BGR */
1801 DWORD *dstpixel, val, buf;
1802 DWORD *ptr = (DWORD *)(srcbits + left*3);
1804 int div = dstwidth % 4;
1807 for(h = lines - 1; h >= 0; h--)
1809 dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);
1811 for (x = 0; x < dstwidth/4; x++) { /* do 3 dwords source, 4 dwords dest at a time */
1813 *dstpixel++ = buf&0x00ffffff; /* b1, g1, r1 */
1814 val = (buf >> 24); /* b2 */
1816 *dstpixel++ = (val | (buf<<8)) &0x00ffffff; /* g2, r2 */
1817 val = (buf >> 16); /* b3, g3 */
1819 *dstpixel++ = (val | (buf<<16)) &0x00ffffff; /* r3 */
1820 *dstpixel++ = (buf >> 8); /* b4, g4, r4 */
1822 for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
1824 *dstpixel++ = *(DWORD*)bits & 0x00ffffff; /* b, g, r */
1826 ptr = (DWORD*)((srcbits+=linebytes)+left*3);
1829 else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff ) /* packed BGR to unpacked RGB */
1831 DWORD *dstpixel, val, buf;
1832 DWORD *ptr = (DWORD *)(srcbits + left*3);
1834 int div = dstwidth % 4;
1837 for(h = lines - 1; h >= 0; h--)
1839 dstpixel = (DWORD *) (bmpImage->data + h*bmpImage->bytes_per_line + left*4);
1841 for (x = 0; x < dstwidth/4; x++) { /* do 3 dwords source, 4 dwords dest at a time */
1843 *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16); /* b1, g1, r1 */
1844 val = ((buf&0xff000000)>>8); /* b2 */
1846 *dstpixel++ = val | ((buf&0xff)<<8) | ((buf&0xff00)>>8); /* g2, r2 */
1847 val = (buf&0xff0000) | ((buf&0xff000000)>>16); /* b3, g3 */
1849 *dstpixel++ = val | (buf&0xff); /* r3 */
1850 *dstpixel++ = ((buf&0xff00)<<8) | ((buf&0xff0000)>>8) | (buf>>24); /* b4, g4, r4 */
1852 for ( divk=div, bits=(BYTE*)ptr; divk>0; divk--, bits+=3 ) /* do remainder */
1854 buf = *(DWORD*)bits;
1855 *dstpixel++ = ((buf&0xff)<<16) | (buf&0xff00) | ((buf&0xff0000)>>16); /* b, g, r */
1857 ptr = (DWORD*)((srcbits+=linebytes)+left*3);
1867 if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f ) /* BGR888 to RGB555 */
1869 DWORD *ptr = (DWORD *)(srcbits + left*3), val;
1872 int div = dstwidth % 4;
1875 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1876 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1877 for (x = 0; x < dstwidth/4; x++) {
1878 *dstpixel++ = (WORD)((((val = *ptr++) << 7) & 0x7c00) | ((val >> 6) & 0x03e0) | ((val >> 19) & 0x1f));
1879 *dstpixel++ = (WORD)(((val >> 17) & 0x7c00) | (((val = *ptr++) << 2) & 0x03e0) | ((val >> 11) & 0x1f));
1880 *dstpixel++ = (WORD)(((val >> 9) & 0x07c00) | ((val >> 22) & 0x03e0) | (((val = *ptr++) >> 3) & 0x1f));
1881 *dstpixel++ = (WORD)(((val >> 1) & 0x07c00) | ((val >> 14) & 0x03e0) | ((val >> 27) & 0x1f));
1883 for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth not divisible by 4? */
1884 *dstpixel++ = (((WORD)bits[0] << 7) & 0x07c00) |
1885 (((WORD)bits[1] << 2) & 0x03e0) |
1886 (((WORD)bits[2] >> 3) & 0x001f);
1887 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1890 else if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 ) /* BGR888 to BGR555 */
1892 DWORD *ptr = (DWORD *)(srcbits + left*3), val;
1895 int div = dstwidth % 4;
1898 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1899 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1900 for (x = 0; x < dstwidth/4; x++) {
1901 *dstpixel++ = (WORD)((((val = *ptr++) >> 3) & 0x1f) | ((val >> 6) & 0x03e0) | ((val >> 9) & 0x7c00));
1902 *dstpixel++ = (WORD)(((val >> 27) & 0x1f) | (((val = *ptr++) << 2) & 0x03e0) | ((val >> 1) & 0x7c00));
1903 *dstpixel++ = (WORD)(((val >> 19) & 0x1f) | ((val >> 22) & 0x03e0) | (((val = *ptr++) << 7) & 0x7c00));
1904 *dstpixel++ = (WORD)(((val >> 11) & 0x1f) | ((val >> 14) & 0x03e0) | ((val >> 17) & 0x7c00));
1906 for (bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth not divisible by 4? */
1907 *dstpixel++ = (((WORD)bits[2] << 7) & 0x07c00) |
1908 (((WORD)bits[1] << 2) & 0x03e0) |
1909 (((WORD)bits[0] >> 3) & 0x001f);
1910 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1920 DWORD *ptr = (DWORD *)(srcbits + left*3), val;
1923 int div = dstwidth % 4;
1926 if( bmpImage->blue_mask == 0x001f && bmpImage->red_mask == 0xf800 ) /* BGR888 to BGR565 */
1928 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1929 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1930 for (x = 0; x < dstwidth/4; x++) {
1931 *dstpixel++ = (WORD)((((val = *ptr++) >> 3) & 0x1f) | ((val >> 5) & 0x07e0) | ((val >> 8) & 0xf800));
1932 *dstpixel++ = (WORD)(((val >> 27) & 0x1f) | (((val = *ptr++) << 3) & 0x07e0) | ((val) & 0xf800));
1933 *dstpixel++ = (WORD)(((val >> 19) & 0x1f) | ((val >> 21) & 0x07e0) | (((val = *ptr++) << 8) & 0xf800));
1934 *dstpixel++ = (WORD)(((val >> 11) & 0x1f) | ((val >> 13) & 0x07e0) | ((val >> 16) & 0xf800));
1936 for ( bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth is not divisible by 4? */
1937 *dstpixel++ = (((WORD)bits[2] << 8) & 0xf800) |
1938 (((WORD)bits[1] << 3) & 0x07e0) |
1939 (((WORD)bits[0] >> 3) & 0x001f);
1940 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1943 else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x001f ) /* BGR888 to RGB565 */
1945 for (h = lines - 1; h >= 0; h--) { /* Do 4 pixels at a time */
1946 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line + left*2);
1947 for (x = 0; x < dstwidth/4; x++) {
1948 *dstpixel++ = (WORD)((((val = *ptr++) << 8) & 0xf800) | ((val >> 5) & 0x07e0) | ((val >> 19) & 0x1f));
1949 *dstpixel++ = (WORD)(((val >> 16) & 0xf800) | (((val = *ptr++) << 3) & 0x07e0) | ((val >> 11) & 0x1f));
1950 *dstpixel++ = (WORD)(((val >> 8) & 0xf800) | ((val >> 21) & 0x07e0) | (((val = *ptr++) >> 3) & 0x1f));
1951 *dstpixel++ = (WORD)((val & 0xf800) | ((val >> 13) & 0x07e0) | ((val >> 27) & 0x1f));
1953 for ( bits = (LPBYTE)ptr, divk=div; divk > 0; divk--, bits+=3) /* dstwidth is not divisible by 4? */
1954 *dstpixel++ = (((WORD)bits[0] << 8) & 0xf800) |
1955 (((WORD)bits[1] << 3) & 0x07e0) |
1956 (((WORD)bits[2] >> 3) & 0x001f);
1957 ptr = (DWORD *)((srcbits += linebytes) + left * 3);
1969 LPBYTE bits = (LPBYTE)srcbits + left*3;
1971 for (h = lines - 1; h >= 0; h--) {
1972 for (x = left; x < dstwidth+left; x++, bits+=3)
1973 XPutPixel( bmpImage, x, h,
1974 X11DRV_PALETTE_ToPhysical(dc, RGB(bits[2], bits[1], bits[0])));
1975 bits = (LPBYTE)(srcbits += linebytes) + left * 3;
1982 FIXME("from 24 bit DIB to %d bit bitmap with mask R,G,B %x,%x,%x\n",
1983 bmpImage->bits_per_pixel, (int)bmpImage->red_mask,
1984 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
1990 /***********************************************************************
1991 * X11DRV_DIB_GetImageBits_24
1993 * GetDIBits for an 24-bit deep DIB.
1995 static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
1996 DWORD dstwidth, DWORD srcwidth,
1997 PALETTEENTRY *srccolors, XImage *bmpImage )
2002 /* align to 32 bit */
2003 DWORD linebytes = (dstwidth * 3 + 3) & ~3;
2008 dstbits = dstbits + ( linebytes * (lines-1) );
2009 linebytes = -linebytes;
2012 switch ( bmpImage->depth )
2016 if (bmpImage->bits_per_pixel == 24) {
2017 int tocopy = linebytes;
2019 BYTE *ptr = (LPBYTE)dstbits;
2021 if (tocopy < 0 ) tocopy = -tocopy;
2022 srcpixel = bmpImage->data + lines*tocopy;
2023 for(h = lines ; h-- ; ) {
2025 memcpy(ptr,srcpixel,tocopy);
2026 ptr = (LPBYTE)(dstbits+=linebytes);
2033 DWORD *srcpixel, buf;
2035 DWORD *ptr=(DWORD *)dstbits;
2036 int quotient = dstwidth / 4;
2037 int remainder = dstwidth % 4;
2040 /* ==== 24/32 BGR bitmap to 24 BGR dib==== */
2041 if( bmpImage->blue_mask == 0xff && bmpImage->red_mask == 0xff0000 )
2043 for(h = lines - 1; h >= 0; h--)
2045 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2047 for (x = 0; x < quotient; x++) { /* do 4 dwords source, 3 dwords dest at a time */
2048 buf = ((*srcpixel++)&0x00ffffff); /* b1, g1, r1*/
2049 *ptr++ = buf | ((*srcpixel)<<24); /* b2 */
2050 buf = ((*srcpixel++>>8)&0x0000ffff); /* g2, r2 */
2051 *ptr++ = buf | ((*srcpixel)<<16); /* b3, g3 */
2052 buf = ((*srcpixel++>>16)&0x000000ff); /* r3 */
2053 *ptr++ = buf | ((*srcpixel++)<<8); /* b4, g4, r4 */
2055 for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
2058 *(WORD*)bits = buf; /* b, g */
2059 *(bits+2) = buf>>16; /* r */
2061 ptr = (DWORD*)(dstbits+=linebytes);
2065 /* ==== 24/32 RGB bitmap to 24 BGR dib ==== */
2066 else if( bmpImage->blue_mask == 0xff0000 && bmpImage->red_mask == 0xff )
2068 for(h = lines - 1; h >= 0; h--)
2070 srcpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2072 for (x = 0; x < quotient; x++) { /* do 4 dwords source, 3 dwords dest at a time */
2074 val = ((buf&0xff0000)>>16) | (buf&0xff00) | ((buf&0xff)<<16); /* b1, g1, r1 */
2076 *ptr++ = val | ((buf&0xff0000)<<8); /* b2 */
2077 val = ((buf&0xff00)>>8) | ((buf&0xff)<<8); /* g2, r2 */
2079 *ptr++ = val | (buf&0xff0000) | ((buf&0xff00)<<16); /* b3, g3 */
2080 val = (buf&0xff); /* r3 */
2082 *ptr++ = val | ((buf&0xff0000)>>8) | ((buf&0xff00)<<8) | (buf<<24); /* b4, g4, r4 */
2084 for ( remk=remainder, bits=(BYTE*)ptr; remk>0; remk--, bits+=3 ) /* do remainder */
2087 *(WORD*)bits = (buf&0xff00) | ((buf&0xff0000)>>16) ; /* b, g */
2088 *(bits+2) = buf; /* r */
2090 ptr = (DWORD*)(dstbits+=linebytes);
2093 else goto notsupported;
2100 LPBYTE bits = dstbits;
2103 /* ==== 555 BGR bitmap to 24 BGR dib ==== */
2104 if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0x7c00 )
2106 for (h = lines - 1; h >= 0; h--) {
2107 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2108 for (x = 0; x < srcwidth; x++, bits += 3) {
2110 bits[2] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2111 bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07)); /*Green*/
2112 bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2114 bits = (dstbits += linebytes);
2117 /* ==== 555 RGB bitmap to 24 RGB dib==== */
2118 else if( bmpImage->blue_mask == 0x7c00 && bmpImage->red_mask == 0x1f )
2120 for (h = lines - 1; h >= 0; h--) {
2121 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2122 for (x = 0; x < srcwidth; x++, bits += 3) {
2124 bits[0] = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2125 bits[1] = (BYTE)(((val >> 2) & 0xf8) | ((val >> 7) & 0x07)); /*Green*/
2126 bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2128 bits = (dstbits += linebytes);
2131 else goto notsupported;
2138 LPBYTE bits = dstbits;
2141 /* ==== 565 BGR bitmap to 24 BGR dib ==== */
2142 if( bmpImage->blue_mask == 0x1f && bmpImage->red_mask == 0xf800 )
2144 for (h = lines - 1; h >= 0; h--) {
2145 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2146 for (x = 0; x < srcwidth; x++, bits += 3) {
2148 bits[2] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2149 bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2150 bits[0] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2152 bits = (dstbits += linebytes);
2155 /* ==== 565 RGB bitmap to 24 BGR dib ==== */
2156 else if( bmpImage->blue_mask == 0xf800 && bmpImage->red_mask == 0x1f )
2158 for (h = lines - 1; h >= 0; h--) {
2159 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2160 for (x = 0; x < srcwidth; x++, bits += 3) {
2162 bits[0] = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2163 bits[1] = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2164 bits[2] = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x07)); /*Blue*/
2166 bits = (dstbits += linebytes);
2169 else goto notsupported;
2174 /* ==== monochrome bitmap to 24 BGR dib ==== */
2176 /* ==== 4 colormap bitmap to 24 BGR dib ==== */
2177 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2179 LPBYTE bits = dstbits;
2182 for (h = lines - 1; h >= 0; h--) {
2183 for (x = 0; x < dstwidth; x++) {
2184 val = srccolors[XGetPixel(bmpImage, x, h)];
2185 *bits++ = val.peBlue;
2186 *bits++ = val.peGreen;
2187 *bits++ = val.peRed;
2189 bits = (dstbits += linebytes);
2192 else goto notsupported;
2197 /* ==== 8 colormap bitmap to 24 BGR dib ==== */
2198 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask == 0 && srccolors)
2201 LPBYTE bits = dstbits;
2204 for (h = lines - 1; h >= 0; h--) {
2205 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
2206 for (x = 0; x < dstwidth; x++ ) {
2207 val = srccolors[(int)*srcpixel++];
2208 *bits++ = val.peBlue; /*Blue*/
2209 *bits++ = val.peGreen; /*Green*/
2210 *bits++ = val.peRed; /*Red*/
2212 bits = (dstbits += linebytes);
2215 else goto notsupported;
2222 LPBYTE bits = dstbits;
2224 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 24 bit DIB\n",
2225 bmpImage->depth, (int)bmpImage->red_mask,
2226 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2227 for (h = lines - 1; h >= 0; h--)
2229 for (x = 0; x < dstwidth; x++, bits += 3)
2231 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
2232 bits[0] = GetBValue(pixel);
2233 bits[1] = GetGValue(pixel);
2234 bits[2] = GetRValue(pixel);
2236 bits = (dstbits += linebytes);
2244 /***********************************************************************
2245 * X11DRV_DIB_SetImageBits_32
2247 * SetDIBits for a 32-bit deep DIB.
2249 static void X11DRV_DIB_SetImageBits_32( int lines, const BYTE *srcbits,
2250 DWORD srcwidth, DWORD dstwidth, int left,
2251 DC *dc, XImage *bmpImage )
2256 DWORD linebytes = (srcwidth * 4);
2261 srcbits = srcbits + ( linebytes * (lines-1) );
2262 linebytes = -linebytes;
2265 ptr = (DWORD *) srcbits + left;
2267 switch ( bmpImage->depth )
2270 /* ==== 32 BGR dib to 24/32 BGR bitmap ==== */
2271 if (bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff) {
2272 for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
2273 memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
2277 /* ==== 32 BGR dib to 24/32 RGB bitmap ==== */
2278 else if (bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000)
2282 for (h = lines - 1; h >= 0; h--) {
2283 dstpixel = (DWORD *) (bmpImage->data + h * bmpImage->bytes_per_line);
2284 for (x = 0; x < dstwidth; x++, ptr++) {
2285 *dstpixel++ = ((*ptr << 16) & 0xff0000) | (*ptr & 0xff00) | ((*ptr >> 16) & 0xff);
2287 ptr = (DWORD *) (srcbits += linebytes) + left;
2290 else goto notsupported;
2295 /* ==== 32 BGR dib to 24 (888) BGR bitmap ==== */
2296 /* we need to check that source mask matches destination */
2300 ptr = (DWORD *) srcbits + left;
2301 bptr = bmpImage->data;
2303 for (h = lines - 1; h >= 0; h--) {
2304 for (x = 0; x < dstwidth; x++) {
2305 /* *ptr is a 32bit value */
2306 /* bptr points to first of 3 bytes */
2307 *bptr++ = (*ptr >> 16) & 0xff;
2308 *bptr++ = (*ptr >> 8) & 0xff;
2309 *bptr++ = (*ptr ) & 0xff;
2312 ptr = (DWORD *) (srcbits += linebytes) + left;
2318 /* ==== 32 BGR dib to 555 BGR bitmap ==== */
2319 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f) {
2322 for (h = lines - 1; h >= 0; h--) {
2323 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2324 for (x = 0; x < dstwidth; x++, ptr++) {
2325 *dstpixel++ = (WORD) (((*ptr >> 9) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 3) & 0x001f));
2327 ptr = (DWORD *) (srcbits += linebytes) + left;
2330 /* ==== 32 BGR dib to 555 RGB bitmap ==== */
2331 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
2335 for (h = lines - 1; h >= 0; h--) {
2336 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2337 for (x = 0; x < dstwidth; x++, ptr++) {
2338 *dstpixel++ = (WORD) (((*ptr << 7) & 0x7c00) | ((*ptr >> 6) & 0x03e0) | ((*ptr >> 19) & 0x001f));
2340 ptr = (DWORD *) (srcbits += linebytes) + left;
2343 else goto notsupported;
2348 /* ==== 32 BGR dib to 565 BGR bitmap ==== */
2349 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2353 for (h = lines - 1; h >= 0; h--) {
2354 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2355 for (x = 0; x < dstwidth; x++, ptr++) {
2356 *dstpixel++ = (WORD) (((*ptr >> 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 3) & 0x001f));
2358 ptr = (DWORD *) (srcbits += linebytes) + left;
2361 /* ==== 32 BGR dib to 565 RGB bitmap ==== */
2362 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0xf800)
2366 for (h = lines - 1; h >= 0; h--) {
2367 dstpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2368 for (x = 0; x < dstwidth; x++, ptr++) {
2369 *dstpixel++ = (WORD) (((*ptr << 8) & 0xf800) | ((*ptr >> 5) & 0x07e0) | ((*ptr >> 19) & 0x001f));
2371 ptr = (DWORD *) (srcbits += linebytes) + left;
2374 else goto notsupported;
2382 LPBYTE bits = (LPBYTE)srcbits + left*4;
2384 for (h = lines - 1; h >= 0; h--) {
2385 for (x = left; x < dstwidth+left; x++, bits += 4)
2386 XPutPixel( bmpImage, x, h,
2387 X11DRV_PALETTE_ToPhysical(dc, RGB( bits[2], bits[1], *bits )));
2388 bits = (LPBYTE)(srcbits += linebytes) + left * 4;
2395 FIXME("32 bit DIB %d bit bitmap\n", bmpImage->bits_per_pixel);
2401 /***********************************************************************
2402 * X11DRV_DIB_GetImageBits_32
2404 * GetDIBits for an 32-bit deep DIB.
2406 static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
2407 DWORD dstwidth, DWORD srcwidth,
2408 PALETTEENTRY *srccolors, XImage *bmpImage )
2414 /* align to 32 bit */
2415 DWORD linebytes = (srcwidth * 4);
2416 DWORD copybytes = linebytes;
2421 dstbits = dstbits + ( linebytes * (lines-1) );
2422 linebytes = -linebytes;
2427 switch ( bmpImage->depth )
2430 /* ==== 24/32 BGR bitmap to 32 BGR dib ==== */
2431 if ( bmpImage->red_mask == 0xff0000 && bmpImage->blue_mask == 0xff )
2432 for (h = lines - 1; h >= 0; h--, dstbits+=linebytes)
2433 memcpy( dstbits, bmpImage->data + h*bmpImage->bytes_per_line, copybytes );
2435 /* ==== 24/32 RGB bitmap to 32 BGR dib ==== */
2436 else if ( bmpImage->red_mask == 0xff && bmpImage->blue_mask == 0xff0000 )
2440 for (h = lines - 1; h >= 0; h--) {
2441 srcbits = bmpImage->data + h * bmpImage->bytes_per_line;
2442 for (x = 0; x < dstwidth; x++, bits+=4, srcbits+=2) {
2443 *(bits + 2) = *srcbits++;
2444 *(bits + 1) = *srcbits++;
2447 bits = (dstbits += linebytes);
2450 else goto notsupported;
2454 /* ==== 24 BGR bitmap to 32 (0888) BGR dib ==== */
2455 /* we need to check that source mask matches destination */
2461 srcpixel = (DWORD *) dstbits;
2462 bptr = bmpImage->data;
2464 for (h = lines - 1; h >= 0; h--) {
2465 for (x = 0; x < dstwidth; x++) {
2466 /* *srcpixel is a 32bit value */
2467 /* bptr points to first of 3 bytes */
2469 srcdata = srcdata << 8 | *bptr++;
2470 srcdata = srcdata << 8 | *bptr++;
2471 srcdata = srcdata << 8 | *bptr++;
2473 *srcpixel++ = srcdata;
2475 srcpixel = (DWORD *) (dstbits += linebytes);
2485 /* ==== 555 BGR bitmap to 32 BGR dib ==== */
2486 if (bmpImage->red_mask == 0x7c00 && bmpImage->blue_mask == 0x001f)
2488 for (h = lines - 1; h >= 0; h--) {
2489 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2490 for (x = 0; x < dstwidth; x++, bits+=2) {
2492 *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
2493 *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
2494 *bits = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07)); /*Red*/
2496 bits = (dstbits += linebytes);
2499 /* ==== 555 RGB bitmap to 32 BGR dib ==== */
2500 else if (bmpImage->red_mask == 0x001f && bmpImage->blue_mask == 0x7c00)
2502 for (h = lines - 1; h >= 0; h--) {
2503 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2504 for (x = 0; x < dstwidth; x++, bits+=2) {
2506 *bits++ = (BYTE)(((val >> 7) & 0xf8) | ((val >> 12) & 0x07));/*Blue*/
2507 *bits++ = (BYTE)(((val >> 2) & 0xfc) | ((val >> 8) & 0x03)); /*Green*/
2508 *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Red*/
2510 bits = (dstbits += linebytes);
2513 else goto notsupported;
2522 /* ==== 565 BGR bitmap to 32 BGR dib ==== */
2523 if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2525 for (h = lines - 1; h >= 0; h--) {
2526 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2527 for (x = 0; x < srcwidth; x++, bits+=2) {
2529 *bits++ = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Blue*/
2530 *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2531 *bits = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07)); /*Red*/
2533 bits = (dstbits += linebytes);
2536 /* ==== 565 RGB bitmap to 32 BGR dib ==== */
2537 else if (bmpImage->red_mask == 0xf800 && bmpImage->blue_mask == 0x001f)
2539 for (h = lines - 1; h >= 0; h--) {
2540 srcpixel = (LPWORD) (bmpImage->data + h * bmpImage->bytes_per_line);
2541 for (x = 0; x < srcwidth; x++, bits+=2) {
2543 *bits++ = (BYTE)(((val >> 8) & 0xf8) | ((val >> 13) & 0x07));/*Blue*/
2544 *bits++ = (BYTE)(((val >> 3) & 0xfc) | ((val >> 9) & 0x03)); /*Green*/
2545 *bits = (BYTE)(((val << 3) & 0xf8) | ((val >> 2) & 0x03)); /*Red*/
2547 bits = (dstbits += linebytes);
2550 else goto notsupported;
2555 /* ==== monochrome bitmap to 32 BGR dib ==== */
2557 /* ==== 4 colormap bitmap to 32 BGR dib ==== */
2558 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2562 for (h = lines - 1; h >= 0; h--) {
2563 for (x = 0; x < dstwidth; x++) {
2564 val = srccolors[XGetPixel(bmpImage, x, h)];
2565 *bits++ = val.peBlue;
2566 *bits++ = val.peGreen;
2567 *bits++ = val.peRed;
2570 bits = (dstbits += linebytes);
2573 else goto notsupported;
2578 /* ==== 8 colormap bitmap to 32 BGR dib ==== */
2579 if (bmpImage->red_mask==0 && bmpImage->green_mask==0 && bmpImage->blue_mask==0 && srccolors)
2584 for (h = lines - 1; h >= 0; h--) {
2585 srcpixel = bmpImage->data + h*bmpImage->bytes_per_line;
2586 for (x = 0; x < dstwidth; x++) {
2587 val = srccolors[(int)*srcpixel++];
2588 *bits++ = val.peBlue; /*Blue*/
2589 *bits++ = val.peGreen; /*Green*/
2590 *bits++ = val.peRed; /*Red*/
2593 bits = (dstbits += linebytes);
2596 else goto notsupported;
2601 FIXME("from %d bit bitmap with mask R,G,B %x,%x,%x to 32 bit DIB\n",
2602 bmpImage->depth, (int)bmpImage->red_mask,
2603 (int)bmpImage->green_mask, (int)bmpImage->blue_mask );
2604 for (h = lines - 1; h >= 0; h--)
2606 for (x = 0; x < dstwidth; x++, bits += 4)
2608 COLORREF pixel = X11DRV_PALETTE_ToLogical( XGetPixel( bmpImage, x, h ) );
2609 bits[0] = GetBValue(pixel);
2610 bits[1] = GetGValue(pixel);
2611 bits[2] = GetRValue(pixel);
2613 bits = (dstbits += linebytes);
2619 /***********************************************************************
2620 * X11DRV_DIB_SetImageBits
2622 * Transfer the bits to an X image.
2623 * Helper function for SetDIBits() and SetDIBitsToDevice().
2624 * The Xlib critical section must be entered before calling this function.
2626 int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
2628 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
2632 bmpImage = descr->image;
2634 bmpImage = XCreateImage( display, X11DRV_GetVisual(), descr->depth, ZPixmap, 0, NULL,
2635 descr->infoWidth, lines, 32, 0 );
2636 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
2637 if(bmpImage->data == NULL) {
2638 ERR("Out of memory!\n");
2639 XDestroyImage( bmpImage );
2644 /* Transfer the pixels */
2645 switch(descr->infoBpp)
2648 X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
2649 descr->width, descr->xSrc, (int *)(descr->colorMap),
2653 if (descr->compression) {
2654 XGetSubImage( display, descr->drawable, descr->xDest, descr->yDest,
2655 descr->width, descr->height, AllPlanes, ZPixmap,
2656 bmpImage, descr->xSrc, descr->ySrc );
2658 X11DRV_DIB_SetImageBits_RLE4( descr->lines, descr->bits,
2659 descr->infoWidth, descr->width,
2660 descr->xSrc, (int *)(descr->colorMap),
2663 X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
2664 descr->infoWidth, descr->width,
2665 descr->xSrc, (int*)(descr->colorMap),
2669 if (descr->compression) {
2670 XGetSubImage( display, descr->drawable, descr->xDest, descr->yDest,
2671 descr->width, descr->height, AllPlanes, ZPixmap,
2672 bmpImage, descr->xSrc, descr->ySrc );
2673 X11DRV_DIB_SetImageBits_RLE8( descr->lines, descr->bits,
2674 descr->infoWidth, descr->width,
2675 descr->xSrc, (int *)(descr->colorMap),
2678 X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
2679 descr->infoWidth, descr->width,
2680 descr->xSrc, (int *)(descr->colorMap),
2685 X11DRV_DIB_SetImageBits_16( descr->lines, descr->bits,
2686 descr->infoWidth, descr->width,
2687 descr->xSrc, descr->dc,
2688 descr->rMask, descr->gMask, descr->bMask,
2692 X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
2693 descr->infoWidth, descr->width,
2694 descr->xSrc, descr->dc, bmpImage );
2697 X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
2698 descr->infoWidth, descr->width,
2699 descr->xSrc, descr->dc,
2703 WARN("(%d): Invalid depth\n", descr->infoBpp );
2709 XShmPutImage( display, descr->drawable, descr->gc, bmpImage,
2710 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2711 descr->width, descr->height, FALSE );
2712 XSync( display, 0 );
2715 XPutImage( display, descr->drawable, descr->gc, bmpImage,
2716 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
2717 descr->width, descr->height );
2719 if (!descr->image) XDestroyImage( bmpImage );
2723 /***********************************************************************
2724 * X11DRV_DIB_GetImageBits
2726 * Transfer the bits from an X image.
2727 * The Xlib critical section must be entered before calling this function.
2729 int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
2731 int lines = descr->lines >= 0 ? descr->lines : -descr->lines;
2735 bmpImage = descr->image;
2737 bmpImage = XCreateImage( display, X11DRV_GetVisual(), descr->depth, ZPixmap, 0, NULL,
2738 descr->infoWidth, lines, 32, 0 );
2739 bmpImage->data = calloc( lines, bmpImage->bytes_per_line );
2740 if(bmpImage->data == NULL) {
2741 ERR("Out of memory!\n");
2742 XDestroyImage( bmpImage );
2746 XGetSubImage( display, descr->drawable, descr->xSrc, descr->ySrc,
2747 descr->width, lines, AllPlanes, ZPixmap,
2748 bmpImage, descr->xDest, descr->yDest );
2750 /* Transfer the pixels */
2751 switch(descr->infoBpp)
2754 X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
2755 descr->infoWidth, descr->width,
2756 descr->colorMap, descr->palentry,
2761 if (descr->compression)
2762 FIXME("Compression not yet supported!\n");
2764 X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
2765 descr->infoWidth, descr->width,
2766 descr->colorMap, descr->palentry,
2771 if (descr->compression)
2772 FIXME("Compression not yet supported!\n");
2774 X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
2775 descr->infoWidth, descr->width,
2776 descr->colorMap, descr->palentry,
2781 X11DRV_DIB_GetImageBits_16( descr->lines, (LPVOID)descr->bits,
2782 descr->infoWidth,descr->width,
2784 descr->rMask, descr->gMask, descr->bMask,
2789 X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
2790 descr->infoWidth,descr->width,
2791 descr->palentry, bmpImage );
2795 X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
2796 descr->infoWidth, descr->width,
2797 descr->palentry, bmpImage );
2801 WARN("(%d): Invalid depth\n", descr->infoBpp );
2805 if (!descr->image) XDestroyImage( bmpImage );
2809 /*************************************************************************
2810 * X11DRV_SetDIBitsToDevice
2813 INT X11DRV_SetDIBitsToDevice( DC *dc, INT xDest, INT yDest, DWORD cx,
2814 DWORD cy, INT xSrc, INT ySrc,
2815 UINT startscan, UINT lines, LPCVOID bits,
2816 const BITMAPINFO *info, UINT coloruse )
2818 X11DRV_DIB_IMAGEBITS_DESCR descr;
2819 DWORD width, oldcy = cy;
2821 int height, tmpheight;
2822 X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
2825 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
2826 &descr.infoBpp, &descr.compression ) == -1)
2829 if (height < 0) height = -height;
2830 if (!lines || (startscan >= height)) return 0;
2831 if (startscan + lines > height) lines = height - startscan;
2832 if (ySrc < startscan) ySrc = startscan;
2833 else if (ySrc >= startscan + lines) return 0;
2834 if (xSrc >= width) return 0;
2835 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
2836 if (xSrc + cx >= width) cx = width - xSrc;
2837 if (!cx || !cy) return 0;
2839 X11DRV_SetupGCForText( dc ); /* To have the correct colors */
2840 TSXSetFunction(display, physDev->gc, X11DRV_XROPfunction[dc->ROPmode-1]);
2842 switch (descr.infoBpp)
2847 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
2848 coloruse == DIB_PAL_COLORS ? dc : NULL, coloruse,
2849 dc->bitsPerPixel, info, &descr.nColorMap );
2850 if (!descr.colorMap) return 0;
2851 descr.rMask = descr.gMask = descr.bMask = 0;
2855 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
2856 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
2857 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
2862 descr.rMask = descr.gMask = descr.bMask = 0;
2867 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
2868 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
2869 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
2877 descr.palentry = NULL;
2878 descr.lines = tmpheight >= 0 ? lines : -lines;
2879 descr.infoWidth = width;
2880 descr.depth = dc->bitsPerPixel;
2881 descr.drawable = physDev->drawable;
2882 descr.gc = physDev->gc;
2884 descr.ySrc = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy)
2886 descr.xDest = dc->DCOrgX + XLPTODP( dc, xDest );
2887 descr.yDest = dc->DCOrgY + YLPTODP( dc, yDest ) +
2888 (tmpheight >= 0 ? oldcy-cy : 0);
2891 descr.useShm = FALSE;
2893 EnterCriticalSection( &X11DRV_CritSection );
2894 result = CALL_LARGE_STACK( X11DRV_DIB_SetImageBits, &descr );
2895 LeaveCriticalSection( &X11DRV_CritSection );
2897 if (descr.infoBpp <= 8)
2898 HeapFree(GetProcessHeap(), 0, descr.colorMap);
2902 /***********************************************************************
2903 * X11DRV_DIB_SetDIBits
2905 INT X11DRV_DIB_SetDIBits(
2906 BITMAPOBJ *bmp, DC *dc, UINT startscan,
2907 UINT lines, LPCVOID bits, const BITMAPINFO *info,
2908 UINT coloruse, HBITMAP hbitmap)
2910 X11DRV_DIB_IMAGEBITS_DESCR descr;
2911 int height, tmpheight;
2916 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
2917 &descr.infoBpp, &descr.compression ) == -1)
2921 if (height < 0) height = -height;
2922 if (!lines || (startscan >= height))
2925 if (startscan + lines > height) lines = height - startscan;
2927 switch (descr.infoBpp)
2932 descr.colorMap = (RGBQUAD *)X11DRV_DIB_BuildColorMap(
2933 coloruse == DIB_PAL_COLORS ? descr.dc : NULL, coloruse,
2934 bmp->bitmap.bmBitsPixel,
2935 info, &descr.nColorMap );
2936 if (!descr.colorMap) return 0;
2937 descr.rMask = descr.gMask = descr.bMask = 0;
2941 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
2942 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
2943 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
2948 descr.rMask = descr.gMask = descr.bMask = 0;
2953 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
2954 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
2955 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
2963 if(!bmp->physBitmap)
2964 X11DRV_CreateBitmap(hbitmap);
2968 descr.palentry = NULL;
2969 descr.lines = tmpheight >= 0 ? lines : -lines;
2970 descr.depth = bmp->bitmap.bmBitsPixel;
2971 descr.drawable = (Pixmap)bmp->physBitmap;
2972 descr.gc = BITMAP_GC(bmp);
2976 descr.yDest = height - startscan - lines;
2977 descr.width = bmp->bitmap.bmWidth;
2978 descr.height = lines;
2979 descr.useShm = FALSE;
2981 EnterCriticalSection( &X11DRV_CritSection );
2982 result = CALL_LARGE_STACK( X11DRV_DIB_SetImageBits, &descr );
2983 LeaveCriticalSection( &X11DRV_CritSection );
2985 if (descr.colorMap) HeapFree(GetProcessHeap(), 0, descr.colorMap);
2990 /***********************************************************************
2991 * X11DRV_DIB_GetDIBits
2993 INT X11DRV_DIB_GetDIBits(
2994 BITMAPOBJ *bmp, DC *dc, UINT startscan,
2995 UINT lines, LPVOID bits, BITMAPINFO *info,
2996 UINT coloruse, HBITMAP hbitmap)
2998 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
2999 X11DRV_DIB_IMAGEBITS_DESCR descr;
3000 PALETTEOBJ * palette;
3002 TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
3003 lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
3004 (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
3007 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC )))
3010 if( lines > info->bmiHeader.biHeight ) lines = info->bmiHeader.biHeight;
3011 /* Top-down images have a negative biHeight, the scanlines of theses images
3012 * were inverted in X11DRV_DIB_GetImageBits_xx
3013 * To prevent this we simply change the sign of lines
3014 * (the number of scan lines to copy).
3015 * Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
3017 if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
3019 if( startscan >= bmp->bitmap.bmHeight )
3025 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
3026 &descr.infoBpp, &descr.compression ) == -1)
3032 switch (descr.infoBpp)
3038 descr.rMask = descr.gMask = descr.bMask = 0;
3042 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
3043 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
3044 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
3048 descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
3049 descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0xff00;
3050 descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0xff;
3055 if(!bmp->physBitmap)
3056 X11DRV_CreateBitmap(hbitmap);
3060 descr.palentry = palette->logpalette.palPalEntry;
3063 descr.lines = lines;
3064 descr.depth = bmp->bitmap.bmBitsPixel;
3065 descr.drawable = (Pixmap)bmp->physBitmap;
3066 descr.gc = BITMAP_GC(bmp);
3067 descr.width = bmp->bitmap.bmWidth;
3068 descr.height = bmp->bitmap.bmHeight;
3069 descr.colorMap = info->bmiColors;
3074 if (descr.lines > 0)
3076 descr.ySrc = (descr.height-1) - (startscan + (lines-1));
3080 descr.ySrc = startscan;
3082 #ifdef HAVE_LIBXXSHM
3084 descr.useShm = (dib->shminfo.shmid != -1);
3087 descr.useShm = FALSE;
3089 EnterCriticalSection( &X11DRV_CritSection );
3091 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits, &descr );
3093 LeaveCriticalSection( &X11DRV_CritSection );
3095 if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
3096 info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
3097 info->bmiHeader.biWidth,
3098 info->bmiHeader.biHeight,
3099 info->bmiHeader.biBitCount );
3101 info->bmiHeader.biCompression = 0;
3104 GDI_ReleaseObj( dc->hPalette );
3109 /***********************************************************************
3110 * DIB_DoProtectDIBSection
3112 static void X11DRV_DIB_DoProtectDIBSection( BITMAPOBJ *bmp, DWORD new_prot )
3114 DIBSECTION *dib = bmp->dib;
3115 INT effHeight = dib->dsBm.bmHeight >= 0? dib->dsBm.bmHeight
3116 : -dib->dsBm.bmHeight;
3117 /* use the biSizeImage data as the memory size only if we're dealing with a
3118 compressed image where the value is set. Otherwise, calculate based on
3120 INT totalSize = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
3121 ? dib->dsBmih.biSizeImage
3122 : dib->dsBm.bmWidthBytes * effHeight;
3125 VirtualProtect(dib->dsBm.bmBits, totalSize, new_prot, &old_prot);
3126 TRACE("Changed protection from %ld to %ld\n", old_prot, new_prot);
3129 /***********************************************************************
3130 * X11DRV_DIB_DoUpdateDIBSection
3132 static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
3134 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3135 X11DRV_DIB_IMAGEBITS_DESCR descr;
3137 if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
3138 &descr.infoBpp, &descr.compression ) == -1)
3142 descr.palentry = NULL;
3143 descr.image = dib->image;
3144 descr.colorMap = (RGBQUAD *)dib->colorMap;
3145 descr.nColorMap = dib->nColorMap;
3146 descr.bits = dib->dibSection.dsBm.bmBits;
3147 descr.depth = bmp->bitmap.bmBitsPixel;
3149 switch (descr.infoBpp)
3155 descr.rMask = descr.gMask = descr.bMask = 0;
3159 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0x7c00;
3160 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0x03e0;
3161 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0x001f;
3165 descr.rMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[0] : 0xff;
3166 descr.gMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[1] : 0xff00;
3167 descr.bMask = (descr.compression == BI_BITFIELDS) ? dib->dibSection.dsBitfields[2] : 0xff0000;
3172 descr.drawable = (Pixmap)bmp->physBitmap;
3173 descr.gc = BITMAP_GC(bmp);
3178 descr.width = bmp->bitmap.bmWidth;
3179 descr.height = bmp->bitmap.bmHeight;
3180 #ifdef HAVE_LIBXXSHM
3181 descr.useShm = (dib->shminfo.shmid != -1);
3183 descr.useShm = FALSE;
3188 TRACE("Copying from Pixmap to DIB bits\n");
3189 EnterCriticalSection( &X11DRV_CritSection );
3190 CALL_LARGE_STACK( X11DRV_DIB_GetImageBits, &descr );
3191 LeaveCriticalSection( &X11DRV_CritSection );
3195 TRACE("Copying from DIB bits to Pixmap\n");
3196 EnterCriticalSection( &X11DRV_CritSection );
3197 CALL_LARGE_STACK( X11DRV_DIB_SetImageBits, &descr );
3198 LeaveCriticalSection( &X11DRV_CritSection );
3202 /***********************************************************************
3203 * X11DRV_DIB_FaultHandler
3205 static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
3207 BOOL handled = FALSE;
3210 bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
3211 if (!bmp) return FALSE;
3214 switch (((X11DRV_DIBSECTION *) bmp->dib)->status)
3216 case X11DRV_DIB_GdiMod:
3217 TRACE("called in status DIB_GdiMod\n" );
3218 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3219 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3220 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3221 ((X11DRV_DIBSECTION *) bmp->dib)->status = X11DRV_DIB_InSync;
3225 case X11DRV_DIB_InSync:
3226 TRACE("called in status X11DRV_DIB_InSync\n" );
3227 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3228 ((X11DRV_DIBSECTION *) bmp->dib)->status = X11DRV_DIB_AppMod;
3232 case X11DRV_DIB_AppMod:
3233 FIXME("called in status X11DRV_DIB_AppMod: this can't happen!\n" );
3236 case X11DRV_DIB_NoHandler:
3237 FIXME("called in status DIB_NoHandler: this can't happen!\n" );
3241 GDI_ReleaseObj( (HBITMAP)res );
3245 /***********************************************************************
3246 * X11DRV_DIB_CmnUpdateDIBSection
3248 static void X11DRV_DIB_CmnUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
3251 if (!bmp->dib) return;
3255 /* Prepare for access to the DIB by GDI functions */
3257 switch (((X11DRV_DIBSECTION *) bmp->dib)->status)
3260 case X11DRV_DIB_NoHandler:
3261 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
3264 case X11DRV_DIB_GdiMod:
3265 TRACE("fromDIB called in status X11DRV_DIB_GdiMod\n" );
3269 case X11DRV_DIB_InSync:
3270 TRACE("fromDIB called in status X11DRV_DIB_InSync\n" );
3274 case X11DRV_DIB_AppMod:
3275 TRACE("fromDIB called in status X11DRV_DIB_AppMod\n" );
3276 X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
3277 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3278 ((X11DRV_DIBSECTION *) bmp->dib)->status = X11DRV_DIB_InSync;
3284 /* Acknowledge write access to the DIB by GDI functions */
3286 switch (((X11DRV_DIBSECTION *) bmp->dib)->status)
3289 case X11DRV_DIB_NoHandler:
3290 X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
3293 case X11DRV_DIB_GdiMod:
3294 TRACE(" toDIB called in status X11DRV_DIB_GdiMod\n" );
3298 case X11DRV_DIB_InSync:
3299 TRACE(" toDIB called in status X11DRV_DIB_InSync\n" );
3300 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
3301 ((X11DRV_DIBSECTION *) bmp->dib)->status = X11DRV_DIB_GdiMod;
3304 case X11DRV_DIB_AppMod:
3305 FIXME(" toDIB called in status X11DRV_DIB_AppMod: "
3306 "this can't happen!\n" );
3312 /***********************************************************************
3313 * X11DRV_DIB_UpdateDIBSection2
3315 void X11DRV_DIB_UpdateDIBSection2(HBITMAP hbmp, BOOL toDIB)
3319 bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbmp, BITMAP_MAGIC );
3322 X11DRV_DIB_CmnUpdateDIBSection(bmp, toDIB);
3324 GDI_ReleaseObj(hbmp);
3327 /***********************************************************************
3328 * X11DRV_DIB_UpdateDIBSection
3330 void X11DRV_DIB_UpdateDIBSection(DC *dc, BOOL toDIB)
3332 /* Ensure this is a Compatible DC that has a DIB section selected */
3335 if (!(dc->flags & DC_MEMORY)) return;
3337 X11DRV_DIB_UpdateDIBSection2(dc->hBitmap, toDIB);
3340 /***********************************************************************
3341 * X11DRV_DIB_CreateDIBSection16
3343 HBITMAP16 X11DRV_DIB_CreateDIBSection16(
3344 DC *dc, BITMAPINFO *bmi, UINT16 usage,
3345 SEGPTR *bits, HANDLE section,
3346 DWORD offset, DWORD ovr_pitch)
3348 HBITMAP res = X11DRV_DIB_CreateDIBSection(dc, bmi, usage, NULL,
3349 section, offset, ovr_pitch);
3352 BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
3353 if ( bmp && bmp->dib )
3355 DIBSECTION *dib = bmp->dib;
3356 INT height = dib->dsBm.bmHeight >= 0 ?
3357 dib->dsBm.bmHeight : -dib->dsBm.bmHeight;
3358 /* same as above - only use biSizeImage as the correct size if it a
3359 compressed image and it's currently non-zero. In other cases, use
3360 width * height as the value. */
3361 INT size = dib->dsBmih.biSizeImage && dib->dsBmih.biCompression != BI_RGB
3362 ? dib->dsBmih.biSizeImage
3363 : dib->dsBm.bmWidthBytes * height;
3364 if ( dib->dsBm.bmBits )
3366 ((X11DRV_DIBSECTION *) bmp->dib)->selector =
3367 SELECTOR_AllocBlock( dib->dsBm.bmBits, size, WINE_LDT_FLAGS_DATA );
3369 TRACE("ptr = %p, size =%d, selector = %04x, segptr = %ld\n",
3370 dib->dsBm.bmBits, size, ((X11DRV_DIBSECTION *) bmp->dib)->selector,
3371 PTR_SEG_OFF_TO_SEGPTR(((X11DRV_DIBSECTION *) bmp->dib)->selector, 0));
3373 *bits = PTR_SEG_OFF_TO_SEGPTR( ((X11DRV_DIBSECTION *) bmp->dib)->selector, 0 );
3375 if (bmp) GDI_ReleaseObj( res );
3381 /***********************************************************************
3382 * X11DRV_XShmErrorHandler
3385 static int XShmErrorHandler(Display *dpy, XErrorEvent *event)
3391 /***********************************************************************
3392 * X11DRV_XShmCreateImage
3396 #ifdef HAVE_LIBXXSHM
3397 extern BOOL X11DRV_XShmCreateImage(XImage** image, int width, int height, int bpp,
3398 XShmSegmentInfo* shminfo)
3400 int (*WineXHandler)(Display *, XErrorEvent *);
3402 *image = TSXShmCreateImage(display, X11DRV_GetVisual(), bpp, ZPixmap, NULL, shminfo, width, height);
3403 if( *image != NULL )
3405 EnterCriticalSection( &X11DRV_CritSection );
3406 shminfo->shmid = shmget(IPC_PRIVATE, (*image)->bytes_per_line * height,
3408 if( shminfo->shmid != -1 )
3410 shminfo->shmaddr = (*image)->data = shmat(shminfo->shmid, 0, 0);
3411 if( shminfo->shmaddr != (char*)-1 )
3413 shminfo->readOnly = FALSE;
3414 if( TSXShmAttach( display, shminfo ) != 0)
3416 /* Reset the error flag */
3418 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3419 XSync( display, 0 );
3423 shmctl(shminfo->shmid, IPC_RMID, 0);
3425 XSetErrorHandler(WineXHandler);
3426 LeaveCriticalSection( &X11DRV_CritSection );
3428 return TRUE; /* Success! */
3430 /* An error occured */
3432 XSetErrorHandler(WineXHandler);
3434 shmdt(shminfo->shmaddr);
3436 shmctl(shminfo->shmid, IPC_RMID, 0);
3439 XDestroyImage(*image);
3440 LeaveCriticalSection( &X11DRV_CritSection );
3444 #endif /* HAVE_LIBXXSHM */
3448 /***********************************************************************
3449 * X11DRV_DIB_CreateDIBSection
3451 HBITMAP X11DRV_DIB_CreateDIBSection(
3452 DC *dc, BITMAPINFO *bmi, UINT usage,
3453 LPVOID *bits, HANDLE section,
3454 DWORD offset, DWORD ovr_pitch)
3457 BITMAPOBJ *bmp = NULL;
3458 X11DRV_DIBSECTION *dib = NULL;
3459 int *colorMap = NULL;
3462 /* Fill BITMAP32 structure with DIB data */
3463 BITMAPINFOHEADER *bi = &bmi->bmiHeader;
3464 INT effHeight, totalSize;
3467 TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
3468 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
3469 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
3471 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
3473 bm.bmWidth = bi->biWidth;
3474 bm.bmHeight = effHeight;
3475 bm.bmWidthBytes = ovr_pitch ? ovr_pitch
3476 : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
3477 bm.bmPlanes = bi->biPlanes;
3478 bm.bmBitsPixel = bi->biBitCount;
3481 /* Get storage location for DIB bits. Only use biSizeImage if it's valid and
3482 we're dealing with a compressed bitmap. Otherwise, use width * height. */
3483 totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
3484 ? bi->biSizeImage : bm.bmWidthBytes * effHeight;
3487 bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS,
3488 0L, offset, totalSize);
3489 else if (ovr_pitch && offset)
3490 bm.bmBits = (LPVOID) offset;
3493 bm.bmBits = VirtualAlloc(NULL, totalSize,
3494 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
3497 /* Create Color Map */
3498 if (bm.bmBits && bm.bmBitsPixel <= 8)
3499 colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? dc : NULL,
3500 usage, bm.bmBitsPixel, bmi, &nColorMap );
3502 /* Allocate Memory for DIB and fill structure */
3504 dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
3507 dib->dibSection.dsBm = bm;
3508 dib->dibSection.dsBmih = *bi;
3509 dib->dibSection.dsBmih.biSizeImage = totalSize;
3511 /* Set dsBitfields values */
3512 if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
3514 dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
3516 else switch( bi->biBitCount )
3519 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
3520 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
3521 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
3525 dib->dibSection.dsBitfields[0] = 0xff;
3526 dib->dibSection.dsBitfields[1] = 0xff00;
3527 dib->dibSection.dsBitfields[2] = 0xff0000;
3531 dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff;
3532 dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0xff00;
3533 dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0xff0000;
3536 dib->dibSection.dshSection = section;
3537 dib->dibSection.dsOffset = offset;
3539 dib->status = X11DRV_DIB_NoHandler;
3542 dib->nColorMap = nColorMap;
3543 dib->colorMap = colorMap;
3546 /* Create Device Dependent Bitmap and add DIB pointer */
3549 res = CreateDIBitmap(dc->hSelf, bi, 0, NULL, bmi, usage);
3552 bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
3555 bmp->dib = (DIBSECTION *) dib;
3557 if(!bmp->physBitmap)
3558 X11DRV_CreateBitmap(res);
3566 #ifdef HAVE_LIBXXSHM
3567 if (TSXShmQueryExtension(display) &&
3568 X11DRV_XShmCreateImage( &dib->image, bm.bmWidth, effHeight,
3569 bmp->bitmap.bmBitsPixel, &dib->shminfo ) )
3571 ; /* Created Image */
3573 XCREATEIMAGE( dib->image, bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
3574 dib->shminfo.shmid = -1;
3577 XCREATEIMAGE( dib->image, bm.bmWidth, effHeight, bmp->bitmap.bmBitsPixel );
3581 /* Clean up in case of errors */
3582 if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
3584 TRACE("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n",
3585 res, bmp, dib, bm.bmBits);
3589 UnmapViewOfFile(bm.bmBits), bm.bmBits = NULL;
3591 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
3594 if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
3595 if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
3596 if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
3597 if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
3598 if (res) { DeleteObject(res); res = 0; }
3601 /* Install fault handler, if possible */
3604 if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
3606 if (section || offset)
3608 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
3609 if (dib) dib->status = X11DRV_DIB_AppMod;
3613 X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
3614 if (dib) dib->status = X11DRV_DIB_InSync;
3619 /* Return BITMAP handle and storage location */
3620 if (bmp) GDI_ReleaseObj(res);
3621 if (bm.bmBits && bits) *bits = bm.bmBits;
3625 /***********************************************************************
3626 * X11DRV_DIB_DeleteDIBSection
3628 void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
3630 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3634 #ifdef HAVE_LIBXXSHM
3635 if (dib->shminfo.shmid != -1)
3637 TSXShmDetach (display, &(dib->shminfo));
3638 XDestroyImage (dib->image);
3639 shmdt (dib->shminfo.shmaddr);
3640 dib->shminfo.shmid = -1;
3644 XDestroyImage( dib->image );
3648 HeapFree(GetProcessHeap(), 0, dib->colorMap);
3650 if (dib->selector) SELECTOR_FreeBlock( dib->selector );
3653 /***********************************************************************
3654 * X11DRV_DIB_SetDIBColorTable
3656 UINT X11DRV_DIB_SetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, const RGBQUAD *colors)
3658 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3660 if (dib && dib->colorMap) {
3661 X11DRV_DIB_GenColorMap( dc, dib->colorMap, DIB_RGB_COLORS, dib->dibSection.dsBm.bmBitsPixel,
3662 TRUE, colors, start, count + start );
3668 /***********************************************************************
3669 * X11DRV_DIB_GetDIBColorTable
3671 UINT X11DRV_DIB_GetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT count, RGBQUAD *colors)
3673 X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
3675 if (dib && dib->colorMap) {
3676 int i, end = count + start;
3677 if (end > dib->nColorMap) end = dib->nColorMap;
3678 for (i = start; i < end; i++,colors++) {
3679 COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] );
3680 colors->rgbBlue = GetBValue(col);
3681 colors->rgbGreen = GetGValue(col);
3682 colors->rgbRed = GetRValue(col);
3683 colors->rgbReserved = 0;
3691 /**************************************************************************
3692 * X11DRV_DIB_CreateDIBFromPixmap
3694 * Allocates a packed DIB and copies the Pixmap data into it.
3695 * If bDeletePixmap is TRUE, the Pixmap passed in is deleted after the conversion.
3697 HGLOBAL X11DRV_DIB_CreateDIBFromPixmap(Pixmap pixmap, HDC hdc, BOOL bDeletePixmap)
3700 BITMAPOBJ *pBmp = NULL;
3701 HGLOBAL hPackedDIB = 0;
3703 /* Allocates an HBITMAP which references the Pixmap passed to us */
3704 hBmp = X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(pixmap);
3707 TRACE("\tCould not create bitmap header for Pixmap\n");
3712 * Create a packed DIB from the Pixmap wrapper bitmap created above.
3713 * A packed DIB contains a BITMAPINFO structure followed immediately by
3714 * an optional color palette and the pixel data.
3716 hPackedDIB = DIB_CreateDIBFromBitmap(hdc, hBmp);
3718 /* Get a pointer to the BITMAPOBJ structure */
3719 pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3721 /* We can now get rid of the HBITMAP wrapper we created earlier.
3722 * Note: Simply calling DeleteObject will free the embedded Pixmap as well.
3726 /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
3727 pBmp->physBitmap = NULL;
3730 GDI_ReleaseObj( hBmp );
3734 TRACE("\tReturning packed DIB %x\n", hPackedDIB);
3739 /**************************************************************************
3740 * X11DRV_DIB_CreatePixmapFromDIB
3742 * Creates a Pixmap from a packed DIB
3744 Pixmap X11DRV_DIB_CreatePixmapFromDIB( HGLOBAL hPackedDIB, HDC hdc )
3746 Pixmap pixmap = None;
3748 BITMAPOBJ *pBmp = NULL;
3749 LPBYTE pPackedDIB = NULL;
3750 LPBITMAPINFO pbmi = NULL;
3751 LPBITMAPINFOHEADER pbmiHeader = NULL;
3752 LPBYTE pbits = NULL;
3754 /* Get a pointer to the packed DIB's data */
3755 pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
3756 pbmiHeader = (LPBITMAPINFOHEADER)pPackedDIB;
3757 pbmi = (LPBITMAPINFO)pPackedDIB;
3758 pbits = (LPBYTE)(pPackedDIB
3759 + DIB_BitmapInfoSize( (LPBITMAPINFO)pbmiHeader, DIB_RGB_COLORS ));
3761 /* Create a DDB from the DIB */
3763 hBmp = CreateDIBitmap(hdc,
3770 GlobalUnlock(hPackedDIB);
3772 TRACE("CreateDIBitmap returned %x\n", hBmp);
3774 /* Retrieve the internal Pixmap from the DDB */
3776 pBmp = (BITMAPOBJ *) GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
3778 pixmap = (Pixmap)pBmp->physBitmap;
3779 /* clear the physBitmap so that we can steal its pixmap */
3780 pBmp->physBitmap = NULL;
3783 /* Delete the DDB we created earlier now that we have stolen its pixmap */
3784 GDI_ReleaseObj( hBmp );
3787 TRACE("\tReturning Pixmap %ld\n", pixmap);