int wgdos_expand_row_to_data( int ncols, float mdi, float accuracy, float base, Boolean *missing_data, Boolean *zero, int *data, float *unpacked_data, int *mdi_clashes, const function* const parent ) { int non_special_so_far; /* Number of non-special items unpacked so far */ int col; /* Number of items unpacked so far */ int off=1; function subroutine; int log_messages=(get_verbosity()>=VERBOSITY_MESSAGE); set_function_name(__func__, &subroutine, parent); double dacc, ddata, dbase, dval; *mdi_clashes = 0; non_special_so_far = 0; dacc=accuracy; dbase=base; message[0]=0; for ( col = 0; col < ncols; col ++ ) { off=1; if ( missing_data[col] ) { unpacked_data[col] = mdi; snprintf (message+strlen(message), MAX_MESSAGE_SIZE-strlen(message), " %012g / %-12s", unpacked_data[col],"MDI"); } else if ( zero[col] ) { unpacked_data[col] = 0.0; snprintf (message+strlen(message), MAX_MESSAGE_SIZE-strlen(message), " %012g / %-12s", unpacked_data[col],"Zero"); } else { dval=dacc*data[non_special_so_far]+dbase; unpacked_data[col] = dval; if ( unpacked_data[col] == mdi ) { (*mdi_clashes)++; } non_special_so_far++; off=1; snprintf (message+strlen(message), MAX_MESSAGE_SIZE-strlen(message), " %012g / %-12d", unpacked_data[col],data[non_special_so_far-off]); } if (log_messages &&(col%4 == 3)) { snprintf(message+strlen(message), MAX_MESSAGE_SIZE-strlen(message), "%3d", col); MO_syslog (VERBOSITY_MESSAGE, message, &subroutine); message[0]=0; } } if (message[0]!=0 && log_messages) { snprintf(message+strlen(message), MAX_MESSAGE_SIZE-strlen(message), "%3d", col); MO_syslog (VERBOSITY_MESSAGE, message, &subroutine); message[0]=0; } return 0; } /* end function PP_Wgdos_Expand_Row */
int wgdos_decode_row_parameters( char** data, float* base, Boolean *missing_data_present, Boolean *zeros_bitmap_present, int *bits_per_value, int *nop, const function* const parent ) { int int2_pair[2], int2_temp; int baselen = 1; int status=0; union { int i; float f; } basetemp; function subroutine; set_function_name(__func__, &subroutine, parent); /* Read base value for row */ /* Use the union to change byteorder of basetemp value: needs an integer, so use the int version of basetemp */ memcpy(&basetemp, *data, 4); basetemp.i = ntohl(basetemp.i); basetemp.i = ntohl(*(int*)*data); /* And change the IBM float to an IEEE float: uses the float version of basetemp */ status=convert_float_ibm_to_ieee32(&basetemp.i, (int*)base, &baselen); if (status <0) { MO_syslog(VERBOSITY_ERROR, "IEEE/IBM float conversion failed", &subroutine); } *data = *data + 4; /* Read bits_per_value and flags */ int2_temp =ntohl(*((int *)*data)); *nop=int2_temp%65536; int2_pair[0] = int2_temp >> 16; *zeros_bitmap_present = ((int2_pair[0] & 128) != 0); /* 8th bit: zero's present? */ *missing_data_present = ((int2_pair[0] & 32) != 0); /* 6th bit: MDI's present? */ *bits_per_value = int2_pair[0] & 31; /* Lowest 5 bits: bits per value (<32) */ *data = *data + 4; snprintf(message, MAX_MESSAGE_SIZE, "Decoded BitFlags Zero:%d, MDI: %d. %d bits per value base value %f, %d words taken", *zeros_bitmap_present, *missing_data_present, *bits_per_value, *base, *nop); MO_syslog(VERBOSITY_MESSAGE, message, &subroutine); return status; } /* end function PP_Wgdos_Start_Row */
int wgdos_decode_field_parameters ( /* IN */ char** data, /* address of PP field to read from */ int unpacked_len, /* Expected length that data should expand to when */ /* unpacked, >=0 */ /* OUT */ float *accuracy, /* Absolute accuracy to which data held in field */ int *ncols, /* Number of columns in field, >=0 */ int *nrows, /* Number of rows in field, >=0 */ const function* const parent ) { int log_2_acc; /* Log to base 2 of accuracy */ int status=0; function subroutine; set_function_name(__func__, &subroutine, parent); typedef struct wgdos_field_header { uint32_t total_length; uint32_t precision; uint16_t pts_in_row; uint16_t rows_in_field; } wgdos_field_header; wgdos_field_header* field_header_pointer; wgdos_field_header field_header; *accuracy = 0.0; *ncols = 0; *nrows = 0; field_header_pointer=(wgdos_field_header*)*data; field_header.total_length=ntohl(field_header_pointer->total_length); field_header.precision=ntohl(field_header_pointer->precision); field_header.pts_in_row=ntohs(field_header_pointer->pts_in_row); field_header.rows_in_field=ntohs(field_header_pointer->rows_in_field); log_2_acc=field_header.precision; *accuracy=pow(2, log_2_acc); *ncols=field_header.pts_in_row; *nrows=field_header.rows_in_field; /* read ncols, nrows */ if (*ncols <= 0) { printf("zero/negative ncols\n"); status=-1; } else if (*nrows <= 0) { printf("zero/negative nrows\n"); status = -1; } else if (*nrows * *ncols != unpacked_len) { printf("size inconsistent %d * %d != %d\n", *nrows, *ncols, unpacked_len); status = -1; } #ifdef DEBUG snprintf(message, MAX_MESSAGE_SIZE, "WGDOS_decode_field_parameters returned total length %d, precision %d, row length %d and rows %d", field_header.total_length, field_header.precision, field_header.pts_in_row, field_header.rows_in_field); MO_syslog(VERBOSITY_MESSAGE, message, &subroutine); #endif return status; }
int unpack_ppfield(float mdi, int data_size, char* data, int pack, int unpacked_size, float* to, function* parent) { float* unpacked; int* ip_in; int* ip_out; int count; function subroutine; set_function_name(__func__, &subroutine, parent); unpacked=malloc(unpacked_size*sizeof(float)); snprintf(message, MAX_MESSAGE_SIZE, "MDI %f", mdi); MO_syslog(VERBOSITY_INFO, message, &subroutine); switch(pack) { case 0: MO_syslog(VERBOSITY_INFO, "Unpacked data", &subroutine); ip_in=(int*)data; ip_out=(int*)unpacked; for (count=0; count<data_size; count++) { ip_out[count]=htonl(ip_in[count]); } break; case 1: MO_syslog(VERBOSITY_INFO, "WGDOS packed data", &subroutine); if (wgdos_unpack(data, unpacked_size, unpacked, mdi, parent)) { MO_syslog(VERBOSITY_INFO, "wgdos_unpack Failed", &subroutine); free(unpacked); return 1; } break; case 4: MO_syslog(VERBOSITY_INFO, "RLE packed data", &subroutine); ip_in=(int*)data; ip_out=(int*)data; for (count=0; count<data_size; count++) { ip_out[count]=htonl(ip_in[count]); } if (runlen_decode(unpacked, unpacked_size, (float*)data, data_size, mdi, &subroutine)) { MO_syslog(VERBOSITY_INFO, "runlen_decode Failed", &subroutine); free(unpacked); return 1; } break; default: MO_syslog(VERBOSITY_ERROR, "Unrecognised packing code", &subroutine); return 1; } if (to!=NULL) { memcpy(to, unpacked, unpacked_size*sizeof(float)); } free(unpacked); return 0; }
int wgdos_expand_broken_row_to_data( int ncols, int badnumbers, float mdi, float accuracy, float base, Boolean *missing_data, Boolean *zero, int *data, float *unpacked_data, int *mdi_clashes, const function* const parent ) { int non_special_so_far; /* Number of non-special items unpacked so far */ int col; /* Number of items unpacked so far */ int off=1; int log_messages=(get_verbosity()>=VERBOSITY_MESSAGE); function subroutine; set_function_name(__func__, &subroutine, parent); *mdi_clashes = 0; non_special_so_far = 0; message[0]=0; for ( col = 0; col < ncols; col ++ ) { off=1; if ( missing_data[col]) { unpacked_data[col] = mdi; } else if ( zero[col] ) { unpacked_data[col] = 0.0; } else { if (non_special_so_far >= badnumbers) { unpacked_data[col] = mdi; } else { unpacked_data[col] = accuracy * data[non_special_so_far] + base; if ( unpacked_data[col] == mdi ) { (*mdi_clashes)++; } non_special_so_far++; off=1; } } if (log_messages && (col%3 == 0)) { snprintf(message+strlen(message), MAX_MESSAGE_SIZE-strlen(message), "%3d", col); MO_syslog (VERBOSITY_MESSAGE, message, &subroutine); message[0]=0; } if (log_messages) { snprintf (message+strlen(message), MAX_MESSAGE_SIZE-strlen(message), " %.16g/%05d", unpacked_data[col],data[non_special_so_far-off]); } } if (log_messages && message[0]!=0) { snprintf(message+strlen(message), MAX_MESSAGE_SIZE-strlen(message), "%3d", col); MO_syslog (VERBOSITY_MESSAGE, message, &subroutine); message[0]=0; } return 0; } /* end function PP_Wgdos_Expand_Broken_Row */