v01i053: pc-paintbrush - convert pc-paintbrush to sunraster format
Charles Mcgrew
mcgrew at dartagnan.rutgers.edu
Fri Jul 21 07:14:45 AEST 1989
Submitted-by: gfr at cobra.mitre.org (Glenn Roberts)
Posting-number: Volume 1, Issue 53
Archive-name: pc-paintbrush
[ I couldn't test this one out - but here it is. Note that this
is not a 'shar' format posting. -CWM ]
The program below converts PC-paintbrush images to Sun
rasterfile format. We've found this to be of some use
for creating images, logos, etc. Please feel free to place
this program in the Sun-Spots archives.
- Glenn Roberts, The MITRE Corp., McLean VA (703) 883-6820
gfr at cobra.mitre.org
=-=-=-=- cut here =-=-=-=-=-=
/*
** pcx2ras -- Convert PC Paintbrush files to Sun rasterfile format
**
** Version: 2.1
**
** Usage: pcx2ras [-d] [-e] [-t type] [input.pcx] [output.pr]
**
** Options:
**
** -d Display the pixrect before outputting to file (user
** must be in SunView).
**
** -e Shorthand for -t 2
**
** -t type Specify the type of rasterfile to write:
** 0 Old format files compatible with Release 1.1.
** 1 Standard format.
** 2 Run-length encoding of bytes.
** 65535 To experiment with private encodings.
**
** Authors:
** Glenn F. Roberts, 703-883-6820 (gfr at cobra.mitre.org)
** Frederick Kuhl, 703-883-7559 (fkuhl at amadeus.mitre.org)
** MITRE Corporation
** 7525 Colshire Drive, McLean VA 22102
**
** History:
**
** Version 1.0, 11 Aug 87 Frederick Kuhl
**
** This version handles only EGA images and it treats them as if
** they were monochrome; specifically, it converts only the first
** (red) plane of multiplane images and ignores the other planes.
** Pixels are converted to pixels (and negated). Coordinate systems
** of Paintbrush and Sun are the same. The rasterfile definition
** requires that each scan line be extended to an integral multiple
** of 16 bits. But the number of scan lines is the same.
**
** Version 2.0, 12 Aug 87 Glenn F. Roberts
**
** 1) Program now functions by converting paintbrush file into
** Sun pixrect form. This makes it easy to perform any
** pixrect operation on the image. Image can be displayed
** using Sun's screenload program.
** 2) Input can be either piped (stdin and stdout) or from
** command line file names.
** 3) Color is now supported. To obtain black and white image
** pipe the output of this program through rasfilter8to1.
**
** 4) Image can be previewed using -d switch.
**
** Version 2.1, 13 Aug 87 Glenn F. Roberts
**
** -t and -e switches added.
**
** Version 2.1.1, 6 Jan 89 Glenn F. Roberts
**
** added SWAB constant so can be compiled for 80386
** (previously hard-wired for 68000).
*/
#include <stdio.h>
#include <suntool/sunview.h>
#include <suntool/canvas.h>
#define COLORMAP_SIZE 16
/* define SWAB here for 68000 machines */
/* #define SWAB */
char *malloc();
/* This is the header for .PCX files */
struct pcx_hdr_st {
unsigned char manufacturer; /* mfg. code (ignore) */
unsigned char version; /* version should be 5 */
unsigned char encoding; /* should be 1 */
unsigned char bitsPerPix; /* 1 for EGA images */
short window [4]; /* xmin,ymin,xmax,ymax */
short hres; /* 640 for EGA */
short vres; /* 350 for EGA */
unsigned char colormap [48]; /* color map */
unsigned char reserved; /* reserved */
unsigned char nplanes; /* 4 for EGA */
short bytesPerLine; /* this IS used! */
short unused [30]; /* filler (to 128) */
} hdr;
int display, prtype;
FILE *fin, *fout;
main (argc, argv)
int argc;
char *argv[];
{
int i;
struct pixrect *picture, *pcx_load();
Frame frame;
Canvas canvas;
Pixwin *pw;
colormap_t prcolormap;
unsigned char red[COLORMAP_SIZE];
unsigned char green[COLORMAP_SIZE];
unsigned char blue[COLORMAP_SIZE];
/* set defaults for user-controlled arguments */
prtype = RT_STANDARD;
display = FALSE;
fin = stdin;
fout = stdout;
/* parse any command line arguments */
parse_arguments(argc, argv);
/* load pixrect from paintbrush file */
picture = pcx_load(fin, &hdr);
fprintf(stderr, "\nImage loaded... width = %d, height = %d\n",
picture->pr_size.x, picture->pr_size.y);
/* create corresponding Sun color maps */
for (i=0; i<COLORMAP_SIZE; i++) {
red[i] = hdr.colormap[i*3];
green[i] = hdr.colormap[i*3+1];
blue[i] = hdr.colormap[i*3+2];
}
prcolormap.type = RMT_EQUAL_RGB;
prcolormap.length = COLORMAP_SIZE;
prcolormap.map[0] = red;
prcolormap.map[1] = green;
prcolormap.map[2] = blue;
/* if requested, show image to user, then wait for user to 'quit' */
if (display) {
frame = window_create(NULL, FRAME,
WIN_WIDTH, picture->pr_size.x+10,
WIN_HEIGHT, picture->pr_size.y+25,
FRAME_LABEL, "Paintbrush",
0);
canvas = window_create(frame, CANVAS,
CANVAS_RETAINED, FALSE,
CANVAS_AUTO_EXPAND, TRUE,
CANVAS_AUTO_SHRINK, TRUE,
CANVAS_WIDTH, picture->pr_size.x,
CANVAS_HEIGHT, picture->pr_size.y,
0);
pw = canvas_pixwin(canvas);
pw_setcmsname(pw, "paint");
pw_putcolormap(pw, 0, COLORMAP_SIZE, red, green, blue);
window_set(canvas,
CANVAS_RETAINED, TRUE,
0);
pw_rop(pw, 0, 0, picture->pr_size.x, picture->pr_size.y, PIX_SRC,
picture, 0, 0);
window_main_loop(frame);
}
/* now write the pixrect output */
pr_dump(picture, fout, &prcolormap, prtype, prtype==RT_BYTE_ENCODED);
/* return normally */
exit(0);
}
/* parse_arguments -- parse command-line arguments (file names
** and switches).
*/
parse_arguments(argc, argv)
int argc;
char *argv[];
{
int nfiles;
nfiles = 0;
while (--argc > 0) {
++argv;
if ((*argv)[0] == '-')
/* process switches */
switch ((*argv)[1]) {
case 'd':
display = TRUE;
break;
case 'e':
prtype = RT_BYTE_ENCODED;
break;
case 't':
prtype = atoi(*++argv);
--argc;
break;
}
else
/* process file names */
switch (nfiles) {
case 0:
if ((fin = fopen(*argv, "r")) == NULL) {
fprintf(stderr, "Error opening input file\n");
exit(1);
}
nfiles++;
break;
case 1:
if ((fout = fopen(*argv, "w")) == NULL) {
fprintf(stderr, "Error opening output file\n");
exit(1);
}
nfiles++;
break;
}
}
}
/* pcx_load -- Load paintbrush file into memory pixrect
** (similar to SunView pr_load() routine).
*/
struct pixrect *pcx_load(input, hdr)
FILE *input;
struct pcx_hdr_st *hdr;
{
int width, height, depth, byte, col, row, i;
int value;
struct pixrect *pr;
char *buff0, *buff1, *buff2, *buff3;
char byte0, byte1, byte2, byte3;
/* first load the paintbrush header */
pcx_load_header(input, hdr);
width = hdr->window[2] - hdr->window[0] + 1;
height = hdr->window[3] - hdr->window[1] + 1;
depth = 8;
/* create a memory pixrect to store the image */
pr = mem_create(width, height, depth);
/* allocate line buffers for 4 planes */
buff0 = malloc (hdr->bytesPerLine);
buff1 = malloc (hdr->bytesPerLine);
buff2 = malloc (hdr->bytesPerLine);
buff3 = malloc (hdr->bytesPerLine);
/* process each PCX scan line */
fprintf(stderr, "\nConverting image ...");
for (row = 0; row < height; row++) {
get_line(input, buff0, hdr->bytesPerLine);
get_line(input, buff1, hdr->bytesPerLine);
get_line(input, buff2, hdr->bytesPerLine);
get_line(input, buff3, hdr->bytesPerLine);
for (byte=0; byte<hdr->bytesPerLine; byte++) {
byte0 = buff0[byte];
byte1 = buff1[byte];
byte2 = buff2[byte];
byte3 = buff3[byte];
for (col=byte*8+7, i=7; i>=0; i--) {
value = ((byte3 & 0x01) << 3) +
((byte2 & 0x01) << 2) +
((byte1 & 0x01) << 1) +
(byte0 & 0x01);
if (col < width)
pr_put(pr, col--, row, value);
byte0 >>= 1;
byte1 >>= 1;
byte2 >>= 1;
byte3 >>= 1;
}
}
}
free(buff0);
free(buff1);
free(buff2);
free(buff3);
return pr;
}
/* get_line -- Get a scan line from paintbrush file
*/
get_line(input, buffer, len)
FILE *input;
char *buffer;
int len;
{
int i, aByte;
for (i=0; i<len; ++i) {
if ((aByte = encgetc(input)) == EOF) {
fprintf(stderr, "Unexpected EOF\n");
exit (1);
}
*buffer++ = aByte;
}
}
/* pcx_load_header -- Load header from a paintbrush file
** (similar to SunView pr_load_header() routine).
*/
pcx_load_header(input, hdr)
FILE *input;
struct pcx_hdr_st *hdr;
{
fread (hdr, sizeof(struct pcx_hdr_st), 1, input);
#ifdef SWAB
/* byte order is reversed between 8088 and 68000: */
swab (hdr->window, hdr->window, 8);
swab (&hdr->hres, &hdr->hres, 2);
swab (&hdr->vres, &hdr->vres, 2);
swab (&hdr->bytesPerLine, &hdr->bytesPerLine, 2);
#endif
fprintf (stderr,"\n*** Header Information:\n\n");
fprintf (stderr,"mfg. code: %d\n", hdr->manufacturer);
fprintf (stderr,"version: %d\n", hdr->version);
fprintf (stderr,"encoding: %d\n", hdr->encoding);
fprintf (stderr,"bits per pixel: %d\n", hdr->bitsPerPix);
fprintf (stderr,"window: %d %d %d %d\n", hdr->window[0],
hdr->window[1],
hdr->window[2],
hdr->window[3]);
fprintf (stderr,"horiz. resolution: %d\n", hdr->hres);
fprintf (stderr,"vert. resolution: %d\n", hdr->vres);
fprintf (stderr,"number of planes: %d\n", hdr->nplanes);
fprintf (stderr,"bytes per line: %d\n", hdr->bytesPerLine);
}
/* encgetc -- Return next encoded picture byte from input
** crack the run-length encoding
*/
encgetc (input)
FILE *input;
{
static int theByte, count = 0;
int next;
if (count > 0) {
--count;
return theByte;
} else {
if ((next=getc(input)) == EOF)
return EOF;
if ((next & 0xC0) == 0xC0) {
count = ((int)next & 0x003F) - 1;
if ((next=getc(input)) == EOF) {
fprintf (stderr, "read failed\n");
exit (1);
}
theByte = next;
return theByte;
} else
return next;
}
}
More information about the Comp.sources.sun
mailing list