]> Creatis software - creaContours.git/blob - lib/kernel_ManagerContour_NDimensions/ParserOsirix/OsirixParser.cxx
Feature #1772 Add licence terms for all files.
[creaContours.git] / lib / kernel_ManagerContour_NDimensions / ParserOsirix / OsirixParser.cxx
1 /*# ---------------------------------------------------------------------
2 #
3 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
4 #                        pour la Sant�)
5 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
6 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
7 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
8 #
9 #  This software is governed by the CeCILL-B license under French law and
10 #  abiding by the rules of distribution of free software. You can  use,
11 #  modify and/ or redistribute the software under the terms of the CeCILL-B
12 #  license as circulated by CEA, CNRS and INRIA at the following URL
13 #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
14 #  or in the file LICENSE.txt.
15 #
16 #  As a counterpart to the access to the source code and  rights to copy,
17 #  modify and redistribute granted by the license, users are provided only
18 #  with a limited warranty  and the software's author,  the holder of the
19 #  economic rights,  and the successive licensors  have only  limited
20 #  liability.
21 #
22 #  The fact that you are presently reading this means that you have had
23 #  knowledge of the CeCILL-B license and that you accept its terms.
24 # ------------------------------------------------------------------------ */
25
26
27 //----------------------------------------------------------------------------------------------------------------
28 // Class definition include
29 //----------------------------------------------------------------------------------------------------------------
30 #include "OsirixParser.h"
31 #include <stdio.h>
32
33
34 OsirixParser::OsirixParser(std::string xsdfile, double* spacing, int* extent)
35 {
36         schema=xsdfile;
37
38         OSIRIX_DICT = "dict";
39         OSIRIX_KEY = "key";
40         OSIRIX_IMAGES = "Images";
41         OSIRIX_ARRAY = "array";
42         OSIRIX_IMAGEINDEX = "ImageIndex";
43         OSIRIX_INTEGER = "integer";
44         OSIRIX_NUMBEROFROIS = "NumberOfROIs";
45         OSIRIX_ROIS = "ROIs";
46         OSIRIX_POINT_MM = "Point_mm";
47         OSIRIX_POINT_PX = "Point_px";
48         OSIRIX_STRING = "string";
49         OSIRIX_NAME = "Name";
50
51         if(spacing != NULL){
52                 _spacing[0] = spacing[0];
53                 _spacing[1] = spacing[1];
54                 _spacing[2] = spacing[2];
55         }else{
56                 _spacing[0] = 1;
57                 _spacing[1] = 1;
58                 _spacing[2] = 1;
59         }
60
61         if(extent != NULL){
62                 _extent[0] = extent[0];
63                 _extent[1] = extent[1];
64                 _extent[2] = extent[2];
65                 _extent[3] = extent[3];
66                 _extent[4] = extent[4];
67                 _extent[5] = extent[5];
68                 
69         }else{
70                 _extent[0] = 1;
71                 _extent[1] = 1;
72                 _extent[2] = 1;         
73                 _extent[3] = 1;
74                 _extent[4] = 1;
75                 _extent[5] = 1;
76         }
77
78
79         /*HEADER*/
80         CREACONTOUR = "--CreaContour--";
81         CREACONTOUR_VERSION = "Version 1.0.2";
82         CREACONTOUR_IMAGEDIMENSIONS = "ImageDimensions";
83         CREACONTOUR_IMAGESPACING = "ImageSpacing";
84         CREACONTOUR_NUMBEROFCONTOURS = "NumberOfContours";
85         /*FOR EACH CONTOUR*/
86         CREACONTOUR_INSTANT = "Instant";
87         CREACONTOUR_TYPEMODEL = "TypeModel";
88         CREACONTOUR_NUMBEROFCONTROLPOINTS = "NumberOfControlPoints";
89         CREACONTOUR_TYPEVIEW = "TypeView";      
90         /*STATICCONTOURS*/
91         CREACONTOUR_NUMBEROFCONTOURSSTATIC = "NumberOfContoursStatic";
92
93         TEMPIMPORTOSIRIXFILE = "";
94
95 #ifdef WIN32
96
97         char currentPath[_MAX_PATH];    
98         GetModuleFileName(NULL, currentPath, _MAX_PATH);
99         TEMPIMPORTOSIRIXFILE = currentPath;
100
101         TEMPIMPORTOSIRIXFILE = TEMPIMPORTOSIRIXFILE.substr(0,TEMPIMPORTOSIRIXFILE.find_last_of("\\"));
102
103         TEMPIMPORTOSIRIXFILE.append("\\data\\TEMPIMPORTOSIRIXFILE.roi");
104         
105 #else
106         char * pPath;
107         pPath = getenv ("HOME");
108
109         if(pPath){
110             TEMPIMPORTOSIRIXFILE.append(pPath);
111         }else{
112             TEMPIMPORTOSIRIXFILE.append(".");
113         }
114         TEMPIMPORTOSIRIXFILE.append("/.creaContourDataTemp/TEMPIMPORTOSIRIXFILE.roi");
115 #endif
116         
117 }
118 OsirixParser::~OsirixParser(){
119
120 }
121
122 int OsirixParser::ParseFile(const char* xmlfile){
123
124         xercesc::DOMDocument *doc;
125
126
127         try {
128             XMLPlatformUtils::Initialize();
129         }
130         catch (const XMLException& toCatch) {
131             char* message = XMLString::transcode(toCatch.getMessage());
132             cout << "Error during initialization! :\n"
133                  << message << "\n";
134             XMLString::release(&message);
135             return 1;
136         }
137
138         XercesDOMParser* OsirixParser = new XercesDOMParser();
139
140
141                 OsirixParser->setDoNamespaces(true);
142                 OsirixParser->setDoSchema(true);
143                 OsirixParser->setValidationScheme(XercesDOMParser::Val_Always );
144                 OsirixParser->setExternalNoNamespaceSchemaLocation(XMLString::transcode(schema.c_str()));
145                 OsirixParser->setValidationSchemaFullChecking(true);
146                 OsirixParser->setValidationConstraintFatal(true);
147                 OsirixParser->setExitOnFirstFatalError(true);
148
149
150         ErrorHandler* errHandler = (ErrorHandler*) new OsirixParserErrorHandler();
151
152         OsirixParser->setErrorHandler(errHandler);
153
154
155         try {
156             OsirixParser->parse(xmlfile);
157
158
159                         if(OsirixParser->getErrorCount() > 0){
160
161                                 errorline = ((OsirixParserErrorHandler*)OsirixParser->getErrorHandler())->getErrorMsg();
162
163
164                                 delete OsirixParser;
165                                 delete errHandler;
166                                 return -2;
167                         }
168
169
170
171         }
172         catch (const XMLException& toCatch) {
173             char* message = XMLString::transcode(toCatch.getMessage());
174             cout << "Exception message is: \n"
175                  << message << "\n";
176             XMLString::release(&message);
177                         delete OsirixParser;
178                     delete errHandler;
179             return -1;
180         }
181         catch (const DOMException& toCatch) {
182             char* message = XMLString::transcode(toCatch.msg);
183             cout << "Exception message is: \n"
184                  << message << "\n";
185             XMLString::release(&message);
186                         delete OsirixParser;
187                         delete errHandler;
188             return -1;
189         }
190         catch (...) {
191             cout << "Unexpected Exception \n" ;
192                         delete OsirixParser;
193                         delete errHandler;
194             return -1;
195         }
196
197                 std::cout<<"parsing document..."<<std::endl;
198
199
200         doc = OsirixParser->getDocument();
201 //              DOMNodeList* list = doc->getChildNodes();               
202                 getUserData(doc->getDocumentElement());
203
204
205                 saveCreaContoursFormat();
206
207         delete OsirixParser;
208         delete errHandler;
209
210
211
212                 return 0;
213
214 }
215
216 void OsirixParser::setErrorLine(DOMNodeList* list){
217
218         DOMNode* node = list->item(0);
219         this->errorline =       XMLString::transcode(node->getTextContent());
220
221 }
222 DOMNode* OsirixParser::getLastNode(DOMNodeList* list){
223
224
225         DOMNode* node;
226         /*for(int i = list->getLength()-1; i >= 0 ;i--){
227
228                 node = list->item(i);
229
230                 if(node->getNodeType() == DOMNode::ELEMENT_NODE){
231                         i = -1;
232                 }
233
234         }*/
235         node = list->item(list->getLength()-1);
236
237
238
239         if(node->getChildNodes()->getLength()>0){
240                 return getLastNode(node->getChildNodes());
241         }
242         return node;
243
244 }
245
246 void OsirixParser::getUserData(DOMElement* element){
247         parseOSIRIX_DICT(element->getElementsByTagName(XMLString::transcode(OSIRIX_DICT)));
248 }
249
250 void OsirixParser::parseOSIRIX_DICT(DOMNodeList* list){
251         int i, j;
252         DOMNode* node, *childnode, *childnode1, *childarray;
253         std::string point_mm, point_px, osirixinteger, imageindex, temp;
254         DOMNodeList* childlist;
255         point_mm = OSIRIX_POINT_MM;
256         point_px = OSIRIX_POINT_PX;
257         imageindex = OSIRIX_IMAGEINDEX;
258         osirixinteger = OSIRIX_INTEGER;
259         
260         std::string osirixstring = OSIRIX_STRING;
261         std::string osirixname = OSIRIX_NAME;
262         
263
264         for(i = 0; i < (int)(list->getLength()); i++){
265                 node = list->item(i);           
266                 childlist = node->getChildNodes();
267                 for(j = 0; j < (int)(childlist->getLength());j++){
268                         childnode = childlist->item(j);                 
269                         temp = XMLString::transcode(childnode->getTextContent());       
270
271
272                         if(point_mm.compare(temp)==0){                          
273                                 childarray = childlist->item(j+2);
274                                 //temp = XMLString::transcode(childarray->getNodeName());                                       
275                                 if(childarray != 0){                                    
276                                         parseOSIRIX_POINT_MM(childarray->getChildNodes());                                      
277                                 }                               
278                         }else if(point_px.compare(temp)==0){                            
279                                 childarray = childlist->item(j+2);
280                                 //temp = XMLString::transcode(childarray->getNodeName());                                       
281                                 if(childarray != 0){                                    
282                                         parseOSIRIX_POINT_PX(childarray->getChildNodes());                                      
283                                 }                               
284                         }else if(imageindex.compare(temp) == 0){
285                                 childnode1 = childlist->item(j+2);
286                                 if(childnode1 != NULL && osirixinteger.compare(XMLString::transcode(childnode1->getNodeName())) == 0){
287                                         _imageindex = atoi(XMLString::transcode(childnode1->getTextContent()));                                         
288                                 }                               
289                         } else if(osirixname.compare(temp) == 0) {
290                           // keep information about the name of the ROI
291                                 childnode1 = childlist->item(j+2);
292                                 if(childnode1 != NULL && osirixstring.compare(XMLString::transcode(childnode1->getNodeName())) == 0){
293                                   char* roiname = XMLString::transcode(childnode1->getTextContent());
294                                   _roiname = string(roiname);
295                                 }
296                         }
297                 }               
298         }
299 }
300
301 void OsirixParser::parseOSIRIX_POINT_MM(DOMNodeList* list){
302         int i, stringfound0, stringfound1;
303         DOMNode* node;
304         string temp, osirix_string, numx, numy, numz;
305         vector<double>* vectorx;
306         vector<double>* vectory;
307         vector<double>* vectorz;
308         vectorXYZ vectorxyz;
309         double x, y, z; 
310
311         vectorx = new vector<double>;
312         vectory = new vector<double>;
313         vectorz = new vector<double>;
314
315         osirix_string = OSIRIX_STRING;
316
317         for(i = 0; i < (int)(list->getLength()); i++){
318                 node = list->item(i);
319                 if(osirix_string.compare(XMLString::transcode(node->getNodeName()))==0){
320                         temp = XMLString::transcode(node->getTextContent());                    
321
322                         stringfound0 = temp.find(",",0);
323                         numx = temp.substr(1, stringfound0-1);
324
325                         stringfound1 = temp.find(",",stringfound0+1);
326                         numy = temp.substr(stringfound0+1, stringfound1-stringfound0-1);
327
328                         stringfound0 = temp.find(")",stringfound1+1);
329                         numz = temp.substr(stringfound1+1, stringfound0-stringfound1-1);
330
331                         x = atof(numx.c_str());         
332                         y = atof(numy.c_str());         
333                         z = atof(numz.c_str());         
334
335                         vectorx->push_back(x);
336                         vectory->push_back(y);
337                         vectorz->push_back(z);
338                 }               
339         }
340         if(vectorx->size() > 0){
341                 vectorxyz.push_back(*vectorx);
342                 vectorxyz.push_back(*vectory);
343                 vectorxyz.push_back(*vectorz);
344                 contoursmapMM.insert(pair<int, vectorXYZ>(contoursmapMM.size(), vectorxyz));
345                 contoursnameMM.insert(pair<int, string>(contoursnameMM.size(), _roiname));
346         }
347 }
348
349 void OsirixParser::parseOSIRIX_POINT_PX(DOMNodeList* list){
350         int i, stringfound0, stringfound1;
351         DOMNode* node;
352         string temp, osirix_string, numx, numy;
353         vector<double>* vectorx;
354         vector<double>* vectory;        
355         vector<double>* vectorz;        
356         vectorXYZ vectorxyz;
357         double x, y, z; 
358
359         vectorx = new vector<double>;
360         vectory = new vector<double>;   
361         vectorz = new vector<double>;   
362
363         osirix_string = OSIRIX_STRING;
364
365         for(i = 0; i < (int)(list->getLength()); i++){
366                 node = list->item(i);
367                 if(osirix_string.compare(XMLString::transcode(node->getNodeName()))==0){
368                         temp = XMLString::transcode(node->getTextContent());                    
369
370                         stringfound0 = temp.find(",",0);
371                         numx = temp.substr(1, stringfound0-1);                                  
372
373                         stringfound1 = temp.find(")",stringfound0+1);
374                         numy = temp.substr(stringfound0+1, stringfound1-stringfound0-1);
375
376                         x = atof(numx.c_str());         
377                         y = atof(numy.c_str());                                 
378
379                         vectorx->push_back(x);
380                         vectory->push_back(y);  
381                         vectorz->push_back(_imageindex);
382                 }               
383         }
384         if(vectorx->size() > 0){
385                 vectorxyz.push_back(*vectorx);
386                 vectorxyz.push_back(*vectory);  
387                 vectorxyz.push_back(*vectorz);  
388                 contoursmapPX.insert(pair<int, vectorXYZ>(contoursmapPX.size(), vectorxyz));
389                 contoursnamePX.insert(pair<int, string>(contoursnamePX.size(), _roiname));
390         }       
391 }
392                 
393
394
395 void OsirixParser::getData(DOMNodeList* list, std::vector<std::string>& vect, std::string tagname){
396
397         for(int i = 0; i < (int)(list->getLength()); i++){
398                 DOMNode* node = list->item(i);
399                 if(tagname.compare(XMLString::transcode(node->getNodeName()))==0){
400                         std::cout<<"NODENAME "<<XMLString::transcode(node->getTextContent())<<std::endl;
401                         vect.push_back(XMLString::transcode(node->getTextContent()));
402                 }
403
404         }
405 }
406
407 void OsirixParser::saveCreaContoursFormat(){
408         FILE *pFile=fopen(TEMPIMPORTOSIRIXFILE.c_str(),"w+");
409
410         if(pFile){
411                 writeHeader(pFile);
412                 writeContours(pFile);
413                 writeContoursStatic(pFile);
414                 fclose(pFile);
415         }
416 }
417
418 void OsirixParser::writeContoursStatic(FILE* pFile){
419         fprintf(pFile, CREACONTOUR_IMAGEDIMENSIONS);
420         fprintf(pFile, " %d %d %d\n", _extent[1] - _extent[0],_extent[3] - _extent[2], _extent[5] - _extent[4]);
421         fprintf(pFile, CREACONTOUR_IMAGESPACING);
422         fprintf(pFile, " %f %f %f\n", _spacing[0], _spacing[1], _spacing[2]);
423         fprintf(pFile, CREACONTOUR_NUMBEROFCONTOURSSTATIC);
424         fprintf(pFile, " 0\n");
425 }
426
427 void OsirixParser::writeContours(FILE* pFile){
428         
429         map<int, vectorXYZ>::iterator itPX;
430         vector<double> vectx, vecty, vectz;
431         int i, valuez;
432         int dimz = 0, dimy = 0;
433
434         if(_extent != 0){
435                 dimz = _extent[5] - _extent[4] + 1;
436                 dimy = _extent[3] - _extent[2] + 1;
437         }
438
439         /*for (itMM = contoursmapMM.begin(),  itPX = contoursmapPX.begin(); 
440                         itMM != contoursmapMM.end(), itPX != contoursmapPX.end(); 
441                         itMM++, itPX++ ){*/
442         for (itPX = contoursmapPX.begin(); itPX != contoursmapPX.end(); itPX++ ){
443
444                 vectx = ((*itPX).second)[0];
445                 vecty = ((*itPX).second)[1];
446                 vectz = ((*itPX).second)[2];
447
448                 if(!vectz.empty()){
449
450                         valuez = (int) vectz[0] / _spacing[2];
451
452                         fprintf(pFile, CREACONTOUR_INSTANT);
453                         fprintf(pFile, " 1 %d 1 1 1 1\n",dimz - valuez);
454                         fprintf(pFile, CREACONTOUR_TYPEMODEL);
455                         fprintf(pFile, " 1\n");
456                         fprintf(pFile, CREACONTOUR_NUMBEROFCONTROLPOINTS);
457                         fprintf(pFile, " %d\n", vectz.size());
458                         for(i = 0; i < vectx.size(); i++){
459                           fprintf(pFile, "%f %f 900.00\n", vectx[i]/ _spacing[0], dimy - vecty[i]/ _spacing[1]);
460                           // fprintf(pFile, "%f %f %f\n", vectx[i] , vecty[i], vectz[i]);
461                         }               
462                         fprintf(pFile, CREACONTOUR_TYPEVIEW);
463                         fprintf(pFile, " 1\n");
464                         
465                 }
466         }
467 }
468
469 void OsirixParser::writeHeader(FILE* pFile){ 
470          
471
472         fprintf(pFile, CREACONTOUR);
473         fprintf(pFile, "\n");
474         fprintf(pFile, CREACONTOUR_VERSION);
475         fprintf(pFile, "\n");
476         fprintf(pFile, CREACONTOUR_IMAGEDIMENSIONS);
477         fprintf(pFile, " %d %d %d\n", _extent[1] - _extent[0],_extent[3] - _extent[2], _extent[5] - _extent[4]);
478         fprintf(pFile, CREACONTOUR_IMAGESPACING);
479         fprintf(pFile, " %f %f %f\n", _spacing[0], _spacing[1], _spacing[2]);
480         fprintf(pFile, CREACONTOUR_NUMBEROFCONTOURS);
481         fprintf(pFile, " %d\n", contoursmapPX.size());
482
483
484
485 }
486
487
488 std::string OsirixParser::getContoursFileName(){
489         return TEMPIMPORTOSIRIXFILE;
490 }
491
492 /**
493 **      The Error Handler's interface implementation
494 **/
495
496 /**
497         ** Default Constructor
498         **/
499 OsirixParserErrorHandler::OsirixParserErrorHandler()
500 : ErrorHandler(){
501
502
503
504
505 }
506         /**
507         ** Desctructor by defect
508         **/
509 OsirixParserErrorHandler::~OsirixParserErrorHandler(){
510 }
511
512 void    OsirixParserErrorHandler::warning (const SAXParseException &exc){
513 }
514
515 void    OsirixParserErrorHandler::error (const SAXParseException &exc){
516         char c[1000];
517         errormsg = "Column ";
518 //      errormsg +=     itoa(exc.getColumnNumber(),c,10);
519 #ifdef WIN32
520         sprintf_s(c,"%d",(int)(exc.getColumnNumber()));
521 #else
522         sprintf(c,"%d",(int)(exc.getColumnNumber()));
523 #endif
524         errormsg +=     std::string(c);
525
526         errormsg += " Line ";
527 //      errormsg +=     itoa(exc.getLineNumber(),c,10);
528 #ifdef WIN32
529         sprintf_s(c,"%d",(int)(exc.getLineNumber()));
530 #else
531         sprintf(c,"%d",(int)(exc.getLineNumber()));
532 #endif
533         errormsg +=     std::string(c);
534
535         errormsg += " ";
536         errormsg += XMLString::transcode(exc.getMessage());
537
538 }
539
540 void    OsirixParserErrorHandler::fatalError (const SAXParseException &exc){
541         char c[1000];
542         errormsg = "Column ";
543 //      errormsg +=     itoa(exc.getColumnNumber(),c,10);
544 #ifdef WIN32
545         sprintf_s(c,"%d",(int)(exc.getColumnNumber()));
546 #else
547         sprintf(c,"%d",(int)(exc.getColumnNumber()));
548 #endif
549         errormsg +=     std::string(c);
550
551         errormsg += " Line ";
552 //      errormsg +=     itoa(exc.getLineNumber(),c,10);
553 #ifdef WIN32
554         sprintf_s(c,"%d",(int)(exc.getLineNumber()));
555 #else
556         sprintf(c,"%d",(int)(exc.getLineNumber()));
557 #endif
558         errormsg +=     std::string(c);
559
560         errormsg += " ";
561         errormsg += XMLString::transcode(exc.getMessage());
562 }
563
564 void    OsirixParserErrorHandler::resetErrors (){
565 }
566
567 std::string OsirixParserErrorHandler::getErrorMsg(){
568         return this->errormsg;
569 }