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

  1. /*
  2.    Copyright (c) 1991 - 1993 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_pcx.c: PCX converter part of project "hp2xx"
  25.  **
  26.  ** 91/01/19  V 1.00  HWW  Originating: Format accepted by MS-Paintbrush,
  27.  **              but not by emTeX drivers
  28.  **              Use MS-Paintbrush "load/save" for conversion
  29.  ** 91/02/15  V 1.01  HWW  VAX_C support added (not tested yet!)
  30.  ** 91/02/18  V 1.02  HWW  PCX format: no zero run length allowed
  31.  ** 91/02/20  V 1.03  HWW  Some VAX_C changes, debugged
  32.  ** 91/06/09  V 1.04  HWW  New options added
  33.  ** 91/06/16  V 1.05  HWW  Writing of PCX header now machine-independent
  34.  ** 91/10/15  V 1.06  HWW  ANSI_C
  35.  ** 91/10/25  V 1.07  HWW  VAX: fopen() augmentations used, open() removed
  36.  ** 92/05/17  V 1.07b HWW  Output to stdout if outfile == '-'
  37.  ** 92/05/19  V 1.07c HWW  Abort if color mode
  38.  ** 92/06/08  V 1.08a HWW  First color version
  39.  **
  40.  **          NOTE: According to my tests, setting of the
  41.  **            color lookup table is ignored by other programs,
  42.  **            so this code is *preliminary* when color is used.
  43.  **            Correct colors appeared only if the color setting corresponded to
  44.  **            PC conventions...
  45.  **/
  46.  
  47.  
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50. #include "bresnham.h"
  51. #include "hp2xx.h"
  52.  
  53.  
  54. typedef    enum {PCX_INIT, PCX_NORMAL, PCX_EXIT}
  55.     PCXmode;
  56.  
  57.  
  58.  
  59.  
  60. void    RLEcode_to_file (int c, int repeat, FILE *fd)
  61. {
  62.   if ((repeat==1) && ((c & 0xC0) != 0xC0))
  63.   {
  64.     if (putc (c, fd) == EOF)
  65.     {
  66.         perror("RLEcode_to_file (1)");
  67.         exit    (ERROR);
  68.     }
  69.   }
  70.   else
  71.   {
  72.     if (putc (repeat | 0xC0, fd) == EOF)
  73.     {
  74.         perror("RLEcode_to_file (2)");
  75.         exit    (ERROR);
  76.     }
  77.     if (putc (c, fd) == EOF)
  78.     {
  79.         perror("RLEcode_to_file (3)");
  80.         exit    (ERROR);
  81.     }
  82.   }
  83. }
  84.  
  85.  
  86.  
  87.  
  88. void    byte_to_PCX (Byte b, PCXmode mode, FILE *fd)
  89. {
  90. static    last_b, rept;
  91.  
  92.   switch (mode)
  93.   {
  94.   case PCX_NORMAL:
  95.     if (b == last_b)
  96.     {
  97.         if (++rept == 63)
  98.         {
  99.             RLEcode_to_file (last_b, rept, fd);
  100.             rept = 0;
  101.         }
  102.     }
  103.     else
  104.     {
  105.         if (rept)
  106.             RLEcode_to_file (last_b, rept, fd);
  107.         rept    = 1;
  108.         last_b    = b;
  109.     }
  110.     break;
  111.  
  112.   case PCX_INIT:
  113.     rept = 0;
  114.     last_b = -2;    /* Init to impossible value    */
  115.     break;
  116.  
  117.   case PCX_EXIT:
  118.     if (rept)
  119.     {
  120.         RLEcode_to_file (last_b, rept, fd);
  121.         rept = 0;
  122.     }
  123.     break;
  124.   }
  125. }
  126.  
  127.  
  128.  
  129.  
  130.  
  131. typedef struct {
  132.     char    creator, version, encoding, bits;
  133.     short    xmin, ymin, xmax, ymax, hres, vres;
  134.     char    palette[16][3], vmode, planes;
  135.     short    byteperline, paletteinfo;
  136.     char    dummy[58];
  137. } PCXheader;
  138.  
  139.  
  140.  
  141. void    start_PCX (PAR *p, PicBuf *picbuf, FILE *fd)
  142. {
  143. PCXheader    h;
  144. int        i, j;
  145.  
  146.   h.creator    = 0x0A;        /* ZSoft label            */
  147.   h.version    = '\003';    /* V 2.8/3.0, no palette info    */
  148.   h.encoding    = 1;        /* RLE                */
  149.   h.bits    = 1;        /* Bits per pixel        */
  150.   h.xmin    = 0;            /* Range of bitmap        */
  151.   h.ymin    = 0;
  152.   h.xmax    = picbuf->nc - 1;
  153.   h.ymax    = picbuf->nr - 1;
  154.   h.hres    = p->dpi_x;    /* Resolution            */
  155.   h.vres    = p->dpi_y;
  156.  
  157.   for (i=0; i<8; i++)
  158.      for (j=0; j<3; j++)
  159.      {
  160.     h.palette[i  ][j] = p->Clut[i][j];
  161.     h.palette[i+8][j] = p->Clut[i][j];
  162.      }
  163.  
  164.   h.vmode    = 0;        /* Reserved               */
  165.   h.planes    = picbuf->depth;/* Number of color planes       */
  166.   h.byteperline    = picbuf->nb;    /* Number of bytes per line       */
  167.   h.paletteinfo    = 1;        /* 1 = color & b/w, 2 = gray scale */
  168.   for (i=0; i<58; )        /* Filler for a max. of 128 bytes  */
  169.   {
  170.     h.dummy[i++] = 'H';
  171.     h.dummy[i++] = 'W';
  172.   }
  173.  
  174. /**
  175.  ** For complete machine independence, a bytewise writing of this header
  176.  ** is mandatory. Else, fill bytes or HIGH/LOW-endian machines must be
  177.  ** considered. A simple "fwrite(h,128,1,fd)" may not suffice!
  178.  **/
  179.  
  180.   if (fputc (h.creator,    fd) == EOF)        goto ERROR_EXIT;
  181.   if (fputc (h.version,    fd) == EOF)        goto ERROR_EXIT;
  182.   if (fputc (h.encoding,fd) == EOF)        goto ERROR_EXIT;
  183.   if (fputc (h.bits,    fd) == EOF)        goto ERROR_EXIT;
  184.   if (fputc ((h.xmin & 0xff),    fd) == EOF)    goto ERROR_EXIT;
  185.   if (fputc ((h.xmin >> 8),    fd) == EOF)    goto ERROR_EXIT;
  186.   if (fputc ((h.ymin & 0xff),    fd) == EOF)    goto ERROR_EXIT;
  187.   if (fputc ((h.ymin >> 8),    fd) == EOF)    goto ERROR_EXIT;
  188.   if (fputc ((h.xmax & 0xff),    fd) == EOF)    goto ERROR_EXIT;
  189.   if (fputc ((h.xmax >> 8),    fd) == EOF)    goto ERROR_EXIT;
  190.   if (fputc ((h.ymax & 0xff),    fd) == EOF)    goto ERROR_EXIT;
  191.   if (fputc ((h.ymax >> 8),    fd) == EOF)    goto ERROR_EXIT;
  192.   if (fputc ((h.hres & 0xff),    fd) == EOF)    goto ERROR_EXIT;
  193.   if (fputc ((h.hres >> 8),    fd) == EOF)    goto ERROR_EXIT;
  194.   if (fputc ((h.vres & 0xff),    fd) == EOF)    goto ERROR_EXIT;
  195.   if (fputc ((h.vres >> 8),    fd) == EOF)    goto ERROR_EXIT;
  196.   if (fwrite((VOID *) h.palette,48,1,fd) != 1)    goto ERROR_EXIT;
  197.   if (fputc (h.vmode,    fd) == EOF)        goto ERROR_EXIT;
  198.   if (fputc (h.planes,    fd) == EOF)        goto ERROR_EXIT;
  199.   if (fputc ((h.byteperline & 0xff),fd) == EOF)    goto ERROR_EXIT;
  200.   if (fputc ((h.byteperline >> 8),  fd) == EOF)    goto ERROR_EXIT;
  201.   if (fputc ((h.paletteinfo & 0xff),fd) == EOF)    goto ERROR_EXIT;
  202.   if (fputc ((h.paletteinfo >> 8),  fd) == EOF)    goto ERROR_EXIT;
  203.   if (fwrite((VOID *) h.dummy,58,1,fd) != 1)    goto ERROR_EXIT;
  204.   return;
  205.  
  206. ERROR_EXIT:
  207.   perror      ("start_PCX");
  208.   free_PicBuf (picbuf, p->swapfile);
  209.   exit          (ERROR);
  210. }
  211.  
  212.  
  213.  
  214. void    PicBuf_to_PCX (PicBuf *picbuf, PAR *p)
  215. {
  216. FILE    *fd;
  217. RowBuf    *row;
  218. int    row_c, np, x;
  219. Byte    *pb;
  220.  
  221.   if (!p->quiet)
  222.     fprintf(stderr, "\nWriting PCX output\n");
  223.   if (*p->outfile != '-')
  224.   {
  225. #ifdef VAX
  226.     if ((fd = fopen(p->outfile, WRITE_BIN, "rfm=var","mrs=512")) == NULL)
  227.     {
  228. #else
  229.     if ((fd = fopen(p->outfile, WRITE_BIN)) == NULL)
  230.     {
  231. #endif
  232.         perror ("hp2xx -- opening output file");
  233.         free_PicBuf (picbuf, p->swapfile);
  234.         exit (ERROR);
  235.     }
  236.   }
  237.   else    fd = stdout;
  238.  
  239.   start_PCX (p, picbuf, fd);
  240.  
  241.   /* Backward since highest index is lowest line on screen! */
  242.   for (row_c = picbuf->nr - 1; row_c >= 0; row_c--)
  243.   {
  244.     if ((!p->quiet) && (row_c % 10 == 0))
  245.           /* For the impatients among us ...    */
  246.         putc('.',stderr);
  247.     row = get_RowBuf (picbuf, row_c);
  248.     byte_to_PCX (0, PCX_INIT, fd);
  249.     pb = row->buf;
  250.     for (np=0; np < picbuf->depth; np++)
  251.         for (x=0; x < picbuf->nb; x++)
  252.             byte_to_PCX (~*pb++, PCX_NORMAL, fd);
  253.     byte_to_PCX (0, PCX_EXIT, fd);    /* Flush    */
  254.   }
  255.   if (p->is_color && !p->quiet)
  256.     fprintf(stderr,"WARNING: PCX colors may (yet) be arbitrary!\n");
  257.  
  258.   if (!p->quiet)
  259.     fputc ('\n', stderr);
  260.   if (fd != stdout)
  261.     fclose (fd);
  262. }
  263.