home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume19 / fbm / part05 / flklnr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-08  |  6.5 KB  |  255 lines

  1. /*****************************************************************
  2.  * flklnr.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.  * fbm.c: 
  9.  *
  10.  * USAGE
  11.  *    clean_fbm (input, output, beta, gamma, nbr)
  12.  *
  13.  * EDITLOG
  14.  *    LastEditDate = Tue Mar  7 19:57:19 1989 - Michael Mauldin
  15.  *    LastFileName = /usr2/mlm/src/misc/fbm/flklnr.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. /****************************************************************
  31.  * clean_fbm: determine whether image is in color, and call the
  32.  *            appropriate cleaning routine.
  33.  ****************************************************************/
  34.  
  35. #ifndef lint
  36. static char *fbmid =
  37.     "$FBM flklnr.c <0.9> 07-Mar-89  (C) 1989 by Michael Mauldin$";
  38. #endif
  39.  
  40. clean_fbm (input, output, beta, gamma, nbr)
  41. FBM *input, *output;
  42. int beta, gamma, nbr;
  43. {
  44.   if (input->hdr.planes == 1)
  45.   { return (clean_bw (input, output, beta, gamma, nbr)); }
  46.   else
  47.   { return (clean_bw (input, output, beta, gamma, nbr)); }
  48. }
  49.  
  50. /****************************************************************
  51.  * clean_bw: use a digital Laplacian filter to clean a BW image
  52.  ****************************************************************/
  53.  
  54. clean_bw (input, output, beta, gamma, nbr)
  55. FBM *input, *output;
  56. int beta, gamma, nbr;
  57. { register unsigned char *obm, *bmp;
  58.   register int dx, dy, left, right, top, bot, i, j;
  59.   int rowlen, w, h, off, cnt;
  60.   int new, sum, sumw, sumb, Whites;
  61.   int bf, wf, ubf, uwf; /* white and black pixel counters */
  62.  
  63.   double pc;
  64.  
  65.   if (input->hdr.planes != 1)
  66.   { fprintf (stderr, "clean_bw: can't process color images\n");
  67.     return (0);
  68.   }
  69.  
  70.   fprintf (stderr, "Clean BW, beta %d, gamma %d, nbr %d\n",
  71.        beta, gamma, nbr);
  72.  
  73.   /* Allocate output */
  74.   output->hdr = input->hdr;
  75.   alloc_fbm (output);
  76.  
  77.   w = input->hdr.cols;
  78.   h = input->hdr.rows;
  79.   rowlen = input->hdr.rowlen;
  80.   Whites = 252;
  81.  
  82.   /* If not edge detect do black white trip point */
  83.   if (gamma > 0)
  84.   {
  85.     fprintf (stderr, "Thresholding image, gamma %d...\n", gamma);
  86.     bf = wf = 0;
  87.     for (j=0; j < h; j++)
  88.     { bmp = &(input->bm[j*rowlen]);
  89.  
  90.       for (i=0; i < w; i++)
  91.       {
  92.         if (bmp[i] >= gamma)    { bmp[i] = WHITE; wf++; }
  93.         else            { bmp[i] = BLACK; bf++; }
  94.       }
  95.     }
  96.  
  97.     pc = (((double)bf) * 100.00) / ((double)(bf + wf));
  98.     fprintf (stderr, "Converted to %1.2f %% Black, %1.2f %% White image.\n",
  99.          pc, (100.00 - pc));
  100.   }
  101.  
  102.   /* Set pixel counters for image statistics */
  103.   bf = wf = ubf = uwf = 0;
  104.   off = nbr/2;
  105.  
  106.   /* Compute outer border of 2 pixels */
  107.     /* Compute Top Line U1 of Pixels */
  108.       /* Compute U1L1Pixel */
  109.  
  110.   /* Compute Main Image Body */
  111.   for (j=0; j<h; j++)
  112.   { obm = &(output->bm[j*rowlen]);
  113.  
  114.     /* Set limits of neighborhood */
  115.     top   =  j-off;        if (top < 0)    top = 0;
  116.     bot   =  top+nbr;        if (bot > h)    bot = h;
  117.  
  118.     for (i=0; i<w; i++)
  119.     { sum = 0;
  120.       cnt = 0;
  121.       
  122.       /* Set limits of neighborhood */
  123.       left  =  i-off;        if (left < 0)    left = 0;
  124.       right =  left+nbr;    if (right > w)    right = w;
  125.       
  126.       /* Sample neighborhood */
  127.       bmp = &(input->bm[top*rowlen]);
  128.     
  129.       for (dy = top;   dy < bot;   dy++, bmp += rowlen)
  130.       { for (dx = left;   dx < right;   dx++)
  131.         { sum += bmp[dx]; cnt ++; }
  132.       }
  133.       
  134.       if (cnt == 0)
  135.       { fprintf (stderr, "Panic, no pixels in neighborhood!\n");
  136.         abort ();
  137.       }
  138.       
  139.       sumw = sum * 100 / (WHITE * cnt);
  140.       sumb = 100 - sumw;
  141.       
  142.       if (input->bm[i + j*rowlen] > Whites)
  143.       {
  144.         if (sumw < beta) { new = BLACK; bf++; }
  145.         else { new = WHITE; uwf++; }
  146.       }
  147.       else
  148.       {
  149.         if (sumb < beta) { new = WHITE; wf++; }
  150.         else { new = BLACK; ubf++; }
  151.       }
  152.  
  153.       obm[i] = new;
  154.     }
  155.   }
  156.  
  157.  
  158.   fprintf (stderr, "Cleaning pass complete for %2d neighbors of %d pixels.\n",
  159.        beta, w*h);
  160.   fprintf (stderr, "Removed %d white pixels and %d black pixels.\n", bf, wf);
  161.   fprintf (stderr, "Left Unchanged %d white and %d black pixels.\n", uwf, ubf);
  162.  
  163.   return (1);
  164. }
  165.  
  166. # ifdef UNDEFINED
  167. /****************************************************************
  168.  * clean_clr: use a digital Laplacian filter to edge detect a CLR image
  169.  ****************************************************************/
  170.  
  171. clean_clr (input, output, beta)
  172. FBM *input, *output;
  173. double beta;
  174. { register unsigned char *b, *obm, *avg;
  175.   register int i, j, k, rowlen, plnlen, w, h, p, sum;
  176.   int new, delta, beta100 = beta * 100;
  177.   unsigned char gray[500000];
  178.  
  179.   fprintf (stderr, "Sharpen color, beta %lg\n", beta);
  180.  
  181.   /* Allocate output */
  182.   output->hdr = input->hdr;
  183.   alloc_fbm (output);
  184.  
  185.   w = input->hdr.cols;
  186.   h = input->hdr.rows;
  187.   p = input->hdr.planes;
  188.   rowlen = input->hdr.rowlen;
  189.   plnlen = input->hdr.plnlen;
  190.   
  191.   /* Calculate the intensity plane */
  192. /*  gray = (unsigned char *) malloc (plnlen); */
  193.   
  194.   fprintf (stderr, "Allocating %d bytes for gray[]\n", plnlen);
  195.  
  196.   for (j=0; j<h; j++)  
  197.   { b = &(input->bm[j*rowlen]);
  198.     avg = &(gray[j*rowlen]);    
  199.  
  200.     for (i=0; i<w; i++)
  201.     { sum = 0;
  202.       for (k=0; k<p; k++)
  203.       { sum += b[i+k*plnlen]; }
  204.       avg[i] = sum/p;
  205.     }
  206.   }
  207.   
  208.   /* Copy edges directly */
  209.   for (k=0; k<p; k++)
  210.   {  for (j=0; j<h; j++)
  211.     { output->bm[k*plnlen + j*rowlen] =
  212.     input->bm[k*plnlen + j*rowlen];
  213.       output->bm[k*plnlen + j*rowlen + w-1] =
  214.     input->bm[k*plnlen + j*rowlen + w-1];
  215.     }
  216.   
  217.     for (i=0; i<w; i++)
  218.     { output->bm[k*plnlen + i] =
  219.     input->bm[k*plnlen + i];
  220.       output->bm[k*plnlen + (h-1)*rowlen + i] =
  221.     input->bm[k*plnlen + (h-1)*rowlen + i];
  222.     }
  223.   }
  224.  
  225.   for (j=1; j < h-1; j++)
  226.   { avg = &(gray[j*rowlen]);
  227.     
  228.     for (i=1; i < w-1; i++)
  229.     { sum = avg[i-rowlen-1] +     avg[i-rowlen] + avg[i-rowlen+1] +
  230.         avg[i-1]        - 8 * avg[i]        + avg[i+1]        +
  231.         avg[i+rowlen-1] +     avg[i+rowlen] + avg[i+rowlen+1];
  232.  
  233.       for (k=0; k<p; k++)
  234.       { b =  &(input->bm[k*plnlen + j*rowlen + i]);
  235.         obm = &(output->bm[k*plnlen + j*rowlen + i]);
  236.         
  237.     if (sum < 0)
  238.     { delta = - (beta100 * *b * -sum / (8*100)); }
  239.     else
  240.     { delta = beta100 * *b * sum / (8*100); }
  241.   
  242.     new = *b - delta;
  243.   
  244.     if (new < BLACK) new = BLACK;
  245.     else if (new > WHITE) new = WHITE;
  246.     
  247.     *obm = new;
  248.       }
  249.     }
  250.   }
  251.  
  252.   return (1);
  253. }
  254. # endif
  255.