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

  1. /*****************************************************************
  2.  * flextr.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.  * flextr.c: Extract a rectangle and/or resize it.
  11.  *
  12.  * CONTENTS
  13.  *    extract_fbm (input, output, xo, yo, w, h, ow, oh, title, credits)
  14.  *
  15.  * EDITLOG
  16.  *    LastEditDate = Mon Jun 25 17:03:19 1990 - Michael Mauldin
  17.  *    LastFileName = /usr2/mlm/src/misc/fbm0.99/flextr.c
  18.  *
  19.  * HISTORY
  20.  * 25-Jun-90  Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
  21.  *    Package for Release 1.0
  22.  *
  23.  * 13-Jun-90  Michael Mauldin (mlm) at Carnegie Mellon University
  24.  *    Final release (version 1.0) mlm@cs.cmu.edu
  25.  *
  26.  * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
  27.  *    Beta release (version 0.9) mlm@cs.cmu.edu
  28.  *
  29.  * 12-Nov-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  30.  *    Created.
  31.  *****************************************************************/
  32.  
  33. # include <stdio.h>
  34. # include <math.h>
  35. # include <ctype.h>
  36. # include "fbm.h"
  37.  
  38. /****************************************************************
  39.  * extract_fbm: Resize a bitmap
  40.  *    copy input [xo:xo+w yo:yo+h] to output [ow oh]
  41.  ****************************************************************/
  42.  
  43. #ifndef lint
  44. static char *fbmid =
  45. "$FBM flextr.c <1.0> 25-Jun-90  (C) 1989,1990 by Michael Mauldin, source \
  46. code available free from MLM@CS.CMU.EDU and from UUNET archives$";
  47. #endif
  48.  
  49. extract_fbm (input, output, xo, yo, w, h, ow, oh, title, credits)
  50. FBM *input, *output;
  51. int xo, yo, h, w, oh, ow;
  52. char *title, *credits;
  53. { int k, rowlen;
  54.  
  55.   if ((w != ow || h != oh) && input->hdr.bits != 8)
  56.   { fprintf (stderr,
  57.          "Can't resize images with %d bits per pixel\n", input->hdr.bits);
  58.     return (0);
  59.   }
  60.  
  61.   if (input->hdr.physbits != 8)
  62.   { fprintf (stderr,
  63.          "Can't extract images with %d physbits per pixel\n",
  64.          input->hdr.physbits);
  65.     return (0);
  66.   }
  67.  
  68.   if (h < 1 || w < 1 || oh < 1 || ow < 1)
  69.   { fprintf (stderr, "Extract: zero dimension [%dx%d] => [%dx%d]\n", 
  70.          w, h, ow, oh);
  71.     return (0);
  72.   }
  73.  
  74.   fprintf (stderr,
  75.        "Extract \"%s\" <%d,%d> [%dx%d] => [%dx%d] %d pixels\n",
  76.        title ? title : input->hdr.title[0] ? input->hdr.title : "untitled",
  77.        xo, yo, w, h, ow, oh, ow*oh);
  78.  
  79.   if (xo+w > input->hdr.cols)
  80.   { fprintf (stderr, "Warning, input exceeds image horizontally\n");
  81.     fprintf (stderr, "    xo %d, w %d, input->hdr.cols %d\n",
  82.          xo, w, input->hdr.cols);
  83.   }
  84.   if (yo+h > input->hdr.rows)
  85.   { fprintf (stderr, "Warning, input exceeds image vertically\n");
  86.     fprintf (stderr, "    yo %d, h %d, input->hdr.rows %d\n",
  87.          yo, h, input->hdr.rows);
  88.   }
  89.  
  90.   /* Calculate length of row (pad to even byte boundary) */
  91.   rowlen = 2 * ((ow * input->hdr.physbits + 15) / 16);
  92.   
  93.   /* Now build header for output bit map */
  94.   output->hdr.cols = ow;
  95.   output->hdr.rows = oh;
  96.   output->hdr.planes = input->hdr.planes;
  97.   output->hdr.bits = input->hdr.bits;
  98.   output->hdr.physbits = input->hdr.physbits;
  99.   output->hdr.rowlen = rowlen;
  100.   output->hdr.plnlen = oh * output->hdr.rowlen;
  101.   output->hdr.clrlen = input->hdr.clrlen;
  102.   output->hdr.aspect = input->hdr.aspect * ow * h / (oh * w);
  103.  
  104.   if (title == NULL || *title == '\0')
  105.   { strncpy (output->hdr.title, input->hdr.title, FBM_MAX_TITLE); }
  106.   else
  107.   { strcpy (output->hdr.title, title); }
  108.     
  109.   if (credits == NULL || *credits == '\0')
  110.   { strncpy (output->hdr.credits, input->hdr.credits, FBM_MAX_TITLE); }
  111.   else
  112.   { strcpy (output->hdr.credits, credits); }
  113.     
  114.   /* Allocate space for output bits */
  115.   alloc_fbm (output);
  116.  
  117.   copy_clr (input, output);
  118.  
  119.   /* Warning about resizing mapped image */
  120.   if (input->hdr.clrlen > 0 && (w != ow || h != oh))
  121.   { fprintf (stderr,
  122.          "Warning, %s\n         %s\n",
  123.          "resizing a mapped image is probably not what you want",
  124.          "I'll do it anyway, but you should probably use unmap first.");
  125.   }
  126.  
  127.   /* Now extract each plane separately */
  128.   for (k=0; k<output->hdr.planes; k++)
  129.   { if (! extract_one (&(input->bm[k * input->hdr.plnlen]),
  130.                &(output->bm[k * output->hdr.plnlen]),
  131.                input->hdr.cols, input->hdr.rows,
  132.                input->hdr.rowlen, output->hdr.rowlen,
  133.                xo, yo, w, h, ow, oh))
  134.     { free_fbm (output); return (0); }
  135.   }
  136.  
  137.   return (1);
  138. }
  139.  
  140. /****************************************************************
  141.  * extract_one: Resize a bitmap
  142.  *    copy input [xo:xo+w yo:yo+h] to output [ow oh]
  143.  ****************************************************************/
  144.  
  145. extract_one (inbm, outbm, cols, rows, inlen, outlen, xo, yo, w, h, ow, oh)
  146. unsigned char *inbm, *outbm;
  147. int inlen, outlen, xo, yo, h, w, oh, ow;
  148. { register int xf, yf, xi, i; 
  149.   register unsigned char *bm1, *bm2,  *obm;
  150.   int j, yi, dc;
  151.  
  152.   /* Check for scale of 1-1, special case for speed */
  153.   if (w == ow && h == oh && xo >= 0 && yo >= 0 && xo+w <= cols && yo+h <= rows)
  154.   { for (j=0; j<h; j++)
  155.     { bm1 = &inbm[(j+yo) * inlen];
  156.       obm = &outbm[j * outlen];
  157.  
  158.       for (i=0; i<w; i++)
  159.       { obm[i] = bm1[i + xo]; }
  160.     }
  161.   }
  162.   else
  163.   {    
  164.     for (j = 0; j<oh; j++)
  165.     { yi = (j*h / oh) + yo;
  166.       yf = (j*h % oh);
  167.  
  168.       obm = &outbm[j * outlen];
  169.       bm1 = &inbm[yi * inlen];
  170.       bm2 = bm1 + inlen;
  171.  
  172.       for (i=0; i<ow; i++)
  173.       { xi = (i*w / ow) + xo;
  174.         xf = (i*w % ow);
  175.  
  176.     if (xi < 0 || yi < 0 ||
  177.         xi > cols-2 ||
  178.         yi > rows-2)
  179.     { static cntr = 0;
  180.  
  181.       /* If right on edge, just use edge value */
  182.       if ((xi == cols-1 &&
  183.            yi >= 0 && yi <= rows-1) ||
  184.           (yi == rows-1 &&
  185.            xi >= 0 && xi <= cols-1))
  186.       { obm[i] = bm1[xi]; }
  187.       else
  188.       { obm[i] = 255;
  189.  
  190.         if (cntr++ < 3)
  191.         { fprintf (stderr,
  192.                "i,j %d,%d => xi,yi %d,%d, out of bounds %d,%d\n",
  193.                i, j, xi, yi, cols, rows);
  194.           fprintf (stderr,
  195.                "w %d, h %d, ow %d, oh %d\n\n", 
  196.                w, h, ow, oh);
  197.         }  
  198.       }
  199.         }
  200.     else
  201.     { dc = ( bm1[xi]   * (ow-xf)*(oh-yf) + 
  202.          bm2[xi]   * (ow-xf)*(yf) + 
  203.          bm1[xi+1] * (xf)*(oh-yf) + 
  204.          bm2[xi+1] * (xf)*(yf) ) / (ow*oh);
  205.  
  206.       if (dc < 0)        { dc = 0; }
  207.       else if (dc > 255)    { dc = 255; }
  208.  
  209.       obm[i] = dc;
  210.     }
  211.       }
  212.     }
  213.   }
  214.  
  215.   return (1);
  216. }
  217.