00001
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <grass/config.h>
00005 #include <grass/gis.h>
00006 #include <grass/glocale.h>
00007 #include "G.h"
00008
00009 #ifndef HAVE_GDAL
00010 #undef GDAL_LINK
00011 #endif
00012
00013 #ifdef GDAL_LINK
00014
00015 #ifdef GDAL_DYNAMIC
00016 # if defined(__unix) || defined(__unix__)
00017 # include <dlfcn.h>
00018 # endif
00019 # ifdef _WIN32
00020 # include <windows.h>
00021 # endif
00022 # undef CPL_STDCALL
00023 # define CPL_STDCALL
00024 #endif
00025
00026 static void CPL_STDCALL (*pGDALAllRegister)(void);
00027 static void CPL_STDCALL (*pGDALClose)(GDALDatasetH);
00028 static GDALRasterBandH CPL_STDCALL (*pGDALGetRasterBand)(GDALDatasetH, int);
00029 static GDALDatasetH CPL_STDCALL (*pGDALOpen)(
00030 const char *pszFilename, GDALAccess eAccess);
00031 static CPLErr CPL_STDCALL (*pGDALRasterIO)(
00032 GDALRasterBandH hRBand, GDALRWFlag eRWFlag,
00033 int nDSXOff, int nDSYOff, int nDSXSize, int nDSYSize,
00034 void * pBuffer, int nBXSize, int nBYSize,GDALDataType eBDataType,
00035 int nPixelSpace, int nLineSpace);
00036
00037 #if GDAL_DYNAMIC
00038 # if defined(__unix) && !defined(__unix__)
00039 # define __unix__ __unix
00040 # endif
00041
00042 static void *library_h;
00043
00044 static void *get_symbol(const char *name)
00045 {
00046 void *sym;
00047
00048 # ifdef __unix__
00049 sym = dlsym(library_h, name);
00050 # endif
00051 # ifdef _WIN32
00052 sym = GetProcAddress((HINSTANCE) library_h, name);
00053 # endif
00054
00055 if (!sym)
00056 G_fatal_error(_("Unable to locate symbol <%s>"), name);
00057
00058 return sym;
00059 }
00060
00061 static void try_load_library(const char *name)
00062 {
00063 # ifdef __unix__
00064 library_h = dlopen(name, RTLD_NOW);
00065 # endif
00066 # ifdef _WIN32
00067 library_h = LoadLibrary(name);
00068 # endif
00069 }
00070
00071 static void load_library(void)
00072 {
00073 static const char * const candidates[] = {
00074 # ifdef __unix__
00075 "libgdal.1.1.so",
00076 "gdal.1.0.so",
00077 "gdal.so.1.0",
00078 "libgdal.so.1",
00079 "libgdal.so",
00080 # endif
00081 # ifdef _WIN32
00082 "gdal16.dll",
00083 "gdal15.dll",
00084 "gdal11.dll",
00085 "gdal.1.0.dll",
00086 "gdal.dll",
00087 # endif
00088 NULL
00089 };
00090 int i;
00091
00092 for (i = 0; candidates[i]; i++) {
00093 try_load_library(candidates[i]);
00094 if (library_h)
00095 return;
00096 }
00097
00098 G_fatal_error(_("Unable to load GDAL library"));
00099 }
00100
00101 static void init_gdal(void)
00102 {
00103 load_library();
00104
00105 pGDALAllRegister = get_symbol("GDALAllRegister");
00106 pGDALOpen = get_symbol("GDALOpen");
00107 pGDALClose = get_symbol("GDALClose");
00108 pGDALGetRasterBand = get_symbol("GDALGetRasterBand");
00109 pGDALRasterIO = get_symbol("GDALRasterIO");
00110 }
00111
00112 #else
00113
00114 static void init_gdal(void)
00115 {
00116 pGDALAllRegister = &GDALAllRegister;
00117 pGDALOpen = &GDALOpen;
00118 pGDALClose = &GDALClose;
00119 pGDALGetRasterBand = &GDALGetRasterBand;
00120 pGDALRasterIO = &GDALRasterIO;
00121 }
00122
00123 #endif
00124
00125 #endif
00126
00127 struct GDAL_link *G_get_gdal_link(const char *name, const char *mapset)
00128 {
00129 #ifdef GDAL_LINK
00130 static int initialized;
00131 GDALDatasetH data;
00132 GDALRasterBandH band;
00133 GDALDataType type;
00134 RASTER_MAP_TYPE req_type;
00135 #endif
00136 const char *filename;
00137 int band_num;
00138 struct GDAL_link *gdal;
00139 RASTER_MAP_TYPE map_type;
00140 FILE *fp;
00141 struct Key_Value *key_val;
00142 const char *p;
00143 DCELL null_val;
00144
00145 if (!G_find_cell2(name, mapset))
00146 return NULL;
00147
00148 map_type = G_raster_map_type(name, mapset);
00149 if (map_type < 0)
00150 return NULL;
00151
00152 fp = G_fopen_old_misc("cell_misc", "gdal", name, mapset);
00153 if (!fp)
00154 return NULL;
00155 key_val = G_fread_key_value(fp);
00156 fclose(fp);
00157
00158 if (!key_val)
00159 return NULL;
00160
00161 filename = G_find_key_value("file", key_val);
00162 if (!filename)
00163 return NULL;
00164
00165 p = G_find_key_value("band", key_val);
00166 if (!p)
00167 return NULL;
00168 band_num = atoi(p);
00169 if (!band_num)
00170 return NULL;
00171
00172 p = G_find_key_value("null", key_val);
00173 if (!p)
00174 return NULL;
00175 if (strcmp(p, "none") == 0)
00176 G_set_d_null_value(&null_val, 1);
00177 else
00178 null_val = atof(p);
00179
00180 #ifdef GDAL_LINK
00181 p = G_find_key_value("type", key_val);
00182 if (!p)
00183 return NULL;
00184 type = atoi(p);
00185
00186 switch (type) {
00187 case GDT_Byte:
00188 case GDT_Int16:
00189 case GDT_UInt16:
00190 case GDT_Int32:
00191 case GDT_UInt32:
00192 req_type = CELL_TYPE;
00193 break;
00194 case GDT_Float32:
00195 req_type = FCELL_TYPE;
00196 break;
00197 case GDT_Float64:
00198 req_type = DCELL_TYPE;
00199 break;
00200 default:
00201 return NULL;
00202 }
00203
00204 if (req_type != map_type)
00205 return NULL;
00206
00207 if (!initialized) {
00208 init_gdal();
00209 (*pGDALAllRegister)();
00210 initialized = 1;
00211 }
00212
00213 data = (*pGDALOpen)(filename, GA_ReadOnly);
00214 if (!data)
00215 return NULL;
00216
00217 band = (*pGDALGetRasterBand)(data, band_num);
00218 if (!band) {
00219 (*pGDALClose)(data);
00220 return NULL;
00221 }
00222 #endif
00223
00224 gdal = G_calloc(1, sizeof(struct GDAL_link));
00225
00226 gdal->filename = G_store(filename);
00227 gdal->band_num = band_num;
00228 gdal->null_val = null_val;
00229 #ifdef GDAL_LINK
00230 gdal->data = data;
00231 gdal->band = band;
00232 gdal->type = type;
00233 #endif
00234
00235 return gdal;
00236 }
00237
00238 void G_close_gdal_link(struct GDAL_link *gdal)
00239 {
00240 #ifdef GDAL_LINK
00241 (*pGDALClose)(gdal->data);
00242 #endif
00243 G_free(gdal->filename);
00244 G_free(gdal);
00245 }
00246
00247 #ifdef GDAL_LINK
00248 CPLErr G_gdal_raster_IO(
00249 GDALRasterBandH band, GDALRWFlag rw_flag,
00250 int x_off, int y_off, int x_size, int y_size,
00251 void *buffer, int buf_x_size, int buf_y_size, GDALDataType buf_type,
00252 int pixel_size, int line_size)
00253 {
00254 return (*pGDALRasterIO)(
00255 band, rw_flag, x_off, y_off, x_size, y_size,
00256 buffer, buf_x_size, buf_y_size, buf_type,
00257 pixel_size, line_size);
00258 }
00259 #endif