int GTIFKeyGet(GTIF *gtif, geokey_t thekey, void *val, int index, int count) { int kindex = gtif->gt_keyindex[ thekey ]; GeoKey *key; gsize_t size; char *data; tagtype_t type; if (!kindex) return 0; key = gtif->gt_keys+kindex; if (!count) count = key->gk_count - index; if (count <=0) return 0; if (count > key->gk_count) count = key->gk_count; size = key->gk_size; type = key->gk_type; if (count==1 && type==TYPE_SHORT) data = (char *)&key->gk_data; else data = key->gk_data; _GTIFmemcpy( val, data + index*size, count*size ); if (type==TYPE_ASCII) ((char *)val)[count-1] = '\0'; /* replace last char with NULL */ return count; }
static int WriteKey(GTIF* gt, TempKeyData* tempData, KeyEntry* entptr, GeoKey* keyptr) { int count; entptr->ent_key = (pinfo_t) keyptr->gk_key; entptr->ent_count = (pinfo_t) keyptr->gk_count; count = entptr->ent_count; if (count==1 && keyptr->gk_type==TYPE_SHORT) { entptr->ent_location = GTIFF_LOCAL; memcpy(&(entptr->ent_val_offset), &keyptr->gk_data, sizeof(pinfo_t)); return 1; } switch (keyptr->gk_type) { case TYPE_SHORT: entptr->ent_location = GTIFF_GEOKEYDIRECTORY; entptr->ent_val_offset = (pinfo_t) ((pinfo_t*)keyptr->gk_data - gt->gt_short); break; case TYPE_DOUBLE: entptr->ent_location = GTIFF_DOUBLEPARAMS; entptr->ent_val_offset = (pinfo_t) ((double*)keyptr->gk_data - gt->gt_double); break; case TYPE_ASCII: if( tempData->tk_asciiParams == NULL ) return 0; entptr->ent_location = GTIFF_ASCIIPARAMS; entptr->ent_val_offset = (pinfo_t) tempData->tk_asciiParamsOffset; _GTIFmemcpy (tempData->tk_asciiParams + tempData->tk_asciiParamsOffset , keyptr->gk_data, keyptr->gk_count); tempData->tk_asciiParams[tempData->tk_asciiParamsOffset+keyptr->gk_count-1] = '|'; tempData->tk_asciiParamsOffset += keyptr->gk_count; break; default: return 0; /* failure */ } return 1; /* success */ }
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 */ }