24 #if defined(_MSC_VER) && (_MSC_VER < 1600) 32 #define PLY_INT8_MAX (127) 33 #define PLY_INT8_MIN (-PLY_INT8_MAX-1) 34 #define PLY_INT16_MAX (32767) 35 #define PLY_INT16_MIN (-PLY_INT16_MAX-1) 36 #define PLY_INT32_MAX (2147483647) 37 #define PLY_INT32_MIN (-PLY_INT32_MAX-1) 38 #define PLY_UINT8_MAX (255) 39 #define PLY_UINT16_MAX (65535) 40 #define PLY_UINT32_MAX (4294967295) 49 #define PLY_INT8_MIN INT8_MIN 50 #define PLY_INT8_MAX INT8_MAX 51 #define PLY_INT16_MIN INT16_MIN 52 #define PLY_INT16_MAX INT16_MAX 53 #define PLY_INT32_MIN INT32_MIN 54 #define PLY_INT32_MAX INT32_MAX 55 #define PLY_UINT8_MAX UINT8_MAX 56 #define PLY_UINT16_MAX UINT16_MAX 57 #define PLY_UINT32_MAX UINT32_MAX 65 #define BUFFERSIZE (8*1024) 73 "binary_big_endian",
"binary_little_endian",
"ascii",
NULL 77 "int8",
"uint8",
"int16",
"uint16",
78 "int32",
"uint32",
"float32",
"float64",
79 "char",
"uchar",
"short",
"ushort",
80 "int",
"uint",
"float",
"double",
235 static void ply_reverse(
void *anydata,
size_t size);
240 static int ply_find_string(
const char *item,
const char*
const list[]);
294 #define BWORD(p) (p->buffer + p->buffer_token) 295 #define BLINE(p) (p->buffer + p->buffer_token) 298 #define BFIRST(p) (p->buffer + p->buffer_first) 301 #define BSIZE(p) (p->buffer_last - p->buffer_first) 304 #define BSKIP(p, s) (p->buffer_first += s) 309 size_t size =
BSIZE(ply);
318 if (size <= 0)
return 0;
331 char *magic = ply->
buffer;
333 ply->
error_cb(ply,
"Unable to read magic number from file");
337 if (magic[0] !=
'p' || magic[1] !=
'l' || magic[2] !=
'y' 338 || !isspace(magic[3])) {
339 ply->
error_cb(ply,
"Wrong magic number. Expected 'ply'");
344 ply->
rn = magic[3] ==
'\r' && magic[4] ==
'\n';
361 error_cb(
NULL,
"Out of memory");
369 error_cb(ply,
"Incompatible type system");
374 fp = fopen(name,
"rb");
376 error_cb(ply,
"Unable to open file");
394 while (strcmp(
BWORD(ply),
"end_header")) {
418 assert(ply && element_name && property_name);
420 if (!element)
return 0;
423 property->read_cb = read_cb;
424 property->pdata =
pdata;
425 property->idata =
idata;
453 error_cb(
NULL,
"Out of memory");
457 error_cb(ply,
"Incompatible type system");
462 fp = fopen(name,
"wb");
464 error_cb(ply,
"Unable to create file");
485 assert(name && strlen(name) <
WORDSIZE && ninstances >= 0);
486 if (strlen(name) >=
WORDSIZE || ninstances < 0) {
491 if (!element)
return 0;
492 strcpy(element->
name, name);
501 assert(name && strlen(name) <
WORDSIZE);
511 property->type = type;
520 assert(name && strlen(name) <
WORDSIZE);
536 property->length_type = length_type;
537 property->value_type = value_type;
550 char *new_comment =
NULL;
551 assert(ply && comment && strlen(comment) <
LINESIZE);
552 if (!comment || strlen(comment) >=
LINESIZE) {
558 if (!new_comment)
return 0;
559 strcpy(new_comment, comment);
564 char *new_obj_info =
NULL;
565 assert(ply && obj_info && strlen(obj_info) <
LINESIZE);
566 if (!obj_info || strlen(obj_info) >=
LINESIZE) {
572 if (!new_obj_info)
return 0;
573 strcpy(new_obj_info, obj_info);
582 if (fprintf(ply->
fp,
"ply\nformat %s 1.0\n",
594 if (fprintf(ply->
fp,
"element %s %ld\n", element->
name,
599 if (fprintf(ply->
fp,
"property list %s %s %s\n",
604 if (fprintf(ply->
fp,
"property %s %s\n",
610 return fprintf(ply->
fp,
"end_header\n") > 0;
629 }
else type =
property->value_type;
631 type =
property->type;
635 ply_ferror(ply,
"Failed writing %s of %s %d (%s: %s)",
655 return !breakafter || putc(
'\n', ply->
fp) > 0;
660 assert(ply && ply->
fp);
690 if (!last)
return ply->
element;
699 if (name) *name = element->
name;
700 if (ninstances) *ninstances = (long) element->
ninstances;
707 if (!last)
return element->
property;
716 if (name) *name =
property->name;
717 if (type) *type =
property->type;
718 if (length_type) *length_type =
property->length_type;
719 if (value_type) *value_type =
property->value_type;
726 if (!last)
return ply->
comment;
746 if (!argument)
return 0;
747 if (element) *element = argument->
element;
755 if (!argument)
return 0;
756 if (property) *
property = argument->
property;
757 if (length) *length = argument->
length;
758 if (value_index) *value_index = argument->
value_index;
765 if (!argument)
return 0;
766 if (pdata) *pdata = argument->
pdata;
767 if (idata) *idata = argument->
idata;
773 if (!argument)
return 0.0;
774 return argument->
value;
780 if (pdata) *pdata = ply->
pdata;
781 if (idata) *idata = ply->
idata;
796 if (!handler(ply, &length)) {
797 ply_ferror(ply,
"Error reading '%s' of '%s' number %d",
802 argument->
length = (long) length;
805 if (read_cb && !read_cb(argument)) {
810 handler = driver[
property->value_type];
812 for (l = 0; l < (long) length; l++) {
815 if (!handler(ply, &argument->
value)) {
816 ply_ferror(ply,
"Error reading value number %d of '%s' of " 817 "'%s' number %d", l+1, property->
name,
822 if (read_cb && !read_cb(argument)) {
837 if (!handler(ply, &argument->
value)) {
838 ply_ferror(ply,
"Error reading '%s' of '%s' number %d",
842 if (read_cb && !read_cb(argument)) {
867 argument->
pdata =
property->pdata;
868 argument->
idata =
property->idata;
878 assert(item && list);
879 for (i = 0; list[i]; i++)
880 if (!strcmp(list[i], item))
return i;
890 assert(element || nelements == 0);
891 assert(!element || nelements > 0);
892 for (i = 0; i < nelements; i++)
893 if (!strcmp(element[i].name, name))
return &element[i];
901 assert(element && name);
904 assert(property || nproperties == 0);
905 assert(!property || nproperties > 0);
906 for (i = 0; i < nproperties; i++)
907 if (!strcmp(property[i].name, name))
return &
property[i];
912 size_t size = strlen(
BWORD(ply));
916 }
else if (size == 0) {
928 t = strspn(
BFIRST(ply),
" \n\r\t");
930 if (t >=
BSIZE(ply)) {
939 t = strcspn(
BFIRST(ply),
" \n\r\t");
941 if (t <
BSIZE(ply)) {
954 t += strcspn(
BFIRST(ply) + t,
" \n\r\t");
956 if (t >=
BSIZE(ply)) {
981 const char *end =
NULL;
984 end = strchr(
BFIRST(ply),
'\n');
1001 end = strchr(end,
'\n');
1016 char *buffer = (
char *) anybuffer;
1035 char *buffer = (
char *) anybuffer;
1068 char *data = (
char *) anydata;
1071 for (i = 0; i < size/2; i++) {
1073 data[i] = data[size-i-1];
1074 data[size-i-1] = temp;
1097 element->
name[0] =
'\0';
1104 property->name[0] =
'\0';
1105 property->type = -1;
1106 property->length_type = -1;
1107 property->value_type = -1;
1109 property->pdata =
NULL;
1110 property->idata = 0;
1115 if (!ply)
return NULL;
1121 long *nmemb,
long size) {
1122 void *temp = *pointer;
1123 long count = *nmemb + 1;
1124 if (!temp) temp = malloc(count*size);
1125 else temp = realloc(temp, count*size);
1132 return (
char *) temp + (count-1) * size;
1142 if (!element)
return NULL;
1163 if (strcmp(
BWORD(ply),
"format"))
return 0;
1172 if (strcmp(
BWORD(ply),
"1.0"))
return 0;
1179 if (strcmp(
BWORD(ply),
"comment"))
return 0;
1188 if (strcmp(
BWORD(ply),
"obj_info"))
return 0;
1199 if (strcmp(
BWORD(ply),
"property"))
return 0;
1227 if (strcmp(
BWORD(ply),
"element"))
return 0;
1230 if (!element)
return 0;
1236 if (sscanf(
BWORD(ply),
"%ld", &dummy) != 1) {
1251 fprintf(stderr,
"RPly: %s\n", message);
1258 vsprintf(buffer, fmt, ap);
1264 unsigned long i = 1;
1265 unsigned char *s = (
unsigned char *) &i;
1277 assert(
sizeof(
float) == 4);
1278 assert(
sizeof(
double) == 8);
1285 if (
sizeof(
float) != 4)
return 0;
1286 if (
sizeof(
double) != 8)
return 0;
1295 return fprintf(ply->
fp,
"%d ", (
t_ply_int8) value) > 0;
1324 if (value < -FLT_MAX || value > FLT_MAX)
return 0;
1325 return fprintf(ply->
fp,
"%g ", (
float) value) > 0;
1329 if (value < -DBL_MAX || value > DBL_MAX)
return 0;
1330 return fprintf(ply->
fp,
"%g ", value) > 0;
1370 float float32 = (float) value;
1371 if (value > FLT_MAX || value < -FLT_MAX)
return 0;
1372 return ply->
odriver->
ochunk(ply, &float32,
sizeof(float32));
1385 *value = strtol(
BWORD(ply), &end, 10);
1393 *value = strtol(
BWORD(ply), &end, 10);
1401 *value = strtol(
BWORD(ply), &end, 10);
1409 *value = strtol(
BWORD(ply), &end, 10);
1417 *value = strtol(
BWORD(ply), &end, 10);
1425 *value = strtol(
BWORD(ply), &end, 10);
1433 *value = strtod(
BWORD(ply), &end);
1434 if (*end || *value < -FLT_MAX || *value > FLT_MAX)
return 0;
1441 *value = strtod(
BWORD(ply), &end);
1442 if (*end || *value < -DBL_MAX || *value > DBL_MAX)
return 0;
1462 if (!ply->
idriver->
ichunk(ply, &int16,
sizeof(int16)))
return 0;
1469 if (!ply->
idriver->
ichunk(ply, &uint16,
sizeof(uint16)))
return 0;
1476 if (!ply->
idriver->
ichunk(ply, &int32,
sizeof(int32)))
return 0;
1483 if (!ply->
idriver->
ichunk(ply, &uint32,
sizeof(uint32)))
return 0;
1490 if (!ply->
idriver->
ichunk(ply, &float32,
sizeof(float32)))
return 0;
1529 "reverse binary input" 1559 "reverse binary output"
static int obinary_uint8(p_ply ply, double value)
int ply_add_scalar_property(p_ply ply, const char *name, e_ply_type type)
static int iascii_float64(p_ply ply, double *value)
static const char *const ply_type_list[]
static int ibinary_int8(p_ply ply, double *value)
int ply_add_comment(p_ply ply, const char *comment)
int(* p_ply_ihandler)(p_ply ply, double *value)
struct t_ply_property_ * p_ply_property
static int ply_check_line(p_ply ply)
int ply_get_argument_user_data(p_ply_argument argument, void **pdata, long *idata)
static p_ply_element ply_grow_element(p_ply ply)
int(* p_ply_ochunk)(p_ply ply, void *anydata, size_t size)
static void ply_ferror(p_ply ply, const char *fmt,...)
static int ply_read_header_comment(p_ply ply)
int ply_get_ply_user_data(p_ply ply, void **pdata, long *idata)
static int obinary_float64(p_ply ply, double value)
static int oascii_uint32(p_ply ply, double value)
double ply_get_argument_value(p_ply_argument argument)
static int ply_read_element(p_ply ply, p_ply_element element, p_ply_argument argument)
static int ply_read_line(p_ply ply)
static int ply_write_chunk_reverse(p_ply ply, void *anybuffer, size_t size)
static p_ply_property ply_find_property(p_ply_element element, const char *name)
static int ibinary_int32(p_ply ply, double *value)
static t_ply_odriver ply_odriver_ascii
static int ply_read_header_magic(p_ply ply)
static int ply_read_header_obj_info(p_ply ply)
const char * ply_get_next_comment(p_ply ply, const char *last)
const char * ply_get_next_obj_info(p_ply ply, const char *last)
int ply_add_property(p_ply ply, const char *name, e_ply_type type, e_ply_type length_type, e_ply_type value_type)
static int ibinary_uint16(p_ply ply, double *value)
static void * ply_grow_array(p_ply ply, void **pointer, long *nmemb, long size)
static int oascii_int8(p_ply ply, double value)
static int ibinary_int16(p_ply ply, double *value)
static int ibinary_uint8(p_ply ply, double *value)
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)
static void ply_error_cb(p_ply ply, const char *message)
static int obinary_int16(p_ply ply, double value)
int ply_add_obj_info(p_ply ply, const char *obj_info)
static int ply_read_word(p_ply ply)
int ply_write_header(p_ply ply)
static t_ply_odriver ply_odriver_binary
static t_ply_idriver ply_idriver_binary_reverse
enum e_ply_storage_mode_ e_ply_storage_mode
static e_ply_storage_mode ply_arch_endian(void)
static int ply_read_property(p_ply ply, p_ply_element element, p_ply_property property, p_ply_argument argument)
static int iascii_float32(p_ply ply, double *value)
p_ply_property ply_get_next_property(p_ply_element element, p_ply_property last)
static int iascii_uint8(p_ply ply, double *value)
static int obinary_int32(p_ply ply, double value)
static int obinary_int8(p_ply ply, double value)
static int ply_read_header_property(p_ply ply)
static int iascii_int32(p_ply ply, double *value)
static int oascii_uint8(p_ply ply, double value)
int(* p_ply_read_cb)(p_ply_argument argument)
void(* p_ply_error_cb)(p_ply ply, const char *message)
static int BREFILL(p_ply ply)
static int ibinary_uint32(p_ply ply, double *value)
p_ply ply_create(const char *name, e_ply_storage_mode storage_mode, p_ply_error_cb error_cb, long idata, void *pdata)
static int ply_write_chunk(p_ply ply, void *anybuffer, size_t size)
static void ply_element_init(p_ply_element element)
static int ply_read_header_element(p_ply ply)
static int oascii_int16(p_ply ply, double value)
static int iascii_int8(p_ply ply, double *value)
static void ply_property_init(p_ply_property property)
static p_ply ply_alloc(void)
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)
struct t_ply_property_ t_ply_property
static int oascii_float32(p_ply ply, double value)
p_ply_ohandler ohandler[16]
static int ibinary_float64(p_ply ply, double *value)
int ply_add_element(p_ply ply, const char *name, long ninstances)
static int iascii_uint16(p_ply ply, double *value)
static int ply_read_list_property(p_ply ply, p_ply_element element, p_ply_property property, p_ply_argument argument)
static int oascii_int32(p_ply ply, double value)
static int ply_read_scalar_property(p_ply ply, p_ply_element element, p_ply_property property, p_ply_argument argument)
static int obinary_uint16(p_ply ply, double value)
static int oascii_float64(p_ply ply, double value)
struct t_ply_element_ * p_ply_element
int(* p_ply_ichunk)(p_ply ply, void *anydata, size_t size)
struct t_ply_odriver_ t_ply_odriver
static int oascii_uint16(p_ply ply, double value)
p_ply_ihandler ihandler[16]
e_ply_storage_mode storage_mode
static t_ply_idriver ply_idriver_binary
p_ply_element ply_get_next_element(p_ply ply, p_ply_element last)
int ply_get_argument_property(p_ply_argument argument, p_ply_property *property, long *length, long *value_index)
int(* p_ply_ohandler)(p_ply ply, double value)
static int iascii_uint32(p_ply ply, double *value)
static t_ply_odriver ply_odriver_binary_reverse
KF_EXPORTS void error(const char *error_string, const char *file, const int line, const char *func="")
Error handler. All GPU functions from this subsystem call the function to report an error...
static int iascii_int16(p_ply ply, double *value)
int ply_get_element_info(p_ply_element element, const char **name, long *ninstances)
static int obinary_uint32(p_ply ply, double value)
enum e_ply_io_mode_ e_ply_io_mode
static int ply_find_string(const char *item, const char *const list[])
static void ply_finish_word(p_ply ply, size_t size)
int ply_add_list_property(p_ply ply, const char *name, e_ply_type length_type, e_ply_type value_type)
t_ply_odriver * p_ply_odriver
struct t_ply_argument_ t_ply_argument
static int ply_read_header_format(p_ply ply)
static void ply_reverse(void *anydata, size_t size)
p_ply ply_open(const char *name, p_ply_error_cb error_cb, long idata, void *pdata)
static p_ply_element ply_find_element(p_ply ply, const char *name)
static int ply_check_word(p_ply ply)
struct t_ply_element_ t_ply_element
static void ply_init(p_ply ply)
static int ibinary_float32(p_ply ply, double *value)
static int ply_read_chunk(p_ply ply, void *anybuffer, size_t size)
t_ply_idriver * p_ply_idriver
static int obinary_float32(p_ply ply, double value)
static const char *const ply_storage_mode_list[]
int ply_read_header(p_ply ply)
int ply_get_argument_element(p_ply_argument argument, p_ply_element *element, long *instance_index)
static int ply_type_check(void)
static int ply_read_chunk_reverse(p_ply ply, void *anybuffer, size_t size)
static t_ply_idriver ply_idriver_ascii
static p_ply_property ply_grow_property(p_ply ply, p_ply_element element)
struct t_ply_idriver_ t_ply_idriver
int ply_write(p_ply ply, double value)