A fits loader for the imlib2 library.
[zanmar/loader_fits] / loader_fits.c
1 #include "loader_common.h"
2 #include "fitsio.h"
3
4 #define SWAP32(x) (x) = \
5 ((((x) & 0x000000ff ) << 24) |\
6  (((x) & 0x0000ff00 ) << 8) |\
7  (((x) & 0x00ff0000 ) >> 8) |\
8  (((x) & 0xff000000 ) >> 24))
9
10 char
11 load(ImlibImage * im, ImlibProgressFunction progress,
12      char progress_granularity, char immediate_load)
13 {
14    int                 w = 0, h = 0, alpha = 0;
15    //FILE               *f;
16    fitsfile            *f;
17    int                 status;
18
19    if (im->data)
20       return 0;
21    //f = fopen(im->real_file, "rb");
22    if ( fits_open_file( &f, im->real_file, READONLY, &status) )
23          return 0;
24    
25
26    //if (!f)
27    //   return 0;
28
29    /* header */
30    {
31       long                naxes[2];
32       int                 nfound;
33       //char                buf[256], buf2[256];
34
35       /* read the NAXIS1 and NAXIS2 keyword to get image size */
36       if ( fits_read_keys_lng( f, "NAXIS", 1, 2, naxes, &nfound, &status ) ){
37            fits_close_file(f, &status);
38            return 0;
39       }
40       w = naxes[ 0 ];
41       h = naxes[ 1 ];
42     
43       /*
44       buf[0] = '\0';
45       if (!fgets(buf, 255, f))
46         {
47            fclose(f);
48            return 0;
49         }
50       buf2[0] = '\0';
51       sscanf(buf, "%s %i %i %i", buf2, &w, &h, &alpha);
52       if (strcmp(buf2, "ARGB"))
53         {
54            fclose(f);
55            return 0;
56         }
57         */
58       if (!IMAGE_DIMENSIONS_OK(w, h))
59         {
60            fits_close_file(f, &status);
61            //fclose(f);
62            return 0;
63         }
64       im->w = w;
65       im->h = h;
66       if (!im->format)
67         {
68            if (alpha)
69               SET_FLAG(im->flags, F_HAS_ALPHA);
70            else
71               UNSET_FLAG(im->flags, F_HAS_ALPHA);
72            im->format = strdup("fits");
73         }
74    }
75    if (((!im->data) && (im->loader)) || (immediate_load) || (progress))
76      {
77         DATA32             *ptr;
78         DATA8              gray;
79         int                 y, x, pl = 0;
80         char                pper = 0;
81         float              *buffer, datamin, datamax, nullval = 0;
82         int                anynull, nbuffer;
83         long               fpixel = 1;
84
85         //gray = ceil(floatvalue * 256)
86         //*ptr = ( ( ( ( (0xff << 8) | gray) << 8) | gray) << 8) | gray 
87
88         /* must set the im->data member before callign progress function */
89         ptr = im->data = malloc(w * h * sizeof(DATA32));
90         nbuffer = w;
91         buffer = malloc( nbuffer * sizeof( float ) );
92
93         if (!im->data)
94           {
95              fits_close_file(f, &status);
96              //fclose(f);
97              return 0;
98           }
99         datamin = 1E8;
100         datamax = -1E8;
101         for (y = 0; y < h; y++)
102           {
103              //fread(ptr, im->w, 4, f);
104              fits_read_img( f, TFLOAT, fpixel, nbuffer, &nullval,
105                           buffer, &anynull, &status);
106              for( x = 0; x < w; x++ ){
107                  if( buffer[ x ] > datamax ) 
108                      datamax = buffer[ x ];
109                  if( buffer[ x ] < datamin )
110                      datamin = buffer[ x ];
111              }
112
113              for( x = 0; x < w; x++ ){
114                  gray = ceil( ( buffer[ x ] - datamin ) / ( datamax - datamin ) * 256 );
115                  *ptr = ( ( ( ( (0xff << 8) | gray) << 8) | gray) << 8) | gray ;
116                  ptr++;
117              }
118
119              fpixel += nbuffer;
120              //*ptr = y;
121
122              //ptr += im->w;
123              if (progress)
124                {
125                   char                per;
126                   int                 l;
127
128                   per = (char)((100 * y) / im->h);
129                   if (((per - pper) >= progress_granularity) ||
130                       (y == (im->h - 1)))
131                     {
132                        l = y - pl;
133                        if (!progress(im, per, 0, (y - l), im->w, l))
134                          {
135                             fits_close_file(f, &status);
136                             //fclose(f);
137                             return 2;
138                          }
139                        pper = per;
140                        pl = y;
141                     }
142                }
143           }
144      }
145    //fclose(f);
146    fits_close_file(f, &status);
147    return 1;
148 }
149
150 char
151 save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity)
152 {
153    FILE               *f;
154    DATA32             *ptr;
155    int                 y, pl = 0, alpha = 0;
156    char                pper = 0;
157
158
159    /* no image data? abort */
160    if (!im->data)
161       return 0;
162    f = fopen(im->real_file, "wb");
163    if (!f)
164       return 0;
165    if (im->flags & F_HAS_ALPHA)
166       alpha = 1;
167    fprintf(f, "ARGB %i %i %i\n", im->w, im->h, alpha);
168    ptr = im->data;
169    for (y = 0; y < im->h; y++)
170      {
171         fwrite(ptr, im->w, 4, f);
172         ptr += im->w;
173         if (progress)
174           {
175              char                per;
176              int                 l;
177
178              per = (char)((100 * y) / im->h);
179              if (((per - pper) >= progress_granularity) || (y == (im->h - 1)))
180                {
181                   l = y - pl;
182                   if (!progress(im, per, 0, (y - l), im->w, l))
183                     {
184                        fclose(f);
185                        return 2;
186                     }
187                   pper = per;
188                   pl = y;
189                }
190           }
191      }
192    /* finish off */
193    fclose(f);
194    return 1;
195 }
196
197 void
198 formats(ImlibLoader * l)
199 {
200    char               *list_formats[] = { "fits", "fts", "fit" };
201
202    {
203       int                 i;
204
205       l->num_formats = (sizeof(list_formats) / sizeof(char *));
206       l->formats = malloc(sizeof(char *) * l->num_formats);
207       for (i = 0; i < l->num_formats; i++)
208          l->formats[i] = strdup(list_formats[i]);
209    }
210 }