Revision: 75360
http://sourceforge.net/p/brlcad/code/75360
Author: starseeker
Date: 2020-04-11 01:34:28 +0000 (Sat, 11 Apr 2020)
Log Message:
-----------
Shift rply from a src/other library to embedded files.
Modified Paths:
--------------
brlcad/trunk/src/conv/ply/CMakeLists.txt
brlcad/trunk/src/other/CMakeLists.txt
Added Paths:
-----------
brlcad/trunk/src/conv/ply/rply.c
brlcad/trunk/src/conv/ply/rply.h
brlcad/trunk/src/conv/ply/rply_license.txt
Removed Paths:
-------------
brlcad/trunk/src/other/rply/
brlcad/trunk/src/other/rply.dist
Modified: brlcad/trunk/src/conv/ply/CMakeLists.txt
===================================================================
--- brlcad/trunk/src/conv/ply/CMakeLists.txt 2020-04-11 01:27:08 UTC (rev
75359)
+++ brlcad/trunk/src/conv/ply/CMakeLists.txt 2020-04-11 01:34:28 UTC (rev
75360)
@@ -2,19 +2,22 @@
${CMAKE_CURRENT_SOURCE_DIR}
${BU_INCLUDE_DIRS}
${RT_INCLUDE_DIRS}
- ${RPLY_INCLUDE_DIRS}
)
BRLCAD_INCLUDE_DIRS(PLY_INCLUDE_DIRS)
-BRLCAD_ADDEXEC(ply-g ply-g.c "${RPLY_LIBRARIES};librt;libnmg;libbu;libwdb")
-BRLCAD_ADDEXEC(g-ply g-ply.c "${RPLY_LIBRARIES};librt;libnmg;libbu")
+BRLCAD_ADDEXEC(ply-g "ply-g.c;rply.c" "librt;libnmg;libbu;libwdb")
+BRLCAD_ADDEXEC(g-ply "g-ply.c;rply.c" "librt;libnmg;libbu")
-if(CPP_DLL_DEFINES)
- SET_PROPERTY(TARGET ply-g APPEND PROPERTY COMPILE_DEFINITIONS
"RPLY_DLL_IMPORTS")
- SET_PROPERTY(TARGET g-ply APPEND PROPERTY COMPILE_DEFINITIONS
"RPLY_DLL_IMPORTS")
-endif(CPP_DLL_DEFINES)
+if (CPP_DLL_DEFINES)
+ set_property(TARGET ply-g APPEND PROPERTY COMPILE_DEFINITIONS
"RPLY_DLL_IMPORTS")
+ set_property(TARGET g-ply APPEND PROPERTY COMPILE_DEFINITIONS
"RPLY_DLL_IMPORTS")
+endif (CPP_DLL_DEFINES)
-CMAKEFILES(CMakeLists.txt)
+CMAKEFILES(
+ CMakeLists.txt
+ rply.h
+ rply_license.txt
+ )
# Local Variables:
# tab-width: 8
Copied: brlcad/trunk/src/conv/ply/rply.c (from rev 75359,
brlcad/trunk/src/other/rply/rply.c)
===================================================================
--- brlcad/trunk/src/conv/ply/rply.c (rev 0)
+++ brlcad/trunk/src/conv/ply/rply.c 2020-04-11 01:34:28 UTC (rev 75360)
@@ -0,0 +1,1664 @@
+/* ----------------------------------------------------------------------
+ * RPly library, read/write PLY files
+ * Diego Nehab, IMPA
+ * http://www.impa.br/~diego/software/rply
+ *
+ * This library is distributed under the MIT License. See notice
+ * at the end of this file.
+ * ---------------------------------------------------------------------- */
+
+#include "common.h"
+
+#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"
+
+/* pointers to tokenized word and line in buffer */
+#define BWORD(p) (p->buffer + p->buffer_token)
+#define BLINE(p) (p->buffer + p->buffer_token)
+
+/* pointer to start of untouched bytes in buffer */
+#define BFIRST(p) (p->buffer + p->buffer_first)
+
+/* number of bytes untouched in buffer */
+#define BSIZE(p) (p->buffer_last - p->buffer_first)
+
+/* consumes data from buffer */
+#define BSKIP(p, s) (p->buffer_first += s)
+
+/* ----------------------------------------------------------------------
+ * Make sure we get our integer types right
+ * ---------------------------------------------------------------------- */
+#if defined(_MSC_VER) && (_MSC_VER < 1600)
+/* C99 stdint.h only supported in MSVC++ 10.0 and up */
+typedef __int8 t_ply_int8;
+typedef __int16 t_ply_int16;
+typedef __int32 t_ply_int32;
+typedef unsigned __int8 t_ply_uint8;
+typedef unsigned __int16 t_ply_uint16;
+typedef unsigned __int32 t_ply_uint32;
+#define PLY_INT8_MAX (127)
+#define PLY_INT8_MIN (-PLY_INT8_MAX-1)
+#define PLY_INT16_MAX (32767)
+#define PLY_INT16_MIN (-PLY_INT16_MAX-1)
+#define PLY_INT32_MAX (2147483647)
+#define PLY_INT32_MIN (-PLY_INT32_MAX-1)
+#define PLY_UINT8_MAX (255)
+#define PLY_UINT16_MAX (65535)
+#define PLY_UINT32_MAX (4294967295)
+#else
+#include <stdint.h>
+typedef int8_t t_ply_int8;
+typedef int16_t t_ply_int16;
+typedef int32_t t_ply_int32;
+typedef uint8_t t_ply_uint8;
+typedef uint16_t t_ply_uint16;
+typedef uint32_t t_ply_uint32;
+#define PLY_INT8_MIN INT8_MIN
+#define PLY_INT8_MAX INT8_MAX
+#define PLY_INT16_MIN INT16_MIN
+#define PLY_INT16_MAX INT16_MAX
+#define PLY_INT32_MIN INT32_MIN
+#define PLY_INT32_MAX INT32_MAX
+#define PLY_UINT8_MAX UINT8_MAX
+#define PLY_UINT16_MAX UINT16_MAX
+#define PLY_UINT32_MAX UINT32_MAX
+#endif
+
+/* ----------------------------------------------------------------------
+ * 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[] = {
+ "invalid",
+ "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
+ * rn: skip extra char after end_header?
+ * 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: error callback
+ * pdata/idata: user data defined with ply_open/ply_create
+ * ---------------------------------------------------------------------- */
+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 rn;
+ 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;
+ void *pdata;
+ long idata;
+} t_ply;
+
+/* ----------------------------------------------------------------------
+ * I/O functions and drivers
+ * ---------------------------------------------------------------------- */
+static int ply_read_word(p_ply ply);
+static int ply_check_word(p_ply ply);
+static void ply_finish_word(p_ply ply, size_t size);
+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);
+
+/* ----------------------------------------------------------------------
+ * Output handlers
+ * ---------------------------------------------------------------------- */
+static int oascii_int8(p_ply ply, double value) {
+ if (value > PLY_INT8_MAX || value < PLY_INT8_MIN) return 0;
+ return fprintf(ply->fp, "%d", (t_ply_int8) value) > 0;
+}
+
+static int oascii_uint8(p_ply ply, double value) {
+ if (value > PLY_UINT8_MAX || value < 0) return 0;
+ return fprintf(ply->fp, "%d", (t_ply_uint8) value) > 0;
+}
+
+static int oascii_int16(p_ply ply, double value) {
+ if (value > PLY_INT16_MAX || value < PLY_INT16_MIN) return 0;
+ return fprintf(ply->fp, "%d", (t_ply_int16) value) > 0;
+}
+
+static int oascii_uint16(p_ply ply, double value) {
+ if (value > PLY_UINT16_MAX || value < 0) return 0;
+ return fprintf(ply->fp, "%d", (t_ply_uint16) value) > 0;
+}
+
+static int oascii_int32(p_ply ply, double value) {
+ if (value > PLY_INT32_MAX || value < PLY_INT32_MIN) return 0;
+ return fprintf(ply->fp, "%d", (t_ply_int32) value) > 0;
+}
+
+static int oascii_uint32(p_ply ply, double value) {
+ if (value > PLY_UINT32_MAX || value < 0) return 0;
+ return fprintf(ply->fp, "%d", (t_ply_uint32) value) > 0;
+}
+
+static int oascii_float32(p_ply ply, double value) {
+ if (value < -FLT_MAX || value > FLT_MAX) return 0;
+ return fprintf(ply->fp, "%g", (float) value) > 0;
+}
+
+static int oascii_float64(p_ply ply, double value) {
+ if (value < -DBL_MAX || value > DBL_MAX) return 0;
+ return fprintf(ply->fp, "%g", value) > 0;
+}
+
+static int obinary_int8(p_ply ply, double value) {
+ t_ply_int8 int8 = (t_ply_int8) value;
+ if (value > PLY_INT8_MAX || value < PLY_INT8_MIN) return 0;
+ return ply->odriver->ochunk(ply, &int8, sizeof(int8));
+}
+
+static int obinary_uint8(p_ply ply, double value) {
+ t_ply_uint8 uint8 = (t_ply_uint8) value;
+ if (value > PLY_UINT8_MAX || value < 0) return 0;
+ return ply->odriver->ochunk(ply, &uint8, sizeof(uint8));
+}
+
+static int obinary_int16(p_ply ply, double value) {
+ t_ply_int16 int16 = (t_ply_int16) value;
+ if (value > PLY_INT16_MAX || value < PLY_INT16_MIN) return 0;
+ return ply->odriver->ochunk(ply, &int16, sizeof(int16));
+}
+
+static int obinary_uint16(p_ply ply, double value) {
+ t_ply_uint16 uint16 = (t_ply_uint16) value;
+ if (value > PLY_UINT16_MAX || value < 0) return 0;
+ return ply->odriver->ochunk(ply, &uint16, sizeof(uint16));
+}
+
+static int obinary_int32(p_ply ply, double value) {
+ t_ply_int32 int32 = (t_ply_int32) value;
+ if (value > PLY_INT32_MAX || value < PLY_INT32_MIN) return 0;
+ return ply->odriver->ochunk(ply, &int32, sizeof(int32));
+}
+
+static int obinary_uint32(p_ply ply, double value) {
+ t_ply_uint32 uint32 = (t_ply_uint32) value;
+ if (value > PLY_UINT32_MAX || value < 0) return 0;
+ return ply->odriver->ochunk(ply, &uint32, sizeof(uint32));
+}
+
+static int obinary_float32(p_ply ply, double value) {
+ float float32 = (float) value;
+ if (value > FLT_MAX || value < -FLT_MAX) return 0;
+ return ply->odriver->ochunk(ply, &float32, sizeof(float32));
+}
+
+static int obinary_float64(p_ply ply, double value) {
+ return ply->odriver->ochunk(ply, &value, sizeof(value));
+}
+
+/* ----------------------------------------------------------------------
+ * Input handlers
+ * ---------------------------------------------------------------------- */
+static int iascii_int8(p_ply ply, double *value) {
+ char *end;
+ if (!ply_read_word(ply)) return 0;
+ *value = strtol(BWORD(ply), &end, 10);
+ if (*end || *value > PLY_INT8_MAX || *value < PLY_INT8_MIN) return 0;
+ return 1;
+}
+
+static int iascii_uint8(p_ply ply, double *value) {
+ char *end;
+ if (!ply_read_word(ply)) return 0;
+ *value = strtol(BWORD(ply), &end, 10);
+ if (*end || *value > PLY_UINT8_MAX || *value < 0) return 0;
+ return 1;
+}
+
+static int iascii_int16(p_ply ply, double *value) {
+ char *end;
+ if (!ply_read_word(ply)) return 0;
+ *value = strtol(BWORD(ply), &end, 10);
+ if (*end || *value > PLY_INT16_MAX || *value < PLY_INT16_MIN) return 0;
+ return 1;
+}
+
+static int iascii_uint16(p_ply ply, double *value) {
+ char *end;
+ if (!ply_read_word(ply)) return 0;
+ *value = strtol(BWORD(ply), &end, 10);
+ if (*end || *value > PLY_UINT16_MAX || *value < 0) return 0;
+ return 1;
+}
+
+static int iascii_int32(p_ply ply, double *value) {
+ char *end;
+ if (!ply_read_word(ply)) return 0;
+ *value = strtol(BWORD(ply), &end, 10);
+ if (*end || *value > PLY_INT32_MAX || *value < PLY_INT32_MIN) return 0;
+ return 1;
+}
+
+static int iascii_uint32(p_ply ply, double *value) {
+ char *end;
+ if (!ply_read_word(ply)) return 0;
+ *value = strtol(BWORD(ply), &end, 10);
+ if (*end || *value > PLY_UINT32_MAX || *value < 0) return 0;
+ return 1;
+}
+
+static int iascii_float32(p_ply ply, double *value) {
+ char *end;
+ if (!ply_read_word(ply)) return 0;
+ *value = strtod(BWORD(ply), &end);
+ if (*end || *value < -FLT_MAX || *value > FLT_MAX) return 0;
+ return 1;
+}
+
+static int iascii_float64(p_ply ply, double *value) {
+ char *end;
+ if (!ply_read_word(ply)) return 0;
+ *value = strtod(BWORD(ply), &end);
+ if (*end || *value < -DBL_MAX || *value > DBL_MAX) return 0;
+ return 1;
+}
+
+static int ibinary_int8(p_ply ply, double *value) {
+ t_ply_int8 int8;
+ if (!ply->idriver->ichunk(ply, &int8, 1)) return 0;
+ *value = int8;
+ return 1;
+}
+
+static int ibinary_uint8(p_ply ply, double *value) {
+ t_ply_uint8 uint8;
+ if (!ply->idriver->ichunk(ply, &uint8, 1)) return 0;
+ *value = uint8;
+ return 1;
+}
+
+static int ibinary_int16(p_ply ply, double *value) {
+ t_ply_int16 int16;
+ if (!ply->idriver->ichunk(ply, &int16, sizeof(int16))) return 0;
+ *value = int16;
+ return 1;
+}
+
+static int ibinary_uint16(p_ply ply, double *value) {
+ t_ply_uint16 uint16;
+ if (!ply->idriver->ichunk(ply, &uint16, sizeof(uint16))) return 0;
+ *value = uint16;
+ return 1;
+}
+
+static int ibinary_int32(p_ply ply, double *value) {
+ t_ply_int32 int32;
+ if (!ply->idriver->ichunk(ply, &int32, sizeof(int32))) return 0;
+ *value = int32;
+ return 1;
+}
+
+static int ibinary_uint32(p_ply ply, double *value) {
+ t_ply_uint32 uint32;
+ if (!ply->idriver->ichunk(ply, &uint32, sizeof(uint32))) return 0;
+ *value = uint32;
+ return 1;
+}
+
+static int ibinary_float32(p_ply ply, double *value) {
+ float float32;
+ if (!ply->idriver->ichunk(ply, &float32, sizeof(float32))) return 0;
+ *value = float32;
+ return 1;
+}
+
+static int ibinary_float64(p_ply ply, double *value) {
+ return ply->idriver->ichunk(ply, value, sizeof(double));
+}
+
+/* ----------------------------------------------------------------------
+ * Constants
+ * ---------------------------------------------------------------------- */
+static t_ply_idriver ply_idriver_ascii = {
+ { iascii_int8, iascii_uint8, iascii_int16, iascii_uint16,
+ iascii_int32, iascii_uint32, iascii_float32, iascii_float64,
+ iascii_int8, iascii_uint8, iascii_int16, iascii_uint16,
+ iascii_int32, iascii_uint32, iascii_float32, iascii_float64
+ }, /* order matches e_ply_type enum */
+ NULL,
+ "ascii input"
+};
+
+static t_ply_idriver ply_idriver_binary = {
+ { ibinary_int8, ibinary_uint8, ibinary_int16, ibinary_uint16,
+ ibinary_int32, ibinary_uint32, ibinary_float32, ibinary_float64,
+ ibinary_int8, ibinary_uint8, ibinary_int16, ibinary_uint16,
+ ibinary_int32, ibinary_uint32, ibinary_float32, ibinary_float64
+ }, /* order matches e_ply_type enum */
+ ply_read_chunk,
+ "binary input"
+};
+
+static t_ply_idriver ply_idriver_binary_reverse = {
+ { ibinary_int8, ibinary_uint8, ibinary_int16, ibinary_uint16,
+ ibinary_int32, ibinary_uint32, ibinary_float32, ibinary_float64,
+ ibinary_int8, ibinary_uint8, ibinary_int16, ibinary_uint16,
+ ibinary_int32, ibinary_uint32, ibinary_float32, ibinary_float64
+ }, /* order matches e_ply_type enum */
+ ply_read_chunk_reverse,
+ "reverse binary input"
+};
+
+static t_ply_odriver ply_odriver_ascii = {
+ { oascii_int8, oascii_uint8, oascii_int16, oascii_uint16,
+ oascii_int32, oascii_uint32, oascii_float32, oascii_float64,
+ oascii_int8, oascii_uint8, oascii_int16, oascii_uint16,
+ oascii_int32, oascii_uint32, oascii_float32, oascii_float64
+ }, /* order matches e_ply_type enum */
+ NULL,
+ "ascii output"
+};
+
+static t_ply_odriver ply_odriver_binary = {
+ { obinary_int8, obinary_uint8, obinary_int16, obinary_uint16,
+ obinary_int32, obinary_uint32, obinary_float32, obinary_float64,
+ obinary_int8, obinary_uint8, obinary_int16, obinary_uint16,
+ obinary_int32, obinary_uint32, obinary_float32, obinary_float64
+ }, /* order matches e_ply_type enum */
+ ply_write_chunk,
+ "binary output"
+};
+
+static t_ply_odriver ply_odriver_binary_reverse = {
+ { obinary_int8, obinary_uint8, obinary_int16, obinary_uint16,
+ obinary_int32, obinary_uint32, obinary_float32, obinary_float64,
+ obinary_int8, obinary_uint8, obinary_int16, obinary_uint16,
+ obinary_int32, obinary_uint32, obinary_float32, obinary_float64
+ }, /* order matches e_ply_type enum */
+ ply_write_chunk_reverse,
+ "reverse binary output"
+};
+
+/* ----------------------------------------------------------------------
+ * String functions
+ * ---------------------------------------------------------------------- */
+static e_ply_type ply_find_type_string(const char *item);
+static e_ply_storage_mode ply_find_storage_string(const char *item);
+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_magic(p_ply ply);
+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);
+
+/* ----------------------------------------------------------------------
+ * Error handling
+ * ---------------------------------------------------------------------- */
+static void ply_error_cb(p_ply ply, const char *message);
+static void ply_ferror(p_ply ply, const char *fmt, ...);
+
+/* ----------------------------------------------------------------------
+ * Memory allocation and initialization
+ * ---------------------------------------------------------------------- */
+static void ply_init(p_ply ply);
+static void ply_element_init(p_ply_element element);
+static void ply_property_init(p_ply_property property);
+static p_ply ply_alloc(void);
+static p_ply_element ply_grow_element(p_ply ply);
+static p_ply_property ply_grow_property(p_ply ply, p_ply_element element);
+static void *ply_grow_array(p_ply ply, void **pointer, long *nmemb, long size);
+
+/* ----------------------------------------------------------------------
+ * Special functions
+ * ---------------------------------------------------------------------- */
+static e_ply_storage_mode ply_arch_endian(void);
+static int ply_type_check(void);
+
+/* ----------------------------------------------------------------------
+ * Auxiliary read functions
+ * ---------------------------------------------------------------------- */
+static int ply_read_element(p_ply ply, p_ply_element element,
+ p_ply_argument argument);
+static int ply_read_property(p_ply ply, p_ply_element element,
+ p_ply_property property, p_ply_argument argument);
+static int ply_read_list_property(p_ply ply, p_ply_element element,
+ p_ply_property property, p_ply_argument argument);
+static int ply_read_scalar_property(p_ply ply, p_ply_element element,
+ p_ply_property property, p_ply_argument argument);
+
+/* ----------------------------------------------------------------------
+ * Buffer support functions
+ * ---------------------------------------------------------------------- */
+
+/* refills the buffer */
+static int BREFILL(p_ply ply) {
+ /* move untouched data to beginning of buffer */
+ size_t size = BSIZE(ply);
+ memmove(ply->buffer, BFIRST(ply), size);
+ ply->buffer_last = size;
+ ply->buffer_first = ply->buffer_token = 0;
+ /* fill remaining with new data */
+ size = fread(ply->buffer+size, 1, BUFFERSIZE-size-1, ply->fp);
+ /* place sentinel so we can use str* functions with buffer */
+ ply->buffer[BUFFERSIZE-1] = '\0';
+ /* check if read failed */
+ if (size <= 0) return 0;
+ /* increase size to account for new data */
+ ply->buffer_last += size;
+ return 1;
+}
+
+/* We don't care about end-of-line, generally, because we
+ * separate words by any white-space character.
+ * Unfortunately, in binary mode, right after 'end_header',
+ * we have to know *exactly* how many characters to skip */
+/* We use the end-of-line marker after the 'ply' magic
+ * number to figure out what to do */
+static int ply_read_header_magic(p_ply ply) {
+ char *magic = ply->buffer;
+ if (!BREFILL(ply)) {
+ ply->error_cb(ply, "Unable to read magic number from file");
+ return 0;
+ }
+ /* check if it is ply */
+ if (magic[0] != 'p' || magic[1] != 'l' || magic[2] != 'y'
+ || !isspace(magic[3])) {
+ ply->error_cb(ply, "Wrong magic number. Expected 'ply'");
+ return 0;
+ }
+ /* figure out if we have to skip the extra character
+ * after header when we reach the binary part of file */
+ ply->rn = magic[3] == '\r' && magic[4] == '\n';
+ BSKIP(ply, 3);
+ return 1;
+}
+
+/* ----------------------------------------------------------------------
+ * Exported functions
+ * ---------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------
+ * Read support functions
+ * ---------------------------------------------------------------------- */
+p_ply ply_open(const char *name, p_ply_error_cb error_cb,
+ long idata, void *pdata) {
+ FILE *fp = NULL;
+ p_ply ply = ply_alloc();
+ if (error_cb == NULL) error_cb = ply_error_cb;
+ if (!ply) {
+ error_cb(NULL, "Out of memory");
+ return NULL;
+ }
+ ply->idata = idata;
+ ply->pdata = pdata;
+ ply->io_mode = PLY_READ;
+ ply->error_cb = error_cb;
+ if (!ply_type_check()) {
+ error_cb(ply, "Incompatible type system");
+ free(ply);
+ return NULL;
+ }
+ assert(name);
+ fp = fopen(name, "rb");
+ if (!fp) {
+ error_cb(ply, "Unable to open file");
+ free(ply);
+ return NULL;
+ }
+ ply->fp = fp;
+ return ply;
+}
+
+int ply_read_header(p_ply ply) {
+ assert(ply && ply->fp && ply->io_mode == PLY_READ);
+ if (!ply_read_header_magic(ply)) return 0;
+ if (!ply_read_word(ply)) return 0;
+ /* parse file format */
+ if (!ply_read_header_format(ply)) {
+ ply_ferror(ply, "Invalid file format");
+ return 0;
+ }
+ /* parse elements, comments or obj_infos until the end of header */
+ while (strcmp(BWORD(ply), "end_header")) {
+ if (!ply_read_header_comment(ply) &&
+ !ply_read_header_element(ply) &&
+ !ply_read_header_obj_info(ply)) {
+ ply_ferror(ply, "Unexpected token '%s'", BWORD(ply));
+ return 0;
+ }
+ }
+ /* skip extra character? */
+ if (ply->rn) {
+ if (BSIZE(ply) < 1 && !BREFILL(ply)) {
+ ply_ferror(ply, "Unexpected end of file");
+ return 0;
+ }
+ BSKIP(ply, 1);
+ }
+ return 1;
+}
+
+long ply_set_read_cb(p_ply ply, const char *element_name,
+ const char* property_name, p_ply_read_cb read_cb,
+ void *pdata, long idata) {
+ p_ply_element element = NULL;
+ p_ply_property property = NULL;
+ assert(ply && element_name && property_name);
+ element = ply_find_element(ply, element_name);
+ if (!element) return 0;
+ property = ply_find_property(element, property_name);
+ if (!property) return 0;
+ property->read_cb = read_cb;
+ property->pdata = pdata;
+ property->idata = idata;
+ return (int) element->ninstances;
+}
+
+int ply_read(p_ply ply) {
+ long i;
+ p_ply_argument argument;
+ assert(ply && ply->fp && ply->io_mode == PLY_READ);
+ argument = &ply->argument;
+ /* for each element type */
+ for (i = 0; i < ply->nelements; i++) {
+ p_ply_element element = &ply->element[i];
+ argument->element = element;
+ if (!ply_read_element(ply, element, argument))
+ return 0;
+ }
+ return 1;
+}
+
+/* ----------------------------------------------------------------------
+ * Write support functions
+ * ---------------------------------------------------------------------- */
+p_ply ply_create(const char *name, e_ply_storage_mode storage_mode,
+ p_ply_error_cb error_cb, long idata, void *pdata) {
+ FILE *fp = NULL;
+ p_ply ply = ply_alloc();
+ if (error_cb == NULL) error_cb = ply_error_cb;
+ if (!ply) {
+ error_cb(NULL, "Out of memory");
+ return NULL;
+ }
+ if (!ply_type_check()) {
+ error_cb(ply, "Incompatible type system");
+ free(ply);
+ return NULL;
+ }
+ assert(name && storage_mode <= PLY_DEFAULT);
+ fp = fopen(name, "wb");
+ if (!fp) {
+ error_cb(ply, "Unable to create file");
+ free(ply);
+ return NULL;
+ }
+ ply->idata = idata;
+ ply->pdata = pdata;
+ ply->io_mode = PLY_WRITE;
+ if (storage_mode == PLY_DEFAULT) storage_mode = ply_arch_endian();
+ if (storage_mode == PLY_ASCII) ply->odriver = &ply_odriver_ascii;
+ else if (storage_mode == ply_arch_endian())
+ ply->odriver = &ply_odriver_binary;
+ else ply->odriver = &ply_odriver_binary_reverse;
+ ply->storage_mode = storage_mode;
+ ply->fp = fp;
+ ply->error_cb = error_cb;
+ return ply;
+}
+
+int ply_add_element(p_ply ply, const char *name, long ninstances) {
+ p_ply_element element = NULL;
+ assert(ply && ply->fp && ply->io_mode == PLY_WRITE);
+ assert(name && strlen(name) < WORDSIZE && ninstances >= 0);
+ if (strlen(name) >= WORDSIZE || ninstances < 0) {
+ ply_ferror(ply, "Invalid arguments");
+ return 0;
+ }
+ element = ply_grow_element(ply);
+ if (!element) return 0;
+ strcpy(element->name, name);
+ element->ninstances = ninstances;
+ return 1;
+}
+
+int ply_add_scalar_property(p_ply ply, const char *name, e_ply_type type) {
+ p_ply_element element = NULL;
+ p_ply_property property = NULL;
+ assert(ply && ply->fp && ply->io_mode == PLY_WRITE);
+ assert(name && strlen(name) < WORDSIZE);
+ assert(type < PLY_LIST);
+ if (strlen(name) >= WORDSIZE || type >= PLY_LIST) {
+ ply_ferror(ply, "Invalid arguments");
+ return 0;
+ }
+ element = &ply->element[ply->nelements-1];
+ property = ply_grow_property(ply, element);
+ if (!property) return 0;
+ strcpy(property->name, name);
+ property->type = type;
+ return 1;
+}
+
+int ply_add_list_property(p_ply ply, const char *name,
+ e_ply_type length_type, e_ply_type value_type) {
+ p_ply_element element = NULL;
+ p_ply_property property = NULL;
+ assert(ply && ply->fp && ply->io_mode == PLY_WRITE);
+ assert(name && strlen(name) < WORDSIZE);
+ if (strlen(name) >= WORDSIZE) {
+ ply_ferror(ply, "Invalid arguments");
+ return 0;
+ }
+ assert(length_type < PLY_LIST);
+ assert(value_type < PLY_LIST);
+ if (length_type >= PLY_LIST || value_type >= PLY_LIST) {
+ ply_ferror(ply, "Invalid arguments");
+ return 0;
+ }
+ element = &ply->element[ply->nelements-1];
+ property = ply_grow_property(ply, element);
+ if (!property) return 0;
+ strcpy(property->name, name);
+ property->type = PLY_LIST;
+ property->length_type = length_type;
+ property->value_type = value_type;
+ return 1;
+}
+
+int ply_add_property(p_ply ply, const char *name, e_ply_type type,
+ e_ply_type length_type, e_ply_type value_type) {
+ if (type == PLY_LIST)
+ return ply_add_list_property(ply, name, length_type, value_type);
+ else
+ return ply_add_scalar_property(ply, name, type);
+}
+
+int ply_add_comment(p_ply ply, const char *comment) {
+ char *new_comment = NULL;
+ assert(ply && comment && strlen(comment) < LINESIZE);
+ if (!comment || strlen(comment) >= LINESIZE) {
+ ply_ferror(ply, "Invalid arguments");
+ return 0;
+ }
+ new_comment = (char *) ply_grow_array(ply, (void **) &ply->comment,
+ &ply->ncomments, LINESIZE);
+ if (!new_comment) return 0;
+ strcpy(new_comment, comment);
+ return 1;
+}
+
+int ply_add_obj_info(p_ply ply, const char *obj_info) {
+ char *new_obj_info = NULL;
+ assert(ply && obj_info && strlen(obj_info) < LINESIZE);
+ if (!obj_info || strlen(obj_info) >= LINESIZE) {
+ ply_ferror(ply, "Invalid arguments");
+ return 0;
+ }
+ new_obj_info = (char *) ply_grow_array(ply, (void **) &ply->obj_info,
+ &ply->nobj_infos, LINESIZE);
+ if (!new_obj_info) return 0;
+ strcpy(new_obj_info, obj_info);
+ return 1;
+}
+
+int ply_write_header(p_ply ply) {
+ long i, j;
+ assert(ply && ply->fp && ply->io_mode == PLY_WRITE);
+ assert(ply->element || ply->nelements == 0);
+ assert(!ply->element || ply->nelements > 0);
+ if (fprintf(ply->fp, "ply\nformat %s 1.0\n",
+ ply_storage_mode_list[ply->storage_mode]) <= 0) goto error;
+ for (i = 0; i < ply->ncomments; i++)
+ if (fprintf(ply->fp, "comment %s\n", ply->comment + LINESIZE*i) <= 0)
+ goto error;
+ for (i = 0; i < ply->nobj_infos; i++)
+ if (fprintf(ply->fp, "obj_info %s\n", ply->obj_info + LINESIZE*i) <= 0)
+ goto error;
+ for (i = 0; i < ply->nelements; i++) {
+ p_ply_element element = &ply->element[i];
+ assert(element->property || element->nproperties == 0);
+ assert(!element->property || element->nproperties > 0);
+ if (fprintf(ply->fp, "element %s %ld\n", element->name,
+ element->ninstances) <= 0) goto error;
+ for (j = 0; j < element->nproperties; j++) {
+ p_ply_property property = &element->property[j];
+ if (property->type == PLY_LIST) {
+ if (fprintf(ply->fp, "property list %s %s %s\n",
+ ply_type_list[property->length_type],
+ ply_type_list[property->value_type],
+ property->name) <= 0) goto error;
+ } else {
+ if (fprintf(ply->fp, "property %s %s\n",
+ ply_type_list[property->type],
+ property->name) <= 0) goto error;
+ }
+ }
+ }
+ return fprintf(ply->fp, "end_header\n") > 0;
+error:
+ ply_ferror(ply, "Error writing to file");
+ return 0;
+}
+
+int ply_write(p_ply ply, double value) {
+ p_ply_element element = NULL;
+ p_ply_property property = NULL;
+ int type = -1;
+ int breakafter = 0;
+ int spaceafter = 1;
+ if (ply->welement > ply->nelements) return 0;
+ element = &ply->element[ply->welement];
+ if (ply->wproperty > element->nproperties) return 0;
+ property = &element->property[ply->wproperty];
+ if (property->type == PLY_LIST) {
+ if (ply->wvalue_index == 0) {
+ type = property->length_type;
+ ply->wlength = (long) value;
+ } else type = property->value_type;
+ } else {
+ type = property->type;
+ ply->wlength = 0;
+ }
+ if (!ply->odriver->ohandler[type](ply, value)) {
+ ply_ferror(ply, "Failed writing %s of %s %d (%s: %s)",
+ property->name, element->name,
+ ply->winstance_index,
+ ply->odriver->name, ply_type_list[type]);
+ return 0;
+ }
+ ply->wvalue_index++;
+ if (ply->wvalue_index > ply->wlength) {
+ ply->wvalue_index = 0;
+ ply->wproperty++;
+ }
+ if (ply->wproperty >= element->nproperties) {
+ ply->wproperty = 0;
+ ply->winstance_index++;
+ breakafter = 1;
+ spaceafter = 0;
+ }
+ if (ply->winstance_index >= element->ninstances) {
+ ply->winstance_index = 0;
+ do {
+ ply->welement++;
+ element = &ply->element[ply->welement];
+ } while (ply->welement < ply->nelements && !element->ninstances);
+ }
+ if (ply->storage_mode == PLY_ASCII) {
+ return (!spaceafter || putc(' ', ply->fp) > 0) &&
+ (!breakafter || putc('\n', ply->fp) > 0);
+ } else {
+ return 1;
+ }
+}
+
+int ply_close(p_ply ply) {
+ long i;
+ assert(ply && ply->fp);
+ assert(ply->element || ply->nelements == 0);
+ assert(!ply->element || ply->nelements > 0);
+ /* write last chunk to file */
+ if (ply->io_mode == PLY_WRITE &&
+ fwrite(ply->buffer, 1, ply->buffer_last, ply->fp) < ply->buffer_last) {
+ ply_ferror(ply, "Error closing up");
+ return 0;
+ }
+ fclose(ply->fp);
+ /* free all memory used by handle */
+ if (ply->element) {
+ for (i = 0; i < ply->nelements; i++) {
+ p_ply_element element = &ply->element[i];
+ if (element->property) free(element->property);
+ }
+ free(ply->element);
+ }
+ if (ply->obj_info) free(ply->obj_info);
+ if (ply->comment) free(ply->comment);
+ free(ply);
+ return 1;
+}
+
+/* ----------------------------------------------------------------------
+ * Query support functions
+ * ---------------------------------------------------------------------- */
+p_ply_element ply_get_next_element(p_ply ply,
+ p_ply_element last) {
+ assert(ply);
+ if (!last) return ply->element;
+ last++;
+ if (last < ply->element + ply->nelements) return last;
+ else return NULL;
+}
+
+int ply_get_element_info(p_ply_element element, const char** name,
+ long *ninstances) {
+ assert(element);
+ if (name) *name = element->name;
+ if (ninstances) *ninstances = (long) element->ninstances;
+ return 1;
+}
+
+p_ply_property ply_get_next_property(p_ply_element element,
+ p_ply_property last) {
+ assert(element);
+ if (!last) return element->property;
+ last++;
+ if (last < element->property + element->nproperties) return last;
+ else return NULL;
+}
+
+int ply_get_property_info(p_ply_property property, const char** name,
+ e_ply_type *type, e_ply_type *length_type, e_ply_type *value_type) {
+ assert(property);
+ if (name) *name = property->name;
+ if (type) *type = property->type;
+ if (length_type) *length_type = property->length_type;
+ if (value_type) *value_type = property->value_type;
+ return 1;
+
+}
+
+const char *ply_get_next_comment(p_ply ply, const char *last) {
+ assert(ply);
+ if (!last) return ply->comment;
+ last += LINESIZE;
+ if (last < ply->comment + LINESIZE*ply->ncomments) return last;
+ else return NULL;
+}
+
+const char *ply_get_next_obj_info(p_ply ply, const char *last) {
+ assert(ply);
+ if (!last) return ply->obj_info;
+ last += LINESIZE;
+ if (last < ply->obj_info + LINESIZE*ply->nobj_infos) return last;
+ else return NULL;
+}
+
+/* ----------------------------------------------------------------------
+ * Callback argument support functions
+ * ---------------------------------------------------------------------- */
+int ply_get_argument_element(p_ply_argument argument,
+ p_ply_element *element, long *instance_index) {
+ assert(argument);
+ if (!argument) return 0;
+ if (element) *element = argument->element;
+ if (instance_index) *instance_index = argument->instance_index;
+ return 1;
+}
+
+int ply_get_argument_property(p_ply_argument argument,
+ p_ply_property *property, long *length, long *value_index) {
+ assert(argument);
+ if (!argument) return 0;
+ if (property) *property = argument->property;
+ if (length) *length = argument->length;
+ if (value_index) *value_index = argument->value_index;
+ return 1;
+}
+
+int ply_get_argument_user_data(p_ply_argument argument, void **pdata,
+ long *idata) {
+ assert(argument);
+ if (!argument) return 0;
+ if (pdata) *pdata = argument->pdata;
+ if (idata) *idata = argument->idata;
+ return 1;
+}
+
+double ply_get_argument_value(p_ply_argument argument) {
+ assert(argument);
+ if (!argument) return 0.0;
+ return argument->value;
+}
+
+int ply_get_ply_user_data(p_ply ply, void **pdata, long *idata) {
+ assert(ply);
+ if (!ply) return 0;
+ if (pdata) *pdata = ply->pdata;
+ if (idata) *idata = ply->idata;
+ return 1;
+}
+
+/* ----------------------------------------------------------------------
+ * Internal functions
+ * ---------------------------------------------------------------------- */
+static int ply_read_list_property(p_ply ply, p_ply_element element,
+ p_ply_property property, p_ply_argument argument) {
+ int l;
+ p_ply_read_cb read_cb = property->read_cb;
+ p_ply_ihandler *driver = ply->idriver->ihandler;
+ /* get list length */
+ p_ply_ihandler handler = driver[property->length_type];
+ double length;
+ if (!handler(ply, &length)) {
+ ply_ferror(ply, "Error reading '%s' of '%s' number %d",
+ property->name, element->name, argument->instance_index);
+ return 0;
+ }
+ /* invoke callback to pass length in value field */
+ argument->length = (long) length;
+ argument->value_index = -1;
+ argument->value = length;
+ if (read_cb && !read_cb(argument)) {
+ ply_ferror(ply, "Aborted by user");
+ return 0;
+ }
+ /* read list values */
+ handler = driver[property->value_type];
+ /* for each value in list */
+ for (l = 0; l < (long) length; l++) {
+ /* read value from file */
+ argument->value_index = l;
+ if (!handler(ply, &argument->value)) {
+ ply_ferror(ply, "Error reading value number %d of '%s' of "
+ "'%s' number %d", l+1, property->name,
+ element->name, argument->instance_index);
+ return 0;
+ }
+ /* invoke callback to pass value */
+ if (read_cb && !read_cb(argument)) {
+ ply_ferror(ply, "Aborted by user");
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int ply_read_scalar_property(p_ply ply, p_ply_element element,
+ p_ply_property property, p_ply_argument argument) {
+ p_ply_read_cb read_cb = property->read_cb;
+ p_ply_ihandler *driver = ply->idriver->ihandler;
+ p_ply_ihandler handler = driver[property->type];
+ argument->length = 1;
+ argument->value_index = 0;
+ if (!handler(ply, &argument->value)) {
+ ply_ferror(ply, "Error reading '%s' of '%s' number %d",
+ property->name, element->name, argument->instance_index);
+ return 0;
+ }
+ if (read_cb && !read_cb(argument)) {
+ ply_ferror(ply, "Aborted by user");
+ return 0;
+ }
+ return 1;
+}
+
+static int ply_read_property(p_ply ply, p_ply_element element,
+ p_ply_property property, p_ply_argument argument) {
+ if (property->type == PLY_LIST)
+ return ply_read_list_property(ply, element, property, argument);
+ else
+ return ply_read_scalar_property(ply, element, property, argument);
+}
+
+static int ply_read_element(p_ply ply, p_ply_element element,
+ p_ply_argument argument) {
+ long j, k;
+ /* for each element of this type */
+ for (j = 0; j < element->ninstances; j++) {
+ argument->instance_index = j;
+ /* for each property */
+ for (k = 0; k < element->nproperties; k++) {
+ p_ply_property property = &element->property[k];
+ argument->property = property;
+ argument->pdata = property->pdata;
+ argument->idata = property->idata;
+ if (!ply_read_property(ply, element, property, argument))
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static e_ply_type ply_find_type_string(const char *item) {
+ assert(item);
+ if (!strcmp("int8", item)) {
+ return PLY_INT8;
+ }
+ if (!strcmp("uint8", item)){
+ return PLY_UINT8;
+ }
+ if (!strcmp("int16", item)){
+ return PLY_INT16;
+ }
+ if (!strcmp("uint16", item)){
+ return PLY_UINT16;
+ }
+ if (!strcmp("int32", item)){
+ return PLY_INT32;
+ }
+ if (!strcmp("uint32", item)){
+ return PLY_UIN32;
+ }
+ if (!strcmp("float32", item)){
+ return PLY_FLOAT32;
+ }
+ if (!strcmp("float64", item)){
+ return PLY_FLOAT64;
+ }
+ if (!strcmp("char", item)){
+ return PLY_CHAR;
+ }
+ if (!strcmp("uchar", item)){
+ return PLY_UCHAR;
+ }
+ if (!strcmp("short", item)){
+ return PLY_SHORT;
+ }
+ if (!strcmp("ushort", item)){
+ return PLY_USHORT;
+ }
+ if (!strcmp("int", item)){
+ return PLY_INT;
+ }
+ if (!strcmp("uint", item)){
+ return PLY_UINT;
+ }
+ if (!strcmp("float", item)){
+ return PLY_FLOAT;
+ }
+ if (!strcmp("double", item)){
+ return PLY_DOUBLE;
+ }
+ if (!strcmp("list", item)) {
+ return PLY_LIST;
+ }
+ return PLY_INVALID_TYPE;
+}
+
+static e_ply_storage_mode ply_find_storage_string(const char *item) {
+ assert(item);
+ if (!strcmp("binary_big_endian", item)) {
+ return PLY_BIG_ENDIAN;
+ }
+ if (!strcmp("binary_little_endian", item)){
+ return PLY_LITTLE_ENDIAN;
+ }
+ if (!strcmp("ascii", item)){
+ return PLY_ASCII;
+ }
+ return PLY_INVALID_STORAGE;
+}
+
+static p_ply_element ply_find_element(p_ply ply, const char *name) {
+ p_ply_element element;
+ int i, nelements;
+ assert(ply && name);
+ element = ply->element;
+ nelements = ply->nelements;
+ assert(element || nelements == 0);
+ assert(!element || nelements > 0);
+ for (i = 0; i < nelements; i++)
+ if (!strcmp(element[i].name, name)) return &element[i];
+ return NULL;
+}
+
+static p_ply_property ply_find_property(p_ply_element element,
+ const char *name) {
+ p_ply_property property;
+ int i, nproperties;
+ assert(element && name);
+ property = element->property;
+ nproperties = element->nproperties;
+ assert(property || nproperties == 0);
+ assert(!property || nproperties > 0);
+ for (i = 0; i < nproperties; i++)
+ if (!strcmp(property[i].name, name)) return &property[i];
+ return NULL;
+}
+
+static int ply_check_word(p_ply ply) {
+ size_t size = strlen(BWORD(ply));
+ if (size >= WORDSIZE) {
+ ply_ferror(ply, "Word too long");
+ return 0;
+ } else if (size == 0) {
+ ply_ferror(ply, "Unexpected end of file");
+ return 0;
+ }
+ return 1;
+}
+
+static int ply_read_word(p_ply ply) {
+ size_t t = 0;
+ assert(ply && ply->fp && ply->io_mode == PLY_READ);
+ /* skip leading blanks */
+ while (1) {
+ t = strspn(BFIRST(ply), " \n\r\t");
+ /* check if all buffer was made of blanks */
+ if (t >= BSIZE(ply)) {
+ if (!BREFILL(ply)) {
+ ply_ferror(ply, "Unexpected end of file");
+ return 0;
+ }
+ } else break;
+ }
+ BSKIP(ply, t);
+ /* look for a space after the current word */
+ t = strcspn(BFIRST(ply), " \n\r\t");
+ /* if we didn't reach the end of the buffer, we are done */
+ if (t < BSIZE(ply)) {
+ ply_finish_word(ply, t);
+ return ply_check_word(ply);
+ }
+ /* otherwise, try to refill buffer */
+ if (!BREFILL(ply)) {
+ /* if we reached the end of file, try to do with what we have */
+ ply_finish_word(ply, t);
+ return ply_check_word(ply);
+ /* ply_ferror(ply, "Unexpected end of file"); */
+ /* return 0; */
+ }
+ /* keep looking from where we left */
+ t += strcspn(BFIRST(ply) + t, " \n\r\t");
+ /* check if the token is too large for our buffer */
+ if (t >= BSIZE(ply)) {
+ ply_ferror(ply, "Token too large");
+ return 0;
+ }
+ /* we are done */
+ ply_finish_word(ply, t);
+ return ply_check_word(ply);
+}
+
+static void ply_finish_word(p_ply ply, size_t size) {
+ ply->buffer_token = ply->buffer_first;
+ BSKIP(ply, size);
+ *BFIRST(ply) = '\0';
+ BSKIP(ply, 1);
+}
+
+static int ply_check_line(p_ply ply) {
+ if (strlen(BLINE(ply)) >= LINESIZE) {
+ ply_ferror(ply, "Line too long");
+ return 0;
+ }
+ return 1;
+}
+
+static int ply_read_line(p_ply ply) {
+ const char *end = NULL;
+ assert(ply && ply->fp && ply->io_mode == PLY_READ);
+ /* look for a end of line */
+ end = strchr(BFIRST(ply), '\n');
+ /* if we didn't reach the end of the buffer, we are done */
+ if (end) {
+ ply->buffer_token = ply->buffer_first;
+ BSKIP(ply, end - BFIRST(ply));
+ *BFIRST(ply) = '\0';
+ BSKIP(ply, 1);
+ return ply_check_line(ply);
+ } else {
+ end = ply->buffer + BSIZE(ply);
+ /* otherwise, try to refill buffer */
+ if (!BREFILL(ply)) {
+ ply_ferror(ply, "Unexpected end of file");
+ return 0;
+ }
+ }
+ /* keep looking from where we left */
+ end = strchr(end, '\n');
+ /* check if the token is too large for our buffer */
+ if (!end) {
+ ply_ferror(ply, "Token too large");
+ return 0;
+ }
+ /* we are done */
+ ply->buffer_token = ply->buffer_first;
+ BSKIP(ply, end - BFIRST(ply));
+ *BFIRST(ply) = '\0';
+ BSKIP(ply, 1);
+ return ply_check_line(ply);
+}
+
+static int ply_read_chunk(p_ply ply, void *anybuffer, size_t size) {
+ char *buffer = (char *) anybuffer;
+ size_t i = 0;
+ assert(ply && ply->fp && ply->io_mode == PLY_READ);
+ assert(ply->buffer_first <= ply->buffer_last);
+ while (i < size) {
+ if (ply->buffer_first < ply->buffer_last) {
+ buffer[i] = ply->buffer[ply->buffer_first];
+ ply->buffer_first++;
+ i++;
+ } else {
+ ply->buffer_first = 0;
+ ply->buffer_last = fread(ply->buffer, 1, BUFFERSIZE, ply->fp);
+ if (ply->buffer_last <= 0) return 0;
+ }
+ }
+ return 1;
+}
+
+static int ply_write_chunk(p_ply ply, void *anybuffer, size_t size) {
+ char *buffer = (char *) anybuffer;
+ size_t i = 0;
+ assert(ply && ply->fp && ply->io_mode == PLY_WRITE);
+ assert(ply->buffer_last <= BUFFERSIZE);
+ while (i < size) {
+ if (ply->buffer_last < BUFFERSIZE) {
+ ply->buffer[ply->buffer_last] = buffer[i];
+ ply->buffer_last++;
+ i++;
+ } else {
+ ply->buffer_last = 0;
+ if (fwrite(ply->buffer, 1, BUFFERSIZE, ply->fp) < BUFFERSIZE)
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int ply_write_chunk_reverse(p_ply ply, void *anybuffer, size_t size) {
+ int ret = 0;
+ ply_reverse(anybuffer, size);
+ ret = ply_write_chunk(ply, anybuffer, size);
+ ply_reverse(anybuffer, size);
+ return ret;
+}
+
+static int ply_read_chunk_reverse(p_ply ply, void *anybuffer, size_t size) {
+ if (!ply_read_chunk(ply, anybuffer, size)) return 0;
+ ply_reverse(anybuffer, size);
+ return 1;
+}
+
+static void ply_reverse(void *anydata, size_t size) {
+ char *data = (char *) anydata;
+ char temp;
+ size_t i;
+ for (i = 0; i < size/2; i++) {
+ temp = data[i];
+ data[i] = data[size-i-1];
+ data[size-i-1] = temp;
+ }
+}
+
+static void ply_init(p_ply ply) {
+ ply->element = NULL;
+ ply->nelements = 0;
+ ply->comment = NULL;
+ ply->ncomments = 0;
+ ply->obj_info = NULL;
+ ply->nobj_infos = 0;
+ ply->idriver = NULL;
+ ply->odriver = NULL;
+ ply->buffer[0] = '\0';
+ ply->buffer_first = ply->buffer_last = ply->buffer_token = 0;
+ ply->welement = 0;
+ ply->wproperty = 0;
+ ply->winstance_index = 0;
+ ply->wlength = 0;
+ ply->wvalue_index = 0;
+}
+
+static void ply_element_init(p_ply_element element) {
+ element->name[0] = '\0';
+ element->ninstances = 0;
+ element->property = NULL;
+ element->nproperties = 0;
+}
+
+static void ply_property_init(p_ply_property property) {
+ property->name[0] = '\0';
+ property->type = PLY_INVALID_TYPE;
+ property->length_type = PLY_INVALID_TYPE;
+ property->value_type = PLY_INVALID_TYPE;
+ property->read_cb = (p_ply_read_cb) NULL;
+ property->pdata = NULL;
+ property->idata = 0;
+}
+
+static p_ply ply_alloc(void) {
+ p_ply ply = (p_ply) calloc(1, sizeof(t_ply));
+ if (!ply) return NULL;
+ ply_init(ply);
+ return ply;
+}
+
+static void *ply_grow_array(p_ply ply, void **pointer,
+ long *nmemb, long size) {
+ void *temp = *pointer;
+ long count = *nmemb + 1;
+ if (!temp) temp = malloc(count*size);
+ else temp = realloc(temp, count*size);
+ if (!temp) {
+ ply_ferror(ply, "Out of memory");
+ return NULL;
+ }
+ *pointer = temp;
+ *nmemb = count;
+ return (char *) temp + (count-1) * size;
+}
+
+static p_ply_element ply_grow_element(p_ply ply) {
+ p_ply_element element = NULL;
+ assert(ply);
+ assert(ply->element || ply->nelements == 0);
+ assert(!ply->element || ply->nelements > 0);
+ element = (p_ply_element) ply_grow_array(ply, (void **) &ply->element,
+ &ply->nelements, sizeof(t_ply_element));
+ if (!element) return NULL;
+ ply_element_init(element);
+ return element;
+}
+
+static p_ply_property ply_grow_property(p_ply ply, p_ply_element element) {
+ p_ply_property property = NULL;
+ assert(ply);
+ assert(element);
+ assert(element->property || element->nproperties == 0);
+ assert(!element->property || element->nproperties > 0);
+ property = (p_ply_property) ply_grow_array(ply,
+ (void **) &element->property,
+ &element->nproperties, sizeof(t_ply_property));
+ if (!property) return NULL;
+ ply_property_init(property);
+ return property;
+}
+
+static int ply_read_header_format(p_ply ply) {
+ assert(ply && ply->fp && ply->io_mode == PLY_READ);
+ if (strcmp(BWORD(ply), "format")) return 0;
+ if (!ply_read_word(ply)) return 0;
+ ply->storage_mode = ply_find_storage_string(BWORD(ply));
+ if (ply->storage_mode == PLY_INVALID_STORAGE) return 0;
+ if (ply->storage_mode == PLY_ASCII) ply->idriver = &ply_idriver_ascii;
+ else if (ply->storage_mode == ply_arch_endian())
+ ply->idriver = &ply_idriver_binary;
+ else ply->idriver = &ply_idriver_binary_reverse;
+ if (!ply_read_word(ply)) return 0;
+ if (strcmp(BWORD(ply), "1.0")) return 0;
+ if (!ply_read_word(ply)) return 0;
+ return 1;
+}
+
+static int ply_read_header_comment(p_ply ply) {
+ assert(ply && ply->fp && ply->io_mode == PLY_READ);
+ if (strcmp(BWORD(ply), "comment")) return 0;
+ if (!ply_read_line(ply)) return 0;
+ if (!ply_add_comment(ply, BLINE(ply))) return 0;
+ if (!ply_read_word(ply)) return 0;
+ return 1;
+}
+
+static int ply_read_header_obj_info(p_ply ply) {
+ assert(ply && ply->fp && ply->io_mode == PLY_READ);
+ if (strcmp(BWORD(ply), "obj_info")) return 0;
+ if (!ply_read_line(ply)) return 0;
+ if (!ply_add_obj_info(ply, BLINE(ply))) return 0;
+ if (!ply_read_word(ply)) return 0;
+ return 1;
+}
+
+static int ply_read_header_property(p_ply ply) {
+ p_ply_element element = NULL;
+ p_ply_property property = NULL;
+ /* make sure it is a property */
+ if (strcmp(BWORD(ply), "property")) return 0;
+ element = &ply->element[ply->nelements-1];
+ property = ply_grow_property(ply, element);
+ if (!property) return 0;
+ /* get property type */
+ if (!ply_read_word(ply)) return 0;
+ property->type = ply_find_type_string(BWORD(ply));
+ if (property->type == (e_ply_type) (-1)) return 0;
+ if (property->type == PLY_LIST) {
+ /* if it's a list, we need the base types */
+ if (!ply_read_word(ply)) return 0;
+ property->length_type = ply_find_type_string(BWORD(ply));
+ if (property->length_type == (e_ply_type) (-1)) return 0;
+ if (!ply_read_word(ply)) return 0;
+ property->value_type = ply_find_type_string(BWORD(ply));
+ if (property->value_type == (e_ply_type) (-1)) return 0;
+ }
+ /* get property name */
+ if (!ply_read_word(ply)) return 0;
+ strcpy(property->name, BWORD(ply));
+ if (!ply_read_word(ply)) return 0;
+ return 1;
+}
+
+static int ply_read_header_element(p_ply ply) {
+ p_ply_element element = NULL;
+ long dummy;
+ assert(ply && ply->fp && ply->io_mode == PLY_READ);
+ if (strcmp(BWORD(ply), "element")) return 0;
+ /* allocate room for new element */
+ element = ply_grow_element(ply);
+ if (!element) return 0;
+ /* get element name */
+ if (!ply_read_word(ply)) return 0;
+ strcpy(element->name, BWORD(ply));
+ /* get number of elements of this type */
+ if (!ply_read_word(ply)) return 0;
+ if (sscanf(BWORD(ply), "%ld", &dummy) != 1) {
+ ply_ferror(ply, "Expected number got '%s'", BWORD(ply));
+ return 0;
+ }
+ element->ninstances = dummy;
+ /* get all properties for this element */
+ if (!ply_read_word(ply)) return 0;
+ while (ply_read_header_property(ply) ||
+ ply_read_header_comment(ply) || ply_read_header_obj_info(ply))
+ /* do nothing */;
+ return 1;
+}
+
+static void ply_error_cb(p_ply ply, const char *message) {
+ (void) ply;
+ fprintf(stderr, "RPly: %s\n", message);
+}
+
+static void ply_ferror(p_ply ply, const char *fmt, ...) {
+ char buffer[1024];
+ va_list ap;
+ va_start(ap, fmt);
+ vsprintf(buffer, fmt, ap);
+ va_end(ap);
+ ply->error_cb(ply, buffer);
+}
+
+static e_ply_storage_mode ply_arch_endian(void) {
+ unsigned long i = 1;
+ unsigned char *s = (unsigned char *) &i;
+ if (*s == 1) return PLY_LITTLE_ENDIAN;
+ else return PLY_BIG_ENDIAN;
+}
+
+static int ply_type_check(void) {
+ assert(sizeof(t_ply_int8) == 1);
+ assert(sizeof(t_ply_uint8) == 1);
+ assert(sizeof(t_ply_int16) == 2);
+ assert(sizeof(t_ply_uint16) == 2);
+ assert(sizeof(t_ply_int32) == 4);
+ assert(sizeof(t_ply_uint32) == 4);
+ assert(sizeof(float) == 4);
+ assert(sizeof(double) == 8);
+ if (sizeof(t_ply_int8) != 1) return 0;
+ if (sizeof(t_ply_uint8) != 1) return 0;
+ if (sizeof(t_ply_int16) != 2) return 0;
+ if (sizeof(t_ply_uint16) != 2) return 0;
+ if (sizeof(t_ply_int32) != 4) return 0;
+ if (sizeof(t_ply_uint32) != 4) return 0;
+ if (sizeof(float) != 4) return 0;
+ if (sizeof(double) != 8) return 0;
+ return 1;
+}
+
+/* ----------------------------------------------------------------------
+ * Copyright (C) 2003-2011 Diego Nehab. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * ---------------------------------------------------------------------- */
+
+/*
+ * Local Variables:
+ * tab-width: 8
+ * mode: C
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
Copied: brlcad/trunk/src/conv/ply/rply.h (from rev 75359,
brlcad/trunk/src/other/rply/rply.h)
===================================================================
--- brlcad/trunk/src/conv/ply/rply.h (rev 0)
+++ brlcad/trunk/src/conv/ply/rply.h 2020-04-11 01:34:28 UTC (rev 75360)
@@ -0,0 +1,392 @@
+#ifndef RPLY_H
+#define RPLY_H
+/* ----------------------------------------------------------------------
+ * RPly library, read/write PLY files
+ * Diego Nehab, IMPA
+ * http://www.impa.br/~diego/software/rply
+ *
+ * This library is distributed under the MIT License. See notice
+ * at the end of this file.
+ * ---------------------------------------------------------------------- */
+
+#include "common.h"
+
+#ifndef RPLY_EXPORT
+# if defined(RPLY_DLL_EXPORTS) && defined(RPLY_DLL_IMPORTS)
+# error "Only RPLY_DLL_EXPORTS or RPLY_DLL_IMPORTS can be defined, not
both."
+# elif defined(RPLY_DLL_EXPORTS)
+# define RPLY_EXPORT __declspec(dllexport)
+# elif defined(RPLY_DLL_IMPORTS)
+# define RPLY_EXPORT __declspec(dllimport)
+# else
+# define RPLY_EXPORT
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RPLY_VERSION "RPly 1.1.3"
+#define RPLY_COPYRIGHT "Copyright (C) 2003-2013 Diego Nehab"
+#define RPLY_AUTHORS "Diego Nehab"
+
+/* ----------------------------------------------------------------------
+ * Types
+ * ---------------------------------------------------------------------- */
+/* structures are opaque */
+typedef struct t_ply_ *p_ply;
+typedef struct t_ply_element_ *p_ply_element;
+typedef struct t_ply_property_ *p_ply_property;
+typedef struct t_ply_argument_ *p_ply_argument;
+
+/* ply format mode type */
+typedef enum e_ply_storage_mode_ {
+ PLY_INVALID_STORAGE,
+ PLY_BIG_ENDIAN,
+ PLY_LITTLE_ENDIAN,
+ PLY_ASCII,
+ PLY_DEFAULT /* has to be the last in enum */
+} e_ply_storage_mode; /* order matches ply_storage_mode_list */
+
+/* ply data type */
+typedef enum e_ply_type {
+ PLY_INVALID_TYPE,
+ PLY_INT8, PLY_UINT8, PLY_INT16, PLY_UINT16,
+ PLY_INT32, PLY_UIN32, PLY_FLOAT32, PLY_FLOAT64,
+ PLY_CHAR, PLY_UCHAR, PLY_SHORT, PLY_USHORT,
+ PLY_INT, PLY_UINT, PLY_FLOAT, PLY_DOUBLE,
+ PLY_LIST /* has to be the last in enum */
+} e_ply_type; /* order matches ply_type_list */
+
+/* ----------------------------------------------------------------------
+ * Error callback prototype
+ *
+ * message: error message
+ * ply: handle returned by ply_open or ply_create
+ * ---------------------------------------------------------------------- */
+typedef void (*p_ply_error_cb)(p_ply ply, const char *message);
+
+/* ----------------------------------------------------------------------
+ * Gets user data from within an error callback
+ *
+ * ply: handle returned by ply_open or ply_create
+ * idata,pdata: contextual information set in ply_open or ply_create
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_get_ply_user_data(p_ply ply, void **pdata, long *idata);
+
+/* ----------------------------------------------------------------------
+ * Opens a PLY file for reading (fails if file is not a PLY file)
+ *
+ * name: file name
+ * error_cb: error callback function
+ * idata,pdata: contextual information available to users
+ *
+ * Returns 1 if successful, 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT p_ply ply_open(const char *name, p_ply_error_cb error_cb, long
idata,
+ void *pdata);
+
+/* ----------------------------------------------------------------------
+ * Reads and parses the header of a PLY file returned by ply_open
+ *
+ * ply: handle returned by ply_open
+ *
+ * Returns 1 if successfull, 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_read_header(p_ply ply);
+
+/* ----------------------------------------------------------------------
+ * Property reading callback prototype
+ *
+ * argument: parameters for property being processed when callback is called
+ *
+ * Returns 1 if should continue processing file, 0 if should abort.
+ * ---------------------------------------------------------------------- */
+typedef int (*p_ply_read_cb)(p_ply_argument argument);
+
+/* ----------------------------------------------------------------------
+ * Sets up callbacks for property reading after header was parsed
+ *
+ * ply: handle returned by ply_open
+ * element_name: element where property is
+ * property_name: property to associate element with
+ * read_cb: function to be called for each property value
+ * pdata/idata: user data that will be passed to callback
+ *
+ * Returns 0 if no element or no property in element, returns the
+ * number of element instances otherwise.
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT long ply_set_read_cb(p_ply ply, const char *element_name,
+ const char *property_name, p_ply_read_cb read_cb,
+ void *pdata, long idata);
+
+/* ----------------------------------------------------------------------
+ * Returns information about the element originating a callback
+ *
+ * argument: handle to argument
+ * element: receives a the element handle (if non-null)
+ * instance_index: receives the index of the current element instance
+ * (if non-null)
+ *
+ * Returns 1 if successfull, 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_get_argument_element(p_ply_argument argument,
+ p_ply_element *element, long *instance_index);
+
+/* ----------------------------------------------------------------------
+ * Returns information about the property originating a callback
+ *
+ * argument: handle to argument
+ * property: receives the property handle (if non-null)
+ * length: receives the number of values in this property (if non-null)
+ * value_index: receives the index of current property value (if non-null)
+ *
+ * Returns 1 if successfull, 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_get_argument_property(p_ply_argument argument,
+ p_ply_property *property, long *length, long *value_index);
+
+/* ----------------------------------------------------------------------
+ * Returns user data associated with callback
+ *
+ * pdata: receives a copy of user custom data pointer (if non-null)
+ * idata: receives a copy of user custom data integer (if non-null)
+ *
+ * Returns 1 if successfull, 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_get_argument_user_data(p_ply_argument argument, void
**pdata,
+ long *idata);
+
+/* ----------------------------------------------------------------------
+ * Returns the value associated with a callback
+ *
+ * argument: handle to argument
+ *
+ * Returns the current data item
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT double ply_get_argument_value(p_ply_argument argument);
+
+/* ----------------------------------------------------------------------
+ * Reads all elements and properties calling the callbacks defined with
+ * calls to ply_set_read_cb
+ *
+ * ply: handle returned by ply_open
+ *
+ * Returns 1 if successfull, 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_read(p_ply ply);
+
+/* ----------------------------------------------------------------------
+ * Iterates over all elements by returning the next element.
+ * Call with NULL to return handle to first element.
+ *
+ * ply: handle returned by ply_open
+ * last: handle of last element returned (NULL for first element)
+ *
+ * Returns element if successfull or NULL if no more elements
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT p_ply_element ply_get_next_element(p_ply ply, p_ply_element last);
+
+/* ----------------------------------------------------------------------
+ * Iterates over all comments by returning the next comment.
+ * Call with NULL to return pointer to first comment.
+ *
+ * ply: handle returned by ply_open
+ * last: pointer to last comment returned (NULL for first comment)
+ *
+ * Returns comment if successfull or NULL if no more comments
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT const char *ply_get_next_comment(p_ply ply, const char *last);
+
+/* ----------------------------------------------------------------------
+ * Iterates over all obj_infos by returning the next obj_info.
+ * Call with NULL to return pointer to first obj_info.
+ *
+ * ply: handle returned by ply_open
+ * last: pointer to last obj_info returned (NULL for first obj_info)
+ *
+ * Returns obj_info if successfull or NULL if no more obj_infos
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT const char *ply_get_next_obj_info(p_ply ply, const char *last);
+
+/* ----------------------------------------------------------------------
+ * Returns information about an element
+ *
+ * element: element of interest
+ * name: receives a pointer to internal copy of element name (if non-null)
+ * ninstances: receives the number of instances of this element (if non-null)
+ *
+ * Returns 1 if successfull or 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_get_element_info(p_ply_element element, const char** name,
+ long *ninstances);
+
+/* ----------------------------------------------------------------------
+ * Iterates over all properties by returning the next property.
+ * Call with NULL to return handle to first property.
+ *
+ * element: handle of element with the properties of interest
+ * last: handle of last property returned (NULL for first property)
+ *
+ * Returns element if successfull or NULL if no more properties
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT p_ply_property ply_get_next_property(p_ply_element element,
+ p_ply_property last);
+
+/* ----------------------------------------------------------------------
+ * Returns information about a property
+ *
+ * property: handle to property of interest
+ * name: receives a pointer to internal copy of property name (if non-null)
+ * type: receives the property type (if non-null)
+ * length_type: for list properties, receives the scalar type of
+ * the length field (if non-null)
+ * value_type: for list properties, receives the scalar type of the value
+ * fields (if non-null)
+ *
+ * Returns 1 if successfull or 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_get_property_info(p_ply_property property, const char**
name,
+ e_ply_type *type, e_ply_type *length_type, e_ply_type *value_type);
+
+/* ----------------------------------------------------------------------
+ * Creates new PLY file
+ *
+ * name: file name
+ * storage_mode: file format mode
+ *
+ * Returns handle to PLY file if successfull, NULL otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT p_ply ply_create(const char *name, e_ply_storage_mode
storage_mode,
+ p_ply_error_cb error_cb, long idata, void *pdata);
+
+/* ----------------------------------------------------------------------
+ * Adds a new element to the PLY file created by ply_create
+ *
+ * ply: handle returned by ply_create
+ * name: name of new element
+ * ninstances: number of element of this time in file
+ *
+ * Returns 1 if successfull, 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_add_element(p_ply ply, const char *name, long ninstances);
+
+/* ----------------------------------------------------------------------
+ * Adds a new property to the last element added by ply_add_element
+ *
+ * ply: handle returned by ply_create
+ * name: name of new property
+ * type: property type
+ * length_type: scalar type of length field of a list property
+ * value_type: scalar type of value fields of a list property
+ *
+ * Returns 1 if successfull, 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_add_property(p_ply ply, const char *name, e_ply_type type,
+ e_ply_type length_type, e_ply_type value_type);
+
+/* ----------------------------------------------------------------------
+ * Adds a new list property to the last element added by ply_add_element
+ *
+ * ply: handle returned by ply_create
+ * name: name of new property
+ * length_type: scalar type of length field of a list property
+ * value_type: scalar type of value fields of a list property
+ *
+ * Returns 1 if successfull, 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_add_list_property(p_ply ply, const char *name,
+ e_ply_type length_type, e_ply_type value_type);
+
+/* ----------------------------------------------------------------------
+ * Adds a new property to the last element added by ply_add_element
+ *
+ * ply: handle returned by ply_create
+ * name: name of new property
+ * type: property type
+ *
+ * Returns 1 if successfull, 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_add_scalar_property(p_ply ply, const char *name,
e_ply_type type);
+
+/* ----------------------------------------------------------------------
+ * Adds a new comment item
+ *
+ * ply: handle returned by ply_create
+ * comment: pointer to string with comment text
+ *
+ * Returns 1 if successfull, 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_add_comment(p_ply ply, const char *comment);
+
+/* ----------------------------------------------------------------------
+ * Adds a new obj_info item
+ *
+ * ply: handle returned by ply_create
+ * comment: pointer to string with obj_info data
+ *
+ * Returns 1 if successfull, 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_add_obj_info(p_ply ply, const char *obj_info);
+
+/* ----------------------------------------------------------------------
+ * Writes the PLY file header after all element and properties have been
+ * defined by calls to ply_add_element and ply_add_property
+ *
+ * ply: handle returned by ply_create
+ *
+ * Returns 1 if successfull, 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_write_header(p_ply ply);
+
+/* ----------------------------------------------------------------------
+ * Writes one property value, in the order they should be written to the
+ * file. For each element type, write all elements of that type in order.
+ * For each element, write all its properties in order. For scalar
+ * properties, just write the value. For list properties, write the length
+ * and then each of the values.
+ *
+ * ply: handle returned by ply_create
+ *
+ * Returns 1 if successfull, 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_write(p_ply ply, double value);
+
+/* ----------------------------------------------------------------------
+ * Closes a PLY file handle. Releases all memory used by handle
+ *
+ * ply: handle to be closed.
+ *
+ * Returns 1 if successfull, 0 otherwise
+ * ---------------------------------------------------------------------- */
+RPLY_EXPORT int ply_close(p_ply ply);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RPLY_H */
+
+/* ----------------------------------------------------------------------
+ * Copyright (C) 2003-2011 Diego Nehab. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * ---------------------------------------------------------------------- */
Copied: brlcad/trunk/src/conv/ply/rply_license.txt (from rev 75359,
brlcad/trunk/src/other/rply/LICENSE)
===================================================================
--- brlcad/trunk/src/conv/ply/rply_license.txt (rev 0)
+++ brlcad/trunk/src/conv/ply/rply_license.txt 2020-04-11 01:34:28 UTC (rev
75360)
@@ -0,0 +1,20 @@
+RPly 1.1.3 license
+Copyright \xA9 2003-2013 Diego Nehab.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
Modified: brlcad/trunk/src/other/CMakeLists.txt
===================================================================
--- brlcad/trunk/src/other/CMakeLists.txt 2020-04-11 01:27:08 UTC (rev
75359)
+++ brlcad/trunk/src/other/CMakeLists.txt 2020-04-11 01:34:28 UTC (rev
75360)
@@ -921,18 +921,6 @@
mark_as_advanced(P2T_STATIC)
mark_as_advanced(P2T_TESTS)
-# RPLY I/O library
-add_subdirectory(rply)
-include("${CMAKE_CURRENT_SOURCE_DIR}/rply.dist")
-CMAKEFILES_IN_DIR(rply_ignore_files rply)
-DISTCLEAN("${CMAKE_CURRENT_SOURCE_DIR}/rply/Makefile")
-set(RPLY_LIBRARIES "rply" CACHE STRING "RPLY library" FORCE)
-set(RPLY_INCLUDE_DIRS "${BRLCAD_SOURCE_DIR}/src/other/rply" CACHE STRING
"Directory containing rply header" FORCE)
-SetTargetFolder(rply "Third Party Libraries")
-SetTargetFolder(rply-static "Third Party Libraries")
-mark_as_advanced(RPLY_LIBRARIES)
-mark_as_advanced(RPLY_INCLUDE_DIRS)
-
# PROJ.4 library - used by GDAL
set(proj4_DESCRIPTION "
Option for enabling and disabling compilation of the PROJ.4 geographic
Deleted: brlcad/trunk/src/other/rply.dist
===================================================================
--- brlcad/trunk/src/other/rply.dist 2020-04-11 01:27:08 UTC (rev 75359)
+++ brlcad/trunk/src/other/rply.dist 2020-04-11 01:34:28 UTC (rev 75360)
@@ -1,6 +0,0 @@
-set(rply_ignore_files
-CMakeLists.txt
-LICENSE
-rply.c
-rply.h
-)
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits