home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 309.lha / PBM_PLUS / pgm / pgmenhance.c < prev    next >
C/C++ Source or Header  |  1980-12-04  |  3KB  |  112 lines

  1. /* pgmenhance.c - edge-enhance a portable graymap
  2. **
  3. ** Copyright (C) 1989 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 <stdio.h>
  14. #include "pgm.h"
  15.  
  16. main( argc, argv )
  17. int argc;
  18. char *argv[];
  19.     {
  20.     FILE *ifd;
  21.     register gray **grays, *newgrayrow, *ngP;
  22.     int argn, n, rows, cols, row, col;
  23.     float phi, omphi;
  24.     gray maxval, sum;
  25.     long newval;
  26.     char *usage = "[-N] [pgmfile]  ( 1 <= N <= 9, default = 9 )";
  27.  
  28.     pm_progname = argv[0];
  29.  
  30.     argn = 1;
  31.     n = 9;
  32.  
  33.     if ( argn < argc )
  34.     {
  35.     if ( argv[argn][0] == '-' )
  36.         {
  37.         if ( sscanf( &(argv[argn][1]), "%d", &n ) != 1 )
  38.         pm_usage( usage );
  39.         if ( n < 1 || n > 9 )
  40.         pm_usage( usage );
  41.         argn++;
  42.         }
  43.     }
  44.  
  45.     if ( argn != argc )
  46.     {
  47.     ifd = pm_openr( argv[argn] );
  48.     argn++;
  49.     }
  50.     else
  51.     ifd = stdin;
  52.  
  53.     if ( argn != argc )
  54.     pm_usage( usage );
  55.  
  56.     pgm_pbmmaxval = 255;    /* use a larger value for better (?) results */
  57.     grays = pgm_readpgm( ifd, &cols, &rows, &maxval );
  58.  
  59.     pgm_writepgminit( stdout, cols, rows, maxval );
  60.     newgrayrow = pgm_allocrow( cols );
  61.  
  62.     /* The edge enhancing technique is taken from Philip R. Thompson's "xim"
  63.     ** program, which in turn took it from section 6 of "Digital Halftones by
  64.     ** Dot Diffusion", D. E. Knuth, ACM Transaction on Graphics Vol. 6, No. 4,
  65.     ** October 1987, which in turn got it from two 1976 papers by J. F. Jarvis
  66.     ** et. al.
  67.     */
  68.     phi = n / 10.0;
  69.     omphi = 1.0 - phi;
  70.  
  71.     /* Row 0. */
  72.     for ( col = 0, ngP = newgrayrow; col < cols; col++, ngP++ )
  73.     *ngP = grays[0][col];
  74.     pgm_writepgmrow( stdout, newgrayrow, cols, maxval );
  75.  
  76.     /* Other rows. */
  77.     for ( row = 1; row < rows - 1; row++ )
  78.     {
  79.     ngP = newgrayrow;
  80.     *ngP = grays[row][0];
  81.     ngP++;
  82.     for ( col = 1; col < cols - 1; col++, ngP++ )
  83.         {
  84.         /* Compute the sum of the neighborhood. */
  85.         sum =
  86.         grays[row-1][col-1] + grays[row-1][col] + grays[row-1][col+1] +
  87.         grays[row  ][col-1] + grays[row  ][col] + grays[row  ][col+1] +
  88.         grays[row+1][col-1] + grays[row+1][col] + grays[row+1][col+1];
  89.         /* Now figure new value. */
  90.         newval =
  91.         (long) ( ( grays[row][col] - phi * sum / 9 ) / omphi + 0.5 );
  92.         if ( newval < 0 )
  93.         newgrayrow[col] = 0;
  94.         else if ( newval > maxval )
  95.         newgrayrow[col] = maxval;
  96.         else
  97.         newgrayrow[col] = newval;
  98.         }
  99.     newgrayrow[cols - 1] = grays[row][cols - 1];
  100.     pgm_writepgmrow( stdout, newgrayrow, cols, maxval );
  101.     }
  102.  
  103.     /* Last row. */
  104.     for ( col = 0, ngP = newgrayrow; col < cols; col++, ngP++ )
  105.     *ngP = grays[rows - 1][col];
  106.     pgm_writepgmrow( stdout, newgrayrow, cols, maxval );
  107.  
  108.     pm_close( ifd );
  109.  
  110.     exit( 0 );
  111.     }
  112.