home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3441 < prev    next >
Encoding:
Internet Message Format  |  1991-06-05  |  37.5 KB

  1. From: cristy@eplrx7.uucp (John Cristy)
  2. Newsgroups: alt.sources
  3. Subject: SUNtoPS
  4. Message-ID: <1991Jun5.020356.7315@eplrx7.uucp>
  5. Date: 5 Jun 91 02:03:56 GMT
  6.  
  7. SUN raster to Postscript... 
  8.  
  9. /*
  10. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  11. %                                                                             %
  12. %                                                                             %
  13. %                                                                             %
  14. %                 IIIII  M   M  PPPP    OOO   RRRR    TTTTT                   %
  15. %                   I    MM MM  P   P  O   O  R   R     T                     %
  16. %                   I    M M M  PPPP   O   O  RRRR      T                     %
  17. %                   I    M   M  P      O   O  R R       T                     %
  18. %                 IIIII  M   M  P       OOO   R  R      T                     % 
  19. %                                                                             %
  20. %                                                                             %
  21. %         Import SUN raster image to Encapsulated Postscript format.          %
  22. %                                                                             %
  23. %                                                                             %
  24. %                                                                             %
  25. %                           Software Design                                   %
  26. %                             John Cristy                                     %
  27. %                            January  1991                                    %
  28. %                                                                             %
  29. %                                                                             %
  30. %  Copyright 1991 E. I. Dupont de Nemours & Company                           %
  31. %                                                                             %
  32. %  Permission to use, copy, modify, distribute, and sell this software and    %
  33. %  its documentation for any purpose is hereby granted without fee,           %
  34. %  provided that the above Copyright notice appear in all copies and that     %
  35. %  both that Copyright notice and this permission notice appear in            %
  36. %  supporting documentation, and that the name of E. I. Dupont de Nemours     %
  37. %  & Company not be used in advertising or publicity pertaining to            %
  38. %  distribution of the software without specific, written prior               %
  39. %  permission.  E. I. Dupont de Nemours & Company makes no representations    %
  40. %  about the suitability of this software for any purpose.  It is provided    %
  41. %  "as is" without express or implied warranty.                               %
  42. %                                                                             %
  43. %  E. I. Dupont de Nemours & Company disclaims all warranties with regard     %
  44. %  to this software, including all implied warranties of merchantability      %
  45. %  and fitness, in no event shall E. I. Dupont de Nemours & Company be        %
  46. %  liable for any special, indirect or consequential damages or any           %
  47. %  damages whatsoever resulting from loss of use, data or profits, whether    %
  48. %  in an action of contract, negligence or other tortious action, arising     %
  49. %  out of or in connection with the use or performance of this software.      %
  50. %                                                                             %
  51. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  52. %  Command syntax:
  53. %
  54. %  import [-scene #] image.sun image.ps
  55. %  
  56. %  Specify 'image.sun' as '-' for standard input.  
  57. %  Specify 'image.ps' as '-' for standard output.
  58. %  
  59. %
  60. */
  61.  
  62. /*
  63.   Include declarations
  64. */
  65. #include <stdio.h>
  66. #include <ctype.h>
  67. #include <math.h>
  68. #ifdef __STDC__
  69. #include <stdlib.h>
  70. #else
  71. #ifndef vms
  72. #include <malloc.h>
  73. #include <memory.h>
  74.  
  75. extern long
  76.   strtol(),
  77.   time();
  78. #endif
  79. #endif
  80.  
  81. /*
  82.   Define declarations for the Display program.
  83. */
  84. #define False  0
  85. #define Intensity(color)  \
  86.   (((color).red*77+(color).green*150+(color).blue*29) >> 8)
  87. #define Max(x,y)  (((x) > (y)) ? (x) : (y))
  88. #define MaxColormapSize  65535
  89. #define MaxImageSize  (4096*4096)
  90. #define MaxRgb  255
  91. #define MaxRunlength  255
  92. #define Min(x,y)  (((x) < (y)) ? (x) : (y))
  93. #define MinInfoSize (1 << 18)
  94. #define True  1
  95. #define Warning(message,qualifier)  \
  96. {  \
  97.   (void) fprintf(stderr,"%s: %s",application_name,message);  \
  98.   if (qualifier != (char *) NULL)  \
  99.     (void) fprintf(stderr," (%s)",qualifier);  \
  100.   (void) fprintf(stderr,".\n");  \
  101. }
  102.  
  103. /*
  104.   Image Id's
  105. */
  106. #define UnknownId  0
  107. #define ImageMagickId  1
  108. /*
  109.   Image classes:
  110. */
  111. #define UnknownClass  0
  112. #define DirectClass  1
  113. #define PseudoClass  2
  114. /*
  115.   Image compression algorithms:
  116. */
  117. #define UnknownCompression  0
  118. #define NoCompression  1
  119. #define RunlengthEncodedCompression  2
  120. #define QEncodedCompression  3
  121.  
  122. /*
  123.   Typedef declarations for the Display program.
  124. */
  125. typedef struct _ColorPacket
  126. {
  127.   unsigned char
  128.     red,
  129.     green,
  130.     blue;
  131.  
  132.   unsigned short
  133.     index;
  134. } ColorPacket;
  135.  
  136. typedef struct _RunlengthPacket
  137. {
  138.   unsigned char
  139.     red,
  140.     green,
  141.     blue,
  142.     length;
  143.  
  144.   unsigned short
  145.     index;
  146. } RunlengthPacket;
  147.  
  148. typedef struct _Image
  149. {
  150.   FILE
  151.     *file;
  152.  
  153.   char
  154.     filename[256];
  155.  
  156.   char
  157.     *comments;
  158.  
  159.   unsigned int
  160.     id,
  161.     class,
  162.     compression,
  163.     columns,
  164.     rows;
  165.  
  166.   unsigned int
  167.     colors;
  168.  
  169.   ColorPacket
  170.     *colormap;
  171.  
  172.   unsigned int
  173.     packets,
  174.     runlength;
  175.  
  176.   RunlengthPacket
  177.     *pixels;
  178.  
  179.   unsigned int
  180.     scene;
  181. } Image;
  182.  
  183. /*
  184.   Variable declarations.
  185. */
  186. char
  187.   *application_name;
  188.  
  189. /*
  190. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  191. %                                                                             %
  192. %                                                                             %
  193. %                                                                             %
  194. %   E r r o r                                                                 %
  195. %                                                                             %
  196. %                                                                             %
  197. %                                                                             %
  198. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  199. %
  200. %  Function Error displays an error message and then terminates the program.
  201. %
  202. %  The format of the Error routine is:
  203. %
  204. %      Error(message,qualifier)
  205. %
  206. %  A description of each parameter follows:
  207. %
  208. %    o message:  Specifies the message to display before terminating the
  209. %      program.
  210. %
  211. %    o qualifier:  Specifies any qualifier to the message.
  212. %
  213. %
  214. */
  215. void Error(message,qualifier)
  216. char
  217.   *message,
  218.   *qualifier;
  219. {
  220.   (void) fprintf(stderr,"%s: %s",application_name,message); 
  221.   if (qualifier != (char *) NULL)
  222.     (void) fprintf(stderr," %s",qualifier);
  223.   (void) fprintf(stderr,".\n");
  224.   exit(1);
  225. }
  226.  
  227. /*
  228. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  229. %                                                                             %
  230. %                                                                             %
  231. %                                                                             %
  232. %  M S B F i r s t O r d e r                                                  %
  233. %                                                                             %
  234. %                                                                             %
  235. %                                                                             %
  236. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  237. %
  238. %  Function MSBFirstOrder converts a least-significant byte first buffer of
  239. %  integers to most-significant byte first.
  240. %
  241. %  The format of the MSBFirstOrder routine is:
  242. %
  243. %       MSBFirstOrder(p,length);
  244. %
  245. %  A description of each parameter follows.
  246. %
  247. %   o  p:  Specifies a pointer to a buffer of integers.
  248. %
  249. %   o  length:  Specifies the length of the buffer.
  250. %
  251. %
  252. */
  253. MSBFirstOrder(p,length)
  254. register char 
  255.   *p;
  256.  
  257. register unsigned 
  258.   length;
  259. {
  260.   register char 
  261.     c,
  262.     *q,
  263.     *sp;
  264.  
  265.   q=p+length;
  266.   while (p < q) 
  267.   {
  268.     sp=p+3;
  269.     c=(*sp);
  270.     *sp=(*p);
  271.     *p++=c;
  272.     sp=p+1;
  273.     c=(*sp);
  274.     *sp=(*p);
  275.     *p++=c;
  276.     p+=2;
  277.   }
  278. }
  279.  
  280. /*
  281. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  282. %                                                                             %
  283. %                                                                             %
  284. %                                                                             %
  285. %   P r i n t I m a g e                                                       %
  286. %                                                                             %
  287. %                                                                             %
  288. %                                                                             %
  289. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  290. %
  291. %  Function PrintImage translates a MIFF image to encapsulated Postscript for
  292. %  printing.  If the supplied geometry is null, the image is centered on the
  293. %  Postscript page.  Otherwise, the image is positioned as specified by the
  294. %  geometry.
  295. %
  296. %  The format of the PrintImage routine is:
  297. %
  298. %      status=PrintImage(image)
  299. %
  300. %  A description of each parameter follows:
  301. %
  302. %    o status: Function PrintImage return True if the image is printed.
  303. %      False is returned if the image file cannot be opened for printing.
  304. %
  305. %    o image: The address of a structure of type Image;  returned from
  306. %      ReadImage.
  307. %
  308. %
  309. */
  310. unsigned int PrintImage(image)
  311. Image
  312.   *image;
  313. {
  314. #define PageBottomMargin 92
  315. #define PageLeftMargin 16
  316. #define PageWidth  612
  317. #define PageHeight 792
  318.  
  319.   static char
  320.     *Postscript[]=
  321.     {
  322.       "%",
  323.       "% Display a color image.  The image is displayed in color on",
  324.       "% Postscript viewers or printers that support color, otherwise",
  325.       "% it is displayed as grayscale.",
  326.       "%",
  327.       "/buffer 512 string def",
  328.       "/byte 1 string def",
  329.       "/color_packet 3 string def",
  330.       "/compression 1 string def",
  331.       "/gray_packet 1 string def",
  332.       "/pixels 768 string def",
  333.       "",
  334.       "/DirectClassPacket",
  335.       "{",
  336.       "  %",
  337.       "  % Get a DirectClass packet.",
  338.       "  %",
  339.       "  % Parameters: ",
  340.       "  %   red.",
  341.       "  %   green.",
  342.       "  %   blue.",
  343.       "  %   length: number of pixels minus one of this color (optional).",
  344.       "  %",
  345.       "  currentfile color_packet readhexstring pop pop",
  346.       "  compression 0 gt",
  347.       "  {",
  348.       "    /number_pixels 3 def",
  349.       "  }",
  350.       "  {",
  351.       "    currentfile byte readhexstring pop 0 get",
  352.       "    /number_pixels exch 1 add 3 mul def",
  353.       "  } ifelse",
  354.       "  0 3 number_pixels 1 sub",
  355.       "  {",
  356.       "    pixels exch color_packet putinterval",
  357.       "  } for",
  358.       "  pixels 0 number_pixels getinterval",
  359.       "} bind def",
  360.       "",
  361.       "/DirectClassImage",
  362.       "{",
  363.       "  %",
  364.       "  % Display a DirectClass image.",
  365.       "  %",
  366.       "  systemdict /colorimage known",
  367.       "  {",
  368.       "    columns rows 8",
  369.       "    [",
  370.       "      columns 0 0",
  371.       "      rows neg 0 rows",
  372.       "    ]",
  373.       "    { DirectClassPacket } false 3 colorimage",
  374.       "  }",
  375.       "  {",
  376.       "    %",
  377.       "    % No colorimage operator;  convert to grayscale.",
  378.       "    %",
  379.       "    columns rows 8",
  380.       "    [",
  381.       "      columns 0 0",
  382.       "      rows neg 0 rows",
  383.       "    ]",
  384.       "    { GrayDirectClassPacket } image",
  385.       "  } ifelse",
  386.       "} bind def",
  387.       "",
  388.       "/GrayDirectClassPacket",
  389.       "{",
  390.       "  %",
  391.       "  % Get a DirectClass packet;  convert to grayscale.",
  392.       "  %",
  393.       "  % Parameters: ",
  394.       "  %   red",
  395.       "  %   green",
  396.       "  %   blue",
  397.       "  %   length: number of pixels minus one of this color (optional).",
  398.       "  %",
  399.       "  currentfile color_packet readhexstring pop pop",
  400.       "  color_packet 0 get 0.299 mul",
  401.       "  color_packet 1 get 0.587 mul add",
  402.       "  color_packet 2 get 0.114 mul add",
  403.       "  cvi",
  404.       "  /gray_packet exch def",
  405.       "  compression 0 gt",
  406.       "  {",
  407.       "    /number_pixels 1 def",
  408.       "  }",
  409.       "  {",
  410.       "    currentfile byte readhexstring pop 0 get",
  411.       "    /number_pixels exch 1 add def",
  412.       "  } ifelse",
  413.       "  0 1 number_pixels 1 sub",
  414.       "  {",
  415.       "    pixels exch gray_packet put",
  416.       "  } for",
  417.       "  pixels 0 number_pixels getinterval",
  418.       "} bind def",
  419.       "",
  420.       "/GrayPseudoClassPacket",
  421.       "{",
  422.       "  %",
  423.       "  % Get a PseudoClass packet;  convert to grayscale.",
  424.       "  %",
  425.       "  % Parameters: ",
  426.       "  %   index: index into the colormap.",
  427.       "  %   length: number of pixels minus one of this color (optional).",
  428.       "  %",
  429.       "  currentfile byte readhexstring pop 0 get",
  430.       "  /offset exch 3 mul def",
  431.       "  /color_packet colormap offset 3 getinterval def",
  432.       "  color_packet 0 get 0.299 mul",
  433.       "  color_packet 1 get 0.587 mul add",
  434.       "  color_packet 2 get 0.114 mul add",
  435.       "  cvi",
  436.       "  /gray_packet exch def",
  437.       "  compression 0 gt",
  438.       "  {",
  439.       "    /number_pixels 1 def",
  440.       "  }",
  441.       "  {",
  442.       "    currentfile byte readhexstring pop 0 get",
  443.       "    /number_pixels exch 1 add def",
  444.       "  } ifelse",
  445.       "  0 1 number_pixels 1 sub",
  446.       "  {",
  447.       "    pixels exch gray_packet put",
  448.       "  } for",
  449.       "  pixels 0 number_pixels getinterval",
  450.       "} bind def",
  451.       "",
  452.       "/PseudoClassPacket",
  453.       "{",
  454.       "  %",
  455.       "  % Get a PseudoClass packet.",
  456.       "  %",
  457.       "  % Parameters: ",
  458.       "  %   index: index into the colormap.",
  459.       "  %   length: number of pixels minus one of this color (optional).",
  460.       "  %",
  461.       "  %",
  462.       "  currentfile byte readhexstring pop 0 get",
  463.       "  /offset exch 3 mul def",
  464.       "  /color_packet colormap offset 3 getinterval def",
  465.       "  compression 0 gt",
  466.       "  {",
  467.       "    /number_pixels 3 def",
  468.       "  }",
  469.       "  {",
  470.       "    currentfile byte readhexstring pop 0 get",
  471.       "    /number_pixels exch 1 add 3 mul def",
  472.       "  } ifelse",
  473.       "  0 3 number_pixels 1 sub",
  474.       "  {",
  475.       "    pixels exch color_packet putinterval",
  476.       "  } for",
  477.       "  pixels 0 number_pixels getinterval",
  478.       "} bind def",
  479.       "",
  480.       "/PseudoClassImage",
  481.       "{",
  482.       "  %",
  483.       "  % Display a PseudoClass image.",
  484.       "  %",
  485.       "  % Parameters: ",
  486.       "  %   colors: number of colors in the colormap.",
  487.       "  %   colormap: red, green, blue color packets.",
  488.       "  %",
  489.       "  currentfile buffer readline pop",
  490.       "  token pop /colors exch def pop",
  491.       "  /colors colors 3 mul def",
  492.       "  /colormap colors string def",
  493.       "  currentfile colormap readhexstring pop pop",
  494.       "  systemdict /colorimage known",
  495.       "  {",
  496.       "    columns rows 8",
  497.       "    [",
  498.       "      columns 0 0",
  499.       "      rows neg 0 rows",
  500.       "    ]",
  501.       "    { PseudoClassPacket } false 3 colorimage",
  502.       "  }",
  503.       "  {",
  504.       "    %",
  505.       "    % No colorimage operator;  convert to grayscale.",
  506.       "    %",
  507.       "    columns rows 8",
  508.       "    [",
  509.       "      columns 0 0",
  510.       "      rows neg 0 rows",
  511.       "    ]",
  512.       "    { GrayPseudoClassPacket } image",
  513.       "  } ifelse",
  514.       "} bind def",
  515.       "",
  516.       "/DisplayImage",
  517.       "{",
  518.       "  %",
  519.       "  % Display a DirectClass or PseudoClass image.",
  520.       "  %",
  521.       "  % Parameters: ",
  522.       "  %   x & y translation.",
  523.       "  %   x & y scale.",
  524.       "  %   image columns & rows.",
  525.       "  %   class: 0-DirectClass or 1-PseudoClass.",
  526.       "  %   compression: 0-RunlengthEncodedCompression or 1-NoCompression.",
  527.       "  %   hex color packets.",
  528.       "  %",
  529.       "  gsave",
  530.       "  currentfile buffer readline pop",
  531.       "  token pop /x exch def",
  532.       "  token pop /y exch def pop",
  533.       "  x y translate",
  534.       "  currentfile buffer readline pop",
  535.       "  token pop /x exch def",
  536.       "  token pop /y exch def pop",
  537.       "  x y scale",
  538.       "  currentfile buffer readline pop",
  539.       "  token pop /columns exch def",
  540.       "  token pop /rows exch def pop",
  541.       "  currentfile buffer readline pop",
  542.       "  token pop /class exch def pop",
  543.       "  currentfile buffer readline pop",
  544.       "  token pop /compression exch def pop",
  545.       "  class 0 gt { PseudoClassImage } { DirectClassImage } ifelse",
  546.       "  grestore",
  547.       "  showpage",
  548.       "} bind def",
  549.       "",
  550.       "DisplayImage",
  551.       NULL
  552.     };
  553.  
  554.   char
  555.     **q;
  556.  
  557.   int
  558.     center,
  559.     x,
  560.     y;
  561.  
  562.   register RunlengthPacket
  563.     *p;
  564.  
  565.   register int
  566.     i,
  567.     j;
  568.  
  569.   unsigned int
  570.     height,
  571.     width;
  572.  
  573.   /*
  574.     Open output image file.
  575.   */
  576.   if (*image->filename == '-')
  577.     image->file=stdout;
  578.   else
  579.     image->file=fopen(image->filename,"w");
  580.   if (image->file == (FILE *) NULL)
  581.     {
  582.       (void) fprintf(stderr,"%s: unable to print image, cannot open %s.\n",
  583.         application_name,image->filename);
  584.       return(False);
  585.     }
  586.   width=image->columns;
  587.   height=image->rows;
  588.   center=True;
  589.   if (center)
  590.     {
  591.       int
  592.         delta_x,
  593.         delta_y;
  594.  
  595.       unsigned long
  596.         scale;
  597.  
  598.       /*
  599.         Center image on Postscript page.
  600.       */
  601.       if (width > (PageWidth-(2*PageLeftMargin)))
  602.         {
  603.           scale=((PageWidth-(2*PageLeftMargin)) << 14)/width;
  604.           width=(width*scale) >> 14;
  605.           height=(height*scale) >> 14;
  606.         }
  607.       if (height > (PageHeight-(2*PageBottomMargin)))
  608.         {
  609.           scale=((PageHeight-(2*PageBottomMargin)) << 14)/height;
  610.           width=(width*scale) >> 14;
  611.           height=(height*scale) >> 14;
  612.         }
  613.       delta_x=PageWidth-(width+(2*PageLeftMargin));
  614.       delta_y=PageHeight-(height+(2*PageBottomMargin));
  615.       if (delta_x >= 0)
  616.         x=delta_x/2+PageLeftMargin;
  617.       else
  618.         x=PageLeftMargin;
  619.       if (delta_y >= 0)
  620.         y=delta_y/2+PageBottomMargin;
  621.       else
  622.         y=PageBottomMargin;
  623.     }
  624.   /*
  625.     Output encapsulated Postscript header.
  626.   */
  627.   (void) fprintf(image->file,"%%!PS-Adobe-2.0 EPSF-2.0\n");
  628.   (void) fprintf(image->file,"%%%%BoundingBox: %d %d %d %d\n",x,y,x+width,
  629.     y+height);
  630.   (void) fprintf(image->file,"%%%%Creator: ImageMagick\n");
  631.   (void) fprintf(image->file,"%%%%Title: %s\n",image->filename);
  632.   (void) fprintf(image->file,"%%%%EndComments\n");
  633.   /*
  634.     Output encapsulated Postscript commands.
  635.   */
  636.   for (q=Postscript; *q; q++)
  637.     (void) fprintf(image->file,"%s\n",*q);
  638.   /*
  639.     Output image data.
  640.   */
  641.   (void) fprintf(image->file,"%d %d\n%d %d\n%d %d\n%d\n%d\n",x,y,width,height,
  642.     image->columns,image->rows,(image->class == PseudoClass),
  643.     image->compression == NoCompression);
  644.   x=0;
  645.   p=image->pixels;
  646.   switch (image->class)
  647.   {
  648.     case DirectClass:
  649.     {
  650.       switch (image->compression)
  651.       {
  652.         case RunlengthEncodedCompression:
  653.         default:
  654.         {
  655.           /*
  656.             Dump runlength-encoded DirectColor packets.
  657.           */
  658.           for (i=0; i < image->packets; i++)
  659.           {
  660.             x++;
  661.             (void) fprintf(image->file,"%02x%02x%02x%02x",p->red,p->green,
  662.               p->blue,p->length);
  663.             if (x == 9)
  664.               {
  665.                 x=0;
  666.                 (void) fprintf(image->file,"\n");
  667.               }
  668.             p++;
  669.           }
  670.           break;
  671.         }
  672.         case NoCompression:
  673.         {
  674.           /*
  675.             Dump DirectColor packets.
  676.           */
  677.           for (i=0; i < image->packets; i++)
  678.           {
  679.             for (j=0; j <= p->length; j++)
  680.             {
  681.               x++;
  682.               (void) fprintf(image->file,"%02x%02x%02x",p->red,p->green,
  683.                 p->blue);
  684.               if (x == 12)
  685.                 {
  686.                   x=0;
  687.                   (void) fprintf(image->file,"\n");
  688.                 }
  689.             }
  690.             p++;
  691.           }
  692.           break;
  693.         }
  694.       }
  695.       break;
  696.     }
  697.     case PseudoClass:
  698.     {
  699.       /*
  700.         Dump number of colors, colormap, PseudoColor packets.
  701.       */
  702.       (void) fprintf(image->file,"%d\n",image->colors);
  703.       for (i=0; i < image->colors; i++)
  704.         (void) fprintf(image->file,"%02x%02x%02x\n",image->colormap[i].red,
  705.           image->colormap[i].green,image->colormap[i].blue);
  706.       switch (image->compression)
  707.       {
  708.         case RunlengthEncodedCompression:
  709.         default:
  710.         {
  711.           for (i=0; i < image->packets; i++)
  712.           {
  713.             x++;
  714.             (void) fprintf(image->file,"%02x%02x",p->index,p->length);
  715.             if (x == 18)
  716.               {
  717.                 x=0;
  718.                 (void) fprintf(image->file,"\n");
  719.               }
  720.             p++;
  721.           }
  722.           break;
  723.         }
  724.         case NoCompression:
  725.         {
  726.           for (i=0; i < image->packets; i++)
  727.           {
  728.             for (j=0; j <= p->length; j++)
  729.             {
  730.               x++;
  731.               (void) fprintf(image->file,"%02x",p->index);
  732.               if (x == 36)
  733.                 {
  734.                   x=0;
  735.                   (void) fprintf(image->file,"\n");
  736.                 }
  737.             }
  738.             p++;
  739.           }
  740.         }
  741.         break;
  742.       }
  743.     }
  744.   }
  745.   (void) fprintf(image->file,"\n\n");
  746.   (void) fprintf(image->file,"%%%%Trailer\n");
  747.   if (image->file != stdin)
  748.     (void) fclose(image->file);
  749.   return(True);
  750. }
  751.  
  752. /*
  753. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  754. %                                                                             %
  755. %                                                                             %
  756. %                                                                             %
  757. %  R e a d D a t a                                                            %
  758. %                                                                             %
  759. %                                                                             %
  760. %                                                                             %
  761. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  762. %
  763. %  Function ReadData reads data from the image file and returns it.  If it
  764. %  cannot read the requested number of items, False is returned indicating
  765. %  an error.
  766. %
  767. %  The format of the ReadData routine is:
  768. %
  769. %      status=ReadData(data,size,number_items,file)
  770. %
  771. %  A description of each parameter follows:
  772. %
  773. %    o status:  Function ReadData returns True if all the data requested
  774. %      is obtained without error, otherwise False.
  775. %
  776. %    o data:  Specifies an area to place the information reuested from
  777. %      the file.
  778. %
  779. %    o size:  Specifies an integer representing the length of an
  780. %      individual item to be read from the file.
  781. %
  782. %    o numer_items:  Specifies an integer representing the number of items
  783. %      to read from the file.
  784. %
  785. %    o file:  Specifies a file to read the data.
  786. %
  787. %
  788. */
  789. unsigned int ReadData(data,size,number_items,file)
  790. char
  791.   *data;
  792.  
  793. int
  794.   size,
  795.   number_items;
  796.  
  797. FILE
  798.   *file;
  799. {
  800.   size*=number_items;
  801.   while (size > 0)
  802.   {
  803.     number_items=fread(data,1,size,file);
  804.     if (number_items <= 0)
  805.       return(False);
  806.     size-=number_items;
  807.     data+=number_items;
  808.   }
  809.   return(True);
  810. }
  811.  
  812. /*
  813. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  814. %                                                                             %
  815. %                                                                             %
  816. %                                                                             %
  817. %  R e a d S U N I m a g e                                                    %
  818. %                                                                             %
  819. %                                                                             %
  820. %                                                                             %
  821. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  822. %
  823. %  Function ReadSUNImage reads an image file and returns it.  It allocates 
  824. %  the memory necessary for the new Image structure and returns a pointer to 
  825. %  the new image.
  826. %
  827. %  The format of the ReadSUNImage routine is:
  828. %
  829. %      image=ReadSUNImage(filename)
  830. %
  831. %  A description of each parameter follows:
  832. %
  833. %    o image:  Function ReadSUNImage returns a pointer to the image after 
  834. %      reading.  A null image is returned if there is a a memory shortage or 
  835. %      if the image cannot be read.
  836. %
  837. %    o filename:  Specifies the name of the image to read.
  838. %
  839. %
  840. */
  841. static Image *ReadSUNImage(filename)
  842. char
  843.   *filename;
  844. {
  845. #define RMT_EQUAL_RGB  1
  846. #define RMT_NONE  0
  847. #define RMT_RAW  2
  848. #define RT_STANDARD  1
  849. #define RT_ENCODED  2
  850. #define RT_FORMAT_RGB  3
  851.  
  852.   typedef struct _Rasterfile
  853.   {
  854.     int
  855.       magic,
  856.       width,
  857.       height,
  858.       depth,
  859.       length,
  860.       type,
  861.       maptype,
  862.       maplength;
  863.   } Rasterfile;
  864.  
  865.   Image
  866.     *image;
  867.  
  868.   Rasterfile
  869.     sun_header;
  870.  
  871.   register int
  872.     bit,
  873.     i,
  874.     x,
  875.     y;
  876.  
  877.   register RunlengthPacket
  878.     *q;
  879.  
  880.   register unsigned char
  881.     *p;
  882.  
  883.   unsigned char
  884.     blue,
  885.     green,
  886.     red,
  887.     *sun_data,
  888.     *sun_pixels;
  889.  
  890.   unsigned long 
  891.     lsb_first;
  892.  
  893.   unsigned short
  894.     index;
  895.  
  896.   /*
  897.     Allocate image structure.
  898.   */
  899.   image=(Image *) malloc(sizeof(Image));
  900.   if (image == (Image *) NULL)
  901.     Error("memory allocation error",(char *) NULL);
  902.   /*
  903.     Initialize Image structure.
  904.   */
  905.   image->id=UnknownId;
  906.   image->class=DirectClass;
  907.   image->compression=RunlengthEncodedCompression;
  908.   image->columns=0;
  909.   image->rows=0;
  910.   image->packets=0;
  911.   image->colors=0;
  912.   image->scene=0;
  913.   image->colormap=(ColorPacket *) NULL;
  914.   image->pixels=(RunlengthPacket *) NULL;
  915.   image->comments=(char *) NULL;
  916.   /*
  917.     Open image file.
  918.   */
  919.   (void) strcpy(image->filename,filename);
  920.   if (*image->filename == '-')
  921.     image->file=stdin;
  922.   else
  923.     if (strcmp(image->filename+strlen(image->filename)-2,".Z") != 0)
  924.       image->file=fopen(image->filename,"r");
  925.     else
  926.       {
  927.         char
  928.           command[256];
  929.  
  930.         /*
  931.           Image file is compressed-- uncompress it.
  932.         */
  933.         (void) sprintf(command,"uncompress -c %s",image->filename);
  934.         image->file=(FILE *) popen(command,"r");
  935.       }
  936.   if (image->file == (FILE *) NULL)
  937.     Error("unable to open file",image->filename);
  938.   /*
  939.     Read raster image.
  940.   */
  941.   (void) ReadData((char *) &sun_header,1,sizeof(Rasterfile),image->file);
  942.   /*
  943.     Ensure the header byte-order is most-significant byte first.
  944.   */
  945.   lsb_first=1;
  946.   if (*(char *) &lsb_first)
  947.     MSBFirstOrder((char *) &sun_header,sizeof(sun_header));
  948.   if (sun_header.magic != 0x59a66a95)
  949.     Error("not a SUN raster,",image->filename);
  950.   switch (sun_header.maptype)
  951.   {
  952.     case RMT_NONE:
  953.     {
  954.       if (sun_header.depth < 24)
  955.         {
  956.           /*
  957.             Create linear color ramp.
  958.           */
  959.           image->colors=1 << sun_header.depth;
  960.           image->colormap=(ColorPacket *) 
  961.             malloc(image->colors*sizeof(ColorPacket));
  962.           if (image->colormap == (ColorPacket *) NULL)
  963.             Error("memory allocation error",(char *) NULL);
  964.           for (i=0; i < image->colors; i++)
  965.           {
  966.             image->colormap[i].red=(255*i)/(image->colors-1);
  967.             image->colormap[i].green=(255*i)/(image->colors-1);
  968.             image->colormap[i].blue=(255*i)/(image->colors-1);
  969.           }
  970.         }
  971.       break;
  972.     }
  973.     case RMT_EQUAL_RGB:
  974.     {
  975.       unsigned char
  976.         *sun_colormap;
  977.  
  978.       /*
  979.         Read Sun raster colormap.
  980.       */
  981.       image->colors=sun_header.maplength/3;
  982.       image->colormap=
  983.         (ColorPacket *) malloc(image->colors*sizeof(ColorPacket));
  984.       sun_colormap=(unsigned char *) 
  985.         malloc(image->colors*sizeof(unsigned char));
  986.       if ((image->colormap == (ColorPacket *) NULL) ||
  987.           (sun_colormap == (unsigned char *) NULL))
  988.         Error("memory allocation error",(char *) NULL);
  989.       (void) ReadData((char *) sun_colormap,1,(int) image->colors,image->file);
  990.       for (i=0; i < image->colors; i++)
  991.         image->colormap[i].red=sun_colormap[i];
  992.       (void) ReadData((char *) sun_colormap,1,(int) image->colors,image->file);
  993.       for (i=0; i < image->colors; i++)
  994.         image->colormap[i].green=sun_colormap[i];
  995.       (void) ReadData((char *) sun_colormap,1,(int) image->colors,image->file);
  996.       for (i=0; i < image->colors; i++)
  997.         image->colormap[i].blue=sun_colormap[i];
  998.       (void) free((char *) sun_colormap);
  999.       break;
  1000.     }
  1001.     case RMT_RAW:
  1002.     {
  1003.       unsigned char
  1004.         *sun_colormap;
  1005.  
  1006.       /*
  1007.         Read Sun raster colormap.
  1008.       */
  1009.       sun_colormap=(unsigned char *) 
  1010.         malloc((unsigned int) sun_header.maplength*sizeof(unsigned char));
  1011.       if (sun_colormap == (unsigned char *) NULL)
  1012.         Error("memory allocation error",(char *) NULL);
  1013.       (void) ReadData((char *) sun_colormap,1,sun_header.maplength,
  1014.         image->file);
  1015.       (void) free((char *) sun_colormap);
  1016.       break;
  1017.     }
  1018.     default:
  1019.     {
  1020.       Error("colormap type is not supported",image->filename);
  1021.       break;
  1022.     }
  1023.   }
  1024.   sun_data=(unsigned char *) 
  1025.     malloc((unsigned int) sun_header.length*sizeof(unsigned char));
  1026.   if (sun_data == (unsigned char *) NULL)
  1027.     Error("memory allocation error",(char *) NULL);
  1028.   (void) ReadData((char *) sun_data,1,sun_header.length,image->file);
  1029.   sun_pixels=sun_data;
  1030.   if (sun_header.type == RT_ENCODED) 
  1031.     {
  1032.       register int
  1033.         count,
  1034.         number_pixels;
  1035.  
  1036.       register unsigned char
  1037.         byte,
  1038.         *q;
  1039.  
  1040.       /*
  1041.         Read run-length encoded raster pixels.
  1042.       */
  1043.       number_pixels=(sun_header.width+(sun_header.width % 2))*
  1044.         sun_header.height*(((sun_header.depth-1) >> 3)+1);
  1045.       sun_pixels=(unsigned char *) 
  1046.         malloc((unsigned int) number_pixels*sizeof(unsigned char));
  1047.       if (sun_pixels == (unsigned char *) NULL)
  1048.         Error("memory allocation error",(char *) NULL);
  1049.       p=sun_data;
  1050.       q=sun_pixels;
  1051.       while ((q-sun_pixels) <= number_pixels)
  1052.       {
  1053.         byte=(*p++);
  1054.         if (byte != 128)
  1055.           *q++=byte;
  1056.         else
  1057.           {
  1058.             /*
  1059.               Runlength-encoded packet: <count><byte>
  1060.             */
  1061.             count=(*p++);
  1062.             if (count > 0)
  1063.               byte=(*p++);
  1064.             while (count >= 0)
  1065.             {
  1066.               *q++=byte;
  1067.               count--;
  1068.             }
  1069.          }
  1070.       }
  1071.     (void) free((char *) sun_data);
  1072.   }
  1073.   /*
  1074.     Create image.
  1075.   */
  1076.   image->comments=(char *) malloc((unsigned int) (strlen(image->filename)+256));
  1077.   if (image->comments == (char *) NULL)
  1078.     Error("memory allocation error",(char *) NULL);
  1079.   (void) sprintf(image->comments,"\n  Imported from Sun raster image:  %s\n\0",
  1080.     image->filename);
  1081.   image->class=(sun_header.depth < 24 ? PseudoClass : DirectClass);
  1082.   image->columns=sun_header.width;
  1083.   image->rows=sun_header.height;
  1084.   image->pixels=(RunlengthPacket *) 
  1085.     malloc(image->columns*image->rows*sizeof(RunlengthPacket));
  1086.   if (image->pixels == (RunlengthPacket *) NULL)
  1087.     Error("memory allocation error",(char *) NULL);
  1088.   /*
  1089.     Convert Sun raster image to runlength-encoded packets.
  1090.   */
  1091.   p=sun_pixels;
  1092.   image->packets=0;
  1093.   q=image->pixels;
  1094.   q->length=MaxRunlength;
  1095.   if (sun_header.depth == 1)
  1096.     for (y=0; y < image->rows; y++)
  1097.     {
  1098.       /*
  1099.         Convert bitmap scanline to runlength-encoded color packets.
  1100.       */
  1101.       for (x=0; x < (image->columns >> 3); x++) 
  1102.       {
  1103.         for (bit=7; bit >= 0; bit--)
  1104.         {
  1105.           index=((*p) & (0x01 << bit) ? 0x00 : 0x01);
  1106.           red=image->colormap[index].red;
  1107.           green=image->colormap[index].green;
  1108.           blue=image->colormap[index].blue;
  1109.           if ((red == q->red) && (green == q->green) && (blue == q->blue) &&
  1110.               (q->length < MaxRunlength))
  1111.             q->length++;
  1112.           else
  1113.             {
  1114.               if (image->packets > 0)
  1115.                 q++;
  1116.               image->packets++;
  1117.               q->red=red;
  1118.               q->green=green;
  1119.               q->blue=blue;
  1120.               q->index=index;
  1121.               q->length=0;
  1122.             }
  1123.         }
  1124.         p++;
  1125.       }
  1126.       if ((image->columns % 8) != 0)
  1127.         {
  1128.           for (bit=7; bit >= (8-(image->columns % 8)); bit--)
  1129.           {
  1130.             index=((*p) & (0x01 << bit) ? 0x00 : 0x01);
  1131.             red=image->colormap[index].red;
  1132.             green=image->colormap[index].green;
  1133.             blue=image->colormap[index].blue;
  1134.             if ((red == q->red) && (green == q->green) && (blue == q->blue) &&
  1135.                 (q->length < MaxRunlength))
  1136.               q->length++;
  1137.             else
  1138.               {
  1139.                 if (image->packets > 0)
  1140.                   q++;
  1141.                 image->packets++;
  1142.                 q->red=red;
  1143.                 q->green=green;
  1144.                 q->blue=blue;
  1145.                 q->index=index;
  1146.                 q->length=0;
  1147.               }
  1148.           }
  1149.           p++;
  1150.         }
  1151.     }
  1152.   else
  1153.     if (image->class == PseudoClass)
  1154.       for (y=0; y < image->rows; y++)
  1155.       {
  1156.         /*
  1157.           Convert PseudoColor scanline to runlength-encoded color packets.
  1158.         */
  1159.         for (x=0; x < image->columns; x++) 
  1160.         {
  1161.           index=(*p++);
  1162.           red=image->colormap[index].red;
  1163.           green=image->colormap[index].green;
  1164.           blue=image->colormap[index].blue;
  1165.           if ((red == q->red) && (green == q->green) && (blue == q->blue) &&
  1166.               (q->length < MaxRunlength))
  1167.             q->length++;
  1168.           else
  1169.             {
  1170.               if (image->packets > 0)
  1171.                 q++;
  1172.               image->packets++;
  1173.               q->red=red;
  1174.               q->green=green;
  1175.               q->blue=blue;
  1176.               q->index=index;
  1177.               q->length=0;
  1178.             }
  1179.         }
  1180.         if ((image->columns % 2) != 0)
  1181.           p++;
  1182.       }
  1183.     else
  1184.       for (y=0; y < image->rows; y++)
  1185.       {
  1186.         /*
  1187.           Convert DirectColor scanline to runlength-encoded color packets.
  1188.         */
  1189.         for (x=0; x < image->columns; x++) 
  1190.         {
  1191.           if (sun_header.type == RT_STANDARD)
  1192.             {
  1193.               blue=(*p++);
  1194.               green=(*p++);
  1195.               red=(*p++);
  1196.             }
  1197.           else
  1198.             {
  1199.               red=(*p++);
  1200.               green=(*p++);
  1201.               blue=(*p++);
  1202.             }
  1203.           if (image->colors > 0)
  1204.             {
  1205.               red=image->colormap[red].red;
  1206.               green=image->colormap[green].green;
  1207.               blue=image->colormap[blue].blue;
  1208.             }
  1209.           if ((red == q->red) && (green == q->green) && (blue == q->blue) &&
  1210.               (q->length < MaxRunlength))
  1211.               q->length++;
  1212.             else
  1213.               {
  1214.                 if (image->packets > 0)
  1215.                   q++;
  1216.                 image->packets++;
  1217.                 q->red=red;
  1218.                 q->green=green;
  1219.                 q->blue=blue;
  1220.                 q->index=0;
  1221.                 q->length=0;
  1222.               }
  1223.         }
  1224.         if ((image->columns % 2) != 0)
  1225.           p++;
  1226.       }
  1227.   (void) free((char *) sun_pixels);
  1228.   if (image->file != stdin)
  1229.     if (strcmp(image->filename+strlen(image->filename)-2,".Z") != 0)
  1230.       (void) fclose(image->file);
  1231.     else
  1232.       (void) pclose(image->file);
  1233.   if (image->packets > ((image->columns*image->rows*3) >> 2))
  1234.     image->compression=NoCompression;
  1235.   image->pixels=(RunlengthPacket *)
  1236.     realloc((char *) image->pixels,image->packets*sizeof(RunlengthPacket));
  1237.   return(image);
  1238. }
  1239.  
  1240. /*
  1241. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1242. %                                                                             %
  1243. %                                                                             %
  1244. %                                                                             %
  1245. %   U s a g e                                                                 %
  1246. %                                                                             %
  1247. %                                                                             %
  1248. %                                                                             %
  1249. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1250. %
  1251. %  Function Usage displays the program usage;
  1252. %
  1253. %  The format of the Usage routine is:
  1254. %
  1255. %      Usage(message)
  1256. %
  1257. %  A description of each parameter follows:
  1258. %
  1259. %    message:  Specifies a specific message to display to the user.
  1260. %
  1261. */
  1262. static void Usage(message)
  1263. char
  1264.   *message;
  1265. {
  1266.   if (message != (char *) NULL)
  1267.     (void) fprintf(stderr,"Can't continue, %s\n\n",message);
  1268.   (void) fprintf(stderr,"Usage: %s [-scene #] image.sun image.ps\n\n",
  1269.     application_name);
  1270.   (void) fprintf(stderr,"Specify 'image.sun' as '-' for standard input.\n");
  1271.   (void) fprintf(stderr,"Specify 'image.ps' as '-' for standard output.\n");
  1272.   exit(1);
  1273. }
  1274.  
  1275. /*
  1276. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1277. %                                                                             %
  1278. %                                                                             %
  1279. %                                                                             %
  1280. %  M a i n                                                                    %
  1281. %                                                                             %
  1282. %                                                                             %
  1283. %                                                                             %
  1284. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1285. %
  1286. %
  1287. */
  1288. int main(argc,argv)
  1289. int
  1290.   argc;
  1291.    
  1292. char
  1293.   *argv[];
  1294. {
  1295.   char
  1296.     filename[256];
  1297.  
  1298.   Image
  1299.     *image;
  1300.  
  1301.   int
  1302.     i;
  1303.  
  1304.   unsigned int
  1305.     scene;
  1306.  
  1307.   /*
  1308.     Initialize program variables.
  1309.   */
  1310.   application_name=argv[0];
  1311.   i=1;
  1312.   scene=0;
  1313.   if (argc < 3)
  1314.     Usage((char *) NULL);
  1315.   /*
  1316.     Read image and convert to MIFF format.
  1317.   */
  1318.   if (strncmp(argv[i],"-scene",2) == 0)
  1319.     {
  1320.       i++;
  1321.       scene=atoi(argv[i++]);
  1322.     }
  1323.   (void) strcpy(filename,argv[i++]);
  1324.   image=ReadSUNImage(filename);
  1325.   if (image == (Image *) NULL)
  1326.     exit(1);
  1327.   (void) strcpy(image->filename,argv[i++]);
  1328.   image->scene=scene;
  1329.   (void) PrintImage(image);
  1330.   (void) fprintf(stderr,"%s => %s  %dx%d\n",filename,image->filename,
  1331.     image->columns,image->rows);
  1332.   return(False);
  1333. }
  1334. --
  1335. The UUCP Mailer
  1336.