00001 /******************************************************************************
00002 * $Id: gdalrasterband_cpp-source.html,v 1.13 2002/12/21 19:13:13 warmerda Exp $
00003 *
00004 * Project: GDAL Core
00005 * Purpose: Base class for format specific band class implementation. This
00006 * base class provides default implementation for many methods.
00007 * Author: Frank Warmerdam, warmerda@home.com
00008 *
00009 ******************************************************************************
00010 * Copyright (c) 1998, Frank Warmerdam
00011 *
00012 * Permission is hereby granted, free of charge, to any person obtaining a
00013 * copy of this software and associated documentation files (the "Software"),
00014 * to deal in the Software without restriction, including without limitation
00015 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00016 * and/or sell copies of the Software, and to permit persons to whom the
00017 * Software is furnished to do so, subject to the following conditions:
00018 *
00019 * The above copyright notice and this permission notice shall be included
00020 * in all copies or substantial portions of the Software.
00021 *
00022 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00023 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00024 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00025 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00026 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00027 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00028 * DEALINGS IN THE SOFTWARE.
00029 ******************************************************************************
00030 * $Log: gdalrasterband_cpp-source.html,v $
00030 * Revision 1.13 2002/12/21 19:13:13 warmerda
00030 * updated
00030 *
00031 * Revision 1.35 2002/12/18 15:19:26 warmerda
00032 * added errors in some unimplemented methods
00033 *
00034 * Revision 1.34 2002/11/11 16:02:06 dron
00035 * More error messages added.
00036 *
00037 * Revision 1.33 2002/10/17 17:55:31 warmerda
00038 * Minor improvement to RasterIO() docs.
00039 *
00040 * Revision 1.32 2002/09/15 15:32:50 dron
00041 * Added InitBlockInfo() call to ReadBlock() and WriteBlock() functions.
00042 *
00043 * Revision 1.31 2002/08/14 12:33:34 warmerda
00044 * Validate eRWFlag.
00045 *
00046 * Revision 1.30 2002/07/09 20:33:12 warmerda
00047 * expand tabs
00048 *
00049 * Revision 1.29 2002/05/29 15:58:26 warmerda
00050 * removed GetDescription(), added SetColorInterpretation()
00051 *
00052 * Revision 1.28 2002/05/28 18:55:08 warmerda
00053 * added GetDataset()
00054 *
00055 * Revision 1.27 2002/03/01 14:29:09 warmerda
00056 * added GetBand() method on GDALRasterBand
00057 *
00058 * Revision 1.26 2001/12/07 15:29:45 warmerda
00059 * added InitBlockInfo() in GetHistogram()
00060 *
00061 * Revision 1.25 2001/10/18 14:35:22 warmerda
00062 * avoid conflicts between parameters and member data
00063 *
00064 * Revision 1.24 2001/10/17 16:20:45 warmerda
00065 * make histograming work with complex data (r(treat as magnitude)
00066 *
00067 * Revision 1.23 2001/07/18 04:04:30 warmerda
00068 * added CPL_CVSID
00069 *
00070 * Revision 1.22 2001/07/05 13:13:40 warmerda
00071 * added UnitType from C support
00072 *
00073 * Revision 1.21 2000/10/06 15:25:48 warmerda
00074 * added setnodata, and some other methods
00075 *
00076 * Revision 1.20 2000/08/25 14:26:51 warmerda
00077 * added GDALHasArbitraryOverviews
00078 *
00079 * Revision 1.19 2000/08/16 15:50:52 warmerda
00080 * fixed some bugs with floating (datasetless) bands
00081 *
00082 * Revision 1.18 2000/07/12 00:19:29 warmerda
00083 * Removed extra line feed.
00084 *
00085 * Revision 1.17 2000/06/05 17:24:05 warmerda
00086 * added real complex support
00087 *
00088 * Revision 1.16 2000/04/21 21:56:59 warmerda
00089 * moved metadata to GDALMajorObject
00090 *
00091 * Revision 1.15 2000/03/31 13:42:27 warmerda
00092 * added metadata support
00093 *
00094 * Revision 1.14 2000/03/24 00:09:05 warmerda
00095 * rewrote cache management
00096 *
00097 * Revision 1.13 2000/03/10 13:54:37 warmerda
00098 * fixed use of overviews in gethistogram
00099 *
00100 * Revision 1.12 2000/03/09 23:22:03 warmerda
00101 * added GetHistogram
00102 *
00103 * Revision 1.11 2000/03/08 19:59:16 warmerda
00104 * added GDALFlushRasterCache
00105 *
00106 * Revision 1.10 2000/03/06 21:50:37 warmerda
00107 * added min/max support
00108 *
00109 * Revision 1.9 2000/03/06 02:22:01 warmerda
00110 * added overviews, colour tables, and many other methods
00111 *
00112 * Revision 1.8 2000/02/28 16:34:28 warmerda
00113 * added arg window check in RasterIO()
00114 *
00115 * Revision 1.7 1999/11/17 16:18:10 warmerda
00116 * fixed example code
00117 *
00118 * Revision 1.6 1999/10/21 13:24:37 warmerda
00119 * Fixed some build breaking variable name differences.
00120 *
00121 * Revision 1.5 1999/10/01 14:44:02 warmerda
00122 * added documentation
00123 *
00124 * Revision 1.4 1998/12/31 18:54:25 warmerda
00125 * Implement initial GDALRasterBlock support, and block cache
00126 *
00127 * Revision 1.3 1998/12/06 22:17:09 warmerda
00128 * Fill out rasterio support.
00129 *
00130 * Revision 1.2 1998/12/06 02:52:08 warmerda
00131 * Added new methods, and C cover functions.
00132 *
00133 * Revision 1.1 1998/12/03 18:32:01 warmerda
00134 * New
00135 */
00136
00137 #include "gdal_priv.h"
00138 #include "cpl_string.h"
00139
00140 CPL_CVSID("$Id: gdalrasterband_cpp-source.html,v 1.13 2002/12/21 19:13:13 warmerda Exp $");
00141
00142 /************************************************************************/
00143 /* GDALRasterBand() */
00144 /************************************************************************/
00145
00148 GDALRasterBand::GDALRasterBand()
00149
00150 {
00151 poDS = NULL;
00152 nBand = 0;
00153
00154 eAccess = GA_ReadOnly;
00155 nBlockXSize = nBlockYSize = -1;
00156 eDataType = GDT_Byte;
00157
00158 nBlocksPerRow = 0;
00159 nBlocksPerColumn = 0;
00160
00161 papoBlocks = NULL;
00162 }
00163
00164 /************************************************************************/
00165 /* ~GDALRasterBand() */
00166 /************************************************************************/
00167
00171 GDALRasterBand::~GDALRasterBand()
00172
00173 {
00174 FlushCache();
00175
00176 CPLFree( papoBlocks );
00177 }
00178
00179 /************************************************************************/
00180 /* RasterIO() */
00181 /************************************************************************/
00182
00248 CPLErr GDALRasterBand::RasterIO( GDALRWFlag eRWFlag,
00249 int nXOff, int nYOff, int nXSize, int nYSize,
00250 void * pData, int nBufXSize, int nBufYSize,
00251 GDALDataType eBufType,
00252 int nPixelSpace,
00253 int nLineSpace )
00254
00255 {
00256 /* -------------------------------------------------------------------- */
00257 /* If pixel and line spaceing are defaulted assign reasonable */
00258 /* value assuming a packed buffer. */
00259 /* -------------------------------------------------------------------- */
00260 if( nPixelSpace == 0 )
00261 nPixelSpace = GDALGetDataTypeSize( eBufType ) / 8;
00262
00263 if( nLineSpace == 0 )
00264 nLineSpace = nPixelSpace * nBufXSize;
00265
00266 /* -------------------------------------------------------------------- */
00267 /* Do some validation of parameters. */
00268 /* -------------------------------------------------------------------- */
00269 if( nXOff < 0 || nXOff + nXSize > nRasterXSize
00270 || nYOff < 0 || nYOff + nYSize > nRasterYSize )
00271 {
00272 CPLError( CE_Failure, CPLE_IllegalArg,
00273 "Access window out of range in RasterIO(). Requested\n"
00274 "(%d,%d) of size %dx%d on raster of %dx%d.",
00275 nXOff, nYOff, nXSize, nYSize, nRasterXSize, nRasterYSize );
00276 return CE_Failure;
00277 }
00278
00279 if( eRWFlag != GF_Read && eRWFlag != GF_Write )
00280 {
00281 CPLError( CE_Failure, CPLE_IllegalArg,
00282 "eRWFlag = %d, only GF_Read (0) and GF_Write (1) are legal.",
00283 eRWFlag );
00284 return CE_Failure;
00285 }
00286
00287 /* -------------------------------------------------------------------- */
00288 /* Some size values are "noop". Lets just return to avoid */
00289 /* stressing lower level functions. */
00290 /* -------------------------------------------------------------------- */
00291 if( nXSize < 1 || nYSize < 1 || nBufXSize < 1 || nBufYSize < 1 )
00292 {
00293 CPLDebug( "GDAL",
00294 "RasterIO() skipped for odd window or buffer size.\n"
00295 " Window = (%d,%d)x%dx%d\n"
00296 " Buffer = %dx%d\n",
00297 nXOff, nYOff, nXSize, nYSize,
00298 nBufXSize, nBufYSize );
00299
00300 return CE_None;
00301 }
00302
00303 /* -------------------------------------------------------------------- */
00304 /* Call the format specific function. */
00305 /* -------------------------------------------------------------------- */
00306 return( IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
00307 pData, nBufXSize, nBufYSize, eBufType,
00308 nPixelSpace, nLineSpace ) );
00309 }
00310
00311 /************************************************************************/
00312 /* GDALRasterIO() */
00313 /************************************************************************/
00314
00315 CPLErr GDALRasterIO( GDALRasterBandH hBand, GDALRWFlag eRWFlag,
00316 int nXOff, int nYOff,
00317 int nXSize, int nYSize,
00318 void * pData,
00319 int nBufXSize, int nBufYSize,
00320 GDALDataType eBufType,
00321 int nPixelSpace,
00322 int nLineSpace )
00323
00324 {
00325 GDALRasterBand *poBand = (GDALRasterBand *) hBand;
00326
00327 return( poBand->RasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
00328 pData, nBufXSize, nBufYSize, eBufType,
00329 nPixelSpace, nLineSpace ) );
00330 }
00331
00332 /************************************************************************/
00333 /* ReadBlock() */
00334 /************************************************************************/
00335
00418 CPLErr GDALRasterBand::ReadBlock( int nXBlockOff, int nYBlockOff,
00419 void * pImage )
00420
00421 {
00422 /* -------------------------------------------------------------------- */
00423 /* Validate arguments. */
00424 /* -------------------------------------------------------------------- */
00425 CPLAssert( pImage != NULL );
00426
00427 if( nXBlockOff < 0
00428 || nXBlockOff*nBlockXSize >= nRasterXSize )
00429 {
00430 CPLError( CE_Failure, CPLE_IllegalArg,
00431 "Illegal nXBlockOff value (%d) in "
00432 "GDALRasterBand::ReadBlock()\n",
00433 nXBlockOff );
00434
00435 return( CE_Failure );
00436 }
00437
00438 if( nYBlockOff < 0
00439 || nYBlockOff*nBlockYSize >= nRasterYSize )
00440 {
00441 CPLError( CE_Failure, CPLE_IllegalArg,
00442 "Illegal nYBlockOff value (%d) in "
00443 "GDALRasterBand::ReadBlock()\n",
00444 nYBlockOff );
00445
00446 return( CE_Failure );
00447 }
00448
00449 InitBlockInfo();
00450
00451 /* -------------------------------------------------------------------- */
00452 /* Invoke underlying implementation method. */
00453 /* -------------------------------------------------------------------- */
00454 return( IReadBlock( nXBlockOff, nYBlockOff, pImage ) );
00455 }
00456
00457 /************************************************************************/
00458 /* GDALReadBlock() */
00459 /************************************************************************/
00460
00461 CPLErr GDALReadBlock( GDALRasterBandH hBand, int nXOff, int nYOff,
00462 void * pData )
00463
00464 {
00465 GDALRasterBand *poBand = (GDALRasterBand *) hBand;
00466
00467 return( poBand->ReadBlock( nXOff, nYOff, pData ) );
00468 }
00469
00470 /************************************************************************/
00471 /* IWriteBlock() */
00472 /* */
00473 /* Default internal implementation ... to be overriden by */
00474 /* subclasses that support writing. */
00475 /************************************************************************/
00476
00477 CPLErr GDALRasterBand::IWriteBlock( int, int, void * )
00478
00479 {
00480 CPLError( CE_Failure, CPLE_NotSupported,
00481 "WriteBlock() not supported for this dataset." );
00482
00483 return( CE_Failure );
00484 }
00485
00486 /************************************************************************/
00487 /* WriteBlock() */
00488 /************************************************************************/
00489
00520 CPLErr GDALRasterBand::WriteBlock( int nXBlockOff, int nYBlockOff,
00521 void * pImage )
00522
00523 {
00524 /* -------------------------------------------------------------------- */
00525 /* Validate arguments. */
00526 /* -------------------------------------------------------------------- */
00527 CPLAssert( pImage != NULL );
00528
00529 if( nXBlockOff < 0
00530 || nXBlockOff*nBlockXSize >= GetXSize() )
00531 {
00532 CPLError( CE_Failure, CPLE_IllegalArg,
00533 "Illegal nXBlockOff value (%d) in "
00534 "GDALRasterBand::WriteBlock()\n",
00535 nXBlockOff );
00536
00537 return( CE_Failure );
00538 }
00539
00540 if( nYBlockOff < 0
00541 || nYBlockOff*nBlockYSize >= GetYSize() )
00542 {
00543 CPLError( CE_Failure, CPLE_IllegalArg,
00544 "Illegal nYBlockOff value (%d) in "
00545 "GDALRasterBand::WriteBlock()\n",
00546 nYBlockOff );
00547
00548 return( CE_Failure );
00549 }
00550
00551 if( eAccess == GA_ReadOnly )
00552 {
00553 CPLError( CE_Failure, CPLE_NoWriteAccess,
00554 "Attempt to write to read only dataset in"
00555 "GDALRasterBand::WriteBlock().\n" );
00556
00557 return( CE_Failure );
00558 }
00559
00560 InitBlockInfo();
00561
00562 /* -------------------------------------------------------------------- */
00563 /* Invoke underlying implementation method. */
00564 /* -------------------------------------------------------------------- */
00565 return( IWriteBlock( nXBlockOff, nYBlockOff, pImage ) );
00566 }
00567
00568 /************************************************************************/
00569 /* GDALWriteBlock() */
00570 /************************************************************************/
00571
00572 CPLErr GDALWriteBlock( GDALRasterBandH hBand, int nXOff, int nYOff,
00573 void * pData )
00574
00575 {
00576 GDALRasterBand *poBand = (GDALRasterBand *) hBand;
00577
00578 return( poBand->WriteBlock( nXOff, nYOff, pData ) );
00579 }
00580
00581
00582 /************************************************************************/
00583 /* GetRasterDataType() */
00584 /************************************************************************/
00585
00593 GDALDataType GDALRasterBand::GetRasterDataType()
00594
00595 {
00596 return eDataType;
00597 }
00598
00599 /************************************************************************/
00600 /* GDALGetRasterDataType() */
00601 /************************************************************************/
00602
00603 GDALDataType GDALGetRasterDataType( GDALRasterBandH hBand )
00604
00605 {
00606 return( ((GDALRasterBand *) hBand)->GetRasterDataType() );
00607 }
00608
00609 /************************************************************************/
00610 /* GetBlockSize() */
00611 /************************************************************************/
00612
00633 void GDALRasterBand::GetBlockSize( int * pnXSize, int *pnYSize )
00634
00635 {
00636 CPLAssert( nBlockXSize > 0 && nBlockYSize > 0 );
00637
00638 if( pnXSize != NULL )
00639 *pnXSize = nBlockXSize;
00640 if( pnYSize != NULL )
00641 *pnYSize = nBlockYSize;
00642 }
00643
00644 /************************************************************************/
00645 /* GDALGetBlockSize() */
00646 /************************************************************************/
00647
00648 void GDALGetBlockSize( GDALRasterBandH hBand, int * pnXSize, int * pnYSize )
00649
00650 {
00651 GDALRasterBand *poBand = (GDALRasterBand *) hBand;
00652
00653 poBand->GetBlockSize( pnXSize, pnYSize );
00654 }
00655
00656 /************************************************************************/
00657 /* InitBlockInfo() */
00658 /************************************************************************/
00659
00660 void GDALRasterBand::InitBlockInfo()
00661
00662 {
00663 if( papoBlocks != NULL )
00664 return;
00665
00666 CPLAssert( nBlockXSize > 0 && nBlockYSize > 0 );
00667
00668 nBlocksPerRow = (nRasterXSize+nBlockXSize-1) / nBlockXSize;
00669 nBlocksPerColumn = (nRasterYSize+nBlockYSize-1) / nBlockYSize;
00670
00671 papoBlocks = (GDALRasterBlock **)
00672 CPLCalloc( sizeof(void*), nBlocksPerRow * nBlocksPerColumn );
00673 }
00674
00675
00676 /************************************************************************/
00677 /* AdoptBlock() */
00678 /* */
00679 /* Add a block to the raster band's block matrix. If this */
00680 /* exceeds our maximum blocks for this layer, flush the oldest */
00681 /* block out. */
00682 /* */
00683 /* This method is protected. */
00684 /************************************************************************/
00685
00686 CPLErr GDALRasterBand::AdoptBlock( int nBlockXOff, int nBlockYOff,
00687 GDALRasterBlock * poBlock )
00688
00689 {
00690 int nBlockIndex;
00691
00692 InitBlockInfo();
00693
00694 CPLAssert( nBlockXOff >= 0 && nBlockXOff < nBlocksPerRow );
00695 CPLAssert( nBlockYOff >= 0 && nBlockYOff < nBlocksPerColumn );
00696
00697 nBlockIndex = nBlockXOff + nBlockYOff * nBlocksPerRow;
00698 if( papoBlocks[nBlockIndex] == poBlock )
00699 return( CE_None );
00700
00701 if( papoBlocks[nBlockIndex] != NULL )
00702 FlushBlock( nBlockXOff, nBlockYOff );
00703
00704 papoBlocks[nBlockIndex] = poBlock;
00705 poBlock->Touch();
00706
00707 return( CE_None );
00708 }
00709
00710 /************************************************************************/
00711 /* FlushCache() */
00712 /************************************************************************/
00713
00725 CPLErr GDALRasterBand::FlushCache()
00726
00727 {
00728 for( int iY = 0; iY < nBlocksPerColumn; iY++ )
00729 {
00730 for( int iX = 0; iX < nBlocksPerRow; iX++ )
00731 {
00732 if( papoBlocks[iX + iY*nBlocksPerRow] != NULL )
00733 {
00734 CPLErr eErr;
00735
00736 eErr = FlushBlock( iX, iY );
00737
00738 if( eErr != CE_None )
00739 return eErr;
00740 }
00741 }
00742 }
00743
00744 return( CE_None );
00745 }
00746
00747 /************************************************************************/
00748 /* GDALFlushRasterCache() */
00749 /************************************************************************/
00750
00751 CPLErr GDALFlushRasterCache( GDALRasterBandH hBand )
00752
00753 {
00754 return ((GDALRasterBand *) hBand)->FlushCache();
00755 }
00756
00757 /************************************************************************/
00758 /* FlushBlock() */
00759 /* */
00760 /* Flush a block out of the block cache. If it has been */
00761 /* modified write it to disk. If no specific tile is */
00762 /* indicated, write the oldest tile. */
00763 /* */
00764 /* Protected method. */
00765 /************************************************************************/
00766
00767 CPLErr GDALRasterBand::FlushBlock( int nBlockXOff, int nBlockYOff )
00768
00769 {
00770 int nBlockIndex;
00771 GDALRasterBlock *poBlock;
00772 CPLErr eErr = CE_None;
00773
00774 InitBlockInfo();
00775
00776 /* -------------------------------------------------------------------- */
00777 /* Validate */
00778 /* -------------------------------------------------------------------- */
00779 CPLAssert( nBlockXOff >= 0 && nBlockXOff < nBlocksPerRow );
00780 CPLAssert( nBlockYOff >= 0 && nBlockYOff < nBlocksPerColumn );
00781
00782 nBlockIndex = nBlockXOff + nBlockYOff * nBlocksPerRow;
00783 poBlock = papoBlocks[nBlockIndex];
00784 if( poBlock == NULL )
00785 return( CE_None );
00786
00787 /* -------------------------------------------------------------------- */
00788 /* Remove, and update count. */
00789 /* -------------------------------------------------------------------- */
00790 papoBlocks[nBlockIndex] = NULL;
00791
00792 /* -------------------------------------------------------------------- */
00793 /* Is the target block dirty? If so we need to write it. */
00794 /* -------------------------------------------------------------------- */
00795 if( poBlock->GetDirty() )
00796 poBlock->Write();
00797
00798 /* -------------------------------------------------------------------- */
00799 /* Deallocate the block; */
00800 /* -------------------------------------------------------------------- */
00801 delete poBlock;
00802
00803 return( eErr );
00804 }
00805
00806
00807 /************************************************************************/
00808 /* GetBlockRef() */
00809 /************************************************************************/
00810
00826 GDALRasterBlock * GDALRasterBand::GetBlockRef( int nXBlockOff,
00827 int nYBlockOff )
00828
00829 {
00830 int nBlockIndex;
00831
00832 InitBlockInfo();
00833
00834 /* -------------------------------------------------------------------- */
00835 /* Validate the request */
00836 /* -------------------------------------------------------------------- */
00837 if( nXBlockOff < 0 || nXBlockOff >= nBlocksPerRow )
00838 {
00839 CPLError( CE_Failure, CPLE_IllegalArg,
00840 "Illegal nBlockXOff value (%d) in "
00841 "GDALRasterBand::GetBlockRef()\n",
00842 nXBlockOff );
00843
00844 return( NULL );
00845 }
00846
00847 if( nYBlockOff < 0 || nYBlockOff >= nBlocksPerColumn )
00848 {
00849 CPLError( CE_Failure, CPLE_IllegalArg,
00850 "Illegal nBlockYOff value (%d) in "
00851 "GDALRasterBand::GetBlockRef()\n",
00852 nYBlockOff );
00853
00854 return( NULL );
00855 }
00856
00857 /* -------------------------------------------------------------------- */
00858 /* If the block isn't already in the cache, we will need to */
00859 /* create it, read into it, and adopt it. Adopting it may */
00860 /* flush an old tile from the cache. */
00861 /* -------------------------------------------------------------------- */
00862 nBlockIndex = nXBlockOff + nYBlockOff * nBlocksPerRow;
00863
00864 if( papoBlocks[nBlockIndex] == NULL )
00865 {
00866 GDALRasterBlock *poBlock;
00867
00868 poBlock = new GDALRasterBlock( this, nXBlockOff, nYBlockOff );
00869
00870 /* allocate data space */
00871 if( poBlock->Internalize() != CE_None )
00872 {
00873 delete poBlock;
00874 CPLError( CE_Failure, CPLE_AppDefined, "Internalize failed",
00875 nXBlockOff, nYBlockOff);
00876 return( NULL );
00877 }
00878
00879 if( IReadBlock(nXBlockOff,nYBlockOff,poBlock->GetDataRef()) != CE_None)
00880 {
00881 delete poBlock;
00882 CPLError( CE_Failure, CPLE_AppDefined,
00883 "IReadBlock failed at X offset %d, Y offset %d",
00884 nXBlockOff, nYBlockOff );
00885 return( NULL );
00886 }
00887
00888 AdoptBlock( nXBlockOff, nYBlockOff, poBlock );
00889 }
00890
00891 /* -------------------------------------------------------------------- */
00892 /* Every read access updates the last touched time. */
00893 /* -------------------------------------------------------------------- */
00894 if( papoBlocks[nBlockIndex] != NULL )
00895 papoBlocks[nBlockIndex]->Touch();
00896
00897 return( papoBlocks[nBlockIndex] );
00898 }
00899
00900 /************************************************************************/
00901 /* GetAccess() */
00902 /************************************************************************/
00903
00910 GDALAccess GDALRasterBand::GetAccess()
00911
00912 {
00913 return eAccess;
00914 }
00915
00916 /************************************************************************/
00917 /* GetCategoryNames() */
00918 /************************************************************************/
00919
00935 char **GDALRasterBand::GetCategoryNames()
00936
00937 {
00938 return NULL;
00939 }
00940
00941 /************************************************************************/
00942 /* GDALGetRasterCategoryNames() */
00943 /************************************************************************/
00944
00945 char **GDALGetRasterCategoryNames( GDALRasterBandH hBand )
00946
00947 {
00948 return ((GDALRasterBand *) hBand)->GetCategoryNames();
00949 }
00950
00951 /************************************************************************/
00952 /* SetCategoryNames() */
00953 /************************************************************************/
00954
00970 CPLErr GDALRasterBand::SetCategoryNames( char ** )
00971
00972 {
00973 CPLError( CE_Failure, CPLE_NotSupported,
00974 "SetCategoryNames() not supported for this dataset." );
00975
00976 return CE_Failure;
00977 }
00978
00979 /************************************************************************/
00980 /* GDALSetCategoryNames() */
00981 /************************************************************************/
00982
00983 CPLErr GDALSetRasterCategoryNames( GDALRasterBandH hBand, char ** papszNames )
00984
00985 {
00986 return ((GDALRasterBand *) hBand)->SetCategoryNames( papszNames );
00987 }
00988
00989 /************************************************************************/
00990 /* GetNoDataValue() */
00991 /************************************************************************/
00992
01009 double GDALRasterBand::GetNoDataValue( int *pbSuccess )
01010
01011 {
01012 if( pbSuccess != NULL )
01013 *pbSuccess = FALSE;
01014
01015 return -1e10;
01016 }
01017
01018 /************************************************************************/
01019 /* GDALGetRasterNoDataValue() */
01020 /************************************************************************/
01021
01022 double GDALGetRasterNoDataValue( GDALRasterBandH hBand, int *pbSuccess )
01023
01024 {
01025 return ((GDALRasterBand *) hBand)->GetNoDataValue( pbSuccess );
01026 }
01027
01028 /************************************************************************/
01029 /* SetNoDataValue() */
01030 /************************************************************************/
01031
01047 CPLErr GDALRasterBand::SetNoDataValue( double )
01048
01049 {
01050 CPLError( CE_Failure, CPLE_NotSupported,
01051 "SetNoDataValue() not supported for this dataset." );
01052 return CE_Failure;
01053 }
01054
01055 /************************************************************************/
01056 /* GDALSetRasterNoDataValue() */
01057 /************************************************************************/
01058
01059 CPLErr GDALSetRasterNoDataValue( GDALRasterBandH hBand, double dfValue )
01060
01061 {
01062 return ((GDALRasterBand *) hBand)->SetNoDataValue( dfValue );
01063 }
01064
01065 /************************************************************************/
01066 /* GetMaximum() */
01067 /************************************************************************/
01068
01083 double GDALRasterBand::GetMaximum( int *pbSuccess )
01084
01085 {
01086 if( pbSuccess != NULL )
01087 *pbSuccess = FALSE;
01088
01089 switch( eDataType )
01090 {
01091 case GDT_Byte:
01092 return 255;
01093
01094 case GDT_UInt16:
01095 return 65535;
01096
01097 case GDT_Int16:
01098 case GDT_CInt16:
01099 return 32767;
01100
01101 case GDT_Int32:
01102 case GDT_CInt32:
01103 return 2147483647.0;
01104
01105 case GDT_UInt32:
01106 return 4294967295.0;
01107
01108 case GDT_Float32:
01109 case GDT_CFloat32:
01110 return 4294967295.0; /* not actually accurate */
01111
01112 case GDT_Float64:
01113 case GDT_CFloat64:
01114 return 4294967295.0; /* not actually accurate */
01115
01116 default:
01117 return 4294967295.0; /* not actually accurate */
01118 }
01119 }
01120
01121 /************************************************************************/
01122 /* GDALGetRasterMaximum() */
01123 /************************************************************************/
01124
01125 double GDALGetRasterMaximum( GDALRasterBandH hBand, int *pbSuccess )
01126
01127 {
01128 return ((GDALRasterBand *) hBand)->GetMaximum( pbSuccess );
01129 }
01130
01131 /************************************************************************/
01132 /* GetMinimum() */
01133 /************************************************************************/
01134
01149 double GDALRasterBand::GetMinimum( int *pbSuccess )
01150
01151 {
01152 if( pbSuccess != NULL )
01153 *pbSuccess = FALSE;
01154
01155 switch( eDataType )
01156 {
01157 case GDT_Byte:
01158 return 0;
01159
01160 case GDT_UInt16:
01161 return 0;
01162
01163 case GDT_Int16:
01164 return -32768;
01165
01166 case GDT_Int32:
01167 return -2147483648.0;
01168
01169 case GDT_UInt32:
01170 return 0;
01171
01172 case GDT_Float32:
01173 return -4294967295.0; /* not actually accurate */
01174
01175 case GDT_Float64:
01176 return -4294967295.0; /* not actually accurate */
01177
01178 default:
01179 return -4294967295.0; /* not actually accurate */
01180 }
01181 }
01182
01183 /************************************************************************/
01184 /* GDALGetRasterMinimum() */
01185 /************************************************************************/
01186
01187 double GDALGetRasterMinimum( GDALRasterBandH hBand, int *pbSuccess )
01188
01189 {
01190 return ((GDALRasterBand *) hBand)->GetMinimum( pbSuccess );
01191 }
01192
01193 /************************************************************************/
01194 /* GetColorInterpretation() */
01195 /************************************************************************/
01196
01209 GDALColorInterp GDALRasterBand::GetColorInterpretation()
01210
01211 {
01212 return GCI_Undefined;
01213 }
01214
01215 /************************************************************************/
01216 /* GDALGetRasterColorInterpretation() */
01217 /************************************************************************/
01218
01219 GDALColorInterp GDALGetRasterColorInterpretation( GDALRasterBandH hBand )
01220
01221 {
01222 return ((GDALRasterBand *) hBand)->GetColorInterpretation();
01223 }
01224
01225 /************************************************************************/
01226 /* SetColorInterpretation() */
01227 /************************************************************************/
01228
01237 CPLErr GDALRasterBand::SetColorInterpretation( GDALColorInterp eColorInterp )
01238
01239 {
01240 CPLError( CE_Failure, CPLE_NotSupported,
01241 "SetColorInterpretation() not supported for this dataset." );
01242 return CE_Failure;
01243 }
01244
01245 /************************************************************************/
01246 /* GDALSetRasterColorInterpretation() */
01247 /************************************************************************/
01248
01249 CPLErr GDALSetRasterColorInterpretation( GDALRasterBandH hBand,
01250 GDALColorInterp eColorInterp )
01251
01252 {
01253 return ((GDALRasterBand *) hBand)->SetColorInterpretation(eColorInterp);
01254 }
01255
01256 /************************************************************************/
01257 /* GetColorTable() */
01258 /************************************************************************/
01259
01272 GDALColorTable *GDALRasterBand::GetColorTable()
01273
01274 {
01275 return NULL;
01276 }
01277
01278 /************************************************************************/
01279 /* GDALGetRasterColorTable() */
01280 /************************************************************************/
01281
01282 GDALColorTableH GDALGetRasterColorTable( GDALRasterBandH hBand )
01283
01284 {
01285 return (GDALColorTableH) ((GDALRasterBand *) hBand)->GetColorTable();
01286 }
01287
01288 /************************************************************************/
01289 /* SetColorTable() */
01290 /************************************************************************/
01291
01307 CPLErr GDALRasterBand::SetColorTable( GDALColorTable * poCT )
01308
01309 {
01310 CPLError( CE_Failure, CPLE_NotSupported,
01311 "SetColorTable() not supported for this dataset." );
01312 return CE_Failure;
01313 }
01314
01315 /************************************************************************/
01316 /* GDALSetRasterColorTable() */
01317 /************************************************************************/
01318
01319 CPLErr GDALSetRasterColorTable( GDALRasterBandH hBand, GDALColorTableH hCT )
01320
01321 {
01322 return ((GDALRasterBand *) hBand)->SetColorTable( (GDALColorTable *) hCT );
01323 }
01324
01325 /************************************************************************/
01326 /* HasArbitraryOverviews() */
01327 /************************************************************************/
01328
01344 int GDALRasterBand::HasArbitraryOverviews()
01345
01346 {
01347 return FALSE;
01348 }
01349
01350 /************************************************************************/
01351 /* GDALHasArbitraryOverviews() */
01352 /************************************************************************/
01353
01354 int GDALHasArbitraryOverviews( GDALRasterBandH hBand )
01355
01356 {
01357 return ((GDALRasterBand *) hBand)->HasArbitraryOverviews();
01358 }
01359
01360 /************************************************************************/
01361 /* GetOverviewCount() */
01362 /************************************************************************/
01363
01372 int GDALRasterBand::GetOverviewCount()
01373
01374 {
01375 if( poDS != NULL && poDS->oOvManager.IsInitialized() )
01376 return poDS->oOvManager.GetOverviewCount( nBand );
01377 else
01378 return 0;
01379 }
01380
01381 /************************************************************************/
01382 /* GDALGetOverviewCount() */
01383 /************************************************************************/
01384
01385 int GDALGetOverviewCount( GDALRasterBandH hBand )
01386
01387 {
01388 return ((GDALRasterBand *) hBand)->GetOverviewCount();
01389 }
01390
01391
01392 /************************************************************************/
01393 /* GetOverview() */
01394 /************************************************************************/
01395
01406 GDALRasterBand * GDALRasterBand::GetOverview( int i )
01407
01408 {
01409 if( poDS != NULL && poDS->oOvManager.IsInitialized() )
01410 return poDS->oOvManager.GetOverview( nBand, i );
01411 else
01412 return NULL;
01413 }
01414
01415 /************************************************************************/
01416 /* GDALGetOverview() */
01417 /************************************************************************/
01418
01419 GDALRasterBandH GDALGetOverview( GDALRasterBandH hBand, int i )
01420
01421 {
01422 return (GDALRasterBandH) ((GDALRasterBand *) hBand)->GetOverview(i);
01423 }
01424
01425 /************************************************************************/
01426 /* BuildOverviews() */
01427 /************************************************************************/
01428
01445 CPLErr GDALRasterBand::BuildOverviews( const char *pszResampling,
01446 int nOverviews, int *panOverviewList,
01447 GDALProgressFunc pfnProgress,
01448 void * pProgressData )
01449
01450 {
01451 CPLError( CE_Failure, CPLE_NotSupported,
01452 "BuildOverviews() not supported for this dataset." );
01453
01454 return( CE_Failure );
01455 }
01456
01457 /************************************************************************/
01458 /* GetOffset() */
01459 /************************************************************************/
01460
01480 double GDALRasterBand::GetOffset( int *pbSuccess )
01481
01482 {
01483 if( pbSuccess != NULL )
01484 *pbSuccess = FALSE;
01485
01486 return 0.0;
01487 }
01488
01489 /************************************************************************/
01490 /* GetScale() */
01491 /************************************************************************/
01492
01512 double GDALRasterBand::GetScale( int *pbSuccess )
01513
01514 {
01515 if( pbSuccess != NULL )
01516 *pbSuccess = FALSE;
01517
01518 return 1.0;
01519 }
01520
01521 /************************************************************************/
01522 /* GetUnitType() */
01523 /************************************************************************/
01524
01538 const char *GDALRasterBand::GetUnitType()
01539
01540 {
01541 return "";
01542 }
01543
01544 /************************************************************************/
01545 /* GDALGetRasterUnitType() */
01546 /************************************************************************/
01547
01548 const char *GDALGetRasterUnitType( GDALRasterBandH hBand )
01549
01550 {
01551 return ((GDALRasterBand *) hBand)->GetUnitType();
01552 }
01553
01554 /************************************************************************/
01555 /* GetXSize() */
01556 /************************************************************************/
01557
01566 int GDALRasterBand::GetXSize()
01567
01568 {
01569 return nRasterXSize;
01570 }
01571
01572 /************************************************************************/
01573 /* GDALGetRasterBandXSize() */
01574 /************************************************************************/
01575
01576 int GDALGetRasterBandXSize( GDALRasterBandH hBand )
01577
01578 {
01579 return ((GDALRasterBand *) hBand)->GetXSize();
01580 }
01581
01582 /************************************************************************/
01583 /* GetYSize() */
01584 /************************************************************************/
01585
01594 int GDALRasterBand::GetYSize()
01595
01596 {
01597 return nRasterYSize;
01598 }
01599
01600 /************************************************************************/
01601 /* GDALGetRasterBandYSize() */
01602 /************************************************************************/
01603
01604 int GDALGetRasterBandYSize( GDALRasterBandH hBand )
01605
01606 {
01607 return ((GDALRasterBand *) hBand)->GetYSize();
01608 }
01609
01610 /************************************************************************/
01611 /* GetBand() */
01612 /************************************************************************/
01613
01627 int GDALRasterBand::GetBand()
01628
01629 {
01630 return nBand;
01631 }
01632
01633 /************************************************************************/
01634 /* GetDataset() */
01635 /************************************************************************/
01636
01649 GDALDataset *GDALRasterBand::GetDataset()
01650
01651 {
01652 return poDS;
01653 }
01654
01655 /************************************************************************/
01656 /* GetHistogram() */
01657 /************************************************************************/
01658
01695 CPLErr GDALRasterBand::GetHistogram( double dfMin, double dfMax,
01696 int nBuckets, int *panHistogram,
01697 int bIncludeOutOfRange, int bApproxOK,
01698 GDALProgressFunc pfnProgress,
01699 void *pProgressData )
01700
01701 {
01702 CPLAssert( pfnProgress != NULL );
01703
01704 /* -------------------------------------------------------------------- */
01705 /* If we have overviews, use them for the histogram. */
01706 /* -------------------------------------------------------------------- */
01707 if( bApproxOK && GetOverviewCount() > 0 )
01708 {
01709 double dfBestPixels = GetXSize() * GetYSize();
01710 GDALRasterBand *poBestOverview = NULL;
01711
01712 for( int i = 0; i < GetOverviewCount(); i++ )
01713 {
01714 GDALRasterBand *poOverview = GetOverview(i);
01715 double dfPixels;
01716
01717 dfPixels = poOverview->GetXSize() * poOverview->GetYSize();
01718 if( dfPixels < dfBestPixels )
01719 {
01720 dfBestPixels = dfPixels;
01721 poBestOverview = poOverview;
01722 }
01723
01724 if( poBestOverview != NULL )
01725 return poBestOverview->
01726 GetHistogram( dfMin, dfMax, nBuckets, panHistogram,
01727 bIncludeOutOfRange, bApproxOK,
01728 pfnProgress, pProgressData );
01729 }
01730 }
01731
01732 /* -------------------------------------------------------------------- */
01733 /* Figure out the ratio of blocks we will read to get an */
01734 /* approximate value. */
01735 /* -------------------------------------------------------------------- */
01736 int nSampleRate;
01737 double dfScale;
01738
01739 InitBlockInfo();
01740
01741 if( bApproxOK )
01742 nSampleRate =
01743 (int) MAX(1,sqrt((double) nBlocksPerRow * nBlocksPerColumn));
01744 else
01745 nSampleRate = 1;
01746
01747 dfScale = nBuckets / (dfMax - dfMin);
01748
01749 /* -------------------------------------------------------------------- */
01750 /* Read the blocks, and add to histogram. */
01751 /* -------------------------------------------------------------------- */
01752 memset( panHistogram, 0, sizeof(int) * nBuckets );
01753 for( int iSampleBlock = 0;
01754 iSampleBlock < nBlocksPerRow * nBlocksPerColumn;
01755 iSampleBlock += nSampleRate )
01756 {
01757 double dfValue = 0.0, dfReal, dfImag;
01758 int iXBlock, iYBlock, nXCheck, nYCheck;
01759 GDALRasterBlock *poBlock;
01760
01761 if( !pfnProgress( iSampleBlock/(double)nBlocksPerRow*nBlocksPerColumn,
01762 NULL, pProgressData ) )
01763 return CE_Failure;
01764
01765 iYBlock = iSampleBlock / nBlocksPerRow;
01766 iXBlock = iSampleBlock - nBlocksPerRow * iYBlock;
01767
01768 poBlock = GetBlockRef( iXBlock, iYBlock );
01769 if( poBlock == NULL )
01770 return CE_Failure;
01771
01772 if( (iXBlock+1) * nBlockXSize > GetXSize() )
01773 nXCheck = GetXSize() - iXBlock * nBlockXSize;
01774 else
01775 nXCheck = nBlockXSize;
01776
01777 if( (iYBlock+1) * nBlockYSize > GetYSize() )
01778 nYCheck = GetYSize() - iYBlock * nBlockYSize;
01779 else
01780 nYCheck = nBlockYSize;
01781
01782 /* this is a special case for a common situation */
01783 if( poBlock->GetDataType() == GDT_Byte
01784 && dfScale == 1.0 && (dfMin >= -0.5 && dfMin <= 0.5)
01785 && nYCheck == nBlockYSize && nXCheck == nBlockXSize
01786 && nBuckets == 256 )
01787 {
01788 int nPixels = nXCheck * nYCheck;
01789 GByte *pabyData = (GByte *) poBlock->GetDataRef();
01790
01791 for( int i = 0; i < nPixels; i++ )
01792 panHistogram[pabyData[i]]++;
01793
01794 continue; /* to next sample block */
01795 }
01796
01797 /* this isn't the fastest way to do this, but is easier for now */
01798 for( int iY = 0; iY < nYCheck; iY++ )
01799 {
01800 for( int iX = 0; iX < nXCheck; iX++ )
01801 {
01802 int iOffset = iX + iY * nBlockXSize;
01803 int nIndex;
01804
01805 switch( poBlock->GetDataType() )
01806 {
01807 case GDT_Byte:
01808 dfValue = ((GByte *) poBlock->GetDataRef())[iOffset];
01809 break;
01810
01811 case GDT_UInt16:
01812 dfValue = ((GUInt16 *) poBlock->GetDataRef())[iOffset];
01813 break;
01814 case GDT_Int16:
01815 dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset];
01816 break;
01817 case GDT_UInt32:
01818 dfValue = ((GUInt32 *) poBlock->GetDataRef())[iOffset];
01819 break;
01820 case GDT_Int32:
01821 dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset];
01822 break;
01823 case GDT_Float32:
01824 dfValue = ((float *) poBlock->GetDataRef())[iOffset];
01825 break;
01826 case GDT_Float64:
01827 dfValue = ((double *) poBlock->GetDataRef())[iOffset];
01828 break;
01829 case GDT_CInt16:
01830 dfReal = ((GInt16 *) poBlock->GetDataRef())[iOffset*2];
01831 dfImag = ((GInt16 *) poBlock->GetDataRef())[iOffset*2+1];
01832 dfValue = sqrt( dfReal * dfReal + dfImag * dfImag );
01833 break;
01834 case GDT_CInt32:
01835 dfReal = ((GInt32 *) poBlock->GetDataRef())[iOffset*2];
01836 dfImag = ((GInt32 *) poBlock->GetDataRef())[iOffset*2+1];
01837 dfValue = sqrt( dfReal * dfReal + dfImag * dfImag );
01838 break;
01839 case GDT_CFloat32:
01840 dfReal = ((float *) poBlock->GetDataRef())[iOffset*2];
01841 dfImag = ((float *) poBlock->GetDataRef())[iOffset*2+1];
01842 dfValue = sqrt( dfReal * dfReal + dfImag * dfImag );
01843 break;
01844 case GDT_CFloat64:
01845 dfReal = ((double *) poBlock->GetDataRef())[iOffset*2];
01846 dfImag = ((double *) poBlock->GetDataRef())[iOffset*2+1];
01847 dfValue = sqrt( dfReal * dfReal + dfImag * dfImag );
01848 break;
01849 default:
01850 CPLAssert( FALSE );
01851 return CE_Failure;
01852 }
01853
01854 nIndex = (int) floor((dfValue - dfMin) * dfScale);
01855
01856 if( nIndex < 0 )
01857 {
01858 if( bIncludeOutOfRange )
01859 panHistogram[0]++;
01860 }
01861 else if( nIndex >= nBuckets )
01862 {
01863 if( bIncludeOutOfRange )
01864 panHistogram[nBuckets-1]++;
01865 }
01866 else
01867 {
01868 panHistogram[nIndex]++;
01869 }
01870 }
01871 }
01872 }
01873
01874 pfnProgress( 1.0, NULL, pProgressData );
01875
01876 return CE_None;
01877 }
01878
01879 /************************************************************************/
01880 /* GDALGetRasterHistogram() */
01881 /************************************************************************/
01882
01883 CPLErr GDALGetRasterHistogram( GDALRasterBandH hBand,
01884 double dfMin, double dfMax,
01885 int nBuckets, int *panHistogram,
01886 int bIncludeOutOfRange, int bApproxOK,
01887 GDALProgressFunc pfnProgress,
01888 void *pProgressData )
01889
01890 {
01891 return ((GDALRasterBand *) hBand)->
01892 GetHistogram( dfMin, dfMax, nBuckets, panHistogram,
01893 bIncludeOutOfRange, bApproxOK,
01894 pfnProgress, pProgressData );
01895 }
1.2.3-20001105 written by Dimitri van Heesch,
© 1997-2000