LCOV - code coverage report
Current view: top level - frmts/gtiff/libgeotiff - geo_print.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 0 260 0.0 %
Date: 2026-07-24 18:27:47 Functions: 0 10 0.0 %

          Line data    Source code
       1             : /**********************************************************************
       2             :  *
       3             :  *  geo_print.c  -- Key-dumping routines for GEOTIFF files.
       4             :  *
       5             :  *    Written By: Niles D. Ritter.
       6             :  *
       7             :  *  copyright (c) 1995   Niles D. Ritter
       8             :  *
       9             :  *  Permission granted to use this software, so long as this copyright
      10             :  *  notice accompanies any products derived therefrom.
      11             :  *
      12             :  **********************************************************************/
      13             : 
      14             : #include <stdio.h>
      15             : #include <string.h>
      16             : #include <limits.h>
      17             : 
      18             : #include "geotiff.h"   /* public interface        */
      19             : #include "geo_tiffp.h" /* external TIFF interface */
      20             : #include "geo_keyp.h"  /* private interface       */
      21             : #include "geokeys.h"
      22             : 
      23             : 
      24             : #define FMT_GEOTIFF "Geotiff_Information:"
      25             : #define FMT_VERSION "Version: %hu"
      26             : #define FMT_REV     "Key_Revision: %1hu.%hu"
      27             : #define FMT_TAGS    "Tagged_Information:"
      28             : #define FMT_TAGEND  "End_Of_Tags."
      29             : #define FMT_KEYS    "Keyed_Information:"
      30             : #define FMT_KEYEND  "End_Of_Keys."
      31             : #define FMT_GEOEND  "End_Of_Geotiff."
      32             : #define FMT_DOUBLE  "%-17.15g"
      33             : #define FMT_SHORT   "%-11hu"
      34             : 
      35             : static int DefaultPrint(char *string, void *aux);
      36             : static void PrintKey(GTIF *gtif,GeoKey *key, GTIFPrintMethod print,void *aux);
      37             : static void PrintGeoTags(GTIF *gtif,GTIFReadMethod scan,void *aux);
      38             : static void PrintTag(int tag, int nrows, double *data, int ncols,
      39             :           GTIFPrintMethod print,void *aux);
      40             : static int DefaultRead(char *string, void *aux);
      41             : static int  ReadKey(GTIF *gt, GTIFReadMethod scan, void *aux);
      42             : static int  ReadTag(GTIF *gt,GTIFReadMethod scan,void *aux);
      43             : 
      44             : /*
      45             :  * Print off the directory info, using whatever method is specified
      46             :  * (defaults to fprintf if null). The "aux" parameter is provided for user
      47             :  * defined method for passing parameters or whatever.
      48             :  *
      49             :  * The output format is a "GeoTIFF meta-data" file, which may be
      50             :  * used to import information with the GTIFFImport() routine.
      51             :  */
      52             : 
      53           0 : void GTIFPrint(GTIF *gtif, GTIFPrintMethod print,void *aux)
      54             : {
      55             : 
      56           0 :     if (!print) print = &DefaultPrint;
      57           0 :     if (!aux) aux=stdout;
      58             : 
      59             :     char message[1024];
      60           0 :     sprintf(message,FMT_GEOTIFF "\n");
      61           0 :     print(message,aux);
      62           0 :     sprintf(message, FMT_VERSION,gtif->gt_version);
      63           0 :     print("   ",aux); print(message,aux); print("\n",aux);
      64           0 :     sprintf(message, FMT_REV,gtif->gt_rev_major,
      65           0 :             gtif->gt_rev_minor);
      66           0 :     print("   ",aux); print(message,aux); print("\n",aux);
      67             : 
      68           0 :     sprintf(message,"   %s\n",FMT_TAGS); print(message,aux);
      69           0 :     PrintGeoTags(gtif,print,aux);
      70           0 :     sprintf(message,"      %s\n",FMT_TAGEND); print(message,aux);
      71             : 
      72           0 :     sprintf(message,"   %s\n",FMT_KEYS); print(message,aux);
      73           0 :     int numkeys = gtif->gt_num_keys;
      74           0 :     GeoKey *key = gtif->gt_keys;
      75           0 :     for (int i=0; i<numkeys; i++)
      76             :     {
      77           0 :         ++key;
      78           0 :         PrintKey(gtif, key,print,aux);
      79             :     }
      80           0 :     sprintf(message,"      %s\n",FMT_KEYEND); print(message,aux);
      81             : 
      82           0 :     sprintf(message,"   %s\n",FMT_GEOEND); print(message,aux);
      83           0 : }
      84             : 
      85           0 : static void PrintGeoTags(GTIF *gt, GTIFPrintMethod print,void *aux)
      86             : {
      87           0 :   tiff_t *tif=gt->gt_tif;
      88           0 :         if( tif == NULL )
      89           0 :             return;
      90             : 
      91             :   double *data;
      92             :   int count;
      93             : 
      94           0 :   if ((gt->gt_methods.get)(tif, GTIFF_TIEPOINTS, &count, &data ))
      95           0 :     PrintTag(GTIFF_TIEPOINTS,count/3, data, 3, print, aux);
      96           0 :   if ((gt->gt_methods.get)(tif, GTIFF_PIXELSCALE, &count, &data ))
      97           0 :     PrintTag(GTIFF_PIXELSCALE,count/3, data, 3, print, aux);
      98           0 :   if ((gt->gt_methods.get)(tif, GTIFF_TRANSMATRIX, &count, &data ))
      99           0 :     PrintTag(GTIFF_TRANSMATRIX,count/4, data, 4, print, aux);
     100             : }
     101             : 
     102           0 : static void PrintTag(int tag, int nrows, double *dptr, int ncols,
     103             :           GTIFPrintMethod print,void *aux)
     104             : {
     105           0 :   print("      ",aux);
     106           0 :   print(GTIFTagName(tag),aux);
     107             : 
     108             :         char message[1024];
     109           0 :   sprintf(message," (%d,%d):\n",nrows,ncols);
     110           0 :   print(message,aux);
     111             : 
     112           0 :   double *data=dptr;
     113           0 :   for (int i=0;i<nrows;i++)
     114             :   {
     115           0 :     print("         ",aux);
     116           0 :     for (int j=0;j<ncols;j++)
     117             :     {
     118           0 :       sprintf(message,FMT_DOUBLE,*data++);
     119           0 :       print(message,aux);
     120             : 
     121           0 :                         if( j < ncols-1 )
     122           0 :                             print(" ",aux);
     123             :     }
     124           0 :     print("\n",aux);
     125             :   }
     126           0 :   _GTIFFree(dptr); /* free up the allocated memory */
     127           0 : }
     128             : 
     129           0 : static void PrintKey(GTIF *gtif, GeoKey *key, GTIFPrintMethod print, void *aux)
     130             : {
     131             : 
     132           0 :     print("      ",aux);
     133           0 :     const geokey_t keyid = (geokey_t) key->gk_key;
     134           0 :     print((char*)GTIFKeyNameEx(gtif, keyid),aux);
     135             : 
     136           0 :     int count = (int) key->gk_count;
     137             :     char message[40];
     138           0 :     sprintf(message," (%s,%d): ",GTIFTypeName(key->gk_type),count);
     139           0 :     print(message,aux);
     140             : 
     141             :     char *data;
     142           0 :     if (key->gk_type==TYPE_SHORT && count==1)
     143           0 :         data = (char *)&key->gk_data;
     144             :     else
     145           0 :         data = key->gk_data;
     146             : 
     147             :     int vals_now;
     148             :     pinfo_t *sptr;
     149             :     double *dptr;
     150           0 :     switch (key->gk_type)
     151             :     {
     152           0 :       case TYPE_ASCII:
     153             :       {
     154           0 :           print("\"",aux);
     155             : 
     156           0 :           int in_char = 0;
     157           0 :           int out_char = 0;
     158           0 :           while( in_char < count-1 )
     159             :           {
     160           0 :               const char ch = ((char *) data)[in_char++];
     161             : 
     162           0 :               if( ch == '\n' )
     163             :               {
     164           0 :                   message[out_char++] = '\\';
     165           0 :                   message[out_char++] = 'n';
     166             :               }
     167           0 :               else if( ch == '\\' )
     168             :               {
     169           0 :                   message[out_char++] = '\\';
     170           0 :                   message[out_char++] = '\\';
     171             :               }
     172             :               else
     173           0 :                   message[out_char++] = ch;
     174             : 
     175             :               /* flush message if buffer full */
     176           0 :               if( (size_t)out_char >= sizeof(message)-3 )
     177             :               {
     178           0 :                   message[out_char] = '\0';
     179           0 :                   print(message,aux);
     180           0 :                   out_char = 0;
     181             :               }
     182             :           }
     183             : 
     184           0 :           message[out_char]='\0';
     185           0 :           print(message,aux);
     186             : 
     187           0 :           print("\"\n",aux);
     188             :       }
     189           0 :       break;
     190             : 
     191           0 :       case TYPE_DOUBLE:
     192           0 :         for (dptr = (double *)data; count > 0; count-= vals_now)
     193             :         {
     194           0 :             vals_now = count > 3? 3: count;
     195           0 :             for (int i=0; i<vals_now; i++,dptr++)
     196             :             {
     197           0 :                 sprintf(message,FMT_DOUBLE ,*dptr);
     198           0 :                 print(message,aux);
     199             :             }
     200           0 :             print("\n",aux);
     201             :         }
     202           0 :         break;
     203             : 
     204           0 :       case TYPE_SHORT:
     205           0 :         sptr = (pinfo_t *)data;
     206           0 :         if (count==1)
     207             :         {
     208           0 :             print( (char*)GTIFValueNameEx(gtif,keyid,*sptr), aux );
     209           0 :             print( "\n", aux );
     210             :         }
     211           0 :         else if( sptr == NULL && count > 0 )
     212           0 :             print( "****Corrupted data****\n", aux );
     213             :         else
     214             :         {
     215           0 :             for (; count > 0; count-= vals_now)
     216             :             {
     217           0 :                 vals_now = count > 3? 3: count;
     218           0 :                 for (int i=0; i<vals_now; i++,sptr++)
     219             :                 {
     220           0 :                     sprintf(message,FMT_SHORT,*sptr);
     221           0 :                     print(message,aux);
     222             :                 }
     223           0 :                 print("\n",aux);
     224             :             }
     225             :         }
     226           0 :         break;
     227             : 
     228           0 :       default:
     229           0 :         sprintf(message, "Unknown Type (%d)\n",key->gk_type);
     230           0 :         print(message,aux);
     231           0 :         break;
     232             :     }
     233           0 : }
     234             : 
     235           0 : static int DefaultPrint(char *string, void *aux)
     236             : {
     237             :     /* Pretty boring */
     238           0 :     fprintf((FILE *)aux,"%s",string);
     239           0 :     return 1;
     240             : }
     241             : 
     242             : 
     243             : /*
     244             :  *  Importing metadata file
     245             :  */
     246             : 
     247             : /*
     248             :  * Import the directory info, using whatever method is specified
     249             :  * (defaults to fscanf if null). The "aux" parameter is provided for user
     250             :  * defined method for passing file or whatever.
     251             :  *
     252             :  * The input format is a "GeoTIFF meta-data" file, which may be
     253             :  * generated by the GTIFFPrint() routine.
     254             :  */
     255             : 
     256           0 : int GTIFImport(GTIF *gtif, GTIFReadMethod scan,void *aux)
     257             : {
     258           0 :     if (!scan) scan = &DefaultRead;
     259           0 :     if (!aux) aux=stdin;
     260             : 
     261             :     /* Caution: if you change this size, also change it in DefaultRead */
     262             :     char message[1024];
     263           0 :     scan(message,aux);
     264           0 :     if (strncmp(message,FMT_GEOTIFF,8)) return 0;
     265           0 :     scan(message,aux);
     266           0 :     if (!sscanf(message,FMT_VERSION,(short unsigned*)&gtif->gt_version)) return 0;
     267           0 :     scan(message,aux);
     268           0 :     if (sscanf(message,FMT_REV,(short unsigned*)&gtif->gt_rev_major,
     269           0 :                (short unsigned*)&gtif->gt_rev_minor) !=2) return 0;
     270             : 
     271           0 :     scan(message,aux);
     272           0 :     if (strncmp(message,FMT_TAGS,8)) return 0;
     273             :     int status;
     274           0 :     while ((status=ReadTag(gtif,scan,aux))>0);
     275           0 :     if (status < 0) return 0;
     276             : 
     277           0 :     scan(message,aux);
     278           0 :     if (strncmp(message,FMT_KEYS,8)) return 0;
     279           0 :     while ((status=ReadKey(gtif,scan,aux))>0);
     280             : 
     281           0 :     return (status==0); /* success */
     282             : }
     283             : 
     284           0 : static int StringError(char *string)
     285             : {
     286           0 :     fprintf(stderr,"Parsing Error at \'%s\'\n",string);
     287           0 :     return -1;
     288             : }
     289             : 
     290             : #define SKIPWHITE(vptr) \
     291             :   while (*vptr && (*vptr==' '||*vptr=='\t')) vptr++
     292             : #define FINDCHAR(vptr,c) \
     293             :   while (*vptr && *vptr!=(c)) vptr++
     294             : 
     295           0 : static int ReadTag(GTIF *gt,GTIFReadMethod scan,void *aux)
     296             : {
     297             :     char message[1024];
     298             : 
     299           0 :     scan(message,aux);
     300           0 :     if (!strncmp(message,FMT_TAGEND,8)) return 0;
     301             : 
     302             :     char tagname[100];
     303             :     int nrows;
     304             :     int ncols;
     305           0 :     const int num=sscanf(message,"%99[^( ] (%d,%d):\n",tagname,&nrows,&ncols);
     306           0 :     if (num!=3) return StringError(message);
     307             : 
     308           0 :     const int tag = GTIFTagCode(tagname);
     309           0 :     if (tag < 0) return StringError(tagname);
     310             : 
     311           0 :     if (nrows <= 0 || ncols <= 0 || (size_t)nrows > INT_MAX / ncols / sizeof(double))
     312             :     {
     313           0 :         return StringError(tagname);
     314             :     }
     315             : 
     316           0 :     const int count = nrows*ncols;
     317             : 
     318           0 :     double *data = (double *) _GTIFcalloc(count * sizeof(double));
     319           0 :     if (!data)
     320             :     {
     321           0 :         fprintf(stderr,"Out of memory error allocating memory for tag %s\n",tagname);
     322           0 :         return -1;
     323             :     }
     324           0 :     double *dptr = data;
     325             : 
     326           0 :     for (int i=0;i<nrows;i++)
     327             :     {
     328           0 :         scan(message,aux);
     329           0 :         char *vptr = message;
     330           0 :         for (int j=0;j<ncols;j++)
     331             :         {
     332           0 :             if (!sscanf(vptr,"%lg",dptr++))
     333             :             {
     334           0 :                 _GTIFFree( data );
     335           0 :                 return StringError(vptr);
     336             :             }
     337           0 :             FINDCHAR(vptr,' ');
     338           0 :             SKIPWHITE(vptr);
     339             :         }
     340             :     }
     341           0 :     (gt->gt_methods.set)(gt->gt_tif, (pinfo_t) tag, count, data );
     342             : 
     343           0 :     _GTIFFree( data );
     344             : 
     345           0 :     return 1;
     346             : }
     347             : 
     348             : 
     349           0 : static int ReadKey(GTIF *gt, GTIFReadMethod scan, void *aux)
     350             : {
     351             :     char message[2048];
     352           0 :     scan(message,aux);
     353           0 :     if (!strncmp(message,FMT_KEYEND,8)) return 0;
     354             : 
     355             :     char name[1000];
     356             :     char type[20];
     357             :     int count;
     358           0 :     const int num = sscanf(message,"%99[^( ] (%19[^,],%d):\n",name,type,&count);
     359           0 :     if (num!=3) return StringError(message);
     360             : 
     361           0 :     if (count <= 0)
     362             :     {
     363           0 :         return StringError(message);
     364             :     }
     365             : 
     366           0 :     char *vptr = message;
     367           0 :     FINDCHAR(vptr,':');
     368           0 :     if (!*vptr) return StringError(message);
     369           0 :     vptr+=2;
     370             : 
     371           0 :     const int keycode = GTIFKeyCode(name);
     372             :     geokey_t key;
     373           0 :     if( keycode < 0 )
     374           0 :         return StringError(name);
     375             :     else
     376           0 :         key = (geokey_t) keycode;
     377             : 
     378           0 :     const int typecode = GTIFTypeCode(type);
     379             :     tagtype_t ktype;
     380           0 :     if( typecode < 0 )
     381           0 :         return StringError(type);
     382             :     else
     383           0 :         ktype = (tagtype_t) typecode;
     384             : 
     385             :     /* skip white space */
     386           0 :     SKIPWHITE(vptr);
     387           0 :     if (!*vptr) return StringError(message);
     388             : 
     389             :     int outcount;
     390             :     int vals_now;
     391             :     int icode;
     392             :     pinfo_t code;
     393             :     short  *sptr;
     394             :     double *dptr;
     395             : 
     396           0 :     switch (ktype)
     397             :     {
     398           0 :       case TYPE_ASCII:
     399             :       {
     400             :           char *cdata;
     401           0 :           int out_char = 0;
     402             : 
     403           0 :           FINDCHAR(vptr,'"');
     404           0 :           if (!*vptr) return StringError(message);
     405             : 
     406           0 :           cdata = (char *) _GTIFcalloc( count+1 );
     407             : 
     408           0 :           vptr++;
     409           0 :           while( out_char < count-1 )
     410             :           {
     411           0 :               if( *vptr == '\0' )
     412           0 :                   break;
     413             : 
     414           0 :               else if( vptr[0] == '\\' && vptr[1] == 'n' )
     415             :               {
     416           0 :                   cdata[out_char++] = '\n';
     417           0 :                   vptr += 2;
     418             :               }
     419           0 :               else if( vptr[0] == '\\' && vptr[1] == '\\' )
     420             :               {
     421           0 :                   cdata[out_char++] = '\\';
     422           0 :                   vptr += 2;
     423             :               }
     424             :               else
     425           0 :                   cdata[out_char++] = *(vptr++);
     426             :           }
     427             : 
     428           0 :           if( out_char < count-1 ||  *vptr != '"' )
     429             :           {
     430           0 :               _GTIFFree( cdata );
     431           0 :               return StringError(message);
     432             :           }
     433             : 
     434           0 :           cdata[count-1] = '\0';
     435           0 :           GTIFKeySet(gt,key,ktype,count,cdata);
     436             : 
     437           0 :           _GTIFFree( cdata );
     438             :       }
     439           0 :       break;
     440             : 
     441           0 :       case TYPE_DOUBLE:
     442             :       {
     443           0 :         if ((size_t)count > INT_MAX / sizeof(double))
     444             :         {
     445           0 :             fprintf(stderr,"Too large count for key %s\n",name);
     446           0 :             return -1;
     447             :         }
     448           0 :         double *data = (double *) _GTIFcalloc(count * sizeof(double));
     449           0 :         if (!data)
     450             :         {
     451           0 :             fprintf(stderr,"Out of memory error allocating memory for key %s\n",name);
     452           0 :             return -1;
     453             :         }
     454             : 
     455           0 :         outcount = count;
     456             : 
     457           0 :         for (dptr = data; count > 0; count-= vals_now)
     458             :         {
     459           0 :             vals_now = count > 3? 3: count;
     460           0 :             for (int i=0; i<vals_now; i++,dptr++)
     461             :             {
     462           0 :                 if (!sscanf(vptr,"%lg" ,dptr))
     463           0 :                     StringError(vptr);
     464           0 :                 FINDCHAR(vptr,' ');
     465           0 :                 SKIPWHITE(vptr);
     466             :             }
     467           0 :             if (vals_now<count)
     468             :             {
     469           0 :                 scan(message,aux);
     470           0 :                 vptr = message;
     471             :             }
     472             :         }
     473           0 :         if (outcount==1)
     474           0 :             GTIFKeySet(gt,key,ktype,outcount,data[0]);
     475             :         else
     476           0 :             GTIFKeySet(gt,key,ktype,outcount,data);
     477           0 :         _GTIFFree(data);
     478           0 :         break;
     479             :       }
     480             : 
     481           0 :       case TYPE_SHORT:
     482           0 :         if (count==1)
     483             :         {
     484           0 :             icode = GTIFValueCode(key,vptr);
     485           0 :             if (icode < 0) return StringError(vptr);
     486           0 :             code = (pinfo_t) icode;
     487           0 :             GTIFKeySet(gt,key,ktype,count,code);
     488             :         }
     489             :         else  /* multi-valued short - no such thing yet */
     490             :         {
     491           0 :             if ((size_t)count > INT_MAX / sizeof(short))
     492             :             {
     493           0 :                 fprintf(stderr,"Too large count for key %s\n",name);
     494           0 :                 return -1;
     495             :             }
     496           0 :             short *data = (short *) _GTIFcalloc(count * sizeof(short));
     497           0 :             if (!data)
     498             :             {
     499           0 :                 fprintf(stderr,"Out of memory error allocating memory for key %s\n",name);
     500           0 :                 return -1;
     501             :             }
     502           0 :             outcount = count;
     503           0 :             for (sptr = data; count > 0; count-= vals_now)
     504             :             {
     505           0 :                 vals_now = count > 3? 3: count;
     506           0 :                 for (int i=0; i<vals_now; i++,sptr++)
     507             :                 {
     508             :                     int   work_int;
     509             : 
     510             :                     /* note: FMT_SHORT (%11hd) not supported on IRIX */
     511           0 :                     sscanf(message,"%11d",&work_int);
     512           0 :                     *sptr = (short) work_int;
     513           0 :                     scan(message,aux);
     514             :                 }
     515           0 :                 if (vals_now<count)
     516             :                 {
     517           0 :                     scan(message,aux);
     518             :                     /* FIXME: the following is dead assignment */
     519             :                     /*vptr = message;*/
     520             :                 }
     521             :             }
     522           0 :             GTIFKeySet(gt,key,ktype,outcount,sptr);
     523           0 :             _GTIFFree(data);
     524             :         }
     525           0 :         break;
     526             : 
     527           0 :       default:
     528           0 :         return -1;
     529             :     }
     530           0 :     return 1;
     531             : }
     532             : 
     533             : 
     534           0 : static int DefaultRead(char *string, void *aux)
     535             : {
     536             :     /* 1023 comes from char message[1024]; in GTIFFImport */
     537           0 :     const int num_read = fscanf((FILE *)aux, "%1023[^\n]\n", string);
     538           0 :     if (num_read == 0) {
     539           0 :       fprintf(stderr, "geo_print.c DefaultRead failed to read anything.\n");
     540             :     }
     541           0 :     return 1;
     542             : }

Generated by: LCOV version 1.14