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.10 2002/04/16 13:11:48 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.10  2002/04/16 13:11:48  warmerda
00030  * updated
00030  *
00031  * Revision 1.27  2002/03/01 14:29:09  warmerda
00032  * added GetBand() method on GDALRasterBand
00033  *
00034  * Revision 1.26  2001/12/07 15:29:45  warmerda
00035  * added InitBlockInfo() in GetHistogram()
00036  *
00037  * Revision 1.25  2001/10/18 14:35:22  warmerda
00038  * avoid conflicts between parameters and member data
00039  *
00040  * Revision 1.24  2001/10/17 16:20:45  warmerda
00041  * make histograming work with complex data (r(treat as magnitude)
00042  *
00043  * Revision 1.23  2001/07/18 04:04:30  warmerda
00044  * added CPL_CVSID
00045  *
00046  * Revision 1.22  2001/07/05 13:13:40  warmerda
00047  * added UnitType from C support
00048  *
00049  * Revision 1.21  2000/10/06 15:25:48  warmerda
00050  * added setnodata, and some other methods
00051  *
00052  * Revision 1.20  2000/08/25 14:26:51  warmerda
00053  * added GDALHasArbitraryOverviews
00054  *
00055  * Revision 1.19  2000/08/16 15:50:52  warmerda
00056  * fixed some bugs with floating (datasetless) bands
00057  *
00058  * Revision 1.18  2000/07/12 00:19:29  warmerda
00059  * Removed extra line feed.
00060  *
00061  * Revision 1.17  2000/06/05 17:24:05  warmerda
00062  * added real complex support
00063  *
00064  * Revision 1.16  2000/04/21 21:56:59  warmerda
00065  * moved metadata to GDALMajorObject
00066  *
00067  * Revision 1.15  2000/03/31 13:42:27  warmerda
00068  * added metadata support
00069  *
00070  * Revision 1.14  2000/03/24 00:09:05  warmerda
00071  * rewrote cache management
00072  *
00073  * Revision 1.13  2000/03/10 13:54:37  warmerda
00074  * fixed use of overviews in gethistogram
00075  *
00076  * Revision 1.12  2000/03/09 23:22:03  warmerda
00077  * added GetHistogram
00078  *
00079  * Revision 1.11  2000/03/08 19:59:16  warmerda
00080  * added GDALFlushRasterCache
00081  *
00082  * Revision 1.10  2000/03/06 21:50:37  warmerda
00083  * added min/max support
00084  *
00085  * Revision 1.9  2000/03/06 02:22:01  warmerda
00086  * added overviews, colour tables, and many other methods
00087  *
00088  * Revision 1.8  2000/02/28 16:34:28  warmerda
00089  * added arg window check in RasterIO()
00090  *
00091  * Revision 1.7  1999/11/17 16:18:10  warmerda
00092  * fixed example code
00093  *
00094  * Revision 1.6  1999/10/21 13:24:37  warmerda
00095  * Fixed some build breaking variable name differences.
00096  *
00097  * Revision 1.5  1999/10/01 14:44:02  warmerda
00098  * added documentation
00099  *
00100  * Revision 1.4  1998/12/31 18:54:25  warmerda
00101  * Implement initial GDALRasterBlock support, and block cache
00102  *
00103  * Revision 1.3  1998/12/06 22:17:09  warmerda
00104  * Fill out rasterio support.
00105  *
00106  * Revision 1.2  1998/12/06 02:52:08  warmerda
00107  * Added new methods, and C cover functions.
00108  *
00109  * Revision 1.1  1998/12/03 18:32:01  warmerda
00110  * New
00111  */
00112 
00113 #include "gdal_priv.h"
00114 #include "cpl_string.h"
00115 
00116 CPL_CVSID("$Id: gdalrasterband_cpp-source.html,v 1.10 2002/04/16 13:11:48 warmerda Exp $");
00117 
00118 /************************************************************************/
00119 /*                           GDALRasterBand()                           */
00120 /************************************************************************/
00121 
00124 GDALRasterBand::GDALRasterBand()
00125 
00126 {
00127     poDS = NULL;
00128     nBand = 0;
00129 
00130     eAccess = GA_ReadOnly;
00131     nBlockXSize = nBlockYSize = -1;
00132     eDataType = GDT_Byte;
00133 
00134     nBlocksPerRow = 0;
00135     nBlocksPerColumn = 0;
00136 
00137     papoBlocks = NULL;
00138 }
00139 
00140 /************************************************************************/
00141 /*                          ~GDALRasterBand()                           */
00142 /************************************************************************/
00143 
00147 GDALRasterBand::~GDALRasterBand()
00148 
00149 {
00150     FlushCache();
00151     
00152     CPLFree( papoBlocks );
00153 }
00154 
00155 /************************************************************************/
00156 /*                              RasterIO()                              */
00157 /************************************************************************/
00158 
00224 CPLErr GDALRasterBand::RasterIO( GDALRWFlag eRWFlag,
00225                                  int nXOff, int nYOff, int nXSize, int nYSize,
00226                                  void * pData, int nBufXSize, int nBufYSize,
00227                                  GDALDataType eBufType,
00228                                  int nPixelSpace,
00229                                  int nLineSpace )
00230 
00231 {
00232 /* -------------------------------------------------------------------- */
00233 /*      If pixel and line spaceing are defaulted assign reasonable      */
00234 /*      value assuming a packed buffer.                                 */
00235 /* -------------------------------------------------------------------- */
00236     if( nPixelSpace == 0 )
00237         nPixelSpace = GDALGetDataTypeSize( eBufType ) / 8;
00238     
00239     if( nLineSpace == 0 )
00240         nLineSpace = nPixelSpace * nBufXSize;
00241     
00242 /* -------------------------------------------------------------------- */
00243 /*      Do some validation of parameters.                               */
00244 /* -------------------------------------------------------------------- */
00245     if( nXOff < 0 || nXOff + nXSize > nRasterXSize
00246         || nYOff < 0 || nYOff + nYSize > nRasterYSize )
00247     {
00248         CPLError( CE_Failure, CPLE_IllegalArg,
00249                   "Access window out of range in RasterIO().  Requested\n"
00250                   "(%d,%d) of size %dx%d on raster of %dx%d.",
00251                   nXOff, nYOff, nXSize, nYSize, nRasterXSize, nRasterYSize );
00252         return CE_Failure;
00253     }
00254 
00255 /* -------------------------------------------------------------------- */
00256 /*      Some size values are "noop".  Lets just return to avoid         */
00257 /*      stressing lower level functions.                                */
00258 /* -------------------------------------------------------------------- */
00259     if( nXSize < 1 || nYSize < 1 || nBufXSize < 1 || nBufYSize < 1 )
00260     {
00261         CPLDebug( "GDAL", 
00262                   "RasterIO() skipped for odd window or buffer size.\n"
00263                   "  Window = (%d,%d)x%dx%d\n"
00264                   "  Buffer = %dx%d\n",
00265                   nXOff, nYOff, nXSize, nYSize, 
00266                   nBufXSize, nBufYSize );
00267 
00268         return CE_None;
00269     }
00270     
00271 /* -------------------------------------------------------------------- */
00272 /*      Call the format specific function.                              */
00273 /* -------------------------------------------------------------------- */
00274     return( IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
00275                        pData, nBufXSize, nBufYSize, eBufType,
00276                        nPixelSpace, nLineSpace ) );
00277 }
00278 
00279 /************************************************************************/
00280 /*                            GDALRasterIO()                            */
00281 /************************************************************************/
00282 
00283 CPLErr GDALRasterIO( GDALRasterBandH hBand, GDALRWFlag eRWFlag,
00284                      int nXOff, int nYOff,
00285                      int nXSize, int nYSize,
00286                      void * pData,
00287                      int nBufXSize, int nBufYSize,
00288                      GDALDataType eBufType,
00289                      int nPixelSpace,
00290                      int nLineSpace )
00291 
00292 {
00293     GDALRasterBand      *poBand = (GDALRasterBand *) hBand;
00294 
00295     return( poBand->RasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
00296                               pData, nBufXSize, nBufYSize, eBufType,
00297                               nPixelSpace, nLineSpace ) );
00298 }
00299                      
00300 /************************************************************************/
00301 /*                             ReadBlock()                              */
00302 /************************************************************************/
00303 
00386 CPLErr GDALRasterBand::ReadBlock( int nXBlockOff, int nYBlockOff,
00387                                    void * pImage )
00388 
00389 {
00390 /* -------------------------------------------------------------------- */
00391 /*      Validate arguments.                                             */
00392 /* -------------------------------------------------------------------- */
00393     CPLAssert( pImage != NULL );
00394     
00395     if( nXBlockOff < 0
00396         || nXBlockOff*nBlockXSize >= nRasterXSize )
00397     {
00398         CPLError( CE_Failure, CPLE_IllegalArg,
00399                   "Illegal nXBlockOff value (%d) in "
00400                         "GDALRasterBand::ReadBlock()\n",
00401                   nXBlockOff );
00402 
00403         return( CE_Failure );
00404     }
00405 
00406     if( nYBlockOff < 0
00407         || nYBlockOff*nBlockYSize >= nRasterYSize )
00408     {
00409         CPLError( CE_Failure, CPLE_IllegalArg,
00410                   "Illegal nYBlockOff value (%d) in "
00411                         "GDALRasterBand::ReadBlock()\n",
00412                   nYBlockOff );
00413 
00414         return( CE_Failure );
00415     }
00416     
00417 /* -------------------------------------------------------------------- */
00418 /*      Invoke underlying implementation method.                        */
00419 /* -------------------------------------------------------------------- */
00420     return( IReadBlock( nXBlockOff, nYBlockOff, pImage ) );
00421 }
00422 
00423 /************************************************************************/
00424 /*                           GDALReadBlock()                            */
00425 /************************************************************************/
00426 
00427 CPLErr GDALReadBlock( GDALRasterBandH hBand, int nXOff, int nYOff,
00428                       void * pData )
00429 
00430 {
00431     GDALRasterBand      *poBand = (GDALRasterBand *) hBand;
00432 
00433     return( poBand->ReadBlock( nXOff, nYOff, pData ) );
00434 }
00435 
00436 /************************************************************************/
00437 /*                            IWriteBlock()                             */
00438 /*                                                                      */
00439 /*      Default internal implementation ... to be overriden by          */
00440 /*      subclasses that support writing.                                */
00441 /************************************************************************/
00442 
00443 CPLErr GDALRasterBand::IWriteBlock( int, int, void * )
00444 
00445 {
00446     CPLError( CE_Failure, CPLE_NotSupported,
00447               "WriteBlock() not supported for this dataset." );
00448     
00449     return( CE_Failure );
00450 }
00451 
00452 /************************************************************************/
00453 /*                             WriteBlock()                             */
00454 /************************************************************************/
00455 
00486 CPLErr GDALRasterBand::WriteBlock( int nXBlockOff, int nYBlockOff,
00487                                    void * pImage )
00488 
00489 {
00490 /* -------------------------------------------------------------------- */
00491 /*      Validate arguments.                                             */
00492 /* -------------------------------------------------------------------- */
00493     CPLAssert( pImage != NULL );
00494     
00495     if( nXBlockOff < 0
00496         || nXBlockOff*nBlockXSize >= GetXSize() )
00497     {
00498         CPLError( CE_Failure, CPLE_IllegalArg,
00499                   "Illegal nXBlockOff value (%d) in "
00500                         "GDALRasterBand::WriteBlock()\n",
00501                   nXBlockOff );
00502 
00503         return( CE_Failure );
00504     }
00505 
00506     if( nYBlockOff < 0
00507         || nYBlockOff*nBlockYSize >= GetYSize() )
00508     {
00509         CPLError( CE_Failure, CPLE_IllegalArg,
00510                   "Illegal nYBlockOff value (%d) in "
00511                         "GDALRasterBand::WriteBlock()\n",
00512                   nYBlockOff );
00513 
00514         return( CE_Failure );
00515     }
00516 
00517     if( eAccess == GA_ReadOnly )
00518     {
00519         CPLError( CE_Failure, CPLE_NoWriteAccess,
00520                   "Attempt to write to read only dataset in"
00521                   "GDALRasterBand::WriteBlock().\n" );
00522 
00523         return( CE_Failure );
00524     }
00525     
00526 /* -------------------------------------------------------------------- */
00527 /*      Invoke underlying implementation method.                        */
00528 /* -------------------------------------------------------------------- */
00529     return( IWriteBlock( nXBlockOff, nYBlockOff, pImage ) );
00530 }
00531 
00532 /************************************************************************/
00533 /*                           GDALWriteBlock()                           */
00534 /************************************************************************/
00535 
00536 CPLErr GDALWriteBlock( GDALRasterBandH hBand, int nXOff, int nYOff,
00537                        void * pData )
00538 
00539 {
00540     GDALRasterBand      *poBand = (GDALRasterBand *) hBand;
00541 
00542     return( poBand->WriteBlock( nXOff, nYOff, pData ) );
00543 }
00544 
00545 
00546 /************************************************************************/
00547 /*                         GetRasterDataType()                          */
00548 /************************************************************************/
00549 
00557 GDALDataType GDALRasterBand::GetRasterDataType()
00558 
00559 {
00560     return eDataType;
00561 }
00562 
00563 /************************************************************************/
00564 /*                       GDALGetRasterDataType()                        */
00565 /************************************************************************/
00566 
00567 GDALDataType GDALGetRasterDataType( GDALRasterBandH hBand )
00568 
00569 {
00570     return( ((GDALRasterBand *) hBand)->GetRasterDataType() );
00571 }
00572 
00573 /************************************************************************/
00574 /*                            GetBlockSize()                            */
00575 /************************************************************************/
00576 
00597 void GDALRasterBand::GetBlockSize( int * pnXSize, int *pnYSize )
00598 
00599 {
00600     CPLAssert( nBlockXSize > 0 && nBlockYSize > 0 );
00601     
00602     if( pnXSize != NULL )
00603         *pnXSize = nBlockXSize;
00604     if( pnYSize != NULL )
00605         *pnYSize = nBlockYSize;
00606 }
00607 
00608 /************************************************************************/
00609 /*                          GDALGetBlockSize()                          */
00610 /************************************************************************/
00611 
00612 void GDALGetBlockSize( GDALRasterBandH hBand, int * pnXSize, int * pnYSize )
00613 
00614 {
00615     GDALRasterBand      *poBand = (GDALRasterBand *) hBand;
00616 
00617     poBand->GetBlockSize( pnXSize, pnYSize );
00618 }
00619 
00620 /************************************************************************/
00621 /*                           InitBlockInfo()                            */
00622 /************************************************************************/
00623 
00624 void GDALRasterBand::InitBlockInfo()
00625 
00626 {
00627     if( papoBlocks != NULL )
00628         return;
00629 
00630     CPLAssert( nBlockXSize > 0 && nBlockYSize > 0 );
00631     
00632     nBlocksPerRow = (nRasterXSize+nBlockXSize-1) / nBlockXSize;
00633     nBlocksPerColumn = (nRasterYSize+nBlockYSize-1) / nBlockYSize;
00634     
00635     papoBlocks = (GDALRasterBlock **)
00636         CPLCalloc( sizeof(void*), nBlocksPerRow * nBlocksPerColumn );
00637 }
00638 
00639 
00640 /************************************************************************/
00641 /*                             AdoptBlock()                             */
00642 /*                                                                      */
00643 /*      Add a block to the raster band's block matrix.  If this         */
00644 /*      exceeds our maximum blocks for this layer, flush the oldest     */
00645 /*      block out.                                                      */
00646 /*                                                                      */
00647 /*      This method is protected.                                       */
00648 /************************************************************************/
00649 
00650 CPLErr GDALRasterBand::AdoptBlock( int nBlockXOff, int nBlockYOff,
00651                                    GDALRasterBlock * poBlock )
00652 
00653 {
00654     int         nBlockIndex;
00655     
00656     InitBlockInfo();
00657     
00658     CPLAssert( nBlockXOff >= 0 && nBlockXOff < nBlocksPerRow );
00659     CPLAssert( nBlockYOff >= 0 && nBlockYOff < nBlocksPerColumn );
00660 
00661     nBlockIndex = nBlockXOff + nBlockYOff * nBlocksPerRow;
00662     if( papoBlocks[nBlockIndex] == poBlock )
00663         return( CE_None );
00664 
00665     if( papoBlocks[nBlockIndex] != NULL )
00666         FlushBlock( nBlockXOff, nBlockYOff );
00667 
00668     papoBlocks[nBlockIndex] = poBlock;
00669     poBlock->Touch();
00670 
00671     return( CE_None );
00672 }
00673 
00674 /************************************************************************/
00675 /*                             FlushCache()                             */
00676 /************************************************************************/
00677 
00689 CPLErr GDALRasterBand::FlushCache()
00690 
00691 {
00692     for( int iY = 0; iY < nBlocksPerColumn; iY++ )
00693     {
00694         for( int iX = 0; iX < nBlocksPerRow; iX++ )
00695         {
00696             if( papoBlocks[iX + iY*nBlocksPerRow] != NULL )
00697             {
00698                 CPLErr    eErr;
00699 
00700                 eErr = FlushBlock( iX, iY );
00701 
00702                 if( eErr != CE_None )
00703                     return eErr;
00704             }
00705         }
00706     }
00707 
00708     return( CE_None );
00709 }
00710 
00711 /************************************************************************/
00712 /*                        GDALFlushRasterCache()                        */
00713 /************************************************************************/
00714 
00715 CPLErr GDALFlushRasterCache( GDALRasterBandH hBand )
00716 
00717 {
00718     return ((GDALRasterBand *) hBand)->FlushCache();
00719 }
00720 
00721 /************************************************************************/
00722 /*                             FlushBlock()                             */
00723 /*                                                                      */
00724 /*      Flush a block out of the block cache.  If it has been           */
00725 /*      modified write it to disk.  If no specific tile is              */
00726 /*      indicated, write the oldest tile.                               */
00727 /*                                                                      */
00728 /*      Protected method.                                               */
00729 /************************************************************************/
00730 
00731 CPLErr GDALRasterBand::FlushBlock( int nBlockXOff, int nBlockYOff )
00732 
00733 {
00734     int         nBlockIndex;
00735     GDALRasterBlock *poBlock;
00736     CPLErr      eErr = CE_None;
00737         
00738     InitBlockInfo();
00739     
00740 /* -------------------------------------------------------------------- */
00741 /*      Validate                                                        */
00742 /* -------------------------------------------------------------------- */
00743     CPLAssert( nBlockXOff >= 0 && nBlockXOff < nBlocksPerRow );
00744     CPLAssert( nBlockYOff >= 0 && nBlockYOff < nBlocksPerColumn );
00745 
00746     nBlockIndex = nBlockXOff + nBlockYOff * nBlocksPerRow;
00747     poBlock = papoBlocks[nBlockIndex];
00748     if( poBlock == NULL )
00749         return( CE_None );
00750 
00751 /* -------------------------------------------------------------------- */
00752 /*      Remove, and update count.                                       */
00753 /* -------------------------------------------------------------------- */
00754     papoBlocks[nBlockIndex] = NULL;
00755 
00756 /* -------------------------------------------------------------------- */
00757 /*      Is the target block dirty?  If so we need to write it.          */
00758 /* -------------------------------------------------------------------- */
00759     if( poBlock->GetDirty() )
00760         poBlock->Write();
00761 
00762 /* -------------------------------------------------------------------- */
00763 /*      Deallocate the block;                                           */
00764 /* -------------------------------------------------------------------- */
00765     delete poBlock;
00766 
00767     return( eErr );
00768 }
00769 
00770 
00771 /************************************************************************/
00772 /*                            GetBlockRef()                             */
00773 /************************************************************************/
00774 
00790 GDALRasterBlock * GDALRasterBand::GetBlockRef( int nXBlockOff,
00791                                                int nYBlockOff )
00792 
00793 {
00794     int         nBlockIndex;
00795 
00796     InitBlockInfo();
00797     
00798 /* -------------------------------------------------------------------- */
00799 /*      Validate the request                                            */
00800 /* -------------------------------------------------------------------- */
00801     if( nXBlockOff < 0 || nXBlockOff >= nBlocksPerRow )
00802     {
00803         CPLError( CE_Failure, CPLE_IllegalArg,
00804                   "Illegal nBlockXOff value (%d) in "
00805                         "GDALRasterBand::GetBlockRef()\n",
00806                   nXBlockOff );
00807 
00808         return( NULL );
00809     }
00810 
00811     if( nYBlockOff < 0 || nYBlockOff >= nBlocksPerColumn )
00812     {
00813         CPLError( CE_Failure, CPLE_IllegalArg,
00814                   "Illegal nBlockYOff value (%d) in "
00815                         "GDALRasterBand::GetBlockRef()\n",
00816                   nYBlockOff );
00817 
00818         return( NULL );
00819     }
00820 
00821 /* -------------------------------------------------------------------- */
00822 /*      If the block isn't already in the cache, we will need to        */
00823 /*      create it, read into it, and adopt it.  Adopting it may         */
00824 /*      flush an old tile from the cache.                               */
00825 /* -------------------------------------------------------------------- */
00826     nBlockIndex = nXBlockOff + nYBlockOff * nBlocksPerRow;
00827     
00828     if( papoBlocks[nBlockIndex] == NULL )
00829     {
00830         GDALRasterBlock *poBlock;
00831         
00832         poBlock = new GDALRasterBlock( this, nXBlockOff, nYBlockOff );
00833 
00834         /* allocate data space */
00835         if( poBlock->Internalize() != CE_None )
00836         {
00837             delete poBlock;
00838 
00839             return( NULL );
00840         }
00841 
00842         if( IReadBlock(nXBlockOff,nYBlockOff,poBlock->GetDataRef()) != CE_None)
00843         {
00844             delete poBlock;
00845             return( NULL );
00846         }
00847 
00848         AdoptBlock( nXBlockOff, nYBlockOff, poBlock );
00849     }
00850 
00851 /* -------------------------------------------------------------------- */
00852 /*      Every read access updates the last touched time.                */
00853 /* -------------------------------------------------------------------- */
00854     if( papoBlocks[nBlockIndex] != NULL )
00855         papoBlocks[nBlockIndex]->Touch();
00856 
00857     return( papoBlocks[nBlockIndex] );
00858 }
00859 
00860 /************************************************************************/
00861 /*                             GetAccess()                              */
00862 /************************************************************************/
00863 
00870 GDALAccess GDALRasterBand::GetAccess()
00871 
00872 {
00873     return eAccess;
00874 }
00875 
00876 /************************************************************************/
00877 /*                          GetCategoryNames()                          */
00878 /************************************************************************/
00879 
00895 char **GDALRasterBand::GetCategoryNames()
00896 
00897 {
00898     return NULL;
00899 }
00900 
00901 /************************************************************************/
00902 /*                     GDALGetRasterCategoryNames()                     */
00903 /************************************************************************/
00904 
00905 char **GDALGetRasterCategoryNames( GDALRasterBandH hBand )
00906 
00907 {
00908     return ((GDALRasterBand *) hBand)->GetCategoryNames();
00909 }
00910 
00911 /************************************************************************/
00912 /*                          SetCategoryNames()                          */
00913 /************************************************************************/
00914 
00930 CPLErr GDALRasterBand::SetCategoryNames( char ** )
00931 
00932 {
00933     return CE_Failure;
00934 }
00935 
00936 /************************************************************************/
00937 /*                        GDALSetCategoryNames()                        */
00938 /************************************************************************/
00939 
00940 CPLErr GDALSetRasterCategoryNames( GDALRasterBandH hBand, char ** papszNames )
00941 
00942 {
00943     return ((GDALRasterBand *) hBand)->SetCategoryNames( papszNames );
00944 }
00945 
00946 /************************************************************************/
00947 /*                           GetNoDataValue()                           */
00948 /************************************************************************/
00949 
00966 double GDALRasterBand::GetNoDataValue( int *pbSuccess )
00967 
00968 {
00969     if( pbSuccess != NULL )
00970         *pbSuccess = FALSE;
00971     
00972     return -1e10;
00973 }
00974 
00975 /************************************************************************/
00976 /*                      GDALGetRasterNoDataValue()                      */
00977 /************************************************************************/
00978 
00979 double GDALGetRasterNoDataValue( GDALRasterBandH hBand, int *pbSuccess )
00980 
00981 {
00982     return ((GDALRasterBand *) hBand)->GetNoDataValue( pbSuccess );
00983 }
00984 
00985 /************************************************************************/
00986 /*                           SetNoDataValue()                           */
00987 /************************************************************************/
00988 
01004 CPLErr GDALRasterBand::SetNoDataValue( double )
01005 
01006 {
01007     return CE_Failure;
01008 }
01009 
01010 /************************************************************************/
01011 /*                         GDALSetRasterNoDataValue()                   */
01012 /************************************************************************/
01013 
01014 CPLErr GDALSetRasterNoDataValue( GDALRasterBandH hBand, double dfValue )
01015 
01016 {
01017     return ((GDALRasterBand *) hBand)->SetNoDataValue( dfValue );
01018 }
01019 
01020 /************************************************************************/
01021 /*                             GetMaximum()                             */
01022 /************************************************************************/
01023 
01038 double GDALRasterBand::GetMaximum( int *pbSuccess )
01039 
01040 {
01041     if( pbSuccess != NULL )
01042         *pbSuccess = FALSE;
01043 
01044     switch( eDataType )
01045     {
01046       case GDT_Byte:
01047         return 255;
01048 
01049       case GDT_UInt16:
01050         return 65535;
01051 
01052       case GDT_Int16:
01053       case GDT_CInt16:
01054         return 32767;
01055 
01056       case GDT_Int32:
01057       case GDT_CInt32:
01058         return 2147483647.0;
01059 
01060       case GDT_UInt32:
01061         return 4294967295.0;
01062 
01063       case GDT_Float32:
01064       case GDT_CFloat32:
01065         return 4294967295.0; /* not actually accurate */
01066 
01067       case GDT_Float64:
01068       case GDT_CFloat64:
01069         return 4294967295.0; /* not actually accurate */
01070 
01071       default:
01072         return 4294967295.0; /* not actually accurate */
01073     }
01074 }
01075 
01076 /************************************************************************/
01077 /*                        GDALGetRasterMaximum()                        */
01078 /************************************************************************/
01079 
01080 double GDALGetRasterMaximum( GDALRasterBandH hBand, int *pbSuccess )
01081 
01082 {
01083     return ((GDALRasterBand *) hBand)->GetMaximum( pbSuccess );
01084 }
01085 
01086 /************************************************************************/
01087 /*                             GetMinimum()                             */
01088 /************************************************************************/
01089 
01104 double GDALRasterBand::GetMinimum( int *pbSuccess )
01105 
01106 {
01107     if( pbSuccess != NULL )
01108         *pbSuccess = FALSE;
01109 
01110     switch( eDataType )
01111     {
01112       case GDT_Byte:
01113         return 0;
01114 
01115       case GDT_UInt16:
01116         return 0;
01117 
01118       case GDT_Int16:
01119         return -32768;
01120 
01121       case GDT_Int32:
01122         return -2147483648.0;
01123 
01124       case GDT_UInt32:
01125         return 0;
01126 
01127       case GDT_Float32:
01128         return -4294967295.0; /* not actually accurate */
01129 
01130       case GDT_Float64:
01131         return -4294967295.0; /* not actually accurate */
01132 
01133       default:
01134         return -4294967295.0; /* not actually accurate */
01135     }
01136 }
01137 
01138 /************************************************************************/
01139 /*                        GDALGetRasterMinimum()                        */
01140 /************************************************************************/
01141 
01142 double GDALGetRasterMinimum( GDALRasterBandH hBand, int *pbSuccess )
01143 
01144 {
01145     return ((GDALRasterBand *) hBand)->GetMinimum( pbSuccess );
01146 }
01147 
01148 /************************************************************************/
01149 /*                       GetColorInterpretation()                       */
01150 /************************************************************************/
01151 
01164 GDALColorInterp GDALRasterBand::GetColorInterpretation()
01165 
01166 {
01167     return GCI_Undefined;
01168 }
01169 
01170 /************************************************************************/
01171 /*                  GDALGetRasterColorInterpretation()                  */
01172 /************************************************************************/
01173 
01174 GDALColorInterp GDALGetRasterColorInterpretation( GDALRasterBandH hBand )
01175 
01176 {
01177     return ((GDALRasterBand *) hBand)->GetColorInterpretation();
01178 }
01179 
01180 /************************************************************************/
01181 /*                           GetColorTable()                            */
01182 /************************************************************************/
01183 
01196 GDALColorTable *GDALRasterBand::GetColorTable()
01197 
01198 {
01199     return NULL;
01200 }
01201 
01202 /************************************************************************/
01203 /*                      GDALGetRasterColorTable()                       */
01204 /************************************************************************/
01205 
01206 GDALColorTableH GDALGetRasterColorTable( GDALRasterBandH hBand )
01207 
01208 {
01209     return (GDALColorTableH) ((GDALRasterBand *) hBand)->GetColorTable();
01210 }
01211 
01212 /************************************************************************/
01213 /*                           SetColorTable()                            */
01214 /************************************************************************/
01215 
01231 CPLErr GDALRasterBand::SetColorTable( GDALColorTable * poCT )
01232 
01233 {
01234     return CE_Failure;
01235 }
01236 
01237 /************************************************************************/
01238 /*                      GDALSetRasterColorTable()                       */
01239 /************************************************************************/
01240 
01241 CPLErr GDALSetRasterColorTable( GDALRasterBandH hBand, GDALColorTableH hCT )
01242 
01243 {
01244     return ((GDALRasterBand *) hBand)->SetColorTable( (GDALColorTable *) hCT );
01245 }
01246 
01247 /************************************************************************/
01248 /*                       HasArbitraryOverviews()                        */
01249 /************************************************************************/
01250 
01266 int GDALRasterBand::HasArbitraryOverviews()
01267 
01268 {
01269     return FALSE;
01270 }
01271 
01272 /************************************************************************/
01273 /*                     GDALHasArbitraryOverviews()                      */
01274 /************************************************************************/
01275 
01276 int GDALHasArbitraryOverviews( GDALRasterBandH hBand )
01277 
01278 {
01279     return ((GDALRasterBand *) hBand)->HasArbitraryOverviews();
01280 }
01281 
01282 /************************************************************************/
01283 /*                          GetOverviewCount()                          */
01284 /************************************************************************/
01285 
01294 int GDALRasterBand::GetOverviewCount()
01295 
01296 {
01297     if( poDS != NULL && poDS->oOvManager.IsInitialized() )
01298         return poDS->oOvManager.GetOverviewCount( nBand );
01299     else
01300         return 0;
01301 }
01302 
01303 /************************************************************************/
01304 /*                        GDALGetOverviewCount()                        */
01305 /************************************************************************/
01306 
01307 int GDALGetOverviewCount( GDALRasterBandH hBand )
01308 
01309 {
01310     return ((GDALRasterBand *) hBand)->GetOverviewCount();
01311 }
01312 
01313 
01314 /************************************************************************/
01315 /*                            GetOverview()                             */
01316 /************************************************************************/
01317 
01328 GDALRasterBand * GDALRasterBand::GetOverview( int i )
01329 
01330 {
01331     if( poDS != NULL && poDS->oOvManager.IsInitialized() )
01332         return poDS->oOvManager.GetOverview( nBand, i );
01333     else
01334         return NULL;
01335 }
01336 
01337 /************************************************************************/
01338 /*                          GDALGetOverview()                           */
01339 /************************************************************************/
01340 
01341 GDALRasterBandH GDALGetOverview( GDALRasterBandH hBand, int i )
01342 
01343 {
01344     return (GDALRasterBandH) ((GDALRasterBand *) hBand)->GetOverview(i);
01345 }
01346 
01347 /************************************************************************/
01348 /*                           BuildOverviews()                           */
01349 /************************************************************************/
01350 
01367 CPLErr GDALRasterBand::BuildOverviews( const char *pszResampling, 
01368                                        int nOverviews, int *panOverviewList, 
01369                                        GDALProgressFunc pfnProgress, 
01370                                        void * pProgressData )
01371 
01372 {
01373     CPLError( CE_Failure, CPLE_NotSupported,
01374               "BuildOverviews() not supported for this dataset." );
01375     
01376     return( CE_Failure );
01377 }
01378 
01379 /************************************************************************/
01380 /*                             GetOffset()                              */
01381 /************************************************************************/
01382 
01402 double GDALRasterBand::GetOffset( int *pbSuccess )
01403 
01404 {
01405     if( pbSuccess != NULL )
01406         *pbSuccess = FALSE;
01407 
01408     return 0.0;
01409 }
01410 
01411 /************************************************************************/
01412 /*                              GetScale()                              */
01413 /************************************************************************/
01414 
01434 double GDALRasterBand::GetScale( int *pbSuccess )
01435 
01436 {
01437     if( pbSuccess != NULL )
01438         *pbSuccess = FALSE;
01439 
01440     return 1.0;
01441 }
01442 
01443 /************************************************************************/
01444 /*                           GetDescription()                           */
01445 /************************************************************************/
01446 
01453 const char *GDALRasterBand::GetDescription()
01454 
01455 {
01456     return "";
01457 }
01458 
01459 
01460 /************************************************************************/
01461 /*                            GetUnitType()                             */
01462 /************************************************************************/
01463 
01477 const char *GDALRasterBand::GetUnitType()
01478 
01479 {
01480     return "";
01481 }
01482 
01483 /************************************************************************/
01484 /*                       GDALGetRasterUnitType()                        */
01485 /************************************************************************/
01486 
01487 const char *GDALGetRasterUnitType( GDALRasterBandH hBand )
01488 
01489 {
01490     return ((GDALRasterBand *) hBand)->GetUnitType();
01491 }
01492 
01493 /************************************************************************/
01494 /*                              GetXSize()                              */
01495 /************************************************************************/
01496 
01505 int GDALRasterBand::GetXSize()
01506 
01507 {
01508     return nRasterXSize;
01509 }
01510 
01511 /************************************************************************/
01512 /*                       GDALGetRasterBandXSize()                       */
01513 /************************************************************************/
01514 
01515 int GDALGetRasterBandXSize( GDALRasterBandH hBand )
01516 
01517 {
01518     return ((GDALRasterBand *) hBand)->GetXSize();
01519 }
01520 
01521 /************************************************************************/
01522 /*                              GetYSize()                              */
01523 /************************************************************************/
01524 
01533 int GDALRasterBand::GetYSize()
01534 
01535 {
01536     return nRasterYSize;
01537 }
01538 
01539 /************************************************************************/
01540 /*                       GDALGetRasterBandYSize()                       */
01541 /************************************************************************/
01542 
01543 int GDALGetRasterBandYSize( GDALRasterBandH hBand )
01544 
01545 {
01546     return ((GDALRasterBand *) hBand)->GetYSize();
01547 }
01548 
01549 /************************************************************************/
01550 /*                              GetBand()                               */
01551 /************************************************************************/
01552 
01553 int GDALRasterBand::GetBand()
01554 
01555 {
01556     return nBand;
01557 }
01558 
01559 /************************************************************************/
01560 /*                            GetHistogram()                            */
01561 /************************************************************************/
01562 
01599 CPLErr GDALRasterBand::GetHistogram( double dfMin, double dfMax, 
01600                                      int nBuckets, int *panHistogram, 
01601                                      int bIncludeOutOfRange, int bApproxOK,
01602                                      GDALProgressFunc pfnProgress, 
01603                                      void *pProgressData )
01604 
01605 {
01606     CPLAssert( pfnProgress != NULL );
01607 
01608 /* -------------------------------------------------------------------- */
01609 /*      If we have overviews, use them for the histogram.               */
01610 /* -------------------------------------------------------------------- */
01611     if( bApproxOK && GetOverviewCount() > 0 )
01612     {
01613         double dfBestPixels = GetXSize() * GetYSize();
01614         GDALRasterBand *poBestOverview = NULL;
01615         
01616         for( int i = 0; i < GetOverviewCount(); i++ )
01617         {
01618             GDALRasterBand *poOverview = GetOverview(i);
01619             double         dfPixels;
01620 
01621             dfPixels = poOverview->GetXSize() * poOverview->GetYSize();
01622             if( dfPixels < dfBestPixels )
01623             {
01624                 dfBestPixels = dfPixels;
01625                 poBestOverview = poOverview;
01626             }
01627             
01628             if( poBestOverview != NULL )
01629                 return poBestOverview->
01630                     GetHistogram( dfMin, dfMax, nBuckets, panHistogram, 
01631                                   bIncludeOutOfRange, bApproxOK, 
01632                                   pfnProgress, pProgressData );
01633         }
01634     }
01635 
01636 /* -------------------------------------------------------------------- */
01637 /*      Figure out the ratio of blocks we will read to get an           */
01638 /*      approximate value.                                              */
01639 /* -------------------------------------------------------------------- */
01640     int         nSampleRate;
01641     double      dfScale;
01642 
01643     InitBlockInfo();
01644     
01645     if( bApproxOK )
01646         nSampleRate = 
01647             (int) MAX(1,sqrt((double) nBlocksPerRow * nBlocksPerColumn));
01648     else
01649         nSampleRate = 1;
01650     
01651     dfScale = nBuckets / (dfMax - dfMin);
01652 
01653 /* -------------------------------------------------------------------- */
01654 /*      Read the blocks, and add to histogram.                          */
01655 /* -------------------------------------------------------------------- */
01656     memset( panHistogram, 0, sizeof(int) * nBuckets );
01657     for( int iSampleBlock = 0; 
01658          iSampleBlock < nBlocksPerRow * nBlocksPerColumn;
01659          iSampleBlock += nSampleRate )
01660     {
01661         double dfValue = 0.0, dfReal, dfImag;
01662         int  iXBlock, iYBlock, nXCheck, nYCheck;
01663         GDALRasterBlock *poBlock;
01664 
01665         if( !pfnProgress( iSampleBlock/(double)nBlocksPerRow*nBlocksPerColumn,
01666                           NULL, pProgressData ) )
01667             return CE_Failure;
01668 
01669         iYBlock = iSampleBlock / nBlocksPerRow;
01670         iXBlock = iSampleBlock - nBlocksPerRow * iYBlock;
01671         
01672         poBlock = GetBlockRef( iXBlock, iYBlock );
01673         if( poBlock == NULL )
01674             return CE_Failure;
01675         
01676         if( (iXBlock+1) * nBlockXSize > GetXSize() )
01677             nXCheck = GetXSize() - iXBlock * nBlockXSize;
01678         else
01679             nXCheck = nBlockXSize;
01680 
01681         if( (iYBlock+1) * nBlockYSize > GetYSize() )
01682             nYCheck = GetYSize() - iYBlock * nBlockYSize;
01683         else
01684             nYCheck = nBlockYSize;
01685 
01686         /* this is a special case for a common situation */
01687         if( poBlock->GetDataType() == GDT_Byte
01688             && dfScale == 1.0 && (dfMin >= -0.5 && dfMin <= 0.5)
01689             && nYCheck == nBlockYSize && nXCheck == nBlockXSize
01690             && nBuckets == 256 )
01691         {
01692             int    nPixels = nXCheck * nYCheck;
01693             GByte  *pabyData = (GByte *) poBlock->GetDataRef();
01694             
01695             for( int i = 0; i < nPixels; i++ )
01696                 panHistogram[pabyData[i]]++;
01697             
01698             continue; /* to next sample block */
01699         }
01700 
01701         /* this isn't the fastest way to do this, but is easier for now */
01702         for( int iY = 0; iY < nYCheck; iY++ )
01703         {
01704             for( int iX = 0; iX < nXCheck; iX++ )
01705             {
01706                 int    iOffset = iX + iY * nBlockXSize;
01707                 int    nIndex;
01708 
01709                 switch( poBlock->GetDataType() )
01710                 {
01711                   case GDT_Byte:
01712                     dfValue = ((GByte *) poBlock->GetDataRef())[iOffset];
01713                     break;
01714 
01715                   case GDT_UInt16:
01716                     dfValue = ((GUInt16 *) poBlock->GetDataRef())[iOffset];
01717                     break;
01718                   case GDT_Int16:
01719                     dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset];
01720                     break;
01721                   case GDT_UInt32:
01722                     dfValue = ((GUInt32 *) poBlock->GetDataRef())[iOffset];
01723                     break;
01724                   case GDT_Int32:
01725                     dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset];
01726                     break;
01727                   case GDT_Float32:
01728                     dfValue = ((float *) poBlock->GetDataRef())[iOffset];
01729                     break;
01730                   case GDT_Float64:
01731                     dfValue = ((double *) poBlock->GetDataRef())[iOffset];
01732                     break;
01733                   case GDT_CInt16:
01734                     dfReal = ((GInt16 *) poBlock->GetDataRef())[iOffset*2];
01735                     dfImag = ((GInt16 *) poBlock->GetDataRef())[iOffset*2+1];
01736                     dfValue = sqrt( dfReal * dfReal + dfImag * dfImag );
01737                     break;
01738                   case GDT_CInt32:
01739                     dfReal = ((GInt32 *) poBlock->GetDataRef())[iOffset*2];
01740                     dfImag = ((GInt32 *) poBlock->GetDataRef())[iOffset*2+1];
01741                     dfValue = sqrt( dfReal * dfReal + dfImag * dfImag );
01742                     break;
01743                   case GDT_CFloat32:
01744                     dfReal = ((float *) poBlock->GetDataRef())[iOffset*2];
01745                     dfImag = ((float *) poBlock->GetDataRef())[iOffset*2+1];
01746                     dfValue = sqrt( dfReal * dfReal + dfImag * dfImag );
01747                     break;
01748                   case GDT_CFloat64:
01749                     dfReal = ((double *) poBlock->GetDataRef())[iOffset*2];
01750                     dfImag = ((double *) poBlock->GetDataRef())[iOffset*2+1];
01751                     dfValue = sqrt( dfReal * dfReal + dfImag * dfImag );
01752                     break;
01753                   default:
01754                     CPLAssert( FALSE );
01755                     return CE_Failure;
01756                 }
01757                 
01758                 nIndex = (int) floor((dfValue - dfMin) * dfScale);
01759 
01760                 if( nIndex < 0 )
01761                 {
01762                     if( bIncludeOutOfRange )
01763                         panHistogram[0]++;
01764                 }
01765                 else if( nIndex >= nBuckets )
01766                 {
01767                     if( bIncludeOutOfRange )
01768                         panHistogram[nBuckets-1]++;
01769                 }
01770                 else
01771                 {
01772                     panHistogram[nIndex]++;
01773                 }
01774             }
01775         }
01776     }
01777 
01778     pfnProgress( 1.0, NULL, pProgressData );
01779 
01780     return CE_None;
01781 }
01782 
01783 /************************************************************************/
01784 /*                       GDALGetRasterHistogram()                       */
01785 /************************************************************************/
01786 
01787 CPLErr GDALGetRasterHistogram( GDALRasterBandH hBand, 
01788                                double dfMin, double dfMax, 
01789                                int nBuckets, int *panHistogram, 
01790                                int bIncludeOutOfRange, int bApproxOK,
01791                                GDALProgressFunc pfnProgress, 
01792                                void *pProgressData )
01793 
01794 {
01795     return ((GDALRasterBand *) hBand)->
01796         GetHistogram( dfMin, dfMax, nBuckets, panHistogram, 
01797                       bIncludeOutOfRange, bApproxOK,
01798                       pfnProgress, pProgressData );
01799 }

Generated at Thu Mar 28 09:47:30 2002 for GDAL by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000