grantk@manta.NOSC.MIL (Kelly J. Grant) (12/12/89)
Hi Netlanders
Thanks to all who responded to my posting on the PCX/TIFF file format.
I recieved the following replies regarding PCX format. This network is
really a wonderful way to exchange info.
I got so many 'me toos' I decided to post this even though it's a little
long. There are two references to other sources of tools and information,
followed by a PCX specification and finally C source code to use PCX. I
don't know if the code works; I've been so busy I haven't had a chance to
try it. So, if it doesn't work, I'll quote the Blues Brothers," Whaddaya
want for nuttin, rrrrrrrrrubber bissssskits" :-)
I received a TIFF spec, but it's LONG. I could possibly uuencode/ARC it...
I also received this TIFF pointer: send mail to sam@ucbvax.berkeley.edu, and
see what you get.
Good luck all. Happy Holidays.
Kelly
-----------------------------------------------------------------------------
Kelly Grant grantk@manta.nosc.mil (619) 225-8401
Computer Sciences Corp ^^^^^^^^ Important: manta.UUCP won't get to me
4045 Hancock Street "If you are given lemons.....see if you can trade for
San Diego, CA 92110 chocolate" - me
================== Posting # 1 =============================================
Try the PCX programmer's Toolkit from Genus Microcomputing
1-800-227-0918. They have over 45 routines to display, save,
and print PCX.
------------------ Posting # 2 ---------------------------------------------
The PCX file format is available FREE from:
ZSoft Corp.
450 Franklin Rd. Suite 100
Marietta, GA 30067
I suggest you call, and they will send it to you.
It has sample C routines for encoding in the spec.
Sorry, I don't have an electronic copy of the spec.
Oh, the number is: (404) 428-0008
------------------ Posting # 3 ---------------------------------------------
pcx ( PC Paintbrush ) format
----------------------------
HEADER (128 bytes)
0 $0A always
1 ver byte, Version nr: 0 2.5
2 2.8 with palette info or
3.0 without or
MS Paintbrush 1.0
3 2.8 or 3.0 without or
MS Paintbrush 1.0
5 3.0 with palette info or
MS Paintbrush 1.0
2 1 run length encoding mode
3 n bits per pixel
4 X1 word, x position upper left corner, normally 0
6 Y1 word, y position upper left corner, normally 0
8 X2 word, x position lower right corner
A Y2 word, y position lower right corner
C HRES word, card horizontal resolution ?
E VRES word, card vertical resolution ?
10 PAL 48 bytes, palette info
40 NPL byte, number of planes
41 BPL word, bytes per line in picture
Picture dimensions are given by:
horizontal = X2 - X1 + 1
vertical = Y2 - Y1 + 1
Palette has one of two formats:
EGA: Data is stored as 16 triples. Each triple is a 3 byte
quantity of Red, Green and Blue, ranging 0-255. As
there are only four levels of RGB on IBM EGA, only
the two most significant bits need to be used.
CGA: First triple, first byte: 4 msb's give background.
Second triple, first byte: 3 msb's give foreground.
Data begins at position 128 ($80) in the file. The image is stored
line by line, so if we have an RGBI-image we get:
scan line 0: RRR
GGG
BBB
III
scan line 1: RRR
GGG
BBB
III
etc...
Encoding:
A count byte (byte with two most sign. bits set)
means we should repeat next byte n times. n is given
by the six least sign. bits in the count byte.
tot is nr of bytes expected
count=0;
while( count<tot )
ch = getnext()
if( ( ch & 0xC0 ) == 0xC0 )
nr = ch & 0x3F
ch = getnext()
else
nr = 1;
put(ch,nr)
count += nr
end while
------------------ Posting # 4 ---------------------------------------------
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef struct {
BYTE
dum0, /**/
ver, /* version nr, accept 0,3 */
code, /* 1 */
pixsize; /* bits per pixel */
WORD
x1, y1, /* upper left corner */
x2, y2, /* lower right corner */
xres, yres;
BYTE
clrma,
vmode,
nplane;
WORD
bpln; /* bytes per line */
BYTE
extra;
} PCXHEAD;
/*------------------------------------------------------------*\
| iimppcx Import paintbrush file |
| [-i infile] [-o outfile] [-m] [-V] |
| |
| Return codes: |
| 0 OK |
| -1 Invocation error |
| 1 Source file error |
| 2 Source format error |
| 3 Destination file error |
\*------------------------------------------------------------*/
#include <stdio.h>
/*============================================================*/
void
Done();
/*============================================================*/
#define PROGVER "iimppcx 1.0\n"
int PicSizeX, PicSizeY,
PicResX = 1000, PicResY = 1000,
image_type = -1,
flag_m=0,
PC;
/*============================================================*/
main(argc,argv) int argc; char *argv[];
{
int
res;
char
*inf, *outf;
FILE
*ip, *op;
PCXHEAD
head;
res = Init(argc,argv, &inf, &outf);
if(res!=0)
Done(-1);
ip = fopen(inf, "r");
if(ip==NULL)
return(1);
GetPcxHead(ip,&head);
ShowPcxHead(&head);
GetPcxIm(ip,outf,&head);
Done(0);
}
/*------------------------------------------------------------*/
static int Init(argc, argv, inf, outf) int argc; char *argv[], **inf, **outf;
{
short
test=255;
int
i=1;
char
ch,
*cp;
if( *( (char *) &test ) )
PC = 1;
else
PC = 0;
/*
printf("PC=%d\n",PC);
*/
while(i<argc) {
if(argv[i][0]!='-')
return(-1);
ch = argv[i][1];
if( (ch=='i' || ch=='o') && strlen(argv[i])<3 )
cp = argv[++i];
else
cp = &argv[i][2];
switch(argv[i][1]) {
case 'i':
*inf = cp;
break;
case 'o':
*outf = cp;
break;
case 'm':
flag_m = 1;
break;
case 'V':
fprintf(stderr,"%s", PROGVER);
Done(0);
default:
return(-1);
break;
}
i++;
}
return(0);
}
/*------------------------------------------------------------*/
void Done(stat) int stat;
{
#ifdef DEBUG
fprintf(stderr,"Exit(%d)\n", stat);
#endif
exit(stat);
}
/*------------------------------------------------------------*/
int GetPcxIm(ip,outfile,head) FILE *ip; char *outfile; PCXHEAD *head;
{
char
buf[256];
FILE
*op, *fopen();
int
x, xn, y, ch,
sizex, sizey,
res;
float
prop;
extern int
errno;
op = fopen(outfile,"w");
if(!op)
exit(1);
#ifdef DEBUG
fprintf(stderr,"GetPcxIm($%X,%s,$%X)\n",ip,outfile,head);fflush(stderr);
#endif
/*----------------------*/
/* Normalize resolution */
/*----------------------*/
if(head->xres>head->yres) {
head->yres = (int) (head->yres*1000.0/head->xres);
head->xres = 1000;
}
else {
head->xres = (int) (head->xres*1000.0/head->yres);
head->yres = 1000;
}
prop = (1.0*sizex/head->xres) / (1.0*sizey/head->yres);
sizex = head->x2 - head->x1 + 1;
sizey = head->y2 - head->y1 + 1;
/*----------------------*/
/* Write the Pic header */
/*----------------------*/
if(prop>1.0)
fprintf(op,"P0.0 %d %d:", 1000, (int) (1000/prop));
else
fprintf(op,"P0.0 %d %d:", (int) (1000*prop), 1000);
/*---------------------*/
/* Binary Image Header */
/*---------------------*/
fprintf(op,"BI 0 0 %d %d %d %d:", head->xres, head->yres, sizex, sizey);
/*-------------*/
/* Write image */
/*-------------*/
xn = (sizex+7)/8;
for(y=0; y<sizey; y++) {
GetLine(ip, buf, xn);
for(x=0; x<xn; x++)
putc(buf[x], op);
} /* for y... */
fclose(op);
return(0);
}
/*------------------------------------------------------------*/
ShowPcxHead(head) PCXHEAD *head;
{
printf("dum0=%d\n", head->dum0);
printf("ver=%d\n", head->ver);
printf("code=%d\n", head->code);
printf("pixsize=%d\n", head->pixsize);
printf("x1=%d\n", head->x1);
printf("y1=%d\n", head->y1);
printf("x2=%d\n", head->x2);
printf("y2=%d\n", head->y2);
printf("xres=%d\n", head->xres);
printf("yres=%d\n", head->yres);
printf("clrma=%d\n", head->clrma);
printf("vmode=%d\n", head->vmode);
printf("nplane=%d\n", head->nplane);
printf("bpln=%d\n", head->bpln);
printf("extra=%d\n", head->extra);
}
/*------------------------------------------------------------*/
/* Get information in PCX file header. Return error code !=0 if error */
/*------------------------------------------------------------*/
static int GetPcxHead(ip,head) FILE *ip; PCXHEAD *head;
{
fread(&head->dum0, 1, 1, ip);
fread(&head->ver, 1, 1, ip);
fread(&head->code, 1, 1, ip);
fread(&head->pixsize, 1, 1, ip);
fread(&head->x1, 2, 1, ip);
if(!PC)
flip(&head->x1);
fread(&head->y1, 2, 1, ip);
if(!PC)
flip(&head->y1);
fread(&head->x2, 2, 1, ip);
if(!PC)
flip(&head->x2);
fread(&head->y2, 2, 1, ip);
if(!PC)
flip(&head->y2);
fread(&head->xres, 2, 1, ip);
if(!PC)
flip(&head->xres);
fread(&head->yres, 2, 1, ip);
if(!PC)
flip(&head->yres);
fread(&head->clrma, 1, 1, ip);
fread(&head->vmode, 1, 1, ip);
fread(&head->nplane, 1, 1, ip);
fread(&head->bpln, 2, 1, ip);
if(!PC)
flip(&head->bpln);
fread(&head->extra, 1, 1, ip);
fseek(ip, 128L, 0);
}
/*------------------------------------------------------------*/
GetLine(ip, buf, xn) FILE *ip; char buf[]; int xn;
{
int
count,
ch,
i=0;
buf[xn-1] = 0x00;
while(i<xn) {
ch = fgetc(ip);
if( (ch&0xC0)==0xC0 ) {
count = ch & 0x3F;
ch = fgetc(ip);
} else {
count = 1;
}
while(count-->0)
buf[i++] = ch;
}
}
/*------------------------------------------------------------*/
flip(valp) char *valp;
{
char
ch;
ch = *valp;
*valp = *(valp+1);
*(valp+1) = ch;
}
/*=========================== END ===========================*/
--
Kelly Grant grantk@manta.nosc.mil (619) 225-8401
Computer Sciences Corp ^^^^^^^^ Important: manta.UUCP won't get to me
4045 Hancock Street "If you are given lemons.....see if you can trade for
San Diego, CA 92110 chocolate" - me