1 /***************************************************************************
2  * This file is a part of CADS/UVS fits2jpeg conversion software           *
3  *   Copyright (C) 2012 by CADS/UV Software Team,                          *
4  *                         Indian Institute of Astrophysics                *
5  *                         Bangalore 560034                                *
6  *                         cads_AT_iiap.res.in                             *
7  *                                                                         *
8  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  *   This program is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
16  *   GNU General Public License for more details.                          *
17  *                                                                         *
18  *   You should have received a copy of the GNU General Public License     *
19  *   along with this program; if not, write to the                         *
20  *   Free Software Foundation, Inc.,                                       *
21  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
22  ***************************************************************************/
24 /*Header Definitions*/
25 #include "fits2jpeg.h"
27 /*---------------------------------------------------------------------------*
28  * SCALE_PIXELS: Changes the pixel scale to linear/log/sqroot/etc..
29  *---------------------------------------------------------------------------*/
30 void scale_pixels(int scale, unsigned int npixels,
31                  float *data, JSAMPLE *image_buffer)
32 {
33     unsigned int i = 0;
34     int JMAXVAL = 255;
35     float datamax = 0.0, datamin = 0.0, tmp = 0.0;
36     float hist[256] = {0.0}, cumhist[256] = {0.0};
37     float scl_data = 0.0;
40     /* first find min & max in data                                          */
41     datamax = -1.0 * FLT_MAX;
42     datamin = FLT_MAX;
43     for (i = 0; i < npixels; ++i)
44     {
45         if (data[i] > datamax) datamax = data[i];
46         if (data[i] < datamin) datamin = data[i];
47     } /*endfor*/
50     /* Convert data into bytscaled values for jpeg file                     */
51     /* the dynamic range is reduced to 255 for jpeg                         */
52     scl_data = (datamax - datamin)/(float)JMAXVAL;
54     for (i = 0; i < npixels; ++i)
55         data[i] = (data[i] - datamin)/scl_data;
58     /* All data is now squeezed into the range 0 - 255                       */
59     /* NOTE: At this point onwards min & max is 0 and 255 respectively       */
60     datamax = (float)JMAXVAL;
61     datamin = 0.0;
63     /* initialize image histogram. ensure all are zeroes in hist[]           */
64     /*-----------------------------------------------------------------------*/
65     for (i = 0; i <= JMAXVAL; ++i) hist[i] = 0;
67     /* construct the image histogram */
68     tmp = 1.0/(float)npixels;
69     for (i = 0; i <= npixels; ++i)
70         hist[(int)floor(data[i])] += tmp;
72     /* And the cumulative histogram */
73     cumhist[0] = hist[0];
74     for (i = 1; i <= JMAXVAL; ++i)
75         cumhist[i] += cumhist[i - 1] + hist[i];
77     /* Linear scale (min-max) : This is the default scaling
78      * histo-eq will fail if we dont generate image_buffer here              */
79     for (i = 0; i < npixels; ++i)
80         image_buffer[i] = (int)(data[i]);
82     /*-----------------------------------------------------------------------*/
85     switch (scale)
86     {
87         case 1 :                                              /* Square root */
88             printinfo("Using square-root scale");
89             scl_data = sqrt((float)JMAXVAL)/(float)JMAXVAL;
90             for (i = 0; i < npixels; ++i)
91                 image_buffer[i] = (int)(sqrt(data[i])/scl_data);
92             break;
94         case 2 :                                                   /* Square */
95             printinfo("Using quadratic scale");
96             scl_data = pow((float)JMAXVAL,2)/(float)JMAXVAL;
97             for (i = 0; i < npixels; ++i)
98                 image_buffer[i] = (int)abs((pow(data[i],2) - 1.0)/scl_data);
99             break;
101         case 3 :                                                    /* Cubic */
102             printinfo("Using cubic scale");
103             scl_data = pow((float)JMAXVAL,3)/(float)JMAXVAL;
104             for (i = 0; i < npixels; ++i)
105                 image_buffer[i] = (int)abs((pow(data[i],3) - 1.0)/scl_data);
106             break;
108         case 4 :                                                      /* log */
109             printinfo("Using log scale");
110             scl_data = log(1.0 + (float)JMAXVAL)/(float)JMAXVAL;
111             for (i = 0; i < npixels; ++i)
112                 image_buffer[i] = (int)((log(abs(data[i]) + 1.0))/scl_data);
113             break;
115         case 5 :
116             /* contrast stretch */
117             printinfo("Performing histogram stretch (normalization)");
119             /* We need to go through the cumulative histogram to pick the
120              *  appropriate values for datamin and datamax               */
121             i = 0;
122             while (i < JMAXVAL)
123             {
124                 if (cumhist[i] >= 0.01)
125                 {
126                     datamin = (float) i;
127                     break;
128                 }
129                 i++;
130             }
131             i = JMAXVAL;
132             while (i > 0)
133             {
134                 if (cumhist[i] <= 0.99)
135                 {
136                     datamax = (float) i;
137                     break;
138                 }
139                 i--;
140             }
141             scl_data = (datamax - datamin)/(float)JMAXVAL;
142             for (i = 0; i < npixels; ++i)
143             {
144                 if (image_buffer[i] >= datamax)
145                     image_buffer[i] = JMAXVAL;
146                 else if (image_buffer[i] <= datamin)
147                     image_buffer[i] = 0;
148                 else
149                     image_buffer[i] = (int) abs((image_buffer[i]
150                                     - datamin)/scl_data);
151             }
152             break;
154         case 6 :
155             /* histogram equalization */
156             printinfo("Performing Histogram Equalization");
157             for (i = 0; i <  npixels; ++i)
158                 image_buffer[i] = cumhist[image_buffer[i]] * JMAXVAL;
159             break;
160         default :
161             printinfo("Using linear scale");
162             break;
163     }
167 /*---------------------------------------------------------------------------*
168  * RESIZE_IMAGE: Scales down/up the image_buffer
169  *---------------------------------------------------------------------------*/
170 void resize_image(long *xdim, long *ydim, float zoomfact, JSAMPLE *image_buffer)
172     int offset = 0, index = 0;
173     int A, B, C, D, x, y, gray;
174     JSAMPLE *buff;
175     unsigned int i = 0, j = 0;
176     unsigned long npixels = 0;
177     long w = *xdim, h = *ydim;
178     long zxdim = 0, zydim = 0;
179     float xdiff, ydiff, xratio, yratio;
181     zxdim  = (int)(w * zoomfact);
182     zydim  = (int)(h * zoomfact);
184     npixels= zxdim * zydim;
186     xratio = ((float)(w - 1))/zxdim;
187     yratio = ((float)(h - 1))/zydim;
189                                      /* allocate space for *buff */
190     buff   = (unsigned char *) malloc(sizeof(char) * zxdim * zydim);
192     index  = 0;
193     offset = 0;
194     for (i = 0; i < zydim; i++)
195     {
196         y     = (int)(yratio * i);
197         ydiff = (yratio * i) - y;
199         for (j = 0; j < zxdim; j++)
200         {
201             x = (int)(xratio * j);
203             xdiff = (xratio * j) - x;
204             index = y * w + x;
206             A = image_buffer[index]         & 0xff;
207             B = image_buffer[index + 1]     & 0xff;
208             C = image_buffer[index + w]     & 0xff;
209             D = image_buffer[index + w + 1] & 0xff;
211             gray = (int)(A * (1 - xdiff) * (1 - ydiff)
212                  +       B * (xdiff)     * (1 - ydiff)
213                  +       C * (ydiff)     * (1 - xdiff)
214                  +       D * (xdiff)     * (ydiff)
215                     );
216             buff[offset++] = gray;
217         }
218     }
219     *xdim = zxdim;
220     *ydim = zydim;
221     image_buffer = realloc(image_buffer, sizeof(char) * npixels);
222     if (!image_buffer)
223         printerro("Failed to allocate memory");
225     for (i = 0; i <  npixels; ++i)
226         image_buffer[i] = buff[i];