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