| 6008 | |
| 6009 | /*! . */ |
| 6010 | GMT_LOCAL struct GMT_CUBE * gmtapi_import_cube (struct GMTAPI_CTRL *API, int object_ID, unsigned int mode, struct GMT_CUBE *cube) { |
| 6011 | /* Handles the reading of a 3-D data cube given in one of several ways. |
| 6012 | * Get the entire cube: |
| 6013 | * mode = GMT_CONTAINER_AND_DATA reads both header and cube; |
| 6014 | * Get a subset of the cube: Call gmtapi_import_cube twice: |
| 6015 | * 1. first with mode = GMT_CONTAINER_ONLY which reads header only. Then, pass |
| 6016 | * the new S_obj-> wesn to match your desired subregion |
| 6017 | * 2. 2nd with mode = GMT_DATA_ONLY, which reads cube based on header's settings |
| 6018 | * If the cube->data array is NULL it will be allocated for you. |
| 6019 | */ |
| 6020 | |
| 6021 | char file[PATH_MAX] = {""}; |
| 6022 | int item, new_item, new_ID; |
| 6023 | bool done = true; |
| 6024 | openmp_int row, col, kol, row_out, i0, i1, j0, j1; |
| 6025 | uint64_t k0, k1, ij, ij_orig, n_layers = 0, k, n_layers_used, here; |
| 6026 | unsigned int both_set = (GMT_CONTAINER_ONLY | GMT_DATA_ONLY); |
| 6027 | unsigned int method, start_over_method = 0; |
| 6028 | double dx, dy, d; |
| 6029 | double *level = NULL, z_min, z_max, w_range[2] = {0.0, 0.0}; |
| 6030 | p_func_uint64_t GMT_2D_to_index = NULL; |
| 6031 | struct GMT_CUBE *U_obj = NULL, *U_orig = NULL; |
| 6032 | struct GMT_GRID *G = NULL; |
| 6033 | struct GMT_MATRIX *M_obj = NULL; |
| 6034 | struct GMT_MATRIX_HIDDEN *MH = NULL; |
| 6035 | struct GMT_CUBE_HIDDEN *UH = NULL; |
| 6036 | struct GMT_GRID_HEADER_HIDDEN *HH = NULL; |
| 6037 | struct GMTAPI_DATA_OBJECT *S_obj = NULL; |
| 6038 | struct GMT_CTRL *GMT = API->GMT; |
| 6039 | GMT_getfunction api_get_val = NULL; |
| 6040 | |
| 6041 | GMT_Report (API, GMT_MSG_DEBUG, "gmtapi_import_cube: Passed ID = %d and mode = %d\n", object_ID, mode); |
| 6042 | |
| 6043 | if ((item = gmtlib_validate_id (API, GMT_IS_CUBE, object_ID, GMT_IN, GMT_NOTSET)) == GMT_NOTSET) return_null (API, API->error); |
| 6044 | |
| 6045 | S_obj = API->object[item]; /* Current data object */ |
| 6046 | if (S_obj->status != GMT_IS_UNUSED && S_obj->method == GMT_IS_FILE && !(mode & GMT_IO_RESET)) return_null (API, GMT_READ_ONCE); /* Already read this file before, so fail unless overridden by mode */ |
| 6047 | if ((mode & both_set) == both_set) mode -= both_set; /* Allow users to have set GMT_CONTAINER_ONLY | GMT_DATA_ONLY; reset to GMT_CONTAINER_AND_DATA */ |
| 6048 | if ((mode & GMT_CONTAINER_ONLY) && S_obj->region && S_obj->method == GMT_IS_FILE) { |
| 6049 | GMT_Report (API, GMT_MSG_ERROR, "Cannot request a subset when just inquiring about the cube header\n"); |
| 6050 | return_null (API, GMT_SUBSET_NOT_ALLOWED); |
| 6051 | } |
| 6052 | |
| 6053 | if (S_obj->region && cube) { /* See if this is really a subset or just the same region as the cube */ |
| 6054 | if (cube->header->wesn[XLO] == S_obj->wesn[XLO] && cube->header->wesn[XHI] == S_obj->wesn[XHI] && \ |
| 6055 | cube->header->wesn[YLO] == S_obj->wesn[YLO] && cube->header->wesn[YHI] == S_obj->wesn[YHI] && \ |
| 6056 | cube->z_range[0] == S_obj->wesn[ZLO] && cube->z_range[1] == S_obj->wesn[ZHI]) |
| 6057 | S_obj->region = false; |
| 6058 | } |
| 6059 | method = gmtapi_set_method (S_obj); /* Get the actual method to use since may be MATRIX or VECTOR masquerading as GRID */ |
| 6060 | |
| 6061 | start_over_import_cube: /* We may get here if we cannot honor a GMT_IS_REFERENCE from below */ |
| 6062 | |
| 6063 | switch (method) { |
| 6064 | /* Status: This case is fully tested and operational */ |
| 6065 | case GMT_IS_FILE: /* Name of a cube file on disk */ |
| 6066 | /* When source is an actual file we place the cube container into the S_obj->resource slot; no new object required */ |
| 6067 | /* If we need to read the header etc then we based this on the first layer in the cube */ |
no test coverage detected