about summary refs log tree commit diff
path: root/analyzer/pamtable.c
diff options
context:
space:
mode:
Diffstat (limited to 'analyzer/pamtable.c')
-rw-r--r--analyzer/pamtable.c89
1 files changed, 73 insertions, 16 deletions
diff --git a/analyzer/pamtable.c b/analyzer/pamtable.c
index 2835469a..333eff69 100644
--- a/analyzer/pamtable.c
+++ b/analyzer/pamtable.c
@@ -15,12 +15,16 @@
 #include "mallocvar.h"
 #include "nstring.h"
 
+enum Style {STYLE_BASIC, STYLE_TUPLE};
+
 struct CmdlineInfo {
     /* All the information the user supplied in the command line,
        in a form easy for the program to use.
     */
     const char * inputFileName;  /* Name of input file */
-    unsigned int  verbose;
+    enum Style   outputStyle;
+    unsigned int hex;
+    unsigned int verbose;
 };
 
 
@@ -29,16 +33,19 @@ parseCommandLine(int argc, const char ** const argv,
                  struct CmdlineInfo * const cmdlineP) {
 
     optEntry * option_def;
-        /* Instructions to OptParseOptions3 on how to parse our options.
+        /* Instructions to OptParseOptions4 on how to parse our options.
          */
     optStruct3 opt;
 
     unsigned int option_def_index;
+    unsigned int tuple;
 
     MALLOCARRAY(option_def, 100);
 
     option_def_index = 0;   /* incremented by OPTENT3 */
 
+    OPTENT3(0,   "tuple",     OPT_FLAG,  NULL, &tuple,               0);
+    OPTENT3(0,   "hex",       OPT_FLAG,  NULL, &cmdlineP->hex,       0);
     OPTENT3(0,   "verbose",   OPT_FLAG,  NULL, &cmdlineP->verbose,   0);
         /* For future expansion */
 
@@ -46,9 +53,17 @@ parseCommandLine(int argc, const char ** const argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We have no parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+    pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
+    if (tuple && cmdlineP->hex)
+        pm_error("-hex is invalid with -tuple");
+
+    if (tuple)
+        cmdlineP->outputStyle = STYLE_TUPLE;
+    else
+        cmdlineP->outputStyle = STYLE_BASIC;
+
     if (argc-1 > 1)
         pm_error("Too many arguments (%d).  File name is the only argument.",
                  argc-1);
@@ -74,12 +89,27 @@ typedef struct {
     const char * interTupleGutter;
        /* What we print between tuples within a row */
 
+    const char * rowStartString;
+       /* What we print at the beginning of each row */
+
+    const char * rowEndString;
+       /* What we print at the end of each row */
+
 } Format;
 
 
 
+static double const
+log16(double const arg) {
+
+    return log(arg)/log(16);
+}
+
+
+
 static const char *
-sampleFormat(const struct pam * const pamP) {
+basicSampleFormat(const struct pam * const pamP,
+                  bool               const wantHex) {
 /*----------------------------------------------------------------------------
    The printf format string for a single sample in the output table.
 
@@ -87,11 +117,21 @@ sampleFormat(const struct pam * const pamP) {
 
    This format does not include any spacing between samples.
 -----------------------------------------------------------------------------*/
-    unsigned int const decimalWidth = ROUNDU(ceil(log10(pamP->maxval + 1)));
-
+    unsigned int cipherWidth;
+    char         formatSpecifier;
+    const char * flag;
     const char * retval;
 
-    pm_asprintf(&retval, "%%%uu", decimalWidth);
+    if (wantHex) {
+        formatSpecifier = 'x';
+        cipherWidth     = ROUNDU(ceil(log16(pamP->maxval + 1)));
+        flag            = "0";
+    } else {
+        formatSpecifier = 'u';
+        cipherWidth     = ROUNDU(ceil(log10(pamP->maxval + 1)));
+        flag            = "";
+    }
+    pm_asprintf(&retval, "%%%s%u%c", flag, cipherWidth, formatSpecifier);
 
     return retval;
 }
@@ -100,13 +140,26 @@ sampleFormat(const struct pam * const pamP) {
 
 static void
 makeFormat(const struct pam * const pamP,
+           enum Style         const outputStyle,
+           bool               const wantHex,
            Format *           const formatP) {
 
-    formatP->sampleFmt = sampleFormat(pamP);
-
-    formatP->interSampleGutter = " ";
-
-    formatP->interTupleGutter = pamP->depth > 1 ? "|" : " ";
+    switch (outputStyle) {
+      case STYLE_BASIC:
+          formatP->sampleFmt         = basicSampleFormat(pamP, wantHex);
+          formatP->interSampleGutter = " ";
+          formatP->interTupleGutter  = pamP->depth > 1 ? "|" : " ";
+          formatP->rowStartString    = "";
+          formatP->rowEndString      = "\n";
+          break;
+      case STYLE_TUPLE:
+          formatP->sampleFmt         = pm_strdup("%u");
+          formatP->interSampleGutter = ",";
+          formatP->interTupleGutter  = ") (";
+          formatP->rowStartString    = "(";
+          formatP->rowEndString      = ")\n";
+          break;
+    }
 }
 
 
@@ -127,6 +180,8 @@ printRow(const struct pam * const pamP,
 
     unsigned int col;
 
+    fputs (format.rowStartString, ofP);
+
     for (col = 0; col < pamP->width; ++col) {
         unsigned int plane;
 
@@ -142,7 +197,7 @@ printRow(const struct pam * const pamP,
         }
     }
 
-    fputs("\n", ofP);
+    fputs (format.rowEndString, ofP);
 }
 
 
@@ -150,14 +205,16 @@ printRow(const struct pam * const pamP,
 static void
 printRaster(FILE *             const ifP,
             const struct pam * const pamP,
-            FILE *             const ofP) {
+            FILE *             const ofP,
+            enum Style         const outputStyle,
+            bool               const wantHex) {
 
     Format format;
 
     tuple * inputRow;   /* Row from input image */
     unsigned int row;
 
-    makeFormat(pamP, &format);
+    makeFormat(pamP, outputStyle, wantHex, &format);
 
     inputRow = pnm_allocpamrow(pamP);
 
@@ -189,7 +246,7 @@ main(int argc, const char *argv[]) {
 
     pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type));
 
-    printRaster(ifP, &inpam, stdout);
+    printRaster(ifP, &inpam, stdout, cmdline.outputStyle, cmdline.hex);
 
     pm_close(inpam.file);