Skip to content

Commit 5a7cf26

Browse files
authored
Merge pull request #1692 from NOAA-GSD/ejh_fix_nc3_deflate
now testing that nc_inq_var_deflate()/nc_inq_var_szip() work for all formats and returns settings consistent with no compression in use
2 parents b51767e + db8abfc commit 5a7cf26

File tree

4 files changed

+96
-16
lines changed

4 files changed

+96
-16
lines changed

RELEASE_NOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ This file contains a high-level description of this package's evolution. Release
88
## 4.8.0 - TBD
99

1010
* [Bug Fix][cmake] Correct an issue with parallel filter test logic in CMake-based builds.
11+
* [Bug Fix] Now allow nc_inq_var_deflate()/nc_inq_var_szip() to be called for all formats, not just HDF5. Non-HDF5 files return NC_NOERR and report no compression in use. This reverts behavior that was changed in the 4.7.4 release. See [https://github.com/Unidata/netcdf-c/issues/1691].
1112
* [Bug Fix] Compiling on a big-endian machine exposes some missing forward delcarations in dfilter.c.
1213

1314
## 4.7.4 - March 27, 2020

libdispatch/dvar.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -317,21 +317,26 @@ nc_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
317317
}
318318

319319
/**
320-
Set the zlib compression settings for a netCDF-4/HDF5 variable.
320+
Set the zlib compression and shuffle settings for a variable in an
321+
netCDF/HDF5 file.
321322
322323
This function must be called after nc_def_var and before nc_enddef
323324
or any functions which writes data to the file.
324325
325-
Deflation and shuffline require chunked data. If this function is
326+
Deflation and shuffle are only available for HDF5 files. Attempting
327+
to set them on non-HDF5 files will return ::NC_ENOTNC4.
328+
329+
Deflation and shuffle require chunked data. If this function is
326330
called on a variable with contiguous data, then the data is changed
327331
to chunked data, with default chunksizes. Use nc_def_var_chunking()
328332
to tune performance with user-defined chunksizes.
329333
330334
If this function is called on a scalar variable, ::NC_EINVAL is
331335
returned. Only chunked variables may use filters.
332336
333-
If this function is called on a variable which already has szip
334-
compression turned on, ::NC_EINVAL is returned.
337+
Zlib compression cannot be used with szip compression. If this
338+
function is called on a variable which already has szip compression
339+
turned on, ::NC_EINVAL is returned.
335340
336341
@note Parallel I/O reads work with compressed data. Parallel I/O
337342
writes work with compressed data in netcdf-c-4.7.4 and later
@@ -341,6 +346,28 @@ nc_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
341346
variable in a file opened for parallel I/O will automatically
342347
switch the access for that variable to collective access.
343348
349+
@note The HDF5 manual has this to say about shuffle:
350+
351+
The shuffle filter de-interlaces a block of data by reordering
352+
the bytes. All the bytes from one consistent byte position of
353+
each data element are placed together in one block; all bytes
354+
from a second consistent byte position of each data element are
355+
placed together a second block; etc. For example, given three
356+
data elements of a 4-byte datatype stored as 012301230123,
357+
shuffling will re-order data as 000111222333. This can be a
358+
valuable step in an effective compression algorithm because the
359+
bytes in each byte position are often closely related to each
360+
other and putting them together can increase the compression
361+
ratio.
362+
363+
As implied above, the primary value of the shuffle filter lies
364+
in its coordinated use with a compression filter; it does not
365+
provide data compression when used alone. When the shuffle
366+
filter is applied to a dataset immediately prior to the use of a
367+
compression filter, the compression ratio achieved is often
368+
superior to that achieved by the use of a compression filter
369+
without the shuffle filter.
370+
344371
@param ncid NetCDF or group ID, from a previous call to nc_open(),
345372
nc_create(), nc_def_grp(), or associated inquiry functions such as
346373
nc_inq_ncid().

libdispatch/dvarinq.c

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,18 @@ nc_inq_varnatts(int ncid, int varid, int *nattsp)
255255
nattsp);
256256
}
257257

258-
/** \ingroup variables
259-
Learn the storage and deflate settings for a variable.
258+
/**
259+
\ingroup variables
260+
261+
Learn the shuffle and deflate settings for a variable.
262+
263+
Deflation is compression with the zlib library. Shuffle re-orders the
264+
data bytes to provide better compression (see nc_def_var_deflate()).
265+
266+
Deflation is only available for HDF5 files. For classic and other
267+
files, this function will return setting that indicate that deflation
268+
is not in use, and that the shuffle filter is not in use. That is:
269+
shuffle off, deflate off, and a deflate level of 0.
260270
261271
\param ncid NetCDF or group ID, from a previous call to nc_open(),
262272
nc_create(), nc_def_grp(), or associated inquiry functions such as
@@ -277,7 +287,6 @@ use, and deflate_levelp is provided, it will get a zero. (This
277287
behavior is expected by the Fortran APIs). \ref ignored_if_null.
278288
279289
\returns ::NC_NOERR No error.
280-
\returns ::NC_ENOTNC4 Not a netCDF-4 file.
281290
\returns ::NC_EBADID Bad ncid.
282291
\returns ::NC_ENOTVAR Invalid variable ID.
283292
\author Ed Hartnett, Dennis Heimbigner
@@ -289,8 +298,9 @@ nc_inq_var_deflate(int ncid, int varid, int *shufflep, int *deflatep, int *defla
289298
size_t nparams;
290299
unsigned int params[4];
291300
int deflating = 0;
292-
293-
int stat = NC_check_id(ncid,&ncp);
301+
int stat;
302+
303+
stat = NC_check_id(ncid,&ncp);
294304
if(stat != NC_NOERR) return stat;
295305
TRACE(nc_inq_var_deflate);
296306

@@ -299,6 +309,18 @@ nc_inq_var_deflate(int ncid, int varid, int *shufflep, int *deflatep, int *defla
299309
switch (stat) {
300310
case NC_ENOFILTER: deflating = 0; stat = NC_NOERR; break;
301311
case NC_NOERR: deflating = 1; break;
312+
case NC_ENOTNC4:
313+
/* As a special case, to support behavior already coded into user
314+
* applications, handle classic format files by reporting no
315+
* deflation. */
316+
if (shufflep)
317+
*shufflep = 0;
318+
if (deflatep)
319+
*deflatep = 0;
320+
if (deflate_levelp)
321+
*deflate_levelp = 0;
322+
return NC_NOERR;
323+
break;
302324
default: return stat;
303325
}
304326
if(deflatep) *deflatep = deflating;
@@ -637,16 +659,20 @@ Learn the szip settings of a variable.
637659
638660
This function returns the szip settings for a variable. To turn on
639661
szip compression, use nc_def_var_szip(). Szip compression is only
640-
available if HDF5 was built with szip support. The nc_def_var_filter
641-
function may also be used to set szip compression.
662+
available for netCDF/HDF5 files, and only if HDF5 was built with szip
663+
support.
642664
643-
If a variable is not using szip, then a zero will be passed back
644-
for both options_maskp and pixels_per_blockp.
665+
If a variable is not using szip, or if this function is called on a
666+
file that is not a HDF5 file, then a zero will be passed back for both
667+
options_maskp and pixels_per_blockp.
645668
646669
For more information on HDF5 and szip see
647670
https://support.hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetSzip
648671
and https://support.hdfgroup.org/doc_resource/SZIP/index.html.
649672
673+
The nc_def_var_filter function may also be used to set szip
674+
compression.
675+
650676
\param ncid NetCDF or group ID, from a previous call to nc_open(),
651677
nc_create(), nc_def_grp(), or associated inquiry functions such as
652678
nc_inq_ncid().
@@ -667,12 +693,10 @@ szip is not in use for this variable. \ref ignored_if_null.
667693
668694
\returns ::NC_NOERR No error.
669695
\returns ::NC_EBADID Bad ncid.
670-
\returns ::NC_ENOTNC4 Not a netCDF-4 file.
671696
\returns ::NC_ENOTVAR Invalid variable ID.
672697
\returns ::NC_EFILTER Filter error.
673698
674699
\author Ed Hartnett, Dennis Heimbigner
675-
676700
*/
677701
int
678702
nc_inq_var_szip(int ncid, int varid, int *options_maskp, int *pixels_per_blockp)
@@ -693,7 +717,9 @@ nc_inq_var_szip(int ncid, int varid, int *options_maskp, int *pixels_per_blockp)
693717
return NC_EFILTER; /* bad # params */
694718
break;
695719
case NC_ENOFILTER:
696-
/* If the szip filter is not in use, return 0 for both parameters. */
720+
case NC_ENOTNC4:
721+
/* If the szip filter is not in use, or if this is not a HDF5
722+
* file, return 0 for both parameters. */
697723
params[0] = 0;
698724
params[1] = 0;
699725
stat = NC_NOERR;

nc_test/tst_formats.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,27 @@ main(int argc, char **argv)
171171
int data = TEST_VAL_42;
172172
int data_in;
173173
int fill_value = TEST_VAL_42 * 2;
174+
int shuffle_in, deflate_in, deflate_level_in;
175+
int options_mask_in, pixels_per_block_in;
174176

175177
/* Try to set fill mode after data have been written. */
176178
sprintf(file_name, "%s_%d_%d_%d_elatefill.nc", FILE_NAME_BASE, format[f], d, a);
177179
if (nc_set_default_format(format[f], NULL)) ERR;
178180
if (nc_create(file_name, 0, &ncid)) ERR;
179181
if (nc_def_dim(ncid, DIM_NAME, DIM_LEN, &dimid)) ERR;
180182
if (nc_def_var(ncid, VAR_NAME, NC_INT, NDIM1, &dimid, &varid)) ERR;
183+
184+
/* There is no deflate on this var, and that is true in
185+
* all formats. */
186+
if (nc_inq_var_deflate(ncid, varid, &shuffle_in, &deflate_in,
187+
&deflate_level_in)) ERR;
188+
if (shuffle_in || deflate_in || deflate_level_in) ERR;
189+
190+
/* There is no szip on this var, and that is true in
191+
* all formats. */
192+
if (nc_inq_var_szip(ncid, varid, &options_mask_in, &pixels_per_block_in)) ERR;
193+
if (options_mask_in || pixels_per_block_in) ERR;
194+
181195
if (nc_enddef(ncid)) ERR;
182196
/* For netCDF-4, we don't actually have to write data to
183197
* prevent future setting of the fill value. Once the user
@@ -208,6 +222,18 @@ main(int argc, char **argv)
208222
if (ret != (a ? NC_ELATEDEF: NC_ELATEFILL)) ERR;
209223
}
210224
if (nc_enddef(ncid)) ERR;
225+
226+
/* There is (still!) no deflate on this var, and that
227+
* is true in all formats. */
228+
if (nc_inq_var_deflate(ncid, varid, &shuffle_in, &deflate_in,
229+
&deflate_level_in)) ERR;
230+
if (shuffle_in || deflate_in || deflate_level_in) ERR;
231+
232+
/* There is (still!) no szip on this var, and that is
233+
* true in all formats. */
234+
if (nc_inq_var_szip(ncid, varid, &options_mask_in, &pixels_per_block_in)) ERR;
235+
if (options_mask_in || pixels_per_block_in) ERR;
236+
211237
if (nc_close(ncid)) ERR;
212238

213239
/* Open the file and check data. */

0 commit comments

Comments
 (0)