"Fossies" - the Fresh Open Source Software Archive

Member "libgeotiff-1.6.0/geo_print.c" (15 Jun 2019, 14066 Bytes) of package /linux/privat/libgeotiff-1.6.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "geo_print.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.5.1_vs_1.6.0.

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