0 /*
1 * ISC License
2 * Copyright (c) 2023 RMF <rawmonk@firemail.cc>
3 */
4 #if __has_include(<stb_image.h>)
5 #include <stdlib.h>
6 #include <string.h>
7
8 #ifndef NO_SANDBOX
9 #ifdef __linux__
10 #define STATIC_ALLOC
11 #endif
12 #endif
13
14 #ifdef STATIC_ALLOC
15 size_t img_memory_length;
16 char *img_memory;
17 char *img_memory_ptr;
18 int allocations_count = 0;
19 struct allocation {
20 void *ptr;
21 size_t length;
22 unsigned taken:1;
23 };
24 struct allocation allocations[2048] = {0};
25 #define LENGTH(X) (sizeof(X) / sizeof(*X))
26
27 void *img_malloc(size_t size) {
28 void *ptr = img_memory_ptr;
29 int i;
30 for (i = 0; i < allocations_count; i++) {
31 if (allocations[i].taken) continue;
32 if (allocations[i].length > size) {
33 return allocations[i].ptr;
34 }
35 }
36 if (allocations_count >= LENGTH(allocations))
37 return NULL;
38 if (ptr + size > (void*)img_memory + img_memory_length)
39 return NULL;
40 allocations[allocations_count].ptr = ptr;
41 allocations[allocations_count].length = size;
42 allocations[allocations_count].taken = 1;
43 allocations_count++;
44 img_memory_ptr += size;
45 return ptr;
46 }
47
48 void *img_realloc(void *ptr, size_t size) {
49 char *prev, *new;
50 int i;
51 if (!ptr) return img_malloc(size);
52 prev = img_memory;
53 for (i = 0; i < LENGTH(allocations); i++) {
54 if (allocations[i].ptr == ptr) break;
55 }
56 if (allocations[i].length >= size) {
57 allocations[i].length = size;
58 return prev;
59 }
60 new = img_malloc(size);
61 memcpy(new, allocations[i].ptr, allocations[i].length);
62 return new;
63 }
64
65 void img_free(void *ptr) {
66 int i;
67 if (allocations_count < 1) return;
68 if (allocations[allocations_count - 1].ptr == ptr) {
69 int found = 0;
70 allocations_count--;
71 allocations[allocations_count].taken = 0;
72 for (i = allocations_count - 1; i >= 0; i--) {
73 if (allocations[i].taken) {
74 allocations_count = i;
75 img_memory_ptr = allocations[i].ptr;
76 found = 1;
77 break;
78 }
79 }
80 if (!found) img_memory_ptr = img_memory;
81 return;
82 }
83 for (i = allocations_count - 1; i >= 0; i--) {
84 if (allocations[i].ptr == ptr) {
85 allocations[i].taken = 0;
86 break;
87 }
88 }
89 }
90
91 #define STBI_MALLOC img_malloc
92 #define STBI_REALLOC img_realloc
93 #define STBI_FREE img_free
94 #endif
95 #define STB_IMAGE_IMPLEMENTATION
96 #include <stb_image.h>
97
98 void image_memory_set(void *memory, size_t len) {
99 #ifdef STATIC_ALLOC
100 img_memory = memory;
101 img_memory_length = len;
102 #else
103 free(memory);
104 #endif
105 }
106
107 void *image_load(void *data, int len, int *x, int *y) {
108 int comp;
109 #ifdef STATIC_ALLOC
110 img_memory_ptr = img_memory;
111 memset(allocations, 0, sizeof(allocations));
112 allocations_count = 0;
113 #endif
114 return stbi_load_from_memory(data, len, x, y, &comp, 3);
115 }
116 #else
117 typedef int hide_warning;
118 #endif
119