]> code.delx.au - refind/blob - libeg/lodepng_xtra.c
Added OS check to mkrlconf.sh. Bypass checks for BIOS-mode boot
[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.
6 *
7 * See http://lodev.org/lodepng/ for the original LodePNG.
8 *
9 */
10
11 #include "global.h"
12 #include "../refind/screen.h"
13 #include "lodepng.h"
14
15 // EFI's equivalent of realloc requires the original buffer's size as an
16 // input parameter, which the standard libc realloc does not require. Thus,
17 // I've modified lodepng_malloc() to allocate more memory to store this data,
18 // and lodepng_realloc() can then read it when required. Because the size is
19 // stored at the start of the allocated area, these functions are NOT
20 // interchangeable with the standard EFI functions; memory allocated via
21 // lodepng_malloc() should be freed via lodepng_free(), and myfree() should
22 // NOT be used with memory allocated via AllocatePool() or AllocateZeroPool()!
23
24 void* lodepng_malloc(size_t size) {
25 void *ptr;
26
27 ptr = AllocateZeroPool(size + sizeof(size_t));
28 if (ptr) {
29 *(size_t *) ptr = size;
30 return ((size_t *) ptr) + 1;
31 } else {
32 return NULL;
33 }
34 } // void* lodepng_malloc()
35
36 void lodepng_free (void *ptr) {
37 if (ptr) {
38 ptr = (void *) (((size_t *) ptr) - 1);
39 FreePool(ptr);
40 }
41 } // void lodepng_free()
42
43 static size_t report_size(void *ptr) {
44 if (ptr)
45 return * (((size_t *) ptr) - 1);
46 else
47 return 0;
48 } // size_t report_size()
49
50 void* lodepng_realloc(void *ptr, size_t new_size) {
51 size_t *new_pool;
52 size_t old_size;
53
54 new_pool = lodepng_malloc(new_size);
55 if (new_pool && ptr) {
56 old_size = report_size(ptr);
57 CopyMem(new_pool, ptr, (old_size < new_size) ? old_size : new_size);
58 }
59 return new_pool;
60 } // lodepng_realloc()
61
62 // Finds length of ASCII string, which MUST be NULL-terminated.
63 int MyStrlen(const char *InString) {
64 int Length = 0;
65
66 if (InString) {
67 while (InString[Length] != '\0')
68 Length++;
69 }
70 return Length;
71 } // int MyStrlen()
72
73 typedef struct _lode_color {
74 UINT8 red;
75 UINT8 green;
76 UINT8 blue;
77 UINT8 alpha;
78 } lode_color;
79
80 EG_IMAGE * egDecodePNG(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN IconSize, IN BOOLEAN WantAlpha) {
81 EG_IMAGE *NewImage = NULL;
82 unsigned Error, Width, Height;
83 EG_PIXEL *PixelData;
84 lode_color *LodeData;
85 UINTN i;
86
87 Error = lodepng_decode_memory((unsigned char **) &PixelData, &Width, &Height, (unsigned char*) FileData,
88 (size_t) FileDataLength, LCT_RGBA, 8);
89
90 if (Error) {
91 return NULL;
92 }
93
94 // allocate image structure and buffer
95 NewImage = egCreateImage(Width, Height, WantAlpha);
96 if ((NewImage == NULL) || (NewImage->Width != Width) || (NewImage->Height != Height))
97 return NULL;
98
99 LodeData = (lode_color *) PixelData;
100
101 // Annoyingly, EFI and LodePNG use different ordering of RGB values in
102 // their pixel data representations, so we've got to adjust them....
103 for (i = 0; i < (NewImage->Height * NewImage->Width); i++) {
104 NewImage->PixelData[i].r = LodeData[i].red;
105 NewImage->PixelData[i].g = LodeData[i].green;
106 NewImage->PixelData[i].b = LodeData[i].blue;
107 if (WantAlpha)
108 NewImage->PixelData[i].a = LodeData[i].alpha;
109 }
110 lodepng_free(PixelData);
111
112 return NewImage;
113 } // EG_IMAGE * egDecodePNG()