Hi Karen,
Attached is the source code for ucnids. You can compile it with the
following command: gcc ucnids.c -o ucnids -lz
Let me know if you have any questions.
Best,
-Mike
*Mike Zuranski*
Data Engineer II
Unidata Program Center
University Corporation for Atmospheric Research
On Wed, Jan 4, 2023 at 8:59 AM Karen Cooper - NOAA Affiliate via ldm-users <
ldm-users@xxxxxxxxxxxxxxxx> wrote:
> Does anyone have an updated copy of ucnids that will decode the newer
> NEXRAD3 products?
>
> --
> *"Outside of a dog, a book is a man's best friend. Inside of a dog, it's
> too dark to read."*
> *--Groucho Marx*
>
> -------------------------------------------
> Karen.Cooper@xxxxxxxx
>
> Phone#: 405-325-6456
> Cell: 405-834-8559
> CIWRO/OU
> National Severe Storms Laboratory
>
> _______________________________________________
> NOTE: All exchanges posted to Unidata maintained email lists are
> recorded in the Unidata inquiry tracking system and made publicly
> available through the web. Users who post to any of the lists we
> maintain are reminded to remove any personal information that they
> do not want to be made public.
>
>
> ldm-users mailing list
> ldm-users@xxxxxxxxxxxxxxxx
> For list information or to unsubscribe, visit:
> https://www.unidata.ucar.edu/mailing_lists/
>
/********************************************************************
* ucnids - NIDS decompression utility for data compressed with zlib
*
* syntax: ucnids [options] ifile ofile
* ifile and ofile can be "-" to use standard input and output
* options:
* none - output uncompressed product with NOAAPORT CCB
* -c - output with standard WMO CCB
* -r - output with strippped WMO CCB (RPS output)
* -w - output with WXP-like WMO header
* -n - output stripping header and leaving raw NIDS data
********************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <zlib.h>
#include <sys/stat.h>
void mkdirs( char *path ){
int len;
int i;
len = strlen( path );
for( i = 1; i < len-1; i++ ){
if( path[i] == '/' ){
path[i] = 0;
mkdir( path, 0755 );
path[i] = '/';
}
}
}
int main( int argc, char **argv ){
FILE *ifile;
FILE *ofile;
unsigned char soh[101];
unsigned char seq[101];
unsigned char wmo[101];
unsigned char awip[101];
unsigned char inbuf[1000];
unsigned int insize;
unsigned char outbuf[10000];
z_stream zs;
int out;
int len;
int iret;
int off;
int i;
int verb;
int wxp;
int inbytes;
int outbytes;
int check;
int floc;
verb = 0;
off = 0;
while( 1 ){
if( argc > 1 && !strcmp( argv[1+off], "-v" )){
verb = 1;
off++;
}
else if( argc > 1+off && !strcmp( argv[1+off], "-c" )){
out = 1;
off++;
}
else if( argc > 1+off && !strcmp( argv[1+off], "-w" )){
out = 2;
off++;
}
else if( argc > 1+off && !strcmp( argv[1+off], "-n" )){
out = 3;
off++;
}
else if( argc > 1+off && !strcmp( argv[1+off], "-r" )){
out = 4;
off++;
}
else
break;
}
if( argc == 1+off || argv[1+off][0] == '-' )
ifile = stdin;
else
ifile = fopen( argv[1+off], "r" );
if( ifile == NULL ) exit( 1 );
if( argc < 3+off || argv[2+off][0] == '-' )
ofile = stdin;
else {
mkdirs( argv[2+off] );
ofile = fopen( argv[2+off], "w" );
if( !ofile ) exit( 1 );
}
fgets( soh, 100, ifile );
/*
Account for both raw input (0x01) and WXP input (**)
*/
wxp = 0;
off = 0;
check = ((soh[0] << 8 + soh[1]) % 31);
if( check == 0 ){
off = strlen( soh );
memcpy( inbuf, soh, off );
}
else if( soh[0] == '\n' ){
fgets( soh, 100, ifile );
len = strlen( soh )-7;
memcpy( wmo, soh+3, len );
wmo[len] = 0;
fgets( awip, 100, ifile );
wxp = 1;
}
else if( soh[0] == '*' ){
len = strlen( soh )-7;
memcpy( wmo, soh+3, len );
wmo[len] = 0;
fgets( awip, 100, ifile );
wxp = 1;
}
else if( soh[0] == 0x01 ){
fgets( seq, 100, ifile );
fgets( wmo, 100, ifile );
fgets( awip, 100, ifile );
}
iret = 0;
zs.total_out = 4000;
for( i = 0; i < 1000 && (iret != Z_STREAM_END || zs.total_out == 4000); i++
){
/*
Read in a block of data
*/
floc = ftell( ifile );
insize = fread( inbuf+off, 1, 1000-off, ifile );
if( verb ) fprintf( stderr, "Read: %X %d\n", floc, insize );
if( off == 0 && insize == 0 ) break;
inbytes+=insize;
len = insize + off;
/*
Check for 789C byte sequence denoting zlib compression
If data are not compressed, pass through raw data
*/
check = (((inbuf[0] << 8) + inbuf[1]) % 31);
//printf( "check %X %X %d\n", inbuf[0], inbuf[1], check );
if( i == 0 && check != 0 ){
if( wxp ){
if( out == 1 ){
fwrite( "\001\r\r\n001\r\r\n", 1, 10, ofile );
fprintf( ofile, "%18.18s\r\r\n", wmo );
}
else if( out == 2 ){
fprintf( ofile, soh );
fprintf( ofile, awip );
}
}
else {
if( out == 1 ){
fprintf( ofile, soh );
fprintf( ofile, seq );
fprintf( ofile, wmo );
fprintf( ofile, awip );
}
else if( out == 2 ){
fprintf( ofile, "** %18.18s ***\n%s", wmo, awip );
}
}
fwrite( inbuf, 1, insize, ofile );
while(( insize = fread( inbuf, 1, 1000, ifile )) > 0 ){
fwrite( inbuf, 1, insize, ofile );
}
exit( 0 );
}
if(( check == 0 && inbuf[0] == 0x78 && i < 5 )|| iret != Z_STREAM_END ){
zs.avail_in = len;
zs.avail_out = 10000;
zs.next_in = inbuf;
zs.next_out = outbuf;
/*
Check to see if 4000 byte block has been read and reinitialize
*/
if( i == 0 || iret == Z_STREAM_END ){
zs.zalloc = NULL;
zs.zfree = NULL;
inflateInit( &zs );
}
/*
Inflate NIDS data
*/
iret = inflate( &zs, Z_STREAM_END );
if( verb ) fprintf( stderr, "Inf: %d -- %d %d %d -- 10000 %d %d -- %2X
%2X -- %2X %2X\n",
iret, len, zs.avail_in, zs.total_in, zs.avail_out, zs.total_out,
inbuf[0], inbuf[1], outbuf[0], outbuf[1] );
off = zs.avail_in;
}
else {
memcpy( outbuf, inbuf, len );
zs.avail_out = 10000-len;
off = 0;
if( verb ) fprintf( stderr, "Cpy: %d - %2X %2X\n", len, inbuf[0],
inbuf[1] );
}
/*
Process header data for first block
WMO CCB output
*/
if( i == 0 && out == 1 ){
fwrite( "\001\r\r\n001\r\r\n", 1, 10, ofile );
fwrite( outbuf+24, 1, 10000-zs.avail_out-24, ofile );
}
/*
WXP header output
*/
else if( i == 0 && out == 2 ){
fprintf( ofile, "** %18.18s ***\n%s", wmo, awip );
fwrite( outbuf+54, 1, 10000-zs.avail_out-54, ofile );
}
/*
Raw NIDS output
*/
else if( i == 0 && out == 3 ){
fwrite( outbuf+54, 1, 10000-zs.avail_out-54, ofile );
outbytes+=10000-zs.avail_out-54;
}
/*
Stripped WMO CCB output
*/
else if( i == 0 && out == 4 ){
fwrite( outbuf+24, 1, 10000-zs.avail_out-24, ofile );
}
/*
Raw output with NOAAPORT CCB
*/
else {
fwrite( outbuf, 1, 10000-zs.avail_out, ofile );
outbytes+=10000-zs.avail_out;
}
/*
Move remaining data that still is compressed and prepared
for next inflate
*/
memcpy( inbuf, inbuf+len-off, off );
if( iret < 0 ) break;
}
exit( 0 );
}