1 : /******************************************************************************
2 : * $Id: gdaldataset.cpp 23156 2011-10-01 15:34:16Z rouault $
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 23156 2011-10-01 15:34:16Z rouault $");
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 6600 : static unsigned long GDALSharedDatasetHashFunc(const void* elt)
87 : {
88 6600 : SharedDatasetCtxt* psStruct = (SharedDatasetCtxt*) elt;
89 6600 : return (unsigned long) (CPLHashSetHashStr(psStruct->pszDescription) ^ psStruct->eAccess ^ psStruct->nPID);
90 : }
91 :
92 5577 : static int GDALSharedDatasetEqualFunc(const void* elt1, const void* elt2)
93 : {
94 5577 : SharedDatasetCtxt* psStruct1 = (SharedDatasetCtxt*) elt1;
95 5577 : SharedDatasetCtxt* psStruct2 = (SharedDatasetCtxt*) elt2;
96 : return strcmp(psStruct1->pszDescription, psStruct2->pszDescription) == 0 &&
97 : psStruct1->nPID == psStruct2->nPID &&
98 5577 : psStruct1->eAccess == psStruct2->eAccess;
99 : }
100 :
101 262 : static void GDALSharedDatasetFreeFunc(void* elt)
102 : {
103 262 : SharedDatasetCtxt* psStruct = (SharedDatasetCtxt*) elt;
104 262 : CPLFree(psStruct->pszDescription);
105 262 : CPLFree(psStruct);
106 262 : }
107 :
108 80201 : static unsigned long GDALDatasetHashFunc(const void* elt)
109 : {
110 80201 : DatasetCtxt* psStruct = (DatasetCtxt*) elt;
111 80201 : return (unsigned long)(GUIntBig) psStruct->poDS;
112 : }
113 :
114 35646 : static int GDALDatasetEqualFunc(const void* elt1, const void* elt2)
115 : {
116 35646 : DatasetCtxt* psStruct1 = (DatasetCtxt*) elt1;
117 35646 : DatasetCtxt* psStruct2 = (DatasetCtxt*) elt2;
118 35646 : return psStruct1->poDS == psStruct2->poDS ;
119 : }
120 :
121 15163 : static void GDALDatasetFreeFunc(void* elt)
122 : {
123 15163 : DatasetCtxt* psStruct = (DatasetCtxt*) elt;
124 15163 : CPLFree(psStruct);
125 15163 : }
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 23692 : void** GDALGetphDLMutex()
137 : {
138 23692 : return &hDLMutex;
139 : }
140 :
141 : /* The current thread will act in the behalf of the thread of PID responsiblePID */
142 22296 : void GDALSetResponsiblePIDForCurrentThread(GIntBig responsiblePID)
143 : {
144 22296 : GIntBig* pResponsiblePID = (GIntBig*) CPLGetTLS(CTLS_RESPONSIBLEPID);
145 22296 : if (pResponsiblePID == NULL)
146 : {
147 87 : pResponsiblePID = (GIntBig*) CPLMalloc(sizeof(GIntBig));
148 87 : CPLSetTLS(CTLS_RESPONSIBLEPID, pResponsiblePID, TRUE);
149 : }
150 22296 : *pResponsiblePID = responsiblePID;
151 22296 : }
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 49915 : GIntBig GDALGetResponsiblePIDForCurrentThread()
156 : {
157 49915 : GIntBig* pResponsiblePID = (GIntBig*) CPLGetTLS(CTLS_RESPONSIBLEPID);
158 49915 : if (pResponsiblePID == NULL)
159 2158 : return CPLGetPID();
160 47757 : 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 15163 : GDALDataset::GDALDataset()
187 :
188 : {
189 15163 : poDriver = NULL;
190 15163 : eAccess = GA_ReadOnly;
191 15163 : nRasterXSize = 512;
192 15163 : nRasterYSize = 512;
193 15163 : nBands = 0;
194 15163 : papoBands = NULL;
195 15163 : nRefCount = 1;
196 15163 : bShared = FALSE;
197 :
198 : /* -------------------------------------------------------------------- */
199 : /* Add this dataset to the open dataset list. */
200 : /* -------------------------------------------------------------------- */
201 : {
202 15163 : CPLMutexHolderD( &hDLMutex );
203 :
204 15163 : if (phAllDatasetSet == NULL)
205 594 : phAllDatasetSet = CPLHashSetNew(GDALDatasetHashFunc, GDALDatasetEqualFunc, GDALDatasetFreeFunc);
206 15163 : DatasetCtxt* ctxt = (DatasetCtxt*)CPLMalloc(sizeof(DatasetCtxt));
207 15163 : ctxt->poDS = this;
208 15163 : ctxt->nPIDCreatorForShared = -1;
209 15163 : CPLHashSetInsert(phAllDatasetSet, ctxt);
210 : }
211 :
212 : /* -------------------------------------------------------------------- */
213 : /* Set forced caching flag. */
214 : /* -------------------------------------------------------------------- */
215 : bForceCachedIO = CSLTestBoolean(
216 15163 : CPLGetConfigOption( "GDAL_FORCE_CACHING", "NO") );
217 15163 : }
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 15163 : 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 15163 : if( nBands != 0 || !EQUAL(GetDescription(),"") )
247 : {
248 14778 : 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 14778 : "GDALClose(%s, this=%p)", GetDescription(), this );
256 : }
257 :
258 : /* -------------------------------------------------------------------- */
259 : /* Remove dataset from the "open" dataset list. */
260 : /* -------------------------------------------------------------------- */
261 : {
262 15163 : CPLMutexHolderD( &hDLMutex );
263 :
264 : DatasetCtxt sStruct;
265 15163 : sStruct.poDS = this;
266 15163 : DatasetCtxt* psStruct = (DatasetCtxt*) CPLHashSetLookup(phAllDatasetSet, &sStruct);
267 15163 : GIntBig nPIDCreatorForShared = psStruct->nPIDCreatorForShared;
268 15163 : CPLHashSetRemove(phAllDatasetSet, psStruct);
269 :
270 15163 : if (bShared && phSharedDatasetSet != NULL)
271 : {
272 : SharedDatasetCtxt* psStruct;
273 : SharedDatasetCtxt sStruct;
274 262 : sStruct.nPID = nPIDCreatorForShared;
275 262 : sStruct.eAccess = eAccess;
276 262 : sStruct.pszDescription = (char*) GetDescription();
277 262 : psStruct = (SharedDatasetCtxt*) CPLHashSetLookup(phSharedDatasetSet, &sStruct);
278 524 : if (psStruct && psStruct->poDS == this)
279 : {
280 262 : CPLHashSetRemove(phSharedDatasetSet, psStruct);
281 : }
282 : else
283 : {
284 0 : CPLDebug("GDAL", "Should not happen. Cannot find %s, this=%p in phSharedDatasetSet", GetDescription(), this);
285 : }
286 : }
287 :
288 15163 : if (CPLHashSetSize(phAllDatasetSet) == 0)
289 : {
290 594 : CPLHashSetDestroy(phAllDatasetSet);
291 594 : phAllDatasetSet = NULL;
292 594 : if (phSharedDatasetSet)
293 : {
294 143 : CPLHashSetDestroy(phSharedDatasetSet);
295 : }
296 594 : phSharedDatasetSet = NULL;
297 594 : CPLFree(ppDatasets);
298 594 : ppDatasets = NULL;
299 15163 : }
300 : }
301 :
302 : /* -------------------------------------------------------------------- */
303 : /* Destroy the raster bands if they exist. */
304 : /* -------------------------------------------------------------------- */
305 425599 : for( i = 0; i < nBands && papoBands != NULL; i++ )
306 : {
307 410436 : if( papoBands[i] != NULL )
308 410436 : delete papoBands[i];
309 : }
310 :
311 15163 : CPLFree( papoBands );
312 15163 : }
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 20673 : void GDALDataset::FlushCache()
332 :
333 : {
334 : int i;
335 :
336 : // This sometimes happens if a dataset is destroyed before completely
337 : // built.
338 :
339 20673 : if( papoBands == NULL )
340 409 : return;
341 :
342 1042335 : for( i = 0; i < nBands; i++ )
343 : {
344 1022071 : if( papoBands[i] != NULL )
345 1022071 : 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 331 : void CPL_STDCALL GDALFlushCache( GDALDatasetH hDS )
360 :
361 : {
362 331 : VALIDATE_POINTER0( hDS, "GDALFlushCache" );
363 :
364 331 : ((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 29 : void GDALDataset::BlockBasedFlushCache()
379 :
380 : {
381 : GDALRasterBand *poBand1;
382 : int nBlockXSize, nBlockYSize, iBand;
383 :
384 29 : poBand1 = GetRasterBand( 1 );
385 29 : if( poBand1 == NULL )
386 : {
387 1 : GDALDataset::FlushCache();
388 1 : return;
389 : }
390 :
391 28 : poBand1->GetBlockSize( &nBlockXSize, &nBlockYSize );
392 :
393 : /* -------------------------------------------------------------------- */
394 : /* Verify that all bands match. */
395 : /* -------------------------------------------------------------------- */
396 62 : for( iBand = 1; iBand < nBands; iBand++ )
397 : {
398 : int nThisBlockXSize, nThisBlockYSize;
399 34 : GDALRasterBand *poBand = GetRasterBand( iBand+1 );
400 :
401 34 : poBand->GetBlockSize( &nThisBlockXSize, &nThisBlockYSize );
402 34 : if( nThisBlockXSize != nBlockXSize && nThisBlockYSize != nBlockYSize )
403 : {
404 0 : GDALDataset::FlushCache();
405 0 : return;
406 : }
407 : }
408 :
409 : /* -------------------------------------------------------------------- */
410 : /* Now flush writable data. */
411 : /* -------------------------------------------------------------------- */
412 328 : for( int iY = 0; iY < poBand1->nBlocksPerColumn; iY++ )
413 : {
414 600 : for( int iX = 0; iX < poBand1->nBlocksPerRow; iX++ )
415 : {
416 1000 : for( iBand = 0; iBand < nBands; iBand++ )
417 : {
418 700 : GDALRasterBand *poBand = GetRasterBand( iBand+1 );
419 :
420 700 : if( poBand->papoBlocks[iX + iY*poBand1->nBlocksPerRow] != NULL)
421 : {
422 : CPLErr eErr;
423 :
424 400 : eErr = poBand->FlushBlock( iX, iY );
425 :
426 400 : 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()) 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 : ReportError( 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 67 : CPLErr CPL_STDCALL GDALAddBand( GDALDatasetH hDataset,
495 : GDALDataType eType, char **papszOptions )
496 :
497 : {
498 67 : VALIDATE_POINTER1( hDataset, "GDALAddBand", CE_Failure );
499 :
500 67 : 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 621776 : void GDALDataset::SetBand( int nNewBand, GDALRasterBand * poBand )
511 :
512 : {
513 : /* -------------------------------------------------------------------- */
514 : /* Do we need to grow the bands list? */
515 : /* -------------------------------------------------------------------- */
516 621776 : if( nBands < nNewBand || papoBands == NULL ) {
517 : int i;
518 : GDALRasterBand** papoNewBands;
519 :
520 357351 : if( papoBands == NULL )
521 : papoNewBands = (GDALRasterBand **)
522 14714 : VSICalloc(sizeof(GDALRasterBand*), MAX(nNewBand,nBands));
523 : else
524 : papoNewBands = (GDALRasterBand **)
525 : VSIRealloc(papoBands, sizeof(GDALRasterBand*) *
526 342637 : MAX(nNewBand,nBands));
527 357351 : if (papoNewBands == NULL)
528 : {
529 : ReportError(CE_Failure, CPLE_OutOfMemory,
530 0 : "Cannot allocate band array");
531 0 : return;
532 : }
533 357351 : papoBands = papoNewBands;
534 :
535 708852 : for( i = nBands; i < nNewBand; i++ )
536 351501 : papoBands[i] = NULL;
537 :
538 357351 : nBands = MAX(nBands,nNewBand);
539 : }
540 :
541 : /* -------------------------------------------------------------------- */
542 : /* Set the band. Resetting the band is currently not permitted. */
543 : /* -------------------------------------------------------------------- */
544 621776 : if( papoBands[nNewBand-1] != NULL )
545 : {
546 : ReportError(CE_Failure, CPLE_NotSupported,
547 0 : "Cannot set band %d as it is already set", nNewBand);
548 0 : return;
549 : }
550 :
551 621776 : 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 621776 : poBand->nBand = nNewBand;
559 621776 : poBand->poDS = this;
560 621776 : poBand->nRasterXSize = nRasterXSize;
561 621776 : poBand->nRasterYSize = nRasterYSize;
562 621776 : 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 385839 : int GDALDataset::GetRasterXSize()
580 :
581 : {
582 385839 : 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 5253 : int CPL_STDCALL GDALGetRasterXSize( GDALDatasetH hDataset )
596 :
597 : {
598 5253 : VALIDATE_POINTER1( hDataset, "GDALGetRasterXSize", 0 );
599 :
600 5253 : 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 134276 : int GDALDataset::GetRasterYSize()
619 :
620 : {
621 134276 : 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 13560 : int CPL_STDCALL GDALGetRasterYSize( GDALDatasetH hDataset )
635 :
636 : {
637 13560 : VALIDATE_POINTER1( hDataset, "GDALGetRasterYSize", 0 );
638 :
639 13560 : 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 2242807 : GDALRasterBand * GDALDataset::GetRasterBand( int nBandId )
660 :
661 : {
662 2242807 : if ( papoBands )
663 : {
664 2242806 : if( nBandId < 1 || nBandId > nBands )
665 : {
666 : ReportError( CE_Failure, CPLE_IllegalArg,
667 : "GDALDataset::GetRasterBand(%d) - Illegal band #\n",
668 0 : nBandId );
669 0 : return NULL;
670 : }
671 : else
672 2242806 : return( papoBands[nBandId-1] );
673 : }
674 1 : 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 179026 : GDALRasterBandH CPL_STDCALL GDALGetRasterBand( GDALDatasetH hDS, int nBandId )
687 :
688 : {
689 179026 : VALIDATE_POINTER1( hDS, "GDALGetRasterBand", NULL );
690 :
691 179026 : 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 1728679 : int GDALDataset::GetRasterCount()
707 :
708 : {
709 1728679 : 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 338420 : int CPL_STDCALL GDALGetRasterCount( GDALDatasetH hDS )
723 :
724 : {
725 338420 : VALIDATE_POINTER1( hDS, "GDALGetRasterCount", 0 );
726 :
727 338420 : 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 4194 : const char *GDALDataset::GetProjectionRef()
753 :
754 : {
755 4194 : 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 1784 : const char * CPL_STDCALL GDALGetProjectionRef( GDALDatasetH hDS )
769 :
770 : {
771 1784 : VALIDATE_POINTER1( hDS, "GDALGetProjectionRef", NULL );
772 :
773 1784 : 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 2 : CPLErr GDALDataset::SetProjection( const char * pszProjection )
796 :
797 : {
798 2 : if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
799 : ReportError( CE_Failure, CPLE_NotSupported,
800 0 : "Dataset does not support the SetProjection() method." );
801 2 : 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 1225 : CPLErr CPL_STDCALL GDALSetProjection( GDALDatasetH hDS, const char * pszProjection )
815 :
816 : {
817 1225 : VALIDATE_POINTER1( hDS, "GDALSetProjection", CE_Failure );
818 :
819 1225 : 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 3868 : CPLErr GDALDataset::GetGeoTransform( double * padfTransform )
859 :
860 : {
861 3868 : CPLAssert( padfTransform != NULL );
862 :
863 3868 : padfTransform[0] = 0.0; /* X Origin (top left corner) */
864 3868 : padfTransform[1] = 1.0; /* X Pixel size */
865 3868 : padfTransform[2] = 0.0;
866 :
867 3868 : padfTransform[3] = 0.0; /* Y Origin (top left corner) */
868 3868 : padfTransform[4] = 0.0;
869 3868 : padfTransform[5] = 1.0; /* Y Pixel Size */
870 :
871 3868 : 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 1659 : CPLErr CPL_STDCALL GDALGetGeoTransform( GDALDatasetH hDS, double * padfTransform )
885 :
886 : {
887 1659 : VALIDATE_POINTER1( hDS, "GDALGetGeoTransform", CE_Failure );
888 :
889 1659 : 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 2 : CPLErr GDALDataset::SetGeoTransform( double * padfTransform )
912 :
913 : {
914 2 : if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
915 : ReportError( CE_Failure, CPLE_NotSupported,
916 0 : "SetGeoTransform() not supported for this dataset." );
917 :
918 2 : 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 1208 : GDALSetGeoTransform( GDALDatasetH hDS, double * padfTransform )
933 :
934 : {
935 1208 : VALIDATE_POINTER1( hDS, "GDALSetGeoTransform", CE_Failure );
936 :
937 1208 : 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 779 : GDALDriver * GDALDataset::GetDriver()
994 :
995 : {
996 779 : 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 554 : GDALDriverH CPL_STDCALL GDALGetDatasetDriver( GDALDatasetH hDataset )
1010 :
1011 : {
1012 554 : VALIDATE_POINTER1( hDataset, "GDALGetDatasetDriver", NULL );
1013 :
1014 554 : 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 5408 : int GDALDataset::Reference()
1032 :
1033 : {
1034 5408 : 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 62 : int CPL_STDCALL GDALReferenceDataset( GDALDatasetH hDataset )
1048 :
1049 : {
1050 62 : VALIDATE_POINTER1( hDataset, "GDALReferenceDataset", 0 );
1051 :
1052 62 : 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 16729 : int GDALDataset::Dereference()
1071 :
1072 : {
1073 16729 : 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 15882 : int CPL_STDCALL GDALDereferenceDataset( GDALDatasetH hDataset )
1087 :
1088 : {
1089 15882 : VALIDATE_POINTER1( hDataset, "GDALDereferenceDataset", 0 );
1090 :
1091 15882 : 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 14809 : int GDALDataset::GetShared()
1105 :
1106 : {
1107 14809 : return bShared;
1108 : }
1109 :
1110 : /************************************************************************/
1111 : /* MarkAsShared() */
1112 : /************************************************************************/
1113 :
1114 : /**
1115 : * \brief Mark this dataset as available for sharing.
1116 : */
1117 :
1118 262 : void GDALDataset::MarkAsShared()
1119 :
1120 : {
1121 262 : CPLAssert( !bShared );
1122 :
1123 262 : bShared = TRUE;
1124 :
1125 262 : GIntBig nPID = GDALGetResponsiblePIDForCurrentThread();
1126 : SharedDatasetCtxt* psStruct;
1127 :
1128 : /* Insert the dataset in the set of shared opened datasets */
1129 262 : CPLMutexHolderD( &hDLMutex );
1130 262 : if (phSharedDatasetSet == NULL)
1131 143 : phSharedDatasetSet = CPLHashSetNew(GDALSharedDatasetHashFunc, GDALSharedDatasetEqualFunc, GDALSharedDatasetFreeFunc);
1132 :
1133 262 : psStruct = (SharedDatasetCtxt*)CPLMalloc(sizeof(SharedDatasetCtxt));
1134 262 : psStruct->poDS = this;
1135 262 : psStruct->nPID = nPID;
1136 262 : psStruct->eAccess = eAccess;
1137 262 : psStruct->pszDescription = CPLStrdup(GetDescription());
1138 262 : if(CPLHashSetLookup(phSharedDatasetSet, psStruct) != NULL)
1139 : {
1140 0 : CPLFree(psStruct);
1141 : ReportError(CE_Failure, CPLE_AppDefined,
1142 0 : "An existing shared dataset has already this description. This should not happen");
1143 : }
1144 : else
1145 : {
1146 262 : CPLHashSetInsert(phSharedDatasetSet, psStruct);
1147 :
1148 : DatasetCtxt sStruct;
1149 262 : sStruct.poDS = this;
1150 262 : DatasetCtxt* psStruct = (DatasetCtxt*) CPLHashSetLookup(phAllDatasetSet, &sStruct);
1151 262 : psStruct->nPIDCreatorForShared = nPID;
1152 262 : }
1153 262 : }
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 3763 : int GDALDataset::GetGCPCount()
1168 :
1169 : {
1170 3763 : return 0;
1171 : }
1172 :
1173 : /************************************************************************/
1174 : /* GDALGetGCPCount() */
1175 : /************************************************************************/
1176 :
1177 : /**
1178 : * \brief Get number of GCPs.
1179 : *
1180 : * @see GDALDataset::GetGCPCount()
1181 : */
1182 :
1183 186 : int CPL_STDCALL GDALGetGCPCount( GDALDatasetH hDS )
1184 :
1185 : {
1186 186 : VALIDATE_POINTER1( hDS, "GDALGetGCPCount", 0 );
1187 :
1188 186 : 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 86 : const char * CPL_STDCALL GDALGetGCPProjection( GDALDatasetH hDS )
1223 :
1224 : {
1225 86 : VALIDATE_POINTER1( hDS, "GDALGetGCPProjection", NULL );
1226 :
1227 86 : 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 1 : const GDAL_GCP *GDALDataset::GetGCPs()
1244 :
1245 : {
1246 1 : return NULL;
1247 : }
1248 :
1249 : /************************************************************************/
1250 : /* GDALGetGCPs() */
1251 : /************************************************************************/
1252 :
1253 : /**
1254 : * \brief Fetch GCPs.
1255 : *
1256 : * @see GDALDataset::GetGCPs()
1257 : */
1258 :
1259 56 : const GDAL_GCP * CPL_STDCALL GDALGetGCPs( GDALDatasetH hDS )
1260 :
1261 : {
1262 56 : VALIDATE_POINTER1( hDS, "GDALGetGCPs", NULL );
1263 :
1264 56 : 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 0 : CPLErr GDALDataset::SetGCPs( int nGCPCount,
1298 : const GDAL_GCP *pasGCPList,
1299 : const char * pszGCPProjection )
1300 :
1301 : {
1302 : (void) nGCPCount;
1303 : (void) pasGCPList;
1304 : (void) pszGCPProjection;
1305 :
1306 0 : if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
1307 : ReportError( 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 2 : CPLErr CPL_STDCALL GDALSetGCPs( GDALDatasetH hDS, int nGCPCount,
1324 : const GDAL_GCP *pasGCPList,
1325 : 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 nListBands 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 175 : CPLErr GDALDataset::BuildOverviews( const char *pszResampling,
1372 : int nOverviews, int *panOverviewList,
1373 : int nListBands, int *panBandList,
1374 : GDALProgressFunc pfnProgress,
1375 : void * pProgressData )
1376 :
1377 : {
1378 : CPLErr eErr;
1379 175 : int *panAllBandList = NULL;
1380 :
1381 175 : if( nListBands == 0 )
1382 : {
1383 173 : nListBands = GetRasterCount();
1384 173 : panAllBandList = (int *) CPLMalloc(sizeof(int) * nListBands);
1385 440 : for( int i = 0; i < nListBands; i++ )
1386 267 : panAllBandList[i] = i+1;
1387 :
1388 173 : panBandList = panAllBandList;
1389 : }
1390 :
1391 175 : if( pfnProgress == NULL )
1392 167 : pfnProgress = GDALDummyProgress;
1393 :
1394 : eErr = IBuildOverviews( pszResampling, nOverviews, panOverviewList,
1395 175 : nListBands, panBandList, pfnProgress, pProgressData );
1396 :
1397 175 : if( panAllBandList != NULL )
1398 173 : CPLFree( panAllBandList );
1399 :
1400 175 : return eErr;
1401 : }
1402 :
1403 : /************************************************************************/
1404 : /* GDALBuildOverviews() */
1405 : /************************************************************************/
1406 :
1407 : /**
1408 : * \brief Build raster overview(s)
1409 : *
1410 : * @see GDALDataset::BuildOverviews()
1411 : */
1412 :
1413 171 : CPLErr CPL_STDCALL GDALBuildOverviews( GDALDatasetH hDataset,
1414 : const char *pszResampling,
1415 : int nOverviews, int *panOverviewList,
1416 : int nListBands, int *panBandList,
1417 : GDALProgressFunc pfnProgress,
1418 : void * pProgressData )
1419 :
1420 : {
1421 171 : VALIDATE_POINTER1( hDataset, "GDALBuildOverviews", CE_Failure );
1422 :
1423 : return ((GDALDataset *) hDataset)->BuildOverviews(
1424 : pszResampling, nOverviews, panOverviewList, nListBands, panBandList,
1425 171 : pfnProgress, pProgressData );
1426 : }
1427 :
1428 : /************************************************************************/
1429 : /* IBuildOverviews() */
1430 : /* */
1431 : /* Default implementation. */
1432 : /************************************************************************/
1433 :
1434 79 : CPLErr GDALDataset::IBuildOverviews( const char *pszResampling,
1435 : int nOverviews, int *panOverviewList,
1436 : int nListBands, int *panBandList,
1437 : GDALProgressFunc pfnProgress,
1438 : void * pProgressData )
1439 :
1440 : {
1441 79 : if( oOvManager.IsInitialized() )
1442 : return oOvManager.BuildOverviews( NULL, pszResampling,
1443 : nOverviews, panOverviewList,
1444 : nListBands, panBandList,
1445 79 : pfnProgress, pProgressData );
1446 : else
1447 : {
1448 : ReportError( 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 349619 : 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 : int nPixelSpace, int nLineSpace, int nBandSpace)
1469 :
1470 : {
1471 : int iBandIndex;
1472 349619 : CPLErr eErr = CE_None;
1473 349619 : const char* pszInterleave = NULL;
1474 :
1475 349619 : CPLAssert( NULL != pData );
1476 :
1477 368186 : if (nXSize == nBufXSize && nYSize == nBufYSize &&
1478 18567 : (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 1264 : nPixelSpace, nLineSpace, nBandSpace );
1485 : }
1486 :
1487 715721 : for( iBandIndex = 0;
1488 : iBandIndex < nBandCount && eErr == CE_None;
1489 : iBandIndex++ )
1490 : {
1491 367366 : GDALRasterBand *poBand = GetRasterBand(panBandMap[iBandIndex]);
1492 : GByte *pabyBandData;
1493 :
1494 367366 : if (poBand == NULL)
1495 : {
1496 0 : eErr = CE_Failure;
1497 0 : break;
1498 : }
1499 :
1500 367366 : pabyBandData = ((GByte *) pData) + iBandIndex * nBandSpace;
1501 :
1502 : eErr = poBand->IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
1503 : (void *) pabyBandData, nBufXSize, nBufYSize,
1504 367366 : eBufType, nPixelSpace, nLineSpace );
1505 : }
1506 :
1507 348355 : return eErr;
1508 : }
1509 :
1510 :
1511 : /************************************************************************/
1512 : /* RasterIO() */
1513 : /************************************************************************/
1514 :
1515 : /**
1516 : * \brief Read/write a region of image data from multiple bands.
1517 : *
1518 : * This method allows reading a region of one or more GDALRasterBands from
1519 : * this dataset into a buffer, or writing data from a buffer into a region
1520 : * of the GDALRasterBands. It automatically takes care of data type
1521 : * translation if the data type (eBufType) of the buffer is different than
1522 : * that of the GDALRasterBand.
1523 : * The method also takes care of image decimation / replication if the
1524 : * buffer size (nBufXSize x nBufYSize) is different than the size of the
1525 : * region being accessed (nXSize x nYSize).
1526 : *
1527 : * The nPixelSpace, nLineSpace and nBandSpace parameters allow reading into or
1528 : * writing from various organization of buffers.
1529 : *
1530 : * For highest performance full resolution data access, read and write
1531 : * on "block boundaries" as returned by GetBlockSize(), or use the
1532 : * ReadBlock() and WriteBlock() methods.
1533 : *
1534 : * This method is the same as the C GDALDatasetRasterIO() function.
1535 : *
1536 : * @param eRWFlag Either GF_Read to read a region of data, or GF_Write to
1537 : * write a region of data.
1538 : *
1539 : * @param nXOff The pixel offset to the top left corner of the region
1540 : * of the band to be accessed. This would be zero to start from the left side.
1541 : *
1542 : * @param nYOff The line offset to the top left corner of the region
1543 : * of the band to be accessed. This would be zero to start from the top.
1544 : *
1545 : * @param nXSize The width of the region of the band to be accessed in pixels.
1546 : *
1547 : * @param nYSize The height of the region of the band to be accessed in lines.
1548 : *
1549 : * @param pData The buffer into which the data should be read, or from which
1550 : * it should be written. This buffer must contain at least
1551 : * nBufXSize * nBufYSize * nBandCount words of type eBufType. It is organized
1552 : * in left to right,top to bottom pixel order. Spacing is controlled by the
1553 : * nPixelSpace, and nLineSpace parameters.
1554 : *
1555 : * @param nBufXSize the width of the buffer image into which the desired region
1556 : * is to be read, or from which it is to be written.
1557 : *
1558 : * @param nBufYSize the height of the buffer image into which the desired
1559 : * region is to be read, or from which it is to be written.
1560 : *
1561 : * @param eBufType the type of the pixel values in the pData data buffer. The
1562 : * pixel values will automatically be translated to/from the GDALRasterBand
1563 : * data type as needed.
1564 : *
1565 : * @param nBandCount the number of bands being read or written.
1566 : *
1567 : * @param panBandMap the list of nBandCount band numbers being read/written.
1568 : * Note band numbers are 1 based. This may be NULL to select the first
1569 : * nBandCount bands.
1570 : *
1571 : * @param nPixelSpace The byte offset from the start of one pixel value in
1572 : * pData to the start of the next pixel value within a scanline. If defaulted
1573 : * (0) the size of the datatype eBufType is used.
1574 : *
1575 : * @param nLineSpace The byte offset from the start of one scanline in
1576 : * pData to the start of the next. If defaulted (0) the size of the datatype
1577 : * eBufType * nBufXSize is used.
1578 : *
1579 : * @param nBandSpace the byte offset from the start of one bands data to the
1580 : * start of the next. If defaulted (0) the value will be
1581 : * nLineSpace * nBufYSize implying band sequential organization
1582 : * of the data buffer.
1583 : *
1584 : * @return CE_Failure if the access fails, otherwise CE_None.
1585 : */
1586 :
1587 350251 : CPLErr GDALDataset::RasterIO( GDALRWFlag eRWFlag,
1588 : int nXOff, int nYOff, int nXSize, int nYSize,
1589 : void * pData, int nBufXSize, int nBufYSize,
1590 : GDALDataType eBufType,
1591 : int nBandCount, int *panBandMap,
1592 : int nPixelSpace, int nLineSpace, int nBandSpace )
1593 :
1594 : {
1595 350251 : int i = 0;
1596 350251 : int bNeedToFreeBandMap = FALSE;
1597 350251 : CPLErr eErr = CE_None;
1598 :
1599 350251 : if( NULL == pData )
1600 : {
1601 : ReportError( CE_Failure, CPLE_AppDefined,
1602 0 : "The buffer into which the data should be read is null" );
1603 0 : return CE_Failure;
1604 : }
1605 :
1606 : /* -------------------------------------------------------------------- */
1607 : /* Some size values are "noop". Lets just return to avoid */
1608 : /* stressing lower level functions. */
1609 : /* -------------------------------------------------------------------- */
1610 350251 : if( nXSize < 1 || nYSize < 1 || nBufXSize < 1 || nBufYSize < 1 )
1611 : {
1612 : CPLDebug( "GDAL",
1613 : "RasterIO() skipped for odd window or buffer size.\n"
1614 : " Window = (%d,%d)x%dx%d\n"
1615 : " Buffer = %dx%d\n",
1616 : nXOff, nYOff, nXSize, nYSize,
1617 0 : nBufXSize, nBufYSize );
1618 :
1619 0 : return CE_None;
1620 : }
1621 :
1622 : /* -------------------------------------------------------------------- */
1623 : /* If pixel and line spaceing are defaulted assign reasonable */
1624 : /* value assuming a packed buffer. */
1625 : /* -------------------------------------------------------------------- */
1626 350251 : if( nPixelSpace == 0 )
1627 339526 : nPixelSpace = GDALGetDataTypeSize( eBufType ) / 8;
1628 :
1629 350251 : if( nLineSpace == 0 )
1630 : {
1631 347214 : if (nPixelSpace > INT_MAX / nBufXSize)
1632 : {
1633 : ReportError( CE_Failure, CPLE_AppDefined,
1634 0 : "Int overflow : %d x %d", nPixelSpace, nBufXSize );
1635 0 : return CE_Failure;
1636 : }
1637 347214 : nLineSpace = nPixelSpace * nBufXSize;
1638 : }
1639 :
1640 : /* The nBandCount > 1 test is necessary to allow reading only */
1641 : /* one band, even if the nLineSpace would overflow, but as it */
1642 : /* is not used in that case, it can be left to 0 (#3481) */
1643 350251 : if( nBandSpace == 0 && nBandCount > 1 )
1644 : {
1645 1023 : if (nLineSpace > INT_MAX / nBufYSize)
1646 : {
1647 : ReportError( CE_Failure, CPLE_AppDefined,
1648 0 : "Int overflow : %d x %d", nLineSpace, nBufYSize );
1649 0 : return CE_Failure;
1650 : }
1651 1023 : nBandSpace = nLineSpace * nBufYSize;
1652 : }
1653 :
1654 350251 : if( panBandMap == NULL )
1655 : {
1656 10406 : if (nBandCount > GetRasterCount())
1657 : {
1658 : ReportError( CE_Failure, CPLE_IllegalArg,
1659 : "nBandCount cannot be greater than %d",
1660 0 : GetRasterCount() );
1661 0 : return CE_Failure;
1662 : }
1663 10406 : panBandMap = (int *) VSIMalloc2(sizeof(int), nBandCount);
1664 10406 : if (panBandMap == NULL)
1665 : {
1666 : ReportError( CE_Failure, CPLE_OutOfMemory,
1667 0 : "Out of memory while allocating band map array" );
1668 0 : return CE_Failure;
1669 : }
1670 40242 : for( i = 0; i < nBandCount; i++ )
1671 29836 : panBandMap[i] = i+1;
1672 :
1673 10406 : bNeedToFreeBandMap = TRUE;
1674 : }
1675 :
1676 : /* -------------------------------------------------------------------- */
1677 : /* Do some validation of parameters. */
1678 : /* -------------------------------------------------------------------- */
1679 350251 : if( nXOff < 0 || nXOff > INT_MAX - nXSize || nXOff + nXSize > nRasterXSize
1680 : || nYOff < 0 || nYOff > INT_MAX - nYSize || nYOff + nYSize > nRasterYSize )
1681 : {
1682 : ReportError( CE_Failure, CPLE_IllegalArg,
1683 : "Access window out of range in RasterIO(). Requested\n"
1684 : "(%d,%d) of size %dx%d on raster of %dx%d.",
1685 2 : nXOff, nYOff, nXSize, nYSize, nRasterXSize, nRasterYSize );
1686 2 : eErr = CE_Failure;
1687 : }
1688 :
1689 350251 : if( eRWFlag != GF_Read && eRWFlag != GF_Write )
1690 : {
1691 : ReportError( CE_Failure, CPLE_IllegalArg,
1692 : "eRWFlag = %d, only GF_Read (0) and GF_Write (1) are legal.",
1693 0 : eRWFlag );
1694 0 : eErr = CE_Failure;
1695 : }
1696 :
1697 723374 : for( i = 0; i < nBandCount && eErr == CE_None; i++ )
1698 : {
1699 373123 : if( panBandMap[i] < 1 || panBandMap[i] > GetRasterCount() )
1700 : {
1701 : ReportError( CE_Failure, CPLE_IllegalArg,
1702 : "panBandMap[%d] = %d, this band does not exist on dataset.",
1703 0 : i, panBandMap[i] );
1704 0 : eErr = CE_Failure;
1705 : }
1706 :
1707 373123 : if( eErr == CE_None && GetRasterBand( panBandMap[i] ) == NULL )
1708 : {
1709 : ReportError( CE_Failure, CPLE_IllegalArg,
1710 : "panBandMap[%d]=%d, this band should exist but is NULL!",
1711 0 : i, panBandMap[i] );
1712 0 : eErr = CE_Failure;
1713 : }
1714 : }
1715 :
1716 : /* -------------------------------------------------------------------- */
1717 : /* We are being forced to use cached IO instead of a driver */
1718 : /* specific implementation. */
1719 : /* -------------------------------------------------------------------- */
1720 350251 : if( bForceCachedIO )
1721 : {
1722 : eErr =
1723 : BlockBasedRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
1724 : pData, nBufXSize, nBufYSize, eBufType,
1725 : nBandCount, panBandMap,
1726 6 : nPixelSpace, nLineSpace, nBandSpace );
1727 : }
1728 :
1729 : /* -------------------------------------------------------------------- */
1730 : /* Call the format specific function. */
1731 : /* -------------------------------------------------------------------- */
1732 350245 : else if( eErr == CE_None )
1733 : {
1734 : eErr =
1735 : IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
1736 : pData, nBufXSize, nBufYSize, eBufType,
1737 : nBandCount, panBandMap,
1738 350243 : nPixelSpace, nLineSpace, nBandSpace );
1739 : }
1740 :
1741 : /* -------------------------------------------------------------------- */
1742 : /* Cleanup */
1743 : /* -------------------------------------------------------------------- */
1744 350251 : if( bNeedToFreeBandMap )
1745 10406 : CPLFree( panBandMap );
1746 :
1747 350251 : return eErr;
1748 : }
1749 :
1750 : /************************************************************************/
1751 : /* GDALDatasetRasterIO() */
1752 : /************************************************************************/
1753 :
1754 : /**
1755 : * \brief Read/write a region of image data from multiple bands.
1756 : *
1757 : * @see GDALDataset::RasterIO()
1758 : */
1759 :
1760 : CPLErr CPL_STDCALL
1761 339176 : GDALDatasetRasterIO( GDALDatasetH hDS, GDALRWFlag eRWFlag,
1762 : int nXOff, int nYOff, int nXSize, int nYSize,
1763 : void * pData, int nBufXSize, int nBufYSize,
1764 : GDALDataType eBufType,
1765 : int nBandCount, int *panBandMap,
1766 : int nPixelSpace, int nLineSpace, int nBandSpace )
1767 :
1768 : {
1769 339176 : VALIDATE_POINTER1( hDS, "GDALDatasetRasterIO", CE_Failure );
1770 :
1771 339176 : GDALDataset *poDS = (GDALDataset *) hDS;
1772 :
1773 : return( poDS->RasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
1774 : pData, nBufXSize, nBufYSize, eBufType,
1775 : nBandCount, panBandMap,
1776 339176 : nPixelSpace, nLineSpace, nBandSpace ) );
1777 : }
1778 :
1779 : /************************************************************************/
1780 : /* GetOpenDatasets() */
1781 : /************************************************************************/
1782 :
1783 4 : static int GDALGetOpenDatasetsForeach(void* elt, void* user_data)
1784 : {
1785 4 : int* pnIndex = (int*) user_data;
1786 4 : DatasetCtxt* psStruct = (DatasetCtxt*) elt;
1787 :
1788 4 : ppDatasets[*pnIndex] = psStruct->poDS;
1789 :
1790 4 : (*pnIndex) ++;
1791 :
1792 4 : return TRUE;
1793 : }
1794 :
1795 : /**
1796 : * \brief Fetch all open GDAL dataset handles.
1797 : *
1798 : * This method is the same as the C function GDALGetOpenDatasets().
1799 : *
1800 : * NOTE: This method is not thread safe. The returned list may change
1801 : * at any time and it should not be freed.
1802 : *
1803 : * @param pnCount integer into which to place the count of dataset pointers
1804 : * being returned.
1805 : *
1806 : * @return a pointer to an array of dataset handles.
1807 : */
1808 :
1809 1044 : GDALDataset **GDALDataset::GetOpenDatasets( int *pnCount )
1810 :
1811 : {
1812 1044 : CPLMutexHolderD( &hDLMutex );
1813 :
1814 1044 : if (phAllDatasetSet != NULL)
1815 : {
1816 2 : int nIndex = 0;
1817 2 : *pnCount = CPLHashSetSize(phAllDatasetSet);
1818 2 : ppDatasets = (GDALDataset**) CPLRealloc(ppDatasets, (*pnCount) * sizeof(GDALDataset*));
1819 2 : CPLHashSetForeach(phAllDatasetSet, GDALGetOpenDatasetsForeach, &nIndex);
1820 2 : return ppDatasets;
1821 : }
1822 : else
1823 : {
1824 1042 : *pnCount = 0;
1825 1042 : return NULL;
1826 0 : }
1827 : }
1828 :
1829 : /************************************************************************/
1830 : /* GDALGetOpenDatasets() */
1831 : /************************************************************************/
1832 :
1833 : /**
1834 : * \brief Fetch all open GDAL dataset handles.
1835 : *
1836 : * @see GDALDataset::GetOpenDatasets()
1837 : */
1838 :
1839 0 : void CPL_STDCALL GDALGetOpenDatasets( GDALDatasetH **ppahDSList, int *pnCount )
1840 :
1841 : {
1842 0 : VALIDATE_POINTER0( ppahDSList, "GDALGetOpenDatasets" );
1843 0 : VALIDATE_POINTER0( pnCount, "GDALGetOpenDatasets" );
1844 :
1845 0 : *ppahDSList = (GDALDatasetH *) GDALDataset::GetOpenDatasets( pnCount);
1846 : }
1847 :
1848 : /************************************************************************/
1849 : /* GDALGetAccess() */
1850 : /************************************************************************/
1851 :
1852 : /**
1853 : * \brief Return access flag
1854 : *
1855 : * @see GDALDataset::GetAccess()
1856 : */
1857 :
1858 0 : int CPL_STDCALL GDALGetAccess( GDALDatasetH hDS )
1859 : {
1860 0 : VALIDATE_POINTER1( hDS, "GDALGetAccess", 0 );
1861 :
1862 0 : return ((GDALDataset *) hDS)->GetAccess();
1863 : }
1864 :
1865 : /************************************************************************/
1866 : /* AdviseRead() */
1867 : /************************************************************************/
1868 :
1869 : /**
1870 : * \brief Advise driver of upcoming read requests.
1871 : *
1872 : * Some GDAL drivers operate more efficiently if they know in advance what
1873 : * set of upcoming read requests will be made. The AdviseRead() method allows
1874 : * an application to notify the driver of the region and bands of interest,
1875 : * and at what resolution the region will be read.
1876 : *
1877 : * Many drivers just ignore the AdviseRead() call, but it can dramatically
1878 : * accelerate access via some drivers.
1879 : *
1880 : * @param nXOff The pixel offset to the top left corner of the region
1881 : * of the band to be accessed. This would be zero to start from the left side.
1882 : *
1883 : * @param nYOff The line offset to the top left corner of the region
1884 : * of the band to be accessed. This would be zero to start from the top.
1885 : *
1886 : * @param nXSize The width of the region of the band to be accessed in pixels.
1887 : *
1888 : * @param nYSize The height of the region of the band to be accessed in lines.
1889 : *
1890 : * @param nBufXSize the width of the buffer image into which the desired region
1891 : * is to be read, or from which it is to be written.
1892 : *
1893 : * @param nBufYSize the height of the buffer image into which the desired
1894 : * region is to be read, or from which it is to be written.
1895 : *
1896 : * @param eBufType the type of the pixel values in the pData data buffer. The
1897 : * pixel values will automatically be translated to/from the GDALRasterBand
1898 : * data type as needed.
1899 : *
1900 : * @param nBandCount the number of bands being read or written.
1901 : *
1902 : * @param panBandMap the list of nBandCount band numbers being read/written.
1903 : * Note band numbers are 1 based. This may be NULL to select the first
1904 : * nBandCount bands.
1905 : *
1906 : * @param papszOptions a list of name=value strings with special control
1907 : * options. Normally this is NULL.
1908 : *
1909 : * @return CE_Failure if the request is invalid and CE_None if it works or
1910 : * is ignored.
1911 : */
1912 :
1913 0 : CPLErr GDALDataset::AdviseRead( int nXOff, int nYOff, int nXSize, int nYSize,
1914 : int nBufXSize, int nBufYSize,
1915 : GDALDataType eBufType,
1916 : int nBandCount, int *panBandMap,
1917 : char **papszOptions )
1918 :
1919 : {
1920 : int iBand;
1921 :
1922 0 : for( iBand = 0; iBand < nBandCount; iBand++ )
1923 : {
1924 : CPLErr eErr;
1925 : GDALRasterBand *poBand;
1926 :
1927 0 : if( panBandMap == NULL )
1928 0 : poBand = GetRasterBand(iBand+1);
1929 : else
1930 0 : poBand = GetRasterBand(panBandMap[iBand]);
1931 :
1932 : eErr = poBand->AdviseRead( nXOff, nYOff, nXSize, nYSize,
1933 0 : nBufXSize, nBufYSize, eBufType, papszOptions );
1934 :
1935 0 : if( eErr != CE_None )
1936 0 : return eErr;
1937 : }
1938 :
1939 0 : return CE_None;
1940 : }
1941 :
1942 : /************************************************************************/
1943 : /* GDALDatasetAdviseRead() */
1944 : /************************************************************************/
1945 :
1946 : /**
1947 : * \brief Advise driver of upcoming read requests.
1948 : *
1949 : * @see GDALDataset::AdviseRead()
1950 : */
1951 : CPLErr CPL_STDCALL
1952 0 : GDALDatasetAdviseRead( GDALDatasetH hDS,
1953 : int nXOff, int nYOff, int nXSize, int nYSize,
1954 : int nBufXSize, int nBufYSize, GDALDataType eDT,
1955 : int nBandCount, int *panBandMap,char **papszOptions )
1956 :
1957 : {
1958 0 : VALIDATE_POINTER1( hDS, "GDALDatasetAdviseRead", CE_Failure );
1959 :
1960 : return ((GDALDataset *) hDS)->AdviseRead( nXOff, nYOff, nXSize, nYSize,
1961 : nBufXSize, nBufYSize, eDT,
1962 : nBandCount, panBandMap,
1963 0 : papszOptions );
1964 : }
1965 :
1966 : /************************************************************************/
1967 : /* GetFileList() */
1968 : /************************************************************************/
1969 :
1970 : /**
1971 : * \brief Fetch files forming dataset.
1972 : *
1973 : * Returns a list of files believed to be part of this dataset. If it returns
1974 : * an empty list of files it means there is believed to be no local file
1975 : * system files associated with the dataset (for instance a virtual dataset).
1976 : * The returned file list is owned by the caller and should be deallocated
1977 : * with CSLDestroy().
1978 : *
1979 : * The returned filenames will normally be relative or absolute paths
1980 : * depending on the path used to originally open the dataset. The strings
1981 : * will be UTF-8 encoded.
1982 : *
1983 : * This method is the same as the C GDALGetFileList() function.
1984 : *
1985 : * @return NULL or a NULL terminated array of file names.
1986 : */
1987 :
1988 1520 : char **GDALDataset::GetFileList()
1989 :
1990 : {
1991 1520 : CPLString osMainFilename = GetDescription();
1992 : int bMainFileReal;
1993 : VSIStatBufL sStat;
1994 :
1995 : /* -------------------------------------------------------------------- */
1996 : /* Is the main filename even a real filesystem object? */
1997 : /* -------------------------------------------------------------------- */
1998 1520 : bMainFileReal = VSIStatExL( osMainFilename, &sStat, VSI_STAT_EXISTS_FLAG ) == 0;
1999 :
2000 : /* -------------------------------------------------------------------- */
2001 : /* Form new list. */
2002 : /* -------------------------------------------------------------------- */
2003 1520 : char **papszList = NULL;
2004 :
2005 1520 : if( bMainFileReal )
2006 1513 : papszList = CSLAddString( papszList, osMainFilename );
2007 :
2008 : /* -------------------------------------------------------------------- */
2009 : /* Do we have a known overview file? */
2010 : /* -------------------------------------------------------------------- */
2011 1520 : if( oOvManager.IsInitialized() && oOvManager.poODS != NULL )
2012 : {
2013 65 : char **papszOvrList = oOvManager.poODS->GetFileList();
2014 65 : papszList = CSLInsertStrings( papszList, -1, papszOvrList );
2015 65 : CSLDestroy( papszOvrList );
2016 : }
2017 :
2018 : /* -------------------------------------------------------------------- */
2019 : /* Do we have a known overview file? */
2020 : /* -------------------------------------------------------------------- */
2021 1520 : if( oOvManager.HaveMaskFile() )
2022 : {
2023 5 : char **papszMskList = oOvManager.poMaskDS->GetFileList();
2024 5 : papszList = CSLInsertStrings( papszList, -1, papszMskList );
2025 5 : CSLDestroy( papszMskList );
2026 : }
2027 :
2028 : /* -------------------------------------------------------------------- */
2029 : /* Do we have a world file? */
2030 : /* -------------------------------------------------------------------- */
2031 1520 : if( bMainFileReal )
2032 : {
2033 1513 : const char* pszExtension = CPLGetExtension( osMainFilename );
2034 1513 : if( strlen(pszExtension) > 2 )
2035 : {
2036 : // first + last + 'w'
2037 : char szDerivedExtension[4];
2038 1507 : szDerivedExtension[0] = pszExtension[0];
2039 1507 : szDerivedExtension[1] = pszExtension[strlen(pszExtension)-1];
2040 1507 : szDerivedExtension[2] = 'w';
2041 1507 : szDerivedExtension[3] = '\0';
2042 1507 : CPLString osWorldFilename = CPLResetExtension( osMainFilename, szDerivedExtension );
2043 :
2044 1507 : if (oOvManager.papszInitSiblingFiles)
2045 : {
2046 : int iSibling = CSLFindString(oOvManager.papszInitSiblingFiles,
2047 1024 : CPLGetFilename(osWorldFilename));
2048 1024 : if (iSibling >= 0)
2049 : {
2050 : osWorldFilename.resize(strlen(osWorldFilename) -
2051 2 : strlen(oOvManager.papszInitSiblingFiles[iSibling]));
2052 2 : osWorldFilename += oOvManager.papszInitSiblingFiles[iSibling];
2053 2 : papszList = CSLAddString( papszList, osWorldFilename );
2054 : }
2055 : }
2056 483 : else if( VSIStatExL( osWorldFilename, &sStat, VSI_STAT_EXISTS_FLAG ) == 0 )
2057 1 : papszList = CSLAddString( papszList, osWorldFilename );
2058 : }
2059 : }
2060 :
2061 1520 : return papszList;
2062 : }
2063 :
2064 : /************************************************************************/
2065 : /* GDALGetFileList() */
2066 : /************************************************************************/
2067 :
2068 : /**
2069 : * \brief Fetch files forming dataset.
2070 : *
2071 : * @see GDALDataset::GetFileList()
2072 : */
2073 :
2074 1429 : char ** CPL_STDCALL GDALGetFileList( GDALDatasetH hDS )
2075 :
2076 : {
2077 1429 : VALIDATE_POINTER1( hDS, "GDALGetFileList", NULL );
2078 :
2079 1429 : return ((GDALDataset *) hDS)->GetFileList();
2080 : }
2081 :
2082 : /************************************************************************/
2083 : /* CreateMaskBand() */
2084 : /************************************************************************/
2085 :
2086 : /**
2087 : * \brief Adds a mask band to the dataset
2088 : *
2089 : * The default implementation of the CreateMaskBand() method is implemented
2090 : * based on similar rules to the .ovr handling implemented using the
2091 : * GDALDefaultOverviews object. A TIFF file with the extension .msk will
2092 : * be created with the same basename as the original file, and it will have
2093 : * one band.
2094 : * The mask images will be deflate compressed tiled images with the same
2095 : * block size as the original image if possible.
2096 : *
2097 : * Note that if you got a mask band with a previous call to GetMaskBand(),
2098 : * it might be invalidated by CreateMaskBand(). So you have to call GetMaskBand()
2099 : * again.
2100 : *
2101 : * @since GDAL 1.5.0
2102 : *
2103 : * @param nFlags ignored. GMF_PER_DATASET will be assumed.
2104 : * @return CE_None on success or CE_Failure on an error.
2105 : *
2106 : * @see http://trac.osgeo.org/gdal/wiki/rfc15_nodatabitmask
2107 : *
2108 : */
2109 5 : CPLErr GDALDataset::CreateMaskBand( int nFlags )
2110 :
2111 : {
2112 5 : if( oOvManager.IsInitialized() )
2113 : {
2114 5 : CPLErr eErr = oOvManager.CreateMaskBand( nFlags, -1 );
2115 5 : if (eErr != CE_None)
2116 0 : return eErr;
2117 :
2118 : /* Invalidate existing raster band masks */
2119 : int i;
2120 16 : for(i=0;i<nBands;i++)
2121 : {
2122 11 : GDALRasterBand* poBand = papoBands[i];
2123 11 : if (poBand->bOwnMask)
2124 1 : delete poBand->poMask;
2125 11 : poBand->bOwnMask = false;
2126 11 : poBand->poMask = NULL;
2127 : }
2128 :
2129 5 : return CE_None;
2130 : }
2131 :
2132 : ReportError( CE_Failure, CPLE_NotSupported,
2133 0 : "CreateMaskBand() not supported for this dataset." );
2134 :
2135 0 : return( CE_Failure );
2136 : }
2137 :
2138 : /************************************************************************/
2139 : /* GDALCreateDatasetMaskBand() */
2140 : /************************************************************************/
2141 :
2142 : /**
2143 : * \brief Adds a mask band to the dataset
2144 : * @see GDALDataset::CreateMaskBand()
2145 : */
2146 19 : CPLErr CPL_STDCALL GDALCreateDatasetMaskBand( GDALDatasetH hDS, int nFlags )
2147 :
2148 : {
2149 19 : VALIDATE_POINTER1( hDS, "GDALCreateDatasetMaskBand", CE_Failure );
2150 :
2151 19 : return ((GDALDataset *) hDS)->CreateMaskBand( nFlags );
2152 : }
2153 :
2154 : /************************************************************************/
2155 : /* GDALOpen() */
2156 : /************************************************************************/
2157 :
2158 : /**
2159 : * \brief Open a raster file as a GDALDataset.
2160 : *
2161 : * This function will try to open the passed file, or virtual dataset
2162 : * name by invoking the Open method of each registered GDALDriver in turn.
2163 : * The first successful open will result in a returned dataset. If all
2164 : * drivers fail then NULL is returned and an error is issued.
2165 : *
2166 : * Several recommandations :
2167 : * <ul>
2168 : * <li>If you open a dataset object with GA_Update access, it is not recommanded
2169 : * to open a new dataset on the same underlying file.</li>
2170 : * <li>The returned dataset should only be accessed by one thread at a time. If you
2171 : * want to use it from different threads, you must add all necessary code (mutexes, etc.)
2172 : * to avoid concurrent use of the object. (Some drivers, such as GeoTIFF, maintain internal
2173 : * state variables that are updated each time a new block is read, thus preventing concurrent
2174 : * use.) </li>
2175 : * </ul>
2176 : *
2177 : * For drivers supporting the VSI virtual file API, it is possible to open
2178 : * a file in a .zip archive (see VSIInstallZipFileHandler()), in a .tar/.tar.gz/.tgz archive
2179 : * (see VSIInstallTarFileHandler()) or on a HTTP / FTP server (see VSIInstallCurlFileHandler())
2180 : *
2181 : * \sa GDALOpenShared()
2182 : *
2183 : * @param pszFilename the name of the file to access. In the case of
2184 : * exotic drivers this may not refer to a physical file, but instead contain
2185 : * information for the driver on how to access a dataset. It should be in UTF-8
2186 : * encoding.
2187 : *
2188 : * @param eAccess the desired access, either GA_Update or GA_ReadOnly. Many
2189 : * drivers support only read only access.
2190 : *
2191 : * @return A GDALDatasetH handle or NULL on failure. For C++ applications
2192 : * this handle can be cast to a GDALDataset *.
2193 : */
2194 :
2195 : GDALDatasetH CPL_STDCALL
2196 8255 : GDALOpen( const char * pszFilename, GDALAccess eAccess )
2197 :
2198 : {
2199 8255 : return GDALOpenInternal(pszFilename, eAccess, NULL);
2200 : }
2201 :
2202 : /* The drivers listed in papszAllowedDrivers can be in any order */
2203 : /* Only the order of registration will be taken into account */
2204 8277 : GDALDatasetH GDALOpenInternal( const char * pszFilename, GDALAccess eAccess,
2205 : const char* const * papszAllowedDrivers)
2206 : {
2207 8277 : GDALOpenInfo oOpenInfo( pszFilename, eAccess );
2208 8277 : return GDALOpenInternal(oOpenInfo, papszAllowedDrivers);
2209 : }
2210 :
2211 8392 : GDALDatasetH GDALOpenInternal( GDALOpenInfo& oOpenInfo,
2212 : const char* const * papszAllowedDrivers)
2213 : {
2214 :
2215 8392 : VALIDATE_POINTER1( oOpenInfo.pszFilename, "GDALOpen", NULL );
2216 :
2217 : int iDriver;
2218 8392 : GDALDriverManager *poDM = GetGDALDriverManager();
2219 8392 : CPLLocaleC oLocaleForcer;
2220 :
2221 8392 : CPLErrorReset();
2222 8392 : CPLAssert( NULL != poDM );
2223 :
2224 294715 : for( iDriver = 0; iDriver < poDM->GetDriverCount(); iDriver++ )
2225 : {
2226 293567 : GDALDriver *poDriver = poDM->GetDriver( iDriver );
2227 : GDALDataset *poDS;
2228 :
2229 293567 : if (papszAllowedDrivers != NULL &&
2230 : CSLFindString((char**)papszAllowedDrivers, GDALGetDriverShortName(poDriver)) == -1)
2231 2640 : continue;
2232 :
2233 290927 : if ( poDriver->pfnOpen == NULL )
2234 0 : continue;
2235 :
2236 290927 : poDS = poDriver->pfnOpen( &oOpenInfo );
2237 290927 : if( poDS != NULL )
2238 : {
2239 7195 : if( strlen(poDS->GetDescription()) == 0 )
2240 549 : poDS->SetDescription( oOpenInfo.pszFilename );
2241 :
2242 7195 : if( poDS->poDriver == NULL )
2243 6217 : poDS->poDriver = poDriver;
2244 :
2245 :
2246 7195 : if( CPLGetPID() != GDALGetResponsiblePIDForCurrentThread() )
2247 : CPLDebug( "GDAL", "GDALOpen(%s, this=%p) succeeds as %s (pid=%d, responsiblePID=%d).",
2248 0 : oOpenInfo.pszFilename, poDS, poDriver->GetDescription(),
2249 0 : (int)CPLGetPID(), (int)GDALGetResponsiblePIDForCurrentThread() );
2250 : else
2251 : CPLDebug( "GDAL", "GDALOpen(%s, this=%p) succeeds as %s.",
2252 7195 : oOpenInfo.pszFilename, poDS, poDriver->GetDescription() );
2253 :
2254 7195 : return (GDALDatasetH) poDS;
2255 : }
2256 :
2257 283732 : if( CPLGetLastErrorNo() != 0 )
2258 49 : return NULL;
2259 : }
2260 :
2261 1148 : if( oOpenInfo.bStatOK )
2262 : CPLError( CE_Failure, CPLE_OpenFailed,
2263 : "`%s' not recognised as a supported file format.\n",
2264 66 : oOpenInfo.pszFilename );
2265 : else
2266 : CPLError( CE_Failure, CPLE_OpenFailed,
2267 : "`%s' does not exist in the file system,\n"
2268 : "and is not recognised as a supported dataset name.\n",
2269 1082 : oOpenInfo.pszFilename );
2270 :
2271 1148 : return NULL;
2272 : }
2273 :
2274 : /************************************************************************/
2275 : /* GDALOpenShared() */
2276 : /************************************************************************/
2277 :
2278 : /**
2279 : * \brief Open a raster file as a GDALDataset.
2280 : *
2281 : * This function works the same as GDALOpen(), but allows the sharing of
2282 : * GDALDataset handles for a dataset with other callers to GDALOpenShared().
2283 : *
2284 : * In particular, GDALOpenShared() will first consult it's list of currently
2285 : * open and shared GDALDataset's, and if the GetDescription() name for one
2286 : * exactly matches the pszFilename passed to GDALOpenShared() it will be
2287 : * referenced and returned.
2288 : *
2289 : * Starting with GDAL 1.6.0, if GDALOpenShared() is called on the same pszFilename
2290 : * from two different threads, a different GDALDataset object will be returned as
2291 : * it is not safe to use the same dataset from different threads, unless the user
2292 : * does explicitely use mutexes in its code.
2293 : *
2294 : * For drivers supporting the VSI virtual file API, it is possible to open
2295 : * a file in a .zip archive (see VSIInstallZipFileHandler()), in a .tar/.tar.gz/.tgz archive
2296 : * (see VSIInstallTarFileHandler()) or on a HTTP / FTP server (see VSIInstallCurlFileHandler())
2297 : *
2298 : * \sa GDALOpen()
2299 : *
2300 : * @param pszFilename the name of the file to access. In the case of
2301 : * exotic drivers this may not refer to a physical file, but instead contain
2302 : * information for the driver on how to access a dataset. It should be in
2303 : * UTF-8 encoding.
2304 : *
2305 : * @param eAccess the desired access, either GA_Update or GA_ReadOnly. Many
2306 : * drivers support only read only access.
2307 : *
2308 : * @return A GDALDatasetH handle or NULL on failure. For C++ applications
2309 : * this handle can be cast to a GDALDataset *.
2310 : */
2311 :
2312 : GDALDatasetH CPL_STDCALL
2313 5317 : GDALOpenShared( const char *pszFilename, GDALAccess eAccess )
2314 :
2315 : {
2316 5317 : VALIDATE_POINTER1( pszFilename, "GDALOpenShared", NULL );
2317 :
2318 : /* -------------------------------------------------------------------- */
2319 : /* First scan the existing list to see if it could already */
2320 : /* contain the requested dataset. */
2321 : /* -------------------------------------------------------------------- */
2322 : {
2323 5317 : CPLMutexHolderD( &hDLMutex );
2324 :
2325 5317 : if (phSharedDatasetSet != NULL)
2326 : {
2327 5171 : GIntBig nThisPID = GDALGetResponsiblePIDForCurrentThread();
2328 : SharedDatasetCtxt* psStruct;
2329 : SharedDatasetCtxt sStruct;
2330 :
2331 5171 : sStruct.nPID = nThisPID;
2332 5171 : sStruct.pszDescription = (char*) pszFilename;
2333 5171 : sStruct.eAccess = eAccess;
2334 5171 : psStruct = (SharedDatasetCtxt*) CPLHashSetLookup(phSharedDatasetSet, &sStruct);
2335 5171 : if (psStruct == NULL && eAccess == GA_ReadOnly)
2336 : {
2337 119 : sStruct.eAccess = GA_Update;
2338 119 : psStruct = (SharedDatasetCtxt*) CPLHashSetLookup(phSharedDatasetSet, &sStruct);
2339 : }
2340 5171 : if (psStruct)
2341 : {
2342 5052 : psStruct->poDS->Reference();
2343 5052 : return psStruct->poDS;
2344 : }
2345 0 : }
2346 : }
2347 :
2348 : /* -------------------------------------------------------------------- */
2349 : /* Try opening the the requested dataset. */
2350 : /* -------------------------------------------------------------------- */
2351 : GDALDataset *poDataset;
2352 :
2353 265 : poDataset = (GDALDataset *) GDALOpen( pszFilename, eAccess );
2354 265 : if( poDataset != NULL )
2355 : {
2356 264 : if (strcmp(pszFilename, poDataset->GetDescription()) != 0)
2357 : {
2358 : CPLError(CE_Warning, CPLE_NotSupported,
2359 : "A dataset opened by GDALOpenShared should have the same filename (%s) "
2360 : "and description (%s)",
2361 2 : pszFilename, poDataset->GetDescription());
2362 : }
2363 : else
2364 : {
2365 262 : poDataset->MarkAsShared();
2366 : }
2367 : }
2368 :
2369 265 : return (GDALDatasetH) poDataset;
2370 : }
2371 :
2372 : /************************************************************************/
2373 : /* GDALClose() */
2374 : /************************************************************************/
2375 :
2376 : /**
2377 : * \brief Close GDAL dataset.
2378 : *
2379 : * For non-shared datasets (opened with GDALOpen()) the dataset is closed
2380 : * using the C++ "delete" operator, recovering all dataset related resources.
2381 : * For shared datasets (opened with GDALOpenShared()) the dataset is
2382 : * dereferenced, and closed only if the referenced count has dropped below 1.
2383 : *
2384 : * @param hDS The dataset to close. May be cast from a "GDALDataset *".
2385 : */
2386 :
2387 14175 : void CPL_STDCALL GDALClose( GDALDatasetH hDS )
2388 :
2389 : {
2390 14175 : VALIDATE_POINTER0( hDS, "GDALClose" );
2391 :
2392 14175 : GDALDataset *poDS = (GDALDataset *) hDS;
2393 14175 : CPLMutexHolderD( &hDLMutex );
2394 14175 : CPLLocaleC oLocaleForcer;
2395 :
2396 14175 : if (poDS->GetShared())
2397 : {
2398 : /* -------------------------------------------------------------------- */
2399 : /* If this file is in the shared dataset list then dereference */
2400 : /* it, and only delete/remote it if the reference count has */
2401 : /* dropped to zero. */
2402 : /* -------------------------------------------------------------------- */
2403 726 : if( poDS->Dereference() > 0 )
2404 : return;
2405 :
2406 545 : delete poDS;
2407 : return;
2408 : }
2409 :
2410 : /* -------------------------------------------------------------------- */
2411 : /* This is not shared dataset, so directly delete it. */
2412 : /* -------------------------------------------------------------------- */
2413 13449 : delete poDS;
2414 : }
2415 :
2416 : /************************************************************************/
2417 : /* GDALDumpOpenDataset() */
2418 : /************************************************************************/
2419 :
2420 0 : static int GDALDumpOpenSharedDatasetsForeach(void* elt, void* user_data)
2421 : {
2422 0 : SharedDatasetCtxt* psStruct = (SharedDatasetCtxt*) elt;
2423 0 : FILE *fp = (FILE*) user_data;
2424 : const char *pszDriverName;
2425 0 : GDALDataset *poDS = psStruct->poDS;
2426 :
2427 0 : if( poDS->GetDriver() == NULL )
2428 0 : pszDriverName = "DriverIsNULL";
2429 : else
2430 0 : pszDriverName = poDS->GetDriver()->GetDescription();
2431 :
2432 0 : poDS->Reference();
2433 : VSIFPrintf( fp, " %d %c %-6s %7d %dx%dx%d %s\n",
2434 : poDS->Dereference(),
2435 : poDS->GetShared() ? 'S' : 'N',
2436 : pszDriverName,
2437 : (int)psStruct->nPID,
2438 : poDS->GetRasterXSize(),
2439 : poDS->GetRasterYSize(),
2440 : poDS->GetRasterCount(),
2441 0 : poDS->GetDescription() );
2442 :
2443 0 : return TRUE;
2444 : }
2445 :
2446 :
2447 0 : static int GDALDumpOpenDatasetsForeach(void* elt, void* user_data)
2448 : {
2449 0 : DatasetCtxt* psStruct = (DatasetCtxt*) elt;
2450 0 : FILE *fp = (FILE*) user_data;
2451 : const char *pszDriverName;
2452 0 : GDALDataset *poDS = psStruct->poDS;
2453 :
2454 : /* Don't list shared datasets. They have already been listed by */
2455 : /* GDALDumpOpenSharedDatasetsForeach */
2456 0 : if (poDS->GetShared())
2457 0 : return TRUE;
2458 :
2459 0 : if( poDS->GetDriver() == NULL )
2460 0 : pszDriverName = "DriverIsNULL";
2461 : else
2462 0 : pszDriverName = poDS->GetDriver()->GetDescription();
2463 :
2464 0 : poDS->Reference();
2465 : VSIFPrintf( fp, " %d %c %-6s %7d %dx%dx%d %s\n",
2466 : poDS->Dereference(),
2467 : poDS->GetShared() ? 'S' : 'N',
2468 : pszDriverName,
2469 : -1,
2470 : poDS->GetRasterXSize(),
2471 : poDS->GetRasterYSize(),
2472 : poDS->GetRasterCount(),
2473 0 : poDS->GetDescription() );
2474 :
2475 0 : return TRUE;
2476 : }
2477 :
2478 : /**
2479 : * \brief List open datasets.
2480 : *
2481 : * Dumps a list of all open datasets (shared or not) to the indicated
2482 : * text file (may be stdout or stderr). This function is primariliy intended
2483 : * to assist in debugging "dataset leaks" and reference counting issues.
2484 : * The information reported includes the dataset name, referenced count,
2485 : * shared status, driver name, size, and band count.
2486 : */
2487 :
2488 444 : int CPL_STDCALL GDALDumpOpenDatasets( FILE *fp )
2489 :
2490 : {
2491 444 : VALIDATE_POINTER1( fp, "GDALDumpOpenDatasets", 0 );
2492 :
2493 444 : CPLMutexHolderD( &hDLMutex );
2494 :
2495 444 : if (phAllDatasetSet != NULL)
2496 : {
2497 0 : VSIFPrintf( fp, "Open GDAL Datasets:\n" );
2498 0 : CPLHashSetForeach(phAllDatasetSet, GDALDumpOpenDatasetsForeach, fp);
2499 0 : if (phSharedDatasetSet != NULL)
2500 : {
2501 0 : CPLHashSetForeach(phSharedDatasetSet, GDALDumpOpenSharedDatasetsForeach, fp);
2502 : }
2503 0 : return CPLHashSetSize(phAllDatasetSet);
2504 : }
2505 : else
2506 : {
2507 444 : return 0;
2508 0 : }
2509 : }
2510 :
2511 : /************************************************************************/
2512 : /* BeginAsyncReader() */
2513 : /************************************************************************/
2514 :
2515 : /**
2516 : * \brief Sets up an asynchronous data request
2517 : *
2518 : * This method establish an asynchronous raster read request for the
2519 : * indicated window on the dataset into the indicated buffer. The parameters
2520 : * for windowing, buffer size, buffer type and buffer organization are similar
2521 : * to those for GDALDataset::RasterIO(); however, this call only launches
2522 : * the request and filling the buffer is accomplished via calls to
2523 : * GetNextUpdatedRegion() on the return GDALAsyncReader session object.
2524 : *
2525 : * Once all processing for the created session is complete, or if no further
2526 : * refinement of the request is required, the GDALAsyncReader object should
2527 : * be destroyed with the GDALDataset::EndAsyncReader() method.
2528 : *
2529 : * Note that the data buffer (pData) will potentially continue to be
2530 : * updated as long as the session lives, but it is not deallocated when
2531 : * the session (GDALAsyncReader) is destroyed with EndAsyncReader(). It
2532 : * should be deallocated by the application at that point.
2533 : *
2534 : * Additional information on asynchronous IO in GDAL may be found at:
2535 : * http://trac.osgeo.org/gdal/wiki/rfc24_progressive_data_support
2536 : *
2537 : * This method is the same as the C GDALBeginAsyncReader() function.
2538 : *
2539 : * @param nXOff The pixel offset to the top left corner of the region
2540 : * of the band to be accessed. This would be zero to start from the left side.
2541 : *
2542 : * @param nYOff The line offset to the top left corner of the region
2543 : * of the band to be accessed. This would be zero to start from the top.
2544 : *
2545 : * @param nXSize The width of the region of the band to be accessed in pixels.
2546 : *
2547 : * @param nYSize The height of the region of the band to be accessed in lines.
2548 : *
2549 : * @param pBuf The buffer into which the data should be read. This buffer must
2550 : * contain at least nBufXSize * nBufYSize * nBandCount words of type eBufType.
2551 : * It is organized in left to right,top to bottom pixel order. Spacing is
2552 : * controlled by the nPixelSpace, and nLineSpace parameters.
2553 : *
2554 : * @param nBufXSize the width of the buffer image into which the desired region
2555 : * is to be read, or from which it is to be written.
2556 : *
2557 : * @param nBufYSize the height of the buffer image into which the desired
2558 : * region is to be read, or from which it is to be written.
2559 : *
2560 : * @param eBufType the type of the pixel values in the pData data buffer. The
2561 : * pixel values will automatically be translated to/from the GDALRasterBand
2562 : * data type as needed.
2563 : *
2564 : * @param nBandCount the number of bands being read or written.
2565 : *
2566 : * @param panBandMap the list of nBandCount band numbers being read/written.
2567 : * Note band numbers are 1 based. This may be NULL to select the first
2568 : * nBandCount bands.
2569 : *
2570 : * @param nPixelSpace The byte offset from the start of one pixel value in
2571 : * pData to the start of the next pixel value within a scanline. If defaulted
2572 : * (0) the size of the datatype eBufType is used.
2573 : *
2574 : * @param nLineSpace The byte offset from the start of one scanline in
2575 : * pData to the start of the next. If defaulted the size of the datatype
2576 : * eBufType * nBufXSize is used.
2577 : *
2578 : * @param nBandSpace the byte offset from the start of one bands data to the
2579 : * start of the next. If defaulted (zero) the value will be
2580 : * nLineSpace * nBufYSize implying band sequential organization
2581 : * of the data buffer.
2582 : *
2583 : * @param papszOptions Driver specific control options in a string list or NULL.
2584 : * Consult driver documentation for options supported.
2585 : *
2586 : * @return The GDALAsyncReader object representing the request.
2587 : */
2588 :
2589 : GDALAsyncReader*
2590 1 : GDALDataset::BeginAsyncReader(int nXOff, int nYOff,
2591 : int nXSize, int nYSize,
2592 : void *pBuf,
2593 : int nBufXSize, int nBufYSize,
2594 : GDALDataType eBufType,
2595 : int nBandCount, int* panBandMap,
2596 : int nPixelSpace, int nLineSpace,
2597 : int nBandSpace, char **papszOptions)
2598 : {
2599 : // See gdaldefaultasync.cpp
2600 :
2601 : return
2602 : GDALGetDefaultAsyncReader( this,
2603 : nXOff, nYOff, nXSize, nYSize,
2604 : pBuf, nBufXSize, nBufYSize, eBufType,
2605 : nBandCount, panBandMap,
2606 : nPixelSpace, nLineSpace, nBandSpace,
2607 1 : papszOptions );
2608 : }
2609 :
2610 : /************************************************************************/
2611 : /* GDALBeginAsyncReader() */
2612 : /************************************************************************/
2613 :
2614 : GDALAsyncReaderH CPL_STDCALL
2615 1 : GDALBeginAsyncReader(GDALDatasetH hDS, int xOff, int yOff,
2616 : int xSize, int ySize,
2617 : void *pBuf,
2618 : int bufXSize, int bufYSize,
2619 : GDALDataType bufType,
2620 : int nBandCount, int* bandMap,
2621 : int nPixelSpace, int nLineSpace,
2622 : int nBandSpace,
2623 : char **papszOptions)
2624 :
2625 : {
2626 1 : VALIDATE_POINTER1( hDS, "GDALDataset", NULL );
2627 : return (GDALAsyncReaderH)((GDALDataset *) hDS)->
2628 : BeginAsyncReader(xOff, yOff,
2629 : xSize, ySize,
2630 : pBuf, bufXSize, bufYSize,
2631 : bufType, nBandCount, bandMap,
2632 : nPixelSpace, nLineSpace,
2633 1 : nBandSpace, papszOptions);
2634 : }
2635 :
2636 : /************************************************************************/
2637 : /* EndAsyncReader() */
2638 : /************************************************************************/
2639 :
2640 : /**
2641 : * End asynchronous request.
2642 : *
2643 : * This method destroys an asynchronous io request and recovers all
2644 : * resources associated with it.
2645 : *
2646 : * This method is the same as the C function GDALEndAsyncReader().
2647 : *
2648 : * @param poARIO pointer to a GDALAsyncReader
2649 : */
2650 :
2651 1 : void GDALDataset::EndAsyncReader(GDALAsyncReader *poARIO )
2652 : {
2653 1 : delete poARIO;
2654 1 : }
2655 :
2656 : /************************************************************************/
2657 : /* GDALEndAsyncReader() */
2658 : /************************************************************************/
2659 1 : void CPL_STDCALL GDALEndAsyncReader(GDALDatasetH hDS, GDALAsyncReaderH hAsyncReaderH)
2660 : {
2661 1 : VALIDATE_POINTER0( hDS, "GDALDataset" );
2662 1 : VALIDATE_POINTER0( hAsyncReaderH, "GDALAsyncReader" );
2663 1 : ((GDALDataset *) hDS) -> EndAsyncReader((GDALAsyncReader *)hAsyncReaderH);
2664 : }
2665 :
2666 : /************************************************************************/
2667 : /* CloseDependentDatasets() */
2668 : /************************************************************************/
2669 :
2670 : /**
2671 : * Drop references to any other datasets referenced by this dataset.
2672 : *
2673 : * This method should release any reference to other datasets (e.g. a VRT
2674 : * dataset to its sources), but not close the current dataset itself.
2675 : *
2676 : * If at least, one reference to a dependant dataset has been dropped,
2677 : * this method should return TRUE. Otherwise it *should* return FALSE.
2678 : * (Failure to return the proper value might result in infinite loop)
2679 : *
2680 : * This method can be called several times on a given dataset. After
2681 : * the first time, it should not do anything and return FALSE.
2682 : *
2683 : * The driver implementation may choose to destroy its raster bands,
2684 : * so be careful not to call any method on the raster bands afterwards.
2685 : *
2686 : * Basically the only safe action you can do after calling CloseDependantDatasets()
2687 : * is to call the destructor.
2688 : *
2689 : * Note: the only legitimate caller of CloseDependantDatasets() is
2690 : * GDALDriverManager::~GDALDriverManager()
2691 : *
2692 : * @return TRUE if at least one reference to another dataset has been dropped.
2693 : */
2694 868 : int GDALDataset::CloseDependentDatasets()
2695 : {
2696 868 : return oOvManager.CloseDependentDatasets();
2697 : }
2698 :
2699 : /************************************************************************/
2700 : /* ReportError() */
2701 : /************************************************************************/
2702 :
2703 : /**
2704 : * \brief Emits an error related to a dataset.
2705 : *
2706 : * This function is a wrapper for regular CPLError(). The only difference
2707 : * with CPLError() is that it prepends the error message with the dataset
2708 : * name.
2709 : *
2710 : * @param eErrClass one of CE_Warning, CE_Failure or CE_Fatal.
2711 : * @param err_no the error number (CPLE_*) from cpl_error.h.
2712 : * @param fmt a printf() style format string. Any additional arguments
2713 : * will be treated as arguments to fill in this format in a manner
2714 : * similar to printf().
2715 : *
2716 : * @since GDAL 1.9.0
2717 : */
2718 :
2719 2 : void GDALDataset::ReportError(CPLErr eErrClass, int err_no, const char *fmt, ...)
2720 : {
2721 : va_list args;
2722 :
2723 2 : va_start(args, fmt);
2724 :
2725 : char szNewFmt[256];
2726 2 : const char* pszDSName = GetDescription();
2727 2 : if (strlen(fmt) + strlen(pszDSName) + 3 >= sizeof(szNewFmt) - 1)
2728 0 : pszDSName = CPLGetFilename(pszDSName);
2729 3 : if (pszDSName[0] != '\0' &&
2730 : strlen(fmt) + strlen(pszDSName) + 3 < sizeof(szNewFmt) - 1)
2731 : {
2732 : snprintf(szNewFmt, sizeof(szNewFmt), "%s: %s",
2733 1 : pszDSName, fmt);
2734 1 : CPLErrorV( eErrClass, err_no, szNewFmt, args );
2735 : }
2736 : else
2737 : {
2738 1 : CPLErrorV( eErrClass, err_no, fmt, args );
2739 : }
2740 2 : va_end(args);
2741 2 : }
|