From: edp@math.zko.dec.com (Eric Postpischil)
Newsgroups: comp.sys.palmtops
Subject: Re: Anybody know the format for .pcx files?
Date: 29 Jul 92 13:20:00 GMT
Reply-To: edp@math.zko.dec.com (Eric Postpischil)
Organization: Digital Equipment Corporation

In article <l79piuINNpu3@exodus.Eng.Sun.COM>, falk@peregrine.Eng.Sun.COM
(Ed Falk) writes:

>Hi all; the subject really says it all.  I'd like the ability to
>convert .pcx to other formats and back.  Anybody know the format?

Here's a quick hack I wrote to convert a bitmap to a .PCX file, where
the bitmap is represented as a file with lines of text containing "-"
and "#" characters for off and on bits, respectively.  This is designed
ONLY for 240 by 128 HP-95 PCX files; it will barf on anything else.


                                -- edp (Eric Postpischil)
                                "Always mount a scratch monkey."
                                edp@alien.enet.dec.com



#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>


struct pcxheader
{
	char	manufacturer;
	char	version;
	char	encoding;
	char	bits_per_pixel;
	short	xmin, ymin;
	short	xmax, ymax;
	short	hres;
	short	vres;
	char	palette[48];
	char	reserved;
	char	colour_planes;
	short	bytes_per_line;
	short	palette_type;
	char	filler[58];
};
#define	depth(header)	(header->ymax - header->ymin + 1)


#define	MEMORY	0
#define	OPEN	1
#define	FORMAT	2
void	panic(int error)
{
	switch (error)
	{
		case MEMORY:
			fprintf(stderr, "Out of memory.\n");
			break;
		case OPEN:
			break;
		case FORMAT:
			fprintf(stderr, "Input file is not in proper format.\n");
			break;
	}
	exit(1);
}


struct pcxheader	*writepcxheader(FILE *file)
{
	struct pcxheader	*header;
	int	i, j;

	header = (struct pcxheader *) calloc(1, sizeof *header);
	if (!header)
		panic(MEMORY);
	header->manufacturer = 0xa;
	header->version = 5;
	header->encoding = 1;
	header->bits_per_pixel = 1;
	header->xmin = 0;
	header->ymin = 0;
	header->xmax = 239;
	header->ymax = 127;
	header->hres = 0;
	header->vres = 0;
	header->colour_planes = 0x1;
	header->bytes_per_line = 32;
	header->palette_type = 0;

	fwrite(header, 1, sizeof *header, file);

	return header;
}


char	*pcxalloc(struct pcxheader *header)
{
	char	*p;

	p = calloc(1, header->bytes_per_line * depth(header));
	if (!p)
		panic(MEMORY);
	return p;
}


void	writepcxline(char *p, FILE *file, struct pcxheader *header)
{
	int	i, t;

	for (t = 0; t < header->bytes_per_line;)
	{
		for (i=1; t+i<header->bytes_per_line && p[t]==p[t+i]; i++)
			;
		if (i > 1)
		{
			fputc(i | 0xc0, file);
			fputc(p[t], file);
			t += i;
		}
		else
		{
			if ((p[t] & 0xc0) == 0xc0)
				fputc(0xc1, file);
			fputc(p[t++], file);
		}
	}
}


void	packpcxfile(char *buffer, FILE *file, struct pcxheader *header)
{
	int	i;

	for (i = 0; i < depth(header); i++)
		writepcxline(buffer+i*header->bytes_per_line, file, header);
}


void	getbuffer(char *buffer, struct pcxheader *header, FILE *file)
{
	int	i, j;
	char	t;
	char	*p;

	for (i = 0; i < depth(header); i++)
	{
		p = &buffer[i * header->bytes_per_line];
		for (j = 0; j <= header->xmax - header->xmin; j++)
		{
			t = getc(file);
			*p <<= 1;
			if (t == '#')
				*p |= 1;
			else if (t == '-')
				;
			else
				panic(FORMAT);
			if ((j & 7) == 7)
				p++;
		}
		if (getc(file) != '\n')
			panic(FORMAT);
	}
}


int	main(int argc, char *argv[], char *arge[])
{
	struct pcxheader	*header;
	FILE	*in, *out;
	char	*buffer;

	if (argc > 1)
	{
		in = fopen(argv[1], "r");
		if (!in)
		{
			fprintf(stderr, "%s:  Unable to open %s.\n",
				argv[0], argv[1]);
			panic(OPEN);
		}
		if (argc > 2)
		{
			out = fopen(argv[2], "w");
			if (!out)
			{
				fprintf(stderr, "%s:  Unable to open %s.\n",
					argv[0], argv[2]);
				panic(OPEN);
			}
		}
		else
			out = stdout;
	}
	else
		in = stdin;

	header = writepcxheader(out);
	buffer = pcxalloc(header);
	getbuffer(buffer, header, in);
	packpcxfile(buffer, out, header);
}
Newsgroups: comp.sys.palmtops