authorRekhesh Mohan <reks@iiap.res.in>
Wed, 11 Jul 2012 21:54:56 +0000 (03:24 +0530)
committerRekhesh Mohan <reks@iiap.res.in>
Wed, 11 Jul 2012 21:54:56 +0000 (03:24 +0530)
README.txt
configure.ac
src/Makefile.am
src/fits2jpeg.c
src/fits2jpeg.h
src/getopt.c
src/image.c
src/messages.c

index 2164ec0..df79f4a 100644 (file)
@@ -80,26 +80,42 @@ file named `INSTALL.txt'.
 2.USAGE
 -------
 
-  fits2jpeg [options] <fits_file>
+ Usage: fits2jpeg [options] <fits_file>
+
+ Options are:
 
-  Options are:
     -h help
 
     -s <scale_type>
-       scale for output image intensity. Valid arguments are:
-
-         linear         for linear scaling, default
+       scale for output image, where <scale_type> can be:
+         linear         Linear scale, default
          sqroot         for square root scale
          square         for quadratic scale
          cubic          for cubic scale
          log            for log scale
+         normalize      for linear histogram stretch
+         equalize       for histogram equalization
+
+    -r <min>:<max>
+       Clip output image to min-max range. Eg:
+         0:100          Use only values in the range 0-100
+         100:0          Same as above, but negative image
+           :10          Clip everything above 10
+         10:            Clip everything below 10
+
+    -n
+       Negate the image.
+
+    -q <value>
+       jpeg quality factor. Defines the jpeg encoding quality
+       Valid range: 0-100, default value: 100, which is for
+       best quality (and largest file size).
 
-    -e <operation>
-       Imaghe enhancement operations. Valid arguments are:
+    -z <zoomfactor>
+       Resize/Scale output image by <zoomfactor>. Eg:
+         0.5            Shrink output to half of input
+         2.0            Magnify output to double the size
 
-         equalize       perform histogram equalization
-         normalize      perform a linear contrast stretch
-                        (use cutoffs at 1% and 99% for image data)
 
   Output will be written to <fits_file_root>.jpg. For eg.,
 
@@ -112,7 +128,7 @@ file named `INSTALL.txt'.
 
   More examples:
 
-  i. fits2jpeg -s cubic sirius.fits
+  i. fits2jpeg -s log sirius.fits
      will write out sirius.jpg, flux/intensity in log scale
 
  ii. fits2jpeg -s sqroot *.fits
@@ -120,12 +136,13 @@ file named `INSTALL.txt'.
      square-root scaling of flux/intensity - Good for very
      high dynamic range images
 
-iii. fits2jpeg -e normalize ngc4151.fits
-     Converts ngc4151.fits to ngc4151.jpg, contrast stretched.
+iii. fits2jpeg -n ngc4151.fits
+     Converts ngc4151.fits to ngc4151.jpg, negative image.
 
-NOTE: You can perform scaling + enhancing on an image. Scaling will
-      always be performed first. In most cases combining these two
-      would lead to un-usable images :)
+iv.  fits2jpeg -s square -n -r 10:2000 m31.fits
+     Write out m31.jpg, after square scaling of flux/intensity,
+     negate image and clip pixel values in the range 10 to 2000
+     units.
 
 
 3. DOCUMENTATION
@@ -159,4 +176,4 @@ Either way, please include as many details as possible.
 
 -----------------------------------------------------------
 Reks, 28 June 2012 <reks_at_iiap.res.in>
-      Last modified: 28 June 2012
+      Last modified: 10 July 2012
index 4349060..dd6b85e 100644 (file)
@@ -1,4 +1,4 @@
-AC_INIT([CADS_fits2jpeg], [1.90], [cads@iiap.res.in])
+AC_INIT([CADS_fits2jpeg], [1.95], [cads@iiap.res.in])
 AC_LANG_C
 AM_INIT_AUTOMAKE([-Wall -Werror])
 AC_CONFIG_SRCDIR([config.h.in])
@@ -13,7 +13,7 @@ AC_PROG_MAKE_SET
 # Checks for libraries.
 
 # Checks for header files.
-AC_CHECK_HEADERS([stdio.h stdlib.h string.h math.h])
+AC_CHECK_HEADERS([stdio.h stdlib.h string.h math.h float.h ctype.h libgen.h dirent.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 
index 4b35902..1e368c7 100644 (file)
@@ -1,3 +1,3 @@
 bin_PROGRAMS = fits2jpeg
-fits2jpeg_SOURCES = fits2jpeg.c getopt.c signal_handler.c
-
+fits2jpeg_SOURCES = fits2jpeg.c messages.c getopt.c image.c signal_handler.c
+noinst_HEADERS = fits2jpeg.h
\ No newline at end of file
index 116251b..60420e2 100644 (file)
@@ -29,6 +29,7 @@
 
   Reconstruction and additional features: Reks
  *---------------------------------------------------------------------------*/
+
 /*---------------------------------------------------------------------------
   Modification History
 
   Reks 28 June 2012
   1. rebranded to CADS/UVS
 
-  Reks 05 July 2012 v2.0 plans
+  Reks 05-10 July 2012 v2.0 plans
   1. Merged scale & operations to single flag
+  2. added fits2jpeg.h, help/banner functions moved to messages.c
+  3. Options to clip image min/max
+  4. negate image option
+  5. jpeg quality factor
+  6. pixel scaling operations moved to image.c
+  7. Image resizing works for reducing size. segfaults for zoom > 1 :(
   TODO
-      1. New option to specify min-max for image
+      1. move fits read to image.c
       2. specify output directory
-      3. output filename for single input file
-      4. Image resizing options
-
- *-------------------------------------------------------------------------*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-/*Header Definitions*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <libgen.h>
-#include <dirent.h>
-#include <fitsio2.h>
-#include <jpeglib.h>
-
-#define PROGRAM "fits2jpeg"
-#define r2d (90./atan2(1,0))
-#define MAX_TEXT 150
-int my_getopt(int, char * const *, const char *);
-void signals_handler(int);
-void set_signals(void);
+      3. Image resizing options
+ *---------------------------------------------------------------------------*/
+
+#include "fits2jpeg.h"
 
 char *optarg;
 int optindex;
-/*---------------------------------------------------------------------------*/
-void PRINT_BANNER()
-{
-    printf("\n");
-    printf(" %s %s\n", PROGRAM, VERSION);
-    printf(" Converts fits image files to jpeg\n");
-    printf("-----------------------------------------------------------\n");
-}
-/*---------------------------------------------------------------------------*/
-void usage()
-{
-    printf ("\n Usage: fits2jpeg [-s <options>] <fits_file>             \n");
-    printf ("  Options are:                                             \n");
-    printf ("    -h help                                                \n");
-    printf ("    -s <scale_type>                                        \n");
-    printf ("       scale for output image, where <scale_type> can be:  \n");
-    printf ("         linear         Linear scale, default              \n");
-    printf ("         sqroot         for square root scale              \n");
-    printf ("         square         for quadratic scale                \n");
-    printf ("         cubic          for cubic scale                    \n");
-    printf ("         log            for log scale                      \n");
-    printf ("         normalize      for linear histogram stretch       \n");
-    printf ("         equalize       for histogram equalization         \n");
-    printf ("  Output will be written to <fits_file_root>.jpg. Wild card\n");
-    printf ("  entries allowed in <fits_file>; For eg: *.fits, m31*.fits\n");
-    printf ("  ngc???.fits etc.                                         \n");
-    printf ("-----------------------------------------------------------\n");
-    printf ("Copyright (c) 2012 The CADS Team, IIAp. [GPL v3.0 or later]\n");
-    printf ("Report Bugs to: http://cads.iiap.res.in/bugzilla           \n");
-    printf ("Documentation : http://cads.iiap.res.in/software         \n\n");
-    exit(1);
-}
-/*---------------------------------------------------------------------------*/
 
 /*--------------------------- Begin Main Progam -----------------------------*/
 int main(int argc, char *argv[], char *envp[])
 {
     fitsfile *fptr;
 
-    int scale = 0, process = 0, status = 0, nfound, anynull;
-    unsigned int i = 0, j = 0, npixels = 0;
-    long naxes[2], row_stride;
-    float datamin = 0.0, datamax = 0.0;
-    float nullval = 0.0, scl_data;
+    int scale = 0, process = 0, status = 0, jpgqual = 100, nfound, anynull;
+    unsigned int i = 0, j = 0, usrclip = 0, usrnegt = 0, usrzoom = 0;
+    long xdim = 0, ydim = 0, naxes[2], row_stride;
+    unsigned long npixels = 0;
+    float datamin = 0.0, datamax = 0.0, nullval = 0.0, zoomfact = 1.0;
     float *data;
-    float tmp = 0.0;
-    float hist[256] = {0.0}, cumhist[256] = {0.0};
     char jpeg_file_name[MAX_TEXT] = "", fits_file_name[MAX_TEXT] = "";
+    char *tmpstr, *sptr;
 
     int opt;                                                   /* For getopt */
     extern char *optarg;
@@ -159,7 +111,6 @@ int main(int argc, char *argv[], char *envp[])
 
     struct jpeg_error_mgr jerr;
     struct jpeg_compress_struct cinfo;
-    int JMAXVAL = 255;                    /* Max value for greyscale in jpeg */
     JSAMPROW row_pointer[1];
     JSAMPLE *image_buffer;
     /*---------------- End of variable initialization -----------------------*/
@@ -170,41 +121,86 @@ int main(int argc, char *argv[], char *envp[])
     /*-------------------- Parse command line inputs ------------------------*/
 
     if (argc < 2) usage();  /* People who don't give any arguments need help */
-    while ( ( opt = my_getopt ( argc, argv, "s:r:h" ) ) != EOF )
+    while ( ( opt = my_getopt ( argc, argv, "e:hnq:r:s:z:" ) ) != EOF )
         switch ( opt )
         {
         case 's':
-            if      (strcmp(optarg, "sqroot")   ==0) scale = 1;
+            if      (strcmp(optarg, "linear")   ==0) scale = 0;
+            else if (strcmp(optarg, "sqroot")   ==0) scale = 1;
             else if (strcmp(optarg, "square")   ==0) scale = 2;
-            else if (strcmp(optarg, "cube")     ==0) scale = 3;
+            else if (strcmp(optarg, "cubic")    ==0) scale = 3;
             else if (strcmp(optarg, "log")      ==0) scale = 4;
             else if (strcmp(optarg, "normalize")==0) scale = 5;
             else if (strcmp(optarg, "equalize") ==0) scale = 6;
             else
+                scale = 0;
+            break;
+
+        case 'e':
+            /* Need to preserve it for backward compatibility */
+            if      (strcmp(optarg, "normalize")==0) scale = 5;
+            else if (strcmp(optarg, "equalize") ==0) scale = 6;
+            else
+                printerro(strcat(optarg, " -- Unrecognized option"));
+            break;
+
+        case 'r':
+            tmpstr = optarg;         /* make a copy.. and leave optarg alone */
+            sptr = strpbrk(tmpstr, ":");               /* Find the delimiter */
+            if (sptr == NULL)
+                printerro("Expected a ':' as separator for min/max");
+
+            if (sptr+1 == tmpstr + strlen(tmpstr))         /* -c <datamin>: */
+                datamax = FLT_MAX;
+            else
+                datamax = atof(sptr+1);
+
+            /* There should be an easier way to find datamin alongside datamax,
+             * but I am too sleepy to try anything now                       */
+            sptr = strchr(tmpstr, ':');
+            if (sptr == tmpstr)                             /* -c :<datamax> */
+                datamin = -1.0*FLT_MAX;
+            else
             {
-                fprintf(stderr, "ERROR  : Unrecognized option : %s\n", optarg);
-                exit(EXIT_FAILURE);
+                sptr = strtok(tmpstr, ":");
+                datamin = atof(sptr);
             }
+            printinfo("User defined pixel range");
+
+            /* Remember.. now we have user specified range */
+            usrclip = 1;
             break;
 
-        case 'r':
-            /*
-             * read a string like <min>:<max>
-             * set a flag. If this flag is on, do a 'reverse map'
-             * instead of search for datamin & datamax
+        case 'n' :
+            usrnegt = 1;
+            break;
+
+        case 'q' :
+            jpgqual = atoi(optarg);
+            if (jpgqual < 0) jpgqual = 0;
+            if (jpgqual > 100) jpgqual = 100;
+            printf("INFO   : jpeg quality factor changed to %d\n", jpgqual);
+            break;
+
+        case 'z' :
+
+            /* Do something to scale image
              */
+            zoomfact = atof(optarg);
+            if (zoomfact < 0.0) zoomfact = 1.0;
+            usrzoom = 1;
             break;
 
         case 'h':
             usage();
             break;
 
-        case '*':
-            usage();
+        default :
+            printerro("You can try 'fits2jpeg -h' for valid options");
             break;
         }
 
-    if ((argc - optindex) == 0) usage();       /* Somebody gave only options */
+    if ((argc - optindex) == 0) usage();        /* Someone gave only options */
 
     /*---------------------- Begin processing files -------------------------*/
 
@@ -225,11 +221,7 @@ int main(int argc, char *argv[], char *envp[])
         fits_open_file(&fptr, fits_file_name, READONLY, &status);
         fits_read_keys_lng(fptr, "NAXIS", 1, 2, naxes, &nfound, &status);
         if (status)
-        {
-            fprintf(stderr, "ERROR  : Could not open file: %s\n",
-                    fits_file_name);
-            exit(EXIT_FAILURE);
-        }/*Endif*/
+            printerro(strcat(fits_file_name, " <-- Failed to open the file"));
 
         /* Read in data */
         npixels = naxes[0] * naxes[1];
@@ -238,158 +230,55 @@ int main(int argc, char *argv[], char *envp[])
         nullval = 0;
         if (fits_read_img(fptr, TFLOAT, 1, npixels, &nullval, data, &anynull,
                           &status))
-        {
-            fprintf(stderr, "ERROR  : No valid fits image data in %s\n",
-                    fits_file_name);
-            exit(EXIT_FAILURE);
-        }/*Endif*/
+            printerro(strcat(fits_file_name, " has no valid fits image data"));
 
         fits_close_file(fptr, &status);
         /*Close data file*/
         printf("INFO   : data input from %s\n", fits_file_name);
 
-        /* IF no range is provided, find min & max in image */
-        datamax = -1.0e9;
-        datamin = +1.0e9;
-        for (i = 0; i < npixels; ++i)
-        {
-            if (data[i] > datamax) datamax = data[i];
-            if (data[i] < datamin) datamin = data[i];
-        } /*endfor*/
-
-
-        /* Convert data into bytscaled values for jpeg file                 */
-        /* the dynamic range is reduced to 255 for jpeg                     */
-        scl_data = (datamax - datamin)/(float)JMAXVAL;
-        for (i = 0; i < npixels; ++i)
-            data[i] = (data[i] - datamin)/scl_data;
-
-        /* All data is now squeezed into the range 0 - 255                   */
-        /* NOTE: At this point onwards min & max is 0 and 255 respectively   */
-
 
         /* Now we need to look at user options..                             */
-        /* 1. scale it as per user's requirement.                            */
-        /* 2. image enhancing operations                                     */
-                                                    /* Allocate image buffer */
-        image_buffer = (unsigned char *) malloc(sizeof(char) * npixels);
-        scl_data = 1.0;
-
-
-        /* initialize image histogram. ensure all are zeroes in hist[]       */
         /*-------------------------------------------------------------------*/
-        for (i = 0; i <= JMAXVAL; ++i) hist[i] = 0;
 
-        /* construct the image histogram */
-        tmp = 1.0/(float)npixels;
-        for (i = 0; i <= npixels; ++i)
-            hist[(int)floor(data[i])] += tmp;
-
-        /* And the cumulative histogram */
-        cumhist[0] = hist[0];
-        for (i = 1; i <= JMAXVAL; ++i)
-            cumhist[i] += cumhist[i - 1] + hist[i];
-        /*-------------------------------------------------------------------*/
-
-
-        switch (scale)
+        /* IF user has provided a range, fix them as min & max in image */
+        if (usrclip == 1)
         {
-        case 1 :                                              /* Square root */
-            printf("INFO   : Using square-root scale\n");
-            scl_data = sqrt((float)JMAXVAL)/(float)JMAXVAL;
             for (i = 0; i < npixels; ++i)
-                image_buffer[i] = (int)(sqrt(data[i])/scl_data);
-            break;
-
-        case 2 :                                                   /* Square */
-            printf("INFO   : Using quadratic scale\n");
-            scl_data = pow((float)JMAXVAL,2)/(float)JMAXVAL;
-            for (i = 0; i < npixels; ++i)
-                image_buffer[i] = (int)abs((pow(data[i],2) - 1.0)/scl_data);
-            break;
-
-        case 3 :                                                    /* Cubic */
-            printf("INFO   : Using cubic scale\n");
-            scl_data = pow((float)JMAXVAL,3)/(float)JMAXVAL;
-            for (i = 0; i < npixels; ++i)
-                image_buffer[i] = (int)abs((pow(data[i],3) - 1.0)/scl_data);
-            break;
-
-        case 4 :                                                      /* log */
-            printf("INFO   : Using log scale\n");
-            scl_data = log(1.0 + (float)JMAXVAL)/(float)JMAXVAL;
-            for (i = 0; i < npixels; ++i)
-                image_buffer[i] = (int)((log(abs(data[i]) + 1.0))/scl_data);
-            break;
-
-        case 5 :
-            /* contrast stretch */
-            printf("INFO   : Performing histogram stretch (normalization)\n");
-
-            datamax = (float)JMAXVAL;
-            datamin = 0.0;
-
-            /* We need to go through the cumulative histogram to pick the
-             *  appropriate values for datamin and datamax               */
-            i = 0;
-            while (i < JMAXVAL)
             {
-                if (cumhist[i] >= 0.01)
-                {
-                    datamin = (float) i;
-                    break;
-                }
-                i++;
-            }
-            i = JMAXVAL;
-            while (i > 0)
-            {
-                if (cumhist[i] <= 0.99)
-                {
-                    datamax = (float) i;
-                    break;
-                }
-                i--;
-            }
-            scl_data = (datamax - datamin)/(float)JMAXVAL;
-            for (i = 0; i < npixels; ++i)
-            {
-                if (image_buffer[i] >= datamax)
-                    image_buffer[i] = JMAXVAL;
-                else if (image_buffer[i] <= datamin)
-                    image_buffer[i] = 0;
-                else
-                    image_buffer[i] = (int) abs((image_buffer[i]
-                                    - datamin)/scl_data);
-            }
-            break;
+                if (data[i] > datamax) data[i] = datamax;
+                if (data[i] < datamin) data[i] = datamin;
+            } /*endfor*/
+        }
 
-        case 6 :
-           /* histogram equalization */
-            printf("INFO   : Performing Histogram Equalization\n");
-            for (i = 0; i <  npixels; ++i)
-                image_buffer[i] = cumhist[image_buffer[i]]*255;
-            break;
+        /* Allocate image buffer */
+        image_buffer = (unsigned char *) malloc(sizeof(char) * npixels);
+        scale_pixels(scale, npixels, data, image_buffer);
 
-        default:                                   /* Linear scale (min-max) */
-            for (i = 0; i < npixels; ++i)
-                image_buffer[i] = (int)(data[i]);
-            break;
+        /* Before we write jpeg, check if there is any requirement to negate
+         * the image (usrnegt = 1)                                           */
+        if (usrnegt == 1)
+        {
+            printinfo("Negating Image");
+            for (i = 0; i <  npixels; ++i) image_buffer[i] ^= 0xff;
         }
 
+        xdim = naxes[0];
+        ydim = naxes[1];
+        if (usrzoom == 1) resize_image(&xdim, &ydim, zoomfact, image_buffer);
 
         /*Write out data into JPEG file*/
+        jpeg_file = fopen(jpeg_file_name, "wb");/* Open JPEG file for writing*/
         cinfo.err = jpeg_std_error(&jerr);             /* JPEG error handler */
         jpeg_create_compress(&cinfo);                 /* JPEG initialization */
-        jpeg_file = fopen(jpeg_file_name, "wb");/* Open JPEG file for writing*/
         jpeg_stdio_dest(&cinfo, jpeg_file); /* Send compressed data to stdio */
-        cinfo.image_width = naxes[0];                         /* Image width */
-        cinfo.image_height = naxes[1];                       /* Image height */
+        cinfo.image_width = xdim;                             /* Image width */
+        cinfo.image_height = ydim;                           /* Image height */
         cinfo.input_components = 1;            /* Number of colors per pixel */
         cinfo.in_color_space = JCS_GRAYSCALE;   /* colorspace of input image */
         jpeg_set_defaults(&cinfo);                      /* Set JPEG defaults */
+        jpeg_set_quality(&cinfo, jpgqual, TRUE);  /* Set jpeg quality factor */
         jpeg_start_compress(&cinfo, TRUE);       /* default data compression */
-        row_stride = naxes[0];            /* JSAMPLEs per row inimage buffer */
+        row_stride = xdim;                /* JSAMPLEs per row inimage buffer */
 
         /* Now we have to turn the data upside down                          */
         while (cinfo.next_scanline < cinfo.image_height)
@@ -397,6 +286,7 @@ int main(int argc, char *argv[], char *envp[])
             row_pointer[0] = &image_buffer[(cinfo.image_height -
                                             cinfo.next_scanline) *
                                             row_stride];
+
             (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
         }/*Loop through file writing one line at a time*/
 
index 1389f6b..a96f9fb 100644 (file)
@@ -47,4 +47,5 @@ void set_signals(void);
 void printinfo(const char *);
 void printwarn(const char *);
 void printerro(const char *);
-void scale_image(int, int, float *, JSAMPLE *);
+void scale_pixels(int, unsigned int, float *, JSAMPLE *);
+void resize_image(long *, long *, float, JSAMPLE *);
index 5f27eb8..2e76f34 100644 (file)
@@ -109,7 +109,7 @@ int my_getopt(int nargc, char * const *nargv, const char *ostr)
                 (void)fprintf(stderr,
                               "ERROR  : option requires an argument -- %c\n",
                               optopt);
-            return (BADCH);
+            exit (BADCH);
         }
         else                                                   /* white space */
             optarg = nargv[optindex];
index 7a068e9..d1c22f0 100644 (file)
 /*Header Definitions*/
 #include "fits2jpeg.h"
 
-void scale_image(int scale, int npixels,
+/*---------------------------------------------------------------------------*
+ * SCALE_PIXELS: Changes the pixel scale to linear/log/sqroot/etc..
+ *---------------------------------------------------------------------------*/
+void scale_pixels(int scale, unsigned int npixels,
                  float *data, JSAMPLE *image_buffer)
 {
     unsigned int i = 0;
@@ -34,7 +37,7 @@ void scale_image(int scale, int npixels,
     float scl_data = 0.0;
 
 
-    /* first find min & max in data */
+    /* first find min & max in data                                          */
     datamax = -1.0 * FLT_MAX;
     datamin = FLT_MAX;
     for (i = 0; i < npixels; ++i)
@@ -43,19 +46,22 @@ void scale_image(int scale, int npixels,
         if (data[i] < datamin) datamin = data[i];
     } /*endfor*/
 
-    /* Convert data into bytscaled values for jpeg file                 */
-    /* the dynamic range is reduced to 255 for jpeg                     */
+
+    /* Convert data into bytscaled values for jpeg file                     */
+    /* the dynamic range is reduced to 255 for jpeg                         */
     scl_data = (datamax - datamin)/(float)JMAXVAL;
+
     for (i = 0; i < npixels; ++i)
         data[i] = (data[i] - datamin)/scl_data;
 
-    /* All data is now squeezed into the range 0 - 255                   */
-    /* NOTE: At this point onwards min & max is 0 and 255 respectively   */
+
+    /* All data is now squeezed into the range 0 - 255                       */
+    /* NOTE: At this point onwards min & max is 0 and 255 respectively       */
     datamax = (float)JMAXVAL;
     datamin = 0.0;
 
-    /* initialize image histogram. ensure all are zeroes in hist[]       */
-    /*-------------------------------------------------------------------*/
+    /* initialize image histogram. ensure all are zeroes in hist[]           */
+    /*-----------------------------------------------------------------------*/
     for (i = 0; i <= JMAXVAL; ++i) hist[i] = 0;
 
     /* construct the image histogram */
@@ -69,11 +75,11 @@ void scale_image(int scale, int npixels,
         cumhist[i] += cumhist[i - 1] + hist[i];
 
     /* Linear scale (min-max) : This is the default scaling
-     * if we dont generate image_buffer here, histo-eq will fail */
+     * histo-eq will fail if we dont generate image_buffer here              */
     for (i = 0; i < npixels; ++i)
         image_buffer[i] = (int)(data[i]);
 
-    /*-------------------------------------------------------------------*/
+    /*-----------------------------------------------------------------------*/
 
 
     switch (scale)
@@ -140,7 +146,8 @@ void scale_image(int scale, int npixels,
                 else if (image_buffer[i] <= datamin)
                     image_buffer[i] = 0;
                 else
-                    image_buffer[i] = (int) abs((image_buffer[i] - datamin)/scl_data);
+                    image_buffer[i] = (int) abs((image_buffer[i]
+                                    - datamin)/scl_data);
             }
             break;
 
@@ -148,7 +155,7 @@ void scale_image(int scale, int npixels,
             /* histogram equalization */
             printinfo("Performing Histogram Equalization");
             for (i = 0; i <  npixels; ++i)
-                image_buffer[i] = cumhist[image_buffer[i]] * 255;
+                image_buffer[i] = cumhist[image_buffer[i]] * JMAXVAL;
             break;
         default :
             printinfo("Using linear scale");
@@ -156,3 +163,65 @@ void scale_image(int scale, int npixels,
     }
 
 }
+
+/*---------------------------------------------------------------------------*
+ * RESIZE_IMAGE: Scales down/up the image_buffer
+ *---------------------------------------------------------------------------*/
+void resize_image(long *xdim, long *ydim, float zoomfact, JSAMPLE *image_buffer)
+{
+    int offset = 0, index = 0;
+    int A, B, C, D, x, y, gray;
+    JSAMPLE *buff;
+    unsigned int i = 0, j = 0;
+    unsigned long npixels = 0;
+    long w = *xdim, h = *ydim;
+    long zxdim = 0, zydim = 0;
+    float xdiff, ydiff, xratio, yratio;
+
+    zxdim  = (int)(w * zoomfact);
+    zydim  = (int)(h * zoomfact);
+
+    npixels= zxdim * zydim;
+
+    xratio = ((float)(w - 1))/zxdim;
+    yratio = ((float)(h - 1))/zydim;
+
+                                     /* allocate space for *buff */
+    buff   = (unsigned char *) malloc(sizeof(char) * zxdim * zydim);
+
+    index  = 0;
+    offset = 0;
+    for (i = 0; i < zydim; i++)
+    {
+        y     = (int)(yratio * i);
+        ydiff = (yratio * i) - y;
+
+        for (j = 0; j < zxdim; j++)
+        {
+            x = (int)(xratio * j);
+
+            xdiff = (xratio * j) - x;
+            index = y * w + x;
+
+            A = image_buffer[index]         & 0xff;
+            B = image_buffer[index + 1]     & 0xff;
+            C = image_buffer[index + w]     & 0xff;
+            D = image_buffer[index + w + 1] & 0xff;
+
+            gray = (int)(A * (1 - xdiff) * (1 - ydiff)
+                 +       B * (xdiff)     * (1 - ydiff)
+                 +       C * (ydiff)     * (1 - xdiff)
+                 +       D * (xdiff)     * (ydiff)
+                    );
+            buff[offset++] = gray;
+        }
+    }
+    *xdim = zxdim;
+    *ydim = zydim;
+    image_buffer = realloc(image_buffer, sizeof(char) * npixels);
+    if (!image_buffer)
+        printerro("Failed to allocate memory");
+
+    for (i = 0; i <  npixels; ++i)
+        image_buffer[i] = buff[i];
+}
index 4386e55..edcdc68 100644 (file)
@@ -47,7 +47,7 @@ void usage()
     printf ("         log            for log scale                      \n");
     printf ("         normalize      for linear histogram stretch       \n");
     printf ("         equalize       for histogram equalization         \n");
-    printf ("    -c <min>:<max>                                         \n");
+    printf ("    -r <min>:<max>                                         \n");
     printf ("       Clip output image to min-max range. Eg:             \n");
     printf ("         0:100          Use only values in the range 0-100 \n");
     printf ("         100:0          Same as above, but negative image  \n");
@@ -55,7 +55,7 @@ void usage()
     printf ("         10:            Clip everything below 10           \n");
     printf ("    -n                                                     \n");
     printf ("       Negate the image                                    \n");
-    printf ("    -q                                                     \n");
+    printf ("    -q <value>                                             \n");
     printf ("       quality factor. Defines the jpeg encoding quality   \n");
     printf ("       Valid range: 0-100, default value: 100 (max.quality)\n");
     printf ("    -z <zoomfactor>                                        \n");