/brlcad/tags/rel-4-0/sig/umod.c

https://bitbucket.org/vrrm/brl-cad-copy-for-fast-history-browsing-in-git · C · 200 lines · 151 code · 23 blank · 26 comment · 38 complexity · 41c05523ee92433591847e3933805770 MD5 · raw file

  1. /*
  2. * I M O D . C
  3. *
  4. * Modify intensities in a stream of short (16 bit) unsigned integers.
  5. *
  6. * Allows any number of add, subtract, multiply, divide, or
  7. * exponentiation operations to be performed on a picture.
  8. * Keeps track of and reports clipping.
  9. *
  10. * Author -
  11. * Lee A. Butler
  12. * 25 October 1990
  13. *
  14. * Source -
  15. * SECAD/VLD Computing Consortium, Bldg 394
  16. * The U. S. Army Ballistic Research Laboratory
  17. * Aberdeen Proving Ground, Maryland 21005-5066
  18. *
  19. * Copyright Notice -
  20. * This software is Copyright (C) 1986 by the United States Army.
  21. * All rights reserved.
  22. */
  23. #ifndef lint
  24. static char RCSid[] = "@(#)$Header$ (BRL)";
  25. #endif
  26. #include <stdio.h>
  27. #include <math.h>
  28. /* #include "externs.h" */
  29. #if !defined(SYSV) && defined(BSD) && BSD < 43
  30. #define strrchr rindex
  31. #endif
  32. extern int getopt();
  33. extern char *optarg;
  34. extern int optind;
  35. char *progname = "(noname)";
  36. char *file_name;
  37. char usage[] = "\
  38. Usage: smod {-a add -s sub -m mult -d div -A(abs) -e exp -r root} [file.s]\n";
  39. #define ADD 1
  40. #define MULT 2
  41. #define ABS 3
  42. #define POW 4
  43. #define BUFLEN (8192*2) /* usually 2 pages of memory, 16KB */
  44. int numop = 0; /* number of operations */
  45. int op[256]; /* operations */
  46. double val[256]; /* arguments to operations */
  47. unsigned short iobuf[BUFLEN]; /* input buffer */
  48. int mapbuf[65536]; /* translation buffer/lookup table */
  49. get_args( argc, argv )
  50. register char **argv;
  51. {
  52. register int c;
  53. double d;
  54. while ( (c = getopt( argc, argv, "a:s:m:d:Ae:r:" )) != EOF ) {
  55. switch( c ) {
  56. case 'a':
  57. op[ numop ] = ADD;
  58. val[ numop++ ] = atof(optarg);
  59. break;
  60. case 's':
  61. op[ numop ] = ADD;
  62. val[ numop++ ] = - atof(optarg);
  63. break;
  64. case 'm':
  65. op[ numop ] = MULT;
  66. val[ numop++ ] = atof(optarg);
  67. break;
  68. case 'd':
  69. op[ numop ] = MULT;
  70. d = atof(optarg);
  71. if( d == 0.0 ) {
  72. (void)fprintf( stderr, "bwmod: divide by zero!\n" );
  73. exit( 2 );
  74. }
  75. val[ numop++ ] = 1.0 / d;
  76. break;
  77. case 'A':
  78. op[ numop ] = ABS;
  79. val[ numop++ ] = 0;
  80. break;
  81. case 'e':
  82. op[ numop ] = POW;
  83. val[ numop++ ] = atof(optarg);
  84. break;
  85. case 'r':
  86. op[ numop ] = POW;
  87. d = atof(optarg);
  88. if( d == 0.0 ) {
  89. (void)fprintf( stderr, "bwmod: zero root!\n" );
  90. exit( 2 );
  91. }
  92. val[ numop++ ] = 1.0 / d;
  93. break;
  94. default: /* '?' */
  95. return(0);
  96. }
  97. }
  98. if( optind >= argc ) {
  99. if( isatty((int)fileno(stdin)) )
  100. return(0);
  101. file_name = "-";
  102. } else {
  103. file_name = argv[optind];
  104. if( freopen(file_name, "r", stdin) == NULL ) {
  105. (void)fprintf( stderr,
  106. "bwmod: cannot open \"%s\" for reading\n",
  107. file_name );
  108. return(0);
  109. }
  110. }
  111. if ( argc > ++optind )
  112. (void)fprintf( stderr, "bwmod: excess argument(s) ignored\n" );
  113. return(1); /* OK */
  114. }
  115. void mk_trans_tbl()
  116. {
  117. register int i, j;
  118. register double d;
  119. /* create translation map */
  120. for (j = 0; j < 65536 ; ++j) {
  121. d = j;
  122. for (i=0 ; i < numop ; i++) {
  123. switch (op[i]) {
  124. case ADD : d += val[i]; break;
  125. case MULT: d *= val[i]; break;
  126. case POW : d = pow( d, val[i]); break;
  127. case ABS : if (d < 0.0) d = - d; break;
  128. default : (void)fprintf(stderr, "%s: error in op\n",
  129. progname); break;
  130. }
  131. }
  132. if (d > 65535.0)
  133. mapbuf[j] = 65537;
  134. else if (d < 0.0)
  135. mapbuf[j] = -1;
  136. else
  137. mapbuf[j] = d + 0.5;
  138. }
  139. }
  140. int main( argc, argv )
  141. int argc;
  142. char **argv;
  143. {
  144. register unsigned short *p, *q;
  145. register unsigned int n;
  146. unsigned long clip_high, clip_low;
  147. char *strrchr();
  148. if (!(progname=strrchr(*argv, '/')))
  149. progname = *argv;
  150. if( !get_args( argc, argv ) || isatty(fileno(stdin))
  151. || isatty(fileno(stdout)) ) {
  152. (void)fputs(usage, stderr);
  153. exit( 1 );
  154. }
  155. mk_trans_tbl();
  156. clip_high = clip_low = 0;
  157. while ( (n=fread(iobuf, sizeof(*iobuf), BUFLEN, stdin)) > 0) {
  158. /* translate */
  159. for (p=iobuf, q= &iobuf[n] ; p < q ; ++p) {
  160. if (mapbuf[*p] > 65535) { ++clip_high; *p = 65535; }
  161. else if (mapbuf[*p] < -0) { ++clip_low; *p = 0; }
  162. else *p = (unsigned short)mapbuf[*p];
  163. }
  164. /* output */
  165. if (fwrite(iobuf, sizeof(*iobuf), n, stdout) != n) {
  166. (void)fprintf(stderr, "%s: Error writing stdout\n",
  167. progname);
  168. exit(-1);
  169. }
  170. }
  171. if( clip_high != 0L || clip_low != 0L ) {
  172. (void)fprintf( stderr, "%s: clipped %lu high, %lu low\n",
  173. progname,
  174. clip_high, clip_low );
  175. }
  176. return(0);
  177. }