#include #include #include #define PDS_HAS_GDS(pds) ((pds[7] & 128) != 0) #define PDS_HAS_BMS(pds) ((pds[7] & 64) != 0) #define out stdout /* grib0.c Wesley Ebisuzaki 1995 * * convert grib0 to grib 1 * * step 1 .. read & parse grib file * step 2 .. write a grib1 file * * bugs: * (1) muliple vertical levels (PV, NV) not handled * (2) parameter table not changed * (3) century is hard wired to 20th century change * for 2000, century=20, year=100 * for 2001, century=21, year=1 * * 1/98 changed realloc(pds,27) to realloc(pds,28), updated bugs */ unsigned char *pds, *gds, *bms, *bds; int pds_len =0, gds_len = 0, bms_len = 0, bds_len = 0; int read_GRIB(FILE *file) { int c; /* search for GRIB */ for(;;) { c = getc(file); if (c == EOF) return 0; if (c != 'G') continue; c = getc(file); if (c == EOF) return 0; if (c != 'R') continue; c = getc(file); if (c == EOF) return 0; if (c != 'I') continue; c = getc(file); if (c == EOF) return 0; if (c != 'B') continue; break; } return 1; } int read_7777(FILE *file) { if (getc(file) != '7') return 0; if (getc(file) != '7') return 0; if (getc(file) != '7') return 0; if (getc(file) != '7') return 0; return 1; } int read_len24(FILE *file) { /* * read the length of a section .. 24 bits, unsigned integer */ int i, count, len; len = 0; for (count = 0; count < 3; count++) { i = getc(file); if (i == EOF) return -1; len = len * 256 + i; } return len; } int read_section(FILE *file, unsigned char **section, int *len) { unsigned char *space; int i; unsigned int j; if ((i = read_len24(file)) == -1) return -1; space = (unsigned char *) malloc((size_t) i); if (space == NULL) return -1; j = *len = i; space[2] = (j & 255); space[1] = ((j >> 8) & 255); space[0] = ((j >> 16) & 255); if (fread(space+3, sizeof (char), i-3, file) != i-3) { return -1; } *section = space; return 0; } void new_pds() { int i; if (pds_len < 28) { /* change to size to atleast 28 octets */ pds = (char unsigned *) realloc(pds, 28); for (i = pds_len; i < 28; i++) { pds[i] = 0; } pds[24] = 20; /* century */ pds_len = 28; /* adjust pds_len */ pds[0] = pds[1] = 0; pds[2] = 28; } /* if contents of the parameter table have changed * insert code here to * (1) change pds[8] (octet 9) parameter indicator/units * (2) change pds[3] (octet 4) parameter table version * * if the units have changed .. oh boy, you are * going to have to decode the BMS/BDS * scale the numbers * compute the BDS and BMS * this is not hard using the yet to be released gribw library */ fprintf(stderr,"pds edition# %d\n",pds[3]); } void new_gds() { gds[3] = 0; /* set NV = 0 */ gds[4] = 0; /* set PV = 0 */ } void main() { int i, len; while (read_GRIB(stdin)) { i = read_section(stdin, &pds, &pds_len); fprintf(stderr, "pds %d , rc %d\n", pds_len, i); new_pds(); if (PDS_HAS_GDS(pds)) { i = read_section(stdin, &gds, &gds_len); fprintf(stderr,"gds %d , rc %d\n", gds_len, i); new_gds(); } else { gds = NULL; gds_len = 0; } if (PDS_HAS_BMS(pds)) { i = read_section(stdin, &bms, &bms_len); fprintf(stderr,"bms %d , rc %d\n", bms_len, i); } else { bms = NULL; bms_len = 0; } i = read_section(stdin, &bds, &bds_len); fprintf(stderr,"bds %d , rc %d\n", bds_len, i); if (read_7777(stdin) == 0) { fprintf(stderr,"Missing 7777 - last section\n"); exit(8); } /* now to write file */ len = 8 + pds_len + gds_len + bms_len + bds_len + 4; fprintf(stderr,"grib1 len %d\n",len); /* write indicator section */ fprintf(out,"GRIB"); fprintf(out,"%c%c%c",(unsigned char) ((len>>16) & 255), (unsigned char) ((len>>8) & 255), (unsigned char) (len & 255)); fprintf(out,"%c", (char) 1); fwrite(pds, sizeof (char), pds_len, out); if (gds_len) { fwrite(gds, sizeof (char), gds_len, out); } if (bms_len) { fwrite(bms, sizeof (char), bms_len, out); } fwrite(bds, sizeof (char), bds_len, out); fprintf(out,"7777"); /* free memory */ free(pds); if (gds_len) free(gds); if (bms_len) free(bms); free(bds); } }