home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / fontutils-0.6 / imageto / out-epsf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-16  |  5.6 KB  |  171 lines

  1. /* out-epsf.c: output the whole image as an EPS file.
  2.  
  3. Copyright (C) 1992 Free Software Foundation, Inc.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include "hexify.h"
  22. #include "report.h"
  23.  
  24. #include "main.h"
  25. #include "out-epsf.h"
  26.  
  27. extern string version_string;
  28.  
  29. static void pack_scanline (one_byte *, unsigned);
  30.  
  31. /* Convert a number in pixels to big points, which are Adobe's units.
  32.    (72 big points to the inch.)  */
  33. #define PIXELS_TO_BP(v, dpi) (72 * (v) / (dpi))
  34.  
  35. /* Abbreviations for output to `eps_file'.  */
  36. #define OUT_STRING(s) fprintf (eps_file, "%s", s)
  37. #define OUT_SIMPLE(s) fprintf (eps_file, "%%%%%s\n", s)
  38. #define OUT_COMMENT(s, v) fprintf (eps_file, "%%%%%s: %s\n", s, v)
  39. #define OUT1(s, v1) fprintf (eps_file, s, v1)
  40. #define OUT2(s, v1, v2) fprintf (eps_file, s, v1, v2)
  41. #define OUT3(s, v1, v2, v3) fprintf (eps_file, s, v1, v2, v3)
  42.  
  43. /* Write an Encapsulated PostScript file corresponding to the image.  */
  44.  
  45. void
  46. write_epsf (string output_name, image_header_type image_header)
  47. {
  48.   /* Just black & white, or do we have grayscale?  */
  49.   boolean monochrome_p = image_header.depth == 1;
  50.   
  51.   /* Just for convenience.  */
  52.   unsigned width = image_header.width;
  53.   unsigned height = image_header.height;
  54.   
  55.   /* We pack the image tightly if it's monochrome.  */
  56.   unsigned width_used = monochrome_p ? width / 8 + !!(width % 8) : width;
  57.  
  58.   /* Buffer into which we'll read the image data.  */
  59.   unsigned scanline_count = 0;
  60.   one_byte *scanline = xmalloc (width);
  61.   
  62.   /* Open the output file OUTPUT_NAME.  */
  63.   FILE *eps_file = xfopen (output_name, "w");
  64.  
  65.   OUT_STRING ("%!PS-Adobe-3.0 EPSF-3.0\n");
  66.   OUT2 ("%%%%BoundingBox: 0 0 %u %u\n", width, height);
  67.   OUT_COMMENT ("Creator", version_string);
  68.   OUT_COMMENT ("Title", output_name);
  69.   OUT_COMMENT ("CreationDate", now ());
  70.   OUT_COMMENT ("DocumentData", "Clean7Bit");
  71.   OUT_SIMPLE ("EndComments");
  72.   
  73.   /* We map the image to the unit square for image(mask) and scale the
  74.      coordinate system to get back to the original size.  I can't grasp
  75.      how to use the matrix argument to image(mask) to avoid the scaling,
  76.      but I'm sure it's possible. */
  77.   OUT2 ("gsave\n  %u %u scale\n", width, height);
  78.   
  79.   /* We need a buffer to hold the string chunks as we read them.  It
  80.      can't be of arbitrary size: it must be an exact multiple of the
  81.      total number of data characters.  Otherwise, we will read past the
  82.      end of the data.  */
  83.   OUT1 ("/image-buffer %u string def\n", width_used);
  84.   
  85.   /* If we are monochrome, we use the `imagemask' operator; else `image'.  */
  86.   OUT2 ("  %u %u", width, height);
  87.  
  88.   if (monochrome_p)
  89.     OUT_STRING (" true"); /* The `invert' argument.  */
  90.   else
  91.     OUT1 (" %u", image_header.depth); /* bits/sample */
  92.   
  93.   OUT3 (" [%u 0 0 -%u 0 %u]\n", width, height, height);
  94.   OUT_STRING ("{currentfile image-buffer readhexstring pop}\n");
  95.   OUT1 ("%s\n", monochrome_p ? "imagemask" : "image");
  96.   
  97.   /* Read the image.  */
  98.   while ((*image_get_scanline) (scanline))
  99.     {
  100.       string h;
  101.       unsigned loc;
  102.  
  103.       scanline_count++;
  104.       if (scanline_count % 10 == 0)
  105.         REPORT1 (".%s", scanline_count % 790 == 0 ? "\n" : "");
  106.       
  107.       /* Monochrome images are output with eight samples/byte; grayscale
  108.          images are output with one sample/byte.  */
  109.       if (monochrome_p)
  110.         pack_scanline (scanline, width);
  111.  
  112.       /* Convert binary to ASCII hexadecimal.  */
  113.       h = hexify (scanline, width_used);
  114.  
  115.       /* Adobe says lines in EPS files should be no more than 255
  116.          characters.  How silly.  */
  117.       for (loc = 1; loc <= 2 * width_used; loc++)
  118.         {
  119.           putc (h[loc - 1], eps_file);
  120.           if (loc % 255 == 0)
  121.             putc ('\n', eps_file);
  122.     }
  123.       
  124.       free (h);
  125.       putc ('\n', eps_file);
  126.     }
  127.   
  128.   /* Restore the ctm.  */
  129.   OUT_STRING ("grestore\n");
  130.  
  131.   if (scanline_count != image_header.height)
  132.     WARNING2 ("Expected %u scanlines, read %u", image_header.height,
  133.               scanline_count); 
  134.   
  135.   OUT_SIMPLE ("TRAILER");
  136.   OUT_SIMPLE ("EOF");
  137. }
  138.  
  139. /* Change the one bit/byte representation (call each byte a `cell') of
  140.    LENGTH bits in DATA to be eight bits/byte.  Pad the last byte with
  141.    zero.  We don't change those bytes beyond the end of packed portion,
  142.    thus assuming they are not looked at.  */
  143.  
  144. static void
  145. pack_scanline (one_byte *data, unsigned length)
  146. {
  147.   unsigned cell; /* Which bit in the original data we're on.  */
  148.   unsigned packing_loc = 0; /* Which byte we're currently packing.  */
  149.   unsigned packing_bit = 8; /* How much to shift.  */
  150.   
  151.   /* The very first cell has to be treated specially, because we must
  152.      initialize it with itself shifted left (if we're going to use data
  153.      in place, that is.)  */
  154.   data[0] <<= 7;
  155.   
  156.   for (cell = 0; cell < length; cell++)
  157.     {
  158.       packing_bit--;
  159.       data[packing_loc] |= data[cell] << packing_bit;
  160.       if (packing_bit == 0)
  161.         {
  162.           packing_bit = 8;
  163.           packing_loc++;
  164.           
  165.           /* After the first byte, we can just clear the byte at
  166.              `packing_loc', since `cell' has already moved beyond it.  */
  167.           data[packing_loc] = 0;
  168.     }
  169.     }
  170. }
  171.