| 184 | #define Return(code) {Free_Ctrl (GMT, Ctrl); gmt_end_module (GMT, GMT_cpy); bailout (code);} |
| 185 | |
| 186 | EXTERN_MSC int GMT_grdsample (void *V_API, int mode, void *args) { |
| 187 | |
| 188 | int error = 0; |
| 189 | openmp_int row, col; |
| 190 | unsigned int registration; |
| 191 | |
| 192 | uint64_t ij; |
| 193 | |
| 194 | char format[GMT_BUFSIZ]; |
| 195 | |
| 196 | double *lon = NULL, lat, wesn_i[4], wesn_o[4], inc[2], ince[2]; |
| 197 | |
| 198 | struct GRDSAMPLE_CTRL *Ctrl = NULL; |
| 199 | struct GMT_GRID *Gin = NULL, *Gout = NULL; |
| 200 | struct GMT_GRID_HEADER_HIDDEN *HH = NULL; |
| 201 | struct GMT_CTRL *GMT = NULL, *GMT_cpy = NULL; |
| 202 | struct GMT_OPTION *options = NULL; |
| 203 | struct GMTAPI_CTRL *API = gmt_get_api_ptr (V_API); /* Cast from void to GMTAPI_CTRL pointer */ |
| 204 | |
| 205 | /*----------------------- Standard module initialization and parsing ----------------------*/ |
| 206 | |
| 207 | if (API == NULL) return (GMT_NOT_A_SESSION); |
| 208 | if (mode == GMT_MODULE_PURPOSE) return (usage (API, GMT_MODULE_PURPOSE)); /* Return the purpose of program */ |
| 209 | options = GMT_Create_Options (API, mode, args); if (API->error) return (API->error); /* Set or get option list */ |
| 210 | |
| 211 | if ((error = gmt_report_usage (API, options, 0, usage)) != GMT_NOERROR) bailout (error); /* Give usage if requested */ |
| 212 | |
| 213 | /* Parse the command-line arguments */ |
| 214 | |
| 215 | if ((GMT = gmt_init_module (API, THIS_MODULE_LIB, THIS_MODULE_CLASSIC_NAME, THIS_MODULE_KEYS, THIS_MODULE_NEEDS, module_kw, &options, &GMT_cpy)) == NULL) bailout (API->error); /* Save current state */ |
| 216 | if (GMT_Parse_Common (API, THIS_MODULE_OPTIONS, options)) Return (API->error); |
| 217 | Ctrl = New_Ctrl (GMT); /* Allocate and initialize a new control structure */ |
| 218 | if ((error = parse (GMT, Ctrl, options)) != 0) Return (error); |
| 219 | |
| 220 | /*---------------------------- This is the grdsample main code ----------------------------*/ |
| 221 | |
| 222 | gmt_grd_set_datapadding (GMT, true); /* Turn on gridpadding when reading a subset */ |
| 223 | |
| 224 | gmt_enable_threads (GMT); /* Set number of active threads, if supported */ |
| 225 | GMT_Report (API, GMT_MSG_INFORMATION, "Processing input grid\n"); |
| 226 | gmt_set_pad (GMT, 2U); /* Ensure space for BCs in case an API passed pad == 0 */ |
| 227 | if ((Gin = GMT_Read_Data (API, GMT_IS_GRID, GMT_IS_FILE, GMT_IS_SURFACE, GMT_CONTAINER_ONLY, NULL, Ctrl->In.file, NULL)) == NULL) { /* Get header only */ |
| 228 | Return (API->error); |
| 229 | } |
| 230 | |
| 231 | /* There are two separate regions that we need to worry about and ensure they are consistent when a user |
| 232 | * selects a subset. This is because the grid region and the desired region may not only be different, but |
| 233 | * may be phase-shifted. That means a single w/e/s/n cannot be used both to specify a subset for READING and |
| 234 | * also as an OUTPUT region. Thus, below we create two regions: |
| 235 | * wesn_i: This is initially the input grid's domain. If no -R is given then that is what we will read. |
| 236 | * wesn_o: This is the region given by -R. If no -R then it is the same as wesn_i. |
| 237 | * If no -R is given then wesn_i == wesn_o and (presumably) there is only differences in inc and registration. |
| 238 | * If there is a -R, then we adjust wesn_i and wesn_o thus: |
| 239 | * wesn_i: We move the boundaries inwards by the grid's own increments until the bounds are equal to or inside the -R. |
| 240 | * Then, if we are inside and we are able to move one step outwards we do so to ensure we cover the output range. |
| 241 | * wesn_o: We move the boundaries inwards by the -Iinc spacing as long as we are outside the input grid. |
| 242 | */ |
| 243 |
nothing calls this directly
no test coverage detected