00001 /****************************************************************************** 00002 * $Id: gdalrasterband_cpp-source.html,v 1.10 2002/04/16 13:11:48 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.10 2002/04/16 13:11:48 warmerda 00030 * updated 00030 * 00031 * Revision 1.27 2002/03/01 14:29:09 warmerda 00032 * added GetBand() method on GDALRasterBand 00033 * 00034 * Revision 1.26 2001/12/07 15:29:45 warmerda 00035 * added InitBlockInfo() in GetHistogram() 00036 * 00037 * Revision 1.25 2001/10/18 14:35:22 warmerda 00038 * avoid conflicts between parameters and member data 00039 * 00040 * Revision 1.24 2001/10/17 16:20:45 warmerda 00041 * make histograming work with complex data (r(treat as magnitude) 00042 * 00043 * Revision 1.23 2001/07/18 04:04:30 warmerda 00044 * added CPL_CVSID 00045 * 00046 * Revision 1.22 2001/07/05 13:13:40 warmerda 00047 * added UnitType from C support 00048 * 00049 * Revision 1.21 2000/10/06 15:25:48 warmerda 00050 * added setnodata, and some other methods 00051 * 00052 * Revision 1.20 2000/08/25 14:26:51 warmerda 00053 * added GDALHasArbitraryOverviews 00054 * 00055 * Revision 1.19 2000/08/16 15:50:52 warmerda 00056 * fixed some bugs with floating (datasetless) bands 00057 * 00058 * Revision 1.18 2000/07/12 00:19:29 warmerda 00059 * Removed extra line feed. 00060 * 00061 * Revision 1.17 2000/06/05 17:24:05 warmerda 00062 * added real complex support 00063 * 00064 * Revision 1.16 2000/04/21 21:56:59 warmerda 00065 * moved metadata to GDALMajorObject 00066 * 00067 * Revision 1.15 2000/03/31 13:42:27 warmerda 00068 * added metadata support 00069 * 00070 * Revision 1.14 2000/03/24 00:09:05 warmerda 00071 * rewrote cache management 00072 * 00073 * Revision 1.13 2000/03/10 13:54:37 warmerda 00074 * fixed use of overviews in gethistogram 00075 * 00076 * Revision 1.12 2000/03/09 23:22:03 warmerda 00077 * added GetHistogram 00078 * 00079 * Revision 1.11 2000/03/08 19:59:16 warmerda 00080 * added GDALFlushRasterCache 00081 * 00082 * Revision 1.10 2000/03/06 21:50:37 warmerda 00083 * added min/max support 00084 * 00085 * Revision 1.9 2000/03/06 02:22:01 warmerda 00086 * added overviews, colour tables, and many other methods 00087 * 00088 * Revision 1.8 2000/02/28 16:34:28 warmerda 00089 * added arg window check in RasterIO() 00090 * 00091 * Revision 1.7 1999/11/17 16:18:10 warmerda 00092 * fixed example code 00093 * 00094 * Revision 1.6 1999/10/21 13:24:37 warmerda 00095 * Fixed some build breaking variable name differences. 00096 * 00097 * Revision 1.5 1999/10/01 14:44:02 warmerda 00098 * added documentation 00099 * 00100 * Revision 1.4 1998/12/31 18:54:25 warmerda 00101 * Implement initial GDALRasterBlock support, and block cache 00102 * 00103 * Revision 1.3 1998/12/06 22:17:09 warmerda 00104 * Fill out rasterio support. 00105 * 00106 * Revision 1.2 1998/12/06 02:52:08 warmerda 00107 * Added new methods, and C cover functions. 00108 * 00109 * Revision 1.1 1998/12/03 18:32:01 warmerda 00110 * New 00111 */ 00112 00113 #include "gdal_priv.h" 00114 #include "cpl_string.h" 00115 00116 CPL_CVSID("$Id: gdalrasterband_cpp-source.html,v 1.10 2002/04/16 13:11:48 warmerda Exp $"); 00117 00118 /************************************************************************/ 00119 /* GDALRasterBand() */ 00120 /************************************************************************/ 00121 00124 GDALRasterBand::GDALRasterBand() 00125 00126 { 00127 poDS = NULL; 00128 nBand = 0; 00129 00130 eAccess = GA_ReadOnly; 00131 nBlockXSize = nBlockYSize = -1; 00132 eDataType = GDT_Byte; 00133 00134 nBlocksPerRow = 0; 00135 nBlocksPerColumn = 0; 00136 00137 papoBlocks = NULL; 00138 } 00139 00140 /************************************************************************/ 00141 /* ~GDALRasterBand() */ 00142 /************************************************************************/ 00143 00147 GDALRasterBand::~GDALRasterBand() 00148 00149 { 00150 FlushCache(); 00151 00152 CPLFree( papoBlocks ); 00153 } 00154 00155 /************************************************************************/ 00156 /* RasterIO() */ 00157 /************************************************************************/ 00158 00224 CPLErr GDALRasterBand::RasterIO( GDALRWFlag eRWFlag, 00225 int nXOff, int nYOff, int nXSize, int nYSize, 00226 void * pData, int nBufXSize, int nBufYSize, 00227 GDALDataType eBufType, 00228 int nPixelSpace, 00229 int nLineSpace ) 00230 00231 { 00232 /* -------------------------------------------------------------------- */ 00233 /* If pixel and line spaceing are defaulted assign reasonable */ 00234 /* value assuming a packed buffer. */ 00235 /* -------------------------------------------------------------------- */ 00236 if( nPixelSpace == 0 ) 00237 nPixelSpace = GDALGetDataTypeSize( eBufType ) / 8; 00238 00239 if( nLineSpace == 0 ) 00240 nLineSpace = nPixelSpace * nBufXSize; 00241 00242 /* -------------------------------------------------------------------- */ 00243 /* Do some validation of parameters. */ 00244 /* -------------------------------------------------------------------- */ 00245 if( nXOff < 0 || nXOff + nXSize > nRasterXSize 00246 || nYOff < 0 || nYOff + nYSize > nRasterYSize ) 00247 { 00248 CPLError( CE_Failure, CPLE_IllegalArg, 00249 "Access window out of range in RasterIO(). Requested\n" 00250 "(%d,%d) of size %dx%d on raster of %dx%d.", 00251 nXOff, nYOff, nXSize, nYSize, nRasterXSize, nRasterYSize ); 00252 return CE_Failure; 00253 } 00254 00255 /* -------------------------------------------------------------------- */ 00256 /* Some size values are "noop". Lets just return to avoid */ 00257 /* stressing lower level functions. */ 00258 /* -------------------------------------------------------------------- */ 00259 if( nXSize < 1 || nYSize < 1 || nBufXSize < 1 || nBufYSize < 1 ) 00260 { 00261 CPLDebug( "GDAL", 00262 "RasterIO() skipped for odd window or buffer size.\n" 00263 " Window = (%d,%d)x%dx%d\n" 00264 " Buffer = %dx%d\n", 00265 nXOff, nYOff, nXSize, nYSize, 00266 nBufXSize, nBufYSize ); 00267 00268 return CE_None; 00269 } 00270 00271 /* -------------------------------------------------------------------- */ 00272 /* Call the format specific function. */ 00273 /* -------------------------------------------------------------------- */ 00274 return( IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, 00275 pData, nBufXSize, nBufYSize, eBufType, 00276 nPixelSpace, nLineSpace ) ); 00277 } 00278 00279 /************************************************************************/ 00280 /* GDALRasterIO() */ 00281 /************************************************************************/ 00282 00283 CPLErr GDALRasterIO( GDALRasterBandH hBand, GDALRWFlag eRWFlag, 00284 int nXOff, int nYOff, 00285 int nXSize, int nYSize, 00286 void * pData, 00287 int nBufXSize, int nBufYSize, 00288 GDALDataType eBufType, 00289 int nPixelSpace, 00290 int nLineSpace ) 00291 00292 { 00293 GDALRasterBand *poBand = (GDALRasterBand *) hBand; 00294 00295 return( poBand->RasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, 00296 pData, nBufXSize, nBufYSize, eBufType, 00297 nPixelSpace, nLineSpace ) ); 00298 } 00299 00300 /************************************************************************/ 00301 /* ReadBlock() */ 00302 /************************************************************************/ 00303 00386 CPLErr GDALRasterBand::ReadBlock( int nXBlockOff, int nYBlockOff, 00387 void * pImage ) 00388 00389 { 00390 /* -------------------------------------------------------------------- */ 00391 /* Validate arguments. */ 00392 /* -------------------------------------------------------------------- */ 00393 CPLAssert( pImage != NULL ); 00394 00395 if( nXBlockOff < 0 00396 || nXBlockOff*nBlockXSize >= nRasterXSize ) 00397 { 00398 CPLError( CE_Failure, CPLE_IllegalArg, 00399 "Illegal nXBlockOff value (%d) in " 00400 "GDALRasterBand::ReadBlock()\n", 00401 nXBlockOff ); 00402 00403 return( CE_Failure ); 00404 } 00405 00406 if( nYBlockOff < 0 00407 || nYBlockOff*nBlockYSize >= nRasterYSize ) 00408 { 00409 CPLError( CE_Failure, CPLE_IllegalArg, 00410 "Illegal nYBlockOff value (%d) in " 00411 "GDALRasterBand::ReadBlock()\n", 00412 nYBlockOff ); 00413 00414 return( CE_Failure ); 00415 } 00416 00417 /* -------------------------------------------------------------------- */ 00418 /* Invoke underlying implementation method. */ 00419 /* -------------------------------------------------------------------- */ 00420 return( IReadBlock( nXBlockOff, nYBlockOff, pImage ) ); 00421 } 00422 00423 /************************************************************************/ 00424 /* GDALReadBlock() */ 00425 /************************************************************************/ 00426 00427 CPLErr GDALReadBlock( GDALRasterBandH hBand, int nXOff, int nYOff, 00428 void * pData ) 00429 00430 { 00431 GDALRasterBand *poBand = (GDALRasterBand *) hBand; 00432 00433 return( poBand->ReadBlock( nXOff, nYOff, pData ) ); 00434 } 00435 00436 /************************************************************************/ 00437 /* IWriteBlock() */ 00438 /* */ 00439 /* Default internal implementation ... to be overriden by */ 00440 /* subclasses that support writing. */ 00441 /************************************************************************/ 00442 00443 CPLErr GDALRasterBand::IWriteBlock( int, int, void * ) 00444 00445 { 00446 CPLError( CE_Failure, CPLE_NotSupported, 00447 "WriteBlock() not supported for this dataset." ); 00448 00449 return( CE_Failure ); 00450 } 00451 00452 /************************************************************************/ 00453 /* WriteBlock() */ 00454 /************************************************************************/ 00455 00486 CPLErr GDALRasterBand::WriteBlock( int nXBlockOff, int nYBlockOff, 00487 void * pImage ) 00488 00489 { 00490 /* -------------------------------------------------------------------- */ 00491 /* Validate arguments. */ 00492 /* -------------------------------------------------------------------- */ 00493 CPLAssert( pImage != NULL ); 00494 00495 if( nXBlockOff < 0 00496 || nXBlockOff*nBlockXSize >= GetXSize() ) 00497 { 00498 CPLError( CE_Failure, CPLE_IllegalArg, 00499 "Illegal nXBlockOff value (%d) in " 00500 "GDALRasterBand::WriteBlock()\n", 00501 nXBlockOff ); 00502 00503 return( CE_Failure ); 00504 } 00505 00506 if( nYBlockOff < 0 00507 || nYBlockOff*nBlockYSize >= GetYSize() ) 00508 { 00509 CPLError( CE_Failure, CPLE_IllegalArg, 00510 "Illegal nYBlockOff value (%d) in " 00511 "GDALRasterBand::WriteBlock()\n", 00512 nYBlockOff ); 00513 00514 return( CE_Failure ); 00515 } 00516 00517 if( eAccess == GA_ReadOnly ) 00518 { 00519 CPLError( CE_Failure, CPLE_NoWriteAccess, 00520 "Attempt to write to read only dataset in" 00521 "GDALRasterBand::WriteBlock().\n" ); 00522 00523 return( CE_Failure ); 00524 } 00525 00526 /* -------------------------------------------------------------------- */ 00527 /* Invoke underlying implementation method. */ 00528 /* -------------------------------------------------------------------- */ 00529 return( IWriteBlock( nXBlockOff, nYBlockOff, pImage ) ); 00530 } 00531 00532 /************************************************************************/ 00533 /* GDALWriteBlock() */ 00534 /************************************************************************/ 00535 00536 CPLErr GDALWriteBlock( GDALRasterBandH hBand, int nXOff, int nYOff, 00537 void * pData ) 00538 00539 { 00540 GDALRasterBand *poBand = (GDALRasterBand *) hBand; 00541 00542 return( poBand->WriteBlock( nXOff, nYOff, pData ) ); 00543 } 00544 00545 00546 /************************************************************************/ 00547 /* GetRasterDataType() */ 00548 /************************************************************************/ 00549 00557 GDALDataType GDALRasterBand::GetRasterDataType() 00558 00559 { 00560 return eDataType; 00561 } 00562 00563 /************************************************************************/ 00564 /* GDALGetRasterDataType() */ 00565 /************************************************************************/ 00566 00567 GDALDataType GDALGetRasterDataType( GDALRasterBandH hBand ) 00568 00569 { 00570 return( ((GDALRasterBand *) hBand)->GetRasterDataType() ); 00571 } 00572 00573 /************************************************************************/ 00574 /* GetBlockSize() */ 00575 /************************************************************************/ 00576 00597 void GDALRasterBand::GetBlockSize( int * pnXSize, int *pnYSize ) 00598 00599 { 00600 CPLAssert( nBlockXSize > 0 && nBlockYSize > 0 ); 00601 00602 if( pnXSize != NULL ) 00603 *pnXSize = nBlockXSize; 00604 if( pnYSize != NULL ) 00605 *pnYSize = nBlockYSize; 00606 } 00607 00608 /************************************************************************/ 00609 /* GDALGetBlockSize() */ 00610 /************************************************************************/ 00611 00612 void GDALGetBlockSize( GDALRasterBandH hBand, int * pnXSize, int * pnYSize ) 00613 00614 { 00615 GDALRasterBand *poBand = (GDALRasterBand *) hBand; 00616 00617 poBand->GetBlockSize( pnXSize, pnYSize ); 00618 } 00619 00620 /************************************************************************/ 00621 /* InitBlockInfo() */ 00622 /************************************************************************/ 00623 00624 void GDALRasterBand::InitBlockInfo() 00625 00626 { 00627 if( papoBlocks != NULL ) 00628 return; 00629 00630 CPLAssert( nBlockXSize > 0 && nBlockYSize > 0 ); 00631 00632 nBlocksPerRow = (nRasterXSize+nBlockXSize-1) / nBlockXSize; 00633 nBlocksPerColumn = (nRasterYSize+nBlockYSize-1) / nBlockYSize; 00634 00635 papoBlocks = (GDALRasterBlock **) 00636 CPLCalloc( sizeof(void*), nBlocksPerRow * nBlocksPerColumn ); 00637 } 00638 00639 00640 /************************************************************************/ 00641 /* AdoptBlock() */ 00642 /* */ 00643 /* Add a block to the raster band's block matrix. If this */ 00644 /* exceeds our maximum blocks for this layer, flush the oldest */ 00645 /* block out. */ 00646 /* */ 00647 /* This method is protected. */ 00648 /************************************************************************/ 00649 00650 CPLErr GDALRasterBand::AdoptBlock( int nBlockXOff, int nBlockYOff, 00651 GDALRasterBlock * poBlock ) 00652 00653 { 00654 int nBlockIndex; 00655 00656 InitBlockInfo(); 00657 00658 CPLAssert( nBlockXOff >= 0 && nBlockXOff < nBlocksPerRow ); 00659 CPLAssert( nBlockYOff >= 0 && nBlockYOff < nBlocksPerColumn ); 00660 00661 nBlockIndex = nBlockXOff + nBlockYOff * nBlocksPerRow; 00662 if( papoBlocks[nBlockIndex] == poBlock ) 00663 return( CE_None ); 00664 00665 if( papoBlocks[nBlockIndex] != NULL ) 00666 FlushBlock( nBlockXOff, nBlockYOff ); 00667 00668 papoBlocks[nBlockIndex] = poBlock; 00669 poBlock->Touch(); 00670 00671 return( CE_None ); 00672 } 00673 00674 /************************************************************************/ 00675 /* FlushCache() */ 00676 /************************************************************************/ 00677 00689 CPLErr GDALRasterBand::FlushCache() 00690 00691 { 00692 for( int iY = 0; iY < nBlocksPerColumn; iY++ ) 00693 { 00694 for( int iX = 0; iX < nBlocksPerRow; iX++ ) 00695 { 00696 if( papoBlocks[iX + iY*nBlocksPerRow] != NULL ) 00697 { 00698 CPLErr eErr; 00699 00700 eErr = FlushBlock( iX, iY ); 00701 00702 if( eErr != CE_None ) 00703 return eErr; 00704 } 00705 } 00706 } 00707 00708 return( CE_None ); 00709 } 00710 00711 /************************************************************************/ 00712 /* GDALFlushRasterCache() */ 00713 /************************************************************************/ 00714 00715 CPLErr GDALFlushRasterCache( GDALRasterBandH hBand ) 00716 00717 { 00718 return ((GDALRasterBand *) hBand)->FlushCache(); 00719 } 00720 00721 /************************************************************************/ 00722 /* FlushBlock() */ 00723 /* */ 00724 /* Flush a block out of the block cache. If it has been */ 00725 /* modified write it to disk. If no specific tile is */ 00726 /* indicated, write the oldest tile. */ 00727 /* */ 00728 /* Protected method. */ 00729 /************************************************************************/ 00730 00731 CPLErr GDALRasterBand::FlushBlock( int nBlockXOff, int nBlockYOff ) 00732 00733 { 00734 int nBlockIndex; 00735 GDALRasterBlock *poBlock; 00736 CPLErr eErr = CE_None; 00737 00738 InitBlockInfo(); 00739 00740 /* -------------------------------------------------------------------- */ 00741 /* Validate */ 00742 /* -------------------------------------------------------------------- */ 00743 CPLAssert( nBlockXOff >= 0 && nBlockXOff < nBlocksPerRow ); 00744 CPLAssert( nBlockYOff >= 0 && nBlockYOff < nBlocksPerColumn ); 00745 00746 nBlockIndex = nBlockXOff + nBlockYOff * nBlocksPerRow; 00747 poBlock = papoBlocks[nBlockIndex]; 00748 if( poBlock == NULL ) 00749 return( CE_None ); 00750 00751 /* -------------------------------------------------------------------- */ 00752 /* Remove, and update count. */ 00753 /* -------------------------------------------------------------------- */ 00754 papoBlocks[nBlockIndex] = NULL; 00755 00756 /* -------------------------------------------------------------------- */ 00757 /* Is the target block dirty? If so we need to write it. */ 00758 /* -------------------------------------------------------------------- */ 00759 if( poBlock->GetDirty() ) 00760 poBlock->Write(); 00761 00762 /* -------------------------------------------------------------------- */ 00763 /* Deallocate the block; */ 00764 /* -------------------------------------------------------------------- */ 00765 delete poBlock; 00766 00767 return( eErr ); 00768 } 00769 00770 00771 /************************************************************************/ 00772 /* GetBlockRef() */ 00773 /************************************************************************/ 00774 00790 GDALRasterBlock * GDALRasterBand::GetBlockRef( int nXBlockOff, 00791 int nYBlockOff ) 00792 00793 { 00794 int nBlockIndex; 00795 00796 InitBlockInfo(); 00797 00798 /* -------------------------------------------------------------------- */ 00799 /* Validate the request */ 00800 /* -------------------------------------------------------------------- */ 00801 if( nXBlockOff < 0 || nXBlockOff >= nBlocksPerRow ) 00802 { 00803 CPLError( CE_Failure, CPLE_IllegalArg, 00804 "Illegal nBlockXOff value (%d) in " 00805 "GDALRasterBand::GetBlockRef()\n", 00806 nXBlockOff ); 00807 00808 return( NULL ); 00809 } 00810 00811 if( nYBlockOff < 0 || nYBlockOff >= nBlocksPerColumn ) 00812 { 00813 CPLError( CE_Failure, CPLE_IllegalArg, 00814 "Illegal nBlockYOff value (%d) in " 00815 "GDALRasterBand::GetBlockRef()\n", 00816 nYBlockOff ); 00817 00818 return( NULL ); 00819 } 00820 00821 /* -------------------------------------------------------------------- */ 00822 /* If the block isn't already in the cache, we will need to */ 00823 /* create it, read into it, and adopt it. Adopting it may */ 00824 /* flush an old tile from the cache. */ 00825 /* -------------------------------------------------------------------- */ 00826 nBlockIndex = nXBlockOff + nYBlockOff * nBlocksPerRow; 00827 00828 if( papoBlocks[nBlockIndex] == NULL ) 00829 { 00830 GDALRasterBlock *poBlock; 00831 00832 poBlock = new GDALRasterBlock( this, nXBlockOff, nYBlockOff ); 00833 00834 /* allocate data space */ 00835 if( poBlock->Internalize() != CE_None ) 00836 { 00837 delete poBlock; 00838 00839 return( NULL ); 00840 } 00841 00842 if( IReadBlock(nXBlockOff,nYBlockOff,poBlock->GetDataRef()) != CE_None) 00843 { 00844 delete poBlock; 00845 return( NULL ); 00846 } 00847 00848 AdoptBlock( nXBlockOff, nYBlockOff, poBlock ); 00849 } 00850 00851 /* -------------------------------------------------------------------- */ 00852 /* Every read access updates the last touched time. */ 00853 /* -------------------------------------------------------------------- */ 00854 if( papoBlocks[nBlockIndex] != NULL ) 00855 papoBlocks[nBlockIndex]->Touch(); 00856 00857 return( papoBlocks[nBlockIndex] ); 00858 } 00859 00860 /************************************************************************/ 00861 /* GetAccess() */ 00862 /************************************************************************/ 00863 00870 GDALAccess GDALRasterBand::GetAccess() 00871 00872 { 00873 return eAccess; 00874 } 00875 00876 /************************************************************************/ 00877 /* GetCategoryNames() */ 00878 /************************************************************************/ 00879 00895 char **GDALRasterBand::GetCategoryNames() 00896 00897 { 00898 return NULL; 00899 } 00900 00901 /************************************************************************/ 00902 /* GDALGetRasterCategoryNames() */ 00903 /************************************************************************/ 00904 00905 char **GDALGetRasterCategoryNames( GDALRasterBandH hBand ) 00906 00907 { 00908 return ((GDALRasterBand *) hBand)->GetCategoryNames(); 00909 } 00910 00911 /************************************************************************/ 00912 /* SetCategoryNames() */ 00913 /************************************************************************/ 00914 00930 CPLErr GDALRasterBand::SetCategoryNames( char ** ) 00931 00932 { 00933 return CE_Failure; 00934 } 00935 00936 /************************************************************************/ 00937 /* GDALSetCategoryNames() */ 00938 /************************************************************************/ 00939 00940 CPLErr GDALSetRasterCategoryNames( GDALRasterBandH hBand, char ** papszNames ) 00941 00942 { 00943 return ((GDALRasterBand *) hBand)->SetCategoryNames( papszNames ); 00944 } 00945 00946 /************************************************************************/ 00947 /* GetNoDataValue() */ 00948 /************************************************************************/ 00949 00966 double GDALRasterBand::GetNoDataValue( int *pbSuccess ) 00967 00968 { 00969 if( pbSuccess != NULL ) 00970 *pbSuccess = FALSE; 00971 00972 return -1e10; 00973 } 00974 00975 /************************************************************************/ 00976 /* GDALGetRasterNoDataValue() */ 00977 /************************************************************************/ 00978 00979 double GDALGetRasterNoDataValue( GDALRasterBandH hBand, int *pbSuccess ) 00980 00981 { 00982 return ((GDALRasterBand *) hBand)->GetNoDataValue( pbSuccess ); 00983 } 00984 00985 /************************************************************************/ 00986 /* SetNoDataValue() */ 00987 /************************************************************************/ 00988 01004 CPLErr GDALRasterBand::SetNoDataValue( double ) 01005 01006 { 01007 return CE_Failure; 01008 } 01009 01010 /************************************************************************/ 01011 /* GDALSetRasterNoDataValue() */ 01012 /************************************************************************/ 01013 01014 CPLErr GDALSetRasterNoDataValue( GDALRasterBandH hBand, double dfValue ) 01015 01016 { 01017 return ((GDALRasterBand *) hBand)->SetNoDataValue( dfValue ); 01018 } 01019 01020 /************************************************************************/ 01021 /* GetMaximum() */ 01022 /************************************************************************/ 01023 01038 double GDALRasterBand::GetMaximum( int *pbSuccess ) 01039 01040 { 01041 if( pbSuccess != NULL ) 01042 *pbSuccess = FALSE; 01043 01044 switch( eDataType ) 01045 { 01046 case GDT_Byte: 01047 return 255; 01048 01049 case GDT_UInt16: 01050 return 65535; 01051 01052 case GDT_Int16: 01053 case GDT_CInt16: 01054 return 32767; 01055 01056 case GDT_Int32: 01057 case GDT_CInt32: 01058 return 2147483647.0; 01059 01060 case GDT_UInt32: 01061 return 4294967295.0; 01062 01063 case GDT_Float32: 01064 case GDT_CFloat32: 01065 return 4294967295.0; /* not actually accurate */ 01066 01067 case GDT_Float64: 01068 case GDT_CFloat64: 01069 return 4294967295.0; /* not actually accurate */ 01070 01071 default: 01072 return 4294967295.0; /* not actually accurate */ 01073 } 01074 } 01075 01076 /************************************************************************/ 01077 /* GDALGetRasterMaximum() */ 01078 /************************************************************************/ 01079 01080 double GDALGetRasterMaximum( GDALRasterBandH hBand, int *pbSuccess ) 01081 01082 { 01083 return ((GDALRasterBand *) hBand)->GetMaximum( pbSuccess ); 01084 } 01085 01086 /************************************************************************/ 01087 /* GetMinimum() */ 01088 /************************************************************************/ 01089 01104 double GDALRasterBand::GetMinimum( int *pbSuccess ) 01105 01106 { 01107 if( pbSuccess != NULL ) 01108 *pbSuccess = FALSE; 01109 01110 switch( eDataType ) 01111 { 01112 case GDT_Byte: 01113 return 0; 01114 01115 case GDT_UInt16: 01116 return 0; 01117 01118 case GDT_Int16: 01119 return -32768; 01120 01121 case GDT_Int32: 01122 return -2147483648.0; 01123 01124 case GDT_UInt32: 01125 return 0; 01126 01127 case GDT_Float32: 01128 return -4294967295.0; /* not actually accurate */ 01129 01130 case GDT_Float64: 01131 return -4294967295.0; /* not actually accurate */ 01132 01133 default: 01134 return -4294967295.0; /* not actually accurate */ 01135 } 01136 } 01137 01138 /************************************************************************/ 01139 /* GDALGetRasterMinimum() */ 01140 /************************************************************************/ 01141 01142 double GDALGetRasterMinimum( GDALRasterBandH hBand, int *pbSuccess ) 01143 01144 { 01145 return ((GDALRasterBand *) hBand)->GetMinimum( pbSuccess ); 01146 } 01147 01148 /************************************************************************/ 01149 /* GetColorInterpretation() */ 01150 /************************************************************************/ 01151 01164 GDALColorInterp GDALRasterBand::GetColorInterpretation() 01165 01166 { 01167 return GCI_Undefined; 01168 } 01169 01170 /************************************************************************/ 01171 /* GDALGetRasterColorInterpretation() */ 01172 /************************************************************************/ 01173 01174 GDALColorInterp GDALGetRasterColorInterpretation( GDALRasterBandH hBand ) 01175 01176 { 01177 return ((GDALRasterBand *) hBand)->GetColorInterpretation(); 01178 } 01179 01180 /************************************************************************/ 01181 /* GetColorTable() */ 01182 /************************************************************************/ 01183 01196 GDALColorTable *GDALRasterBand::GetColorTable() 01197 01198 { 01199 return NULL; 01200 } 01201 01202 /************************************************************************/ 01203 /* GDALGetRasterColorTable() */ 01204 /************************************************************************/ 01205 01206 GDALColorTableH GDALGetRasterColorTable( GDALRasterBandH hBand ) 01207 01208 { 01209 return (GDALColorTableH) ((GDALRasterBand *) hBand)->GetColorTable(); 01210 } 01211 01212 /************************************************************************/ 01213 /* SetColorTable() */ 01214 /************************************************************************/ 01215 01231 CPLErr GDALRasterBand::SetColorTable( GDALColorTable * poCT ) 01232 01233 { 01234 return CE_Failure; 01235 } 01236 01237 /************************************************************************/ 01238 /* GDALSetRasterColorTable() */ 01239 /************************************************************************/ 01240 01241 CPLErr GDALSetRasterColorTable( GDALRasterBandH hBand, GDALColorTableH hCT ) 01242 01243 { 01244 return ((GDALRasterBand *) hBand)->SetColorTable( (GDALColorTable *) hCT ); 01245 } 01246 01247 /************************************************************************/ 01248 /* HasArbitraryOverviews() */ 01249 /************************************************************************/ 01250 01266 int GDALRasterBand::HasArbitraryOverviews() 01267 01268 { 01269 return FALSE; 01270 } 01271 01272 /************************************************************************/ 01273 /* GDALHasArbitraryOverviews() */ 01274 /************************************************************************/ 01275 01276 int GDALHasArbitraryOverviews( GDALRasterBandH hBand ) 01277 01278 { 01279 return ((GDALRasterBand *) hBand)->HasArbitraryOverviews(); 01280 } 01281 01282 /************************************************************************/ 01283 /* GetOverviewCount() */ 01284 /************************************************************************/ 01285 01294 int GDALRasterBand::GetOverviewCount() 01295 01296 { 01297 if( poDS != NULL && poDS->oOvManager.IsInitialized() ) 01298 return poDS->oOvManager.GetOverviewCount( nBand ); 01299 else 01300 return 0; 01301 } 01302 01303 /************************************************************************/ 01304 /* GDALGetOverviewCount() */ 01305 /************************************************************************/ 01306 01307 int GDALGetOverviewCount( GDALRasterBandH hBand ) 01308 01309 { 01310 return ((GDALRasterBand *) hBand)->GetOverviewCount(); 01311 } 01312 01313 01314 /************************************************************************/ 01315 /* GetOverview() */ 01316 /************************************************************************/ 01317 01328 GDALRasterBand * GDALRasterBand::GetOverview( int i ) 01329 01330 { 01331 if( poDS != NULL && poDS->oOvManager.IsInitialized() ) 01332 return poDS->oOvManager.GetOverview( nBand, i ); 01333 else 01334 return NULL; 01335 } 01336 01337 /************************************************************************/ 01338 /* GDALGetOverview() */ 01339 /************************************************************************/ 01340 01341 GDALRasterBandH GDALGetOverview( GDALRasterBandH hBand, int i ) 01342 01343 { 01344 return (GDALRasterBandH) ((GDALRasterBand *) hBand)->GetOverview(i); 01345 } 01346 01347 /************************************************************************/ 01348 /* BuildOverviews() */ 01349 /************************************************************************/ 01350 01367 CPLErr GDALRasterBand::BuildOverviews( const char *pszResampling, 01368 int nOverviews, int *panOverviewList, 01369 GDALProgressFunc pfnProgress, 01370 void * pProgressData ) 01371 01372 { 01373 CPLError( CE_Failure, CPLE_NotSupported, 01374 "BuildOverviews() not supported for this dataset." ); 01375 01376 return( CE_Failure ); 01377 } 01378 01379 /************************************************************************/ 01380 /* GetOffset() */ 01381 /************************************************************************/ 01382 01402 double GDALRasterBand::GetOffset( int *pbSuccess ) 01403 01404 { 01405 if( pbSuccess != NULL ) 01406 *pbSuccess = FALSE; 01407 01408 return 0.0; 01409 } 01410 01411 /************************************************************************/ 01412 /* GetScale() */ 01413 /************************************************************************/ 01414 01434 double GDALRasterBand::GetScale( int *pbSuccess ) 01435 01436 { 01437 if( pbSuccess != NULL ) 01438 *pbSuccess = FALSE; 01439 01440 return 1.0; 01441 } 01442 01443 /************************************************************************/ 01444 /* GetDescription() */ 01445 /************************************************************************/ 01446 01453 const char *GDALRasterBand::GetDescription() 01454 01455 { 01456 return ""; 01457 } 01458 01459 01460 /************************************************************************/ 01461 /* GetUnitType() */ 01462 /************************************************************************/ 01463 01477 const char *GDALRasterBand::GetUnitType() 01478 01479 { 01480 return ""; 01481 } 01482 01483 /************************************************************************/ 01484 /* GDALGetRasterUnitType() */ 01485 /************************************************************************/ 01486 01487 const char *GDALGetRasterUnitType( GDALRasterBandH hBand ) 01488 01489 { 01490 return ((GDALRasterBand *) hBand)->GetUnitType(); 01491 } 01492 01493 /************************************************************************/ 01494 /* GetXSize() */ 01495 /************************************************************************/ 01496 01505 int GDALRasterBand::GetXSize() 01506 01507 { 01508 return nRasterXSize; 01509 } 01510 01511 /************************************************************************/ 01512 /* GDALGetRasterBandXSize() */ 01513 /************************************************************************/ 01514 01515 int GDALGetRasterBandXSize( GDALRasterBandH hBand ) 01516 01517 { 01518 return ((GDALRasterBand *) hBand)->GetXSize(); 01519 } 01520 01521 /************************************************************************/ 01522 /* GetYSize() */ 01523 /************************************************************************/ 01524 01533 int GDALRasterBand::GetYSize() 01534 01535 { 01536 return nRasterYSize; 01537 } 01538 01539 /************************************************************************/ 01540 /* GDALGetRasterBandYSize() */ 01541 /************************************************************************/ 01542 01543 int GDALGetRasterBandYSize( GDALRasterBandH hBand ) 01544 01545 { 01546 return ((GDALRasterBand *) hBand)->GetYSize(); 01547 } 01548 01549 /************************************************************************/ 01550 /* GetBand() */ 01551 /************************************************************************/ 01552 01553 int GDALRasterBand::GetBand() 01554 01555 { 01556 return nBand; 01557 } 01558 01559 /************************************************************************/ 01560 /* GetHistogram() */ 01561 /************************************************************************/ 01562 01599 CPLErr GDALRasterBand::GetHistogram( double dfMin, double dfMax, 01600 int nBuckets, int *panHistogram, 01601 int bIncludeOutOfRange, int bApproxOK, 01602 GDALProgressFunc pfnProgress, 01603 void *pProgressData ) 01604 01605 { 01606 CPLAssert( pfnProgress != NULL ); 01607 01608 /* -------------------------------------------------------------------- */ 01609 /* If we have overviews, use them for the histogram. */ 01610 /* -------------------------------------------------------------------- */ 01611 if( bApproxOK && GetOverviewCount() > 0 ) 01612 { 01613 double dfBestPixels = GetXSize() * GetYSize(); 01614 GDALRasterBand *poBestOverview = NULL; 01615 01616 for( int i = 0; i < GetOverviewCount(); i++ ) 01617 { 01618 GDALRasterBand *poOverview = GetOverview(i); 01619 double dfPixels; 01620 01621 dfPixels = poOverview->GetXSize() * poOverview->GetYSize(); 01622 if( dfPixels < dfBestPixels ) 01623 { 01624 dfBestPixels = dfPixels; 01625 poBestOverview = poOverview; 01626 } 01627 01628 if( poBestOverview != NULL ) 01629 return poBestOverview-> 01630 GetHistogram( dfMin, dfMax, nBuckets, panHistogram, 01631 bIncludeOutOfRange, bApproxOK, 01632 pfnProgress, pProgressData ); 01633 } 01634 } 01635 01636 /* -------------------------------------------------------------------- */ 01637 /* Figure out the ratio of blocks we will read to get an */ 01638 /* approximate value. */ 01639 /* -------------------------------------------------------------------- */ 01640 int nSampleRate; 01641 double dfScale; 01642 01643 InitBlockInfo(); 01644 01645 if( bApproxOK ) 01646 nSampleRate = 01647 (int) MAX(1,sqrt((double) nBlocksPerRow * nBlocksPerColumn)); 01648 else 01649 nSampleRate = 1; 01650 01651 dfScale = nBuckets / (dfMax - dfMin); 01652 01653 /* -------------------------------------------------------------------- */ 01654 /* Read the blocks, and add to histogram. */ 01655 /* -------------------------------------------------------------------- */ 01656 memset( panHistogram, 0, sizeof(int) * nBuckets ); 01657 for( int iSampleBlock = 0; 01658 iSampleBlock < nBlocksPerRow * nBlocksPerColumn; 01659 iSampleBlock += nSampleRate ) 01660 { 01661 double dfValue = 0.0, dfReal, dfImag; 01662 int iXBlock, iYBlock, nXCheck, nYCheck; 01663 GDALRasterBlock *poBlock; 01664 01665 if( !pfnProgress( iSampleBlock/(double)nBlocksPerRow*nBlocksPerColumn, 01666 NULL, pProgressData ) ) 01667 return CE_Failure; 01668 01669 iYBlock = iSampleBlock / nBlocksPerRow; 01670 iXBlock = iSampleBlock - nBlocksPerRow * iYBlock; 01671 01672 poBlock = GetBlockRef( iXBlock, iYBlock ); 01673 if( poBlock == NULL ) 01674 return CE_Failure; 01675 01676 if( (iXBlock+1) * nBlockXSize > GetXSize() ) 01677 nXCheck = GetXSize() - iXBlock * nBlockXSize; 01678 else 01679 nXCheck = nBlockXSize; 01680 01681 if( (iYBlock+1) * nBlockYSize > GetYSize() ) 01682 nYCheck = GetYSize() - iYBlock * nBlockYSize; 01683 else 01684 nYCheck = nBlockYSize; 01685 01686 /* this is a special case for a common situation */ 01687 if( poBlock->GetDataType() == GDT_Byte 01688 && dfScale == 1.0 && (dfMin >= -0.5 && dfMin <= 0.5) 01689 && nYCheck == nBlockYSize && nXCheck == nBlockXSize 01690 && nBuckets == 256 ) 01691 { 01692 int nPixels = nXCheck * nYCheck; 01693 GByte *pabyData = (GByte *) poBlock->GetDataRef(); 01694 01695 for( int i = 0; i < nPixels; i++ ) 01696 panHistogram[pabyData[i]]++; 01697 01698 continue; /* to next sample block */ 01699 } 01700 01701 /* this isn't the fastest way to do this, but is easier for now */ 01702 for( int iY = 0; iY < nYCheck; iY++ ) 01703 { 01704 for( int iX = 0; iX < nXCheck; iX++ ) 01705 { 01706 int iOffset = iX + iY * nBlockXSize; 01707 int nIndex; 01708 01709 switch( poBlock->GetDataType() ) 01710 { 01711 case GDT_Byte: 01712 dfValue = ((GByte *) poBlock->GetDataRef())[iOffset]; 01713 break; 01714 01715 case GDT_UInt16: 01716 dfValue = ((GUInt16 *) poBlock->GetDataRef())[iOffset]; 01717 break; 01718 case GDT_Int16: 01719 dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset]; 01720 break; 01721 case GDT_UInt32: 01722 dfValue = ((GUInt32 *) poBlock->GetDataRef())[iOffset]; 01723 break; 01724 case GDT_Int32: 01725 dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset]; 01726 break; 01727 case GDT_Float32: 01728 dfValue = ((float *) poBlock->GetDataRef())[iOffset]; 01729 break; 01730 case GDT_Float64: 01731 dfValue = ((double *) poBlock->GetDataRef())[iOffset]; 01732 break; 01733 case GDT_CInt16: 01734 dfReal = ((GInt16 *) poBlock->GetDataRef())[iOffset*2]; 01735 dfImag = ((GInt16 *) poBlock->GetDataRef())[iOffset*2+1]; 01736 dfValue = sqrt( dfReal * dfReal + dfImag * dfImag ); 01737 break; 01738 case GDT_CInt32: 01739 dfReal = ((GInt32 *) poBlock->GetDataRef())[iOffset*2]; 01740 dfImag = ((GInt32 *) poBlock->GetDataRef())[iOffset*2+1]; 01741 dfValue = sqrt( dfReal * dfReal + dfImag * dfImag ); 01742 break; 01743 case GDT_CFloat32: 01744 dfReal = ((float *) poBlock->GetDataRef())[iOffset*2]; 01745 dfImag = ((float *) poBlock->GetDataRef())[iOffset*2+1]; 01746 dfValue = sqrt( dfReal * dfReal + dfImag * dfImag ); 01747 break; 01748 case GDT_CFloat64: 01749 dfReal = ((double *) poBlock->GetDataRef())[iOffset*2]; 01750 dfImag = ((double *) poBlock->GetDataRef())[iOffset*2+1]; 01751 dfValue = sqrt( dfReal * dfReal + dfImag * dfImag ); 01752 break; 01753 default: 01754 CPLAssert( FALSE ); 01755 return CE_Failure; 01756 } 01757 01758 nIndex = (int) floor((dfValue - dfMin) * dfScale); 01759 01760 if( nIndex < 0 ) 01761 { 01762 if( bIncludeOutOfRange ) 01763 panHistogram[0]++; 01764 } 01765 else if( nIndex >= nBuckets ) 01766 { 01767 if( bIncludeOutOfRange ) 01768 panHistogram[nBuckets-1]++; 01769 } 01770 else 01771 { 01772 panHistogram[nIndex]++; 01773 } 01774 } 01775 } 01776 } 01777 01778 pfnProgress( 1.0, NULL, pProgressData ); 01779 01780 return CE_None; 01781 } 01782 01783 /************************************************************************/ 01784 /* GDALGetRasterHistogram() */ 01785 /************************************************************************/ 01786 01787 CPLErr GDALGetRasterHistogram( GDALRasterBandH hBand, 01788 double dfMin, double dfMax, 01789 int nBuckets, int *panHistogram, 01790 int bIncludeOutOfRange, int bApproxOK, 01791 GDALProgressFunc pfnProgress, 01792 void *pProgressData ) 01793 01794 { 01795 return ((GDALRasterBand *) hBand)-> 01796 GetHistogram( dfMin, dfMax, nBuckets, panHistogram, 01797 bIncludeOutOfRange, bApproxOK, 01798 pfnProgress, pProgressData ); 01799 }