about summary refs log tree commit diff
path: root/analyzer/pamsharpmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'analyzer/pamsharpmap.c')
-rw-r--r--analyzer/pamsharpmap.c188
1 files changed, 188 insertions, 0 deletions
diff --git a/analyzer/pamsharpmap.c b/analyzer/pamsharpmap.c
new file mode 100644
index 00000000..73923ab9
--- /dev/null
+++ b/analyzer/pamsharpmap.c
@@ -0,0 +1,188 @@
+/*----------------------------------------------------------------------------
+                                Pnmsharpness
+------------------------------------------------------------------------------
+
+  Bryan Henderson derived this (January 2004) from the program Pnmsharp
+  by B.W. van Schooten and distributed to Bryan under the Perl
+  Artistic License, as part of the Photopnmtools package.  Bryan placed
+  his modifications in the public domain.
+
+  This is the copyright/license notice from the original:
+
+   Copyright (c) 2002, 2003 by B.W. van Schooten. All rights reserved.
+   This software is distributed under the Perl Artistic License.
+   No warranty. See file 'artistic.license' for more details.
+
+   boris@13thmonkey.org
+   www.13thmonkey.org/~boris/photopnmtools/ 
+-----------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <math.h>
+
+#include "pam.h"
+#include "shhopt.h"
+#include "mallocvar.h"
+
+struct cmdlineInfo {
+    /* All the information the user supplied in the command line,
+       in a form easy for the program to use.
+    */
+    const char *inputFilespec;  /* '-' if stdin */
+    unsigned int context;
+};
+
+
+
+static void
+parseCommandLine ( int argc, char ** argv,
+                   struct cmdlineInfo *cmdlineP ) {
+/*----------------------------------------------------------------------------
+   parse program command line described in Unix standard form by argc
+   and argv.  Return the information in the options as *cmdlineP.  
+
+   If command line is internally inconsistent (invalid options, etc.),
+   issue error message to stderr and abort program.
+
+   Note that the strings we return are stored in the storage that
+   was passed to us as the argv array.  We also trash *argv.
+-----------------------------------------------------------------------------*/
+    optEntry *option_def = malloc(100*sizeof(optEntry));
+        /* Instructions to optParseOptions3 on how to parse our options.
+         */
+    optStruct3 opt;
+
+    unsigned int option_def_index;
+
+    unsigned int contextSpec;
+
+    option_def_index = 0;   /* incremented by OPTENT3 */
+    OPTENT3(0, "context",       OPT_UINT,   &cmdlineP->context,       
+            &contextSpec,         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 */
+
+    optParseOptions3( &argc, argv, opt, sizeof(opt), 0);
+        /* Uses and sets argc, argv, and some of *cmdlineP and others. */
+
+    if (!contextSpec)
+        cmdlineP->context = 1;
+
+    if (cmdlineP->context < 1)
+        pm_error("-context must be at least 1");
+
+
+    if (argc-1 > 1)
+        pm_error("The only argument is the input file name");
+    else if (argc-1 < 1)
+        cmdlineP->inputFilespec = "-";
+    else
+        cmdlineP->inputFilespec = argv[1];
+}
+
+
+
+static void
+makeSharpnessPixel(struct pam * const pamP,
+                   float *      const sharpness,
+                   tuple        const sharpnessTuple) {
+
+    unsigned int plane;
+    for (plane = 0; plane < pamP->depth; ++plane)
+        sharpnessTuple[plane] = 
+            (sample)(sharpness[plane] * pamP->maxval + 0.5);
+}
+
+
+
+static void
+makeBlackTuplen(struct pam * const pamP,
+                tuplen       const tuplen) {
+
+    unsigned int plane;
+    for (plane = 0; plane < pamP->depth; ++plane)
+        tuplen[plane] = 0.0;
+}
+
+
+
+static void
+makeBlackRown(struct pam * const pamP,
+              tuplen *     const tuplenrow) {
+
+    unsigned int col;
+    for (col = 0; col < pamP->width; ++col)
+        makeBlackTuplen(pamP, tuplenrow[col]);
+}
+
+
+
+int
+main(int argc, char **argv) {
+
+    struct cmdlineInfo cmdline;
+    FILE * ifP;
+    tuplen ** tuplenarray;
+    struct pam inpam;
+    struct pam mappam;
+    tuple ** map;
+    int row;
+    float * sharpness;
+
+	pnm_init(&argc, argv);
+
+    parseCommandLine(argc, argv, &cmdline);
+
+    ifP = pm_openr(cmdline.inputFilespec);
+
+	tuplenarray = pnm_readpamn(ifP, &inpam, sizeof(inpam));
+
+    mappam = inpam;
+    mappam.file = stdout;
+    mappam.maxval = 255;
+
+    MALLOCARRAY_NOFAIL(sharpness, inpam.depth);
+            
+    map = pnm_allocpamarray(&mappam);
+    makeBlackRown(&inpam, tuplenarray[0]);
+    for (row = 1; row < inpam.height-1; ++row) {
+        int col;
+        makeBlackTuplen(&inpam, tuplenarray[row][0]);
+        for (col = 1; col < inpam.width-1; ++col) {
+            int dy;
+            unsigned int plane;
+            
+            for (plane = 0; plane < inpam.depth; ++plane)
+                sharpness[plane] = 0.0;
+
+            for (dy = -1; dy <= 1; ++dy) {
+                int dx;
+                for (dx = -1; dx <= 1; ++dx) {
+                    if (dx != 0 || dy != 0) {
+                        unsigned int plane;
+                        for (plane = 0; plane < inpam.depth; ++plane) {
+                            samplen const sampleval = 
+                                tuplenarray[row][col][plane];
+                            samplen const sampleval2 = 
+                                tuplenarray[row+dy][col+dx][plane];
+                            sharpness[plane] += fabs(sampleval - sampleval2);
+                        }
+                    }
+                }
+            }
+            makeSharpnessPixel(&mappam, sharpness, map[row][col]);
+        }
+        makeBlackTuplen(&inpam, tuplenarray[row][inpam.width-1]);
+    }
+    makeBlackRown(&inpam, tuplenarray[inpam.height-1]);
+    free(sharpness);
+    
+    pnm_writepam(&mappam, map);
+
+    pnm_freepamarray(map, &mappam);
+	pnm_freepamarrayn(tuplenarray, &inpam);
+
+	return 0;
+}