SUN Raster to Postscript (update)
John Cristy
cristy at eplrx7.uucp
Sat Jun 8 01:47:04 AEST 1991
Someone suggested that SUNtoPS should have the image fill the Postscript
page. So here it is:
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% 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 PageLeftMargin 16
#define PageTopMargin 92
#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_factor.",
" % 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
delta_x,
delta_y,
x,
y;
register RunlengthPacket
*p;
register int
i,
j;
unsigned int
height,
width;
unsigned long
scale_factor;
/*
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);
}
/*
Scale image to size of Postscript page.
*/
scale_factor=((PageWidth-(2*PageLeftMargin)) << 14)/image->columns;
if (scale_factor > (((PageHeight-(2*PageTopMargin)) << 14)/image->rows))
scale_factor=((PageHeight-(2*PageTopMargin)) << 14)/image->rows;
width=(image->columns*scale_factor+8191) >> 14;
height=(image->rows*scale_factor+8191) >> 14;
/*
Center image on Postscript page.
*/
delta_x=PageWidth-(width+(2*PageLeftMargin));
delta_y=PageHeight-(height+(2*PageTopMargin));
if (delta_x >= 0)
x=delta_x/2+PageLeftMargin;
else
x=PageLeftMargin;
if (delta_y >= 0)
y=delta_y/2+PageTopMargin;
else
y=PageTopMargin;
/*
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 number_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
More information about the Alt.sources
mailing list