GetSystemPaletteEntries returns palette size if entries==NULL.
[wine] / objects / bitmap.c
1 /*
2  * GDI bitmap objects
3  *
4  * Copyright 1993 Alexandre Julliard
5  *           1998 Huw D M Davies
6  */
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include "gdi.h"
11 #include "dc.h"
12 #include "bitmap.h"
13 #include "heap.h"
14 #include "global.h"
15 #include "sysmetrics.h"
16 #include "cursoricon.h"
17 #include "debug.h"
18 #include "x11drv.h"
19
20 /***********************************************************************
21  *           BITMAP_GetPadding
22  *
23  * Return number of bytes to pad a scanline of 16-bit aligned Windows DDB data.
24  */
25 INT32 BITMAP_GetPadding( int bmWidth, int bpp )
26 {
27     INT32 pad;
28
29     switch (bpp) 
30     {
31     case 1:
32         pad = ((bmWidth-1) & 8) ? 0 : 1;
33         break;
34
35     case 8:
36         pad = (2 - (bmWidth & 1)) & 1;
37         break;
38
39     case 24:
40         pad = (bmWidth*3) & 1;
41         break;
42
43     case 32:
44     case 16:
45     case 15:
46         pad = 0; /* we have 16bit alignment already */
47         break;
48
49     case 4:
50         if (!(bmWidth & 3)) pad = 0;
51         else pad = ((4 - (bmWidth & 3)) + 1) / 2;
52         break;
53
54     default:
55         WARN(bitmap,"Unknown depth %d, please report.\n", bpp );
56         return -1;
57     }
58     return pad;
59 }
60
61 /***********************************************************************
62  *           BITMAP_GetWidthBytes
63  *
64  * Return number of bytes taken by a scanline of 16-bit aligned Windows DDB
65  * data.
66  */
67 INT32 BITMAP_GetWidthBytes( INT32 bmWidth, INT32 bpp )
68 {
69     switch(bpp)
70     {
71     case 1:
72         return 2 * ((bmWidth+15) >> 4);
73
74     case 24:
75         bmWidth *= 3; /* fall through */
76     case 8:
77         return bmWidth + (bmWidth & 1);
78
79     case 32:
80         return bmWidth * 4;
81
82     case 16:
83     case 15:
84         return bmWidth * 2;
85
86     case 4:
87         return 2 * ((bmWidth+3) >> 2);
88
89     default:
90         WARN(bitmap,"Unknown depth %d, please report.\n", bpp );
91     }
92     return -1;
93 }
94
95 /***********************************************************************
96  *           CreateUserBitmap16    (GDI.407)
97  */
98 HBITMAP16 WINAPI CreateUserBitmap16( INT16 width, INT16 height, UINT16 planes,
99                                      UINT16 bpp, LPCVOID bits )
100 {
101     return CreateBitmap16( width, height, planes, bpp, bits );
102 }
103
104 /***********************************************************************
105  *           CreateUserDiscardableBitmap16    (GDI.409)
106  */
107 HBITMAP16 WINAPI CreateUserDiscardableBitmap16( WORD dummy, 
108                                                 INT16 width, INT16 height )
109 {
110     return CreateUserBitmap16( width, height, 1, screenDepth, NULL );
111 }
112
113
114 /***********************************************************************
115  *           CreateBitmap16    (GDI.48)
116  */
117 HBITMAP16 WINAPI CreateBitmap16( INT16 width, INT16 height, UINT16 planes,
118                                  UINT16 bpp, LPCVOID bits )
119 {
120     return CreateBitmap32( width, height, planes, bpp, bits );
121 }
122
123
124 /******************************************************************************
125  * CreateBitmap32 [GDI32.25]  Creates a bitmap with the specified info
126  *
127  * PARAMS
128  *    width  [I] bitmap width
129  *    height [I] bitmap height
130  *    planes [I] Number of color planes
131  *    bpp    [I] Number of bits to identify a color
132  *    bits   [I] Pointer to array containing color data
133  *
134  * RETURNS
135  *    Success: Handle to bitmap
136  *    Failure: 0
137  */
138 HBITMAP32 WINAPI CreateBitmap32( INT32 width, INT32 height, UINT32 planes,
139                                  UINT32 bpp, LPCVOID bits )
140 {
141     BITMAPOBJ *bmp;
142     HBITMAP32 hbitmap;
143
144     planes = (BYTE)planes;
145     bpp    = (BYTE)bpp;
146
147
148       /* Check parameters */
149     if (!height || !width) return 0;
150     if (planes != 1) {
151         FIXME(bitmap, "planes = %d\n", planes);
152         return 0;
153     }
154     if (height < 0) height = -height;
155     if (width < 0) width = -width;
156
157       /* Create the BITMAPOBJ */
158     hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
159     if (!hbitmap) return 0;
160
161     TRACE(bitmap, "%dx%d, %d colors returning %08x\n", width, height,
162           1 << (planes*bpp), hbitmap);
163
164     bmp = (BITMAPOBJ *) GDI_HEAP_LOCK( hbitmap );
165
166     bmp->size.cx = 0;
167     bmp->size.cy = 0;
168     bmp->bitmap.bmType = 0;
169     bmp->bitmap.bmWidth = width;
170     bmp->bitmap.bmHeight = height;
171     bmp->bitmap.bmPlanes = planes;
172     bmp->bitmap.bmBitsPixel = bpp;
173     bmp->bitmap.bmWidthBytes = BITMAP_GetWidthBytes( width, bpp );
174     bmp->bitmap.bmBits = NULL;
175
176     bmp->DDBitmap = NULL;
177     bmp->dib = NULL;
178
179     if (bits) /* Set bitmap bits */
180         SetBitmapBits32( hbitmap, height * bmp->bitmap.bmWidthBytes,
181                          bits );
182     GDI_HEAP_UNLOCK( hbitmap );
183     return hbitmap;
184 }
185
186
187 /***********************************************************************
188  *           CreateCompatibleBitmap16    (GDI.51)
189  */
190 HBITMAP16 WINAPI CreateCompatibleBitmap16(HDC16 hdc, INT16 width, INT16 height)
191 {
192     return CreateCompatibleBitmap32( hdc, width, height );
193 }
194
195
196 /******************************************************************************
197  * CreateCompatibleBitmap32 [GDI32.30]  Creates a bitmap compatible with the DC
198  *
199  * PARAMS
200  *    hdc    [I] Handle to device context
201  *    width  [I] Width of bitmap
202  *    height [I] Height of bitmap
203  *
204  * RETURNS
205  *    Success: Handle to bitmap
206  *    Failure: 0
207  */
208 HBITMAP32 WINAPI CreateCompatibleBitmap32( HDC32 hdc, INT32 width, INT32 height)
209 {
210     HBITMAP32 hbmpRet = 0;
211     DC *dc;
212
213     TRACE(bitmap, "(%04x,%d,%d) = \n", hdc, width, height );
214     if (!(dc = DC_GetDCPtr( hdc ))) return 0;
215     if ((width >0x1000) || (height > 0x1000)) {
216         FIXME(bitmap,"got bad width %d or height %d, please look for reason\n",
217               width, height );
218         return 0;
219     }
220     hbmpRet = CreateBitmap32( width, height, 1, dc->w.bitsPerPixel, NULL );
221
222     if(dc->funcs->pCreateBitmap)
223         dc->funcs->pCreateBitmap( hbmpRet );
224
225     TRACE(bitmap,"\t\t%04x\n", hbmpRet);
226     return hbmpRet;
227 }
228
229
230 /***********************************************************************
231  *           CreateBitmapIndirect16    (GDI.49)
232  */
233 HBITMAP16 WINAPI CreateBitmapIndirect16( const BITMAP16 * bmp )
234 {
235     return CreateBitmap16( bmp->bmWidth, bmp->bmHeight, bmp->bmPlanes,
236                            bmp->bmBitsPixel, PTR_SEG_TO_LIN( bmp->bmBits ) );
237 }
238
239
240 /******************************************************************************
241  * CreateBitmapIndirect32 [GDI32.26]  Creates a bitmap with the specifies info
242  *
243  * RETURNS
244  *    Success: Handle to bitmap
245  *    Failure: NULL
246  */
247 HBITMAP32 WINAPI CreateBitmapIndirect32(
248     const BITMAP32 * bmp) /* [in] Pointer to the bitmap data */
249 {
250     return CreateBitmap32( bmp->bmWidth, bmp->bmHeight, bmp->bmPlanes,
251                            bmp->bmBitsPixel, bmp->bmBits );
252 }
253
254
255 /***********************************************************************
256  *           GetBitmapBits16    (GDI.74)
257  */
258 LONG WINAPI GetBitmapBits16( HBITMAP16 hbitmap, LONG count, LPVOID buffer )
259 {
260     return GetBitmapBits32( hbitmap, count, buffer );
261 }
262
263
264 /***********************************************************************
265  * GetBitmapBits32 [GDI32.143]  Copies bitmap bits of bitmap to buffer
266  * 
267  * RETURNS
268  *    Success: Number of bytes copied
269  *    Failure: 0
270  */
271 LONG WINAPI GetBitmapBits32(
272     HBITMAP32 hbitmap, /* [in]  Handle to bitmap */
273     LONG count,        /* [in]  Number of bytes to copy */
274     LPVOID bits)       /* [out] Pointer to buffer to receive bits */
275 {
276     BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
277     LONG height, ret;
278     
279     if (!bmp) return 0;
280
281     if (count < 0) {
282         WARN(bitmap, "(%ld): Negative number of bytes passed???\n", count );
283         count = -count;
284     }
285
286     /* Only get entire lines */
287     height = count / bmp->bitmap.bmWidthBytes;
288     if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight;
289     count = height * bmp->bitmap.bmWidthBytes;
290     if (count == 0)
291       {
292         WARN(bitmap, "Less then one entire line requested\n");
293         GDI_HEAP_UNLOCK( hbitmap );
294         return 0;
295       }
296
297
298     TRACE(bitmap, "(%08x, %ld, %p) %dx%d %d colors fetched height: %ld\n",
299             hbitmap, count, bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
300             1 << bmp->bitmap.bmBitsPixel, height );
301
302     if(bmp->DDBitmap) { 
303
304         TRACE(bitmap, "Calling device specific BitmapBits\n");
305         if(bmp->DDBitmap->funcs->pBitmapBits)
306             ret = bmp->DDBitmap->funcs->pBitmapBits(hbitmap, bits, count,
307                                                     DDB_GET);
308         else {
309             ERR(bitmap, "BitmapBits == NULL??\n");
310             ret = 0;
311         }       
312
313     } else {
314
315         if(!bmp->bitmap.bmBits) {
316             WARN(bitmap, "Bitmap is empty\n");
317             ret = 0;
318         } else {
319             memcpy(bits, bmp->bitmap.bmBits, count);
320             ret = count;
321         }
322
323     }
324
325     GDI_HEAP_UNLOCK( hbitmap );
326     return ret;
327 }
328
329
330 /***********************************************************************
331  *           SetBitmapBits16    (GDI.106)
332  */
333 LONG WINAPI SetBitmapBits16( HBITMAP16 hbitmap, LONG count, LPCVOID buffer )
334 {
335     return SetBitmapBits32( hbitmap, count, buffer );
336 }
337
338
339 /******************************************************************************
340  * SetBitmapBits32 [GDI32.303]  Sets bits of color data for a bitmap
341  *
342  * RETURNS
343  *    Success: Number of bytes used in setting the bitmap bits
344  *    Failure: 0
345  */
346 LONG WINAPI SetBitmapBits32(
347     HBITMAP32 hbitmap, /* [in] Handle to bitmap */
348     LONG count,        /* [in] Number of bytes in bitmap array */
349     LPCVOID bits)      /* [in] Address of array with bitmap bits */
350 {
351     BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
352     LONG height, ret;
353     
354     if (!bmp) return 0;
355
356     if (count < 0) {
357         WARN(bitmap, "(%ld): Negative number of bytes passed???\n", count );
358         count = -count;
359     }
360
361     /* Only get entire lines */
362     height = count / bmp->bitmap.bmWidthBytes;
363     if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight;
364     count = height * bmp->bitmap.bmWidthBytes;
365
366     TRACE(bitmap, "(%08x, %ld, %p) %dx%d %d colors fetched height: %ld\n",
367             hbitmap, count, bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
368             1 << bmp->bitmap.bmBitsPixel, height );
369
370     if(bmp->DDBitmap) {
371
372         TRACE(bitmap, "Calling device specific BitmapBits\n");
373         if(bmp->DDBitmap->funcs->pBitmapBits)
374             ret = bmp->DDBitmap->funcs->pBitmapBits(hbitmap, (void *) bits,
375                                                     count, DDB_SET);
376         else {
377             ERR(bitmap, "BitmapBits == NULL??\n");
378             ret = 0;
379         }
380         
381     } else {
382
383         if(!bmp->bitmap.bmBits) /* Alloc enough for entire bitmap */
384             bmp->bitmap.bmBits = HeapAlloc( GetProcessHeap(), 0, count );
385         if(!bmp->bitmap.bmBits) {
386             WARN(bitmap, "Unable to allocate bit buffer\n");
387             ret = 0;
388         } else {
389             memcpy(bmp->bitmap.bmBits, bits, count);
390             ret = count;
391         }
392     }
393
394     GDI_HEAP_UNLOCK( hbitmap );
395     return ret;
396 }
397
398 /***********************************************************************
399  * LoadImage16 [USER.389]
400  *
401  */
402 HANDLE16 WINAPI LoadImage16( HINSTANCE16 hinst, LPCSTR name, UINT16 type,
403                              INT16 desiredx, INT16 desiredy, UINT16 loadflags)
404 {
405         if (HIWORD(name)) {
406             TRACE(resource,"(0x%04x,%s,%d,%d,%d,0x%08x)\n",
407                 hinst,(char *)PTR_SEG_TO_LIN(name),type,desiredx,desiredy,loadflags);
408         } else {
409             TRACE(resource,"LoadImage16(0x%04x,%p,%d,%d,%d,0x%08x)\n",
410                 hinst,name,type,desiredx,desiredy,loadflags);
411         }
412         switch (type) {
413         case IMAGE_BITMAP:
414                 return LoadBitmap16(hinst,(SEGPTR)name);
415         case IMAGE_ICON:
416                 return LoadIcon16(hinst,(SEGPTR)name);
417         case IMAGE_CURSOR:
418                 return LoadCursor16(hinst,(SEGPTR)name);
419         }
420         return 0;
421         
422 }
423
424 /**********************************************************************
425  *          LoadImage32A    (USER32.365)
426  * 
427  * FIXME: implementation lacks some features, see LR_ defines in windows.h
428  */
429
430 HANDLE32 WINAPI LoadImage32A( HINSTANCE32 hinst, LPCSTR name, UINT32 type,
431                               INT32 desiredx, INT32 desiredy, UINT32 loadflags)
432 {
433     HANDLE32 res;
434     LPWSTR u_name;
435
436     if (HIWORD(name)) u_name = HEAP_strdupAtoW(GetProcessHeap(), 0, name);
437     else u_name=(LPWSTR)name;
438     res = LoadImage32W(hinst, u_name, type, desiredx, desiredy, loadflags);
439     if (HIWORD(name)) HeapFree(GetProcessHeap(), 0, u_name);
440     return res;
441 }
442
443
444 /******************************************************************************
445  * LoadImage32W [USER32.366]  Loads an icon, cursor, or bitmap
446  *
447  * PARAMS
448  *    hinst     [I] Handle of instance that contains image
449  *    name      [I] Name of image
450  *    type      [I] Type of image
451  *    desiredx  [I] Desired width
452  *    desiredy  [I] Desired height
453  *    loadflags [I] Load flags
454  *
455  * RETURNS
456  *    Success: Handle to newly loaded image
457  *    Failure: NULL
458  *
459  * FIXME: Implementation lacks some features, see LR_ defines in windows.h
460  */
461 HANDLE32 WINAPI LoadImage32W( HINSTANCE32 hinst, LPCWSTR name, UINT32 type,
462                 INT32 desiredx, INT32 desiredy, UINT32 loadflags )
463 {
464     if (HIWORD(name)) {
465         TRACE(resource,"(0x%04x,%p,%d,%d,%d,0x%08x)\n",
466               hinst,name,type,desiredx,desiredy,loadflags);
467     } else {
468         TRACE(resource,"(0x%04x,%p,%d,%d,%d,0x%08x)\n",
469               hinst,name,type,desiredx,desiredy,loadflags);
470     }
471     if (loadflags & LR_DEFAULTSIZE) {
472         if (type == IMAGE_ICON) {
473             if (!desiredx) desiredx = SYSMETRICS_CXICON;
474             if (!desiredy) desiredy = SYSMETRICS_CYICON;
475         } else if (type == IMAGE_CURSOR) {
476             if (!desiredx) desiredx = SYSMETRICS_CXCURSOR;
477             if (!desiredy) desiredy = SYSMETRICS_CYCURSOR;
478         }
479     }
480     if (loadflags & LR_LOADFROMFILE) loadflags &= ~LR_SHARED;
481     switch (type) {
482     case IMAGE_BITMAP:
483         return BITMAP_LoadBitmap32W(hinst, name, loadflags);
484
485     case IMAGE_ICON:
486         {
487         HDC32 hdc = GetDC32(0);
488         UINT32 palEnts = GetSystemPaletteEntries32(hdc, 0, 0, NULL);
489         ReleaseDC32(0, hdc);
490
491         return CURSORICON_Load32(hinst, name, desiredx, desiredy,
492                                  MIN(16, palEnts), FALSE, loadflags);
493         }
494
495     case IMAGE_CURSOR:
496         return CURSORICON_Load32(hinst, name, desiredx, desiredy,
497                                  1, TRUE, loadflags);
498     }
499     return 0;
500 }
501
502
503 /**********************************************************************
504  *              BITMAP_CopyBitmap
505  *
506  */
507 HBITMAP32 BITMAP_CopyBitmap(HBITMAP32 hbitmap)
508 {
509     BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
510     HBITMAP32 res = 0;
511     BITMAP32 bm;
512
513     if(!bmp) return 0;
514
515     bm = bmp->bitmap;
516     bm.bmBits = NULL;
517     res = CreateBitmapIndirect32(&bm);
518
519     if(res) {
520         char *buf = HeapAlloc( GetProcessHeap(), 0, bm.bmWidthBytes *
521                                bm.bmHeight );
522         GetBitmapBits32 (hbitmap, bm.bmWidthBytes * bm.bmHeight, buf);
523         SetBitmapBits32 (res, bm.bmWidthBytes * bm.bmHeight, buf);
524         HeapFree( GetProcessHeap(), 0, buf );
525     }
526
527     GDI_HEAP_UNLOCK( hbitmap );
528     return res;
529 }
530
531
532 /******************************************************************************
533  * CopyImage32 [USER32.61]  Creates new image and copies attributes to it
534  *
535  * PARAMS
536  *    hnd      [I] Handle to image to copy
537  *    type     [I] Type of image to copy
538  *    desiredx [I] Desired width of new image
539  *    desiredy [I] Desired height of new image
540  *    flags    [I] Copy flags
541  *
542  * RETURNS
543  *    Success: Handle to newly created image
544  *    Failure: NULL
545  *
546  * FIXME: implementation still lacks nearly all features, see LR_*
547  * defines in windows.h
548  */
549 HICON32 WINAPI CopyImage32( HANDLE32 hnd, UINT32 type, INT32 desiredx,
550                              INT32 desiredy, UINT32 flags )
551 {
552     switch (type)
553     {
554         case IMAGE_BITMAP:
555                 return BITMAP_CopyBitmap(hnd);
556         case IMAGE_ICON:
557                 return CopyIcon32(hnd);
558         case IMAGE_CURSOR:
559                 return CopyCursor32(hnd);
560     }
561     return 0;
562 }
563
564 /**********************************************************************
565  *          LoadBitmap16    (USER.175)
566  *
567  * NOTES
568  *    Can this call LoadBitmap32?
569  */
570 HBITMAP16 WINAPI LoadBitmap16( HINSTANCE16 instance, SEGPTR name )
571 {
572     HBITMAP32 hbitmap = 0;
573     HDC32 hdc;
574     HRSRC16 hRsrc;
575     HGLOBAL16 handle;
576     BITMAPINFO *info;
577
578     if (HIWORD(name))
579     {
580         char *str = (char *)PTR_SEG_TO_LIN( name );
581         TRACE(bitmap, "(%04x,'%s')\n", instance, str );
582         if (str[0] == '#') name = (SEGPTR)(DWORD)(WORD)atoi( str + 1 );
583     }
584     else
585         TRACE(bitmap, "(%04x,%04x)\n",
586                         instance, LOWORD(name) );
587
588     if (!instance)  /* OEM bitmap */
589     {
590         if (HIWORD((int)name)) return 0;
591         return OBM_LoadBitmap( LOWORD((int)name) );
592     }
593
594     if (!(hRsrc = FindResource16( instance, name, RT_BITMAP16 ))) return 0;
595     if (!(handle = LoadResource16( instance, hRsrc ))) return 0;
596
597     info = (BITMAPINFO *)LockResource16( handle );
598     if ((hdc = GetDC32(0)) != 0)
599     {
600         char *bits = (char *)info + DIB_BitmapInfoSize( info, DIB_RGB_COLORS );
601         hbitmap = CreateDIBitmap32( hdc, &info->bmiHeader, CBM_INIT,
602                                     bits, info, DIB_RGB_COLORS );
603         ReleaseDC32( 0, hdc );
604     }
605     FreeResource16( handle );
606     return hbitmap;
607 }
608
609
610 /**********************************************************************
611  *       BITMAP_LoadBitmap32W
612  */
613 HBITMAP32 BITMAP_LoadBitmap32W(HINSTANCE32 instance,LPCWSTR name, 
614                                UINT32 loadflags)
615 {
616     HBITMAP32 hbitmap = 0;
617     HDC32 hdc;
618     HRSRC32 hRsrc;
619     HGLOBAL32 handle;
620     char *ptr = NULL;
621     BITMAPINFO *info, *fix_info=NULL;
622     HGLOBAL32 hFix;
623     int size;
624
625     if (!(loadflags & LR_LOADFROMFILE)) {
626       if (!instance)  /* OEM bitmap */
627       {
628           if (HIWORD((int)name)) return 0;
629           return OBM_LoadBitmap( LOWORD((int)name) );
630       }
631
632       if (!(hRsrc = FindResource32W( instance, name, RT_BITMAP32W ))) return 0;
633       if (!(handle = LoadResource32( instance, hRsrc ))) return 0;
634
635       if ((info = (BITMAPINFO *)LockResource32( handle )) == NULL) return 0;
636     }
637     else
638     {
639         if (!(ptr = (char *)VIRTUAL_MapFileW( name ))) return 0;
640         info = (BITMAPINFO *)(ptr + sizeof(BITMAPFILEHEADER));
641     }
642     size = DIB_BitmapInfoSize(info, DIB_RGB_COLORS);
643     if ((hFix = GlobalAlloc32(0, size))) fix_info=GlobalLock32(hFix);
644     if (fix_info) {
645       BYTE pix;
646
647       memcpy(fix_info, info, size);
648       pix = *((LPBYTE)info+DIB_BitmapInfoSize(info, DIB_RGB_COLORS));
649       DIB_FixColorsToLoadflags(fix_info, loadflags, pix);
650       if ((hdc = GetDC32(0)) != 0) {
651         if (loadflags & LR_CREATEDIBSECTION)
652           hbitmap = CreateDIBSection32(hdc, fix_info, DIB_RGB_COLORS, NULL, 0, 0);
653         else {
654           char *bits = (char *)info + size;;
655           hbitmap = CreateDIBitmap32( hdc, &fix_info->bmiHeader, CBM_INIT,
656                                       bits, fix_info, DIB_RGB_COLORS );
657         }
658         ReleaseDC32( 0, hdc );
659       }
660       GlobalUnlock32(hFix);
661       GlobalFree32(hFix);
662     }
663     if (loadflags & LR_LOADFROMFILE) UnmapViewOfFile( ptr );
664     return hbitmap;
665 }
666
667
668 /******************************************************************************
669  * LoadBitmap32W [USER32.358]  Loads bitmap from the executable file
670  *
671  * RETURNS
672  *    Success: Handle to specified bitmap
673  *    Failure: NULL
674  */
675 HBITMAP32 WINAPI LoadBitmap32W(
676     HINSTANCE32 instance, /* [in] Handle to application instance */
677     LPCWSTR name)         /* [in] Address of bitmap resource name */
678 {
679     return BITMAP_LoadBitmap32W(instance, name, 0);
680 }
681
682
683 /**********************************************************************
684  *          LoadBitmap32A   (USER32.357)
685  */
686 HBITMAP32 WINAPI LoadBitmap32A( HINSTANCE32 instance, LPCSTR name )
687 {
688     HBITMAP32 res;
689     if (!HIWORD(name)) res = LoadBitmap32W( instance, (LPWSTR)name );
690     else
691     {
692         LPWSTR uni = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
693         res = LoadBitmap32W( instance, uni );
694         HeapFree( GetProcessHeap(), 0, uni );
695     }
696     return res;
697 }
698
699
700 /***********************************************************************
701  *           BITMAP_DeleteObject
702  */
703 BOOL32 BITMAP_DeleteObject( HBITMAP16 hbitmap, BITMAPOBJ * bmp )
704 {
705     if( bmp->DDBitmap ) {
706         if( bmp->DDBitmap->funcs->pDeleteObject )
707             bmp->DDBitmap->funcs->pDeleteObject( hbitmap );
708     }
709
710     if( bmp->bitmap.bmBits )
711         HeapFree( GetProcessHeap(), 0, bmp->bitmap.bmBits );
712
713     DIB_DeleteDIBSection( bmp );
714
715     return GDI_FreeObject( hbitmap );
716 }
717
718         
719 /***********************************************************************
720  *           BITMAP_GetObject16
721  */
722 INT16 BITMAP_GetObject16( BITMAPOBJ * bmp, INT16 count, LPVOID buffer )
723 {
724     if (bmp->dib)
725     {
726         if ( count <= sizeof(BITMAP16) )
727         {
728             BITMAP32 *bmp32 = &bmp->dib->dibSection.dsBm;
729             BITMAP16 bmp16;
730             bmp16.bmType       = bmp32->bmType;
731             bmp16.bmWidth      = bmp32->bmWidth;
732             bmp16.bmHeight     = bmp32->bmHeight;
733             bmp16.bmWidthBytes = bmp32->bmWidthBytes;
734             bmp16.bmPlanes     = bmp32->bmPlanes;
735             bmp16.bmBitsPixel  = bmp32->bmBitsPixel;
736             bmp16.bmBits       = (SEGPTR)0;
737             memcpy( buffer, &bmp16, count );
738             return count;
739         }
740         else
741         {
742             FIXME(bitmap, "not implemented for DIBs: count %d\n", count);
743             return 0;
744         }
745     }
746     else
747     {
748         BITMAP16 bmp16;
749         bmp16.bmType       = bmp->bitmap.bmType;
750         bmp16.bmWidth      = bmp->bitmap.bmWidth;
751         bmp16.bmHeight     = bmp->bitmap.bmHeight;
752         bmp16.bmWidthBytes = bmp->bitmap.bmWidthBytes;
753         bmp16.bmPlanes     = bmp->bitmap.bmPlanes;
754         bmp16.bmBitsPixel  = bmp->bitmap.bmBitsPixel;
755         bmp16.bmBits       = (SEGPTR)0;
756         if (count > sizeof(bmp16)) count = sizeof(bmp16);
757         memcpy( buffer, &bmp16, count );
758         return count;
759     }
760 }
761     
762
763 /***********************************************************************
764  *           BITMAP_GetObject32
765  */
766 INT32 BITMAP_GetObject32( BITMAPOBJ * bmp, INT32 count, LPVOID buffer )
767 {
768     if (bmp->dib)
769     {
770         if (count < sizeof(DIBSECTION))
771         {
772             if (count > sizeof(BITMAP32)) count = sizeof(BITMAP32);
773         }
774         else
775         {
776             if (count > sizeof(DIBSECTION)) count = sizeof(DIBSECTION);
777         }
778
779         memcpy( buffer, &bmp->dib->dibSection, count );
780         return count;
781     }
782     else
783     {
784         if (count > sizeof(BITMAP32)) count = sizeof(BITMAP32);
785         memcpy( buffer, &bmp->bitmap, count );
786         return count;
787     }
788 }
789     
790
791 /***********************************************************************
792  *           CreateDiscardableBitmap16    (GDI.156)
793  */
794 HBITMAP16 WINAPI CreateDiscardableBitmap16( HDC16 hdc, INT16 width,
795                                             INT16 height )
796 {
797     return CreateCompatibleBitmap16( hdc, width, height );
798 }
799
800
801 /******************************************************************************
802  * CreateDiscardableBitmap32 [GDI32.38]  Creates a discardable bitmap
803  *
804  * RETURNS
805  *    Success: Handle to bitmap
806  *    Failure: NULL
807  */
808 HBITMAP32 WINAPI CreateDiscardableBitmap32(
809     HDC32 hdc,    /* [in] Handle to device context */
810     INT32 width,  /* [in] Bitmap width */
811     INT32 height) /* [in] Bitmap height */
812 {
813     return CreateCompatibleBitmap32( hdc, width, height );
814 }
815
816
817 /***********************************************************************
818  *           GetBitmapDimensionEx16    (GDI.468)
819  *
820  * NOTES
821  *    Can this call GetBitmapDimensionEx32?
822  */
823 BOOL16 WINAPI GetBitmapDimensionEx16( HBITMAP16 hbitmap, LPSIZE16 size )
824 {
825     BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
826     if (!bmp) return FALSE;
827     CONV_SIZE32TO16( &bmp->size, size );
828     GDI_HEAP_UNLOCK( hbitmap );
829     return TRUE;
830 }
831
832
833 /******************************************************************************
834  * GetBitmapDimensionEx32 [GDI32.144]  Retrieves dimensions of a bitmap
835  *
836  * RETURNS
837  *    Success: TRUE
838  *    Failure: FALSE
839  */
840 BOOL32 WINAPI GetBitmapDimensionEx32(
841     HBITMAP32 hbitmap, /* [in]  Handle to bitmap */
842     LPSIZE32 size)     /* [out] Address of struct receiving dimensions */
843 {
844     BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
845     if (!bmp) return FALSE;
846     *size = bmp->size;
847     GDI_HEAP_UNLOCK( hbitmap );
848     return TRUE;
849 }
850
851
852 /***********************************************************************
853  *           GetBitmapDimension    (GDI.162)
854  */
855 DWORD WINAPI GetBitmapDimension( HBITMAP16 hbitmap )
856 {
857     SIZE16 size;
858     if (!GetBitmapDimensionEx16( hbitmap, &size )) return 0;
859     return MAKELONG( size.cx, size.cy );
860 }
861
862
863 /***********************************************************************
864  *           SetBitmapDimensionEx16    (GDI.478)
865  */
866 BOOL16 WINAPI SetBitmapDimensionEx16( HBITMAP16 hbitmap, INT16 x, INT16 y,
867                                       LPSIZE16 prevSize )
868 {
869     BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
870     if (!bmp) return FALSE;
871     if (prevSize) CONV_SIZE32TO16( &bmp->size, prevSize );
872     bmp->size.cx = x;
873     bmp->size.cy = y;
874     GDI_HEAP_UNLOCK( hbitmap );
875     return TRUE;
876 }
877
878
879 /******************************************************************************
880  * SetBitmapDimensionEx32 [GDI32.304]  Assignes dimensions to a bitmap
881  *
882  * RETURNS
883  *    Success: TRUE
884  *    Failure: FALSE
885  */
886 BOOL32 WINAPI SetBitmapDimensionEx32(
887     HBITMAP32 hbitmap, /* [in]  Handle to bitmap */
888     INT32 x,           /* [in]  Bitmap width */
889     INT32 y,           /* [in]  Bitmap height */
890     LPSIZE32 prevSize) /* [out] Address of structure for orig dims */
891 {
892     BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
893     if (!bmp) return FALSE;
894     if (prevSize) *prevSize = bmp->size;
895     bmp->size.cx = x;
896     bmp->size.cy = y;
897     GDI_HEAP_UNLOCK( hbitmap );
898     return TRUE;
899 }
900
901
902 /***********************************************************************
903  *           SetBitmapDimension    (GDI.163)
904  */
905 DWORD WINAPI SetBitmapDimension( HBITMAP16 hbitmap, INT16 x, INT16 y )
906 {
907     SIZE16 size;
908     if (!SetBitmapDimensionEx16( hbitmap, x, y, &size )) return 0;
909     return MAKELONG( size.cx, size.cy );
910 }
911