NetCDF  4.9.2
dfilter.c
Go to the documentation of this file.
1 /*
2  * Copyright 2018, University Corporation for Atmospheric Research
3  * See netcdf/COPYRIGHT file for copying and redistribution conditions.
4  */
10 #include "config.h"
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <string.h>
14 #ifdef _MSC_VER
15 #include <io.h>
16 #endif
17 
18 #include "netcdf.h"
19 #include "netcdf_filter.h"
20 #include "ncdispatch.h"
21 #include "nc4internal.h"
22 
23 #ifdef USE_HDF5
24 #include "hdf5internal.h"
25 #endif
26 
27 #ifdef ENABLE_NCZARR
28 #include "zdispatch.h"
29 #endif
30 
31 /*
32 Unified filter related code
33 */
34 
35 /**************************************************/
36 /* Per-variable filters */
37 
57 EXTERNL int
58 nc_inq_var_filter_ids(int ncid, int varid, size_t* nfiltersp, unsigned int* ids)
59 {
60  NC* ncp;
61  int stat = NC_check_id(ncid,&ncp);
62  if(stat != NC_NOERR) return stat;
63  TRACE(nc_inq_var_filter_ids);
64  if((stat = ncp->dispatch->inq_var_filter_ids(ncid,varid,nfiltersp,ids))) goto done;
65 
66 done:
67  return stat;
68 }
69 
93 EXTERNL int
94 nc_inq_var_filter_info(int ncid, int varid, unsigned int id, size_t* nparamsp, unsigned int* params)
95 {
96  NC* ncp;
97  int stat = NC_check_id(ncid,&ncp);
98  if(stat != NC_NOERR) return stat;
100  if((stat = ncp->dispatch->inq_var_filter_info(ncid,varid,id,nparamsp,params))) goto done;
101 
102 done:
103  return stat;
104 }
105 
123 EXTERNL int
124 nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int* params)
125 {
126  int stat = NC_NOERR;
127  NC* ncp;
128  int fixedsize;
129  nc_type xtype;
130 
131  TRACE(nc_inq_var_filter);
132  if((stat = NC_check_id(ncid,&ncp))) return stat;
133  /* Get variable' type */
134  if((stat = nc_inq_vartype(ncid,varid,&xtype))) return stat;
135  /* If the variable's type is not fixed-size, then signal error */
136  if((stat = NC4_inq_type_fixed_size(ncid, xtype, &fixedsize))) return stat;
137  if(!fixedsize) return NC_EFILTER;
138  if((stat = ncp->dispatch->def_var_filter(ncid,varid,id,nparams,params))) goto done;
139 done:
140  return stat;
141 }
142 
170 EXTERNL int
171 nc_inq_var_filter(int ncid, int varid, unsigned int* idp, size_t* nparamsp, unsigned int* params)
172 {
173  NC* ncp;
174  size_t nfilters;
175  unsigned int* ids = NULL;
176  int stat = NC_check_id(ncid,&ncp);
177 
178  if(stat != NC_NOERR) return stat;
179  TRACE(nc_inq_var_filter);
180 
181  /* Get the number of filters on this variable */
182  if((stat = nc_inq_var_filter_ids(ncid,varid,&nfilters, NULL))) goto done;
183  /* If no filters, then return zero */
184  if(nfilters == 0) {
185  if(idp) *idp = 0;
186  goto done;
187  }
188  /* Get the filter ids */
189  if((ids = calloc(sizeof(unsigned int),nfilters)) == NULL) {stat = NC_ENOMEM; goto done;}
190  if((stat = nc_inq_var_filter_ids(ncid,varid,&nfilters, ids))) goto done;
191  /* Get params for the first filter */
192  if((stat = nc_inq_var_filter_info(ncid,varid,ids[0],nparamsp,params))) goto done;
193  if(idp) *idp = ids[0];
194  done:
195  nullfree(ids);
196  return stat;
197 }
198 
212 EXTERNL int
213 nc_inq_filter_avail(int ncid, unsigned id)
214 {
215  int stat = NC_NOERR;
216  NC* ncp;
217 
218  stat = NC_check_id(ncid,&ncp);
219  if(stat != NC_NOERR) return stat;
220  if((stat = ncp->dispatch->inq_filter_avail(ncid,id))) goto done;
221 done:
222  return stat;
223 }
224 
225 /**************************************************/
226 /* Support direct user defined filters */
227 
228 #ifdef ENABLE_CLIENTSIDE_FILTERS
229 
241 EXTERNL int
242 nc_filter_client_register(unsigned int id, void* info)
243 {
244  int stat = NC_NOERR;
245 #ifdef USE_HDF5
246  NC_FILTER_OBJ_HDF5 client;
247  if(id == 0 ||info == NULL)
248  return NC_EINVAL;
249  memset(&client,0,sizeof(client));
250  client.hdr.format = NC_FILTER_FORMAT_HDF5;
251  client.sort = NC_FILTER_SORT_CLIENT;
252  client.u.client.id = id;
253  client.u.client.info = info;
254  /* Note use of a global function, not part of the dispatch table */
255  stat = nc4_global_filter_action(NCFILTER_CLIENT_REG, id, &client);
256 #else
257  stat = NC_ENOTBUILT;
258 #endif
259  return stat;
260 }
261 
270 EXTERNL int
271 nc_filter_client_unregister(unsigned int id)
272 {
273 int stat = NC_NOERR;
274 #ifdef USE_HDF5
275  stat = nc4_global_filter_action(NCFILTER_CLIENT_UNREG, id, NULL);
276 #else
277  stat = NC_ENOTBUILT;
278 #endif
279  return stat;
280 }
281 
291 EXTERNL int
292 nc_filter_client_inq(unsigned int id, void* infop)
293 {
294 int stat = NC_NOERR;
295 #ifdef USE_HDF5
296  H5Z_class2_t* hct = (H5Z_class2_t*)infop;
297  NC_FILTER_OBJ_HDF5 client;
298  if(id == 0 ||infop == NULL)
299  return NC_EINVAL;
300  memset(&client,0,sizeof(client));
301  client.hdr.format = NC_FILTER_FORMAT_HDF5;
302  client.sort = NC_FILTER_SORT_CLIENT;
303  client.u.client.id = id;
304  client.u.client.info = hct;
305  /* Note use of a global function, not part of the dispatch table */
306  stat = nc4_global_filter_action(NCFILTER_CLIENT_INQ, id, &client);
307  if(stat == NC_NOERR) {
308  *hct = *(H5Z_class2_t*)client.u.client.info;
309  }
310 #else
311  stat = NC_ENOTBUILT;
312 #endif
313  return stat;
314 }
315 #endif /*ENABLE_CLIENTSIDE_FILTERS*/
316 
317 /**************************************************/
318 /* Functions for accessing standardized filters */
319 
331 int
332 nc_def_var_bzip2(int ncid, int varid, int level)
333 {
334  int stat = NC_NOERR;
335  unsigned ulevel;
336 
337  if((stat = nc_inq_filter_avail(ncid,H5Z_FILTER_BZIP2))) goto done;
338  /* Filter is available */
339  /* 1 <= Level <= 9 */
340  if (level < 1 || level > 9)
341  return NC_EINVAL;
342  ulevel = (unsigned) level; /* Keep bit pattern */
343  if((stat = nc_def_var_filter(ncid,varid,H5Z_FILTER_BZIP2,1,&ulevel))) goto done;
344 done:
345  return stat;
346 }
347 
362 int
363 nc_inq_var_bzip2(int ncid, int varid, int* hasfilterp, int *levelp)
364 {
365  int stat = NC_NOERR;
366  size_t nparams;
367  unsigned params = 0;
368  int hasfilter = 0;
369 
370  if((stat = nc_inq_filter_avail(ncid,H5Z_FILTER_BZIP2))) goto done;
371  /* Filter is available */
372  /* Get filter info */
373  stat = nc_inq_var_filter_info(ncid,varid,H5Z_FILTER_BZIP2,&nparams,NULL);
374  if(stat == NC_ENOFILTER) {stat = NC_NOERR; hasfilter = 0; goto done;}
375  if(stat != NC_NOERR) goto done;
376  hasfilter = 1;
377  if(nparams != 1) {stat = NC_EFILTER; goto done;}
378  if((stat = nc_inq_var_filter_info(ncid,varid,H5Z_FILTER_BZIP2,&nparams,&params))) goto done;
379 done:
380  if(levelp) *levelp = (int)params;
381  if(hasfilterp) *hasfilterp = hasfilter;
382  return stat;
383 }
384 
399 int
400 nc_def_var_zstandard(int ncid, int varid, int level)
401 {
402 #ifdef HAVE_ZSTD
403  int stat = NC_NOERR;
404  unsigned ulevel;
405 
406  if((stat = nc_inq_filter_avail(ncid,H5Z_FILTER_ZSTD))) goto done;
407  /* Filter is available */
408  /* Level must be between -131072 and 22 on Zstandard v. 1.4.5 (~202009)
409  Earlier versions have fewer levels (especially fewer negative levels) */
410  if (level < -131072 || level > 22)
411  return NC_EINVAL;
412  ulevel = (unsigned) level; /* Keep bit pattern */
413  if((stat = nc_def_var_filter(ncid,varid,H5Z_FILTER_ZSTD,1,&ulevel))) goto done;
414 done:
415  return stat;
416 #else
417  return NC_NOERR;
418 #endif /*HAVE_ZSTD*/
419 }
420 
435 int
436 nc_inq_var_zstandard(int ncid, int varid, int* hasfilterp, int *levelp)
437 {
438 #ifdef HAVE_ZSTD
439  int stat = NC_NOERR;
440  size_t nparams;
441  unsigned params = 0;
442  int hasfilter = 0;
443 
444  if((stat = nc_inq_filter_avail(ncid,H5Z_FILTER_ZSTD))) goto done;
445  /* Filter is available */
446  /* Get filter info */
447  stat = nc_inq_var_filter_info(ncid,varid,H5Z_FILTER_ZSTD,&nparams,NULL);
448  if(stat == NC_ENOFILTER) {stat = NC_NOERR; hasfilter = 0; goto done;}
449  if(stat != NC_NOERR) goto done;
450  hasfilter = 1;
451  if(nparams != 1) {stat = NC_EFILTER; goto done;}
452  if((stat = nc_inq_var_filter_info(ncid,varid,H5Z_FILTER_ZSTD,&nparams,&params))) goto done;
453 done:
454  if(levelp) *levelp = (int)params;
455  if(hasfilterp) *hasfilterp = hasfilter;
456  return stat;
457 #else
458  return NC_NOERR;
459 #endif /*HAVE_ZSTD*/
460 }
461 
476 int
477 nc_def_var_blosc(int ncid, int varid, unsigned subcompressor, unsigned level, unsigned blocksize, unsigned addshuffle)
478 {
479 #ifdef HAVE_BLOSC
480  int stat = NC_NOERR;
481  unsigned params[7];;
482 
483  if((stat = nc_inq_filter_avail(ncid,H5Z_FILTER_BLOSC))) goto done;
484  /* Filter is available */
485 
486  /* Verify parameters */
487  if(addshuffle > (unsigned)BLOSC_BITSHUFFLE) {stat = NC_EINVAL; goto done;}
488  if(subcompressor > (unsigned)BLOSC_ZSTD) {stat = NC_EINVAL; goto done;}
489 
490  /* Set the parameters */
491  params[0] = 0;
492  params[1] = 0;
493  params[2] = 0;
494  params[3] = blocksize;
495  params[4] = level;
496  params[5] = addshuffle;
497  params[6] = subcompressor;
498  if((stat = nc_def_var_filter(ncid,varid,H5Z_FILTER_BLOSC,7,params))) goto done;
499 done:
500  return stat;
501 #else
502  return NC_NOERR;
503 #endif
504 }
505 
526 int
527 nc_inq_var_blosc(int ncid, int varid, int* hasfilterp, unsigned* subcompressorp,
528  unsigned* levelp, unsigned* blocksizep, unsigned* addshufflep)
529 {
530 #ifdef HAVE_BLOSC
531  int stat = NC_NOERR;
532  size_t nparams;
533  unsigned params[7];
534  int hasfilter = 0;
535 
536  if((stat = nc_inq_filter_avail(ncid,H5Z_FILTER_BLOSC))) goto done;
537  /* Filter is available */
538 
539  /* Get filter info */
540  stat = nc_inq_var_filter_info(ncid,varid,H5Z_FILTER_BLOSC,&nparams,NULL);
541  if(stat == NC_ENOFILTER) {stat = NC_NOERR; hasfilter = 0; goto done;}
542  if(stat != NC_NOERR) goto done;
543  hasfilter = 1;
544  if(nparams != 7) {stat = NC_EFILTER; goto done;}
545  if((stat = nc_inq_var_filter_info(ncid,varid,H5Z_FILTER_BLOSC,&nparams,params))) goto done;
546  if(blocksizep) *blocksizep = params[3];
547  if(levelp) *levelp = params[4];
548  if(addshufflep) *addshufflep = params[5];
549  if(subcompressorp) *subcompressorp = params[6];
550 done:
551  if(hasfilterp) *hasfilterp = hasfilter;
552  return stat;
553 #else
554  return NC_NOERR;
555 #endif
556 }
int nc_inq_var_blosc(int ncid, int varid, int *hasfilterp, unsigned *subcompressorp, unsigned *levelp, unsigned *blocksizep, unsigned *addshufflep)
Learn whether Blosc compression is on for a variable, and, if so, the settings.
Definition: dfilter.c:527
int nc_def_var_zstandard(int ncid, int varid, int level)
Turn on Zstandard compression for a variable.
Definition: dfilter.c:400
int nc_inq_var_bzip2(int ncid, int varid, int *hasfilterp, int *levelp)
Learn whether bzip2 compression is on for a variable, and, if so, the level setting.
Definition: dfilter.c:363
int nc_def_var_bzip2(int ncid, int varid, int level)
Turn on bzip2 compression for a variable.
Definition: dfilter.c:332
EXTERNL int nc_inq_filter_avail(int ncid, unsigned id)
Test if filter is available.
Definition: dfilter.c:213
int nc_inq_var_zstandard(int ncid, int varid, int *hasfilterp, int *levelp)
Learn whether Zstandard compression is on for a variable, and, if so, the level setting.
Definition: dfilter.c:436
EXTERNL int nc_def_var_filter(int ncid, int varid, unsigned int id, size_t nparams, const unsigned int *params)
Define a new variable filter Assumes HDF5 format using unsigned ints.
Definition: dfilter.c:124
EXTERNL int nc_inq_vartype(int ncid, int varid, nc_type *xtypep)
Learn the type of a variable.
Definition: dvarinq.c:178
int nc_def_var_blosc(int ncid, int varid, unsigned subcompressor, unsigned level, unsigned blocksize, unsigned addshuffle)
Turn on blosc for a variable.
Definition: dfilter.c:477
EXTERNL int nc_inq_var_filter_info(int ncid, int varid, unsigned int id, size_t *nparamsp, unsigned int *params)
Find the the param info about filter (if any) associated with a variable and with specified id.
Definition: dfilter.c:94
EXTERNL int nc_inq_var_filter(int ncid, int varid, unsigned int *idp, size_t *nparamsp, unsigned int *params)
Find the first filter (if any) associated with a variable.
Definition: dfilter.c:171
EXTERNL int nc_inq_var_filter_ids(int ncid, int varid, size_t *nfiltersp, unsigned int *ids)
Find the set of filters (if any) associated with a variable.
Definition: dfilter.c:58
Main header file for the C API.
#define NC_EFILTER
Filter operation failed.
Definition: netcdf.h:513
#define NC_ENOMEM
Memory allocation (malloc) failure.
Definition: netcdf.h:448
#define EXTERNL
Needed for DLL build.
Definition: netcdf.h:556
#define NC_EINVAL
Invalid Argument.
Definition: netcdf.h:378
#define NC_NOERR
No Error.
Definition: netcdf.h:368
#define NC_ENOTBUILT
Attempt to use feature that was not turned on when netCDF was built.
Definition: netcdf.h:508
#define NC_ENOFILTER
Filter not defined on variable.
Definition: netcdf.h:517
int nc_type
The nc_type type is just an int.
Definition: netcdf.h:25