home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / pnm / pnmcomp.c < prev    next >
C/C++ Source or Header  |  1993-10-04  |  6KB  |  183 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1992, David Koblas.                                     | */
  3. /* |   Permission to use, copy, modify, and distribute this software   | */
  4. /* |   and its documentation for any purpose and without fee is hereby | */
  5. /* |   granted, provided that the above copyright notice appear in all | */
  6. /* |   copies and that both that copyright notice and this permission  | */
  7. /* |   notice appear in supporting documentation.  This software is    | */
  8. /* |   provided "as is" without express or implied warranty.           | */
  9. /* +-------------------------------------------------------------------+ */
  10.  
  11. #include "pnm.h"
  12. #include "pgm.h"
  13. #include "ppm.h"
  14.  
  15. static gray     **alpha = NULL;
  16. static int      alphaCols, alphaRows;
  17. static xelval   alphaMax;
  18. static pixel    **image = NULL;
  19. static int      imageCols, imageRows, imageType;
  20. static xelval   imageMax;
  21. static int      InvertFlag = 0;
  22.  
  23. static char     *usage =
  24.         "[-invert] [-xoff N] [-yoff N] [-alpha file] overlay [image] [output]";
  25.  
  26. /* prototypes */
  27. void composite ARGS((int xoff, int yoff, FILE *ifp, FILE *ofp));
  28.  
  29. int
  30. main(argc, argv)
  31. int     argc;
  32. char    *argv[];
  33. {
  34.         int     xoff = 0, yoff = 0;
  35.         FILE    *ifp, *ofp, *fp;
  36.         int     argn = 1;
  37.  
  38.  
  39.         pnm_init(&argc, argv);
  40.  
  41.         while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0') {
  42.                 if (pm_keymatch(argv[argn], "-xoff", 2)) {
  43.                         if (argn == argc ||
  44.                             sscanf(argv[++argn], "%d", &xoff) != 1)
  45.                                 pm_usage(usage);
  46.                 } else if (pm_keymatch(argv[argn], "-yoff", 2)) {
  47.                         if (argn == argc ||
  48.                             sscanf(argv[++argn], "%d", &yoff) != 1)
  49.                                 pm_usage(usage);
  50.                 } else if (pm_keymatch(argv[argn], "-alpha", 2)) {
  51.                         if (argn == argc || alpha != NULL)
  52.                                 pm_usage(usage);
  53.  
  54.                         fp = pm_openr(argv[++argn]);
  55.                         alpha = pgm_readpgm(fp, &alphaCols,
  56.                                                 &alphaRows, &alphaMax);
  57.                         pm_close(fp);
  58.                 } else if (pm_keymatch(argv[argn], "-invert", 2)) {
  59.                         InvertFlag = 1;
  60.                 } else {
  61.                         pm_usage(usage);
  62.                 }
  63.                 argn++;
  64.         }
  65.  
  66.         /*
  67.         **  Read the overlay file
  68.         */
  69.         if (argc == argn)
  70.                 pm_usage(usage);
  71.  
  72.         fp = pm_openr(argv[argn++]);
  73.         image = pnm_readpnm(fp, &imageCols, &imageRows, &imageMax, &imageType);
  74.         pm_close(fp);
  75.  
  76.         /*
  77.         **  If there is an alphamap check to make sure it is the
  78.         **    same size as the image.
  79.         */
  80.         if (alpha != NULL && (imageCols!=alphaCols || imageRows!=alphaRows))
  81.                 pm_error("Alpha map and Image are not the same size");
  82.  
  83.         /*
  84.         **  Now get the data file
  85.         */
  86.         if (argc != argn)
  87.                 ifp = pm_openr(argv[argn++]);
  88.         else
  89.                 ifp = stdin;
  90.  
  91.         /*
  92.         **  And the output file
  93.         */
  94.         if (argc != argn)
  95.                 ofp = pm_openw(argv[argn++]);
  96.         else
  97.                 ofp = stdout;
  98.  
  99.         /*
  100.         **  Composite the images together
  101.         */
  102.         composite(xoff, yoff, ifp, ofp);
  103.  
  104.         pm_close(ifp);
  105.         pm_close(ofp);
  106. }
  107.  
  108. void composite(xoff, yoff, ifp, ofp)
  109. int     xoff, yoff;
  110. FILE    *ifp, *ofp;
  111. {
  112.         int     x, y, x0, y0;
  113.         int     r,g,b;
  114.         xelval  v, maxv, omaxv;
  115.         xel     *pixels;
  116.         double  f;
  117.         int     rows, cols, type, otype;
  118.  
  119.         pnm_readpnminit(ifp, &cols, &rows, &maxv, &type);
  120.  
  121.         pixels = pnm_allocrow(cols);
  122.  
  123.         pnm_writepnminit(ofp, cols, rows, maxv, type, 0);
  124.  
  125.         /*
  126.         **  Convert overlay image to common type & max
  127.         */
  128.         otype = (imageType < type) ? type : imageType;
  129.         omaxv = (imageMax  < maxv) ? maxv : imageMax;
  130.  
  131.         if (imageType != otype || imageMax != omaxv) {
  132.                 pnm_promoteformat(image, imageCols, imageRows,
  133.                                 imageMax, imageType, omaxv, otype);
  134.                 imageType = otype;
  135.                 imageMax  = omaxv;
  136.         }
  137.  
  138.         for (y = 0; y < rows; y++) {
  139.                 /*
  140.                 **  Read a row and convert it to the output type
  141.                 */
  142.                 pnm_readpnmrow(ifp, pixels, cols, maxv, type);
  143.  
  144.                 if (type != otype || maxv != omaxv)
  145.                         pnm_promoteformatrow(pixels, cols, maxv,
  146.                                                 type, omaxv, otype);
  147.  
  148.                 /*
  149.                 **  Now overlay the overlay with alpha (if defined)
  150.                 */
  151.                 for (x = 0; x < cols; x++) {
  152.                         x0 = x - xoff;
  153.                         y0 = y - yoff;
  154.  
  155.                         if (x0 < 0 || x0 >= imageCols)
  156.                                 continue;
  157.                         if (y0 < 0 || y0 >= imageRows)
  158.                                 continue;
  159.  
  160.                         if (alpha == NULL) {
  161.                                 f = 1.0;
  162.                         } else {
  163.                                 f = (double)alpha[y0][x0] / (double)alphaMax;
  164.                                 if (InvertFlag)
  165.                                         f = 1.0 - f;
  166.                         }
  167.  
  168.                         r = PPM_GETR(pixels[x])     * (1.0 - f) +
  169.                             PPM_GETR(image[y0][x0]) * f;
  170.                         g = PPM_GETG(pixels[x])     * (1.0 - f) +
  171.                             PPM_GETG(image[y0][x0]) * f;
  172.                         b = PPM_GETB(pixels[x])     * (1.0 - f) +
  173.                             PPM_GETB(image[y0][x0]) * f;
  174.  
  175.                         PPM_ASSIGN(pixels[x], r, g, b);
  176.                 }
  177.  
  178.                 pnm_writepnmrow(ofp, pixels, cols, maxv, otype, 0);
  179.         }
  180.  
  181.         pnm_freerow(pixels);
  182. }
  183.