1 /*
2 Copyright (C) 2021 The Blosc Developers <blosc@blosc.org>
3 https://blosc.org
4 License: BSD 3-Clause (see LICENSE.txt)
5
6 Example program demonstrating use of the Blosc filter from C code.
7
8 To compile this program:
9
10 $ gcc urfilters.c -o urfilters -lblosc2
11
12 To run:
13
14 $ ./urfilters
15
16 */
17
18
19 #include "stdio.h"
20 #include <blosc2.h>
21
22 #define KB 1024.
23 #define MB (1024*KB)
24 #define GB (1024*MB)
25
26 #define CHUNKSIZE (1000 * 1000)
27 #define NCHUNKS 100
28 #define NTHREADS 4
29
30
filter_forward(const uint8_t * src,uint8_t * dest,int32_t size,uint8_t meta,blosc2_cparams * cparams)31 int filter_forward(const uint8_t* src, uint8_t* dest, int32_t size, uint8_t meta, blosc2_cparams *cparams) {
32 blosc2_schunk *schunk = cparams->schunk;
33
34 for (int i = 0; i < size / schunk->typesize; ++i) {
35 switch (schunk->typesize) {
36 case 8:
37 ((int64_t *) dest)[i] = ((int64_t *) src)[i] + 1;
38 break;
39 case 4:
40 ((int32_t *) dest)[i] = ((int32_t *) src)[i] + 1;
41 break;
42 case 2:
43 ((int16_t *) dest)[i] = ((int16_t *) src)[i] + 1;
44 break;
45 default:
46 BLOSC_TRACE_ERROR("Item size %d not supported", schunk->typesize);
47 return BLOSC2_ERROR_FAILURE;
48 }
49 }
50 return BLOSC2_ERROR_SUCCESS;
51 }
52
filter_backward(const uint8_t * src,uint8_t * dest,int32_t size,uint8_t meta,blosc2_dparams * dparams)53 int filter_backward(const uint8_t* src, uint8_t* dest, int32_t size, uint8_t meta, blosc2_dparams *dparams) {
54 blosc2_schunk *schunk = dparams->schunk;
55
56 for (int i = 0; i < size / schunk->typesize; ++i) {
57 switch (schunk->typesize) {
58 case 8:
59 ((int64_t *) dest)[i] = ((int64_t *) src)[i] - 1;
60 break;
61 case 4:
62 ((int32_t *) dest)[i] = ((int32_t *) src)[i] - 1;
63 break;
64 case 2:
65 ((int16_t *) dest)[i] = ((int16_t *) src)[i] - 1;
66 break;
67 default:
68 BLOSC_TRACE_ERROR("Item size %d not supported", schunk->typesize);
69 return BLOSC2_ERROR_FAILURE;
70 }
71 }
72 return BLOSC2_ERROR_SUCCESS;
73 }
74
main(void)75 int main(void) {
76 static int32_t data[CHUNKSIZE];
77 static int32_t data_dest[CHUNKSIZE];
78 int32_t isize = CHUNKSIZE * sizeof(int32_t);
79 int dsize;
80 int64_t nbytes, cbytes;
81
82 blosc2_filter urfilter;
83 urfilter.id = 250;
84 urfilter.forward = filter_forward;
85 urfilter.backward = filter_backward;
86
87 blosc2_register_filter(&urfilter);
88
89 blosc2_cparams cparams = BLOSC2_CPARAMS_DEFAULTS;
90 cparams.filters[4] = urfilter.id;
91 cparams.filters_meta[4] = 0;
92
93 blosc2_dparams dparams = BLOSC2_DPARAMS_DEFAULTS;
94
95
96 blosc2_schunk* schunk;
97 int i, nchunk;
98 blosc_timestamp_t last, current;
99 double ttotal;
100
101 printf("Blosc version info: %s (%s)\n", blosc_get_version_string(), BLOSC_VERSION_DATE);
102
103 /* Create a super-chunk container */
104 cparams.typesize = sizeof(int32_t);
105 cparams.clevel = 9;
106 blosc2_storage storage = {.cparams=&cparams, .dparams=&dparams};
107 schunk = blosc2_schunk_new(&storage);
108
109 blosc_set_timestamp(&last);
110 for (nchunk = 0; nchunk < NCHUNKS; nchunk++) {
111 for (i = 0; i < CHUNKSIZE; i++) {
112 data[i] = i * nchunk;
113 }
114 int nchunks = blosc2_schunk_append_buffer(schunk, data, isize);
115 if (nchunks != nchunk + 1) {
116 printf("Unexpected nchunks!");
117 return -1;
118 }
119 }
120 /* Gather some info */
121 nbytes = schunk->nbytes;
122 cbytes = schunk->cbytes;
123 blosc_set_timestamp(¤t);
124 ttotal = blosc_elapsed_secs(last, current);
125 printf("Compression ratio: %.1f MB -> %.1f MB (%.1fx)\n",
126 nbytes / MB, cbytes / MB, (1. * nbytes) / cbytes);
127 printf("Compression time: %.3g s, %.1f MB/s\n",
128 ttotal, nbytes / (ttotal * MB));
129
130 /* Retrieve and decompress the chunks (0-based count) */
131 blosc_set_timestamp(&last);
132 for (nchunk = NCHUNKS-1; nchunk >= 0; nchunk--) {
133 dsize = blosc2_schunk_decompress_chunk(schunk, nchunk, data_dest, isize);
134 if (dsize < 0) {
135 printf("Decompression error. Error code: %d\n", dsize);
136 return dsize;
137 }
138 }
139 blosc_set_timestamp(¤t);
140 ttotal = blosc_elapsed_secs(last, current);
141 printf("Decompression time: %.3g s, %.1f MB/s\n",
142 ttotal, nbytes / (ttotal * MB));
143
144 /* Check integrity of the second chunk (made of non-zeros) */
145 blosc2_schunk_decompress_chunk(schunk, 1, data_dest, isize);
146 for (i = 0; i < CHUNKSIZE; i++) {
147 if (data_dest[i] != i) {
148 printf("Decompressed data differs from original %d, %d!\n",
149 i, data_dest[i]);
150 return -1;
151 }
152 }
153
154 printf("Successful roundtrip data <-> schunk !\n");
155
156 /* Free resources */
157 /* Destroy the super-chunk */
158 blosc2_schunk_free(schunk);
159
160 return 0;
161 }
162