]> Creatis software - creaContours.git/blob - lib/kernel_ManagerContour_NDimensions/ParserOsirix/OsirixParser.cxx
#3206 creaContours Feature New Normal branch vtk7itk4wx3-mingw
[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         
99     wchar_t currentPath2[512];
100     long result = GetModuleFileName(NULL, currentPath2, pathsize);
101 //      GetModuleFileName(NULL, currentPath, _MAX_PATH);
102         int ret = wcstombs ( currentPath, currentPath2, sizeof(pname) );        
103         
104         TEMPIMPORTOSIRIXFILE = currentPath;
105
106         TEMPIMPORTOSIRIXFILE = TEMPIMPORTOSIRIXFILE.substr(0,TEMPIMPORTOSIRIXFILE.find_last_of("\\"));
107
108         TEMPIMPORTOSIRIXFILE.append("\\data\\TEMPIMPORTOSIRIXFILE.roi");
109         
110 #else
111         char * pPath;
112         pPath = getenv ("HOME");
113
114         if(pPath){
115             TEMPIMPORTOSIRIXFILE.append(pPath);
116         }else{
117             TEMPIMPORTOSIRIXFILE.append(".");
118         }
119         TEMPIMPORTOSIRIXFILE.append("/.creaContourDataTemp/TEMPIMPORTOSIRIXFILE.roi");
120 #endif
121         
122 }
123 OsirixParser::~OsirixParser(){
124
125 }
126
127 int OsirixParser::ParseFile(const char* xmlfile){
128
129         xercesc::DOMDocument *doc;
130
131
132         try {
133             XMLPlatformUtils::Initialize();
134         }
135         catch (const XMLException& toCatch) {
136             char* message = XMLString::transcode(toCatch.getMessage());
137             cout << "Error during initialization! :\n"
138                  << message << "\n";
139             XMLString::release(&message);
140             return 1;
141         }
142
143         XercesDOMParser* OsirixParser = new XercesDOMParser();
144
145
146                 OsirixParser->setDoNamespaces(true);
147                 OsirixParser->setDoSchema(true);
148                 OsirixParser->setValidationScheme(XercesDOMParser::Val_Always );
149                 OsirixParser->setExternalNoNamespaceSchemaLocation(XMLString::transcode(schema.c_str()));
150                 OsirixParser->setValidationSchemaFullChecking(true);
151                 OsirixParser->setValidationConstraintFatal(true);
152                 OsirixParser->setExitOnFirstFatalError(true);
153
154
155         ErrorHandler* errHandler = (ErrorHandler*) new OsirixParserErrorHandler();
156
157         OsirixParser->setErrorHandler(errHandler);
158
159
160         try {
161             OsirixParser->parse(xmlfile);
162
163
164                         if(OsirixParser->getErrorCount() > 0){
165
166                                 errorline = ((OsirixParserErrorHandler*)OsirixParser->getErrorHandler())->getErrorMsg();
167
168
169                                 delete OsirixParser;
170                                 delete errHandler;
171                                 return -2;
172                         }
173
174
175
176         }
177         catch (const XMLException& toCatch) {
178             char* message = XMLString::transcode(toCatch.getMessage());
179             cout << "Exception message is: \n"
180                  << message << "\n";
181             XMLString::release(&message);
182                         delete OsirixParser;
183                     delete errHandler;
184             return -1;
185         }
186         catch (const DOMException& toCatch) {
187             char* message = XMLString::transcode(toCatch.msg);
188             cout << "Exception message is: \n"
189                  << message << "\n";
190             XMLString::release(&message);
191                         delete OsirixParser;
192                         delete errHandler;
193             return -1;
194         }
195         catch (...) {
196             cout << "Unexpected Exception \n" ;
197                         delete OsirixParser;
198                         delete errHandler;
199             return -1;
200         }
201
202                 std::cout<<"parsing document..."<<std::endl;
203
204
205         doc = OsirixParser->getDocument();
206 //              DOMNodeList* list = doc->getChildNodes();               
207                 getUserData(doc->getDocumentElement());
208
209
210                 saveCreaContoursFormat();
211
212         delete OsirixParser;
213         delete errHandler;
214
215
216
217                 return 0;
218
219 }
220
221 void OsirixParser::setErrorLine(DOMNodeList* list){
222
223         DOMNode* node = list->item(0);
224         this->errorline =       XMLString::transcode(node->getTextContent());
225
226 }
227 DOMNode* OsirixParser::getLastNode(DOMNodeList* list){
228
229
230         DOMNode* node;
231         /*for(int i = list->getLength()-1; i >= 0 ;i--){
232
233                 node = list->item(i);
234
235                 if(node->getNodeType() == DOMNode::ELEMENT_NODE){
236                         i = -1;
237                 }
238
239         }*/
240         node = list->item(list->getLength()-1);
241
242
243
244         if(node->getChildNodes()->getLength()>0){
245                 return getLastNode(node->getChildNodes());
246         }
247         return node;
248
249 }
250
251 void OsirixParser::getUserData(DOMElement* element){
252         parseOSIRIX_DICT(element->getElementsByTagName(XMLString::transcode(OSIRIX_DICT)));
253 }
254
255 void OsirixParser::parseOSIRIX_DICT(DOMNodeList* list){
256         int i, j;
257         DOMNode* node, *childnode, *childnode1, *childarray;
258         std::string point_mm, point_px, osirixinteger, imageindex, temp;
259         DOMNodeList* childlist;
260         point_mm = OSIRIX_POINT_MM;
261         point_px = OSIRIX_POINT_PX;
262         imageindex = OSIRIX_IMAGEINDEX;
263         osirixinteger = OSIRIX_INTEGER;
264         
265         std::string osirixstring = OSIRIX_STRING;
266         std::string osirixname = OSIRIX_NAME;
267         
268
269         for(i = 0; i < (int)(list->getLength()); i++){
270                 node = list->item(i);           
271                 childlist = node->getChildNodes();
272                 for(j = 0; j < (int)(childlist->getLength());j++){
273                         childnode = childlist->item(j);                 
274                         temp = XMLString::transcode(childnode->getTextContent());       
275
276
277                         if(point_mm.compare(temp)==0){                          
278                                 childarray = childlist->item(j+2);
279                                 //temp = XMLString::transcode(childarray->getNodeName());                                       
280                                 if(childarray != 0){                                    
281                                         parseOSIRIX_POINT_MM(childarray->getChildNodes());                                      
282                                 }                               
283                         }else if(point_px.compare(temp)==0){                            
284                                 childarray = childlist->item(j+2);
285                                 //temp = XMLString::transcode(childarray->getNodeName());                                       
286                                 if(childarray != 0){                                    
287                                         parseOSIRIX_POINT_PX(childarray->getChildNodes());                                      
288                                 }                               
289                         }else if(imageindex.compare(temp) == 0){
290                                 childnode1 = childlist->item(j+2);
291                                 if(childnode1 != NULL && osirixinteger.compare(XMLString::transcode(childnode1->getNodeName())) == 0){
292                                         _imageindex = atoi(XMLString::transcode(childnode1->getTextContent()));                                         
293                                 }                               
294                         } else if(osirixname.compare(temp) == 0) {
295                           // keep information about the name of the ROI
296                                 childnode1 = childlist->item(j+2);
297                                 if(childnode1 != NULL && osirixstring.compare(XMLString::transcode(childnode1->getNodeName())) == 0){
298                                   char* roiname = XMLString::transcode(childnode1->getTextContent());
299                                   _roiname = string(roiname);
300                                 }
301                         }
302                 }               
303         }
304 }
305
306 void OsirixParser::parseOSIRIX_POINT_MM(DOMNodeList* list){
307         int i, stringfound0, stringfound1;
308         DOMNode* node;
309         string temp, osirix_string, numx, numy, numz;
310         vector<double>* vectorx;
311         vector<double>* vectory;
312         vector<double>* vectorz;
313         vectorXYZ vectorxyz;
314         double x, y, z; 
315
316         vectorx = new vector<double>;
317         vectory = new vector<double>;
318         vectorz = new vector<double>;
319
320         osirix_string = OSIRIX_STRING;
321
322         for(i = 0; i < (int)(list->getLength()); i++){
323                 node = list->item(i);
324                 if(osirix_string.compare(XMLString::transcode(node->getNodeName()))==0){
325                         temp = XMLString::transcode(node->getTextContent());                    
326
327                         stringfound0 = temp.find(",",0);
328                         numx = temp.substr(1, stringfound0-1);
329
330                         stringfound1 = temp.find(",",stringfound0+1);
331                         numy = temp.substr(stringfound0+1, stringfound1-stringfound0-1);
332
333                         stringfound0 = temp.find(")",stringfound1+1);
334                         numz = temp.substr(stringfound1+1, stringfound0-stringfound1-1);
335
336                         x = atof(numx.c_str());         
337                         y = atof(numy.c_str());         
338                         z = atof(numz.c_str());         
339
340                         vectorx->push_back(x);
341                         vectory->push_back(y);
342                         vectorz->push_back(z);
343                 }               
344         }
345         if(vectorx->size() > 0){
346                 vectorxyz.push_back(*vectorx);
347                 vectorxyz.push_back(*vectory);
348                 vectorxyz.push_back(*vectorz);
349                 contoursmapMM.insert(pair<int, vectorXYZ>(contoursmapMM.size(), vectorxyz));
350                 contoursnameMM.insert(pair<int, string>(contoursnameMM.size(), _roiname));
351         }
352 }
353
354 void OsirixParser::parseOSIRIX_POINT_PX(DOMNodeList* list){
355         int i, stringfound0, stringfound1;
356         DOMNode* node;
357         string temp, osirix_string, numx, numy;
358         vector<double>* vectorx;
359         vector<double>* vectory;        
360         vector<double>* vectorz;        
361         vectorXYZ vectorxyz;
362         double x, y, z; 
363
364         vectorx = new vector<double>;
365         vectory = new vector<double>;   
366         vectorz = new vector<double>;   
367
368         osirix_string = OSIRIX_STRING;
369
370         for(i = 0; i < (int)(list->getLength()); i++){
371                 node = list->item(i);
372                 if(osirix_string.compare(XMLString::transcode(node->getNodeName()))==0){
373                         temp = XMLString::transcode(node->getTextContent());                    
374
375                         stringfound0 = temp.find(",",0);
376                         numx = temp.substr(1, stringfound0-1);                                  
377
378                         stringfound1 = temp.find(")",stringfound0+1);
379                         numy = temp.substr(stringfound0+1, stringfound1-stringfound0-1);
380
381                         x = atof(numx.c_str());         
382                         y = atof(numy.c_str());                                 
383
384                         vectorx->push_back(x);
385                         vectory->push_back(y);  
386                         vectorz->push_back(_imageindex);
387                 }               
388         }
389         if(vectorx->size() > 0){
390                 vectorxyz.push_back(*vectorx);
391                 vectorxyz.push_back(*vectory);  
392                 vectorxyz.push_back(*vectorz);  
393                 contoursmapPX.insert(pair<int, vectorXYZ>(contoursmapPX.size(), vectorxyz));
394                 contoursnamePX.insert(pair<int, string>(contoursnamePX.size(), _roiname));
395         }       
396 }
397                 
398
399
400 void OsirixParser::getData(DOMNodeList* list, std::vector<std::string>& vect, std::string tagname){
401
402         for(int i = 0; i < (int)(list->getLength()); i++){
403                 DOMNode* node = list->item(i);
404                 if(tagname.compare(XMLString::transcode(node->getNodeName()))==0){
405                         std::cout<<"NODENAME "<<XMLString::transcode(node->getTextContent())<<std::endl;
406                         vect.push_back(XMLString::transcode(node->getTextContent()));
407                 }
408
409         }
410 }
411
412 void OsirixParser::saveCreaContoursFormat(){
413         FILE *pFile=fopen(TEMPIMPORTOSIRIXFILE.c_str(),"w+");
414
415         if(pFile){
416                 writeHeader(pFile);
417                 writeContours(pFile);
418                 writeContoursStatic(pFile);
419                 fclose(pFile);
420         }
421 }
422
423 void OsirixParser::writeContoursStatic(FILE* pFile){
424         fprintf(pFile, CREACONTOUR_IMAGEDIMENSIONS);
425         fprintf(pFile, " %d %d %d\n", _extent[1] - _extent[0],_extent[3] - _extent[2], _extent[5] - _extent[4]);
426         fprintf(pFile, CREACONTOUR_IMAGESPACING);
427         fprintf(pFile, " %f %f %f\n", _spacing[0], _spacing[1], _spacing[2]);
428         fprintf(pFile, CREACONTOUR_NUMBEROFCONTOURSSTATIC);
429         fprintf(pFile, " 0\n");
430 }
431
432 void OsirixParser::writeContours(FILE* pFile){
433         
434         map<int, vectorXYZ>::iterator itPX;
435         vector<double> vectx, vecty, vectz;
436         int i, valuez;
437         int dimz = 0, dimy = 0;
438
439         if(_extent != 0){
440                 dimz = _extent[5] - _extent[4] + 1;
441                 dimy = _extent[3] - _extent[2] + 1;
442         }
443
444         /*for (itMM = contoursmapMM.begin(),  itPX = contoursmapPX.begin(); 
445                         itMM != contoursmapMM.end(), itPX != contoursmapPX.end(); 
446                         itMM++, itPX++ ){*/
447         for (itPX = contoursmapPX.begin(); itPX != contoursmapPX.end(); itPX++ ){
448
449                 vectx = ((*itPX).second)[0];
450                 vecty = ((*itPX).second)[1];
451                 vectz = ((*itPX).second)[2];
452
453                 if(!vectz.empty()){
454
455                         valuez = (int) vectz[0] / _spacing[2];
456
457                         fprintf(pFile, CREACONTOUR_INSTANT);
458                         fprintf(pFile, " 1 %d 1 1 1 1\n",dimz - valuez);
459                         fprintf(pFile, CREACONTOUR_TYPEMODEL);
460                         fprintf(pFile, " 1\n");
461                         fprintf(pFile, CREACONTOUR_NUMBEROFCONTROLPOINTS);
462                         fprintf(pFile, " %d\n", vectz.size());
463                         for(i = 0; i < vectx.size(); i++){
464                           fprintf(pFile, "%f %f 900.00\n", vectx[i]/ _spacing[0], dimy - vecty[i]/ _spacing[1]);
465                           // fprintf(pFile, "%f %f %f\n", vectx[i] , vecty[i], vectz[i]);
466                         }               
467                         fprintf(pFile, CREACONTOUR_TYPEVIEW);
468                         fprintf(pFile, " 1\n");
469                         
470                 }
471         }
472 }
473
474 void OsirixParser::writeHeader(FILE* pFile){ 
475          
476
477         fprintf(pFile, CREACONTOUR);
478         fprintf(pFile, "\n");
479         fprintf(pFile, CREACONTOUR_VERSION);
480         fprintf(pFile, "\n");
481         fprintf(pFile, CREACONTOUR_IMAGEDIMENSIONS);
482         fprintf(pFile, " %d %d %d\n", _extent[1] - _extent[0],_extent[3] - _extent[2], _extent[5] - _extent[4]);
483         fprintf(pFile, CREACONTOUR_IMAGESPACING);
484         fprintf(pFile, " %f %f %f\n", _spacing[0], _spacing[1], _spacing[2]);
485         fprintf(pFile, CREACONTOUR_NUMBEROFCONTOURS);
486         fprintf(pFile, " %d\n", contoursmapPX.size());
487
488
489
490 }
491
492
493 std::string OsirixParser::getContoursFileName(){
494         return TEMPIMPORTOSIRIXFILE;
495 }
496
497 /**
498 **      The Error Handler's interface implementation
499 **/
500
501 /**
502         ** Default Constructor
503         **/
504 OsirixParserErrorHandler::OsirixParserErrorHandler()
505 : ErrorHandler(){
506
507
508
509
510 }
511         /**
512         ** Desctructor by defect
513         **/
514 OsirixParserErrorHandler::~OsirixParserErrorHandler(){
515 }
516
517 void    OsirixParserErrorHandler::warning (const SAXParseException &exc){
518 }
519
520 void    OsirixParserErrorHandler::error (const SAXParseException &exc){
521         char c[1000];
522         errormsg = "Column ";
523 //      errormsg +=     itoa(exc.getColumnNumber(),c,10);
524 #ifdef WIN32
525         sprintf_s(c,"%d",(int)(exc.getColumnNumber()));
526 #else
527         sprintf(c,"%d",(int)(exc.getColumnNumber()));
528 #endif
529         errormsg +=     std::string(c);
530
531         errormsg += " Line ";
532 //      errormsg +=     itoa(exc.getLineNumber(),c,10);
533 #ifdef WIN32
534         sprintf_s(c,"%d",(int)(exc.getLineNumber()));
535 #else
536         sprintf(c,"%d",(int)(exc.getLineNumber()));
537 #endif
538         errormsg +=     std::string(c);
539
540         errormsg += " ";
541         errormsg += XMLString::transcode(exc.getMessage());
542
543 }
544
545 void    OsirixParserErrorHandler::fatalError (const SAXParseException &exc){
546         char c[1000];
547         errormsg = "Column ";
548 //      errormsg +=     itoa(exc.getColumnNumber(),c,10);
549 #ifdef WIN32
550         sprintf_s(c,"%d",(int)(exc.getColumnNumber()));
551 #else
552         sprintf(c,"%d",(int)(exc.getColumnNumber()));
553 #endif
554         errormsg +=     std::string(c);
555
556         errormsg += " Line ";
557 //      errormsg +=     itoa(exc.getLineNumber(),c,10);
558 #ifdef WIN32
559         sprintf_s(c,"%d",(int)(exc.getLineNumber()));
560 #else
561         sprintf(c,"%d",(int)(exc.getLineNumber()));
562 #endif
563         errormsg +=     std::string(c);
564
565         errormsg += " ";
566         errormsg += XMLString::transcode(exc.getMessage());
567 }
568
569 void    OsirixParserErrorHandler::resetErrors (){
570 }
571
572 std::string OsirixParserErrorHandler::getErrorMsg(){
573         return this->errormsg;
574 }