Release 960611
[wine/multimedia.git] / objects / dib.c
blobbecf1853c338e314227729b3400fffe750f6a136
1 /*
2 * GDI device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <X11/Xlib.h>
10 #include <X11/Xutil.h>
11 #include "dc.h"
12 #include "bitmap.h"
13 #include "callback.h"
14 #include "palette.h"
15 #include "stackframe.h"
16 #include "stddebug.h"
17 #include "color.h"
18 #include "debug.h"
19 #include "xmalloc.h"
21 extern void CLIPPING_UpdateGCRegion(DC* );
23 /***********************************************************************
24 * DIB_GetImageWidthBytes
26 * Return the width of an X image in bytes
28 int DIB_GetImageWidthBytes( int width, int depth )
30 int words;
32 switch(depth)
34 case 1: words = (width + 31) / 32; break;
35 case 4: words = (width + 7) / 8; break;
36 case 8: words = (width + 3) / 4; break;
37 case 15:
38 case 16: words = (width + 1) / 2; break;
39 case 24: words = width; break;
40 default:
41 fprintf(stderr, "DIB: unsupported depth %d.\n", depth );
42 exit(1);
44 return 4 * words;
48 /***********************************************************************
49 * DIB_BitmapInfoSize
51 * Return the size of the bitmap info structure.
53 int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse )
55 int colors;
57 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
59 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
60 colors = (core->bcBitCount != 24) ? 1 << core->bcBitCount : 0;
61 return sizeof(BITMAPCOREHEADER) + colors *
62 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
64 else /* assume BITMAPINFOHEADER */
66 colors = info->bmiHeader.biClrUsed;
67 if (!colors && (info->bmiHeader.biBitCount != 24))
68 colors = 1 << info->bmiHeader.biBitCount;
69 return sizeof(BITMAPINFOHEADER) + colors *
70 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
75 /***********************************************************************
76 * DIB_DIBmpToImage
78 * Create an XImage pointing to the bitmap data.
80 static XImage *DIB_DIBmpToImage( BITMAPINFOHEADER * bmp, void * bmpData )
82 extern void _XInitImageFuncPtrs( XImage* );
83 XImage * image;
85 image = XCreateImage(display, DefaultVisualOfScreen( screen ),
86 bmp->biBitCount, ZPixmap, 0, bmpData,
87 bmp->biWidth, bmp->biHeight, 32,
88 DIB_GetImageWidthBytes(bmp->biWidth,bmp->biBitCount));
89 if (!image) return 0;
90 image->byte_order = MSBFirst;
91 image->bitmap_bit_order = MSBFirst;
92 image->bitmap_unit = 16;
93 _XInitImageFuncPtrs(image);
94 return image;
98 /***********************************************************************
99 * DIB_GetBitmapInfo
101 * Get the info from a bitmap header.
102 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
104 static int DIB_GetBitmapInfo( BITMAPINFOHEADER *header, DWORD *width,
105 DWORD *height, WORD *bpp )
107 if (header->biSize == sizeof(BITMAPINFOHEADER))
109 *width = header->biWidth;
110 *height = header->biHeight;
111 *bpp = header->biBitCount;
112 return 1;
114 if (header->biSize == sizeof(BITMAPCOREHEADER))
116 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
117 *width = core->bcWidth;
118 *height = core->bcHeight;
119 *bpp = core->bcBitCount;
120 return 0;
122 fprintf( stderr, "DIB_GetBitmapInfo: wrong size (%ld) for header\n",
123 header->biSize );
124 return -1;
128 /***********************************************************************
129 * DIB_BuildColorMap
131 * Build the color map from the bitmap palette. Should not be called
132 * for a 24-bit deep bitmap.
134 static int *DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth,
135 BITMAPINFO *info )
137 int i, colors;
138 BOOL isInfo;
139 WORD *colorPtr;
140 int *colorMapping;
142 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
144 colors = info->bmiHeader.biClrUsed;
145 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
146 colorPtr = (WORD *)info->bmiColors;
148 else /* assume BITMAPCOREINFO */
150 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
151 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
153 if (!(colorMapping = (int *)malloc( colors * sizeof(int) ))) return NULL;
155 if (coloruse == DIB_RGB_COLORS)
157 if (isInfo)
159 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
161 if (depth == 1) /* Monochrome */
162 for (i = 0; i < colors; i++, rgb++)
163 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
164 rgb->rgbBlue > 255*3/2);
165 else
166 for (i = 0; i < colors; i++, rgb++)
167 colorMapping[i] = COLOR_ToPhysical( dc, RGB(rgb->rgbRed,
168 rgb->rgbGreen,
169 rgb->rgbBlue));
171 else
173 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
175 if (depth == 1) /* Monochrome */
176 for (i = 0; i < colors; i++, rgb++)
177 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
178 rgb->rgbtBlue > 255*3/2);
179 else
180 for (i = 0; i < colors; i++, rgb++)
181 colorMapping[i] = COLOR_ToPhysical( dc, RGB(rgb->rgbtRed,
182 rgb->rgbtGreen,
183 rgb->rgbtBlue));
186 else /* DIB_PAL_COLORS */
188 for (i = 0; i < colors; i++, colorPtr++)
189 colorMapping[i] = COLOR_ToPhysical( dc, PALETTEINDEX(*colorPtr) );
191 return colorMapping;
195 /***********************************************************************
196 * DIB_SetImageBits_1
198 * SetDIBits for a 1-bit deep DIB.
200 static void DIB_SetImageBits_1( WORD lines, BYTE *bits, WORD width,
201 int *colors, XImage *bmpImage )
203 WORD i, x;
204 BYTE pad, pix;
206 if (!(width & 31)) pad = 0;
207 else pad = ((32 - (width & 31)) + 7) / 8;
209 while (lines--)
211 for (i = width/8, x = 0; (i > 0); i--)
213 pix = *bits++;
214 XPutPixel( bmpImage, x++, lines, colors[pix >> 7] );
215 XPutPixel( bmpImage, x++, lines, colors[(pix >> 6) & 1] );
216 XPutPixel( bmpImage, x++, lines, colors[(pix >> 5) & 1] );
217 XPutPixel( bmpImage, x++, lines, colors[(pix >> 4) & 1] );
218 XPutPixel( bmpImage, x++, lines, colors[(pix >> 3) & 1] );
219 XPutPixel( bmpImage, x++, lines, colors[(pix >> 2) & 1] );
220 XPutPixel( bmpImage, x++, lines, colors[(pix >> 1) & 1] );
221 XPutPixel( bmpImage, x++, lines, colors[pix & 1] );
223 pix = *bits;
224 switch(width & 7)
226 case 7: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
227 case 6: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
228 case 5: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
229 case 4: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
230 case 3: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
231 case 2: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] ); pix <<= 1;
232 case 1: XPutPixel( bmpImage, x++, lines, colors[pix >> 7] );
234 bits += pad;
239 /***********************************************************************
240 * DIB_SetImageBits_4
242 * SetDIBits for a 4-bit deep DIB.
244 static void DIB_SetImageBits_4( WORD lines, BYTE *bits, WORD width,
245 int *colors, XImage *bmpImage )
247 WORD i, x;
248 BYTE pad;
250 if (!(width & 7)) pad = 0;
251 else pad = ((8 - (width & 7)) + 1) / 2;
253 while (lines--)
255 for (i = width/2, x = 0; i > 0; i--)
257 BYTE pix = *bits++;
258 XPutPixel( bmpImage, x++, lines, colors[pix >> 4] );
259 XPutPixel( bmpImage, x++, lines, colors[pix & 0x0f] );
261 if (width & 1) XPutPixel( bmpImage, x, lines, colors[*bits >> 4] );
262 bits += pad;
266 #define check_xy(x,y) \
267 if (x > width) { \
268 x = 0; \
269 if (lines) \
270 lines--; \
273 /***********************************************************************
274 * DIB_SetImageBits_RLE4
276 * SetDIBits for a 4-bit deep compressed DIB.
278 static void DIB_SetImageBits_RLE4( WORD lines, BYTE *bits, WORD width,
279 int *colors, XImage *bmpImage )
281 int x = 0, c, length;
282 BYTE *begin = bits;
284 lines--;
285 while ((short)lines >= 0)
287 length = *bits++;
288 if (length) { /* encoded */
289 c = *bits++;
290 while (length--) {
291 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
292 check_xy(x, y);
293 if (length) {
294 length--;
295 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
296 check_xy(x, y);
299 } else {
300 length = *bits++;
301 switch (length) {
302 case 0: /* eol */
303 x = 0;
304 lines--;
305 continue;
307 case 1: /* eopicture */
308 return;
310 case 2: /* delta */
311 x += *bits++;
312 lines -= *bits++;
313 continue;
315 default: /* absolute */
316 while (length--) {
317 c = *bits++;
318 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
319 check_xy(x, y);
320 if (length) {
321 length--;
322 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
323 check_xy(x, y);
326 if ((bits - begin) & 1)
327 bits++;
333 /***********************************************************************
334 * DIB_SetImageBits_8
336 * SetDIBits for an 8-bit deep DIB.
338 static void DIB_SetImageBits_8( WORD lines, BYTE *bits, WORD width,
339 int *colors, XImage *bmpImage )
341 WORD x;
342 BYTE pad = (4 - (width & 3)) & 3;
344 while (lines--)
346 for (x = 0; x < width; x++)
347 XPutPixel( bmpImage, x, lines, colors[*bits++] );
348 bits += pad;
352 /***********************************************************************
353 * DIB_SetImageBits_RLE8
355 * SetDIBits for an 8-bit deep compressed DIB.
357 * This function rewritten 941113 by James Youngman. WINE blew out when I
358 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
360 * This was because the algorithm assumed that all RLE8 bitmaps end with the
361 * 'End of bitmap' escape code. This code is very much laxer in what it
362 * allows to end the expansion. Possibly too lax. See the note by
363 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
364 * bitmap should end with RleEnd, but on the other hand, software exists
365 * that produces ones that don't and Windows 3.1 doesn't complain a bit
366 * about it.
368 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
369 * James A. Youngman <mbcstjy@afs.man.ac.uk>
370 * [JAY]
373 enum Rle8_EscapeCodes
376 * Apologies for polluting your file's namespace...
378 RleEol = 0, /* End of line */
379 RleEnd = 1, /* End of bitmap */
380 RleDelta = 2 /* Delta */
383 static void DIB_SetImageBits_RLE8(WORD lines,
384 BYTE *bits,
385 WORD width,
386 int *colors,
387 XImage *bmpImage)
389 int x; /* X-positon on each line. Increases. */
390 int line; /* Line #. Starts at lines-1, decreases */
391 BYTE *pIn = bits; /* Pointer to current position in bits */
392 BYTE length; /* The length pf a run */
393 BYTE color_index; /* index into colors[] as read from bits */
394 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
395 WORD color; /* value of colour[color_index] */
397 if (lines == 0) /* Let's hope this doesn't happen. */
398 return;
401 * Note that the bitmap data is stored by Windows starting at the
402 * bottom line of the bitmap and going upwards. Within each line,
403 * the data is stored left-to-right. That's the reason why line
404 * goes from lines-1 to 0. [JAY]
407 x = 0;
408 line = lines-1;
411 length = *pIn++;
414 * If the length byte is not zero (which is the escape value),
415 * We have a run of length pixels all the same colour. The colour
416 * index is stored next.
418 * If the length byte is zero, we need to read the next byte to
419 * know what to do. [JAY]
421 if (length != 0)
424 * [Run-Length] Encoded mode
426 color_index = (*pIn++); /* Get the colour index. */
427 color = colors[color_index];
429 while(length--)
430 XPutPixel(bmpImage, x++, line, color);
432 else
435 * Escape codes (may be an absolute sequence though)
437 escape_code = (*pIn++);
438 switch(escape_code)
440 case RleEol: /* =0, end of line */
442 x = 0;
443 line--;
444 break;
447 case RleEnd: /* =1, end of bitmap */
450 * Not all RLE8 bitmaps end with this
451 * code. For example, Paint Shop Pro
452 * produces some that don't. That's (I think)
453 * what caused the previous implementation to
454 * fail. [JAY]
456 line=-1; /* Cause exit from do loop. */
457 break;
460 case RleDelta: /* =2, a delta */
463 * Note that deltaing to line 0
464 * will cause an exit from the loop,
465 * which may not be what is intended.
466 * The fact that there is a delta in the bits
467 * almost certainly implies that there is data
468 * to follow. You may feel that we should
469 * jump to the top of the loop to avoid exiting
470 * in this case.
472 * TODO: Decide what to do here in that case. [JAY]
474 x += (*pIn++);
475 line -= (*pIn++);
476 if (line == 0)
478 dprintf_bitmap(stddeb,
479 "DIB_SetImageBits_RLE8(): "
480 "Delta to last line of bitmap "
481 "(wrongly?) causes loop exit\n");
483 break;
486 default: /* >2, switch to absolute mode */
489 * Absolute Mode
491 length = escape_code;
492 while(length--)
494 color_index = (*pIn++);
495 XPutPixel(bmpImage, x++, line,
496 colors[color_index]);
500 * If you think for a moment you'll realise that the
501 * only time we could ever possibly read an odd
502 * number of bytes is when there is a 0x00 (escape),
503 * a value >0x02 (absolute mode) and then an odd-
504 * length run. Therefore this is the only place we
505 * need to worry about it. Everywhere else the
506 * bytes are always read in pairs. [JAY]
508 if (escape_code & 1)
509 pIn++; /* Throw away the pad byte. */
510 break;
512 } /* switch (escape_code) : Escape sequence */
513 } /* process either an encoded sequence or an escape sequence */
515 /* We expect to come here more than once per line. */
516 } while (line >= 0); /* Do this until the bitmap is filled */
519 * Everybody comes here at the end.
520 * Check how we exited the loop and print a message if it's a bit odd.
521 * [JAY]
523 if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) )
525 dprintf_bitmap(stddeb, "DIB_SetImageBits_RLE8(): End-of-bitmap "
526 "without (strictly) proper escape code. Last two "
527 "bytes were: %02X %02X.\n",
528 (int)*(pIn-2),
529 (int)*(pIn-1));
534 /***********************************************************************
535 * DIB_SetImageBits_24
537 * SetDIBits for a 24-bit deep DIB.
539 static void DIB_SetImageBits_24( WORD lines, BYTE *bits, WORD width,
540 DC *dc, XImage *bmpImage )
542 WORD x;
543 BYTE pad = (4 - ((width*3) & 3)) & 3;
545 while (lines--)
547 for (x = 0; x < width; x++, bits += 3)
549 XPutPixel( bmpImage, x, lines,
550 COLOR_ToPhysical( dc, RGB(bits[0],bits[1],bits[2]) ));
552 bits += pad;
557 /***********************************************************************
558 * DIB_SetImageBits
560 * Transfer the bits to an X image.
561 * Helper function for SetDIBits() and SetDIBitsToDevice().
563 static int DIB_SetImageBits( DC *dc, WORD lines, WORD depth, LPSTR bits,
564 DWORD infoWidth, WORD infoBpp, DWORD compression,
565 BITMAPINFO *info, WORD coloruse,
566 Drawable drawable, GC gc, int xSrc, int ySrc,
567 int xDest, int yDest, int width, int height )
569 int *colorMapping;
570 XImage *bmpImage;
572 /* Build the color mapping table */
574 if (infoBpp == 24) colorMapping = NULL;
575 else
576 if (!(colorMapping = DIB_BuildColorMap( dc, coloruse, depth, info )))
577 return 0;
579 if( dc->w.flags & DC_DIRTY ) CLIPPING_UpdateGCRegion(dc);
581 /* Transfer the pixels */
582 XCREATEIMAGE(bmpImage, infoWidth, lines, depth );
584 switch(infoBpp)
586 case 1:
587 DIB_SetImageBits_1( lines, bits, infoWidth,
588 colorMapping, bmpImage );
589 break;
590 case 4:
591 if (compression) DIB_SetImageBits_RLE4( lines, bits, infoWidth,
592 colorMapping, bmpImage );
593 else DIB_SetImageBits_4( lines, bits, infoWidth,
594 colorMapping, bmpImage );
595 break;
596 case 8:
597 if (compression) DIB_SetImageBits_RLE8( lines, bits, infoWidth,
598 colorMapping, bmpImage );
599 else DIB_SetImageBits_8( lines, bits, infoWidth,
600 colorMapping, bmpImage );
601 break;
602 case 24:
603 DIB_SetImageBits_24( lines, bits, infoWidth, dc, bmpImage );
604 break;
605 default:
606 fprintf( stderr, "Invalid depth %d for SetDIBits!\n", infoBpp );
607 break;
609 if (colorMapping) free(colorMapping);
610 XPutImage( display, drawable, gc, bmpImage, xSrc, ySrc,
611 xDest, yDest, width, height );
612 XDestroyImage( bmpImage );
613 return lines;
617 /***********************************************************************
618 * StretchDIBits (GDI.439)
620 int StretchDIBits( HDC hdc,
621 WORD xDest, WORD yDest, WORD wDestWidth, WORD wDestHeight,
622 WORD xSrc, WORD ySrc, WORD wSrcWidth, WORD wSrcHeight,
623 LPSTR bits, LPBITMAPINFO info, WORD wUsage, DWORD dwRop )
625 HBITMAP hBitmap, hOldBitmap;
626 HDC hdcMem;
628 hBitmap = CreateDIBitmap( hdc, &info->bmiHeader, CBM_INIT,
629 bits, info, wUsage );
630 hdcMem = CreateCompatibleDC( hdc );
631 hOldBitmap = SelectObject( hdcMem, hBitmap );
632 StretchBlt( hdc, xDest, yDest, wDestWidth, wDestHeight,
633 hdcMem, xSrc, ySrc, wSrcWidth, wSrcHeight, dwRop );
634 SelectObject( hdcMem, hOldBitmap );
635 DeleteDC( hdcMem );
636 DeleteObject( hBitmap );
637 return wSrcHeight;
641 /***********************************************************************
642 * SetDIBits (GDI.440)
644 int SetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines,
645 LPSTR bits, BITMAPINFO * info, WORD coloruse )
647 DC * dc;
648 BITMAPOBJ * bmp;
649 DWORD width, height, compression = 0;
650 WORD bpp;
652 /* Check parameters */
654 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
655 if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
656 return 0;
657 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &bpp ) == -1)
658 return 0;
659 if (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
660 compression = info->bmiHeader.biCompression;
661 if (!lines || (startscan >= (WORD)height)) return 0;
662 if (startscan + lines > height) lines = height - startscan;
664 return CallTo32_LargeStack( (int(*)())DIB_SetImageBits, 17,
665 dc, lines, bmp->bitmap.bmBitsPixel,
666 bits, width, bpp, compression, info,
667 coloruse, bmp->pixmap, BITMAP_GC(bmp), 0, 0, 0,
668 startscan, bmp->bitmap.bmWidth, lines );
672 /***********************************************************************
673 * SetDIBitsToDevice (GDI.443)
675 int SetDIBitsToDevice( HDC hdc, short xDest, short yDest, WORD cx, WORD cy,
676 WORD xSrc, WORD ySrc, WORD startscan, WORD lines,
677 LPSTR bits, BITMAPINFO * info, WORD coloruse )
679 DC * dc;
680 DWORD width, height, compression = 0;
681 WORD bpp;
683 /* Check parameters */
685 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
686 if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &bpp ) == -1)
687 return 0;
688 if (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
689 compression = info->bmiHeader.biCompression;
690 if (!lines || (startscan >= height)) return 0;
691 if (startscan + lines > height) lines = height - startscan;
692 if (ySrc < startscan) ySrc = startscan;
693 else if (ySrc >= startscan + lines) return 0;
694 if (xSrc >= width) return 0;
695 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
696 if (xSrc + cx >= width) cx = width - xSrc;
697 if (!cx || !cy) return 0;
699 DC_SetupGCForText( dc ); /* To have the correct colors */
700 XSetFunction( display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] );
701 return CallTo32_LargeStack( (int(*)())DIB_SetImageBits, 17,
702 dc, lines, dc->w.bitsPerPixel, bits, width,
703 bpp, compression, info, coloruse,
704 dc->u.x.drawable, dc->u.x.gc,
705 xSrc, ySrc - startscan,
706 dc->w.DCOrgX + XLPTODP( dc, xDest ),
707 dc->w.DCOrgY + YLPTODP( dc, yDest ),
708 cx, cy );
713 /***********************************************************************
714 * GetDIBits (GDI.441)
716 int GetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines,
717 LPSTR bits, BITMAPINFO * info, WORD coloruse )
719 DC * dc;
720 BITMAPOBJ * bmp;
721 PALETTEENTRY * palEntry;
722 PALETTEOBJ * palette;
723 XImage * bmpImage, * dibImage;
724 int i, x, y;
726 if (!lines) return 0;
727 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
728 if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
729 return 0;
730 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
731 return 0;
733 /* Transfer color info */
735 palEntry = palette->logpalette.palPalEntry;
736 for (i = 0; i < info->bmiHeader.biClrUsed; i++, palEntry++)
738 if (coloruse == DIB_RGB_COLORS)
740 info->bmiColors[i].rgbRed = palEntry->peRed;
741 info->bmiColors[i].rgbGreen = palEntry->peGreen;
742 info->bmiColors[i].rgbBlue = palEntry->peBlue;
743 info->bmiColors[i].rgbReserved = 0;
745 else ((WORD *)info->bmiColors)[i] = (WORD)i;
748 /* Transfer the pixels (very slow...) */
750 if (bits)
752 bmpImage = (XImage *)CallTo32_LargeStack( (int (*)())XGetImage, 8,
753 display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth,
754 bmp->bitmap.bmHeight, AllPlanes, ZPixmap );
755 dibImage = DIB_DIBmpToImage( &info->bmiHeader, bits );
757 for (y = 0; y < lines; y++)
759 for (x = 0; x < info->bmiHeader.biWidth; x++)
761 XPutPixel( dibImage, x, y,
762 XGetPixel(bmpImage, x, bmp->bitmap.bmHeight-startscan-y-1) );
767 dibImage->data = NULL;
768 XDestroyImage( dibImage );
769 XDestroyImage( bmpImage );
771 info->bmiHeader.biCompression = 0;
772 return lines;
776 /***********************************************************************
777 * CreateDIBitmap (GDI.442)
779 HBITMAP CreateDIBitmap( HDC hdc, BITMAPINFOHEADER * header, DWORD init,
780 LPVOID bits, BITMAPINFO * data, UINT coloruse )
782 HBITMAP handle;
783 BOOL fColor;
784 DWORD width, height;
785 WORD bpp;
787 if (DIB_GetBitmapInfo( header, &width, &height, &bpp ) == -1) return 0;
789 /* Check if we should create a monochrome or color bitmap. */
790 /* We create a monochrome bitmap only if it has exactly 2 */
791 /* colors, which are either black or white, nothing else. */
792 /* In all other cases, we create a color bitmap. */
794 if (bpp != 1) fColor = TRUE;
795 else if ((coloruse != DIB_RGB_COLORS) ||
796 (init != CBM_INIT) || !data) fColor = FALSE;
797 else
799 if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
801 RGBQUAD *rgb = data->bmiColors;
802 DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
803 if ((col == RGB(0,0,0)) || (col == RGB(0xff,0xff,0xff)))
805 rgb++;
806 col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
807 fColor = ((col != RGB(0,0,0)) && (col != RGB(0xff,0xff,0xff)));
809 else fColor = TRUE;
811 else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
813 RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
814 DWORD col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
815 if ((col == RGB(0,0,0)) || (col == RGB(0xff,0xff,0xff)))
817 rgb++;
818 col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
819 fColor = ((col != RGB(0,0,0)) && (col != RGB(0xff,0xff,0xff)));
821 else fColor = TRUE;
823 else
825 fprintf( stderr, "CreateDIBitmap: wrong size (%ld) for data\n",
826 data->bmiHeader.biSize );
827 return 0;
831 /* Now create the bitmap */
833 handle = fColor ? CreateCompatibleBitmap( hdc, width, height ) :
834 CreateBitmap( width, height, 1, 1, NULL );
835 if (!handle) return 0;
837 if (init == CBM_INIT)
838 SetDIBits( hdc, handle, 0, height, bits, data, coloruse );
839 return handle;