Coverage Report

Created: 2023-12-08 06:32

/src/c-blosc2/plugins/codecs/zfp/blosc2-zfp.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
  Copyright (c) 2021  The Blosc Development Team <blosc@blosc.org>
3
  https://blosc.org
4
  License: BSD 3-Clause (see LICENSE.txt)
5
*/
6
7
#include "blosc-private.h"
8
#include "zfp.h"
9
#include "blosc2-zfp.h"
10
#include "../plugins/codecs/zfp/zfp-private.h"
11
#include "../plugins/plugin_utils.h"
12
#include "context.h"
13
#include "frame.h"
14
#include "blosc2/codecs-registry.h"
15
#include "blosc2.h"
16
17
#include <assert.h>
18
#include <math.h>
19
#include <stdlib.h>
20
#include <string.h>
21
22
23
int zfp_acc_compress(const uint8_t *input, int32_t input_len, uint8_t *output,
24
0
                     int32_t output_len, uint8_t meta, blosc2_cparams *cparams, const void *chunk) {
25
0
  BLOSC_UNUSED_PARAM(chunk);
26
0
  ZFP_ERROR_NULL(input);
27
0
  ZFP_ERROR_NULL(output);
28
0
  ZFP_ERROR_NULL(cparams);
29
0
  ZFP_ERROR_NULL(cparams->schunk);
30
31
0
  double tol = (int8_t) meta;
32
0
  int8_t ndim;
33
0
  int64_t *shape = malloc(8 * sizeof(int64_t));
34
0
  int32_t *chunkshape = malloc(8 * sizeof(int32_t));
35
0
  int32_t *blockshape = malloc(8 * sizeof(int32_t));
36
0
  uint8_t *smeta;
37
0
  int32_t smeta_len;
38
0
  if (blosc2_meta_get(cparams->schunk, "b2nd", &smeta, &smeta_len) < 0) {
39
0
    free(shape);
40
0
    free(chunkshape);
41
0
    free(blockshape);
42
0
    BLOSC_TRACE_ERROR("b2nd layer not found!");
43
0
    return BLOSC2_ERROR_FAILURE;
44
0
  }
45
0
  deserialize_meta(smeta, smeta_len, &ndim, shape, chunkshape, blockshape);
46
0
  free(smeta);
47
48
0
  for(int i = 0; i < ndim; i++) {
49
0
    if (blockshape[i] < 4) {
50
0
      BLOSC_TRACE_ERROR("ZFP does not support blocks smaller than cells (4x...x4");
51
0
      return BLOSC2_ERROR_FAILURE;
52
0
    }
53
0
  }
54
55
0
  zfp_type type;     /* array scalar type */
56
0
  zfp_field *field;  /* array meta data */
57
0
  zfp_stream *zfp;   /* stream containing the real output buffer */
58
0
  zfp_stream *zfp_aux;   /* auxiliary compressed stream */
59
0
  bitstream *stream; /* bit stream to write to or read from */
60
0
  bitstream *stream_aux; /* auxiliary bit stream to write to or read from */
61
0
  size_t zfpsize;    /* byte size of compressed stream */
62
0
  double tolerance = pow(10, tol);
63
64
0
  int32_t typesize = cparams->typesize;
65
66
0
  switch (typesize) {
67
0
    case sizeof(float):
68
0
      type = zfp_type_float;
69
0
      break;
70
0
    case sizeof(double):
71
0
      type = zfp_type_double;
72
0
      break;
73
0
    default:
74
0
      free(shape);
75
0
      free(chunkshape);
76
0
      free(blockshape);
77
0
      BLOSC_TRACE_ERROR("ZFP is not available for typesize: %d", typesize);
78
0
      return BLOSC2_ERROR_FAILURE;
79
0
  }
80
81
0
  zfp = zfp_stream_open(NULL);
82
0
  zfp_stream_set_accuracy(zfp, tolerance);
83
0
  stream = stream_open(output, output_len);
84
0
  zfp_stream_set_bit_stream(zfp, stream);
85
0
  zfp_stream_rewind(zfp);
86
87
0
  switch (ndim) {
88
0
    case 1:
89
0
      field = zfp_field_1d((void *) input, type, blockshape[0]);
90
0
      break;
91
0
    case 2:
92
0
      field = zfp_field_2d((void *) input, type, blockshape[1], blockshape[0]);
93
0
      break;
94
0
    case 3:
95
0
      field = zfp_field_3d((void *) input, type, blockshape[2], blockshape[1], blockshape[0]);
96
0
      break;
97
0
    case 4:
98
0
      field = zfp_field_4d((void *) input, type, blockshape[3], blockshape[2], blockshape[1], blockshape[0]);
99
0
      break;
100
0
    default:
101
0
      free(shape);
102
0
      free(chunkshape);
103
0
      free(blockshape);
104
0
      BLOSC_TRACE_ERROR("ZFP is not available for ndims: %d", ndim);
105
0
      return BLOSC2_ERROR_FAILURE;
106
0
  }
107
108
0
  int zfp_maxout = (int) zfp_stream_maximum_size(zfp, field);
109
0
  zfp_stream_close(zfp);
110
0
  stream_close(stream);
111
0
  uint8_t *aux_out = malloc(zfp_maxout);
112
0
  zfp_aux = zfp_stream_open(NULL);
113
0
  zfp_stream_set_accuracy(zfp_aux, tolerance);
114
0
  stream_aux = stream_open(aux_out, zfp_maxout);
115
0
  zfp_stream_set_bit_stream(zfp_aux, stream_aux);
116
0
  zfp_stream_rewind(zfp_aux);
117
118
0
  zfpsize = zfp_compress(zfp_aux, field);
119
120
  /* clean up */
121
0
  zfp_field_free(field);
122
0
  zfp_stream_close(zfp_aux);
123
0
  stream_close(stream_aux);
124
0
  free(shape);
125
0
  free(chunkshape);
126
0
  free(blockshape);
127
128
0
  if (zfpsize == 0) {
129
0
    BLOSC_TRACE_ERROR("\n ZFP: Compression failed\n");
130
0
    free(aux_out);
131
0
    return (int) zfpsize;
132
0
  }
133
0
  if ((int32_t) zfpsize >= input_len) {
134
0
    BLOSC_TRACE_ERROR("\n ZFP: Compressed data is bigger than input! \n");
135
0
    free(aux_out);
136
0
    return 0;
137
0
  }
138
139
0
  memcpy(output, aux_out, zfpsize);
140
0
  free(aux_out);
141
142
0
  return (int) zfpsize;
143
0
}
144
145
int zfp_acc_decompress(const uint8_t *input, int32_t input_len, uint8_t *output,
146
1
                       int32_t output_len, uint8_t meta, blosc2_dparams *dparams, const void *chunk) {
147
1
  ZFP_ERROR_NULL(input);
148
1
  ZFP_ERROR_NULL(output);
149
1
  ZFP_ERROR_NULL(dparams);
150
1
  ZFP_ERROR_NULL(dparams->schunk);
151
0
  BLOSC_UNUSED_PARAM(chunk);
152
153
0
  blosc2_schunk *sc = dparams->schunk;
154
0
  int32_t typesize = sc->typesize;
155
156
0
  double tol = (int8_t) meta;
157
0
  int8_t ndim;
158
0
  int64_t *shape = malloc(8 * sizeof(int64_t));
159
0
  int32_t *chunkshape = malloc(8 * sizeof(int32_t));
160
0
  int32_t *blockshape = malloc(8 * sizeof(int32_t));
161
0
  uint8_t *smeta;
162
0
  int32_t smeta_len;
163
0
  if (blosc2_meta_get(sc, "b2nd", &smeta, &smeta_len) < 0) {
164
0
    BLOSC_TRACE_ERROR("Cannot access b2nd meta info");
165
0
    free(shape);
166
0
    free(chunkshape);
167
0
    free(blockshape);
168
0
    return BLOSC2_ERROR_FAILURE;
169
0
  }
170
0
  deserialize_meta(smeta, smeta_len, &ndim, shape, chunkshape, blockshape);
171
0
  free(smeta);
172
173
0
  zfp_type type;     /* array scalar type */
174
0
  zfp_field *field;  /* array meta data */
175
0
  zfp_stream *zfp;   /* compressed stream */
176
0
  bitstream *stream; /* bit stream to write to or read from */
177
0
  size_t zfpsize;    /* byte size of compressed stream */
178
0
  double tolerance = pow(10, tol);
179
180
0
  switch (typesize) {
181
0
    case sizeof(float):
182
0
      type = zfp_type_float;
183
0
      break;
184
0
    case sizeof(double):
185
0
      type = zfp_type_double;
186
0
      break;
187
0
    default:
188
0
      free(shape);
189
0
      free(chunkshape);
190
0
      free(blockshape);
191
0
      BLOSC_TRACE_ERROR("ZFP is not available for typesize: %d", typesize);
192
0
      return BLOSC2_ERROR_FAILURE;
193
0
  }
194
195
0
  zfp = zfp_stream_open(NULL);
196
0
  zfp_stream_set_accuracy(zfp, tolerance);
197
0
  stream = stream_open((void *) input, input_len);
198
0
  zfp_stream_set_bit_stream(zfp, stream);
199
0
  zfp_stream_rewind(zfp);
200
201
0
  switch (ndim) {
202
0
    case 1:
203
0
      field = zfp_field_1d((void *) output, type, blockshape[0]);
204
0
      break;
205
0
    case 2:
206
0
      field = zfp_field_2d((void *) output, type, blockshape[1], blockshape[0]);
207
0
      break;
208
0
    case 3:
209
0
      field = zfp_field_3d((void *) output, type, blockshape[2], blockshape[1], blockshape[0]);
210
0
      break;
211
0
    case 4:
212
0
      field = zfp_field_4d((void *) output, type, blockshape[3], blockshape[2], blockshape[1], blockshape[0]);
213
0
      break;
214
0
    default:
215
0
      free(shape);
216
0
      free(chunkshape);
217
0
      free(blockshape);
218
0
      BLOSC_TRACE_ERROR("ZFP is not available for ndims: %d", ndim);
219
0
      return BLOSC2_ERROR_FAILURE;
220
0
  }
221
222
0
  zfpsize = zfp_decompress(zfp, field);
223
224
  /* clean up */
225
0
  zfp_field_free(field);
226
0
  zfp_stream_close(zfp);
227
0
  stream_close(stream);
228
0
  free(shape);
229
0
  free(chunkshape);
230
0
  free(blockshape);
231
232
0
  if (zfpsize == 0) {
233
0
    BLOSC_TRACE_ERROR("\n ZFP: Decompression failed\n");
234
0
    return (int) zfpsize;
235
0
  }
236
237
0
  return (int) output_len;
238
0
}
239
240
int zfp_prec_compress(const uint8_t *input, int32_t input_len, uint8_t *output,
241
0
                      int32_t output_len, uint8_t meta, blosc2_cparams *cparams, const void *chunk) {
242
0
  BLOSC_UNUSED_PARAM(chunk);
243
0
  ZFP_ERROR_NULL(input);
244
0
  ZFP_ERROR_NULL(output);
245
0
  ZFP_ERROR_NULL(cparams);
246
0
  ZFP_ERROR_NULL(cparams->schunk);
247
248
0
  int8_t ndim;
249
0
  int64_t *shape = malloc(8 * sizeof(int64_t));
250
0
  int32_t *chunkshape = malloc(8 * sizeof(int32_t));
251
0
  int32_t *blockshape = malloc(8 * sizeof(int32_t));
252
0
  uint8_t *smeta;
253
0
  int32_t smeta_len;
254
0
  if (blosc2_meta_get(cparams->schunk, "b2nd", &smeta, &smeta_len) < 0) {
255
0
    free(shape);
256
0
    free(chunkshape);
257
0
    free(blockshape);
258
0
    BLOSC_TRACE_ERROR("b2nd layer not found!");
259
0
    return BLOSC2_ERROR_FAILURE;
260
0
  }
261
0
  deserialize_meta(smeta, smeta_len, &ndim, shape, chunkshape, blockshape);
262
0
  free(smeta);
263
264
0
  for(int i = 0; i < ndim; i++) {
265
0
    if (blockshape[i] < 4) {
266
0
      BLOSC_TRACE_ERROR("ZFP does not support blocks smaller than cells (4x...x4");
267
0
      return BLOSC2_ERROR_FAILURE;
268
0
    }
269
0
  }
270
271
0
  zfp_type type;     /* array scalar type */
272
0
  zfp_field *field;  /* array meta data */
273
0
  zfp_stream *zfp;   /* stream containing the real output buffer */
274
0
  zfp_stream *zfp_aux;   /* auxiliary compressed stream */
275
0
  bitstream *stream; /* bit stream to write to or read from */
276
0
  bitstream *stream_aux; /* auxiliary bit stream to write to or read from */
277
0
  size_t zfpsize;    /* byte size of compressed stream */
278
279
0
  uint prec;
280
0
  switch (ndim) {
281
0
    case 1:
282
0
      prec = meta + 5;
283
0
      break;
284
0
    case 2:
285
0
      prec = meta + 7;
286
0
      break;
287
0
    case 3:
288
0
      prec = meta + 9;
289
0
      break;
290
0
    case 4:
291
0
      prec = meta + 11;
292
0
      break;
293
0
    default:
294
0
      free(shape);
295
0
      free(chunkshape);
296
0
      free(blockshape);
297
0
      BLOSC_TRACE_ERROR("ZFP is not available for ndims: %d", ndim);
298
0
      return BLOSC2_ERROR_FAILURE;
299
0
  }
300
301
0
  if (prec > ZFP_MAX_PREC) {
302
0
    BLOSC_TRACE_ERROR("Max precision for this codecs is %d", ZFP_MAX_PREC);
303
0
    prec = ZFP_MAX_PREC;
304
0
  }
305
306
0
  int32_t typesize = cparams->typesize;
307
0
  switch (typesize) {
308
0
    case sizeof(float):
309
0
      type = zfp_type_float;
310
0
      break;
311
0
    case sizeof(double):
312
0
      type = zfp_type_double;
313
0
      break;
314
0
    default:
315
0
      free(shape);
316
0
      free(chunkshape);
317
0
      free(blockshape);
318
0
      BLOSC_TRACE_ERROR("ZFP is not available for typesize: %d", typesize);
319
0
      return BLOSC2_ERROR_FAILURE;
320
0
  }
321
322
0
  zfp = zfp_stream_open(NULL);
323
0
  zfp_stream_set_precision(zfp, prec);
324
0
  stream = stream_open(output, output_len);
325
0
  zfp_stream_set_bit_stream(zfp, stream);
326
0
  zfp_stream_rewind(zfp);
327
328
0
  switch (ndim) {
329
0
    case 1:
330
0
      field = zfp_field_1d((void *) input, type, blockshape[0]);
331
0
      break;
332
0
    case 2:
333
0
      field = zfp_field_2d((void *) input, type, blockshape[1], blockshape[0]);
334
0
      break;
335
0
    case 3:
336
0
      field = zfp_field_3d((void *) input, type, blockshape[2], blockshape[1], blockshape[0]);
337
0
      break;
338
0
    case 4:
339
0
      field = zfp_field_4d((void *) input, type, blockshape[3], blockshape[2], blockshape[1], blockshape[0]);
340
0
      break;
341
0
    default:
342
0
      free(shape);
343
0
      free(chunkshape);
344
0
      free(blockshape);
345
0
      BLOSC_TRACE_ERROR("ZFP is not available for ndims: %d", ndim);
346
0
      return BLOSC2_ERROR_FAILURE;
347
0
  }
348
349
0
  int zfp_maxout = (int) zfp_stream_maximum_size(zfp, field);
350
0
  zfp_stream_close(zfp);
351
0
  stream_close(stream);
352
0
  uint8_t *aux_out = malloc(zfp_maxout);
353
0
  zfp_aux = zfp_stream_open(NULL);
354
0
  zfp_stream_set_precision(zfp_aux, prec);
355
0
  stream_aux = stream_open(aux_out, zfp_maxout);
356
0
  zfp_stream_set_bit_stream(zfp_aux, stream_aux);
357
0
  zfp_stream_rewind(zfp_aux);
358
359
0
  zfpsize = zfp_compress(zfp_aux, field);
360
361
  /* clean up */
362
0
  zfp_field_free(field);
363
0
  zfp_stream_close(zfp_aux);
364
0
  stream_close(stream_aux);
365
0
  free(shape);
366
0
  free(chunkshape);
367
0
  free(blockshape);
368
369
0
  if (zfpsize == 0) {
370
0
    BLOSC_TRACE_ERROR("\n ZFP: Compression failed\n");
371
0
    free(aux_out);
372
0
    return (int) zfpsize;
373
0
  }
374
0
  if ((int32_t) zfpsize >= input_len) {
375
0
    BLOSC_TRACE_ERROR("\n ZFP: Compressed data is bigger than input! \n");
376
0
    free(aux_out);
377
0
    return 0;
378
0
  }
379
380
0
  memcpy(output, aux_out, zfpsize);
381
0
  free(aux_out);
382
383
0
  return (int) zfpsize;
384
0
}
385
386
int zfp_prec_decompress(const uint8_t *input, int32_t input_len, uint8_t *output,
387
1
                        int32_t output_len, uint8_t meta, blosc2_dparams *dparams, const void *chunk) {
388
1
  ZFP_ERROR_NULL(input);
389
1
  ZFP_ERROR_NULL(output);
390
1
  ZFP_ERROR_NULL(dparams);
391
1
  ZFP_ERROR_NULL(dparams->schunk);
392
0
  BLOSC_UNUSED_PARAM(chunk);
393
394
0
  blosc2_schunk *sc = dparams->schunk;
395
0
  int32_t typesize = sc->typesize;
396
0
  int8_t ndim;
397
0
  int64_t *shape = malloc(8 * sizeof(int64_t));
398
0
  int32_t *chunkshape = malloc(8 * sizeof(int32_t));
399
0
  int32_t *blockshape = malloc(8 * sizeof(int32_t));
400
0
  uint8_t *smeta;
401
0
  int32_t smeta_len;
402
0
  if (blosc2_meta_get(sc, "b2nd", &smeta, &smeta_len) < 0) {
403
0
    BLOSC_TRACE_ERROR("Cannot access b2nd meta info");
404
0
    free(shape);
405
0
    free(chunkshape);
406
0
    free(blockshape);
407
0
    return BLOSC2_ERROR_FAILURE;
408
0
  }
409
0
  deserialize_meta(smeta, smeta_len, &ndim, shape, chunkshape, blockshape);
410
0
  free(smeta);
411
412
0
  zfp_type type;     /* array scalar type */
413
0
  zfp_field *field;  /* array meta data */
414
0
  zfp_stream *zfp;   /* compressed stream */
415
0
  bitstream *stream; /* bit stream to write to or read from */
416
0
  size_t zfpsize;    /* byte size of compressed stream */
417
418
0
  uint prec;
419
0
  switch (ndim) {
420
0
    case 1:
421
0
      prec = meta + 5;
422
0
      break;
423
0
    case 2:
424
0
      prec = meta + 7;
425
0
      break;
426
0
    case 3:
427
0
      prec = meta + 9;
428
0
      break;
429
0
    case 4:
430
0
      prec = meta + 11;
431
0
      break;
432
0
    default:
433
0
      free(shape);
434
0
      free(chunkshape);
435
0
      free(blockshape);
436
0
      BLOSC_TRACE_ERROR("ZFP is not available for ndims: %d", ndim);
437
0
      return BLOSC2_ERROR_FAILURE;
438
0
  }
439
440
0
  if (prec > ZFP_MAX_PREC) {
441
0
    BLOSC_TRACE_ERROR("Max precision for this codecs is %d", ZFP_MAX_PREC);
442
0
    prec = ZFP_MAX_PREC;
443
0
  }
444
445
0
  switch (typesize) {
446
0
    case sizeof(float):
447
0
      type = zfp_type_float;
448
0
      break;
449
0
    case sizeof(double):
450
0
      type = zfp_type_double;
451
0
      break;
452
0
    default:
453
0
      free(shape);
454
0
      free(chunkshape);
455
0
      free(blockshape);
456
0
      BLOSC_TRACE_ERROR("ZFP is not available for typesize: %d", typesize);
457
0
      return BLOSC2_ERROR_FAILURE;
458
0
  }
459
460
0
  zfp = zfp_stream_open(NULL);
461
0
  zfp_stream_set_precision(zfp, prec);
462
0
  stream = stream_open((void *) input, input_len);
463
0
  zfp_stream_set_bit_stream(zfp, stream);
464
0
  zfp_stream_rewind(zfp);
465
466
0
  switch (ndim) {
467
0
    case 1:
468
0
      field = zfp_field_1d((void *) output, type, blockshape[0]);
469
0
      break;
470
0
    case 2:
471
0
      field = zfp_field_2d((void *) output, type, blockshape[1], blockshape[0]);
472
0
      break;
473
0
    case 3:
474
0
      field = zfp_field_3d((void *) output, type, blockshape[2], blockshape[1], blockshape[0]);
475
0
      break;
476
0
    case 4:
477
0
      field = zfp_field_4d((void *) output, type, blockshape[3], blockshape[2], blockshape[1], blockshape[0]);
478
0
      break;
479
0
    default:
480
0
      free(shape);
481
0
      free(chunkshape);
482
0
      free(blockshape);
483
0
      BLOSC_TRACE_ERROR("ZFP is not available for ndims: %d", ndim);
484
0
      return BLOSC2_ERROR_FAILURE;
485
0
  }
486
487
0
  zfpsize = zfp_decompress(zfp, field);
488
489
  /* clean up */
490
0
  zfp_field_free(field);
491
0
  zfp_stream_close(zfp);
492
0
  stream_close(stream);
493
0
  free(shape);
494
0
  free(chunkshape);
495
0
  free(blockshape);
496
497
0
  if (zfpsize == 0) {
498
0
    BLOSC_TRACE_ERROR("\n ZFP: Decompression failed\n");
499
0
    return (int) zfpsize;
500
0
  }
501
502
0
  return (int) output_len;
503
0
}
504
505
int zfp_rate_compress(const uint8_t *input, int32_t input_len, uint8_t *output,
506
0
                      int32_t output_len, uint8_t meta, blosc2_cparams *cparams, const void *chunk) {
507
0
  BLOSC_UNUSED_PARAM(chunk);
508
0
  ZFP_ERROR_NULL(input);
509
0
  ZFP_ERROR_NULL(output);
510
0
  ZFP_ERROR_NULL(cparams);
511
0
  ZFP_ERROR_NULL(cparams->schunk);
512
513
0
  double ratio = (double) meta / 100.0;
514
0
  int8_t ndim;
515
0
  int64_t *shape = malloc(8 * sizeof(int64_t));
516
0
  int32_t *chunkshape = malloc(8 * sizeof(int32_t));
517
0
  int32_t *blockshape = malloc(8 * sizeof(int32_t));
518
0
  uint8_t *smeta;
519
0
  int32_t smeta_len;
520
0
  if (blosc2_meta_get(cparams->schunk, "b2nd", &smeta, &smeta_len) < 0) {
521
0
    free(shape);
522
0
    free(chunkshape);
523
0
    free(blockshape);
524
0
    BLOSC_TRACE_ERROR("b2nd layer not found!");
525
0
    return BLOSC2_ERROR_FAILURE;
526
0
  }
527
0
  deserialize_meta(smeta, smeta_len, &ndim, shape, chunkshape, blockshape);
528
0
  free(smeta);
529
530
0
  for(int i = 0; i < ndim; i++) {
531
0
    if (blockshape[i] < 4) {
532
0
      BLOSC_TRACE_ERROR("ZFP does not support blocks smaller than cells (4x...x4");
533
0
      return BLOSC2_ERROR_FAILURE;
534
0
    }
535
0
  }
536
537
0
  zfp_type type;     /* array scalar type */
538
0
  zfp_field *field;  /* array meta data */
539
0
  zfp_stream *zfp;   /* stream containing the real output buffer */
540
0
  zfp_stream *zfp_aux;   /* auxiliary compressed stream */
541
0
  bitstream *stream; /* bit stream to write to or read from */
542
0
  bitstream *stream_aux; /* auxiliary bit stream to write to or read from */
543
0
  size_t zfpsize;    /* byte size of compressed stream */
544
545
0
  int32_t typesize = cparams->typesize;
546
547
0
  switch (typesize) {
548
0
    case sizeof(float):
549
0
      type = zfp_type_float;
550
0
      break;
551
0
    case sizeof(double):
552
0
      type = zfp_type_double;
553
0
      break;
554
0
    default:
555
0
      BLOSC_TRACE_ERROR("ZFP is not available for typesize: %d", typesize);
556
0
      return BLOSC2_ERROR_FAILURE;
557
0
  }
558
0
  double rate = ratio * typesize * 8;     // convert from output size / input size to output bits per input value
559
0
  uint cellsize = 1u << (2 * ndim);
560
0
  double min_rate;
561
0
  if (type == zfp_type_float) {
562
0
    min_rate = (double) (1 + 8u) / cellsize;
563
0
    if (rate < min_rate) {
564
0
      BLOSC_TRACE_ERROR("ZFP minimum rate for this item type is %f. Compression will be done using this one.\n",
565
0
                        min_rate);
566
0
    }
567
0
  }
568
0
  else {
569
0
    min_rate = (double) (1 + 11u) / cellsize;
570
0
    if (rate < min_rate) {
571
0
      BLOSC_TRACE_ERROR("ZFP minimum rate for this item type is %f. Compression will be done using this one.\n",
572
0
                        min_rate);
573
0
    }
574
0
  }
575
0
  zfp = zfp_stream_open(NULL);
576
0
  stream = stream_open(output, output_len);
577
0
  zfp_stream_set_bit_stream(zfp, stream);
578
0
  zfp_stream_rewind(zfp);
579
580
0
  switch (ndim) {
581
0
    case 1:
582
0
      field = zfp_field_1d((void *) input, type, blockshape[0]);
583
0
      break;
584
0
    case 2:
585
0
      field = zfp_field_2d((void *) input, type, blockshape[1], blockshape[0]);
586
0
      break;
587
0
    case 3:
588
0
      field = zfp_field_3d((void *) input, type, blockshape[2], blockshape[1], blockshape[0]);
589
0
      break;
590
0
    case 4:
591
0
      field = zfp_field_4d((void *) input, type, blockshape[3], blockshape[2], blockshape[1], blockshape[0]);
592
0
      break;
593
0
    default:
594
0
      free(shape);
595
0
      free(chunkshape);
596
0
      free(blockshape);
597
0
      BLOSC_TRACE_ERROR("ZFP is not available for ndims: %d", ndim);
598
0
      return BLOSC2_ERROR_FAILURE;
599
0
  }
600
601
0
  int zfp_maxout = (int) zfp_stream_maximum_size(zfp, field);
602
0
  zfp_stream_close(zfp);
603
0
  stream_close(stream);
604
0
  uint8_t *aux_out = malloc(zfp_maxout);
605
0
  zfp_aux = zfp_stream_open(NULL);
606
0
  stream_aux = stream_open(aux_out, zfp_maxout);
607
0
  zfp_stream_set_bit_stream(zfp_aux, stream_aux);
608
0
  zfp_stream_rewind(zfp_aux);
609
0
  zfp_stream_set_rate(zfp_aux, rate, type, ndim, zfp_false);
610
611
0
  zfpsize = zfp_compress(zfp_aux, field);
612
613
  /* clean up */
614
0
  zfp_field_free(field);
615
0
  zfp_stream_close(zfp_aux);
616
0
  stream_close(stream_aux);
617
0
  free(shape);
618
0
  free(chunkshape);
619
0
  free(blockshape);
620
621
0
  if (zfpsize == 0) {
622
0
    BLOSC_TRACE_ERROR("\n ZFP: Compression failed\n");
623
0
    free(aux_out);
624
0
    return (int) zfpsize;
625
0
  }
626
0
  if ((int32_t) zfpsize >= input_len) {
627
0
    BLOSC_TRACE_ERROR("\n ZFP: Compressed data is bigger than input! \n");
628
0
    free(aux_out);
629
0
    return 0;
630
0
  }
631
632
0
  memcpy(output, aux_out, zfpsize);
633
0
  free(aux_out);
634
635
0
  return (int) zfpsize;
636
0
}
637
638
int zfp_rate_decompress(const uint8_t *input, int32_t input_len, uint8_t *output,
639
1
                        int32_t output_len, uint8_t meta, blosc2_dparams *dparams, const void *chunk) {
640
1
  ZFP_ERROR_NULL(input);
641
1
  ZFP_ERROR_NULL(output);
642
1
  ZFP_ERROR_NULL(dparams);
643
1
  ZFP_ERROR_NULL(dparams->schunk);
644
0
  BLOSC_UNUSED_PARAM(chunk);
645
646
0
  blosc2_schunk *sc = dparams->schunk;
647
0
  int32_t typesize = sc->typesize;
648
649
0
  double ratio = (double) meta / 100.0;
650
0
  int8_t ndim;
651
0
  int64_t *shape = malloc(8 * sizeof(int64_t));
652
0
  int32_t *chunkshape = malloc(8 * sizeof(int32_t));
653
0
  int32_t *blockshape = malloc(8 * sizeof(int32_t));
654
0
  uint8_t *smeta;
655
0
  int32_t smeta_len;
656
0
  if (blosc2_meta_get(sc, "b2nd", &smeta, &smeta_len) < 0) {
657
0
    BLOSC_TRACE_ERROR("Cannot access b2nd meta info");
658
0
    free(shape);
659
0
    free(chunkshape);
660
0
    free(blockshape);
661
0
    return BLOSC2_ERROR_FAILURE;
662
0
  }
663
0
  deserialize_meta(smeta, smeta_len, &ndim, shape, chunkshape, blockshape);
664
0
  free(smeta);
665
666
0
  zfp_type type;     /* array scalar type */
667
0
  zfp_field *field;  /* array meta data */
668
0
  zfp_stream *zfp;   /* compressed stream */
669
0
  bitstream *stream; /* bit stream to write to or read from */
670
0
  size_t zfpsize;    /* byte size of compressed stream */
671
672
0
  switch (typesize) {
673
0
    case sizeof(float):
674
0
      type = zfp_type_float;
675
0
      break;
676
0
    case sizeof(double):
677
0
      type = zfp_type_double;
678
0
      break;
679
0
    default:
680
0
      free(shape);
681
0
      free(chunkshape);
682
0
      free(blockshape);
683
0
      BLOSC_TRACE_ERROR("ZFP is not available for typesize: %d", typesize);
684
0
      return BLOSC2_ERROR_FAILURE;
685
0
  }
686
0
  double rate =
687
0
      ratio * (double) typesize * 8;     // convert from output size / input size to output bits per input value
688
0
  zfp = zfp_stream_open(NULL);
689
0
  zfp_stream_set_rate(zfp, rate, type, ndim, zfp_false);
690
691
0
  stream = stream_open((void *) input, input_len);
692
0
  zfp_stream_set_bit_stream(zfp, stream);
693
0
  zfp_stream_rewind(zfp);
694
695
0
  switch (ndim) {
696
0
    case 1:
697
0
      field = zfp_field_1d((void *) output, type, blockshape[0]);
698
0
      break;
699
0
    case 2:
700
0
      field = zfp_field_2d((void *) output, type, blockshape[1], blockshape[0]);
701
0
      break;
702
0
    case 3:
703
0
      field = zfp_field_3d((void *) output, type, blockshape[2], blockshape[1], blockshape[0]);
704
0
      break;
705
0
    case 4:
706
0
      field = zfp_field_4d((void *) output, type, blockshape[3], blockshape[2], blockshape[1], blockshape[0]);
707
0
      break;
708
0
    default:
709
0
      free(shape);
710
0
      free(chunkshape);
711
0
      free(blockshape);
712
0
      BLOSC_TRACE_ERROR("ZFP is not available for ndims: %d", ndim);
713
0
      return BLOSC2_ERROR_FAILURE;
714
0
  }
715
716
0
  zfpsize = zfp_decompress(zfp, field);
717
718
  /* clean up */
719
0
  zfp_field_free(field);
720
0
  zfp_stream_close(zfp);
721
0
  stream_close(stream);
722
0
  free(shape);
723
0
  free(chunkshape);
724
0
  free(blockshape);
725
726
0
  if (zfpsize == 0) {
727
0
    BLOSC_TRACE_ERROR("\n ZFP: Decompression failed\n");
728
0
    return (int) zfpsize;
729
0
  }
730
731
0
  return (int) output_len;
732
0
}
733
734
0
int zfp_getcell(void *thread_context, const uint8_t *block, int32_t cbytes, uint8_t *dest, int32_t destsize) {
735
0
  struct thread_context *thread_ctx = thread_context;
736
0
  blosc2_context *context = thread_ctx->parent_context;
737
0
  bool meta = false;
738
0
  int8_t ndim = ZFP_MAX_DIM + 1;
739
0
  int32_t blockmeta[ZFP_MAX_DIM];
740
0
  if (context->schunk->blockshape == NULL) {
741
    // blockshape is not filled yet.  Use the Blosc2 NDim layer to populate it.
742
0
    for (int nmetalayer = 0; nmetalayer < context->schunk->nmetalayers; nmetalayer++) {
743
0
      if (strcmp("b2nd", context->schunk->metalayers[nmetalayer]->name) == 0) {
744
0
        meta = true;
745
0
        uint8_t *pmeta = context->schunk->metalayers[nmetalayer]->content;
746
0
        ndim = (int8_t) pmeta[2];
747
0
        assert(ndim <= ZFP_MAX_DIM);
748
0
        pmeta += (6 + ndim * 9 + ndim * 5);
749
0
        for (int8_t i = 0; (uint8_t) i < ndim; i++) {
750
0
          pmeta += 1;
751
0
          swap_store(blockmeta + i, pmeta, sizeof(int32_t));
752
0
          pmeta += sizeof(int32_t);
753
0
        }
754
0
      }
755
0
    }
756
0
    if (!meta) {
757
0
      return -1;
758
0
    }
759
0
    context->schunk->ndim = ndim;
760
0
    context->schunk->blockshape = malloc(sizeof(int64_t) * ndim);
761
0
    for (int i = 0; i < ndim; ++i) {
762
0
      context->schunk->blockshape[i] = (int64_t) blockmeta[i];
763
0
    }
764
0
  }
765
0
  ndim = context->schunk->ndim;
766
0
  int64_t *blockshape = context->schunk->blockshape;
767
768
  // Compute the coordinates of the cell
769
0
  int64_t cell_start_ndim[ZFP_MAX_DIM];
770
0
  int64_t cell_ind_ndim[ZFP_MAX_DIM];
771
0
  int64_t ncell_ndim[ZFP_MAX_DIM];
772
0
  int64_t ind_strides[ZFP_MAX_DIM];
773
0
  int64_t cell_strides[ZFP_MAX_DIM];
774
0
  int64_t cell_ind, ncell;
775
0
  blosc2_unidim_to_multidim(ndim, blockshape, thread_ctx->zfp_cell_start, cell_start_ndim);
776
0
  for (int i = 0; i < ndim; ++i) {
777
0
    cell_ind_ndim[i] = cell_start_ndim[i] % ZFP_MAX_DIM;
778
0
    ncell_ndim[i] = cell_start_ndim[i] / ZFP_MAX_DIM;
779
0
  }
780
0
  ind_strides[ndim - 1] = cell_strides[ndim - 1] = 1;
781
0
  for (int i = ndim - 2; i >= 0; --i) {
782
0
    ind_strides[i] = ZFP_MAX_DIM * ind_strides[i + 1];
783
0
    cell_strides[i] = ((blockshape[i + 1] - 1) / ZFP_MAX_DIM + 1) * cell_strides[i + 1];
784
0
  }
785
0
  blosc2_multidim_to_unidim(cell_ind_ndim, (int8_t) ndim, ind_strides, &cell_ind);
786
0
  blosc2_multidim_to_unidim(ncell_ndim, (int8_t) ndim, cell_strides, &ncell);
787
0
  int cell_nitems = (int) (1u << (2 * ndim));
788
0
  if ((thread_ctx->zfp_cell_nitems > cell_nitems) ||
789
0
      ((cell_ind + thread_ctx->zfp_cell_nitems) > cell_nitems)) {
790
0
    return 0;
791
0
  }
792
793
  // Get the ZFP stream
794
0
  zfp_type type;     /* array scalar type */
795
0
  zfp_stream *zfp;   /* compressed stream */
796
0
  bitstream *stream; /* bit stream to write to or read from */
797
0
  int32_t typesize = context->typesize;
798
0
  zfp = zfp_stream_open(NULL);
799
800
0
  switch (typesize) {
801
0
    case sizeof(float):
802
0
      type = zfp_type_float;
803
0
      break;
804
0
    case sizeof(double):
805
0
      type = zfp_type_double;
806
0
      break;
807
0
    default:
808
0
      BLOSC_TRACE_ERROR("ZFP is not available for typesize: %d", typesize);
809
0
      return BLOSC2_ERROR_FAILURE;
810
0
  }
811
0
  uint8_t compmeta = context->compcode_meta;   // access to compressed chunk header
812
0
  double rate = (double) (compmeta * typesize * 8) /
813
0
                100.0;     // convert from output size / input size to output bits per input value
814
0
  zfp_stream_set_rate(zfp, rate, type, ndim, zfp_false);
815
816
0
  stream = stream_open((void *) block, cbytes);
817
0
  zfp_stream_set_bit_stream(zfp, stream);
818
0
  zfp_stream_rewind(zfp);
819
820
  // Check that ncell is a valid index
821
0
  int ncells = (int) ((cbytes * 8) / zfp->maxbits);
822
0
  if (ncell >= ncells) {
823
0
    BLOSC_TRACE_ERROR("Invalid cell index");
824
0
    return -1;
825
0
  }
826
827
  // Position the stream at the ncell bit offset for reading
828
0
  stream_rseek(zfp->stream, (size_t) (ncell * zfp->maxbits));
829
830
  // Get the cell
831
0
  size_t zfpsize;
832
0
  uint8_t *cell = malloc(cell_nitems * typesize);
833
0
  switch (ndim) {
834
0
    case 1:
835
0
      if (type == zfp_type_float) {
836
0
        zfpsize = zfp_decode_block_float_1(zfp, (float *) cell);
837
0
      }
838
0
      else {
839
0
        zfpsize = zfp_decode_block_double_1(zfp, (double *) cell);
840
0
      }
841
0
      break;
842
0
    case 2:
843
0
      if (type == zfp_type_float) {
844
0
        zfpsize = zfp_decode_block_float_2(zfp, (float *) cell);
845
0
      }
846
0
      else {
847
0
        zfpsize = zfp_decode_block_double_2(zfp, (double *) cell);
848
0
      }
849
0
      break;
850
0
    case 3:
851
0
      if (type == zfp_type_float) {
852
0
        zfpsize = zfp_decode_block_float_3(zfp, (float *) cell);
853
0
      }
854
0
      else {
855
0
        zfpsize = zfp_decode_block_double_3(zfp, (double *) cell);
856
0
      }
857
0
      break;
858
0
    case 4:
859
0
      if (type == zfp_type_float) {
860
0
        zfpsize = zfp_decode_block_float_4(zfp, (float *) cell);
861
0
      }
862
0
      else {
863
0
        zfpsize = zfp_decode_block_double_4(zfp, (double *) cell);
864
0
      }
865
0
      break;
866
0
    default:
867
0
      BLOSC_TRACE_ERROR("ZFP is not available for ndims: %d", ndim);
868
0
      return BLOSC2_ERROR_FAILURE;
869
0
  }
870
0
  memcpy(dest, &cell[cell_ind * typesize], thread_ctx->zfp_cell_nitems * typesize);
871
0
  zfp_stream_close(zfp);
872
0
  stream_close(stream);
873
0
  free(cell);
874
875
0
  if ((zfpsize == 0) || ((int32_t) zfpsize > (destsize * 8)) ||
876
0
      ((int32_t) zfpsize > (cell_nitems * typesize * 8)) ||
877
0
      ((thread_ctx->zfp_cell_nitems * typesize * 8) > (int32_t) zfpsize)) {
878
0
    BLOSC_TRACE_ERROR("ZFP error or small destsize");
879
0
    return -1;
880
0
  }
881
882
0
  return (int) (thread_ctx->zfp_cell_nitems * typesize);
883
0
}