1 /*
2
3 File: file_spe.c
4
5 Copyright (C) 2007 Christophe GRENIER <grenier@cgsecurity.org>
6
7 This software is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write the Free Software Foundation, Inc., 51
19 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 #ifdef HAVE_STRING_H
27 #include <string.h>
28 #endif
29 #include <stdio.h>
30 #include "types.h"
31 #include "filegen.h"
32 #include "common.h"
33 #include "log.h"
34
35 static void register_header_check_spe(file_stat_t *file_stat);
36 static int header_check_spe(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new);
37
38 const file_hint_t file_hint_spe= {
39 .extension="spe",
40 .description="WinSpec bitmap image",
41 .max_filesize=PHOTOREC_MAX_FILE_SIZE,
42 .recover=1,
43 .enable_by_default=1,
44 .register_header_check=®ister_header_check_spe
45 };
46
47 struct header_spe
48 {
49 uint16_t dioden; /* 0 num of physical pixels (X axis) */
50 int16_t avgexp; /* 2 number of accumulations per scan */
51 /* if > 32767, set to -1 and */
52 /* see lavgexp below (668) */
53 int16_t exposure; /* 4 exposure time (in milliseconds) */
54 /* if > 32767, set to -1 and */
55 /* see lexpos below (660) */
56 uint16_t xDimDet; /* 6 Detector x dimension of chip */
57 int16_t mode; /* 8 timing mode */
58 float exp_sec; /* 10 alternative exposure, in secs. */
59 int16_t asyavg; /* 14 number of asynchron averages */
60 int16_t asyseq; /* 16 number of asynchron sequential */
61 uint16_t yDimDet; /* 18 y dimension of CCD or detector. */
62 char date[10]; /* 20 date as MM/DD/YY */
63 int16_t ehour; /* 30 Experiment Time: Hours (as binary) */
64 int16_t eminute; /* 32 Experiment Time: Minutes(as binary)*/
65 int16_t noscan; /* 34 number of multiple scans */
66 /* if noscan == -1 use lnoscan */
67 int16_t fastacc; /* 36 */
68 int16_t seconds; /* 38 Experiment Time: Seconds(as binary)*/
69 int16_t DetType; /* 40 CCD/DiodeArray type */
70 uint16_t xdim; /* 42 actual # of pixels on x axis */
71 int16_t stdiode; /* 44 trigger diode */
72 float nanox; /* 46 */
73 float calibdio[10]; /* 50 calibration diodes */
74 char fastfile[16]; /* 90 name of pixel control file */
75 int16_t asynen; /* 106 asynchron enable flag 0 = off */
76 int16_t datatype; /* 108 experiment data type */
77 /* 0 = FLOATING POINT */
78 /* 1 = LONG INTEGER */
79 /* 2 = INTEGER */
80 /* 3 = UNSIGNED INTEGER */
81 float calibnan[10]; /* 110 calibration nanometer */
82 int16_t BackGrndApplied; /* 150 set to 1 if background sub done */
83 int16_t astdiode; /* 152 */
84 uint16_t minblk; /* 154 min. # of strips per skips */
85 uint16_t numminblk; /* 156 # of min-blocks before geo skps */
86 double calibpol[4]; /* 158 calibration coeffients */
87 uint16_t ADCrate; /* 190 ADC rate */
88 uint16_t ADCtype; /* 192 ADC type */
89 uint16_t ADCresolution; /* 194 ADC resolution */
90 uint16_t ADCbitAdjust; /* 196 ADC bit adjust */
91 uint16_t gain; /* 198 gain */
92 char exprem[5][80]; /* 200 experiment remarks */
93 uint16_t geometric; /* 600 geometric operations rotate 0x01 */
94 /* reverse 0x02, flip 0x04 */
95 char xlabel[16]; /* 602 Intensity display string */
96 uint16_t cleans; /* 618 cleans */
97 uint16_t NumSkpPerCln; /* 620 number of skips per clean. */
98 char califile[16]; /* 622 calibration file name (CSMA) */
99 char bkgdfile[16]; /* 638 background file name */
100 int16_t srccmp; /* 654 number of source comp. diodes */
101 uint16_t ydim; /* 656 y dimension of raw data. */
102 int16_t scramble; /* 658 0 = scrambled, 1 = unscrambled */
103 int32_t lexpos; /* 660 int32_t exposure in milliseconds */
104 /* used if exposure set to -1 */
105 int32_t lnoscan; /* 664 int32_t num of scans */
106 /* used if noscan set to -1 */
107 int32_t lavgexp; /* 668 int32_t num of accumulations */
108 /* used if avgexp set to -1 */
109 char stripfil[16]; /* 672 stripe file (st130) */
110 char sw_version[16]; /* 688 Version of SW creating this file */
111 int16_t type; /* 704 1 = new120 (Type II) */
112 /* 2 = old120 (Type I ) */
113 /* 3 = ST130 */
114 /* 4 = ST121 */
115 /* 5 = ST138 */
116 /* 6 = DC131 (PentaMax) */
117 /* 7 = ST133 (MicroMax/SpectroMax), */
118 /* 8 = ST135 (GPIB) */
119 /* 9 = VICCD */
120 /* 10 = ST116 (GPIB) */
121 /* 11 = OMA3 (GPIB) */
122 /* 12 = OMA4 */
123 int16_t flatFieldApplied; /* 706 Set to 1 if flat field was applied */
124 int16_t spare[8]; /* 708 reserved */
125 int16_t kin_trig_mode; /* 724 Kinetics Trigger Mode */
126 char dlabel[16]; /* 726 Data label. */
127 char empty[686]; /* 742 EMPTY BLOCK FOR EXPANSION */
128 float clkspd_us; /* 1428 Vert Clock Speed in micro-sec */
129 int16_t HWaccumFlag; /* 1432 set to 1 if accum done by Hardware */
130 int16_t StoreSync; /* 1434 set to 1 if store sync used. */
131 int16_t BlemishApplied; /* 1436 set to 1 if blemish removal applied */
132 int16_t CosmicApplied; /* 1438 set to 1 if cosmic ray removal done */
133 int16_t CosmicType; /* 1440 if cosmic ray applied, this is type */
134 float CosmicThreshold; /* 1442 Threshold of cosmic ray removal. */
135 int32_t NumFrames; /* 1446 number of frames in file. */
136 float MaxIntensity; /* 1450 max intensity of data (future) */
137 float MinIntensity; /* 1454 min intensity of data (future) */
138 char ylabel[16]; /* 1458 y axis label. */
139 uint16_t ShutterType; /* 1474 shutter type. */
140 float shutterComp; /* 1476 shutter compensation time. */
141 uint16_t readoutMode; /* 1480 Readout mode, full,kinetics, etc */
142 uint16_t WindowSize; /* 1482 window size for kinetics only. */
143 uint16_t clkspd; /* 1484 clock speed for kinetics & */
144 /* frame transfer. */
145 uint16_t interface_type; /* 1486 computer interface (isa-taxi, */
146 /* pci, eisa, etc.) */
147 uint32_t ioAdd1; /* 1488 I/O address of inteface card. */
148 uint32_t ioAdd2; /* 1492 if more than one address for card. */
149 uint32_t ioAdd3; /* 1496 */
150 uint16_t intLevel; /* 1500 interrupt level interface card */
151 uint16_t GPIBadd; /* 1502 GPIB address (if used) */
152 uint16_t ControlAdd; /* 1504 GPIB controller address (if used) */
153 uint16_t controllerNum; /* 1506 if multiple controller system will */
154 /* have controller # data came from. */
155 /* (Future Item) */
156 uint16_t SWmade; /* 1508 Software which created this file */
157 int16_t NumROI; /* 1510 number of ROIs used. if 0 assume 1 */
158 /* 1512 - 1630 ROI information */
159 struct ROIinfo { /* */
160 uint16_t startx; /* left x start value. */
161 uint16_t endx; /* right x value. */
162 uint16_t groupx; /* amount x is binned/grouped in hw. */
163 uint16_t starty; /* top y start value. */
164 uint16_t endy; /* bottom y value. */
165 uint16_t groupy; /* amount y is binned/grouped in hw. */
166 } ROIinfoblk[10]; /* ROI Starting Offsets: */
167 /* ROI 1 = 1512 */
168 /* ROI 2 = 1524 */
169 /* ROI 3 = 1536 */
170 /* ROI 4 = 1548 */
171 /* ROI 5 = 1560 */
172 /* ROI 6 = 1572 */
173 /* ROI 7 = 1584 */
174 /* ROI 8 = 1596 */
175 /* ROI 9 = 1608 */
176 /* ROI 10 = 1620 */
177 char FlatField[120]; /* 1632 Flat field file name. */
178 char background[120]; /* 1752 Background sub. file name. */
179 char blemish[120]; /* 1872 Blemish file name. */
180 float file_header_ver; /* 1992 Version of this file header */
181 char UserInfo[1000]; /* 1996-2995 user data. */
182 int32_t WinView_id; /* 2996 Set to 0x01234567L if file was */
183 /* created by WinX */
184
185 /* START OF X CALIBRATION STRUCTURE */
186
187 double xcal_offset; /* 3000 offset for absolute data scaling */
188 double xcal_factor; /* 3008 factor for absolute data scaling */
189 char xcal_current_unit; /* 3016 selected scaling unit */
190 char xcal_reserved1; /* 3017 reserved */
191 char xcal_string[40]; /* 3018 special string for scaling */
192 char xcal_reserved2[40]; /* 3058 reserved */
193 char xcal_calib_valid; /* 3098 flag if calibration is valid */
194 char xcal_input_unit; /* 3099 current input units for */
195 /* "calib_value" */
196 char xcal_polynom_unit; /* 3100 linear UNIT and used */
197 /* in the "polynom_coeff" */
198 char xcal_polynom_order; /* 3101 ORDER of calibration POLYNOM */
199 char xcal_calib_count; /* 3102 valid calibration data pairs */
200 double xcal_pixel_position[10];/* 3103 pixel pos. of calibration data */
201 double xcal_calib_value[10]; /* 3183 calibration VALUE at above pos */
202 double xcal_polynom_coeff[6]; /* 3263 polynom COEFFICIENTS */
203 double xcal_laser_position; /* 3311 laser wavenumber for relativ WN */
204 char xcal_reserved3; /* 3319 reserved */
205 unsigned char xcal_new_calib_flag; /* 3320 If set to 200, valid label below */
206 char xcal_calib_label[81]; /* 3321 Calibration label (NULL term'd) */
207 char xcal_expansion[87]; /* 3402 Calibration Expansion area */
208
209 /* START OF Y CALIBRATION STRUCTURE */
210
211 double ycal_offset; /* 3489 offset for absolute data scaling */
212 double ycal_factor; /* 3497 factor for absolute data scaling */
213 char ycal_current_unit; /* 3505 selected scaling unit */
214 char ycal_reserved1; /* 3506 reserved */
215 char ycal_string[40]; /* 3507 special string for scaling */
216 char ycal_reserved2[40]; /* 3547 reserved */
217 char ycal_calib_valid; /* 3587 flag if calibration is valid */
218 char ycal_input_unit; /* 3588 current input units for */
219 /* "calib_value" */
220 char ycal_polynom_unit; /* 3589 linear UNIT and used */
221 /* in the "polynom_coeff" */
222 char ycal_polynom_order; /* 3590 ORDER of calibration POLYNOM */
223 char ycal_calib_count; /* 3591 valid calibration data pairs */
224 double ycal_pixel_position[10];/* 3592 pixel pos. of calibration data */
225 double ycal_calib_value[10]; /* 3672 calibration VALUE at above pos */
226 double ycal_polynom_coeff[6]; /* 3752 polynom COEFFICIENTS */
227 double ycal_laser_position; /* 3800 laser wavenumber for relativ WN */
228 char ycal_reserved3; /* 3808 reserved */
229 unsigned char ycal_new_calib_flag; /* 3809 If set to 200, valid label below */
230 char ycal_calib_label[81]; /* 3810 Calibration label (NULL term'd) */
231 char ycal_expansion[87]; /* 3891 Calibration Expansion area */
232
233 /* END OF CALIBRATION STRUCTURES */
234
235 char Istring[40]; /* 3978 special Intensity scaling string */
236 char empty3[80]; /* 4018 empty block to reach 4100 bytes */
237 int16_t lastvalue; /* 4098 Always the LAST value in the header */
238 } __attribute__ ((gcc_struct, __packed__));
239
240 static const unsigned char spe_header[4]= {0x67, 0x45, 0x23, 0x01};
241
register_header_check_spe(file_stat_t * file_stat)242 static void register_header_check_spe(file_stat_t *file_stat)
243 {
244 register_header_check(0xbb4, spe_header,sizeof(spe_header), &header_check_spe, file_stat);
245 }
246
header_check_spe(const unsigned char * buffer,const unsigned int buffer_size,const unsigned int safe_header_only,const file_recovery_t * file_recovery,file_recovery_t * file_recovery_new)247 static int header_check_spe(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new)
248 {
249 const struct header_spe *spe=(const struct header_spe*)buffer;
250 if(le32(spe->WinView_id)==0x01234567L && le16(spe->lastvalue)==0x5555)
251 {
252 reset_file_recovery(file_recovery_new);
253 file_recovery_new->extension=file_hint_spe.extension;
254 file_recovery_new->min_filesize=4100;
255 file_recovery_new->calculated_file_size=(uint64_t)le16(spe->xdim)*le16(spe->ydim)*le32(spe->NumFrames);
256 file_recovery_new->calculated_file_size*=(le16(spe->datatype)<=1?4:2);
257 file_recovery_new->calculated_file_size+=4100;
258 log_debug("spe xdim=%u ydim=%u NumFrames=%u datatype=%u size=%llu\n",
259 le16(spe->xdim), le16(spe->ydim), (unsigned int)le32(spe->NumFrames), le16(spe->datatype),
260 (long long unsigned) file_recovery_new->calculated_file_size);
261 file_recovery_new->data_check=&data_check_size;
262 file_recovery_new->file_check=&file_check_size;
263 return 1;
264 }
265 return 0;
266 }
267