about summary refs log tree commit diff
path: root/editor/pgmenhance.c
diff options
context:
space:
mode:
Diffstat (limited to 'editor/pgmenhance.c')
-rw-r--r--editor/pgmenhance.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/editor/pgmenhance.c b/editor/pgmenhance.c
new file mode 100644
index 00000000..83670568
--- /dev/null
+++ b/editor/pgmenhance.c
@@ -0,0 +1,112 @@
+/* pgmenhance.c - edge-enhance a portable graymap
+**
+** Copyright (C) 1989, 1991 by Jef Poskanzer.
+**
+** Permission to use, copy, modify, and distribute this software and its
+** documentation for any purpose and without fee is hereby granted, provided
+** that the above copyright notice appear in all copies and that both that
+** copyright notice and this permission notice appear in supporting
+** documentation.  This software is provided "as is" without express or
+** implied warranty.
+*/
+
+#include "pgm.h"
+
+int
+main(int argc, char * argv[] ) {
+    FILE* ifp;
+    gray* prevrow;
+    gray* thisrow;
+    gray* nextrow;
+    gray* temprow;
+    gray* newrow;
+    int argn, n, rows, cols, row, col;
+    float phi, omphi;
+    gray maxval;
+    int format;
+    const char* const usage = "[-N] [pgmfile]  ( 1 <= N <= 9, default = 9 )";
+
+    pgm_init( &argc, argv );
+
+    argn = 1;
+    n = 9;
+
+    if ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) {
+        if ( sscanf( &(argv[argn][1]), "%d", &n ) != 1 )
+            pm_usage( usage );
+        if ( n < 1 || n > 9 )
+            pm_usage( usage );
+        ++argn;
+    }
+
+    if ( argn != argc ) {
+        ifp = pm_openr( argv[argn] );
+        ++argn;
+    } else
+        ifp = stdin;
+
+    if ( argn != argc )
+        pm_usage( usage );
+
+    pgm_readpgminit( ifp, &cols, &rows, &maxval, &format );
+    prevrow = pgm_allocrow( cols );
+    thisrow = pgm_allocrow( cols );
+    nextrow = pgm_allocrow( cols );
+
+    pgm_writepgminit( stdout, cols, rows, maxval, 0 );
+    newrow = pgm_allocrow( cols );
+
+    /* The edge enhancing technique is taken from Philip R. Thompson's "xim"
+    ** program, which in turn took it from section 6 of "Digital Halftones by
+    ** Dot Diffusion", D. E. Knuth, ACM Transaction on Graphics Vol. 6, No. 4,
+    ** October 1987, which in turn got it from two 1976 papers by J. F. Jarvis
+    ** et. al.
+    */
+    phi = n / 10.0;
+    omphi = 1.0 - phi;
+
+    /* First row. */
+    pgm_readpgmrow( ifp, thisrow, cols, maxval, format );
+    pgm_writepgmrow( stdout, thisrow, cols, maxval, 0 );
+    pgm_readpgmrow( ifp, nextrow, cols, maxval, format );
+
+    /* Other rows. */
+    for ( row = 1; row < rows - 1; row++ ) {
+        temprow = prevrow;
+        prevrow = thisrow;
+        thisrow = nextrow;
+        nextrow = temprow;
+        pgm_readpgmrow( ifp, nextrow, cols, maxval, format );
+        
+        newrow[0] = thisrow[0];
+        for (col = 1; col < cols - 1; col++) {
+            /* Compute the sum of the neighborhood. */
+            long sum, newval;
+            sum =
+                (long) prevrow[col-1] + (long) prevrow[col] +
+                (long) prevrow[col+1] +
+                (long) thisrow[col-1] + (long) thisrow[col] +
+                (long) thisrow[col+1] +
+                (long) nextrow[col-1] + (long) nextrow[col] +
+                (long) nextrow[col+1];
+            /* Now figure new value. */
+            newval = ( ( thisrow[col] - phi * sum / 9 ) / omphi + 0.5 );
+            if ( newval < 0 )
+                newrow[col] = 0;
+            else if ( newval > maxval )
+                newrow[col] = maxval;
+            else
+                newrow[col] = newval;
+        }
+        newrow[cols - 1] = thisrow[cols - 1];
+        pgm_writepgmrow( stdout, newrow, cols, maxval, 0 );
+    }
+    pm_close( ifp );
+    
+    /* Last row. */
+    pgm_writepgmrow( stdout, nextrow, cols, maxval, 0 );
+
+    pm_close( stdout );
+
+    exit( 0 );
+}