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

doxygen1.2.3-20001105 Dimitri van Heesch, © 1997-2000