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
 -------
 
 2.USAGE
 -------
 
-  fits2jpeg [options] <fits_file>
+ Usage: fits2jpeg [options] <fits_file>
+
+ Options are:
 
 
-  Options are:
     -h help
 
     -s <scale_type>
     -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
          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.,
 
 
   Output will be written to <fits_file_root>.jpg. For eg.,
 
@@ -112,7 +128,7 @@ file named `INSTALL.txt'.
 
   More examples:
 
 
   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
      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
 
      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
 
 
 3. DOCUMENTATION
@@ -159,4 +176,4 @@ Either way, please include as many details as possible.
 
 -----------------------------------------------------------
 Reks, 28 June 2012 <reks_at_iiap.res.in>
 
 -----------------------------------------------------------
 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])
 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.
 # 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.
 
 
 # Checks for typedefs, structures, and compiler characteristics.
 
index 4b35902..1e368c7 100644 (file)
@@ -1,3 +1,3 @@
 bin_PROGRAMS = fits2jpeg
 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
  *---------------------------------------------------------------------------*/
 
   Reconstruction and additional features: Reks
  *---------------------------------------------------------------------------*/
+
 /*---------------------------------------------------------------------------
   Modification History
 
 /*---------------------------------------------------------------------------
   Modification History
 
   Reks 28 June 2012
   1. rebranded to CADS/UVS
 
   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
   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
   TODO
-      1. New option to specify min-max for image
+      1. move fits read to image.c
       2. specify output directory
       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;
 
 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;
 
 
 /*--------------------------- 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 *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 jpeg_file_name[MAX_TEXT] = "", fits_file_name[MAX_TEXT] = "";
+    char *tmpstr, *sptr;
 
     int opt;                                                   /* For getopt */
     extern char *optarg;
 
     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;
 
     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 -----------------------*/
     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 */
     /*-------------------- 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':
         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, "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
             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;
 
             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;
 
             break;
 
         case 'h':
             usage();
             break;
 
-        case '*':
-            usage();
+        default :
+            printerro("You can try 'fits2jpeg -h' for valid options");
             break;
         }
 
             break;
         }
 
-    if ((argc - optindex) == 0) usage();       /* Somebody gave only options */
+    if ((argc - optindex) == 0) usage();        /* Someone gave only options */
 
     /*---------------------- Begin processing files -------------------------*/
 
 
     /*---------------------- 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)
         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];
 
         /* 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))
         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);
 
 
         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..                             */
 
         /* 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)
             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*/
 
         /*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 */
         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 */
         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 */
         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 */
         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)
 
         /* 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];
             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*/
 
             (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 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);
                 (void)fprintf(stderr,
                               "ERROR  : option requires an argument -- %c\n",
                               optopt);
-            return (BADCH);
+            exit (BADCH);
         }
         else                                                   /* white space */
             optarg = nargv[optindex];
         }
         else                                                   /* white space */
             optarg = nargv[optindex];
index 7a068e9..d1c22f0 100644 (file)
 /*Header Definitions*/
 #include "fits2jpeg.h"
 
 /*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;
                  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;
 
 
     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)
     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*/
 
         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;
     scl_data = (datamax - datamin)/(float)JMAXVAL;
+
     for (i = 0; i < npixels; ++i)
         data[i] = (data[i] - datamin)/scl_data;
 
     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;
 
     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 */
     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
         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]);
 
     for (i = 0; i < npixels; ++i)
         image_buffer[i] = (int)(data[i]);
 
-    /*-------------------------------------------------------------------*/
+    /*-----------------------------------------------------------------------*/
 
 
     switch (scale)
 
 
     switch (scale)
@@ -140,7 +146,8 @@ void scale_image(int scale, int npixels,
                 else if (image_buffer[i] <= datamin)
                     image_buffer[i] = 0;
                 else
                 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;
 
             }
             break;
 
@@ -148,7 +155,7 @@ void scale_image(int scale, int npixels,
             /* histogram equalization */
             printinfo("Performing Histogram Equalization");
             for (i = 0; i <  npixels; ++i)
             /* 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");
             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 ("         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");
     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 ("         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");
     printf ("       quality factor. Defines the jpeg encoding quality   \n");
     printf ("       Valid range: 0-100, default value: 100 (max.quality)\n");
     printf ("    -z <zoomfactor>                                        \n");