about summary refs log tree commit diff
path: root/editor/pnmalias.c
diff options
context:
space:
mode:
Diffstat (limited to 'editor/pnmalias.c')
-rw-r--r--editor/pnmalias.c250
1 files changed, 250 insertions, 0 deletions
diff --git a/editor/pnmalias.c b/editor/pnmalias.c
new file mode 100644
index 00000000..36b41ce4
--- /dev/null
+++ b/editor/pnmalias.c
@@ -0,0 +1,250 @@
+/* pnmmalias.c - antialias a portable anymap.
+**
+** Copyright (C) 1992 by Alberto Accomazzi, Smithsonian Astrophysical
+** Observatory.
+**
+** 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 "pnm.h"
+
+int
+main(int argc, char * argv[] ) {
+    FILE* ifp;
+    xel* xelrow[3];
+    xel* newxelrow;
+    pixel bgcolorppm, fgcolorppm;
+    register xel* xpP;
+    register xel* xP;
+    register xel* xnP;
+    register xel* nxP;
+    xel bgcolor, fgcolor;
+    int argn, rows, cols, format, newformat, bgonly, fgonly;
+    int bgalias, fgalias;
+    int row;
+    double fmask[9], weight;
+    xelval maxval;
+    xelval newmaxval;
+    const char* const usage = "[-bgcolor <color>] [-fgcolor <color>] [-bonly] [-fonly] [-balias] [-falias] [-weight <w>] [pnmfile]";
+
+    pnm_init( &argc, argv );
+
+    bgonly = fgonly = 0;
+    bgalias = fgalias = 0;
+    weight = 1./3.;
+    argn = 1;
+    PPM_ASSIGN( bgcolorppm, 0, 0, 0);
+    PPM_ASSIGN( fgcolorppm, 0, 0, 0);
+
+    while ( argn < argc && argv[argn][0] == '-' )
+        {
+        if ( pm_keymatch( argv[argn], "-fgcolor", 3 ) ) 
+        {
+        if ( ++argn >= argc ) 
+        pm_usage( usage );
+        else 
+        fgcolorppm = ppm_parsecolor( argv[argn], PPM_MAXMAXVAL );
+        }
+        else if ( pm_keymatch( argv[argn], "-bgcolor", 3 ) ) 
+        {
+        if ( ++argn >= argc ) 
+        pm_usage( usage );
+        else 
+        bgcolorppm = ppm_parsecolor( argv[argn], PPM_MAXMAXVAL );
+        }
+        else if ( pm_keymatch( argv[argn], "-weight", 2 ) ) 
+        {
+        if ( ++argn >= argc ) 
+        pm_usage( usage );
+        else if ( sscanf( argv[argn], "%lf", &weight ) != 1 )
+            pm_usage( usage );
+        else if ( weight >= 1. || weight <= 0. )
+        {
+        pm_message( "weight factor w must be 0.0 < w < 1.0" );
+        pm_usage( usage );
+        }
+        }
+    else if ( pm_keymatch( argv[argn], "-bonly", 3 ) )
+        bgonly = 1;
+    else if ( pm_keymatch( argv[argn], "-fonly", 3 ) )
+        fgonly = 1;
+    else if ( pm_keymatch( argv[argn], "-balias", 3 ) )
+        bgalias = 1;
+    else if ( pm_keymatch( argv[argn], "-falias", 3 ) )
+        fgalias = 1;
+    else if ( pm_keymatch( argv[argn], "-bfalias", 3 ) )
+        bgalias = fgalias = 0;
+    else if ( pm_keymatch( argv[argn], "-fbalias", 3 ) )
+        bgalias = fgalias = 0;
+        else
+            pm_usage( usage );
+        ++argn;
+        }
+
+    if ( argn != argc )
+    {
+    ifp = pm_openr( argv[argn] );
+    ++argn;
+    }
+    else
+    ifp = stdin;
+
+    if ( argn != argc )
+    pm_usage( usage );
+
+    /* normalize mask elements */
+    fmask[4] = weight;
+    fmask[0] = fmask[1] = fmask[2] = fmask[3] = ( 1.0 - weight ) / 8.0;
+    fmask[5] = fmask[6] = fmask[7] = fmask[8] = ( 1.0 - weight ) / 8.0;
+
+    pnm_readpnminit( ifp, &cols, &rows, &maxval, &format );
+   
+    xelrow[0] = pnm_allocrow( cols );
+    xelrow[1] = pnm_allocrow( cols );
+    xelrow[2] = pnm_allocrow( cols );
+    newxelrow = pnm_allocrow( cols );
+
+    /* Promote PBM files to PGM. */
+    if ( PNM_FORMAT_TYPE(format) == PBM_TYPE ) {
+        newformat = PGM_TYPE;
+        newmaxval = PGM_MAXMAXVAL;
+        pm_message( "promoting from PBM to PGM" );
+    } else {
+        newformat = format;
+        newmaxval = maxval;
+    }
+
+    /* Figure out foreground pixel value if none was given */
+    if (PPM_GETR(fgcolorppm) == 0 && PPM_GETG(fgcolorppm) == 0 && 
+        PPM_GETB(fgcolorppm) == 0 ) {
+        if ( PNM_FORMAT_TYPE(newformat) == PGM_TYPE )
+            PNM_ASSIGN1( fgcolor, newmaxval );
+        else 
+            PPM_ASSIGN( fgcolor, newmaxval, newmaxval, newmaxval );
+    } else {
+        if ( PNM_FORMAT_TYPE(newformat) == PGM_TYPE )
+            PNM_ASSIGN1( fgcolor, PPM_GETR( fgcolorppm ) );
+        else 
+            fgcolor = fgcolorppm;
+    }
+
+    if (PPM_GETR(bgcolorppm) != 0 || PPM_GETG(bgcolorppm) != 0 || 
+        PPM_GETB(bgcolorppm) != 0 ) {
+        if ( PNM_FORMAT_TYPE(newformat) == PGM_TYPE )
+            PNM_ASSIGN1( bgcolor, PPM_GETR( bgcolorppm) );
+        else 
+            bgcolor = bgcolorppm;
+    } else {
+        if ( PNM_FORMAT_TYPE(newformat) == PGM_TYPE )
+            PNM_ASSIGN1( bgcolor, 0 );
+        else 
+            PPM_ASSIGN( bgcolor, 0, 0, 0 );
+    }
+
+
+    pnm_readpnmrow( ifp, xelrow[0], cols, newmaxval, format );
+    pnm_readpnmrow( ifp, xelrow[1], cols, newmaxval, format );
+    pnm_writepnminit( stdout, cols, rows, newmaxval, newformat, 0 );
+    pnm_writepnmrow( stdout, xelrow[0], cols, newmaxval, newformat, 0 );
+
+    for ( row = 1; row < rows - 1; ++row ) {
+        int col;
+        int value, valuer, valueg, valueb;
+
+        pnm_readpnmrow( ifp, xelrow[(row+1)%3], cols, newmaxval, format );
+        newxelrow[0] = xelrow[row%3][0];
+        
+        for ( col = 1, xpP = (xelrow[(row-1)%3] + 1), xP = (xelrow[row%3] + 1),
+                  xnP = (xelrow[(row+1)%3] + 1), nxP = (newxelrow+1); 
+              col < cols - 1; ++col, ++xpP, ++xP, ++xnP, ++nxP ) {
+
+            int fgflag, bgflag;
+
+            /* Reset flags if anti-aliasing is to be done on foreground
+             * or background pixels only */
+            if ( ( bgonly && PNM_EQUAL( *xP, fgcolor ) ) ||
+                 ( fgonly && PNM_EQUAL( *xP, bgcolor ) ) ) 
+                bgflag = fgflag = 0;
+            else {
+                /* Do anti-aliasing here: see if pixel is at the border of a
+                 * background or foreground stepwise side */
+                bgflag = 
+                    (PNM_EQUAL(*xpP,bgcolor) && PNM_EQUAL(*(xP+1),bgcolor)) ||
+                    (PNM_EQUAL(*(xP+1),bgcolor) && PNM_EQUAL(*xnP,bgcolor)) ||
+                    (PNM_EQUAL(*xnP,bgcolor) && PNM_EQUAL(*(xP-1),bgcolor)) ||
+                    (PNM_EQUAL(*(xP-1),bgcolor) && PNM_EQUAL(*xpP,bgcolor));
+                fgflag = 
+                    (PNM_EQUAL(*xpP,fgcolor) && PNM_EQUAL(*(xP+1),fgcolor)) ||
+                    (PNM_EQUAL(*(xP+1),fgcolor) && PNM_EQUAL(*xnP,fgcolor)) ||
+                    (PNM_EQUAL(*xnP,fgcolor) && PNM_EQUAL(*(xP-1),fgcolor)) ||
+                    (PNM_EQUAL(*(xP-1),fgcolor) && PNM_EQUAL(*xpP,fgcolor)); 
+            }
+            if ( ( bgflag && bgalias ) || ( fgflag && fgalias ) || 
+                 ( bgflag && fgflag ) )
+                switch( PNM_FORMAT_TYPE( newformat ) ) {   
+                case PGM_TYPE:
+                    value = PNM_GET1(*(xpP-1)) * fmask[0] +
+                        PNM_GET1(*(xpP  )) * fmask[1] + 
+                        PNM_GET1(*(xpP+1)) * fmask[2] +
+                        PNM_GET1(*(xP -1)) * fmask[3] +
+                        PNM_GET1(*(xP   )) * fmask[4] +
+                        PNM_GET1(*(xP +1)) * fmask[5] +
+                        PNM_GET1(*(xnP-1)) * fmask[6] +
+                        PNM_GET1(*(xnP  )) * fmask[7] +
+                        PNM_GET1(*(xnP+1)) * fmask[8] +
+                        0.5;
+                    PNM_ASSIGN1( *nxP, value );
+                    break;
+                default:
+                    valuer= PPM_GETR(*(xpP-1)) * fmask[0] +
+                        PPM_GETR(*(xpP  )) * fmask[1] + 
+                        PPM_GETR(*(xpP+1)) * fmask[2] +
+                        PPM_GETR(*(xP -1)) * fmask[3] +
+                        PPM_GETR(*(xP   )) * fmask[4] +
+                        PPM_GETR(*(xP +1)) * fmask[5] +
+                        PPM_GETR(*(xnP-1)) * fmask[6] +
+                        PPM_GETR(*(xnP  )) * fmask[7] +
+                        PPM_GETR(*(xnP+1)) * fmask[8] +
+                        0.5;
+                    valueg= PPM_GETG(*(xpP-1)) * fmask[0] +
+                        PPM_GETG(*(xpP  )) * fmask[1] + 
+                        PPM_GETG(*(xpP+1)) * fmask[2] +
+                        PPM_GETG(*(xP -1)) * fmask[3] +
+                        PPM_GETG(*(xP   )) * fmask[4] +
+                        PPM_GETG(*(xP +1)) * fmask[5] +
+                        PPM_GETG(*(xnP-1)) * fmask[6] +
+                        PPM_GETG(*(xnP  )) * fmask[7] +
+                        PPM_GETG(*(xnP+1)) * fmask[8] +
+                        0.5;
+                    valueb= PPM_GETB(*(xpP-1)) * fmask[0] +
+                        PPM_GETB(*(xpP  )) * fmask[1] + 
+                        PPM_GETB(*(xpP+1)) * fmask[2] +
+                        PPM_GETB(*(xP -1)) * fmask[3] +
+                        PPM_GETB(*(xP   )) * fmask[4] +
+                        PPM_GETB(*(xP +1)) * fmask[5] +
+                        PPM_GETB(*(xnP-1)) * fmask[6] +
+                        PPM_GETB(*(xnP  )) * fmask[7] +
+                        PPM_GETB(*(xnP+1)) * fmask[8] +
+                        0.5;
+                    PPM_ASSIGN( *nxP, valuer, valueg, valueb );
+                    break;
+                }
+            else
+                *nxP = *xP;
+        }
+
+        newxelrow[cols-1] = xelrow[row%3][cols-1];
+        pnm_writepnmrow( stdout, newxelrow, cols, newmaxval, newformat, 0 );
+    }
+        
+    pnm_writepnmrow( stdout, xelrow[row%3], cols, newmaxval, newformat, 0 );
+    
+    pm_close( ifp );
+    exit ( 0 );
+}
+