"Fossies" - the Fresh Open Source Software Archive

Member "libgeotiff-1.6.0/geo_write.c" (15 Jun 2019, 6228 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_write.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_write.c  -- Public routines for GEOTIFF GeoKey access.
    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 source code derived therefrom.
   11  *
   12  **********************************************************************/
   13 
   14 #include "geotiffio.h"   /* public interface        */
   15 #include "geo_tiffp.h" /* external TIFF interface */
   16 #include "geo_keyp.h"  /* private interface       */
   17 
   18 static int WriteKey(GTIF* gt, TempKeyData* tempData,
   19                     KeyEntry* entptr, GeoKey* keyptr);
   20 static int SortKeys(GTIF* gt,int *sortkeys);
   21 
   22 
   23 /**
   24 This function flushes all the GeoTIFF keys that have been set with the
   25 GTIFKeySet() function into the associated
   26 TIFF file.
   27 
   28 @param gt The GeoTIFF handle returned by GTIFNew.
   29 
   30 GTIFWriteKeys() should be called before
   31 GTIFFree() is used to deallocate a GeoTIFF access handle.
   32  */
   33 
   34 int GTIFWriteKeys(GTIF *gt)
   35 {
   36     int i;
   37     GeoKey *keyptr;
   38     KeyEntry *entptr;
   39     KeyHeader *header;
   40     TempKeyData tempData;
   41     int sortkeys[MAX_KEYS];
   42 
   43     if (!(gt->gt_flags & FLAG_FILE_MODIFIED)) return 1;
   44 
   45     if( gt->gt_tif == NULL )
   46         return 0;
   47 
   48     tempData.tk_asciiParams = 0;
   49     tempData.tk_asciiParamsLength = 0;
   50     tempData.tk_asciiParamsOffset = 0;
   51 
   52     /*  Sort the Keys into numerical order */
   53     if (!SortKeys(gt,sortkeys))
   54     {
   55         /* XXX error: a key was not recognized */
   56     }
   57 
   58     /* Set up header of ProjectionInfo tag */
   59     header = (KeyHeader *)gt->gt_short;
   60     header->hdr_num_keys = (pinfo_t) gt->gt_num_keys;
   61     header->hdr_version  = gt->gt_version;
   62     header->hdr_rev_major  = gt->gt_rev_major;
   63     header->hdr_rev_minor  = gt->gt_rev_minor;
   64 
   65     /* Sum up the ASCII tag lengths */
   66     for (i = 0; i < gt->gt_num_keys; i++)
   67     {
   68         keyptr = gt->gt_keys + sortkeys[i];
   69         if (keyptr->gk_type == TYPE_ASCII)
   70         {
   71             tempData.tk_asciiParamsLength += keyptr->gk_count;
   72         }
   73     }
   74     if (tempData.tk_asciiParamsLength > 0)
   75     {
   76         tempData.tk_asciiParams =
   77             (char *)_GTIFcalloc(tempData.tk_asciiParamsLength + 1);
   78         if( tempData.tk_asciiParams == NULL )
   79             return 0;
   80         tempData.tk_asciiParams[tempData.tk_asciiParamsLength] = '\0';
   81     }
   82 
   83     /* Set up the rest of SHORT array properly */
   84     keyptr = gt->gt_keys;
   85     entptr = (KeyEntry*)(gt->gt_short + 4);
   86     for (i=0; i< gt->gt_num_keys; i++,entptr++)
   87     {
   88         if (!WriteKey(gt,&tempData,entptr,keyptr+sortkeys[i]))
   89         {
   90             if (tempData.tk_asciiParamsLength > 0)
   91             {
   92                 _GTIFFree (tempData.tk_asciiParams);
   93             }
   94             return 0;
   95         }
   96     }
   97 
   98     /* Write out the Key Directory */
   99     (gt->gt_methods.set)(gt->gt_tif, GTIFF_GEOKEYDIRECTORY, gt->gt_nshorts, gt->gt_short );
  100 
  101     /* Write out the params directories */
  102     if (gt->gt_ndoubles)
  103         (gt->gt_methods.set)(gt->gt_tif, GTIFF_DOUBLEPARAMS, gt->gt_ndoubles, gt->gt_double );
  104     if (tempData.tk_asciiParamsLength > 0)
  105     {
  106         /* just to be safe */
  107         tempData.tk_asciiParams[tempData.tk_asciiParamsLength] = '\0';
  108         (gt->gt_methods.set)(gt->gt_tif,
  109                              GTIFF_ASCIIPARAMS, 0, tempData.tk_asciiParams);
  110     }
  111 
  112     gt->gt_flags &= ~FLAG_FILE_MODIFIED;
  113 
  114     if (tempData.tk_asciiParamsLength > 0)
  115     {
  116         _GTIFFree (tempData.tk_asciiParams);
  117     }
  118     return 1;
  119 }
  120 
  121 /**********************************************************************
  122  *
  123  *                        Private Routines
  124  *
  125  **********************************************************************/
  126 
  127 /*
  128  * Given GeoKey, write out the KeyEntry entries, returning 0 if failure.
  129  *  This is the exact complement of ReadKey().
  130  */
  131 
  132 static int WriteKey(GTIF* gt, TempKeyData* tempData,
  133                     KeyEntry* entptr, GeoKey* keyptr)
  134 {
  135     int count;
  136 
  137     entptr->ent_key = (pinfo_t) keyptr->gk_key;
  138     entptr->ent_count = (pinfo_t) keyptr->gk_count;
  139     count = entptr->ent_count;
  140 
  141     if (count==1 && keyptr->gk_type==TYPE_SHORT)
  142     {
  143         entptr->ent_location = GTIFF_LOCAL;
  144         memcpy(&(entptr->ent_val_offset), &keyptr->gk_data, sizeof(pinfo_t));
  145         return 1;
  146     }
  147 
  148     switch (keyptr->gk_type)
  149     {
  150       case TYPE_SHORT:
  151         entptr->ent_location = GTIFF_GEOKEYDIRECTORY;
  152         entptr->ent_val_offset = (pinfo_t)
  153             ((pinfo_t*)keyptr->gk_data - gt->gt_short);
  154         break;
  155       case TYPE_DOUBLE:
  156         entptr->ent_location = GTIFF_DOUBLEPARAMS;
  157         entptr->ent_val_offset = (pinfo_t)
  158             ((double*)keyptr->gk_data - gt->gt_double);
  159         break;
  160       case TYPE_ASCII:
  161         if( tempData->tk_asciiParams == NULL )
  162             return 0;
  163         entptr->ent_location = GTIFF_ASCIIPARAMS;
  164         entptr->ent_val_offset = (pinfo_t) tempData->tk_asciiParamsOffset;
  165         _GTIFmemcpy (tempData->tk_asciiParams + tempData->tk_asciiParamsOffset
  166                      , keyptr->gk_data, keyptr->gk_count);
  167         tempData->tk_asciiParams[tempData->tk_asciiParamsOffset+keyptr->gk_count-1] = '|';
  168         tempData->tk_asciiParamsOffset += keyptr->gk_count;
  169         break;
  170       default:
  171         return 0; /* failure */
  172     }
  173 
  174     return 1; /* success */
  175 }
  176 
  177 
  178 /*
  179  * Numerically sort the GeoKeys.
  180  * We just do a linear search through
  181  * the list and pull out the keys that were set.
  182  */
  183 
  184 static int SortKeys(GTIF* gt,int *sortkeys)
  185 {
  186     int i, did_work;
  187 
  188     /* A bit convoluted to make Clang Static Analyzer happy */
  189     if( gt->gt_num_keys <= 0 )
  190         return 1;
  191 
  192     sortkeys[0] = 1;
  193     for( i = 1; i < gt->gt_num_keys; i++ )
  194         sortkeys[i] = i+1;
  195 
  196     do {  /* simple bubble sort */
  197         did_work = 0;
  198         for( i = 0; i < gt->gt_num_keys-1; i++ )
  199         {
  200             if( gt->gt_keys[sortkeys[i]].gk_key
  201                 > gt->gt_keys[sortkeys[i+1]].gk_key )
  202             {
  203                 /* swap keys in sort list */
  204                 int j = sortkeys[i];
  205                 sortkeys[i] = sortkeys[i+1];
  206                 sortkeys[i+1] = j;
  207 
  208                 did_work = 1;
  209             }
  210         }
  211     } while( did_work );
  212 
  213     return 1;
  214 }