Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

gdalrasterband.cpp

00001 /******************************************************************************
00002  * $Id: gdalrasterband_cpp-source.html,v 1.8 2001/07/05 13:24:08 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.8  2001/07/05 13:24:08  warmerda
00030  * *** empty log message ***
00030  *
00031  * Revision 1.22  2001/07/05 13:13:40  warmerda
00032  * added UnitType from C support
00033  *
00034  * Revision 1.21  2000/10/06 15:25:48  warmerda
00035  * added setnodata, and some other methods
00036  *
00037  * Revision 1.20  2000/08/25 14:26:51  warmerda
00038  * added GDALHasArbitraryOverviews
00039  *
00040  * Revision 1.19  2000/08/16 15:50:52  warmerda
00041  * fixed some bugs with floating (datasetless) bands
00042  *
00043  * Revision 1.18  2000/07/12 00:19:29  warmerda
00044  * Removed extra line feed.
00045  *
00046  * Revision 1.17  2000/06/05 17:24:05  warmerda
00047  * added real complex support
00048  *
00049  * Revision 1.16  2000/04/21 21:56:59  warmerda
00050  * moved metadata to GDALMajorObject
00051  *
00052  * Revision 1.15  2000/03/31 13:42:27  warmerda
00053  * added metadata support
00054  *
00055  * Revision 1.14  2000/03/24 00:09:05  warmerda
00056  * rewrote cache management
00057  *
00058  * Revision 1.13  2000/03/10 13:54:37  warmerda
00059  * fixed use of overviews in gethistogram
00060  *
00061  * Revision 1.12  2000/03/09 23:22:03  warmerda
00062  * added GetHistogram
00063  *
00064  * Revision 1.11  2000/03/08 19:59:16  warmerda
00065  * added GDALFlushRasterCache
00066  *
00067  * Revision 1.10  2000/03/06 21:50:37  warmerda
00068  * added min/max support
00069  *
00070  * Revision 1.9  2000/03/06 02:22:01  warmerda
00071  * added overviews, colour tables, and many other methods
00072  *
00073  * Revision 1.8  2000/02/28 16:34:28  warmerda
00074  * added arg window check in RasterIO()
00075  *
00076  * Revision 1.7  1999/11/17 16:18:10  warmerda
00077  * fixed example code
00078  *
00079  * Revision 1.6  1999/10/21 13:24:37  warmerda
00080  * Fixed some build breaking variable name differences.
00081  *
00082  * Revision 1.5  1999/10/01 14:44:02  warmerda
00083  * added documentation
00084  *
00085  * Revision 1.4  1998/12/31 18:54:25  warmerda
00086  * Implement initial GDALRasterBlock support, and block cache
00087  *
00088  * Revision 1.3  1998/12/06 22:17:09  warmerda
00089  * Fill out rasterio support.
00090  *
00091  * Revision 1.2  1998/12/06 02:52:08  warmerda
00092  * Added new methods, and C cover functions.
00093  *
00094  * Revision 1.1  1998/12/03 18:32:01  warmerda
00095  * New
00096  */
00097 
00098 #include "gdal_priv.h"
00099 #include "cpl_string.h"
00100 
00101 /************************************************************************/
00102 /*                           GDALRasterBand()                           */
00103 /************************************************************************/
00104 
00107 GDALRasterBand::GDALRasterBand()
00108 
00109 {
00110     poDS = NULL;
00111     nBand = 0;
00112 
00113     eAccess = GA_ReadOnly;
00114     nBlockXSize = nBlockYSize = -1;
00115     eDataType = GDT_Byte;
00116 
00117     nBlocksPerRow = 0;
00118     nBlocksPerColumn = 0;
00119 
00120     papoBlocks = NULL;
00121 }
00122 
00123 /************************************************************************/
00124 /*                          ~GDALRasterBand()                           */
00125 /************************************************************************/
00126 
00130 GDALRasterBand::~GDALRasterBand()
00131 
00132 {
00133     FlushCache();
00134     
00135     CPLFree( papoBlocks );
00136 }
00137 
00138 /************************************************************************/
00139 /*                              RasterIO()                              */
00140 /************************************************************************/
00141 
00207 CPLErr GDALRasterBand::RasterIO( GDALRWFlag eRWFlag,
00208                                  int nXOff, int nYOff, int nXSize, int nYSize,
00209                                  void * pData, int nBufXSize, int nBufYSize,
00210                                  GDALDataType eBufType,
00211                                  int nPixelSpace,
00212                                  int nLineSpace )
00213 
00214 {
00215 /* -------------------------------------------------------------------- */
00216 /*      If pixel and line spaceing are defaulted assign reasonable      */
00217 /*      value assuming a packed buffer.                                 */
00218 /* -------------------------------------------------------------------- */
00219     if( nPixelSpace == 0 )
00220         nPixelSpace = GDALGetDataTypeSize( eBufType ) / 8;
00221     
00222     if( nLineSpace == 0 )
00223         nLineSpace = nPixelSpace * nBufXSize;
00224     
00225 /* -------------------------------------------------------------------- */
00226 /*      Do some validation of parameters.                               */
00227 /* -------------------------------------------------------------------- */
00228     if( nXOff < 0 || nXOff + nXSize > nRasterXSize
00229         || nYOff < 0 || nYOff + nYSize > nRasterYSize )
00230     {
00231         CPLError( CE_Failure, CPLE_IllegalArg,
00232                   "Access window out of range in RasterIO().  Requested\n"
00233                   "(%d,%d) of size %dx%d on raster of %dx%d.",
00234                   nXOff, nYOff, nXSize, nYSize, nRasterXSize, nRasterYSize );
00235         return CE_Failure;
00236     }
00237 
00238 /* -------------------------------------------------------------------- */
00239 /*      Some size values are "noop".  Lets just return to avoid         */
00240 /*      stressing lower level functions.                                */
00241 /* -------------------------------------------------------------------- */
00242     if( nXSize < 1 || nYSize < 1 || nBufXSize < 1 || nBufYSize < 1 )
00243     {
00244         CPLDebug( "GDAL", 
00245                   "RasterIO() skipped for odd window or buffer size.\n"
00246                   "  Window = (%d,%d)x%dx%d\n"
00247                   "  Buffer = %dx%d\n",
00248                   nXOff, nYOff, nXSize, nYSize, 
00249                   nBufXSize, nBufYSize );
00250 
00251         return CE_None;
00252     }
00253     
00254 /* -------------------------------------------------------------------- */
00255 /*      Call the format specific function.                              */
00256 /* -------------------------------------------------------------------- */
00257     return( IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
00258                        pData, nBufXSize, nBufYSize, eBufType,
00259                        nPixelSpace, nLineSpace ) );
00260 }
00261 
00262 /************************************************************************/
00263 /*                            GDALRasterIO()                            */
00264 /************************************************************************/
00265 
00266 CPLErr GDALRasterIO( GDALRasterBandH hBand, GDALRWFlag eRWFlag,
00267                      int nXOff, int nYOff,
00268                      int nXSize, int nYSize,
00269                      void * pData,
00270                      int nBufXSize, int nBufYSize,
00271                      GDALDataType eBufType,
00272                      int nPixelSpace,
00273                      int nLineSpace )
00274 
00275 {
00276     GDALRasterBand      *poBand = (GDALRasterBand *) hBand;
00277 
00278     return( poBand->RasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
00279                               pData, nBufXSize, nBufYSize, eBufType,
00280                               nPixelSpace, nLineSpace ) );
00281 }
00282                      
00283 /************************************************************************/
00284 /*                             ReadBlock()                              */
00285 /************************************************************************/
00286 
00369 CPLErr GDALRasterBand::ReadBlock( int nXBlockOff, int nYBlockOff,
00370                                    void * pImage )
00371 
00372 {
00373 /* -------------------------------------------------------------------- */
00374 /*      Validate arguments.                                             */
00375 /* -------------------------------------------------------------------- */
00376     CPLAssert( pImage != NULL );
00377     
00378     if( nXBlockOff < 0
00379         || nXBlockOff*nBlockXSize >= nRasterXSize )
00380     {
00381         CPLError( CE_Failure, CPLE_IllegalArg,
00382                   "Illegal nXBlockOff value (%d) in "
00383                         "GDALRasterBand::ReadBlock()\n",
00384                   nXBlockOff );
00385 
00386         return( CE_Failure );
00387     }
00388 
00389     if( nYBlockOff < 0
00390         || nYBlockOff*nBlockYSize >= nRasterYSize )
00391     {
00392         CPLError( CE_Failure, CPLE_IllegalArg,
00393                   "Illegal nYBlockOff value (%d) in "
00394                         "GDALRasterBand::ReadBlock()\n",
00395                   nYBlockOff );
00396 
00397         return( CE_Failure );
00398     }
00399     
00400 /* -------------------------------------------------------------------- */
00401 /*      Invoke underlying implementation method.                        */
00402 /* -------------------------------------------------------------------- */
00403     return( IReadBlock( nXBlockOff, nYBlockOff, pImage ) );
00404 }
00405 
00406 /************************************************************************/
00407 /*                           GDALReadBlock()                            */
00408 /************************************************************************/
00409 
00410 CPLErr GDALReadBlock( GDALRasterBandH hBand, int nXOff, int nYOff,
00411                       void * pData )
00412 
00413 {
00414     GDALRasterBand      *poBand = (GDALRasterBand *) hBand;
00415 
00416     return( poBand->ReadBlock( nXOff, nYOff, pData ) );
00417 }
00418 
00419 /************************************************************************/
00420 /*                            IWriteBlock()                             */
00421 /*                                                                      */
00422 /*      Default internal implementation ... to be overriden by          */
00423 /*      subclasses that support writing.                                */
00424 /************************************************************************/
00425 
00426 CPLErr GDALRasterBand::IWriteBlock( int, int, void * )
00427 
00428 {
00429     CPLError( CE_Failure, CPLE_NotSupported,
00430               "WriteBlock() not supported for this dataset." );
00431     
00432     return( CE_Failure );
00433 }
00434 
00435 /************************************************************************/
00436 /*                             WriteBlock()                             */
00437 /************************************************************************/
00438 
00469 CPLErr GDALRasterBand::WriteBlock( int nXBlockOff, int nYBlockOff,
00470                                    void * pImage )
00471 
00472 {
00473 /* -------------------------------------------------------------------- */
00474 /*      Validate arguments.                                             */
00475 /* -------------------------------------------------------------------- */
00476     CPLAssert( pImage != NULL );
00477     
00478     if( nXBlockOff < 0
00479         || nXBlockOff*nBlockXSize >= GetXSize() )
00480     {
00481         CPLError( CE_Failure, CPLE_IllegalArg,
00482                   "Illegal nXBlockOff value (%d) in "
00483                         "GDALRasterBand::WriteBlock()\n",
00484                   nXBlockOff );
00485 
00486         return( CE_Failure );
00487     }
00488 
00489     if( nYBlockOff < 0
00490         || nYBlockOff*nBlockYSize >= GetYSize() )
00491     {
00492         CPLError( CE_Failure, CPLE_IllegalArg,
00493                   "Illegal nYBlockOff value (%d) in "
00494                         "GDALRasterBand::WriteBlock()\n",
00495                   nYBlockOff );
00496 
00497         return( CE_Failure );
00498     }
00499 
00500     if( eAccess == GA_ReadOnly )
00501     {
00502         CPLError( CE_Failure, CPLE_NoWriteAccess,
00503                   "Attempt to write to read only dataset in"
00504                   "GDALRasterBand::WriteBlock().\n" );
00505 
00506         return( CE_Failure );
00507     }
00508     
00509 /* -------------------------------------------------------------------- */
00510 /*      Invoke underlying implementation method.                        */
00511 /* -------------------------------------------------------------------- */
00512     return( IWriteBlock( nXBlockOff, nYBlockOff, pImage ) );
00513 }
00514 
00515 /************************************************************************/
00516 /*                           GDALWriteBlock()                           */
00517 /************************************************************************/
00518 
00519 CPLErr GDALWriteBlock( GDALRasterBandH hBand, int nXOff, int nYOff,
00520                        void * pData )
00521 
00522 {
00523     GDALRasterBand      *poBand = (GDALRasterBand *) hBand;
00524 
00525     return( poBand->WriteBlock( nXOff, nYOff, pData ) );
00526 }
00527 
00528 
00529 /************************************************************************/
00530 /*                         GetRasterDataType()                          */
00531 /************************************************************************/
00532 
00540 GDALDataType GDALRasterBand::GetRasterDataType()
00541 
00542 {
00543     return eDataType;
00544 }
00545 
00546 /************************************************************************/
00547 /*                       GDALGetRasterDataType()                        */
00548 /************************************************************************/
00549 
00550 GDALDataType GDALGetRasterDataType( GDALRasterBandH hBand )
00551 
00552 {
00553     return( ((GDALRasterBand *) hBand)->GetRasterDataType() );
00554 }
00555 
00556 /************************************************************************/
00557 /*                            GetBlockSize()                            */
00558 /************************************************************************/
00559 
00580 void GDALRasterBand::GetBlockSize( int * pnXSize, int *pnYSize )
00581 
00582 {
00583     CPLAssert( nBlockXSize > 0 && nBlockYSize > 0 );
00584     
00585     if( pnXSize != NULL )
00586         *pnXSize = nBlockXSize;
00587     if( pnYSize != NULL )
00588         *pnYSize = nBlockYSize;
00589 }
00590 
00591 /************************************************************************/
00592 /*                          GDALGetBlockSize()                          */
00593 /************************************************************************/
00594 
00595 void GDALGetBlockSize( GDALRasterBandH hBand, int * pnXSize, int * pnYSize )
00596 
00597 {
00598     GDALRasterBand      *poBand = (GDALRasterBand *) hBand;
00599 
00600     poBand->GetBlockSize( pnXSize, pnYSize );
00601 }
00602 
00603 /************************************************************************/
00604 /*                           InitBlockInfo()                            */
00605 /************************************************************************/
00606 
00607 void GDALRasterBand::InitBlockInfo()
00608 
00609 {
00610     if( papoBlocks != NULL )
00611         return;
00612 
00613     CPLAssert( nBlockXSize > 0 && nBlockYSize > 0 );
00614     
00615     nBlocksPerRow = (nRasterXSize+nBlockXSize-1) / nBlockXSize;
00616     nBlocksPerColumn = (nRasterYSize+nBlockYSize-1) / nBlockYSize;
00617     
00618     papoBlocks = (GDALRasterBlock **)
00619         CPLCalloc( sizeof(void*), nBlocksPerRow * nBlocksPerColumn );
00620 }
00621 
00622 
00623 /************************************************************************/
00624 /*                             AdoptBlock()                             */
00625 /*                                                                      */
00626 /*      Add a block to the raster band's block matrix.  If this         */
00627 /*      exceeds our maximum blocks for this layer, flush the oldest     */
00628 /*      block out.                                                      */
00629 /*                                                                      */
00630 /*      This method is protected.                                       */
00631 /************************************************************************/
00632 
00633 CPLErr GDALRasterBand::AdoptBlock( int nBlockXOff, int nBlockYOff,
00634                                    GDALRasterBlock * poBlock )
00635 
00636 {
00637     int         nBlockIndex;
00638     
00639     InitBlockInfo();
00640     
00641     CPLAssert( nBlockXOff >= 0 && nBlockXOff < nBlocksPerRow );
00642     CPLAssert( nBlockYOff >= 0 && nBlockYOff < nBlocksPerColumn );
00643 
00644     nBlockIndex = nBlockXOff + nBlockYOff * nBlocksPerRow;
00645     if( papoBlocks[nBlockIndex] == poBlock )
00646         return( CE_None );
00647 
00648     if( papoBlocks[nBlockIndex] != NULL )
00649         FlushBlock( nBlockXOff, nBlockYOff );
00650 
00651     papoBlocks[nBlockIndex] = poBlock;
00652     poBlock->Touch();
00653 
00654     return( CE_None );
00655 }
00656 
00657 /************************************************************************/
00658 /*                             FlushCache()                             */
00659 /************************************************************************/
00660 
00672 CPLErr GDALRasterBand::FlushCache()
00673 
00674 {
00675     for( int iY = 0; iY < nBlocksPerColumn; iY++ )
00676     {
00677         for( int iX = 0; iX < nBlocksPerRow; iX++ )
00678         {
00679             if( papoBlocks[iX + iY*nBlocksPerRow] != NULL )
00680             {
00681                 CPLErr    eErr;
00682 
00683                 eErr = FlushBlock( iX, iY );
00684 
00685                 if( eErr != CE_None )
00686                     return eErr;
00687             }
00688         }
00689     }
00690 
00691     return( CE_None );
00692 }
00693 
00694 /************************************************************************/
00695 /*                        GDALFlushRasterCache()                        */
00696 /************************************************************************/
00697 
00698 CPLErr GDALFlushRasterCache( GDALRasterBandH hBand )
00699 
00700 {
00701     return ((GDALRasterBand *) hBand)->FlushCache();
00702 }
00703 
00704 /************************************************************************/
00705 /*                             FlushBlock()                             */
00706 /*                                                                      */
00707 /*      Flush a block out of the block cache.  If it has been           */
00708 /*      modified write it to disk.  If no specific tile is              */
00709 /*      indicated, write the oldest tile.                               */
00710 /*                                                                      */
00711 /*      Protected method.                                               */
00712 /************************************************************************/
00713 
00714 CPLErr GDALRasterBand::FlushBlock( int nBlockXOff, int nBlockYOff )
00715 
00716 {
00717     int         nBlockIndex;
00718     GDALRasterBlock *poBlock;
00719     CPLErr      eErr = CE_None;
00720         
00721     InitBlockInfo();
00722     
00723 /* -------------------------------------------------------------------- */
00724 /*      Validate                                                        */
00725 /* -------------------------------------------------------------------- */
00726     CPLAssert( nBlockXOff >= 0 && nBlockXOff < nBlocksPerRow );
00727     CPLAssert( nBlockYOff >= 0 && nBlockYOff < nBlocksPerColumn );
00728 
00729     nBlockIndex = nBlockXOff + nBlockYOff * nBlocksPerRow;
00730     poBlock = papoBlocks[nBlockIndex];
00731     if( poBlock == NULL )
00732         return( CE_None );
00733 
00734 /* -------------------------------------------------------------------- */
00735 /*      Remove, and update count.                                       */
00736 /* -------------------------------------------------------------------- */
00737     papoBlocks[nBlockIndex] = NULL;
00738 
00739 /* -------------------------------------------------------------------- */
00740 /*      Is the target block dirty?  If so we need to write it.          */
00741 /* -------------------------------------------------------------------- */
00742     if( poBlock->GetDirty() )
00743         poBlock->Write();
00744 
00745 /* -------------------------------------------------------------------- */
00746 /*      Deallocate the block;                                           */
00747 /* -------------------------------------------------------------------- */
00748     delete poBlock;
00749 
00750     return( eErr );
00751 }
00752 
00753 
00754 /************************************************************************/
00755 /*                            GetBlockRef()                             */
00756 /************************************************************************/
00757 
00773 GDALRasterBlock * GDALRasterBand::GetBlockRef( int nXBlockOff,
00774                                                int nYBlockOff )
00775 
00776 {
00777     int         nBlockIndex;
00778 
00779     InitBlockInfo();
00780     
00781 /* -------------------------------------------------------------------- */
00782 /*      Validate the request                                            */
00783 /* -------------------------------------------------------------------- */
00784     if( nXBlockOff < 0 || nXBlockOff >= nBlocksPerRow )
00785     {
00786         CPLError( CE_Failure, CPLE_IllegalArg,
00787                   "Illegal nBlockXOff value (%d) in "
00788                         "GDALRasterBand::GetBlockRef()\n",
00789                   nXBlockOff );
00790 
00791         return( NULL );
00792     }
00793 
00794     if( nYBlockOff < 0 || nYBlockOff >= nBlocksPerColumn )
00795     {
00796         CPLError( CE_Failure, CPLE_IllegalArg,
00797                   "Illegal nBlockYOff value (%d) in "
00798                         "GDALRasterBand::GetBlockRef()\n",
00799                   nYBlockOff );
00800 
00801         return( NULL );
00802     }
00803 
00804 /* -------------------------------------------------------------------- */
00805 /*      If the block isn't already in the cache, we will need to        */
00806 /*      create it, read into it, and adopt it.  Adopting it may         */
00807 /*      flush an old tile from the cache.                               */
00808 /* -------------------------------------------------------------------- */
00809     nBlockIndex = nXBlockOff + nYBlockOff * nBlocksPerRow;
00810     
00811     if( papoBlocks[nBlockIndex] == NULL )
00812     {
00813         GDALRasterBlock *poBlock;
00814         
00815         poBlock = new GDALRasterBlock( this, nXBlockOff, nYBlockOff );
00816 
00817         /* allocate data space */
00818         if( poBlock->Internalize() != CE_None )
00819         {
00820             delete poBlock;
00821 
00822             return( NULL );
00823         }
00824 
00825         if( IReadBlock(nXBlockOff,nYBlockOff,poBlock->GetDataRef()) != CE_None)
00826         {
00827             delete poBlock;
00828             return( NULL );
00829         }
00830 
00831         AdoptBlock( nXBlockOff, nYBlockOff, poBlock );
00832     }
00833 
00834 /* -------------------------------------------------------------------- */
00835 /*      Every read access updates the last touched time.                */
00836 /* -------------------------------------------------------------------- */
00837     if( papoBlocks[nBlockIndex] != NULL )
00838         papoBlocks[nBlockIndex]->Touch();
00839 
00840     return( papoBlocks[nBlockIndex] );
00841 }
00842 
00843 /************************************************************************/
00844 /*                             GetAccess()                              */
00845 /************************************************************************/
00846 
00853 GDALAccess GDALRasterBand::GetAccess()
00854 
00855 {
00856     return eAccess;
00857 }
00858 
00859 /************************************************************************/
00860 /*                          GetCategoryNames()                          */
00861 /************************************************************************/
00862 
00878 char **GDALRasterBand::GetCategoryNames()
00879 
00880 {
00881     return NULL;
00882 }
00883 
00884 /************************************************************************/
00885 /*                     GDALGetRasterCategoryNames()                     */
00886 /************************************************************************/
00887 
00888 char **GDALGetRasterCategoryNames( GDALRasterBandH hBand )
00889 
00890 {
00891     return ((GDALRasterBand *) hBand)->GetCategoryNames();
00892 }
00893 
00894 /************************************************************************/
00895 /*                          SetCategoryNames()                          */
00896 /************************************************************************/
00897 
00913 CPLErr GDALRasterBand::SetCategoryNames( char ** )
00914 
00915 {
00916     return CE_Failure;
00917 }
00918 
00919 /************************************************************************/
00920 /*                        GDALSetCategoryNames()                        */
00921 /************************************************************************/
00922 
00923 CPLErr GDALSetRasterCategoryNames( GDALRasterBandH hBand, char ** papszNames )
00924 
00925 {
00926     return ((GDALRasterBand *) hBand)->SetCategoryNames( papszNames );
00927 }
00928 
00929 /************************************************************************/
00930 /*                           GetNoDataValue()                           */
00931 /************************************************************************/
00932 
00949 double GDALRasterBand::GetNoDataValue( int *pbSuccess )
00950 
00951 {
00952     if( pbSuccess != NULL )
00953         *pbSuccess = FALSE;
00954     
00955     return -1e10;
00956 }
00957 
00958 /************************************************************************/
00959 /*                      GDALGetRasterNoDataValue()                      */
00960 /************************************************************************/
00961 
00962 double GDALGetRasterNoDataValue( GDALRasterBandH hBand, int *pbSuccess )
00963 
00964 {
00965     return ((GDALRasterBand *) hBand)->GetNoDataValue( pbSuccess );
00966 }
00967 
00968 /************************************************************************/
00969 /*                           SetNoDataValue()                           */
00970 /************************************************************************/
00971 
00987 CPLErr GDALRasterBand::SetNoDataValue( double )
00988 
00989 {
00990     return CE_Failure;
00991 }
00992 
00993 /************************************************************************/
00994 /*                         GDALSetRasterNoDataValue()                   */
00995 /************************************************************************/
00996 
00997 CPLErr GDALSetRasterNoDataValue( GDALRasterBandH hBand, double dfValue )
00998 
00999 {
01000     return ((GDALRasterBand *) hBand)->SetNoDataValue( dfValue );
01001 }
01002 
01003 /************************************************************************/
01004 /*                             GetMaximum()                             */
01005 /************************************************************************/
01006 
01021 double GDALRasterBand::GetMaximum( int *pbSuccess )
01022 
01023 {
01024     if( pbSuccess != NULL )
01025         *pbSuccess = FALSE;
01026 
01027     switch( eDataType )
01028     {
01029       case GDT_Byte:
01030         return 255;
01031 
01032       case GDT_UInt16:
01033         return 65535;
01034 
01035       case GDT_Int16:
01036       case GDT_CInt16:
01037         return 32767;
01038 
01039       case GDT_Int32:
01040       case GDT_CInt32:
01041         return 2147483647.0;
01042 
01043       case GDT_UInt32:
01044         return 4294967295.0;
01045 
01046       case GDT_Float32:
01047       case GDT_CFloat32:
01048         return 4294967295.0; /* not actually accurate */
01049 
01050       case GDT_Float64:
01051       case GDT_CFloat64:
01052         return 4294967295.0; /* not actually accurate */
01053 
01054       default:
01055         return 4294967295.0; /* not actually accurate */
01056     }
01057 }
01058 
01059 /************************************************************************/
01060 /*                        GDALGetRasterMaximum()                        */
01061 /************************************************************************/
01062 
01063 double GDALGetRasterMaximum( GDALRasterBandH hBand, int *pbSuccess )
01064 
01065 {
01066     return ((GDALRasterBand *) hBand)->GetMaximum( pbSuccess );
01067 }
01068 
01069 /************************************************************************/
01070 /*                             GetMinimum()                             */
01071 /************************************************************************/
01072 
01087 double GDALRasterBand::GetMinimum( int *pbSuccess )
01088 
01089 {
01090     if( pbSuccess != NULL )
01091         *pbSuccess = FALSE;
01092 
01093     switch( eDataType )
01094     {
01095       case GDT_Byte:
01096         return 0;
01097 
01098       case GDT_UInt16:
01099         return 0;
01100 
01101       case GDT_Int16:
01102         return -32768;
01103 
01104       case GDT_Int32:
01105         return -2147483648.0;
01106 
01107       case GDT_UInt32:
01108         return 0;
01109 
01110       case GDT_Float32:
01111         return -4294967295.0; /* not actually accurate */
01112 
01113       case GDT_Float64:
01114         return -4294967295.0; /* not actually accurate */
01115 
01116       default:
01117         return -4294967295.0; /* not actually accurate */
01118     }
01119 }
01120 
01121 /************************************************************************/
01122 /*                        GDALGetRasterMinimum()                        */
01123 /************************************************************************/
01124 
01125 double GDALGetRasterMinimum( GDALRasterBandH hBand, int *pbSuccess )
01126 
01127 {
01128     return ((GDALRasterBand *) hBand)->GetMinimum( pbSuccess );
01129 }
01130 
01131 /************************************************************************/
01132 /*                       GetColorInterpretation()                       */
01133 /************************************************************************/
01134 
01147 GDALColorInterp GDALRasterBand::GetColorInterpretation()
01148 
01149 {
01150     return GCI_Undefined;
01151 }
01152 
01153 /************************************************************************/
01154 /*                  GDALGetRasterColorInterpretation()                  */
01155 /************************************************************************/
01156 
01157 GDALColorInterp GDALGetRasterColorInterpretation( GDALRasterBandH hBand )
01158 
01159 {
01160     return ((GDALRasterBand *) hBand)->GetColorInterpretation();
01161 }
01162 
01163 /************************************************************************/
01164 /*                           GetColorTable()                            */
01165 /************************************************************************/
01166 
01179 GDALColorTable *GDALRasterBand::GetColorTable()
01180 
01181 {
01182     return NULL;
01183 }
01184 
01185 /************************************************************************/
01186 /*                      GDALGetRasterColorTable()                       */
01187 /************************************************************************/
01188 
01189 GDALColorTableH GDALGetRasterColorTable( GDALRasterBandH hBand )
01190 
01191 {
01192     return (GDALColorTableH) ((GDALRasterBand *) hBand)->GetColorTable();
01193 }
01194 
01195 /************************************************************************/
01196 /*                           SetColorTable()                            */
01197 /************************************************************************/
01198 
01214 CPLErr GDALRasterBand::SetColorTable( GDALColorTable * poCT )
01215 
01216 {
01217     return CE_Failure;
01218 }
01219 
01220 /************************************************************************/
01221 /*                      GDALSetRasterColorTable()                       */
01222 /************************************************************************/
01223 
01224 CPLErr GDALSetRasterColorTable( GDALRasterBandH hBand, GDALColorTableH hCT )
01225 
01226 {
01227     return ((GDALRasterBand *) hBand)->SetColorTable( (GDALColorTable *) hCT );
01228 }
01229 
01230 /************************************************************************/
01231 /*                       HasArbitraryOverviews()                        */
01232 /************************************************************************/
01233 
01249 int GDALRasterBand::HasArbitraryOverviews()
01250 
01251 {
01252     return FALSE;
01253 }
01254 
01255 /************************************************************************/
01256 /*                     GDALHasArbitraryOverviews()                      */
01257 /************************************************************************/
01258 
01259 int GDALHasArbitraryOverviews( GDALRasterBandH hBand )
01260 
01261 {
01262     return ((GDALRasterBand *) hBand)->HasArbitraryOverviews();
01263 }
01264 
01265 /************************************************************************/
01266 /*                          GetOverviewCount()                          */
01267 /************************************************************************/
01268 
01277 int GDALRasterBand::GetOverviewCount()
01278 
01279 {
01280     if( poDS != NULL && poDS->oOvManager.IsInitialized() )
01281         return poDS->oOvManager.GetOverviewCount( nBand );
01282     else
01283         return 0;
01284 }
01285 
01286 /************************************************************************/
01287 /*                        GDALGetOverviewCount()                        */
01288 /************************************************************************/
01289 
01290 int GDALGetOverviewCount( GDALRasterBandH hBand )
01291 
01292 {
01293     return ((GDALRasterBand *) hBand)->GetOverviewCount();
01294 }
01295 
01296 
01297 /************************************************************************/
01298 /*                            GetOverview()                             */
01299 /************************************************************************/
01300 
01311 GDALRasterBand * GDALRasterBand::GetOverview( int i )
01312 
01313 {
01314     if( poDS != NULL && poDS->oOvManager.IsInitialized() )
01315         return poDS->oOvManager.GetOverview( nBand, i );
01316     else
01317         return NULL;
01318 }
01319 
01320 /************************************************************************/
01321 /*                          GDALGetOverview()                           */
01322 /************************************************************************/
01323 
01324 GDALRasterBandH GDALGetOverview( GDALRasterBandH hBand, int i )
01325 
01326 {
01327     return (GDALRasterBandH) ((GDALRasterBand *) hBand)->GetOverview(i);
01328 }
01329 
01330 /************************************************************************/
01331 /*                           BuildOverviews()                           */
01332 /************************************************************************/
01333 
01350 CPLErr GDALRasterBand::BuildOverviews( const char *pszResampling, 
01351                                        int nOverviews, int *panOverviewList, 
01352                                        GDALProgressFunc pfnProgress, 
01353                                        void * pProgressData )
01354 
01355 {
01356     CPLError( CE_Failure, CPLE_NotSupported,
01357               "BuildOverviews() not supported for this dataset." );
01358     
01359     return( CE_Failure );
01360 }
01361 
01362 /************************************************************************/
01363 /*                             GetOffset()                              */
01364 /************************************************************************/
01365 
01385 double GDALRasterBand::GetOffset( int *pbSuccess )
01386 
01387 {
01388     if( pbSuccess != NULL )
01389         *pbSuccess = FALSE;
01390 
01391     return 0.0;
01392 }
01393 
01394 /************************************************************************/
01395 /*                              GetScale()                              */
01396 /************************************************************************/
01397 
01417 double GDALRasterBand::GetScale( int *pbSuccess )
01418 
01419 {
01420     if( pbSuccess != NULL )
01421         *pbSuccess = FALSE;
01422 
01423     return 1.0;
01424 }
01425 
01426 /************************************************************************/
01427 /*                           GetDescription()                           */
01428 /************************************************************************/
01429 
01436 const char *GDALRasterBand::GetDescription()
01437 
01438 {
01439     return "";
01440 }
01441 
01442 
01443 /************************************************************************/
01444 /*                            GetUnitType()                             */
01445 /************************************************************************/
01446 
01460 const char *GDALRasterBand::GetUnitType()
01461 
01462 {
01463     return "";
01464 }
01465 
01466 /************************************************************************/
01467 /*                       GDALGetRasterUnitType()                        */
01468 /************************************************************************/
01469 
01470 const char *GDALGetRasterUnitType( GDALRasterBandH hBand )
01471 
01472 {
01473     return ((GDALRasterBand *) hBand)->GetUnitType();
01474 }
01475 
01476 /************************************************************************/
01477 /*                              GetXSize()                              */
01478 /************************************************************************/
01479 
01488 int GDALRasterBand::GetXSize()
01489 
01490 {
01491     return nRasterXSize;
01492 }
01493 
01494 /************************************************************************/
01495 /*                       GDALGetRasterBandXSize()                       */
01496 /************************************************************************/
01497 
01498 int GDALGetRasterBandXSize( GDALRasterBandH hBand )
01499 
01500 {
01501     return ((GDALRasterBand *) hBand)->GetXSize();
01502 }
01503 
01504 /************************************************************************/
01505 /*                              GetYSize()                              */
01506 /************************************************************************/
01507 
01516 int GDALRasterBand::GetYSize()
01517 
01518 {
01519     return nRasterYSize;
01520 }
01521 
01522 /************************************************************************/
01523 /*                       GDALGetRasterBandYSize()                       */
01524 /************************************************************************/
01525 
01526 int GDALGetRasterBandYSize( GDALRasterBandH hBand )
01527 
01528 {
01529     return ((GDALRasterBand *) hBand)->GetYSize();
01530 }
01531 
01532 /************************************************************************/
01533 /*                            GetHistogram()                            */
01534 /************************************************************************/
01535 
01572 CPLErr GDALRasterBand::GetHistogram( double dfMin, double dfMax, 
01573                                      int nBuckets, int *panHistogram, 
01574                                      int bIncludeOutOfRange, int bApproxOK,
01575                                      GDALProgressFunc pfnProgress, 
01576                                      void *pProgressData )
01577 
01578 {
01579     CPLAssert( pfnProgress != NULL );
01580 
01581 /* -------------------------------------------------------------------- */
01582 /*      If we have overviews, use them for the histogram.               */
01583 /* -------------------------------------------------------------------- */
01584     if( bApproxOK && GetOverviewCount() > 0 )
01585     {
01586         double dfBestPixels = GetXSize() * GetYSize();
01587         GDALRasterBand *poBestOverview = NULL;
01588         
01589         for( int i = 0; i < GetOverviewCount(); i++ )
01590         {
01591             GDALRasterBand *poOverview = GetOverview(i);
01592             double         dfPixels;
01593 
01594             dfPixels = poOverview->GetXSize() * poOverview->GetYSize();
01595             if( dfPixels < dfBestPixels )
01596             {
01597                 dfBestPixels = dfPixels;
01598                 poBestOverview = poOverview;
01599             }
01600             
01601             if( poBestOverview != NULL )
01602                 return poBestOverview->
01603                     GetHistogram( dfMin, dfMax, nBuckets, panHistogram, 
01604                                   bIncludeOutOfRange, bApproxOK, 
01605                                   pfnProgress, pProgressData );
01606         }
01607     }
01608 
01609 /* -------------------------------------------------------------------- */
01610 /*      Figure out the ratio of blocks we will read to get an           */
01611 /*      approximate value.                                              */
01612 /* -------------------------------------------------------------------- */
01613     int         nBlockXSize, nBlockYSize;
01614     int         nBlocksPerRow, nBlocksPerColumn;
01615     int         nSampleRate;
01616     double      dfScale;
01617 
01618     GetBlockSize( &nBlockXSize, &nBlockYSize );
01619     nBlocksPerRow = (GetXSize() + nBlockXSize - 1) / nBlockXSize;
01620     nBlocksPerColumn = (GetYSize() + nBlockYSize - 1) / nBlockYSize;
01621 
01622     if( bApproxOK )
01623         nSampleRate = 
01624             (int) MAX(1,sqrt((double) nBlocksPerRow * nBlocksPerColumn));
01625     else
01626         nSampleRate = 1;
01627     
01628     dfScale = nBuckets / (dfMax - dfMin);
01629 
01630 /* -------------------------------------------------------------------- */
01631 /*      Read the blocks, and add to histogram.                          */
01632 /* -------------------------------------------------------------------- */
01633     memset( panHistogram, 0, sizeof(int) * nBuckets );
01634     for( int iSampleBlock = 0; 
01635          iSampleBlock < nBlocksPerRow * nBlocksPerColumn;
01636          iSampleBlock += nSampleRate )
01637     {
01638         double dfValue = 0.0;
01639         int  iXBlock, iYBlock, nXCheck, nYCheck;
01640         GDALRasterBlock *poBlock;
01641 
01642         if( !pfnProgress( iSampleBlock/(double)nBlocksPerRow*nBlocksPerColumn,
01643                           NULL, pProgressData ) )
01644             return CE_Failure;
01645 
01646         iYBlock = iSampleBlock / nBlocksPerRow;
01647         iXBlock = iSampleBlock - nBlocksPerRow * iYBlock;
01648         
01649         poBlock = GetBlockRef( iXBlock, iYBlock );
01650         if( poBlock == NULL )
01651             return CE_Failure;
01652         
01653         if( (iXBlock+1) * nBlockXSize > GetXSize() )
01654             nXCheck = GetXSize() - iXBlock * nBlockXSize;
01655         else
01656             nXCheck = nBlockXSize;
01657 
01658         if( (iYBlock+1) * nBlockYSize > GetYSize() )
01659             nYCheck = GetYSize() - iYBlock * nBlockYSize;
01660         else
01661             nYCheck = nBlockYSize;
01662 
01663         /* this is a special case for a common situation */
01664         if( poBlock->GetDataType() == GDT_Byte
01665             && dfScale == 1.0 && (dfMin >= -0.5 && dfMin <= 0.5)
01666             && nYCheck == nBlockYSize && nXCheck == nBlockXSize
01667             && nBuckets == 256 )
01668         {
01669             int    nPixels = nXCheck * nYCheck;
01670             GByte  *pabyData = (GByte *) poBlock->GetDataRef();
01671             
01672             for( int i = 0; i < nPixels; i++ )
01673                 panHistogram[pabyData[i]]++;
01674             
01675             continue; /* to next sample block */
01676         }
01677 
01678         /* this isn't the fastest way to do this, but is easier for now */
01679         for( int iY = 0; iY < nYCheck; iY++ )
01680         {
01681             for( int iX = 0; iX < nXCheck; iX++ )
01682             {
01683                 int    iOffset = iX + iY * nBlockXSize;
01684                 int    nIndex;
01685 
01686                 switch( poBlock->GetDataType() )
01687                 {
01688                   case GDT_Byte:
01689                     dfValue = ((GByte *) poBlock->GetDataRef())[iOffset];
01690                     break;
01691 
01692                   case GDT_UInt16:
01693                     dfValue = ((GUInt16 *) poBlock->GetDataRef())[iOffset];
01694                     break;
01695                   case GDT_Int16:
01696                     dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset];
01697                     break;
01698                   case GDT_UInt32:
01699                     dfValue = ((GUInt32 *) poBlock->GetDataRef())[iOffset];
01700                     break;
01701                   case GDT_Int32:
01702                     dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset];
01703                     break;
01704                   case GDT_Float32:
01705                     dfValue = ((float *) poBlock->GetDataRef())[iOffset];
01706                     break;
01707                   case GDT_Float64:
01708                     dfValue = ((double *) poBlock->GetDataRef())[iOffset];
01709                     break;
01710                   default:
01711                     CPLAssert( FALSE );
01712                     return CE_Failure;
01713                 }
01714                 
01715                 nIndex = (int) floor((dfValue - dfMin) * dfScale);
01716 
01717                 if( nIndex < 0 )
01718                 {
01719                     if( bIncludeOutOfRange )
01720                         panHistogram[0]++;
01721                 }
01722                 else if( nIndex >= nBuckets )
01723                 {
01724                     if( bIncludeOutOfRange )
01725                         panHistogram[nBuckets-1]++;
01726                 }
01727                 else
01728                 {
01729                     panHistogram[nIndex]++;
01730                 }
01731             }
01732         }
01733     }
01734 
01735     pfnProgress( 1.0, NULL, pProgressData );
01736 
01737     return CE_None;
01738 }
01739 
01740 /************************************************************************/
01741 /*                       GDALGetRasterHistogram()                       */
01742 /************************************************************************/
01743 
01744 CPLErr GDALGetRasterHistogram( GDALRasterBandH hBand, 
01745                                double dfMin, double dfMax, 
01746                                int nBuckets, int *panHistogram, 
01747                                int bIncludeOutOfRange, int bApproxOK,
01748                                GDALProgressFunc pfnProgress, 
01749                                void *pProgressData )
01750 
01751 {
01752     return ((GDALRasterBand *) hBand)->
01753         GetHistogram( dfMin, dfMax, nBuckets, panHistogram, 
01754                       bIncludeOutOfRange, bApproxOK,
01755                       pfnProgress, pProgressData );
01756 }

Generated at Thu Jul 5 09:16:13 2001 for GDAL by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000