My Project
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 
#define MatFirstDirBlk
Definition: ecat63.h:28
#define MatBLKSIZE
Definition: ecat63.h:27
#define ECAT7_IEEER4
Definition: ecat7.h:62
#define ECAT7_VAXI4
Definition: ecat7.h:60
char ecat7errmsg[128]
Definition: ecat7.h:99
#define ECAT7_SUNI4
Definition: ecat7.h:64
#define ECAT7_BYTE
Definition: ecat7.h:58
#define ECAT7_VAXI2
Definition: ecat7.h:59
#define ECAT7_VAXR4
Definition: ecat7.h:61
int ECAT7_TEST
Definition: ecat7.h:101
#define ECAT7_SUNI2
Definition: ecat7.h:63
void ecat7PrintImageheader(ECAT7_imageheader *h, FILE *fp)
Definition: ecat7p.c:137
void ecat7PrintPolmapheader(ECAT7_polmapheader *h, FILE *fp)
Definition: ecat7p.c:310
void ecat7Print2DScanheader(ECAT7_2Dscanheader *h, FILE *fp)
Definition: ecat7p.c:396
void ecat7PrintScanheader(ECAT7_scanheader *h, FILE *fp)
Definition: ecat7p.c:215
int ecat7pxlbytes(short int data_type)
Definition: ecat7r.c:1055
int ecat7Read2DScanMatrix(FILE *fp, int first_block, int last_block, ECAT7_2Dscanheader *h, float **fdata)
Definition: ecat7r.c:749
int ecat7ReadScanheader(FILE *fp, int blk, ECAT7_scanheader *h)
Definition: ecat7r.c:424
float ecat7rFloat(void *bufi, int isvax, int islittle)
Definition: ecat7r.c:1015
int ecat7ReadPolmapheader(FILE *fp, int blk, ECAT7_polmapheader *h)
Definition: ecat7r.c:325
int ecat7ReadMatrixdata(FILE *fp, int start_block, int block_nr, char *data, int dtype)
Definition: ecat7r.c:595
int ecat7ReadNormheader(FILE *fp, int blk, ECAT7_normheader *h)
Definition: ecat7r.c:378
int ecat7ReadAttenheader(FILE *fp, int blk, ECAT7_attenheader *h)
Definition: ecat7r.c:268
int ecat7rInt(void *bufi, int isvax, int islittle)
Definition: ecat7r.c:1038
int ecat7ReadMainheader(FILE *fp, ECAT7_mainheader *h)
Definition: ecat7r.c:78
int ecat7ReadPolarmapMatrix(FILE *fp, int first_block, int last_block, ECAT7_polmapheader *h, float **fdata)
Definition: ecat7r.c:939
int ecat7Read2DScanheader(FILE *fp, int blk, ECAT7_2Dscanheader *h)
Definition: ecat7r.c:485
int ecat7ReadImageMatrix(FILE *fp, int first_block, int last_block, ECAT7_imageheader *h, float **fdata)
Definition: ecat7r.c:656
int ecat7ReadImageheader(FILE *fp, int blk, ECAT7_imageheader *h)
Definition: ecat7r.c:177
int ecat7Read2DNormheader(FILE *fp, int blk, ECAT7_2Dnormheader *h)
Definition: ecat7r.c:546
int ecat7ReadScanMatrix(FILE *fp, int first_block, int last_block, ECAT7_scanheader *h, float **fdata)
Definition: ecat7r.c:844
short int fill_cti[123]
Definition: ecat7.h:474
short int storage_order
Definition: ecat7.h:471
short int fill_user[50]
Definition: ecat7.h:475
short int num_dimensions
Definition: ecat7.h:460
float norm_min
Definition: ecat7.h:466
float scale_factor
Definition: ecat7.h:465
float norm_quality_factor
Definition: ecat7.h:469
short int num_angles
Definition: ecat7.h:462
float fov_source_width
Definition: ecat7.h:468
short int num_z_elements
Definition: ecat7.h:463
short int span
Definition: ecat7.h:472
short int norm_quality_factor_code
Definition: ecat7.h:470
short int num_r_elements
Definition: ecat7.h:461
short int ring_difference
Definition: ecat7.h:464
float norm_max
Definition: ecat7.h:467
short int data_type
Definition: ecat7.h:459
short int fill_user[50]
Definition: ecat7.h:455
int num_accepted_beats
Definition: ecat7.h:437
int total_coin_rate
Definition: ecat7.h:449
short int physical_planes[8]
Definition: ecat7.h:453
float tot_avg_uncor
Definition: ecat7.h:448
short int fill_gate[6]
Definition: ecat7.h:434
short int num_dimensions
Definition: ecat7.h:424
short int num_z_elements
Definition: ecat7.h:428
short int ring_difference
Definition: ecat7.h:429
short int scan_min
Definition: ecat7.h:439
float x_resolution
Definition: ecat7.h:430
float deadtime_correction_factor
Definition: ecat7.h:452
int frame_start_time
Definition: ecat7.h:450
short int corrections_applied
Definition: ecat7.h:427
float w_resolution
Definition: ecat7.h:433
short int data_type
Definition: ecat7.h:423
float tot_avg_cor
Definition: ecat7.h:447
float y_resolution
Definition: ecat7.h:431
short int scan_max
Definition: ecat7.h:440
short int num_angles
Definition: ecat7.h:426
short int fill_cti[83]
Definition: ecat7.h:454
short int num_r_elements
Definition: ecat7.h:425
float uncor_singles[16]
Definition: ecat7.h:446
float scale_factor
Definition: ecat7.h:438
float z_resolution
Definition: ecat7.h:432
float cor_singles[16]
Definition: ecat7.h:445
int frame_duration
Definition: ecat7.h:451
short int data_type
Definition: ecat7.h:480
short int num_dimensions
Definition: ecat7.h:482
float edge_finding_threshold
Definition: ecat7.h:526
float z_resolution
Definition: ecat7.h:498
short int span
Definition: ecat7.h:530
short int attenuation_type
Definition: ecat7.h:484
short int num_angles
Definition: ecat7.h:488
float attenuation_min
Definition: ecat7.h:516
float scale_factor
Definition: ecat7.h:502
short int num_z_elements
Definition: ecat7.h:490
short int fill_cti[86]
Definition: ecat7.h:534
float y_radius
Definition: ecat7.h:510
float tilt_angle
Definition: ecat7.h:512
float w_resolution
Definition: ecat7.h:500
float y_resolution
Definition: ecat7.h:496
float x_radius
Definition: ecat7.h:508
short int ring_difference
Definition: ecat7.h:492
short int num_r_elements
Definition: ecat7.h:486
float additional_atten_coeff[8]
Definition: ecat7.h:524
short int fill_user[50]
Definition: ecat7.h:536
float attenuation_max
Definition: ecat7.h:518
short int num_additional_atten_coeff
Definition: ecat7.h:522
float attenuation_coeff
Definition: ecat7.h:514
float x_resolution
Definition: ecat7.h:494
float skull_thickness
Definition: ecat7.h:520
float x_offset
Definition: ecat7.h:504
short int storage_order
Definition: ecat7.h:528
short int z_elements[64]
Definition: ecat7.h:532
float y_offset
Definition: ecat7.h:506
float mt_2_2
Definition: ecat7.h:310
float num_angles
Definition: ecat7.h:274
short int recon_type
Definition: ecat7.h:344
short int image_max
Definition: ecat7.h:252
short int filter_order
Definition: ecat7.h:294
float mt_1_2
Definition: ecat7.h:304
short int y_dimension
Definition: ecat7.h:236
float filter_scatter_slope
Definition: ecat7.h:298
short int scatter_type
Definition: ecat7.h:342
float scale_factor
Definition: ecat7.h:248
short int rfilter_code
Definition: ecat7.h:324
float x_offset
Definition: ecat7.h:240
short int x_dimension
Definition: ecat7.h:234
float x_pixel_size
Definition: ecat7.h:254
float mt_3_2
Definition: ecat7.h:316
float z_pixel_size
Definition: ecat7.h:258
float zfilter_cutoff
Definition: ecat7.h:328
float mt_1_1
Definition: ecat7.h:302
int gate_duration
Definition: ecat7.h:282
int frame_start_time
Definition: ecat7.h:262
int processing_code
Definition: ecat7.h:280
short int fill_cti[87]
Definition: ecat7.h:348
float recon_zoom
Definition: ecat7.h:246
float decay_corr_fctr
Definition: ecat7.h:278
short int z_dimension
Definition: ecat7.h:238
short int rfilter_order
Definition: ecat7.h:326
float num_r_elements
Definition: ecat7.h:272
float y_resolution
Definition: ecat7.h:268
short int zfilter_order
Definition: ecat7.h:334
float filter_resolution
Definition: ecat7.h:290
float mt_3_1
Definition: ecat7.h:314
float x_resolution
Definition: ecat7.h:266
int num_accepted_beats
Definition: ecat7.h:286
float mt_2_1
Definition: ecat7.h:308
short int data_type
Definition: ecat7.h:230
float mt_2_3
Definition: ecat7.h:312
float z_resolution
Definition: ecat7.h:270
float filter_ramp_slope
Definition: ecat7.h:292
float zfilter_resolution
Definition: ecat7.h:330
float z_offset
Definition: ecat7.h:244
float rfilter_resolution
Definition: ecat7.h:322
float mt_1_3
Definition: ecat7.h:306
short int fill_user[49]
Definition: ecat7.h:350
float filter_scatter_fraction
Definition: ecat7.h:296
float z_rotation_angle
Definition: ecat7.h:276
short int num_dimensions
Definition: ecat7.h:232
short int image_min
Definition: ecat7.h:250
short int filter_code
Definition: ecat7.h:264
char annotation[40]
Definition: ecat7.h:300
float y_offset
Definition: ecat7.h:242
float mt_2_4
Definition: ecat7.h:338
float mt_3_4
Definition: ecat7.h:340
short int recon_views
Definition: ecat7.h:346
float mt_1_4
Definition: ecat7.h:336
int frame_duration
Definition: ecat7.h:260
short int zfilter_code
Definition: ecat7.h:332
float y_pixel_size
Definition: ecat7.h:256
float rfilter_cutoff
Definition: ecat7.h:320
int r_wave_offset
Definition: ecat7.h:284
float mt_3_3
Definition: ecat7.h:318
float filter_cutoff_frequency
Definition: ecat7.h:288
float dosage
Definition: ecat7.h:217
char serial_number[10]
Definition: ecat7.h:115
char patient_name[32]
Definition: ecat7.h:158
char study_description[32]
Definition: ecat7.h:178
float well_counter_corr_factor
Definition: ecat7.h:219
short int compression_code
Definition: ecat7.h:152
char physician_name[32]
Definition: ecat7.h:174
short int patient_orientation
Definition: ecat7.h:183
short int file_type
Definition: ecat7.h:113
char isotope_name[8]
Definition: ecat7.h:119
int scan_start_time
Definition: ecat7.h:117
float distance_scanned
Definition: ecat7.h:137
char original_file_name[32]
Definition: ecat7.h:107
char facility_name[20]
Definition: ecat7.h:185
char patient_id[16]
Definition: ecat7.h:156
float transaxial_fov
Definition: ecat7.h:139
short int sw_version
Definition: ecat7.h:109
short int num_gates
Definition: ecat7.h:191
short int upr_true_thres
Definition: ecat7.h:205
short int angular_compression
Definition: ecat7.h:141
short int calibration_units
Definition: ecat7.h:148
short int fill_cti[6]
Definition: ecat7.h:225
float patient_weight
Definition: ecat7.h:168
float gantry_tilt
Definition: ecat7.h:125
short int transm_source_type
Definition: ecat7.h:135
short int wobble_speed
Definition: ecat7.h:133
char magic_number[14]
Definition: ecat7.h:105
float plane_separation
Definition: ecat7.h:199
int dose_start_time
Definition: ecat7.h:215
short int num_frames
Definition: ecat7.h:189
float gantry_rotation
Definition: ecat7.h:127
float init_bed_position
Definition: ecat7.h:195
short int coin_samp_mode
Definition: ecat7.h:143
short int acquisition_type
Definition: ecat7.h:181
float bed_elevation
Definition: ecat7.h:129
float isotope_halflife
Definition: ecat7.h:121
char user_process_code[10]
Definition: ecat7.h:207
short int axial_samp_mode
Definition: ecat7.h:145
char operator_name[32]
Definition: ecat7.h:176
short int calibration_units_label
Definition: ecat7.h:150
char data_units[32]
Definition: ecat7.h:221
short int num_planes
Definition: ecat7.h:187
short int acquisition_mode
Definition: ecat7.h:209
float patient_height
Definition: ecat7.h:166
char radiopharmaceutical[32]
Definition: ecat7.h:123
int patient_birth_date
Definition: ecat7.h:172
short int septa_state
Definition: ecat7.h:223
float bin_size
Definition: ecat7.h:211
float intrinsic_tilt
Definition: ecat7.h:131
float branching_fraction
Definition: ecat7.h:213
char patient_dexterity
Definition: ecat7.h:162
short int num_bed_pos
Definition: ecat7.h:193
float patient_age
Definition: ecat7.h:164
float ecat_calibration_factor
Definition: ecat7.h:146
short int lwr_true_thres
Definition: ecat7.h:203
short int lwr_sctr_thres
Definition: ecat7.h:201
short int system_type
Definition: ecat7.h:111
char patient_sex
Definition: ecat7.h:160
char study_type[12]
Definition: ecat7.h:154
float bed_position[15]
Definition: ecat7.h:197
short int num_crystal_rings
Definition: ecat7.h:546
short int lld
Definition: ecat7.h:553
float norm_quality_factor
Definition: ecat7.h:557
short int norm_quality_factor_code
Definition: ecat7.h:559
short int scatter_energy
Definition: ecat7.h:555
short int num_geo_corr_planes
Definition: ecat7.h:549
short int max_ring_diff
Definition: ecat7.h:569
short int span
Definition: ecat7.h:567
float ring_dtcor1[32]
Definition: ecat7.h:561
short int num_transaxial_crystals
Definition: ecat7.h:544
short int uld
Definition: ecat7.h:551
short int crystals_per_ring
Definition: ecat7.h:547
short int fill_user[50]
Definition: ecat7.h:573
float ring_dtcor2[32]
Definition: ecat7.h:563
float crystal_dtcor[8]
Definition: ecat7.h:565
short int fill_cti[48]
Definition: ecat7.h:571
short int num_r_elements
Definition: ecat7.h:542
short int data_type
Definition: ecat7.h:540
short int fill_cti[27]
Definition: ecat7.h:601
short int processing_code
Definition: ecat7.h:593
short int polar_map_type
Definition: ecat7.h:578
float ring_position[32]
Definition: ecat7.h:581
short int image_max
Definition: ecat7.h:588
float pixel_size
Definition: ecat7.h:590
short int num_rings
Definition: ecat7.h:579
char database_name[30]
Definition: ecat7.h:600
short int sectors_per_ring[32]
Definition: ecat7.h:580
short int data_type
Definition: ecat7.h:577
char annotation[40]
Definition: ecat7.h:595
short int quant_units
Definition: ecat7.h:594
short int long_axis_left[3]
Definition: ecat7.h:584
int num_accepted_beats
Definition: ecat7.h:598
char polar_map_protocol[20]
Definition: ecat7.h:599
int frame_start_time
Definition: ecat7.h:592
short int image_min
Definition: ecat7.h:587
float scale_factor
Definition: ecat7.h:589
short int start_angle
Definition: ecat7.h:583
int frame_duration
Definition: ecat7.h:591
short int position_data
Definition: ecat7.h:586
short int ring_angle[32]
Definition: ecat7.h:582
short int long_axis_right[3]
Definition: ecat7.h:585
short int corrections_applied
Definition: ecat7.h:363
float z_resolution
Definition: ecat7.h:377
float uncor_singles[128]
Definition: ecat7.h:419
float w_resolution
Definition: ecat7.h:379
float v_resolution
Definition: ecat7.h:375
float x_resolution
Definition: ecat7.h:373
short int fill_cti[90]
Definition: ecat7.h:415
short int num_dimensions
Definition: ecat7.h:357
short int num_angles
Definition: ecat7.h:361
int gate_duration
Definition: ecat7.h:383
short int scan_max
Definition: ecat7.h:393
short int num_z_elements[64]
Definition: ecat7.h:365
int frame_start_time
Definition: ecat7.h:409
float scale_factor
Definition: ecat7.h:389
float tot_avg_uncor
Definition: ecat7.h:405
short int fill_user[50]
Definition: ecat7.h:417
float deadtime_correction_factor
Definition: ecat7.h:413
float tot_avg_cor
Definition: ecat7.h:403
short int data_type
Definition: ecat7.h:355
short int axial_compression
Definition: ecat7.h:371
short int fill_gate[6]
Definition: ecat7.h:381
short int ring_difference
Definition: ecat7.h:367
int r_wave_offset
Definition: ecat7.h:385
int frame_duration
Definition: ecat7.h:411
int num_accepted_beats
Definition: ecat7.h:387
short int scan_min
Definition: ecat7.h:391
short int num_r_elements
Definition: ecat7.h:359
short int storage_order
Definition: ecat7.h:369
int total_coin_rate
Definition: ecat7.h:407