JEPG转DICOM

 

//======================================================================================
// NanJing ChunRen L.T.D
// Created by HGB
//======================================================================================
/*convert.h*/


#ifdef __cplusplus
extern "C" {
#endif


// 下列部分用于定义SCU/SCP回调函数

//typedef void (__stdcall * STORESCPCALLBACK)(T_StoreProgress* progress, LPCSTR filename);

// 下列函数用于处理SCU高级网络服务
/*BOOL __stdcall dicom_echoscu_execute(LPCSTR servername, int serverport,
          LPCSTR servertitle, LPCSTR clienttitle);
BOOL __stdcall dicom_storescu_execute(LPCSTR servername, int serverport,
           LPCSTR servertitle, LPCSTR clienttitle,
           LPCSTR filelist, STORESCUCALLBACK callback);*/

// 下列函数用于处理SCP高级网络服务
//int __declspec(dllexport) IncInt(int params);
bool __stdcall jpg2dcm(LPSTR BmpSrc, LPSTR DcmDest, LPSTR PatientName, LPSTR PatientSex);
//int __stdcall(dllexport) IncInt(int params);


#ifdef __cplusplus
}
#endif
 

#ifdef __cplusplus

extern "C" {
#endif


// 下列部分用于定义SCU/SCP回调函数

//typedef void (__stdcall * STORESCPCALLBACK)(T_StoreProgress* progress, LPCSTR filename);

// 下列函数用于处理SCU高级网络服务
/*BOOL __stdcall dicom_echoscu_execute(LPCSTR servername, int serverport,
          LPCSTR servertitle, LPCSTR clienttitle);
BOOL __stdcall dicom_storescu_execute(LPCSTR servername, int serverport,
           LPCSTR servertitle, LPCSTR clienttitle,
           LPCSTR filelist, STORESCUCALLBACK callback);*/

// 下列函数用于处理SCP高级网络服务
//int __declspec(dllexport) IncInt(int params);
bool __stdcall jpg2dcm(LPSTR BmpSrc, LPSTR DcmDest, LPSTR PatientName, LPSTR PatientSex);
//int __stdcall(dllexport) IncInt(int params);


#ifdef __cplusplus
}
 

#endif


 

//======================================================================================
// NanJing ChunRen L.T.D
// Created by HGB
//======================================================================================
 

/*convert.cpp*/
 

// convert.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
//#include <afx.h>
#include "convert.h"
#include "xImageDCM.h"

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}


int IncInt(int params)
{
    return params+1;
}


bool __stdcall jpg2dcm(LPSTR BmpSrc, LPSTR DcmDest, LPSTR PatientID, LPSTR PatientName,
                       LPSTR PatientSex, LPSTR StudyDate)
{
    CxImageDCM dcm;
    //CString    m_sBmpSrcFile;
    //CString    m_sDcmDestFile;
    //dcm.Load(BmpSrc,CXIMAGE_FORMAT_BMP);
    dcm.Load(BmpSrc,CXIMAGE_FORMAT_JPG);
    if(!dcm.IsValid()){
        return false;
    }else{
        /*m_sBmpSrcFile=filename;
        m_sDcmDestFile=m_sBmpSrcFile;
        m_sDcmDestFile.TrimRight(filename);
        m_sDcmDestFile+=_T("dcm");*/
        //if(dcm.SaveAsDCM(m_sDcmDestFile))
        if(dcm.SaveAsDCM(DcmDest, PatientID, PatientName, PatientSex, StudyDate))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}


 

//======================================================================================
// NanJing ChunRen L.T.D
// Created by HGB
//======================================================================================

// xImageDCM.cpp: implementation of the CxImageDCM class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
//#include "DCMConverter.h"
#include "xImageDCM.h"


#include "osconfig.h"    /* make sure OS specific configuration is included first */


#ifdef HAVE_GUSI_H
#include <GUSI.h>
#endif

#include "dctk.h"          /* for various dcmdata headers */
#include "dcdebug.h"       /* for SetDebugLevel */
#include "cmdlnarg.h"      /* for prepareCmdLineArgs */
#include "dcuid.h"         /* for dcmtk version name */
#include "dcrledrg.h"      /* for DcmRLEDecoderRegistration */

#include "dcmp_w_picpath.h"      /* for DicomImage */
#include "digsdfn.h"       /* for DiGSDFunction */
#include "diciefn.h"       /* for DiCIELABFunction */

#include "ofconapp.h"      /* for OFConsoleApplication */
#include "ofcmdln.h"       /* for OFCommandLine */

#include "diregist.h"      /* include to support color p_w_picpaths */
#include "ofstd.h"         /* for OFStandard */

#include "djdecode.h"     /* for dcmjpeg decoders */
#include "dipijpeg.h"     /* for dcmp_w_picpath JPEG plugin */
#include "dipitiff.h"     /* for dcmp_w_picpath TIFF plugin */
#include "dipipng.h"      /* for dcmp_w_picpath PNG plugin */
#include "zlib.h"         /* for zlibVersion() */

#include "ofstream.h"


/*#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif*/




//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CxImageDCM::CxImageDCM()
{
    //init pointers
    pDib = pSelection = pAlpha = NULL;
    pLayers = NULL;
    //init structures
    memset(&head,0,sizeof(BITMAPINFOHEADER));
    memset(&info,0,sizeof(CXIMAGEINFO));
    //init default attributes
    info.dwType = 0;
    info.nQuality = 90;
    info.nAlphaMax = 255;
    info.nBkgndIndex = -1;
    info.bEnabled = true;
    SetXDPI(96);
    SetYDPI(96);
}

CxImageDCM::~CxImageDCM()
{

}

bool CxImageDCM::SaveAsBMP(const TCHAR *fileName)
{//please refer to the implementation of dcmj2pnm
    return false;
}

bool CxImageDCM::SaveAsJPG(const TCHAR* fileName)
{//you may also use DCMTK's JPG encoding plug-in
    return CxImage::Save(fileName,CXIMAGE_FORMAT_JPG);
}

bool CxImageDCM::LoadDCM(const TCHAR* filename)
{  
    DcmFileFormat *dfile = new DcmFileFormat();
    OFCondition cond = dfile->loadFile(filename, EXS_Unknown,
        EGL_withoutGL,DCM_MaxReadLength,ERM_autoDetect);
    
    if (cond.bad()) {
        return false;//AfxMessageBox(cond.text());
    }
    
    E_TransferSyntax xfer = dfile->getDataset()->getOriginalXfer();
    DicomImage *di = new DicomImage(dfile, xfer,
        CIF_AcrNemaCompatibility ,
        0, 1);
    
    if (di->getStatus() != EIS_Normal)
        return false;//AfxMessageBox(DicomImage::getString(di->getStatus()));
   
 

    //可改为MemoryStream操作,以替换不安全低效的临时文件
    di->writeBMP("c:\\from_dicom.bmp",24);
    
    return CxImage::Load("c:\\from_dicom.bmp",CXIMAGE_FORMAT_BMP);
    
}

bool CxImageDCM::SaveAsDCM(const TCHAR* filename, const TCHAR* PatientID,
                           const TCHAR* PatientName, const TCHAR* PatientSex,
                           const TCHAR* StudyDate)
{
    CxImageDCM::IncreaseBpp(24);
    char uid[100];
    DcmFileFormat fileformat;
    DcmDataset *dataset = fileformat.getDataset();
    dataset->putAndInsertString(DCM_SOPClassUID,
        UID_SecondaryCaptureImageStorage);
    dataset->putAndInsertString(DCM_SOPInstanceUID,
        dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT));
    dataset->putAndInsertString(DCM_StudyInstanceUID ,
        dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT));
    dataset->putAndInsertString(DCM_SeriesInstanceUID ,
        dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT));
    dataset->putAndInsertString(DCM_Modality,"OT");
    dataset->putAndInsertString(DCM_PatientID, PatientID);
    dataset->putAndInsertString(DCM_PatientsName, PatientName);
    dataset->putAndInsertString(DCM_PatientsSex, PatientSex);
    dataset->putAndInsertString(DCM_StudyDate, StudyDate);
    dataset->putAndInsertString(DCM_WindowCenter, "256");
    dataset->putAndInsertString(DCM_WindowWidth, "128");
        
//    dataset->putAndInsertUint32(DCM_MetaElementGroupLength,128);
    dataset->putAndInsertUint16(DCM_FileMetaInformationVersion,
        0x0001);
    dataset->putAndInsertString(DCM_MediaStorageSOPClassUID,
        UID_MultiframeTrueColorSecondaryCaptureImageStorage);
    dataset->putAndInsertString(DCM_MediaStorageSOPInstanceUID,
        dcmGenerateUniqueIdentifier(uid,SITE_INSTANCE_UID_ROOT));
    dataset->putAndInsertString(DCM_TransferSyntaxUID,
        UID_LittleEndianExplicitTransferSyntax);

    /*added by HGB*/
    //dataset->findAndDeleteElement(DCM_ImplementationClassUID, OFTrue);
    //dataset->findAndDeleteElement(DCM_ImplementationVersionName, OFTrue);
    //end added

    //dataset->putAndInsertString(DCM_ImplementationClassUID,
    //    dcmGenerateUniqueIdentifier(uid,SITE_INSTANCE_UID_ROOT));
    //dataset->putAndInsertString(DCM_ImplementationVersionName,
    //    "SEEKERSOFT1.3.01", OFTrue);

    dataset->putAndInsertString(DCM_UID,
        UID_MultiframeTrueColorSecondaryCaptureImageStorage);
    dataset->putAndInsertUint16(DCM_SamplesPerPixel,3);
    dataset->putAndInsertString(DCM_PhotometricInterpretation,
        "RGB");
    dataset->putAndInsertUint16(DCM_SamplesPerPixel,3);
    dataset->putAndInsertUint16(DCM_BitsAllocated,8);
    dataset->putAndInsertUint16(DCM_BitsStored,8);
    dataset->putAndInsertUint16(DCM_HighBit,7);
    dataset->putAndInsertUint16(DCM_PixelRepresentation,0);
    dataset->putAndInsertUint16(DCM_PlanarConfiguration,0);
    dataset->putAndInsertUint16(DCM_Rows,GetHeight());
    dataset->putAndInsertUint16(DCM_Columns,GetWidth());
    //add more tags here
    /* ... */
    BYTE* pData=new BYTE[GetHeight()*info.dwEffWidth];
    BYTE* pSrc=GetBits(head.biHeight-1);
    BYTE* pDst=pData;
    for(long y=0; y < head.biHeight; y++){
        memcpy(pDst,pSrc,info.dwEffWidth);
        pSrc-=info.dwEffWidth;
        pDst+=info.dwEffWidth;
    }
    dataset->putAndInsertUint8Array(DCM_PixelData,
        pData, GetHeight()*info.dwEffWidth);
    delete[] pData;

    OFCondition status = fileformat.saveFile(filename,
        EXS_LittleEndianImplicit,EET_UndefinedLength,EGL_withoutGL);
    if (status.bad())
        return false;//AfxMessageBox("Error: cannot write DICOM file ");

    return true;     
}