home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume19 / fbm / part04 / flextr.c < prev    next >
C/C++ Source or Header  |  1989-06-08  |  6KB  |  200 lines

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