DCMTK引用dicom.dic等dic文件问题

引起的错误

在linux含有DCMTK的程序发布后,发现读出的tag信息有错误,主要为:

  1. findAndGetString、findAndGetStringArray等拿到的字符串在tag为非字符串时错误,打印出来之后发现OFString存的是对应的16进制,而非正常的类似atoi函数一样的,自动转换为对应的值。例如:

TAG:DCM_PixelSpacing 值为:0.647135,0.647135

findAndGetOFStringArray(DCM_PixelSpacing, imageSpacingString)

读出应该是: “.6471354.6471354”

而读取dicom.dic错误的情况下是:“2e\36\34\37\31\33\35\34\5c\2e\36\34\37\31\33\35\34\20”

  1. 读取 seriesUID错误
dataset->findAndGetOFString(DCM_SeriesInstanceUID, seriesIDString)

seriesUIDString返回的值是studyUID

问题根源

问题根源是dicom.dic没有正确被读取导致,跟踪dcmtk的代码,发现这个文件可以在CMake编译时,DCMTK_DEFAULT_DICT ,选择Builtin(Unix类默认)或者External(windows下默认)。
但是根据实际测试(3.6.7发布版本),即使在linux下选择了 Builtin ,似乎也没有把dic文件内置。

最后定位到源码 dcdict.cc 的代码如下:

#define DCM_DICT_ENVIRONMENT_VARIABLE   "DCMDICTPATH"

OFBool
DcmDataDictionary::loadExternalDictionaries()
{
    const char* env = NULL;
    size_t len;
    int sepCnt = 0;
    OFBool loadFailed = OFFalse;

    /* if DCMDICTPATH environment variable should be considered, read it */
#ifdef DCM_DICT_USE_DCMDICTPATH
    env = getenv(DCM_DICT_ENVIRONMENT_VARIABLE);
#endif
    /* if DCMDICTPATH environment variable is not set or empty,
     * and reading of external dictionary is generally permitted,
     * try to read dictionary from default path
     */
    if ((env == NULL) || (strlen(env) == 0)) {
#if DCM_DICT_DEFAULT == DCM_DICT_DEFAULT_USE_EXTERNAL
        env = DCM_DICT_DEFAULT_PATH;
#endif
    }

    /* if any mechanism for external dictionary (environment or default external)
     * is actually provided it, parse env and load all dictionaries specified therein.
     */
    if ((env != NULL) && (strlen(env) != 0)) {
        len = strlen(env);
        for (size_t i = 0; i < len; ++i) {
            if (env[i] == ENVIRONMENT_PATH_SEPARATOR) {
                sepCnt++;
            }
        }

        if (sepCnt == 0) {
            if (!loadDictionary(env, OFTrue)) {
                return OFFalse;
            }
        } else {
            char** dictArray;

            dictArray = OFstatic_cast(char **, malloc((sepCnt + 1) * sizeof(char*)));

            int ndicts = splitFields(env, dictArray, sepCnt + 1,
                                     ENVIRONMENT_PATH_SEPARATOR);

            for (int ii = 0; ii < ndicts; ii++) {
                if ((dictArray[ii] != NULL) && (strlen(dictArray[ii]) > 0)) {
                    if (!loadDictionary(dictArray[ii], OFTrue)) {
                        loadFailed = OFTrue;
                    }
                }
                free(dictArray[ii]);
            }
            free(dictArray);
        }
    }
    return (loadFailed) ? (OFFalse) : (OFTrue);
}

可以看到dcmtk尝试加载环境变量DCMDICTPATH指向的路径下的dic文件,如果没有则去< datadir >/dicom.dic 去找,如果还没有则使用默认(问题出现在默认上)。

解决思路

比较推荐的是dcdict.h 使用了全局单例,可以直接访问GlobalDcmDataDictionary的单例dcmDataDict,手动调用

const DcmDataDictionary &globalDataDict = dcmDataDict.rdlock();
globalDataDict .loadExternalDictionaries() 
	……
dcmDataDict.rdunlock();

或者:
配置环境变量 DCMDICTPATH ,或者将dic文件拷贝到目标机器和本地同样的 < datadir >/dicom.dic 位置(不推荐,会污染目标机环境)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值