LCOV - code coverage report
Current view: top level - apps - gdal_translate_bin.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 83 120 69.2 %
Date: 2024-11-21 22:18:42 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL Utilities
       4             :  * Purpose:  GDAL Image Translator Program
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 1998, 2002, Frank Warmerdam
       9             :  * Copyright (c) 2007-2014, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "cpl_string.h"
      15             : #include "gdal_version.h"
      16             : #include "gdal_priv.h"
      17             : #include "ogr_spatialref.h"
      18             : #include "commonutils.h"
      19             : #include "gdal_utils_priv.h"
      20             : 
      21             : /*  ******************************************************************* */
      22             : /*                               Usage()                                */
      23             : /* ******************************************************************** */
      24             : 
      25           4 : static void Usage()
      26             : {
      27           4 :     fprintf(stderr, "%s\n", GDALTranslateGetParserUsage().c_str());
      28             : 
      29           4 :     exit(1);
      30             : }
      31             : 
      32             : /************************************************************************/
      33             : /*                                main()                                */
      34             : /************************************************************************/
      35             : 
      36         166 : MAIN_START(argc, argv)
      37             : 
      38             : {
      39             :     /* Check strict compilation and runtime library version as we use C++ API */
      40         166 :     if (!GDAL_CHECK_VERSION(argv[0]))
      41           0 :         exit(1);
      42             : 
      43         166 :     EarlySetConfigOptions(argc, argv);
      44             : 
      45             :     /* -------------------------------------------------------------------- */
      46             :     /*      Register standard GDAL drivers, and process generic GDAL        */
      47             :     /*      command options.                                                */
      48             :     /* -------------------------------------------------------------------- */
      49         166 :     GDALAllRegister();
      50         166 :     argc = GDALGeneralCmdLineProcessor(argc, &argv, 0);
      51         166 :     if (argc < 1)
      52           0 :         exit(-argc);
      53             : 
      54             :     /* -------------------------------------------------------------------- */
      55             :     /*      Set optimal setting for best performance with huge input VRT.   */
      56             :     /*      The rationale for 450 is that typical Linux process allow       */
      57             :     /*      only 1024 file descriptors per process and we need to keep some */
      58             :     /*      spare for shared libraries, etc. so let's go down to 900.       */
      59             :     /*      And some datasets may need 2 file descriptors, so divide by 2   */
      60             :     /*      for security.                                                   */
      61             :     /* -------------------------------------------------------------------- */
      62         166 :     if (CPLGetConfigOption("GDAL_MAX_DATASET_POOL_SIZE", nullptr) == nullptr)
      63             :     {
      64             : #if defined(__MACH__) && defined(__APPLE__)
      65             :         // On Mach, the default limit is 256 files per process
      66             :         // TODO We should eventually dynamically query the limit for all OS
      67             :         CPLSetConfigOption("GDAL_MAX_DATASET_POOL_SIZE", "100");
      68             : #else
      69         166 :         CPLSetConfigOption("GDAL_MAX_DATASET_POOL_SIZE", "450");
      70             : #endif
      71             :     }
      72             : 
      73         320 :     GDALTranslateOptionsForBinary sOptionsForBinary;
      74             :     GDALTranslateOptions *psOptions =
      75         166 :         GDALTranslateOptionsNew(argv + 1, &sOptionsForBinary);
      76         163 :     CSLDestroy(argv);
      77             : 
      78         163 :     if (psOptions == nullptr)
      79             :     {
      80           4 :         Usage();
      81             :     }
      82             : 
      83         159 :     if (sOptionsForBinary.osDest == "/vsistdout/")
      84             :     {
      85           0 :         sOptionsForBinary.bQuiet = true;
      86             :     }
      87             : 
      88         159 :     if (!(sOptionsForBinary.bQuiet))
      89             :     {
      90         148 :         GDALTranslateOptionsSetProgress(psOptions, GDALTermProgress, nullptr);
      91             :     }
      92             : 
      93         159 :     if (!sOptionsForBinary.osFormat.empty())
      94             :     {
      95             :         GDALDriverH hDriver =
      96         102 :             GDALGetDriverByName(sOptionsForBinary.osFormat.c_str());
      97         102 :         if (hDriver == nullptr)
      98             :         {
      99           0 :             fprintf(stderr, "Output driver `%s' not recognised.\n",
     100             :                     sOptionsForBinary.osFormat.c_str());
     101           0 :             fprintf(stderr, "The following format drivers are configured and "
     102             :                             "support output:\n");
     103           0 :             for (int iDr = 0; iDr < GDALGetDriverCount(); iDr++)
     104             :             {
     105           0 :                 hDriver = GDALGetDriver(iDr);
     106             : 
     107           0 :                 if (GDALGetMetadataItem(hDriver, GDAL_DCAP_RASTER, nullptr) !=
     108           0 :                         nullptr &&
     109           0 :                     (GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATE, nullptr) !=
     110           0 :                          nullptr ||
     111           0 :                      GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATECOPY,
     112             :                                          nullptr) != nullptr))
     113             :                 {
     114           0 :                     fprintf(stderr, "  %s: %s\n",
     115             :                             GDALGetDriverShortName(hDriver),
     116             :                             GDALGetDriverLongName(hDriver));
     117             :                 }
     118             :             }
     119             : 
     120           0 :             GDALTranslateOptionsFree(psOptions);
     121             : 
     122           0 :             GDALDestroyDriverManager();
     123           0 :             exit(1);
     124             :         }
     125             :     }
     126             : 
     127             :     /* -------------------------------------------------------------------- */
     128             :     /*      Attempt to open source file.                                    */
     129             :     /* -------------------------------------------------------------------- */
     130             : 
     131             :     GDALDatasetH hDataset =
     132         159 :         GDALOpenEx(sOptionsForBinary.osSource.c_str(),
     133             :                    GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR,
     134         159 :                    sOptionsForBinary.aosAllowedInputDrivers.List(),
     135         159 :                    sOptionsForBinary.aosOpenOptions.List(), nullptr);
     136             : 
     137         159 :     if (hDataset == nullptr)
     138             :     {
     139           5 :         GDALDestroyDriverManager();
     140           5 :         exit(1);
     141             :     }
     142             : 
     143             :     /* -------------------------------------------------------------------- */
     144             :     /*      Handle subdatasets.                                             */
     145             :     /* -------------------------------------------------------------------- */
     146         461 :     if (!sOptionsForBinary.bCopySubDatasets &&
     147         154 :         GDALGetRasterCount(hDataset) == 0 &&
     148           0 :         CSLCount(GDALGetMetadata(hDataset, "SUBDATASETS")) > 0)
     149             :     {
     150           0 :         fprintf(stderr, "Input file contains subdatasets. Please, select one "
     151             :                         "of them for reading.\n");
     152           0 :         GDALClose(hDataset);
     153           0 :         GDALDestroyDriverManager();
     154           0 :         exit(1);
     155             :     }
     156             : 
     157         154 :     int bUsageError = FALSE;
     158         154 :     GDALDatasetH hOutDS = nullptr;
     159         154 :     GDALDriverH hOutDriver = nullptr;
     160             : 
     161         154 :     if (sOptionsForBinary.osFormat.empty())
     162             :     {
     163          52 :         hOutDriver = GDALGetDriverByName(
     164         104 :             GetOutputDriverForRaster(sOptionsForBinary.osDest.c_str()));
     165             :     }
     166             :     else
     167             :     {
     168         102 :         hOutDriver = GDALGetDriverByName(sOptionsForBinary.osFormat.c_str());
     169             :     }
     170             : 
     171         154 :     if (hOutDriver == nullptr)
     172             :     {
     173           0 :         fprintf(stderr, "Output driver not found.\n");
     174           0 :         GDALClose(hDataset);
     175           0 :         GDALDestroyDriverManager();
     176           0 :         exit(1);
     177             :     }
     178             : 
     179             :     bool bCopyCreateSubDatasets =
     180         154 :         (GDALGetMetadataItem(hOutDriver, GDAL_DCAP_SUBCREATECOPY, nullptr) !=
     181         154 :          nullptr);
     182             : 
     183         155 :     if (sOptionsForBinary.bCopySubDatasets &&
     184           1 :         CSLCount(GDALGetMetadata(hDataset, "SUBDATASETS")) > 0)
     185             :     {
     186           1 :         if (bCopyCreateSubDatasets)
     187             :         {
     188             :             // GDAL sets the size of the dataset with subdatasets to 512x512
     189             :             // this removes the srcwin function from this operation
     190           0 :             hOutDS = GDALTranslate(sOptionsForBinary.osDest.c_str(), hDataset,
     191             :                                    psOptions, &bUsageError);
     192           0 :             GDALClose(hOutDS);
     193             :         }
     194             :         else
     195             :         {
     196           1 :             char **papszSubdatasets = GDALGetMetadata(hDataset, "SUBDATASETS");
     197           1 :             const int nSubdatasets = CSLCount(papszSubdatasets) / 2;
     198             :             char *pszSubDest = static_cast<char *>(
     199           1 :                 CPLMalloc(strlen(sOptionsForBinary.osDest.c_str()) + 32));
     200             : 
     201           2 :             CPLString osPath = CPLGetPath(sOptionsForBinary.osDest.c_str());
     202             :             CPLString osBasename =
     203           2 :                 CPLGetBasename(sOptionsForBinary.osDest.c_str());
     204             :             CPLString osExtension =
     205           2 :                 CPLGetExtension(sOptionsForBinary.osDest.c_str());
     206           2 :             CPLString osTemp;
     207             : 
     208           1 :             const char *pszFormat = nullptr;
     209           1 :             if (nSubdatasets < 10)
     210             :             {
     211           1 :                 pszFormat = "%s_%d";
     212             :             }
     213           0 :             else if (nSubdatasets < 100)
     214             :             {
     215           0 :                 pszFormat = "%s_%002d";
     216             :             }
     217             :             else
     218             :             {
     219           0 :                 pszFormat = "%s_%003d";
     220             :             }
     221             : 
     222           1 :             const char *pszDest = pszSubDest;
     223             : 
     224           2 :             for (int i = 0; papszSubdatasets[i] != nullptr; i += 2)
     225             :             {
     226             :                 char *pszSource =
     227           1 :                     CPLStrdup(strstr(papszSubdatasets[i], "=") + 1);
     228           1 :                 osTemp = CPLSPrintf(pszFormat, osBasename.c_str(), i / 2 + 1);
     229           1 :                 osTemp = CPLFormFilename(osPath, osTemp, osExtension);
     230           1 :                 strcpy(pszSubDest, osTemp.c_str());
     231           1 :                 hDataset = GDALOpenEx(pszSource, GDAL_OF_RASTER, nullptr,
     232           1 :                                       sOptionsForBinary.aosOpenOptions.List(),
     233             :                                       nullptr);
     234           1 :                 CPLFree(pszSource);
     235           1 :                 if (!sOptionsForBinary.bQuiet)
     236           1 :                     printf("Input file size is %d, %d\n",
     237             :                            GDALGetRasterXSize(hDataset),
     238             :                            GDALGetRasterYSize(hDataset));
     239             :                 hOutDS =
     240           1 :                     GDALTranslate(pszDest, hDataset, psOptions, &bUsageError);
     241           1 :                 if (hOutDS == nullptr)
     242           0 :                     break;
     243           1 :                 GDALClose(hOutDS);
     244             :             }
     245             : 
     246           1 :             CPLFree(pszSubDest);
     247             :         }
     248             : 
     249           1 :         if (bUsageError == TRUE)
     250           0 :             Usage();
     251           1 :         GDALClose(hDataset);
     252           1 :         GDALTranslateOptionsFree(psOptions);
     253             : 
     254           1 :         GDALDestroy();
     255           1 :         return 0;
     256             :     }
     257             : 
     258         153 :     if (!sOptionsForBinary.bQuiet)
     259         144 :         printf("Input file size is %d, %d\n", GDALGetRasterXSize(hDataset),
     260             :                GDALGetRasterYSize(hDataset));
     261             : 
     262         153 :     hOutDS = GDALTranslate(sOptionsForBinary.osDest.c_str(), hDataset,
     263             :                            psOptions, &bUsageError);
     264         153 :     if (bUsageError == TRUE)
     265           0 :         Usage();
     266         153 :     int nRetCode = hOutDS ? 0 : 1;
     267             : 
     268             :     /* Close hOutDS before hDataset for the -f VRT case */
     269         153 :     if (GDALClose(hOutDS) != CE_None)
     270             :     {
     271           0 :         nRetCode = 1;
     272           0 :         if (CPLGetLastErrorType() == CE_None)
     273             :         {
     274           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     275             :                      "Unknown error occurred in GDALClose()");
     276             :         }
     277             :     }
     278         153 :     GDALClose(hDataset);
     279         153 :     GDALTranslateOptionsFree(psOptions);
     280             : 
     281         153 :     GDALDestroy();
     282             : 
     283         153 :     return nRetCode;
     284             : }
     285             : 
     286           0 : MAIN_END

Generated by: LCOV version 1.14