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

doxygen1.2.2 Dimitri van Heesch, © 1997-2000