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.10 2002/04/16 13:11:48 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.10  2002/04/16 13:11:48  warmerda
    00030  * updated
    00030  *
    00031  * Revision 1.29  2001/12/07 20:04:21  warmerda
    00032  * fixed serious bug in random sampler
    00033  *
    00034  * Revision 1.28  2001/11/30 03:41:26  warmerda
    00035  * Fixed bug with the block sampling rate being too low to satisfy large
    00036  * sample count values.  Fixed bug with tiled images including some uninitialized
    00037  * or zero data in the sample set on partial edge tiles.
    00038  *
    00039  * Revision 1.27  2001/11/26 20:14:01  warmerda
    00040  * added GDALProjDef stubs for old 'bridges'
    00041  *
    00042  * Revision 1.26  2001/11/19 16:03:16  warmerda
    00043  * moved GDALDectoDMS here
    00044  *
    00045  * Revision 1.25  2001/08/15 15:05:44  warmerda
    00046  * return magnitude for complex samples in random sampler
    00047  *
    00048  * Revision 1.24  2001/07/18 04:04:30  warmerda
    00049  * added CPL_CVSID
    00050  *
    00051  * Revision 1.23  2001/05/01 18:09:25  warmerda
    00052  * added GDALReadWorldFile()
    00053  *
    00054  * Revision 1.22  2000/12/04 20:45:14  warmerda
    00055  * removed unused variable.
    00056  *
    00057  * Revision 1.21  2000/10/06 15:22:49  warmerda
    00058  * added GDALDataTypeUnion
    00059  *
    00060  * Revision 1.20  2000/08/18 15:24:48  warmerda
    00061  * added GDALTermProgress
    00062  *
    00063  * Revision 1.19  2000/08/09 16:25:42  warmerda
    00064  * don't crash if block is null
    00065  *
    00066  * Revision 1.18  2000/07/11 14:35:43  warmerda
    00067  * added documentation
    00068  *
    00069  * Revision 1.17  2000/07/05 17:53:33  warmerda
    00070  * Removed unused code related to nXCheck.
    00071  *
    00072  * Revision 1.16  2000/06/27 17:21:26  warmerda
    00073  * added GDALGetRasterSampleOverview
    00074  *
    00075  * Revision 1.15  2000/06/26 22:17:49  warmerda
    00076  * added scaled progress support
    00077  *
    00078  * Revision 1.14  2000/06/05 17:24:05  warmerda
    00079  * added real complex support
    00080  *
    00081  * Revision 1.13  2000/04/21 21:55:32  warmerda
    00082  * made more robust if block read fails
    00083  *
    00084  * Revision 1.12  2000/04/17 20:59:40  warmerda
    00085  * Removed printf.
    00086  *
    00087  * Revision 1.11  2000/04/17 20:59:14  warmerda
    00088  * fixed sampling bug
    00089  *
    00090  * Revision 1.10  2000/03/31 13:41:45  warmerda
    00091  * added gcp support functions
    00092  *
    00093  * Revision 1.9  2000/03/24 00:09:19  warmerda
    00094  * added sort-of random sampling
    00095  *
    00096  * Revision 1.8  2000/03/23 16:53:21  warmerda
    00097  * use overviews for approximate min/max
    00098  *
    00099  * Revision 1.7  2000/03/09 23:21:44  warmerda
    00100  * added GDALDummyProgress
    00101  *
    00102  * Revision 1.6  2000/03/06 21:59:44  warmerda
    00103  * added min/max calculate
    00104  *
    00105  * Revision 1.5  2000/03/06 02:20:15  warmerda
    00106  * added getname functions for colour interpretations
    00107  *
    00108  * Revision 1.4  1999/07/23 19:35:47  warmerda
    00109  * added GDALGetDataTypeName
    00110  *
    00111  * Revision 1.3  1999/05/17 02:00:45  vgough
    00112  * made pure_virtual C linkage
    00113  *
    00114  * Revision 1.2  1999/05/16 19:32:13  warmerda
    00115  * Added __pure_virtual.
    00116  *
    00117  * Revision 1.1  1998/12/06 02:50:16  warmerda
    00118  * New
    00119  *
    00120  */
    00121
    00122 #include "gdal_priv.h"
    00123 #include "cpl_string.h"
    00124
    00125 CPL_CVSID("$Id: gdal_misc_cpp-source.html,v 1.10 2002/04/16 13:11:48 warmerda Exp $");
    00126
    00127 /************************************************************************/
    00128 /*                           __pure_virtual()                           */
    00129 /*                                                                      */
    00130 /*      The following is a gross hack to remove the last remaining      */
    00131 /*      dependency on the GNU C++ standard library.                     */
    00132 /************************************************************************/
    00133
    00134 #ifdef __GNUC__
    00135
    00136 extern "C"
    00137 void __pure_virtual()
    00138
    00139 {
    00140 }
    00141
    00142 #endif
    00143
    00144 /************************************************************************/
    00145 /*                         GDALDataTypeUnion()                          */
    00146 /************************************************************************/
    00147
    00158 GDALDataType GDALDataTypeUnion( GDALDataType eType1, GDALDataType eType2 )
    00159
    00160 {
    00161     int         bFloating, bComplex, nBits, bSigned;
    00162
    00163     bComplex = GDALDataTypeIsComplex(eType1) | GDALDataTypeIsComplex(eType2);
    00164
    00165     switch( eType1 )
    00166     {
    00167       case GDT_Byte:
    00168         nBits = 8;
    00169         bSigned = FALSE;
    00170         bFloating = FALSE;
    00171         break;
    00172
    00173       case GDT_Int16:
    00174       case GDT_CInt16:
    00175         nBits = 16;
    00176         bSigned = TRUE;
    00177         bFloating = FALSE;
    00178         break;
    00179
    00180       case GDT_UInt16:
    00181         nBits = 16;
    00182         bSigned = FALSE;
    00183         bFloating = FALSE;
    00184         break;
    00185
    00186       case GDT_Int32:
    00187       case GDT_CInt32:
    00188         nBits = 32;
    00189         bSigned = TRUE;
    00190         bFloating = FALSE;
    00191         break;
    00192
    00193       case GDT_UInt32:
    00194         nBits = 32;
    00195         bSigned = FALSE;
    00196         bFloating = FALSE;
    00197         break;
    00198
    00199       case GDT_Float32:
    00200       case GDT_CFloat32:
    00201         nBits = 32;
    00202         bSigned = TRUE;
    00203         bFloating = TRUE;
    00204         break;
    00205
    00206       case GDT_Float64:
    00207       case GDT_CFloat64:
    00208         nBits = 64;
    00209         bSigned = TRUE;
    00210         bFloating = TRUE;
    00211         break;
    00212
    00213       default:
    00214         CPLAssert( FALSE );
    00215         return GDT_Unknown;
    00216     }
    00217
    00218     switch( eType2 )
    00219     {
    00220       case GDT_Byte:
    00221         break;
    00222
    00223       case GDT_Int16:
    00224         nBits = MAX(nBits,16);
    00225         bSigned = TRUE;
    00226         break;
    00227
    00228       case GDT_UInt16:
    00229         nBits = MAX(nBits,16);
    00230         break;
    00231
    00232       case GDT_Int32:
    00233       case GDT_CInt32:
    00234         nBits = MAX(nBits,32);
    00235         bSigned = TRUE;
    00236         break;
    00237
    00238       case GDT_UInt32:
    00239         nBits = MAX(nBits,32);
    00240         break;
    00241
    00242       case GDT_Float32:
    00243       case GDT_CFloat32:
    00244         nBits = MAX(nBits,32);
    00245         bSigned = TRUE;
    00246         bFloating = TRUE;
    00247         break;
    00248
    00249       case GDT_Float64:
    00250       case GDT_CFloat64:
    00251         nBits = MAX(nBits,64);
    00252         bSigned = TRUE;
    00253         bFloating = TRUE;
    00254         break;
    00255
    00256       default:
    00257         CPLAssert( FALSE );
    00258         return GDT_Unknown;
    00259     }
    00260
    00261     if( nBits == 8 )
    00262         return GDT_Byte;
    00263     else if( nBits == 16 && bComplex )
    00264         return GDT_CInt16;
    00265     else if( nBits == 16 && bSigned )
    00266         return GDT_Int16;
    00267     else if( nBits == 16 && !bSigned )
    00268         return GDT_UInt16;
    00269     else if( nBits == 32 && bFloating && bComplex )
    00270         return GDT_CFloat32;
    00271     else if( nBits == 32 && bFloating )
    00272         return GDT_Float32;
    00273     else if( nBits == 32 && bComplex )
    00274         return GDT_CInt32;
    00275     else if( nBits == 32 && bSigned )
    00276         return GDT_Int32;
    00277     else if( nBits == 32 && !bSigned )
    00278         return GDT_UInt32;
    00279     else if( nBits == 64 && bComplex )
    00280         return GDT_CFloat64;
    00281     else
    00282         return GDT_Float64;
    00283 }
    00284
    00285
    00286 /************************************************************************/
    00287 /*                        GDALGetDataTypeSize()                         */
    00288 /************************************************************************/
    00289 int GDALGetDataTypeSize( GDALDataType eDataType )
    00290
    00291 {
    00292     switch( eDataType )
    00293     {
    00294       case GDT_Byte:
    00295         return 8;
    00296
    00297       case GDT_UInt16:
    00298       case GDT_Int16:
    00299         return 16;
    00300
    00301       case GDT_UInt32:
    00302       case GDT_Int32:
    00303       case GDT_Float32:
    00304       case GDT_CInt16:
    00305         return 32;
    00306
    00307       case GDT_Float64:
    00308       case GDT_CInt32:
    00309       case GDT_CFloat32:
    00310         return 64;
    00311
    00312       case GDT_CFloat64:
    00313         return 128;
    00314
    00315       default:
    00316         CPLAssert( FALSE );
    00317         return 0;
    00318     }
    00319 }
    00320
    00321 /************************************************************************/
    00322 /*                       GDALDataTypeIsComplex()                        */
    00323 /************************************************************************/
    00324
    00325 int GDALDataTypeIsComplex( GDALDataType eDataType )
    00326
    00327 {
    00328     switch( eDataType )
    00329     {
    00330       case GDT_CInt16:
    00331       case GDT_CInt32:
    00332       case GDT_CFloat32:
    00333       case GDT_CFloat64:
    00334         return TRUE;
    00335
    00336       default:
    00337         return FALSE;
    00338     }
    00339 }
    00340
    00341 /************************************************************************/
    00342 /*                        GDALGetDataTypeName()                         */
    00343 /************************************************************************/
    00344
    00345 const char *GDALGetDataTypeName( GDALDataType eDataType )
    00346
    00347 {
    00348     switch( eDataType )
    00349     {
    00350       case GDT_Byte:
    00351         return "Byte";
    00352
    00353       case GDT_UInt16:
    00354         return "UInt16";
    00355
    00356       case GDT_Int16:
    00357         return "Int16";
    00358
    00359       case GDT_UInt32:
    00360         return "UInt32";
    00361
    00362       case GDT_Int32:
    00363         return "Int32";
    00364
    00365       case GDT_Float32:
    00366         return "Float32";
    00367
    00368       case GDT_Float64:
    00369         return "Float64";
    00370
    00371       case GDT_CInt16:
    00372         return "CInt16";
    00373
    00374       case GDT_CInt32:
    00375         return "CInt32";
    00376
    00377       case GDT_CFloat32:
    00378         return "CFloat32";
    00379
    00380       case GDT_CFloat64:
    00381         return "CFloat64";
    00382
    00383       default:
    00384         return NULL;
    00385     }
    00386 }
    00387
    00388 /************************************************************************/
    00389 /*                  GDALGetPaletteInterpretationName()                  */
    00390 /************************************************************************/
    00391
    00392 const char *GDALGetPaletteInterpretationName( GDALPaletteInterp eInterp )
    00393
    00394 {
    00395     switch( eInterp )
    00396     {
    00397       case GPI_Gray:
    00398         return "Gray";
    00399
    00400       case GPI_RGB:
    00401         return "RGB";
    00402
    00403       case GPI_CMYK:
    00404         return "CMYK";
    00405
    00406       case GPI_HLS:
    00407         return "HLS";
    00408
    00409       default:
    00410         return "Unknown";
    00411     }
    00412 }
    00413
    00414 /************************************************************************/
    00415 /*                   GDALGetColorInterpretationName()                   */
    00416 /************************************************************************/
    00417
    00418 const char *GDALGetColorInterpretationName( GDALColorInterp eInterp )
    00419
    00420 {
    00421     switch( eInterp )
    00422     {
    00423       case GCI_Undefined:
    00424         return "Undefined";
    00425
    00426       case GCI_GrayIndex:
    00427         return "Gray";
    00428
    00429       case GCI_PaletteIndex:
    00430         return "Palette";
    00431
    00432       case GCI_RedBand:
    00433         return "Red";
    00434
    00435       case GCI_GreenBand:
    00436         return "Green";
    00437
    00438       case GCI_BlueBand:
    00439         return "Blue";
    00440
    00441       case GCI_AlphaBand:
    00442         return "Alpha";
    00443
    00444       case GCI_HueBand:
    00445         return "Hue";
    00446
    00447       case GCI_SaturationBand:
    00448         return "Saturation";
    00449
    00450       case GCI_LightnessBand:
    00451         return "Lightness";
    00452
    00453       case GCI_CyanBand:
    00454         return "Cyan";
    00455
    00456       case GCI_MagentaBand:
    00457         return "Magenta";
    00458
    00459       case GCI_YellowBand:
    00460         return "Yellow";
    00461
    00462       case GCI_BlackBand:
    00463         return "Black";
    00464
    00465       default:
    00466         return "Unknown";
    00467     }
    00468 }
    00469
    00470 /************************************************************************/
    00471 /*                      GDALComputeRasterMinMax()                       */
    00472 /************************************************************************/
    00473
    00492 void GDALComputeRasterMinMax( GDALRasterBandH hBand, int bApproxOK,
    00493                               double adfMinMax[2] )
    00494
    00495 {
    00496     double       dfMin=0.0, dfMax=0.0;
    00497     GDALRasterBand *poBand;
    00498
    00499 /* -------------------------------------------------------------------- */
    00500 /*      Does the driver already know the min/max?                       */
    00501 /* -------------------------------------------------------------------- */
    00502     if( bApproxOK )
    00503     {
    00504         int          bSuccessMin, bSuccessMax;
    00505
    00506         dfMin = GDALGetRasterMinimum( hBand, &bSuccessMin );
    00507         dfMax = GDALGetRasterMaximum( hBand, &bSuccessMax );
    00508
    00509         if( bSuccessMin && bSuccessMax )
    00510         {
    00511             adfMinMax[0] = dfMin;
    00512             adfMinMax[1] = dfMax;
    00513             return;
    00514         }
    00515     }
    00516
    00517 /* -------------------------------------------------------------------- */
    00518 /*      If we have overview bands, use them for min/max.                */
    00519 /* -------------------------------------------------------------------- */
    00520     if( bApproxOK )
    00521         poBand = (GDALRasterBand *) GDALGetRasterSampleOverview( hBand, 2500 );
    00522     else
    00523         poBand = (GDALRasterBand *) hBand;
    00524
    00525 /* -------------------------------------------------------------------- */
    00526 /*      Figure out the ratio of blocks we will read to get an           */
    00527 /*      approximate value.                                              */
    00528 /* -------------------------------------------------------------------- */
    00529     int         nBlockXSize, nBlockYSize;
    00530     int         nBlocksPerRow, nBlocksPerColumn;
    00531     int         nSampleRate;
    00532     int         bGotNoDataValue, bFirstValue = TRUE;
    00533     double      dfNoDataValue;
    00534
    00535     dfNoDataValue = poBand->GetNoDataValue( &bGotNoDataValue );
    00536
    00537     poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
    00538     nBlocksPerRow = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
    00539     nBlocksPerColumn = (poBand->GetYSize() + nBlockYSize - 1) / nBlockYSize;
    00540
    00541     if( bApproxOK )
    00542         nSampleRate =
    00543             (int) MAX(1,sqrt((double) nBlocksPerRow * nBlocksPerColumn));
    00544     else
    00545         nSampleRate = 1;
    00546
    00547     for( int iSampleBlock = 0;
    00548          iSampleBlock < nBlocksPerRow * nBlocksPerColumn;
    00549          iSampleBlock += nSampleRate )
    00550     {
    00551         double dfValue = 0.0;
    00552         int  iXBlock, iYBlock, nXCheck, nYCheck;
    00553         GDALRasterBlock *poBlock;
    00554
    00555         iYBlock = iSampleBlock / nBlocksPerRow;
    00556         iXBlock = iSampleBlock - nBlocksPerRow * iYBlock;
    00557
    00558         poBlock = poBand->GetBlockRef( iXBlock, iYBlock );
    00559         if( poBlock == NULL )
    00560             continue;
    00561
    00562         if( (iXBlock+1) * nBlockXSize > poBand->GetXSize() )
    00563             nXCheck = poBand->GetXSize() - iXBlock * nBlockXSize;
    00564         else
    00565             nXCheck = nBlockXSize;
    00566
    00567         if( (iYBlock+1) * nBlockYSize > poBand->GetYSize() )
    00568             nYCheck = poBand->GetYSize() - iYBlock * nBlockYSize;
    00569         else
    00570             nYCheck = nBlockYSize;
    00571
    00572         /* this isn't the fastest way to do this, but is easier for now */
    00573         for( int iY = 0; iY < nYCheck; iY++ )
    00574         {
    00575             for( int iX = 0; iX < nXCheck; iX++ )
    00576             {
    00577                 int    iOffset = iX + iY * nBlockXSize;
    00578
    00579                 switch( poBlock->GetDataType() )
    00580                 {
    00581                   case GDT_Byte:
    00582                     dfValue = ((GByte *) poBlock->GetDataRef())[iOffset];
    00583                     break;
    00584                   case GDT_UInt16:
    00585                     dfValue = ((GUInt16 *) poBlock->GetDataRef())[iOffset];
    00586                     break;
    00587                   case GDT_Int16:
    00588                     dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset];
    00589                     break;
    00590                   case GDT_UInt32:
    00591                     dfValue = ((GUInt32 *) poBlock->GetDataRef())[iOffset];
    00592                     break;
    00593                   case GDT_Int32:
    00594                     dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset];
    00595                     break;
    00596                   case GDT_Float32:
    00597                     dfValue = ((float *) poBlock->GetDataRef())[iOffset];
    00598                     break;
    00599                   case GDT_Float64:
    00600                     dfValue = ((double *) poBlock->GetDataRef())[iOffset];
    00601                     break;
    00602                   case GDT_CInt16:
    00603                     dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset*2];
    00604                     break;
    00605                   case GDT_CInt32:
    00606                     dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset*2];
    00607                     break;
    00608                   case GDT_CFloat32:
    00609                     dfValue = ((float *) poBlock->GetDataRef())[iOffset*2];
    00610                     break;
    00611                   case GDT_CFloat64:
    00612                     dfValue = ((double *) poBlock->GetDataRef())[iOffset*2];
    00613                     break;
    00614                   default:
    00615                     CPLAssert( FALSE );
    00616                 }
    00617
    00618                 if( bGotNoDataValue && dfValue == dfNoDataValue )
    00619                     continue;
    00620
    00621                 if( bFirstValue )
    00622                 {
    00623                     dfMin = dfMax = dfValue;
    00624                     bFirstValue = FALSE;
    00625                 }
    00626                 else
    00627                 {
    00628                     dfMin = MIN(dfMin,dfValue);
    00629                     dfMax = MAX(dfMax,dfValue);
    00630                 }
    00631             }
    00632         }
    00633     }
    00634
    00635     adfMinMax[0] = dfMin;
    00636     adfMinMax[1] = dfMax;
    00637 }
    00638
    00639 /************************************************************************/
    00640 /*                         GDALDummyProgress()                          */
    00641 /************************************************************************/
    00642
    00707 int GDALDummyProgress( double, const char *, void * )
    00708
    00709 {
    00710     return TRUE;
    00711 }
    00712
    00713 /************************************************************************/
    00714 /*                         GDALScaledProgress()                         */
    00715 /************************************************************************/
    00716 typedef struct {
    00717     GDALProgressFunc pfnProgress;
    00718     void *pData;
    00719     double dfMin;
    00720     double dfMax;
    00721 } GDALScaledProgressInfo;
    00722
    00723 int GDALScaledProgress( double dfComplete, const char *pszMessage,
    00724                         void *pData )
    00725
    00726 {
    00727     GDALScaledProgressInfo *psInfo = (GDALScaledProgressInfo *) pData;
    00728
    00729     return psInfo->pfnProgress( dfComplete * (psInfo->dfMax - psInfo->dfMin)
    00730                                 + psInfo->dfMin,
    00731                                 pszMessage, psInfo->pData );
    00732 }
    00733
    00734 /************************************************************************/
    00735 /*                      GDALCreateScaledProgress()                      */
    00736 /************************************************************************/
    00737
    00738 void *GDALCreateScaledProgress( double dfMin, double dfMax,
    00739                                 GDALProgressFunc pfnProgress,
    00740                                 void * pData )
    00741
    00742 {
    00743     GDALScaledProgressInfo *psInfo;
    00744
    00745     psInfo = (GDALScaledProgressInfo *)
    00746         CPLCalloc(sizeof(GDALScaledProgressInfo),1);
    00747
    00748     if( ABS(dfMin-dfMax) < 0.0000001 )
    00749         dfMax = dfMin + 0.01;
    00750
    00751     psInfo->pData = pData;
    00752     psInfo->pfnProgress = pfnProgress;
    00753     psInfo->dfMin = dfMin;
    00754     psInfo->dfMax = dfMax;
    00755
    00756     return (void *) psInfo;
    00757 }
    00758
    00759 /************************************************************************/
    00760 /*                     GDALDestroyScaledProgress()                      */
    00761 /************************************************************************/
    00762
    00763 void GDALDestroyScaledProgress( void * pData )
    00764
    00765 {
    00766     CPLFree( pData );
    00767 }
    00768
    00769 /************************************************************************/
    00770 /*                          GDALTermProgress()                          */
    00771 /************************************************************************/
    00772
    00773 int GDALTermProgress( double dfComplete, const char *pszMessage, void * )
    00774
    00775 {
    00776     static double dfLastComplete = -1.0;
    00777
    00778     if( dfLastComplete > dfComplete )
    00779     {
    00780         if( dfLastComplete > 1.0 )
    00781             dfLastComplete = -1.0;
    00782         else
    00783             dfLastComplete = dfComplete;
    00784     }
    00785
    00786     if( floor(dfLastComplete*10) != floor(dfComplete*10) )
    00787     {
    00788         int    nPercent = (int) floor(dfComplete*100);
    00789
    00790         if( nPercent == 0 && pszMessage != NULL )
    00791             fprintf( stdout, "%s:", pszMessage );
    00792
    00793         if( nPercent == 100 )
    00794             fprintf( stdout, "%d - done.\n", (int) floor(dfComplete*100) );
    00795         else
    00796         {
    00797             fprintf( stdout, "%d.", (int) floor(dfComplete*100) );
    00798             fflush( stdout );
    00799         }
    00800     }
    00801     else if( floor(dfLastComplete*30) != floor(dfComplete*30) )
    00802     {
    00803         fprintf( stdout, "." );
    00804         fflush( stdout );
    00805     }
    00806
    00807     dfLastComplete = dfComplete;
    00808
    00809     return TRUE;
    00810 }
    00811
    00812 /************************************************************************/
    00813 /*                    GDALGetRasterSampleOverview()                     */
    00814 /************************************************************************/
    00815
    00831 GDALRasterBandH GDALGetRasterSampleOverview( GDALRasterBandH hBand,
    00832                                              int nDesiredSamples )
    00833
    00834 {
    00835     int     nBestSamples;
    00836     GDALRasterBandH hBestBand = hBand;
    00837
    00838     nBestSamples = GDALGetRasterBandXSize(hBand)
    00839         * GDALGetRasterBandYSize(hBand);
    00840
    00841     for( int iOverview = 0;
    00842          iOverview < GDALGetOverviewCount( hBand );
    00843          iOverview++ )
    00844     {
    00845         GDALRasterBandH hOBand = GDALGetOverview( hBand, iOverview );
    00846         int    nOSamples;
    00847
    00848         nOSamples = GDALGetRasterBandXSize(hOBand)
    00849             * GDALGetRasterBandYSize(hOBand);
    00850
    00851         if( nOSamples < nBestSamples && nOSamples > nDesiredSamples )
    00852         {
    00853             nBestSamples = nOSamples;
    00854             hBestBand = hOBand;
    00855         }
    00856     }
    00857
    00858     return hBestBand;
    00859 }
    00860
    00861 /************************************************************************/
    00862 /*                     GDALGetRandomRasterSample()                      */
    00863 /************************************************************************/
    00864
    00865 int GDALGetRandomRasterSample( GDALRasterBandH hBand, int nSamples,
    00866                                float *pafSampleBuf )
    00867
    00868 {
    00869     GDALRasterBand *poBand;
    00870
    00871     poBand = (GDALRasterBand *) GDALGetRasterSampleOverview( hBand, nSamples );
    00872
    00873 /* -------------------------------------------------------------------- */
    00874 /*      Figure out the ratio of blocks we will read to get an           */
    00875 /*      approximate value.                                              */
    00876 /* -------------------------------------------------------------------- */
    00877     int         nBlockXSize, nBlockYSize;
    00878     int         nBlocksPerRow, nBlocksPerColumn;
    00879     int         nSampleRate;
    00880     int         bGotNoDataValue;
    00881     double      dfNoDataValue;
    00882     int         nActualSamples = 0;
    00883     int         nBlockSampleRate;
    00884     int         nBlockPixels, nBlockCount;
    00885
    00886     dfNoDataValue = poBand->GetNoDataValue( &bGotNoDataValue );
    00887
    00888     poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
    00889
    00890     nBlocksPerRow = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
    00891     nBlocksPerColumn = (poBand->GetYSize() + nBlockYSize - 1) / nBlockYSize;
    00892
    00893     nBlockPixels = nBlockXSize * nBlockYSize;
    00894     nBlockCount = nBlocksPerRow * nBlocksPerColumn;
    00895
    00896     nSampleRate = (int) MAX(1,sqrt((double) nBlockCount)-2.0);
    00897
    00898     if( nSampleRate == nBlocksPerRow && nSampleRate > 1 )
    00899         nSampleRate--;
    00900
    00901     while( nSampleRate > 1
    00902            && ((nBlockCount-1) / nSampleRate + 1) * nBlockPixels < nSamples )
    00903         nSampleRate--;
    00904
    00905     nBlockSampleRate =
    00906         MAX(1,nBlockPixels / (nSamples / ((nBlockCount-1) / nSampleRate + 1)));
    00907
    00908     for( int iSampleBlock = 0;
    00909          iSampleBlock < nBlockCount;
    00910          iSampleBlock += nSampleRate )
    00911     {
    00912         double dfValue = 0.0, dfReal, dfImag;
    00913         int  iXBlock, iYBlock, iX, iY, iXValid, iYValid, iRemainder = 0;
    00914         GDALRasterBlock *poBlock;
    00915
    00916         iYBlock = iSampleBlock / nBlocksPerRow;
    00917         iXBlock = iSampleBlock - nBlocksPerRow * iYBlock;
    00918
    00919         poBlock = poBand->GetBlockRef( iXBlock, iYBlock );
    00920         if( poBlock == NULL )
    00921             continue;
    00922
    00923         if( iXBlock * nBlockXSize > poBand->GetXSize() )
    00924             iXValid = poBand->GetXSize() - iXBlock * nBlockXSize;
    00925         else
    00926             iXValid = nBlockXSize;
    00927
    00928         if( iYBlock * nBlockYSize > poBand->GetYSize() )
    00929             iYValid = poBand->GetYSize() - iYBlock * nBlockYSize;
    00930         else
    00931             iYValid = nBlockYSize;
    00932
    00933         for( iY = 0; iY < iYValid; iY++ )
    00934         {
    00935             for( iX = iRemainder; iX < iXValid; iX += nBlockSampleRate )
    00936             {
    00937                 int     iOffset;
    00938
    00939                 iOffset = iX + iY * nBlockXSize;
    00940                 switch( poBlock->GetDataType() )
    00941                 {
    00942                   case GDT_Byte:
    00943                     dfValue = ((GByte *) poBlock->GetDataRef())[iOffset];
    00944                     break;
    00945                   case GDT_UInt16:
    00946                     dfValue = ((GUInt16 *) poBlock->GetDataRef())[iOffset];
    00947                     break;
    00948                   case GDT_Int16:
    00949                     dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset];
    00950                     break;
    00951                   case GDT_UInt32:
    00952                     dfValue = ((GUInt32 *) poBlock->GetDataRef())[iOffset];
    00953                     break;
    00954                   case GDT_Int32:
    00955                     dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset];
    00956                     break;
    00957                   case GDT_Float32:
    00958                     dfValue = ((float *) poBlock->GetDataRef())[iOffset];
    00959                     break;
    00960                   case GDT_Float64:
    00961                     dfValue = ((double *) poBlock->GetDataRef())[iOffset];
    00962                     break;
    00963                   case GDT_CInt16:
    00964                     dfReal = ((GInt16 *) poBlock->GetDataRef())[iOffset*2];
    00965                     dfImag = ((GInt16 *) poBlock->GetDataRef())[iOffset*2+1];
    00966                     dfValue = sqrt(dfReal*dfReal + dfImag*dfImag);
    00967                     break;
    00968                   case GDT_CInt32:
    00969                     dfReal = ((GInt32 *) poBlock->GetDataRef())[iOffset*2];
    00970                     dfImag = ((GInt32 *) poBlock->GetDataRef())[iOffset*2+1];
    00971                     dfValue = sqrt(dfReal*dfReal + dfImag*dfImag);
    00972                     break;
    00973                   case GDT_CFloat32:
    00974                     dfReal = ((float *) poBlock->GetDataRef())[iOffset*2];
    00975                     dfImag = ((float *) poBlock->GetDataRef())[iOffset*2+1];
    00976                     dfValue = sqrt(dfReal*dfReal + dfImag*dfImag);
    00977                     break;
    00978                   case GDT_CFloat64:
    00979                     dfReal = ((double *) poBlock->GetDataRef())[iOffset*2];
    00980                     dfImag = ((double *) poBlock->GetDataRef())[iOffset*2+1];
    00981                     dfValue = sqrt(dfReal*dfReal + dfImag*dfImag);
    00982                     break;
    00983                   default:
    00984                     CPLAssert( FALSE );
    00985                 }
    00986
    00987                 if( bGotNoDataValue && dfValue == dfNoDataValue )
    00988                     continue;
    00989
    00990                 if( nActualSamples < nSamples )
    00991                     pafSampleBuf[nActualSamples++] = dfValue;
    00992             }
    00993
    00994             iRemainder = iX - iXValid;
    00995         }
    00996     }
    00997
    00998     return nActualSamples;
    00999 }
    01000
    01001 /************************************************************************/
    01002 /*                            GDALInitGCPs()                            */
    01003 /************************************************************************/
    01004
    01005 void GDALInitGCPs( int nCount, GDAL_GCP * psGCP )
    01006
    01007 {
    01008     for( int iGCP = 0; iGCP < nCount; iGCP++ )
    01009     {
    01010         memset( psGCP, 0, sizeof(GDAL_GCP) );
    01011         psGCP->pszId = CPLStrdup("");
    01012         psGCP->pszInfo = CPLStrdup("");
    01013         psGCP++;
    01014     }
    01015 }
    01016
    01017 /************************************************************************/
    01018 /*                           GDALDeinitGCPs()                           */
    01019 /************************************************************************/
    01020
    01021 void GDALDeinitGCPs( int nCount, GDAL_GCP * psGCP )
    01022
    01023 {
    01024     for( int iGCP = 0; iGCP < nCount; iGCP++ )
    01025     {
    01026         CPLFree( psGCP->pszId );
    01027         CPLFree( psGCP->pszInfo );
    01028         psGCP++;
    01029     }
    01030 }
    01031
    01032 /************************************************************************/
    01033 /*                         GDALDuplicateGCPs()                          */
    01034 /************************************************************************/
    01035
    01036 GDAL_GCP *GDALDuplicateGCPs( int nCount, const GDAL_GCP *pasGCPList )
    01037
    01038 {
    01039     GDAL_GCP    *pasReturn;
    01040
    01041     pasReturn = (GDAL_GCP *) CPLMalloc(sizeof(GDAL_GCP) * nCount);
    01042     GDALInitGCPs( nCount, pasReturn );
    01043
    01044     for( int iGCP = 0; iGCP < nCount; iGCP++ )
    01045     {
    01046         CPLFree( pasReturn[iGCP].pszId );
    01047         pasReturn[iGCP].pszId = CPLStrdup( pasGCPList[iGCP].pszId );
    01048
    01049         CPLFree( pasReturn[iGCP].pszInfo );
    01050         pasReturn[iGCP].pszInfo = CPLStrdup( pasGCPList[iGCP].pszInfo );
    01051
    01052         pasReturn[iGCP].dfGCPPixel = pasGCPList[iGCP].dfGCPPixel;
    01053         pasReturn[iGCP].dfGCPLine = pasGCPList[iGCP].dfGCPLine;
    01054         pasReturn[iGCP].dfGCPX = pasGCPList[iGCP].dfGCPX;
    01055         pasReturn[iGCP].dfGCPY = pasGCPList[iGCP].dfGCPY;
    01056         pasReturn[iGCP].dfGCPZ = pasGCPList[iGCP].dfGCPZ;
    01057     }
    01058
    01059     return pasReturn;
    01060 }
    01061
    01062 /************************************************************************/
    01063 /*                         GDALReadWorldFile()                          */
    01064 /*                                                                      */
    01065 /*      Helper function for translator implementators wanting           */
    01066 /*      support for ESRI world files.                                   */
    01067 /************************************************************************/
    01068
    01069 int GDALReadWorldFile( const char * pszBaseFilename, const char *pszExtension,
    01070                        double *padfGeoTransform )
    01071
    01072 {
    01073     const char  *pszTFW;
    01074     char        szExtUpper[32], szExtLower[32];
    01075     int         i;
    01076     FILE        *fpTFW;
    01077     char        **papszLines;
    01078
    01079     if( *pszExtension == '.' )
    01080         pszExtension++;
    01081
    01082 /* -------------------------------------------------------------------- */
    01083 /*      Generate upper and lower case versions of the extension.        */
    01084 /* -------------------------------------------------------------------- */
    01085     strcpy( szExtUpper, pszExtension );
    01086     strcpy( szExtLower, pszExtension );
    01087
    01088     for( i = 0; szExtUpper[i] != '\0'; i++ )
    01089     {
    01090         if( szExtUpper[i] >= 'a' && szExtUpper[i] <= 'z' )
    01091             szExtUpper[i] = szExtUpper[i] - 'a' + 'A';
    01092         if( szExtLower[i] >= 'A' && szExtLower[i] <= 'Z' )
    01093             szExtLower[i] = szExtLower[i] - 'A' + 'a';
    01094     }
    01095
    01096 /* -------------------------------------------------------------------- */
    01097 /*      Try lower case, then upper case.                                */
    01098 /* -------------------------------------------------------------------- */
    01099     pszTFW = CPLResetExtension( pszBaseFilename, szExtLower );
    01100
    01101     fpTFW = VSIFOpen( pszTFW, "rt" );
    01102
    01103 #ifndef WIN32
    01104     if( fpTFW == NULL )
    01105     {
    01106         pszTFW = CPLResetExtension( pszBaseFilename, szExtUpper );
    01107         fpTFW = VSIFOpen( pszTFW, "rt" );
    01108     }
    01109 #endif
    01110
    01111     if( fpTFW == NULL )
    01112         return FALSE;
    01113
    01114     VSIFClose( fpTFW );
    01115
    01116 /* -------------------------------------------------------------------- */
    01117 /*      We found the file, now load and parse it.                       */
    01118 /* -------------------------------------------------------------------- */
    01119     papszLines = CSLLoad( pszTFW );
    01120     if( CSLCount(papszLines) >= 6
    01121         && atof(papszLines[0]) != 0.0
    01122         && atof(papszLines[3]) != 0.0 )
    01123     {
    01124         padfGeoTransform[0] = atof(papszLines[4]);
    01125         padfGeoTransform[1] = atof(papszLines[0]);
    01126         padfGeoTransform[2] = atof(papszLines[2]);
    01127         padfGeoTransform[3] = atof(papszLines[5]);
    01128         padfGeoTransform[4] = atof(papszLines[1]);
    01129         padfGeoTransform[5] = atof(papszLines[3]);
    01130
    01131         // correct for center of pixel vs. top left of pixel
    01132         padfGeoTransform[0] -= 0.5 * padfGeoTransform[1];
    01133         padfGeoTransform[0] -= 0.5 * padfGeoTransform[2];
    01134         padfGeoTransform[3] -= 0.5 * padfGeoTransform[4];
    01135         padfGeoTransform[3] -= 0.5 * padfGeoTransform[5];
    01136
    01137         CSLDestroy(papszLines);
    01138
    01139         return TRUE;
    01140     }
    01141     else
    01142     {
    01143         CPLDebug( "GDAL",
    01144                   "GDALReadWorldFile(%s) found file, but it was corrupt.",
    01145                   pszTFW );
    01146         CSLDestroy(papszLines);
    01147         return FALSE;
    01148     }
    01149 }
    01150
    01151 /************************************************************************/
    01152 /*                            GDALDecToDMS()                            */
    01153 /*                                                                      */
    01154 /*      Translate a decimal degrees value to a DMS string with          */
    01155 /*      hemisphere.                                                     */
    01156 /************************************************************************/
    01157
    01158 const char *GDALDecToDMS( double dfAngle, const char * pszAxis,
    01159                           int nPrecision )
    01160
    01161 {
    01162     int         nDegrees, nMinutes;
    01163     double      dfSeconds;
    01164     char        szFormat[30];
    01165     static char szBuffer[50];
    01166     const char  *pszHemisphere;
    01167
    01168
    01169     nDegrees = (int) ABS(dfAngle);
    01170     nMinutes = (int) ((ABS(dfAngle) - nDegrees) * 60);
    01171     dfSeconds = (ABS(dfAngle) * 3600 - nDegrees*3600 - nMinutes*60);
    01172
    01173     if( EQUAL(pszAxis,"Long") && dfAngle < 0.0 )
    01174         pszHemisphere = "W";
    01175     else if( EQUAL(pszAxis,"Long") )
    01176         pszHemisphere = "E";
    01177     else if( dfAngle < 0.0 )
    01178         pszHemisphere = "S";
    01179     else
    01180         pszHemisphere = "N";
    01181
    01182     sprintf( szFormat, "%%3dd%%2d\'%%.%df\"%s", nPrecision, pszHemisphere );
    01183     sprintf( szBuffer, szFormat, nDegrees, nMinutes, dfSeconds );
    01184
    01185     return( szBuffer );
    01186 }
    01187
    01188 /************************************************************************/
    01189 /* -------------------------------------------------------------------- */
    01190 /*      The following stubs are present to ensure that older GDAL       */
    01191 /*      bridges don't fail with newer libraries.                        */
    01192 /* -------------------------------------------------------------------- */
    01193 /************************************************************************/
    01194
    01195 CPL_C_START
    01196
    01197 void *GDALCreateProjDef( const char * pszDef )
    01198 {
    01199     CPLDebug( "GDAL", "GDALCreateProjDef no longer supported." );
    01200     return NULL;
    01201 }
    01202
    01203 CPLErr GDALReprojectToLongLat( void *pDef, double *, double * )
    01204 {
    01205     CPLDebug( "GDAL", "GDALReprojectToLatLong no longer supported." );
    01206     return CE_Failure;
    01207 }
    01208
    01209 CPLErr GDALReprojectFromLongLat( void *pDef, double *, double * )
    01210 {
    01211     CPLDebug( "GDAL", "GDALReprojectFromLatLong no longer supported." );
    01212     return CE_Failure;
    01213 }
    01214
    01215 void GDALDestroyProjDef( void *pDef )
    01216
    01217 {
    01218     CPLDebug( "GDAL", "GDALDestroyProjDef no longer supported." );
    01219 }
    01220
    01221 CPL_C_END