aboutsummaryrefslogtreecommitdiff
path: root/vendor/x11iraf/ximtool/eps.c
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /vendor/x11iraf/ximtool/eps.c
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'vendor/x11iraf/ximtool/eps.c')
-rw-r--r--vendor/x11iraf/ximtool/eps.c1902
1 files changed, 1902 insertions, 0 deletions
diff --git a/vendor/x11iraf/ximtool/eps.c b/vendor/x11iraf/ximtool/eps.c
new file mode 100644
index 00000000..ec7f83a8
--- /dev/null
+++ b/vendor/x11iraf/ximtool/eps.c
@@ -0,0 +1,1902 @@
+#include <stdio.h>
+#include <math.h>
+#include <time.h>
+#include <pwd.h>
+#include "eps.h"
+
+#ifdef __STDC__
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+#ifdef SOLARIS
+#include <sys/systeminfo.h>
+#endif
+
+
+/*
+** EPS.C -- EPS hardcopy routines. This code takes an input structure
+** containing the pixels, colormap, and output specifications and creates
+** and Encapsulated PostScript file.
+**
+** #include "eps.h" # flags, macro defs, etc.
+**
+** psim = eps_init ()
+** eps_print (psim, fp, &data, xdim, ydim, depth, pad)
+** eps_close (psim)
+**
+** eps_setPage (psim, orient, paper_size, scale, flags)
+** eps_setCmap (psim, &r, &g, &b, ncolors)
+** eps_setCompress (psim, ctype)
+** eps_setColorType (psim, otype)
+** eps_setLabel (psim, &label)
+** eps_setTransform (psim, z1, z2, ztype, offset, slope, cmap_name)
+** eps_setCorners (psim, llx, lly, urx, ury)
+**
+** eps_getImageSize (psim, xdim, ydim, &width, &height)
+** eps_getImagePos (psim, xdim, ydim, &llx, &llx)
+**
+** # Read-only Macro functions: Result type
+** ---------------------------- -----------
+** Orientation (psim) EPS_PORTRAIT | EPS_LANDSCAPE
+** Scale (psim) float scale value
+** MaxScale (psim) float maxaspect scale value
+** DoAutoScale (psim) bool
+** DoAutoRotate (psim) bool
+** DoMaxAspect (psim) bool
+** PageType (psim) EPS_LETTER | EPS_LEGAL | ...
+** PageXdim (psim) page pixel width
+** PageYdim (psim) page pixel height
+** PageWidth (psim) page size in inches
+** PageHeight (psim) page size in inches
+**
+** The first three routines are all that's required to output an array of
+** pixels to an open file descriptor. The default output produced is a
+** grayscale EPS file, centered in a portrait orientation (unless a rotation
+** is required to make it fit on the page) and auto scaled to fit on a normal
+** 8.5"x11" page.
+**
+** The remaining routines can be used to set various options, new colormaps
+** labels, etc. They are not required unless you need to override one or
+** more of the output defaults.
+*/
+
+#define MAX_LENLABEL 256
+#define SZ_EPSBUF 8193
+
+#ifndef AIXV3
+#ifndef OSF1
+typedef unsigned char uchar;
+#endif
+#endif
+
+
+static char *hextab = "0123456789abcdef";
+static int pixnum = 0, lpix = 0;
+static uchar *pixbuf;
+
+
+/* Public procedures.
+*/
+void eps_setPage(), eps_setTransform(), eps_setCorners();
+
+
+/* Private procedures.
+*/
+static void eps_simpleHeader(), eps_colorHeader();
+static void eps_pageParams(), eps_simpleTrailer();
+static void eps_writeCmap(), eps_writeTrailer();
+static void eps_writeMono(), eps_writePix();
+static void eps_writeMonoRGB(), eps_writeRGB();
+static void eps_putPix(), eps_flushPix();
+static void eps_annotate(), eps_portLabels(), eps_landLabels();
+static void eps_doColorbar();
+static float ticstep();
+static char *make_label();
+
+
+static int debug = 0;
+
+
+/* EPS_INIT -- Allocate and return an initialized pointer to a structure
+** containing the default output setup.
+*/
+PSImage *
+eps_init()
+{
+ register int i, n;
+ register PSImage *ps;
+ register uchar *op;
+
+
+ /* Allocate the structure. */
+ ps = (PSImage *) calloc ((unsigned)1, sizeof (PSImage));
+
+ /* Initialize the structure. */
+ ps->cols = 0;
+ ps->rows = 0;
+ ps->colorClass = EPS_GRAYSCALE;
+ ps->compression = NoCompression;
+ ps->annotate = 1;
+ ps->label = (char *) calloc (MAX_LENLABEL, sizeof (uchar));
+ ps->z1 = 0.0;
+ ps->z2 = 255.0;
+ ps->ztype = 0;
+
+ /* Set up a default grayscale colormap. */
+ ps->cmap.ncolors = 256;
+ for (i=0; i<ps->cmap.ncolors; i++)
+ ps->cmap.r[i] = ps->cmap.g[i] = ps->cmap.b[i] = i;
+ ps->cmap.IsDefault = 1;
+
+ /* Load the page information defaults. */
+ eps_setPage (ps, EPS_PORTRAIT, EPS_LETTER, 100, EPS_AUTOSCALE);
+
+ /* Initialize the annotation flags */
+ ps->page.flags |= (EPS_DOTITLE|EPS_DOBORDERS|EPS_DOCOLORBAR);
+
+ /* Initialize the pixel buffer array */
+ pixbuf = (uchar *) calloc (SZ_EPSBUF, sizeof (uchar));
+
+ return (ps);
+}
+
+
+/* EPS_PRINT -- Dump the given array of pixels to the output file as an EPS
+** format file. The data array may contain 8-bit, 24-bit RGB triplets, or
+** 32-bit RGBA pixels.
+*/
+void
+eps_print (psim, fp, data, xdim, ydim, depth, pad)
+PSImage *psim; /* EPS image structure */
+FILE *fp; /* output file descriptor */
+uchar *data; /* array of image pixels */
+int xdim, ydim; /* image dimensions */
+int depth; /* bits / pixel, must be 8,24, or 32 */
+int pad; /* bytes per line of padding */
+{
+ int npix = xdim * ydim;
+ uchar *pix = data;
+
+
+ psim->cols = xdim; /* save it for the headers */
+ psim->rows = ydim;
+
+ if (debug)
+ fprintf (stderr, "eps_print: w=%d h=%d d=%d pad=%d\n",
+ xdim, ydim, depth, pad);
+
+ switch (psim->colorClass) {
+ case EPS_GRAYSCALE:
+ /* Regardless of the color type desired we'll either write the
+ * pixels directly or convert from pseudocolor or RGB. For a
+ * start dump the header.
+ */
+ eps_simpleHeader (psim, fp);
+
+ if (psim->cmap.IsDefault && depth == 8) {
+ /* We're using the default grayscale colormap with an
+ * 8-bit image, so just dump the pixels.
+ */
+ if (debug)
+ fprintf (stderr,"eps_print: straight grayscale.\n");
+ eps_writePix (fp, pix, &psim->cmap, npix, xdim, pad);
+
+ } else if (!psim->cmap.IsDefault && depth == 8) {
+ /* We're using an arbitrary colormap with an 8-bit image,
+ * so convert to grayscale and write the pixels.
+ */
+ if (debug)
+ fprintf (stderr,"eps_print: pseudo cnv to grayscale.\n");
+ eps_writeMono (fp, pix, &psim->cmap, npix, xdim, pad);
+
+ } else {
+ /* Convert RGBA to grayscale. */
+ if (debug)
+ fprintf (stderr,"eps_print: RGB cnv to grayscale.\n");
+ eps_writeMonoRGB (fp, pix, npix, xdim, depth, pad);
+
+ }
+
+ /* Now that the image is out we restore the graphics context. */
+ fprintf (fp, "grestore\n" );
+
+ /* Write the colorbar. */
+ if (psim->annotate)
+ eps_annotate (psim, fp);
+
+ /* Write the trailer. */
+ eps_simpleTrailer (fp);
+ break;
+
+ case EPS_PSEUDOCOLOR:
+ /* Write the color prolog header. */
+ eps_colorHeader (psim, fp);
+
+ /* Dump the colormap. */
+ eps_writeCmap (&psim->cmap, fp);
+
+ /* Write color indices. */
+ eps_writePix (fp, pix, &psim->cmap, npix, xdim, pad);
+
+ /* Write the colorbar. */
+ if (psim->annotate)
+ eps_annotate (psim, fp);
+
+ /* Write the trailer to finish it off. */
+ eps_writeTrailer (fp);
+ break;
+
+ case EPS_TRUECOLOR:
+ /* Write the seudocolor prolog header. */
+ eps_colorHeader (psim, fp);
+
+ eps_writeRGB (fp, pix, &psim->cmap, npix, xdim, depth, pad);
+
+ /* Write the colorbar. */
+ if (psim->annotate)
+ eps_annotate (psim, fp);
+
+ /* Write the trailer to finish it off. */
+ eps_writeTrailer (fp);
+ break;
+
+ default:
+ perror ("Bad colorClass specification.\n");
+ break;
+ }
+
+ fflush (fp);
+}
+
+
+/* EPS_CLOSE -- Close down the EPS output structure.
+*/
+void
+eps_close (psim)
+PSImage *psim; /* EPS image structure */
+{
+ if (psim->label)
+ (void) free ((char *) psim->label);
+ (void) free ((char *) pixbuf);
+ (void) free (psim);
+}
+
+
+/* EPS_SETPAGE -- Inialize the page setup with a different size, orientation,
+** or scale options.
+*/
+void
+eps_setPage (psim, orientation, paper_size, scale, flags)
+PSImage *psim; /* EPS image structure */
+int orientation; /* page orientation flag */
+int paper_size; /* paper size flag */
+int scale; /* image scale percentage */
+int flags; /* option flags */
+{
+ int NPageTypes = sizeof (PageInfo) / sizeof (PSPageInfo);
+
+
+ /* Set the orientation of the output */
+ if (orientation == EPS_PORTRAIT)
+ psim->page.orientation = EPS_PORTRAIT;
+ else if (orientation == EPS_LANDSCAPE)
+ psim->page.orientation = EPS_LANDSCAPE;
+ else
+ perror ("eps_setPage: Invalid orientation.");
+
+ /* Set the output paper size */
+ if (paper_size >= 0 && paper_size <= NPageTypes)
+ psim->page.page_type = paper_size;
+ else
+ perror ("eps_setPage: Invalid paper size.");
+
+ /* Set scale and recompute dpi resolution. */
+ psim->page.scale = (float) scale / 100.0;
+ psim->page.maxscale = (float) scale / 100.0;
+ psim->page.dpi = 72; /* need to recalculate */
+
+ /* Set the option flags */
+ psim->page.flags = flags;
+
+ if (debug) {
+ fprintf (stderr,
+ "eps_setPage: orientation:%d size:%d scale:%g\n",
+ Orientation(psim), PageType(psim), Scale(psim));
+ fprintf (stderr,"\tautoscale:%d autorotate:%d maxaspect:%d\n",
+ DoAutoScale(psim), DoAutoRotate(psim), DoMaxAspect(psim));
+ }
+}
+
+
+/* EPS_SETCMAP -- Define a given colormap to be used on output.
+*/
+void
+eps_setCmap (psim, r, g, b, ncolors)
+PSImage *psim; /* EPS image structure */
+uchar *r, *g, *b; /* color components */
+int ncolors; /* number of colors in colormap */
+{
+ register int i = 0;
+
+ /* Load the colormap. */
+ psim->cmap.ncolors = ncolors;
+ /* for (i=0; i < ncolors; i++) { */
+ for (i=0; i < 256; i++) {
+ psim->cmap.r[i] = r[i];
+ psim->cmap.g[i] = g[i];
+ psim->cmap.b[i] = b[i];
+ }
+
+ psim->cmap.IsDefault = 0;
+}
+
+
+/* EPS_SETCOMPRESS -- Define the type of output compression to use.
+*/
+void
+eps_setCompress (psim, compress)
+PSImage *psim; /* EPS image structure */
+int compress; /* compression type flag */
+{
+ /* Set the compression type to use. */
+ switch (compress) {
+ case NoCompression:
+ case RLECompression:
+ psim->compression = compress;
+ break;
+ case LZWCompression:
+ case JPEGCompression:
+ default:
+ perror ("eps_setCompress: Invalid compression type.");
+ }
+}
+
+
+/* EPS_SETCOLORTYPE -- Set the type of output image to be written, e.g. even
+** though we have an RGB or pseudocolor image we may wish to coerce it to
+** a grayscale on output.
+*/
+void
+eps_setColorType (psim, color_class)
+PSImage *psim; /* EPS image structure */
+int color_class; /* output color class */
+{
+ /* Set the compression type to use. */
+ switch (color_class) {
+ case EPS_GRAYSCALE:
+ case EPS_PSEUDOCOLOR:
+ case EPS_TRUECOLOR:
+ psim->colorClass = color_class;
+ break;
+ default:
+ perror ("eps_setColorType: Invalid output color type.");
+ }
+}
+
+
+/* EPS_SETLABEL -- Set the output label to be used in annotation.
+*/
+void
+eps_setLabel (psim, label)
+register PSImage *psim; /* EPS image structure */
+char *label; /* Label string */
+{
+ register int maxlen = MAX_LENLABEL;
+
+ if (!psim->label)
+ psim->label = (char *) malloc (maxlen);
+
+ if (psim->page.flags & EPS_DOTITLE) {
+ (void) strncpy (psim->label, label, maxlen-1);
+ psim->label[maxlen-1] = '\0';
+ } else
+ psim->label[0] = '\0';
+}
+
+
+/* EPS_SETTRANSFORM -- Set the color transformation parameters, i.e. the
+** z1/z2 values that map the image pixel values being displayed to the number
+** of colors we have available. This is used in the annotation when labeling
+** the colorbar.
+*/
+void
+eps_setTransform (psim, z1, z2, ztype, offset, scale, cmap_name)
+PSImage *psim; /* EPS image structure */
+float z1, z2; /* zscale values */
+int ztype; /* Transformation type */
+float offset, scale; /* brightness/contrast values */
+char *cmap_name; /* colormap name */
+{
+ psim->z1 = z1;
+ psim->z2 = z2;
+ psim->ztype = ztype;
+ psim->offset = offset;
+ psim->scale = scale;
+ if (!psim->cmap.cmap_name)
+ psim->cmap.cmap_name = (char *) malloc (16);
+ strcpy (psim->cmap.cmap_name, cmap_name);
+
+ if (debug) {
+ fprintf (stderr,
+ "setTransform: z1=%g z2=%g zt=%d offset=%g scale=%g name='%s'\n",
+ psim->z1, psim->z2, psim->ztype,
+ psim->offset, psim->scale,
+ psim->cmap.cmap_name);
+ }
+}
+
+
+/* EPS_SETCORNERS -- Set the image corner values.
+*/
+void
+eps_setCorners (psim, llx, lly, urx, ury)
+PSImage *psim; /* EPS image structure */
+int llx, lly, urx, ury; /* image corners */
+{
+ psim->llx = llx;
+ psim->lly = lly;
+ psim->urx = urx;
+ psim->ury = ury;
+}
+
+
+/* EPS_GETIMAGESIZE -- Given the current page parameters and image dimensions,
+** compute the size of the image (in inches) on the page.
+*/
+void
+eps_getImageSize (psim, xdim, ydim, width, height)
+PSImagePtr psim; /* EPS image struct */
+int xdim, ydim; /* image dimensions */
+float *width, *height; /* width x height of image on page */
+{
+ int icols, irows, scols, srows, turnflag;
+ float llx, lly;
+
+
+ /* Get the common page parameters. */
+ eps_pageParams (psim, &llx, &lly, &icols, &irows, &scols, &srows,
+ &turnflag);
+
+ *width = (scols / (float) psim->page.dpi);
+ *height = (srows / (float) psim->page.dpi);
+}
+
+
+/* EPS_GETIMAGEPOS -- Given the current page parameters and image dimensions,
+** compute the position of the image (in pixels) on the page.
+*/
+void
+eps_getImagePos (psim, xdim, ydim, llx, lly)
+PSImagePtr psim; /* EPS image struct */
+int xdim, ydim; /* image dimensions */
+int *llx, *lly; /* LL coords for centered image */
+{
+ int icols, irows, scols, srows, turnflag;
+ float lx, ly;
+
+
+ /* Get the common page parameters. */
+ eps_pageParams (psim, &lx, &ly, &icols, &irows, &scols, &srows,
+ &turnflag);
+
+ *llx = (int) lx;
+ *lly = (int) ly;
+}
+
+
+/************************
+ * Private Procedures *
+ ************************/
+
+
+/* EPS_PAGEPARAMS -- Compute the EPS page parameters.
+*/
+static void
+eps_pageParams (psim, llx, lly, icols, irows, scols, srows, turnflag)
+PSImagePtr psim; /* EPS image struct */
+float *llx, *lly; /* LL coords for centered image */
+int *icols, *irows; /* final image rows/cols */
+int *scols, *srows; /* scaled rows/cols */
+int *turnflag; /* turn the image? */
+{
+ int devpix, pwidth, pheight, cols=0, rows=0;
+ float pixfac, scale = Scale(psim), margin;
+
+
+ /* See if we need to rotate the image to fit on the page. */
+ margin = (psim->annotate ? 0.9 : 0.95);
+ pwidth = (int) PageXdim(psim) * margin;
+ pheight = (int) PageYdim(psim) * margin;
+ *icols = cols = psim->cols;
+ *irows = rows = psim->rows;
+ *turnflag = 0;
+ if (DoAutoRotate(psim)) {
+ if (psim->cols > psim->rows && (scale * psim->cols) > pwidth) {
+ if (debug) fprintf (stderr, "Rotating image....\n");
+ *turnflag = 1;
+ cols = *irows;
+ rows = *icols;
+ }
+ } else if (psim->page.orientation == EPS_LANDSCAPE) {
+ if (debug) fprintf (stderr, "Rotating image....\n");
+ *turnflag = 1;
+ cols = *irows;
+ rows = *icols;
+ }
+
+ if (turnflag) {
+ margin = (turnflag ? 0.825 : margin);
+ pwidth = (int) PageXdim(psim) * margin;
+ pheight = (int) PageYdim(psim) * margin;
+ }
+
+ /* Figure out the image size. */
+ devpix = psim->page.dpi / 72.0 + 0.5; /* device pixels per unit */
+ pixfac = 72.0 / psim->page.dpi * devpix;
+ *scols = psim->page.scale * cols * pixfac;
+ *srows = psim->page.scale * rows * pixfac;
+
+ /* See if we need to fiddle with the size to get it on the page
+ * the way we want.
+ */
+ if (debug) {
+ fprintf (stderr, "before: scale=%g scols=%d srows=%d pixfac=%g\n",
+ scale, *scols, *srows, pixfac);
+ fprintf (stderr, "\tpwidth=%d pheight=%d\n", pwidth, pheight);
+ fprintf (stderr,"\tautoscale:%d autorotate:%d maxaspect:%d\n",
+ DoAutoScale(psim), DoAutoRotate(psim), DoMaxAspect(psim));
+ }
+ if ( *scols > pwidth || *srows > pheight ) {
+
+ /* Image is larger than we think will fit on the page. If we're
+ * autoscaling reset the scale.
+ */
+ if (DoAutoScale(psim)) {
+ if (debug)
+ fprintf (stderr, "Image too big, autoscaling...\n");
+ if ( *scols >= pwidth ) {
+ if (*scols >= *srows) {
+ scale *= (float)PageXdim(psim) / (float)*scols * margin;
+ *scols = scale * cols * pixfac;
+ *srows = scale * rows * pixfac;
+ } else {
+ scale *= (float)PageYdim(psim) / (float)*srows * margin;
+ *scols = scale * cols * pixfac;
+ *srows = scale * rows * pixfac;
+ }
+ }
+ if (debug)
+ fprintf (stderr, ": scale=%f scols=%d srows=%d pixfac=%g\n",
+ scale, *scols, *srows, pixfac);
+ if ( *srows >= pheight ) {
+ if (*scols >= *srows) {
+ scale *= (float)PageXdim(psim) / (float)*scols * margin;
+ *scols = scale * cols * pixfac;
+ *srows = scale * rows * pixfac;
+ } else {
+ scale *= (float)PageYdim(psim) / (float)*srows * margin;
+ *scols = scale * cols * pixfac;
+ *srows = scale * rows * pixfac;
+ }
+ }
+ if (debug)
+ fprintf (stderr, ": scale=%f scols=%d srows=%d pixfac=%g\n",
+ scale, *scols, *srows, pixfac);
+ psim->page.maxscale = scale; /* update new scale factor */
+
+ } else {
+ /* Notify user that the image won't fit and suggest a scale. */
+ if ( *scols > pwidth )
+ scale *= (float) PageXdim(psim) / (float) *scols * margin;
+ if ( *srows > pheight )
+ scale *= (float) PageYdim(psim) / (float) *srows * margin;
+ psim->page.maxscale = scale; /* update new scale factor */
+
+ fprintf (stderr,
+ "Image too big for the page, no autoscaling set...\n");
+ fprintf (stderr, "Reset autoscale flag or use scale < %g\n",
+ scale);
+ }
+
+ }
+
+ if (DoMaxAspect(psim)) {
+ /* Image will fit on page, but blow it up to a maximum size for
+ * the page orientation but retain the image aspect.
+ */
+ if (debug)
+ fprintf (stderr, "Doing max aspect...");
+ if ( *scols >= *srows ) {
+ scale *= (float) PageXdim(psim) / (float) *scols * margin;
+ *scols = scale * cols * pixfac;
+ *srows = scale * rows * pixfac;
+ } else if ( *srows > *scols ) {
+ scale *= (float) PageYdim(psim) / (float) *srows * margin;
+ *scols = scale * cols * pixfac;
+ *srows = scale * rows * pixfac;
+ }
+ psim->page.maxscale = scale; /* update new scale factor */
+ }
+
+ /* Center it on the page. */
+ *llx = (PageXdim(psim) - *scols) / 2 - (*turnflag ? 10 : 0);
+ *lly = (PageYdim(psim) - *srows) / 2 + (*turnflag ? 0 : 10);
+
+ if (debug) {
+ fprintf(stderr,"after: scale=%g scols=%d srows=%d ",
+ scale, *scols, *srows);
+ fprintf(stderr,"icols=%d irows=%d llx=%g lly=%g\n",
+ *icols, *irows, *llx, *lly);
+ }
+}
+
+
+/* EPS_WRITEPIX -- Write the pixels or color indices directly.
+*/
+static void
+eps_writePix (fp, pix, cmap, npix, xdim, pad)
+FILE *fp;
+uchar *pix;
+PSCmap *cmap;
+int npix;
+int xdim;
+int pad;
+{
+ register int i, min, max;
+
+
+ min = *pix;
+ max = *pix;
+ while (npix > 0) {
+ min = (min > *pix ? *pix : min);
+ max = (max < *pix ? *pix : max);
+
+ /* Write the pixels. */
+ for (i=0; i < PIX_PER_LINE && npix--; i+=2) {
+ pixbuf[pixnum++] = (uchar) hextab[((uchar)*pix >> 4)];
+ pixbuf[pixnum++] = (uchar) hextab[((uchar)*pix++ & 0x0F)];
+ }
+ pixbuf[pixnum++] = '\n';
+
+ if (pixnum >= (SZ_EPSBUF - PIX_PER_LINE - 1)) {
+ pixbuf[pixnum] = '\0';
+ fwrite ((char *)pixbuf, sizeof(char), pixnum, fp);
+ pixnum = 0;
+ }
+
+ /* Skip the pad chars. */
+ for (i=0; i<pad && npix; i++, npix--)
+ pix++;
+ }
+ cmap->min = min;
+ cmap->max = max;
+ eps_flushPix (fp);
+}
+
+
+/* EPS_WRITEMONO -- Write a pseudocolor image and convert to grayscale.
+*/
+static void
+eps_writeMono (fp, pix, cmap, npix, xdim, pad)
+FILE *fp;
+uchar *pix;
+PSCmap *cmap;
+int npix;
+int xdim;
+int pad;
+{
+ register int i, min, max;
+ register uchar pval;
+
+ min = *pix;
+ max = *pix;
+ while (npix > 0) {
+ min = (min > *pix ? *pix : min);
+ max = (max < *pix ? *pix : max);
+
+ /* Write the pixels. */
+ for (i=0; i < PIX_PER_LINE && npix; i+=2, npix-- ) {
+ pval = (uchar) MONO (cmap->r[*pix],
+ cmap->g[*pix],
+ cmap->b[*pix++]);
+ pixbuf[pixnum++] = (uchar) hextab[(pval >> 4)];
+ pixbuf[pixnum++] = (uchar) hextab[(pval & 0x0F)];
+ }
+ pixbuf[pixnum++] = '\n';
+
+ if (pixnum >= (SZ_EPSBUF - PIX_PER_LINE - 1) || !npix) {
+ pixbuf[pixnum] = '\0';
+ fwrite ((char *)pixbuf, sizeof(char), pixnum, fp);
+ pixnum = 0;
+ }
+
+ /* skip the pad chars */
+ for (i=0; i<pad && npix; i++, npix--)
+ pix++;
+ }
+ cmap->min = min;
+ cmap->max = max;
+ eps_flushPix (fp);
+}
+
+
+/* EPS_WRITEMONORGB -- Write RGB data converted to grayscale.
+*/
+static void
+eps_writeMonoRGB (fp, pix, npix, xdim, depth, pad)
+FILE *fp;
+uchar *pix;
+int npix;
+int xdim;
+int depth;
+int pad;
+{
+ register int i;
+ register uchar pval;
+
+
+ while (npix > 0) {
+ /* Write the pixels. */
+ if (depth < 24) {
+ for (i=0; i < PIX_PER_LINE && npix; i+=2, npix-=3 ) {
+ pval = (uchar) MONO (*pix++, *pix++, *pix++);
+ pixbuf[pixnum++] = (uchar) hextab[(pval >> 4)];
+ pixbuf[pixnum++] = (uchar) hextab[(pval & 0x0F)];
+ }
+ } else {
+ /* Skip alpha channel in the loop */
+ for (i=0; i < PIX_PER_LINE && npix; i+=2, npix-=3, pix++ ) {
+ pval = (uchar) MONO (*pix++, *pix++, *pix++);
+ pixbuf[pixnum++] = (uchar) hextab[(pval >> 4)];
+ pixbuf[pixnum++] = (uchar) hextab[(pval & 0x0F)];
+ }
+ }
+ pixbuf[pixnum++] = '\n';
+
+ if (pixnum >= (SZ_EPSBUF - PIX_PER_LINE - 1)) {
+ pixbuf[pixnum] = '\0';
+ fwrite ((char *)pixbuf, sizeof(char), pixnum, fp);
+ pixnum = 0;
+ }
+
+ /* skip the pad chars */
+ for (i=0; i<pad && npix; i++, npix--)
+ pix++;
+ }
+ eps_flushPix (fp);
+}
+
+
+/* EPS_WRITERGB -- Write the pixels in RGB format, skipping a possible alpha
+** channel.
+*/
+static void
+eps_writeRGB (fp, pix, cmap, npix, xdim, depth, pad)
+FILE *fp;
+uchar *pix;
+PSCmap *cmap;
+int npix;
+int xdim;
+int depth;
+int pad;
+{
+ register int i, j, min, max;
+ register uchar val;
+
+
+ min = *pix;
+ max = *pix;
+ while (npix > 0) {
+ min = (min > *pix ? *pix : min);
+ max = (max < *pix ? *pix : max);
+
+ /* Write the pixels. */
+ if (depth < 24) {
+ for (i=0; i < PIX_PER_LINE && npix; i+=6, npix--, pix++ ) {
+ val = (uchar) cmap->r[*pix];
+ pixbuf[pixnum++] = (uchar) hextab[((uchar)val >> 4)];
+ pixbuf[pixnum++] = (uchar) hextab[((uchar)val & 0x0F)];
+ val = (uchar) cmap->g[*pix];
+ pixbuf[pixnum++] = (uchar) hextab[((uchar)val >> 4)];
+ pixbuf[pixnum++] = (uchar) hextab[((uchar)val & 0x0F)];
+ val = (uchar) cmap->b[*pix];
+ pixbuf[pixnum++] = (uchar) hextab[((uchar)val >> 4)];
+ pixbuf[pixnum++] = (uchar) hextab[((uchar)val & 0x0F)];
+ }
+ } else {
+ /* Skip alpha channel in the loop */
+ for (i=0; i < PIX_PER_LINE && npix; i+=6, npix-=3, pix++ ) {
+ pixbuf[pixnum++] = (uchar) hextab[((uchar)*pix >> 4)];
+ pixbuf[pixnum++] = (uchar) hextab[((uchar)*pix++ & 0x0F)];
+ pixbuf[pixnum++] = (uchar) hextab[((uchar)*pix >> 4)];
+ pixbuf[pixnum++] = (uchar) hextab[((uchar)*pix++ & 0x0F)];
+ pixbuf[pixnum++] = (uchar) hextab[((uchar)*pix >> 4)];
+ pixbuf[pixnum++] = (uchar) hextab[((uchar)*pix++ & 0x0F)];
+ }
+ }
+ pixbuf[pixnum++] = '\n';
+
+ if (pixnum >= (SZ_EPSBUF - PIX_PER_LINE - 1)) {
+ pixbuf[pixnum] = '\0';
+ fwrite ((char *)pixbuf, sizeof(char), pixnum, fp);
+ pixnum = 0;
+ }
+
+
+ /* skip the pad chars */
+ for (i=0; i<pad && npix; i++, npix--)
+ pix++;
+ }
+ cmap->min = min;
+ cmap->max = max;
+ eps_flushPix (fp);
+}
+
+
+/* EPS_WRITECMAP -- Output Postscript colormap.
+*/
+static void
+eps_writeCmap (cmap, fp)
+PSCmap *cmap;
+FILE *fp;
+{
+ register int i, j;
+
+ /* Dump number of colors and colormap used. */
+ fprintf (fp, "256\n");
+ for (i=0; i < 256; ) {
+ for (j=0; j < 10 && i < 256; i++, j++) {
+ fprintf (fp, "%02x%02x%02x",
+ cmap->r[i], cmap->g[i], cmap->b[i]);
+ }
+ fprintf (fp, "\n");
+ }
+}
+
+
+/* EPS_SIMPLEHEADER -- Output simple Postscript header.
+*/
+static char *EPSSimpleRLEProlog[]= {
+ "/rlestr1 1 string def\n",
+ "/readrlestring { /* s -- nr */\n",
+ " /rlestr exch def /* - */\n",
+ " currentfile rlestr1 readhexstring pop /* s1 */\n",
+ " 0 get /* c */\n",
+ " dup 127 le { /* c */\n",
+ " currentfile rlestr 0 /* c f s 0 */\n",
+ " 4 3 roll /* f s 0 c */\n",
+ " 1 add getinterval /* f s */\n",
+ " readhexstring pop /* s */\n",
+ " length /* nr */\n",
+ " } { /* c */\n",
+ " 256 exch sub dup /* n n */\n",
+ " currentfile rlestr1 readhexstring pop /* n n s1 */\n",
+ " 0 get /* n n c */\n",
+ " exch 0 exch 1 exch 1 sub { /* n c 0 1 n-1*/\n",
+ " rlestr exch 2 index put\n",
+ " } for /* n c */\n",
+ " pop /* nr */\n",
+ " } ifelse /* nr */\n",
+ "} bind def\n",
+ "/readstring { /* s -- s */\n",
+ " dup length 0 { /* s l 0 */\n",
+ " 3 copy exch /* s l n s n l*/\n",
+ " 1 index sub /* s l n s n r*/\n",
+ " getinterval /* s l n ss */\n",
+ " readrlestring /* s l n nr */\n",
+ " add /* s l n */\n",
+ " 2 copy le { exit } if /* s l n */\n",
+ " } loop /* s l l */\n",
+ " pop pop /* s */\n",
+ "} bind def\n",
+ NULL
+};
+
+static void
+eps_simpleHeader (psim, fp)
+PSImagePtr psim;
+FILE *fp;
+{
+ register char **line;
+ int icols=0, irows=0, scols=0, srows=0, turnflag=0;
+ float llx = 0.0, lly = 0.0;
+ time_t timer;
+
+
+ /* Get the common page parameters. */
+ eps_pageParams (psim, &llx, &lly, &icols, &irows, &scols, &srows,
+ &turnflag);
+
+ /* Now write header and prolog stuff */
+ fprintf (fp, "%%!PS-Adobe-3.0 EPSF-3.0\n" );
+ fprintf (fp, "%%%%Title: XImtool Screen Hardcopy\n");
+ fprintf (fp, "%%%%Creator: XImtool\n");
+ timer = time ((time_t *) NULL);
+ (void) localtime (&timer);
+ fprintf (fp, "%%%%CreationDate: %s", ctime(&timer));
+ if (psim->annotate)
+ fprintf (fp, "%%%%BoundingBox: %d %d %d %d\n",
+ (int) (MAX (0, llx - X_ANNOT_MARGIN)),
+ (int) (MAX (0, lly - Y_ANNOT_MARGIN)),
+ (int) ( llx + scols + 0.5 + X_ANNOT_MARGIN),
+ (int) ( lly + srows + 0.5 + Y_ANNOT_MARGIN) );
+ else
+ fprintf (fp, "%%%%BoundingBox: %d %d %d %d\n",
+ (int) (MAX (0, llx - 10)),
+ (int) (MAX (0, lly - 10)),
+ (int) ( llx + scols + 0.5 + 10),
+ (int) ( lly + srows + 0.5 + 10) );
+ fprintf (fp, "%%%%Pages: 1\n");
+ fprintf (fp, "%%%%EndComments\n" );
+
+ if ( psim->compression == RLECompression ) {
+ for (line = EPSSimpleRLEProlog; *line; line++)
+ fprintf (fp, "%s\n",*line);
+ } else {
+ fprintf (fp, "/readstring {\n" ); /* s -- s */
+ fprintf (fp, " currentfile exch readhexstring pop\n" );
+ fprintf (fp, "} bind def\n" );
+ }
+
+ if (psim->colorClass == EPS_TRUECOLOR) {
+ fprintf (fp, "/rpicstr %d string def\n", icols );
+ fprintf (fp, "/gpicstr %d string def\n", icols );
+ fprintf (fp, "/bpicstr %d string def\n", icols );
+ } else
+ fprintf (fp, "/picstr %d string def\n", icols );
+ fprintf (fp, "%%%%EndProlog\n" );
+ fprintf (fp, "%%%%Page: 1 1\n" );
+ fprintf (fp, "gsave\n" );
+
+ fprintf (fp, "%g %g translate\n", llx, lly );
+ fprintf (fp, "%d %d scale\n", scols, srows );
+ if ( turnflag ) {
+ if (debug) fprintf (stderr, "turnflag enabled....\n");
+ fprintf (fp, "0.5 0.5 translate 90 rotate -0.5 -0.5 translate\n");
+ }
+ fprintf (fp, "%d %d 8\n", icols, irows);
+ fprintf (fp, "[ %d 0 0 -%d 0 %d ]\n", icols, irows, irows );
+
+ if (psim->colorClass == EPS_TRUECOLOR) {
+ fprintf (fp, "{ rpicstr readstring }\n" );
+ fprintf (fp, "{ gpicstr readstring }\n" );
+ fprintf (fp, "{ bpicstr readstring }\n" );
+ fprintf (fp, "true 3\n" );
+ fprintf (fp, "colorimage\n" );
+ } else {
+ fprintf (fp, "{ picstr readstring }\n" );
+ fprintf (fp, "image\n" );
+ }
+}
+
+
+/* EPS_ANNOTATE -- Annotate the main image window with axis labels,
+** colorbars, and the title string.
+*/
+
+static void
+eps_annotate (psim, fp)
+PSImagePtr psim;
+FILE *fp;
+{
+ register char **line;
+ register int i;
+ int icols=0, irows=0, scols=0, srows=0, turnflag=0;
+ int cbar_size, nlabels;
+ int xpos, xstep, ypos, ystep;
+ float Mval, xval, yval, tic, mtic, Mtic;
+ float llx = 0.0, lly = 0.0;
+
+
+ /* Get the common page parameters. */
+ eps_pageParams (psim, &llx, &lly, &icols, &irows, &scols, &srows,
+ &turnflag);
+
+ /* Main image title. */
+ if (psim->label != NULL && (psim->page.flags & EPS_DOTITLE)) {
+ /* Write the annotation prolog stufd. */
+ fprintf (fp, "gsave\n" );
+
+ fprintf (fp,
+ "/labelfont /NewCenturySchlbk-Roman findfont 16 scalefont def\n");
+ if (turnflag) {
+ fprintf (fp, "/label { moveto labelfont setfont\n");
+ fprintf (fp, " 90 rotate show -90 rotate\n} def\n" );
+ fprintf (fp, "(%s) %g %g label\n", psim->label,
+ llx - TITLE_OFFSET,
+ lly + (srows/2) - 8.25*(strlen(psim->label)/2) );
+ } else {
+ fprintf (fp, "/label { moveto labelfont setfont show } def\n" );
+ fprintf (fp, "(%s) %g %g label\n", psim->label,
+ llx + (scols/2) - 8.25*(strlen(psim->label)/2),
+ lly + srows + TITLE_OFFSET);
+ }
+ fprintf (fp, "grestore\n");
+ }
+
+ /* A border for the image axes. */
+ if (psim->page.flags & EPS_DOBORDERS) {
+ fprintf (fp, "gsave\n" );
+ fprintf (fp, "/imBorder {\n");
+ fprintf (fp, " %-4d %-4d moveto %% Outer axis\n",
+ (int)(llx - AXIS_OOFFSET),
+ (int)(lly - AXIS_OOFFSET));
+ fprintf (fp, " 0 %-4d rlineto\n", srows + (2 * AXIS_OOFFSET));
+ fprintf (fp, " %-4d 0 rlineto\n", scols + (2 * AXIS_OOFFSET));
+ fprintf (fp, " 0 -%-4d rlineto\n", srows + (2 * AXIS_OOFFSET));
+ fprintf (fp, " closepath\n");
+ fprintf (fp, " %g setlinewidth\n", AXIS_OWIDTH);
+ fprintf (fp, " stroke\n");
+
+ fprintf (fp, " %-4d %-4d moveto %% Inner axis\n",
+ (int)(llx - AXIS_IOFFSET),
+ (int)(lly - AXIS_IOFFSET));
+ fprintf (fp, " 0 %-4d rlineto\n", srows + (2 * AXIS_IOFFSET));
+ fprintf (fp, " %-4d 0 rlineto\n", scols + (2 * AXIS_IOFFSET));
+ fprintf (fp, " 0 -%-4d rlineto\n", srows + (2 * AXIS_IOFFSET));
+ fprintf (fp, " closepath\n");
+ fprintf (fp, " %g setlinewidth\n", AXIS_IWIDTH);
+ fprintf (fp, " stroke\n");
+
+ fprintf (fp, "} def\n");
+ fprintf (fp, "imBorder\n");
+
+ /* Axis label font definitions. */
+ fprintf (fp,"/axlabelfont /Times-Roman findfont 8 scalefont def\n");
+ fprintf (fp,
+ "/axlabel { moveto axlabelfont setfont %s show %s } def\n",
+ (turnflag ? "90 rotate" : " "),
+ (turnflag ? "-90 rotate" : " "));
+
+ /* Axis ticmark procedures. */
+ fprintf (fp, "/xMajorTicmark {\n");
+ fprintf (fp, " moveto\n");
+ fprintf (fp, " 0 %d rlineto ", MAJOR_TICK_SIZE);
+ fprintf (fp, " 0 %d rmoveto ",
+ srows + MAJOR_TICK_SIZE + (2 * AXIS_IOFFSET) );
+ fprintf (fp, " 0 -%d rlineto\n", MAJOR_TICK_SIZE);
+ fprintf (fp, " %g setlinewidth\n stroke\n", MAJOR_TICK_WIDTH);
+ fprintf (fp, "} def\n");
+ fprintf (fp, "/yMajorTicmark {\n");
+ fprintf (fp, " moveto\n");
+ fprintf (fp, " %d 0 rlineto ", MAJOR_TICK_SIZE);
+ fprintf (fp, " %d 0 rmoveto ",
+ scols + MAJOR_TICK_SIZE + (2 * AXIS_IOFFSET) );
+ fprintf (fp, " -%d 0 rlineto\n", MAJOR_TICK_SIZE);
+ fprintf (fp, " %g setlinewidth\n stroke\n", MAJOR_TICK_WIDTH);
+ fprintf (fp, "} def\n");
+ fprintf (fp, "/xMinorTicmark {\n");
+ fprintf (fp, " moveto\n");
+ fprintf (fp, " 0 %d rlineto ", MINOR_TICK_SIZE);
+ fprintf (fp, " 0 %d rmoveto ",
+ srows + MAJOR_TICK_SIZE + (2*AXIS_IOFFSET) +
+ (MAJOR_TICK_SIZE - MINOR_TICK_SIZE) );
+ fprintf (fp, " 0 -%d rlineto\n", MINOR_TICK_SIZE);
+ fprintf (fp, " %g setlinewidth\n stroke\n", MINOR_TICK_WIDTH);
+ fprintf (fp, "} def\n");
+ fprintf (fp, "/yMinorTicmark {\n");
+ fprintf (fp, " moveto\n");
+ fprintf (fp, " %d 0 rlineto ", MINOR_TICK_SIZE);
+ fprintf (fp, " %d 0 rmoveto ",
+ scols + MAJOR_TICK_SIZE + (2*AXIS_IOFFSET) +
+ (MAJOR_TICK_SIZE - MINOR_TICK_SIZE) );
+ fprintf (fp, " -%d 0 rlineto\n", MINOR_TICK_SIZE);
+ fprintf (fp, " %g setlinewidth\n stroke\n", MINOR_TICK_WIDTH);
+ fprintf (fp, "} def\n");
+
+ /* The axis labeling. */
+ if (turnflag)
+ eps_landLabels (fp, psim, scols, srows, icols, irows, llx, lly);
+ else
+ eps_portLabels (fp, psim, scols, srows, icols, irows, llx, lly);
+ fprintf (fp, "grestore\n");
+ }
+
+ /* The colorbar. */
+ if (psim->page.flags & EPS_DOCOLORBAR) {
+ eps_doColorbar (fp, psim, scols, srows, llx, lly, turnflag);
+
+ /* Print the transform information. */
+ fprintf (fp, "gsave\n");
+ fprintf (fp, "/Times-Roman findfont 8 scalefont setfont\n");
+ if (turnflag) {
+ cbar_size = MIN (512, MAX (256, srows + 2));
+ fprintf (fp, "%d %d moveto\n",
+ (int)llx + scols + 26,
+ (int)lly + (srows/2) - (cbar_size/2)-(cbar_size==256?5:1));
+ } else {
+ cbar_size = MIN (512, MAX (256, scols + 2));
+ fprintf (fp, "%d %d moveto\n",
+ (int)llx + (scols/2) - (cbar_size/2)-(cbar_size==256?5:1),
+ (int)(lly-29));
+ }
+ fprintf (fp, "(z1=%.2f z2=%.2f ztrans=%s Con=%.2f Brt=%.2f cmap=%s ncolors=%d) %s show %s\n",
+ psim->z1, psim->z2,
+ (psim->ztype==EPS_UNITARY ? "unitary":
+ (psim->ztype==EPS_LINEAR ? "linear" : "log")),
+ psim->scale, psim->offset,
+ psim->cmap.cmap_name,
+ psim->cmap.max - psim->cmap.min + 1,
+ (turnflag ? "90 rotate" : " "),
+ (turnflag ? "-90 rotate" : " "));
+ fprintf (fp, "grestore\n");
+ }
+
+ /* Print the timestamp. */
+ fprintf (fp, "gsave\n");
+ fprintf (fp, "/Times-Roman findfont 6 scalefont setfont\n");
+ fprintf (fp, "20 15 moveto\n(%s) show\n", make_label());
+ fprintf (fp, "grestore\n");
+
+ if (debug) {
+ fprintf (stderr, "colormap: min/max = %d/%d\n",
+ psim->cmap.min, psim->cmap.max);
+ fprintf (stderr, "label: '%s'", make_label());
+ }
+}
+
+
+/* EPS_PORTRAITLABELS -- Write out the labeling procedures for a portrait
+** mode image.
+*/
+
+static void
+eps_portLabels (fp, psim, scols, srows, icols, irows, llx, lly)
+FILE *fp;
+PSImagePtr psim;
+int scols, srows;
+int icols, irows;
+float llx, lly;
+{
+ int start, end, range, nlabels;
+ float xpos, xstep, ypos, ystep;
+ float Mval, xval=0.0, yval=0.0, tic, mtic, Mtic;
+
+
+ /* X Axis labeling and ticmarks.
+ */
+ nlabels = (scols > 256 ? 5 : 3);
+ fprintf (fp, "/axLabelX {\n");
+ if (psim->urx > psim->llx) {
+ start = psim->llx;
+ end = psim->urx;
+ } else {
+ start = psim->urx;
+ end = psim->llx;
+ }
+ range = end - start + 1;
+ Mtic = tic = ticstep ((float)range, (range>=256 ? NTICMARKS : 3));
+ mtic = (float) tic / (tic < 100 ? 5. : 10.);
+ Mval = ( (int)(start + Mtic) / (int) Mtic) * Mtic;
+ xval = ( (int)(start + mtic) / (int) mtic) * mtic;
+ xstep = mtic * ((float)scols/(float)(range));
+ if (psim->urx > psim->llx)
+ xpos = llx + ( (float)(xval - start) / (float)range * scols);
+ else {
+ xpos = (llx + scols) - ((float)(xval-start) / (float)range * scols);
+ xstep = -xstep;
+ }
+ while (xval <= end) {
+ if ( xval == Mval ) {
+ fprintf (fp, " %4d %4d xMajorTicmark\t",
+ (int)xpos, (int)(lly-AXIS_OOFFSET));
+ fprintf (fp, " (%g) %d %d axlabel\n",
+ xval,
+ (int)xpos-(xval>=1000?8:(xval>=100?5:2)),
+ (int)(lly-14));
+ Mval += Mtic;
+ } else
+ fprintf (fp, "\t%4d %4d xMinorTicmark\n",
+ (int)xpos, (int)(lly-AXIS_OOFFSET));
+ xval += mtic;
+ xpos += xstep;
+ }
+ fprintf (fp, "} def\n");
+ fprintf (fp, "axLabelX\n");
+
+ /* Y Axis labeling and ticmarks. */
+ nlabels = (srows > 256 ? 5 : 3);
+ fprintf (fp, "/axLabelY {\n");
+ if (psim->ury > psim->lly) {
+ start = psim->lly;
+ end = psim->ury;
+ } else {
+ start = psim->ury;
+ end = psim->lly;
+ }
+ range = end - start + 1;
+ Mtic = tic = ticstep ((float)range, (range>=256 ? NTICMARKS : 3));
+ mtic = (float) tic / (tic < 100 ? 5. : 10.);
+ Mval = ( (int)(start + Mtic) / (int) Mtic) * Mtic;
+ yval = ( (int)(start + mtic) / (int) mtic) * mtic;
+ ystep = mtic * ((float)srows/(float)(range));
+ if (psim->ury > psim->lly)
+ ypos = lly + ( (float)(yval - start) / (float)range * srows);
+ else {
+ ypos = (lly + srows) - ((float)(yval-start) / (float)range * srows);
+ ystep = -ystep;
+ }
+ while (yval <= end) {
+ if ( yval == Mval ) {
+ fprintf (fp, " %4d %4d yMajorTicmark\t",
+ (int)(llx-AXIS_OOFFSET), (int)ypos);
+ fprintf (fp, " (%g) %d %d axlabel\n",
+ yval,
+ (int)(llx-(yval>=1000?27:(yval>=100?20:16))),
+ (int)ypos-2);
+ Mval += Mtic;
+ } else
+ fprintf (fp, "\t%4d %4d yMinorTicmark\n",
+ (int)(llx-AXIS_OOFFSET), (int)ypos);
+ yval += mtic;
+ ypos += ystep;
+ }
+ fprintf (fp, "} def\n");
+ fprintf (fp, "axLabelY\n");
+}
+
+
+/* EPS_LANDSCAPELABELS -- Write out the labeling procedures for a landscape
+** mode image.
+*/
+static void
+eps_landLabels (fp, psim, scols, srows, icols, irows, llx, lly)
+FILE *fp;
+PSImagePtr psim;
+int scols, srows;
+int icols, irows;
+float llx, lly;
+{
+ float xpos, xstep, ypos, ystep;
+ int start, end, range, nlabels;
+ float Mval, xval=0.0, yval=0.0, tic, mtic, Mtic;
+
+
+ /* X Axis labeling and ticmarks. */
+ nlabels = (srows > 256 ? 5 : 3);
+ fprintf (fp, "/axLabelX {\n");
+ if (psim->ury > psim->lly) {
+ start = psim->lly;
+ end = psim->ury;
+ } else {
+ start = psim->ury;
+ end = psim->lly;
+ }
+ range = end - start + 1;
+ Mtic = tic = ticstep ((float)range, (range>=256 ? NTICMARKS : 3));
+ mtic = (float) tic / (tic < 100 ? 5. : 10.);
+ Mval = ( (int)(start + Mtic) / (int) Mtic) * Mtic;
+ xval = ( (int)(start + mtic) / (int) mtic) * mtic;
+ xstep = mtic * ((float)scols/(float)(range));
+ if (psim->ury > psim->lly)
+ xpos = (llx + scols) - ((float)(xval-start) / (float)range * scols);
+ else {
+ xpos = llx + ((float)(xval-start) / (float)range * scols);
+ xstep = -xstep;
+ }
+ while (xval <= end ) {
+ if ( xval == Mval ) {
+ fprintf (fp, " %4d %4d xMajorTicmark\t",
+ (int)xpos, (int)(lly-AXIS_OOFFSET));
+ fprintf (fp, " (%g) %d %d axlabel\n",
+ xval,
+ (int)xpos+2,
+ (int)(lly-(yval>=1000?30:(yval>=100?25:20))) );
+ Mval += Mtic;
+ } else
+ fprintf (fp, "\t%4d %4d xMinorTicmark\n",
+ (int)xpos, (int)(lly-AXIS_OOFFSET));
+ xval += mtic;
+ xpos -= xstep;
+ }
+ fprintf (fp, "} def\n");
+ fprintf (fp, "axLabelX\n");
+
+ /* Y Axis labeling and ticmarks. */
+ nlabels = (srows > 256 ? 5 : 3);
+ fprintf (fp, "/axLabelY {\n");
+ if (psim->urx > psim->llx) {
+ start = psim->llx;
+ end = psim->urx;
+ } else {
+ start = psim->urx;
+ end = psim->llx;
+ }
+ Mtic = tic = ticstep ((float)range, (range>=256 ? NTICMARKS : 3));
+ mtic = (float) tic / (tic < 100 ? 5. : 10.);
+ Mval = ( (int)(start + Mtic) / (int) Mtic) * Mtic;
+ yval = ( (int)(start + mtic) / (int) mtic) * mtic;
+ ystep = mtic * ((float)scols/(float)(range));
+ if (psim->urx > psim->llx)
+ ypos = lly + ( (float)(yval - start) / (float)range * scols);
+ else {
+ ypos = (lly + srows) - ((float)(yval-start) / (float)range * scols);
+ ystep = -ystep;
+ }
+ while (yval <= end) {
+ if ( yval == Mval ) {
+ fprintf (fp, " %4d %4d yMajorTicmark\t",
+ (int)(llx-AXIS_OOFFSET), (int)ypos);
+ fprintf (fp, " (%g) %d %d axlabel\n",
+ yval,
+ (int)(llx+scols+(2*AXIS_OOFFSET)+2),
+ (int)ypos-(yval>=1000?9:(yval>=100?6:2)) );
+ Mval += Mtic;
+ } else
+ fprintf (fp, "\t%4d %4d yMinorTicmark\n",
+ (int)(llx-AXIS_OOFFSET), (int)ypos);
+ yval += mtic;
+ ypos += ystep;
+ }
+ fprintf (fp, "} def\n");
+ fprintf (fp, "axLabelY\n");
+}
+
+
+/* EPS_DOCOLORBAR -- Annotate the image with a colorbar.
+*/
+
+static void
+eps_doColorbar (fp, psim, scols, srows, llx, lly, turnflag)
+FILE *fp;
+PSImagePtr psim;
+int scols, srows;
+float llx, lly;
+int turnflag;
+{
+ register int i, j, cbar_size;
+ int ncolors, nlabels, pos, step, cmel, cmstep, val;
+
+
+ /* Colorbar label font definitions. */
+ fprintf (fp, "/cblabelfont /Times-Roman findfont 10 scalefont def\n");
+ fprintf (fp, "/cblabel { moveto cblabelfont setfont %s show %s } def\n",
+ (turnflag ? "90 rotate" : " "),
+ (turnflag ? "-90 rotate" : " "));
+
+ /* A border for the colorbar. */
+ fprintf (fp, "/cbarBorder {\n");
+ if (turnflag) {
+ cbar_size = MIN (512, MAX (256, srows + 2)) - 1;
+ fprintf (fp, " %4d %4d moveto\n",
+ (int)llx + scols + 31,
+ (int)lly + (srows/2) - (cbar_size/2) - 1);
+ fprintf (fp, " 17 0 rlineto\n");
+ fprintf (fp, " 0 %4d rlineto\n", cbar_size + 3);
+ fprintf (fp, " -17 0 rlineto\n");
+ } else {
+ cbar_size = MIN (512, MAX (256, scols + 2));
+ fprintf (fp, " %-4d %4d moveto\n",
+ (int)llx + (scols/2) - (cbar_size/2) - 1,
+ (int)(lly - 46));
+ fprintf (fp, " 0 14 rlineto\n");
+ fprintf (fp, " %-4d 0 rlineto\n", cbar_size + 3);
+ fprintf (fp, " 0 -14 rlineto\n");
+ }
+ fprintf (fp, " closepath\n");
+ fprintf (fp, " 1 setlinewidth\n");
+ fprintf (fp, " stroke\n");
+ fprintf (fp, "} def\n");
+ fprintf (fp, "cbarBorder\n");
+
+ /* Draw the colorbar labels, but only for grayscale images. */
+ ncolors = psim->cmap.max - psim->cmap.min + 1;
+ nlabels = 5;
+ if (turnflag)
+ pos = (int)lly + (srows/2) - (cbar_size/2);
+ else
+ pos = (int)llx + (scols/2) - (cbar_size/2);
+ step = cbar_size / nlabels;
+ cmel = psim->cmap.min;
+ cmstep = ncolors / nlabels;
+ for (i=0; i <= nlabels; i++) {
+ val = MONO(psim->cmap.r[cmel], /* get grayscale value */
+ psim->cmap.g[cmel],
+ psim->cmap.b[cmel]);
+ if (psim->z1 != 0.0 && psim->z2 != 0.0) {
+ /* We have a transformation defined, convert the grayscale
+ * value to original image values. Assumes a linear
+ * transformation, for a log transformation the wcsbox
+ * reports only screen units so we'll do that here as well.
+ */
+ if (psim->ztype == EPS_LINEAR)
+ val = ((psim->z2-psim->z1)/(float)ncolors)*cmel + psim->z1;
+ }
+
+ if (turnflag)
+ fprintf (fp, "(%d) %d %d cblabel\n",
+ val,
+ (int)llx + scols + 57,
+ pos-(val<100?3:6));
+ else
+ fprintf (fp, "(%d) %d %d cblabel\n",
+ val,
+ pos-(val<100?3:6),
+ (int)(lly-55));
+ cmel += cmstep;
+ cmel = (cmel < psim->cmap.max ? cmel : psim->cmap.max);
+ pos += step;
+ }
+
+ /* Draw the colorbar. */
+ if (psim->colorClass == EPS_GRAYSCALE) {
+ fprintf (fp, "/cbarstr %d string def\n", ncolors);
+ fprintf (fp, "gsave\n" );
+ if (turnflag) {
+ fprintf (fp, "%d %d translate\n",
+ (int)(llx + scols + 45),
+ (int)(lly + (srows/2) - (cbar_size/2)) + 1);
+ fprintf (fp,
+ "0.5 0.5 translate 90 rotate -0.5 -0.5 translate\n");
+ } else {
+ fprintf (fp, "%g %g translate\n",
+ llx + (scols/2) - (cbar_size/2) + 1,
+ lly - 45 );
+ }
+ fprintf (fp, "%d 12 scale\n", cbar_size);
+ fprintf (fp, "%d 1 8 [ %d 0 0 1 0 0 ]\n", ncolors, ncolors);
+
+ fprintf (fp, "{ cbarstr readstring }\n" );
+ fprintf (fp, "image\n" );
+
+ } else {
+ fprintf (fp, "DisplayImage\n" );
+ if (turnflag) {
+ fprintf (fp, "%d %d\n",
+ (int)(llx + scols + 34),
+ (int)(lly + (srows/2) - (cbar_size/2)));
+ fprintf (fp, "12 %d\n", cbar_size);
+ } else {
+ fprintf (fp, "%d %d\n",
+ (int)llx + (scols/2) - (cbar_size/2),
+ (int)lly - 45 );
+ fprintf (fp, "%d 12\n", cbar_size);
+ }
+ fprintf (fp, "%d 1\n", ncolors);
+ fprintf (fp, "%d\n", turnflag);
+ fprintf (fp, "0\n");
+ fprintf (fp, "1\n");
+ }
+
+ /* Write out the colormap used. */
+ if (psim->colorClass == EPS_GRAYSCALE) {
+ for (i=psim->cmap.min; i <= psim->cmap.max; i++ ) {
+ fprintf (fp, "%02x",
+ MONO(psim->cmap.r[i],psim->cmap.g[i], psim->cmap.b[i]));
+ if ((i+1) % 32 == 0)
+ fprintf (fp, "\n");
+ }
+ fprintf (fp, "\n");
+ fprintf (fp, "grestore\n");
+ } else {
+ for (j=1, i=psim->cmap.min; i <= psim->cmap.max; i++, j++ )
+ fprintf (fp, "%02x%02x%02x\n",
+ psim->cmap.r[i],psim->cmap.g[i], psim->cmap.b[i]);
+ if (j % 12 ==0)
+ fprintf (fp, "\n");
+ }
+}
+
+
+/* EPS_COLORHEADER - Write the pseudocolor header prolog and compute EPS page
+** parameters.
+*/
+static char *EPSColorProlog[]=
+ {
+ "%%BeginProlog",
+ "%",
+ "% Display a color image. The image is displayed in color on",
+ "% Postscript viewers or printers that support color, otherwise",
+ "% it is displayed as grayscale.",
+ "%",
+ "/buffer 512 string def",
+ "/byte 1 string def",
+ "/color_packet 3 string def",
+ "/pixels 768 string def",
+ "",
+ "/DirectClassPacket",
+ "{",
+ " %",
+ " % Get a DirectClass packet.",
+ " %",
+ " % Parameters: ",
+ " % red.",
+ " % green.",
+ " % blue.",
+ " % length: number of pixels minus one of this color (optional).",
+ " %",
+ " currentfile color_packet readhexstring pop pop",
+ " compression 0 gt",
+ " {",
+ " /number_pixels 3 def",
+ " }",
+ " {",
+ " currentfile byte readhexstring pop 0 get",
+ " /number_pixels exch 1 add 3 mul def",
+ " } ifelse",
+ " 0 3 number_pixels 1 sub",
+ " {",
+ " pixels exch color_packet putinterval",
+ " } for",
+ " pixels 0 number_pixels getinterval",
+ "} bind def",
+ "",
+ "/DirectClassImage",
+ "{",
+ " %",
+ " % Display a DirectClass image.",
+ " %",
+ " systemdict /colorimage known",
+ " {",
+ " columns rows 8",
+ " [",
+ " columns 0 0",
+ " rows neg 0 rows",
+ " ]",
+ " { DirectClassPacket } false 3 colorimage",
+ " }",
+ " {",
+ " %",
+ " % No colorimage operator; convert to grayscale.",
+ " %",
+ " columns rows 8",
+ " [",
+ " columns 0 0",
+ " rows neg 0 rows",
+ " ]",
+ " { GrayDirectClassPacket } image",
+ " } ifelse",
+ "} bind def",
+ "",
+ "/GrayDirectClassPacket",
+ "{",
+ " %",
+ " % Get a DirectClass packet; convert to grayscale.",
+ " %",
+ " % Parameters: ",
+ " % red",
+ " % green",
+ " % blue",
+ " % length: number of pixels minus one of this color (optional).",
+ " %",
+ " currentfile color_packet readhexstring pop pop",
+ " color_packet 0 get 0.299 mul",
+ " color_packet 1 get 0.587 mul add",
+ " color_packet 2 get 0.114 mul add",
+ " cvi",
+ " /gray_packet exch def",
+ " compression 0 gt",
+ " {",
+ " /number_pixels 1 def",
+ " }",
+ " {",
+ " currentfile byte readhexstring pop 0 get",
+ " /number_pixels exch 1 add def",
+ " } ifelse",
+ " 0 1 number_pixels 1 sub",
+ " {",
+ " pixels exch gray_packet put",
+ " } for",
+ " pixels 0 number_pixels getinterval",
+ "} bind def",
+ "",
+ "/GrayPseudoClassPacket",
+ "{",
+ " %",
+ " % Get a PseudoClass packet; convert to grayscale.",
+ " %",
+ " % Parameters: ",
+ " % index: index into the colormap.",
+ " % length: number of pixels minus one of this color (optional).",
+ " %",
+ " currentfile byte readhexstring pop 0 get",
+ " /offset exch 3 mul def",
+ " /color_packet colormap offset 3 getinterval def",
+ " color_packet 0 get 0.299 mul",
+ " color_packet 1 get 0.587 mul add",
+ " color_packet 2 get 0.114 mul add",
+ " cvi",
+ " /gray_packet exch def",
+ " compression 0 gt",
+ " {",
+ " /number_pixels 1 def",
+ " }",
+ " {",
+ " currentfile byte readhexstring pop 0 get",
+ " /number_pixels exch 1 add def",
+ " } ifelse",
+ " 0 1 number_pixels 1 sub",
+ " {",
+ " pixels exch gray_packet put",
+ " } for",
+ " pixels 0 number_pixels getinterval",
+ "} bind def",
+ "",
+ "/PseudoClassPacket",
+ "{",
+ " %",
+ " % Get a PseudoClass packet.",
+ " %",
+ " % Parameters: ",
+ " % index: index into the colormap.",
+ " % length: number of pixels minus one of this color (optional).",
+ " %",
+ " currentfile byte readhexstring pop 0 get",
+ " /offset exch 3 mul def",
+ " /color_packet colormap offset 3 getinterval def",
+ " compression 0 gt",
+ " {",
+ " /number_pixels 3 def",
+ " }",
+ " {",
+ " currentfile byte readhexstring pop 0 get",
+ " /number_pixels exch 1 add 3 mul def",
+ " } ifelse",
+ " 0 3 number_pixels 1 sub",
+ " {",
+ " pixels exch color_packet putinterval",
+ " } for",
+ " pixels 0 number_pixels getinterval",
+ "} bind def",
+ "",
+ "/PseudoClassImage",
+ "{",
+ " %",
+ " % Display a PseudoClass image.",
+ " %",
+ " % Parameters: ",
+ " % colors: number of colors in the colormap.",
+ " % colormap: red, green, blue color packets.",
+ " %",
+ " currentfile buffer readline pop",
+ " token pop /colors exch def pop",
+ " /colors colors 3 mul def",
+ " /colormap colors string def",
+ " currentfile colormap readhexstring pop pop",
+ " systemdict /colorimage known",
+ " {",
+ " columns rows 8",
+ " [",
+ " columns 0 0",
+ " rows neg 0 rows",
+ " ]",
+ " { PseudoClassPacket } false 3 colorimage",
+ " }",
+ " {",
+ " %",
+ " % No colorimage operator; convert to grayscale.",
+ " %",
+ " columns rows 8",
+ " [",
+ " columns 0 0",
+ " rows neg 0 rows",
+ " ]",
+ " { GrayPseudoClassPacket } image",
+ " } ifelse",
+ "} bind def",
+ "",
+ "/DisplayImage",
+ "{",
+ " %",
+ " % Display a DirectClass or PseudoClass image.",
+ " %",
+ " % Parameters: ",
+ " % x & y translation.",
+ " % x & y scale.",
+ " % image columns & rows.",
+ " % orientation: 0-Portrait or 1-Landscape",
+ " % class: 0-DirectClass or 1-PseudoClass.",
+ " % compression: 0-RunlengthEncodedCompression or 1-NoCompression.",
+ " % hex color packets.",
+ " %",
+ " gsave",
+ " currentfile buffer readline pop",
+ " token pop /x exch def",
+ " token pop /y exch def pop",
+ " x y translate",
+ " currentfile buffer readline pop",
+ " token pop /x exch def",
+ " token pop /y exch def pop",
+ " x y scale",
+ " currentfile buffer readline pop",
+ " token pop /columns exch def",
+ " token pop /rows exch def pop",
+ " currentfile buffer readline pop",
+ " token pop /orient exch def pop",
+ " orient 0 gt { 0.5 0.5 translate 90 rotate -0.5 -0.5 translate } if",
+ " currentfile buffer readline pop",
+ " token pop /class exch def pop",
+ " currentfile buffer readline pop",
+ " token pop /compression exch def pop",
+ " class 0 gt { PseudoClassImage } { DirectClassImage } ifelse",
+ " grestore",
+ "} bind def",
+ "%%EndProlog",
+ "%%Page: 1 1",
+ NULL
+};
+
+
+static void
+eps_colorHeader (psim, fp)
+PSImagePtr psim;
+FILE *fp;
+{
+ register char **line;
+ int icols=0, irows=0, scols=0, srows=0, turnflag=0;
+ float llx = 0.0, lly = 0.0;
+ time_t timer;
+
+
+ /* Get the common page parameters. */
+ eps_pageParams (psim, &llx, &lly, &icols, &irows, &scols, &srows,
+ &turnflag);
+
+ /* Now write header and prolog stuff */
+ fprintf (fp, "%%!PS-Adobe-3.0 EPSF-3.0\n");
+ fprintf (fp, "%%%%Title: XImtool Screen Hardcopy\n");
+ fprintf (fp, "%%%%Creator: XImtool\n");
+ timer = time ((time_t *) NULL);
+ (void) localtime (&timer);
+ fprintf (fp, "%%%%CreationDate: %s", ctime(&timer));
+ if (psim->annotate)
+ fprintf (fp, "%%%%BoundingBox: %d %d %d %d\n",
+ (int) (MAX (0, llx - X_ANNOT_MARGIN)),
+ (int) (MAX (0, lly - Y_ANNOT_MARGIN)),
+ (int) ( llx + scols + 0.5 + X_ANNOT_MARGIN),
+ (int) ( lly + srows + 0.5 + Y_ANNOT_MARGIN) );
+ else
+ fprintf (fp, "%%%%BoundingBox: %d %d %d %d\n",
+ (int) (MAX (0, llx - 10)),
+ (int) (MAX (0, lly - 10)),
+ (int) ( llx + scols + 0.5 + 10),
+ (int) ( lly + srows + 0.5 + 10) );
+ fprintf (fp, "%%%%Pages: 1\n");
+ fprintf (fp, "%%%%EndComments\n");
+
+ /* Output remaining Postscript prolog commands. */
+ for (line = EPSColorProlog; *line; line++)
+ fprintf (fp, "%s\n",*line);
+ fprintf (fp, "userdict begin\n");
+ fprintf (fp, "%%%%BeginData:\n");
+
+ fprintf (fp, "DisplayImage\n");
+
+ /* Now write the image display parameters, specifically
+ *
+ * x & y translation.
+ * x & y scale.
+ * image columns & rows.
+ * orientation: 0-Portrait or 1-Landscape
+ * class: 0-DirectClass or 1-PseudoClass.
+ * compression: 0-RunlengthEncodedCompression or 1-NoCompression.
+ * hex color packets.
+ */
+
+ fprintf (fp, "%d %d\n%u %u\n%u %u\n%d\n%d\n%d\n",
+ (int) llx, (int) lly,
+ (int) scols, (int) srows,
+ psim->cols, psim->rows,
+ turnflag,
+ psim->colorClass == EPS_PSEUDOCOLOR,
+ psim->compression == NoCompression);
+}
+
+
+/* EPS_WRITETRAILER -- Output Postscript trailer blurb.
+*/
+static void
+eps_writeTrailer (fp)
+FILE *fp;
+{
+ fprintf (fp, "\n");
+ fprintf (fp, "showpage\n");
+ fprintf (fp, "%%%%EndData\n");
+ fprintf (fp, "end\n");
+ fprintf (fp, "%%%%PageTrailer\n");
+ fprintf (fp, "%%%%Trailer\n");
+ fprintf (fp, "%%%%EOF\n");
+}
+
+
+/* EPS_SIMPLETRAILER -- Output Postscript trailer blurb.
+*/
+static void
+eps_simpleTrailer (fp)
+FILE *fp;
+{
+ fprintf (fp, "showpage\n");
+}
+
+
+static void
+eps_flushPix (fp)
+FILE *fp;
+{
+ pixbuf[pixnum] = '\0';
+ fprintf (fp, "%s", pixbuf);
+ pixnum = 0;
+ lpix = 0;
+}
+
+
+/* Utility Routines.
+*/
+
+/* TICSTEP -- calculate nice intervals for the ticmarks.
+*/
+static float
+ticstep (range,nsteps)
+float range;
+int nsteps;
+{
+ double df, t2, t5, p1, p2, p3;
+ float ticstep;
+ int logtic;
+
+
+ df = range / (float)(nsteps + 1);
+ t2 = 0.301029996;
+ t5 = 0.698970004;
+ p1 = log10 ((double)(df > 0.0 ? df : -df));
+ p2 = (int) p1;
+ p3 = p1 - p2;
+ if(p3 < 0.) {
+ p3 = p2 + 1.;
+ p2 = p2 - 1.;
+ }
+
+ if (p3 < 1.0e-10)
+ ticstep = pow((double)10.0,(double)(p2));
+ else if (p3 > 0. && p3 <= t2)
+ ticstep = pow((double)10.0,(double)(p2+t2));
+ else if (p3 > t2 && p3 <= t5)
+ ticstep = pow((double)10.0,(double)(p2+t5));
+ else if (p3 > t5 && p3 <= 1.)
+ ticstep = pow((double)10.0,(double)(p2+1.));
+ else
+ ticstep = df;
+
+ logtic = (int) log10(ticstep) - 1;
+ ticstep = (int)( (ticstep / pow((double)10.,(double)logtic)) *
+ pow((double)10.,(double)logtic) );
+
+ if (ticstep < 0.1) ticstep = 0.10;
+
+ return (ticstep);
+}
+
+
+/* MAKE_LABEL -- Generate the label for the output printer page.
+*/
+static char *
+make_label()
+{
+ static char buf[128];
+ char hostname[32];
+ char username[32];
+ struct passwd *pw;
+ long clock;
+
+
+ bzero (buf, 128);
+ bzero (hostname, 32);
+ bzero (username, 32);
+
+#ifdef SOLARIS
+ sysinfo (SI_HOSTNAME, hostname, 32);
+#else
+ gethostname (hostname, 32);
+#endif
+
+ clock = time(0);
+ pw = getpwuid (getuid());
+ strcpy (username, pw->pw_name);
+ endpwent();
+
+ sprintf (buf, "NOAO/IRAF %s@%s %s",
+ username, hostname, asctime(localtime(&clock)));
+
+ return (buf);
+}