1 : /******************************************************************************
2 : * $Id: gdaldataset.cpp 19162 2010-03-22 16:45:08Z warmerdam $
3 : *
4 : * Project: GDAL Core
5 : * Purpose: Base class for raster file formats.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1998, 2003, Frank Warmerdam
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "gdal_priv.h"
31 : #include "cpl_string.h"
32 : #include "cpl_hash_set.h"
33 : #include "cpl_multiproc.h"
34 :
35 : CPL_CVSID("$Id: gdaldataset.cpp 19162 2010-03-22 16:45:08Z warmerdam $");
36 :
37 : CPL_C_START
38 : GDALAsyncReader *
39 : GDALGetDefaultAsyncReader( GDALDataset *poDS,
40 : int nXOff, int nYOff,
41 : int nXSize, int nYSize,
42 : void *pBuf,
43 : int nBufXSize, int nBufYSize,
44 : GDALDataType eBufType,
45 : int nBandCount, int* panBandMap,
46 : int nPixelSpace, int nLineSpace,
47 : int nBandSpace, char **papszOptions);
48 : CPL_C_END
49 :
50 : typedef struct
51 : {
52 : /* PID of the thread that mark the dataset as shared */
53 : /* This may not be the actual PID, but the responsiblePID */
54 : GIntBig nPID;
55 : char *pszDescription;
56 : GDALAccess eAccess;
57 :
58 : GDALDataset *poDS;
59 : } SharedDatasetCtxt;
60 :
61 : typedef struct
62 : {
63 : GDALDataset *poDS;
64 : /* In the case of a shared dataset, memorize the PID of the thread */
65 : /* that marked the dataset as shared, so that we can remove it from */
66 : /* the phSharedDatasetSet in the destructor of the dataset, even */
67 : /* if GDALClose is called from a different thread */
68 : /* Ideally, this should be stored in the GDALDataset object itself */
69 : /* but this is inconvenient to change the object size at that time */
70 : GIntBig nPIDCreatorForShared;
71 : } DatasetCtxt;
72 :
73 : /* Set of datasets opened as shared datasets (with GDALOpenShared) */
74 : /* The values in the set are of type SharedDatasetCtxt */
75 : static CPLHashSet* phSharedDatasetSet = NULL;
76 :
77 : /* Set of all datasets created in the constructor of GDALDataset */
78 : /* The values in the set are of type DatasetCtxt */
79 : static CPLHashSet* phAllDatasetSet = NULL;
80 : static void *hDLMutex = NULL;
81 :
82 : /* Static array of all datasets. Used by GDALGetOpenDatasets */
83 : /* Not thread-safe. See GDALGetOpenDatasets */
84 : static GDALDataset** ppDatasets = NULL;
85 :
86 5945 : static unsigned long GDALSharedDatasetHashFunc(const void* elt)
87 : {
88 5945 : SharedDatasetCtxt* psStruct = (SharedDatasetCtxt*) elt;
89 5945 : return (unsigned long) (CPLHashSetHashStr(psStruct->pszDescription) ^ psStruct->eAccess ^ psStruct->nPID);
90 : }
91 :
92 5391 : static int GDALSharedDatasetEqualFunc(const void* elt1, const void* elt2)
93 : {
94 5391 : SharedDatasetCtxt* psStruct1 = (SharedDatasetCtxt*) elt1;
95 5391 : SharedDatasetCtxt* psStruct2 = (SharedDatasetCtxt*) elt2;
96 : return strcmp(psStruct1->pszDescription, psStruct2->pszDescription) == 0 &&
97 : psStruct1->nPID == psStruct2->nPID &&
98 5391 : psStruct1->eAccess == psStruct2->eAccess;
99 : }
100 :
101 170 : static void GDALSharedDatasetFreeFunc(void* elt)
102 : {
103 170 : SharedDatasetCtxt* psStruct = (SharedDatasetCtxt*) elt;
104 170 : CPLFree(psStruct->pszDescription);
105 170 : CPLFree(psStruct);
106 170 : }
107 :
108 73491 : static unsigned long GDALDatasetHashFunc(const void* elt)
109 : {
110 73491 : DatasetCtxt* psStruct = (DatasetCtxt*) elt;
111 73491 : return (unsigned long)(GUIntBig) psStruct->poDS;
112 : }
113 :
114 30721 : static int GDALDatasetEqualFunc(const void* elt1, const void* elt2)
115 : {
116 30721 : DatasetCtxt* psStruct1 = (DatasetCtxt*) elt1;
117 30721 : DatasetCtxt* psStruct2 = (DatasetCtxt*) elt2;
118 30721 : return psStruct1->poDS == psStruct2->poDS ;
119 : }
120 :
121 13509 : static void GDALDatasetFreeFunc(void* elt)
122 : {
123 13509 : DatasetCtxt* psStruct = (DatasetCtxt*) elt;
124 13509 : CPLFree(psStruct);
125 13509 : }
126 :
127 : /************************************************************************/
128 : /* Functions shared between gdalproxypool.cpp and gdaldataset.cpp */
129 : /************************************************************************/
130 :
131 : void** GDALGetphDLMutex();
132 : void GDALSetResponsiblePIDForCurrentThread(GIntBig responsiblePID);
133 : GIntBig GDALGetResponsiblePIDForCurrentThread();
134 :
135 : /* The open-shared mutex must be used by the ProxyPool too */
136 9428 : void** GDALGetphDLMutex()
137 : {
138 9428 : return &hDLMutex;
139 : }
140 :
141 : /* The current thread will act in the behalf of the thread of PID responsiblePID */
142 9251 : void GDALSetResponsiblePIDForCurrentThread(GIntBig responsiblePID)
143 : {
144 9251 : GIntBig* pResponsiblePID = (GIntBig*) CPLGetTLS(CTLS_RESPONSIBLEPID);
145 9251 : if (pResponsiblePID == NULL)
146 : {
147 18 : pResponsiblePID = (GIntBig*) CPLMalloc(sizeof(GIntBig));
148 18 : CPLSetTLS(CTLS_RESPONSIBLEPID, pResponsiblePID, TRUE);
149 : }
150 9251 : *pResponsiblePID = responsiblePID;
151 9251 : }
152 :
153 : /* Get the PID of the thread that the current thread will act in the behalf of */
154 : /* By default : the current thread acts in the behalf of itself */
155 34074 : GIntBig GDALGetResponsiblePIDForCurrentThread()
156 : {
157 34074 : GIntBig* pResponsiblePID = (GIntBig*) CPLGetTLS(CTLS_RESPONSIBLEPID);
158 34074 : if (pResponsiblePID == NULL)
159 4407 : return CPLGetPID();
160 29667 : return *pResponsiblePID;
161 : }
162 :
163 :
164 : /************************************************************************/
165 : /* ==================================================================== */
166 : /* GDALDataset */
167 : /* ==================================================================== */
168 : /************************************************************************/
169 :
170 : /**
171 : * \class GDALDataset "gdal_priv.h"
172 : *
173 : * A dataset encapsulating one or more raster bands. Details are
174 : * further discussed in the <a href="gdal_datamodel.html#GDALDataset">GDAL
175 : * Data Model</a>.
176 : *
177 : * Use GDALOpen() or GDALOpenShared() to create a GDALDataset for a named file,
178 : * or GDALDriver::Create() or GDALDriver::CreateCopy() to create a new
179 : * dataset.
180 : */
181 :
182 : /************************************************************************/
183 : /* GDALDataset() */
184 : /************************************************************************/
185 :
186 13509 : GDALDataset::GDALDataset()
187 :
188 : {
189 13509 : poDriver = NULL;
190 13509 : eAccess = GA_ReadOnly;
191 13509 : nRasterXSize = 512;
192 13509 : nRasterYSize = 512;
193 13509 : nBands = 0;
194 13509 : papoBands = NULL;
195 13509 : nRefCount = 1;
196 13509 : bShared = FALSE;
197 :
198 : /* -------------------------------------------------------------------- */
199 : /* Add this dataset to the open dataset list. */
200 : /* -------------------------------------------------------------------- */
201 : {
202 13509 : CPLMutexHolderD( &hDLMutex );
203 :
204 13509 : if (phAllDatasetSet == NULL)
205 5409 : phAllDatasetSet = CPLHashSetNew(GDALDatasetHashFunc, GDALDatasetEqualFunc, GDALDatasetFreeFunc);
206 13509 : DatasetCtxt* ctxt = (DatasetCtxt*)CPLMalloc(sizeof(DatasetCtxt));
207 13509 : ctxt->poDS = this;
208 13509 : ctxt->nPIDCreatorForShared = -1;
209 13509 : CPLHashSetInsert(phAllDatasetSet, ctxt);
210 : }
211 :
212 : /* -------------------------------------------------------------------- */
213 : /* Set forced caching flag. */
214 : /* -------------------------------------------------------------------- */
215 : bForceCachedIO = CSLTestBoolean(
216 13509 : CPLGetConfigOption( "GDAL_FORCE_CACHING", "NO") );
217 13509 : }
218 :
219 :
220 : /************************************************************************/
221 : /* ~GDALDataset() */
222 : /************************************************************************/
223 :
224 : /**
225 : * \brief Destroy an open GDALDataset.
226 : *
227 : * This is the accepted method of closing a GDAL dataset and deallocating
228 : * all resources associated with it.
229 : *
230 : * Equivelent of the C callable GDALClose(). Except that GDALClose() first
231 : * decrements the reference count, and then closes only if it has dropped to
232 : * zero.
233 : *
234 : * For Windows users, it is not recommanded using the delete operator on the
235 : * dataset object because of known issues when allocating and freeing memory across
236 : * module boundaries. Calling GDALClose() is then a better option.
237 : */
238 :
239 13509 : GDALDataset::~GDALDataset()
240 :
241 : {
242 : int i;
243 :
244 : // we don't want to report destruction of datasets that
245 : // were never really open.
246 13509 : if( nBands != 0 || !EQUAL(GetDescription(),"") )
247 : {
248 13160 : if( CPLGetPID() != GDALGetResponsiblePIDForCurrentThread() )
249 : CPLDebug( "GDAL",
250 : "GDALClose(%s, this=%p) (pid=%d, responsiblePID=%d)", GetDescription(), this,
251 : (int)CPLGetPID(),
252 0 : (int)GDALGetResponsiblePIDForCurrentThread() );
253 : else
254 : CPLDebug( "GDAL",
255 13160 : "GDALClose(%s, this=%p)", GetDescription(), this );
256 : }
257 :
258 : /* -------------------------------------------------------------------- */
259 : /* Remove dataset from the "open" dataset list. */
260 : /* -------------------------------------------------------------------- */
261 : {
262 13509 : CPLMutexHolderD( &hDLMutex );
263 :
264 : DatasetCtxt sStruct;
265 13509 : sStruct.poDS = this;
266 13509 : DatasetCtxt* psStruct = (DatasetCtxt*) CPLHashSetLookup(phAllDatasetSet, &sStruct);
267 13509 : GIntBig nPIDCreatorForShared = psStruct->nPIDCreatorForShared;
268 13509 : CPLHashSetRemove(phAllDatasetSet, psStruct);
269 :
270 13509 : if (bShared && phSharedDatasetSet != NULL)
271 : {
272 : SharedDatasetCtxt* psStruct;
273 : SharedDatasetCtxt sStruct;
274 187 : sStruct.nPID = nPIDCreatorForShared;
275 187 : sStruct.eAccess = eAccess;
276 187 : sStruct.pszDescription = (char*) GetDescription();
277 187 : psStruct = (SharedDatasetCtxt*) CPLHashSetLookup(phSharedDatasetSet, &sStruct);
278 357 : if (psStruct && psStruct->poDS == this)
279 : {
280 170 : CPLHashSetRemove(phSharedDatasetSet, psStruct);
281 : }
282 : else
283 : {
284 17 : CPLDebug("GDAL", "Should not happen. Cannot find %s, this=%p in phSharedDatasetSet", GetDescription(), this);
285 : }
286 : }
287 :
288 13509 : if (CPLHashSetSize(phAllDatasetSet) == 0)
289 : {
290 5409 : CPLHashSetDestroy(phAllDatasetSet);
291 5409 : phAllDatasetSet = NULL;
292 5409 : if (phSharedDatasetSet)
293 : {
294 149 : CPLHashSetDestroy(phSharedDatasetSet);
295 : }
296 5409 : phSharedDatasetSet = NULL;
297 5409 : CPLFree(ppDatasets);
298 5409 : ppDatasets = NULL;
299 13509 : }
300 : }
301 :
302 : /* -------------------------------------------------------------------- */
303 : /* Destroy the raster bands if they exist. */
304 : /* -------------------------------------------------------------------- */
305 632636 : for( i = 0; i < nBands && papoBands != NULL; i++ )
306 : {
307 619127 : if( papoBands[i] != NULL )
308 619125 : delete papoBands[i];
309 : }
310 :
311 13509 : CPLFree( papoBands );
312 13509 : }
313 :
314 : /************************************************************************/
315 : /* FlushCache() */
316 : /************************************************************************/
317 :
318 : /**
319 : * \brief Flush all write cached data to disk.
320 : *
321 : * Any raster (or other GDAL) data written via GDAL calls, but buffered
322 : * internally will be written to disk.
323 : *
324 : * Using this method does not prevent use from calling GDALClose()
325 : * to properly close a dataset and ensure that important data not addressed
326 : * by FlushCache() is written in the file.
327 : *
328 : * This method is the same as the C function GDALFlushCache().
329 : */
330 :
331 18293 : void GDALDataset::FlushCache()
332 :
333 : {
334 : int i;
335 :
336 : // This sometimes happens if a dataset is destroyed before completely
337 : // built.
338 :
339 18293 : if( papoBands == NULL )
340 344 : return;
341 :
342 1037076 : for( i = 0; i < nBands; i++ )
343 : {
344 1019127 : if( papoBands[i] != NULL )
345 1019127 : papoBands[i]->FlushCache();
346 : }
347 : }
348 :
349 : /************************************************************************/
350 : /* GDALFlushCache() */
351 : /************************************************************************/
352 :
353 : /**
354 : * \brief Flush all write cached data to disk.
355 : *
356 : * @see GDALDataset::FlushCache().
357 : */
358 :
359 14 : void CPL_STDCALL GDALFlushCache( GDALDatasetH hDS )
360 :
361 : {
362 14 : VALIDATE_POINTER0( hDS, "GDALFlushCache" );
363 :
364 14 : ((GDALDataset *) hDS)->FlushCache();
365 : }
366 :
367 : /************************************************************************/
368 : /* BlockBasedFlushCache() */
369 : /* */
370 : /* This helper method can be called by the */
371 : /* GDALDataset::FlushCache() for particular drivers to ensure */
372 : /* that buffers will be flushed in a manner suitable for pixel */
373 : /* interleaved (by block) IO. That is, if all the bands have */
374 : /* the same size blocks then a given block will be flushed for */
375 : /* all bands before proceeding to the next block. */
376 : /************************************************************************/
377 :
378 0 : void GDALDataset::BlockBasedFlushCache()
379 :
380 : {
381 : GDALRasterBand *poBand1;
382 : int nBlockXSize, nBlockYSize, iBand;
383 :
384 0 : poBand1 = GetRasterBand( 1 );
385 0 : if( poBand1 == NULL )
386 : {
387 0 : GDALDataset::FlushCache();
388 0 : return;
389 : }
390 :
391 0 : poBand1->GetBlockSize( &nBlockXSize, &nBlockYSize );
392 :
393 : /* -------------------------------------------------------------------- */
394 : /* Verify that all bands match. */
395 : /* -------------------------------------------------------------------- */
396 0 : for( iBand = 1; iBand < nBands; iBand++ )
397 : {
398 : int nThisBlockXSize, nThisBlockYSize;
399 0 : GDALRasterBand *poBand = GetRasterBand( iBand+1 );
400 :
401 0 : poBand->GetBlockSize( &nThisBlockXSize, &nThisBlockYSize );
402 0 : if( nThisBlockXSize != nBlockXSize && nThisBlockYSize != nBlockYSize )
403 : {
404 0 : GDALDataset::FlushCache();
405 0 : return;
406 : }
407 : }
408 :
409 : /* -------------------------------------------------------------------- */
410 : /* Now flush writable data. */
411 : /* -------------------------------------------------------------------- */
412 0 : for( int iY = 0; iY < poBand1->nBlocksPerColumn; iY++ )
413 : {
414 0 : for( int iX = 0; iX < poBand1->nBlocksPerRow; iX++ )
415 : {
416 0 : for( iBand = 0; iBand < nBands; iBand++ )
417 : {
418 0 : GDALRasterBand *poBand = GetRasterBand( iBand+1 );
419 :
420 0 : if( poBand->papoBlocks[iX + iY*poBand1->nBlocksPerRow] != NULL)
421 : {
422 : CPLErr eErr;
423 :
424 0 : eErr = poBand->FlushBlock( iX, iY );
425 :
426 0 : if( eErr != CE_None )
427 0 : return;
428 : }
429 : }
430 : }
431 : }
432 : }
433 :
434 : /************************************************************************/
435 : /* RasterInitialize() */
436 : /* */
437 : /* Initialize raster size */
438 : /************************************************************************/
439 :
440 0 : void GDALDataset::RasterInitialize( int nXSize, int nYSize )
441 :
442 : {
443 0 : CPLAssert( nXSize > 0 && nYSize > 0 );
444 :
445 0 : nRasterXSize = nXSize;
446 0 : nRasterYSize = nYSize;
447 0 : }
448 :
449 : /************************************************************************/
450 : /* AddBand() */
451 : /************************************************************************/
452 :
453 : /**
454 : * \brief Add a band to a dataset.
455 : *
456 : * This method will add a new band to the dataset if the underlying format
457 : * supports this action. Most formats do not.
458 : *
459 : * Note that the new GDALRasterBand is not returned. It may be fetched
460 : * after successful completion of the method by calling
461 : * GDALDataset::GetRasterBand(GDALDataset::GetRasterCount()-1) as the newest
462 : * band will always be the last band.
463 : *
464 : * @param eType the data type of the pixels in the new band.
465 : *
466 : * @param papszOptions a list of NAME=VALUE option strings. The supported
467 : * options are format specific. NULL may be passed by default.
468 : *
469 : * @return CE_None on success or CE_Failure on failure.
470 : */
471 :
472 0 : CPLErr GDALDataset::AddBand( GDALDataType eType, char ** papszOptions )
473 :
474 : {
475 : (void) eType;
476 : (void) papszOptions;
477 :
478 : CPLError( CE_Failure, CPLE_NotSupported,
479 0 : "Dataset does not support the AddBand() method." );
480 :
481 0 : return CE_Failure;
482 : }
483 :
484 : /************************************************************************/
485 : /* GDALAddBand() */
486 : /************************************************************************/
487 :
488 : /**
489 : * \brief Add a band to a dataset.
490 : *
491 : * @see GDALDataset::AddBand().
492 : */
493 :
494 : CPLErr CPL_STDCALL GDALAddBand( GDALDatasetH hDataset,
495 59 : GDALDataType eType, char **papszOptions )
496 :
497 : {
498 59 : VALIDATE_POINTER1( hDataset, "GDALAddBand", CE_Failure );
499 :
500 59 : return ((GDALDataset *) hDataset)->AddBand( eType, papszOptions );
501 : }
502 :
503 : /************************************************************************/
504 : /* SetBand() */
505 : /* */
506 : /* Set a band in the band array, updating the band count, and */
507 : /* array size appropriately. */
508 : /************************************************************************/
509 :
510 619622 : void GDALDataset::SetBand( int nNewBand, GDALRasterBand * poBand )
511 :
512 : {
513 : /* -------------------------------------------------------------------- */
514 : /* Do we need to grow the bands list? */
515 : /* -------------------------------------------------------------------- */
516 619622 : if( nBands < nNewBand || papoBands == NULL ) {
517 : int i;
518 : GDALRasterBand** papoNewBands;
519 :
520 355325 : if( papoBands == NULL )
521 : papoNewBands = (GDALRasterBand **)
522 13136 : VSICalloc(sizeof(GDALRasterBand*), MAX(nNewBand,nBands));
523 : else
524 : papoNewBands = (GDALRasterBand **)
525 : VSIRealloc(papoBands, sizeof(GDALRasterBand*) *
526 342189 : MAX(nNewBand,nBands));
527 355325 : if (papoNewBands == NULL)
528 : {
529 : CPLError(CE_Failure, CPLE_OutOfMemory,
530 0 : "Cannot allocate band array");
531 0 : return;
532 : }
533 355325 : papoBands = papoNewBands;
534 :
535 705357 : for( i = nBands; i < nNewBand; i++ )
536 350032 : papoBands[i] = NULL;
537 :
538 355325 : nBands = MAX(nBands,nNewBand);
539 : }
540 :
541 : /* -------------------------------------------------------------------- */
542 : /* Set the band. Resetting the band is currently not permitted. */
543 : /* -------------------------------------------------------------------- */
544 619622 : if( papoBands[nNewBand-1] != NULL )
545 : {
546 : CPLError(CE_Failure, CPLE_NotSupported,
547 0 : "Cannot set band %d as it is already set", nNewBand);
548 0 : return;
549 : }
550 :
551 619622 : papoBands[nNewBand-1] = poBand;
552 :
553 : /* -------------------------------------------------------------------- */
554 : /* Set back reference information on the raster band. Note */
555 : /* that the GDALDataset is a friend of the GDALRasterBand */
556 : /* specifically to allow this. */
557 : /* -------------------------------------------------------------------- */
558 619622 : poBand->nBand = nNewBand;
559 619622 : poBand->poDS = this;
560 619622 : poBand->nRasterXSize = nRasterXSize;
561 619622 : poBand->nRasterYSize = nRasterYSize;
562 619622 : poBand->eAccess = eAccess; /* default access to be same as dataset */
563 : }
564 :
565 : /************************************************************************/
566 : /* GetRasterXSize() */
567 : /************************************************************************/
568 :
569 : /**
570 :
571 : \brief Fetch raster width in pixels.
572 :
573 : Equivelent of the C function GDALGetRasterXSize().
574 :
575 : @return the width in pixels of raster bands in this GDALDataset.
576 :
577 : */
578 :
579 378436 : int GDALDataset::GetRasterXSize()
580 :
581 : {
582 378436 : return nRasterXSize;
583 : }
584 :
585 : /************************************************************************/
586 : /* GDALGetRasterXSize() */
587 : /************************************************************************/
588 :
589 : /**
590 : * \brief Fetch raster width in pixels.
591 : *
592 : * @see GDALDataset::GetRasterXSize().
593 : */
594 :
595 4873 : int CPL_STDCALL GDALGetRasterXSize( GDALDatasetH hDataset )
596 :
597 : {
598 4873 : VALIDATE_POINTER1( hDataset, "GDALGetRasterXSize", 0 );
599 :
600 4873 : return ((GDALDataset *) hDataset)->GetRasterXSize();
601 : }
602 :
603 :
604 : /************************************************************************/
605 : /* GetRasterYSize() */
606 : /************************************************************************/
607 :
608 : /**
609 :
610 : \brief Fetch raster height in pixels.
611 :
612 : Equivelent of the C function GDALGetRasterYSize().
613 :
614 : @return the height in pixels of raster bands in this GDALDataset.
615 :
616 : */
617 :
618 110027 : int GDALDataset::GetRasterYSize()
619 :
620 : {
621 110027 : return nRasterYSize;
622 : }
623 :
624 : /************************************************************************/
625 : /* GDALGetRasterYSize() */
626 : /************************************************************************/
627 :
628 : /**
629 : * \brief Fetch raster height in pixels.
630 : *
631 : * @see GDALDataset::GetRasterYSize().
632 : */
633 :
634 13179 : int CPL_STDCALL GDALGetRasterYSize( GDALDatasetH hDataset )
635 :
636 : {
637 13179 : VALIDATE_POINTER1( hDataset, "GDALGetRasterYSize", 0 );
638 :
639 13179 : return ((GDALDataset *) hDataset)->GetRasterYSize();
640 : }
641 :
642 : /************************************************************************/
643 : /* GetRasterBand() */
644 : /************************************************************************/
645 :
646 : /**
647 :
648 : \brief Fetch a band object for a dataset.
649 :
650 : Equivalent of the C function GDALGetRasterBand().
651 :
652 : @param nBandId the index number of the band to fetch, from 1 to
653 : GetRasterCount().
654 :
655 : @return the nBandId th band object
656 :
657 : */
658 :
659 2207570 : GDALRasterBand * GDALDataset::GetRasterBand( int nBandId )
660 :
661 : {
662 2207570 : if ( papoBands )
663 : {
664 2207570 : if( nBandId < 1 || nBandId > nBands )
665 : {
666 : CPLError( CE_Failure, CPLE_IllegalArg,
667 : "GDALDataset::GetRasterBand(%d) - Illegal band #\n",
668 0 : nBandId );
669 0 : return NULL;
670 : }
671 : else
672 2207570 : return( papoBands[nBandId-1] );
673 : }
674 0 : return NULL;
675 : }
676 :
677 : /************************************************************************/
678 : /* GDALGetRasterBand() */
679 : /************************************************************************/
680 :
681 : /**
682 : * \brief Fetch a band object for a dataset.
683 : * @see GDALDataset::GetRasterBand().
684 : */
685 :
686 176851 : GDALRasterBandH CPL_STDCALL GDALGetRasterBand( GDALDatasetH hDS, int nBandId )
687 :
688 : {
689 176851 : VALIDATE_POINTER1( hDS, "GDALGetRasterBand", NULL );
690 :
691 176851 : return( (GDALRasterBandH) ((GDALDataset *) hDS)->GetRasterBand(nBandId) );
692 : }
693 :
694 : /************************************************************************/
695 : /* GetRasterCount() */
696 : /************************************************************************/
697 :
698 : /**
699 : * \brief Fetch the number of raster bands on this dataset.
700 : *
701 : * Same as the C function GDALGetRasterCount().
702 : *
703 : * @return the number of raster bands.
704 : */
705 :
706 1713493 : int GDALDataset::GetRasterCount()
707 :
708 : {
709 1713493 : return papoBands ? nBands : 0;
710 : }
711 :
712 : /************************************************************************/
713 : /* GDALGetRasterCount() */
714 : /************************************************************************/
715 :
716 : /**
717 : * \brief Fetch the number of raster bands on this dataset.
718 : *
719 : * @see GDALDataset::GetRasterCount().
720 : */
721 :
722 338033 : int CPL_STDCALL GDALGetRasterCount( GDALDatasetH hDS )
723 :
724 : {
725 338033 : VALIDATE_POINTER1( hDS, "GDALGetRasterCount", 0 );
726 :
727 338033 : return( ((GDALDataset *) hDS)->GetRasterCount() );
728 : }
729 :
730 : /************************************************************************/
731 : /* GetProjectionRef() */
732 : /************************************************************************/
733 :
734 : /**
735 : * \brief Fetch the projection definition string for this dataset.
736 : *
737 : * Same as the C function GDALGetProjectionRef().
738 : *
739 : * The returned string defines the projection coordinate system of the
740 : * image in OpenGIS WKT format. It should be suitable for use with the
741 : * OGRSpatialReference class.
742 : *
743 : * When a projection definition is not available an empty (but not NULL)
744 : * string is returned.
745 : *
746 : * @return a pointer to an internal projection reference string. It should
747 : * not be altered, freed or expected to last for long.
748 : *
749 : * @see http://www.gdal.org/ogr/osr_tutorial.html
750 : */
751 :
752 3882 : const char *GDALDataset::GetProjectionRef()
753 :
754 : {
755 3882 : return( "" );
756 : }
757 :
758 : /************************************************************************/
759 : /* GDALGetProjectionRef() */
760 : /************************************************************************/
761 :
762 : /**
763 : * \brief Fetch the projection definition string for this dataset.
764 : *
765 : * @see GDALDataset::GetProjectionRef()
766 : */
767 :
768 2025 : const char * CPL_STDCALL GDALGetProjectionRef( GDALDatasetH hDS )
769 :
770 : {
771 2025 : VALIDATE_POINTER1( hDS, "GDALGetProjectionRef", NULL );
772 :
773 2025 : return( ((GDALDataset *) hDS)->GetProjectionRef() );
774 : }
775 :
776 : /************************************************************************/
777 : /* SetProjection() */
778 : /************************************************************************/
779 :
780 : /**
781 : * \brief Set the projection reference string for this dataset.
782 : *
783 : * The string should be in OGC WKT or PROJ.4 format. An error may occur
784 : * because of incorrectly specified projection strings, because the dataset
785 : * is not writable, or because the dataset does not support the indicated
786 : * projection. Many formats do not support writing projections.
787 : *
788 : * This method is the same as the C GDALSetProjection() function.
789 : *
790 : * @param pszProjection projection reference string.
791 : *
792 : * @return CE_Failure if an error occurs, otherwise CE_None.
793 : */
794 :
795 0 : CPLErr GDALDataset::SetProjection( const char * )
796 :
797 : {
798 0 : if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
799 : CPLError( CE_Failure, CPLE_NotSupported,
800 0 : "Dataset does not support the SetProjection() method." );
801 0 : return CE_Failure;
802 : }
803 :
804 : /************************************************************************/
805 : /* GDALSetProjection() */
806 : /************************************************************************/
807 :
808 : /**
809 : * \brief Set the projection reference string for this dataset.
810 : *
811 : * @see GDALDataset::SetProjection()
812 : */
813 :
814 977 : CPLErr CPL_STDCALL GDALSetProjection( GDALDatasetH hDS, const char * pszProjection )
815 :
816 : {
817 977 : VALIDATE_POINTER1( hDS, "GDALSetProjection", CE_Failure );
818 :
819 977 : return( ((GDALDataset *) hDS)->SetProjection(pszProjection) );
820 : }
821 :
822 : /************************************************************************/
823 : /* GetGeoTransform() */
824 : /************************************************************************/
825 :
826 : /**
827 : * \brief Fetch the affine transformation coefficients.
828 : *
829 : * Fetches the coefficients for transforming between pixel/line (P,L) raster
830 : * space, and projection coordinates (Xp,Yp) space.
831 : *
832 : * \code
833 : * Xp = padfTransform[0] + P*padfTransform[1] + L*padfTransform[2];
834 : * Yp = padfTransform[3] + P*padfTransform[4] + L*padfTransform[5];
835 : * \endcode
836 : *
837 : * In a north up image, padfTransform[1] is the pixel width, and
838 : * padfTransform[5] is the pixel height. The upper left corner of the
839 : * upper left pixel is at position (padfTransform[0],padfTransform[3]).
840 : *
841 : * The default transform is (0,1,0,0,0,1) and should be returned even when
842 : * a CE_Failure error is returned, such as for formats that don't support
843 : * transformation to projection coordinates.
844 : *
845 : * NOTE: GetGeoTransform() isn't expressive enough to handle the variety of
846 : * OGC Grid Coverages pixel/line to projection transformation schemes.
847 : * Eventually this method will be depreciated in favour of a more general
848 : * scheme.
849 : *
850 : * This method does the same thing as the C GDALGetGeoTransform() function.
851 : *
852 : * @param padfTransform an existing six double buffer into which the
853 : * transformation will be placed.
854 : *
855 : * @return CE_None on success, or CE_Failure if no transform can be fetched.
856 : */
857 :
858 3595 : CPLErr GDALDataset::GetGeoTransform( double * padfTransform )
859 :
860 : {
861 3595 : CPLAssert( padfTransform != NULL );
862 :
863 3595 : padfTransform[0] = 0.0; /* X Origin (top left corner) */
864 3595 : padfTransform[1] = 1.0; /* X Pixel size */
865 3595 : padfTransform[2] = 0.0;
866 :
867 3595 : padfTransform[3] = 0.0; /* Y Origin (top left corner) */
868 3595 : padfTransform[4] = 0.0;
869 3595 : padfTransform[5] = 1.0; /* Y Pixel Size */
870 :
871 3595 : return( CE_Failure );
872 : }
873 :
874 : /************************************************************************/
875 : /* GDALGetGeoTransform() */
876 : /************************************************************************/
877 :
878 : /**
879 : * \brief Fetch the affine transformation coefficients.
880 : *
881 : * @see GDALDataset::GetGeoTransform()
882 : */
883 :
884 1580 : CPLErr CPL_STDCALL GDALGetGeoTransform( GDALDatasetH hDS, double * padfTransform )
885 :
886 : {
887 1580 : VALIDATE_POINTER1( hDS, "GDALGetGeoTransform", CE_Failure );
888 :
889 1580 : return( ((GDALDataset *) hDS)->GetGeoTransform(padfTransform) );
890 : }
891 :
892 : /************************************************************************/
893 : /* SetGeoTransform() */
894 : /************************************************************************/
895 :
896 : /**
897 : * \brief Set the affine transformation coefficients.
898 : *
899 : * See GetGeoTransform() for details on the meaning of the padfTransform
900 : * coefficients.
901 : *
902 : * This method does the same thing as the C GDALSetGeoTransform() function.
903 : *
904 : * @param padfTransform a six double buffer containing the transformation
905 : * coefficients to be written with the dataset.
906 : *
907 : * @return CE_None on success, or CE_Failure if this transform cannot be
908 : * written.
909 : */
910 :
911 0 : CPLErr GDALDataset::SetGeoTransform( double * )
912 :
913 : {
914 0 : if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
915 : CPLError( CE_Failure, CPLE_NotSupported,
916 0 : "SetGeoTransform() not supported for this dataset." );
917 :
918 0 : return( CE_Failure );
919 : }
920 :
921 : /************************************************************************/
922 : /* GDALSetGeoTransform() */
923 : /************************************************************************/
924 :
925 : /**
926 : * \brief Set the affine transformation coefficients.
927 : *
928 : * @see GDALDataset::SetGeoTransform()
929 : */
930 :
931 : CPLErr CPL_STDCALL
932 1023 : GDALSetGeoTransform( GDALDatasetH hDS, double * padfTransform )
933 :
934 : {
935 1023 : VALIDATE_POINTER1( hDS, "GDALSetGeoTransform", CE_Failure );
936 :
937 1023 : return( ((GDALDataset *) hDS)->SetGeoTransform(padfTransform) );
938 : }
939 :
940 : /************************************************************************/
941 : /* GetInternalHandle() */
942 : /************************************************************************/
943 :
944 : /**
945 : * \brief Fetch a format specific internally meaningful handle.
946 : *
947 : * This method is the same as the C GDALGetInternalHandle() method.
948 : *
949 : * @param pszHandleName the handle name desired. The meaningful names
950 : * will be specific to the file format.
951 : *
952 : * @return the desired handle value, or NULL if not recognised/supported.
953 : */
954 :
955 0 : void *GDALDataset::GetInternalHandle( const char * )
956 :
957 : {
958 0 : return( NULL );
959 : }
960 :
961 : /************************************************************************/
962 : /* GDALGetInternalHandle() */
963 : /************************************************************************/
964 :
965 : /**
966 : * \brief Fetch a format specific internally meaningful handle.
967 : *
968 : * @see GDALDataset::GetInternalHandle()
969 : */
970 :
971 : void * CPL_STDCALL
972 0 : GDALGetInternalHandle( GDALDatasetH hDS, const char * pszRequest )
973 :
974 : {
975 0 : VALIDATE_POINTER1( hDS, "GDALGetInternalHandle", NULL );
976 :
977 0 : return( ((GDALDataset *) hDS)->GetInternalHandle(pszRequest) );
978 : }
979 :
980 : /************************************************************************/
981 : /* GetDriver() */
982 : /************************************************************************/
983 :
984 : /**
985 : * \brief Fetch the driver to which this dataset relates.
986 : *
987 : * This method is the same as the C GDALGetDatasetDriver() function.
988 : *
989 : * @return the driver on which the dataset was created with GDALOpen() or
990 : * GDALCreate().
991 : */
992 :
993 479 : GDALDriver * GDALDataset::GetDriver()
994 :
995 : {
996 479 : return poDriver;
997 : }
998 :
999 : /************************************************************************/
1000 : /* GDALGetDatasetDriver() */
1001 : /************************************************************************/
1002 :
1003 : /**
1004 : * \brief Fetch the driver to which this dataset relates.
1005 : *
1006 : * @see GDALDataset::GetDriver()
1007 : */
1008 :
1009 455 : GDALDriverH CPL_STDCALL GDALGetDatasetDriver( GDALDatasetH hDataset )
1010 :
1011 : {
1012 455 : VALIDATE_POINTER1( hDataset, "GDALGetDatasetDriver", NULL );
1013 :
1014 455 : return (GDALDriverH) ((GDALDataset *) hDataset)->GetDriver();
1015 : }
1016 :
1017 : /************************************************************************/
1018 : /* Reference() */
1019 : /************************************************************************/
1020 :
1021 : /**
1022 : * \brief Add one to dataset reference count.
1023 : *
1024 : * The reference is one after instantiation.
1025 : *
1026 : * This method is the same as the C GDALReferenceDataset() function.
1027 : *
1028 : * @return the post-increment reference count.
1029 : */
1030 :
1031 5233 : int GDALDataset::Reference()
1032 :
1033 : {
1034 5233 : return ++nRefCount;
1035 : }
1036 :
1037 : /************************************************************************/
1038 : /* GDALReferenceDataset() */
1039 : /************************************************************************/
1040 :
1041 : /**
1042 : * \brief Add one to dataset reference count.
1043 : *
1044 : * @see GDALDataset::Reference()
1045 : */
1046 :
1047 46 : int CPL_STDCALL GDALReferenceDataset( GDALDatasetH hDataset )
1048 :
1049 : {
1050 46 : VALIDATE_POINTER1( hDataset, "GDALReferenceDataset", 0 );
1051 :
1052 46 : return ((GDALDataset *) hDataset)->Reference();
1053 : }
1054 :
1055 : /************************************************************************/
1056 : /* Dereference() */
1057 : /************************************************************************/
1058 :
1059 : /**
1060 : * \brief Subtract one from dataset reference count.
1061 : *
1062 : * The reference is one after instantiation. Generally when the reference
1063 : * count has dropped to zero the dataset may be safely deleted (closed).
1064 : *
1065 : * This method is the same as the C GDALDereferenceDataset() function.
1066 : *
1067 : * @return the post-decrement reference count.
1068 : */
1069 :
1070 15108 : int GDALDataset::Dereference()
1071 :
1072 : {
1073 15108 : return --nRefCount;
1074 : }
1075 :
1076 : /************************************************************************/
1077 : /* GDALDereferenceDataset() */
1078 : /************************************************************************/
1079 :
1080 : /**
1081 : * \brief Subtract one from dataset reference count.
1082 : *
1083 : * @see GDALDataset::Dereference()
1084 : */
1085 :
1086 14650 : int CPL_STDCALL GDALDereferenceDataset( GDALDatasetH hDataset )
1087 :
1088 : {
1089 14650 : VALIDATE_POINTER1( hDataset, "GDALDereferenceDataset", 0 );
1090 :
1091 14650 : return ((GDALDataset *) hDataset)->Dereference();
1092 : }
1093 :
1094 : /************************************************************************/
1095 : /* GetShared() */
1096 : /************************************************************************/
1097 :
1098 : /**
1099 : * \brief Returns shared flag.
1100 : *
1101 : * @return TRUE if the GDALDataset is available for sharing, or FALSE if not.
1102 : */
1103 :
1104 12940 : int GDALDataset::GetShared()
1105 :
1106 : {
1107 12940 : return bShared;
1108 : }
1109 :
1110 : /************************************************************************/
1111 : /* MarkAsShared() */
1112 : /************************************************************************/
1113 :
1114 : /**
1115 : * \brief Mark this dataset as available for sharing.
1116 : */
1117 :
1118 170 : void GDALDataset::MarkAsShared()
1119 :
1120 : {
1121 170 : CPLAssert( !bShared );
1122 :
1123 170 : bShared = TRUE;
1124 :
1125 170 : GIntBig nPID = GDALGetResponsiblePIDForCurrentThread();
1126 : SharedDatasetCtxt* psStruct;
1127 :
1128 : /* Insert the dataset in the set of shared opened datasets */
1129 170 : CPLMutexHolderD( &hDLMutex );
1130 170 : if (phSharedDatasetSet == NULL)
1131 149 : phSharedDatasetSet = CPLHashSetNew(GDALSharedDatasetHashFunc, GDALSharedDatasetEqualFunc, GDALSharedDatasetFreeFunc);
1132 :
1133 170 : psStruct = (SharedDatasetCtxt*)CPLMalloc(sizeof(SharedDatasetCtxt));
1134 170 : psStruct->poDS = this;
1135 170 : psStruct->nPID = nPID;
1136 170 : psStruct->eAccess = eAccess;
1137 170 : psStruct->pszDescription = CPLStrdup(GetDescription());
1138 170 : if(CPLHashSetLookup(phSharedDatasetSet, psStruct) != NULL)
1139 : {
1140 0 : CPLFree(psStruct);
1141 : CPLError(CE_Failure, CPLE_AppDefined,
1142 0 : "An existing shared dataset has already this description. This should not happen");
1143 : }
1144 : else
1145 : {
1146 170 : CPLHashSetInsert(phSharedDatasetSet, psStruct);
1147 :
1148 : DatasetCtxt sStruct;
1149 170 : sStruct.poDS = this;
1150 170 : DatasetCtxt* psStruct = (DatasetCtxt*) CPLHashSetLookup(phAllDatasetSet, &sStruct);
1151 170 : psStruct->nPIDCreatorForShared = nPID;
1152 170 : }
1153 170 : }
1154 :
1155 : /************************************************************************/
1156 : /* GetGCPCount() */
1157 : /************************************************************************/
1158 :
1159 : /**
1160 : * \brief Get number of GCPs.
1161 : *
1162 : * This method is the same as the C function GDALGetGCPCount().
1163 : *
1164 : * @return number of GCPs for this dataset. Zero if there are none.
1165 : */
1166 :
1167 3533 : int GDALDataset::GetGCPCount()
1168 :
1169 : {
1170 3533 : return 0;
1171 : }
1172 :
1173 : /************************************************************************/
1174 : /* GDALGetGCPCount() */
1175 : /************************************************************************/
1176 :
1177 : /**
1178 : * \brief Get number of GCPs.
1179 : *
1180 : * @see GDALDataset::GetGCPCount()
1181 : */
1182 :
1183 185 : int CPL_STDCALL GDALGetGCPCount( GDALDatasetH hDS )
1184 :
1185 : {
1186 185 : VALIDATE_POINTER1( hDS, "GDALGetGCPCount", 0 );
1187 :
1188 185 : return ((GDALDataset *) hDS)->GetGCPCount();
1189 : }
1190 :
1191 : /************************************************************************/
1192 : /* GetGCPProjection() */
1193 : /************************************************************************/
1194 :
1195 : /**
1196 : * \brief Get output projection for GCPs.
1197 : *
1198 : * This method is the same as the C function GDALGetGCPProjection().
1199 : *
1200 : * The projection string follows the normal rules from GetProjectionRef().
1201 : *
1202 : * @return internal projection string or "" if there are no GCPs.
1203 : * It should not be altered, freed or expected to last for long.
1204 : */
1205 :
1206 0 : const char *GDALDataset::GetGCPProjection()
1207 :
1208 : {
1209 0 : return "";
1210 : }
1211 :
1212 : /************************************************************************/
1213 : /* GDALGetGCPProjection() */
1214 : /************************************************************************/
1215 :
1216 : /**
1217 : * \brief Get output projection for GCPs.
1218 : *
1219 : * @see GDALDataset::GetGCPProjection()
1220 : */
1221 :
1222 90 : const char * CPL_STDCALL GDALGetGCPProjection( GDALDatasetH hDS )
1223 :
1224 : {
1225 90 : VALIDATE_POINTER1( hDS, "GDALGetGCPProjection", NULL );
1226 :
1227 90 : return ((GDALDataset *) hDS)->GetGCPProjection();
1228 : }
1229 :
1230 : /************************************************************************/
1231 : /* GetGCPs() */
1232 : /************************************************************************/
1233 :
1234 : /**
1235 : * \brief Fetch GCPs.
1236 : *
1237 : * This method is the same as the C function GDALGetGCPs().
1238 : *
1239 : * @return pointer to internal GCP structure list. It should not be modified,
1240 : * and may change on the next GDAL call.
1241 : */
1242 :
1243 0 : const GDAL_GCP *GDALDataset::GetGCPs()
1244 :
1245 : {
1246 0 : return NULL;
1247 : }
1248 :
1249 : /************************************************************************/
1250 : /* GDALGetGCPs() */
1251 : /************************************************************************/
1252 :
1253 : /**
1254 : * \brief Fetch GCPs.
1255 : *
1256 : * @see GDALDataset::GetGCPs()
1257 : */
1258 :
1259 60 : const GDAL_GCP * CPL_STDCALL GDALGetGCPs( GDALDatasetH hDS )
1260 :
1261 : {
1262 60 : VALIDATE_POINTER1( hDS, "GDALGetGCPs", NULL );
1263 :
1264 60 : return ((GDALDataset *) hDS)->GetGCPs();
1265 : }
1266 :
1267 :
1268 : /************************************************************************/
1269 : /* SetGCPs() */
1270 : /************************************************************************/
1271 :
1272 : /**
1273 : * \brief Assign GCPs.
1274 : *
1275 : * This method is the same as the C function GDALSetGCPs().
1276 : *
1277 : * This method assigns the passed set of GCPs to this dataset, as well as
1278 : * setting their coordinate system. Internally copies are made of the
1279 : * coordinate system and list of points, so the caller remains resposible for
1280 : * deallocating these arguments if appropriate.
1281 : *
1282 : * Most formats do not support setting of GCPs, even foramts that can
1283 : * handle GCPs. These formats will return CE_Failure.
1284 : *
1285 : * @param nGCPCount number of GCPs being assigned.
1286 : *
1287 : * @param pasGCPList array of GCP structures being assign (nGCPCount in array).
1288 : *
1289 : * @param pszGCPProjection the new OGC WKT coordinate system to assign for the
1290 : * GCP output coordinates. This parameter should be "" if no output coordinate
1291 : * system is known.
1292 : *
1293 : * @return CE_None on success, CE_Failure on failure (including if action is
1294 : * not supported for this format).
1295 : */
1296 :
1297 : CPLErr GDALDataset::SetGCPs( int nGCPCount,
1298 : const GDAL_GCP *pasGCPList,
1299 0 : const char * pszGCPProjection )
1300 :
1301 : {
1302 : (void) nGCPCount;
1303 : (void) pasGCPList;
1304 : (void) pszGCPProjection;
1305 :
1306 0 : if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
1307 : CPLError( CE_Failure, CPLE_NotSupported,
1308 0 : "Dataset does not support the SetGCPs() method." );
1309 :
1310 0 : return CE_Failure;
1311 : }
1312 :
1313 : /************************************************************************/
1314 : /* GDALSetGCPs() */
1315 : /************************************************************************/
1316 :
1317 : /**
1318 : * \brief Assign GCPs.
1319 : *
1320 : * @see GDALDataset::SetGCPs()
1321 : */
1322 :
1323 : CPLErr CPL_STDCALL GDALSetGCPs( GDALDatasetH hDS, int nGCPCount,
1324 : const GDAL_GCP *pasGCPList,
1325 2 : const char *pszGCPProjection )
1326 :
1327 : {
1328 2 : VALIDATE_POINTER1( hDS, "GDALSetGCPs", CE_Failure );
1329 :
1330 : return ((GDALDataset *) hDS)->SetGCPs( nGCPCount, pasGCPList,
1331 2 : pszGCPProjection );
1332 : }
1333 :
1334 : /************************************************************************/
1335 : /* BuildOverviews() */
1336 : /************************************************************************/
1337 :
1338 : /**
1339 : * \brief Build raster overview(s)
1340 : *
1341 : * If the operation is unsupported for the indicated dataset, then
1342 : * CE_Failure is returned, and CPLGetLastErrorNo() will return
1343 : * CPLE_NotSupported.
1344 : *
1345 : * This method is the same as the C function GDALBuildOverviews().
1346 : *
1347 : * @param pszResampling one of "NEAREST", "GAUSS", "CUBIC", "AVERAGE", "MODE",
1348 : * "AVERAGE_MAGPHASE" or "NONE" controlling the downsampling method applied.
1349 : * @param nOverviews number of overviews to build.
1350 : * @param panOverviewList the list of overview decimation factors to build.
1351 : * @param nBand number of bands to build overviews for in panBandList. Build
1352 : * for all bands if this is 0.
1353 : * @param panBandList list of band numbers.
1354 : * @param pfnProgress a function to call to report progress, or NULL.
1355 : * @param pProgressData application data to pass to the progress function.
1356 : *
1357 : * @return CE_None on success or CE_Failure if the operation doesn't work.
1358 : *
1359 : * For example, to build overview level 2, 4 and 8 on all bands the following
1360 : * call could be made:
1361 : * <pre>
1362 : * int anOverviewList[3] = { 2, 4, 8 };
1363 : *
1364 : * poDataset->BuildOverviews( "NEAREST", 3, anOverviewList, 0, NULL,
1365 : * GDALDummyProgress, NULL );
1366 : * </pre>
1367 : *
1368 : * @see GDALRegenerateOverviews()
1369 : */
1370 :
1371 : CPLErr GDALDataset::BuildOverviews( const char *pszResampling,
1372 : int nOverviews, int *panOverviewList,
1373 : int nListBands, int *panBandList,
1374 : GDALProgressFunc pfnProgress,
1375 147 : void * pProgressData )
1376 :
1377 : {
1378 : CPLErr eErr;
1379 147 : int *panAllBandList = NULL;
1380 :
1381 147 : if( nListBands == 0 )
1382 : {
1383 145 : nListBands = GetRasterCount();
1384 145 : panAllBandList = (int *) CPLMalloc(sizeof(int) * nListBands);
1385 355 : for( int i = 0; i < nListBands; i++ )
1386 210 : panAllBandList[i] = i+1;
1387 :
1388 145 : panBandList = panAllBandList;
1389 : }
1390 :
1391 147 : if( pfnProgress == NULL )
1392 140 : pfnProgress = GDALDummyProgress;
1393 :
1394 : eErr = IBuildOverviews( pszResampling, nOverviews, panOverviewList,
1395 147 : nListBands, panBandList, pfnProgress, pProgressData );
1396 :
1397 147 : if( panAllBandList != NULL )
1398 145 : CPLFree( panAllBandList );
1399 :
1400 147 : return eErr;
1401 : }
1402 :
1403 : /************************************************************************/
1404 : /* GDALBuildOverviews() */
1405 : /************************************************************************/
1406 :
1407 : /**
1408 : * \brief Build raster overview(s)
1409 : *
1410 : * @see GDALDataset::BuildOverviews()
1411 : */
1412 :
1413 : CPLErr CPL_STDCALL GDALBuildOverviews( GDALDatasetH hDataset,
1414 : const char *pszResampling,
1415 : int nOverviews, int *panOverviewList,
1416 : int nListBands, int *panBandList,
1417 : GDALProgressFunc pfnProgress,
1418 143 : void * pProgressData )
1419 :
1420 : {
1421 143 : VALIDATE_POINTER1( hDataset, "GDALBuildOverviews", CE_Failure );
1422 :
1423 : return ((GDALDataset *) hDataset)->BuildOverviews(
1424 : pszResampling, nOverviews, panOverviewList, nListBands, panBandList,
1425 143 : pfnProgress, pProgressData );
1426 : }
1427 :
1428 : /************************************************************************/
1429 : /* IBuildOverviews() */
1430 : /* */
1431 : /* Default implementation. */
1432 : /************************************************************************/
1433 :
1434 : CPLErr GDALDataset::IBuildOverviews( const char *pszResampling,
1435 : int nOverviews, int *panOverviewList,
1436 : int nListBands, int *panBandList,
1437 : GDALProgressFunc pfnProgress,
1438 72 : void * pProgressData )
1439 :
1440 : {
1441 72 : if( oOvManager.IsInitialized() )
1442 : return oOvManager.BuildOverviews( NULL, pszResampling,
1443 : nOverviews, panOverviewList,
1444 : nListBands, panBandList,
1445 72 : pfnProgress, pProgressData );
1446 : else
1447 : {
1448 : CPLError( CE_Failure, CPLE_NotSupported,
1449 0 : "BuildOverviews() not supported for this dataset." );
1450 :
1451 0 : return( CE_Failure );
1452 : }
1453 : }
1454 :
1455 : /************************************************************************/
1456 : /* IRasterIO() */
1457 : /* */
1458 : /* The default implementation of IRasterIO() is to pass the */
1459 : /* request off to each band objects rasterio methods with */
1460 : /* appropriate arguments. */
1461 : /************************************************************************/
1462 :
1463 : CPLErr GDALDataset::IRasterIO( GDALRWFlag eRWFlag,
1464 : int nXOff, int nYOff, int nXSize, int nYSize,
1465 : void * pData, int nBufXSize, int nBufYSize,
1466 : GDALDataType eBufType,
1467 : int nBandCount, int *panBandMap,
1468 347774 : int nPixelSpace, int nLineSpace, int nBandSpace)
1469 :
1470 : {
1471 : int iBandIndex;
1472 347774 : CPLErr eErr = CE_None;
1473 347774 : const char* pszInterleave = NULL;
1474 :
1475 347774 : CPLAssert( NULL != pData );
1476 :
1477 347774 : if (nXSize == nBufXSize && nYSize == nBufYSize &&
1478 : (pszInterleave = GetMetadataItem("INTERLEAVE", "IMAGE_STRUCTURE")) != NULL &&
1479 : EQUAL(pszInterleave, "PIXEL"))
1480 : {
1481 : return BlockBasedRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
1482 : pData, nBufXSize, nBufYSize,
1483 : eBufType, nBandCount, panBandMap,
1484 942 : nPixelSpace, nLineSpace, nBandSpace );
1485 : }
1486 :
1487 710888 : for( iBandIndex = 0;
1488 : iBandIndex < nBandCount && eErr == CE_None;
1489 : iBandIndex++ )
1490 : {
1491 364056 : GDALRasterBand *poBand = GetRasterBand(panBandMap[iBandIndex]);
1492 : GByte *pabyBandData;
1493 :
1494 364056 : pabyBandData = ((GByte *) pData) + iBandIndex * nBandSpace;
1495 :
1496 : eErr = poBand->IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
1497 : (void *) pabyBandData, nBufXSize, nBufYSize,
1498 364056 : eBufType, nPixelSpace, nLineSpace );
1499 : }
1500 :
1501 346832 : return eErr;
1502 : }
1503 :
1504 :
1505 : /************************************************************************/
1506 : /* RasterIO() */
1507 : /************************************************************************/
1508 :
1509 : /**
1510 : * \brief Read/write a region of image data from multiple bands.
1511 : *
1512 : * This method allows reading a region of one or more GDALRasterBands from
1513 : * this dataset into a buffer, or writing data from a buffer into a region
1514 : * of the GDALRasterBands. It automatically takes care of data type
1515 : * translation if the data type (eBufType) of the buffer is different than
1516 : * that of the GDALRasterBand.
1517 : * The method also takes care of image decimation / replication if the
1518 : * buffer size (nBufXSize x nBufYSize) is different than the size of the
1519 : * region being accessed (nXSize x nYSize).
1520 : *
1521 : * The nPixelSpace, nLineSpace and nBandSpace parameters allow reading into or
1522 : * writing from various organization of buffers.
1523 : *
1524 : * For highest performance full resolution data access, read and write
1525 : * on "block boundaries" as returned by GetBlockSize(), or use the
1526 : * ReadBlock() and WriteBlock() methods.
1527 : *
1528 : * This method is the same as the C GDALDatasetRasterIO() function.
1529 : *
1530 : * @param eRWFlag Either GF_Read to read a region of data, or GF_Write to
1531 : * write a region of data.
1532 : *
1533 : * @param nXOff The pixel offset to the top left corner of the region
1534 : * of the band to be accessed. This would be zero to start from the left side.
1535 : *
1536 : * @param nYOff The line offset to the top left corner of the region
1537 : * of the band to be accessed. This would be zero to start from the top.
1538 : *
1539 : * @param nXSize The width of the region of the band to be accessed in pixels.
1540 : *
1541 : * @param nYSize The height of the region of the band to be accessed in lines.
1542 : *
1543 : * @param pData The buffer into which the data should be read, or from which
1544 : * it should be written. This buffer must contain at least
1545 : * nBufXSize * nBufYSize * nBandCount words of type eBufType. It is organized
1546 : * in left to right,top to bottom pixel order. Spacing is controlled by the
1547 : * nPixelSpace, and nLineSpace parameters.
1548 : *
1549 : * @param nBufXSize the width of the buffer image into which the desired region
1550 : * is to be read, or from which it is to be written.
1551 : *
1552 : * @param nBufYSize the height of the buffer image into which the desired
1553 : * region is to be read, or from which it is to be written.
1554 : *
1555 : * @param eBufType the type of the pixel values in the pData data buffer. The
1556 : * pixel values will automatically be translated to/from the GDALRasterBand
1557 : * data type as needed.
1558 : *
1559 : * @param nBandCount the number of bands being read or written.
1560 : *
1561 : * @param panBandMap the list of nBandCount band numbers being read/written.
1562 : * Note band numbers are 1 based. This may be NULL to select the first
1563 : * nBandCount bands.
1564 : *
1565 : * @param nPixelSpace The byte offset from the start of one pixel value in
1566 : * pData to the start of the next pixel value within a scanline. If defaulted
1567 : * (0) the size of the datatype eBufType is used.
1568 : *
1569 : * @param nLineSpace The byte offset from the start of one scanline in
1570 : * pData to the start of the next. If defaulted (0) the size of the datatype
1571 : * eBufType * nBufXSize is used.
1572 : *
1573 : * @param nBandSpace the byte offset from the start of one bands data to the
1574 : * start of the next. If defaulted (0) the value will be
1575 : * nLineSpace * nBufYSize implying band sequential organization
1576 : * of the data buffer.
1577 : *
1578 : * @return CE_Failure if the access fails, otherwise CE_None.
1579 : */
1580 :
1581 : CPLErr GDALDataset::RasterIO( GDALRWFlag eRWFlag,
1582 : int nXOff, int nYOff, int nXSize, int nYSize,
1583 : void * pData, int nBufXSize, int nBufYSize,
1584 : GDALDataType eBufType,
1585 : int nBandCount, int *panBandMap,
1586 347848 : int nPixelSpace, int nLineSpace, int nBandSpace )
1587 :
1588 : {
1589 347848 : int i = 0;
1590 347848 : int bNeedToFreeBandMap = FALSE;
1591 347848 : CPLErr eErr = CE_None;
1592 :
1593 347848 : if( NULL == pData )
1594 : {
1595 : CPLError( CE_Failure, CPLE_AppDefined,
1596 0 : "The buffer into which the data should be read is null" );
1597 0 : return CE_Failure;
1598 : }
1599 :
1600 : /* -------------------------------------------------------------------- */
1601 : /* Some size values are "noop". Lets just return to avoid */
1602 : /* stressing lower level functions. */
1603 : /* -------------------------------------------------------------------- */
1604 347848 : if( nXSize < 1 || nYSize < 1 || nBufXSize < 1 || nBufYSize < 1 )
1605 : {
1606 : CPLDebug( "GDAL",
1607 : "RasterIO() skipped for odd window or buffer size.\n"
1608 : " Window = (%d,%d)x%dx%d\n"
1609 : " Buffer = %dx%d\n",
1610 : nXOff, nYOff, nXSize, nYSize,
1611 0 : nBufXSize, nBufYSize );
1612 :
1613 0 : return CE_None;
1614 : }
1615 :
1616 : /* -------------------------------------------------------------------- */
1617 : /* If pixel and line spaceing are defaulted assign reasonable */
1618 : /* value assuming a packed buffer. */
1619 : /* -------------------------------------------------------------------- */
1620 347848 : if( nPixelSpace == 0 )
1621 338911 : nPixelSpace = GDALGetDataTypeSize( eBufType ) / 8;
1622 :
1623 347848 : if( nLineSpace == 0 )
1624 : {
1625 345959 : if (nPixelSpace > INT_MAX / nBufXSize)
1626 : {
1627 : CPLError( CE_Failure, CPLE_AppDefined,
1628 0 : "Int overflow : %d x %d", nPixelSpace, nBufXSize );
1629 0 : return CE_Failure;
1630 : }
1631 345959 : nLineSpace = nPixelSpace * nBufXSize;
1632 : }
1633 :
1634 : /* The nBandCount > 1 test is necessary to allow reading only */
1635 : /* one band, even if the nLineSpace would overflow, but as it */
1636 : /* is not used in that case, it can be left to 0 (#3481) */
1637 347848 : if( nBandSpace == 0 && nBandCount > 1 )
1638 : {
1639 746 : if (nLineSpace > INT_MAX / nBufYSize)
1640 : {
1641 : CPLError( CE_Failure, CPLE_AppDefined,
1642 0 : "Int overflow : %d x %d", nLineSpace, nBufYSize );
1643 0 : return CE_Failure;
1644 : }
1645 746 : nBandSpace = nLineSpace * nBufYSize;
1646 : }
1647 :
1648 347848 : if( panBandMap == NULL )
1649 : {
1650 9338 : if (nBandCount > GetRasterCount())
1651 : {
1652 : CPLError( CE_Failure, CPLE_IllegalArg,
1653 : "nBandCount cannot be greater than %d",
1654 0 : GetRasterCount() );
1655 0 : return CE_Failure;
1656 : }
1657 9338 : panBandMap = (int *) VSIMalloc2(sizeof(int), nBandCount);
1658 9338 : if (panBandMap == NULL)
1659 : {
1660 : CPLError( CE_Failure, CPLE_OutOfMemory,
1661 0 : "Out of memory while allocating band map array" );
1662 0 : return CE_Failure;
1663 : }
1664 36312 : for( i = 0; i < nBandCount; i++ )
1665 26974 : panBandMap[i] = i+1;
1666 :
1667 9338 : bNeedToFreeBandMap = TRUE;
1668 : }
1669 :
1670 : /* -------------------------------------------------------------------- */
1671 : /* Do some validation of parameters. */
1672 : /* -------------------------------------------------------------------- */
1673 347848 : if( nXOff < 0 || nXOff > INT_MAX - nXSize || nXOff + nXSize > nRasterXSize
1674 : || nYOff < 0 || nYOff > INT_MAX - nYSize || nYOff + nYSize > nRasterYSize )
1675 : {
1676 : CPLError( CE_Failure, CPLE_IllegalArg,
1677 : "Access window out of range in RasterIO(). Requested\n"
1678 : "(%d,%d) of size %dx%d on raster of %dx%d.",
1679 2 : nXOff, nYOff, nXSize, nYSize, nRasterXSize, nRasterYSize );
1680 2 : eErr = CE_Failure;
1681 : }
1682 :
1683 347848 : if( eRWFlag != GF_Read && eRWFlag != GF_Write )
1684 : {
1685 : CPLError( CE_Failure, CPLE_IllegalArg,
1686 : "eRWFlag = %d, only GF_Read (0) and GF_Write (1) are legal.",
1687 0 : eRWFlag );
1688 0 : eErr = CE_Failure;
1689 : }
1690 :
1691 714964 : for( i = 0; i < nBandCount && eErr == CE_None; i++ )
1692 : {
1693 367116 : if( panBandMap[i] < 1 || panBandMap[i] > GetRasterCount() )
1694 : {
1695 : CPLError( CE_Failure, CPLE_IllegalArg,
1696 : "panBandMap[%d] = %d, this band does not exist on dataset.",
1697 0 : i, panBandMap[i] );
1698 0 : eErr = CE_Failure;
1699 : }
1700 :
1701 367116 : if( eErr == CE_None && GetRasterBand( panBandMap[i] ) == NULL )
1702 : {
1703 : CPLError( CE_Failure, CPLE_IllegalArg,
1704 : "panBandMap[%d]=%d, this band should exist but is NULL!",
1705 0 : i, panBandMap[i] );
1706 0 : eErr = CE_Failure;
1707 : }
1708 : }
1709 :
1710 : /* -------------------------------------------------------------------- */
1711 : /* We are being forced to use cached IO instead of a driver */
1712 : /* specific implementation. */
1713 : /* -------------------------------------------------------------------- */
1714 347848 : if( bForceCachedIO )
1715 : {
1716 : eErr =
1717 : BlockBasedRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
1718 : pData, nBufXSize, nBufYSize, eBufType,
1719 : nBandCount, panBandMap,
1720 6 : nPixelSpace, nLineSpace, nBandSpace );
1721 : }
1722 :
1723 : /* -------------------------------------------------------------------- */
1724 : /* Call the format specific function. */
1725 : /* -------------------------------------------------------------------- */
1726 347842 : else if( eErr == CE_None )
1727 : {
1728 : eErr =
1729 : IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
1730 : pData, nBufXSize, nBufYSize, eBufType,
1731 : nBandCount, panBandMap,
1732 347840 : nPixelSpace, nLineSpace, nBandSpace );
1733 : }
1734 :
1735 : /* -------------------------------------------------------------------- */
1736 : /* Cleanup */
1737 : /* -------------------------------------------------------------------- */
1738 347848 : if( bNeedToFreeBandMap )
1739 9338 : CPLFree( panBandMap );
1740 :
1741 347848 : return eErr;
1742 : }
1743 :
1744 : /************************************************************************/
1745 : /* GDALDatasetRasterIO() */
1746 : /************************************************************************/
1747 :
1748 : /**
1749 : * \brief Read/write a region of image data from multiple bands.
1750 : *
1751 : * @see GDALDataset::RasterIO()
1752 : */
1753 :
1754 : CPLErr CPL_STDCALL
1755 : GDALDatasetRasterIO( GDALDatasetH hDS, GDALRWFlag eRWFlag,
1756 : int nXOff, int nYOff, int nXSize, int nYSize,
1757 : void * pData, int nBufXSize, int nBufYSize,
1758 : GDALDataType eBufType,
1759 : int nBandCount, int *panBandMap,
1760 338219 : int nPixelSpace, int nLineSpace, int nBandSpace )
1761 :
1762 : {
1763 338219 : VALIDATE_POINTER1( hDS, "GDALDatasetRasterIO", CE_Failure );
1764 :
1765 338219 : GDALDataset *poDS = (GDALDataset *) hDS;
1766 :
1767 : return( poDS->RasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
1768 : pData, nBufXSize, nBufYSize, eBufType,
1769 : nBandCount, panBandMap,
1770 338219 : nPixelSpace, nLineSpace, nBandSpace ) );
1771 : }
1772 :
1773 : /************************************************************************/
1774 : /* GetOpenDatasets() */
1775 : /************************************************************************/
1776 :
1777 0 : static int GDALGetOpenDatasetsForeach(void* elt, void* user_data)
1778 : {
1779 0 : int* pnIndex = (int*) user_data;
1780 0 : ppDatasets[*pnIndex] = (GDALDataset*) elt;
1781 :
1782 0 : (*pnIndex) ++;
1783 :
1784 0 : return TRUE;
1785 : }
1786 :
1787 : /**
1788 : * \brief Fetch all open GDAL dataset handles.
1789 : *
1790 : * This method is the same as the C function GDALGetOpenDatasets().
1791 : *
1792 : * NOTE: This method is not thread safe. The returned list may changed
1793 : * at any time.
1794 : *
1795 : * @param pnCount integer into which to place the count of dataset pointers
1796 : * being returned.
1797 : *
1798 : * @return a pointer to an array of dataset handles.
1799 : */
1800 :
1801 0 : GDALDataset **GDALDataset::GetOpenDatasets( int *pnCount )
1802 :
1803 : {
1804 0 : CPLMutexHolderD( &hDLMutex );
1805 :
1806 0 : if (phAllDatasetSet != NULL)
1807 : {
1808 0 : int nIndex = 0;
1809 0 : *pnCount = CPLHashSetSize(phAllDatasetSet);
1810 0 : ppDatasets = (GDALDataset**) CPLRealloc(ppDatasets, (*pnCount) * sizeof(GDALDataset*));
1811 0 : CPLHashSetForeach(phAllDatasetSet, GDALGetOpenDatasetsForeach, &nIndex);
1812 0 : return ppDatasets;
1813 : }
1814 : else
1815 : {
1816 0 : *pnCount = 0;
1817 0 : return NULL;
1818 0 : }
1819 : }
1820 :
1821 : /************************************************************************/
1822 : /* GDALGetOpenDatasets() */
1823 : /************************************************************************/
1824 :
1825 : /**
1826 : * \brief Fetch all open GDAL dataset handles.
1827 : *
1828 : * @see GDALDataset::GetOpenDatasets()
1829 : */
1830 :
1831 0 : void CPL_STDCALL GDALGetOpenDatasets( GDALDatasetH **ppahDSList, int *pnCount )
1832 :
1833 : {
1834 0 : VALIDATE_POINTER0( ppahDSList, "GDALGetOpenDatasets" );
1835 0 : VALIDATE_POINTER0( pnCount, "GDALGetOpenDatasets" );
1836 :
1837 0 : *ppahDSList = (GDALDatasetH *) GDALDataset::GetOpenDatasets( pnCount);
1838 : }
1839 :
1840 : /************************************************************************/
1841 : /* GDALGetAccess() */
1842 : /************************************************************************/
1843 :
1844 : /**
1845 : * \brief Return access flag
1846 : *
1847 : * @see GDALDataset::GetAccess()
1848 : */
1849 :
1850 0 : int CPL_STDCALL GDALGetAccess( GDALDatasetH hDS )
1851 : {
1852 0 : VALIDATE_POINTER1( hDS, "GDALGetAccess", 0 );
1853 :
1854 0 : return ((GDALDataset *) hDS)->GetAccess();
1855 : }
1856 :
1857 : /************************************************************************/
1858 : /* AdviseRead() */
1859 : /************************************************************************/
1860 :
1861 : /**
1862 : * \brief Advise driver of upcoming read requests.
1863 : *
1864 : * Some GDAL drivers operate more efficiently if they know in advance what
1865 : * set of upcoming read requests will be made. The AdviseRead() method allows
1866 : * an application to notify the driver of the region and bands of interest,
1867 : * and at what resolution the region will be read.
1868 : *
1869 : * Many drivers just ignore the AdviseRead() call, but it can dramatically
1870 : * accelerate access via some drivers.
1871 : *
1872 : * @param nXOff The pixel offset to the top left corner of the region
1873 : * of the band to be accessed. This would be zero to start from the left side.
1874 : *
1875 : * @param nYOff The line offset to the top left corner of the region
1876 : * of the band to be accessed. This would be zero to start from the top.
1877 : *
1878 : * @param nXSize The width of the region of the band to be accessed in pixels.
1879 : *
1880 : * @param nYSize The height of the region of the band to be accessed in lines.
1881 : *
1882 : * @param nBufXSize the width of the buffer image into which the desired region
1883 : * is to be read, or from which it is to be written.
1884 : *
1885 : * @param nBufYSize the height of the buffer image into which the desired
1886 : * region is to be read, or from which it is to be written.
1887 : *
1888 : * @param eBufType the type of the pixel values in the pData data buffer. The
1889 : * pixel values will automatically be translated to/from the GDALRasterBand
1890 : * data type as needed.
1891 : *
1892 : * @param nBandCount the number of bands being read or written.
1893 : *
1894 : * @param panBandMap the list of nBandCount band numbers being read/written.
1895 : * Note band numbers are 1 based. This may be NULL to select the first
1896 : * nBandCount bands.
1897 : *
1898 : * @param papszOptions a list of name=value strings with special control
1899 : * options. Normally this is NULL.
1900 : *
1901 : * @return CE_Failure if the request is invalid and CE_None if it works or
1902 : * is ignored.
1903 : */
1904 :
1905 : CPLErr GDALDataset::AdviseRead( int nXOff, int nYOff, int nXSize, int nYSize,
1906 : int nBufXSize, int nBufYSize,
1907 : GDALDataType eDT,
1908 : int nBandCount, int *panBandMap,
1909 0 : char **papszOptions )
1910 :
1911 : {
1912 : int iBand;
1913 :
1914 0 : for( iBand = 0; iBand < nBandCount; iBand++ )
1915 : {
1916 : CPLErr eErr;
1917 : GDALRasterBand *poBand;
1918 :
1919 0 : if( panBandMap == NULL )
1920 0 : poBand = GetRasterBand(iBand+1);
1921 : else
1922 0 : poBand = GetRasterBand(panBandMap[iBand]);
1923 :
1924 : eErr = poBand->AdviseRead( nXOff, nYOff, nXSize, nYSize,
1925 0 : nBufXSize, nBufYSize, eDT, papszOptions );
1926 :
1927 0 : if( eErr != CE_None )
1928 0 : return eErr;
1929 : }
1930 :
1931 0 : return CE_None;
1932 : }
1933 :
1934 : /************************************************************************/
1935 : /* GDALDatasetAdviseRead() */
1936 : /************************************************************************/
1937 :
1938 : /**
1939 : * \brief Advise driver of upcoming read requests.
1940 : *
1941 : * @see GDALDataset::AdviseRead()
1942 : */
1943 : CPLErr CPL_STDCALL
1944 : GDALDatasetAdviseRead( GDALDatasetH hDS,
1945 : int nXOff, int nYOff, int nXSize, int nYSize,
1946 : int nBufXSize, int nBufYSize, GDALDataType eDT,
1947 0 : int nBandCount, int *panBandMap,char **papszOptions )
1948 :
1949 : {
1950 0 : VALIDATE_POINTER1( hDS, "GDALDatasetAdviseRead", CE_Failure );
1951 :
1952 : return ((GDALDataset *) hDS)->AdviseRead( nXOff, nYOff, nXSize, nYSize,
1953 : nBufXSize, nBufYSize, eDT,
1954 : nBandCount, panBandMap,
1955 0 : papszOptions );
1956 : }
1957 :
1958 : /************************************************************************/
1959 : /* GetFileList() */
1960 : /************************************************************************/
1961 :
1962 : /**
1963 : * \brief Fetch files forming dataset.
1964 : *
1965 : * Returns a list of files believed to be part of this dataset. If it returns
1966 : * an empty list of files it means there is believed to be no local file
1967 : * system files associated with the dataset (for instance a virtual dataset).
1968 : * The returned file list is owned by the caller and should be deallocated
1969 : * with CSLDestroy().
1970 : *
1971 : * The returned filenames will normally be relative or absolute paths
1972 : * depending on the path used to originally open the dataset.
1973 : *
1974 : * This method is the same as the C GDALGetFileList() function.
1975 : *
1976 : * @return NULL or a NULL terminated array of file names.
1977 : */
1978 :
1979 1340 : char **GDALDataset::GetFileList()
1980 :
1981 : {
1982 1340 : CPLString osMainFilename = GetDescription();
1983 : int bMainFileReal;
1984 : VSIStatBufL sStat;
1985 :
1986 : /* -------------------------------------------------------------------- */
1987 : /* Is the main filename even a real filesystem object? */
1988 : /* -------------------------------------------------------------------- */
1989 1340 : bMainFileReal = VSIStatL( osMainFilename, &sStat ) == 0;
1990 :
1991 : /* -------------------------------------------------------------------- */
1992 : /* Form new list. */
1993 : /* -------------------------------------------------------------------- */
1994 1340 : char **papszList = NULL;
1995 :
1996 1340 : if( bMainFileReal )
1997 1235 : papszList = CSLAddString( papszList, osMainFilename );
1998 :
1999 : /* -------------------------------------------------------------------- */
2000 : /* Do we have a known overview file? */
2001 : /* -------------------------------------------------------------------- */
2002 1340 : if( oOvManager.IsInitialized() && oOvManager.poODS != NULL )
2003 : {
2004 59 : char **papszOvrList = oOvManager.poODS->GetFileList();
2005 59 : papszList = CSLInsertStrings( papszList, -1, papszOvrList );
2006 59 : CSLDestroy( papszOvrList );
2007 : }
2008 :
2009 : /* -------------------------------------------------------------------- */
2010 : /* Do we have a known overview file? */
2011 : /* -------------------------------------------------------------------- */
2012 1340 : if( oOvManager.HaveMaskFile() )
2013 : {
2014 4 : char **papszMskList = oOvManager.poMaskDS->GetFileList();
2015 4 : papszList = CSLInsertStrings( papszList, -1, papszMskList );
2016 4 : CSLDestroy( papszMskList );
2017 : }
2018 :
2019 : /* -------------------------------------------------------------------- */
2020 : /* Do we have a world file? */
2021 : /* -------------------------------------------------------------------- */
2022 1340 : if( bMainFileReal )
2023 : {
2024 1235 : const char* pszExtension = CPLGetExtension( osMainFilename );
2025 1235 : if( strlen(pszExtension) > 2 )
2026 : {
2027 : // first + last + 'w'
2028 : char szDerivedExtension[4];
2029 1224 : szDerivedExtension[0] = pszExtension[0];
2030 1224 : szDerivedExtension[1] = pszExtension[strlen(pszExtension)-1];
2031 1224 : szDerivedExtension[2] = 'w';
2032 1224 : szDerivedExtension[3] = '\0';
2033 1224 : CPLString osWorldFilename = CPLResetExtension( osMainFilename, szDerivedExtension );
2034 :
2035 1224 : if( VSIStatL( osWorldFilename, &sStat ) == 0 )
2036 3 : papszList = CSLAddString( papszList, osWorldFilename );
2037 : }
2038 : }
2039 :
2040 1340 : return papszList;
2041 : }
2042 :
2043 : /************************************************************************/
2044 : /* GDALGetFileList() */
2045 : /************************************************************************/
2046 :
2047 : /**
2048 : * \brief Fetch files forming dataset.
2049 : *
2050 : * @see GDALDataset::GetFileList()
2051 : */
2052 :
2053 1268 : char ** CPL_STDCALL GDALGetFileList( GDALDatasetH hDS )
2054 :
2055 : {
2056 1268 : VALIDATE_POINTER1( hDS, "GDALGetFileList", NULL );
2057 :
2058 1268 : return ((GDALDataset *) hDS)->GetFileList();
2059 : }
2060 :
2061 : /************************************************************************/
2062 : /* CreateMaskBand() */
2063 : /************************************************************************/
2064 :
2065 : /**
2066 : * \brief Adds a mask band to the dataset
2067 : *
2068 : * The default implementation of the CreateMaskBand() method is implemented
2069 : * based on similar rules to the .ovr handling implemented using the
2070 : * GDALDefaultOverviews object. A TIFF file with the extension .msk will
2071 : * be created with the same basename as the original file, and it will have
2072 : * one band.
2073 : * The mask images will be deflate compressed tiled images with the same
2074 : * block size as the original image if possible.
2075 : *
2076 : * @since GDAL 1.5.0
2077 : *
2078 : * @param nFlags ignored. GMF_PER_DATASET will be assumed.
2079 : * @return CE_None on success or CE_Failure on an error.
2080 : *
2081 : * @see http://trac.osgeo.org/gdal/wiki/rfc15_nodatabitmask
2082 : *
2083 : */
2084 3 : CPLErr GDALDataset::CreateMaskBand( int nFlags )
2085 :
2086 : {
2087 3 : if( oOvManager.IsInitialized() )
2088 3 : return oOvManager.CreateMaskBand( nFlags, -1 );
2089 :
2090 : CPLError( CE_Failure, CPLE_NotSupported,
2091 0 : "CreateMaskBand() not supported for this dataset." );
2092 :
2093 0 : return( CE_Failure );
2094 : }
2095 :
2096 : /************************************************************************/
2097 : /* GDALCreateDatasetMaskBand() */
2098 : /************************************************************************/
2099 :
2100 : /**
2101 : * \brief Adds a mask band to the dataset
2102 : * @see GDALDataset::CreateMaskBand()
2103 : */
2104 7 : CPLErr CPL_STDCALL GDALCreateDatasetMaskBand( GDALDatasetH hDS, int nFlags )
2105 :
2106 : {
2107 7 : VALIDATE_POINTER1( hDS, "GDALCreateDatasetMaskBand", CE_Failure );
2108 :
2109 7 : return ((GDALDataset *) hDS)->CreateMaskBand( nFlags );
2110 : }
2111 :
2112 : /************************************************************************/
2113 : /* GDALOpen() */
2114 : /************************************************************************/
2115 :
2116 : /**
2117 : * \brief Open a raster file as a GDALDataset.
2118 : *
2119 : * This function will try to open the passed file, or virtual dataset
2120 : * name by invoking the Open method of each registered GDALDriver in turn.
2121 : * The first successful open will result in a returned dataset. If all
2122 : * drivers fail then NULL is returned.
2123 : *
2124 : * Several recommandations :
2125 : * <ul>
2126 : * <li>If you open a dataset object with GA_Update access, it is not recommanded
2127 : * to open a new dataset on the same underlying file.</li>
2128 : * <li>The returned dataset should only be accessed by one thread at a time. If you
2129 : * want to use it from different threads, you must add all necessary code (mutexes, etc.)
2130 : * to avoid concurrent use of the object. (Some drivers, such as GeoTIFF, maintain internal
2131 : * state variables that are updated each time a new block is read, thus preventing concurrent
2132 : * use.) </li>
2133 : * </ul>
2134 : *
2135 : * \sa GDALOpenShared()
2136 : *
2137 : * @param pszFilename the name of the file to access. In the case of
2138 : * exotic drivers this may not refer to a physical file, but instead contain
2139 : * information for the driver on how to access a dataset.
2140 : *
2141 : * @param eAccess the desired access, either GA_Update or GA_ReadOnly. Many
2142 : * drivers support only read only access.
2143 : *
2144 : * @return A GDALDatasetH handle or NULL on failure. For C++ applications
2145 : * this handle can be cast to a GDALDataset *.
2146 : */
2147 :
2148 : GDALDatasetH CPL_STDCALL
2149 7441 : GDALOpen( const char * pszFilename, GDALAccess eAccess )
2150 :
2151 : {
2152 7441 : VALIDATE_POINTER1( pszFilename, "GDALOpen", NULL );
2153 :
2154 : int iDriver;
2155 7441 : GDALDriverManager *poDM = GetGDALDriverManager();
2156 7441 : GDALOpenInfo oOpenInfo( pszFilename, eAccess );
2157 7441 : CPLLocaleC oLocaleForcer;
2158 :
2159 7441 : CPLErrorReset();
2160 7441 : CPLAssert( NULL != poDM );
2161 :
2162 223415 : for( iDriver = 0; iDriver < poDM->GetDriverCount(); iDriver++ )
2163 : {
2164 222361 : GDALDriver *poDriver = poDM->GetDriver( iDriver );
2165 : GDALDataset *poDS;
2166 :
2167 222361 : if ( poDriver->pfnOpen == NULL )
2168 0 : continue;
2169 :
2170 222361 : poDS = poDriver->pfnOpen( &oOpenInfo );
2171 222361 : if( poDS != NULL )
2172 : {
2173 6343 : if( strlen(poDS->GetDescription()) == 0 )
2174 478 : poDS->SetDescription( pszFilename );
2175 :
2176 6343 : if( poDS->poDriver == NULL )
2177 5548 : poDS->poDriver = poDriver;
2178 :
2179 :
2180 6343 : if( CPLGetPID() != GDALGetResponsiblePIDForCurrentThread() )
2181 : CPLDebug( "GDAL", "GDALOpen(%s, this=%p) succeeds as %s (pid=%d, responsiblePID=%d).",
2182 : pszFilename, poDS, poDriver->GetDescription(),
2183 0 : (int)CPLGetPID(), (int)GDALGetResponsiblePIDForCurrentThread() );
2184 : else
2185 : CPLDebug( "GDAL", "GDALOpen(%s, this=%p) succeeds as %s.",
2186 6343 : pszFilename, poDS, poDriver->GetDescription() );
2187 :
2188 13784 : return (GDALDatasetH) poDS;
2189 : }
2190 :
2191 216018 : if( CPLGetLastErrorNo() != 0 )
2192 44 : return NULL;
2193 : }
2194 :
2195 1054 : if( oOpenInfo.bStatOK )
2196 : CPLError( CE_Failure, CPLE_OpenFailed,
2197 : "`%s' not recognised as a supported file format.\n",
2198 71 : pszFilename );
2199 : else
2200 : CPLError( CE_Failure, CPLE_OpenFailed,
2201 : "`%s' does not exist in the file system,\n"
2202 : "and is not recognised as a supported dataset name.\n",
2203 983 : pszFilename );
2204 :
2205 1054 : return NULL;
2206 : }
2207 :
2208 : /************************************************************************/
2209 : /* GDALOpenShared() */
2210 : /************************************************************************/
2211 :
2212 : /**
2213 : * \brief Open a raster file as a GDALDataset.
2214 : *
2215 : * This function works the same as GDALOpen(), but allows the sharing of
2216 : * GDALDataset handles for a dataset with other callers to GDALOpenShared().
2217 : *
2218 : * In particular, GDALOpenShared() will first consult it's list of currently
2219 : * open and shared GDALDataset's, and if the GetDescription() name for one
2220 : * exactly matches the pszFilename passed to GDALOpenShared() it will be
2221 : * referenced and returned.
2222 : *
2223 : * Starting with GDAL 1.6.0, if GDALOpenShared() is called on the same pszFilename
2224 : * from two different threads, a different GDALDataset object will be returned as
2225 : * it is not safe to use the same dataset from different threads, unless the user
2226 : * does explicitely use mutexes in its code.
2227 : *
2228 : * \sa GDALOpen()
2229 : *
2230 : * @param pszFilename the name of the file to access. In the case of
2231 : * exotic drivers this may not refer to a physical file, but instead contain
2232 : * information for the driver on how to access a dataset.
2233 : *
2234 : * @param eAccess the desired access, either GA_Update or GA_ReadOnly. Many
2235 : * drivers support only read only access.
2236 : *
2237 : * @return A GDALDatasetH handle or NULL on failure. For C++ applications
2238 : * this handle can be cast to a GDALDataset *.
2239 : */
2240 :
2241 : GDALDatasetH CPL_STDCALL
2242 5223 : GDALOpenShared( const char *pszFilename, GDALAccess eAccess )
2243 :
2244 : {
2245 5223 : VALIDATE_POINTER1( pszFilename, "GDALOpenShared", NULL );
2246 :
2247 : /* -------------------------------------------------------------------- */
2248 : /* First scan the existing list to see if it could already */
2249 : /* contain the requested dataset. */
2250 : /* -------------------------------------------------------------------- */
2251 : {
2252 5223 : CPLMutexHolderD( &hDLMutex );
2253 :
2254 5223 : if (phSharedDatasetSet != NULL)
2255 : {
2256 5064 : GIntBig nThisPID = GDALGetResponsiblePIDForCurrentThread();
2257 : SharedDatasetCtxt* psStruct;
2258 : SharedDatasetCtxt sStruct;
2259 :
2260 5064 : sStruct.nPID = nThisPID;
2261 5064 : sStruct.pszDescription = (char*) pszFilename;
2262 5064 : sStruct.eAccess = eAccess;
2263 5064 : psStruct = (SharedDatasetCtxt*) CPLHashSetLookup(phSharedDatasetSet, &sStruct);
2264 5064 : if (psStruct == NULL && eAccess == GA_ReadOnly)
2265 : {
2266 14 : sStruct.eAccess = GA_Update;
2267 14 : psStruct = (SharedDatasetCtxt*) CPLHashSetLookup(phSharedDatasetSet, &sStruct);
2268 : }
2269 5064 : if (psStruct)
2270 : {
2271 5050 : psStruct->poDS->Reference();
2272 10100 : return psStruct->poDS;
2273 : }
2274 0 : }
2275 : }
2276 :
2277 : /* -------------------------------------------------------------------- */
2278 : /* Try opening the the requested dataset. */
2279 : /* -------------------------------------------------------------------- */
2280 : GDALDataset *poDataset;
2281 :
2282 173 : poDataset = (GDALDataset *) GDALOpen( pszFilename, eAccess );
2283 173 : if( poDataset != NULL )
2284 : {
2285 172 : if (strcmp(pszFilename, poDataset->GetDescription()) != 0)
2286 : {
2287 : CPLError(CE_Warning, CPLE_NotSupported,
2288 : "A dataset opened by GDALOpenShared should have the same filename (%s) "
2289 : "and description (%s)",
2290 2 : pszFilename, poDataset->GetDescription());
2291 : }
2292 : else
2293 : {
2294 170 : poDataset->MarkAsShared();
2295 : }
2296 : }
2297 :
2298 173 : return (GDALDatasetH) poDataset;
2299 : }
2300 :
2301 : /************************************************************************/
2302 : /* GDALClose() */
2303 : /************************************************************************/
2304 :
2305 : /**
2306 : * \brief Close GDAL dataset.
2307 : *
2308 : * For non-shared datasets (opened with GDALOpen()) the dataset is closed
2309 : * using the C++ "delete" operator, recovering all dataset related resources.
2310 : * For shared datasets (opened with GDALOpenShared()) the dataset is
2311 : * dereferenced, and closed only if the referenced count has dropped below 1.
2312 : *
2313 : * @param hDS The dataset to close. May be cast from a "GDALDataset *".
2314 : */
2315 :
2316 12600 : void CPL_STDCALL GDALClose( GDALDatasetH hDS )
2317 :
2318 : {
2319 12600 : VALIDATE_POINTER0( hDS, "GDALClose" );
2320 :
2321 12600 : GDALDataset *poDS = (GDALDataset *) hDS;
2322 12600 : CPLMutexHolderD( &hDLMutex );
2323 12600 : CPLLocaleC oLocaleForcer;
2324 :
2325 12600 : if (poDS->GetShared())
2326 : {
2327 : /* -------------------------------------------------------------------- */
2328 : /* If this file is in the shared dataset list then dereference */
2329 : /* it, and only delete/remote it if the reference count has */
2330 : /* dropped to zero. */
2331 : /* -------------------------------------------------------------------- */
2332 424 : if( poDS->Dereference() > 0 )
2333 424 : return;
2334 :
2335 313 : delete poDS;
2336 : return;
2337 : }
2338 :
2339 : /* -------------------------------------------------------------------- */
2340 : /* This is not shared dataset, so directly delete it. */
2341 : /* -------------------------------------------------------------------- */
2342 12176 : delete poDS;
2343 : }
2344 :
2345 : /************************************************************************/
2346 : /* GDALDumpOpenDataset() */
2347 : /************************************************************************/
2348 :
2349 0 : static int GDALDumpOpenSharedDatasetsForeach(void* elt, void* user_data)
2350 : {
2351 0 : SharedDatasetCtxt* psStruct = (SharedDatasetCtxt*) elt;
2352 0 : FILE *fp = (FILE*) user_data;
2353 : const char *pszDriverName;
2354 0 : GDALDataset *poDS = psStruct->poDS;
2355 :
2356 0 : if( poDS->GetDriver() == NULL )
2357 0 : pszDriverName = "DriverIsNULL";
2358 : else
2359 0 : pszDriverName = poDS->GetDriver()->GetDescription();
2360 :
2361 0 : poDS->Reference();
2362 : VSIFPrintf( fp, " %d %c %-6s %7d %dx%dx%d %s\n",
2363 : poDS->Dereference(),
2364 : poDS->GetShared() ? 'S' : 'N',
2365 : pszDriverName,
2366 : (int)psStruct->nPID,
2367 : poDS->GetRasterXSize(),
2368 : poDS->GetRasterYSize(),
2369 : poDS->GetRasterCount(),
2370 0 : poDS->GetDescription() );
2371 :
2372 0 : return TRUE;
2373 : }
2374 :
2375 :
2376 0 : static int GDALDumpOpenDatasetsForeach(void* elt, void* user_data)
2377 : {
2378 0 : DatasetCtxt* psStruct = (DatasetCtxt*) elt;
2379 0 : FILE *fp = (FILE*) user_data;
2380 : const char *pszDriverName;
2381 0 : GDALDataset *poDS = psStruct->poDS;
2382 :
2383 : /* Don't list shared datasets. They have already been listed by */
2384 : /* GDALDumpOpenSharedDatasetsForeach */
2385 0 : if (poDS->GetShared())
2386 0 : return TRUE;
2387 :
2388 0 : if( poDS->GetDriver() == NULL )
2389 0 : pszDriverName = "DriverIsNULL";
2390 : else
2391 0 : pszDriverName = poDS->GetDriver()->GetDescription();
2392 :
2393 0 : poDS->Reference();
2394 : VSIFPrintf( fp, " %d %c %-6s %7d %dx%dx%d %s\n",
2395 : poDS->Dereference(),
2396 : poDS->GetShared() ? 'S' : 'N',
2397 : pszDriverName,
2398 : -1,
2399 : poDS->GetRasterXSize(),
2400 : poDS->GetRasterYSize(),
2401 : poDS->GetRasterCount(),
2402 0 : poDS->GetDescription() );
2403 :
2404 0 : return TRUE;
2405 : }
2406 :
2407 : /**
2408 : * \brief List open datasets.
2409 : *
2410 : * Dumps a list of all open datasets (shared or not) to the indicated
2411 : * text file (may be stdout or stderr). This function is primariliy intended
2412 : * to assist in debugging "dataset leaks" and reference counting issues.
2413 : * The information reported includes the dataset name, referenced count,
2414 : * shared status, driver name, size, and band count.
2415 : */
2416 :
2417 346 : int CPL_STDCALL GDALDumpOpenDatasets( FILE *fp )
2418 :
2419 : {
2420 346 : VALIDATE_POINTER1( fp, "GDALDumpOpenDatasets", 0 );
2421 :
2422 346 : CPLMutexHolderD( &hDLMutex );
2423 :
2424 346 : if (phAllDatasetSet != NULL)
2425 : {
2426 0 : VSIFPrintf( fp, "Open GDAL Datasets:\n" );
2427 0 : CPLHashSetForeach(phAllDatasetSet, GDALDumpOpenDatasetsForeach, fp);
2428 0 : if (phSharedDatasetSet != NULL)
2429 : {
2430 0 : CPLHashSetForeach(phSharedDatasetSet, GDALDumpOpenSharedDatasetsForeach, fp);
2431 : }
2432 346 : return CPLHashSetSize(phAllDatasetSet);
2433 : }
2434 : else
2435 : {
2436 346 : return 0;
2437 0 : }
2438 : }
2439 :
2440 : /************************************************************************/
2441 : /* BeginAsyncReader() */
2442 : /************************************************************************/
2443 :
2444 : /**
2445 : * \brief Sets up an asynchronous data request
2446 : *
2447 : * This method establish an asynchronous raster read request for the
2448 : * indicated window on the dataset into the indicated buffer. The parameters
2449 : * for windowing, buffer size, buffer type and buffer organization are similar
2450 : * to those for GDALDataset::RasterIO(); however, this call only launches
2451 : * the request and filling the buffer is accomplished via calls to
2452 : * GetNextUpdatedRegion() on the return GDALAsyncReader session object.
2453 : *
2454 : * Once all processing for the created session is complete, or if no further
2455 : * refinement of the request is required, the GDALAsyncReader object should
2456 : * be destroyed with the GDALDataset::EndAsyncReader() method.
2457 : *
2458 : * Note that the data buffer (pData) will potentially continue to be
2459 : * updated as long as the session lives, but it is not deallocated when
2460 : * the session (GDALAsyncReader) is destroyed with EndAsyncReader(). It
2461 : * should be deallocated by the application at that point.
2462 : *
2463 : * Additional information on asynchronous IO in GDAL may be found at:
2464 : * http://trac.osgeo.org/gdal/wiki/rfc24_progressive_data_support
2465 : *
2466 : * This method is the same as the C GDALBeginAsyncReader() function.
2467 : *
2468 : * @param nXOff The pixel offset to the top left corner of the region
2469 : * of the band to be accessed. This would be zero to start from the left side.
2470 : *
2471 : * @param nYOff The line offset to the top left corner of the region
2472 : * of the band to be accessed. This would be zero to start from the top.
2473 : *
2474 : * @param nXSize The width of the region of the band to be accessed in pixels.
2475 : *
2476 : * @param nYSize The height of the region of the band to be accessed in lines.
2477 : *
2478 : * @param pBuf The buffer into which the data should be read. This buffer must
2479 : * contain at least nBufXSize * nBufYSize * nBandCount words of type eBufType.
2480 : * It is organized in left to right,top to bottom pixel order. Spacing is
2481 : * controlled by the nPixelSpace, and nLineSpace parameters.
2482 : *
2483 : * @param nBufXSize the width of the buffer image into which the desired region
2484 : * is to be read, or from which it is to be written.
2485 : *
2486 : * @param nBufYSize the height of the buffer image into which the desired
2487 : * region is to be read, or from which it is to be written.
2488 : *
2489 : * @param eBufType the type of the pixel values in the pData data buffer. The
2490 : * pixel values will automatically be translated to/from the GDALRasterBand
2491 : * data type as needed.
2492 : *
2493 : * @param nBandCount the number of bands being read or written.
2494 : *
2495 : * @param panBandMap the list of nBandCount band numbers being read/written.
2496 : * Note band numbers are 1 based. This may be NULL to select the first
2497 : * nBandCount bands.
2498 : *
2499 : * @param nPixelSpace The byte offset from the start of one pixel value in
2500 : * pData to the start of the next pixel value within a scanline. If defaulted
2501 : * (0) the size of the datatype eBufType is used.
2502 : *
2503 : * @param nLineSpace The byte offset from the start of one scanline in
2504 : * pData to the start of the next. If defaulted the size of the datatype
2505 : * eBufType * nBufXSize is used.
2506 : *
2507 : * @param nBandSpace the byte offset from the start of one bands data to the
2508 : * start of the next. If defaulted (zero) the value will be
2509 : * nLineSpace * nBufYSize implying band sequential organization
2510 : * of the data buffer.
2511 : *
2512 : * @param papszOptions Driver specific control options in a string list or NULL.
2513 : * Consult driver documentation for options supported.
2514 : *
2515 : * @return The GDALAsyncReader object representing the request.
2516 : */
2517 :
2518 : GDALAsyncReader*
2519 : GDALDataset::BeginAsyncReader(int nXOff, int nYOff,
2520 : int nXSize, int nYSize,
2521 : void *pBuf,
2522 : int nBufXSize, int nBufYSize,
2523 : GDALDataType eBufType,
2524 : int nBandCount, int* panBandMap,
2525 : int nPixelSpace, int nLineSpace,
2526 1 : int nBandSpace, char **papszOptions)
2527 : {
2528 : // See gdaldefaultasync.cpp
2529 :
2530 : return
2531 : GDALGetDefaultAsyncReader( this,
2532 : nXOff, nYOff, nXSize, nYSize,
2533 : pBuf, nBufXSize, nBufYSize, eBufType,
2534 : nBandCount, panBandMap,
2535 : nPixelSpace, nLineSpace, nBandSpace,
2536 1 : papszOptions );
2537 : }
2538 :
2539 : /************************************************************************/
2540 : /* GDALBeginAsyncReader() */
2541 : /************************************************************************/
2542 :
2543 : GDALAsyncReaderH CPL_STDCALL
2544 : GDALBeginAsyncReader(GDALDatasetH hDS, int xOff, int yOff,
2545 : int xSize, int ySize,
2546 : void *pBuf,
2547 : int bufXSize, int bufYSize,
2548 : GDALDataType bufType,
2549 : int nBandCount, int* bandMap,
2550 : int nPixelSpace, int nLineSpace,
2551 : int nBandSpace,
2552 1 : char **papszOptions)
2553 :
2554 : {
2555 1 : VALIDATE_POINTER1( hDS, "GDALDataset", NULL );
2556 : return (GDALAsyncReaderH)((GDALDataset *) hDS)->
2557 : BeginAsyncReader(xOff, yOff,
2558 : xSize, ySize,
2559 : pBuf, bufXSize, bufYSize,
2560 : bufType, nBandCount, bandMap,
2561 : nPixelSpace, nLineSpace,
2562 1 : nBandSpace, papszOptions);
2563 : }
2564 :
2565 : /************************************************************************/
2566 : /* EndAsyncReader() */
2567 : /************************************************************************/
2568 :
2569 : /**
2570 : * End asynchronous request.
2571 : *
2572 : * This method destroys an asynchronous io request and recovers all
2573 : * resources associated with it.
2574 : *
2575 : * This method is the same as the C function GDALEndAsyncReader().
2576 : *
2577 : * @param poARIO pointer to a GDALAsyncReader
2578 : */
2579 :
2580 1 : void GDALDataset::EndAsyncReader(GDALAsyncReader *poARIO )
2581 : {
2582 1 : delete poARIO;
2583 1 : }
2584 :
2585 : /************************************************************************/
2586 : /* GDALEndAsyncReader() */
2587 : /************************************************************************/
2588 1 : void CPL_STDCALL GDALEndAsyncReader(GDALDatasetH hDS, GDALAsyncReaderH hAsyncReaderH)
2589 : {
2590 1 : VALIDATE_POINTER0( hDS, "GDALDataset" );
2591 1 : VALIDATE_POINTER0( hAsyncReaderH, "GDALAsyncReader" );
2592 1 : ((GDALDataset *) hDS) -> EndAsyncReader((GDALAsyncReader *)hAsyncReaderH);
2593 : }
2594 :
|