/*---------------------------------------------------------------------------*/ /* Program: imps.c */ /* */ /* Purpose: This program converts a KUIM format image to postscript */ /* for display on a laser printer or inclusion in a document. */ /* The messy postcript code is based on a /usr/image program */ /* by Terry Yoo at University of North Carolina at Chapel Hill. */ /* */ /* Author: John Gauch, Yanning Zhu */ /* */ /* Date: April 1, 1994 - Original version. */ /* June 10, 1995 - Updated output for inclusion in Word. */ /* December 2, 1996 - Color support added. */ /* */ /* Note: Copyright (C) The University of Kansas, 1994-1996 */ /*---------------------------------------------------------------------------*/ #include #define ROUND(f) ((f>0) ? (int)(f+0.5) : (int)(f-0.5)) #define MAPSIZE 1024 #define DEFMAPSIZE 256 #define LWMAPSIZE 33 #define MAXINTENSITY 255 #define PAGEHEIGHT 792 #define PAGEWIDTH 612 #define USABLEHEIGHT 756 #define USABLEWIDTH 576 #define ONEINCH 72 /* Global variables */ BYTE_TYPE **Data1; unsigned char Red[nCMAP]; unsigned char Green[nCMAP]; unsigned char Blue[nCMAP]; char Title[nTITLE]; int PureFlag = FALSE; int ZoomFlag = FALSE; int Xdim, Ydim; FILE *fd; /*---------------------------------------------------------------------------*/ /* Purpose: This routine converts an image to postscript. */ /*---------------------------------------------------------------------------*/ void ColorPS() { int index, i; float xscale, yscale, scale = 1.0; int x1, x2, y1, y2; /* Prepare to resize the image */ if (ZoomFlag == TRUE) { xscale = (float) USABLEWIDTH / (float) Xdim; yscale = (float) USABLEHEIGHT / (float) Ydim; scale = (xscale < yscale) ? xscale : yscale; } /* Calculate bounding box */ x1 = (int) ((PAGEWIDTH - Xdim * scale) / 2), y1 = (int) ((PAGEHEIGHT - Ydim * scale) / 2); x2 = x1 + Xdim; y2 = y1 + Ydim; /* Write out introductory comments */ fprintf(fd, "%%%!PS-Adobe-2.0\n"); fprintf(fd, "%%%%Title %s\n", Title); fprintf(fd, "%%%%Creator IMPS version 2.0\n"); fprintf(fd, "%%%%BoundingBox: %d %d %d %d\n", x1, y1, x2, y2); fprintf(fd, "%%%%Pages: 1\n"); fprintf(fd, "%%%%EndComments:\n"); fprintf(fd, "%%%%EndProlog:\n"); fprintf(fd, "%%%%Page: 1 1:\n"); fprintf(fd, "/origstate save def\n"); fprintf(fd, "20 dict begin\n"); /* Write out image title */ if (PureFlag == FALSE) { fprintf(fd, "\n"); fprintf(fd, "/Helvetica findfont 12 scalefont setfont\n"); fprintf(fd, "%d 0 sub\n", PAGEWIDTH); fprintf(fd, "(%s) stringwidth pop sub\n", Title); fprintf(fd, "2 div\n"); fprintf(fd, "%d moveto\n", y1 - ONEINCH / 4); fprintf(fd, "0 setgray\n"); fprintf(fd, "(%s) show\n\n", Title); } /* Write out image display program */ fprintf(fd, "\n"); fprintf(fd, "/pix %d string def\n", Xdim); fprintf(fd, "%d %d translate\n", x1, y1); fprintf(fd, "%d %d scale\n", (int) (Xdim * scale), (int) (Ydim * scale)); fprintf(fd, "%d %d 8\n", Xdim, Ydim); fprintf(fd, "[%d 0 0 -%d 0 %d]\n", Xdim, Ydim, Ydim); fprintf(fd, " {currentfile pix readhexstring pop }\n"); fprintf(fd, "false 3\n"); fprintf(fd, "colorimage\n\n"); /* Write out pixel information */ for (index = 0; index < Xdim * Ydim; index++) { i = Data1[0][index]; fprintf(fd, "%02x%02x%02x", Red[i], Green[i], Blue[i]); if ((index + 1) % Xdim == 0) fprintf(fd, "\n"); } /* Print postscript footer information */ fprintf(fd, "\n"); fprintf(fd, "showpage\n"); fprintf(fd, "end\n"); fprintf(fd, "origstate restore\n"); fprintf(fd, "%%%%Trailer\n"); } /*---------------------------------------------------------------------------*/ /* Purpose: This routine converts an image to postscript. */ /*---------------------------------------------------------------------------*/ void GreyPS() { int index; float xscale, yscale, scale = 1.0; int x1, x2, y1, y2; /* Prepare to resize the image */ if (ZoomFlag == TRUE) { xscale = (float) USABLEWIDTH / (float) Xdim; yscale = (float) USABLEHEIGHT / (float) Ydim; scale = (xscale < yscale) ? xscale : yscale; } /* Calculate bounding box */ x1 = (int) ((PAGEWIDTH - Xdim * scale) / 2), y1 = (int) ((PAGEHEIGHT - Ydim * scale) / 2); x2 = x1 + Xdim; y2 = y1 + Ydim; /* Write out introductory comments */ fprintf(fd, "%%%!PS-Adobe-2.0 EPSF-2.0\n"); fprintf(fd, "%%%%Title %s\n", Title); fprintf(fd, "%%%%Creator IMPS version 2.0\n"); fprintf(fd, "%%%%BoundingBox: %d %d %d %d\n", x1, y1, x2, y2); fprintf(fd, "%%%%Pages: 1\n"); fprintf(fd, "%%%%EndComments:\n"); fprintf(fd, "%%%%EndProlog:\n"); fprintf(fd, "%%%%Page: 1 1:\n"); fprintf(fd, "/origstate save def\n"); fprintf(fd, "20 dict begin\n"); /* Write out image title */ if (PureFlag == FALSE) { fprintf(fd, "\n"); fprintf(fd, "/Helvetica findfont 12 scalefont setfont\n"); fprintf(fd, "%d 0 sub\n", PAGEWIDTH); fprintf(fd, "(%s) stringwidth pop sub\n", Title); fprintf(fd, "2 div\n"); fprintf(fd, "%d moveto\n", y1 - ONEINCH / 4); fprintf(fd, "0 setgray\n"); fprintf(fd, "(%s) show\n\n", Title); } /* Write out image display program */ fprintf(fd, "\n"); fprintf(fd, "/pix %d string def\n", Xdim); fprintf(fd, "%d %d translate\n", x1, y1); fprintf(fd, "%d %d scale\n", (int) (Xdim * scale), (int) (Ydim * scale)); fprintf(fd, "%d %d 8\n", Xdim, Ydim); fprintf(fd, "[%d 0 0 -%d 0 %d]\n", Xdim, Ydim, Ydim); fprintf(fd, " {currentfile pix readhexstring pop }\n"); fprintf(fd, "image\n\n"); /* Write out pixel information */ for (index = 0; index < Xdim * Ydim; index++) { fprintf(fd, "%02x", Data1[0][index]); if ((index + 1) % Xdim == 0) fprintf(fd, "\n"); } /* Print postscript footer information */ fprintf(fd, "\n"); fprintf(fd, "showpage\n"); fprintf(fd, "end\n"); fprintf(fd, "origstate restore\n"); fprintf(fd, "%%%%Trailer\n"); } /*---------------------------------------------------------------------------*/ /* Purpose: This is the main program. */ /*---------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { /* Image variables */ char Name1[50]; char Name2[50]; IM_TYPE *Image1; BYTE_TYPE *Data0; int PixType, Zdim, DimCnt; /* Program variables */ int Debug = FALSE; int i = 0, x, y; int Max, Min; float Scale; /* Interpret program options */ fprintf(stderr, "IMPS Program - KUIM Version 3.0\n\n"); while ((++i < argc) && (argv[i][0] == '-')) switch (argv[i][1]) { case 'p': PureFlag = TRUE; break; case 'z': ZoomFlag = TRUE; break; case 'd': Debug = TRUE; break; default: Error("Invalid option encountered"); break; } /* Check number of file names */ if (argc - i < 1) { fprintf(stderr, "Usage: imps [options] infile [outfile]\n"); fprintf(stderr, " [-p] Output pure postscript for TeX\n"); fprintf(stderr, " [-z] Zoom image to fill page\n"); exit(1); } /* Get image file names from argument list */ if (sscanf(argv[i++], "%s", Name1) == 0) Error("Could not get input file name"); if ((i < argc) && (sscanf(argv[i++], "%s", Name2) == 0)) Error("Could not get output file name"); /* Read input image */ Image1 = im_open(Name1, &PixType, &Xdim, &Ydim, &Zdim, &DimCnt); if (DimCnt == 3) Error("Can not handle 3D images"); /* Handle 1D images */ if (DimCnt == 1) { /* Read 1D data */ Data0 = (BYTE_TYPE *) im_alloc1D(Image1, BYTE); im_read(Image1, BYTE, (char *) Data0); im_get_title(Image1, Title); if (strcmp(Title, "") == 0) strcpy(Title, Name1); /* Create 2D plot of 1D data */ Ydim = 256; Image1 = im_create("/dev/null", BYTE, Xdim, Ydim, 1); Data1 = (BYTE_TYPE **) im_alloc2D(Image1, BYTE); for (y = 0; y < Ydim; y++) for (x = 0; x < Xdim; x++) if ((Ydim - y) < Data0[x]) Data1[y][x] = 255; else Data1[y][x] = 0; for (y = 0; y < Ydim; y++) Data1[y][0] = Data1[y][Xdim - 1] = 0; for (x = 0; x < Xdim; x++) Data1[0][x] = Data1[Ydim - 1][x] = 0; } /* Handle 2D images */ if (DimCnt == 2) { if ((PixType == PSEUDO) || (PixType == COLOR) || (PixType == JPEG_RGB)) { Data1 = (BYTE_TYPE **) im_alloc2D(Image1, BYTE); im_read(Image1, PSEUDO, (char *) &(Data1[0][0])); im_get_cmap(Image1, Red, Green, Blue); im_get_title(Image1, Title); if (strcmp(Title, "") == 0) strcpy(Title, Name1); } else { Data1 = (BYTE_TYPE **) im_alloc2D(Image1, BYTE); im_read(Image1, BYTE, (char *) &(Data1[0][0])); im_get_title(Image1, Title); if (strcmp(Title, "") == 0) strcpy(Title, Name1); /* Scale input image to 0..255 if needed */ Min = Max = Data1[0][0]; for (y = 0; y < Ydim; y++) for (x = 0; x < Xdim; x++) if (Min > Data1[y][x]) Min = Data1[y][x]; else if (Max < Data1[y][x]) Max = Data1[y][x]; if (Max > Min) Scale = (float) (255.0 / (Max - Min)); else Scale = 1.0; for (y = 0; y < Ydim; y++) for (x = 0; x < Xdim; x++) Data1[y][x] = (BYTE_TYPE) ROUND((Data1[y][x] - Min) * Scale); } } /* Open output file */ if (strcmp(Name2, "") == 0) fd = stdout; else if ((fd = fopen(Name2, "w")) == NULL) Error("Can not open output file"); /* Convert image to postscript */ if ((PixType == PSEUDO) || (PixType == COLOR) || (PixType == JPEG_RGB)) ColorPS(); else GreyPS(); im_free2D((char **) Data1); fclose(fd); return (0); }