LCOV - code coverage report
Current view: directory - gcore - gdal_misc.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 1033 636 61.6 %
Date: 2012-12-26 Functions: 46 36 78.3 %

       1                 : /******************************************************************************
       2                 :  * $Id: gdal_misc.cpp 25340 2012-12-21 20:30:21Z rouault $
       3                 :  *
       4                 :  * Project:  GDAL Core
       5                 :  * Purpose:  Free standing functions for GDAL.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1999, Frank Warmerdam
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "gdal_priv.h"
      31                 : #include "cpl_string.h"
      32                 : #include "cpl_minixml.h"
      33                 : #include "cpl_multiproc.h"
      34                 : #include <ctype.h>
      35                 : #include <string>
      36                 : 
      37                 : CPL_CVSID("$Id: gdal_misc.cpp 25340 2012-12-21 20:30:21Z rouault $");
      38                 : 
      39                 : #include "ogr_spatialref.h"
      40                 : 
      41                 : /************************************************************************/
      42                 : /*                           __pure_virtual()                           */
      43                 : /*                                                                      */
      44                 : /*      The following is a gross hack to remove the last remaining      */
      45                 : /*      dependency on the GNU C++ standard library.                     */
      46                 : /************************************************************************/
      47                 : 
      48                 : #ifdef __GNUC__
      49                 : 
      50                 : extern "C"
      51               0 : void __pure_virtual()
      52                 : 
      53                 : {
      54               0 : }
      55                 : 
      56                 : #endif
      57                 : 
      58                 : /************************************************************************/
      59                 : /*                         GDALDataTypeUnion()                          */
      60                 : /************************************************************************/
      61                 : 
      62                 : /**
      63                 :  * \brief Return the smallest data type that can fully express both input data
      64                 :  * types.
      65                 :  *
      66                 :  * @param eType1 first data type.
      67                 :  * @param eType2 second data type.
      68                 :  *
      69                 :  * @return a data type able to express eType1 and eType2.
      70                 :  */
      71                 : 
      72                 : GDALDataType CPL_STDCALL 
      73             740 : GDALDataTypeUnion( GDALDataType eType1, GDALDataType eType2 )
      74                 : 
      75                 : {
      76                 :     int         bFloating, bComplex, nBits, bSigned;
      77                 : 
      78             740 :     bComplex = GDALDataTypeIsComplex(eType1) | GDALDataTypeIsComplex(eType2);
      79                 :     
      80             740 :     switch( eType1 )
      81                 :     {
      82                 :       case GDT_Byte:
      83             513 :         nBits = 8;
      84             513 :         bSigned = FALSE;
      85             513 :         bFloating = FALSE;
      86             513 :         break;
      87                 :         
      88                 :       case GDT_Int16:
      89                 :       case GDT_CInt16:
      90               0 :         nBits = 16;
      91               0 :         bSigned = TRUE;
      92               0 :         bFloating = FALSE;
      93               0 :         break;
      94                 :         
      95                 :       case GDT_UInt16:
      96               0 :         nBits = 16;
      97               0 :         bSigned = FALSE;
      98               0 :         bFloating = FALSE;
      99               0 :         break;
     100                 :         
     101                 :       case GDT_Int32:
     102                 :       case GDT_CInt32:
     103               7 :         nBits = 32;
     104               7 :         bSigned = TRUE;
     105               7 :         bFloating = FALSE;
     106               7 :         break;
     107                 :         
     108                 :       case GDT_UInt32:
     109               0 :         nBits = 32;
     110               0 :         bSigned = FALSE;
     111               0 :         bFloating = FALSE;
     112               0 :         break;
     113                 : 
     114                 :       case GDT_Float32:
     115                 :       case GDT_CFloat32:
     116             220 :         nBits = 32;
     117             220 :         bSigned = TRUE;
     118             220 :         bFloating = TRUE;
     119             220 :         break;
     120                 : 
     121                 :       case GDT_Float64:
     122                 :       case GDT_CFloat64:
     123               0 :         nBits = 64;
     124               0 :         bSigned = TRUE;
     125               0 :         bFloating = TRUE;
     126               0 :         break;
     127                 : 
     128                 :       default:
     129               0 :         CPLAssert( FALSE );
     130               0 :         return GDT_Unknown;
     131                 :     }
     132                 : 
     133             740 :     switch( eType2 )
     134                 :     {
     135                 :       case GDT_Byte:
     136             248 :         break;
     137                 :         
     138                 :       case GDT_Int16:
     139                 :       case GDT_CInt16:
     140              66 :         nBits = MAX(nBits,16);
     141              66 :         bSigned = TRUE;
     142              66 :         break;
     143                 :         
     144                 :       case GDT_UInt16:
     145              26 :         nBits = MAX(nBits,16);
     146              26 :         break;
     147                 :         
     148                 :       case GDT_Int32:
     149                 :       case GDT_CInt32:
     150             276 :         nBits = MAX(nBits,32);
     151             276 :         bSigned = TRUE;
     152             276 :         break;
     153                 :         
     154                 :       case GDT_UInt32:
     155              25 :         nBits = MAX(nBits,32);
     156              25 :         break;
     157                 : 
     158                 :       case GDT_Float32:
     159                 :       case GDT_CFloat32:
     160              49 :         nBits = MAX(nBits,32);
     161              49 :         bSigned = TRUE;
     162              49 :         bFloating = TRUE;
     163              49 :         break;
     164                 : 
     165                 :       case GDT_Float64:
     166                 :       case GDT_CFloat64:
     167              50 :         nBits = MAX(nBits,64);
     168              50 :         bSigned = TRUE;
     169              50 :         bFloating = TRUE;
     170              50 :         break;
     171                 : 
     172                 :       default:
     173               0 :         CPLAssert( FALSE );
     174               0 :         return GDT_Unknown;
     175                 :     }
     176                 : 
     177             740 :     if( nBits == 8 )
     178             248 :         return GDT_Byte;
     179             492 :     else if( nBits == 16 && bComplex )
     180              22 :         return GDT_CInt16;
     181             470 :     else if( nBits == 16 && bSigned )
     182              44 :         return GDT_Int16;
     183             426 :     else if( nBits == 16 && !bSigned )
     184              26 :         return GDT_UInt16;
     185             400 :     else if( nBits == 32 && bFloating && bComplex )
     186              24 :         return GDT_CFloat32;
     187             376 :     else if( nBits == 32 && bFloating )
     188             245 :         return GDT_Float32;
     189             131 :     else if( nBits == 32 && bComplex )
     190              22 :         return GDT_CInt32;
     191             109 :     else if( nBits == 32 && bSigned )
     192              34 :         return GDT_Int32;
     193              75 :     else if( nBits == 32 && !bSigned )
     194              25 :         return GDT_UInt32;
     195              50 :     else if( nBits == 64 && bComplex )
     196              24 :         return GDT_CFloat64;
     197                 :     else
     198              26 :         return GDT_Float64;
     199                 : }
     200                 : 
     201                 : 
     202                 : /************************************************************************/
     203                 : /*                        GDALGetDataTypeSize()                         */
     204                 : /************************************************************************/
     205                 : 
     206                 : /**
     207                 :  * \brief Get data type size in bits.
     208                 :  *
     209                 :  * Returns the size of a a GDT_* type in bits, <b>not bytes</b>!
     210                 :  *
     211                 :  * @param eDataType type, such as GDT_Byte.
     212                 :  * @return the number of bits or zero if it is not recognised.
     213                 :  */
     214                 : 
     215         8975314 : int CPL_STDCALL GDALGetDataTypeSize( GDALDataType eDataType )
     216                 : 
     217                 : {
     218         8975314 :     switch( eDataType )
     219                 :     {
     220                 :       case GDT_Byte:
     221         5538994 :         return 8;
     222                 : 
     223                 :       case GDT_UInt16:
     224                 :       case GDT_Int16:
     225         1486909 :         return 16;
     226                 : 
     227                 :       case GDT_UInt32:
     228                 :       case GDT_Int32:
     229                 :       case GDT_Float32:
     230                 :       case GDT_CInt16:
     231         1731482 :         return 32;
     232                 : 
     233                 :       case GDT_Float64:
     234                 :       case GDT_CInt32:
     235                 :       case GDT_CFloat32:
     236           46054 :         return 64;
     237                 : 
     238                 :       case GDT_CFloat64:
     239          171875 :         return 128;
     240                 : 
     241                 :       default:
     242               0 :         return 0;
     243                 :     }
     244                 : }
     245                 : 
     246                 : /************************************************************************/
     247                 : /*                       GDALDataTypeIsComplex()                        */
     248                 : /************************************************************************/
     249                 : 
     250                 : /**
     251                 :  * \brief Is data type complex? 
     252                 :  *
     253                 :  * @return TRUE if the passed type is complex (one of GDT_CInt16, GDT_CInt32, 
     254                 :  * GDT_CFloat32 or GDT_CFloat64), that is it consists of a real and imaginary
     255                 :  * component. 
     256                 :  */
     257                 : 
     258          288535 : int CPL_STDCALL GDALDataTypeIsComplex( GDALDataType eDataType )
     259                 : 
     260                 : {
     261          288535 :     switch( eDataType )
     262                 :     {
     263                 :       case GDT_CInt16:
     264                 :       case GDT_CInt32:
     265                 :       case GDT_CFloat32:
     266                 :       case GDT_CFloat64:
     267             584 :         return TRUE;
     268                 : 
     269                 :       default:
     270          287951 :         return FALSE;
     271                 :     }
     272                 : }
     273                 : 
     274                 : /************************************************************************/
     275                 : /*                        GDALGetDataTypeName()                         */
     276                 : /************************************************************************/
     277                 : 
     278                 : /**
     279                 :  * \brief Get name of data type.
     280                 :  *
     281                 :  * Returns a symbolic name for the data type.  This is essentially the
     282                 :  * the enumerated item name with the GDT_ prefix removed.  So GDT_Byte returns
     283                 :  * "Byte".  The returned strings are static strings and should not be modified
     284                 :  * or freed by the application.  These strings are useful for reporting
     285                 :  * datatypes in debug statements, errors and other user output. 
     286                 :  *
     287                 :  * @param eDataType type to get name of.
     288                 :  * @return string corresponding to existing data type
     289                 :  *         or NULL pointer if invalid type given.
     290                 :  */
     291                 : 
     292           19352 : const char * CPL_STDCALL GDALGetDataTypeName( GDALDataType eDataType )
     293                 : 
     294                 : {
     295           19352 :     switch( eDataType )
     296                 :     {
     297                 :       case GDT_Unknown:
     298             238 :         return "Unknown";
     299                 : 
     300                 :       case GDT_Byte:
     301           10404 :         return "Byte";
     302                 : 
     303                 :       case GDT_UInt16:
     304            1117 :         return "UInt16";
     305                 : 
     306                 :       case GDT_Int16:
     307            1063 :         return "Int16";
     308                 : 
     309                 :       case GDT_UInt32:
     310             949 :         return "UInt32";
     311                 :         
     312                 :       case GDT_Int32:
     313             924 :         return "Int32";
     314                 :         
     315                 :       case GDT_Float32:
     316            1007 :         return "Float32";
     317                 : 
     318                 :       case GDT_Float64:
     319             788 :         return "Float64";
     320                 : 
     321                 :       case GDT_CInt16:
     322             731 :         return "CInt16";
     323                 : 
     324                 :       case GDT_CInt32:
     325             715 :         return "CInt32";
     326                 : 
     327                 :       case GDT_CFloat32:
     328             715 :         return "CFloat32";
     329                 : 
     330                 :       case GDT_CFloat64:
     331             701 :         return "CFloat64";
     332                 : 
     333                 :       default:
     334               0 :         return NULL;
     335                 :     }
     336                 : }
     337                 : 
     338                 : /************************************************************************/
     339                 : /*                        GDALGetDataTypeByName()                       */
     340                 : /************************************************************************/
     341                 : 
     342                 : /**
     343                 :  * \brief Get data type by symbolic name.
     344                 :  *
     345                 :  * Returns a data type corresponding to the given symbolic name. This
     346                 :  * function is opposite to the GDALGetDataTypeName().
     347                 :  *
     348                 :  * @param pszName string containing the symbolic name of the type.
     349                 :  * 
     350                 :  * @return GDAL data type.
     351                 :  */
     352                 : 
     353             647 : GDALDataType CPL_STDCALL GDALGetDataTypeByName( const char *pszName )
     354                 : 
     355                 : {
     356             647 :     VALIDATE_POINTER1( pszName, "GDALGetDataTypeByName", GDT_Unknown );
     357                 : 
     358                 :     int iType;
     359                 :     
     360            1321 :     for( iType = 1; iType < GDT_TypeCount; iType++ )
     361                 :     {
     362            1320 :         if( GDALGetDataTypeName((GDALDataType)iType) != NULL
     363                 :             && EQUAL(GDALGetDataTypeName((GDALDataType)iType), pszName) )
     364                 :         {
     365             646 :             return (GDALDataType)iType;
     366                 :         }
     367                 :     }
     368                 : 
     369               1 :     return GDT_Unknown;
     370                 : }
     371                 : 
     372                 : /************************************************************************/
     373                 : /*                        GDALGetAsyncStatusTypeByName()                */
     374                 : /************************************************************************/
     375                 : /**
     376                 :  * Get AsyncStatusType by symbolic name.
     377                 :  *
     378                 :  * Returns a data type corresponding to the given symbolic name. This
     379                 :  * function is opposite to the GDALGetAsyncStatusTypeName().
     380                 :  *
     381                 :  * @param pszName string containing the symbolic name of the type.
     382                 :  * 
     383                 :  * @return GDAL AsyncStatus type.
     384                 :  */
     385               0 : GDALAsyncStatusType CPL_DLL CPL_STDCALL GDALGetAsyncStatusTypeByName( const char *pszName )
     386                 : {
     387               0 :     VALIDATE_POINTER1( pszName, "GDALGetAsyncStatusTypeByName", GARIO_ERROR);
     388                 : 
     389                 :     int iType;
     390                 : 
     391               0 :     for( iType = 1; iType < GARIO_TypeCount; iType++ )
     392                 :     {
     393               0 :         if( GDALGetAsyncStatusTypeName((GDALAsyncStatusType)iType) != NULL
     394                 :             && EQUAL(GDALGetAsyncStatusTypeName((GDALAsyncStatusType)iType), pszName) )
     395                 :         {
     396               0 :             return (GDALAsyncStatusType)iType;
     397                 :         }
     398                 :     }
     399                 : 
     400               0 :     return GARIO_ERROR;
     401                 : }
     402                 : 
     403                 : 
     404                 : /************************************************************************/
     405                 : /*                        GDALGetAsyncStatusTypeName()                 */
     406                 : /************************************************************************/
     407                 : 
     408                 : /**
     409                 :  * Get name of AsyncStatus data type.
     410                 :  *
     411                 :  * Returns a symbolic name for the AsyncStatus data type.  This is essentially the
     412                 :  * the enumerated item name with the GARIO_ prefix removed.  So GARIO_COMPLETE returns
     413                 :  * "COMPLETE".  The returned strings are static strings and should not be modified
     414                 :  * or freed by the application.  These strings are useful for reporting
     415                 :  * datatypes in debug statements, errors and other user output. 
     416                 :  *
     417                 :  * @param eAsyncStatusType type to get name of.
     418                 :  * @return string corresponding to type.
     419                 :  */
     420                 : 
     421               0 :  const char * CPL_STDCALL GDALGetAsyncStatusTypeName( GDALAsyncStatusType eAsyncStatusType )
     422                 : 
     423                 : {
     424               0 :     switch( eAsyncStatusType )
     425                 :     {
     426                 :       case GARIO_PENDING:
     427               0 :         return "PENDING";
     428                 : 
     429                 :       case GARIO_UPDATE:
     430               0 :         return "UPDATE";
     431                 : 
     432                 :       case GARIO_ERROR:
     433               0 :         return "ERROR";
     434                 : 
     435                 :       case GARIO_COMPLETE:
     436               0 :         return "COMPLETE";
     437                 :       default:
     438               0 :         return NULL;
     439                 :     }
     440                 : }
     441                 : 
     442                 : /************************************************************************/
     443                 : /*                  GDALGetPaletteInterpretationName()                  */
     444                 : /************************************************************************/
     445                 : 
     446                 : /**
     447                 :  * \brief Get name of palette interpretation
     448                 :  *
     449                 :  * Returns a symbolic name for the palette interpretation.  This is the
     450                 :  * the enumerated item name with the GPI_ prefix removed.  So GPI_Gray returns
     451                 :  * "Gray".  The returned strings are static strings and should not be modified
     452                 :  * or freed by the application.
     453                 :  *
     454                 :  * @param eInterp palette interpretation to get name of.
     455                 :  * @return string corresponding to palette interpretation.
     456                 :  */
     457                 : 
     458               4 : const char *GDALGetPaletteInterpretationName( GDALPaletteInterp eInterp )
     459                 : 
     460                 : {
     461               4 :     switch( eInterp )
     462                 :     {
     463                 :       case GPI_Gray:
     464               0 :         return "Gray";
     465                 : 
     466                 :       case GPI_RGB:
     467               4 :         return "RGB";
     468                 :         
     469                 :       case GPI_CMYK:
     470               0 :         return "CMYK";
     471                 : 
     472                 :       case GPI_HLS:
     473               0 :         return "HLS";
     474                 :         
     475                 :       default:
     476               0 :         return "Unknown";
     477                 :     }
     478                 : }
     479                 : 
     480                 : /************************************************************************/
     481                 : /*                   GDALGetColorInterpretationName()                   */
     482                 : /************************************************************************/
     483                 : 
     484                 : /**
     485                 :  * \brief Get name of color interpretation
     486                 :  *
     487                 :  * Returns a symbolic name for the color interpretation.  This is derived from
     488                 :  * the enumerated item name with the GCI_ prefix removed, but there are some
     489                 :  * variations. So GCI_GrayIndex returns "Gray" and GCI_RedBand returns "Red".
     490                 :  * The returned strings are static strings and should not be modified
     491                 :  * or freed by the application.
     492                 :  *
     493                 :  * @param eInterp color interpretation to get name of.
     494                 :  * @return string corresponding to color interpretation
     495                 :  *         or NULL pointer if invalid enumerator given.
     496                 :  */
     497                 : 
     498            2098 : const char *GDALGetColorInterpretationName( GDALColorInterp eInterp )
     499                 : 
     500                 : {
     501            2098 :     switch( eInterp )
     502                 :     {
     503                 :       case GCI_Undefined:
     504             526 :         return "Undefined";
     505                 : 
     506                 :       case GCI_GrayIndex:
     507             883 :         return "Gray";
     508                 : 
     509                 :       case GCI_PaletteIndex:
     510             162 :         return "Palette";
     511                 : 
     512                 :       case GCI_RedBand:
     513             189 :         return "Red";
     514                 : 
     515                 :       case GCI_GreenBand:
     516             143 :         return "Green";
     517                 : 
     518                 :       case GCI_BlueBand:
     519             103 :         return "Blue";
     520                 : 
     521                 :       case GCI_AlphaBand:
     522              35 :         return "Alpha";
     523                 : 
     524                 :       case GCI_HueBand:
     525               6 :         return "Hue";
     526                 : 
     527                 :       case GCI_SaturationBand:
     528               6 :         return "Saturation";
     529                 : 
     530                 :       case GCI_LightnessBand:
     531               6 :         return "Lightness";
     532                 : 
     533                 :       case GCI_CyanBand:
     534               6 :         return "Cyan";
     535                 : 
     536                 :       case GCI_MagentaBand:
     537               6 :         return "Magenta";
     538                 : 
     539                 :       case GCI_YellowBand:
     540               6 :         return "Yellow";
     541                 : 
     542                 :       case GCI_BlackBand:
     543               6 :         return "Black";
     544                 :         
     545                 :       case GCI_YCbCr_YBand:
     546               7 :         return "YCbCr_Y";
     547                 :         
     548                 :       case GCI_YCbCr_CbBand:
     549               5 :         return "YCbCr_Cb";
     550                 :         
     551                 :       case GCI_YCbCr_CrBand:
     552               3 :         return "YCbCr_Cr";
     553                 :         
     554                 :       default:
     555               0 :         return "Unknown";
     556                 :     }
     557                 : }
     558                 : 
     559                 : /************************************************************************/
     560                 : /*                GDALGetColorInterpretationByName()                    */
     561                 : /************************************************************************/
     562                 : 
     563                 : /**
     564                 :  * \brief Get color interpreation by symbolic name.
     565                 :  *
     566                 :  * Returns a color interpreation corresponding to the given symbolic name. This
     567                 :  * function is opposite to the GDALGetColorInterpretationName().
     568                 :  *
     569                 :  * @param pszName string containing the symbolic name of the color interpretation.
     570                 :  * 
     571                 :  * @return GDAL color interpretation.
     572                 :  *
     573                 :  * @since GDAL 1.7.0
     574                 :  */
     575                 : 
     576             524 : GDALColorInterp GDALGetColorInterpretationByName( const char *pszName )
     577                 : 
     578                 : {
     579             524 :     VALIDATE_POINTER1( pszName, "GDALGetColorInterpretationByName", GCI_Undefined );
     580                 : 
     581                 :     int iType;
     582                 :     
     583            1585 :     for( iType = 0; iType <= GCI_Max; iType++ )
     584                 :     {
     585            1585 :         if( EQUAL(GDALGetColorInterpretationName((GDALColorInterp)iType), pszName) )
     586                 :         {
     587             524 :             return (GDALColorInterp)iType;
     588                 :         }
     589                 :     }
     590                 : 
     591               0 :     return GCI_Undefined;
     592                 : }
     593                 : 
     594                 : /************************************************************************/
     595                 : /*                         GDALDummyProgress()                          */
     596                 : /************************************************************************/
     597                 : 
     598                 : /**
     599                 :  * \brief Stub progress function.
     600                 :  *
     601                 :  * This is a stub (does nothing) implementation of the GDALProgressFunc()
     602                 :  * semantics.  It is primarily useful for passing to functions that take
     603                 :  * a GDALProgressFunc() argument but for which the application does not want
     604                 :  * to use one of the other progress functions that actually do something.
     605                 :  */
     606                 : 
     607          103300 : int CPL_STDCALL GDALDummyProgress( double dfComplete, const char *pszMessage, 
     608                 :                                    void *pData )
     609                 : 
     610                 : {
     611          103300 :     return TRUE;
     612                 : }
     613                 : 
     614                 : /************************************************************************/
     615                 : /*                         GDALScaledProgress()                         */
     616                 : /************************************************************************/
     617                 : typedef struct { 
     618                 :     GDALProgressFunc pfnProgress;
     619                 :     void *pData;
     620                 :     double dfMin;
     621                 :     double dfMax;
     622                 : } GDALScaledProgressInfo;
     623                 : 
     624                 : /**
     625                 :  * \brief Scaled progress transformer.
     626                 :  *
     627                 :  * This is the progress function that should be passed along with the
     628                 :  * callback data returned by GDALCreateScaledProgress().
     629                 :  */
     630                 : 
     631           35326 : int CPL_STDCALL GDALScaledProgress( double dfComplete, const char *pszMessage, 
     632                 :                                     void *pData )
     633                 : 
     634                 : {
     635           35326 :     GDALScaledProgressInfo *psInfo = (GDALScaledProgressInfo *) pData;
     636                 : 
     637                 :     return psInfo->pfnProgress( dfComplete * (psInfo->dfMax - psInfo->dfMin)
     638                 :                                 + psInfo->dfMin,
     639           35326 :                                 pszMessage, psInfo->pData );
     640                 : }
     641                 : 
     642                 : /************************************************************************/
     643                 : /*                      GDALCreateScaledProgress()                      */
     644                 : /************************************************************************/
     645                 : 
     646                 : /**
     647                 :  * \brief Create scaled progress transformer.
     648                 :  *
     649                 :  * Sometimes when an operations wants to report progress it actually
     650                 :  * invokes several subprocesses which also take GDALProgressFunc()s, 
     651                 :  * and it is desirable to map the progress of each sub operation into
     652                 :  * a portion of 0.0 to 1.0 progress of the overall process.  The scaled
     653                 :  * progress function can be used for this. 
     654                 :  *
     655                 :  * For each subsection a scaled progress function is created and
     656                 :  * instead of passing the overall progress func down to the sub functions,
     657                 :  * the GDALScaledProgress() function is passed instead.
     658                 :  *
     659                 :  * @param dfMin the value to which 0.0 in the sub operation is mapped.
     660                 :  * @param dfMax the value to which 1.0 is the sub operation is mapped.
     661                 :  * @param pfnProgress the overall progress function.
     662                 :  * @param pData the overall progress function callback data. 
     663                 :  *
     664                 :  * @return pointer to pass as pProgressArg to sub functions.  Should be freed
     665                 :  * with GDALDestroyScaledProgress(). 
     666                 :  *
     667                 :  * Example:
     668                 :  *
     669                 :  * \code
     670                 :  *   int MyOperation( ..., GDALProgressFunc pfnProgress, void *pProgressData );
     671                 :  *
     672                 :  *   {
     673                 :  *       void *pScaledProgress;
     674                 :  *
     675                 :  *       pScaledProgress = GDALCreateScaledProgress( 0.0, 0.5, pfnProgress, 
     676                 :  *                                                   pProgressData );
     677                 :  *       GDALDoLongSlowOperation( ..., GDALScaledProgress, pScaledProgress );
     678                 :  *       GDALDestroyScaledProgress( pScaledProgress );
     679                 :  *
     680                 :  *       pScaledProgress = GDALCreateScaledProgress( 0.5, 1.0, pfnProgress, 
     681                 :  *                                                   pProgressData );
     682                 :  *       GDALDoAnotherOperation( ..., GDALScaledProgress, pScaledProgress );
     683                 :  *       GDALDestroyScaledProgress( pScaledProgress );
     684                 :  *
     685                 :  *       return ...;
     686                 :  *   }
     687                 :  * \endcode
     688                 :  */
     689                 : 
     690             798 : void * CPL_STDCALL GDALCreateScaledProgress( double dfMin, double dfMax, 
     691                 :                                 GDALProgressFunc pfnProgress, 
     692                 :                                 void * pData )
     693                 : 
     694                 : {
     695                 :     GDALScaledProgressInfo *psInfo;
     696                 : 
     697                 :     psInfo = (GDALScaledProgressInfo *) 
     698             798 :         CPLCalloc(sizeof(GDALScaledProgressInfo),1);
     699                 : 
     700             798 :     if( ABS(dfMin-dfMax) < 0.0000001 )
     701               0 :         dfMax = dfMin + 0.01;
     702                 : 
     703             798 :     psInfo->pData = pData;
     704             798 :     psInfo->pfnProgress = pfnProgress;
     705             798 :     psInfo->dfMin = dfMin;
     706             798 :     psInfo->dfMax = dfMax;
     707                 : 
     708             798 :     return (void *) psInfo;
     709                 : }
     710                 : 
     711                 : /************************************************************************/
     712                 : /*                     GDALDestroyScaledProgress()                      */
     713                 : /************************************************************************/
     714                 : 
     715                 : /**
     716                 :  * \brief Cleanup scaled progress handle.
     717                 :  *
     718                 :  * This function cleans up the data associated with a scaled progress function
     719                 :  * as returned by GADLCreateScaledProgress(). 
     720                 :  *
     721                 :  * @param pData scaled progress handle returned by GDALCreateScaledProgress().
     722                 :  */
     723                 : 
     724             798 : void CPL_STDCALL GDALDestroyScaledProgress( void * pData )
     725                 : 
     726                 : {
     727             798 :     CPLFree( pData );
     728             798 : }
     729                 : 
     730                 : /************************************************************************/
     731                 : /*                          GDALTermProgress()                          */
     732                 : /************************************************************************/
     733                 : 
     734                 : /**
     735                 :  * \brief Simple progress report to terminal.
     736                 :  *
     737                 :  * This progress reporter prints simple progress report to the
     738                 :  * terminal window.  The progress report generally looks something like
     739                 :  * this:
     740                 : 
     741                 : \verbatim
     742                 : 0...10...20...30...40...50...60...70...80...90...100 - done.
     743                 : \endverbatim
     744                 : 
     745                 :  * Every 2.5% of progress another number or period is emitted.  Note that
     746                 :  * GDALTermProgress() uses internal static data to keep track of the last
     747                 :  * percentage reported and will get confused if two terminal based progress
     748                 :  * reportings are active at the same time.
     749                 :  *
     750                 :  * The GDALTermProgress() function maintains an internal memory of the 
     751                 :  * last percentage complete reported in a static variable, and this makes
     752                 :  * it unsuitable to have multiple GDALTermProgress()'s active eithin a 
     753                 :  * single thread or across multiple threads.
     754                 :  *
     755                 :  * @param dfComplete completion ratio from 0.0 to 1.0.
     756                 :  * @param pszMessage optional message.
     757                 :  * @param pProgressArg ignored callback data argument. 
     758                 :  *
     759                 :  * @return Always returns TRUE indicating the process should continue.
     760                 :  */
     761                 : 
     762           35084 : int CPL_STDCALL GDALTermProgress( double dfComplete, const char *pszMessage, 
     763                 :                       void * pProgressArg )
     764                 : 
     765                 : {
     766                 :     static int nLastTick = -1;
     767           35084 :     int nThisTick = (int) (dfComplete * 40.0);
     768                 : 
     769                 :     (void) pProgressArg;
     770                 : 
     771           35084 :     nThisTick = MIN(40,MAX(0,nThisTick));
     772                 : 
     773                 :     // Have we started a new progress run?  
     774           35084 :     if( nThisTick < nLastTick && nLastTick >= 39 )
     775              14 :         nLastTick = -1;
     776                 : 
     777           35084 :     if( nThisTick <= nLastTick )
     778           30572 :         return TRUE;
     779                 : 
     780           26045 :     while( nThisTick > nLastTick )
     781                 :     {
     782           17021 :         nLastTick++;
     783           17021 :         if( nLastTick % 4 == 0 )
     784            4601 :             fprintf( stdout, "%d", (nLastTick / 4) * 10 );
     785                 :         else
     786           12420 :             fprintf( stdout, "." );
     787                 :     }
     788                 : 
     789            4512 :     if( nThisTick == 40 )
     790             414 :         fprintf( stdout, " - done.\n" );
     791                 :     else
     792            4098 :         fflush( stdout );
     793                 : 
     794            4512 :     return TRUE;
     795                 : }
     796                 : 
     797                 : /************************************************************************/
     798                 : /*                     GDALGetRandomRasterSample()                      */
     799                 : /************************************************************************/
     800                 : 
     801                 : int CPL_STDCALL 
     802               0 : GDALGetRandomRasterSample( GDALRasterBandH hBand, int nSamples, 
     803                 :                            float *pafSampleBuf )
     804                 : 
     805                 : {
     806               0 :     VALIDATE_POINTER1( hBand, "GDALGetRandomRasterSample", 0 );
     807                 : 
     808                 :     GDALRasterBand *poBand;
     809                 : 
     810               0 :     poBand = (GDALRasterBand *) GDALGetRasterSampleOverview( hBand, nSamples );
     811               0 :     CPLAssert( NULL != poBand );
     812                 : 
     813                 : /* -------------------------------------------------------------------- */
     814                 : /*      Figure out the ratio of blocks we will read to get an           */
     815                 : /*      approximate value.                                              */
     816                 : /* -------------------------------------------------------------------- */
     817                 :     int         nBlockXSize, nBlockYSize;
     818                 :     int         nBlocksPerRow, nBlocksPerColumn;
     819                 :     int         nSampleRate;
     820                 :     int         bGotNoDataValue;
     821                 :     double      dfNoDataValue;
     822               0 :     int         nActualSamples = 0;
     823                 :     int         nBlockSampleRate;
     824                 :     int         nBlockPixels, nBlockCount;
     825                 : 
     826               0 :     dfNoDataValue = poBand->GetNoDataValue( &bGotNoDataValue );
     827                 : 
     828               0 :     poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
     829                 : 
     830               0 :     nBlocksPerRow = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
     831               0 :     nBlocksPerColumn = (poBand->GetYSize() + nBlockYSize - 1) / nBlockYSize;
     832                 : 
     833               0 :     nBlockPixels = nBlockXSize * nBlockYSize;
     834               0 :     nBlockCount = nBlocksPerRow * nBlocksPerColumn;
     835                 : 
     836               0 :     if( nBlocksPerRow == 0 || nBlocksPerColumn == 0 || nBlockPixels == 0 
     837                 :         || nBlockCount == 0 )
     838                 :     {
     839                 :         CPLError( CE_Failure, CPLE_AppDefined,
     840                 :                   "GDALGetRandomRasterSample(): returning because band"
     841               0 :                   " appears degenerate." );
     842                 : 
     843               0 :         return FALSE;
     844                 :     }
     845                 : 
     846               0 :     nSampleRate = (int) MAX(1,sqrt((double) nBlockCount)-2.0);
     847                 : 
     848               0 :     if( nSampleRate == nBlocksPerRow && nSampleRate > 1 )
     849               0 :         nSampleRate--;
     850                 : 
     851               0 :     while( nSampleRate > 1 
     852                 :            && ((nBlockCount-1) / nSampleRate + 1) * nBlockPixels < nSamples )
     853               0 :         nSampleRate--;
     854                 : 
     855               0 :     if ((nSamples / ((nBlockCount-1) / nSampleRate + 1)) == 0)
     856               0 :         nBlockSampleRate = 1;
     857                 :     else
     858                 :         nBlockSampleRate = 
     859               0 :             MAX(1,nBlockPixels / (nSamples / ((nBlockCount-1) / nSampleRate + 1)));
     860                 : 
     861               0 :     for( int iSampleBlock = 0; 
     862                 :          iSampleBlock < nBlockCount;
     863                 :          iSampleBlock += nSampleRate )
     864                 :     {
     865               0 :         double dfValue = 0.0, dfReal, dfImag;
     866               0 :         int  iXBlock, iYBlock, iX, iY, iXValid, iYValid, iRemainder = 0;
     867                 :         GDALRasterBlock *poBlock;
     868                 : 
     869               0 :         iYBlock = iSampleBlock / nBlocksPerRow;
     870               0 :         iXBlock = iSampleBlock - nBlocksPerRow * iYBlock;
     871                 : 
     872               0 :         poBlock = poBand->GetLockedBlockRef( iXBlock, iYBlock );
     873               0 :         if( poBlock == NULL )
     874               0 :             continue;
     875               0 :         if( poBlock->GetDataRef() == NULL )
     876                 :         {
     877               0 :             poBlock->DropLock();
     878               0 :             continue;
     879                 :         }
     880                 : 
     881               0 :         if( (iXBlock + 1) * nBlockXSize > poBand->GetXSize() )
     882               0 :             iXValid = poBand->GetXSize() - iXBlock * nBlockXSize;
     883                 :         else
     884               0 :             iXValid = nBlockXSize;
     885                 : 
     886               0 :         if( (iYBlock + 1) * nBlockYSize > poBand->GetYSize() )
     887               0 :             iYValid = poBand->GetYSize() - iYBlock * nBlockYSize;
     888                 :         else
     889               0 :             iYValid = nBlockYSize;
     890                 : 
     891               0 :         for( iY = 0; iY < iYValid; iY++ )
     892                 :         {
     893               0 :             for( iX = iRemainder; iX < iXValid; iX += nBlockSampleRate )
     894                 :             {
     895                 :                 int     iOffset;
     896                 : 
     897               0 :                 iOffset = iX + iY * nBlockXSize; 
     898               0 :                 switch( poBlock->GetDataType() )
     899                 :                 {
     900                 :                   case GDT_Byte:
     901               0 :                     dfValue = ((GByte *) poBlock->GetDataRef())[iOffset];
     902               0 :                     break;
     903                 :                   case GDT_UInt16:
     904               0 :                     dfValue = ((GUInt16 *) poBlock->GetDataRef())[iOffset];
     905               0 :                     break;
     906                 :                   case GDT_Int16:
     907               0 :                     dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset];
     908               0 :                     break;
     909                 :                   case GDT_UInt32:
     910               0 :                     dfValue = ((GUInt32 *) poBlock->GetDataRef())[iOffset];
     911               0 :                     break;
     912                 :                   case GDT_Int32:
     913               0 :                     dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset];
     914               0 :                     break;
     915                 :                   case GDT_Float32:
     916               0 :                     dfValue = ((float *) poBlock->GetDataRef())[iOffset];
     917               0 :                     break;
     918                 :                   case GDT_Float64:
     919               0 :                     dfValue = ((double *) poBlock->GetDataRef())[iOffset];
     920               0 :                     break;
     921                 :                   case GDT_CInt16:
     922               0 :                     dfReal = ((GInt16 *) poBlock->GetDataRef())[iOffset*2];
     923               0 :                     dfImag = ((GInt16 *) poBlock->GetDataRef())[iOffset*2+1];
     924               0 :                     dfValue = sqrt(dfReal*dfReal + dfImag*dfImag);
     925               0 :                     break;
     926                 :                   case GDT_CInt32:
     927               0 :                     dfReal = ((GInt32 *) poBlock->GetDataRef())[iOffset*2];
     928               0 :                     dfImag = ((GInt32 *) poBlock->GetDataRef())[iOffset*2+1];
     929               0 :                     dfValue = sqrt(dfReal*dfReal + dfImag*dfImag);
     930               0 :                     break;
     931                 :                   case GDT_CFloat32:
     932               0 :                     dfReal = ((float *) poBlock->GetDataRef())[iOffset*2];
     933               0 :                     dfImag = ((float *) poBlock->GetDataRef())[iOffset*2+1];
     934               0 :                     dfValue = sqrt(dfReal*dfReal + dfImag*dfImag);
     935               0 :                     break;
     936                 :                   case GDT_CFloat64:
     937               0 :                     dfReal = ((double *) poBlock->GetDataRef())[iOffset*2];
     938               0 :                     dfImag = ((double *) poBlock->GetDataRef())[iOffset*2+1];
     939               0 :                     dfValue = sqrt(dfReal*dfReal + dfImag*dfImag);
     940               0 :                     break;
     941                 :                   default:
     942               0 :                     CPLAssert( FALSE );
     943                 :                 }
     944                 :             
     945               0 :                 if( bGotNoDataValue && dfValue == dfNoDataValue )
     946               0 :                     continue;
     947                 : 
     948               0 :                 if( nActualSamples < nSamples )
     949               0 :                     pafSampleBuf[nActualSamples++] = (float) dfValue;
     950                 :             }
     951                 : 
     952               0 :             iRemainder = iX - iXValid;
     953                 :         }
     954                 : 
     955               0 :         poBlock->DropLock();
     956                 :     }
     957                 : 
     958               0 :     return nActualSamples;
     959                 : }
     960                 : 
     961                 : /************************************************************************/
     962                 : /*                            GDALInitGCPs()                            */
     963                 : /************************************************************************/
     964                 : 
     965           19718 : void CPL_STDCALL GDALInitGCPs( int nCount, GDAL_GCP * psGCP )
     966                 : 
     967                 : {
     968           19718 :     if( nCount > 0 )
     969                 :     {
     970           19648 :         VALIDATE_POINTER0( psGCP, "GDALInitGCPs" );
     971                 :     }
     972                 : 
     973           52371 :     for( int iGCP = 0; iGCP < nCount; iGCP++ )
     974                 :     {
     975           32653 :         memset( psGCP, 0, sizeof(GDAL_GCP) );
     976           32653 :         psGCP->pszId = CPLStrdup("");
     977           32653 :         psGCP->pszInfo = CPLStrdup("");
     978           32653 :         psGCP++;
     979                 :     }
     980                 : }
     981                 : 
     982                 : /************************************************************************/
     983                 : /*                           GDALDeinitGCPs()                           */
     984                 : /************************************************************************/
     985                 : 
     986            6223 : void CPL_STDCALL GDALDeinitGCPs( int nCount, GDAL_GCP * psGCP )
     987                 : 
     988                 : {
     989            6223 :     if ( nCount > 0 )
     990                 :     {
     991             370 :         VALIDATE_POINTER0( psGCP, "GDALDeinitGCPs" );
     992                 :     }
     993                 : 
     994           39133 :     for( int iGCP = 0; iGCP < nCount; iGCP++ )
     995                 :     {
     996           32910 :         CPLFree( psGCP->pszId );
     997           32910 :         CPLFree( psGCP->pszInfo );
     998           32910 :         psGCP++;
     999                 :     }
    1000                 : }
    1001                 : 
    1002                 : /************************************************************************/
    1003                 : /*                         GDALDuplicateGCPs()                          */
    1004                 : /************************************************************************/
    1005                 : 
    1006                 : GDAL_GCP * CPL_STDCALL 
    1007             126 : GDALDuplicateGCPs( int nCount, const GDAL_GCP *pasGCPList )
    1008                 : 
    1009                 : {
    1010                 :     GDAL_GCP    *pasReturn;
    1011                 : 
    1012             126 :     pasReturn = (GDAL_GCP *) CPLMalloc(sizeof(GDAL_GCP) * nCount);
    1013             126 :     GDALInitGCPs( nCount, pasReturn );
    1014                 : 
    1015             390 :     for( int iGCP = 0; iGCP < nCount; iGCP++ )
    1016                 :     {
    1017             264 :         CPLFree( pasReturn[iGCP].pszId );
    1018             264 :         pasReturn[iGCP].pszId = CPLStrdup( pasGCPList[iGCP].pszId );
    1019                 : 
    1020             264 :         CPLFree( pasReturn[iGCP].pszInfo );
    1021             264 :         pasReturn[iGCP].pszInfo = CPLStrdup( pasGCPList[iGCP].pszInfo );
    1022                 : 
    1023             264 :         pasReturn[iGCP].dfGCPPixel = pasGCPList[iGCP].dfGCPPixel;
    1024             264 :         pasReturn[iGCP].dfGCPLine = pasGCPList[iGCP].dfGCPLine;
    1025             264 :         pasReturn[iGCP].dfGCPX = pasGCPList[iGCP].dfGCPX;
    1026             264 :         pasReturn[iGCP].dfGCPY = pasGCPList[iGCP].dfGCPY;
    1027             264 :         pasReturn[iGCP].dfGCPZ = pasGCPList[iGCP].dfGCPZ;
    1028                 :     }
    1029                 : 
    1030             126 :     return pasReturn;
    1031                 : }
    1032                 : 
    1033                 : /************************************************************************/
    1034                 : /*                       GDALFindAssociatedFile()                       */
    1035                 : /************************************************************************/
    1036                 : 
    1037                 : /**
    1038                 :  * Find file with alternate extension.
    1039                 :  *
    1040                 :  * Finds the file with the indicated extension, substituting it in place
    1041                 :  * of the extension of the base filename.  Generally used to search for 
    1042                 :  * associated files like world files .RPB files, etc.  If necessary, the
    1043                 :  * extension will be tried in both upper and lower case.  If a sibling file
    1044                 :  * list is available it will be used instead of doing VSIStatExL() calls to 
    1045                 :  * probe the file system.  
    1046                 :  *
    1047                 :  * Note that the result is a dynamic CPLString so this method should not 
    1048                 :  * be used in a situation where there could be cross heap issues.  It is
    1049                 :  * generally imprudent for application built on GDAL to use this function
    1050                 :  * unless they are sure they will always use the same runtime heap as GDAL.
    1051                 :  *
    1052                 :  * @param pszBaseFilename the filename relative to which to search.
    1053                 :  * @param pszExt the target extension in either upper or lower case.
    1054                 :  * @param papszSiblingFiles the list of files in the same directory as 
    1055                 :  * pszBaseFilename or NULL if they are not known. 
    1056                 :  * @param nFlags special options controlling search.  None defined yet, just 
    1057                 :  * pass 0.
    1058                 :  * 
    1059                 :  * @return an empty string if the target is not found, otherwise the target
    1060                 :  * file with similar path style as the pszBaseFilename. 
    1061                 :  */
    1062                 : 
    1063            6409 : CPLString GDALFindAssociatedFile( const char *pszBaseFilename, 
    1064                 :                                   const char *pszExt,
    1065                 :                                   char **papszSiblingFiles, 
    1066                 :                                   int nFlags )
    1067                 : 
    1068                 : {
    1069                 :     (void) nFlags;
    1070                 : 
    1071            6409 :     CPLString osTarget = CPLResetExtension( pszBaseFilename, pszExt );
    1072                 : 
    1073            6409 :     if( papszSiblingFiles == NULL )
    1074                 :     {
    1075                 :         VSIStatBufL sStatBuf;
    1076                 : 
    1077            2978 :         if( VSIStatExL( osTarget, &sStatBuf, VSI_STAT_EXISTS_FLAG ) != 0 )
    1078                 :         {
    1079            2953 :             CPLString osAltExt = pszExt;
    1080                 : 
    1081            2953 :             if( islower( pszExt[0] ) )
    1082               0 :                 osAltExt.toupper();
    1083                 :             else
    1084            2953 :                 osAltExt.tolower();
    1085                 : 
    1086            2953 :             osTarget = CPLResetExtension( pszBaseFilename, osAltExt );
    1087                 : 
    1088            2953 :             if( VSIStatExL( osTarget, &sStatBuf, VSI_STAT_EXISTS_FLAG ) != 0 )
    1089            2951 :                 return "";
    1090                 :         }
    1091                 :     }
    1092                 :     else
    1093                 :     {
    1094                 :         int iSibling = CSLFindString( papszSiblingFiles, 
    1095            3431 :                                       CPLGetFilename(osTarget) );
    1096            3431 :         if( iSibling < 0 )
    1097            3422 :             return "";
    1098                 : 
    1099               9 :         osTarget.resize(osTarget.size() - strlen(papszSiblingFiles[iSibling]));
    1100               9 :         osTarget += papszSiblingFiles[iSibling];
    1101                 :     }
    1102                 : 
    1103              36 :     return osTarget;
    1104                 : }
    1105                 :                              
    1106                 : /************************************************************************/
    1107                 : /*                         GDALLoadOziMapFile()                         */
    1108                 : /************************************************************************/
    1109                 : 
    1110                 : #define MAX_GCP 30
    1111                 :  
    1112               1 : int CPL_STDCALL GDALLoadOziMapFile( const char *pszFilename,
    1113                 :                                     double *padfGeoTransform, char **ppszWKT, 
    1114                 :                                     int *pnGCPCount, GDAL_GCP **ppasGCPs )
    1115                 : 
    1116                 : 
    1117                 : {
    1118                 :     char  **papszLines;
    1119               1 :     int   iLine, nLines=0;
    1120               1 :     int         nCoordinateCount = 0;
    1121                 :     GDAL_GCP    asGCPs[MAX_GCP];
    1122                 :     
    1123               1 :     VALIDATE_POINTER1( pszFilename, "GDALLoadOziMapFile", FALSE );
    1124               1 :     VALIDATE_POINTER1( padfGeoTransform, "GDALLoadOziMapFile", FALSE );
    1125               1 :     VALIDATE_POINTER1( pnGCPCount, "GDALLoadOziMapFile", FALSE );
    1126               1 :     VALIDATE_POINTER1( ppasGCPs, "GDALLoadOziMapFile", FALSE );
    1127                 : 
    1128               1 :     papszLines = CSLLoad2( pszFilename, 1000, 200, NULL );
    1129                 : 
    1130               1 :     if ( !papszLines )
    1131               0 :         return FALSE;
    1132                 : 
    1133               1 :     nLines = CSLCount( papszLines );
    1134                 : 
    1135                 :     // Check the OziExplorer Map file signature
    1136               2 :     if ( nLines < 5
    1137               1 :          || !EQUALN(papszLines[0], "OziExplorer Map Data File Version ", 34) )
    1138                 :     {
    1139                 :         CPLError( CE_Failure, CPLE_AppDefined,
    1140                 :         "GDALLoadOziMapFile(): file \"%s\" is not in OziExplorer Map format.",
    1141               0 :                   pszFilename );
    1142               0 :         CSLDestroy( papszLines );
    1143               0 :         return FALSE;
    1144                 :     }
    1145                 : 
    1146               1 :     OGRSpatialReference oSRS;
    1147               1 :     OGRErr eErr = OGRERR_NONE;
    1148                 : 
    1149                 :     /* The Map Scale Factor has been introduced recently on the 6th line */
    1150                 :     /* and is a trick that is used to just change that line without changing */
    1151                 :     /* the rest of the MAP file but providing an imagery that is smaller or larger */
    1152                 :     /* so we have to correct the pixel/line values read in the .MAP file so they */
    1153                 :     /* match the actual imagery dimension. Well, this is a bad summary of what */
    1154                 :     /* is explained at http://tech.groups.yahoo.com/group/OziUsers-L/message/12484 */
    1155               1 :     double dfMSF = 1;
    1156                 : 
    1157              52 :     for ( iLine = 5; iLine < nLines; iLine++ )
    1158                 :     {
    1159              51 :         if ( EQUALN(papszLines[iLine], "MSF,", 4) )
    1160                 :         {
    1161               0 :             dfMSF = atof(papszLines[iLine] + 4);
    1162               0 :             if (dfMSF <= 0.01) /* Suspicious values */
    1163                 :             {
    1164               0 :                 CPLDebug("OZI", "Suspicious MSF value : %s", papszLines[iLine]);
    1165               0 :                 dfMSF = 1;
    1166                 :             }
    1167                 :         }
    1168                 :     }
    1169                 : 
    1170               1 :     eErr = oSRS.importFromOzi( papszLines );
    1171               1 :     if ( eErr == OGRERR_NONE )
    1172                 :     {
    1173               1 :         if ( ppszWKT != NULL )
    1174               1 :             oSRS.exportToWkt( ppszWKT );
    1175                 :     }
    1176                 : 
    1177                 :     // Iterate all lines in the MAP-file
    1178              52 :     for ( iLine = 5; iLine < nLines; iLine++ )
    1179                 :     {
    1180              51 :         char    **papszTok = NULL;
    1181                 : 
    1182              51 :         papszTok = CSLTokenizeString2( papszLines[iLine], ",",
    1183                 :                                        CSLT_ALLOWEMPTYTOKENS
    1184                 :                                        | CSLT_STRIPLEADSPACES
    1185             102 :                                        | CSLT_STRIPENDSPACES );
    1186                 : 
    1187              51 :         if ( CSLCount(papszTok) < 12 )
    1188                 :         {
    1189              21 :             CSLDestroy(papszTok);
    1190              21 :             continue;
    1191                 :         }
    1192                 : 
    1193              94 :         if ( CSLCount(papszTok) >= 17
    1194              30 :              && EQUALN(papszTok[0], "Point", 5)
    1195              30 :              && !EQUAL(papszTok[2], "")
    1196               4 :              && !EQUAL(papszTok[3], "")
    1197                 :              && nCoordinateCount < MAX_GCP )
    1198                 :         {
    1199               4 :             int     bReadOk = FALSE;
    1200               4 :             double  dfLon = 0., dfLat = 0.;
    1201                 : 
    1202              20 :             if ( !EQUAL(papszTok[6], "")
    1203               4 :                  && !EQUAL(papszTok[7], "")
    1204               4 :                  && !EQUAL(papszTok[9], "")
    1205               4 :                  && !EQUAL(papszTok[10], "") )
    1206                 :             {
    1207                 :                 // Set geographical coordinates of the pixels
    1208               4 :                 dfLon = CPLAtofM(papszTok[9]) + CPLAtofM(papszTok[10]) / 60.0;
    1209               4 :                 dfLat = CPLAtofM(papszTok[6]) + CPLAtofM(papszTok[7]) / 60.0;
    1210               4 :                 if ( EQUAL(papszTok[11], "W") )
    1211               1 :                     dfLon = -dfLon;
    1212               4 :                 if ( EQUAL(papszTok[8], "S") )
    1213               0 :                     dfLat = -dfLat;
    1214                 : 
    1215                 :                 // Transform from the geographical coordinates into projected
    1216                 :                 // coordinates.
    1217               4 :                 if ( eErr == OGRERR_NONE )
    1218                 :                 {
    1219               4 :                     OGRSpatialReference *poLatLong = NULL;
    1220               4 :                     OGRCoordinateTransformation *poTransform = NULL;
    1221                 : 
    1222               4 :                     poLatLong = oSRS.CloneGeogCS();
    1223               4 :                     if ( poLatLong )
    1224                 :                     {
    1225               4 :                         poTransform = OGRCreateCoordinateTransformation( poLatLong, &oSRS );
    1226               4 :                         if ( poTransform )
    1227                 :                         {
    1228               4 :                             bReadOk = poTransform->Transform( 1, &dfLon, &dfLat );
    1229               4 :                             delete poTransform;
    1230                 :                         }
    1231               4 :                         delete poLatLong;
    1232                 :                     }
    1233                 :                 }
    1234                 :             }
    1235               0 :             else if ( !EQUAL(papszTok[14], "")
    1236               0 :                       && !EQUAL(papszTok[15], "") )
    1237                 :             {
    1238                 :                 // Set cartesian coordinates of the pixels.
    1239               0 :                 dfLon = CPLAtofM(papszTok[14]);
    1240               0 :                 dfLat = CPLAtofM(papszTok[15]);
    1241               0 :                 bReadOk = TRUE;
    1242                 : 
    1243                 :                 //if ( EQUAL(papszTok[16], "S") )
    1244                 :                 //    dfLat = -dfLat;
    1245                 :             }
    1246                 : 
    1247               4 :             if ( bReadOk )
    1248                 :             {
    1249               4 :                 GDALInitGCPs( 1, asGCPs + nCoordinateCount );
    1250                 : 
    1251                 :                 // Set pixel/line part
    1252               4 :                 asGCPs[nCoordinateCount].dfGCPPixel = CPLAtofM(papszTok[2]) / dfMSF;
    1253               4 :                 asGCPs[nCoordinateCount].dfGCPLine = CPLAtofM(papszTok[3]) / dfMSF;
    1254                 : 
    1255               4 :                 asGCPs[nCoordinateCount].dfGCPX = dfLon;
    1256               4 :                 asGCPs[nCoordinateCount].dfGCPY = dfLat;
    1257                 : 
    1258               4 :                 nCoordinateCount++;
    1259                 :             }
    1260                 :         }
    1261                 : 
    1262              30 :         CSLDestroy( papszTok );
    1263                 :     }
    1264                 : 
    1265               1 :     CSLDestroy( papszLines );
    1266                 : 
    1267               1 :     if ( nCoordinateCount == 0 )
    1268                 :     {
    1269                 :         CPLDebug( "GDAL", "GDALLoadOziMapFile(\"%s\") did read no GCPs.", 
    1270               0 :                   pszFilename );
    1271               0 :         return FALSE;
    1272                 :     }
    1273                 : 
    1274                 : /* -------------------------------------------------------------------- */
    1275                 : /*      Try to convert the GCPs into a geotransform definition, if      */
    1276                 : /*      possible.  Otherwise we will need to use them as GCPs.          */
    1277                 : /* -------------------------------------------------------------------- */
    1278               1 :     if( !GDALGCPsToGeoTransform( nCoordinateCount, asGCPs, padfGeoTransform, 
    1279                 :                                  CSLTestBoolean(CPLGetConfigOption("OZI_APPROX_GEOTRANSFORM", "NO")) ) )
    1280                 :     {
    1281               1 :         if ( pnGCPCount && ppasGCPs )
    1282                 :         {
    1283                 :             CPLDebug( "GDAL", 
    1284                 :                 "GDALLoadOziMapFile(%s) found file, wasn't able to derive a\n"
    1285                 :                 "first order geotransform.  Using points as GCPs.",
    1286               1 :                 pszFilename );
    1287                 : 
    1288                 :             *ppasGCPs = (GDAL_GCP *) 
    1289               1 :                 CPLCalloc( sizeof(GDAL_GCP),nCoordinateCount );
    1290               1 :             memcpy( *ppasGCPs, asGCPs, sizeof(GDAL_GCP) * nCoordinateCount );
    1291               1 :             *pnGCPCount = nCoordinateCount;
    1292                 :         }
    1293                 :     }
    1294                 :     else
    1295                 :     {
    1296               0 :         GDALDeinitGCPs( nCoordinateCount, asGCPs );
    1297                 :     }
    1298                 :      
    1299               1 :     return TRUE;
    1300                 : }
    1301                 : 
    1302                 : #undef MAX_GCP
    1303                 : 
    1304                 : /************************************************************************/
    1305                 : /*                       GDALReadOziMapFile()                           */
    1306                 : /************************************************************************/
    1307                 : 
    1308               0 : int CPL_STDCALL GDALReadOziMapFile( const char * pszBaseFilename,
    1309                 :                                     double *padfGeoTransform, char **ppszWKT,
    1310                 :                                     int *pnGCPCount, GDAL_GCP **ppasGCPs )
    1311                 : 
    1312                 : 
    1313                 : {
    1314                 :     const char  *pszOzi;
    1315                 :     FILE  *fpOzi;
    1316                 : 
    1317                 : /* -------------------------------------------------------------------- */
    1318                 : /*      Try lower case, then upper case.                                */
    1319                 : /* -------------------------------------------------------------------- */
    1320               0 :     pszOzi = CPLResetExtension( pszBaseFilename, "map" );
    1321                 : 
    1322               0 :     fpOzi = VSIFOpen( pszOzi, "rt" );
    1323                 : 
    1324               0 :     if ( fpOzi == NULL && VSIIsCaseSensitiveFS(pszOzi) )
    1325                 :     {
    1326               0 :         pszOzi = CPLResetExtension( pszBaseFilename, "MAP" );
    1327               0 :         fpOzi = VSIFOpen( pszOzi, "rt" );
    1328                 :     }
    1329                 :     
    1330               0 :     if ( fpOzi == NULL )
    1331               0 :         return FALSE;
    1332                 : 
    1333               0 :     VSIFClose( fpOzi );
    1334                 : 
    1335                 : /* -------------------------------------------------------------------- */
    1336                 : /*      We found the file, now load and parse it.                       */
    1337                 : /* -------------------------------------------------------------------- */
    1338                 :     return GDALLoadOziMapFile( pszOzi, padfGeoTransform, ppszWKT,
    1339               0 :                                pnGCPCount, ppasGCPs );
    1340                 : }
    1341                 : 
    1342                 : /************************************************************************/
    1343                 : /*                         GDALLoadTabFile()                            */
    1344                 : /*                                                                      */
    1345                 : /*      Helper function for translator implementators wanting           */
    1346                 : /*      support for MapInfo .tab-files.                                 */
    1347                 : /************************************************************************/
    1348                 : 
    1349                 : #define MAX_GCP 256
    1350                 :  
    1351               2 : int CPL_STDCALL GDALLoadTabFile( const char *pszFilename,
    1352                 :                                  double *padfGeoTransform, char **ppszWKT, 
    1353                 :                                  int *pnGCPCount, GDAL_GCP **ppasGCPs )
    1354                 : 
    1355                 : 
    1356                 : {
    1357                 :     char  **papszLines;
    1358               2 :     char        **papszTok=NULL;
    1359               2 :     int         bTypeRasterFound = FALSE;
    1360               2 :     int   bInsideTableDef = FALSE;
    1361               2 :     int   iLine, numLines=0;
    1362               2 :     int         nCoordinateCount = 0;
    1363                 :     GDAL_GCP    asGCPs[MAX_GCP];
    1364                 :     
    1365               2 :     papszLines = CSLLoad2( pszFilename, 1000, 200, NULL );
    1366                 : 
    1367               2 :     if ( !papszLines )
    1368               0 :         return FALSE;
    1369                 : 
    1370               2 :     numLines = CSLCount(papszLines);
    1371                 : 
    1372                 :     // Iterate all lines in the TAB-file
    1373              28 :     for(iLine=0; iLine<numLines; iLine++)
    1374                 :     {
    1375              26 :         CSLDestroy(papszTok);
    1376              26 :         papszTok = CSLTokenizeStringComplex(papszLines[iLine], " \t(),;", 
    1377              52 :                                             TRUE, FALSE);
    1378                 : 
    1379              26 :         if (CSLCount(papszTok) < 2)
    1380               4 :             continue;
    1381                 : 
    1382                 :         // Did we find table definition
    1383              24 :         if (EQUAL(papszTok[0], "Definition") && EQUAL(papszTok[1], "Table") )
    1384                 :         {
    1385               2 :             bInsideTableDef = TRUE;
    1386                 :         }
    1387              22 :         else if (bInsideTableDef && (EQUAL(papszTok[0], "Type")) )
    1388                 :         {
    1389                 :             // Only RASTER-type will be handled
    1390               2 :             if (EQUAL(papszTok[1], "RASTER"))
    1391                 :             {
    1392               2 :                 bTypeRasterFound = TRUE;
    1393                 :             }
    1394                 :             else
    1395                 :             {
    1396               0 :                 CSLDestroy(papszTok);
    1397               0 :                 CSLDestroy(papszLines);
    1398               0 :                 return FALSE;
    1399                 :             }
    1400                 :         }
    1401              28 :         else if (bTypeRasterFound && bInsideTableDef
    1402                 :                  && CSLCount(papszTok) > 4
    1403              10 :                  && EQUAL(papszTok[4], "Label") 
    1404                 :                  && nCoordinateCount < MAX_GCP )
    1405                 :         {
    1406               8 :             GDALInitGCPs( 1, asGCPs + nCoordinateCount );
    1407                 :             
    1408               8 :             asGCPs[nCoordinateCount].dfGCPPixel = CPLAtofM(papszTok[2]);
    1409               8 :             asGCPs[nCoordinateCount].dfGCPLine = CPLAtofM(papszTok[3]);
    1410               8 :             asGCPs[nCoordinateCount].dfGCPX = CPLAtofM(papszTok[0]);
    1411               8 :             asGCPs[nCoordinateCount].dfGCPY = CPLAtofM(papszTok[1]);
    1412               8 :             if( papszTok[5] != NULL )
    1413                 :             {
    1414               8 :                 CPLFree( asGCPs[nCoordinateCount].pszId );
    1415               8 :                 asGCPs[nCoordinateCount].pszId = CPLStrdup(papszTok[5]);
    1416                 :             }
    1417                 : 
    1418               8 :             nCoordinateCount++;
    1419                 :         }
    1420              16 :         else if( bTypeRasterFound && bInsideTableDef 
    1421               4 :                  && EQUAL(papszTok[0],"CoordSys") 
    1422                 :                  && ppszWKT != NULL )
    1423                 :         {
    1424               2 :             OGRSpatialReference oSRS;
    1425                 :             
    1426               2 :             if( oSRS.importFromMICoordSys( papszLines[iLine] ) == OGRERR_NONE )
    1427               2 :                 oSRS.exportToWkt( ppszWKT );
    1428                 :         }
    1429              10 :         else if( EQUAL(papszTok[0],"Units") 
    1430                 :                  && CSLCount(papszTok) > 1 
    1431               2 :                  && EQUAL(papszTok[1],"degree") )
    1432                 :         {
    1433                 :             /*
    1434                 :             ** If we have units of "degree", but a projected coordinate
    1435                 :             ** system we need to convert it to geographic.  See to01_02.TAB.
    1436                 :             */
    1437               0 :             if( ppszWKT != NULL && *ppszWKT != NULL
    1438                 :                 && EQUALN(*ppszWKT,"PROJCS",6) )
    1439                 :             {
    1440               0 :                 OGRSpatialReference oSRS, oSRSGeogCS;
    1441               0 :                 char *pszSrcWKT = *ppszWKT;
    1442                 : 
    1443               0 :                 oSRS.importFromWkt( &pszSrcWKT );
    1444               0 :                 oSRSGeogCS.CopyGeogCSFrom( &oSRS );
    1445               0 :                 CPLFree( *ppszWKT );
    1446               0 :                 oSRSGeogCS.exportToWkt( ppszWKT );
    1447                 :             }
    1448                 :         }
    1449                 :             
    1450                 :     }
    1451                 : 
    1452               2 :     CSLDestroy(papszTok);
    1453               2 :     CSLDestroy(papszLines);
    1454                 : 
    1455               2 :     if( nCoordinateCount == 0 )
    1456                 :     {
    1457                 :         CPLDebug( "GDAL", "GDALLoadTabFile(%s) did not get any GCPs.", 
    1458               0 :                   pszFilename );
    1459               0 :         return FALSE;
    1460                 :     }
    1461                 : 
    1462                 : /* -------------------------------------------------------------------- */
    1463                 : /*      Try to convert the GCPs into a geotransform definition, if      */
    1464                 : /*      possible.  Otherwise we will need to use them as GCPs.          */
    1465                 : /* -------------------------------------------------------------------- */
    1466               2 :     if( !GDALGCPsToGeoTransform( nCoordinateCount, asGCPs, padfGeoTransform, 
    1467                 :                                  FALSE ) )
    1468                 :     {
    1469               0 :         if (pnGCPCount && ppasGCPs)
    1470                 :         {
    1471                 :             CPLDebug( "GDAL", 
    1472                 :                 "GDALLoadTabFile(%s) found file, wasn't able to derive a\n"
    1473                 :                 "first order geotransform.  Using points as GCPs.",
    1474               0 :                 pszFilename );
    1475                 : 
    1476                 :             *ppasGCPs = (GDAL_GCP *) 
    1477               0 :                 CPLCalloc( sizeof(GDAL_GCP),nCoordinateCount );
    1478               0 :             memcpy( *ppasGCPs, asGCPs, sizeof(GDAL_GCP) * nCoordinateCount );
    1479               0 :             *pnGCPCount = nCoordinateCount;
    1480                 :         }
    1481                 :     }
    1482                 :     else
    1483                 :     {
    1484               2 :         GDALDeinitGCPs( nCoordinateCount, asGCPs );
    1485                 :     }
    1486                 :      
    1487               2 :     return TRUE;
    1488                 : }
    1489                 : 
    1490                 : #undef MAX_GCP
    1491                 : 
    1492                 : /************************************************************************/
    1493                 : /*                         GDALReadTabFile()                            */
    1494                 : /*                                                                      */
    1495                 : /*      Helper function for translator implementators wanting           */
    1496                 : /*      support for MapInfo .tab-files.                                 */
    1497                 : /************************************************************************/
    1498                 : 
    1499               0 : int CPL_STDCALL GDALReadTabFile( const char * pszBaseFilename, 
    1500                 :                                  double *padfGeoTransform, char **ppszWKT, 
    1501                 :                                  int *pnGCPCount, GDAL_GCP **ppasGCPs )
    1502                 : 
    1503                 : 
    1504                 : {
    1505                 :     return GDALReadTabFile2(pszBaseFilename, padfGeoTransform,
    1506                 :                             ppszWKT, pnGCPCount, ppasGCPs,
    1507               0 :                             NULL, NULL);
    1508                 : }
    1509                 : 
    1510                 : 
    1511            1133 : int GDALReadTabFile2( const char * pszBaseFilename,
    1512                 :                       double *padfGeoTransform, char **ppszWKT,
    1513                 :                       int *pnGCPCount, GDAL_GCP **ppasGCPs,
    1514                 :                       char** papszSiblingFiles, char** ppszTabFileNameOut )
    1515                 : {
    1516                 :     const char  *pszTAB;
    1517                 :     VSILFILE  *fpTAB;
    1518                 : 
    1519            1133 :     if (ppszTabFileNameOut)
    1520            1133 :         *ppszTabFileNameOut = NULL;
    1521                 : 
    1522            1133 :     pszTAB = CPLResetExtension( pszBaseFilename, "tab" );
    1523                 : 
    1524            1133 :     if (papszSiblingFiles)
    1525                 :     {
    1526            1034 :         int iSibling = CSLFindString(papszSiblingFiles, CPLGetFilename(pszTAB));
    1527            1034 :         if (iSibling >= 0)
    1528                 :         {
    1529               2 :             CPLString osTabFilename = pszBaseFilename;
    1530                 :             osTabFilename.resize(strlen(pszBaseFilename) -
    1531               2 :                                  strlen(CPLGetFilename(pszBaseFilename)));
    1532               2 :             osTabFilename += papszSiblingFiles[iSibling];
    1533               2 :             if ( GDALLoadTabFile(osTabFilename, padfGeoTransform, ppszWKT,
    1534                 :                                  pnGCPCount, ppasGCPs ) )
    1535                 :             {
    1536               2 :                 if (ppszTabFileNameOut)
    1537               2 :                     *ppszTabFileNameOut = CPLStrdup(osTabFilename);
    1538               2 :                 return TRUE;
    1539               0 :             }
    1540                 :         }
    1541            1032 :         return FALSE;
    1542                 :     }
    1543                 : 
    1544                 : /* -------------------------------------------------------------------- */
    1545                 : /*      Try lower case, then upper case.                                */
    1546                 : /* -------------------------------------------------------------------- */
    1547                 : 
    1548              99 :     fpTAB = VSIFOpenL( pszTAB, "rt" );
    1549                 : 
    1550              99 :     if( fpTAB == NULL && VSIIsCaseSensitiveFS(pszTAB) )
    1551                 :     {
    1552              99 :         pszTAB = CPLResetExtension( pszBaseFilename, "TAB" );
    1553              99 :         fpTAB = VSIFOpenL( pszTAB, "rt" );
    1554                 :     }
    1555                 :     
    1556              99 :     if( fpTAB == NULL )
    1557              99 :         return FALSE;
    1558                 : 
    1559               0 :     VSIFCloseL( fpTAB );
    1560                 : 
    1561                 : /* -------------------------------------------------------------------- */
    1562                 : /*      We found the file, now load and parse it.                       */
    1563                 : /* -------------------------------------------------------------------- */
    1564               0 :     if (GDALLoadTabFile( pszTAB, padfGeoTransform, ppszWKT,
    1565                 :                          pnGCPCount, ppasGCPs ) )
    1566                 :     {
    1567               0 :         if (ppszTabFileNameOut)
    1568               0 :             *ppszTabFileNameOut = CPLStrdup(pszTAB);
    1569               0 :         return TRUE;
    1570                 :     }
    1571               0 :     return FALSE;
    1572                 : }
    1573                 : 
    1574                 : /************************************************************************/
    1575                 : /*                         GDALLoadWorldFile()                          */
    1576                 : /************************************************************************/
    1577                 : 
    1578                 : /**
    1579                 :  * \brief Read ESRI world file. 
    1580                 :  *
    1581                 :  * This function reads an ESRI style world file, and formats a geotransform
    1582                 :  * from its contents.
    1583                 :  *
    1584                 :  * The world file contains an affine transformation with the parameters
    1585                 :  * in a different order than in a geotransform array. 
    1586                 :  *
    1587                 :  * <ul>
    1588                 :  * <li> geotransform[1] : width of pixel
    1589                 :  * <li> geotransform[4] : rotational coefficient, zero for north up images.
    1590                 :  * <li> geotransform[2] : rotational coefficient, zero for north up images.
    1591                 :  * <li> geotransform[5] : height of pixel (but negative)
    1592                 :  * <li> geotransform[0] + 0.5 * geotransform[1] + 0.5 * geotransform[2] : x offset to center of top left pixel.
    1593                 :  * <li> geotransform[3] + 0.5 * geotransform[4] + 0.5 * geotransform[5] : y offset to center of top left pixel.
    1594                 :  * </ul>
    1595                 :  *
    1596                 :  * @param pszFilename the world file name.
    1597                 :  * @param padfGeoTransform the six double array into which the
    1598                 :  * geotransformation should be placed. 
    1599                 :  *
    1600                 :  * @return TRUE on success or FALSE on failure.
    1601                 :  */
    1602                 : 
    1603                 : int CPL_STDCALL 
    1604              24 : GDALLoadWorldFile( const char *pszFilename, double *padfGeoTransform )
    1605                 : 
    1606                 : {
    1607                 :     char        **papszLines;
    1608                 : 
    1609              24 :     VALIDATE_POINTER1( pszFilename, "GDALLoadWorldFile", FALSE );
    1610              24 :     VALIDATE_POINTER1( padfGeoTransform, "GDALLoadWorldFile", FALSE );
    1611                 : 
    1612              24 :     papszLines = CSLLoad2( pszFilename, 100, 100, NULL );
    1613                 : 
    1614              24 :     if ( !papszLines )
    1615               0 :         return FALSE;
    1616                 : 
    1617                 :    double world[6];
    1618                 :     // reads the first 6 non-empty lines
    1619              24 :     int nLines = 0;
    1620              24 :     int nLinesCount = CSLCount(papszLines);
    1621              24 :     for( int i = 0; i < nLinesCount && nLines < 6; ++i )
    1622                 :     {
    1623             144 :         CPLString line(papszLines[i]);
    1624             144 :         if( line.Trim().empty() )
    1625               0 :           continue;
    1626                 : 
    1627             144 :         world[nLines] = CPLAtofM(line);
    1628             144 :         ++nLines;
    1629                 :     }
    1630                 :       
    1631              72 :     if( nLines == 6 
    1632              24 :         && (world[0] != 0.0 || world[2] != 0.0)
    1633              24 :         && (world[3] != 0.0 || world[1] != 0.0) )
    1634                 :     {
    1635              24 :         padfGeoTransform[0] = world[4];
    1636              24 :         padfGeoTransform[1] = world[0];
    1637              24 :         padfGeoTransform[2] = world[2];
    1638              24 :         padfGeoTransform[3] = world[5];
    1639              24 :         padfGeoTransform[4] = world[1];
    1640              24 :         padfGeoTransform[5] = world[3];
    1641                 : 
    1642                 :         // correct for center of pixel vs. top left of pixel
    1643              24 :         padfGeoTransform[0] -= 0.5 * padfGeoTransform[1];
    1644              24 :         padfGeoTransform[0] -= 0.5 * padfGeoTransform[2];
    1645              24 :         padfGeoTransform[3] -= 0.5 * padfGeoTransform[4];
    1646              24 :         padfGeoTransform[3] -= 0.5 * padfGeoTransform[5];
    1647                 : 
    1648              24 :         CSLDestroy(papszLines);
    1649                 : 
    1650              24 :         return TRUE;
    1651                 :     }
    1652                 :     else
    1653                 :     {
    1654                 :         CPLDebug( "GDAL", 
    1655                 :                   "GDALLoadWorldFile(%s) found file, but it was corrupt.",
    1656               0 :                   pszFilename );
    1657               0 :         CSLDestroy(papszLines);
    1658               0 :         return FALSE;
    1659                 :     }
    1660                 : }
    1661                 : 
    1662                 : /************************************************************************/
    1663                 : /*                         GDALReadWorldFile()                          */
    1664                 : /************************************************************************/
    1665                 : 
    1666                 : /**
    1667                 :  * \brief Read ESRI world file. 
    1668                 :  *
    1669                 :  * This function reads an ESRI style world file, and formats a geotransform
    1670                 :  * from its contents.  It does the same as GDALLoadWorldFile() function, but
    1671                 :  * it will form the filename for the worldfile from the filename of the raster
    1672                 :  * file referred and the suggested extension.  If no extension is provided,
    1673                 :  * the code will internally try the unix style and windows style world file
    1674                 :  * extensions (eg. for .tif these would be .tfw and .tifw). 
    1675                 :  *
    1676                 :  * The world file contains an affine transformation with the parameters
    1677                 :  * in a different order than in a geotransform array. 
    1678                 :  *
    1679                 :  * <ul>
    1680                 :  * <li> geotransform[1] : width of pixel
    1681                 :  * <li> geotransform[4] : rotational coefficient, zero for north up images.
    1682                 :  * <li> geotransform[2] : rotational coefficient, zero for north up images.
    1683                 :  * <li> geotransform[5] : height of pixel (but negative)
    1684                 :  * <li> geotransform[0] + 0.5 * geotransform[1] + 0.5 * geotransform[2] : x offset to center of top left pixel.
    1685                 :  * <li> geotransform[3] + 0.5 * geotransform[4] + 0.5 * geotransform[5] : y offset to center of top left pixel.
    1686                 :  * </ul>
    1687                 :  *
    1688                 :  * @param pszBaseFilename the target raster file.
    1689                 :  * @param pszExtension the extension to use (ie. ".wld") or NULL to derive it
    1690                 :  * from the pszBaseFilename
    1691                 :  * @param padfGeoTransform the six double array into which the 
    1692                 :  * geotransformation should be placed. 
    1693                 :  *
    1694                 :  * @return TRUE on success or FALSE on failure.
    1695                 :  */
    1696                 : 
    1697                 : int CPL_STDCALL 
    1698            1104 : GDALReadWorldFile( const char *pszBaseFilename, const char *pszExtension,
    1699                 :                    double *padfGeoTransform )
    1700                 : 
    1701                 : {
    1702                 :     return GDALReadWorldFile2(pszBaseFilename, pszExtension,
    1703            1104 :                               padfGeoTransform, NULL, NULL);
    1704                 : }
    1705                 : 
    1706            6201 : int GDALReadWorldFile2( const char *pszBaseFilename, const char *pszExtension,
    1707                 :                         double *padfGeoTransform, char** papszSiblingFiles,
    1708                 :                         char** ppszWorldFileNameOut )
    1709                 : {
    1710                 :     const char  *pszTFW;
    1711                 :     char        szExtUpper[32], szExtLower[32];
    1712                 :     int         i;
    1713                 : 
    1714            6201 :     VALIDATE_POINTER1( pszBaseFilename, "GDALReadWorldFile", FALSE );
    1715            6201 :     VALIDATE_POINTER1( padfGeoTransform, "GDALReadWorldFile", FALSE );
    1716                 : 
    1717            6201 :     if (ppszWorldFileNameOut)
    1718            4530 :         *ppszWorldFileNameOut = NULL;
    1719                 : 
    1720                 : /* -------------------------------------------------------------------- */
    1721                 : /*      If we aren't given an extension, try both the unix and          */
    1722                 : /*      windows style extensions.                                       */
    1723                 : /* -------------------------------------------------------------------- */
    1724            6201 :     if( pszExtension == NULL )
    1725                 :     {
    1726                 :         char szDerivedExtension[100];
    1727            1431 :         std::string  oBaseExt = CPLGetExtension( pszBaseFilename );
    1728                 : 
    1729            2862 :         if( oBaseExt.length() < 2 )
    1730             120 :             return FALSE;
    1731                 : 
    1732                 :         // windows version - first + last + 'w'
    1733            1311 :         szDerivedExtension[0] = oBaseExt[0];
    1734            1311 :         szDerivedExtension[1] = oBaseExt[oBaseExt.length()-1];
    1735            1311 :         szDerivedExtension[2] = 'w';
    1736            1311 :         szDerivedExtension[3] = '\0';
    1737                 :         
    1738            1311 :         if( GDALReadWorldFile2( pszBaseFilename, szDerivedExtension,
    1739                 :                                 padfGeoTransform, papszSiblingFiles,
    1740                 :                                 ppszWorldFileNameOut ) )
    1741              10 :             return TRUE;
    1742                 : 
    1743                 :         // unix version - extension + 'w'
    1744            1301 :         if( oBaseExt.length() > sizeof(szDerivedExtension)-2 )
    1745               0 :             return FALSE;
    1746                 : 
    1747            1301 :         strcpy( szDerivedExtension, oBaseExt.c_str() );
    1748            1301 :         strcat( szDerivedExtension, "w" );
    1749                 :         return GDALReadWorldFile2( pszBaseFilename, szDerivedExtension,
    1750                 :                                   padfGeoTransform, papszSiblingFiles,
    1751            1301 :                                   ppszWorldFileNameOut );
    1752                 :     }
    1753                 : 
    1754                 : /* -------------------------------------------------------------------- */
    1755                 : /*      Skip the leading period in the extension if there is one.       */
    1756                 : /* -------------------------------------------------------------------- */
    1757            4770 :     if( *pszExtension == '.' )
    1758             367 :         pszExtension++;
    1759                 : 
    1760                 : /* -------------------------------------------------------------------- */
    1761                 : /*      Generate upper and lower case versions of the extension.        */
    1762                 : /* -------------------------------------------------------------------- */
    1763            4770 :     CPLStrlcpy( szExtUpper, pszExtension, sizeof(szExtUpper) );
    1764            4770 :     CPLStrlcpy( szExtLower, pszExtension, sizeof(szExtLower) );
    1765                 : 
    1766           20385 :     for( i = 0; szExtUpper[i] != '\0'; i++ )
    1767                 :     {
    1768           15615 :         szExtUpper[i] = (char) toupper(szExtUpper[i]);
    1769           15615 :         szExtLower[i] = (char) tolower(szExtLower[i]);
    1770                 :     }
    1771                 : 
    1772                 :     VSIStatBufL sStatBuf;
    1773                 :     int bGotTFW;
    1774                 : 
    1775            4770 :     pszTFW = CPLResetExtension( pszBaseFilename, szExtLower );
    1776                 : 
    1777            4770 :     if (papszSiblingFiles)
    1778                 :     {
    1779            3210 :         int iSibling = CSLFindString(papszSiblingFiles, CPLGetFilename(pszTFW));
    1780            3210 :         if (iSibling >= 0)
    1781                 :         {
    1782              13 :             CPLString osTFWFilename = pszBaseFilename;
    1783                 :             osTFWFilename.resize(strlen(pszBaseFilename) -
    1784              13 :                                  strlen(CPLGetFilename(pszBaseFilename)));
    1785              13 :             osTFWFilename += papszSiblingFiles[iSibling];
    1786              13 :             if (GDALLoadWorldFile( osTFWFilename, padfGeoTransform ))
    1787                 :             {
    1788              13 :                 if (ppszWorldFileNameOut)
    1789              13 :                     *ppszWorldFileNameOut = CPLStrdup(osTFWFilename);
    1790              13 :                 return TRUE;
    1791               0 :             }
    1792                 :         }
    1793            3197 :         return FALSE;
    1794                 :     }
    1795                 : 
    1796                 : /* -------------------------------------------------------------------- */
    1797                 : /*      Try lower case, then upper case.                                */
    1798                 : /* -------------------------------------------------------------------- */
    1799                 : 
    1800            1560 :     bGotTFW = VSIStatExL( pszTFW, &sStatBuf, VSI_STAT_EXISTS_FLAG ) == 0;
    1801                 : 
    1802            1560 :     if( !bGotTFW  && VSIIsCaseSensitiveFS(pszTFW) )
    1803                 :     {
    1804            1549 :         pszTFW = CPLResetExtension( pszBaseFilename, szExtUpper );
    1805            1549 :         bGotTFW = VSIStatExL( pszTFW, &sStatBuf, VSI_STAT_EXISTS_FLAG ) == 0;
    1806                 :     }
    1807                 :     
    1808            1560 :     if( !bGotTFW )
    1809            1549 :         return FALSE;
    1810                 : 
    1811                 : /* -------------------------------------------------------------------- */
    1812                 : /*      We found the file, now load and parse it.                       */
    1813                 : /* -------------------------------------------------------------------- */
    1814              11 :     if (GDALLoadWorldFile( pszTFW, padfGeoTransform ))
    1815                 :     {
    1816              11 :         if (ppszWorldFileNameOut)
    1817               3 :             *ppszWorldFileNameOut = CPLStrdup(pszTFW);
    1818              11 :         return TRUE;
    1819                 :     }
    1820               0 :     return FALSE;
    1821                 : }
    1822                 : 
    1823                 : /************************************************************************/
    1824                 : /*                         GDALWriteWorldFile()                          */
    1825                 : /*                                                                      */
    1826                 : /*      Helper function for translator implementators wanting           */
    1827                 : /*      support for ESRI world files.                                   */
    1828                 : /************************************************************************/
    1829                 : 
    1830                 : /**
    1831                 :  * \brief Write ESRI world file. 
    1832                 :  *
    1833                 :  * This function writes an ESRI style world file from the passed geotransform.
    1834                 :  *
    1835                 :  * The world file contains an affine transformation with the parameters
    1836                 :  * in a different order than in a geotransform array. 
    1837                 :  *
    1838                 :  * <ul>
    1839                 :  * <li> geotransform[1] : width of pixel
    1840                 :  * <li> geotransform[4] : rotational coefficient, zero for north up images.
    1841                 :  * <li> geotransform[2] : rotational coefficient, zero for north up images.
    1842                 :  * <li> geotransform[5] : height of pixel (but negative)
    1843                 :  * <li> geotransform[0] + 0.5 * geotransform[1] + 0.5 * geotransform[2] : x offset to center of top left pixel.
    1844                 :  * <li> geotransform[3] + 0.5 * geotransform[4] + 0.5 * geotransform[5] : y offset to center of top left pixel.
    1845                 :  * </ul>
    1846                 :  *
    1847                 :  * @param pszBaseFilename the target raster file.
    1848                 :  * @param pszExtension the extension to use (ie. ".wld"). Must not be NULL
    1849                 :  * @param padfGeoTransform the six double array from which the 
    1850                 :  * geotransformation should be read. 
    1851                 :  *
    1852                 :  * @return TRUE on success or FALSE on failure.
    1853                 :  */
    1854                 : 
    1855                 : int CPL_STDCALL 
    1856               7 : GDALWriteWorldFile( const char * pszBaseFilename, const char *pszExtension,
    1857                 :                     double *padfGeoTransform )
    1858                 : 
    1859                 : {
    1860               7 :     VALIDATE_POINTER1( pszBaseFilename, "GDALWriteWorldFile", FALSE );
    1861               7 :     VALIDATE_POINTER1( pszExtension, "GDALWriteWorldFile", FALSE );
    1862               7 :     VALIDATE_POINTER1( padfGeoTransform, "GDALWriteWorldFile", FALSE );
    1863                 : 
    1864                 : /* -------------------------------------------------------------------- */
    1865                 : /*      Prepare the text to write to the file.                          */
    1866                 : /* -------------------------------------------------------------------- */
    1867               7 :     CPLString osTFWText;
    1868                 : 
    1869                 :     osTFWText.Printf( "%.10f\n%.10f\n%.10f\n%.10f\n%.10f\n%.10f\n", 
    1870                 :                       padfGeoTransform[1],
    1871                 :                       padfGeoTransform[4],
    1872                 :                       padfGeoTransform[2],
    1873                 :                       padfGeoTransform[5],
    1874               7 :                       padfGeoTransform[0] 
    1875               7 :                       + 0.5 * padfGeoTransform[1]
    1876               7 :                       + 0.5 * padfGeoTransform[2],
    1877               7 :                       padfGeoTransform[3]
    1878               7 :                       + 0.5 * padfGeoTransform[4]
    1879              21 :                       + 0.5 * padfGeoTransform[5] );
    1880                 : 
    1881                 : /* -------------------------------------------------------------------- */
    1882                 : /*      Update extention, and write to disk.                            */
    1883                 : /* -------------------------------------------------------------------- */
    1884                 :     const char  *pszTFW;
    1885                 :     VSILFILE    *fpTFW;
    1886                 : 
    1887               7 :     pszTFW = CPLResetExtension( pszBaseFilename, pszExtension );
    1888               7 :     fpTFW = VSIFOpenL( pszTFW, "wt" );
    1889               7 :     if( fpTFW == NULL )
    1890               0 :         return FALSE;
    1891                 : 
    1892               7 :     VSIFWriteL( (void *) osTFWText.c_str(), 1, osTFWText.size(), fpTFW );
    1893               7 :     VSIFCloseL( fpTFW );
    1894                 : 
    1895               7 :     return TRUE;
    1896                 : }
    1897                 : 
    1898                 : /************************************************************************/
    1899                 : /*                          GDALVersionInfo()                           */
    1900                 : /************************************************************************/
    1901                 : 
    1902                 : /**
    1903                 :  * \brief Get runtime version information.
    1904                 :  *
    1905                 :  * Available pszRequest values:
    1906                 :  * <ul>
    1907                 :  * <li> "VERSION_NUM": Returns GDAL_VERSION_NUM formatted as a string.  ie. "1170"
    1908                 :  *      Note: starting with GDAL 1.10, this string will be longer than 4 characters.
    1909                 :  * <li> "RELEASE_DATE": Returns GDAL_RELEASE_DATE formatted as a string.  
    1910                 :  * ie. "20020416".
    1911                 :  * <li> "RELEASE_NAME": Returns the GDAL_RELEASE_NAME. ie. "1.1.7"
    1912                 :  * <li> "--version": Returns one line version message suitable for use in 
    1913                 :  * response to --version requests.  ie. "GDAL 1.1.7, released 2002/04/16"
    1914                 :  * <li> "LICENCE": Returns the content of the LICENSE.TXT file from the GDAL_DATA directory.
    1915                 :  *      Before GDAL 1.7.0, the returned string was leaking memory but this is now resolved.
    1916                 :  *      So the result should not been freed by the caller.
    1917                 :  * <li> "BUILD_INFO": List of NAME=VALUE pairs separated by newlines with 
    1918                 :  * information on build time options.
    1919                 :  * </ul>
    1920                 :  *
    1921                 :  * @param pszRequest the type of version info desired, as listed above.
    1922                 :  *
    1923                 :  * @return an internal string containing the requested information.
    1924                 :  */
    1925                 : 
    1926            2548 : const char * CPL_STDCALL GDALVersionInfo( const char *pszRequest )
    1927                 : 
    1928                 : {
    1929                 : /* -------------------------------------------------------------------- */
    1930                 : /*      Try to capture as much build information as practical.          */
    1931                 : /* -------------------------------------------------------------------- */
    1932            2548 :     if( pszRequest != NULL && EQUAL(pszRequest,"BUILD_INFO") ) 
    1933                 :     {
    1934               1 :         CPLString osBuildInfo;
    1935                 : 
    1936                 : #ifdef ESRI_BUILD
    1937                 :         osBuildInfo += "ESRI_BUILD=YES\n";
    1938                 : #endif
    1939                 : #ifdef PAM_ENABLED
    1940               1 :         osBuildInfo += "PAM_ENABLED=YES\n";
    1941                 : #endif
    1942                 : #ifdef OGR_ENABLED
    1943               1 :         osBuildInfo += "OGR_ENABLED=YES\n";
    1944                 : #endif
    1945                 : 
    1946               1 :         CPLFree(CPLGetTLS(CTLS_VERSIONINFO));
    1947               1 :         CPLSetTLS(CTLS_VERSIONINFO, CPLStrdup(osBuildInfo), TRUE );
    1948               1 :         return (char *) CPLGetTLS(CTLS_VERSIONINFO);
    1949                 :     }
    1950                 : 
    1951                 : /* -------------------------------------------------------------------- */
    1952                 : /*      LICENSE is a special case. We try to find and read the          */
    1953                 : /*      LICENSE.TXT file from the GDAL_DATA directory and return it     */
    1954                 : /* -------------------------------------------------------------------- */
    1955            2547 :     if( pszRequest != NULL && EQUAL(pszRequest,"LICENSE") )
    1956                 :     {
    1957               0 :         char* pszResultLicence = (char*) CPLGetTLS( CTLS_VERSIONINFO_LICENCE );
    1958               0 :         if( pszResultLicence != NULL )
    1959                 :         {
    1960               0 :             return pszResultLicence;
    1961                 :         }
    1962                 : 
    1963               0 :         const char *pszFilename = CPLFindFile( "etc", "LICENSE.TXT" );
    1964               0 :         VSILFILE *fp = NULL;
    1965                 :         int  nLength;
    1966                 : 
    1967               0 :         if( pszFilename != NULL )
    1968               0 :             fp = VSIFOpenL( pszFilename, "r" );
    1969                 : 
    1970               0 :         if( fp != NULL )
    1971                 :         {
    1972               0 :             VSIFSeekL( fp, 0, SEEK_END );
    1973               0 :             nLength = (int) VSIFTellL( fp ) + 1;
    1974               0 :             VSIFSeekL( fp, SEEK_SET, 0 );
    1975                 : 
    1976               0 :             pszResultLicence = (char *) VSICalloc(1,nLength);
    1977               0 :             if (pszResultLicence)
    1978               0 :                 VSIFReadL( pszResultLicence, 1, nLength-1, fp );
    1979                 : 
    1980               0 :             VSIFCloseL( fp );
    1981                 :         }
    1982                 : 
    1983               0 :         if (!pszResultLicence)
    1984                 :         {
    1985                 :             pszResultLicence = CPLStrdup(
    1986                 :                      "GDAL/OGR is released under the MIT/X license.\n"
    1987                 :                      "The LICENSE.TXT distributed with GDAL/OGR should\n"
    1988               0 :                      "contain additional details.\n" );
    1989                 :         }
    1990                 : 
    1991               0 :         CPLSetTLS( CTLS_VERSIONINFO_LICENCE, pszResultLicence, TRUE );
    1992               0 :         return pszResultLicence;
    1993                 :     }
    1994                 : 
    1995                 : /* -------------------------------------------------------------------- */
    1996                 : /*      All other strings are fairly small.                             */
    1997                 : /* -------------------------------------------------------------------- */
    1998            2547 :     CPLString osVersionInfo;
    1999                 : 
    2000            4961 :     if( pszRequest == NULL || EQUAL(pszRequest,"VERSION_NUM") )
    2001            2414 :         osVersionInfo.Printf( "%d", GDAL_VERSION_NUM );
    2002             133 :     else if( EQUAL(pszRequest,"RELEASE_DATE") )
    2003               0 :         osVersionInfo.Printf( "%d", GDAL_RELEASE_DATE );
    2004             133 :     else if( EQUAL(pszRequest,"RELEASE_NAME") )
    2005              32 :         osVersionInfo.Printf( GDAL_RELEASE_NAME );
    2006                 :     else // --version
    2007                 :         osVersionInfo.Printf( "GDAL %s, released %d/%02d/%02d",
    2008                 :                               GDAL_RELEASE_NAME, 
    2009                 :                               GDAL_RELEASE_DATE / 10000, 
    2010                 :                               (GDAL_RELEASE_DATE % 10000) / 100,
    2011             101 :                               GDAL_RELEASE_DATE % 100 );
    2012                 : 
    2013            2547 :     CPLFree(CPLGetTLS(CTLS_VERSIONINFO)); // clear old value.
    2014            2547 :     CPLSetTLS(CTLS_VERSIONINFO, CPLStrdup(osVersionInfo), TRUE ); 
    2015            2547 :     return (char *) CPLGetTLS(CTLS_VERSIONINFO);
    2016                 : }
    2017                 : 
    2018                 : /************************************************************************/
    2019                 : /*                         GDALCheckVersion()                           */
    2020                 : /************************************************************************/
    2021                 : 
    2022                 : /** Return TRUE if GDAL library version at runtime matches nVersionMajor.nVersionMinor.
    2023                 : 
    2024                 :     The purpose of this method is to ensure that calling code will run with the GDAL
    2025                 :     version it is compiled for. It is primarly intented for external plugins.
    2026                 : 
    2027                 :     @param nVersionMajor Major version to be tested against
    2028                 :     @param nVersionMinor Minor version to be tested against
    2029                 :     @param pszCallingComponentName If not NULL, in case of version mismatch, the method
    2030                 :                                    will issue a failure mentionning the name of
    2031                 :                                    the calling component.
    2032                 : 
    2033                 :     @return TRUE if GDAL library version at runtime matches nVersionMajor.nVersionMinor, FALSE otherwise.
    2034                 :   */
    2035           14188 : int CPL_STDCALL GDALCheckVersion( int nVersionMajor, int nVersionMinor,
    2036                 :                                   const char* pszCallingComponentName)
    2037                 : {
    2038           14188 :     if (nVersionMajor == GDAL_VERSION_MAJOR &&
    2039                 :         nVersionMinor == GDAL_VERSION_MINOR)
    2040           14188 :         return TRUE;
    2041                 : 
    2042               0 :     if (pszCallingComponentName)
    2043                 :     {
    2044                 :         CPLError( CE_Failure, CPLE_AppDefined,
    2045                 :                   "%s was compiled against GDAL %d.%d but current library version is %d.%d\n",
    2046                 :                   pszCallingComponentName, nVersionMajor, nVersionMinor,
    2047               0 :                   GDAL_VERSION_MAJOR, GDAL_VERSION_MINOR);
    2048                 :     }
    2049               0 :     return FALSE;
    2050                 : }
    2051                 : 
    2052                 : /************************************************************************/
    2053                 : /*                            GDALDecToDMS()                            */
    2054                 : /*                                                                      */
    2055                 : /*      Translate a decimal degrees value to a DMS string with          */
    2056                 : /*      hemisphere.                                                     */
    2057                 : /************************************************************************/
    2058                 : 
    2059             260 : const char * CPL_STDCALL GDALDecToDMS( double dfAngle, const char * pszAxis,
    2060                 :                           int nPrecision )
    2061                 : 
    2062                 : {
    2063             260 :     return CPLDecToDMS( dfAngle, pszAxis, nPrecision );
    2064                 : }
    2065                 : 
    2066                 : /************************************************************************/
    2067                 : /*                         GDALPackedDMSToDec()                         */
    2068                 : /************************************************************************/
    2069                 : 
    2070                 : /**
    2071                 :  * \brief Convert a packed DMS value (DDDMMMSSS.SS) into decimal degrees.
    2072                 :  *
    2073                 :  * See CPLPackedDMSToDec().
    2074                 :  */
    2075                 : 
    2076               4 : double CPL_STDCALL GDALPackedDMSToDec( double dfPacked )
    2077                 : 
    2078                 : {
    2079               4 :     return CPLPackedDMSToDec( dfPacked );
    2080                 : }
    2081                 : 
    2082                 : /************************************************************************/
    2083                 : /*                         GDALDecToPackedDMS()                         */
    2084                 : /************************************************************************/
    2085                 : 
    2086                 : /**
    2087                 :  * \brief Convert decimal degrees into packed DMS value (DDDMMMSSS.SS).
    2088                 :  *
    2089                 :  * See CPLDecToPackedDMS().
    2090                 :  */
    2091                 : 
    2092               4 : double CPL_STDCALL GDALDecToPackedDMS( double dfDec )
    2093                 : 
    2094                 : {
    2095               4 :     return CPLDecToPackedDMS( dfDec );
    2096                 : }
    2097                 : 
    2098                 : /************************************************************************/
    2099                 : /*                       GDALGCPsToGeoTransform()                       */
    2100                 : /************************************************************************/
    2101                 : 
    2102                 : /**
    2103                 :  * \brief Generate Geotransform from GCPs. 
    2104                 :  *
    2105                 :  * Given a set of GCPs perform first order fit as a geotransform. 
    2106                 :  *
    2107                 :  * Due to imprecision in the calculations the fit algorithm will often 
    2108                 :  * return non-zero rotational coefficients even if given perfectly non-rotated
    2109                 :  * inputs.  A special case has been implemented for corner corner coordinates
    2110                 :  * given in TL, TR, BR, BL order.  So when using this to get a geotransform
    2111                 :  * from 4 corner coordinates, pass them in this order. 
    2112                 :  * 
    2113                 :  * @param nGCPCount the number of GCPs being passed in.
    2114                 :  * @param pasGCPs the list of GCP structures. 
    2115                 :  * @param padfGeoTransform the six double array in which the affine 
    2116                 :  * geotransformation will be returned. 
    2117                 :  * @param bApproxOK If FALSE the function will fail if the geotransform is not 
    2118                 :  * essentially an exact fit (within 0.25 pixel) for all GCPs. 
    2119                 :  * 
    2120                 :  * @return TRUE on success or FALSE if there aren't enough points to prepare a
    2121                 :  * geotransform, the pointers are ill-determined or if bApproxOK is FALSE 
    2122                 :  * and the fit is poor.
    2123                 :  */
    2124                 : 
    2125                 : int CPL_STDCALL 
    2126             315 : GDALGCPsToGeoTransform( int nGCPCount, const GDAL_GCP *pasGCPs,
    2127                 :                         double *padfGeoTransform, int bApproxOK )
    2128                 : 
    2129                 : {
    2130                 :     int    i;
    2131                 : 
    2132                 : /* -------------------------------------------------------------------- */
    2133                 : /*      Recognise a few special cases.                                  */
    2134                 : /* -------------------------------------------------------------------- */
    2135             315 :     if( nGCPCount < 2 )
    2136               7 :         return FALSE;
    2137                 : 
    2138             308 :     if( nGCPCount == 2 )
    2139                 :     {
    2140               0 :         if( pasGCPs[1].dfGCPPixel == pasGCPs[0].dfGCPPixel 
    2141               0 :             || pasGCPs[1].dfGCPLine == pasGCPs[0].dfGCPLine )
    2142               0 :             return FALSE;
    2143                 : 
    2144               0 :         padfGeoTransform[1] = (pasGCPs[1].dfGCPX - pasGCPs[0].dfGCPX)
    2145               0 :             / (pasGCPs[1].dfGCPPixel - pasGCPs[0].dfGCPPixel);
    2146               0 :         padfGeoTransform[2] = 0.0;
    2147                 : 
    2148               0 :         padfGeoTransform[4] = 0.0;
    2149               0 :         padfGeoTransform[5] = (pasGCPs[1].dfGCPY - pasGCPs[0].dfGCPY)
    2150               0 :             / (pasGCPs[1].dfGCPLine - pasGCPs[0].dfGCPLine);
    2151                 :         
    2152                 :         padfGeoTransform[0] = pasGCPs[0].dfGCPX 
    2153               0 :             - pasGCPs[0].dfGCPPixel * padfGeoTransform[1]
    2154               0 :             - pasGCPs[0].dfGCPLine * padfGeoTransform[2];
    2155                 :         
    2156               0 :         padfGeoTransform[3] = pasGCPs[0].dfGCPY 
    2157               0 :             - pasGCPs[0].dfGCPPixel * padfGeoTransform[4]
    2158               0 :             - pasGCPs[0].dfGCPLine * padfGeoTransform[5];
    2159                 : 
    2160               0 :         return TRUE;
    2161                 :     }
    2162                 : 
    2163                 : /* -------------------------------------------------------------------- */
    2164                 : /*      Special case of 4 corner coordinates of a non-rotated           */
    2165                 : /*      image.  The points must be in TL-TR-BR-BL order for now.        */
    2166                 : /*      This case helps avoid some imprecision in the general           */
    2167                 : /*      calcuations.                                                    */
    2168                 : /* -------------------------------------------------------------------- */
    2169            3039 :     if( nGCPCount == 4 
    2170             305 :         && pasGCPs[0].dfGCPLine == pasGCPs[1].dfGCPLine
    2171             344 :         && pasGCPs[2].dfGCPLine == pasGCPs[3].dfGCPLine
    2172             172 :         && pasGCPs[0].dfGCPPixel == pasGCPs[3].dfGCPPixel
    2173             344 :         && pasGCPs[1].dfGCPPixel == pasGCPs[2].dfGCPPixel
    2174             172 :         && pasGCPs[0].dfGCPLine != pasGCPs[2].dfGCPLine
    2175             170 :         && pasGCPs[0].dfGCPPixel != pasGCPs[1].dfGCPPixel 
    2176             170 :         && pasGCPs[0].dfGCPY == pasGCPs[1].dfGCPY
    2177             314 :         && pasGCPs[2].dfGCPY == pasGCPs[3].dfGCPY
    2178             157 :         && pasGCPs[0].dfGCPX == pasGCPs[3].dfGCPX
    2179             314 :         && pasGCPs[1].dfGCPX == pasGCPs[2].dfGCPX
    2180             157 :         && pasGCPs[0].dfGCPY != pasGCPs[2].dfGCPY
    2181             112 :         && pasGCPs[0].dfGCPX != pasGCPs[1].dfGCPX )
    2182                 :     {
    2183             112 :         padfGeoTransform[1] = (pasGCPs[1].dfGCPX - pasGCPs[0].dfGCPX)
    2184             112 :             / (pasGCPs[1].dfGCPPixel - pasGCPs[0].dfGCPPixel);
    2185             112 :         padfGeoTransform[2] = 0.0;
    2186             112 :         padfGeoTransform[4] = 0.0;
    2187             224 :         padfGeoTransform[5] = (pasGCPs[2].dfGCPY - pasGCPs[1].dfGCPY)
    2188             224 :             / (pasGCPs[2].dfGCPLine - pasGCPs[1].dfGCPLine);
    2189                 : 
    2190                 :         padfGeoTransform[0] = 
    2191             112 :             pasGCPs[0].dfGCPX - pasGCPs[0].dfGCPPixel * padfGeoTransform[1];
    2192             112 :         padfGeoTransform[3] = 
    2193             112 :             pasGCPs[0].dfGCPY - pasGCPs[0].dfGCPLine * padfGeoTransform[5];
    2194             112 :         return TRUE;
    2195                 :     }
    2196                 : 
    2197                 : /* -------------------------------------------------------------------- */
    2198                 : /* In the general case, do a least squares error approximation by       */
    2199                 : /* solving the equation Sum[(A - B*x + C*y - Lon)^2] = minimum    */
    2200                 : /* -------------------------------------------------------------------- */
    2201                 :   
    2202             196 :     double sum_x = 0.0, sum_y = 0.0, sum_xy = 0.0, sum_xx = 0.0, sum_yy = 0.0;
    2203             196 :     double sum_Lon = 0.0, sum_Lonx = 0.0, sum_Lony = 0.0;
    2204             196 :     double sum_Lat = 0.0, sum_Latx = 0.0, sum_Laty = 0.0;
    2205                 :     double divisor;
    2206                 : 
    2207             983 :     for (i = 0; i < nGCPCount; ++i) {
    2208             787 :         sum_x += pasGCPs[i].dfGCPPixel;
    2209             787 :         sum_y += pasGCPs[i].dfGCPLine;
    2210             787 :         sum_xy += pasGCPs[i].dfGCPPixel * pasGCPs[i].dfGCPLine;
    2211             787 :         sum_xx += pasGCPs[i].dfGCPPixel * pasGCPs[i].dfGCPPixel;
    2212             787 :         sum_yy += pasGCPs[i].dfGCPLine * pasGCPs[i].dfGCPLine;
    2213             787 :         sum_Lon += pasGCPs[i].dfGCPX;
    2214             787 :         sum_Lonx += pasGCPs[i].dfGCPX * pasGCPs[i].dfGCPPixel;
    2215             787 :         sum_Lony += pasGCPs[i].dfGCPX * pasGCPs[i].dfGCPLine;
    2216             787 :         sum_Lat += pasGCPs[i].dfGCPY;
    2217             787 :         sum_Latx += pasGCPs[i].dfGCPY * pasGCPs[i].dfGCPPixel;
    2218             787 :         sum_Laty += pasGCPs[i].dfGCPY * pasGCPs[i].dfGCPLine;
    2219                 :     }
    2220                 : 
    2221                 :     divisor = nGCPCount * (sum_xx * sum_yy - sum_xy * sum_xy)
    2222                 :         + 2 * sum_x * sum_y * sum_xy - sum_y * sum_y * sum_xx
    2223             196 :         - sum_x * sum_x * sum_yy;
    2224                 : 
    2225                 : /* -------------------------------------------------------------------- */
    2226                 : /*      If the divisor is zero, there is no valid solution.             */
    2227                 : /* -------------------------------------------------------------------- */
    2228             196 :     if (divisor == 0.0)
    2229               2 :         return FALSE;
    2230                 : 
    2231                 : /* -------------------------------------------------------------------- */
    2232                 : /*      Compute top/left origin.                                        */
    2233                 : /* -------------------------------------------------------------------- */
    2234                 : 
    2235                 :     padfGeoTransform[0] = (sum_Lon * (sum_xx * sum_yy - sum_xy * sum_xy)
    2236                 :                            + sum_Lonx * (sum_y * sum_xy - sum_x *  sum_yy)
    2237                 :                            + sum_Lony * (sum_x * sum_xy - sum_y * sum_xx))
    2238             194 :         / divisor;
    2239                 : 
    2240             194 :     padfGeoTransform[3] = (sum_Lat * (sum_xx * sum_yy - sum_xy * sum_xy)
    2241                 :                            + sum_Latx * (sum_y * sum_xy - sum_x *  sum_yy)
    2242                 :                            + sum_Laty * (sum_x * sum_xy - sum_y * sum_xx)) 
    2243             194 :         / divisor;
    2244                 : 
    2245                 : /* -------------------------------------------------------------------- */
    2246                 : /*      Compute X related coefficients.                                 */
    2247                 : /* -------------------------------------------------------------------- */
    2248             194 :     padfGeoTransform[1] = (sum_Lon * (sum_y * sum_xy - sum_x * sum_yy)
    2249                 :                            + sum_Lonx * (nGCPCount * sum_yy - sum_y * sum_y)
    2250                 :                            + sum_Lony * (sum_x * sum_y - sum_xy * nGCPCount))
    2251             194 :         / divisor;
    2252                 : 
    2253             194 :     padfGeoTransform[2] = (sum_Lon * (sum_x * sum_xy - sum_y * sum_xx)
    2254                 :                            + sum_Lonx * (sum_x * sum_y - nGCPCount * sum_xy)
    2255                 :                            + sum_Lony * (nGCPCount * sum_xx - sum_x * sum_x))
    2256             194 :         / divisor;
    2257                 : 
    2258                 : /* -------------------------------------------------------------------- */
    2259                 : /*      Compute Y related coefficients.                                 */
    2260                 : /* -------------------------------------------------------------------- */
    2261             194 :     padfGeoTransform[4] = (sum_Lat * (sum_y * sum_xy - sum_x * sum_yy)
    2262                 :                            + sum_Latx * (nGCPCount * sum_yy - sum_y * sum_y)
    2263                 :                            + sum_Laty * (sum_x * sum_y - sum_xy * nGCPCount))
    2264             194 :         / divisor;
    2265                 : 
    2266             194 :     padfGeoTransform[5] = (sum_Lat * (sum_x * sum_xy - sum_y * sum_xx)
    2267                 :                            + sum_Latx * (sum_x * sum_y - nGCPCount * sum_xy)
    2268                 :                            + sum_Laty * (nGCPCount * sum_xx - sum_x * sum_x))
    2269             194 :         / divisor;
    2270                 : 
    2271                 : /* -------------------------------------------------------------------- */
    2272                 : /*      Now check if any of the input points fit this poorly.           */
    2273                 : /* -------------------------------------------------------------------- */
    2274             194 :     if( !bApproxOK )
    2275                 :     {
    2276             388 :         double dfPixelSize = ABS(padfGeoTransform[1]) 
    2277             388 :             + ABS(padfGeoTransform[2])
    2278             388 :             + ABS(padfGeoTransform[4])
    2279            1164 :             + ABS(padfGeoTransform[5]);
    2280                 : 
    2281             956 :         for( i = 0; i < nGCPCount; i++ )
    2282                 :         {
    2283                 :             double      dfErrorX, dfErrorY;
    2284                 : 
    2285                 :             dfErrorX = 
    2286            1532 :                 (pasGCPs[i].dfGCPPixel * padfGeoTransform[1]
    2287            1532 :                  + pasGCPs[i].dfGCPLine * padfGeoTransform[2]
    2288             766 :                  + padfGeoTransform[0]) 
    2289            3830 :                 - pasGCPs[i].dfGCPX;
    2290                 :             dfErrorY = 
    2291            1532 :                 (pasGCPs[i].dfGCPPixel * padfGeoTransform[4]
    2292            1532 :                  + pasGCPs[i].dfGCPLine * padfGeoTransform[5]
    2293             766 :                  + padfGeoTransform[3]) 
    2294            3830 :                 - pasGCPs[i].dfGCPY;
    2295                 : 
    2296             766 :             if( ABS(dfErrorX) > 0.25 * dfPixelSize 
    2297                 :                 || ABS(dfErrorY) > 0.25 * dfPixelSize )
    2298               4 :                 return FALSE;
    2299                 :         }
    2300                 :     }
    2301                 : 
    2302             190 :     return TRUE;
    2303                 : }
    2304                 : 
    2305                 : /************************************************************************/
    2306                 : /*                    GDALGeneralCmdLineProcessor()                     */
    2307                 : /************************************************************************/
    2308                 : 
    2309                 : /**
    2310                 :  * \brief General utility option processing.
    2311                 :  *
    2312                 :  * This function is intended to provide a variety of generic commandline 
    2313                 :  * options for all GDAL commandline utilities.  It takes care of the following
    2314                 :  * commandline options:
    2315                 :  *  
    2316                 :  *  --version: report version of GDAL in use. 
    2317                 :  *  --build: report build info about GDAL in use.
    2318                 :  *  --license: report GDAL license info.
    2319                 :  *  --formats: report all format drivers configured.
    2320                 :  *  --format [format]: report details of one format driver. 
    2321                 :  *  --optfile filename: expand an option file into the argument list. 
    2322                 :  *  --config key value: set system configuration option. 
    2323                 :  *  --debug [on/off/value]: set debug level.
    2324                 :  *  --mempreload dir: preload directory contents into /vsimem
    2325                 :  *  --pause: Pause for user input (allows time to attach debugger)
    2326                 :  *  --locale [locale]: Install a locale using setlocale() (debugging)
    2327                 :  *  --help-general: report detailed help on general options. 
    2328                 :  *
    2329                 :  * The argument array is replaced "in place" and should be freed with 
    2330                 :  * CSLDestroy() when no longer needed.  The typical usage looks something
    2331                 :  * like the following.  Note that the formats should be registered so that
    2332                 :  * the --formats and --format options will work properly.
    2333                 :  *
    2334                 :  *  int main( int argc, char ** argv )
    2335                 :  *  { 
    2336                 :  *    GDALAllRegister();
    2337                 :  *
    2338                 :  *    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
    2339                 :  *    if( argc < 1 )
    2340                 :  *        exit( -argc );
    2341                 :  *
    2342                 :  * @param nArgc number of values in the argument list.
    2343                 :  * @param ppapszArgv pointer to the argument list array (will be updated in place).
    2344                 :  * @param nOptions unused for now.
    2345                 :  *
    2346                 :  * @return updated nArgc argument count.  Return of 0 requests terminate 
    2347                 :  * without error, return of -1 requests exit with error code.
    2348                 :  */
    2349                 : 
    2350                 : int CPL_STDCALL 
    2351             601 : GDALGeneralCmdLineProcessor( int nArgc, char ***ppapszArgv, int nOptions )
    2352                 : 
    2353                 : {
    2354             601 :     char **papszReturn = NULL;
    2355                 :     int  iArg;
    2356             601 :     char **papszArgv = *ppapszArgv;
    2357                 : 
    2358                 :     (void) nOptions;
    2359                 :     
    2360                 : /* -------------------------------------------------------------------- */
    2361                 : /*      Preserve the program name.                                      */
    2362                 : /* -------------------------------------------------------------------- */
    2363             601 :     papszReturn = CSLAddString( papszReturn, papszArgv[0] );
    2364                 : 
    2365                 : /* ==================================================================== */
    2366                 : /*      Loop over all arguments.                                        */
    2367                 : /* ==================================================================== */
    2368            3604 :     for( iArg = 1; iArg < nArgc; iArg++ )
    2369                 :     {
    2370                 : /* -------------------------------------------------------------------- */
    2371                 : /*      --version                                                       */
    2372                 : /* -------------------------------------------------------------------- */
    2373            3003 :         if( EQUAL(papszArgv[iArg],"--version") )
    2374                 :         {
    2375               0 :             printf( "%s\n", GDALVersionInfo( "--version" ) );
    2376               0 :             CSLDestroy( papszReturn );
    2377               0 :             return 0;
    2378                 :         }
    2379                 : 
    2380                 : /* -------------------------------------------------------------------- */
    2381                 : /*      --build                                                         */
    2382                 : /* -------------------------------------------------------------------- */
    2383            3003 :         else if( EQUAL(papszArgv[iArg],"--build") )
    2384                 :         {
    2385               0 :             printf( "%s", GDALVersionInfo( "BUILD_INFO" ) );
    2386               0 :             CSLDestroy( papszReturn );
    2387               0 :             return 0;
    2388                 :         }
    2389                 : 
    2390                 : /* -------------------------------------------------------------------- */
    2391                 : /*      --license                                                       */
    2392                 : /* -------------------------------------------------------------------- */
    2393            3003 :         else if( EQUAL(papszArgv[iArg],"--license") )
    2394                 :         {
    2395               0 :             printf( "%s\n", GDALVersionInfo( "LICENSE" ) );
    2396               0 :             CSLDestroy( papszReturn );
    2397               0 :             return 0;
    2398                 :         }
    2399                 : 
    2400                 : /* -------------------------------------------------------------------- */
    2401                 : /*      --config                                                        */
    2402                 : /* -------------------------------------------------------------------- */
    2403            3003 :         else if( EQUAL(papszArgv[iArg],"--config") )
    2404                 :         {
    2405               8 :             if( iArg + 2 >= nArgc )
    2406                 :             {
    2407                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
    2408               0 :                           "--config option given without a key and value argument." );
    2409               0 :                 CSLDestroy( papszReturn );
    2410               0 :                 return -1;
    2411                 :             }
    2412                 : 
    2413               8 :             CPLSetConfigOption( papszArgv[iArg+1], papszArgv[iArg+2] );
    2414                 : 
    2415               8 :             iArg += 2;
    2416                 :         }
    2417                 : 
    2418                 : /* -------------------------------------------------------------------- */
    2419                 : /*      --mempreload                                                    */
    2420                 : /* -------------------------------------------------------------------- */
    2421            2995 :         else if( EQUAL(papszArgv[iArg],"--mempreload") )
    2422                 :         {
    2423                 :             int i;
    2424                 : 
    2425               0 :             if( iArg + 1 >= nArgc )
    2426                 :             {
    2427                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
    2428               0 :                           "--mempreload option given without directory path.");
    2429               0 :                 CSLDestroy( papszReturn );
    2430               0 :                 return -1;
    2431                 :             }
    2432                 :             
    2433               0 :             char **papszFiles = CPLReadDir( papszArgv[iArg+1] );
    2434               0 :             if( CSLCount(papszFiles) == 0 )
    2435                 :             {
    2436                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
    2437               0 :                           "--mempreload given invalid or empty directory.");
    2438               0 :                 CSLDestroy( papszReturn );
    2439               0 :                 return -1;
    2440                 :             }
    2441                 :                 
    2442               0 :             for( i = 0; papszFiles[i] != NULL; i++ )
    2443                 :             {
    2444               0 :                 CPLString osOldPath, osNewPath;
    2445                 :                 VSIStatBufL sStatBuf;
    2446                 :                 
    2447               0 :                 if( EQUAL(papszFiles[i],".") || EQUAL(papszFiles[i],"..") )
    2448               0 :                     continue;
    2449                 : 
    2450               0 :                 osOldPath = CPLFormFilename( papszArgv[iArg+1], 
    2451               0 :                                              papszFiles[i], NULL );
    2452               0 :                 osNewPath.Printf( "/vsimem/%s", papszFiles[i] );
    2453                 : 
    2454               0 :                 if( VSIStatL( osOldPath, &sStatBuf ) != 0
    2455                 :                     || VSI_ISDIR( sStatBuf.st_mode ) )
    2456                 :                 {
    2457                 :                     CPLDebug( "VSI", "Skipping preload of %s.", 
    2458               0 :                               osOldPath.c_str() );
    2459               0 :                     continue;
    2460                 :                 }
    2461                 : 
    2462                 :                 CPLDebug( "VSI", "Preloading %s to %s.", 
    2463               0 :                           osOldPath.c_str(), osNewPath.c_str() );
    2464                 : 
    2465               0 :                 if( CPLCopyFile( osNewPath, osOldPath ) != 0 )
    2466                 :                 {
    2467                 :                     CPLError( CE_Failure, CPLE_AppDefined,
    2468                 :                               "Failed to copy %s to /vsimem", 
    2469               0 :                               osOldPath.c_str() );
    2470               0 :                     return -1;
    2471                 :                 }
    2472                 :             }
    2473                 :             
    2474               0 :             CSLDestroy( papszFiles );
    2475               0 :             iArg += 1;
    2476                 :         }
    2477                 : 
    2478                 : /* -------------------------------------------------------------------- */
    2479                 : /*      --debug                                                         */
    2480                 : /* -------------------------------------------------------------------- */
    2481            2995 :         else if( EQUAL(papszArgv[iArg],"--debug") )
    2482                 :         {
    2483               0 :             if( iArg + 1 >= nArgc )
    2484                 :             {
    2485                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
    2486               0 :                           "--debug option given without debug level." );
    2487               0 :                 CSLDestroy( papszReturn );
    2488               0 :                 return -1;
    2489                 :             }
    2490                 : 
    2491               0 :             CPLSetConfigOption( "CPL_DEBUG", papszArgv[iArg+1] );
    2492               0 :             iArg += 1;
    2493                 :         }
    2494                 : 
    2495                 : /* -------------------------------------------------------------------- */
    2496                 : /*      --optfile                                                       */
    2497                 : /*                                                                      */
    2498                 : /*      Annoyingly the options inserted by --optfile will *not* be      */
    2499                 : /*      processed properly if they are general options.                 */
    2500                 : /* -------------------------------------------------------------------- */
    2501            2995 :         else if( EQUAL(papszArgv[iArg],"--optfile") )
    2502                 :         {
    2503                 :             const char *pszLine;
    2504                 :             FILE *fpOptFile;
    2505                 : 
    2506               0 :             if( iArg + 1 >= nArgc )
    2507                 :             {
    2508                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
    2509               0 :                           "--optfile option given without filename." );
    2510               0 :                 CSLDestroy( papszReturn );
    2511               0 :                 return -1;
    2512                 :             }
    2513                 : 
    2514               0 :             fpOptFile = VSIFOpen( papszArgv[iArg+1], "rb" );
    2515                 : 
    2516               0 :             if( fpOptFile == NULL )
    2517                 :             {
    2518                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
    2519                 :                           "Unable to open optfile '%s'.\n%s",
    2520               0 :                           papszArgv[iArg+1], VSIStrerror( errno ) );
    2521               0 :                 CSLDestroy( papszReturn );
    2522               0 :                 return -1;
    2523                 :             }
    2524                 :             
    2525               0 :             while( (pszLine = CPLReadLine( fpOptFile )) != NULL )
    2526                 :             {
    2527                 :                 char **papszTokens;
    2528                 :                 int i;
    2529                 : 
    2530               0 :                 if( pszLine[0] == '#' || strlen(pszLine) == 0 )
    2531               0 :                     continue;
    2532                 : 
    2533               0 :                 papszTokens = CSLTokenizeString( pszLine );
    2534               0 :                 for( i = 0; papszTokens != NULL && papszTokens[i] != NULL; i++)
    2535               0 :                     papszReturn = CSLAddString( papszReturn, papszTokens[i] );
    2536               0 :                 CSLDestroy( papszTokens );
    2537                 :             }
    2538                 : 
    2539               0 :             VSIFClose( fpOptFile );
    2540                 :                 
    2541               0 :             iArg += 1;
    2542                 :         }
    2543                 : 
    2544                 : /* -------------------------------------------------------------------- */
    2545                 : /*      --formats                                                       */
    2546                 : /* -------------------------------------------------------------------- */
    2547            2995 :         else if( EQUAL(papszArgv[iArg], "--formats") )
    2548                 :         {
    2549                 :             int iDr;
    2550                 : 
    2551               0 :             printf( "Supported Formats:\n" );
    2552               0 :             for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ )
    2553                 :             {
    2554               0 :                 GDALDriverH hDriver = GDALGetDriver(iDr);
    2555                 :                 const char *pszRWFlag, *pszVirtualIO;
    2556                 :                 
    2557               0 :                 if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) )
    2558               0 :                     pszRWFlag = "rw+";
    2559               0 :                 else if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY, 
    2560                 :                                               NULL ) )
    2561               0 :                     pszRWFlag = "rw";
    2562                 :                 else
    2563               0 :                     pszRWFlag = "ro";
    2564                 :                 
    2565               0 :                 if( GDALGetMetadataItem( hDriver, GDAL_DCAP_VIRTUALIO, NULL) )
    2566               0 :                     pszVirtualIO = "v";
    2567                 :                 else
    2568               0 :                     pszVirtualIO = "";
    2569                 : 
    2570                 :                 printf( "  %s (%s%s): %s\n",
    2571                 :                         GDALGetDriverShortName( hDriver ),
    2572                 :                         pszRWFlag, pszVirtualIO,
    2573               0 :                         GDALGetDriverLongName( hDriver ) );
    2574                 :             }
    2575                 : 
    2576               0 :             CSLDestroy( papszReturn );
    2577               0 :             return 0;
    2578                 :         }
    2579                 : 
    2580                 : /* -------------------------------------------------------------------- */
    2581                 : /*      --format                                                        */
    2582                 : /* -------------------------------------------------------------------- */
    2583            2995 :         else if( EQUAL(papszArgv[iArg], "--format") )
    2584                 :         {
    2585                 :             GDALDriverH hDriver;
    2586                 :             char **papszMD;
    2587                 : 
    2588               0 :             CSLDestroy( papszReturn );
    2589                 : 
    2590               0 :             if( iArg + 1 >= nArgc )
    2591                 :             {
    2592                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
    2593               0 :                           "--format option given without a format code." );
    2594               0 :                 return -1;
    2595                 :             }
    2596                 : 
    2597               0 :             hDriver = GDALGetDriverByName( papszArgv[iArg+1] );
    2598               0 :             if( hDriver == NULL )
    2599                 :             {
    2600                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
    2601                 :                           "--format option given with format '%s', but that format not\n"
    2602                 :                           "recognised.  Use the --formats option to get a list of available formats,\n"
    2603                 :                           "and use the short code (ie. GTiff or HFA) as the format identifier.\n", 
    2604               0 :                           papszArgv[iArg+1] );
    2605               0 :                 return -1;
    2606                 :             }
    2607                 : 
    2608               0 :             printf( "Format Details:\n" );
    2609               0 :             printf( "  Short Name: %s\n", GDALGetDriverShortName( hDriver ) );
    2610               0 :             printf( "  Long Name: %s\n", GDALGetDriverLongName( hDriver ) );
    2611                 : 
    2612               0 :             papszMD = GDALGetMetadata( hDriver, NULL );
    2613                 : 
    2614               0 :             if( CSLFetchNameValue( papszMD, GDAL_DMD_EXTENSION ) )
    2615                 :                 printf( "  Extension: %s\n", 
    2616               0 :                         CSLFetchNameValue( papszMD, GDAL_DMD_EXTENSION ) );
    2617               0 :             if( CSLFetchNameValue( papszMD, GDAL_DMD_MIMETYPE ) )
    2618                 :                 printf( "  Mime Type: %s\n", 
    2619               0 :                         CSLFetchNameValue( papszMD, GDAL_DMD_MIMETYPE ) );
    2620               0 :             if( CSLFetchNameValue( papszMD, GDAL_DMD_HELPTOPIC ) )
    2621                 :                 printf( "  Help Topic: %s\n", 
    2622               0 :                         CSLFetchNameValue( papszMD, GDAL_DMD_HELPTOPIC ) );
    2623                 :             
    2624               0 :             if( CSLFetchBoolean( papszMD, GDAL_DCAP_CREATE, FALSE ) )
    2625               0 :                 printf( "  Supports: Create() - Create writeable dataset.\n" );
    2626               0 :             if( CSLFetchBoolean( papszMD, GDAL_DCAP_CREATECOPY, FALSE ) )
    2627               0 :                 printf( "  Supports: CreateCopy() - Create dataset by copying another.\n" );
    2628               0 :             if( CSLFetchBoolean( papszMD, GDAL_DCAP_VIRTUALIO, FALSE ) )
    2629               0 :                 printf( "  Supports: Virtual IO - eg. /vsimem/\n" );
    2630               0 :             if( CSLFetchNameValue( papszMD, GDAL_DMD_CREATIONDATATYPES ) )
    2631                 :                 printf( "  Creation Datatypes: %s\n",
    2632               0 :                         CSLFetchNameValue( papszMD, GDAL_DMD_CREATIONDATATYPES ) );
    2633               0 :             if( CSLFetchNameValue( papszMD, GDAL_DMD_CREATIONOPTIONLIST ) )
    2634                 :             {
    2635                 :                 CPLXMLNode *psCOL = 
    2636                 :                     CPLParseXMLString( 
    2637                 :                         CSLFetchNameValue( papszMD, 
    2638               0 :                                            GDAL_DMD_CREATIONOPTIONLIST ) );
    2639                 :                 char *pszFormattedXML = 
    2640               0 :                     CPLSerializeXMLTree( psCOL );
    2641                 : 
    2642               0 :                 CPLDestroyXMLNode( psCOL );
    2643                 :                 
    2644               0 :                 printf( "\n%s\n", pszFormattedXML );
    2645               0 :                 CPLFree( pszFormattedXML );
    2646                 :             }
    2647               0 :             return 0;
    2648                 :         }
    2649                 : 
    2650                 : /* -------------------------------------------------------------------- */
    2651                 : /*      --help-general                                                  */
    2652                 : /* -------------------------------------------------------------------- */
    2653            2995 :         else if( EQUAL(papszArgv[iArg],"--help-general") )
    2654                 :         {
    2655               0 :             printf( "Generic GDAL utility command options:\n" );
    2656               0 :             printf( "  --version: report version of GDAL in use.\n" );
    2657               0 :             printf( "  --license: report GDAL license info.\n" );
    2658               0 :             printf( "  --formats: report all configured format drivers.\n" );
    2659               0 :             printf( "  --format [format]: details of one format.\n" );
    2660               0 :             printf( "  --optfile filename: expand an option file into the argument list.\n" );
    2661               0 :             printf( "  --config key value: set system configuration option.\n" );
    2662               0 :             printf( "  --debug [on/off/value]: set debug level.\n" );
    2663               0 :             printf( "  --pause: wait for user input, time to attach debugger\n" );
    2664               0 :             printf( "  --locale [locale]: install locale for debugging (ie. en_US.UTF-8)\n" );
    2665               0 :             printf( "  --help-general: report detailed help on general options.\n" );
    2666               0 :             CSLDestroy( papszReturn );
    2667               0 :             return 0;
    2668                 :         }
    2669                 : 
    2670                 : /* -------------------------------------------------------------------- */
    2671                 : /*      --locale                                                        */
    2672                 : /* -------------------------------------------------------------------- */
    2673            2995 :         else if( EQUAL(papszArgv[iArg],"--locale") && iArg < nArgc-1 )
    2674                 :         {
    2675               0 :             setlocale( LC_ALL, papszArgv[++iArg] );
    2676                 :         }
    2677                 : 
    2678                 : /* -------------------------------------------------------------------- */
    2679                 : /*      --pause                                                         */
    2680                 : /* -------------------------------------------------------------------- */
    2681            2995 :         else if( EQUAL(papszArgv[iArg],"--pause") )
    2682                 :         {
    2683               0 :             printf( "Hit <ENTER> to Continue.\n" );
    2684               0 :             CPLReadLine( stdin );
    2685                 :         }
    2686                 : 
    2687                 : /* -------------------------------------------------------------------- */
    2688                 : /*      carry through unrecognised options.                             */
    2689                 : /* -------------------------------------------------------------------- */
    2690                 :         else
    2691                 :         {
    2692            2995 :             papszReturn = CSLAddString( papszReturn, papszArgv[iArg] );
    2693                 :         }
    2694                 :     }
    2695                 : 
    2696             601 :     *ppapszArgv = papszReturn;
    2697                 : 
    2698             601 :     return CSLCount( *ppapszArgv );
    2699                 : }
    2700                 : 
    2701                 : 
    2702                 : /************************************************************************/
    2703                 : /*                          _FetchDblFromMD()                           */
    2704                 : /************************************************************************/
    2705                 : 
    2706              90 : static int _FetchDblFromMD( char **papszMD, const char *pszKey, 
    2707                 :                             double *padfTarget, int nCount, double dfDefault )
    2708                 : 
    2709                 : {
    2710                 :     char szFullKey[200];
    2711                 : 
    2712              90 :     sprintf( szFullKey, "%s", pszKey );
    2713                 : 
    2714              90 :     const char *pszValue = CSLFetchNameValue( papszMD, szFullKey );
    2715                 :     int i;
    2716                 :     
    2717             560 :     for( i = 0; i < nCount; i++ )
    2718             470 :         padfTarget[i] = dfDefault;
    2719                 : 
    2720              90 :     if( pszValue == NULL )
    2721              20 :         return FALSE;
    2722                 : 
    2723              70 :     if( nCount == 1 )
    2724                 :     {
    2725              50 :         *padfTarget = CPLAtofM( pszValue );
    2726              50 :         return TRUE;
    2727                 :     }
    2728                 : 
    2729                 :     char **papszTokens = CSLTokenizeStringComplex( pszValue, " ,", 
    2730              20 :                                                    FALSE, FALSE );
    2731                 : 
    2732              20 :     if( CSLCount( papszTokens ) != nCount )
    2733                 :     {
    2734               0 :         CSLDestroy( papszTokens );
    2735               0 :         return FALSE;
    2736                 :     }
    2737                 : 
    2738             420 :     for( i = 0; i < nCount; i++ )
    2739             400 :         padfTarget[i] = CPLAtofM(papszTokens[i]);
    2740                 : 
    2741              20 :     CSLDestroy( papszTokens );
    2742                 : 
    2743              20 :     return TRUE;
    2744                 : }
    2745                 : 
    2746                 : /************************************************************************/
    2747                 : /*                         GDALExtractRPCInfo()                         */
    2748                 : /*                                                                      */
    2749                 : /*      Extract RPC info from metadata, and apply to an RPCInfo         */
    2750                 : /*      structure.  The inverse of this function is RPCInfoToMD() in    */
    2751                 : /*      alg/gdal_rpc.cpp (should it be needed).                         */
    2752                 : /************************************************************************/
    2753                 : 
    2754               5 : int CPL_STDCALL GDALExtractRPCInfo( char **papszMD, GDALRPCInfo *psRPC )
    2755                 : 
    2756                 : {
    2757               5 :     if( CSLFetchNameValue( papszMD, "LINE_NUM_COEFF" ) == NULL )
    2758               0 :         return FALSE;
    2759                 : 
    2760               5 :     if( CSLFetchNameValue( papszMD, "LINE_NUM_COEFF" ) == NULL 
    2761                 :         || CSLFetchNameValue( papszMD, "LINE_DEN_COEFF" ) == NULL 
    2762                 :         || CSLFetchNameValue( papszMD, "SAMP_NUM_COEFF" ) == NULL 
    2763                 :         || CSLFetchNameValue( papszMD, "SAMP_DEN_COEFF" ) == NULL )
    2764                 :     {
    2765                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2766               0 :                  "Some required RPC metadata missing in GDALExtractRPCInfo()");
    2767               0 :         return FALSE;
    2768                 :     }
    2769                 : 
    2770               5 :     _FetchDblFromMD( papszMD, "LINE_OFF", &(psRPC->dfLINE_OFF), 1, 0.0 );
    2771               5 :     _FetchDblFromMD( papszMD, "LINE_SCALE", &(psRPC->dfLINE_SCALE), 1, 1.0 );
    2772               5 :     _FetchDblFromMD( papszMD, "SAMP_OFF", &(psRPC->dfSAMP_OFF), 1, 0.0 );
    2773               5 :     _FetchDblFromMD( papszMD, "SAMP_SCALE", &(psRPC->dfSAMP_SCALE), 1, 1.0 );
    2774               5 :     _FetchDblFromMD( papszMD, "HEIGHT_OFF", &(psRPC->dfHEIGHT_OFF), 1, 0.0 );
    2775               5 :     _FetchDblFromMD( papszMD, "HEIGHT_SCALE", &(psRPC->dfHEIGHT_SCALE),1, 1.0);
    2776               5 :     _FetchDblFromMD( papszMD, "LAT_OFF", &(psRPC->dfLAT_OFF), 1, 0.0 );
    2777               5 :     _FetchDblFromMD( papszMD, "LAT_SCALE", &(psRPC->dfLAT_SCALE), 1, 1.0 );
    2778               5 :     _FetchDblFromMD( papszMD, "LONG_OFF", &(psRPC->dfLONG_OFF), 1, 0.0 );
    2779               5 :     _FetchDblFromMD( papszMD, "LONG_SCALE", &(psRPC->dfLONG_SCALE), 1, 1.0 );
    2780                 : 
    2781                 :     _FetchDblFromMD( papszMD, "LINE_NUM_COEFF", psRPC->adfLINE_NUM_COEFF, 
    2782               5 :                      20, 0.0 );
    2783                 :     _FetchDblFromMD( papszMD, "LINE_DEN_COEFF", psRPC->adfLINE_DEN_COEFF, 
    2784               5 :                      20, 0.0 );
    2785                 :     _FetchDblFromMD( papszMD, "SAMP_NUM_COEFF", psRPC->adfSAMP_NUM_COEFF, 
    2786               5 :                      20, 0.0 );
    2787                 :     _FetchDblFromMD( papszMD, "SAMP_DEN_COEFF", psRPC->adfSAMP_DEN_COEFF, 
    2788               5 :                      20, 0.0 );
    2789                 :     
    2790               5 :     _FetchDblFromMD( papszMD, "MIN_LONG", &(psRPC->dfMIN_LONG), 1, -180.0 );
    2791               5 :     _FetchDblFromMD( papszMD, "MIN_LAT", &(psRPC->dfMIN_LAT), 1, -90.0 );
    2792               5 :     _FetchDblFromMD( papszMD, "MAX_LONG", &(psRPC->dfMAX_LONG), 1, 180.0 );
    2793               5 :     _FetchDblFromMD( papszMD, "MAX_LAT", &(psRPC->dfMAX_LAT), 1, 90.0 );
    2794                 : 
    2795               5 :     return TRUE;
    2796                 : }
    2797                 : 
    2798                 : /************************************************************************/
    2799                 : /*                     GDALFindAssociatedAuxFile()                      */
    2800                 : /************************************************************************/
    2801                 : 
    2802            4565 : GDALDataset *GDALFindAssociatedAuxFile( const char *pszBasename,
    2803                 :                                         GDALAccess eAccess,
    2804                 :                                         GDALDataset *poDependentDS )
    2805                 : 
    2806                 : {
    2807            4565 :     const char *pszAuxSuffixLC = "aux";
    2808            4565 :     const char *pszAuxSuffixUC = "AUX";
    2809                 : 
    2810            4565 :     if( EQUAL(CPLGetExtension(pszBasename), pszAuxSuffixLC) )
    2811              33 :         return NULL;
    2812                 : 
    2813                 : /* -------------------------------------------------------------------- */
    2814                 : /*      Don't even try to look for an .aux file if we don't have a      */
    2815                 : /*      path of any kind.                                               */
    2816                 : /* -------------------------------------------------------------------- */
    2817            4532 :     if( strlen(pszBasename) == 0 )
    2818               0 :         return NULL;
    2819                 : 
    2820                 : /* -------------------------------------------------------------------- */
    2821                 : /*      We didn't find that, so try and find a corresponding aux        */
    2822                 : /*      file.  Check that we are the dependent file of the aux          */
    2823                 : /*      file, or if we aren't verify that the dependent file does       */
    2824                 : /*      not exist, likely mean it is us but some sort of renaming       */
    2825                 : /*      has occured.                                                    */
    2826                 : /* -------------------------------------------------------------------- */
    2827            4532 :     CPLString osJustFile = CPLGetFilename(pszBasename); // without dir
    2828            4532 :     CPLString osAuxFilename = CPLResetExtension(pszBasename, pszAuxSuffixLC);
    2829            4532 :     GDALDataset *poODS = NULL;
    2830                 :     GByte abyHeader[32];
    2831                 :     VSILFILE *fp;
    2832                 : 
    2833            4532 :     fp = VSIFOpenL( osAuxFilename, "rb" );
    2834                 : 
    2835                 : 
    2836            4532 :     if ( fp == NULL && VSIIsCaseSensitiveFS(osAuxFilename)) 
    2837                 :     {
    2838                 :         // Can't found file with lower case suffix. Try the upper case one.
    2839            4488 :         osAuxFilename = CPLResetExtension(pszBasename, pszAuxSuffixUC);
    2840            4488 :         fp = VSIFOpenL( osAuxFilename, "rb" );
    2841                 :     }
    2842                 : 
    2843            4532 :     if( fp != NULL )
    2844                 :     {
    2845              44 :         if( VSIFReadL( abyHeader, 1, 32, fp ) == 32 &&
    2846                 :             EQUALN((char *) abyHeader,"EHFA_HEADER_TAG",15) )
    2847                 :         {
    2848                 :             /* Avoid causing failure in opening of main file from SWIG bindings */
    2849                 :             /* when auxiliary file cannot be opened (#3269) */
    2850              20 :             CPLTurnFailureIntoWarning(TRUE);
    2851              20 :             poODS = (GDALDataset *) GDALOpenShared( osAuxFilename, eAccess );
    2852              20 :             CPLTurnFailureIntoWarning(FALSE);
    2853                 :         }
    2854              44 :         VSIFCloseL( fp );
    2855                 :     }
    2856                 : 
    2857                 : /* -------------------------------------------------------------------- */
    2858                 : /*      Try replacing extension with .aux                               */
    2859                 : /* -------------------------------------------------------------------- */
    2860            4532 :     if( poODS != NULL )
    2861                 :     {
    2862                 :         const char *pszDep
    2863              20 :             = poODS->GetMetadataItem( "HFA_DEPENDENT_FILE", "HFA" );
    2864              20 :         if( pszDep == NULL  )
    2865                 :         {
    2866                 :             CPLDebug( "AUX", 
    2867                 :                       "Found %s but it has no dependent file, ignoring.",
    2868               0 :                       osAuxFilename.c_str() );
    2869               0 :             GDALClose( poODS );
    2870               0 :             poODS = NULL;
    2871                 :         }
    2872              20 :         else if( !EQUAL(pszDep,osJustFile) )
    2873                 :         {
    2874                 :             VSIStatBufL sStatBuf;
    2875                 : 
    2876               0 :             if( VSIStatExL( pszDep, &sStatBuf, VSI_STAT_EXISTS_FLAG ) == 0 )
    2877                 :             {
    2878                 :                 CPLDebug( "AUX", "%s is for file %s, not %s, ignoring.",
    2879                 :                           osAuxFilename.c_str(), 
    2880               0 :                           pszDep, osJustFile.c_str() );
    2881               0 :                 GDALClose( poODS );
    2882               0 :                 poODS = NULL;
    2883                 :             }
    2884                 :             else
    2885                 :             {
    2886                 :                 CPLDebug( "AUX", "%s is for file %s, not %s, but since\n"
    2887                 :                           "%s does not exist, we will use .aux file as our own.",
    2888                 :                           osAuxFilename.c_str(), 
    2889                 :                           pszDep, osJustFile.c_str(),
    2890               0 :                           pszDep );
    2891                 :             }
    2892                 :         }
    2893                 : 
    2894                 : /* -------------------------------------------------------------------- */
    2895                 : /*      Confirm that the aux file matches the configuration of the      */
    2896                 : /*      dependent dataset.                                              */
    2897                 : /* -------------------------------------------------------------------- */
    2898              20 :         if( poODS != NULL && poDependentDS != NULL
    2899                 :             && (poODS->GetRasterCount() != poDependentDS->GetRasterCount()
    2900                 :                 || poODS->GetRasterXSize() != poDependentDS->GetRasterXSize()
    2901                 :                 || poODS->GetRasterYSize() != poDependentDS->GetRasterYSize()) )
    2902                 :         {
    2903                 :             CPLDebug( "AUX",
    2904                 :                       "Ignoring aux file %s as its raster configuration\n"
    2905                 :                       "(%dP x %dL x %dB) does not match master file (%dP x %dL x %dB)", 
    2906                 :                       osAuxFilename.c_str(),
    2907                 :                       poODS->GetRasterXSize(), 
    2908                 :                       poODS->GetRasterYSize(),
    2909                 :                       poODS->GetRasterCount(),
    2910                 :                       poDependentDS->GetRasterXSize(), 
    2911                 :                       poDependentDS->GetRasterYSize(),
    2912               5 :                       poDependentDS->GetRasterCount() );
    2913                 : 
    2914               5 :             GDALClose( poODS );
    2915               5 :             poODS = NULL;
    2916                 :         }
    2917                 :     }
    2918                 :         
    2919                 : /* -------------------------------------------------------------------- */
    2920                 : /*      Try appending .aux to the end of the filename.                  */
    2921                 : /* -------------------------------------------------------------------- */
    2922            4532 :     if( poODS == NULL )
    2923                 :     {
    2924            4517 :         osAuxFilename = pszBasename;
    2925            4517 :         osAuxFilename += ".";
    2926            4517 :         osAuxFilename += pszAuxSuffixLC;
    2927            4517 :         fp = VSIFOpenL( osAuxFilename, "rb" );
    2928            4517 :         if ( fp == NULL && VSIIsCaseSensitiveFS(osAuxFilename) )
    2929                 :         {
    2930                 :             // Can't found file with lower case suffix. Try the upper case one.
    2931            4498 :             osAuxFilename = pszBasename;
    2932            4498 :             osAuxFilename += ".";
    2933            4498 :             osAuxFilename += pszAuxSuffixUC;
    2934            4498 :             fp = VSIFOpenL( osAuxFilename, "rb" );
    2935                 :         }
    2936                 : 
    2937            4517 :         if( fp != NULL )
    2938                 :         {
    2939              19 :             if( VSIFReadL( abyHeader, 1, 32, fp ) == 32 &&
    2940                 :                 EQUALN((char *) abyHeader,"EHFA_HEADER_TAG",15) )
    2941                 :             {
    2942                 :                 /* Avoid causing failure in opening of main file from SWIG bindings */
    2943                 :                 /* when auxiliary file cannot be opened (#3269) */
    2944               0 :                 CPLTurnFailureIntoWarning(TRUE);
    2945               0 :                 poODS = (GDALDataset *) GDALOpenShared( osAuxFilename, eAccess );
    2946               0 :                 CPLTurnFailureIntoWarning(FALSE);
    2947                 :             }
    2948              19 :             VSIFCloseL( fp );
    2949                 :         }
    2950                 :  
    2951            4517 :         if( poODS != NULL )
    2952                 :         {
    2953                 :             const char *pszDep
    2954               0 :                 = poODS->GetMetadataItem( "HFA_DEPENDENT_FILE", "HFA" );
    2955               0 :             if( pszDep == NULL  )
    2956                 :             {
    2957                 :                 CPLDebug( "AUX", 
    2958                 :                           "Found %s but it has no dependent file, ignoring.",
    2959               0 :                           osAuxFilename.c_str() );
    2960               0 :                 GDALClose( poODS );
    2961               0 :                 poODS = NULL;
    2962                 :             }
    2963               0 :             else if( !EQUAL(pszDep,osJustFile) )
    2964                 :             {
    2965                 :                 VSIStatBufL sStatBuf;
    2966                 : 
    2967               0 :                 if( VSIStatExL( pszDep, &sStatBuf, VSI_STAT_EXISTS_FLAG ) == 0 )
    2968                 :                 {
    2969                 :                     CPLDebug( "AUX", "%s is for file %s, not %s, ignoring.",
    2970                 :                               osAuxFilename.c_str(), 
    2971               0 :                               pszDep, osJustFile.c_str() );
    2972               0 :                     GDALClose( poODS );
    2973               0 :                     poODS = NULL;
    2974                 :                 }
    2975                 :                 else
    2976                 :                 {
    2977                 :                     CPLDebug( "AUX", "%s is for file %s, not %s, but since\n"
    2978                 :                               "%s does not exist, we will use .aux file as our own.",
    2979                 :                               osAuxFilename.c_str(), 
    2980                 :                               pszDep, osJustFile.c_str(),
    2981               0 :                               pszDep );
    2982                 :                 }
    2983                 :             }
    2984                 :         }
    2985                 :     }
    2986                 : 
    2987                 : /* -------------------------------------------------------------------- */
    2988                 : /*      Confirm that the aux file matches the configuration of the      */
    2989                 : /*      dependent dataset.                                              */
    2990                 : /* -------------------------------------------------------------------- */
    2991            4532 :     if( poODS != NULL && poDependentDS != NULL
    2992                 :         && (poODS->GetRasterCount() != poDependentDS->GetRasterCount()
    2993                 :             || poODS->GetRasterXSize() != poDependentDS->GetRasterXSize()
    2994                 :             || poODS->GetRasterYSize() != poDependentDS->GetRasterYSize()) )
    2995                 :     {
    2996                 :         CPLDebug( "AUX",
    2997                 :                   "Ignoring aux file %s as its raster configuration\n"
    2998                 :                   "(%dP x %dL x %dB) does not match master file (%dP x %dL x %dB)", 
    2999                 :                   osAuxFilename.c_str(),
    3000                 :                   poODS->GetRasterXSize(), 
    3001                 :                   poODS->GetRasterYSize(),
    3002                 :                   poODS->GetRasterCount(),
    3003                 :                   poDependentDS->GetRasterXSize(), 
    3004                 :                   poDependentDS->GetRasterYSize(),
    3005               0 :                   poDependentDS->GetRasterCount() );
    3006                 : 
    3007               0 :         GDALClose( poODS );
    3008               0 :         poODS = NULL;
    3009                 :     }
    3010                 : 
    3011            4532 :     return poODS;
    3012                 : }
    3013                 : 
    3014                 : /************************************************************************/
    3015                 : /* -------------------------------------------------------------------- */
    3016                 : /*      The following stubs are present to ensure that older GDAL       */
    3017                 : /*      bridges don't fail with newer libraries.                        */
    3018                 : /* -------------------------------------------------------------------- */
    3019                 : /************************************************************************/
    3020                 : 
    3021                 : CPL_C_START
    3022                 : 
    3023               0 : void * CPL_STDCALL GDALCreateProjDef( const char * )
    3024                 : {
    3025               0 :     CPLDebug( "GDAL", "GDALCreateProjDef no longer supported." );
    3026               0 :     return NULL;
    3027                 : }
    3028                 : 
    3029               0 : CPLErr CPL_STDCALL GDALReprojectToLongLat( void *, double *, double * )
    3030                 : {
    3031               0 :     CPLDebug( "GDAL", "GDALReprojectToLatLong no longer supported." );
    3032               0 :     return CE_Failure;
    3033                 : }
    3034                 : 
    3035               0 : CPLErr CPL_STDCALL GDALReprojectFromLongLat( void *, double *, double * )
    3036                 : {
    3037               0 :     CPLDebug( "GDAL", "GDALReprojectFromLatLong no longer supported." );
    3038               0 :     return CE_Failure;
    3039                 : }
    3040                 : 
    3041               0 : void CPL_STDCALL GDALDestroyProjDef( void * )
    3042                 : 
    3043                 : {
    3044               0 :     CPLDebug( "GDAL", "GDALDestroyProjDef no longer supported." );
    3045               0 : }
    3046                 : 
    3047                 : CPL_C_END
    3048                 : 
    3049                 : /************************************************************************/
    3050                 : /* Infrastructure to check that dataset characteristics are valid       */
    3051                 : /************************************************************************/
    3052                 : 
    3053                 : CPL_C_START
    3054                 : 
    3055                 : /**
    3056                 :   * \brief Return TRUE if the dataset dimensions are valid.
    3057                 :   *
    3058                 :   * @param nXSize raster width
    3059                 :   * @param nYSize raster height
    3060                 :   *
    3061                 :   * @since GDAL 1.7.0
    3062                 :   */
    3063            1368 : int GDALCheckDatasetDimensions( int nXSize, int nYSize )
    3064                 : {
    3065            1368 :     if (nXSize <= 0 || nYSize <= 0)
    3066                 :     {
    3067                 :         CPLError(CE_Failure, CPLE_AppDefined,
    3068               0 :                  "Invalid dataset dimensions : %d x %d", nXSize, nYSize);
    3069               0 :         return FALSE;
    3070                 :     }
    3071            1368 :     return TRUE;
    3072                 : }
    3073                 : 
    3074                 : /**
    3075                 :   * \brief Return TRUE if the band count is valid.
    3076                 :   *
    3077                 :   * If the configuration option GDAL_MAX_BAND_COUNT is defined,
    3078                 :   * the band count will be compared to the maximum number of band allowed.
    3079                 :   *
    3080                 :   * @param nBands the band count
    3081                 :   * @param bIsZeroAllowed TRUE if band count == 0 is allowed
    3082                 :   *
    3083                 :   * @since GDAL 1.7.0
    3084                 :   */
    3085                 : 
    3086             925 : int GDALCheckBandCount( int nBands, int bIsZeroAllowed )
    3087                 : {
    3088             925 :     int nMaxBands = -1;
    3089             925 :     const char* pszMaxBandCount = CPLGetConfigOption("GDAL_MAX_BAND_COUNT", NULL);
    3090             925 :     if (pszMaxBandCount != NULL)
    3091                 :     {
    3092               0 :         nMaxBands = atoi(pszMaxBandCount);
    3093                 :     }
    3094             925 :     if (nBands < 0 || (!bIsZeroAllowed && nBands == 0) ||
    3095                 :         (nMaxBands >= 0 && nBands > nMaxBands) )
    3096                 :     {
    3097                 :         CPLError(CE_Failure, CPLE_AppDefined,
    3098               6 :                  "Invalid band count : %d", nBands);
    3099               6 :         return FALSE;
    3100                 :     }
    3101             919 :     return TRUE;
    3102                 : }
    3103                 : 
    3104                 : CPL_C_END
    3105                 : 

Generated by: LCOV version 1.7