Revision: 65120
          http://sourceforge.net/p/brlcad/code/65120
Author:   starseeker
Date:     2015-05-30 19:42:02 +0000 (Sat, 30 May 2015)
Log Message:
-----------
Add an example of dsp_add_opt.c using the experimental libbu opt API.  Looks a 
bit too simple to make a really good test - should probably experiment with rt 
for a real stress test.

Modified Paths:
--------------
    brlcad/trunk/src/util/CMakeLists.txt

Added Paths:
-----------
    brlcad/trunk/src/util/dsp_add_opt.c

Modified: brlcad/trunk/src/util/CMakeLists.txt
===================================================================
--- brlcad/trunk/src/util/CMakeLists.txt        2015-05-30 19:40:21 UTC (rev 
65119)
+++ brlcad/trunk/src/util/CMakeLists.txt        2015-05-30 19:42:02 UTC (rev 
65120)
@@ -93,6 +93,9 @@
 # ignore it for now
 CMAKEFILES(test_bu_arg_parse.c)
 
+# LIBBU advance option handling test
+BRLCAD_ADDEXEC(dsp_add_opt dsp_add_opt.c libbu NO_INSTALL)
+
 # a new admin file
 BRLCAD_ADDEXEC(admin-db "admin-db.cpp;bu_arg_parse.cpp" "libbu;librt" 
NO_INSTALL)
 

Added: brlcad/trunk/src/util/dsp_add_opt.c
===================================================================
--- brlcad/trunk/src/util/dsp_add_opt.c                         (rev 0)
+++ brlcad/trunk/src/util/dsp_add_opt.c 2015-05-30 19:42:02 UTC (rev 65120)
@@ -0,0 +1,319 @@
+/*                       D S P _ A D D . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2004-2014 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ */
+/** @file util/dsp_add.c
+ *
+ * add 2 files of network unsigned shorts
+ *
+ * Options
+ * h help
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <sys/stat.h>
+#include "bio.h"
+
+#include "vmath.h"
+#include "bu/getopt.h"
+#include "bu/malloc.h"
+#include "bu/log.h"
+#include "bu/opt.h"
+#include "bu/cv.h"
+#include "bn.h"
+
+
+/* declarations to support use of bu_getopt() system call */
+static const char usage[] = "Usage: dsp_add [opts] dsp_1 dsp_2 > dsp_3\n";
+
+enum dsp_add_enums {DSP_HELP};
+struct bu_opt_desc dsp_opt_desc[3] = {
+    {DSP_HELP, 0, 0, "h", "help", NULL, "-h", "--help", "Print help and exit"},
+    {DSP_HELP, 0, 0, "?", "",     NULL, "-?", "", ""},
+    BU_OPT_DESC_NULL
+};
+
+/* purpose: combine two dsp files
+ *
+ * description: Combines two dsp files (which are binary files
+ * comprised of network unsigned shorts).  The two files must be of
+ * identical size.  The result, written to stdout, is a file where
+ * each cell's height is the total of the heights of the same cell
+ * in the input files.
+ *
+ * See the BRL-CAD wiki for a tutorial on using dsp's.
+ *
+ * see_also: dsp(5) asc2dsp(1) cv(1)
+ *
+ * opt: -h brief help
+ *
+ * opt: -? brief help
+ *
+ */
+
+#define ADD_STYLE_INT 0
+#define ADD_STYLE_FLOAT 1
+
+static int style = ADD_STYLE_INT;
+
+/*
+ * tell user how to invoke this program, then exit
+ */
+static void
+print_usage()
+{
+    const char *help = bu_opt_describe(dsp_opt_desc, NULL);
+    bu_log(usage);
+    bu_log("Options:\n%s\n", help);
+    bu_free((char *)help, "help str");
+    bu_exit (1, NULL);
+}
+
+
+/*
+ * Parse command line flags
+ */
+struct bu_ptbl *
+parse_args(int ac, char *av[])
+{
+    size_t i = 0;
+    struct bu_ptbl *results;
+    (void)bu_opt_parse(&results, NULL, ac, (const char **)av, dsp_opt_desc);
+    bu_opt_compact(results);
+
+    for (i = 0; i < BU_PTBL_LEN(results); i++) {
+       struct bu_opt_data *d = (struct bu_opt_data *)BU_PTBL_GET(results, i);
+       if (!d->valid || !d->name || !d->desc) continue;
+       switch(d->desc->shortopt[0]) {
+           default:
+               bu_opt_data_free_tbl(results);
+               print_usage();
+       }
+    }
+
+    return results;
+}
+
+
+static void
+swap_bytes(unsigned short *buf, unsigned long count)
+{
+    unsigned short *p;
+
+    for (p = &buf[count-1]; p >= buf; p--)
+       *p = ((*p << 8) & 0x0ff00) | (*p >> 8);
+}
+
+
+/*
+ * Perform floating point addition and re-normalization of the data.
+ */
+static void
+add_float(unsigned short *buf1, unsigned short *buf2, unsigned long count)
+{
+    unsigned short *p, *q, *e;
+    double *dbuf, *d;
+    double min, max, k;
+
+    dbuf = (double *)bu_malloc(sizeof(double) * count, "buffer of double");
+
+    min = MAX_FASTF;
+    max = -MAX_FASTF;
+    e = &buf1[count];
+
+    /* add everything, keeping track of the min/max values found */
+    for (d = dbuf, p = buf1, q = buf2; p < e; p++, q++, d++) {
+       *d = *p + *q;
+       if (*d > max) max = *d;
+       if (*d < min) min = *d;
+    }
+
+    /* now we convert back to unsigned shorts in the range 1 .. 65535 */
+
+    k = 65534.0 / (max - min);
+
+    bu_log("min: %g scale: %g\n", min - k, k);
+
+    for (d = dbuf, p = buf1, q = buf2; p < e; p++, q++, d++)
+       *p = (unsigned short)  ((*d - min) * k) + 1;
+
+    bu_free(dbuf, "buffer of double");
+}
+
+
+/*
+ * Perform simple integer addition to the input streams.
+ * Issue warning on overflow.
+ *
+ * Result:     buf1 contents modified
+ */
+static void
+add_int(unsigned short *buf1, unsigned short *buf2, unsigned long count)
+{
+    int int_value;
+    unsigned long i;
+    unsigned short s;
+
+    for (i = 0; i < count; i++) {
+       int_value = buf1[i] + buf2[i];
+       s = (unsigned short)int_value;
+
+       if (s != int_value) {
+           bu_log("overflow (%d+%d) == %d at %lu\n",
+                  buf1[i], buf2[i], int_value, i);
+       }
+       buf1[i] = s;
+    }
+
+}
+
+
+/*
+ * Call parse_args to handle command line arguments first, then
+ * process input.
+ */
+int
+main(int ac, char *av[])
+{
+    struct bu_opt_data *non_opts;
+    struct bu_ptbl *results;
+    FILE *in1, *in2;
+    unsigned short *buf1, *buf2;
+    size_t count;
+    int in_cookie, out_cookie;
+    int conv;
+    struct stat sb;
+    size_t ret;
+    const char *f1, *f2;
+
+    if (ac < 2)
+       print_usage();
+
+    if (isatty(fileno(stdout))) {
+       bu_log("Error: Must redirect standard output\n");
+       print_usage();
+    }
+
+    results = parse_args(ac, av);
+    non_opts = bu_opt_find(BU_NON_OPTS, results);
+
+    if (!non_opts->args || BU_PTBL_LEN(non_opts->args) < 2) {
+       bu_log("Error: No files specified\n");
+       print_usage();
+    }
+
+    /* Open the files */
+    f1 = bu_opt_data_arg(non_opts, 0);
+    f2 = bu_opt_data_arg(non_opts, 1);
+
+    in1 = fopen(f1, "r");
+    if (!in1) {
+       perror(f1);
+       return -1;
+    }
+
+    if (fstat(fileno(in1), &sb)) {
+       perror(f1);
+       fclose(in1);
+       return -1;
+    }
+
+    count = sb.st_size;
+    buf1 = (unsigned short *)bu_malloc((size_t)sb.st_size, "buf1");
+
+    in2 = fopen(f2, "r");
+    if (!in2) {
+       perror(f2);
+       fclose(in1);
+       return -1;
+    }
+
+    if (fstat(fileno(in2), &sb)) {
+       perror(f2);
+       fclose(in1);
+       fclose(in2);
+       return -1;
+    }
+
+    if ((size_t)sb.st_size != count) {
+       fclose(in1);
+       fclose(in2);
+       bu_exit(EXIT_FAILURE, "**** ERROR **** file size mis-match\n");
+    }
+
+    buf2 = (unsigned short *)bu_malloc((size_t)sb.st_size, "buf2");
+
+    count = count >> 1; /* convert count of char to count of short */
+
+    /* Read the terrain data */
+    ret = fread(buf1, sizeof(short), count, in1);
+    if (ret < count)
+       perror("fread");
+    fclose(in1);
+
+    ret = fread(buf2, sizeof(short), count, in2);
+    if (ret < count)
+       perror("fread");
+    fclose(in2);
+
+    /* Convert from network to host format */
+    in_cookie = bu_cv_cookie("nus");
+    out_cookie = bu_cv_cookie("hus");
+    conv = (bu_cv_optimize(in_cookie) != bu_cv_optimize(out_cookie));
+
+    if (conv) {
+       swap_bytes(buf1, count);
+       swap_bytes(buf2, count);
+    }
+
+    /* add the two datasets together */
+    switch (style) {
+       case ADD_STYLE_FLOAT    : add_float(buf1, buf2, count); break;
+       case ADD_STYLE_INT      : add_int(buf1, buf2, count); break;
+       default                 : bu_log("Error: Unknown add style\n");
+           break;
+    }
+
+    /* convert back to network format & write out */
+    if (conv) {
+       swap_bytes(buf1, count);
+       swap_bytes(buf2, count);
+    }
+
+    if (fwrite(buf1, sizeof(short), count, stdout) != count) {
+       bu_log("Error writing data\n");
+       return -1;
+    }
+
+    bu_opt_data_free_tbl(results);
+
+    return 0;
+}
+
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */


Property changes on: brlcad/trunk/src/util/dsp_add_opt.c
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to