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

Generated at Sat Dec 21 14:01:59 2002 for GDAL by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000