home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / NETWORK / netpbm_src.lzh / NETPBM / PNM / pnmsmooth.c < prev    next >
C/C++ Source or Header  |  1996-11-28  |  5KB  |  189 lines

  1. /* pnmsmooth.c - smooth out an image by replacing each pixel with the 
  2. **               average of its width x height neighbors.
  3. **
  4. ** Version 2.0   December 5, 1994
  5. **
  6. ** Copyright (C) 1994 by Mike Burns (burns@chem.psu.edu)
  7. **
  8. ** Permission to use, copy, modify, and distribute this software and its
  9. ** documentation for any purpose and without fee is hereby granted, provided
  10. ** that the above copyright notice appear in all copies and that both that
  11. ** copyright notice and this permission notice appear in supporting
  12. ** documentation.  This software is provided "as is" without express or
  13. ** implied warranty.
  14. */
  15.  
  16. /* Version 2.0 - December 5, 1994
  17. ** ------------------------------
  18. ** Rewrote as a C program that accepts a few options instead of a shell 
  19. ** script with no options.
  20. **
  21. */
  22.  
  23. #include "pnm.h"
  24. #ifndef OSK
  25. #include <sys/wait.h>
  26. #endif
  27.  
  28. #define TRUE    1
  29. #define FALSE   0
  30.  
  31. int
  32. main( argc, argv )
  33.     int argc;
  34.     char* argv[];
  35.     {
  36.     FILE *cofp;
  37.     char *tempfn;
  38.     char *pnmfn;
  39.     int argn;
  40.     int col, row;
  41.     int format, forceplain;
  42.     int cols, rows;
  43.     int newmaxval;        /* normally xelval, but want int here */
  44.     xelval g;
  45.     xel *outputrow;
  46.     int pid, status;
  47. #ifdef OSK
  48.     char mytemp[20] = "/r0/smoothXXXXXX";
  49.     extern char **environ;
  50.     char *argblk[] = {"pnmconvol", tempfn, pnmfn, 0,};
  51. #endif
  52.     int DUMPFLAG = FALSE;
  53.     char *usage = "[-size width height] [-dump dumpfile] [pnmfile]";
  54.  
  55.     pnm_init( &argc, argv );
  56.  
  57.     /* set up defaults */
  58.     cols = 3;
  59.     rows = 3;
  60.     format = PGM_FORMAT;
  61.     forceplain = 1;
  62.     pnmfn = (char *) 0;        /* initialize to NULL just in case */
  63.  
  64.     argn = 1;
  65.     while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  66.     {
  67.     if ( pm_keymatch( argv[argn], "-size", 2 ) )
  68.         {
  69.         ++argn;
  70.         if ( argn+1 >= argc )
  71.         {
  72.         pm_message( "incorrect number of arguments for -size option" );
  73.         pm_usage( usage );
  74.         }
  75.         else if ( argv[argn][0] == '-' || argv[argn+1][0] == '-' )
  76.         {
  77.         pm_message( "invalid arguments to -size option: %s %s", 
  78.             argv[argn], argv[argn+1] );
  79.         pm_usage( usage );
  80.         }
  81.         if ( (cols = atoi(argv[argn])) == 0 )
  82.         pm_error( "invalid width size specification: %s", argv[argn] );
  83.         ++argn;
  84.         if ( (rows = atoi(argv[argn])) == 0 )
  85.         pm_error( "invalid height size specification: %s",argv[argn] );
  86.         if ( cols % 2 != 1 || rows % 2 != 1 )
  87.         pm_error( "the convolution matrix must have an odd number of rows and columns" );
  88.         }
  89.     else if ( pm_keymatch( argv[argn], "-dump", 2 ) )
  90.         {
  91.         ++argn;
  92.         if ( argn >= argc )
  93.         {
  94.         pm_message( "missing argument to -dump option" );
  95.         pm_usage( usage );
  96.         }
  97.         else if ( argv[argn][0] == '-' )
  98.         {
  99.         pm_message( "invalid argument to -dump option: %s", 
  100.             argv[argn] );
  101.         pm_usage( usage );
  102.         }
  103.         cofp = pm_openw( argv[argn] );
  104.         DUMPFLAG = TRUE;
  105.         }
  106.     else
  107.         pm_usage( usage );
  108.     ++argn;
  109.     }
  110.  
  111.     /* Only get file name if given on command line to pass through to 
  112.     ** pnmconvol.  If filename is coming from stdin, pnmconvol will read it.
  113.     */
  114.     if ( argn < argc )
  115.     {
  116.     pnmfn = argv[argn];
  117.     ++argn;
  118.     }
  119.  
  120.     if ( argn != argc )
  121.     pm_usage( usage );
  122.  
  123.  
  124.     if ( !DUMPFLAG )
  125.     {
  126. #ifndef OSK
  127.     if ( (tempfn = tmpnam((char *) 0)) == NULL )
  128. #else
  129.     if ( (tempfn = mktemp(mytemp)) == NULL )
  130. #endif
  131.         pm_error( "could not create temporary file name" );
  132.     if ( (cofp = pm_openw(tempfn)) == NULL )
  133.         pm_error( "could not create temporary convolution file" );
  134.     }
  135.  
  136.     /* Generate mean value for all pixels in convolution matrix. */
  137.     g = rows * cols + 1;
  138.  
  139.     /* Make sure newmaxval is not larger than PNM_MAXMAXVAL or else
  140.     ** newmaxval will overrun its defined data size and become garbage.
  141.     */
  142.     newmaxval = ( rows * cols ) * 2;
  143.     if ( newmaxval > PNM_MAXMAXVAL )
  144.     pm_error( "generated maxval is too large: %d", newmaxval );
  145.  
  146.     pnm_writepnminit( cofp, cols, rows, newmaxval, format, forceplain );
  147.     outputrow = pnm_allocrow( cols );
  148.  
  149.     for ( row = 0; row < rows; ++ row )
  150.     {
  151.     for ( col = 0; col < cols; ++col )
  152.         PNM_ASSIGN1( outputrow[col], g );
  153.     pnm_writepnmrow( cofp, outputrow, cols, newmaxval, format, forceplain );
  154.     }
  155.     pm_close( cofp );
  156.     pnm_freerow( outputrow );
  157.  
  158.     /* If we're only going to dump the file, now is the time to stop. */
  159.     if ( DUMPFLAG )
  160.     exit( 0 );
  161. #ifndef OSK
  162.     /* fork a child process */
  163.     if ( (pid = fork()) < 0 )
  164.     pm_error( "fork" );
  165.  
  166.     /* child process executes following code */
  167.     if ( pid == 0 )
  168.     {
  169.     /* If pnmfile name is not given on command line, then pnmfn will be
  170.     ** (char *) 0 and the arglist will terminate there.
  171.     */
  172.     execlp( "pnmconvol", "pnmconvol", tempfn, pnmfn, (char *) 0 );
  173.     pm_error( "error executing pnmconvol command" );
  174.     }
  175.  
  176. #else
  177.     /* fork a child process */
  178.     if ( (pid = os9exec(os9forkc, argblk[0], argblk, environ, 0, 0, 3)) == -1)
  179.         pm_error( "error executing pnmconvol command" );
  180.  
  181. #endif
  182.     /* wait for child to finish */
  183.     while ( wait(&status) != pid )
  184.     ;
  185.  
  186.     unlink( tempfn );
  187.     exit( 0 );
  188.     }
  189.