1 /*********************************************************************
2 array -- Functions for I/O on arrays (images or cubes)
3 This is part of GNU Astronomy Utilities (Gnuastro) package.
4 
5 Original author:
6      Mohammad Akhlaghi <mohammad@akhlaghi.org>
7 Contributing author(s):
8 Copyright (C) 2018-2021, Free Software Foundation, Inc.
9 
10 Gnuastro is free software: you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation, either version 3 of the License, or (at your
13 option) any later version.
14 
15 Gnuastro is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
22 **********************************************************************/
23 #include <config.h>
24 
25 #include <stdio.h>
26 #include <errno.h>
27 #include <error.h>
28 #include <stdlib.h>
29 
30 #include <gnuastro/txt.h>
31 #include <gnuastro/fits.h>
32 #include <gnuastro/jpeg.h>
33 #include <gnuastro/tiff.h>
34 #include <gnuastro/array.h>
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 /*********************************************************************/
46 /*****************        High-level functions        ****************/
47 /*********************************************************************/
48 int
gal_array_name_recognized(char * name)49 gal_array_name_recognized(char *name)
50 {
51   if( gal_array_name_recognized_multiext(name) ) return 1;
52   else if ( gal_jpeg_name_is_jpeg(name)        ) return 1;
53   else                                           return 0;
54 
55   /* Control should not get to here, but just to avoid compiler warnings,
56      we'll return a NULL. */
57   error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to solve the "
58         "problem. Control must not reach the end of this function", __func__,
59         PACKAGE_BUGREPORT);
60   return 0;
61 }
62 
63 
64 
65 
66 
67 int
gal_array_name_recognized_multiext(char * name)68 gal_array_name_recognized_multiext(char *name)
69 {
70   if(       gal_fits_name_is_fits(name) ) return 1;
71   else if ( gal_tiff_name_is_tiff(name) ) return 1;
72   else                                    return 0;
73 
74   /* Control should not get to here, but just to avoid compiler warnings,
75      we'll return a NULL. */
76   error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to solve the "
77         "problem. Control must not reach the end of this function", __func__,
78         PACKAGE_BUGREPORT);
79   return 0;
80 }
81 
82 
83 
84 
85 
86 int
gal_array_file_recognized(char * name)87 gal_array_file_recognized(char *name)
88 {
89   if(       gal_fits_file_recognized(name) ) return 1;
90   else if ( gal_jpeg_name_is_jpeg(name)    ) return 1;
91   else if ( gal_tiff_name_is_tiff(name)    ) return 1;
92   else                                       return 0;
93 }
94 
95 
96 
97 
98 
99 /* Read (all the possibly existing) color channels within each
100    extension/dir of the given file. */
101 gal_data_t *
gal_array_read(char * filename,char * extension,gal_list_str_t * lines,size_t minmapsize,int quietmmap)102 gal_array_read(char *filename, char *extension, gal_list_str_t *lines,
103                size_t minmapsize, int quietmmap)
104 {
105   size_t ext;
106 
107   /* FITS  */
108   if( gal_fits_file_recognized(filename) )
109     return gal_fits_img_read(filename, extension, minmapsize, quietmmap);
110 
111   /* TIFF */
112   else if ( gal_tiff_name_is_tiff(filename) )
113     {
114       ext=gal_tiff_dir_string_read(extension);
115       return gal_tiff_read(filename, ext, minmapsize, quietmmap);
116     }
117 
118   /* JPEG */
119   else if ( gal_jpeg_name_is_jpeg(filename) )
120     return gal_jpeg_read(filename, minmapsize, quietmmap);
121 
122   /* Default: plain text. */
123   else
124     return gal_txt_image_read(filename, lines, minmapsize, quietmmap);
125 
126   /* Control should not get to here, but just to avoid compiler warnings,
127      we'll return a NULL. */
128   error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to solve the "
129         "problem. Control must not reach the end of this function", __func__,
130         PACKAGE_BUGREPORT);
131   return NULL;
132 }
133 
134 
135 
136 
137 
138 /* Read the contents of the given file/extension to a specific type. */
139 gal_data_t *
gal_array_read_to_type(char * filename,char * extension,gal_list_str_t * lines,uint8_t type,size_t minmapsize,int quietmmap)140 gal_array_read_to_type(char *filename, char *extension,
141                        gal_list_str_t *lines, uint8_t type,
142                        size_t minmapsize, int quietmmap)
143 {
144   gal_data_t *out=NULL;
145   gal_data_t *next, *in=gal_array_read(filename, extension, lines,
146                                        minmapsize, quietmmap);
147 
148   /* Go over all the channels. */
149   while(in)
150     {
151       next=in->next;
152       in->next=NULL;
153       gal_list_data_add(&out, gal_data_copy_to_new_type_free(in, type));
154       in=next;
155     }
156 
157   /* Invert the reverse list and return. */
158   gal_list_data_reverse(&out);
159   return out;
160 }
161 
162 
163 
164 
165 
166 /* Read the input array and make sure it is only one channel. */
167 gal_data_t *
gal_array_read_one_ch(char * filename,char * extension,gal_list_str_t * lines,size_t minmapsize,int quietmmap)168 gal_array_read_one_ch(char *filename, char *extension, gal_list_str_t *lines,
169                       size_t minmapsize, int quietmmap)
170 {
171   char *fname;
172   gal_data_t *out;
173   out=gal_array_read(filename, extension, lines, minmapsize, quietmmap);
174 
175   if(out->next)
176     {
177       if(extension)
178         {
179           if( asprintf(&fname, "%s (hdu %s)", filename, extension)<0 )
180             error(EXIT_FAILURE, 0, "%s: asprintf allocation error", __func__);
181         }
182       else
183         fname=filename;
184 
185       error(EXIT_FAILURE, 0, "%s: contains %zu channels (it isn't "
186             "monochrome).\n\n"
187             "You can use Gnuastro's ConvertType program to separate the "
188             "(color) channels into separate extensions of a FITS file, with "
189             "a command like this:\n\n"
190             "    $ astconvertt %s -h%s --output=sep-ch.fits",
191             fname, gal_list_data_number(out), filename, extension);
192     }
193 
194   return out;
195 }
196 
197 
198 
199 
200 
201 /* Read a single-channel dataset into a specific type. */
202 gal_data_t *
gal_array_read_one_ch_to_type(char * filename,char * extension,gal_list_str_t * lines,uint8_t type,size_t minmapsize,int quietmmap)203 gal_array_read_one_ch_to_type(char *filename, char *extension,
204                               gal_list_str_t *lines, uint8_t type,
205                               size_t minmapsize, int quietmmap)
206 {
207   gal_data_t *out=gal_array_read_one_ch(filename, extension, lines,
208                                         minmapsize, quietmmap);
209 
210   return gal_data_copy_to_new_type_free(out, type);
211 }
212