home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d3xx / d306 / rexxplplot.lha / RexxPlPlot / src / src.zoo / iff.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-01-06  |  12.7 KB  |  542 lines

  1. /* This file contains the iff device dependent subroutines for plplot */
  2. /* Tomas G Rokicki (Radical Eye Software), sometime in September 1989 */
  3.  
  4. #include "plplot.h"
  5. #include <stdio.h>
  6. #ifdef AZTEC_C
  7. #define memset(ptr,val,len)    setmem(ptr,len,val)
  8. extern char *calloc();
  9. #include <functions.h>
  10. #else
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #endif
  14. #include <math.h>
  15. #include <exec/types.h>
  16. #include <exec/memory.h>
  17. #include <devices/printer.h>
  18. #include <devices/prtbase.h>
  19.  
  20. static FILE *OutFile;
  21.  
  22. /* bitmap contains a pointer to an area of memory NBYTES in size */
  23. static short *bitmap;
  24.  
  25. static bitmapx, bitmapy, xdpi, ydpi ;
  26. static int wordsperrow ;
  27. char *outname ;
  28.  
  29. int getval(s)
  30. char *s ;
  31. {
  32.    int m ;
  33.  
  34.    while (1) {
  35.       printf(s) ;
  36.       fflush(stdout) ;
  37.       if (scanf("%d", &m) == 1 && m > 10 && m < 10000)
  38.          return(m) ;
  39.       printf("No value or value out of range; please try again\n") ;
  40.    }
  41. }
  42.  
  43. void iffquery(x, y, X, Y)
  44. int *x, *y, *X, *Y ;
  45. {
  46.    if (xdpi == 0)
  47.       xdpi = getval("Please enter desired horizontal IFF resolution (dpi):  ") ;
  48.    if (ydpi == 0)
  49.       ydpi = getval("Please enter desired vertical IFF resolution (dpi)  :  ") ;
  50.    if (bitmapx == 0)
  51.       bitmapx = getval("Please enter desired horizontal IFF size in pixels  :  ") ;
  52.    if (bitmapy == 0)
  53.       bitmapy = getval("Please enter desired vertical IFF size in pixels    :  ") ;
  54.    *x = xdpi ;
  55.    *y = ydpi ;
  56.    *X = bitmapx ;
  57.    *Y = bitmapy ;
  58. }
  59.  
  60. static char tempfile[100] ;
  61.  
  62. void pliff(x1, y1, x2, y2, n)
  63. int x1, y1, x2, y2 ;
  64. char *n ;
  65. {
  66.    if (x1)
  67.       xdpi = x1 ;
  68.    if (y1)
  69.       ydpi = y1 ;
  70.    if (x2)
  71.       bitmapx = x2 ;
  72.    if (y2)
  73.       bitmapy = y2 ;
  74.    if (n && *n) {
  75.       strcpy(tempfile, n) ;
  76.       outname = tempfile ;
  77.    }
  78. }
  79.  
  80. /* Opens the file for binary mode. */
  81.  
  82. void iffini()
  83. {
  84.   /* Allocate storage for bit map matrix */
  85.   wordsperrow = (bitmapx + 15) / 16 ;
  86.   if((bitmap = (short *)calloc(wordsperrow * 2,bitmapy)) == NULL)
  87.    printf("Out of memory in call to calloc \n");
  88. }
  89.  
  90. void iffopenfile()
  91. {
  92.   char FileName[80];
  93.  
  94.   if (outname == 0 || outname[0] == 0) {
  95.      printf("Enter IFF file name:  ");
  96.      scanf("%s",FileName);
  97.      outname = FileName ;
  98.   }
  99.  
  100.   if((OutFile = fopen(outname,"w")) == NULL) {
  101.    printf("Error opening %s \n",outname);
  102.    exit(1);
  103.   }
  104.   outname = 0 ;
  105. }
  106.  
  107. /* Set IFF to test mode */
  108. void ifftex()
  109. {
  110.   /* do nothing here */
  111. }
  112.  
  113. /* Set IFF to graphics mode */
  114. void iffgra()
  115. {
  116.   /* Do nothing here */
  117. }
  118.  
  119. static int firstclear ;
  120.  
  121. void iffwritefile() ;
  122.  
  123. /* Print out page */
  124. void iffclr()
  125. {
  126.   if (firstclear == 0) {
  127.      firstclear = 1 ;
  128.      memset((char *)bitmap,'\0',wordsperrow * (long)bitmapy * 2);
  129.      return ;
  130.   }
  131.   iffopenfile() ;
  132.   iffwritefile(bitmapx, bitmapy, wordsperrow, bitmap) ;
  133.   memset((char *)bitmap,'\0',wordsperrow * (long)bitmapy * 2);
  134.   fclose(OutFile) ;
  135. }
  136.  
  137. /* Change color */
  138. void iffcol(colour)
  139. int colour;
  140. {
  141. }
  142.  
  143. /* Function to draw the line in the bitmap */
  144. /* While not written in assembly, this should still be quite a bit faster */
  145. /* then the code it replaces from the DviJep driver.  As a matter of fact, */
  146. /* it can be moved there painlessly. */
  147. void ifflin(x1,y1,x2,y2)
  148. register int x1,y1,x2,y2;
  149. {
  150.    register short *p ;
  151.    register unsigned int b ;
  152.    register int t ;
  153.    int d ;
  154.    int nextrow ;
  155.  
  156.    if (x1 < 0 || x2 < 0 || x1 >= bitmapx || x2 >= bitmapx ||
  157.        y1 < 0 || y2 < 0 || y1 >= bitmapy || y2 >= bitmapy) {
  158.       printf("Error:  line out of range: %d %d %d %d\n", x1, y1, x2, y2) ;
  159.       exit(1) ;
  160.    }
  161.    /* we always want to go left to right. */
  162.    if (x1 > x2) {
  163.       t = x1 ; x1 = x2 ; x2 = t ;
  164.       t = y1 ; y1 = y2 ; y2 = t ;
  165.    }
  166.    p = bitmap + y1 * (long)wordsperrow ;
  167.    /* we always want to go `up'. */
  168.    if (y2 > y1)
  169.       nextrow = wordsperrow ;
  170.    else {
  171.       y2 = y1 * 2 - y2 ;
  172.       nextrow = - wordsperrow ;
  173.    }
  174.    b = 1L << (15 - (x1 & 15)) ;
  175.    p += (x1 >> 4) ;
  176.    x2 -= x1 ;
  177.    y2 -= y1 ;
  178.    /* two routines, one for major in x, one for major in y */
  179.    if (y2 > x2) {
  180.       d = y2 ;
  181.       t = x2 / 2 ;
  182.       y1 = y2 ;
  183.       while (y1 >= 0) {
  184.          *p |= b ;
  185.          p += nextrow ;
  186.          t += x2 ;
  187.          if (t >= d) {
  188.             t -= d ;
  189.             b >>= 1 ;
  190.             if (b == 0) {
  191.                b = 0x8000 ;
  192.                p++ ;
  193.             }
  194.          }
  195.          y1-- ;
  196.       }
  197.    } else {
  198.       d = x2 ;
  199.       t = y2 / 2 ;
  200.       x1 = x2 ;
  201.       while (x1 >= 0) {
  202.          *p |= b ;
  203.          b >>= 1 ;
  204.          if (b == 0) {
  205.             b = 0x8000 ;
  206.             p++ ;
  207.          }
  208.          t += y2 ;
  209.          if (t >= d) {
  210.             t -= d ;
  211.             p += nextrow ;
  212.          }
  213.          x1-- ;
  214.       }
  215.    }
  216. }
  217.  
  218. /* Reset printer and close file */
  219. void ifftid()
  220. {
  221.   iffclr();
  222.   /* Reset Printer */
  223.   free((void *)bitmap);
  224. }
  225. /*
  226.  *   Code we steal to write a black and white IFF file.
  227.  */
  228. static struct iffhead {
  229.    char formname[4] ;
  230.    long formlen ; /* fill me in */
  231.    char ilbmname[4] ;
  232.    char bmhdname[4] ;
  233.    long bmhdlen ;
  234.    short w, h ; /* fill me in */
  235.    long dummy0 ;
  236.    char numplanes, masking, compression, pad1 ;
  237.    short tc ;
  238.    char xas, yas ;
  239.    short pw, ph ;
  240.    char cmapname[4] ;
  241.    long cmaplen ;
  242.    char r0, g0, b0, r1, g1, b1 ;
  243.    char bodyname[4] ;
  244.    long bodylen ; /* fill me in */
  245. } iffhead = { {'F','O','R','M'}, 0, {'I','L','B','M'}, {'B','M','H','D'}, 20,
  246.       0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 320, 200, {'C','M','A','P'}, 6, 240, 240,
  247.       240, 0, 0, 0, {'B','O','D','Y'}, 0 } ;
  248. static long iffpos ;
  249. static short curbyte = -1 ;
  250. static short curcount = 0 ;
  251. static short runcount = 0 ;
  252. static void iffobyte(b)
  253. register int b ;
  254. {
  255.    putc(b, OutFile) ;
  256.    iffpos++ ;
  257. }
  258. char outchunk[256] ;
  259. static void iffoutbyte(b)
  260. register int b ;
  261. {
  262.    register int i ;
  263.  
  264.    if (b == curbyte && runcount < 125) {
  265.       runcount++ ;
  266.    } else {
  267.       if (runcount > 2) {
  268.          if (curcount > 0) {
  269.             iffobyte(curcount-1) ;
  270.             for (i=0; i<curcount; i++)
  271.                iffobyte(outchunk[i]) ;
  272.             curcount = 0 ;
  273.          }
  274.          iffobyte(256 - runcount + 1) ;
  275.          iffobyte(curbyte) ;
  276.          curbyte = -1 ;
  277.          runcount = 0 ;
  278.       } else {
  279.          while (runcount > 0) {
  280.             outchunk[curcount++] = curbyte ;
  281.             runcount-- ;
  282.          }
  283.          if (curcount > 110) {
  284.             iffobyte(curcount-1) ;
  285.             for (i=0; i<curcount; i++)
  286.                iffobyte(outchunk[i]) ;
  287.             curcount = 0 ;
  288.          }
  289.       }
  290.       curbyte = b ;
  291.       runcount = 1 ;
  292.    }
  293. }
  294. void finishrow()
  295. {
  296.    register int i ;
  297.  
  298.    if (runcount <= 2) {
  299.       while (runcount > 0) {
  300.          outchunk[curcount++] = curbyte ;
  301.          runcount-- ;
  302.       }
  303.    }
  304.    if (curcount > 0) {
  305.       iffobyte(curcount-1) ;
  306.       for (i=0; i<curcount; i++)
  307.          iffobyte(outchunk[i]) ;
  308.       curcount = 0 ;
  309.    }
  310.    if (runcount > 0) {
  311.       iffobyte(256 - runcount + 1) ;
  312.       iffobyte(curbyte) ;
  313.       curbyte = -1 ;
  314.       runcount = 0 ;
  315.    }
  316. }
  317.  
  318. /*
  319.  *   Finally we get into the nitty gritty of writing the stupid file.
  320.  */
  321. static void iffwritefile(w, h, wpr, p)
  322. register int w, h, wpr ;
  323. register short *p ;
  324. {
  325.    register int i, j ;
  326.  
  327.    fwrite((char *)&iffhead, 1, sizeof(struct iffhead), OutFile) ;
  328.    iffpos = 0 ;
  329.    for (j=0; j<h; j++) {
  330.       for (i=wpr; i; i--, p++) {
  331.          iffoutbyte((*p >> 8) & 255) ;
  332.          iffoutbyte(*p & 255) ;
  333.       }
  334.       finishrow() ;
  335.    }
  336.    if (iffpos & 1)
  337.       iffobyte(0) ;
  338.    fseek(OutFile, 0L, 0) ;
  339.    iffhead.w = w ;
  340.    iffhead.h = h ;
  341.    iffhead.pw = w ;
  342.    iffhead.ph = h ;
  343.    iffhead.formlen = iffpos + sizeof(struct iffhead) - 8 ;
  344.    iffhead.bodylen = iffpos ;
  345.    iffhead.xas = xdpi ;
  346.    iffhead.yas = ydpi ;
  347.    fwrite((char *)&iffhead, 1, sizeof(struct iffhead), OutFile) ;
  348. }
  349. /*
  350.  *   And, finally, the code to dump to Preferences.
  351.  */
  352. #define Dmpport(a,b,c) dmpport(a,b,c)
  353. static union printerIO {
  354.    struct IOStdReq ios ;
  355.    struct IODRPReq iodrp ;
  356.    struct IOPrtCmdReq iopc ;
  357. } *printerIO ;
  358. static struct PrinterData *PD ;
  359. static struct PrinterExtendedData *PED ;
  360. static struct MsgPort *replyport ;
  361. static long signal ;
  362. static short prtopen ;
  363. static struct RastPort rastport ;
  364. static struct BitMap Bitmap ;
  365. static short numrows ;
  366. static short dummycolors[] = { 0x0000, 0x0fff } ;
  367. static struct ColorMap dummyColorMap = { NULL, NULL, 2, (APTR)&dummycolors } ;
  368. /*
  369.  *   This is our main routine that talks to the printer device.  It
  370.  *   just does a dumprastport().
  371.  *
  372.  *   Note that a quality of `0' means to use the default quality set
  373.  *   by preferences.
  374.  */
  375. static void doio() {
  376.    register struct IODRPReq *ioreq ;
  377.    long waitflags ;
  378.  
  379.    ioreq = &printerIO->iodrp ;
  380.    SendIO(ioreq) ;
  381.    while (1) {
  382.       if (GetMsg(replyport) == NULL)
  383.          waitflags = Wait((1L << replyport->mp_SigBit)) ;
  384.       else
  385.          break ;
  386.    }
  387. }
  388. static void dmpport(flags, x, y)
  389. long flags ;
  390. int x, y ;
  391. {
  392.    register struct IODRPReq *ioreq ;
  393.  
  394.    ioreq = &printerIO->iodrp ;
  395.    ioreq->io_Command = PRD_DUMPRPORT ;
  396.    ioreq->io_RastPort = &rastport ;
  397.    ioreq->io_ColorMap = &dummyColorMap ;
  398.    ioreq->io_Modes = 0 ;
  399.    ioreq->io_SrcX = 0 ;
  400.    ioreq->io_SrcY = 0 ;
  401.    ioreq->io_SrcWidth = x ;
  402.    ioreq->io_SrcHeight = y ;
  403.    ioreq->io_DestCols = x ;
  404.    ioreq->io_DestRows = y ;
  405.    ioreq->io_Special = flags | SPECIAL_NOFORMFEED | SPECIAL_TRUSTME  ;
  406.    doio() ;
  407. }
  408. static void error(s)
  409. char *s ;
  410. {
  411.    printf("Error:  %s\n", s) ;
  412.    exit(1) ;
  413. }
  414. void prefquery(x, y, X, Y)
  415. int *x, *y, *X, *Y ;
  416. {
  417.    replyport = (struct MsgPort *)CreatePort("PlPlot.PIO", 0L) ;
  418.    if (replyport == NULL)
  419.       error("! couldn't open reply port") ;
  420.    printerIO = (union printerIO *)
  421.                      AllocMem((long)sizeof(union printerIO), MEMF_CLEAR) ;
  422.    if (printerIO == NULL)
  423.       error("! couldn't allocate mem") ;
  424.    if (OpenDevice("printer.device", 0L, printerIO, 0L) != NULL)
  425.       error("! couldn't open printer.device") ;
  426.    prtopen = 1 ;
  427.    printerIO->ios.io_Message.mn_ReplyPort = replyport ;
  428.    PD = (struct PrinterData *)printerIO->iodrp.io_Device ;
  429. /*
  430.  *   The user is full of shit with his settings of Preferences; we
  431.  *   override them all.
  432.  */
  433.    PD->pd_Preferences.PrintImage = IMAGE_NEGATIVE ;
  434.    PD->pd_Preferences.PrintShade = SHADE_BW ;
  435.    PD->pd_Preferences.PrintThreshold = 7 ;
  436.    PD->pd_Preferences.PrintFlags = INTEGER_SCALING  ;
  437.    PED = &PD->pd_SegmentData->ps_PED ;
  438. /*
  439.  *   It's too bad we need to set up these ridiculous values just to get
  440.  *   the parameters for the selected printer . . .
  441.  */
  442.    Bitmap.BytesPerRow = 4 ;
  443.    Bitmap.Rows = 600 ;
  444.    Bitmap.Depth = 1 ;
  445.    rastport.BitMap = &Bitmap ;
  446.    dmpport((long)(SPECIAL_NOPRINT), 16, 504) ;
  447.    numrows = PED->ped_NumRows ;
  448.    xdpi = PED->ped_XDotsInch ;
  449.    ydpi = PED->ped_YDotsInch ;
  450.    bitmapx = PED->ped_MaxXDots ;
  451.    bitmapy = ydpi * 10 ;
  452.    *x = xdpi ;
  453.    *y = ydpi ;
  454.    *X = bitmapx ;
  455.    *Y = bitmapy ;
  456. }
  457. void prefini() {
  458. /*
  459.  *   We are okay, so we allocate a nice chunk of memory for our bitmap.
  460.  *   This chunk of memory must be as wide as the widest page.  Its height
  461.  *   must be a multiple of numrows, and we want it to be as large as
  462.  *   possible without taking away too much memory.  More than about a fourth
  463.  *   of a page is wasted, though.  So, for now we simply take a fourth of
  464.  *   a page, rounded up to a multiple of NumRows, and grab us a chunk of
  465.  *   memory.
  466.  */
  467.    iffini() ;
  468. /*
  469.  *   Now we set up and stuff our bitmap structure.
  470.  */
  471.    Bitmap.BytesPerRow = wordsperrow * 2 ;
  472.    Bitmap.Rows = bitmapy ;
  473.    Bitmap.Planes[0] = (PLANEPTR)bitmap ;
  474. }
  475. /*
  476.  *   How do we eject a page?  I dunno.  Let's pretend that a form
  477.  *   feed always works.
  478.  */
  479. static void eject() {
  480.    printerIO->ios.io_Command = PRD_RAWWRITE;
  481.    printerIO->ios.io_Data = (APTR)"\014" ;
  482.    printerIO->ios.io_Length = 1 ;
  483.    doio() ;
  484. }
  485. /*
  486.  *   Now the dump routine.
  487.  */
  488. void prefclr() {
  489.   if (firstclear == 0) {
  490.      firstclear = 1 ;
  491.      memset((char *)bitmap,'\0',wordsperrow * (long)bitmapy * 2);
  492.      return ;
  493.   }
  494.   dmpport(0L, bitmapx, bitmapy) ;
  495.   eject() ;
  496.   memset((char *)bitmap,'\0',wordsperrow * (long)bitmapy * 2);
  497. }
  498. /*
  499.  *   Here we free anything allocated in this file.
  500.  */
  501. void preftid() {
  502.    prefclr() ;
  503.    free((void *)bitmap);
  504.    if (prtopen) {
  505.       CloseDevice(printerIO) ;
  506.       prtopen = 0 ;
  507.    }
  508.    if (printerIO) {
  509.       FreeMem(printerIO, (long)sizeof(union printerIO)) ;
  510.       printerIO = NULL ;
  511.    }
  512.    if (replyport) {
  513.       RemPort(replyport) ;
  514.       DeletePort(replyport) ;
  515.       replyport = NULL ;
  516.    }
  517. }
  518.  
  519. /*
  520.  *   This function `thickens' the lines by one pixel.
  521.  */
  522. void plthicken() {
  523.    register unsigned short *p ;
  524.    register int i, j ;
  525.  
  526.    if (bitmap == NULL)
  527.       return ;
  528.    /* first we `thicken' horizontally. */
  529.    p = (unsigned short *)bitmap ;
  530.    for (j=0; j < bitmapy; j++) {
  531.       for (i=1; i < wordsperrow; i++, p++)
  532.          *p |= (*p << 1) | (p[1] >> 15) ;
  533.       *p |= (*p << 1) ;
  534.       p++ ;
  535.    }
  536.    /* next we `thicken' vertically. */
  537.    p = (unsigned short *)bitmap ;
  538.    for (j=1; j < bitmapy; j++)
  539.       for (i=0; i<wordsperrow; i++, p++)
  540.          *p |= p[wordsperrow] ;
  541. }
  542.