home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / NETWORK / netpbm_src.lzh / NETPBM / PNM / pnmarith.c < prev    next >
C/C++ Source or Header  |  1996-11-18  |  6KB  |  236 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 =
  33. "-add|-subtract|-multiply|-difference|-minimum|-maximum pnmfile1 pnmfile2";
  34.  
  35.  
  36.     pnm_init( &argc, argv );
  37.  
  38.     argn = 1;
  39.     function = ' ';
  40.  
  41.     /* Check for flags. */
  42.     if ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  43.     {
  44.     if ( pm_keymatch( argv[argn], "-add", 2 ) )
  45.         function = '+';
  46.     else if ( pm_keymatch( argv[argn], "-subtract", 2 ) )
  47.         function = '-';
  48.     else if ( pm_keymatch( argv[argn], "-multiply", 2 ) )
  49.         function = '*';
  50.     else if ( pm_keymatch( argv[argn], "-difference", 2 ) )
  51.         function = 'D';
  52.     else if ( pm_keymatch( argv[argn], "-minimum", 2 ) )
  53.         function = 'N';
  54.     else if ( pm_keymatch( argv[argn], "-maximum", 2 ) )
  55.         function = 'X';
  56.     else
  57.         pm_usage( usage );
  58.     ++argn;
  59.     }
  60.  
  61.     if ( function == ' ' )
  62.     pm_usage( usage );
  63.  
  64.     if ( argn == argc )
  65.     pm_usage( usage );
  66.     ifp1 = pm_openr( argv[argn] );
  67.     ++argn;
  68.  
  69.     if ( argn == argc )
  70.     pm_usage( usage );
  71.     ifp2 = pm_openr( argv[argn] );
  72.     ++argn;
  73.  
  74.     if ( argn != argc )
  75.     pm_usage( usage );
  76.  
  77.     pnm_readpnminit( ifp1, &cols1, &rows1, &maxval1, &format1 );
  78.     xelrow1 = pnm_allocrow( cols1 );
  79.     pnm_readpnminit( ifp2, &cols2, &rows2, &maxval2, &format2 );
  80.     if ( cols2 != cols1 || rows2 != rows1 )
  81.     pm_error(
  82.         "the two anymaps must be the same width and height" );
  83.     xelrow2 = pnm_allocrow( cols1 );
  84.  
  85.     maxval3 = max( maxval1, maxval2 );
  86.     format3 = max( PNM_FORMAT_TYPE(format1), PNM_FORMAT_TYPE(format2) );
  87.     if ( PNM_FORMAT_TYPE(format1) != format3 ||
  88.      PNM_FORMAT_TYPE(format2) != format3 )
  89.     {
  90.     switch ( PNM_FORMAT_TYPE(format3) )
  91.         {
  92.         case PPM_TYPE:
  93.         if ( PNM_FORMAT_TYPE(format1) != format3 )
  94.         pm_message( "promoting first file to PPM" );
  95.         if ( PNM_FORMAT_TYPE(format2) != format3 )
  96.         pm_message( "promoting second file to PPM" );
  97.         break;
  98.         case PGM_TYPE:
  99.         if ( PNM_FORMAT_TYPE(format1) != format3 )
  100.         pm_message( "promoting first file to PGM" );
  101.         if ( PNM_FORMAT_TYPE(format2) != format3 )
  102.         pm_message( "promoting second file to PGM" );
  103.         break;
  104.         }
  105.     }
  106.  
  107.     pnm_writepnminit( stdout, cols1, rows1, maxval3, format3, 0 );
  108.     for ( row = 0; row < rows1; ++row )
  109.     {
  110.     pnm_readpnmrow( ifp1, xelrow1, cols1, maxval1, format1 );
  111.     if ( maxval1 != maxval3 || PNM_FORMAT_TYPE(format1) != format3 )
  112.         pnm_promoteformatrow(
  113.         xelrow1, cols1, maxval1, format1, maxval3, format3 );
  114.  
  115.     pnm_readpnmrow( ifp2, xelrow2, cols1, maxval2, format2 );
  116.     if ( maxval2 != maxval3 || PNM_FORMAT_TYPE(format2) != format3 )
  117.         pnm_promoteformatrow(
  118.         xelrow2, cols1, maxval2, format2, maxval3, format3 );
  119.  
  120.     for ( col = 0, x1P = xelrow1, x2P = xelrow2;
  121.           col < cols1; ++col, ++x1P, ++x2P )
  122.         {
  123.         switch ( PNM_FORMAT_TYPE(format3) )
  124.         {
  125.         case PPM_TYPE:
  126.         {
  127.         int r1, g1, b1, r2, g2, b2;
  128.  
  129.         r1 = PPM_GETR( *x1P );
  130.         g1 = PPM_GETG( *x1P );
  131.         b1 = PPM_GETB( *x1P );
  132.         r2 = PPM_GETR( *x2P );
  133.         g2 = PPM_GETG( *x2P );
  134.         b2 = PPM_GETB( *x2P );
  135.         switch ( function )
  136.             {
  137.             case '+':
  138.             r1 += r2;
  139.             g1 += g2;
  140.             b1 += b2;
  141.             break;
  142.  
  143.             case '-':
  144.             r1 -= r2;
  145.             g1 -= g2;
  146.             b1 -= b2;
  147.             break;
  148.  
  149.             case '*':
  150.             r1 = r1 * r2 / maxval3;
  151.             g1 = g1 * g2 / maxval3;
  152.             b1 = b1 * b2 / maxval3;
  153.             break;
  154.  
  155.             case 'D':
  156.             r1 = (r1>r2)?(r1-r2):(r2-r1);
  157.             g1 = (g1>g2)?(g1-g2):(g2-g1);
  158.             b1 = (b1>b2)?(b1-b2):(b2-b1);
  159.             break;
  160.  
  161.             case 'N':
  162.             r1 = (r1>r2)?(r2):(r1);
  163.             g1 = (g1>g2)?(g2):(g1);
  164.             b1 = (b1>b2)?(b2):(b1);
  165.             break;
  166.   
  167.             case 'X':
  168.             r1 = (r1>r2)?(r1):(r2);
  169.             g1 = (g1>g2)?(g1):(g2);
  170.             b1 = (b1>b2)?(b1):(b2);
  171.             break;
  172.  
  173.             default:
  174.             pm_error( "can't happen" );
  175.             }
  176.         if ( r1 < 0 ) r1 = 0;
  177.         else if ( r1 > maxval3 ) r1 = maxval3;
  178.         if ( g1 < 0 ) g1 = 0;
  179.         else if ( g1 > maxval3 ) g1 = maxval3;
  180.         if ( b1 < 0 ) b1 = 0;
  181.         else if ( b1 > maxval3 ) b1 = maxval3;
  182.         PPM_ASSIGN( *x1P, r1, g1, b1 );
  183.         }
  184.         break;
  185.  
  186.         default:
  187.         {
  188.         int g1, g2;
  189.  
  190.         g1 = PNM_GET1( *x1P );
  191.         g2 = PNM_GET1( *x2P );
  192.         switch ( function )
  193.             {
  194.             case '+':
  195.             g1 += g2;
  196.             break;
  197.  
  198.             case '-':
  199.             g1 -= g2;
  200.             break;
  201.  
  202.             case '*':
  203.             g1 = g1 * g2 / maxval3;
  204.             break;
  205.  
  206.             case 'D':
  207.             g1 = (g1>g2)?(g1-g2):(g2-g1);
  208.             break;
  209.  
  210.             case 'N':
  211.             g1 = (g1>g2)?(g2):(g1);
  212.             break;
  213.   
  214.             case 'X':
  215.             g1 = (g1>g2)?(g1):(g2);
  216.             break;
  217.  
  218.             default:
  219.             pm_error( "can't happen" );
  220.             }
  221.         if ( g1 < 0 ) g1 = 0;
  222.         else if ( g1 > maxval3 ) g1 = maxval3;
  223.         PNM_ASSIGN1( *x1P, g1 );
  224.         }
  225.         break;
  226.         }
  227.         }
  228.     pnm_writepnmrow( stdout, xelrow1, cols1, maxval3, format3, 0 );
  229.     }
  230.  
  231.     pm_close( ifp1 );
  232.     pm_close( ifp2 );
  233.  
  234.     exit( 0 );
  235.     }
  236.