]> code.delx.au - refind/blob - libeg/lodepng_xtra.c
343fbffc1c67501efecee5bb4622370b44658fb0
[refind] / libeg / lodepng_xtra.c
1 /*
2 * Additional functions to support LodePNG for use in rEFInd
3 *
4 * copyright (c) 2013 by by Roderick W. Smith, and distributed
5 * under the terms of the GNU GPL v3, or (at your option) any
6 * later version.
7 *
8 * See http://lodev.org/lodepng/ for the original LodePNG.
9 *
10 */
11 /*
12 * This program is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26 #include "global.h"
27 #include "../refind/screen.h"
28 #include "lodepng.h"
29
30 // EFI's equivalent of realloc requires the original buffer's size as an
31 // input parameter, which the standard libc realloc does not require. Thus,
32 // I've modified lodepng_malloc() to allocate more memory to store this data,
33 // and lodepng_realloc() can then read it when required. Because the size is
34 // stored at the start of the allocated area, these functions are NOT
35 // interchangeable with the standard EFI functions; memory allocated via
36 // lodepng_malloc() should be freed via lodepng_free(), and myfree() should
37 // NOT be used with memory allocated via AllocatePool() or AllocateZeroPool()!
38
39 void* lodepng_malloc(size_t size) {
40 void *ptr;
41
42 ptr = AllocateZeroPool(size + sizeof(size_t));
43 if (ptr) {
44 *(size_t *) ptr = size;
45 return ((size_t *) ptr) + 1;
46 } else {
47 return NULL;
48 }
49 } // void* lodepng_malloc()
50
51 void lodepng_free (void *ptr) {
52 if (ptr) {
53 ptr = (void *) (((size_t *) ptr) - 1);
54 FreePool(ptr);
55 }
56 } // void lodepng_free()
57
58 static size_t report_size(void *ptr) {
59 if (ptr)
60 return * (((size_t *) ptr) - 1);
61 else
62 return 0;
63 } // size_t report_size()
64
65 void* lodepng_realloc(void *ptr, size_t new_size) {
66 size_t *new_pool;
67 size_t old_size;
68
69 new_pool = lodepng_malloc(new_size);
70 if (new_pool && ptr) {
71 old_size = report_size(ptr);
72 CopyMem(new_pool, ptr, (old_size < new_size) ? old_size : new_size);
73 }
74 return new_pool;
75 } // lodepng_realloc()
76
77 // Finds length of ASCII string, which MUST be NULL-terminated.
78 int MyStrlen(const char *InString) {
79 int Length = 0;
80
81 if (InString) {
82 while (InString[Length] != '\0')
83 Length++;
84 }
85 return Length;
86 } // int MyStrlen()
87
88 typedef struct _lode_color {
89 UINT8 red;
90 UINT8 green;
91 UINT8 blue;
92 UINT8 alpha;
93 } lode_color;
94
95 EG_IMAGE * egDecodePNG(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN IconSize, IN BOOLEAN WantAlpha) {
96 EG_IMAGE *NewImage = NULL;
97 unsigned Error, Width, Height;
98 EG_PIXEL *PixelData;
99 lode_color *LodeData;
100 UINTN i;
101
102 Error = lodepng_decode_memory((unsigned char **) &PixelData, &Width, &Height, (unsigned char*) FileData,
103 (size_t) FileDataLength, LCT_RGBA, 8);
104
105 if (Error) {
106 return NULL;
107 }
108
109 // allocate image structure and buffer
110 NewImage = egCreateImage(Width, Height, WantAlpha);
111 if ((NewImage == NULL) || (NewImage->Width != Width) || (NewImage->Height != Height))
112 return NULL;
113
114 LodeData = (lode_color *) PixelData;
115
116 // Annoyingly, EFI and LodePNG use different ordering of RGB values in
117 // their pixel data representations, so we've got to adjust them....
118 for (i = 0; i < (NewImage->Height * NewImage->Width); i++) {
119 NewImage->PixelData[i].r = LodeData[i].red;
120 NewImage->PixelData[i].g = LodeData[i].green;
121 NewImage->PixelData[i].b = LodeData[i].blue;
122 if (WantAlpha)
123 NewImage->PixelData[i].a = LodeData[i].alpha;
124 }
125 lodepng_free(PixelData);
126
127 return NewImage;
128 } // EG_IMAGE * egDecodePNG()