📄 ply.c
字号:
/******************************************************************************
Read an element from an ascii file.
Entry:
plyfile - file identifier
elem_ptr - pointer to element
******************************************************************************/
void ascii_get_element(PlyFile *plyfile, char *elem_ptr)
{
int j,k;
PlyElement *elem;
PlyProperty *prop;
char **words;
int nwords;
int which_word;
char *elem_data,*item;
char *item_ptr;
int item_size;
int int_val;
unsigned int uint_val;
double double_val;
int list_count;
int store_it;
char **store_array;
char *orig_line;
char *other_data;
int other_flag;
/* the kind of element we're reading currently */
elem = plyfile->which_elem;
/* do we need to setup for other_props? */
if (elem->other_offset != NO_OTHER_PROPS) {
char **ptr;
other_flag = 1;
/* make room for other_props */
other_data = (char *) myalloc (elem->other_size);
/* store pointer in user's structure to the other_props */
ptr = (char **) (elem_ptr + elem->other_offset);
*ptr = other_data;
}
else
other_flag = 0;
/* read in the element */
words = get_words (plyfile->fp, &nwords, &orig_line);
if (words == NULL) {
fprintf (stderr, "ply_get_element: unexpected end of file\n");
exit (-1);
}
which_word = 0;
for (j = 0; j < elem->nprops; j++) {
prop = elem->props[j];
store_it = (elem->store_prop[j] | other_flag);
/* store either in the user's structure or in other_props */
if (elem->store_prop[j])
elem_data = elem_ptr;
else
elem_data = other_data;
if (prop->is_list == PLY_LIST) { /* a list */
/* get and store the number of items in the list */
get_ascii_item (words[which_word++], prop->count_external,
&int_val, &uint_val, &double_val);
if (store_it) {
item = elem_data + prop->count_offset;
store_item(item, prop->count_internal, int_val, uint_val, double_val);
}
/* allocate space for an array of items and store a ptr to the array */
list_count = int_val;
item_size = ply_type_size[prop->internal_type];
store_array = (char **) (elem_data + prop->offset);
if (list_count == 0) {
if (store_it)
*store_array = NULL;
}
else {
if (store_it) {
item_ptr = (char *) myalloc (sizeof (char) * item_size * list_count);
item = item_ptr;
*store_array = item_ptr;
}
/* read items and store them into the array */
for (k = 0; k < list_count; k++) {
get_ascii_item (words[which_word++], prop->external_type,
&int_val, &uint_val, &double_val);
if (store_it) {
store_item (item, prop->internal_type,
int_val, uint_val, double_val);
item += item_size;
}
}
}
}
else if (prop->is_list == PLY_STRING) { /* a string */
if (store_it) {
char *str;
char **str_ptr;
str = strdup (words[which_word++]);
item = elem_data + prop->offset;
str_ptr = (char **) item;
*str_ptr = str;
}
else {
which_word++;
}
}
else { /* a scalar */
get_ascii_item (words[which_word++], prop->external_type,
&int_val, &uint_val, &double_val);
if (store_it) {
item = elem_data + prop->offset;
store_item (item, prop->internal_type, int_val, uint_val, double_val);
}
}
}
free (words);
}
/******************************************************************************
Read an element from a binary file.
Entry:
plyfile - file identifier
elem_ptr - pointer to an element
******************************************************************************/
void binary_get_element(PlyFile *plyfile, char *elem_ptr)
{
int j,k;
PlyElement *elem;
PlyProperty *prop;
FILE *fp = plyfile->fp;
char *elem_data;
char *item;
char *item_ptr;
int item_size;
int int_val;
unsigned int uint_val;
double double_val;
int list_count;
int store_it;
char **store_array;
char *other_data;
int other_flag;
/* the kind of element we're reading currently */
elem = plyfile->which_elem;
/* do we need to setup for other_props? */
if (elem->other_offset != NO_OTHER_PROPS) {
char **ptr;
other_flag = 1;
/* make room for other_props */
other_data = (char *) myalloc (elem->other_size);
/* store pointer in user's structure to the other_props */
ptr = (char **) (elem_ptr + elem->other_offset);
*ptr = other_data;
}
else
other_flag = 0;
/* read in a number of elements */
for (j = 0; j < elem->nprops; j++) {
prop = elem->props[j];
store_it = (elem->store_prop[j] | other_flag);
/* store either in the user's structure or in other_props */
if (elem->store_prop[j])
elem_data = elem_ptr;
else
elem_data = other_data;
if (prop->is_list == PLY_LIST) { /* list */
/* get and store the number of items in the list */
get_binary_item (fp, prop->count_external,
&int_val, &uint_val, &double_val);
if (store_it) {
item = elem_data + prop->count_offset;
store_item(item, prop->count_internal, int_val, uint_val, double_val);
}
/* allocate space for an array of items and store a ptr to the array */
list_count = int_val;
item_size = ply_type_size[prop->internal_type];
store_array = (char **) (elem_data + prop->offset);
if (list_count == 0) {
if (store_it)
*store_array = NULL;
}
else {
if (store_it) {
item_ptr = (char *) myalloc (sizeof (char) * item_size * list_count);
item = item_ptr;
*store_array = item_ptr;
}
/* read items and store them into the array */
for (k = 0; k < list_count; k++) {
get_binary_item (fp, prop->external_type,
&int_val, &uint_val, &double_val);
if (store_it) {
store_item (item, prop->internal_type,
int_val, uint_val, double_val);
item += item_size;
}
}
}
}
else if (prop->is_list == PLY_STRING) { /* string */
int len;
char *str;
fread (&len, sizeof(int), 1, fp);
str = (char *) myalloc (len);
fread (str, len, 1, fp);
if (store_it) {
char **str_ptr;
item = elem_data + prop->offset;
str_ptr = (char **) item;
*str_ptr = str;
}
}
else { /* scalar */
get_binary_item (fp, prop->external_type,
&int_val, &uint_val, &double_val);
if (store_it) {
item = elem_data + prop->offset;
store_item (item, prop->internal_type, int_val, uint_val, double_val);
}
}
}
}
/******************************************************************************
Write to a file the word that represents a PLY data type.
Entry:
fp - file pointer
code - code for type
******************************************************************************/
void write_scalar_type (FILE *fp, int code)
{
/* make sure this is a valid code */
if (code <= StartType || code >= EndType) {
fprintf (stderr, "write_scalar_type: bad data code = %d\n", code);
exit (-1);
}
/* write the code to a file */
fprintf (fp, "%s", type_names[code]);
}
/******************************************************************************
Get a text line from a file and break it up into words.
IMPORTANT: The calling routine should call "free" on the returned pointer once
finished with it.
Entry:
fp - file to read from
Exit:
nwords - number of words returned
orig_line - the original line of characters
returns a list of words from the line, or NULL if end-of-file
******************************************************************************/
char **get_words(FILE *fp, int *nwords, char **orig_line)
{
#define BIG_STRING 4096
static char str[BIG_STRING];
static char str_copy[BIG_STRING];
char **words;
int max_words = 10;
int num_words = 0;
char *ptr,*ptr2;
char *result;
words = (char **) myalloc (sizeof (char *) * max_words);
/* read in a line */
result = fgets (str, BIG_STRING, fp);
if (result == NULL) {
*nwords = 0;
*orig_line = NULL;
return (NULL);
}
/* convert line-feed and tabs into spaces */
/* (this guarentees that there will be a space before the */
/* null character at the end of the string) */
str[BIG_STRING-2] = ' ';
str[BIG_STRING-1] = '\0';
for (ptr = str, ptr2 = str_copy; *ptr != '\0'; ptr++, ptr2++) {
*ptr2 = *ptr;
if (*ptr == '\t') {
*ptr = ' ';
*ptr2 = ' ';
}
else if (*ptr == '\n') {
*ptr = ' ';
*ptr2 = '\0';
break;
}
}
/* find the words in the line */
ptr = str;
while (*ptr != '\0') {
/* jump over leading spaces */
while (*ptr == ' ')
ptr++;
/* break if we reach the end */
if (*ptr == '\0')
break;
/* allocate more room for words if necessary */
if (num_words >= max_words) {
max_words += 10;
words = (char **) realloc (words, sizeof (char *) * max_words);
}
if (*ptr == '\"') { /* a quote indidicates that we have a string */
/* skip over leading quote */
ptr++;
/* save pointer to beginning of word */
words[num_words++] = ptr;
/* find trailing quote or end of line */
while (*ptr != '\"' && *ptr != '\0')
ptr++;
/* replace quote with a null character to mark the end of the word */
/* if we are not already at the end of the line */
if (*ptr != '\0')
*ptr++ = '\0';
}
else { /* non-string */
/* save pointer to beginning of word */
words[num_words++] = ptr;
/* jump over non-spaces */
while (*ptr != ' ')
ptr++;
/* place a null character here to mark the end of the word */
*ptr++ = '\0';
}
}
/* return the list of words */
*nwords = num_words;
*orig_line = str_copy;
return (words);
}
/******************************************************************************
Return the value of an item, given a pointer to it and its type.
Entry:
item - pointer to item
type - data type that "item" points to
Exit:
returns a double-precision float that contains the value of the item
******************************************************************************/
double get_item_value(char *item, int type)
{
unsigned char *puchar;
char *pchar;
short int *pshort;
unsigned short int *pushort;
int *pint;
unsigned int *puint;
float *pfloat;
double *pdouble;
int int_value;
unsigned int uint_value;
double double_value;
switch (type) {
case Int8:
pchar = (char *) item;
int_value = *pchar;
return ((double) int_value);
case Uint8:
puchar = (unsigned char *) item;
int_value = *puchar;
return ((double) int_value);
case Int16:
pshort = (short int *) item;
int_value = *pshort;
return ((double) int_value);
case Uint16:
pushort = (unsigned short int *) item;
int_value = *pushort;
return ((double) int_value);
case Int32:
pint = (int *) item;
int_value = *pint;
return ((double) int_value);
case Uint32:
puint = (unsigned int *) item;
uint_value = *puint;
return ((double) uint_value);
case Float32:
pfloat = (float *) item;
double_value = *pfloat;
return (double_value);
case Float64:
pdouble = (double *) item;
double_value = *pdouble;
return (double_value);
default:
fprintf (stderr, "get_item_value: bad type = %d\n", type);
exit (-1);
}
return (0.0); /* never actually gets here */
}
/******************************************************************************
Write out an item to a file as raw binary bytes.
Entry:
fp - file to write to
int_val - integer version of item
uint_val - unsigned integer version of item
double_val - double-precision float version of item
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -