home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume5 / pbm3 / part3 / pbmcrop.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-03  |  4.1 KB  |  180 lines

  1. /* pbmcrop.c - crop a portable bitmap
  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. #include "pbm.h"
  15.  
  16. main( argc, argv )
  17. int argc;
  18. char *argv[];
  19.     {
  20.     FILE *ifd;
  21.     bit **bits, **newbits, background;
  22.     int argn, backdefault, c;
  23.     int rows, cols, row, col, newrows, newcols;
  24.     int top, bottom, left, right;
  25.     char *usage = "usage:  %s [-0]/[-w]/[-1]/[-b] [pbmfile]\n";
  26.  
  27.     argn = 1;
  28.     backdefault = 1;
  29.  
  30.     /* Check for flags. */
  31.     if ( argn < argc )
  32.     {
  33.     if ( argv[argn][0] == '-' )
  34.         {
  35.         if ( ( argv[argn][1] == '0' || argv[argn][1] == 'w' ||
  36.            argv[argn][1] == 'W' ) && argv[argn][2] == '\0' )
  37.         {
  38.         backdefault = 0;
  39.         background = 0;
  40.         }
  41.         else if ( ( argv[argn][1] == '1' || argv[argn][1] == 'b' ||
  42.             argv[argn][1] == 'B' ) && argv[argn][2] == '\0' )
  43.         {
  44.         backdefault = 0;
  45.         background = 1;
  46.         }
  47.         else
  48.         {
  49.         fprintf( stderr, usage, argv[0] );
  50.         exit( 1 );
  51.         }
  52.         argn++;
  53.         }
  54.     }
  55.  
  56.     if ( argn == argc )
  57.     ifd = stdin;
  58.     else
  59.     {
  60.         ifd = fopen( argv[argn], "r" );
  61.         if ( ifd == NULL )
  62.         {
  63.         fprintf( stderr, "%s: can't open.\n", argv[argn] );
  64.         exit( 1 );
  65.         }
  66.     argn++;
  67.     }
  68.     bits = pbm_readpbm( ifd, &cols, &rows );
  69.     if ( ifd != stdin )
  70.     fclose( ifd );
  71.  
  72.     if ( argn != argc )
  73.     {
  74.     fprintf( stderr, usage, argv[0] );
  75.     exit( 1 );
  76.     }
  77.  
  78.     if ( backdefault )
  79.     {
  80.     /* Guess what the background is by looking for an edge of
  81.     ** all one color.
  82.     */
  83.     c = 0;
  84.     for ( col = 0; col < cols; col++ )
  85.         c += bits[0][col];
  86.     if ( c == 0 )
  87.         background = 0;
  88.     else if ( c == cols )
  89.         background = 1;
  90.     else
  91.         {
  92.         c = 0;
  93.         for ( col = 0; col < cols; col++ )
  94.         c += bits[rows - 1][col];
  95.         if ( c == 0 )
  96.         background = 0;
  97.         else if ( c == cols )
  98.         background = 1;
  99.         else
  100.         {
  101.         c = 0;
  102.         for ( row = 0; row < rows; row++ )
  103.             c += bits[row][0];
  104.         if ( c == 0 )
  105.             background = 0;
  106.         else if ( c == rows )
  107.             background = 1;
  108.         else
  109.             {
  110.             c = 0;
  111.             for ( row = 0; row < rows; row++ )
  112.             c += bits[row][cols - 1];
  113.             if ( c == 0 )
  114.             background = 0;
  115.             else if ( c == rows )
  116.             background = 1;
  117.             else
  118.             {
  119.             fprintf( stderr, "(nothing to crop, continuing)\n" );
  120.             background = 0;        /* arbitrary */
  121.             }
  122.             }
  123.         }
  124.         }
  125.     }
  126.  
  127.     /* Find first non-background line. */
  128.     for ( top = 0; top < rows; top++ )
  129.     for ( col = 0; col < cols; col++ )
  130.         if ( bits[top][col] != background )
  131.         goto gottop;
  132. gottop:
  133.  
  134.     /* Find last non-background line. */
  135.     for ( bottom = rows - 1; bottom >= top; bottom-- )
  136.     for ( col = 0; col < cols; col++ )
  137.         if ( bits[bottom][col] != background )
  138.         goto gotbottom;
  139. gotbottom:
  140.  
  141.     /* Find first non-background column. */
  142.     for ( left = 0; left < cols; left++ )
  143.     for ( row = top; row <= bottom; row++ )
  144.         if ( bits[row][left] != background )
  145.         goto gotleft;
  146. gotleft:
  147.  
  148.     /* Find last non-background column. */
  149.     for ( right = cols - 1; right > left; right-- )
  150.     for ( row = top; row <= bottom; row++ )
  151.         if ( bits[row][right] != background )
  152.         goto gotright;
  153. gotright:
  154.  
  155.     if ( top > 0 )
  156.     fprintf( stderr, "(cropping %d %d-rows off the top)\n",
  157.          top, background );
  158.     if ( bottom < rows - 1 )
  159.     fprintf( stderr, "(cropping %d %d-rows off the bottom)\n",
  160.          rows - 1 - bottom, background );
  161.     if ( left > 0 )
  162.     fprintf( stderr, "(cropping %d %d-cols off the left)\n",
  163.          left, background );
  164.     if ( right < cols - 1 )
  165.     fprintf( stderr, "(cropping %d %d-cols off the right)\n",
  166.          cols - 1 - right, background );
  167.  
  168.     /* Now copy into a new array. */
  169.     newcols = right - left + 1;
  170.     newrows = bottom - top + 1;
  171.     newbits = pbm_allocarray( newcols, newrows );
  172.     for ( row = top; row <= bottom; row++ )
  173.         for ( col = left; col <= right; col++ )
  174.         newbits[row-top][col-left] = bits[row][col];
  175.  
  176.     pbm_writepbm( stdout, newbits, newcols, newrows );
  177.  
  178.     exit( 0 );
  179.     }
  180.