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=&register_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