home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume1 / calentool / part07 / ras2ps.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-27  |  11.4 KB  |  452 lines

  1. /*
  2.  * $Header: ras2ps.c,v 2.1 89/05/09 14:19:40 billr Exp $
  3.  */
  4. /*
  5.  * ras2ps - convert Sun raster file to RLL Postscript file
  6.  *
  7.  * Based on the sun2ps program by Glenn Boysko and modified slightly
  8.  * by Bill Randle, Tektronix, Inc.
  9.  * Original source of unknown copyright status; modifications Copyright
  10.  * 1989, Tektronix, Inc.
  11.  */
  12. #include "ct.h"        /* for the NO_PRINTER #define */
  13. #ifndef NO_PRINTER
  14. /******************************************************************************
  15. *                                          *
  16. *    File:         sun2ps.c                              *
  17. *    Author:       Glenn Boysko                          *
  18. *    Organization: Case Western Reserve University                  *
  19. *    EMail:          {decvax, sun}!mandrill!boysko                  *
  20. *              boysko@mandrill.cwru.edu                      *
  21. *    Created:      Wed Mar 23 9:25pm                          *
  22. *    Contents:     Sun Rasterfile to PostScript image (using a run-length  *
  23. *            encoding scheme.)                      *
  24. *                                          *
  25. *    (Adapted from "postimage" filter by J. R. Bammi.)              *
  26. *                                          *
  27. *    @(#)sun2ps.c    1.8
  28. ******************************************************************************/
  29.  
  30. /* Sun standard raster file format (as obtained by screendump(1)).
  31.  *
  32.  * Header    (8 16-bit quantities)
  33.  * Color Map
  34.  * Image
  35.  *
  36.  */
  37.  
  38. /* Header Format:
  39.  * 
  40.  * ras_magic        (int)    Raster Magic number 0x59a66a95
  41.  * ras_width        (int)    Width of image in pixels.
  42.  * ras_height        (int)    Height of image in pixels.
  43.  * ras_depth        (int)    Bits per pixel.    Either 1 or 8 bits.
  44.  * ras_length        (int)    Length of image in bytes, after line padding.
  45.  * ras_type        (int)    Type of file. Assumed to be RT_STANDARD (1) if
  46.  *                produced by a screendump command.
  47.  * ras_maptype        (int)    Type of color map. 
  48.  * ras_maplength    (int)    Length of color map in bytes.
  49.  *
  50.  */
  51.  
  52. /* Ras_maplength bytes of Color map data. */
  53.  
  54. /* Ras_length bytes of Image data. */
  55.  
  56. #include <stdio.h>
  57. #include <pixrect/pixrect_hs.h>
  58.  
  59. /* Buffer and Input Modes... */
  60. #define LITERAL    0
  61. #define COPY    1
  62. #define IGNORE    2
  63.  
  64. /* Transmission Variables. */
  65. int BufCount;
  66.  
  67. unsigned char Buffer[128],
  68.                CurrByte,
  69.                NextByte,
  70.                *BufferP = Buffer;
  71.  
  72. FILE *ofile;
  73.  
  74. /* Diagnostic Variables. */
  75. int    DiagNLongRuns = 0,
  76.          DiagMaxRunLength = 0,
  77.          DiagNumRuns = 0;
  78. double    DiagSumRunLength = 0;
  79.  
  80. ras2ps(infile, outfile)
  81. FILE *infile, *outfile;
  82. {
  83.      double     sizex, sizey, transx, transy, rotate;
  84.      struct rasterfile rh;
  85.      int i, BS, pad,inv;
  86.      
  87.  
  88.      extern double atof();
  89.      
  90.      sizex = 7.5;
  91.      sizey = 10.0;
  92.      transx = transy = 0.5;
  93.      inv = 0;
  94.      ofile = outfile;
  95.      
  96.      if (pr_load_header(infile, &rh) != 0)
  97.       Error("Can't read rasterfile header\n");
  98.  
  99. #ifdef EXTRADIAGS
  100.      fprintf(stderr, "Ras_width = %d, Ras_height = %d, Ras_depth = %d\n", 
  101.          rh.ras_width, rh.ras_height, rh.ras_depth);
  102.      fprintf(stderr, "Ras_length = %d, Ras_type = %d, Ras_maplength = %d\n",
  103.          rh.ras_length, rh.ras_type, rh.ras_maplength);
  104. #endif
  105.      
  106.      if (rh.ras_magic != RAS_MAGIC)
  107.      {    
  108.       Error("Input file is not a Sun Rasterfile!\n");
  109.      }
  110.      
  111.      if (rh.ras_type != RT_STANDARD)
  112.      {
  113.       Error("Input file is not in Sun Standard Rasterfile format.\n");
  114.      }
  115.      
  116.      /* Scan off color table */
  117.      if (rh.ras_maptype != RMT_NONE && rh.ras_maplength > 0)
  118.     pr_load_colormap(infile, &rh, NULL);
  119.      
  120.      if ( pad = 16 - (rh.ras_width%16) ) {
  121.      rh.ras_width += pad;
  122. #ifdef EXTRADIAGS
  123.     fprintf(stderr, "Ras_width changed to %d\n",rh.ras_width);
  124. #endif
  125.      }
  126.  
  127.      PrintPostScriptRoutines(rh.ras_height, rh.ras_width, rh.ras_depth,
  128.                  transx, transy, sizex, sizey, rotate);
  129.      
  130.      BS = Encode(infile, rh.ras_length, inv);
  131.      
  132. #ifdef DIAGS
  133.      fprintf(stderr, "Encoded %d bytes into %d. (Ratio=%d%%)\n",
  134.          rh.ras_length, BS, 100 - (100 * BS) / rh.ras_length);
  135.      Diags();
  136. #endif     
  137.      fclose(infile);
  138.  
  139.      PrintPostScriptClosing();
  140.      fclose(outfile);
  141. }
  142.      
  143. /******************************************************************************
  144. *    I/O Routines.                                  *
  145. ******************************************************************************/
  146. int
  147. gb(Fp)        /* Get a byte from Fp. */
  148. FILE *Fp;
  149. {
  150.      int byte;
  151.      
  152.      if (!feof(Fp))
  153.       byte = getc(Fp);
  154.      else
  155.       Error("Premature EOF.\n");
  156.      if (ferror(Fp))
  157.       Error("I/O Error.\n");
  158.      return(byte);
  159. }
  160.  
  161. int
  162. gw(Fp)        /* Get a word (int) from Fp. */
  163. FILE *Fp;
  164. {
  165.      int word;
  166.      
  167.      if (!feof(Fp))
  168.       word = getw(Fp);
  169.      else
  170.       Error("Premature EOF.\n");
  171.      if (ferror(Fp))
  172.       Error("I/O Error.\n");
  173.      return(word);
  174. }
  175.  
  176. SendHex(Byte)        /* Send a Hex char to Stdout. */
  177. unsigned char Byte;
  178. {
  179.      static int LineCount = 0;
  180.  
  181.      fprintf(ofile, "%02x",  0xff & Byte);
  182.      if (++LineCount == 16)
  183.      {
  184.       fputc('\n', ofile);
  185.       LineCount = 0;
  186.      }
  187. }
  188.      
  189. int
  190. SendBuffer(Inv)        /* Send a buffer to Stdout. Return BytesSent. */
  191. int Inv;
  192. {
  193.      int i, BytesSent;
  194.      
  195.      if (BufferMode() == LITERAL)
  196.      {
  197.       SendHex( (unsigned char) 0xff & BufCount );
  198.       for (i = 0; i < BufCount+1; i++)
  199.       {
  200.            SendHex( (Inv) ? Buffer[i] : ~Buffer[i]);
  201.       }
  202.       BytesSent = BufCount+2;
  203.      }
  204.      else if (BufferMode() == COPY)
  205.      {
  206.       SendHex( (unsigned char) 0xff & (0x100 + BufCount) );
  207.       SendHex( (Inv) ? Buffer[0] : ~Buffer[0]);
  208.       BytesSent = 2;
  209.       DiagRecLRun(mag(BufCount)+1);
  210.      }
  211.      return(BytesSent);
  212. }
  213.  
  214. /******************************************************************************
  215. *    Utility Routines.                              *
  216. ******************************************************************************/
  217. int
  218. mag(Byte)    /* Magitude of a signed char. */
  219. int Byte;
  220. {
  221.      if (Byte & 0x80)
  222.      {
  223.       /* Signed */
  224.       Byte = ~(--Byte);
  225.      }
  226.      return( 0xff & Byte );
  227. }
  228.       
  229. /******************************************************************************
  230. *    Buffer Management Routines.                          *
  231. ******************************************************************************/
  232. int
  233. InputMode()
  234. {
  235.      if (CurrByte == NextByte)
  236.       return(COPY);
  237.      return(LITERAL);
  238. }
  239.  
  240. int
  241. BufferMode()
  242. {
  243.      if (BufCount >= 0 && BufCount <= 127)
  244.       return(LITERAL);
  245.      else if (BufCount >= -127 && BufCount <= -1)
  246.       return(COPY);
  247.      return(IGNORE);
  248. }
  249.  
  250. InitLitMode(Fp, NBytes, Inv)
  251. FILE *Fp;
  252. int *NBytes, Inv;
  253. {
  254.      BufferP    = Buffer;
  255.      BufCount   = -1;
  256.      ContLitMode(Fp, NBytes, Inv);
  257. }
  258.  
  259. ContLitMode(Fp, NBytes, Inv)
  260. FILE *Fp;
  261. int *NBytes, Inv;
  262. {
  263.      if (BufCount == 127)
  264.      {
  265.       SendBuffer(Inv);
  266.       BufferP  = Buffer;
  267.       BufCount = -1;
  268.      }
  269.      *BufferP++ = CurrByte;
  270.      BufCount++;
  271.      CurrByte   = NextByte;
  272.      NextByte   = (unsigned char) gb(Fp);
  273.      (*NBytes)--;
  274. }
  275.      
  276. InitCopyMode(Fp, NBytes, Inv)
  277. FILE *Fp;
  278. int *NBytes, Inv;
  279. {
  280.      BufferP    = Buffer;
  281.      *BufferP++ = CurrByte;
  282.      BufCount   = -1;
  283.      CurrByte   = (unsigned char) gb(Fp);
  284.      NextByte   = (unsigned char) gb(Fp);
  285.      *NBytes   -= 2;
  286. }
  287.  
  288. ContCopyMode(Fp, NBytes, Inv)
  289. FILE *Fp;
  290. int *NBytes, Inv;
  291. {
  292.      if (BufCount == -127)
  293.      {
  294.       SendBuffer(Inv);
  295.       InitCopyMode(Fp, NBytes, Inv);
  296.       DiagNLongRuns++;
  297.      }
  298.      BufCount--;
  299.      CurrByte   = NextByte;
  300.      NextByte   = gb(Fp);
  301.      (*NBytes)--;
  302. }
  303.  
  304. /******************************************************************************
  305. *    Encoding Algorithm.                              *
  306. ******************************************************************************/
  307. int
  308. Encode(Fp, NBytes, Inv)
  309. FILE *Fp;
  310. int NBytes, Inv;
  311. {
  312.      int BytesSent = 0;
  313.      
  314.      /* Initialize Buffer, BufCount, NextByte, CurrByte */
  315.      CurrByte = (unsigned char) gb(Fp);
  316.      NextByte = (unsigned char) gb(Fp);
  317.      if (InputMode() == LITERAL)
  318.      {
  319.       InitLitMode(Fp, &NBytes, Inv);
  320.      }
  321.      else
  322.      {
  323.       InitCopyMode(Fp, &NBytes, Inv);
  324.      }
  325.      while (NBytes > 3)
  326.      {
  327.       switch(BufferMode())
  328.       {
  329.         case LITERAL:
  330.            if (InputMode() == COPY)
  331.            {
  332.             BytesSent += SendBuffer(Inv);
  333.             InitCopyMode(Fp, &NBytes, Inv);
  334.            }
  335.            else
  336.            {
  337.             ContLitMode(Fp, &NBytes, Inv);
  338.            }
  339.            break;
  340.         case COPY:
  341.            if (CurrByte == Buffer[0])
  342.            {
  343.             ContCopyMode(Fp, &NBytes, Inv);
  344.            }
  345.            else
  346.            {
  347.             BytesSent += SendBuffer(Inv);
  348.             if (InputMode() == COPY)
  349.             {
  350.              InitCopyMode(Fp, &NBytes, Inv);
  351.             }
  352.             else
  353.             {
  354.              InitLitMode(Fp, &NBytes, Inv);
  355.             }
  356.            }
  357.            break;
  358.         default:
  359.            Error("Bad Buffer Mode... Sorry\n");
  360.            break;
  361.       }
  362.      }
  363.      BytesSent += SendBuffer(Inv);
  364.      /* Send out rem'g 2-3 bytes in LITERAL mode. */
  365.      Buffer[0] = CurrByte;
  366.      Buffer[1] = NextByte;
  367.      if (NBytes == 3)
  368.       Buffer[2] = gb(Fp);
  369.      BufCount = NBytes-1;
  370.      BytesSent += SendBuffer(Inv);
  371.      return(BytesSent);
  372. }
  373.  
  374. /******************************************************************************
  375. *    Diagnostic Routines.                              *
  376. ******************************************************************************/
  377. DiagRecLRun(Rlength)
  378. int Rlength;
  379. {
  380. #ifdef DIAGS
  381.      if (Rlength > DiagMaxRunLength)
  382.       DiagMaxRunLength = Rlength;
  383.      DiagSumRunLength += Rlength;
  384.      DiagNumRuns++;
  385. #endif
  386. }
  387.  
  388. Diags()
  389. {
  390. #ifdef DIAGS
  391.      fprintf(stderr, "Longest Run (<= 128) = %d\n", DiagMaxRunLength);
  392.      fprintf(stderr, "Number of Runs over 128 = %d\n", DiagNLongRuns);
  393.      fprintf(stderr, "Average Run Length of %d. (%d Runs)\n",
  394.          (int) DiagSumRunLength / DiagNumRuns, DiagNumRuns);
  395. #endif
  396. }
  397.  
  398. /******************************************************************************
  399. *    PostScript Output Routines.                           *
  400. ******************************************************************************/
  401. PrintPostScriptRoutines(ras_h, ras_w, ras_d, tx, ty, sx, sy, rot)
  402. int ras_h, ras_w, ras_d;
  403. double tx, ty, sx, sy, rot;
  404. {
  405.      fprintf(ofile, "%%!\n/inch {72 mul} def\n");
  406.      fprintf(ofile, "/bpp %d def\n", ras_d);
  407.      fprintf(ofile, "/scanlines %d def\n", ras_h);
  408.      fprintf(ofile, "/scansize %d def\n", ras_w);
  409.      fprintf(ofile, "/bitmapx\n{");
  410.      fprintf(ofile, " %d %d %d [%d 0 0 %d 0 %d] ", ras_w, ras_h, ras_d, ras_w, 
  411.         -ras_h, ras_h);
  412.      fprintf(ofile, "{currentfile readrlehexstring pop } image\n} def\n");
  413.      fprintf(ofile, "gsave\n");
  414.      fprintf(ofile, "%f inch %f inch translate\n",tx, ty);
  415.      fprintf(ofile, "%f rotate\n", rot );
  416.      fprintf(ofile, "%f inch %f inch scale\n", sx, sy);
  417.      fprintf(ofile, "/readrlehexstring\t%% rle_file => decoded_string boolean\n");
  418.      fprintf(ofile, "{\n\t/fileptr exch def\n\tfileptr 1 string readhexstring {");
  419.      fprintf(ofile, "\n\t\t0 get dup 128 and 0 eq\n");
  420.      fprintf(ofile, "\t\t{ 1 add /Buffer exch string def\n");
  421.      fprintf(ofile, "\t\t\tfileptr Buffer readhexstring\n\t\t}\n\t\t{");
  422.      fprintf(ofile, " 256 exch sub /BufCount exch def\n");
  423.      fprintf(ofile, "\t\t\t/Buffer BufCount 1 add string def\n");
  424.      fprintf(ofile, "\t\t\t/RunInt fileptr 1 string readhexstring");
  425.      fprintf(ofile, " pop 0 get def\n");
  426.      fprintf(ofile, "\t\t\t0 1 BufCount { RunInt Buffer 3 1 roll put } for\n");
  427.      fprintf(ofile, "\t\t\tBuffer true\n\t\t} ifelse\n\t}\n\t{ false } ifelse\n");
  428.      fprintf(ofile, "} def\n");
  429.      fprintf(ofile, "/clipathx\n{\tnewpath\n\t0 0 moveto\n\t%f inch 0", sx);
  430.      fprintf(ofile, " lineto\n\t%f inch %f inch lineto\n\t0 %f inch lineto\n",
  431.         sx, sy, sy);
  432.      fprintf(ofile, "\tclosepath\n} def\nclipathx clip\n");
  433.      fprintf(ofile, "bitmapx\n");
  434. }
  435.  
  436. PrintPostScriptClosing()
  437. {     
  438.      fprintf(ofile, "\ngrestore\n");
  439.      fprintf(ofile, "showpage\n");
  440. }
  441.  
  442. /******************************************************************************
  443. *    Error Routine.                                  *
  444. ******************************************************************************/
  445. Error(S1)
  446. char *S1;
  447. {
  448.      *(S1 + strlen(S1)) = '\0';    /* delete trailing \n */
  449.      err_rpt(S1, FATAL);
  450. }
  451. #endif    /* NO_PRINTER */
  452.