-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathblosc.scm
207 lines (160 loc) · 5.46 KB
/
blosc.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#|
Chicken Scheme bindings for the Blosc compression library.
Written for Chicken Scheme by Ivan Raikov.
|#
(module blosc
(
initialize!
compress
compress!
decompress
decompress!
sizes
set-nthreads!
set-compressor!
free-resources!
version-format
max-threads
max-overhead
)
(import scheme (except (chicken base) compress) (chicken foreign) (chicken format)
(chicken blob) srfi-4)
#>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <blosc.h>
#define C_bytevector_length(x) (C_header_size(x))
<#
(define version-format (foreign-value "BLOSC_VERSION_FORMAT" int))
(define max-overhead (foreign-value "BLOSC_MAX_OVERHEAD" int))
(define do-shuffle (foreign-value "BLOSC_DOSHUFFLE" int))
(define mem-cpyed (foreign-value "BLOSC_MEMCPYED" int))
(define max-threads (foreign-value "BLOSC_MAX_THREADS" int))
(define max-typesize 255)
(define max-buffersize 4294967295)
;; Initializes the BLOSC compressor
(define (initialize!)
((foreign-lambda* void ()
#<<END
blosc_init();
END
)))
(define blosc-compress
(foreign-safe-lambda* int ((int level) (int shuffle) (unsigned-int itemsize)
(scheme-object dest) (scheme-object src))
#<<END
int result=0; size_t srcsize=0, destsize=0;
void *srcdata=NULL, *destdata=NULL;
C_i_check_bytevector (src);
C_i_check_bytevector (dest);
srcsize = C_bytevector_length(src);
srcdata = C_c_bytevector (src);
destsize = C_bytevector_length(dest);
destdata = C_c_bytevector (dest);
result = blosc_compress(level, shuffle, itemsize, srcsize, srcdata, destdata, destsize);
if (result < 0)
{
printf("Blosc compression error. Error code: %d\n", result);
}
assert(result >= 0);
C_return (result);
END
))
(define (compress! dest src #!key (level 5) (shuffle #t) (itemsize 1))
(if (< itemsize 0)
(error 'compress! "item size must be positive"))
(if (or (< level 0) (> level 9))
(error 'compress! "level must be between 0 and 9, inclusive"))
(blosc-compress level (if shuffle 1 0) itemsize dest src))
(define (compress src #!key (level 5) (shuffle #t) (itemsize 1))
(assert (< 0 (blob-size src)))
(let* ((dest (make-blob (+ (blob-size src) max-overhead)))
(sz (compress! dest src level: level shuffle: shuffle itemsize: itemsize)))
(u8vector->blob/shared (subu8vector (blob->u8vector/shared dest) 0 sz))))
;; Given a compressed buffer, return the (uncompressed, compressed, block) size
(define cbuffer-sizes
(foreign-safe-lambda* void ((scheme-object buffer) (u32vector sizes))
#<<END
size_t nbytes=0, cbytes=0, blocksize=0;
void *cbuffer = NULL;
C_i_check_bytevector (buffer);
cbuffer = C_c_bytevector (buffer);
blosc_cbuffer_sizes(cbuffer, &nbytes, &cbytes, &blocksize);
sizes[0] = nbytes;
sizes[1] = cbytes;
sizes[2] = blocksize;
END
))
;; Given a compressed buffer `buf`, return a tuple
;; of the `(uncompressed, compressed, block)` sizes in bytes.
(define (sizes buf)
(let ((res (make-u32vector 3 0)))
(cbuffer-sizes buf res)
(u32vector->list res)
))
(define blosc-decompress
(foreign-safe-lambda* int ((scheme-object dest) (scheme-object src))
#<<END
int result=0; size_t destsize=0;
void *srcdata=NULL, *destdata=NULL;
C_i_check_bytevector (src);
C_i_check_bytevector (dest);
srcdata = C_c_bytevector (src);
destdata = C_c_bytevector (dest);
destsize = C_bytevector_length(dest);
result = blosc_decompress(srcdata, destdata, destsize);
if (result < 0)
{
printf("Blosc decompression error. Error code: %d\n", result);
}
assert(result >= 0);
C_return (result);
END
))
(define (decompress! dest src)
(let* ((uncompressed-sz (car (sizes src)))
(len (blob-size dest)))
(if (not (<= uncompressed-sz len))
(error 'decompress! "destination buffer is too small"))
(blosc-decompress dest src)
dest))
(define (decompress src)
(let* ((uncompressed-sz (car (sizes src))))
(decompress! (make-blob uncompressed-sz) src)))
;; Initialize a pool of threads for compression / decompression.
;; If `nthreads` is 1, the the serial version is chosen and a possible previous existing pool is ended.
;; If this function is not callled, `nthreads` is set to 1 internally.
(define (set-nthreads! n)
((foreign-lambda* void ((int n))
#<<END
blosc_set_nthreads(n);
END
) n))
;; Set the current compression algorithm to `s`. The currently supported
;; algorithms in the default Blosc module build are `"blosclz"`, `"lz4"`,
;; and `"l4hc"`. Throws an error if `s` is not the name
;; of a supported algorithm. Returns a nonnegative integer code used
;; internally by Blosc to identify the compressor.
(define (set-compressor! s)
(case s (("blosclz" "lz4" "l4hc")
((foreign-lambda* void ((c-string s))
#<<END
blosc_set_compressor(s);
END
) s))
(else (error 'set-compressor! "unrecognized compression algorithm" s))
))
;; Free possible memory temporaries and thread resources.
;; Use this when you are not going to use Blosc for a long while.
;; In case of problems releasing resources, it returns `false`,
;; whereas it returns `true` on success.
(define (free-resources!)
((foreign-lambda* int ()
#<<END
int result = blosc_free_resources();
C_return(result);
END
)))
)