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
-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
 -----------
-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
@@ -26,9 +25,10 @@ Pre-requisites:
     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:
 
 
@@ -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
-     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.
 
-  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
 -------
 
-  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
+       Prints out a usage-help message, much like this section.
 
     -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
-
-    -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.,
 
@@ -107,32 +136,55 @@ file named `INSTALL.txt'.
 
   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
-     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
 ----------------
-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]
@@ -141,10 +193,9 @@ in the user manual, which is yet to be written :(
 
 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
@@ -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.
 
+
 -----------------------------------------------------------
 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])
@@ -13,15 +13,17 @@ AC_PROG_MAKE_SET
 # Checks for libraries.
 
 # Checks for header files.
-AC_CHECK_HEADERS([stdio.h stdlib.h string.h math.h])
+#AC_CHECK_HEADERS([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 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              #
 #---------------------------------------------------------------------#
index 4b35902..148dfb3 100644 (file)
@@ -1,3 +1,5 @@
 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                                *
@@ -29,6 +30,7 @@
 
   Reconstruction and additional features: Reks
  *---------------------------------------------------------------------------*/
+
 /*---------------------------------------------------------------------------
   Modification History
 
 
   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;
-/*---------------------------------------------------------------------------*/
-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[])
 {
-    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 tmp = 0.0;
-    float hist[256] = {0.0}, cumhist[256] = {0.0};
     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;
-
+    mode_t mode = 0755;
     FILE *jpeg_file;
-
     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 -----------------------*/
 
-    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 */
-    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':
-            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':
-            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;
 
-        case '*':
-            usage();
+        default :
+            printerro("You can try 'fits2jpeg -h' for valid options");
             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 -------------------------*/
 
@@ -205,168 +249,65 @@ int main(int argc, char *argv[], char *envp[])
         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..                             */
-        /* 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)
-                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*/
+        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 */
-        jpeg_file = fopen(jpeg_file_name, "wb");/* Open JPEG file for writing*/
         jpeg_stdio_dest(&cinfo, jpeg_file); /* Send compressed data to stdio */
-        cinfo.image_width = naxes[0];                         /* Image width */
-        cinfo.image_height = naxes[1];                       /* Image height */
+        cinfo.image_width = xdim;                             /* Image width */
+        cinfo.image_height = ydim;                           /* Image height */
         cinfo.input_components = 1;            /* Number of colors per pixel */
         cinfo.in_color_space = JCS_GRAYSCALE;   /* colorspace of input image */
         jpeg_set_defaults(&cinfo);                      /* Set JPEG defaults */
+        jpeg_set_quality(&cinfo, jpgqual, TRUE);  /* Set jpeg quality factor */
         jpeg_start_compress(&cinfo, TRUE);       /* default data compression */
-        row_stride = naxes[0];            /* JSAMPLEs per row inimage buffer */
+        row_stride = xdim;                /* JSAMPLEs per row inimage buffer */
 
         /* Now we have to turn the data upside down                          */
         while (cinfo.next_scanline < cinfo.image_height)
@@ -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];
+
             (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);
+}
+