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

Generated by: LCOV version 1.14