/* * v_wordb -- [count]b * Move backward a word at a time. * * PUBLIC: int v_wordb __P((SCR *, VICMD *)); */ int v_wordb(SCR *sp, VICMD *vp) { return (bword(sp, vp, LITTLEWORD)); }
/* * v_WordB -- [count]B * Move backward a bigword at a time. * * PUBLIC: int v_wordB __P((SCR *, VICMD *)); */ int v_wordB(SCR *sp, VICMD *vp) { return (bword(sp, vp, BIGWORD)); }
int unpack5 (void) { int i; /* index */ static int indicator = 0x47524942; /* GRIB */ const int lenis = 8; /* length of IS Indicator Section always 8 */ int lenpds; /* length of Product Definition Section in bytes PDS */ int locpds; /* location of Product Definition Section, bytes PDS */ int lengds; /* length of Grid Description Section in bytes GDS */ int locgds; /* location of Grid Description Section in bytes GDS */ int lenbds; /* length of Binary Data Section in bytes BDS */ int lenbms; /* length of Bit Map Section in bytes BMS */ int locbms, locbds; int flag_gds_bms; int grid_id; /* grid identification byte 7 */ unsigned short int scaledx; /* decimal scaling factor with sign bit */ unsigned short int scalebx; /* binary scaling factor with sign bit */ int dscale; /* decimal scaling factor, negative is twos compliment */ int bscale; /* decimal scaling factor, negative is twos compliment */ int qno; int stat; /* status of call to x9ie32 & gribinfo */ int n_bits; /* number of bits for a packed data point */ int is; /* index for unpacking grid, byte based */ int exw; /* packed value for one gridpoint */ int ref_val_ibm; float ref_val; float Min, Max; /* min-max values of unpacked grid */ float bsc, dsc; /* binary and decimal scaling factors */ float fexw; /* floating point unpacked gridpoint vallue */ const float rho = 1.225; /* kg/m**3 */ const float g = 9.81; /* m/s**2 */ const float pvvscale = -1./(rho*g); if (bug>3) printf("in unpack5\n"); if(bug>3) fflush(NULL); /* DEBUG */ if(buf[0] != indicator) {printf("incorrect indicator %.4s %08x\n",buf,buf[0]);} stat = gribinfo (); if (stat == -2) {printf("error return from gribinfo\n"); return -2;} if (stat != 0) {printf("error return from gribinfo\n"); return -1;} locpds = lenis; lenpds = bword ( (char *)buf, locpds, 3); flag_gds_bms = bword ( (char *)buf, locpds+7, 1); locgds = locpds + lenpds; if ((flag_gds_bms & 0x00000080) > 0) {lengds = bword ( (char *)buf, locgds, 3);} else {lengds = 0;} /* grid descriptor section not present */ locbms = locgds + lengds; if ((flag_gds_bms & 0x00000040) > 0) {lenbms = bword ( (char *)buf, locbms, 3);} else {lenbms = 0;} /* bit map section not present */ locbds = locbms + lenbms; lenbds = bword ( (char *)buf, locbds, 3); grid_id = bword ( (char *)buf, locpds+6, 1); n_bits = bword ( (char *)buf, locbds+10, 1); scaledx = bword ( (char *)buf, locpds+26, 2); scalebx = bword ( (char *)buf, locbds+4, 2); dscale = lscale(scaledx); bscale = lscale(scalebx); ref_val_ibm = bword ( (char *)buf, locbds+6, 4); qno = 1; /* number of words to convert from IBM to IEEE format */ stat = x9ie32 (&ref_val_ibm,&ref_val,qno); if (stat != 0) {printf("x9ie32 error \n"); return -1;} if (bug > 3) printf("%04x %04x %4d %4d %f\n", /* DEBUG */ scaledx,scalebx, dscale,bscale, ref_val); /* DEBUG */ Min = 99999999e2; Max = -Min; if(bscale != 0) {bsc = pow(2.0, (double)bscale);} else {bsc = 1.0;} if(dscale != 0) {dsc = pow(10., (double)dscale);} else {dsc = 1.0;} is = (locbds + 11) * 8; for (i=0; i<gi.gridsize; i++) { exw = exbits(is,n_bits,buf); is = is + n_bits; fexw = (float)exw; if (bscale != 0) {fexw = fexw * bsc;} fexw = (fexw + ref_val) / dsc; exw = (int)fexw; /* should do scaling here */ /*jbuff[i] = exw;*/ ubuf[i] = fexw; if (fexw < Min) Min = fexw; if (fexw > Max) Max = fexw; } if (bug > 3) printf("min-max %14.6e %14.6e %5d\n", Min, Max, gi.gridsize); if (pvv_flag) {for(i=0; i<gi.gridsize; i++) ubuf[i] = ubuf[i] * pvvscale; if (bug>3) printf("scaled by %f\n", pvvscale); } if (bug > 3) printf("exit unpack5\n"); if (bug > 3) fflush(NULL); /* DEBUG */ return 0; }
/* * Decompress a packed data block. Returns the unpacked length if * successful, or negative error codes if not. * * If COMPRESSOR is defined, it also returns the leeway number * (which gets stored at offset 16 into the compressed-file header) * in `*leeway', if `leeway' isn't NULL. */ long rnc_unpack (void *packed, void *unpacked #ifdef COMPRESSOR , long *leeway #endif , long packed_len, long unpacked_len) { unsigned char *input = packed; unsigned char *output = unpacked; unsigned char *inputend, *outputend; bit_stream bs; huf_table raw, dist, len; unsigned long ch_count; unsigned long ret_len; unsigned out_crc; #ifdef COMPRESSOR long lee = 0; #endif if(unpacked_len >= 0) { ret_len = unpacked_len; outputend = output + ret_len; inputend = input + packed_len; out_crc = 0; goto rnc_unpack_go; } if (blong(input) != RNC_SIGNATURE) return RNC_FILE_IS_NOT_RNC; ret_len = blong (input+4); outputend = output + ret_len; inputend = input + 18 + blong(input+8); input += 18; /* skip header */ /* * Check the packed-data CRC. Also save the unpacked-data CRC * for later. */ if (rnc_crc(input, inputend-input) != bword(input-4)) return RNC_PACKED_CRC_ERROR; out_crc = bword(input-6); rnc_unpack_go: bitread_init (&bs, &input); bit_advance (&bs, 2, &input); /* discard first two bits */ /* * Process chunks. */ while (output < outputend) { #ifdef COMPRESSOR long this_lee; #endif read_huftable (&raw, &bs, &input); read_huftable (&dist, &bs, &input); read_huftable (&len, &bs, &input); ch_count = bit_read (&bs, 0xFFFF, 16, &input); while (1) { long length, posn; length = huf_read (&raw, &bs, &input); if (length == -1) return RNC_HUF_DECODE_ERROR; if (length) { while (length--) *output++ = *input++; bitread_fix (&bs, &input); } if (--ch_count <= 0) break; posn = huf_read (&dist, &bs, &input); if (posn == -1) return RNC_HUF_DECODE_ERROR; length = huf_read (&len, &bs, &input); if (length == -1) return RNC_HUF_DECODE_ERROR; posn += 1; length += 2; while (length--) { *output = output[-posn]; output++; } #ifdef COMPRESSOR this_lee = (inputend - input) - (outputend - output); if (lee < this_lee) lee = this_lee; #endif } } if (outputend != output) return RNC_FILE_SIZE_MISMATCH; #ifdef COMPRESSOR if (leeway) *leeway = lee; #endif if(unpacked_len >= 0) { // do nothing } else { /* * Check the unpacked-data CRC. */ if (rnc_crc(outputend-ret_len, ret_len) != out_crc) return RNC_UNPACKED_CRC_ERROR; } return ret_len; }
int gribinfo () { static long indicator = 0x47524942; /* GRIB */ const int lenis = 8; /* length of IS Indicator Section always 8 */ long lenpds; /* length of Product Definition Section in bytes PDS */ long locpds; /* location of Product Definition Section, bytes PDS */ long lengds; /* length of Grid Description Section in bytes GDS */ long lenbds; /* length of Binary Data Section in bytes BDS */ int flag_gds_bms; unsigned short int scaledx; /* decimal scaling factor with sign bit */ unsigned short int scalebx; /* binary scaling factor with sign bit */ int dscale; /* decimal scaling factor, negative is twos compliment */ int bscale; /* decimal scaling factor, negative is twos compliment */ int qno; int stat; /* status of call to x9ie32 & gribinfo */ int n_bits; /* number of bits for a packed data point */ long ref_val_ibm; float ref_val; int i_param; /* parameter, type of grid */ long i_level; /* indicator of level, 100 is pressure level in mb */ locpds = lenis; gi.locpds = lenis; lenpds = bword ( (char *)buf, locpds, 3); flag_gds_bms = bword ( (char *)buf, locpds+7, 1); gi.lenpds = lenpds; gi.locgds = locpds + lenpds; if ((flag_gds_bms & 0x00000080) > 0) {lengds = bword ( (char *)buf, gi.locgds, 3);} else {lengds = 0;} /* grid descriptor section not present */ gi.lengds = lengds; gi.locbms = gi.locgds + lengds; if ((flag_gds_bms & 0x00000040) > 0) {gi.lenbms = bword ( (char *)buf, gi.locbms, 3);} else {gi.lenbms = 0;} /* bit map section not present */ gi.locbds = gi.locbms + gi.lenbms; lenbds = bword ( (char *)buf, gi.locbds, 3); gi.lenbds = bword ( (char *)buf, gi.locbds, 3); gi.grid_id = bword ( (char *)buf, locpds+6, 1); n_bits = bword ( (char *)buf, gi.locbds+10, 1); scaledx = bword ( (char *)buf, locpds+26, 2); scalebx = bword ( (char *)buf, gi.locbds+4, 2); dscale = lscale(scaledx); bscale = lscale(scalebx); ref_val_ibm = bword ( (char *)buf, gi.locbds+6, 4); qno = 1; /* number of words to convert from IBM to IEEE format */ stat = x9ie32 (&ref_val_ibm,&ref_val,qno); if (stat != 0) {printf("x9ie32 error %d\n", stat); return -1;} if (bug > 3) { printf("%08x %08x %08x %08x %08x %08x %14.6e", scaledx,scalebx, dscale,bscale, ref_val_ibm,ref_val,ref_val); printf(" %08x ",ref_val); /* DEBUG */ printf("%14.6e\n", ref_val); } stat = gridproj (); if (stat != 0) {printf("error return from gridproj %d\n",stat); return -2;} i_param = bword ( (char *)buf, locpds+8, 1); i_level = bword ( (char *)buf, locpds+9, 1); if (i_level == 100) {gi.level = bword ( (char *)buf, locpds+10, 2);} /* Determine if this is a wind field */ if (i_param == winds.u_id || i_param == winds.v_id) {gi.windflag = 1;} else {gi.windflag = 0;} return 0; }
// If COMPRESSOR is defined, it also returns the leeway number // (which gets stored at offset 16 into the compressed-file header) // in `*leeway', if `leeway' isn't NULL. long rnc_unpack (void *packed, void *unpacked, unsigned int flags #ifdef COMPRESSOR , long *leeway #endif ) { unsigned char *input = (unsigned char *)packed; unsigned char *output = (unsigned char *)unpacked; unsigned char *inputend, *outputend; bit_stream bs; huf_table raw, dist, len; unsigned long ch_count; unsigned long ret_len, inp_len; long out_crc; #ifdef COMPRESSOR long lee = 0; #endif if (blong(input) != RNC_SIGNATURE) if (!(flags&RNC_IGNORE_HEADER_VAL_ERROR)) return RNC_HEADER_VAL_ERROR; ret_len = blong (input+4); inp_len = blong (input+8); if ((ret_len>(1<<30))||(inp_len>(1<<30))) return RNC_HEADER_VAL_ERROR; outputend = output + ret_len; inputend = input + 18 + inp_len; input += 18; // skip header // Check the packed-data CRC. Also save the unpacked-data CRC // for later. if (rnc_crc(input, inputend-input) != (long)bword(input-4)) if (!(flags&RNC_IGNORE_PACKED_CRC_ERROR)) return RNC_PACKED_CRC_ERROR; out_crc = bword(input-6); bitread_init (&bs, &input, inputend); bit_advance (&bs, 2, &input, inputend); // discard first two bits // Process chunks. while (output < outputend) { #ifdef COMPRESSOR long this_lee; #endif if (inputend-input<6) { if (!(flags&RNC_IGNORE_HUF_EXCEEDS_RANGE)) return RNC_HUF_EXCEEDS_RANGE; else {output=outputend;ch_count=0;break;} } read_huftable (&raw, &bs, &input, inputend); read_huftable (&dist, &bs, &input, inputend); read_huftable (&len, &bs, &input, inputend); ch_count = bit_read (&bs, 0xFFFF, 16, &input, inputend); while (1) { long length, posn; length = huf_read (&raw, &bs, &input,inputend); if (length == -1) { if (!(flags&RNC_IGNORE_HUF_DECODE_ERROR)) return RNC_HUF_DECODE_ERROR; else {output=outputend;ch_count=0;break;} } if (length) { while (length--) { if ((input>=inputend)||(output>=outputend)) { if (!(flags&RNC_IGNORE_HUF_EXCEEDS_RANGE)) return RNC_HUF_EXCEEDS_RANGE; else {output=outputend;ch_count=0;break;} } *output++ = *input++; } bitread_fix (&bs, &input, inputend); } if (--ch_count <= 0) break; posn = huf_read (&dist, &bs, &input,inputend); if (posn == -1) { if (!(flags&RNC_IGNORE_HUF_DECODE_ERROR)) return RNC_HUF_DECODE_ERROR; else {output=outputend;ch_count=0;break;} } length = huf_read (&len, &bs, &input,inputend); if (length == -1) { if (!(flags&RNC_IGNORE_HUF_DECODE_ERROR)) return RNC_HUF_DECODE_ERROR; else {output=outputend;ch_count=0;break;} } posn += 1; length += 2; while (length--) { if (((output-posn)<(unsigned char *)unpacked) || ((output-posn)>(unsigned char *)outputend) || ((output)<(unsigned char *)unpacked) || ((output)>(unsigned char *)outputend)) { if (!(flags&RNC_IGNORE_HUF_EXCEEDS_RANGE)) return RNC_HUF_EXCEEDS_RANGE; else {output=outputend-1;ch_count=0;break;} } *output = output[-posn]; output++; } #ifdef COMPRESSOR this_lee = (inputend - input) - (outputend - output); if (lee < this_lee) lee = this_lee; #endif } } if (outputend != output) { if (!(flags&RNC_IGNORE_FILE_SIZE_MISMATCH)) return RNC_FILE_SIZE_MISMATCH; } #ifdef COMPRESSOR if (leeway) *leeway = lee; #endif // Check the unpacked-data CRC. if (rnc_crc(outputend-ret_len, ret_len) != out_crc) { if (!(flags&RNC_IGNORE_UNPACKED_CRC_ERROR)) return RNC_UNPACKED_CRC_ERROR; } return ret_len; }