Пример #1
0
int
main(int ac, char **av)
{
	int	x;
	char	*file = (char *)NULL;
	pid_t	pid = 0;
	int	uucpstyle = FALSE;	/* indicating UUCP style locks */
	int	only_check = TRUE;	/* don't make a lock */

	Pname = ((Pname = strrchr(av[0], '/')) ? Pname + 1 : av[0]);

	for(x = 1; x < ac; x++) {
		if (av[x][0] == '-') {
			switch(av[x][1]) {
			case 'u':
				uucpstyle = TRUE;
				break;
			case 'd':
				Debug = TRUE;
				break;
			case 'p':
				if (strlen(av[x]) > 2) {
					pid = atoi(&av[x][2]);
				} else {
					if (++x >= ac) {
						bad_usage();
					}
					pid = atoi(av[x]);
				}
				only_check = FALSE;	/* wants one */
				break;
			case 'f':
				if (strlen(av[x]) > 2) {
					file = &av[x][2];
				} else {
					if (++x >= ac) {
						bad_usage();
					}
					file = av[x];
				}
				break;
			default:
				bad_usage();
			}
		}
	}

	if (file == (char *)NULL || (!only_check && pid <= 0)) {
		bad_usage();
	}

	if (only_check) {
		exit(cklock(file, uucpstyle) ? LOCK_GOOD : LOCK_BAD);
	}

	exit(mklock(file, pid, uucpstyle) ? LOCK_SET : LOCK_FAIL);
}
Пример #2
0
/* public api */
void parse_options(int argc, char **argv)
{
    int opt;

    setup_default_config(&config);
    while((opt = getopt_long(argc, argv, "+p:nhvV", long_options, NULL)) != -1) {
        switch(opt) {
            case 'p':
                set_prefix(optarg);
                break;
            case 'v':
                config.is_verbose++;
                break;
            case 'h':
                print_usage(argv[0]);
                exit(0);
                break;
            case 'V':
                print_version();
                exit(0);
                break;
            case 'n':
                config.no_hide = 1;
                break;
            case 's':
                config.stub = 1;
                break;
            default:
                bad_usage(argv[0]);
                exit(-1);
        }
    }

    if (argc - optind != 2) {
        bad_usage(argv[0]);
        exit(-1);
    }

    /* if no prefix is given we use a default prefix build on output name */
    if (!config.prefix && argv[optind + 1]) {
        char *bn = basename(strdup(argv[optind + 1]));
        char *last_dot = rindex(bn, '.');

        if (last_dot)
            *last_dot = '\0';
        config.prefix = strcat(bn, "_");
    }
}
Пример #3
0
int main(int argc, char** argv)
{
	char *executable, *path;
	char *resolved_location;
	char **real_argv;
	size_t name_arg;
	const char *ignore_prefix = NULL;
	const char *home;
	char *replace_dir;
	bool use_basename = false;
	
	program_name = strrchr(argv[0], '/');
	if (program_name == NULL) {
		program_name = argv[0];
	} else {
		++program_name;
	}
	
	home = getenv("HOME");
	if (home == NULL) {
		fatal_error("HOME is not defined");
	}
	
	{
		size_t home_len = strlen(home);
		size_t replace_len = home_len + 1 + strlen(REPLACE_COMMAND_DIR);
		replace_dir = xmalloc(replace_len + 1);
		memcpy(replace_dir, home, home_len);
		replace_dir[home_len] = '/';
		memcpy(replace_dir + home_len + 1, REPLACE_COMMAND_DIR,
		       strlen(REPLACE_COMMAND_DIR));
		replace_dir[replace_len] = '\0';
	}
	
	for (name_arg = 1; name_arg != argc; ++name_arg) {
		const char *arg = argv[name_arg];
		if (arg[0] == '\0') {
			bad_usage("Empty executable name argument");
		}
		if (arg[0] == '-') {
			if (0 == strcmp(arg, "--ignore-home")) {
				ignore_prefix = home;

			} else if (0 == strcmp(arg, "--use-basename")) {
				use_basename = true;

			} else if (0 == strcmp(arg, "--help")) {
				show_usage(replace_dir);

			} else if (0 == strcmp(arg, "--version")) {
				show_version(replace_dir);

			} else if (0 == strcmp(arg, "--")) {
				++name_arg;
				break;
			
			} else {
				bad_usage("Unknown option '%s'", arg);
			}
			 
			continue;
		}
		break;
	}

	if (name_arg == argc) {
		bad_usage("Missed executable name argument");
	}
	
	executable = argv[name_arg];
	if (!use_basename) {
		if (strchr(executable, '/') != NULL) {
			bad_usage("Execute name should not contain '/': %s",
				executable);
		}
	} else {
		char* last_slash = strrchr(executable, '/');
		if (last_slash != NULL) {
			executable = last_slash + 1;
		}
	}
	
	path = getenv("PATH");
	if (path == NULL || path[0] == '\0') {
		fatal_error("$PATH is not defined");
	}
	
	resolved_location = locate_next_exec(
		path, replace_dir, executable, ignore_prefix);
		
	real_argv = xmalloc(sizeof(real_argv[0]) * (argc - name_arg + 1));
	real_argv[0] = executable;
	memcpy(real_argv + 1, argv + name_arg + 1, 
		sizeof(real_argv[0]) * (argc - name_arg - 1));
	real_argv[argc - name_arg] = NULL;

	execv(resolved_location, real_argv);
	fatal_error("Failed to execute '%s': %s", resolved_location, strerror(errno));

	return 0;
}
Пример #4
0
int main(int argc, char *argv[])
{
	const char *home;
	char chanfile[2 * PATH_MAX];
	int list_channels = 0;
	unsigned int chan_no = 0;
	const char *chan_name = NULL;
	unsigned int adapter = 0, frontend = 0, demux = 0, dvr = 0, rec_psi = 0;
	int bypass = 0;
	int opt, copt = 0;
	int human_readable = 0;

	lnb_type = *lnb_enum(0);

	while ((opt = getopt(argc, argv, "Hhqrpn:a:f:d:c:l:xib")) != -1) {
		switch (opt) {
		case '?':
		case 'h':
		default:
			bad_usage(argv[0], 0);
		case 'b':
			bypass = 1;
			break;
		case 'q':
			list_channels = 1;
			break;
		case 'r':
			dvr = 1;
			break;
		case 'n':
			chan_no = strtoul(optarg, NULL, 0);
			break;
		case 'a':
			adapter = strtoul(optarg, NULL, 0);
			break;
		case 'f':
			frontend = strtoul(optarg, NULL, 0);
			break;
		case 'p':
			rec_psi = 1;
			break;
		case 'd':
			demux = strtoul(optarg, NULL, 0);
			break;
		case 'c':
			copt = 1;
			strncpy(chanfile, optarg, sizeof(chanfile));
			break;
		case 'l':
			if (lnb_decode(optarg, &lnb_type) < 0) {
				bad_usage(argv[0], 1);
				return -1;
			}
			break;
		case 'x':
			exit_after_tuning = 1;
			break;
		case 'H':
			human_readable = 1;
			break;
		case 'i':
			interactive = 1;
			exit_after_tuning = 1;
		}
	}
	lnb_type.low_val *= 1000;	/* convert to kiloherz */
	lnb_type.high_val *= 1000;	/* convert to kiloherz */
	lnb_type.switch_val *= 1000;	/* convert to kiloherz */

	if (optind < argc)
		chan_name = argv[optind];

	if (chan_name && chan_no) {
		bad_usage(argv[0], 0);
		return -1;
	}
	if (list_channels && (chan_name || chan_no)) {
		bad_usage(argv[0], 0);
		return -1;
	}
	if (!list_channels && !chan_name && !chan_no && !interactive) {
		bad_usage(argv[0], 0);
		return -1;
	}

	if (!copt) {
		if (!(home = getenv("HOME"))) {
			fprintf(stderr, "error: $HOME not set\n");
			return TRUE;
		}
		snprintf(chanfile,
			 sizeof(chanfile),
			 "%s/.szap/%i/%s",
	   		 home,
	   		 adapter,
	   		 CHANNEL_FILE);

		if (access(chanfile, R_OK))
			snprintf(chanfile,
				 sizeof(chanfile),
				 "%s/.szap/%s",
	    			 home,
	    			 CHANNEL_FILE);
	}
	printf("reading channels from file '%s'\n", chanfile);

	if (rec_psi)
		dvr=1;

	if (!read_channels(chanfile,
			   list_channels,
		    	   chan_no,
		    	   chan_name,
			   adapter,
		    	   frontend,
		    	   demux,
		    	   dvr,
		    	   rec_psi,
		    	   bypass,
		    	   human_readable))
		return TRUE;

	return FALSE;
}
Пример #5
0
int main(int argc, char **argv)
{
    program_name = argv[0];
    char *test_dir = NULL;

    bool base_failures = false;
    bool retest_failures = false;
    bool show_output = false;
    char opt;
    while ((opt = getopt(argc, argv, "bfhot:")) != -1) {
        switch (opt) {
          case 'b':
            base_failures = true;
            break;
          case 'f':
            retest_failures = true;
            break;
          case 'o':
            show_output = true;
            break;
          case 'h':
            usage();
          case 't':
            free(test_dir);
            test_dir = xstrdup(optarg);
          default:
            bad_usage(NULL);
        }
    }
    if (optind == argc)
        bad_usage("missing BUILD_DIR argument");
    char *build_dir = argv[optind];
        
    if (optind + 1 < argc)
        bad_usage("too many arguments");
        
    if (base_failures && retest_failures)
        bad_usage("only one of -b or -f can be given");

    if (!test_dir)
        test_dir = home_path(test_dir_path);
    
    if (chdir(build_dir))
        perror_and_abort();

    char *exec_args[9];
    size_t n = 0;
    char *test_driver = concat_path(test_dir, "jstests.py");
    exec_args[n++] = test_driver;
    exec_args[n++] = test_driver;
    exec_args[n++] = "--timeout=20";
    if (retest_failures) {
        exec_args[n++] = xasprintf("--file=%s/%s", build_dir, "failures.txt");
    } else if (base_failures){
        exec_args[n++] = xasprintf("--failure-file=%s/%s", build_dir, "base_failures.txt");
    } else {
        exec_args[n++] = xasprintf("--failure-file=%s/%s", build_dir, "failures.txt");
        exec_args[n++] = xasprintf("--exclude-file=%s/%s", build_dir, "base_failures.txt");
    }
    if (show_output) {
        exec_args[n++] = "-s";
        exec_args[n++] = "-o";
    }
    exec_args[n++] = xasprintf("%s/%s", build_dir, "js");
    exec_args[n++] = NULL;

    assert(n <= sizeof(exec_args) / sizeof(exec_args[0]));

    execvp("python", exec_args);
    perror_and_abort();
}
Пример #6
0
/**
 * basic options needed
 * @adapter
 * @frontend
 * @freq (Mhz)
 * @pol (13/18)
 * @srate (kSps)
 * @pos (0 - 3)
 * @LNB (low, high, switch) Mhz
 *
 */
int main(int argc, char *argv[])
{
	int opt;
	int ret, fd, adapter=0, frontend=0, pos;
	int simple;
	struct lnb_types_st lnb;
	struct sec_params sec;

	memset(&sec, 0, sizeof(sec));

	lnb = lnbs[0]; /* default is Universal LNB */
	while ((opt = getopt(argc, argv, "Hh:a:f:p:s:l:")) != -1) {
		switch (opt) {
		case '?':
		case 'h':
		default: /* help */
			bad_usage(argv[0], 0);
			break;
		case 'a': /* adapter */
			adapter = strtoul(optarg, NULL, 0);
			break;
		case 'f': /* demodulator (device) */
			frontend = strtoul(optarg, NULL, 0);
			break;
		case 'p': /* parameters */
			if (params_decode(optarg, argv, &sec) < 0) {
				bad_usage(argv[0], 1);
				return -1;
			}
			break;
		case 's': /* diseqc position */
			pos = strtoul(optarg, NULL, 0);
			pos % 2 ? (sec.burst = SEC_MINI_B) : (sec.burst = SEC_MINI_A);
			break;
		case 'l':
			if (lnb_parse(optarg, &lnb) < 0) {
				bad_usage(argv[0], 1);
				return -1;
			}
			break;
		case 'H':
			simple = 1; /* human readable */
			break;
		}
	}
	lnb.low_val	*= 1000; /* kHz */
	lnb.high_val	*= 1000; /* kHz */
	lnb.switch_val	*= 1000; /* kHz */

	sec.freq *= 1000; /* kHz */
	sec.srate *= 1000;

	ret = frontend_open(&fd, adapter, frontend);
	if (ret < 0) {
		fprintf(stderr, "Adapter:%d Frontend:%d open failed, err=%d\n", adapter, frontend, ret);
		return -1;
	}
	ret = lnb_setup(&lnb, &sec);
	if (ret < 0) {
		fprintf(stderr, "LNB setup failed, err=%d\n", ret);
		fprintf(stderr, "%s", usage_str);
		goto err;
	}

	ret = diseqc_setup(fd, &sec);
	if (ret < 0) {
		fprintf(stderr, "SEC setup failed, err=%d\n", ret);
		goto err;;
	}

	ret = tune_to(fd, &sec);
	if (ret < 0) {
		fprintf(stderr, "Adapter:%d Frontend:%d tune_to %d %d failed, err=%d\n", adapter, frontend, sec.freq, sec.srate, ret);
		goto err;;
	}

	ret = check_frontend(fd, 1);
	if (ret < 0) {
		fprintf(stderr, "check frontend failed\n");
		goto err;;
	}
err:
	return ret;
}
int main(int argc, char **argv) {
    struct jpeg_decompress_struct dinfo;
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;

    char *file1;   /* input filename */
    char *file2;   /* output filename */
    FILE *fh1;     /* input file handle */
    FILE *fh2;     /* output file handle */
    float *data;   /* partially-convolved rows in 4-tuples: r, g, b, sum */
    float **ptrs;  /* pointers into input buffer, one for each scanline */
    JSAMPLE *line; /* input/output buffer */
    float *fx,*fy; /* convolution kernel cache */
    int mode;      /* resize mode (see M_SET_SIZE, etc.) */
    int quality;   /* jpeg quality: 0 to 100 */
    int len;       /* length of one line in data */
    int w1, h1, z1; /* size of input image */
    int w2, h2;    /* size of output image */
    int w3, h3;    /* size of convolution kernel */
    int xo, yo;    /* number of cols/rows to side of center of kernel */
    int y1, n1;    /* first row and number of rows loaded into input buffer */
    int yc;        /* last row loaded from input file */
    int x2, y2;    /* current location in output image */
    float ox, oy;  /* offset of origin in input image */
    float sx, sy;  /* amount to scale horizontal and vertical */
    float xf, yf;  /* corresponding location in input image */
    float ax, ay;  /* constants needed for Lanczos kernel */
    float extra;   /* multiply kernel radius by this to get extra lobes */
    int kernel;    /* boolean: dump convolution kernel and abort? */
    int verbose;   /* boolean: verbose mode? */

    /* Temporary variables. */
    float *ptr1, *ptr2, *ptr3;
    JSAMPLE *ptr4;
    int x, y, i, j, k, c;
    float f, r, g, b, s, *accum;

    /* Print help message. */
    if (argc <= 1 || get_flag(argv, &argc, "-h", "--help")) {
        printf("\n");
        printf("USAGE\n");
        printf("    %s\n", USAGE);
        printf("\n");
        printf("OPTIONS\n");
        printf("    <w>x<h>             Width and height of output image, e.g., '200x200'.\n");
        printf("    <input.jpg>         Input image.  Must be 'normal' RGB color JPEG.\n");
        printf("    <output.jpg>        Output image.  Clobbers any existing file.\n");
        printf("\n");
        printf("    --set-size          Default mode: set to given size, ignoring aspect ratio.\n");
        printf("    --set-area          Keep aspect ratio, reducing/enlarging to area of given box.\n");
        printf("    --max-size          Keep aspect ratio, reducing to within given box.\n");
        printf("    --max-area          Keep aspect ratio, reducing to area of given box.\n");
        printf("    --min-size          Keep aspect ratio, enlarging to contain given box.\n");
        printf("    --min-area          Keep aspect ratio, enlarging to area of given box.\n");
        printf("    --crop              Reduce/enlarge, cropping to get correct ratio.\n");
        printf("\n");
        printf("    -q --quality <pct>  JPEG quality of output image; default depends on size.\n");
        printf("    -r --radius <n>     Radius of convolution kernel, > 0; default is 1.0.\n");
        printf("    -s --sharp <n>      Amount to sharpen output, >= 0; default is 0.2.\n");
        printf("\n");
        printf("    --flat              Average pixels within box of given radius.\n");
        printf("    --linear            Weight pixels within box linearly by closeness.\n");
        printf("    --hermite           Hermite cubic spline filter; similar to Gaussian.\n");
        printf("    --catrom [<M>]      Catmull-Rom cubic spline; default is M = 0.5 at R = 1.\n");
        printf("    --mitchell          Mitchell-Netravali filter (see Keys filter).\n");
        printf("    --keys [<B> <C>]    Keys family filters; default is B = C = 1/3 (Mitchell).\n");
        printf("    --lanczos [<N>]     Lanczos windowed sinc filter; default is N = 3 lobes.\n");
        printf("\n");
        printf("    -h --help           Print this message.\n");
        printf("    -v --verbose        Verbose / debug mode.\n");
        printf("    -k --kernel         Dump convolution kernel without processing image.\n");
        printf("\n");
        exit(1);
    }

    /* Get command line args. */
    get_size(argv, &argc, &w2, &h2);
    quality = get_value(argv, &argc, "-q", "--quality", default_quality(w2, h2));
    radius  = get_value(argv, &argc, "-r", "--radius", 1.0);
    sharp   = get_value(argv, &argc, "-s", "--sharp", 0.2);
    verbose = get_flag(argv, &argc, "-v", "--verbose");
    kernel  = get_flag(argv, &argc, "-k", "--kernel");

    /* Only allowed one mode flag. */
    mode = get_flag(argv, &argc, "--set-size", 0) ? M_SET_SIZE :
           get_flag(argv, &argc, "--max-size", 0) ? M_MAX_SIZE :
           get_flag(argv, &argc, "--min-size", 0) ? M_MIN_SIZE :
           get_flag(argv, &argc, "--set-area", 0) ? M_SET_AREA :
           get_flag(argv, &argc, "--max-area", 0) ? M_MAX_AREA :
           get_flag(argv, &argc, "--min-area", 0) ? M_MIN_AREA :
           get_flag(argv, &argc, "--crop",     0) ? M_CROP     : M_SET_SIZE;

    /* Each filter type takes different arguments. */
    if (get_filter(argv, &argc, "--flat", 0, 0, 0)) {
        filter = F_FLAT;
        extra  = 1.0;
    } else if (get_filter(argv, &argc, "--linear", 0, 0, 0)) {
        filter = F_LINEAR;
        extra  = 1.0;
    } else if (get_filter(argv, &argc, "--hermite", 0, 0, 0)) {
        filter = F_HERMITE;
        extra  = 1.0;
    } else if (get_filter(argv, &argc, "--catrom",   1, 1.0, 0.0)) {
        filter = F_CATROM;
        extra  = 2.0;
    } else if (get_filter(argv, &argc, "--mitchell", 0, 0.0, 0.0)) {
        filter = F_KEYS;
        extra  = 2.0;
        arg1   = 1.0 / 3.0;
        arg2   = 1.0 / 3.0;
    } else if (get_filter(argv, &argc, "--keys",     2, 1.0/3.0, 1.0/3.0)) {
        filter = F_KEYS;
        extra  = 2.0;
    } else if (get_filter(argv, &argc, "--lanczos",  1, 3.0, 0.0)) {
        filter = F_LANCZOS;
        extra  = arg1;
    } else {
        filter = F_LANCZOS;
        arg1   = 3.0;
        extra  = arg1;
    }

    /* Get files last because they complain if there are any flags left. */
    file1 = get_file(argv, &argc);
    file2 = get_file(argv, &argc);
    if (argc > 1) bad_usage("unexpected argument: %s", argv[1]);

    /* Create and initialize decompress object. */
    dinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&dinfo);
    if ((fh1 = fopen(file1, "rb")) == NULL) {
        fprintf(stderr, "can't open %s for reading\n", file1);
        exit(1);
    }
    jpeg_stdio_src(&dinfo, fh1);

    /* Get dimensions and format of input image. */
    jpeg_read_header(&dinfo, TRUE);
    jpeg_start_decompress(&dinfo);
    w1 = dinfo.output_width;
    h1 = dinfo.output_height;
    z1 = dinfo.output_components;

    /* Choose output size. */
    if (mode == M_SET_SIZE) {
        /* leave as is */
        sx = (double)w2 / w1;
        sy = (double)h2 / h1;
        ox = oy = 0.0;
    } else if (mode == M_MAX_SIZE) {
        if (w1 > w2 && h1 * w2 / w1 < h2) {
            sx = sy = (double)w2 / w1;
            h2 = sy * h1 + 0.5;
        } else if (h1 > h2) {
            sx = sy = (double)h2 / h1;
            w2 = sx * w1 + 0.5;
        } else {
            sx = sy = 1.0;
            w2 = w1;
            h2 = h1;
        }
        ox = oy = 0.0;
    } else if (mode == M_MIN_SIZE) {
        if (w1 < w2 && h1 * w2 / w1 > h2) {
            sx = sy = (double)w2 / w1;
            h2 = sy * h1 + 0.5;
        } else if (h1 < h2) {
            sx = sy = (double)h2 / h1;
            w2 = sx * w1 + 0.5;
        } else {
            sx = sy = 1.0;
            w2 = w1;
            h2 = h1;
        }
        ox = oy = 0.0;
    } else if (mode == M_SET_AREA) {
        sx = sy = sqrt(((double)w2) * h2 / w1 / h1);
        w2 = sx * w1 + 0.5;
        h2 = sy * h1 + 0.5;
        ox = oy = 0.0;
    } else if (mode == M_MAX_AREA) {
        if (w1 * h1 > w2 * h2) {
            sx = sy = sqrt(((double)w2) * h2 / w1 / h1);
            w2 = sx * w1 + 0.5;
            h2 = sy * h1 + 0.5;
        } else {
            sx = sy = 1.0;
            w2 = w1;
            h2 = h1;
        }
        ox = oy = 0.0;
    } else if (mode == M_MIN_AREA) {
        if (w1 * h1 < w2 * h2) {
            sx = sy = sqrt(((double)w2) * h2 / w1 / h1);
            w2 = sx * w1 + 0.5;
            h2 = sy * h1 + 0.5;
        } else {
            sx = sy = 1.0;
            w2 = w1;
            h2 = h1;
        }
        ox = oy = 0.0;
    } else if (mode == M_CROP) {
        sx = (double)w2 / w1;
        sy = (double)h2 / h1;
        sx = sy = sx > sy ? sx : sy;
        ox = ((double)w1 - (double)w2 / sx) * 0.5;
        oy = ((double)h1 - (double)h2 / sy) * 0.5;
    } else {
        fprintf(stderr, "invalid mode: %d!", mode);
        exit(1);
    }

    if (verbose) {
        fprintf(stderr, "input:   %dx%d (%d) %s\n", w1, h1, z1, file1);
        fprintf(stderr, "output:  %dx%d (%d) %s\n", w2, h2, z1, file2);
        if (sx > 1.0 && sy > 1.0)
            fprintf(stderr, "enlarge: %.2f %.2f\n", sx*1.0, sy*1.0);
        else
            fprintf(stderr, "reduce:  %.2f %.2f\n", 1.0/sx, 1.0/sy);
        fprintf(stderr, "origin:  %.2f %.2f\n", ox, oy);
        fprintf(stderr, "quality: %d\n", quality);
        fprintf(stderr, "radius:  %f\n", radius);
        fprintf(stderr, "sharp:   %f\n", sharp);
        if (filter == F_FLAT)    fprintf(stderr, "filter:  flat\n");
        if (filter == F_LINEAR)  fprintf(stderr, "filter:  bilinear\n");
        if (filter == F_HERMITE) fprintf(stderr, "filter:  hermite\n");
        if (filter == F_CATROM)  fprintf(stderr, "filter:  Catmull-Rom (M=%f)\n", arg1);
        if (filter == F_KEYS)    fprintf(stderr, "filter:  Keys-family (B=%f, C=%f)\n", arg1, arg2);
        if (filter == F_LANCZOS) fprintf(stderr, "filter:  Lanczos (N=%f)\n", arg1);
    }

    /* Calculate size of convolution kernel. */
    ax = sx < 1 ? radius / sx : radius;
    ay = sy < 1 ? radius / sy : radius;
    xo = (int)(ax * extra + 0.5);
    yo = (int)(ay * extra + 0.5);
    w3 = xo + xo + 1;
    h3 = yo + yo + 1;

    /* Pre-calculate coefficients for Keys-family filters. */
    if (filter == F_CATROM) {
        filter = F_KEYS;
        c1 = 2.0 - arg1;
        c2 = -3.0 + arg1;
        c3 = 0.0;
        c4 = 1.0;
        c5 = -arg1;
        c6 = 2.0 * arg1;
        c7 = -arg1;
        c8 = 0.0;
    } else if (filter == F_KEYS) {
        c1 = ( 12.0 + -9.0 * arg1 +  -6.0 * arg2) / 6.0;
        c2 = (-18.0 + 12.0 * arg1 +   6.0 * arg2) / 6.0;
        c3 = (  0.0 +  0.0 * arg1 +   0.0 * arg2) / 6.0;
        c4 = (  6.0 + -2.0 * arg1 +   0.0 * arg2) / 6.0;
        c5 = (  0.0 + -1.0 * arg1 +  -6.0 * arg2) / 6.0;
        c6 = (  0.0 +  3.0 * arg1 +  12.0 * arg2) / 6.0;
        c7 = (  0.0 + -3.0 * arg1 +  -6.0 * arg2) / 6.0;
        c8 = (  0.0 +  1.0 * arg1 +   0.0 * arg2) / 6.0;
    }

    if (verbose) {
        fprintf(stderr, "w1-h1:   %d %d\n", w1, h1);
        fprintf(stderr, "xo-yo:   %d %d\n", xo, yo);
        fprintf(stderr, "w3-h3:   %d %d\n", w3, h3);
        fprintf(stderr, "ax-ay:  %8.5f %8.5f\n", ax, ay);
        fprintf(stderr, "c1-4:   %8.5f %8.5f %8.5f %8.5f\n", c1, c2, c3, c4);
        fprintf(stderr, "c5-8:   %8.5f %8.5f %8.5f %8.5f\n", c5, c6, c7, c8);
    }

    /* Debug convolution kernel. */
    if (kernel) {
        f = -1;
        for (xf=0; xf<10.0; xf+=0.1) {
            s = calc_factor(xf);
            fprintf(stderr, "%5.2f %7.4f\n", xf, s);
            if (s == 0.0 && f == 0.0)
                break;
            f = s;
        }
        exit(0);
    }

    /* Allocate buffers. */
    len   = w2 * (z1 + 1);
    data  = (float*)malloc(h3 * len * sizeof(float));
    ptrs  = (float**)malloc(h3 * sizeof(float*));
    line  = (JSAMPLE*)malloc((w1 > w2 ? w1 : w2) * z1 * sizeof(JSAMPLE));
    fx    = (float*)malloc(w2 * w3 * sizeof(float));
    fy    = (float*)malloc(h2 * h3 * sizeof(float));
    accum = (float*)malloc(z1 * sizeof(float));

    /* Cache horizontal and vertical components of kernel. */
    for (x2=0, ptr3=fx; x2<w2; x2++) {
        xf = ((float)x2) / sx + ox;
        for (i=0, x=(int)xf-xo; i<w3; i++, x++) {
            *ptr3++ = calc_factor(fabs(xf-x) / ax);
        }
    }
    for (y2=0, ptr3=fy; y2<h2; y2++) {
        yf = ((float)y2) / sy + oy;
        for (i=0, y=(int)yf-yo; i<h3; i++, y++) {
            *ptr3++ = calc_factor(fabs(yf-y) / ay);
        }
    }

    /* Create and initialize compress object. */
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    if ((fh2 = fopen(file2, "wb")) == NULL) {
        fprintf(stderr, "can't open %s for writing\n", file2);
        exit(1);
    }
    jpeg_stdio_dest(&cinfo, fh2);
    cinfo.image_width = w2;
    cinfo.image_height = h2;
    cinfo.input_components = z1;
    switch (z1) {
    case 1:
        cinfo.in_color_space = JCS_GRAYSCALE;
        break;
    case 3:
        cinfo.in_color_space = JCS_RGB;
        break;
    case 4:
        cinfo.in_color_space = JCS_CMYK;
        break;
    default:
        fprintf(stderr, "Not sure what colorspace to make output for input file with %d components.\n", z1);
        exit(1);
    }
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, quality, TRUE);
    jpeg_start_compress(&cinfo, TRUE);

    /* Loop through output rows. */
    n1 = 0;  /* (num lines in buffer) */
    yc = -1; /* (last line loaded) */
    for (y2=0; y2<h2; y2++) {
        yf = ((float)y2) / sy + oy;

        /* Make sure we have the 'yo' rows above and below this row. */
        y = (int)yf - yo;
        if (y - y1 >= h3) n1 = 0;
        ptr1 = n1 ? ptrs[y - y1] : data;
        if (n1) n1 -= y - y1;
        for (i=0; i<h3; i++, y++) {

            /* Move already-loaded lines into place until run out. */
            ptrs[i] = ptr1;
            ptr1 += len;
            if (ptr1 >= data + len * h3) ptr1 = data;

            /* Need to load this line into next available slot. */
            /* It's okay to leave junk in lines outside input image. */
            if (n1-- <= 0 && y >= 0 && y < h1) {

                /* Read lines until get the one we want. */
                for (; yc<y; yc++) {
                    if (!jpeg_read_scanlines(&dinfo, &line, 1)) {
                        fprintf(stderr, "JPEG image corrupted at line %d.\n", yc);
                        exit(1);
                    }
                }

                /* Do horizontal part of convolution now.  Stores a partial
                /* result for each output column for this input row. */
/* ------------------------- start switch 1 on z1 ------------------------- */
                switch (z1) {
                case 1:
                    for (x2=0, ptr2=ptrs[i], ptr3=fx; x2<w2; x2++) {
                        xf = ((float)x2) / sx + ox;
                        r = s = 0;
                        for (j=0, x=(int)xf-xo; j<w3; j++, x++) {
                            f = *ptr3++;
                            if (x >= 0 && x < w1 && fabs(f) > 1e-8) {
                                ptr4 = line + x;
                                r += f * *ptr4++;
                                s += f;
                            }
                        }
                        if (fabs(s) > 1e-3) {
                            *ptr2++ = r;
                            *ptr2++ = s;
                        } else {
                            fprintf(stderr, "x factor near zero -- shouldn't happen!\n");
                            ptr4 = line + (int)xf;
                            *ptr2++ = *ptr4++;
                            *ptr2++ = 1.0;
                        }
                    }
                    break;

                case 3:
                    for (x2=0, ptr2=ptrs[i], ptr3=fx; x2<w2; x2++) {
                        xf = ((float)x2) / sx + ox;
                        r = g = b = s = 0;
                        for (j=0, x=(int)xf-xo; j<w3; j++, x++) {
                            f = *ptr3++;
                            if (x >= 0 && x < w1 && fabs(f) > 1e-8) {
                                ptr4 = line + x + x + x;
                                r += f * *ptr4++;
                                g += f * *ptr4++;
                                b += f * *ptr4++;
                                s += f;
                            }
                        }
                        if (fabs(s) > 1e-3) {
                            *ptr2++ = r;
                            *ptr2++ = g;
                            *ptr2++ = b;
                            *ptr2++ = s;
                        } else {
                            fprintf(stderr, "x factor near zero -- shouldn't happen!\n");
                            ptr4 = line + (int)xf * 3;
                            *ptr2++ = *ptr4++;
                            *ptr2++ = *ptr4++;
                            *ptr2++ = *ptr4++;
                            *ptr2++ = 1.0;
                        }
                    }
                    break;

                default:
                    for (x2=0, ptr2=ptrs[i], ptr3=fx; x2<w2; x2++) {
                        xf = ((float)x2) / sx + ox;
                        for (s=k=0; k<z1; k++)
                            accum[k] = 0;
                        for (j=0, x=(int)xf-xo; j<w3; j++, x++) {
                            f = *ptr3++;
                            if (x >= 0 && x < w1 && fabs(f) > 1e-8) {
                                ptr4 = line + x * z1;
                                for (k=0; k<z1; k++)
                                    accum[k] += f * *ptr4++;
                                s += f;
                            }
                        }
                        if (fabs(s) > 1e-3) {
                            for (k=0; k<z1; k++)
                                *ptr2++ = accum[k];
                            *ptr2++ = s;
                        } else {
                            fprintf(stderr, "x factor near zero -- shouldn't happen!\n");
                            ptr4 = line + (int)xf * z1;
                            for (k=0; k<z1; k++)
                                *ptr2++ = *ptr4++;
                            *ptr2++ = 1.0;
                        }
                    }
                }
/* ------------------------- end switch 1 on z1 ------------------------- */

            }
/* printf("i=%d y2=%d yc=%d y1=%d n1=%d ptrs[i]=%d\n", i, y2, yc, y1, n1, (ptrs[i]-data)/len); */
        }

        /* Now have h3 lines in buffer, starting at y - yo. */
        y1 = (int)yf - yo;
        n1 = h3;

        /* Do vertical part of convolution now.  Finish off calculation for
        /* each output column in this output row by iterating over partial
        /* results for each corresponding input row we calculated above. */
/* ------------------------- start switch 2 on z1 ------------------------- */
        switch (z1) {
        case 1:
            for (x2=0, ptr4=line; x2<w2; x2++) {
                xf = ((float)x2) / sx + ox;
                r = s = 0;
                ptr3 = fy + y2 * h3;
                for (i=0, y=(int)yf-yo; i<h3; i++, y++) {
                    f = *ptr3++;
                    if (y >= 0 && y < h1 && fabs(f) > 1e-8) {
                        ptr1 = ptrs[i] + x2 + x2;
                        r += f * *ptr1++;
                        s += f * *ptr1++;
                    }
/* printf("x2=%d y2=%d i=%d f=%f s=%f (y=%d ptr1=%d)\n", x2, y2, i, f, s, y, (ptr1-data)/len); */
                }
                if (fabs(s) > 1e-3) {
                    *ptr4++ = (c = r / s) > 255 ? 255 : c < 0 ? 0 : c;
                } else {
                    fprintf(stderr, "y factor near zero -- shouldn't happen!\n");
                    ptr1 = ptrs[h3/2] + ((int)xf) * 4;
                    *ptr4++ = *ptr1++;
                }
            }
            break;

        case 3:
            for (x2=0, ptr4=line; x2<w2; x2++) {
                xf = ((float)x2) / sx + ox;
                r = g = b = s = 0;
                ptr3 = fy + y2 * h3;
                for (i=0, y=(int)yf-yo; i<h3; i++, y++) {
                    f = *ptr3++;
                    if (y >= 0 && y < h1 && fabs(f) > 1e-8) {
                        ptr1 = ptrs[i] + x2 * 4;
                        r += f * *ptr1++;
                        g += f * *ptr1++;
                        b += f * *ptr1++;
                        s += f * *ptr1++;
                    }
/* printf("x2=%d y2=%d i=%d f=%f s=%f (y=%d ptr1=%d)\n", x2, y2, i, f, s, y, (ptr1-data)/len); */
                }
                if (fabs(s) > 1e-3) {
                    *ptr4++ = (c = r / s) > 255 ? 255 : c < 0 ? 0 : c;
                    *ptr4++ = (c = g / s) > 255 ? 255 : c < 0 ? 0 : c;
                    *ptr4++ = (c = b / s) > 255 ? 255 : c < 0 ? 0 : c;
                } else {
                    fprintf(stderr, "y factor near zero -- shouldn't happen!\n");
                    ptr1 = ptrs[h3/2] + ((int)xf) * 4;
                    *ptr4++ = *ptr1++;
                    *ptr4++ = *ptr1++;
                    *ptr4++ = *ptr1++;
                }
            }
            break;

        default:
            for (x2=0, ptr4=line; x2<w2; x2++) {
                xf = ((float)x2) / sx + ox;
                for (s=k=0; k<z1; k++)
                    accum[k] = 0;
                ptr3 = fy + y2 * h3;
                for (i=0, y=(int)yf-yo; i<h3; i++, y++) {
                    f = *ptr3++;
                    if (y >= 0 && y < h1 && fabs(f) > 1e-8) {
                        ptr1 = ptrs[i] + x2 * (z1 + 1);
                        for (k=0; k<z1; k++)
                            accum[k] += f * *ptr1++;
                        s += f * *ptr1++;
                    }
/* printf("x2=%d y2=%d i=%d f=%f s=%f (y=%d ptr1=%d)\n", x2, y2, i, f, s, y, (ptr1-data)/len); */
                }
                if (fabs(s) > 1e-3) {
                    for (k=0; k<z1; k++)
                        *ptr4++ = (c = accum[k] / s) > 255 ? 255 : c < 0 ? 0 : c;
                } else {
                    fprintf(stderr, "y factor near zero -- shouldn't happen!\n");
                    ptr1 = ptrs[h3/2] + ((int)xf) * 4;
                    for (k=0; k<z1; k++)
                        *ptr4++ = *ptr1++;
                }
            }
        }
/* ------------------------- end switch 2 on z1 ------------------------- */

        /* Write this output line. */
        jpeg_write_scanlines(&cinfo, &line, 1);
    }

    /* Finish off compression. */
    jpeg_finish_compress(&cinfo);

    /* Clean up. */
    jpeg_destroy_decompress(&dinfo);
    jpeg_destroy_compress(&cinfo);
    free(data);
    free(line);
    free(ptrs);
    free(fx);
    free(accum);
    exit(0);
}