]>
code.delx.au - refind/blob - libeg/load_bmp.c
3 * Loading function for BMP images
5 * Copyright (c) 2006 Christoph Pfisterer
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the
20 * * Neither the name of Christoph Pfisterer nor the names of the
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 #ifdef __MAKEWITH_GNUEFI
60 UINT16 Planes
; // Must be 1
61 UINT16 BitPerPixel
; // 1, 4, 8, or 24
62 UINT32 CompressionType
;
63 UINT32 ImageSize
; // Compressed image size in bytes
64 UINT32 XPixelsPerMeter
;
65 UINT32 YPixelsPerMeter
;
66 UINT32 NumberOfColors
;
67 UINT32 ImportantColors
;
77 EG_IMAGE
* egDecodeBMP(IN UINT8
*FileData
, IN UINTN FileDataLength
, IN UINTN IconSize
, IN BOOLEAN WantAlpha
)
80 BMP_IMAGE_HEADER
*BmpHeader
;
81 BMP_COLOR_MAP
*BmpColorMap
;
85 UINTN ImageLineOffset
;
86 UINT8 ImageValue
= 0, AlphaValue
;
88 UINTN Index
, BitIndex
;
90 // read and check header
91 if (FileDataLength
< sizeof(BMP_IMAGE_HEADER
) || FileData
== NULL
)
93 BmpHeader
= (BMP_IMAGE_HEADER
*) FileData
;
94 if (BmpHeader
->CharB
!= 'B' || BmpHeader
->CharM
!= 'M')
96 if (BmpHeader
->CompressionType
!= 0)
98 if (BmpHeader
->BitPerPixel
!= 1 && BmpHeader
->BitPerPixel
!= 4 &&
99 BmpHeader
->BitPerPixel
!= 8 && BmpHeader
->BitPerPixel
!= 24)
102 // calculate parameters
103 ImageLineOffset
= BmpHeader
->PixelWidth
;
104 if (BmpHeader
->BitPerPixel
== 24)
105 ImageLineOffset
*= 3;
106 else if (BmpHeader
->BitPerPixel
== 1)
107 ImageLineOffset
= (ImageLineOffset
+ 7) >> 3;
108 else if (BmpHeader
->BitPerPixel
== 4)
109 ImageLineOffset
= (ImageLineOffset
+ 1) >> 1;
110 if ((ImageLineOffset
% 4) != 0)
111 ImageLineOffset
= ImageLineOffset
+ (4 - (ImageLineOffset
% 4));
113 if (BmpHeader
->ImageOffset
+ ImageLineOffset
* BmpHeader
->PixelHeight
> FileDataLength
)
116 // allocate image structure and buffer
117 NewImage
= egCreateImage(BmpHeader
->PixelWidth
, BmpHeader
->PixelHeight
, WantAlpha
);
118 if (NewImage
== NULL
)
120 AlphaValue
= WantAlpha
? 255 : 0;
123 BmpColorMap
= (BMP_COLOR_MAP
*)(FileData
+ sizeof(BMP_IMAGE_HEADER
));
124 ImagePtrBase
= FileData
+ BmpHeader
->ImageOffset
;
125 for (y
= 0; y
< BmpHeader
->PixelHeight
; y
++) {
126 ImagePtr
= ImagePtrBase
;
127 ImagePtrBase
+= ImageLineOffset
;
128 PixelPtr
= NewImage
->PixelData
+ (BmpHeader
->PixelHeight
- 1 - y
) * BmpHeader
->PixelWidth
;
130 switch (BmpHeader
->BitPerPixel
) {
133 for (x
= 0; x
< BmpHeader
->PixelWidth
; x
++) {
136 ImageValue
= *ImagePtr
++;
138 Index
= (ImageValue
>> (7 - BitIndex
)) & 0x01;
139 PixelPtr
->b
= BmpColorMap
[Index
].Blue
;
140 PixelPtr
->g
= BmpColorMap
[Index
].Green
;
141 PixelPtr
->r
= BmpColorMap
[Index
].Red
;
142 PixelPtr
->a
= AlphaValue
;
148 for (x
= 0; x
<= BmpHeader
->PixelWidth
- 2; x
+= 2) {
149 ImageValue
= *ImagePtr
++;
151 Index
= ImageValue
>> 4;
152 PixelPtr
->b
= BmpColorMap
[Index
].Blue
;
153 PixelPtr
->g
= BmpColorMap
[Index
].Green
;
154 PixelPtr
->r
= BmpColorMap
[Index
].Red
;
155 PixelPtr
->a
= AlphaValue
;
158 Index
= ImageValue
& 0x0f;
159 PixelPtr
->b
= BmpColorMap
[Index
].Blue
;
160 PixelPtr
->g
= BmpColorMap
[Index
].Green
;
161 PixelPtr
->r
= BmpColorMap
[Index
].Red
;
162 PixelPtr
->a
= AlphaValue
;
165 if (x
< BmpHeader
->PixelWidth
) {
166 ImageValue
= *ImagePtr
++;
168 Index
= ImageValue
>> 4;
169 PixelPtr
->b
= BmpColorMap
[Index
].Blue
;
170 PixelPtr
->g
= BmpColorMap
[Index
].Green
;
171 PixelPtr
->r
= BmpColorMap
[Index
].Red
;
172 PixelPtr
->a
= AlphaValue
;
178 for (x
= 0; x
< BmpHeader
->PixelWidth
; x
++) {
180 PixelPtr
->b
= BmpColorMap
[Index
].Blue
;
181 PixelPtr
->g
= BmpColorMap
[Index
].Green
;
182 PixelPtr
->r
= BmpColorMap
[Index
].Red
;
183 PixelPtr
->a
= AlphaValue
;
189 for (x
= 0; x
< BmpHeader
->PixelWidth
; x
++) {
190 PixelPtr
->b
= *ImagePtr
++;
191 PixelPtr
->g
= *ImagePtr
++;
192 PixelPtr
->r
= *ImagePtr
++;
193 PixelPtr
->a
= AlphaValue
;
208 VOID
egEncodeBMP(IN EG_IMAGE
*Image
, OUT UINT8
**FileDataReturn
, OUT UINTN
*FileDataLengthReturn
)
210 BMP_IMAGE_HEADER
*BmpHeader
;
212 UINTN FileDataLength
;
215 UINTN ImageLineOffset
;
219 ImageLineOffset
= Image
->Width
* 3;
220 if ((ImageLineOffset
% 4) != 0)
221 ImageLineOffset
= ImageLineOffset
+ (4 - (ImageLineOffset
% 4));
223 // allocate buffer for file data
224 FileDataLength
= sizeof(BMP_IMAGE_HEADER
) + Image
->Height
* ImageLineOffset
;
225 FileData
= AllocateZeroPool(FileDataLength
);
226 if (FileData
== NULL
) {
227 Print(L
"Error allocate %d bytes\n", FileDataLength
);
228 *FileDataReturn
= NULL
;
229 *FileDataLengthReturn
= 0;
234 BmpHeader
= (BMP_IMAGE_HEADER
*)FileData
;
235 BmpHeader
->CharB
= 'B';
236 BmpHeader
->CharM
= 'M';
237 BmpHeader
->Size
= FileDataLength
;
238 BmpHeader
->ImageOffset
= sizeof(BMP_IMAGE_HEADER
);
239 BmpHeader
->HeaderSize
= 40;
240 BmpHeader
->PixelWidth
= Image
->Width
;
241 BmpHeader
->PixelHeight
= Image
->Height
;
242 BmpHeader
->Planes
= 1;
243 BmpHeader
->BitPerPixel
= 24;
244 BmpHeader
->CompressionType
= 0;
245 BmpHeader
->XPixelsPerMeter
= 0xb13;
246 BmpHeader
->YPixelsPerMeter
= 0xb13;
249 ImagePtrBase
= FileData
+ BmpHeader
->ImageOffset
;
250 for (y
= 0; y
< Image
->Height
; y
++) {
251 ImagePtr
= ImagePtrBase
;
252 ImagePtrBase
+= ImageLineOffset
;
253 PixelPtr
= Image
->PixelData
+ (Image
->Height
- 1 - y
) * Image
->Width
;
255 for (x
= 0; x
< Image
->Width
; x
++) {
256 *ImagePtr
++ = PixelPtr
->b
;
257 *ImagePtr
++ = PixelPtr
->g
;
258 *ImagePtr
++ = PixelPtr
->r
;
263 *FileDataReturn
= FileData
;
264 *FileDataLengthReturn
= FileDataLength
;