示例#1
0
文件: geo_tiffp.c 项目: drons/gdal
/* returns the value of TIFF tag <tag>, or if
 * the value is an array, returns an allocated buffer
 * containing the values. Allocate a copy of the actual
 * buffer, sized up for updating.
 */
static int _GTIFGetField (tiff_t *tif, pinfo_t tag, int *count, void *val )
{
    int status;
    unsigned short scount=0;
    char *tmp;
    char *value;
    gsize_t size = _gtiff_size[_GTIFTagType (tif,tag)];

    if (_GTIFTagType(tif,  tag) == TYPE_ASCII)
    {
        status = TIFFGetField((TIFF *)tif,tag,&tmp);
        if (!status) return status;
        scount = (unsigned short) (strlen(tmp)+1);
    }
    else status = TIFFGetField((TIFF *)tif,tag,&scount,&tmp);
    if (!status) return status;

    *count = scount;

    value = (char *)_GTIFcalloc( (scount+MAX_VALUES)*size);
    if (!value) return 0;

    _TIFFmemcpy( value, tmp,  size * scount);

    *(char **)val = value;
    return status;
}
示例#2
0
static int ReadTag(GTIF *gt,GTIFReadMethod scan,void *aux)
{
    int i,j,tag;
    char *vptr;
    char tagname[100];
    double *data,*dptr;
    int count,nrows,ncols,num;
    char message[1024];

    scan(message,aux);
    if (!strncmp(message,FMT_TAGEND,8)) return 0;

    num=sscanf(message,"%[^( ] (%d,%d):\n",tagname,&nrows,&ncols);
    if (num!=3) return StringError(message);

    tag = GTIFTagCode(tagname);
    if (tag < 0) return StringError(tagname);

    count = nrows*ncols;

    data = (double *) _GTIFcalloc(count * sizeof(double));
    dptr = data;

    for (i=0; i<nrows; i++)
    {
        scan(message,aux);
        vptr = message;
        for (j=0; j<ncols; j++)
        {
            if (!sscanf(vptr,"%lg",dptr++))
                return StringError(vptr);
            FINDCHAR(vptr,' ');
            SKIPWHITE(vptr);
        }
    }
    (gt->gt_methods.set)(gt->gt_tif, (pinfo_t) tag, count, data );

    _GTIFFree( data );

    return 1;
}
示例#3
0
/* returns the value of TIFF tag <tag>, or if
 * the value is an array, returns an allocated buffer
 * containing the values. Allocate a copy of the actual
 * buffer, sized up for updating.
 */
static int _GTIFGetField (tiff_t *tif, pinfo_t tag, int *count, void *val )
{
    int item_size, data_type;
    void *internal_value, *ret_value;

    if( !ST_GetKey( (ST_TIFF*) tif, (int) tag, count, &data_type, 
                    &internal_value ) )
        return 0;

    if( data_type != ST_TagType( tag ) )
        return 0;

    item_size = ST_TypeSize( data_type );

    ret_value = (char *)_GTIFcalloc( *count * item_size );
    if (!ret_value) return 0;

    _TIFFmemcpy( ret_value, internal_value,  item_size * *count );
	
    *(void **)val = ret_value;
    return 1;
}
示例#4
0
int GTIFWriteKeys(GTIF *gt)
{
    int i;
    GeoKey *keyptr;
    KeyEntry *entptr;
    KeyHeader *header;
    TempKeyData tempData;
    int sortkeys[MAX_KEYS];
	
    if (!(gt->gt_flags & FLAG_FILE_MODIFIED)) return 1;

    if( gt->gt_tif == NULL )
        return 0;
	
    tempData.tk_asciiParams = 0;
    tempData.tk_asciiParamsLength = 0;
    tempData.tk_asciiParamsOffset = 0;

    /*  Sort the Keys into numerical order */
    if (!SortKeys(gt,sortkeys))
    {
        /* XXX error: a key was not recognized */
    }
	
    /* Set up header of ProjectionInfo tag */
    header = (KeyHeader *)gt->gt_short;
    header->hdr_num_keys = (pinfo_t) gt->gt_num_keys;
    header->hdr_version  = GvCurrentVersion;
    header->hdr_rev_major  = GvCurrentRevision;
    header->hdr_rev_minor  = GvCurrentMinorRev;
	
    /* Sum up the ASCII tag lengths */
    for (i = 0; i < gt->gt_num_keys; i++)
    {
        keyptr = gt->gt_keys + sortkeys[i];
        if (keyptr->gk_type == TYPE_ASCII)
        {
            tempData.tk_asciiParamsLength += keyptr->gk_count;
        }
    }
    if (tempData.tk_asciiParamsLength > 0)
    {
        tempData.tk_asciiParams =
            (char *)_GTIFcalloc(tempData.tk_asciiParamsLength + 1);
        tempData.tk_asciiParams[tempData.tk_asciiParamsLength] = '\0';
    }

    /* Set up the rest of SHORT array properly */
    keyptr = gt->gt_keys;
    entptr = (KeyEntry*)(gt->gt_short + 4);
    for (i=0; i< gt->gt_num_keys; i++,entptr++)
    {
        if (!WriteKey(gt,&tempData,entptr,keyptr+sortkeys[i])) return 0;
    }	
	
    /* Write out the Key Directory */
    (gt->gt_methods.set)(gt->gt_tif, GTIFF_GEOKEYDIRECTORY, gt->gt_nshorts, gt->gt_short );	
	
    /* Write out the params directories */
    if (gt->gt_ndoubles)
        (gt->gt_methods.set)(gt->gt_tif, GTIFF_DOUBLEPARAMS, gt->gt_ndoubles, gt->gt_double );
    if (tempData.tk_asciiParamsLength > 0)
    {
        /* just to be safe */
        tempData.tk_asciiParams[tempData.tk_asciiParamsLength] = '\0';
        (gt->gt_methods.set)(gt->gt_tif,
                             GTIFF_ASCIIPARAMS, 0, tempData.tk_asciiParams);
    }
	
    gt->gt_flags &= ~FLAG_FILE_MODIFIED;

    if (tempData.tk_asciiParamsLength > 0)
    {
        _GTIFFree (tempData.tk_asciiParams);
    }
    return 1;
}
示例#5
0
GTIF* GTIFNewWithMethods(void *tif, TIFFMethod* methods)
{
    GTIF* gt=(GTIF*)0;
    int count,bufcount,index;
    GeoKey *keyptr;
    pinfo_t *data;
    KeyEntry *entptr;
    KeyHeader *header;
    TempKeyData tempData;

    memset( &tempData, 0, sizeof(tempData) );
    gt = (GTIF*)_GTIFcalloc( sizeof(GTIF));
    if (!gt) goto failure;	
	
    /* install TIFF file and I/O methods */
    gt->gt_tif = (tiff_t *)tif;
    memcpy( &gt->gt_methods, methods, sizeof(TIFFMethod) );

    /* since this is an array, GTIF will allocate the memory */
    if ( tif == NULL 
         || !(gt->gt_methods.get)(tif, GTIFF_GEOKEYDIRECTORY, &gt->gt_nshorts, &data ))
    {
        /* No ProjectionInfo, create a blank one */
        data=(pinfo_t*)_GTIFcalloc((4+MAX_VALUES)*sizeof(pinfo_t));
        if (!data) goto failure;	
        header = (KeyHeader *)data;
        header->hdr_version = GvCurrentVersion;
        header->hdr_rev_major = GvCurrentRevision;
        header->hdr_rev_minor = GvCurrentMinorRev;
        gt->gt_nshorts=sizeof(KeyHeader)/sizeof(pinfo_t);
    }
    else
    {
        /* resize data array so it can be extended if needed */
        data = (pinfo_t*) _GTIFrealloc(data,(4+MAX_VALUES)*sizeof(pinfo_t));
    }
    gt->gt_short = data;
    header = (KeyHeader *)data;
	
    if (header->hdr_version > GvCurrentVersion) goto failure;
    if (header->hdr_rev_major > GvCurrentRevision)
    {
        /* issue warning */
    }
	
    /* If we got here, then the geokey can be parsed */
    count = header->hdr_num_keys;

    if (count * sizeof(KeyEntry) >= (4 + MAX_VALUES) * sizeof(pinfo_t)) 
        goto failure; 

    gt->gt_num_keys = count;
    gt->gt_version  = header->hdr_version;
    gt->gt_rev_major  = header->hdr_rev_major;
    gt->gt_rev_minor  = header->hdr_rev_minor;

    bufcount = count+MAX_KEYS; /* allow for expansion */

    /* Get the PARAMS Tags, if any */
    if (tif == NULL
        || !(gt->gt_methods.get)(tif, GTIFF_DOUBLEPARAMS,
                                 &gt->gt_ndoubles, &gt->gt_double ))
    {
        gt->gt_double=(double*)_GTIFcalloc(MAX_VALUES*sizeof(double));
        if (!gt->gt_double) goto failure;	
    }
    else
    {
        /* resize data array so it can be extended if needed */
        gt->gt_double = (double*) _GTIFrealloc(gt->gt_double,
                                               (MAX_VALUES)*sizeof(double));
    }
    if ( tif == NULL
         || !(gt->gt_methods.get)(tif, GTIFF_ASCIIPARAMS,
                                  &tempData.tk_asciiParamsLength,
                                  &tempData.tk_asciiParams ))
    {
        tempData.tk_asciiParams         = 0;
        tempData.tk_asciiParamsLength   = 0;
    }
    else
    {
        /* last NULL doesn't count; "|" used for delimiter */
        --tempData.tk_asciiParamsLength;
    }

    /* allocate space for GeoKey array and its index */
    gt->gt_keys = (GeoKey *)_GTIFcalloc( sizeof(GeoKey)*bufcount);
    if (!gt->gt_keys) goto failure;
    gt->gt_keyindex = (int *)_GTIFcalloc( sizeof(int)*(MAX_KEYINDEX+1));
    if (!gt->gt_keyindex) goto failure;
	
    /*  Loop to get all GeoKeys */
    entptr = ((KeyEntry *)data) + 1;
    keyptr = gt->gt_keys;
    gt->gt_keymin = MAX_KEYINDEX;
    gt->gt_keymax = 0;
    for (index=1; index<=count; index++,entptr++)
    {
        if (!ReadKey(gt, &tempData, entptr, ++keyptr))
            goto failure;
			
        /* Set up the index (start at 1, since 0=unset) */
        gt->gt_keyindex[entptr->ent_key] = index;		
    }

    if( tempData.tk_asciiParams != NULL )
        _GTIFFree( tempData.tk_asciiParams );
	
    return gt;
	
  failure:
    /* Notify of error */
    if( tempData.tk_asciiParams != NULL )
        _GTIFFree( tempData.tk_asciiParams );    
    GTIFFree (gt);
    return (GTIF *)0;
}
示例#6
0
static int ReadKey(GTIF* gt, TempKeyData* tempData,
                   KeyEntry* entptr, GeoKey* keyptr)
{
    int offset,count;
	
    keyptr->gk_key = entptr->ent_key;
    keyptr->gk_count = entptr->ent_count;
    count = entptr->ent_count;
    offset = entptr->ent_val_offset;
    if (gt->gt_keymin > keyptr->gk_key)  gt->gt_keymin=keyptr->gk_key;
    if (gt->gt_keymax < keyptr->gk_key)  gt->gt_keymax=keyptr->gk_key;
	
    if (entptr->ent_location)
        keyptr->gk_type = (gt->gt_methods.type)(gt->gt_tif,entptr->ent_location);
    else
        keyptr->gk_type = (gt->gt_methods.type)(gt->gt_tif,GTIFF_GEOKEYDIRECTORY);
	  
    switch (entptr->ent_location)
    {
        case GTIFF_LOCAL:
            /* store value into data value */
            *(pinfo_t *)(&keyptr->gk_data) = entptr->ent_val_offset;
            break;
        case GTIFF_GEOKEYDIRECTORY:
            keyptr->gk_data = (char *)(gt->gt_short+offset);
            if (gt->gt_nshorts < offset+count)
                gt->gt_nshorts = offset+count;
            break;
        case GTIFF_DOUBLEPARAMS:
            keyptr->gk_data = (char *)(gt->gt_double+offset);
            if (gt->gt_ndoubles < offset+count)
                gt->gt_ndoubles = offset+count;
            break;
        case GTIFF_ASCIIPARAMS:
            if( offset + count == tempData->tk_asciiParamsLength + 1 
                && count > 0 )
            {
                /* some vendors seem to feel they should not use the 
                   terminating '|' char, but do include a terminating '\0'
                   which we lose in the low level reading code.  
                   If this is the case, drop the extra character */
                count--;
            }
            else if (offset < tempData->tk_asciiParamsLength
                     && offset + count > tempData->tk_asciiParamsLength )
            {
                count = tempData->tk_asciiParamsLength - offset;
                /* issue warning... if we could */
            }
            else if (offset + count > tempData->tk_asciiParamsLength)
                return (0);

            keyptr->gk_count = MAX(1,count+1);
            keyptr->gk_data = (char *) _GTIFcalloc (keyptr->gk_count);

            _GTIFmemcpy (keyptr->gk_data,
                         tempData->tk_asciiParams + offset, count);
            if( keyptr->gk_data[MAX(0,count-1)] == '|' )
            {
                keyptr->gk_data[MAX(0,count-1)] = '\0';
                keyptr->gk_count = count;
            }
            else
                keyptr->gk_data[MAX(0,count)] = '\0';
            break;
        default:
            return 0; /* failure */
    }
    keyptr->gk_size = _gtiff_size[keyptr->gk_type];
	
    return 1; /* success */
}
示例#7
0
static int ReadKey(GTIF *gt, GTIFReadMethod scan, void *aux)
{
    tagtype_t ktype;
    int count,outcount;
    int vals_now,i;
    geokey_t key;
    int icode;
    pinfo_t code;
    short  *sptr;
    char name[1000];
    char type[20];
    double data[100];
    double *dptr;
    char *vptr;
    int num;
    char message[2048];

    scan(message,aux);
    if (!strncmp(message,FMT_KEYEND,8)) return 0;

    num=sscanf(message,"%[^( ] (%[^,],%d):\n",name,type,&count);
    if (num!=3) return StringError(message);

    vptr = message;
    FINDCHAR(vptr,':');
    if (!*vptr) return StringError(message);
    vptr+=2;

    if( GTIFKeyCode(name) < 0 )
        return StringError(name);
    else
        key = (geokey_t) GTIFKeyCode(name);

    if( GTIFTypeCode(type) < 0 )
        return StringError(type);
    else
        ktype = (tagtype_t) GTIFTypeCode(type);

    /* skip white space */
    SKIPWHITE(vptr);
    if (!*vptr) return StringError(message);

    switch (ktype)
    {
    case TYPE_ASCII:
    {
        char *cdata;
        int out_char = 0;

        FINDCHAR(vptr,'"');
        if (!*vptr) return StringError(message);

        cdata = (char *) _GTIFcalloc( count+1 );

        vptr++;
        while( out_char < count-1 )
        {
            if( *vptr == '\0' )
                break;

            else if( vptr[0] == '\\' && vptr[1] == 'n' )
            {
                cdata[out_char++] = '\n';
                vptr += 2;
            }
            else if( vptr[0] == '\\' && vptr[1] == '\\' )
            {
                cdata[out_char++] = '\\';
                vptr += 2;
            }
            else
                cdata[out_char++] = *(vptr++);
        }

        if( out_char < count-1 ) return StringError(message);
        if( *vptr != '"' ) return StringError(message);

        cdata[count-1] = '\0';
        GTIFKeySet(gt,key,ktype,count,cdata);

        _GTIFFree( cdata );
    }
    break;

    case TYPE_DOUBLE:
        outcount = count;
        for (dptr = data; count > 0; count-= vals_now)
        {
            vals_now = count > 3? 3: count;
            for (i=0; i<vals_now; i++,dptr++)
            {
                if (!sscanf(vptr,"%lg" ,dptr))
                    StringError(vptr);
                FINDCHAR(vptr,' ');
                SKIPWHITE(vptr);
            }
            if (vals_now<count)
            {
                scan(message,aux);
                vptr = message;
            }
        }
        if (outcount==1)
            GTIFKeySet(gt,key,ktype,outcount,data[0]);
        else
            GTIFKeySet(gt,key,ktype,outcount,data);
        break;

    case TYPE_SHORT:
        if (count==1)
        {
            icode = GTIFValueCode(key,vptr);
            if (icode < 0) return StringError(vptr);
            code = (pinfo_t) icode;
            GTIFKeySet(gt,key,ktype,count,code);
        }
        else  /* multi-valued short - no such thing yet */
        {
            char* cdata;
            memcpy(&cdata, &data, sizeof(void*));
            sptr = (short *)cdata;
            outcount = count;
            for (; count > 0; count-= vals_now)
            {
                vals_now = count > 3? 3: count;
                for (i=0; i<vals_now; i++,sptr++)
                {
                    int		work_int;

                    /* note: FMT_SHORT (%11hd) not supported on IRIX */
                    sscanf(message,"%11d",&work_int);
                    *sptr = (short) work_int;
                    scan(message,aux);
                }
                if (vals_now<count)
                {
                    scan(message,aux);
                    vptr = message;
                }
            }
            GTIFKeySet(gt,key,ktype,outcount,sptr);
        }
        break;

    default:
        return -1;
    }
    return 1;
}