Release 980215
[wine/multimedia.git] / objects / dib.c
blobc4227ef0ddb0ac769ecc4e9bef9eaf51edab209a
1 /*
2 * GDI device-independent bitmaps
4 * Copyright 1993,1994 Alexandre Julliard
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "ts_xlib.h"
10 #include "ts_xutil.h"
11 #include "dc.h"
12 #include "bitmap.h"
13 #include "callback.h"
14 #include "palette.h"
15 #include "stddebug.h"
16 #include "color.h"
17 #include "debug.h"
19 extern void CLIPPING_UpdateGCRegion(DC* );
21 static int bitmapDepthTable[] = { 8, 1, 32, 16, 24, 15, 4, 0 };
22 static int ximageDepthTable[] = { 0, 0, 0, 0, 0, 0, 0 };
25 /* This structure holds the arguments for DIB_SetImageBits() */
26 typedef struct
28 DC *dc;
29 LPCVOID bits;
30 int lines;
31 DWORD infoWidth;
32 WORD depth;
33 WORD infoBpp;
34 const BITMAPINFO *info;
35 WORD coloruse;
36 Drawable drawable;
37 GC gc;
38 int xSrc;
39 int ySrc;
40 int xDest;
41 int yDest;
42 int width;
43 int height;
44 } DIB_SETIMAGEBITS_DESCR;
47 /***********************************************************************
48 * DIB_Init
50 BOOL32 DIB_Init(void)
52 int i;
53 XImage* testimage;
55 for( i = 0; bitmapDepthTable[i]; i++ )
57 testimage = TSXCreateImage(display, DefaultVisualOfScreen(screen),
58 bitmapDepthTable[i], ZPixmap, 0, NULL, 1, 1, 32, 20 );
59 if( testimage ) ximageDepthTable[i] = testimage->bits_per_pixel;
60 else return FALSE;
61 TSXDestroyImage(testimage);
63 return TRUE;
66 /***********************************************************************
67 * DIB_GetXImageWidthBytes
69 * Return the width of an X image in bytes
71 int DIB_GetXImageWidthBytes( int width, int depth )
73 int i;
75 if (!ximageDepthTable[0]) {
76 DIB_Init();
78 for( i = 0; bitmapDepthTable[i] ; i++ )
79 if( bitmapDepthTable[i] == depth )
80 return (4 * ((width * ximageDepthTable[i] + 31)/32));
81 fprintf(stderr, "DIB: unsupported depth %d.\n", depth );
82 return (4 * width);
85 /***********************************************************************
86 * DIB_GetDIBWidthBytes
88 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
89 * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
91 int DIB_GetDIBWidthBytes( int width, int depth )
93 int words;
95 switch(depth)
97 case 1: words = (width + 31) / 32; break;
98 case 4: words = (width + 7) / 8; break;
99 case 8: words = (width + 3) / 4; break;
100 case 15:
101 case 16: words = (width + 1) / 2; break;
102 case 24: words = (width * 3 + 3)/4; break;
104 default:
105 fprintf(stderr, "DIB: unsupported depth %d.\n", depth );
106 /* fall through */
107 case 32:
108 words = width;
110 return 4 * words;
114 /***********************************************************************
115 * DIB_BitmapInfoSize
117 * Return the size of the bitmap info structure including color table.
119 int DIB_BitmapInfoSize( BITMAPINFO * info, WORD coloruse )
121 int colors;
123 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
125 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
126 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
127 return sizeof(BITMAPCOREHEADER) + colors *
128 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
130 else /* assume BITMAPINFOHEADER */
132 colors = info->bmiHeader.biClrUsed;
133 if (!colors && (info->bmiHeader.biBitCount <= 8))
134 colors = 1 << info->bmiHeader.biBitCount;
135 return sizeof(BITMAPINFOHEADER) + colors *
136 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
141 /***********************************************************************
142 * DIB_GetBitmapInfo
144 * Get the info from a bitmap header.
145 * Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
147 static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
148 int *height, WORD *bpp )
150 if (header->biSize == sizeof(BITMAPINFOHEADER))
152 *width = header->biWidth;
153 *height = header->biHeight;
154 *bpp = header->biBitCount;
155 return 1;
157 if (header->biSize == sizeof(BITMAPCOREHEADER))
159 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
160 *width = core->bcWidth;
161 *height = core->bcHeight;
162 *bpp = core->bcBitCount;
163 return 0;
165 fprintf( stderr, "DIB_GetBitmapInfo: wrong size (%ld) for header\n",
166 header->biSize );
167 return -1;
171 /***********************************************************************
172 * DIB_BuildColorMap
174 * Build the color map from the bitmap palette. Should not be called
175 * for a 24-bit deep bitmap.
177 static int *DIB_BuildColorMap( DC *dc, WORD coloruse, WORD depth,
178 const BITMAPINFO *info )
180 int i, colors;
181 BOOL32 isInfo;
182 WORD *colorPtr;
183 int *colorMapping;
185 if ((isInfo = (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))))
187 colors = info->bmiHeader.biClrUsed;
188 if (!colors) colors = 1 << info->bmiHeader.biBitCount;
189 colorPtr = (WORD *)info->bmiColors;
191 else /* assume BITMAPCOREINFO */
193 colors = 1 << ((BITMAPCOREHEADER *)&info->bmiHeader)->bcBitCount;
194 colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
196 if (!(colorMapping = (int *)HeapAlloc(GetProcessHeap(), 0,
197 colors * sizeof(int) ))) return NULL;
199 if (coloruse == DIB_RGB_COLORS)
201 if (isInfo)
203 RGBQUAD * rgb = (RGBQUAD *)colorPtr;
205 if (depth == 1) /* Monochrome */
206 for (i = 0; i < colors; i++, rgb++)
207 colorMapping[i] = (rgb->rgbRed + rgb->rgbGreen +
208 rgb->rgbBlue > 255*3/2);
209 else
210 for (i = 0; i < colors; i++, rgb++)
211 colorMapping[i] = COLOR_ToPhysical( dc, RGB(rgb->rgbRed,
212 rgb->rgbGreen,
213 rgb->rgbBlue));
215 else
217 RGBTRIPLE * rgb = (RGBTRIPLE *)colorPtr;
219 if (depth == 1) /* Monochrome */
220 for (i = 0; i < colors; i++, rgb++)
221 colorMapping[i] = (rgb->rgbtRed + rgb->rgbtGreen +
222 rgb->rgbtBlue > 255*3/2);
223 else
224 for (i = 0; i < colors; i++, rgb++)
225 colorMapping[i] = COLOR_ToPhysical( dc, RGB(rgb->rgbtRed,
226 rgb->rgbtGreen,
227 rgb->rgbtBlue));
230 else /* DIB_PAL_COLORS */
232 for (i = 0; i < colors; i++, colorPtr++)
233 colorMapping[i] = COLOR_ToPhysical( dc, PALETTEINDEX(*colorPtr) );
235 return colorMapping;
238 /***********************************************************************
239 * DIB_SetImageBits_1_Line
241 * Handles a single line of 1 bit data.
243 static void DIB_SetImageBits_1_Line(DWORD dstwidth, int left, int *colors,
244 XImage *bmpImage, int h, const BYTE *bits)
246 BYTE pix;
247 DWORD i, x;
249 dstwidth += left; bits += left >> 3;
251 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
252 for (i = dstwidth/8, x = left&~7; (i > 0); i--)
254 pix = *bits++;
255 XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
256 XPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] );
257 XPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] );
258 XPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] );
259 XPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] );
260 XPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] );
261 XPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] );
262 XPutPixel( bmpImage, x++, h, colors[pix & 1] );
264 pix = *bits;
265 switch(dstwidth & 7)
267 case 7: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
268 case 6: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
269 case 5: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
270 case 4: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
271 case 3: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
272 case 2: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
273 case 1: XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
277 /***********************************************************************
278 * DIB_SetImageBits_1
280 * SetDIBits for a 1-bit deep DIB.
282 static void DIB_SetImageBits_1( int lines, const BYTE *srcbits,
283 DWORD srcwidth, DWORD dstwidth, int left,
284 int *colors, XImage *bmpImage )
286 int h;
288 /* 32 bit aligned */
289 DWORD linebytes = ((srcwidth + 31) & ~31) / 8;
291 if (lines > 0) {
292 for (h = lines-1; h >=0; h--) {
293 DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h, srcbits);
294 srcbits += linebytes;
296 } else {
297 lines = -lines;
298 for (h = 0; h < lines; h++) {
299 DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h, srcbits);
300 srcbits += linebytes;
306 /***********************************************************************
307 * DIB_SetImageBits_4
309 * SetDIBits for a 4-bit deep DIB.
311 static void DIB_SetImageBits_4( int lines, const BYTE *srcbits,
312 DWORD srcwidth, DWORD dstwidth, int left,
313 int *colors, XImage *bmpImage )
315 DWORD i, x;
316 int h;
317 const BYTE *bits = srcbits + (left >> 1);
319 /* 32 bit aligned */
320 DWORD linebytes = ((srcwidth+7)&~7)/2;
322 dstwidth += left;
324 /* FIXME: should avoid putting x<left pixels (minor speed issue) */
325 if (lines > 0) {
326 for (h = lines-1; h >= 0; h--) {
327 for (i = dstwidth/2, x = left&~1; i > 0; i--) {
328 BYTE pix = *bits++;
329 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
330 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
332 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
333 srcbits += linebytes;
334 bits = srcbits + (left >> 1);
336 } else {
337 lines = -lines;
338 for (h = 0; h < lines; h++) {
339 for (i = dstwidth/2, x = left&~1; i > 0; i--) {
340 BYTE pix = *bits++;
341 XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
342 XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
344 if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
345 srcbits += linebytes;
346 bits = srcbits + (left >> 1);
351 #define check_xy(x,y) \
352 if (x > width) { \
353 x = 0; \
354 if (lines) \
355 lines--; \
358 /***********************************************************************
359 * DIB_SetImageBits_RLE4
361 * SetDIBits for a 4-bit deep compressed DIB.
363 static void DIB_SetImageBits_RLE4( int lines, const BYTE *bits, DWORD width,
364 DWORD dstwidth, int left, int *colors, XImage *bmpImage )
366 int x = 0, c, length;
367 const BYTE *begin = bits;
369 dstwidth += left; /* FIXME: avoid putting x<left pixels */
371 lines--;
372 while ((int)lines >= 0)
374 length = *bits++;
375 if (length) { /* encoded */
376 c = *bits++;
377 while (length--) {
378 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
379 check_xy(x, y);
380 if (length) {
381 length--;
382 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
383 check_xy(x, y);
386 } else {
387 length = *bits++;
388 switch (length) {
389 case 0: /* eol */
390 x = 0;
391 lines--;
392 continue;
394 case 1: /* eopicture */
395 return;
397 case 2: /* delta */
398 x += *bits++;
399 lines -= *bits++;
400 continue;
402 default: /* absolute */
403 while (length--) {
404 c = *bits++;
405 XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
406 check_xy(x, y);
407 if (length) {
408 length--;
409 XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
410 check_xy(x, y);
413 if ((bits - begin) & 1)
414 bits++;
420 /***********************************************************************
421 * DIB_SetImageBits_8
423 * SetDIBits for an 8-bit deep DIB.
425 static void DIB_SetImageBits_8( int lines, const BYTE *srcbits,
426 DWORD srcwidth, DWORD dstwidth, int left,
427 int *colors, XImage *bmpImage )
429 DWORD x;
430 int h;
431 const BYTE *bits = srcbits + left;
433 /* align to 32 bit */
434 DWORD linebytes = (srcwidth + 3) & ~3;
436 dstwidth+=left;
438 if (lines > 0) {
439 for (h = lines - 1; h >= 0; h--) {
440 for (x = left; x < dstwidth; x++, bits++) {
441 XPutPixel( bmpImage, x, h, colors[*bits] );
443 bits = (srcbits += linebytes) + left;
445 } else {
446 lines = -lines;
447 for (h = 0; h < lines; h++) {
448 for (x = left; x < dstwidth; x++, bits++) {
449 XPutPixel( bmpImage, x, h, colors[*bits] );
451 bits = (srcbits += linebytes) + left;
456 /***********************************************************************
457 * DIB_SetImageBits_RLE8
459 * SetDIBits for an 8-bit deep compressed DIB.
461 * This function rewritten 941113 by James Youngman. WINE blew out when I
462 * first ran it because my desktop wallpaper is a (large) RLE8 bitmap.
464 * This was because the algorithm assumed that all RLE8 bitmaps end with the
465 * 'End of bitmap' escape code. This code is very much laxer in what it
466 * allows to end the expansion. Possibly too lax. See the note by
467 * case RleDelta. BTW, MS's documentation implies that a correct RLE8
468 * bitmap should end with RleEnd, but on the other hand, software exists
469 * that produces ones that don't and Windows 3.1 doesn't complain a bit
470 * about it.
472 * (No) apologies for my English spelling. [Emacs users: c-indent-level=4].
473 * James A. Youngman <mbcstjy@afs.man.ac.uk>
474 * [JAY]
477 enum Rle8_EscapeCodes
480 * Apologies for polluting your file's namespace...
482 RleEol = 0, /* End of line */
483 RleEnd = 1, /* End of bitmap */
484 RleDelta = 2 /* Delta */
487 static void DIB_SetImageBits_RLE8( int lines, const BYTE *bits, DWORD width,
488 DWORD dstwidth, int left, int *colors, XImage *bmpImage )
490 int x; /* X-positon on each line. Increases. */
491 int line; /* Line #. Starts at lines-1, decreases */
492 const BYTE *pIn = bits; /* Pointer to current position in bits */
493 BYTE length; /* The length pf a run */
494 BYTE color_index; /* index into colors[] as read from bits */
495 BYTE escape_code; /* See enum Rle8_EscapeCodes.*/
496 WORD color; /* value of colour[color_index] */
498 if (lines == 0) /* Let's hope this doesn't happen. */
499 return;
501 dstwidth += left; /* FIXME: avoid putting x<left pixels */
504 * Note that the bitmap data is stored by Windows starting at the
505 * bottom line of the bitmap and going upwards. Within each line,
506 * the data is stored left-to-right. That's the reason why line
507 * goes from lines-1 to 0. [JAY]
510 x = 0;
511 line = lines-1;
514 length = *pIn++;
517 * If the length byte is not zero (which is the escape value),
518 * We have a run of length pixels all the same colour. The colour
519 * index is stored next.
521 * If the length byte is zero, we need to read the next byte to
522 * know what to do. [JAY]
524 if (length != 0)
527 * [Run-Length] Encoded mode
529 color_index = (*pIn++); /* Get the colour index. */
530 color = colors[color_index];
532 while(length--)
533 XPutPixel(bmpImage, x++, line, color);
535 else
538 * Escape codes (may be an absolute sequence though)
540 escape_code = (*pIn++);
541 switch(escape_code)
543 case RleEol: /* =0, end of line */
545 x = 0;
546 line--;
547 break;
550 case RleEnd: /* =1, end of bitmap */
553 * Not all RLE8 bitmaps end with this
554 * code. For example, Paint Shop Pro
555 * produces some that don't. That's (I think)
556 * what caused the previous implementation to
557 * fail. [JAY]
559 line=-1; /* Cause exit from do loop. */
560 break;
563 case RleDelta: /* =2, a delta */
566 * Note that deltaing to line 0
567 * will cause an exit from the loop,
568 * which may not be what is intended.
569 * The fact that there is a delta in the bits
570 * almost certainly implies that there is data
571 * to follow. You may feel that we should
572 * jump to the top of the loop to avoid exiting
573 * in this case.
575 * TODO: Decide what to do here in that case. [JAY]
577 x += (*pIn++);
578 line -= (*pIn++);
579 if (line == 0)
581 dprintf_bitmap(stddeb,
582 "DIB_SetImageBits_RLE8(): "
583 "Delta to last line of bitmap "
584 "(wrongly?) causes loop exit\n");
586 break;
589 default: /* >2, switch to absolute mode */
592 * Absolute Mode
594 length = escape_code;
595 while(length--)
597 color_index = (*pIn++);
598 XPutPixel(bmpImage, x++, line,
599 colors[color_index]);
603 * If you think for a moment you'll realise that the
604 * only time we could ever possibly read an odd
605 * number of bytes is when there is a 0x00 (escape),
606 * a value >0x02 (absolute mode) and then an odd-
607 * length run. Therefore this is the only place we
608 * need to worry about it. Everywhere else the
609 * bytes are always read in pairs. [JAY]
611 if (escape_code & 1)
612 pIn++; /* Throw away the pad byte. */
613 break;
615 } /* switch (escape_code) : Escape sequence */
616 } /* process either an encoded sequence or an escape sequence */
618 /* We expect to come here more than once per line. */
619 } while (line >= 0); /* Do this until the bitmap is filled */
622 * Everybody comes here at the end.
623 * Check how we exited the loop and print a message if it's a bit odd.
624 * [JAY]
626 if ( (*(pIn-2) != 0/*escape*/) || (*(pIn-1)!= RleEnd) )
628 dprintf_bitmap(stddeb, "DIB_SetImageBits_RLE8(): End-of-bitmap "
629 "without (strictly) proper escape code. Last two "
630 "bytes were: %02X %02X.\n",
631 (int)*(pIn-2),
632 (int)*(pIn-1));
637 /***********************************************************************
638 * DIB_SetImageBits_16
640 * SetDIBits for a 16-bit deep DIB.
642 static void DIB_SetImageBits_16( int lines, const BYTE *srcbits,
643 DWORD srcwidth, DWORD dstwidth, int left,
644 DC *dc, XImage *bmpImage )
646 DWORD x;
647 LPWORD ptr;
648 WORD val;
649 int h;
650 BYTE r, g, b;
652 /* align to 32 bit */
653 DWORD linebytes = (srcwidth * 2 + 3) & ~3;
655 dstwidth += left;
657 ptr = (LPWORD) srcbits + left;
658 if (lines > 0) {
659 for (h = lines - 1; h >= 0; h--) {
660 for (x = left; x < dstwidth; x++, ptr++) {
661 val = *ptr;
662 r = (BYTE) ((val & 0x7c00) >> 7);
663 g = (BYTE) ((val & 0x03e0) >> 2);
664 b = (BYTE) ((val & 0x001f) << 3);
665 XPutPixel( bmpImage, x, h,
666 COLOR_ToPhysical(dc, RGB(r,g,b)) );
668 ptr = (LPWORD) (srcbits += linebytes) + left;
670 } else {
671 lines = -lines;
672 for (h = 0; h < lines; h++) {
673 for (x = left; x < dstwidth; x++, ptr++) {
674 val = *ptr;
675 r = (BYTE) ((val & 0x7c00) >> 7);
676 g = (BYTE) ((val & 0x03e0) >> 2);
677 b = (BYTE) ((val & 0x001f) << 3);
678 XPutPixel( bmpImage, x, h,
679 COLOR_ToPhysical(dc, RGB(r,g,b)) );
681 ptr = (LPWORD) (srcbits += linebytes) + left;
687 /***********************************************************************
688 * DIB_SetImageBits_24
690 * SetDIBits for a 24-bit deep DIB.
692 static void DIB_SetImageBits_24( int lines, const BYTE *srcbits,
693 DWORD srcwidth, DWORD dstwidth, int left,
694 DC *dc, XImage *bmpImage )
696 DWORD x;
697 const BYTE *bits = srcbits + left * 3;
698 int h;
700 /* align to 32 bit */
701 DWORD linebytes = (srcwidth * 3 + 3) & ~3;
703 dstwidth += left;
705 /* "bits" order is reversed for some reason */
707 if (lines > 0) {
708 for (h = lines - 1; h >= 0; h--) {
709 for (x = left; x < dstwidth; x++, bits += 3) {
710 XPutPixel( bmpImage, x, h,
711 COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
713 bits = (srcbits += linebytes) + left * 3;
715 } else {
716 lines = -lines;
717 for (h = 0; h < lines; h++) {
718 for (x = left; x < dstwidth; x++, bits += 3) {
719 XPutPixel( bmpImage, x, h,
720 COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
722 bits = (srcbits += linebytes) + left * 3;
728 /***********************************************************************
729 * DIB_SetImageBits_32
731 * SetDIBits for a 32-bit deep DIB.
733 static void DIB_SetImageBits_32( int lines, const BYTE *srcbits,
734 DWORD srcwidth, DWORD dstwidth, int left,
735 DC *dc, XImage *bmpImage )
737 DWORD x;
738 const BYTE *bits = srcbits + left * 4;
739 int h;
741 DWORD linebytes = (srcwidth * 4);
743 dstwidth += left;
745 if (lines > 0) {
746 for (h = lines - 1; h >= 0; h--) {
747 for (x = left; x < dstwidth; x++, bits += 4) {
748 XPutPixel( bmpImage, x, h,
749 COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
751 bits = (srcbits += linebytes) + left * 4;
753 } else {
754 lines = -lines;
755 for (h = 0; h < lines; h++) {
756 for (x = left; x < dstwidth; x++, bits += 4) {
757 XPutPixel( bmpImage, x, h,
758 COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
760 bits = (srcbits += linebytes) + left * 4;
766 /***********************************************************************
767 * DIB_SetImageBits
769 * Transfer the bits to an X image.
770 * Helper function for SetDIBits() and SetDIBitsToDevice().
771 * The Xlib critical section must be entered before calling this function.
773 static int DIB_SetImageBits( const DIB_SETIMAGEBITS_DESCR *descr )
775 int *colorMapping;
776 XImage *bmpImage;
777 DWORD compression = 0;
778 int lines;
780 if (descr->info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
781 compression = descr->info->bmiHeader.biCompression;
783 /* Build the color mapping table */
785 if (descr->infoBpp > 8) colorMapping = NULL;
786 else if (!(colorMapping = DIB_BuildColorMap( descr->dc, descr->coloruse,
787 descr->depth, descr->info )))
788 return 0;
790 if( descr->dc->w.flags & DC_DIRTY ) CLIPPING_UpdateGCRegion(descr->dc);
792 /* Transfer the pixels */
793 lines = descr->lines;
794 if (lines < 0) lines = -lines;
795 XCREATEIMAGE(bmpImage, descr->infoWidth, lines, descr->depth );
797 switch(descr->infoBpp)
799 case 1:
800 DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
801 descr->width, descr->xSrc, colorMapping, bmpImage );
802 break;
803 case 4:
804 if (compression) DIB_SetImageBits_RLE4( descr->lines, descr->bits,
805 descr->infoWidth, descr->width, descr->xSrc,
806 colorMapping, bmpImage );
807 else DIB_SetImageBits_4( descr->lines, descr->bits, descr->infoWidth,
808 descr->width, descr->xSrc, colorMapping, bmpImage );
809 break;
810 case 8:
811 if (compression) DIB_SetImageBits_RLE8( descr->lines, descr->bits,
812 descr->infoWidth, descr->width, descr->xSrc,
813 colorMapping, bmpImage );
814 else DIB_SetImageBits_8( descr->lines, descr->bits, descr->infoWidth,
815 descr->width, descr->xSrc, colorMapping, bmpImage );
816 break;
817 case 15:
818 case 16:
819 DIB_SetImageBits_16( descr->lines, descr->bits, descr->infoWidth,
820 descr->width, descr->xSrc, descr->dc, bmpImage);
821 break;
822 case 24:
823 DIB_SetImageBits_24( descr->lines, descr->bits, descr->infoWidth,
824 descr->width, descr->xSrc, descr->dc, bmpImage );
825 break;
826 case 32:
827 DIB_SetImageBits_32( descr->lines, descr->bits, descr->infoWidth,
828 descr->width, descr->xSrc, descr->dc, bmpImage);
829 break;
830 default:
831 fprintf( stderr, "Invalid depth %d for SetDIBits!\n", descr->infoBpp );
832 break;
834 if (colorMapping) HeapFree( GetProcessHeap(), 0, colorMapping );
835 XPutImage( display, descr->drawable, descr->gc, bmpImage,
836 descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
837 descr->width, descr->height );
838 XDestroyImage( bmpImage );
839 return lines;
843 /***********************************************************************
844 * StretchDIBits16 (GDI.439)
846 INT16 WINAPI StretchDIBits16(HDC16 hdc, INT16 xDst, INT16 yDst, INT16 widthDst,
847 INT16 heightDst, INT16 xSrc, INT16 ySrc, INT16 widthSrc,
848 INT16 heightSrc, const VOID *bits,
849 const BITMAPINFO *info, UINT16 wUsage, DWORD dwRop )
851 return (INT16)StretchDIBits32( hdc, xDst, yDst, widthDst, heightDst,
852 xSrc, ySrc, widthSrc, heightSrc, bits,
853 info, wUsage, dwRop );
857 /***********************************************************************
858 * StretchDIBits32 (GDI32.351)
860 INT32 WINAPI StretchDIBits32(HDC32 hdc, INT32 xDst, INT32 yDst, INT32 widthDst,
861 INT32 heightDst, INT32 xSrc, INT32 ySrc, INT32 widthSrc,
862 INT32 heightSrc, const void *bits,
863 const BITMAPINFO *info, UINT32 wUsage, DWORD dwRop )
865 HBITMAP32 hBitmap, hOldBitmap;
866 HDC32 hdcMem;
868 hBitmap = CreateDIBitmap32( hdc, &info->bmiHeader, CBM_INIT,
869 bits, info, wUsage );
870 hdcMem = CreateCompatibleDC32( hdc );
871 hOldBitmap = SelectObject32( hdcMem, hBitmap );
872 StretchBlt32( hdc, xDst, yDst, widthDst, heightDst,
873 hdcMem, xSrc, ySrc, widthSrc, heightSrc, dwRop );
874 SelectObject32( hdcMem, hOldBitmap );
875 DeleteDC32( hdcMem );
876 DeleteObject32( hBitmap );
877 return heightSrc;
881 /***********************************************************************
882 * SetDIBits16 (GDI.440)
884 INT16 WINAPI SetDIBits16( HDC16 hdc, HBITMAP16 hbitmap, UINT16 startscan,
885 UINT16 lines, LPCVOID bits, const BITMAPINFO *info,
886 UINT16 coloruse )
888 return SetDIBits32( hdc, hbitmap, startscan, lines, bits, info, coloruse );
892 /***********************************************************************
893 * SetDIBits32 (GDI32.312)
895 INT32 WINAPI SetDIBits32( HDC32 hdc, HBITMAP32 hbitmap, UINT32 startscan,
896 UINT32 lines, LPCVOID bits, const BITMAPINFO *info,
897 UINT32 coloruse )
899 DIB_SETIMAGEBITS_DESCR descr;
900 BITMAPOBJ * bmp;
901 int height, tmpheight;
902 INT32 result;
904 /* Check parameters */
906 descr.dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
907 if (!descr.dc)
909 descr.dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
910 if (!descr.dc) return 0;
912 if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
914 GDI_HEAP_UNLOCK( hdc );
915 return 0;
917 if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &height,
918 &descr.infoBpp ) == -1)
920 GDI_HEAP_UNLOCK( hbitmap );
921 GDI_HEAP_UNLOCK( hdc );
922 return 0;
924 tmpheight = height;
925 if (height < 0) height = -height;
926 if (!lines || (startscan >= height))
928 GDI_HEAP_UNLOCK( hbitmap );
929 GDI_HEAP_UNLOCK( hdc );
930 return 0;
932 if (startscan + lines > height) lines = height - startscan;
934 descr.bits = bits;
935 descr.lines = tmpheight >= 0 ? lines : -lines;
936 descr.depth = bmp->bitmap.bmBitsPixel;
937 descr.info = info;
938 descr.coloruse = coloruse;
939 descr.drawable = bmp->pixmap;
940 descr.gc = BITMAP_GC(bmp);
941 descr.xSrc = 0;
942 descr.ySrc = 0;
943 descr.xDest = 0;
944 descr.yDest = height - startscan - lines;
945 descr.width = bmp->bitmap.bmWidth;
946 descr.height = lines;
948 EnterCriticalSection( &X11DRV_CritSection );
949 result = CALL_LARGE_STACK( DIB_SetImageBits, &descr );
950 LeaveCriticalSection( &X11DRV_CritSection );
952 GDI_HEAP_UNLOCK( hdc );
953 GDI_HEAP_UNLOCK( hbitmap );
954 return result;
958 /***********************************************************************
959 * SetDIBitsToDevice16 (GDI.443)
961 INT16 WINAPI SetDIBitsToDevice16(HDC16 hdc, INT16 xDest, INT16 yDest, INT16 cx,
962 INT16 cy, INT16 xSrc, INT16 ySrc, UINT16 startscan,
963 UINT16 lines, LPCVOID bits, const BITMAPINFO *info,
964 UINT16 coloruse )
966 return SetDIBitsToDevice32( hdc, xDest, yDest, cx, cy, xSrc, ySrc,
967 startscan, lines, bits, info, coloruse );
971 /***********************************************************************
972 * SetDIBitsToDevice32 (GDI32.313)
974 INT32 WINAPI SetDIBitsToDevice32(HDC32 hdc, INT32 xDest, INT32 yDest, DWORD cx,
975 DWORD cy, INT32 xSrc, INT32 ySrc, UINT32 startscan,
976 UINT32 lines, LPCVOID bits, const BITMAPINFO *info,
977 UINT32 coloruse )
979 DIB_SETIMAGEBITS_DESCR descr;
980 DC * dc;
981 DWORD width, oldcy = cy;
982 INT32 result;
983 int height, tmpheight;
985 /* Check parameters */
987 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
988 if (!dc)
990 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
991 if (!dc) return 0;
993 if (DIB_GetBitmapInfo( &info->bmiHeader, &width,
994 &height, &descr.infoBpp ) == -1)
995 return 0;
996 tmpheight = height;
997 if (height < 0) height = -height;
998 if (!lines || (startscan >= height)) return 0;
999 if (startscan + lines > height) lines = height - startscan;
1000 if (ySrc < startscan) ySrc = startscan;
1001 else if (ySrc >= startscan + lines) return 0;
1002 if (xSrc >= width) return 0;
1003 if (ySrc + cy >= startscan + lines) cy = startscan + lines - ySrc;
1004 if (xSrc + cx >= width) cx = width - xSrc;
1005 if (!cx || !cy) return 0;
1007 DC_SetupGCForText( dc ); /* To have the correct colors */
1008 TSXSetFunction( display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] );
1010 descr.dc = dc;
1011 descr.bits = bits;
1012 descr.lines = tmpheight >= 0 ? lines : -lines;
1013 descr.infoWidth = width;
1014 descr.depth = dc->w.bitsPerPixel;
1015 descr.info = info;
1016 descr.coloruse = coloruse;
1017 descr.drawable = dc->u.x.drawable;
1018 descr.gc = dc->u.x.gc;
1019 descr.xSrc = xSrc;
1020 descr.ySrc = tmpheight >= 0 ? lines-(ySrc-startscan)-cy+(oldcy-cy) : ySrc - startscan;
1021 descr.xDest = dc->w.DCOrgX + XLPTODP( dc, xDest );
1022 descr.yDest = dc->w.DCOrgY + YLPTODP( dc, yDest ) + (tmpheight >= 0 ? oldcy-cy : 0);
1023 descr.width = cx;
1024 descr.height = cy;
1026 EnterCriticalSection( &X11DRV_CritSection );
1027 result = CALL_LARGE_STACK( DIB_SetImageBits, &descr );
1028 LeaveCriticalSection( &X11DRV_CritSection );
1029 return result;
1032 /***********************************************************************
1033 * SetDIBColorTable32 (GDI32.311)
1035 UINT32 WINAPI SetDIBColorTable32( HDC32 hdc, UINT32 startpos, UINT32 entries,
1036 RGBQUAD *colors )
1038 DC * dc;
1039 PALETTEENTRY * palEntry;
1040 PALETTEOBJ * palette;
1041 RGBQUAD *end;
1043 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1044 if (!dc)
1046 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
1047 if (!dc) return 0;
1050 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
1052 return 0;
1055 /* Transfer color info */
1057 if (dc->w.bitsPerPixel <= 8) {
1058 palEntry = palette->logpalette.palPalEntry + startpos;
1059 if (startpos + entries > (1 << dc->w.bitsPerPixel)) {
1060 entries = (1 << dc->w.bitsPerPixel) - startpos;
1062 for (end = colors + entries; colors < end; palEntry++, colors++)
1064 palEntry->peRed = colors->rgbRed;
1065 palEntry->peGreen = colors->rgbGreen;
1066 palEntry->peBlue = colors->rgbBlue;
1068 } else {
1069 entries = 0;
1071 GDI_HEAP_UNLOCK( dc->w.hPalette );
1072 return entries;
1075 /***********************************************************************
1076 * GetDIBColorTable32 (GDI32.169)
1078 UINT32 WINAPI GetDIBColorTable32( HDC32 hdc, UINT32 startpos, UINT32 entries,
1079 RGBQUAD *colors )
1081 DC * dc;
1082 PALETTEENTRY * palEntry;
1083 PALETTEOBJ * palette;
1084 RGBQUAD *end;
1086 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1087 if (!dc)
1089 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
1090 if (!dc) return 0;
1093 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
1095 return 0;
1098 /* Transfer color info */
1100 if (dc->w.bitsPerPixel <= 8) {
1101 palEntry = palette->logpalette.palPalEntry + startpos;
1102 if (startpos + entries > (1 << dc->w.bitsPerPixel)) {
1103 entries = (1 << dc->w.bitsPerPixel) - startpos;
1105 for (end = colors + entries; colors < end; palEntry++, colors++)
1107 colors->rgbRed = palEntry->peRed;
1108 colors->rgbGreen = palEntry->peGreen;
1109 colors->rgbBlue = palEntry->peBlue;
1110 colors->rgbReserved = 0;
1112 } else {
1113 entries = 0;
1115 GDI_HEAP_UNLOCK( dc->w.hPalette );
1116 return entries;
1119 /***********************************************************************
1120 * GetDIBits16 (GDI.441)
1122 INT16 WINAPI GetDIBits16( HDC16 hdc, HBITMAP16 hbitmap, UINT16 startscan,
1123 UINT16 lines, LPSTR bits, BITMAPINFO * info,
1124 UINT16 coloruse )
1126 return GetDIBits32( hdc, hbitmap, startscan, lines, bits, info, coloruse );
1130 /***********************************************************************
1131 * GetDIBits32 (GDI32.170)
1133 * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/func/src/f30_14.htm
1135 INT32 WINAPI GetDIBits32( HDC32 hdc, HBITMAP32 hbitmap, UINT32 startscan,
1136 UINT32 lines, LPSTR bits, BITMAPINFO * info,
1137 UINT32 coloruse )
1139 DC * dc;
1140 BITMAPOBJ * bmp;
1141 PALETTEENTRY * palEntry;
1142 PALETTEOBJ * palette;
1143 XImage * bmpImage;
1144 int i, x, y;
1146 if (!lines) return 0;
1147 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1148 if (!dc)
1150 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
1151 if (!dc) return 0;
1153 if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
1154 return 0;
1155 if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
1157 GDI_HEAP_UNLOCK( hbitmap );
1158 return 0;
1161 /* Transfer color info */
1163 if (info->bmiHeader.biBitCount<=8) {
1164 palEntry = palette->logpalette.palPalEntry;
1165 for (i = 0; i < info->bmiHeader.biClrUsed; i++, palEntry++)
1167 if (coloruse == DIB_RGB_COLORS)
1169 info->bmiColors[i].rgbRed = palEntry->peRed;
1170 info->bmiColors[i].rgbGreen = palEntry->peGreen;
1171 info->bmiColors[i].rgbBlue = palEntry->peBlue;
1172 info->bmiColors[i].rgbReserved = 0;
1174 else ((WORD *)info->bmiColors)[i] = (WORD)i;
1178 if (bits)
1180 BYTE* bbits = bits;
1181 int pad, yend, xend = bmp->bitmap.bmWidth;
1183 dprintf_bitmap(stddeb, "GetDIBits: %u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
1184 lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
1185 (int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight, startscan );
1187 /* adjust number of scanlines to copy */
1189 if( lines > info->bmiHeader.biHeight ) lines = info->bmiHeader.biHeight;
1190 yend = startscan + lines;
1191 if( startscan >= bmp->bitmap.bmHeight )
1193 GDI_HEAP_UNLOCK( hbitmap );
1194 GDI_HEAP_UNLOCK( dc->w.hPalette );
1195 return FALSE;
1197 if( yend > bmp->bitmap.bmHeight ) yend = bmp->bitmap.bmHeight;
1199 /* adjust scanline width */
1201 pad = info->bmiHeader.biWidth - bmp->bitmap.bmWidth;
1202 if( pad < 0 )
1204 /* bitmap is wider than DIB, copy only a part */
1206 pad = 0;
1207 xend = info->bmiHeader.biWidth;
1210 EnterCriticalSection( &X11DRV_CritSection );
1211 bmpImage = (XImage *)CALL_LARGE_STACK( BITMAP_GetXImage, bmp );
1213 switch( info->bmiHeader.biBitCount )
1215 case 8:
1216 /* pad up to 32 bit */
1217 pad += (4 - (info->bmiHeader.biWidth & 3)) & 3;
1218 for( y = yend - 1; (int)y >= (int)startscan; y-- )
1220 for( x = 0; x < xend; x++ )
1221 *bbits++ = XGetPixel( bmpImage, x, y );
1222 bbits += pad;
1224 break;
1225 case 1:
1226 pad += ((32 - (info->bmiHeader.biWidth & 31)) / 8) & 3;
1227 for( y = yend - 1; (int)y >= (int)startscan; y-- )
1229 *bbits = 0;
1230 for( x = 0; x < xend; x++ ) {
1232 *bbits |= XGetPixel( bmpImage, x, y)<<(7-(x&7));
1233 if ((x&7)==7) {
1234 bbits++;
1235 *bbits=0;
1238 bbits += pad;
1240 break;
1241 case 4:
1242 pad += ((8 - (info->bmiHeader.biWidth & 7)) / 2) & 3;
1243 for( y = yend - 1; (int)y >= (int)startscan; y-- )
1245 *bbits = 0;
1246 for( x = 0; x < xend; x++ ) {
1248 *bbits |= XGetPixel( bmpImage, x, y)<<(4*(1-(x&1)));
1249 if ((x&1)==1) {
1250 bbits++;
1251 *bbits=0;
1254 bbits += pad;
1256 break;
1257 case 15:
1258 case 16:
1259 pad += (4 - ((info->bmiHeader.biWidth*2) & 3)) & 3;
1260 for( y = yend - 1; (int)y >= (int)startscan; y-- )
1262 *bbits = 0;
1263 for( x = 0; x < xend; x++ ) {
1264 unsigned long pixel=XGetPixel( bmpImage, x, y);
1265 *bbits++ = pixel & 0xff;
1266 *bbits++ = (pixel >> 8) & 0xff;
1268 bbits += pad;
1270 break;
1271 case 24:
1272 pad += (4 - ((info->bmiHeader.biWidth*3) & 3)) & 3;
1273 for( y = yend - 1; (int)y >= (int)startscan; y-- )
1275 *bbits = 0;
1276 for( x = 0; x < xend; x++ ) {
1277 unsigned long pixel=XGetPixel( bmpImage, x, y);
1278 *bbits++ = (pixel >>16) & 0xff;
1279 *bbits++ = (pixel >> 8) & 0xff;
1280 *bbits++ = pixel & 0xff;
1282 bbits += pad;
1284 break;
1285 case 32:
1286 for( y = yend - 1; (int)y >= (int)startscan; y-- )
1288 *bbits = 0;
1289 for( x = 0; x < xend; x++ ) {
1290 unsigned long pixel=XGetPixel( bmpImage, x, y);
1291 *bbits++ = (pixel >>16) & 0xff;
1292 *bbits++ = (pixel >> 8) & 0xff;
1293 *bbits++ = pixel & 0xff;
1296 break;
1297 default:
1298 fprintf(stderr,"GetDIBits*: unsupported depth %d\n",
1299 info->bmiHeader.biBitCount
1301 break;
1304 XDestroyImage( bmpImage );
1305 LeaveCriticalSection( &X11DRV_CritSection );
1307 info->bmiHeader.biCompression = 0;
1309 else if( info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
1311 /* fill in struct members */
1313 info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
1314 info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
1315 info->bmiHeader.biPlanes = 1;
1316 info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
1317 info->bmiHeader.biSizeImage = bmp->bitmap.bmHeight *
1318 DIB_GetDIBWidthBytes( bmp->bitmap.bmWidth,
1319 bmp->bitmap.bmBitsPixel );
1320 info->bmiHeader.biCompression = 0;
1323 GDI_HEAP_UNLOCK( hbitmap );
1324 GDI_HEAP_UNLOCK( dc->w.hPalette );
1325 return lines;
1329 /***********************************************************************
1330 * CreateDIBitmap16 (GDI.442)
1332 HBITMAP16 WINAPI CreateDIBitmap16( HDC16 hdc, const BITMAPINFOHEADER * header,
1333 DWORD init, LPCVOID bits, const BITMAPINFO * data,
1334 UINT16 coloruse )
1336 return CreateDIBitmap32( hdc, header, init, bits, data, coloruse );
1340 /***********************************************************************
1341 * CreateDIBitmap32 (GDI32.37)
1343 HBITMAP32 WINAPI CreateDIBitmap32( HDC32 hdc, const BITMAPINFOHEADER *header,
1344 DWORD init, LPCVOID bits, const BITMAPINFO *data,
1345 UINT32 coloruse )
1347 HBITMAP32 handle;
1348 BOOL32 fColor;
1349 DWORD width;
1350 int height;
1351 WORD bpp;
1353 if (DIB_GetBitmapInfo( header, &width, &height, &bpp ) == -1) return 0;
1354 if (height < 0) height = -height;
1356 /* Check if we should create a monochrome or color bitmap. */
1357 /* We create a monochrome bitmap only if it has exactly 2 */
1358 /* colors, which are either black or white, nothing else. */
1359 /* In all other cases, we create a color bitmap. */
1361 if (bpp != 1) fColor = TRUE;
1362 else if ((coloruse != DIB_RGB_COLORS) ||
1363 (init != CBM_INIT) || !data) fColor = FALSE;
1364 else
1366 if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
1368 RGBQUAD *rgb = data->bmiColors;
1369 DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
1370 if ((col == RGB(0,0,0)) || (col == RGB(0xff,0xff,0xff)))
1372 rgb++;
1373 col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
1374 fColor = ((col != RGB(0,0,0)) && (col != RGB(0xff,0xff,0xff)));
1376 else fColor = TRUE;
1378 else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
1380 RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
1381 DWORD col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
1382 if ((col == RGB(0,0,0)) || (col == RGB(0xff,0xff,0xff)))
1384 rgb++;
1385 col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
1386 fColor = ((col != RGB(0,0,0)) && (col != RGB(0xff,0xff,0xff)));
1388 else fColor = TRUE;
1390 else
1392 fprintf( stderr, "CreateDIBitmap: wrong size (%ld) for data\n",
1393 data->bmiHeader.biSize );
1394 return 0;
1398 /* Now create the bitmap */
1400 handle = fColor ? CreateCompatibleBitmap32( hdc, width, height ) :
1401 CreateBitmap32( width, height, 1, 1, NULL );
1402 if (!handle) return 0;
1404 if (init == CBM_INIT)
1405 SetDIBits32( hdc, handle, 0, height, bits, data, coloruse );
1406 return handle;
1409 /***********************************************************************
1410 * CreateDIBSection16 (GDI.489)
1412 HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, BITMAPINFO *bmi, UINT16 usage,
1413 LPVOID **bits, HANDLE16 section,
1414 DWORD offset)
1416 return CreateDIBSection32 (hdc, bmi, usage, bits, section, offset);
1419 /***********************************************************************
1420 * CreateDIBSection32 (GDI32.36)
1422 HBITMAP32 WINAPI CreateDIBSection32 (HDC32 hdc, BITMAPINFO *bmi, UINT32 usage,
1423 LPVOID **bits,HANDLE32 section,
1424 DWORD offset)
1426 HBITMAP32 res = 0;
1428 fprintf(stderr,
1429 "CreateDIBSection(%d,[w=%ld,h=%ld],%d,%p,0x%08x,%ld),semistub\n",
1430 hdc,bmi->bmiHeader.biWidth,bmi->bmiHeader.biHeight,
1431 usage,bits,section,offset
1433 if (bmi->bmiHeader.biHeight < 0 ) bmi->bmiHeader.biHeight = -bmi->bmiHeader.biHeight;
1434 if (bmi->bmiHeader.biWidth < 0 ) bmi->bmiHeader.biWidth = -bmi->bmiHeader.biWidth;
1435 /* FIXME. The following line isn't quite right. */
1436 res = CreateDIBitmap32 (hdc, &bmi->bmiHeader, 0, NULL, bmi, 0);
1437 if (res)
1439 BITMAP32 bmp;
1440 if (GetObject32A (res, sizeof (bmp), &bmp))
1442 /* FIXME: this is wrong! (bmBits is always NULL) */
1443 if (bits) *bits = bmp.bmBits;
1444 /* hmpf */
1445 fprintf(stderr,"allocating %ld bytes of memory\n",bmi->bmiHeader.biWidth*bmi->bmiHeader.biHeight*4);
1446 if (bits) *bits = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,bmi->bmiHeader.biWidth*bmi->bmiHeader.biHeight*4);
1447 return res;
1451 /* Error. */
1452 if (res) DeleteObject32 (res);
1453 if (bits) *bits = NULL;
1454 return 0;