cristy@eplrx7.uucp (John Cristy) (06/05/91)
SUN raster to Postscript... /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % IIIII M M PPPP OOO RRRR TTTTT % % I MM MM P P O O R R T % % I M M M PPPP O O RRRR T % % I M M P O O R R T % % IIIII M M P OOO R R T % % % % % % Import SUN raster image to Encapsulated Postscript format. % % % % % % % % Software Design % % John Cristy % % January 1991 % % % % % % Copyright 1991 E. I. Dupont de Nemours & Company % % % % Permission to use, copy, modify, distribute, and sell this software and % % its documentation for any purpose is hereby granted without fee, % % provided that the above Copyright notice appear in all copies and that % % both that Copyright notice and this permission notice appear in % % supporting documentation, and that the name of E. I. Dupont de Nemours % % & Company not be used in advertising or publicity pertaining to % % distribution of the software without specific, written prior % % permission. E. I. Dupont de Nemours & Company makes no representations % % about the suitability of this software for any purpose. It is provided % % "as is" without express or implied warranty. % % % % E. I. Dupont de Nemours & Company disclaims all warranties with regard % % to this software, including all implied warranties of merchantability % % and fitness, in no event shall E. I. Dupont de Nemours & Company be % % liable for any special, indirect or consequential damages or any % % damages whatsoever resulting from loss of use, data or profits, whether % % in an action of contract, negligence or other tortious action, arising % % out of or in connection with the use or performance of this software. % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Command syntax: % % import [-scene #] image.sun image.ps % % Specify 'image.sun' as '-' for standard input. % Specify 'image.ps' as '-' for standard output. % % */ /* Include declarations */ #include <stdio.h> #include <ctype.h> #include <math.h> #ifdef __STDC__ #include <stdlib.h> #else #ifndef vms #include <malloc.h> #include <memory.h> extern long strtol(), time(); #endif #endif /* Define declarations for the Display program. */ #define False 0 #define Intensity(color) \ (((color).red*77+(color).green*150+(color).blue*29) >> 8) #define Max(x,y) (((x) > (y)) ? (x) : (y)) #define MaxColormapSize 65535 #define MaxImageSize (4096*4096) #define MaxRgb 255 #define MaxRunlength 255 #define Min(x,y) (((x) < (y)) ? (x) : (y)) #define MinInfoSize (1 << 18) #define True 1 #define Warning(message,qualifier) \ { \ (void) fprintf(stderr,"%s: %s",application_name,message); \ if (qualifier != (char *) NULL) \ (void) fprintf(stderr," (%s)",qualifier); \ (void) fprintf(stderr,".\n"); \ } /* Image Id's */ #define UnknownId 0 #define ImageMagickId 1 /* Image classes: */ #define UnknownClass 0 #define DirectClass 1 #define PseudoClass 2 /* Image compression algorithms: */ #define UnknownCompression 0 #define NoCompression 1 #define RunlengthEncodedCompression 2 #define QEncodedCompression 3 /* Typedef declarations for the Display program. */ typedef struct _ColorPacket { unsigned char red, green, blue; unsigned short index; } ColorPacket; typedef struct _RunlengthPacket { unsigned char red, green, blue, length; unsigned short index; } RunlengthPacket; typedef struct _Image { FILE *file; char filename[256]; char *comments; unsigned int id, class, compression, columns, rows; unsigned int colors; ColorPacket *colormap; unsigned int packets, runlength; RunlengthPacket *pixels; unsigned int scene; } Image; /* Variable declarations. */ char *application_name; /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % E r r o r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function Error displays an error message and then terminates the program. % % The format of the Error routine is: % % Error(message,qualifier) % % A description of each parameter follows: % % o message: Specifies the message to display before terminating the % program. % % o qualifier: Specifies any qualifier to the message. % % */ void Error(message,qualifier) char *message, *qualifier; { (void) fprintf(stderr,"%s: %s",application_name,message); if (qualifier != (char *) NULL) (void) fprintf(stderr," %s",qualifier); (void) fprintf(stderr,".\n"); exit(1); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % M S B F i r s t O r d e r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function MSBFirstOrder converts a least-significant byte first buffer of % integers to most-significant byte first. % % The format of the MSBFirstOrder routine is: % % MSBFirstOrder(p,length); % % A description of each parameter follows. % % o p: Specifies a pointer to a buffer of integers. % % o length: Specifies the length of the buffer. % % */ MSBFirstOrder(p,length) register char *p; register unsigned length; { register char c, *q, *sp; q=p+length; while (p < q) { sp=p+3; c=(*sp); *sp=(*p); *p++=c; sp=p+1; c=(*sp); *sp=(*p); *p++=c; p+=2; } } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % P r i n t I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function PrintImage translates a MIFF image to encapsulated Postscript for % printing. If the supplied geometry is null, the image is centered on the % Postscript page. Otherwise, the image is positioned as specified by the % geometry. % % The format of the PrintImage routine is: % % status=PrintImage(image) % % A description of each parameter follows: % % o status: Function PrintImage return True if the image is printed. % False is returned if the image file cannot be opened for printing. % % o image: The address of a structure of type Image; returned from % ReadImage. % % */ unsigned int PrintImage(image) Image *image; { #define PageBottomMargin 92 #define PageLeftMargin 16 #define PageWidth 612 #define PageHeight 792 static char *Postscript[]= { "%", "% Display a color image. The image is displayed in color on", "% Postscript viewers or printers that support color, otherwise", "% it is displayed as grayscale.", "%", "/buffer 512 string def", "/byte 1 string def", "/color_packet 3 string def", "/compression 1 string def", "/gray_packet 1 string def", "/pixels 768 string def", "", "/DirectClassPacket", "{", " %", " % Get a DirectClass packet.", " %", " % Parameters: ", " % red.", " % green.", " % blue.", " % length: number of pixels minus one of this color (optional).", " %", " currentfile color_packet readhexstring pop pop", " compression 0 gt", " {", " /number_pixels 3 def", " }", " {", " currentfile byte readhexstring pop 0 get", " /number_pixels exch 1 add 3 mul def", " } ifelse", " 0 3 number_pixels 1 sub", " {", " pixels exch color_packet putinterval", " } for", " pixels 0 number_pixels getinterval", "} bind def", "", "/DirectClassImage", "{", " %", " % Display a DirectClass image.", " %", " systemdict /colorimage known", " {", " columns rows 8", " [", " columns 0 0", " rows neg 0 rows", " ]", " { DirectClassPacket } false 3 colorimage", " }", " {", " %", " % No colorimage operator; convert to grayscale.", " %", " columns rows 8", " [", " columns 0 0", " rows neg 0 rows", " ]", " { GrayDirectClassPacket } image", " } ifelse", "} bind def", "", "/GrayDirectClassPacket", "{", " %", " % Get a DirectClass packet; convert to grayscale.", " %", " % Parameters: ", " % red", " % green", " % blue", " % length: number of pixels minus one of this color (optional).", " %", " currentfile color_packet readhexstring pop pop", " color_packet 0 get 0.299 mul", " color_packet 1 get 0.587 mul add", " color_packet 2 get 0.114 mul add", " cvi", " /gray_packet exch def", " compression 0 gt", " {", " /number_pixels 1 def", " }", " {", " currentfile byte readhexstring pop 0 get", " /number_pixels exch 1 add def", " } ifelse", " 0 1 number_pixels 1 sub", " {", " pixels exch gray_packet put", " } for", " pixels 0 number_pixels getinterval", "} bind def", "", "/GrayPseudoClassPacket", "{", " %", " % Get a PseudoClass packet; convert to grayscale.", " %", " % Parameters: ", " % index: index into the colormap.", " % length: number of pixels minus one of this color (optional).", " %", " currentfile byte readhexstring pop 0 get", " /offset exch 3 mul def", " /color_packet colormap offset 3 getinterval def", " color_packet 0 get 0.299 mul", " color_packet 1 get 0.587 mul add", " color_packet 2 get 0.114 mul add", " cvi", " /gray_packet exch def", " compression 0 gt", " {", " /number_pixels 1 def", " }", " {", " currentfile byte readhexstring pop 0 get", " /number_pixels exch 1 add def", " } ifelse", " 0 1 number_pixels 1 sub", " {", " pixels exch gray_packet put", " } for", " pixels 0 number_pixels getinterval", "} bind def", "", "/PseudoClassPacket", "{", " %", " % Get a PseudoClass packet.", " %", " % Parameters: ", " % index: index into the colormap.", " % length: number of pixels minus one of this color (optional).", " %", " %", " currentfile byte readhexstring pop 0 get", " /offset exch 3 mul def", " /color_packet colormap offset 3 getinterval def", " compression 0 gt", " {", " /number_pixels 3 def", " }", " {", " currentfile byte readhexstring pop 0 get", " /number_pixels exch 1 add 3 mul def", " } ifelse", " 0 3 number_pixels 1 sub", " {", " pixels exch color_packet putinterval", " } for", " pixels 0 number_pixels getinterval", "} bind def", "", "/PseudoClassImage", "{", " %", " % Display a PseudoClass image.", " %", " % Parameters: ", " % colors: number of colors in the colormap.", " % colormap: red, green, blue color packets.", " %", " currentfile buffer readline pop", " token pop /colors exch def pop", " /colors colors 3 mul def", " /colormap colors string def", " currentfile colormap readhexstring pop pop", " systemdict /colorimage known", " {", " columns rows 8", " [", " columns 0 0", " rows neg 0 rows", " ]", " { PseudoClassPacket } false 3 colorimage", " }", " {", " %", " % No colorimage operator; convert to grayscale.", " %", " columns rows 8", " [", " columns 0 0", " rows neg 0 rows", " ]", " { GrayPseudoClassPacket } image", " } ifelse", "} bind def", "", "/DisplayImage", "{", " %", " % Display a DirectClass or PseudoClass image.", " %", " % Parameters: ", " % x & y translation.", " % x & y scale.", " % image columns & rows.", " % class: 0-DirectClass or 1-PseudoClass.", " % compression: 0-RunlengthEncodedCompression or 1-NoCompression.", " % hex color packets.", " %", " gsave", " currentfile buffer readline pop", " token pop /x exch def", " token pop /y exch def pop", " x y translate", " currentfile buffer readline pop", " token pop /x exch def", " token pop /y exch def pop", " x y scale", " currentfile buffer readline pop", " token pop /columns exch def", " token pop /rows exch def pop", " currentfile buffer readline pop", " token pop /class exch def pop", " currentfile buffer readline pop", " token pop /compression exch def pop", " class 0 gt { PseudoClassImage } { DirectClassImage } ifelse", " grestore", " showpage", "} bind def", "", "DisplayImage", NULL }; char **q; int center, x, y; register RunlengthPacket *p; register int i, j; unsigned int height, width; /* Open output image file. */ if (*image->filename == '-') image->file=stdout; else image->file=fopen(image->filename,"w"); if (image->file == (FILE *) NULL) { (void) fprintf(stderr,"%s: unable to print image, cannot open %s.\n", application_name,image->filename); return(False); } width=image->columns; height=image->rows; center=True; if (center) { int delta_x, delta_y; unsigned long scale; /* Center image on Postscript page. */ if (width > (PageWidth-(2*PageLeftMargin))) { scale=((PageWidth-(2*PageLeftMargin)) << 14)/width; width=(width*scale) >> 14; height=(height*scale) >> 14; } if (height > (PageHeight-(2*PageBottomMargin))) { scale=((PageHeight-(2*PageBottomMargin)) << 14)/height; width=(width*scale) >> 14; height=(height*scale) >> 14; } delta_x=PageWidth-(width+(2*PageLeftMargin)); delta_y=PageHeight-(height+(2*PageBottomMargin)); if (delta_x >= 0) x=delta_x/2+PageLeftMargin; else x=PageLeftMargin; if (delta_y >= 0) y=delta_y/2+PageBottomMargin; else y=PageBottomMargin; } /* Output encapsulated Postscript header. */ (void) fprintf(image->file,"%%!PS-Adobe-2.0 EPSF-2.0\n"); (void) fprintf(image->file,"%%%%BoundingBox: %d %d %d %d\n",x,y,x+width, y+height); (void) fprintf(image->file,"%%%%Creator: ImageMagick\n"); (void) fprintf(image->file,"%%%%Title: %s\n",image->filename); (void) fprintf(image->file,"%%%%EndComments\n"); /* Output encapsulated Postscript commands. */ for (q=Postscript; *q; q++) (void) fprintf(image->file,"%s\n",*q); /* Output image data. */ (void) fprintf(image->file,"%d %d\n%d %d\n%d %d\n%d\n%d\n",x,y,width,height, image->columns,image->rows,(image->class == PseudoClass), image->compression == NoCompression); x=0; p=image->pixels; switch (image->class) { case DirectClass: { switch (image->compression) { case RunlengthEncodedCompression: default: { /* Dump runlength-encoded DirectColor packets. */ for (i=0; i < image->packets; i++) { x++; (void) fprintf(image->file,"%02x%02x%02x%02x",p->red,p->green, p->blue,p->length); if (x == 9) { x=0; (void) fprintf(image->file,"\n"); } p++; } break; } case NoCompression: { /* Dump DirectColor packets. */ for (i=0; i < image->packets; i++) { for (j=0; j <= p->length; j++) { x++; (void) fprintf(image->file,"%02x%02x%02x",p->red,p->green, p->blue); if (x == 12) { x=0; (void) fprintf(image->file,"\n"); } } p++; } break; } } break; } case PseudoClass: { /* Dump number of colors, colormap, PseudoColor packets. */ (void) fprintf(image->file,"%d\n",image->colors); for (i=0; i < image->colors; i++) (void) fprintf(image->file,"%02x%02x%02x\n",image->colormap[i].red, image->colormap[i].green,image->colormap[i].blue); switch (image->compression) { case RunlengthEncodedCompression: default: { for (i=0; i < image->packets; i++) { x++; (void) fprintf(image->file,"%02x%02x",p->index,p->length); if (x == 18) { x=0; (void) fprintf(image->file,"\n"); } p++; } break; } case NoCompression: { for (i=0; i < image->packets; i++) { for (j=0; j <= p->length; j++) { x++; (void) fprintf(image->file,"%02x",p->index); if (x == 36) { x=0; (void) fprintf(image->file,"\n"); } } p++; } } break; } } } (void) fprintf(image->file,"\n\n"); (void) fprintf(image->file,"%%%%Trailer\n"); if (image->file != stdin) (void) fclose(image->file); return(True); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d D a t a % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function ReadData reads data from the image file and returns it. If it % cannot read the requested number of items, False is returned indicating % an error. % % The format of the ReadData routine is: % % status=ReadData(data,size,number_items,file) % % A description of each parameter follows: % % o status: Function ReadData returns True if all the data requested % is obtained without error, otherwise False. % % o data: Specifies an area to place the information reuested from % the file. % % o size: Specifies an integer representing the length of an % individual item to be read from the file. % % o numer_items: Specifies an integer representing the number of items % to read from the file. % % o file: Specifies a file to read the data. % % */ unsigned int ReadData(data,size,number_items,file) char *data; int size, number_items; FILE *file; { size*=number_items; while (size > 0) { number_items=fread(data,1,size,file); if (number_items <= 0) return(False); size-=number_items; data+=number_items; } return(True); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d S U N I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function ReadSUNImage reads an image file and returns it. It allocates % the memory necessary for the new Image structure and returns a pointer to % the new image. % % The format of the ReadSUNImage routine is: % % image=ReadSUNImage(filename) % % A description of each parameter follows: % % o image: Function ReadSUNImage returns a pointer to the image after % reading. A null image is returned if there is a a memory shortage or % if the image cannot be read. % % o filename: Specifies the name of the image to read. % % */ static Image *ReadSUNImage(filename) char *filename; { #define RMT_EQUAL_RGB 1 #define RMT_NONE 0 #define RMT_RAW 2 #define RT_STANDARD 1 #define RT_ENCODED 2 #define RT_FORMAT_RGB 3 typedef struct _Rasterfile { int magic, width, height, depth, length, type, maptype, maplength; } Rasterfile; Image *image; Rasterfile sun_header; register int bit, i, x, y; register RunlengthPacket *q; register unsigned char *p; unsigned char blue, green, red, *sun_data, *sun_pixels; unsigned long lsb_first; unsigned short index; /* Allocate image structure. */ image=(Image *) malloc(sizeof(Image)); if (image == (Image *) NULL) Error("memory allocation error",(char *) NULL); /* Initialize Image structure. */ image->id=UnknownId; image->class=DirectClass; image->compression=RunlengthEncodedCompression; image->columns=0; image->rows=0; image->packets=0; image->colors=0; image->scene=0; image->colormap=(ColorPacket *) NULL; image->pixels=(RunlengthPacket *) NULL; image->comments=(char *) NULL; /* Open image file. */ (void) strcpy(image->filename,filename); if (*image->filename == '-') image->file=stdin; else if (strcmp(image->filename+strlen(image->filename)-2,".Z") != 0) image->file=fopen(image->filename,"r"); else { char command[256]; /* Image file is compressed-- uncompress it. */ (void) sprintf(command,"uncompress -c %s",image->filename); image->file=(FILE *) popen(command,"r"); } if (image->file == (FILE *) NULL) Error("unable to open file",image->filename); /* Read raster image. */ (void) ReadData((char *) &sun_header,1,sizeof(Rasterfile),image->file); /* Ensure the header byte-order is most-significant byte first. */ lsb_first=1; if (*(char *) &lsb_first) MSBFirstOrder((char *) &sun_header,sizeof(sun_header)); if (sun_header.magic != 0x59a66a95) Error("not a SUN raster,",image->filename); switch (sun_header.maptype) { case RMT_NONE: { if (sun_header.depth < 24) { /* Create linear color ramp. */ image->colors=1 << sun_header.depth; image->colormap=(ColorPacket *) malloc(image->colors*sizeof(ColorPacket)); if (image->colormap == (ColorPacket *) NULL) Error("memory allocation error",(char *) NULL); for (i=0; i < image->colors; i++) { image->colormap[i].red=(255*i)/(image->colors-1); image->colormap[i].green=(255*i)/(image->colors-1); image->colormap[i].blue=(255*i)/(image->colors-1); } } break; } case RMT_EQUAL_RGB: { unsigned char *sun_colormap; /* Read Sun raster colormap. */ image->colors=sun_header.maplength/3; image->colormap= (ColorPacket *) malloc(image->colors*sizeof(ColorPacket)); sun_colormap=(unsigned char *) malloc(image->colors*sizeof(unsigned char)); if ((image->colormap == (ColorPacket *) NULL) || (sun_colormap == (unsigned char *) NULL)) Error("memory allocation error",(char *) NULL); (void) ReadData((char *) sun_colormap,1,(int) image->colors,image->file); for (i=0; i < image->colors; i++) image->colormap[i].red=sun_colormap[i]; (void) ReadData((char *) sun_colormap,1,(int) image->colors,image->file); for (i=0; i < image->colors; i++) image->colormap[i].green=sun_colormap[i]; (void) ReadData((char *) sun_colormap,1,(int) image->colors,image->file); for (i=0; i < image->colors; i++) image->colormap[i].blue=sun_colormap[i]; (void) free((char *) sun_colormap); break; } case RMT_RAW: { unsigned char *sun_colormap; /* Read Sun raster colormap. */ sun_colormap=(unsigned char *) malloc((unsigned int) sun_header.maplength*sizeof(unsigned char)); if (sun_colormap == (unsigned char *) NULL) Error("memory allocation error",(char *) NULL); (void) ReadData((char *) sun_colormap,1,sun_header.maplength, image->file); (void) free((char *) sun_colormap); break; } default: { Error("colormap type is not supported",image->filename); break; } } sun_data=(unsigned char *) malloc((unsigned int) sun_header.length*sizeof(unsigned char)); if (sun_data == (unsigned char *) NULL) Error("memory allocation error",(char *) NULL); (void) ReadData((char *) sun_data,1,sun_header.length,image->file); sun_pixels=sun_data; if (sun_header.type == RT_ENCODED) { register int count, number_pixels; register unsigned char byte, *q; /* Read run-length encoded raster pixels. */ number_pixels=(sun_header.width+(sun_header.width % 2))* sun_header.height*(((sun_header.depth-1) >> 3)+1); sun_pixels=(unsigned char *) malloc((unsigned int) number_pixels*sizeof(unsigned char)); if (sun_pixels == (unsigned char *) NULL) Error("memory allocation error",(char *) NULL); p=sun_data; q=sun_pixels; while ((q-sun_pixels) <= number_pixels) { byte=(*p++); if (byte != 128) *q++=byte; else { /* Runlength-encoded packet: <count><byte> */ count=(*p++); if (count > 0) byte=(*p++); while (count >= 0) { *q++=byte; count--; } } } (void) free((char *) sun_data); } /* Create image. */ image->comments=(char *) malloc((unsigned int) (strlen(image->filename)+256)); if (image->comments == (char *) NULL) Error("memory allocation error",(char *) NULL); (void) sprintf(image->comments,"\n Imported from Sun raster image: %s\n\0", image->filename); image->class=(sun_header.depth < 24 ? PseudoClass : DirectClass); image->columns=sun_header.width; image->rows=sun_header.height; image->pixels=(RunlengthPacket *) malloc(image->columns*image->rows*sizeof(RunlengthPacket)); if (image->pixels == (RunlengthPacket *) NULL) Error("memory allocation error",(char *) NULL); /* Convert Sun raster image to runlength-encoded packets. */ p=sun_pixels; image->packets=0; q=image->pixels; q->length=MaxRunlength; if (sun_header.depth == 1) for (y=0; y < image->rows; y++) { /* Convert bitmap scanline to runlength-encoded color packets. */ for (x=0; x < (image->columns >> 3); x++) { for (bit=7; bit >= 0; bit--) { index=((*p) & (0x01 << bit) ? 0x00 : 0x01); red=image->colormap[index].red; green=image->colormap[index].green; blue=image->colormap[index].blue; if ((red == q->red) && (green == q->green) && (blue == q->blue) && (q->length < MaxRunlength)) q->length++; else { if (image->packets > 0) q++; image->packets++; q->red=red; q->green=green; q->blue=blue; q->index=index; q->length=0; } } p++; } if ((image->columns % 8) != 0) { for (bit=7; bit >= (8-(image->columns % 8)); bit--) { index=((*p) & (0x01 << bit) ? 0x00 : 0x01); red=image->colormap[index].red; green=image->colormap[index].green; blue=image->colormap[index].blue; if ((red == q->red) && (green == q->green) && (blue == q->blue) && (q->length < MaxRunlength)) q->length++; else { if (image->packets > 0) q++; image->packets++; q->red=red; q->green=green; q->blue=blue; q->index=index; q->length=0; } } p++; } } else if (image->class == PseudoClass) for (y=0; y < image->rows; y++) { /* Convert PseudoColor scanline to runlength-encoded color packets. */ for (x=0; x < image->columns; x++) { index=(*p++); red=image->colormap[index].red; green=image->colormap[index].green; blue=image->colormap[index].blue; if ((red == q->red) && (green == q->green) && (blue == q->blue) && (q->length < MaxRunlength)) q->length++; else { if (image->packets > 0) q++; image->packets++; q->red=red; q->green=green; q->blue=blue; q->index=index; q->length=0; } } if ((image->columns % 2) != 0) p++; } else for (y=0; y < image->rows; y++) { /* Convert DirectColor scanline to runlength-encoded color packets. */ for (x=0; x < image->columns; x++) { if (sun_header.type == RT_STANDARD) { blue=(*p++); green=(*p++); red=(*p++); } else { red=(*p++); green=(*p++); blue=(*p++); } if (image->colors > 0) { red=image->colormap[red].red; green=image->colormap[green].green; blue=image->colormap[blue].blue; } if ((red == q->red) && (green == q->green) && (blue == q->blue) && (q->length < MaxRunlength)) q->length++; else { if (image->packets > 0) q++; image->packets++; q->red=red; q->green=green; q->blue=blue; q->index=0; q->length=0; } } if ((image->columns % 2) != 0) p++; } (void) free((char *) sun_pixels); if (image->file != stdin) if (strcmp(image->filename+strlen(image->filename)-2,".Z") != 0) (void) fclose(image->file); else (void) pclose(image->file); if (image->packets > ((image->columns*image->rows*3) >> 2)) image->compression=NoCompression; image->pixels=(RunlengthPacket *) realloc((char *) image->pixels,image->packets*sizeof(RunlengthPacket)); return(image); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % U s a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Function Usage displays the program usage; % % The format of the Usage routine is: % % Usage(message) % % A description of each parameter follows: % % message: Specifies a specific message to display to the user. % */ static void Usage(message) char *message; { if (message != (char *) NULL) (void) fprintf(stderr,"Can't continue, %s\n\n",message); (void) fprintf(stderr,"Usage: %s [-scene #] image.sun image.ps\n\n", application_name); (void) fprintf(stderr,"Specify 'image.sun' as '-' for standard input.\n"); (void) fprintf(stderr,"Specify 'image.ps' as '-' for standard output.\n"); exit(1); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % M a i n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % */ int main(argc,argv) int argc; char *argv[]; { char filename[256]; Image *image; int i; unsigned int scene; /* Initialize program variables. */ application_name=argv[0]; i=1; scene=0; if (argc < 3) Usage((char *) NULL); /* Read image and convert to MIFF format. */ if (strncmp(argv[i],"-scene",2) == 0) { i++; scene=atoi(argv[i++]); } (void) strcpy(filename,argv[i++]); image=ReadSUNImage(filename); if (image == (Image *) NULL) exit(1); (void) strcpy(image->filename,argv[i++]); image->scene=scene; (void) PrintImage(image); (void) fprintf(stderr,"%s => %s %dx%d\n",filename,image->filename, image->columns,image->rows); return(False); } -- The UUCP Mailer