home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / source / fbm12s.lha / flmedn.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-18  |  3.9 KB  |  158 lines

  1. /*****************************************************************
  2.  * flmedn.c: FBM Release 1.1 04-Feb-93 Michael Mauldin
  3.  *
  4.  * Copyright (C) 1993 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.  * flmedn.c: 
  11.  *
  12.  * CONTENTS
  13.  *    median_fbm (input, output)
  14.  *
  15.  * EDITLOG
  16.  *    LastEditDate = Mon Jun 25 00:18:02 1990 - Michael Mauldin
  17.  *    LastFileName = /usr2/mlm/src/misc/fbm/flmedn.c
  18.  *
  19.  * HISTORY
  20.  * 04-Feb-93  Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
  21.  *    Created.
  22.  *****************************************************************/
  23.  
  24. # include <stdio.h>
  25. # include <math.h>
  26. # include <ctype.h>
  27. # include "fbm.h"
  28.  
  29. /****************************************************************
  30.  * median_fbm: determine whether image is in color, and call the
  31.  *            appropriate medianing routine.
  32.  ****************************************************************/
  33.  
  34. #ifndef lint
  35. static char *fbmid =
  36. "$FBM flmedn.c <1.0> 04-Feb-93  (C) 1993 by Michael Mauldin, source \
  37. code available free from MLM@CS.CMU.EDU and from UUNET archives$";
  38. #endif
  39.  
  40.  
  41. /****************************************************************
  42.  * median_fbm: median filter an unmapped image
  43.  ****************************************************************/
  44.  
  45. median_fbm (input, output, beta)
  46. FBM *input, *output;
  47. double beta;
  48. { register unsigned char *bmp, *obm, *ibm;
  49.   register int i, j, k, rowlen, plnlen, w, h, p, sum;
  50.   int new, delta, beta100 = beta * 100;
  51.   int mdn[9];
  52.   unsigned char *gray;
  53.  
  54.   if (input->hdr.physbits != 8)
  55.   { fprintf (stderr, "median_bw: can't median images with %d physbits\n",
  56.          input->hdr.physbits);
  57.     return (0);
  58.   }
  59.  
  60.   if (input->hdr.clrlen > 0)
  61.   { fprintf (stderr, "median_bw: can't median images with %d physbits\n",
  62.          input->hdr.physbits);
  63.     return (0);
  64.   }
  65.  
  66.  
  67.   /* Allocate output */
  68.   output->hdr = input->hdr;
  69.   alloc_fbm (output);
  70.  
  71.   w = input->hdr.cols;
  72.   h = input->hdr.rows;
  73.   p = input->hdr.planes;
  74.   rowlen = input->hdr.rowlen;
  75.   plnlen = input->hdr.plnlen;
  76.   
  77.   for (k=0; k<p; k++)
  78.   {
  79.     /* Copy edges directly */
  80.     for (j=0; j<h; j++)
  81.     { output->bm[k*plnlen + j*rowlen] =
  82.     input->bm[k*plnlen + j*rowlen];
  83.       output->bm[k*plnlen + j*rowlen + w-1] =
  84.     input->bm[k*plnlen + j*rowlen + w-1];
  85.     }
  86.   
  87.     for (i=0; i<w; i++)
  88.     { output->bm[k*plnlen + i] =
  89.     input->bm[k*plnlen + i];
  90.       output->bm[k*plnlen + (h-1)*rowlen + i] =
  91.     input->bm[k*plnlen + (h-1)*rowlen + i];
  92.     }
  93.  
  94.     /* Now set each pixel to median of 9 */
  95.     for (j=1; j < h-1; j++)
  96.     { ibm = &(input->bm[k*plnlen + j*rowlen]);
  97.       obm = &(output->bm[k*plnlen + j*rowlen]);
  98.         
  99.       for (i=1; i < w-1; i++)
  100.       { mdn[0] = ibm[i-rowlen-1];
  101.     mdn[1] = ibm[i-rowlen];
  102.     mdn[2] = ibm[i-rowlen+1];
  103.     mdn[3] = ibm[i-1];
  104.     mdn[4] = ibm[i];
  105.     mdn[5] = ibm[i+1];
  106.     mdn[6] = ibm[i+rowlen-1];
  107.     mdn[7] = ibm[i+rowlen];
  108.     mdn[8] = ibm[i+rowlen+1];
  109.  
  110.     obm[i] = median (mdn, 9);
  111.       }
  112.     }
  113.   }
  114.   
  115.   return (1);
  116. }
  117.  
  118. /****************************************************************
  119.  * median: Return the median of an array, perhaps reordering the
  120.  * elements of the array.  Uses bubble sort 
  121.  ****************************************************************/
  122.  
  123. median (arr, n)
  124. register int *arr, n;
  125. { register int swapped = 1, t, i, mid = n>>1;
  126.  
  127.   while (swapped)
  128.   { swapped = 0;
  129.  
  130.     for (i=1; i<n; i++)
  131.     { if (arr[i-1] > arr[i])
  132.       { t = arr[i];
  133.         arr[i] = arr[i-1];
  134.     arr[i-1] = t;
  135.     swapped++;
  136.       }
  137.     }
  138.   }
  139.   
  140.   if (n&1)
  141.   { return (arr[mid]); }
  142.   else
  143.   { return ((arr[mid - 1] + arr[mid]) / 2); }
  144. }
  145.  
  146. # ifdef TESTING
  147. main (argc, argv)
  148. char *argv[];
  149. { int arr[32], n=0;
  150.  
  151.   for (n=1; n<argc; n++)
  152.   { arr[n-1] = atoi (argv[n]); }
  153.   n--;
  154.  
  155.   fprintf (stderr, "median = %d\n", median (arr, n));
  156. }
  157. # endif
  158.