1 #include <loader_common.h>
4 //TODO: add a color table.
5 //invert gray scale, Check if feh or qiv can do this.
6 // add option to check for datamin and datamax on the header
7 // make it more robust. datamax > datamin
8 // write the fits writer!
10 #define SWAP32(x) (x) = \
11 ((((x) & 0x000000ff ) << 24) |\
12 (((x) & 0x0000ff00 ) << 8) |\
13 (((x) & 0x00ff0000 ) >> 8) |\
14 (((x) & 0xff000000 ) >> 24))
16 void getRGB( double, double, double, short, short, DATA8 *, DATA8 *, DATA8 * );
19 load(ImlibImage * im, ImlibProgressFunction progress,
20 char progress_granularity, char immediate_load)
23 int w = 0, h = 0, alpha = 0;
30 //f = fopen(im->real_file, "rb");
31 if ( fits_open_file( &f, im->real_file, READONLY, &status) ) {
42 //char buf[256], buf2[256];
44 /* read the NAXIS1 and NAXIS2 keyword to get image size */
45 if ( fits_read_keys_lng( f, "NAXIS", 1, 2, naxes, &nfound, &status ) ){
46 fits_close_file(f, &status);
54 if (!fgets(buf, 255, f))
60 sscanf(buf, "%s %i %i %i", buf2, &w, &h, &alpha);
61 if (strcmp(buf2, "ARGB"))
67 if (!IMAGE_DIMENSIONS_OK(w, h))
69 fits_close_file(f, &status);
78 SET_FLAG(im->flags, F_HAS_ALPHA);
80 UNSET_FLAG(im->flags, F_HAS_ALPHA);
81 im->format = strdup("fits");
84 if (((!im->data) && (im->loader)) || (immediate_load) || (progress))
90 double *buffer, datamin, datamax, nullval = 0, *subim;
93 long *bin, nmax = 0, ndataok, sumpix = 0;
94 int nbin, k, kmin, mostfreq = 0, nsub;
96 char *envdmin, *envdmax;
97 short color, inv, stepx, stepy;
99 fprintf(stderr, "%s\n", im->real_file );
100 /* must set the im->data member before callign progress function */
101 ptr = im->data = malloc(w * h * sizeof(DATA32));
103 buffer = malloc( nbuffer * sizeof( double ) );
107 fits_close_file(f, &status);
112 envdmin = getenv( "DATAMIN" );
113 envdmax = getenv( "DATAMAX" );
114 if( envdmin != NULL && envdmax != NULL ){
115 datamin = atof( envdmin );
116 datamax = atof( envdmax );
117 fprintf(stderr, "ENV:data min %g, max %g\n", datamin, datamax);}
121 datamax = -HUGE_VALF;
125 if( stepx == 0 ) stepx = 1;
126 if( stepy == 0 ) stepy = 1;
128 fprintf(stderr, "subsample image: %d %d\n", stepx, stepy );
130 //Find min max and save a subsample image
133 subim = malloc( (w / stepx + 1)*(h / stepy +1)*sizeof( double ) );
134 fprintf(stderr, "image: %d %d %d \n", w / stepx * h / stepy, w/stepx+1,h/stepy+1);
135 for (y = 0; y < h; y += stepy )
137 fits_read_img( f, TDOUBLE, fpixel, nbuffer, &nullval,
138 buffer, &anynull, &status);
139 for( x = 0; x < w; x += stepx ){
140 subim[ nsub ] = buffer[ x ];
142 if( buffer[ x ] > datamax )
143 datamax = buffer[ x ];
144 if( buffer[ x ] < datamin )
145 datamin = buffer[ x ];
147 fpixel += nbuffer * stepy;
149 fprintf(stderr, "data min %g, max %g\n", datamin, datamax);
150 fprintf(stderr, "subimage has %d pixels out of %d... %d %d\n", nsub, w*h, y, x);
152 nbin = 4 * sqrt( datamax - datamin );
153 if( nbin > 5000 ) nbin = 1000;
154 binw = ( datamax - datamin ) / nbin;
155 fprintf(stderr, "nbin and bin width:%d %g\n", nbin, binw);
156 bin = calloc( nbin, sizeof( long ) );
159 for( y = 0; y < nsub; y++ ){
160 for( k = 0; k < nbin; k++ ){
161 if( subim[ y ] >= k*binw && subim[ y ] < ( k+1 )*binw ){
170 for (y = 0; y < h; y++)
172 fits_read_img( f, TDOUBLE, fpixel, nbuffer, &nullval,
173 buffer, &anynull, &status);
174 for( x = 0; x < w; x++ ){
175 for( k = 0; k < nbin; k++ ){
176 if( buffer[ x ] >= k * binw &&
177 buffer[ x ] < ( k + 1 ) * binw ){
187 //Find most frequent pixel value
188 for( k = 0; k < nbin; k++ ){
189 if( bin[ k ] > nmax ){
193 //fprintf(stderr, "%ld ", bin[ k ] );
195 fprintf(stderr, "\nmostfreq and nmax = %d %ld ", mostfreq, nmax );
197 //Set new DATAMIN. look for FWHM on a log scale
198 nmax = log( nmax ) / 2;
199 datamin = ( mostfreq + 0.5 ) * binw;
200 for( k = mostfreq - 1; k >= 0; k-- ){
202 if( log( bin[ k ] ) < nmax ){
204 datamin = ( (kmin) + 0.5 ) * binw;
208 if( k == 0 ){ //case were we have one single peak surrounded by 0
210 datamin = ( (kmin) + 0.5 ) * binw;
213 //Set new DATAMAX when we have 99.5% of the pixels accounted for
216 for( k = 0; k < kmin; k++)
218 //ndataok = h * w; //To get values closer to ds9's uncomment this
219 ndataok = 0.997 * ndataok;
220 for( k = kmin; k < nbin; k++){
222 if( sumpix > ndataok )
225 datamax = ( ( k + 1 ) + 0.5 ) * binw;
230 // use the new datamin datamax values to rescale and create imlib im
235 for (y = 0; y < h; y++)
237 fits_read_img( f, TDOUBLE, fpixel, nbuffer, &nullval,
238 buffer, &anynull, &status);
240 for( x = w - 1; x >= 0; x-- ){
241 getRGB( buffer[ x ], datamin, datamax, color, inv, &r, &g, &b);
242 if( x == w / 100 && y == h / 100 ) fprintf( stderr, "\n%d %d %d %g\n",r,g,b, buffer[ x ]);
243 *ptr = (((( (0xff << 8) | r) << 8) | g) << 8) | b ;
253 per = (char)((100 * y) / im->h);
254 if (((per - pper) >= progress_granularity) ||
258 if (!progress(im, per, 0, (y - l), im->w, l))
260 fits_close_file(f, &status);
269 fprintf(stderr, "\ndata min %g, max %g\n", datamin, datamax);
274 fits_close_file(f, &status);
279 save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity)
283 int y, pl = 0, alpha = 0;
287 /* no image data? abort */
290 f = fopen(im->real_file, "wb");
293 if (im->flags & F_HAS_ALPHA)
295 fprintf(f, "ARGB %i %i %i\n", im->w, im->h, alpha);
297 for (y = 0; y < im->h; y++)
299 fwrite(ptr, im->w, 4, f);
306 per = (char)((100 * y) / im->h);
307 if (((per - pper) >= progress_granularity) || (y == (im->h - 1)))
310 if (!progress(im, per, 0, (y - l), im->w, l))
326 formats(ImlibLoader * l)
328 char *list_formats[] = { "fits", "fts", "fit" };
333 l->num_formats = (sizeof(list_formats) / sizeof(char *));
334 l->formats = malloc(sizeof(char *) * l->num_formats);
335 for (i = 0; i < l->num_formats; i++)
336 l->formats[i] = strdup(list_formats[i]);
340 void getRGB( double val, double min, double max, short color, short inv,
341 DATA8 *r, DATA8 *g, DATA8 *b ){
344 const float slsR[200]={0, 0.043442, 0.086883, 0.130325, 0.173767, 0.217208,
345 0.260650, 0.304092, 0.347533, 0.390975, 0.434417, 0.477858, 0.521300,
346 0.506742, 0.492183, 0.477625, 0.463067, 0.448508, 0.433950, 0.419392,
347 0.404833, 0.390275, 0.375717, 0.361158, 0.346600, 0.317717, 0.288833,
348 0.259950, 0.231067, 0.202183, 0.173300, 0.144417, 0.115533, 0.086650,
349 0.057767, 0.028883, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
350 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
351 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.033167,
352 0.066333, 0.099500, 0.132667, 0.165833, 0.199000, 0.232167, 0.265333,
353 0.298500, 0.331667, 0.364833, 0.398000, 0.430950, 0.463900, 0.496850,
354 0.529800, 0.562750, 0.595700, 0.628650, 0.661600, 0.694550, 0.727500,
355 0.760450, 0.793400, 0.810617, 0.827833, 0.845050, 0.862267, 0.879483,
356 0.896700, 0.913917, 0.931133, 0.948350, 0.965567, 0.982783, 1, 0.995725,
357 0.991450, 0.987175, 0.982900, 0.978625, 0.974350, 0.970075, 0.965800,
358 0.961525, 0.957250, 0.952975, 0.948700, 0.952975, 0.957250, 0.961525,
359 0.965800, 0.970075, 0.974350, 0.978625, 0.982900, 0.987175, 0.991450,
360 0.995725, 1, 0.998342, 0.996683, 0.995025, 0.993367, 0.991708, 0.990050,
361 0.988392, 0.986733, 0.985075, 0.983417, 0.981758, 0.980100, 0.955925,
362 0.931750, 0.907575, 0.883400, 0.859225, 0.835050, 0.810875, 0.786700,
363 0.762525, 0.738350, 0.714175, 0.690000, 0.715833, 0.741667, 0.767500,
364 0.793333, 0.819167, 0.845000, 0.870833, 0.896667, 0.922500, 0.948333,
365 0.974167, 1, 1, 1, 1, 1, 1, 1, 1};
367 const float slsG[200]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
368 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.019817,
369 0.039633, 0.059450, 0.079267, 0.099083, 0.118900, 0.138717, 0.158533,
370 0.178350, 0.198167, 0.217983, 0.237800, 0.268533, 0.299267, 0.330000,
371 0.360733, 0.391467, 0.422200, 0.452933, 0.483667, 0.514400, 0.545133,
372 0.575867, 0.606600, 0.631733, 0.656867, 0.682000, 0.707133, 0.732267,
373 0.757400, 0.782533, 0.807667, 0.832800, 0.857933, 0.883067, 0.908200,
374 0.901908, 0.895617, 0.889325, 0.883033, 0.876742, 0.870450, 0.864158,
375 0.857867, 0.851575, 0.845283, 0.838992, 0.832700, 0.832308, 0.831917,
376 0.831525, 0.831133, 0.830742, 0.830350, 0.829958, 0.829567, 0.829175,
377 0.828783, 0.828392, 0.828000, 0.834167, 0.840333, 0.846500, 0.852667,
378 0.858833, 0.865000, 0.871167, 0.877333, 0.883500, 0.889667, 0.895833,
379 0.902000, 0.902000, 0.902000, 0.902000, 0.902000, 0.902000, 0.902000,
380 0.902000, 0.902000, 0.902000, 0.902000, 0.902000, 0.902000, 0.897133,
381 0.892267, 0.887400, 0.882533, 0.877667, 0.872800, 0.867933, 0.863067,
382 0.858200, 0.853333, 0.848467, 0.843600, 0.824892, 0.806183, 0.787475,
383 0.768767, 0.750058, 0.731350, 0.712642, 0.693933, 0.675225, 0.656517,
384 0.637808, 0.619100, 0.600408, 0.581717, 0.563025, 0.544333, 0.525642,
385 0.506950, 0.488258, 0.469567, 0.450875, 0.432183, 0.413492, 0.394800,
386 0.361900, 0.329000, 0.296100, 0.263200, 0.230300, 0.197400, 0.164500,
387 0.131600, 0.098700, 0.065800, 0.032900, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
388 0, 0, 0, 0.083333, 0.166667, 0.250000, 0.333333, 0.416667, 0.500000,
389 0.583333, 0.666667, 0.750000, 0.833333, 0.916667, 1, 1, 1, 1, 1, 1, 1,
392 const float slsB[200]={0, 0.052883, 0.105767, 0.158650, 0.211533, 0.264417,
393 0.317300, 0.370183, 0.423067, 0.475950, 0.528833, 0.581717, 0.634600,
394 0.640217, 0.645833, 0.651450, 0.657067, 0.662683, 0.668300, 0.673917,
395 0.679533, 0.685150, 0.690767, 0.696383, 0.702000, 0.712192, 0.722383,
396 0.732575, 0.742767, 0.752958, 0.763150, 0.773342, 0.783533, 0.793725,
397 0.803917, 0.814108, 0.824300, 0.838942, 0.853583, 0.868225, 0.882867,
398 0.897508, 0.912150, 0.926792, 0.941433, 0.956075, 0.970717, 0.985358,
399 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.975300, 0.950600, 0.925900,
400 0.901200, 0.876500, 0.851800, 0.827100, 0.802400, 0.777700, 0.753000,
401 0.728300, 0.703600, 0.676675, 0.649750, 0.622825, 0.595900, 0.568975,
402 0.542050, 0.515125, 0.488200, 0.461275, 0.434350, 0.407425, 0.380500,
403 0.354858, 0.329217, 0.303575, 0.277933, 0.252292, 0.226650, 0.201008,
404 0.175367, 0.149725, 0.124083, 0.098442, 0.072800, 0.066733, 0.060667,
405 0.054600, 0.048533, 0.042467, 0.036400, 0.030333, 0.024267, 0.018200,
406 0.012133, 0.006067, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.003983,
407 0.007967, 0.011950, 0.015933, 0.019917, 0.023900, 0.027883, 0.031867,
408 0.035850, 0.039833, 0.043817, 0.047800, 0.051600, 0.055400, 0.059200,
409 0.063000, 0.066800, 0.070600, 0.074400, 0.078200, 0.082000, 0.085800,
410 0.089600, 0.093400, 0.085617, 0.077833, 0.070050, 0.062267, 0.054483,
411 0.046700, 0.038917, 0.031133, 0.023350, 0.015567, 0.007783, 0, 0, 0,
412 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
413 0.083333, 0.166667, 0.250000, 0.333333, 0.416667, 0.500000, 0.583333,
414 0.666667, 0.750000, 0.833333, 0.916667, 1, 1, 1, 1, 1, 1, 1, 1};
422 fac = ( val - min ) / ( max - min );
424 if( inv ) fac = 1 - fac;
426 if( color == 0 ){ // gray
427 *r = ceil ( fac * 255 );
432 if( color == 1 ){ // color SLS
433 ind = ceil( fac * 199 ); // color table has 200 elements
434 *r = ceil( slsR[ ind ] * 255 );
435 *g = ceil( slsG[ ind ] * 255 );
436 *b = ceil( slsB[ ind ] * 255 );