about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--analyzer/pamfile.c199
-rw-r--r--doc/HISTORY2
2 files changed, 149 insertions, 52 deletions
diff --git a/analyzer/pamfile.c b/analyzer/pamfile.c
index a7c3c5ac..c85c055c 100644
--- a/analyzer/pamfile.c
+++ b/analyzer/pamfile.c
@@ -10,21 +10,24 @@
 ** implied warranty.
 */
 
+#include <stdbool.h>
 #include "pm_c_util.h"
 #include "mallocvar.h"
 #include "nstring.h"
 #include "shhopt.h"
 #include "pam.h"
 
+enum ReportFormat {RF_HUMAN, RF_COUNT, RF_MACHINE, RF_SIZE};
+
 struct CmdlineInfo {
     /* All the information the user supplied in the command line,
        in a form easy for the program to use.
     */
     int inputFileCount;  /* Number of input files */
     const char ** inputFilespec;  /* Filespecs of input files */
-    unsigned int allimages;  /* -allimages or -count */
-    unsigned int count;      /* -count */
-    unsigned int comments;   /* -comments */
+    unsigned int allimages;
+    unsigned int comments;
+    enum ReportFormat reportFormat;
 };
 
 
@@ -42,17 +45,20 @@ parseCommandLine(int argc, const char ** argv,
     optStruct3 opt;
 
     unsigned int option_def_index;
+    unsigned int countSpec, machineSpec, sizeSpec;
 
     MALLOCARRAY_NOFAIL(option_def, 100);
     
     option_def_index = 0;   /* incremented by OPTENT3 */
     OPTENT3(0,   "allimages", OPT_FLAG,  NULL, &cmdlineP->allimages,   0);
-    OPTENT3(0,   "count",     OPT_FLAG,  NULL, &cmdlineP->count,       0);
+    OPTENT3(0,   "count",     OPT_FLAG,  NULL, &countSpec,             0);
     OPTENT3(0,   "comments",  OPT_FLAG,  NULL, &cmdlineP->comments,    0);
+    OPTENT3(0,   "machine",   OPT_FLAG,  NULL, &machineSpec,           0);
+    OPTENT3(0,   "size",      OPT_FLAG,  NULL, &sizeSpec,              0);
 
     opt.opt_table     = option_def;
-    opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */
-    opt.allowNegNum   = FALSE; /* We have no parms that are negative numbers */
+    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);
         /* Uses and sets argc, argv, and some of *cmdlineP and others */
@@ -60,13 +66,24 @@ parseCommandLine(int argc, const char ** argv,
     cmdlineP->inputFilespec = (const char **)&argv[1];
     cmdlineP->inputFileCount = argc - 1;
 
+    if (machineSpec + sizeSpec + countSpec > 1)
+        pm_error("You can specify only one of -machine, -size, and -count");
+    else if (machineSpec)
+        cmdlineP->reportFormat = RF_MACHINE;
+    else if (sizeSpec)
+        cmdlineP->reportFormat = RF_SIZE;
+    else if (countSpec)
+        cmdlineP->reportFormat = RF_COUNT;
+    else
+        cmdlineP->reportFormat = RF_HUMAN;
+
     free(option_def);
 }
 
 
 
 static void
-dumpHeader(struct pam const pam) {
+dumpHeaderHuman(struct pam const pam) {
 
     switch (pam.format) {
     case PAM_FORMAT:
@@ -108,6 +125,62 @@ dumpHeader(struct pam const pam) {
 
 
 static void
+dumpHeaderMachine(struct pam const pam) {
+
+    const char * formatString;
+    bool plain;
+
+    switch (pam.format) {
+    case PAM_FORMAT:
+        formatString = "PAM";
+        plain = false;
+        break;
+
+	case PBM_FORMAT:
+        formatString = "PBM";
+        plain = TRUE;
+        break;
+
+	case RPBM_FORMAT:
+        formatString = "PBM";
+        plain = false;
+        break;
+
+	case PGM_FORMAT:
+        formatString = "PGM";
+        plain = TRUE;
+        break;
+
+	case RPGM_FORMAT:
+        formatString = "PGM";
+        plain = false;
+        break;
+
+	case PPM_FORMAT:
+        formatString = "PPM";
+        plain = TRUE;
+        break;
+
+	case RPPM_FORMAT:
+        formatString = "PPM";
+        plain = false;        break;
+    }
+
+    printf("%s %s %d %d %d %ld %s\n", formatString,
+           plain ? "PLAIN" : "RAW", pam.width, pam.height,
+           pam.depth, pam.maxval, pam.tuple_type);
+
+}
+
+
+static void
+dumpHeaderSize(struct pam const pam) {
+
+    printf("%d %d\n", pam.width, pam.height);
+}
+
+
+static void
 dumpComments(const char * const comments) {
 
     const char * p;
@@ -124,7 +197,7 @@ dumpComments(const char * const comments) {
         if (*p == '\n')
             startOfLine = TRUE;
         else
-            startOfLine = FALSE;
+            startOfLine = false;
     }
     if (!startOfLine)
         fputc('\n', stdout);
@@ -133,13 +206,35 @@ dumpComments(const char * const comments) {
 
 
 static void
-doOneImage(const char * const name,
-           unsigned int const imageDoneCount,
-           FILE *       const fileP,
-           bool         const allimages,
-           bool         const justCount,
-           bool         const wantComments,
-           bool *       const eofP) {
+readToNextImage(const struct pam * const pamP,
+                bool *             const eofP) {
+
+    tuple * tuplerow;
+    unsigned int row;
+
+    tuplerow = pnm_allocpamrow(pamP);
+
+    for (row = 0; row < pamP->height; ++row)
+        pnm_readpamrow(pamP, tuplerow);
+
+    pnm_freepamrow(tuplerow);
+
+    {
+        int eof;
+        pnm_nextimage(pamP->file, &eof);
+        *eofP = eof;
+    }
+}
+
+
+static void
+doOneImage(const char *      const name,
+           unsigned int      const imageDoneCount,
+           FILE *            const fileP,
+           enum ReportFormat const reportFormat,
+           bool              const allimages,
+           bool              const wantComments,
+           bool *            const eofP) {
                     
     struct pam pam;
     const char * comments;
@@ -149,74 +244,70 @@ doOneImage(const char * const name,
 
     pnm_readpaminit(fileP, &pam, PAM_STRUCT_SIZE(comment_p));
         
-    if (!justCount) {
+    switch (reportFormat) {
+    case RF_COUNT:
+        break;
+    case RF_SIZE:
+        dumpHeaderSize(pam);
+        break;
+    case RF_MACHINE:
+        printf("%s: ", name);
+        dumpHeaderMachine(pam);
+        break;
+    case RF_HUMAN:
         if (allimages)
             printf("%s:\tImage %d:\t", name, imageDoneCount);
         else 
             printf("%s:\t", name);
-            
-        dumpHeader(pam);
+
+        dumpHeaderHuman(pam);
+
         if (wantComments)
             dumpComments(comments);
     }
     pm_strfree(comments);
 
     pnm_checkpam(&pam, PM_CHECK_BASIC, &checkRetval);
-    if (allimages) {
-        tuple * tuplerow;
-        unsigned int row;
-        
-        tuplerow = pnm_allocpamrow(&pam);
-        
-        for (row = 0; row < pam.height; ++row) 
-            pnm_readpamrow(&pam, tuplerow);
-        
-        pnm_freepamrow(tuplerow);
-        
-        {
-            int eof;
-            pnm_nextimage(fileP, &eof);
-            *eofP = eof;
-        }
-    }
+
+    if (allimages)
+        readToNextImage(&pam, eofP);
 }
 
 
 
 static void
-describeOneFile(const char * const name,
-                FILE *       const fileP,
-                bool         const allimages,
-                bool         const justCount,
-                bool         const wantComments) {
+describeOneFile(const char *      const name,
+                FILE *            const fileP,
+                enum ReportFormat const reportFormat,
+                bool              const allimages,
+                bool              const wantComments) {
 /*----------------------------------------------------------------------------
    Describe one image stream (file).  Its name, for purposes of display,
    is 'name'.  The file is open as *fileP and positioned to the beginning.
 
+   'reportFormat' tells which of the various sets of information we provide.
+
    'allimages' means report on every image in the stream and read all of
    every image from it, as opposed to reading just the header of the first
    image and reporting just on that.
 
-   'justCount' means don't tell anything about the stream except how
-   many images are in it.  Pretty useless without 'allimages'.
-
    'wantComments' means to show the comments from the image header.
-   Meaningless with 'justCount'.
+   Meaningful only when 'reportFormat' is RF_HUMAN.
 -----------------------------------------------------------------------------*/
     unsigned int imageDoneCount;
         /* Number of images we've processed so far */
     bool eof;
     
-    eof = FALSE;
+    eof = false;
     imageDoneCount = 0;
 
     while (!eof && (imageDoneCount < 1 || allimages)) {
         doOneImage(name, imageDoneCount, fileP,
-                   allimages, justCount, wantComments,
+                   reportFormat, allimages, wantComments,
                    &eof);
         ++imageDoneCount;
     }
-    if (justCount)
+    if (reportFormat == RF_COUNT)
         printf("%s:\t%u images\n", name, imageDoneCount);
 }
 
@@ -232,16 +323,20 @@ main(int argc, const char *argv[]) {
     parseCommandLine(argc, argv, &cmdline);
 
     if (cmdline.inputFileCount == 0)
-        describeOneFile("stdin", stdin, cmdline.allimages || cmdline.count,
-                        cmdline.count, cmdline.comments);
+        describeOneFile("stdin", stdin, cmdline.reportFormat,
+                        cmdline.allimages ||
+                            cmdline.reportFormat == RF_COUNT,
+                        cmdline.comments);
     else {
         unsigned int i;
         for (i = 0; i < cmdline.inputFileCount; ++i) {
             FILE * ifP;
             ifP = pm_openr(cmdline.inputFilespec[i]);
-            describeOneFile(cmdline.inputFilespec[i], ifP, 
-                            cmdline.allimages || cmdline.count,
-                            cmdline.count, cmdline.comments);
+            describeOneFile(cmdline.inputFilespec[i], ifP,
+                            cmdline.reportFormat,
+                            cmdline.allimages ||
+                                cmdline.reportFormat == RF_COUNT,
+                            cmdline.comments);
             pm_close(ifP);
 	    }
 	}
diff --git a/doc/HISTORY b/doc/HISTORY
index 0fa19b85..6143ab7e 100644
--- a/doc/HISTORY
+++ b/doc/HISTORY
@@ -6,6 +6,8 @@ CHANGE HISTORY
 
 not yet  BJH  Release 10.86.00
 
+              pamfile: Add -machine and -size .
+
               pamstretch: Reject very large scale factors instead of producing
               incorrect output.