00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024 00025 00026 00027 00028 00029 00030 00030 00030 00030 00031 00032 00033 00034 00035 00036 00037 00038 00039 00040 00041 00042 00043 00044 00045 00046 00047 00048 00049 00050 00051 00052 00053 00054 00055 00056 00057 00058 00059 00060 00061 00062 00063 00064 00065 00066 00067 00068 00069 00070 00071 00072 00073 00074 00075 00076 00077 00078 00079 00080 00081 00082 00083 00084 00085 00086 00087 00088 00089 00090
00091
00092 #include "gdal_priv.h"
00093 #include "cpl_string.h"
00094
00095
00096
00097
00098
00101 GDALRasterBand::GDALRasterBand()
00102
00103 {
00104 poDS = NULL;
00105 nBand = 0;
00106
00107 eAccess = GA_ReadOnly;
00108 nBlockXSize = nBlockYSize = -1;
00109 eDataType = GDT_Byte;
00110
00111 nBlocksPerRow = 0;
00112 nBlocksPerColumn = 0;
00113
00114 papoBlocks = NULL;
00115 }
00116
00117
00118
00119
00120
00124 GDALRasterBand::~GDALRasterBand()
00125
00126 {
00127 FlushCache();
00128
00129 CPLFree( papoBlocks );
00130 }
00131
00132
00133
00134
00135
00201 CPLErr GDALRasterBand::RasterIO( GDALRWFlag eRWFlag,
00202 int nXOff, int nYOff, int nXSize, int nYSize,
00203 void * pData, int nBufXSize, int nBufYSize,
00204 GDALDataType eBufType,
00205 int nPixelSpace,
00206 int nLineSpace )
00207
00208 {
00209
00210
00211
00212
00213 if( nPixelSpace == 0 )
00214 nPixelSpace = GDALGetDataTypeSize( eBufType ) / 8;
00215
00216 if( nLineSpace == 0 )
00217 nLineSpace = nPixelSpace * nBufXSize;
00218
00219
00220
00221
00222 if( nXOff < 0 || nXOff + nXSize > nRasterXSize
00223 || nYOff < 0 || nYOff + nYSize > nRasterYSize )
00224 {
00225 CPLError( CE_Failure, CPLE_IllegalArg,
00226 "Access window out of range in RasterIO(). Requested\n"
00227 "(%d,%d) of size %dx%d on raster of %dx%d.",
00228 nXOff, nYOff, nXSize, nYSize, nRasterXSize, nRasterYSize );
00229 return CE_Failure;
00230 }
00231
00232
00233
00234
00235
00236 if( nXSize < 1 || nYSize < 1 || nBufXSize < 1 || nBufYSize < 1 )
00237 {
00238 CPLDebug( "GDAL",
00239 "RasterIO() skipped for odd window or buffer size.\n"
00240 " Window = (%d,%d)x%dx%d\n"
00241 " Buffer = %dx%d\n",
00242 nXOff, nYOff, nXSize, nYSize,
00243 nBufXSize, nBufYSize );
00244
00245 return CE_None;
00246 }
00247
00248
00249
00250
00251 return( IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
00252 pData, nBufXSize, nBufYSize, eBufType,
00253 nPixelSpace, nLineSpace ) );
00254 }
00255
00256
00257
00258
00259
00260 CPLErr GDALRasterIO( GDALRasterBandH hBand, GDALRWFlag eRWFlag,
00261 int nXOff, int nYOff,
00262 int nXSize, int nYSize,
00263 void * pData,
00264 int nBufXSize, int nBufYSize,
00265 GDALDataType eBufType,
00266 int nPixelSpace,
00267 int nLineSpace )
00268
00269 {
00270 GDALRasterBand *poBand = (GDALRasterBand *) hBand;
00271
00272 return( poBand->RasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
00273 pData, nBufXSize, nBufYSize, eBufType,
00274 nPixelSpace, nLineSpace ) );
00275 }
00276
00277
00278
00279
00280
00363 CPLErr GDALRasterBand::ReadBlock( int nXBlockOff, int nYBlockOff,
00364 void * pImage )
00365
00366 {
00367
00368
00369
00370 CPLAssert( pImage != NULL );
00371
00372 if( nXBlockOff < 0
00373 || nXBlockOff*nBlockXSize >= nRasterXSize )
00374 {
00375 CPLError( CE_Failure, CPLE_IllegalArg,
00376 "Illegal nXBlockOff value (%d) in "
00377 "GDALRasterBand::ReadBlock()\n",
00378 nXBlockOff );
00379
00380 return( CE_Failure );
00381 }
00382
00383 if( nYBlockOff < 0
00384 || nYBlockOff*nBlockYSize >= nRasterYSize )
00385 {
00386 CPLError( CE_Failure, CPLE_IllegalArg,
00387 "Illegal nYBlockOff value (%d) in "
00388 "GDALRasterBand::ReadBlock()\n",
00389 nYBlockOff );
00390
00391 return( CE_Failure );
00392 }
00393
00394
00395
00396
00397 return( IReadBlock( nXBlockOff, nYBlockOff, pImage ) );
00398 }
00399
00400
00401
00402
00403
00404 CPLErr GDALReadBlock( GDALRasterBandH hBand, int nXOff, int nYOff,
00405 void * pData )
00406
00407 {
00408 GDALRasterBand *poBand = (GDALRasterBand *) hBand;
00409
00410 return( poBand->ReadBlock( nXOff, nYOff, pData ) );
00411 }
00412
00413
00414
00415
00416
00417
00418
00419
00420 CPLErr GDALRasterBand::IWriteBlock( int, int, void * )
00421
00422 {
00423 CPLError( CE_Failure, CPLE_NotSupported,
00424 "WriteBlock() not supported for this dataset." );
00425
00426 return( CE_Failure );
00427 }
00428
00429
00430
00431
00432
00463 CPLErr GDALRasterBand::WriteBlock( int nXBlockOff, int nYBlockOff,
00464 void * pImage )
00465
00466 {
00467
00468
00469
00470 CPLAssert( pImage != NULL );
00471
00472 if( nXBlockOff < 0
00473 || nXBlockOff*nBlockXSize >= GetXSize() )
00474 {
00475 CPLError( CE_Failure, CPLE_IllegalArg,
00476 "Illegal nXBlockOff value (%d) in "
00477 "GDALRasterBand::WriteBlock()\n",
00478 nXBlockOff );
00479
00480 return( CE_Failure );
00481 }
00482
00483 if( nYBlockOff < 0
00484 || nYBlockOff*nBlockYSize >= GetYSize() )
00485 {
00486 CPLError( CE_Failure, CPLE_IllegalArg,
00487 "Illegal nYBlockOff value (%d) in "
00488 "GDALRasterBand::WriteBlock()\n",
00489 nYBlockOff );
00490
00491 return( CE_Failure );
00492 }
00493
00494 if( eAccess == GA_ReadOnly )
00495 {
00496 CPLError( CE_Failure, CPLE_NoWriteAccess,
00497 "Attempt to write to read only dataset in"
00498 "GDALRasterBand::WriteBlock().\n" );
00499
00500 return( CE_Failure );
00501 }
00502
00503
00504
00505
00506 return( IWriteBlock( nXBlockOff, nYBlockOff, pImage ) );
00507 }
00508
00509
00510
00511
00512
00513 CPLErr GDALWriteBlock( GDALRasterBandH hBand, int nXOff, int nYOff,
00514 void * pData )
00515
00516 {
00517 GDALRasterBand *poBand = (GDALRasterBand *) hBand;
00518
00519 return( poBand->WriteBlock( nXOff, nYOff, pData ) );
00520 }
00521
00522
00523
00524
00525
00526
00534 GDALDataType GDALRasterBand::GetRasterDataType()
00535
00536 {
00537 return eDataType;
00538 }
00539
00540
00541
00542
00543
00544 GDALDataType GDALGetRasterDataType( GDALRasterBandH hBand )
00545
00546 {
00547 return( ((GDALRasterBand *) hBand)->GetRasterDataType() );
00548 }
00549
00550
00551
00552
00553
00574 void GDALRasterBand::GetBlockSize( int * pnXSize, int *pnYSize )
00575
00576 {
00577 CPLAssert( nBlockXSize > 0 && nBlockYSize > 0 );
00578
00579 if( pnXSize != NULL )
00580 *pnXSize = nBlockXSize;
00581 if( pnYSize != NULL )
00582 *pnYSize = nBlockYSize;
00583 }
00584
00585
00586
00587
00588
00589 void GDALGetBlockSize( GDALRasterBandH hBand, int * pnXSize, int * pnYSize )
00590
00591 {
00592 GDALRasterBand *poBand = (GDALRasterBand *) hBand;
00593
00594 poBand->GetBlockSize( pnXSize, pnYSize );
00595 }
00596
00597
00598
00599
00600
00601 void GDALRasterBand::InitBlockInfo()
00602
00603 {
00604 if( papoBlocks != NULL )
00605 return;
00606
00607 CPLAssert( nBlockXSize > 0 && nBlockYSize > 0 );
00608
00609 nBlocksPerRow = (nRasterXSize+nBlockXSize-1) / nBlockXSize;
00610 nBlocksPerColumn = (nRasterYSize+nBlockYSize-1) / nBlockYSize;
00611
00612 papoBlocks = (GDALRasterBlock **)
00613 CPLCalloc( sizeof(void*), nBlocksPerRow * nBlocksPerColumn );
00614 }
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627 CPLErr GDALRasterBand::AdoptBlock( int nBlockXOff, int nBlockYOff,
00628 GDALRasterBlock * poBlock )
00629
00630 {
00631 int nBlockIndex;
00632
00633 InitBlockInfo();
00634
00635 CPLAssert( nBlockXOff >= 0 && nBlockXOff < nBlocksPerRow );
00636 CPLAssert( nBlockYOff >= 0 && nBlockYOff < nBlocksPerColumn );
00637
00638 nBlockIndex = nBlockXOff + nBlockYOff * nBlocksPerRow;
00639 if( papoBlocks[nBlockIndex] == poBlock )
00640 return( CE_None );
00641
00642 if( papoBlocks[nBlockIndex] != NULL )
00643 FlushBlock( nBlockXOff, nBlockYOff );
00644
00645 papoBlocks[nBlockIndex] = poBlock;
00646 poBlock->Touch();
00647
00648 return( CE_None );
00649 }
00650
00651
00652
00653
00654
00666 CPLErr GDALRasterBand::FlushCache()
00667
00668 {
00669 for( int iY = 0; iY < nBlocksPerColumn; iY++ )
00670 {
00671 for( int iX = 0; iX < nBlocksPerRow; iX++ )
00672 {
00673 if( papoBlocks[iX + iY*nBlocksPerRow] != NULL )
00674 {
00675 CPLErr eErr;
00676
00677 eErr = FlushBlock( iX, iY );
00678
00679 if( eErr != CE_None )
00680 return eErr;
00681 }
00682 }
00683 }
00684
00685 return( CE_None );
00686 }
00687
00688
00689
00690
00691
00692 CPLErr GDALFlushRasterCache( GDALRasterBandH hBand )
00693
00694 {
00695 return ((GDALRasterBand *) hBand)->FlushCache();
00696 }
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708 CPLErr GDALRasterBand::FlushBlock( int nBlockXOff, int nBlockYOff )
00709
00710 {
00711 int nBlockIndex;
00712 GDALRasterBlock *poBlock;
00713 CPLErr eErr = CE_None;
00714
00715 InitBlockInfo();
00716
00717
00718
00719
00720 CPLAssert( nBlockXOff >= 0 && nBlockXOff < nBlocksPerRow );
00721 CPLAssert( nBlockYOff >= 0 && nBlockYOff < nBlocksPerColumn );
00722
00723 nBlockIndex = nBlockXOff + nBlockYOff * nBlocksPerRow;
00724 poBlock = papoBlocks[nBlockIndex];
00725 if( poBlock == NULL )
00726 return( CE_None );
00727
00728
00729
00730
00731 papoBlocks[nBlockIndex] = NULL;
00732
00733
00734
00735
00736 if( poBlock->GetDirty() )
00737 poBlock->Write();
00738
00739
00740
00741
00742 delete poBlock;
00743
00744 return( eErr );
00745 }
00746
00747
00748
00749
00750
00751
00767 GDALRasterBlock * GDALRasterBand::GetBlockRef( int nXBlockOff,
00768 int nYBlockOff )
00769
00770 {
00771 int nBlockIndex;
00772
00773 InitBlockInfo();
00774
00775
00776
00777
00778 if( nXBlockOff < 0 || nXBlockOff >= nBlocksPerRow )
00779 {
00780 CPLError( CE_Failure, CPLE_IllegalArg,
00781 "Illegal nBlockXOff value (%d) in "
00782 "GDALRasterBand::GetBlockRef()\n",
00783 nXBlockOff );
00784
00785 return( NULL );
00786 }
00787
00788 if( nYBlockOff < 0 || nYBlockOff >= nBlocksPerColumn )
00789 {
00790 CPLError( CE_Failure, CPLE_IllegalArg,
00791 "Illegal nBlockYOff value (%d) in "
00792 "GDALRasterBand::GetBlockRef()\n",
00793 nYBlockOff );
00794
00795 return( NULL );
00796 }
00797
00798
00799
00800
00801
00802
00803 nBlockIndex = nXBlockOff + nYBlockOff * nBlocksPerRow;
00804
00805 if( papoBlocks[nBlockIndex] == NULL )
00806 {
00807 GDALRasterBlock *poBlock;
00808
00809 poBlock = new GDALRasterBlock( this, nXBlockOff, nYBlockOff );
00810
00811
00812 if( poBlock->Internalize() != CE_None )
00813 {
00814 delete poBlock;
00815
00816 return( NULL );
00817 }
00818
00819 if( IReadBlock(nXBlockOff,nYBlockOff,poBlock->GetDataRef()) != CE_None)
00820 {
00821 delete poBlock;
00822 return( NULL );
00823 }
00824
00825 AdoptBlock( nXBlockOff, nYBlockOff, poBlock );
00826 }
00827
00828
00829
00830
00831 if( papoBlocks[nBlockIndex] != NULL )
00832 papoBlocks[nBlockIndex]->Touch();
00833
00834 return( papoBlocks[nBlockIndex] );
00835 }
00836
00837
00838
00839
00840
00847 GDALAccess GDALRasterBand::GetAccess()
00848
00849 {
00850 return eAccess;
00851 }
00852
00853
00854
00855
00856
00872 char **GDALRasterBand::GetCategoryNames()
00873
00874 {
00875 return NULL;
00876 }
00877
00878
00879
00880
00881
00898 double GDALRasterBand::GetNoDataValue( int *pbSuccess )
00899
00900 {
00901 if( pbSuccess != NULL )
00902 *pbSuccess = FALSE;
00903
00904 return -1e10;
00905 }
00906
00907
00908
00909
00910
00911 double GDALGetRasterNoDataValue( GDALRasterBandH hBand, int *pbSuccess )
00912
00913 {
00914 return ((GDALRasterBand *) hBand)->GetNoDataValue( pbSuccess );
00915 }
00916
00917
00918
00919
00920
00935 double GDALRasterBand::GetMaximum( int *pbSuccess )
00936
00937 {
00938 if( pbSuccess != NULL )
00939 *pbSuccess = FALSE;
00940
00941 switch( eDataType )
00942 {
00943 case GDT_Byte:
00944 return 255;
00945
00946 case GDT_UInt16:
00947 return 65535;
00948
00949 case GDT_Int16:
00950 case GDT_CInt16:
00951 return 32767;
00952
00953 case GDT_Int32:
00954 case GDT_CInt32:
00955 return 2147483647.0;
00956
00957 case GDT_UInt32:
00958 return 4294967295.0;
00959
00960 case GDT_Float32:
00961 case GDT_CFloat32:
00962 return 4294967295.0;
00963
00964 case GDT_Float64:
00965 case GDT_CFloat64:
00966 return 4294967295.0;
00967
00968 default:
00969 return 4294967295.0;
00970 }
00971 }
00972
00973
00974
00975
00976
00977 double GDALGetRasterMaximum( GDALRasterBandH hBand, int *pbSuccess )
00978
00979 {
00980 return ((GDALRasterBand *) hBand)->GetMaximum( pbSuccess );
00981 }
00982
00983
00984
00985
00986
01001 double GDALRasterBand::GetMinimum( int *pbSuccess )
01002
01003 {
01004 if( pbSuccess != NULL )
01005 *pbSuccess = FALSE;
01006
01007 switch( eDataType )
01008 {
01009 case GDT_Byte:
01010 return 0;
01011
01012 case GDT_UInt16:
01013 return 0;
01014
01015 case GDT_Int16:
01016 return -32768;
01017
01018 case GDT_Int32:
01019 return -2147483648.0;
01020
01021 case GDT_UInt32:
01022 return 0;
01023
01024 case GDT_Float32:
01025 return -4294967295.0;
01026
01027 case GDT_Float64:
01028 return -4294967295.0;
01029
01030 default:
01031 return -4294967295.0;
01032 }
01033 }
01034
01035
01036
01037
01038
01039 double GDALGetRasterMinimum( GDALRasterBandH hBand, int *pbSuccess )
01040
01041 {
01042 return ((GDALRasterBand *) hBand)->GetMinimum( pbSuccess );
01043 }
01044
01045
01046
01047
01048
01061 GDALColorInterp GDALRasterBand::GetColorInterpretation()
01062
01063 {
01064 return GCI_Undefined;
01065 }
01066
01067
01068
01069
01070
01071 GDALColorInterp GDALGetRasterColorInterpretation( GDALRasterBandH hBand )
01072
01073 {
01074 return ((GDALRasterBand *) hBand)->GetColorInterpretation();
01075 }
01076
01077
01078
01079
01080
01093 GDALColorTable *GDALRasterBand::GetColorTable()
01094
01095 {
01096 return NULL;
01097 }
01098
01099
01100
01101
01102
01103 GDALColorTableH GDALGetRasterColorTable( GDALRasterBandH hBand )
01104
01105 {
01106 return (GDALColorTableH) ((GDALRasterBand *) hBand)->GetColorTable();
01107 }
01108
01109
01110
01111
01112
01128 int GDALRasterBand::HasArbitraryOverviews()
01129
01130 {
01131 return FALSE;
01132 }
01133
01134
01135
01136
01137
01138 int GDALHasArbitraryOverviews( GDALRasterBandH hBand )
01139
01140 {
01141 return ((GDALRasterBand *) hBand)->HasArbitraryOverviews();
01142 }
01143
01144
01145
01146
01147
01156 int GDALRasterBand::GetOverviewCount()
01157
01158 {
01159 if( poDS != NULL && poDS->oOvManager.IsInitialized() )
01160 return poDS->oOvManager.GetOverviewCount( nBand );
01161 else
01162 return 0;
01163 }
01164
01165
01166
01167
01168
01169 int GDALGetOverviewCount( GDALRasterBandH hBand )
01170
01171 {
01172 return ((GDALRasterBand *) hBand)->GetOverviewCount();
01173 }
01174
01175
01176
01177
01178
01179
01190 GDALRasterBand * GDALRasterBand::GetOverview( int i )
01191
01192 {
01193 if( poDS != NULL && poDS->oOvManager.IsInitialized() )
01194 return poDS->oOvManager.GetOverview( nBand, i );
01195 else
01196 return NULL;
01197 }
01198
01199
01200
01201
01202
01203 GDALRasterBandH GDALGetOverview( GDALRasterBandH hBand, int i )
01204
01205 {
01206 return (GDALRasterBandH) ((GDALRasterBand *) hBand)->GetOverview(i);
01207 }
01208
01209
01210
01211
01212
01229 CPLErr GDALRasterBand::BuildOverviews( const char *pszResampling,
01230 int nOverviews, int *panOverviewList,
01231 GDALProgressFunc pfnProgress,
01232 void * pProgressData )
01233
01234 {
01235 CPLError( CE_Failure, CPLE_NotSupported,
01236 "BuildOverviews() not supported for this dataset." );
01237
01238 return( CE_Failure );
01239 }
01240
01241
01242
01243
01244
01264 double GDALRasterBand::GetOffset( int *pbSuccess )
01265
01266 {
01267 if( pbSuccess != NULL )
01268 *pbSuccess = FALSE;
01269
01270 return 0.0;
01271 }
01272
01273
01274
01275
01276
01296 double GDALRasterBand::GetScale( int *pbSuccess )
01297
01298 {
01299 if( pbSuccess != NULL )
01300 *pbSuccess = FALSE;
01301
01302 return 1.0;
01303 }
01304
01305
01306
01307
01308
01315 const char *GDALRasterBand::GetDescription()
01316
01317 {
01318 return "";
01319 }
01320
01321
01322
01323
01324
01325
01337 const char *GDALRasterBand::GetUnitType()
01338
01339 {
01340 return "";
01341 }
01342
01343
01344
01345
01346
01355 int GDALRasterBand::GetXSize()
01356
01357 {
01358 return nRasterXSize;
01359 }
01360
01361
01362
01363
01364
01365 int GDALGetRasterBandXSize( GDALRasterBandH hBand )
01366
01367 {
01368 return ((GDALRasterBand *) hBand)->GetXSize();
01369 }
01370
01371
01372
01373
01374
01383 int GDALRasterBand::GetYSize()
01384
01385 {
01386 return nRasterYSize;
01387 }
01388
01389
01390
01391
01392
01393 int GDALGetRasterBandYSize( GDALRasterBandH hBand )
01394
01395 {
01396 return ((GDALRasterBand *) hBand)->GetYSize();
01397 }
01398
01399
01400
01401
01402
01439 CPLErr GDALRasterBand::GetHistogram( double dfMin, double dfMax,
01440 int nBuckets, int *panHistogram,
01441 int bIncludeOutOfRange, int bApproxOK,
01442 GDALProgressFunc pfnProgress,
01443 void *pProgressData )
01444
01445 {
01446 CPLAssert( pfnProgress != NULL );
01447
01448
01449
01450
01451 if( bApproxOK && GetOverviewCount() > 0 )
01452 {
01453 double dfBestPixels = GetXSize() * GetYSize();
01454 GDALRasterBand *poBestOverview = NULL;
01455
01456 for( int i = 0; i < GetOverviewCount(); i++ )
01457 {
01458 GDALRasterBand *poOverview = GetOverview(i);
01459 double dfPixels;
01460
01461 dfPixels = poOverview->GetXSize() * poOverview->GetYSize();
01462 if( dfPixels < dfBestPixels )
01463 {
01464 dfBestPixels = dfPixels;
01465 poBestOverview = poOverview;
01466 }
01467
01468 if( poBestOverview != NULL )
01469 return poBestOverview->
01470 GetHistogram( dfMin, dfMax, nBuckets, panHistogram,
01471 bIncludeOutOfRange, bApproxOK,
01472 pfnProgress, pProgressData );
01473 }
01474 }
01475
01476
01477
01478
01479
01480 int nBlockXSize, nBlockYSize;
01481 int nBlocksPerRow, nBlocksPerColumn;
01482 int nSampleRate;
01483 double dfScale;
01484
01485 GetBlockSize( &nBlockXSize, &nBlockYSize );
01486 nBlocksPerRow = (GetXSize() + nBlockXSize - 1) / nBlockXSize;
01487 nBlocksPerColumn = (GetYSize() + nBlockYSize - 1) / nBlockYSize;
01488
01489 if( bApproxOK )
01490 nSampleRate =
01491 (int) MAX(1,sqrt((double) nBlocksPerRow * nBlocksPerColumn));
01492 else
01493 nSampleRate = 1;
01494
01495 dfScale = nBuckets / (dfMax - dfMin);
01496
01497
01498
01499
01500 memset( panHistogram, 0, sizeof(int) * nBuckets );
01501 for( int iSampleBlock = 0;
01502 iSampleBlock < nBlocksPerRow * nBlocksPerColumn;
01503 iSampleBlock += nSampleRate )
01504 {
01505 double dfValue = 0.0;
01506 int iXBlock, iYBlock, nXCheck, nYCheck;
01507 GDALRasterBlock *poBlock;
01508
01509 if( !pfnProgress( iSampleBlock/(double)nBlocksPerRow*nBlocksPerColumn,
01510 NULL, pProgressData ) )
01511 return CE_Failure;
01512
01513 iYBlock = iSampleBlock / nBlocksPerRow;
01514 iXBlock = iSampleBlock - nBlocksPerRow * iYBlock;
01515
01516 poBlock = GetBlockRef( iXBlock, iYBlock );
01517 if( poBlock == NULL )
01518 return CE_Failure;
01519
01520 if( (iXBlock+1) * nBlockXSize > GetXSize() )
01521 nXCheck = GetXSize() - iXBlock * nBlockXSize;
01522 else
01523 nXCheck = nBlockXSize;
01524
01525 if( (iYBlock+1) * nBlockYSize > GetYSize() )
01526 nYCheck = GetYSize() - iYBlock * nBlockYSize;
01527 else
01528 nYCheck = nBlockYSize;
01529
01530
01531 if( poBlock->GetDataType() == GDT_Byte
01532 && dfScale == 1.0 && (dfMin >= -0.5 && dfMin <= 0.5)
01533 && nYCheck == nBlockYSize && nXCheck == nBlockXSize
01534 && nBuckets == 256 )
01535 {
01536 int nPixels = nXCheck * nYCheck;
01537 GByte *pabyData = (GByte *) poBlock->GetDataRef();
01538
01539 for( int i = 0; i < nPixels; i++ )
01540 panHistogram[pabyData[i]]++;
01541
01542 continue;
01543 }
01544
01545
01546 for( int iY = 0; iY < nYCheck; iY++ )
01547 {
01548 for( int iX = 0; iX < nXCheck; iX++ )
01549 {
01550 int iOffset = iX + iY * nBlockXSize;
01551 int nIndex;
01552
01553 switch( poBlock->GetDataType() )
01554 {
01555 case GDT_Byte:
01556 dfValue = ((GByte *) poBlock->GetDataRef())[iOffset];
01557 break;
01558
01559 case GDT_UInt16:
01560 dfValue = ((GUInt16 *) poBlock->GetDataRef())[iOffset];
01561 break;
01562 case GDT_Int16:
01563 dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset];
01564 break;
01565 case GDT_UInt32:
01566 dfValue = ((GUInt32 *) poBlock->GetDataRef())[iOffset];
01567 break;
01568 case GDT_Int32:
01569 dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset];
01570 break;
01571 case GDT_Float32:
01572 dfValue = ((float *) poBlock->GetDataRef())[iOffset];
01573 break;
01574 case GDT_Float64:
01575 dfValue = ((double *) poBlock->GetDataRef())[iOffset];
01576 break;
01577 default:
01578 CPLAssert( FALSE );
01579 return CE_Failure;
01580 }
01581
01582 nIndex = (int) floor((dfValue - dfMin) * dfScale);
01583
01584 if( nIndex < 0 )
01585 {
01586 if( bIncludeOutOfRange )
01587 panHistogram[0]++;
01588 }
01589 else if( nIndex >= nBuckets )
01590 {
01591 if( bIncludeOutOfRange )
01592 panHistogram[nBuckets-1]++;
01593 }
01594 else
01595 {
01596 panHistogram[nIndex]++;
01597 }
01598 }
01599 }
01600 }
01601
01602 pfnProgress( 1.0, NULL, pProgressData );
01603
01604 return CE_None;
01605 }
01606
01607
01608
01609
01610
01611 CPLErr GDALGetRasterHistogram( GDALRasterBandH hBand,
01612 double dfMin, double dfMax,
01613 int nBuckets, int *panHistogram,
01614 int bIncludeOutOfRange, int bApproxOK,
01615 GDALProgressFunc pfnProgress,
01616 void *pProgressData )
01617
01618 {
01619 return ((GDALRasterBand *) hBand)->
01620 GetHistogram( dfMin, dfMax, nBuckets, panHistogram,
01621 bIncludeOutOfRange, bApproxOK,
01622 pfnProgress, pProgressData );
01623 }