Filewatcher File Search
FTP Search
  
Directory 
  
Content Search 
   
pkg://vimage-1.1.tar.gz:38196/vimage.c  downloads

/*
 * $Id: vimage.c,v 1.6 1995/09/16 14:01:57 traister Exp traister $
 * vimage - an SVGA picture viewer for Linux using VGAlib 1.3
 * Copyright (c) 1995, Joseph J. Traister
 * 
 * $Log: vimage.c,v $
 * Revision 1.6  1995/09/16  14:01:57  traister
 * Rewrote error reporting throughout.
 * Added file type table to facilitate adding new image types.
 *
 * Revision 1.5  1995/09/03  02:14:54  traister
 * Added ReadFile() to generically read an image.
 *
 * Revision 1.4  1995/08/06  03:05:55  traister
 * Added ESC exit to final wait loop in SlideShow()
 *
 * Revision 1.3  1995/07/30  19:20:47  traister
 * Updated copyright prior to first public release
 *
 * Revision 1.2  1995/05/13  22:40:17  traister
 * Added "break" in slide show when ESC hit.
 *
 * Revision 1.1  1995/05/13  01:40:52  traister
 * Initial revision
 *
 */

/*   This program is free software; you can redistribute it and/or
     modify it under the terms of the GNU General Public License
     as published by the Free Software Foundation; either version 2
     of the License, or (at your option) any later version.

     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */

#include <vga.h>
#include <errno.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <values.h>
#include <getopt.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>
#include "vimage.h"

/*
   Initial size of, and increment to, fnames array size during
   slide file read
*/
#define NAME_INC 100

#ifdef NCURSES_SUPPORT
#define OPTSTRING "m:l:d:qxra2fs:Rcvit"
#else
#define OPTSTRING "m:l:d:qxra2fs:Rvit"
#endif

char progname[PATH_MAX], modename[256]="", **fnames=NULL;
char errmsg[512];
int quiet=0, automode=0, pictime=6, twopass=0, floyd=0, slide=0, reverse=0;
int interact=0, notruecolor=0;
unsigned loopcount=1, printstats=0;

#ifdef NCURSES_SUPPORT
int filesel=0;
#endif

FTYPE ftypes[] = {
  { "", NULL, NULL },  /* dummy entry. 0= invalid file */
#ifdef JPEG_SUPPORT
  { "JPEG", ReadJPEGHead, ReadJPEG },
#endif
  { "TIFF", ReadTIFFHead, ReadTIFF },
  { "Targa", ReadTargaHead, ReadTarga },
  { "Sun Rasterfile", ReadRasterfileHead, ReadRasterfile },
  { "PNM", ReadPNMHead, ReadPNM },
  { "GIF", ReadGIFHead, ReadGIF }
};

#define NR_FTYPES (sizeof(ftypes)/sizeof(FTYPE)-1)

int randcompare(const void*, const void*);
int ReadSlideFile(char*);
int Interact(char**, int);

int main(int argc, char **argv)
{
  char temp[PATH_MAX], c;
  extern int optind;
  extern char *optarg;
  int fc=0, i, errval=0, randfiles=0, pipe_input=0, filetype;
  FILE *fpin;
  IMAGE image, newimage;

  SetID();
  strcpy(progname, argv[0]);
  optind = 1;
  while ((i=getopt(argc, argv, OPTSTRING)) != EOF) {
    switch (i) {
    case 't':
      notruecolor = 1;
      break;

    case 'l':
      loopcount = atoi(optarg);
      break;
      
    case 'd':
      pictime = atoi(optarg);
      break;
      
    case 'q':
      quiet = 1;
      break;

    case 'x':
      printstats = 1;
      break;

    case 'r':
      reverse = 1;
      break;

    case 'a':
      automode = 1;
      break;
      
    case 'm':
      strcpy(modename, optarg);
      break;

    case '2':
      twopass = 1;
      break;

    case 'f':
      floyd = 1;
      break;

    case 'R':
      randfiles=1;
      break;

    case 's':
      fc = ReadSlideFile(optarg);
      if (fc < 0) {
	fprintf(stderr, "%s: %s\n", progname, errmsg);
	return -1;
      }
      slide = 1;
      break;

    case 'v':
      printf("%s: version %s\n", progname, VERSION);
      return 0;

    case 'i':
      interact=1;
      break;

#ifdef NCURSES_SUPPORT
    case 'c':
      filesel=1;
      break;
#endif
      
    case '?':
    default:
      errval++;
    }
  }

  if (optind == argc && !slide) {
    if (!isatty(STDIN_FILENO)) {
      pipe_input = 1;
      sprintf(temp, "/tmp/vimage.%i", getpid());
      if (!(fnames = (char**)malloc(sizeof(char*)))) {
	fprintf(stderr, "%s: %s: %s\n", progname, strerror(errno), temp);
	return -1;
      }
      if (!(fnames[0] = (char*)malloc(strlen(temp)+1))) {
	fprintf(stderr, "%s: %s: %s\n", progname, strerror(errno), temp);
	return -1;
      }
      strcpy(fnames[0], temp);
      if (!(fpin = fopen(temp, "w"))) {
	fprintf(stderr, "%s: %s: %s\n", progname, strerror(errno), temp);
	return -1;
      }
      while ((i=getchar()) != EOF)
	fputc(i, fpin);
      fc = 1;
      fclose(fpin);
    } else
      errval++;
  }

  if (errval) {
    fprintf(stderr,
	    "Vimage v"VERSION" - Copyright (c) 1995, Joe Traister\n"
	    "Usage: %s [options] [-s slide | file ... | < filename]\n"
	    "Options:\n"
            "  -R        Display pictures in random order\n"
            "  -a        Automatically choose video mode based on picture "
            "size\n"
	    "            and number of colors\n"
#ifdef NCURSES_SUPPORT
	    "  -c        Use full-screen file selector\n"
#endif
	    "  -f        Add Floyd-Steinberg dithering to Heckbert median "
            "cut\n"
	    "  -q        Quiet, do not display or break on file read errors\n"
	    "  -r        Show pictures in reverse order\n"
	    "  -t        Do not use 24-bit video modes (for Cirrus Logic "
	    "5426/28)\n"
	    "  -x        No picture display, list image statistics instead\n"
	    "  -2        Use Heckbert median cut (2-pass) color palette"
	    " computation\n"
	    "  -d n      Delay {n} seconds between pictures (Default=6)\n"
	    "  -l n      Loop through pictures {n} times (Default=1)\n"
	    "  -m mode   Use video mode {mode}\n"
	    "  -s slide  Read filenames from file {slide}\n"
	    "  -v        Print version and quit\n"
	    "  Shows "
#ifdef JPEG_SUPPORT
	    "JPEG, "
#endif
	    "Targa, PPM, PBM, PGM, GIF, SunRaster and TIFF images\n",
	    progname);
    return -1;
  }

  if (!slide && !pipe_input) {
    fc = argc-optind;
    if (!(fnames = (char**)malloc(sizeof(char*)*fc))) {
      fprintf(stderr, "%s: %s: %s\n", progname, strerror(errno), temp);
      return -1;
    }
    for (i=0; i < fc; i++) {
      if (!(fnames[i] = (char*)malloc(strlen(argv[i+optind])+1))) {
	fprintf(stderr, "%s: %s: %s\n", progname, strerror(errno), temp);
	return -1;
      }
      strcpy(fnames[i], argv[i+optind]);
    }
  }

  if (printstats) {
    for (i=0; i < fc; i++) {
      if (!(fpin = fopen(fnames[i], "r"))) 
	if (quiet)
	  continue;
	else {
	  fprintf(stderr, "%s: %s: %s\n", progname, strerror(errno), temp);
	  return -1;
	}
      filetype = GetFileHead(fpin, &image);
      fclose(fpin);
      if (filetype < 0) {
	fprintf(stderr, "%s: %s: %s\n", progname, errmsg, fnames[i]);
	return -1;
      } else if (!filetype)
	printf("%s: Unknown file type: %s\n", progname, fnames[i]);
      else {
	printf("%s: %ix%ix%i %s\n", fnames[i], image.width, image.height, 
	       image.palsize > 0 ? image.palsize : 1<<(-image.palsize),
	       ftypes[filetype].name);
      }
    }
    return 0;
  }
#ifdef NCURSES_SUPPORT
  if (filesel)
    return fileSelector(fnames, fc);
#endif
  if (InitVGA(modename)) {
    fprintf(stderr, "%s: %s\n", progname, errmsg);
    return -1;
  }
  if (fc == 1) {
    pictime = 0;
    if (!pipe_input)
      printf("%s: Reading file: %s\n", progname, fnames[0]);
    if (ReadFile(fnames[0], &image)) {
      fprintf(stderr, "%s: %s\n", progname, errmsg);
      return -1;
    }
    SetModeInfo(&image);
    if (image.width > modeinfo->width || image.height > modeinfo->height) {
      if (!pipe_input)
	printf("%s: Scaling...\n", progname);
      if (Scale(&image, &newimage, modeinfo->width, modeinfo->height)) {
	fprintf(stderr, "%s: %s: %s\n", progname, errmsg, fnames[0]);
	return -1;
      }
      free(image.bits);
      memcpy(&image, &newimage, sizeof(IMAGE));
    }
    if (modeinfo->bytesperpixel == 1 && image.palsize < -8) {
      if (!pipe_input)
	printf("%s: Color quantizing...\n", progname);
      if (twopass) {
	if (HeckbertMedianCut(&image, &newimage)) {
	  fprintf(stderr, "%s: %s: %s\n", progname, errmsg, fnames[0]);
	  return -1;
	}
      } else {
	if (MapToCube(&image, &newimage)) {
	  fprintf(stderr, "%s: %s: %s\n", progname, errmsg, fnames[0]);
	  return -1;
	}
      }
      free(image.bits);
      memcpy(&image, &newimage, sizeof(IMAGE));
    }
    SetVideoMode();
    if (DisplayImage(&image)) {
      VGAShutdown();
      fprintf(stderr, "%s: %s: %s\n", progname, errmsg, fnames[0]);
      return -1;
    }
    do {
      c = vga_getch();
    } while (c != '\n' && c != 'Q' && c != 'q' && c != 0x1b);
    free(image.bits);
    VGAShutdown();
    if (pipe_input)
      unlink(fnames[0]);
  } else if (interact) {
    if (Interact(fnames, fc)) {
      fprintf(stderr, "%s: %s\n", progname, errmsg);
      return -1;
    }
  } else {
    if (randfiles) {
      srand(getpid() ^ time(0));
      qsort(fnames, fc, sizeof(char*), randcompare);
    }
    if (Slideshow(fnames, fc)) {
      fprintf(stderr, "%s: %s\n", progname, errmsg);
      return -1;
    }
  }
  return 0;
}

int Interact(char **fnames, int fc)
{
  int curr=0, quit=0, cont, c;
  IMAGE image, newimage;

  do {
    image.bits=NULL;
    if (ReadFile(fnames[curr], &image))
      if (quiet)
	continue;
      else
	return -1;
    SetModeInfo(&image);
    if (image.width > modeinfo->width || image.height > modeinfo->height) {
      if (Scale(&image, &newimage, modeinfo->width, modeinfo->height)) {
	free(image.bits);
	if (quiet)
	  continue;
	else {
	  strcat(errmsg, ": ");
	  strcat(errmsg, fnames[curr]);
	  return -1;
	}
      }
      free(image.bits);
      memcpy(&image, &newimage, sizeof(IMAGE));
    }
    if (modeinfo->bytesperpixel == 1 && image.palsize < -8) {
      if (twopass) {
	if (HeckbertMedianCut(&image, &newimage)) {
	  free(image.bits);
	  if (quiet)
	    continue;
	  else {
	    strcat(errmsg, ": ");
	    strcat(errmsg, fnames[curr]);
	    return -1;
	  }
	}
      } else {
	if (MapToCube(&image, &newimage)) {
	  free(image.bits);
	  if (quiet)
	    continue;
	  else {
	    strcat(errmsg, ": ");
	    strcat(errmsg, fnames[curr]);
	    return -1;
	  }
	}
      }
      free(image.bits);
      memcpy(&image, &newimage, sizeof(IMAGE));
    }
    SetVideoMode();
    if (DisplayImage(&image)) {
      VGAShutdown();
      free(image.bits);
      strcat(errmsg, ": ");
      strcat(errmsg, fnames[curr]);
      return -1;
    }
    free(image.bits);
    cont=0;
    do {
      switch (c=vga_getkey()) {
      case ' ':
	if (curr < fc-1) {
	  cont = 1;
	  curr++;
	}
	break;

      case 0x7f: /* backspace key */
	if (curr > 0) {
	  cont = 1;
	  curr--;
	}
	break;
	
      case 'q':
      case 'Q':
      case '\n':
      case 0x1b:
	quit=1;
      }
    } while (!cont && !quit);
  } while (!quit);
  return 0;
}    
      

int Slideshow(char **fnames, int fc)
{
  int i, loop=0, timer;
  IMAGE image, newimage;

  timer=0;
  if (!reverse)
    i = 0;
  else
    i = fc-1;
  while (1) {
    image.bits = NULL;
    if (!ReadFile(fnames[i], &image)) {
      SetModeInfo(&image);
      if (image.width > modeinfo->width || image.height > modeinfo->height) {
	if (Scale(&image, &newimage, modeinfo->width, modeinfo->height)) {
	  free(image.bits);
	  if (quiet)
	    goto next;
	  else {
	    VGAShutdown();
	    strcat(errmsg, ": ");
	    strcat(errmsg, fnames[i]);
	    return -1;
	  }
	}
	free(image.bits);
	memcpy(&image, &newimage, sizeof(IMAGE));
      }
      if (modeinfo->bytesperpixel == 1 && image.palsize < -8) {
	if (twopass) {
	  if (HeckbertMedianCut(&image, &newimage)) {
	    free(image.bits);
	    if (quiet)
	      goto next;
	    else {
	      VGAShutdown();
	      strcat(errmsg, ": ");
	      strcat(errmsg, fnames[i]);
	      return -1;
	    }
	  }
	} else {
	  if (MapToCube(&image, &newimage)) {
	    free(image.bits);
	    if (quiet)
	      goto next;
	    else {
	      VGAShutdown();
	      strcat(errmsg, ": ");
	      strcat(errmsg, fnames[i]);
	      return -1;
	    }
	  }
	}
	free(image.bits);
	memcpy(&image, &newimage, sizeof(IMAGE));
      }
      if (timer)
	do {
	  if (vga_getkey() == 0x1b) {  /* ESC exits slideshow */
	    VGAShutdown();
	    return 0;
	  }
	} while (pictime > (time(0)-timer));
      SetVideoMode();
      if (DisplayImage(&image)) {
	free(image.bits);
	VGAShutdown();
	return -1;
      }
      free(image.bits);
      timer = time(0);
    } else
      if (!quiet)
	return -1;

  next:
    if (!reverse) {
      i++;
      if (i >= fc) {
	loop++;
	if (loop >= loopcount)
	  break;
	i = 0;
      }
    } else {
      i--;
      if (i < 0) {
	loop++;
	if (loop >= loopcount)
	  break;
	i = fc-1;
      }
    }
  }
  timer = time(0);
  while (time(0)-timer < pictime)
    if (vga_getkey() == 0x1b)
      break;
  VGAShutdown();
  return 0;
}

int GetFileHead(FILE *fpin, IMAGE *image)
{
  int i, status;

  for (i=NR_FTYPES; i > 0; --i) {
    status = ftypes[i].rhead(fpin, image);
    if (status < 0)
      return -1;
    if (status)
      return i;
    rewind(fpin);
  }
  return 0;
}

int ReadFile(char *filename, IMAGE *image)
{
  FILE *fpin;
  int filetype;

  if (!(fpin = fopen(filename, "r"))) {
    strcpy(errmsg, strerror(errno));
    strcat(errmsg, ": ");
    strcat(errmsg, filename);
    return -1;
  }
  if ((filetype=GetFileHead(fpin, image)) < 0) {
    strcat(errmsg, ": ");
    strcat(errmsg, filename);
    fclose(fpin);
    return -1;
  }
  if (!filetype) {
    strcpy(errmsg, "Unknown file type: ");
    strcat(errmsg, filename);
    fclose(fpin);
    return -1;
  }
  if (ftypes[filetype].rfile(fpin, image)) {
    fclose(fpin);
    strcat(errmsg, ": ");
    strcat(errmsg, filename);
    return -1;
  }
  fclose(fpin);
  return 0;
}

int randcompare(const void *arg1, const void *arg2)
{
  if (rand() < RAND_MAX/2)
    return 1;
  else
    return -1;
}

int ReadSlideFile(char *slidefile)
{
  int fc=0, size=NAME_INC;
  FILE *fpin;
  char temp[PATH_MAX], *chp;

  if (!(fpin = fopen(slidefile, "r"))) {
    strcpy(errmsg, strerror(errno));
    strcat(errmsg, ": ");
    strcat(errmsg, slidefile);
    return -1;
  }
  if (!(fnames = (char**)malloc(sizeof(char*)*size))) {
    strcpy(errmsg, strerror(errno));
    strcat(errmsg, ": ");
    strcat(errmsg, slidefile);
    return -1;
  }
  while (!feof(fpin)) {
    fgets(temp, PATH_MAX, fpin);
    chp = strchr(temp, '#');
    if (chp)
      *chp = '\0';
    if (!strlen(temp))
      continue;
    for (chp=temp+strlen(temp)-1; chp >= temp; chp--)
      if (isgraph(*chp)) {
	*(chp+1) = '\0';
	break;
      }
    if (chp < temp)
      continue;
    for (chp=temp; chp-temp < strlen(temp); chp++)
      if (isgraph(*chp))
	break;
    if (chp != temp)
      memmove(temp, chp, strlen(temp)-(chp-temp)+1);
    if (fc >= size) {
      size += NAME_INC;
      if (!(fnames = (char**)realloc(fnames, sizeof(char*)*size))) {
	strcpy(errmsg, strerror(errno));
	strcat(errmsg, ": ");
	strcat(errmsg, slidefile);
	return -1;
      }
    }
    if (!(fnames[fc] = (char*)malloc(strlen(temp)+1))) {
      strcpy(errmsg, strerror(errno));
      strcat(errmsg, ": ");
      strcat(errmsg, slidefile);
      return -1;
    }
    strcpy(fnames[fc], temp);
    temp[0] = '\0';
    fc++;
  }
  if (size != fc) {
    if (!(fnames = realloc(fnames, sizeof(char*)*fc))) {
      strcpy(errmsg, strerror(errno));
      strcat(errmsg, ": ");
      strcat(errmsg, slidefile);
      return -1;
    }
  }
  if (!fc) {
    strcpy(errmsg, "No slide file names found: ");
    strcat(errmsg, slidefile);
    return -1;
  }
  fclose(fpin);
  return fc;
}
Results 1 - 1
Help - FTP Sites List - Software Dir.
Searching half a billion files worldwide
© 1997-2009 MARUHN Internet Solutions