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 #endif
00023
00024 static void CPL_STDCALL(*pGDALAllRegister) (void);
00025 static void CPL_STDCALL(*pGDALClose) (GDALDatasetH);
00026 static GDALRasterBandH CPL_STDCALL(*pGDALGetRasterBand) (GDALDatasetH, int);
00027 static GDALDatasetH CPL_STDCALL(*pGDALOpen) (const char *pszFilename,
00028 GDALAccess eAccess);
00029 static CPLErr CPL_STDCALL(*pGDALRasterIO) (GDALRasterBandH hRBand,
00030 GDALRWFlag eRWFlag, int nDSXOff,
00031 int nDSYOff, int nDSXSize,
00032 int nDSYSize, void *pBuffer,
00033 int nBXSize, int nBYSize,
00034 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 "libgdal-1.dll",
00087 "gdal.dll",
00088 # endif
00089 NULL
00090 };
00091 int i;
00092
00093 for (i = 0; candidates[i]; i++) {
00094 try_load_library(candidates[i]);
00095 if (library_h)
00096 return;
00097 }
00098
00099 G_fatal_error(_("Unable to load GDAL library"));
00100 }
00101
00102 static void init_gdal(void)
00103 {
00104 load_library();
00105
00106 #ifdef _WIN32
00107 pGDALAllRegister = get_symbol("_GDALAllRegister@0");
00108 pGDALOpen = get_symbol("_GDALOpen@8");
00109 pGDALClose = get_symbol("_GDALClose@4");
00110 pGDALGetRasterBand = get_symbol("_GDALGetRasterBand@8");
00111 pGDALRasterIO = get_symbol("_GDALRasterIO@48");
00112 #else
00113 pGDALAllRegister = get_symbol("GDALAllRegister");
00114 pGDALOpen = get_symbol("GDALOpen");
00115 pGDALClose = get_symbol("GDALClose");
00116 pGDALGetRasterBand = get_symbol("GDALGetRasterBand");
00117 pGDALRasterIO = get_symbol("GDALRasterIO");
00118 #endif
00119 }
00120
00121 #else
00122
00123 static void init_gdal(void)
00124 {
00125 pGDALAllRegister = &GDALAllRegister;
00126 pGDALOpen = &GDALOpen;
00127 pGDALClose = &GDALClose;
00128 pGDALGetRasterBand = &GDALGetRasterBand;
00129 pGDALRasterIO = &GDALRasterIO;
00130 }
00131
00132 #endif
00133
00134 #endif
00135
00136 struct GDAL_link *G_get_gdal_link(const char *name, const char *mapset)
00137 {
00138 #ifdef GDAL_LINK
00139 static int initialized;
00140 GDALDatasetH data;
00141 GDALRasterBandH band;
00142 GDALDataType type;
00143 RASTER_MAP_TYPE req_type;
00144 #endif
00145 const char *filename;
00146 int band_num;
00147 struct GDAL_link *gdal;
00148 RASTER_MAP_TYPE map_type;
00149 FILE *fp;
00150 struct Key_Value *key_val;
00151 const char *p;
00152 DCELL null_val;
00153
00154 if (!G_find_cell2(name, mapset))
00155 return NULL;
00156
00157 map_type = G_raster_map_type(name, mapset);
00158 if (map_type < 0)
00159 return NULL;
00160
00161 fp = G_fopen_old_misc("cell_misc", "gdal", name, mapset);
00162 if (!fp)
00163 return NULL;
00164 key_val = G_fread_key_value(fp);
00165 fclose(fp);
00166
00167 if (!key_val)
00168 return NULL;
00169
00170 filename = G_find_key_value("file", key_val);
00171 if (!filename)
00172 return NULL;
00173
00174 p = G_find_key_value("band", key_val);
00175 if (!p)
00176 return NULL;
00177 band_num = atoi(p);
00178 if (!band_num)
00179 return NULL;
00180
00181 p = G_find_key_value("null", key_val);
00182 if (!p)
00183 return NULL;
00184 if (strcmp(p, "none") == 0)
00185 G_set_d_null_value(&null_val, 1);
00186 else
00187 null_val = atof(p);
00188
00189 #ifdef GDAL_LINK
00190 p = G_find_key_value("type", key_val);
00191 if (!p)
00192 return NULL;
00193 type = atoi(p);
00194
00195 switch (type) {
00196 case GDT_Byte:
00197 case GDT_Int16:
00198 case GDT_UInt16:
00199 case GDT_Int32:
00200 case GDT_UInt32:
00201 req_type = CELL_TYPE;
00202 break;
00203 case GDT_Float32:
00204 req_type = FCELL_TYPE;
00205 break;
00206 case GDT_Float64:
00207 req_type = DCELL_TYPE;
00208 break;
00209 default:
00210 return NULL;
00211 }
00212
00213 if (req_type != map_type)
00214 return NULL;
00215
00216 if (!initialized) {
00217 init_gdal();
00218 (*pGDALAllRegister) ();
00219 initialized = 1;
00220 }
00221
00222 data = (*pGDALOpen) (filename, GA_ReadOnly);
00223 if (!data)
00224 return NULL;
00225
00226 band = (*pGDALGetRasterBand) (data, band_num);
00227 if (!band) {
00228 (*pGDALClose) (data);
00229 return NULL;
00230 }
00231 #endif
00232
00233 gdal = G_calloc(1, sizeof(struct GDAL_link));
00234
00235 gdal->filename = G_store(filename);
00236 gdal->band_num = band_num;
00237 gdal->null_val = null_val;
00238 #ifdef GDAL_LINK
00239 gdal->data = data;
00240 gdal->band = band;
00241 gdal->type = type;
00242 #endif
00243
00244 return gdal;
00245 }
00246
00247 void G_close_gdal_link(struct GDAL_link *gdal)
00248 {
00249 #ifdef GDAL_LINK
00250 (*pGDALClose) (gdal->data);
00251 #endif
00252 G_free(gdal->filename);
00253 G_free(gdal);
00254 }
00255
00256 #ifdef GDAL_LINK
00257 CPLErr G_gdal_raster_IO(GDALRasterBandH band, GDALRWFlag rw_flag,
00258 int x_off, int y_off, int x_size, int y_size,
00259 void *buffer, int buf_x_size, int buf_y_size,
00260 GDALDataType buf_type, int pixel_size, int line_size)
00261 {
00262 return (*pGDALRasterIO) (band, rw_flag, x_off, y_off, x_size, y_size,
00263 buffer, buf_x_size, buf_y_size, buf_type,
00264 pixel_size, line_size);
00265 }
00266 #endif