#include <stdio.h>
#define progname "adnoise"

short asize ;    /* pic dimensions */
short header=1;/* set if pic file contains a header char */
short rms=2;     

FILE *fp, *fq = NULL;            /* input,output picture channels */
 
main(argc,argv)
char **argv;
{

  argv++;
  while ((argc>1)&&((*argv)[0] == '-'))
  {

    switch((*argv)[1]) {
    case 'x':
      sscanf(*argv+2,"%hd",&asize);
      if(asize<0) error("picture size");
      header=0;
      break;
    case 'r':
      sscanf(*argv+2,"%hd",&rms);
      if(rms<0) error("bad rms");
      break;
    default:
      error("unknown flag");
      break;
    }
    --argc;argv++;
  }
 
  if (argc<3)
    error("missing arguments");
  else
  {
    if((fp = fopen(*argv++,"r")) == NULL)
      error("can't access input file");
    --argc;

    if((fq = fopen(*argv,"w")) == NULL)
      error("can't access output file");
  }
  adnoise();
  fclose(fp);
  fclose(fq);
}
 
error(s)
char *s;
{
  fprintf(stderr,"%s: %s\n",progname,s);
  exit(1);
}
 
short seed=111;
#define BITS 10

randseed ()
/* BITS in the range 1 to 15 (probably best for <= 10, say)*/
{
  seed = (23501*seed + 6923);  /*&32767;*/ 
  return((seed >> (15-BITS)) & ((1 << BITS) - 1));
}

float gausseed()
{
register short v;
register char i;
  for(i=0,v=0 ;i<12 ;i++)
         v+=randseed();
  return((v-512.0*12.0)/2048.0);
}

adnoise()
{
long i,area;
short c;
  if (header)
     asize=getc(fp)&0377;
  if (asize<0)   error("array size out of range");
  area = asize*asize;

  if(header||asize<256)   putc(asize,fq);

  for (i=0;i<area;i++) {
       c= (getc(fp)&0377) + ((short) rms*gausseed());
       if(c<0) c=0;
       if(255<c) c=255;
       putc(c,fq);
   }
}
