home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume19
/
fbm
/
part04
/
flextr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-06-08
|
6KB
|
200 lines
/*****************************************************************
* flextr.c: FBM Library 0.9 (Beta test) 07-Mar-89 Michael Mauldin
*
* Copyright (C) 1989 by Michael Mauldin. Permission is granted to
* use this file in whole or in part provided that you do not sell it
* for profit and that this copyright notice is retained unchanged.
*
* flextr.c: Extract a rectangle and/or resize it.
*
* CONTENTS
* extract_fbm (input, output, xo, yo, w, h, ow, oh, title, credits)
*
* EDITLOG
* LastEditDate = Tue Mar 7 19:56:56 1989 - Michael Mauldin
* LastFileName = /usr2/mlm/src/misc/fbm/flextr.c
*
* HISTORY
* 07-Mar-89 Michael Mauldin (mlm) at Carnegie Mellon University
* Beta release (version 0.9) mlm@cs.cmu.edu
*
* 12-Nov-88 Michael Mauldin (mlm) at Carnegie-Mellon University
* Created.
*****************************************************************/
# include <stdio.h>
# include <math.h>
# include <ctype.h>
# include "fbm.h"
/****************************************************************
* extract_fbm: Resize a bitmap
* copy input [xo:xo+w yo:yo+h] to output [ow oh]
****************************************************************/
#ifndef lint
static char *fbmid =
"$FBM flextr.c <0.9> 07-Mar-89 (C) 1989 by Michael Mauldin$";
#endif
extract_fbm (input, output, xo, yo, w, h, ow, oh, title, credits)
FBM *input, *output;
int xo, yo, h, w, oh, ow;
char *title, *credits;
{ int k, rowlen;
if ((w != ow || h != oh) && input->hdr.bits != 8)
{ fprintf (stderr,
"Can't resize images with %d bits per pixel\n", input->hdr.bits);
return (0);
}
if (input->hdr.physbits != 8)
{ fprintf (stderr,
"Can't extract images with %d physbits per pixel\n",
input->hdr.physbits);
return (0);
}
if (h < 1 || w < 1 || oh < 1 || ow < 1)
{ fprintf (stderr, "Extract: zero dimension [%dx%d] => [%dx%d]\n",
w, h, ow, oh);
return (0);
}
fprintf (stderr,
"Extract \"%s\" <%d,%d> [%dx%d] => [%dx%d] %d pixels\n",
title ? title : input->hdr.title ? input->hdr.title : "untitled",
xo, yo, w, h, ow, oh, ow*oh);
if (xo+w > input->hdr.cols)
{ fprintf (stderr, "Warning, input exceeds image horizontally\n");
fprintf (stderr, " xo %d, w %d, input->hdr.cols %d\n",
xo, w, input->hdr.cols);
}
if (yo+h > input->hdr.rows)
{ fprintf (stderr, "Warning, input exceeds image vertically\n");
fprintf (stderr, " yo %d, h %d, input->hdr.rows %d\n",
yo, h, input->hdr.rows);
}
/* Calculate length of row (pad to even byte boundary) */
rowlen = 2 * ((ow * input->hdr.physbits + 15) / 16);
/* Now build header for output bit map */
output->hdr.cols = ow;
output->hdr.rows = oh;
output->hdr.planes = input->hdr.planes;
output->hdr.bits = input->hdr.bits;
output->hdr.physbits = input->hdr.physbits;
output->hdr.rowlen = rowlen;
output->hdr.plnlen = oh * output->hdr.rowlen;
output->hdr.clrlen = input->hdr.clrlen;
output->hdr.aspect = input->hdr.aspect * ow * h / (oh * w);
if (title == NULL || *title == '\0')
{ strncpy (output->hdr.title, input->hdr.title, FBM_MAX_TITLE); }
else
{ strcpy (output->hdr.title, title); }
if (credits == NULL || *credits == '\0')
{ strncpy (output->hdr.credits, input->hdr.credits, FBM_MAX_TITLE); }
else
{ strcpy (output->hdr.credits, credits); }
/* Allocate space for output bits */
alloc_fbm (output);
copy_clr (input, output);
/* Now extract each plane separately */
for (k=0; k<output->hdr.planes; k++)
{ if (! extract_one (&(input->bm[k * input->hdr.plnlen]),
&(output->bm[k * output->hdr.plnlen]),
input->hdr.cols, input->hdr.rows,
input->hdr.rowlen, output->hdr.rowlen,
xo, yo, w, h, ow, oh))
{ free_fbm (output); return (0); }
}
return (1);
}
/****************************************************************
* extract_one: Resize a bitmap
* copy input [xo:xo+w yo:yo+h] to output [ow oh]
****************************************************************/
extract_one (inbm, outbm, cols, rows, inlen, outlen, xo, yo, w, h, ow, oh)
unsigned char *inbm, *outbm;
int inlen, outlen, xo, yo, h, w, oh, ow;
{ register int xf, yf, xi, i;
register unsigned char *bm1, *bm2, *obm;
int j, yi, dc;
/* Check for scale of 1-1, special case for speed */
if (w == ow && h == oh && xo >= 0 && yo >= 0 && xo+w <= cols && yo+h <= rows)
{ for (j=0; j<h; j++)
{ bm1 = &inbm[(j+yo) * inlen];
obm = &outbm[j * outlen];
for (i=0; i<w; i++)
{ obm[i] = bm1[i + xo]; }
}
}
else
{
for (j = 0; j<oh; j++)
{ yi = (j*h / oh) + yo;
yf = (j*h % oh);
obm = &outbm[j * outlen];
bm1 = &inbm[yi * inlen];
bm2 = bm1 + inlen;
for (i=0; i<ow; i++)
{ xi = (i*w / ow) + xo;
xf = (i*w % ow);
if (xi < 0 || yi < 0 ||
xi > cols-2 ||
yi > rows-2)
{ static cntr = 0;
/* If right on edge, just use edge value */
if ((xi == cols-1 &&
yi >= 0 && yi <= rows-1) ||
(yi == rows-1 &&
xi >= 0 && xi <= cols-1))
{ obm[i] = bm1[xi]; }
else
{ obm[i] = 255;
if (cntr++ < 3)
{ fprintf (stderr,
"i,j %d,%d => xi,yi %d,%d, out of bounds %d,%d\n",
i, j, xi, yi, cols, rows);
fprintf (stderr,
"w %d, h %d, ow %d, oh %d\n\n",
w, h, ow, oh);
}
}
}
else
{ dc = ( bm1[xi] * (ow-xf)*(oh-yf) +
bm2[xi] * (ow-xf)*(yf) +
bm1[xi+1] * (xf)*(oh-yf) +
bm2[xi+1] * (xf)*(yf) ) / (ow*oh);
if (dc < 0) { dc = 0; }
else if (dc > 255) { dc = 255; }
obm[i] = dc;
}
}
}
}
return (1);
}