📄 toast.c
字号:
/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. *//* $Header: /home/kbs/jutta/src/gsm/gsm-1.0/src/RCS/toast.c,v 1.4 1994/05/10 20:18:49 jutta Exp $ */#include "private.h"#include "toast.h"/* toast -- lossy sound compression using the gsm library. */char * progname;int f_decode = 0; /* decode rather than encode (-d) */int f_cat = 0; /* write to stdout, not foo.gsm (-c) */int f_force = 0; /* force deletion (-f) */int f_precious = 0; /* avoid deletion (-p) */int f_fast = 0; /* use faster fpt algorithm (-F) */int f_verbose = 0; /* debugging (-V) */struct stat instat; /* stat (inname) */FILE *in, *out;char *inname, *outname;/* * The function (*output)() writes a frame of 160 samples given as * 160 signed 16 bit values (gsm_signals) to <out>. * The function (*input)() reads one such frame from <in>. * The function (*init_output)() begins output (e.g. writes a header)., * The function (*init_input)() begins input (e.g. skips a header). * * There are different versions of input, output, init_input and init_output * for different formats understood by toast; which ones are used * depends on the command line arguments and, in their absence, the * filename; the fallback is #defined in toast.h * * The specific implementations of input, output, init_input and init_output * for a format `foo' live in toast_foo.c. */int (*output ) P((gsm_signal *)), (*input ) P((gsm_signal *));int (*init_input) P((void)), (*init_output) P((void));static int generic_init P0() { return 0; } /* NOP */struct fmtdesc { char * name, * longname, * suffix; int (* init_input ) P((void)), (* init_output) P((void)); int (* input ) P((gsm_signal * )), (* output) P((gsm_signal * ));} f_audio = { "audio", "8 kHz, 8 bit u-law encoding with Sun audio header", ".au", audio_init_input, audio_init_output, ulaw_input, ulaw_output}, f_ulaw = { "u-law", "plain 8 kHz, 8 bit u-law encoding", ".u", generic_init, generic_init, ulaw_input, ulaw_output }, f_alaw = { "A-law", "8 kHz, 8 bit A-law encoding", ".A", generic_init, generic_init, alaw_input, alaw_output}, f_linear = { "linear", "16 bit (13 significant) signed 8 kHz signal", ".l", generic_init, generic_init, linear_input, linear_output};struct fmtdesc * alldescs[] = { &f_audio, &f_alaw, &f_ulaw, &f_linear, (struct fmtdesc *)NULL};#define DEFAULT_FORMAT f_ulaw /* default audio format, others */ /* are: f_alaw,f_audio,f_linear */struct fmtdesc * f_format = 0;/* * basename + suffix of a pathname */static char * endname P1((name), char * name){ if (name) { char * s = strrchr(name, '/'); if (s && s[1]) name = s + 1; } return name;}/* * Try to figure out what we're supposed to do from the argv[0], if * any, and set the parameters accordingly. */static void parse_argv0 P1((av0), char * av0 ){ int l; progname = av0 = endname(av0 ? av0 : "toast"); /* If the name starts with `un', we want to decode, not code. * If the name ends in `cat', we want to write to stdout, * and decode as well. */ if (!strncmp(av0, "un", 2)) f_decode = 1; if ( (l = strlen(av0)) >= 3 /* strlen("cat") */ && !strcmp( av0 + l - 3, "cat" )) f_cat = f_decode = 1;}/* * Check whether the name (possibly generated by appending * .gsm to something else) is short enough for this system. */static int length_okay P1((name), char * name){ long max_filename_length = 0; char * end; /* If our _pathname_ is too long, we'll usually not be * able to open the file at all -- don't worry about that. * * But if the _filename_ is too long, there is danger of * silent truncation on some systems, which results * in the target replacing the source! */ if (!name) return 0; end = endname(name);#ifdef NAME_MAX max_filename_length = NAME_MAX;#else#ifdef _PC_NAME_MAX#ifdef USE_PATHCONF { char * s, tmp; /* s = dirname(name) */ if ((s = end) > name) { if (s > name + 1) s--; tmp = s; *s = 0; } errno = 0; max_filename_length = pathconf(s > name ? name : ".", _PC_NAME_MAX); if (max_filename_length == -1 && errno) { perror( s > name ? name : "." ); fprintf(stderr, "%s: cannot get dynamic filename length limit for %s.\n", progname, s > name ? name : "."); return 0; } if (s > name) *s = tmp; }#endif /* USE_PATHCONF */#endif /* _PC_NAME_MAX */#endif /* !NAME_MAX */ if (max_filename_length > 0 && strlen(end) > max_filename_length) { fprintf(stderr, "%s: filename \"%s\" is too long (maximum is %ld)\n", progname, endname(name), max_filename_length ); return 0; } return 1;}/* * Return a pointer the suffix of a string, if any. * A suffix alone has no suffix, an empty suffix can not be had. */static char * suffix P2((name, suf), char *name, char * suf) { size_t nlen = strlen(name); size_t slen = strlen(suf); if (!slen || nlen <= slen) return (char *)0; name += nlen - slen; return memcmp(name, suf, slen) ? (char *)0 : name;}static void catch_signals P1((fun), SIGHANDLER_T (*fun) ()) {#ifdef SIGHUP signal( SIGHUP, fun );#endif#ifdef SIGINT signal( SIGINT, fun );#endif#ifdef SIGPIPE signal( SIGPIPE, fun );#endif#ifdef SIGTERM signal( SIGTERM, fun );#endif#ifdef SIGXFSZ signal( SIGXFSZ, fun );#endif}static SIGHANDLER_T onintr P0(){ char * tmp = outname;#ifdef HAS_SYSV_SIGNALS catch_signals( SIG_IGN );#endif outname = (char *)0; if (tmp) (void)unlink(tmp); exit(1);}/* * Allocate some memory and complain if it fails. */static char * emalloc P1((len), size_t len){ char * s; if (!(s = malloc(len))) { fprintf(stderr, "%s: failed to malloc %d bytes -- abort\n", progname, len); onintr(); exit(1); } return s;}static char* normalname P3((name, want, cut), char *name, char *want,char *cut){ size_t maxlen; char * s, * p; p = (char *)0; if (!name) return p; maxlen = strlen(name) + 1 + strlen(want) + strlen(cut); p = strcpy(emalloc(maxlen), name); if (s = suffix(p, cut)) strcpy(s, want); else if (*want && !suffix(p, want)) strcat(p, want); return p;}/* * Generate a `plain' (non-encoded) name from a given name. */static char * plainname P1((name), char *name){ return normalname(name, "", SUFFIX_TOASTED );}/* * Generate a `code' name (foo.Z) from a given name. */static char * codename P1((name), char *name){ return normalname( name, SUFFIX_TOASTED, "" );}/* * If we're supposed to ask (fileno (stderr) is a tty, and f_force not * set), ask the user whether to overwrite a file or not. */static int ok_to_replace P1(( name ), char * name){ int reply, c; if (f_force) return 1; /* YES, do replace */ if (!isatty(fileno(stderr))) return 0; /* NO, don't replace */ fprintf(stderr, "%s already exists; do you wish to overwrite %s (y or n)? ", name, name); fflush(stderr); for (c = reply = getchar(); c != '\n' && c != EOF; c = getchar()) ; if (reply == 'y') return 1; fprintf(stderr, "\tnot overwritten\n"); return 0;}static void update_mode P0(){ if (!instat.st_nlink) return; /* couldn't stat in */#ifdef HAS_FCHMOD if (fchmod(fileno(out), instat.st_mode & 07777)) { perror(outname); fprintf(stderr, "%s: could not change file mode of \"%s\"\n", progname, outname); }#else if (outname && chmod(outname, instat.st_mode & 07777)) { perror(outname); fprintf(stderr, "%s: could not change file mode of \"%s\"\n", progname, outname); }#endif /* HAS_FCHMOD */}static void update_own P0(){ if (!instat.st_nlink) return; /* couldn't stat in */#ifdef HAS_FCHOWN (void)fchown(fileno(out), instat.st_uid, instat.st_gid);#else /* (void)chown(outname, instat.st_uid, instat.st_gid);*/#endif /* HAS_FCHOWN */}static void update_times P0(){ if (!instat.st_nlink) return; /* couldn't stat in */#ifdef HAS_UTIMES if (outname) { struct timeval tv[2]; tv[0].tv_sec = instat.st_atime; tv[1].tv_sec = instat.st_mtime; tv[0].tv_usec = tv[1].tv_usec = 0; (void) utimes(outname, tv); }#else#ifdef HAS_UTIME if (outname) {#ifdef HAS_UTIMBUF struct utimbuf ut; ut.actime = instat.st_atime; ut.modtime = instat.st_mtime;# ifdef HAS_UTIMEUSEC ut.acusec = instat.st_ausec; ut.modusec = instat.st_musec;# endif /* HAS_UTIMEUSEC */ (void) utime(outname, &ut);#else /* UTIMBUF */ time_t ut[2]; ut[0] = instat.st_atime;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -