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