LCOV - code coverage report
Current view: directory - frmts/pcidsk/sdk/core - pcidsk_utils.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 237 158 66.7 %
Date: 2012-12-26 Functions: 20 14 70.0 %

       1                 : /******************************************************************************
       2                 :  *
       3                 :  * Purpose:  Various private (undocumented) utility functions.
       4                 :  * 
       5                 :  ******************************************************************************
       6                 :  * Copyright (c) 2009
       7                 :  * PCI Geomatics, 50 West Wilmot Street, Richmond Hill, Ont, Canada
       8                 :  *
       9                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      10                 :  * copy of this software and associated documentation files (the "Software"),
      11                 :  * to deal in the Software without restriction, including without limitation
      12                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      13                 :  * and/or sell copies of the Software, and to permit persons to whom the
      14                 :  * Software is furnished to do so, subject to the following conditions:
      15                 :  *
      16                 :  * The above copyright notice and this permission notice shall be included
      17                 :  * in all copies or substantial portions of the Software.
      18                 :  *
      19                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      20                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      21                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      22                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      23                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      24                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      25                 :  * DEALINGS IN THE SOFTWARE.
      26                 :  ****************************************************************************/
      27                 : #include "pcidsk_config.h"
      28                 : #include "pcidsk_types.h"
      29                 : #include "pcidsk_exception.h"
      30                 : #include "pcidsk_georef.h"
      31                 : #include "pcidsk_io.h"
      32                 : #include "core/pcidsk_utils.h"
      33                 : #include <cstdlib>
      34                 : #include <cstring>
      35                 : #include <cctype>
      36                 : #include <cstdio>
      37                 : #include <cmath>
      38                 : #include <iostream>
      39                 : 
      40                 : using namespace PCIDSK;
      41                 : 
      42                 : #if defined(_MSC_VER) && (_MSC_VER < 1500)
      43                 : #  define vsnprintf _vsnprintf
      44                 : #endif
      45                 : 
      46                 : /************************************************************************/
      47                 : /*                         GetCurrentDateTime()                         */
      48                 : /************************************************************************/
      49                 : 
      50                 : // format we want: "HH:MM DDMMMYYYY \0"
      51                 : 
      52                 : #include <time.h>
      53                 : #include <sys/types.h>
      54                 : 
      55             142 : void  PCIDSK::GetCurrentDateTime( char *out_time )
      56                 : 
      57                 : {
      58                 :     time_t      clock;
      59                 :     char            ctime_out[25];
      60                 : 
      61             142 :     time( &clock );
      62             142 :     strncpy( ctime_out, ctime(&clock), 24 ); // TODO: reentrance issue?
      63                 : 
      64                 :     // ctime() products: "Wed Jun 30 21:49:08 1993\n"
      65                 : 
      66             142 :     ctime_out[24] = '\0';
      67                 : 
      68             142 :     out_time[0] = ctime_out[11];
      69             142 :     out_time[1] = ctime_out[12];
      70             142 :     out_time[2] = ':';
      71             142 :     out_time[3] = ctime_out[14];
      72             142 :     out_time[4] = ctime_out[15];
      73             142 :     out_time[5] = ' ';
      74             142 :     out_time[6] = ctime_out[8];
      75             142 :     out_time[7] = ctime_out[9];
      76             142 :     out_time[8] = ctime_out[4];
      77             142 :     out_time[9] = ctime_out[5];
      78             142 :     out_time[10] = ctime_out[6];
      79             142 :     out_time[11] = ctime_out[20];
      80             142 :     out_time[12] = ctime_out[21];
      81             142 :     out_time[13] = ctime_out[22];
      82             142 :     out_time[14] = ctime_out[23];
      83             142 :     out_time[15] = ' ';
      84             142 :     out_time[16] = '\0';
      85             142 : }
      86                 : 
      87                 : /************************************************************************/
      88                 : /*                              UCaseStr()                              */
      89                 : /*                                                                      */
      90                 : /*      Force a string into upper case "in place".                      */
      91                 : /************************************************************************/
      92                 : 
      93              72 : std::string &PCIDSK::UCaseStr( std::string &target )
      94                 : 
      95                 : {
      96             392 :     for( unsigned int i = 0; i < target.size(); i++ )
      97                 :     {
      98             320 :         if( islower(target[i]) )
      99               0 :             target[i] = (char) toupper(target[i]);
     100                 :     }
     101                 :     
     102              72 :     return target;
     103                 : }
     104                 : 
     105                 : /************************************************************************/
     106                 : /*                             atouint64()                              */
     107                 : /************************************************************************/
     108                 : 
     109             992 : uint64 PCIDSK::atouint64( const char *str_value )
     110                 : 
     111                 : {
     112                 : #if defined(__MSVCRT__) || defined(_MSC_VER)
     113                 :     return (uint64) _atoi64( str_value );
     114                 : #else
     115             992 :     return (uint64) atoll( str_value );
     116                 : #endif
     117                 : }
     118                 : 
     119                 : /************************************************************************/
     120                 : /*                              atoint64()                              */
     121                 : /************************************************************************/
     122                 : 
     123               0 : int64 PCIDSK::atoint64( const char *str_value )
     124                 : 
     125                 : {
     126                 : #if defined(__MSVCRT__) || defined(_MSC_VER)
     127                 :     return (int64) _atoi64( str_value );
     128                 : #else
     129               0 :     return (int64) atoll( str_value );
     130                 : #endif
     131                 : }
     132                 : 
     133                 : /************************************************************************/
     134                 : /*                            SwapPixels()                              */
     135                 : /************************************************************************/
     136                 : /**
     137                 :  * @brief Perform an endianess swap for a given buffer of pixels
     138                 :  *
     139                 :  * Baed on the provided data type, do an appropriate endianess swap for
     140                 :  * a buffer of pixels. Deals with the Complex case specially, in
     141                 :  * particular.
     142                 :  *
     143                 :  * @param data the pixels to be swapped
     144                 :  * @param type the data type of the pixels
     145                 :  * @param count the count of pixels (not bytes, words, etc.)
     146                 :  */
     147             164 : void PCIDSK::SwapPixels(void* const data, 
     148                 :                         const eChanType type, 
     149                 :                         const std::size_t count)
     150                 : {
     151             164 :     switch(type) {
     152                 :     case CHN_8U:
     153                 :     case CHN_16U:
     154                 :     case CHN_16S:
     155                 :     case CHN_32R:
     156             124 :         SwapData(data, DataTypeSize(type), count);
     157             124 :         break;
     158                 :     case CHN_C16U:
     159                 :     case CHN_C16S:
     160                 :     case CHN_C32R:
     161              40 :         SwapData(data, DataTypeSize(type) / 2, count * 2);
     162              40 :         break;
     163                 :     default:
     164                 :         ThrowPCIDSKException("Unknown data type passed to SwapPixels."
     165               0 :             "This is a software bug. Please contact your vendor.");
     166                 :     }
     167             164 : }
     168                 : 
     169                 : /************************************************************************/
     170                 : /*                              SwapData()                              */
     171                 : /************************************************************************/
     172                 : 
     173          153531 : void PCIDSK::SwapData( void* const data, const int size, const int wcount )
     174                 : 
     175                 : {
     176          153531 :     uint8* data8 = reinterpret_cast<uint8*>(data);
     177          153531 :     std::size_t count = wcount;
     178                 : 
     179          153531 :     if( size == 2 )
     180                 :     {
     181                 :         uint8 t;
     182                 : 
     183            6220 :         for( ; count; count-- )
     184                 :         {
     185            6096 :             t = data8[0];
     186            6096 :             data8[0] = data8[1];
     187            6096 :             data8[1] = t;
     188                 : 
     189            6096 :             data8 += 2;
     190                 :         }
     191                 :     }
     192          153407 :     else if( size == 1 )
     193                 :         /* do nothing */; 
     194          153407 :     else if( size == 4 )
     195                 :     {
     196                 :         uint8 t;
     197                 : 
     198          163220 :         for( ; count; count-- )
     199                 :         {
     200           83589 :             t = data8[0];
     201           83589 :             data8[0] = data8[3];
     202           83589 :             data8[3] = t;
     203                 : 
     204           83589 :             t = data8[1];
     205           83589 :             data8[1] = data8[2];
     206           83589 :             data8[2] = t;
     207                 : 
     208           83589 :             data8 += 4;
     209                 :         }
     210                 :     }
     211           73776 :     else if( size == 8 )
     212                 :     {
     213                 :         uint8 t;
     214                 : 
     215          478298 :         for( ; count; count-- )
     216                 :         {
     217          404522 :             t = data8[0];
     218          404522 :             data8[0] = data8[7];
     219          404522 :             data8[7] = t;
     220                 : 
     221          404522 :             t = data8[1];
     222          404522 :             data8[1] = data8[6];
     223          404522 :             data8[6] = t;
     224                 : 
     225          404522 :             t = data8[2];
     226          404522 :             data8[2] = data8[5];
     227          404522 :             data8[5] = t;
     228                 : 
     229          404522 :             t = data8[3];
     230          404522 :             data8[3] = data8[4];
     231          404522 :             data8[4] = t;
     232                 : 
     233          404522 :             data8 += 8;
     234                 :         }
     235                 :     }
     236                 :     else
     237               0 :         ThrowPCIDSKException( "Unsupported data size in SwapData()" );
     238          153531 : }
     239                 : 
     240                 : /************************************************************************/
     241                 : /*                          BigEndianSystem()                           */
     242                 : /************************************************************************/
     243                 : 
     244             148 : bool PCIDSK::BigEndianSystem()
     245                 : 
     246                 : {
     247             148 :     unsigned short test_value = 1;
     248                 :     char test_char_value[2];
     249                 : 
     250             148 :     memcpy( test_char_value, &test_value, 2 );
     251                 : 
     252             148 :     return test_char_value[0] == 0;
     253                 : }
     254                 : 
     255                 : 
     256                 : /************************************************************************/
     257                 : /*                          ParseTileFormat()                           */
     258                 : /*                                                                      */
     259                 : /*      Parse blocksize and compression out of a TILED interleaving     */
     260                 : /*      string as passed to the Create() function or stored in          */
     261                 : /*      _DBLayout metadata.                                             */
     262                 : /************************************************************************/
     263                 : 
     264               3 : void PCIDSK::ParseTileFormat( std::string full_text, 
     265                 :                               int &block_size, std::string &compression )
     266                 : 
     267                 : {
     268               3 :     compression = "NONE";
     269               3 :     block_size = 127;
     270                 : 
     271               3 :     UCaseStr( full_text );
     272                 : 
     273                 : /* -------------------------------------------------------------------- */
     274                 : /*      Only operate on tiled stuff.                                    */
     275                 : /* -------------------------------------------------------------------- */
     276               3 :     if( strncmp(full_text.c_str(),"TILED",5) != 0 )
     277               0 :         return;
     278                 : 
     279                 : /* -------------------------------------------------------------------- */
     280                 : /*      Do we have a block size?                                        */
     281                 : /* -------------------------------------------------------------------- */
     282               3 :     const char *next_text = full_text.c_str() + 5;
     283                 : 
     284               3 :     if( isdigit(*next_text) )
     285                 :     {
     286               2 :         block_size = atoi(next_text);
     287               8 :         while( isdigit(*next_text) )
     288               4 :             next_text++;
     289                 :     }
     290                 :     
     291               8 :     while( *next_text == ' ' )
     292               2 :         next_text++;
     293                 : 
     294                 : /* -------------------------------------------------------------------- */
     295                 : /*      Do we have a compression type?                                  */
     296                 : /* -------------------------------------------------------------------- */
     297               3 :     if( *next_text != '\0' )
     298                 :     {
     299               2 :         compression = next_text;
     300               2 :         if (compression == "NO_WARNINGS")
     301               0 :             compression = "";
     302               2 :         else if( compression != "RLE"
     303                 :             && strncmp(compression.c_str(),"JPEG",4) != 0 
     304                 :             && compression != "NONE"
     305                 :             && compression != "QUADTREE" )
     306                 :         {
     307                 :             ThrowPCIDSKException( "Unsupported tile compression scheme '%s' requested.",
     308               0 :                                   compression.c_str() );
     309                 :         }
     310                 :     }    
     311                 : }
     312                 :                       
     313                 : /************************************************************************/
     314                 : /*                           pci_strcasecmp()                           */
     315                 : /************************************************************************/
     316                 : 
     317               0 : int PCIDSK::pci_strcasecmp( const char *string1, const char *string2 )
     318                 : 
     319                 : {
     320                 :     int i;
     321                 : 
     322               0 :     for( i = 0; string1[i] != '\0' && string2[i] != '\0'; i++ )
     323                 :     {
     324               0 :         char c1 = string1[i];
     325               0 :         char c2 = string2[i];
     326                 : 
     327               0 :         if( islower(c1) )
     328               0 :             c1 = (char) toupper(c1);
     329               0 :         if( islower(c2) )
     330               0 :             c2 = (char) toupper(c2);
     331                 : 
     332               0 :         if( c1 < c2 )
     333               0 :             return -1;
     334               0 :         else if( c1 > c2 )
     335               0 :             return 1;
     336                 :     }
     337                 : 
     338               0 :     if( string1[i] == '\0' && string2[i] == '\0' )
     339               0 :         return 0;
     340               0 :     else if( string1[i] == '\0' )
     341               0 :         return 1;
     342                 :     else
     343               0 :         return -1;
     344                 : }
     345                 : 
     346                 : /************************************************************************/
     347                 : /*                          pci_strncasecmp()                           */
     348                 : /************************************************************************/
     349                 : 
     350            2165 : int PCIDSK::pci_strncasecmp( const char *string1, const char *string2, int len )
     351                 : 
     352                 : {
     353                 :     int i;
     354                 : 
     355            4118 :     for( i = 0; i < len; i++ )
     356                 :     {
     357            3590 :         if( string1[i] == '\0' && string2[i] == '\0' )
     358               0 :             return 0;
     359            3590 :         else if( string1[i] == '\0' )
     360               0 :             return 1;
     361            3590 :         else if( string2[i] == '\0' )
     362               0 :             return -1;
     363                 : 
     364            3590 :         char c1 = string1[i];
     365            3590 :         char c2 = string2[i];
     366                 : 
     367            3590 :         if( islower(c1) )
     368               0 :             c1 = (char) toupper(c1);
     369            3590 :         if( islower(c2) )
     370               0 :             c2 = (char) toupper(c2);
     371                 : 
     372            3590 :         if( c1 < c2 )
     373             946 :             return -1;
     374            2644 :         else if( c1 > c2 )
     375             691 :             return 1;
     376                 :     }
     377                 : 
     378             528 :     return 0;
     379                 : }
     380                 : 
     381                 : /************************************************************************/
     382                 : /*                         ProjParmsFromText()                          */
     383                 : /*                                                                      */
     384                 : /*      function to turn a ProjParms string (17 floating point          */
     385                 : /*      numbers) into an array, as well as attaching the units code     */
     386                 : /*      derived from the geosys string.                                 */
     387                 : /************************************************************************/
     388                 : 
     389              27 : std::vector<double> PCIDSK::ProjParmsFromText( std::string geosys, 
     390                 :                                                std::string sparms )
     391                 : 
     392                 : {
     393              27 :     std::vector<double> dparms;
     394              27 :     const char *next = sparms.c_str();
     395                 : 
     396             192 :     for( next = sparms.c_str(); *next != '\0'; )
     397                 :     {
     398             138 :         dparms.push_back( atof(next) );
     399                 : 
     400                 :         // move past this token
     401             414 :         while( *next != '\0' && *next != ' ' )
     402             138 :             next++;
     403                 : 
     404                 :         // move past white space.
     405             406 :         while( *next != '\0' && *next == ' ' )
     406             130 :             next++;
     407                 :     }
     408                 : 
     409              27 :     dparms.resize(18);
     410                 : 
     411                 :     // This is rather iffy!
     412              27 :     if( EQUALN(geosys.c_str(),"DEGREE",3) )
     413               0 :         dparms[17] = (double) (int) UNIT_DEGREE;
     414              27 :     else if( EQUALN(geosys.c_str(),"MET",3) )
     415              19 :         dparms[17] = (double) (int) UNIT_METER;
     416               8 :     else if( EQUALN(geosys.c_str(),"FOOT",4) )
     417               0 :         dparms[17] = (double) (int) UNIT_US_FOOT;
     418               8 :     else if( EQUALN(geosys.c_str(),"FEET",4) )
     419               0 :         dparms[17] = (double) (int) UNIT_US_FOOT;
     420               8 :     else if( EQUALN(geosys.c_str(),"INTL FOOT",5) )
     421               0 :         dparms[17] = (double) (int) UNIT_INTL_FOOT;
     422               8 :     else if( EQUALN(geosys.c_str(),"SPCS",4) )
     423               0 :         dparms[17] = (double) (int) UNIT_METER;
     424               8 :     else if( EQUALN(geosys.c_str(),"SPIF",4) )
     425               0 :         dparms[17] = (double) (int) UNIT_INTL_FOOT;
     426               8 :     else if( EQUALN(geosys.c_str(),"SPAF",4) )
     427               0 :         dparms[17] = (double) (int) UNIT_US_FOOT;
     428                 :     else
     429               8 :         dparms[17] = -1.0; /* unknown */
     430                 :     
     431               0 :     return dparms;
     432                 : }
     433                 : 
     434                 : /************************************************************************/
     435                 : /*                          ProjParmsToText()                           */
     436                 : /************************************************************************/
     437                 : 
     438               2 : std::string PCIDSK::ProjParmsToText( std::vector<double> dparms )
     439                 : 
     440                 : {
     441                 :     unsigned int i;
     442               2 :     std::string sparms;
     443                 : 
     444              36 :     for( i = 0; i < 17; i++ )
     445                 :     {
     446                 :         char value[64];
     447                 :         double dvalue;
     448                 : 
     449              34 :         if( i < dparms.size() )
     450              34 :             dvalue = dparms[i];
     451                 :         else
     452               0 :             dvalue = 0.0;
     453                 : 
     454              34 :         if( dvalue == floor(dvalue) )
     455              34 :             sprintf( value, "%d", (int) dvalue );
     456                 :         else
     457               0 :             sprintf( value, "%.15g", dvalue );
     458                 :         
     459              34 :         if( i > 0 )
     460              32 :             sparms += " ";
     461                 :         
     462              34 :         sparms += value;
     463                 :     }
     464                 : 
     465               0 :     return sparms;
     466                 : }
     467                 : 
     468                 : /************************************************************************/
     469                 : /*                            ExtractPath()                             */
     470                 : /*                                                                      */
     471                 : /*      Extract the directory path portion of the passed filename.      */
     472                 : /*      It assumes the last component is a filename and should not      */
     473                 : /*      be passed a bare path.  The trailing directory delimeter is     */
     474                 : /*      removed from the result.  The return result is an empty         */
     475                 : /*      string for a simple filename passed in with no directory        */
     476                 : /*      component.                                                      */
     477                 : /************************************************************************/
     478                 : 
     479               7 : std::string PCIDSK::ExtractPath( std::string filename )
     480                 : 
     481                 : {
     482                 :     int i;
     483                 : 
     484             105 :     for( i = filename.size()-1; i >= 0; i-- )
     485                 :     {
     486             105 :         if( filename[i] == '\\' || filename[i] == '/' )
     487               7 :             break;
     488                 :     }
     489                 : 
     490               7 :     if( i > 0 )
     491               7 :         return filename.substr(0,i);
     492                 :     else
     493               0 :         return "";
     494                 : }
     495                 : 
     496                 : /************************************************************************/
     497                 : /*                         MergeRelativePath()                          */
     498                 : /*                                                                      */
     499                 : /*      This attempts to take src_filename and make it relative to      */
     500                 : /*      the base of the file "base", if this evaluates to a new file    */
     501                 : /*      in the filesystem.  It will not make any change if              */
     502                 : /*      src_filename appears to be absolute or if the altered path      */
     503                 : /*      does not resolve to a file in the filesystem.                   */
     504                 : /************************************************************************/
     505                 : 
     506             185 : std::string PCIDSK::MergeRelativePath( const PCIDSK::IOInterfaces *io_interfaces,
     507                 :                                        std::string base, 
     508                 :                                        std::string src_filename )
     509                 : 
     510                 : {
     511                 : /* -------------------------------------------------------------------- */
     512                 : /*      Does src_filename appear to be absolute?                        */
     513                 : /* -------------------------------------------------------------------- */
     514             185 :     if( src_filename.size() == 0 )
     515             169 :         return src_filename; // we can't do anything with a blank.
     516              16 :     else if( src_filename.size() > 2 && src_filename[1] == ':' )
     517               0 :         return src_filename; // has a drive letter?
     518              16 :     else if( src_filename[0] == '/' || src_filename[0] == '\\' )
     519               9 :         return src_filename; // has a leading dir marker. 
     520                 : 
     521                 : /* -------------------------------------------------------------------- */
     522                 : /*      Figure out what path split char we want to use.                 */
     523                 : /* -------------------------------------------------------------------- */
     524                 : #if defined(__MSVCRT__) || defined(_MSC_VER)
     525                 :     const static char  path_split = '\\';
     526                 : #else
     527                 :     const static char  path_split = '/';
     528                 : #endif
     529                 : 
     530                 : /* -------------------------------------------------------------------- */
     531                 : /*      Merge paths.                                                    */
     532                 : /* -------------------------------------------------------------------- */
     533               7 :     std::string base_path = ExtractPath( base );
     534               7 :     std::string result;
     535                 : 
     536               7 :     if( base_path == "" )
     537               0 :         return src_filename;
     538                 : 
     539               7 :     result = base_path;
     540               7 :     result += path_split;
     541               7 :     result += src_filename;
     542                 : 
     543                 : /* -------------------------------------------------------------------- */
     544                 : /*      Check if the target exists by this name.                        */
     545                 : /* -------------------------------------------------------------------- */
     546                 :     try 
     547                 :     {
     548               9 :         void *hFile = io_interfaces->Open( result, "r" );
     549                 :         // should throw an exception on failure.
     550               5 :         io_interfaces->Close( hFile );
     551               5 :         return result;
     552                 :     }
     553               4 :     catch( ... )
     554                 :     {
     555               2 :         return src_filename;
     556               0 :     }
     557                 : }
     558                 : 
     559                 : 
     560                 : /************************************************************************/
     561                 : /*                            DefaultDebug()                            */
     562                 : /*                                                                      */
     563                 : /*      Default implementation of the Debug() output interface.         */
     564                 : /************************************************************************/
     565                 : 
     566               0 : void PCIDSK::DefaultDebug( const char * message )
     567                 : 
     568                 : {
     569                 :     static bool initialized = false;
     570                 :     static bool enabled = false;
     571                 :     
     572               0 :     if( !initialized )
     573                 :     {
     574               0 :         if( getenv( "PCIDSK_DEBUG" ) != NULL )
     575               0 :             enabled = true;
     576                 : 
     577               0 :         initialized = true;
     578                 :     }
     579                 : 
     580               0 :     if( enabled )
     581               0 :         std::cerr << message;
     582               0 : }
     583                 : 
     584                 : /************************************************************************/
     585                 : /*                               vDebug()                               */
     586                 : /*                                                                      */
     587                 : /*      Helper function for Debug().                                    */
     588                 : /************************************************************************/
     589                 : 
     590               0 : static void vDebug( void (*pfnDebug)(const char *),
     591                 :                     const char *fmt, std::va_list args )
     592                 : 
     593                 : {
     594               0 :     std::string message;
     595                 : 
     596                 : /* -------------------------------------------------------------------- */
     597                 : /*      This implementation for platforms without vsnprintf() will      */
     598                 : /*      just plain fail if the formatted contents are too large.        */
     599                 : /* -------------------------------------------------------------------- */
     600                 : #if defined(MISSING_VSNPRINTF)
     601                 :     char *pszBuffer = (char *) malloc(30000);
     602                 :     if( vsprintf( pszBuffer, fmt, args) > 29998 )
     603                 :     {
     604                 :         message = "PCIDSK::Debug() ... buffer overrun.";
     605                 :     }
     606                 :     else
     607                 :         message = pszBuffer;
     608                 : 
     609                 :     free( pszBuffer );
     610                 : 
     611                 : /* -------------------------------------------------------------------- */
     612                 : /*      This should grow a big enough buffer to hold any formatted      */
     613                 : /*      result.                                                         */
     614                 : /* -------------------------------------------------------------------- */
     615                 : #else
     616                 :     char szModestBuffer[500];
     617                 :     int nPR;
     618                 :     va_list wrk_args;
     619                 : 
     620                 : #ifdef va_copy
     621               0 :     va_copy( wrk_args, args );
     622                 : #else
     623                 :     wrk_args = args;
     624                 : #endif
     625                 :     
     626                 :     nPR = vsnprintf( szModestBuffer, sizeof(szModestBuffer), fmt, 
     627               0 :                      wrk_args );
     628               0 :     if( nPR == -1 || nPR >= (int) sizeof(szModestBuffer)-1 )
     629                 :     {
     630               0 :         int nWorkBufferSize = 2000;
     631               0 :         char *pszWorkBuffer = (char *) malloc(nWorkBufferSize);
     632                 : 
     633                 : #ifdef va_copy
     634               0 :         va_end( wrk_args );
     635               0 :         va_copy( wrk_args, args );
     636                 : #else
     637                 :         wrk_args = args;
     638                 : #endif
     639               0 :         while( (nPR=vsnprintf( pszWorkBuffer, nWorkBufferSize, fmt, wrk_args))
     640                 :                >= nWorkBufferSize-1 
     641                 :                || nPR == -1 )
     642                 :         {
     643               0 :             nWorkBufferSize *= 4;
     644                 :             pszWorkBuffer = (char *) realloc(pszWorkBuffer, 
     645               0 :                                              nWorkBufferSize );
     646                 : #ifdef va_copy
     647               0 :             va_end( wrk_args );
     648               0 :             va_copy( wrk_args, args );
     649                 : #else
     650                 :             wrk_args = args;
     651                 : #endif
     652                 :         }
     653               0 :         message = pszWorkBuffer;
     654               0 :         free( pszWorkBuffer );
     655                 :     }
     656                 :     else
     657                 :     {
     658               0 :         message = szModestBuffer;
     659                 :     }
     660               0 :     va_end( wrk_args );
     661                 : #endif
     662                 : 
     663                 : /* -------------------------------------------------------------------- */
     664                 : /*      Forward the message.                                            */
     665                 : /* -------------------------------------------------------------------- */
     666               0 :     pfnDebug( message.c_str() );
     667               0 : }
     668                 : 
     669                 : /************************************************************************/
     670                 : /*                               Debug()                                */
     671                 : /*                                                                      */
     672                 : /*      Function to write output to a debug stream if one is            */
     673                 : /*      enabled.  This is intended to be widely called in the           */
     674                 : /*      library.                                                        */
     675                 : /************************************************************************/
     676                 : 
     677               0 : void PCIDSK::Debug( void (*pfnDebug)(const char *), const char *fmt, ... )
     678                 : 
     679                 : {
     680               0 :     if( pfnDebug == NULL )
     681               0 :         return;
     682                 : 
     683                 :     std::va_list args;
     684                 : 
     685               0 :     va_start( args, fmt );
     686               0 :     vDebug( pfnDebug, fmt, args );
     687               0 :     va_end( args );
     688            2139 : }

Generated by: LCOV version 1.7