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 }