1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 
19 
20 #include "itkPhilipsPAR.h"
21 #include <fstream>
22 #include <iostream>
23 #include <algorithm>
24 
25 /**
26  * \author Don C. Bigler
27  *         The Pennsylvania State University 2005
28  *
29  * This implementation was contributed as a paper to the Insight Journal
30  * http://insight-journal.org/midas/handle.php?handle=1926/1381
31  *
32  */
33 
34 namespace itk
35 {
36 /*#=== IMAGE INFORMATION DEFINITION ============================================
37 #
38 #The rest of this file contains ONE line per image, this line contains the
39 #following information:
40 #
41 #slice number                             (integer)
42 #echo number                              (integer)
43 #dynamic scan number                      (integer)
44 #cardiac phase number                     (integer)
45 #image_type_mr                            (integer)
46 #scanning sequence                        (integer)
47 #index in REC file (in images)            (integer)
48 #rescale intercept                        (float)
49 #rescale slope                            (float)
50 #scale slope                              (float)
51 #window center                            (integer)
52 #window width                             (integer)
53 #image angulation (ap,fh,rl in degrees )  (3*float)
54 #image offcentre (ap,fh,rl in mm )        (3*float)
55 #image_display_orientation                (integer)
56 #slice orientation ( TRA/SAG/COR )        (integer)
57 #fmri_status_indication                   (integer)
58 #image_type_ed_es  (end diast/end syst)   (integer)
59 #pixel spacing (x,y) (in mm)              (2*float)
60 #echo_time                                (float)
61 #dyn_scan_begin_time                      (float)
62 #trigger_time                             (float)
63 #diffusion_b_factor                       (float)
64 #image_flip_angle (in degrees)            (float)
65 #
66 #=== IMAGE INFORMATION =======================================================*/
67 /**
68  * \struct image_info_defV3
69  */
70 struct image_info_defV3 {
71   int problemreading;
72   int slice;
73   int echo;
74   int dynamic;
75   int cardiac;
76   int image_type_mr;
77   int scan_sequence;
78   int index;
79   float rescale_int;
80   float rescale_slope;
81   float scale_slope;
82   int window_center;
83   int window_width;
84   float angAP;
85   float angFH;
86   float angRL;
87   float offAP;
88   float offFH;
89   float offRL;
90   int display_orientation;
91   int slice_orientation;
92   int fmri_status_indication;
93   int image_type_ed_es;
94   float spacingx;
95   float spacingy;
96   float echo_time;
97   float dyn_scan_begin_time;
98   float trigger_time;
99   float diffusion_b_factor;
100   float image_flip_angle;
101 };
102 
103 /*#=== IMAGE INFORMATION DEFINITION ============================================
104 #The rest of this file contains ONE line per image, this line contains the
105 #following information:
106 #
107 #slice number                             (integer)
108 #echo number                              (integer)
109 #dynamic scan number                      (integer)
110 #cardiac phase number                     (integer)
111 #image_type_mr                            (integer)
112 #scanning sequence                        (integer)
113 #index in REC file (in images)            (integer)
114 #image pixel size (in bits)               (integer)
115 #scan percentage                          (integer)
116 #recon resolution (x y)                   (2*integer)
117 #rescale intercept                        (float)
118 #rescale slope                            (float)
119 #scale slope                              (float)
120 #window center                            (integer)
121 #window width                             (integer)
122 #image angulation (ap,fh,rl in degrees )  (3*float)
123 #image offcentre (ap,fh,rl in mm )        (3*float)
124 #slice thickness (in mm )                 (float)
125 #slice gap (in mm )                       (float)
126 #image_display_orientation                (integer)
127 #slice orientation ( TRA/SAG/COR )        (integer)
128 #fmri_status_indication                   (integer)
129 #image_type_ed_es  (end diast/end syst)   (integer)
130 #pixel spacing (x,y) (in mm)              (2*float)
131 #echo_time                                (float)
132 #dyn_scan_begin_time                      (float)
133 #trigger_time                             (float)
134 #diffusion_b_factor                       (float)
135 #number of averages                       (integer)
136 #image_flip_angle (in degrees)            (float)
137 #cardiac frequency   (bpm)                (integer)
138 #minimum RR-interval (in ms)              (integer)
139 #maximum RR-interval (in ms)              (integer)
140 #TURBO factor  <0=no turbo>               (integer)
141 #Inversion delay (in ms)                  (float)
142 Version 4.1
143 #diffusion b value number    (imagekey!)  (integer)
144 #gradient orientation number (imagekey!)  (integer)
145 #contrast type                            (string)
146 #diffusion anisotropy type                (string)
147 #diffusion (ap, fh, rl)                   (3*float)
148 Version 4.2
149 #label type (ASL)            (imagekey!)  (integer)
150 #
151 #=== IMAGE INFORMATION =======================================================*/
152 /**
153  * \struct image_info_defV4
154  */
155 struct image_info_defV4 {
156   int problemreading;
157   int slice;
158   int echo;
159   int dynamic;
160   int cardiac;
161   int image_type_mr;
162   int scan_sequence;
163   int index;
164   int image_bits;
165   int scan_percent;
166   int recon_dimx;
167   int recon_dimy;
168   float rescale_int;
169   float rescale_slope;
170   float scale_slope;
171   int window_center;
172   int window_width;
173   float angAP;
174   float angFH;
175   float angRL;
176   float offAP;
177   float offFH;
178   float offRL;
179   float slice_thick;
180   float slice_gap;
181   int display_orientation;
182   int slice_orientation;
183   int fmri_status_indication;
184   int image_type_ed_es;
185   float spacingx;
186   float spacingy;
187   float echo_time;
188   float dyn_scan_begin_time;
189   float trigger_time;
190   float diffusion_b_factor;
191   int num_averages;
192   float image_flip_angle;
193   int cardiac_freq;
194   int min_rr_int;
195   int max_rr_int;
196   int turbo_factor;
197   float inversion_delay;
198   // Version 4.1 added diffusion gradient information
199   int diffusion_b_value_number;
200   int gradient_orientation_number;
201   int contrast_type;
202   float diffusion_ap;
203   float diffusion_fh;
204   float diffusion_rl;
205   // Version 4.2 added ASL labels
206   int labelTypeASL;
207 };
208 
GetImageInformationDefinitionV3(std::string file,int lineNum,PhilipsPAR * philipsPARClass)209 struct image_info_defV3 GetImageInformationDefinitionV3(std::string file,
210                                                         int lineNum, PhilipsPAR *philipsPARClass)
211 {
212   struct image_info_defV3 tempInfo;
213   std::string             currentLine = "";
214 
215   memset( (void *)&tempInfo, 0, sizeof( struct image_info_defV3 ) );
216   if ( lineNum < 89 )
217     {
218     tempInfo.problemreading = 1;
219     return tempInfo;
220     }
221   currentLine = philipsPARClass->GetLineNumber(file, lineNum);
222   if ( ( currentLine == "" )
223        || ( currentLine == "\n" )
224        || ( currentLine == "\r\n" )
225        || ( currentLine == "\r" )
226        || ( currentLine == "#=== END OF DATA DESCRIPTION FILE ======================"
227                            "=========================" )
228        || ( currentLine == "#=== END OF DATA DESCRIPTION FILE ======================"
229                            "=========================\r" ) )
230     {
231     tempInfo.problemreading = 1;
232     return tempInfo;
233     }
234   std::istringstream inString(currentLine);
235   if ( !inString )
236     {
237     tempInfo.problemreading = 1;
238     return tempInfo;
239     }
240   inString >> tempInfo.slice >> tempInfo.echo >> tempInfo.dynamic;
241   inString >> tempInfo.cardiac >> tempInfo.image_type_mr
242   >> tempInfo.scan_sequence;
243   inString >> tempInfo.index >> tempInfo.rescale_int >> tempInfo.rescale_slope;
244   inString >> tempInfo.scale_slope >> tempInfo.window_center
245   >> tempInfo.window_width;
246   inString >> tempInfo.angAP >> tempInfo.angFH >> tempInfo.angRL;
247   inString >> tempInfo.offAP >> tempInfo.offFH >> tempInfo.offRL;
248   inString >> tempInfo.display_orientation >> tempInfo.slice_orientation
249   >> tempInfo.fmri_status_indication;
250   inString >> tempInfo.image_type_ed_es >> tempInfo.spacingx
251   >> tempInfo.spacingy;
252   inString >> tempInfo.echo_time >> tempInfo.dyn_scan_begin_time
253   >> tempInfo.trigger_time;
254   inString >> tempInfo.diffusion_b_factor >> tempInfo.image_flip_angle;
255   return tempInfo;
256 }
257 
GetImageInformationDefinitionV4(std::string file,int lineNum,PhilipsPAR * philipsPARClass)258 struct image_info_defV4 GetImageInformationDefinitionV4(std::string file,
259                                                         int lineNum, PhilipsPAR *philipsPARClass)
260 {
261   struct image_info_defV4 tempInfo;
262   std::string             currentLine = "";
263 
264   memset( (void *)&tempInfo, 0, sizeof( struct image_info_defV4 ) );
265   if ( lineNum < 92 )
266     {
267     tempInfo.problemreading = 1;
268     return tempInfo;
269     }
270   currentLine = philipsPARClass->GetLineNumber(file, lineNum);
271   if ( ( currentLine == "" )
272        || ( currentLine == "\n" )
273        || ( currentLine == "\r\n" )
274        || ( currentLine == "\r" )
275        || ( currentLine == "#=== END OF DATA DESCRIPTION FILE ======================"
276                            "=========================" )
277        || ( currentLine == "#=== END OF DATA DESCRIPTION FILE ======================"
278                            "=========================\r" ) )
279     {
280     tempInfo.problemreading = 1;
281     return tempInfo;
282     }
283   std::istringstream inString(currentLine);
284   if ( !inString )
285     {
286     tempInfo.problemreading = 1;
287     return tempInfo;
288     }
289   inString >> tempInfo.slice >> tempInfo.echo >> tempInfo.dynamic;
290   inString >> tempInfo.cardiac >> tempInfo.image_type_mr
291   >> tempInfo.scan_sequence;
292   inString >> tempInfo.index >> tempInfo.image_bits >> tempInfo.scan_percent;
293   inString >> tempInfo.recon_dimx >> tempInfo.recon_dimy;
294   inString >> tempInfo.rescale_int >> tempInfo.rescale_slope;
295   inString >> tempInfo.scale_slope >> tempInfo.window_center
296   >> tempInfo.window_width;
297   inString >> tempInfo.angAP >> tempInfo.angFH >> tempInfo.angRL;
298   inString >> tempInfo.offAP >> tempInfo.offFH >> tempInfo.offRL;
299   inString >> tempInfo.slice_thick >> tempInfo.slice_gap;
300   inString >> tempInfo.display_orientation >> tempInfo.slice_orientation
301   >> tempInfo.fmri_status_indication;
302   inString >> tempInfo.image_type_ed_es >> tempInfo.spacingx
303   >> tempInfo.spacingy;
304   inString >> tempInfo.echo_time >> tempInfo.dyn_scan_begin_time
305   >> tempInfo.trigger_time;
306   inString >> tempInfo.diffusion_b_factor >> tempInfo.num_averages
307   >> tempInfo.image_flip_angle;
308   inString >> tempInfo.cardiac_freq >> tempInfo.min_rr_int
309   >> tempInfo.max_rr_int;
310   inString >> tempInfo.turbo_factor >> tempInfo.inversion_delay;
311   return tempInfo;
312 }
313 
GetImageInformationDefinitionV41(std::string file,int lineNum,PhilipsPAR * philipsPARClass)314 struct image_info_defV4 GetImageInformationDefinitionV41(std::string file,
315                                                          int lineNum, PhilipsPAR *philipsPARClass)
316 {
317   struct image_info_defV4 tempInfo;
318   std::string             currentLine = "";
319 
320   memset( (void *)&tempInfo, 0, sizeof( struct image_info_defV4 ) );
321   if ( lineNum < 99 )
322     {
323     tempInfo.problemreading = 1;
324     return tempInfo;
325     }
326   currentLine = philipsPARClass->GetLineNumber(file, lineNum);
327   if ( ( currentLine == "" )
328        || ( currentLine == "\n" )
329        || ( currentLine == "\r\n" )
330        || ( currentLine == "\r" )
331        || ( currentLine == "#=== END OF DATA DESCRIPTION FILE ======================"
332                            "=========================" )
333        || ( currentLine == "#=== END OF DATA DESCRIPTION FILE ======================"
334                            "=========================\r" ) )
335     {
336     tempInfo.problemreading = 1;
337     return tempInfo;
338     }
339   std::istringstream inString(currentLine);
340   if ( !inString )
341     {
342     tempInfo.problemreading = 1;
343     return tempInfo;
344     }
345   inString >> tempInfo.slice >> tempInfo.echo >> tempInfo.dynamic;
346   inString >> tempInfo.cardiac >> tempInfo.image_type_mr
347   >> tempInfo.scan_sequence;
348   inString >> tempInfo.index >> tempInfo.image_bits >> tempInfo.scan_percent;
349   inString >> tempInfo.recon_dimx >> tempInfo.recon_dimy;
350   inString >> tempInfo.rescale_int >> tempInfo.rescale_slope;
351   inString >> tempInfo.scale_slope >> tempInfo.window_center
352   >> tempInfo.window_width;
353   inString >> tempInfo.angAP >> tempInfo.angFH >> tempInfo.angRL;
354   inString >> tempInfo.offAP >> tempInfo.offFH >> tempInfo.offRL;
355   inString >> tempInfo.slice_thick >> tempInfo.slice_gap;
356   inString >> tempInfo.display_orientation >> tempInfo.slice_orientation
357   >> tempInfo.fmri_status_indication;
358   inString >> tempInfo.image_type_ed_es >> tempInfo.spacingx
359   >> tempInfo.spacingy;
360   inString >> tempInfo.echo_time >> tempInfo.dyn_scan_begin_time
361   >> tempInfo.trigger_time;
362   inString >> tempInfo.diffusion_b_factor >> tempInfo.num_averages
363   >> tempInfo.image_flip_angle;
364   inString >> tempInfo.cardiac_freq >> tempInfo.min_rr_int
365   >> tempInfo.max_rr_int;
366   inString >> tempInfo.turbo_factor >> tempInfo.inversion_delay;
367   inString >> tempInfo.diffusion_b_value_number
368   >> tempInfo.gradient_orientation_number;
369   inString >> tempInfo.contrast_type >> tempInfo.contrast_type;
370   inString >> tempInfo.diffusion_ap >> tempInfo.diffusion_fh
371   >> tempInfo.diffusion_rl;
372   return tempInfo;
373 }
374 
GetImageInformationDefinitionV42(std::string file,int lineNum,PhilipsPAR * philipsPARClass)375 struct image_info_defV4 GetImageInformationDefinitionV42(std::string file,
376                                                          int lineNum, PhilipsPAR *philipsPARClass)
377 {
378   struct image_info_defV4 tempInfo;
379   std::string             currentLine = "";
380 
381   memset( (void *)&tempInfo, 0, sizeof( struct image_info_defV4 ) );
382   if ( lineNum < 101 )
383     {
384     tempInfo.problemreading = 1;
385     return tempInfo;
386     }
387   currentLine = philipsPARClass->GetLineNumber(file, lineNum);
388   if ( ( currentLine == "" )
389        || ( currentLine == "\n" )
390        || ( currentLine == "\r\n" )
391        || ( currentLine == "\r" )
392        || ( currentLine == "#=== END OF DATA DESCRIPTION FILE ======================"
393                            "=========================" )
394        || ( currentLine == "#=== END OF DATA DESCRIPTION FILE ======================"
395                            "=========================\r" ) )
396     {
397     tempInfo.problemreading = 1;
398     return tempInfo;
399     }
400   std::istringstream inString(currentLine);
401   if ( !inString )
402     {
403     tempInfo.problemreading = 1;
404     return tempInfo;
405     }
406   inString >> tempInfo.slice >> tempInfo.echo >> tempInfo.dynamic;
407   inString >> tempInfo.cardiac >> tempInfo.image_type_mr
408   >> tempInfo.scan_sequence;
409   inString >> tempInfo.index >> tempInfo.image_bits >> tempInfo.scan_percent;
410   inString >> tempInfo.recon_dimx >> tempInfo.recon_dimy;
411   inString >> tempInfo.rescale_int >> tempInfo.rescale_slope;
412   inString >> tempInfo.scale_slope >> tempInfo.window_center
413   >> tempInfo.window_width;
414   inString >> tempInfo.angAP >> tempInfo.angFH >> tempInfo.angRL;
415   inString >> tempInfo.offAP >> tempInfo.offFH >> tempInfo.offRL;
416   inString >> tempInfo.slice_thick >> tempInfo.slice_gap;
417   inString >> tempInfo.display_orientation >> tempInfo.slice_orientation
418   >> tempInfo.fmri_status_indication;
419   inString >> tempInfo.image_type_ed_es >> tempInfo.spacingx
420   >> tempInfo.spacingy;
421   inString >> tempInfo.echo_time >> tempInfo.dyn_scan_begin_time
422   >> tempInfo.trigger_time;
423   inString >> tempInfo.diffusion_b_factor >> tempInfo.num_averages
424   >> tempInfo.image_flip_angle;
425   inString >> tempInfo.cardiac_freq >> tempInfo.min_rr_int
426   >> tempInfo.max_rr_int;
427   inString >> tempInfo.turbo_factor >> tempInfo.inversion_delay;
428   inString >> tempInfo.diffusion_b_value_number
429   >> tempInfo.gradient_orientation_number;
430   inString >> tempInfo.contrast_type >> tempInfo.contrast_type;
431   inString >> tempInfo.diffusion_ap >> tempInfo.diffusion_fh
432   >> tempInfo.diffusion_rl;
433   inString >> tempInfo.labelTypeASL;
434   return tempInfo;
435 }
436 
PhilipsPAR()437 PhilipsPAR::PhilipsPAR()
438 {
439   this->m_FileName = "";
440   this->m_PARFileLines.resize(0);
441 }
442 
~PhilipsPAR()443 PhilipsPAR::~PhilipsPAR()
444 {}
445 
GetLineNumber(std::string file,int lineNum)446 std::string PhilipsPAR::GetLineNumber(std::string file, int lineNum)
447 {
448   std::string line = "";
449   char        readFileBuffer[1024] = "";
450 
451   if ( lineNum <= 0 )
452     {
453     return line;
454     }
455 
456   // If this is the first time, read the whole file into memory.
457   if ( file != this->m_FileName )
458     {
459     this->m_FileName = file;
460     this->m_PARFileLines.resize(0);
461 
462     // Try to read the text file.
463     std::ifstream local_InputStream;
464     local_InputStream.open(file.c_str(), std::ios::in);
465     if ( local_InputStream.fail() )
466       {
467       return line;
468       }
469     while ( !local_InputStream.eof() )
470       {
471       local_InputStream.getline( readFileBuffer, sizeof( readFileBuffer ) );
472       line = readFileBuffer;
473       this->m_PARFileLines.push_back(line);
474       }
475     local_InputStream.close();
476     }
477 
478   // Return line if not EOF.
479   line = "";
480   if ( ( std::vector< std::string >::size_type )lineNum
481        <= this->m_PARFileLines.size() )
482     {
483     line = this->m_PARFileLines[lineNum - 1];
484     }
485 
486   return line;
487 }
488 
GetPARVersion(std::string parFile)489 int PhilipsPAR::GetPARVersion(std::string parFile)
490 {
491   //read version number of Philips research tools
492   //Research tools are used to extract data from database; data formats differ
493   //considerably between versions. Handles V3, V4, V4.1, and V4.2
494   int         ResToolsVersion = RESEARCH_IMAGE_EXPORT_TOOL_UNKNOWN;
495 
496   // Character index 61 on line 8 should be 'V'.
497   std::string currentLine = this->GetLineNumber(parFile, 8);
498   if ( ( currentLine.length() >= 63 )
499        && ( currentLine[61] == 'V' ) )
500     {
501     // Next characters contain the version number.
502     switch ( currentLine[62] )
503       {
504       case '3':
505         ResToolsVersion = RESEARCH_IMAGE_EXPORT_TOOL_V3;
506         break;
507       case '4':
508         {
509         if ( ( currentLine.length() == 63 )
510              || ( currentLine[63] ) != '.' )
511           {
512           ResToolsVersion = RESEARCH_IMAGE_EXPORT_TOOL_V4;
513           }
514         else if ( currentLine.length() >= 65 )
515           {
516           switch ( currentLine[64] )
517             {
518             case '1':
519               ResToolsVersion = RESEARCH_IMAGE_EXPORT_TOOL_V4_1;
520               break;
521             case '2':
522               ResToolsVersion = RESEARCH_IMAGE_EXPORT_TOOL_V4_2;
523               break;
524             }
525           }
526         }
527         break;
528       }
529     }
530   return ResToolsVersion;
531 }
532 
GetGeneralInfoString(std::string file,int lineNum)533 std::string PhilipsPAR::GetGeneralInfoString(std::string file, int lineNum)
534 {
535   std::string            currentLine = "";
536   std::string::size_type index;
537   std::string            outString = "";
538 
539   if ( ( lineNum < 12 ) || ( lineNum > 51 ) )
540     {
541     return outString;
542     }
543   currentLine = this->GetLineNumber(file, lineNum);
544   index = currentLine.find(":");
545   if ( index != std::string::npos )
546     {
547     std::string tempString = ":";
548     outString = currentLine.substr( index + tempString.length() );
549     }
550   return outString;
551 }
552 
553 #define UNDEFINED "Undefined"
554 
555 // Originally adapted from r2agui.m
ReadPAR(std::string parFile,struct par_parameter * pPar)556 void PhilipsPAR::ReadPAR(std::string parFile, struct par_parameter *pPar)
557 {
558   std::istringstream inString;
559 
560   if ( pPar == nullptr )
561     {
562     std::ostringstream message;
563     message << "ReadPAR: pPar == nullptr";
564     ExceptionObject exception(__FILE__, __LINE__,
565                               message.str(),
566                               ITK_LOCATION);
567     throw exception;
568     }
569 
570   // Zero out struct.
571   memset( (void *)pPar, 0, sizeof( struct par_parameter ) );
572   // Need to set strings to UNDEFINED to avoid segmentation faults.
573   strcpy(pPar->patient_name, UNDEFINED);
574   strcpy(pPar->exam_name, UNDEFINED);
575   strcpy(pPar->protocol_name, UNDEFINED);
576   strcpy(pPar->exam_date, UNDEFINED);
577   strcpy(pPar->exam_time, UNDEFINED);
578   strcpy(pPar->series_type, UNDEFINED);
579   strcpy(pPar->patient_position, UNDEFINED);
580   strcpy(pPar->prep_direction, UNDEFINED);
581   strcpy(pPar->technique, UNDEFINED);
582   strcpy(pPar->scan_mode, UNDEFINED);
583   // Set image types index to -1.
584   memset( (void *)pPar->image_types, -1, sizeof( pPar->image_types ) );
585   // Set num_slice_repetitions to 1 to avoid divide by zero.
586   pPar->num_slice_repetitions = 1;
587 
588   // Get PAR version.
589   pPar->ResToolsVersion = this->GetPARVersion(parFile);
590 
591   // Parse PAR file according to version.
592   switch ( pPar->ResToolsVersion )
593     {
594     case RESEARCH_IMAGE_EXPORT_TOOL_V3:
595       {
596       struct image_info_defV3 tempInfo;
597       struct image_info_defV3 tempInfo1;
598       float                   fovAP, fovFH, fovRL;
599       // Start at line 12 and work through PAR file.
600       // Line numbers are hard-coded on purpose.
601       strncpy( pPar->patient_name, this->GetGeneralInfoString(parFile, 12).c_str(),
602                sizeof( pPar->patient_name ) );
603       strncpy( pPar->exam_name, this->GetGeneralInfoString(parFile, 13).c_str(),
604                sizeof( pPar->exam_name ) );
605       strncpy( pPar->protocol_name, this->GetGeneralInfoString(parFile, 14).c_str(),
606                sizeof( pPar->protocol_name ) );
607       strncpy( pPar->exam_date, this->GetGeneralInfoString(parFile, 15).c_str(),
608                this->GetGeneralInfoString(parFile, 15).find("/") );
609       strncpy( pPar->exam_time,
610                this->GetGeneralInfoString(parFile, 15).substr(
611                  this->GetGeneralInfoString(parFile, 15).find("/") + 1).c_str(),
612                sizeof( pPar->exam_time ) );
613       inString.str( this->GetGeneralInfoString(parFile, 16) );
614       inString >> pPar->scno;
615       inString.clear();
616       inString.str( this->GetGeneralInfoString(parFile, 17) );
617       inString >> pPar->recno;
618       inString.clear();
619       inString.str( this->GetGeneralInfoString(parFile, 18) );
620       inString >> pPar->scan_duration;
621       inString.clear();
622       inString.str( this->GetGeneralInfoString(parFile, 19) );
623       inString >> pPar->cardiac_phases;
624       inString.clear();
625       inString.str( this->GetGeneralInfoString(parFile, 20) );
626       inString >> pPar->echoes;
627       inString.clear();
628       inString.str( this->GetGeneralInfoString(parFile, 21) );
629       inString >> pPar->slice;
630       inString.clear();
631       inString.str( this->GetGeneralInfoString(parFile, 22) );
632       inString >> pPar->dyn;
633       inString.clear();
634       inString.str( this->GetGeneralInfoString(parFile, 23) );
635       inString >> pPar->mixes;
636       inString.clear();
637       inString.str( this->GetGeneralInfoString(parFile, 24) );
638       inString >> pPar->bit;
639       inString.clear();
640       strncpy( pPar->technique, this->GetGeneralInfoString(parFile, 25).c_str(),
641                sizeof( pPar->technique ) );
642       strncpy( pPar->scan_mode, this->GetGeneralInfoString(parFile, 26).c_str(),
643                sizeof( pPar->scan_mode ) );
644       inString.str( this->GetGeneralInfoString(parFile, 27) );
645       inString >> pPar->scan_resolution[0];
646       inString >> pPar->scan_resolution[1];
647       inString.clear();
648       inString.str( this->GetGeneralInfoString(parFile, 28) );
649       inString >> pPar->scan_percent;
650       inString.clear();
651       inString.str( this->GetGeneralInfoString(parFile, 29) );
652       inString >> pPar->dim[0] >> pPar->dim[1];
653       pPar->dim[2] = pPar->slice;
654       inString.clear();
655       inString.str( this->GetGeneralInfoString(parFile, 30) );
656       inString >> pPar->num_averages;
657       inString.clear();
658       // It appears that the max number of mixes
659       // parameter indicates the number of experiment
660       // repititions.  This assumption is based on
661       // the T1 mapping images that use the look-locker
662       // sequence.
663       inString.str( this->GetGeneralInfoString(parFile, 31) );
664       for ( int repTime = 0; repTime < pPar->mixes; repTime++ )
665         {
666         inString >> pPar->repetition_time[repTime];
667         }
668       inString.clear();
669       tempInfo = GetImageInformationDefinitionV3(parFile, 89, this);
670       if ( tempInfo.problemreading )
671         {
672         std::ostringstream message;
673         message << "ReadPAR: Problem with GetImageInformationDefinitionV3()";
674         ExceptionObject exception(__FILE__, __LINE__,
675                                   message.str(),
676                                   ITK_LOCATION);
677         throw exception;
678         }
679       pPar->sliceorient = tempInfo.slice_orientation;
680       int echoNumber = tempInfo.echo;
681       pPar->echo_times[0] = tempInfo.echo_time;
682       int cardiacPhase = tempInfo.cardiac;
683       pPar->trigger_times[0] = tempInfo.trigger_time;
684       pPar->vox[0] = tempInfo.spacingx;
685       pPar->vox[1] = tempInfo.spacingy;
686       inString.str( this->GetGeneralInfoString(parFile, 32) );
687       inString >> fovAP >> fovFH >> fovRL;
688       inString.clear();
689       // slice orientation: transversal
690       if ( pPar->sliceorient == PAR_SLICE_ORIENTATION_TRANSVERSAL )
691         {
692         pPar->fov[0] = fovAP;
693         pPar->fov[1] = fovRL;
694         }
695       // slice orientation: sagittal
696       if ( pPar->sliceorient == PAR_SLICE_ORIENTATION_SAGITTAL )
697         {
698         pPar->fov[0] = fovFH;
699         pPar->fov[1] = fovAP;
700         }
701       // slice orientation: coronal
702       if ( pPar->sliceorient == PAR_SLICE_ORIENTATION_CORONAL )
703         {
704         pPar->fov[0] = fovRL;
705         pPar->fov[1] = fovFH;
706         }
707       inString.str( this->GetGeneralInfoString(parFile, 33) );
708       inString >> pPar->slth;
709       inString.clear();
710       inString.str( this->GetGeneralInfoString(parFile, 34) );
711       inString >> pPar->gap;
712       inString.clear();
713       pPar->fov[2] = ( pPar->gap + pPar->slth ) * pPar->slice;
714       pPar->vox[2] = pPar->slth + pPar->gap;
715       inString.str( this->GetGeneralInfoString(parFile, 35) );
716       inString >> pPar->water_fat_shift;
717       inString.clear();
718       inString.str( this->GetGeneralInfoString(parFile, 36) );
719       inString >> pPar->angAP;
720       inString >> pPar->angFH;
721       inString >> pPar->angRL;
722       inString.clear();
723       inString.str( this->GetGeneralInfoString(parFile, 37) );
724       inString >> pPar->offAP;
725       inString >> pPar->offFH;
726       inString >> pPar->offRL;
727       inString.clear();
728       inString.str( this->GetGeneralInfoString(parFile, 38) );
729       inString >> pPar->flow_comp;
730       inString.clear();
731       inString.str( this->GetGeneralInfoString(parFile, 39) );
732       inString >> pPar->presaturation;
733       inString.clear();
734       inString.str( this->GetGeneralInfoString(parFile, 40) );
735       inString >> pPar->cardiac_freq;
736       inString.clear();
737       inString.str( this->GetGeneralInfoString(parFile, 41) );
738       inString >> pPar->min_rr_int;
739       inString.clear();
740       inString.str( this->GetGeneralInfoString(parFile, 42) );
741       inString >> pPar->max_rr_int;
742       inString.clear();
743       inString.str( this->GetGeneralInfoString(parFile, 43) );
744       inString >> pPar->phase_encode_vel[0];
745       inString >> pPar->phase_encode_vel[1];
746       inString >> pPar->phase_encode_vel[2];
747       inString.clear();
748       inString.str( this->GetGeneralInfoString(parFile, 44) );
749       inString >> pPar->mtc;
750       inString.clear();
751       inString.str( this->GetGeneralInfoString(parFile, 45) );
752       inString >> pPar->spir;
753       inString.clear();
754       inString.str( this->GetGeneralInfoString(parFile, 46) );
755       inString >> pPar->epi;
756       inString.clear();
757       inString.str( this->GetGeneralInfoString(parFile, 47) );
758       inString >> pPar->turbo;
759       inString.clear();
760       inString.str( this->GetGeneralInfoString(parFile, 48) );
761       inString >> pPar->dynamic_scan;
762       inString.clear();
763       inString.str( this->GetGeneralInfoString(parFile, 49) );
764       inString >> pPar->diffusion;
765       inString.clear();
766       inString.str( this->GetGeneralInfoString(parFile, 50) );
767       inString >> pPar->diff_echo;
768       inString.clear();
769       inString.str( this->GetGeneralInfoString(parFile, 51) );
770       inString >> pPar->inversion_delay;
771       inString.clear();
772       // OK, need to figure out how many images are stored in the REC file
773       // and whether or not the images are sorted by slice or by image blocks.
774       // Also get echo times and trigger_times.
775       if ( pPar->slice > 1 )
776         {
777         int lineIncrement = 89;
778         int echoIndex = 0;
779         int cardiacIndex = 0;
780         tempInfo1 = GetImageInformationDefinitionV3(parFile, 90, this);
781         if ( tempInfo1.problemreading )
782           {
783           pPar->problemreading = 1;
784           std::ostringstream message;
785           message << "ReadPAR: Problem with GetImageInformationDefinitionV3()";
786           ExceptionObject exception(__FILE__, __LINE__,
787                                     message.str(),
788                                     ITK_LOCATION);
789           throw exception;
790           }
791         if ( ( tempInfo1.slice - tempInfo.slice ) > 0 )
792           {
793           pPar->slicessorted = 1;
794           }
795         // If slices are sorted I only need to calculate the number of
796         // image blocks (if more than 1) and store the echo times.
797         if ( pPar->slicessorted )
798           {
799           ++pPar->image_blocks;
800           ++pPar->num_image_types;
801           pPar->image_types[0] = tempInfo.image_type_mr;
802           ++pPar->num_scanning_sequences;
803           pPar->scanning_sequences[0] = tempInfo.scan_sequence;
804           lineIncrement += pPar->slice;
805           tempInfo1 = GetImageInformationDefinitionV3(parFile, lineIncrement, this);
806           while ( !tempInfo1.problemreading && tempInfo1.slice )
807             {
808             int isUnique = 1;
809             // Find unique image types in REC.
810             for ( int i = 0; i < pPar->num_image_types; i++ )
811               {
812               if ( pPar->image_types[i] == tempInfo1.image_type_mr )
813                 {
814                 isUnique = 0;
815                 break;
816                 }
817               }
818             if ( isUnique )
819               {
820               ++pPar->num_image_types;
821               pPar->image_types[pPar->num_image_types - 1] =
822                 tempInfo1.image_type_mr;
823               }
824             isUnique = 1;
825             // Find all of the scanning sequences.
826             for ( int i = 0; i < pPar->num_scanning_sequences; i++ )
827               {
828               if ( pPar->scanning_sequences[i] == tempInfo1.scan_sequence )
829                 {
830                 isUnique = 0;
831                 break;
832                 }
833               }
834             if ( isUnique )
835               {
836               ++pPar->num_scanning_sequences;
837               pPar->scanning_sequences[pPar->num_scanning_sequences - 1] =
838                 tempInfo1.scan_sequence;
839               }
840             ++pPar->image_blocks;
841             lineIncrement += pPar->slice;
842             // Get the echo times.
843             if ( echoNumber != tempInfo1.echo )
844               {
845               ++echoIndex;
846               pPar->echo_times[echoIndex] = tempInfo1.echo_time;
847               echoNumber = tempInfo1.echo;
848               }
849             // Get the trigger times
850             if ( (cardiacIndex < (pPar->cardiac_phases-1)) &&
851               (cardiacPhase != tempInfo1.cardiac) )
852               {
853               ++cardiacIndex;
854               pPar->trigger_times[cardiacIndex] = tempInfo1.trigger_time;
855               cardiacPhase = tempInfo1.cardiac;
856               }
857             tempInfo1 = GetImageInformationDefinitionV3(parFile, lineIncrement, this);
858             }
859           }
860         // Slices are not sorted.
861         else
862           {
863           int slice = tempInfo.slice;
864           ++pPar->image_blocks;
865           ++pPar->num_image_types;
866           pPar->image_types[0] = tempInfo.image_type_mr;
867           ++pPar->num_scanning_sequences;
868           pPar->scanning_sequences[0] = tempInfo.scan_sequence;
869           ++lineIncrement;
870           tempInfo1 = GetImageInformationDefinitionV3(parFile, lineIncrement, this);
871           while ( !tempInfo1.problemreading && tempInfo1.slice )
872             {
873             if ( slice == tempInfo1.slice )
874               {
875               int isUnique = 1;
876               // Find unique image types in REC.
877               for ( int i = 0; i < pPar->num_image_types; i++ )
878                 {
879                 if ( pPar->image_types[i] == tempInfo1.image_type_mr )
880                   {
881                   isUnique = 0;
882                   break;
883                   }
884                 }
885               if ( isUnique )
886                 {
887                 ++pPar->num_image_types;
888                 pPar->image_types[pPar->num_image_types - 1] =
889                   tempInfo1.image_type_mr;
890                 }
891               isUnique = 1;
892               // Find all of the scanning sequences.
893               for ( int i = 0; i < pPar->num_scanning_sequences; i++ )
894                 {
895                 if ( pPar->scanning_sequences[i] == tempInfo1.scan_sequence )
896                   {
897                   isUnique = 0;
898                   break;
899                   }
900                 }
901               if ( isUnique )
902                 {
903                 ++pPar->num_scanning_sequences;
904                 pPar->scanning_sequences[pPar->num_scanning_sequences - 1] =
905                   tempInfo1.scan_sequence;
906                 }
907               ++pPar->image_blocks;
908               // Get the echo times.
909               if ( echoNumber != tempInfo1.echo )
910                 {
911                 ++echoIndex;
912                 pPar->echo_times[echoIndex] = tempInfo1.echo_time;
913                 echoNumber = tempInfo1.echo;
914                 }
915               // Get the trigger times
916               if ( (cardiacIndex < (pPar->cardiac_phases-1)) &&
917                 (cardiacPhase != tempInfo1.cardiac) )
918                 {
919                 ++cardiacIndex;
920                 pPar->trigger_times[cardiacIndex] = tempInfo1.trigger_time;
921                 cardiacPhase = tempInfo1.cardiac;
922                 }
923               }
924             else
925               {
926               lineIncrement = 89;
927               // OK, I need to determine if there are more image blocks, only
928               // if pPar->num_image_types or pPar->num_scanning_sequences > 1
929               if ( ( pPar->num_image_types > 1 )
930                    || ( pPar->num_scanning_sequences > 1 ) )
931                 {
932                 pPar->num_slice_repetitions = pPar->image_blocks;
933                 lineIncrement += ( pPar->slice * pPar->num_slice_repetitions );
934                 tempInfo1 = GetImageInformationDefinitionV3(parFile,
935                                                             lineIncrement, this);
936                 while ( !tempInfo1.problemreading && tempInfo1.slice )
937                   {
938                   // Get the echo times.
939                   if ( echoNumber != tempInfo1.echo )
940                     {
941                     ++echoIndex;
942                     pPar->echo_times[echoIndex] = tempInfo1.echo_time;
943                     echoNumber = tempInfo1.echo;
944                     }
945                   // Get the trigger times
946                   if ( (cardiacIndex < (pPar->cardiac_phases-1)) &&
947                     (cardiacPhase != tempInfo1.cardiac) )
948                     {
949                     ++cardiacIndex;
950                     pPar->trigger_times[cardiacIndex] = tempInfo1.trigger_time;
951                     cardiacPhase = tempInfo1.cardiac;
952                     }
953                   pPar->image_blocks += pPar->num_slice_repetitions;
954                   lineIncrement += ( pPar->slice * pPar->num_slice_repetitions );
955                   tempInfo1 = GetImageInformationDefinitionV3(parFile,
956                                                               lineIncrement, this);
957                   }
958                 }
959               break;
960               }
961             ++lineIncrement;
962             tempInfo1 = GetImageInformationDefinitionV3(parFile, lineIncrement, this);
963             }
964           }
965         // This is a sanity check.  The echoIndex should match
966         // (pPar->echoes-1).
967         if ( ( pPar->echoes - 1 ) != echoIndex )
968           {
969           pPar->problemreading = 1;
970           std::ostringstream message;
971           message << "ReadPAR: (pPar->echoes-1) != echoIndex, "
972                   << "pPar->echoes-1 = " << pPar->echoes - 1
973                   << " and echoIndex = " << echoIndex;
974           ExceptionObject exception(__FILE__, __LINE__,
975                                     message.str(),
976                                     ITK_LOCATION);
977           throw exception;
978           }
979         // Another sanity check.  The cardiacIndex should match
980         // (pPar->cardiac_phases-1).
981         if ( ( pPar->cardiac_phases - 1 ) != cardiacIndex )
982           {
983           pPar->problemreading = 1;
984           std::ostringstream message;
985           message << "ReadPAR: (pPar->cardiac_phases-1) != cardiacIndex, "
986                   << "pPar->cardiac_phases-1 = " << pPar->cardiac_phases - 1
987                   << " and cardiacIndex = " << cardiacIndex;
988           ExceptionObject exception(__FILE__, __LINE__,
989                                     message.str(),
990                                     ITK_LOCATION);
991           throw exception;
992           }
993         }
994       // Only 1 slice, but how many repetitions of that slice?
995       else
996         {
997         int lineIncrement = 89;
998         int echoIndex = 0;
999         int cardiacIndex = 0;
1000         int slice = tempInfo.slice;
1001         int firstEchoNumber = echoNumber;
1002         int firstCardiacPhase = cardiacPhase;
1003         int firstDynamic = tempInfo.dynamic;
1004         ++pPar->image_blocks;
1005         ++pPar->num_image_types;
1006         pPar->image_types[0] = tempInfo.image_type_mr;
1007         ++pPar->num_scanning_sequences;
1008         pPar->scanning_sequences[0] = tempInfo.scan_sequence;
1009         ++lineIncrement;
1010         tempInfo1 = GetImageInformationDefinitionV3(parFile, lineIncrement, this);
1011         while ( !tempInfo1.problemreading && tempInfo1.slice )
1012           {
1013           if ( slice == tempInfo1.slice )
1014             {
1015             int isUnique = 1;
1016             // Find unique image types in REC.
1017             for ( int i = 0; i < pPar->num_image_types; i++ )
1018               {
1019               if ( pPar->image_types[i] == tempInfo1.image_type_mr )
1020                 {
1021                 isUnique = 0;
1022                 break;
1023                 }
1024               }
1025             if ( isUnique )
1026               {
1027               ++pPar->num_image_types;
1028               pPar->image_types[pPar->num_image_types - 1] =
1029                 tempInfo1.image_type_mr;
1030               }
1031             isUnique = 1;
1032             // Find all of the scanning sequences.
1033             for ( int i = 0; i < pPar->num_scanning_sequences; i++ )
1034               {
1035               if ( pPar->scanning_sequences[i] == tempInfo1.scan_sequence )
1036                 {
1037                 isUnique = 0;
1038                 break;
1039                 }
1040               }
1041             if ( isUnique )
1042               {
1043               ++pPar->num_scanning_sequences;
1044               pPar->scanning_sequences[pPar->num_scanning_sequences - 1] =
1045                 tempInfo1.scan_sequence;
1046               }
1047             ++pPar->image_blocks;
1048             // Get the echo times.
1049             if ( echoNumber != tempInfo1.echo )
1050               {
1051               ++echoIndex;
1052               pPar->echo_times[echoIndex] = tempInfo1.echo_time;
1053               echoNumber = tempInfo1.echo;
1054               }
1055             // Get the trigger times
1056             if ( (cardiacIndex < (pPar->cardiac_phases-1)) &&
1057               (cardiacPhase != tempInfo1.cardiac) )
1058               {
1059               ++cardiacIndex;
1060               pPar->trigger_times[cardiacIndex] = tempInfo1.trigger_time;
1061               cardiacPhase = tempInfo1.cardiac;
1062               }
1063             // Need to keep track of the number of consecutive slice
1064             // repetitions.
1065             if ( ( pPar->echoes > 1 ) && ( firstEchoNumber == tempInfo1.echo ) )
1066               {
1067               ++pPar->num_slice_repetitions;
1068               }
1069             if ( ( pPar->cardiac_phases > 1 )
1070                  && ( firstCardiacPhase == tempInfo1.cardiac ) )
1071               {
1072               ++pPar->num_slice_repetitions;
1073               }
1074             if ( ( pPar->dyn > 1 ) && ( firstDynamic == tempInfo1.dynamic ) )
1075               {
1076               ++pPar->num_slice_repetitions;
1077               }
1078             }
1079           else
1080             {
1081             break;
1082             }
1083           ++lineIncrement;
1084           tempInfo1 = GetImageInformationDefinitionV3(parFile, lineIncrement, this);
1085           }
1086         // This is a sanity check.  The echoIndex should match
1087         // (pPar->echoes-1).
1088         if ( ( pPar->echoes - 1 ) != echoIndex )
1089           {
1090           pPar->problemreading = 1;
1091           std::ostringstream message;
1092           message << "ReadPAR: (pPar->echoes-1) != echoIndex, "
1093                   << "pPar->echoes-1 = " << pPar->echoes - 1
1094                   << " and echoIndex = " << echoIndex;
1095           ExceptionObject exception(__FILE__, __LINE__,
1096                                     message.str(),
1097                                     ITK_LOCATION);
1098           throw exception;
1099           }
1100         // Another sanity check.  The cardiacIndex should match
1101         // (pPar->cardiac_phases-1).
1102         if ( ( pPar->cardiac_phases - 1 ) != cardiacIndex )
1103           {
1104           pPar->problemreading = 1;
1105           std::ostringstream message;
1106           message << "ReadPAR: (pPar->cardiac_phases-1) != cardiacIndex, "
1107                   << "pPar->cardiac_phases-1 = " << pPar->cardiac_phases - 1
1108                   << " and cardiacIndex = " << cardiacIndex;
1109           ExceptionObject exception(__FILE__, __LINE__,
1110                                     message.str(),
1111                                     ITK_LOCATION);
1112           throw exception;
1113           }
1114         }
1115       }
1116       break;
1117 
1118     case RESEARCH_IMAGE_EXPORT_TOOL_V4:
1119     case RESEARCH_IMAGE_EXPORT_TOOL_V4_1:
1120     case RESEARCH_IMAGE_EXPORT_TOOL_V4_2:
1121       {
1122       struct image_info_defV4 tempInfo;
1123       struct image_info_defV4 tempInfo1;
1124       float                   fovAP, fovFH, fovRL;
1125       // Start at line 12 and work through PAR file.
1126       // Line numbers are hard-coded on purpose.
1127       strncpy( pPar->patient_name, this->GetGeneralInfoString(parFile, 12).c_str(),
1128                sizeof( pPar->patient_name ) );
1129       strncpy( pPar->exam_name, this->GetGeneralInfoString(parFile, 13).c_str(),
1130                sizeof( pPar->exam_name ) );
1131       strncpy( pPar->protocol_name, this->GetGeneralInfoString(parFile, 14).c_str(),
1132                sizeof( pPar->protocol_name ) );
1133       strncpy( pPar->exam_date,
1134                this->GetGeneralInfoString(parFile, 15).c_str(),
1135                this->GetGeneralInfoString(parFile, 15).find("/") );
1136       strncpy( pPar->exam_time,
1137                this->GetGeneralInfoString(parFile, 15).substr(
1138                  this->GetGeneralInfoString(parFile, 15).find("/") + 1).c_str(),
1139                sizeof( pPar->exam_time ) );
1140       strncpy( pPar->series_type, this->GetGeneralInfoString(parFile, 16).c_str(),
1141                sizeof( pPar->series_type ) );
1142       inString.str( this->GetGeneralInfoString(parFile, 17) );
1143       inString >> pPar->scno;
1144       inString.clear();
1145       inString.str( this->GetGeneralInfoString(parFile, 18) );
1146       inString >> pPar->recno;
1147       inString.clear();
1148       inString.str( this->GetGeneralInfoString(parFile, 19) );
1149       inString >> pPar->scan_duration;
1150       inString.clear();
1151       inString.str( this->GetGeneralInfoString(parFile, 20) );
1152       inString >> pPar->cardiac_phases;
1153       inString.clear();
1154       inString.str( this->GetGeneralInfoString(parFile, 21) );
1155       inString >> pPar->echoes;
1156       inString.clear();
1157       inString.str( this->GetGeneralInfoString(parFile, 22) );
1158       inString >> pPar->slice;
1159       inString.clear();
1160       inString.str( this->GetGeneralInfoString(parFile, 23) );
1161       inString >> pPar->dyn;
1162       inString.clear();
1163       inString.str( this->GetGeneralInfoString(parFile, 24) );
1164       inString >> pPar->mixes;
1165       inString.clear();
1166       strncpy( pPar->patient_position, this->GetGeneralInfoString(parFile, 25).c_str(),
1167                sizeof( pPar->patient_position ) );
1168       strncpy( pPar->prep_direction, this->GetGeneralInfoString(parFile, 26).c_str(),
1169                sizeof( pPar->prep_direction ) );
1170       strncpy( pPar->technique, this->GetGeneralInfoString(parFile, 27).c_str(),
1171                sizeof( pPar->technique ) );
1172       inString.str( this->GetGeneralInfoString(parFile, 28) );
1173       inString >> pPar->scan_resolution[0];
1174       inString >> pPar->scan_resolution[1];
1175       inString.clear();
1176       inString.str( this->GetGeneralInfoString(parFile, 29) );
1177       inString >> pPar->scan_mode;
1178       inString.clear();
1179       // It appears that the max number of mixes
1180       // parameter indicates the number of experiment
1181       // repititions.  This assumption is based on
1182       // the T1 mapping images that use the look-locker
1183       // sequence.
1184       inString.str( this->GetGeneralInfoString(parFile, 30) );
1185       for ( int repTime = 0; repTime < pPar->mixes; repTime++ )
1186         {
1187         inString >> pPar->repetition_time[repTime];
1188         }
1189       inString.clear();
1190       switch ( pPar->ResToolsVersion )
1191         {
1192         case RESEARCH_IMAGE_EXPORT_TOOL_V4:
1193           tempInfo = GetImageInformationDefinitionV4(parFile, 92, this);
1194           break;
1195         case RESEARCH_IMAGE_EXPORT_TOOL_V4_1:
1196           tempInfo = GetImageInformationDefinitionV41(parFile, 99, this);
1197           break;
1198         case RESEARCH_IMAGE_EXPORT_TOOL_V4_2:
1199           tempInfo = GetImageInformationDefinitionV42(parFile, 101, this);
1200           break;
1201         }
1202       if ( tempInfo.problemreading )
1203         {
1204         pPar->problemreading = 1;
1205         std::ostringstream message;
1206         message << "ReadPAR: Problem with GetImageInformationDefinitionV4()";
1207         ExceptionObject exception(__FILE__, __LINE__,
1208                                   message.str(),
1209                                   ITK_LOCATION);
1210         throw exception;
1211         }
1212       pPar->sliceorient = tempInfo.slice_orientation;
1213       int echoNumber = tempInfo.echo;
1214       pPar->echo_times[0] = tempInfo.echo_time;
1215       int cardiacPhase = tempInfo.cardiac;
1216       pPar->trigger_times[0] = tempInfo.trigger_time;
1217       pPar->dim[0] = tempInfo.recon_dimx;
1218       pPar->dim[1] = tempInfo.recon_dimy;
1219       pPar->dim[2] = pPar->slice;
1220       pPar->bit = tempInfo.image_bits;
1221       pPar->slth = tempInfo.slice_thick;
1222       pPar->gap = tempInfo.slice_gap;
1223       pPar->vox[0] = tempInfo.spacingx;
1224       pPar->vox[1] = tempInfo.spacingy;
1225       pPar->vox[2] = tempInfo.slice_thick + tempInfo.slice_gap;
1226       inString.str( this->GetGeneralInfoString(parFile, 31) );
1227       inString >> fovAP >> fovFH >> fovRL;
1228       inString.clear();
1229       // slice orientation: transversal
1230       if ( pPar->sliceorient == PAR_SLICE_ORIENTATION_TRANSVERSAL )
1231         {
1232         pPar->fov[0] = fovAP;
1233         pPar->fov[1] = fovRL;
1234         }
1235       // slice orientation: sagittal
1236       if ( pPar->sliceorient == PAR_SLICE_ORIENTATION_SAGITTAL )
1237         {
1238         pPar->fov[0] = fovFH;
1239         pPar->fov[1] = fovAP;
1240         }
1241       // slice orientation: coronal
1242       if ( pPar->sliceorient == PAR_SLICE_ORIENTATION_CORONAL )
1243         {
1244         pPar->fov[0] = fovRL;
1245         pPar->fov[1] = fovFH;
1246         }
1247       pPar->fov[2] = ( pPar->gap + pPar->slth ) * pPar->slice;
1248       inString.str( this->GetGeneralInfoString(parFile, 32) );
1249       inString >> pPar->water_fat_shift;
1250       inString.clear();
1251       inString.str( this->GetGeneralInfoString(parFile, 33) );
1252       inString >> pPar->angAP;
1253       inString >> pPar->angFH;
1254       inString >> pPar->angRL;
1255       inString.clear();
1256       inString.str( this->GetGeneralInfoString(parFile, 34) );
1257       inString >> pPar->offAP;
1258       inString >> pPar->offFH;
1259       inString >> pPar->offRL;
1260       inString.clear();
1261       inString.str( this->GetGeneralInfoString(parFile, 35) );
1262       inString >> pPar->flow_comp;
1263       inString.clear();
1264       inString.str( this->GetGeneralInfoString(parFile, 36) );
1265       inString >> pPar->presaturation;
1266       inString.clear();
1267       inString.str( this->GetGeneralInfoString(parFile, 37) );
1268       inString >> pPar->phase_encode_vel[0];
1269       inString >> pPar->phase_encode_vel[1];
1270       inString >> pPar->phase_encode_vel[2];
1271       inString.clear();
1272       inString.str( this->GetGeneralInfoString(parFile, 38) );
1273       inString >> pPar->mtc;
1274       inString.clear();
1275       inString.str( this->GetGeneralInfoString(parFile, 39) );
1276       inString >> pPar->spir;
1277       inString.clear();
1278       inString.str( this->GetGeneralInfoString(parFile, 40) );
1279       inString >> pPar->epi;
1280       inString.clear();
1281       inString.str( this->GetGeneralInfoString(parFile, 41) );
1282       inString >> pPar->dynamic_scan;
1283       inString.clear();
1284       inString.str( this->GetGeneralInfoString(parFile, 42) );
1285       inString >> pPar->diffusion;
1286       inString.clear();
1287       inString.str( this->GetGeneralInfoString(parFile, 43) );
1288       inString >> pPar->diff_echo;
1289       inString.clear();
1290       // Versions >= 4.1
1291       if ( pPar->ResToolsVersion >= RESEARCH_IMAGE_EXPORT_TOOL_V4_1 )
1292         {
1293         inString.str( this->GetGeneralInfoString(parFile, 44) );
1294         inString >> pPar->max_num_diff_vals;
1295         inString.clear();
1296         inString.str( this->GetGeneralInfoString(parFile, 45) );
1297         inString >> pPar->max_num_grad_orient;
1298         inString.clear();
1299         }
1300       // Version 4.2 only
1301       if ( pPar->ResToolsVersion == RESEARCH_IMAGE_EXPORT_TOOL_V4_2 )
1302         {
1303         inString.str( this->GetGeneralInfoString(parFile, 46) );
1304         inString >> pPar->num_label_types;
1305         inString.clear();
1306         }
1307       // OK, need to figure out how many images are stored in the REC file
1308       // and whether or not the images are sorted by slice or by image blocks.
1309       // Also get echo times.
1310       if ( pPar->slice > 1 )
1311         {
1312         int lineIncrement = 92;
1313         int echoIndex = 0;
1314         int cardiacIndex = 0;
1315         switch ( pPar->ResToolsVersion )
1316           {
1317           case RESEARCH_IMAGE_EXPORT_TOOL_V4:
1318             tempInfo1 = GetImageInformationDefinitionV4(parFile, 93, this);
1319             break;
1320           case RESEARCH_IMAGE_EXPORT_TOOL_V4_1:
1321             lineIncrement = 99;
1322             tempInfo1 = GetImageInformationDefinitionV41(parFile, 100, this);
1323             break;
1324           case RESEARCH_IMAGE_EXPORT_TOOL_V4_2:
1325             lineIncrement = 101;
1326             tempInfo1 = GetImageInformationDefinitionV42(parFile, 102, this);
1327             break;
1328           }
1329         if ( tempInfo1.problemreading )
1330           {
1331           pPar->problemreading = 1;
1332           std::ostringstream message;
1333           message << "ReadPAR: Problem with GetImageInformationV4()";
1334           ExceptionObject exception(__FILE__, __LINE__,
1335                                     message.str(),
1336                                     ITK_LOCATION);
1337           throw exception;
1338           }
1339         if ( ( tempInfo1.slice - tempInfo.slice ) > 0 )
1340           {
1341           pPar->slicessorted = 1;
1342           }
1343         // If slices are sorted I only need to calculate the number of
1344         // image blocks (if more than 1) and store the echo times.
1345         if ( pPar->slicessorted )
1346           {
1347           ++pPar->image_blocks;
1348           ++pPar->num_image_types;
1349           pPar->image_types[0] = tempInfo.image_type_mr;
1350           ++pPar->num_scanning_sequences;
1351           pPar->scanning_sequences[0] = tempInfo.scan_sequence;
1352           lineIncrement += pPar->slice;
1353           // lineIncrement is set according to version 4.x PAR file.
1354           tempInfo1 = GetImageInformationDefinitionV4(parFile, lineIncrement, this);
1355           while ( !tempInfo1.problemreading && tempInfo1.slice )
1356             {
1357             int isUnique = 1;
1358             // Find unique image types in REC.
1359             for ( int i = 0; i < pPar->num_image_types; i++ )
1360               {
1361               if ( pPar->image_types[i] == tempInfo1.image_type_mr )
1362                 {
1363                 isUnique = 0;
1364                 break;
1365                 }
1366               }
1367             if ( isUnique )
1368               {
1369               ++pPar->num_image_types;
1370               pPar->image_types[pPar->num_image_types - 1] =
1371                 tempInfo1.image_type_mr;
1372               }
1373             isUnique = 1;
1374             // Find all of the scanning sequences.
1375             for ( int i = 0; i < pPar->num_scanning_sequences; i++ )
1376               {
1377               if ( pPar->scanning_sequences[i] == tempInfo1.scan_sequence )
1378                 {
1379                 isUnique = 0;
1380                 break;
1381                 }
1382               }
1383             if ( isUnique )
1384               {
1385               ++pPar->num_scanning_sequences;
1386               pPar->scanning_sequences[pPar->num_scanning_sequences - 1] =
1387                 tempInfo1.scan_sequence;
1388               }
1389             ++pPar->image_blocks;
1390             // Get the echo times.
1391             if ( echoNumber != tempInfo1.echo )
1392               {
1393               ++echoIndex;
1394               pPar->echo_times[echoIndex] = tempInfo1.echo_time;
1395               echoNumber = tempInfo1.echo;
1396               }
1397             // Get the trigger times
1398             if ( (cardiacIndex < (pPar->cardiac_phases-1)) &&
1399               (cardiacPhase != tempInfo1.cardiac) )
1400               {
1401               ++cardiacIndex;
1402               pPar->trigger_times[cardiacIndex] = tempInfo1.trigger_time;
1403               cardiacPhase = tempInfo1.cardiac;
1404               }
1405             lineIncrement += pPar->slice;
1406             // lineIncrement is set according to version 4.x PAR file.
1407             tempInfo1 = GetImageInformationDefinitionV4(parFile, lineIncrement, this);
1408             }
1409           }
1410         // Slices are not sorted.
1411         else
1412           {
1413           int slice = tempInfo.slice;
1414           ++pPar->image_blocks;
1415           ++pPar->num_image_types;
1416           pPar->image_types[0] = tempInfo.image_type_mr;
1417           ++pPar->num_scanning_sequences;
1418           pPar->scanning_sequences[0] = tempInfo.scan_sequence;
1419           ++lineIncrement;
1420           // lineIncrement is set according to version 4.x PAR file.
1421           tempInfo1 = GetImageInformationDefinitionV4(parFile, lineIncrement, this);
1422           while ( !tempInfo1.problemreading && tempInfo1.slice )
1423             {
1424             // This if statement applies to just the first slice.
1425             if ( slice == tempInfo1.slice )
1426               {
1427               // Find unique image types in REC.
1428               int isUnique = 1;
1429               for ( int i = 0; i < pPar->num_image_types; i++ )
1430                 {
1431                 if ( pPar->image_types[i] == tempInfo1.image_type_mr )
1432                   {
1433                   isUnique = 0;
1434                   break;
1435                   }
1436                 }
1437               if ( isUnique )
1438                 {
1439                 ++pPar->num_image_types;
1440                 pPar->image_types[pPar->num_image_types - 1] =
1441                   tempInfo1.image_type_mr;
1442                 }
1443               isUnique = 1;
1444               // Find all of the scanning sequences.
1445               for ( int i = 0; i < pPar->num_scanning_sequences; i++ )
1446                 {
1447                 if ( pPar->scanning_sequences[i] == tempInfo1.scan_sequence )
1448                   {
1449                   isUnique = 0;
1450                   break;
1451                   }
1452                 }
1453               if ( isUnique )
1454                 {
1455                 ++pPar->num_scanning_sequences;
1456                 pPar->scanning_sequences[pPar->num_scanning_sequences - 1] =
1457                   tempInfo1.scan_sequence;
1458                 }
1459               ++pPar->image_blocks;
1460               // Get the echo times.
1461               if ( echoNumber != tempInfo1.echo )
1462                 {
1463                 ++echoIndex;
1464                 pPar->echo_times[echoIndex] = tempInfo1.echo_time;
1465                 echoNumber = tempInfo1.echo;
1466                 }
1467               // Get the trigger times
1468               if ( (cardiacIndex < (pPar->cardiac_phases-1)) &&
1469                 (cardiacPhase != tempInfo1.cardiac) )
1470                 {
1471                 ++cardiacIndex;
1472                 pPar->trigger_times[cardiacIndex] = tempInfo1.trigger_time;
1473                 cardiacPhase = tempInfo1.cardiac;
1474                 }
1475               }
1476             // Now we have sufficient information to parse the rest of the PAR
1477             // file.
1478             else
1479               {
1480               switch ( pPar->ResToolsVersion )
1481                 {
1482                 case RESEARCH_IMAGE_EXPORT_TOOL_V4:
1483                   lineIncrement = 92;
1484                   break;
1485                 case RESEARCH_IMAGE_EXPORT_TOOL_V4_1:
1486                   lineIncrement = 99;
1487                   break;
1488                 case RESEARCH_IMAGE_EXPORT_TOOL_V4_2:
1489                   lineIncrement = 101;
1490                   break;
1491                 }
1492               // OK, I need to determine if there are more image blocks, only
1493               // if pPar->num_image_types or pPar->num_scanning_sequences > 1
1494               if ( ( pPar->num_image_types > 1 )
1495                    || ( pPar->num_scanning_sequences > 1 ) )
1496                 {
1497                 pPar->num_slice_repetitions = pPar->image_blocks;
1498                 lineIncrement += ( pPar->slice * pPar->num_slice_repetitions );
1499                 // lineIncrement is set according to version 4.x PAR file.
1500                 tempInfo1 = GetImageInformationDefinitionV4(parFile,
1501                                                             lineIncrement, this);
1502                 while ( !tempInfo1.problemreading && tempInfo1.slice )
1503                   {
1504                   // Get the echo times.
1505                   if ( echoNumber != tempInfo1.echo )
1506                     {
1507                     ++echoIndex;
1508                     pPar->echo_times[echoIndex] = tempInfo1.echo_time;
1509                     echoNumber = tempInfo1.echo;
1510                     }
1511                   // Get the trigger times
1512                   if ( (cardiacIndex < (pPar->cardiac_phases-1)) &&
1513                     (cardiacPhase != tempInfo1.cardiac) )
1514                     {
1515                     ++cardiacIndex;
1516                     pPar->trigger_times[cardiacIndex] = tempInfo1.trigger_time;
1517                     cardiacPhase = tempInfo1.cardiac;
1518                     }
1519                   pPar->image_blocks += pPar->num_slice_repetitions;
1520                   lineIncrement += ( pPar->slice * pPar->num_slice_repetitions );
1521                   tempInfo1 = GetImageInformationDefinitionV4(parFile,
1522                                                               lineIncrement, this);
1523                   }
1524                 }
1525               break;
1526               }
1527             ++lineIncrement;
1528             tempInfo1 = GetImageInformationDefinitionV4(parFile, lineIncrement, this);
1529             }
1530           }
1531         // This is a sanity check.  The echoIndex should match
1532         // (pPar->echoes-1).
1533         if ( ( pPar->echoes - 1 ) != echoIndex )
1534           {
1535           pPar->problemreading = 1;
1536           std::ostringstream message;
1537           message << "ReadPAR: (pPar->echoes-1) != echoIndex, "
1538                   << "pPar->echoes-1 = " << pPar->echoes - 1
1539                   << " and echoIndex = " << echoIndex;
1540           ExceptionObject exception(__FILE__, __LINE__,
1541                                     message.str(),
1542                                     ITK_LOCATION);
1543           throw exception;
1544           }
1545         // Another sanity check.  The cardiacIndex should match
1546         // (pPar->cardiac_phases-1).
1547         if ( ( pPar->cardiac_phases - 1 ) != cardiacIndex )
1548           {
1549           pPar->problemreading = 1;
1550           std::ostringstream message;
1551           message << "ReadPAR: (pPar->cardiac_phases-1) != cardiacIndex, "
1552                   << "pPar->cardiac_phases-1 = " << pPar->cardiac_phases - 1
1553                   << " and cardiacIndex = " << cardiacIndex;
1554           ExceptionObject exception(__FILE__, __LINE__,
1555                                     message.str(),
1556                                     ITK_LOCATION);
1557           throw exception;
1558           }
1559         }
1560       // Only 1 slice, but how many repetitions of that slice?
1561       else
1562         {
1563         int lineIncrement = 92;
1564         int echoIndex = 0;
1565         int cardiacIndex = 0;
1566         int slice = tempInfo.slice;
1567         int firstEchoNumber = echoNumber;
1568         int firstCardiacPhase = cardiacPhase;
1569         int firstDynamic = tempInfo.dynamic;
1570         ++pPar->image_blocks;
1571         ++pPar->num_image_types;
1572         pPar->image_types[0] = tempInfo.image_type_mr;
1573         ++pPar->num_scanning_sequences;
1574         pPar->scanning_sequences[0] = tempInfo.scan_sequence;
1575         switch ( pPar->ResToolsVersion )
1576           {
1577           case RESEARCH_IMAGE_EXPORT_TOOL_V4_1:
1578             lineIncrement = 99;
1579             break;
1580           case RESEARCH_IMAGE_EXPORT_TOOL_V4_2:
1581             lineIncrement = 101;
1582             break;
1583           }
1584         ++lineIncrement;
1585         tempInfo1 = GetImageInformationDefinitionV4(parFile, lineIncrement, this);
1586         while ( !tempInfo1.problemreading && tempInfo1.slice )
1587           {
1588           if ( slice == tempInfo1.slice )
1589             {
1590             int isUnique = 1;
1591             // Find unique image types in REC.
1592             for ( int i = 0; i < pPar->num_image_types; i++ )
1593               {
1594               if ( pPar->image_types[i] == tempInfo1.image_type_mr )
1595                 {
1596                 isUnique = 0;
1597                 break;
1598                 }
1599               }
1600             if ( isUnique )
1601               {
1602               ++pPar->num_image_types;
1603               pPar->image_types[pPar->num_image_types - 1] =
1604                 tempInfo1.image_type_mr;
1605               }
1606             isUnique = 1;
1607             // Find all of the scanning sequences.
1608             for ( int i = 0; i < pPar->num_scanning_sequences; i++ )
1609               {
1610               if ( pPar->scanning_sequences[i] == tempInfo1.scan_sequence )
1611                 {
1612                 isUnique = 0;
1613                 break;
1614                 }
1615               }
1616             if ( isUnique )
1617               {
1618               ++pPar->num_scanning_sequences;
1619               pPar->scanning_sequences[pPar->num_scanning_sequences - 1] =
1620                 tempInfo1.scan_sequence;
1621               }
1622             ++pPar->image_blocks;
1623             // Should be equal after the first iteration, but will only
1624             // add additional echoes in latter iterations if they differ
1625             // from the first.
1626             if ( echoNumber != tempInfo1.echo )
1627               {
1628               ++echoIndex;
1629               pPar->echo_times[echoIndex] = tempInfo1.echo_time;
1630               echoNumber = tempInfo1.echo;
1631               }
1632             // Get the trigger times
1633             if ( (cardiacIndex < (pPar->cardiac_phases-1)) &&
1634               (cardiacPhase != tempInfo1.cardiac) )
1635               {
1636               ++cardiacIndex;
1637               pPar->trigger_times[cardiacIndex] = tempInfo1.trigger_time;
1638               cardiacPhase = tempInfo1.cardiac;
1639               }
1640             // Need to keep track of the number of consecutive slice
1641             // repetitions.
1642             if ( ( pPar->echoes > 1 ) && ( firstEchoNumber == tempInfo1.echo ) )
1643               {
1644               ++pPar->num_slice_repetitions;
1645               }
1646             if ( ( pPar->cardiac_phases > 1 )
1647                  && ( firstCardiacPhase == tempInfo1.cardiac ) )
1648               {
1649               ++pPar->num_slice_repetitions;
1650               }
1651             if ( ( pPar->dyn > 1 ) && ( firstDynamic == tempInfo1.dynamic ) )
1652               {
1653               ++pPar->num_slice_repetitions;
1654               }
1655             }
1656           else
1657             {
1658             break;
1659             }
1660           ++lineIncrement;
1661           tempInfo1 = GetImageInformationDefinitionV4(parFile, lineIncrement, this);
1662           }
1663         // This is a sanity check.  The echoIndex should match
1664         // (pPar->echoes-1).
1665         if ( ( pPar->echoes - 1 ) != echoIndex )
1666           {
1667           pPar->problemreading = 1;
1668           std::ostringstream message;
1669           message << "ReadPAR: (pPar->echoes-1) != echoIndex, "
1670                   << "pPar->echoes-1 = " << pPar->echoes - 1
1671                   << " and echoIndex = " << echoIndex;
1672           ExceptionObject exception(__FILE__, __LINE__,
1673                                     message.str(),
1674                                     ITK_LOCATION);
1675           throw exception;
1676           }
1677         // Another sanity check.  The cardiacIndex should match
1678         // (pPar->cardiac_phases-1).
1679         if ( ( pPar->cardiac_phases - 1 ) != cardiacIndex )
1680           {
1681           pPar->problemreading = 1;
1682           std::ostringstream message;
1683           message << "ReadPAR: (pPar->cardiac_phases-1) != cardiacIndex, "
1684                   << "pPar->cardiac_phases-1 = " << pPar->cardiac_phases - 1
1685                   << " and cardiacIndex = " << cardiacIndex;
1686           ExceptionObject exception(__FILE__, __LINE__,
1687                                     message.str(),
1688                                     ITK_LOCATION);
1689           throw exception;
1690           }
1691         }
1692       }
1693       break;
1694 
1695     default:
1696       {
1697       pPar->problemreading = 1;
1698       std::ostringstream message;
1699       message << "ReadPAR: Unknown PAR version";
1700       ExceptionObject exception(__FILE__, __LINE__,
1701                                 message.str(),
1702                                 ITK_LOCATION);
1703       throw exception;
1704       }
1705     }
1706 
1707   // Reorder the image type matrix so that it is least to greatest.
1708   // Only if the slices need sorting.
1709   if ( !pPar->slicessorted )
1710     {
1711     std::vector< int > sortedImageTypes;
1712     for ( int j = 0; j < pPar->num_image_types; j++ )
1713       {
1714       sortedImageTypes.push_back(pPar->image_types[j]);
1715       }
1716 
1717     std::sort( sortedImageTypes.begin(), sortedImageTypes.end() );
1718     for ( int k = 0; k < pPar->num_image_types; k++ )
1719       {
1720       pPar->image_types[k] = sortedImageTypes[k];
1721       }
1722 
1723     // Reorder the scanning sequences matrix so that it is least to greatest.
1724     std::vector< int > sortedScanningSequences;
1725     for ( int l = 0; l < pPar->num_scanning_sequences; l++ )
1726       {
1727       sortedScanningSequences.push_back(pPar->scanning_sequences[l]);
1728       }
1729 
1730     std::sort( sortedScanningSequences.begin(), sortedScanningSequences.end() );
1731     for ( int m = 0; m < pPar->num_scanning_sequences; m++ )
1732       {
1733       pPar->scanning_sequences[m] = sortedScanningSequences[m];
1734       }
1735     }
1736 
1737   // This is a final fixup that will report the total z dimension
1738   // as the product of the #of slices and the number of image blocks.
1739   pPar->dim[2] *= pPar->image_blocks;
1740 }
1741 
1742 PhilipsPAR::PARSliceIndexImageTypeVector
GetRECSliceIndexImageTypes(std::string parFile)1743 PhilipsPAR::GetRECSliceIndexImageTypes(std::string parFile)
1744 {
1745   PhilipsPAR::PARSliceIndexImageTypeVector recSliceIndexImageTypes;
1746   int                                      ResToolsVersion;
1747 
1748   // Check version of PAR file.
1749   ResToolsVersion = this->GetPARVersion(parFile);
1750   if ( ResToolsVersion == RESEARCH_IMAGE_EXPORT_TOOL_UNKNOWN )
1751     {
1752     return recSliceIndexImageTypes;
1753     }
1754 
1755   switch ( ResToolsVersion )
1756     {
1757     case RESEARCH_IMAGE_EXPORT_TOOL_V3:
1758       {
1759       struct image_info_defV3            tempInfo;
1760       PhilipsPAR::PARSliceIndexImageType sliceAndType;
1761       int                                lineIncrement = 89;
1762       tempInfo = GetImageInformationDefinitionV3(parFile, lineIncrement, this);
1763       while ( !tempInfo.problemreading && tempInfo.slice )
1764         {
1765         sliceAndType.first = tempInfo.slice;
1766         sliceAndType.second = tempInfo.image_type_mr;
1767         recSliceIndexImageTypes.push_back(sliceAndType);
1768         ++lineIncrement;
1769         tempInfo = GetImageInformationDefinitionV3(parFile, lineIncrement, this);
1770         }
1771       }
1772       break;
1773     case RESEARCH_IMAGE_EXPORT_TOOL_V4:
1774       {
1775       struct image_info_defV4            tempInfo;
1776       PhilipsPAR::PARSliceIndexImageType sliceAndType;
1777       int                                lineIncrement = 92;
1778       tempInfo = GetImageInformationDefinitionV4(parFile, lineIncrement, this);
1779       while ( !tempInfo.problemreading && tempInfo.slice )
1780         {
1781         sliceAndType.first = tempInfo.slice;
1782         sliceAndType.second = tempInfo.image_type_mr;
1783         recSliceIndexImageTypes.push_back(sliceAndType);
1784         ++lineIncrement;
1785         tempInfo = GetImageInformationDefinitionV4(parFile, lineIncrement, this);
1786         }
1787       }
1788       break;
1789     case RESEARCH_IMAGE_EXPORT_TOOL_V4_1:
1790       {
1791       struct image_info_defV4            tempInfo;
1792       PhilipsPAR::PARSliceIndexImageType sliceAndType;
1793       int                                lineIncrement = 99;
1794       tempInfo = GetImageInformationDefinitionV41(parFile, lineIncrement, this);
1795       while ( !tempInfo.problemreading && tempInfo.slice )
1796         {
1797         sliceAndType.first = tempInfo.slice;
1798         sliceAndType.second = tempInfo.image_type_mr;
1799         recSliceIndexImageTypes.push_back(sliceAndType);
1800         ++lineIncrement;
1801         tempInfo = GetImageInformationDefinitionV41(parFile, lineIncrement, this);
1802         }
1803       }
1804       break;
1805     case RESEARCH_IMAGE_EXPORT_TOOL_V4_2:
1806       {
1807       struct image_info_defV4            tempInfo;
1808       PhilipsPAR::PARSliceIndexImageType sliceAndType;
1809       int                                lineIncrement = 101;
1810       tempInfo = GetImageInformationDefinitionV42(parFile, lineIncrement, this);
1811       while ( !tempInfo.problemreading && tempInfo.slice )
1812         {
1813         sliceAndType.first = tempInfo.slice;
1814         sliceAndType.second = tempInfo.image_type_mr;
1815         recSliceIndexImageTypes.push_back(sliceAndType);
1816         ++lineIncrement;
1817         tempInfo = GetImageInformationDefinitionV42(parFile, lineIncrement, this);
1818         }
1819       }
1820       break;
1821     }
1822   return recSliceIndexImageTypes;
1823 }
1824 
1825 PhilipsPAR::PARSliceIndexScanSequenceVector
GetRECSliceIndexScanningSequence(std::string parFile)1826 PhilipsPAR::GetRECSliceIndexScanningSequence(std::string parFile)
1827 {
1828   PhilipsPAR::PARSliceIndexScanSequenceVector recSliceIndexScanSequence;
1829   int                                         ResToolsVersion;
1830 
1831   // Check version of PAR file.
1832   ResToolsVersion = this->GetPARVersion(parFile);
1833   if ( ResToolsVersion == RESEARCH_IMAGE_EXPORT_TOOL_UNKNOWN )
1834     {
1835     return recSliceIndexScanSequence;
1836     }
1837 
1838   switch ( ResToolsVersion )
1839     {
1840     case RESEARCH_IMAGE_EXPORT_TOOL_V3:
1841       {
1842       struct image_info_defV3               tempInfo;
1843       PhilipsPAR::PARSliceIndexScanSequence sliceAndSequence;
1844       int                                   lineIncrement = 89;
1845       tempInfo = GetImageInformationDefinitionV3(parFile, lineIncrement, this);
1846       while ( !tempInfo.problemreading && tempInfo.slice )
1847         {
1848         sliceAndSequence.first = tempInfo.slice;
1849         sliceAndSequence.second = tempInfo.scan_sequence;
1850         recSliceIndexScanSequence.push_back(sliceAndSequence);
1851         ++lineIncrement;
1852         tempInfo = GetImageInformationDefinitionV3(parFile, lineIncrement, this);
1853         }
1854       }
1855       break;
1856     case RESEARCH_IMAGE_EXPORT_TOOL_V4:
1857       {
1858       struct image_info_defV4               tempInfo;
1859       PhilipsPAR::PARSliceIndexScanSequence sliceAndSequence;
1860       int                                   lineIncrement = 92;
1861       tempInfo = GetImageInformationDefinitionV4(parFile, lineIncrement, this);
1862       while ( !tempInfo.problemreading && tempInfo.slice )
1863         {
1864         sliceAndSequence.first = tempInfo.slice;
1865         sliceAndSequence.second = tempInfo.scan_sequence;
1866         recSliceIndexScanSequence.push_back(sliceAndSequence);
1867         ++lineIncrement;
1868         tempInfo = GetImageInformationDefinitionV4(parFile, lineIncrement, this);
1869         }
1870       }
1871       break;
1872     case RESEARCH_IMAGE_EXPORT_TOOL_V4_1:
1873       {
1874       struct image_info_defV4               tempInfo;
1875       PhilipsPAR::PARSliceIndexScanSequence sliceAndSequence;
1876       int                                   lineIncrement = 99;
1877       tempInfo = GetImageInformationDefinitionV41(parFile, lineIncrement, this);
1878       while ( !tempInfo.problemreading && tempInfo.slice )
1879         {
1880         sliceAndSequence.first = tempInfo.slice;
1881         sliceAndSequence.second = tempInfo.scan_sequence;
1882         recSliceIndexScanSequence.push_back(sliceAndSequence);
1883         ++lineIncrement;
1884         tempInfo = GetImageInformationDefinitionV41(parFile, lineIncrement, this);
1885         }
1886       }
1887       break;
1888     case RESEARCH_IMAGE_EXPORT_TOOL_V4_2:
1889       {
1890       struct image_info_defV4               tempInfo;
1891       PhilipsPAR::PARSliceIndexScanSequence sliceAndSequence;
1892       int                                   lineIncrement = 101;
1893       tempInfo = GetImageInformationDefinitionV42(parFile, lineIncrement, this);
1894       while ( !tempInfo.problemreading && tempInfo.slice )
1895         {
1896         sliceAndSequence.first = tempInfo.slice;
1897         sliceAndSequence.second = tempInfo.scan_sequence;
1898         recSliceIndexScanSequence.push_back(sliceAndSequence);
1899         ++lineIncrement;
1900         tempInfo = GetImageInformationDefinitionV42(parFile, lineIncrement, this);
1901         }
1902       }
1903       break;
1904     }
1905   return recSliceIndexScanSequence;
1906 }
1907 
1908 PhilipsPAR::PARImageTypeScanSequenceVector
GetImageTypesScanningSequence(std::string parFile)1909 PhilipsPAR::GetImageTypesScanningSequence(std::string parFile)
1910 {
1911   PhilipsPAR::PARImageTypeScanSequenceVector recImageTypesScanSequence;
1912   struct par_parameter                       parParam;
1913 
1914   // Read the PAR file.
1915   try
1916     {
1917     this->ReadPAR(parFile, &parParam);
1918     }
1919   catch ( ExceptionObject & )
1920     {
1921     return recImageTypesScanSequence;
1922     }
1923 
1924   switch ( parParam.ResToolsVersion )
1925     {
1926     case RESEARCH_IMAGE_EXPORT_TOOL_V3:
1927       {
1928       struct image_info_defV3 tempInfo;
1929       for ( int scanIndex = 0; scanIndex < parParam.num_scanning_sequences;
1930             scanIndex++ )
1931         {
1932         PhilipsPAR::PARImageTypeScanSequence imageTypeAndSequence;
1933         int                                  lineIncrement = 89;
1934         int                                  imageType[PAR_DEFAULT_IMAGE_TYPES_SIZE] = { -1, -1, -1, -1, -1, -1, -1, -1 };
1935         tempInfo = GetImageInformationDefinitionV3(parFile, lineIncrement, this);
1936         while ( !tempInfo.problemreading && tempInfo.slice )
1937           {
1938           if ( ( *( imageType + tempInfo.image_type_mr ) < 0 )
1939                && ( tempInfo.scan_sequence == *( parParam.scanning_sequences + scanIndex ) ) )
1940             {
1941             *( imageType + tempInfo.image_type_mr ) = tempInfo.image_type_mr;
1942             }
1943           ++lineIncrement;
1944           tempInfo = GetImageInformationDefinitionV3(parFile, lineIncrement, this);
1945           }
1946         for ( int imageTypeIndex = 0; imageTypeIndex < PAR_DEFAULT_IMAGE_TYPES_SIZE;
1947               imageTypeIndex++ )
1948           {
1949           if ( *( imageType + imageTypeIndex ) >= 0 )
1950             {
1951             imageTypeAndSequence.first = imageTypeIndex;
1952             imageTypeAndSequence.second =
1953               *( parParam.scanning_sequences + scanIndex );
1954             recImageTypesScanSequence.push_back(imageTypeAndSequence);
1955             }
1956           }
1957         }
1958       }
1959       break;
1960     case RESEARCH_IMAGE_EXPORT_TOOL_V4:
1961       {
1962       struct image_info_defV4 tempInfo;
1963       for ( int scanIndex = 0; scanIndex < parParam.num_scanning_sequences;
1964             scanIndex++ )
1965         {
1966         PhilipsPAR::PARImageTypeScanSequence imageTypeAndSequence;
1967         int                                  lineIncrement = 92;
1968         int                                  imageType[PAR_DEFAULT_IMAGE_TYPES_SIZE] = { -1, -1, -1, -1, -1, -1, -1, -1 };
1969         tempInfo = GetImageInformationDefinitionV4(parFile, lineIncrement, this);
1970         while ( !tempInfo.problemreading && tempInfo.slice )
1971           {
1972           if ( ( *( imageType + tempInfo.image_type_mr ) < 0 )
1973                && ( tempInfo.scan_sequence == *( parParam.scanning_sequences + scanIndex ) ) )
1974             {
1975             *( imageType + tempInfo.image_type_mr ) = tempInfo.image_type_mr;
1976             }
1977           ++lineIncrement;
1978           tempInfo = GetImageInformationDefinitionV4(parFile, lineIncrement, this);
1979           }
1980         for ( int imageTypeIndex = 0; imageTypeIndex < PAR_DEFAULT_IMAGE_TYPES_SIZE;
1981               imageTypeIndex++ )
1982           {
1983           if ( *( imageType + imageTypeIndex ) >= 0 )
1984             {
1985             imageTypeAndSequence.first = imageTypeIndex;
1986             imageTypeAndSequence.second =
1987               *( parParam.scanning_sequences + scanIndex );
1988             recImageTypesScanSequence.push_back(imageTypeAndSequence);
1989             }
1990           }
1991         }
1992       }
1993       break;
1994     case RESEARCH_IMAGE_EXPORT_TOOL_V4_1:
1995       {
1996       struct image_info_defV4 tempInfo;
1997       for ( int scanIndex = 0; scanIndex < parParam.num_scanning_sequences;
1998             scanIndex++ )
1999         {
2000         PhilipsPAR::PARImageTypeScanSequence imageTypeAndSequence;
2001         int                                  lineIncrement = 99;
2002         int                                  imageType[PAR_DEFAULT_IMAGE_TYPES_SIZE] = { -1, -1, -1, -1, -1, -1, -1, -1 };
2003         tempInfo = GetImageInformationDefinitionV41(parFile, lineIncrement, this);
2004         while ( !tempInfo.problemreading && tempInfo.slice )
2005           {
2006           if ( ( *( imageType + tempInfo.image_type_mr ) < 0 )
2007                && ( tempInfo.scan_sequence == *( parParam.scanning_sequences + scanIndex ) ) )
2008             {
2009             *( imageType + tempInfo.image_type_mr ) = tempInfo.image_type_mr;
2010             }
2011           ++lineIncrement;
2012           tempInfo = GetImageInformationDefinitionV41(parFile, lineIncrement, this);
2013           }
2014         for ( int imageTypeIndex = 0; imageTypeIndex < PAR_DEFAULT_IMAGE_TYPES_SIZE;
2015               imageTypeIndex++ )
2016           {
2017           if ( *( imageType + imageTypeIndex ) >= 0 )
2018             {
2019             imageTypeAndSequence.first = imageTypeIndex;
2020             imageTypeAndSequence.second =
2021               *( parParam.scanning_sequences + scanIndex );
2022             recImageTypesScanSequence.push_back(imageTypeAndSequence);
2023             }
2024           }
2025         }
2026       }
2027       break;
2028     case RESEARCH_IMAGE_EXPORT_TOOL_V4_2:
2029       {
2030       struct image_info_defV4 tempInfo;
2031       for ( int scanIndex = 0; scanIndex < parParam.num_scanning_sequences;
2032             scanIndex++ )
2033         {
2034         PhilipsPAR::PARImageTypeScanSequence imageTypeAndSequence;
2035         int                                  lineIncrement = 101;
2036         int                                  imageType[PAR_DEFAULT_IMAGE_TYPES_SIZE] = { -1, -1, -1, -1, -1, -1, -1, -1 };
2037         tempInfo = GetImageInformationDefinitionV42(parFile, lineIncrement, this);
2038         while ( !tempInfo.problemreading && tempInfo.slice )
2039           {
2040           if ( ( *( imageType + tempInfo.image_type_mr ) < 0 )
2041                && ( tempInfo.scan_sequence == *( parParam.scanning_sequences + scanIndex ) ) )
2042             {
2043             *( imageType + tempInfo.image_type_mr ) = tempInfo.image_type_mr;
2044             }
2045           ++lineIncrement;
2046           tempInfo = GetImageInformationDefinitionV42(parFile, lineIncrement, this);
2047           }
2048         for ( int imageTypeIndex = 0; imageTypeIndex < PAR_DEFAULT_IMAGE_TYPES_SIZE;
2049               imageTypeIndex++ )
2050           {
2051           if ( *( imageType + imageTypeIndex ) >= 0 )
2052             {
2053             imageTypeAndSequence.first = imageTypeIndex;
2054             imageTypeAndSequence.second =
2055               *( parParam.scanning_sequences + scanIndex );
2056             recImageTypesScanSequence.push_back(imageTypeAndSequence);
2057             }
2058           }
2059         }
2060       }
2061       break;
2062     }
2063   return recImageTypesScanSequence;
2064 }
2065 
GetRECRescaleValues(std::string parFile,PhilipsPAR::PARRescaleValuesContainer * rescaleValues,int scan_sequence)2066 bool PhilipsPAR::GetRECRescaleValues(std::string parFile,
2067                                      PhilipsPAR::PARRescaleValuesContainer *rescaleValues, int scan_sequence)
2068 {
2069   int ResToolsVersion;
2070 
2071   rescaleValues->clear();
2072   // Must match size of image_types
2073   rescaleValues->resize(PAR_DEFAULT_IMAGE_TYPES_SIZE);
2074   PhilipsPAR::PARRescaleValues zero(0.0);
2075   for ( unsigned int zeroIndex = 0; zeroIndex < rescaleValues->size(); zeroIndex++ )
2076     {
2077     ( *rescaleValues )[zeroIndex] = zero; // Zero out everything
2078     }
2079 
2080   // Check version of PAR file.
2081   ResToolsVersion = this->GetPARVersion(parFile);
2082   if ( ResToolsVersion == RESEARCH_IMAGE_EXPORT_TOOL_UNKNOWN )
2083     {
2084     return false;
2085     }
2086 
2087   switch ( ResToolsVersion )
2088     {
2089     case RESEARCH_IMAGE_EXPORT_TOOL_V3:
2090       {
2091       struct image_info_defV3      tempInfo;
2092       PhilipsPAR::PARRescaleValues rescale;
2093       int                          imageType[PAR_DEFAULT_IMAGE_TYPES_SIZE] = { -1, -1, -1, -1, -1, -1, -1, -1 };
2094       int                          lineIncrement = 89;
2095       tempInfo = GetImageInformationDefinitionV3(parFile, lineIncrement, this);
2096       while ( !tempInfo.problemreading && tempInfo.slice )
2097         {
2098         if ( ( *( imageType + tempInfo.image_type_mr ) < 0 )
2099              && ( tempInfo.scan_sequence == scan_sequence ) )
2100           {
2101           *( imageType + tempInfo.image_type_mr ) = tempInfo.image_type_mr;
2102           rescale[0] = tempInfo.rescale_int;
2103           rescale[1] = tempInfo.rescale_slope;
2104           rescale[2] = tempInfo.scale_slope;
2105           ( *rescaleValues )[tempInfo.image_type_mr] = rescale;
2106           }
2107         ++lineIncrement;
2108         tempInfo = GetImageInformationDefinitionV3(parFile, lineIncrement, this);
2109         }
2110       }
2111       break;
2112     case RESEARCH_IMAGE_EXPORT_TOOL_V4:
2113       {
2114       struct image_info_defV4      tempInfo;
2115       PhilipsPAR::PARRescaleValues rescale;
2116       int                          imageType[PAR_DEFAULT_IMAGE_TYPES_SIZE] = { -1, -1, -1, -1, -1, -1, -1, -1 };
2117       int                          lineIncrement = 92;
2118       tempInfo = GetImageInformationDefinitionV4(parFile, lineIncrement, this);
2119       while ( !tempInfo.problemreading && tempInfo.slice )
2120         {
2121         if ( ( *( imageType + tempInfo.image_type_mr ) < 0 )
2122              && ( tempInfo.scan_sequence == scan_sequence ) )
2123           {
2124           *( imageType + tempInfo.image_type_mr ) = tempInfo.image_type_mr;
2125           rescale[0] = tempInfo.rescale_int;
2126           rescale[1] = tempInfo.rescale_slope;
2127           rescale[2] = tempInfo.scale_slope;
2128           ( *rescaleValues )[tempInfo.image_type_mr] = rescale;
2129           }
2130         ++lineIncrement;
2131         tempInfo = GetImageInformationDefinitionV4(parFile, lineIncrement, this);
2132         }
2133       }
2134       break;
2135     case RESEARCH_IMAGE_EXPORT_TOOL_V4_1:
2136       {
2137       struct image_info_defV4      tempInfo;
2138       PhilipsPAR::PARRescaleValues rescale;
2139       int                          imageType[PAR_DEFAULT_IMAGE_TYPES_SIZE] = { -1, -1, -1, -1, -1, -1, -1, -1 };
2140       int                          lineIncrement = 99;
2141       tempInfo = GetImageInformationDefinitionV41(parFile, lineIncrement, this);
2142       while ( !tempInfo.problemreading && tempInfo.slice )
2143         {
2144         if ( ( *( imageType + tempInfo.image_type_mr ) < 0 )
2145              && ( tempInfo.scan_sequence == scan_sequence ) )
2146           {
2147           *( imageType + tempInfo.image_type_mr ) = tempInfo.image_type_mr;
2148           rescale[0] = tempInfo.rescale_int;
2149           rescale[1] = tempInfo.rescale_slope;
2150           rescale[2] = tempInfo.scale_slope;
2151           ( *rescaleValues )[tempInfo.image_type_mr] = rescale;
2152           }
2153         ++lineIncrement;
2154         tempInfo = GetImageInformationDefinitionV41(parFile, lineIncrement, this);
2155         }
2156       }
2157       break;
2158     case RESEARCH_IMAGE_EXPORT_TOOL_V4_2:
2159       {
2160       struct image_info_defV4      tempInfo;
2161       PhilipsPAR::PARRescaleValues rescale;
2162       int                          imageType[PAR_DEFAULT_IMAGE_TYPES_SIZE] = { -1, -1, -1, -1, -1, -1, -1, -1 };
2163       int                          lineIncrement = 101;
2164       tempInfo = GetImageInformationDefinitionV42(parFile, lineIncrement, this);
2165       while ( !tempInfo.problemreading && tempInfo.slice )
2166         {
2167         if ( ( *( imageType + tempInfo.image_type_mr ) < 0 )
2168              && ( tempInfo.scan_sequence == scan_sequence ) )
2169           {
2170           *( imageType + tempInfo.image_type_mr ) = tempInfo.image_type_mr;
2171           rescale[0] = tempInfo.rescale_int;
2172           rescale[1] = tempInfo.rescale_slope;
2173           rescale[2] = tempInfo.scale_slope;
2174           ( *rescaleValues )[tempInfo.image_type_mr] = rescale;
2175           }
2176         ++lineIncrement;
2177         tempInfo = GetImageInformationDefinitionV42(parFile, lineIncrement, this);
2178         }
2179       }
2180       break;
2181     }
2182   return true;
2183 }
2184 
GetDiffusionGradientOrientationAndBValues(std::string parFile,PhilipsPAR::PARDiffusionValuesContainer * gradientValues,PhilipsPAR::PARBValuesContainer * bValues)2185 bool PhilipsPAR::GetDiffusionGradientOrientationAndBValues(std::string parFile,
2186                                                            PhilipsPAR::PARDiffusionValuesContainer *gradientValues,
2187                                                            PhilipsPAR::PARBValuesContainer *bValues)
2188 {
2189   gradientValues->resize(0); // Reset to zero size.
2190   bValues->resize(0);
2191   struct par_parameter tempPar;
2192   int                  ResToolsVersion;
2193 
2194   // Check version of PAR file.
2195   // Diffusion gradients are only stored in PAR version >= 4.1
2196   ResToolsVersion = this->GetPARVersion(parFile);
2197   if ( ResToolsVersion >= RESEARCH_IMAGE_EXPORT_TOOL_V4_1 )
2198     {
2199     struct image_info_defV4 tempInfo;
2200     int                     gradientOrientationNumber = -1;
2201     int                     lineIncrement = 99;
2202 
2203     if ( ResToolsVersion == RESEARCH_IMAGE_EXPORT_TOOL_V4_2 )
2204       {
2205       lineIncrement = 101;
2206       }
2207 
2208     try
2209       {
2210       this->ReadPAR(parFile, &tempPar);
2211       }
2212     catch ( ExceptionObject & )
2213       {
2214       return false;
2215       }
2216 
2217     gradientValues->resize(tempPar.max_num_grad_orient);
2218     bValues->resize(tempPar.max_num_grad_orient);
2219 
2220     if ( tempPar.max_num_grad_orient <= 0 )
2221       {
2222       return true;
2223       }
2224 
2225     // Can use either version 4.1 or 4.2 GetImageInformationDefinition
2226     // function.
2227     int gradientDirectionCount = 0;
2228     tempInfo = GetImageInformationDefinitionV41(parFile, lineIncrement, this);
2229     while ( !tempInfo.problemreading && tempInfo.slice
2230             && ( gradientDirectionCount < tempPar.max_num_grad_orient ) )
2231       {
2232       int tempGradientOrientationNumber = tempInfo.gradient_orientation_number;
2233       if ( gradientOrientationNumber != tempGradientOrientationNumber )
2234         {
2235         PhilipsPAR::PARDiffusionValues direction;
2236         direction[0] = tempInfo.diffusion_ap;
2237         direction[1] = tempInfo.diffusion_fh;
2238         direction[2] = tempInfo.diffusion_rl;
2239         ( *gradientValues )[gradientDirectionCount] = direction;
2240         ( *bValues )[gradientDirectionCount] = tempInfo.diffusion_b_factor;
2241         ++gradientDirectionCount;
2242         gradientOrientationNumber = tempGradientOrientationNumber;
2243         }
2244       ++lineIncrement;
2245       tempInfo = GetImageInformationDefinitionV41(parFile, lineIncrement, this);
2246       }
2247     }
2248   return true;
2249 }
2250 
GetLabelTypesASL(std::string parFile,PhilipsPAR::PARLabelTypesASLContainer * labelTypes)2251 bool PhilipsPAR::GetLabelTypesASL(std::string parFile,
2252                                   PhilipsPAR::PARLabelTypesASLContainer *labelTypes)
2253 {
2254   labelTypes->resize(0); // Reset to zero size.
2255   struct par_parameter tempPar;
2256   int                  ResToolsVersion;
2257 
2258   // Check version of PAR file.
2259   // ASL labels are only stored in PAR version >= 4.2
2260   ResToolsVersion = this->GetPARVersion(parFile);
2261   if ( ResToolsVersion >= RESEARCH_IMAGE_EXPORT_TOOL_V4_2 )
2262     {
2263     struct image_info_defV4 tempInfo;
2264     int                     aslLabelNumber = -1;
2265     int                     lineIncrement = 101;
2266 
2267     try
2268       {
2269       this->ReadPAR(parFile, &tempPar);
2270       }
2271     catch ( ExceptionObject & )
2272       {
2273       return false;
2274       }
2275 
2276     labelTypes->resize(tempPar.num_label_types);
2277 
2278     if ( tempPar.num_label_types <= 0 )
2279       {
2280       return true;
2281       }
2282 
2283     int aslLabelCount = 0;
2284     tempInfo = GetImageInformationDefinitionV42(parFile, lineIncrement, this);
2285     while ( !tempInfo.problemreading && tempInfo.slice
2286             && ( aslLabelCount < tempPar.num_label_types ) )
2287       {
2288       int tempASLLabelNumber = tempInfo.labelTypeASL;
2289       if ( aslLabelNumber != tempASLLabelNumber )
2290         {
2291         ( *labelTypes )[aslLabelCount] = tempASLLabelNumber;
2292         ++aslLabelCount;
2293         aslLabelNumber = tempASLLabelNumber;
2294         }
2295       ++lineIncrement;
2296       tempInfo = GetImageInformationDefinitionV42(parFile, lineIncrement, this);
2297       }
2298     }
2299   return true;
2300 }
2301 
PrintSelf(std::ostream & os,Indent indent) const2302 void PhilipsPAR::PrintSelf(std::ostream & os, Indent indent) const
2303 {
2304   Superclass::PrintSelf(os, indent);
2305 }
2306 } // end namespace itk
2307