Release 970509
[wine] / objects / bitmap.c
1 /*
2  * GDI bitmap objects
3  *
4  * Copyright 1993 Alexandre Julliard
5  */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <X11/Xlib.h>
11 #include <X11/Xutil.h>
12 #include "gdi.h"
13 #include "callback.h"
14 #include "dc.h"
15 #include "bitmap.h"
16 #include "heap.h"
17 #include "stddebug.h"
18 #include "debug.h"
19
20 #ifdef PRELIMINARY_WING16_SUPPORT
21 #include <sys/types.h>
22 #include <sys/ipc.h>
23 #include <sys/shm.h>
24 #endif
25
26   /* GCs used for B&W and color bitmap operations */
27 GC BITMAP_monoGC = 0, BITMAP_colorGC = 0;
28
29 extern void CLIPPING_UpdateGCRegion( DC * dc );  /* objects/clipping.c */
30
31
32 /***********************************************************************
33  *           CreateBitmap16    (GDI.48)
34  */
35 HBITMAP16 CreateBitmap16( INT16 width, INT16 height, UINT16 planes,
36                           UINT16 bpp, LPCVOID bits )
37 {
38     return CreateBitmap32( width, height, planes, bpp, bits );
39 }
40
41
42 /***********************************************************************
43  *           CreateBitmap32    (GDI32.25)
44  */
45 HBITMAP32 CreateBitmap32( INT32 width, INT32 height, UINT32 planes,
46                           UINT32 bpp, LPCVOID bits )
47 {
48     BITMAPOBJ * bmpObjPtr;
49     HBITMAP32 hbitmap;
50
51     planes = (BYTE)planes;
52     bpp    = (BYTE)bpp;
53
54     dprintf_gdi( stddeb, "CreateBitmap: %dx%d, %d colors\n", 
55                  width, height, 1 << (planes*bpp) );
56
57       /* Check parameters */
58     if (!height || !width || planes != 1) return 0;
59     if ((bpp != 1) && (bpp != screenDepth)) return 0;
60     if (height < 0) height = -height;
61     if (width < 0) width = -width;
62
63       /* Create the BITMAPOBJ */
64     hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
65     if (!hbitmap) return 0;
66     bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LIN_ADDR( hbitmap );
67
68     bmpObjPtr->size.cx = 0;
69     bmpObjPtr->size.cy = 0;
70     bmpObjPtr->bitmap.bmType = 0;
71     bmpObjPtr->bitmap.bmWidth = (INT16)width;
72     bmpObjPtr->bitmap.bmHeight = (INT16)height;
73     bmpObjPtr->bitmap.bmPlanes = (BYTE)planes;
74     bmpObjPtr->bitmap.bmBitsPixel = (BYTE)bpp;
75     bmpObjPtr->bitmap.bmWidthBytes = (INT16)BITMAP_WIDTH_BYTES( width, bpp );
76     bmpObjPtr->bitmap.bmBits = NULL;
77
78       /* Create the pixmap */
79     bmpObjPtr->pixmap = XCreatePixmap(display, rootWindow, width, height, bpp);
80     if (!bmpObjPtr->pixmap)
81     {
82         GDI_HEAP_FREE( hbitmap );
83         hbitmap = 0;
84     }
85     else if (bits)  /* Set bitmap bits */
86         SetBitmapBits32( hbitmap, height * bmpObjPtr->bitmap.bmWidthBytes,
87                          bits );
88     return hbitmap;
89 }
90
91
92 /***********************************************************************
93  *           CreateCompatibleBitmap16    (GDI.51)
94  */
95 HBITMAP16 CreateCompatibleBitmap16( HDC16 hdc, INT16 width, INT16 height )
96 {
97     return CreateCompatibleBitmap32( hdc, width, height );
98 }
99
100
101 /***********************************************************************
102  *           CreateCompatibleBitmap32    (GDI32.30)
103  */
104 HBITMAP32 CreateCompatibleBitmap32( HDC32 hdc, INT32 width, INT32 height )
105 {
106     HBITMAP32 hbmpRet = 0;
107     DC *dc;
108
109     dprintf_gdi( stddeb, "CreateCompatibleBitmap(%04x,%d,%d) = \n", 
110                  hdc, width, height );
111     if (!(dc = DC_GetDCPtr( hdc ))) return 0;
112     hbmpRet = CreateBitmap32( width, height, 1, dc->w.bitsPerPixel, NULL );
113     dprintf_gdi(stddeb,"\t\t%04x\n", hbmpRet);
114     return hbmpRet;
115 }
116
117
118 /***********************************************************************
119  *           CreateBitmapIndirect16    (GDI.49)
120  */
121 HBITMAP16 CreateBitmapIndirect16( const BITMAP16 * bmp )
122 {
123     return CreateBitmap16( bmp->bmWidth, bmp->bmHeight, bmp->bmPlanes,
124                            bmp->bmBitsPixel, PTR_SEG_TO_LIN( bmp->bmBits ) );
125 }
126
127
128 /***********************************************************************
129  *           CreateBitmapIndirect32    (GDI32.26)
130  */
131 HBITMAP32 CreateBitmapIndirect32( const BITMAP32 * bmp )
132 {
133     return CreateBitmap32( bmp->bmWidth, bmp->bmHeight, bmp->bmPlanes,
134                            bmp->bmBitsPixel, bmp->bmBits );
135 }
136
137
138 /***********************************************************************
139  *           GetBitmapBits16    (GDI.74)
140  */
141 LONG GetBitmapBits16( HBITMAP16 hbitmap, LONG count, LPVOID buffer )
142 {
143     return GetBitmapBits32( hbitmap, count, buffer );
144 }
145
146
147 /***********************************************************************
148  *           GetBitmapBits32    (GDI32.143)
149  */
150 LONG GetBitmapBits32( HBITMAP32 hbitmap, LONG count, LPVOID buffer )
151 {
152     BITMAPOBJ * bmp;
153     LONG height,widthbytes;
154     XImage * image;
155     LPBYTE tmpbuffer,tbuf;
156     int h,w,pad;
157     
158     /* KLUDGE! */
159     if (count < 0) {
160         fprintf(stderr, "Negative number of bytes (%ld) passed to GetBitmapBits???\n", count );
161         count = -count;
162     }
163     bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
164     if (!bmp) return 0;
165
166       /* Only get entire lines */
167     height = count / bmp->bitmap.bmWidthBytes;
168     if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight;
169     dprintf_bitmap(stddeb, "GetBitmapBits: %dx%d %d colors %p fetched height: %ld\n",
170             bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
171             1 << bmp->bitmap.bmBitsPixel, buffer, height );
172     if (!height) return 0;
173
174     switch (bmp->bitmap.bmBitsPixel) {
175     case 1:
176         if (!(bmp->bitmap.bmWidth & 15))
177                 pad = 0;
178         else
179                 pad = ((16 - (bmp->bitmap.bmWidth & 15)) + 7) / 8;
180         break;
181     case 4:
182         if (!(bmp->bitmap.bmWidth & 3))
183             pad = 0;
184         else
185             pad = ((4 - (bmp->bitmap.bmWidth & 3)) + 1) / 2;
186         break;
187     case 8:
188         pad = (2 - (bmp->bitmap.bmWidth & 1)) & 1;
189         break;
190     case 15:
191     case 16:
192         pad = 0; /* we have 16bit alignment already */
193         break;
194     case 24:
195         pad = (bmp->bitmap.bmWidth*3) & 1;
196         break;
197     default:
198         fprintf(stderr,"GetBitMapBits32: unknown depth %d, please report.\n",
199                 bmp->bitmap.bmBitsPixel
200         );
201         return 0;
202     }
203
204     widthbytes  = DIB_GetImageWidthBytesX11(bmp->bitmap.bmWidth,bmp->bitmap.bmBitsPixel);
205     tmpbuffer   = (LPBYTE)xmalloc(widthbytes*height);
206     image = XCreateImage( display, DefaultVisualOfScreen(screen),
207                   bmp->bitmap.bmBitsPixel, ZPixmap, 0, tmpbuffer,
208                   bmp->bitmap.bmWidth,height,32,widthbytes
209     );
210     
211     CallTo32_LargeStack( (int(*)())XGetSubImage, 11,
212                          display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth,
213                          height, AllPlanes, ZPixmap, image, 0, 0 );
214
215     /* copy XImage to 16 bit padded image buffer with real bitsperpixel */
216
217     tbuf = buffer;
218     switch (bmp->bitmap.bmBitsPixel)
219     {
220     case 1:
221         for (h=0;h<height;h++)
222         {
223             *tbuf = 0;
224             for (w=0;w<bmp->bitmap.bmWidth;w++)
225             {
226                 *tbuf |= XGetPixel(image,w,h)<<(7-(w&7));
227                 if ((w&7) == 7) *(++tbuf) = 0;
228             }
229             tbuf += pad;
230         }
231         break;
232     case 4:
233         for (h=0;h<height;h++)
234         {
235             for (w=0;w<bmp->bitmap.bmWidth;w++)
236             {
237                 if (!(w & 1)) *tbuf = XGetPixel( image, w, h) << 4;
238                 else *tbuf++ |= XGetPixel( image, w, h) & 0x0f;
239             }
240             tbuf += pad;
241         }
242         break;
243     case 8:
244         for (h=0;h<height;h++)
245         {
246             for (w=0;w<bmp->bitmap.bmWidth;w++)
247                 *tbuf++ = XGetPixel(image,w,h);
248             tbuf += pad;
249         }
250         break;
251     case 15:
252     case 16:
253         for (h=0;h<height;h++)
254         {
255             for (w=0;w<bmp->bitmap.bmWidth;w++)
256             {
257                 long pixel = XGetPixel(image,w,h);
258
259                 *tbuf++ = pixel & 0xff;
260                 *tbuf++ = (pixel>>8) & 0xff;
261             }
262         }
263         break;
264     case 24:
265         for (h=0;h<height;h++)
266         {
267             for (w=0;w<bmp->bitmap.bmWidth;w++)
268             {
269                 long pixel = XGetPixel(image,w,h);
270
271                 *tbuf++ = pixel & 0xff;
272                 *tbuf++ = (pixel>> 8) & 0xff;
273                 *tbuf++ = (pixel>>16) & 0xff;
274             }
275             tbuf += pad;
276         }
277     }
278     XDestroyImage( image ); /* frees tbuffer too */
279     return height * bmp->bitmap.bmWidthBytes;
280 }
281
282
283 /***********************************************************************
284  *           SetBitmapBits16    (GDI.106)
285  */
286 LONG SetBitmapBits16( HBITMAP16 hbitmap, LONG count, LPCVOID buffer )
287 {
288     return SetBitmapBits32( hbitmap, count, buffer );
289 }
290
291
292 /***********************************************************************
293  *           SetBitmapBits32    (GDI32.303)
294  */
295 LONG SetBitmapBits32( HBITMAP32 hbitmap, LONG count, LPCVOID buffer )
296 {
297     BITMAPOBJ * bmp;
298     LONG height;
299     XImage * image;
300     LPBYTE sbuf,tmpbuffer;
301     int w,h,pad,widthbytes;
302     
303     /* KLUDGE! */
304     if (count < 0) {
305         fprintf(stderr, "Negative number of bytes (%ld) passed to SetBitmapBits???\n", count );
306         count = -count;
307     }
308     bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
309     if (!bmp) return 0;
310
311     dprintf_bitmap(stddeb, "SetBitmapBits: %dx%d %d colors %p\n",
312             bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
313             1 << bmp->bitmap.bmBitsPixel, buffer );
314
315       /* Only set entire lines */
316     height = count / bmp->bitmap.bmWidthBytes;
317     if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight;
318     if (!height) return 0;
319         
320     switch (bmp->bitmap.bmBitsPixel) {
321     case 1:
322         if (!(bmp->bitmap.bmWidth & 15))
323                 pad = 0;
324         else
325                 pad = ((16 - (bmp->bitmap.bmWidth & 15)) + 7) / 8;
326         break;
327     case 4:
328         if (!(bmp->bitmap.bmWidth & 3))
329             pad = 0;
330         else
331             pad = ((4 - (bmp->bitmap.bmWidth & 3)) + 1) / 2;
332         break;
333     case 8:
334         pad = (2 - (bmp->bitmap.bmWidth & 1)) & 1;
335         break;
336     case 15:
337     case 16:
338         pad = 0; /* we have 16bit alignment already */
339         break;
340     case 24:
341         pad = (bmp->bitmap.bmWidth*3) & 1;
342         break;
343     default:
344         fprintf(stderr,"SetBitMapBits32: unknown depth %d, please report.\n",
345                 bmp->bitmap.bmBitsPixel
346         );
347         return 0;
348     }
349     sbuf = (LPBYTE)buffer;
350
351     widthbytes  = DIB_GetImageWidthBytesX11(bmp->bitmap.bmWidth,bmp->bitmap.bmBitsPixel);
352     tmpbuffer   = (LPBYTE)xmalloc(widthbytes*height);
353     image = XCreateImage( display, DefaultVisualOfScreen(screen),
354                   bmp->bitmap.bmBitsPixel, ZPixmap, 0, tmpbuffer,
355                   bmp->bitmap.bmWidth,height,32,widthbytes
356     );
357     
358     /* copy 16 bit padded image buffer with real bitsperpixel to XImage */
359     sbuf = (LPBYTE)buffer;
360     switch (bmp->bitmap.bmBitsPixel)
361     {
362     case 1:
363         for (h=0;h<height;h++)
364         {
365             for (w=0;w<bmp->bitmap.bmWidth;w++)
366             {
367                 XPutPixel(image,w,h,(sbuf[0]>>(7-(w&7))) & 1);
368                 if ((w&7) == 7)
369                     sbuf++;
370             }
371             sbuf += pad;
372         }
373         break;
374     case 4:
375         for (h=0;h<height;h++)
376         {
377             for (w=0;w<bmp->bitmap.bmWidth;w++)
378             {
379                 if (!(w & 1)) XPutPixel( image, w, h, *sbuf >> 4 );
380                 else XPutPixel( image, w, h, *sbuf++ & 0xf );
381             }
382             sbuf += pad;
383         }
384         break;
385     case 8:
386         for (h=0;h<height;h++)
387         {
388             for (w=0;w<bmp->bitmap.bmWidth;w++)
389                 XPutPixel(image,w,h,*sbuf++);
390             sbuf += pad;
391         }
392         break;
393     case 15:
394     case 16:
395         for (h=0;h<height;h++)
396         {
397             for (w=0;w<bmp->bitmap.bmWidth;w++)
398             {
399                 XPutPixel(image,w,h,sbuf[1]*256+sbuf[0]);
400                 sbuf+=2;
401             }
402         }
403         break;
404     case 24: 
405         for (h=0;h<height;h++)
406         {
407             for (w=0;w<bmp->bitmap.bmWidth;w++)
408             {
409                 XPutPixel(image,w,h,(sbuf[2]<<16)+(sbuf[1]<<8)+sbuf[0]);
410                 sbuf += 3;
411             }
412             sbuf += pad;
413         }
414         break;
415     }
416
417     CallTo32_LargeStack( XPutImage, 10,
418                          display, bmp->pixmap, BITMAP_GC(bmp), image, 0, 0,
419                          0, 0, bmp->bitmap.bmWidth, height );
420     XDestroyImage( image ); /* frees tmpbuffer too */
421     return height * bmp->bitmap.bmWidthBytes;
422 }
423
424 /**********************************************************************
425  *          LoadImageA    (USER32.364)
426  * FIXME: implementation still lacks nearly all features, see LR_*
427  * defines in windows.h
428  */
429
430 HANDLE32 LoadImage32A(
431         HINSTANCE32 hinst,LPCSTR name,UINT32 type,INT32 desiredx,
432         INT32 desiredy,UINT32 loadflags
433 ) {
434         if (HIWORD(name)) {
435                 dprintf_resource(stddeb,"LoadImage32A(0x%04x,%s,%d,%d,%d,0x%08x)\n",
436                         hinst,name,type,desiredx,desiredy,loadflags
437                 );
438         } else {
439                 dprintf_resource(stddeb,"LoadImage32A(0x%04x,%p,%d,%d,%d,0x%08x)\n",
440                         hinst,name,type,desiredx,desiredy,loadflags
441                 );
442         }
443         switch (type) {
444         case IMAGE_BITMAP:
445                 return LoadBitmap32A(hinst,name);
446         case IMAGE_ICON:
447                 return LoadIcon32A(hinst,name);
448         case IMAGE_CURSOR:
449                 return LoadCursor32A(hinst,name);
450         }
451         return 0;
452 }
453
454 /**********************************************************************
455  *          CopyImage32    (USER32.60)
456  *
457  * FIXME: implementation still lacks nearly all features, see LR_*
458  * defines in windows.h
459  */
460 HANDLE32 CopyImage32( HANDLE32 hnd, UINT32 type, INT32 desiredx,
461                       INT32 desiredy, UINT32 flags )
462 {
463     switch (type)
464     {
465         case IMAGE_BITMAP:
466                 return hnd;     /* FIXME ... need to copy here */
467         case IMAGE_ICON:
468                 return CopyIcon32(hnd);
469         case IMAGE_CURSOR:
470                 return CopyCursor32(hnd);
471     }
472     return 0;
473 }
474
475
476 /**********************************************************************
477  *          LoadBitmap16    (USER.175)
478  */
479 HBITMAP16 LoadBitmap16( HINSTANCE16 instance, SEGPTR name )
480 {
481     HBITMAP32 hbitmap = 0;
482     HDC32 hdc;
483     HRSRC16 hRsrc;
484     HGLOBAL16 handle;
485     BITMAPINFO *info;
486
487     if (HIWORD(name))
488     {
489         char *str = (char *)PTR_SEG_TO_LIN( name );
490         dprintf_bitmap( stddeb, "LoadBitmap16(%04x,'%s')\n", instance, str );
491         if (str[0] == '#') name = (SEGPTR)(DWORD)(WORD)atoi( str + 1 );
492     }
493     else
494         dprintf_bitmap( stddeb, "LoadBitmap16(%04x,%04x)\n",
495                         instance, LOWORD(name) );
496
497     if (!instance)  /* OEM bitmap */
498     {
499         if (HIWORD((int)name)) return 0;
500         return OBM_LoadBitmap( LOWORD((int)name) );
501     }
502
503     if (!(hRsrc = FindResource16( instance, name, RT_BITMAP ))) return 0;
504     if (!(handle = LoadResource16( instance, hRsrc ))) return 0;
505
506     info = (BITMAPINFO *)LockResource16( handle );
507     if ((hdc = GetDC32(0)) != 0)
508     {
509         char *bits = (char *)info + DIB_BitmapInfoSize( info, DIB_RGB_COLORS );
510         hbitmap = CreateDIBitmap32( hdc, &info->bmiHeader, CBM_INIT,
511                                     bits, info, DIB_RGB_COLORS );
512         ReleaseDC32( 0, hdc );
513     }
514     FreeResource16( handle );
515     return hbitmap;
516 }
517
518 /**********************************************************************
519  *          LoadBitmap32W   (USER32.357)
520  */
521 HBITMAP32 LoadBitmap32W( HINSTANCE32 instance, LPCWSTR name )
522 {
523     HBITMAP32 hbitmap = 0;
524     HDC32 hdc;
525     HRSRC32 hRsrc;
526     HGLOBAL32 handle;
527     BITMAPINFO *info;
528
529     if (!instance)  /* OEM bitmap */
530     {
531         if (HIWORD((int)name)) return 0;
532         return OBM_LoadBitmap( LOWORD((int)name) );
533     }
534
535     if (!(hRsrc = FindResource32W( instance, name,
536                 (LPWSTR)RT_BITMAP ))) return 0;
537     if (!(handle = LoadResource32( instance, hRsrc ))) return 0;
538
539     info = (BITMAPINFO *)LockResource32( handle );
540     if ((hdc = GetDC32(0)) != 0)
541     {
542         char *bits = (char *)info + DIB_BitmapInfoSize( info, DIB_RGB_COLORS );
543         hbitmap = CreateDIBitmap32( hdc, &info->bmiHeader, CBM_INIT,
544                                     bits, info, DIB_RGB_COLORS );
545         ReleaseDC32( 0, hdc );
546     }
547     return hbitmap;
548 }
549
550
551 /**********************************************************************
552  *          LoadBitmap32A   (USER32.356)
553  */
554 HBITMAP32 LoadBitmap32A( HINSTANCE32 instance, LPCSTR name )
555 {
556     HBITMAP32 res;
557     if (!HIWORD(name)) res = LoadBitmap32W( instance, (LPWSTR)name );
558     else
559     {
560         LPWSTR uni = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
561         res = LoadBitmap32W( instance, uni );
562         HeapFree( GetProcessHeap(), 0, uni );
563     }
564     return res;
565 }
566
567
568 /***********************************************************************
569  *           BITMAP_DeleteObject
570  */
571 BOOL32 BITMAP_DeleteObject( HBITMAP16 hbitmap, BITMAPOBJ * bmp )
572 {
573 #ifdef PRELIMINARY_WING16_SUPPORT
574     if( bmp->bitmap.bmBits )
575         XShmDetach( display, (XShmSegmentInfo*)bmp->bitmap.bmBits );
576 #endif
577
578     XFreePixmap( display, bmp->pixmap );
579 #ifdef PRELIMINARY_WING16_SUPPORT
580     if( bmp->bitmap.bmBits )
581     {
582     __ShmBitmapCtl* p = (__ShmBitmapCtl*)bmp->bitmap.bmBits;
583       WORD          sel = HIWORD(p->bits);
584       unsigned long l, limit = GetSelectorLimit(sel);
585
586       for( l = 0; l < limit; l += 0x10000, sel += __AHINCR )
587            FreeSelector(sel);
588       shmctl(p->si.shmid, IPC_RMID, NULL); 
589       shmdt(p->si.shmaddr);  /* already marked for destruction */
590     }
591 #endif
592     return GDI_FreeObject( hbitmap );
593 }
594
595         
596 /***********************************************************************
597  *           BITMAP_GetObject16
598  */
599 INT16 BITMAP_GetObject16( BITMAPOBJ * bmp, INT16 count, LPVOID buffer )
600 {
601     if (count > sizeof(bmp->bitmap)) count = sizeof(bmp->bitmap);
602     memcpy( buffer, &bmp->bitmap, count );
603     return count;
604 }
605     
606
607 /***********************************************************************
608  *           BITMAP_GetObject32
609  */
610 INT32 BITMAP_GetObject32( BITMAPOBJ * bmp, INT32 count, LPVOID buffer )
611 {
612     BITMAP32 bmp32;
613     bmp32.bmType       = bmp->bitmap.bmType;
614     bmp32.bmWidth      = bmp->bitmap.bmWidth;
615     bmp32.bmHeight     = bmp->bitmap.bmHeight;
616     bmp32.bmWidthBytes = bmp->bitmap.bmWidthBytes;
617     bmp32.bmPlanes     = bmp->bitmap.bmPlanes;
618     bmp32.bmBitsPixel  = bmp->bitmap.bmBitsPixel;
619     bmp32.bmBits       = NULL;
620     if (count > sizeof(bmp32)) count = sizeof(bmp32);
621     memcpy( buffer, &bmp32, count );
622     return count;
623 }
624     
625
626
627 /***********************************************************************
628  *           CreateDiscardableBitmap16    (GDI.156)
629  */
630 HBITMAP16 CreateDiscardableBitmap16( HDC16 hdc, INT16 width, INT16 height )
631 {
632     return CreateCompatibleBitmap16( hdc, width, height );
633 }
634
635
636 /***********************************************************************
637  *           CreateDiscardableBitmap32    (GDI32.38)
638  */
639 HBITMAP32 CreateDiscardableBitmap32( HDC32 hdc, INT32 width, INT32 height )
640 {
641     return CreateCompatibleBitmap32( hdc, width, height );
642 }
643
644
645 /***********************************************************************
646  *           GetBitmapDimensionEx16    (GDI.468)
647  */
648 BOOL16 GetBitmapDimensionEx16( HBITMAP16 hbitmap, LPSIZE16 size )
649 {
650     BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
651     if (!bmp) return FALSE;
652     *size = bmp->size;
653     return TRUE;
654 }
655
656
657 /***********************************************************************
658  *           GetBitmapDimensionEx32    (GDI32.144)
659  */
660 BOOL32 GetBitmapDimensionEx32( HBITMAP32 hbitmap, LPSIZE32 size )
661 {
662     BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
663     if (!bmp) return FALSE;
664     size->cx = (INT32)bmp->size.cx;
665     size->cy = (INT32)bmp->size.cy;
666     return TRUE;
667 }
668
669
670 /***********************************************************************
671  *           GetBitmapDimension    (GDI.162)
672  */
673 DWORD GetBitmapDimension( HBITMAP16 hbitmap )
674 {
675     SIZE16 size;
676     if (!GetBitmapDimensionEx16( hbitmap, &size )) return 0;
677     return MAKELONG( size.cx, size.cy );
678 }
679
680
681 /***********************************************************************
682  *           SetBitmapDimensionEx16    (GDI.478)
683  */
684 BOOL16 SetBitmapDimensionEx16( HBITMAP16 hbitmap, INT16 x, INT16 y,
685                                LPSIZE16 prevSize )
686 {
687     BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
688     if (!bmp) return FALSE;
689     if (prevSize) *prevSize = bmp->size;
690     bmp->size.cx = x;
691     bmp->size.cy = y;
692     return TRUE;
693 }
694
695
696 /***********************************************************************
697  *           SetBitmapDimensionEx32    (GDI32.304)
698  */
699 BOOL32 SetBitmapDimensionEx32( HBITMAP32 hbitmap, INT32 x, INT32 y,
700                                LPSIZE32 prevSize )
701 {
702     BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
703     if (!bmp) return FALSE;
704     if (prevSize) CONV_SIZE16TO32( &bmp->size, prevSize );
705     bmp->size.cx = (INT16)x;
706     bmp->size.cy = (INT16)y;
707     return TRUE;
708 }
709
710
711 /***********************************************************************
712  *           SetBitmapDimension    (GDI.163)
713  */
714 DWORD SetBitmapDimension( HBITMAP16 hbitmap, INT16 x, INT16 y )
715 {
716     SIZE16 size;
717     if (!SetBitmapDimensionEx16( hbitmap, x, y, &size )) return 0;
718     return MAKELONG( size.cx, size.cy );
719 }