jedioutcast/utils/roq2/libim/imvfbflip.c
2013-04-04 13:07:40 -05:00

534 lines
8.4 KiB
C

/**
** $Header: /roq/libim/imvfbflip.c 1 11/02/99 4:38p Zaphod $
** Copyright (c) 1989-1995 San Diego Supercomputer Center (SDSC)
** a division of General Atomics, San Diego, California, USA
**
** Users and possessors of this source code are hereby granted a
** nonexclusive, royalty-free copyright and design patent license to
** use this code in individual software. License is not granted for
** commercial resale, in whole or in part, without prior written
** permission from SDSC. This source is provided "AS IS" without express
** or implied warranty of any kind.
**
** For further information contact:
** E-Mail: info@sds.sdsc.edu
**
** Surface Mail: Information Center
** San Diego Supercomputer Center
** P.O. Box 85608
** San Diego, CA 92138-5608
** (619) 534-5000
**/
#define HEADER " $Header: /roq/libim/imvfbflip.c 1 11/02/99 4:38p Zaphod $"
/**
** FILE
** imvfbflip.c - Function to Flip a Virtual Frame Buffer
**
** PROJECT
** libim - SDSC image manipulation library
**
** DESCRIPTION
** imvfbflip.c contains the routine to flip a vfb for
** the IM package.
**
** PUBLIC CONTENTS
** d =defined constant
** f =function
** m =defined macro
** t =typedef/struct/union
** v =variable
** ? =other
**
** ImVfbFlip f flip a VFB
**
** PRIVATE CONTENTS
** none
**
** HISTORY
** $Log: /roq/libim/imvfbflip.c $
*
* 1 11/02/99 4:38p Zaphod
** Revision 1.9 1995/06/29 00:28:04 bduggan
** updated copyright year
**
** Revision 1.8 1995/06/16 08:52:59 bduggan
** changed bcopy to memcpy
**
** Revision 1.7 94/10/03 11:29:49 nadeau
** Updated to ANSI C and C++ compatibility.
** Removed all use of register keyword.
** Minimized use of custom SDSC types (e.g., uchar vs. unsigned char)
** Changed all float arguments to double.
** Added forward declarations.
** Added misc. casts to passify SGI and DEC compilers.
** Changed all macros and defined constants to have names
** starting with IM.
** Updated comments.
** Updated indenting on some code.
** Updated copyright message.
**
** Revision 1.6 92/08/31 17:38:04 vle
** Updated copyright notice.
**
** Revision 1.5 91/09/18 17:26:52 mcleodj
** Modified routine to correctly handle destination`
** vfb's that are not equivalent to the source vfb.
**
** Revision 1.4 91/09/13 14:50:07 nadeau
** Removed unnecessary inclusion of <stdio.h>
**
** Revision 1.3 91/07/12 10:31:21 nadeau
** Removed extra include statement.
**
** Revision 1.2 90/07/23 13:55:39 nadeau
** Totally rewrote. The original version wouldn't compile. If it had
** compiled, it wouldn't have linked. If it had linked, it wouldn't
** have properly flipped images. If it had properly flipped images,
** it would have done it in the slowest possible way. The shear
** stupidity of the original version is mind-boggeling.
**
** Revision 1.1 90/03/06 17:33:56 mercurio
** Initial revision
**
**/
/**
** CODE CREDITS
** Custom development, Dave Nadeau, San Diego Supercomputer Center, 1990.
**/
#include "iminternal.h"
/*
* FUNCTION
* ImVfbFlip - flip a VFB
*
* DESCRIPTION
* If no destination VFB is given, a new destination VFB is created.
*
* The source VFB is then copied into the destination VFB, flipping
* its pixels horizontally, vertically, or both.
*/
ImVfb * /* Returns flipped VFB */
#ifdef __STDC__
ImVfbFlip( ImVfb *vfbSrc, int flipDirection, ImVfb *vfbDst )
#else
ImVfbFlip( vfbSrc, flipDirection, vfbDst )
ImVfb *vfbSrc; /* VFB to flip */
int flipDirection; /* Direction to flip */
ImVfb *vfbDst; /* VFB to overwrite with flipped source */
#endif
{
int x, y; /* column, row indices */
int hw; /* Half image width */
int hh; /* Half image height */
int wm1; /* Width of image, minus 1 */
int hm1; /* Height of image, minus 1 */
int nBytes; /* # bytes per pixel */
unsigned char *pixel; /* Temporary pixel holder */
ImVfbPtr pSrc, pDst; /* src, dst pixel pointers */
/* Check the flip direction */
if ( flipDirection != IMVFBXFLIP && flipDirection != IMVFBYFLIP &&
flipDirection != IMVFBXYFLIP )
{
ImErrNo = IMEBADFLIP;
return( IMVFBNULL );
}
/* Allocate a new VFB, if necessary */
if ( vfbDst == IMVFBNEW )
{
vfbDst = ImVfbAlloc( ImVfbQWidth( vfbSrc ),
ImVfbQHeight( vfbSrc ), ImVfbQFields( vfbSrc ) );
if ( vfbDst == IMVFBNULL )
{
ImErrNo = IMEMALLOC;
return( IMVFBNULL );
}
/*
* For a new vfb, All the infomation (including any colortables)
* in the source vfb must be re-written to the destination
* in a flipped order therfore the range of pixel information
* to parse (ie: hh and hw) is the entire source vfb
* range (ie: h x w)
*/
ImVfbSClt( vfbDst, ImVfbQClt( vfbSrc ) );
hh = ImVfbQHeight( vfbDst );
hw = ImVfbQWidth( vfbDst );
}
else if ( vfbDst == vfbSrc )
{
/*
* If the request is to replace the source Vfb with the flipped
* pixel information thereby overwriting the original pixel
* data, a short cut can be performed. Only half of the pixels
* need to be parsed through to achieve the flipped effect
* NOTE: the color table ( if any ) automatically remains
* attached to the source vfb.
*/
hh = ImVfbQHeight( vfbDst )/2;
hw = ImVfbQWidth( vfbDst )/2;
}
else if ( ImVfbQWidth( vfbSrc ) != ImVfbQWidth( vfbDst ) ||
ImVfbQHeight( vfbSrc ) != ImVfbQHeight( vfbDst ) ||
ImVfbQFields( vfbSrc ) != ImVfbQFields( vfbDst ) )
{
/* If different VFB's, must have the same size. */
ImErrNo = IMEDIFFSIZE;
return ( IMVFBNULL );
}
else
{
/*
* If the request is to overwrite a destination Vfb that
* has already been allocated before the request and
* is the same size as the source, then the full parsing
* of pixel data must occur.
*/
hh = ImVfbQHeight( vfbDst );
hw = ImVfbQWidth( vfbDst );
}
/* Allocate temporary space for one pixel. */
nBytes = ImVfbQNBytes( vfbSrc );
if ( (pixel = (unsigned char *) malloc( nBytes )) == NULL )
{
ImErrNo = IMEMALLOC;
return( IMVFBNULL );
}
/* Flip the source into the destination. */
if ( flipDirection == IMVFBXFLIP || flipDirection == IMVFBXYFLIP )
{
/* Flip horizontally. */
wm1 = ImVfbQWidth( vfbDst ) - 1;
for ( y = 0; y < ImVfbQHeight( vfbSrc ); y++ )
{
pSrc = ImVfbQPtr( vfbSrc, 0, y );
pDst = ImVfbQPtr( vfbDst, wm1, y );
for ( x = 0; x < hw; x++, ImVfbSRight( vfbSrc, pSrc ),
ImVfbSLeft( vfbDst, pDst ) )
{
memcpy( pixel, (void*) pSrc, nBytes );
memcpy( (void *) pSrc, pDst, nBytes );
memcpy( (void *) pDst, pixel, nBytes );
}
}
if ( flipDirection == IMVFBXFLIP )
{
free( (char *)pixel );
return ( vfbDst );
}
/*
* If the execution reaches this point, then a flip of the
* pixel data in the y direction must be performed.
* Execution time can be saved by making the previously
* x-flipped destination vfb the source vfb, in which
* case the amount of pixel data of the vfb's height to parse
* must be reduced in half.
* NOTE: this is only necessary for requests to flip a source
* vfb into a new destination vfb .
*/
vfbSrc = vfbDst;
hh = ImVfbQHeight( vfbDst )/2;
}
/* Flip vertically. */
hm1 = ImVfbQHeight( vfbDst ) - 1;
for ( x = 0; x < ImVfbQWidth( vfbSrc ); x++ )
{
pSrc = ImVfbQPtr( vfbSrc, x, 0 );
pDst = ImVfbQPtr( vfbDst, x, hm1 );
for ( y = 0; y < hh; y++, ImVfbSDown( vfbSrc, pSrc ),
ImVfbSUp( vfbDst, pDst ) )
{
memcpy( pixel, pSrc, nBytes );
memcpy( (void *)pSrc, pDst, nBytes );
memcpy( (void *)pDst, pixel, nBytes );
}
}
free( (char *)pixel );
return ( vfbDst );
}