[netcdfgroup] nccopy suggestion

Hello,

Our main use of the NetCDF 4 is to compress files and have the hability
to uncompress 'on the fly' while reading variables.
nccopy is a good utility to convert files from one format to another
(any conversion can be done provided we use the 'classic' scheme).

But nccopy cannot compress variable from ones in a netCDF 3 file (since
it has no 'deflate' attribute) which is our main goal for this utility
So I have created nccompress from nccopy which can do this:

    nccompress -d 1 -k 4 Infile.nc Outfile.nc

and all vars are compressed in a NetCDF4/HDF5 file (if -k is for a
classic file or a 64 bits file, -d is ignored).

I give you the patch to apply to nccopy.c if you are interested in this.
Maybe it is not the better way to do this (I have not filtered the no
dimension vars, for example) but it works.

Cheers,
Ph.P.
-- 
Philippe Poilbarbe
CLS - Space Oceanography Division.

--- nccopy.c    2010-07-21 16:04:50.000000000 +0200
+++ nccompress.c        2010-07-21 18:48:56.000000000 +0200
@@ -1,10 +1,17 @@
 /*********************************************************************
  *   Copyright 2008, University Corporation for Atmospheric Research
  *   See netcdf/README file for copying and redistribution conditions.
- *   $ID$
+ *   $Id$
  *********************************************************************/
 
-#include "config.h"            /* for USE_NETCDF4 macro */
+/*
+ * Adapted from nccopy with the ability to change compression level
+ * Ph.P. 2010/07/21
+ */
+
+/*#include "config.h"*/                /* for USE_NETCDF4 macro */
+/* config.h not here, Ph.P. */
+#define USE_NETCDF4
 #include <stdlib.h>
 #include <stdio.h>
 #ifndef _WIN32
@@ -32,6 +39,7 @@
 static char *progname;                 /* for error messages */
 static int nofill_flag = 1; /* default is not to fill, because fill
                             * values will be copied anyway */
+static int compress_level = -1;
 
 static void
 check(int err, const char* fcn, const char* file, const int line)
@@ -427,6 +435,11 @@
        stat = nc_inq_var_deflate(igrp, varid, 
                                  &shuffle, &deflate, &deflate_level);
        CHECK(stat, nc_inq_var_deflate);
+       if(compress_level >= 0)
+       {
+         deflate       = (compress_level <= 0 ? 0 : 1);
+         deflate_level = (compress_level <= 0 ? 0 : compress_level);
+       }
        if(deflate != 0 || shuffle != 0) {
            stat = nc_def_var_deflate(ogrp, o_varid, 
                                      shuffle, deflate, deflate_level);
@@ -453,6 +466,21 @@
     }
     return stat;
 }
+static int
+set_var_compressed(int igrp, int varid, int ogrp, int o_varid)
+{
+    int stat = NC_NOERR;
+    if (compress_level > 0)
+    {                          /* handle compression parameters */
+       int shuffle=NC_NOSHUFFLE, deflate, deflate_level;
+       deflate = 1;
+       deflate_level = compress_level;
+       stat = nc_def_var_deflate(ogrp, o_varid, 
+                                     shuffle, deflate, deflate_level);
+       CHECK(stat, nc_def_var_deflate);
+    }
+    return stat;
+}
 
 /* Release the variable chunk cache allocated for variable varid in
  * group igrp  with it.  This is not necessary, but will save some
@@ -639,6 +667,9 @@
             * chunking, endianness, deflation, checksumming, fill, etc. */
            stat = copy_var_specials(igrp, varid, ogrp, o_varid);
            CHECK(stat, copy_var_specials);
+       } else if ( (outkind == NC_FORMAT_NETCDF4 || outkind == 
NC_FORMAT_NETCDF4_CLASSIC)) {
+           stat = set_var_compressed(igrp, varid, ogrp, o_varid);
+           CHECK(stat, set_var_compressed);
        }
     }
 #endif /* USE_NETCDF4 */
@@ -949,6 +980,7 @@
 #define USAGE   "\
   [-k n]    kind of netCDF format for output file, default same as input\n\
            1 classic, 2 64-bit offset, 3 netCDF-4, 4 netCDF-4 classic model\n\
+  [-d n]    level of compression, default same as input (0=none 9=max)\n\
   [-m n]    size in bytes of copy buffer\n\
   infile    name of netCDF input file\n\
   outfile   name for netCDF output file\n"
@@ -1008,7 +1040,7 @@
        return 1;
     }
 
-    while ((c = getopt(argc, argv, "k:m:")) != EOF) {
+    while ((c = getopt(argc, argv, "k:d:m:")) != EOF) {
        switch(c) {
         case 'k': /* for specifying variant of netCDF format to be generated 
                      Possible values are:
@@ -1042,6 +1074,9 @@
                }
            }
            break;
+       case 'd':               /* non-default compression level */
+           compress_level = strtol(optarg, NULL, 10);
+           break;
        case 'm':               /* non-default size of data copy buffer */
            copybuf_size = strtoll(optarg, NULL, 10);
            break;
  • 2010 messages navigation, sorted by:
    1. Thread
    2. Subject
    3. Author
    4. Date
    5. ↑ Table Of Contents
  • Search the netcdfgroup archives: