131 lines
5.0 KiB
C
131 lines
5.0 KiB
C
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <stdarg.h>
|
||
|
#include "rply.h"
|
||
|
|
||
|
/* internal function prototypes */
|
||
|
static void error(const char *fmt, ...);
|
||
|
static void help(void);
|
||
|
static void parse_arguments(int argc, char **argv,
|
||
|
e_ply_storage_mode *storage_mode,
|
||
|
const char **iname, const char **oname);
|
||
|
static void setup_callbacks(p_ply iply, p_ply oply);
|
||
|
|
||
|
/* given a format mode, an input file name and an output file name,
|
||
|
* convert input file to output in given format mode */
|
||
|
int main(int argc, char **argv) {
|
||
|
const char *value = NULL;
|
||
|
e_ply_storage_mode storage_mode = PLY_LITTLE_ENDIAN;
|
||
|
const char *iname = NULL, *oname = NULL;
|
||
|
p_ply iply = NULL, oply = NULL;
|
||
|
/* parse command line arguments */
|
||
|
parse_arguments(argc, argv, &storage_mode, &iname, &oname);
|
||
|
/* open input file and make sure we parsed its header */
|
||
|
iply = ply_open(iname, NULL, 0, NULL);
|
||
|
if (!iply) error("Unable to open file '%s'", iname);
|
||
|
if (!ply_read_header(iply)) error("Failed reading '%s' header", iname);
|
||
|
/* create output file */
|
||
|
oply = ply_create(oname, storage_mode, NULL, 0, NULL);
|
||
|
if (!oply) error("Unable to create file '%s'", oname);
|
||
|
/* create elements and properties in output file and
|
||
|
* setup callbacks for them in input file */
|
||
|
setup_callbacks(iply, oply);
|
||
|
/* pass comments and obj_infos from input to output */
|
||
|
value = NULL;
|
||
|
while ((value = ply_get_next_comment(iply, value)))
|
||
|
if (!ply_add_comment(oply, value))
|
||
|
error("Failed adding comments");
|
||
|
value = NULL;
|
||
|
while ((value = ply_get_next_obj_info(iply, value)))
|
||
|
if (!ply_add_obj_info(oply, value))
|
||
|
error("Failed adding comments");
|
||
|
/* write output header */
|
||
|
if (!ply_write_header(oply)) error("Failed writing '%s' header", oname);
|
||
|
/* read input file generating callbacks that pass data to output file */
|
||
|
if (!ply_read(iply)) error("Conversion failed");
|
||
|
/* close up, we are done */
|
||
|
if (!ply_close(iply)) error("Error closing file '%s'", iname);
|
||
|
if (!ply_close(oply)) error("Error closing file '%s'", oname);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* prints an error message and exits */
|
||
|
static void error(const char *fmt, ...) {
|
||
|
va_list ap;
|
||
|
va_start(ap, fmt);
|
||
|
vfprintf(stderr, fmt, ap);
|
||
|
va_end(ap);
|
||
|
fprintf(stderr, "\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
/* prints the help message and exits */
|
||
|
static void help(void) {
|
||
|
error("Usage:\n"
|
||
|
" convert <option> <input> <output>\n"
|
||
|
"Options:\n"
|
||
|
" -a, --ascii: convert to ascii format\n"
|
||
|
" -b, --big-endian: convert to big-endian format\n"
|
||
|
" -l, --little-endian: convert to little-endian format\n");
|
||
|
}
|
||
|
|
||
|
/* parse command line parameters */
|
||
|
static void parse_arguments(int argc, char **argv,
|
||
|
e_ply_storage_mode *storage_mode,
|
||
|
const char **iname, const char **oname) {
|
||
|
if (argc < 4) help();
|
||
|
if (strcmp(argv[1], "--ascii") == 0 ||
|
||
|
strcmp(argv[1], "-a") == 0)
|
||
|
*storage_mode = PLY_ASCII;
|
||
|
else if (strcmp(argv[1], "--little-endian") == 0 ||
|
||
|
strcmp(argv[1], "-l") == 0)
|
||
|
*storage_mode = PLY_LITTLE_ENDIAN;
|
||
|
else if (strcmp(argv[1], "--big-endian") == 0 ||
|
||
|
strcmp(argv[1], "-b") == 0)
|
||
|
*storage_mode = PLY_BIG_ENDIAN;
|
||
|
else help();
|
||
|
*iname = argv[2];
|
||
|
*oname = argv[3];
|
||
|
}
|
||
|
|
||
|
/* read callback */
|
||
|
static int callback(p_ply_argument argument) {
|
||
|
void *pdata;
|
||
|
/* just pass the value from the input file to the output file */
|
||
|
ply_get_argument_user_data(argument, &pdata, NULL);
|
||
|
ply_write((p_ply) pdata, ply_get_argument_value(argument));
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/* prepares the conversion */
|
||
|
static void setup_callbacks(p_ply iply, p_ply oply) {
|
||
|
p_ply_element element = NULL;
|
||
|
/* iterate over all elements in input file */
|
||
|
while ((element = ply_get_next_element(iply, element))) {
|
||
|
p_ply_property property = NULL;
|
||
|
long ninstances = 0;
|
||
|
const char *element_name;
|
||
|
ply_get_element_info(element, &element_name, &ninstances);
|
||
|
/* add this element to output file */
|
||
|
if (!ply_add_element(oply, element_name, ninstances))
|
||
|
error("Unable to add output element '%s'", element_name);
|
||
|
/* iterate over all properties of current element */
|
||
|
while ((property = ply_get_next_property(element, property))) {
|
||
|
const char *property_name;
|
||
|
e_ply_type type, length_type, value_type;
|
||
|
ply_get_property_info(property, &property_name, &type,
|
||
|
&length_type, &value_type);
|
||
|
/* setup input callback for this property */
|
||
|
if (!ply_set_read_cb(iply, element_name, property_name, callback,
|
||
|
oply, 0))
|
||
|
error("Unable to setup input callback for property '%s'",
|
||
|
property_name);
|
||
|
/* add this property to output file */
|
||
|
if (!ply_add_property(oply, property_name, type, length_type,
|
||
|
value_type))
|
||
|
error("Unable to add output property '%s'", property_name);
|
||
|
}
|
||
|
}
|
||
|
}
|