home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / pgm / pgmenhance.c < prev    next >
C/C++ Source or Header  |  1993-10-04  |  3KB  |  126 lines

  1. /* pgmenhance.c - edge-enhance a portable graymap
  2. **
  3. ** Copyright (C) 1989, 1991 by Jef Poskanzer.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include "pgm.h"
  14.  
  15. int
  16. main( argc, argv )
  17. int argc;
  18. char* argv[];
  19.     {
  20.     FILE* ifp;
  21.     gray* prevrow;
  22.     gray* thisrow;
  23.     gray* nextrow;
  24.     gray* temprow;
  25.     gray* newrow;
  26.     register gray* ngP;
  27.     int argn, n, rows, cols, row, col;
  28.     float phi, omphi;
  29.     gray maxval;
  30.     long sum, newval;
  31.     int format;
  32.     char* usage = "[-N] [pgmfile]  ( 1 <= N <= 9, default = 9 )";
  33.  
  34.  
  35.     pgm_init( &argc, argv );
  36.  
  37.     argn = 1;
  38.     n = 9;
  39.  
  40.     if ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  41.     {
  42.     if ( sscanf( &(argv[argn][1]), "%d", &n ) != 1 )
  43.         pm_usage( usage );
  44.     if ( n < 1 || n > 9 )
  45.         pm_usage( usage );
  46.     ++argn;
  47.     }
  48.  
  49.     if ( argn != argc )
  50.     {
  51.     ifp = pm_openr( argv[argn] );
  52.     ++argn;
  53.     }
  54.     else
  55.     ifp = stdin;
  56.  
  57.     if ( argn != argc )
  58.     pm_usage( usage );
  59.  
  60.     pgm_pbmmaxval = 255;    /* use a larger value for better (?) results */
  61.     pgm_readpgminit( ifp, &cols, &rows, &maxval, &format );
  62.     prevrow = pgm_allocrow( cols );
  63.     thisrow = pgm_allocrow( cols );
  64.     nextrow = pgm_allocrow( cols );
  65.  
  66.     pgm_writepgminit( stdout, cols, rows, maxval, 0 );
  67.     newrow = pgm_allocrow( cols );
  68.  
  69.     /* The edge enhancing technique is taken from Philip R. Thompson's "xim"
  70.     ** program, which in turn took it from section 6 of "Digital Halftones by
  71.     ** Dot Diffusion", D. E. Knuth, ACM Transaction on Graphics Vol. 6, No. 4,
  72.     ** October 1987, which in turn got it from two 1976 papers by J. F. Jarvis
  73.     ** et. al.
  74.     */
  75.     phi = n / 10.0;
  76.     omphi = 1.0 - phi;
  77.  
  78.     /* First row. */
  79.     pgm_readpgmrow( ifp, thisrow, cols, maxval, format );
  80.     pgm_writepgmrow( stdout, thisrow, cols, maxval, 0 );
  81.     pgm_readpgmrow( ifp, nextrow, cols, maxval, format );
  82.  
  83.     /* Other rows. */
  84.     for ( row = 1; row < rows - 1; row++ )
  85.     {
  86.     temprow = prevrow;
  87.     prevrow = thisrow;
  88.     thisrow = nextrow;
  89.     nextrow = temprow;
  90.     pgm_readpgmrow( ifp, nextrow, cols, maxval, format );
  91.  
  92.     ngP = newrow;
  93.     *ngP = thisrow[0];
  94.     ngP++;
  95.     for ( col = 1; col < cols - 1; col++, ngP++ )
  96.         {
  97.         /* Compute the sum of the neighborhood. */
  98.         sum =
  99.         (long) prevrow[col-1] + (long) prevrow[col] +
  100.         (long) prevrow[col+1] +
  101.         (long) thisrow[col-1] + (long) thisrow[col] +
  102.         (long) thisrow[col+1] +
  103.         (long) nextrow[col-1] + (long) nextrow[col] +
  104.         (long) nextrow[col+1];
  105.         /* Now figure new value. */
  106.         newval = ( ( thisrow[col] - phi * sum / 9 ) / omphi + 0.5 );
  107.         if ( newval < 0 )
  108.         *ngP = 0;
  109.         else if ( newval > maxval )
  110.         *ngP = maxval;
  111.         else
  112.         *ngP = newval;
  113.         }
  114.     *ngP = thisrow[cols - 1];
  115.     pgm_writepgmrow( stdout, newrow, cols, maxval, 0 );
  116.     }
  117.     pm_close( ifp );
  118.  
  119.     /* Last row. */
  120.     pgm_writepgmrow( stdout, nextrow, cols, maxval, 0 );
  121.  
  122.     pm_close( stdout );
  123.  
  124.     exit( 0 );
  125.     }
  126.