home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Encyclopedia of Graphics File Formats Companion
/
GFF_CD.ISO
/
software
/
unix
/
saoimage
/
sao1_07.tar
/
pancopy.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-04-20
|
8KB
|
245 lines
#ifndef lint
static char SccsId[] = "%W% %G%";
#endif
/* Module: pancopy.c (Pan Copy)
* Purpose: Copy data between short integer image buffers in different
* flavors of blocking (used to fill pan buffer)
* Subroutine: copy_buf_subsample() returns: void
* Subroutine: copy_buf_replicate() returns: void
* Subroutine: copy_buf_sum() returns: void
* Subroutine: copy_buf_max() returns: void
* Copyright: 1988 Smithsonian Astrophysical Observatory
* You may do anything you like with this file except remove
* this copyright. The Smithsonian Astrophysical Observatory
* makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without
* express or implied warranty.
* Modified: {0} Michael VanHilst initial version 3 December 1988
* {n} <who> -- <does what> -- <when>
*/
#include <stdio.h> /* define stderr, NULL, etc. */
#include "hfiles/define.h" /* define MIN, MAX, etc. */
/*
* Subroutine: copy_buf_replicate
* Purpose: Copy data from main buffer to pan buffer, zooming UP by
* replicating. (for zoom > 1)
* Exception: Assumes a perfect fit (edge to edge, all pixels mapped)
*/
void copy_buf_replicate ( ibuf, obuf, dupe, iwidth, owidth, oheight )
short *ibuf; /* pointer to input buffer */
register short *obuf; /* pointer in output buffer */
register int dupe; /* imbuf to panbuf duplicating count */
int iwidth; /* width of input buffer */
int owidth, oheight; /* dimensions of output buffer */
{
register short *ptr; /* loop pointer in either buffer */
register short *rowend; /* loop pointer to end of a row */
short *obufend; /* pointer at end of output buffer */
short *thisband; /* pointer to line to replicate for band */
short *nextband; /* pointer to end of replicated band */
int bandsz; /* pixels between bands */
#ifdef DEBUG
if( dupe <= 0 ) {
(void)fprintf(stderr, "pan zoom error\n");
return;
}
#endif
obufend = obuf + (owidth * oheight);
bandsz = dupe * owidth;
/* quit when obuf is full */
while( obuf < obufend ) {
/* mark end of row replication */
thisband = obuf;
nextband = obuf + bandsz;
/* first make one row with column replication */
ptr = ibuf;
rowend = ibuf + iwidth;
do {
register int rep;
rep = 0;
while( rep++ < dupe )
*obuf++ = *ptr;
} while( ++ptr < rowend );
/* replicate this row as needed */
rowend = obuf;
while( obuf < nextband ) {
ptr = thisband;
while( ptr < rowend )
*obuf++ = *ptr++;
}
ibuf += iwidth;
}
}
/*
* Subroutine: copy_buf_subsample
* Purpose: Copy data between buffers, zooming down by sub-sampling
* Exception: Assumes a perfect fit
*/
void copy_buf_subsample ( ibuf, obuf, subsample, iwidth, owidth, oheight )
short *ibuf; /* pointer to input buffer */
register short *obuf; /* pointer in output buffer */
register int subsample; /* in to out sub-sampling increment */
int iwidth; /* width of input buffer */
int owidth, oheight; /* dimensions of output buffer */
{
register short *iptr; /* pointer within ibuf */
register int iptr_advance; /* to advance iptr to start next row */
register short *rowend; /* loop reference pointer to end of obuf row */
register short *obufend; /* loop reference pointer to end of obuf */
int bufoff; /* subsample offset into sample block */
#ifdef DEBUG
if( subsample <= 0 ) {
(void)fprintf(stderr, "pan zoom error\n");
return;
}
#endif
/* initialize parameter values */
/* choose offsets to center the sample in block (not just start at 0) */
bufoff = MAX (0, ((subsample - 1) / 2));
/* center area of data by splitting remainder */
iptr = ibuf + ((bufoff * iwidth) + bufoff);
/* advance zoom lines minus what was ticked off (i*z - o*z) */
iptr_advance = (iwidth - owidth) * subsample;
/* quit when obuf is full */
obufend = obuf + (owidth * oheight);
/* loop through sub-sampling */
while( obuf < obufend ) {
/* MAKE A SUB-SAMPLED LINE */
rowend = obuf + owidth;
while( obuf < rowend ) {
*obuf++ = *iptr;
iptr += subsample;
}
iptr += iptr_advance;
}
}
/*
* Subroutine: copy_buf_sum
* Purpose: Copy data between buffers, zoom down by summing or averaging
* Exception: Assumes a perfect fit
*/
void copy_buf_sum ( ibuf, obuf, block, av, iwidth, owidth, oheight )
short *ibuf; /* pointer to input buffer */
register short *obuf; /* pointer in output buffer */
register int block; /* blocking factor */
int av; /* flag to select averaging */
int iwidth; /* width of input buffer */
int owidth, oheight; /* dimensions of output buffer */
{
register short *iptr, *inextsum, *onextline;
short *isumline;
int blocksq, halfbsq;
int iadvance;
int oline;
#ifdef DEBUG
if( block <= 0 ) {
(void)fprintf(stderr, "pan zoom error\n");
return;
}
#endif
if( av ) {
blocksq = block * block;
halfbsq = blocksq / 2;
}
iadvance = block * iwidth;
/* count the output lines */
for( oline=0; oline<oheight; oline++ ) {
bzero((char *)obuf, owidth);
isumline = ibuf + iadvance;
onextline = obuf + owidth;
/* make block passes with same out line, summing */
while( ibuf < isumline ) {
/* remember ibuf at start of this line */
iptr = ibuf;
/* go through output line block times */
while( obuf < onextline ) {
/* sum for block piece of line */
inextsum = iptr + block;
while( iptr < inextsum )
*obuf += *iptr++;
obuf++;
}
/* reset outline, advance inline */
obuf -= owidth;
ibuf += iwidth;
}
/* if averaging, divide by block squared (rounding) */
if( av ) {
/* make one more pass through outline, dividing */
/* put inc where compiler is sure to have it sequenced right */
do {
*obuf = (*obuf + halfbsq) / blocksq;
} while( ++obuf < onextline );
} else {
obuf = onextline;
}
}
}
/*
* Subroutine: copy_buf_max
* Purpose: Copy data between buffers, zoom down by taking the max
* Exception: Assumes a perfect fit
*/
void copy_buf_max ( ibuf, obuf, block, iwidth, owidth, oheight )
short *ibuf; /* pointer to input buffer */
register short *obuf; /* pointer in output buffer */
register int block; /* blocking factor */
int iwidth; /* width of input buffer */
int owidth, oheight; /* dimensions of output buffer */
{
register short *iptr, *inextsum, *onextline;
short *isumline;
int iadvance;
int oline;
short absmin;
#ifdef DEBUG
if( block <= 0 ) {
(void)fprintf(stderr, "pan zoom error\n");
return;
}
#endif
absmin = -32767;
iadvance = block * iwidth;
/* count the output lines */
for( oline=0; oline<oheight; oline++ ) {
/* set line to lowest possible value (use isumline as temp storage) */
onextline = obuf + owidth;
isumline = obuf;
do {
*obuf = absmin;
} while( ++obuf < onextline );
obuf = isumline;
isumline = ibuf + iadvance;
/* make block passes with same out line, summing */
while( ibuf < isumline ) {
/* remember ibuf at start of this line */
iptr = ibuf;
/* go through output line block times */
while( obuf < onextline ) {
/* sum for block piece of line */
inextsum = iptr + block;
do {
if( *iptr > *obuf )
*obuf = *iptr;
} while( ++iptr < inextsum );
obuf++;
}
/* reset outline, advance inline */
obuf -= owidth;
ibuf += iwidth;
}
/* go on to next line */
obuf = onextline;
}
}