ecat7r.c
Go to the documentation of this file.
00001 /******************************************************************************
00002 
00003   Copyright (c) 2003-2010 Turku PET Centre
00004 
00005   Library file: ecat7r.c
00006   Description:  Functions for reading ECAT 7.x format.
00007 
00008   This library is free software; you can redistribute it and/or
00009   modify it under the terms of the GNU Lesser General Public
00010   License as published by the Free Software Foundation; either
00011   version 2.1 of the License, or (at your option) any later version.
00012 
00013   This library is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016   See the GNU Lesser General Public License for more details:
00017   http://www.gnu.org/copyleft/lesser.html
00018 
00019   You should have received a copy of the GNU Lesser General Public License
00020   along with this library/program; if not, write to the Free Software
00021   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
00022 
00023   Turku PET Centre, Turku, Finland, http://www.turkupetcentre.fi
00024   
00025   Modification history:
00026   2003-07-24 Vesa Oikonen
00027     First created.
00028   2003-09-08 VO
00029     Added support for 3D sinograms, ecat7ReadScanMatrix().
00030   2004-05-23 VO
00031     Comments changed into Doxygen format.
00032   2004-06-21 VO
00033     ecat7ReadScanMatrix():
00034     Before: reads datablocks based on matrix list.
00035     After: if block number based on bin nr is smaller, then read only those
00036     Reason: simulated file with erroneous matrix list.
00037   2004-09-20 VO
00038     Doxygen style comments are corrected.
00039   2004-11-10 VO
00040     Calculation of trueblockNr simplified in ecat7ReadScanMatrix().
00041   2006-02-07 Jarkko Johansson
00042     Comments added in ecat7ReadScanMatrix().
00043   2007-03-21 VO  
00044     ecat7ReadImageheader(): fill_cti[] and fill_user[] are read correctly.
00045   2007-03-27 VO
00046     Added ecat7ReadPolarmapMatrix().
00047   2010-08-19 VO
00048     Main header field patient_birth_date can be in two different int formats,
00049     either YYYYMMDD or as seconds from start of year 1970. In latter case
00050     the number can be negative, which is not identified correctly by all C
00051     library versions. Therefore those are converted to YYYYMMDD format.
00052 
00053 
00054 ******************************************************************************/
00055 #include <locale.h>
00056 #include <stdio.h>
00057 #include <stdlib.h>
00058 #include <math.h>
00059 #include <ctype.h>
00060 #include <string.h>
00061 #include <unistd.h>
00062 #include <time.h>
00063 /*****************************************************************************/
00064 #include <swap.h>
00065 #include <datetime.h>
00066 #include "include/ecat7.h"
00067 /*****************************************************************************/
00068 
00069 /*****************************************************************************/
00078 int ecat7ReadMainheader(FILE *fp, ECAT7_mainheader *h) {
00079   unsigned char buf[MatBLKSIZE];
00080   int little; /* 1 if current platform is little endian (i386), else 0 */
00081   struct tm st;
00082 
00083   if(ECAT7_TEST) printf("ecat7ReadMainheader()\n");
00084   if(fp==NULL || h==NULL) return(1);
00085   little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
00086 
00087   /* Seek the first block */
00088   fseek(fp, 0, SEEK_SET); if(ftell(fp)!=0) return(2); 
00089   /* Read the header block */
00090   if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
00091   
00092   /* Copy the header fields and swap if necessary */
00093   memcpy(&h->magic_number, buf+0, 14);
00094   memcpy(&h->original_file_name, buf+14, 32);
00095   if(little) swabip(buf+46, 2); memcpy(&h->sw_version, buf+46, 2);
00096   if(little) swabip(buf+48, 2); memcpy(&h->system_type, buf+48, 2);
00097   if(little) swabip(buf+50, 2); memcpy(&h->file_type, buf+50, 2);
00098   memcpy(&h->serial_number, buf+52, 10);
00099   if(little) swawbip(buf+62, 4); memcpy(&h->scan_start_time, buf+62, 4);
00100   memcpy(&h->isotope_name, buf+66, 8);
00101   if(little) swawbip(buf+74, 4); memcpy(&h->isotope_halflife, buf+74, 4);
00102   memcpy(&h->radiopharmaceutical, buf+78, 32);
00103   if(little) swawbip(buf+110, 4); memcpy(&h->gantry_tilt, buf+110, 4);
00104   if(little) swawbip(buf+114, 4); memcpy(&h->gantry_rotation, buf+114, 4);
00105   if(little) swawbip(buf+118, 4); memcpy(&h->bed_elevation, buf+118, 4);
00106   if(little) swawbip(buf+122, 4); memcpy(&h->intrinsic_tilt, buf+122, 4);
00107   if(little) swabip(buf+126, 2); memcpy(&h->wobble_speed, buf+126, 2);
00108   if(little) swabip(buf+128, 2); memcpy(&h->transm_source_type, buf+128, 2);
00109   if(little) swawbip(buf+130, 4); memcpy(&h->distance_scanned, buf+130, 4);
00110   if(little) swawbip(buf+134, 4); memcpy(&h->transaxial_fov, buf+134, 4);
00111   if(little) swabip(buf+138, 2); memcpy(&h->angular_compression, buf+138, 2);
00112   if(little) swabip(buf+140, 2); memcpy(&h->coin_samp_mode, buf+140, 2);
00113   if(little) swabip(buf+142, 2); memcpy(&h->axial_samp_mode, buf+142, 2);
00114   if(little) swawbip(buf+144, 4); memcpy(&h->ecat_calibration_factor, buf+144, 4);
00115   if(little) swabip(buf+148, 2); memcpy(&h->calibration_units, buf+148, 2);
00116   if(little) swabip(buf+150, 2); memcpy(&h->calibration_units_label, buf+150, 2);
00117   if(little) swabip(buf+152, 2); memcpy(&h->compression_code, buf+152, 2);
00118   memcpy(&h->study_type, buf+154, 12);
00119   memcpy(&h->patient_id, buf+166, 16);
00120   memcpy(&h->patient_name, buf+182, 32);
00121   memcpy(&h->patient_sex, buf+214, 1);
00122   memcpy(&h->patient_dexterity, buf+215, 1);
00123   if(little) swawbip(buf+216, 4); memcpy(&h->patient_age, buf+216, 4);
00124   if(little) swawbip(buf+220, 4); memcpy(&h->patient_height, buf+220, 4);
00125   if(little) swawbip(buf+224, 4); memcpy(&h->patient_weight, buf+224, 4);
00126   if(little) swawbip(buf+228, 4); memcpy(&h->patient_birth_date, buf+228, 4);
00127   memcpy(&h->physician_name, buf+232, 32);
00128   memcpy(&h->operator_name, buf+264, 32);
00129   memcpy(&h->study_description, buf+296, 32);
00130   if(little) swabip(buf+328, 2); memcpy(&h->acquisition_type, buf+328, 2);
00131   if(little) swabip(buf+330, 2); memcpy(&h->patient_orientation, buf+330, 2);
00132   memcpy(&h->facility_name, buf+332, 20);
00133   if(little) swabip(buf+352, 2); memcpy(&h->num_planes, buf+352, 2);
00134   if(little) swabip(buf+354, 2); memcpy(&h->num_frames, buf+354, 2);
00135   if(little) swabip(buf+356, 2); memcpy(&h->num_gates, buf+356, 2);
00136   if(little) swabip(buf+358, 2); memcpy(&h->num_bed_pos, buf+358, 2);
00137   if(little) swawbip(buf+360, 4); memcpy(&h->init_bed_position, buf+360, 4);
00138   if(little) swawbip(buf+364, 15*4); memcpy(h->bed_position, buf+364, 15*4);
00139   if(little) swawbip(buf+424, 4); memcpy(&h->plane_separation, buf+424, 4);
00140   if(little) swabip(buf+428, 2); memcpy(&h->lwr_sctr_thres, buf+428, 2);
00141   if(little) swabip(buf+430, 2); memcpy(&h->lwr_true_thres, buf+430, 2);
00142   memcpy(&h->upr_true_thres, buf+432, 2); if(little) swabip(&h->upr_true_thres, 2);
00143   memcpy(&h->user_process_code, buf+434, 10);
00144   if(little) swabip(buf+444, 2); memcpy(&h->acquisition_mode, buf+444, 2);
00145   if(little) swawbip(buf+446, 4); memcpy(&h->bin_size, buf+446, 4);
00146   if(little) swawbip(buf+450, 4); memcpy(&h->branching_fraction, buf+450, 4);
00147   if(little) swawbip(buf+454, 4); memcpy(&h->dose_start_time, buf+454, 4);
00148   if(little) swawbip(buf+458, 4); memcpy(&h->dosage, buf+458, 4);
00149   if(little) swawbip(buf+462, 4); memcpy(&h->well_counter_corr_factor, buf+462, 4);
00150   memcpy(&h->data_units, buf+466, 32);
00151   if(little) swabip(buf+498, 2); memcpy(&h->septa_state, buf+498, 2);
00152   memcpy(&h->fill_cti, buf+500, 12);
00153 
00154   /* Patient birth date can have been saved in two different int formats,
00155      either YYYYMMDD or as seconds from start of year 1970. In latter case
00156      the number can be negative. */
00157   /* Seconds from start of year 1970 are converted to YYYYMMDD format */
00158   if(isdate4(h->patient_birth_date, NULL, NULL, NULL)!=0) {
00159     time_to_tm((time_t)h->patient_birth_date, 12*3600-timezone, &st);
00160     h->patient_birth_date=10000*(st.tm_year+1900)+100*(st.tm_mon+1)+st.tm_mday;
00161   }
00162 
00163   return(0);
00164 }
00165 /*****************************************************************************/
00166 
00167 /*****************************************************************************/
00177 int ecat7ReadImageheader(FILE *fp, int blk, ECAT7_imageheader *h) {
00178   unsigned char buf[MatBLKSIZE];
00179   int little; /* 1 if current platform is little endian (i386), else 0 */
00180 
00181   if(ECAT7_TEST) printf("ecat7ReadImageheader()\n");
00182   if(fp==NULL || h==NULL) return(1);
00183   little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
00184 
00185   /* Seek the subheader block */
00186   fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
00187   if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
00188   /* Read the header block */
00189   if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
00190 
00191   /* Copy the header fields and swap if necessary */
00192   if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
00193   if(little) swabip(buf+2, 2); memcpy(&h->num_dimensions, buf+2, 2);
00194   if(little) swabip(buf+4, 2); memcpy(&h->x_dimension, buf+4, 2);
00195   if(little) swabip(buf+6, 2); memcpy(&h->y_dimension, buf+6, 2);
00196   if(little) swabip(buf+8, 2); memcpy(&h->z_dimension, buf+8, 2);
00197   if(little) swawbip(buf+10, 4); memcpy(&h->x_offset, buf+10, 4);
00198   if(little) swawbip(buf+14, 4); memcpy(&h->y_offset, buf+14, 4);
00199   if(little) swawbip(buf+18, 4); memcpy(&h->z_offset, buf+18, 4);
00200   if(little) swawbip(buf+22, 4); memcpy(&h->recon_zoom, buf+22, 4);
00201   if(little) swawbip(buf+26, 4); memcpy(&h->scale_factor, buf+26, 4);
00202   if(little) swabip(buf+30, 2); memcpy(&h->image_min, buf+30, 2);
00203   if(little) swabip(buf+32, 2); memcpy(&h->image_max, buf+32, 2);
00204   if(little) swawbip(buf+34, 4); memcpy(&h->x_pixel_size, buf+34, 4);
00205   if(little) swawbip(buf+38, 4); memcpy(&h->y_pixel_size, buf+38, 4);
00206   if(little) swawbip(buf+42, 4); memcpy(&h->z_pixel_size, buf+42, 4);
00207   if(little) swawbip(buf+46, 4); memcpy(&h->frame_duration, buf+46, 4);
00208   if(little) swawbip(buf+50, 4); memcpy(&h->frame_start_time, buf+50, 4);
00209   if(little) swabip(buf+54, 2); memcpy(&h->filter_code, buf+54, 2);
00210   if(little) swawbip(buf+56, 4); memcpy(&h->x_resolution, buf+56, 4);
00211   if(little) swawbip(buf+60, 4); memcpy(&h->y_resolution, buf+60, 4);
00212   if(little) swawbip(buf+64, 4); memcpy(&h->z_resolution, buf+64, 4);
00213   if(little) swawbip(buf+68, 4); memcpy(&h->num_r_elements, buf+68, 4);
00214   if(little) swawbip(buf+72, 4); memcpy(&h->num_angles, buf+72, 4);
00215   if(little) swawbip(buf+76, 4); memcpy(&h->z_rotation_angle, buf+76, 4);
00216   if(little) swawbip(buf+80, 4); memcpy(&h->decay_corr_fctr, buf+80, 4);
00217   if(little) swawbip(buf+84, 4); memcpy(&h->processing_code, buf+84, 4);
00218   if(little) swawbip(buf+88, 4); memcpy(&h->gate_duration, buf+88, 4);
00219   if(little) swawbip(buf+92, 4); memcpy(&h->r_wave_offset, buf+92, 4);
00220   if(little) swawbip(buf+96, 4); memcpy(&h->num_accepted_beats, buf+96, 4);
00221   if(little) swawbip(buf+100, 4); memcpy(&h->filter_cutoff_frequency, buf+100, 4);
00222   if(little) swawbip(buf+104, 4); memcpy(&h->filter_resolution, buf+104, 4);
00223   if(little) swawbip(buf+108, 4); memcpy(&h->filter_ramp_slope, buf+108, 4);
00224   if(little) swabip(buf+112, 2); memcpy(&h->filter_order, buf+112, 2);
00225   if(little) swawbip(buf+114, 4); memcpy(&h->filter_scatter_fraction, buf+114, 4);
00226   if(little) swawbip(buf+118, 4); memcpy(&h->filter_scatter_slope, buf+118, 4);
00227   memcpy(&h->annotation, buf+122, 40);
00228   if(little) swawbip(buf+162, 4); memcpy(&h->mt_1_1, buf+162, 4);
00229   if(little) swawbip(buf+166, 4); memcpy(&h->mt_1_2, buf+166, 4);
00230   if(little) swawbip(buf+170, 4); memcpy(&h->mt_1_3, buf+170, 4);
00231   if(little) swawbip(buf+174, 4); memcpy(&h->mt_2_1, buf+174, 4);
00232   if(little) swawbip(buf+178, 4); memcpy(&h->mt_2_2, buf+178, 4);
00233   if(little) swawbip(buf+182, 4); memcpy(&h->mt_2_3, buf+182, 4);
00234   if(little) swawbip(buf+186, 4); memcpy(&h->mt_3_1, buf+186, 4);
00235   if(little) swawbip(buf+190, 4); memcpy(&h->mt_3_2, buf+190, 4);
00236   if(little) swawbip(buf+194, 4); memcpy(&h->mt_3_3, buf+194, 4);
00237   if(little) swawbip(buf+198, 4); memcpy(&h->rfilter_cutoff, buf+198, 4);
00238   if(little) swawbip(buf+202, 4); memcpy(&h->rfilter_resolution, buf+202, 4);
00239   if(little) swabip(buf+206, 2); memcpy(&h->rfilter_code, buf+206, 2);
00240   if(little) swabip(buf+208, 2); memcpy(&h->rfilter_order, buf+208, 2);
00241   if(little) swawbip(buf+210, 4); memcpy(&h->zfilter_cutoff, buf+210, 4);
00242   if(little) swawbip(buf+214, 4); memcpy(&h->zfilter_resolution, buf+214, 4);
00243   if(little) swabip(buf+218, 2); memcpy(&h->zfilter_code, buf+218, 2);
00244   if(little) swabip(buf+220, 2); memcpy(&h->zfilter_order, buf+220, 2);
00245   if(little) swawbip(buf+222, 4); memcpy(&h->mt_1_4, buf+222, 4);
00246   if(little) swawbip(buf+226, 4); memcpy(&h->mt_2_4, buf+226, 4);
00247   if(little) swawbip(buf+230, 4); memcpy(&h->mt_3_4, buf+230, 4);
00248   if(little) swabip(buf+234, 2); memcpy(&h->scatter_type, buf+234, 2);
00249   if(little) swabip(buf+236, 2); memcpy(&h->recon_type, buf+236, 2);
00250   if(little) swabip(buf+238, 2); memcpy(&h->recon_views, buf+238, 2);
00251   memcpy(&h->fill_cti, buf+240, 174);
00252   memcpy(&h->fill_user, buf+414, 96);
00253 
00254   return(0);
00255 }
00256 /*****************************************************************************/
00257 
00258 /*****************************************************************************/
00268 int ecat7ReadAttenheader(FILE *fp, int blk, ECAT7_attenheader *h) {
00269   unsigned char buf[MatBLKSIZE];
00270   int little; /* 1 if current platform is little endian (i386), else 0 */
00271 
00272   if(ECAT7_TEST) printf("ecat7ReadAttenheader()\n");
00273   if(fp==NULL || h==NULL) return(1);
00274   little=little_endian();
00275 
00276   /* Seek the subheader block */
00277   fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
00278   if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
00279   /* Read the header block */
00280   if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
00281   /* Copy the header fields and swap if necessary */
00282   if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
00283   if(little) swabip(buf+2, 2); memcpy(&h->num_dimensions, buf+2, 2);
00284   if(little) swabip(buf+4, 2); memcpy(&h->attenuation_type, buf+4, 2);
00285   if(little) swabip(buf+6, 2); memcpy(&h->num_r_elements, buf+6, 2);
00286   if(little) swabip(buf+8, 2); memcpy(&h->num_angles, buf+8, 2);
00287   if(little) swabip(buf+10, 2); memcpy(&h->num_z_elements, buf+10, 2);
00288   if(little) swabip(buf+12, 2); memcpy(&h->ring_difference, buf+12, 2);
00289   if(little) swawbip(buf+14, 4); memcpy(&h->x_resolution, buf+14, 4);
00290   if(little) swawbip(buf+18, 4); memcpy(&h->y_resolution, buf+18, 4);
00291   if(little) swawbip(buf+22, 4); memcpy(&h->z_resolution, buf+22, 4);
00292   if(little) swawbip(buf+26, 4); memcpy(&h->w_resolution, buf+26, 4);
00293   if(little) swawbip(buf+30, 4); memcpy(&h->scale_factor, buf+30, 4);
00294   if(little) swawbip(buf+34, 4); memcpy(&h->x_offset, buf+34, 4);
00295   if(little) swawbip(buf+38, 4); memcpy(&h->y_offset, buf+38, 4);
00296   if(little) swawbip(buf+42, 4); memcpy(&h->x_radius, buf+42, 4);
00297   if(little) swawbip(buf+46, 4); memcpy(&h->y_radius, buf+46, 4);
00298   if(little) swawbip(buf+50, 4); memcpy(&h->tilt_angle, buf+50, 4);
00299   if(little) swawbip(buf+54, 4); memcpy(&h->attenuation_coeff, buf+54, 4);
00300   if(little) swawbip(buf+58, 4); memcpy(&h->attenuation_min, buf+58, 4);
00301   if(little) swawbip(buf+62, 4); memcpy(&h->attenuation_max, buf+62, 4);
00302   if(little) swawbip(buf+66, 4); memcpy(&h->skull_thickness, buf+66, 4);
00303   if(little) swabip(buf+70, 2); memcpy(&h->num_additional_atten_coeff, buf+70, 2);
00304   if(little) swawbip(buf+72, 8*4); memcpy(h->additional_atten_coeff, buf+72, 8*4);
00305   if(little) swawbip(buf+104, 4); memcpy(&h->edge_finding_threshold, buf+104, 4);
00306   if(little) swabip(buf+108, 2); memcpy(&h->storage_order, buf+108, 2);
00307   if(little) swabip(buf+110, 2); memcpy(&h->span, buf+110, 2);
00308   if(little) swabip(buf+112, 64*2); memcpy(h->z_elements, buf+112, 64*2);
00309   if(little) swabip(buf+240, 86*2); memcpy(h->fill_cti, buf+240, 86*2);
00310   if(little) swabip(buf+412, 50*2); memcpy(h->fill_user, buf+412, 50*2);
00311   return(0);
00312 }
00313 /*****************************************************************************/
00314 
00315 /*****************************************************************************/
00325 int ecat7ReadPolmapheader(FILE *fp, int blk, ECAT7_polmapheader *h) {
00326   unsigned char buf[MatBLKSIZE];
00327   int little; /* 1 if current platform is little endian (i386), else 0 */
00328 
00329   if(ECAT7_TEST) printf("ecat7ReadPolarmapheader()\n");
00330   if(fp==NULL || h==NULL) return(1);
00331   little=little_endian();
00332 
00333   /* Seek the subheader block */
00334   fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
00335   if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
00336   /* Read the header block */
00337   if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
00338   /* Copy the header fields and swap if necessary */
00339   if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
00340   if(little) swabip(buf+2, 2); memcpy(&h->polar_map_type, buf+2, 2);
00341   if(little) swabip(buf+4, 2); memcpy(&h->num_rings, buf+4, 2);
00342   if(little) swabip(buf+6, 32*2); memcpy(h->sectors_per_ring, buf+6, 32*2);
00343   if(little) swawbip(buf+70, 32*4); memcpy(h->ring_position, buf+70, 32*4);
00344   if(little) swabip(buf+198, 32*2); memcpy(h->ring_angle, buf+198, 32*2);
00345   if(little) swabip(buf+262, 2); memcpy(&h->start_angle, buf+262, 2);
00346   if(little) swabip(buf+264, 3*2); memcpy(h->long_axis_left, buf+264, 3*2);
00347   if(little) swabip(buf+270, 3*2); memcpy(h->long_axis_right, buf+270, 3*2);
00348   if(little) swabip(buf+276, 2); memcpy(&h->position_data, buf+276, 2);
00349   if(little) swabip(buf+278, 2); memcpy(&h->image_min, buf+278, 2);
00350   if(little) swabip(buf+280, 2); memcpy(&h->image_max, buf+280, 2);
00351   if(little) swawbip(buf+282, 4); memcpy(&h->scale_factor, buf+282, 4);
00352   if(little) swawbip(buf+286, 4); memcpy(&h->pixel_size, buf+286, 4);
00353   if(little) swawbip(buf+290, 4); memcpy(&h->frame_duration, buf+290, 4);
00354   if(little) swawbip(buf+294, 4); memcpy(&h->frame_start_time, buf+294, 4);
00355   if(little) swabip(buf+298, 2); memcpy(&h->processing_code, buf+298, 2);
00356   if(little) swabip(buf+300, 2); memcpy(&h->quant_units, buf+300, 2);
00357   memcpy(h->annotation, buf+302, 40);
00358   if(little) swawbip(buf+342, 4); memcpy(&h->gate_duration, buf+342, 4);
00359   if(little) swawbip(buf+346, 4); memcpy(&h->r_wave_offset, buf+346, 4);
00360   if(little) swawbip(buf+350, 4); memcpy(&h->num_accepted_beats, buf+350, 4);
00361   memcpy(h->polar_map_protocol, buf+354, 20);
00362   memcpy(h->database_name, buf+374, 30);
00363   if(little) swabip(buf+404, 27*2); memcpy(h->fill_cti, buf+404, 27*2);
00364   return(0);
00365 }
00366 /*****************************************************************************/
00367 
00368 /*****************************************************************************/
00378 int ecat7ReadNormheader(FILE *fp, int blk, ECAT7_normheader *h) {
00379   unsigned char buf[MatBLKSIZE];
00380   int little; /* 1 if current platform is little endian (i386), else 0 */
00381 
00382   if(ECAT7_TEST) printf("ecat7ReadNormheader()\n");
00383   if(fp==NULL || h==NULL) return(1);
00384   little=little_endian();
00385 
00386   /* Seek the subheader block */
00387   fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
00388   if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2); 
00389   /* Read the header block */
00390   if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
00391   /* Copy the header fields and swap if necessary */
00392   if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
00393   if(little) swabip(buf+2, 2); memcpy(&h->num_r_elements, buf+2, 2);
00394   if(little) swabip(buf+4, 2); memcpy(&h->num_transaxial_crystals, buf+4, 2);
00395   if(little) swabip(buf+6, 2); memcpy(&h->num_crystal_rings, buf+6, 2);
00396   if(little) swabip(buf+8, 2); memcpy(&h->crystals_per_ring, buf+8, 2);
00397   if(little) swabip(buf+10, 2); memcpy(&h->num_geo_corr_planes, buf+10, 2);
00398   if(little) swabip(buf+12, 2); memcpy(&h->uld, buf+12, 2);
00399   if(little) swabip(buf+14, 2); memcpy(&h->lld, buf+14, 2);
00400   if(little) swabip(buf+16, 2); memcpy(&h->scatter_energy, buf+16, 2);
00401   if(little) swawbip(buf+18, 4); memcpy(&h->norm_quality_factor, buf+18, 4);
00402   if(little) swabip(buf+22, 2); memcpy(&h->norm_quality_factor_code, buf+22, 2);
00403   if(little) swawbip(buf+24, 32*4); memcpy(h->ring_dtcor1, buf+24, 32*4);
00404   if(little) swawbip(buf+152, 32*4); memcpy(h->ring_dtcor2, buf+152, 32*4);
00405   if(little) swawbip(buf+280, 8*4); memcpy(h->crystal_dtcor, buf+280, 8*4);
00406   if(little) swabip(buf+312, 2); memcpy(&h->span, buf+312, 2);
00407   if(little) swabip(buf+314, 2); memcpy(&h->max_ring_diff, buf+314, 2);
00408   if(little) swabip(buf+316, 48*2); memcpy(h->fill_cti, buf+316, 48*2);
00409   if(little) swabip(buf+412, 50*2); memcpy(h->fill_user, buf+412, 50*2);
00410   return(0);
00411 }
00412 /*****************************************************************************/
00413 
00414 /*****************************************************************************/
00424 int ecat7ReadScanheader(FILE *fp, int blk, ECAT7_scanheader *h) {
00425   unsigned char buf[2*MatBLKSIZE];
00426   int little; /* 1 if current platform is little endian (i386), else 0 */
00427 
00428   if(ECAT7_TEST) printf("ecat7ReadScanheader()\n");
00429   if(fp==NULL || h==NULL) return(1);
00430   little=little_endian(); if(ECAT7_TEST) printf("little=%d\n", little);
00431 
00432   /* Seek the subheader block */
00433   fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET); if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
00434   /* Read the header block */
00435   if(fread(buf, MatBLKSIZE, 2, fp)<1) return(3);
00436 
00437   /* Copy the header fields and swap if necessary */
00438   if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
00439   if(little) swabip(buf+2, 2); memcpy(&h->num_dimensions, buf+2, 2);
00440   if(little) swabip(buf+4, 2); memcpy(&h->num_r_elements, buf+4, 2);
00441   if(little) swabip(buf+6, 2); memcpy(&h->num_angles, buf+6, 2);
00442   if(little) swabip(buf+8, 2); memcpy(&h->corrections_applied, buf+8, 2);
00443   if(little) swabip(buf+10, 64*2); memcpy(h->num_z_elements, buf+10, 64*2);
00444   if(little) swabip(buf+138, 2); memcpy(&h->ring_difference, buf+138, 2);
00445   if(little) swabip(buf+140, 2); memcpy(&h->storage_order, buf+140, 2);
00446   if(little) swabip(buf+142, 2); memcpy(&h->axial_compression, buf+142, 2);
00447   if(little) swawbip(buf+144, 4); memcpy(&h->x_resolution, buf+144, 4);
00448   if(little) swawbip(buf+148, 4); memcpy(&h->v_resolution, buf+148, 4);
00449   if(little) swawbip(buf+152, 4); memcpy(&h->z_resolution, buf+152, 4);
00450   if(little) swawbip(buf+156, 4); memcpy(&h->w_resolution, buf+156, 4);
00451   if(little) swabip(buf+160, 6*2); memcpy(h->fill_gate, buf+160, 6*2);
00452   if(little) swawbip(buf+172, 4); memcpy(&h->gate_duration, buf+172, 4);
00453   if(little) swawbip(buf+176, 4); memcpy(&h->r_wave_offset, buf+176, 4);
00454   if(little) swawbip(buf+180, 4); memcpy(&h->num_accepted_beats, buf+180, 4);
00455   if(little) swawbip(buf+184, 4); memcpy(&h->scale_factor, buf+184, 4);
00456   if(little) swabip(buf+188, 2); memcpy(&h->scan_min, buf+188, 2);
00457   if(little) swabip(buf+190, 2); memcpy(&h->scan_max, buf+190, 2);
00458   if(little) swawbip(buf+192, 4); memcpy(&h->prompts, buf+192, 4);
00459   if(little) swawbip(buf+196, 4); memcpy(&h->delayed, buf+196, 4);
00460   if(little) swawbip(buf+200, 4); memcpy(&h->multiples, buf+200, 4);
00461   if(little) swawbip(buf+204, 4); memcpy(&h->net_trues, buf+204, 4);
00462   if(little) swawbip(buf+208, 4); memcpy(&h->tot_avg_cor, buf+208, 4);
00463   if(little) swawbip(buf+212, 4); memcpy(&h->tot_avg_uncor, buf+212, 4);
00464   if(little) swawbip(buf+216, 4); memcpy(&h->total_coin_rate, buf+216, 4);
00465   if(little) swawbip(buf+220, 4); memcpy(&h->frame_start_time, buf+220, 4);
00466   if(little) swawbip(buf+224, 4); memcpy(&h->frame_duration, buf+224, 4);
00467   if(little) swawbip(buf+228, 4); memcpy(&h->deadtime_correction_factor, buf+228, 4);
00468   if(little) swabip(buf+232, 90*2); memcpy(h->fill_cti, buf+232, 90*2);
00469   if(little) swabip(buf+412, 50*2); memcpy(h->fill_user, buf+412, 50*2);
00470   if(little) swawbip(buf+512, 128*4); memcpy(h->uncor_singles, buf+512, 128*4);
00471   return(0);
00472 }
00473 /*****************************************************************************/
00474 
00475 /*****************************************************************************/
00485 int ecat7Read2DScanheader(FILE *fp, int blk, ECAT7_2Dscanheader *h) {
00486   unsigned char buf[MatBLKSIZE];
00487   int little; /* 1 if current platform is little endian (i386), else 0 */
00488 
00489   if(ECAT7_TEST) printf("ecat7Read2DScanheader()\n");
00490   if(fp==NULL || h==NULL) return(1);
00491   little=little_endian();
00492 
00493   /* Seek the subheader block */
00494   fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
00495   if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2);
00496   /* Read the header block */
00497   if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
00498   /* Copy the header fields and swap if necessary */
00499   if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
00500   if(little) swabip(buf+2, 2); memcpy(&h->num_dimensions, buf+2, 2);
00501   if(little) swabip(buf+4, 2); memcpy(&h->num_r_elements, buf+4, 2);
00502   if(little) swabip(buf+6, 2); memcpy(&h->num_angles, buf+6, 2);
00503   if(little) swabip(buf+8, 2); memcpy(&h->corrections_applied, buf+8, 2);
00504   if(little) swabip(buf+10, 2); memcpy(&h->num_z_elements, buf+10, 2);
00505   if(little) swabip(buf+12, 2); memcpy(&h->ring_difference, buf+12, 2);
00506   if(little) swawbip(buf+14, 4); memcpy(&h->x_resolution, buf+14, 4);
00507   if(little) swawbip(buf+18, 4); memcpy(&h->y_resolution, buf+18, 4);
00508   if(little) swawbip(buf+22, 4); memcpy(&h->z_resolution, buf+22, 4);
00509   if(little) swawbip(buf+26, 4); memcpy(&h->w_resolution, buf+26, 4);
00510   if(little) swabip(buf+30, 6*2); memcpy(h->fill_gate, buf+30, 6*2);
00511   if(little) swawbip(buf+42, 4); memcpy(&h->gate_duration, buf+42, 4);
00512   if(little) swawbip(buf+46, 4); memcpy(&h->r_wave_offset, buf+46, 4);
00513   if(little) swawbip(buf+50, 4); memcpy(&h->num_accepted_beats, buf+50, 4);
00514   if(little) swawbip(buf+54, 4); memcpy(&h->scale_factor, buf+54, 4);
00515   if(little) swabip(buf+58, 2); memcpy(&h->scan_min, buf+58, 2);
00516   if(little) swabip(buf+60, 2); memcpy(&h->scan_max, buf+60, 2);
00517   if(little) swawbip(buf+62, 4); memcpy(&h->prompts, buf+62, 4);
00518   if(little) swawbip(buf+66, 4); memcpy(&h->delayed, buf+66, 4);
00519   if(little) swawbip(buf+70, 4); memcpy(&h->multiples, buf+70, 4);
00520   if(little) swawbip(buf+74, 4); memcpy(&h->net_trues, buf+74, 4);
00521   if(little) swawbip(buf+78, 16*4); memcpy(h->cor_singles, buf+78, 16*4);
00522   if(little) swawbip(buf+142, 16*4); memcpy(h->uncor_singles, buf+142, 16*4);
00523   if(little) swawbip(buf+206, 4); memcpy(&h->tot_avg_cor, buf+206, 4);
00524   if(little) swawbip(buf+210, 4); memcpy(&h->tot_avg_uncor, buf+210, 4);
00525   if(little) swawbip(buf+214, 4); memcpy(&h->total_coin_rate, buf+214, 4);
00526   if(little) swawbip(buf+218, 4); memcpy(&h->frame_start_time, buf+218, 4);
00527   if(little) swawbip(buf+222, 4); memcpy(&h->frame_duration, buf+222, 4);
00528   if(little) swawbip(buf+226, 4); memcpy(&h->deadtime_correction_factor, buf+226, 4);
00529   if(little) swabip(buf+230, 8*2); memcpy(h->physical_planes, buf+230, 8*2);
00530   if(little) swabip(buf+246, 83*2); memcpy(h->fill_cti, buf+246, 83*2);
00531   if(little) swabip(buf+412, 50*2); memcpy(h->fill_user, buf+412, 50*2);
00532   return(0);
00533 }
00534 /*****************************************************************************/
00535 
00536 /*****************************************************************************/
00546 int ecat7Read2DNormheader(FILE *fp, int blk, ECAT7_2Dnormheader *h) {
00547   unsigned char buf[MatBLKSIZE];
00548   int little; /* 1 if current platform is little endian (i386), else 0 */
00549 
00550   if(ECAT7_TEST) printf("ecat7Read2Dnormheader()\n");
00551   if(fp==NULL || h==NULL) return(1);
00552   little=little_endian();
00553 
00554   /* Seek the subheader block */
00555   fseek(fp, (blk-1)*MatBLKSIZE, SEEK_SET);
00556   if(ftell(fp)!=(blk-1)*MatBLKSIZE) return(2); 
00557   /* Read the header block */
00558   if(fread(buf, MatBLKSIZE, 1, fp)<1) return(3);
00559   /* Copy the header fields and swap if necessary */
00560   if(little) swabip(buf+0, 2); memcpy(&h->data_type, buf+0, 2);
00561   if(little) swabip(buf+2, 2); memcpy(&h->num_dimensions, buf+2, 2);
00562   if(little) swabip(buf+4, 2); memcpy(&h->num_r_elements, buf+4, 2);
00563   if(little) swabip(buf+6, 2); memcpy(&h->num_angles, buf+6, 2);
00564   if(little) swabip(buf+8, 2); memcpy(&h->num_z_elements, buf+8, 2);
00565   if(little) swabip(buf+10, 2); memcpy(&h->ring_difference, buf+10, 2);
00566   if(little) swawbip(buf+12, 4); memcpy(&h->scale_factor, buf+12, 4);
00567   if(little) swawbip(buf+16, 4); memcpy(&h->norm_min, buf+16, 4);
00568   if(little) swawbip(buf+20, 4); memcpy(&h->norm_max, buf+20, 4);
00569   if(little) swawbip(buf+24, 4); memcpy(&h->fov_source_width, buf+24, 4);
00570   if(little) swawbip(buf+28, 4); memcpy(&h->norm_quality_factor, buf+28, 4);
00571   if(little) swabip(buf+32, 2); memcpy(&h->norm_quality_factor_code, buf+32, 2);
00572   if(little) swabip(buf+34, 2); memcpy(&h->storage_order, buf+34, 2);
00573   if(little) swabip(buf+36, 2); memcpy(&h->span, buf+36, 2);
00574   if(little) swabip(buf+38, 64*2); memcpy(h->fill_cti, buf+38, 64*2);
00575   if(little) swabip(buf+166, 123*2); memcpy(h->fill_cti, buf+166, 123*2);
00576   if(little) swabip(buf+412, 50*2); memcpy(h->fill_user, buf+412, 50*2);
00577   return(0);
00578 }
00579 /*****************************************************************************/
00580 
00581 /*****************************************************************************/
00595 int ecat7ReadMatrixdata(FILE *fp, int start_block, int block_nr, char *data, int dtype) {
00596   int i, n, little, err=0;
00597   char *cptr;
00598   float f;
00599 
00600   if(ECAT7_TEST) printf("ecat7ReadMatrixdata(fp, %d, %d, data, %d)\n",
00601     start_block, block_nr, dtype);
00602   /* Check the arguments */
00603   if(block_nr<=0 || start_block<1 || data==NULL) return(1);
00604   /* Seek the first data block */
00605   fseek(fp, (start_block-1)*MatBLKSIZE, SEEK_SET);
00606   if(ftell(fp)!=(start_block-1)*MatBLKSIZE) return(9);
00607   /* Read the data blocks */
00608   if(fread(data, MatBLKSIZE, block_nr, fp) < block_nr) return(2);
00609   /* Translate data if necessary */
00610   little=little_endian();
00611   switch(dtype) {
00612     case ECAT7_BYTE: /* byte format...no translation necessary */
00613       break;
00614     case ECAT7_VAXI2:  /* byte conversion necessary on big endian platform */
00615       if(!little) {cptr=data; swabip(cptr, block_nr*MatBLKSIZE);}
00616       break;
00617     case ECAT7_VAXI4:
00618       for(i=0, cptr=data; i<block_nr*MatBLKSIZE; i+=4, cptr+=4) {
00619         n=ecat7rInt(cptr, 1, little); memcpy(cptr, &n, 4);
00620       }
00621       break;
00622     case ECAT7_VAXR4:
00623       for(i=0, cptr=data; i<block_nr*MatBLKSIZE; i+=4, cptr+=4) {
00624         f=ecat7rFloat(cptr, 1, little); memcpy(cptr, &f, 4);
00625       }
00626       break;
00627     case ECAT7_IEEER4: /* IEEE float ; byte conversion necessary on little endian platforms */
00628     case ECAT7_SUNI4:  /* SUN int ; byte conversion necessary on little endian platforms */
00629       if(little) swawbip(data, block_nr*MatBLKSIZE);
00630       break;
00631     case ECAT7_SUNI2:  /* SUN short ; byte conversion necessary on little endian platforms */
00632       if(little) swabip(data, block_nr*MatBLKSIZE);
00633       break;
00634     default:  /* if something else, for now think it as an error */ 
00635       err=2;
00636       break;
00637   }
00638   return(err);
00639 }
00640 /*****************************************************************************/
00641 
00642 /*****************************************************************************/
00656 int ecat7ReadImageMatrix(FILE *fp, int first_block, int last_block, ECAT7_imageheader *h, float **fdata) {
00657   int i, ret, blockNr, pxlNr;
00658   char *mdata, *mptr;
00659   float *_fdata, *fptr;
00660   short int *sptr;
00661   int *iptr;
00662   
00663   
00664   if(ECAT7_TEST) printf("ecat7ReadImageMatrix(fp, %d, %d, hdr, fdata)\n",
00665     first_block, last_block);
00666   if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
00667     sprintf(ecat7errmsg, "invalid function parameter.\n");
00668     return(1);
00669   }
00670   *fdata=(float*)NULL;
00671   
00672   /* Read subheader */
00673   ret=ecat7ReadImageheader(fp, first_block, h);
00674   if(ret) {
00675     sprintf(ecat7errmsg, "cannot read subheader (%d).\n", ret);
00676     return(5);
00677   }
00678   if(ECAT7_TEST>4) ecat7PrintImageheader(h, stdout);
00679   pxlNr=h->x_dimension*h->y_dimension;
00680   if(h->num_dimensions>2) pxlNr*=h->z_dimension;
00681   if(pxlNr<=0) {
00682     sprintf(ecat7errmsg, "invalid matrix dimension.\n");
00683     return(6);  
00684   }
00685   
00686   /* Read matrix data */
00687   blockNr=last_block-first_block; if(blockNr<1) return(0);
00688   mdata=(char*)malloc(blockNr*MatBLKSIZE);
00689   if(mdata==NULL) {
00690     sprintf(ecat7errmsg, "cannot allocate memory.\n");
00691     return(8);  
00692   }
00693   mptr=mdata;
00694   ret=ecat7ReadMatrixdata(fp, first_block+1, blockNr, mptr, h->data_type);
00695   if(ret || mdata==NULL) {
00696     sprintf(ecat7errmsg, "cannot read matrix data (%d).\n", ret);
00697     free(mdata); return(9);
00698   }
00699   
00700   /* Allocate memory for float data */
00701   _fdata=(float*)malloc(pxlNr*sizeof(float));
00702   if(_fdata==NULL) {
00703     sprintf(ecat7errmsg, "cannot allocate memory.\n");
00704     free(mdata); return(11);  
00705   }
00706 
00707   /* Convert matrix data to floats */
00708   fptr=_fdata; mptr=mdata;
00709   if(h->data_type==ECAT7_BYTE) {
00710     for(i=0; i<pxlNr; i++, mptr++, fptr++)
00711       *fptr=h->scale_factor*(float)(*mptr);
00712   } else if(h->data_type==ECAT7_VAXI2 || h->data_type==ECAT7_SUNI2) {
00713     for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
00714       sptr=(short int*)mptr;
00715       *fptr=h->scale_factor*(float)(*sptr);
00716     }
00717   } else if(h->data_type==ECAT7_VAXI4 || h->data_type==ECAT7_SUNI4) {
00718     for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
00719       iptr=(int*)mptr;
00720       *fptr=h->scale_factor*(float)(*iptr);
00721     }
00722   } else if(h->data_type==ECAT7_VAXR4 || h->data_type==ECAT7_IEEER4) {
00723     memcpy(fptr, mptr, pxlNr*4);
00724     for(i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
00725   }
00726   free(mdata);
00727   *fdata=_fdata;
00728 
00729   return(0);
00730 }
00731 /*****************************************************************************/
00732 
00733 /*****************************************************************************/
00749 int ecat7Read2DScanMatrix(FILE *fp, int first_block, int last_block,
00750         ECAT7_2Dscanheader *h, float **fdata) {
00751   int i, ret, blockNr, pxlNr;
00752   char *mdata, *mptr;
00753   float *_fdata, *fptr;
00754   short int *sptr;
00755   int *iptr;
00756 
00757 
00758   if(ECAT7_TEST) printf("ecat7Read2DScanMatrix(fp, %d, %d, hdr, fdata)\n",
00759     first_block, last_block);
00760   if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
00761     sprintf(ecat7errmsg, "invalid function parameter.\n");
00762     return(1);
00763   }
00764   *fdata=(float*)NULL;
00765   
00766   /* Read subheader */
00767   ret=ecat7Read2DScanheader(fp, first_block, h);
00768   if(ret) {
00769     sprintf(ecat7errmsg, "cannot read subheader (%d).\n", ret);
00770     return(5);
00771   }
00772   if(ECAT7_TEST>4) ecat7Print2DScanheader(h, stdout);
00773   pxlNr=h->num_r_elements*h->num_angles;
00774   if(h->num_dimensions>2) pxlNr*=h->num_z_elements;
00775   if(pxlNr<=0) {
00776     sprintf(ecat7errmsg, "invalid matrix dimension.\n");
00777     return(6);  
00778   }
00779   
00780   /* Read matrix data */
00781   blockNr=last_block-first_block; if(blockNr<1) return(0);
00782   mdata=(char*)malloc(blockNr*MatBLKSIZE);
00783   if(mdata==NULL) {
00784     sprintf(ecat7errmsg, "cannot allocate memory.\n");
00785     return(8);  
00786   }
00787   mptr=mdata;
00788   ret=ecat7ReadMatrixdata(fp, first_block+1, blockNr, mptr, h->data_type);
00789   if(ret || mdata==NULL) {
00790     sprintf(ecat7errmsg, "cannot read matrix data (%d).\n", ret);
00791     free(mdata); return(9);
00792   }
00793   
00794   /* Allocate memory for float data */
00795   _fdata=(float*)malloc(pxlNr*sizeof(float));
00796   if(_fdata==NULL) {
00797     sprintf(ecat7errmsg, "cannot allocate memory.\n");
00798     free(mdata); return(11);  
00799   }
00800 
00801   /* Convert matrix data to floats */
00802   fptr=_fdata; mptr=mdata;
00803   if(h->data_type==ECAT7_BYTE) {
00804     for(i=0; i<pxlNr; i++, mptr++, fptr++)
00805       *fptr=h->scale_factor*(float)(*mptr);
00806   } else if(h->data_type==ECAT7_VAXI2 || h->data_type==ECAT7_SUNI2) {
00807     for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
00808       sptr=(short int*)mptr;
00809       *fptr=h->scale_factor*(float)(*sptr);
00810     }
00811   } else if(h->data_type==ECAT7_VAXI4 || h->data_type==ECAT7_SUNI4) {
00812     for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
00813       iptr=(int*)mptr;
00814       *fptr=h->scale_factor*(float)(*iptr);
00815     }
00816   } else if(h->data_type==ECAT7_VAXR4 || h->data_type==ECAT7_IEEER4) {
00817     memcpy(fptr, mptr, pxlNr*4);
00818     for(i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
00819   }
00820   free(mdata);
00821   *fdata=_fdata;
00822 
00823   return(0);
00824 }
00825 /*****************************************************************************/
00826 
00827 /*****************************************************************************/
00844 int ecat7ReadScanMatrix(FILE *fp, int first_block, int last_block, ECAT7_scanheader *h, float **fdata) {
00845   int i, ret, blockNr, trueblockNr, pxlNr, dimz;
00846   char *mdata, *mptr;
00847   float *_fdata, *fptr;
00848   short int *sptr;
00849   int *iptr;
00850   
00851   
00852   if(ECAT7_TEST) printf("ecat7ReadScanMatrix(fp, %d, %d, hdr, fdata)\n",
00853     first_block, last_block);
00854   if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) {
00855     sprintf(ecat7errmsg, "invalid function parameter.\n");
00856     return(1);
00857   }
00858   *fdata=(float*)NULL;
00859   
00860   /* Read subheader */
00861   ret=ecat7ReadScanheader(fp, first_block, h);
00862   if(ret) {
00863     sprintf(ecat7errmsg, "cannot read subheader (%d).\n", ret);
00864     return(5);
00865   }
00866   if(ECAT7_TEST>4) ecat7PrintScanheader(h, stdout);
00867   pxlNr=h->num_r_elements*h->num_angles;
00868   for(i=dimz=0; i<64; i++) dimz+=h->num_z_elements[i]; pxlNr*=dimz;
00869   if(pxlNr<=0) {
00870     sprintf(ecat7errmsg, "invalid matrix dimension.\n");
00871     return(6);  
00872   }
00873   trueblockNr=pxlNr*ecat7pxlbytes(h->data_type);
00874   trueblockNr=(trueblockNr+MatBLKSIZE-1)/MatBLKSIZE;
00875 
00876   /* Read matrix data; note that header takes 2 blocks */
00877   blockNr=last_block-first_block-1; if(blockNr<1) return(0);
00878   if(blockNr<trueblockNr) trueblockNr=blockNr;
00879   mdata=(char*)malloc(blockNr*MatBLKSIZE);
00880   if(mdata==NULL) {
00881     sprintf(ecat7errmsg, "cannot allocate memory.\n");
00882     return(8);  
00883   }
00884   mptr=mdata; /* note that only true block nr is read! */
00885   ret=ecat7ReadMatrixdata(fp, first_block+2, trueblockNr, mptr, h->data_type);
00886   if(ret || mdata==NULL) {
00887     sprintf(ecat7errmsg, "cannot read matrix data (%d).\n", ret);
00888     free(mdata); return(9);
00889   }
00890   
00891   /* Allocate memory for float data */
00892   _fdata=(float*)malloc(pxlNr*sizeof(float));
00893   if(_fdata==NULL) {
00894     sprintf(ecat7errmsg, "cannot allocate memory.\n");
00895     free(mdata); return(11);  
00896   }
00897 
00898   /* Convert matrix data to floats */
00899   fptr=_fdata; mptr=mdata;
00900   if(h->data_type==ECAT7_BYTE) {
00901     for(i=0; i<pxlNr; i++, mptr++, fptr++)
00902       *fptr=h->scale_factor*(float)(*mptr);
00903   } else if(h->data_type==ECAT7_VAXI2 || h->data_type==ECAT7_SUNI2) {
00904     for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
00905       sptr=(short int*)mptr;
00906       *fptr=h->scale_factor*(float)(*sptr);
00907     }
00908   } else if(h->data_type==ECAT7_VAXI4 || h->data_type==ECAT7_SUNI4) {
00909     for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
00910       iptr=(int*)mptr;
00911       *fptr=h->scale_factor*(float)(*iptr);
00912     }
00913   } else if(h->data_type==ECAT7_VAXR4 || h->data_type==ECAT7_IEEER4) {
00914     memcpy(fptr, mptr, pxlNr*4);
00915     for(i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
00916   }
00917   free(mdata);
00918   *fdata=_fdata;
00919 
00920   return(0);
00921 }
00922 /*****************************************************************************/
00923 
00924 /*****************************************************************************/
00939 int ecat7ReadPolarmapMatrix(FILE *fp, int first_block, int last_block, ECAT7_polmapheader *h, float **fdata) {
00940   int i, ret, blockNr, pxlNr;
00941   char *mdata, *mptr;
00942   float *_fdata, *fptr;
00943   short int *sptr;
00944   int *iptr;
00945 
00946 
00947   if(ECAT7_TEST) printf("ecat7ReadPolarmapMatrix(fp, %d, %d, hdr, fdata)\n",
00948     first_block, last_block);
00949   if(fp==NULL || first_block<=MatFirstDirBlk || h==NULL) return 1;
00950   *fdata=(float*)NULL;
00951 
00952   /* Read subheader */
00953   ret=ecat7ReadPolmapheader(fp, first_block, h);
00954   if(ret) {
00955     sprintf(ecat7errmsg, "cannot read subheader (%d).\n", ret);
00956     return 2;
00957   }
00958   if(ECAT7_TEST>4) ecat7PrintPolmapheader(h, stdout);
00959   for(i=pxlNr=0; i<h->num_rings; i++) pxlNr+=h->sectors_per_ring[i];
00960   if(pxlNr<=0) return 3;
00961 
00962   /* Read matrix data */
00963   blockNr=last_block-first_block; if(blockNr<1) return 0;
00964   mdata=(char*)malloc(blockNr*MatBLKSIZE);
00965   if(mdata==NULL) return 4;
00966   mptr=mdata;
00967   ret=ecat7ReadMatrixdata(fp, first_block+1, blockNr, mptr, h->data_type);
00968   if(ret || mdata==NULL) {
00969     if(mdata!=NULL) free(mdata);
00970     return 5;
00971   }
00972 
00973   /* Allocate memory for float data */
00974   _fdata=(float*)malloc(pxlNr*sizeof(float));
00975   if(_fdata==NULL) {
00976     sprintf(ecat7errmsg, "cannot allocate memory.\n");
00977     free(mdata); return 4;
00978   }
00979 
00980   /* Convert matrix data to floats */
00981   fptr=_fdata; mptr=mdata;
00982   if(h->data_type==ECAT7_BYTE) {
00983     for(i=0; i<pxlNr; i++, mptr++, fptr++)
00984       *fptr=h->scale_factor*(float)(*mptr);
00985   } else if(h->data_type==ECAT7_VAXI2 || h->data_type==ECAT7_SUNI2) {
00986     for(i=0; i<pxlNr; i++, mptr+=2, fptr++) {
00987       sptr=(short int*)mptr;
00988       *fptr=h->scale_factor*(float)(*sptr);
00989     }
00990   } else if(h->data_type==ECAT7_VAXI4 || h->data_type==ECAT7_SUNI4) {
00991     for(i=0; i<pxlNr; i++, mptr+=4, fptr++) {
00992       iptr=(int*)mptr;
00993       *fptr=h->scale_factor*(float)(*iptr);
00994     }
00995   } else if(h->data_type==ECAT7_VAXR4 || h->data_type==ECAT7_IEEER4) {
00996     memcpy(fptr, mptr, pxlNr*4);
00997     for(i=0; i<pxlNr; i++, fptr++) *fptr *= h->scale_factor;
00998   }
00999   free(mdata);
01000   *fdata=_fdata;
01001 
01002   return 0;
01003 }
01004 /*****************************************************************************/
01005 
01006 /*****************************************************************************/
01015 float ecat7rFloat(void *bufi, int isvax, int islittle) {
01016   union {unsigned int ul; float f;} t;
01017 
01018   memcpy(&t.ul, bufi, 4); if(t.ul==0) {return(0.0);}
01019   if(isvax) { /* if input is in VAX format */
01020     /* Swap words on i386 and bytes on SUN */
01021     if(islittle) swawip(&t.ul, 4); else swabip(&t.ul, 4);
01022     t.ul-=(2L<<23); /* subtract 2 from exp */
01023   } else { /* input is in i386 format */
01024     if(!islittle) swawbip(&t.ul, 4); /* Switch words and bytes on SUN */
01025   }
01026   return(t.f);
01027 }
01028 
01038 int ecat7rInt(void *bufi, int isvax, int islittle) {
01039   int i;
01040 
01041   /* Swap both words and bytes on SUN */
01042   memcpy(&i, bufi, 4); if(!islittle) swawbip(&i, 4);
01043   return(i);
01044 }
01045 /*****************************************************************************/
01046 
01047 /*****************************************************************************/
01055 int ecat7pxlbytes(short int data_type) {
01056   int byteNr=0;
01057   switch(data_type) {
01058     case ECAT7_BYTE: byteNr=1; break;
01059     case ECAT7_VAXI2:
01060     case ECAT7_SUNI2: byteNr=2; break;
01061     case ECAT7_VAXI4:
01062     case ECAT7_VAXR4:
01063     case ECAT7_IEEER4:
01064     case ECAT7_SUNI4: byteNr=4; break;
01065   }
01066   return(byteNr);
01067 }
01068 /*****************************************************************************/
01069 
01070 /*****************************************************************************/
01071