aboutsummaryrefslogtreecommitdiff
path: root/vendor/x11iraf/ximtool/save.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/save.c
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'vendor/x11iraf/ximtool/save.c')
-rw-r--r--vendor/x11iraf/ximtool/save.c377
1 files changed, 377 insertions, 0 deletions
diff --git a/vendor/x11iraf/ximtool/save.c b/vendor/x11iraf/ximtool/save.c
new file mode 100644
index 00000000..51d5b7c4
--- /dev/null
+++ b/vendor/x11iraf/ximtool/save.c
@@ -0,0 +1,377 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+
+#include "ximtool.h"
+
+/*
+ * SAVE.C -- Routines for saving image rasters to disk files.
+ *
+ * xim_initSave (xim)
+ * xim_saveClose (xim)
+ *
+ * status = xim_saveFile (xim, fname, format, x0,y0, nx,ny)
+ *
+ * xims_rename (xim, old, new) # save alert action
+ * xims_cancel (xim, fname) # save alert action
+ *
+ * xim_saveFile saves the current display frame to the named file using
+ * the format specified. If nx or ny is zero the entire frame is saved,
+ * otherwise the indicated region is saved.
+ */
+
+static int xims_write();
+static void savestat(), savetext();
+
+
+/* XIM_INITSAVE -- Initialize the file save structure.
+ */
+void
+xim_initSave (xim)
+register XimDataPtr xim;
+{
+ register fileSavePtr fsp;
+ extern char *getcwd(), *getenv();
+ char buf[SZ_LINE];
+
+ if (!(xim->fsp = fsp = (fileSavePtr) calloc (1, sizeof (fileSave))))
+ return;
+
+ fsp->seqno = 0;
+ fsp->format = XIM_RAS;
+ fsp->colorType = XIM_PSEUDOCOLOR;
+ strcpy (fsp->fname, "frame%d.ras");
+
+ /* Now update the GUI. */
+ sprintf (buf, "format ras");
+ xim_message (xim, "saveOptions", buf);
+ sprintf (buf, "color pseudocolor");
+ xim_message (xim, "saveOptions", buf);
+ sprintf (buf, "fname frame%%d.ras");
+ xim_message (xim, "saveOptions", buf);
+}
+
+
+/* XIM_SAVECLOSE -- Close the save structure.
+ */
+void
+xim_saveClose (xim)
+register XimDataPtr xim;
+{
+ register fileSavePtr fsp = xim->fsp;
+
+ if (fsp)
+ free ((char *) fsp);
+}
+
+
+/* XIM_SAVEFILE - Save the current display frame to a disk file. If nx or
+ * ny is zero the entire frame is saved, otherwise the given region is saved.
+ */
+int
+xim_saveFile (xim, template, fileformat, x0,y0, nx,ny)
+register XimDataPtr xim;
+char *template; /* file name or printf format */
+int fileformat; /* output raster file format/type */
+int x0, y0, nx, ny; /* region of display to be saved */
+{
+ register int i, j;
+ register fileSavePtr fsp = xim->fsp;
+ int w, h, ncols;
+ char text[SZ_LINE], fname[SZ_FNAME];
+ unsigned char r[256], g[256], b[256];
+ unsigned char *pixels = NULL;
+ int status = -1;
+ static int debug=0;
+ extern int errno;
+ FILE *fp;
+ char *mktemp();
+
+ /* Generate output file name. */
+ sprintf (fname, template, fsp->seqno++);
+
+ /* Get the display pixels and colormap. The routine allocates a
+ * pointer to the pixels we'll need to free when we're done.
+ */
+ pixels = xim_readDisplay (xim, x0,y0,nx,ny, &w,&h, r,g,b, &ncols);
+ if (!pixels)
+ goto done;
+
+ if (debug) {
+ register int cpix, val;
+ fprintf (stderr, "saveFile: %s -> %dx%d at %d colors\n",
+ fname, w, h, ncols);
+ cpix = (w/2+(h/2)*w);
+ val = pixels[cpix];
+ fprintf (stderr, "Center pixel %d: val=%d (%d,%d,%d)\n",cpix,
+ val,r[val],g[val],b[val]);
+ fprintf (stderr, "User Colormap\n");
+ for (i=0; i < 256; ) {
+ for (j=1; j < 4 && i < 256; j++)
+ fprintf (stderr, " %3d(%3d,%3d,%3d)",i,r[i],g[i],b[i++]);
+ fprintf (stderr, "\n");
+ }
+ }
+
+ fsp->w = w;
+ fsp->h = h;
+ fsp->d = 8;
+
+ if (access (fname, F_OK) < 0) {
+ if (fp = fopen (fname, "w")) {
+ struct stat fs;
+
+ xims_write (xim, fp, fileformat, pixels, w,h,8, r,g,b, 256);
+ fclose (fp);
+ stat (fname, &fs);
+
+ savetext (xim, fsp->seqno, fname, fileformat, (int)fs.st_size,
+ w, h, 8);
+ sprintf (text, "Wrote %d bytes to %s", (int)fs.st_size, fname);
+ savestat (xim, text);
+
+ } else {
+ sprintf (text, "Error %d\nCannot open file %s", errno, fname);
+ xim_alert (xim, text, NULL, NULL);
+ fsp->seqno--;
+ }
+
+ } else {
+ /* Named file already exists. Write a temporary file and
+ * post an alert to ask the user if they want to overwrite
+ * the existing file.
+ */
+ char ok_action[SZ_LINE];
+ char cancel_action[SZ_LINE];
+ char tmpfile[SZ_FNAME];
+ char *ip, *op, *last;
+
+ /* Write to a temporary file in the same directory as fname. */
+ for (ip=fname, op=tmpfile, last=tmpfile; *op = *ip++; op++)
+ if (*op == '/')
+ last = op + 1;
+ *last = '\0';
+ strcat (tmpfile, "ximsXXXXXX");
+ if (mktemp(tmpfile) == (char *)NULL)
+ goto done;
+
+ if (!(fp = fopen (tmpfile, "w"))) {
+ sprintf (text, "Cannot open temporary file:\n%s", tmpfile);
+ xim_alert (xim, text, NULL, NULL);
+ goto done;
+ }
+ xims_write (xim, fp, fileformat, pixels, w,h,8, r,g,b, 256);
+ fclose (fp);
+
+ sprintf (text, "%s\n%s\n%s",
+ "The following file already exists:", fname,
+ "Do you want to overwrite this file?");
+
+ sprintf (ok_action, "save rename %s %s", tmpfile, fname);
+ sprintf (cancel_action, "save cancel %s", tmpfile);
+
+ xim_alert (xim, text, ok_action, cancel_action);
+ }
+
+ status = 0;
+done:
+ if (pixels)
+ free ((char *) pixels);
+ return (status);
+}
+
+
+/* XIMS_WRITE -- Write a file in the indicated format.
+ */
+static int
+xims_write (xim, fp, fileformat, pixels, w,h,d, r,g,b, ncolors)
+register XimDataPtr xim;
+FILE *fp;
+int fileformat;
+unsigned char *pixels;
+int w, h, d;
+unsigned char *r, *g, *b;
+int ncolors;
+{
+ register fileSavePtr fsp = xim->fsp;
+ register PSImagePtr psim = xim->psim;
+ register FrameBufPtr fb = xim->df_p;
+ register ColorMapPtr cm = &colormaps[fb->colormap-1];
+ register int sv_annotate = psim->annotate;
+ register int sv_colorClass = psim->colorClass;
+ int gray=0, status=0;
+
+
+ switch (fileformat) {
+ case XIM_RAS:
+ /* Write Sun Rasterfile. We don't support 24-bit yet but can
+ * add it later.
+ */
+ savestat (xim, "Generating Sun rasterfile...");
+ if (xim->fsp->colorType == XIM_GRAYSCALE)
+ status = writeSunRas (fp, pixels, 8, w,h, r,g,b, ncolors, 1);
+ else
+ status = writeSunRas (fp, pixels, 8, w,h, r,g,b, ncolors, 2);
+
+ break;
+
+ case XIM_FITS:
+ /* Write a simple FITS file.
+ */
+ savestat (xim, "Generating FITS file...");
+ status = writeFITS (fp, pixels, w, h, r, g, b, ncolors);
+ break;
+
+ case XIM_GIF:
+ /* Write a GIF file.
+ */
+ savestat (xim, "Generating GIF file...");
+ gray = (xim->fsp->colorType == XIM_GRAYSCALE);
+ status = writeGIF (fp, pixels, w, h, r, g, b, ncolors, gray);
+ break;
+
+ case XIM_TIFF:
+ /* Write a TIFF file.
+ */
+ savestat (xim, "Generating TIFF file...");
+ gray = (xim->fsp->colorType == XIM_GRAYSCALE);
+ status = writeTIFF (fp, pixels, w, h, ncolors, gray, r, g, b);
+ break;
+
+ case XIM_EPS:
+ /* Write an EPS file.
+ */
+ savestat (xim, "Generating postscript output...");
+
+ /* Temporarily reset the values. */
+ psim->annotate = 0;
+ psim->colorClass = xim->fsp->colorType;
+
+ /* Set up some of the EPS options print to the file. */
+ eps_setCmap (psim, r, g, b, ncolors);
+ eps_setTransform (psim, fb->ctran.z1, fb->ctran.z2, fb->ctran.zt,
+ fb->offset, fb->scale, cm->name);
+ eps_print (psim, fp, pixels, w, h, 8, 0);
+
+ /* Restore the saved values. */
+ psim->annotate = sv_annotate;
+ psim->colorClass = sv_colorClass;
+ break;
+
+ case XIM_JPEG:
+ case XIM_X11:
+ case XIM_RAW:
+ default:
+ /* We don't know what this is so give up and notify the GUI. */
+ savestat (xim, "Save file format not implemented.");
+ status = -1;
+ break;
+ }
+
+ return (status);
+}
+
+
+/* The following implement the ok and cancel actions posted by the alert in
+ * xim_save above.
+ */
+void
+xims_rename (xim, old, new)
+register XimDataPtr xim;
+char *old, *new;
+{
+ register fileSavePtr fsp = xim->fsp;
+ char text[SZ_LINE];
+ struct stat fs;
+
+ unlink (new);
+ if (rename(old,new) != 0 || stat(new,&fs) != 0) {
+ sprintf (text, "Could not write file %s", new);
+ savestat (xim, text);
+ } else {
+ stat (new, &fs);
+ savetext (xim, fsp->seqno, new, fsp->format, (int)fs.st_size,
+ fsp->w, fsp->h, fsp->d);
+ sprintf (text, "Wrote %d bytes to %s", (int)fs.st_size, new);
+ savestat (xim, text);
+ }
+}
+
+void
+xims_cancel (xim, fname)
+register XimDataPtr xim;
+char *fname;
+{
+ savestat (xim, "Save cancelled.");
+ unlink (fname);
+}
+
+
+/* SAVESTAT -- Internal routine for save status messages.
+ */
+static void
+savestat (xim, message)
+register XimDataPtr xim;
+char *message;
+{
+ char text[SZ_LINE];
+ sprintf (text, "status {%s}", message);
+ xim_message (xim, "saveOptions", text);
+}
+
+
+/* SAVETEXT -- Write something useful the text box in the save panel.
+ */
+static void
+savetext (xim, seqno, fullname, fileformat, filesize, w,h,d)
+register XimDataPtr xim;
+int seqno;
+char *fullname;
+int fileformat;
+int filesize;
+int w, h, d;
+{
+ register char *ip;
+ char *fmt, *fname, text[SZ_LINE];
+
+ for (ip=fname=fullname; *ip; ip++)
+ if (*ip == '/')
+ fname = ip + 1;
+
+ switch (fileformat) {
+ case XIM_RAS:
+ fmt = "Sun rasterfile";
+ break;
+ case XIM_GIF:
+ fmt = "GIF file";
+ break;
+ case XIM_TIFF:
+ fmt = "TIFF file";
+ break;
+ case XIM_JPEG:
+ fmt = "JPEG file";
+ break;
+ case XIM_X11:
+ fmt = "X11 window dump";
+ break;
+ case XIM_FITS:
+ fmt = "FITS file";
+ break;
+ case XIM_RAW:
+ fmt = "Raw bytes";
+ break;
+ case XIM_EPS:
+ fmt = "EPS file";
+ break;
+ default:
+ fmt = "unknown format";
+ break;
+ }
+
+ sprintf (text, "text {-- Frame %d --\n%s\n%s\n%d bytes\n%dx%dx%d}",
+ seqno-1, fname, fmt, filesize, w, h, d);
+ xim_message (xim, "saveOptions", text);
+}