2
2
from __future__ import absolute_import, print_function, division
3
3
4
4
5
+ import sys
6
+ import ctypes
7
+ # noinspection PyUnresolvedReferences
5
8
import numpy as np
6
9
cimport numpy as np
10
+ # noinspection PyUnresolvedReferences
11
+ from libc.stdint cimport uintptr_t
12
+ # noinspection PyUnresolvedReferences
13
+ from .definitions cimport malloc, realloc, free, PyBytes_AsString
7
14
8
15
9
- def decompress (bytes cdata , np.ndarray array ):
16
+ PY2 = sys.version_info[0 ] == 2
17
+
18
+
19
+ cdef extern from " blosc.h" :
20
+ cdef enum :
21
+ BLOSC_MAX_OVERHEAD,
22
+ BLOSC_VERSION_STRING,
23
+ BLOSC_VERSION_DATE
24
+
25
+ void blosc_init()
26
+ void blosc_destroy()
27
+ int blosc_set_nthreads(int nthreads)
28
+ int blosc_set_compressor(const char * compname)
29
+ int blosc_compress(int clevel, int doshuffle, size_t typesize,
30
+ size_t nbytes, void * src, void * dest,
31
+ size_t destsize) nogil
32
+ int blosc_decompress(void * src, void * dest, size_t destsize) nogil
33
+ int blosc_compname_to_compcode(const char * compname)
34
+ int blosc_compress_ctx(int clevel, int doshuffle, size_t typesize,
35
+ size_t nbytes, const void * src, void * dest,
36
+ size_t destsize, const char * compressor,
37
+ size_t blocksize, int numinternalthreads) nogil
38
+ int blosc_decompress_ctx(const void * src, void * dest, size_t destsize,
39
+ int numinternalthreads) nogil
40
+ void blosc_cbuffer_sizes(void * cbuffer, size_t * nbytes,
41
+ size_t * cbytes, size_t * blocksize)
42
+
43
+
44
+ def version ():
45
+ """ Return the version of blosc that zarr was compiled with."""
46
+
47
+ ver_str = < char * > BLOSC_VERSION_STRING
48
+ ver_date = < char * > BLOSC_VERSION_DATE
49
+ if not PY2:
50
+ ver_str = ver_str.decode()
51
+ ver_date = ver_date.decode()
52
+ return ver_str, ver_date
53
+
54
+
55
+ def init ():
56
+ blosc_init()
57
+
58
+
59
+ def destroy ():
60
+ blosc_destroy()
61
+
62
+
63
+ def compname_to_compcode (cname ):
64
+ if not isinstance (cname, bytes):
65
+ cname = cname.encode(' ascii' )
66
+ ccode = blosc_compname_to_compcode(cname)
67
+ if ccode < 0 :
68
+ raise ValueError (' compressor not available: %r ' % cname)
69
+ return ccode
70
+
71
+
72
+ def decompress (bytes cdata , np.ndarray array , use_context ):
10
73
""" Decompress data into a numpy array.
11
74
12
75
Parameters
@@ -15,18 +78,42 @@ def decompress(bytes cdata, np.ndarray array):
15
78
Compressed data, including blosc header.
16
79
array : ndarray
17
80
Numpy array to decompress into.
81
+ use_context : bool
82
+ If True, use blosc contextual mode. Otherwise use global locking mode.
18
83
19
84
Notes
20
85
-----
21
86
Assumes that the size of the destination array is correct for the size of
22
87
the uncompressed data.
23
88
24
89
"""
25
- # TODO
26
- pass
27
90
91
+ cdef:
92
+ int ret
93
+ char * source
94
+ char * dest
95
+ size_t nbytes
28
96
29
- def compress (np.ndarray array , bytes cname , int clevel , int shuffle ):
97
+ # setup
98
+ source = PyBytes_AsString(cdata)
99
+ dest = array.data
100
+ nbytes = array.nbytes
101
+
102
+ # perform decompression
103
+ if use_context:
104
+ with nogil:
105
+ ret = blosc_decompress_ctx(source, dest, nbytes, 1 )
106
+
107
+ else :
108
+ ret = blosc_decompress(source, dest, nbytes)
109
+
110
+ # handle errors
111
+ if ret <= 0 :
112
+ raise RuntimeError (' error during blosc decompression: %d ' % ret)
113
+
114
+
115
+ def compress (np.ndarray array , char* cname , int clevel , int shuffle ,
116
+ use_context ):
30
117
""" Compress data in a numpy array.
31
118
32
119
Parameters
@@ -39,12 +126,54 @@ def compress(np.ndarray array, bytes cname, int clevel, int shuffle):
39
126
Compression level.
40
127
shuffle : int
41
128
Shuffle filter.
129
+ use_context : bool
130
+ If True, use blosc contextual mode. Otherwise use global locking mode.
42
131
43
132
Returns
44
133
-------
45
134
cdata : bytes
46
135
Compressed data.
47
136
48
137
"""
49
- # TODO
50
- pass
138
+
139
+ cdef:
140
+ char * source
141
+ char * dest
142
+ char * cdata
143
+ size_t nbytes, cbytes, itemsize
144
+ bytes cdata_bytes
145
+
146
+ # obtain reference to underlying buffer
147
+ source = array.data
148
+
149
+ # allocate memory for compressed data
150
+ nbytes = array.nbytes
151
+ itemsize = array.dtype.itemsize
152
+ dest = < char * > malloc(nbytes + BLOSC_MAX_OVERHEAD)
153
+
154
+ # perform compression
155
+ if use_context:
156
+ with nogil:
157
+ cbytes = blosc_compress_ctx(clevel, shuffle, itemsize, nbytes,
158
+ source, dest,
159
+ nbytes + BLOSC_MAX_OVERHEAD, cname,
160
+ 0 , 1 )
161
+
162
+ else :
163
+ compressor_set = blosc_set_compressor(cname)
164
+ if compressor_set < 0 :
165
+ raise ValueError (' compressor not supported: %r ' % cname)
166
+ cbytes = blosc_compress(clevel, shuffle, itemsize, nbytes, source,
167
+ dest, nbytes + BLOSC_MAX_OVERHEAD)
168
+
169
+ # check compression was successful
170
+ if cbytes <= 0 :
171
+ raise RuntimeError (' error during blosc compression: %d ' % cbytes)
172
+
173
+ # free the unused memory
174
+ cdata = < char * > realloc(dest, cbytes)
175
+
176
+ # store as bytes
177
+ cdata_bytes = ctypes.string_at(< uintptr_t> cdata, cbytes)
178
+
179
+ return cdata_bytes
0 commit comments