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