LCOV - code coverage report
Current view: top level - apps - gdal_footprint_bin.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 61 88 69.3 %
Date: 2024-11-21 22:18:42 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL Utilities
       4             :  * Purpose:  Computes the footprint of a GDAL raster
       5             :  * Authors:  Even Rouault, <even dot rouault at spatialys dot com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2023, Even Rouault <even dot rouault at spatialys dot com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "cpl_string.h"
      14             : #include "gdal_version.h"
      15             : #include "commonutils.h"
      16             : #include "gdal_utils_priv.h"
      17             : #include "gdal_priv.h"
      18             : #include "ogrsf_frmts.h"
      19             : 
      20             : /**
      21             :  * @brief Makes sure the GDAL library is properly cleaned up before exiting.
      22             :  * @param nCode exit code
      23             :  * @todo Move to API
      24             :  */
      25           1 : static void GDALExit(int nCode)
      26             : {
      27           1 :     GDALDestroy();
      28           1 :     exit(nCode);
      29             : }
      30             : 
      31             : /************************************************************************/
      32             : /*                               Usage()                                */
      33             : /************************************************************************/
      34             : 
      35           0 : static void Usage()
      36             : {
      37           0 :     fprintf(stderr, "%s\n", GDALFootprintAppGetParserUsage().c_str());
      38           0 :     GDALExit(1);
      39           0 : }
      40             : 
      41             : /************************************************************************/
      42             : /*                                main()                                */
      43             : /************************************************************************/
      44             : 
      45           8 : MAIN_START(argc, argv)
      46             : {
      47             :     /* Check strict compilation and runtime library version as we use C++ API */
      48           8 :     if (!GDAL_CHECK_VERSION(argv[0]))
      49           0 :         GDALExit(1);
      50             : 
      51           8 :     EarlySetConfigOptions(argc, argv);
      52             : 
      53             :     /* -------------------------------------------------------------------- */
      54             :     /*      Generic arg processing.                                         */
      55             :     /* -------------------------------------------------------------------- */
      56           8 :     GDALAllRegister();
      57           8 :     argc = GDALGeneralCmdLineProcessor(argc, &argv, 0);
      58           8 :     if (argc < 1)
      59           0 :         GDALExit(-argc);
      60             : 
      61             :     /* -------------------------------------------------------------------- */
      62             :     /*      Parse command line                                              */
      63             :     /* -------------------------------------------------------------------- */
      64             : 
      65          14 :     GDALFootprintOptionsForBinary sOptionsForBinary;
      66             :     // coverity[tainted_data]
      67             :     std::unique_ptr<GDALFootprintOptions, decltype(&GDALFootprintOptionsFree)>
      68             :         psOptions{GDALFootprintOptionsNew(argv + 1, &sOptionsForBinary),
      69           8 :                   GDALFootprintOptionsFree};
      70             : 
      71           7 :     CSLDestroy(argv);
      72             : 
      73           7 :     if (psOptions == nullptr)
      74             :     {
      75           0 :         Usage();
      76             :     }
      77             : 
      78           7 :     if (!(sOptionsForBinary.bQuiet))
      79             :     {
      80           6 :         GDALFootprintOptionsSetProgress(psOptions.get(), GDALTermProgress,
      81             :                                         nullptr);
      82             :     }
      83             : 
      84             :     /* -------------------------------------------------------------------- */
      85             :     /*      Open input file.                                                */
      86             :     /* -------------------------------------------------------------------- */
      87           7 :     GDALDatasetH hInDS = GDALOpenEx(sOptionsForBinary.osSource.c_str(),
      88             :                                     GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR,
      89             :                                     /*papszAllowedDrivers=*/nullptr,
      90           7 :                                     sOptionsForBinary.aosOpenOptions.List(),
      91             :                                     /*papszSiblingFiles=*/nullptr);
      92             : 
      93           7 :     if (hInDS == nullptr)
      94           1 :         GDALExit(1);
      95             : 
      96             :     /* -------------------------------------------------------------------- */
      97             :     /*      Open output file if it exists.                                  */
      98             :     /* -------------------------------------------------------------------- */
      99           6 :     GDALDatasetH hDstDS = nullptr;
     100           6 :     if (!(sOptionsForBinary.bCreateOutput))
     101             :     {
     102           5 :         CPLPushErrorHandler(CPLQuietErrorHandler);
     103             :         hDstDS =
     104           5 :             GDALOpenEx(sOptionsForBinary.osDest.c_str(),
     105             :                        GDAL_OF_VECTOR | GDAL_OF_VERBOSE_ERROR | GDAL_OF_UPDATE,
     106             :                        nullptr, nullptr, nullptr);
     107           5 :         CPLPopErrorHandler();
     108             :     }
     109             : 
     110           7 :     if (!sOptionsForBinary.osFormat.empty() &&
     111           1 :         (sOptionsForBinary.bCreateOutput || hDstDS == nullptr))
     112             :     {
     113           1 :         GDALDriverManager *poDM = GetGDALDriverManager();
     114             :         GDALDriver *poDriver =
     115           1 :             poDM->GetDriverByName(sOptionsForBinary.osFormat.c_str());
     116           1 :         char **papszDriverMD = (poDriver) ? poDriver->GetMetadata() : nullptr;
     117           2 :         if (poDriver == nullptr ||
     118           1 :             !CPLTestBool(CSLFetchNameValueDef(papszDriverMD, GDAL_DCAP_VECTOR,
     119           2 :                                               "FALSE")) ||
     120           1 :             !CPLTestBool(
     121             :                 CSLFetchNameValueDef(papszDriverMD, GDAL_DCAP_CREATE, "FALSE")))
     122             :         {
     123           0 :             fprintf(stderr,
     124             :                     "Output driver `%s' not recognised or does not support "
     125             :                     "direct output file creation.\n",
     126             :                     sOptionsForBinary.osFormat.c_str());
     127           0 :             fprintf(stderr, "The following format drivers are configured and "
     128             :                             "support direct output:\n");
     129             : 
     130           0 :             for (int iDriver = 0; iDriver < poDM->GetDriverCount(); iDriver++)
     131             :             {
     132           0 :                 GDALDriver *poIter = poDM->GetDriver(iDriver);
     133           0 :                 papszDriverMD = poIter->GetMetadata();
     134           0 :                 if (CPLTestBool(CSLFetchNameValueDef(
     135           0 :                         papszDriverMD, GDAL_DCAP_VECTOR, "FALSE")) &&
     136           0 :                     CPLTestBool(CSLFetchNameValueDef(
     137             :                         papszDriverMD, GDAL_DCAP_CREATE, "FALSE")))
     138             :                 {
     139           0 :                     fprintf(stderr, "  -> `%s'\n", poIter->GetDescription());
     140             :                 }
     141             :             }
     142           0 :             GDALExit(1);
     143             :         }
     144             :     }
     145             : 
     146           6 :     if (hDstDS && sOptionsForBinary.bOverwrite)
     147             :     {
     148           1 :         auto poDstDS = GDALDataset::FromHandle(hDstDS);
     149           1 :         int nLayerCount = poDstDS->GetLayerCount();
     150           1 :         int iLayerToDelete = -1;
     151           2 :         for (int i = 0; i < nLayerCount; ++i)
     152             :         {
     153           1 :             auto poLayer = poDstDS->GetLayer(i);
     154           2 :             if (poLayer &&
     155           1 :                 poLayer->GetName() == sOptionsForBinary.osDestLayerName)
     156             :             {
     157           0 :                 iLayerToDelete = i;
     158           0 :                 break;
     159             :             }
     160             :         }
     161           1 :         bool bDeleteOK = false;
     162           1 :         if (iLayerToDelete >= 0 && poDstDS->TestCapability(ODsCDeleteLayer))
     163             :         {
     164           0 :             bDeleteOK = poDstDS->DeleteLayer(iLayerToDelete) == OGRERR_NONE;
     165             :         }
     166           1 :         if (!bDeleteOK && nLayerCount == 1)
     167             :         {
     168           1 :             GDALClose(hDstDS);
     169           1 :             hDstDS = nullptr;
     170           1 :             CPLPushErrorHandler(CPLQuietErrorHandler);
     171           1 :             GDALDeleteDataset(nullptr, sOptionsForBinary.osDest.c_str());
     172           1 :             CPLPopErrorHandler();
     173           1 :             VSIUnlink(sOptionsForBinary.osDest.c_str());
     174           1 :         }
     175             :     }
     176           5 :     else if (sOptionsForBinary.bOverwrite)
     177             :     {
     178           0 :         CPLPushErrorHandler(CPLQuietErrorHandler);
     179           0 :         GDALDeleteDataset(nullptr, sOptionsForBinary.osDest.c_str());
     180           0 :         CPLPopErrorHandler();
     181           0 :         VSIUnlink(sOptionsForBinary.osDest.c_str());
     182             :     }
     183             : 
     184           6 :     int bUsageError = FALSE;
     185             :     GDALDatasetH hRetDS =
     186           6 :         GDALFootprint(sOptionsForBinary.osDest.c_str(), hDstDS, hInDS,
     187           6 :                       psOptions.get(), &bUsageError);
     188           6 :     if (bUsageError == TRUE)
     189           0 :         Usage();
     190             : 
     191           6 :     int nRetCode = hRetDS ? 0 : 1;
     192             : 
     193           6 :     GDALClose(hInDS);
     194           6 :     if (GDALClose(hRetDS) != CE_None)
     195           0 :         nRetCode = 1;
     196             : 
     197           6 :     GDALDestroyDriverManager();
     198             : 
     199           6 :     return nRetCode;
     200             : }
     201             : 
     202           0 : MAIN_END

Generated by: LCOV version 1.14