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