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