home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / gnu / gs252b.lzh / GS252B / GDEVGIMG.C < prev    next >
C/C++ Source or Header  |  1993-07-30  |  5KB  |  174 lines

  1. /* Copyright (C) 1992 Aladdin Enterprises.  All rights reserved.
  2.    Distributed by Free Software Foundation, Inc.
  3.  
  4. This file is part of Ghostscript.
  5.  
  6. Ghostscript is distributed in the hope that it will be useful, but
  7. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  8. to anyone for the consequences of using it or for whether it serves any
  9. particular purpose or works at all, unless he says so in writing.  Refer
  10. to the Ghostscript General Public License for full details.
  11.  
  12. Everyone is granted permission to copy, modify and redistribute
  13. Ghostscript, but only under the conditions described in the Ghostscript
  14. General Public License.  A copy of this license is supposed to have been
  15. given to you along with Ghostscript so you can know your rights and
  16. responsibilities.  It should be in a file named COPYING.  Among other
  17. things, the copyright notice and this notice must be preserved on all
  18. copies.  */
  19.  
  20. /* gdevgimg.c */
  21. /* GEM image file format devices for Ghostscript */
  22. #include "gdevprn.h"
  23. #include "gserrors.h"        /* REALLY? */
  24.  
  25. /* This driver supports the GEM image format mainly used on Atari ST computers.
  26.  * I coded this driver by changing the PCX drivers originally written by
  27.  * Phil Conrad. It supports only monochrome picture because of the
  28.  * difficulties with storing the color palette in the GEM image format. For
  29.  * comments and bug reports please contact:
  30.  * haebler@dmswwu1a.uni-muenster.de
  31.  *                                  Marcus Haebler, 10.08.92 */
  32.  
  33. /* ------ The device descriptors ------ */
  34.  
  35. /*
  36.  * Standard U.S. page width and height.  A4 paper is 8.4" x 11.7".
  37.  */
  38. #define WIDTH_10THS 85
  39. #define HEIGHT_10THS 110
  40.  
  41. /*
  42.  * Default X and Y resolution.
  43.  */
  44. #define X_DPI 72
  45. #define Y_DPI 72
  46.  
  47. /* Monochrome. */
  48.  
  49. private dev_proc_print_page (gemimg_print_page);
  50.  
  51. gx_device_printer gs_gemimg_device =
  52. prn_device (prn_std_procs, "gemimg",
  53.         WIDTH_10THS, HEIGHT_10THS,
  54.         X_DPI, Y_DPI,
  55.         0, 0, 0, 0,        /* margins */
  56.         1, gemimg_print_page);
  57.  
  58. /* ------ Private definitions ------ */
  59.  
  60. typedef struct
  61.   {
  62.     short im_version;        /* normally '1' */
  63.     short im_headlength;    /* length in words */
  64.     short im_nplanes;        /* number of color planes */
  65.     short im_patlen;        /* pattern length in bytes (usually 2) */
  66.     short im_pixwidth;        /* pixel width in mm/1000 */
  67.     short im_pixheight;        /* pixel height in mm/1000 */
  68.     short im_scanwidth;        /* line width in pixels */
  69.     short im_nlines;        /* number of lines */
  70.   } img_header;
  71.  
  72.  
  73. /* Write a monochrome GEM image page. */
  74. private int
  75. gemimg_print_page (gx_device_printer * pdev, FILE * file)
  76. {
  77.   img_header header;
  78.   int height = pdev->height;
  79.   uint raster = (pdev->width + 7) >> 3;    /* how many bytes per line */
  80.   char *row1 = (char *) gs_malloc (raster, 1, "img line buffer 1");
  81.   char *row2 = (char *) gs_malloc (raster, 1, "img line buffer 2");
  82.   int y = 0, n, m, z, x = 0;
  83.   int code = 0;            /* return code */
  84.  
  85.   /* setup the header struct */
  86.   header.im_version = 1;
  87.   header.im_headlength = 8;
  88.   header.im_nplanes = 1;
  89.   header.im_patlen = 2;
  90.   header.im_pixwidth = (short) (25400. / pdev->x_pixels_per_inch + 0.5);
  91.   header.im_pixheight = (short) (25400. / pdev->y_pixels_per_inch + 0.5);
  92.   header.im_scanwidth = pdev->width;
  93.   header.im_nlines = pdev->height;
  94.  
  95.   if (row1 == 0 || row2 == 0)    /* can't allocate row buffer*/
  96.     return gs_error_VMerror;
  97.  
  98.   /* Write the header. */
  99.  
  100.   fwrite ((const char *) &header, 1, 16, file);
  101.  
  102.   /* Dump the contents of the image. */
  103.   while (y < height)
  104.     {
  105.       gdev_prn_copy_scan_lines (pdev, y, row1, raster);
  106.       for (n = 1; ((n + y) < height && n < 255); n++)    /* repeating lines? */
  107.     {
  108.       gdev_prn_copy_scan_lines (pdev, y + n, row2, raster);
  109.       if (memcmp ((char *) row1, (char *) row2, raster) != 0)
  110.         {
  111.           break;
  112.         }
  113.     }
  114.       if (n > 1)
  115.     {
  116.       fwrite ("\x00\x00\xff", 3, 1, file);
  117.       fputc (n, file);
  118.     }
  119.       /* code one line */
  120.       while (x < raster)
  121.     {
  122.       if (row1[x] == '\x00')/* solid run with \0 ? */
  123.         {
  124.           for (m = 1; (row1[x + m] == '\x00' && m < 127 &&
  125.                (x + m) < raster); m++);
  126.           fputc (m, file);
  127.           x += m;
  128.           continue;
  129.         }
  130.       if (row1[x] == '\xff')/* solid run with \xff ? */
  131.         {
  132.           for (m = 1; (row1[x + m] == '\xff' && m < 127 &&
  133.                (x + m) < raster); m++);
  134.           fputc (128 + m, file);
  135.           x += m;
  136.           continue;
  137.         }
  138.       /* Pattern run ? */
  139.       if ((x + 3) < raster && row1[x] == row1[(x + 2)] &&
  140.           row1[(x + 1)] == row1[(x + 3)])
  141.         {
  142.           for (m = 4; ((x + m + 1) < raster && row1[x]
  143.                == row1[x + m] && row1[x + 1]
  144.                == row1[x + m + 1] && m < 510); m += 2);
  145.           fputc (0, file);
  146.           fprintf (file, "%c%c%c", m / 2, row1[x], row1[x + 1]);
  147.           x += m;
  148.           continue;
  149.         }
  150.       /* It is a bit string */
  151.       fputc (0x80, file);
  152.       for (m = 1; (x + m) < raster && row1[x + m] != '\x00' &&
  153.            row1[x + m] != '\xff' && m < 255; m++)
  154.         {
  155.           if (x + m + 3 < raster)
  156.         {
  157.           if (row1[x + m] == row1[x + m + 2] &&
  158.               row1[x + m + 1] == row1[x + m + 3])
  159.             break;
  160.         }
  161.         }
  162.       fputc (m, file);
  163.       for (z = 0; z < m; z++)
  164.         fputc (row1[x + z], file);
  165.       x += m;
  166.     }
  167.       y += n;
  168.       x = 0;
  169.     }
  170.   gs_free ((char *) row1, raster, 1, "img line buffer 1");
  171.   gs_free ((char *) row2, raster, 1, "img line buffer 2");
  172.   return code;
  173. }
  174.