/** ** $Header: /roq/libim/imtga.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/imtga.c 1 11/02/99 4:38p Zaphod $" /** ** FILE ** imtga.c - Targa ** ** PROJECT ** libim - SDSC image manipulation library ** ** DESCRIPTION ** imtga.c contains routines to read and write Targa image 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 ** ** imTgaRead f read a Targa file ** imTgaWriteRGB16 f write an uncomp RGB file with 16 bits/pixel ** imTgaWriteRGB24 f write an uncomp RGB file with 24 bits/pixel ** imTgaWriteRGB32 f write an uncomp RGB file with 32 bits/pixel ** imTgaWriteRGBRLE16 f write an RLE comp RGB file with 16 bits/pixel ** imTgaWriteRGBRLE24 f write an RLE comp RGB file with 24 bits/pixel ** imTgaWriteRGBRLE32 f write an RLE comp RGB file with 32 bits/pixel ** imTgaWriteCLT8 f write an uncomp CLT file with 8 bits/pixel ** ImTgaWritCLT16 f write an uncomp CLT file with 16 bits/pixel ** imTgaWriteCLTRLE8 f write an RLE comp CLT file with 8 bits/pixel ** imTgaWriteCLTRLE16 f write an RLE comp CLT file with 16 bits/pixel ** imTgaWriteGREY8 f write an uncomp grscl file with 8 bits/pixel ** ImTgaWritGREY16 f write an uncomp grscl file with 16 bits/pixel ** imTgaWriteGREYRLE8 f write an RLE comp grsclfile with 8 bits/pixel ** imTgaWriteGREYRLE16 f write an RLE comp grscfile with 16 bits/pixel ** ** imTga2ByteExpand_PIX( ); f expands 2 bytes of color into the vfb ** imTga2ByteExpand_CLT( ); f expands 2 bytes of color into the clt ** imReadTga_1and3(); f reads in a Targa type 1 or type 3 file ** imReadTga_2(); f reads in a Targa type 2 file ** imReadTga_9and11(); f reads in a Targa type 9 or type 11 file ** imReadTga_10(); f reads in a Targa type 10 file ** imTgaWriteHeader(); f writes out a Targa header file ** imTgaWriteRLE8(); f writes out a RLE encoded 8bit/pixel file ** imTgaWrite8image(); f writes out an unencoded 8bit/pixel file ** imTgaWriteRLE16(); f writes out a RLE encoded 16bit/pixel file ** imTgaWrite16image(); f writes out an unencoded 16bit/pixel file ** ** ** HISTORY ** $Log: /roq/libim/imtga.c $ * * 1 11/02/99 4:38p Zaphod ** Revision 1.17 1995/06/29 00:28:04 bduggan ** updated copyright year ** ** Revision 1.16 1995/06/15 21:15:56 bduggan ** removed unreachable code. ** changed spelling of significant ** ** Revision 1.15 1995/05/17 23:47:42 bduggan ** Fixed crummy rle encoding algorithm ** ** Revision 1.14 1995/04/03 21:37:40 bduggan ** took out #ifdef NEWMAGIC ** ** Revision 1.13 1995/01/10 23:44:43 bduggan ** put in IMMULTI, IMPIPE instead of TRUE/FALSE ** made read/write routines static ** ** Revision 1.12 94/10/03 11:30:59 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:52:48 nadeau ** Corrected info messages. ** ** Revision 1.10 92/11/04 12:08:08 groening ** put ImFIleFormat info and magic number info ** from imfmt.c into this file. ** ** Revision 1.9 92/10/19 14:18:54 groening ** forg ** forgot to remove debug statements ** ** Revision 1.8 92/10/19 14:08:59 groening ** fixed bug in rle ** added ImInfo stuff again ** file was mangled in disk crash ** ** Revision 1.7 92/09/25 12:05:58 groening ** added print information for iminfo ** ** Revision 1.6 92/09/05 11:33:32 groening ** fixed bug in read index 16 ** ** Revision 1.5 92/09/03 18:12:36 vle ** Fixed vfb initialization bug in imTgaWrite16image(). ** ** Revision 1.4 92/09/02 17:38:08 groening ** fixed insignificant stupid bug in index 16 conversion ** ** Revision 1.3 92/08/31 17:36:06 vle ** Updated copyright notice. ** ** Revision 1.2 92/08/24 14:28:49 groening ** minor stuff ** ** Revision 1.1 92/06/02 09:33:24 groening ** Initial revision ** ** **/ #include "iminternal.h" /** ** FORMAT ** TGA - Truevision Targa image file ** ** AKA ** vda,ivb ** ** FORMAT REFERENCES ** Supercharged Bitmapped Graphics, Steve Rimmer ** Graphics File Formats, David C. Kay, John R. Levine ** ** CODE CREDITS ** Custom development, Chris Groening, San Diego Supercomputer Center, 1992. ** ** DESCRIPTION ** There are nine different ways that a targa file can be stored: ** 0 - No image data included. ** 1 - Uncompressed, color-mapped images. ** 2 - Umcompressed, RGB images. ** 3 - Uncompressed, black and white images. ** 9 - Runlength encoded color mapped images. ** 10 - Runlength encoded RGB images. ** 11 - Compressed black and white images. ** 32 - Compressed color-mapped data, using Huffman, Delta ** and RLE encoding. ** 33 - Compressed color-mapped data, using Huffman, Delta ** and RLE encoding, 4-pass quadtree-type process. ** ************************************************************************* ** AS OF NOW ONLY TYPES 0,1,2,3,9,10,11 ARE SUPPORTED ** ** 2 AND 4 WAY TYPE INTERLEAVING ARE NOT SUPPORTED ** ** COLOR MAP TABLES ARE ONLY WRITTEN RED, GREEN, BLUE WITH 1 BYTE EACH ** ** NOTE: Word form truevision has it that types 32 and 33 are obsolete, and ** were never that widespread. The same with two and four way interleaving. ************************************************************************* ** ** The 'header' lies in the first 18 bytes of the targa file. ** It is described as follows: ** ** OFFSET LENGTH DESCRIPTION ** ----------------------------------------------------------------- ** | | | | ** | 0 | 1 | Number of characters in Identification field. | ** | | | | ** | | | This field is a one byte unsigned integer, | ** | | | specifying the length of the Image | ** | | | Identification Filed. It ranges from 0-255. | ** | | | A 0 means that no Image Ident. field is there.| ** | | | | ** ----------------------------------------------------------------- ** | | | | ** | 1 | 1 | Color Map type | ** | | | | ** | | | 0 - no color map included. | ** | | | 1 - color map included. | ** | | | | ** ----------------------------------------------------------------- ** | | | | ** | 2 | 1 | Image Type Code | ** | | | | ** | | | What kind of Data type is in the file. | ** | | | ('magic number'? (0,1,2,3,9,10,11,32,33)) | ** | | | | ** ----------------------------------------------------------------- ** | | | | ** | 3 | 5 | Color map Specification | ** | | | | ** | 3 | 2 | Color Map Origin | ** | | | Integer (lo -hi) index of first colormap entry| ** | | | | ** | 5 | 2 | Color Map Length | ** | | | Integer (lo-hi) count of colormap entries | ** | | | | ** | 7 | 1 | Color Map entry Size | ** | | | Number of bits in color map entry. | ** | | | 16 for Targa 16, 24 for targa 24, 32 for 32 | ** | | | | ** ----------------------------------------------------------------- ** | | | | ** | 8 | 10 | Image specification | ** | | | | ** | 8 | 2 | X origin of Image. | ** | | | Integer (lo-hi) X coordinate of lower left | ** | | | corner of image. | ** | | | | ** | 10 | 2 | Y origin of Image. | ** | | | Integer (lo-hi) Y coordinate of lower left | ** | | | corner of image. | ** | | | | ** | 12 | 2 | Width of image. | ** | | | Integer (lo-hi) width of image in pixels. | ** | | | | ** | 14 | 2 | Length of image. | ** | | | Integer (lo-hi) length of image in pixels. | ** | | | | ** | 16 | l | Image Pixel size | ** | | | Number of bits in a pixel, 16 for Targa 16 etc| ** | | | | ** | 17 | 1 | Image Descriptor Byte | ** | | | BITS 3-0: number of attribute bits associated | ** | | | with each pixel. For targa 16 this should be | ** | | | 0 or 1. For the Targa 24 it should be 0 and | ** | | | for the 32 it should be 8 | ** | | | BIT 4 & BIT 5 : Pixel data storage order | ** | | | Screen dest of first pixel | ** | | | 0 0 Bottom left | ** | | | 0 1 Top left | ** | | | 1 0 Bottom right | ** | | | 1 1 Top right | ** | | | BITS 7-6: must be zero | ** | | | | ** ----------------------------------------------------------------- ** | | | | ** | 18 |varies | Image identification field. | ** | | | Contains a free-form identification field of | ** | | | the length specified in byte 1 of the image | ** | | | record. It's usually omitted (byte 1 =0), but| ** | | | can be up to 255 characters. If more info is | ** | | | needed, it can be stored after the image data | ** | | | | ** ----------------------------------------------------------------- ** | | | | ** |varies |varies | Color Map Data | ** | | | The offset is determined by the size of the | ** | | | Image Identifaction Field. | ** | | | The length is determined by the Color Map | ** | | | Specification, which describes the size of | ** | | | each entry and the number of entries. | ** | | | Each color map entry is 2, 3, or 4 bytes. | ** | | | Unused bits are assumed to specify attribute | ** | | | bits. | ** | | | | ** | | | 4 bytes - 1 red, 1 green, 1 blue and 1 att. | ** | | | | ** | | | 3 bytes - 1 red, 1 green, 1 blue. | ** | | | | ** | | | 2 bytes - ARRRRRGG GGGBBBBB each letter= 1 bit| ** | | | There is lo-hi storage order so bytes will | ** | | | be reversed | ** | | | | ** ----------------------------------------------------------------- ** | | | | ** |varies |varies | Image Data Field | ** | | | | ** | | | This field specifies (width) x (height) | ** | | | color map indices. The indices are stored in| ** | | | packets. There are many kinds of packets. | ** | | | they consist of a 1 byte header, which | ** | | | idenitfies the type of packet and specifies | ** | | | a count, folowed by a variable-length body. | ** | | | | ** | | | Run-length packet: | ** | | | First bit ID =1 then 7 bit repetition count | ** | | | minus one. (largest possible size is 128) | ** | | | | ** | | | Raw packet: | ** | | | First bit ID =0 then 7 bit repetition count | ** | | | minus one. (largest possible size is 128) | ** | | | | ** | | | Both of these can cross scanlines | ** | | | | ** ----------------------------------------------------------------- **/ /* * TGA - Targa File Format * For information on these structures, how to use them, etc. please * see imfmt.c. * TGA */ #ifdef __STDC__ static int imTgaRead( int ioType, int fd, FILE* fp, TagTable *flagsTable, TagTable *tagTable ); static int imTgaWriteRGB16( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable ); static int imTgaWriteRGBRLE16( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE* fp, TagTable *flagsTable, TagTable *tagTable ); static int imTgaWriteRGB24( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable ); static int imTgaWriteRGBRLE24( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable); static int imTgaWriteRGB32( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable); static int imTgaWriteRGBRLE32( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable); static int imTgaWriteCLT8( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable); static int imTgaWriteCLTRLE8( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable); static int imTgaWriteCLT16( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable); static int imTgaWriteCLTRLE16( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable); static int imTgaWriteGREY8( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable); static int imTgaWriteGREYRLE8( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable); static int imTgaWriteGREY16( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable); static int imTgaWriteGREYRLE16( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable); #else static int imTgaRead(); static int imTgaWriteRGB16(); static int imTgaWriteRGBRLE16(); static int imTgaWriteRGB24(); static int imTgaWriteRGBRLE24(); static int imTgaWriteRGB32( ); static int imTgaWriteRGBRLE32(); static int imTgaWriteCLT8(); static int imTgaWriteCLTRLE8(); static int imTgaWriteCLT16( ); static int imTgaWriteCLTRLE16( ); static int imTgaWriteGREY8( ); static int imTgaWriteGREYRLE8(); static int imTgaWriteGREY16( ); static int imTgaWriteGREYRLE16( ); #endif static char *imTgaNames[ ] = { "tga", "vda", "ivb", NULL}; static ImFileFormatReadMap imTgaReadMap[ ] = { /* in out */ /* type, ch, dep, attr. VFB type attr. */ { IN,1,8, C|RLE, IMVFBINDEX8, C}, { IN,1,16, C|RLE, IMVFBINDEX16, C}, { RGB,3,8, C|RLE, IMVFBRGB, C}, { RGB,3,8, A|C|RLE,IMVFBRGB, A|C}, { RGB,3,5, A|C|RLE,IMVFBRGB, A|C}, { RGB,3,5, A|RLE, IMVFBRGB, A}, { RGB,3,8, RLE, IMVFBRGB, 0}, { RGB,3,8, A|RLE, IMVFBRGB, A}, { IN,1,8, RLE, IMVFBGREY, 0}, { IN,1,16, RLE, IMVFBGREY, 0}, { IN,1,8, C, IMVFBINDEX8, C}, { IN,1,16, C, IMVFBINDEX16, C}, { RGB,3,8, C, IMVFBRGB, C}, { RGB,3,8, A|C, IMVFBRGB, A|C}, { RGB,3,5, A|C, IMVFBRGB, A|C}, { RGB,3,5, A, IMVFBRGB, A}, { RGB,3,8, 0, IMVFBRGB, 0}, { RGB,3,8, A, IMVFBRGB, A}, { IN,1,8, 0, IMVFBGREY, 0}, { IN,1,16, 0, IMVFBGREY, 0}, { -1, 0, -1, 0}, }; static ImFileFormatWriteMap imTgaWriteMap[ ] = { /* in out */ /* VFB type, attr., type,ch,dep, attr., func */ { IMVFBINDEX8, C, IN,1,8, C|RLE, imTgaWriteCLTRLE8 }, { IMVFBINDEX8, C, IN,1,8, C, imTgaWriteCLT8 }, { IMVFBINDEX8, 0, IN,1,8, RLE, imTgaWriteGREYRLE8 }, { IMVFBINDEX8, 0, IN,1,8, 0, imTgaWriteGREY8 }, { IMVFBINDEX16, 0, IN,1,16, RLE, imTgaWriteGREYRLE16 }, { IMVFBINDEX16, 0, IN,1,16, 0, imTgaWriteGREY16 }, { IMVFBINDEX16, C, IN,1,16, C|RLE, imTgaWriteCLTRLE16 }, { IMVFBINDEX16, C, IN,1,16, C, imTgaWriteCLT16 }, { IMVFBRGB, 0, RGB,3,8, RLE, imTgaWriteRGBRLE24 }, { IMVFBRGB, A, RGB,3,8, A|RLE, imTgaWriteRGBRLE32 }, { IMVFBRGB, 0, RGB,3,8, 0, imTgaWriteRGB24 }, { IMVFBRGB, A, RGB,3,8, A, imTgaWriteRGB32 }, { IMVFBRGB, A, RGB,3,5, A, imTgaWriteRGB16 }, { IMVFBRGB, A, RGB,3,5, A|RLE, imTgaWriteRGBRLE16 }, { -1, 0, -1, 0}, }; static ImFileMagic imFileTgaMagic []= { { 0, 0, NULL}, }; ImFileFormat ImFileTgaFormat = { imTgaNames, "Truevision Targa image file", "Truevision", "8- and 16-bit monochrome, 8- and 16-bit color index, 16-, 24-, and\n\ 32-bit RGB+alpha, uncompressed (standard) and RLE compressed image files.", "8- and 16-bit monochrome, 8- and 16-bit color index, 16-, 24-, and\n\ 32-bit RGB+alpha, uncompressed (standard) and RLE compressed image files.", imFileTgaMagic, IMNOMULTI, IMNOPIPE, IMNOMULTI, IMNOPIPE, imTgaRead, imTgaReadMap, imTgaWriteMap }; #ifdef __STDC__ static void imTga2ByteExpand_PIX (int byte2, int byte1, ImVfbPtr pPixel, ImVfb *vfb); static void imTga2ByteExpand_CLT (int byte2, int byte1, ImCltPtr pColor); static int imReadTga_1and3 (int ioType,int fd,FILE *fp,ImVfb *vfb, int q,int h,int w); static int imReadTga_2 (int ioType,int fd,FILE *fp,ImVfb *vfb, int q,int h,int w); static int imReadTga_9and11 (int ioType,int fd,FILE* fp,ImVfb *vfb, int q,int h,int w); static int imReadTga_10 (int ioType,int fd,FILE* fp,ImVfb *vfb, int q,int h,int w); static int imTgaWriteHeader( int ioType, int fd, FILE *fp,TagTable *flagsTable, TagTable *tagTable,int stype,int spix,int cmsize ); static int imTgaWriteRLE8( int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable ); static int imTgaWrite8image( int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable ); static int imTgaWriteRLE16( int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable ); static int imTgaWrite16image( int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable ); #else static void imTga2ByteExpand_PIX( ); static void imTga2ByteExpand_CLT( ); static int imReadTga_1and3(); static int imReadTga_2(); static int imReadTga_9and11(); static int imReadTga_10(); static int imTgaWriteHeader(); static int imTgaWriteRLE8(); static int imTgaWrite8image(); static int imTgaWriteRLE16(); static int imTgaWrite16image(); #endif #define IMTGA_NODATA 0 #define IMTGA_UNCOMPCOLORMAP 1 #define IMTGA_UNCOMPRGB 2 #define IMTGA_UNCOMPBW 3 #define IMTGA_RLECOLORMAP 9 #define IMTGA_RLERGB 10 #define IMTGA_RLEBW 11 #define IMTGA_HUFF 32 #define IMTGA_HUFF4TYPE 33 /* TYPEDEF & STRUCTURE * imTgaHeaderInfo - Targa file header information * imTgaHeaderFields - Targa file header fields for binary package */ typedef struct imTgaHeaderInfo { int tga_numc_ident; /* number of chars. in ident. field */ unsigned short tga_cmtype; /* whether or not a colormap exists */ int tga_stype; /* Storage type */ int tga_cmorigin; /* Color map origin */ int tga_cmlen; /* Color map length */ int tga_cmsize; /* Color map entry size */ int tga_imxorg; /* X origin of image */ int tga_imyorg; /* Y origin of image */ int tga_imwid; /* Width of image */ int tga_imhgt; /* Height of image */ int tga_spix; /* Image pixel size */ int tga_imdesc; /* Image descriptor byte */ } imTgaHeaderInfo; static BinField imTgaHeaderFields[]= { { UINT, 1, 1 }, /* tga_numc_ident */ { USHORT, 1, 1 }, /* tga_cmtype */ { UINT, 1, 1 }, /* tga_stype */ { UINT, 2, 1 }, /* tga_cmorigin */ { UINT, 2, 1 }, /* tga_cmlen */ { UINT, 1, 1 }, /* tga_cmsize */ { UINT, 2, 1 }, /* tga_imxorg */ { UINT, 2, 1 }, /* tga_imyorg */ { UINT, 2, 1 }, /* tga_imwid */ { UINT, 2, 1 }, /* tga_imlen */ { UINT, 1, 1 }, /* tga_spix */ { UINT, 1, 1 }, /* tga_imdesc */ { 0, 0, 0} }; /* FUNCTION * * imTga2ByteExpand_PIX * * DESCRIPTION * Takes a long word (2 bytes) which is configured as per Targa * specs as ARRRRRGG GGGBBBBB. It then breaks it up into the * corresponding components. And adds them into the vfb. */ static void #ifdef __STDC__ imTga2ByteExpand_PIX (int byte2, int byte1, ImVfbPtr pPixel, ImVfb* vfb) #else imTga2ByteExpand_PIX (byte2, byte1, pPixel, vfb) int byte2,byte1; /* 2bytes to be expanded */ ImVfbPtr pPixel; ImVfb *vfb; #endif { int expatr; /* The attribute bit */ int expred; /* The five red bits */ int expgreen; /* The five green bits */ int expblue; /* The five blue bits */ int exptemp; expatr = (byte1 &0x80) >> 7; expred = (byte1 &0x7c) >> 2; expgreen = (byte1 &0x03) << 3; exptemp = (byte2 &0xe0) >> 5; expgreen = (expgreen |exptemp); expblue = (byte2 &0x1f) ; ImVfbSRed (vfb, pPixel, expred*8); ImVfbSGreen (vfb, pPixel, expgreen*8); ImVfbSBlue (vfb, pPixel, expblue*8); ImVfbSAlpha (vfb, pPixel, expatr); } /* FUNCTION * * imTga2ByteExpand_CLT * * DESCRIPTION * Takes a long word (2 bytes) which is configured as per Targa * specs as ARRRRRGG GGGBBBBB. It then breaks it up into the * corresponding components. And adds them into the clt. */ static void #ifdef __STDC__ imTga2ByteExpand_CLT (int byte2, int byte1, ImCltPtr pColor) #else imTga2ByteExpand_CLT (byte2, byte1, pColor) int byte2,byte1; /* 2bytes to be expanded */ ImCltPtr pColor; #endif { int expatr; /* The attribute bit */ int expred; /* The five red bits */ int expgreen; /* The five green bits */ int expblue; /* The five blue bits */ int exptemp; expatr = (byte1 &0x80) >> 7; expred = (byte1 &0x7c) >> 2; expgreen = (byte1 &0x03) << 3; exptemp = (byte2 &0xe0) >> 5; expgreen = (expgreen |exptemp); expblue = (byte2 &0x1f) ; ImCltSBlue (pColor, expblue); ImCltSGreen (pColor, expgreen); ImCltSRed (pColor, expred); } /* * 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 number of tags read in */ #ifdef __STDC__ imTgaRead( int ioType, int fd, FILE* fp, TagTable *flagsTable, TagTable *tagTable ) #else imTgaRead( 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 { unsigned char *pBuffer; /* buffer pointer */ ImVfbPtr pPixel; /* VFB pixel pointer */ ImVfb *vfb; /* Read in image */ ImClt *clt; /* New clt */ ImCltPtr pColor; /* CLT entry pointer */ imTgaHeaderInfo header; /* Tga header info pointer */ unsigned char *buffer; /* Run buffer */ char *TgaName; /* Name of targa image in file */ int i,x,y; /* Counter */ int colortable; /* color map flag */ int n,m,h,w,z,q; /* convenient short names */ int tga_attbits; /* number of attribute bits per pixel */ int tga_orgbita; /* screen origin bit 4 */ int tga_orgbitb; /* screen origin bit 5 */ int tga_rsrvd; /* data storage interleave bits */ char message[500]; /* Tmp error message text */ /* the binary byte order is lo-hi */ BinByteOrder (BINLBF); /* * Read in the header.. */ if (ImBinReadStruct (ioType, fd, fp, &header, imTgaHeaderFields)==-1) { ImReturnBinError(); } w = header.tga_imwid; h = header.tga_imhgt; z = header.tga_stype; q = header.tga_spix; tga_attbits = header.tga_imdesc & 0xf; tga_orgbita = (header.tga_imdesc & 0x10) >> 4; tga_orgbitb = (header.tga_imdesc & 0x20) >> 5; tga_rsrvd = (header.tga_imdesc & 0xc0) >> 6; /* makes sure the type is one we deal with, check color map flag if there should be one */ colortable=0; switch (z) { case IMTGA_NODATA: ImErrorFatal (ImQError(), -1, IMENOIMAGE); /* break; (not reached) */ case IMTGA_UNCOMPCOLORMAP: case IMTGA_RLECOLORMAP: colortable=1; break; case IMTGA_UNCOMPRGB: case IMTGA_UNCOMPBW: case IMTGA_RLERGB: case IMTGA_RLEBW: break; case IMTGA_HUFF: case IMTGA_HUFF4TYPE: default: ImErrorFatal (ImQError(), -1, IMEFORMAT); /* break; (not reached) */ } /* Make sure that there is a color map if the type requires one */ if ((colortable) & (!header.tga_cmtype)) ImErrorFatal (ImQError(), -1, IMENOCLT); /* If there is a color table when one doesn't need to be there save it anyway */ if (header.tga_cmtype) colortable=1; /* Allocate a VFB of the required size and type */ switch (z) { case IMTGA_UNCOMPCOLORMAP: /*color mapped image */ case IMTGA_UNCOMPBW: /*monochrome image */ case IMTGA_RLECOLORMAP: /*RLE color mapped image */ case IMTGA_RLEBW: /* compressed monochrome image*/ switch (q) { case 8: /*Targa 16 */ if ( (vfb = ImVfbAlloc (w, h, IMVFBINDEX8) ) ==IMVFBNULL) { ImErrorFatal (ImQError(), -1, IMEMALLOC); } break; case 16: /*Targa 24 (and hopefully 32*/ if ( (vfb = ImVfbAlloc (w, h, IMVFBINDEX16) ) ==IMVFBNULL) { ImErrorFatal (ImQError(), -1, IMEMALLOC); } break; default: /* unsupported type 1 */ sprintf (message, "Weird number of bits per pixel stored'%i'",q); ImErrorFatal (message, -1, IMESYNTAX); /* break; (not reached) */ } break; case IMTGA_UNCOMPRGB: /*RGB image */ case IMTGA_RLERGB: /*RLE RGB image */ switch (q) { case 24: /* No attribute byte */ if ( (vfb =ImVfbAlloc (w,h,IMVFBRGB) ) == IMVFBNULL) { ImErrorFatal (ImQError(), -1, IMEMALLOC); } break; case 16: /* ARRRRRGG GGGBBBBB */ case 32: /* Attribute byte as well */ if ((vfb=ImVfbAlloc (w,h,IMVFBRGB|IMVFBALPHA))==IMVFBNULL) { ImErrorFatal (ImQError(), -1, IMEMALLOC); } break; default: /*kind've a weird amount of bits*/ sprintf (message, "Weird number of bits per pixel stored'%i'",q); ImErrorFatal (message, -1, IMESYNTAX); /* break; (not reached) */ } break; default: ImErrorFatal (ImQError(), -1, IMEFORMAT); /* break; (not reached) */ } /* if needed allocate a name field and read into it */ if (header.tga_numc_ident) { ImMalloc (TgaName, char*, header.tga_numc_ident+1); ImBinRead (ioType, fd, fp, TgaName, UCHAR,1, header.tga_numc_ident); /* information to printout if verbose flag has been set */ sprintf( message, "%s", TgaName); ImInfo( "Image Name", message ); } /* information to printout if verbose flag has been set */ sprintf( message, "Least Significant Byte First"); ImInfo( "Byte Order", message ); sprintf( message, "%d x %d",w,h); ImInfo( "Resolution", message ); if ( (z==IMTGA_UNCOMPCOLORMAP) || (z==IMTGA_RLECOLORMAP) ) sprintf (message, "%d-bit Color Indexed", header.tga_spix); if ( (z==IMTGA_UNCOMPRGB) || (z==IMTGA_RLERGB) ) sprintf (message, "%d-bit RGB", header.tga_spix); if ( (z==IMTGA_UNCOMPBW) || (z==IMTGA_RLEBW) ) sprintf (message, "%d-bit Grayscale", header.tga_spix); ImInfo( "Type", message ); /* if needed allocate a color lookup table and read into it*/ if (colortable) { n=header.tga_cmlen; m=header.tga_cmsize; if ((clt = ImCltAlloc (n)) == IMCLTNULL) ImErrorFatal (ImQError(), -1, IMEMALLOC); /* information to printout if verbose flag has been set */ sprintf (message, "%d Entries",m); ImInfo( "Color Table", message ); /* there appears to be no interleaving for targa color tables */ /* there is however a variable number of bytes per entry */ switch (m) { case 16: /* ARRRRRGG GGGBBBBB */ ImMalloc ( buffer, unsigned char *, sizeof(unsigned char)*n*2); pColor = ImCltQFirst (clt); if (ImBinRead (ioType,fd,fp,buffer, UCHAR, 1, n*2)== -1) { free ( (char *)buffer); ImReturnBinError(); } n *=2; for (i =0; i8) && (z<12)) sprintf (message, "Run Length Encoded"); else sprintf (message, "none"); ImInfo( "Compression Type", message ); if (((q==16) || (q==32) ) && ( (z==IMTGA_UNCOMPRGB) || (z==IMTGA_RLERGB))) sprintf (message, "%d-bit", q); else sprintf (message, "none"); ImInfo( "Alpha Channel", message ); /* Now we read the image pixel data in from our data file */ switch (z) { case IMTGA_UNCOMPCOLORMAP: /* CLT unencoded */ case IMTGA_UNCOMPBW: /* GreyScale */ imReadTga_1and3 (ioType,fd,fp,vfb, q,h,w); break; case IMTGA_UNCOMPRGB: /* RGB unencoded */ imReadTga_2 (ioType,fd,fp,vfb, q,h,w); break; case IMTGA_RLECOLORMAP: /* CLT RLE encoded */ case IMTGA_RLEBW: /* B&W RLE encoded */ imReadTga_9and11 (ioType,fd,fp,vfb,q,h,w); break; case IMTGA_RLERGB: /* RGB RLE encoded */ imReadTga_10 (ioType,fd,fp,vfb,q,h,w); break; default: ImErrorFatal (ImQError(), -1, IMEFORMAT); /* break; (not reached) */ } /* Attach (set) the vfb's color lookup table if one */ if (colortable) ImVfbSClt(vfb, clt); if ( (!tga_orgbita) & (!tga_orgbitb)) { /* If the screen origin is in the lower left hand corner flip */ sprintf (message, "Lower Left-Hand Corner"); ImVfbFlip (vfb, IMVFBYFLIP, vfb); } else if ( (tga_orgbita) & (!tga_orgbitb)) { /* If the screen origin is in the lower right hand corner flip*/ sprintf (message, "Lower Right-Hand Corner"); ImVfbFlip (vfb, IMVFBXYFLIP, vfb); } else if ( (tga_orgbita) & (tga_orgbitb)) { /* If the screen origin is in the top right hand corner flip */ sprintf (message, "Upper Right-Hand Corner"); ImVfbFlip (vfb, IMVFBXFLIP, vfb); } else sprintf (message, "Upper Left-Hand Corner"); ImInfo( "Screen Origin", message ); /* Attach name field to vfb is there is one */ if (header.tga_numc_ident) { TagTableAppend (tagTable, TagEntryAlloc("image name",POINTER,&TgaName)); } /* Attach vfb to tag table */ TagTableAppend (tagTable, TagEntryAlloc ("image vfb", POINTER, &vfb)); return(1); } /* * FUNCTION * imReadTga_1and3 - read either a type 1 or type 3 that has 1 or 2 bytes * per pixel * * type 1 - color lookup table that is not encoded. * type 3 - greyscale image that is not encoded. */ static int /* Returns 1 on successful read */ #ifdef __STDC__ imReadTga_1and3 (int ioType,int fd,FILE *fp,ImVfb *vfb, int q,int h,int w) #else imReadTga_1and3 (ioType,fd,fp,vfb, q,h,w) int ioType; /* I/O flags */ int fd; /* Input file descriptor */ FILE *fp; /* Input file pointer */ ImVfb *vfb; /* Read in Image */ int q; /* How many bits per pixel */ int h; /* Height of image */ int w; /* width of image */ #endif { sdsc_uint16 *bufferl; /* Run buffer (type long) */ sdsc_uint16 *pBufferl; /* bufferl pointer */ ImVfbPtr pPixel; /*VFB pixel pointer */ int x,y; /* Counters */ unsigned char *buffer; /* Run buffer */ unsigned char *pBuffer; /* buffer pointer */ /* interleaving best be noninterleaved as per specs*/ if (q==8) /* one byte per index */ { ImMalloc (buffer, unsigned char *, w * sizeof(unsigned char) ); pPixel = ImVfbQFirst (vfb); for (y =0; y0) { if (ImBinRead (ioType,fd,fp,buffer,UCHAR,1,1) == -1) { free ( (char *)buffer); ImReturnBinError(); } pBuffer = buffer; leadByte = (*pBuffer++); rle = (leadByte&0x80); /* rle = first bit */ count = (leadByte&0x7F)+1; /*count = last 7 bytes +1 */ if (rle) /* run length encoded packet */ { if (ImBinRead (ioType,fd,fp,buffer,UCHAR,1,1) == -1) { free ( (char *)buffer); ImReturnBinError(); } pBuffer = buffer; for (y=0; y0 ) { if (ImBinRead (ioType,fd,fp,bufferl,UINT16,2,1) == -1) { free ( (sdsc_uint16 *)bufferl); ImReturnBinError(); } pBufferl = bufferl; leadByte = (*pBufferl++); rle = (leadByte&0x80); /* rle = first bit */ count = (leadByte&0x7F)+1; /*count = last 7 bytes +1 */ if (rle) /* run length encoded packet */ { if (ImBinRead (ioType,fd,fp,bufferl,UINT16,2,1) == -1) { free ( (sdsc_uint16 *)bufferl); ImReturnBinError(); } pBufferl = bufferl; for (y=0; y0) { if (ImBinRead (ioType,fd,fp,buffer,UCHAR,1,1) == -1) { free ( (char *)buffer); ImReturnBinError(); } pBuffer = buffer; leadByte = (*pBuffer++); rle = (leadByte&0x80); /* rle = first bit */ count = (leadByte&0x7F)+1; /*count = last 7 bytes +1 */ if (rle) /* run length encoded packet */ { if (ImBinRead (ioType,fd,fp,buffer,UCHAR,1,2) == -1) { free ( (char *)buffer); ImReturnBinError(); } pBuffer = buffer; for (y=0; y0 ) { if (ImBinRead (ioType,fd,fp,buffer,UCHAR,1,1) == -1) { free ( (char *)buffer); ImReturnBinError(); } pBuffer = buffer; leadByte = (*pBuffer++); rle = (leadByte&0x80); /* rle = first bit */ count = (leadByte&0x7F)+1; /*count = last 7 bytes +1 */ if (rle) /* run length encoded packet */ { if (ImBinRead (ioType,fd,fp,buffer,UCHAR,1,3) == -1) { free ( (char *)buffer); ImReturnBinError(); } pBuffer = buffer; for (y=0; y 0) { if (ImBinRead (ioType,fd,fp,buffer,UCHAR,1,1) == -1) { free ( (char *)buffer); ImReturnBinError(); } pBuffer = buffer; leadByte = (*pBuffer++); rle = (leadByte&0x80); /* rle = first bit */ count = (leadByte&0x7F)+1; /*count = last 7 bytes +1 */ if (rle) /* run length encoded packet */ { if (ImBinRead (ioType,fd,fp,buffer,UCHAR,1,4) == -1) { free ( (char *)buffer); ImReturnBinError(); } pBuffer = buffer; for (y=0; y> 8; \ imTgaRLEBuf[2] = (index16 & 0x00ff); \ if ( ImBinWrite( ioType, fd, fp, imTgaRLEBuf, UCHAR, 1, 3)==-1) \ { \ ImReturnBinError( ); \ } #define imTgaDumpConstantRun3(b,g,r,len) \ imTgaRLEBuf[0] = (unsigned char) len; \ imTgaRLEBuf[0] |= 0x80; \ imTgaRLEBuf[1] = b; \ imTgaRLEBuf[2] = g; \ imTgaRLEBuf[3] = r; \ if ( ImBinWrite( ioType, fd, fp, imTgaRLEBuf, UCHAR, 1, 4)==-1) \ { \ ImReturnBinError( ); \ } #define imTgaDumpConstantRun4(b,g,r,a,len) \ imTgaRLEBuf[0] = (unsigned char) len; \ imTgaRLEBuf[0] |= 0x80; \ imTgaRLEBuf[1] = b; \ imTgaRLEBuf[2] = g; \ imTgaRLEBuf[3] = r; \ imTgaRLEBuf[4] = a; \ if ( ImBinWrite( ioType, fd, fp, imTgaRLEBuf, UCHAR, 1, 5)==-1) \ { \ ImReturnBinError( ); \ } /* * FUNCTION * imTgaWriteRGB24 - write a Targa RGB file * * DESCRIPTION * That VFB is queried, and the Targa file header written out. * The VFB data is then copied to the file. */ static int /* Returns # of tags used */ #ifdef __STDC__ imTgaWriteRGB24( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable ) #else imTgaWriteRGB24( 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 pptr; /* Pixel pointer */ imTgaHeaderInfo header; /* Tga file header */ unsigned char *buffer; /* line buffer */ unsigned char *pBuffer; /* current location in buffer */ int n,x,y,i,j; /* Counter */ TagEntry *tagEntry; /* Tmp table entry */ char *tmpString; /* Tmp string holder */ int stype; /* Storage type */ int spix; /* Number of bits per image pixel */ int cmsize; /* Number of bits per color map pixel */ /* Set up and write out the header */ BinByteOrder (BINLBF); TagEntryQValue (TagTableQDirect (tagTable, "image vfb", 0), &vfb); stype =IMTGA_UNCOMPRGB; spix =24; cmsize =24; /* write the header out */ imTgaWriteHeader ( ioType, fd, fp,flagsTable, tagTable,stype,spix,cmsize); x = ImVfbQWidth(vfb); y = ImVfbQHeight(vfb); /* allocate buffer space for (width*length*3) scan lines */ ImMalloc (buffer, unsigned char *,3*x); pptr = ImVfbQFirst (vfb); for (j=0; j 0, dump varRun. * otherwise, add this pixel to constantRun. */ if (ImVfbSameRGB(vfb,lastPixel,thisPixel)) { if (varRunLength > 0) { imTgaDumpVarRun(3,varRun, varRunLength - 1); varRunLength = 0; } constantRunLength++; if (constantRunLength==128) { /* Dump a constant run. */ imTgaDumpConstantRun3(ImVfbQBlue(vfb,lastPixel), ImVfbQGreen(vfb, lastPixel), ImVfbQRed(vfb, lastPixel), constantRunLength - 1); constantRunLength = 0; } } else /* This is different from the last character. */ /* Do the exact opposite of the if-branch. */ { varRun[varRunLength*3] = ImVfbQBlue(vfb, lastPixel); varRun[varRunLength*3+1] = ImVfbQGreen(vfb, lastPixel); varRun[varRunLength*3+2] = ImVfbQRed(vfb, lastPixel); if (constantRunLength > 0) { imTgaDumpConstantRun3(ImVfbQBlue(vfb, lastPixel), ImVfbQGreen(vfb, lastPixel), ImVfbQRed(vfb, lastPixel), constantRunLength); constantRunLength = 0; } else { /* Only increment if this is not the end of a constant run. */ varRunLength++; } if (varRunLength==128) { /* Dump variable run. */ imTgaDumpVarRun(3,varRun, varRunLength - 1); varRunLength = 0; } } lastPixel = thisPixel; } /* Dump whatever is left. */ if (constantRunLength==0 && varRunLength==0) { /* single pixel is left. */ imTgaDumpConstantRun3(ImVfbQBlue(vfb, thisPixel), ImVfbQGreen(vfb, thisPixel), ImVfbQRed(vfb, thisPixel), 0 ); } if (constantRunLength > 0) { imTgaDumpConstantRun3(ImVfbQBlue(vfb, thisPixel), ImVfbQGreen(vfb, thisPixel), ImVfbQRed(vfb, thisPixel), constantRunLength ); } if (varRunLength > 0) { varRun[varRunLength*3] = ImVfbQBlue (vfb, lastPixel); varRun[varRunLength*3+1] = ImVfbQGreen(vfb, lastPixel); varRun[varRunLength*3+2] = ImVfbQRed (vfb, lastPixel); imTgaDumpVarRun(3,varRun, varRunLength ); } return (1); } /* * FUNCTION * imTgaWriteRGB32 - write a Targa RGB file that has an alpha channel * * DESCRIPTION * That VFB is queried, and the Targa file header written out. * The VFB data is then copied to the file. */ static int /* Returns # of tags used */ #ifdef __STDC__ imTgaWriteRGB32( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable) #else imTgaWriteRGB32( 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 pptr; /* Pixel pointer */ imTgaHeaderInfo header; /* Tga file header */ unsigned char *buffer; /* line buffer */ unsigned char *pBuffer; /* current location in buffer */ int n,x,y,i,j; /* Counter */ TagEntry *tagEntry; /* Tmp table entry */ char *tmpString; /* Tmp string holder */ int stype; /* Storage type */ int spix; /* Number of bits per image pixel */ int cmsize; /* Number of bits per color map pixel */ /* Set up and write out the header */ BinByteOrder (BINLBF); TagEntryQValue (TagTableQDirect (tagTable, "image vfb", 0), &vfb); stype = IMTGA_UNCOMPRGB; spix =32; cmsize =24; /* write the header out */ imTgaWriteHeader ( ioType, fd, fp,flagsTable, tagTable,stype,spix,cmsize); x = ImVfbQWidth(vfb); y = ImVfbQHeight(vfb); /* allocate buffer space for (width*length83) scan lines */ ImMalloc (buffer, unsigned char *,4*x); pptr = ImVfbQFirst (vfb); for (j=0; j 0, dump varRun. * otherwise, add this pixel to constantRun. */ if (ImVfbSameRGBA(vfb,lastPixel,thisPixel)) { if (varRunLength > 0) { imTgaDumpVarRun(4,varRun, varRunLength - 1); varRunLength = 0; } constantRunLength++; if (constantRunLength==128) { /* Dump a constant run. */ imTgaDumpConstantRun4( ImVfbQBlue(vfb,lastPixel), ImVfbQGreen(vfb, lastPixel), ImVfbQRed(vfb, lastPixel), ImVfbQAlpha(vfb,lastPixel), constantRunLength - 1); constantRunLength = 0; } } else /* This is different from the last character. */ /* Do the exact opposite of the if-branch. */ { varRun[varRunLength*4] = ImVfbQBlue(vfb, lastPixel); varRun[varRunLength*4+1] = ImVfbQGreen(vfb, lastPixel); varRun[varRunLength*4+2] = ImVfbQRed(vfb, lastPixel); varRun[varRunLength*4+3] = ImVfbQAlpha(vfb, lastPixel); if (constantRunLength > 0) { imTgaDumpConstantRun4( ImVfbQBlue(vfb, lastPixel), ImVfbQGreen(vfb, lastPixel), ImVfbQRed(vfb, lastPixel), ImVfbQAlpha(vfb, lastPixel), constantRunLength); constantRunLength = 0; } else { /* Only increment if this is not the end of a constant run. */ varRunLength++; } if (varRunLength==128) { /* Dump variable run. */ imTgaDumpVarRun(4,varRun, varRunLength - 1); varRunLength = 0; } } lastPixel = thisPixel; } /* Dump whatever is left. */ if (constantRunLength==0 && varRunLength==0) { /* single pixel is left. */ imTgaDumpConstantRun4( ImVfbQBlue(vfb, thisPixel), ImVfbQGreen(vfb, thisPixel), ImVfbQRed(vfb, thisPixel), ImVfbQAlpha(vfb,thisPixel), 0 ); } if (constantRunLength > 0) { imTgaDumpConstantRun4( ImVfbQBlue(vfb, thisPixel), ImVfbQGreen(vfb, thisPixel), ImVfbQRed(vfb, thisPixel), ImVfbQAlpha(vfb,thisPixel), constantRunLength ); } if (varRunLength > 0) { varRun[varRunLength*4] = ImVfbQBlue (vfb, lastPixel); varRun[varRunLength*4+1] = ImVfbQGreen(vfb, lastPixel); varRun[varRunLength*4+2] = ImVfbQRed (vfb, lastPixel); varRun[varRunLength*4+3] = ImVfbQAlpha (vfb, lastPixel); imTgaDumpVarRun(4,varRun, varRunLength ); } return (1); } /* * FUNCTION * imTgaWriteCLT8 - write a Targa CLT file that has 8 bits pre channel * * DESCRIPTION * That VFB is queried, and the Targa file header written out. * The VFB data is then copied to the file. */ static int /* Returns # of tags used */ #ifdef __STDC__ imTgaWriteCLT8( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable) #else imTgaWriteCLT8( 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 { TagEntry *tagEntry; /* Tmp table entry */ int stype; /* Storage type */ int spix; /* Number of bits per image pixel */ int cmsize; /* Number of bits per color map pixel */ /* Set up and write out the header */ stype = IMTGA_UNCOMPCOLORMAP; spix = 8; cmsize = 24; /*write header out */ imTgaWriteHeader (ioType, fd, fp, flagsTable, tagTable,stype,spix,cmsize); imTgaWrite8image (ioType, fd, fp, flagsTable, tagTable); return(1); } /* * FUNCTION * imTgaWrite8image - write a Targa file that has 8 bits pre channel * * DESCRIPTION * That VFB is queried, The VFB data is then copied to the file. */ static int /* Returns # of tags used */ #ifdef __STDC__ imTgaWrite8image( int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable ) #else imTgaWrite8image( 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 read from */ #endif { ImVfb *vfb; /* Read in image */ ImVfbPtr pptr; /* Pixel pointer */ imTgaHeaderInfo header; /* Tga file header */ unsigned char *buffer; /* line buffer */ unsigned char *pBuffer; /* current location in buffer */ int x,y,i,j; /* Counter */ TagEntry *tagEntry; /* Tmp table entry */ BinByteOrder (BINLBF); TagEntryQValue (TagTableQDirect (tagTable, "image vfb", 0), &vfb); x =ImVfbQWidth(vfb); y = ImVfbQHeight(vfb); /* allocate buffer space for (width*length83) scan lines */ ImMalloc (buffer, unsigned char *, 1*x); pptr = ImVfbQFirst (vfb); for (j=0; j 0, dump varRun. * otherwise, add this pixel to constantRun. */ if (ImVfbSameIndex8(vfb,lastPixel,thisPixel)) { if (varRunLength > 0) { imTgaDumpVarRun(1,varRun, varRunLength - 1); varRunLength = 0; } constantRunLength++; if (constantRunLength==128) { /* Dump a constant run. */ imTgaDumpConstantRun1(ImVfbQIndex(vfb,lastPixel), constantRunLength - 1); constantRunLength = 0; } } else /* This is different from the last character. */ /* Do the exact opposite of the if-branch. */ { varRun[varRunLength] = ImVfbQIndex(vfb, lastPixel); if (constantRunLength > 0) { imTgaDumpConstantRun1(ImVfbQIndex(vfb, lastPixel), constantRunLength); constantRunLength = 0; } else { /* Only increment if this is not the end of a constant run. */ varRunLength++; } if (varRunLength==128) { /* Dump variable run. */ imTgaDumpVarRun(1,varRun, varRunLength - 1); varRunLength = 0; } } lastPixel = thisPixel; } /* Dump whatever is left. */ if (constantRunLength==0 && varRunLength==0) { /* single pixel is left. */ imTgaDumpConstantRun1(ImVfbQIndex(vfb, thisPixel), 0 ); } if (constantRunLength > 0) { imTgaDumpConstantRun1(ImVfbQIndex(vfb, thisPixel), constantRunLength ); } if (varRunLength > 0) { varRun[varRunLength] = ImVfbQIndex (vfb, lastPixel); imTgaDumpVarRun(1,varRun, varRunLength ); } return (1); } /* * FUNCTION * imTgaWriteCLT16 - write a Targa CLT file that has 16 bits pre channel * * DESCRIPTION * That VFB is queried, and the Targa file header written out. * The VFB data is then copied to the file. */ static int /* Returns # of tags used */ #ifdef __STDC__ imTgaWriteCLT16( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable) #else imTgaWriteCLT16( 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 { int stype; /* Storage type */ int spix; /* Number of bits per image pixel */ int cmsize; /* Number of bits per color map pixel */ /* Set up and write out the header */ stype = IMTGA_UNCOMPCOLORMAP; spix = 16; cmsize = 24; /* Write header out */ imTgaWriteHeader (ioType, fd, fp, flagsTable, tagTable,stype,spix,cmsize); imTgaWrite16image (ioType, fd, fp, flagsTable, tagTable); return(1); } /* * FUNCTION * imTgaWrite16image - write a Targa CLT file that has 16 bits per channel * * DESCRIPTION * That VFB is queried, The VFB data is then copied to the file. */ static int /* Returns # of tags used */ #ifdef __STDC__ imTgaWrite16image( int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable ) #else imTgaWrite16image( 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 read from */ #endif { ImVfb *vfb; /* Read in image */ ImVfbPtr pptr; /* Pixel pointer */ imTgaHeaderInfo header; /* Tga file header */ unsigned char *bufferl; /* line buffer */ unsigned char *pBufferl; /* current location in buffer */ int x,y,i,j; /* Counter */ TagEntry *tagEntry; /* Tmp table entry */ BinByteOrder (BINLBF); TagEntryQValue (TagTableQDirect (tagTable, "image vfb", 0), &vfb); x = ImVfbQWidth(vfb); y = ImVfbQHeight(vfb); /* allocate buffer space for (width*length) scan lines */ ImMalloc (bufferl, unsigned char *, 2 * x * sizeof(unsigned char)); pptr = ImVfbQFirst (vfb); for (j=0; j> 8; ImVfbSInc (vfb, pptr); } if (ImBinWrite (ioType, fd, fp, bufferl, UCHAR, 1, x*2 ) ==-1) { free ( bufferl); ImReturnBinError( ); } } free (bufferl); return (1); } /* * FUNCTION * imTgaWriteCLTRLE16 - write a Targa CLT file that has 16 bits per channel * and is RLE. * * DESCRIPTION * That VFB is queried, and the Targa file header written out. * The VFB data is then copied to the file. */ static int /* Returns # of tags used */ #ifdef __STDC__ imTgaWriteCLTRLE16( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable) #else imTgaWriteCLTRLE16( 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 { int stype; /* Storage type */ int spix; /* Number of bits per image pixel */ int cmsize; /* Number of bits per color map pixel */ /* Set up and write out the header */ BinByteOrder (BINLBF); stype = IMTGA_RLECOLORMAP; spix = 16; cmsize = 24; /* write the header out */ imTgaWriteHeader ( ioType, fd, fp,flagsTable, tagTable,stype,spix,cmsize); imTgaWriteRLE16(ioType,fd,fp,flagsTable,tagTable); return(1); } /* * FUNCTION * imTgaWriteRLE16 - write a Targa CLT file that has 16 bits pre channel * and is RLE. * * DESCRIPTION * That VFB is queried, The VFB data is then copied to the file. */ static int /* Returns # of tags used */ #ifdef __STDC__ imTgaWriteRLE16( int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable ) #else imTgaWriteRLE16( 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 read from */ #endif { ImVfb *vfb; /* Read in image */ ImVfbPtr vfbPtr; /* Pixel pointer */ TagEntry *tagEntry; /* Tmp table entry */ int stype; /* Storage type */ int spix; /* Number of bits per image pixel */ int cmsize; /* Number of bits per color map pixel */ unsigned char varRun[128*2]; /* Holds a variable run */ int varRunLength; /* Length of this variable run. */ int constantRunLength; /* Length of this constant run. */ ImVfbPtr lastPixel, thisPixel; /* point to pixels. */ int i; /* loop index */ /* * In this function, a variable run refers to a series of different * pixel values. The 'length' of such a run is one less than the * number of pixels. For instance, if our pixel values were * "A B C D" then this would be a "variable run of length 3". * * Similarly, "A A A" would be a "constant run of length 3". */ TagEntryQValue (TagTableQDirect (tagTable, "image vfb", 0), &vfb); /* Initialize stuff. */ varRunLength = 0; constantRunLength = 0; thisPixel = ImVfbQFirst( vfb ); lastPixel = thisPixel; for (i = 1;i < ImVfbQWidth(vfb) * ImVfbQHeight( vfb ) ; i++) { ImVfbSInc(vfb,thisPixel); /* * If this pixel is the same as the last one then: * if varRunLength > 0, dump varRun. * otherwise, add this pixel to constantRun. */ if (ImVfbSameIndex16(vfb,lastPixel,thisPixel)) { if (varRunLength > 0) { imTgaDumpVarRun(2,varRun, varRunLength - 1); varRunLength = 0; } constantRunLength++; if (constantRunLength==128) { /* Dump a constant run. */ imTgaDumpConstantRun2(ImVfbQIndex16(vfb,lastPixel), constantRunLength - 1); constantRunLength = 0; } } else /* This is different from the last character. */ /* Do the exact opposite of the if-branch. */ { varRun[varRunLength*2] = (ImVfbQIndex16(vfb, lastPixel) & 0xff00) >> 8; varRun[varRunLength*2+1] = ImVfbQIndex16(vfb, lastPixel) & 0x00ff; if (constantRunLength > 0) { imTgaDumpConstantRun2(ImVfbQIndex16(vfb, lastPixel), constantRunLength); constantRunLength = 0; } else { /* Only increment if this is not the end of a constant run. */ varRunLength++; } if (varRunLength==128) { /* Dump variable run. */ imTgaDumpVarRun(2,varRun, varRunLength - 1); varRunLength = 0; } } lastPixel = thisPixel; } /* Dump whatever is left. */ if (constantRunLength==0 && varRunLength==0) { /* single pixel is left. */ imTgaDumpConstantRun2(ImVfbQIndex16(vfb, thisPixel), 0 ); } if (constantRunLength > 0) { imTgaDumpConstantRun2(ImVfbQIndex16(vfb, thisPixel), constantRunLength ); } if (varRunLength > 0) { varRun[varRunLength*2] = (ImVfbQIndex16(vfb, lastPixel) & 0xff00) >> 8; varRun[varRunLength*2+1] = ImVfbQIndex16(vfb, lastPixel) & 0x00ff; imTgaDumpVarRun(2,varRun, varRunLength ); } return (1); } /* * FUNCTION * imTgaWriteRGB16 - write a Targa RGB with 2 bytes per pixel file * * DESCRIPTION * That VFB is queried, and the Targa file header written out. * The VFB data is then copied to the file. */ static int /* Returns # of tags used */ #ifdef __STDC__ imTgaWriteRGB16( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable ) #else imTgaWriteRGB16( 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 pptr; /* Pixel pointer */ imTgaHeaderInfo header; /* Tga file header */ unsigned char *buffer; /* line buffer */ unsigned char *pBuffer; /* current location in buffer */ int n,x,y,i,j; /* Counter */ TagEntry *tagEntry; /* Tmp table entry */ char *tmpString; /* Tmp string holder */ int stype; /* Storage type */ int spix; /* Number of bits per image pixel */ int cmsize; /* Number of bits per color map pixel */ unsigned char expBlue,expGreen,expRed; /* Pixels before shrunk */ unsigned char byte1,byte2; /* Pixels after shrunk to 2 bytes */ /* Set up and write out the header */ BinByteOrder (BINLBF); TagEntryQValue (TagTableQDirect (tagTable, "image vfb", 0), &vfb); stype = IMTGA_UNCOMPRGB; spix = 16; cmsize = 24; /* write the header out */ imTgaWriteHeader ( ioType, fd, fp,flagsTable, tagTable,stype,spix,cmsize); x = ImVfbQWidth(vfb); y = ImVfbQHeight(vfb); /* allocate buffer space for (width*length*3) scan lines */ ImMalloc (buffer, unsigned char *,2*x); pptr = ImVfbQFirst (vfb); for (j=0; j>3) <<2 ; expGreen= ((ImVfbQGreen (vfb, pptr))>>2) >>4 ; byte2 = (byte2 | expRed |expGreen); byte1 = ((ImVfbQGreen (vfb, pptr))>>2) << 5; expBlue= (ImVfbQBlue (vfb, pptr))>>3 ; byte1 = (byte1 |expBlue); *pBuffer++ =byte1; *pBuffer++ =byte2; ImVfbSInc (vfb, pptr); } if (ImBinWrite (ioType, fd, fp, buffer, UCHAR,1,pBuffer - buffer) ==-1) { free ( (char *)buffer); ImReturnBinError( ); } } free ( (char *)buffer); return (1); } /* * FUNCTION * imTgaWriteRGBRLE16 - write a Targa RGB file that is RLE 2 bytes * per pixel. * * DESCRIPTION * That VFB is queried, and the Targa file header written out. * The VFB data is then copied to the file. */ static int /* Returns # of tags used */ #ifdef __STDC__ imTgaWriteRGBRLE16( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE* fp, TagTable *flagsTable, TagTable *tagTable ) #else imTgaWriteRGBRLE16( 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 pptr; /* Pixel pointer */ imTgaHeaderInfo header; /* Tga file header */ unsigned char *bufferRle; /* line buffer for rle packets */ unsigned char *bufferUn; /* line buffer for unencoded */ unsigned char *bufferCount; /* Count buffer */ unsigned char *pBuffer; /* current location in buffer */ int n,x,y,i,j; /* Counter */ TagEntry *tagEntry; /* Tmp table entry */ char *tmpString; /* Tmp string holder */ int stype; /* Storage type */ int spix; /* Number of bits per image pixel */ int cmsize; /* Number of bits per color map pixel */ int total; /* counter for number of bytes encoded*/ int currentColor; /* What color from vfb are we on */ int field; /* The field from the color we are on */ int fieldNext; /* The field from the color we are on */ int fieldRed; /* The field from the color we are on */ int fieldGreen; /* The field from the color we are on */ int fieldBlue; /* The field from the color we are on */ int fieldAlpha; /* The field from the color we are on */ int fieldRedNext; /* The field from the color we are on */ int fieldGreenNext; /* The field from the color we are on */ int fieldBlueNext; /* The field from the color we are on */ int fieldAlphaNext; /* The field from the color we are on */ int count; /* Numbe to store in packet */ unsigned char byte1,byte2,byte3,byte4;/* Bytes to write from rle packet */ int atend; /* whether at end of vfb or not */ int stopSpot; /* when should stop reading out of vfb*/ unsigned char expBlue,expGreen,expRed; /* Pixels before shrunk */ /* Set up and write out the header */ BinByteOrder (BINLBF); TagEntryQValue (TagTableQDirect (tagTable, "image vfb", 0), &vfb); stype = IMTGA_RLERGB; spix = 16; cmsize = 24; /* write the header out */ imTgaWriteHeader ( ioType, fd, fp,flagsTable, tagTable,stype,spix,cmsize); y = ImVfbQWidth(vfb); x = ImVfbQHeight(vfb); stopSpot=(x*y*1)-3; /* allocate buffer space for one RLE packet */ /* unencoded it can reach up to 129 bytes */ ImMalloc (bufferUn, unsigned char *,260); ImMalloc (bufferRle, unsigned char *,4); ImMalloc (bufferCount, unsigned char *,1); pptr = ImVfbQFirst (vfb); /* get the first pixel color to start with */ total =0; /* a running count of bytes encoded */ currentColor = 0; /* Color to start with */ atend =0; /*not at the end of the vfb yet */ fieldRed = ImVfbQRed(vfb,pptr); fieldGreen = ImVfbQGreen(vfb,pptr); fieldBlue = ImVfbQBlue(vfb,pptr); ImVfbSInc(vfb,pptr); fieldRedNext = ImVfbQRed(vfb,pptr); fieldGreenNext = ImVfbQGreen(vfb,pptr); fieldBlueNext = ImVfbQBlue(vfb,pptr); if ((fieldRed==fieldGreen) && (fieldGreen==fieldBlue)) field=fieldRed; else field = -1; if ((fieldRedNext==fieldGreenNext) && (fieldGreenNext==fieldBlueNext)) fieldNext=fieldRedNext; else fieldNext = -2; do { /* encode width by height scanlines */ count=0; /* Count-1 is what's stored*/ /* see if you should rle something */ while ( (count<128) && (field == fieldNext) && (!atend) ) { if ( ( count+total) > stopSpot) atend=1; count++; fieldRed = fieldRedNext; fieldGreen = fieldGreenNext; fieldBlue = fieldBlueNext; fieldAlpha = fieldAlphaNext; ImVfbSInc(vfb,pptr); fieldRedNext = ImVfbQRed(vfb,pptr); fieldGreenNext = ImVfbQGreen(vfb,pptr); fieldBlueNext = ImVfbQBlue(vfb,pptr); fieldAlphaNext = ImVfbQAlpha(vfb,pptr); if ((fieldRed==fieldGreen) && (fieldGreen==fieldBlue) && (fieldBlue==fieldAlpha)) field=fieldRed; else field = -1; if ((fieldRedNext==fieldGreenNext) && (fieldGreenNext==fieldBlueNext) && (fieldBlueNext==fieldAlphaNext)) fieldNext=fieldRedNext; else fieldNext = -2; } if (count>0) /* Actually have something to encode */ { count--; pBuffer = bufferRle; byte1= count | 0x80; /* Store 1 then count in one byte */ *pBuffer++ = byte1; byte4 = fieldAlpha << 7; expRed= (fieldRed>>3) <<2 ; expGreen= (fieldGreen>>2) >>4 ; byte4 = (byte4 | expRed |expGreen); byte3 = (fieldGreen>>2) << 5; expBlue= fieldBlue >>3 ; byte3 = (byte3 |expBlue); *pBuffer++ = byte3; *pBuffer++ = byte4; if (ImBinWrite (ioType,fd,fp,bufferRle,UCHAR,1,3)==-1) { free ( (char *) bufferRle); ImReturnBinError( ); } } else { count= -1; pBuffer = bufferUn; while ( (count<127) && (field !=fieldNext) && (!atend) ) { byte4 = fieldAlpha << 7; expRed= (fieldRed>>3) <<2 ; expGreen= (fieldGreen>>2) >>4 ; byte4 = (byte4 | expRed |expGreen); byte3 = (fieldGreen>>2) << 5; expBlue= fieldBlue >>3 ; byte3 = (byte3 |expBlue); *pBuffer++ = byte3; *pBuffer++ = byte4; if ( ( count+total) > stopSpot) atend=1; count++; fieldRed = fieldRedNext; fieldGreen = fieldGreenNext; fieldBlue = fieldBlueNext; fieldAlpha = fieldAlphaNext; ImVfbSInc(vfb,pptr); fieldRedNext = ImVfbQRed(vfb,pptr); fieldGreenNext = ImVfbQGreen(vfb,pptr); fieldBlueNext = ImVfbQBlue(vfb,pptr); fieldAlphaNext = ImVfbQAlpha(vfb,pptr); if ((fieldRed==fieldGreen) && (fieldGreen==fieldBlue) && (fieldBlue==fieldAlpha)) field=fieldRed; else field = -1; if ((fieldRedNext==fieldGreenNext) && (fieldGreenNext==fieldBlueNext) && (fieldBlueNext==fieldAlphaNext)) fieldNext=fieldRedNext; else fieldNext = -2; } byte1= count & 0x7F; /* Store 0 then count in one byte*/ pBuffer = bufferCount; *pBuffer = byte1; if (ImBinWrite (ioType,fd,fp,bufferCount,UCHAR,1,1)==-1) { free ( (char *) bufferCount); ImReturnBinError( ); } if (ImBinWrite (ioType,fd,fp,bufferUn,UCHAR,1,2*(count+1))==-1) { free ( (char *) bufferUn); ImReturnBinError( ); } } total+=count+1; } while (!atend); /* encode width by height scanlines */ free ( (char *)bufferRle); free ( (char *)bufferUn); free ( (char *)bufferCount); return (1); } /* * FUNCTION * imTgaWriteGREY8 - write a Targa file that is greyscale with 8bits * * DESCRIPTION * That VFB is queried, and the Targa file header written out. * The VFB data is then copied to the file. */ static int /* Returns # of tags used */ #ifdef __STDC__ imTgaWriteGREY8( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable) #else imTgaWriteGREY8( 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 { int stype; /* Storage type */ int spix; /* Number of bits per image pixel */ int cmsize; /* Number of bits per color map pixel */ BinByteOrder (BINLBF); /* Set up and write out the header */ stype = IMTGA_UNCOMPBW; spix = 8; cmsize = 0; /* write the header out */ imTgaWriteHeader ( ioType, fd, fp,flagsTable, tagTable,stype,spix,cmsize); imTgaWrite8image ( ioType, fd, fp,flagsTable, tagTable); return (1); } /* * FUNCTION * imTgaWriteGREYRLE8 - write a Targa file that is greyscale * run-length-encoded with 2 bytes per pixel. * * DESCRIPTION * That VFB is queried, and the Targa file header written out. * The VFB data is then copied to the file. */ static int /* Returns # of tags used */ #ifdef __STDC__ imTgaWriteGREYRLE8( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable) #else imTgaWriteGREYRLE8( 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 { int stype; /* Storage type */ int spix; /* Number of bits per image pixel */ int cmsize; /* Number of bits per color map pixel */ BinByteOrder (BINLBF); stype = IMTGA_RLEBW; spix = 8; cmsize = 0; /* write the header out */ imTgaWriteHeader ( ioType, fd, fp,flagsTable, tagTable,stype,spix,cmsize); imTgaWriteRLE8 (ioType, fd, fp, flagsTable,tagTable); return (1); } /* * FUNCTION * imTgaWriteGREY16 - write a Targa file that is greyscale with 16bits. * * DESCRIPTION * That VFB is queried, and the Targa file header written out. * The VFB data is then copied to the file. */ static int /* Returns # of tags used */ #ifdef __STDC__ imTgaWriteGREY16( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable) #else imTgaWriteGREY16( 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 { int stype; /* Storage type */ int spix; /* Number of bits per image pixel */ int cmsize; /* Number of bits per color map pixel */ BinByteOrder (BINLBF); /* Set up and write out the header */ stype = IMTGA_UNCOMPBW; spix = 16; cmsize = 0; /* write the header out */ imTgaWriteHeader ( ioType, fd, fp,flagsTable, tagTable,stype,spix,cmsize); imTgaWrite16image (ioType, fd, fp, flagsTable,tagTable); return (1); } /* * FUNCTION * imTgaWriteGREYRLE16 - write a Targa file run-length-encoded * with 16 bits per pixel. * * DESCRIPTION * That VFB is queried, and the Targa file header written out. * The VFB data is then copied to the file. */ static int /* Returns # of tags used */ #ifdef __STDC__ imTgaWriteGREYRLE16( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable) #else imTgaWriteGREYRLE16( 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 { int stype; /* Storage type */ int spix; /* Number of bits per image pixel */ int cmsize; /* Number of bits per color map pixel */ BinByteOrder (BINLBF); /* Set up and write out the header */ stype = IMTGA_RLEBW; spix = 16; cmsize = 0; /* write the header out */ imTgaWriteHeader ( ioType, fd, fp,flagsTable, tagTable,stype,spix,cmsize); imTgaWriteRLE16 (ioType, fd, fp, flagsTable,tagTable); return (1); } /* * FUNCTION * imTgaWriteHeader - write a Targa file header * * DESCRIPTION * Based on info passed to it a standard Targa file header written out. * If there is a color lookup table then it too is written out. * If there is a name field it too is written out. */ static int /* Returns # of tags used */ #ifdef __STDC__ imTgaWriteHeader( int ioType, int fd, FILE *fp,TagTable *flagsTable, TagTable *tagTable,int stype,int spix,int cmsize ) #else imTgaWriteHeader( ioType, fd, fp,flagsTable, tagTable,stype,spix,cmsize ) int ioType; /* I/O flags */ int fd; /* Input file descriptor */ FILE *fp; /* Input file pointer */ TagTable *flagsTable; TagTable *tagTable; int stype; /* what data storage type it is */ int spix; /* The number of bits per image pixel*/ int cmsize; /* The number of bits per clt pixel*/ #endif { ImVfb *vfb; /* Read in image */ ImVfbPtr pptr; /* Pixel pointer */ ImClt *clt; /* CLT pointer */ ImCltPtr pColor; imTgaHeaderInfo header; /* Tga file header */ unsigned char *buffer; /* line buffer */ unsigned char *pBuffer; /* current location in buffer */ int n,x,y,i,j; /* Counter */ TagEntry *tagEntry; /* Tmp table entry */ char *tmpString; /* Tmp string holder */ int tga_attbits; /* number of attribute bits per pix. */ int tga_rsrvd; /* Reserved bit */ int tga_orgbita; /* Screen origin bit 4 */ int tga_orgbitb; /* Screen origin bit 5 */ char message[200]; /* Used for ImInfo string */ /* Set up and write out the header */ BinByteOrder (BINLBF); TagEntryQValue (TagTableQDirect (tagTable, "image vfb", 0), &vfb); clt = ImVfbQClt(vfb); /* Get the name field if there is one */ tagEntry = TagTableQDirect (tagTable, "image name",0); if (tagEntry == TAGENTRYNULL) header.tga_numc_ident = 0; else { TagEntryQValue(tagEntry, &tmpString); header.tga_numc_ident=strlen(tmpString); if (header.tga_numc_ident>255) header.tga_numc_ident=255; ImInfo( "Image Name", tmpString ); } if (ImVfbQClt(vfb)==IMCLTNULL) header.tga_cmtype = 0; else if (cmsize == 0) header.tga_cmtype = 0; else header.tga_cmtype = 1; header.tga_stype = stype; header.tga_cmorigin = 0; if (header.tga_cmtype) header.tga_cmlen = ImCltQNColors(clt); else header.tga_cmlen = 0; header.tga_cmsize = cmsize; header.tga_imxorg = 0; header.tga_imyorg = 0; header.tga_imwid = ImVfbQWidth(vfb); header.tga_imhgt = ImVfbQHeight( vfb); header.tga_spix = spix; tga_attbits = 0; tga_orgbita = 0 << 4; tga_orgbitb = 1 << 5; tga_rsrvd = 0 << 6; header.tga_imdesc=tga_attbits|tga_orgbita|tga_orgbitb|tga_rsrvd; /* information to printout if verbose flag has been set */ ImInfo ("Byte Order", "Least Significant Byte First"); sprintf (message, "%d x %d", ImVfbQWidth(vfb), ImVfbQHeight(vfb)); ImInfo ("Resolution", message); if ( (stype==IMTGA_UNCOMPCOLORMAP) || (stype==IMTGA_RLECOLORMAP) ) sprintf (message, "%d-bit Color Indexed", spix); if ( (stype==IMTGA_UNCOMPRGB) || (stype==IMTGA_RLERGB) ) sprintf (message, "%d-bit RGB", spix); if ( (stype==IMTGA_UNCOMPBW) || (stype==IMTGA_RLEBW) ) sprintf (message, "%d-bit Greyscale", spix); ImInfo( "Type", message ); if (cmsize>0) { sprintf (message, "%d Entries",cmsize); ImInfo( "Color Table", message ); } /* information to printout if verbose flag has been set */ if ((stype>8) && (stype<12)) sprintf (message, "Run Length Encoded (RLE)"); else sprintf (message, "none"); ImInfo( "Compression Type", message ); if (((spix==16) || (spix==32) ) && ( (stype==IMTGA_UNCOMPRGB) || (stype==IMTGA_RLERGB))) sprintf (message, "%d-bit", spix); else sprintf (message, "none"); ImInfo( "Alpha Channel", message ); /* Now we read the image pixel data in from our data file */ /* write the header out */ if (ImBinWriteStruct (ioType, fd, fp, &header, imTgaHeaderFields) ==-1) ImReturnBinError( ); if (header.tga_numc_ident) /* if there is a name to write */ ImBinWrite (ioType, fd, fp, tmpString, UCHAR,1,header.tga_numc_ident); /* write out a clt if there is one */ if (header.tga_cmlen) { ImMalloc (buffer, unsigned char *, 3*header.tga_cmlen) pColor = ImCltQFirst(clt); pBuffer = buffer; for (j=0; j