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

  1. /* pnmcat.c - concatenate portable anymaps
  2. **
  3. ** Copyright (C) 1989, 1991 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** ifp;
  21.     register xel* newxelrow;
  22.     xel** xelrow;
  23.     xel* background;
  24.     xelval* maxval;
  25.     xelval newmaxval;
  26.     int argn, backdefault, backblack, lrflag, tbflag, justify, nfiles;
  27.     int* rows;
  28.     int* cols;
  29.     int* format;
  30.     int newformat;
  31.     int i, row;
  32.     register int col;
  33.     int newrows, newcols, new;
  34.     char* usage = "[-white|-black] -leftright|-lr [-jtop|-jbottom] pnmfile ...\n               [-white|-black] -topbottom|-tb [-jleft|-jright] pnmfile ...";
  35.  
  36.     pnm_init( &argc, argv );
  37.  
  38.     argn = 1;
  39.     backdefault = 1;
  40.     lrflag = tbflag = 0;
  41.     justify = 0;
  42.  
  43.     /* Check for flags. */
  44.     while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  45.     {
  46.     if ( pm_keymatch( argv[argn], "-white", 2 ) )
  47.         {
  48.         backdefault = 0;
  49.         backblack = 0;
  50.         }
  51.     else if ( pm_keymatch( argv[argn], "-black", 2 ) )
  52.         {
  53.         backdefault = 0;
  54.         backblack = 1;
  55.         }
  56.     else if ( pm_keymatch( argv[argn], "-lr", 2 ) ||
  57.               pm_keymatch( argv[argn], "-leftright", 2 ) )
  58.         lrflag = 1;
  59.     else if ( pm_keymatch( argv[argn], "-tb", 2 ) ||
  60.               pm_keymatch( argv[argn], "-topbottom", 2 ) )
  61.         tbflag = 1;
  62.     else if ( pm_keymatch( argv[argn], "-jtop", 3 ) )
  63.         justify = -1;
  64.     else if ( pm_keymatch( argv[argn], "-jbottom", 3 ) )
  65.         justify = 1;
  66.     else if ( pm_keymatch( argv[argn], "-jleft", 3 ) )
  67.         justify = -1;
  68.     else if ( pm_keymatch( argv[argn], "-jright", 3 ) )
  69.         justify = 1;
  70.     else if ( pm_keymatch( argv[argn], "-jcenter", 3 ) )
  71.         justify = 0;
  72.     else
  73.         pm_usage( usage );
  74.     ++argn;
  75.     }
  76.  
  77.     if ( lrflag && tbflag )
  78.     pm_error( "only one of -lr and -tb may be specified" );
  79.     if ( ! ( lrflag || tbflag ) )
  80.     pm_error( "one of -lr or -tb must be specified" );
  81.  
  82.     if ( argn < argc )
  83.     nfiles = argc - argn;
  84.     else
  85.     nfiles = 1;
  86.     ifp = (FILE**) malloc( nfiles * sizeof(FILE*) );
  87.     xelrow = (xel**) malloc( nfiles * sizeof(xel*) );
  88.     background = (xel*) malloc( nfiles * sizeof(xel) );
  89.     maxval = (xelval*) malloc( nfiles * sizeof(xelval) );
  90.     rows = (int*) malloc( nfiles * sizeof(int) );
  91.     cols = (int*) malloc( nfiles * sizeof(int) );
  92.     format = (int*) malloc( nfiles * sizeof(int) );
  93.     if ( ifp == (FILE**) 0 || xelrow == (xel**) 0 || background == (xel*) 0 ||
  94.      maxval == (xelval*) 0 || rows == (int*) 0 || cols == (int*) 0 ||
  95.      format == (int*) 0 )
  96.     pm_error( "out of memory" );
  97.     if ( argn < argc )
  98.     {
  99.     for ( i = 0; i < nfiles; ++i )
  100.         ifp[i] = pm_openr( argv[argn+i] );
  101.     }
  102.     else
  103.     ifp[0] = stdin;
  104.  
  105.     newcols = 0;
  106.     newrows = 0;
  107.     for ( i = 0; i < nfiles; ++i )
  108.     {
  109.     pnm_readpnminit( ifp[i], &cols[i], &rows[i], &maxval[i], &format[i] );
  110.     if ( i == 0 )
  111.         {
  112.         newmaxval = maxval[i];
  113.         newformat = format[i];
  114.         }
  115.     else
  116.         {
  117.         if ( PNM_FORMAT_TYPE(format[i]) > PNM_FORMAT_TYPE(newformat) )
  118.         newformat = format[i];
  119.         if ( maxval[i] > newmaxval )
  120.         newmaxval = maxval[i];
  121.         }
  122.     xelrow[i] = pnm_allocrow( cols[i] );
  123.     if ( lrflag )
  124.         {
  125.         newcols += cols[i];
  126.         if ( rows[i] > newrows )
  127.         newrows = rows[i];
  128.         }
  129.     else
  130.         {
  131.         newrows += rows[i];
  132.         if ( cols[i] > newcols )
  133.         newcols = cols[i];
  134.         }
  135.     }
  136.     for ( i = 0; i < nfiles; ++i )
  137.     {
  138.     /* Read first row just to get a good guess at the background. */
  139.     pnm_readpnmrow( ifp[i], xelrow[i], cols[i], maxval[i], format[i] );
  140.     pnm_promoteformatrow(
  141.         xelrow[i], cols[i], maxval[i], format[i], newmaxval, newformat );
  142.     if (  backdefault )
  143.         background[i] =
  144.         pnm_backgroundxelrow(
  145.             xelrow[i], cols[i], newmaxval, newformat );
  146.     else
  147.         if ( backblack )
  148.         background[i] = pnm_blackxel( newmaxval, newformat );
  149.         else
  150.         background[i] = pnm_whitexel( newmaxval, newformat );
  151.     }
  152.  
  153.     newxelrow = pnm_allocrow( newcols );
  154.  
  155.     pnm_writepnminit( stdout, newcols, newrows, newmaxval, newformat, 0 );
  156.  
  157.     if ( lrflag )
  158.     {
  159.     for ( row = 0; row < newrows; ++row )
  160.         {
  161.         new = 0;
  162.         for ( i = 0; i < nfiles; ++i )
  163.         {
  164.         int padtop;
  165.  
  166.         if ( justify == -1 )
  167.             padtop = 0;
  168.         else if ( justify == 1 )
  169.             padtop = newrows - rows[i];
  170.         else
  171.             padtop = ( newrows - rows[i] ) / 2;
  172.         if ( row < padtop || row >= padtop + rows[i] )
  173.             {
  174.             for ( col = 0; col < cols[i]; ++col )
  175.             newxelrow[new+col] = background[i];
  176.             }
  177.         else
  178.             {
  179.             if ( row != padtop )    /* first row already read */
  180.             {
  181.             pnm_readpnmrow(
  182.                 ifp[i], xelrow[i], cols[i], maxval[i], format[i] );
  183.             pnm_promoteformatrow(
  184.                 xelrow[i], cols[i], maxval[i], format[i],
  185.                 newmaxval, newformat );
  186.             }
  187.             for ( col = 0; col < cols[i]; ++col )
  188.             newxelrow[new+col] = xelrow[i][col];
  189.             }
  190.         new += cols[i];
  191.         }
  192.         pnm_writepnmrow( stdout, newxelrow, newcols, newmaxval, newformat, 0 );
  193.         }
  194.     }
  195.     else
  196.     {
  197.     int padleft;
  198.  
  199.     new = 0;
  200.     i = 0;
  201.     if ( justify == -1 )
  202.         padleft = 0;
  203.     else if ( justify == 1 )
  204.         padleft = newcols - cols[i];
  205.     else
  206.         padleft = ( newcols - cols[i] ) / 2;
  207.  
  208.     for ( row = 0; row < newrows; ++row )
  209.         {
  210.         if ( row - new >= rows[i] )
  211.         {
  212.         new += rows[i];
  213.         ++i;
  214.         if ( i >= nfiles )
  215.             pm_error( "shouldn't happen" );
  216.         if ( justify == -1 )
  217.             padleft = 0;
  218.         else if ( justify == 1 )
  219.             padleft = newcols - cols[i];
  220.         else
  221.             padleft = ( newcols - cols[i] ) / 2;
  222.         }
  223.         if ( row - new > 0 )
  224.         {
  225.         pnm_readpnmrow(
  226.             ifp[i], xelrow[i], cols[i], maxval[i], format[i] );
  227.         pnm_promoteformatrow(
  228.             xelrow[i], cols[i], maxval[i], format[i],
  229.             newmaxval, newformat );
  230.         }
  231.         for ( col = 0; col < padleft; ++col )
  232.         newxelrow[col] = background[i];
  233.         for ( col = 0; col < cols[i]; ++col )
  234.         newxelrow[padleft+col] = xelrow[i][col];
  235.         for ( col = padleft + cols[i]; col < newcols; ++col )
  236.         newxelrow[col] = background[i];
  237.         pnm_writepnmrow( stdout, newxelrow, newcols, newmaxval, newformat, 0 );
  238.         }
  239.     }
  240.  
  241.     for ( i = 0; i < nfiles; ++i )
  242.     pm_close( ifp[i] );
  243.     pm_close( stdout );
  244.  
  245.     exit( 0 );
  246.     }
  247.