home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / fbm / src / fbnorm.c < prev    next >
C/C++ Source or Header  |  1990-06-24  |  5KB  |  193 lines

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