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

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