mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-12-21 08:39:46 +08:00
44d0dcaad2
re: https://github.com/Unidata/netcdf-c/issues/1584 Support has been added for multiple filters per variable. This affects a number of components in netcdf. The new APIs are documented in NUG/filters.md. The primary changes are: * A set of new functions are provided (see __include/netcdf_filter.h__). - Obtain a list of the filters associated with a variable - Obtain the parameters for a specific filter. * The existing __nc_inq_var_filter__ function now returns info about the first defined filter. * The utilities (ncgen, ncdump, and nccopy) now support an extended format for specifying a sequence of filters. The general form is __<filter>|<filter>..._. * The ncdump **_Filter** attribute now dumps a list of all the filters associated with a variable using the above new format. * Filter specifications can now use a filter name instead of number for filters known to the netcdf library, which in turn is taken from the HDF5 filter registration page. * New errors are defined: NC_EFILTER and NC_ENOFILTER. The latter is returned if an attempt is made to access an unknown filter. * Internally, the dispatch table has been extended to add a function to handle all of the filter functions. * New, filter-related, tests were added to nc_test4. * A new plugin was added to the plugins directory to help with testing. Notes: 1. The shuffle and fletcher32 filters are not part of the multifilter system. Misc. changes: 1. A debug module was added to libhdf5 to help catch error locations.
155 lines
3.8 KiB
C
155 lines
3.8 KiB
C
/* This is part of the netCDF package.
|
|
Copyright 2018 University Corporation for Atmospheric Research/Unidata
|
|
See COPYRIGHT file for conditions of use.
|
|
*/
|
|
|
|
/*
|
|
* Example illustrates the use of SZIP compression in netCDF5
|
|
* Taken from HDF5 example.
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "nc_tests.h"
|
|
#include "err_macros.h"
|
|
#include "netcdf.h"
|
|
|
|
#undef PLAIN
|
|
#define USECLOSE
|
|
|
|
/* Szip Constants. */
|
|
#define HDF5_FILTER_SZIP 4
|
|
#define H5_SZIP_MAX_PIXELS_PER_BLOCK_IN 32
|
|
#define H5_SZIP_MAX_PIXELS_PER_BLOCK_OUT 64
|
|
|
|
/* Option Mask Flags (Refere to HDF5 szip documentation) */
|
|
#define H5_SZIP_ALLOW_K13_OPTION_MASK 1 /*Allows k split = 13 compression mode. (Default)*/
|
|
#define H5_SZIP_CHIP_OPTION_MASK 2 /*Compresses exactly as in hardware*/
|
|
#define H5_SZIP_EC_OPTION_MASK 4 /*Selects entropy coding method. (Default)*/
|
|
#define H5_SZIP_NN_OPTION_MASK 32 /*Selects nearest neighbor coding method*/
|
|
|
|
#define NX 500
|
|
#define NY 600
|
|
#define CH_NX 100
|
|
#define CH_NY 25
|
|
|
|
|
|
static void initialize(void);
|
|
static int compare(void);
|
|
|
|
static float buf[NX][NY];
|
|
static float buf_r[NX][NY];
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
int ncid, varid, dimids[2];
|
|
size_t dims[2], chunk_size[2];
|
|
unsigned int szip_params[2]; /* [0]=options_mask [1]=pixels_per_block */
|
|
int options_mask_in, pixels_per_block_in;
|
|
int errcnt = 0;
|
|
|
|
/* Create a new file using read/write access. */
|
|
if(nc_create("testszip.nc", NC_CLOBBER|NC_NETCDF4, &ncid)) ERR;
|
|
|
|
/* Create dims */
|
|
dims[0] = NX;
|
|
dims[1] = NY;
|
|
if(nc_def_dim(ncid, "x", dims[0], &dimids[0])) ERR;
|
|
if(nc_def_dim(ncid, "y", dims[1], &dimids[1])) ERR;
|
|
|
|
/* Create a dimensioned variable */
|
|
if(nc_def_var(ncid, "datasetF32", NC_FLOAT, 2, dimids, &varid)) ERR;
|
|
|
|
/* no fill */
|
|
if(nc_def_var_fill(ncid, varid, 1, NULL)) ERR;
|
|
|
|
/* Define chunking for the variable:
|
|
* the raw data is to be partitioned into 100x100 element chunks.
|
|
*/
|
|
chunk_size[0] = CH_NX;
|
|
chunk_size[1] = CH_NY;
|
|
if(nc_def_var_chunking(ncid, varid, NC_CHUNKED, chunk_size)) ERR;
|
|
|
|
#ifndef PLAIN
|
|
/*
|
|
* Set parameters for SZIP compression; check the description of
|
|
* the H5Pset_szip function in the HDF5 Reference Manual for more
|
|
* information.
|
|
*/
|
|
szip_params[0] = H5_SZIP_NN_OPTION_MASK;
|
|
szip_params[1] = H5_SZIP_MAX_PIXELS_PER_BLOCK_IN;
|
|
if(nc_def_var_filter(ncid, varid, HDF5_FILTER_SZIP, 2, szip_params)) ERR;
|
|
if(nc_inq_var_szip(ncid, varid, &options_mask_in, &pixels_per_block_in)) ERR;
|
|
if(!(options_mask_in & H5_SZIP_NN_OPTION_MASK)) ERR;
|
|
#endif
|
|
|
|
if(nc_enddef(ncid)) ERR;
|
|
|
|
initialize();
|
|
|
|
/* Write the array to the file */
|
|
if(nc_put_var_float(ncid, varid, &buf[0][0])) ERR;
|
|
|
|
#ifdef USECLOSE
|
|
/* Close and re-open the file */
|
|
if(nc_close(ncid)) ERR;
|
|
if(nc_open("testszip.nc", NC_NETCDF4, &ncid)) ERR;
|
|
if(nc_inq_varid(ncid, "datasetF32", &varid)) ERR;
|
|
#endif
|
|
|
|
/*
|
|
* Read the array. This is similar to writing data,
|
|
* except the data flows in the opposite direction.
|
|
* Note: Decompression should be automatic.
|
|
*/
|
|
|
|
memset(buf_r,0,sizeof(buf_r));
|
|
if(nc_get_var_float(ncid, varid, &buf_r[0][0])) ERR;
|
|
|
|
/* Do comparison */
|
|
errcnt = compare();
|
|
|
|
if(nc_close(ncid)) ERR;
|
|
|
|
if(errcnt) ERR;
|
|
|
|
SUMMARIZE_ERR;
|
|
FINAL_RESULTS;
|
|
|
|
return (errcnt==0?0:1);
|
|
}
|
|
|
|
static int
|
|
compare()
|
|
{
|
|
int i,j;
|
|
int errs = 0;
|
|
|
|
/* Do comparison */
|
|
for (i=0; i < NX; i++) {
|
|
for (j=0; j < NY; j++) {
|
|
if(buf[i][j] != buf_r[i][j]) {
|
|
errs++;
|
|
printf("mismatch: [%d][%d]: write = %f read=%f\n",
|
|
i,j,buf[i][j],buf_r[i][j]);
|
|
}
|
|
}
|
|
}
|
|
return errs;
|
|
}
|
|
|
|
static void
|
|
initialize(void)
|
|
{
|
|
int i, j;
|
|
/* Initialize data buffer with some bogus data. */
|
|
for(i=0; i < NX; i++) {
|
|
for(j=0; j < NY; j++) {
|
|
buf[i][j] = (float)(i + j);
|
|
}
|
|
}
|
|
}
|
|
|