authorRekhesh Mohan <reks@iiap.res.in>
Thu, 12 Jul 2012 15:58:07 +0000 (21:28 +0530)
committerRekhesh Mohan <reks@iiap.res.in>
Thu, 12 Jul 2012 15:58:07 +0000 (21:28 +0530)
ChangeLog.txt
README.txt
configure.ac
src/Makefile.am
src/filesys.c [new file with mode: 0644]
src/fits2jpeg.c
src/fits2jpeg.h [new file with mode: 0644]
src/image.c [new file with mode: 0644]
src/messages.c [new file with mode: 0644]

index e557841..e10220c 100644 (file)
@@ -3,5 +3,35 @@ CHANGELOG for CADS/UVS fits2jpeg software
 ------------------------------------------------------------------------
 
 NOTE: This file records the changes made after the release of the stable
 ------------------------------------------------------------------------
 
 NOTE: This file records the changes made after the release of the stable
-version fits2jpeg-1.0 
+version fits2jpeg-1.0
 ------------------------------------------------------------------------
 ------------------------------------------------------------------------
+
+
+
+Updates in 2.0 Release
+----------------------
+
+  1. Merged scale & operations to single flag
+     v1.0 had normalize/equalize handled by "-e" flag and rest of
+     image operations by "-s" flag. Both are merged into "-s" in
+     this release.
+
+  2. New option to clip image min/max
+     You can limit the pixel-values in output image using the flag
+     "-r". For eg: -r 10:300 to generate jpegs with pixel values in
+     the range 10 to 300.
+
+  3. New option to negate image option
+     A negative image can be generated using "-n" flag.
+
+  4. New option to resize image
+     zoom or shrink output image by "-z <zoomfact>".
+
+  5. New option to choose jpeg quality factor
+     You can choose the jpeg quality factor by "-q <quality>"
+     Quality factor was fixed at 100 in previous release.
+
+  6. New option to specify output directory for saving jpeg images
+     Output location can be specified by "-d </path/to/folder>"
+     If the target directory does not exist, the whole tree will be
+     created.
index 2164ec0..eeace20 100644 (file)
@@ -6,12 +6,11 @@ README file for CADS/UVS fits2jpeg software
 
 0. FEATURES
 -----------
 
 0. FEATURES
 -----------
-fits2jpeg is a tiny program to read FITS Images and convert them
-to jpeg, which is more popular. This software supports various
-type of intensity scaling and image enhancements. fits2jpeg do not
-support coordinate axes overlay. fits2jpeg supports batch mode
-operations - for instance, converting several fits files to jpeg
-at once.
+fits2jpeg is a tiny program to read FITS Images and convert them to jpeg, which
+is more popular. This software supports various type of intensity scaling and
+image enhancements. fits2jpeg do not support coordinate axes overlay. fits2jpeg
+supports batch mode operations - for instance, converting several fits files to
+jpeg at once.
 
 
 1. BUILD/INSTALL
 
 
 1. BUILD/INSTALL
@@ -26,9 +25,10 @@ Pre-requisites:
     http://heasarc.gsfc.nasa.gov/docs/software/fitsio/fitsio.html
 
  b) JPEGLIB
     http://heasarc.gsfc.nasa.gov/docs/software/fitsio/fitsio.html
 
  b) JPEGLIB
-    jpeg library and headers. libjpeg is installed by default on most
-    platforms, but we need the header files too. Once you have cfitsio
-    and jpeglib installed, you may proceed with compiling jpeg2fits.
+    jpeg library and headers. libjpeg is installed by default on most platforms,
+    but we need the header files too. Once you have cfitsio and jpeglib
+    installed, you may proceed with compiling jpeg2fits.
+
     Follow these 4 steps:
 
 
     Follow these 4 steps:
 
 
@@ -61,45 +61,74 @@ Pre-requisites:
   2. Type `make' to compile the package.
 
   3. Type `make install' to install the programs and any data files and
   2. Type `make' to compile the package.
 
   3. Type `make install' to install the programs and any data files and
-     documentation. By default, the binary is copied to /usr/local/bin.
-     You may change this destination by passing on the following
-     argument to configure:
+     documentation. By default, the binary is copied to /usr/local/bin. You may
+     change this destination by passing on the following argument to configure:
 
              --prefix=/your/chosen/destination
 
      Which would result in the binary in /your/chosen/destination/bin
      You may need to ensure that in $PATH to run the program.
 
 
              --prefix=/your/chosen/destination
 
      Which would result in the binary in /your/chosen/destination/bin
      You may need to ensure that in $PATH to run the program.
 
-  4. You can remove the program binaries and object files from the
-     source code directory by typing `make clean'.
+  4. You can remove the program binaries and object files from the source code
+     directory by typing `make clean'.
 
 
-You may read more about configure script and others in the accompanying
-file named `INSTALL.txt'.
+You may read more about configure script and others in the accompanying file
+named `INSTALL.txt'.
 
 
 2.USAGE
 -------
 
 
 
 2.USAGE
 -------
 
-  fits2jpeg [options] <fits_file>
+ Usage: fits2jpeg [options] <fits_file>
+        You need to specify a fits image file <fits_file> for this program to
+        work. Everything else is optional. A brief description of them are
+        listed below:
 
 
-  Options are:
     -h help
     -h help
+       Prints out a usage-help message, much like this section.
 
     -s <scale_type>
 
     -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
-
-    -e <operation>
-       Imaghe enhancement operations. Valid arguments are:
-
-         equalize       perform histogram equalization
-         normalize      perform a linear contrast stretch
-                        (use cutoffs at 1% and 99% for image data)
+         normalize      for linear histogram stretch
+         equalize       for histogram equalization
+
+    -n
+       Negate the image
+
+    -q <value>
+       quality factor. Defines the jpeg encoding quality
+       Valid range: 0-100, default value: 100, which means
+       best quality and largest file-size.
+
+    -d <path/to/output/directory>
+       Write jpeg file to this specified directory. Will
+       create it if needed. Default is to write jpeg in the
+       same directory of fits image file
+
+    -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
+
+    -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
+                        Allowed range: 0.01 to 4.0
+       NOTE: Zooming will be carried out after all other
+             operations, before writing out jpeg image
+
+       fits2jpeg uses a bilinear interpolation based algorithm
+       to scale the image. Allowed range: 0.01 to 4.0
+       NOTE: Anything outside the allowed range will be clipped
+             to this range.
 
   Output will be written to <fits_file_root>.jpg. For eg.,
 
 
   Output will be written to <fits_file_root>.jpg. For eg.,
 
@@ -107,32 +136,55 @@ file named `INSTALL.txt'.
 
   writes output to jpeg file 30dor.jpg
 
 
   writes output to jpeg file 30dor.jpg
 
-  Wild card entries allowed in <fits_file>. For eg: *.fits,
-  m31*.fits ngc???.fits etc.
+  Wild card entries allowed in <fits_file>. For eg: *.fits, m31*.fits
+  ngc???.fits etc.
 
 
-  More examples:
 
 
-  i. fits2jpeg -s cubic sirius.fits
+3.1 Examples:
+-------------
+  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
-     Converts all fits files in the directory to jpegs, with
-     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.
+     Converts all fits files in the directory to jpegs, with square-root scaling
+     of flux/intensity - Good for very high dynamic range images
+
+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.
+
+  v. fits2jpeg -s equalize -r 200: -d/path/to/mydir NGS253*.fits
+
+     Reads all fits files in the present directory that matches the filename
+     patterm, performs a histogram equalization, drops pixel values below 200
+     and write out all the corresponding jpeg files to directory /path/to/mydir
+     Will create the destination directory tree if it does not exist.
+
+
+3.1. Sequence of operations
+---------------------------
+Here is the sequence of operations, after reading the fits file:
+
+     i. clip the image to user specified pixel limits, if it was requested
+    ii. Squeeze image pixel values to jpeg limits (0 - 255)
+   iii. image scaling function, default being linear pixel scale
+    iv. Negate the image, if requested
+     v. Image zoom - magnify or shrink the image
+    vi. Write out jpeg file
 
 
 3. DOCUMENTATION
 ----------------
 
 
 3. DOCUMENTATION
 ----------------
-An extensive coverage of how this program works along with line
-by line account of the happenings within the code, are dealt with
-in the user manual, which is yet to be written :(
+An extensive coverage of how this program works along with line by line account
+of the happenings within the code, are dealt with in the user manual, which is
+yet to be written :(
 
 
 4. LICENSE: GPL [See the file COPYING.txt for details]
 
 
 4. LICENSE: GPL [See the file COPYING.txt for details]
@@ -141,10 +193,9 @@ in the user manual, which is yet to be written :(
 
 5. DISCLAIMER
 -------------
 
 5. DISCLAIMER
 -------------
-You may encounter bugs in this software. If you do, please
-report them. Your bug reports are valuable contributions,
-since they allow us to notice and fix problems on
-machines/platforms we don't have, and/or remained un-noticed.
+You may encounter bugs in this software. If you do, please report them. Your bug
+reports are valuable contributions, since they allow us to notice and fix
+problems on machines/platforms we don't have, and/or remained un-noticed.
 
 
 6. REPORTING BUGS
 
 
 6. REPORTING BUGS
@@ -157,6 +208,7 @@ If you are too lazy, drop in an email to: cads_AT_iiap.res.in
 
 Either way, please include as many details as possible.
 
 
 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 c63208d..0e27801 100644 (file)
@@ -1,4 +1,4 @@
-AC_INIT([CADS_fits2jpeg], [1.0], [cads@iiap.res.in])
+AC_INIT([CADS_fits2jpeg], [2.0], [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,15 +13,17 @@ 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([string.h math.h float.h ctype.h libgen.h dirent.h])
+#AC_CHECK_HEADERS([sys/stat.h sys/types.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 
 
 # Checks for typedefs, structures, and compiler characteristics.
 
+
 # Checks for library functions.
 AC_FUNC_MALLOC
 
 LIBS="$LIBS -L/usr/lib64 -L/usr/lib -lm -ljpeg -lcfitsio"
 # Checks for library functions.
 AC_FUNC_MALLOC
 
 LIBS="$LIBS -L/usr/lib64 -L/usr/lib -lm -ljpeg -lcfitsio"
-CFLAGS="-ansi $CFLAGS -I/usr/include -I/usr/include/cfitsio"
+CFLAGS="-ansi -Wall $CFLAGS -I/usr/include -I/usr/include/cfitsio"
 #---------------------------------------------------------------------#
 #           Now we check for cfitsio headers and library              #
 #---------------------------------------------------------------------#
 #---------------------------------------------------------------------#
 #           Now we check for cfitsio headers and library              #
 #---------------------------------------------------------------------#
index 4b35902..148dfb3 100644 (file)
@@ -1,3 +1,5 @@
 bin_PROGRAMS = fits2jpeg
 bin_PROGRAMS = fits2jpeg
-fits2jpeg_SOURCES = fits2jpeg.c getopt.c signal_handler.c
-
+fits2jpeg_SOURCES = fits2jpeg.c image.c       \
+                    messages.c filesys.c      \
+                    getopt.c signal_handler.c
+noinst_HEADERS = fits2jpeg.h
\ No newline at end of file
diff --git a/src/filesys.c b/src/filesys.c
new file mode 100644 (file)
index 0000000..e7ff547
--- /dev/null
@@ -0,0 +1,87 @@
+/***************************************************************************
+ * This file is a part of CADS/UVS fits2jpeg conversion software           *
+ *   Copyright (C) 2012 by CADS/UV Software Team,                          *
+ *                         Indian Institute of Astrophysics                *
+ *                         Bangalore 560034                                *
+ *                         cads_AT_iiap.res.in                             *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+/*Header Definitions*/
+#include "fits2jpeg.h"
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*
+ * MAKE_DIR: Wrapper to mkdir() with some basic error checks
+ *---------------------------------------------------------------------------*/
+int make_dir(char * folder, mode_t mode)
+{
+    struct stat st;
+    int status = 0;
+
+    if (stat(folder, &st) != 0)
+    {
+        /* Directory does not exist - make it */
+        status = mkdir(folder, mode);
+        if (status) return status;
+    }
+    else if (!S_ISDIR(st.st_mode))
+        return status = -1;
+    return status;
+}
+
+/*---------------------------------------------------------------------------*
+ * MAKE_TREE: moves through a directory path and creates directories and
+ *            subdirectories using make_dir(), top-down.
+ *---------------------------------------------------------------------------*/
+int make_tree(char * folder, mode_t mode)
+{
+    char *pp;
+    char *sp;
+    int  status = 0;
+    char *fpath = strdup(folder);
+
+    pp = fpath;
+
+    while (status == 0 && (sp = strchr(pp, '/')) != 0)
+    {
+        if (sp != pp)
+        {
+            *sp = '\0';
+            status = make_dir(fpath, mode);
+            *sp = '/';
+        }
+        pp = sp + 1;
+    }
+
+    if (status == 0) status = make_dir(folder, mode);
+    return status;
+}
+
+/*---------------------------------------------------------------------------*
+ * STRDUP: This one is not a part of ANSI-strict, so we had to write one
+ *---------------------------------------------------------------------------*/
+char *strdup(const char *str)
+{
+    int n = strlen(str) + 1;
+    char *dup = malloc(n);
+    if(dup)
+    {
+        strcpy(dup, str);
+    }
+    return dup;
+}
index b387ff0..7390330 100644 (file)
@@ -1,4 +1,5 @@
 /***************************************************************************
 /***************************************************************************
+ * This file is a part of CADS/UVS fits2jpeg conversion software           *
  *   Copyright (C) 2012 by CADS/UV Software Team,                          *
  *                         Indian Institute of Astrophysics                *
  *                         Bangalore 560034                                *
  *   Copyright (C) 2012 by CADS/UV Software Team,                          *
  *                         Indian Institute of Astrophysics                *
  *                         Bangalore 560034                                *
@@ -29,6 +30,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
- *-------------------------------------------------------------------------*/
-
-#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);
+
+  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
+  8. moved fits read to image.c
+  9. Option to specify output directory
+ *---------------------------------------------------------------------------*/
+
+#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\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 ("    -e <operation>                                         \n");
-    printf ("       Image enhancements, where <operation> can be:       \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[])
 {
 
 /*--------------------------- 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, jpgqual = 100, status = 0;
+    unsigned int i = 0, j = 0;
+    unsigned int customdir = 0, usrclip = 0, usrnegt = 0, usrzoom = 0;
+    long xdim = 0, ydim = 0, row_stride;
+    unsigned long npixels = 0;
+    float datamin = 0.0, datamax = 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 output_dir[MAX_TEXT] = "";
+    char *tmpstr, *sptr;
 
     int opt;                                                   /* For getopt */
     extern char *optarg;
     extern int optindex;
 
     int opt;                                                   /* For getopt */
     extern char *optarg;
     extern int optindex;
-
+    mode_t mode = 0755;
     FILE *jpeg_file;
     FILE *jpeg_file;
-
     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 -----------------------*/
 
-    PRINT_BANNER();        /* Header: Talks about program, version & purpose */
+    banner();              /* Header: Talks about program, version & purpose */
     set_signals();                                  /* Trap un-natural exits */
 
     /*-------------------- Parse command line inputs ------------------------*/
 
     if (argc < 2) usage();  /* People who don't give any arguments need help */
     set_signals();                                  /* Trap un-natural exits */
 
     /*-------------------- Parse command line inputs ------------------------*/
 
     if (argc < 2) usage();  /* People who don't give any arguments need help */
-    while ( ( opt = my_getopt ( argc, argv, "s:e:h" ) ) != EOF )
+    while ( ( opt = my_getopt ( argc, argv, "d:e:hnq:r:s:z:" ) ) != EOF )
         switch ( opt )
         {
         case 's':
         switch ( opt )
         {
         case 's':
-            if (strcmp(optarg, "sqroot")   ==0) scale = 1;
-            if (strcmp(optarg, "square")   ==0) scale = 2;
-            if (strcmp(optarg, "cube")     ==0) scale = 3;
-            if (strcmp(optarg, "log")      ==0) scale = 4;
+            if      (strcmp(optarg, "linear") == 0) scale = 0;
+            else if (strcmp(optarg, "sqroot") == 0)
+            {
+                printinfo("Using square-root scale");
+                scale = 1;
+            }
+            else if (strcmp(optarg, "square") == 0)
+            {
+                printinfo("Using quadratic scale");
+                scale = 2;
+            }
+            else if (strcmp(optarg, "cubic") == 0)
+            {
+                printinfo("Using cubic scale");
+                scale = 3;
+            }
+            else if (strcmp(optarg, "log") == 0)
+            {
+                printinfo("Using log scale");
+                scale = 4;
+            }
+            else if (strcmp(optarg, "normalize") == 0)
+            {
+                printinfo("Performing histogram stretch (normalization)");
+                scale = 5;
+            }
+            else if (strcmp(optarg, "equalize") == 0)
+            {
+                printinfo("Performing Histogram Equalization");
+                scale = 6;
+            }
+            else
+            {
+                printwarn(strcat(optarg, " -- Unrecognized option"));
+                scale = 0;
+            }
             break;
 
         case 'e':
             break;
 
         case 'e':
-            if (strcmp(optarg, "normalize")==0) process = 1;
-            if (strcmp(optarg, "equalize") ==0) process = 2;
+            /* 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
+            {
+                sptr = strtok(tmpstr, ":");
+                datamin = atof(sptr);
+            }
+
+            /* Remember.. now we have user specified range */
+            usrclip = 1;
+            break;
+
+        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' :
+            zoomfact = atof(optarg);
+            zoomfact = fabs(zoomfact);
+            if (zoomfact < 0.01) zoomfact = 0.01;
+            if (zoomfact > 4.0) zoomfact = 4.0;
+            usrzoom = 1;
+            break;
+
+        case 'd':
+            strcpy(output_dir, optarg);
+            printf("INFO   : Output image directory is %s\n", output_dir);
+            customdir = 1;
+            status = make_tree(output_dir, mode);
+            if (status != 0) printerro("Unable to create output directory");
             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 (scale == 0) printinfo("Using linear scale");
+    if ((argc - optindex) == 0) usage();        /* Someone gave only options */
 
     /*---------------------- Begin processing files -------------------------*/
 
 
     /*---------------------- Begin processing files -------------------------*/
 
@@ -205,168 +249,65 @@ int main(int argc, char *argv[], char *envp[])
         strtok(jpeg_file_name, ".");
         strcat(jpeg_file_name, ".jpg");
 
         strtok(jpeg_file_name, ".");
         strcat(jpeg_file_name, ".jpg");
 
-        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*/
-
-        /* Read in data */
-        npixels = naxes[0] * naxes[1];
-        data = (float *) malloc(sizeof(float) * npixels);
-
-        nullval = 0;
-        if (fits_read_img(fptr, TFLOAT, 1, npixels, &nullval, data, &anynull,
-                          &status))
+        if (customdir == 1)
         {
         {
-            fprintf(stderr, "ERROR  : No valid fits image data in %s\n",
-                    fits_file_name);
-            exit(EXIT_FAILURE);
-        }/*Endif*/
+            if (output_dir[strlen(output_dir) - 1] != '/')
+                strcat(output_dir, "/");
 
 
-        fits_close_file(fptr, &status);
-        /*Close data file*/
-        printf("INFO   : data input from %s\n", fits_file_name);
-
-        /* 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*/
+            strcat(output_dir, basename(jpeg_file_name));
+            strcpy(jpeg_file_name, output_dir);
+        }
 
 
-        /* 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;
+        read_fits(fits_file_name, &xdim, &ydim, &data);
+        npixels = xdim * ydim;
 
 
-        /* All data is now squeezed into the range 0 - 255                   */
-        /* NOTE: At this point onwards min & max is 0 and 255 respectively   */
+        printf("INFO   : data input from %s\n", fits_file_name);
 
 
         /* 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;
-        switch (scale)
-        {
-        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;
+        /*-------------------------------------------------------------------*/
 
 
-        default:                                   /* Linear scale (min-max) */
+        /* IF user has provided a range, fix them as min & max in image */
+        if (usrclip == 1)
+        {
+            printinfo("user defined pixel range");
             for (i = 0; i < npixels; ++i)
             for (i = 0; i < npixels; ++i)
-                image_buffer[i] = (int)(data[i]);
-            break;
+            {
+                if (data[i] > datamax) data[i] = datamax;
+                if (data[i] < datamin) data[i] = datamin;
+            } /*endfor*/
         }
 
         }
 
-        /* initialize image histogram. ensure all are zeroes in hist[]       */
-        for (i = 0; i <= JMAXVAL; ++i) hist[i] = 0;
+        scale_pixels(scale, npixels, data, &image_buffer);
 
 
-        /* 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 (process)
+        /* Before we write jpeg, check if there is any requirement to negate
+         * the image (usrnegt = 1)                                           */
+        if (usrnegt == 1)
         {
         {
-        case 1 :                                         /* contrast stretch */
-            printf("INFO   : Performing contrast 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;
-
+            printinfo("Negating Image");
+            for (i = 0; i <  npixels; ++i) image_buffer[i] ^= 0xff;
+        }
 
 
-        case 2 :                                   /* histogram equalization */
-            printf("INFO   : Performing Histogram Equalization\n");
-            for (i = 0; i <  npixels; ++i)
-                image_buffer[i] = cumhist[image_buffer[i]]*255;
-            break;
+        if (usrzoom == 1)
+        {
+            printf("INFO   : Image zoom factor = %3.2f\n", zoomfact);
+            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*/
+        if (!jpeg_file) printerro("Unable to create output file");
         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)
@@ -374,6 +315,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*/
 
diff --git a/src/fits2jpeg.h b/src/fits2jpeg.h
new file mode 100644 (file)
index 0000000..accff93
--- /dev/null
@@ -0,0 +1,61 @@
+/***************************************************************************
+ * This file is a part of CADS/UVS fits2jpeg conversion software           *
+ *   Copyright (C) 2012 by CADS/UV Software Team,                          *
+ *                         Indian Institute of Astrophysics                *
+ *                         Bangalore 560034                                *
+ *                         cads_AT_iiap.res.in                             *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/*Header Definitions*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+#include <ctype.h>
+#include <math.h>
+#include <errno.h>
+#include <libgen.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <fitsio2.h>
+#include <jpeglib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#define PROGRAM "fits2jpeg"
+#define r2d (90./atan2(1,0))
+#define MAX_TEXT 1024
+
+int my_getopt(int, char * const *, const char *);
+int make_dir(char *, mode_t);
+int make_tree(char *, mode_t);
+void banner(void);
+void usage(void);
+void signals_handler(int);
+void set_signals(void);
+void printinfo(const char *);
+void printwarn(const char *);
+void printerro(const char *);
+void read_fits(char *, long *, long *, float **);
+void scale_pixels(int, unsigned int, float *, JSAMPLE **);
+void resize_image(long *, long *, float, JSAMPLE **);
+char *strdup(const char *);
diff --git a/src/image.c b/src/image.c
new file mode 100644 (file)
index 0000000..a47b9b7
--- /dev/null
@@ -0,0 +1,252 @@
+/***************************************************************************
+ * This file is a part of CADS/UVS fits2jpeg conversion software           *
+ *   Copyright (C) 2012 by CADS/UV Software Team,                          *
+ *                         Indian Institute of Astrophysics                *
+ *                         Bangalore 560034                                *
+ *                         cads_AT_iiap.res.in                             *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+/*Header Definitions*/
+#include "fits2jpeg.h"
+
+/*---------------------------------------------------------------------------*
+ * READ_FITS: To reads data from a fits image file.. (isn't that obvious?)
+ *---------------------------------------------------------------------------*/
+void read_fits(char * fits_file_name, long * xdim, long * ydim, float ** data)
+{
+    fitsfile *fptr;
+    int status = 0, nfound, anynull;
+    long naxes[2];
+    long npixels;
+    float nullval = 0.0;
+
+    fits_open_file(&fptr, fits_file_name, READONLY, &status);
+    fits_read_keys_lng(fptr, "NAXIS", 1, 2, naxes, &nfound, &status);
+    if (status)
+        printerro(strcat(fits_file_name, " <-- Failed to open the file"));
+
+    /* Read in data */
+    npixels = naxes[0] * naxes[1];
+    (*data) = malloc(sizeof(float) * npixels);
+
+    nullval = 0;
+    if (fits_read_img(fptr, TFLOAT, 1, npixels, &nullval, (*data), &anynull,
+        &status))
+        printerro(strcat(fits_file_name, " has no valid fits image data"));
+
+    *xdim = naxes[0];
+    *ydim = naxes[1];
+
+    fits_close_file(fptr, &status);
+}
+
+/*---------------------------------------------------------------------------*
+ * 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;
+    int JMAXVAL = 255;
+    float datamax = 0.0, datamin = 0.0, tmp = 0.0;
+    float hist[256] = {0.0}, cumhist[256] = {0.0};
+    float scl_data = 0.0;
+
+
+    /* first find min & max in data                                          */
+    datamax = -1.0 * FLT_MAX;
+    datamin = FLT_MAX;
+    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       */
+    datamax = (float)JMAXVAL;
+    datamin = 0.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];
+
+    /* Allocate image buffer */
+    (*image_buffer) = malloc(sizeof(unsigned char) * npixels);
+
+
+    /* Linear scale (min-max) : This is the default scaling
+     * 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)
+    {
+        case 1 :                                              /* Square root */
+            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 */
+            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 */
+            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 */
+            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 */
+            /* 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;
+
+        case 6 :                                   /* histogram equalization */
+            for (i = 0; i <  npixels; ++i)
+                (*image_buffer)[i] = cumhist[(*image_buffer)[i]] * JMAXVAL;
+            break;
+        default :
+            break;
+    }
+}
+
+/*---------------------------------------------------------------------------*
+ * RESIZE_IMAGE: Scales down/up the image_buffer using bilinear scaling
+ * Based on an article by "John" at
+ * http://tech-algorithm.com/articles/bilinear-image-scaling/
+ *---------------------------------------------------------------------------*/
+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   = malloc(sizeof(unsigned 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(unsigned char) * npixels);
+    for (i = 0; i <  npixels; ++i)
+        (*image_buffer)[i] = buff[i];
+    free(buff);
+}
diff --git a/src/messages.c b/src/messages.c
new file mode 100644 (file)
index 0000000..ed4063e
--- /dev/null
@@ -0,0 +1,99 @@
+/***************************************************************************
+ * This file is a part of CADS/UVS fits2jpeg conversion software           *
+ *   Copyright (C) 2012 by CADS/UV Software Team,                          *
+ *                         Indian Institute of Astrophysics                *
+ *                         Bangalore 560034                                *
+ *                         cads_AT_iiap.res.in                             *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+/*Header Definitions*/
+#include "fits2jpeg.h"
+
+/*---------------------------------------------------------------------------*/
+void 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 [options] <fits_file>\n");
+    printf ("          Name of fits image file <fits_file> is mandatory.\n");
+    printf ("          Optional parameters are listed below: \n\n");
+    printf ("    -h help                                                \n");
+    printf ("       Print this help message and exit                    \n\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\n");
+    printf ("    -n                                                     \n");
+    printf ("       Negate the image                                    \n\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\n");
+    printf ("    -d <path/to/output/directory>                          \n");
+    printf ("       Write jpeg file to this specified directory. Will   \n");
+    printf ("       create it if needed. Default is to write jpeg in the\n");
+    printf ("       same directory as fits image file                   \n\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 ("           :10          Clip everything above 10           \n");
+    printf ("         10:            Clip everything below 10           \n\n");
+    printf ("    -z <zoomfactor>                                        \n");
+    printf ("       Resize/Scale output image by <zoomfactor>. Eg:      \n");
+    printf ("         0.5            Shrink output to half of input     \n");
+    printf ("         2.0            Magnify output to double the size  \n");
+    printf ("                        Allowed range: 0.01 to 4.0         \n");
+    printf ("       NOTE: Zooming will be carried out after all other   \n");
+    printf ("             operations, before writing out jpeg image     \n\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);
+}
+
+void printinfo(const char * msg)
+{
+    fprintf(stdout, "INFO   : %s\n", msg);
+}
+
+void printwarn(const char * msg)
+{
+    fprintf(stdout, "WARNING: %s\n", msg);
+}
+
+void printerro(const char * msg)
+{
+    fprintf(stderr, "ERROR  : %s\n", msg);
+    exit(EXIT_FAILURE);
+}
+