home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / fbm / src / fbext.c < prev    next >
C/C++ Source or Header  |  1990-06-24  |  7KB  |  220 lines

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