home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume19 / fbm / part05 / fbext.c next >
Encoding:
C/C++ Source or Header  |  1989-06-08  |  6.2 KB  |  213 lines

  1. /*****************************************************************
  2.  * fbext.c: FBM Library 0.94 (Beta test) 20-May-89  Michael Mauldin
  3.  *
  4.  * Copyright (C) 1989 by Michael Mauldin.  Permission is granted to
  5.  * use this file in whole or in part provided that you do not sell it
  6.  * for profit and that this copyright notice is retained unchanged.
  7.  *
  8.  * fbext.c: 
  9.  *
  10.  * USAGE
  11.  *    % fbext [ -w<width> -h<height> -W<maxwidth> -H<maxheight>
  12.  *         -a<aspect> -t'title' -c'credits' ]
  13.  *           [ x y width height ] < foo.fbm > bar.fbm
  14.  *
  15.  * EDITLOG
  16.  *    LastEditDate = Sat May 20 19:03:55 1989 - Michael Mauldin
  17.  *    LastFileName = /usr2/mlm/src/misc/fbm/fbext.c
  18.  *
  19.  * HISTORY
  20.  * 20-May-89  Michael Mauldin (mlm) at Carnegie Mellon University
  21.  *    Bug fix from Dave Cohrs <dave@cs.wisc.edu>
  22.  *
  23.  * 20-Apr-89  Michael Mauldin (mlm) at Carnegie Mellon University
  24.  *    Beta release (version 0.91) mlm@cs.cmu.edu
  25.  *
  26.  * 22-Aug-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  27.  *    Created.
  28.  *****************************************************************/
  29.  
  30. # include <stdio.h>
  31. # include <math.h>
  32. # include "fbm.h"
  33.  
  34. int allowrot = 0;
  35.  
  36. # define USAGE \
  37. "Usage:    fbext [ -w<width> -h<height> ] [ -R ]\n\
  38.           [ -W<maxwdith> -H<maxheight> -s<size> ]\n\
  39.           [ -a<aspect> -t'title' -c'credits' ] [ -<type> ]\n\
  40.           [ x y [ width height ] ]    < image > image"
  41.  
  42. #ifndef lint
  43. static char *fbmid =
  44.     "$FBM fbext.c <0.94> 20-May-89  (C) 1989 by Michael Mauldin$";
  45. #endif
  46.  
  47. main (argc, argv)
  48. char *argv[];
  49. { int xo = -1, yo = -1, w = -1, h = -1, ow = -1, oh = -1, size = -1;
  50.   int mh = -1, mw = -1;
  51.   double aspect = -1.0;
  52.   char title[FBM_MAX_TITLE], credits[FBM_MAX_TITLE];
  53.   FBM input, rotated, output, *image = &input;
  54.   int outtype = FMT_FBM;
  55.  
  56.   /* Clear the memory pointers so alloc_fbm won't be confused */
  57.   input.cm  = input.bm  = (unsigned char *) NULL;
  58.   rotated.cm = rotated.bm = (unsigned char *) NULL;
  59.   output.cm = output.bm = (unsigned char *) NULL;
  60.  
  61.   title[0] = '\0';
  62.   credits[0] = '\0';
  63.  
  64.   /* Get the options */
  65.   while (--argc > 0 && (*++argv)[0] == '-')
  66.   { while (*++(*argv))
  67.     { switch (**argv)
  68.       { case 't':    strcpy (title, *argv+1); CLRARG; break;
  69.     case 'c':    strcpy (credits, *argv+1); CLRARG; break;
  70.     case 'a':    aspect = atof (*argv+1); SKIPARG; break;
  71.     case 'w':    ow = atoi (*argv+1); SKIPARG; break;
  72.     case 'h':    oh = atoi (*argv+1); SKIPARG; break;
  73.     case 'W':    mw = atoi (*argv+1); SKIPARG; break;
  74.     case 'H':    mh = atoi (*argv+1); SKIPARG; break;
  75.     case 'R':    allowrot++; break;
  76.     case 's':    size = atoi (*argv+1); SKIPARG; break;
  77.     case 'A':    outtype = FMT_ATK; break;
  78.     case 'B':    outtype = FMT_FACE; break;
  79.     case 'F':    outtype = FMT_FBM; break;
  80.     case 'G':    outtype = FMT_GIF; break;
  81.     case 'I':    outtype = FMT_IFF; break;
  82.     case 'L':    outtype = FMT_LEAF; break;
  83.     case 'M':    outtype = FMT_MCP; break;
  84.     case 'P':    outtype = FMT_PBM; break;
  85.     case 'S':    outtype = FMT_SUN; break;
  86.     case 'T':    outtype = FMT_TIFF; break;
  87.     case 'X':    outtype = FMT_X11; break;
  88.     case 'Z':    outtype = FMT_PCX; break;
  89.     default:    fprintf (stderr, "%s\n", USAGE);
  90.             exit (1);
  91.       }
  92.     }
  93.   }
  94.  
  95.  
  96.   if (read_bitmap (&input, (char *) NULL))
  97.   {
  98.     if (image->hdr.physbits != 8)
  99.     { fprintf (stderr,
  100.            "Can't handle images with %d bits and %d physbits per pixel\n",
  101.            image->hdr.bits, image->hdr.physbits);
  102.       exit (1);
  103.     }
  104.  
  105.     /* Get arguments */
  106.     if (argc > 0)    xo    = atoi (argv[0]);
  107.     if (xo < 0)        xo    = 0;
  108.  
  109.     if (argc > 1)    yo    = atoi (argv[1]);
  110.     if (yo < 0)        yo    = 0;
  111.  
  112.     if (argc > 2)    w    = atoi (argv[2]);
  113.     if (w < 0)        w    = image->hdr.cols - xo;
  114.  
  115.     if (argc > 3)    h    = atoi (argv[3]);
  116.     if (h < 0)        h    = image->hdr.rows - yo;
  117.  
  118.     if (argc > 4)    ow    = atoi (argv[4]);
  119.  
  120.     if (argc > 5)    aspect = atof (argv[5]);
  121.     
  122.     /* If 'allowrot' is on, rotate image if its fits better */
  123.     if (allowrot && mh > 0 && mw > 0)
  124.     { int inhoriz=0, outhoriz=0;
  125.     
  126.       if (aspect < 0.0) aspect = 1.0;
  127.     
  128.       if (image->hdr.cols >= (image->hdr.aspect * image->hdr.rows)) inhoriz++;
  129.       if (mw >= (aspect * mh))                     outhoriz++;
  130.       
  131.       if (inhoriz != outhoriz)
  132.       { if (rotate_fbm (image, &rotated, 90))
  133.         { free (image);
  134.       image = &rotated;
  135.       
  136.       fprintf (stderr, "Rotating [%dx%d] image for better fit [%dx%d]\n",
  137.            image->hdr.rows, image->hdr.cols, mw, mh);
  138.     }
  139.       }
  140.       else
  141.       { exit (1); }
  142.     }
  143.  
  144.     /* If max number of pixels specified, calculate width and height */
  145.     if (size > 0)
  146.     { if (ow > 0 || oh > 0)
  147.       { fprintf (stderr,
  148.       "fbext: error, can only specify one of size and width,height\n");
  149.     exit (1);
  150.       }
  151.       
  152.       aspect = 1.0;
  153.  
  154.       ow = sqrt ((double) size * w / (h * image->hdr.aspect));
  155.       ow &= ~7;            /* Make width multiple of 8 */
  156.       oh = ow * image->hdr.aspect * h / w;
  157.     }
  158.  
  159.     /* If given width and height, must determine output aspect */
  160.     if (aspect <= 0.0)
  161.     { if (ow > 0 && oh > 0)
  162.       { aspect = image->hdr.aspect * ow * h / (oh * w); }
  163.       else
  164.       { aspect = image->hdr.aspect; }
  165.     }
  166.  
  167.     /* If given only maximum sizes, assume largest width */
  168.     if (ow <= 0 && oh <= 0)
  169.     { if (mw > 0)    ow = mw;
  170.       else if (mh > 0)    oh = mh;
  171.     }
  172.  
  173.     /*
  174.      * If given one of width or height, calculate the other.
  175.      * If given only aspect ratio, inflate the smaller dimension
  176.      */
  177.  
  178.     if (ow > 0 && oh > 0)
  179.     { /* Nothing to pick */ }
  180.     else if (ow <= 0 && oh > 0)
  181.     { ow = ((double) oh + 0.5) * (aspect / image->hdr.aspect) * w / h; }
  182.     else if (ow > 0 && oh <= 0)
  183.     { oh = ((double) ow + 0.5) * (image->hdr.aspect / aspect) * h / w; }
  184.     else if (aspect != image->hdr.aspect)
  185.     { if (aspect > image->hdr.aspect)
  186.       { oh = h;
  187.         ow = ((double) oh + 0.5) * (aspect / image->hdr.aspect) * w / h;
  188.       }
  189.       else
  190.       { ow = w;
  191.         oh = ((double) ow + 0.5) * (input.hdr.aspect / aspect) * h / w;
  192.       }
  193.     }
  194.     else
  195.     { ow = w; oh = h; }
  196.      
  197.     /* If either dimension exceeds given maximums, shrink the image to fit */
  198.     if (mh > 0 && oh > mh)
  199.     { ow = ow * mh / oh; oh = mh; }
  200.  
  201.     /* Now extract the specified rectangle and write it out */
  202.     if (mw > 0 && ow > mw)
  203.     { oh = oh * mw / ow; ow = mw; }
  204.  
  205.     if (extract_fbm (&input, &output, xo, yo, w, h, ow, oh,
  206.              title[0] ? title : NULL,
  207.              credits[0] ? credits : NULL))
  208.     { if (write_bitmap (&output, stdout, outtype)) exit (0); }
  209.   }
  210.   
  211.   exit (1);
  212. }
  213.