home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / os2 / hpgl312.zip / TO_PAC.C < prev    next >
C/C++ Source or Header  |  1993-04-18  |  24KB  |  777 lines

  1. /*
  2.    Copyright (c) 1992  Norbert Meyer.  All rights reserved.
  3.    Distributed by Free Software Foundation, Inc.
  4.  
  5. This file is part of HP2xx.
  6.  
  7. HP2xx is distributed in the hope that it will be useful, but
  8. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  9. to anyone for the consequences of using it or for whether it serves any
  10. particular purpose or works at all, unless he says so in writing.  Refer
  11. to the GNU General Public License, Version 2 or later, for full details.
  12.  
  13. Everyone is granted permission to copy, modify and redistribute
  14. HP2xx, but only under the conditions described in the GNU General Public
  15. License.  A copy of this license is supposed to have been
  16. given to you along with HP2xx so you can know your rights and
  17. responsibilities.  It should be in a file named COPYING.  Among other
  18. things, the copyright notice and this notice must be preserved on all
  19. copies.
  20.  
  21. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  22. */
  23.  
  24. /** to_pac.c:  converts the hp2xx-intern bitmap into a series of
  25.  **            files with STAD-format (*.PAC) - part of project
  26.  **            "hp2xx" (from Heinz Werntges).
  27.  **
  28.  **            STAD-format is very popular in the Atari-world and
  29.  **            is supported by many commercial (for instance, the
  30.  **            original STAD-programm (Appliction Systems,
  31.  **            Heidelberg, FRG)) and PD pixel-graphic programms.
  32.  **
  33.  **            Each PAC-file represents a monochrome picture with
  34.  **            640 x 400 pixels. Therefore, if the hp2xx-bitmap
  35.  **            is larger than 640 x 400 pixels more than one PAC-
  36.  **            file has to be generated.
  37.  **
  38.  ** NOTE:     This is an unsupported addition to hp2xx, not a regular
  39.  **          module!
  40.  **
  41.  ** 91/12/01  V 1.00  NM   Originating (using HWW's TO_PIC
  42.  **                        as prototype)
  43.  ** 92/02/23  V 1.10  NM   ANSI-style, bottom-up-style
  44.  ** 92/02/27  V 1.10a NM   errno.h added
  45.  ** 92/04/14  V 1.10b NM   New order for if (...) { ... }
  46.  ** 92/05/19  V 1.10c HWW  Abort if color mode
  47.  **/
  48.  
  49. #include <stdio.h>
  50. #include <stdlib.h>
  51. #include <string.h>
  52. #include <errno.h>
  53. #include "bresnham.h"
  54. #include "hp2xx.h"
  55.  
  56.  
  57.  
  58.  
  59. #define PAC_XRES       640             /* defining a "screen"  */
  60. #define PAC_YRES       400
  61. #define PAC_BPL        (PAC_XRES>>3)   /* Byte Per Line        */
  62.  
  63.  
  64. #define TESTHORI        0              /* modes for using      */
  65. #define TESTVERTI       1              /* Pack_PAC             */
  66. #define WRITEHORI       2
  67. #define WRITEVERTI      3
  68. #define WRITEUNPACKED   4
  69.  
  70.  
  71.  
  72. /* -------------------------------------------------------- */
  73.  
  74.  
  75. int     Screenpos_PAC (int *scr_x, int *scr_y, int mode)
  76. /** *scr_x, *scr_y; position in unpacked screen-dump
  77.  ** mode;           actual compression mode
  78.  ** increases absolute and x/y byte-position in screen or
  79.  ** returns 32000, if increase is not senseful
  80.  **/
  81. {
  82.     int     nr;         /* absolute byte-number */
  83.     int     x = *scr_x; /* just to ease my work */
  84.     int     y = *scr_y; /* ...                  */
  85.  
  86.     if (mode == TESTVERTI || mode == WRITEVERTI)
  87.     {
  88.         y++;
  89.     if (y >= 400)
  90.     {
  91.         y = 0;
  92.         x++;
  93.     }
  94.     }
  95.     else
  96.     {
  97.         x++;
  98.     if (x >= 80)
  99.     {
  100.             x = 0;
  101.             y++;
  102.         }
  103.     }
  104.  
  105.     if (x >= 80 || y >= 400)
  106.     {
  107.     nr = 32000;
  108.     }
  109.     else
  110.     {
  111.         nr = x + y * 80;
  112.     }
  113.  
  114.     *scr_x = x;
  115.     *scr_y = y;
  116.  
  117.     return nr;
  118. }
  119.  
  120.  
  121. /* -------------------------------------------------------- */
  122.  
  123.  
  124. int     Pack_PAC(Byte *screen, Byte packbyte, Byte lablbyte, Byte specbyte,
  125.                  int mode, FILE *fd)
  126. /** *screen;         unpacked 32k-bitmap
  127.  ** packbyte;        most frequent byte in screen
  128.  ** lablbyte;        indicates packbyte
  129.  ** specbyte;        indicates repetitions and
  130.  **                  pack-, labl- or specbyte
  131.  ** mode;    TESTHORI     = test horiz. compression
  132.  **          TESTVERTI    = test vert.  compression
  133.  **          WRITEHORI    = write horiz. compr. file
  134.  **          WRITEVERTI   = write verti. compr. file
  135.  **          WRITEUNPACKED= write uncompressed  file
  136.  ** *fd;             file descriptor of PAC file
  137.  **/
  138.  
  139. /** result is:   calculated length of PAC-file
  140.  **                  for mode = TESTxxx
  141.  **              32000 if no efficient compression is
  142.  **                  possible
  143.  **              0 for mode = WRITExxx
  144.  **              ERROR for occuring errors
  145.  **/
  146.  
  147. {
  148.     int     scr_x = 0, scr_y = 0;   /* x/y-position in screen   */
  149.     int     scr_pos = 0;            /* byte-position in screen  */
  150.  
  151.     int     pac_pos = 0;            /* byte-position in PAC    */
  152.     Byte    actbyte;                /* actual byte              */
  153.     int     rep;                    /* repetitions (of bytes)   */
  154.     Byte    repbyte;                /* repetition-byte          */
  155.     Byte    nullbyte = 0;           /* contains 0               */
  156.  
  157.     int     pac_pos_org;            /* to store the original    */
  158.     Byte    actbyte_org;            /* state of ...             */
  159.  
  160.     char    horimark[4]  = {'p', 'M', '8', '5'};
  161.     char    vertimark[4] = {'p', 'M', '8', '6'};
  162.                                     /* STAD was written by      */
  163.                                     /* Peter Melzer in 1985/86  */
  164.  
  165.     if (mode != WRITEUNPACKED)
  166.     {
  167.         /* compression required */
  168.  
  169.         /*                          */
  170.         /* Label: 'pM85' or 'pM86'  */
  171.         /*                          */
  172.  
  173.     if (mode == WRITEHORI || mode == WRITEVERTI)
  174.     {
  175.             /* writing required */
  176.  
  177.         if (mode == WRITEHORI)
  178.         {
  179.         /* write 'pM85' (horizontal compression)    */
  180.         if (fwrite((char *) horimark, (size_t) 1, (size_t) 4, fd) != (size_t) 4)
  181.             return ERROR;
  182.  
  183.         }
  184.         else
  185.         {
  186.                 /* write 'pM86' (vertical compression)  */
  187.                 if (fwrite((char *) vertimark, (size_t) 1, (size_t) 4, fd) != (size_t) 4)
  188.                     return ERROR;
  189.             }
  190.         }
  191.         pac_pos += 4;
  192.  
  193.         /*                                  */
  194.         /* label-, pack-, and special-byte  */
  195.         /*                                  */
  196.  
  197.     if (mode == WRITEHORI || mode == WRITEVERTI)
  198.     {
  199.             /* write pack-, label-, and special-byte    */
  200.             if (fwrite((Byte *) &lablbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  201.                 return ERROR;
  202.             if (fwrite((Byte *) &packbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  203.                 return ERROR;
  204.             if (fwrite((Byte *) &specbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  205.         return ERROR;
  206.         }
  207.         pac_pos += 3;
  208.  
  209.         do {
  210.             actbyte = *(screen + scr_pos);
  211.  
  212.         if (actbyte == packbyte)
  213.         {
  214.                 /*                          */
  215.                 /* special case: packbyte   */
  216.                 /*                          */
  217.         if (mode == WRITEHORI || mode == WRITEVERTI)
  218.         {
  219.             /* write lablbyte (indicates packbyte-repetition)   */
  220.             if (fwrite((Byte *) &lablbyte, (size_t) 1,
  221.                    (size_t) 1, fd) != (size_t) 1)
  222.                 return ERROR;
  223.                 }
  224.                 /* determine number of packbyte-repetitions:    */
  225.                 pac_pos++;
  226.                 scr_pos = Screenpos_PAC(&scr_x, &scr_y, mode);
  227.                 rep = 0;
  228.         if (scr_pos < 32000)
  229.         {
  230.                     /* not at the end of the screen-dump    */
  231.                     actbyte = *(screen + scr_pos);
  232.             while (actbyte == packbyte && rep < 255)
  233.             {
  234.                         scr_pos = Screenpos_PAC(&scr_x, &scr_y, mode);
  235.                         rep++;
  236.                         if (scr_pos >= 32000) break;
  237.                         actbyte = *(screen + scr_pos);
  238.                     }
  239.                 }
  240.                 repbyte = (Byte) rep;
  241.         if (mode == WRITEHORI || mode == WRITEVERTI)
  242.         {
  243.                     /* write number of packbyte-repetions   */
  244.                     if (fwrite((Byte *) &repbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  245.                         return ERROR;
  246.                 }
  247.                 pac_pos++;
  248.  
  249.         }
  250.         else if (actbyte == lablbyte)
  251.         {
  252.                 /*                                              */
  253.                 /* special case: label-byte (needs a special    */
  254.                 /*               representation)                */
  255.                 /*                                              */
  256.         if (mode == WRITEHORI || mode == WRITEVERTI)
  257.         {
  258.                     /* write specbyte   */
  259.                     if (fwrite((Byte *) &specbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  260.                         return ERROR;
  261.                 }
  262.                 pac_pos++;
  263.         if (mode == WRITEHORI || mode == WRITEVERTI)
  264.         {
  265.                     /* write lablbyte (which should be indicated) */
  266.                     if (fwrite((Byte *) &lablbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  267.                         return ERROR;
  268.                 }
  269.                 /* determine number of lablbytes:   */
  270.                 pac_pos++;
  271.                 scr_pos = Screenpos_PAC(&scr_x, &scr_y, mode);
  272.                 rep = 0;
  273.         if (scr_pos < 32000)
  274.         {
  275.                     /* not at the end of the screen-dump    */
  276.                     actbyte = *(screen + scr_pos);
  277.             while (actbyte == lablbyte && rep < 255)
  278.             {
  279.                         scr_pos = Screenpos_PAC(&scr_x, &scr_y, mode);
  280.                         rep++;
  281.                         if (scr_pos >= 32000) break;
  282.                         actbyte = *(screen + scr_pos);
  283.                     }
  284.                 }
  285.                 repbyte = (Byte) rep;
  286.         if (mode == WRITEHORI || mode == WRITEVERTI)
  287.         {
  288.                     /* write number of lablbyte-repetions   */
  289.                     if (fwrite((Byte *) &repbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  290.                         return ERROR;
  291.                 }
  292.                 pac_pos++;
  293.  
  294.         }
  295.         else if (actbyte == specbyte)
  296.         {
  297.                 /*                                              */
  298.                 /* special case: special-byte   (needs a        */
  299.                 /*                special representation)       */
  300.                 /*                                              */
  301.         if (mode == WRITEHORI || mode == WRITEVERTI)
  302.         {
  303.                     /* write specbyte   */
  304.                     if (fwrite((Byte *) &specbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  305.                         return ERROR;
  306.                 }
  307.                 pac_pos++;
  308.         if (mode == WRITEHORI || mode == WRITEVERTI)
  309.         {
  310.                     /* write specbyte (which should be indicated) */
  311.                     if (fwrite((Byte *) &specbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  312.                         return ERROR;
  313.                 }
  314.                 /* determine number of specbytes:   */
  315.                 pac_pos++;
  316.                 scr_pos = Screenpos_PAC(&scr_x, &scr_y, mode);
  317.                 rep = 0;
  318.         if (scr_pos < 32000)
  319.         {
  320.                     /* not at the end of the screen-dump    */
  321.                     actbyte = *(screen + scr_pos);
  322.             while (actbyte == specbyte && rep < 255)
  323.             {
  324.                         scr_pos = Screenpos_PAC(&scr_x, &scr_y, mode);
  325.                         rep++;
  326.                         if (scr_pos >= 32000) break;
  327.                         actbyte = *(screen + scr_pos);
  328.                     }
  329.                 }
  330.                 repbyte = (Byte) rep;
  331.         if (mode == WRITEHORI || mode == WRITEVERTI)
  332.         {
  333.                     /* write number of specbyte-repetions   */
  334.                     if (fwrite((Byte *) &repbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  335.                         return ERROR;
  336.                 }
  337.                 pac_pos++;
  338.  
  339.         }
  340.         else
  341.         {
  342.         /*              */
  343.         /* normal byte  */
  344.         /*              */
  345.         if (scr_pos < 31999)
  346.         {
  347.             /* byte-repetition possible (not at the end)    */
  348.  
  349.             actbyte_org = actbyte;  /* conservate state     */
  350.             pac_pos_org = pac_pos;  /* before searching     */
  351.                         /* for repetitions      */
  352.  
  353.             /* determine number of byte-repetitions:    */
  354.             pac_pos++;
  355.             scr_pos = Screenpos_PAC(&scr_x, &scr_y, mode);
  356.             rep = 0;
  357.             if (scr_pos < 32000)
  358.             {
  359.                         /* not at the end of the screen-dump    */
  360.                         actbyte = *(screen + scr_pos);
  361.             while (actbyte == actbyte_org && rep < 255)
  362.             {
  363.                             scr_pos = Screenpos_PAC(&scr_x, &scr_y, mode);
  364.                             rep++;
  365.                             if (scr_pos >= 32000) break;
  366.                             actbyte = *(screen + scr_pos);
  367.                         }
  368.                     }
  369.  
  370.             if (rep == 0)         /* no repetition    */
  371.             {
  372.             actbyte = actbyte_org;  /* restore old state    */
  373.             pac_pos = pac_pos_org;
  374.  
  375.             if (mode == WRITEHORI || mode == WRITEVERTI) {
  376.                 /* write single byte    */
  377.             if (fwrite((Byte *) &actbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  378.                 return ERROR;
  379.             }
  380.             pac_pos++;
  381.             }
  382.             else
  383.             {                /* with repetition  */
  384.                         actbyte = actbyte_org;  /* restore old state    */
  385.                         pac_pos = pac_pos_org;
  386.  
  387.             if (mode == WRITEHORI || mode == WRITEVERTI)
  388.             {
  389.                             /* write specbyte   */
  390.                             if (fwrite((Byte *) &specbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  391.                                 return ERROR;
  392.                         }
  393.                         pac_pos++;
  394.  
  395.             if (mode == WRITEHORI || mode == WRITEVERTI)
  396.             {
  397.                             /* write repeating byte */
  398.                             if (fwrite((Byte *) &actbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  399.                                 return ERROR;
  400.                         }
  401.                         pac_pos++;
  402.  
  403.                         repbyte = (Byte) rep;
  404.             if (mode == WRITEHORI || mode == WRITEVERTI)
  405.             {
  406.                             /* write repetition number  */
  407.                             if (fwrite((Byte *) &repbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  408.                                 return ERROR;
  409.                         }
  410.                         pac_pos++;
  411.             }
  412.         }
  413.         else
  414.         {
  415.                     /* byte-repetition not possible due to the end  */
  416.  
  417.             if (mode == WRITEHORI || mode == WRITEVERTI)
  418.             {
  419.                             /* write single byte    */
  420.                             if (fwrite((Byte *) &actbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  421.                                 return ERROR;
  422.                         }
  423.                         scr_pos = Screenpos_PAC(&scr_x, &scr_y, mode);
  424.                         pac_pos++;
  425.                 }
  426.             }
  427.  
  428.         } while (pac_pos < 31997 && scr_pos < 32000);
  429.  
  430.     if (pac_pos < 31997)  /* compression was effective    */
  431.     {
  432.         if (mode == WRITEHORI || mode == WRITEVERTI)
  433.         {
  434.                 /* write final: specbyte + Ox00 + Ox00  */
  435.                 if (fwrite((Byte *) &specbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  436.                     return ERROR;
  437.                 if (fwrite((Byte *) &nullbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  438.                     return ERROR;
  439.                 if (fwrite((Byte *) &nullbyte, (size_t) 1, (size_t) 1, fd) != (size_t) 1)
  440.                     return ERROR;
  441.                 return 0;
  442.             }
  443.             pac_pos += 3;
  444.             return pac_pos;
  445.     }
  446.     else
  447.     {                /* compression was ineffective  */
  448.         if (mode == WRITEHORI || mode == WRITEVERTI)
  449.         {
  450.         /* in WRITExxx-mode (with compression) you should   */
  451.         /* never reach this place !                         */
  452.         return ERROR;
  453.         }
  454.         return 32000;
  455.     }
  456.  
  457.     }
  458.     else
  459.     {
  460.             /* writing unpacked screen-dump */
  461.             if (fwrite((Byte *) screen, (size_t) 1, (size_t) 32000, fd) < (size_t) 32000)
  462.                 return ERROR;
  463.  
  464.             return 0;
  465.     }
  466. }
  467.  
  468.  
  469. /* -------------------------------------------------------- */
  470.  
  471.  
  472. void    Analyze_PAC(Byte *screen, Byte *packbyte, Byte *lablbyte,
  473.                     Byte *specbyte)
  474. /** *screen;         unpacked 32k-bitmap
  475.  ** *packbyte;       most frequent byte in screen
  476.  ** *lablbyte;       indicates packbyte
  477.  ** *specbyte;       indicates repetitions and
  478.  **                  pack-, labl- or specbyte
  479.  **/
  480. {
  481.     int     i;
  482.     int     freq[256];      /* frequency of bytes in picture */
  483.  
  484.     *packbyte = (Byte) 0;
  485.     *lablbyte = (Byte) 0;
  486.     *specbyte = (Byte) 0;
  487.  
  488.     /* initialize frequency-array */
  489.     for (i = 0; i < 256; i++)
  490.         freq[i] = 0;
  491.  
  492.     /* determine frequency of bytes */
  493.     for (i = 0; i < 32000; i++)
  494.         freq[(int) *(screen + i)]++;
  495.  
  496.     /* determine most frequent byte (packbyte) */
  497.     for (i = 0; i < 256; i++)
  498.         if (freq[i] > freq[(int) *packbyte])
  499.             *packbyte = (Byte) i;
  500.  
  501.     /* determine byte with lowest frequency (lablbyte)  */
  502.     while (*lablbyte == *packbyte)  /* avoid identity   */
  503.         (*lablbyte)++;
  504.  
  505.     for (i = 0; i < 256; i++)
  506.         if (freq[i] < freq[(int) *lablbyte] && (Byte)i != *packbyte)
  507.             *lablbyte = (Byte) i;
  508.  
  509.     /* determine byte with second lowest frequency (specbyte)   */
  510.     while (*specbyte == *packbyte || *specbyte == *lablbyte)
  511.         (*specbyte)++;                      /* avoid identity   */
  512.  
  513.     for (i = 0; i < 256; i++)
  514.         if (freq[i] < freq[(int) *specbyte]
  515.             && (Byte)i != *packbyte && (Byte)i != *lablbyte)
  516.             *specbyte = (Byte) i;
  517. }
  518.  
  519.  
  520. /* -------------------------------------------------------- */
  521.  
  522.  
  523. void    Screen_for_PAC (PicBuf *picbuf, Byte *screen, int x, int y)
  524. /** *picbuf;         structure of hp2xx-bitmap
  525.  ** *screen;         32000 byte buffer (1 screen)
  526.  ** x, y;            actual screen
  527.  ** copies bitmap section into screen-buffer
  528.  **/
  529. {
  530.   RowBuf        *row;           /* pointer to one row   */
  531.   int           buf_x, buf_y;   /* position in bitmap   */
  532.   int           scr_x, scr_y;   /* position in screen   */
  533.   int           row_nr;         /* actual row-number    */
  534.  
  535.  
  536.   for (buf_y = PAC_YRES * y, scr_y = 0; scr_y < PAC_YRES; buf_y++, scr_y++)
  537.   {
  538.      for (buf_x = PAC_BPL * x, scr_x = 0; scr_x < PAC_BPL; buf_x++, scr_x++)
  539.      {
  540.  
  541.     if (buf_y < picbuf->nr && buf_x < picbuf->nb)
  542.     {
  543.         row_nr = picbuf->nr - (buf_y + 1);
  544.         row = get_RowBuf(picbuf, row_nr);
  545.         screen[scr_x + scr_y * PAC_BPL] = (Byte) row->buf[buf_x];
  546.     }
  547.     else
  548.         screen[scr_x + scr_y * PAC_BPL] = (Byte) 0;
  549.      }
  550.   }
  551. }
  552.  
  553.  
  554. /* -------------------------------------------------------- */
  555.  
  556.  
  557. void    Name_PAC (char *filename, char *basename, int y_screens,
  558.                   int x, int y)
  559. /* adds number and extension to basename, giving the complete filename */
  560. {
  561.   char  ext[9];    /* file-number and extension    */
  562.   int    nr;        /* file-number                    */
  563.  
  564.   nr = x * (y_screens + 1) + y;
  565.  
  566.   sprintf(ext,"%02d.pac", nr);
  567.   strcpy (filename, basename);
  568.   strcat (filename, ext);
  569.  
  570. }
  571.  
  572.  
  573. /* -------------------------------------------------------- */
  574.  
  575.  
  576. void    PicBuf_to_PAC (PicBuf *picbuf, PAR *p)
  577. /** *picbuf;         structure of hp2xx-bitmap
  578.  ** *p;              all parameters
  579.  ** "main" programm of to_stad.c
  580.  **/
  581. {
  582.  
  583. #define BLOCKS 100       /* max. 100 files        */
  584.  
  585.  
  586. FILE    *fd;                    /* stream handle                */
  587. int     x_screens, y_screens;   /* max. of file-counters        */
  588. int     x, y;                   /* file-counters                */
  589. char    basename[32];           /* filename without extension   */
  590. char    filename[96];           /* filename, complete           */
  591.  
  592. static Byte screen[32000];      /* sorry for wasting memory,    */
  593.                 /* but there's no convincing    */
  594.                 /* STAD-packaging mechanism     */
  595.                 /* without at least 32000 bytes */
  596.                 /* of the valuable memory       */
  597.  
  598. Byte    packbyte;               /* most frequent byte in screen */
  599. Byte    lablbyte;               /* indicates packbyte           */
  600. Byte    specbyte;               /* indicates repetitions and    */
  601.                 /* pack-, labl- or specbyte     */
  602.  
  603. int     horicompr;              /* length horiz. compr. picture */
  604. int     verticompr;             /* length verti. compr. picture */
  605.  
  606. #ifdef VAX
  607. int     hd;                     /* file handle                  */
  608. #endif
  609.  
  610.   if (picbuf->depth > 1)
  611.   {
  612.     fprintf(stderr, "\nPAC mode does not support colors yet -- sorry\n");
  613.     free_PicBuf (picbuf, p->swapfile);
  614.     exit (ERROR);
  615.   }
  616.  
  617.  /**
  618.   **  check number of screens (rows * columns)
  619.   **/
  620.   x_screens = (picbuf->nb - 1) / PAC_BPL;
  621.   y_screens = (picbuf->nr - 1) / PAC_YRES;
  622.  
  623.   if (((x_screens + 1) * (y_screens + 1)) > BLOCKS)
  624.   {
  625.     perror("hp2xx -- Too many PAC files necessary");
  626.     free_PicBuf (picbuf, p->swapfile);
  627.     exit (ERROR);
  628.   }
  629.  
  630.  /**
  631.   **  action message
  632.   **/
  633.   if (!p->quiet)
  634.   {
  635.       fprintf(stderr, "\n\nWriting PAC output: %d rows of %d bytes\n",
  636.               picbuf->nr, picbuf->nb);
  637.       fprintf(stderr, "corresponding to %d x %d PAC-files\n",
  638.               x_screens + 1, y_screens + 1);
  639.   }
  640.  
  641.  /**
  642.   **  creat basename (filename without extension)
  643.   **/
  644.   if (*p->outfile)
  645.   {
  646.     strncpy (basename, p->outfile, 6);
  647.     basename[6] = '\0';
  648.   }
  649.   else
  650.     strcpy  (basename, "stad");     /* Default name */
  651.  
  652.  /**
  653.   **  run over all screens
  654.   **/
  655.   for (y = 0; y <= y_screens; y++)
  656.   {
  657.     for (x = 0; x <= x_screens; x++)
  658.     {
  659.     /* make actual filename */
  660.     Name_PAC (filename, basename, y_screens, x, y);
  661.     if (!p->quiet)
  662.         fprintf(stderr,"%s-> ", filename);
  663.  
  664.     /* collect data from hp2xx-bitmap   */
  665.     if (!p->quiet)
  666.         fprintf(stderr,"data: fetch, ");
  667.     Screen_for_PAC (picbuf, screen, x, y);
  668.  
  669.     /* determine pack-, label-, special-byte */
  670.     if (!p->quiet)
  671.         fprintf(stderr,"analyse [1");
  672.     Analyze_PAC(screen, &packbyte, &lablbyte, &specbyte);
  673.     if (!p->quiet)
  674.         fprintf(stderr,"] ");
  675.  
  676.     /* preset file-descriptor (to give him a defined state) */
  677.     fd = NULL;
  678.  
  679.     /* test horizontal compression mode */
  680.     if (!p->quiet)
  681.         fprintf(stderr,"[2");
  682.     if ((horicompr = Pack_PAC(screen, packbyte, lablbyte, specbyte,
  683.              TESTHORI, fd)) == ERROR)
  684.     {
  685.         perror ("\nhp2xx -- test horiz.-PAC file");
  686.         free_PicBuf (picbuf, p->swapfile);
  687.         exit (ERROR);
  688.     }
  689.     if (!p->quiet)
  690.         fprintf(stderr,"] ");
  691.  
  692.     /* test vertical compression mode */
  693.     if (!p->quiet)
  694.         fprintf(stderr,"[3");
  695.     if ((verticompr = Pack_PAC(screen, packbyte, lablbyte, specbyte,
  696.               TESTVERTI, fd)) == ERROR)
  697.     {
  698.         perror ("\nhp2xx -- test vert.-PAC file");
  699.         free_PicBuf (picbuf, p->swapfile);
  700.         exit (ERROR);
  701.     }
  702.     if (!p->quiet)
  703.         fprintf(stderr,"] ;");
  704.  
  705.     /* open file to write   */
  706.     if (!p->quiet)
  707.         fprintf(stderr,"file: open, ");
  708. #ifdef VAX
  709.     if ((hd = creat(filename, 0,"rfm=var","mrs=512")) == -1)
  710.         perror ("\nhp2xx -- creating PAC-output file");
  711.     if( (fd = fdopen(hd, WRITE_BIN)) == NULL)
  712.     {
  713. #else
  714.     if ((fd = fopen(filename, WRITE_BIN)) == NULL)
  715.     {
  716. #endif
  717.         perror ("\nhp2xx -- opening PAC file");
  718.         free_PicBuf (picbuf, p->swapfile);
  719.         exit (ERROR);
  720.     }
  721.  
  722.     /* decide which file shall be written   */
  723.     if (!p->quiet)
  724.         fprintf(stderr,"write, ");
  725.     if (horicompr >= 32000 && verticompr >= 32000)
  726.     {
  727.         /* no compression was sucessfull, write unpacked file   */
  728.         if (Pack_PAC(screen, packbyte, lablbyte, specbyte,
  729.               WRITEUNPACKED, fd))
  730.         {
  731.         perror ("\nhp2xx -- writing PAC file");
  732.         free_PicBuf (picbuf, p->swapfile);
  733.         exit (ERROR);
  734.         }
  735.     }
  736.     else if (horicompr <= verticompr)
  737.     {
  738.         /* horizontal compression was better, write it  */
  739.         if (Pack_PAC(screen, packbyte, lablbyte, specbyte,
  740.               WRITEHORI, fd))
  741.         {
  742.         perror ("\nhp2xx -- writing PAC file");
  743.         free_PicBuf (picbuf, p->swapfile);
  744.         exit (ERROR);
  745.         }
  746.     }
  747.     else
  748.     {
  749.         /* vertical compression was better, write it    */
  750.         if (Pack_PAC(screen, packbyte, lablbyte, specbyte,
  751.               WRITEVERTI, fd))
  752.         {
  753.         perror ("\nhp2xx -- writing PAC file");
  754.         free_PicBuf (picbuf, p->swapfile);
  755.         exit (ERROR);
  756.         }
  757.     }
  758.  
  759.  
  760.     /* close file   */
  761.     if (!p->quiet)
  762.         fprintf(stderr,"close");
  763.     fclose(fd);
  764.  
  765.     /* line feed    */
  766.     if (!p->quiet)
  767.         fprintf(stderr,"\n");
  768.  
  769.     }
  770.   }
  771.  
  772.     /* final message    */
  773.     if (!p->quiet)
  774.     fprintf(stderr,"(End of PAC)\n");
  775.  
  776. }
  777.