1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://www.centreleonberard.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
28 #include "clitkGateAsciiImageIO.h"
29 #include "clitkCommon.h"
32 #include <itkMetaDataObject.h>
34 std::ostream& operator<<(std::ostream& os, const clitk::GateAsciiImageIO::GateAsciiHeader& header)
36 os << "matrix_size=[" << header.matrix_size[0] << "," << header.matrix_size[1] << "," << header.matrix_size[2] << "]" << endl;
37 os << "resolution=[" << header.resolution[0] << "," << header.resolution[1] << "," << header.resolution[2] << "]" << endl;
38 os << "voxel_size=[" << header.voxel_size[0] << "," << header.voxel_size[1] << "," << header.voxel_size[2] << "]" << endl;
39 os << "nb_value=" << header.nb_value << endl;
43 //--------------------------------------------------------------------
44 // Read Image Information
45 void clitk::GateAsciiImageIO::ReadImageInformation()
47 itkGenericExceptionMacro(<< "Could not open file (for reading): " << m_FileName);
50 /* Convert hnd to ITK image information */
51 SetNumberOfDimensions(2);
52 //SetDimensions(0, hnd.SizeX);
53 //SetDimensions(1, hnd.SizeY);
54 //SetSpacing(0, hnd.dIDUResolutionX);
55 //SetSpacing(1, hnd.dIDUResolutionY);
56 //SetOrigin(0, -0.5*(hnd.SizeX-1)*hnd.dIDUResolutionX); //SR: assumed centered
57 //SetOrigin(1, -0.5*(hnd.SizeY-1)*hnd.dIDUResolutionY); //SR: assumed centered
58 //SetComponentType(itk::ImageIOBase::UINT);
60 /* Store important meta information in the meta data dictionary */
61 //itk::EncapsulateMetaData<double>(this->GetMetaDataDictionary(), "dCTProjectionAngle", hnd.dCTProjectionAngle);
62 //itk::ExposeMetaData<double>( this->GetMetaDataDictionary(), &(hnd.dCTProjectionAngle), "dCTProjectionAngle");
65 //--------------------------------------------------------------------
66 bool clitk::GateAsciiImageIO::CanReadFile(const char* FileNameToRead)
68 std::string filename(FileNameToRead);
71 std::string filenameext = GetExtension(filename);
72 if (filenameext != std::string("txt")) return false;
76 FILE* handle = fopen(filename.c_str(),"r");
77 if (!handle) return false;
79 GateAsciiHeader header;
80 if (!ReadHeader(handle,header)) { fclose(handle); return false; }
87 //--------------------------------------------------------------------
89 bool clitk::GateAsciiImageIO::ReadLine(FILE* handle, std::string& line)
91 std::stringstream stream;
95 if (ferror(handle)) return false;
96 if (fread(&item,1,1,handle) != 1) return false;
98 if (item=='\n' or feof(handle)) {
107 std::string ExtractMatch(const std::string& base, const regmatch_t& match)
109 return base.substr(match.rm_so,match.rm_eo-match.rm_so);
112 template <typename T>
113 T ConvertFromString(const std::string& value)
115 std::stringstream stream;
122 //--------------------------------------------------------------------
124 bool clitk::GateAsciiImageIO::ReadHeader(FILE* handle, GateAsciiHeader& header)
130 regex_t re_matrix_size;
132 regex_t re_voxel_size;
134 regmatch_t matches[4];
138 ret = regcomp(&re_comment,"^#.+$",REG_EXTENDED|REG_NEWLINE);
140 ret = regcomp(&re_matrix_size,"^# +Matrix *Size *= +\\(([0-9]+\\.?[0-9]*),([0-9]+\\.?[0-9]*),([0-9]+\\.?[0-9]*)\\)$",REG_EXTENDED|REG_NEWLINE);
142 ret = regcomp(&re_resol,"^# +Resol *= +\\(([0-9]+),([0-9]+),([0-9]+)\\)$",REG_EXTENDED|REG_NEWLINE);
144 ret = regcomp(&re_voxel_size,"^# +Voxel *Size *= +\\(([0-9]+\\.?[0-9]*),([0-9]+\\.?[0-9]*),([0-9]+\\.?[0-9]*)\\)$",REG_EXTENDED|REG_NEWLINE);
146 ret = regcomp(&re_nb_value,"^# +nbVal *= +([0-9]+)$",REG_EXTENDED|REG_NEWLINE);
150 if (!ReadLine(handle,line)) return false;
151 if (regexec(&re_comment,line.c_str(),1,matches,0) == REG_NOMATCH) return false;
153 if (!ReadLine(handle,line)) return false;
154 if (regexec(&re_matrix_size,line.c_str(),4,matches,0) == REG_NOMATCH) return false;
155 header.matrix_size[0] = ConvertFromString<double>(ExtractMatch(line,matches[1]));
156 header.matrix_size[1] = ConvertFromString<double>(ExtractMatch(line,matches[2]));
157 header.matrix_size[2] = ConvertFromString<double>(ExtractMatch(line,matches[3]));
159 if (!ReadLine(handle,line)) return false;
160 if (regexec(&re_resol,line.c_str(),4,matches,0) == REG_NOMATCH) return false;
161 header.resolution[0] = ConvertFromString<int>(ExtractMatch(line,matches[1]));
162 header.resolution[1] = ConvertFromString<int>(ExtractMatch(line,matches[2]));
163 header.resolution[2] = ConvertFromString<int>(ExtractMatch(line,matches[3]));
165 if (!ReadLine(handle,line)) return false;
166 if (regexec(&re_voxel_size,line.c_str(),4,matches,0) == REG_NOMATCH) return false;
167 header.voxel_size[0] = ConvertFromString<double>(ExtractMatch(line,matches[1]));
168 header.voxel_size[1] = ConvertFromString<double>(ExtractMatch(line,matches[2]));
169 header.voxel_size[2] = ConvertFromString<double>(ExtractMatch(line,matches[3]));
171 if (!ReadLine(handle,line)) return false;
172 if (regexec(&re_nb_value,line.c_str(),2,matches,0) == REG_NOMATCH) return false;
173 header.nb_value = ConvertFromString<int>(ExtractMatch(line,matches[1]));
175 if (!ReadLine(handle,line)) return false;
176 if (regexec(&re_comment,line.c_str(),1,matches,0) == REG_NOMATCH) return false;
181 //--------------------------------------------------------------------
182 // Read Image Content
183 void clitk::GateAsciiImageIO::Read(void * buffer)
187 uint32_t* buf = (uint32_t*)buffer;
188 unsigned char *pt_lut;
192 int lut_idx, lut_off;
199 fp = fopen (m_FileName.c_str(), "rb");
201 itkGenericExceptionMacro(<< "Could not open file (for reading): " << m_FileName);
203 pt_lut = (unsigned char*) malloc (sizeof (unsigned char) * GetDimensions(0) * GetDimensions(1));
206 fseek (fp, 1024, SEEK_SET);
207 fread (pt_lut, sizeof(unsigned char), (GetDimensions(1)-1)*GetDimensions(0) / 4, fp);
210 for (i = 0; i < GetDimensions(0); i++) {
211 fread (&a, sizeof(uint32_t), 1, fp);
216 /* Read first pixel of second row */
217 fread (&a, sizeof(uint32_t), 1, fp);
221 /* Decompress the rest */
224 while (i < GetDimensions(0) * GetDimensions(1)) {
225 uint32_t r11, r12, r21;
227 r11 = buf[i-GetDimensions(0)-1];
228 r12 = buf[i-GetDimensions(0)];
252 num_read = fread (&dc, sizeof(unsigned char), 1, fp);
253 if (num_read != 1) goto read_error;
257 num_read = fread (&ds, sizeof(unsigned short), 1, fp);
258 if (num_read != 1) goto read_error;
262 num_read = fread (&dl, sizeof(uint32_t), 1, fp);
263 if (num_read != 1) goto read_error;
268 buf[i] = r21 + r12 + diff - r11;
280 itkGenericExceptionMacro(<< "Error reading gate ascii file");
286 //--------------------------------------------------------------------
287 bool clitk::GateAsciiImageIO::CanWriteFile(const char* FileNameToWrite)
292 //--------------------------------------------------------------------
294 void clitk::GateAsciiImageIO::Write(const void* buffer)