/src/c-blosc2/blosc/blosc-private.h
Line | Count | Source (jump to first uncovered line) |
1 | | /********************************************************************* |
2 | | Blosc - Blocked Shuffling and Compression Library |
3 | | |
4 | | Copyright (c) 2021 Blosc Development Team <blosc@blosc.org> |
5 | | https://blosc.org |
6 | | License: BSD 3-Clause (see LICENSE.txt) |
7 | | |
8 | | See LICENSE.txt for details about copyright and rights to use. |
9 | | **********************************************************************/ |
10 | | |
11 | | |
12 | | #ifndef BLOSC_BLOSC_PRIVATE_H |
13 | | #define BLOSC_BLOSC_PRIVATE_H |
14 | | |
15 | | #include "blosc2/blosc2-common.h" |
16 | | #include "blosc2.h" |
17 | | |
18 | | #include <stdbool.h> |
19 | | #include <stdlib.h> |
20 | | #include <stdint.h> |
21 | | |
22 | | /********************************************************************* |
23 | | |
24 | | Utility functions meant to be used internally. |
25 | | |
26 | | *********************************************************************/ |
27 | | |
28 | 0 | #define to_little(dest, src, itemsize) endian_handler(true, dest, src, itemsize) |
29 | | #define from_little(dest, src, itemsize) endian_handler(true, dest, src, itemsize) |
30 | 0 | #define to_big(dest, src, itemsize) endian_handler(false, dest, src, itemsize) |
31 | 0 | #define from_big(dest, src, itemsize) endian_handler(false, dest, src, itemsize) |
32 | | |
33 | | |
34 | | // Return true if platform is little endian; else false |
35 | 295k | static bool is_little_endian(void) { |
36 | 295k | static const int i = 1; |
37 | 295k | char* p = (char*)&i; |
38 | | |
39 | 295k | if (p[0] == 1) { |
40 | 295k | return true; |
41 | 295k | } |
42 | 0 | else { |
43 | 0 | return false; |
44 | 0 | } |
45 | 295k | } blosc2.c:is_little_endian Line | Count | Source | 35 | 295k | static bool is_little_endian(void) { | 36 | 295k | static const int i = 1; | 37 | 295k | char* p = (char*)&i; | 38 | | | 39 | 295k | if (p[0] == 1) { | 40 | 295k | return true; | 41 | 295k | } | 42 | 0 | else { | 43 | 0 | return false; | 44 | 0 | } | 45 | 295k | } |
Unexecuted instantiation: schunk.c:is_little_endian Unexecuted instantiation: frame.c:is_little_endian Unexecuted instantiation: codecs-registry.c:is_little_endian Unexecuted instantiation: tuners-registry.c:is_little_endian Unexecuted instantiation: filters-registry.c:is_little_endian |
46 | | |
47 | | |
48 | | static inline void endian_handler(bool little, void *dest, const void *pa, int size) |
49 | 0 | { |
50 | 0 | bool little_endian = is_little_endian(); |
51 | 0 | if (little_endian == little) { |
52 | 0 | memcpy(dest, pa, size); |
53 | 0 | } |
54 | 0 | else { |
55 | 0 | uint8_t* pa_ = (uint8_t*)pa; |
56 | 0 | uint8_t pa2_[8]; |
57 | 0 | switch (size) { |
58 | 0 | case 8: |
59 | 0 | pa2_[0] = pa_[7]; |
60 | 0 | pa2_[1] = pa_[6]; |
61 | 0 | pa2_[2] = pa_[5]; |
62 | 0 | pa2_[3] = pa_[4]; |
63 | 0 | pa2_[4] = pa_[3]; |
64 | 0 | pa2_[5] = pa_[2]; |
65 | 0 | pa2_[6] = pa_[1]; |
66 | 0 | pa2_[7] = pa_[0]; |
67 | 0 | break; |
68 | 0 | case 4: |
69 | 0 | pa2_[0] = pa_[3]; |
70 | 0 | pa2_[1] = pa_[2]; |
71 | 0 | pa2_[2] = pa_[1]; |
72 | 0 | pa2_[3] = pa_[0]; |
73 | 0 | break; |
74 | 0 | case 2: |
75 | 0 | pa2_[0] = pa_[1]; |
76 | 0 | pa2_[1] = pa_[0]; |
77 | 0 | break; |
78 | 0 | case 1: |
79 | 0 | pa2_[0] = pa_[0]; |
80 | 0 | break; |
81 | 0 | default: |
82 | 0 | BLOSC_TRACE_ERROR("Unhandled size: %d.", size); |
83 | 0 | } |
84 | 0 | memcpy(dest, pa2_, size); |
85 | 0 | } |
86 | 0 | } Unexecuted instantiation: blosc2.c:endian_handler Unexecuted instantiation: schunk.c:endian_handler Unexecuted instantiation: frame.c:endian_handler Unexecuted instantiation: codecs-registry.c:endian_handler Unexecuted instantiation: tuners-registry.c:endian_handler Unexecuted instantiation: filters-registry.c:endian_handler |
87 | | |
88 | | /* Copy 4 bytes from @p *pa to int32_t, changing endianness if necessary. */ |
89 | 25.3k | static inline int32_t sw32_(const void* pa) { |
90 | 25.3k | int32_t idest; |
91 | | |
92 | 25.3k | bool little_endian = is_little_endian(); |
93 | 25.3k | if (little_endian) { |
94 | 25.3k | memcpy(&idest, pa, sizeof(idest)); |
95 | 25.3k | } |
96 | 0 | else { |
97 | 0 | #if defined (__GNUC__) |
98 | 0 | return __builtin_bswap32(*(unsigned int *)pa); |
99 | | #elif defined (_MSC_VER) /* Visual Studio */ |
100 | | return _byteswap_ulong(*(unsigned int *)pa); |
101 | | #else |
102 | | uint8_t *dest = (uint8_t *)&idest; |
103 | | dest[0] = pa_[3]; |
104 | | dest[1] = pa_[2]; |
105 | | dest[2] = pa_[1]; |
106 | | dest[3] = pa_[0]; |
107 | | #endif |
108 | 0 | } |
109 | 25.3k | return idest; |
110 | 25.3k | } Line | Count | Source | 89 | 25.3k | static inline int32_t sw32_(const void* pa) { | 90 | 25.3k | int32_t idest; | 91 | | | 92 | 25.3k | bool little_endian = is_little_endian(); | 93 | 25.3k | if (little_endian) { | 94 | 25.3k | memcpy(&idest, pa, sizeof(idest)); | 95 | 25.3k | } | 96 | 0 | else { | 97 | 0 | #if defined (__GNUC__) | 98 | 0 | return __builtin_bswap32(*(unsigned int *)pa); | 99 | | #elif defined (_MSC_VER) /* Visual Studio */ | 100 | | return _byteswap_ulong(*(unsigned int *)pa); | 101 | | #else | 102 | | uint8_t *dest = (uint8_t *)&idest; | 103 | | dest[0] = pa_[3]; | 104 | | dest[1] = pa_[2]; | 105 | | dest[2] = pa_[1]; | 106 | | dest[3] = pa_[0]; | 107 | | #endif | 108 | 0 | } | 109 | 25.3k | return idest; | 110 | 25.3k | } |
Unexecuted instantiation: schunk.c:sw32_ Unexecuted instantiation: frame.c:sw32_ Unexecuted instantiation: codecs-registry.c:sw32_ Unexecuted instantiation: tuners-registry.c:sw32_ Unexecuted instantiation: filters-registry.c:sw32_ |
111 | | |
112 | | /* Copy 4 bytes from int32_t to @p *dest, changing endianness if necessary. */ |
113 | 125k | static inline void _sw32(void* dest, int32_t a) { |
114 | 125k | uint8_t* dest_ = (uint8_t*)dest; |
115 | 125k | uint8_t* pa = (uint8_t*)&a; |
116 | | |
117 | 125k | bool little_endian = is_little_endian(); |
118 | 125k | if (little_endian) { |
119 | 125k | memcpy(dest_, &a, sizeof(a));; |
120 | 125k | } |
121 | 0 | else { |
122 | 0 | #if defined (__GNUC__) |
123 | 0 | *(int32_t *)dest_ = __builtin_bswap32(*(unsigned int *)pa); |
124 | | #elif defined (_MSC_VER) /* Visual Studio */ |
125 | | *(int32_t *)dest_ = _byteswap_ulong(*(unsigned int *)pa); |
126 | | #else |
127 | | dest_[0] = pa[3]; |
128 | | dest_[1] = pa[2]; |
129 | | dest_[2] = pa[1]; |
130 | | dest_[3] = pa[0]; |
131 | | #endif |
132 | 0 | } |
133 | 125k | } Line | Count | Source | 113 | 125k | static inline void _sw32(void* dest, int32_t a) { | 114 | 125k | uint8_t* dest_ = (uint8_t*)dest; | 115 | 125k | uint8_t* pa = (uint8_t*)&a; | 116 | | | 117 | 125k | bool little_endian = is_little_endian(); | 118 | 125k | if (little_endian) { | 119 | 125k | memcpy(dest_, &a, sizeof(a));; | 120 | 125k | } | 121 | 0 | else { | 122 | 0 | #if defined (__GNUC__) | 123 | 0 | *(int32_t *)dest_ = __builtin_bswap32(*(unsigned int *)pa); | 124 | | #elif defined (_MSC_VER) /* Visual Studio */ | 125 | | *(int32_t *)dest_ = _byteswap_ulong(*(unsigned int *)pa); | 126 | | #else | 127 | | dest_[0] = pa[3]; | 128 | | dest_[1] = pa[2]; | 129 | | dest_[2] = pa[1]; | 130 | | dest_[3] = pa[0]; | 131 | | #endif | 132 | 0 | } | 133 | 125k | } |
Unexecuted instantiation: schunk.c:_sw32 Unexecuted instantiation: frame.c:_sw32 Unexecuted instantiation: codecs-registry.c:_sw32 Unexecuted instantiation: tuners-registry.c:_sw32 Unexecuted instantiation: filters-registry.c:_sw32 |
134 | | |
135 | | /* Reverse swap bits in a 32-bit integer */ |
136 | 0 | static inline int32_t bswap32_(int32_t a) { |
137 | 0 | #if defined (__GNUC__) |
138 | 0 | return __builtin_bswap32(a); |
139 | |
|
140 | | #elif defined (_MSC_VER) /* Visual Studio */ |
141 | | return _byteswap_ulong(a); |
142 | | #else |
143 | | a = ((a & 0x000000FF) << 24) | |
144 | | ((a & 0x0000FF00) << 8) | |
145 | | ((a & 0x00FF0000) >> 8) | |
146 | | ((a & 0xFF000000) >> 24); |
147 | | return a; |
148 | | #endif |
149 | 0 | } Unexecuted instantiation: blosc2.c:bswap32_ Unexecuted instantiation: schunk.c:bswap32_ Unexecuted instantiation: frame.c:bswap32_ Unexecuted instantiation: codecs-registry.c:bswap32_ Unexecuted instantiation: tuners-registry.c:bswap32_ Unexecuted instantiation: filters-registry.c:bswap32_ |
150 | | |
151 | | /** |
152 | | * @brief Register a filter in Blosc. |
153 | | * |
154 | | * @param filter The filter to register. |
155 | | * |
156 | | * @return 0 if succeeds. Else a negative code is returned. |
157 | | */ |
158 | | int register_filter_private(blosc2_filter *filter); |
159 | | |
160 | | /** |
161 | | * @brief Register a codec in Blosc. |
162 | | * |
163 | | * @param codec The codec to register. |
164 | | * |
165 | | * @return 0 if succeeds. Else a negative code is returned. |
166 | | */ |
167 | | int register_codec_private(blosc2_codec *codec); |
168 | | |
169 | | |
170 | | /** |
171 | | * @brief Register a tune in Blosc. |
172 | | * |
173 | | * @param tune The tune to register. |
174 | | * |
175 | | * @return 0 if succeeds. Else a negative code is returned. |
176 | | */ |
177 | | int register_tuner_private(blosc2_tuner *tuner); |
178 | | |
179 | | int fill_tuner(blosc2_tuner *tuner); |
180 | | |
181 | | extern blosc2_tuner g_tuners[256]; |
182 | | extern int g_ntuners; |
183 | | |
184 | | |
185 | | #if defined(_WIN32) |
186 | | #include <windows.h> |
187 | | #ifndef PATH_MAX |
188 | | #define PATH_MAX MAX_PATH |
189 | | #endif |
190 | | #define RTLD_LAZY 0x000 |
191 | | #define popen _popen |
192 | | #define pclose _pclose |
193 | | |
194 | | static struct { |
195 | | long lasterror; |
196 | | const char *err_rutin; |
197 | | } |
198 | | var = { |
199 | | 0, |
200 | | NULL |
201 | | }; |
202 | | |
203 | | static inline void *dlopen (const char *filename, int flags) { |
204 | | BLOSC_UNUSED_PARAM(flags); |
205 | | HINSTANCE hInst; |
206 | | hInst = LoadLibrary(filename); |
207 | | if (hInst==NULL) { |
208 | | var.lasterror = GetLastError(); |
209 | | var.err_rutin = "dlopen"; |
210 | | } |
211 | | |
212 | | return hInst; |
213 | | } |
214 | | |
215 | | static inline void *dlsym(void *handle, const char *name) { |
216 | | FARPROC fp; |
217 | | fp = GetProcAddress((HINSTANCE)handle, name); |
218 | | if (!fp) { |
219 | | var.lasterror = GetLastError (); |
220 | | var.err_rutin = "dlsym"; |
221 | | } |
222 | | return (void *)(intptr_t)fp; |
223 | | } |
224 | | |
225 | | static inline int dlclose(void *handle) { |
226 | | bool ok = FreeLibrary((HINSTANCE)handle); |
227 | | if (!ok) { |
228 | | var.lasterror = GetLastError(); |
229 | | var.err_rutin = "dlclose"; |
230 | | return BLOSC2_ERROR_FAILURE; |
231 | | } |
232 | | return BLOSC2_ERROR_SUCCESS; |
233 | | } |
234 | | |
235 | | static inline const char *dlerror (void) { |
236 | | static char errstr [88]; |
237 | | if (var.lasterror) { |
238 | | sprintf (errstr, "%s error #%ld", var.err_rutin, var.lasterror); |
239 | | return errstr; |
240 | | } else { |
241 | | return NULL; |
242 | | } |
243 | | } |
244 | | #else |
245 | | #include <dlfcn.h> |
246 | | #endif |
247 | | |
248 | | |
249 | 0 | static inline int get_libpath(char *plugin_name, char *libpath, char *python_version) { |
250 | 0 | BLOSC_TRACE_INFO("Trying to get plugin path with python%s\n", python_version); |
251 | 0 | char python_cmd[PATH_MAX] = {0}; |
252 | 0 | sprintf(python_cmd, "python%s -c \"import blosc2_%s; blosc2_%s.print_libpath()\"", python_version, plugin_name, plugin_name); |
253 | 0 | FILE *fp = popen(python_cmd, "r"); |
254 | 0 | if (fp == NULL) { |
255 | 0 | BLOSC_TRACE_ERROR("Could not run python"); |
256 | 0 | return BLOSC2_ERROR_FAILURE; |
257 | 0 | } |
258 | 0 | if (fgets(libpath, PATH_MAX, fp) == NULL) { |
259 | 0 | BLOSC_TRACE_ERROR("Could not read python output"); |
260 | 0 | pclose(fp); |
261 | 0 | return BLOSC2_ERROR_FAILURE; |
262 | 0 | } |
263 | 0 | pclose(fp); |
264 | |
|
265 | 0 | return BLOSC2_ERROR_SUCCESS; |
266 | 0 | } Unexecuted instantiation: blosc2.c:get_libpath Unexecuted instantiation: schunk.c:get_libpath Unexecuted instantiation: frame.c:get_libpath Unexecuted instantiation: codecs-registry.c:get_libpath Unexecuted instantiation: tuners-registry.c:get_libpath Unexecuted instantiation: filters-registry.c:get_libpath |
267 | | |
268 | 0 | static inline void* load_lib(char *plugin_name, char *libpath) { |
269 | | // Attempt to directly load the library by name |
270 | | #if defined(_WIN32) |
271 | | // Windows dynamic library (DLL) format |
272 | | snprintf(libpath, PATH_MAX, "blosc2_%s.dll", plugin_name); |
273 | | #else |
274 | | // Unix/Linux/Mac OS dynamic library (.so) format |
275 | 0 | snprintf(libpath, PATH_MAX, "libblosc2_%s.so", plugin_name); |
276 | 0 | #endif |
277 | 0 | void* loaded_lib = dlopen(libpath, RTLD_LAZY); |
278 | 0 | if (loaded_lib != NULL) { |
279 | 0 | BLOSC_TRACE_INFO("Successfully loaded %s directly\n", libpath); |
280 | 0 | return loaded_lib; |
281 | 0 | } else { |
282 | | #if defined(_WIN32) |
283 | | BLOSC_TRACE_INFO("Failed to load %s directly, error: %lu\n", libpath, GetLastError()); |
284 | | #else |
285 | 0 | BLOSC_TRACE_INFO("Failed to load %s directly, error: %s\n", libpath, dlerror()); |
286 | 0 | #endif |
287 | 0 | } |
288 | | // If direct loading fails, fallback to using Python to find the library path |
289 | 0 | if (get_libpath(plugin_name, libpath, "") < 0 && get_libpath(plugin_name, libpath, "3") < 0) { |
290 | 0 | BLOSC_TRACE_ERROR("Problems when running python or python3 for getting plugin path"); |
291 | 0 | return NULL; |
292 | 0 | } |
293 | | |
294 | 0 | if (strlen(libpath) == 0) { |
295 | 0 | BLOSC_TRACE_ERROR("Could not find plugin libpath"); |
296 | 0 | return NULL; |
297 | 0 | } |
298 | | |
299 | | // Try to load the library again with the path from Python |
300 | 0 | loaded_lib = dlopen(libpath, RTLD_LAZY); |
301 | 0 | if (loaded_lib == NULL) { |
302 | 0 | BLOSC_TRACE_ERROR("Attempt to load plugin in path '%s' failed with error: %s", libpath, dlerror()); |
303 | 0 | } else { |
304 | 0 | BLOSC_TRACE_INFO("Successfully loaded library with Python path: %s\n", libpath); |
305 | 0 | } |
306 | | |
307 | 0 | return loaded_lib; |
308 | 0 | } Unexecuted instantiation: blosc2.c:load_lib Unexecuted instantiation: schunk.c:load_lib Unexecuted instantiation: frame.c:load_lib Unexecuted instantiation: codecs-registry.c:load_lib Unexecuted instantiation: tuners-registry.c:load_lib Unexecuted instantiation: filters-registry.c:load_lib |
309 | | |
310 | | |
311 | | #endif /* BLOSC_BLOSC_PRIVATE_H */ |