~ubuntu-branches/debian/sid/gdal/sid

« back to all changes in this revision

Viewing changes to gcore/gdal_misc.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2012-05-07 15:04:42 UTC
  • mfrom: (5.5.16 experimental)
  • Revision ID: package-import@ubuntu.com-20120507150442-2eks97loeh6rq005
Tags: 1.9.0-1
* Ready for sid, starting transition.
* All symfiles updated to latest builds.
* Added dh_numpy call in debian/rules to depend on numpy ABI.
* Policy bumped to 3.9.3, no changes required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/******************************************************************************
2
 
 * $Id: gdal_misc.cpp 19900 2010-06-23 09:30:34Z dron $
 
2
 * $Id: gdal_misc.cpp 23156 2011-10-01 15:34:16Z rouault $
3
3
 *
4
4
 * Project:  GDAL Core
5
5
 * Purpose:  Free standing functions for GDAL.
34
34
#include <ctype.h>
35
35
#include <string>
36
36
 
37
 
CPL_CVSID("$Id: gdal_misc.cpp 19900 2010-06-23 09:30:34Z dron $");
 
37
CPL_CVSID("$Id: gdal_misc.cpp 23156 2011-10-01 15:34:16Z rouault $");
38
38
 
39
39
#include "ogr_spatialref.h"
40
40
 
208
208
 *
209
209
 * Returns the size of a a GDT_* type in bits, <b>not bytes</b>!
210
210
 *
211
 
 * @param data type, such as GDT_Byte. 
 
211
 * @param eDataType type, such as GDT_Byte.
212
212
 * @return the number of bits or zero if it is not recognised.
213
213
 */
214
214
 
285
285
 * datatypes in debug statements, errors and other user output. 
286
286
 *
287
287
 * @param eDataType type to get name of.
288
 
 * @return string corresponding to type.
 
288
 * @return string corresponding to existing data type
 
289
 *         or NULL pointer if invalid type given.
289
290
 */
290
291
 
291
292
const char * CPL_STDCALL GDALGetDataTypeName( GDALDataType eDataType )
369
370
}
370
371
 
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
GDALAsyncStatusType CPL_DLL CPL_STDCALL GDALGetAsyncStatusTypeByName( const char *pszName )
 
386
{
 
387
        VALIDATE_POINTER1( pszName, "GDALGetAsyncStatusTypeByName", GARIO_ERROR);
 
388
 
 
389
    int iType;
 
390
 
 
391
        for( iType = 1; iType < GARIO_TypeCount; iType++ )
 
392
    {
 
393
        if( GDALGetAsyncStatusTypeName((GDALAsyncStatusType)iType) != NULL
 
394
            && EQUAL(GDALGetAsyncStatusTypeName((GDALAsyncStatusType)iType), pszName) )
 
395
        {
 
396
            return (GDALAsyncStatusType)iType;
 
397
        }
 
398
    }
 
399
 
 
400
        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
 const char * CPL_STDCALL GDALGetAsyncStatusTypeName( GDALAsyncStatusType eAsyncStatusType )
 
422
 
 
423
{
 
424
    switch( eAsyncStatusType )
 
425
    {
 
426
      case GARIO_PENDING:
 
427
        return "PENDING";
 
428
 
 
429
      case GARIO_UPDATE:
 
430
        return "UPDATE";
 
431
 
 
432
      case GARIO_ERROR:
 
433
        return "ERROR";
 
434
 
 
435
      case GARIO_COMPLETE:
 
436
        return "COMPLETE";
 
437
      default:
 
438
        return NULL;
 
439
    }
 
440
}
 
441
 
 
442
/************************************************************************/
372
443
/*                  GDALGetPaletteInterpretationName()                  */
373
444
/************************************************************************/
374
445
 
420
491
 * or freed by the application.
421
492
 *
422
493
 * @param eInterp color interpretation to get name of.
423
 
 * @return string corresponding to color interpretation.
 
494
 * @return string corresponding to color interpretation
 
495
 *         or NULL pointer if invalid enumerator given.
424
496
 */
425
497
 
426
498
const char *GDALGetColorInterpretationName( GDALColorInterp eInterp )
957
1029
 
958
1030
    return pasReturn;
959
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
CPLString GDALFindAssociatedFile( const char *pszBaseFilename, 
 
1064
                                  const char *pszExt,
 
1065
                                  char **papszSiblingFiles, 
 
1066
                                  int nFlags )
 
1067
 
 
1068
{
 
1069
    (void) nFlags;
 
1070
 
 
1071
    CPLString osTarget = CPLResetExtension( pszBaseFilename, pszExt );
 
1072
 
 
1073
    if( papszSiblingFiles == NULL )
 
1074
    {
 
1075
        VSIStatBufL sStatBuf;
 
1076
 
 
1077
        if( VSIStatExL( osTarget, &sStatBuf, VSI_STAT_EXISTS_FLAG ) != 0 )
 
1078
        {
 
1079
            CPLString osAltExt = pszExt;
 
1080
 
 
1081
            if( islower( pszExt[0] ) )
 
1082
                osAltExt.toupper();
 
1083
            else
 
1084
                osAltExt.tolower();
 
1085
 
 
1086
            osTarget = CPLResetExtension( pszBaseFilename, osAltExt );
 
1087
 
 
1088
            if( VSIStatExL( osTarget, &sStatBuf, VSI_STAT_EXISTS_FLAG ) != 0 )
 
1089
                return "";
 
1090
        }
 
1091
    }
 
1092
    else
 
1093
    {
 
1094
        int iSibling = CSLFindString( papszSiblingFiles, 
 
1095
                                      CPLGetFilename(osTarget) );
 
1096
        if( iSibling < 0 )
 
1097
            return "";
 
1098
 
 
1099
        osTarget.resize(osTarget.size() - strlen(papszSiblingFiles[iSibling]));
 
1100
        osTarget += papszSiblingFiles[iSibling];
 
1101
    }
 
1102
 
 
1103
    return osTarget;
 
1104
}
960
1105
                             
961
1106
/************************************************************************/
962
1107
/*                         GDALLoadOziMapFile()                         */
1002
1147
    const char *pszProj = NULL, *pszProjParms = NULL;
1003
1148
    OGRErr eErr = OGRERR_NONE;
1004
1149
 
 
1150
    /* The Map Scale Factor has been introduced recently on the 6th line */
 
1151
    /* and is a trick that is used to just change that line without changing */
 
1152
    /* the rest of the MAP file but providing an imagery that is smaller or larger */
 
1153
    /* so we have to correct the pixel/line values read in the .MAP file so they */
 
1154
    /* match the actual imagery dimension. Well, this is a bad summary of what */
 
1155
    /* is explained at http://tech.groups.yahoo.com/group/OziUsers-L/message/12484 */
 
1156
    double dfMSF = 1;
 
1157
 
1005
1158
    for ( iLine = 5; iLine < nLines; iLine++ )
1006
1159
    {
1007
 
        if ( EQUALN(papszLines[iLine], "Map Projection", 14) )
 
1160
        if ( EQUALN(papszLines[iLine], "MSF,", 4) )
 
1161
        {
 
1162
            dfMSF = atof(papszLines[iLine] + 4);
 
1163
            if (dfMSF <= 0.01) /* Suspicious values */
 
1164
            {
 
1165
                CPLDebug("OZI", "Suspicious MSF value : %s", papszLines[iLine]);
 
1166
                dfMSF = 1;
 
1167
            }
 
1168
        }
 
1169
        else if ( EQUALN(papszLines[iLine], "Map Projection", 14) )
1008
1170
        {
1009
1171
            pszProj = papszLines[iLine];
1010
 
            continue;
1011
1172
        }
1012
 
 
1013
 
        if ( EQUALN(papszLines[iLine], "Projection Setup", 16) )
 
1173
        else if ( EQUALN(papszLines[iLine], "Projection Setup", 16) )
1014
1174
        {
1015
1175
            pszProjParms = papszLines[iLine];
1016
 
            continue;
1017
1176
        }
1018
1177
    }
1019
1178
 
1038
1197
                                       | CSLT_STRIPENDSPACES );
1039
1198
 
1040
1199
        if ( CSLCount(papszTok) < 12 )
 
1200
        {
 
1201
            CSLDestroy(papszTok);
1041
1202
            continue;
 
1203
        }
1042
1204
 
1043
1205
        if ( CSLCount(papszTok) >= 17
1044
1206
             && EQUALN(papszTok[0], "Point", 5)
1047
1209
             && nCoordinateCount < MAX_GCP )
1048
1210
        {
1049
1211
            int     bReadOk = FALSE;
1050
 
            double  dfLon, dfLat;
 
1212
            double  dfLon = 0., dfLat = 0.;
1051
1213
 
1052
1214
            if ( !EQUAL(papszTok[6], "")
1053
1215
                 && !EQUAL(papszTok[7], "")
1099
1261
                GDALInitGCPs( 1, asGCPs + nCoordinateCount );
1100
1262
 
1101
1263
                // Set pixel/line part
1102
 
                asGCPs[nCoordinateCount].dfGCPPixel = CPLAtofM(papszTok[2]);
1103
 
                asGCPs[nCoordinateCount].dfGCPLine = CPLAtofM(papszTok[3]);
 
1264
                asGCPs[nCoordinateCount].dfGCPPixel = CPLAtofM(papszTok[2]) / dfMSF;
 
1265
                asGCPs[nCoordinateCount].dfGCPLine = CPLAtofM(papszTok[3]) / dfMSF;
1104
1266
 
1105
1267
                asGCPs[nCoordinateCount].dfGCPX = dfLon;
1106
1268
                asGCPs[nCoordinateCount].dfGCPY = dfLat;
1126
1288
/*      possible.  Otherwise we will need to use them as GCPs.          */
1127
1289
/* -------------------------------------------------------------------- */
1128
1290
    if( !GDALGCPsToGeoTransform( nCoordinateCount, asGCPs, padfGeoTransform, 
1129
 
                                 FALSE ) )
 
1291
                                 CSLTestBoolean(CPLGetConfigOption("OZI_APPROX_GEOTRANSFORM", "NO")) ) )
1130
1292
    {
1131
1293
        if ( pnGCPCount && ppasGCPs )
1132
1294
        {
1171
1333
 
1172
1334
    fpOzi = VSIFOpen( pszOzi, "rt" );
1173
1335
 
1174
 
#ifndef WIN32
1175
 
    if ( fpOzi == NULL )
 
1336
    if ( fpOzi == NULL && VSIIsCaseSensitiveFS(pszOzi) )
1176
1337
    {
1177
1338
        pszOzi = CPLResetExtension( pszBaseFilename, "MAP" );
1178
1339
        fpOzi = VSIFOpen( pszOzi, "rt" );
1179
1340
    }
1180
 
#endif
1181
1341
    
1182
1342
    if ( fpOzi == NULL )
1183
1343
        return FALSE;
1354
1514
 
1355
1515
 
1356
1516
{
 
1517
    return GDALReadTabFile2(pszBaseFilename, padfGeoTransform,
 
1518
                            ppszWKT, pnGCPCount, ppasGCPs,
 
1519
                            NULL, NULL);
 
1520
}
 
1521
 
 
1522
 
 
1523
int GDALReadTabFile2( const char * pszBaseFilename,
 
1524
                      double *padfGeoTransform, char **ppszWKT,
 
1525
                      int *pnGCPCount, GDAL_GCP **ppasGCPs,
 
1526
                      char** papszSiblingFiles, char** ppszTabFileNameOut )
 
1527
{
1357
1528
    const char  *pszTAB;
1358
 
    FILE        *fpTAB;
1359
 
 
1360
 
/* -------------------------------------------------------------------- */
1361
 
/*      Try lower case, then upper case.                                */
1362
 
/* -------------------------------------------------------------------- */
 
1529
    VSILFILE    *fpTAB;
 
1530
 
 
1531
    if (ppszTabFileNameOut)
 
1532
        *ppszTabFileNameOut = NULL;
 
1533
 
1363
1534
    pszTAB = CPLResetExtension( pszBaseFilename, "tab" );
1364
1535
 
1365
 
    fpTAB = VSIFOpen( pszTAB, "rt" );
1366
 
 
1367
 
#ifndef WIN32
1368
 
    if( fpTAB == NULL )
 
1536
    if (papszSiblingFiles)
 
1537
    {
 
1538
        int iSibling = CSLFindString(papszSiblingFiles, CPLGetFilename(pszTAB));
 
1539
        if (iSibling >= 0)
 
1540
        {
 
1541
            CPLString osTabFilename = pszBaseFilename;
 
1542
            osTabFilename.resize(strlen(pszBaseFilename) -
 
1543
                                 strlen(CPLGetFilename(pszBaseFilename)));
 
1544
            osTabFilename += papszSiblingFiles[iSibling];
 
1545
            if ( GDALLoadTabFile(osTabFilename, padfGeoTransform, ppszWKT,
 
1546
                                 pnGCPCount, ppasGCPs ) )
 
1547
            {
 
1548
                if (ppszTabFileNameOut)
 
1549
                    *ppszTabFileNameOut = CPLStrdup(osTabFilename);
 
1550
                return TRUE;
 
1551
            }
 
1552
        }
 
1553
        return FALSE;
 
1554
    }
 
1555
 
 
1556
/* -------------------------------------------------------------------- */
 
1557
/*      Try lower case, then upper case.                                */
 
1558
/* -------------------------------------------------------------------- */
 
1559
 
 
1560
    fpTAB = VSIFOpenL( pszTAB, "rt" );
 
1561
 
 
1562
    if( fpTAB == NULL && VSIIsCaseSensitiveFS(pszTAB) )
1369
1563
    {
1370
1564
        pszTAB = CPLResetExtension( pszBaseFilename, "TAB" );
1371
 
        fpTAB = VSIFOpen( pszTAB, "rt" );
 
1565
        fpTAB = VSIFOpenL( pszTAB, "rt" );
1372
1566
    }
1373
 
#endif
1374
1567
    
1375
1568
    if( fpTAB == NULL )
1376
1569
        return FALSE;
1377
1570
 
1378
 
    VSIFClose( fpTAB );
 
1571
    VSIFCloseL( fpTAB );
1379
1572
 
1380
1573
/* -------------------------------------------------------------------- */
1381
1574
/*      We found the file, now load and parse it.                       */
1382
1575
/* -------------------------------------------------------------------- */
1383
 
    return GDALLoadTabFile( pszTAB, padfGeoTransform, ppszWKT,
1384
 
                            pnGCPCount, ppasGCPs );
 
1576
    if (GDALLoadTabFile( pszTAB, padfGeoTransform, ppszWKT,
 
1577
                         pnGCPCount, ppasGCPs ) )
 
1578
    {
 
1579
        if (ppszTabFileNameOut)
 
1580
            *ppszTabFileNameOut = CPLStrdup(pszTAB);
 
1581
        return TRUE;
 
1582
    }
 
1583
    return FALSE;
1385
1584
}
1386
1585
 
1387
1586
/************************************************************************/
1512
1711
                   double *padfGeoTransform )
1513
1712
 
1514
1713
{
 
1714
    return GDALReadWorldFile2(pszBaseFilename, pszExtension,
 
1715
                              padfGeoTransform, NULL, NULL);
 
1716
}
 
1717
 
 
1718
int GDALReadWorldFile2( const char *pszBaseFilename, const char *pszExtension,
 
1719
                        double *padfGeoTransform, char** papszSiblingFiles,
 
1720
                        char** ppszWorldFileNameOut )
 
1721
{
1515
1722
    const char  *pszTFW;
1516
1723
    char        szExtUpper[32], szExtLower[32];
1517
1724
    int         i;
1519
1726
    VALIDATE_POINTER1( pszBaseFilename, "GDALReadWorldFile", FALSE );
1520
1727
    VALIDATE_POINTER1( padfGeoTransform, "GDALReadWorldFile", FALSE );
1521
1728
 
 
1729
    if (ppszWorldFileNameOut)
 
1730
        *ppszWorldFileNameOut = NULL;
 
1731
 
1522
1732
/* -------------------------------------------------------------------- */
1523
1733
/*      If we aren't given an extension, try both the unix and          */
1524
1734
/*      windows style extensions.                                       */
1537
1747
        szDerivedExtension[2] = 'w';
1538
1748
        szDerivedExtension[3] = '\0';
1539
1749
        
1540
 
        if( GDALReadWorldFile( pszBaseFilename, szDerivedExtension, 
1541
 
                               padfGeoTransform ) )
 
1750
        if( GDALReadWorldFile2( pszBaseFilename, szDerivedExtension,
 
1751
                                padfGeoTransform, papszSiblingFiles,
 
1752
                                ppszWorldFileNameOut ) )
1542
1753
            return TRUE;
1543
1754
 
1544
1755
        // unix version - extension + 'w'
1547
1758
 
1548
1759
        strcpy( szDerivedExtension, oBaseExt.c_str() );
1549
1760
        strcat( szDerivedExtension, "w" );
1550
 
        return GDALReadWorldFile( pszBaseFilename, szDerivedExtension, 
1551
 
                                  padfGeoTransform );
 
1761
        return GDALReadWorldFile2( pszBaseFilename, szDerivedExtension,
 
1762
                                  padfGeoTransform, papszSiblingFiles,
 
1763
                                  ppszWorldFileNameOut );
1552
1764
    }
1553
1765
 
1554
1766
/* -------------------------------------------------------------------- */
1569
1781
        szExtLower[i] = (char) tolower(szExtLower[i]);
1570
1782
    }
1571
1783
 
1572
 
/* -------------------------------------------------------------------- */
1573
 
/*      Try lower case, then upper case.                                */
1574
 
/* -------------------------------------------------------------------- */
1575
1784
    VSIStatBufL sStatBuf;
1576
1785
    int bGotTFW;
1577
1786
 
1578
1787
    pszTFW = CPLResetExtension( pszBaseFilename, szExtLower );
1579
1788
 
1580
 
    bGotTFW = VSIStatL( pszTFW, &sStatBuf ) == 0;
1581
 
 
1582
 
#ifndef WIN32
1583
 
    if( !bGotTFW )
 
1789
    if (papszSiblingFiles)
 
1790
    {
 
1791
        int iSibling = CSLFindString(papszSiblingFiles, CPLGetFilename(pszTFW));
 
1792
        if (iSibling >= 0)
 
1793
        {
 
1794
            CPLString osTFWFilename = pszBaseFilename;
 
1795
            osTFWFilename.resize(strlen(pszBaseFilename) -
 
1796
                                 strlen(CPLGetFilename(pszBaseFilename)));
 
1797
            osTFWFilename += papszSiblingFiles[iSibling];
 
1798
            if (GDALLoadWorldFile( osTFWFilename, padfGeoTransform ))
 
1799
            {
 
1800
                if (ppszWorldFileNameOut)
 
1801
                    *ppszWorldFileNameOut = CPLStrdup(osTFWFilename);
 
1802
                return TRUE;
 
1803
            }
 
1804
        }
 
1805
        return FALSE;
 
1806
    }
 
1807
 
 
1808
/* -------------------------------------------------------------------- */
 
1809
/*      Try lower case, then upper case.                                */
 
1810
/* -------------------------------------------------------------------- */
 
1811
 
 
1812
    bGotTFW = VSIStatExL( pszTFW, &sStatBuf, VSI_STAT_EXISTS_FLAG ) == 0;
 
1813
 
 
1814
    if( !bGotTFW  && VSIIsCaseSensitiveFS(pszTFW) )
1584
1815
    {
1585
1816
        pszTFW = CPLResetExtension( pszBaseFilename, szExtUpper );
1586
 
        bGotTFW = VSIStatL( pszTFW, &sStatBuf ) == 0;
 
1817
        bGotTFW = VSIStatExL( pszTFW, &sStatBuf, VSI_STAT_EXISTS_FLAG ) == 0;
1587
1818
    }
1588
 
#endif
1589
1819
    
1590
1820
    if( !bGotTFW )
1591
1821
        return FALSE;
1593
1823
/* -------------------------------------------------------------------- */
1594
1824
/*      We found the file, now load and parse it.                       */
1595
1825
/* -------------------------------------------------------------------- */
1596
 
    return GDALLoadWorldFile( pszTFW, padfGeoTransform );
 
1826
    if (GDALLoadWorldFile( pszTFW, padfGeoTransform ))
 
1827
    {
 
1828
        if (ppszWorldFileNameOut)
 
1829
            *ppszWorldFileNameOut = CPLStrdup(pszTFW);
 
1830
        return TRUE;
 
1831
    }
 
1832
    return FALSE;
1597
1833
}
1598
1834
 
1599
1835
/************************************************************************/
1658
1894
/*      Update extention, and write to disk.                            */
1659
1895
/* -------------------------------------------------------------------- */
1660
1896
    const char  *pszTFW;
1661
 
    FILE    *fpTFW;
 
1897
    VSILFILE    *fpTFW;
1662
1898
 
1663
1899
    pszTFW = CPLResetExtension( pszBaseFilename, pszExtension );
1664
1900
    fpTFW = VSIFOpenL( pszTFW, "wt" );
1712
1948
        }
1713
1949
 
1714
1950
        const char *pszFilename = CPLFindFile( "etc", "LICENSE.TXT" );
1715
 
        FILE *fp = NULL;
 
1951
        VSILFILE *fp = NULL;
1716
1952
        int  nLength;
1717
1953
 
1718
1954
        if( pszFilename != NULL )
2072
2308
 *  --config key value: set system configuration option. 
2073
2309
 *  --debug [on/off/value]: set debug level.
2074
2310
 *  --mempreload dir: preload directory contents into /vsimem
 
2311
 *  --pause: Pause for user input (allows time to attach debugger)
 
2312
 *  --locale [locale]: Install a locale using setlocale() (debugging)
2075
2313
 *  --help-general: report detailed help on general options. 
2076
2314
 *
2077
2315
 * The argument array is replaced "in place" and should be freed with 
2088
2326
 *        exit( -argc );
2089
2327
 *
2090
2328
 * @param nArgc number of values in the argument list.
2091
 
 * @param Pointer to the argument list array (will be updated in place). 
 
2329
 * @param ppapszArgv pointer to the argument list array (will be updated in place).
 
2330
 * @param nOptions unused for now.
2092
2331
 *
2093
2332
 * @return updated nArgc argument count.  Return of 0 requests terminate 
2094
2333
 * without error, return of -1 requests exit with error code.
2179
2418
            for( i = 0; papszFiles[i] != NULL; i++ )
2180
2419
            {
2181
2420
                CPLString osOldPath, osNewPath;
 
2421
                VSIStatBufL sStatBuf;
2182
2422
                
2183
2423
                if( EQUAL(papszFiles[i],".") || EQUAL(papszFiles[i],"..") )
2184
2424
                    continue;
2187
2427
                                             papszFiles[i], NULL );
2188
2428
                osNewPath.Printf( "/vsimem/%s", papszFiles[i] );
2189
2429
 
 
2430
                if( VSIStatL( osOldPath, &sStatBuf ) != 0
 
2431
                    || VSI_ISDIR( sStatBuf.st_mode ) )
 
2432
                {
 
2433
                    CPLDebug( "VSI", "Skipping preload of %s.", 
 
2434
                              osOldPath.c_str() );
 
2435
                    continue;
 
2436
                }
 
2437
 
2190
2438
                CPLDebug( "VSI", "Preloading %s to %s.", 
2191
2439
                          osOldPath.c_str(), osNewPath.c_str() );
2192
2440
 
2193
2441
                if( CPLCopyFile( osNewPath, osOldPath ) != 0 )
 
2442
                {
 
2443
                    CPLError( CE_Failure, CPLE_AppDefined,
 
2444
                              "Failed to copy %s to /vsimem", 
 
2445
                              osOldPath.c_str() );
2194
2446
                    return -1;
 
2447
                }
2195
2448
            }
2196
2449
            
2197
2450
            CSLDestroy( papszFiles );
2383
2636
            printf( "  --optfile filename: expand an option file into the argument list.\n" );
2384
2637
            printf( "  --config key value: set system configuration option.\n" );
2385
2638
            printf( "  --debug [on/off/value]: set debug level.\n" );
 
2639
            printf( "  --pause: wait for user input, time to attach debugger\n" );
 
2640
            printf( "  --locale [locale]: install locale for debugging (ie. en_US.UTF-8)\n" );
2386
2641
            printf( "  --help-general: report detailed help on general options.\n" );
2387
2642
            CSLDestroy( papszReturn );
2388
2643
            return 0;
2397
2652
        }
2398
2653
 
2399
2654
/* -------------------------------------------------------------------- */
 
2655
/*      --pause                                                         */
 
2656
/* -------------------------------------------------------------------- */
 
2657
        else if( EQUAL(papszArgv[iArg],"--pause") )
 
2658
        {
 
2659
            printf( "Hit <ENTER> to Continue.\n" );
 
2660
            CPLReadLine( stdin );
 
2661
        }
 
2662
 
 
2663
/* -------------------------------------------------------------------- */
2400
2664
/*      carry through unrecognised options.                             */
2401
2665
/* -------------------------------------------------------------------- */
2402
2666
        else
2517
2781
 
2518
2782
{
2519
2783
    const char *pszAuxSuffixLC = "aux";
2520
 
#ifndef WIN32
2521
2784
    const char *pszAuxSuffixUC = "AUX";
2522
 
#endif
2523
2785
 
2524
2786
    if( EQUAL(CPLGetExtension(pszBasename), pszAuxSuffixLC) )
2525
2787
        return NULL;
2542
2804
    CPLString osAuxFilename = CPLResetExtension(pszBasename, pszAuxSuffixLC);
2543
2805
    GDALDataset *poODS = NULL;
2544
2806
    GByte abyHeader[32];
2545
 
    FILE *fp;
 
2807
    VSILFILE *fp;
2546
2808
 
2547
2809
    fp = VSIFOpenL( osAuxFilename, "rb" );
2548
2810
 
2549
2811
 
2550
 
    if ( fp == NULL ) 
 
2812
    if ( fp == NULL && VSIIsCaseSensitiveFS(osAuxFilename)) 
2551
2813
    {
2552
2814
        // Can't found file with lower case suffix. Try the upper case one.
2553
 
        // no point in doing this on Win32 with case insensitive filenames.
2554
 
#ifndef WIN32
2555
2815
        osAuxFilename = CPLResetExtension(pszBasename, pszAuxSuffixUC);
2556
2816
        fp = VSIFOpenL( osAuxFilename, "rb" );
2557
 
#endif
2558
2817
    }
2559
2818
 
2560
2819
    if( fp != NULL )
2561
2820
    {
2562
 
        VSIFReadL( abyHeader, 1, 32, fp );
2563
 
        if( EQUALN((char *) abyHeader,"EHFA_HEADER_TAG",15) )
2564
 
            poODS =  (GDALDataset *) GDALOpenShared( osAuxFilename, eAccess );
 
2821
        if( VSIFReadL( abyHeader, 1, 32, fp ) == 32 &&
 
2822
            EQUALN((char *) abyHeader,"EHFA_HEADER_TAG",15) )
 
2823
        {
 
2824
            /* Avoid causing failure in opening of main file from SWIG bindings */
 
2825
            /* when auxiliary file cannot be opened (#3269) */
 
2826
            CPLTurnFailureIntoWarning(TRUE);
 
2827
            poODS = (GDALDataset *) GDALOpenShared( osAuxFilename, eAccess );
 
2828
            CPLTurnFailureIntoWarning(FALSE);
 
2829
        }
2565
2830
        VSIFCloseL( fp );
2566
2831
    }
2567
2832
 
2584
2849
        {
2585
2850
            VSIStatBufL sStatBuf;
2586
2851
 
2587
 
            if( VSIStatL( pszDep, &sStatBuf ) == 0 )
 
2852
            if( VSIStatExL( pszDep, &sStatBuf, VSI_STAT_EXISTS_FLAG ) == 0 )
2588
2853
            {
2589
2854
                CPLDebug( "AUX", "%s is for file %s, not %s, ignoring.",
2590
2855
                          osAuxFilename.c_str(), 
2636
2901
        osAuxFilename += ".";
2637
2902
        osAuxFilename += pszAuxSuffixLC;
2638
2903
        fp = VSIFOpenL( osAuxFilename, "rb" );
2639
 
#ifndef WIN32
2640
 
        if ( fp == NULL )
 
2904
        if ( fp == NULL && VSIIsCaseSensitiveFS(osAuxFilename) )
2641
2905
        {
2642
2906
            // Can't found file with lower case suffix. Try the upper case one.
2643
2907
            osAuxFilename = pszBasename;
2645
2909
            osAuxFilename += pszAuxSuffixUC;
2646
2910
            fp = VSIFOpenL( osAuxFilename, "rb" );
2647
2911
        }
2648
 
#endif
2649
2912
 
2650
2913
        if( fp != NULL )
2651
2914
        {
2652
 
            VSIFReadL( abyHeader, 1, 32, fp );
2653
 
            if( EQUALN((char *) abyHeader,"EHFA_HEADER_TAG",15) )
 
2915
            if( VSIFReadL( abyHeader, 1, 32, fp ) == 32 &&
 
2916
                EQUALN((char *) abyHeader,"EHFA_HEADER_TAG",15) )
 
2917
            {
 
2918
                /* Avoid causing failure in opening of main file from SWIG bindings */
 
2919
                /* when auxiliary file cannot be opened (#3269) */
 
2920
                CPLTurnFailureIntoWarning(TRUE);
2654
2921
                poODS = (GDALDataset *) GDALOpenShared( osAuxFilename, eAccess );
 
2922
                CPLTurnFailureIntoWarning(FALSE);
 
2923
            }
2655
2924
            VSIFCloseL( fp );
2656
2925
        }
2657
2926
 
2671
2940
            {
2672
2941
                VSIStatBufL sStatBuf;
2673
2942
 
2674
 
                if( VSIStatL( pszDep, &sStatBuf ) == 0 )
 
2943
                if( VSIStatExL( pszDep, &sStatBuf, VSI_STAT_EXISTS_FLAG ) == 0 )
2675
2944
                {
2676
2945
                    CPLDebug( "AUX", "%s is for file %s, not %s, ignoring.",
2677
2946
                              osAuxFilename.c_str(),