home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / pnm / pnmalias.c < prev    next >
C/C++ Source or Header  |  1994-01-27  |  8KB  |  256 lines

  1. /* pnmmalias.c - antialias a portable anymap.
  2. **
  3. ** Copyright (C) 1992 by Alberto Accomazzi, Smithsonian Astrophysical
  4. ** Observatory.
  5. **
  6. ** Permission to use, copy, modify, and distribute this software and its
  7. ** documentation for any purpose and without fee is hereby granted, provided
  8. ** that the above copyright notice appear in all copies and that both that
  9. ** copyright notice and this permission notice appear in supporting
  10. ** documentation.  This software is provided "as is" without express or
  11. ** implied warranty.
  12. */
  13.  
  14. #include "pnm.h"
  15.  
  16. int
  17. main( argc, argv )
  18.     int argc;
  19.     char* argv[];
  20.     {
  21.     FILE* ifp;
  22.     xel* xelrow[3];
  23.     xel* newxelrow;
  24.     pixel bgcolorppm, fgcolorppm;
  25.     register xel* xpP;
  26.     register xel* xP;
  27.     register xel* xnP;
  28.     register xel* nxP;
  29.     xel bgcolor, fgcolor;
  30.     int argn, rows, cols, format, newformat, bgflag, fgflag, bgonly, fgonly;
  31.     int bgalias, fgalias;
  32.     register int row, col, i;
  33.     double fmask[9], weight;
  34.     xelval maxval, value, valuer, valueg, valueb;
  35.     char* usage = "[-bgcolor <color>] [-fgcolor <color>] [-bonly] [-fonly] [-balias] [-falias] [-weight <w>] [pnmfile]";
  36.  
  37.     pnm_init( &argc, argv );
  38.  
  39.     bgonly = fgonly = 0;
  40.     bgalias = fgalias = 0;
  41.     weight = 1./3.;
  42.     argn = 1;
  43.     PPM_ASSIGN( bgcolorppm, 0, 0, 0);
  44.     PPM_ASSIGN( fgcolorppm, 0, 0, 0);
  45.  
  46.     while ( argn < argc && argv[argn][0] == '-' )
  47.         {
  48.         if ( pm_keymatch( argv[argn], "-fgcolor", 3 ) ) 
  49.         {
  50.         if ( ++argn >= argc ) 
  51.         pm_usage( usage );
  52.         else 
  53.         fgcolorppm = ppm_parsecolor( argv[argn], PPM_MAXMAXVAL );
  54.         }
  55.         else if ( pm_keymatch( argv[argn], "-bgcolor", 3 ) ) 
  56.         {
  57.         if ( ++argn >= argc ) 
  58.         pm_usage( usage );
  59.         else 
  60.         bgcolorppm = ppm_parsecolor( argv[argn], PPM_MAXMAXVAL );
  61.         }
  62.         else if ( pm_keymatch( argv[argn], "-weight", 2 ) ) 
  63.         {
  64.         if ( ++argn >= argc ) 
  65.         pm_usage( usage );
  66.         else if ( sscanf( argv[argn], "%lf", &weight ) != 1 )
  67.             pm_usage( usage );
  68.         else if ( weight >= 1. || weight <= 0. )
  69.         {
  70.         pm_message( "weight factor w must be 0.0 < w < 1.0" );
  71.         pm_usage( usage );
  72.         }
  73.         }
  74.       else if ( pm_keymatch( argv[argn], "-bonly", 3 ) )
  75.         bgonly = 1;
  76.       else if ( pm_keymatch( argv[argn], "-fonly", 3 ) )
  77.         fgonly = 1;
  78.       else if ( pm_keymatch( argv[argn], "-balias", 3 ) )
  79.         bgalias = 1;
  80.       else if ( pm_keymatch( argv[argn], "-falias", 3 ) )
  81.         fgalias = 1;
  82.       else if ( pm_keymatch( argv[argn], "-bfalias", 3 ) )
  83.         bgalias = fgalias = 0;
  84.       else if ( pm_keymatch( argv[argn], "-fbalias", 3 ) )
  85.         bgalias = fgalias = 0;
  86.         else
  87.             pm_usage( usage );
  88.         ++argn;
  89.         }
  90.  
  91.     if ( argn != argc )
  92.     {
  93.     ifp = pm_openr( argv[argn] );
  94.     ++argn;
  95.     }
  96.     else
  97.     ifp = stdin;
  98.  
  99.     if ( argn != argc )
  100.     pm_usage( usage );
  101.  
  102.     /* normalize mask elements */
  103.     fmask[4] = weight;
  104.     fmask[0] = fmask[1] = fmask[2] = fmask[3] = ( 1.0 - weight ) / 8.0;
  105.     fmask[5] = fmask[6] = fmask[7] = fmask[8] = ( 1.0 - weight ) / 8.0;
  106.  
  107.     /* use larger value for better results */
  108.     pnm_pbmmaxval = PNM_MAXMAXVAL;
  109.     pnm_readpnminit( ifp, &cols, &rows, &maxval, &format );
  110.    
  111.     xelrow[0] = pnm_allocrow( cols );
  112.     xelrow[1] = pnm_allocrow( cols );
  113.     xelrow[2] = pnm_allocrow( cols );
  114.     newxelrow = pnm_allocrow( cols );
  115.  
  116.     /* Promote PBM files to PGM. */
  117.     if ( PNM_FORMAT_TYPE(format) == PBM_TYPE )
  118.     {
  119.         newformat = PGM_TYPE;
  120.     pm_message( "promoting from PBM to PGM" );
  121.     }
  122.     else
  123.         newformat = format;
  124.  
  125.     /* Figure out foreground pixel value if none was given */
  126.     if (PPM_GETR(fgcolorppm) == 0 && PPM_GETG(fgcolorppm) == 0 && 
  127.     PPM_GETB(fgcolorppm) == 0 )
  128.     {
  129.         if ( PNM_FORMAT_TYPE(newformat) == PGM_TYPE )
  130.         PNM_ASSIGN1( fgcolor, maxval );
  131.     else 
  132.         PPM_ASSIGN( fgcolor, maxval, maxval, maxval );
  133.     }
  134.     else 
  135.     {
  136.         if ( PNM_FORMAT_TYPE(newformat) == PGM_TYPE )
  137.         PNM_ASSIGN1( fgcolor, PPM_GETR( fgcolorppm ) );
  138.     else 
  139.         fgcolor = fgcolorppm;
  140.     }
  141.  
  142.     if (PPM_GETR(bgcolorppm) != 0 || PPM_GETG(bgcolorppm) != 0 || 
  143.     PPM_GETB(bgcolorppm) != 0 )
  144.     {
  145.         if ( PNM_FORMAT_TYPE(newformat) == PGM_TYPE )
  146.         PNM_ASSIGN1( bgcolor, PPM_GETR( bgcolorppm) );
  147.     else 
  148.         bgcolor = bgcolorppm;
  149.     }
  150.     else
  151.     {
  152.         if ( PNM_FORMAT_TYPE(newformat) == PGM_TYPE )
  153.         PNM_ASSIGN1( bgcolor, 0 );
  154.     else 
  155.         PPM_ASSIGN( bgcolor, 0, 0, 0 );
  156.     }
  157.  
  158.  
  159.     pnm_readpnmrow( ifp, xelrow[0], cols, maxval, format );
  160.     pnm_readpnmrow( ifp, xelrow[1], cols, maxval, format );
  161.     pnm_writepnminit( stdout, cols, rows, maxval, newformat, 0 );
  162.     pnm_writepnmrow( stdout, xelrow[0], cols, maxval, newformat, 0 );
  163.  
  164.     for ( row = 1; row < rows - 1; ++row )
  165.     {
  166.     pnm_readpnmrow( ifp, xelrow[(row+1)%3], cols, maxval, format );
  167.     newxelrow[0] = xelrow[row%3][0];
  168.  
  169.     for ( col = 1, xpP = (xelrow[(row-1)%3] + 1), xP = (xelrow[row%3] + 1),
  170.         xnP = (xelrow[(row+1)%3] + 1), nxP = (newxelrow+1); 
  171.         col < cols - 1; ++col, ++xpP, ++xP, ++xnP, ++nxP ) 
  172.         {
  173.         /* Do anti-aliasing here: see if pixel is at the border of a
  174.          * background or foreground stepwise side */
  175.         bgflag = (PNM_EQUAL(*xpP,bgcolor) && PNM_EQUAL(*(xP+1),bgcolor)) ||
  176.              (PNM_EQUAL(*(xP+1),bgcolor) && PNM_EQUAL(*xnP,bgcolor)) ||
  177.              (PNM_EQUAL(*xnP,bgcolor) && PNM_EQUAL(*(xP-1),bgcolor)) ||
  178.              (PNM_EQUAL(*(xP-1),bgcolor) && PNM_EQUAL(*xpP,bgcolor));
  179.         fgflag = (PNM_EQUAL(*xpP,fgcolor) && PNM_EQUAL(*(xP+1),fgcolor)) ||
  180.              (PNM_EQUAL(*(xP+1),fgcolor) && PNM_EQUAL(*xnP,fgcolor)) ||
  181.              (PNM_EQUAL(*xnP,fgcolor) && PNM_EQUAL(*(xP-1),fgcolor)) ||
  182.              (PNM_EQUAL(*(xP-1),fgcolor) && PNM_EQUAL(*xpP,fgcolor)); 
  183.  
  184.         /* Reset flags if anti-aliasing is to be done on foreground
  185.          * or background pixels only */
  186.         if ( ( bgonly && PNM_EQUAL( *xP, fgcolor ) ) ||
  187.          ( fgonly && PNM_EQUAL( *xP, bgcolor ) ) ) 
  188.         bgflag = fgflag = 0;
  189.  
  190.         if ( ( bgflag && bgalias ) || ( fgflag && fgalias ) || 
  191.          ( bgflag && fgflag ) )
  192.         switch( PNM_FORMAT_TYPE( newformat ) )
  193.             {    
  194.             case PGM_TYPE:
  195.             value = PNM_GET1(*(xpP-1)) * fmask[0] +
  196.                 PNM_GET1(*(xpP  )) * fmask[1] +    
  197.                 PNM_GET1(*(xpP+1)) * fmask[2] +
  198.                 PNM_GET1(*(xP -1)) * fmask[3] +
  199.                 PNM_GET1(*(xP   )) * fmask[4] +
  200.                 PNM_GET1(*(xP +1)) * fmask[5] +
  201.                 PNM_GET1(*(xnP-1)) * fmask[6] +
  202.                 PNM_GET1(*(xnP  )) * fmask[7] +
  203.                 PNM_GET1(*(xnP+1)) * fmask[8] +
  204.                 0.5;
  205.             PNM_ASSIGN1( *nxP, value );
  206.                 break;
  207.             default:
  208.             valuer= PPM_GETR(*(xpP-1)) * fmask[0] +
  209.                 PPM_GETR(*(xpP  )) * fmask[1] +    
  210.                 PPM_GETR(*(xpP+1)) * fmask[2] +
  211.                 PPM_GETR(*(xP -1)) * fmask[3] +
  212.                 PPM_GETR(*(xP   )) * fmask[4] +
  213.                 PPM_GETR(*(xP +1)) * fmask[5] +
  214.                 PPM_GETR(*(xnP-1)) * fmask[6] +
  215.                 PPM_GETR(*(xnP  )) * fmask[7] +
  216.                 PPM_GETR(*(xnP+1)) * fmask[8] +
  217.                 0.5;
  218.             valueg= PPM_GETG(*(xpP-1)) * fmask[0] +
  219.                 PPM_GETG(*(xpP  )) * fmask[1] +    
  220.                 PPM_GETG(*(xpP+1)) * fmask[2] +
  221.                 PPM_GETG(*(xP -1)) * fmask[3] +
  222.                 PPM_GETG(*(xP   )) * fmask[4] +
  223.                 PPM_GETG(*(xP +1)) * fmask[5] +
  224.                 PPM_GETG(*(xnP-1)) * fmask[6] +
  225.                 PPM_GETG(*(xnP  )) * fmask[7] +
  226.                 PPM_GETG(*(xnP+1)) * fmask[8] +
  227.                 0.5;
  228.             valueb= PPM_GETB(*(xpP-1)) * fmask[0] +
  229.                 PPM_GETB(*(xpP  )) * fmask[1] +    
  230.                 PPM_GETB(*(xpP+1)) * fmask[2] +
  231.                 PPM_GETB(*(xP -1)) * fmask[3] +
  232.                 PPM_GETB(*(xP   )) * fmask[4] +
  233.                 PPM_GETB(*(xP +1)) * fmask[5] +
  234.                 PPM_GETB(*(xnP-1)) * fmask[6] +
  235.                 PPM_GETB(*(xnP  )) * fmask[7] +
  236.                 PPM_GETB(*(xnP+1)) * fmask[8] +
  237.                 0.5;
  238.             PPM_ASSIGN( *nxP, valuer, valueg, valueb );
  239.             break;
  240.             }
  241.         else
  242.         *nxP = *xP;
  243.         }
  244.  
  245.     newxelrow[cols-1] = xelrow[row%3][cols-1];
  246.     pnm_writepnmrow( stdout, newxelrow, cols, maxval, newformat, 0 );
  247.  
  248.         }
  249.         
  250.     pnm_writepnmrow( stdout, xelrow[row%3], cols, maxval, newformat, 0 );
  251.  
  252.     pm_close( ifp );
  253.     exit ( 0 );
  254.     }
  255.  
  256.