mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-02-17 16:50:18 +08:00
Merge branch 'dmh_merge_aggregate.wif' into v4.6.1-release-branch.wif
This commit is contained in:
commit
6074ef0751
@ -7,6 +7,9 @@
|
||||
|
||||
# Ed Hartnett, Ward Fisher
|
||||
|
||||
|
||||
|
||||
|
||||
# This directory stores libtool macros, put there by aclocal.
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
|
@ -7,6 +7,8 @@ This file contains a high-level description of this package's evolution. Release
|
||||
|
||||
## 4.6.1 - TBD
|
||||
|
||||
* [Bug Fix] Corrected an issue which could result in a dap4 failure. See [Github #888](https://github.com/Unidata/netcdf-c/pull/888) for more information.
|
||||
* [Bug Fix][Enhancement] Allow `nccopy` to control output filter suppresion. See [Github #894](https://github.com/Unidata/netcdf-c/pull/894) for more information.
|
||||
* [Enhancement] Reverted some new behaviors that, while in line with the netCDF specification, broke existing workflows. See [Github #843](https://github.com/Unidata/netcdf-c/issues/843) for more information.
|
||||
* [Bug Fix] Improved support for CRT builds with Visual Studio, improves zlib detection in hdf5 library. See [Github #853](https://github.com/Unidata/netcdf-c/pull/853) for more information.
|
||||
* [Enhancement][Internal] Moved HDF4 into a distinct dispatch layer. See [Github #849](https://github.com/Unidata/netcdf-c/pull/849) for more information.
|
||||
|
5
cf
5
cf
@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
#NB=1
|
||||
#DB=1
|
||||
DB=1
|
||||
#X=-x
|
||||
FAST=1
|
||||
|
||||
@ -124,7 +124,8 @@ FLAGS="$FLAGS --disable-parallel4"
|
||||
fi
|
||||
|
||||
if test "x${DB}" = x1 ; then
|
||||
FLAGS="$FLAGS --disable-shared --enable-static"
|
||||
#FLAGS="$FLAGS --disable-shared --enable-static"
|
||||
FLAGS="$FLAGS --enable-static"
|
||||
else
|
||||
FLAGS="$FLAGS --enable-shared"
|
||||
fi
|
||||
|
@ -750,7 +750,6 @@ INPUT = \
|
||||
@abs_top_srcdir@/docs/install-fortran.md \
|
||||
@abs_top_srcdir@/docs/types.dox \
|
||||
@abs_top_srcdir@/docs/internal.dox \
|
||||
@abs_top_srcdir@/docs/indexing.dox \
|
||||
@abs_top_srcdir@/docs/windows-binaries.md \
|
||||
@abs_top_srcdir@/docs/guide.dox \
|
||||
@abs_top_srcdir@/docs/OPeNDAP.dox \
|
||||
|
@ -142,10 +142,34 @@ The "-F" option can be used repeatedly as long as the variable name
|
||||
part is different. A different filter id and parameters can be
|
||||
specified for each occurrence.
|
||||
|
||||
Note that if the input file has compressed variables, that fact
|
||||
will be invisble to nccopy because it is handled within the
|
||||
netcdf-c/hdf5 library code. This is true for any program that calls
|
||||
the netcdf-c library.
|
||||
As a rule, any input filter on an input variable will be applied
|
||||
to the equivalent output variable -- assuming the output file type
|
||||
is netcdf-4. It is, however, sometimes convenient to suppress
|
||||
output compression either totally or on a per-variable basis.
|
||||
Total suppression of output filters can be accomplished by specifying
|
||||
a special case of "-F", namely this.
|
||||
````
|
||||
nccopy -F "none" input.nc output.nc
|
||||
````
|
||||
Suppression of output filtering for a specific variable can be accomplished
|
||||
using this format.
|
||||
````
|
||||
nccopy -F "var,none" input.nc output.nc
|
||||
````
|
||||
where "var" is the fully qualified name of the variable.
|
||||
|
||||
The rules for all possible cases of the "-F" flag are defined
|
||||
by this table.
|
||||
|
||||
<table>
|
||||
<tr><th>-F none<th>-Fvar,...<th>Input Filter<th>Applied Output Filter
|
||||
<tr><td>true<td>unspecified<td>NA<td>unfiltered
|
||||
<tr><td>true<td>-Fvar,none<td>NA<td>unfiltered
|
||||
<tr><td>true<td>-Fvar,...<td>NA<td>use output filter
|
||||
<tr><td>false<td>unspecified<td>defined<td>use input filter
|
||||
<tr><td>false<td>-Fvar,none<td>NA<td>unfiltered
|
||||
<tr><td>false<td>-Fvar,...<td>NA<td>use output filter
|
||||
</table>
|
||||
|
||||
Parameter Encoding {#ParamEncode}
|
||||
==========
|
||||
@ -416,5 +440,5 @@ References {#References}
|
||||
|
||||
1. https://support.hdfgroup.org/HDF5/doc/Advanced/DynamicallyLoadedFilters/HDF5DynamicallyLoadedFilters.pdf
|
||||
2. https://support.hdfgroup.org/HDF5/doc/TechNotes/TechNote-HDF5-CompressionTroubleshooting.pdf
|
||||
3. https://support.hdfgroup.org/services/filters.html
|
||||
3. https://portal.hdfgroup.org/display/support/Contributions#Contributions-filters
|
||||
4. https://support.hdfgroup.org/services/contributions.html#filters
|
||||
|
@ -21,7 +21,7 @@ DLLSRC=${PLUGINSRC} ${BZIP2SRC}
|
||||
lib_LTLIBRARIES = libbzip2.la
|
||||
|
||||
libbzip2_la_SOURCES = ${DLLSRC}
|
||||
libbzip2_la_LDFLAGS = -module -avoid-version -shared -export-dynamic -no-undefined
|
||||
libbzip2_la_LDFLAGS = -module -avoid-version -shared -export-dynamic -no-undefined -rpath ${abs_builddir}
|
||||
|
||||
endif #ENABLE_FILTER_TESTING
|
||||
EXTRA_DIST = CMakeLists.txt H5Zbzip2.c Makefile.am blocksort.c bzlib.c bzlib.h bzlib_private.h compress.c \
|
||||
|
@ -18,9 +18,9 @@ DLLSRC=${PLUGINSRC} ${BZIP2SRC} ${PLUGINHDRS} ${BZIP2HDRS}
|
||||
lib_LTLIBRARIES = libbzip2.la libmisc.la
|
||||
|
||||
libbzip2_la_SOURCES = ${DLLSRC}
|
||||
libbzip2_la_LDFLAGS = -module -avoid-version -shared -export-dynamic -no-undefined
|
||||
libbzip2_la_LDFLAGS = -module -avoid-version -shared -export-dynamic -no-undefined -rpath ${abs_builddir}
|
||||
|
||||
libmisc_la_SOURCES = H5Zmisc.c h5misc.h
|
||||
libmisc_la_LDFLAGS = -module -avoid-version -shared -export-dynamic -no-undefined
|
||||
libmisc_la_LDFLAGS = -module -avoid-version -shared -export-dynamic -no-undefined -rpath ${abs_builddir}
|
||||
|
||||
endif #ENABLE_FILTER_TESTING
|
||||
|
@ -55,11 +55,11 @@ if ! test -f ${MISCPATH} ; then echo "Unable to locate ${MISCPATH}"; exit 1; fi
|
||||
|
||||
if test "x$API" = x1 ; then
|
||||
echo "*** Testing dynamic filters using API"
|
||||
rm -f ./bzip2.nc ./bzip2.dump ./tmp_tst_filter
|
||||
rm -f ./bzip2.nc ./bzip2.dump ./tst_filter.txt
|
||||
${execdir}/test_filter
|
||||
${NCDUMP} -s bzip2.nc > ./tmp_tst_filter
|
||||
${NCDUMP} -s bzip2.nc > ./tst_filter.txt
|
||||
# Remove irrelevant -s output
|
||||
sclean ./tmp_tst_filter ./bzip2.dump
|
||||
sclean ./tst_filter.txt ./bzip2.dump
|
||||
diff -b -w ${srcdir}/bzip2.cdl ./bzip2.dump
|
||||
echo "*** Pass: API dynamic filter"
|
||||
fi
|
||||
@ -67,61 +67,88 @@ fi
|
||||
if test "x$MISC" = x1 ; then
|
||||
echo
|
||||
echo "*** Testing dynamic filters parameter passing"
|
||||
rm -f ./testmisc.nc tmp_tst_filter tmp_tst_filter2
|
||||
rm -f ./testmisc.nc tst_filter.txt tst_filter2.txt
|
||||
${execdir}/test_filter_misc
|
||||
# Verify the parameters via ncdump
|
||||
${NCDUMP} -s testmisc.nc > ./tmp_tst_filter
|
||||
${NCDUMP} -s testmisc.nc > ./tst_filter.txt
|
||||
# Extract the parameters
|
||||
getfilterattr ./tmp_tst_filter ./tmp_tst_filter2
|
||||
rm -f ./tmp_tst_filter
|
||||
trimleft ./tmp_tst_filter2 ./tmp_tst_filter
|
||||
rm -f ./tmp_tst_filter2
|
||||
cat >./tmp_tst_filter2 <<EOF
|
||||
getfilterattr ./tst_filter.txt ./tst_filter2.txt
|
||||
rm -f ./tst_filter.txt
|
||||
trimleft ./tst_filter2.txt ./tst_filter.txt
|
||||
rm -f ./tst_filter2.txt
|
||||
cat >./tst_filter2.txt <<EOF
|
||||
var:_Filter = "32768,1,239,23,65511,27,77,93,1145389056,3287505826,1097305129,1,2147483648,4294967295,4294967295" ;
|
||||
EOF
|
||||
diff -b -w ./tmp_tst_filter ./tmp_tst_filter2
|
||||
diff -b -w ./tst_filter.txt ./tst_filter2.txt
|
||||
echo "*** Pass: parameter passing"
|
||||
fi
|
||||
|
||||
if test "x$NG" = x1 ; then
|
||||
echo "*** Testing dynamic filters using ncgen"
|
||||
rm -f ./bzip2.nc ./bzip2.dump ./tmp_tst_filter
|
||||
rm -f ./bzip2.nc ./bzip2.dump ./tst_filter.txt
|
||||
${NCGEN} -lb -4 -o bzip2.nc ${srcdir}/bzip2.cdl
|
||||
${NCDUMP} -s bzip2.nc > ./tmp_tst_filter
|
||||
${NCDUMP} -s bzip2.nc > ./tst_filter.txt
|
||||
# Remove irrelevant -s output
|
||||
sclean ./tmp_tst_filter ./bzip2.dump
|
||||
sclean ./tst_filter.txt ./bzip2.dump
|
||||
diff -b -w ${srcdir}/bzip2.cdl ./bzip2.dump
|
||||
echo "*** Pass: ncgen dynamic filter"
|
||||
fi
|
||||
|
||||
if test "x$NCP" = x1 ; then
|
||||
echo "*** Testing dynamic filters using nccopy"
|
||||
rm -f ./unfiltered.nc ./filtered.nc ./filtered.dump ./tmp_tst_filter
|
||||
rm -f ./unfiltered.nc ./filtered.nc ./tmp.nc ./filtered.dump ./tst_filter.txt
|
||||
${NCGEN} -4 -lb -o unfiltered.nc ${srcdir}/unfiltered.cdl
|
||||
echo " *** Testing simple filter application"
|
||||
${NCCOPY} -F "/g/var,307,9,4" unfiltered.nc filtered.nc
|
||||
${NCDUMP} -s filtered.nc > ./tmp_tst_filter
|
||||
${NCDUMP} -s filtered.nc > ./tst_filter.txt
|
||||
# Remove irrelevant -s output
|
||||
sclean ./tmp_tst_filter ./filtered.dump
|
||||
sclean ./tst_filter.txt ./filtered.dump
|
||||
diff -b -w ${srcdir}/filtered.cdl ./filtered.dump
|
||||
echo "*** Pass: nccopy dynamic filter"
|
||||
echo " *** Pass: nccopy simple filter"
|
||||
|
||||
echo " *** Testing pass-thru of filters"
|
||||
rm -f ./tst_filter.txt tst_filter2.txt ./tst_filter2.nc
|
||||
${NCCOPY} ./filtered.nc ./tst_filter2.nc
|
||||
${NCDUMP} -s tst_filter2.nc > ./tst_filter.txt
|
||||
sed -e '/_Filter/p' -e d < ./tst_filter.txt >tst_filter2.txt
|
||||
test -s tst_filter2.txt
|
||||
echo " *** Pass: pass-thru of filters"
|
||||
|
||||
echo " *** Testing -F none"
|
||||
rm -f ./tst_filter.txt ./tst_filter2.txt ./tst_filter.nc
|
||||
${NCCOPY} -F none ./filtered.nc ./tst_filter.nc
|
||||
${NCDUMP} -s tst_filter.nc > ./tst_filter.txt
|
||||
sed -e '/_Filter/p' -e d < ./tst_filter.txt >./tst_filter2.txt
|
||||
test ! -s tst_filter2.txt
|
||||
echo " *** Pass: -F none"
|
||||
|
||||
echo " *** Testing -F var,none "
|
||||
rm -f ./tst_filter.txt ./tst_filter.nc
|
||||
${NCCOPY} -F "/g/var,none" ./filtered.nc ./tst_filter.nc
|
||||
${NCDUMP} -s tst_filter.nc > ./tst_filter.txt
|
||||
sed -e '/_Filter/p' -e d < ./tst_filter.txt >tst_filter2.txt
|
||||
test ! -s tst_filter2.txt
|
||||
echo " *** Pass: -F var,none"
|
||||
|
||||
echo "*** Pass: all nccopy filter tests"
|
||||
fi
|
||||
|
||||
if test "x$UNK" = x1 ; then
|
||||
echo "*** Testing access to filter info when filter dll is not available"
|
||||
rm -f bzip2.nc ./tmp_tst_filter
|
||||
rm -f bzip2.nc ./tst_filter.txt
|
||||
# build bzip2.nc
|
||||
${NCGEN} -lb -4 -o bzip2.nc ${srcdir}/bzip2.cdl
|
||||
# dump and clean bzip2.nc header only when filter is avail
|
||||
${NCDUMP} -hs bzip2.nc > ./tmp_tst_filter
|
||||
${NCDUMP} -hs bzip2.nc > ./tst_filter.txt
|
||||
# Remove irrelevant -s output
|
||||
sclean ./tmp_tst_filter bzip2.dump
|
||||
sclean ./tst_filter.txt bzip2.dump
|
||||
# Now hide the filter code
|
||||
mv ${BZIP2PATH} ${BZIP2PATH}.save
|
||||
# dump and clean bzip2.nc header only when filter is not avail
|
||||
rm -f ./tmp_tst_filter
|
||||
${NCDUMP} -hs bzip2.nc > ./tmp_tst_filter
|
||||
rm -f ./tst_filter.txt
|
||||
${NCDUMP} -hs bzip2.nc > ./tst_filter.txt
|
||||
# Remove irrelevant -s output
|
||||
sclean ./tmp_tst_filter bzip2x.dump
|
||||
sclean ./tst_filter.txt bzip2x.dump
|
||||
# Restore the filter code
|
||||
mv ${BZIP2PATH}.save ${BZIP2PATH}
|
||||
diff -b -w ./bzip2.dump ./bzip2x.dump
|
||||
@ -137,10 +164,10 @@ echo "*** Pass: ncgen dynamic filter"
|
||||
fi
|
||||
|
||||
#cleanup
|
||||
rm -f ./bzip*.nc ./unfiltered.nc ./filtered.nc ./tmp_tst_filter ./tmp_tst_filter2 *.dump bzip*hdr.*
|
||||
rm -fr ./test_bzip2.c
|
||||
rm -fr ./testmisc.nc
|
||||
|
||||
rm -f ./bzip*.nc ./unfiltered.nc ./filtered.nc ./tst_filter.txt ./tst_filter2.txt *.dump bzip*hdr.*
|
||||
rm -f ./test_bzip2.c
|
||||
rm -f ./testmisc.nc
|
||||
rm -f ./tst_filter2.nc
|
||||
echo "*** Pass: all selected tests passed"
|
||||
|
||||
exit 0
|
||||
|
@ -178,7 +178,6 @@ main(int argc, char **argv)
|
||||
fprintf(stderr,"*** Test Charlie's test for renaming with one enddef...");
|
||||
{
|
||||
int ncid, dimid, varid;
|
||||
nc_set_log_level(5);
|
||||
|
||||
/* Create a nice, simple file. This file will contain one
|
||||
* dataset, "lon", which is a dimscale. */
|
||||
|
@ -4,6 +4,10 @@
|
||||
|
||||
# Ed Hartnett, Dennis Heimbigner, Ward Fisher
|
||||
|
||||
#SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
|
||||
#sh_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
|
||||
#LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver-verbose
|
||||
|
||||
# Put together AM_CPPFLAGS and AM_LDFLAGS.
|
||||
include $(top_srcdir)/lib_flags.am
|
||||
LDADD = ${top_builddir}/liblib/libnetcdf.la
|
||||
|
167
ncdump/nccopy.c
167
ncdump/nccopy.c
@ -61,6 +61,7 @@ typedef struct VarID {
|
||||
|
||||
struct FilterSpec {
|
||||
char* fqn;
|
||||
int nofilter; /* 1=> do not apply any filters to this variable */
|
||||
unsigned int filterid;
|
||||
size_t nparams;
|
||||
unsigned int* params;
|
||||
@ -68,6 +69,7 @@ struct FilterSpec {
|
||||
|
||||
static int nfilterspecs = 0; /* Number of defined filter specs */
|
||||
static struct FilterSpec filterspecs[MAX_FILTER_SPECS];
|
||||
static int suppressfilters = 0; /* 1 => do not apply any output filters unless specified */
|
||||
|
||||
#endif
|
||||
|
||||
@ -83,9 +85,11 @@ static size_t option_chunk_cache_size = CHUNK_CACHE_SIZE; /* default from config
|
||||
static size_t option_chunk_cache_nelems = CHUNK_CACHE_NELEMS; /* default from config.h */
|
||||
static int option_read_diskless = 0; /* default, don't read input into memory on open */
|
||||
static int option_write_diskless = 0; /* default, don't write output to diskless file */
|
||||
#ifdef USE_NETCDF4
|
||||
static int option_min_chunk_bytes = CHUNK_THRESHOLD; /* default, don't chunk variable if prod of
|
||||
* chunksizes of its dimensions is smaller
|
||||
* than this */
|
||||
#endif
|
||||
static int option_nlgrps = 0; /* Number of groups specified with -g
|
||||
* option on command line */
|
||||
static char** option_lgrps = 0; /* list of group names specified with -g
|
||||
@ -242,6 +246,9 @@ parsefilterspec(const char* optarg0, struct FilterSpec* spec)
|
||||
char* remainder = NULL;
|
||||
|
||||
if(optarg0 == NULL || strlen(optarg0) == 0 || spec == NULL) return 0;
|
||||
|
||||
memset(spec,0,sizeof(struct FilterSpec));
|
||||
|
||||
optarg = strdup(optarg0);
|
||||
|
||||
/* Collect the fqn, taking escapes into account */
|
||||
@ -253,7 +260,8 @@ parsefilterspec(const char* optarg0, struct FilterSpec* spec)
|
||||
else if(*p == '\0') {remainder = p; break;}
|
||||
/* else continue */
|
||||
}
|
||||
if(strlen(optarg) == 0) return 0; /* fqn does not exist */
|
||||
if(strlen(optarg) == 0) {stat = NC_EINVAL; goto done;} /* fqn does not exist */
|
||||
|
||||
/* Make sure leading '/' is in place */
|
||||
if(optarg[0]=='/')
|
||||
spec->fqn = strdup(optarg);
|
||||
@ -263,6 +271,12 @@ parsefilterspec(const char* optarg0, struct FilterSpec* spec)
|
||||
strcat(spec->fqn,optarg);
|
||||
}
|
||||
|
||||
/* Check for special cases */
|
||||
if(strcmp(remainder,"none") == 0) {
|
||||
spec->nofilter = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Collect the id+parameters */
|
||||
if((stat = NC_parsefilterspec(remainder,&id,&nparams,¶ms)) == NC_NOERR) {
|
||||
if(spec != NULL) {
|
||||
@ -271,6 +285,9 @@ parsefilterspec(const char* optarg0, struct FilterSpec* spec)
|
||||
spec->params = params;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if(optarg) free(optarg);
|
||||
return stat;
|
||||
}
|
||||
|
||||
@ -721,57 +738,101 @@ static int
|
||||
copy_var_filter(int igrp, int varid, int ogrp, int o_varid)
|
||||
{
|
||||
int stat = NC_NOERR;
|
||||
#ifdef USE_NETCDF4
|
||||
VarID vid = {igrp,varid};
|
||||
VarID ovid = {ogrp,o_varid};
|
||||
/* handle filter parameters, copying from input, overriding with command-line options */
|
||||
struct FilterSpec spec;
|
||||
int i, found;
|
||||
struct FilterSpec inspec, ospec, actualspec;
|
||||
int i;
|
||||
char* ofqn = NULL;
|
||||
int format, oformat;
|
||||
int inputdefined, outputdefined, unfiltered;
|
||||
|
||||
/* Get file format of the input and output */
|
||||
if((stat=nc_inq_format(vid.grpid,&format))) goto done;
|
||||
if((stat=nc_inq_format(ovid.grpid,&oformat))) goto done;
|
||||
|
||||
if(oformat != NC_FORMAT_NETCDF4 && oformat != NC_FORMAT_NETCDF4_CLASSIC)
|
||||
goto done; /* Can only use filter when output is netcdf4 */
|
||||
goto done; /* Can only use filter when output is some netcdf4 variant */
|
||||
|
||||
/* Compute the output vid's FQN */
|
||||
if((stat = computeFQN(ovid,&ofqn))) goto done;
|
||||
/* See if any filter spec is defined for this output variable */
|
||||
for(found=0,i=0;i<nfilterspecs;i++) {
|
||||
if(strcmp(filterspecs[i].fqn,ofqn)==0) {spec = filterspecs[i]; found = 1; break;}
|
||||
}
|
||||
if(!found) {
|
||||
spec.filterid = 0; /* marker to indicate not filter to apply */
|
||||
if((oformat == NC_FORMAT_NETCDF4
|
||||
|| oformat != NC_FORMAT_NETCDF4_CLASSIC)
|
||||
&& (format == NC_FORMAT_NETCDF4
|
||||
|| format != NC_FORMAT_NETCDF4_CLASSIC)
|
||||
) {
|
||||
/* Only bother to look if both input and output are netcdf-4 */
|
||||
if((stat=nc_inq_var_filter(vid.grpid,vid.varid,&spec.filterid,&spec.nparams,NULL)))
|
||||
goto done;
|
||||
if(spec.filterid > 0) {/* input has a filter */
|
||||
spec.params = (unsigned int*)malloc(sizeof(unsigned int)*spec.nparams);
|
||||
if((stat=nc_inq_var_filter(vid.grpid,vid.varid,&spec.filterid,&spec.nparams,spec.params)))
|
||||
goto done;
|
||||
|
||||
/* Clear the in and out specs */
|
||||
memset(&inspec,0,sizeof(inspec));
|
||||
memset(&ospec,0,sizeof(ospec));
|
||||
memset(&actualspec,0,sizeof(actualspec));
|
||||
|
||||
/* Is there a filter on the output variable */
|
||||
outputdefined = 0; /* default is no filter defined */
|
||||
/* Only bother to look if output is netcdf-4 variant */
|
||||
if(oformat == NC_FORMAT_NETCDF4 || oformat == NC_FORMAT_NETCDF4_CLASSIC) {
|
||||
/* See if any output filter spec is defined for this output variable */
|
||||
for(i=0;i<nfilterspecs;i++) {
|
||||
if(strcmp(filterspecs[i].fqn,ofqn)==0) {
|
||||
ospec = filterspecs[i];
|
||||
outputdefined = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Is there a filter on the input variable */
|
||||
inputdefined = 0; /* default is no filter defined */
|
||||
/* Only bother to look if input is netcdf-4 variant */
|
||||
if(format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_NETCDF4_CLASSIC) {
|
||||
stat=nc_inq_var_filter(vid.grpid,vid.varid,&inspec.filterid,&inspec.nparams,NULL);
|
||||
if(stat && stat != NC_EFILTER)
|
||||
goto done; /* true error */
|
||||
if(stat == NC_NOERR) {/* input has a filter */
|
||||
inspec.params = (unsigned int*)malloc(sizeof(unsigned int)*inspec.nparams);
|
||||
if((stat=nc_inq_var_filter(vid.grpid,vid.varid,&inspec.filterid,&inspec.nparams,inspec.params)))
|
||||
goto done;
|
||||
inputdefined = 1;
|
||||
}
|
||||
}
|
||||
/* Apply filter spec if any */
|
||||
if(spec.filterid > 0) {/* Apply filter */
|
||||
#ifdef USE_NETCDF4
|
||||
if((stat=nc_def_var_filter(ovid.grpid,ovid.varid,spec.filterid,spec.nparams,spec.params)))
|
||||
|
||||
/* Rules for choosing output filter are as follows:
|
||||
|
||||
global output input Actual Output
|
||||
suppress filter filter filter
|
||||
-----------------------------------------------
|
||||
true undefined NA unfiltered
|
||||
true 'none' NA unfiltered
|
||||
true defined NA use output filter
|
||||
false undefined defined use input filter
|
||||
false 'none' NA unfiltered
|
||||
false defined NA use output filter
|
||||
*/
|
||||
|
||||
unfiltered = 0;
|
||||
|
||||
if(suppressfilters && !outputdefined) /* row 1 */
|
||||
unfiltered = 1;
|
||||
else if(suppressfilters && outputdefined && ospec.nofilter) /* row 2 */
|
||||
unfiltered = 1;
|
||||
else if(suppressfilters && outputdefined) /* row 3 */
|
||||
actualspec = ospec;
|
||||
else if(!suppressfilters && !outputdefined && inputdefined) /* row 4 */
|
||||
actualspec = inspec;
|
||||
else if(!suppressfilters && outputdefined && ospec.nofilter) /* row 5 */
|
||||
unfiltered = 1;
|
||||
else if(!suppressfilters && outputdefined) /* row 6 */
|
||||
actualspec = ospec;
|
||||
|
||||
/* Apply actual filter spec if any */
|
||||
if(!unfiltered) {
|
||||
if((stat=nc_def_var_filter(ovid.grpid,ovid.varid,
|
||||
actualspec.filterid,
|
||||
actualspec.nparams,
|
||||
actualspec.params)))
|
||||
goto done;
|
||||
#endif
|
||||
}
|
||||
done:
|
||||
/* Cleanup */
|
||||
if(spec.filterid > 0 && spec.nparams > 0 && spec.params != NULL)
|
||||
free(spec.params);
|
||||
#endif /*USE_NETCDF4*/
|
||||
if(ofqn != NULL) free(ofqn);
|
||||
if(inspec.fqn) free(inspec.fqn);
|
||||
if(inspec.params) free(inspec.params);
|
||||
/* Note we do not clean actualspec because it is a copy of in|out spec */
|
||||
return stat;
|
||||
}
|
||||
|
||||
@ -1342,8 +1403,10 @@ copy_data(int igrp, int ogrp)
|
||||
/* Count total number of dimensions in ncid and all its descendant subgroups */
|
||||
int
|
||||
count_dims(int ncid) {
|
||||
int numgrps;
|
||||
int ndims;
|
||||
#ifdef USE_NETCDF4
|
||||
int numgrps;
|
||||
#endif
|
||||
NC_CHECK(nc_inq_ndims(ncid, &ndims));
|
||||
#ifdef USE_NETCDF4
|
||||
NC_CHECK(nc_inq_grps(ncid, &numgrps, NULL));
|
||||
@ -1784,10 +1847,12 @@ usage(void)
|
||||
int
|
||||
main(int argc, char**argv)
|
||||
{
|
||||
int exitcode = EXIT_SUCCESS;
|
||||
char* inputfile = NULL;
|
||||
char* outputfile = NULL;
|
||||
int c;
|
||||
#ifdef USE_NETCDF4
|
||||
int i;
|
||||
struct FilterSpec filterspec;
|
||||
#endif
|
||||
|
||||
@ -1970,14 +2035,20 @@ main(int argc, char**argv)
|
||||
break;
|
||||
case 'F': /* optional filter spec for a specified variable */
|
||||
#ifdef USE_NETCDF4
|
||||
if(parsefilterspec(optarg,&filterspec) != NC_NOERR)
|
||||
usage();
|
||||
if(nfilterspecs >= (MAX_FILTER_SPECS-1))
|
||||
error("too many -F filterspecs\n");
|
||||
filterspecs[nfilterspecs] = filterspec;
|
||||
nfilterspecs++;
|
||||
// Force output to be netcdf-4
|
||||
option_kind = NC_FORMAT_NETCDF4;
|
||||
/* If the arg is "none" then suppress all filters
|
||||
on output unless explicit */
|
||||
if(strcmp(optarg,"none")==0) {
|
||||
suppressfilters = 1;
|
||||
} else {
|
||||
if(parsefilterspec(optarg,&filterspec) != NC_NOERR)
|
||||
usage();
|
||||
if(nfilterspecs >= (MAX_FILTER_SPECS-1))
|
||||
error("too many -F filterspecs\n");
|
||||
filterspecs[nfilterspecs] = filterspec;
|
||||
nfilterspecs++;
|
||||
// Force output to be netcdf-4
|
||||
option_kind = NC_FORMAT_NETCDF4;
|
||||
}
|
||||
#else
|
||||
error("-F requires netcdf-4");
|
||||
#endif
|
||||
@ -2001,7 +2072,7 @@ main(int argc, char**argv)
|
||||
|
||||
#ifdef USE_NETCDF4
|
||||
#ifdef DEBUGFILTER
|
||||
{ int i,j;
|
||||
{ int j;
|
||||
for(i=0;i<nfilterspecs;i++) {
|
||||
struct FilterSpec *spec = &filterspecs[i];
|
||||
fprintf(stderr,"filterspecs[%d]={fqn=|%s| filterid=%u nparams=%ld params=",
|
||||
@ -2018,6 +2089,16 @@ main(int argc, char**argv)
|
||||
#endif /*USE_NETCDF4*/
|
||||
|
||||
if(copy(inputfile, outputfile) != NC_NOERR)
|
||||
exit(EXIT_FAILURE);
|
||||
exit(EXIT_SUCCESS);
|
||||
exitcode = EXIT_FAILURE;
|
||||
|
||||
#ifdef USE_NETCDF4
|
||||
/* Clean up */
|
||||
for(i=0;i<nfilterspecs;i++) {
|
||||
struct FilterSpec* spec = &filterspecs[i];
|
||||
if(spec->fqn) free(spec->fqn);
|
||||
if(spec->params) free(spec->params);
|
||||
}
|
||||
#endif /*USE_NETCDF4*/
|
||||
|
||||
exit(exitcode);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user