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

409 lines
12 KiB
C

/**
** $Header: /roq/libim/imx.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/imx.c 1 11/02/99 4:38p Zaphod $"
/**
** FILE
** imx.c - Stardent AVS X image file I/O
**
** PROJECT
** libim - SDSC image manipulation library
**
** DESCRIPTION
** imx.c contains routines to read and write Stardent AVS X files for
** the image manipulation library. Raster data read in is stored
** in a VFB. Raster data written out is taken from a tag table.
**
** PUBLIC CONTENTS
** d =defined constant
** f =function
** m =defined macro
** t =typedef/struct/union
** v =variable
** ? =other
** none
**
** PRIVATE CONTENTS
** imXRead f read a Stardent AVS X file
** imXWrite f write a Stardent AVS X X file
**
**
** HISTORY
** $Log: /roq/libim/imx.c $
*
* 1 11/02/99 4:38p Zaphod
** Revision 1.15 1995/06/29 00:28:04 bduggan
** updated copyright year
**
** Revision 1.14 1995/04/03 21:40:55 bduggan
** took out #ifdef NEWMAGIC
**
** Revision 1.13 1995/01/10 23:50:33 bduggan
** made read/write routines static
**
** Revision 1.12 94/10/03 11:31:12 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.
** Rearranged magic number structures for format handlers.
** Made format handler routines static (i.e., local to file).
** Updated comments, adding format descriptions and references.
** Updated indenting on some code.
** Updated copyright message.
**
** Revision 1.11 92/12/03 01:56:31 nadeau
** Corrected info messages.
**
** Revision 1.10 92/11/24 11:52:29 groening
** Removed bogus code dealing with mythical, but not actual,
** DEC AVS version of the X format.
**
** Revision 1.9 92/11/18 12:29:21 groening
** added error statements to correspond
** with addition of new imdecx.c file
**
** Revision 1.8 92/11/04 12:10:22 groening
** put ImFIleFormat info and magic number info
** from imfmt.c into this file.
**
** Revision 1.7 92/10/19 14:05:46 groening
** added ImInfo features
**
** Revision 1.6 92/09/25 12:07:04 groening
** added print information for ImInfo
**
** Revision 1.5 92/09/02 11:12:38 vle
** Fixed copyright notice.
**
** Revision 1.4 92/08/31 17:43:50 vle
** Updated copyright notice.
**
** Revision 1.3 91/10/03 09:24:45 nadeau
** Fixed problem with alpha channel handling.
**
** Revision 1.2 91/02/12 10:47:13 nadeau
** Removed the tag table error checking now handled by
** ImFileWrite. Removed VFB conversion also now handled by
** ImFileWrite.
**
** Revision 1.1 91/01/30 18:17:56 nadeau
** Initial revision
**
**/
#include "iminternal.h"
#ifndef L_SET
#define L_SET 0 /* Absolute offset */
#define L_CUR 1
#define L_END 2
#endif
/**
** FORMAT
** X - Stardent AVS X image file
**
** AKA
** avs, mbfx, mbfavs
**
** FORMAT REFERENCES
** AVS File Formats, Appendix E, Stardent Application Visualization
** System, User's Guide, Stardent
**
** CODE CREDITS
** Custom development, Dave Nadeau, San Diego Supercomputer Center, 1991.
**
** DESCRIPTION
** Stardent AVS X image files start with a two 32-bit words giving the
** image width and height, respectively. Following these size words
** are a stream of (width*height) 32-bit words giving the RGB value
** for consecutive pixels. Scanlines are not padded.
**
** Each 32-bit pixel value is structured as four 8-bit quantities:
**
** high-order matte (alpha)
** red
** green
** low-order blue
**/
/*
* X - Stardent AVS image file
* For information on these structures, how to use them, etc. please
* see imfmt.c.
*/
#ifdef __STDC__
static int imXRead( int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable );
static int imXWrite( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable,
TagTable *tagTable );
#else
static int imXRead( );
static int imXWrite( );
#endif
static char *imXNames[ ] = { "x", "avs", "mbfx", "mbfavs", NULL };
static ImFileFormatReadMap imXReadMap[ ] =
{
/* in out */
/* type,ch,dep, attr. VFB type attr. */
{ RGB,3,8, A, IMVFBRGB, A },
{ -1, 0, -1, 0 },
};
static ImFileFormatWriteMap imXWriteMap[ ] =
{
/* in out */
/* VFB type, attr., type,ch,dep, attr., func */
{ IMVFBRGB, 0, RGB,3,8, A, imXWrite },
{ IMVFBRGB, A, RGB,3,8, A, imXWrite },
{ -1, 0, -1, 0, NULL },
};
static ImFileMagic imFileXMagic []=
{
{ 0, 0, NULL},
};
ImFileFormat ImFileXFormat =
{
imXNames, "AVS X image file",
"AVS Inc.",
"24-bit RGB + 8-bit Alpha plane uncompressed image files.",
"24-bit RGB + 8-bit Alpha plane uncompressed image files.",
imFileXMagic,
IMNOMULTI, IMPIPE,
IMNOMULTI, IMPIPE,
imXRead, imXReadMap, imXWriteMap
};
/*
* FUNCTION
* imXRead - read a Stardent AVS X file
*
* DESCRIPTION
* The image size is read in, followed by the pixel values.
* A VFB is added to the tag table.
*/
static int /* Returns # tags read in */
#ifdef __STDC__
imXRead( int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable )
#else
imXRead( ioType, fd, fp, flagsTable, tagTable )
int ioType; /* I/O flags */
int fd; /* Input file descriptor */
FILE *fp; /* Input file pointer */
TagTable *flagsTable; /* Flags */
TagTable *tagTable; /* Tag table to add to */
#endif
{
ImVfb *vfb; /* Read in image */
ImVfbPtr pPixel; /* Pixel pointer */
sdsc_uint32 *buffer; /* Run buffer */
sdsc_uint32 *pBuffer; /* Run buffer pointer */
int width, height; /* Image dimensions */
int i; /* Counter */
char message[200]; /* contains information for ImInfo */
/*
* Read in the image size.
*/
BinByteOrder( BINMBF );
if ( ImBinRead( ioType, fd, fp, &width, INT, 4, 1 ) == -1 )
{
ImReturnBinError( );
}
if ( ImBinRead( ioType, fd, fp, &height, INT, 4, 1 ) == -1 )
{
ImReturnBinError( );
}
sprintf (message, "Most Significant Byte First");
ImInfo ("Byte Order",message);
sprintf (message, "%d x %d", width, height);
ImInfo ("Resolution",message);
ImInfo ("Type","24-bit RGB");
ImInfo ("Alpha Channel","8-bit");
/*
* Allocate an RGB and Alpha plane VFB of the required size.
*/
if ( (vfb = ImVfbAlloc( width, height, IMVFBRGB|IMVFBALPHA )) == IMVFBNULL )
{
ImErrorFatal( ImQError( ), -1, ImErrNo );
}
/*
* Read in and copy to the VFB, one scanline at a time.
*/
pPixel = ImVfbQFirst( vfb );
ImMalloc( buffer, sdsc_uint32 *, sizeof( sdsc_uint32 ) * width );
while ( height-- )
{
pBuffer = buffer;
if ( ImBinRead( ioType, fd, fp, buffer, UINT32, 4, width )== -1)
{
free( (char *)buffer );
ImVfbFree( vfb );
ImReturnBinError( );
}
for ( i = 0; i < width; i++, pBuffer++ )
{
ImVfbSAlpha( vfb, pPixel, ((*pBuffer)>>24) & 0xFF );
ImVfbSRed( vfb, pPixel, ((*pBuffer)>>16) & 0xFF );
ImVfbSGreen( vfb, pPixel, ((*pBuffer)>>8) & 0xFF );
ImVfbSBlue( vfb, pPixel, (*pBuffer) & 0xFF );
ImVfbSInc( vfb, pPixel );
}
}
free( (char *)buffer );
TagTableAppend( tagTable, TagEntryAlloc( "image vfb", POINTER, &vfb ) );
return ( 1 );
}
/*
* FUNCTION
* imXWrite - write a Stardent AVS X file
*
* DESCRIPTION
* That VFB is queried, and the X file header written out.
* The VFB data is then copied to the file.
*/
static int /* Returns # of tags used */
#ifdef __STDC__
imXWrite( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable )
#else
imXWrite( pMap, ioType, fd, fp, flagsTable, tagTable )
ImFileFormatWriteMap *pMap; /* Write map entry to adhear to */
int ioType; /* I/O flags */
int fd; /* Input file descriptor */
FILE *fp; /* Input file pointer */
TagTable *flagsTable; /* Flags */
TagTable *tagTable; /* Tag table to read from */
#endif
{
ImVfb *vfb; /* Read in image */
ImVfbPtr pPixel; /* Pixel pointer */
sdsc_uint32 *buffer; /* Run buffer */
sdsc_uint32 *pBuffer; /* Run buffer pointer */
int width, height; /* Image dimensions */
int i; /* Counter */
char message[200]; /* contains information for ImInfo */
/*
* Write out the image size.
*/
TagEntryQValue( TagTableQDirect( tagTable, "image vfb", 0 ), &vfb );
width = ImVfbQWidth( vfb );
height = ImVfbQHeight( vfb );
BinByteOrder( BINMBF );
if ( ImBinWrite( ioType, fd, fp, &width, INT, 4, 1 ) == -1 )
{
ImReturnBinError( );
}
if ( ImBinWrite( ioType, fd, fp, &height, INT, 4, 1 ) == -1 )
{
ImReturnBinError( );
}
sprintf (message, "Most Significant Byte First");
ImInfo ("Byte Order",message);
sprintf (message, "%d x %d", width, height);
ImInfo ("Resolution",message);
ImInfo ("Type","24-bit RGB" );
ImInfo ("Alpha Channel","8-bit");
/*
* Copy the image to the file. If there's an alpha channel, add it.
*/
pPixel = ImVfbQFirst( vfb );
ImMalloc( buffer, sdsc_uint32 *, sizeof( sdsc_uint32 ) * width );
if ( ImVfbQFields( vfb ) & IMVFBALPHA )
{
while ( height-- )
{
pBuffer = buffer;
for ( i = 0; i < width; i++, pBuffer++ )
{
*pBuffer =
(((ImVfbQAlpha(vfb,pPixel))&0xFF)<<24) |
(((ImVfbQRed(vfb,pPixel))&0xFF)<<16)|
(((ImVfbQGreen(vfb,pPixel))&0xFF)<<8)|
((ImVfbQBlue(vfb,pPixel))&0xFF);
ImVfbSInc( vfb, pPixel );
}
if ( ImBinWrite( ioType, fd, fp, buffer, UINT32, 4, width ) == -1 )
{
free( (char *)buffer );
ImReturnBinError( );
}
}
free( (char *)buffer );
return ( 1 );
}
while ( height-- )
{
pBuffer = buffer;
for ( i = 0; i < width; i++, pBuffer++ )
{
*pBuffer =
(((ImVfbQRed(vfb,pPixel))&0xFF)<<16) |
(((ImVfbQGreen(vfb,pPixel))&0xFF)<<8) |
((ImVfbQBlue(vfb,pPixel))&0xFF);
ImVfbSInc( vfb, pPixel );
}
if ( ImBinWrite( ioType, fd, fp, buffer, UINT32, 4, width)== -1)
{
free( (char *)buffer );
ImReturnBinError( );
}
}
free( (char *)buffer );
return ( 1 );
}