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

  1. /*
  2.    Copyright (c) 1992  Norbert Meyer & Heinz W. Werntges.  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_img.c:   converts the HP2xx-intern bitmap into a GEM bit-
  25.  **             image file, normally labelled with the extension
  26.  **             IMG --- part of project "hp2xx" (from Heinz Werntges).
  27.  **
  28.  **             The IMG-format was originally proposed as standard
  29.  **             bit-image format for the graphical enviroment GEM
  30.  **             by Digital Research which is used by the Atari ST
  31.  **             and TT computers (GEM and the IMG-format are also
  32.  **             available for IBM PC-compatible computers). But
  33.  **             during the first years other pixel graphic formats
  34.  **             became popular. Now, the Atari ST, TT-series begins
  35.  **             to diversify and the IMG-format has a Renaissance,
  36.  **             since it is independent from the used screen type.
  37.  **             In future the IMG-format will be one of the most
  38.  **             important pixel graphic-formats for Atari ST, TT-
  39.  **             computers.
  40.  **
  41.  **             A second reason why the IMG-format is important is
  42.  **             the fact, that the Public Domain Atari-TeX supports
  43.  **             it - and HP2xx has the intent to be a tool for TeX.
  44.  **
  45.  **
  46.  ** 91/12/13  V 1.00  NM   Originating (Friday, 13th!)
  47.  ** 92/01/26  V 1.01  NM   Bottom-up order, ANSI style calls
  48.  ** 92/02/28  V 1.02  NM   Percent information instead of activity-points
  49.  ** 92/05/17  V 1.02b HWW  Output to stdout if outfile == '-'
  50.  ** 92/05/19  V 1.02c HWW  Abort if color mode
  51.  ** 92/11/08  V 1.02d HWW  File opening changed to standard
  52.  **
  53.  ** NOTE by HWW: This file is maintained by NM (due to lack of time,
  54.  **              only occasionally). Recent changes done by myself
  55.  **              only resulted out of necessity. Volunteer maintainers for
  56.  **              this file should contact NM (for his address, see file
  57.  **              hp2xx.c). I guess he'll be willing to hand this job over.
  58.  **/
  59.  
  60. #include <stdio.h>
  61. #include <stdlib.h>
  62. #include <string.h>
  63. #include "bresnham.h"
  64. #include "hp2xx.h"
  65.  
  66.  
  67.  
  68. Byte    get_byte_IMG(int row_c, int pos, PicBuf *picbuf)
  69. /* yields one byte which should be analyzed */
  70. {
  71.     int     row_nr;     /* "real" row number    */
  72.     RowBuf  *row;       /* pointer to one row   */
  73.     Byte    get_byte;   /* byte to be returned  */
  74.  
  75.     row_nr = picbuf->nr - (row_c + 1);
  76.     row = get_RowBuf(picbuf, row_nr);
  77.     get_byte = (Byte) row->buf[pos];
  78.  
  79.     return (get_byte);
  80. }
  81.  
  82.  
  83. /* ---------------------------------------------------------------- */
  84.  
  85.  
  86. int     vert_rep_IMG(int row_c, PicBuf *picbuf)
  87. /* determines number of vertical repetitions of a row */
  88. {
  89.     int     vert_rep = 0;       /* vertical repetition factor   */
  90.  
  91.     int     Img_w = picbuf->nb; /* number of bytes/rows         */
  92.     int     Img_h = picbuf->nr; /* number of rows               */
  93.  
  94.     int     pos;                /* position in row              */
  95.  
  96.     Byte    org_byte;           /* byte in original row         */
  97.     Byte    cmp_byte;           /* byte in compared row         */
  98.  
  99.     int     cmp_row_c = row_c +1;   /* row number of compared row   */
  100.  
  101.  
  102.     while (cmp_row_c < Img_h)
  103.     {
  104.     /* following row(s) available   */
  105.  
  106.     for (pos = 0; pos < Img_w; pos++)
  107.     {
  108.         org_byte = get_byte_IMG(row_c, pos, picbuf);
  109.         cmp_byte = get_byte_IMG(cmp_row_c, pos, picbuf);
  110.  
  111.         if (org_byte != cmp_byte)
  112.         /* found first difference!  */
  113.         return vert_rep;
  114.     }
  115.  
  116.     cmp_row_c++;
  117.     vert_rep++;
  118.  
  119.     if(vert_rep >= 254) break;
  120.  
  121.     }
  122.  
  123.     return vert_rep;
  124. }
  125.  
  126.  
  127. /* ---------------------------------------------------------------- */
  128.  
  129.  
  130. int     empty_SR_IMG(int row_c, int pos, PicBuf *picbuf)
  131. /* determines number of empty solid runs starting at actual position    */
  132. {
  133.     int     empty_SR_c = 0; /* counts empty solid runs  */
  134.     int     cmp_pos;        /* it's position            */
  135.  
  136.     int     Img_w = picbuf->nb; /* number of bytes/row  */
  137.  
  138.  
  139.     for (cmp_pos = pos; cmp_pos < Img_w; cmp_pos++)
  140.     {
  141.     if(get_byte_IMG(row_c, cmp_pos, picbuf) != (Byte)0)
  142.         break;
  143.     empty_SR_c++;
  144.     if (empty_SR_c >= 127) break;
  145.     }
  146.     return empty_SR_c;
  147. }
  148.  
  149.  
  150. /* ---------------------------------------------------------------- */
  151.  
  152.  
  153. int     full_SR_IMG(int row_c, int pos, PicBuf *picbuf)
  154. /* determines number of full solid runs starting at actual position */
  155. {
  156.     int     full_SR_c = 0;  /* counts full solid runs   */
  157.     int     cmp_pos;        /* it's position            */
  158.  
  159.     int     Img_w = picbuf->nb; /* number of bytes/row  */
  160.  
  161.     for (cmp_pos = pos; cmp_pos < Img_w; cmp_pos++)
  162.     {
  163.     if(get_byte_IMG(row_c, cmp_pos, picbuf) != (Byte)255)
  164.         break;
  165.     full_SR_c++;
  166.     if (full_SR_c >= 127) break;
  167.     }
  168.     return full_SR_c;
  169. }
  170.  
  171.  
  172. /* ---------------------------------------------------------------- */
  173.  
  174.  
  175. int     PR_IMG(int row_c, int pos, PicBuf *picbuf)
  176. /* determines number of pattern runs starting at actual position    */
  177. {
  178.     int     PR_c = 0;       /* counts full solid runs           */
  179.     Byte    first_byte;     /* first byte of pattern (2 bytes)  */
  180.     Byte    second_byte;    /* second byte of pattern           */
  181.     Byte    cmp_1st_byte;   /* 1st byte for comparision         */
  182.     Byte    cmp_2nd_byte;   /* 2nd byte for comparision         */
  183.     int     cmp_pos;        /* actual position                  */
  184.  
  185.     int     Img_w = picbuf->nb; /* number of bytes/row  */
  186.  
  187.     if (pos + 3 < Img_w)
  188.     {
  189.     /* actual position is not end of the row    */
  190.     first_byte  = get_byte_IMG(row_c, pos, picbuf);
  191.     second_byte = get_byte_IMG(row_c, pos + 1, picbuf);
  192.  
  193.     for(cmp_pos = pos + 2; cmp_pos + 1 < Img_w; cmp_pos += 2)
  194.     {
  195.         cmp_1st_byte  = get_byte_IMG(row_c, cmp_pos, picbuf);
  196.         cmp_2nd_byte  = get_byte_IMG(row_c, cmp_pos + 1, picbuf);
  197.  
  198.         if (cmp_1st_byte != first_byte || cmp_2nd_byte != second_byte)
  199.         break;
  200.         PR_c++;
  201.         if (PR_c >= 254)
  202.         break;
  203.     }
  204.     return PR_c;
  205.     } else
  206.     /* actual position to close to the end of the row   */
  207.     return 0;
  208. }
  209.  
  210.  
  211. /* ---------------------------------------------------------------- */
  212.  
  213.  
  214. void    write_byte_IMG (Byte write_byte, PicBuf *picbuf, PAR *p, FILE *fd)
  215. /* Writes one Byte to the opened IMG-file   */
  216. {
  217.     if(fputc((int)write_byte, fd) == EOF)
  218.     {
  219.     perror("\nhp2xx --- writing IMG file:");
  220.     free_PicBuf (picbuf, p->swapfile);
  221.     exit(ERROR);
  222.     }
  223. }
  224.  
  225.  
  226. /* ---------------------------------------------------------------- */
  227.  
  228.  
  229. void    write_VR_IMG (Byte number, PicBuf *picbuf, PAR *p, FILE *fd)
  230. /* Writes vertical repetition label to the opened IMG-file  */
  231. {
  232.     write_byte_IMG((Byte)0, picbuf, p, fd);
  233.     write_byte_IMG((Byte)0, picbuf, p, fd);
  234.     write_byte_IMG((Byte)255, picbuf, p, fd);
  235.     write_byte_IMG(number, picbuf, p, fd);
  236. }
  237.  
  238.  
  239. /* ---------------------------------------------------------------- */
  240.  
  241.  
  242. void    write_PR_IMG (  Byte number, Byte first_byte, Byte second_byte,
  243.             PicBuf *picbuf, PAR *p, FILE *fd)
  244. /* Writes pattern run label to the opened IMG-file  */
  245. {
  246.     write_byte_IMG((Byte)0, picbuf, p, fd);
  247.     write_byte_IMG(number, picbuf, p, fd);
  248.     write_byte_IMG(first_byte, picbuf, p, fd);
  249.     write_byte_IMG(second_byte, picbuf, p, fd);
  250. }
  251.  
  252.  
  253. /* ---------------------------------------------------------------- */
  254.  
  255.  
  256. void    write_empty_SR_IMG (Byte number, PicBuf *picbuf, PAR *p, FILE *fd)
  257. /* Writes empty solid run to the opened IMG-file    */
  258. {
  259.     write_byte_IMG(number, picbuf, p, fd);
  260. }
  261.  
  262.  
  263. /* ---------------------------------------------------------------- */
  264.  
  265.  
  266. void    write_full_SR_IMG (Byte number, PicBuf *picbuf, PAR *p, FILE *fd)
  267. /* Writes empty solid run to the opened IMG-file    */
  268. {
  269.     Byte    write_byte = (Byte)128;
  270.  
  271.     write_byte = write_byte | number;
  272.     write_byte_IMG(write_byte, picbuf, p, fd);
  273. }
  274.  
  275.  
  276. /* ---------------------------------------------------------------- */
  277.  
  278.  
  279. void    write_BS_IMG (Byte number, PicBuf *picbuf, PAR *p, FILE *fd)
  280. /* Writes bit string label to the opened IMG-file   */
  281. {
  282.     write_byte_IMG((Byte)128, picbuf, p, fd);
  283.     write_byte_IMG(number, picbuf, p, fd);
  284. }
  285.  
  286.  
  287. /* ---------------------------------------------------------------- */
  288.  
  289.  
  290. void    PicBuf_to_IMG (PicBuf *picbuf, PAR *p)
  291. {
  292.     FILE    *fd;            /* file descriptor                  */
  293.  
  294.     int     row_c;                  /* row counter              */
  295.     int     Img_w = picbuf->nb;     /* bytes per row            */
  296.     int     Img_h = picbuf->nr;     /* number of lines          */
  297.  
  298.     int        percent = 0;            /* progression indicator    */
  299.  
  300.     int     Dpi_x = p->dpi_x;       /* dots per inch            */
  301.     int     Dpi_y = p->dpi_y;
  302.  
  303.     int     vert_rep;       /* vertical repetitions             */
  304.  
  305.     Byte    act_byte;       /* actual byte                      */
  306.  
  307.     int     act_pos;        /* actual byte-position in the row  */
  308.     int     first_pos = 0;  /* first pos. of bit string         */
  309.     int     last_pos = 0;   /* last pos. of bit string          */
  310.     int     i_pos;          /* loop index                       */
  311.  
  312.     int     open_BS;            /* was a bit string opened?     */
  313.  
  314.     int     empty_SR_len;       /* length of empty solid run    */
  315.     int     full_SR_len;        /* length of full solid run     */
  316.     int     PR_len;             /* length of pattern run        */
  317.     int     BS_len;             /* length of bit string         */
  318.  
  319.     int     idummy;
  320.     double  ddummy;
  321.  
  322.  
  323.     if (picbuf->depth > 1)
  324.     {
  325.     fprintf(stderr, "\nIMG mode does not support colors yet -- sorry\n");
  326.     free_PicBuf (picbuf, p->swapfile);
  327.     exit (ERROR);
  328.     }
  329.  
  330.     /*                  */
  331.     /* action message   */
  332.     /*                  */
  333.     if (!p->quiet)
  334.     {
  335.     fprintf(stderr, "\n\nWriting IMG output: %d rows of %d bytes\n",
  336.         picbuf->nr, picbuf->nb);
  337.     fprintf(stderr,"\n%s:\no open",
  338.         *p->outfile == '-' ? "<stdout>" : p->outfile);
  339.     }
  340.  
  341.  
  342.     if (*p->outfile != '-')
  343.     {
  344. #ifdef VAX
  345.     if ((fd = fopen(p->outfile, WRITE_BIN, "rfm=var","mrs=512")) == NULL)
  346.     {
  347. #else
  348.     if ((fd = fopen(p->outfile, WRITE_BIN)) == NULL)
  349.     {
  350. #endif
  351.         perror ("hp2xx -- opening output file");
  352.         free_PicBuf (picbuf, p->swapfile);
  353.         exit (ERROR);
  354.     }
  355.     }
  356.     else    fd = stdout;
  357.  
  358.  
  359.     /**
  360.      ** write header (8 words)
  361.      **/
  362.  
  363.     if (!p->quiet)
  364.     fprintf(stderr,"\no write\n  - header");
  365.  
  366.     /* version number = 1   */
  367.     write_byte_IMG((Byte)0, picbuf, p, fd);
  368.     write_byte_IMG((Byte)1, picbuf, p, fd);
  369.  
  370.     /* length of header (in words) = 8  */
  371.     write_byte_IMG((Byte)0, picbuf, p, fd);
  372.     write_byte_IMG((Byte)8, picbuf, p, fd);
  373.  
  374.     /* number of bits/pixel (bit-planes) = 1    */
  375.     write_byte_IMG((Byte)0, picbuf, p, fd);
  376.     write_byte_IMG((Byte)1, picbuf, p, fd);
  377.  
  378.     /* length of pattern run (in bytes) = 2     */
  379.     write_byte_IMG((Byte)0, picbuf, p, fd);
  380.     write_byte_IMG((Byte)2, picbuf, p, fd);
  381.  
  382.     /* width of pixel in 1/1000 mm  */
  383.     ddummy = (double)Dpi_x;
  384.     ddummy = 25.4 / ddummy * 1000.0 / 256;
  385.     act_byte = (Byte)ddummy;
  386.     write_byte_IMG(act_byte, picbuf, p, fd);
  387.     ddummy = (double)Dpi_x;
  388.     ddummy = 25.4 / ddummy * 1000.0;
  389.     idummy = (int)ddummy & 255;
  390.     act_byte = (Byte)idummy;
  391.     write_byte_IMG(act_byte, picbuf, p, fd);
  392.  
  393.     /* height of pixel in 1/1000 mm */
  394.     ddummy = (double)Dpi_y;
  395.     ddummy = 25.4 / ddummy * 1000.0 / 256;
  396.     act_byte = (Byte)ddummy;
  397.     write_byte_IMG(act_byte, picbuf, p, fd);
  398.     ddummy = (double)Dpi_y;
  399.     ddummy = 25.4 / ddummy * 1000.0;
  400.     idummy = (int)ddummy & 255;
  401.     act_byte = (Byte)idummy;
  402.     write_byte_IMG(act_byte, picbuf, p, fd);
  403.  
  404.     /* width of row in pixel    */
  405.     idummy = Img_w * 8 / 256;
  406.     act_byte = (Byte)idummy;
  407.     write_byte_IMG(act_byte, picbuf, p, fd);
  408.     idummy = Img_w * 8;
  409.     idummy = idummy & 255;
  410.     act_byte = (Byte)idummy;
  411.     write_byte_IMG(act_byte, picbuf, p, fd);
  412.  
  413.     /* number of rows */
  414.     idummy = Img_h  / 256;
  415.     act_byte = (Byte)idummy;
  416.     write_byte_IMG(act_byte, picbuf, p, fd);
  417.     idummy = Img_h;
  418.     idummy = idummy & 255;
  419.     act_byte = (Byte)idummy;
  420.     write_byte_IMG(act_byte, picbuf, p, fd);
  421.  
  422.     if (!p->quiet)
  423.         fprintf(stderr,"\n  - data: ");
  424.  
  425.     /**
  426.      **  Loop over all lines
  427.      **/
  428.  
  429.  
  430.  
  431.     for (row_c = 0; row_c < Img_h; row_c++)
  432.     {
  433.     /*      */
  434.     /* ...  */
  435.     /*      */
  436.     if(!p->quiet)
  437.     {
  438.         if((int)(((float)row_c * 100.0) / (float)Img_h) >= (percent + 10))
  439.         {
  440.                 percent += 10;
  441.                 fprintf(stderr, "%d%% ",percent);
  442.             }
  443.         }
  444.  
  445.         /*                                  */
  446.         /* Determine vertical repetition    */
  447.         /*                                  */
  448.     if ((vert_rep = vert_rep_IMG(row_c, picbuf)) > 0)
  449.     {
  450.             row_c += vert_rep;
  451.         if(!p->quiet)
  452.         {
  453.         if((int)(((float)row_c * 100.0) / (float)Img_h) >= (percent + 10))
  454.         {
  455.             percent += 10;
  456.             fprintf(stderr, "%d%% ",percent);
  457.         }
  458.         }
  459.         write_VR_IMG((Byte)(vert_rep + 1), picbuf, p, fd);
  460.     }
  461.  
  462.     /**
  463.      **  Analyse actual row in detail
  464.      **/
  465.  
  466.     /* prepare bit string switch        */
  467.  
  468.         open_BS = FALSE;
  469.  
  470.     /* prepare byte position            */
  471.  
  472.     act_pos = 0;
  473.  
  474.     /**
  475.      ** Loop over all bytes in actual row
  476.      **/
  477.     do {
  478.         if(open_BS == TRUE  )
  479.         {
  480.         /* bit string was opened before */
  481.  
  482.         if (  (empty_SR_len = empty_SR_IMG(row_c, act_pos, picbuf)) > 3
  483.            || (full_SR_len = full_SR_IMG(row_c, act_pos, picbuf)) > 3
  484.            || (PR_len = PR_IMG(row_c, act_pos, picbuf)) > 2
  485.            || act_pos >= Img_w - 1
  486.            || last_pos - first_pos + 1 >= 254)
  487.         {
  488.             /* it's worth to stop the bit string    */
  489.             open_BS = FALSE;
  490.  
  491.             if (act_pos >= Img_w -1)    /* special case:    */
  492.             {
  493.             last_pos = act_pos;     /* last byte in row */
  494.             act_pos++;
  495.             }
  496.  
  497.             BS_len = last_pos - first_pos + 1;
  498.             write_BS_IMG((Byte)BS_len, picbuf, p, fd);
  499.             for (i_pos = first_pos; i_pos <= last_pos; i_pos++)
  500.             {
  501.             act_byte = get_byte_IMG(row_c, i_pos, picbuf);
  502.             write_byte_IMG(act_byte, picbuf, p, fd);
  503.             }
  504.  
  505.         }
  506.         else
  507.         {
  508.             /* the bit string should continue   */
  509.             last_pos = act_pos;
  510.             act_pos++;
  511.         }
  512.  
  513.         } else {
  514.         /* no bit string open   */
  515.  
  516.         if ((empty_SR_len = empty_SR_IMG(row_c, act_pos, picbuf)) > 0)
  517.         {
  518.             act_pos += empty_SR_len;
  519.             write_empty_SR_IMG((Byte)empty_SR_len, picbuf, p, fd);
  520.  
  521.         }
  522.           else
  523.         if ((full_SR_len = full_SR_IMG(row_c, act_pos, picbuf)) > 0)
  524.         {
  525.             act_pos += full_SR_len;
  526.             write_full_SR_IMG((Byte)full_SR_len, picbuf, p, fd);
  527.  
  528.         }
  529.           else
  530.         if ((PR_len = PR_IMG(row_c, act_pos, picbuf)) > 0)
  531.         {
  532.             write_PR_IMG((Byte)(PR_len + 1),
  533.                  get_byte_IMG(row_c, act_pos, picbuf),
  534.                  get_byte_IMG(row_c, act_pos +1 , picbuf),
  535.                  picbuf, p, fd);
  536.             act_pos += (PR_len + 1) * 2;
  537.  
  538.         }
  539.           else
  540.         {    /* remaining: bit string, open it   */
  541.             open_BS = TRUE;
  542.             first_pos = act_pos;
  543.             last_pos  = act_pos;
  544.             if (act_pos < Img_w - 1)
  545.             act_pos++;
  546.         }
  547.  
  548.         }
  549.     } while (act_pos < Img_w);
  550.  
  551.     }
  552.  
  553.     if(!p->quiet)
  554.     if (percent < 100)
  555.         fprintf(stderr, "100%%");
  556.     fprintf(stderr, "\no close\n");
  557.  
  558.     if (fclose(fd) != 0)
  559.     {
  560.     perror("\nhp2xx -- closing IMG:");
  561.     free_PicBuf (picbuf, p->swapfile);
  562.     exit(ERROR);
  563.     }
  564.     if(!p->quiet)
  565.     fprintf(stderr, "\n(End of IMG)\n");
  566.  
  567. }
  568.  
  569.