📄 xccxct.c
字号:
/*****************************************************************************
* Copyright 2001, The Aerospace Corporation *
* All rights reserved *
* File: "xccxct.c" *
* Description: This file contains the functions that perform the reading of *
* multiple component collection, transformation matrix, and *
* component bitdepth files. *
* Author: James H. Kasner *
* Affiliation: The Aerospace Corporation *
* Version: VM8.5 *
* Last Revised: 6 February, 2001 *
*****************************************************************************/
#define ushort unsigned short
#define uchar unsigned char
#define ulong unsigned long
#define uint unsigned int
#define BUF_LEN 16384
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include "local_services.h"
#include "component_mix_local.h"
#include "xccxct.h"
/* The following type definitions and function prototypes */
/* apply only to this file. The public (non-static) functions */
/* and associated type definitions are in xccxct.h. */
typedef struct compdat{
ushort no_components; /* Number of components in collection */
ushort *indices; /* Pointer to array of component indices */
} CompData, *CompDataptr;
typedef struct collect *Groupptr;
typedef struct collect{
ushort no_collections; /* Number of component collections */
CompDataptr collections; /* Pointer to array of component structures */
Groupptr next; /* Pointer to the next collection set */
} Group;
typedef struct bddata *BitDepthptr;
typedef struct bddata{
CompDataptr bdcollect; /* Pointer to structure containing collection */
int bitdepth; /* Signed representation of component bitdepths */
BitDepthptr next; /* Pointer to the next bitdepth set */
} BitDepth;
typedef struct new_string{
ushort length; /* String length including NULL termination */
char *string; /* The character array */
} MyString, *MyStringptr;
/*------------------------- Function Prototypes -------------------------*/
static void convert_to_lower(char *in);
static char *fgets2(char *in,int n,FILE *fp);
static short parse_token(char *token,ushort *start);
static ushort get_collection(ushort **indices,char *collection);
static Group *parse_collection(char *collect);
static uint skip_comments(char *buffer,int buf_len,FILE *fp,char *filename);
/*-----------------------------------------------------------------------*/
/* ========================================================================= *
* --------------------------- Internal Functions -------------------------- *
* ========================================================================= */
/*****************************************************************************
* STATIC convert_to_lower *
*****************************************************************************/
/* Converts a string to lower case replacing the original */
static void convert_to_lower(char *in)
{
ushort i;
for(i=0;i<strlen(in);i++)
in[i]=(char)tolower(in[i]);
}
/*****************************************************************************
* STATIC fgets2 *
*****************************************************************************/
/* This function is a modification of the traditional fgets function. */
/* fgets2 trims out any CR/LF in a string returned by fgets. */
/* */
/* Note that fgets reads until it finds a "newline". For the UNIX platform */
/* this means an LF (0x0A), for the Mac it means a CR (0x0D). On the PC it */
/* looks for a CR/LF (0x0D/0x0A) pair in text mode. In binary mode it really */
/* triggers only on LF. This will tend to gobble up CRs as well. The CRs */
/* are not needed as they are in text mode. fgets2 behaves like gets, but for */
/* buffers other than stdin. */
static char *fgets2(char *in,int n,FILE *fp)
{
int i;
char *retval;
retval = fgets(in,n,fp);
if(retval != NULL){
for(i=(strlen(in)-1);i>=0;i--){
if(in[i] == '\r' || in[i] == '\n')
in[i] = '\0';
}
}
return(retval);
}
/*****************************************************************************
* STATIC strip_comment *
*****************************************************************************/
/* Strips C++ style comments off of an input line. The input line must be NULL */
/* terminated. Returns the new length of the line. The comment is stripped by */
/* replacing the first '/' with a '\0' null. This terminates the string. Any */
/* whitespace preceding the comment is then eliminated by this function. So if */
/* an input line is: */
/* */
/* 'Text and numbers 1.23 6.39 9.006 /* A comment' */
/* */
/* This line becomes: */
/* */
/* 'Text and numbers 1.23 6.39 9.006' */
uint strip_comment(char *in)
{
uint i,length;
int j;
length = strlen(in);
/* Find the '/*' comment indicator */
for(i=0;i<length;i++){
if(in[i] == '/' && in[i+1] == '/'){
in[i] = '\0';
break;
}
}
length = strlen(in);
for(j=length-1;j>=0;j--){
if(!isspace(in[j])){
in[j+1] = '\0';
break;
}
else if(j==0)
in[j] = '\0';
}
length = strlen(in);
return(length);
}
/*****************************************************************************
* STATIC parse_token *
*****************************************************************************/
/* Given a token, this function determines which bands were chosen by */
/* interpreting the token. Tokens are either numbers like 23 or ranges like */
/* 4-7. This function returns the number of bands in each range and returns */
/* this along with the first band number. If the start value is greater than */
/* the end value, a negative number of bands is returned. This indicates a */
/* decrement condition. */
static short parse_token(char *token,ushort *start)
{
ushort i,finish;
char temp[256];
i=strcspn(token,"-");
strncpy(temp,token,i);
temp[i]='\0';
sscanf(temp,"%hu",start);
if(i!=strlen(token)){
strcpy(temp,token+i+1);
sscanf(temp,"%hu",&finish);
}
else
finish=*start;
if (*start > finish)
return(finish-(*start)-1);
else
return(finish-(*start)+1);
}
/*****************************************************************************
* STATIC get_collection *
*****************************************************************************/
/* Fills in a component collection given a collection string. This function */
/* allocates storage for the collection indices and returns the number of */
/* components in the collection. */
static ushort get_collection(ushort **indices,char *collection)
{
ushort start,no_components;
ushort incdec,pos,length;
short i,number;
char temp_str[256],*retval;
char ct[]=",:;.",*temp_comps;
if (collection == NULL)
local_error("Empty component collection specification "
"(get_collection)");
/* The strtok routine is destructive, so copy the string */
length = strlen(collection)+1;
temp_comps = (char *)local_malloc(COMPONENT_COLLECTION_MEM_KEY,
length*sizeof(char));
strcpy(temp_comps,collection);
/* Determine the total number of components in this collection */
retval=strtok(temp_comps,ct);
if(retval!=NULL)
strcpy(temp_str,retval);
else if(retval==NULL)
local_error("Empty component collection specification "
"(get_collection)");
no_components = 0;
do{
number=parse_token(temp_str,&start);
if (number < 0)
no_components -= number;
else
no_components += number;
retval=strtok(NULL,ct);
if(retval!=NULL)
strcpy(temp_str,retval);
}while(retval!=NULL);
/* Allocate array for indices, re-copy the string */
*indices = (ushort *)local_malloc(COMPONENT_COLLECTION_MEM_KEY,
no_components*sizeof(ushort));
strcpy(temp_comps,collection);
/* Determine the actual component indices */
retval=strtok(temp_comps,ct);
if(retval!=NULL)
strcpy(temp_str,retval);
else if(retval==NULL)
local_error("Empty band subset specification (get_collection)");
pos = 0;
do{
number=parse_token(temp_str,&start);
if (number < 0){
number = -number;
incdec = -1;
}
else
incdec = 1;
for(i=0;i<number;i++){
(*indices)[pos] = start;
start += incdec;
pos++;
}
retval=strtok(NULL,ct);
if(retval!=NULL)
strcpy(temp_str,retval);
}while(retval!=NULL);
/* Release memory */
local_free((void *) temp_comps);
return (no_components);
}
/*****************************************************************************
* STATIC parse_collection *
*****************************************************************************/
/* Given a string containing one or more component collections, this function */
/* parses the collections. Multiple component collections within a string are */
/* delimited by '[]' brackets. If there is only one collection in a string */
/* the [] brackets are optional. */
/* */
/* This function returns a pointer to a Collection data structure which */
/* contains the number of component collections and pointers to other */
/* structures that hold the actual collection indices. */
static Group *parse_collection(char *collect)
{
ushort i,length,no_comp_collects;
char tokens[]="[]",*temp_collect,*retval;
Groupptr comp_collects;
MyStringptr collection_strings;
if(collect == NULL)
local_error("Empty component collection specification "
"(parse_collection)");
else{
/* The strtok function is destructive, so copy the string */
length = strlen(collect)+1;
temp_collect = (char *)local_malloc(COMPONENT_COLLECTION_MEM_KEY,
length*sizeof(char));
strcpy(temp_collect,collect);
/* Determine number of collections in the string */
retval = strtok(temp_collect,tokens);
no_comp_collects = 0;
if(retval!=NULL)
no_comp_collects++;
else if(retval==NULL)
local_error("Empty component collection specification"
" (parse_collection)");
do{
retval = strtok(NULL,tokens);
if(retval!=NULL)
no_comp_collects++;
}while(retval!=NULL);
/* Allocate array of structures to hold the component */
/* collection strings. Since you can't nest calls to strtok, */
/* we are going to first split the input string into its */
/* individual collections and then process them one at a */
/* time with strtok. */
collection_strings =
(MyString *)local_malloc(COMPONENT_COLLECTION_MEM_KEY,
no_comp_collects*sizeof(MyString));
/* Determine the length and store each collection substring */
strcpy(temp_collect,collect);
retval = strtok(temp_collect,tokens);
i=0;
if(retval!=NULL){
collection_strings[i].length = strlen(retval)+1;
collection_strings[i].string =
(char *)local_malloc(COMPONENT_COLLECTION_MEM_KEY,
collection_strings[i].length*sizeof(char));
strcpy(collection_strings[i].string,retval);
i++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -