xref: /reactos/dll/cpl/desk/dibitmap.c (revision c2c66aff)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS Display Control Panel
4  * FILE:            dll/cpl/desk/dibitmap.c
5  * PURPOSE:         DIB loading
6  *
7  * PROGRAMMERS:     Trevor McCort (lycan359@gmail.com)
8  */
9 
10 #include "desk.h"
11 
12 PDIBITMAP
DibLoadImage(LPTSTR lpFilename)13 DibLoadImage(LPTSTR lpFilename)
14 {
15     PDIBITMAP lpBitmap;
16     GpBitmap  *bitmap;
17     BitmapData lock;
18 
19     if (GdipCreateBitmapFromFile(lpFilename, &bitmap) != Ok)
20     {
21         return NULL;
22     }
23 
24     lpBitmap = HeapAlloc(GetProcessHeap(), 0, sizeof(DIBITMAP));
25     if (lpBitmap == NULL)
26     {
27         GdipDisposeImage((GpImage*)bitmap);
28         return NULL;
29     }
30 
31     lpBitmap->info = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFO));
32     if (lpBitmap->info == NULL)
33     {
34         HeapFree(GetProcessHeap(), 0, lpBitmap);
35         GdipDisposeImage((GpImage*)bitmap);
36         return NULL;
37     }
38 
39     if (GdipGetImageWidth((GpImage*)bitmap, &lpBitmap->width) != Ok ||
40         GdipGetImageHeight((GpImage*)bitmap, &lpBitmap->height) != Ok)
41     {
42         HeapFree(GetProcessHeap(), 0, lpBitmap->info);
43         HeapFree(GetProcessHeap(), 0, lpBitmap);
44         GdipDisposeImage((GpImage*)bitmap);
45         return NULL;
46     }
47 
48     lpBitmap->bits = HeapAlloc(GetProcessHeap(), 0, lpBitmap->width * lpBitmap->height * 4);
49     if (!lpBitmap->bits)
50     {
51         HeapFree(GetProcessHeap(), 0, lpBitmap->info);
52         HeapFree(GetProcessHeap(), 0, lpBitmap);
53         GdipDisposeImage((GpImage*)bitmap);
54         return NULL;
55     }
56 
57     ZeroMemory(lpBitmap->info, sizeof(BITMAPINFO));
58     lpBitmap->info->bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
59     lpBitmap->info->bmiHeader.biWidth       = lpBitmap->width;
60     lpBitmap->info->bmiHeader.biHeight      = -(INT)lpBitmap->height;
61     lpBitmap->info->bmiHeader.biPlanes      = 1;
62     lpBitmap->info->bmiHeader.biBitCount    = 32;
63     lpBitmap->info->bmiHeader.biCompression = BI_RGB;
64     lpBitmap->info->bmiHeader.biSizeImage   = lpBitmap->width * lpBitmap->height * 4;
65 
66     lock.Width = lpBitmap->width;
67     lock.Height = lpBitmap->height;
68     lock.Stride = lpBitmap->width * 4;
69     lock.PixelFormat = PixelFormat32bppPARGB;
70     lock.Scan0  = lpBitmap->bits;
71     lock.Reserved = 0;
72 
73     if (GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead | ImageLockModeUserInputBuf, PixelFormat32bppPARGB, &lock) != Ok)
74     {
75         HeapFree(GetProcessHeap(), 0, lpBitmap->bits);
76         HeapFree(GetProcessHeap(), 0, lpBitmap->info);
77         HeapFree(GetProcessHeap(), 0, lpBitmap);
78         GdipDisposeImage((GpImage*)bitmap);
79         return NULL;
80     }
81 
82     GdipBitmapUnlockBits(bitmap, &lock);
83     GdipDisposeImage((GpImage*)bitmap);
84 
85     return lpBitmap;
86 }
87 
88 
89 VOID
DibFreeImage(PDIBITMAP lpBitmap)90 DibFreeImage(PDIBITMAP lpBitmap)
91 {
92     if (lpBitmap == NULL)
93         return;
94 
95     /* Free the image data */
96     if (lpBitmap->bits != NULL)
97         HeapFree(GetProcessHeap(), 0, lpBitmap->bits);
98 
99     /* Free the bitmap info */
100     if (lpBitmap->info != NULL)
101         HeapFree(GetProcessHeap(), 0, lpBitmap->info);
102 
103     /* Free the bitmap structure */
104     if (lpBitmap != NULL)
105         HeapFree(GetProcessHeap(), 0, lpBitmap);
106 }
107