summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c217f20)
raw | patch | inline | side by side (parent: c217f20)
author | Rekhesh Mohan <reks@iiap.res.in> | |
Thu, 12 Jul 2012 15:40:31 +0000 (21:10 +0530) | ||
committer | Rekhesh Mohan <reks@iiap.res.in> | |
Thu, 12 Jul 2012 15:40:31 +0000 (21:10 +0530) |
README.txt | patch | blob | history | |
configure.ac | patch | blob | history | |
src/Makefile.am | patch | blob | history | |
src/filesys.c | [new file with mode: 0644] | patch | blob |
src/fits2jpeg.c | patch | blob | history | |
src/fits2jpeg.h | patch | blob | history | |
src/image.c | patch | blob | history | |
src/messages.c | patch | blob | history |
diff --git a/README.txt b/README.txt
--- a/README.txt
+++ b/README.txt
-------
Usage: fits2jpeg [options] <fits_file>
-
- Options are:
+ 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:
-h help
+ Prints out a usage-help message, much like this section.
-s <scale_type>
scale for output image, where <scale_type> can be:
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
:10 Clip everything above 10
10: Clip everything below 10
- -n
- Negate the image.
-
- -q <value>
- jpeg quality factor. Defines the jpeg encoding quality
- Valid range: 0-100, default value: 100, which is for
- best quality (and largest file size).
-
-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.,
Wild card entries allowed in <fits_file>. For eg: *.fits, m31*.fits
ngc???.fits etc.
- More examples:
+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
+
+ 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.
-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.
+ 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
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
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
-AC_INIT([CADS_fits2jpeg], [1.95], [cads@iiap.res.in])
+AC_INIT([CADS_fits2jpeg], [1.99], [cads@iiap.res.in])
AC_LANG_C
AM_INIT_AUTOMAKE([-Wall -Werror])
AC_CONFIG_SRCDIR([config.h.in])
# Checks for libraries.
# Checks for header files.
-AC_CHECK_HEADERS([string.h math.h float.h ctype.h libgen.h dirent.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.
diff --git a/src/Makefile.am b/src/Makefile.am
--- a/src/Makefile.am
+++ b/src/Makefile.am
bin_PROGRAMS = fits2jpeg
-fits2jpeg_SOURCES = fits2jpeg.c messages.c getopt.c image.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
--- /dev/null
+++ b/src/filesys.c
@@ -0,0 +1,77 @@
+/***************************************************************************
+ * 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"
+
+/*---------------------------------------------------------------------------*/
+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;
+}
+
+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;
+}
+
+char *strdup(const char *str)
+{
+ int n = strlen(str) + 1;
+ char *dup = malloc(n);
+ if(dup)
+ {
+ strcpy(dup, str);
+ }
+ return dup;
+}
diff --git a/src/fits2jpeg.c b/src/fits2jpeg.c
--- a/src/fits2jpeg.c
+++ b/src/fits2jpeg.c
/***************************************************************************
+ * 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 *
5. jpeg quality factor
6. pixel scaling operations moved to image.c
7. Image resizing
- TODO
- 1. move fits read to image.c
- 2. specify output directory
+ 8. moved fits read to image.c
+ 9. Option to specify output directory
*---------------------------------------------------------------------------*/
#include "fits2jpeg.h"
/*--------------------------- Begin Main Progam -----------------------------*/
int main(int argc, char *argv[], char *envp[])
{
- fitsfile *fptr;
-
- int scale = 0, status = 0, jpgqual = 100, nfound, anynull;
- unsigned int i = 0, j = 0, usrclip = 0, usrnegt = 0, usrzoom = 0;
- long xdim = 0, ydim = 0, naxes[2], row_stride;
+ 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, nullval = 0.0, zoomfact = 1.0;
+ float datamin = 0.0, datamax = 0.0, zoomfact = 1.0;
float *data;
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;
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, "e:hnq:r:s:z:" ) ) != EOF )
+ while ( ( opt = my_getopt ( argc, argv, "d:e:hnq:r:s:z:" ) ) != EOF )
switch ( opt )
{
case 's':
- if (strcmp(optarg, "linear") ==0) scale = 0;
- else if (strcmp(optarg, "sqroot") ==0) scale = 1;
- else if (strcmp(optarg, "square") ==0) scale = 2;
- else if (strcmp(optarg, "cubic") ==0) scale = 3;
- else if (strcmp(optarg, "log") ==0) scale = 4;
- else if (strcmp(optarg, "normalize")==0) scale = 5;
- else if (strcmp(optarg, "equalize") ==0) scale = 6;
+ 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':
/* Need to preserve it for backward compatibility */
- if (strcmp(optarg, "normalize")==0) scale = 5;
- else if (strcmp(optarg, "equalize") ==0) scale = 6;
+ if (strcmp(optarg, "normalize") == 0) scale = 5;
+ else if (strcmp(optarg, "equalize") == 0) scale = 6;
else
printerro(strcat(optarg, " -- Unrecognized option"));
break;
break;
case 'z' :
-
- /* Do something to scale image
- */
zoomfact = atof(optarg);
- zoomfact = abs(zoomfact);
+ 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;
printerro("You can try 'fits2jpeg -h' for valid options");
break;
}
-
+ if (scale == 0) printinfo("Using linear scale");
if ((argc - optindex) == 0) usage(); /* Someone gave only options */
/*---------------------- Begin processing files -------------------------*/
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)
- printerro(strcat(fits_file_name, " <-- Failed to open the file"));
+ if (customdir == 1)
+ {
+ if (output_dir[strlen(output_dir) - 1] != '/')
+ strcat(output_dir, "/");
- /* Read in data */
- npixels = naxes[0] * naxes[1];
- data = malloc(sizeof(float) * npixels);
+ strcat(output_dir, basename(jpeg_file_name));
+ strcpy(jpeg_file_name, output_dir);
+ }
- 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"));
+ read_fits(fits_file_name, &xdim, &ydim, &data);
+ npixels = xdim * ydim;
- fits_close_file(fptr, &status);
- /*Close data file*/
printf("INFO : data input from %s\n", fits_file_name);
for (i = 0; i < npixels; ++i) image_buffer[i] ^= 0xff;
}
- xdim = naxes[0];
- ydim = naxes[1];
if (usrzoom == 1)
{
printf("INFO : Image zoom factor = %3.2f\n", zoomfact);
/*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_stdio_dest(&cinfo, jpeg_file); /* Send compressed data to stdio */
diff --git a/src/fits2jpeg.h b/src/fits2jpeg.h
--- a/src/fits2jpeg.h
+++ b/src/fits2jpeg.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 *);
-void PRINT_BANNER(void);
+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
--- a/src/image.c
+++ b/src/image.c
/*Header Definitions*/
#include "fits2jpeg.h"
+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..
*---------------------------------------------------------------------------*/
switch (scale)
{
case 1 : /* Square root */
- printinfo("Using square-root scale");
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 */
- printinfo("Using quadratic scale");
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 */
- printinfo("Using cubic scale");
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 */
- printinfo("Using log scale");
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 */
- printinfo("Performing histogram stretch (normalization)");
-
+ case 5 : /* contrast stretch */
/* We need to go through the cumulative histogram to pick the
- * appropriate values for datamin and datamax */
+ * appropriate values for datamin and datamax */
i = 0;
while (i < JMAXVAL)
{
}
break;
- case 6 :
- /* histogram equalization */
- printinfo("Performing Histogram Equalization");
+ case 6 : /* histogram equalization */
for (i = 0; i < npixels; ++i)
(*image_buffer)[i] = cumhist[(*image_buffer)[i]] * JMAXVAL;
break;
default :
- printinfo("Using linear scale");
break;
}
}
diff --git a/src/messages.c b/src/messages.c
--- a/src/messages.c
+++ b/src/messages.c
#include "fits2jpeg.h"
/*---------------------------------------------------------------------------*/
-void PRINT_BANNER()
+void banner()
{
printf("\n");
printf(" %s %s\n", PROGRAM, VERSION);
void usage()
{
printf ("\n Usage: fits2jpeg [options] <fits_file>\n");
- printf (" Options are: \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 (" cubic for cubic scale \n");
printf (" log for log scale \n");
printf (" normalize for linear histogram stretch \n");
- printf (" equalize for histogram equalization \n");
+ printf (" 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");
- printf (" -n \n");
- printf (" Negate the image \n");
- printf (" -q <value> \n");
- printf (" quality factor. Defines the jpeg encoding quality \n");
- printf (" Valid range: 0-100, default value: 100 (max.quality)\n");
+ printf (" 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");
+ 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");