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

  1. /* pgmnorm.c - read a portable graymap and normalize the contrast
  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. #ifdef    SYSV
  15. #include <string.h>
  16. #else    SYSV
  17. #include <strings.h>
  18. #endif    SYSV
  19. #include "pgm.h"
  20.  
  21. #define max(a,b) ((a) > (b) ? (a) : (b))
  22. #define MAXMAXVAL 1023
  23.  
  24. main( argc, argv )
  25. int argc;
  26. char *argv[];
  27.     {
  28.     FILE *ifd;
  29.     gray maxval, **grays;
  30.     register gray range, *gP;
  31.     int argn, rows, cols, row, hist[MAXMAXVAL+1], i, size, cutoff, count;
  32.     float bpercent, wpercent;
  33.     int bvalue, wvalue;
  34.     int specbpercent, specbvalue, specwpercent, specwvalue;
  35.     register int col;
  36.     char *usage = "[-bpercent <n> | -bvalue <n>] [-wpercent <n> | -wvalue <n>] [pgmfile]";
  37.  
  38.     pm_progname = argv[0];
  39.  
  40.     argn = 1;
  41.     bpercent = 2.0;
  42.     wpercent = 1.0;
  43.     specbpercent = specbvalue = specwpercent = specwvalue = 0;
  44.  
  45.     while ( argn + 1 < argc && argv[argn][0] == '-' )
  46.     {
  47.     if ( strncmp(argv[argn],"-bpercent",max(strlen(argv[argn]),3)) == 0 )
  48.         {
  49.         if ( specbvalue )
  50.         pm_error(
  51.             "only one of -bpercent and -bvalue may be specified",
  52.             0,0,0,0,0 );
  53.         if ( sscanf( argv[argn+1], "%g", &bpercent ) != 1 )
  54.         pm_usage( usage );
  55.         if ( bpercent < 0.0  || bpercent > 100.0 )
  56.         pm_error(
  57.             "black percentage must between 0 and 100", 0,0,0,0,0 );
  58.         specbpercent = 1;
  59.         }
  60.     else if ( strncmp(argv[argn],"-bvalue",max(strlen(argv[argn]),3)) == 0 )
  61.         {
  62.         if ( specbpercent )
  63.         pm_error(
  64.             "only one of -bpercent and -bvalue may be specified",
  65.             0,0,0,0,0 );
  66.         if ( sscanf( argv[argn+1], "%d", &bvalue ) != 1 )
  67.         pm_usage( usage );
  68.         if ( bvalue < 0 )
  69.         pm_error( "black value must be >= 0", 0,0,0,0,0 );
  70.         specbvalue = 1;
  71.         }
  72.     else if ( strncmp(argv[argn],"-wpercent",max(strlen(argv[argn]),3)) == 0 )
  73.         {
  74.         if ( specwvalue )
  75.         pm_error(
  76.             "only one of -wpercent and -wvalue may be specified",
  77.             0,0,0,0,0 );
  78.         if ( sscanf( argv[argn+1], "%g", &wpercent ) != 1 )
  79.         pm_usage( usage );
  80.         if ( wpercent < 0.0 || wpercent > 100.0 )
  81.         pm_error(
  82.             "white percentage must be between 0 and 100", 0,0,0,0,0 );
  83.         specwpercent = 1;
  84.         }
  85.     else if ( strncmp(argv[argn],"-wvalue",max(strlen(argv[argn]),3)) == 0 )
  86.         {
  87.         if ( specwpercent )
  88.         pm_error(
  89.             "only one of -wpercent and -wvalue may be specified",
  90.             0,0,0,0,0 );
  91.         if ( sscanf( argv[argn+1], "%d", &wvalue ) != 1 )
  92.         pm_usage( usage );
  93.         if ( wvalue < 0 )
  94.         pm_error( "white value must be >= 0", 0,0,0,0,0 );
  95.         specwvalue = 1;
  96.         }
  97.     else
  98.         pm_usage( usage );
  99.     argn += 2;
  100.     }
  101.  
  102.     if ( argn < argc )
  103.     {
  104.     ifd = pm_openr( argv[argn] );
  105.     argn++;
  106.     }
  107.     else
  108.     ifd = stdin;
  109.  
  110.     if ( argn != argc )
  111.     pm_usage( usage );
  112.  
  113.     grays = pgm_readpgm( ifd, &cols, &rows, &maxval );
  114.  
  115.     pm_close( ifd );
  116.  
  117.     if ( ( ! specbvalue ) || ( ! specwvalue ) )
  118.     {
  119.     /* Build histogram. */
  120.     for ( i = 0; i <= maxval; i++ )
  121.         hist[i] = 0;
  122.     for ( row = 0; row < rows; row++ )
  123.         for ( col = 0, gP = grays[row]; col < cols; col++, gP++ )
  124.         hist[*gP]++;
  125.     size = rows * cols;
  126.     if ( ! specbvalue )
  127.         { /* Compute bvalue from bpercent. */
  128.         cutoff = size * bpercent / 100.0;
  129.         count = 0;
  130.         for ( bvalue = 0; bvalue <= maxval; bvalue++ )
  131.         {
  132.         count += hist[bvalue];
  133.         if ( count > cutoff )
  134.         break;
  135.         }
  136.         }
  137.     if ( ! specwvalue )
  138.         { /* Compute wvalue from wpercent. */
  139.         cutoff = size * wpercent / 100.0;
  140.         count = 0;
  141.         for ( wvalue = maxval; wvalue >= 0; wvalue-- )
  142.         {
  143.         count += hist[wvalue];
  144.         if ( count > cutoff )
  145.             break;
  146.         }
  147.         }
  148.     }
  149.  
  150.     /* Now rescale so that bvalue maps to 0, wvalue maps to maxval. */
  151.     fprintf(
  152.     stderr, "(Remapping %d..%d to %d..%d.)\n", bvalue, wvalue, 0, maxval );
  153.     pgm_writepgminit( stdout, cols, rows, maxval );
  154.     range = wvalue - bvalue;
  155.     for ( row = 0; row < rows; row++ )
  156.     {
  157.         for ( col = 0, gP = grays[row]; col < cols; col++, gP++ )
  158.         {
  159.         if ( *gP <= bvalue )
  160.         *gP = 0;
  161.         else if ( *gP >= wvalue )
  162.         *gP = maxval;
  163.         else
  164.         *gP = ( *gP - bvalue ) * maxval / range;
  165.         }
  166.     pgm_writepgmrow( stdout, grays[row], cols, maxval );
  167.     }
  168.  
  169.     exit( 0 );
  170.     }
  171.