Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

gdal_misc.cpp

00001 /******************************************************************************
00002  * $Id: gdal_misc_cpp-source.html,v 1.6 2001/01/22 22:22:23 warmerda Exp $
00003  *
00004  * Project:  GDAL Core
00005  * Purpose:  Free standing functions for GDAL.
00006  * Author:   Frank Warmerdam, warmerda@home.com
00007  *
00008  ******************************************************************************
00009  * Copyright (c) 1999, Frank Warmerdam
00010  *
00011  * Permission is hereby granted, free of charge, to any person obtaining a
00012  * copy of this software and associated documentation files (the "Software"),
00013  * to deal in the Software without restriction, including without limitation
00014  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00015  * and/or sell copies of the Software, and to permit persons to whom the
00016  * Software is furnished to do so, subject to the following conditions:
00017  *
00018  * The above copyright notice and this permission notice shall be included
00019  * in all copies or substantial portions of the Software.
00020  *
00021  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00022  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00023  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00024  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00025  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00026  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00027  * DEALINGS IN THE SOFTWARE.
00028  ******************************************************************************
00029  *
00030  * $Log: gdal_misc_cpp-source.html,v $
00030  * Revision 1.6  2001/01/22 22:22:23  warmerda
00030  * *** empty log message ***
00030  *
00031  * Revision 1.22  2000/12/04 20:45:14  warmerda
00032  * removed unused variable.
00033  *
00034  * Revision 1.21  2000/10/06 15:22:49  warmerda
00035  * added GDALDataTypeUnion
00036  *
00037  * Revision 1.20  2000/08/18 15:24:48  warmerda
00038  * added GDALTermProgress
00039  *
00040  * Revision 1.19  2000/08/09 16:25:42  warmerda
00041  * don't crash if block is null
00042  *
00043  * Revision 1.18  2000/07/11 14:35:43  warmerda
00044  * added documentation
00045  *
00046  * Revision 1.17  2000/07/05 17:53:33  warmerda
00047  * Removed unused code related to nXCheck.
00048  *
00049  * Revision 1.16  2000/06/27 17:21:26  warmerda
00050  * added GDALGetRasterSampleOverview
00051  *
00052  * Revision 1.15  2000/06/26 22:17:49  warmerda
00053  * added scaled progress support
00054  *
00055  * Revision 1.14  2000/06/05 17:24:05  warmerda
00056  * added real complex support
00057  *
00058  * Revision 1.13  2000/04/21 21:55:32  warmerda
00059  * made more robust if block read fails
00060  *
00061  * Revision 1.12  2000/04/17 20:59:40  warmerda
00062  * Removed printf.
00063  *
00064  * Revision 1.11  2000/04/17 20:59:14  warmerda
00065  * fixed sampling bug
00066  *
00067  * Revision 1.10  2000/03/31 13:41:45  warmerda
00068  * added gcp support functions
00069  *
00070  * Revision 1.9  2000/03/24 00:09:19  warmerda
00071  * added sort-of random sampling
00072  *
00073  * Revision 1.8  2000/03/23 16:53:21  warmerda
00074  * use overviews for approximate min/max
00075  *
00076  * Revision 1.7  2000/03/09 23:21:44  warmerda
00077  * added GDALDummyProgress
00078  *
00079  * Revision 1.6  2000/03/06 21:59:44  warmerda
00080  * added min/max calculate
00081  *
00082  * Revision 1.5  2000/03/06 02:20:15  warmerda
00083  * added getname functions for colour interpretations
00084  *
00085  * Revision 1.4  1999/07/23 19:35:47  warmerda
00086  * added GDALGetDataTypeName
00087  *
00088  * Revision 1.3  1999/05/17 02:00:45  vgough
00089  * made pure_virtual C linkage
00090  *
00091  * Revision 1.2  1999/05/16 19:32:13  warmerda
00092  * Added __pure_virtual.
00093  *
00094  * Revision 1.1  1998/12/06 02:50:16  warmerda
00095  * New
00096  *
00097  */
00098 
00099 #include "gdal_priv.h"
00100 
00101 /************************************************************************/
00102 /*                           __pure_virtual()                           */
00103 /*                                                                      */
00104 /*      The following is a gross hack to remove the last remaining      */
00105 /*      dependency on the GNU C++ standard library.                     */
00106 /************************************************************************/
00107 
00108 #ifdef __GNUC__
00109 
00110 extern "C"
00111 void __pure_virtual()
00112 
00113 {
00114 }
00115 
00116 #endif
00117 
00118 /************************************************************************/
00119 /*                         GDALDataTypeUnion()                          */
00120 /************************************************************************/
00121 
00132 GDALDataType GDALDataTypeUnion( GDALDataType eType1, GDALDataType eType2 )
00133 
00134 {
00135     int         bFloating, bComplex, nBits, bSigned;
00136 
00137     bComplex = GDALDataTypeIsComplex(eType1) | GDALDataTypeIsComplex(eType2);
00138     
00139     switch( eType1 )
00140     {
00141       case GDT_Byte:
00142         nBits = 8;
00143         bSigned = FALSE;
00144         bFloating = FALSE;
00145         break;
00146         
00147       case GDT_Int16:
00148       case GDT_CInt16:
00149         nBits = 16;
00150         bSigned = TRUE;
00151         bFloating = FALSE;
00152         break;
00153         
00154       case GDT_UInt16:
00155         nBits = 16;
00156         bSigned = FALSE;
00157         bFloating = FALSE;
00158         break;
00159         
00160       case GDT_Int32:
00161       case GDT_CInt32:
00162         nBits = 32;
00163         bSigned = TRUE;
00164         bFloating = FALSE;
00165         break;
00166         
00167       case GDT_UInt32:
00168         nBits = 32;
00169         bSigned = FALSE;
00170         bFloating = FALSE;
00171         break;
00172 
00173       case GDT_Float32:
00174       case GDT_CFloat32:
00175         nBits = 32;
00176         bSigned = TRUE;
00177         bFloating = TRUE;
00178         break;
00179 
00180       case GDT_Float64:
00181       case GDT_CFloat64:
00182         nBits = 64;
00183         bSigned = TRUE;
00184         bFloating = TRUE;
00185         break;
00186 
00187       default:
00188         CPLAssert( FALSE );
00189         return GDT_Unknown;
00190     }
00191 
00192     switch( eType2 )
00193     {
00194       case GDT_Byte:
00195         break;
00196         
00197       case GDT_Int16:
00198         nBits = MAX(nBits,16);
00199         bSigned = TRUE;
00200         break;
00201         
00202       case GDT_UInt16:
00203         nBits = MAX(nBits,16);
00204         break;
00205         
00206       case GDT_Int32:
00207       case GDT_CInt32:
00208         nBits = MAX(nBits,32);
00209         bSigned = TRUE;
00210         break;
00211         
00212       case GDT_UInt32:
00213         nBits = MAX(nBits,32);
00214         break;
00215 
00216       case GDT_Float32:
00217       case GDT_CFloat32:
00218         nBits = MAX(nBits,32);
00219         bSigned = TRUE;
00220         bFloating = TRUE;
00221         break;
00222 
00223       case GDT_Float64:
00224       case GDT_CFloat64:
00225         nBits = MAX(nBits,64);
00226         bSigned = TRUE;
00227         bFloating = TRUE;
00228         break;
00229 
00230       default:
00231         CPLAssert( FALSE );
00232         return GDT_Unknown;
00233     }
00234 
00235     if( nBits == 8 )
00236         return GDT_Byte;
00237     else if( nBits == 16 && bComplex )
00238         return GDT_CInt16;
00239     else if( nBits == 16 && bSigned )
00240         return GDT_Int16;
00241     else if( nBits == 16 && !bSigned )
00242         return GDT_UInt16;
00243     else if( nBits == 32 && bFloating && bComplex )
00244         return GDT_CFloat32;
00245     else if( nBits == 32 && bFloating )
00246         return GDT_Float32;
00247     else if( nBits == 32 && bComplex )
00248         return GDT_CInt32;
00249     else if( nBits == 32 && bSigned )
00250         return GDT_Int32;
00251     else if( nBits == 32 && !bSigned )
00252         return GDT_UInt32;
00253     else if( nBits == 64 && bComplex )
00254         return GDT_CFloat64;
00255     else
00256         return GDT_Float64;
00257 }
00258 
00259 
00260 /************************************************************************/
00261 /*                        GDALGetDataTypeSize()                         */
00262 /************************************************************************/
00263 int GDALGetDataTypeSize( GDALDataType eDataType )
00264 
00265 {
00266     switch( eDataType )
00267     {
00268       case GDT_Byte:
00269         return 8;
00270 
00271       case GDT_UInt16:
00272       case GDT_Int16:
00273         return 16;
00274 
00275       case GDT_UInt32:
00276       case GDT_Int32:
00277       case GDT_Float32:
00278       case GDT_CInt16:
00279         return 32;
00280 
00281       case GDT_Float64:
00282       case GDT_CInt32:
00283       case GDT_CFloat32:
00284         return 64;
00285 
00286       case GDT_CFloat64:
00287         return 128;
00288 
00289       default:
00290         CPLAssert( FALSE );
00291         return 0;
00292     }
00293 }
00294 
00295 /************************************************************************/
00296 /*                       GDALDataTypeIsComplex()                        */
00297 /************************************************************************/
00298 
00299 int GDALDataTypeIsComplex( GDALDataType eDataType )
00300 
00301 {
00302     switch( eDataType )
00303     {
00304       case GDT_CInt16:
00305       case GDT_CInt32:
00306       case GDT_CFloat32:
00307       case GDT_CFloat64:
00308         return TRUE;
00309 
00310       default:
00311         return FALSE;
00312     }
00313 }
00314 
00315 /************************************************************************/
00316 /*                        GDALGetDataTypeName()                         */
00317 /************************************************************************/
00318 
00319 const char *GDALGetDataTypeName( GDALDataType eDataType )
00320 
00321 {
00322     switch( eDataType )
00323     {
00324       case GDT_Byte:
00325         return "Byte";
00326 
00327       case GDT_UInt16:
00328         return "UInt16";
00329 
00330       case GDT_Int16:
00331         return "Int16";
00332 
00333       case GDT_UInt32:
00334         return "UInt32";
00335         
00336       case GDT_Int32:
00337         return "Int32";
00338         
00339       case GDT_Float32:
00340         return "Float32";
00341 
00342       case GDT_Float64:
00343         return "Float64";
00344 
00345       case GDT_CInt16:
00346         return "CInt16";
00347 
00348       case GDT_CInt32:
00349         return "CInt32";
00350 
00351       case GDT_CFloat32:
00352         return "CFloat32";
00353 
00354       case GDT_CFloat64:
00355         return "CFloat64";
00356 
00357       default:
00358         return NULL;
00359     }
00360 }
00361 
00362 /************************************************************************/
00363 /*                  GDALGetPaletteInterpretationName()                  */
00364 /************************************************************************/
00365 
00366 const char *GDALGetPaletteInterpretationName( GDALPaletteInterp eInterp )
00367 
00368 {
00369     switch( eInterp )
00370     {
00371       case GPI_Gray:
00372         return "Gray";
00373 
00374       case GPI_RGB:
00375         return "RGB";
00376         
00377       case GPI_CMYK:
00378         return "CMYK";
00379 
00380       case GPI_HLS:
00381         return "HLS";
00382         
00383       default:
00384         return "Unknown";
00385     }
00386 }
00387 
00388 /************************************************************************/
00389 /*                   GDALGetColorInterpretationName()                   */
00390 /************************************************************************/
00391 
00392 const char *GDALGetColorInterpretationName( GDALColorInterp eInterp )
00393 
00394 {
00395     switch( eInterp )
00396     {
00397       case GCI_Undefined:
00398         return "Undefined";
00399 
00400       case GCI_GrayIndex:
00401         return "Gray";
00402 
00403       case GCI_PaletteIndex:
00404         return "Palette";
00405 
00406       case GCI_RedBand:
00407         return "Red";
00408 
00409       case GCI_GreenBand:
00410         return "Green";
00411 
00412       case GCI_BlueBand:
00413         return "Blue";
00414 
00415       case GCI_AlphaBand:
00416         return "Alpha";
00417 
00418       case GCI_HueBand:
00419         return "Hue";
00420 
00421       case GCI_SaturationBand:
00422         return "Saturation";
00423 
00424       case GCI_LightnessBand:
00425         return "Lightness";
00426 
00427       case GCI_CyanBand:
00428         return "Cyan";
00429 
00430       case GCI_MagentaBand:
00431         return "Magenta";
00432 
00433       case GCI_YellowBand:
00434         return "Yellow";
00435 
00436       case GCI_BlackBand:
00437         return "Black";
00438         
00439       default:
00440         return "Unknown";
00441     }
00442 }
00443 
00444 /************************************************************************/
00445 /*                      GDALComputeRasterMinMax()                       */
00446 /************************************************************************/
00447 
00466 void GDALComputeRasterMinMax( GDALRasterBandH hBand, int bApproxOK, 
00467                               double adfMinMax[2] )
00468 
00469 {
00470     double       dfMin=0.0, dfMax=0.0;
00471     GDALRasterBand *poBand;
00472 
00473 /* -------------------------------------------------------------------- */
00474 /*      Does the driver already know the min/max?                       */
00475 /* -------------------------------------------------------------------- */
00476     if( bApproxOK )
00477     {
00478         int          bSuccessMin, bSuccessMax;
00479 
00480         dfMin = GDALGetRasterMinimum( hBand, &bSuccessMin );
00481         dfMax = GDALGetRasterMaximum( hBand, &bSuccessMax );
00482 
00483         if( bSuccessMin && bSuccessMax )
00484         {
00485             adfMinMax[0] = dfMin;
00486             adfMinMax[1] = dfMax;
00487             return;
00488         }
00489     }
00490     
00491 /* -------------------------------------------------------------------- */
00492 /*      If we have overview bands, use them for min/max.                */
00493 /* -------------------------------------------------------------------- */
00494     if( bApproxOK )
00495         poBand = (GDALRasterBand *) GDALGetRasterSampleOverview( hBand, 2500 );
00496     else 
00497         poBand = (GDALRasterBand *) hBand;
00498     
00499 /* -------------------------------------------------------------------- */
00500 /*      Figure out the ratio of blocks we will read to get an           */
00501 /*      approximate value.                                              */
00502 /* -------------------------------------------------------------------- */
00503     int         nBlockXSize, nBlockYSize;
00504     int         nBlocksPerRow, nBlocksPerColumn;
00505     int         nSampleRate;
00506     int         bGotNoDataValue, bFirstValue = TRUE;
00507     double      dfNoDataValue;
00508 
00509     dfNoDataValue = poBand->GetNoDataValue( &bGotNoDataValue );
00510 
00511     poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
00512     nBlocksPerRow = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
00513     nBlocksPerColumn = (poBand->GetYSize() + nBlockYSize - 1) / nBlockYSize;
00514 
00515     if( bApproxOK )
00516         nSampleRate = 
00517             (int) MAX(1,sqrt((double) nBlocksPerRow * nBlocksPerColumn));
00518     else
00519         nSampleRate = 1;
00520     
00521     for( int iSampleBlock = 0; 
00522          iSampleBlock < nBlocksPerRow * nBlocksPerColumn;
00523          iSampleBlock += nSampleRate )
00524     {
00525         double dfValue = 0.0;
00526         int  iXBlock, iYBlock, nXCheck, nYCheck;
00527         GDALRasterBlock *poBlock;
00528 
00529         iYBlock = iSampleBlock / nBlocksPerRow;
00530         iXBlock = iSampleBlock - nBlocksPerRow * iYBlock;
00531         
00532         poBlock = poBand->GetBlockRef( iXBlock, iYBlock );
00533         if( poBlock == NULL )
00534             continue;
00535         
00536         if( (iXBlock+1) * nBlockXSize > poBand->GetXSize() )
00537             nXCheck = poBand->GetXSize() - iXBlock * nBlockXSize;
00538         else
00539             nXCheck = nBlockXSize;
00540 
00541         if( (iYBlock+1) * nBlockYSize > poBand->GetYSize() )
00542             nYCheck = poBand->GetYSize() - iYBlock * nBlockYSize;
00543         else
00544             nYCheck = nBlockYSize;
00545 
00546         /* this isn't the fastest way to do this, but is easier for now */
00547         for( int iY = 0; iY < nYCheck; iY++ )
00548         {
00549             for( int iX = 0; iX < nXCheck; iX++ )
00550             {
00551                 int    iOffset = iX + iY * nBlockXSize;
00552 
00553                 switch( poBlock->GetDataType() )
00554                 {
00555                   case GDT_Byte:
00556                     dfValue = ((GByte *) poBlock->GetDataRef())[iOffset];
00557                     break;
00558                   case GDT_UInt16:
00559                     dfValue = ((GUInt16 *) poBlock->GetDataRef())[iOffset];
00560                     break;
00561                   case GDT_Int16:
00562                     dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset];
00563                     break;
00564                   case GDT_UInt32:
00565                     dfValue = ((GUInt32 *) poBlock->GetDataRef())[iOffset];
00566                     break;
00567                   case GDT_Int32:
00568                     dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset];
00569                     break;
00570                   case GDT_Float32:
00571                     dfValue = ((float *) poBlock->GetDataRef())[iOffset];
00572                     break;
00573                   case GDT_Float64:
00574                     dfValue = ((double *) poBlock->GetDataRef())[iOffset];
00575                     break;
00576                   case GDT_CInt16:
00577                     dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset*2];
00578                     break;
00579                   case GDT_CInt32:
00580                     dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset*2];
00581                     break;
00582                   case GDT_CFloat32:
00583                     dfValue = ((float *) poBlock->GetDataRef())[iOffset*2];
00584                     break;
00585                   case GDT_CFloat64:
00586                     dfValue = ((double *) poBlock->GetDataRef())[iOffset*2];
00587                     break;
00588                   default:
00589                     CPLAssert( FALSE );
00590                 }
00591                 
00592                 if( bGotNoDataValue && dfValue == dfNoDataValue )
00593                     continue;
00594 
00595                 if( bFirstValue )
00596                 {
00597                     dfMin = dfMax = dfValue;
00598                     bFirstValue = FALSE;
00599                 }
00600                 else
00601                 {
00602                     dfMin = MIN(dfMin,dfValue);
00603                     dfMax = MAX(dfMax,dfValue);
00604                 }
00605             }
00606         }
00607     }
00608 
00609     adfMinMax[0] = dfMin;
00610     adfMinMax[1] = dfMax;
00611 }
00612 
00613 /************************************************************************/
00614 /*                         GDALDummyProgress()                          */
00615 /************************************************************************/
00616 
00681 int GDALDummyProgress( double, const char *, void * )
00682 
00683 {
00684     return TRUE;
00685 }
00686 
00687 /************************************************************************/
00688 /*                         GDALScaledProgress()                         */
00689 /************************************************************************/
00690 typedef struct { 
00691     GDALProgressFunc pfnProgress;
00692     void *pData;
00693     double dfMin;
00694     double dfMax;
00695 } GDALScaledProgressInfo;
00696 
00697 int GDALScaledProgress( double dfComplete, const char *pszMessage, 
00698                         void *pData )
00699 
00700 {
00701     GDALScaledProgressInfo *psInfo = (GDALScaledProgressInfo *) pData;
00702 
00703     return psInfo->pfnProgress( dfComplete * (psInfo->dfMax - psInfo->dfMin)
00704                                 + psInfo->dfMin,
00705                                 pszMessage, psInfo->pData );
00706 }
00707 
00708 /************************************************************************/
00709 /*                      GDALCreateScaledProgress()                      */
00710 /************************************************************************/
00711 
00712 void *GDALCreateScaledProgress( double dfMin, double dfMax, 
00713                                 GDALProgressFunc pfnProgress, 
00714                                 void * pData )
00715 
00716 {
00717     GDALScaledProgressInfo *psInfo;
00718 
00719     psInfo = (GDALScaledProgressInfo *) 
00720         CPLCalloc(sizeof(GDALScaledProgressInfo),1);
00721 
00722     if( ABS(dfMin-dfMax) < 0.0000001 )
00723         dfMax = dfMin + 0.01;
00724 
00725     psInfo->pData = pData;
00726     psInfo->pfnProgress = pfnProgress;
00727     psInfo->dfMin = dfMin;
00728     psInfo->dfMax = dfMax;
00729 
00730     return (void *) psInfo;
00731 }
00732 
00733 /************************************************************************/
00734 /*                     GDALDestroyScaledProgress()                      */
00735 /************************************************************************/
00736 
00737 void GDALDestroyScaledProgress( void * pData )
00738 
00739 {
00740     CPLFree( pData );
00741 }
00742 
00743 /************************************************************************/
00744 /*                          GDALTermProgress()                          */
00745 /************************************************************************/
00746 
00747 int GDALTermProgress( double dfComplete, const char *pszMessage, void * )
00748 
00749 {
00750     static double dfLastComplete = -1.0;
00751 
00752     if( dfLastComplete > dfComplete )
00753     {
00754         if( dfLastComplete > 1.0 )
00755             dfLastComplete = -1.0;
00756         else
00757             dfLastComplete = dfComplete;
00758     }
00759 
00760     if( floor(dfLastComplete*10) != floor(dfComplete*10) )
00761     {
00762         int    nPercent = (int) floor(dfComplete*100);
00763 
00764         if( nPercent == 0 && pszMessage != NULL )
00765             fprintf( stdout, "%s:", pszMessage );
00766 
00767         if( nPercent == 100 )
00768             fprintf( stdout, "%d - done.\n", (int) floor(dfComplete*100) );
00769         else
00770         {
00771             fprintf( stdout, "%d.", (int) floor(dfComplete*100) );
00772             fflush( stdout );
00773         }
00774     }
00775     else if( floor(dfLastComplete*30) != floor(dfComplete*30) )
00776     {
00777         fprintf( stdout, "." );
00778         fflush( stdout );
00779     }
00780 
00781     dfLastComplete = dfComplete;
00782 
00783     return TRUE;
00784 }
00785 
00786 /************************************************************************/
00787 /*                    GDALGetRasterSampleOverview()                     */
00788 /************************************************************************/
00789 
00805 GDALRasterBandH GDALGetRasterSampleOverview( GDALRasterBandH hBand, 
00806                                              int nDesiredSamples )
00807 
00808 {
00809     int     nBestSamples; 
00810     GDALRasterBandH hBestBand = hBand;
00811 
00812     nBestSamples = GDALGetRasterBandXSize(hBand) 
00813         * GDALGetRasterBandYSize(hBand);
00814 
00815     for( int iOverview = 0; 
00816          iOverview < GDALGetOverviewCount( hBand );
00817          iOverview++ )
00818     {
00819         GDALRasterBandH hOBand = GDALGetOverview( hBand, iOverview );
00820         int    nOSamples;
00821 
00822         nOSamples = GDALGetRasterBandXSize(hOBand) 
00823             * GDALGetRasterBandYSize(hOBand);
00824 
00825         if( nOSamples < nBestSamples && nOSamples > nDesiredSamples )
00826         {
00827             nBestSamples = nOSamples;
00828             hBestBand = hOBand;
00829         }
00830     }
00831 
00832     return hBestBand;
00833 }
00834 
00835 /************************************************************************/
00836 /*                     GDALGetRandomRasterSample()                      */
00837 /************************************************************************/
00838 
00839 int GDALGetRandomRasterSample( GDALRasterBandH hBand, int nSamples, 
00840                                float *pafSampleBuf )
00841 
00842 {
00843     GDALRasterBand *poBand;
00844 
00845     poBand = (GDALRasterBand *) GDALGetRasterSampleOverview( hBand, nSamples );
00846 
00847 /* -------------------------------------------------------------------- */
00848 /*      Figure out the ratio of blocks we will read to get an           */
00849 /*      approximate value.                                              */
00850 /* -------------------------------------------------------------------- */
00851     int         nBlockXSize, nBlockYSize;
00852     int         nBlocksPerRow, nBlocksPerColumn;
00853     int         nSampleRate;
00854     int         bGotNoDataValue;
00855     double      dfNoDataValue;
00856     int         nActualSamples = 0;
00857     int         nBlockSampleRate;
00858 
00859     dfNoDataValue = poBand->GetNoDataValue( &bGotNoDataValue );
00860 
00861     poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
00862     nBlocksPerRow = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
00863     nBlocksPerColumn = (poBand->GetYSize() + nBlockYSize - 1) / nBlockYSize;
00864 
00865     nSampleRate = 
00866         (int) MAX(1,sqrt((double) nBlocksPerRow * nBlocksPerColumn)-2.0);
00867 
00868     if( nSampleRate == nBlocksPerRow && nSampleRate > 1 )
00869         nSampleRate--;
00870 
00871     nBlockSampleRate = MAX(1,(nBlockXSize * nBlockYSize) / 
00872         (nSamples / (nBlocksPerRow*nBlocksPerColumn / nSampleRate)));
00873     
00874     for( int iSampleBlock = 0; 
00875          iSampleBlock < nBlocksPerRow * nBlocksPerColumn;
00876          iSampleBlock += nSampleRate )
00877     {
00878         double dfValue = 0.0;
00879         int  iXBlock, iYBlock, iOffset;
00880         GDALRasterBlock *poBlock;
00881 
00882         iYBlock = iSampleBlock / nBlocksPerRow;
00883         iXBlock = iSampleBlock - nBlocksPerRow * iYBlock;
00884 
00885         poBlock = poBand->GetBlockRef( iXBlock, iYBlock );
00886         if( poBlock == NULL )
00887             continue;
00888         
00889         /* this isn't the fastest way to do this, but is easier for now */
00890         for( iOffset = nBlockXSize*nBlockYSize-1; 
00891              iOffset >= 0 && nActualSamples < nSamples; 
00892              iOffset -= nBlockSampleRate )
00893         {
00894             switch( poBlock->GetDataType() )
00895             {
00896               case GDT_Byte:
00897                 dfValue = ((GByte *) poBlock->GetDataRef())[iOffset];
00898                 break;
00899               case GDT_UInt16:
00900                 dfValue = ((GUInt16 *) poBlock->GetDataRef())[iOffset];
00901                 break;
00902               case GDT_Int16:
00903                 dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset];
00904                 break;
00905               case GDT_UInt32:
00906                 dfValue = ((GUInt32 *) poBlock->GetDataRef())[iOffset];
00907                 break;
00908               case GDT_Int32:
00909                 dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset];
00910                 break;
00911               case GDT_Float32:
00912                 dfValue = ((float *) poBlock->GetDataRef())[iOffset];
00913                 break;
00914               case GDT_Float64:
00915                 dfValue = ((double *) poBlock->GetDataRef())[iOffset];
00916                 break;
00917               case GDT_CInt16:
00918                 dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset*2];
00919                 break;
00920               case GDT_CInt32:
00921                 dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset*2];
00922                 break;
00923               case GDT_CFloat32:
00924                 dfValue = ((float *) poBlock->GetDataRef())[iOffset*2];
00925                 break;
00926               case GDT_CFloat64:
00927                 dfValue = ((double *) poBlock->GetDataRef())[iOffset*2];
00928                 break;
00929               default:
00930                 CPLAssert( FALSE );
00931             }
00932             
00933             if( bGotNoDataValue && dfValue == dfNoDataValue )
00934                 continue;
00935 
00936             pafSampleBuf[nActualSamples++] = dfValue;
00937         }
00938     }
00939 
00940     return nActualSamples;
00941 }
00942 
00943 /************************************************************************/
00944 /*                            GDALInitGCPs()                            */
00945 /************************************************************************/
00946 
00947 void GDALInitGCPs( int nCount, GDAL_GCP * psGCP )
00948 
00949 {
00950     for( int iGCP = 0; iGCP < nCount; iGCP++ )
00951     {
00952         memset( psGCP, 0, sizeof(GDAL_GCP) );
00953         psGCP->pszId = CPLStrdup("");
00954         psGCP->pszInfo = CPLStrdup("");
00955         psGCP++;
00956     }
00957 }
00958 
00959 /************************************************************************/
00960 /*                           GDALDeinitGCPs()                           */
00961 /************************************************************************/
00962 
00963 void GDALDeinitGCPs( int nCount, GDAL_GCP * psGCP )
00964 
00965 {
00966     for( int iGCP = 0; iGCP < nCount; iGCP++ )
00967     {
00968         CPLFree( psGCP->pszId );
00969         CPLFree( psGCP->pszInfo );
00970         psGCP++;
00971     }
00972 }
00973 
00974 /************************************************************************/
00975 /*                         GDALDuplicateGCPs()                          */
00976 /************************************************************************/
00977 
00978 GDAL_GCP *GDALDuplicateGCPs( int nCount, const GDAL_GCP *pasGCPList )
00979 
00980 {
00981     GDAL_GCP    *pasReturn;
00982 
00983     pasReturn = (GDAL_GCP *) CPLMalloc(sizeof(GDAL_GCP) * nCount);
00984     GDALInitGCPs( nCount, pasReturn );
00985 
00986     for( int iGCP = 0; iGCP < nCount; iGCP++ )
00987     {
00988         CPLFree( pasReturn[iGCP].pszId );
00989         pasReturn[iGCP].pszId = CPLStrdup( pasGCPList[iGCP].pszId );
00990 
00991         CPLFree( pasReturn[iGCP].pszInfo );
00992         pasReturn[iGCP].pszInfo = CPLStrdup( pasGCPList[iGCP].pszInfo );
00993 
00994         pasReturn[iGCP].dfGCPPixel = pasGCPList[iGCP].dfGCPPixel;
00995         pasReturn[iGCP].dfGCPLine = pasGCPList[iGCP].dfGCPLine;
00996         pasReturn[iGCP].dfGCPX = pasGCPList[iGCP].dfGCPX;
00997         pasReturn[iGCP].dfGCPY = pasGCPList[iGCP].dfGCPY;
00998         pasReturn[iGCP].dfGCPZ = pasGCPList[iGCP].dfGCPZ;
00999     }
01000 
01001     return pasReturn;
01002 }
01003                              

Generated at Tue Jan 16 12:43:36 2001 for GDAL by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000