home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume19 / fbm / part03 / fbnorm.c < prev    next >
C/C++ Source or Header  |  1989-06-08  |  5KB  |  176 lines

  1. /*****************************************************************
  2.  * fbnorm.c: FBM Library 0.9 (Beta test) 07-Mar-89  Michael Mauldin
  3.  *
  4.  * Copyright (C) 1989 by Michael Mauldin.  Permission is granted to
  5.  * use this file in whole or in part provided that you do not sell it
  6.  * for profit and that this copyright notice is retained unchanged.
  7.  *
  8.  * fbnorm.c: Normalize contrast and brightness of image
  9.  *
  10.  * USAGE
  11.  *      % fbnorm < image > image2
  12.  *
  13.  * EDITLOG
  14.  *      LastEditDate = Tue Mar  7 19:56:35 1989 - Michael Mauldin
  15.  *      LastFileName = /usr2/mlm/src/misc/fbm/fbnorm.c
  16.  *
  17.  * HISTORY
  18.  * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
  19.  *    Beta release (version 0.9) mlm@cs.cmu.edu
  20.  *
  21.  * 21-Aug-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  22.  *      Created.
  23.  *****************************************************************/
  24.  
  25. # include <stdio.h>
  26. # include <math.h>
  27. # include <ctype.h>
  28. # include "fbm.h"
  29.  
  30. # define USAGE \
  31.     "Usage: fbnorm [ -b<val> -w<val> ] [ -<type> ] < image > image"
  32.  
  33. #ifndef lint
  34. static char *fbmid =
  35.     "$FBM fbnorm.c <0.9> 07-Mar-89  (C) 1989 by Michael Mauldin$";
  36. #endif
  37.  
  38. main (argc, argv)
  39. char *argv[];
  40. { FBM image;
  41.   register unsigned char *bmptr, *tail;
  42.   register int j, k, ch, size, cnt;
  43.   int min = -1, max = -1, cutoff;
  44.   int hist[BYTE];
  45.   double blackp = -1.0, whitep = -1.0;    /* Percent */
  46.   int outtype = FMT_FBM;
  47.  
  48.   /* Get the options */
  49.   while (--argc > 0 && (*++argv)[0] == '-')
  50.   { while (*++(*argv))
  51.     { switch (**argv)
  52.       { case 'b':       blackp = atof (*argv+1); SKIPARG; break;
  53.         case 'w':       whitep = atof (*argv+1); SKIPARG; break;
  54.     case 'A':    outtype = FMT_ATK; break;
  55.     case 'B':    outtype = FMT_FACE; break;
  56.     case 'F':    outtype = FMT_FBM; break;
  57.     case 'G':    outtype = FMT_GIF; break;
  58.     case 'I':    outtype = FMT_IFF; break;
  59.     case 'L':    outtype = FMT_LEAF; break;
  60.     case 'M':    outtype = FMT_MCP; break;
  61.     case 'P':    outtype = FMT_PBM; break;
  62.     case 'S':    outtype = FMT_SUN; break;
  63.     case 'T':    outtype = FMT_TIFF; break;
  64.     case 'X':    outtype = FMT_X11; break;
  65.     case 'Z':    outtype = FMT_PCX; break;
  66.         default:        fprintf (stderr, "%s\n", USAGE);
  67.                         exit (1);
  68.       }
  69.     }
  70.   }
  71.  
  72.   if (argc == 1)
  73.   { blackp = whitep = atof (argv[0]); }
  74.   else if (argc == 2)
  75.   { min = atoi (argv[0]); max = atoi (argv[1]); }
  76.   else if (argc > 2)
  77.   { fprintf (stderr, "%s\n", USAGE);
  78.     exit (1);
  79.   }
  80.   
  81.   /* Clear the memory pointer so alloc_fbm won't be confused */
  82.   image.cm  = image.bm  = (unsigned char *) NULL;
  83.  
  84.   /* Now read in the image */
  85.   if (read_bitmap (&image, (char *) NULL))
  86.   { 
  87.     /* Check input type */
  88.     if (image.hdr.physbits != 8)
  89.     { fprintf (stderr,
  90.            "Can't resize images with %d physical bits per pixel\n",
  91.            image.hdr.physbits);
  92.       exit (1);
  93.     }
  94.  
  95.     /* Set default tail sizes */
  96.     if (image.hdr.planes > 1)        /* Color defaults */
  97.     { if (blackp < 0.0) blackp = 0.5;
  98.       if (whitep < 0.0) whitep = 0.5;
  99.     }
  100.     else                /* Bw defaults */
  101.     { if (blackp < 0.0) blackp = 2.0;
  102.       if (whitep < 0.0) whitep = 1.0;
  103.     }
  104.  
  105.     size = image.hdr.rows * image.hdr.cols * image.hdr.planes;
  106.  
  107.     /* Calculate min and max (if not given as arguments) */
  108.     if (min < 0 || max < 0)
  109.     {
  110.       /* Compute histogram */
  111.       for (ch=0; ch<BYTE; ch++)
  112.       { hist[ch] = 0; }
  113.   
  114.       for (k=0; k<image.hdr.planes; k++)
  115.       { for (j=0; j< image.hdr.rows; j++)
  116.         { bmptr = &(image.bm[k*image.hdr.plnlen + j*image.hdr.rowlen]);
  117.           tail = bmptr + image.hdr.cols;
  118.           
  119.           while (bmptr < tail)
  120.           { hist[*bmptr++]++; }
  121.         }
  122.       }
  123.  
  124.       /* Take off 'blackp' percent of darkest pixels */      
  125.       cutoff = size * blackp / 100.0;
  126.  
  127.       for (ch=0, cnt=0; ch<BYTE; ch++)
  128.       { if ((cnt += hist[ch]) > cutoff)
  129.         { min = ch; break; }
  130.       }
  131.  
  132.       /* Take off 'whitep' percent of darkest pixels */      
  133.       cutoff = size * whitep / 100.0;
  134.  
  135.       for (ch = BYTE-1, cnt=0; ch >= 0; ch--)
  136.       { if ((cnt += hist[ch]) > cutoff)
  137.         { max = ch; break; }
  138.       }
  139.     }
  140.       
  141.     fprintf (stderr, "Normalizing: \"%s\" <%d,%d> ==> <0..255>\n",
  142.              image.hdr.title[0] ? image.hdr.title : "(untitled)", min, max);
  143.  
  144.     bmptr = image.bm;
  145.     tail = bmptr+size;
  146.  
  147.     while (bmptr < tail)
  148.     { ch = *bmptr;
  149.  
  150.       if (ch <= min)
  151.       { ch = 0; }
  152.       else if (ch >= max)
  153.       { ch = 255; }
  154.       else
  155.       { ch = (ch - min) * 255 / (max - min); }
  156.  
  157.        if (ch < 0 || ch > 255)
  158.        { fprintf (stderr, "raw %d, min %d, max %d, out %d\n",
  159.                   *bmptr, min, max, ch);
  160.        }
  161.  
  162.       *bmptr++ = ch;
  163.     }
  164.     
  165.     /* The image is now an 8bit per pixel image */
  166.     image.hdr.bits = 8;
  167.  
  168.     /* Write it out */
  169.     write_bitmap (&image, stdout, outtype);
  170.   }
  171.   else
  172.   { exit (1); }
  173.   
  174.   exit (0);
  175. }
  176.