GRASS Programmer's Manual  6.4.2(2012)
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gdal.c
Go to the documentation of this file.
1 
14 #include <stdlib.h>
15 #include <string.h>
16 #include <grass/config.h>
17 #include <grass/gis.h>
18 #include <grass/glocale.h>
19 #include "G.h"
20 
21 #ifndef HAVE_GDAL
22 #undef GDAL_LINK
23 #endif
24 
25 #ifdef GDAL_LINK
26 
27 #ifdef GDAL_DYNAMIC
28 # if defined(__unix) || defined(__unix__)
29 # include <dlfcn.h>
30 # endif
31 # ifdef _WIN32
32 # include <windows.h>
33 # endif
34 #endif
35 
36 static void CPL_STDCALL (*pGDALAllRegister)(void);
37 static void CPL_STDCALL (*pGDALClose)(GDALDatasetH);
38 static GDALRasterBandH CPL_STDCALL (*pGDALGetRasterBand)(GDALDatasetH, int);
39 static GDALDatasetH CPL_STDCALL (*pGDALOpen)(
40  const char *pszFilename, GDALAccess eAccess);
41 static CPLErr CPL_STDCALL (*pGDALRasterIO)(
42  GDALRasterBandH hRBand, GDALRWFlag eRWFlag,
43  int nDSXOff, int nDSYOff, int nDSXSize, int nDSYSize,
44  void * pBuffer, int nBXSize, int nBYSize,GDALDataType eBDataType,
45  int nPixelSpace, int nLineSpace);
46 
47 #if GDAL_DYNAMIC
48 # if defined(__unix) && !defined(__unix__)
49 # define __unix__ __unix
50 # endif
51 
52 static void *library_h;
53 
54 static void *get_symbol(const char *name)
55 {
56  void *sym;
57 
58 # ifdef __unix__
59  sym = dlsym(library_h, name);
60 # endif
61 # ifdef _WIN32
62  sym = GetProcAddress((HINSTANCE) library_h, name);
63 # endif
64 
65  if (!sym)
66  G_fatal_error(_("Unable to locate symbol <%s>"), name);
67 
68  return sym;
69 }
70 
71 static void try_load_library(const char *name)
72 {
73 # ifdef __unix__
74  library_h = dlopen(name, RTLD_NOW);
75 # endif
76 # ifdef _WIN32
77  library_h = LoadLibrary(name);
78 # endif
79 }
80 
81 static void load_library(void)
82 {
83  static const char * const candidates[] = {
84 # ifdef __unix__
85  "libgdal.1.1.so",
86  "gdal.1.0.so",
87  "gdal.so.1.0",
88  "libgdal.so.1",
89  "libgdal.so",
90  "libgdal1.6.0.so",
91  "libgdal1.7.0.so",
92 # endif
93 # ifdef _WIN32
94  "gdal19.dll",
95  "gdal18.dll",
96  "gdal17.dll",
97  "gdal16.dll",
98  "gdal15.dll",
99  "gdal11.dll",
100  "gdal.1.0.dll",
101  "libgdal-1.dll",
102  "gdal.dll",
103 # endif
104  NULL
105  };
106  int i;
107 
108  for (i = 0; candidates[i]; i++) {
109  try_load_library(candidates[i]);
110  if (library_h)
111  return;
112  }
113 
114  G_fatal_error(_("Unable to load GDAL library"));
115 }
116 
117 static void init_gdal(void)
118 {
119  load_library();
120 
121 # ifdef _WIN32
122  pGDALAllRegister = get_symbol("_GDALAllRegister@0");
123  pGDALOpen = get_symbol("_GDALOpen@8");
124  pGDALClose = get_symbol("_GDALClose@4");
125  pGDALGetRasterBand = get_symbol("_GDALGetRasterBand@8");
126  pGDALRasterIO = get_symbol("_GDALRasterIO@48");
127 #else
128  pGDALAllRegister = get_symbol("GDALAllRegister");
129  pGDALOpen = get_symbol("GDALOpen");
130  pGDALClose = get_symbol("GDALClose");
131  pGDALGetRasterBand = get_symbol("GDALGetRasterBand");
132  pGDALRasterIO = get_symbol("GDALRasterIO");
133 #endif
134 }
135 
136 #else /* GDAL_DYNAMIC */
137 
138 static void init_gdal(void)
139 {
140  pGDALAllRegister = &GDALAllRegister;
141  pGDALOpen = &GDALOpen;
142  pGDALClose = &GDALClose;
143  pGDALGetRasterBand = &GDALGetRasterBand;
144  pGDALRasterIO = &GDALRasterIO;
145 }
146 
147 #endif /* GDAL_DYNAMIC */
148 
149 #endif /* GDAL_LINK */
150 
151 struct GDAL_link *G_get_gdal_link(const char *name, const char *mapset)
152 {
153 #ifdef GDAL_LINK
154  static int initialized;
155  GDALDatasetH data;
156  GDALRasterBandH band;
157  GDALDataType type;
158  RASTER_MAP_TYPE req_type;
159 #endif
160  const char *filename;
161  int band_num;
162  struct GDAL_link *gdal;
163  RASTER_MAP_TYPE map_type;
164  FILE *fp;
165  struct Key_Value *key_val;
166  const char *p;
167  DCELL null_val;
168 
169  if (!G_find_cell2(name, mapset))
170  return NULL;
171 
172  map_type = G_raster_map_type(name, mapset);
173  if (map_type < 0)
174  return NULL;
175 
176  fp = G_fopen_old_misc("cell_misc", "gdal", name, mapset);
177  if (!fp)
178  return NULL;
179  key_val = G_fread_key_value(fp);
180  fclose(fp);
181 
182  if (!key_val)
183  return NULL;
184 
185  filename = G_find_key_value("file", key_val);
186  if (!filename)
187  return NULL;
188 
189  p = G_find_key_value("band", key_val);
190  if (!p)
191  return NULL;
192  band_num = atoi(p);
193  if (!band_num)
194  return NULL;
195 
196  p = G_find_key_value("null", key_val);
197  if (!p)
198  return NULL;
199  if (strcmp(p, "none") == 0)
200  G_set_d_null_value(&null_val, 1);
201  else
202  null_val = atof(p);
203 
204 #ifdef GDAL_LINK
205  p = G_find_key_value("type", key_val);
206  if (!p)
207  return NULL;
208  type = atoi(p);
209 
210  switch (type) {
211  case GDT_Byte:
212  case GDT_Int16:
213  case GDT_UInt16:
214  case GDT_Int32:
215  case GDT_UInt32:
216  req_type = CELL_TYPE;
217  break;
218  case GDT_Float32:
219  req_type = FCELL_TYPE;
220  break;
221  case GDT_Float64:
222  req_type = DCELL_TYPE;
223  break;
224  default:
225  return NULL;
226  }
227 
228  if (req_type != map_type)
229  return NULL;
230 
231  if (!initialized) {
232  init_gdal();
233  (*pGDALAllRegister)();
234  initialized = 1;
235  }
236 
237  data = (*pGDALOpen)(filename, GA_ReadOnly);
238  if (!data)
239  return NULL;
240 
241  band = (*pGDALGetRasterBand)(data, band_num);
242  if (!band) {
243  (*pGDALClose)(data);
244  return NULL;
245  }
246 #endif
247 
248  gdal = G_calloc(1, sizeof(struct GDAL_link));
249 
250  gdal->filename = G_store(filename);
251  gdal->band_num = band_num;
252  gdal->null_val = null_val;
253 #ifdef GDAL_LINK
254  gdal->data = data;
255  gdal->band = band;
256  gdal->type = type;
257 #endif
258 
259  return gdal;
260 }
261 
262 void G_close_gdal_link(struct GDAL_link *gdal)
263 {
264 #ifdef GDAL_LINK
265  (*pGDALClose)(gdal->data);
266 #endif
267  G_free(gdal->filename);
268  G_free(gdal);
269 }
270 
271 #ifdef GDAL_LINK
272 CPLErr G_gdal_raster_IO(
273  GDALRasterBandH band, GDALRWFlag rw_flag,
274  int x_off, int y_off, int x_size, int y_size,
275  void *buffer, int buf_x_size, int buf_y_size, GDALDataType buf_type,
276  int pixel_size, int line_size)
277 {
278  return (*pGDALRasterIO)(
279  band, rw_flag, x_off, y_off, x_size, y_size,
280  buffer, buf_x_size, buf_y_size, buf_type,
281  pixel_size, line_size);
282 }
283 #endif