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 | } |
---|