2383 lines
38 KiB
C
2383 lines
38 KiB
C
/**
|
|
|
|
** $Header: /roq/libim/impbm.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/impbm.c 1 11/02/99 4:38p Zaphod $"
|
|
|
|
|
|
|
|
/**
|
|
|
|
** FILE
|
|
|
|
** impbm.c - I/O for Jef Poskanzer's PBM file formats
|
|
|
|
**
|
|
|
|
** PROJECT
|
|
|
|
** libim - SDSC image manipulation library
|
|
|
|
**
|
|
|
|
** DESCRIPTION
|
|
|
|
** impbm.c contains routines to read and write the various PBM suite
|
|
|
|
** 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
|
|
|
|
**
|
|
|
|
** imPbmRead f read a PBM file
|
|
|
|
**
|
|
|
|
** imPbmWrite1 f write a 1-bit ASCII PBM file
|
|
|
|
** imPbmWrite8 f write an 8-bit ASCII PGM file
|
|
|
|
** imPbmWriteRGB f write an RGB ASCII PPM file
|
|
|
|
** imRpbmWrite1 f write an 1-bit raw PBM file
|
|
|
|
** imRpbmWrite8 f write an 8-bit raw PGM file
|
|
|
|
** imRpbmWriteRGB f write an RGB raw PPM file
|
|
|
|
**
|
|
|
|
** readAsciiInt f read in an ASCII string integer
|
|
|
|
**
|
|
|
|
** HISTORY
|
|
|
|
** $Log: /roq/libim/impbm.c $
|
|
*
|
|
* 1 11/02/99 4:38p Zaphod
|
|
|
|
** Revision 1.15 1995/06/29 00:28:04 bduggan
|
|
|
|
** updated copyright year
|
|
|
|
**
|
|
|
|
** Revision 1.14 1995/06/15 20:34:11 bduggan
|
|
|
|
** added casts for strlen
|
|
|
|
**
|
|
|
|
** Revision 1.13 1995/05/17 23:46:16 bduggan
|
|
|
|
** Merged everything into one format, with an ascii compression option
|
|
|
|
**
|
|
|
|
** Revision 1.12 1995/04/03 21:32:07 bduggan
|
|
|
|
** took out #ifdef NEWMAGIC
|
|
|
|
**
|
|
|
|
** Revision 1.11 1995/01/10 23:35:34 bduggan
|
|
|
|
** uncapitlized i's in local functions
|
|
|
|
** made read/write routines static
|
|
|
|
**
|
|
|
|
** Revision 1.10 1994/10/03 11:30:19 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.10 1994/10/03 11:30:19 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.9 92/12/03 01:50:12 nadeau
|
|
|
|
** Corrected info messages.
|
|
|
|
**
|
|
|
|
** Revision 1.8 92/11/24 11:51:57 groening
|
|
|
|
** Removed use of IMINFOMSG and added file format table
|
|
|
|
** declarations and initializations.
|
|
|
|
**
|
|
|
|
** Revision 1.7 92/10/19 14:17:09 groening
|
|
|
|
** fixed bug on read mono
|
|
|
|
** added ImINfo statements
|
|
|
|
**
|
|
|
|
** Revision 1.6 92/08/31 17:29:10 vle
|
|
|
|
** Updated copyright notice.
|
|
|
|
**
|
|
|
|
** Revision 1.5 92/04/09 09:32:36 groening
|
|
|
|
** To make the compiler happy added extern statements.
|
|
|
|
**
|
|
|
|
** Revision 1.4 92/04/08 10:48:30 nadeau
|
|
|
|
** Fixed SGI ANSI cc complaints about passing unsigned char arrays
|
|
|
|
** as args to functions expecting char arrays. Big deal.
|
|
|
|
**
|
|
|
|
** Revision 1.3 91/10/03 09:14:47 nadeau
|
|
|
|
** Fixed #includes. Fixed monochrome write bug that
|
|
|
|
** inverted meaning of black and white.
|
|
|
|
**
|
|
|
|
** Revision 1.2 91/03/08 14:29:15 nadeau
|
|
|
|
** Nearly a total rewrite. Ran it all through 'indent', the UNIX
|
|
|
|
** C beautifier, just to make it readable. Rearranged. Restructured.
|
|
|
|
** Rewrote. Added comments. Removed meaningless ones. Added code
|
|
|
|
** to work with the latest enhancements to ImFileRead and ImFileWrite.
|
|
|
|
** Basically a total rewrite.
|
|
|
|
**
|
|
|
|
** Revision 1.1 91/01/18 15:40:34 doeringd
|
|
|
|
** Initial revision
|
|
|
|
**/
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include "iminternal.h"
|
|
|
|
|
|
|
|
/**
|
|
|
|
** FORMAT
|
|
|
|
** PBM - Jef Poskanzer's PBM file formats
|
|
|
|
**
|
|
|
|
** AKA
|
|
|
|
** rpbm,pgm,rpgm,ppm,rppm
|
|
|
|
**
|
|
|
|
** FORMAT REFERENCES
|
|
|
|
** Graphics File Formats, David C. Kay, John R. Levine
|
|
|
|
**
|
|
|
|
** CODE CREDITS
|
|
|
|
** Custom development, Donald Doering, San Diego Supercomputer Center, 1991.
|
|
|
|
** Custom development, Dave Nadeau, San Diego Supercomputer Center, 1991.
|
|
|
|
**
|
|
|
|
** DESCRIPTION
|
|
|
|
** The PBM suite really defines six (6) file formats:
|
|
|
|
**
|
|
|
|
** PBM ASCII Monochrome bitmap
|
|
|
|
** PGM ASCII Grayscale pixel map
|
|
|
|
** PPM ASCII Color pixel map
|
|
|
|
**
|
|
|
|
** RPBM Raw Monochrome bitmap
|
|
|
|
** RPGM Raw Grayscale pixel map
|
|
|
|
** RPPM Raw Color pixel map
|
|
|
|
**
|
|
|
|
** The ASCII formats store the image as ASCII, human-readable files,
|
|
|
|
** while the raw formats store them as raw binary files. Since the
|
|
|
|
** binary files are still only byte-based (8-bit grayscale, 8-bit per
|
|
|
|
** channel RGB), they are still portable (but a lot smaller and faster).
|
|
|
|
**
|
|
|
|
** All six formats start with a file header of the form:
|
|
|
|
**
|
|
|
|
** unsigned char magic1;
|
|
|
|
** unsigned char magic2;
|
|
|
|
** unsigned int width, height;
|
|
|
|
**
|
|
|
|
** magic1 is always a 'P'.
|
|
|
|
**
|
|
|
|
** magic2 selects which of the six formats:
|
|
|
|
**
|
|
|
|
** '1' PBM
|
|
|
|
** '2' PGM
|
|
|
|
** '3' PPM
|
|
|
|
** '4' RPBM
|
|
|
|
** '5' RPGM
|
|
|
|
** '6' RPPM
|
|
|
|
**
|
|
|
|
** width and height are the width and height of the image in pixels.
|
|
|
|
**
|
|
|
|
** For formats other than PBM and RPBM, the header also contains:
|
|
|
|
**
|
|
|
|
** unsigned int maxIntensity;
|
|
|
|
**
|
|
|
|
** maxIntensity is the highest value allowed for one channel of the
|
|
|
|
** image. For instance, for 8-bit grayscale, maxIntensity is 255.
|
|
|
|
** For 24-bit RGB images, maxIntensity is also 255 (8-bit channels).
|
|
|
|
**
|
|
|
|
** When reading images, incomming pixel values are scaled from the
|
|
|
|
** range 0-maxIntensity, up or down to the VFB 8-bit range 0-255.
|
|
|
|
**
|
|
|
|
** For monochrome PBM and RPBM files, 0 is white and 1 is black. This
|
|
|
|
** is the opposite of the image library's conventions. However, PGM,
|
|
|
|
** RPGM, PPM, and RPPM files all follow the convention that 0 is black,
|
|
|
|
** and 1 is brighter than black (255 is full intensity).
|
|
|
|
**
|
|
|
|
** NOTE: the header is always ASCII, including maxIntensity.
|
|
|
|
**
|
|
|
|
** ASCII FORMATS
|
|
|
|
** For the three ASCII formats, the rest of the file is filled with
|
|
|
|
** ASCII integer values separated by white space. Carriage returns,
|
|
|
|
** form feeds, spaces, and tabs are ignored. Comments starting with
|
|
|
|
** a '#' and extending to the end of the line are ignored.
|
|
|
|
**
|
|
|
|
** When we write ASCII formats, to make the format more readable,
|
|
|
|
** carriage returns are inserted after every 70 characters or so.
|
|
|
|
**
|
|
|
|
** BINARY FORMATS
|
|
|
|
** For the three "raw" binary formats, the rest of the file is filled
|
|
|
|
** with 8-bit values.
|
|
|
|
**/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* PBM - ASCII bitmap (monochrome)
|
|
|
|
* PGM - ASCII gray (grayscale)
|
|
|
|
* PNM - any ASCII format
|
|
|
|
* PPM - ASCII pixel (RGB color)
|
|
|
|
* RPBM - Raw bitmap (monochrome)
|
|
|
|
* RPGM - Raw gray (grayscale)
|
|
|
|
* RPNM - any Raw format
|
|
|
|
* RPPM - Raw pixel (RGB color)
|
|
|
|
*
|
|
|
|
* All 8 formats share the same read call. Some share the same write calls.
|
|
|
|
*/
|
|
|
|
#ifdef __STDC__
|
|
|
|
static int imPbmRead(int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable);
|
|
|
|
static int imPbmWrite1( ImFileFormatWriteMap * pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable );
|
|
|
|
static int imPbmWrite8( ImFileFormatWriteMap * pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable );
|
|
|
|
static int imPbmWriteRGB( ImFileFormatWriteMap * pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable );
|
|
|
|
static int imRpbmWrite1( ImFileFormatWriteMap * pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable );
|
|
|
|
static int imRpbmWrite8( ImFileFormatWriteMap * pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable );
|
|
|
|
static int imRpbmWriteRGB( ImFileFormatWriteMap * pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable );
|
|
|
|
#else
|
|
|
|
static int imPbmRead( );
|
|
|
|
static int imPbmWrite1( ), imPbmWrite8( ), imPbmWriteRGB( );
|
|
|
|
static int imRpbmWrite1( ), imRpbmWrite8( ), imRpbmWriteRGB( );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Magic constants
|
|
|
|
*/
|
|
|
|
#define IMPBM_MAGIC1 'P'
|
|
|
|
#define IMPBM_MAGIC2 '1'
|
|
|
|
#define IMPGM_MAGIC2 '2'
|
|
|
|
#define IMPPM_MAGIC2 '3'
|
|
|
|
#define IMRPBM_MAGIC2 '4'
|
|
|
|
#define IMRPGM_MAGIC2 '5'
|
|
|
|
#define IMRPPM_MAGIC2 '6'
|
|
|
|
|
|
|
|
|
|
|
|
static char *imPbmNames[ ] = { "pbm", "rpbm", "pgm", "rpgm", "pnm", "rpnm", "ppm", "rppm", NULL };
|
|
|
|
|
|
|
|
static unsigned char imPbmMagicNumber[ ] = { IMPBM_MAGIC1, IMPBM_MAGIC2 };
|
|
|
|
static unsigned char imRpbmMagicNumber[ ] = { IMPBM_MAGIC1, IMRPBM_MAGIC2 };
|
|
|
|
static unsigned char imPgmMagicNumber[ ] = { IMPBM_MAGIC1, IMPGM_MAGIC2 };
|
|
|
|
static unsigned char imRpgmMagicNumber[ ] = { IMPBM_MAGIC1, IMRPGM_MAGIC2 };
|
|
|
|
static unsigned char imPpmMagicNumber[ ] = { IMPBM_MAGIC1, IMPPM_MAGIC2 };
|
|
|
|
static unsigned char imRppmMagicNumber[ ] = { IMPBM_MAGIC1, IMRPPM_MAGIC2 };
|
|
|
|
|
|
|
|
|
|
|
|
static ImFileFormatReadMap imPbmReadMap[ ] =
|
|
|
|
{
|
|
|
|
/* in out */
|
|
|
|
/* type,ch,dep, attr. VFB type attr. */
|
|
|
|
{ IN,1,1, 0, IMVFBMONO, 0 },
|
|
|
|
{ IN,1,8, 0, IMVFBINDEX8, 0 },
|
|
|
|
{ RGB,3,8, 0, IMVFBRGB, 0 },
|
|
|
|
{ IN,1,1, ASC, IMVFBMONO, 0 },
|
|
|
|
{ IN,1,8, ASC, IMVFBINDEX8, 0 },
|
|
|
|
{ RGB,3,8, ASC, IMVFBRGB, 0 },
|
|
|
|
{ -1, 0, -1, 0 },
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static ImFileFormatWriteMap imPbmWriteMap[ ] =
|
|
|
|
{
|
|
|
|
/* in out */
|
|
|
|
/* VFB type, attr., type,ch,dep, attr., func */
|
|
|
|
{ IMVFBMONO, 0, IN,1,1, ASC, imPbmWrite1 },
|
|
|
|
{ IMVFBMONO, 0, IN,1,1, 0, imRpbmWrite1 },
|
|
|
|
{ IMVFBINDEX8, 0, IN,1,8, ASC, imPbmWrite8 },
|
|
|
|
{ IMVFBINDEX8, 0, IN,1,8, 0, imRpbmWrite8 },
|
|
|
|
{ IMVFBRGB, 0, RGB,3,8, ASC, imPbmWriteRGB },
|
|
|
|
{ IMVFBRGB, 0, RGB,3,8, 0, imRpbmWriteRGB },
|
|
|
|
{ -1, 0, -1, 0, NULL },
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static ImFileMagic imFilePbmMagic []=
|
|
|
|
{
|
|
|
|
{0, 2, imPbmMagicNumber },
|
|
|
|
{0, 2, imRpbmMagicNumber },
|
|
|
|
{0, 2, imPgmMagicNumber },
|
|
|
|
{0, 2, imRpgmMagicNumber },
|
|
|
|
{0, 2, imPpmMagicNumber },
|
|
|
|
{0, 2, imRppmMagicNumber },
|
|
|
|
{ 0, 0, NULL },
|
|
|
|
};
|
|
|
|
|
|
|
|
ImFileFormat ImFilePbmFormat =
|
|
|
|
{
|
|
|
|
imPbmNames, "PBM Portable Bit Map file",
|
|
|
|
"Jef Poskanzer",
|
|
|
|
"1-bit monochrome, 8-bit grayscale, 24-bit rgb, ascii encoded or binary",
|
|
|
|
"1-bit monochrome PBM images.",
|
|
|
|
imFilePbmMagic,
|
|
|
|
IMNOMULTI, IMPIPE,
|
|
|
|
IMNOMULTI, IMPIPE,
|
|
|
|
imPbmRead, imPbmReadMap, imPbmWriteMap
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __STDC__
|
|
|
|
static int skipEOL( int ioTyne, int fd, FILE *fp );
|
|
|
|
static int readAsciiInt( int ioType, int fd, FILE *fp, int *value );
|
|
|
|
#else
|
|
|
|
static int skipEOL( );
|
|
|
|
static int readAsciiInt();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#define IMWrite(ioType,fd,fp,buffer,size) \
|
|
((ioType&IMFILEIOFD) ? \
|
|
write( fd, buffer, size ) \
|
|
: \
|
|
fwrite( buffer, 1, size, fp ))
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* FUNCTION
|
|
|
|
* imPbmRead - read a PBM file
|
|
|
|
*
|
|
|
|
* DESCRIPTION
|
|
|
|
* The header is read in, followed by the image pixels in either
|
|
|
|
* ASCII or raw format.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int /* Returns status */
|
|
|
|
#ifdef __STDC__
|
|
|
|
imPbmRead(int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable)
|
|
|
|
#else
|
|
|
|
imPbmRead(ioType, fd, fp, flagsTable, tagTable)
|
|
|
|
int ioType; /* I/O type */
|
|
|
|
int fd; /* Input file descriptor */
|
|
|
|
FILE *fp; /* Input file buffer pointer */
|
|
|
|
TagTable *flagsTable; /* Input parameter/flags */
|
|
|
|
TagTable *tagTable; /* Tag table to add to */
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
ImVfbPtr pPixel; /* VFB pixel pointer */
|
|
|
|
unsigned char *pBuffer; /* Buffer pointer */
|
|
|
|
int bitShift; /* Shift amount for expanding Mono*/
|
|
|
|
int width, height; /* Image size */
|
|
|
|
int fields; /* VFB fields */
|
|
|
|
int maxIntensity; /* Maximum channel intensity */
|
|
|
|
float colorScale; /* Intensity scaling */
|
|
|
|
unsigned char magic[2]; /* Magic number */
|
|
|
|
unsigned char byte; /* Byte holder */
|
|
|
|
int hue; /* Incomming channel value */
|
|
|
|
ImVfb *vfb; /* New VFB */
|
|
|
|
unsigned char *buffer; /* Incomming byte buffer */
|
|
|
|
int x, y; /* VFB location */
|
|
|
|
char message[100]; /* ImInfo message */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the magic number
|
|
|
|
*/
|
|
|
|
BinByteOrder( BINMBF );
|
|
|
|
ImInfo ("Byte Order","Most Significant Byte First");
|
|
|
|
if ( ImBinRead( ioType, fd, fp, magic, UCHAR, 1, 2 ) == -1 )
|
|
|
|
ImReturnBinError( );
|
|
|
|
if ( magic[0] != IMPBM_MAGIC1 )
|
|
|
|
{
|
|
|
|
ImErrNo = IMEMAGIC;
|
|
|
|
ImErrorFatal( ImQError( ), -1, ImErrNo );
|
|
|
|
}
|
|
|
|
switch ( magic[1] )
|
|
|
|
{
|
|
|
|
case IMPBM_MAGIC2:
|
|
|
|
case IMRPBM_MAGIC2:
|
|
|
|
fields = IMVFBMONO;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IMPGM_MAGIC2:
|
|
|
|
case IMRPGM_MAGIC2:
|
|
|
|
fields = IMVFBINDEX8;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IMPPM_MAGIC2:
|
|
|
|
case IMRPPM_MAGIC2:
|
|
|
|
fields = IMVFBRGB;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ImErrNo = IMEMAGIC;
|
|
|
|
ImErrorFatal( ImQError( ), -1, ImErrNo );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Read image size.
|
|
|
|
*/
|
|
|
|
if ( readAsciiInt( ioType, fd, fp, &width ) == -1)
|
|
|
|
return ( -1 ); /* Error already handled */
|
|
|
|
if ( readAsciiInt( ioType, fd, fp, &height ) == -1)
|
|
|
|
return ( -1 ); /* Error already handled */
|
|
|
|
|
|
|
|
|
|
|
|
sprintf (message, "%d x %d",width, height);
|
|
|
|
ImInfo ("Resolution",message);
|
|
|
|
switch ( magic[1] )
|
|
|
|
{
|
|
|
|
case IMPBM_MAGIC2:
|
|
|
|
ImInfo ("Type","1-bit Monochrome");
|
|
|
|
ImInfo ("Compression", "Ascii");
|
|
|
|
break;
|
|
|
|
case IMRPBM_MAGIC2:
|
|
|
|
ImInfo ("Type","1-bit Monochrome");
|
|
|
|
ImInfo ("Compression", "none");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IMPGM_MAGIC2:
|
|
|
|
ImInfo ("Type","8-bit Grayscale");
|
|
|
|
ImInfo ("Compression", "Ascii");
|
|
|
|
break;
|
|
|
|
case IMRPGM_MAGIC2:
|
|
|
|
ImInfo ("Type","8-bit Grayscale");
|
|
|
|
ImInfo ("Compression", "none");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IMPPM_MAGIC2:
|
|
|
|
ImInfo ("Type","24-bit RGB");
|
|
|
|
ImInfo ("Compression", "Ascii");
|
|
|
|
break;
|
|
|
|
case IMRPPM_MAGIC2:
|
|
|
|
ImInfo ("Type","24-bit RGB");
|
|
|
|
ImInfo ("Compression", "none");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Except for PBM and RPBM formats, read in the maximum channel
|
|
|
|
* value 'maxIntensity'.
|
|
|
|
*
|
|
|
|
* Compute how to scale color values from their incomming value
|
|
|
|
* range of 0-maxIntensity, to our range of 0-255 (8-bit indexes
|
|
|
|
* and RGB components).
|
|
|
|
*/
|
|
|
|
maxIntensity = 0;
|
|
|
|
if ( magic[1] != IMPBM_MAGIC2 && magic[1] != IMRPBM_MAGIC2 )
|
|
|
|
{
|
|
|
|
if ( readAsciiInt( ioType, fd, fp, &maxIntensity ) == -1 )
|
|
|
|
return ( -1 ); /* Error already handled */
|
|
|
|
colorScale = 255.0 / (float) maxIntensity;
|
|
|
|
}
|
|
|
|
skipEOL( ioType, fd, fp );
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate a VFB of the required size.
|
|
|
|
*/
|
|
|
|
if ((vfb = ImVfbAlloc( width, height, fields )) == IMVFBNULL)
|
|
|
|
{
|
|
|
|
ImErrorFatal( ImQError( ), -1, ImErrNo );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Read in the image, depending upon how it is stored.
|
|
|
|
*/
|
|
|
|
switch ( magic[1] )
|
|
|
|
{
|
|
|
|
case IMPPM_MAGIC2: /* ASCII Color */
|
|
|
|
pPixel = ImVfbQFirst( vfb );
|
|
|
|
for (y = 0; y < height; y++)
|
|
|
|
{
|
|
|
|
for ( x = 0; x < width; x++)
|
|
|
|
{
|
|
|
|
if ( readAsciiInt( ioType, fd, fp, &hue ) == -1)
|
|
|
|
return (-1);
|
|
|
|
ImVfbSRed( vfb, pPixel, colorScale * hue );
|
|
|
|
|
|
|
|
if ( readAsciiInt( ioType, fd, fp, &hue ) == -1)
|
|
|
|
return (-1);
|
|
|
|
ImVfbSGreen( vfb, pPixel, colorScale * hue );
|
|
|
|
|
|
|
|
if ( readAsciiInt( ioType, fd, fp, &hue ) == -1)
|
|
|
|
return (-1);
|
|
|
|
ImVfbSBlue( vfb, pPixel, colorScale * hue );
|
|
|
|
|
|
|
|
ImVfbSInc( vfb, pPixel );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IMRPPM_MAGIC2: /* Raw Color */
|
|
|
|
/* Skip carriage return. */
|
|
|
|
ImMalloc( buffer, unsigned char *, width * 3 );
|
|
|
|
pPixel = ImVfbQFirst( vfb );
|
|
|
|
for (y = 0; y < height; y++)
|
|
|
|
{
|
|
|
|
if ( ImBinRead( ioType, fd, fp, buffer, UCHAR, 1, width * 3 ) == -1 )
|
|
|
|
{
|
|
|
|
free( (char *)buffer );
|
|
|
|
ImReturnBinError( );
|
|
|
|
}
|
|
|
|
pBuffer = buffer;
|
|
|
|
for ( x = 0; x < width; x++ )
|
|
|
|
{
|
|
|
|
ImVfbSRed( vfb, pPixel, colorScale * *pBuffer++ );
|
|
|
|
ImVfbSGreen( vfb, pPixel, colorScale * *pBuffer++ );
|
|
|
|
ImVfbSBlue( vfb, pPixel, colorScale * *pBuffer++ );
|
|
|
|
ImVfbSInc( vfb, pPixel );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free( (char *) buffer );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IMPGM_MAGIC2: /* ASCII grayscale */
|
|
|
|
pPixel = ImVfbQFirst( vfb );
|
|
|
|
for (y = 0; y < height; y++)
|
|
|
|
{
|
|
|
|
for (x = 0; x < width; x++ )
|
|
|
|
{
|
|
|
|
if ( readAsciiInt( ioType, fd, fp, &hue ) == -1)
|
|
|
|
return (-1);
|
|
|
|
ImVfbSIndex8( vfb, pPixel, colorScale * hue );
|
|
|
|
ImVfbSInc( vfb, pPixel );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IMRPGM_MAGIC2: /* Raw grayscale */
|
|
|
|
/* Skip carriage return. */
|
|
|
|
ImMalloc( buffer, unsigned char *, width );
|
|
|
|
pPixel = ImVfbQFirst( vfb );
|
|
|
|
for (y = 0; y < height; y++)
|
|
|
|
{
|
|
|
|
if ( ImBinRead( ioType, fd, fp, buffer, UCHAR, 1, width ) == -1 )
|
|
|
|
{
|
|
|
|
free( (char *)buffer );
|
|
|
|
ImReturnBinError( );
|
|
|
|
}
|
|
|
|
pBuffer = buffer;
|
|
|
|
for ( x = 0; x < width; x++ )
|
|
|
|
{
|
|
|
|
ImVfbSIndex8( vfb, pPixel, colorScale * *pBuffer++ );
|
|
|
|
ImVfbSInc( vfb, pPixel );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free( (char *) buffer );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IMPBM_MAGIC2: /* ASCII bitmap (mono) */
|
|
|
|
pPixel = ImVfbQFirst( vfb );
|
|
|
|
for (y = 0; y < height; y++)
|
|
|
|
{
|
|
|
|
for (x = 0; x < width; x++ )
|
|
|
|
{
|
|
|
|
if ( readAsciiInt( ioType, fd, fp, &hue ) == -1)
|
|
|
|
return (-1);
|
|
|
|
/*
|
|
|
|
* hue = 0 (white) maps to VFB 1 (white).
|
|
|
|
* hue = 1 (black) maps to VFB 0 (black).
|
|
|
|
*/
|
|
|
|
ImVfbSMono( vfb, pPixel, (~hue) & 0x1 );
|
|
|
|
ImVfbSInc( vfb, pPixel );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IMRPBM_MAGIC2: /* Raw bitmap (mono) */
|
|
|
|
/* Skip carriage return. */
|
|
|
|
ImMalloc( buffer, unsigned char *, (width + 7) / 8 );
|
|
|
|
pPixel = ImVfbQFirst( vfb );
|
|
|
|
for (y = 0; y < height; y++)
|
|
|
|
{
|
|
|
|
bitShift = -1;
|
|
|
|
if ( ImBinRead( ioType, fd, fp, buffer, UCHAR, 1, (width + 7) / 8 ) == -1 )
|
|
|
|
{
|
|
|
|
free( (char *)buffer );
|
|
|
|
ImReturnBinError( );
|
|
|
|
}
|
|
|
|
pBuffer = buffer;
|
|
|
|
for ( x = 0; x < width; x++ )
|
|
|
|
{
|
|
|
|
if (bitShift == -1)
|
|
|
|
{
|
|
|
|
byte = ~(*pBuffer++);
|
|
|
|
bitShift = 7;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* hue = 0 (white) maps to VFB 1 (white).
|
|
|
|
* hue = 1 (black) maps to VFB 0 (black).
|
|
|
|
*/
|
|
|
|
ImVfbSMono( vfb, pPixel,
|
|
|
|
!((byte >> bitShift--)& 0x1) );
|
|
|
|
ImVfbSInc( vfb, pPixel );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free( (char *) buffer );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Add the VFB to the tagTable.
|
|
|
|
*/
|
|
|
|
TagTableAppend( tagTable, TagEntryAlloc( "image vfb", POINTER, &vfb ) );
|
|
|
|
|
|
|
|
return ( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* FUNCTION
|
|
|
|
* skipEOL - skip to end of line
|
|
|
|
* readAsciiInt - read in an ASCII string integer
|
|
|
|
*
|
|
|
|
* DESCRIPTION
|
|
|
|
* White space and comments are skipped up to the first digit of a number.
|
|
|
|
* The number is read in and returned. If a read problem occurs, a -1
|
|
|
|
* is returned as the function value. Otherwise 0 is returned.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int /* Returns status */
|
|
|
|
#ifdef __STDC__
|
|
|
|
skipEOL( int ioType, int fd, FILE *fp )
|
|
|
|
#else
|
|
|
|
skipEOL( ioType, fd, fp )
|
|
|
|
int ioType; /* I/O type */
|
|
|
|
int fd; /* File descriptor to use */
|
|
|
|
FILE *fp; /* File pointer to use */
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
int ich; /* Input character (as integer) */
|
|
|
|
unsigned char ch; /* Input character */
|
|
|
|
|
|
|
|
ch = '\0';
|
|
|
|
if ( ioType & IMFILEIOFD )
|
|
|
|
{
|
|
|
|
while ( ch != '\n' )
|
|
|
|
{
|
|
|
|
if ( read( fd, &ch, 1 ) <= 0 )
|
|
|
|
{
|
|
|
|
ImErrNo = IMESYNTAX;
|
|
|
|
ImErrorFatal( ImQError( ), -1, ImErrNo );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
while ( (ich = getc( fp )) != '\n' && ich != EOF )
|
|
|
|
;
|
|
|
|
if ( ich == EOF )
|
|
|
|
{
|
|
|
|
ImErrNo = IMESYNTAX;
|
|
|
|
ImErrorFatal( ImQError( ), -1, ImErrNo );
|
|
|
|
}
|
|
|
|
return ( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
static int /* Returns status */
|
|
|
|
#ifdef __STDC__
|
|
|
|
readAsciiInt( int ioType, int fd, FILE *fp, int *value )
|
|
|
|
#else
|
|
|
|
readAsciiInt( ioType, fd, fp, value )
|
|
|
|
int ioType; /* I/O type */
|
|
|
|
int fd; /* File descriptor to use */
|
|
|
|
FILE *fp; /* File pointer to use */
|
|
|
|
int *value; /* Returned integer value */
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
int ich; /* Input character (as integer) */
|
|
|
|
unsigned char ch; /* Input character */
|
|
|
|
|
|
|
|
if ( ioType & IMFILEIOFD )
|
|
|
|
{
|
|
|
|
/* Skip white space and comments that start with a '#' */
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if ( read( fd, &ch, 1 ) <= 0 )
|
|
|
|
{
|
|
|
|
ImErrNo = IMESYNTAX;
|
|
|
|
ImErrorFatal( ImQError( ), -1, ImErrNo );
|
|
|
|
}
|
|
|
|
if ( ch == '#' )
|
|
|
|
{
|
|
|
|
if ( skipEOL( ioType, fd, fp ) == -1 )
|
|
|
|
return ( -1 );
|
|
|
|
ch = '\n';
|
|
|
|
}
|
|
|
|
} while ( isspace( ch ) );
|
|
|
|
|
|
|
|
/* Read in and assemble an integer. */
|
|
|
|
*value = 0;
|
|
|
|
while ( isdigit( ch ) )
|
|
|
|
{
|
|
|
|
*value = *value * 10 + (ch - '0');
|
|
|
|
if ( read( fd, &ch, 1 ) <= 0 )
|
|
|
|
{
|
|
|
|
ImErrNo = IMESYNTAX;
|
|
|
|
ImErrorFatal( ImQError( ), -1, ImErrNo );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Skip white space and comments starting with '#'. Read in
|
|
|
|
* a single integer.
|
|
|
|
*/
|
|
|
|
while ( (ich = getc( fp )) == '#' || isspace( ich ) )
|
|
|
|
{
|
|
|
|
if ( ich == '#' )
|
|
|
|
if ( skipEOL( ioType, fd, fp ) == -1 )
|
|
|
|
return ( -1 );
|
|
|
|
}
|
|
|
|
if ( ich == EOF )
|
|
|
|
{
|
|
|
|
ImErrNo = IMESYNTAX;
|
|
|
|
ImErrorFatal( ImQError( ), -1, ImErrNo );
|
|
|
|
}
|
|
|
|
ungetc( ich, fp );
|
|
|
|
if ( fscanf( fp, "%d", value ) != 1 )
|
|
|
|
{
|
|
|
|
ImErrNo = IMESYNTAX;
|
|
|
|
ImErrorFatal( ImQError( ), -1, ImErrNo );
|
|
|
|
}
|
|
|
|
return ( 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* FUNCTION
|
|
|
|
* imPbmWrite1 - write a 1-bit ASCII PBM file
|
|
|
|
* imPbmWrite8 - write an 8-bit ASCII PGM file
|
|
|
|
* imPbmWriteRGB - write an RGB ASCII PPM file
|
|
|
|
*
|
|
|
|
* DESCRIPTION
|
|
|
|
* 1-bit: The image is written out in ASCII as a series of 1-bit values
|
|
|
|
* each in the form: "i ". To make the PBM file more readable,
|
|
|
|
* carriage returns are added every 70 characters or so.
|
|
|
|
*
|
|
|
|
* 8-bit: The image is written out in ASCII as a series of 8-bit index
|
|
|
|
* values, each in the form: "iii ". To make the PGM file more readable,
|
|
|
|
* carriage returns are added every 70 characters or so.
|
|
|
|
*
|
|
|
|
* RGB: The image is written out in ASCII as a series of RGB values, each
|
|
|
|
* in the form: "rrr ggg bbb ". To make the PPM file more readable,
|
|
|
|
* carriage returns are added every 70 characters or so (after the nearest
|
|
|
|
* complete tripplet).
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int
|
|
|
|
#ifdef __STDC__
|
|
|
|
imPbmWrite1(ImFileFormatWriteMap * pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable )
|
|
|
|
#else
|
|
|
|
imPbmWrite1( pMap, ioType, fd, fp, flagsTable, tagTable )
|
|
|
|
ImFileFormatWriteMap *pMap; /* Write map entry to adhear to */
|
|
|
|
int ioType; /* I/O type flag */
|
|
|
|
int fd; /* Unbuffered file descriptor */
|
|
|
|
FILE *fp; /* Buffered file pointer */
|
|
|
|
TagTable *flagsTable; /* Max color value flag */
|
|
|
|
TagTable *tagTable; /* Tag list to read from */
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
int x, y; /* Pixel location counters */
|
|
|
|
ImVfbPtr pPixel; /* Current pixel */
|
|
|
|
ImVfb *vfb; /* Image to output */
|
|
|
|
int width; /* Image width */
|
|
|
|
int height; /* Image height */
|
|
|
|
unsigned char buffer[200]; /* Line buffer */
|
|
|
|
unsigned char *pBuffer; /* Current location in buffer */
|
|
|
|
unsigned char *pBufferStop; /* Where to stop & flush in buffer*/
|
|
|
|
char message[100]; /* ImInfo message */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the VFB and its attributes. Write the PBM header.
|
|
|
|
*/
|
|
|
|
TagEntryQValue( TagTableQDirect( tagTable, "image vfb", 0 ), &vfb );
|
|
|
|
width = ImVfbQWidth( vfb );
|
|
|
|
height = ImVfbQHeight( vfb );
|
|
|
|
sprintf( (char *)buffer, "%c%c\n%d %d\n", IMPBM_MAGIC1, IMPBM_MAGIC2,
|
|
|
|
width, height );
|
|
|
|
IMWrite( ioType, fd, fp, buffer, strlen( (char*)buffer ) );
|
|
|
|
|
|
|
|
ImInfo ("Byte Order","Most Significant Byte First");
|
|
|
|
ImInfo ("Type","1-bit Monochrome");
|
|
|
|
sprintf (message, "%d x %d",width, height);
|
|
|
|
ImInfo ("Resolution",message);
|
|
|
|
ImInfo ("Compression", "Ascii");
|
|
|
|
|
|
|
|
pPixel = ImVfbQFirst( vfb );
|
|
|
|
pBufferStop = buffer + 70; /* Flush soon after 70 chars */
|
|
|
|
pBuffer = buffer;
|
|
|
|
|
|
|
|
for ( y = 0; y < height; y++ )
|
|
|
|
{
|
|
|
|
for ( x = 0; x < width; x++ )
|
|
|
|
{
|
|
|
|
if ( pBuffer >= pBufferStop )
|
|
|
|
{
|
|
|
|
*pBuffer = '\n';
|
|
|
|
IMWrite( ioType, fd, fp, buffer,pBuffer-buffer+1);
|
|
|
|
pBuffer = buffer;
|
|
|
|
}
|
|
|
|
sprintf( (char *)pBuffer, "%1d ",
|
|
|
|
(~ImVfbQMono( vfb, pPixel )) & 0x1 );
|
|
|
|
pBuffer += 2;
|
|
|
|
ImVfbSInc( vfb, pPixel );
|
|
|
|
}
|
|
|
|
if ( pBuffer != buffer )
|
|
|
|
{
|
|
|
|
*pBuffer = '\n';
|
|
|
|
IMWrite( ioType, fd, fp, buffer,pBuffer-buffer+1);
|
|
|
|
pBuffer = buffer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
#ifdef __STDC__
|
|
|
|
imPbmWrite8(ImFileFormatWriteMap * pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable )
|
|
|
|
#else
|
|
|
|
imPbmWrite8( pMap, ioType, fd, fp, flagsTable, tagTable )
|
|
|
|
ImFileFormatWriteMap *pMap; /* Write map entry to adhear to */
|
|
|
|
int ioType; /* I/O type flag */
|
|
|
|
int fd; /* Unbuffered file descriptor */
|
|
|
|
FILE *fp; /* Buffered file pointer */
|
|
|
|
TagTable *flagsTable; /* Max color value flag */
|
|
|
|
TagTable *tagTable; /* Tag list to read from */
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
int x, y; /* Pixel location counters */
|
|
|
|
ImVfbPtr pPixel; /* Current pixel */
|
|
|
|
ImVfb *vfb; /* Image to output */
|
|
|
|
int width; /* Image width */
|
|
|
|
int height; /* Image height */
|
|
|
|
unsigned char buffer[200]; /* Line buffer */
|
|
|
|
unsigned char *pBuffer; /* Current location in buffer */
|
|
|
|
unsigned char *pBufferStop; /* Where to stop & flush in buffer*/
|
|
|
|
char message[100]; /* ImInfo message */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the VFB and its attributes. Write the PGM header.
|
|
|
|
*/
|
|
|
|
TagEntryQValue( TagTableQDirect( tagTable, "image vfb", 0 ), &vfb );
|
|
|
|
width = ImVfbQWidth( vfb );
|
|
|
|
height = ImVfbQHeight( vfb );
|
|
|
|
sprintf( (char *)buffer, "%c%c\n%d %d\n255\n", IMPBM_MAGIC1, IMPGM_MAGIC2,
|
|
|
|
width, height );
|
|
|
|
IMWrite( ioType, fd, fp, buffer, strlen((char*) buffer ) );
|
|
|
|
|
|
|
|
ImInfo ("Byte Order","Most Significant Byte First");
|
|
|
|
ImInfo ("Type","8-bit Grayscale");
|
|
|
|
sprintf (message, "%d x %d",width, height);
|
|
|
|
ImInfo ("Resolution",message);
|
|
|
|
ImInfo ("Compression", "Ascii");
|
|
|
|
|
|
|
|
pPixel = ImVfbQFirst( vfb );
|
|
|
|
pBufferStop = buffer + 68; /* Flush soon after 68 chars */
|
|
|
|
pBuffer = buffer;
|
|
|
|
|
|
|
|
for ( y = 0; y < height; y++ )
|
|
|
|
{
|
|
|
|
for ( x = 0; x < width; x++ )
|
|
|
|
{
|
|
|
|
if ( pBuffer >= pBufferStop )
|
|
|
|
{
|
|
|
|
*pBuffer = '\n';
|
|
|
|
IMWrite( ioType, fd, fp, buffer,pBuffer-buffer+1);
|
|
|
|
pBuffer = buffer;
|
|
|
|
}
|
|
|
|
sprintf( (char *)pBuffer, "%03d ",
|
|
|
|
(ImVfbQIndex8( vfb, pPixel ) & 0xFF) );
|
|
|
|
pBuffer += 4;
|
|
|
|
ImVfbSInc( vfb, pPixel );
|
|
|
|
}
|
|
|
|
if ( pBuffer != buffer )
|
|
|
|
{
|
|
|
|
*pBuffer = '\n';
|
|
|
|
IMWrite( ioType, fd, fp, buffer,pBuffer-buffer+1);
|
|
|
|
pBuffer = buffer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
#ifdef __STDC__
|
|
|
|
imPbmWriteRGB(ImFileFormatWriteMap * pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable )
|
|
|
|
#else
|
|
|
|
imPbmWriteRGB( pMap, ioType, fd, fp, flagsTable, tagTable )
|
|
|
|
ImFileFormatWriteMap *pMap; /* Write map entry to adhear to */
|
|
|
|
int ioType; /* I/O type flag */
|
|
|
|
int fd; /* Unbuffered file descriptor */
|
|
|
|
FILE *fp; /* Buffered file pointer */
|
|
|
|
TagTable *flagsTable; /* Max color value flag */
|
|
|
|
TagTable *tagTable; /* Tag list to read from */
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
int x, y; /* Pixel location counters */
|
|
|
|
ImVfbPtr pPixel; /* Current pixel */
|
|
|
|
ImVfb *vfb; /* Image to output */
|
|
|
|
int width; /* Image width */
|
|
|
|
int height; /* Image height */
|
|
|
|
unsigned char buffer[200]; /* Line buffer */
|
|
|
|
unsigned char *pBuffer; /* Current location in buffer */
|
|
|
|
unsigned char *pBufferStop; /* Where to stop & flush in buffer*/
|
|
|
|
char message[100]; /* ImInfo message */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the VFB and its attributes. Write the PPM header.
|
|
|
|
*/
|
|
|
|
TagEntryQValue( TagTableQDirect( tagTable, "image vfb", 0 ), &vfb );
|
|
|
|
width = ImVfbQWidth( vfb );
|
|
|
|
height = ImVfbQHeight( vfb );
|
|
|
|
sprintf( (char *)buffer, "%c%c\n%d %d\n255\n", IMPBM_MAGIC1, IMPPM_MAGIC2,
|
|
|
|
width, height );
|
|
|
|
IMWrite( ioType, fd, fp, buffer, strlen((char*) buffer ) );
|
|
|
|
|
|
|
|
ImInfo ("Byte Order","Most Significant Byte First");
|
|
|
|
ImInfo ("Type","24-bit RGB");
|
|
|
|
sprintf (message, "%d x %d",width, height);
|
|
|
|
ImInfo ("Resolution",message);
|
|
|
|
ImInfo ("Compression", "Ascii");
|
|
|
|
|
|
|
|
pPixel = ImVfbQFirst( vfb );
|
|
|
|
pBufferStop = buffer + 65; /* Flush soon after 65 chars */
|
|
|
|
pBuffer = buffer;
|
|
|
|
|
|
|
|
for ( y = 0; y < height; y++ )
|
|
|
|
{
|
|
|
|
for ( x = 0; x < width; x++ )
|
|
|
|
{
|
|
|
|
if ( pBuffer >= pBufferStop )
|
|
|
|
{
|
|
|
|
*pBuffer = '\n';
|
|
|
|
IMWrite( ioType, fd, fp, buffer,pBuffer-buffer+1);
|
|
|
|
pBuffer = buffer;
|
|
|
|
}
|
|
|
|
sprintf( (char *)pBuffer, "%03d %03d %03d ",
|
|
|
|
(ImVfbQRed( vfb, pPixel ) & 0xFF),
|
|
|
|
(ImVfbQGreen( vfb, pPixel ) & 0xFF),
|
|
|
|
(ImVfbQBlue( vfb, pPixel ) & 0xFF) );
|
|
|
|
pBuffer += 13;
|
|
|
|
ImVfbSInc( vfb, pPixel );
|
|
|
|
}
|
|
|
|
if ( pBuffer != buffer )
|
|
|
|
{
|
|
|
|
*pBuffer = '\n';
|
|
|
|
IMWrite( ioType, fd, fp, buffer,pBuffer-buffer+1);
|
|
|
|
pBuffer = buffer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* FUNCTION
|
|
|
|
* imRpbmWrite1 - write an 1-bit raw PBM file
|
|
|
|
* imRpbmWrite8 - write an 8-bit raw PGM file
|
|
|
|
* imRpbmWriteRGB - write an RGB raw PPM file
|
|
|
|
*
|
|
|
|
* DESCRIPTION
|
|
|
|
* 1-bit: The image is written out in binary as a series of 8-bit values,
|
|
|
|
* each one constructed from 8 1-bit mono values.
|
|
|
|
*
|
|
|
|
* 8-bit: The image is written out in binary as a series of 8-bit index
|
|
|
|
* values.
|
|
|
|
*
|
|
|
|
* RGB: The image is written out in binary as a series of RGB values.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int
|
|
|
|
#ifdef __STDC__
|
|
|
|
imRpbmWrite1(ImFileFormatWriteMap * pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable )
|
|
|
|
#else
|
|
|
|
imRpbmWrite1( pMap, ioType, fd, fp, flagsTable, tagTable )
|
|
|
|
ImFileFormatWriteMap *pMap; /* Write map entry to adhear to */
|
|
|
|
int ioType; /* I/O type flag */
|
|
|
|
int fd; /* Unbuffered file descriptor */
|
|
|
|
FILE *fp; /* Buffered file pointer */
|
|
|
|
TagTable *flagsTable; /* Max color value flag */
|
|
|
|
TagTable *tagTable; /* Tag list to read from */
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
int x, y; /* Pixel location counters */
|
|
|
|
ImVfbPtr pPixel; /* Current pixel */
|
|
|
|
ImVfb *vfb; /* Image to output */
|
|
|
|
int width; /* Image width */
|
|
|
|
int height; /* Image height */
|
|
|
|
unsigned char buf[200]; /* Temp buffer */
|
|
|
|
unsigned char *buffer; /* Line buffer */
|
|
|
|
unsigned char *pBuffer; /* Current location in buffer */
|
|
|
|
int shift; /* How far to shift */
|
|
|
|
int byte; /* Byte being built up */
|
|
|
|
char message[100]; /* ImInfo message */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the VFB and its attributes. Write the PBM header.
|
|
|
|
*/
|
|
|
|
TagEntryQValue( TagTableQDirect( tagTable, "image vfb", 0 ), &vfb );
|
|
|
|
width = ImVfbQWidth( vfb );
|
|
|
|
height = ImVfbQHeight( vfb );
|
|
|
|
sprintf( (char *)buf, "%c%c\n%d %d\n", IMPBM_MAGIC1, IMRPBM_MAGIC2,
|
|
|
|
width, height );
|
|
|
|
IMWrite( ioType, fd, fp, buf, strlen((char*) buf ) );
|
|
|
|
|
|
|
|
ImInfo ("Byte Order","Most Significant Byte First");
|
|
|
|
ImInfo ("Type","1-bit Monochrome");
|
|
|
|
sprintf (message, "%d x %d",width, height);
|
|
|
|
ImInfo ("Resolution",message);
|
|
|
|
ImInfo ("Compression", "none");
|
|
|
|
|
|
|
|
ImMalloc( buffer, unsigned char *, (width + 7) / 8 );
|
|
|
|
pPixel = ImVfbQFirst( vfb );
|
|
|
|
for ( y = 0; y < height; y++ )
|
|
|
|
{
|
|
|
|
byte = 0;
|
|
|
|
shift = 7;
|
|
|
|
pBuffer = buffer;
|
|
|
|
for ( x = 0; x < width; x++ )
|
|
|
|
{
|
|
|
|
byte |= (ImVfbQMono( vfb, pPixel ) & 0x1) << shift--;
|
|
|
|
ImVfbSInc( vfb, pPixel );
|
|
|
|
if ( shift == -1 )
|
|
|
|
{
|
|
|
|
*pBuffer++ = byte;
|
|
|
|
shift = 7;
|
|
|
|
byte = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( shift != 7 )
|
|
|
|
*pBuffer++ = byte;
|
|
|
|
IMWrite( ioType, fd, fp, buffer, pBuffer - buffer );
|
|
|
|
}
|
|
|
|
|
|
|
|
free( (char *)buffer );
|
|
|
|
return ( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
#ifdef __STDC__
|
|
|
|
imRpbmWrite8(ImFileFormatWriteMap * pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable )
|
|
|
|
#else
|
|
|
|
imRpbmWrite8( pMap, ioType, fd, fp, flagsTable, tagTable )
|
|
|
|
ImFileFormatWriteMap *pMap; /* Write map entry to adhear to */
|
|
|
|
int ioType; /* I/O type flag */
|
|
|
|
int fd; /* Unbuffered file descriptor */
|
|
|
|
FILE *fp; /* Buffered file pointer */
|
|
|
|
TagTable *flagsTable; /* Max color value flag */
|
|
|
|
TagTable *tagTable; /* Tag list to read from */
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
int x, y; /* Pixel location counters */
|
|
|
|
ImVfbPtr pPixel; /* Current pixel */
|
|
|
|
ImVfb *vfb; /* Image to output */
|
|
|
|
int width; /* Image width */
|
|
|
|
int height; /* Image height */
|
|
|
|
unsigned char buf[200]; /* Temp buffer */
|
|
|
|
unsigned char *buffer; /* Line buffer */
|
|
|
|
unsigned char *pBuffer; /* Current location in buffer */
|
|
|
|
char message[100]; /* ImInfo message */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the VFB and its attributes. Write the PBM header.
|
|
|
|
*/
|
|
|
|
TagEntryQValue( TagTableQDirect( tagTable, "image vfb", 0 ), &vfb );
|
|
|
|
width = ImVfbQWidth( vfb );
|
|
|
|
height = ImVfbQHeight( vfb );
|
|
|
|
sprintf( (char *)buf, "%c%c\n%d %d\n255\n", IMPBM_MAGIC1, IMRPGM_MAGIC2,
|
|
|
|
width, height );
|
|
|
|
IMWrite( ioType, fd, fp, buf, strlen((char*) buf ) );
|
|
|
|
|
|
|
|
ImInfo ("Byte Order","Most Significant Byte First");
|
|
|
|
ImInfo ("Type","8-bit Grayscale");
|
|
|
|
sprintf (message, "%d x %d",width, height);
|
|
|
|
ImInfo ("Resolution",message);
|
|
|
|
ImInfo ("Compression", "none");
|
|
|
|
|
|
|
|
ImMalloc( buffer, unsigned char *, width );
|
|
|
|
pPixel = ImVfbQFirst( vfb );
|
|
|
|
for ( y = 0; y < height; y++ )
|
|
|
|
{
|
|
|
|
pBuffer = buffer;
|
|
|
|
for ( x = 0; x < width; x++ )
|
|
|
|
{
|
|
|
|
*pBuffer++ = ImVfbQIndex8( vfb, pPixel );
|
|
|
|
ImVfbSInc( vfb, pPixel );
|
|
|
|
}
|
|
|
|
IMWrite( ioType, fd, fp, buffer, pBuffer - buffer );
|
|
|
|
}
|
|
|
|
|
|
|
|
free( (char *)buffer );
|
|
|
|
return ( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
#ifdef __STDC__
|
|
|
|
imRpbmWriteRGB(ImFileFormatWriteMap * pMap, int ioType, int fd, FILE *fp, TagTable *flagsTable, TagTable *tagTable )
|
|
|
|
#else
|
|
|
|
imRpbmWriteRGB( pMap, ioType, fd, fp, flagsTable, tagTable )
|
|
|
|
ImFileFormatWriteMap *pMap; /* Write map entry to adhear to */
|
|
|
|
int ioType; /* I/O type flag */
|
|
|
|
int fd; /* Unbuffered file descriptor */
|
|
|
|
FILE *fp; /* Buffered file pointer */
|
|
|
|
TagTable *flagsTable; /* Max color value flag */
|
|
|
|
TagTable *tagTable; /* Tag list to read from */
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
int x, y; /* Pixel location counters */
|
|
|
|
ImVfbPtr pPixel; /* Current pixel */
|
|
|
|
ImVfb *vfb; /* Image to output */
|
|
|
|
int width; /* Image width */
|
|
|
|
int height; /* Image height */
|
|
|
|
unsigned char buf[200]; /* Temp buffer */
|
|
|
|
unsigned char *buffer; /* Line buffer */
|
|
|
|
unsigned char *pBuffer; /* Current location in buffer */
|
|
|
|
char message[100]; /* ImInfo message */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the VFB and its attributes. Write the PPM header.
|
|
|
|
*/
|
|
|
|
TagEntryQValue( TagTableQDirect( tagTable, "image vfb", 0 ), &vfb );
|
|
|
|
width = ImVfbQWidth( vfb );
|
|
|
|
height = ImVfbQHeight( vfb );
|
|
|
|
sprintf( (char *)buf, "%c%c\n%d %d\n255\n", IMPBM_MAGIC1, IMRPPM_MAGIC2,
|
|
|
|
width, height );
|
|
|
|
IMWrite( ioType, fd, fp, buf, strlen((char*) buf ) );
|
|
|
|
|
|
|
|
ImInfo ("Byte Order","Most Significant Byte First");
|
|
|
|
ImInfo ("Type","24-bit RGB");
|
|
|
|
sprintf (message, "%d x %d",width, height);
|
|
|
|
ImInfo ("Resolution",message);
|
|
|
|
ImInfo ("Compression", "none");
|
|
|
|
|
|
|
|
ImMalloc( buffer, unsigned char *, width * 3 );
|
|
|
|
pPixel = ImVfbQFirst( vfb );
|
|
|
|
for ( y = 0; y < height; y++ )
|
|
|
|
{
|
|
|
|
pBuffer = buffer;
|
|
|
|
for ( x = 0; x < width; x++ )
|
|
|
|
{
|
|
|
|
*pBuffer++ = ImVfbQRed( vfb, pPixel );
|
|
|
|
*pBuffer++ = ImVfbQGreen( vfb, pPixel );
|
|
|
|
*pBuffer++ = ImVfbQBlue( vfb, pPixel );
|
|
|
|
ImVfbSInc( vfb, pPixel );
|
|
|
|
}
|
|
|
|
IMWrite( ioType, fd, fp, buffer, pBuffer - buffer );
|
|
|
|
}
|
|
|
|
|
|
|
|
free( (char *)buffer );
|
|
|
|
return ( 1 );
|
|
|
|
}
|
|
|