/* ----------------------------------------------------------------------
* RPly library, read/write PLY files
* Diego Nehab, Princeton University
* http://www.cs.princeton.edu/~diego/professional/rply
*
* This library is distributed under the MIT License. See notice
* at the end of this file.
* ---------------------------------------------------------------------- */
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>
#include <limits.h>
#include <float.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stddef.h>
#include "rply.h"
/* ----------------------------------------------------------------------
* Constants
* ---------------------------------------------------------------------- */
#define WORDSIZE 256
#define LINESIZE 1024
#define BUFFERSIZE (8*1024)
typedef enum e_ply_io_mode_ {
PLY_READ,
PLY_WRITE
} e_ply_io_mode;
static const char *const ply_storage_mode_list[] = {
"binary_big_endian", "binary_little_endian", "ascii", NULL
}; /* order matches e_ply_storage_mode enum */
static const char *const ply_type_list[] = {
"int8", "uint8", "int16", "uint16",
"int32", "uint32", "float32", "float64",
"char", "uchar", "short", "ushort",
"int", "uint", "float", "double",
"list", NULL
}; /* order matches e_ply_type enum */
/* ----------------------------------------------------------------------
* Property reading callback argument
*
* element: name of element being processed
* property: name of property being processed
* nelements: number of elements of this kind in file
* instance_index: index current element of this kind being processed
* length: number of values in current list (or 1 for scalars)
* value_index: index of current value int this list (or 0 for scalars)
* value: value of property
* pdata/idata: user data defined with ply_set_cb
*
* Returns handle to ply file if succesful, NULL otherwise.
* ---------------------------------------------------------------------- */
typedef struct t_ply_argument_ {
p_ply_element element;
long instance_index;
p_ply_property property;
long length, value_index;
double value;
void *pdata;
long idata;
} t_ply_argument;
/* ----------------------------------------------------------------------
* Property information
*
* name: name of this property
* type: type of this property (list or type of scalar value)
* length_type, value_type: type of list property count and values
* read_cb: function to be called when this property is called
*
* Returns 1 if should continue processing file, 0 if should abort.
* ---------------------------------------------------------------------- */
typedef struct t_ply_property_ {
char name[WORDSIZE];
e_ply_type type, value_type, length_type;
p_ply_read_cb read_cb;
void *pdata;
long idata;
} t_ply_property;
/* ----------------------------------------------------------------------
* Element information
*
* name: name of this property
* ninstances: number of elements of this type in file
* property: property descriptions for this element
* nproperty: number of properties in this element
*
* Returns 1 if should continue processing file, 0 if should abort.
* ---------------------------------------------------------------------- */
typedef struct t_ply_element_ {
char name[WORDSIZE];
long ninstances;
p_ply_property property;
long nproperties;
} t_ply_element;
/* ----------------------------------------------------------------------
* Input/output driver
*
* Depending on file mode, different functions are used to read/write
* property fields. The drivers make it transparent to read/write in ascii,
* big endian or little endian cases.
* ---------------------------------------------------------------------- */
typedef int (*p_ply_ihandler)(p_ply ply, double *value);
typedef int (*p_ply_ichunk)(p_ply ply, void *anydata, size_t size);
typedef struct t_ply_idriver_ {
p_ply_ihandler ihandler[16];
p_ply_ichunk ichunk;
const char *name;
} t_ply_idriver;
typedef t_ply_idriver *p_ply_idriver;
typedef int (*p_ply_ohandler)(p_ply ply, double value);
typedef int (*p_ply_ochunk)(p_ply ply, void *anydata, size_t size);
typedef struct t_ply_odriver_ {
p_ply_ohandler ohandler[16];
p_ply_ochunk ochunk;
const char *name;
} t_ply_odriver;
typedef t_ply_odriver *p_ply_odriver;
/* ----------------------------------------------------------------------
* Ply file handle.
*
* io_mode: read or write (from e_ply_io_mode)
* storage_mode: mode of file associated with handle (from e_ply_storage_mode)
* element: elements description for this file
* nelement: number of different elements in file
* comment: comments for this file
* ncomments: number of comments in file
* obj_info: obj_info items for this file
* nobj_infos: number of obj_info items in file
* fp: file pointer associated with ply file
* c: last character read from ply file
* buffer: last word/chunck of data read from ply file
* buffer_first, buffer_last: interval of untouched good data in buffer
* buffer_token: start of parsed token (line or word) in buffer
* idriver, odriver: input driver used to get property fields from file
* argument: storage space for callback arguments
* welement, wproperty: element/property type being written
* winstance_index: index of instance of current element being written
* wvalue_index: index of list property value being written
* wlength: number of values in list property being written
* error_cb: callback for error messages
* ---------------------------------------------------------------------- */
typedef struct t_ply_ {
e_ply_io_mode io_mode;
e_ply_storage_mode storage_mode;
p_ply_element element;
long nelements;
char *comment;
long ncomments;
char *obj_info;
long nobj_infos;
FILE *fp;
int c;
char buffer[BUFFERSIZE];
size_t buffer_first, buffer_token, buffer_last;
p_ply_idriver idriver;
p_ply_odriver odriver;
t_ply_argument argument;
long welement, wproperty;
long winstance_index, wvalue_index, wlength;
p_ply_error_cb error_cb;
} t_ply;
/* ----------------------------------------------------------------------
* I/O functions and drivers
* ---------------------------------------------------------------------- */
static t_ply_idriver ply_idriver_ascii;
static t_ply_idriver ply_idriver_binary;
static t_ply_idriver ply_idriver_binary_reverse;
static t_ply_odriver ply_odriver_ascii;
static t_ply_odriver ply_odriver_binary;
static t_ply_odriver ply_odriver_binary_reverse;
static int ply_read_word(p_ply ply);
static int ply_check_word(p_ply ply);
static int ply_read_line(p_ply ply);
static int ply_check_line(p_ply ply);
static int ply_read_chunk(p_ply ply, void *anybuffer, size_t size);
static int ply_read_chunk_reverse(p_ply ply, void *anybuffer, size_t size);
static int ply_write_chunk(p_ply ply, void *anybuffer, size_t size);
static int ply_write_chunk_reverse(p_ply ply, void *anybuffer, size_t size);
static void ply_reverse(void *anydata, size_t size);
/* ----------------------------------------------------------------------
* String functions
* ---------------------------------------------------------------------- */
static int ply_find_string(const char *item, const char* const list[]);
static p_ply_element ply_find_element(p_ply ply, const char *name);
static p_ply_property ply_find_property(p_ply_element element,
const char *name);
/* ----------------------------------------------------------------------
* Header parsing
* ---------------------------------------------------------------------- */
static int ply_read_header_format(p_ply ply);
static int ply_read_header_comment(p_ply ply);
static int ply_read_header_obj_info(p_ply ply);
static int ply_read_header_property(p_ply ply);
static int ply_read_header_element(p_ply ply);
/* ----------------------------------------------------------------
sweet_infancy
- 粉丝: 24
- 资源: 4