1 /******************************************************************************
2  * $Id: Dataset.i 92caa0d0f67bdff72b5f272d1558b1909bdbeaea 2021-03-31 14:38:01 +0200 Even Rouault $
3  *
4  * Name:     Dataset.i
5  * Project:  GDAL Python Interface
6  * Purpose:  GDAL Core SWIG Interface declarations.
7  * Author:   Kevin Ruland, kruland@ku.edu
8  *
9  ******************************************************************************
10  * Copyright (c) 2005, Kevin Ruland
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  *****************************************************************************/
30 
31 %{
32 /* Returned size is in bytes or 0 if an error occurred. */
33 static
ComputeDatasetRasterIOSize(int buf_xsize,int buf_ysize,int nPixelSize,int nBands,int * bandMap,int nBandMapArrayLength,GIntBig nPixelSpace,GIntBig nLineSpace,GIntBig nBandSpace,int bSpacingShouldBeMultipleOfPixelSize)34 GIntBig ComputeDatasetRasterIOSize (int buf_xsize, int buf_ysize, int nPixelSize,
35                                 int nBands, int* bandMap, int nBandMapArrayLength,
36                                 GIntBig nPixelSpace, GIntBig nLineSpace, GIntBig nBandSpace,
37                                 int bSpacingShouldBeMultipleOfPixelSize )
38 {
39     if (buf_xsize <= 0 || buf_ysize <= 0)
40     {
41         CPLError(CE_Failure, CPLE_IllegalArg, "Illegal values for buffer size");
42         return 0;
43     }
44 
45     if (nPixelSpace < 0 || nLineSpace < 0 || nBandSpace < 0)
46     {
47         CPLError(CE_Failure, CPLE_IllegalArg, "Illegal values for space arguments");
48         return 0;
49     }
50 
51     if (nPixelSize == 0)
52     {
53         CPLError(CE_Failure, CPLE_IllegalArg, "Illegal value for data type");
54         return 0;
55     }
56 
57     if( nPixelSpace == 0 )
58         nPixelSpace = nPixelSize;
59     else if ( bSpacingShouldBeMultipleOfPixelSize && (nPixelSpace % nPixelSize) != 0 )
60     {
61         CPLError(CE_Failure, CPLE_IllegalArg, "nPixelSpace should be a multiple of nPixelSize");
62         return 0;
63     }
64 
65     if( nLineSpace == 0 )
66     {
67         nLineSpace = nPixelSpace * buf_xsize;
68     }
69     else if ( bSpacingShouldBeMultipleOfPixelSize && (nLineSpace % nPixelSize) != 0 )
70     {
71         CPLError(CE_Failure, CPLE_IllegalArg, "nLineSpace should be a multiple of nPixelSize");
72         return 0;
73     }
74 
75     if( nBandSpace == 0 )
76     {
77         nBandSpace = nLineSpace * buf_ysize;
78     }
79     else if ( bSpacingShouldBeMultipleOfPixelSize && (nBandSpace % nPixelSize) != 0 )
80     {
81         CPLError(CE_Failure, CPLE_IllegalArg, "nLineSpace should be a multiple of nPixelSize");
82         return 0;
83     }
84 
85     if (nBands <= 0 || (bandMap != NULL && nBands > nBandMapArrayLength))
86     {
87         CPLError(CE_Failure, CPLE_IllegalArg, "Invalid band count");
88         return 0;
89     }
90 
91     GIntBig nRet = (GIntBig)(buf_ysize - 1) * nLineSpace + (GIntBig)(buf_xsize - 1) * nPixelSpace + (GIntBig)(nBands - 1) * nBandSpace + nPixelSize;
92 #if SIZEOF_VOIDP == 4
93     if (nRet > INT_MAX)
94     {
95         CPLError(CE_Failure, CPLE_IllegalArg, "Integer overflow");
96         return 0;
97     }
98 #endif
99 
100     return nRet;
101 }
102 %}
103 
104 #if defined(SWIGPERL)
105 %{
106 static
DSReadRaster_internal(GDALDatasetShadow * obj,int xoff,int yoff,int xsize,int ysize,int buf_xsize,int buf_ysize,GDALDataType buf_type,GIntBig * buf_size,char ** buf,int band_list,int * pband_list,GIntBig pixel_space,GIntBig line_space,GIntBig band_space,GDALRasterIOExtraArg * psExtraArg)107 CPLErr DSReadRaster_internal( GDALDatasetShadow *obj,
108                             int xoff, int yoff, int xsize, int ysize,
109                             int buf_xsize, int buf_ysize,
110                             GDALDataType buf_type,
111                             GIntBig *buf_size, char **buf,
112                             int band_list, int *pband_list,
113                             GIntBig pixel_space, GIntBig line_space, GIntBig band_space,
114                             GDALRasterIOExtraArg* psExtraArg)
115 {
116   CPLErr result;
117 
118   *buf_size = ComputeDatasetRasterIOSize (buf_xsize, buf_ysize, GDALGetDataTypeSize( buf_type ) / 8,
119                                           band_list ? band_list : GDALGetRasterCount(obj), pband_list, band_list,
120                                           pixel_space, line_space, band_space, FALSE);
121   if (*buf_size == 0)
122   {
123       *buf = 0;
124       return CE_Failure;
125   }
126 
127   *buf = (char*) malloc( *buf_size );
128   if (*buf)
129   {
130     result = GDALDatasetRasterIOEx(obj, GF_Read, xoff, yoff, xsize, ysize,
131                                     (void*) *buf, buf_xsize, buf_ysize, buf_type,
132                                     band_list, pband_list, pixel_space, line_space, band_space,
133                                     psExtraArg );
134     if ( result != CE_None ) {
135         free( *buf );
136         *buf = 0;
137         *buf_size = 0;
138     }
139   }
140   else
141   {
142     CPLError(CE_Failure, CPLE_OutOfMemory, "Not enough memory to allocate " CPL_FRMT_GIB " bytes", *buf_size);
143     result = CE_Failure;
144     *buf = 0;
145     *buf_size = 0;
146   }
147   return result;
148 }
149 %}
150 
151 #endif
152 
153 #if !defined(SWIGJAVA)
154 
155 //************************************************************************/
156 //
157 // Define the extensions for GDALAsyncReader (nee GDALAsyncReaderShadow)
158 //
159 //************************************************************************/
160 %rename (AsyncReader) GDALAsyncReaderShadow;
161 
162 
163 %{
164 typedef struct
165 {
166     GDALAsyncReaderH  hAsyncReader;
167     void             *pyObject;
168 } GDALAsyncReaderWrapper;
169 
170 typedef void* GDALAsyncReaderWrapperH;
171 
AsyncReaderWrapperGetReader(GDALAsyncReaderWrapperH hWrapper)172 static GDALAsyncReaderH AsyncReaderWrapperGetReader(GDALAsyncReaderWrapperH hWrapper)
173 {
174     GDALAsyncReaderWrapper* psWrapper = (GDALAsyncReaderWrapper*)hWrapper;
175     if (psWrapper->hAsyncReader == NULL)
176     {
177         CPLError(CE_Failure, CPLE_AppDefined, "AsyncReader object is defunct");
178     }
179     return psWrapper->hAsyncReader;
180 }
181 
182 #if defined(SWIGPYTHON)
AsyncReaderWrapperGetPyObject(GDALAsyncReaderWrapperH hWrapper)183 static void* AsyncReaderWrapperGetPyObject(GDALAsyncReaderWrapperH hWrapper)
184 {
185     GDALAsyncReaderWrapper* psWrapper = (GDALAsyncReaderWrapper*)hWrapper;
186     return psWrapper->pyObject;
187 }
188 #endif
189 
DeleteAsyncReaderWrapper(GDALAsyncReaderWrapperH hWrapper)190 static void DeleteAsyncReaderWrapper(GDALAsyncReaderWrapperH hWrapper)
191 {
192     GDALAsyncReaderWrapper* psWrapper = (GDALAsyncReaderWrapper*)hWrapper;
193     if (psWrapper->hAsyncReader != NULL)
194     {
195         CPLError(CE_Failure, CPLE_AppDefined,
196                  "Native AsyncReader object will leak. EndAsyncReader() should have been called before");
197     }
198     CPLFree(psWrapper);
199 }
200 
201 %}
202 
203 #if defined(SWIGPYTHON)
204 
205 %nothread;
206 
207 %{
208 
CreateAsyncReaderWrapper(GDALAsyncReaderH hAsyncReader,void * pyObject)209 static GDALAsyncReaderWrapper* CreateAsyncReaderWrapper(GDALAsyncReaderH  hAsyncReader,
210                                                         void             *pyObject)
211 {
212     GDALAsyncReaderWrapper* psWrapper = (GDALAsyncReaderWrapper* )CPLMalloc(sizeof(GDALAsyncReaderWrapper));
213     psWrapper->hAsyncReader = hAsyncReader;
214     psWrapper->pyObject = pyObject;
215     Py_INCREF((PyObject*) psWrapper->pyObject);
216     return psWrapper;
217 }
218 
DisableAsyncReaderWrapper(GDALAsyncReaderWrapperH hWrapper)219 static void DisableAsyncReaderWrapper(GDALAsyncReaderWrapperH hWrapper)
220 {
221     GDALAsyncReaderWrapper* psWrapper = (GDALAsyncReaderWrapper*)hWrapper;
222     if (psWrapper->pyObject)
223     {
224         Py_XDECREF((PyObject*) psWrapper->pyObject);
225     }
226     psWrapper->pyObject = NULL;
227     psWrapper->hAsyncReader = NULL;
228 }
229 %}
230 
231 %thread;
232 
233 #endif
234 
235 class GDALAsyncReaderShadow {
236 private:
237   GDALAsyncReaderShadow();
238 public:
239 %extend {
~GDALAsyncReaderShadow()240     ~GDALAsyncReaderShadow()
241     {
242         DeleteAsyncReaderWrapper(self);
243     }
244 
245     %apply (int *OUTPUT) {(int *)};
GetNextUpdatedRegion(double timeout,int * xoff,int * yoff,int * buf_xsize,int * buf_ysize)246     GDALAsyncStatusType GetNextUpdatedRegion(double timeout, int* xoff, int* yoff, int* buf_xsize, int* buf_ysize )
247     {
248         GDALAsyncReaderH hReader = AsyncReaderWrapperGetReader(self);
249         if (hReader == NULL)
250         {
251             *xoff = 0;
252             *yoff = 0;
253             *buf_xsize = 0;
254             *buf_ysize = 0;
255             return GARIO_ERROR;
256         }
257         return GDALARGetNextUpdatedRegion(hReader, timeout, xoff, yoff, buf_xsize, buf_ysize );
258     }
259     %clear (int *);
260 
261 #if defined(SWIGPYTHON)
262     %apply ( void **outPythonObject ) { (void** ppRetPyObject ) };
GetBuffer(void ** ppRetPyObject)263     void GetBuffer(void** ppRetPyObject)
264     {
265         GDALAsyncReaderH hReader = AsyncReaderWrapperGetReader(self);
266         if (hReader == NULL)
267         {
268             *ppRetPyObject = NULL;
269             return;
270         }
271         *ppRetPyObject = AsyncReaderWrapperGetPyObject(self);
272         Py_INCREF((PyObject*)*ppRetPyObject);
273     }
274     %clear (void** ppRetPyObject );
275 #endif
276 
LockBuffer(double timeout)277     int LockBuffer( double timeout )
278     {
279         GDALAsyncReaderH hReader = AsyncReaderWrapperGetReader(self);
280         if (hReader == NULL)
281         {
282             return 0;
283         }
284         return GDALARLockBuffer(hReader,timeout);
285     }
286 
UnlockBuffer()287     void UnlockBuffer()
288     {
289         GDALAsyncReaderH hReader = AsyncReaderWrapperGetReader(self);
290         if (hReader == NULL)
291         {
292             return;
293         }
294         GDALARUnlockBuffer(hReader);
295     }
296 
297     } /* extend */
298 }; /* GDALAsyncReaderShadow */
299 
300 #endif // !defined(SWIGJAVA)
301 
302 //************************************************************************/
303 //
304 // Define the extensions for Dataset (nee GDALDatasetShadow)
305 //
306 //************************************************************************/
307 
308 %rename (Dataset) GDALDatasetShadow;
309 
310 #ifdef SWIGPYTHON
311 %rename (_SetGCPs) SetGCPs;
312 %rename (_SetGCPs2) SetGCPs2;
313 #endif
314 
315 class GDALDatasetShadow : public GDALMajorObjectShadow {
316 private:
317   GDALDatasetShadow();
318 public:
319 %extend {
320 
321 %immutable;
322   int RasterXSize;
323   int RasterYSize;
324   int RasterCount;
325 //
326 // Needed
327 // _band list?
328 %mutable;
329 
~GDALDatasetShadow()330   ~GDALDatasetShadow() {
331     if ( GDALDereferenceDataset( self ) <= 0 ) {
332       GDALClose(self);
333     }
334   }
335 
GetDriver()336   GDALDriverShadow* GetDriver() {
337     return (GDALDriverShadow*) GDALGetDatasetDriver( self );
338   }
339 
GetRasterBand(int nBand)340   GDALRasterBandShadow* GetRasterBand(int nBand ) {
341     return (GDALRasterBandShadow*) GDALGetRasterBand( self, nBand );
342   }
343 
344 %newobject GetRootGroup;
GetRootGroup()345   GDALGroupHS* GetRootGroup() {
346     return GDALDatasetGetRootGroup(self);
347   }
348 
GetProjection()349   char const *GetProjection() {
350     return GDALGetProjectionRef( self );
351   }
352 
GetProjectionRef()353   char const *GetProjectionRef() {
354     return GDALGetProjectionRef( self );
355   }
356 
357   %newobject GetSpatialRef;
GetSpatialRef()358   OSRSpatialReferenceShadow *GetSpatialRef() {
359     OGRSpatialReferenceH ref = GDALGetSpatialRef(self);
360     if( ref )
361        ref = OSRClone( ref );
362     return (OSRSpatialReferenceShadow*) ref;
363   }
364 
365   %apply Pointer NONNULL {char const *prj};
SetProjection(char const * prj)366   CPLErr SetProjection( char const *prj ) {
367     return GDALSetProjection( self, prj );
368   }
369   %clear char const *prj;
370 
SetSpatialRef(OSRSpatialReferenceShadow * srs)371   CPLErr SetSpatialRef(OSRSpatialReferenceShadow* srs)
372   {
373      return GDALSetSpatialRef( self, (OGRSpatialReferenceH)srs );
374   }
375 
376 #ifdef SWIGPYTHON
377 %feature("kwargs") GetGeoTransform;
378 %apply (int *optional_int) { (int*) };
379   void GetGeoTransform( double argout[6], int* isvalid, int* can_return_null = 0 ) {
380     if (can_return_null && *can_return_null)
381     {
382         *isvalid = (GDALGetGeoTransform( self, argout ) == CE_None );
383     }
384     else
385     {
386         *isvalid = TRUE;
387         if ( GDALGetGeoTransform( self, argout ) != CE_None ) {
388             argout[0] = 0.0;
389             argout[1] = 1.0;
390             argout[2] = 0.0;
391             argout[3] = 0.0;
392             argout[4] = 0.0;
393             argout[5] = 1.0;
394         }
395     }
396   }
397 %clear (int*);
398 #else
GetGeoTransform(double argout[6])399   void GetGeoTransform( double argout[6] ) {
400     if ( GDALGetGeoTransform( self, argout ) != CE_None ) {
401       argout[0] = 0.0;
402       argout[1] = 1.0;
403       argout[2] = 0.0;
404       argout[3] = 0.0;
405       argout[4] = 0.0;
406       argout[5] = 1.0;
407     }
408   }
409 #endif
410 
SetGeoTransform(double argin[6])411   CPLErr SetGeoTransform( double argin[6] ) {
412     return GDALSetGeoTransform( self, argin );
413   }
414 
415   // The (int,int*) arguments are typemapped.  The name of the first argument
416   // becomes the kwarg name for it.
417 #ifndef SWIGCSHARP
418 #ifndef SWIGJAVA
419 %feature("kwargs") BuildOverviews;
420 #endif
421 %apply (int nList, int* pList) { (int overviewlist, int *pOverviews) };
422 #else
423 %apply (void *buffer_ptr) {int *pOverviews};
424 #endif
425 #ifdef SWIGJAVA
426 %apply (const char* stringWithDefaultValue) {const char* resampling};
427   int BuildOverviews( const char *resampling,
428                       int overviewlist, int *pOverviews,
429                       GDALProgressFunc callback = NULL,
430                       void* callback_data=NULL ) {
431 #else
432   int BuildOverviews( const char *resampling = "NEAREST",
433                       int overviewlist = 0 , int *pOverviews = 0,
434                       GDALProgressFunc callback = NULL,
435                       void* callback_data=NULL ) {
436 #endif
437     return GDALBuildOverviews(  self,
438                                 resampling ? resampling : "NEAREST",
439                                 overviewlist,
440                                 pOverviews,
441                                 0,
442                                 0,
443                                 callback,
444                                 callback_data);
445   }
446 #ifndef SWIGCSHARP
447 %clear (int overviewlist, int *pOverviews);
448 #else
449 %clear (int *pOverviews);
450 #endif
451 #ifdef SWIGJAVA
452 %clear (const char *resampling);
453 #endif
454 
GetGCPCount()455   int GetGCPCount() {
456     return GDALGetGCPCount( self );
457   }
458 
GetGCPProjection()459   const char *GetGCPProjection() {
460     return GDALGetGCPProjection( self );
461   }
462 
463 #ifndef SWIGCSHARP
464   %newobject GetGCPSpatialRef;
GetGCPSpatialRef()465   OSRSpatialReferenceShadow *GetGCPSpatialRef() {
466     OGRSpatialReferenceH ref = GDALGetGCPSpatialRef(self);
467     if( ref )
468        ref = OSRClone( ref );
469     return (OSRSpatialReferenceShadow*) ref;
470   }
471 #endif
472 
473 #ifndef SWIGCSHARP
GetGCPs(int * nGCPs,GDAL_GCP const ** pGCPs)474   void GetGCPs( int *nGCPs, GDAL_GCP const **pGCPs ) {
475     *nGCPs = GDALGetGCPCount( self );
476     *pGCPs = GDALGetGCPs( self );
477   }
478 
SetGCPs(int nGCPs,GDAL_GCP const * pGCPs,const char * pszGCPProjection)479   CPLErr SetGCPs( int nGCPs, GDAL_GCP const *pGCPs, const char *pszGCPProjection ) {
480     return GDALSetGCPs( self, nGCPs, pGCPs, pszGCPProjection );
481   }
482 
SetGCPs2(int nGCPs,GDAL_GCP const * pGCPs,OSRSpatialReferenceShadow * hSRS)483   CPLErr SetGCPs2( int nGCPs, GDAL_GCP const *pGCPs, OSRSpatialReferenceShadow* hSRS ) {
484     return GDALSetGCPs2( self, nGCPs, pGCPs, (OGRSpatialReferenceH)hSRS );
485   }
486 
487 #endif
488 
FlushCache()489   void FlushCache() {
490     GDALFlushCache( self );
491   }
492 
493 #ifndef SWIGJAVA
494 %feature ("kwargs") AddBand;
495 #endif
496 /* uses the defined char **options typemap */
497   CPLErr AddBand( GDALDataType datatype = GDT_Byte, char **options = 0 ) {
498     return GDALAddBand( self, datatype, options );
499   }
500 
CreateMaskBand(int nFlags)501   CPLErr CreateMaskBand( int nFlags ) {
502       return GDALCreateDatasetMaskBand( self, nFlags );
503   }
504 
505 %apply (char **CSL) {char **};
GetFileList()506   char **GetFileList() {
507     return GDALGetFileList( self );
508   }
509 %clear char **;
510 
511 #if defined(SWIGPYTHON) || defined(SWIGPERL)
512 %feature("kwargs") WriteRaster;
513 %apply (GIntBig nLen, char *pBuf) { (GIntBig buf_len, char *buf_string) };
514 %apply (GIntBig *optional_GIntBig) { (GIntBig*) };
515 %apply (int *optional_int) { (int*) };
516 #if defined(SWIGPYTHON)
517 %apply (GDALDataType *optional_GDALDataType) { (GDALDataType *buf_type) };
518 #else
519 %apply (int *optional_int) { (GDALDataType *buf_type) };
520 #endif
521 %apply (int nList, int *pList ) { (int band_list, int *pband_list ) };
522   CPLErr WriteRaster( int xoff, int yoff, int xsize, int ysize,
523                       GIntBig buf_len, char *buf_string,
524                       int *buf_xsize = 0, int *buf_ysize = 0,
525                       GDALDataType *buf_type = 0,
526                       int band_list = 0, int *pband_list = 0,
527                       GIntBig* buf_pixel_space = 0, GIntBig* buf_line_space = 0, GIntBig* buf_band_space = 0) {
528     CPLErr eErr;
529     int nxsize = (buf_xsize==0) ? xsize : *buf_xsize;
530     int nysize = (buf_ysize==0) ? ysize : *buf_ysize;
531     GDALDataType ntype;
532     if ( buf_type != 0 ) {
533       ntype = (GDALDataType) *buf_type;
534     } else {
535       int lastband = GDALGetRasterCount( self );
536       if (lastband <= 0)
537         return CE_Failure;
538       ntype = GDALGetRasterDataType( GDALGetRasterBand( self, lastband ) );
539     }
540 
541     GIntBig pixel_space = (buf_pixel_space == 0) ? 0 : *buf_pixel_space;
542     GIntBig line_space = (buf_line_space == 0) ? 0 : *buf_line_space;
543     GIntBig band_space = (buf_band_space == 0) ? 0 : *buf_band_space;
544 
545     GIntBig min_buffer_size =
546       ComputeDatasetRasterIOSize (nxsize, nysize, GDALGetDataTypeSize( ntype ) / 8,
547                                   band_list ? band_list : GDALGetRasterCount(self), pband_list, band_list,
548                                   pixel_space, line_space, band_space, FALSE);
549     if (min_buffer_size == 0)
550         return CE_Failure;
551 
552     if ( buf_len < min_buffer_size )
553     {
554         CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
555         return CE_Failure;
556     }
557 
558     GDALRasterIOExtraArg* psExtraArg = NULL;
559 
560     eErr = GDALDatasetRasterIOEx( self, GF_Write, xoff, yoff, xsize, ysize,
561                                   (void*) buf_string, nxsize, nysize, ntype,
562                                   band_list, pband_list, pixel_space, line_space, band_space, psExtraArg );
563 
564     return eErr;
565   }
566 %clear (int band_list, int *pband_list );
567 %clear (GDALDataType *buf_type);
568 %clear (int*);
569 %clear (GIntBig*);
570 %clear (GIntBig buf_len, char *buf_string);
571 #endif
572 
573 #if defined(SWIGPERL)
574 %feature("kwargs") ReadRaster;
575 %apply (int *optional_int) { (GDALDataType *buf_type) };
576 %apply (int nList, int *pList ) { (int band_list, int *pband_list ) };
577 %apply (GIntBig *nLen, char **pBuf) { (GIntBig *buf_len, char **buf) };
578 %apply ( int *optional_int ) {(int*)};
579 %apply ( GIntBig *optional_GIntBig ) {(GIntBig*)};
580 CPLErr ReadRaster(  int xoff, int yoff, int xsize, int ysize,
581 	              GIntBig *buf_len, char **buf,
582                       int *buf_xsize = 0, int *buf_ysize = 0,
583                       GDALDataType *buf_type = 0,
584                       int band_list = 0, int *pband_list = 0,
585                       GIntBig* buf_pixel_space = 0, GIntBig* buf_line_space = 0, GIntBig* buf_band_space = 0,
586                       GDALRIOResampleAlg resample_alg = GRIORA_NearestNeighbour,
587                       GDALProgressFunc callback = NULL,
588                       void* callback_data=NULL )
589 {
590     CPLErr eErr;
591     int nxsize = (buf_xsize==0) ? xsize : *buf_xsize;
592     int nysize = (buf_ysize==0) ? ysize : *buf_ysize;
593     GDALDataType ntype;
594     if ( buf_type != 0 ) {
595       ntype = (GDALDataType) *buf_type;
596     } else {
597       int lastband = GDALGetRasterCount( self );
598       if (lastband <= 0)
599         return CE_Failure;
600       ntype = GDALGetRasterDataType( GDALGetRasterBand( self, lastband ) );
601     }
602 
603     GDALRasterIOExtraArg sExtraArg;
604     INIT_RASTERIO_EXTRA_ARG(sExtraArg);
605     sExtraArg.eResampleAlg = resample_alg;
606     sExtraArg.pfnProgress = callback;
607     sExtraArg.pProgressData = callback_data;
608 
609     GIntBig pixel_space = (buf_pixel_space == 0) ? 0 : *buf_pixel_space;
610     GIntBig line_space = (buf_line_space == 0) ? 0 : *buf_line_space;
611     GIntBig band_space = (buf_band_space == 0) ? 0 : *buf_band_space;
612 
613     eErr = DSReadRaster_internal( self, xoff, yoff, xsize, ysize,
614                                 nxsize, nysize, ntype,
615                                 buf_len, buf,
616                                 band_list, pband_list,
617                                 pixel_space, line_space, band_space, &sExtraArg);
618 
619     return eErr;
620 }
621 
622 %clear (GDALDataType *buf_type);
623 %clear (int band_list, int *pband_list );
624 %clear (int *buf_len, char **buf );
625 %clear (int*);
626 %clear (GIntBig*);
627 #endif
628 
629 %apply (int *optional_int) { (GDALDataType *buf_type) };
630 %apply (int nList, int *pList ) { (int band_list, int *pband_list ) };
631 CPLErr AdviseRead(  int xoff, int yoff, int xsize, int ysize,
632                     int *buf_xsize = 0, int *buf_ysize = 0,
633                     GDALDataType *buf_type = 0,
634                     int band_list = 0, int *pband_list = 0,
635                     char** options = NULL )
636 {
637     int nxsize = (buf_xsize==0) ? xsize : *buf_xsize;
638     int nysize = (buf_ysize==0) ? ysize : *buf_ysize;
639     GDALDataType ntype;
640     if ( buf_type != 0 ) {
641       ntype = (GDALDataType) *buf_type;
642     } else {
643       int lastband = GDALGetRasterCount( self );
644       if (lastband <= 0)
645         return CE_Failure;
646       ntype = GDALGetRasterDataType( GDALGetRasterBand( self, lastband ) );
647     }
648     return GDALDatasetAdviseRead(self, xoff, yoff, xsize, ysize,
649                                  nxsize, nysize, ntype,
650                                  band_list, pband_list, options);
651 }
652 %clear (GDALDataType *buf_type);
653 %clear (int band_list, int *pband_list );
654 
655 /* NEEDED */
656 /* GetSubDatasets */
657 /* ReadAsArray */
658 /* AddBand */
659 
660 #if defined(SWIGPYTHON)
661 %feature("kwargs") BeginAsyncReader;
662 %newobject BeginAsyncReader;
663 %apply (int nList, int *pList ) { (int band_list, int *pband_list ) };
664 %apply (int nLenKeepObject, char *pBufKeepObject, void* pyObject) { (int buf_len, char *buf_string, void* pyObject) };
665 %apply (int *optional_int) { (int*) };
666   GDALAsyncReaderShadow* BeginAsyncReader(
667        int xOff, int yOff, int xSize, int ySize,
668        int buf_len, char *buf_string, void* pyObject,
669        int buf_xsize, int buf_ysize, GDALDataType bufType = (GDALDataType)0,
670        int band_list = 0, int *pband_list = 0, int nPixelSpace = 0,
671        int nLineSpace = 0, int nBandSpace = 0, char **options = 0)  {
672 
673     if ((options != NULL) && (buf_xsize ==0) && (buf_ysize == 0))
674     {
675         // calculate an appropriate buffer size
676         const char* pszLevel = CSLFetchNameValue(options, "LEVEL");
677         if (pszLevel)
678         {
679             // round up
680             int nLevel = atoi(pszLevel);
681             if( nLevel < 0 || nLevel > 30 )
682             {
683                 CPLError(CE_Failure, CPLE_AppDefined, "Invalid LEVEL: %d", nLevel);
684             }
685             else
686             {
687                 int nRes = 1 << nLevel;
688                 buf_xsize = static_cast<int>(ceil(xSize / (1.0 * nRes)));
689                 buf_ysize = static_cast<int>(ceil(ySize / (1.0 * nRes)));
690             }
691         }
692     }
693 
694     int nxsize = (buf_xsize == 0) ? xSize : buf_xsize;
695     int nysize = (buf_ysize == 0) ? ySize : buf_ysize;
696 
697     GDALDataType ntype;
698     if (bufType != 0) {
699         ntype = (GDALDataType) bufType;
700     }
701     else {
702         ntype = GDT_Byte;
703     }
704 
705     int nBCount = (band_list) != 0 ? band_list : GDALGetRasterCount(self);
706     int nMinSize = nxsize * nysize * nBCount * (GDALGetDataTypeSize(ntype) / 8);
707     if (buf_string == NULL || buf_len < nMinSize)
708     {
709         CPLError(CE_Failure, CPLE_AppDefined, "Buffer is too small");
710         return NULL;
711     }
712 
713     bool myBandList = false;
714     int* pBandList;
715 
716     if (band_list != 0){
717         myBandList = false;
718         pBandList = pband_list;
719     }
720     else
721     {
722         myBandList = true;
723         pBandList = (int*)CPLMalloc(sizeof(int) * nBCount);
724         for (int i = 0; i < nBCount; ++i) {
725             pBandList[i] = i + 1;
726         }
727     }
728 
729     GDALAsyncReaderH hAsyncReader =
730             GDALBeginAsyncReader(self, xOff, yOff, xSize, ySize, (void*) buf_string, nxsize, nysize, ntype, nBCount, pBandList, nPixelSpace, nLineSpace,
731     nBandSpace, options);
732 
733     if ( myBandList ) {
734        CPLFree( pBandList );
735     }
736 
737     if (hAsyncReader)
738     {
739         return (GDALAsyncReaderShadow*) CreateAsyncReaderWrapper(hAsyncReader, pyObject);
740     }
741     else
742     {
743         return NULL;
744     }
745 
746   }
747 
748 %clear(int band_list, int *pband_list);
749 %clear (int buf_len, char *buf_string, void* pyObject);
750 %clear(int*);
751 
EndAsyncReader(GDALAsyncReaderShadow * ario)752   void EndAsyncReader(GDALAsyncReaderShadow* ario){
753     if( ario == NULL ) return;
754     GDALAsyncReaderH hReader = AsyncReaderWrapperGetReader(ario);
755     if (hReader == NULL)
756     {
757         return;
758     }
759     GDALEndAsyncReader(self, hReader);
760     DisableAsyncReaderWrapper(ario);
761   }
762 
763 %feature( "kwargs" ) GetVirtualMem;
764 %newobject GetVirtualMem;
765 %apply (int nList, int *pList ) { (int band_list, int *pband_list ) };
766   CPLVirtualMemShadow* GetVirtualMem( GDALRWFlag eRWFlag,
767                                       int nXOff, int nYOff,
768                                       int nXSize, int nYSize,
769                                       int nBufXSize, int nBufYSize,
770                                       GDALDataType eBufType,
771                                       int band_list, int *pband_list,
772                                       int bIsBandSequential,
773                                       size_t nCacheSize,
774                                       size_t nPageSizeHint,
775                                       char** options = NULL )
776     {
777         int nPixelSpace;
778         int nBandSpace;
779         if( bIsBandSequential != 0 && bIsBandSequential != 1 )
780             return NULL;
781         if( band_list == 0 )
782             return NULL;
783         if( bIsBandSequential || band_list == 1 )
784         {
785             nPixelSpace = 0;
786             nBandSpace = 0;
787         }
788         else
789         {
790             nBandSpace = GDALGetDataTypeSize(eBufType) / 8;
791             nPixelSpace = nBandSpace * band_list;
792         }
793         CPLVirtualMem* vmem = GDALDatasetGetVirtualMem( self,
794                                          eRWFlag,
795                                          nXOff, nYOff,
796                                          nXSize, nYSize,
797                                          nBufXSize, nBufYSize,
798                                          eBufType,
799                                          band_list, pband_list,
800                                          nPixelSpace,
801                                          0,
802                                          nBandSpace,
803                                          nCacheSize,
804                                          nPageSizeHint,
805                                          FALSE,
806                                          options );
807         if( vmem == NULL )
808             return NULL;
809         CPLVirtualMemShadow* vmemshadow = (CPLVirtualMemShadow*)calloc(1, sizeof(CPLVirtualMemShadow));
810         vmemshadow->vmem = vmem;
811         vmemshadow->eBufType = eBufType;
812         vmemshadow->bIsBandSequential = bIsBandSequential;
813         vmemshadow->bReadOnly = (eRWFlag == GF_Read);
814         vmemshadow->nBufXSize = nBufXSize;
815         vmemshadow->nBufYSize = nBufYSize;
816         vmemshadow->nBandCount = band_list;
817         return vmemshadow;
818     }
819 %clear(int band_list, int *pband_list);
820 
821 %feature( "kwargs" ) GetTiledVirtualMem;
822 %newobject GetTiledVirtualMem;
823 %apply (int nList, int *pList ) { (int band_list, int *pband_list ) };
824   CPLVirtualMemShadow* GetTiledVirtualMem( GDALRWFlag eRWFlag,
825                                       int nXOff, int nYOff,
826                                       int nXSize, int nYSize,
827                                       int nTileXSize, int nTileYSize,
828                                       GDALDataType eBufType,
829                                       int band_list, int *pband_list,
830                                       GDALTileOrganization eTileOrganization,
831                                       size_t nCacheSize,
832                                       char** options = NULL )
833     {
834         if( band_list == 0 )
835             return NULL;
836         CPLVirtualMem* vmem = GDALDatasetGetTiledVirtualMem( self,
837                                          eRWFlag,
838                                          nXOff, nYOff,
839                                          nXSize, nYSize,
840                                          nTileXSize, nTileYSize,
841                                          eBufType,
842                                          band_list, pband_list,
843                                          eTileOrganization,
844                                          nCacheSize,
845                                          FALSE,
846                                          options );
847         if( vmem == NULL )
848             return NULL;
849         CPLVirtualMemShadow* vmemshadow = (CPLVirtualMemShadow*)calloc(1, sizeof(CPLVirtualMemShadow));
850         vmemshadow->vmem = vmem;
851         vmemshadow->eBufType = eBufType;
852         vmemshadow->bIsBandSequential = -1;
853         vmemshadow->bReadOnly = (eRWFlag == GF_Read);
854         vmemshadow->nBufXSize = nXSize;
855         vmemshadow->nBufYSize = nYSize;
856         vmemshadow->eTileOrganization = eTileOrganization;
857         vmemshadow->nTileXSize = nTileXSize;
858         vmemshadow->nTileYSize = nTileYSize;
859         vmemshadow->nBandCount = band_list;
860         return vmemshadow;
861     }
862 %clear(int band_list, int *pband_list);
863 
864 #endif /* PYTHON */
865 
866 #if defined(SWIGPYTHON) || defined(SWIGJAVA) || defined(SWIGPERL)
867 
868   /* Note that datasources own their layers */
869 #ifndef SWIGJAVA
870   %feature( "kwargs" ) CreateLayer;
871 #endif
872   OGRLayerShadow *CreateLayer(const char* name,
873               OSRSpatialReferenceShadow* srs=NULL,
874               OGRwkbGeometryType geom_type=wkbUnknown,
875               char** options=0) {
876     OGRLayerShadow* layer = (OGRLayerShadow*) GDALDatasetCreateLayer( self,
877                                   name,
878                                   srs,
879                                   geom_type,
880                                   options);
881     return layer;
882   }
883 
884 #ifndef SWIGJAVA
885   %feature( "kwargs" ) CopyLayer;
886 #endif
887 %apply Pointer NONNULL {OGRLayerShadow *src_layer};
888   OGRLayerShadow *CopyLayer(OGRLayerShadow *src_layer,
889             const char* new_name,
890             char** options=0) {
891     OGRLayerShadow* layer = (OGRLayerShadow*) GDALDatasetCopyLayer( self,
892                                                       src_layer,
893                                                       new_name,
894                                                       options);
895     return layer;
896   }
897 
DeleteLayer(int index)898   OGRErr DeleteLayer(int index){
899     return GDALDatasetDeleteLayer(self, index);
900   }
901 
GetLayerCount()902   int GetLayerCount() {
903     return GDALDatasetGetLayerCount(self);
904   }
905 
906 #ifdef SWIGJAVA
GetLayerByIndex(int index)907   OGRLayerShadow *GetLayerByIndex( int index ) {
908 #else
909   OGRLayerShadow *GetLayerByIndex( int index=0) {
910 #endif
911     OGRLayerShadow* layer = (OGRLayerShadow*) GDALDatasetGetLayer(self, index);
912     return layer;
913   }
914 
915   OGRLayerShadow *GetLayerByName( const char* layer_name) {
916     OGRLayerShadow* layer = (OGRLayerShadow*) GDALDatasetGetLayerByName(self, layer_name);
917     return layer;
918   }
919 
920   void ResetReading()
921   {
922     GDALDatasetResetReading( self );
923   }
924 
925 #ifdef SWIGPYTHON
926 %newobject GetNextFeature;
927 %feature( "kwargs" ) GetNextFeature;
928   OGRFeatureShadow* GetNextFeature( bool include_layer = true,
929                                     bool include_pct = false,
930                                     OGRLayerShadow** ppoBelongingLayer = NULL,
931                                     double* pdfProgressPct = NULL,
932                                     GDALProgressFunc callback = NULL,
933                                     void* callback_data=NULL )
934   {
935     return GDALDatasetGetNextFeature( self, ppoBelongingLayer, pdfProgressPct,
936                                       callback, callback_data );
937   }
938 #else
939     // FIXME: return layer
940 %newobject GetNextFeature;
941   OGRFeatureShadow* GetNextFeature()
942   {
943     return GDALDatasetGetNextFeature( self, NULL, NULL, NULL, NULL );
944   }
945 #endif
946 
947   bool TestCapability(const char * cap) {
948     return (GDALDatasetTestCapability(self, cap) > 0);
949   }
950 
951 #ifndef SWIGJAVA
952   %feature( "kwargs" ) ExecuteSQL;
953 #endif
954   %apply Pointer NONNULL {const char * statement};
955   OGRLayerShadow *ExecuteSQL(const char* statement,
956                         OGRGeometryShadow* spatialFilter=NULL,
957                         const char* dialect="") {
958     OGRLayerShadow* layer = (OGRLayerShadow*) GDALDatasetExecuteSQL(self,
959                                                       statement,
960                                                       spatialFilter,
961                                                       dialect);
962     return layer;
963   }
964 
965 %apply SWIGTYPE *DISOWN {OGRLayerShadow *layer};
966   void ReleaseResultSet(OGRLayerShadow *layer){
967     GDALDatasetReleaseResultSet(self, layer);
968   }
969 %clear OGRLayerShadow *layer;
970 
971   OGRStyleTableShadow *GetStyleTable() {
972     return (OGRStyleTableShadow*) GDALDatasetGetStyleTable(self);
973   }
974 
975   void SetStyleTable(OGRStyleTableShadow* table) {
976     if( table != NULL )
977         GDALDatasetSetStyleTable(self, (OGRStyleTableH) table);
978   }
979 
980 #endif /* defined(SWIGPYTHON) || defined(SWIGJAVA) || defined(SWIGPERL) */
981 
982 
983 OGRErr AbortSQL() {
984     return GDALDatasetAbortSQL(self);
985 }
986 
987 #ifndef SWIGJAVA
988   %feature( "kwargs" ) StartTransaction;
989 #endif
990   OGRErr StartTransaction(int force = FALSE)
991   {
992     return GDALDatasetStartTransaction(self, force);
993   }
994 
995   OGRErr CommitTransaction()
996   {
997     return GDALDatasetCommitTransaction(self);
998   }
999 
1000   OGRErr RollbackTransaction()
1001   {
1002     return GDALDatasetRollbackTransaction(self);
1003   }
1004 
1005   void ClearStatistics()
1006   {
1007       GDALDatasetClearStatistics(self);
1008   }
1009 
1010   %apply Pointer NONNULL {const char* name};
1011   OGRFieldDomainShadow* GetFieldDomain(const char* name)
1012   {
1013     return (OGRFieldDomainShadow*) GDALDatasetGetFieldDomain(self, name);
1014   }
1015   %clear const char* name;
1016 
1017   %apply Pointer NONNULL {OGRFieldDomainShadow* fieldDomain};
1018   bool AddFieldDomain(OGRFieldDomainShadow* fieldDomain)
1019   {
1020       return GDALDatasetAddFieldDomain(self, (OGRFieldDomainH)fieldDomain, NULL);
1021   }
1022   %clear OGRFieldDomainShadow* fieldDomain;
1023 
1024 } /* extend */
1025 }; /* GDALDatasetShadow */
1026 
1027 %{
GDALDatasetShadow_RasterXSize_get(GDALDatasetShadow * h)1028 int GDALDatasetShadow_RasterXSize_get( GDALDatasetShadow *h ) {
1029   return GDALGetRasterXSize( h );
1030 }
GDALDatasetShadow_RasterYSize_get(GDALDatasetShadow * h)1031 int GDALDatasetShadow_RasterYSize_get( GDALDatasetShadow *h ) {
1032   return GDALGetRasterYSize( h );
1033 }
GDALDatasetShadow_RasterCount_get(GDALDatasetShadow * h)1034 int GDALDatasetShadow_RasterCount_get( GDALDatasetShadow *h ) {
1035   return GDALGetRasterCount( h );
1036 }
1037 %}
1038 
1039