1 
2 /** Copyright 2009 Dustin Lang.
3  */
4 
5 #include <stdint.h>
6 
7 #include "qfits_std.h"
8 #include "qfits_config.h"
9 #include "qfits_image.h"
10 #include "qfits_byteswap.h"
11 #include "qfits_error.h"
12 
13 #define FITSOUTPUTPIXEL(fitstype, ival, optr)	\
14 	do {										\
15 		uint8_t* o8;							\
16 		int16_t* o16;							\
17 		int32_t* o32;							\
18 		float*   ofloat;						\
19 		double*  odouble;						\
20 		switch (fitstype) {						\
21 		case BPP_8_UNSIGNED:					\
22 			o8 = optr;							\
23 			*o8 = MIN(255, MAX(0, (uint8_t)ival));  \
24 			break;								\
25 		case BPP_16_SIGNED:								 \
26 			o16 = optr;									 \
27 			*o16 = MIN(INT16_MAX, MAX(INT16_MIN, (int16_t)ival));	\
28 			break;											\
29 		case BPP_32_SIGNED:									\
30 			o32 = optr;										\
31 			*o32 = MIN(INT32_MAX, MAX(INT32_MIN, (int32_t)ival));	\
32 			break;											\
33 		case BPP_IEEE_FLOAT:								\
34 			ofloat = optr;									\
35 			*ofloat = ival;									\
36 			break;											\
37 		case BPP_IEEE_DOUBLE:								\
38 			odouble = optr;									\
39 			*odouble = ival;								\
40 			break;												\
41 		default:													\
42 			qfits_error("Unknown output FITS type %i\n", fitstype); \
43 			return -1;												\
44 		}															\
45 	} while (0)
46 
qfits_pixel_ctype_size(int ctype)47 int qfits_pixel_ctype_size(int ctype) {
48 	switch (ctype) {
49 	case PTYPE_DOUBLE:
50 		return sizeof(double);
51 	case PTYPE_FLOAT:
52 		return sizeof(float);
53 	case PTYPE_INT:
54 		return sizeof(int);
55 	case PTYPE_INT16:
56 		return sizeof(int16_t);
57 	case PTYPE_UINT8:
58 		return sizeof(uint8_t);
59 	}
60 	return -1;
61 }
62 
qfits_pixel_fitstype_size(int fitstype)63 int qfits_pixel_fitstype_size(int fitstype) {
64 	int n = BYTESPERPIXEL(fitstype);
65 	if (!n)
66 		return -1;
67 	return n;
68 }
69 
70 /**
71  Converts a value described by a "PTYPE_"
72  To a value described by a "BPP_"
73  */
qfits_pixel_ctofits(int ctype,int fitstype,const void * cval,void * fitsval)74 int qfits_pixel_ctofits(int ctype, int fitstype,
75 						const void* cval, void* fitsval) {
76 	const float* ifloat;
77 	const double* idouble;
78 	const int* iint;
79 	const uint8_t* iu8;
80 	const int16_t* ii16;
81 
82 	switch (ctype) {
83 	case PTYPE_DOUBLE:
84 		idouble = cval;
85 		FITSOUTPUTPIXEL(fitstype, *idouble, fitsval);
86 		break;
87 
88 	case PTYPE_FLOAT:
89 		ifloat = cval;
90 		FITSOUTPUTPIXEL(fitstype, *ifloat, fitsval);
91 		break;
92 
93 	case PTYPE_INT:
94 		iint = cval;
95 		FITSOUTPUTPIXEL(fitstype, *iint, fitsval);
96 		break;
97 
98 	case PTYPE_UINT8:
99 		iu8 = cval;
100 		// This generates warnings about "comparison always false due to limited range of data".
101 		// These warnings are harmless.
102 		FITSOUTPUTPIXEL(fitstype, *iu8, fitsval);
103 		break;
104 
105 	case PTYPE_INT16:
106 		ii16 = cval;
107 		// This generates warnings about "comparison always false due to limited range of data".
108 		// These warnings are harmless.
109 		FITSOUTPUTPIXEL(fitstype, *ii16, fitsval);
110 		break;
111 
112 	default:
113 		return -1;
114 	}
115 
116 	// Byteswap, if necessary.
117 #ifndef WORDS_BIGENDIAN
118 	switch (fitstype) {
119 	case BPP_8_UNSIGNED:
120 		break;
121 	case BPP_16_SIGNED:
122 		qfits_swap_bytes(fitsval, 2);
123 		break;
124 	case BPP_32_SIGNED:
125 	case BPP_IEEE_FLOAT:
126 		qfits_swap_bytes(fitsval, 4);
127 		break;
128 	case BPP_IEEE_DOUBLE:
129 		qfits_swap_bytes(fitsval, 8);
130 		break;
131 	}
132 #endif
133 	return 0;
134 }
135 
136 
137 #undef FITSOUTPUTPIXEL
138 
139