diff --git a/src/gmt_api.c b/src/gmt_api.c index 9cbffad7511..a312bb16983 100644 --- a/src/gmt_api.c +++ b/src/gmt_api.c @@ -16309,4 +16309,4 @@ int64_t gmt_eliminate_duplicates (struct GMTAPI_CTRL *API, struct GMT_DATASET *D } return (n_dup); -} +} \ No newline at end of file diff --git a/src/gmt_init.c b/src/gmt_init.c index 77006acbce8..182e31c94ae 100644 --- a/src/gmt_init.c +++ b/src/gmt_init.c @@ -14945,6 +14945,39 @@ GMT_LOCAL int gmtinit_get_region_from_data(struct GMTAPI_CTRL *API, int family, } break; + case GMT_IS_IMAGE: + if ((opt = GMT_Find_Option (API, GMT_OPT_INFILE, *options)) == NULL) return GMT_NO_INPUT; /* Got no input argument*/ + file = opt->arg; + if (gmt_M_file_is_memory (file)) { + /* For memory files, directly access the already-loaded image object */ + int object_ID, obj_item; + struct GMTAPI_DATA_OBJECT *S_obj = NULL; + if (sscanf (&file[GMTAPI_OBJECT_ID_START], "%d", &object_ID) != 1) return GMT_OBJECT_NOT_FOUND; + if ((obj_item = gmtlib_validate_id (API, GMT_NOTSET, object_ID, GMT_NOTSET, GMT_NOTSET)) == GMT_NOTSET) return GMT_OBJECT_NOT_FOUND; + S_obj = API->object[obj_item]; + if (S_obj == NULL || S_obj->resource == NULL) return GMT_PTR_IS_NULL; + I = (struct GMT_IMAGE *)S_obj->resource; + gmt_M_memcpy (wesn, I->header->wesn, 4, double); /* Copy over the image region */ + HH = gmt_get_H_hidden (I->header); + if (!exact) gmt_round_wesn (wesn, HH->grdtype > 0); /* Use image w/e/s/n to round to nearest reasonable multiples */ + if (I->header->x_units[0] && I->header->y_units[0] && !strcmp (I->header->x_units, I->header->y_units)) /* Want constant scale */ + *aspect = ((I->header->wesn[XHI]-I->header->wesn[XLO]) >= (I->header->wesn[YHI]-I->header->wesn[YLO])) ? 1 : -1; + /* Don't destroy the image - it's a reference to the original */ + } + else { + /* For regular files, read the image header */ + if (gmt_access (API->GMT, file, R_OK)) return GMT_FILE_NOT_FOUND; /* No such file found */ + if ((I = GMT_Read_Data (API, GMT_IS_IMAGE, GMT_IS_FILE, GMT_IS_SURFACE, GMT_CONTAINER_ONLY|GMT_GRID_IS_IMAGE|GMT_IO_RESET, NULL, file, NULL)) == NULL) + return API->error; /* Failure to read image header */ + gmt_M_memcpy (wesn, I->header->wesn, 4, double); /* Copy over the image region */ + HH = gmt_get_H_hidden (I->header); + if (!exact) gmt_round_wesn (wesn, HH->grdtype > 0); /* Use image w/e/s/n to round to nearest reasonable multiples */ + if (I->header->x_units[0] && I->header->y_units[0] && !strcmp (I->header->x_units, I->header->y_units)) /* Want constant scale */ + *aspect = ((I->header->wesn[XHI]-I->header->wesn[XLO]) >= (I->header->wesn[YHI]-I->header->wesn[YLO])) ? 1 : -1; + if (GMT_Destroy_Data (API, &I) != GMT_NOERROR) return API->error; /* Failure to destroy the temporary image structure */ + } + break; + case GMT_IS_DATASET: for (opt = *options; opt; opt = opt->next) { /* Loop over all options */ if (opt->option != GMT_OPT_INFILE) continue; /* Look for input files we can append to new list */ @@ -15083,11 +15116,29 @@ GMT_LOCAL int gmtinit_set_missing_R_from_grid (struct GMTAPI_CTRL *API, const ch struct GMT_OPTION *opt = NULL; double wesn[4] = {0.0, 0.0, 0.0, 0.0}; char region[GMT_LEN256] = {""}; - int err = GMT_NOERROR; + int err = GMT_NOERROR, family = GMT_IS_GRID; gmt_M_unused(args); /* Here we know the module is using a grid to get -R implicitly */ - if ((err = gmtinit_get_region_from_data (API, GMT_IS_GRID, exact, options, wesn, &API->GMT->common.R.aspect))) + /* First check if the input file is an image */ + if ((opt = GMT_Find_Option (API, GMT_OPT_INFILE, *options)) != NULL) { + /* Check for pre-loaded image in memory (virtual filename has family code 'I') */ + if (gmt_M_memfile_is_image (opt->arg)) { + family = GMT_IS_IMAGE; + } + else { + /* Check for common image extensions */ + char *ext = strrchr (opt->arg, '.'); + if (ext) { + if (strcmp (ext, ".tif") == 0 || strcmp (ext, ".tiff") == 0 || strcmp (ext, ".png") == 0 || + strcmp (ext, ".jpg") == 0 || strcmp (ext, ".jpeg") == 0 || strcmp (ext, ".bmp") == 0 || + strcmp (ext, ".gif") == 0) { + family = GMT_IS_IMAGE; + } + } + } + } + if ((err = gmtinit_get_region_from_data (API, family, exact, options, wesn, &API->GMT->common.R.aspect))) return err; snprintf (region, GMT_LEN256, "%.16g/%.16g/%.16g/%.16g", wesn[XLO], wesn[XHI], wesn[YLO], wesn[YHI]); diff --git a/src/gmt_private.h b/src/gmt_private.h index 628675ee9f5..bde87e617dd 100644 --- a/src/gmt_private.h +++ b/src/gmt_private.h @@ -247,6 +247,7 @@ struct GMTAPI_CTRL { #define GMTAPI_OBJECT_ID_START 21U /* Start position of the encoded object ID in the virtual filename */ #define gmt_M_file_is_memory(file) (file && !strncmp (file, "@GMTAPI@-", GMTAPI_PREFIX_LEN) && strlen (file) == GMTAPI_MEMFILE_LEN) #define gmt_M_memfile_is_grid(file) (gmt_M_file_is_memory(file) && file[GMTAPI_OBJECT_FAMILY_START] == 'G') +#define gmt_M_memfile_is_image(file) (gmt_M_file_is_memory(file) && file[GMTAPI_OBJECT_FAMILY_START] == 'I') #define gmt_M_memfile_is_cube(file) (gmt_M_file_is_memory(file) && file[GMTAPI_OBJECT_FAMILY_START] == 'U') #ifdef __cplusplus