Example #1
0
/*
 * HEADER:100:import_text:misc:1:read text file (X) for data
 */
int f_import_text(ARG1) {
    int ix, iy;
    unsigned int i;
    float t;

    if (mode == -1) {
        if ((*local = (void *) ffopen(arg1, "r")) == NULL) 
            fatal_error("import_text: Could not open %s", arg1);
        decode = 1; 
    }
    else if (mode >= 0) {
	if (header) {
	    if (fscanf((FILE *) *local, "%d %d", &ix, &iy) != 2) {
                fatal_error("import_text: Could not read nx, ny in file %s", arg1);
            }
	    if (nx != ix) {
                fatal_error_i("import_text: nx=%d is wrong",ix);
	    }
	    if (ny != iy) {
                fatal_error_i("import_text: ny=%d is wrong",iy);
	    }
	}
	for (i = 0; i < ndata; i++) {
	    if (fscanf((FILE *) *local, "%f", &t) != 1)
                fatal_error_i("import_text: Could not read data. location=%u",i+1);
	    data[i] = t;
        }
        use_scale = 0;
    }
    return 0;
}
Example #2
0
int f_import_bin(ARG1) {
    unsigned int i, j;
    if (mode == -1) {
        if ((*local = (void *) ffopen(arg1,"rb")) == NULL) {
            fatal_error("Could not open %s", arg1);
        }
        decode = 1;
    }
    if (mode >= 0) {
        if (header) {
            if (fread((void *) &i, sizeof(int), 1, (FILE *) *local) != 1)
                fatal_error("set_bin: read error header","");
            if (i != sizeof(float) * ndata)
                fatal_error_i("import_bin: trailer record size wrong, %u", i);
        }
        j = fread(data, sizeof(float), ndata, (FILE *) *local);
        if (j != ndata) fatal_error_i("import_bin: read error ndata = %u", i);
        if (header) {
            if (fread((void *) &i, sizeof(int), 1, (FILE *) *local) != 1)
                fatal_error("set_bin: read error trailer","");
            if (i != sizeof(float) * ndata)
                fatal_error_i("import_bin: trailer record size wrong, %u", i);
        }
        use_scale = 0;                  // new field, unknown scaling
    }
    return 0;
}
Example #3
0
int f_set_ijval(ARG3) {

    struct local_struct {
        int ix, iy;
	float val;
    };
    struct local_struct *save;

    int x,y;

    if (mode == -1) {
        decode = 1;
        *local = save = (struct local_struct *) malloc( sizeof(struct local_struct));
        if (save == NULL) fatal_error("memory allocation f_ijval","");

        save->ix = atoi(arg1) - 1;
        save->iy = atoi(arg2) - 1;
        save->val = atof(arg3);

	if (save->ix < 0) fatal_error_i("ijval: ix value (%d) should be >= 1", save->ix + 1);
	if (save->iy < 0) fatal_error_i("ijval: iy value (%d) should be >= 1", save->iy + 1);
    }
    if (mode < 0) return 0;
    save = *local;

    x = save->ix;
    y = save->iy;

    if (x < nx && y < ny) data[x + y*nx] = save->val;
    else fatal_error_ii("ijval: failed with problem with grid dimensions (%dx%d)",nx,ny);
    return 0;
}
Example #4
0
int rd_inventory(int *rec_num, int *submsg, long int *pos) {

    long int tmp;
    int c, i;

    /* format: [digits].[submessage]:[pos]: or digits]:[pos]: */

    i = 0;

    c=getchar();
    while (c == ' ') c = getchar();
    if (c == EOF) return 1;
    if (!isdigit((unsigned char) c)) {
	fatal_error_i("bad inventory on line: %d",*rec_num);
    }

    /* record number */
    while (isdigit((unsigned char) c) ) {
	i = 10*i + c - '0';
        c=getchar();
    }

    *rec_num = i;

    if (c == '.') {
        i = 0;
	while (isdigit((unsigned char) (c = getchar()) ) ) {
	    i = 10*i + c - '0';
	}
	*submsg = i;
    }
    else {
        *submsg = 1;
    }

    if (c != ':') fatal_error_i("bad inventory on line: %d",*rec_num);

    tmp = 0;
    while (isdigit((unsigned char) (c = getchar())) ) {
        tmp = 10*tmp + c - '0';
    }

    /* if (c != ':') fatal_error_i("bad inventory on line: %d",*rec_num); */

    /* read the rest of the line */
    while (c != EOF && c != '\n') {
	c = getchar();
    }
    *pos = tmp;
    return 0;
}
Example #5
0
int ffclose(FILE *flocal)
{
    struct opened_file *ptr, *last_ptr;

    if (flocal == stdin || flocal == stdout) return 0;		// do not close stdin or stdout

    last_ptr = NULL;
    ptr = opened_file_start;
    while (ptr != NULL) {
	if (ptr->handle == flocal) {
	    if (ptr->usage_count <= 0) fatal_error_i("ffclose: usage_count = %d <= 0, %d", ptr->usage_count);
	    if (--ptr->usage_count == 0) {   // usage_count is zero, can close file name
	        if (ptr->do_not_close_flag == 1) return 0;
		if (last_ptr == NULL)
		    opened_file_start = ptr->next;
		else {
		    last_ptr->next = ptr->next;
		}
		fclose(ptr->handle);
		free(ptr->name);
		free(ptr);
	    }
	    return 0;
	}
	last_ptr = ptr;
	ptr = ptr->next;
    }
    return 1;	/* not found */
}
Example #6
0
static unsigned int idx(int ix, int iy, int nx, int ny, int cyclic_grid) {
    int i;

    if (iy <= 0) fatal_error("index: iy <= 0","");
    if (iy > ny) fatal_error_i("index: iy = %d",iy);

    i = ix-1;
    if (cyclic_grid) {
        if (i < 0) i = nx - ( (-i) % nx );
        i = i % nx;
    }
    else {
        if (ix <= 0) fatal_error_i("index: ix=%d <= 0",ix);
        if (i >= nx) fatal_error_i("index: ix = %d",ix);
    }

    return (unsigned int) (i + (iy-1)*nx);
}
Example #7
0
int f_set_ijval(ARG3) {

    size_t i;
    long int tmp;
    struct local_struct {
        unsigned int ix, iy;
	float val;
    };
    struct local_struct *save;

    unsigned int x,y;

    if (mode == -1) {
        decode = 1;
        *local = save = (struct local_struct *) malloc( sizeof(struct local_struct));
        if (save == NULL) fatal_error("memory allocation f_ijval","");

	tmp = atol(arg1);
	if (tmp < 1) fatal_error_i("ijval: ix value (%d) should be >= 1", (int) tmp);
        save->ix = atol(arg1) - 1;

	tmp = atol(arg2);
	if (tmp < 1) fatal_error_i("ijval: iy value (%d) should be >= 1", (int) tmp);
        save->iy = atol(arg2) - 1;
        save->val = atof(arg3);

    }
    else if (mode == -2) {
	free(*local);
    }
    if (mode < 0) return 0;
    save = (struct local_struct *) *local;

    x = save->ix;
    y = save->iy;

    if (GDS_Scan_staggered(scan)) fatal_error("ijval: does not support staggered grid","");
    i = x + y * (size_t) nx;
    if (i < ndata) data[i] = save->val;
    else fatal_error_uu("ijval: failed with (%ux%u)",x,y);
    return 0;
}
Example #8
0
int f_set_date(ARG1) {

    int year, month, day, hour, minute, second, i, j, units, n;
    int code_4_11,idx;

    unsigned int dtime;

    if (mode < 0) return 0;

    reftime(sec, &year, &month, &day, &hour, &minute, &second);

    i=strlen(arg1);
    if (i < 4 || i % 2 == 1) fatal_error("set_date: bad date code %s",arg1); 

    i = sscanf(arg1,"%4d%2d%2d%2d%2d%2d" , &year, &month, &day, &hour, &minute, &second);
    if (i < 1) fatal_error("set_date: bad date code %s",arg1); 

    if (check_datecode(year, month, day) != 0 || hour < 0 || hour >= 24 ||
	minute < 0 || minute >= 60 || second < 0 || second >= 60) 
		fatal_error("set_date: bad date code %s",arg1);

    // set reference time
    save_time(year,month,day,hour,minute,second, sec[1]+12);

    idx =  stat_proc_n_time_ranges_index(sec);
    if (idx < 0) return 0;		// not a stat processed template
    n = (int) sec[4][idx];		// number of stat proc elements
    j = idx + 35 - 42;

    // add forecast time to time

    units = code_table_4_4(sec);
    dtime = forecast_time_in_units(sec);
    add_time(&year, &month, &day, &hour, &minute, &second, dtime, units);

    for (i = 0; i < n; i++) {
        // add statistical processing time to time
        code_4_11 = (int) sec[4][47-34+j+i*12];
        units = (int) sec[4][48-34+j+i*12];
        dtime = uint4(sec[4]+49-34+j+i*12);
        if (code_4_11 == 3 || code_4_11 == 4) continue;
        if (code_4_11 == 1 || code_4_11 == 2) {
	    add_time(&year, &month, &day, &hour, &minute, &second, dtime, units);
	}
        else {
	    fatal_error_i("set_date: code 4.11=%d is not supported", code_4_11);
	}
    }

    save_time(year,month,day,hour,minute,second, sec[4]+j);
    return 0;
}
Example #9
0
/*
 * HEADER:100:import_ieee:misc:1:read ieee file (X) for data
 */
int f_import_ieee(ARG1) {

    int i;

    if (mode == -1) {
        if ((*local = (void *) ffopen(arg1, "rb")) == NULL)
            fatal_error("import_ieee: Could not open %s", arg1);
        decode = 1;
    }
    else if (mode >= 0) {
	i = rdieee_file(data, ndata, header, (FILE *) *local);
        if (i) fatal_error_i("import_ieee, error %d", i);
        use_scale = 0;
    }
    return 0;
}
Example #10
0
void accel_set_func(glui32 index, glui32 addr)
{
    int bucknum;
    accelentry_t *ptr;
    int functype;
    acceleration_func new_func = NULL;

    /* Check the Glulx type identifier byte. */
    functype = Mem1(addr);
    if (functype != 0xC0 && functype != 0xC1) {
        fatal_error_i("Attempt to accelerate non-function.", addr);
    }

    if (!accelentries) {
        accelentries = (accelentry_t **)glulx_malloc(ACCEL_HASH_SIZE
                       * sizeof(accelentry_t *));
        if (!accelentries)
            fatal_error("Cannot malloc acceleration table.");
        for (bucknum=0; bucknum<ACCEL_HASH_SIZE; bucknum++)
            accelentries[bucknum] = NULL;
    }

    new_func = accel_find_func(index);
    /* Might be NULL, if the index is zero or not recognized. */

    bucknum = (addr % ACCEL_HASH_SIZE);
    for (ptr = accelentries[bucknum]; ptr; ptr = ptr->next) {
        if (ptr->addr == addr)
            break;
    }
    if (!ptr) {
        if (!new_func) {
            return; /* no need for a new entry */
        }
        ptr = (accelentry_t *)glulx_malloc(sizeof(accelentry_t));
        if (!ptr)
            fatal_error("Cannot malloc acceleration entry.");
        ptr->addr = addr;
        ptr->index = 0;
        ptr->func = NULL;
        ptr->next = accelentries[bucknum];
        accelentries[bucknum] = ptr;
    }

    ptr->index = index;
    ptr->func = new_func;
}
Example #11
0
int f_bin(ARG1) {
    unsigned int i, j;
    if (mode == -1) {
        if ((*local = (void *) ffopen(arg1, file_append ? "ab" : "wb")) == NULL) {
	    fatal_error("Could not open %s", arg1);
	}
        decode = 1;
    }
    else if (mode >= 0) {
        i = ndata * sizeof(float);
        if (header) fwrite((void *) &i, sizeof(int),1, (FILE *) *local);
        j = fwrite((void *) data, sizeof(float), ndata, (FILE *) *local);
	if (j != ndata) fatal_error_i("bin: error writing grid point written=%d", j);
        if (header) fwrite((void *) &i, sizeof(int),1, (FILE *) *local);
        if (flush_mode) fflush((FILE *) *local);
    }
    return 0;
}
int parse_1st_msg(unsigned char **sec) {

	unsigned char *p, *end_of_msg;
	int i;
 
	if (Msg == NULL) fatal_error("parse_1st_msg .. Msg == NULL","");

	Sec[0] = Msg;
	Sec[1] = Sec[2] = Sec[3] = Sec[4] = Sec[5] = Sec[6] = Sec[7] = 
	Sec6_bitmap = NULL;
	end_of_msg = Msg + GB2_MsgLen(Sec);

	p = Msg + 16;

	while (Sec[8] - p > 0) {
	    if (p[4] > 8) fatal_error_i("parse_1st_msg illegal section %d", (int) p[4]);
	    Sec[p[4]] = p;

	    /* Section 6: bitmap */
	    if (p[4] == 6) {
		if (p[5] == 0) {
		    Sec6_bitmap = p;
		}
		else if (p[5] >= 1 && p[5] <= 253) {
	            fatal_error("parse_1st_msg: predefined bitmaps are not handled","");
		}
		else if (p[5] == 254) {
	            fatal_error("parse_1st_msg: illegal grib msg, bitmap not defined code, table 6.0=254","");
		}
	    }

	    /* last section */
	    if (p[4] == 7) {
		for (i = 0; i < 9; i++) {
		    sec[i] = Sec[i];
		}
		return 0;
	    }
	    p += uint4(p);
	    if (p > end_of_msg) fatal_error("bad grib fill","");
	}
	fatal_error("parse_1st_msg illegally format grib","");
	return 1;
}
Example #13
0
int f_hybrid(ARG0) {
    int pdtsize, n, secsize, k;
    if (mode >= 0) {
	pdtsize =  prod_def_temp_size(sec);     // size of PDT with no extra vert coordinates
	secsize = GB2_Sec4_size(sec);		// size of PDT + vert coordinatese + extras
        n = uint2(&(sec[4][5]));                // number of vert coordinate values
	if (n % 2 != 0) fatal_error_i("vertical coordinate parameters should be in pairs, n=%d", n);
	if (n == 0) return 0;
	if (pdtsize + 4*n > secsize) 
	    fatal_error("not enough space allocated for vertical coordinate data","");
	sprintf(inv_out,"Hybrid levels=%d", n/2);
	inv_out += strlen(inv_out);
	for (k = 1; k <= n/2; k++) {
	    sprintf(inv_out," %d=(%9.6f,%9.6f)", k, (double) ieee2flt(sec[4]+pdtsize+k*8-8),
		(double) ieee2flt(sec[4]+pdtsize+k*8-4));
	    inv_out += strlen(inv_out);
	}
    }
    return 0;
}
Example #14
0
int f_ijsmall_grib(ARG3) {

    struct local_struct {
        FILE *out;
        int ix0, iy0, ix1, iy1;
    };
    struct local_struct *save;

    if (mode == -1) {
        decode = latlon = 1;

        *local = save = (struct local_struct *)malloc( sizeof(struct local_struct));
        if (save == NULL) fatal_error("ijsmall_grib  memory allocation ","");

        if (sscanf(arg1,"%d:%d", &(save->ix0), &(save->ix1)) != 2)
            fatal_error("ijsmall_grib: ix0:ix1 = %s?", arg1);
        if (sscanf(arg2,"%d:%d", &(save->iy0), &(save->iy1)) != 2)
            fatal_error("ijsmall_grib: iy0:iy1 = %s?", arg2);
        if ((save->out = ffopen(arg3, "wb")) == NULL)
            fatal_error("ijsmall_grib: could not open %s", arg3);
        if (save->iy0 <= 0) fatal_error_i("ijsmall_grib: iy0=%d <= 0", save->iy0);
        if (save->iy0 > save->iy1) fatal_error("ijsmall_grib: iy0 > iy1","");
        if (save->ix0 > save->ix1) fatal_error("ijsmall_grib: ix0 > ix1","");
    }
    else if (mode == -2) {
        save = (struct local_struct *) *local;
        ffclose(save->out);
        free(save);
    }
    else if (mode >= 0) {
        save = (struct local_struct *) *local;
        if (output_order != wesn) fatal_error("ijsmall_grib: data must be in we:sn order","");
        if (GDS_Scan_staggered(scan)) fatal_error("ijsmall_grib: does not work for staggered grids","");
        small_grib(sec,mode,data,lon,lat, ndata,save->ix0,save->ix1,save->iy0,save->iy1,save->out);
    }
    return 0;
}
Example #15
0
int rewind_file(const char *filename) {
    struct opened_file *ptr;
    int i;

    if (strncmp(filename,"@mem:",5) == 0) {
        i = atoi(filename+5);
        if (i < 0 || i >= N_mem_buffers || (i == 0 && filename[5] != '0')) {
            fatal_error_i("rewind_file: @mem:N  N from 0..%d", N_mem_buffers-1);
        }
        mem_buffer_pos[i] = 0;
        return 0;
    }

    ptr = opened_file_start;
    while (ptr != NULL) {
	if (strcmp(filename,ptr->name) == 0) {
            if (fseek(ptr->handle, 0L, SEEK_SET))
		fatal_error("rewind_file: failed (%s)", filename);
	    return 0;
	}
	ptr = ptr->next;
    }
    return 1;
}
Example #16
0
int main(int argc, char **argv) {

#else

int wgrib2(int argc, const char **argv) {

#endif


//WNE    FILE *in;
    struct seq_file in_file;
    unsigned char *msg, *sec[10];	/* sec[9] = last valid bitmap */
    long int last_pos;

    int file_arg, i, j, num_submsgs;
    int n_arg;
    unsigned int k, ndata;
    int err_4_3_count;
    float *data;
    double ref;
//    double *ddata, ref;

#ifdef USE_G2CLIB
    float missing_c_val_1, missing_c_val_2;
    g2int *bitmap, has_bitmap;
    g2float *g2_data;
    int ii;
#endif

    struct ARGLIST arglist[N_ARGLIST];
    int narglist;
    const char *new_argv[N_ARGLIST];
    void *local[N_ARGLIST];
    int has_inv_option, last_submsg;
    int err, new_GDS, center;
    unsigned char dscale[2];

    init_globals();
    init_inv_out();
    ndata = 0;
    err_4_3_count = 0;

    if (initial_call) {		/* only done 1st time */
	setup_user_gribtable();
//      jas_init();
//      gctpc initialiation
        init(-1,-1,"gctpc_error,txt", "gctpc_param.txt");
        initial_call = 0;
    }

    narglist = 0;
    dscale[0] = dscale[1] = 0;
    mode = 0;

    if (fopen_file(&(rd_inventory_input), "-", "r")) fatal_error("opening stdin for rd_inventory","");
    data = NULL;
//    ddata = NULL;

#ifdef CALLABLE_WGRIB2
    if (setjmp(fatal_err)) {
	fprintf(stderr,"*** arg list to wgrib2:");
	for (i=0; i < argc; i++) {
	    fprintf(stderr," %s", argv[i]);
	}
	fprintf(stderr,"\n\n");
	if (ndata && data != NULL) free(data);
	ndata=0;
        return 1;
    }
#endif

    /* no arguments .. help screen */
    if (argc == 1) {
	mode = -1;
	inv_out[0] = 0;
	f_h(call_ARG0(inv_out,NULL));
	// fprintf(inv_file, "%s\n", inv_out);
	i = strlen(inv_out);
	inv_out[i++] = '\n';
	inv_out[i] = '\0';
        fwrite_file(inv_out, 1, i, &inv_file);
	err_bin(1); err_string(1);
        return 8;
    }

    /* copy argv */

    for (i = 0; i < argc; i++) {
	new_argv[i] = argv[i];
    }

    /* scan for "inv" and input file */
    has_inv_option = 0;
    file_arg = 0;
    for (i = 1; i < argc; i++) {
	if (new_argv[i][0] != '-' || (strcmp(new_argv[i],"-") == 0) ) {
	    /* must be filename */
	    if (file_arg == 0) {
		file_arg = i;
		continue;
	    } else {
		fatal_error_ss("too many grib files .. 1st=%s 2nd=%s", new_argv[file_arg], new_argv[i]);
	    }
	}
	/* must be an option */
	for (j = 0; j < nfunctions; j++) {
	    if (strcmp(&(new_argv[i][1]),functions[j].name) == 0) {
	        if (functions[j].type == inv) has_inv_option = 1;
		i += functions[j].nargs;
                break;
            }
        }
	if (j == nfunctions) {
	    fatal_error("undefined option: %s", new_argv[i]);
	}
    }

    /* if no inv option, use default inventory .. put it at end */
    if (has_inv_option == 0) new_argv[argc++] = "-s";

    /* try opening the input file */
    in_file.file_type = NOT_OPEN;
    if (file_arg != 0) {
	fopen_file(&in_file, new_argv[file_arg],"rb");
    }

    /* "compile" options */
#ifdef DEBUG
    fprintf(stderr,"going to compile phase\n");
#endif
    for (i = 1; i < argc; i++) {

	/* if filename skip */
	if (new_argv[i][0] != '-' || (strcmp(new_argv[i],"-") == 0))  continue;

	/* must be an option */

	for (j = 0; j < nfunctions; j++) {
	    if (strcmp(&(new_argv[i][1]),functions[j].name) == 0) break;
	}
	if (j == nfunctions) fatal_error("unknown option %s", new_argv[i]);

        /* add to function argument list */
	arglist[narglist].fn = j;
	arglist[narglist].i_argc = i+1;

	if (functions[j].type == inv) has_inv_option = 1;

	i += functions[j].nargs;
	if (i >= argc) fatal_error("missing arguments option=%s",functions[j].name);
	narglist++;

    }
    if (has_inv_option == 0) fatal_error("missing arguments on last option","");

    /* initialize options,  mode = -1 */

#ifdef DEBUG
    fprintf(stderr,"going to init options,  narglist %d\n",narglist);
#endif

    for (j = 0; j < narglist; j++) {
	new_inv_out();	/* inv_out[0] = 0; */
	n_arg = functions[arglist[j].fn].nargs;
        err = 0;
#ifdef DEBUG
    fprintf(stderr,"going to init option %s\n", functions[arglist[j].fn].name);
#endif
        if (n_arg == 0) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j);
	else if (n_arg == 1) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc]);
	else if (n_arg == 2) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1]);
	else if (n_arg == 3) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],new_argv[arglist[j].i_argc+2]);
	else if (n_arg == 4) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]);
	else if (n_arg == 5) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
		new_argv[arglist[j].i_argc+4]);
	else if (n_arg == 6) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
		new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]);
	else if (n_arg == 7) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
		new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
		new_argv[arglist[j].i_argc+6]);
	else if (n_arg == 8) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
		new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
		new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]);

        // if(inv_out[0] != 0)  fprintf(inv_file, "%s", inv_out);
        if(inv_out[0] != 0) fwrite_file(inv_out, 1, strnlen(inv_out,INV_BUFFER), &inv_file);

        if (err) {
	    err_bin(1); err_string(1);
	    // cleanup
            return 8;
	}
    }

    /* error and EOF handlers have been initialized */
#ifdef DEBUG
    fprintf(stderr,"initial error and EOF handlers\n");
#endif

    if (has_inv_option == 0) fatal_error("missing arguments on last option","");
    if (in_file.file_type == NOT_OPEN) {
	if (file_arg == 0) fatal_error("no input file defined","");
	else fatal_error("missing input file %s", new_argv[file_arg]);
    }

    if (latlon == 1 && output_order_wanted != wesn) 
           fatal_error("latitude-longitude information is only available with -order we:sn","");

    if (input == inv_mode && (in_file.file_type != DISK && in_file.file_type != MEM)) 
	fatal_error("wgrib2 cannot random access grib input file","");

#ifdef DEBUG
    fprintf(stderr,"going to process data\n");
#endif

    msg_no = 1;
    inv_no = 0;
    len = pos = 0;
    submsg = 0;
    msg = NULL;

    last_pos = -1;
    last_submsg = -1;

    /* if dump mode .. position io stream */
    if (input == dump_mode) {
        while (msg_no < dump_msg) {
// //	    if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq(sec, in, &pos, &len, &num_submsgs);
//	    if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs);
//	    else if (in_file.file_type == DISK) msg = rd_grib2_msg(sec, in, &pos, &len, &num_submsgs);

	    msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs);
            if (msg == NULL) fatal_error_i("record %d not found", dump_msg);
            last_pos = pos;
            pos += len;
            msg_no++;
        }
#ifdef DEBUG
        printf("dump mode msg=%d\n", msg_no);
#endif
    }

    /* 
     * submsg = 0 .. beginning of unread record
     * submsg = i .. start at ith submsg
     * num_submsgs = number of submessages in grib message
     */

    /* inventory loop */ 

    for (;last_message == 0;) {

        /* need position and submessage number of message */
        if (input == inv_mode || input == dump_mode) {
            if (input == inv_mode) {
                if (rd_inventory(&msg_no,&submsg, &pos, &rd_inventory_input)) break;
		if (fseek_file(&in_file, pos,SEEK_SET) != 0) fatal_error("fseek_file failed","");
            }
            else if (input == dump_mode) {
                if (dump_msg == -1) break;
                submsg = dump_submsg;
                dump_msg = -1;
	    }

            if (pos != last_pos) {
// //	        if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq(sec, in, &pos, &len, &num_submsgs);
//	        if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs);
//		else if (in_file.file_type == DISK) msg = rd_grib2_msg(sec, in, &pos, &len, &num_submsgs);
	        msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs);
	        if (msg == NULL) {
                    fatal_error_i("grib message #%d not found", msg_no);
                    break;
                }
                last_pos = pos;
		last_submsg = -1;
            }

            if (pos == last_pos && submsg == last_submsg + 1) {
                /* read previous submessage */
		if (parse_next_msg(sec) != 0) {
                    fprintf(stderr,"\n*** grib message #%d.%d not found ***\n\n", msg_no, submsg);
                    break;
		}
            }
            else {
                /* need to get desired submessage into sec */
		if (parse_1st_msg(sec) != 0) {
                    fprintf(stderr,"\n*** grib message #%d.1 not found ***\n\n", msg_no);
                    break;
		}
                for (i = 2; i <= submsg; i++) {
		    if (parse_next_msg(sec) != 0) {
                        fprintf(stderr,"\n*** grib message #%d.%d not found ***\n\n", msg_no, i);
                        break;
                    }
		}
	    }
            last_submsg = submsg;
	}
        else if (input == all_mode) {
	    if (submsg == 0) {
// //	        if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq(sec, in, &pos, &len, &num_submsgs);
//	        if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs);
//		else if (in_file.file_type == DISK) msg = rd_grib2_msg(sec, in, &pos, &len, &num_submsgs);
	        msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs);
		if (msg == NULL) break;
                submsg = 1;
	    }
	    else if (submsg > num_submsgs) {
		pos += len;
                msg_no++;
// //	        if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq(sec, in, &pos, &len, &num_submsgs);
//	        if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs);
//		else if (in_file.file_type == DISK) msg = rd_grib2_msg(sec, in, &pos, &len, &num_submsgs);
	        msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs);
		if (msg == NULL) break;
                submsg = 1;
	    }
            if (submsg == 1) {
		if (parse_1st_msg(sec) != 0) {
		    fprintf(stderr,"illegal format: parsing 1st submessage\n");
		}
            }
            else {
		if (parse_next_msg(sec) != 0) {
                    fprintf(stderr,"illegal format: parsing submessages\n");
                }
	    }
	}
        if (only_submsg > 0 && only_submsg != submsg) {
	    submsg++;
	    continue;
	}

	if (for_mode) {
	    if (msg_no < for_start || msg_no > for_end || ((msg_no - for_start) % for_step) != 0) {
	        if (msg_no > for_end && input != inv_mode) last_message = 1;
		submsg++;
		continue;
	    }
	}

	/* move inv_no++ before match_inv is made */
	inv_no++;

        if (match || match_fs) {
	   inv_out[0] = 0;
	   if (num_submsgs > 1) {
	       sprintf(inv_out,"%d.%d:", msg_no, submsg);
	   }
           else {
	       sprintf(inv_out,"%d:", msg_no);
	   }

           f_match_inv(call_ARG0(inv_out+strlen(inv_out), NULL));

           if (is_match_fs(inv_out) != 0) {
              submsg++;
	      inv_no--;
              continue;
           }

#ifdef USE_REGEX
           if (is_match(inv_out) != 0) {
              submsg++;
	      inv_no--;
              continue;
           }
#endif

        }
	match_flag = 0;

        if (for_n_mode) {
            if (inv_no < for_n_start || inv_no > for_n_end || ((inv_no - for_n_start) % for_n_step) != 0) {
                if (inv_no > for_n_end) last_message = 1;
                submsg++;
                continue;
            }
        }

        /* see if new GDS */

	if ((i = (int) GB2_Sec3_size(sec)) != old_GDS_size) {
	    new_GDS = 1;
	}
	else {
	    new_GDS = 0;
	    for (j = 0; j < i; j++) {
		if (old_gds[j] != sec[3][j]) new_GDS = 1;
	    }
	}
	if (new_GDS) {
	    GDS_change_no++;
	    if (i > GDS_max_size) {
		if (GDS_max_size) free(old_gds);
		GDS_max_size = i + 100;		/* add 100 just to avoid excessive memory allocations */
    		if ((old_gds = (unsigned char *) malloc(GDS_max_size) ) == NULL) {
			fatal_error("memory allocation problem old_gds in wgrib2.main","");
		}
	    }
	    for (j = 0; j < i; j++) {
		old_gds[j] = sec[3][j];
            }
	    old_GDS_size = i;
	    /* update grid information */
            get_nxny(sec, &nx, &ny, &npnts, &res, &scan);	 /* get nx, ny, and scan mode of grid */
            get_nxny_(sec, &nx_, &ny_, &npnts, &res, &scan);	 /* get nx, ny, and scan mode of grid */

	    output_order = (nx_ < 1 || ny_ < 1) ? raw : output_order_wanted;

            if (latlon) {
		i = 1;

#ifdef USE_PROJ4
		if (use_proj4 && i != 0) {				/* use Proj4 to get lat lon values */
		    i = proj4_get_latlon(sec, &lon, &lat);
//		    if (i == 0) fprintf(stderr,"proj4_get_lat used\n");
		}
#endif

		if (use_gctpc && i != 0) {				/* use gctpc to get lat lon values */
		    i = gctpc_get_latlon(sec, &lon, &lat);
//		    if (i == 0) fprintf(stderr,"gctpc_get_lat used\n");
		}

		if (i != 0) get_latlon(sec, &lon, &lat);		 /* get lat lon of grid points using built-in code */
	    }
	}

	/* Decode NDFD WxText */
	if (WxText) mk_WxKeys(sec);

	// any fixes to raw grib message before decode need to be placed here
	if (fix_ncep_2_flag) fix_ncep_2(sec);
	if (fix_ncep_3_flag) fix_ncep_3(sec);
	if (fix_ncep_4_flag) fix_ncep_4(sec);

#ifdef CHECK
	j = code_table_5_0(sec);		// type of compression

	/* yes this can be simplified but want to split it up in case other decoders have problems */
	if (j == 0 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) 
		fprintf(stderr,"Warning: g2lib/g2clib/grib-api simple encode/decode may differ from WMO standard, use -g2clib 0 for WMO standard\n");
	if ((j == 2 || j == 3) && int2(sec[5]+17) != 0 && int4(sec[5] + 31) == 0 && ieee2flt(sec[5]+11) != 0.0) 
		fprintf(stderr,"Warning: g2lib/g2clib complex encode/decode may differ from WMO standard, use -g2clib 0 for WMO standard\n");
	if (j == 40 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) 
		fprintf(stderr,"Warning: g2lib/g2clib jpeg encode/deocde may differ from WMO standard, use -g2clib 0 for WMO standard\n");
	if (j == 41 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) 
		fprintf(stderr,"Warning: g2lib/g2clib/grib-api png encode/decode may differ from WMO standard, use -g2clib 0 for WMO standard\n");

	/* check the size of Section 7 */
	/* code to check the other sizes needs to be placed in decode routines */

	j = code_table_5_0(sec);		// type of compression
	if (j == 0) {		/* simple */
	    /* to avoid overflow on 32 bit machines */
	    /* old:  k = (GB2_Sec5_nval(sec) * sec[5][19] + 7) / 8 + 5; */
	    k = 5 + (GB2_Sec5_nval(sec)/8) * sec[5][19] +  (GB2_Sec5_nval(sec)%8) * (sec[5][19]/8)
	    	+ ( (GB2_Sec5_nval(sec)%8) * (sec[5][19]%8) + 7) / 8;

	    if (k != GB2_Sec7_size(sec)) {
		fprintf(stderr,"Detected a size mismatch, Section 7, wanted %d found %d\n", k, GB2_Sec7_size(sec));
		if (decode) fatal_error("Section 7 size, mismatch, simple packing","");
	    }
	}
	else if (j == 4) {		/* IEEE */
	    k = GB2_Sec5_nval(sec) * 4 + 5;
	    if (k != GB2_Sec7_size(sec)) {
		fprintf(stderr,"Detected a size mismatch, Section 7, wanted %d found %d\n", k, GB2_Sec7_size(sec));
		if (decode) fatal_error("Section 7 size, mismatch, IEEE packing","");
	    }
	}

	/* code table 4.3 can change units, warn if undefined */

	if (err_4_3_count < 2) {
	    if (code_table_4_3(sec) == 255) {
		fprintf(stderr,"** WARNING input Code Table 4.3 = 255 (undefined) **\n");
		err_4_3_count++;
	    }
        }
#endif

	if (decode) {

#ifdef CHECK
            if (code_table_6_0(sec) == 0) {                         // has bitmap
                k = GB2_Sec3_npts(sec) -  GB2_Sec5_nval(sec);
                if (k != missing_points(sec[6]+6, GB2_Sec3_npts(sec)))
                    fatal_error_uu("inconsistent number of bitmap points sec3-sec5: %u sec6: %u",
			k, missing_points(sec[6]+6, GB2_Sec3_npts(sec)));
            }
            else if (code_table_6_0(sec) == 255) {                  // no bitmap
                if (GB2_Sec3_npts(sec) != GB2_Sec5_nval(sec))
                    fatal_error_uu("inconsistent number of data points sec3: %u sec5: %u",
                        GB2_Sec3_npts(sec), GB2_Sec5_nval(sec));
            }
#endif

            /* allocate data */
            if (GB2_Sec3_npts(sec) != ndata) {
		if (ndata) free(data);
                ndata = GB2_Sec3_npts(sec);
		if (ndata) {
                    data = (float *) malloc(sizeof(float) * (size_t) ndata);
                    if (data == NULL) {
			ndata = 0;
			fatal_error("main: memory allocation failed data","");
		    }
		}
                else { data = NULL; }
            }

	    j = code_table_5_0(sec);		// type of compression

            /* USE G2CLIB */

#ifdef USE_G2CLIB
            if (use_g2clib == 2) {
                err = g2_getfld(msg,submsg,1,1,&grib_data);
                if (err != 0) fatal_error_ii("Fatal g2clib decode err=%d msg=%d", err, msg_no);
                free_gribfield = 1;

                has_bitmap = grib_data->ibmap;
                g2_data = &(grib_data->fld[0]);
                if (has_bitmap == 0 || has_bitmap == 254) {
                    bitmap = grib_data->bmap;
                    for (k = 0; k < ndata; k++) {
                         data[k] = (bitmap[k] == 0) ? UNDEFINED : g2_data[k];
                    }
                }
                else {
                    for (k = 0; k < ndata; k++) {
                        data[k] = g2_data[k];
                    }
                }

                /* complex packing uses special values for undefined */
                ii = sub_missing_values(sec, &missing_c_val_1, &missing_c_val_2);
                if (ii == 1) {
                    for (k = 0; k < ndata; k++) {
                        if (data[k] == missing_c_val_1) data[k] = UNDEFINED;
                    }
                }
                else if (ii == 2) {
                    for (k = 0; k < ndata; k++) {
                        if (data[k] == missing_c_val_1) data[k] = UNDEFINED;
                        if (data[k] == missing_c_val_2) data[k] = UNDEFINED;
                    }
                }
            }
#endif

            /* USE INTERNAL DECODER */

            if (use_g2clib != 2) {
                center = GB2_Center(sec);
                if (use_g2clib == 1) {	// introduce g2clib constant field error
		    /* g2clib ignores decimal scaling for constant fields make internal decoders look like g2clib*/
                    if ( (j == 0 && sec[5][19] == 0) || ((j == 2 || j == 3) && int4(sec[5] + 31) == 0) ||
                         (j == 40 && sec[5][19] == 0) || (j == 41 && sec[5][19] == 0) ||
                         (center == NCEP && j == 40000 && sec[5][19] == 0) || 
                         (center == NCEP && j == 40010 && sec[5][19] == 0)  ) {
			dscale[0] = sec[5][17];
			dscale[1] = sec[5][18];
			sec[5][17] = sec[5][18] = 0;
                    }
		}

		err = unpk_grib(sec, data);
                if (err != 0) fatal_error_i("Fatal decode packing type %d",err);

		if (use_g2clib == 1) {  // fix up data 
		    /* restore decimal scaling */
                    if ( (j == 0 && sec[5][19] == 0) || ((j == 2 || j == 3) && int4(sec[5] + 31) == 0) ||
                         (j == 40 && sec[5][19] == 0) || (j == 41 && sec[5][19]) ||
                         (center == NCEP && j == 40000 && sec[5][19] == 0) || 
                         (center == NCEP && j == 40010 && sec[5][19] == 0)  ) {
			sec[5][17] = dscale[0];
			sec[5][18] = dscale[1];
                    }
		}
            }

	    /* convert to standard output order we:sn */

	    if (output_order_wanted == wesn) to_we_sn_scan(data, scan, npnts, nx, ny, save_translation);
	    else if (output_order_wanted == wens) to_we_ns_scan(data, scan, npnts, nx, ny, save_translation);
	}
        else {
	    if (ndata) free(data);
            ndata = 0;
            data = NULL;
        }

	/* get scaling parameters */

	use_scale = input_scale = scaling(sec, &ref, &dec_scale, &bin_scale, &i) == 0;

	/* make sure msg_no:pos is put in inv_out so that -last will work */
	new_inv_out();	// inv_out[0] = 0;
	if (num_submsgs > 1) {
	    sprintf(inv_out, "%d.%d%s%ld", msg_no, submsg, ":", pos);
	}
        else {
	    sprintf(inv_out, "%d%s%ld", msg_no, ":", pos);
	}
        // fprintf(inv_file, "%s", inv_out);
        fwrite_file(inv_out, 1, strnlen(inv_out,INV_BUFFER), &inv_file);

	for (j = 0; j < narglist; j++) {

	    /* skip execution if match_flag == 1 */
	    /* an output option acts as endif for match_flag */
	    if (match_flag == 1) {
                if (functions[arglist[j].fn].type == output)  match_flag = 0;
		continue;
	    }


            // if (functions[arglist[j].fn].type == inv) fprintf(inv_file, "%s", item_deliminator);
            if (functions[arglist[j].fn].type == inv) fwrite_file(item_deliminator, 1, strlen(item_deliminator), &inv_file);
            if (functions[arglist[j].fn].type != setup) {
		new_inv_out();	// inv_out[0] = 0;
	        n_arg = functions[arglist[j].fn].nargs;
		if (n_arg == 0) 
                    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j);
		else if (n_arg == 1)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			 new_argv[arglist[j].i_argc]);
		else if (n_arg == 2)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1]);
		else if (n_arg == 3)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2]);
		else if (n_arg == 4)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]);
		else if (n_arg == 5)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4]);
		else if (n_arg == 6)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]);
		else if (n_arg == 7)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
			new_argv[arglist[j].i_argc+6]);
		else if (n_arg == 8)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
			new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]);

        	// if(inv_out[0] != 0)  fprintf(inv_file, "%s", inv_out);
        	if(inv_out[0] != 0) fwrite_file(inv_out, 1, strnlen(inv_out,INV_BUFFER), &inv_file);
           }
	}

#ifdef CHECK
	if (!decode) {
            if (code_table_6_0(sec) == 0) {                         // has bitmap
                k = GB2_Sec3_npts(sec) -  GB2_Sec5_nval(sec);
                if (k != missing_points(sec[6]+6, GB2_Sec3_npts(sec)))
                    fatal_error_uu("inconsistent number of bitmap points sec3-sec5: %u sec6: %u",
			k, missing_points(sec[6]+6, GB2_Sec3_npts(sec)));
            }
            else if (code_table_6_0(sec) == 255) {                  // no bitmap
                if (GB2_Sec3_npts(sec) != GB2_Sec5_nval(sec))
                    fatal_error_ii("inconsistent number of data points sec3: %d sec5: %d",
                        (int) GB2_Sec3_npts(sec), (int) GB2_Sec5_nval(sec));
            }
	}
#endif

	submsg++;

#ifdef USE_G2CLIB
	if (free_gribfield) { g2_free(grib_data); free_gribfield = 0;}
#endif

	// fprintf(inv_file, "%s",end_inv);
        fwrite_file(end_inv, 1, strlen(end_inv), &inv_file);

	if (flush_mode) fflush_file(&inv_file);
	if (dump_msg > 0) break;
    }

    /* finalize all functions, call with mode = -2 */

    err = 0;
    for (j = 0; j < narglist; j++) {
//        if (functions[arglist[j].fn].type != setup) {
	    n_arg = functions[arglist[j].fn].nargs;
	    new_inv_out();	// inv_out[0] = 0;
	    if (n_arg == 0) 
                err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j);
	    else if (n_arg == 1)
		err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc]);
	    else if (n_arg == 2)
		err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1]);
	    else if (n_arg == 3)
		err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2]);
	    else if (n_arg == 4)
		err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]);
	    else if (n_arg == 5)
		err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4]);
	    else if (n_arg == 6)
		err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]);
	    else if (n_arg == 7)
		err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
			new_argv[arglist[j].i_argc+6]);
	    else if (n_arg == 8)
		err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
			new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]);
            // if (inv_out[0]) fprintf(stderr, "%s\n", inv_out);
            if (inv_out[0]) fprintf(stderr, "%s%s", inv_out, end_inv);
//        }
    }
    err_bin(0); err_string(0);
    fclose_file(&in_file);
    if (ndata) {
	ndata = 0;
	free(data);
    }
    // return 0;
    return err;
}

void set_mode(int new_mode) {
	mode = new_mode;
}
unsigned char *rd_grib2_msg(FILE *input, long int *pos, unsigned long int *len, int *num_submsgs){

    unsigned long int len_grib;
    long int position, i;
    unsigned long int tmp;
    long int n_bytes;
    int j;
    unsigned char *p, *end_of_msg;
    /* setup grib buffer */
    if (buffer == NULL) {
        if ((buffer = (unsigned char *) malloc(BUFF_ALLOC0)) == NULL) {
	    fatal_error("not enough memory: rd_grib2_msg","");
	}
        buffer_size = BUFF_ALLOC0;
    }

    /* find Msg and length of message */
#ifdef DEBUG
    fprintf(stderr,"rd_grib2_msg: start looking at pos %ld\n", *pos);
#endif
    position = *pos;
    Msg = seek_grib2(input, &position, &len_grib, buffer, MSEEK, &n_bytes);
#ifdef DEBUG
    fprintf(stderr,"rd_grib2_msg: found at %ld .. n_bytes %ld\n", position, n_bytes);
#endif
    *pos = position;

    if (Msg == NULL) {
        *len = 0;
	return NULL;
    }

// for (i = 0; i <4; i++) fprintf(stderr," (%c) ", Msg[i]);

    /* read all whole grib record .. to save I/O time, add to end of buffer */

    if (len_grib + Msg - buffer > buffer_size) {
	tmp = Msg - buffer;
        buffer_size = len_grib + Msg - buffer + 5000;
        buffer = (unsigned char *) realloc((void *) buffer, buffer_size);
        if (buffer == NULL) fatal_error("rd_grib2_msg: ran out of memory","");
	Msg = buffer + tmp;
    }

    if (fseek(input, *pos+n_bytes-(Msg-buffer), SEEK_SET) == -1) {
        fatal_error("rd_grib2_msg seek, outside the file, bad grib file","");
    }

    i = len_grib + Msg - buffer - n_bytes; 	/* no. of bytes need to read */
    if (i > 0 && ((j=fread(buffer+n_bytes, sizeof (unsigned char), i, input)) != i))  {
        fatal_error("rd_grib2_msg, read outside of file, bad grib file","");
    }

// for (i = 0; i <4; i++) fprintf(stderr," (%c) ", Msg[i+len_grib-4]);

    Sec[8] = Msg + len_grib - 4;
    if (Sec[8][0] != 55 || Sec[8][1] != 55 || Sec[8][2] != 55 || Sec[8][3] != 55) {
        fatal_error("rd_grib2_msg, missing end section ('7777')","");
    }
    Sec[0] = Msg;

    /* scan message for number of submessages and perhaps for errors */
    p = Msg +  GB2_Sec0_size;
    end_of_msg = Msg + len_grib;

    i = 0;
    while (p < Sec[8]) {
#ifdef DEBUG
    fprintf(stderr,"rd_grib2_msg: section %d found\n", p[4]);
#endif
	if (p[4] == 7) i++;
	if (uint4(p) < 5) fatal_error_i("rd_grib2_msg: illegal grib: section length, section %i", p[4]);
	p += uint4(p);
	if (p > end_of_msg) fatal_error("bad grib format","");
    }
    if (p != Sec[8]) {
	fatal_error("rd_grib2_msg: illegal format, end section expected","");
    }
    *num_submsgs = i;

    *len = len_grib;
#ifdef DEBUG
    fprintf(stderr,"rd_grib2_msg: found at %ld .. len_grib %ld\n", position, len_grib);
#endif
    return Msg;
}
Example #18
0
int f_mysql_speed(ARG7) {

    char temp_pathname[STRING_SIZE];
    char sql[1500];
    char server[100];
    char user[100];
    char password[100]; 
    char database[100];
    char table[100];
    MYSQL_RES *res;
    MYSQL_ROW row;

    char name[100], desc[100], unit[100], level_buf[100];
    int year, month, day, hour, minute, second;
	
    char vt[20],rt[20];
//    unsigned char *p;
   		
    int i,j;
    double longitude,latitude,value;

    char new_level[50];
    char new_name[50];
    char conv[50];
    char precision[10];
    char last;
    char param[50];
    int ctr;
    int level;
    unsigned int load_local_infile;

    struct local_struct {
        MYSQL *conn;
        FILE *temp_fileptr;
        unsigned int npts;
        char *rows[MAX_NXNY];
	char has_value[MAX_NXNY];
        char *params;
        unsigned int isset;
        unsigned int wlon;
        unsigned int remove_unlikely;
        char runtime[20], validtime[20];
	int last_GDS_change_no;
    };
    struct local_struct *save;

    strcpy(server,arg1);
    strcpy(user,arg2);
    strcpy(password,arg3);
    strcpy(database,arg4);
    strcpy(table,arg5);

    /* initialization phase */

    if (mode == -1) {
        decode = latlon = 1;
        
	*local = save = (struct local_struct *) malloc( sizeof(struct local_struct));
	if (save == NULL) fatal_error("mysql_speed memory allocation ","");

        for (i = 0; i < MAX_NXNY; i++) {
	    save->rows[i] = NULL;
	    save->has_value[i] = 0;
	}
	save->last_GDS_change_no = 0;
	save->conn = mysql_init(NULL);
	save->temp_fileptr= NULL;
	save->params = (char *)  malloc(1500*sizeof(char));
	sprintf(save->params,"%s","");
	save->isset = 0;
	save->runtime[0] = 0;
	save->validtime[0] = 0;
	load_local_infile = 1;		// 1 = LOAD LOCAL INFILE,  0 = do not LOAD LOCAL INFILE

	if (sscanf(arg6,"%d", &save->wlon) != 1) {
            fatal_error("Argument 6, use western longitudes, has to be 0 or 1, error parsing %s", arg6);
        }
        if (sscanf(arg7,"%d", &save->remove_unlikely) != 1) {
            fatal_error("Argument 7, remove unlikely values, has to be 0 or 1, error parsing %s", arg7);
        }
	
	/* Set options for database */
	mysql_options(save->conn,MYSQL_OPT_LOCAL_INFILE, (char *) &load_local_infile);

	/* Connect to database */
	if (!mysql_real_connect(save->conn, server, user, password, database, 0, NULL, 0)) {
	   fatal_error("f_mysql_speed: could not connect to %s", mysql_error(save->conn));
	} 
	return 0;
    }

    /* cleanup phase */

    if (mode == -2) {
    	save = (struct local_struct *) *local;
    	
    	strcpy(temp_pathname, "/tmp/wgrib2_mysqlXXXXXX");
    	if ( -1 == (load_local_infile = mkstemp(temp_pathname)) ) {
	    fatal_error("f_mysql_speed: error making temporary filename","");
	}
	if ( !(save->temp_fileptr = fdopen(load_local_infile, "w")) ) {
	    fatal_error("f_mysql_speed: error making temporary filename","");
	}

    	fprintf(stdout, "Columns to insert: rt,vt,lat,lon%s\n", save->params);
    	fprintf(save->temp_fileptr,"rt,vt,lat,lon%s\n",save->params);
    	for (j = 0; j < save->npts; j++) {
	    if (save->has_value[j] == 1) fprintf(save->temp_fileptr,"%s\n",save->rows[j]);
	}
	fflush(save->temp_fileptr);
	sprintf(sql,"LOAD DATA LOCAL INFILE '%s' INTO TABLE %s FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\\n' IGNORE 1 LINES (rt,vt,lat,lon%s)",temp_pathname,table,save->params);
	printf("Inserting into database, table=%s \n",table);
	printf("%s\n",sql);
	/* send SQL query */
	if (mysql_query(save->conn, sql)) {	
	    fatal_error("f_mysql_speed: connection error %s", mysql_error(save->conn));
	}
	fclose(save->temp_fileptr);
	remove(temp_pathname);
    	mysql_close(save->conn);
    	return 0;
    }

    /* processing phase */

    save = (struct local_struct *) *local;
  	
//    if (new_GDS && save->isset == 0 ) {
    if ((save->last_GDS_change_no != GDS_change_no) && save->isset == 0 ) {
  	//save->npts = GB2_Sec3_npts(sec);
  	save->npts = ndata;
  	if (ndata > MAX_NXNY) fatal_error_i("f_mysql_speed: MAX_NXNY exceeded %d", MAX_NXNY);

	for (i = 0; i < ndata; i++) {
	    if (save->rows[i] == NULL) {
		save->rows[i] = (char *)  malloc(1500*sizeof(char));
		if (save->rows[i] == NULL) fatal_error("f_mysql_speed: memory allocation problem","");
	    }
	    save->rows[i][0] = '\0';
	}

	save->isset = 1;
//    } else if (new_GDS) {
    } else if (save->last_GDS_change_no != GDS_change_no) {
	fatal_error("f_mysql_speed, grid definition has to be the same for all fields","");
   }
   save->last_GDS_change_no = GDS_change_no;
 
    /*Collect runtime and validtime into vt and rt*/

    reftime(sec, &year, &month, &day, &hour, &minute, &second);
//  p = sec[1];
//  sprintf(rt, "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d", (p[12]<<8)+p[13], p[14],p[15],p[16],p[17],p[18]);
    sprintf(rt, "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d", year,month,day,hour,minute,second);

    if (verftime(sec, &year, &month, &day, &hour, &minute, &second) == 0) {
        sprintf(vt,"%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d", year,month,day,hour,minute,second);
    }
    /*Check that runtimes are equal and validtimes are equal*/
    if (save->runtime[0] != 0 && strcmp(save->runtime,rt) != 0) {
	fprintf(stderr, "Error, runtime has to be equal for all fields\n");
    }
    strcpy(save->runtime,rt);

    if (save->validtime[0] != 0 && strcmp(save->validtime,vt) != 0) {
	fprintf(stderr, "Error, validtime has to be equal for all fields\n");
    }
    strcpy(save->validtime,vt);
	
    /*Get levels, parameter name, description and unit*/
    // f_lev(mode, sec, data, ndata, level_buf, local);
    f_lev(call_ARG0(level_buf, NULL));
    //if (ndata != save->npts && save->npts>0) fprintf(stderr,"ERROR: fields do not contain equally many gridpoints, %d , %d \n",save->npts,ndata);
 	   
    if (strcmp(level_buf, "reserved") == 0) return(0);
    getName(sec, mode, NULL, name, desc, unit);
    fprintf(stderr,"Start processing of %s at %s, runtime=%s, validtime=%s \n", name, level_buf,rt,vt);

    ctr = GB2_Center(sec);

    sprintf(sql,"select * from wgrib2_parameter_mapping where center_id=%d and wgrib_param_name='%s' and wgrib_param_levelname='%s'", ctr, name, level_buf);
    fprintf(stderr,"SQL: %s\n", sql);
    if (mysql_query(save->conn, sql)) {	
	fatal_error("f_mysql_speed: mysql error %s", mysql_error(save->conn));
    }
    sprintf(new_level,"%s", "None");
    sprintf(conv,"%s", "None");
    sprintf(precision, "%s", "2");
    printf("\nCenter_id: %d \n", ctr);
    res = mysql_use_result(save->conn);
    while ( (row = mysql_fetch_row(res) ) != NULL) {
	printf("our_name: %s \n", row[3]);
	sprintf(new_name,"%s", row[3]);
	sprintf(new_level,"%s", row[4]);
	sprintf(conv,"%s", row[5]);
	sprintf(precision, "%s", row[6]);
    }

    printf("val_precision: %s \n", precision);
    printf("conversion: %s \n", conv);
    printf("our_levelname: %s \n", new_level);
	
    if (strcmp(new_level,"None") != 0) {
	fprintf(stderr,"Sets level %s as level %s\n", level_buf, new_level);
	sprintf(param, "%s_%s", new_name, new_level);
    } else {
	if (strcmp(level_buf,"surface") == 0) {
	    sprintf(param, "%s_0", name);
	} else {		
	    sscanf(level_buf,"%d %s", &level, &last);
 	    sprintf(param, "%s_%d", name, level);
	}
    }
	
    mysql_free_result(res);

    strcat(save->params,",");
    strcat(save->params,param);
	
    fprintf(stderr,"Gridpoints in data: %d\n", ndata);
    fprintf(stderr, "Gridpoints for insert: %d\n", save->npts);

    fprintf(stderr, "Remove unlikely: %d\n", save->remove_unlikely);
    fprintf(stderr, "Western longitudes: %d\n", save->wlon);

    for (j = 0; j < ndata; j++) {
	longitude = lon[j];
	if (longitude > 180 && save->wlon==1) longitude-=360;
	latitude = lat[j];
	value = data[j];
	if (save->remove_unlikely == 1 && value>0 && value<10e-8) value=0; 			
	if (save->remove_unlikely == 1 && (strcmp(name,"APCP")==0 || strcmp(name,"ASNOW")==0 || strcmp(name,"ACPCP")==0 ) && value==1) value=0;
	value = convunit(value, conv);
	if (strlen(save->rows[j]) < 2) 	{
	    if (!UNDEFINED_VAL(data[j])) {
		save->has_value[j] = 1;
		sprintf(save->rows[j],"\"%s\",\"%s\",%g,%g,%lg",rt,vt,latitude,longitude,value);
	    } else {
		sprintf(save->rows[j],"\"%s\",\"%s\",%g,%g,NULL",rt,vt,latitude,longitude);
	    }
	} else {
	    if (!UNDEFINED_VAL(data[j])) {
		save->has_value[j] = 1;
		sprintf(sql,",%lg",value);
	    } else {
		sprintf(sql,",NULL");
	    }
	    strcat(save->rows[j],sql);
	}

    }
    return 0;
}
Example #19
0
int unpk_complex(unsigned char **sec, float *data, unsigned int ndata) {

    unsigned int i, j, n;
    int k, nbits, ref_group_length;
    unsigned char *p, *d, *mask_pointer;
    double ref_val,factor_10, factor_2, factor;
    float missing1, missing2;
    int n_sub_missing;
    int pack, offset;
    unsigned clocation;
    unsigned int ngroups, ref_group_width, nbit_group_width, len_last, npnts;
    int nbits_group_len, group_length_factor;
    int *group_refs, *group_widths, *group_lengths, *group_offset, *udata;
    unsigned int *group_clocation, *group_location;

    int m1, m2, mask, last, penultimate;
    int extra_vals[2];
    int min_val;
    int ctable_5_4, ctable_5_6,  bitmap_flag, extra_octets;


    extra_vals[0] = extra_vals[1] = 0;
    pack = code_table_5_0(sec);
    if (pack != 2 && pack != 3) return 0;

    p = sec[5];
    ref_val = ieee2flt(p+11);
    factor_2 = Int_Power(2.0, int2(p+15));
    factor_10 = Int_Power(10.0, -int2(p+17));
    ref_val *= factor_10;
    factor = factor_2 * factor_10;
    nbits = p[19];
    ngroups = uint4(p+31);
    bitmap_flag = code_table_6_0(sec);
    ctable_5_6 = code_table_5_6(sec);

    if (pack == 3 && (ctable_5_6 != 1 && ctable_5_6 != 2)) 
	fatal_error_i("unsupported: code table 5.6=%d", ctable_5_6);

    extra_octets = (pack == 2) ? 0 : sec[5][48];

    if (ngroups == 0) {
	if (bitmap_flag == 255) {
            for (i = 0; i < ndata; i++) data[i] = ref_val;
            return 0;
        }
        if (bitmap_flag == 0 || bitmap_flag == 254) {
            mask_pointer = sec[6] + 6;
            mask = 0;
            for (i = 0; i < ndata; i++) {
                if ((i & 7) == 0) mask = *mask_pointer++;
                data[i] = (mask & 128) ?  ref_val : UNDEFINED;
                mask <<= 1;
            }
            return 0;
        }
        fatal_error("unknown bitmap", "");
    }

    ctable_5_4 = code_table_5_4(sec);
    ref_group_width = p[35];
    nbit_group_width = p[36];
    ref_group_length = uint4(p+37);
    group_length_factor = p[41];
    len_last = uint4(p+42);
    nbits_group_len = p[46];

#ifdef DEBUG
    fprintf(stderr,"ctable 5.4 %d ref_group_width %u nbit_group_width %u ref_group_length %u group_length_factor %d\n",
        ctable_5_4, ref_group_width, nbit_group_width, ref_group_length, group_length_factor);
    fprintf(stderr,"len_last %u nbit_group_len %u\n", len_last, nbits_group_len);
#endif

    npnts =  GB2_Sec5_nval(sec); 	// number of defined points
    n_sub_missing = sub_missing_values(sec, &missing1, &missing2);

    // allocate group widths and group lengths
    group_refs = (int *) malloc(sizeof (unsigned int) * (size_t) ngroups);
    group_widths = (int *) malloc(sizeof (unsigned int) * (size_t) ngroups);
    group_lengths = (int *) malloc(sizeof (unsigned int) * (size_t) ngroups);
    group_location = (unsigned int *) malloc(sizeof (unsigned int) * (size_t) ngroups);
    group_clocation = (unsigned int *) malloc(sizeof (unsigned int) * (size_t) ngroups);
    group_offset = (int *) malloc(sizeof (unsigned int) * (size_t) ngroups);
    udata = (int *) malloc(sizeof (unsigned int) * (size_t) npnts);
    if (group_refs == NULL || group_widths == NULL || group_lengths == NULL || 
	group_location == NULL || group_clocation == NULL || group_offset == NULL
	|| udata == NULL) fatal_error("unpk_complex: memory allocation","");

    // read any extra values
    d = sec[7]+5;
    min_val = 0;
    if (extra_octets) {
	extra_vals[0] = uint_n(d,extra_octets);
	d += extra_octets;
	if (ctable_5_6 == 2) {
	    extra_vals[1] = uint_n(d,extra_octets);
	    d += extra_octets;
	}
	min_val = int_n(d,extra_octets);
	d += extra_octets;
    }

    if (ctable_5_4 != 1) fatal_error_i("internal decode does not support code table 5.4=%d",
		ctable_5_4);

#pragma omp parallel
{
#pragma omp sections
    {
    

#pragma omp section
        {
           // read the group reference values
   	   rd_bitstream(d, 0, group_refs, nbits, ngroups);
	}


#pragma omp section
	{
	    unsigned int i;
	    // read the group widths

	    rd_bitstream(d+(nbits*ngroups+7)/8,0,group_widths,nbit_group_width,ngroups);
	    for (i = 0; i < ngroups; i++) group_widths[i] += ref_group_width;
	}


#pragma omp section
	{
	    unsigned int i;
	    // read the group lengths

	    if (ctable_5_4 == 1) {
		rd_bitstream(d+(nbits*ngroups+7)/8+(ngroups*nbit_group_width+7)/8,
		0,group_lengths, nbits_group_len, ngroups-1);

		for (i = 0; i < ngroups-1; i++) {
		    group_lengths[i] = group_lengths[i] * group_length_factor + ref_group_length;
		}
		group_lengths[ngroups-1] = len_last;
	    }
	}

    }


#pragma omp single
    {
        d += (nbits*ngroups + 7)/8 +
             (ngroups * nbit_group_width + 7) / 8 +
             (ngroups * nbits_group_len + 7) / 8;

	// do a check for number of grid points and size
	clocation = offset = n = j = 0;
    }

#pragma omp sections
    {


#pragma omp section
        {
	    unsigned int i;
            for (i = 0; i < ngroups; i++) {
	        group_location[i] = j;
	        j += group_lengths[i];
	        n += group_lengths[i]*group_widths[i];
            }
        }

#pragma omp section
	{
	    unsigned int i;
            for (i = 0; i < ngroups; i++) {
	        group_clocation[i] = clocation;
	        clocation = clocation + group_lengths[i]*(group_widths[i]/8) +
	              (group_lengths[i]/8)*(group_widths[i] % 8);
            }
        }

#pragma omp section
        {
	    unsigned int i;
            for (i = 0; i < ngroups; i++) {
	        group_offset[i] = offset;
	        offset += (group_lengths[i] % 8)*(group_widths[i] % 8);
	    }
        }
    }
}

    if (j != npnts) fatal_error_u("bad complex packing: n points %u",j);
    if (d + (n+7)/8 - sec[7] != GB2_Sec7_size(sec))
        fatal_error("complex unpacking size mismatch old test","");


    if (d + clocation + (offset + 7)/8 - sec[7] != GB2_Sec7_size(sec)) fatal_error("complex unpacking size mismatch","");

#pragma omp parallel for private(i) schedule(static)
    for (i = 0; i < ngroups; i++) {
	group_clocation[i] += (group_offset[i] / 8);
	group_offset[i] = (group_offset[i] % 8);

	rd_bitstream(d + group_clocation[i], group_offset[i], udata+group_location[i], 
		group_widths[i], group_lengths[i]);
    }

    // handle substitute, missing values and reference value
    if (n_sub_missing == 0) {
#pragma omp parallel for private(i,k,j)
	for (i = 0; i < ngroups; i++) {
	    j = group_location[i];
	    for (k = 0; k < group_lengths[i]; k++) {
		udata[j++] += group_refs[i];
	    }
	}
    }
    else if (n_sub_missing == 1) {

#pragma omp parallel for private(i,m1,k,j)
	for (i = 0; i < ngroups; i++) {
	    j = group_location[i];
	    if (group_widths[i] == 0) {
	        m1 = (1 << nbits) - 1;
		if (m1 == group_refs[i]) {
		    for (k = 0; k < group_lengths[i]; k++) udata[j++] = INT_MAX;
		}
		else {
		    for (k = 0; k < group_lengths[i]; k++) udata[j++] += group_refs[i];
		}
	    }
	    else {
	        m1 = (1 << group_widths[i]) - 1;
	        for (k = 0; k < group_lengths[i]; k++) {
		    if (udata[j] == m1) udata[j] = INT_MAX;
		    else udata[j] += group_refs[i];
		    j++;
		}
	    }
	}
    }
    else if (n_sub_missing == 2) {
#pragma omp parallel for private(i,j,k,m1,m2)
	for (i = 0; i < ngroups; i++) {
	    j = group_location[i];
	    if (group_widths[i] == 0) {
	        m1 = (1 << nbits) - 1;
	        m2 = m1 - 1;
		if (m1 == group_refs[i] || m2 == group_refs[i]) {
		    for (k = 0; k < group_lengths[i]; k++) udata[j++] = INT_MAX;
		}
		else {
		    for (k = 0; k < group_lengths[i]; k++) udata[j++] += group_refs[i];
		}
	    }
	    else {
	        m1 = (1 << group_widths[i]) - 1;
	        m2 = m1 - 1;
	        for (k = 0; k < group_lengths[i]; k++) {
		    if (udata[j] == m1 || udata[j] == m2) udata[j] = INT_MAX;
		    else udata[j] += group_refs[i];
		    j++;
		}
	    }
	}
    }

    // post processing

	if (pack == 3) {
	    if (ctable_5_6 == 1) {
		last = extra_vals[0];
		i = 0;
		while (i < npnts) {
		    if (udata[i] == INT_MAX) i++;
		    else {
			udata[i++] = extra_vals[0];
			break;
		    }
		}
		while (i < npnts) {
		    if (udata[i] == INT_MAX) i++;
		    else {
			udata[i] += last + min_val;
			last = udata[i++];
		    }
		}
	    }
	    else if (ctable_5_6 == 2) {
		penultimate = extra_vals[0];
		last = extra_vals[1];

		i = 0;
		while (i < npnts) {
		    if (udata[i] == INT_MAX) i++;
		    else {
			udata[i++] = extra_vals[0];
			break;
		    }
		}
		while (i < npnts) {
		    if (udata[i] == INT_MAX) i++;
		    else {
			udata[i++] = extra_vals[1];
			break;
		    }
		}
	        for (; i < npnts; i++) {
		    if (udata[i] != INT_MAX) {
			udata[i] =  udata[i] + min_val + last + last - penultimate;
			penultimate = last;
			last = udata[i];
		    }
		}
	    }
	    else fatal_error_i("Unsupported: code table 5.6=%d", ctable_5_6);
	}

	// convert to float

	if (bitmap_flag == 255) {
#pragma omp parallel for schedule(static) private(i)
	    for (i = 0; i < ndata; i++) {
		data[i] = (udata[i] == INT_MAX) ? UNDEFINED : 
			ref_val + udata[i] * factor;
	    }
	}
        else if (bitmap_flag == 0 || bitmap_flag == 254) {
	    n = 0;
	    mask = 0;
            mask_pointer = sec[6] + 6;
            for (i = 0; i < ndata; i++) {
                if ((i & 7) == 0) mask = *mask_pointer++;
		if (mask & 128) {
		    if (udata[n] == INT_MAX) data[i] = UNDEFINED;
		    else data[i] = ref_val + udata[n] * factor;
		    n++;
		}
		else data[i] = UNDEFINED;
		mask <<= 1;
            }
        }
        else fatal_error_i("unknown bitmap: %d", bitmap_flag);

	free(group_refs);
	free(group_widths);
	free(group_lengths);
	free(group_location);
	free(group_clocation);
	free(group_offset);
	free(udata);

    return 0;
}
Example #20
0
File: geo.c Project: mmase/wgrib2
int gauss2ll(unsigned char **sec, double **llat, double **llon) {
 
 
    int nlat; /* in grib, number of latitudes must be even! */
  
    double dx, e, w, south, north, lat1, lon1, lat2, lon2, *ylat;
    int isouth, inorth;
    double units;
    double *lat, *lon;
    int basic_ang, sub_ang;
    int i,j, n;
    unsigned int k;
    unsigned char *gds;

    int nnx, nny, nres, nscan;
    unsigned int nnpnts;

    get_nxny(sec, &nnx, &nny, &nnpnts, &nres, &nscan);

    gds = sec[3];
    nlat = 2 * GDS_Gaussian_nlat(gds);

    /* figure out angle units */

    basic_ang = GDS_Gaussian_basic_ang(gds);
    sub_ang = GDS_Gaussian_sub_ang(gds);
    units = basic_ang == 0 ? 0.000001 : (double) basic_ang / (double) sub_ang;

    lat1 = GDS_Gaussian_lat1(gds) * units;
    lat2 = GDS_Gaussian_lat2(gds) * units;
    lon1 = GDS_Gaussian_lon1(gds) * units;
    lon2 = GDS_Gaussian_lon2(gds) * units;

    if (lon1 < 0.0 || lon2 < 0.0 || lon1 > 360.0 || lon2 > 360.0) fatal_error("BAD GDS lon","");
    if (lat1 < -90.0 || lat2 < -90.0 || lat1 > 90.0 || lat2 > 90.0) fatal_error("BAD GDS lat","");

    /* find S latitude and dy */
    if (GDS_Scan_y(nscan)) {
        south = lat1;
        north = lat2;
    }
    else {
        south = lat2;
        north = lat1;
    }
    if (south > north) fatal_error("gaussian grid: lat1 and lat2 inconsistent with scan order","");

    if (nny == -1) {
        fprintf(stderr,"Sorry code does not handle variable ny yet\n");
        return 0;
    }

    if (nny > nlat || nny < 0) fatal_error_i("gauss2ll: bad ny %d",nny);

    if ((*llat = (double *) malloc(nnpnts * sizeof(double))) == NULL) {
        fatal_error("gauss2ll memory allocation failed","");
    }
    if ((*llon = (double *) malloc(nnpnts * sizeof(double))) == NULL) {
        fatal_error("gauss2ll memory allocation failed","");
    }
    lat = *llat;
    lon = *llon;

    /* do latitudes first */
 
    ylat = (double *) malloc(sizeof(double) * nlat);

    /* calculate Gaussian latitudes */
    gauss2lats(nlat, ylat);

    /* find index of south and north */
    isouth = inorth = -1;
    for (i = 0; i < nlat; i++) {
	if (fabs(south - ylat[i]) < LATERR) {
	    isouth = i;
	    break;
	}
    }
    for (i = 0; i < nlat; i++) {
	if (fabs(north - ylat[i]) < LATERR) {
	    inorth = i;
	    break;
	}
    }

    if (isouth < 0 || inorth < 0) fatal_error("gauss2ll: lat1/lat2 not a Gaussian latitude","");
    if (inorth - isouth + 1 != nny) fatal_error("gauss2ll: lat1/lat2 not consistent with ny","");

    n = 0;
    if (nnx >= 0) {        /* regular grid */

#pragma omp parallel for private(i,j)
	for (j = 0; j < nny; j++) {
            for (i = 0; i < nnx; i++) {
                lat[i+j*nnx] = ylat[j+isouth];
            }
        }
    }
    else {                /* quasi regular grid */
        for (j = 0; j < nny; j++) {
            for (i = 0; i < variable_dim[j];  i++) {
                lat[n++] = ylat[j+isouth];
            }
        }
    }

    free(ylat); 

    /* now for the longitudes */
  
    if (GDS_Scan_x(nscan)) {
        e = lon1;
        w = lon2;
    }
    else {
        e = lon2;
        w = lon1;
    }
    if (e > w) w += 360.0;
    if (e < 0.0) {
        e += 360.0;
        w += 360.0;
    }
    if (e >= 360.0) {
        e -= 360.0;
        w -= 360.0;
    }

    if (nnx >= 0) {
        dx = (w-e) / (nnx-1);

#pragma omp parallel
{
#pragma omp for private(i)
	for (i = 0; i < nnx; i++) {
            lon[i] = e + (dx * i) >= 360.0 ?  e + (dx * i) - 360.0 : e + (dx * i);  
	}
#pragma omp for private(i,j)
	for (j = 1; j < nny; j++) {
	    for (i = 0; i < nnx; i++) {
		lon[i+j*nnx] = lon[i];
	    }
	}
}
    }
    else {
        n = 0;
        for (j = 0; j < nny; j++) {
            dx = (w-e) / (variable_dim[j]-1);
            for (i = 0; i < variable_dim[j]; i++) {
                lon[n++] = e + (dx * i) >= 360.0 ?  e + (dx * i) - 360.0 : e + (dx * i);
            }
        }
    }
    return 0;
} /* end gauss2ll() */
Example #21
0
int f_cress_lola(ARG4) {

    int n, nx, ny, nxny, ix, iy, i, j, k, m, iradius;
    double x0,dx, y0,dy, x, y, z, r_sq, sum;
    unsigned char *new_sec[8];
    double *cos_lon, *sin_lon, s, c, tmp, *tmpv, *inc, *wt;
    float *background;

    struct local_struct {
        int nlat, nlon, nRadius;
        double lat0, lon0, dlat, dlon, latn, lonn;
        FILE *out;
	int last_GDS_change_no;
	double Radius[MAX_SCANS];
	double R_earth;
        double *in_x, *in_y, *in_z;
        double *out_x, *out_y, *out_z;
	char *mask;
    };
    struct local_struct *save;

    /* initialization phase */

    if (mode == -1) {
        decode = latlon = 1;	/* request decode of data, lat and lon */

        *local = save = (struct local_struct *) malloc( sizeof(struct local_struct));
        if (save == NULL) fatal_error("cress_lola memory allocation ","");

	/* parse command line arguments */

        if (sscanf(arg1,"%lf:%d:%lf", &x0, &nx, &dx) != 3)
            fatal_error("cress_lola parsing longitudes lon0:nx:dlon  %s", arg1);

        if (dx < 0) fatal_error("cress_lola: dlon < 0", "");
        if (nx <= 0) fatal_error_i("cress_lola: bad nlon %d", nx);
        if (x0 < 0.0) x0 += 360.0;
        if (x0 < 0.0 || x0 >= 360.0) fatal_error("cress_lola: bad initial longitude","");
        save->nlon = nx;
        save->lon0 = x0;
        save->dlon = dx;
        save->lonn = x0 + (nx-1) * dx;

        if (sscanf(arg2,"%lf:%d:%lf", &y0, &ny, &dy) != 3) 
            fatal_error("cress_lola parsing latitudes lat0:nx:dlat  %s", arg2);

        if (dy < 0) fatal_error("cress_lola: dlat < 0","");
        if (ny <= 0) fatal_error_i("cress_lola: bad nlat %d", ny);
        save->nlat = ny;
        save->lat0 = y0;
        save->dlat = dy;
        save->latn = y0 + (ny-1)*dy;
        if (save->latn > 90.0 || save->lat0 < -90.0) fatal_error("cress_lola: bad latitude","");
        nxny = nx*ny;

        if ((save->out = ffopen(arg3,file_append ? "ab" : "wb")) == NULL) 
              fatal_error("cress_lola could not open file %s", arg3);

	iradius = 0;
	save->mask = NULL;
	k = sscanf(arg4, "%lf%n", &tmp, &m);
        while (k == 1) {
            if (iradius >= MAX_SCANS) fatal_error("cres_lola: too many radius parameters","");
            save->Radius[iradius++] = tmp;
	    if (tmp < 0.0 && save->mask == NULL) {
		save->mask = (char *) malloc(nxny * sizeof(char));
		if (save->mask == NULL) fatal_error("cress_lola memory allocation ","");
	    }
            arg4 += m;
            k = sscanf(arg4, ":%lf%n", &tmp, &m);
	}
	save->nRadius = iradius;

fprintf(stderr,"nRadius=%d nx=%d ny=%d\n",save->nRadius, nx, ny);

	save->out_x = (double *) malloc(nxny * sizeof(double));
	save->out_y = (double *) malloc(nxny * sizeof(double));
	save->out_z = (double *) malloc(nxny * sizeof(double));
	if (save->out_x == NULL || save->out_y == NULL || save->out_z == NULL) 
		fatal_error("cress_lola: memory allocation","");

	save->in_x = save->in_y = save->in_z = NULL;
	save->last_GDS_change_no = 0;

	/* out_x, out_y, out_z have the 3-d coordinates of the lola grid */

	cos_lon = (double *) malloc(nx * sizeof(double));
	sin_lon = (double *) malloc(nx * sizeof(double));
	if (cos_lon == NULL || sin_lon == NULL) fatal_error("cress_lola: memory allocation","");
	for (i = 0; i < nx; i++) {
	    x = (x0 + i*dx) * (M_PI / 180.0);
	    cos_lon[i] = cos(x);
	    sin_lon[i] = sin(x);
	}

        for (k = j = 0; j < ny; j++) {
	    y = (y0 + j*dy) * (M_PI / 180.0);
            s = sin(y);
            c = sqrt(1.0 - s * s);
	    for (i = 0; i < nx; i++) {
                save->out_z[k] = s;
                save->out_x[k] = c * cos_lon[i];
                save->out_y[k] = c * sin_lon[i];
		k++;
	    }
	}
	free(cos_lon);
	free(sin_lon);
        return 0;
    }

    save = (struct local_struct *) *local;
    if (mode == -2) {
	ffclose(save->out);
        return 0;
    }

    /* processing phase */
fprintf(stderr,">>processing\n");

    nx = save->nlon;
    ny = save->nlat;
    nxny = nx*ny;

    background = (float *) malloc(nxny * sizeof(float));
    tmpv = (double *) malloc(nxny * sizeof(double));
    inc = (double *) malloc(nxny * sizeof(double));
    wt = (double *) malloc(nxny * sizeof(double));
    if (background == NULL || tmpv == NULL || wt == NULL || inc == NULL) fatal_error("cress_lola: memory allocation","");

    /* Calculate x, y and z of input grid if new grid */
    if (save->last_GDS_change_no != GDS_change_no || save->in_x == NULL) {
	save->last_GDS_change_no = GDS_change_no;
        if (lat == NULL || lon == NULL || data == NULL) fatal_error("cress_lola: no lat, lon, or data","");

	save->R_earth  =  radius_earth(sec);

	if (save->in_x) free(save->in_x);
	if (save->in_y) free(save->in_y);
	if (save->in_z) free(save->in_z);

	save->in_x = (double *) malloc(npnts * sizeof(double));
	save->in_y = (double *) malloc(npnts * sizeof(double));
	save->in_z = (double *) malloc(npnts * sizeof(double));
	if (save->in_x == NULL || save->in_y == NULL || save->in_z == NULL)
	    fatal_error("cress_lola: memory allocation","");

	for (i = 0; i < npnts; i++) {
	    tmp = lon[i];
	    if (tmp < save->lon0) tmp += 360.0;
	    if (lat[i] >= 999.0 || lat[i] > save->latn || lat[i] < save->lat0 || tmp > save->lonn) {
		save->in_x[i] = 999.9;
	    }
	    else {
                s = sin(lat[i] * (M_PI / 180.0));
                c = sqrt(1.0 - s * s);
                save->in_z[i] = s;
                save->in_x[i] = c * cos(lon[i] * (M_PI / 180.0));
                save->in_y[i] = c * sin(lon[i] * (M_PI / 180.0));
            }
        }
fprintf(stderr,"done new gds processing npnts=%d\n", npnts);
    }

    /* at this point x, y, and z of input and output grids have been made */

    /* make new_sec[] with new grid definition */
    for (i = 0; i < 8; i++) new_sec[i] = sec[i];
    new_sec[3] = sec3_lola(nx, save->lon0, save->dlon, ny, save->lat0, save->dlat, sec);

    /* set background to average value of data */

    n = 0;
    sum = 0.0;
    /* make background = ave value */
    for (i = 0; i < npnts; i++) {
        if (save->in_x[i] < 999.0  && ! UNDEFINED_VAL(data[i]) ) {
	    n++;
	    sum += data[i];
	}
    }
    if (n == 0) {
	/* write undefined grid */
	for (i = 0; i < nxny; i++) background[i] = UNDEFINED;
        grib_wrt(new_sec, background, nxny, nx, ny, use_scale, dec_scale, bin_scale,
                wanted_bits, max_bits, grib_type, save->out);
        if (flush_mode) fflush(save->out);
	free(background);
	free(tmpv);
	free(inc);
	free(wt);
	return 0;
    }
    sum /= n;
    for (i = 0; i < nxny; i++) background[i] = sum;
fprintf(stderr,">>sum=%lf n %d background[1] %lf\n", sum, n, background[1]);

    for (iradius = 0; iradius < save->nRadius; iradius++) {
fprintf(stderr,">>radias=%lf nxny %d npnts %d\n", save->Radius[iradius],nxny, npnts);
	/* save->Radius has units of km */
	/* normalize to a sphere of unit radius */
	r_sq = save->Radius[iradius] / (save->R_earth / 1000.0);
	r_sq = r_sq * r_sq;
	/* wt = inc = 0.0; */
	for (k = 0; k < nxny; k++) inc[k] = wt[k] = 0.0;

	for (j = 0; j < npnts; j++) {
	    if (save->in_x[j] > 999.0 || UNDEFINED_VAL(data[j]) ) continue;

	    /* find the background value */
	    x = lon[j] - save->lon0;
	    x = (x < 0.0) ? (x + 360.0) / save->dlon : x / save->dlon;
	    y = (lat[j] - save->lat0) / save->dlat;

	    ix = floor(x);
	    iy = floor(y);
	    if ((double) ix == x && ix == nx-1) ix--;
	    if ((double) iy == y && iy == ny-1) iy--;

	    if (ix < 0 || iy < 0 || ix >= nx || iy >= ny) fatal_error("cress_lola: prog error ix, iy","");

	    x = x - ix;
	    y = y - iy;

	    /* find background value */

	    tmp = background[ix+iy*nx] * (1-x)*(1-y) +
		  background[ix+1+iy*nx] * (x)*(1-y) +
		  background[ix+(iy+1)*nx] * (1-x)*(y) +
		  background[(ix+1)+(iy+1)*nx] * (x)*(y);

// fprintf(stderr,"obs: lat/lon %lf %lf, ix %d / %d iy %d data %lf, background %lf\n", lat[j],lon[j], ix, nx, iy, data[j], tmp);
	    /* data increment */
	    tmp = data[j] - tmp;

	    x = save->in_x[j];
	    y = save->in_y[j];
	    z = save->in_z[j];

	    for (k = 0; k < nxny; k++) {
		tmpv[k] = DIST_SQ(x-save->out_x[k], y-save->out_y[k], z-save->out_z[k]);
		if (tmpv[k] < r_sq) {
		    tmpv[k] = (r_sq - tmpv[k]) / (r_sq + tmpv[k]);
		    wt[k] += tmpv[k];
		    inc[k] += tmpv[k] * tmp;
		}
	    }
	}		

	/* make mask or update background */

	if (save->Radius[iradius] < 0.0) {
	    for (k = 0; k < nxny; k++) save->mask[k] = (wt[k] > 0) ? 1 : 0;
	}
	for (k = 0; k < nxny; k++) {
	    if (wt[k] > 0) background[k] += inc[k]/wt[k];
	}
    }

    if (save->mask) {
	for (k = 0; k < nxny; k++) {
	    if (save->mask[k] == 0) background[k] = UNDEFINED;
	}
    }
    grib_wrt(new_sec, background, nxny, nx, ny, use_scale, dec_scale, bin_scale,
	wanted_bits, max_bits, grib_type, save->out);

    if (flush_mode) fflush(save->out);
    free(background);
    free(tmpv);
    free(wt);
    free(inc);
    return 0;
}
unsigned char *rd_grib2_msg_seq(FILE *input, long int *pos, unsigned long int *len, int *num_submsgs) {
    int i, j, c, c1, c2, c3, c4;
    long int len_grib;
    unsigned char *p, *end_of_msg;

    /* setup grib buffer */
    if (buffer == NULL) {
        if ((buffer = (unsigned char *) malloc(BUFF_ALLOC0)) == NULL) {
            fatal_error("not enough memory: rd_grib2_msg","");
        }
        buffer_size = BUFF_ALLOC0;
    }
    /* search for GRIB...2 */

    while (1) {
	c = get_input(input);
	if (c == EOF) { *len = 0; return NULL; }
	if (c != G) continue;
        if ( (c = get_input(input)) != R) { unget_input(c); continue; }
        if ( (c = get_input(input)) != I) { unget_input(c); continue; }
        if ( (c = get_input(input)) != B) { unget_input(c); continue; }
        c1 = get_input(input);
        c2 = get_input(input);
        c3 = get_input(input);
        c4 = get_input(input);
        if (c4 == 1) {
	    fprintf(stderr,"grib1 message ignored (use wgrib)\n");
	    continue;
	}
        if (c4 != 2) {
	    unget_input(c4);
	    unget_input(c3);
	    unget_input(c2);
	    unget_input(c1);
	    continue;
	}
	buffer[0] = G;
	buffer[1] = R;
	buffer[2] = I;
	buffer[3] = B;
	buffer[4] = c1;
	buffer[5] = c2;
	buffer[6] = c3;
	buffer[7] = c4;
	/* fill in the size 8-15, unget buffer is empty */
	for (i = 0; i < 8; i++) { 
	    buffer[8+i] = c = get_input(input);
	    if (c == EOF) {
	    	*len = 0;
		return NULL;
	    }
    	}
	break;
    }

    *len = len_grib = uint8(buffer+8);
    *pos = pos_input - 16;

    if (buffer_size < len_grib) {
        buffer_size = len_grib + len_grib / 10;
        buffer = (unsigned char *) realloc((void *) buffer, buffer_size);
    }

    if (io_buffer_cnt) fatal_error("rd_grib2_msg_seq: program error: io_buffer is not flushed","");
    j=fread(buffer+16, sizeof (unsigned char), len_grib-16, input);
    pos_input += j;
    
    if (j != len_grib-16) fatal_error("rd_grib2_msg_seq, read outside of file, bad grib file","");

    Msg = buffer;

    Sec[8] = Msg + len_grib - 4;
    if (Sec[8][0] != 55 || Sec[8][1] != 55 || Sec[8][2] != 55 || Sec[8][3] != 55) {
        fatal_error("rd_grib2_msg_seq, missing end section ('7777')","");
    }
    Sec[0] = Msg;

    /* scan message for number of submessages and perhaps for errors */
    p = Msg +  GB2_Sec0_size;
    end_of_msg = Msg + len_grib;

    i = 0;
    while (p < Sec[8]) {
        if (p[4] == 7) i++;
	if (uint4(p) < 5) fatal_error_i("rd_grib2_msg: illegal grib: section length, section %i", p[4]);
        p += uint4(p);
        if (p > end_of_msg) fatal_error("bad grib format","");
    }
    if (p != Sec[8]) {
        fatal_error("rd_grib2_msg: illegal format, end section expected","");
    }
    *num_submsgs = i;

    *len = len_grib;
    return Msg;
}
Example #23
0
int unpk_run_length(unsigned char **sec, float *data, unsigned int ndata) {

    int i, k, pack, decimal_scale, n_bits;
    int mv, mvl;
    unsigned int j, ncheck, npts;

    double *levels, dec_factor;
    int size_compressed_data, nvals, *vals;
    int v, n, factor, range;
    int bitmap_flag;
    unsigned char *mask_pointer;
    const unsigned int mask[] = {128,64,32,16,8,4,2,1};

    pack = code_table_5_0(sec);
    if (pack != 200) return 0;

    npts = GB2_Sec3_npts(sec);
    n_bits = (int) sec[5][11];
    mv = (int) uint2(sec[5]+12);
    mvl = (int) uint2(sec[5]+14);
    decimal_scale = (int) sec[5][16];
    if (decimal_scale > 127) {		// convert signed negative values
	decimal_scale = - (decimal_scale - 128);
    }
    dec_factor = Int_Power(10.0, -decimal_scale);

#ifdef DEBUG
    printf(" packing=%d n_bits=%d mv=%d mvl=%d decimal_scale=%d\n", pack, n_bits, mv, 
		mvl, decimal_scale);
#endif

    size_compressed_data = GB2_Sec7_size(sec)-5;
    nvals = ( size_compressed_data * 8) / n_bits;
#ifdef DEBUG
    printf(" size_compressed data %d npnts %d\n", size_compressed_data, nvals);
#endif

    levels = (double *) malloc(mvl * sizeof(double));
    vals = (int *) malloc(nvals * sizeof(int));

    for (i = 0; i < mvl; i++) {
	levels[i] = int2(sec[5] + 17 + i*2)*dec_factor;
    }

#ifdef DEBUG
    for (i = 0; i < mvl; i++) {
	printf(" lvls[%d] = %lf ", i, levels[i]);
	if (i % 4 == 0) printf("\n");
	if (i % 4 == 0) printf("\n");
    }
    printf("\n");
#endif

    rd_bitstream(sec[7]+5, 0, vals, n_bits, nvals);

    ncheck = i = 0;
    range = (1 << n_bits) - 1 - mv;
    if (range <= 0) fatal_error("unpk_running_length: range error","");

    j = 0;
    mask_pointer = sec[6] + 6;
    bitmap_flag = code_table_6_0(sec);
    if (bitmap_flag == 254) bitmap_flag = 0;
    if (bitmap_flag != 0 && bitmap_flag != 255) 
	fatal_error("unpk_running_length: unsupported bitmap","");
    while (i < nvals) {
	if (vals[i] > mv) fatal_error_i("test rlp val=%d",(int) i);
	v = vals[i++];
	n = 1;
	factor = 1;
	// 12/2014 while (vals[i] > mv && i < nvals) {
	while (i < nvals && vals[i] > mv) {
	    n += factor * (vals[i]-mv-1);
	    factor = factor * range;
	    i++;
	}
	ncheck += n;
        if (ncheck > npts) fatal_error_i("unpk_run_length: ncheck > npts (%u),",npts);

	if (bitmap_flag != 0) {
	    for (k = 0; k < n; k++) data[j++] = levels[v];
	}
	else {
	    for (k = 0; k < n; k++) {
		while (mask_pointer[j >> 3] & mask[j & 7]) {
	            data[j++] = UNDEFINED;
		}
		data[j++] = levels[v];
	    }
	}
    }
    if (j != ndata) fatal_error("unpk_run_length: bitmap problem","");
    free(levels);
    free(vals);
    return 0;
}
Example #24
0
int f_new_grid(ARG4) {
    struct local_struct *save;

    unsigned int i;
    int is_u, is_v, ftn_npnts, ftn_nout;
    int kgds[200], km;
    float *data_in, *data_out;
    double x0, y0, dx, dy, xn, yn;
    double lov, lad, latin1, latin2;
    int proj;					// projection: for LC 0 = NP, 128 = SP
    char name[NAMELEN];
    int j, ibi, ibo, iret, nnx, nny, n_out;
    unsigned char *new_sec[8], *s, *bitmap, *bitmap_out, *p;

    /* for lambertc */
    double r_maj, r_min, ref_lon, ref_lat;

    if (mode == -1) {			// initialization
        decode = 1;
        output_order_wanted = raw;	// in raw order


#ifdef G95
        // initialize g95 runtime library
        if (g95_runstop == 0) {
            g95_runtime_start(0,NULL);
            g95_runstop = 1;
        }
#endif

//        if ( (sizeof(vectors) / sizeof (vectors[0])) % 2 == 1) fatal_error("new_grid: program error in vectors[]","");

        // allocate static variables

        *local = save = (struct local_struct *) malloc( sizeof(struct local_struct));
        if (save == NULL) fatal_error("memory allocation -wind_speed","");

        if ((save->out = ffopen(arg4, file_append ? "ab" : "wb")) == NULL) {
            fatal_error("-new_grid: could not open file %s", arg1);
        }
        save->has_u = 0;
        save->radius_major = save->radius_minor = 0.0;
        init_sec(save->clone_sec);
        s = NULL;

        // parse NCEP grids */
        ncep_grids(&arg1, &arg2, &arg3);

        // for each output grid
        if (strcmp(arg1,"latlon") == 0) {
            if (sscanf(arg2,"%lf:%d:%lf", &x0, &nnx, &dx) != 3)
                fatal_error("new_grid: XDEF wrong:%s",arg2);
            if (sscanf(arg3,"%lf:%d:%lf", &y0, &nny, &dy) != 3)
                fatal_error("new_grid: YDEF wrong:%s",arg3);

            if (x0 < 0.0) x0 += 360.0;
            save->nx = nnx;
            save->ny = nny;
            save->npnts_out = n_out = nnx*nny;
            if (n_out <= 0) fatal_error("new_grid: bad nx, ny","");

            // make a new section 3
            s = sec3_lola(nnx, x0, dx, nny, y0, dy, sec);
        }
        else if (strncmp(arg1,"mercator:",9) == 0) {
            if (sscanf(arg1,"mercator:%lf",  &lad) != 1)
                fatal_error("new_grid: LaD (latitude interesection) not specified","");
            if (sscanf(arg2,"%lf:%d:%lf:%lf", &x0, &nnx, &dx, &xn) != 4)
                fatal_error("new_grid: XDEF wrong:%s",arg2);
            if (sscanf(arg3,"%lf:%d:%lf:%lf", &y0, &nny, &dy, &yn) != 4)

                if (x0 < 0.0) x0 += 360.0;
            save->nx = nnx;
            save->ny = nny;
            save->npnts_out = n_out = nnx*nny;
            if (n_out <= 0) fatal_error("new_grid: bad nx, ny","");

            // make a new section 3
            s = sec3_mercator(lad, nnx, x0, dx, xn, nny, y0, dy, yn, sec);
        }
        else if (strcmp(arg1,"gaussian") == 0) {
            if (sscanf(arg2,"%lf:%d:%lf", &x0, &nnx, &dx) != 3)
                fatal_error("new_grid: XDEF wrong:%s",arg2);
            if (sscanf(arg3,"%lf:%d", &y0, &nny) != 2)
                fatal_error("new_grid: YDEF wrong:%s",arg3);

            if (x0 < 0.0) x0 += 360.0;
            save->nx = nnx;
            save->ny = nny;
            save->npnts_out = n_out = nnx*nny;
            if (n_out <= 0) fatal_error("new_grid: bad nx, ny","");
            // make a new section 3
            s = sec3_gaussian(nnx, x0, dx, nny, y0, sec);
        }
        else if (strncmp(arg1,"lambert:",8) == 0) {
            i = sscanf(arg1,"lambert:%lf:%lf:%lf:%lf", &lov, &latin1, &latin2, &lad);
            if (i < 2) fatal_error("new_grid: arg1 wrong:%s",arg1);
            if (lov < 0.0)  lov += 360.0;
            if (i < 3) latin2 = latin1;
            if (i < 4) lad = latin2;
            proj = 0;
            if (latin2 < 0.0) proj = 128;

            if (sscanf(arg2,"%lf:%d:%lf", &x0, &nnx, &dx) != 3)
                fatal_error("new_grid: XDEF wrong:%s",arg2);
            if (sscanf(arg3,"%lf:%d:%lf", &y0, &nny, &dy) != 3)
                fatal_error("new_grid: YDEF wrong:%s",arg3);

            if (x0 < 0.0) x0 += 360.0;
            save->nx = nnx;
            save->ny = nny;
            save->npnts_out = n_out = nnx*nny;
            if (n_out <= 0) fatal_error("new_grid: bad nx, ny","");

            // make a new section 3
            s = sec3_lc(lov, lad, latin1, latin2, proj, nnx, x0, dx, nny, y0, dy, sec);
        }

        /* for lambertc, input is the lon-lat of center point */
        /* can not calc grid until radius is given, so do lambert code to check args */

        else if (strncmp(arg1,"lambertc:",9) == 0) {
            i = sscanf(arg1,"lambertc:%lf:%lf:%lf:%lf", &lov, &latin1, &latin2, &lad);
            if (i < 2) fatal_error("new_grid: arg1 wrong:%s",arg1);
            if (lov < 0.0)  lov += 360.0;
            if (i < 3) latin2 = latin1;
            if (i < 4) lad = latin2;
            proj = 0;
            if (latin2 < 0.0) proj = 128;

            if (sscanf(arg2,"%lf:%d:%lf", &x0, &nnx, &dx) != 3)
                fatal_error("new_grid: XDEF wrong:%s",arg2);
            if (sscanf(arg3,"%lf:%d:%lf", &y0, &nny, &dy) != 3)
                fatal_error("new_grid: YDEF wrong:%s",arg3);

            if (x0 < 0.0) x0 += 360.0;
            save->nx = nnx;
            save->ny = nny;
            save->npnts_out = n_out = nnx*nny;
            if (n_out <= 0) fatal_error("new_grid: bad nx, ny","");

            // make a new section 3
            s = sec3_lc(lov, lad, latin1, latin2, proj, nnx, x0, dx, nny, y0, dy, sec);
        }

        else if (strncmp(arg1,"nps:",4) == 0 || strncmp(arg1,"sps:",4) == 0)  {
            if (sscanf(arg1,"%*[ns]ps:%lf:%lf", &lov, &lad) != 2) fatal_error("new_grid: arg1 wrong:%s",arg1);
            if (lad != 60.0) fatal_error("New_grid: only LatD = 60 is supported","");
            proj = 0;
            if (arg1[0] == 's') proj = 128;
            if (sscanf(arg2,"%lf:%d:%lf", &x0, &nnx, &dx) != 3)
                fatal_error("new_grid: XDEF wrong:%s",arg2);
            if (sscanf(arg3,"%lf:%d:%lf", &y0, &nny, &dy) != 3)
                fatal_error("new_grid: YDEF wrong:%s",arg3);
            if (lov < 0.0)  lov += 360.0;

            if (x0 < 0.0) x0 += 360.0;
            save->nx = nnx;
            save->ny = nny;
            save->npnts_out = n_out = nnx*nny;
            if (n_out <= 0) fatal_error("new_grid: bad nx, ny","");

            // make a new section 3
            s = sec3_polar_stereo(lov, lad, proj, nnx, x0, dx, nny, y0, dy, sec);
        }
        else fatal_error("new_grid: unsupported output grid %s", arg1);

        // save new section 3
        i = (int) uint4(s);         // size of section 3
        new_sec[3] = save->sec3 = (unsigned char *) malloc(i * sizeof(unsigned char));
        for (j = 0; j < i; j++) save->sec3[j] = s[j];

        // apply wind rotation .. change flag 3.3
        if (wind_rotation == undefined) {
            fprintf(stderr,"Warning: -new_grid wind orientation undefined, "
                    "use \"-new_grid_winds (grid|earth)\", earth used (N=North Pole)\n");
            if ( (p = flag_table_3_3_location(new_sec)) ) *p = *p & (255 - 8);
        }

        if (wind_rotation == grid && (p = flag_table_3_3_location(new_sec))) *p = *p | 8;

        if (mk_kgds(new_sec, save->kgds_out)) fatal_error("new_grid: encoding output kgds","");

        /* some vectors need by interpolation routines */
        if ((save->rlat = (float *) malloc(n_out * sizeof(float))) == NULL)
            fatal_error("new_grid memory allocation","");
        if ((save->rlon = (float *) malloc(n_out * sizeof(float))) == NULL)
            fatal_error("new_grid memory allocation","");
        if ((save->crot = (float *) malloc(n_out * sizeof(float))) == NULL)
            fatal_error("new_grid memory allocation","");
        if ((save->srot = (float *) malloc(n_out * sizeof(float))) == NULL)
            fatal_error("new_grid memory allocation","");

        return 0;
    }

    save = (struct local_struct *) *local;

    if (mode == -2) {			// cleanup
#ifdef G95
        if (g95_runstop == 1) {
            g95_runtime_stop();
            g95_runstop = 0;
        }
#endif
        if (save->has_u > 0) {
            fprintf(stderr,"-new_grid: last field %s was not interpolated (missing V)\n", save->name);
            free(save->u_val);
            free_sec(save->clone_sec);
        }
        free(save->rlon);
        free(save->rlat);
        free(save->crot);
        free(save->srot);
        free(save->sec3);
        ffclose(save->out);
        free(save);

        return 0;
    }

    if (mode >= 0) {			// processing

        /* The kgds of some output grids will change depending on input grid */
        /* for example, radius of earth is not known grib file is read, */
        /*   and mass vs wind fields */
        /* right nowm, only affects lambertc */

        if (strncmp(arg1,"lambertc:",8) == 0) {

            // lambertc depends on the radius of the earth which is
            // set by the input grib file

            /* read earth radius */
            i = axes_earth(sec, &r_maj, &r_min);
            if (i) fatal_error_i("axes_earth: error code %d", i);

            if (save->radius_major != r_maj || save->radius_minor != r_min) {

                // update sec3 and kgds

                i = sscanf(arg1,"lambertc:%lf:%lf:%lf:%lf", &lov, &latin1, &latin2, &lad);
                if (i < 2) fatal_error("new_grid: arg1 wrong:%s",arg1);
                if (lov < 0.0)  lov += 360.0;
                if (i < 3) latin2 = latin1;
                if (i < 4) lad = latin2;
                proj = 0;
                if (latin2 < 0.0) proj = 128;

                if (sscanf(arg2,"%lf:%d:%lf", &x0, &nnx, &dx) != 3)
                    fatal_error("new_grid: XDEF wrong:%s",arg2);
                if (sscanf(arg3,"%lf:%d:%lf", &y0, &nny, &dy) != 3)
                    fatal_error("new_grid: YDEF wrong:%s",arg3);

                if (x0 < 0.0) x0 += 360.0;
                save->nx = nnx;
                save->ny = nny;
                save->npnts_out = n_out = nnx*nny;
                if (n_out <= 0) fatal_error("new_grid: bad nx, ny","");

                ref_lon = x0;
                ref_lat = y0;

                i = new_grid_lambertc(nnx, nny, ref_lon, ref_lat, latin1, latin2, lov, lad, r_maj, r_min, dx, dy, &x0, &y0);
                if (i) fatal_error_i("new_grid_lambertc: error code %d", i);

                // make a new section 3
                s = sec3_lc(lov, lad, latin1, latin2, proj, nnx, x0, dx, nny, y0, dy, sec);

                // save new section 3
                i = (int) uint4(s);         // size of section 3
                for (j = 0; j < i; j++) save->sec3[j] = s[j];

                // make kgds
                new_sec[3] = save->sec3;
                if (mk_kgds(new_sec, save->kgds_out)) fatal_error("new_grid: encoding output kgds","");

                // save radius of earth, to show sec3 and kgds has been done
                save->radius_major = r_maj;
                save->radius_minor = r_min;
            }
        }

        if (output_order != raw) fatal_error("new_grid: must be in raw output order","");
        i = getName(sec, mode, NULL, name, NULL, NULL);
        is_u = is_v = 0;
//	for (j = 0 ; j < sizeof(vectors) / sizeof(vectors[0]); j++) {
        for (j = 0; vectors[j] != NULL; j++) {
            if (strcmp(name,vectors[j]) == 0) {
                if (j % 2 == 0) is_u = 1;
                else is_v = 1;
                break;
            }
        }

// fprintf(stderr, " %s isu %d isv %d has_u %d\n", name, is_u, is_v, save->has_u);
//  for (i = 0; i < 12; i++) { printf("kgds_out[%d] = %d ",i,save->kgds_out[i]); }

        // check if V matches expectation

        if (is_v && (save->has_u == 0  || (same_sec0(sec,save->clone_sec) != 1 ||
                                           same_sec1(sec,save->clone_sec) != 1 ||
                                           same_sec3(sec,save->clone_sec) != 1 ||
                                           same_sec4(sec,save->clone_sec) != 1) )) {
            fprintf(stderr,"-new_grid: %s doesn't pair with previous vector field, field ignored\n", name);
            return 0;
        }

        // if U field - save

        if (is_u) {
            if (save->has_u > 0) {
                fprintf(stderr,"-new_grid: missing V, %s not interpolated\n",save->name);
                free(save->u_val);
                free_sec(save->clone_sec);
            }
            copy_sec(sec, save->clone_sec);
            copy_data(data,ndata,&(save->u_val));
            GB2_ParmNum(save->clone_sec) = GB2_ParmNum(sec) + 1;
            save->has_u = 1;
            strncpy(save->name, name,NAMELEN-1);
            save->name[NAMELEN-2]=0;
            return 0;
        }

        // at this point will call polates with either a scalar or vector

        n_out = save->npnts_out;
        nnx = save->nx;
        nny = save->ny;
        km = 1;			// only one field

        if (mk_kgds(sec, kgds)) fatal_error("new_grid: encoding input kgds","");

        data_in = (float *) malloc(npnts * (1 + (is_v != 0)) * sizeof(float));
        bitmap = (unsigned char *) malloc(npnts * sizeof(unsigned char));
        bitmap_out = (unsigned char *) malloc(n_out * sizeof(unsigned char));
        data_out = (float *) malloc(n_out * (1 + (is_v != 0)) * sizeof(float));

        if (data_in == NULL || data_out == NULL || bitmap == NULL || bitmap_out == NULL)
            fatal_error("new_grid: memory allocation problem","");

        ibi = 0;                        // input bitmap is not used
        if (is_v) {
            for (i = 0; i < npnts; i++) {
                if (DEFINED_VAL(data[i]) && DEFINED_VAL(save->u_val[i])) {
                    data_in[i] = save->u_val[i];
                    data_in[i+npnts] = data[i];
                    bitmap[i] = 1;
                }
                else {
                    data_in[i] = data_in[i + npnts] = 0.0;
                    bitmap[i] = 0;
                    ibi = 1;                // input bitmap is used
                }
            }
            if (mode == 98) fprintf(stderr," UV interpolation %s , %s\n", save->name, name);
        }
        else {
            for (i = 0; i < npnts; i++) {
                if (DEFINED_VAL(data[i])) {
                    data_in[i] = data[i];
                    bitmap[i] = 1;
                }
                else {
                    data_in[i] = 0.0;
                    bitmap[i] = 0;
                    ibi = 1;                // input bitmap is used
                }
            }
        }

        // interpolate

// for (i = 0; i < 12; i++) { printf("\nkgds_in[%d] = %d  out=%d ",i,kgds[i],save->kgds_out[i]); }
        ftn_npnts = (int) npnts;
        ftn_nout = (int) n_out;
        if (is_v) {
            IPOLATEV(&interpol_type, ipopt,kgds,save->kgds_out,
                     &ftn_npnts, &n_out, &km, &ibi, bitmap, data_in, data_in+npnts,
                     &ftn_nout,save->rlat,save->rlon, save->crot, save->srot,
                     &ibo, bitmap_out, data_out, data_out + n_out, &iret);
        }
        else {
            IPOLATES(&interpol_type, ipopt,kgds,save->kgds_out,
                     &ftn_npnts, &n_out, &km, &ibi, bitmap, data_in, &ftn_nout,
                     save->rlat,save->rlon, &ibo, bitmap_out, data_out, &iret);
        }
        if (iret != 0) {
            for (i = 0; i < 12; i++) {
                fprintf(stderr," IPOLATES error: kgds[%d] input %d output %d\n", i+1,kgds[i],save->kgds_out[i]);
            }
            if (iret == 2) fatal_error("IPOLATES failed, unrecognized input grid or no grid overlap","");
            if (iret == 3) fatal_error("IPOLATES failed, unrecognized output grid","");
            fatal_error_i("IPOLATES failed, error %d",iret);

        }
        n_out = (unsigned int) ftn_nout;

        /* use bitmap to set UNDEFINED values */
        if (ibo == 1) {         // has a bitmap
            if (is_v) {
                for (i = 0; i < n_out; i++) {
                    if (bitmap_out[i] == 0) data_out[i] = data_out[i+n_out] = UNDEFINED;
                }
            }
            else {
                for (i = 0; i < n_out; i++) {
                    if (bitmap_out[i] == 0) data_out[i] = UNDEFINED;
                }
            }
        }

        // now to write out the grib file

        for (i = 0; i < 8; i++) new_sec[i] = sec[i];
        new_sec[3] = save->sec3;

        if (is_v != 0) {
            GB2_ParmNum(new_sec) = GB2_ParmNum(new_sec) - 1;
            grib_wrt(new_sec, data_out, n_out, nnx, nny, use_scale, dec_scale, bin_scale,
                     wanted_bits, max_bits, grib_type, save->out);
            GB2_ParmNum(new_sec) = GB2_ParmNum(new_sec) + 1;
            grib_wrt(new_sec, data_out+n_out, n_out, nnx, nny, use_scale, dec_scale, bin_scale,
                     wanted_bits, max_bits, grib_type, save->out);
        }
        else {
            grib_wrt(new_sec, data_out, n_out, nnx, nny, use_scale, dec_scale, bin_scale,
                     wanted_bits, max_bits, grib_type, save->out);
        }
        if (flush_mode) fflush(save->out);
        free(data_in);
        free(bitmap);
        free(bitmap_out);
        free(data_out);
        if (is_v != 0) {
            save->has_u = 0;
            free(save->u_val);
            free_sec(save->clone_sec);
        }
    }
    return 0;
}
Example #25
0
int main(int argc, char **argv) {
    FILE *in;
    unsigned char *msg, *sec[9];
    long int last_pos;
    struct stat stat_buf;  /* for type of grib input file */

    int file_arg, i, j, num_submsgs;
    int n_arg;
    unsigned int k, ndata;
    float *data;
    double *ddata, ref;

#ifdef USE_G2CLIB
    float missing_c_val_1, missing_c_val_2;
    g2int *bitmap, has_bitmap;
    g2float *g2_data;
    int ii;
#endif

    struct ARGLIST arglist[N_ARGLIST];
    int narglist = 0;
    const char *new_argv[N_ARGLIST];
    void *local[N_ARGLIST];
    int has_inv_option, last_submsg;
    int err, new_GDS, gdt, pdt, center;
    unsigned char dscale[2] = {0,0};

    inv_file = stdout;
//    jas_init();

//  gctpc initialiation
    init(-1,-1,"gctpc_1,txt", "gctpc_2.txt");

    data = NULL;
    ndata = 0;

    /* no arguments .. help screen */
    if (argc == 1) {
	// f_help(-1,NULL,NULL,0,inv_out,local,"most");
	mode = -1;
	data = NULL;
	ndata = 0;
	*inv_out = 0;
	f_h(call_ARG0(inv_out,NULL));
	fprintf(inv_file, "%s\n", inv_out);
	eof_bin(); eof_string();
	exit(8);
    }

    setup_user_gribtable();

    /* copy argv */

    for (i = 0; i < argc; i++) {
	new_argv[i] = argv[i];
    }

    /* scan for "inv" and input file */
    has_inv_option = 0;
    file_arg = 0;
    for (i = 1; i < argc; i++) {
	if (new_argv[i][0] != '-') {
	    /* must be filename */
            file_arg = i;
            continue;
        }
	/* must be an option */
	for (j = 0; j < nfunctions; j++) {
	    if (strcmp(&(new_argv[i][1]),functions[j].name) == 0) {
	        if (functions[j].type == inv) has_inv_option = 1;
		i += functions[j].nargs;
                break;
            }
        }
    }

    /* if no inv option, use default inventory .. put it at end */

    if (has_inv_option == 0) {
	for (i = 0; i < argc; i++) {
	    new_argv[i] = new_argv[i];
	}
	new_argv[argc++] = "-s";
    } 


    /* parse parameters */
    file_arg = 0;
    for (i = 1; i < argc; i++) {

	if (new_argv[i][0] != '-' || (strcmp(new_argv[i],"-") == 0) ) {
	    /* must be filename */
	    if (file_arg == 0) {
		file_arg = i;
		continue;
	    } else {
		fatal_error("too many grib files .. 2nd=%s", new_argv[i]);
	    }
	}

	/* must be an option */

	for (j = 0; j < nfunctions; j++) {
	    if (strcmp(&(new_argv[i][1]),functions[j].name) == 0) {
#ifdef DEBUG
		fprintf(stderr,"match .. -%s %d args\n",  functions[j].name, functions[j].nargs);
#endif
                /* add to function argument list */
		arglist[narglist].fn = j;
		arglist[narglist].i_argc = i+1;

	        if (functions[j].type == inv) has_inv_option = 1;

		i += functions[j].nargs;
		if (i >= argc) fatal_error("missing arguments option=%s",functions[j].name);
		narglist++;
		break;
	    }
	}

	if (j == nfunctions) {
	    fatal_error("unknown option %s", new_argv[i]);
	}
    }

    if (has_inv_option == 0) {
        fatal_error("missing arguments on last option","");
    }

    /* initialize options mode = -1 */

#ifdef DEBUG
    fprintf(stderr,"init options narglist %d\n",narglist);
#endif

    for (j = 0; j < narglist; j++) {
	inv_out[0] = 0;
	n_arg = functions[arglist[j].fn].nargs;
        err = 0;
        if (n_arg == 0) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j);
	else if (n_arg == 1) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc]);
	else if (n_arg == 2) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1]);
	else if (n_arg == 3) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],new_argv[arglist[j].i_argc+2]);
	else if (n_arg == 4) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]);
	else if (n_arg == 5) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
		new_argv[arglist[j].i_argc+4]);
	else if (n_arg == 6) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
		new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]);
	else if (n_arg == 7) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
		new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
		new_argv[arglist[j].i_argc+6]);
	else if (n_arg == 8) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j,
		new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],
		new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
		new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
		new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]);

        if(inv_out[0] != 0)  fprintf(inv_file, "%s", inv_out);
        if (err) {
	    err_bin(); err_string();
	    exit(8);
	}
    }

    if (file_arg == 0 && argc > 1) fatal_error("no input file", "");
    if (latlon == 1 && output_order_wanted != wesn) 
           fatal_error("latitude-longitude information is only available with -order we:sn","");

    /* open input file */

    seq_input = 0;
    if (strcmp(new_argv[file_arg],"-") == 0) {
	seq_input = 1;
        in = stdin;
        if (mode == 98) fprintf(stderr, "grib input is stdin\n");
    }
    else { 
        if (stat(new_argv[file_arg], &stat_buf) != -1) {
	    if (S_ISREG(stat_buf.st_mode)) {
                if (mode == 98) fprintf(stderr, "grib input is a regular file\n");
	    }
	    else if (S_ISDIR(stat_buf.st_mode)) {
	        fatal_error("grib input is a directory: %s",new_argv[file_arg]);
	    }
	    else if (S_ISCHR(stat_buf.st_mode)) {
	        seq_input = 1;
                 if (mode == 98) fprintf(stderr, "grib input is a char device\n");
	    }
	    else if (S_ISBLK(stat_buf.st_mode)) {
	        seq_input = 1;
                if (mode == 98) fprintf(stderr, "grib input is a block device\n");
	    }
	    else if (S_ISFIFO(stat_buf.st_mode)) {
	        seq_input = 1;
	        if (mode == 98) fprintf(stderr, "grib input is a fifo device\n");
	    }
	    else {
	        if (mode == 98) fprintf(stderr, "grib input has an unknown type\n");
	    }
	}

	if ((in = fopen(new_argv[file_arg],"rb")) == NULL) {
            fatal_error("could not open file: %s", new_argv[file_arg]);
	}
    }

    /* sequential input - can not do random access */
    if (seq_input && input == inv_mode) fatal_error("wgrib2 cannot random access grib input file","");

    ndata = 0;
    data = NULL;
    ddata = NULL;
    msg_no = 1;
    inv_no = 0;
    len = pos = 0;
    submsg = 0;
    msg = NULL;

    if ((old_gds = (unsigned char *) malloc(GDS_max_size * sizeof(char)) ) == NULL) {
	fatal_error("memory allocation problem old_gds in wgrib2.main","");
    }
    
    last_pos = -1;
    last_submsg = -1;

    /* if dump mode .. position io stream */
    if (input == dump_mode) {
        while (msg_no < dump_msg) {
	    msg = seq_input ?  rd_grib2_msg_seq(in, &pos, &len, &num_submsgs) :
	            rd_grib2_msg(in, &pos, &len, &num_submsgs);
            if (msg == NULL) fatal_error_i("record %d not found", dump_msg);
            last_pos = pos;
            pos += len;
            msg_no++;
        }
#ifdef DEBUG
        printf("dump mode msg=%d\n", msg_no);
#endif
    }

    /* 
     * submsg = 0 .. beginning of unread record
     * submsg = i .. start at ith submsg
     * num_submsgs = number of submessages in grib message
     */

    /* inventory loop */ 

    for (;last_message == 0;) {

        /* need position and submessage number of message */
        if (input == inv_mode || input == dump_mode) {
            if (input == inv_mode) {
                if (rd_inventory(&msg_no,&submsg, &pos)) break;
            }
            else if (input == dump_mode) {
                if (dump_msg == -1) break;
                submsg = dump_submsg;
                dump_msg = -1;
	    }

            if (pos != last_pos) {
		msg = seq_input ?  rd_grib2_msg_seq(in, &pos, &len, &num_submsgs) :
	            rd_grib2_msg(in, &pos, &len, &num_submsgs);
	        if (msg == NULL) {
                    fatal_error_i("grib message #%d not found", msg_no);
                    break;
                }
                last_pos = pos;
		last_submsg = -1;
            }

            if (pos == last_pos && submsg == last_submsg + 1) {
                /* read previous submessage */
		if (parse_next_msg(sec) != 0) {
                    fprintf(stderr,"\n*** grib message #%d.%d not found ***\n\n", msg_no, submsg);
                    break;
		}
            }
            else {
                /* need to get desired submessage into sec */
		if (parse_1st_msg(sec) != 0) {
                    fprintf(stderr,"\n*** grib message #%d.1 not found ***\n\n", msg_no);
                    break;
		}
                for (i = 2; i <= submsg; i++) {
		    if (parse_next_msg(sec) != 0) {
                        fprintf(stderr,"\n*** grib message #%d.%d not found ***\n\n", msg_no, i);
                        break;
                    }
		}
	    }
            last_submsg = submsg;
	}
        else if (input == all_mode) {
	    if (submsg == 0) {
		msg = seq_input ?  rd_grib2_msg_seq(in, &pos, &len, &num_submsgs) :
	            rd_grib2_msg(in, &pos, &len, &num_submsgs);
		if (msg == NULL) break;
                submsg = 1;
	    }
	    else if (submsg > num_submsgs) {
		pos += len;
                msg_no++;
		msg = seq_input ?  rd_grib2_msg_seq(in, &pos, &len, &num_submsgs) :
	            rd_grib2_msg(in, &pos, &len, &num_submsgs);
		if (msg == NULL) break;
                submsg = 1;
	    }
            if (submsg == 1) {
		if (parse_1st_msg(sec) != 0) {
		    fprintf(stderr,"illegal format: parsing 1st submessage\n");
		}
            }
            else {
		if (parse_next_msg(sec) != 0) {
                    fprintf(stderr,"illegal format: parsing submessages\n");
                }
	    }
	}
        if (only_submsg > 0 && only_submsg != submsg) {
	    submsg++;
	    continue;
	}

	if (for_mode) {
	    if (msg_no < for_start || msg_no > for_end || ((msg_no - for_start) % for_step) != 0) {
	        if (msg_no > for_end && input != inv_mode) last_message = 1;
		submsg++;
		continue;
	    }
	}

#ifdef USE_REGEX

	/* move inv_no++ before match_inv is made */
	inv_no++;
        if (match) {
	   inv_out[0] = 0;
	   if (num_submsgs > 1) {
	       sprintf(inv_out,"%d.%d:", msg_no, submsg);
	   }
           else {
	       sprintf(inv_out,"%d:", msg_no);
	   }

           // f_match_inv(0, sec, NULL, 0, inv_out+strlen(inv_out), NULL);
           f_match_inv(call_ARG0(inv_out+strlen(inv_out), NULL));

           if (is_match(inv_out) != 0) {
              submsg++;
	      inv_no--;
              continue;
           }
        }
#endif
	match_flag = 0;

        if (for_n_mode) {
            if (inv_no < for_n_start || inv_no > for_n_end || ((inv_no - for_n_start) % for_n_step) != 0) {
                if (inv_no > for_n_end) last_message = 1;
                submsg++;
                continue;
            }
        }

        /* see if new GDS */

	if ((i = GB2_Sec3_size(sec)) != old_GDS_size) {
	    new_GDS = 1;
	}
	else {
	    new_GDS = 0;
	    for (j = 0; j < i; j++) {
		if (old_gds[j] != sec[3][j]) new_GDS = 1;
	    }
	}
	if (new_GDS) {
	    GDS_change_no++;
	    if (i > GDS_max_size) {
		free(old_gds);
		GDS_max_size = i;
    		if ((old_gds = (unsigned char *) malloc(GDS_max_size) ) == NULL) {
			fatal_error("memory allocation problem old_gds in wgrib2.main","");
		}
	    }
	    for (j = 0; j < i; j++) {
		old_gds[j] = sec[3][j];
            }
	    old_GDS_size = i;
	    /* update grid information */
            get_nxny(sec, &nx, &ny, &npnts, &res, &scan);	 /* get nx, ny, and scan mode of grid */
	    output_order = (nx == -1 || ny == -1) ? raw : output_order_wanted;

            if (latlon) {
		i = 1;
		if (use_gctpc && output_order == wesn) {		/* use gctpc to get lat lon values */
		   i = gctpc_get_latlon(sec, &lon, &lat);
		}
		if (i) get_latlon(sec, &lon, &lat);			 /* get lat lon of grid points */
	    }
	}

	/* Decode NDFD WxText */
	if (WxText) mk_WxKeys(sec);

	// any fixes to raw grib message before decode need to be placed here
	if (fix_ncep_2_flag) fix_ncep_2(sec);
	if (fix_ncep_3_flag) fix_ncep_3(sec);
	if (fix_ncep_4_flag) fix_ncep_4(sec);

#ifdef CHECK
	j = code_table_5_0(sec);		// type of compression

	/* yes this can be simplified but want to split it up in case other decoders have problems */
	if (j == 0 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) 
		fprintf(stderr,"Warning: g2lib/g2clib/grib-api simple decode may differ from WMO standard, use -g2clib 0 for WMO standard\n");
	if ((j == 2 || j == 3) && int2(sec[5]+17) != 0 && int4(sec[5] + 31) == 0 && ieee2flt(sec[5]+11) != 0.0) 
		fprintf(stderr,"Warning: g2lib/g2clib complex decode may differ from WMO standard, use -g2clib 0 for WMO standard\n");
	if (j == 40 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) 
		fprintf(stderr,"Warning: g2lib/g2clib jpeg deocde may differ from WMO standard, use use -g2clib 0 for WMO standard\n");
	if (j == 41 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) 
		fprintf(stderr,"Warning: g2lib/g2clib/grib-api png decode may differ from WMO standard, use -g2clib 0 for WMO standard\n");
#endif

#ifdef CHECK
	/* check the size of Section 7 */
	/* code to check the other sizes needs to be placed in decode routines */

	j = code_table_5_0(sec);		// type of compression
	if (j == 0) {		/* simple */
	    /* to avoid overflow on 32 bit machines */
	    /* old:  k = (GB2_Sec5_nval(sec) * sec[5][19] + 7) / 8 + 5; */
	    k = 5 + (GB2_Sec5_nval(sec)/8) * sec[5][19] +  (GB2_Sec5_nval(sec)%8) * (sec[5][19]/8)
	    	+ ( (GB2_Sec5_nval(sec)%8) * (sec[5][19]%8) + 7) / 8;

	    if (k != GB2_Sec7_size(sec)) {
		fprintf(stderr,"Detected a size mismatch, Section 7, wanted %d found %d\n", k, GB2_Sec7_size(sec));
		if (decode) fatal_error("Section 7 size, mismatch, simple packing","");
	    }
	}
	else if (j == 4) {		/* IEEE */
	    k = GB2_Sec5_nval(sec) * 4 + 5;
	    if (k != GB2_Sec7_size(sec)) {
		fprintf(stderr,"Detected a size mismatch, Section 7, wanted %d found %d\n", k, GB2_Sec7_size(sec));
		if (decode) fatal_error("Section 7 size, mismatch, IEEE packing","");
	    }
	}
#endif

	if (decode) {

#ifdef CHECK
            if (code_table_6_0(sec) == 0) {                         // has bitmap
                k = GB2_Sec3_npts(sec) -  GB2_Sec5_nval(sec);
                if (k != missing_points(sec[6]+6, GB2_Sec3_npts(sec)))
                    fatal_error_ii("inconsistent number of bitmap points sec3-sec5: %d sec6: %d",
			k, missing_points(sec[6]+6, GB2_Sec3_npts(sec)));
            }
            else if (code_table_6_0(sec) == 255) {                  // no bitmap
                if (GB2_Sec3_npts(sec) != GB2_Sec5_nval(sec))
                    fatal_error_ii("inconsistent number of data points sec3: %d sec5: %d",
                        GB2_Sec3_npts(sec), GB2_Sec5_nval(sec));
            }
#endif

            /* allocate data */
            if (GB2_Sec3_npts(sec) != ndata) {
                if (ndata) free(data);
                ndata = GB2_Sec3_npts(sec);
                if (ndata) {
                    data = (float *) malloc(ndata * sizeof(float));
                    if (data == NULL) fatal_error("main: memory allocation failed data","");
                }
                else { data = NULL; }
            }

	    j = code_table_5_0(sec);		// type of compression
	    gdt = code_table_3_1(sec);		// grid type
            pdt = GB2_ProdDefTemplateNo(sec);   // product defintion template

            /* USE G2CLIB */

#ifdef USE_G2CLIB
            if (use_g2clib == 2) {
                err = g2_getfld(msg,submsg,1,1,&grib_data);
                if (err != 0) fatal_error_ii("Fatal g2clib decode err=%d msg=%d", err, msg_no);
                free_gribfield = 1;

                has_bitmap = grib_data->ibmap;
                g2_data = &(grib_data->fld[0]);
                if (has_bitmap == 0 || has_bitmap == 254) {
                    bitmap = grib_data->bmap;
                    for (i = 0; i < ndata; i++) {
                         data[i] = (bitmap[i] == 0) ? UNDEFINED : g2_data[i];
                    }
                }
                else {
                    for (i = 0; i < ndata; i++) {
                        data[i] = g2_data[i];
                    }
                }

                /* complex packing uses special values for undefined */
                ii = sub_missing_values(sec, &missing_c_val_1, &missing_c_val_2);
                if (ii == 1) {
                    for (i = 0; i < ndata; i++) {
                        if (data[i] == missing_c_val_1) data[i] = UNDEFINED;
                    }
                }
                else if (ii == 2) {
                    for (i = 0; i < ndata; i++) {
                        if (data[i] == missing_c_val_1) data[i] = UNDEFINED;
                        if (data[i] == missing_c_val_2) data[i] = UNDEFINED;
                    }
                }
            }
#endif

            /* USE INTERNAL DECODER */

            if (use_g2clib != 2) {
                center = GB2_Center(sec);
                if (use_g2clib == 1) {	// introduce g2clib constant field error
		    /* g2clib ignores decimal scaling for constant fields make internal decoders look like g2clib*/
                    if ( (j == 0 && sec[5][19] == 0) || ((j == 2 || j == 3) && int4(sec[5] + 31) == 0) ||
                         (j == 40 && sec[5][19] == 0) || (j == 41 && sec[5][19] == 0) ||
                         (center == NCEP && j == 40000 && sec[5][19] == 0) || 
                         (center == NCEP && j == 40010 && sec[5][19] == 0)  ) {
			dscale[0] = sec[5][17];
			dscale[1] = sec[5][18];
			sec[5][17] = sec[5][18] = 0;
                    }
		}

		err = unpk_grib(sec, data);
                if (err != 0) fatal_error_i("Fatal decode packing type %d",err);

		if (use_g2clib == 1) {  // fix up data 
		    /* restore decimal scaling */
                    if ( (j == 0 && sec[5][19] == 0) || ((j == 2 || j == 3) && int4(sec[5] + 31) == 0) ||
                         (j == 40 && sec[5][19] == 0) || (j == 41 && sec[5][19]) ||
                         (center == NCEP && j == 40000 && sec[5][19] == 0) || 
                         (center == NCEP && j == 40010 && sec[5][19] == 0)  ) {
			sec[5][17] = dscale[0];
			sec[5][18] = dscale[1];
                    }
		}
            }

	    /* convert to standard output order we:sn */

	    if (output_order_wanted == wesn) to_we_sn_scan(data);
	    else if (output_order_wanted == wens) to_we_ns_scan(data);
	}
        else {
	    if (ndata) free(data);
            ndata = 0;
            data = NULL;
        }

	/* get scaling parameters */

	use_scale = scaling(sec, &ref, &dec_scale, &bin_scale, &i) == 0;


	if (num_submsgs > 1) {
	    fprintf(inv_file, "%d.%d%s%ld", msg_no, submsg, ":", pos);
	}
        else {
	    fprintf(inv_file, "%d%s%ld", msg_no, ":", pos);
	}

	for (j = 0; j < narglist; j++) {

	    /* skip execution if match_flag == 1 */
	    /* an output option acts as endif for match_flag */
	    if (match_flag == 1) {
                if (functions[arglist[j].fn].type == output)  match_flag = 0;
		continue;
	    }


            // if (functions[arglist[j].fn].type == inv) fprintf(inv_file, item_deliminator);
            if (functions[arglist[j].fn].type == inv) fprintf(inv_file, "%s", item_deliminator);
            if (functions[arglist[j].fn].type != setup) {
		inv_out[0] = 0;
	        n_arg = functions[arglist[j].fn].nargs;
		if (n_arg == 0) 
                    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j);
		else if (n_arg == 1)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			 new_argv[arglist[j].i_argc]);
		else if (n_arg == 2)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1]);
		else if (n_arg == 3)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2]);
		else if (n_arg == 4)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]);
		else if (n_arg == 5)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4]);
		else if (n_arg == 6)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]);
		else if (n_arg == 7)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
			new_argv[arglist[j].i_argc+6]);
		else if (n_arg == 8)
		    functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
			new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]);

        	if(inv_out[0] != 0)  fprintf(inv_file, "%s", inv_out);
           }
	}

#ifdef CHECK
	if (!decode) {
            if (code_table_6_0(sec) == 0) {                         // has bitmap
                k = GB2_Sec3_npts(sec) -  GB2_Sec5_nval(sec);
                if (k != missing_points(sec[6]+6, GB2_Sec3_npts(sec)))
                    fatal_error_ii("inconsistent number of bitmap points sec3-sec5: %d sec6: %d",
			k, missing_points(sec[6]+6, GB2_Sec3_npts(sec)));
            }
            else if (code_table_6_0(sec) == 255) {                  // no bitmap
                if (GB2_Sec3_npts(sec) != GB2_Sec5_nval(sec))
                    fatal_error_ii("inconsistent number of data points sec3: %d sec5: %d",
                        GB2_Sec3_npts(sec), GB2_Sec5_nval(sec));
            }
	}
#endif

	submsg++;

#ifdef USE_G2CLIB
	if (free_gribfield) { g2_free(grib_data); free_gribfield = 0;}
#endif

	// fprintf(inv_file, "\n");
	fprintf(inv_file, "%s",end_inv);
	if (flush_mode) fflush(inv_file);
	if (dump_msg > 0) break;
    }

    /* finalize all functions, call with mode = -2 */

    for (j = 0; j < narglist; j++) {
        if (functions[arglist[j].fn].type != setup) {
	    n_arg = functions[arglist[j].fn].nargs;
	    inv_out[0] = 0;
	    if (n_arg == 0) 
                functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j);
	    else if (n_arg == 1)
		functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc]);
	    else if (n_arg == 2)
		functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1]);
	    else if (n_arg == 3)
		functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2]);
	    else if (n_arg == 4)
		functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]);
	    else if (n_arg == 5)
		functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4]);
	    else if (n_arg == 6)
		functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]);
	    else if (n_arg == 7)
		functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
			new_argv[arglist[j].i_argc+6]);
	    else if (n_arg == 8)
		functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j,
			new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1],
			new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3],
			new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5],
			new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]);
            // if (inv_out[0]) fprintf(stderr, "%s\n", inv_out);
            if (inv_out[0]) fprintf(stderr, "%s%s", inv_out, end_inv);
        }
    }
    eof_bin(); eof_string();
    exit(0);
}
Example #26
0
int f_lola(ARG4) {

    int nx, ny, j, k;
    int i, nxny;
    double latitude, longitude;
    double x0,dx, y0,dy;
    unsigned char *new_sec[8];
    float *tmp, t;

    struct local_struct {
        int nlat, nlon;
        double lat0, lon0, dlat, dlon;
        FILE *out;
        int *iptr;
    };
    struct local_struct *save;
    char open_mode[4];

    /* initialization phase */

    if (mode == -1) {
        decode = latlon = 1;
        if (sscanf(arg1,"%lf:%d:%lf", &x0, &nx, &dx) != 3) {
            fatal_error("lola parsing longitudes lon0:nx:dlon  %s", arg1);
        }
        if (sscanf(arg2,"%lf:%d:%lf", &y0,&ny,&dy) != 3) {
            fatal_error("lola parsing latitudes lat0:nx:dlat  %s", arg2);
        }

        if (strcmp(arg4,"spread") != 0 
                && strcmp(arg4,"text") != 0 
                && strcmp(arg4,"grib") != 0
                && strcmp(arg4,"bin") != 0) fatal_error("lola bad write mode %s", arg4);

	if (strcmp(arg4,"grib") == 0 && (dx <= 0 || dy <= 0))
		fatal_error("lola parsing, for grib dlat > 0 and dlon > 0","");

        strcpy(open_mode, file_append ? "a" : "w");
        if (strcmp(arg4,"bin") == 0 || strcmp(arg4,"grib") == 0) strcat(open_mode,"b");

        nxny = nx*ny;
        *local = save = (struct local_struct *)malloc( sizeof(struct local_struct));
        if (save == NULL) fatal_error("lola memory allocation ","");
	if (x0 < 0.0) x0 += 360.0;
	if (x0 >= 360.0) x0 -= 360.0;
	if (x0 < 0.0 || x0 >= 360.0) fatal_error("-lola: bad initial longitude","");
	if (nx <= 0) fatal_error_i("-lola: bad nlon %d", nx);
        save->nlon = nx;
        save->lon0 = x0;
        save->dlon = dx;

	if (y0 < -90.0 || y0 > 90.0) fatal_error("-lola: bad initial latitude","");
	if (ny <= 0) fatal_error_i("-lola: bad nlat %d", ny);
        save->nlat = ny;
        save->lat0 = y0;
        save->dlat = dy;
        save->iptr = (int *) malloc(nx*ny * sizeof(int));
	if (save->iptr == NULL) fatal_error("-lola: memory allocation","");
        if ((save->out = ffopen(arg3,open_mode)) == NULL) 
              fatal_error("lola could not open file %s", arg3);
        return 0;
    }

    /* cleanup phase */

    if (mode == -2) return 0;

    /* processing phase */

    save = *local;
    nx = save->nlon;
    ny = save->nlat;
    nxny = nx*ny;

    if (new_GDS) {

        // if (output_order != wesn) fatal_error("lola only works in we:sn order","");
        if (lat == NULL || lon == NULL || data == NULL) fatal_error("lola: no val","");

        /* find the nearest points for the grid */
        closest_init(sec);
        k = 0;
        for (j = 0; j < ny; j++) {
            latitude = save->lat0 + j*save->dlat;
            for (i = 0; i < nx; i++) {
               longitude = save->lon0 + i*save->dlon;
               save->iptr[k++] = closest(sec, latitude, longitude);
            }
        }
    }

    if (strcmp(arg4,"spread") == 0) {
        k = 0;
        fprintf(save->out, "longitude, latitude, value,\n");
        for (j = 0; j < ny; j++) {
            latitude = save->lat0 + j*save->dlat;
            for (i = 0; i < nx; i++) {
                t = save->iptr[k] >= 0 ? data[save->iptr[k]] : UNDEFINED;
		if (DEFINED_VAL(t)) {
                    longitude = save->lon0 + i*save->dlon;
		    if (longitude >= 360.0) longitude -= 360.0;
                    fprintf(save->out, "%.6lf, %.6lf, %g,\n",longitude,latitude,t);
		}
		k++;
            }
        }
    }

    else if (strcmp(arg4,"bin") == 0) {
        i = nxny * sizeof(float);
        if (header) fwrite((void *) &i, sizeof(int), 1, save->out);
        for (i = 0; i < nxny; i++) {
            t = save->iptr[i] >= 0 ? data[save->iptr[i]] : UNDEFINED;
            fwrite(&t, sizeof(float), 1, save->out);
	}
        if (header) fwrite((void *) &i, sizeof(int), 1, save->out);
    }

    else if (strcmp(arg4,"text") == 0) {
        /* text output */
        if (header == 1) {
            fprintf(save->out ,"%d %d\n", nx, ny);
        }
        for (i = 0; i < nxny; i++) {
            t = save->iptr[i] >= 0 ? data[save->iptr[i]] : UNDEFINED;
            fprintf(save->out, text_format, t);
            fprintf(save->out, ((i+1) % text_column) ? " " : "\n");
        }
    }

    else if (strcmp(arg4,"grib") == 0) {
	/* make new_sec[] with new grid definition */
	for (i = 0; i < 8; i++) new_sec[i] = sec[i];
	new_sec[3] = sec3_lola(nx, save->lon0, save->dlon, ny, save->lat0, save->dlat, sec, NULL, NULL);

	/* get grid values */
	tmp = (float *) malloc(nx*ny * sizeof (float));
	if (tmp == NULL) fatal_error("-lola: memory allocation","");
        for (i = 0; i < nxny; i++) 
            tmp[i] = save->iptr[i] >= 0 ? data[save->iptr[i]] : UNDEFINED;

        grib_wrt(new_sec, tmp, nx*ny, nx, ny, use_scale, dec_scale, bin_scale, 
		wanted_bits, max_bits, grib_type, save->out);

	free(tmp);
    }

    if (flush_mode) fflush(save->out);
    return 0;
}
Example #27
0
int f_submsg_uv(ARG1) {

    struct local_struct {
        unsigned char *sec[9];
	const char *vname;    
        FILE *output;
    };

    struct local_struct *save;
    int i, j, is_v;
    unsigned long int size;
    char name[NAMELEN];
    unsigned char s[8];

    if (mode == -1) {		// initialization

        // allocate static structure

        *local = save = (struct local_struct *) malloc( sizeof(struct local_struct) );
        if (save == NULL) fatal_error("submsg_uv: memory allocation","");

        if ((save->output = ffopen(arg1, file_append ? "ab" : "wb")) == NULL) {
            fatal_error("submsg_uv: could not open file %s", arg1);
        }
	save->vname = NULL;
        init_sec(save->sec);
	return 0;
    }

    save = (struct local_struct *) *local;

    if (mode == -2)  {		// cleanup
	if (save->vname != NULL) {		// write out cached field
	   i = wrt_sec(save->sec[0], save->sec[1], save->sec[2], save->sec[3], 
		save->sec[4], save->sec[5], save->sec[6], save->sec[7], save->output);
	   if (i) fatal_error_i("submsg_uv: last record problem %i",i);
           free_sec(save->sec);
	}
	ffclose(save->output);
        free(save);
	return 0;
    }

    if (mode >= 0 )  {					// processing
        i = getName(sec, mode, NULL, name, NULL, NULL);

	/* see if name == expected vname */
	is_v = 0;
	if (save->vname != NULL && strcmp(name, save->vname) == 0) {
	    is_v = 1;
            if (same_sec0(sec,save->sec) == 0) is_v = 0;
            if (same_sec1(sec,save->sec) == 0) is_v = 0;
            if (same_sec2(sec,save->sec) == 0) is_v = 0;
            if (same_sec3(sec,save->sec) == 0) is_v = 0;

	    i = GB2_ParmNum(sec);
	    j = GB2_ParmCat(sec);
	    GB2_ParmNum(sec) = GB2_ParmNum(save->sec);
	    GB2_ParmCat(sec) = GB2_ParmCat(save->sec);
            if (same_sec4(sec,save->sec) == 0) is_v = 0;
	    GB2_ParmNum(sec) = i;
	    GB2_ParmCat(sec) = j;
	}

	/* finished tests for U/V sequence */

	/* is U/V sequence */
	if (is_v) {
	    size = (unsigned long int) GB2_Sec0_size + GB2_Sec8_size +
	    (sec[1] ? uint4(sec[1]) : 0) +
	    (sec[2] ? uint4(sec[2]) : 0) +
	    (sec[3] ? uint4(sec[3]) : 0) +
	    (sec[4] ? uint4(sec[4]) : 0) +
	    (sec[5] ? uint4(sec[5]) : 0) +
	    (sec[6] ? uint4(sec[6]) : 0) +
	    (sec[7] ? uint4(sec[7]) : 0) +
	    (save->sec[4] ? uint4(save->sec[4]) : 0) +
	    (save->sec[5] ? uint4(save->sec[5]) : 0) +
	    (save->sec[6] ? uint4(save->sec[6]) : 0) +
	    (save->sec[7] ? uint4(save->sec[7]) : 0);

	    fwrite((void *) sec[0], sizeof(char), 8, save->output);
            uint8_char(size, s);
            fwrite((void *) s, sizeof(char), 8, save->output);

            if (sec[1]) {
                i = uint4(sec[1]);
                if (fwrite((void *)sec[1], sizeof(char), i, save->output) != i) return 1;
            }
            if (sec[2]) {
                i = uint4(sec[2]);
                if (fwrite((void *)sec[2], sizeof(char), i, save->output) != i) return 1;
            }
            if (sec[3]) {
                i = uint4(sec[3]);
                if (fwrite((void *)sec[3], sizeof(char), i, save->output) != i) return 1;
            }
            if (save->sec[4]) {
                i = uint4(save->sec[4]);
                if (fwrite((void *)save->sec[4], sizeof(char), i, save->output) != i) return 1;
            }
            if (save->sec[5]) {
                i = uint4(save->sec[5]);
                if (fwrite((void *)save->sec[5],sizeof(char), i, save->output) != i) return 1;
            }
            if (save->sec[6]) {
                i = uint4(save->sec[6]);
                if (fwrite((void *)save->sec[6],sizeof(char), i, save->output) != i) return 1;
            }
            if (save->sec[7]) {
                i = uint4(save->sec[7]);
                if (fwrite((void *)save->sec[7],sizeof(char), i, save->output) != i) return 1;
            }
            if (sec[4]) {
                i = uint4(sec[4]);
                if (fwrite((void *)sec[4], sizeof(char), i, save->output) != i) return 1;
            }
            if (sec[5]) {
                i = uint4(sec[5]);
                if (fwrite((void *)sec[5], sizeof(char), i, save->output) != i) return 1;
            }
            if (sec[6]) {
                i = uint4(sec[6]);
                if (fwrite((void *)sec[6], sizeof(char), i, save->output) != i) return 1;
            }
            if (sec[7]) {
                i = uint4(sec[7]);
                if (fwrite((void *)sec[7], sizeof(char), i, save->output) != i) return 1;
            }

            s[0] = s[1] = s[2] = s[3] = 55; /* s = "7777" */
            if (fwrite((void *) s, sizeof(char), 4, save->output) != 4)
	           fatal_error("submsg_uv: write record problem","");

	    save->vname = NULL;
            free_sec(save->sec);
            return 0;
	}

	/* has U but not V, write U */    

	if (save->vname != NULL) {
	   i = wrt_sec(save->sec[0], save->sec[1], save->sec[2], save->sec[3], 
		save->sec[4], save->sec[5], save->sec[6], save->sec[7], save->output);
	   if (i) fatal_error_i("submsg_uv: write record problem %i",i);
	   free_sec(save->sec);
	   save->vname = NULL;
	}

	/* check to see if new field is a U */

	save->vname = is_u(name);

	/* if U, cache it */
	if (save->vname != NULL) {
	    copy_sec(sec,save->sec);
	    return 0;
	}

	/* not U, write it out */
	i = wrt_sec(sec[0], sec[1], sec[2], sec[3], sec[4], sec[5], sec[6], sec[7], save->output);
	if (i) fatal_error_i("submsg_uv: write problem %i",i);
	return 0;
    }
    return 0;
}
Example #28
0
unsigned char *rd_grib2_msg_seq_file(unsigned char **sec, struct seq_file *input, long int *pos, 
        unsigned long int *len, int *num_submsgs) {
    int i, j, c, c1, c2, c3, c4;
    long int len_grib;
    unsigned char *p, *end_of_msg;

    /* setup grib buffer */
    if (input->buffer == NULL) {
        if ((input->buffer = (unsigned char *) malloc(BUFF_ALLOC0)) == NULL) {
            fatal_error("not enough memory: rd_grib2_msg","");
        }
        input->buffer_size = BUFF_ALLOC0;
    }
    /* search for GRIB...2 */

    while (1) {
	c = getchar_seq_file(input);
	if (c == EOF) { *len = 0; return NULL; }
	if (c != G) continue;
        if ( (c = getchar_seq_file(input)) != R) { unget_seq_file(input, c); continue; }
        if ( (c = getchar_seq_file(input)) != I) { unget_seq_file(input, c); continue; }
        if ( (c = getchar_seq_file(input)) != B) { unget_seq_file(input, c); continue; }
        c1 = getchar_seq_file(input);
        c2 = getchar_seq_file(input);
        c3 = getchar_seq_file(input);
        c4 = getchar_seq_file(input);
        if (c4 == 1) {
	    fprintf(stderr,"grib1 message ignored (use wgrib)\n");
	    continue;
	}
        if (c4 != 2) {
	    unget_seq_file(input, c4);
	    unget_seq_file(input, c3);
	    unget_seq_file(input, c2);
	    unget_seq_file(input, c1);
	    continue;
	}
	input->buffer[0] = G;
	input->buffer[1] = R;
	input->buffer[2] = I;
	input->buffer[3] = B;
	input->buffer[4] = c1;
	input->buffer[5] = c2;
	input->buffer[6] = c3;
	input->buffer[7] = c4;
	/* fill in the size 8-15, unget buffer is empty */
	for (i = 0; i < 8; i++) { 
	    input->buffer[8+i] = c = getchar_seq_file(input);
	    if (c == EOF) {
	    	*len = 0;
		return NULL;
	    }
    	}
	break;
    }

    *len = len_grib = uint8(input->buffer+8);
    *pos = input->pos - 16;

    if (input->buffer_size < len_grib) {
        input->buffer_size = (len_grib*5)/4;
        input->buffer = (unsigned char *) realloc((void *) input->buffer, input->buffer_size);
    }

    j=fread(input->buffer+16, sizeof (unsigned char), len_grib-16, input->input);
    input->pos += j;
    
    if (j != len_grib-16) fatal_error("rd_grib2_msg_seq_file, read outside of file, bad grib file","");

    sec[0] = input->buffer;
    sec[8] = sec[0] + len_grib - 4;
    if (sec[8][0] != 55 || sec[8][1] != 55 || sec[8][2] != 55 || sec[8][3] != 55) {
        fatal_error("rd_grib2_msg_seq_file, missing end section ('7777')","");
    }

    /* scan message for number of submessages and perhaps for errors */
    p = sec[0] +  GB2_Sec0_size;
    end_of_msg = sec[0] + len_grib;

    i = 0;
    while (p < sec[8]) {
        if (p[4] == 7) i++;
	if (uint4(p) < 5) fatal_error_i("rd_grib2_msg_file: illegal grib: section length, section %i", p[4]);
        p += uint4(p);
        if (p > end_of_msg) fatal_error("bad grib format","");
    }
    if (p != sec[8]) {
        fatal_error("rd_grib2_msg: illegal format, end section expected","");
    }
    *num_submsgs = i;

    *len = len_grib;
    return sec[0];
}
Example #29
0
static int do_ave(struct ave_struct *save) {
    int i, j, n, ndata, pdt;
    float *data;
    unsigned char *p, *sec4;
    double factor;

    sec4 = NULL;
    if (save->has_val == 0) return 0; 
#ifdef DEBUG
printf(" ave nfields=%d missing=%d\n",save->n_fields,save->n_missing);
#endif

    ndata = save->n_sum;
    if ((data = (float *) malloc(sizeof(float) * ndata)) == NULL) fatal_error("ave: memory allocation","");
    factor = 1.0 / save->n_fields;
    for (i = 0; i < ndata; i++) {
    	if (save->n[i] != save->n_fields) data[i] = UNDEFINED;
    	else data[i] = factor * save->sum[i];
#ifdef DEBUG
        if (i < 10) printf("data[%d]=%lf n[%d]=%d, sum[%d]=%lf\n",
	    i,data[i],i,save->n[i],i,save->sum[i]);
#endif
    }

    pdt = GB2_ProdDefTemplateNo(save->first_sec);

    // average of a forecast

    if (pdt == 0) {
        sec4 = (unsigned char *) malloc(58 * sizeof(unsigned char));
	if (sec4 == NULL) fatal_error("fcst_ave: memory allocation","");
	for (i = 0; i < 34; i++) {
	    sec4[i] = save->first_sec[4][i];
	}
	uint_char((unsigned int) 58, sec4);		// length
	sec4[8] = 8;			// pdt
	// verification time
        save_time(save->year2,save->month2,save->day2,save->hour2,save->minute2,save->second2, sec4+34);
	sec4[41] = 1;					// 1 time range
	uint_char(save->n_missing, sec4+42);
	sec4[46] = 0;					// average
	sec4[47] = 2;					// rt=constant, ft++
	sec4[48] = save->dt_unit;					// total length of stat processing
	uint_char(save->dt*(save->n_fields+save->n_missing-1), sec4+49);
	sec4[53] = save->dt_unit;					// time step
	uint_char(save->dt, sec4+54);
    }

    // average of an ensemble forecast, use pdt 4.11

    else if (pdt == 1) {
        sec4 = (unsigned char *) malloc(61 * sizeof(unsigned char));
        if (sec4 == NULL) fatal_error("fcst_ave: memory allocation","");
        for (i = 0; i < 37; i++) {
            sec4[i] = save->first_sec[4][i];
        }
        uint_char((unsigned int) 61, sec4);             // length
        sec4[8] = 11;                    // pdt
        // verification time
        save_time(save->year2,save->month2,save->day2,save->hour2,save->minute2,save->second2, sec4+37);
        sec4[44] = 1;                                   // 1 time range
        uint_char(save->n_missing, sec4+45);
        sec4[49] = 0;                                   // average
        sec4[50] = 2;                                   // rt=constant, ft++
        sec4[51] = save->dt_unit;                                       // total length of stat processing
        uint_char(save->dt*(save->n_fields+save->n_missing-1), sec4+52);
        sec4[56] = save->dt_unit;                                       // time step
        uint_char(save->dt, sec4+57);
    }

    // average of an average or accumulation

    else if (pdt == 8) {
	i = GB2_Sec4_size(save->first_sec);
	n = save->first_sec[4][41];
	if (i != 46 + 12*n) fatal_error("ave: invalid sec4 size for pdt=8","");

        // keep pdt == 8 but make it 12 bytes bigger
        sec4 = (unsigned char *) malloc( (i+12) * sizeof(unsigned char));
	if (sec4 == NULL) fatal_error("fcst_ave: memory allocation","");

	uint_char((unsigned int) i+12, sec4);		// new length

	for (i = 4; i < 34; i++) {			// keep base of pdt
	    sec4[i] = save->first_sec[4][i];
	}
	
	// new verification time
        save_time(save->year2,save->month2,save->day2,save->hour2,save->minute2,save->second2, sec4+34);

	// number of stat-proc loops is increased by 1
	sec4[41] = n + 1;

	// copy old stat-proc loops 
	// for (j = n*12-1;  j >= 0; j--) sec4[58+j] = save->first_sec[4][46+j];
	for (j = 0; j < n*12; j++) sec4[46+12+j] = save->first_sec[4][46+j];

#ifdef DEBUG
printf("save->n_missing =%d save->n_fields=%d\n",save->n_missing,save->n_fields);
#endif
	uint_char(save->n_missing, sec4+42);
	sec4[46] = 0;			// average
	sec4[47] = 2;			// fcst++
	sec4[48] = save->dt_unit;						// total length of stat processing
	uint_char(save->dt*(save->n_fields+save->n_missing-1), sec4+49);	// missing
	sec4[53] = save->dt_unit;						// time step
	uint_char(save->dt, sec4+54);

    }
    else {
	fatal_error_i("ave with pdt %d is not supported",pdt);
    }


    // write grib file
    p = save->first_sec[4];
    save->first_sec[4] = sec4;

    grib_wrt(save->first_sec, data, ndata, save->nx, save->ny, 
	save->use_scale, save->dec_scale, save->bin_scale, 
	save->wanted_bits, save->max_bits, save->grib_type, save->output);

    if (flush_mode) fflush(save->output);
    save->first_sec[4] = p;
    free(data);
    free(sec4);
    return 0;
}