home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / CH_2.3 / IMGARITH / IMGARITH.C next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  6.7 KB  |  225 lines

  1. /* 
  2.  * imgarith.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /* IMGARITH:    program combines two images by arithmetic operation of
  10.  *          addition, subtraction, or multiplication
  11.  *          usage: imgarith in1img in2img outimg [-o OPERAND] [-x X] [-y Y] [-L]
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <tiffimage.h>          /* picfile info on images */
  18. #include <images.h>             /* for sun images */
  19. extern void print_sos_lic ();
  20.  
  21. int usage (short);
  22. int input (int, char **, char *, long *, long *);
  23.  
  24. main (argc, argv)
  25.      int argc;
  26.      char *argv[];
  27. {
  28.   register int x1, y1, x2, y2;  /* image incrementors */
  29.   register long temp;
  30.   Image *imgI1, *imgI2;         /* 2 input images, first is also output */
  31.   unsigned char **image1,       /* first and second input image */
  32.   **image2;                     /* first is also output image */
  33.   struct point imgSize1, imgSize2;  /* image dimensions */
  34.   char oper;                    /* operand */
  35.   double correction;            /* overflow correction max or min */
  36.   long x0, y0;                  /* x,y offset of second image in first */
  37.   long endX, endY;              /* end coord.s of image2 in image1 */
  38.  
  39. /* read user parameter values */
  40.   if ((input (argc, argv, &oper, &x0, &y0)) < 0)
  41.     return (-1);
  42.  
  43. /* open images */
  44.   imgI1 = ImageIn (argv[1]);
  45.   if (imgI1->bps == 8 && imgI1->spp == 3) {
  46.     printf ("Got RGB image!!!\nInput image must be Grayscale or B&W!!\n");
  47.     exit (1);
  48.   }
  49.   image1 = imgI1->img;
  50.   imgSize1.y = ImageGetHeight (imgI1);
  51.   imgSize1.x = ImageGetWidth (imgI1);
  52.  
  53.   imgI2 = ImageIn (argv[2]);
  54.   if (imgI2->bps == 8 && imgI2->spp == 3) {
  55.     printf ("Got RGB image!!!\nInput image must be Grayscale or B&W!!\n");
  56.     exit (1);
  57.   }
  58.   image2 = imgI2->img;
  59.   imgSize2.y = ImageGetHeight (imgI2);
  60.   imgSize2.x = ImageGetWidth (imgI2);
  61.  
  62.   printf ("input/output image size is %dx%d\n", imgSize1.x, imgSize1.y);
  63.   if (imgSize1.x != imgSize2.x || imgSize1.y != imgSize2.y)
  64.     printf ("(second image size is %dx%d)\n", imgSize2.x, imgSize2.y);
  65.  
  66.   endX = (imgSize2.x + x0 > imgSize1.x) ? imgSize1.x : imgSize2.x + x0;
  67.   endY = (imgSize2.y + y0 > imgSize1.y) ? imgSize1.y : imgSize2.y + y0;
  68.  
  69. /* perform arithmetic operations
  70.  * for each case, determine any overflow -- and use max or min to correct */
  71.  
  72.   switch (oper) {
  73.  
  74.   case '+':
  75.     correction = 255.0;
  76.     for (y1 = y0, y2 = 0; y1 < endY; y1++, y2++) {
  77.       for (x1 = x0, x2 = 0; x1 < endX; x1++, x2++) {
  78.         temp = image1[y1][x1] + image2[y2][x2];
  79.         if ((double) temp > correction)
  80.           correction = (double) temp;
  81.       }
  82.     }
  83.     for (y1 = y0, y2 = 0; y1 < endY; y1++, y2++) {
  84.       for (x1 = x0, x2 = 0; x1 < endX; x1++, x2++) {
  85.         temp = (long) ((double) (image1[y1][x1] + image2[y2][x2])
  86.                        * 255.0 / correction + 0.5);
  87.         image1[y1][x1] = (unsigned char) temp;
  88.       }
  89.     }
  90.     break;
  91.  
  92.   case '-':
  93.     correction = 0.0;
  94.     for (y1 = y0, y2 = 0; y1 < endY; y1++, y2++) {
  95.       for (x1 = x0, x2 = 0; x1 < endX; x1++, x2++) {
  96.         temp = image1[y1][x1] - image2[y2][x2];
  97.         if ((double) temp < correction)
  98.           correction = (double) temp;
  99.       }
  100.     }
  101.     for (y1 = y0, y2 = 0; y1 < endY; y1++, y2++) {
  102.       for (x1 = x0, x2 = 0; x1 < endX; x1++, x2++) {
  103.         temp = (long) (((double) (image1[y1][x1] - image2[y2][x2])
  104.                         - correction) * 255.0 / (255.0 - correction) + 0.5);
  105.         image1[y1][x1] = (unsigned char) temp;
  106.       }
  107.     }
  108.     break;
  109.   case 'x':
  110.     correction = 255.0;
  111.     for (y1 = y0, y2 = 0; y1 < endY; y1++, y2++) {
  112.       for (x1 = x0, x2 = 0; x1 < endX; x1++, x2++) {
  113.         temp = image1[y1][x1] * image2[y2][x2];
  114.         if ((double) temp > correction)
  115.           correction = (double) temp;
  116.       }
  117.     }
  118.     for (y1 = y0, y2 = 0; y1 < endY; y1++, y2++) {
  119.       for (x1 = x0, x2 = 0; x1 < endX; x1++, x2++) {
  120.         temp = (long) ((double) (image1[y1][x1] * image2[y2][x2])
  121.                        * 255.0 / correction + 0.5);
  122.         image1[y1][x1] = (unsigned char) temp;
  123.       }
  124.     }
  125.     break;
  126.   }
  127.  
  128.   if (correction != 0.0)
  129.     printf ("Intensities are rescaled for out-of-range intensity = %5.2f.\n",
  130.             correction);
  131.  
  132. /* write output image */
  133.   ImageOut (argv[3], imgI1);
  134.   return (0);
  135. }
  136.  
  137.  
  138. /* USAGE:       function gives instructions on usage of program
  139.  *                    usage: usage (flag)
  140.  *              When flag is 1, the long message is given, 0 gives short.
  141.  */
  142.  
  143. int
  144. usage (flag)
  145.      short flag;                /* flag =1 for long message; =0 for short message */
  146. {
  147.  
  148. /* print short usage message or long */
  149.   printf ("USAGE: imgarith in1img in2img outimg [-o OPERAND] [-x X] [-y Y] [-L]\n");
  150.   if (flag == 0)
  151.     return (-1);
  152.  
  153.   printf ("\nimgarith performs arithmetic combination between two\n");
  154.   printf ("images: addition, subtraction, or multiplication\n\n");
  155.   printf ("ARGUMENTS:\n");
  156.   printf ("   in1img: first input image filename (TIF)\n");
  157.   printf ("   in2img: second input image filename (TIF)\n");
  158.   printf ("   outimg: output image filename (TIF)\n\n");
  159.   printf ("OPTIONS:\n");
  160.   printf ("  -o OPERAND: <+,-,x> for addition, subtraction, or mult.\n");
  161.   printf ("              Default is addition (+).\n");
  162.   printf ("        -x X: X-offset location of second image in first.\n");
  163.   printf ("        -y Y: Y-offset location of second image in first.\n");
  164.   printf ("              default = (0,0).\n");
  165.   printf ("              Note that for images of different sizes, the resultant image\n");
  166.   printf ("              will be the size of the first specified image.\n");
  167.   printf ("          -L: print Software License for this module\n");
  168.  
  169.   return (-1);
  170. }
  171.  
  172.  
  173. /* INPUT:       function reads input parameters
  174.  *                  usage: input (argc, argv, &oper, &x0, &y0)
  175.  */
  176.  
  177. #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
  178.  
  179. int
  180. input (argc, argv, oper, x0, y0)
  181.      int argc;
  182.      char *argv[];
  183.      char *oper;                /* operand */
  184.      long *x0, *y0;             /* offset of second image in first */
  185. {
  186.   long n;
  187.  
  188.   if (argc == 1)
  189.     USAGE_EXIT (1);
  190.   if (argc == 2 || argc == 3)
  191.     USAGE_EXIT (0);
  192.  
  193.   *oper = '+';
  194.   *x0 = *y0 = 0;
  195.  
  196.   for (n = 4; n < argc; n++) {
  197.     if (strcmp (argv[n], "-o") == 0) {
  198.       if (++n == argc)
  199.         USAGE_EXIT (0);
  200.       *oper = *(argv[n]);
  201.     }
  202.     else if (strcmp (argv[n], "-x") == 0) {
  203.       if (++n == argc || argv[n][0] == '-')
  204.         USAGE_EXIT (0);
  205.       *x0 = atol (argv[n]);
  206.     }
  207.     else if (strcmp (argv[n], "-y") == 0) {
  208.       if (++n == argc || argv[n][0] == '-')
  209.         USAGE_EXIT (0);
  210.       *y0 = atol (argv[n]);
  211.     }
  212.     else if (strcmp (argv[n], "-L") == 0) {
  213.       print_sos_lic ();
  214.       exit (0);
  215.     }
  216.     else
  217.       USAGE_EXIT (0);
  218.   }
  219.  
  220.   if (*oper != '+' && *oper != '-' && *oper != 'x')
  221.     USAGE_EXIT (0);
  222.  
  223.   return (0);
  224. }
  225.