[2759] | 1 | #include <stdio.h> |
---|
| 2 | #include <stdlib.h> |
---|
| 3 | |
---|
| 4 | #include "dprints.h" /* debug prints */ |
---|
| 5 | #include "gribfuncs.h" /* prototypes */ |
---|
| 6 | |
---|
| 7 | /* |
---|
| 8 | * |
---|
| 9 | ********************************************************************* |
---|
| 10 | * A. FUNCTION: apply_bitmap |
---|
| 11 | * apply the bitmap to the float array. The input float array is |
---|
| 12 | * expanded and filled with 'fill_value' in places where data |
---|
| 13 | * points are missing. |
---|
| 14 | * |
---|
| 15 | * INTERFACE: |
---|
| 16 | * int apply_bitmap (bms, pgrib_data, fill_value, bds_head, errmsg) |
---|
| 17 | * |
---|
| 18 | * ARGUMENTS (I=input, O=output, I&O=input and output): |
---|
| 19 | * (I) BMS_INPUT *bms; |
---|
| 20 | * pointer to the internal BitMap header structure; bit set means |
---|
| 21 | * datapoint is present, bit clear means datapoint is missing. |
---|
| 22 | * (I&O) float **pgrib_data; |
---|
| 23 | * pointer to Data that was unpacked from BDS's bitstr; Incoming |
---|
| 24 | * size is bms->ulbits_set or (ROW*COL - #missingpts) elements; |
---|
| 25 | * (I) float fill_value; |
---|
| 26 | * float value used for missing datapoints in expanded array; |
---|
| 27 | * (O) BDS_HEAD_INPUT *bds_head; |
---|
| 28 | * attribute 'ulGrid_size' to be updated; |
---|
| 29 | * (O) char *errmsg; |
---|
| 30 | * Empty array that's returned filled if error occurred; |
---|
| 31 | * |
---|
| 32 | * RETURN CODE: |
---|
| 33 | * 0> Success; float **pgrib_data probably have been expanded, OR |
---|
| 34 | * Predefined bitmap used, no action taken (float array unchanged); |
---|
| 35 | * 1> NULL bitmap encountered, errmsg filled; |
---|
| 36 | * 2> Error Mallocing space for data array, errmsg filled; |
---|
| 37 | * 3> Tried to access more than available in message, errmsg filled; |
---|
| 38 | * 4> No bits set in BMS, errmsg filled; |
---|
| 39 | ********************************************************************** |
---|
| 40 | */ |
---|
| 41 | #if PROTOTYPE_NEEDED |
---|
| 42 | |
---|
| 43 | int apply_bitmap ( BMS_INPUT *bms, float **pgrib_data, float fill_value, |
---|
| 44 | BDS_HEAD_INPUT *bds_head, char *errmsg) |
---|
| 45 | #else |
---|
| 46 | |
---|
| 47 | int apply_bitmap ( bms, pgrib_data, fill_value, bds_head, errmsg) |
---|
| 48 | BMS_INPUT *bms; |
---|
| 49 | float **pgrib_data; |
---|
| 50 | float fill_value; |
---|
| 51 | BDS_HEAD_INPUT *bds_head; |
---|
| 52 | char *errmsg; |
---|
| 53 | |
---|
| 54 | #endif |
---|
| 55 | { |
---|
| 56 | char *func= "apply_bitmap"; |
---|
| 57 | int i,j; /* temp var */ |
---|
| 58 | int val; /* temp var */ |
---|
| 59 | int buf_indx; /* index for expanded float *buff array */ |
---|
| 60 | int gribdata_indx; /* index for float *Grid_data array */ |
---|
| 61 | int tot_bits_set; /* must be < expanded size */ |
---|
| 62 | char *pbms; /* BIT ptr beg. at BMS data array */ |
---|
| 63 | float *fbuff; /* holds expanded float array */ |
---|
| 64 | int gridsize; /* expanded size r*c */ |
---|
| 65 | |
---|
| 66 | /* |
---|
| 67 | * |
---|
| 68 | * A.0 DEBUG printing |
---|
| 69 | */ |
---|
| 70 | DPRINT1 ("Enter %s()\n", func); |
---|
| 71 | |
---|
| 72 | /* |
---|
| 73 | * |
---|
| 74 | * A.1 IF (using pre-defined bitmap) |
---|
| 75 | * FILL errmsg ! 'case not supported' |
---|
| 76 | * RETURN 0 !success |
---|
| 77 | * ENDIF |
---|
| 78 | */ |
---|
| 79 | if (bms->uslength == 6) /* References pre-defined bitmap */ |
---|
| 80 | { |
---|
| 81 | /* Not currently supported. User can add code inside this IF |
---|
| 82 | * to retreive the bitmap from local storage if available. |
---|
| 83 | * For now, code prints warning and leaves data array alone */ |
---|
| 84 | fprintf(stdout, |
---|
| 85 | "\n%s Warning: Predefined bitmap encountered! Not supported; " \ |
---|
| 86 | "Must apply bitmap to data externally.\n", func); |
---|
| 87 | DPRINT1("Leaving %s: Predefined bitmap used, no action taken\n",func); |
---|
| 88 | return(0); |
---|
| 89 | } |
---|
| 90 | |
---|
| 91 | /* |
---|
| 92 | * |
---|
| 93 | * A.2 IF (Bitmap pointer is NULL) |
---|
| 94 | * FILL errmsg !null pointer |
---|
| 95 | * RETURN 1 |
---|
| 96 | * ENDIF |
---|
| 97 | */ |
---|
| 98 | if (bms->bit_map==NULL) { |
---|
| 99 | DPRINT1 ("Leaving %s: bitmap is Null, no action taken\n", func); |
---|
| 100 | return(1); |
---|
| 101 | } |
---|
| 102 | |
---|
| 103 | /* |
---|
| 104 | * |
---|
| 105 | * A.3 IF (count of bits set in BMS is Zero) |
---|
| 106 | * FILL errmsg |
---|
| 107 | * RETURN 4 !no bits set |
---|
| 108 | * ENDIF |
---|
| 109 | */ |
---|
| 110 | if ((tot_bits_set=bms->ulbits_set) == 0) { |
---|
| 111 | sprintf(errmsg,"%s: No bits set in bitmap. No data retrieved!!\n",func); |
---|
| 112 | DPRINT1("Leaving %s: No bits set in bitmap\n",func); |
---|
| 113 | return(4); |
---|
| 114 | } |
---|
| 115 | |
---|
| 116 | /* |
---|
| 117 | * |
---|
| 118 | * A.4 CALCULATE grid_size from total number of bits in BMS; |
---|
| 119 | */ |
---|
| 120 | /* = (BMS length)*8 bits - 48 header bits - # of unsused bits */ |
---|
| 121 | gridsize=(bms->uslength)*8 - 48 - bms->usUnused_bits; |
---|
| 122 | |
---|
| 123 | DPRINT2 ("Apply Bitmap: expanding array from [%d] to [%d]; ", |
---|
| 124 | tot_bits_set, gridsize); |
---|
| 125 | |
---|
| 126 | /* |
---|
| 127 | * |
---|
| 128 | * A.5 ALLOCATE storage for expanded array |
---|
| 129 | * IF (Malloc error) |
---|
| 130 | * RETURN 2 |
---|
| 131 | * ENDIF |
---|
| 132 | */ |
---|
| 133 | fbuff= (float *)malloc (gridsize * sizeof(float)); |
---|
| 134 | if (fbuff==(float *)NULL) |
---|
| 135 | { |
---|
| 136 | sprintf(errmsg, "%s: Error mallocing %ld bytes\n", func,gridsize); |
---|
| 137 | DPRINT1 ("Leaving %s, malloc error\n",func); |
---|
| 138 | return(2); |
---|
| 139 | } |
---|
| 140 | |
---|
| 141 | /* |
---|
| 142 | * |
---|
| 143 | * A.6 FOR (each point expected) |
---|
| 144 | */ |
---|
| 145 | pbms= bms->bit_map; /* pts to char arry bstr of BMS */ |
---|
| 146 | gribdata_indx=0; /* index for incoming float arr */ |
---|
| 147 | for (buf_indx=0; buf_indx < gridsize; ++pbms) { |
---|
| 148 | |
---|
| 149 | /* |
---|
| 150 | * A.6.1 GET next byte from Bitmap Section Data |
---|
| 151 | */ |
---|
| 152 | val= (int)*pbms & 0x0000ff ; /* BMS bitstream */ |
---|
| 153 | |
---|
| 154 | /* |
---|
| 155 | * A.6.2 LOOP, check each Bit of byte read (left to rightmost) |
---|
| 156 | */ |
---|
| 157 | for (j=7; j>=0 && buf_indx < gridsize; j--) { |
---|
| 158 | /* |
---|
| 159 | * A.6.2.1 IF (bit is set) !means datapoint is present |
---|
| 160 | */ |
---|
| 161 | if (val & (1<<j)) |
---|
| 162 | { |
---|
| 163 | /* |
---|
| 164 | * A.6.2.1.1 IF (trying to access more than #elements in Incoming Array) |
---|
| 165 | * FILL errmsg |
---|
| 166 | * RETURN 3 ! incoming float array unchanged |
---|
| 167 | * ENDIF |
---|
| 168 | */ |
---|
| 169 | if (gribdata_indx == tot_bits_set) { |
---|
| 170 | sprintf(errmsg, |
---|
| 171 | "%s: accessing more than %d elements in Grib_data[]\n", |
---|
| 172 | func, tot_bits_set); |
---|
| 173 | DPRINT1("Leaving %s, access out of range element\n",func); |
---|
| 174 | return(3); /* incoming Float array is unchanged */ |
---|
| 175 | } |
---|
| 176 | |
---|
| 177 | /* |
---|
| 178 | * A.6.2.1.2 !still within range |
---|
| 179 | * STORE datapoint at correct place in expanded array |
---|
| 180 | */ |
---|
| 181 | fbuff[buf_indx++]= (*pgrib_data)[gribdata_indx++]; |
---|
| 182 | } |
---|
| 183 | /* |
---|
| 184 | * ELSE ! means data point is missing |
---|
| 185 | */ |
---|
| 186 | else { |
---|
| 187 | /* |
---|
| 188 | * A.6.2.2 STORE Missing Value at correct place in expanded array |
---|
| 189 | */ |
---|
| 190 | fbuff[buf_indx++]= fill_value; |
---|
| 191 | } |
---|
| 192 | /* |
---|
| 193 | * A.6.2.1 ENDIF |
---|
| 194 | */ |
---|
| 195 | } /* bit loop */ |
---|
| 196 | /* |
---|
| 197 | * A.6.2 ENDLOOP |
---|
| 198 | */ |
---|
| 199 | |
---|
| 200 | } /* for every datapt */ |
---|
| 201 | /* |
---|
| 202 | * A.6 ENDFOR !for every datapoint |
---|
| 203 | */ |
---|
| 204 | |
---|
| 205 | /* |
---|
| 206 | * |
---|
| 207 | * A.7 STORE the grid size into caller's argument |
---|
| 208 | */ |
---|
| 209 | bds_head->ulGrid_size= (unsigned long)gridsize; /* store new sz */ |
---|
| 210 | |
---|
| 211 | /* |
---|
| 212 | * |
---|
| 213 | * A.8 FREE old float array |
---|
| 214 | */ |
---|
| 215 | free (*pgrib_data); |
---|
| 216 | |
---|
| 217 | /* |
---|
| 218 | * |
---|
| 219 | * A.9 ASSIGN new expanded array to pointer |
---|
| 220 | */ |
---|
| 221 | *pgrib_data= fbuff; /* give it addr of expanded arr */ |
---|
| 222 | /* |
---|
| 223 | * |
---|
| 224 | * A.10 RETURN 0 !success |
---|
| 225 | */ |
---|
| 226 | DPRINT1("Leaving %s, Stat=0", func); |
---|
| 227 | return (0); |
---|
| 228 | /* |
---|
| 229 | * |
---|
| 230 | * END OF FUNCTION |
---|
| 231 | * |
---|
| 232 | * |
---|
| 233 | */ |
---|
| 234 | } |
---|