home *** CD-ROM | disk | FTP | other *** search
- /*
- * xscale.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /*
- * XSCALE
- *
- * test scale.c module
- * NOTE: This program is adapted from a fast image
- * scaling algorithm published in the April, 1997, 1998, 1999 MLMSoftwareGroup, LLCe
- * of Doctor Dobb's Journal and is used with permission
- * from the publisher.
- *
- */
-
- #include "xscale.h"
-
- extern short tiffInput; /* flag=0 if no ImageIn to set tags; else =1 */
- extern char *optarg;
- extern int optind, opterr;
-
- /*
- * usage of routine
- */
- void
- usage (char *progname)
- {
- progname = last_bs (progname);
- printf ("USAGE: %s inimg outimg x_scale y_scale [-L]\n", progname);
- printf ("\n%s scales the input image by fast integer interpolation\n", progname);
- printf ("and wrtes the scaled image to the specified output file\n\n");
- printf ("ARGUMENTS:\n");
- printf (" inimg: input image filename (TIF)\n");
- printf (" outimg: output image filename (TIF)\n");
- printf (" x_scale: scaling factor for x-axis (float) >= 0.0\n");
- printf (" y_scale: scaling factor for y-axis (float) >= 0.0\n\n");
- printf ("OPTIONS:\n");
- printf (" -L: print Software License for this module\n");
- exit (1);
- }
-
- void
- scale (Image * imgIn, Image * imgOut, double xscale, double yscale)
- {
- int x, y;
- int ddax, dday, xzoom, yzoom, i, j, k, yline;
- unsigned char **image_in, **image_out; /* input/output image */
-
- image_in = imgIn->img;
- image_out = imgOut->img;
-
- /* Calculate the differential amount */
- xzoom = (int) (1.0 / xscale * 1000);
- yzoom = (int) (1.0 / yscale * 1000);
- /* Initialize the output Y value and vertial differential */
- y = 0;
- dday = 0;
- /* Loop over rows in the original image */
- for (i = 0; i < imgIn->height; i++) {
- /* Adjust the vertical accumulated differential, initialize the
- * output X pixel and horizontal accumulated differential */
- dday -= 1000;
- x = 0;
- ddax = 0;
- /* Loop over pixels in the original image */
- for (j = 0; j < imgIn->width; j++) {
- /* Adjust the horizontal accumulated differential */
- ddax -= 1000;
- while (ddax < 0) {
- /* Store values from original image scanline into the scaled
- * buffer until accumulated differential crosses threshold */
- image_out[y][x] = (unsigned char) image_in[i][j];
- x++;
- ddax += xzoom;
- }
- }
- yline = y;
- while (dday < 0) {
- /* The 'outer loop' -- output resized scan lines until the
- * vertical threshold is crossed */
- dday += yzoom;
- for (k = 0; k < x; k++) {
- image_out[y][k] = (unsigned char) image_out[yline][k];
- }
- y++;
- if (y >= imgOut->height)
- y = imgOut->height - 1;
- }
- }
- }
-
- int
- main (int argc, char *argv[])
- {
-
- Image *imgIn, *imgOut;
- float xscale, yscale;
- int i_arg;
-
- /*
- * cmd line options:
- */
- static char *optstring = "L";
-
- if (argc < 5)
- usage (argv[0]);
-
- /*
- * parse command line
- */
- optind = 5;
- opterr = ON; /* give error messages */
-
- while ((i_arg = getopt (argc, argv, optstring)) != EOF) {
- switch (i_arg) {
- case 'L':
- print_sos_lic ();
- exit (0);
- default:
- usage (argv[0]);
- break;
- }
- }
-
- if (!sscanf (argv[3], "%f", &xscale) || xscale <= 0.0) {
- printf ("\nSomething wrong with x scale factor!!!\n");
- usage (argv[0]);
- }
- if (!sscanf (argv[4], "%f", &yscale) || yscale <= 0.0) {
- printf ("\nSomething wrong with y scale factor!!!\n");
- usage (argv[0]);
- }
-
- /*
- * read input image
- */
- imgIn = ImageIn (argv[1]);
- if (imgIn->bps == 8 && imgIn->spp == 3) {
- printf ("Got RGB image!!!\nInput image must be Grayscale or B&W!!\n");
- exit (1);
- }
- /* reset tiffInput so that we write a grayscale file (i.e tags are not copied) */
- tiffInput = 0;
- /*
- * Allocate memory for output image
- */
- imgOut = ImageAlloc ((int) (yscale * imgIn->height), (int) (xscale * imgIn->width), imgIn->bps);
-
- /*
- * Do the scaling
- */
- scale (imgIn, imgOut, (double) xscale, (double) yscale);
- /*
- * Write the output image
- */
- ImageOut (argv[2], imgOut);
- return (1);
- }
-