jedi-outcast/utils/roq2/libim/imtga.c

6153 lines
104 KiB
C

/**
** $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; i<n; i+=2)
{
imTga2ByteExpand_CLT (buffer[i],buffer[i+1],pColor);
ImCltSInc (clt, pColor);
}
free ( (char *)buffer);
break;
case 24: /* BBBBBBBB GGGGGGGG RRRRRRRR */
ImMalloc ( buffer, unsigned char *, sizeof(unsigned char)*n*3);
pColor = ImCltQFirst (clt);
if (ImBinRead (ioType,fd,fp,buffer, UCHAR, 1, n*3)== -1)
{
free ( (char *)buffer);
ImReturnBinError();
}
n *=3;
for (i =0; i<n; i+=3)
{
ImCltSBlue (pColor, buffer[i]);
ImCltSGreen(pColor, buffer[i+1]);
ImCltSRed (pColor, buffer[i+2]);
ImCltSInc (clt, pColor);
}
free ( (char *)buffer);
break;
case 32: /* BBBBBBBB GGGGGGGG RRRRRRRR AAAAAAAA*/
ImMalloc ( buffer, unsigned char *, sizeof(unsigned char)*n*4);
pColor = ImCltQFirst (clt);
if (ImBinRead (ioType,fd,fp,buffer, UCHAR, 1, n*4)== -1)
{
free ( (char *)buffer);
ImReturnBinError();
}
n *=4;
for (i =0; i<n; i+=4)
{
ImCltSBlue (pColor, buffer[i]);
ImCltSGreen(pColor, buffer[i+1]);
ImCltSRed (pColor, buffer[i+2]);
/* we don't like any attribute bits mucking around our color tables */
ImCltSInc (clt, pColor);
}
free ( (char *)buffer);
break;
default: /* kooky entry type */
sprintf (message, "Weird number of bits per pixel in color table stored'%i'",q);
ImErrorFatal (message, -1, IMESYNTAX);
/* break; (not reached) */
}
}
/* information to printout if verbose flag has been set */
if ((z>8) && (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; y<h; y++)
{
if (ImBinRead (ioType,fd,fp,buffer, UCHAR, 1,w) == -1)
{
free ( (char *)buffer);
ImReturnBinError();
}
pBuffer = buffer;
for (x=0; x<w; x++)
{
ImVfbSIndex8(vfb, pPixel, *pBuffer++ );
ImVfbSInc(vfb, pPixel);
}
}
free ( (char *) buffer);
}
else /*two bytes per index */
{
ImMalloc (bufferl, sdsc_uint16 *, w* sizeof(sdsc_uint16) );
pPixel = ImVfbQFirst (vfb);
for (y =0; y<h; y++)
{
if (ImBinRead (ioType,fd,fp,bufferl,UINT16,2,w) == -1)
{
free ( (sdsc_uint16 *)bufferl);
ImReturnBinError();
}
pBufferl = bufferl;
for (x=0; x<w; x++)
{
ImVfbSIndex16(vfb, pPixel, *pBufferl++ );
ImVfbSInc(vfb, pPixel);
}
}
free ( (sdsc_uint16 *) bufferl);
}
return(1);
}
/*
* FUNCTION
* imReadTga_2 - read a type 2 that has 2, 3 or 4 bytes per pixel
*
* type 2 - unencoded RGB image.
*/
static int /* Returns 1 on successful read */
#ifdef __STDC__
imReadTga_2 (int ioType,int fd,FILE *fp,ImVfb *vfb, int q,int h,int w)
#else
imReadTga_2 (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
{
ImVfbPtr pPixel; /*VFB pixel pointer */
int x,y; /* Counters */
unsigned char *buffer; /* Run buffer */
unsigned char *pBuffer; /* buffer pointer */
switch (q)
{
case 16: /*two bits per pixel*/
ImMalloc (buffer, unsigned char *, w * 2);
pPixel = ImVfbQFirst (vfb);
for (y =0; y<h; y++)
{
if (ImBinRead (ioType,fd,fp,buffer,UCHAR,1,2*w) == -1)
{
free ( (char *)buffer);
ImReturnBinError();
}
pBuffer = buffer;
for (x=0; x<w; x++)
{
imTga2ByteExpand_PIX (*pBuffer,*(pBuffer+1),pPixel,vfb);
pBuffer+=2;
ImVfbSInc(vfb,pPixel);
}
}
free ( (char *) buffer);
break;
case 24: /* three bits per pixel */
ImMalloc (buffer, unsigned char *, w * 3);
pPixel = ImVfbQFirst (vfb);
for (y =0; y<h; y++)
{
if (ImBinRead (ioType,fd,fp,buffer,UCHAR,1,3*w) == -1)
{
free ( (char *)buffer);
ImReturnBinError();
}
pBuffer = buffer;
for (x=0; x<w; x++)
{
ImVfbSBlue(vfb, pPixel, *pBuffer++ );
ImVfbSGreen(vfb, pPixel, *pBuffer++ );
ImVfbSRed(vfb, pPixel, *pBuffer++ );
ImVfbSInc(vfb, pPixel);
}
}
free ( (char *) buffer);
break;
case 32: /* four bits per pixel */
ImMalloc (buffer, unsigned char *, w * 4);
pPixel = ImVfbQFirst (vfb);
for (y =0; y<h; y++)
{
if (ImBinRead (ioType,fd,fp,buffer,UCHAR,1,4*w) == -1)
{
free ( (char *)buffer);
ImReturnBinError();
}
pBuffer = buffer;
for (x=0; x<w; x++)
{
ImVfbSBlue(vfb, pPixel, *pBuffer++ );
ImVfbSGreen(vfb, pPixel, *pBuffer++ );
ImVfbSRed(vfb, pPixel, *pBuffer++ );
ImVfbSAlpha(vfb, pPixel, *pBuffer++ );
ImVfbSInc(vfb, pPixel);
}
}
free ( (char *) buffer);
break;
}
return(1);
}
/*
* FUNCTION
* imReadTga_9and11 - read a Targa CLT or B&W file
*
* DESCRIPTION
* Reads in a type 9 or type 11 image with either 8 or 16 bits per pixel.
*
* type 9 - run-length-encoded color-lookup-table
* type 11 - run-length-encoded greyscale image
*/
static int /* Returns 1 on successful read */
#ifdef __STDC__
imReadTga_9and11 (int ioType,int fd,FILE* fp,ImVfb *vfb, int q,int h,int w)
#else
imReadTga_9and11 (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
{
ImVfbPtr pPixel; /*VFB pixel pointer */
int x,y; /* Counters */
unsigned char *buffer; /* Run buffer (type uchar) */
sdsc_uint16 *bufferl; /* Run buffer (type unsigned char) */
unsigned char *pBuffer; /* buffer pointer */
sdsc_uint16 *pBufferl; /* buffer pointer */
int total; /* Counter for number of bytes encode */
int count; /* Number of bytes to decode */
unsigned char rle; /* whether something is rle or not */
int field; /* red,green, or blue color */
unsigned char leadByte; /* Read in the lead byte */
total = h*w; /* a running count of bytes encode */
field = 0; /* Start with the red pixel */
pPixel = ImVfbQFirst(vfb);
switch (q)
{
case 8: /* one byte per pixel */
ImMalloc (buffer, unsigned char *, 129);
while (total>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,1) == -1)
{
free ( (char *)buffer);
ImReturnBinError();
}
pBuffer = buffer;
for (y=0; y<count; y++)
{
ImVfbSIndex8(vfb,pPixel,*pBuffer);
ImVfbSInc(vfb,pPixel);
}
}
else /* non rleencoded packet */
{
if (ImBinRead (ioType,fd,fp,buffer,UCHAR,1,count) == -1)
{
free ( (char *)buffer);
ImReturnBinError();
}
pBuffer = buffer;
for (y=0; y<count; y++)
{
ImVfbSIndex8(vfb,pPixel,*pBuffer++);
ImVfbSInc(vfb,pPixel);
}
}
total-=count;
}
free ( (char *)buffer);
break; /*break q=8*/
case 16: /* two bytes per pixel */
ImMalloc (bufferl, sdsc_uint16 *, 129* sizeof( sdsc_uint16));
while (total>0 ) {
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; y<count; y++)
{
ImVfbSIndex16(vfb,pPixel,*pBufferl);
ImVfbSInc (vfb, pPixel);
}
}
else /* non rleencoded packet */
{
if (ImBinRead (ioType,fd,fp,bufferl,UINT16,2,count) == -1)
{
free ( (sdsc_uint16 *)bufferl);
ImReturnBinError();
}
pBufferl = bufferl;
for (y=0; y<count; y++)
{
ImVfbSIndex16(vfb,pPixel,*pBufferl++);
ImVfbSInc (vfb, pPixel);
}
}
total-=count;
}
free ( (sdsc_uint16 *)bufferl);
break; /*break q=16*/
}
return(1);
}
/*
* FUNCTION
* imReadTga_10 - write a Targa RGB file
*
* DESCRIPTION
* type 10 - RGB RLE encoded image with 2, 3 or 4 bytes per pixel.
*/
static int /* Returns 1 on successful read */
#ifdef __STDC__
imReadTga_10 (int ioType,int fd,FILE* fp,ImVfb *vfb, int q,int h,int w)
#else
imReadTga_10 (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
{
ImVfbPtr pPixel; /*VFB pixel pointer */
int x,y; /* Counters */
unsigned char *buffer; /* Run buffer (type uchar) */
unsigned char *pBuffer; /* buffer pointer */
int total; /* Counter for number of bytes encode */
int count; /* Number of bytes to decode */
unsigned char rle; /* whether something is rle or not */
int field; /* red,green, or blue color */
unsigned char leadByte; /* Read in the lead byte */
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;
BinByteOrder (BINLBF);
field =0; /* Start with the red pixel */
pPixel = ImVfbQFirst(vfb);
switch (q)
{
case 16: /*three bits per pixel */
ImMalloc (buffer, unsigned char *, 260);
total=h*w; /* a running count of bytes decode */
while (total>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,2) == -1)
{
free ( (char *)buffer);
ImReturnBinError();
}
pBuffer = buffer;
for (y=0; y<count; y++)
{
imTga2ByteExpand_PIX(*pBuffer,*(pBuffer+1),pPixel,vfb);
ImVfbSInc(vfb,pPixel);
}
}
else /* non rleencoded packet */
{
if (ImBinRead (ioType,fd,fp,buffer,UCHAR,1,count*2) == -1)
{
free ( (char *)buffer);
ImReturnBinError();
}
pBuffer = buffer;
for (y=0; y<count; y++)
{
imTga2ByteExpand_PIX(*pBuffer,*(pBuffer+1),pPixel,vfb);
pBuffer+=2;
ImVfbSInc(vfb,pPixel);
}
}
total-=count;
}
free ( (char *)buffer);
break; /* end case q=24 */
case 24: /*three bits per pixel */
ImMalloc (buffer, unsigned char *, 390);
total=h*w*1; /* a running count of bytes decode */
while (total >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,3) == -1)
{
free ( (char *)buffer);
ImReturnBinError();
}
pBuffer = buffer;
for (y=0; y<count; y++)
{
ImVfbSBlue (vfb,pPixel,*(pBuffer));
ImVfbSGreen(vfb,pPixel,*(pBuffer+1));
ImVfbSRed (vfb,pPixel,*(pBuffer+2));
ImVfbSInc (vfb,pPixel);
}
}
else /* non rleencoded packet */
{
if (ImBinRead (ioType,fd,fp,buffer,UCHAR,1,count*3) == -1)
{
free ( (char *)buffer);
ImReturnBinError();
}
pBuffer = buffer;
for (y=0; y<count; y++)
{
ImVfbSBlue (vfb,pPixel,*pBuffer++);
ImVfbSGreen(vfb,pPixel,*pBuffer++);
ImVfbSRed (vfb,pPixel,*pBuffer++);
ImVfbSInc (vfb,pPixel);
}
}
total-=count;
}
free ( (char *)buffer);
break; /* end case q=24 */
case 32: /* four bits per pixel */
ImMalloc (buffer, unsigned char *, 520);
total=h*w*1; /* a running count of bytes decode */
while (total > 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<count; y++)
{
ImVfbSBlue (vfb,pPixel,*(pBuffer));
ImVfbSGreen(vfb,pPixel,*(pBuffer+1));
ImVfbSRed (vfb,pPixel,*(pBuffer+2));
ImVfbSAlpha(vfb,pPixel,*(pBuffer+3));
ImVfbSInc (vfb,pPixel);
}
}
else /* non rleencoded packet */
{
if (ImBinRead (ioType,fd,fp,buffer,UCHAR,1,count*4) == -1)
{
free ( (char *)buffer);
ImReturnBinError();
}
pBuffer = buffer;
for (y=0; y<count; y++)
{
ImVfbSBlue (vfb,pPixel,*pBuffer++);
ImVfbSGreen(vfb,pPixel,*pBuffer++);
ImVfbSRed (vfb,pPixel,*pBuffer++);
ImVfbSAlpha(vfb,pPixel,*pBuffer++);
ImVfbSInc (vfb,pPixel);
}
}
total-=count;
}
free ( (char *)buffer);
break; /* end case q=32 */
} /* end switch q */
return(1);
}
/*
* MACROS
* imTgaDumpVarRun
*
* imTgaDumpConstantRun1
* imTgaDumpConstantRun3
* imTgaDumpConstantRun4
*
* DESCRIPTION
* These are used for RLE encoding.
*
* imTgaDumpVarRun will write out a variable run. That is,
* a stream of pixel values with no two consecutive values
* that are the same. (i.e. A B C D E)
*
* imTgaDumpConstantRun3 will write out a stream of
* pixels with the same value. (i.e. A A A A A)
*
* The integers at the end of these functions' names indicate
* the number of bytes per pixel.
*/
static unsigned char imTgaRLEBuf[10]; /* Buffer for these macros */
#define imTgaDumpVarRun(bytesPerPixel, buffer, len) \
imTgaRLEBuf[0] = (unsigned char) len; \
imTgaRLEBuf[0] &= 0x7f; \
if ( ImBinWrite( ioType, fd, fp, imTgaRLEBuf, UCHAR, 1, 1)==-1) \
{ \
ImReturnBinError( ); \
} \
if ( ImBinWrite( ioType, fd, fp, buffer, UCHAR, 1, bytesPerPixel * (len+1))==-1) \
{ \
ImReturnBinError( ); \
}
#define imTgaDumpConstantRun1(index,len) \
imTgaRLEBuf[0] = (unsigned char) len; \
imTgaRLEBuf[0] |= 0x80; \
imTgaRLEBuf[1] = index; \
if ( ImBinWrite( ioType, fd, fp, imTgaRLEBuf, UCHAR, 1, 2)==-1) \
{ \
ImReturnBinError( ); \
}
#define imTgaDumpConstantRun2(index16,len) \
imTgaRLEBuf[0] = (unsigned char) len; \
imTgaRLEBuf[0] |= 0x80; \
imTgaRLEBuf[1] = (index16 & 0xff00) >> 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<y; j++)
{
pBuffer = buffer;
for (i=0; i<x; i++)
{
*pBuffer++ = ImVfbQBlue (vfb, pptr);
*pBuffer++ = ImVfbQGreen (vfb, pptr);
*pBuffer++ = ImVfbQRed (vfb, pptr);
ImVfbSInc (vfb, pptr);
}
if (ImBinWrite (ioType, fd, fp, buffer, UCHAR,1,pBuffer - buffer) ==-1)
{
free ( (char *)buffer);
ImReturnBinError( );
}
}
free ( (char *)buffer);
return (1);
}
/*
* FUNCTION
* imTgaWriteRGBRLE24 - write a Targa RGB file that 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__
imTgaWriteRGBRLE24( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable)
#else
imTgaWriteRGBRLE24( 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 vfbptr; /* Pixel pointer */
imTgaHeaderInfo header; /* Tga file header */
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*3]; /* 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".
*/
BinByteOrder (BINLBF);
TagEntryQValue (TagTableQDirect (tagTable, "image vfb", 0), &vfb);
/* Set up and write out the header */
stype = IMTGA_RLERGB;
spix = 24;
cmsize = 24;
imTgaWriteHeader ( ioType, fd, fp,flagsTable, tagTable,stype,
spix,cmsize);
/* 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 (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<y; j++)
{
pBuffer = buffer;
for (i=0; i<x; i++)
{
*pBuffer++ = ImVfbQBlue (vfb, pptr);
*pBuffer++ = ImVfbQGreen (vfb, pptr);
*pBuffer++ = ImVfbQRed (vfb, pptr);
*pBuffer++ = ImVfbQAlpha (vfb, pptr);
ImVfbSInc (vfb, pptr);
}
if (ImBinWrite (ioType, fd, fp, buffer, UCHAR,1,pBuffer - buffer) ==-1)
{
free ( (char *)buffer);
ImReturnBinError( );
}
}
free ( (char *)buffer);
return (1);
}
/*
* FUNCTION
* imTgaWriteRGBRLE32 - write a Targa RGBA file that 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__
imTgaWriteRGBRLE32( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable)
#else
imTgaWriteRGBRLE32( 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 */
TagEntry *tagEntry; /* Tmp table entry */
int stype; /* Stoage type */
int spix; /* Numer of bits per image pixel */
int cmsize; /* Numberof bits per color map pixel*/
unsigned char varRun[128*4]; /* 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 */
/* Set up and write out the header */
BinByteOrder (BINLBF);
TagEntryQValue (TagTableQDirect (tagTable, "image vfb", 0), &vfb);
stype = IMTGA_RLERGB;
spix = 32;
cmsize = 24;
/* Write out the header. */
imTgaWriteHeader ( ioType, fd, fp,flagsTable, tagTable,stype,
spix,cmsize);
/*
* 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".
*/
/* 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 (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<y; j++)
{
pBuffer = buffer;
for (i=0; i<x; i++)
{
*pBuffer++ = ImVfbQIndex8 (vfb, pptr);
ImVfbSInc (vfb, pptr);
}
if (ImBinWrite (ioType, fd, fp, buffer, UCHAR,1,pBuffer - buffer) ==-1)
{
free ( (char *)buffer);
ImReturnBinError( );
}
}
free ( (char *)buffer);
return (1);
}
/*
* FUNCTION
* imTgaWriteCLTRLE8 - write a Targa CLT file that has 8 bits pre 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__
imTgaWriteCLTRLE8( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable)
#else
imTgaWriteCLTRLE8( 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 */
stype = IMTGA_RLECOLORMAP;
spix = 8;
cmsize = 24;
BinByteOrder (BINLBF);
/* write the header out */
imTgaWriteHeader ( ioType, fd, fp,flagsTable, tagTable,stype,spix,cmsize);
imTgaWriteRLE8 ( ioType, fd, fp,flagsTable, tagTable);
return(1);
}
/*
* FUNCTION
* imTgaWriteRLE8 - write a Targa CLT file that has 8 bits per 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__
imTgaWriteRLE8( int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable )
#else
imTgaWriteRLE8( 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 */
imTgaHeaderInfo header; /* Tga file header */
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*1]; /* 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 (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<y; j++)
{
pBufferl = bufferl;
for (i=0; i<x; i++)
{
*pBufferl++ = (ImVfbQIndex16 (vfb, pptr) & 0xff) ;
*pBufferl++ = (ImVfbQIndex16 (vfb, pptr) & 0xff00) >> 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<y; j++)
{
pBuffer = buffer;
for (i=0; i<x; i++)
{
byte2 = ((ImVfbQAlpha (vfb, pptr))) << 7;
expRed= ((ImVfbQRed (vfb, pptr))>>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<header.tga_cmlen; j++)
{
*pBuffer++ = ImCltQBlue ( pColor);
*pBuffer++ = ImCltQGreen( pColor);
*pBuffer++ = ImCltQRed ( pColor);
ImCltSInc(clt, pColor);
}
if (ImBinWrite (ioType, fd, fp, buffer, UCHAR,1,pBuffer - buffer) ==-1)
{
free ( (char *)buffer);
ImReturnBinError( );
}
free ( (char *)buffer);
}
return(1);
}