00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "ply.h"
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <math.h>
00045 #include <string.h>
00046
00047 const char *type_names[] = {
00048 "invalid",
00049 "char", "short", "int",
00050 "uchar", "ushort", "uint",
00051 "float", "double", "float32", "uint8", "int32"
00052 };
00053
00054 int ply_type_size[] = {
00055 0, 1, 2, 4, 1, 2, 4, 4, 8, 4, 1, 4
00056 };
00057
00058 #define NO_OTHER_PROPS -1
00059
00060 #define DONT_STORE_PROP 0
00061 #define STORE_PROP 1
00062
00063 #define OTHER_PROP 0
00064 #define NAMED_PROP 1
00065
00066
00067
00068 int equal_strings(const char *, const char *);
00069
00070
00071 PlyElement *find_element(PlyFile *, const char *);
00072
00073
00074 PlyProperty *find_property(PlyElement *, const char *, int *);
00075
00076
00077 void write_scalar_type (FILE *, int);
00078
00079
00080 char **get_words(FILE *, int *, char **);
00081
00082
00083 void write_binary_item(PlyFile *, int, unsigned int, double, int);
00084 void write_ascii_item(FILE *, int, unsigned int, double, int);
00085
00086
00087 void add_element(PlyFile *, char **, int);
00088 void add_property(PlyFile *, char **, int);
00089 void add_comment(PlyFile *, char *);
00090 void add_obj_info(PlyFile *, char *);
00091
00092
00093 void copy_property(PlyProperty *, PlyProperty *);
00094
00095
00096 void store_item(char *, int, int, unsigned int, double);
00097
00098
00099 void get_stored_item( void *, int, int *, unsigned int *, double *);
00100
00101
00102 double get_item_value(char *, int);
00103
00104
00105 void get_ascii_item(char *, int, int *, unsigned int *, double *);
00106 void get_binary_item(PlyFile *, int, int *, unsigned int *, double *);
00107
00108
00109 void ascii_get_element(PlyFile *, char *);
00110 void binary_get_element(PlyFile *, char *);
00111
00112
00113 char *my_alloc(int, int, const char *);
00114
00115
00116
00117
00118
00119 void swap2Bytes( void* ptr )
00120 {
00121 unsigned char* bytes = (unsigned char*)ptr;
00122 unsigned short* result = (unsigned short*)ptr;
00123
00124 *result = (bytes[0]<<8) | bytes[1];
00125 }
00126
00127 void swap4Bytes( void* ptr )
00128 {
00129 unsigned char* bytes = (unsigned char*)ptr;
00130 unsigned int* result = (unsigned int*)ptr;
00131
00132 *result = (bytes[0]<<24) | (bytes[1]<<16) | (bytes[2]<<8) | bytes[3];
00133 }
00134
00135 void swap8Bytes( void* ptr )
00136 {
00137 unsigned char* bytes = (unsigned char*)ptr;
00138 unsigned long long* result = (unsigned long long*)ptr;
00139
00140 *result = ((unsigned long long)(bytes[0])) << 56 |
00141 ((unsigned long long)(bytes[1])) << 48 |
00142 ((unsigned long long)(bytes[2])) << 40 |
00143 ((unsigned long long)(bytes[3])) << 32 |
00144 ((unsigned long long)(bytes[4])) << 24 |
00145 ((unsigned long long)(bytes[5])) << 16 |
00146 ((unsigned long long)(bytes[6])) << 8 |
00147 bytes[7];
00148
00149
00150 }
00151
00152 #ifdef LITTLE_ENDIAN
00153 void swap2LE( void* ) {}
00154 void swap2LE( short* ) {}
00155 void swap2LE( unsigned short* ) {}
00156 void swap4LE( void* ) {}
00157 void swap4LE( int* ) {}
00158 void swap4LE( unsigned int* ) {}
00159 void swap4LE( float* ) {}
00160 void swap8LE( void* ) {}
00161 void swap8LE( long long* ) {}
00162 void swap8LE( unsigned long long* ) {}
00163 void swap8LE( double* ) {}
00164
00165 void swap2BE( void* ptr ) { swap2Bytes(ptr); }
00166 void swap2BE( short* ptr ) { swap2Bytes(ptr); }
00167 void swap2BE( unsigned short* ptr ) { swap2Bytes(ptr); }
00168 void swap4BE( void* ptr ) { swap4Bytes(ptr); }
00169 void swap4BE( int* ptr ) { swap4Bytes(ptr); }
00170 void swap4BE( unsigned int* ptr ) { swap4Bytes(ptr); }
00171 void swap4BE( float* ptr ) { swap4Bytes(ptr); }
00172 void swap8BE( long long* ptr ) { swap8Bytes(ptr); }
00173 void swap8BE( void* ptr ) { swap8Bytes(ptr); }
00174 void swap8BE( unsigned long long* ptr ) { swap8Bytes(ptr); }
00175 void swap8BE( double* ptr ) { swap8Bytes(ptr); }
00176
00177 #else // LITTLE_ENDIAN
00178
00179 void swap2LE( void* ptr ) { swap2Bytes(ptr); }
00180 void swap2LE( short* ptr ) { swap2Bytes(ptr); }
00181 void swap2LE( unsigned short* ptr ) { swap2Bytes(ptr); }
00182 void swap4LE( void* ptr ) { swap4Bytes(ptr); }
00183 void swap4LE( int* ptr ) { swap4Bytes(ptr); }
00184 void swap4LE( unsigned int* ptr ) { swap4Bytes(ptr); }
00185 void swap4LE( float* ptr ) { swap4Bytes(ptr); }
00186 void swap8LE( long long* ptr ) { swap8Bytes(ptr); }
00187 void swap8LE( void* ptr ) { swap8Bytes(ptr); }
00188 void swap8LE( unsigned long long* ptr ) { swap8Bytes(ptr); }
00189 void swap8LE( double* ptr ) { swap8Bytes(ptr); }
00190
00191 void swap2BE( void* ) {}
00192 void swap2BE( short* ) {}
00193 void swap2BE( unsigned short* ) {}
00194 void swap4BE( void* ) {}
00195 void swap4BE( int* ) {}
00196 void swap4BE( unsigned int* ) {}
00197 void swap4BE( float* ) {}
00198 void swap8BE( void* ) {}
00199 void swap8BE( long long* ) {}
00200 void swap8BE( unsigned long long* ) {}
00201 void swap8BE( double* ) {}
00202
00203 #endif // LITTLE_ENDIAN
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 PlyFile *ply_write(
00225 FILE *fp,
00226 int nelems,
00227 const char **elem_names,
00228 int file_type
00229 )
00230 {
00231 int i;
00232 PlyFile *plyfile;
00233 PlyElement *elem;
00234
00235
00236 if (fp == NULL)
00237 return (NULL);
00238
00239
00240
00241 plyfile = (PlyFile *) myalloc (sizeof (PlyFile));
00242 plyfile->file_type = file_type;
00243 plyfile->num_comments = 0;
00244 plyfile->num_obj_info = 0;
00245 plyfile->nelems = nelems;
00246 plyfile->version = 1.0;
00247 plyfile->fp = fp;
00248 plyfile->other_elems = NULL;
00249
00250
00251
00252 plyfile->elems = (PlyElement **) myalloc (sizeof (PlyElement *) * nelems);
00253 for (i = 0; i < nelems; i++) {
00254 elem = (PlyElement *) myalloc (sizeof (PlyElement));
00255 plyfile->elems[i] = elem;
00256 elem->name = strdup (elem_names[i]);
00257 elem->num = 0;
00258 elem->nprops = 0;
00259 }
00260
00261
00262 return (plyfile);
00263 }
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 PlyFile *ply_open_for_writing(
00281 char *filename,
00282 int nelems,
00283 const char **elem_names,
00284 int file_type,
00285 float *version
00286 )
00287 {
00288 PlyFile *plyfile;
00289 char *name;
00290 FILE *fp;
00291
00292
00293
00294 name = (char *) myalloc (sizeof (char) *
00295 (static_cast<int>(strlen (filename)) + 5));
00296 strcpy (name, filename);
00297 if (strlen (name) < 4 ||
00298 strcmp (name + strlen (name) - 4, ".ply") != 0)
00299 strcat (name, ".ply");
00300
00301
00302
00303 fp = fopen (name, "wb");
00304 free (name);
00305 if (fp == NULL) {
00306 return (NULL);
00307 }
00308
00309
00310
00311 plyfile = ply_write (fp, nelems, elem_names, file_type);
00312 if (plyfile == NULL)
00313 return (NULL);
00314
00315
00316 *version = plyfile->version;
00317
00318
00319 return (plyfile);
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 void ply_describe_element(
00336 PlyFile *plyfile,
00337 const char *elem_name,
00338 int nelems,
00339 int nprops,
00340 PlyProperty *prop_list
00341 )
00342 {
00343 int i;
00344 PlyElement *elem;
00345 PlyProperty *prop;
00346
00347
00348 elem = find_element (plyfile, elem_name);
00349 if (elem == NULL) {
00350 fprintf(stderr,"ply_describe_element: can't find element '%s'\n",elem_name);
00351 exit (-1);
00352 }
00353
00354 elem->num = nelems;
00355
00356
00357
00358 elem->nprops = nprops;
00359 elem->props = (PlyProperty **) myalloc (sizeof (PlyProperty *) * nprops);
00360 elem->store_prop = (char *) myalloc (sizeof (char) * nprops);
00361
00362 for (i = 0; i < nprops; i++) {
00363 prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
00364 elem->props[i] = prop;
00365 elem->store_prop[i] = NAMED_PROP;
00366 copy_property (prop, &prop_list[i]);
00367 }
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 void ply_describe_property(
00381 PlyFile *plyfile,
00382 const char *elem_name,
00383 PlyProperty *prop
00384 )
00385 {
00386 PlyElement *elem;
00387 PlyProperty *elem_prop;
00388
00389
00390 elem = find_element (plyfile, elem_name);
00391 if (elem == NULL) {
00392 fprintf(stderr, "ply_describe_property: can't find element '%s'\n",
00393 elem_name);
00394 return;
00395 }
00396
00397
00398
00399 if (elem->nprops == 0) {
00400 elem->props = (PlyProperty **) myalloc (sizeof (PlyProperty *));
00401 elem->store_prop = (char *) myalloc (sizeof (char));
00402 elem->nprops = 1;
00403 }
00404 else {
00405 elem->nprops++;
00406 elem->props = (PlyProperty **)
00407 realloc (elem->props, sizeof (PlyProperty *) * elem->nprops);
00408 elem->store_prop = (char *)
00409 realloc (elem->store_prop, sizeof (char) * elem->nprops);
00410 }
00411
00412
00413 elem->other_offset = 0;
00414 elem_prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
00415 elem->props[elem->nprops - 1] = elem_prop;
00416 elem->store_prop[elem->nprops - 1] = NAMED_PROP;
00417 copy_property (elem_prop, prop);
00418 }
00419
00420
00421
00422
00423
00424
00425
00426 void ply_describe_other_properties(
00427 PlyFile *plyfile,
00428 PlyOtherProp *other,
00429 int offset
00430 )
00431 {
00432 int i;
00433 PlyElement *elem;
00434 PlyProperty *prop;
00435
00436
00437 elem = find_element (plyfile, other->name);
00438 if (elem == NULL) {
00439 fprintf(stderr, "ply_describe_other_properties: can't find element '%s'\n",
00440 other->name);
00441 return;
00442 }
00443
00444
00445
00446 if (elem->nprops == 0) {
00447 elem->props = (PlyProperty **)
00448 myalloc (sizeof (PlyProperty *) * other->nprops);
00449 elem->store_prop = (char *) myalloc (sizeof (char) * other->nprops);
00450 elem->nprops = 0;
00451 }
00452 else {
00453 int newsize;
00454 newsize = elem->nprops + other->nprops;
00455 elem->props = (PlyProperty **)
00456 realloc (elem->props, sizeof (PlyProperty *) * newsize);
00457 elem->store_prop = (char *)
00458 realloc (elem->store_prop, sizeof (char) * newsize);
00459 }
00460
00461
00462
00463 for (i = 0; i < other->nprops; i++) {
00464 prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
00465 copy_property (prop, other->props[i]);
00466 elem->props[elem->nprops] = prop;
00467 elem->store_prop[elem->nprops] = OTHER_PROP;
00468 elem->nprops++;
00469 }
00470
00471
00472 elem->other_size = other->size;
00473 elem->other_offset = offset;
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 void ply_element_count(
00487 PlyFile *plyfile,
00488 const char *elem_name,
00489 int nelems
00490 )
00491 {
00492 PlyElement *elem;
00493
00494
00495 elem = find_element (plyfile, elem_name);
00496 if (elem == NULL) {
00497 fprintf(stderr,"ply_element_count: can't find element '%s'\n",elem_name);
00498 exit (-1);
00499 }
00500
00501 elem->num = nelems;
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513 void ply_header_complete(PlyFile *plyfile)
00514 {
00515 int i,j;
00516 FILE *fp = plyfile->fp;
00517 PlyElement *elem;
00518 PlyProperty *prop;
00519
00520 fprintf (fp, "ply\n");
00521
00522 switch (plyfile->file_type) {
00523 case PLY_ASCII:
00524 fprintf (fp, "format ascii 1.0\n");
00525 break;
00526 case PLY_BINARY_BE:
00527 fprintf (fp, "format binary_big_endian 1.0\n");
00528 break;
00529 case PLY_BINARY_LE:
00530 fprintf (fp, "format binary_little_endian 1.0\n");
00531 break;
00532 default:
00533 fprintf (stderr, "ply_header_complete: bad file type = %d\n",
00534 plyfile->file_type);
00535 exit (-1);
00536 }
00537
00538
00539
00540 for (i = 0; i < plyfile->num_comments; i++)
00541 fprintf (fp, "comment %s\n", plyfile->comments[i]);
00542
00543
00544
00545 for (i = 0; i < plyfile->num_obj_info; i++)
00546 fprintf (fp, "obj_info %s\n", plyfile->obj_info[i]);
00547
00548
00549
00550 for (i = 0; i < plyfile->nelems; i++) {
00551
00552 elem = plyfile->elems[i];
00553 fprintf (fp, "element %s %d\n", elem->name, elem->num);
00554
00555
00556 for (j = 0; j < elem->nprops; j++) {
00557 prop = elem->props[j];
00558 if (prop->is_list) {
00559 fprintf (fp, "property list ");
00560 write_scalar_type (fp, prop->count_external);
00561 fprintf (fp, " ");
00562 write_scalar_type (fp, prop->external_type);
00563 fprintf (fp, " %s\n", prop->name);
00564 }
00565 else {
00566 fprintf (fp, "property ");
00567 write_scalar_type (fp, prop->external_type);
00568 fprintf (fp, " %s\n", prop->name);
00569 }
00570 }
00571 }
00572
00573 fprintf (fp, "end_header\n");
00574 }
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586 void ply_put_element_setup(PlyFile *plyfile, const char *elem_name)
00587 {
00588 PlyElement *elem;
00589
00590 elem = find_element (plyfile, elem_name);
00591 if (elem == NULL) {
00592 fprintf(stderr, "ply_elements_setup: can't find element '%s'\n", elem_name);
00593 exit (-1);
00594 }
00595
00596 plyfile->which_elem = elem;
00597 }
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610 void ply_put_element(PlyFile *plyfile, void *elem_ptr)
00611 {
00612 int j, k;
00613 FILE *fp = plyfile->fp;
00614 PlyElement *elem;
00615 PlyProperty *prop;
00616 char *elem_data,*item;
00617 char **item_ptr;
00618 int list_count;
00619 int item_size;
00620 int int_val;
00621 unsigned int uint_val;
00622 double double_val;
00623 char **other_ptr;
00624
00625 elem = plyfile->which_elem;
00626 elem_data = (char *)elem_ptr;
00627 other_ptr = (char **) (((char *) elem_ptr) + elem->other_offset);
00628
00629
00630
00631 if (plyfile->file_type == PLY_ASCII) {
00632
00633
00634
00635
00636 for (j = 0; j < elem->nprops; j++) {
00637 prop = elem->props[j];
00638 if (elem->store_prop[j] == OTHER_PROP)
00639 elem_data = *other_ptr;
00640 else
00641 elem_data = (char *)elem_ptr;
00642 if (prop->is_list) {
00643 item = elem_data + prop->count_offset;
00644 get_stored_item ((void *) item, prop->count_internal,
00645 &int_val, &uint_val, &double_val);
00646 write_ascii_item (fp, int_val, uint_val, double_val,
00647 prop->count_external);
00648 list_count = uint_val;
00649 item_ptr = (char **) (elem_data + prop->offset);
00650 item = item_ptr[0];
00651 item_size = ply_type_size[prop->internal_type];
00652 for (k = 0; k < list_count; k++) {
00653 get_stored_item ((void *) item, prop->internal_type,
00654 &int_val, &uint_val, &double_val);
00655 write_ascii_item (fp, int_val, uint_val, double_val,
00656 prop->external_type);
00657 item += item_size;
00658 }
00659 }
00660 else {
00661 item = elem_data + prop->offset;
00662 get_stored_item ((void *) item, prop->internal_type,
00663 &int_val, &uint_val, &double_val);
00664 write_ascii_item (fp, int_val, uint_val, double_val,
00665 prop->external_type);
00666 }
00667 }
00668
00669 fprintf (fp, "\n");
00670 }
00671 else {
00672
00673
00674
00675
00676 for (j = 0; j < elem->nprops; j++) {
00677 prop = elem->props[j];
00678 if (elem->store_prop[j] == OTHER_PROP)
00679 elem_data = *other_ptr;
00680 else
00681 elem_data = (char *)elem_ptr;
00682 if (prop->is_list) {
00683 item = elem_data + prop->count_offset;
00684 item_size = ply_type_size[prop->count_internal];
00685 get_stored_item ((void *) item, prop->count_internal,
00686 &int_val, &uint_val, &double_val);
00687 write_binary_item (plyfile, int_val, uint_val, double_val,
00688 prop->count_external);
00689 list_count = uint_val;
00690 item_ptr = (char **) (elem_data + prop->offset);
00691 item = item_ptr[0];
00692 item_size = ply_type_size[prop->internal_type];
00693 for (k = 0; k < list_count; k++) {
00694 get_stored_item ((void *) item, prop->internal_type,
00695 &int_val, &uint_val, &double_val);
00696 write_binary_item (plyfile, int_val, uint_val, double_val,
00697 prop->external_type);
00698 item += item_size;
00699 }
00700 }
00701 else {
00702 item = elem_data + prop->offset;
00703 item_size = ply_type_size[prop->internal_type];
00704 get_stored_item ((void *) item, prop->internal_type,
00705 &int_val, &uint_val, &double_val);
00706 write_binary_item (plyfile, int_val, uint_val, double_val,
00707 prop->external_type);
00708 }
00709 }
00710
00711 }
00712 }
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723 void ply_put_comment(PlyFile *plyfile, const char *comment)
00724 {
00725
00726 if (plyfile->num_comments == 0)
00727 {
00728 plyfile->comments = (char **) myalloc (sizeof (char *));
00729 }
00730 else
00731 {
00732 plyfile->comments = (char **) realloc (plyfile->comments,
00733 sizeof (char *) * (plyfile->num_comments + 1));
00734 }
00735
00736
00737 plyfile->comments[plyfile->num_comments] = strdup (comment);
00738 plyfile->num_comments++;
00739 }
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 void ply_put_obj_info(PlyFile *plyfile, const char *obj_info)
00752 {
00753
00754 if (plyfile->num_obj_info == 0)
00755 {
00756 plyfile->obj_info = (char **) myalloc (sizeof (char *));
00757 }
00758 else
00759 {
00760 plyfile->obj_info = (char **) realloc (plyfile->obj_info,
00761 sizeof (char *) * (plyfile->num_obj_info + 1));
00762 }
00763
00764
00765 plyfile->obj_info[plyfile->num_obj_info] = strdup (obj_info);
00766 plyfile->num_obj_info++;
00767 }
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793 PlyFile *ply_read(FILE *fp, int *nelems, char ***elem_names)
00794 {
00795 int i,j;
00796 PlyFile *plyfile;
00797 int nwords;
00798 char **words;
00799 char **elist;
00800 PlyElement *elem;
00801 char *orig_line;
00802
00803
00804 if (fp == NULL)
00805 return (NULL);
00806
00807
00808
00809 plyfile = (PlyFile *) myalloc (sizeof (PlyFile));
00810 plyfile->nelems = 0;
00811 plyfile->comments = NULL;
00812 plyfile->num_comments = 0;
00813 plyfile->obj_info = NULL;
00814 plyfile->num_obj_info = 0;
00815 plyfile->fp = fp;
00816 plyfile->other_elems = NULL;
00817
00818
00819
00820 words = get_words (plyfile->fp, &nwords, &orig_line);
00821 if (!words || !equal_strings (words[0], "ply"))
00822 return (NULL);
00823
00824 while (words) {
00825
00826
00827
00828 if (equal_strings (words[0], "format")) {
00829 if (nwords != 3)
00830 return (NULL);
00831 if (equal_strings (words[1], "ascii"))
00832 plyfile->file_type = PLY_ASCII;
00833 else if (equal_strings (words[1], "binary_big_endian"))
00834 plyfile->file_type = PLY_BINARY_BE;
00835 else if (equal_strings (words[1], "binary_little_endian"))
00836 plyfile->file_type = PLY_BINARY_LE;
00837 else
00838 {
00839 free (words);
00840 return (NULL);
00841 }
00842 plyfile->version = atof (words[2]);
00843 }
00844 else if (equal_strings (words[0], "element"))
00845 add_element (plyfile, words, nwords);
00846 else if (equal_strings (words[0], "property"))
00847 add_property (plyfile, words, nwords);
00848 else if (equal_strings (words[0], "comment"))
00849 add_comment (plyfile, orig_line);
00850 else if (equal_strings (words[0], "obj_info"))
00851 add_obj_info (plyfile, orig_line);
00852 else if (equal_strings (words[0], "end_header"))
00853 {
00854 free (words);
00855 break;
00856 }
00857
00858
00859 free (words);
00860
00861 words = get_words (plyfile->fp, &nwords, &orig_line);
00862 }
00863
00864
00865
00866
00867
00868 for (i = 0; i < plyfile->nelems; i++) {
00869 elem = plyfile->elems[i];
00870 elem->store_prop = (char *) myalloc (sizeof (char) * elem->nprops);
00871 for (j = 0; j < elem->nprops; j++)
00872 elem->store_prop[j] = DONT_STORE_PROP;
00873 elem->other_offset = NO_OTHER_PROPS;
00874 }
00875
00876
00877
00878 elist = (char **) myalloc (sizeof (char *) * plyfile->nelems);
00879 for (i = 0; i < plyfile->nelems; i++)
00880 elist[i] = strdup (plyfile->elems[i]->name);
00881
00882 *elem_names = elist;
00883 *nelems = plyfile->nelems;
00884
00885
00886
00887 return (plyfile);
00888 }
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905 PlyFile *ply_open_for_reading(
00906 char *filename,
00907 int *nelems,
00908 char ***elem_names,
00909 int *file_type,
00910 float *version
00911 )
00912 {
00913 FILE *fp;
00914 PlyFile *plyfile;
00915 char *name;
00916
00917
00918
00919 name = (char *) myalloc (sizeof (char) *
00920 (static_cast<int>(strlen (filename) + 5)));
00921 strcpy (name, filename);
00922 if (strlen (name) < 4 ||
00923 strcmp (name + strlen (name) - 4, ".ply") != 0)
00924 strcat (name, ".ply");
00925
00926
00927
00928 fp = fopen (name, "rb");
00929 free(name);
00930 if (fp == NULL)
00931 return (NULL);
00932
00933
00934
00935 plyfile = ply_read (fp, nelems, elem_names);
00936
00937
00938
00939 *file_type = plyfile->file_type;
00940 *version = plyfile->version;
00941
00942
00943
00944 return (plyfile);
00945 }
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 PlyProperty **ply_get_element_description(
00962 PlyFile *plyfile,
00963 char *elem_name,
00964 int *nelems,
00965 int *nprops
00966 )
00967 {
00968 int i;
00969 PlyElement *elem;
00970 PlyProperty *prop;
00971 PlyProperty **prop_list;
00972
00973
00974 elem = find_element (plyfile, elem_name);
00975 if (elem == NULL)
00976 return (NULL);
00977
00978 *nelems = elem->num;
00979 *nprops = elem->nprops;
00980
00981
00982 prop_list = (PlyProperty **) myalloc (sizeof (PlyProperty *) * elem->nprops);
00983 for (i = 0; i < elem->nprops; i++) {
00984 prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
00985 copy_property (prop, elem->props[i]);
00986 prop_list[i] = prop;
00987 }
00988
00989
00990 return (prop_list);
00991 }
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005 void ply_get_element_setup( PlyFile *plyfile, char *elem_name, int nprops,
01006 PlyProperty *prop_list )
01007 {
01008 int i;
01009 PlyElement *elem;
01010 PlyProperty *prop;
01011 int index;
01012
01013
01014 elem = find_element (plyfile, elem_name);
01015 plyfile->which_elem = elem;
01016
01017
01018 for (i = 0; i < nprops; i++)
01019 {
01020
01021 prop = find_property (elem, prop_list[i].name, &index);
01022 if (prop == NULL)
01023 {
01024 fprintf ( stderr,
01025 "Warning: Can't find property '%s' in element '%s'\n",
01026 prop_list[i].name, elem_name );
01027 continue;
01028 }
01029
01030
01031 prop->internal_type = prop_list[i].internal_type;
01032 prop->offset = prop_list[i].offset;
01033 prop->count_internal = prop_list[i].count_internal;
01034 prop->count_offset = prop_list[i].count_offset;
01035
01036
01037 elem->store_prop[index] = STORE_PROP;
01038 }
01039 }
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054 void ply_get_property(
01055 PlyFile *plyfile,
01056 char *elem_name,
01057 PlyProperty *prop
01058 )
01059 {
01060 PlyElement *elem;
01061 PlyProperty *prop_ptr;
01062 int index;
01063
01064
01065 elem = find_element (plyfile, elem_name);
01066 plyfile->which_elem = elem;
01067
01068
01069
01070 prop_ptr = find_property (elem, prop->name, &index);
01071 if (prop_ptr == NULL) {
01072 fprintf (stderr, "Warning: Can't find property '%s' in element '%s'\n",
01073 prop->name, elem_name);
01074 return;
01075 }
01076 prop_ptr->internal_type = prop->internal_type;
01077 prop_ptr->offset = prop->offset;
01078 prop_ptr->count_internal = prop->count_internal;
01079 prop_ptr->count_offset = prop->count_offset;
01080
01081
01082 elem->store_prop[index] = STORE_PROP;
01083 }
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096 void ply_get_element(PlyFile *plyfile, void *elem_ptr)
01097 {
01098 if (plyfile->file_type == PLY_ASCII)
01099 ascii_get_element (plyfile, (char *) elem_ptr);
01100 else
01101 binary_get_element (plyfile, (char *) elem_ptr);
01102 }
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116 char **ply_get_comments(PlyFile *plyfile, int *num_comments)
01117 {
01118 *num_comments = plyfile->num_comments;
01119 return (plyfile->comments);
01120 }
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135 char **ply_get_obj_info(PlyFile *plyfile, int *num_obj_info)
01136 {
01137 *num_obj_info = plyfile->num_obj_info;
01138 return (plyfile->obj_info);
01139 }
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153 void setup_other_props(PlyFile *, PlyElement *elem)
01154 {
01155 int i;
01156 PlyProperty *prop;
01157 int size = 0;
01158 int type_size;
01159
01160
01161
01162
01163
01164 for (type_size = 8; type_size > 0; type_size /= 2) {
01165
01166
01167
01168
01169 for (i = 0; i < elem->nprops; i++) {
01170
01171
01172 if (elem->store_prop[i])
01173 continue;
01174
01175 prop = elem->props[i];
01176
01177
01178 prop->internal_type = prop->external_type;
01179 prop->count_internal = prop->count_external;
01180
01181
01182 if (prop->is_list) {
01183
01184
01185 if (type_size == sizeof (void *)) {
01186 prop->offset = size;
01187 size += sizeof (void *);
01188 }
01189
01190
01191 if (type_size == ply_type_size[prop->count_external]) {
01192 prop->count_offset = size;
01193 size += ply_type_size[prop->count_external];
01194 }
01195 }
01196
01197 else if (type_size == ply_type_size[prop->external_type]) {
01198 prop->offset = size;
01199 size += ply_type_size[prop->external_type];
01200 }
01201 }
01202
01203 }
01204
01205
01206 elem->other_size = size;
01207 }
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224 PlyOtherProp *ply_get_other_properties(
01225 PlyFile *plyfile,
01226 char *elem_name,
01227 int offset
01228 )
01229 {
01230 int i;
01231 PlyElement *elem;
01232 PlyOtherProp *other;
01233 PlyProperty *prop;
01234 int nprops;
01235
01236
01237 elem = find_element (plyfile, elem_name);
01238 if (elem == NULL) {
01239 fprintf (stderr, "ply_get_other_properties: Can't find element '%s'\n",
01240 elem_name);
01241 return (NULL);
01242 }
01243
01244
01245 plyfile->which_elem = elem;
01246
01247
01248 elem->other_offset = offset;
01249
01250
01251 setup_other_props (plyfile, elem);
01252
01253
01254 other = (PlyOtherProp *) myalloc (sizeof (PlyOtherProp));
01255 other->name = strdup (elem_name);
01256 #if 0
01257 if (elem->other_offset == NO_OTHER_PROPS) {
01258 other->size = 0;
01259 other->props = NULL;
01260 other->nprops = 0;
01261 return (other);
01262 }
01263 #endif
01264 other->size = elem->other_size;
01265 other->props = (PlyProperty **) myalloc (sizeof(PlyProperty) * elem->nprops);
01266
01267
01268 nprops = 0;
01269 for (i = 0; i < elem->nprops; i++) {
01270 if (elem->store_prop[i])
01271 continue;
01272 prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
01273 copy_property (prop, elem->props[i]);
01274 other->props[nprops] = prop;
01275 nprops++;
01276 }
01277 other->nprops = nprops;
01278
01279 #if 1
01280
01281 if (other->nprops == 0) {
01282 elem->other_offset = NO_OTHER_PROPS;
01283 }
01284 #endif
01285
01286
01287 return (other);
01288 }
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313 PlyOtherElems *ply_get_other_element (
01314 PlyFile *plyfile,
01315 char *elem_name,
01316 int elem_count
01317 )
01318 {
01319 int i;
01320 PlyElement *elem;
01321 PlyOtherElems *other_elems;
01322 OtherElem *other;
01323
01324
01325 elem = find_element (plyfile, elem_name);
01326 if (elem == NULL) {
01327 fprintf (stderr,
01328 "ply_get_other_element: can't find element '%s'\n", elem_name);
01329 exit (-1);
01330 }
01331
01332
01333
01334
01335 if (plyfile->other_elems == NULL) {
01336 plyfile->other_elems = (PlyOtherElems *) myalloc (sizeof (PlyOtherElems));
01337 other_elems = plyfile->other_elems;
01338 other_elems->other_list = (OtherElem *) myalloc (sizeof (OtherElem));
01339 other = &(other_elems->other_list[0]);
01340 other_elems->num_elems = 1;
01341 }
01342 else {
01343 other_elems = plyfile->other_elems;
01344 other_elems->other_list = (OtherElem *) realloc (other_elems->other_list,
01345 sizeof (OtherElem) * other_elems->num_elems + 1);
01346 other = &(other_elems->other_list[other_elems->num_elems]);
01347 other_elems->num_elems++;
01348 }
01349
01350
01351 other->elem_count = elem_count;
01352
01353
01354 other->elem_name = strdup (elem_name);
01355
01356
01357 other->other_data = (OtherData **)
01358 malloc (sizeof (OtherData *) * other->elem_count);
01359
01360
01361 other->other_props = ply_get_other_properties (plyfile, elem_name,
01362 offsetof(OtherData,other_props));
01363
01364
01365 for (i = 0; i < other->elem_count; i++) {
01366
01367 other->other_data[i] = (OtherData *) malloc (sizeof (OtherData));
01368 ply_get_element (plyfile, (void *) other->other_data[i]);
01369 }
01370
01371
01372 return (other_elems);
01373 }
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385 void ply_describe_other_elements (
01386 PlyFile *plyfile,
01387 PlyOtherElems *other_elems
01388 )
01389 {
01390 int i;
01391 OtherElem *other;
01392
01393
01394 if (other_elems == NULL)
01395 return;
01396
01397
01398 plyfile->other_elems = other_elems;
01399
01400
01401
01402 for (i = 0; i < other_elems->num_elems; i++) {
01403 other = &(other_elems->other_list[i]);
01404 ply_element_count (plyfile, other->elem_name, other->elem_count);
01405 ply_describe_other_properties (plyfile, other->other_props,
01406 offsetof(OtherData,other_props));
01407 }
01408 }
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418 void ply_put_other_elements (PlyFile *plyfile)
01419 {
01420 int i,j;
01421 OtherElem *other;
01422
01423
01424 if (plyfile->other_elems == NULL)
01425 return;
01426
01427
01428
01429 for (i = 0; i < plyfile->other_elems->num_elems; i++) {
01430
01431 other = &(plyfile->other_elems->other_list[i]);
01432 ply_put_element_setup (plyfile, other->elem_name);
01433
01434
01435 for (j = 0; j < other->elem_count; j++)
01436 ply_put_element (plyfile, (void *) other->other_data[j]);
01437 }
01438 }
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448 void ply_free_other_elements (PlyOtherElems *)
01449 {
01450
01451 }
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468 void ply_close(PlyFile *plyfile)
01469 {
01470
01471
01472
01473 fclose (plyfile->fp);
01474
01475 int i, j;
01476 PlyElement *elem;
01477 for (i=0; i<plyfile->nelems; i++)
01478 {
01479 elem = plyfile->elems[i];
01480 if ( elem->name ) {free(elem->name);}
01481 for (j=0; j<elem->nprops; j++)
01482 {
01483 if ( elem->props[j]->name ) {free(const_cast<char *>(elem->props[j]->name));}
01484 free (elem->props[j]);
01485 }
01486 free (elem->props);
01487 free (elem->store_prop);
01488 free (elem);
01489 }
01490 free(plyfile->elems);
01491
01492 for (i=0; i<plyfile->num_comments; i++)
01493 {
01494 free (plyfile->comments[i]);
01495 }
01496 free (plyfile->comments);
01497
01498 for (i=0; i<plyfile->num_obj_info; i++)
01499 {
01500 free (plyfile->obj_info[i]);
01501 }
01502 free (plyfile->obj_info);
01503
01504 free (plyfile);
01505 }
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519 void ply_get_info(PlyFile *ply, float *version, int *file_type)
01520 {
01521 if (ply == NULL)
01522 return;
01523
01524 *version = ply->version;
01525 *file_type = ply->file_type;
01526 }
01527
01528
01529
01530
01531
01532
01533 int equal_strings(const char *s1, const char *s2)
01534 {
01535 while (*s1 && *s2)
01536 if (*s1++ != *s2++)
01537 return (0);
01538
01539 if (*s1 != *s2)
01540 return (0);
01541 else
01542 return (1);
01543 }
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557 PlyElement *find_element(PlyFile *plyfile, const char *element)
01558 {
01559 int i;
01560
01561 for (i = 0; i < plyfile->nelems; i++)
01562 if (equal_strings (element, plyfile->elems[i]->name))
01563 return (plyfile->elems[i]);
01564
01565 return (NULL);
01566 }
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581 PlyProperty *find_property(PlyElement *elem, const char *prop_name, int *index)
01582 {
01583 int i;
01584
01585 for( i = 0; i < elem->nprops; i++)
01586 if (equal_strings (prop_name, elem->props[i]->name))
01587 {
01588 *index = i;
01589 return (elem->props[i]);
01590 }
01591
01592 *index = -1;
01593 return (NULL);
01594 }
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605 void ascii_get_element(PlyFile *plyfile, char *elem_ptr)
01606 {
01607 int j,k;
01608 PlyElement *elem;
01609 PlyProperty *prop;
01610 char **words;
01611 int nwords;
01612 int which_word;
01613 char *elem_data,*item=0;
01614 char *item_ptr;
01615 int item_size=0;
01616 int int_val;
01617 unsigned int uint_val;
01618 double double_val;
01619 int list_count;
01620 int store_it;
01621 char **store_array;
01622 char *orig_line;
01623 char *other_data=0;
01624 int other_flag;
01625
01626
01627 elem = plyfile->which_elem;
01628
01629
01630
01631 if (elem->other_offset != NO_OTHER_PROPS) {
01632 char **ptr;
01633 other_flag = 1;
01634
01635 other_data = (char *) myalloc (elem->other_size);
01636
01637 ptr = (char **) (elem_ptr + elem->other_offset);
01638 *ptr = other_data;
01639 }
01640 else
01641 other_flag = 0;
01642
01643
01644
01645 words = get_words (plyfile->fp, &nwords, &orig_line);
01646 if (words == NULL) {
01647 fprintf (stderr, "ply_get_element: unexpected end of file\n");
01648 exit (-1);
01649 }
01650
01651 which_word = 0;
01652
01653 for (j = 0; j < elem->nprops; j++) {
01654
01655 prop = elem->props[j];
01656 store_it = (elem->store_prop[j] | other_flag);
01657
01658
01659 if (elem->store_prop[j])
01660 elem_data = elem_ptr;
01661 else
01662 elem_data = other_data;
01663
01664 if (prop->is_list) {
01665
01666
01667 get_ascii_item (words[which_word++], prop->count_external,
01668 &int_val, &uint_val, &double_val);
01669 if (store_it) {
01670 item = elem_data + prop->count_offset;
01671 store_item(item, prop->count_internal, int_val, uint_val, double_val);
01672 }
01673
01674
01675 list_count = int_val;
01676 item_size = ply_type_size[prop->internal_type];
01677 store_array = (char **) (elem_data + prop->offset);
01678
01679 if (list_count == 0) {
01680 if (store_it)
01681 *store_array = NULL;
01682 }
01683 else {
01684 if (store_it) {
01685 item_ptr = (char *) myalloc (sizeof (char) * item_size * list_count);
01686 item = item_ptr;
01687 *store_array = item_ptr;
01688 }
01689
01690
01691 for (k = 0; k < list_count; k++) {
01692 get_ascii_item (words[which_word++], prop->external_type,
01693 &int_val, &uint_val, &double_val);
01694 if (store_it) {
01695 store_item (item, prop->internal_type,
01696 int_val, uint_val, double_val);
01697 item += item_size;
01698 }
01699 }
01700 }
01701
01702 }
01703 else {
01704 get_ascii_item (words[which_word++], prop->external_type,
01705 &int_val, &uint_val, &double_val);
01706 if (store_it) {
01707 item = elem_data + prop->offset;
01708 store_item (item, prop->internal_type, int_val, uint_val, double_val);
01709 }
01710 }
01711
01712 }
01713
01714 free (words);
01715 }
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726 void binary_get_element(PlyFile *plyfile, char *elem_ptr)
01727 {
01728 int j,k;
01729 PlyElement *elem;
01730 PlyProperty *prop;
01731
01732 char *elem_data,*item=0;
01733 char *item_ptr;
01734 int item_size=0;
01735 int int_val;
01736 unsigned int uint_val;
01737 double double_val;
01738 int list_count;
01739 int store_it;
01740 char **store_array;
01741 char *other_data=0;
01742 int other_flag;
01743
01744
01745 elem = plyfile->which_elem;
01746
01747
01748
01749 if (elem->other_offset != NO_OTHER_PROPS) {
01750 char **ptr;
01751 other_flag = 1;
01752
01753 other_data = (char *) myalloc (elem->other_size);
01754
01755 ptr = (char **) (elem_ptr + elem->other_offset);
01756 *ptr = other_data;
01757 }
01758 else
01759 other_flag = 0;
01760
01761
01762
01763 for (j = 0; j < elem->nprops; j++) {
01764
01765 prop = elem->props[j];
01766 store_it = (elem->store_prop[j] | other_flag);
01767
01768
01769 if (elem->store_prop[j])
01770 elem_data = elem_ptr;
01771 else
01772 elem_data = other_data;
01773
01774 if (prop->is_list) {
01775
01776
01777 get_binary_item (plyfile, prop->count_external,
01778 &int_val, &uint_val, &double_val);
01779 if (store_it) {
01780 item = elem_data + prop->count_offset;
01781 store_item(item, prop->count_internal, int_val, uint_val, double_val);
01782 }
01783
01784
01785 list_count = int_val;
01786
01787
01788
01789
01790 if (store_it) {
01791 item_size = ply_type_size[prop->internal_type];
01792 }
01793 store_array = (char **) (elem_data + prop->offset);
01794 if (list_count == 0) {
01795 if (store_it)
01796 *store_array = NULL;
01797 }
01798 else {
01799 if (store_it) {
01800 item_ptr = (char *) myalloc (sizeof (char) * item_size * list_count);
01801 item = item_ptr;
01802 *store_array = item_ptr;
01803 }
01804
01805
01806 for (k = 0; k < list_count; k++) {
01807 get_binary_item (plyfile, prop->external_type,
01808 &int_val, &uint_val, &double_val);
01809 if (store_it) {
01810 store_item (item, prop->internal_type,
01811 int_val, uint_val, double_val);
01812 item += item_size;
01813 }
01814 }
01815 }
01816
01817 }
01818 else {
01819 get_binary_item (plyfile, prop->external_type,
01820 &int_val, &uint_val, &double_val);
01821 if (store_it) {
01822 item = elem_data + prop->offset;
01823 store_item (item, prop->internal_type, int_val, uint_val, double_val);
01824 }
01825 }
01826
01827 }
01828 }
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839 void write_scalar_type (FILE *fp, int code)
01840 {
01841
01842
01843 if (code <= PLY_START_TYPE || code >= PLY_END_TYPE) {
01844 fprintf (stderr, "write_scalar_type: bad data code = %d\n", code);
01845 exit (-1);
01846 }
01847
01848
01849
01850 fprintf (fp, "%s", type_names[code]);
01851 }
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869 char **get_words(FILE *fp, int *nwords, char **orig_line)
01870 {
01871 #define BIG_STRING 4096
01872 static char str[BIG_STRING];
01873 static char str_copy[BIG_STRING];
01874 char **words;
01875 int max_words = 10;
01876 int num_words = 0;
01877 char *ptr,*ptr2;
01878 char *result;
01879
01880
01881 result = fgets (str, BIG_STRING, fp);
01882 if (result == NULL) {
01883 *nwords = 0;
01884 *orig_line = NULL;
01885 return (NULL);
01886 }
01887
01888 words = (char **) myalloc (sizeof (char *) * max_words);
01889
01890
01891
01892
01893
01894 str[BIG_STRING-2] = ' ';
01895 str[BIG_STRING-1] = '\0';
01896
01897 for (ptr = str, ptr2 = str_copy; *ptr != '\0'; ptr++, ptr2++) {
01898 *ptr2 = *ptr;
01899 if (*ptr == '\t') {
01900 *ptr = ' ';
01901 *ptr2 = ' ';
01902 }
01903 else if (*ptr == '\n') {
01904 *ptr = ' ';
01905 *ptr2 = '\0';
01906 break;
01907 }
01908 }
01909
01910
01911
01912 ptr = str;
01913 while (*ptr != '\0') {
01914
01915
01916 while (*ptr == ' ')
01917 ptr++;
01918
01919
01920 if (*ptr == '\0')
01921 break;
01922
01923
01924 if (num_words >= max_words) {
01925 max_words += 10;
01926 words = (char **) realloc (words, sizeof (char *) * max_words);
01927 }
01928 words[num_words++] = ptr;
01929
01930
01931 while (*ptr != ' ')
01932 ptr++;
01933
01934
01935 *ptr++ = '\0';
01936 }
01937
01938
01939 *nwords = num_words;
01940 *orig_line = str_copy;
01941 return (words);
01942 }
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956 double get_item_value(char *item, int type)
01957 {
01958 unsigned char *puchar;
01959 char *pchar;
01960 short int *pshort;
01961 unsigned short int *pushort;
01962 int *pint;
01963 unsigned int *puint;
01964 float *pfloat;
01965 double *pdouble;
01966 int int_value;
01967 unsigned int uint_value;
01968 double double_value;
01969
01970 switch (type) {
01971 case PLY_CHAR:
01972 pchar = (char *) item;
01973 int_value = *pchar;
01974 return ((double) int_value);
01975 case PLY_UCHAR:
01976 case PLY_UINT8:
01977 puchar = (unsigned char *) item;
01978 int_value = *puchar;
01979 return ((double) int_value);
01980 case PLY_SHORT:
01981 pshort = (short int *) item;
01982 int_value = *pshort;
01983 return ((double) int_value);
01984 case PLY_USHORT:
01985 pushort = (unsigned short int *) item;
01986 int_value = *pushort;
01987 return ((double) int_value);
01988 case PLY_INT:
01989 case PLY_INT32:
01990 pint = (int *) item;
01991 int_value = *pint;
01992 return ((double) int_value);
01993 case PLY_UINT:
01994 puint = (unsigned int *) item;
01995 uint_value = *puint;
01996 return ((double) uint_value);
01997 case PLY_FLOAT:
01998 case PLY_FLOAT32:
01999 pfloat = (float *) item;
02000 double_value = *pfloat;
02001 return (double_value);
02002 case PLY_DOUBLE:
02003 pdouble = (double *) item;
02004 double_value = *pdouble;
02005 return (double_value);
02006 }
02007 fprintf (stderr, "get_item_value: bad type = %d\n", type);
02008 return 0;
02009 }
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023 void write_binary_item(PlyFile *plyfile,
02024 int int_val,
02025 unsigned int uint_val,
02026 double double_val,
02027 int type
02028 )
02029 {
02030 FILE *fp = plyfile->fp;
02031 unsigned char uchar_val;
02032 char char_val;
02033 unsigned short ushort_val;
02034 short short_val;
02035 float float_val;
02036
02037 switch (type) {
02038 case PLY_CHAR:
02039 char_val = int_val;
02040 fwrite (&char_val, 1, 1, fp);
02041 break;
02042 case PLY_SHORT:
02043 short_val = int_val;
02044 if( plyfile->file_type == PLY_BINARY_BE )
02045 swap2BE(&short_val);
02046 else
02047 swap2LE(&short_val);
02048 fwrite (&short_val, 2, 1, fp);
02049 break;
02050 case PLY_INT:
02051 case PLY_INT32:
02052 if( plyfile->file_type == PLY_BINARY_BE )
02053 {
02054 swap4BE(&int_val);
02055 }
02056 else
02057 {
02058 swap4LE(&int_val);
02059 }
02060 fwrite (&int_val, 4, 1, fp);
02061 break;
02062 case PLY_UCHAR:
02063 case PLY_UINT8:
02064 uchar_val = uint_val;
02065 fwrite (&uchar_val, 1, 1, fp);
02066 break;
02067 case PLY_USHORT:
02068 if( plyfile->file_type == PLY_BINARY_BE )
02069 {
02070 swap2BE(&ushort_val);
02071 }
02072 else
02073 {
02074 swap2LE(&ushort_val);
02075 }
02076 ushort_val = uint_val;
02077 fwrite (&ushort_val, 2, 1, fp);
02078 break;
02079 case PLY_UINT:
02080 if( plyfile->file_type == PLY_BINARY_BE )
02081 {
02082 swap4BE(&uint_val);
02083 }
02084 else
02085 {
02086 swap4LE(&uint_val);
02087 }
02088 fwrite (&uint_val, 4, 1, fp);
02089 break;
02090 case PLY_FLOAT:
02091 case PLY_FLOAT32:
02092 float_val = double_val;
02093 if( plyfile->file_type == PLY_BINARY_BE )
02094 {
02095 swap4BE(&float_val);
02096 }
02097 else
02098 {
02099 swap4LE(&float_val);
02100 }
02101 fwrite (&float_val, 4, 1, fp);
02102 break;
02103 case PLY_DOUBLE:
02104 if( plyfile->file_type == PLY_BINARY_BE )
02105 {
02106 swap8BE(&double_val);
02107 }
02108 else
02109 {
02110 swap8LE(&double_val);
02111 }
02112 fwrite (&double_val, 8, 1, fp);
02113 break;
02114 default:
02115 fprintf (stderr, "write_binary_item: bad type = %d\n", type);
02116 exit (-1);
02117 }
02118 }
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132 void write_ascii_item(
02133 FILE *fp,
02134 int int_val,
02135 unsigned int uint_val,
02136 double double_val,
02137 int type
02138 )
02139 {
02140 switch (type) {
02141 case PLY_CHAR:
02142 case PLY_SHORT:
02143 case PLY_INT:
02144 case PLY_INT32:
02145 fprintf (fp, "%d ", int_val);
02146 break;
02147 case PLY_UCHAR:
02148 case PLY_UINT8:
02149 case PLY_USHORT:
02150 case PLY_UINT:
02151 fprintf (fp, "%u ", uint_val);
02152 break;
02153 case PLY_FLOAT:
02154 case PLY_FLOAT32:
02155 case PLY_DOUBLE:
02156 fprintf (fp, "%g ", double_val);
02157 break;
02158 default:
02159 fprintf (stderr, "write_ascii_item: bad type = %d\n", type);
02160 exit (-1);
02161 }
02162 }
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178 void get_stored_item(
02179 void *ptr,
02180 int type,
02181 int *int_val,
02182 unsigned int *uint_val,
02183 double *double_val
02184 )
02185 {
02186 switch (type) {
02187 case PLY_CHAR:
02188 *int_val = *((char *) ptr);
02189 *uint_val = *int_val;
02190 *double_val = *int_val;
02191 break;
02192 case PLY_UCHAR:
02193 case PLY_UINT8:
02194 *uint_val = *((unsigned char *) ptr);
02195 *int_val = *uint_val;
02196 *double_val = *uint_val;
02197 break;
02198 case PLY_SHORT:
02199 *int_val = *((short int *) ptr);
02200 *uint_val = *int_val;
02201 *double_val = *int_val;
02202 break;
02203 case PLY_USHORT:
02204 *uint_val = *((unsigned short int *) ptr);
02205 *int_val = *uint_val;
02206 *double_val = *uint_val;
02207 break;
02208 case PLY_INT:
02209 case PLY_INT32:
02210 *int_val = *((int *) ptr);
02211 *uint_val = *int_val;
02212 *double_val = *int_val;
02213 break;
02214 case PLY_UINT:
02215 *uint_val = *((unsigned int *) ptr);
02216 *int_val = *uint_val;
02217 *double_val = *uint_val;
02218 break;
02219 case PLY_FLOAT:
02220 case PLY_FLOAT32:
02221 *double_val = *((float *) ptr);
02222 *int_val = (int) *double_val;
02223 *uint_val = (unsigned int) *double_val;
02224 break;
02225 case PLY_DOUBLE:
02226 *double_val = *((double *) ptr);
02227 *int_val = (int) *double_val;
02228 *uint_val = (unsigned int) *double_val;
02229 break;
02230 default:
02231 fprintf (stderr, "get_stored_item: bad type = %d\n", type);
02232 exit (-1);
02233 }
02234 }
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251 void get_binary_item(
02252 PlyFile *plyfile,
02253 int type,
02254 int *int_val,
02255 unsigned int *uint_val,
02256 double *double_val
02257 )
02258 {
02259 char c[8];
02260 void *ptr;
02261
02262 ptr = (void *) c;
02263
02264 switch (type) {
02265 case PLY_CHAR:
02266 if( fread (ptr, 1, 1, plyfile->fp) <= 0 )
02267 abort();
02268 *int_val = *((char *) ptr);
02269 *uint_val = *int_val;
02270 *double_val = *int_val;
02271 break;
02272 case PLY_UCHAR:
02273 case PLY_UINT8:
02274 if( fread (ptr, 1, 1, plyfile->fp) <= 0 )
02275 abort();
02276 *uint_val = *((unsigned char *) ptr);
02277 *int_val = *uint_val;
02278 *double_val = *uint_val;
02279 break;
02280 case PLY_SHORT:
02281 if( fread (ptr, 2, 1, plyfile->fp) <= 0 )
02282 abort();
02283 if( plyfile->file_type == PLY_BINARY_BE )
02284 {
02285 swap2BE(ptr);
02286 }
02287 else
02288 {
02289 swap2LE(ptr);
02290 }
02291 *int_val = *((short int *) ptr);
02292 *uint_val = *int_val;
02293 *double_val = *int_val;
02294 break;
02295 case PLY_USHORT:
02296 if( fread (ptr, 2, 1, plyfile->fp) <= 0 )
02297 abort();
02298 if( plyfile->file_type == PLY_BINARY_BE )
02299 {
02300 swap2BE(ptr);
02301 }
02302 else
02303 {
02304 swap2LE(ptr);
02305 }
02306 *uint_val = *((unsigned short int *) ptr);
02307 *int_val = *uint_val;
02308 *double_val = *uint_val;
02309 break;
02310 case PLY_INT:
02311 case PLY_INT32:
02312 if( fread (ptr, 4, 1, plyfile->fp) <= 0 )
02313 abort();
02314 if( plyfile->file_type == PLY_BINARY_BE )
02315 {
02316 swap4BE(ptr);
02317 }
02318 else
02319 {
02320 swap4LE(ptr);
02321 }
02322 *int_val = *((int *) ptr);
02323 *uint_val = *int_val;
02324 *double_val = *int_val;
02325 break;
02326 case PLY_UINT:
02327 if( fread (ptr, 4, 1, plyfile->fp) <= 0 )
02328 abort();
02329 if( plyfile->file_type == PLY_BINARY_BE )
02330 {
02331 swap4BE(ptr);
02332 }
02333 else
02334 {
02335 swap4LE(ptr);
02336 }
02337 *uint_val = *((unsigned int *) ptr);
02338 *int_val = *uint_val;
02339 *double_val = *uint_val;
02340 break;
02341 case PLY_FLOAT:
02342 case PLY_FLOAT32:
02343 if( fread (ptr, 4, 1, plyfile->fp) <= 0 )
02344 abort();
02345 if( plyfile->file_type == PLY_BINARY_BE )
02346 {
02347 swap4BE(ptr);
02348 }
02349 else
02350 {
02351 swap4LE(ptr);
02352 }
02353 *double_val = *((float *) ptr);
02354 *int_val = (int) *double_val;
02355 *uint_val = (unsigned int) *double_val;
02356 break;
02357 case PLY_DOUBLE:
02358 if( fread (ptr, 8, 1, plyfile->fp) <= 0 )
02359 abort();
02360 if( plyfile->file_type == PLY_BINARY_BE )
02361 {
02362 swap8BE(ptr);
02363 }
02364 else
02365 {
02366 swap8LE(ptr);
02367 }
02368 *double_val = *((double *) ptr);
02369 *int_val = (int) *double_val;
02370 *uint_val = (unsigned int) *double_val;
02371 break;
02372 default:
02373 fprintf (stderr, "get_binary_item: bad type = %d\n", type);
02374 exit (-1);
02375 }
02376 }
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393 void get_ascii_item(
02394 char *word,
02395 int type,
02396 int *int_val,
02397 unsigned int *uint_val,
02398 double *double_val
02399 )
02400 {
02401 switch (type) {
02402 case PLY_CHAR:
02403 case PLY_UCHAR:
02404 case PLY_UINT8:
02405 case PLY_SHORT:
02406 case PLY_USHORT:
02407 case PLY_INT:
02408 case PLY_INT32:
02409 *int_val = atoi (word);
02410 *uint_val = *int_val;
02411 *double_val = *int_val;
02412 break;
02413
02414 case PLY_UINT:
02415 *uint_val = strtoul (word, (char **) NULL, 10);
02416 *int_val = *uint_val;
02417 *double_val = *uint_val;
02418 break;
02419
02420 case PLY_FLOAT:
02421 case PLY_FLOAT32:
02422 case PLY_DOUBLE:
02423 *double_val = atof (word);
02424 *int_val = (int) *double_val;
02425 *uint_val = (unsigned int) *double_val;
02426 break;
02427
02428 default:
02429 fprintf (stderr, "get_ascii_item: bad type = %d\n", type);
02430 exit (-1);
02431 }
02432 }
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449 void store_item (
02450 char *item,
02451 int type,
02452 int int_val,
02453 unsigned int uint_val,
02454 double double_val
02455 )
02456 {
02457 unsigned char *puchar;
02458 short int *pshort;
02459 unsigned short int *pushort;
02460 int *pint;
02461 unsigned int *puint;
02462 float *pfloat;
02463 double *pdouble;
02464
02465 switch (type) {
02466 case PLY_CHAR:
02467 *item = int_val;
02468 break;
02469 case PLY_UCHAR:
02470 case PLY_UINT8:
02471 puchar = (unsigned char *) item;
02472 *puchar = uint_val;
02473 break;
02474 case PLY_SHORT:
02475 pshort = (short *) item;
02476 *pshort = int_val;
02477 break;
02478 case PLY_USHORT:
02479 pushort = (unsigned short *) item;
02480 *pushort = uint_val;
02481 break;
02482 case PLY_INT:
02483 case PLY_INT32:
02484 pint = (int *) item;
02485 *pint = int_val;
02486 break;
02487 case PLY_UINT:
02488 puint = (unsigned int *) item;
02489 *puint = uint_val;
02490 break;
02491 case PLY_FLOAT:
02492 case PLY_FLOAT32:
02493 pfloat = (float *) item;
02494 *pfloat = double_val;
02495 break;
02496 case PLY_DOUBLE:
02497 pdouble = (double *) item;
02498 *pdouble = double_val;
02499 break;
02500 default:
02501 fprintf (stderr, "store_item: bad type = %d\n", type);
02502 exit (-1);
02503 }
02504 }
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516 void add_element (PlyFile *plyfile, char **words, int)
02517 {
02518 PlyElement *elem;
02519
02520
02521 elem = (PlyElement *) myalloc (sizeof (PlyElement));
02522 elem->name = strdup (words[1]);
02523 elem->num = atoi (words[2]);
02524 elem->nprops = 0;
02525
02526
02527 if (plyfile->nelems == 0)
02528 plyfile->elems = (PlyElement **) myalloc (sizeof (PlyElement *));
02529 else
02530 plyfile->elems = (PlyElement **) realloc (plyfile->elems,
02531 sizeof (PlyElement *) * (plyfile->nelems + 1));
02532
02533
02534 plyfile->elems[plyfile->nelems] = elem;
02535 plyfile->nelems++;
02536 }
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549 int get_prop_type(char *type_name)
02550 {
02551 int i;
02552
02553 for (i = PLY_START_TYPE + 1; i < PLY_END_TYPE; i++)
02554 if (equal_strings (type_name, type_names[i]))
02555 return (i);
02556
02557
02558 return (0);
02559 }
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571 void add_property (PlyFile *plyfile, char **words, int )
02572 {
02573 PlyProperty *prop;
02574 PlyElement *elem;
02575
02576
02577
02578 prop = (PlyProperty *) myalloc (sizeof (PlyProperty));
02579
02580 if (equal_strings (words[1], "list")) {
02581 prop->count_external = get_prop_type (words[2]);
02582 prop->external_type = get_prop_type (words[3]);
02583 prop->name = strdup (words[4]);
02584 prop->is_list = 1;
02585 }
02586 else {
02587 prop->external_type = get_prop_type (words[1]);
02588 prop->name = strdup (words[2]);
02589 prop->is_list = 0;
02590 }
02591
02592
02593
02594 elem = plyfile->elems[plyfile->nelems - 1];
02595
02596 if (elem->nprops == 0)
02597 elem->props = (PlyProperty **) myalloc (sizeof (PlyProperty *));
02598 else
02599 elem->props = (PlyProperty **) realloc (elem->props,
02600 sizeof (PlyProperty *) * (elem->nprops + 1));
02601
02602 elem->props[elem->nprops] = prop;
02603 elem->nprops++;
02604 }
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615 void add_comment (PlyFile *plyfile, char *line)
02616 {
02617 int i;
02618
02619
02620 i = 7;
02621 while (line[i] == ' ' || line[i] == '\t')
02622 i++;
02623
02624 ply_put_comment (plyfile, &line[i]);
02625 }
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
02636 void add_obj_info (PlyFile *plyfile, char *line)
02637 {
02638 int i;
02639
02640
02641 i = 8;
02642 while (line[i] == ' ' || line[i] == '\t')
02643 i++;
02644
02645 ply_put_obj_info (plyfile, &line[i]);
02646 }
02647
02648
02649
02650
02651
02652
02653 void copy_property(PlyProperty *dest, PlyProperty *src)
02654 {
02655 dest->name = strdup (src->name);
02656 dest->external_type = src->external_type;
02657 dest->internal_type = src->internal_type;
02658 dest->offset = src->offset;
02659
02660 dest->is_list = src->is_list;
02661 dest->count_external = src->count_external;
02662 dest->count_internal = src->count_internal;
02663 dest->count_offset = src->count_offset;
02664 }
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676 char *my_alloc(int size, int lnum, const char *fname)
02677 {
02678 char *ptr;
02679
02680 ptr = (char *) malloc (size);
02681
02682 if (ptr == 0)
02683 fprintf( stderr, "Memory allocation bombed on line %d in %s\n",
02684 lnum, fname);
02685
02686 return (ptr);
02687 }
02688