-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfits2tga.c
171 lines (148 loc) · 5.95 KB
/
fits2tga.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/**
@file fits2tga.c
@author Mitch Richling <https://www.mitchr.me/>
@Copyright Copyright 1998 by Mitch Richling. All rights reserved.
@brief Convert FITS image to TGA@EOL
@Keywords convert fits image tga
@Std C89
This little example uses cfitsio to read in a fits file,
and write out a 24-bit TGA file. It understands the two
most widely used ways to embed color images inside of
FITS.
It converts image data to a double, and thus works with
just about any image data type. I have included
commented out code illustrating how to read a SHORT_IMG.
*/
#include <string.h> /* Strings ISOC */
#include <stdio.h> /* I/O lib ISOC */
#include "fitsio.h"
#include "fitsUtil.h"
#define FITS_READ_T double
//#define FITS_READ_T unsigned short
int main(int argc, char *argv[]) {
int lengthThreeAxis, xLen, yLen;
int i;
int numAxis;
long axLengths[3];
long fpixel[3], numPixels;
fitsfile *fitsFilePtr;
int status;
int kwvBITPIX;
int x, y;
FITS_READ_T *imageArray;
status = 0; /* Must initialize status before use */
/* Open the fits file */
fits_open_file(&fitsFilePtr, argv[1], READONLY, &status);
reportAndExitOnFITSerror(status);
/* Display the data type in the image. */
fits_get_img_type(fitsFilePtr, &kwvBITPIX, &status);
reportAndExitOnFITSerror(status);
switch(kwvBITPIX) {
case BYTE_IMG : fprintf(stderr, "Image Type: 8-bit byte pixels, 0 - 255\n"); break;
case SHORT_IMG : fprintf(stderr, "Image Type: 16 bit integer pixels\n"); break;
case LONG_IMG : fprintf(stderr, "Image Type: 32-bit integer pixels\n"); break;
case FLOAT_IMG : fprintf(stderr, "Image Type: 32-bit floating point pixels\n"); break;
case DOUBLE_IMG : fprintf(stderr, "Image Type: 64-bit floating point pixels\n"); break;
default : fprintf(stderr, "Image Type: UNKNOWN\n"); break;
}
/* Get the axis count for the image */
fits_get_img_dim(fitsFilePtr, &numAxis, &status);
reportAndExitOnFITSerror(status);
fprintf(stderr, "Number of axis: %d\n", numAxis);
/* Find the x/y-axis dimensions and the color dimension if it exists. */
if(numAxis < 2) {
fprintf(stderr, "Too few axes to be a real image!\n");
exit(1);
} else if(numAxis > 3) {
fprintf(stderr, "Too many axes to be a real image!\n");
exit(2);
}
/* Get the size of each axis */
fits_get_img_size(fitsFilePtr, 3, axLengths, &status);
reportAndExitOnFITSerror(status);
/* Find the color axis if it exists.. */
if(numAxis == 2) {
lengthThreeAxis = 0;
xLen = axLengths[1-1];
yLen = axLengths[2-1];
} else { // (numAxis == 3)
if(axLengths[3-1] == 3) {
lengthThreeAxis = 3;
xLen = axLengths[1-1];
yLen = axLengths[2-1];
} else if(axLengths[1-1] == 3) {
lengthThreeAxis = 1;
xLen = axLengths[2-1];
yLen = axLengths[3-1];
} else {
fprintf(stderr, "Found 3 axis, but can't figure out RGB dimension!\n");
exit(3);
}
}
/* Compute the number of pixels */
numPixels = xLen * yLen;
if(lengthThreeAxis)
numPixels = numPixels * 3;
/* Report on image size and color axis location */
if(lengthThreeAxis)
fprintf(stderr, "%dx%d Color FITS image. RGB is ax %d\n", xLen, yLen, lengthThreeAxis);
else
fprintf(stderr, "%dx%d FITS image.\n", xLen, yLen);
/* Set up fpixel for a full image read. */
for(i=1; i<=numAxis; i++)
fpixel[i-1] = 1;
/* Allocate space used for the image. */
imageArray = (FITS_READ_T *)malloc(sizeof(FITS_READ_T)*(numPixels+1));
/* Read in the data in one big gulp */
fits_read_pix(fitsFilePtr, TDOUBLE, fpixel, numPixels, NULL, imageArray, NULL, &status);
//fits_read_pix(fitsFilePtr, TUSHORT, fpixel, numPixels, NULL, imageArray, NULL, &status);
/* Compute maximum pixel value */
FITS_READ_T maxF = imageArray[0];
FITS_READ_T minF = imageArray[0];
for(i=1; i<numPixels; i++) {
if(imageArray[i] > maxF) maxF = imageArray[i];
if(imageArray[i] < minF) minF = imageArray[i];
}
fprintf(stderr, "pix range: [%f, %f]\n", (double)minF, (double)maxF);
/* Print out the image file */
/* Write the TGA header */
putchar(0); /* idlength */
putchar(0); /* colourmaptype */
putchar(2); /* datatypecode */
putchar(0); /* 16-bit colourmap origin */
putchar(0);
putchar(0); /* colurmaplength */
putchar(0);
putchar(0); /* colormapdepth */
putchar(0); /* 16-bit x_origin */
putchar(0);
putchar(0); /* 16-bit y_origon */
putchar(0);
putchar(xLen & 0x00ff); /* LSB xLen */
putchar((xLen & 0xff00)/256); /* MSB xLen */
putchar(yLen & 0x00ff); /* LSB yLen */
putchar((yLen & 0xff00)/256); /* MSB yLen */
putchar(24); /* bits per pixel. */
putchar(0); /* imagedescriptor */
/* Write out the TGA image data */
for(y=0;y<yLen;y++)
for(x=0;x<xLen;x++)
switch(lengthThreeAxis) {
case 0: putchar(255*(imageArray[x+xLen*y]-minF)/(maxF-minF));
putchar(255*(imageArray[x+xLen*y]-minF)/(maxF-minF));
putchar(255*(imageArray[x+xLen*y]-minF)/(maxF-minF)); break;
case 1: putchar(255*(imageArray[3*(x+xLen*y)+2]-minF)/(maxF-minF));
putchar(255*(imageArray[3*(x+xLen*y)+1]-minF)/(maxF-minF));
putchar(255*(imageArray[3*(x+xLen*y)+0]-minF)/(maxF-minF)); break;
case 3: putchar(255*(imageArray[x+xLen*y+2*xLen*yLen]-minF)/(maxF-minF));
putchar(255*(imageArray[x+xLen*y+1*xLen*yLen]-minF)/(maxF-minF));
putchar(255*(imageArray[x+xLen*y+0*xLen*yLen]-minF)/(maxF-minF)); break;
}
/* Free up space used for the image. */
free(imageArray);
/* We are done. Close the file. */
fits_close_file(fitsFilePtr, &status);
reportAndExitOnFITSerror(status);
/* That's it. Time to exit. */
return(0);
}