LCOV - code coverage report
Current view: directory - frmts/gtiff/libgeotiff - geo_write.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 75 69 92.0 %
Date: 2011-12-18 Functions: 3 3 100.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             895 : 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             895 :     if (!(gt->gt_flags & FLAG_FILE_MODIFIED)) return 1;
      44                 : 
      45             895 :     if( gt->gt_tif == NULL )
      46               0 :         return 0;
      47                 :   
      48             895 :     tempData.tk_asciiParams = 0;
      49             895 :     tempData.tk_asciiParamsLength = 0;
      50             895 :     tempData.tk_asciiParamsOffset = 0;
      51                 : 
      52                 :     /*  Sort the Keys into numerical order */
      53             895 :     if (!SortKeys(gt,sortkeys))
      54                 :     {
      55                 :         /* XXX error: a key was not recognized */
      56                 :     }
      57                 :   
      58                 :     /* Set up header of ProjectionInfo tag */
      59             895 :     header = (KeyHeader *)gt->gt_short;
      60             895 :     header->hdr_num_keys = (pinfo_t) gt->gt_num_keys;
      61             895 :     header->hdr_version  = GvCurrentVersion;
      62             895 :     header->hdr_rev_major  = GvCurrentRevision;
      63             895 :     header->hdr_rev_minor  = GvCurrentMinorRev;
      64                 :   
      65                 :     /* Sum up the ASCII tag lengths */
      66            7570 :     for (i = 0; i < gt->gt_num_keys; i++)
      67                 :     {
      68            6675 :         keyptr = gt->gt_keys + sortkeys[i];
      69            6675 :         if (keyptr->gk_type == TYPE_ASCII)
      70                 :         {
      71            1134 :             tempData.tk_asciiParamsLength += keyptr->gk_count;
      72                 :         }
      73                 :     }
      74             895 :     if (tempData.tk_asciiParamsLength > 0)
      75                 :     {
      76             893 :         tempData.tk_asciiParams =
      77             893 :             (char *)_GTIFcalloc(tempData.tk_asciiParamsLength + 1);
      78             893 :         tempData.tk_asciiParams[tempData.tk_asciiParamsLength] = '\0';
      79                 :     }
      80                 : 
      81                 :     /* Set up the rest of SHORT array properly */
      82             895 :     keyptr = gt->gt_keys;
      83             895 :     entptr = (KeyEntry*)(gt->gt_short + 4);
      84            7570 :     for (i=0; i< gt->gt_num_keys; i++,entptr++)
      85                 :     {
      86            6675 :         if (!WriteKey(gt,&tempData,entptr,keyptr+sortkeys[i])) return 0;
      87                 :     } 
      88                 :   
      89                 :     /* Write out the Key Directory */
      90             895 :     (gt->gt_methods.set)(gt->gt_tif, GTIFF_GEOKEYDIRECTORY, gt->gt_nshorts, gt->gt_short ); 
      91                 :   
      92                 :     /* Write out the params directories */
      93             895 :     if (gt->gt_ndoubles)
      94             717 :         (gt->gt_methods.set)(gt->gt_tif, GTIFF_DOUBLEPARAMS, gt->gt_ndoubles, gt->gt_double );
      95             895 :     if (tempData.tk_asciiParamsLength > 0)
      96                 :     {
      97                 :         /* just to be safe */
      98             893 :         tempData.tk_asciiParams[tempData.tk_asciiParamsLength] = '\0';
      99            1786 :         (gt->gt_methods.set)(gt->gt_tif,
     100             893 :                              GTIFF_ASCIIPARAMS, 0, tempData.tk_asciiParams);
     101                 :     }
     102                 :   
     103             895 :     gt->gt_flags &= ~FLAG_FILE_MODIFIED;
     104                 : 
     105             895 :     if (tempData.tk_asciiParamsLength > 0)
     106                 :     {
     107             893 :         _GTIFFree (tempData.tk_asciiParams);
     108                 :     }
     109             895 :     return 1;
     110                 : }
     111                 : 
     112                 : /**********************************************************************
     113                 :  *
     114                 :  *                        Private Routines
     115                 :  *
     116                 :  **********************************************************************/
     117                 :  
     118                 : /*
     119                 :  * Given GeoKey, write out the KeyEntry entries, returning 0 if failure.
     120                 :  *  This is the exact complement of ReadKey().
     121                 :  */
     122                 : 
     123            6675 : static int WriteKey(GTIF* gt, TempKeyData* tempData,
     124                 :                     KeyEntry* entptr, GeoKey* keyptr)
     125                 : {
     126                 :     int count;
     127                 :   
     128            6675 :     entptr->ent_key = (pinfo_t) keyptr->gk_key;
     129            6675 :     entptr->ent_count = (pinfo_t) keyptr->gk_count;
     130            6675 :     count = entptr->ent_count;
     131                 :   
     132            6675 :     if (count==1 && keyptr->gk_type==TYPE_SHORT)
     133                 :     {
     134            3962 :         entptr->ent_location = GTIFF_LOCAL;
     135            3962 :         entptr->ent_val_offset = *(pinfo_t*)&keyptr->gk_data;
     136            3962 :         return 1;
     137                 :     }
     138                 :       
     139            2713 :     switch (keyptr->gk_type)
     140                 :     {
     141                 :       case TYPE_SHORT:
     142               0 :         entptr->ent_location = GTIFF_GEOKEYDIRECTORY;
     143               0 :         entptr->ent_val_offset = (pinfo_t)
     144               0 :             ((pinfo_t*)keyptr->gk_data - gt->gt_short);
     145               0 :         break;
     146                 :       case TYPE_DOUBLE:
     147            1579 :         entptr->ent_location = GTIFF_DOUBLEPARAMS;
     148            1579 :         entptr->ent_val_offset = (pinfo_t) 
     149            1579 :             ((double*)keyptr->gk_data - gt->gt_double);
     150            1579 :         break;
     151                 :       case TYPE_ASCII:
     152            1134 :         entptr->ent_location = GTIFF_ASCIIPARAMS;
     153            1134 :         entptr->ent_val_offset = (pinfo_t) tempData->tk_asciiParamsOffset;
     154            3402 :         _GTIFmemcpy (tempData->tk_asciiParams + tempData->tk_asciiParamsOffset
     155            2268 :                      , keyptr->gk_data, keyptr->gk_count);
     156            1134 :         tempData->tk_asciiParams[tempData->tk_asciiParamsOffset+keyptr->gk_count-1] = '|';
     157            1134 :         tempData->tk_asciiParamsOffset += keyptr->gk_count;
     158            1134 :         break;
     159                 :       default:
     160               0 :         return 0; /* failure */
     161                 :     }
     162                 :   
     163            2713 :     return 1; /* success */
     164                 : }
     165                 : 
     166                 : 
     167                 : /* 
     168                 :  * Numerically sort the GeoKeys.
     169                 :  * We just do a linear search through
     170                 :  * the list and pull out the keys that were set.
     171                 :  */
     172                 : 
     173             895 : static int SortKeys(GTIF* gt,int *sortkeys)
     174                 : {
     175                 :     int i, did_work;
     176                 : 
     177            7570 :     for( i = 0; i < gt->gt_num_keys; i++ )
     178            6675 :         sortkeys[i] = i+1;
     179                 : 
     180                 :     do {  /* simple bubble sort */
     181            3171 :         did_work = 0;
     182           26904 :         for( i = 0; i < gt->gt_num_keys-1; i++ )
     183                 :         {
     184           47466 :             if( gt->gt_keys[sortkeys[i]].gk_key 
     185           23733 :                 > gt->gt_keys[sortkeys[i+1]].gk_key )
     186                 :             {
     187                 :                 /* swap keys in sort list */
     188            7998 :                 int j = sortkeys[i];
     189            7998 :                 sortkeys[i] = sortkeys[i+1];
     190            7998 :                 sortkeys[i+1] = j;
     191                 :                 
     192            7998 :                 did_work = 1;
     193                 :             }
     194                 :         }
     195            3171 :     } while( did_work );
     196                 : 
     197             895 :     return 1;
     198                 : }
     199                 : 

Generated by: LCOV version 1.7