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