ecat7r.c
Go to the documentation of this file.
1 /******************************************************************************
2 
3  Copyright (c) 2003-2010 Turku PET Centre
4 
5  Library file: ecat7r.c
6  Description: Functions for reading ECAT 7.x format.
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Lesser General Public
10  License as published by the Free Software Foundation; either
11  version 2.1 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  See the GNU Lesser General Public License for more details:
17  http://www.gnu.org/copyleft/lesser.html
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with this library/program; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 
23  Turku PET Centre, Turku, Finland, http://www.turkupetcentre.fi
24 
25  Modification history:
26  2003-07-24 Vesa Oikonen
27  First created.
28  2003-09-08 VO
29  Added support for 3D sinograms, ecat7ReadScanMatrix().
30  2004-05-23 VO
31  Comments changed into Doxygen format.
32  2004-06-21 VO
33  ecat7ReadScanMatrix():
34  Before: reads datablocks based on matrix list.
35  After: if block number based on bin nr is smaller, then read only those
36  Reason: simulated file with erroneous matrix list.
37  2004-09-20 VO
38  Doxygen style comments are corrected.
39  2004-11-10 VO
40  Calculation of trueblockNr simplified in ecat7ReadScanMatrix().
41  2006-02-07 Jarkko Johansson
42  Comments added in ecat7ReadScanMatrix().
43  2007-03-21 VO
44  ecat7ReadImageheader(): fill_cti[] and fill_user[] are read correctly.
45  2007-03-27 VO
46  Added ecat7ReadPolarmapMatrix().
47  2010-08-19 VO
48  Main header field patient_birth_date can be in two different int formats,
49  either YYYYMMDD or as seconds from start of year 1970. In latter case
50  the number can be negative, which is not identified correctly by all C
51  library versions. Therefore those are converted to YYYYMMDD format.
52 
53 
54 ******************************************************************************/
55 #include <locale.h>
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <math.h>
59 #include <ctype.h>
60 #include <string.h>
61 #include <unistd.h>
62 #include <time.h>
63 /*****************************************************************************/
64 #include <swap.h>
65 #include <datetime.h>
66 #include "include/ecat7.h"
67 /*****************************************************************************/
68 
69 /*****************************************************************************/
79  unsigned char buf[MatBLKSIZE];
80  int little; /* 1 if current platform is little endian (i386), else 0 */
81  struct tm st;
82 
83  if(ECAT7_TEST) printf("ecat7ReadMainheader()\n");
84  if(fp==NULL || h==NULL) return(1);
85  little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
86 
87  /* Seek the first block */
88  fseek(fp, 0, SEEK_SET); if(ftell(fp)!=0) return(2);
89  /* Read the header block */
90  if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
91 
92  /* Copy the header fields and swap if necessary */
93  memcpy(&h->magic_number, buf+0, 14);
94  memcpy(&h->original_file_name, buf+14, 32);
95  if(little) swabip(buf+46, 2); memcpy(&h->sw_version, buf+46, 2);
96  if(little) swabip(buf+48, 2); memcpy(&h->system_type, buf+48, 2);
97  if(little) swabip(buf+50, 2); memcpy(&h->file_type, buf+50, 2);
98  memcpy(&h->serial_number, buf+52, 10);
99  if(little) swawbip(buf+62, 4); memcpy(&h->scan_start_time, buf+62, 4);
100  memcpy(&h->isotope_name, buf+66, 8);
101  if(little) swawbip(buf+74, 4); memcpy(&h->isotope_halflife, buf+74, 4);
102  memcpy(&h->radiopharmaceutical, buf+78, 32);
103  if(little) swawbip(buf+110, 4); memcpy(&h->gantry_tilt, buf+110, 4);
104  if(little) swawbip(buf+114, 4); memcpy(&h->gantry_rotation, buf+114, 4);
105  if(little) swawbip(buf+118, 4); memcpy(&h->bed_elevation, buf+118, 4);
106  if(little) swawbip(buf+122, 4); memcpy(&h->intrinsic_tilt, buf+122, 4);
107  if(little) swabip(buf+126, 2); memcpy(&h->wobble_speed, buf+126, 2);
108  if(little) swabip(buf+128, 2); memcpy(&h->transm_source_type, buf+128, 2);
109  if(little) swawbip(buf+130, 4); memcpy(&h->distance_scanned, buf+130, 4);
110  if(little) swawbip(buf+134, 4); memcpy(&h->transaxial_fov, buf+134, 4);
111  if(little) swabip(buf+138, 2); memcpy(&h->angular_compression, buf+138, 2);
112  if(little) swabip(buf+140, 2); memcpy(&h->coin_samp_mode, buf+140, 2);
113  if(little) swabip(buf+142, 2); memcpy(&h->axial_samp_mode, buf+142, 2);
114  if(little) swawbip(buf+144, 4); memcpy(&h->ecat_calibration_factor, buf+144, 4);
115  if(little) swabip(buf+148, 2); memcpy(&h->calibration_units, buf+148, 2);
116  if(little) swabip(buf+150, 2); memcpy(&h->calibration_units_label, buf+150, 2);
117  if(little) swabip(buf+152, 2); memcpy(&h->compression_code, buf+152, 2);
118  memcpy(&h->study_type, buf+154, 12);
119  memcpy(&h->patient_id, buf+166, 16);
120  memcpy(&h->patient_name, buf+182, 32);
121  memcpy(&h->patient_sex, buf+214, 1);
122  memcpy(&h->patient_dexterity, buf+215, 1);
123  if(little) swawbip(buf+216, 4); memcpy(&h->patient_age, buf+216, 4);
124  if(little) swawbip(buf+220, 4); memcpy(&h->patient_height, buf+220, 4);
125  if(little) swawbip(buf+224, 4); memcpy(&h->patient_weight, buf+224, 4);
126  if(little) swawbip(buf+228, 4); memcpy(&h->patient_birth_date, buf+228, 4);
127  memcpy(&h->physician_name, buf+232, 32);
128  memcpy(&h->operator_name, buf+264, 32);
129  memcpy(&h->study_description, buf+296, 32);
130  if(little) swabip(buf+328, 2); memcpy(&h->acquisition_type, buf+328, 2);
131  if(little) swabip(buf+330, 2); memcpy(&h->patient_orientation, buf+330, 2);
132  memcpy(&h->facility_name, buf+332, 20);
133  if(little) swabip(buf+352, 2); memcpy(&h->num_planes, buf+352, 2);
134  if(little) swabip(buf+354, 2); memcpy(&h->num_frames, buf+354, 2);
135  if(little) swabip(buf+356, 2); memcpy(&h->num_gates, buf+356, 2);
136  if(little) swabip(buf+358, 2); memcpy(&h->num_bed_pos, buf+358, 2);
137  if(little) swawbip(buf+360, 4); memcpy(&h->init_bed_position, buf+360, 4);
138  if(little) swawbip(buf+364, 15*4); memcpy(h->bed_position, buf+364, 15*4);
139  if(little) swawbip(buf+424, 4); memcpy(&h->plane_separation, buf+424, 4);
140  if(little) swabip(buf+428, 2); memcpy(&h->lwr_sctr_thres, buf+428, 2);
141  if(little) swabip(buf+430, 2); memcpy(&h->lwr_true_thres, buf+430, 2);
142  memcpy(&h->upr_true_thres, buf+432, 2); if(little) swabip(&h->upr_true_thres, 2);
143  memcpy(&h->user_process_code, buf+434, 10);
144  if(little) swabip(buf+444, 2); memcpy(&h->acquisition_mode, buf+444, 2);
145  if(little) swawbip(buf+446, 4); memcpy(&h->bin_size, buf+446, 4);
146  if(little) swawbip(buf+450, 4); memcpy(&h->branching_fraction, buf+450, 4);
147  if(little) swawbip(buf+454, 4); memcpy(&h->dose_start_time, buf+454, 4);
148  if(little) swawbip(buf+458, 4); memcpy(&h->dosage, buf+458, 4);
149  if(little) swawbip(buf+462, 4); memcpy(&h->well_counter_corr_factor, buf+462, 4);
150  memcpy(&h->data_units, buf+466, 32);
151  if(little) swabip(buf+498, 2); memcpy(&h->septa_state, buf+498, 2);
152  memcpy(&h->fill_cti, buf+500, 12);
153 
154  /* Patient birth date can have been saved in two different int formats,
155  either YYYYMMDD or as seconds from start of year 1970. In latter case
156  the number can be negative. */
157  /* Seconds from start of year 1970 are converted to YYYYMMDD format */
158  if(isdate4(h->patient_birth_date, NULL, NULL, NULL)!=0) {
159  time_to_tm((time_t)h->patient_birth_date, 12*3600-timezone, &st);
160  h->patient_birth_date=10000*(st.tm_year+1900)+100*(st.tm_mon+1)+st.tm_mday;
161  }
162 
163  return(0);
164 }
165 /*****************************************************************************/
166 
167 /*****************************************************************************/
177 int ecat7ReadImageheader(FILE *fp, int blk, ECAT7_imageheader *h) {
178  unsigned char buf[MatBLKSIZE];
179  int little; /* 1 if current platform is little endian (i386), else 0 */
180 
181  if(ECAT7_TEST) printf("ecat7ReadImageheader()\n");
182  if(fp==NULL || h==NULL) return(1);
183  little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
184 
185  /* Seek the subheader block */
186  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
187  if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
188  /* Read the header block */
189  if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
190 
191  /* Copy the header fields and swap if necessary */
192  if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
193  if(little) swabip(buf+2, 2); memcpy(&h->num_dimensions, buf+2, 2);
194  if(little) swabip(buf+4, 2); memcpy(&h->x_dimension, buf+4, 2);
195  if(little) swabip(buf+6, 2); memcpy(&h->y_dimension, buf+6, 2);
196  if(little) swabip(buf+8, 2); memcpy(&h->z_dimension, buf+8, 2);
197  if(little) swawbip(buf+10, 4); memcpy(&h->x_offset, buf+10, 4);
198  if(little) swawbip(buf+14, 4); memcpy(&h->y_offset, buf+14, 4);
199  if(little) swawbip(buf+18, 4); memcpy(&h->z_offset, buf+18, 4);
200  if(little) swawbip(buf+22, 4); memcpy(&h->recon_zoom, buf+22, 4);
201  if(little) swawbip(buf+26, 4); memcpy(&h->scale_factor, buf+26, 4);
202  if(little) swabip(buf+30, 2); memcpy(&h->image_min, buf+30, 2);
203  if(little) swabip(buf+32, 2); memcpy(&h->image_max, buf+32, 2);
204  if(little) swawbip(buf+34, 4); memcpy(&h->x_pixel_size, buf+34, 4);
205  if(little) swawbip(buf+38, 4); memcpy(&h->y_pixel_size, buf+38, 4);
206  if(little) swawbip(buf+42, 4); memcpy(&h->z_pixel_size, buf+42, 4);
207  if(little) swawbip(buf+46, 4); memcpy(&h->frame_duration, buf+46, 4);
208  if(little) swawbip(buf+50, 4); memcpy(&h->frame_start_time, buf+50, 4);
209  if(little) swabip(buf+54, 2); memcpy(&h->filter_code, buf+54, 2);
210  if(little) swawbip(buf+56, 4); memcpy(&h->x_resolution, buf+56, 4);
211  if(little) swawbip(buf+60, 4); memcpy(&h->y_resolution, buf+60, 4);
212  if(little) swawbip(buf+64, 4); memcpy(&h->z_resolution, buf+64, 4);
213  if(little) swawbip(buf+68, 4); memcpy(&h->num_r_elements, buf+68, 4);
214  if(little) swawbip(buf+72, 4); memcpy(&h->num_angles, buf+72, 4);
215  if(little) swawbip(buf+76, 4); memcpy(&h->z_rotation_angle, buf+76, 4);
216  if(little) swawbip(buf+80, 4); memcpy(&h->decay_corr_fctr, buf+80, 4);
217  if(little) swawbip(buf+84, 4); memcpy(&h->processing_code, buf+84, 4);
218  if(little) swawbip(buf+88, 4); memcpy(&h->gate_duration, buf+88, 4);
219  if(little) swawbip(buf+92, 4); memcpy(&h->r_wave_offset, buf+92, 4);
220  if(little) swawbip(buf+96, 4); memcpy(&h->num_accepted_beats, buf+96, 4);
221  if(little) swawbip(buf+100, 4); memcpy(&h->filter_cutoff_frequency, buf+100, 4);
222  if(little) swawbip(buf+104, 4); memcpy(&h->filter_resolution, buf+104, 4);
223  if(little) swawbip(buf+108, 4); memcpy(&h->filter_ramp_slope, buf+108, 4);
224  if(little) swabip(buf+112, 2); memcpy(&h->filter_order, buf+112, 2);
225  if(little) swawbip(buf+114, 4); memcpy(&h->filter_scatter_fraction, buf+114, 4);
226  if(little) swawbip(buf+118, 4); memcpy(&h->filter_scatter_slope, buf+118, 4);
227  memcpy(&h->annotation, buf+122, 40);
228  if(little) swawbip(buf+162, 4); memcpy(&h->mt_1_1, buf+162, 4);
229  if(little) swawbip(buf+166, 4); memcpy(&h->mt_1_2, buf+166, 4);
230  if(little) swawbip(buf+170, 4); memcpy(&h->mt_1_3, buf+170, 4);
231  if(little) swawbip(buf+174, 4); memcpy(&h->mt_2_1, buf+174, 4);
232  if(little) swawbip(buf+178, 4); memcpy(&h->mt_2_2, buf+178, 4);
233  if(little) swawbip(buf+182, 4); memcpy(&h->mt_2_3, buf+182, 4);
234  if(little) swawbip(buf+186, 4); memcpy(&h->mt_3_1, buf+186, 4);
235  if(little) swawbip(buf+190, 4); memcpy(&h->mt_3_2, buf+190, 4);
236  if(little) swawbip(buf+194, 4); memcpy(&h->mt_3_3, buf+194, 4);
237  if(little) swawbip(buf+198, 4); memcpy(&h->rfilter_cutoff, buf+198, 4);
238  if(little) swawbip(buf+202, 4); memcpy(&h->rfilter_resolution, buf+202, 4);
239  if(little) swabip(buf+206, 2); memcpy(&h->rfilter_code, buf+206, 2);
240  if(little) swabip(buf+208, 2); memcpy(&h->rfilter_order, buf+208, 2);
241  if(little) swawbip(buf+210, 4); memcpy(&h->zfilter_cutoff, buf+210, 4);
242  if(little) swawbip(buf+214, 4); memcpy(&h->zfilter_resolution, buf+214, 4);
243  if(little) swabip(buf+218, 2); memcpy(&h->zfilter_code, buf+218, 2);
244  if(little) swabip(buf+220, 2); memcpy(&h->zfilter_order, buf+220, 2);
245  if(little) swawbip(buf+222, 4); memcpy(&h->mt_1_4, buf+222, 4);
246  if(little) swawbip(buf+226, 4); memcpy(&h->mt_2_4, buf+226, 4);
247  if(little) swawbip(buf+230, 4); memcpy(&h->mt_3_4, buf+230, 4);
248  if(little) swabip(buf+234, 2); memcpy(&h->scatter_type, buf+234, 2);
249  if(little) swabip(buf+236, 2); memcpy(&h->recon_type, buf+236, 2);
250  if(little) swabip(buf+238, 2); memcpy(&h->recon_views, buf+238, 2);
251  memcpy(&h->fill_cti, buf+240, 174);
252  memcpy(&h->fill_user, buf+414, 96);
253 
254  return(0);
255 }
256 /*****************************************************************************/
257 
258 /*****************************************************************************/
268 int ecat7ReadAttenheader(FILE *fp, int blk, ECAT7_attenheader *h) {
269  unsigned char buf[MatBLKSIZE];
270  int little; /* 1 if current platform is little endian (i386), else 0 */
271 
272  if(ECAT7_TEST) printf("ecat7ReadAttenheader()\n");
273  if(fp==NULL || h==NULL) return(1);
274  little=little_endian();
275 
276  /* Seek the subheader block */
277  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
278  if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
279  /* Read the header block */
280  if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
281  /* Copy the header fields and swap if necessary */
282  if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
283  if(little) swabip(buf+2, 2); memcpy(&h->num_dimensions, buf+2, 2);
284  if(little) swabip(buf+4, 2); memcpy(&h->attenuation_type, buf+4, 2);
285  if(little) swabip(buf+6, 2); memcpy(&h->num_r_elements, buf+6, 2);
286  if(little) swabip(buf+8, 2); memcpy(&h->num_angles, buf+8, 2);
287  if(little) swabip(buf+10, 2); memcpy(&h->num_z_elements, buf+10, 2);
288  if(little) swabip(buf+12, 2); memcpy(&h->ring_difference, buf+12, 2);
289  if(little) swawbip(buf+14, 4); memcpy(&h->x_resolution, buf+14, 4);
290  if(little) swawbip(buf+18, 4); memcpy(&h->y_resolution, buf+18, 4);
291  if(little) swawbip(buf+22, 4); memcpy(&h->z_resolution, buf+22, 4);
292  if(little) swawbip(buf+26, 4); memcpy(&h->w_resolution, buf+26, 4);
293  if(little) swawbip(buf+30, 4); memcpy(&h->scale_factor, buf+30, 4);
294  if(little) swawbip(buf+34, 4); memcpy(&h->x_offset, buf+34, 4);
295  if(little) swawbip(buf+38, 4); memcpy(&h->y_offset, buf+38, 4);
296  if(little) swawbip(buf+42, 4); memcpy(&h->x_radius, buf+42, 4);
297  if(little) swawbip(buf+46, 4); memcpy(&h->y_radius, buf+46, 4);
298  if(little) swawbip(buf+50, 4); memcpy(&h->tilt_angle, buf+50, 4);
299  if(little) swawbip(buf+54, 4); memcpy(&h->attenuation_coeff, buf+54, 4);
300  if(little) swawbip(buf+58, 4); memcpy(&h->attenuation_min, buf+58, 4);
301  if(little) swawbip(buf+62, 4); memcpy(&h->attenuation_max, buf+62, 4);
302  if(little) swawbip(buf+66, 4); memcpy(&h->skull_thickness, buf+66, 4);
303  if(little) swabip(buf+70, 2); memcpy(&h->num_additional_atten_coeff, buf+70, 2);
304  if(little) swawbip(buf+72, 8*4); memcpy(h->additional_atten_coeff, buf+72, 8*4);
305  if(little) swawbip(buf+104, 4); memcpy(&h->edge_finding_threshold, buf+104, 4);
306  if(little) swabip(buf+108, 2); memcpy(&h->storage_order, buf+108, 2);
307  if(little) swabip(buf+110, 2); memcpy(&h->span, buf+110, 2);
308  if(little) swabip(buf+112, 64*2); memcpy(h->z_elements, buf+112, 64*2);
309  if(little) swabip(buf+240, 86*2); memcpy(h->fill_cti, buf+240, 86*2);
310  if(little) swabip(buf+412, 50*2); memcpy(h->fill_user, buf+412, 50*2);
311  return(0);
312 }
313 /*****************************************************************************/
314 
315 /*****************************************************************************/
325 int ecat7ReadPolmapheader(FILE *fp, int blk, ECAT7_polmapheader *h) {
326  unsigned char buf[MatBLKSIZE];
327  int little; /* 1 if current platform is little endian (i386), else 0 */
328 
329  if(ECAT7_TEST) printf("ecat7ReadPolarmapheader()\n");
330  if(fp==NULL || h==NULL) return(1);
331  little=little_endian();
332 
333  /* Seek the subheader block */
334  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
335  if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
336  /* Read the header block */
337  if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
338  /* Copy the header fields and swap if necessary */
339  if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
340  if(little) swabip(buf+2, 2); memcpy(&h->polar_map_type, buf+2, 2);
341  if(little) swabip(buf+4, 2); memcpy(&h->num_rings, buf+4, 2);
342  if(little) swabip(buf+6, 32*2); memcpy(h->sectors_per_ring, buf+6, 32*2);
343  if(little) swawbip(buf+70, 32*4); memcpy(h->ring_position, buf+70, 32*4);
344  if(little) swabip(buf+198, 32*2); memcpy(h->ring_angle, buf+198, 32*2);
345  if(little) swabip(buf+262, 2); memcpy(&h->start_angle, buf+262, 2);
346  if(little) swabip(buf+264, 3*2); memcpy(h->long_axis_left, buf+264, 3*2);
347  if(little) swabip(buf+270, 3*2); memcpy(h->long_axis_right, buf+270, 3*2);
348  if(little) swabip(buf+276, 2); memcpy(&h->position_data, buf+276, 2);
349  if(little) swabip(buf+278, 2); memcpy(&h->image_min, buf+278, 2);
350  if(little) swabip(buf+280, 2); memcpy(&h->image_max, buf+280, 2);
351  if(little) swawbip(buf+282, 4); memcpy(&h->scale_factor, buf+282, 4);
352  if(little) swawbip(buf+286, 4); memcpy(&h->pixel_size, buf+286, 4);
353  if(little) swawbip(buf+290, 4); memcpy(&h->frame_duration, buf+290, 4);
354  if(little) swawbip(buf+294, 4); memcpy(&h->frame_start_time, buf+294, 4);
355  if(little) swabip(buf+298, 2); memcpy(&h->processing_code, buf+298, 2);
356  if(little) swabip(buf+300, 2); memcpy(&h->quant_units, buf+300, 2);
357  memcpy(h->annotation, buf+302, 40);
358  if(little) swawbip(buf+342, 4); memcpy(&h->gate_duration, buf+342, 4);
359  if(little) swawbip(buf+346, 4); memcpy(&h->r_wave_offset, buf+346, 4);
360  if(little) swawbip(buf+350, 4); memcpy(&h->num_accepted_beats, buf+350, 4);
361  memcpy(h->polar_map_protocol, buf+354, 20);
362  memcpy(h->database_name, buf+374, 30);
363  if(little) swabip(buf+404, 27*2); memcpy(h->fill_cti, buf+404, 27*2);
364  return(0);
365 }
366 /*****************************************************************************/
367 
368 /*****************************************************************************/
378 int ecat7ReadNormheader(FILE *fp, int blk, ECAT7_normheader *h) {
379  unsigned char buf[MatBLKSIZE];
380  int little; /* 1 if current platform is little endian (i386), else 0 */
381 
382  if(ECAT7_TEST) printf("ecat7ReadNormheader()\n");
383  if(fp==NULL || h==NULL) return(1);
384  little=little_endian();
385 
386  /* Seek the subheader block */
387  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
388  if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
389  /* Read the header block */
390  if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
391  /* Copy the header fields and swap if necessary */
392  if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
393  if(little) swabip(buf+2, 2); memcpy(&h->num_r_elements, buf+2, 2);
394  if(little) swabip(buf+4, 2); memcpy(&h->num_transaxial_crystals, buf+4, 2);
395  if(little) swabip(buf+6, 2); memcpy(&h->num_crystal_rings, buf+6, 2);
396  if(little) swabip(buf+8, 2); memcpy(&h->crystals_per_ring, buf+8, 2);
397  if(little) swabip(buf+10, 2); memcpy(&h->num_geo_corr_planes, buf+10, 2);
398  if(little) swabip(buf+12, 2); memcpy(&h->uld, buf+12, 2);
399  if(little) swabip(buf+14, 2); memcpy(&h->lld, buf+14, 2);
400  if(little) swabip(buf+16, 2); memcpy(&h->scatter_energy, buf+16, 2);
401  if(little) swawbip(buf+18, 4); memcpy(&h->norm_quality_factor, buf+18, 4);
402  if(little) swabip(buf+22, 2); memcpy(&h->norm_quality_factor_code, buf+22, 2);
403  if(little) swawbip(buf+24, 32*4); memcpy(h->ring_dtcor1, buf+24, 32*4);
404  if(little) swawbip(buf+152, 32*4); memcpy(h->ring_dtcor2, buf+152, 32*4);
405  if(little) swawbip(buf+280, 8*4); memcpy(h->crystal_dtcor, buf+280, 8*4);
406  if(little) swabip(buf+312, 2); memcpy(&h->span, buf+312, 2);
407  if(little) swabip(buf+314, 2); memcpy(&h->max_ring_diff, buf+314, 2);
408  if(little) swabip(buf+316, 48*2); memcpy(h->fill_cti, buf+316, 48*2);
409  if(little) swabip(buf+412, 50*2); memcpy(h->fill_user, buf+412, 50*2);
410  return(0);
411 }
412 /*****************************************************************************/
413 
414 /*****************************************************************************/
424 int ecat7ReadScanheader(FILE *fp, int blk, ECAT7_scanheader *h) {
425  unsigned char buf[2*MatBLKSIZE];
426  int little; /* 1 if current platform is little endian (i386), else 0 */
427 
428  if(ECAT7_TEST) printf("ecat7ReadScanheader()\n");
429  if(fp==NULL || h==NULL) return(1);
430  little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
431 
432  /* Seek the subheader block */
433  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
434  /* Read the header block */
435  if(fread(buf, MatBLKSIZE, 2, fp)<1) return(3);
436 
437  /* Copy the header fields and swap if necessary */
438  if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
439  if(little) swabip(buf+2, 2); memcpy(&h->num_dimensions, buf+2, 2);
440  if(little) swabip(buf+4, 2); memcpy(&h->num_r_elements, buf+4, 2);
441  if(little) swabip(buf+6, 2); memcpy(&h->num_angles, buf+6, 2);
442  if(little) swabip(buf+8, 2); memcpy(&h->corrections_applied, buf+8, 2);
443  if(little) swabip(buf+10, 64*2); memcpy(h->num_z_elements, buf+10, 64*2);
444  if(little) swabip(buf+138, 2); memcpy(&h->ring_difference, buf+138, 2);
445  if(little) swabip(buf+140, 2); memcpy(&h->storage_order, buf+140, 2);
446  if(little) swabip(buf+142, 2); memcpy(&h->axial_compression, buf+142, 2);
447  if(little) swawbip(buf+144, 4); memcpy(&h->x_resolution, buf+144, 4);
448  if(little) swawbip(buf+148, 4); memcpy(&h->v_resolution, buf+148, 4);
449  if(little) swawbip(buf+152, 4); memcpy(&h->z_resolution, buf+152, 4);
450  if(little) swawbip(buf+156, 4); memcpy(&h->w_resolution, buf+156, 4);
451  if(little) swabip(buf+160, 6*2); memcpy(h->fill_gate, buf+160, 6*2);
452  if(little) swawbip(buf+172, 4); memcpy(&h->gate_duration, buf+172, 4);
453  if(little) swawbip(buf+176, 4); memcpy(&h->r_wave_offset, buf+176, 4);
454  if(little) swawbip(buf+180, 4); memcpy(&h->num_accepted_beats, buf+180, 4);
455  if(little) swawbip(buf+184, 4); memcpy(&h->scale_factor, buf+184, 4);
456  if(little) swabip(buf+188, 2); memcpy(&h->scan_min, buf+188, 2);
457  if(little) swabip(buf+190, 2); memcpy(&h->scan_max, buf+190, 2);
458  if(little) swawbip(buf+192, 4); memcpy(&h->prompts, buf+192, 4);
459  if(little) swawbip(buf+196, 4); memcpy(&h->delayed, buf+196, 4);
460  if(little) swawbip(buf+200, 4); memcpy(&h->multiples, buf+200, 4);
461  if(little) swawbip(buf+204, 4); memcpy(&h->net_trues, buf+204, 4);
462  if(little) swawbip(buf+208, 4); memcpy(&h->tot_avg_cor, buf+208, 4);
463  if(little) swawbip(buf+212, 4); memcpy(&h->tot_avg_uncor, buf+212, 4);
464  if(little) swawbip(buf+216, 4); memcpy(&h->total_coin_rate, buf+216, 4);
465  if(little) swawbip(buf+220, 4); memcpy(&h->frame_start_time, buf+220, 4);
466  if(little) swawbip(buf+224, 4); memcpy(&h->frame_duration, buf+224, 4);
467  if(little) swawbip(buf+228, 4); memcpy(&h->deadtime_correction_factor, buf+228, 4);
468  if(little) swabip(buf+232, 90*2); memcpy(h->fill_cti, buf+232, 90*2);
469  if(little) swabip(buf+412, 50*2); memcpy(h->fill_user, buf+412, 50*2);
470  if(little) swawbip(buf+512, 128*4); memcpy(h->uncor_singles, buf+512, 128*4);
471  return(0);
472 }
473 /*****************************************************************************/
474 
475 /*****************************************************************************/
485 int ecat7Read2DScanheader(FILE *fp, int blk, ECAT7_2Dscanheader *h) {
486  unsigned char buf[MatBLKSIZE];
487  int little; /* 1 if current platform is little endian (i386), else 0 */
488 
489  if(ECAT7_TEST) printf("ecat7Read2DScanheader()\n");
490  if(fp==NULL || h==NULL) return(1);
491  little=little_endian();
492 
493  /* Seek the subheader block */
494  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
495  if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
496  /* Read the header block */
497  if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
498  /* Copy the header fields and swap if necessary */
499  if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
500  if(little) swabip(buf+2, 2); memcpy(&h->num_dimensions, buf+2, 2);
501  if(little) swabip(buf+4, 2); memcpy(&h->num_r_elements, buf+4, 2);
502  if(little) swabip(buf+6, 2); memcpy(&h->num_angles, buf+6, 2);
503  if(little) swabip(buf+8, 2); memcpy(&h->corrections_applied, buf+8, 2);
504  if(little) swabip(buf+10, 2); memcpy(&h->num_z_elements, buf+10, 2);
505  if(little) swabip(buf+12, 2); memcpy(&h->ring_difference, buf+12, 2);
506  if(little) swawbip(buf+14, 4); memcpy(&h->x_resolution, buf+14, 4);
507  if(little) swawbip(buf+18, 4); memcpy(&h->y_resolution, buf+18, 4);
508  if(little) swawbip(buf+22, 4); memcpy(&h->z_resolution, buf+22, 4);
509  if(little) swawbip(buf+26, 4); memcpy(&h->w_resolution, buf+26, 4);
510  if(little) swabip(buf+30, 6*2); memcpy(h->fill_gate, buf+30, 6*2);
511  if(little) swawbip(buf+42, 4); memcpy(&h->gate_duration, buf+42, 4);
512  if(little) swawbip(buf+46, 4); memcpy(&h->r_wave_offset, buf+46, 4);
513  if(little) swawbip(buf+50, 4); memcpy(&h->num_accepted_beats, buf+50, 4);
514  if(little) swawbip(buf+54, 4); memcpy(&h->scale_factor, buf+54, 4);
515  if(little) swabip(buf+58, 2); memcpy(&h->scan_min, buf+58, 2);
516  if(little) swabip(buf+60, 2); memcpy(&h->scan_max, buf+60, 2);
517  if(little) swawbip(buf+62, 4); memcpy(&h->prompts, buf+62, 4);
518  if(little) swawbip(buf+66, 4); memcpy(&h->delayed, buf+66, 4);
519  if(little) swawbip(buf+70, 4); memcpy(&h->multiples, buf+70, 4);
520  if(little) swawbip(buf+74, 4); memcpy(&h->net_trues, buf+74, 4);
521  if(little) swawbip(buf+78, 16*4); memcpy(h->cor_singles, buf+78, 16*4);
522  if(little) swawbip(buf+142, 16*4); memcpy(h->uncor_singles, buf+142, 16*4);
523  if(little) swawbip(buf+206, 4); memcpy(&h->tot_avg_cor, buf+206, 4);
524  if(little) swawbip(buf+210, 4); memcpy(&h->tot_avg_uncor, buf+210, 4);
525  if(little) swawbip(buf+214, 4); memcpy(&h->total_coin_rate, buf+214, 4);
526  if(little) swawbip(buf+218, 4); memcpy(&h->frame_start_time, buf+218, 4);
527  if(little) swawbip(buf+222, 4); memcpy(&h->frame_duration, buf+222, 4);
528  if(little) swawbip(buf+226, 4); memcpy(&h->deadtime_correction_factor, buf+226, 4);
529  if(little) swabip(buf+230, 8*2); memcpy(h->physical_planes, buf+230, 8*2);
530  if(little) swabip(buf+246, 83*2); memcpy(h->fill_cti, buf+246, 83*2);
531  if(little) swabip(buf+412, 50*2); memcpy(h->fill_user, buf+412, 50*2);
532  return(0);
533 }
534 /*****************************************************************************/
535 
536 /*****************************************************************************/
546 int ecat7Read2DNormheader(FILE *fp, int blk, ECAT7_2Dnormheader *h) {
547  unsigned char buf[MatBLKSIZE];
548  int little; /* 1 if current platform is little endian (i386), else 0 */
549 
550  if(ECAT7_TEST) printf("ecat7Read2Dnormheader()\n");
551  if(fp==NULL || h==NULL) return(1);
552  little=little_endian();
553 
554  /* Seek the subheader block */
555  fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
556  if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
557  /* Read the header block */
558  if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
559  /* Copy the header fields and swap if necessary */
560  if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
561  if(little) swabip(buf+2, 2); memcpy(&h->num_dimensions, buf+2, 2);
562  if(little) swabip(buf+4, 2); memcpy(&h->num_r_elements, buf+4, 2);
563  if(little) swabip(buf+6, 2); memcpy(&h->num_angles, buf+6, 2);
564  if(little) swabip(buf+8, 2); memcpy(&h->num_z_elements, buf+8, 2);
565  if(little) swabip(buf+10, 2); memcpy(&h->ring_difference, buf+10, 2);
566  if(little) swawbip(buf+12, 4); memcpy(&h->scale_factor, buf+12, 4);
567  if(little) swawbip(buf+16, 4); memcpy(&h->norm_min, buf+16, 4);
568  if(little) swawbip(buf+20, 4); memcpy(&h->norm_max, buf+20, 4);
569  if(little) swawbip(buf+24, 4); memcpy(&h->fov_source_width, buf+24, 4);
570  if(little) swawbip(buf+28, 4); memcpy(&h->norm_quality_factor, buf+28, 4);
571  if(little) swabip(buf+32, 2); memcpy(&h->norm_quality_factor_code, buf+32, 2);
572  if(little) swabip(buf+34, 2); memcpy(&h->storage_order, buf+34, 2);
573  if(little) swabip(buf+36, 2); memcpy(&h->span, buf+36, 2);
574  if(little) swabip(buf+38, 64*2); memcpy(h->fill_cti, buf+38, 64*2);
575  if(little) swabip(buf+166, 123*2); memcpy(h->fill_cti, buf+166, 123*2);
576  if(little) swabip(buf+412, 50*2); memcpy(h->fill_user, buf+412, 50*2);
577  return(0);
578 }
579 /*****************************************************************************/
580 
581 /*****************************************************************************/
595 int ecat7ReadMatrixdata(FILE *fp, int start_block, int block_nr, char *data, int dtype) {
596  int i, n, little, err=0;
597  char *cptr;
598  float f;
599 
600  if(ECAT7_TEST) printf("ecat7ReadMatrixdata(fp, %d, %d, data, %d)\n",
601  start_block, block_nr, dtype);
602  /* Check the arguments */
603  if(block_nr<=0 || start_block<1 || data==NULL) return(1);
604  /* Seek the first data block */
605  fseek(fp, (start_block-1)*MatBLKSIZE, SEEK_SET);
606  if(ftell(fp)!=(start_block-1)*MatBLKSIZE) return(9);
607  /* Read the data blocks */
608  if(fread(data, MatBLKSIZE, block_nr, fp) < block_nr) return(2);
609  /* Translate data if necessary */
610  little=little_endian();
611  switch(dtype) {
612  case ECAT7_BYTE: /* byte format...no translation necessary */
613  break;
614  case ECAT7_VAXI2: /* byte conversion necessary on big endian platform */
615  if(!little) {cptr=data; swabip(cptr, block_nr*MatBLKSIZE);}
616  break;
617  case ECAT7_VAXI4:
618  for(i=0, cptr=data; i<block_nr*MatBLKSIZE; i+=4, cptr+=4) {
619  n=ecat7rInt(cptr, 1, little); memcpy(cptr, &n, 4);
620  }
621  break;
622  case ECAT7_VAXR4:
623  for(i=0, cptr=data; i<block_nr*MatBLKSIZE; i+=4, cptr+=4) {
624  f=ecat7rFloat(cptr, 1, little); memcpy(cptr, &f, 4);
625  }
626  break;
627  case ECAT7_IEEER4: /* IEEE float ; byte conversion necessary on little endian platforms */
628  case ECAT7_SUNI4: /* SUN int ; byte conversion necessary on little endian platforms */
629  if(little) swawbip(data, block_nr*MatBLKSIZE);
630  break;
631  case ECAT7_SUNI2: /* SUN short ; byte conversion necessary on little endian platforms */
632  if(little) swabip(data, block_nr*MatBLKSIZE);
633  break;
634  default: /* if something else, for now think it as an error */
635  err=2;
636  break;
637  }
638  return(err);
639 }
640 /*****************************************************************************/
641 
642 /*****************************************************************************/
656 int ecat7ReadImageMatrix(FILE *fp, int first_block, int last_block, ECAT7_imageheader *h, float **fdata) {
657  int i, ret, blockNr, pxlNr;
658  char *mdata, *mptr;
659  float *_fdata, *fptr;
660  short int *sptr;
661  int *iptr;
662 
663 
664  if(ECAT7_TEST) printf("ecat7ReadImageMatrix(fp, %d, %d, hdr, fdata)\n",
665  first_block, last_block);
666  if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
667  sprintf(ecat7errmsg, "invalid function parameter.\n");
668  return(1);
669  }
670  *fdata=(float*)NULL;
671 
672  /* Read subheader */
673  ret=ecat7ReadImageheader(fp, first_block, h);
674  if(ret) {
675  sprintf(ecat7errmsg, "cannot read subheader (%d).\n", ret);
676  return(5);
677  }
678  if(ECAT7_TEST>4) ecat7PrintImageheader(h, stdout);
679  pxlNr=h->x_dimension*h->y_dimension;
680  if(h->num_dimensions>2) pxlNr*=h->z_dimension;
681  if(pxlNr<=0) {
682  sprintf(ecat7errmsg, "invalid matrix dimension.\n");
683  return(6);
684  }
685 
686  /* Read matrix data */
687  blockNr=last_block-first_block; if(blockNr<1) return(0);
688  mdata=(char*)malloc(blockNr*MatBLKSIZE);
689  if(mdata==NULL) {
690  sprintf(ecat7errmsg, "cannot allocate memory.\n");
691  return(8);
692  }
693  mptr=mdata;
694  ret=ecat7ReadMatrixdata(fp, first_block+1, blockNr, mptr, h->data_type);
695  if(ret || mdata==NULL) {
696  sprintf(ecat7errmsg, "cannot read matrix data (%d).\n", ret);
697  free(mdata); return(9);
698  }
699 
700  /* Allocate memory for float data */
701  _fdata=(float*)malloc(pxlNr*sizeof(float));
702  if(_fdata==NULL) {
703  sprintf(ecat7errmsg, "cannot allocate memory.\n");
704  free(mdata); return(11);
705  }
706 
707  /* Convert matrix data to floats */
708  fptr=_fdata; mptr=mdata;
709  if(h->data_type==ECAT7_BYTE) {
710  for(i=0; i<pxlNr; i++, mptr++, fptr++)
711  *fptr=h->scale_factor*(float)(*mptr);
712  } else if(h->data_type==ECAT7_VAXI2 || h->data_type==ECAT7_SUNI2) {
713  for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
714  sptr=(short int*)mptr;
715  *fptr=h->scale_factor*(float)(*sptr);
716  }
717  } else if(h->data_type==ECAT7_VAXI4 || h->data_type==ECAT7_SUNI4) {
718  for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
719  iptr=(int*)mptr;
720  *fptr=h->scale_factor*(float)(*iptr);
721  }
722  } else if(h->data_type==ECAT7_VAXR4 || h->data_type==ECAT7_IEEER4) {
723  memcpy(fptr, mptr, pxlNr*4);
724  for(i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
725  }
726  free(mdata);
727  *fdata=_fdata;
728 
729  return(0);
730 }
731 /*****************************************************************************/
732 
733 /*****************************************************************************/
749 int ecat7Read2DScanMatrix(FILE *fp, int first_block, int last_block,
750  ECAT7_2Dscanheader *h, float **fdata) {
751  int i, ret, blockNr, pxlNr;
752  char *mdata, *mptr;
753  float *_fdata, *fptr;
754  short int *sptr;
755  int *iptr;
756 
757 
758  if(ECAT7_TEST) printf("ecat7Read2DScanMatrix(fp, %d, %d, hdr, fdata)\n",
759  first_block, last_block);
760  if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
761  sprintf(ecat7errmsg, "invalid function parameter.\n");
762  return(1);
763  }
764  *fdata=(float*)NULL;
765 
766  /* Read subheader */
767  ret=ecat7Read2DScanheader(fp, first_block, h);
768  if(ret) {
769  sprintf(ecat7errmsg, "cannot read subheader (%d).\n", ret);
770  return(5);
771  }
772  if(ECAT7_TEST>4) ecat7Print2DScanheader(h, stdout);
773  pxlNr=h->num_r_elements*h->num_angles;
774  if(h->num_dimensions>2) pxlNr*=h->num_z_elements;
775  if(pxlNr<=0) {
776  sprintf(ecat7errmsg, "invalid matrix dimension.\n");
777  return(6);
778  }
779 
780  /* Read matrix data */
781  blockNr=last_block-first_block; if(blockNr<1) return(0);
782  mdata=(char*)malloc(blockNr*MatBLKSIZE);
783  if(mdata==NULL) {
784  sprintf(ecat7errmsg, "cannot allocate memory.\n");
785  return(8);
786  }
787  mptr=mdata;
788  ret=ecat7ReadMatrixdata(fp, first_block+1, blockNr, mptr, h->data_type);
789  if(ret || mdata==NULL) {
790  sprintf(ecat7errmsg, "cannot read matrix data (%d).\n", ret);
791  free(mdata); return(9);
792  }
793 
794  /* Allocate memory for float data */
795  _fdata=(float*)malloc(pxlNr*sizeof(float));
796  if(_fdata==NULL) {
797  sprintf(ecat7errmsg, "cannot allocate memory.\n");
798  free(mdata); return(11);
799  }
800 
801  /* Convert matrix data to floats */
802  fptr=_fdata; mptr=mdata;
803  if(h->data_type==ECAT7_BYTE) {
804  for(i=0; i<pxlNr; i++, mptr++, fptr++)
805  *fptr=h->scale_factor*(float)(*mptr);
806  } else if(h->data_type==ECAT7_VAXI2 || h->data_type==ECAT7_SUNI2) {
807  for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
808  sptr=(short int*)mptr;
809  *fptr=h->scale_factor*(float)(*sptr);
810  }
811  } else if(h->data_type==ECAT7_VAXI4 || h->data_type==ECAT7_SUNI4) {
812  for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
813  iptr=(int*)mptr;
814  *fptr=h->scale_factor*(float)(*iptr);
815  }
816  } else if(h->data_type==ECAT7_VAXR4 || h->data_type==ECAT7_IEEER4) {
817  memcpy(fptr, mptr, pxlNr*4);
818  for(i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
819  }
820  free(mdata);
821  *fdata=_fdata;
822 
823  return(0);
824 }
825 /*****************************************************************************/
826 
827 /*****************************************************************************/
844 int ecat7ReadScanMatrix(FILE *fp, int first_block, int last_block, ECAT7_scanheader *h, float **fdata) {
845  int i, ret, blockNr, trueblockNr, pxlNr, dimz;
846  char *mdata, *mptr;
847  float *_fdata, *fptr;
848  short int *sptr;
849  int *iptr;
850 
851 
852  if(ECAT7_TEST) printf("ecat7ReadScanMatrix(fp, %d, %d, hdr, fdata)\n",
853  first_block, last_block);
854  if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
855  sprintf(ecat7errmsg, "invalid function parameter.\n");
856  return(1);
857  }
858  *fdata=(float*)NULL;
859 
860  /* Read subheader */
861  ret=ecat7ReadScanheader(fp, first_block, h);
862  if(ret) {
863  sprintf(ecat7errmsg, "cannot read subheader (%d).\n", ret);
864  return(5);
865  }
866  if(ECAT7_TEST>4) ecat7PrintScanheader(h, stdout);
867  pxlNr=h->num_r_elements*h->num_angles;
868  for(i=dimz=0; i<64; i++) dimz+=h->num_z_elements[i]; pxlNr*=dimz;
869  if(pxlNr<=0) {
870  sprintf(ecat7errmsg, "invalid matrix dimension.\n");
871  return(6);
872  }
873  trueblockNr=pxlNr*ecat7pxlbytes(h->data_type);
874  trueblockNr=(trueblockNr+MatBLKSIZE-1)/MatBLKSIZE;
875 
876  /* Read matrix data; note that header takes 2 blocks */
877  blockNr=last_block-first_block-1; if(blockNr<1) return(0);
878  if(blockNr<trueblockNr) trueblockNr=blockNr;
879  mdata=(char*)malloc(blockNr*MatBLKSIZE);
880  if(mdata==NULL) {
881  sprintf(ecat7errmsg, "cannot allocate memory.\n");
882  return(8);
883  }
884  mptr=mdata; /* note that only true block nr is read! */
885  ret=ecat7ReadMatrixdata(fp, first_block+2, trueblockNr, mptr, h->data_type);
886  if(ret || mdata==NULL) {
887  sprintf(ecat7errmsg, "cannot read matrix data (%d).\n", ret);
888  free(mdata); return(9);
889  }
890 
891  /* Allocate memory for float data */
892  _fdata=(float*)malloc(pxlNr*sizeof(float));
893  if(_fdata==NULL) {
894  sprintf(ecat7errmsg, "cannot allocate memory.\n");
895  free(mdata); return(11);
896  }
897 
898  /* Convert matrix data to floats */
899  fptr=_fdata; mptr=mdata;
900  if(h->data_type==ECAT7_BYTE) {
901  for(i=0; i<pxlNr; i++, mptr++, fptr++)
902  *fptr=h->scale_factor*(float)(*mptr);
903  } else if(h->data_type==ECAT7_VAXI2 || h->data_type==ECAT7_SUNI2) {
904  for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
905  sptr=(short int*)mptr;
906  *fptr=h->scale_factor*(float)(*sptr);
907  }
908  } else if(h->data_type==ECAT7_VAXI4 || h->data_type==ECAT7_SUNI4) {
909  for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
910  iptr=(int*)mptr;
911  *fptr=h->scale_factor*(float)(*iptr);
912  }
913  } else if(h->data_type==ECAT7_VAXR4 || h->data_type==ECAT7_IEEER4) {
914  memcpy(fptr, mptr, pxlNr*4);
915  for(i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
916  }
917  free(mdata);
918  *fdata=_fdata;
919 
920  return(0);
921 }
922 /*****************************************************************************/
923 
924 /*****************************************************************************/
939 int ecat7ReadPolarmapMatrix(FILE *fp, int first_block, int last_block, ECAT7_polmapheader *h, float **fdata) {
940  int i, ret, blockNr, pxlNr;
941  char *mdata, *mptr;
942  float *_fdata, *fptr;
943  short int *sptr;
944  int *iptr;
945 
946 
947  if(ECAT7_TEST) printf("ecat7ReadPolarmapMatrix(fp, %d, %d, hdr, fdata)\n",
948  first_block, last_block);
949  if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) return 1;
950  *fdata=(float*)NULL;
951 
952  /* Read subheader */
953  ret=ecat7ReadPolmapheader(fp, first_block, h);
954  if(ret) {
955  sprintf(ecat7errmsg, "cannot read subheader (%d).\n", ret);
956  return 2;
957  }
958  if(ECAT7_TEST>4) ecat7PrintPolmapheader(h, stdout);
959  for(i=pxlNr=0; i<h->num_rings; i++) pxlNr+=h->sectors_per_ring[i];
960  if(pxlNr<=0) return 3;
961 
962  /* Read matrix data */
963  blockNr=last_block-first_block; if(blockNr<1) return 0;
964  mdata=(char*)malloc(blockNr*MatBLKSIZE);
965  if(mdata==NULL) return 4;
966  mptr=mdata;
967  ret=ecat7ReadMatrixdata(fp, first_block+1, blockNr, mptr, h->data_type);
968  if(ret || mdata==NULL) {
969  if(mdata!=NULL) free(mdata);
970  return 5;
971  }
972 
973  /* Allocate memory for float data */
974  _fdata=(float*)malloc(pxlNr*sizeof(float));
975  if(_fdata==NULL) {
976  sprintf(ecat7errmsg, "cannot allocate memory.\n");
977  free(mdata); return 4;
978  }
979 
980  /* Convert matrix data to floats */
981  fptr=_fdata; mptr=mdata;
982  if(h->data_type==ECAT7_BYTE) {
983  for(i=0; i<pxlNr; i++, mptr++, fptr++)
984  *fptr=h->scale_factor*(float)(*mptr);
985  } else if(h->data_type==ECAT7_VAXI2 || h->data_type==ECAT7_SUNI2) {
986  for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
987  sptr=(short int*)mptr;
988  *fptr=h->scale_factor*(float)(*sptr);
989  }
990  } else if(h->data_type==ECAT7_VAXI4 || h->data_type==ECAT7_SUNI4) {
991  for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
992  iptr=(int*)mptr;
993  *fptr=h->scale_factor*(float)(*iptr);
994  }
995  } else if(h->data_type==ECAT7_VAXR4 || h->data_type==ECAT7_IEEER4) {
996  memcpy(fptr, mptr, pxlNr*4);
997  for(i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
998  }
999  free(mdata);
1000  *fdata=_fdata;
1001 
1002  return 0;
1003 }
1004 /*****************************************************************************/
1005 
1006 /*****************************************************************************/
1015 float ecat7rFloat(void *bufi, int isvax, int islittle) {
1016  union {unsigned int ul; float f;} t;
1017 
1018  memcpy(&t.ul, bufi, 4); if(t.ul==0) {return(0.0);}
1019  if(isvax) { /* if input is in VAX format */
1020  /* Swap words on i386 and bytes on SUN */
1021  if(islittle) swawip(&t.ul, 4); else swabip(&t.ul, 4);
1022  t.ul-=(2L<<23); /* subtract 2 from exp */
1023  } else { /* input is in i386 format */
1024  if(!islittle) swawbip(&t.ul, 4); /* Switch words and bytes on SUN */
1025  }
1026  return(t.f);
1027 }
1028 
1038 int ecat7rInt(void *bufi, int isvax, int islittle) {
1039  int i;
1040 
1041  /* Swap both words and bytes on SUN */
1042  memcpy(&i, bufi, 4); if(!islittle) swawbip(&i, 4);
1043  return(i);
1044 }
1045 /*****************************************************************************/
1046 
1047 /*****************************************************************************/
1055 int ecat7pxlbytes(short int data_type) {
1056  int byteNr=0;
1057  switch(data_type) {
1058  case ECAT7_BYTE: byteNr=1; break;
1059  case ECAT7_VAXI2:
1060  case ECAT7_SUNI2: byteNr=2; break;
1061  case ECAT7_VAXI4:
1062  case ECAT7_VAXR4:
1063  case ECAT7_IEEER4:
1064  case ECAT7_SUNI4: byteNr=4; break;
1065  }
1066  return(byteNr);
1067 }
1068 /*****************************************************************************/
1069 
1070 /*****************************************************************************/
1071