mirror of
https://github.com/ioquake/jedi-outcast.git
synced 2024-11-10 07:11:42 +00:00
409 lines
11 KiB
C
409 lines
11 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 );
|
|
}
|