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

  1. /* pnmpaste.c - paste a rectangle into a portable anymap
  2. **
  3. ** Copyright (C) 1989 by Jef Poskanzer.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include "pnm.h"
  14.  
  15. int
  16. main( argc, argv )
  17.     int argc;
  18.     char* argv[];
  19.     {
  20.     FILE* ifp1;
  21.     FILE* ifp2;
  22.     register xel* xelrow1;
  23.     register xel* xelrow2;
  24.     register xel* x1P;
  25.     register xel* x2P;
  26.     xelval maxval1, maxval2, newmaxval;
  27.     int argn, rows1, cols1, format1, x, y;
  28.     int rows2, cols2, format2, newformat, row;
  29.     register int col;
  30.     char function;
  31.     char* usage = "[-replace|-or|-and|-xor] frompnmfile x y [intopnmfile]";
  32.  
  33.     pnm_init( &argc, argv );
  34.  
  35.     argn = 1;
  36.     function = 'r';
  37.  
  38.     /* Check for flags. */
  39.     if ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  40.     {
  41.     if ( pm_keymatch( argv[argn], "-replace", 2 ) )
  42.         function = 'r';
  43.     else if ( pm_keymatch( argv[argn], "-or", 2 ) )
  44.         function = 'o';
  45.     else if ( pm_keymatch( argv[argn], "-and", 2 ) )
  46.         function = 'a';
  47.     else if ( pm_keymatch( argv[argn], "-xor", 2 ) )
  48.         function = 'x';
  49.     else
  50.         pm_usage( usage );
  51.     ++argn;
  52.     }
  53.  
  54.     if ( argn == argc )
  55.     pm_usage( usage );
  56.     ifp1 = pm_openr( argv[argn] );
  57.     ++argn;
  58.  
  59.     if ( argn == argc )
  60.     pm_usage( usage );
  61.     if ( sscanf( argv[argn], "%d", &x ) != 1 )
  62.     pm_usage( usage );
  63.     ++argn;
  64.     if ( argn == argc )
  65.     pm_usage( usage );
  66.     if ( sscanf( argv[argn], "%d", &y ) != 1 )
  67.     pm_usage( usage );
  68.     ++argn;
  69.  
  70.     if ( argn != argc )
  71.     {
  72.     ifp2 = pm_openr( argv[argn] );
  73.     ++argn;
  74.     }
  75.     else
  76.     ifp2 = stdin;
  77.  
  78.     if ( argn != argc )
  79.     pm_usage( usage );
  80.  
  81.     pnm_readpnminit( ifp1, &cols1, &rows1, &maxval1, &format1 );
  82.     xelrow1 = pnm_allocrow(cols1);
  83.     pnm_readpnminit( ifp2, &cols2, &rows2, &maxval2, &format2 );
  84.     xelrow2 = pnm_allocrow(cols2);
  85.  
  86.     if ( x <= -cols2 )
  87.     pm_error(
  88.         "x is too negative -- the second anymap has only %d cols",
  89.         cols2 );
  90.     else if ( x >= cols2 )
  91.     pm_error(
  92.         "x is too large -- the second anymap has only %d cols",
  93.         cols2 );
  94.     if ( y <= -rows2 )
  95.     pm_error(
  96.         "y is too negative -- the second anymap has only %d rows",
  97.         rows2 );
  98.     else if ( y >= rows2 )
  99.     pm_error(
  100.         "y is too large -- the second anymap has only %d rows",
  101.         rows2 );
  102.  
  103.     if ( x < 0 )
  104.     x += cols2;
  105.     if ( y < 0 )
  106.     y += rows2;
  107.  
  108.     if ( x + cols1 > cols2 )
  109.     pm_error( "x + width is too large by %d pixels", x + cols1 - cols2 );
  110.     if ( y + rows1 > rows2 )
  111.     pm_error( "y + height is too large by %d pixels", y + rows1 - rows2 );
  112.  
  113.     newformat = max( PNM_FORMAT_TYPE(format1), PNM_FORMAT_TYPE(format2) );
  114.     newmaxval = max( maxval1, maxval2 );
  115.  
  116.     if ( function != 'r' && newformat != PBM_TYPE )
  117.     pm_error( "no logical operations allowed for non-bitmaps" );
  118.  
  119.     pnm_writepnminit( stdout, cols2, rows2, newmaxval, newformat, 0 );
  120.  
  121.     for ( row = 0; row < rows2; ++row )
  122.     {
  123.     pnm_readpnmrow( ifp2, xelrow2, cols2, maxval2, format2 );
  124.     pnm_promoteformatrow( xelrow2, cols2, maxval2, format2,
  125.         newmaxval, newformat );
  126.  
  127.     if ( row >= y && row < y + rows1 )
  128.         {
  129.         pnm_readpnmrow( ifp1, xelrow1, cols1, maxval1, format1 );
  130.         pnm_promoteformatrow( xelrow1, cols1, maxval1, format1,
  131.         newmaxval, newformat );
  132.         for ( col = 0, x1P = xelrow1, x2P = &(xelrow2[x]);
  133.           col < cols1; ++col, ++x1P, ++x2P )
  134.         {
  135.         register xelval b1, b2;
  136.  
  137.         switch ( function )
  138.             {
  139.             case 'r':
  140.             *x2P = *x1P;
  141.             break;
  142.  
  143.             case 'o':
  144.             b1 = PNM_GET1( *x1P );
  145.             b2 = PNM_GET1( *x2P );
  146.             if ( b1 != 0 || b2 != 0 )
  147.             PNM_ASSIGN1( *x2P, newmaxval );
  148.             else
  149.             PNM_ASSIGN1( *x2P, 0 );
  150.             break;
  151.  
  152.             case 'a':
  153.             b1 = PNM_GET1( *x1P );
  154.             b2 = PNM_GET1( *x2P );
  155.             if ( b1 != 0 && b2 != 0 )
  156.             PNM_ASSIGN1( *x2P, newmaxval );
  157.             else
  158.             PNM_ASSIGN1( *x2P, 0 );
  159.             break;
  160.  
  161.             case 'x':
  162.             b1 = PNM_GET1( *x1P );
  163.             b2 = PNM_GET1( *x2P );
  164.             if ( ( b1 != 0 && b2 == 0 ) || ( b1 == 0 && b2 != 0 ) )
  165.             PNM_ASSIGN1( *x2P, newmaxval );
  166.             else
  167.             PNM_ASSIGN1( *x2P, 0 );
  168.             break;
  169.  
  170.             default:
  171.             pm_error( "can't happen" );
  172.             }
  173.         }
  174.         }
  175.  
  176.     pnm_writepnmrow( stdout, xelrow2, cols2, newmaxval, newformat, 0 );
  177.     }
  178.     
  179.     pm_close( ifp1 );
  180.     pm_close( ifp2 );
  181.     pm_close( stdout );
  182.  
  183.     exit( 0 );
  184.     }
  185.