home *** CD-ROM | disk | FTP | other *** search
- From: matthew@sunpix.East.Sun.COM (Matthew Stier - Sun Visualization Products)
- Newsgroups: alt.sources
- Subject: Vue, a Sunview rasterfile viewer
- Message-ID: <536@sunpix.East.Sun.COM>
- Date: 4 Mar 91 17:19:38 GMT
-
-
- Vue is a Sunview tool to display images in a scrollable Sunview window.
- Vue can be used with or without a filter. Without a filter vue can be
- used to display ordinary rasterfiles. With a user supplied filter, vue
- can display whatever filetype the supplied filter works with.
-
- Enclosed in the following shar, is the filter 'gif2ras'. 'Vue' used
- with the filter 'gif2ras' makes a handy Sunview GIF viewer. Using
- 'zcat' as s filter, 'Vue' can display compressed rasterfiles, with
- pre-decompression.
-
- ---- Cut Here and unpack ----
- #!/bin/sh
- # shar: Shell Archiver (v1.25)
- # Packed Mon Mar 4 11:49:47 EST 1991 by taac-box!matthew
- # from directory /home/matthew/.bin/src/Sunview/Vue
- #
- # Run the following text with /bin/sh to create:
- # Makefile
- # hglass.cursor
- # vue.c
- # vue.h
- # vue.icon
- # vue.man
- # gif2ras.c
- # gif2ras.man
- #
- if test -f Makefile; then echo "File Makefile exists"; else
- echo "x - extracting Makefile (Text)"
- sed 's/^X//' << 'SHAR_EOF' > Makefile &&
- XEXEC = vue gif2ras
- XCFLAGS = -O
- XLDFLAGS = -s
- XLDLIBS = -lsuntool -lsunwindow -lpixrect
- X
- Xexec: $(EXEC)
- X
- Xlint:
- X $(LINT) $(EXEC:=.c) $(LDLIBS)
- X
- Xclean:
- X $(RM) a.out core *.o
- X
- Xrealclean: clean
- X $(RM) $(EXEC)
- X
- SHAR_EOF
- chmod 0777 Makefile || echo "restore of Makefile fails"
- fi
- if test -f hglass.cursor; then echo "File hglass.cursor exists"; else
- echo "x - extracting hglass.cursor (Text)"
- sed 's/^X//' << 'SHAR_EOF' > hglass.cursor &&
- X/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16
- X */
- X 0x7FFE,0x4002,0x200C,0x1A38,0x0FF0,0x07E0,0x03C0,0x0180,
- X 0x0180,0x0240,0x0520,0x0810,0x1108,0x23C4,0x47E2,0x7FFE
- SHAR_EOF
- chmod 0644 hglass.cursor || echo "restore of hglass.cursor fails"
- fi
- if test -f vue.c; then echo "File vue.c exists"; else
- echo "x - extracting vue.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > vue.c &&
- X/*
- Xstatic char rcsID[] = "$Header: cshow.c,v 1.4 87/08/14 13:16:08 david Exp $";
- X */
- X
- X/* Define general items */
- X#define PROGRAMNAME "vue"
- X#define ICON "vue.icon"
- X#define CURSOR "hglass.cursor"
- X#define DEFAULT_LABEL "(hit right mouse button for menu)"
- X
- X/* Get #include */
- X#include <stdio.h>
- X#include <malloc.h>
- X#include <strings.h>
- X#include <sys/param.h>
- X#include <suntool/sunview.h>
- X#include <suntool/canvas.h>
- X#include <suntool/panel.h>
- X#include <suntool/scrollbar.h>
- X#include <suntool/expand_name.h>
- X#include <sunwindow/cms_mono.h>
- X#include "vue.h"
- X
- X/* Load the icon */
- Xstatic short icon_image[] = {
- X#include ICON
- X};
- Xmpr_static(icon_pixrect, 64, 64, 1, icon_image);
- X
- X/* Load the hour_glass cursor */
- Xstatic short cursor_image[] = {
- X#include CURSOR
- X};
- Xmpr_static(cursor_pixrect, 16, 16, 1, cursor_image);
- X
- X/* Define functions */
- Xint main();
- Xvoid frame_event();
- Xint show();
- Xvoid canvas_repaint();
- Xvoid update_canvas_menu();
- Xvoid set_frame_label();
- Xchar *basename();
- Xvoid create_control_panel();
- Xvoid control_panel_proc();
- Xvoid control_panel_done();
- Xvoid selection_update();
- Xvoid filter_update();
- XPixrect *load_pixrect();
- XPixrect *convert8to1();
- XPixrect *convert32to1();
- XPixrect *convert32to8();
- XPixrect *convert8to32();
- Xvoid init_colormap32();
- X
- X/* Define variables */
- Xstatic Icon icon;
- Xstatic Cursor hglass_cursor;
- Xstatic Frame frame;
- Xstatic Frame control_frame;
- Xstatic Canvas canvas;
- Xstatic Pixwin *pw;
- Xstatic Pixrect *pr = 0;
- Xstatic Menu canvas_menu = 0;
- Xstatic Panel control_panel;
- Xstatic Panel_item fname_item;
- Xstatic Panel_item filter_item;
- Xstatic Panel_item order_item;
- Xstatic int where = 0;
- Xstatic int skip = 0;
- Xstatic int nitems;
- Xstatic int max_depth;
- Xstatic char directory[MAXPATHLEN];
- Xstatic char *programname = PROGRAMNAME;
- Xstatic char *filter = "";
- Xstatic char current_image[MAXPATHLEN + 256];
- Xstatic char **filename = 0;
- Xstruct namelist *name_list;
- X
- X/* Define constants */
- X#define ERROR_PAUSE 2
- X#define ESCAPE_KEY '\033'
- X
- Xint
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int getpid();
- X char *getwd();
- X char *sprintf();
- X
- X /* Set 'programname' */
- X if ( argc && *basename(argv[0]) != '\0')
- X programname = basename(argv[0]);
- X
- X /* Search command line for options */
- X while (argc > 1 && argv[1][0] == '-') {
- X switch (argv[1][1]) {
- X case 'f': /* If filter specified, get filter name */
- X if ( argv[1][2] ) {
- X filter = &argv[1][2];
- X } else {
- X if ( argc > 2 ) {
- X filter = argv[2];
- X argc--;
- X argv++;
- X }
- X }
- X break;
- X default: /* invalid option, complain */
- X (void) fprintf(stderr,
- X "Usage: %s [-f filter] [file]....\n",
- X programname);
- X return(1);
- X }
- X argc--;
- X argv++;
- X }
- X
- X /* Set default fname_item for control panel */
- X if (argc > 1 && basename(argv[1]) != argv[1]) {
- X (void) strcpy(directory, argv[1]);
- X (void) strcpy(basename(directory), "*");
- X } else {
- X (void) getwd(directory);
- X (void) strcat(directory, "/*");
- X }
- X
- X /* Create the icon */
- X icon = icon_create(ICON_IMAGE, &icon_pixrect,
- X ICON_LABEL, 0,
- X ICON_WIDTH, icon_pixrect.pr_size.x,
- X ICON_HEIGHT, icon_pixrect.pr_size.y,
- X 0);
- X
- X /* Create the hourglass cursor */
- X hglass_cursor = cursor_create(CURSOR_IMAGE, &cursor_pixrect, 0);
- X
- X /* Create the frame */
- X frame = window_create((Window) 0, FRAME,
- X FRAME_ARGC_PTR_ARGV, &argc, argv,
- X FRAME_ICON, icon,
- X FRAME_PROPS_ACTIVE, TRUE,
- X FRAME_PROPS_ACTION_PROC, control_panel_proc,
- X WIN_ERROR_MSG, "Couldn't create frame",
- X 0);
- X
- X /* Exit program if unable to create frame */
- X if (frame == 0)
- X return(1);
- X
- X /* Set frame label to default label */
- X (void) strcpy(current_image, DEFAULT_LABEL);
- X set_frame_label("%s: %s", current_image);
- X
- X /* Create the canvas */
- X canvas = window_create(frame, CANVAS,
- X CANVAS_AUTO_EXPAND, FALSE,
- X CANVAS_AUTO_SHRINK, FALSE,
- X CANVAS_AUTO_CLEAR, FALSE,
- X CANVAS_RETAINED, FALSE,
- X CANVAS_REPAINT_PROC, canvas_repaint,
- X WIN_EVENT_PROC, frame_event,
- X WIN_CONSUME_KBD_EVENT, WIN_ASCII_EVENTS,
- X WIN_ERROR_MSG, "Couldn't create canvas",
- X WIN_HORIZONTAL_SCROLLBAR, scrollbar_create(SCROLL_LINE_HEIGHT, 1, 0),
- X WIN_VERTICAL_SCROLLBAR, scrollbar_create(SCROLL_LINE_HEIGHT, 1, 0),
- X 0);
- X
- X /* Exit program if unable to create canvas */
- X if (canvas == 0)
- X return(1);
- X
- X /* Get the pixwin for the canvas */
- X pw = canvas_pixwin(canvas);
- X
- X /* determine max depth of the pixwin */
- X max_depth = pw->pw_pixrect->pr_depth;
- X
- X#ifdef CANVAS_COLOR24 /* If CANVAS_COLOR24 not declared, its not supported */
- X /* Set 24-bit color mode if the frame buffer is deep enough */
- X if (max_depth == 24 || max_depth == 32)
- X window_set(canvas, CANVAS_COLOR24, TRUE, 0);
- X#endif /* CANVAS_COLOR24 */
- X
- X /* Create a control panel */
- X create_control_panel();
- X
- X /* Create a selection menu from the remaining items */
- X update_canvas_menu(--argc, ++argv);
- X
- X /* Start main program loop */
- X (void) window_main_loop(frame);
- X
- X /* Exit program successfully */
- X return(0);
- X}
- X
- Xvoid
- Xframe_event(window, event, arg)
- X Window window;
- X Event *event;
- X caddr_t arg;
- X{
- X int item;
- X
- X /* If a mouse button is pressed inside the canvas, do its action */
- X if (event_is_button(event) && event_is_down(event)) {
- X switch(event_action(event)) {
- X case MS_LEFT: /* Goto previous image */
- X skip = (skip > 0 ? -1 : skip - 1);
- X item = (where ? where + skip : 1 + skip);
- X item += (item < 1 ? nitems : 0);
- X break;
- X case MS_MIDDLE: /* Goto next image */
- X skip = (skip < 0 ? 1 : skip + 1);
- X item = where + skip;
- X item -= (item > nitems ? nitems : 0);
- X break;
- X case MS_RIGHT: /* Got to selected image */
- X item = (int) menu_show(canvas_menu, canvas,
- X canvas_window_event(canvas, event), 0);
- X skip = 0;
- X break;
- X default:
- X break;
- X }
- X
- X /* If it is a valid 'item', load the file */
- X if (item > 0 && item <= nitems && item != where ) {
- X /* Announce you are loading a new image */
- X set_frame_label("%s: %s (Loading)", filename[item - 1]);
- X /* Show new file */
- X if (show(filename[item - 1])) {
- X /* Set "where" pointer to image being shown */
- X where = item;
- X /* Zero out the skip_image counter */
- X skip = 0;
- X /* Syncronize MS_RIGHT menu to image being shown */
- X (void) menu_set(canvas_menu, MENU_SELECTED, item, 0);
- X /* Create new title bar */
- X (void) sprintf(current_image, "%s (%d x %d x %d)",
- X filename[item - 1],
- X pr->pr_size.x, pr->pr_size.y, pr->pr_depth);
- X } else {
- X /* Report problem loading image */
- X set_frame_label("%s: Error loading '%s'", filename[item - 1]);
- X /* Pause so people can read it */
- X sleep(ERROR_PAUSE);
- X }
- X /* Update the frame label */
- X set_frame_label("%s: %s", current_image);
- X }
- X } else {
- X /* if the escape key is pressed, open the control panel */
- X if (event_action(event) == ESCAPE_KEY)
- X control_panel_proc();
- X /* handle all other canvas events */
- X (void) window_default_event_proc(window, event, arg);
- X }
- X}
- X
- Xint
- Xshow(name)
- X char *name;
- X{
- X /* Define functions */
- X char *sprintf();
- X
- X /* Define local variables */
- X Cursor current_cursor;
- X char cmsname[CMS_NAMESIZE];
- X colormap_t cm;
- X Pixrect *new_pr = 0;
- X
- X /* Get the current cursor */
- X current_cursor = (Cursor) window_get(canvas,WIN_CURSOR);
- X
- X /* Change cursor to hour glass */
- X (void) window_set(canvas,WIN_CURSOR,hglass_cursor,0);
- X
- X /* Load image into pixrect */
- X new_pr = load_pixrect(name, &cm);
- X
- X /* If an error in reading the file, return cursor to normal and return */
- X if (!new_pr) {
- X (void) window_set(canvas, WIN_CURSOR, current_cursor, 0);
- X return (0);
- X }
- X
- X /* Check pixrect depth against canvas depth, process where necessary */
- X switch (max_depth) {
- X case 1:
- X switch (new_pr->pr_depth) {
- X case 1:
- X break;
- X case 8:
- X new_pr = convert8to1(new_pr, &cm);
- X break;
- X case 32:
- X new_pr = convert32to1(new_pr, &cm);
- X break;
- X default:
- X pr_destroy(new_pr);
- X new_pr = (Pixrect *) 0;
- X break;
- X }
- X break;
- X case 8:
- X switch (new_pr->pr_depth) {
- X case 1:
- X break;
- X case 8:
- X break;
- X case 32:
- X new_pr = convert32to8(new_pr, &cm);
- X break;
- X default:
- X pr_destroy(new_pr);
- X new_pr = (Pixrect *) 0;
- X break;
- X }
- X break;
- X case 24:
- X switch (new_pr->pr_depth) {
- X case 1:
- X pr_destroy(new_pr);
- X new_pr = (Pixrect *) 0;
- X break;
- X case 8:
- X pr_destroy(new_pr);
- X new_pr = (Pixrect *) 0;
- X break;
- X case 32:
- X pr_destroy(new_pr);
- X new_pr = (Pixrect *) 0;
- X break;
- X default:
- X pr_destroy(new_pr);
- X new_pr = (Pixrect *) 0;
- X break;
- X }
- X break;
- X case 32:
- X switch (new_pr->pr_depth) {
- X case 1:
- X break;
- X case 8:
- X new_pr = convert8to32(new_pr, &cm);
- X break;
- X case 32:
- X break;
- X default:
- X pr_destroy(new_pr);
- X new_pr = (Pixrect *) 0;
- X break;
- X }
- X break;
- X default:
- X pr_destroy(new_pr);
- X new_pr = (Pixrect *) 0;
- X break;
- X }
- X
- X /* If an error in converting the file, return cursor to normal and return */
- X if (!new_pr) {
- X (void) window_set(canvas, WIN_CURSOR, current_cursor, 0);
- X return (0);
- X }
- X
- X /* Set colormaps */
- X switch (new_pr->pr_depth) {
- X case 1:
- X (void) pw_setcmsname(pw, CMS_MONOCHROME);
- X break;
- X case 8:
- X switch (cm.type) {
- X case RMT_EQUAL_RGB:
- X (void) sprintf(cmsname, "rs-%05d-%03d",
- X getpid(), cm.length);
- X (void) pw_setcmsname(pw, cmsname);
- X (void) pw_putcolormap(pw, 0, cm.length,
- X cm.map[0], cm.map[1], cm.map[2]);
- X break;
- X default:
- X break;
- X }
- X case 32:
- X break;
- X default:
- X break;
- X }
- X
- X /* Blank the canvas */
- X (void) pw_writebackground(pw, 0, 0,
- X pw->pw_pixrect->pr_size.x, pw->pw_pixrect->pr_size.y, PIX_SRC);
- X
- X /* Resize the new canvas */
- X (void) window_set(canvas,
- X CANVAS_WIDTH, new_pr->pr_size.x,
- X CANVAS_HEIGHT, new_pr->pr_size.y,
- X 0);
- X
- X /* Write the image to the canvas */
- X (void) pw_write(pw, 0, 0,
- X new_pr->pr_size.x, new_pr->pr_size.y, PIX_SRC, new_pr, 0, 0);
- X
- X /* All finished. Clean up and return success */
- X if (pr)
- X pr_destroy(pr);
- X pr = new_pr;
- X (void) window_set(canvas, WIN_CURSOR, current_cursor, 0);
- X return(1);
- X}
- X
- X/*ARGSUSED*/
- Xvoid
- Xcanvas_repaint(canvas, pw, area)
- XCanvas canvas;
- XPixwin *pw;
- XRectlist *area;
- X{
- X if (pr) {
- X /* Repaint the image */
- X (void) pw_write(pw, 0, 0,
- X pr->pr_size.x, pr->pr_size.y, PIX_SRC, pr, 0, 0);
- X } else {
- X /* Blank the canvas */
- X (void) pw_writebackground(pw, 0, 0,
- X pw->pw_pixrect->pr_size.x, pw->pw_pixrect->pr_size.y, PIX_SRC);
- X }
- X}
- X
- Xvoid
- Xupdate_canvas_menu(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X int index;
- X
- X /* Destroy the old menu */
- X if (canvas_menu != 0)
- X menu_destroy(canvas_menu);
- X
- X /* Create a new one */
- X canvas_menu = menu_create(0);
- X
- X /* and fill it in */
- X for (index = 0; index < argc; index++)
- X (void) menu_set(canvas_menu, MENU_STRING_ITEM,
- X argv[index], index + 1, 0);
- X
- X /* and set some variables for frame_event() */
- X skip =0;
- X where = 0;
- X nitems = argc;
- X filename = argv;
- X}
- X
- Xvoid
- Xset_frame_label(format, filename)
- Xchar *format;
- Xchar *filename;
- X{
- X char *sprintf();
- X char *title[MAXPATHLEN];
- X
- X /* create the label */
- X (void) sprintf(title, format, programname, filename);
- X /* send it to the frame */
- X (void) window_set(frame, FRAME_LABEL, title, 0);
- X}
- X
- Xchar *
- Xbasename(pn)
- Xchar *pn; /* pointer to pathname */
- X{
- X char *sp; /* search pointer */
- X
- X /* set search pointer to the start of pathname */
- X sp = pn;
- X
- X /* search pathname for last delimeter */
- X while ( *sp != '\0' ) {
- X if ( *sp++ == '/' )
- X pn = sp;
- X }
- X
- X /* return the basename */
- X return(pn);
- X}
- X
- Xvoid
- Xcreate_control_panel()
- X{
- X
- X control_frame = window_create(frame, FRAME,
- X FRAME_LABEL, programname,
- X FRAME_SHOW_LABEL, TRUE,
- X WIN_SHOW, FALSE,
- X 0);
- X
- X control_panel = window_create(control_frame, PANEL, 0);
- X
- X fname_item = panel_create_item(control_panel, PANEL_TEXT,
- X PANEL_LABEL_Y, ATTR_ROW(0),
- X PANEL_LABEL_X, ATTR_COL(0),
- X PANEL_VALUE_DISPLAY_LENGTH, 32,
- X PANEL_LABEL_STRING, "File: ",
- X PANEL_VALUE, directory,
- X 0);
- X
- X (void) panel_create_item(control_panel, PANEL_BUTTON,
- X PANEL_LABEL_X, ATTR_COL(42),
- X PANEL_LABEL_IMAGE, panel_button_image(control_panel,
- X "Update Menu", 15, (Pixfont *) 0),
- X PANEL_NOTIFY_PROC, selection_update,
- X 0);
- X
- X filter_item = panel_create_item(control_panel, PANEL_TEXT,
- X PANEL_LABEL_Y, ATTR_ROW(1),
- X PANEL_LABEL_X, ATTR_COL(0),
- X PANEL_VALUE_DISPLAY_LENGTH, 32,
- X PANEL_LABEL_STRING, "Filter:",
- X PANEL_VALUE, filter,
- X 0);
- X
- X (void) panel_create_item(control_panel, PANEL_BUTTON,
- X PANEL_LABEL_X, ATTR_COL(42),
- X PANEL_LABEL_IMAGE, panel_button_image(control_panel,
- X "Update filter", 15, (Pixfont *) 0),
- X PANEL_NOTIFY_PROC, filter_update,
- X 0);
- X
- X order_item = panel_create_item(control_panel, PANEL_CYCLE,
- X PANEL_LABEL_Y, ATTR_ROW(2),
- X PANEL_LABEL_X, ATTR_COL(0),
- X PANEL_LABEL_STRING, "Color ordering:",
- X PANEL_CHOICE_STRINGS, "rgb", "bgr", 0,
- X 0);
- X
- X (void) panel_create_item(control_panel, PANEL_BUTTON,
- X PANEL_LABEL_X, ATTR_COL(42),
- X PANEL_LABEL_IMAGE, panel_button_image(control_panel,
- X "Done", 15, (Pixfont *) 0),
- X PANEL_NOTIFY_PROC, control_panel_done,
- X 0);
- X
- X (void) window_set(control_panel, PANEL_CARET_ITEM, fname_item, 0);
- X
- X (void) window_fit(control_panel);
- X (void) window_fit(control_frame);
- X
- X}
- X
- Xvoid
- Xcontrol_panel_proc()
- X{
- X window_set(control_frame,
- X WIN_X, 50,
- X WIN_Y, 50,
- X WIN_SHOW, TRUE,
- X 0);
- X}
- X
- Xvoid
- Xcontrol_panel_done()
- X{
- X window_set(control_frame, WIN_SHOW, FALSE, 0);
- X}
- X
- Xvoid
- Xselection_update()
- X{
- X static char previous_dir[MAXPATHLEN];
- X char current_dir[MAXPATHLEN];
- X char fname[MAXPATHLEN];
- X
- X /* Get a copy of fname_item */
- X (void) strcpy(current_dir, panel_get_value(fname_item));
- X (void) strcpy(fname, current_dir);
- X
- X /* Truncate current_dir to the directory component */
- X (void) strcpy(basename(current_dir), "");
- X
- X /* Truncate fname to filename only */
- X /* If no filename specified, assume wildcard of '*' */
- X if (!strlen(basename(fname))) {
- X (void) strcat(fname, "*");
- X (void) panel_set_value(fname_item, (caddr_t) fname);
- X }
- X
- X /* Change directories to match fname_item */
- X if (strcmp(previous_dir, current_dir)) {
- X (void) chdir(current_dir);
- X (void) strcpy(previous_dir, current_dir);
- X }
- X
- X /* Convert filename to list of files */
- X name_list = expand_name(basename(fname));
- X
- X /* Convert the expanded filename to a canvas menu */
- X update_canvas_menu((int) name_list->count, name_list->names);
- X}
- X
- Xvoid
- Xfilter_update()
- X{
- X /* Get the filter_item value from the control panel */
- X filter = (char *) panel_get_value(filter_item);
- X
- X /* Skip leading whitespace */
- X while ( *filter == ' ' || *filter == '\t' )
- X filter++;
- X}
- X
- XPixrect *
- Xload_pixrect(name, cm)
- Xchar *name;
- Xcolormap_t *cm;
- X{
- X FILE *inf;
- X Pixrect *tpr;
- X char *cmd;
- X char *cmdfmt = "(%s) < %s";
- X
- X /* Load image into pixrect */
- X if (*filter) {
- X /* Allocate enough space to create commandline */
- X cmd = (char *) malloc((unsigned)
- X (strlen(cmdfmt) + strlen(filter) + strlen(name)));
- X /* Verify allocation of commandline space */
- X if (cmd) {
- X /* Load image by piping the file thru a filter */
- X (void) sprintf(cmd, cmdfmt, filter, name);
- X if (!(inf = popen(cmd, "r")))
- X return((Pixrect *) 0);
- X tpr = pr_load(inf, cm);
- X if (pclose(inf))
- X tpr = (Pixrect *) 0;
- X (void) free(cmd);
- X } else {
- X (void) fprintf(stderr,
- X "Error allocating space for filter commandline");
- X }
- X } else {
- X if (!(inf = fopen(name, "r")))
- X return((Pixrect *) 0);
- X tpr = pr_load(inf, cm);
- X if (fclose(inf))
- X tpr = (Pixrect *) 0;
- X }
- X
- X /* And return */
- X return(tpr);
- X}
- X
- XPixrect *
- Xconvert8to1(pr8, cm)
- XPixrect *pr8;
- Xcolormap_t *cm;
- X{
- X /* Define function variables */
- X Pixrect *pr1;
- X unsigned char *cm1 = 0;
- X int x, y, pixel8, pixel1;
- X unsigned long avg = 0;
- X
- X /* Create an 1-bit pixrect */
- X pr1 = mem_create(pr8->pr_size.x, pr8->pr_size.y, 1);
- X
- X /* Verify creation of mem_rect */
- X if (!pr1) {
- X pr_destroy(pr8);
- X return((Pixrect *) 0);
- X }
- X
- X /* Convert the 8-bit pixrect to an 1-bit pixrect */
- X for (y = 0; y < pr8->pr_size.y; y++) {
- X for (x = 0; x < pr8->pr_size.x; x++) {
- X pixel8 = pr_get(pr8, x, y);
- X pixel1 = (ntscr[cm->map[0][pixel8]] +
- X ntscg[cm->map[1][pixel8]] +
- X ntscb[cm->map[2][pixel8]])/256;
- X pixel1 = pixel1 <= dither_table[y%16][x%16];
- X pr_put(pr1, x, y, pixel1);
- X }
- X }
- X
- X /* Destroy the old pixrect, and return the new */
- X pr_destroy(pr8);
- X return(pr1);
- X}
- X
- XPixrect *
- Xconvert32to1(pr32, cm)
- XPixrect *pr32;
- Xcolormap_t *cm;
- X{
- X /* Define function variables */
- X Pixrect *pr1;
- X unsigned char *cm1 = 0;
- X int x, y, blu_shift, grn_shift, red_shift, pixel32, pixel1;
- X
- X /* Create an 1-bit pixrect */
- X pr1 = mem_create(pr32->pr_size.x, pr32->pr_size.y, 1);
- X
- X /* Verify creation of mem_rect */
- X if (!pr1) {
- X pr_destroy(pr32);
- X return((Pixrect *) 0);
- X }
- X
- X /* Set pixel shift value in accordance with the panel selection */
- X switch ((int) panel_get_value(order_item)) {
- X case 0: /* rgb */
- X blu_shift = 0;
- X grn_shift = 8;
- X red_shift = 16;
- X break;
- X case 1: /* bgr */
- X blu_shift = 16;
- X grn_shift = 8;
- X red_shift = 0;
- X break;
- X default: /* rgb */
- X blu_shift = 0;
- X grn_shift = 8;
- X red_shift = 16;
- X break;
- X }
- X
- X /* Convert the 32-bit pixrect to an 1-bit pixrect */
- X for (y = 0; y < pr32->pr_size.y; y++) {
- X for (x = 0; x < pr32->pr_size.x; x++) {
- X pixel32 = pr_get(pr32, x, y);
- X pixel1 = (ntscb[((pixel32 >> blu_shift) & 0xff)] +
- X ntscg[((pixel32 >> grn_shift) & 0xff)] +
- X ntscr[((pixel32 >> red_shift) & 0xff)])/256;
- X pixel1 = pixel1 <= dither_table[y%16][x%16];
- X pr_put(pr1, x, y, pixel1);
- X }
- X }
- X
- X /* Destroy the old pixrect, and return the new */
- X pr_destroy(pr32);
- X return(pr1);
- X}
- X
- XPixrect *
- Xconvert32to8(pr32, cm)
- XPixrect *pr32;
- Xcolormap_t *cm;
- X{
- X
- X#undef CM_SIZE
- X#define CM_SIZE 256
- X#define MAX_BLU 4
- X#define BLU_STEP 85
- X#define MAX_GRN 8
- X#define GRN_STEP 36
- X#define MAX_RED 8
- X#define RED_STEP 36
- X
- X /* Define function variables */
- X int blu_index, grn_index, red_index, cm_index = 0;
- X Pixrect *pr8 = 0;
- X unsigned char *cm8 = 0;
- X int x, y, pixel32, pixel8;
- X int order, blu_shift, grn_shift, red_shift;
- X
- X /* Get the space for a colormap */
- X cm8 = (unsigned char *) malloc(CM_SIZE * 3);
- X
- X /* Verify allocation of colormap space */
- X if (!cm) {
- X pr_destroy(pr32);
- X return((Pixrect *) 0);
- X }
- X
- X /* Create a colormap table */
- X cm->type = RMT_EQUAL_RGB;
- X cm->length = CM_SIZE;
- X cm->map[0] = cm8;
- X cm->map[1] = cm->map[0] + CM_SIZE;
- X cm->map[2] = cm->map[1] + CM_SIZE;
- X
- X /* Fill-in the colormap */
- X for (blu_index = 0; blu_index < MAX_BLU; blu_index++) {
- X for (grn_index = 0; grn_index < MAX_GRN; grn_index++) {
- X for (red_index = 0; red_index < MAX_RED; red_index++) {
- X cm->map[0][cm_index] = red_index * RED_STEP;
- X cm->map[1][cm_index] = grn_index * GRN_STEP;
- X cm->map[2][cm_index] = blu_index * BLU_STEP;
- X cm_index++;
- X }
- X }
- X }
- X
- X /* Create an 8-bit pixrect */
- X pr8 = mem_create(pr32->pr_size.x, pr32->pr_size.y, 8);
- X
- X /* Verify creation of mem_rect */
- X if (!pr8) {
- X pr_destroy(pr32);
- X return((Pixrect *) 0);
- X }
- X
- X /* Set pixel shift value in accordance with the panel selection */
- X switch ((int) panel_get_value(order_item)) {
- X case 0: /* rgb */
- X blu_shift = 0;
- X grn_shift = 10;
- X red_shift = 21;
- X break;
- X case 1: /* bgr */
- X blu_shift = 16;
- X grn_shift = 10;
- X red_shift = 5;
- X break;
- X default: /* rgb */
- X blu_shift = 0;
- X grn_shift = 10;
- X red_shift = 21;
- X break;
- X }
- X
- X /* Convert the 32-bit pixrect to an 8-bit pixrect */
- X for (y = 0; y < pr32->pr_size.y; y++) {
- X for (x = 0; x < pr32->pr_size.x; x++) {
- X pixel32 = pr_get(pr32, x, y);
- X pixel8 = ((pixel32 >> blu_shift) & 0xc0) |
- X ((pixel32 >> grn_shift) & 0x38) |
- X ((pixel32 >> red_shift) & 0x07);
- X pr_put(pr8, x, y, pixel8);
- X }
- X }
- X /* Destroy the old pixrect, and return the new */
- X pr_destroy(pr32);
- X return(pr8);
- X}
- X
- XPixrect *
- Xconvert8to32(pr8, cm)
- XPixrect *pr8;
- Xcolormap_t *cm;
- X{
- X /* Define function variables */
- X Pixrect *pr32 = 0;
- X int x, y, pixel32, pixel8;
- X int order, blu_shift, grn_shift, red_shift;
- X
- X /* Create an 32-bit pixrect */
- X pr32 = mem_create(pr8->pr_size.x, pr8->pr_size.y, 32);
- X
- X /* Verify creation of mem_rect */
- X if (!pr32) {
- X pr_destroy(pr8);
- X return((Pixrect *) 0);
- X }
- X
- X /* Set pixel shift value in accordance with the panel selection */
- X switch ((int) panel_get_value(order_item)) {
- X case 0: /* rgb */
- X blu_shift = 0;
- X grn_shift = 8;
- X red_shift = 16;
- X break;
- X case 1: /* bgr */
- X blu_shift = 16;
- X grn_shift = 8;
- X red_shift = 0;
- X break;
- X default: /* rgb */
- X blu_shift = 0;
- X grn_shift = 8;
- X red_shift = 16;
- X break;
- X }
- X
- X /* Convert the 8-bit pixrect to an 32-bit pixrect */
- X for (y = 0; y < pr8->pr_size.y; y++) {
- X for (x = 0; x < pr8->pr_size.x; x++) {
- X pixel8 = pr_get(pr8, x, y);
- X pixel32 = cm->map[2][pixel8] << blu_shift |
- X cm->map[1][pixel8] << grn_shift |
- X cm->map[0][pixel8] << red_shift;
- X pr_put(pr32, x, y, pixel32);
- X }
- X }
- X /* Destroy the old pixrect, and return the new */
- X pr_destroy(pr8);
- X return(pr32);
- X}
- X
- SHAR_EOF
- chmod 0777 vue.c || echo "restore of vue.c fails"
- fi
- if test -f vue.h; then echo "File vue.h exists"; else
- echo "x - extracting vue.h (Text)"
- sed 's/^X//' << 'SHAR_EOF' > vue.h &&
- Xstatic unsigned int ntscr[] = {
- X 0, 77, 153, 230, 306, 383, 459, 536,
- X 612, 689, 765, 842, 919, 995, 1072, 1148,
- X 1225, 1301, 1378, 1454, 1531, 1607, 1684, 1761,
- X 1837, 1914, 1990, 2067, 2143, 2220, 2296, 2373,
- X 2449, 2526, 2602, 2679, 2756, 2832, 2909, 2985,
- X 3062, 3138, 3215, 3291, 3368, 3444, 3521, 3598,
- X 3674, 3751, 3827, 3904, 3980, 4057, 4133, 4210,
- X 4286, 4363, 4440, 4516, 4593, 4669, 4746, 4822,
- X 4899, 4975, 5052, 5128, 5205, 5282, 5358, 5435,
- X 5511, 5588, 5664, 5741, 5817, 5894, 5970, 6047,
- X 6124, 6200, 6277, 6353, 6430, 6506, 6583, 6659,
- X 6736, 6812, 6889, 6966, 7042, 7119, 7195, 7272,
- X 7348, 7425, 7501, 7578, 7654, 7731, 7807, 7884,
- X 7961, 8037, 8114, 8190, 8267, 8343, 8420, 8496,
- X 8573, 8649, 8726, 8803, 8879, 8956, 9032, 9109,
- X 9185, 9262, 9338, 9415, 9491, 9568, 9645, 9721,
- X 9798, 9874, 9951,10027,10104,10180,10257,10333,
- X 10410,10487,10563,10640,10716,10793,10869,10946,
- X 11022,11099,11175,11252,11329,11405,11482,11558,
- X 11635,11711,11788,11864,11941,12017,12094,12170,
- X 12247,12324,12400,12477,12553,12630,12706,12783,
- X 12859,12936,13012,13089,13166,13242,13319,13395,
- X 13472,13548,13625,13701,13778,13854,13931,14008,
- X 14084,14161,14237,14314,14390,14467,14543,14620,
- X 14696,14773,14850,14926,15003,15079,15156,15232,
- X 15309,15385,15462,15538,15615,15692,15768,15845,
- X 15921,15998,16074,16151,16227,16304,16380,16457,
- X 16534,16610,16687,16763,16840,16916,16993,17069,
- X 17146,17222,17299,17375,17452,17529,17605,17682,
- X 17758,17835,17911,17988,18064,18141,18217,18294,
- X 18371,18447,18524,18600,18677,18753,18830,18906,
- X 18983,19059,19136,19213,19289,19366,19442,19519};
- X
- Xstatic unsigned int ntscg[] = {
- X 0, 150, 301, 451, 601, 751, 902, 1052,
- X 1202, 1352, 1503, 1653, 1803, 1954, 2104, 2254,
- X 2404, 2555, 2705, 2855, 3005, 3156, 3306, 3456,
- X 3607, 3757, 3907, 4057, 4208, 4358, 4508, 4658,
- X 4809, 4959, 5109, 5260, 5410, 5560, 5710, 5861,
- X 6011, 6161, 6311, 6462, 6612, 6762, 6913, 7063,
- X 7213, 7363, 7514, 7664, 7814, 7964, 8115, 8265,
- X 8415, 8566, 8716, 8866, 9016, 9167, 9317, 9467,
- X 9617, 9768, 9918,10068,10218,10369,10519,10669,
- X 10820,10970,11120,11270,11421,11571,11721,11871,
- X 12022,12172,12322,12473,12623,12773,12923,13074,
- X 13224,13374,13524,13675,13825,13975,14126,14276,
- X 14426,14576,14727,14877,15027,15177,15328,15478,
- X 15628,15779,15929,16079,16229,16380,16530,16680,
- X 16830,16981,17131,17281,17432,17582,17732,17882,
- X 18033,18183,18333,18483,18634,18784,18934,19085,
- X 19235,19385,19535,19686,19836,19986,20136,20287,
- X 20437,20587,20738,20888,21038,21188,21339,21489,
- X 21639,21789,21940,22090,22240,22391,22541,22691,
- X 22841,22992,23142,23292,23442,23593,23743,23893,
- X 24044,24194,24344,24494,24645,24795,24945,25095,
- X 25246,25396,25546,25697,25847,25997,26147,26298,
- X 26448,26598,26748,26899,27049,27199,27350,27500,
- X 27650,27800,27951,28101,28251,28401,28552,28702,
- X 28852,29002,29153,29303,29453,29604,29754,29904,
- X 30054,30205,30355,30505,30655,30806,30956,31106,
- X 31257,31407,31557,31707,31858,32008,32158,32308,
- X 32459,32609,32759,32910,33060,33210,33360,33511,
- X 33661,33811,33961,34112,34262,34412,34563,34713,
- X 34863,35013,35164,35314,35464,35614,35765,35915,
- X 36065,36216,36366,36516,36666,36817,36967,37117,
- X 37267,37418,37568,37718,37869,38019,38169,38319};
- X
- Xstatic unsigned int ntscb[] = {
- X 0, 29, 58, 88, 117, 146, 175, 204,
- X 233, 263, 292, 321, 350, 379, 409, 438,
- X 467, 496, 525, 554, 584, 613, 642, 671,
- X 700, 730, 759, 788, 817, 846, 876, 905,
- X 934, 963, 992, 1021, 1051, 1080, 1109, 1138,
- X 1167, 1197, 1226, 1255, 1284, 1313, 1342, 1372,
- X 1401, 1430, 1459, 1488, 1518, 1547, 1576, 1605,
- X 1634, 1663, 1693, 1722, 1751, 1780, 1809, 1839,
- X 1868, 1897, 1926, 1955, 1985, 2014, 2043, 2072,
- X 2101, 2130, 2160, 2189, 2218, 2247, 2276, 2306,
- X 2335, 2364, 2393, 2422, 2451, 2481, 2510, 2539,
- X 2568, 2597, 2627, 2656, 2685, 2714, 2743, 2772,
- X 2802, 2831, 2860, 2889, 2918, 2948, 2977, 3006,
- X 3035, 3064, 3094, 3123, 3152, 3181, 3210, 3239,
- X 3269, 3298, 3327, 3356, 3385, 3415, 3444, 3473,
- X 3502, 3531, 3560, 3590, 3619, 3648, 3677, 3706,
- X 3736, 3765, 3794, 3823, 3852, 3881, 3911, 3940,
- X 3969, 3998, 4027, 4057, 4086, 4115, 4144, 4173,
- X 4202, 4232, 4261, 4290, 4319, 4348, 4378, 4407,
- X 4436, 4465, 4494, 4524, 4553, 4582, 4611, 4640,
- X 4669, 4699, 4728, 4757, 4786, 4815, 4845, 4874,
- X 4903, 4932, 4961, 4990, 5020, 5049, 5078, 5107,
- X 5136, 5166, 5195, 5224, 5253, 5282, 5311, 5341,
- X 5370, 5399, 5428, 5457, 5487, 5516, 5545, 5574,
- X 5603, 5633, 5662, 5691, 5720, 5749, 5778, 5808,
- X 5837, 5866, 5895, 5924, 5954, 5983, 6012, 6041,
- X 6070, 6099, 6129, 6158, 6187, 6216, 6245, 6275,
- X 6304, 6333, 6362, 6391, 6420, 6450, 6479, 6508,
- X 6537, 6566, 6596, 6625, 6654, 6683, 6712, 6742,
- X 6771, 6800, 6829, 6858, 6887, 6917, 6946, 6975,
- X 7004, 7033, 7063, 7092, 7121, 7150, 7179, 7208,
- X 7238, 7267, 7296, 7325, 7354, 7384, 7413, 7442};
- X
- Xstatic int dither_table[16][16] = {
- X { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,254},
- X {128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127},
- X { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223},
- X {160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95},
- X { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247},
- X {136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119},
- X { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215},
- X {168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87},
- X { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253},
- X {130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125},
- X { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221},
- X {162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93},
- X { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245},
- X {138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117},
- X { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213},
- X {170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85}};
- X
- SHAR_EOF
- chmod 0644 vue.h || echo "restore of vue.h fails"
- fi
- if test -f vue.icon; then echo "File vue.icon exists"; else
- echo "x - extracting vue.icon (Text)"
- sed 's/^X//' << 'SHAR_EOF' > vue.icon &&
- X/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
- X */
- X 0x3FFF,0xFFFF,0xFFFF,0xFFFC,0x7FFF,0xFFFF,0xFFFF,0xFFFE,
- X 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xE083,0x5555,0x5591,0x1107,
- X 0xE092,0xAAAA,0xAA88,0x8927,0xE0BB,0x5555,0x55A2,0x2377,
- X 0xE092,0xAAAA,0xAAC4,0x4527,0xE083,0x5555,0x5591,0x1107,
- X 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xE080,0x0000,0x0000,0x0007,
- X 0xE480,0x0000,0x0000,0x0007,0xEE80,0x0000,0x0000,0x0007,
- X 0xE480,0x0000,0x0000,0x0007,0xE080,0x0000,0x0000,0x0007,
- X 0xFF80,0x0000,0x0000,0x0007,0xF580,0x0000,0x0000,0x0007,
- X 0xEA80,0x0000,0x0000,0x0007,0xF59C,0x1C00,0x0000,0x0007,
- X 0xEA8C,0x0800,0x0000,0x0007,0xF586,0x1000,0x0000,0x0007,
- X 0xEA86,0x1000,0x0000,0x0007,0xF586,0x10F3,0xC1E0,0x0007,
- X 0xEA83,0x2061,0x8618,0x0007,0xF583,0x2061,0x8C0C,0x0007,
- X 0xEA83,0x2061,0x8C0C,0x0007,0xF581,0x8061,0x8FFC,0x0007,
- X 0xEA81,0xC061,0x8C00,0x0007,0xF581,0xC061,0x8C00,0x0007,
- X 0xEA80,0x8061,0x8600,0x0007,0xF580,0x8073,0x830C,0x0007,
- X 0xEA80,0x803C,0xC1F0,0x0007,0xFF80,0x0000,0x0000,0x0007,
- X 0xE880,0x0000,0x0000,0x0007,0xE280,0x0000,0x0000,0x0007,
- X 0xE480,0x0000,0x0000,0x0007,0xF180,0x0000,0x0000,0x0007,
- X 0xE880,0x0000,0x0000,0x0007,0xE280,0x0000,0x0000,0x0007,
- X 0xE480,0x0000,0x0000,0x0007,0xF180,0x0000,0x0000,0x0007,
- X 0xE880,0x0000,0x0000,0x0007,0xE280,0x0000,0x0000,0x0007,
- X 0xE480,0x0000,0x0000,0x0007,0xF180,0x0000,0x0000,0x0007,
- X 0xE880,0x0000,0x0000,0x0007,0xE280,0x0000,0x0000,0x0007,
- X 0xE480,0x0000,0x0000,0x0007,0xF180,0x0000,0x0000,0x0007,
- X 0xE880,0x0000,0x0000,0x0007,0xE280,0x0000,0x0000,0x0007,
- X 0xE480,0x0000,0x0000,0x0007,0xF180,0x0000,0x0000,0x0007,
- X 0xE880,0x0000,0x0000,0x0007,0xE280,0x0000,0x0000,0x0007,
- X 0xE480,0x0000,0x0000,0x0007,0xFF80,0x0000,0x0000,0x0007,
- X 0xE080,0x0000,0x0000,0x0007,0xE480,0x0000,0x0000,0x0007,
- X 0xEE80,0x0000,0x0000,0x0007,0xE480,0x0000,0x0000,0x0007,
- X 0xE080,0x0000,0x0000,0x0007,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
- X 0x7FFF,0xFFFF,0xFFFF,0xFFFE,0x3FFF,0xFFFF,0xFFFF,0xFFFC
- SHAR_EOF
- chmod 0777 vue.icon || echo "restore of vue.icon fails"
- fi
- if test -f vue.man; then echo "File vue.man exists"; else
- echo "x - extracting vue.man (Text)"
- sed 's/^X//' << 'SHAR_EOF' > vue.man &&
- X.TH VUE L
- X.SH NAME
- Xvue \- a Sunview rasterfile display program
- X.SH SYNOPSIS
- X\fBvue\fP [ \fB-f filter\fP ] [ \fBfilename... \fP]
- X.SH DESCRIPTION
- XVue is a Sunview tool to display images in a scrollable Sunview
- Xwindow. Vue can be used with or without a filter. Without a filter
- Xvue can be used to display ordinary rasterfiles. With a user
- Xsupplied filter, vue can display whatever filetype the supplied
- Xfilter works with.
- X
- XFile selection within vue is very easy.
- XWhile the mouse cursor is inside the display area,
- Xa new file may selected using any of the three mouse buttons.
- XPressing the right mouse button will display a menu of available files.
- XTo select a new file, simply high-lighting the desired file,
- Xand release the button.
- XSingle stepping thru the file menu is accomplished by clicking
- Xthe left and middle mouse buttons.
- XClicking the left mouse button to go up the list.
- XClicking the middle mouse button to go down the list.
- XVue will "roll-over" upon reaching either end of the list.
- XVue will also "step over" files it cannot load
- X(simply press the same mouse button again).
- X
- XVue uses the frame's label bar to display program status messages,
- Xand the name of the file being displayed.
- X
- XAccess to vue's control panel can be obtain by selecting [props] from
- Xvue's frame menu, or by pressing the [esc] key while the mouse cursor
- Xis inside the display area. The selection menu can be updated by
- Xentering a new filename on the 'File:' line and pressing the [Update_Menu]
- Xbutton. Changing the filter or updating the filter options used can be
- Xdone by editing the 'Filter:' line and pressing the [Update_filter] button.
- X(These lines many contain shell wildcard characters.)
- X.SH OPTIONS
- X.TP
- X\fB-f\fP \fIfilter\fP
- XSpecify a filter vue is to pipe the selected file thru before
- Xdisplaying it. Using 'zcat' as a filter, vue can display the contents
- Xof compressed rasterfiles. Using Patrick J. Naughton's gif2ras program,
- Xvue can be used to display GIF files.
- X.SH AUTHOR
- X.nf
- XMatthew Lee Stier
- XSun Microsystems
- X2000 Aerial Center, Suite 110
- XMorrisville, NC 27560
- X(919) 469-8300
- X.fi
- X.SH CREDITS
- XVue was developed from a program publically called rastershow.
- XRastershow's author is: David DiGiacomo, also an employee of Sun Microsystems
- X.SH NOTES
- XVue expects filters to accept input via stdin, and output the rasterfile
- Xvia stdout. If the filter you intend to use requires command-line option,
- Xthese need to included with the filter argument by enclosing it in single quotes.
- X
- X vue -f 'filter -options' filename filename....
- X
- XAny filter you specify must be reachable using your $PATH enviromental variable,
- Xor you must specify the the filters full path/filename.
- X
- XVue does do rudimentary dithering. This is to permit the viewing of color images
- Xon monochrome workstations, and 24-bit images on 8-bit color displays.
- SHAR_EOF
- chmod 0777 vue.man || echo "restore of vue.man fails"
- fi
- if test -f gif2ras.c; then echo "File gif2ras.c exists"; else
- echo "x - extracting gif2ras.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > gif2ras.c &&
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)gif2ras.c 1.1 89/01/17";
- X#endif
- X/*-
- X * gif2ras.c - Converts from a Compuserve GIF (tm) image to a Sun Raster image.
- X *
- X * Copyright (c) 1988, 1989 by Patrick J. Naughton
- X *
- X * Author: Patrick J. Naughton
- X * naughton@wind.sun.com
- X *
- X * Permission to use, copy, modify, and distribute this software and its
- X * documentation for any purpose and without fee is hereby granted,
- X * provided that the above copyright notice appear in all copies and that
- X * both that copyright notice and this permission notice appear in
- X * supporting documentation.
- X *
- X * This file is provided AS IS with no warranties of any kind. The author
- X * shall have no liability with respect to the infringement of copyrights,
- X * trade secrets or any patents by this file or any part thereof. In no
- X * event will the author be liable for any lost revenue or profits or
- X * other special, indirect and consequential damages.
- X *
- X * Comments and additions should be sent to the author:
- X *
- X * Patrick J. Naughton
- X * Sun Microsystems
- X * 2550 Garcia Ave, MS 14-40
- X * Mountain View, CA 94043
- X * (415) 336-1080
- X *
- X * Revision History:
- X * 01-Jan-89: Added error checking and removed NEXTSHORT.
- X * 07-Sep-88: Added BytesPerScanline fix.
- X * 30-Aug-88: Allow stdin/stdout. Restructured argument parser.
- X * 27-Jul-88: Updated to use libpixrect to fix 386i byteswapping problems.
- X * 11-Apr-88: Converted to C and changed to write Sun rasterfiles.
- X * 19-Jan-88: GIFSLOW.PAS posted to comp.graphics by Jim Briebel,
- X * a Turbo Pascal 4.0 program to painfully slowly display
- X * GIF images on an EGA equipped IBM-PC.
- X *
- X * Description:
- X * This program takes a Compuserve "Graphics Interchange Format" or "GIF"
- X * file as input and writes a file known as a Sun rasterfile. This datafile
- X * can be loaded by the NeWS "readcanvas" operator and is of the same format
- X * as the files in /usr/NeWS/smi/*. Under X11R2 there is a program called
- X * xraster to display these files.
- X *
- X * Portability:
- X * To make this program convert to some image format other than Sun's
- X * Rasterfile format simply seach for the tag "SS:" in the source and
- X * replace these simple mechanisms with the appropriate ones for the
- X * other output format. I have marked all (six) Sun Specific pieces
- X * of code with this comment.
- X *
- X * SS: compile with "cc -o gif2ras -O gif2ras.c -lpixrect"
- X */
- X
- X#include <stdio.h>
- X#include <pixrect/pixrect_hs.h> /* SS: main Pixrect header file */
- X
- Xtypedef int boolean;
- X#define True (1)
- X#define False (0)
- X
- X#define NEXTBYTE (*ptr++)
- X#define IMAGESEP 0x2c
- X#define INTERLACEMASK 0x40
- X#define COLORMAPMASK 0x80
- X
- XFILE *fp;
- X
- Xint BitOffset = 0, /* Bit Offset of next code */
- X XC = 0, YC = 0, /* Output X and Y coords of current pixel */
- X Pass = 0, /* Used by output routine if interlaced pic */
- X OutCount = 0, /* Decompressor output 'stack count' */
- X RWidth, RHeight, /* screen dimensions */
- X Width, Height, /* image dimensions */
- X LeftOfs, TopOfs, /* image offset */
- X BitsPerPixel, /* Bits per pixel, read from GIF header */
- X BytesPerScanline, /* bytes per scanline in output raster */
- X ColorMapSize, /* number of colors */
- X CodeSize, /* Code size, read from GIF header */
- X InitCodeSize, /* Starting code size, used during Clear */
- X Code, /* Value returned by ReadCode */
- X MaxCode, /* limiting value for current code size */
- X ClearCode, /* GIF clear code */
- X EOFCode, /* GIF end-of-information code */
- X CurCode, OldCode, InCode, /* Decompressor variables */
- X FirstFree, /* First free code, generated per GIF spec */
- X FreeCode, /* Decompressor, next free slot in hash table */
- X FinChar, /* Decompressor variable */
- X BitMask, /* AND mask for data size */
- X ReadMask; /* Code AND mask for current code size */
- X
- Xboolean Interlace, HasColormap;
- Xboolean Verbose = False;
- X
- X/* SS: defined in pixrect/pixrect_hs.h */
- XPixrect *Output; /* The Sun Pixrect */
- Xcolormap_t Colormap; /* The Pixrect Colormap */
- X
- Xu_char *Image; /* The result array */
- Xu_char *RawGIF; /* The heap array to hold it, raw */
- Xu_char *Raster; /* The raster data stream, unblocked */
- X
- X /* The hash table used by the decompressor */
- Xint Prefix[4096];
- Xint Suffix[4096];
- X
- X /* An output array used by the decompressor */
- Xint OutCode[1025];
- X
- X /* The color map, read from the GIF header */
- Xu_char Red[256], Green[256], Blue[256];
- X
- Xchar *id = "GIF87a";
- X
- Xchar *pname; /* program name (used for error messages) */
- X
- Xvoid
- Xerror(s1, s2)
- Xchar *s1, *s2;
- X{
- X fprintf(stderr, s1, pname, s2);
- X exit(1);
- X}
- X
- Xvoid
- Xusage()
- X{
- X error("usage: %s -[vq] [-|GIFfile] [rasterfile]\n", NULL);
- X}
- X
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- Xchar *inf = NULL;
- Xchar *outf = NULL;
- Xint filesize;
- Xregister u_char ch, ch1;
- Xregister u_char *ptr, *ptr1;
- Xregister int i;
- X
- X setbuf(stderr, NULL);
- X pname = argv[0];
- X
- X while (--argc)
- X if ((++argv)[0][0] == '-')
- X switch (argv[0][1]) {
- X case 'v':
- X Verbose = True;
- X break;
- X case 'q':
- X usage();
- X case '\0':
- X if (inf == NULL)
- X inf = "Standard Input";
- X else if (outf == NULL)
- X outf = "Standard Output";
- X else
- X usage();
- X break;
- X default:
- X fprintf(stderr, "%s: illegal option -%c.\n", pname,
- X argv[0][1]);
- X exit(1);
- X }
- X else if (inf == NULL)
- X inf = argv[0];
- X else if (outf == NULL)
- X outf = argv[0];
- X else
- X usage();
- X
- X if (inf == NULL || strcmp(inf, "Standard Input") == 0) {
- X inf = "Standard Input";
- X fp = stdin;
- X } else if (!(fp = fopen(inf, "r")))
- X error("%s: %s not found.\n", inf);
- X
- X /* find the size of the file */
- X fseek(fp, 0L, 2);
- X filesize = ftell(fp);
- X fseek(fp, 0L, 0);
- X
- X if (!(ptr = RawGIF = (u_char *) malloc(filesize)))
- X error("%s: not enough memory to read gif file.\n", NULL);
- X
- X if (!(Raster = (u_char *) malloc(filesize)))
- X error("%s: not enough memory to read gif file.\n", NULL);
- X
- X if (fread(ptr, filesize, 1, fp) != 1)
- X error("%s: GIF data read failed\n", NULL);
- X
- X if (strncmp(ptr, id, 6))
- X error("%s: %s is not a GIF file.\n", inf);
- X ptr += 6;
- X
- X/* Get variables from the GIF screen descriptor */
- X
- X ch = NEXTBYTE;
- X RWidth = ch + 0x100 * NEXTBYTE; /* screen dimensions... not used. */
- X ch = NEXTBYTE;
- X RHeight = ch + 0x100 * NEXTBYTE;
- X
- X if (Verbose)
- X fprintf(stderr, "screen dims: %dx%d.\n", RWidth, RHeight);
- X
- X ch = NEXTBYTE;
- X HasColormap = ((ch & COLORMAPMASK) ? True : False);
- X
- X BitsPerPixel = (ch & 7) + 1;
- X ColorMapSize = 1 << BitsPerPixel;
- X BitMask = ColorMapSize - 1;
- X
- X ch = NEXTBYTE; /* background color... not used. */
- X
- X if (NEXTBYTE) /* supposed to be NULL */
- X error("%s: %s is a corrupt GIF file (nonull).\n", inf);
- X
- X/* Read in global colormap. */
- X
- X if (HasColormap) {
- X if (Verbose)
- X fprintf(stderr, "%s is %d bits per pixel, (%d colors).\n",
- X inf, BitsPerPixel, ColorMapSize);
- X for (i = 0; i < ColorMapSize; i++) {
- X Red[i] = NEXTBYTE;
- X Green[i] = NEXTBYTE;
- X Blue[i] = NEXTBYTE;
- X }
- X
- X/* SS: Fill in the Pixrect colormap struct */
- X Colormap.type = RMT_EQUAL_RGB;
- X Colormap.length = ColorMapSize;
- X Colormap.map[0] = Red;
- X Colormap.map[1] = Green;
- X Colormap.map[2] = Blue;
- X }
- X else error("%s: %s does not have a colormap.\n", inf);
- X
- X
- X/* Check for image seperator */
- X
- X if (NEXTBYTE != IMAGESEP)
- X error("%s: %s is a corrupt GIF file (nosep).\n", inf);
- X
- X/* Now read in values from the image descriptor */
- X
- X ch = NEXTBYTE;
- X LeftOfs = ch + 0x100 * NEXTBYTE;
- X ch = NEXTBYTE;
- X TopOfs = ch + 0x100 * NEXTBYTE;
- X ch = NEXTBYTE;
- X Width = ch + 0x100 * NEXTBYTE;
- X ch = NEXTBYTE;
- X Height = ch + 0x100 * NEXTBYTE;
- X Interlace = ((NEXTBYTE & INTERLACEMASK) ? True : False);
- X
- X if (Verbose)
- X fprintf(stderr, "Reading a %d by %d %sinterlaced image...",
- X Width, Height, (Interlace) ? "" : "non-");
- X
- X
- X/* Note that I ignore the possible existence of a local color map.
- X * I'm told there aren't many files around that use them, and the spec
- X * says it's defined for future use. This could lead to an error
- X * reading some files.
- X */
- X
- X/* Start reading the raster data. First we get the intial code size
- X * and compute decompressor constant values, based on this code size.
- X */
- X
- X CodeSize = NEXTBYTE;
- X ClearCode = (1 << CodeSize);
- X EOFCode = ClearCode + 1;
- X FreeCode = FirstFree = ClearCode + 2;
- X
- X/* The GIF spec has it that the code size is the code size used to
- X * compute the above values is the code size given in the file, but the
- X * code size used in compression/decompression is the code size given in
- X * the file plus one. (thus the ++).
- X */
- X
- X CodeSize++;
- X InitCodeSize = CodeSize;
- X MaxCode = (1 << CodeSize);
- X ReadMask = MaxCode - 1;
- X
- X/* Read the raster data. Here we just transpose it from the GIF array
- X * to the Raster array, turning it from a series of blocks into one long
- X * data stream, which makes life much easier for ReadCode().
- X */
- X
- X ptr1 = Raster;
- X do {
- X ch = ch1 = NEXTBYTE;
- X while (ch--) *ptr1++ = NEXTBYTE;
- X if ((ptr1 - Raster ) > filesize)
- X error("%s: %s is a corrupt GIF file (unblock).\n", inf);
- X } while(ch1);
- X
- X free(RawGIF); /* We're done with the raw data now... */
- X
- X if (Verbose) {
- X fprintf(stderr, "done.\n");
- X fprintf(stderr, "Decompressing...");
- X }
- X
- X
- X/* SS: Allocate the Sun Pixrect and make "Image" point to the image data. */
- X Output = mem_create(Width, Height, 8);
- X if (Output == (Pixrect *) NULL)
- X error("%s: not enough memory for output data.\n", NULL);
- X Image = (u_char *) mpr_d(Output)->md_image;
- X BytesPerScanline = mpr_d(Output)->md_linebytes;
- X
- X
- X/* Decompress the file, continuing until you see the GIF EOF code.
- X * One obvious enhancement is to add checking for corrupt files here.
- X */
- X
- X Code = ReadCode();
- X while (Code != EOFCode) {
- X
- X/* Clear code sets everything back to its initial value, then reads the
- X * immediately subsequent code as uncompressed data.
- X */
- X
- X if (Code == ClearCode) {
- X CodeSize = InitCodeSize;
- X MaxCode = (1 << CodeSize);
- X ReadMask = MaxCode - 1;
- X FreeCode = FirstFree;
- X CurCode = OldCode = Code = ReadCode();
- X FinChar = CurCode & BitMask;
- X AddToPixel(FinChar);
- X }
- X else {
- X
- X/* If not a clear code, then must be data: save same as CurCode and InCode */
- X
- X CurCode = InCode = Code;
- X
- X/* If greater or equal to FreeCode, not in the hash table yet;
- X * repeat the last character decoded
- X */
- X
- X if (CurCode >= FreeCode) {
- X CurCode = OldCode;
- X OutCode[OutCount++] = FinChar;
- X }
- X
- X/* Unless this code is raw data, pursue the chain pointed to by CurCode
- X * through the hash table to its end; each code in the chain puts its
- X * associated output code on the output queue.
- X */
- X
- X while (CurCode > BitMask) {
- X if (OutCount > 1024)
- X error("%s: %s is a corrupt GIF file (OutCount).\n", inf);
- X OutCode[OutCount++] = Suffix[CurCode];
- X CurCode = Prefix[CurCode];
- X }
- X
- X/* The last code in the chain is treated as raw data. */
- X
- X FinChar = CurCode & BitMask;
- X OutCode[OutCount++] = FinChar;
- X
- X/* Now we put the data out to the Output routine.
- X * It's been stacked LIFO, so deal with it that way...
- X */
- X
- X for (i = OutCount - 1; i >= 0; i--)
- X AddToPixel(OutCode[i]);
- X OutCount = 0;
- X
- X/* Build the hash table on-the-fly. No table is stored in the file. */
- X
- X Prefix[FreeCode] = OldCode;
- X Suffix[FreeCode] = FinChar;
- X OldCode = InCode;
- X
- X/* Point to the next slot in the table. If we exceed the current
- X * MaxCode value, increment the code size unless it's already 12. If it
- X * is, do nothing: the next code decompressed better be CLEAR
- X */
- X
- X FreeCode++;
- X if (FreeCode >= MaxCode) {
- X if (CodeSize < 12) {
- X CodeSize++;
- X MaxCode *= 2;
- X ReadMask = (1 << CodeSize) - 1;
- X }
- X }
- X }
- X Code = ReadCode();
- X }
- X
- X free(Raster);
- X
- X if (Verbose)
- X fprintf(stderr, "done.\n");
- X
- X if (fp != stdin)
- X fclose(fp);
- X
- X if (outf == NULL || strcmp(outf, "Standard Output") == 0) {
- X outf = "Standard Output";
- X fp = stdout;
- X }
- X else {
- X if (!(fp = fopen(outf, "w")))
- X error("%s: %s couldn't be opened for writing.\n", outf);
- X }
- X
- X if (Verbose)
- X fprintf(stderr, "Writing rasterfile in %s...", outf);
- X
- X/* SS: Pixrect Rasterfile output code. */
- X if (pr_dump(Output, fp, &Colormap, RT_STANDARD, 0) == PIX_ERR)
- X error("%s: error writing Sun Rasterfile: %s\n", outf);
- X
- X if (Verbose)
- X fprintf(stderr, "done.\n");
- X
- X pr_destroy(Output);
- X
- X if (fp != stdout)
- X fclose(fp);
- X
- X exit(0);
- X}
- X
- X
- X/* Fetch the next code from the raster data stream. The codes can be
- X * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to
- X * maintain our location in the Raster array as a BIT Offset. We compute
- X * the byte Offset into the raster array by dividing this by 8, pick up
- X * three bytes, compute the bit Offset into our 24-bit chunk, shift to
- X * bring the desired code to the bottom, then mask it off and return it.
- X */
- XReadCode()
- X{
- Xint RawCode, ByteOffset;
- X
- X ByteOffset = BitOffset / 8;
- X RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]);
- X if (CodeSize >= 8)
- X RawCode += (0x10000 * Raster[ByteOffset + 2]);
- X RawCode >>= (BitOffset % 8);
- X BitOffset += CodeSize;
- X return(RawCode & ReadMask);
- X}
- X
- X
- XAddToPixel(Index)
- Xu_char Index;
- X{
- X *(Image + YC * BytesPerScanline + XC) = Index;
- X
- X/* Update the X-coordinate, and if it overflows, update the Y-coordinate */
- X
- X if (++XC == Width) {
- X
- X/* If a non-interlaced picture, just increment YC to the next scan line.
- X * If it's interlaced, deal with the interlace as described in the GIF
- X * spec. Put the decoded scan line out to the screen if we haven't gone
- X * past the bottom of it
- X */
- X
- X XC = 0;
- X if (!Interlace) YC++;
- X else {
- X switch (Pass) {
- X case 0:
- X YC += 8;
- X if (YC >= Height) {
- X Pass++;
- X YC = 4;
- X }
- X break;
- X case 1:
- X YC += 8;
- X if (YC >= Height) {
- X Pass++;
- X YC = 2;
- X }
- X break;
- X case 2:
- X YC += 4;
- X if (YC >= Height) {
- X Pass++;
- X YC = 1;
- X }
- X break;
- X case 3:
- X YC += 2;
- X break;
- X default:
- X break;
- X }
- X }
- X }
- X}
- SHAR_EOF
- chmod 0644 gif2ras.c || echo "restore of gif2ras.c fails"
- fi
- if test -f gif2ras.man; then echo "File gif2ras.man exists"; else
- echo "x - extracting gif2ras.man (Text)"
- sed 's/^X//' << 'SHAR_EOF' > gif2ras.man &&
- X.TH GIF2SUN L
- X.SH NAME
- Xgif2sun \- GIF to Sun rasterfile filter
- X.SH SYNOPSIS
- X\fBgif2sun\fP [\fB-v\fP] [\fB-q\fP] [\fB-\fP|\fBGIFfile\fP] [\fBrasterfile\fP]
- X.SH DESCRIPTION
- XGenerate the rasterfile equivalent of a GIF image.
- X.SH OPTIONS
- X.TP
- X.nf
- X\fB-v\fP
- XSet verbose mode.
- X(Reports status of program via stderr.)
- X.fi
- X.TP
- X.nf
- X\fB-q\fP
- XDisplay help message.
- X(Usage prompt.)
- X.fi
- X.TP
- X.nf
- X\fB-\fP
- XForce sourcing of GIF file from stdin.
- X(Only needed when sourcing the GIF file from \fBstdin\fP and
- Xspecifying the output rasterfile on the command line.)
- X.fi
- X.SH DIAGNOSTICS
- XSee verbose mode above.
- X.SH AUTHOR
- X.nf
- XPatrick J. Naughton
- XSun Microsystems
- X2550 Garcia Ave, MS 14-40
- XMountain View, CA 94043
- X(415) 336-1080
- X.fi
- SHAR_EOF
- chmod 0644 gif2ras.man || echo "restore of gif2ras.man fails"
- fi
- exit 0
-
- --
- Matthew Lee Stier (mstier@east.Sun.COM) |
- Sun Microsystems --- RTP, NC 27709-3447 | "Wisconsin Escapee"
- uucp: sun!mstier or mcnc!rti!sunpix!matthew |
- phone: (919) 469-8300 fax: (919) 460-8355 |
-