LCOV - code coverage report
Current view: top level - frmts/pcidsk/sdk/core - pcidsk_utils.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 125 226 55.3 %
Date: 2024-11-21 22:18:42 Functions: 11 18 61.1 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Purpose:  Various private (undocumented) utility functions.
       4             :  *
       5             :  ******************************************************************************
       6             :  * Copyright (c) 2009
       7             :  * PCI Geomatics, 90 Allstate Parkway, Markham, Ontario, Canada.
       8             :  *
       9             :  * SPDX-License-Identifier: MIT
      10             :  ****************************************************************************/
      11             : 
      12             : #include "pcidsk_config.h"
      13             : #include "pcidsk_types.h"
      14             : #include "pcidsk_buffer.h"
      15             : #include "pcidsk_exception.h"
      16             : #include "pcidsk_georef.h"
      17             : #include "pcidsk_io.h"
      18             : #include "core/pcidsk_utils.h"
      19             : #include <cstdlib>
      20             : #include <cstring>
      21             : #include <cctype>
      22             : #include <cstdio>
      23             : #include <cmath>
      24             : #include <cstdarg>
      25             : #include <iostream>
      26             : 
      27             : extern "C"
      28             : {
      29             : int CPL_DLL CPLToupper(int c);
      30             : int CPL_DLL CPLTolower(int c);
      31             : }
      32             : 
      33             : #if !defined(va_copy) && defined(__va_copy)
      34             : #define va_copy __va_copy
      35             : #endif
      36             : 
      37             : using namespace PCIDSK;
      38             : 
      39             : /************************************************************************/
      40             : /*                         GetCurrentDateTime()                         */
      41             : /************************************************************************/
      42             : 
      43             : // format we want: "HH:MM DDMMMYYYY \0"
      44             : 
      45             : #include <time.h>
      46             : #include <sys/types.h>
      47             : 
      48        1365 : void    PCIDSK::GetCurrentDateTime( char *out_time )
      49             : 
      50             : {
      51             :     time_t          clock;
      52        1365 :     char            ctime_out[26] = {0};
      53             : 
      54        1365 :     time( &clock );
      55             : #ifdef HAVE_CTIME_R
      56        1365 :     ctime_r(&clock, ctime_out);
      57             : #elif defined(_WIN32)
      58             :     ctime_s(ctime_out, sizeof(ctime_out), &clock);
      59             : #else
      60             :     strncpy( ctime_out, ctime(&clock), 25 );
      61             : #endif
      62             : 
      63             :     // ctime() products: "Wed Jun 30 21:49:08 1993\n"
      64             : 
      65        1365 :     ctime_out[24] = '\0';
      66             : 
      67        1365 :     out_time[0] = ctime_out[11];
      68        1365 :     out_time[1] = ctime_out[12];
      69        1365 :     out_time[2] = ':';
      70        1365 :     out_time[3] = ctime_out[14];
      71        1365 :     out_time[4] = ctime_out[15];
      72        1365 :     out_time[5] = ' ';
      73        1365 :     out_time[6] = ctime_out[8];
      74        1365 :     out_time[7] = ctime_out[9];
      75        1365 :     out_time[8] = ctime_out[4];
      76        1365 :     out_time[9] = ctime_out[5];
      77        1365 :     out_time[10] = ctime_out[6];
      78        1365 :     out_time[11] = ctime_out[20];
      79        1365 :     out_time[12] = ctime_out[21];
      80        1365 :     out_time[13] = ctime_out[22];
      81        1365 :     out_time[14] = ctime_out[23];
      82        1365 :     out_time[15] = ' ';
      83        1365 :     out_time[16] = '\0';
      84        1365 : }
      85             : 
      86             : /************************************************************************/
      87             : /*                              UCaseStr()                              */
      88             : /*                                                                      */
      89             : /*      Force a string into upper case "in place".                      */
      90             : /************************************************************************/
      91             : 
      92         130 : std::string &PCIDSK::UCaseStr( std::string &target )
      93             : 
      94             : {
      95         778 :     for( unsigned int i = 0; i < target.size(); i++ )
      96             :     {
      97         648 :         target[i] = (char) CPLToupper(static_cast<unsigned char>(target[i]));
      98             :     }
      99             : 
     100         130 :     return target;
     101             : }
     102             : 
     103             : /************************************************************************/
     104             : /*                             atouint64()                              */
     105             : /************************************************************************/
     106             : 
     107      541894 : uint64 PCIDSK::atouint64( const char *str_value )
     108             : 
     109             : {
     110             : #if defined(__MSVCRT__) || defined(_MSC_VER)
     111             :     return (uint64) _atoi64( str_value );
     112             : #else
     113      541894 :     return (uint64) atoll( str_value );
     114             : #endif
     115             : }
     116             : 
     117             : /************************************************************************/
     118             : /*                              atoint64()                              */
     119             : /************************************************************************/
     120             : 
     121           0 : int64 PCIDSK::atoint64( const char *str_value )
     122             : 
     123             : {
     124             : #if defined(__MSVCRT__) || defined(_MSC_VER)
     125             :     return (int64) _atoi64( str_value );
     126             : #else
     127           0 :     return (int64) atoll( str_value );
     128             : #endif
     129             : }
     130             : 
     131             : /************************************************************************/
     132             : /*                            SwapPixels()                              */
     133             : /************************************************************************/
     134             : /**
     135             :  * @brief Perform an endianness swap for a given buffer of pixels
     136             :  *
     137             :  * Baed on the provided data type, do an appropriate endianness swap for
     138             :  * a buffer of pixels. Deals with the Complex case specially, in
     139             :  * particular.
     140             :  *
     141             :  * @param data the pixels to be swapped
     142             :  * @param type the data type of the pixels
     143             :  * @param count the count of pixels (not bytes, words, etc.)
     144             :  */
     145         184 : void PCIDSK::SwapPixels(void* const data,
     146             :                         const eChanType type,
     147             :                         const std::size_t count)
     148             : {
     149         184 :     switch(type) {
     150         144 :     case CHN_8U:
     151             :     case CHN_16U:
     152             :     case CHN_16S:
     153             :     case CHN_32U:
     154             :     case CHN_32S:
     155             :     case CHN_32R:
     156             :     case CHN_64U:
     157             :     case CHN_64S:
     158             :     case CHN_64R:
     159         144 :         SwapData(data, DataTypeSize(type), static_cast<int>(count));
     160         144 :         break;
     161          40 :     case CHN_C16U:
     162             :     case CHN_C16S:
     163             :     case CHN_C32U:
     164             :     case CHN_C32S:
     165             :     case CHN_C32R:
     166          40 :         SwapData(data, DataTypeSize(type) / 2, static_cast<int>(count) * 2);
     167          40 :         break;
     168           0 :     default:
     169           0 :         return ThrowPCIDSKException("Unknown data type passed to SwapPixels."
     170           0 :             "This is a software bug. Please contact your vendor.");
     171             :     }
     172             : }
     173             : 
     174             : /************************************************************************/
     175             : /*                              SwapData()                              */
     176             : /************************************************************************/
     177             : #if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ > 3
     178       16051 : void PCIDSK::SwapData( void* const data, const int size, const int wcount )
     179             : {
     180       16051 :     if(size == 2)
     181             :     {
     182        2749 :         uint16 * data16 = reinterpret_cast<uint16*>(data);
     183       25792 :         for(int i = 0; i < wcount; i++)
     184       23043 :             data16[i] = __builtin_bswap16(data16[i]);
     185             :     }
     186       13302 :     else if(size == 4)
     187             :     {
     188       11850 :         uint32 * data32 = reinterpret_cast<uint32*>(data);
     189       51377 :         for(int i = 0; i < wcount; i++)
     190       39527 :             data32[i] = __builtin_bswap32(data32[i]);
     191             :     }
     192        1452 :     else if(size == 8)
     193             :     {
     194        1446 :         uint64 * data64 = reinterpret_cast<uint64*>(data);
     195        6538 :         for(int i = 0; i < wcount; i++)
     196        5092 :             data64[i] = __builtin_bswap64(data64[i]);
     197             :     }
     198       16051 : }
     199             : #elif defined(_MSC_VER)
     200             : #pragma intrinsic(_byteswap_ushort, _byteswap_ulong, _byteswap_uint64)
     201             : 
     202             : void PCIDSK::SwapData( void* const data, const int size, const int wcount )
     203             : {
     204             :     if(size == 2)
     205             :     {
     206             :         uint16 * data16 = reinterpret_cast<uint16*>(data);
     207             :         for(int i = 0; i < wcount; i++)
     208             :             data16[i] = _byteswap_ushort(data16[i]);
     209             :     }
     210             :     else if(size == 4)
     211             :     {
     212             :         uint32 * data32 = reinterpret_cast<uint32*>(data);
     213             :         for(int i = 0; i < wcount; i++)
     214             :             data32[i] = _byteswap_ulong(data32[i]);
     215             :     }
     216             :     else if(size == 8)
     217             :     {
     218             :         uint64 * data64 = reinterpret_cast<uint64*>(data);
     219             :         for(int i = 0; i < wcount; i++)
     220             :             data64[i] = _byteswap_uint64(data64[i]);
     221             :     }
     222             : }
     223             : 
     224             : #else
     225             : 
     226             : void PCIDSK::SwapData( void* const data, const int size, const int wcount )
     227             : 
     228             : {
     229             :     uint8* data8 = reinterpret_cast<uint8*>(data);
     230             :     std::size_t count = wcount;
     231             : 
     232             :     if( size == 2 )
     233             :     {
     234             :         uint8 t;
     235             : 
     236             :         for( ; count; count-- )
     237             :         {
     238             :             t = data8[0];
     239             :             data8[0] = data8[1];
     240             :             data8[1] = t;
     241             : 
     242             :             data8 += 2;
     243             :         }
     244             :     }
     245             :     else if( size == 1 )
     246             :         /* do nothing */;
     247             :     else if( size == 4 )
     248             :     {
     249             :         uint8 t;
     250             : 
     251             :         for( ; count; count-- )
     252             :         {
     253             :             t = data8[0];
     254             :             data8[0] = data8[3];
     255             :             data8[3] = t;
     256             : 
     257             :             t = data8[1];
     258             :             data8[1] = data8[2];
     259             :             data8[2] = t;
     260             : 
     261             :             data8 += 4;
     262             :         }
     263             :     }
     264             :     else if( size == 8 )
     265             :     {
     266             :         uint8 t;
     267             : 
     268             :         for( ; count; count-- )
     269             :         {
     270             :             t = data8[0];
     271             :             data8[0] = data8[7];
     272             :             data8[7] = t;
     273             : 
     274             :             t = data8[1];
     275             :             data8[1] = data8[6];
     276             :             data8[6] = t;
     277             : 
     278             :             t = data8[2];
     279             :             data8[2] = data8[5];
     280             :             data8[5] = t;
     281             : 
     282             :             t = data8[3];
     283             :             data8[3] = data8[4];
     284             :             data8[4] = t;
     285             : 
     286             :             data8 += 8;
     287             :         }
     288             :     }
     289             :     else
     290             :         return ThrowPCIDSKException( "Unsupported data size in SwapData()" );
     291             : }
     292             : 
     293             : #endif
     294             : 
     295             : /************************************************************************/
     296             : /*                          BigEndianSystem()                           */
     297             : /************************************************************************/
     298             : 
     299        6676 : bool PCIDSK::BigEndianSystem()
     300             : 
     301             : {
     302        6676 :     unsigned short test_value = 1;
     303             :     char test_char_value[2];
     304             : 
     305        6676 :     memcpy( test_char_value, &test_value, 2 );
     306             : 
     307        6676 :     return test_char_value[0] == 0;
     308             : }
     309             : 
     310             : 
     311             : /************************************************************************/
     312             : /*                          ParseTileFormat()                           */
     313             : /*                                                                      */
     314             : /*      Parse blocksize and compression out of a TILED interleaving     */
     315             : /*      string as passed to the Create() function or stored in          */
     316             : /*      _DBLayout metadata.                                             */
     317             : /************************************************************************/
     318             : 
     319           7 : void PCIDSK::ParseTileFormat(const std::string& oOptionsIn,
     320             :                              int & nTileSize, std::string & oCompress)
     321             : {
     322           7 :     nTileSize = PCIDSK_DEFAULT_TILE_SIZE;
     323           7 :     oCompress = "NONE";
     324             : 
     325          14 :     std::string oOptions(oOptionsIn);
     326           7 :     UCaseStr(oOptions);
     327             : 
     328           7 :     std::string::size_type nStart = oOptions.find_first_not_of(" ");
     329           7 :     std::string::size_type nEnd = oOptions.find_first_of(" ", nStart);
     330             : 
     331          22 :     while (nStart != std::string::npos || nEnd != std::string::npos)
     332             :     {
     333          30 :         const std::string oToken = oOptions.substr(nStart, nEnd - nStart);
     334             : 
     335          15 :         if (oToken.size() > 5 && STARTS_WITH(oToken.c_str(), "TILED"))
     336             :         {
     337             :             // the TILED entry can be TILED# or TILED=#
     338           6 :             int nPos = oToken[5] == '=' ? 6 : 5;
     339             : 
     340           6 :             nTileSize = atoi(oToken.substr(nPos).c_str());
     341             : 
     342           6 :             if (nTileSize <= 0)
     343           0 :                 ThrowPCIDSKException("Invalid tile option: %s", oToken.c_str());
     344             :         }
     345          18 :         else if (oToken == "NONE" || oToken == "RLE" ||
     346          23 :                  STARTS_WITH(oToken.c_str(), "JPEG") ||
     347           5 :                  STARTS_WITH(oToken.c_str(), "QUADTREE"))
     348             :         {
     349           4 :             oCompress = oToken;
     350             :         }
     351             : 
     352          15 :         nStart = oOptions.find_first_not_of(" ", nEnd);
     353          15 :         nEnd = oOptions.find_first_of(" ", nStart);
     354             :     }
     355           7 : }
     356             : 
     357             : /************************************************************************/
     358             : /*                         ParseLinkedFilename()                        */
     359             : /************************************************************************/
     360             : 
     361           0 : std::string PCIDSK::ParseLinkedFilename(std::string oOptions)
     362             : {
     363           0 :     std::string oToFind = "FILENOCREATE=";
     364           0 :     std::string oLinkedFileName;
     365             : 
     366           0 :     std::string::size_type nStart = oOptions.find_first_not_of(" ");
     367           0 :     std::string::size_type nEnd = oOptions.find_first_of(" ", nStart);
     368             : 
     369           0 :     while (nStart != std::string::npos || nEnd != std::string::npos)
     370             :     {
     371           0 :         std::string oToken = oOptions.substr(nStart, nEnd - nStart);
     372             : 
     373           0 :         if (oToken.size() > oToFind.size() &&
     374           0 :             strncmp(oToken.c_str(), oToFind.c_str(), oToFind.size()) == 0)
     375             :         {
     376           0 :             oLinkedFileName = oOptions.substr(nStart+oToFind.size());
     377           0 :             break;
     378             :         }
     379             : 
     380           0 :         nStart = oOptions.find_first_not_of(" ", nEnd);
     381           0 :         nEnd = oOptions.find_first_of(" ", nStart);
     382             :     }
     383             : 
     384           0 :     return oLinkedFileName;
     385             : }
     386             : 
     387             : /************************************************************************/
     388             : /*                           pci_strcasecmp()                           */
     389             : /************************************************************************/
     390             : 
     391           0 : int PCIDSK::pci_strcasecmp( const char *string1, const char *string2 )
     392             : 
     393             : {
     394             :     int i;
     395             : 
     396           0 :     for( i = 0; string1[i] != '\0' && string2[i] != '\0'; i++ )
     397             :     {
     398           0 :         char c1 = string1[i];
     399           0 :         char c2 = string2[i];
     400             : 
     401           0 :         c1 = (char) CPLToupper(static_cast<unsigned char>(c1));
     402           0 :         c2 = (char) CPLToupper(static_cast<unsigned char>(c2));
     403             : 
     404           0 :         if( c1 < c2 )
     405           0 :             return -1;
     406           0 :         else if( c1 > c2 )
     407           0 :             return 1;
     408             :     }
     409             : 
     410           0 :     if( string1[i] == '\0' && string2[i] == '\0' )
     411           0 :         return 0;
     412           0 :     else if( string1[i] == '\0' )
     413           0 :         return 1;
     414             :     else
     415           0 :         return -1;
     416             : }
     417             : 
     418             : /************************************************************************/
     419             : /*                          pci_strncasecmp()                           */
     420             : /************************************************************************/
     421             : 
     422           0 : int PCIDSK::pci_strncasecmp( const char *string1, const char *string2, size_t len )
     423             : 
     424             : {
     425           0 :     for( size_t i = 0; i < len; i++ )
     426             :     {
     427           0 :         if( string1[i] == '\0' && string2[i] == '\0' )
     428           0 :             return 0;
     429           0 :         else if( string1[i] == '\0' )
     430           0 :             return 1;
     431           0 :         else if( string2[i] == '\0' )
     432           0 :             return -1;
     433             : 
     434           0 :         char c1 = string1[i];
     435           0 :         char c2 = string2[i];
     436             : 
     437           0 :         c1 = (char) CPLToupper(static_cast<unsigned char>(c1));
     438           0 :         c2 = (char) CPLToupper(static_cast<unsigned char>(c2));
     439             : 
     440           0 :         if( c1 < c2 )
     441           0 :             return -1;
     442           0 :         else if( c1 > c2 )
     443           0 :             return 1;
     444             :     }
     445             : 
     446           0 :     return 0;
     447             : }
     448             : 
     449             : /************************************************************************/
     450             : /*                         ProjParamsFromText()                          */
     451             : /*                                                                      */
     452             : /*      function to turn a ProjParams string (17 floating point          */
     453             : /*      numbers) into an array, as well as attaching the units code     */
     454             : /*      derived from the geosys string.                                 */
     455             : /************************************************************************/
     456             : 
     457        1183 : std::vector<double> PCIDSK::ProjParamsFromText( std::string geosys,
     458             :                                                std::string sparms )
     459             : 
     460             : {
     461        1183 :     std::vector<double> dparms;
     462             : 
     463        1404 :     for( const char* next = sparms.c_str(); *next != '\0'; )
     464             :     {
     465         221 :         dparms.push_back( CPLAtof(next) );
     466             : 
     467             :         // move past this token
     468         442 :         while( *next != '\0' && *next != ' ' )
     469         221 :             next++;
     470             : 
     471             :         // move past white space.
     472         429 :         while( *next == ' ' )
     473         208 :             next++;
     474             :     }
     475             : 
     476        1183 :     dparms.resize(18);
     477             : 
     478             :     // This is rather iffy!
     479        1183 :     if( STARTS_WITH_CI(geosys.c_str(), "DEG" /* "DEGREE" */) )
     480           0 :         dparms[17] = (double) (int) UNIT_DEGREE;
     481        1183 :     else if( STARTS_WITH_CI(geosys.c_str(), "MET") )
     482        1171 :         dparms[17] = (double) (int) UNIT_METER;
     483          12 :     else if( STARTS_WITH_CI(geosys.c_str(), "FOOT") )
     484           0 :         dparms[17] = (double) (int) UNIT_US_FOOT;
     485          12 :     else if( STARTS_WITH_CI(geosys.c_str(), "FEET") )
     486           0 :         dparms[17] = (double) (int) UNIT_US_FOOT;
     487          12 :     else if( STARTS_WITH_CI(geosys.c_str(), "INTL " /* "INTL FOOT" */) )
     488           0 :         dparms[17] = (double) (int) UNIT_INTL_FOOT;
     489          12 :     else if( STARTS_WITH_CI(geosys.c_str(), "SPCS") )
     490           0 :         dparms[17] = (double) (int) UNIT_METER;
     491          12 :     else if( STARTS_WITH_CI(geosys.c_str(), "SPIF") )
     492           0 :         dparms[17] = (double) (int) UNIT_INTL_FOOT;
     493          12 :     else if( STARTS_WITH_CI(geosys.c_str(), "SPAF") )
     494           0 :         dparms[17] = (double) (int) UNIT_US_FOOT;
     495             :     else
     496          12 :         dparms[17] = -1.0; /* unknown */
     497             : 
     498        1183 :     return dparms;
     499             : }
     500             : 
     501             : /************************************************************************/
     502             : /*                          ProjParamsToText()                           */
     503             : /************************************************************************/
     504             : 
     505           6 : std::string PCIDSK::ProjParamsToText( std::vector<double> dparms )
     506             : 
     507             : {
     508           6 :     std::string sparms;
     509             : 
     510         108 :     for( unsigned int i = 0; i < 17; i++ )
     511             :     {
     512             :         char value[64];
     513             :         double dvalue;
     514             : 
     515         102 :         if( i < dparms.size() )
     516         102 :             dvalue = dparms[i];
     517             :         else
     518           0 :             dvalue = 0.0;
     519             : 
     520         102 :         if( dvalue == floor(dvalue) )
     521         102 :             CPLsnprintf( value, sizeof(value), "%d", (int) dvalue );
     522             :         else
     523           0 :             CPLsnprintf( value, sizeof(value), "%.15g", dvalue );
     524             : 
     525         102 :         if( i > 0 )
     526          96 :             sparms += " ";
     527             : 
     528         102 :         sparms += value;
     529             :     }
     530             : 
     531           6 :     return sparms;
     532             : }
     533             : 
     534             : /************************************************************************/
     535             : /*                            ExtractPath()                             */
     536             : /*                                                                      */
     537             : /*      Extract the directory path portion of the passed filename.      */
     538             : /*      It assumes the last component is a filename and should not      */
     539             : /*      be passed a bare path.  The trailing directory delimiter is     */
     540             : /*      removed from the result.  The return result is an empty         */
     541             : /*      string for a simple filename passed in with no directory        */
     542             : /*      component.                                                      */
     543             : /************************************************************************/
     544             : 
     545           6 : std::string PCIDSK::ExtractPath( std::string filename )
     546             : 
     547             : {
     548             :     int i;
     549             : 
     550          90 :     for( i = static_cast<int>(filename.size())-1; i >= 0; i-- )
     551             :     {
     552          90 :         if( filename[i] == '\\' || filename[i] == '/' )
     553           6 :             break;
     554             :     }
     555             : 
     556           6 :     if( i > 0 )
     557           6 :         return filename.substr(0,i);
     558             :     else
     559           0 :         return "";
     560             : }
     561             : 
     562             : /************************************************************************/
     563             : /*                         DefaultMergeRelativePath()                   */
     564             : /*                                                                      */
     565             : /*      This attempts to take src_filename and make it relative to      */
     566             : /*      the base of the file "base", if this evaluates to a new file    */
     567             : /*      in the filesystem.  It will not make any change if              */
     568             : /*      src_filename appears to be absolute or if the altered path      */
     569             : /*      does not resolve to a file in the filesystem.                   */
     570             : /************************************************************************/
     571             : 
     572           6 : std::string PCIDSK::DefaultMergeRelativePath(const PCIDSK::IOInterfaces *io_interfaces,
     573             :                                              const std::string& base,
     574             :                                              const std::string& src_filename)
     575             : 
     576             : {
     577             : /* -------------------------------------------------------------------- */
     578             : /*      Does src_filename appear to be absolute?                        */
     579             : /* -------------------------------------------------------------------- */
     580           6 :     if( src_filename.empty() )
     581           0 :         return src_filename; // we can't do anything with a blank.
     582           6 :     else if( src_filename.size() > 2 && src_filename[1] == ':' )
     583           0 :         return src_filename; // has a drive letter?
     584           6 :     else if( src_filename[0] == '/' || src_filename[0] == '\\' )
     585           0 :         return src_filename; // has a leading dir marker.
     586             : 
     587             : /* -------------------------------------------------------------------- */
     588             : /*      Figure out what path split char we want to use.                 */
     589             : /* -------------------------------------------------------------------- */
     590             : #if defined(__MSVCRT__) || defined(_MSC_VER)
     591             :     const static char  path_split = '\\';
     592             : #else
     593             :     const static char  path_split = '/';
     594             : #endif
     595             : 
     596             : /* -------------------------------------------------------------------- */
     597             : /*      Merge paths.                                                    */
     598             : /* -------------------------------------------------------------------- */
     599          12 :     std::string result = ExtractPath( base );
     600             : 
     601           6 :     if( result.empty() )
     602           0 :         return src_filename;
     603             : 
     604           6 :     result += path_split;
     605           6 :     result += src_filename;
     606             : 
     607             : /* -------------------------------------------------------------------- */
     608             : /*      Check if the target exists by this name.                        */
     609             : /* -------------------------------------------------------------------- */
     610             :     try
     611             :     {
     612           8 :         void *hFile = io_interfaces->Open( result, "r" );
     613             :         // should throw an exception on failure.
     614           5 :         io_interfaces->Close( hFile );
     615           5 :         return result;
     616             :     }
     617           2 :     catch( ... )
     618             :     {
     619           1 :         return src_filename;
     620             :     }
     621             : }
     622             : 
     623             : 
     624             : /************************************************************************/
     625             : /*                            DefaultDebug()                            */
     626             : /*                                                                      */
     627             : /*      Default implementation of the Debug() output interface.         */
     628             : /************************************************************************/
     629             : 
     630           0 : void PCIDSK::DefaultDebug( const char * message )
     631             : 
     632             : {
     633             :     static bool initialized = false;
     634             :     static bool enabled = false;
     635             : 
     636           0 :     if( !initialized )
     637             :     {
     638           0 :         if( getenv( "PCIDSK_DEBUG" ) != nullptr )
     639           0 :             enabled = true;
     640             : 
     641           0 :         initialized = true;
     642             :     }
     643             : 
     644           0 :     if( enabled )
     645           0 :         std::cerr << message;
     646           0 : }
     647             : 
     648             : /************************************************************************/
     649             : /*                               vDebug()                               */
     650             : /*                                                                      */
     651             : /*      Helper function for Debug().                                    */
     652             : /************************************************************************/
     653             : 
     654           0 : static void vDebug( void (*pfnDebug)(const char *),
     655             :                     const char *fmt, std::va_list args )
     656             : 
     657             : {
     658           0 :     std::string message;
     659             : 
     660             : /* -------------------------------------------------------------------- */
     661             : /*      This implementation for platforms without vsnprintf() will      */
     662             : /*      just plain fail if the formatted contents are too large.        */
     663             : /* -------------------------------------------------------------------- */
     664             : #if defined(MISSING_VSNPRINTF)
     665             :     char *pszBuffer = (char *) malloc(30000);
     666             :     if( vsprintf( pszBuffer, fmt, args) > 29998 )
     667             :     {
     668             :         message = "PCIDSK::Debug() ... buffer overrun.";
     669             :     }
     670             :     else
     671             :         message = pszBuffer;
     672             : 
     673             :     free( pszBuffer );
     674             : 
     675             : /* -------------------------------------------------------------------- */
     676             : /*      This should grow a big enough buffer to hold any formatted      */
     677             : /*      result.                                                         */
     678             : /* -------------------------------------------------------------------- */
     679             : #else
     680             :     char szModestBuffer[500];
     681             :     int nPR;
     682             :     va_list wrk_args;
     683             : 
     684             : #ifdef va_copy
     685           0 :     va_copy( wrk_args, args );
     686             : #else
     687             :     wrk_args = args;
     688             : #endif
     689             : 
     690           0 :     nPR = vsnprintf( szModestBuffer, sizeof(szModestBuffer), fmt,
     691             :                      wrk_args );
     692           0 :     if( nPR == -1 || nPR >= (int) sizeof(szModestBuffer)-1 )
     693             :     {
     694           0 :         int nWorkBufferSize = 2000;
     695           0 :         PCIDSKBuffer oWorkBuffer(nWorkBufferSize);
     696             : 
     697             : #ifdef va_copy
     698           0 :         va_end( wrk_args );
     699           0 :         va_copy( wrk_args, args );
     700             : #else
     701             :         wrk_args = args;
     702             : #endif
     703           0 :         while( (nPR=vsnprintf( oWorkBuffer.buffer, nWorkBufferSize, fmt, wrk_args))
     704           0 :                >= nWorkBufferSize-1
     705           0 :                || nPR == -1 )
     706             :         {
     707           0 :             nWorkBufferSize *= 4;
     708           0 :             oWorkBuffer.SetSize(nWorkBufferSize);
     709             : #ifdef va_copy
     710           0 :             va_end( wrk_args );
     711           0 :             va_copy( wrk_args, args );
     712             : #else
     713             :             wrk_args = args;
     714             : #endif
     715             :         }
     716           0 :         message = oWorkBuffer.buffer;
     717             :     }
     718             :     else
     719             :     {
     720           0 :         message = szModestBuffer;
     721             :     }
     722           0 :     va_end( wrk_args );
     723             : #endif
     724             : 
     725             : /* -------------------------------------------------------------------- */
     726             : /*      Forward the message.                                            */
     727             : /* -------------------------------------------------------------------- */
     728           0 :     pfnDebug( message.c_str() );
     729           0 : }
     730             : 
     731             : /************************************************************************/
     732             : /*                               Debug()                                */
     733             : /*                                                                      */
     734             : /*      Function to write output to a debug stream if one is            */
     735             : /*      enabled.  This is intended to be widely called in the           */
     736             : /*      library.                                                        */
     737             : /************************************************************************/
     738             : 
     739           0 : void PCIDSK::Debug( void (*pfnDebug)(const char *), const char *fmt, ... )
     740             : 
     741             : {
     742           0 :     if( pfnDebug == nullptr )
     743           0 :         return;
     744             : 
     745             :     std::va_list args;
     746             : 
     747           0 :     va_start( args, fmt );
     748           0 :     vDebug( pfnDebug, fmt, args );
     749           0 :     va_end( args );
     750             : }

Generated by: LCOV version 1.14