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

1704 lines
26 KiB
C

/**
** $Header: /roq/libim/impix.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/impix.c 1 11/02/99 4:38p Zaphod $"
/**
** FILE
** impix.c - Alias PIX file I/O
**
** PROJECT
** libim - SDSC image manipulation library
**
** DESCRIPTION
** impix.c contains routines to read and write Alias PIX 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
** imPixRead f read an Alias PIX file
** imPixWrite f write an Alias PIX file
**
** imPixHeaderInfo t PIX file header information
** imPixHeaderFields v imPixHeaderInfo description for Bin pkg
**
** HISTORY
** $Log: /roq/libim/impix.c $
*
* 1 11/02/99 4:38p Zaphod
** Revision 1.26 1995/06/29 00:28:04 bduggan
** updated copyright year
**
** Revision 1.25 1995/04/03 21:34:19 bduggan
** took out #ifdef NEWMAGIC
**
** Revision 1.24 1995/02/16 21:41:24 bduggan
** Added support for Matte (index8) files
**
** Revision 1.23 1995/01/16 22:53:39 bduggan
** fixed spacing in code
**
** Revision 1.22 1995/01/10 23:39:57 bduggan
** put in IMMULTI, IMPIPE instead of TRUE/FALSE
** made read/write routines static
**
** Revision 1.21 94/10/03 11:30:43 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.20 93/09/22 11:41:23 nadeau
** Corrected spelling error in message.
**
** Revision 1.19 92/12/03 01:51:14 nadeau
** Corrected info messages.
** .,
**
** Revision 1.18 92/11/23 18:43:02 nadeau
** Removed use of IMINFOMSG.
**
** Revision 1.17 92/11/04 12:05:30 groening
** put ImFIleFormat info and magic number info
** from imfmt.c into this file.
**
** Revision 1.16 92/10/16 11:41:07 groening
** added ImInfo statements
**
** Revision 1.15 92/08/31 17:32:34 vle
** Updated copyright notice.
**
** Revision 1.14 91/10/04 10:52:01 nadeau
** Fixed VAX bit shift problem.
**
** Revision 1.13 91/10/03 09:15:50 nadeau
** Fixed #includes.
**
** Revision 1.12 91/03/08 14:31:04 nadeau
** Ooops! Forget to get the VFB before trying to write it out!
** Major core dump time.
**
** Revision 1.11 91/02/12 10:52:58 nadeau
** Removed the tag table checking and VFB conversion now
** handled by ImFileRead and ImFileWrite.
**
** Revision 1.10 90/12/03 12:47:39 nadeau
** Fixed read bug that would cause memory to be overwritten if
** the number of bytes in the file was not a multiple of 4 (ie,
** there were extra bytes at the end).
**
** Revision 1.9 90/07/02 13:21:02 nadeau
** Updated to the new error handling mechanism.
**
** Revision 1.8 90/06/25 14:40:57 nadeau
** Changed ImTag* to Tag* (new names).
**
** Revision 1.7 90/06/25 13:20:54 todd
** Fixed a few little bugs.
**
** Revision 1.6 90/05/16 07:46:32 todd
** Move some macros into new include file iminternal.h for shared use
**
** Revision 1.5 90/05/11 09:55:19 nadeau
** Updated call interface to handle file descriptors and file pointers.
** Updated code to watch for both of these and make the correct bin pkg
** call.
**
** Revision 1.4 90/04/05 17:07:21 todd
** Take out code that checks if input is a pipe. BinRead as much as
** possible. numbytes_read/4 is the number of runs.
** Change pixel arrays from ints to arrays of unsigned chars for portability.
**
** Revision 1.3 90/03/29 08:29:28 todd
** Changed some ints to unsigned ints. PIX Read and Write routines seem
** to work fine.
**
** Revision 1.2 90/03/28 11:13:53 nadeau
** Lots of fiddling and bug fixing. Still doesn't work, but Todd
** has graciously volunteered to work on it now!
**
** Revision 1.1 90/03/06 17:32:24 nadeau
** Initial revision
**
**/
#include "iminternal.h"
/*
**
**
** FORMAT
**
** PIX - Alias Pixel file
**
** AKA
** .alias
**
** FORMAT REFERENCES
** Alias Reference Manual, Alias Research, Inc.
**
** CODE CREDITS
** Custom development, Dave Nadeau, San Diego Supercomputer Center, 1990.
** Custom development, Todd Elvins, San Diego Supercomputer Center, 1990.
**
** DESCRIPTION
** Alias' pix file has a 10-byte header followed by run-length-encoded
** image data.
**
** Header
** ======
**
** The header for a pix file has the following information:
**
** bytes: description:
** ------ -------------
** 0,1 width (x resolution in pixels)
** 2,3 height (y resolution in pixels)
** 4,5 xoffset (unused)
** 6,7 yoffset (unused)
** 8,9 bits per pixel:
** 0x18 for pix files
** 0x08 for matte files (greyscale)
**
** Encoding of Pixel Data
** ======================
**
** The pixels are encoded in 4-byte packages, starting with the top
** scanline. Runs do not extend beyond the end of a scanline. The
** packages have the following format:
**
** byte: data range: description
** ----- ----------- -----------
** 1 1-255 runlength (number of pixels in
** succession with given RGB)
** 2 0-255 blue (value of blue component)
** 3 0-255 green (green component)
** 4 0-255 red (red component)
**
** Example
** =======
** Here is the hex of a file that is 8 pixels wide and 6 pixels high,
** representing a ramp that goes from black at the bottom of the image to
** blue at the top:
**
** 0008 0006 0000 0005 0018 08ff 0000 08cc
** 0000 0899 0000 0866 0000 0833 0000 0000
** 0000
**
** The header is 0008 0006 0000 0005 0018
** The first line is a run of eight pixels of B=0xff (255), G=0, R=0,
** The second line is a run of eight pixels of B=0xcc (204), G=0, R=0
** etc...
**
**
**
**/
#ifdef __STDC__
static int imPixRead( int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable );
static int imPixWrite( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable );
static int imPixReadIndex8( int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable, int x, int y );
static int imPixWriteIndex8( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable
);
#else
static int imPixRead( );
static int imPixWrite( );
static int imPixReadIndex8( );
static int imPixWriteIndex8( );
#endif
static char *imPixNames[ ] = { "pix", "alias", NULL };
static ImFileFormatReadMap imPixReadMap[ ] =
{
/* in out */
/* type,ch,dep, attr. VFB type attr. */
{ IMVFBRGB,3,8, RLE, IMVFBRGB, 0 },
{ IMVFBINDEX8,1,8, RLE, IMVFBRGB, 0 },
{ -1, 0, -1, 0 },
};
static ImFileFormatWriteMap imPixWriteMap[ ] =
{
/* in out */
/* VFB type, attr., type,ch,dep, attr., func */
{ IMVFBRGB, 0, RGB,3,8, RLE, imPixWrite },
{ IMVFBINDEX8, 0, IN,1,8, RLE, imPixWriteIndex8 },
{ -1, 0, -1, 0, NULL },
};
static ImFileMagic imFilePixMagic []=
{
{ 0, 0, NULL},
};
ImFileFormat ImFilePixFormat =
{
imPixNames, "Alias image file",
"Alias Research, Inc.",
"24-bit RGB RLE-compressed images, 8-bit greyscale RLE_compressed images",
"24-bit RGB RLE-compressed images, 8-bit greyscale RLE_compressed images",
imFilePixMagic,
IMNOMULTI, IMPIPE,
IMNOMULTI, IMPIPE,
imPixRead, imPixReadMap, imPixWriteMap
};
/*
* TYPEDEF & STRUCTURE
* imPixHeaderInfo - PIX file header information
* imPixHeaderFields - PIX file header fields for binary pkg.
*
* DESCRIPTION
* A PIX file's header contains the image's width, height, and depth,
* and two unused dummy fields.
*/
typedef struct imPixHeaderInfo
{
short pix_width; /* Image width */
short pix_height; /* Image height */
short pix_dummy1; /* Unused dummy field */
short pix_dummy2; /* Unused dummy field */
short pix_depth; /* Image depth */
} imPixHeaderInfo;
static BinField imPixHeaderFields[ ] =
{
{ SHORT, 2, 1 }, /* pix_width */
{ SHORT, 2, 1 }, /* pix_height */
{ SHORT, 2, 1 }, /* pix_dummy1 */
{ SHORT, 2, 1 }, /* pix_dummy1 */
{ SHORT, 2, 1 }, /* pix_depth */
{ 0, 0, 0 }
};
/*
* FUNCTION
* imPixRead - read an Alias PIX file
*
* DESCRIPTION
* The file header is read and the size of the image determined.
* Space is allocated for the VFB and the run codes read in to
* a run buffer. The run buffer is then expanded into straight
* RGB values in the VFB and the completed VFB added to the tag list.
*/
static int /* Returns # tags read in */
#ifdef __STDC__
imPixRead( int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable )
#else
imPixRead( ioType, fd, fp, flagsTable, tagTable )
int ioType; /* I/O flags */
int fd; /* Input file descriptor */
FILE *fp; /* Input file pointer */
TagTable *flagsTable; /* Flags */
TagTable *tagTable; /* Tag table to add to */
#endif
{
ImVfb *vfb; /* Read in image */
ImVfbPtr pptr; /* Pixel pointer */
imPixHeaderInfo header; /* PIX file header */
unsigned char *runBuffer; /* Run buffer */
unsigned char *rbp; /* Run buffer pointer */
unsigned char r, g, b; /* Red, green, and blue */
long seekPtr; /* File seek pointer */
int nRead; /* Number of pixel runs */
int x,y; /* Convenient short names */
unsigned int count; /* Run length */
char message[100]; /* ImInfo message */
/*
* PIX files are usually generated on Irises, which have an MBF
* byte order. There is no floating point in the file so we
* won't bother setting the float format for BIN.
*/
BinByteOrder( BINMBF );
ImInfo ("Byte Order","Most Significant Byte First");
/*
* Read in the header.
*/
if ( ImBinReadStruct( ioType, fd, fp, &header, imPixHeaderFields )== -1)
{
ImReturnBinError( );
}
x = header.pix_width;
y = header.pix_height;
if (header.pix_depth==0x08)
{ /* Greyscale image */
return imPixReadIndex8(ioType, fd, fp, flagsTable, tagTable, x, y);
}
sprintf (message, "%d x %d", x,y);
ImInfo ("Resolution", message);
ImInfo ( "Type", "24-bit RGB");
ImInfo ( "Compression Type", "Run Length Encoded (RLE)");
/*
* Allocate a VFB of the required size.
*/
if ( (vfb = ImVfbAlloc( x, y, IMVFBRGB )) == IMVFBNULL )
{
ImErrorFatal( ImQError( ), -1, ImErrNo );
}
/*
* Allocate a run buffer large enough for the worst case run
* length encoding.
*/
ImMalloc( runBuffer, unsigned char *, 4 * x * y );
/*
* Read the entire image into the run buffer. The number of bytes
* read divided by 4 is the number of runs.
*/
if ( (nRead = ImBinRead( ioType, fd, fp, runBuffer, UCHAR, 1, 4*x*y )) == -1 )
{
free( (char *)runBuffer );
ImReturnBinError( );
}
/*
* Expand the runs to create a raw RGB image in the VFB.
*/
pptr = ImVfbQFirst( vfb );
for ( rbp = runBuffer; nRead > 3; nRead-=4, rbp+=4 )
{
r = *(rbp+3);
g = *(rbp+2);
b = *(rbp+1);
for ( count = *rbp; count > 0; count-- )
{
ImVfbSRed( vfb, pptr, r );
ImVfbSGreen( vfb, pptr, g );
ImVfbSBlue( vfb, pptr, b );
ImVfbSInc( vfb, pptr );
}
}
free( (char *)runBuffer );
/*
* Add the VFB to the tagTable.
*/
TagTableAppend( tagTable, TagEntryAlloc( "image vfb", POINTER, &vfb ) );
return ( 1 );
}
/*
* FUNCTION
* imPixWrite - write an Alias PIX file
*
* DESCRIPTION
* The PIX file header set up and written out. The VFB data is then
* read, converted to run-codes, and written out.
*/
static int /* Returns # of tags used */
#ifdef __STDC__
imPixWrite( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable )
#else
imPixWrite( 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 */
imPixHeaderInfo header; /* PIX file header */
unsigned char *runBuffer; /* Run buffer */
unsigned char *rbp; /* Run buffer pointer */
unsigned int count; /* Run length */
int nRuns; /* Number of pixel runs */
int n; /* Counter */
int x, y; /* Pixel counters */
int rgb; /* New rgb value */
int oldrgb; /* Old rgb value */
char message[100]; /* ImInfo message */
/*
* PIX files are usually generated on Irises, which have an MBF
* byte order. There is no floating point in the file so we
* won't bother setting the float format for BIN.
*/
BinByteOrder( BINMBF );
/*
* Set up the header and write it out.
*/
TagEntryQValue( TagTableQDirect( tagTable, "image vfb", 0 ), &vfb );
header.pix_width = ImVfbQWidth( vfb );
header.pix_height = ImVfbQHeight( vfb );
header.pix_dummy1 = 0;
header.pix_dummy2 = header.pix_height - 1;
header.pix_depth = 24;
if ( ImBinWriteStruct( ioType, fd, fp, &header, imPixHeaderFields )==-1)
{
ImReturnBinError( );
}
sprintf (message, "%d x %d", header.pix_width, header.pix_height);
ImInfo ("Resolution", message);
ImInfo ( "Type", "24-bit RGB");
ImInfo ( "Compression Type", "Run Length Encoded (RLE)");
/*
* Allocate space for a run buffer large enough for 1 unencoded
* scanline. An encoded scanline will be smaller.
*/
if ( (runBuffer = (unsigned char *)malloc( 4 * header.pix_width )) == NULL )
{
ImErrNo = IMEMALLOC;
ImErrorFatal( ImQError( ), -1, IMEMALLOC );
}
/*
* Run-length encode the VFB. In PIX files, run's always stop
* at the end of a scanline, even if the start of the next scanline
* is the same color.
*/
pptr = ImVfbQFirst( vfb );
for ( y = 0; y < header.pix_height; y++ )
{
rbp = runBuffer;
nRuns = 0;
oldrgb = (((unsigned int)ImVfbQBlue( vfb, pptr )) << 16) |
(((unsigned int)ImVfbQGreen( vfb, pptr )) << 8) |
(unsigned int)ImVfbQRed( vfb, pptr );
ImVfbSInc( vfb, pptr );
count = 1;
for ( x = 1; x < header.pix_width; x++ )
{
rgb = (((unsigned int)ImVfbQBlue( vfb, pptr )) << 16) |
(((unsigned int)ImVfbQGreen( vfb, pptr )) << 8) |
(unsigned int)ImVfbQRed( vfb, pptr );
ImVfbSInc( vfb, pptr );
if ( rgb == oldrgb )
{
/* Add 1 to the run. */
if ( ++count == 255 )
{
/* Overflow 1 byte. Dump run. */
*rbp++ = 255;
*rbp++ = (oldrgb >> 16) & 0xFF;
*rbp++ = (oldrgb >> 8) & 0xFF;
*rbp++ = (oldrgb) & 0xFF;
nRuns++;
count = 0;
}
}
else
{
/* Different color. Dump run. */
if ( count != 0 )
{
*rbp++ = count;
*rbp++ = (oldrgb >> 16) & 0xFF;
*rbp++ = (oldrgb >> 8) & 0xFF;
*rbp++ = (oldrgb) & 0xFF;
nRuns++;
}
count = 1;
oldrgb = rgb;
}
}
if ( count != 0 )
{
*rbp++ = count;
*rbp++ = (oldrgb >> 16) & 0xFF;
*rbp++ = (oldrgb >> 8) & 0xFF;
*rbp++ = (oldrgb) & 0xFF;
nRuns++;
}
/*
* Write out the run buffer.
*/
if ( ImBinWrite( ioType, fd, fp, runBuffer, UCHAR, 1, nRuns * 4 ) == -1 )
{
free( (char *)runBuffer );
ImReturnBinError( );
}
}
/*
* Add a terminating run with a count of 0 and write it out.
*/
*runBuffer = 0; /* Terminate the runs */
if ( ImBinWrite( ioType, fd, fp, runBuffer, UCHAR, 1, 4 ) == -1 )
{
free( (char *)runBuffer );
ImReturnBinError( );
}
free( (char *)runBuffer );
return ( 1 );
}
/*
* FUNCTION
* imPixReadIndex8 - read an Alias PIX file
*
* DESCRIPTION
* The file header has been read and the size of the image has
* been determined by imPixRead.
* Here, space is allocated for the VFB and the run codes read in to
* a run buffer. The run buffer is then expanded into straight
* greyscale values in the VFB and the completed VFB added to the tag list.
*/
static int /* Returns # tags read in */
#ifdef __STDC__
imPixReadIndex8( int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable, int x, int y )
#else
imPixReadIndex8( ioType, fd, fp, flagsTable, tagTable, x, y )
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 */
int x; /* Dimensions of the image */
int y;
#endif
{
ImVfb *vfb; /* Read in image */
ImVfbPtr pptr; /* Pixel pointer */
unsigned char *runBuffer; /* Run buffer */
unsigned char *rbp; /* Run buffer pointer */
unsigned char g; /* Gray value */
long seekPtr; /* File seek pointer */
int nRead; /* Number of bytes read */
unsigned int count; /* Run length */
char message[100];/* ImInfo message */
/* The byte order has been set already by imReadPix */
sprintf (message, "%d x %d", x,y);
ImInfo ("Resolution", message);
ImInfo ( "Type", "8-bit Grayscale");
ImInfo ( "Compression Type", "Run Length Encoded (RLE)");
/*
* Allocate a VFB of the required size.
*/
if ( (vfb = ImVfbAlloc( x, y, IMVFBINDEX8 )) == IMVFBNULL )
{
ImErrorFatal( ImQError( ), -1, ImErrNo );
}
/*
* Allocate a run buffer large enough for the worst case run
* length encoding.
*/
ImMalloc( runBuffer, unsigned char *, 2 * x * y );
/*
* Read the entire image into the run buffer. The number of bytes
* read divided by 2 is the number of runs.
*/
if ( (nRead = ImBinRead( ioType, fd, fp, runBuffer, UCHAR, 1, 2*x*y )) == -1 )
{
free( (char *)runBuffer );
ImReturnBinError( );
}
/*
* Expand the runs to create a grayscale image in the VFB.
*/
pptr = ImVfbQFirst( vfb );
for ( rbp = runBuffer; nRead > 1; nRead-=2, rbp+=2 )
{
g = *(rbp+1);
for ( count = *rbp; count > 0; count-- )
{
ImVfbSIndex8(vfb, pptr, g );
ImVfbSInc( vfb, pptr );
}
}
free( (char *)runBuffer );
/*
* Add the VFB to the tagTable.
*/
TagTableAppend( tagTable, TagEntryAlloc( "image vfb", POINTER, &vfb ) );
return ( 1 );
}
/*
* FUNCTION
* imPixWriteIndex8 - write an Alias PIX file
*
* DESCRIPTION
* The Matte file header set up and written out. The VFB data is then
* read, converted to run-codes, and written out.
*/
static int /* Returns # of tags used */
#ifdef __STDC__
imPixWriteIndex8( ImFileFormatWriteMap *pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable )
#else
imPixWriteIndex8( 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 */
imPixHeaderInfo header; /* PIX file header */
unsigned char *runBuffer; /* Run buffer */
unsigned char *rbp; /* Run buffer pointer */
unsigned int count; /* Run length */
int nRuns; /* Number of pixel runs */
int n; /* Counter */
int x, y; /* Pixel counters */
int grey; /* New greyscale value */
unsigned char oldgrey; /* Old greyscale value */
char message[100]; /* ImInfo message */
/*
* PIX files are usually generated on Irises, which have an MBF
* byte order. There is no floating point in the file so we
* won't bother setting the float format for BIN.
*/
BinByteOrder( BINMBF );
/*
* Set up the header and write it out.
*/
TagEntryQValue( TagTableQDirect( tagTable, "image vfb", 0 ), &vfb );
header.pix_width = ImVfbQWidth( vfb );
header.pix_height = ImVfbQHeight( vfb );
header.pix_dummy1 = 0;
header.pix_dummy2 = header.pix_height - 1;
header.pix_depth = 8;
if ( ImBinWriteStruct( ioType, fd, fp, &header, imPixHeaderFields )==-1)
{
ImReturnBinError( );
}
sprintf (message, "%d x %d", header.pix_width, header.pix_height);
ImInfo ("Resolution", message);
ImInfo ( "Type", "8-bit Grayscale");
ImInfo ( "Compression Type", "Run Length Encoded (RLE)");
/*
* Allocate space for a run buffer large enough for 1 unencoded
* scanline. An encoded scanline will be smaller.
*/
ImMalloc( runBuffer, unsigned char *, 2 * header.pix_width);
/*
* Run-length encode the VFB. In Matte files, runs always stop
* at the end of a scanline, even if the start of the next scanline
* is the same color.
*/
pptr = ImVfbQFirst( vfb );
for ( y = 0; y < header.pix_height; y++ )
{
rbp = runBuffer;
nRuns = 0;
oldgrey = ImVfbQIndex8( vfb, pptr);
ImVfbSInc( vfb, pptr );
count = 1;
for ( x = 1; x < header.pix_width; x++ )
{
grey = ImVfbQIndex8( vfb, pptr );
ImVfbSInc( vfb, pptr );
if ( grey == oldgrey )
{
/* Add 1 to the run. */
if ( ++count == 255 )
{
/* Overflow 1 byte. Dump run. */
*rbp++ = 255;
*rbp++ = oldgrey;
nRuns++;
count = 0;
}
}
else
{
/* Different color. Dump run. */
if ( count != 0 )
{
*rbp++ = count;
*rbp++ = oldgrey;
nRuns++;
}
count = 1;
oldgrey = grey;
}
}
if ( count != 0 )
{
*rbp++ = count;
*rbp++ = oldgrey;
nRuns++;
}
/*
* Write out the run buffer.
*/
if ( ImBinWrite( ioType, fd, fp, runBuffer, UCHAR, 1, nRuns * 2 ) == -1 )
{
free( (char *)runBuffer );
ImReturnBinError( );
}
}
/*
* Add a terminating run with a count of 0 and write it out.
*/
*runBuffer = 0; /* Terminate the runs */
if ( ImBinWrite( ioType, fd, fp, runBuffer, UCHAR, 1, 2 ) == -1 )
{
free( (char *)runBuffer );
ImReturnBinError( );
}
free( (char *)runBuffer );
return ( 1 );
}