home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 309.lha / PBM_PLUS / pnm / pnmcrop.c < prev    next >
C/C++ Source or Header  |  1980-12-04  |  4KB  |  147 lines

  1. /* pnmcrop.c - crop a portable anymap
  2. **
  3. ** Copyright (C) 1988 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 <stdio.h>
  14. #ifdef    SYSV
  15. #include <string.h>
  16. #else    SYSV
  17. #include <strings.h>
  18. #endif    SYSV
  19. #include "pnm.h"
  20.  
  21. #define max(a,b) ((a) > (b) ? (a) : (b))
  22.  
  23. main( argc, argv )
  24. int argc;
  25. char *argv[];
  26.     {
  27.     FILE *ifd;
  28.     register xel **xels, *newxelrow, *xP, *nxP;
  29.     xel background;
  30.     xelval maxval;
  31.     int argn, format, backdefault, backblack;
  32.     int rows, cols, row, col, newrows, newcols;
  33.     int top, bottom, left, right;
  34.     char *usage = "[-white|-black] [pnmfile]";
  35.  
  36.     pm_progname = argv[0];
  37.  
  38.     argn = 1;
  39.     backdefault = 1;
  40.  
  41.     /* Check for flags. */
  42.     if ( argn < argc && argv[argn][0] == '-' )
  43.     {
  44.     if ( strncmp(argv[argn],"-white",max(strlen(argv[argn]),2)) == 0 )
  45.         {
  46.         backdefault = 0;
  47.         backblack = 0;
  48.         }
  49.     else if ( strncmp(argv[argn],"-black",max(strlen(argv[argn]),2)) == 0 )
  50.         {
  51.         backdefault = 0;
  52.         backblack = 1;
  53.         }
  54.     else
  55.         pm_usage( usage );
  56.     argn++;
  57.     }
  58.  
  59.     if ( argn != argc )
  60.     {
  61.     ifd = pm_openr( argv[argn] );
  62.     argn++;
  63.     }
  64.     else
  65.     ifd = stdin;
  66.  
  67.     if ( argn != argc )
  68.     pm_usage( usage );
  69.  
  70.     xels = pnm_readpnm( ifd, &cols, &rows, &maxval, &format );
  71.     pm_close( ifd );
  72.  
  73.     if ( backdefault )
  74.     background = pnm_backgroundxel( xels, cols, rows, maxval, format );
  75.     else
  76.     if ( backblack )
  77.         background = pnm_blackxel( maxval, format );
  78.     else
  79.         background = pnm_whitexel( maxval, format );
  80.  
  81.     /* Find first non-background line. */
  82.     for ( top = 0; top < rows; top++ )
  83.     for ( col = 0, xP = xels[top]; col < cols; col++, xP++ )
  84.         if ( ! PNM_EQUAL( *xP, background ) )
  85.         goto gottop;
  86. gottop:
  87.  
  88.     /* Find last non-background line. */
  89.     for ( bottom = rows - 1; bottom >= top; bottom-- )
  90.     for ( col = 0, xP = xels[bottom]; col < cols; col++, xP++ )
  91.         if ( ! PNM_EQUAL( *xP, background ) )
  92.         goto gotbottom;
  93. gotbottom:
  94.  
  95.     /* Find first non-background column.  To avoid massive paging on
  96.     ** large anymaps, we use a different loop than the above two cases. */
  97.     left = cols - 1;
  98.     for ( row = top; row <= bottom; row++ )
  99.     {
  100.     int thisleft;
  101.  
  102.     for ( thisleft = 0; thisleft < left; thisleft++ )
  103.         if ( ! PNM_EQUAL( xels[row][thisleft], background ) )
  104.         {
  105.         left = thisleft;
  106.         break;
  107.         }
  108.     }
  109.  
  110.     /* Find last non-background column.  Again, use row-major loop. */
  111.     right = left + 1;
  112.     for ( row = top; row <= bottom; row++ )
  113.     {
  114.     int thisright;
  115.  
  116.     for ( thisright = cols - 1; thisright > right; thisright-- )
  117.         if ( ! PNM_EQUAL( xels[row][thisright], background ) )
  118.         {
  119.         right = thisright;
  120.         break;
  121.         }
  122.     }
  123.  
  124.     if ( top > 0 )
  125.     fprintf( stderr, "(cropping %d rows off the top)\n", top );
  126.     if ( bottom < rows - 1 )
  127.     fprintf( stderr, "(cropping %d rows off the bottom)\n", rows - 1 - bottom );
  128.     if ( left > 0 )
  129.     fprintf( stderr, "(cropping %d cols off the left)\n", left );
  130.     if ( right < cols - 1 )
  131.     fprintf( stderr, "(cropping %d cols off the right)\n", cols - 1 - right );
  132.  
  133.     /* Now write out the new anymap. */
  134.     newcols = right - left + 1;
  135.     newrows = bottom - top + 1;
  136.     pnm_writepnminit( stdout, newcols, newrows, maxval, format );
  137.     newxelrow = pnm_allocrow( newcols );
  138.     for ( row = top; row <= bottom; row++ )
  139.     {
  140.         for ( col = left, xP = &(xels[row][left]), nxP = newxelrow; col <= right; col++, xP++, nxP++ )
  141.         *nxP = *xP;
  142.     pnm_writepnmrow( stdout, newxelrow, newcols, maxval, format );
  143.     }
  144.  
  145.     exit( 0 );
  146.     }
  147.