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