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

Generated by: LCOV version 1.14