~ubuntu-branches/ubuntu/wily/ginkgocadx/wily-proposed

« back to all changes in this revision

Viewing changes to src/cadxcore/main/controllers/dcmtk/dicomimg2dcm.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Tille
  • Date: 2011-05-02 08:09:26 UTC
  • Revision ID: james.westby@ubuntu.com-20110502080926-bql5wep49c7hg91t
Tags: upstream-2.4.1.1
ImportĀ upstreamĀ versionĀ 2.4.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  
 
3
 *  $Id: dicomimg2dcm.cpp 3698 2011-04-14 12:38:49Z carlos $
 
4
 *  Ginkgo CADx Project
 
5
 *
 
6
 *  Copyright 2008-10 MetaEmotion S.L. All rights reserved.
 
7
 *  http://ginkgo-cadx.com
 
8
 *
 
9
 *  This file is licensed under LGPL v3 license.
 
10
 *  See License.txt for details
 
11
 *
 
12
 *
 
13
 */
 
14
//#define _GINKGO_TRACE
 
15
#include <api/globals.h>
 
16
#include <main/controllers/controladorlog.h>
 
17
#include <api/icontextoestudio.h>
 
18
#ifdef verify
 
19
#define MACRO_QUE_ESTORBA verify
 
20
#undef verify
 
21
#endif
 
22
 
 
23
#include <wx/image.h>
 
24
 
 
25
#include <dcmtk/config/osconfig.h>
 
26
#include "libi2d/i2d.h"
 
27
#include "libi2d/i2djpgs.h"
 
28
#include "libi2d/i2dles.h"
 
29
#include "libi2d/i2dplsc.h"
 
30
#include "libi2d/i2dplvlp.h"
 
31
#include "libi2d/i2dplnsc.h"
 
32
#include "dicomimg2dcm.h"
 
33
#include "dcmtk/dcmdata/dcdict.h"
 
34
#include "dcmtk/dcmdata/dchashdi.h"
 
35
 
 
36
#include <dcmtk/dcmsr/dsrdoc.h>
 
37
#include <dcmtk/dcmdata/dcfilefo.h>
 
38
 
 
39
#include <main/controllers/controladorpermisos.h>
 
40
#include <api/internacionalizacion.h>
 
41
 
 
42
 
 
43
//en este grupo se almacenaran los atributos privados de ginkgo
 
44
#define GINKGO_GROUP 0x0011
 
45
 
 
46
class DcmElement;
 
47
 
 
48
namespace GIL {
 
49
        namespace DICOM {
 
50
 
 
51
//region "Helpers"
 
52
 
 
53
                DcmElement* DICOMImg2DCM::CrearElementoConValor(const char* s)
 
54
                {
 
55
                        unsigned int g = 0xffff;
 
56
                        unsigned int e = 0xffff;
 
57
 
 
58
                        OFString dicName, valStr;
 
59
                        OFString msg;
 
60
 
 
61
                        OFString str = s;
 
62
                        size_t pos = str.find('=');
 
63
                        if (pos != OFString_npos) {
 
64
                                valStr = str.substr(pos + 1, str.length());
 
65
                                dicName = str.substr(0, pos);
 
66
                        }
 
67
                        else {
 
68
                                dicName = str;
 
69
                        }
 
70
                        pos = dicName.find("|");
 
71
                        if (pos != OFString_npos) {
 
72
                                if (2 != sscanf(dicName.c_str(),"%x|%x", &g, &e))
 
73
                                {
 
74
                                        LOG_ERROR("Dicomizador", "Error al interpretar el tag " << s);
 
75
                                        return NULL;
 
76
                                }
 
77
                        }
 
78
                        else {
 
79
                                DcmTagKey key(0xffff, 0xffff);
 
80
                                const DcmDataDictionary& globalDataDict = dcmDataDict.rdlock();
 
81
                                const DcmDictEntry *dicent = globalDataDict.findEntry(dicName.c_str());
 
82
                                dcmDataDict.unlock();
 
83
                                if (dicent != NULL) {
 
84
                                        // found dictionary name, copy group and element number
 
85
                                        key = dicent->getKey();
 
86
                                        g = key.getGroup();
 
87
                                        e = key.getElement();
 
88
                                } else {
 
89
                                        // not found in dictionary
 
90
                                        std::cerr <<  "bad key format or dictionary name not found in dictionary: " << dicName << std::endl;
 
91
                                        LOG_ERROR("Dicomizador", "Error al obtener la entrada del diccionario para el tag " << dicName.c_str() << ". Cadena: " << s);
 
92
                                        return NULL;
 
93
                                }
 
94
 
 
95
                        }
 
96
                        DcmTag tag(g, e);
 
97
                        if (tag.error() != EC_Normal) {
 
98
                                std::cerr << "Tag desconocido: (" <<
 
99
                                std::hex << std::setw(4) << std::setfill('0') << g << "|" <<
 
100
                                std::hex << std::setw(4) << std::setfill('0') << e << ")" << std::endl;
 
101
                                return NULL;
 
102
                        }
 
103
                        DcmElement *elem = newDicomElement(tag);
 
104
                        if (elem == NULL) {
 
105
                                std::cerr << "No se pudo crear el elemento para el tag: (" <<
 
106
                                std::hex << std::setw(4) << std::setfill('0') << g << "|" <<
 
107
                                std::hex << std::setw(4) << std::setfill('0') << e << ")" << std::endl;
 
108
                                return NULL;
 
109
                        }
 
110
                        if (valStr.length() > 0) {
 
111
                                if (elem->putString(valStr.c_str()).bad()) {
 
112
                                        std::cerr << "No se pudo asignar el valor al elemento: (" <<
 
113
                                        std::hex << std::setw(4) << std::setfill('0') << g << "|" <<
 
114
                                        std::hex << std::setw(4) << std::setfill('0') << e << ")=" << valStr.c_str() << std::endl;
 
115
                                        delete elem;
 
116
                                        return NULL;
 
117
                                }
 
118
                        }
 
119
                        return elem;
 
120
 
 
121
                }
 
122
 
 
123
//endregion
 
124
 
 
125
 
 
126
                void DICOMImg2DCM::Inicializar(std::string& inputFile, IInspectCallBack* pICallback, bool debug, TDICOMOutputFormat outputFormat)
 
127
                {
 
128
                        LiberarMemoria();
 
129
 
 
130
                        if (inputFile.length() == 0) {
 
131
                                throw I2DException("No se ha especificado el fichero de entrada");
 
132
                        }
 
133
 
 
134
                        GNC::GCS::Permisos::EstadoPermiso mantenerCodificacion = GNC::GCS::ControladorPermisos::Instance()->Get("core.importacion", "mantener");
 
135
 
 
136
                        if (mantenerCodificacion.Activo()) {
 
137
                                //probamos a ver si nos vale cn un JPEG source
 
138
                                I2DJpegSource *jpgSource = new I2DJpegSource();
 
139
                                if (jpgSource == NULL) {
 
140
                                        throw I2DException("No se pudo reservar memoria para realizar la conversion");
 
141
                                }
 
142
                                // Set JPEG Options
 
143
                                // Enable/Disable support for progressive JPEG
 
144
                                jpgSource->setProgrSupport(OFTrue);
 
145
                                // Enable/Disable support for extended sequential JPEG
 
146
                                jpgSource->setExtSeqSupport(OFTrue);
 
147
                                jpgSource->setImageFile(inputFile.c_str());
 
148
                                Inicializar(jpgSource, pICallback, debug, outputFormat);
 
149
                        } else {
 
150
                                wxString nombreImagen = FROMPATH(inputFile);
 
151
                                wxImage img(nombreImagen);
 
152
                                if(!img.Ok())
 
153
                                {
 
154
                                        throw I2DException(_Std("Image format not supported"));
 
155
                                }
 
156
                                if(img.HasAlpha())
 
157
                                {
 
158
                                        throw I2DException(_Std("Image format not supported"));
 
159
                                }
 
160
 
 
161
                                unsigned char* imgData = img.GetData();
 
162
                                Inicializar(imgData, img.GetWidth(), img.GetHeight(), pICallback, debug, outputFormat);
 
163
                        } 
 
164
                }
 
165
 
 
166
                void DICOMImg2DCM::Inicializar(unsigned char* pixelData, const int ancho, const int alto, IInspectCallBack* pICallback, bool debug, TDICOMOutputFormat outputFormat)
 
167
                {
 
168
                        I2DLittleEndianSource* littleEndianSource = new I2DLittleEndianSource();
 
169
                        littleEndianSource->setImageData(pixelData, ancho, alto, 3);
 
170
                        Inicializar(littleEndianSource, pICallback, debug, outputFormat);
 
171
                }
 
172
 
 
173
                void DICOMImg2DCM::Inicializar(I2DImgSource* plugEntrada, IInspectCallBack* pICallback, bool debug, TDICOMOutputFormat outputFormat)
 
174
                {
 
175
                        LiberarMemoria();
 
176
 
 
177
                        inputPlug = plugEntrada;
 
178
 
 
179
                        i2d = new Image2Dcm();
 
180
                        if (i2d == NULL) {
 
181
                                throw I2DException("No se pudo reservar memoria para realizar la conversion");
 
182
                        }
 
183
 
 
184
                        OFBool dMode = OFFalse;
 
185
                        OFBool vMode = OFFalse;
 
186
 
 
187
                        if (debug) {
 
188
                                dMode = OFTrue;
 
189
                                vMode = OFTrue;
 
190
                                i2d->setDebugMode(OFTrue);
 
191
                                i2d->setLogStream(&ofConsole);
 
192
                        }
 
193
 
 
194
                        if (vMode)
 
195
                                std::cout << inputPlug->inputFormat() << std::endl;
 
196
 
 
197
                        if (outputFormat == TDOF_VLP) {
 
198
                                outputPlug = new I2DOutputPlugVLP();
 
199
                        } else if (outputFormat == TDOF_SC) {
 
200
                                outputPlug = new I2DOutputPlugSC();
 
201
                        } else if (outputFormat == TDOF_NSC) {
 
202
                                outputPlug = new I2DOutputPlugNewSC();
 
203
                        } else {
 
204
                                throw I2DException("No existe ningun plugin para el formato de salida especificado");
 
205
                        }
 
206
 
 
207
 
 
208
                        if (vMode)
 
209
                                std::cout << outputPlug->ident() << std::endl;
 
210
 
 
211
                        outputPlug->setDebugMode(dMode);
 
212
                        outputPlug->setLogStream(&ofConsole);
 
213
 
 
214
                        ActualizarCampos(pICallback);
 
215
 
 
216
                        // ISO Latin 1 option
 
217
                        //  setISOLatin1(OFTrue)  => set latin-1 as standard character set
 
218
                        //  setISOLatin1(OFFalse) => keep 7-bit ASCII as standard character set
 
219
                        //  i2d->setISOLatin1(OFTrue);
 
220
                        i2d->setUTF8(OFTrue);
 
221
 
 
222
                        // attribute validity checking
 
223
                        //   enabled/disabled
 
224
                        OFBool doChecks = OFTrue;
 
225
 
 
226
                        // insert missing type 2 attributes (SĆ³lo si doChecks es True)
 
227
                        //   enabled/disabled
 
228
                        OFBool insertType2 = OFTrue;
 
229
 
 
230
                        // invent missing type 1 attributes (SĆ³lo si doChecks es True)
 
231
                        //   enabled/disabled
 
232
                        OFBool inventType1 = OFTrue;
 
233
 
 
234
                        i2d->setValidityChecking(doChecks, insertType2, inventType1);
 
235
                        outputPlug->setValidityChecking(doChecks, insertType2, inventType1);
 
236
 
 
237
                        inputPlug->setDebugMode(dMode);
 
238
                        inputPlug->setLogStream(&ofConsole);
 
239
 
 
240
                        // make sure data dictionary is loaded
 
241
                        if (!dcmDataDict.isDictionaryLoaded()) {
 
242
                                LiberarMemoria();
 
243
                                throw I2DException("No se ha cargado el diccionario de datos");
 
244
                        }
 
245
 
 
246
                        OFCondition cond;
 
247
 
 
248
                        cond = i2d->convert(inputPlug, outputPlug, resultObject, writeXfer);
 
249
 
 
250
                        if (cond.bad()) {
 
251
                                //si es un jpegsource se trata de leer la imagen y convertirla desde little endian... (por aqui pasan los png, bmp,... cuando esta activo el mantener)
 
252
                                I2DJpegSource* pJPeg = dynamic_cast<I2DJpegSource*>(inputPlug);
 
253
                                if (pJPeg != NULL) {
 
254
                                        OFString path = pJPeg->getImageFile();
 
255
                                        LiberarMemoria();
 
256
                                        wxString nombreImagen = FROMPATH(path);
 
257
                                        wxImage img(nombreImagen);
 
258
                                        if(!img.Ok())
 
259
                                        {
 
260
                                                throw I2DException(_Std("Image format not supported"));
 
261
                                        }
 
262
                                        if(img.HasAlpha())
 
263
                                        {
 
264
                                                throw I2DException(_Std("Image format not supported"));
 
265
                                        }
 
266
 
 
267
                                        unsigned char* imgData = img.GetData();
 
268
                                        Inicializar(imgData, img.GetWidth(), img.GetHeight(), pICallback, debug, outputFormat);
 
269
                                } else {
 
270
                                        LiberarMemoria();
 
271
                                        throw I2DException(cond.text());
 
272
                                }
 
273
                        }
 
274
 
 
275
                        if (pICallback != NULL) {
 
276
 
 
277
                                // Dumping DICOM Tags...
 
278
                                DcmDataDictionary& globalDataDict = dcmDataDict.wrlock();
 
279
                                DcmHashDictIterator iter(globalDataDict.normalBegin());
 
280
                                DcmHashDictIterator end(globalDataDict.normalEnd());
 
281
 
 
282
                                std::string keyStr;
 
283
                                std::string descStr;
 
284
                                std::string valStr;
 
285
 
 
286
                                char keyFormat[12];
 
287
 
 
288
                                for (; iter != end; ++iter) {
 
289
 
 
290
                                        DcmTagKey tagkey = (*iter)->getKey();
 
291
                                        //std::cout << "Checking " << keyStr << std::endl;
 
292
                                        if (sprintf(keyFormat, "%04X|%04X", tagkey.getGroup(), tagkey.getElement()) > 8) {
 
293
                                                //std::cout << "Asigning " << keyFormat << std::endl;
 
294
                                                keyStr.assign(keyFormat);
 
295
                                                descStr = (*iter)->getTagName();
 
296
                                                OFString val;
 
297
                                                OFCondition c = resultObject->findAndGetOFStringArray(tagkey, val);
 
298
                                                if (c.good()) {
 
299
                                                        valStr = val.c_str();
 
300
                                                        pICallback->Inspect(keyStr, descStr, valStr);
 
301
                                                }
 
302
                                        }
 
303
                                }
 
304
                                dcmDataDict.unlock();
 
305
                        }
 
306
 
 
307
 
 
308
 
 
309
                        if (pICallback != NULL) {
 
310
                                pICallback->Done();
 
311
                        }
 
312
                }
 
313
 
 
314
                int DICOMImg2DCM::InsertarTagsPrivados(TipoPrivateTags& tags){
 
315
                        return InsertarTagsPrivados(tags,i2d->getOverrideKeys());
 
316
                }
 
317
 
 
318
                int DICOMImg2DCM::InsertarTagsPrivados(TipoPrivateTags& tags, DcmDataset* dcmDataSet){
 
319
                        //se busca el uid en el rango (GINKGO_GROUP,0010-00FF)
 
320
                        unsigned int g=GINKGO_GROUP;
 
321
                        unsigned int e=0;
 
322
                        OFCondition cond;
 
323
                        DcmElement* element;
 
324
 
 
325
                        e=GetElementIdentifier(tags,dcmDataSet);
 
326
 
 
327
                        if(e>0x00FF || e==0){
 
328
                                //no deberia llegar aqui
 
329
                                std::cerr<<"error al almacenar los tags privados, todos los slots ocupados" <<std::endl;
 
330
                                return 0;
 
331
                        }
 
332
 
 
333
                        //ya tenemos el e del modulo hay que hacer un desplazamiento de 8 bits a la izquierda para obtener el rango
 
334
                        //si el elemento es 00xx el rango sera xx00-xxFF
 
335
                        e = e << 8;
 
336
 
 
337
                        unsigned int eTemp;
 
338
                        TipoPrivateTags::ListaTags& ListaTags = tags.GetListaTags();
 
339
                        for (TipoPrivateTags::ListaTags::iterator it = ListaTags.begin(); it != ListaTags.end(); ++it)
 
340
                        {
 
341
                                eTemp = e | (*it).first;
 
342
                                element = (*it).second->ToElement(g,eTemp);
 
343
                                if (element != NULL)
 
344
                                {
 
345
                                        cond = dcmDataSet->insert(element, true, false);
 
346
                                        if (cond.bad()) {
 
347
                                                std::cerr << "error al almacenar los tags privados, error al escribir en el dataset: (" << g << ","<<eTemp<<")" <<std::endl;
 
348
                                                return 0;
 
349
                                        }
 
350
                                } else {
 
351
                                        std::cerr << "error al almacenar los tags privados, error al crear el elemento: (" << g << ","<<eTemp<<")" <<std::endl;
 
352
                                        return 0;                                       
 
353
                                }
 
354
                        }
 
355
 
 
356
                        return 1;
 
357
                }
 
358
 
 
359
                int DICOMImg2DCM::InsertarJerarquia(TipoJerarquia& base) {
 
360
                        if (i2d == NULL) {
 
361
                                throw I2DException("El conversor no se ha inicializado previamente");
 
362
                        }
 
363
 
 
364
                        return InsertarJerarquia(base,i2d->getOverrideKeys(), NULL, NULL);
 
365
                };
 
366
 
 
367
                int DICOMImg2DCM::InsertarJerarquia(TipoJerarquia& base,DcmDataset* dcmDataSet, DcmItem* itemPadre, DcmSequenceOfItems* seqPadre)
 
368
                {
 
369
 
 
370
                        int numTotalInsertados = 0;
 
371
                        int numTagsInsertados  = 0;
 
372
                        int numItemsInsertados = 0;
 
373
                        int numSeqsInsertadas  = 0;
 
374
 
 
375
 
 
376
 
 
377
                        // Insertamos todos los tags correspondientes a este nivel en la raiz (de haberla, si no: en el dataset).
 
378
                        for (TipoJerarquia::ListaTags::iterator it = base.tags.begin(); it != base.tags.end(); it++) {
 
379
                                DcmElement* e = this->CrearElementoConValor((*it).first.c_str());
 
380
                                if (e != NULL) {
 
381
                                        e->putString((*it).second.c_str());
 
382
 
 
383
                                        OFCondition cond;
 
384
                                        if (itemPadre == NULL) {
 
385
                                                cond = dcmDataSet->insert(e, OFTrue);
 
386
                                                char* str = NULL;
 
387
                                                e->getString(str);
 
388
                                                /*if(str!=NULL){
 
389
                                                        std::cout << "raiz << " << e->getTag().toString() <<  "=" << str << std::endl;
 
390
                                                }
 
391
                                                else{
 
392
                                                        std::cout << "raiz << " << e->getTag().toString() <<  "="  << std::endl;
 
393
                                                }*/
 
394
                                        }
 
395
                                        else {
 
396
                                                cond = itemPadre->insert(e, OFTrue);
 
397
                                                char* str = NULL;
 
398
                                                e->getString(str);
 
399
                                                /*if(str!=NULL){
 
400
                                                        std::cout << itemPadre->getTag().toString().c_str() << " << " << e->getTag().toString() << " = " << str << std::endl;
 
401
                                                }
 
402
                                                else{
 
403
                                                        std::cout << itemPadre->getTag().toString().c_str() << " << " << e->getTag().toString() << " = " << std::endl;
 
404
                                                }*/
 
405
 
 
406
 
 
407
                                        }
 
408
                                        if (cond.bad()) {
 
409
                                                std::cerr << "No se pudo insertar el elemento: (" << e->getTag().toString().c_str() << "): " << cond.text() << std::endl;
 
410
                                        }
 
411
                                        else {
 
412
                                                numTotalInsertados++;
 
413
                                                numTagsInsertados++;
 
414
                                        }
 
415
                                }
 
416
                        }
 
417
 
 
418
                        // Insertamos todos los items correspondientes a este nivel en la raiz (de haberla, si no: en el dataset).
 
419
 
 
420
                        for (TipoJerarquia::ListaJerarquias::iterator it = base.items.begin(); it != base.items.end(); it++) {
 
421
                                DcmItem *item = new DcmItem();
 
422
 
 
423
                                int nItems = InsertarJerarquia((*it),dcmDataSet, item, NULL);
 
424
 
 
425
                                if (nItems > 0) {
 
426
 
 
427
                                        OFCondition cond;
 
428
 
 
429
                                        if (seqPadre == NULL) {
 
430
                                                //cond = dcmDataSet->insert(item, OFTrue);
 
431
                                                std::cerr << "No se pudo insertar el item directamente a la raiz. Deben insertarse en secuencias o en otros items.  " << nItems << " elementos perdidos: " << cond.text() << std::endl;
 
432
                                                delete item;
 
433
                                        }
 
434
                                        else {
 
435
                                                cond = seqPadre->insert(item, OFTrue);
 
436
                                        //      std::cout << seqPadre->getTag().toString().c_str() << " << " << item->getTag().toString() << std::endl;
 
437
                                        }
 
438
 
 
439
                                        if (cond.bad()) {
 
440
                                                std::cerr << "No se pudo insertar el item a la raiz.  " << nItems << " elementos perdidos: " << cond.text() << std::endl;
 
441
                                                delete item;
 
442
                                        }
 
443
                                        else {
 
444
                                                numTotalInsertados += nItems + 1;
 
445
                                                numItemsInsertados++;
 
446
                                        }
 
447
                                }
 
448
                                else {
 
449
                                        delete item;
 
450
                                }
 
451
                        }
 
452
 
 
453
                        // Insertamos todas las secuencias correspondientes a este nivel en la raiz (de haberla, si no: en el dataset).
 
454
                        for (TipoJerarquia::ListaJerarquias::iterator it = base.secuencias.begin(); it != base.secuencias.end(); it++) {
 
455
 
 
456
                                std::string claveSecuencia = (*it).tagName;
 
457
                                TipoJerarquia& nbase = (*it);
 
458
 
 
459
                                unsigned int sg = 0xffff;
 
460
                                unsigned int se = 0xffff;
 
461
                                int sn = 0;
 
462
 
 
463
                                sn = sscanf(claveSecuencia.c_str(), "%x|%x", &sg, &se);
 
464
                                if (sn < 2) {
 
465
                                        std::cerr << "Formato invalido (" << claveSecuencia.c_str() << "). Solo se soporta (FFFF|FFFF) como formato de tag para secuencias" << std::endl;
 
466
                                        continue;
 
467
                                }
 
468
                                DcmTag stag(sg, se);
 
469
                                if (stag.error() != EC_Normal) {
 
470
                                        std::cerr << "Tag desconocido: " << claveSecuencia << std::endl;
 
471
                                        continue;
 
472
                                }
 
473
                                DcmSequenceOfItems* seq = new DcmSequenceOfItems(stag);
 
474
                                if (seq == NULL) {
 
475
                                        std::cerr << "No se pudo crear la secuencia para el tag: " << claveSecuencia << std::endl;
 
476
                                        continue;
 
477
                                }
 
478
 
 
479
                                int nItems = InsertarJerarquia(nbase,dcmDataSet, NULL, seq);
 
480
 
 
481
                                if (nItems > 0) {
 
482
 
 
483
                                        OFCondition cond;
 
484
 
 
485
                                        if (seqPadre != NULL) {
 
486
                                                DcmItem* item = new DcmItem();
 
487
                                                cond = item->insert(seq);
 
488
                                                seqPadre->insert(item);
 
489
                                //              std::cout << seqPadre->getTag().toString().c_str() << " << " << seq->getTag().toString() << std::endl;
 
490
                                        }
 
491
                                        else if (itemPadre != NULL) {
 
492
                                                cond = itemPadre->insert(seq, OFTrue);
 
493
                                //              std::cout << itemPadre->getTag().toString().c_str() << " << " << seq->getTag().toString() << std::endl;
 
494
 
 
495
                                        }
 
496
                                        else {
 
497
                                                cond = dcmDataSet->insert(seq, OFTrue);
 
498
                                //              std::cout << "raiz << " << seq->getTag().toString() << std::endl;
 
499
                                        }
 
500
 
 
501
                                        if (cond.bad()) {
 
502
                                                std::cerr << "No se pudo insertar el item a la raiz.  " << nItems << " elementos perdidos: " << cond.text() << std::endl;
 
503
                                                delete seq;
 
504
                                        }
 
505
                                        else {
 
506
                                                numTotalInsertados += nItems + 1;
 
507
                                                numSeqsInsertadas++;
 
508
                                        }
 
509
                                }
 
510
                                else {
 
511
                                        delete seq;
 
512
                                }
 
513
                        }
 
514
                        return numTotalInsertados;
 
515
                }
 
516
 
 
517
                void DICOMImg2DCM::ActualizarCampos(IInspectCallBack* pICallback) {
 
518
                        if (i2d == NULL) {
 
519
                                throw I2DException("El conversor no se ha inicializado previamente");
 
520
                        }
 
521
                        if (pICallback != NULL) {
 
522
                                //DcmDataset *overrideKeys = i2d->getOverrideKeys();
 
523
 
 
524
                                TipoJerarquia jerarquiaAInsertar;
 
525
                                pICallback->ObtenerJerarquiaInserccion(jerarquiaAInsertar);
 
526
                                InsertarJerarquia(jerarquiaAInsertar,i2d->getOverrideKeys(), NULL, NULL);
 
527
                        }
 
528
                }
 
529
 
 
530
                bool DICOMImg2DCM::Convertir(std::string& outputFile)
 
531
                {
 
532
 
 
533
                        if (i2d == NULL || inputPlug == NULL || outputPlug == NULL || resultObject == NULL) {
 
534
                                throw I2DException("El conversor no se ha inicializado previamente");
 
535
                        }
 
536
                        if (outputFile.length() == 0) {
 
537
                                throw I2DException("No se ha especificado el fichero de salida");
 
538
                        }
 
539
 
 
540
                        // Group length encoding mode for output DICOM file
 
541
                        E_GrpLenEncoding grpLengthEnc = EGL_recalcGL;
 
542
                        // Item and Sequence encoding mode for output DICOM file
 
543
                        E_EncodingType lengthEnc = EET_ExplicitLength;
 
544
                        // Padding mode for output DICOM file
 
545
                        E_PaddingEncoding padEnc = EPD_noChange;
 
546
                        // File pad length for output DICOM file
 
547
                        unsigned int filepad = 0;
 
548
                        // Item pad length for output DICOM file
 
549
                        unsigned int itempad = 0;
 
550
 
 
551
                        // Group Length Encoding:
 
552
                        //   EGL_recalcGL  => recalculate group lengths if present
 
553
                        //   EGL_withGL    => always write with group length elements
 
554
                        //   EGL_withoutGL => always write without group length elements
 
555
 
 
556
                        grpLengthEnc = EGL_recalcGL;
 
557
 
 
558
                        // Length Encoding in Sequences and Items:
 
559
                        //   EET_ExplicitLength  => write with explicit lengths
 
560
                        //   EET_UndefinedLength => write with undefined lengths
 
561
                        lengthEnc = EET_ExplicitLength;
 
562
 
 
563
                        filepad = 0;
 
564
                        itempad = 0;
 
565
 
 
566
                        OFCondition cond;
 
567
 
 
568
                        i2d->updateOverrideKeys(resultObject);
 
569
 
 
570
                        DcmFileFormat dcmff(resultObject);
 
571
                        cond = dcmff.saveFile(outputFile.c_str(), writeXfer, lengthEnc, grpLengthEnc, padEnc, filepad, itempad);
 
572
                        if (cond.bad()) {
 
573
                                throw I2DException(cond.text());
 
574
                        }
 
575
 
 
576
#ifdef _GINKGO_TRACE
 
577
                        {
 
578
                                std::cout << "----DUMPING DCM----------------------------------------" << std::endl;
 
579
                                // Dumping DICOM Tags...
 
580
                                const DcmDataDictionary& globalDataDict = dcmDataDict.rdlock();
 
581
                                DcmHashDictIterator iter(globalDataDict.normalBegin());
 
582
                                DcmHashDictIterator end(globalDataDict.normalEnd());
 
583
 
 
584
                                std::string keyStr;
 
585
                                std::string descStr;
 
586
                                std::string valStr;
 
587
 
 
588
                                char keyFormat[12];
 
589
 
 
590
                                for (; iter != end; ++iter) {
 
591
 
 
592
                                        DcmTagKey tagkey = (*iter)->getKey();
 
593
                                        //std::cout << "Checking " << keyStr << std::endl;
 
594
                                        if (sprintf(keyFormat, "%04X|%04X", tagkey.getGroup(), tagkey.getElement()) > 8) {
 
595
                                                //std::cout << "Asigning " << keyFormat << std::endl;
 
596
                                                keyStr.assign(keyFormat);
 
597
                                                descStr = (*iter)->getTagName();
 
598
                                                OFString val;
 
599
                                                OFCondition c = resultObject->findAndGetOFStringArray(tagkey, val);
 
600
                                                if (c.good()) {
 
601
                                                        valStr = val.c_str();
 
602
                                                        std::cout << "[" << keyStr.c_str() << "] " << valStr.c_str() << " // " << descStr.c_str() << std::endl;
 
603
                                                }
 
604
                                        }
 
605
                                }
 
606
                                dcmDataDict.unlock();
 
607
                                std::cout << "-------------------------------------------------------" << std::endl;
 
608
                        }
 
609
#endif
 
610
                        return true;
 
611
                }
 
612
 
 
613
                //devuelve el element identifier donde el modulo puede escribir sus tags privados
 
614
                unsigned int DICOMImg2DCM::GetElementIdentifier(GIL::DICOM::TipoPrivateTags& tags, DcmDataset* dataset){
 
615
                        OFCondition cond;
 
616
                        DcmElement* element;
 
617
                        unsigned int g=GINKGO_GROUP;
 
618
                        unsigned int e=0x0010;
 
619
 
 
620
                        for(;e<=0x00FF;e++){
 
621
                                DcmTagKey key(g,e);
 
622
                                cond = dataset->findAndGetElement(key,element,false);
 
623
                                if(element==NULL){
 
624
                                        //esta libre el slot
 
625
                                        //se introduce el uid
 
626
                                        DcmTagKey key(g,e);
 
627
                                        DcmTag tag(key);
 
628
                                        //tipo short string!!!!
 
629
                                        DcmVR vr(EVR_SH);
 
630
                                        tag.setVR(vr);
 
631
                                        if (tag.error() != EC_Normal) {
 
632
                                                std::cerr << "error al almacenar los tags privados, tag desconocido: (" << g << ","<<e<<")" <<std::endl;
 
633
                                                return 0;
 
634
                                        }
 
635
 
 
636
                                        element = newDicomElement(tag);
 
637
 
 
638
                                        if(element==NULL){
 
639
                                                std::cerr << "error al almacenar los tags privados, error al crear el elemento uid: (" << g << ","<<e<<")" <<std::endl;
 
640
                                                return 0;
 
641
                                        }
 
642
 
 
643
                                        cond=element->putString(tags.UIDModulo.c_str());
 
644
 
 
645
                                        if (cond.bad()) {
 
646
                                                std::cerr << "error al almacenar los tags privados, error al escribir el uid: (" << g << ","<<e<<")" <<std::endl;
 
647
                                                return 0;
 
648
                                        }
 
649
 
 
650
                                        cond = dataset->insert(element, true, false);
 
651
                                        break;
 
652
                                }
 
653
 
 
654
                                if(element!=NULL){
 
655
                                        char* cadena;
 
656
                                        std::string ov;
 
657
 
 
658
                                        cond = element->getString(cadena);
 
659
                                        if (cond.good()) {
 
660
                                                ov = std::string(cadena);
 
661
                                        } else {
 
662
                                                continue;
 
663
                                        }
 
664
 
 
665
                                        if(ov==tags.UIDModulo){
 
666
                                                //estamos en el g y e del modulo deseado
 
667
                                                break;
 
668
                                        }
 
669
                                }
 
670
                        }
 
671
 
 
672
                        return e;
 
673
                }
 
674
 
 
675
                bool DICOMImg2DCM::CrearSRDoc(std::string& outputFile, TipoJerarquia& base, std::list<GnkPtr<TipoPrivateTags> >& tagsPrivados) {
 
676
                        DSRDocument *doc = new DSRDocument();
 
677
                        if (doc != NULL)
 
678
                        {
 
679
 
 
680
                                doc->createNewDocument(DSRTypes::DT_BasicTextSR);
 
681
                                doc->setSpecificCharacterSetType(DSRTypes::CS_UTF8);
 
682
                                doc->setSpecificCharacterSet("ISO_IR 192");
 
683
 
 
684
                                doc->setManufacturer("Ginkgo");
 
685
                                doc->setPatientName("Last Name^First Name");
 
686
                                doc->setPatientSex("O");
 
687
                                doc->setReferringPhysicianName("Last Name^First Name");
 
688
 
 
689
                                doc->getTree().addContentItem(DSRTypes::RT_isRoot, DSRTypes::VT_Container);
 
690
 
 
691
                                DcmFileFormat *fileformat = new DcmFileFormat();
 
692
 
 
693
                                DcmDataset *dataset = NULL;
 
694
 
 
695
                                OFCondition cond;
 
696
 
 
697
                                if (fileformat != NULL)
 
698
                                        dataset = fileformat->getDataset();
 
699
                                if (dataset != NULL)
 
700
                                {
 
701
                                        cond = doc->write(*dataset);
 
702
                                        if (cond.good()){
 
703
                                                //utf-8
 
704
                                                if( dataset->putAndInsertOFStringArray(DCM_SpecificCharacterSet, "ISO_IR 192").bad()) {
 
705
                                                        LOG_ERROR("Dicomizacion", "Error al establecer la codificacion en el fichero DICOM");
 
706
                                                }
 
707
                                                InsertarJerarquia(base,dataset,NULL,NULL);
 
708
                                                for(std::list<GnkPtr<TipoPrivateTags> >::iterator it = tagsPrivados.begin(); it!= tagsPrivados.end(); it++){
 
709
                                                        InsertarTagsPrivados(*(*it),dataset);
 
710
                                                }
 
711
                                                //SE ESCRIBE LOS TAGS DEL SR...
 
712
 
 
713
                                                cond = fileformat->saveFile(outputFile.c_str(), EXS_LittleEndianExplicit);
 
714
                                        }
 
715
                                }
 
716
                                delete fileformat;
 
717
 
 
718
                                delete doc;
 
719
 
 
720
                                if (cond.good()){
 
721
                                        return true;
 
722
                                } else {
 
723
                                        return false;
 
724
                                }
 
725
                        }
 
726
                        return false;
 
727
                }
 
728
        }
 
729
}