IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ticket #257: psImageIO.c

File psImageIO.c, 12.9 KB (added by robert.desonia@…, 22 years ago)

uncommented support for all datatypes

Line 
1/** @file psImageIO.c
2 *
3 * @brief Contains image I/O routines.
4 *
5 * This file defines the file input/output functions for the psImage structure.
6 *
7 * @author Robert DeSonia, MHPCC
8 *
9 * @version $Revision: 1.15 $ $Name: $
10 * @date $Date: 2004/11/04 01:05:00 $
11 *
12 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
13 */
14
15#include <fitsio.h>
16#include <unistd.h>
17
18#include "psImageIO.h"
19#include "psError.h"
20#include "psMemory.h"
21
22#include "psImageErrors.h"
23
24psImage* psImageReadSection(psImage* output,
25 psS32 col,
26 psS32 row,
27 psS32 numCols,
28 psS32 numRows,
29 psS32 z,
30 char *extname,
31 psS32 extnum,
32 char *filename)
33{
34 fitsfile *fptr = NULL; /* Pointer to the FITS file */
35 psS32 status = 0; /* CFITSIO file vars */
36 psS32 nAxis = 0;
37 psS32 anynull = 0;
38 psS32 bitPix = 0; /* Pixel type */
39 long nAxes[3];
40 long firstPixel[3]; /* lower-left corner of image subset */
41 long lastPixel[3]; /* upper-right corner of image subset */
42 long increment[3]; /* increment for image subset */
43 char fitsErr[80] = ""; /* CFITSIO error message string */
44 psS32 hduType = IMAGE_HDU;
45 psS32 fitsDatatype = 0;
46 psS32 datatype = 0;
47
48 if (filename == NULL) {
49 psError(PS_ERR_BAD_PARAMETER_NULL, true,
50 PS_ERRORTEXT_psImageIO_FILENAME_NULL);
51 psFree(output);
52 return NULL;
53 }
54
55 /* Open the FITS file */
56 (void)fits_open_file(&fptr, filename, READONLY, &status);
57 if (fptr == NULL || status != 0) {
58 fits_get_errstatus(status, fitsErr);
59 psError(PS_ERR_BAD_PARAMETER_VALUE, true,
60 PS_ERRORTEXT_psImageIO_FILENAME_INVALID,
61 filename, fitsErr);
62 psFree(output);
63 return NULL;
64 }
65
66 /* find the specified extension */
67 if (extname != NULL) {
68 if (fits_movnam_hdu(fptr, hduType, extname, 0, &status) != 0) {
69 fits_get_errstatus(status, fitsErr);
70 status = 0;
71 (void)fits_close_file(fptr, &status);
72 psError(PS_ERR_LOCATION_INVALID, true,
73 PS_ERRORTEXT_psImageIO_EXTNAME_INVALID,
74 extname, filename, fitsErr);
75 psFree(output);
76 return NULL;
77 }
78 } else {
79 if (fits_movabs_hdu(fptr, extnum + 1, &hduType, &status) != 0) {
80 fits_get_errstatus(status, fitsErr);
81 status = 0;
82 (void)fits_close_file(fptr, &status);
83 psError(PS_ERR_LOCATION_INVALID, true,
84 PS_ERRORTEXT_psImageIO_EXTNUM_INVALID,
85 extnum, filename, fitsErr);
86 psFree(output);
87 return NULL;
88 }
89 }
90
91 /* Get the data type 'bitPix' from the FITS image */
92 if (fits_get_img_equivtype(fptr, &bitPix, &status) != 0) {
93 fits_get_errstatus(status, fitsErr);
94 status = 0;
95 (void)fits_close_file(fptr, &status);
96 psError(PS_ERR_IO, true,
97 PS_ERRORTEXT_psImageIO_DATATYPE_UNKNOWN,
98 filename, fitsErr);
99 psFree(output);
100 return NULL;
101 }
102
103 /* Get the dimensions 'nAxis' from the FITS image */
104 if (fits_get_img_dim(fptr, &nAxis, &status) != 0) {
105 (void)fits_get_errstatus(status, fitsErr);
106 status = 0;
107 (void)fits_close_file(fptr, &status);
108 psError(PS_ERR_IO, true,
109 PS_ERRORTEXT_psImageIO_IMAGE_DIM_UNKNOWN,
110 filename, fitsErr);
111 psFree(output);
112 return NULL;
113 }
114
115 /* Validate the number of axis */
116 if ((nAxis < 2) || (nAxis > 3)) {
117 status = 0;
118 (void)fits_close_file(fptr, &status);
119 psError(PS_ERR_IO, true,
120 PS_ERRORTEXT_psImageIO_IMAGE_DIMENSION_UNSUPPORTED,
121 nAxis);
122 psFree(output);
123 return NULL;
124 }
125
126 /* Get the Image size from the FITS file */
127 if (fits_get_img_size(fptr, nAxis, nAxes, &status) != 0) {
128 (void)fits_get_errstatus(status, fitsErr);
129 status = 0;
130 (void)fits_close_file(fptr, &status);
131 psError(PS_ERR_IO, true,
132 PS_ERRORTEXT_psImageIO_IMAGE_SIZE_UNKNOWN,
133 filename, fitsErr);
134 psFree(output);
135 return NULL;
136 }
137
138 if (numCols < 1) {
139 numCols += nAxes[0] - col;
140 }
141 if (numRows < 1) {
142 numRows += nAxes[1] - row;
143 }
144
145 firstPixel[0] = col + 1;
146 firstPixel[1] = row + 1;
147 firstPixel[2] = z + 1;
148
149 lastPixel[0] = firstPixel[0] + numCols - 1;
150 lastPixel[1] = firstPixel[1] + numRows - 1;
151 lastPixel[2] = z + 1;
152
153 increment[0] = 1;
154 increment[1] = 1;
155 increment[2] = 1;
156
157 switch (bitPix) {
158 case BYTE_IMG:
159 datatype = PS_TYPE_U8;
160 fitsDatatype = TBYTE;
161 break;
162 case SBYTE_IMG:
163 datatype = PS_TYPE_S8;
164 fitsDatatype = TSBYTE;
165 break;
166 case USHORT_IMG:
167 datatype = PS_TYPE_U16;
168 fitsDatatype = TUSHORT;
169 break;
170 case SHORT_IMG:
171 datatype = PS_TYPE_S16;
172 fitsDatatype = TSHORT;
173 break;
174 case ULONG_IMG:
175 datatype = PS_TYPE_U32;
176 fitsDatatype = TUINT;
177 break;
178 case LONG_IMG:
179 datatype = PS_TYPE_S32;
180 fitsDatatype = TINT;
181 break;
182 case LONGLONG_IMG:
183 datatype = PS_TYPE_S64;
184 fitsDatatype = TLONGLONG;
185 break;
186 case FLOAT_IMG:
187 datatype = PS_TYPE_F32;
188 fitsDatatype = TFLOAT;
189 break;
190 case DOUBLE_IMG:
191 datatype = PS_TYPE_F64;
192 fitsDatatype = TDOUBLE;
193 break;
194 default:
195 psError(PS_ERR_IO, true,
196 PS_ERRORTEXT_psImageIO_FITS_TYPE_UNSUPPORTED,
197 bitPix, filename);
198 psFree(output);
199 return NULL;
200 }
201 output = psImageRecycle(output, numCols, numRows, datatype);
202 if (fits_read_subset(fptr, fitsDatatype, firstPixel, lastPixel, increment,
203 NULL, output->data.V[0], &anynull, &status) != 0) {
204 psFree(output);
205 (void)fits_get_errstatus(status, fitsErr);
206 status = 0;
207 (void)fits_close_file(fptr, &status);
208 psError(PS_ERR_IO, true,
209 PS_ERRORTEXT_psImageIO_READ_FAILED,
210 filename, fitsErr);
211 return NULL;
212 }
213
214 (void)fits_close_file(fptr, &status);
215
216 return output;
217}
218
219psBool psImageWriteSection(psImage* input,
220 psS32 col0,
221 psS32 row0,
222 psS32 z,
223 char *extname,
224 psS32 extnum,
225 char *filename)
226{
227 psS32 numCols = 0;
228 psS32 numRows = 0;
229
230 psS32 status = 0; /* CFITSIO status */
231 fitsfile *fptr = NULL; /* pointer to the FITS file */
232 long nAxes[3]; /* Image axis vars */
233 long firstPixel[3]; /* First Pixel to read */
234 long lastPixel[3]; /* Last Pixel to read */
235 char fitsErr[80]; /* FITSIO message string */
236 psS32 datatype = 0; /* the datatype of the image */
237 psS32 bitPix = 0; /* FITS bitPix value */
238 psS32 hduType = IMAGE_HDU; /* the HDU type (image,table, etc.) */
239 double bscale = 1.0;
240 double bzero = 0.0;
241 psBool createNewHDU = false;
242
243 /* need a valid image to write */
244 if (input == NULL) {
245 psError(PS_ERR_BAD_PARAMETER_NULL, true,
246 PS_ERRORTEXT_psImage_IMAGE_NULL);
247 return false;
248 }
249
250 numRows = input->numRows;
251 numCols = input->numCols;
252
253 switch (input->type.type) {
254 case PS_TYPE_U8:
255 bitPix = BYTE_IMG;
256 datatype = TBYTE;
257 break;
258 case PS_TYPE_S8:
259 bitPix = BYTE_IMG;
260 bzero = INT8_MIN;
261 datatype = TSBYTE;
262 break;
263 case PS_TYPE_U16:
264 bitPix = SHORT_IMG;
265 bzero = -1.0f * INT16_MIN;
266 datatype = TUSHORT;
267 break;
268 case PS_TYPE_S16:
269 bitPix = SHORT_IMG;
270 datatype = TSHORT;
271 break;
272 case PS_TYPE_U32:
273 bitPix = LONG_IMG;
274 bzero = -1.0f * INT32_MIN;
275 datatype = TUINT;
276 break;
277 case PS_TYPE_S32:
278 bitPix = LONG_IMG;
279 datatype = TINT;
280 break;
281 case PS_TYPE_F32:
282 bitPix = FLOAT_IMG;
283 datatype = TFLOAT;
284 break;
285 case PS_TYPE_F64:
286 bitPix = DOUBLE_IMG;
287 datatype = TDOUBLE;
288 break;
289 default: {
290 char* typeStr;
291 PS_TYPE_NAME(typeStr,input->type.type);
292 psError(PS_ERR_BAD_PARAMETER_TYPE, true,
293 PS_ERRORTEXT_psImageIO_TYPE_UNSUPPORTED,
294 typeStr);
295 return false;
296 }
297 }
298
299 /* Open the FITS file */
300 if (access(filename, F_OK) == 0) { // file
301 // exists
302 (void)fits_open_file(&fptr, filename, READWRITE, &status);
303 if (fptr == NULL || status != 0) {
304 fits_get_errstatus(status, fitsErr);
305 psError(PS_ERR_BAD_PARAMETER_VALUE, true,
306 PS_ERRORTEXT_psImageIO_FILENAME_INVALID,
307 filename, fitsErr);
308 return false;
309 }
310
311 /* find the specified extension */
312 if (extname != NULL) {
313 if (fits_movnam_hdu(fptr, hduType, extname, 0, &status) != 0) {
314 fits_get_errstatus(status, fitsErr);
315 status = 0;
316 (void)fits_close_file(fptr, &status);
317 psError(PS_ERR_LOCATION_INVALID, true,
318 PS_ERRORTEXT_psImageIO_EXTNAME_INVALID,
319 extname, filename, fitsErr);
320 return false;
321 }
322 } else {
323 psS32 numHDUs = 0;
324
325 fits_get_num_hdus(fptr, &numHDUs, &status);
326 if (numHDUs < extnum) {
327 status = 0;
328 (void)fits_close_file(fptr, &status);
329 psError(PS_ERR_LOCATION_INVALID, true,
330 PS_ERRORTEXT_psImageIO_WRITE_EXTNUM_INVALID,
331 extnum, numHDUs);
332 return false;
333 } else if (numHDUs == extnum) {
334 createNewHDU = true;
335 } else if (fits_movabs_hdu(fptr, extnum + 1, &hduType, &status) != 0) {
336 fits_get_errstatus(status, fitsErr);
337 status = 0;
338 (void)fits_close_file(fptr, &status);
339 psError(PS_ERR_LOCATION_INVALID, true,
340 PS_ERRORTEXT_psImageIO_EXTNUM_INVALID,
341 extnum, filename, fitsErr);
342 return false;
343 }
344 }
345
346 } else {
347 // file does not exist
348
349 (void)fits_create_file(&fptr, filename, &status);
350 if (fptr == NULL || status != 0) {
351 fits_get_errstatus(status, fitsErr);
352 psError(PS_ERR_IO, true,
353 PS_ERRORTEXT_psImageIO_FILENAME_CREATE_FAILED,
354 filename, fitsErr);
355 return false;
356 }
357 createNewHDU = true;
358 }
359
360 if (createNewHDU) {
361 /* create the mandatory image keywords */
362 nAxes[0] = col0 + numCols;
363 nAxes[1] = row0 + numRows;
364 nAxes[2] = z + 1;
365 if (fits_create_img(fptr, bitPix, 3, nAxes, &status) != 0) {
366 (void)fits_get_errstatus(status, fitsErr);
367 status = 0;
368 (void)fits_close_file(fptr, &status);
369 psError(PS_ERR_IO, true,
370 PS_ERRORTEXT_psImageIO_CREATE_HDU_FAILED,
371 filename, fitsErr);
372 return false;
373 }
374 // set the bscale/bzero
375 fits_write_key_dbl(fptr, "BZERO", bzero, 12, "Pixel Value Offset", &status);
376 fits_write_key_dbl(fptr, "BSCALE", bscale, 12, "Pixel Value Scale", &status);
377 fits_set_bscale(fptr, bscale, bzero, &status);
378
379 if (extname != NULL) {
380 /* create the extension for the Primary HDU */
381 if (fits_write_key_str(fptr, "EXTNAME", extname, "Extension Name", &status) != 0) {
382 (void)fits_get_errstatus(status, fitsErr);
383 status = 0;
384 (void)fits_close_file(fptr, &status);
385 psError(PS_ERR_IO, true,
386 PS_ERRORTEXT_psImageIO_CREATE_EXTENSION_FAILED,
387 filename, fitsErr);
388 return false;
389 }
390 }
391 }
392
393 firstPixel[0] = col0 + 1;
394 firstPixel[1] = row0 + 1;
395 firstPixel[2] = z + 1;
396
397 lastPixel[0] = firstPixel[0] + numCols - 1;
398 lastPixel[1] = firstPixel[1] + numRows - 1;
399 lastPixel[2] = z + 1;
400
401 if (fits_write_subset(fptr, datatype, firstPixel, lastPixel, input->data.V[0], &status) != 0) {
402 (void)fits_get_errstatus(status, fitsErr);
403 status = 0;
404 (void)fits_close_file(fptr, &status);
405 psError(PS_ERR_IO, true,
406 PS_ERRORTEXT_psImageIO_WRITE_FAILED,
407 filename, fitsErr);
408 return false;
409 }
410
411 status = 0;
412 (void)fits_close_file(fptr, &status);
413
414 return true;
415}