home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / netpbma.zip / pnm / pnmarith.c < prev    next >
C/C++ Source or Header  |  1994-01-05  |  5KB  |  211 lines

  1. /* pnmarith.c - perform arithmetic on two portable anymaps
  2. **
  3. ** slightly modified by Marcel Wijkstra <wijkstra@fwi.uva.nl>
  4. **
  5. **
  6. ** Copyright (C) 1989, 1991 by Jef Poskanzer.
  7. **
  8. ** Permission to use, copy, modify, and distribute this software and its
  9. ** documentation for any purpose and without fee is hereby granted, provided
  10. ** that the above copyright notice appear in all copies and that both that
  11. ** copyright notice and this permission notice appear in supporting
  12. ** documentation.  This software is provided "as is" without express or
  13. ** implied warranty.
  14. */
  15.  
  16. #include "pnm.h"
  17.  
  18. int
  19. main( argc, argv )
  20.     int argc;
  21.     char* argv[];
  22.     {
  23.     FILE* ifp1;
  24.     FILE* ifp2;
  25.     register xel* xelrow1;
  26.     register xel* xelrow2;
  27.     register xel* x1P;
  28.     register xel* x2P;
  29.     xelval maxval1, maxval2, maxval3;
  30.     int argn, rows1, cols1, format1, rows2, cols2, format2, format3, row, col;
  31.     char function;
  32.     char* usage = "-add|-subtract|-multiply|-difference pnmfile1 pnmfile2";
  33.  
  34.  
  35.     pnm_init( &argc, argv );
  36.  
  37.     argn = 1;
  38.     function = ' ';
  39.  
  40.     /* Check for flags. */
  41.     if ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  42.     {
  43.     if ( pm_keymatch( argv[argn], "-add", 2 ) )
  44.         function = '+';
  45.     else if ( pm_keymatch( argv[argn], "-subtract", 2 ) )
  46.         function = '-';
  47.     else if ( pm_keymatch( argv[argn], "-multiply", 2 ) )
  48.         function = '*';
  49.     else if ( pm_keymatch( argv[argn], "-difference", 2 ) )
  50.         function = 'D';
  51.     else
  52.         pm_usage( usage );
  53.     ++argn;
  54.     }
  55.  
  56.     if ( function == ' ' )
  57.     pm_usage( usage );
  58.  
  59.     if ( argn == argc )
  60.     pm_usage( usage );
  61.     ifp1 = pm_openr( argv[argn] );
  62.     ++argn;
  63.  
  64.     if ( argn == argc )
  65.     pm_usage( usage );
  66.     ifp2 = pm_openr( argv[argn] );
  67.     ++argn;
  68.  
  69.     if ( argn != argc )
  70.     pm_usage( usage );
  71.  
  72.     pnm_readpnminit( ifp1, &cols1, &rows1, &maxval1, &format1 );
  73.     xelrow1 = pnm_allocrow( cols1 );
  74.     pnm_readpnminit( ifp2, &cols2, &rows2, &maxval2, &format2 );
  75.     if ( cols2 != cols1 || rows2 != rows1 )
  76.     pm_error(
  77.         "the two anymaps must be the same width and height" );
  78.     xelrow2 = pnm_allocrow( cols1 );
  79.  
  80.     maxval3 = max( maxval1, maxval2 );
  81.     format3 = max( PNM_FORMAT_TYPE(format1), PNM_FORMAT_TYPE(format2) );
  82.     if ( PNM_FORMAT_TYPE(format1) != format3 ||
  83.      PNM_FORMAT_TYPE(format2) != format3 )
  84.     {
  85.     switch ( PNM_FORMAT_TYPE(format3) )
  86.         {
  87.         case PPM_TYPE:
  88.         if ( PNM_FORMAT_TYPE(format1) != format3 )
  89.         pm_message( "promoting first file to PPM" );
  90.         if ( PNM_FORMAT_TYPE(format2) != format3 )
  91.         pm_message( "promoting second file to PPM" );
  92.         break;
  93.         case PGM_TYPE:
  94.         if ( PNM_FORMAT_TYPE(format1) != format3 )
  95.         pm_message( "promoting first file to PGM" );
  96.         if ( PNM_FORMAT_TYPE(format2) != format3 )
  97.         pm_message( "promoting second file to PGM" );
  98.         break;
  99.         }
  100.     }
  101.  
  102.     pnm_writepnminit( stdout, cols1, rows1, maxval3, format3, 0 );
  103.     for ( row = 0; row < rows1; ++row )
  104.     {
  105.     pnm_readpnmrow( ifp1, xelrow1, cols1, maxval1, format1 );
  106.     if ( maxval1 != maxval3 || PNM_FORMAT_TYPE(format1) != format3 )
  107.         pnm_promoteformatrow(
  108.         xelrow1, cols1, maxval1, format1, maxval3, format3 );
  109.  
  110.     pnm_readpnmrow( ifp2, xelrow2, cols1, maxval2, format2 );
  111.     if ( maxval2 != maxval3 || PNM_FORMAT_TYPE(format2) != format3 )
  112.         pnm_promoteformatrow(
  113.         xelrow2, cols1, maxval2, format2, maxval3, format3 );
  114.  
  115.         for ( col = 0, x1P = xelrow1, x2P = xelrow2;
  116.           col < cols1; ++col, ++x1P, ++x2P )
  117.         {
  118.         switch ( PNM_FORMAT_TYPE(format3) )
  119.         {
  120.         case PPM_TYPE:
  121.         {
  122.         int r1, g1, b1, r2, g2, b2;
  123.  
  124.         r1 = PPM_GETR( *x1P );
  125.         g1 = PPM_GETG( *x1P );
  126.         b1 = PPM_GETB( *x1P );
  127.         r2 = PPM_GETR( *x2P );
  128.         g2 = PPM_GETG( *x2P );
  129.         b2 = PPM_GETB( *x2P );
  130.         switch ( function )
  131.             {
  132.             case '+':
  133.             r1 += r2;
  134.             g1 += g2;
  135.             b1 += b2;
  136.             break;
  137.  
  138.             case '-':
  139.             r1 -= r2;
  140.             g1 -= g2;
  141.             b1 -= b2;
  142.             break;
  143.  
  144.             case '*':
  145.             r1 = r1 * r2 / maxval3;
  146.             g1 = g1 * g2 / maxval3;
  147.             b1 = b1 * b2 / maxval3;
  148.             break;
  149.  
  150.             case 'D':
  151.             r1 = (r1>r2)?(r1-r2):(r2-r1);
  152.             g1 = (g1>g2)?(g1-g2):(g2-g1);
  153.             b1 = (b1>b2)?(b1-b2):(b2-b1);
  154.             break;
  155.  
  156.             default:
  157.             pm_error( "can't happen" );
  158.             }
  159.         if ( r1 < 0 ) r1 = 0;
  160.         else if ( r1 > maxval3 ) r1 = maxval3;
  161.         if ( g1 < 0 ) g1 = 0;
  162.         else if ( g1 > maxval3 ) g1 = maxval3;
  163.         if ( b1 < 0 ) b1 = 0;
  164.         else if ( b1 > maxval3 ) b1 = maxval3;
  165.         PPM_ASSIGN( *x1P, r1, g1, b1 );
  166.         }
  167.         break;
  168.  
  169.         default:
  170.         {
  171.         int g1, g2;
  172.  
  173.         g1 = PNM_GET1( *x1P );
  174.         g2 = PNM_GET1( *x2P );
  175.         switch ( function )
  176.             {
  177.             case '+':
  178.             g1 += g2;
  179.             break;
  180.  
  181.             case '-':
  182.             g1 -= g2;
  183.             break;
  184.  
  185.             case '*':
  186.             g1 = g1 * g2 / maxval3;
  187.             break;
  188.  
  189.             case 'D':
  190.             g1 = (g1>g2)?(g1-g2):(g2-g1);
  191.             break;
  192.  
  193.             default:
  194.             pm_error( "can't happen" );
  195.             }
  196.         if ( g1 < 0 ) g1 = 0;
  197.         else if ( g1 > maxval3 ) g1 = maxval3;
  198.         PNM_ASSIGN1( *x1P, g1 );
  199.         }
  200.         break;
  201.         }
  202.         }
  203.     pnm_writepnmrow( stdout, xelrow1, cols1, maxval3, format3, 0 );
  204.     }
  205.  
  206.     pm_close( ifp1 );
  207.     pm_close( ifp2 );
  208.  
  209.     exit( 0 );
  210.     }
  211.