/***************************************************************** * flextr.c: FBM Release 1.0 25-Feb-90 Michael Mauldin * * Copyright (C) 1989,1990 by Michael Mauldin. Permission is granted * to use this file in whole or in part for any purpose, educational, * recreational or commercial, provided that this copyright notice * is retained unchanged. This software is available to all free of * charge by anonymous FTP and in the UUNET archives. * * flextr.c: Extract a rectangle and/or resize it. * * CONTENTS * extract_fbm (input, output, xo, yo, w, h, ow, oh, title, credits) * * EDITLOG * LastEditDate = Mon Jun 25 17:03:19 1990 - Michael Mauldin * LastFileName = /usr2/mlm/src/misc/fbm0.99/flextr.c * * HISTORY * 25-Jun-90 Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon * Package for Release 1.0 * * 13-Jun-90 Michael Mauldin (mlm) at Carnegie Mellon University * Final release (version 1.0) mlm@cs.cmu.edu * * 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 # include # include # 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 <1.0> 25-Jun-90 (C) 1989,1990 by Michael Mauldin, source \ code available free from MLM@CS.CMU.EDU and from UUNET archives$"; #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[0] ? 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); /* Warning about resizing mapped image */ if (input->hdr.clrlen > 0 && (w != ow || h != oh)) { fprintf (stderr, "Warning, %s\n %s\n", "resizing a mapped image is probably not what you want", "I'll do it anyway, but you should probably use unmap first."); } /* Now extract each plane separately */ for (k=0; khdr.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 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); }