1 : /******************************************************************************
2 : * $Id: vrtrasterband.cpp 17852 2009-10-18 11:15:09Z rouault $
3 : *
4 : * Project: Virtual GDAL Datasets
5 : * Purpose: Implementation of VRTRasterBand
6 : * Author: Frank Warmerdam <warmerdam@pobox.com>
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2001, Frank Warmerdam <warmerdam@pobox.com>
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 "vrtdataset.h"
31 : #include "cpl_minixml.h"
32 : #include "cpl_string.h"
33 :
34 : CPL_CVSID("$Id: vrtrasterband.cpp 17852 2009-10-18 11:15:09Z rouault $");
35 :
36 : /************************************************************************/
37 : /* ==================================================================== */
38 : /* VRTRasterBand */
39 : /* ==================================================================== */
40 : /************************************************************************/
41 :
42 : /************************************************************************/
43 : /* VRTRasterBand() */
44 : /************************************************************************/
45 :
46 339 : VRTRasterBand::VRTRasterBand()
47 :
48 : {
49 339 : Initialize( 0, 0 );
50 339 : }
51 :
52 : /************************************************************************/
53 : /* Initialize() */
54 : /************************************************************************/
55 :
56 678 : void VRTRasterBand::Initialize( int nXSize, int nYSize )
57 :
58 : {
59 678 : poDS = NULL;
60 678 : nBand = 0;
61 678 : eAccess = GA_ReadOnly;
62 678 : eDataType = GDT_Byte;
63 :
64 678 : nRasterXSize = nXSize;
65 678 : nRasterYSize = nYSize;
66 :
67 678 : nBlockXSize = MIN(128,nXSize);
68 678 : nBlockYSize = MIN(128,nYSize);
69 :
70 678 : bNoDataValueSet = FALSE;
71 678 : dfNoDataValue = -10000.0;
72 678 : poColorTable = NULL;
73 678 : eColorInterp = GCI_Undefined;
74 :
75 678 : pszUnitType = NULL;
76 678 : papszCategoryNames = NULL;
77 678 : dfOffset = 0.0;
78 678 : dfScale = 1.0;
79 :
80 678 : psSavedHistograms = NULL;
81 678 : }
82 :
83 : /************************************************************************/
84 : /* ~VRTRasterBand() */
85 : /************************************************************************/
86 :
87 339 : VRTRasterBand::~VRTRasterBand()
88 :
89 : {
90 339 : CPLFree( pszUnitType );
91 :
92 339 : if( poColorTable != NULL )
93 10 : delete poColorTable;
94 :
95 339 : CSLDestroy( papszCategoryNames );
96 339 : if( psSavedHistograms != NULL )
97 0 : CPLDestroyXMLNode( psSavedHistograms );
98 339 : }
99 :
100 : /************************************************************************/
101 : /* CopyCommonInfoFrom() */
102 : /* */
103 : /* Copy common metadata, pixel descriptions, and color */
104 : /* interpretation from the provided source band. */
105 : /************************************************************************/
106 :
107 48 : CPLErr VRTRasterBand::CopyCommonInfoFrom( GDALRasterBand * poSrcBand )
108 :
109 : {
110 : int bSuccess;
111 : double dfNoData;
112 :
113 48 : SetMetadata( poSrcBand->GetMetadata() );
114 48 : SetColorTable( poSrcBand->GetColorTable() );
115 48 : SetColorInterpretation(poSrcBand->GetColorInterpretation());
116 48 : if( strlen(poSrcBand->GetDescription()) > 0 )
117 0 : SetDescription( poSrcBand->GetDescription() );
118 48 : dfNoData = poSrcBand->GetNoDataValue( &bSuccess );
119 48 : if( bSuccess )
120 1 : SetNoDataValue( dfNoData );
121 :
122 48 : SetOffset( poSrcBand->GetOffset() );
123 48 : SetScale( poSrcBand->GetScale() );
124 48 : SetCategoryNames( poSrcBand->GetCategoryNames() );
125 48 : if( !EQUAL(poSrcBand->GetUnitType(),"") )
126 1 : SetUnitType( poSrcBand->GetUnitType() );
127 :
128 48 : return CE_None;
129 : }
130 :
131 : /************************************************************************/
132 : /* SetMetadata() */
133 : /************************************************************************/
134 :
135 48 : CPLErr VRTRasterBand::SetMetadata( char **papszMetadata,
136 : const char *pszDomain )
137 :
138 : {
139 48 : ((VRTDataset *) poDS)->SetNeedsFlush();
140 :
141 48 : return GDALRasterBand::SetMetadata( papszMetadata, pszDomain );
142 : }
143 :
144 : /************************************************************************/
145 : /* SetMetadataItem() */
146 : /************************************************************************/
147 :
148 10 : CPLErr VRTRasterBand::SetMetadataItem( const char *pszName,
149 : const char *pszValue,
150 : const char *pszDomain )
151 :
152 : {
153 10 : ((VRTDataset *) poDS)->SetNeedsFlush();
154 :
155 10 : return GDALRasterBand::SetMetadataItem( pszName, pszValue, pszDomain );
156 : }
157 :
158 : /************************************************************************/
159 : /* GetUnitType() */
160 : /************************************************************************/
161 :
162 84 : const char *VRTRasterBand::GetUnitType()
163 :
164 : {
165 84 : if( pszUnitType == NULL )
166 81 : return "";
167 : else
168 3 : return pszUnitType;
169 : }
170 :
171 : /************************************************************************/
172 : /* SetUnitType() */
173 : /************************************************************************/
174 :
175 217 : CPLErr VRTRasterBand::SetUnitType( const char *pszNewValue )
176 :
177 : {
178 217 : CPLFree( pszUnitType );
179 :
180 217 : if( pszNewValue == NULL )
181 216 : pszUnitType = NULL;
182 : else
183 1 : pszUnitType = CPLStrdup(pszNewValue);
184 :
185 217 : return CE_None;
186 : }
187 :
188 : /************************************************************************/
189 : /* GetOffset() */
190 : /************************************************************************/
191 :
192 150 : double VRTRasterBand::GetOffset( int *pbSuccess )
193 :
194 : {
195 150 : if( pbSuccess != NULL )
196 145 : *pbSuccess = TRUE;
197 :
198 150 : return dfOffset;
199 : }
200 :
201 : /************************************************************************/
202 : /* SetOffset() */
203 : /************************************************************************/
204 :
205 264 : CPLErr VRTRasterBand::SetOffset( double dfNewOffset )
206 :
207 : {
208 264 : dfOffset = dfNewOffset;
209 264 : return CE_None;
210 : }
211 :
212 : /************************************************************************/
213 : /* GetScale() */
214 : /************************************************************************/
215 :
216 150 : double VRTRasterBand::GetScale( int *pbSuccess )
217 :
218 : {
219 150 : if( pbSuccess != NULL )
220 78 : *pbSuccess = TRUE;
221 :
222 150 : return dfScale;
223 : }
224 :
225 : /************************************************************************/
226 : /* SetScale() */
227 : /************************************************************************/
228 :
229 264 : CPLErr VRTRasterBand::SetScale( double dfNewScale )
230 :
231 : {
232 264 : dfScale = dfNewScale;
233 264 : return CE_None;
234 : }
235 :
236 : /************************************************************************/
237 : /* GetCategoryNames() */
238 : /************************************************************************/
239 :
240 6 : char **VRTRasterBand::GetCategoryNames()
241 :
242 : {
243 6 : return papszCategoryNames;
244 : }
245 :
246 : /************************************************************************/
247 : /* SetCategoryNames() */
248 : /************************************************************************/
249 :
250 48 : CPLErr VRTRasterBand::SetCategoryNames( char ** papszNewNames )
251 :
252 : {
253 48 : CSLDestroy( papszCategoryNames );
254 48 : papszCategoryNames = CSLDuplicate( papszNewNames );
255 :
256 48 : return CE_None;
257 : }
258 :
259 : /************************************************************************/
260 : /* XMLInit() */
261 : /************************************************************************/
262 :
263 216 : CPLErr VRTRasterBand::XMLInit( CPLXMLNode * psTree,
264 : const char *pszVRTPath )
265 :
266 : {
267 : /* -------------------------------------------------------------------- */
268 : /* Validate a bit. */
269 : /* -------------------------------------------------------------------- */
270 216 : if( psTree == NULL || psTree->eType != CXT_Element
271 : || !EQUAL(psTree->pszValue,"VRTRasterBand") )
272 : {
273 : CPLError( CE_Failure, CPLE_AppDefined,
274 0 : "Invalid node passed to VRTRasterBand::XMLInit()." );
275 0 : return CE_Failure;
276 : }
277 :
278 : /* -------------------------------------------------------------------- */
279 : /* Set the band if provided as an attribute. */
280 : /* -------------------------------------------------------------------- */
281 216 : if( CPLGetXMLValue( psTree, "band", NULL) != NULL )
282 216 : nBand = atoi(CPLGetXMLValue( psTree, "band", "0"));
283 :
284 : /* -------------------------------------------------------------------- */
285 : /* Set the band if provided as an attribute. */
286 : /* -------------------------------------------------------------------- */
287 216 : const char *pszDataType = CPLGetXMLValue( psTree, "dataType", NULL);
288 216 : if( pszDataType != NULL )
289 : {
290 216 : eDataType = GDALGetDataTypeByName(pszDataType);
291 : }
292 :
293 : /* -------------------------------------------------------------------- */
294 : /* Apply any band level metadata. */
295 : /* -------------------------------------------------------------------- */
296 216 : oMDMD.XMLInit( psTree, TRUE );
297 :
298 : /* -------------------------------------------------------------------- */
299 : /* Collect various other items of metadata. */
300 : /* -------------------------------------------------------------------- */
301 216 : SetDescription( CPLGetXMLValue( psTree, "Description", "" ) );
302 :
303 216 : if( CPLGetXMLValue( psTree, "NoDataValue", NULL ) != NULL )
304 38 : SetNoDataValue( atof(CPLGetXMLValue( psTree, "NoDataValue", "0" )) );
305 :
306 216 : SetUnitType( CPLGetXMLValue( psTree, "UnitType", NULL ) );
307 :
308 216 : SetOffset( atof(CPLGetXMLValue( psTree, "Offset", "0.0" )) );
309 216 : SetScale( atof(CPLGetXMLValue( psTree, "Scale", "1.0" )) );
310 :
311 216 : if( CPLGetXMLValue( psTree, "ColorInterp", NULL ) != NULL )
312 : {
313 160 : const char *pszInterp = CPLGetXMLValue( psTree, "ColorInterp", NULL );
314 160 : SetColorInterpretation(GDALGetColorInterpretationByName(pszInterp));
315 : }
316 :
317 : /* -------------------------------------------------------------------- */
318 : /* Category names. */
319 : /* -------------------------------------------------------------------- */
320 216 : if( CPLGetXMLNode( psTree, "CategoryNames" ) != NULL )
321 : {
322 : CPLXMLNode *psEntry;
323 :
324 0 : CSLDestroy( papszCategoryNames );
325 0 : papszCategoryNames = NULL;
326 :
327 0 : for( psEntry = CPLGetXMLNode( psTree, "CategoryNames" )->psChild;
328 : psEntry != NULL; psEntry = psEntry->psNext )
329 : {
330 0 : if( psEntry->eType != CXT_Element
331 : || !EQUAL(psEntry->pszValue,"Category")
332 : || (psEntry->psChild != NULL && psEntry->psChild->eType != CXT_Text) )
333 0 : continue;
334 :
335 : papszCategoryNames = CSLAddString( papszCategoryNames,
336 0 : (psEntry->psChild) ? psEntry->psChild->pszValue : "");
337 : }
338 : }
339 :
340 : /* -------------------------------------------------------------------- */
341 : /* Collect a color table. */
342 : /* -------------------------------------------------------------------- */
343 216 : if( CPLGetXMLNode( psTree, "ColorTable" ) != NULL )
344 : {
345 : CPLXMLNode *psEntry;
346 3 : GDALColorTable oTable;
347 3 : int iEntry = 0;
348 :
349 517 : for( psEntry = CPLGetXMLNode( psTree, "ColorTable" )->psChild;
350 : psEntry != NULL; psEntry = psEntry->psNext )
351 : {
352 : GDALColorEntry sCEntry;
353 :
354 514 : sCEntry.c1 = (short) atoi(CPLGetXMLValue( psEntry, "c1", "0" ));
355 514 : sCEntry.c2 = (short) atoi(CPLGetXMLValue( psEntry, "c2", "0" ));
356 514 : sCEntry.c3 = (short) atoi(CPLGetXMLValue( psEntry, "c3", "0" ));
357 514 : sCEntry.c4 = (short) atoi(CPLGetXMLValue( psEntry, "c4", "255" ));
358 :
359 514 : oTable.SetColorEntry( iEntry++, &sCEntry );
360 : }
361 :
362 3 : SetColorTable( &oTable );
363 : }
364 :
365 : /* -------------------------------------------------------------------- */
366 : /* Histograms */
367 : /* -------------------------------------------------------------------- */
368 216 : CPLXMLNode *psHist = CPLGetXMLNode( psTree, "Histograms" );
369 216 : if( psHist != NULL )
370 : {
371 0 : CPLXMLNode *psNext = psHist->psNext;
372 0 : psHist->psNext = NULL;
373 :
374 0 : psSavedHistograms = CPLCloneXMLTree( psHist );
375 0 : psHist->psNext = psNext;
376 : }
377 :
378 216 : return CE_None;
379 : }
380 :
381 : /************************************************************************/
382 : /* SerializeToXML() */
383 : /************************************************************************/
384 :
385 85 : CPLXMLNode *VRTRasterBand::SerializeToXML( const char *pszVRTPath )
386 :
387 : {
388 : CPLXMLNode *psTree;
389 :
390 85 : psTree = CPLCreateXMLNode( NULL, CXT_Element, "VRTRasterBand" );
391 :
392 : /* -------------------------------------------------------------------- */
393 : /* Various kinds of metadata. */
394 : /* -------------------------------------------------------------------- */
395 : CPLXMLNode *psMD;
396 :
397 : CPLSetXMLValue( psTree, "#dataType",
398 85 : GDALGetDataTypeName( GetRasterDataType() ) );
399 :
400 85 : if( nBand > 0 )
401 85 : CPLSetXMLValue( psTree, "#band", CPLSPrintf( "%d", GetBand() ) );
402 :
403 85 : psMD = oMDMD.Serialize();
404 85 : if( psMD != NULL )
405 31 : CPLAddXMLChild( psTree, psMD );
406 :
407 85 : if( strlen(GetDescription()) > 0 )
408 0 : CPLSetXMLValue( psTree, "Description", GetDescription() );
409 :
410 85 : if( bNoDataValueSet )
411 : CPLSetXMLValue( psTree, "NoDataValue",
412 4 : CPLSPrintf( "%.14E", dfNoDataValue ) );
413 :
414 85 : if( pszUnitType != NULL )
415 0 : CPLSetXMLValue( psTree, "UnitType", pszUnitType );
416 :
417 85 : if( dfOffset != 0.0 )
418 : CPLSetXMLValue( psTree, "Offset",
419 0 : CPLSPrintf( "%.16g", dfOffset ) );
420 :
421 85 : if( dfScale != 1.0 )
422 : CPLSetXMLValue( psTree, "Scale",
423 0 : CPLSPrintf( "%.16g", dfScale ) );
424 :
425 85 : if( eColorInterp != GCI_Undefined )
426 : CPLSetXMLValue( psTree, "ColorInterp",
427 44 : GDALGetColorInterpretationName( eColorInterp ) );
428 :
429 : /* -------------------------------------------------------------------- */
430 : /* Category names. */
431 : /* -------------------------------------------------------------------- */
432 85 : if( papszCategoryNames != NULL )
433 : {
434 : CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element,
435 0 : "CategoryNames" );
436 :
437 0 : for( int iEntry=0; papszCategoryNames[iEntry] != NULL; iEntry++ )
438 : {
439 : CPLCreateXMLElementAndValue( psCT_XML, "Category",
440 0 : papszCategoryNames[iEntry] );
441 : }
442 : }
443 :
444 : /* -------------------------------------------------------------------- */
445 : /* Histograms. */
446 : /* -------------------------------------------------------------------- */
447 85 : if( psSavedHistograms != NULL )
448 0 : CPLAddXMLChild( psTree, CPLCloneXMLTree( psSavedHistograms ) );
449 :
450 : /* -------------------------------------------------------------------- */
451 : /* Color Table. */
452 : /* -------------------------------------------------------------------- */
453 85 : if( poColorTable != NULL )
454 : {
455 : CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element,
456 2 : "ColorTable" );
457 :
458 260 : for( int iEntry=0; iEntry < poColorTable->GetColorEntryCount();
459 : iEntry++ )
460 : {
461 : GDALColorEntry sEntry;
462 : CPLXMLNode *psEntry_XML = CPLCreateXMLNode( psCT_XML, CXT_Element,
463 258 : "Entry" );
464 :
465 258 : poColorTable->GetColorEntryAsRGB( iEntry, &sEntry );
466 :
467 258 : CPLSetXMLValue( psEntry_XML, "#c1", CPLSPrintf("%d",sEntry.c1) );
468 258 : CPLSetXMLValue( psEntry_XML, "#c2", CPLSPrintf("%d",sEntry.c2) );
469 258 : CPLSetXMLValue( psEntry_XML, "#c3", CPLSPrintf("%d",sEntry.c3) );
470 258 : CPLSetXMLValue( psEntry_XML, "#c4", CPLSPrintf("%d",sEntry.c4) );
471 : }
472 : }
473 :
474 85 : return psTree;
475 : }
476 :
477 : /************************************************************************/
478 : /* SetNoDataValue() */
479 : /************************************************************************/
480 :
481 49 : CPLErr VRTRasterBand::SetNoDataValue( double dfNewValue )
482 :
483 : {
484 49 : bNoDataValueSet = TRUE;
485 49 : dfNoDataValue = dfNewValue;
486 :
487 49 : ((VRTDataset *)poDS)->SetNeedsFlush();
488 :
489 49 : return CE_None;
490 : }
491 :
492 : /************************************************************************/
493 : /* GetNoDataValue() */
494 : /************************************************************************/
495 :
496 268 : double VRTRasterBand::GetNoDataValue( int *pbSuccess )
497 :
498 : {
499 268 : if( pbSuccess )
500 238 : *pbSuccess = bNoDataValueSet;
501 :
502 268 : return dfNoDataValue;
503 : }
504 :
505 : /************************************************************************/
506 : /* SetColorTable() */
507 : /************************************************************************/
508 :
509 57 : CPLErr VRTRasterBand::SetColorTable( GDALColorTable *poTableIn )
510 :
511 : {
512 57 : if( poColorTable != NULL )
513 : {
514 0 : delete poColorTable;
515 0 : poColorTable = NULL;
516 : }
517 :
518 57 : if( poTableIn )
519 : {
520 10 : poColorTable = poTableIn->Clone();
521 10 : eColorInterp = GCI_PaletteIndex;
522 : }
523 :
524 57 : ((VRTDataset *)poDS)->SetNeedsFlush();
525 :
526 57 : return CE_None;
527 : }
528 :
529 : /************************************************************************/
530 : /* GetColorTable() */
531 : /************************************************************************/
532 :
533 170 : GDALColorTable *VRTRasterBand::GetColorTable()
534 :
535 : {
536 170 : return poColorTable;
537 : }
538 :
539 : /************************************************************************/
540 : /* SetColorInterpretation() */
541 : /************************************************************************/
542 :
543 248 : CPLErr VRTRasterBand::SetColorInterpretation( GDALColorInterp eInterpIn )
544 :
545 : {
546 248 : ((VRTDataset *)poDS)->SetNeedsFlush();
547 :
548 248 : eColorInterp = eInterpIn;
549 :
550 248 : return CE_None;
551 : }
552 :
553 : /************************************************************************/
554 : /* GetColorInterpretation() */
555 : /************************************************************************/
556 :
557 200 : GDALColorInterp VRTRasterBand::GetColorInterpretation()
558 :
559 : {
560 200 : return eColorInterp;
561 : }
562 :
563 : /************************************************************************/
564 : /* GetHistogram() */
565 : /************************************************************************/
566 :
567 0 : CPLErr VRTRasterBand::GetHistogram( double dfMin, double dfMax,
568 : int nBuckets, int * panHistogram,
569 : int bIncludeOutOfRange, int bApproxOK,
570 : GDALProgressFunc pfnProgress,
571 : void *pProgressData )
572 :
573 : {
574 : /* -------------------------------------------------------------------- */
575 : /* Check if we have a matching histogram. */
576 : /* -------------------------------------------------------------------- */
577 : CPLXMLNode *psHistItem;
578 :
579 : psHistItem = PamFindMatchingHistogram( psSavedHistograms,
580 : dfMin, dfMax, nBuckets,
581 0 : bIncludeOutOfRange, bApproxOK );
582 0 : if( psHistItem != NULL )
583 : {
584 0 : int *panTempHist = NULL;
585 :
586 0 : if( PamParseHistogram( psHistItem, &dfMin, &dfMax, &nBuckets,
587 : &panTempHist,
588 : &bIncludeOutOfRange, &bApproxOK ) )
589 : {
590 0 : memcpy( panHistogram, panTempHist, sizeof(int) * nBuckets );
591 0 : CPLFree( panTempHist );
592 0 : return CE_None;
593 : }
594 : }
595 :
596 : /* -------------------------------------------------------------------- */
597 : /* We don't have an existing histogram matching the request, so */
598 : /* generate one manually. */
599 : /* -------------------------------------------------------------------- */
600 : CPLErr eErr;
601 :
602 : eErr = GDALRasterBand::GetHistogram( dfMin, dfMax,
603 : nBuckets, panHistogram,
604 : bIncludeOutOfRange, bApproxOK,
605 0 : pfnProgress, pProgressData );
606 :
607 : /* -------------------------------------------------------------------- */
608 : /* Save an XML description of this histogram. */
609 : /* -------------------------------------------------------------------- */
610 0 : if( eErr == CE_None )
611 : {
612 : CPLXMLNode *psXMLHist;
613 :
614 : psXMLHist = PamHistogramToXMLTree( dfMin, dfMax, nBuckets,
615 : panHistogram,
616 0 : bIncludeOutOfRange, bApproxOK );
617 0 : if( psXMLHist != NULL )
618 : {
619 0 : ((VRTDataset *) poDS)->SetNeedsFlush();
620 :
621 0 : if( psSavedHistograms == NULL )
622 : psSavedHistograms = CPLCreateXMLNode( NULL, CXT_Element,
623 0 : "Histograms" );
624 :
625 0 : CPLAddXMLChild( psSavedHistograms, psXMLHist );
626 : }
627 : }
628 :
629 0 : return eErr;
630 : }
631 :
632 : /************************************************************************/
633 : /* SetDefaultHistogram() */
634 : /************************************************************************/
635 :
636 0 : CPLErr VRTRasterBand::SetDefaultHistogram( double dfMin, double dfMax,
637 : int nBuckets, int *panHistogram)
638 :
639 : {
640 : CPLXMLNode *psNode;
641 :
642 : /* -------------------------------------------------------------------- */
643 : /* Do we have a matching histogram we should replace? */
644 : /* -------------------------------------------------------------------- */
645 : psNode = PamFindMatchingHistogram( psSavedHistograms,
646 : dfMin, dfMax, nBuckets,
647 0 : TRUE, TRUE );
648 0 : if( psNode != NULL )
649 : {
650 : /* blow this one away */
651 0 : CPLRemoveXMLChild( psSavedHistograms, psNode );
652 0 : CPLDestroyXMLNode( psNode );
653 : }
654 :
655 : /* -------------------------------------------------------------------- */
656 : /* Translate into a histogram XML tree. */
657 : /* -------------------------------------------------------------------- */
658 : CPLXMLNode *psHistItem;
659 :
660 : psHistItem = PamHistogramToXMLTree( dfMin, dfMax, nBuckets,
661 0 : panHistogram, TRUE, FALSE );
662 :
663 : /* -------------------------------------------------------------------- */
664 : /* Insert our new default histogram at the front of the */
665 : /* histogram list so that it will be the default histogram. */
666 : /* -------------------------------------------------------------------- */
667 0 : ((VRTDataset *) poDS)->SetNeedsFlush();
668 :
669 0 : if( psSavedHistograms == NULL )
670 : psSavedHistograms = CPLCreateXMLNode( NULL, CXT_Element,
671 0 : "Histograms" );
672 :
673 0 : psHistItem->psNext = psSavedHistograms->psChild;
674 0 : psSavedHistograms->psChild = psHistItem;
675 :
676 0 : return CE_None;
677 : }
678 :
679 : /************************************************************************/
680 : /* GetDefaultHistogram() */
681 : /************************************************************************/
682 :
683 : CPLErr
684 0 : VRTRasterBand::GetDefaultHistogram( double *pdfMin, double *pdfMax,
685 : int *pnBuckets, int **ppanHistogram,
686 : int bForce,
687 : GDALProgressFunc pfnProgress,
688 : void *pProgressData )
689 :
690 : {
691 0 : if( psSavedHistograms != NULL )
692 : {
693 : CPLXMLNode *psXMLHist;
694 :
695 0 : for( psXMLHist = psSavedHistograms->psChild;
696 : psXMLHist != NULL; psXMLHist = psXMLHist->psNext )
697 : {
698 : int bApprox, bIncludeOutOfRange;
699 :
700 0 : if( psXMLHist->eType != CXT_Element
701 : || !EQUAL(psXMLHist->pszValue,"HistItem") )
702 0 : continue;
703 :
704 0 : if( PamParseHistogram( psXMLHist, pdfMin, pdfMax, pnBuckets,
705 : ppanHistogram, &bIncludeOutOfRange,
706 : &bApprox ) )
707 0 : return CE_None;
708 : else
709 0 : return CE_Failure;
710 : }
711 : }
712 :
713 : return GDALRasterBand::GetDefaultHistogram( pdfMin, pdfMax, pnBuckets,
714 : ppanHistogram, bForce,
715 0 : pfnProgress,pProgressData);
716 : }
717 :
718 : /************************************************************************/
719 : /* GetFileList() */
720 : /************************************************************************/
721 :
722 0 : void VRTRasterBand::GetFileList(char*** ppapszFileList, int *pnSize,
723 : int *pnMaxSize, CPLHashSet* hSetFiles)
724 : {
725 0 : }
|