/*[]=========================================================[]*/ /*[] LEADTOOLS DICOM API Change Transfer Syntax Demo []*/ /*[] []*/ /*[] []*/ /*[] Copyright (c) 1991-2003 LEAD Technologies, Inc. []*/ /*[] All Rights Reserved. []*/ /*[]=========================================================[]*/ #include #include #include "resource.h" #include "..\\..\\..\\include\\ltdic.h" /* LEADTOOLS main header file. */ #include "..\\..\\..\\include\\ltlck.h" #include "J2KOpt.h" #define LEAD_IMPLEMENTATION_CLASS_UID "1.2.840.114257.0.1" #define LEAD_IMPLEMENTATION_VERSION_NAME "LEADTOOLS Demo" BOOL CALLBACK MainDlgProc(HWND, UINT, WPARAM, LPARAM); struct { L_CHAR* pszUID; L_CHAR* pszDescription; } TransferSyntaxArray[] = { UID_IMPLICIT_VR_LITTLE_ENDIAN, "Implicit VR Little Endian (1.2.840.10008.1.2)", UID_EXPLICIT_VR_LITTLE_ENDIAN, "Explicit VR Little Endian (1.2.840.10008.1.2.1)", UID_EXPLICIT_VR_BIG_ENDIAN, "Explicit VR Big Endian (1.2.840.10008.1.2.2)", UID_RLE_LOSSLESS, "RLE Lossless (1.2.840.10008.1.2.5)", UID_JPEG_BASELINE_1, "JPEG Baseline (Process 1) (1.2.840.10008.1.2.4.50)", UID_JPEG_EXTENDED_2_4, "JPEG Extended (Process 2 & 4) (1.2.840.10008.1.2.4.51)", UID_JPEG_LOSSLESS_NONHIER_14, "JPEG Lossless, Non-Hierarchical (Process 14) (1.2.840.10008.1.2.4.57)", UID_JPEG_LOSSLESS_NONHIER_14B, "JPEG Lossless, Non-Hierarchical, First-Order Prediction (1.2.840.10008.1.2.4.70)", UID_JPEG2000_LOSSLESS_ONLY ,"JPEG 2000 Lossless Only (1.2.840.10008.1.2.4.90)", UID_JPEG2000 ,"JPEG 2000 (1.2.840.10008.1.2.4.91)" }; FILEJ2KOPTIONS J2KOptions; L_INT32 nTempQFactor; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { UNLOCKSUPPORT(); if (L_IsSupportLocked(L_SUPPORT_MEDICAL)) { MessageBox(GetDesktopWindow(), TEXT("Medical-Express Support must be unlocked for this demo!"), TEXT("Demo"), MB_OK | MB_ICONERROR); return 0; } // Display the main dialog DialogBox(hInstance, TEXT("MainDialog"), GetDesktopWindow(), (DLGPROC) MainDlgProc); return 0; } // Prototypes VOID ChangeTransferSyntax(HWND hMainDlg); VOID ShowFileDialog(HWND hMainDlg, int iButtonID); VOID UpdateQFactorEditBoxState(HWND hMainDlg); VOID UpdateJ2KOptionsBtnState(HWND hMainDlg); VOID CheckFileMetaInfo(HDICOMDS hDataSet); LPTSTR GetEditBoxText(HWND hMainDlg, int iEditID, BOOL bCheck = TRUE); /*------------------------- The Main Dialog Procedure -------------------------*/ BOOL CALLBACK MainDlgProc(HWND hMainDlg, UINT uiMessage, WPARAM wParam, LPARAM lParam) { HWND hWndNewTranSyn, hWndQFactor, hWndJ2KOptionsBtn; HINSTANCE hInstance; int iArraySize, i; switch (uiMessage) { case WM_INITDIALOG: { HDICOMDS hTempDataSet = L_DicomCreateDS(NULL); // Get default J2K Options if(hTempDataSet) { L_DicomGetDefaultJ2KOptions( hTempDataSet,&J2KOptions, sizeof(FILEJ2KOPTIONS)); L_DicomFreeDS(hTempDataSet); } nTempQFactor = 2 ; // Set the icon for the dialog hInstance = (HINSTANCE) GetWindowLong(hMainDlg, GWL_HINSTANCE); SendMessage(hMainDlg, WM_SETICON, ICON_BIG, LPARAM(LoadIcon(hInstance, TEXT("LEADIcon")))); // Initialize the "New Transfer Syntax" combo box hWndNewTranSyn = GetDlgItem(hMainDlg, IDC_COMBO_NEWTRANSFER); iArraySize = sizeof(TransferSyntaxArray) / sizeof(TransferSyntaxArray[0]); for (i = 0; i < iArraySize; i++) { SendMessage(hWndNewTranSyn, CB_INSERTSTRING, (WPARAM) -1, (LPARAM) TransferSyntaxArray[i].pszDescription); } SendMessage(hWndNewTranSyn, CB_SETCURSEL, 0, 0); // Initialize the "Quality factor" edit box hWndQFactor = GetDlgItem(hMainDlg, IDC_EDIT_QFACTOR); SetWindowText(hWndQFactor, TEXT("2")); EnableWindow(hWndQFactor, FALSE); hWndJ2KOptionsBtn = GetDlgItem(hMainDlg, IDC_J2KOPTIONS); if(hWndJ2KOptionsBtn) { EnableWindow(hWndJ2KOptionsBtn, FALSE); } } return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hMainDlg, 0); return TRUE; case IDC_BUTTON_INFILE: case IDC_BUTTON_OUTFILE: ShowFileDialog(hMainDlg, LOWORD(wParam)); break; case IDC_J2KOPTIONS: { HWND hWndQFactor = GetDlgItem(hMainDlg, IDC_EDIT_QFACTOR); if (IsWindowEnabled(hWndQFactor)) { if (SendMessage(hWndQFactor, EM_LINELENGTH, 0, 0)) { LPTSTR pszQFactor = GetEditBoxText(hMainDlg, IDC_EDIT_QFACTOR, FALSE); nTempQFactor = atoi(pszQFactor); delete [] pszQFactor; if (nTempQFactor < 2 || nTempQFactor > 255) { nTempQFactor = 2; } } } OnJ2KOptions(hMainDlg); } break; case IDC_BUTTON_CHANGE: ChangeTransferSyntax(hMainDlg); break; case IDC_COMBO_NEWTRANSFER: if (HIWORD(wParam) == CBN_SELCHANGE) { UpdateQFactorEditBoxState(hMainDlg); UpdateJ2KOptionsBtnState(hMainDlg); } break; } break; } return FALSE; } VOID ChangeTransferSyntax(HWND hMainDlg) { // The input filename LPTSTR pszInFilename = GetEditBoxText(hMainDlg, IDC_EDIT_INFILE); if (!pszInFilename) return; // The output filename LPTSTR pszOutFilename = GetEditBoxText(hMainDlg, IDC_EDIT_OUTFILE); if (!pszOutFilename) { delete [] pszInFilename; return; } // The quality factor L_INT32 nQFactor = 2; HWND hWndQFactor = GetDlgItem(hMainDlg, IDC_EDIT_QFACTOR); if (IsWindowEnabled(hWndQFactor)) { if (SendMessage(hWndQFactor, EM_LINELENGTH, 0, 0)) { LPTSTR pszQFactor = GetEditBoxText(hMainDlg, IDC_EDIT_QFACTOR, FALSE); nQFactor = atoi(pszQFactor); delete [] pszQFactor; if (nQFactor < 2 || nQFactor > 255) { MessageBox(hMainDlg, TEXT("The quality factor should range from 2 to 255."), TEXT("Demo"), MB_OK); SetFocus(hWndQFactor); SendMessage(hWndQFactor, EM_SETSEL, 0, -1); delete [] pszInFilename; delete [] pszOutFilename; return; } } else { SetWindowText(hWndQFactor, TEXT("2")); } } // The new Transfer Syntax int iIndex = SendMessage(GetDlgItem(hMainDlg, IDC_COMBO_NEWTRANSFER), CB_GETCURSEL, 0, 0); iIndex = (iIndex == CB_ERR) ? 0 : iIndex; L_CHAR* pszNewTranSynUID = TransferSyntaxArray[iIndex].pszUID; HDICOMDS hDataSet = L_DicomCreateDS(NULL); L_UINT16 uRet; // Load the input Data Set uRet = L_DicomLoadDS(hDataSet, pszInFilename, DS_LOAD_CLOSE); if (uRet != DICOM_SUCCESS) { MessageBox(hMainDlg, TEXT("Failed to load the Data Set."), TEXT("Demo"), MB_OK); delete [] pszInFilename; delete [] pszOutFilename; L_DicomFreeDS(hDataSet); return; } L_DicomSetJ2KOptions( hDataSet,&J2KOptions); delete [] pszInFilename; // Change to the desired Transfer Syntax uRet = L_DicomChangeTransferSyntax(hDataSet, pszNewTranSynUID, nQFactor, 0); if (uRet != DICOM_SUCCESS) { TCHAR szMessage[256]; lstrcpy(szMessage, TEXT("Failed to change the Transfer Syntax.")); if (uRet == DICOM_ERROR_PARAMETER) { lstrcat(szMessage, TEXT("\n\nPossible cause: \"Bits Allocated\" for the source ") \ TEXT("Data Set doesn't match the desired Transfer Syntax.")); } MessageBox(hMainDlg, szMessage, TEXT("Demo"), MB_OK); delete [] pszOutFilename; L_DicomFreeDS(hDataSet); return; } // Ensure that the DICOM File Meta Information is added CheckFileMetaInfo(hDataSet); // Save the Data Set uRet = L_DicomSaveDS(hDataSet, pszOutFilename, DS_METAHEADER_PRESENT | DS_GROUP_LENGTHS); delete [] pszOutFilename; L_DicomFreeDS(hDataSet); if (uRet != DICOM_SUCCESS) { MessageBox(hMainDlg, TEXT("Failed to save the Data Set."), TEXT("Demo"), MB_OK); } else { MessageBox(hMainDlg, TEXT("Conversion succeeded."), TEXT("Demo"), MB_OK); } } VOID ShowFileDialog(HWND hMainDlg, int iButtonID) { HWND hWndFilename; OPENFILENAME ofn; TCHAR szFile[MAX_PATH]; hWndFilename = GetDlgItem(hMainDlg, (iButtonID == IDC_BUTTON_INFILE) ? IDC_EDIT_INFILE : IDC_EDIT_OUTFILE); szFile[0] = '\0'; if (SendMessage(hWndFilename, EM_LINELENGTH, 0, 0)) { GetWindowText(hWndFilename, szFile, sizeof(szFile) / sizeof(TCHAR)); } // Initialize the OPENFILENAME structure ZeroMemory(&ofn, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hMainDlg; ofn.lpstrFilter = TEXT("DICOM Files (*.dic;*.dcm)\0*.dic;*.dcm\0All files (*.*)\0*.*\0"); ofn.nFilterIndex = 1; ofn.lpstrFile = szFile; ofn.nMaxFile = sizeof(szFile) / sizeof(TCHAR); ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | ((iButtonID == IDC_BUTTON_INFILE) ? OFN_FILEMUSTEXIST : OFN_OVERWRITEPROMPT); if ((iButtonID == IDC_BUTTON_INFILE) ? GetOpenFileName(&ofn) : GetSaveFileName(&ofn)) { SetWindowText(hWndFilename, szFile); } } VOID UpdateQFactorEditBoxState(HWND hMainDlg) { int iIndex = SendMessage(GetDlgItem(hMainDlg, IDC_COMBO_NEWTRANSFER), CB_GETCURSEL, 0, 0); if (iIndex == CB_ERR) return; HWND hWndQFactor = GetDlgItem(hMainDlg, IDC_EDIT_QFACTOR); // Enable the "Quality factor" edit box if the selected Transfer Syntax involves // compressing the pixel data using a lossy compression. Otherwise, disable it. L_CHAR* pszTranSynUID = TransferSyntaxArray[iIndex].pszUID; if ( (lstrcmp(UID_JPEG_BASELINE_1, pszTranSynUID) == 0) || (lstrcmp(UID_JPEG_EXTENDED_2_4, pszTranSynUID) == 0) || (lstrcmp(UID_JPEG2000, pszTranSynUID) == 0)) { EnableWindow(hWndQFactor, TRUE); } else { EnableWindow(hWndQFactor, FALSE); } } VOID UpdateJ2KOptionsBtnState(HWND hMainDlg) { int iIndex = SendMessage(GetDlgItem(hMainDlg, IDC_COMBO_NEWTRANSFER), CB_GETCURSEL, 0, 0); if (iIndex == CB_ERR) return; HWND hWndJ2KOptionsBtn = GetDlgItem(hMainDlg, IDC_J2KOPTIONS); if(hWndJ2KOptionsBtn == NULL) return; // Enable the "Quality factor" edit box if the selected Transfer Syntax involves // compressing the pixel data using a lossy compression. Otherwise, disable it. L_CHAR* pszTranSynUID = TransferSyntaxArray[iIndex].pszUID; if (lstrcmp(UID_JPEG2000_LOSSLESS_ONLY, pszTranSynUID) == 0 || lstrcmp(UID_JPEG2000, pszTranSynUID) == 0) { EnableWindow(hWndJ2KOptionsBtn, TRUE); } else { EnableWindow(hWndJ2KOptionsBtn, FALSE); } } VOID CheckFileMetaInfo(HDICOMDS hDataSet) { pDICOMELEMENT pElement, pTemp; L_CHAR* pszValue; if (!hDataSet) return; // File Meta Information Version pElement = L_DicomFindFirstElement(hDataSet, NULL, TAG_FILE_META_INFORMATION_VERSION, FALSE); if (pElement == NULL) { pElement = L_DicomInsertElement(hDataSet, NULL, FALSE, TAG_FILE_META_INFORMATION_VERSION, VR_OB, FALSE, 0); } if (pElement) { L_CHAR Values[] = { 0x00, 0x01 }; L_DicomSetCharValue(hDataSet, pElement, Values, 2); } // Media Storage SOP Class UID pElement = L_DicomFindFirstElement(hDataSet, NULL, TAG_MEDIA_STORAGE_SOP_CLASS_UID, FALSE); if (pElement == NULL) { pElement = L_DicomInsertElement(hDataSet, NULL, FALSE, TAG_MEDIA_STORAGE_SOP_CLASS_UID, VR_UI, FALSE, 0); } if (pElement) { pTemp = L_DicomFindFirstElement(hDataSet, NULL, TAG_SOP_CLASS_UID, FALSE); if (pTemp) { pszValue = L_DicomGetStringValue(hDataSet, pTemp, 0, 1); if (pszValue) { L_DicomSetStringValue(hDataSet, pElement, pszValue, 1); } } } // Media Storage SOP Instance UID pElement = L_DicomFindFirstElement(hDataSet, NULL, TAG_MEDIA_STORAGE_SOP_INSTANCE_UID, FALSE); if (pElement == NULL) { pElement = L_DicomInsertElement(hDataSet, NULL, FALSE, TAG_MEDIA_STORAGE_SOP_INSTANCE_UID, VR_UI, FALSE, 0); } if (pElement) { pTemp = L_DicomFindFirstElement(hDataSet, NULL, TAG_SOP_INSTANCE_UID, FALSE); if (pTemp) { pszValue = L_DicomGetStringValue(hDataSet, pTemp, 0, 1); if (pszValue) { L_DicomSetStringValue(hDataSet, pElement, pszValue, 1); } } } // Implementation Class UID pElement = L_DicomFindFirstElement(hDataSet, NULL, TAG_IMPLEMENTATION_CLASS_UID, FALSE); if (pElement == NULL) { pElement = L_DicomInsertElement(hDataSet, NULL, FALSE, TAG_IMPLEMENTATION_CLASS_UID, VR_UI, FALSE, 0); } if (pElement) { L_DicomSetStringValue(hDataSet, pElement, LEAD_IMPLEMENTATION_CLASS_UID, 1); } // Implementation Version Name pElement = L_DicomFindFirstElement(hDataSet, NULL, TAG_IMPLEMENTATION_VERSION_NAME, FALSE); if (pElement == NULL) { pElement = L_DicomInsertElement(hDataSet, NULL, FALSE, TAG_IMPLEMENTATION_VERSION_NAME, VR_SH, FALSE, 0); } if (pElement) { L_DicomSetStringValue(hDataSet, pElement, LEAD_IMPLEMENTATION_VERSION_NAME, 1); } } LPTSTR GetEditBoxText(HWND hMainDlg, int iEditID, BOOL bCheck) { HWND hWndFilename = GetDlgItem(hMainDlg, iEditID); if (SendMessage(hWndFilename, EM_LINELENGTH, 0, 0)) { int iLength = GetWindowTextLength(hWndFilename) + 1; LPTSTR pszFilename = new TCHAR[iLength]; if (!pszFilename) { MessageBox(hMainDlg, TEXT("Failed to allocate memory."), TEXT("Demo"), MB_OK); return NULL; } GetWindowText(hWndFilename, pszFilename, iLength); if (iEditID == IDC_EDIT_INFILE) { // Does the file exist? WIN32_FIND_DATA FindFileData; HANDLE hFind = FindFirstFile(pszFilename, &FindFileData); if (hFind != INVALID_HANDLE_VALUE) { FindClose(hFind); return pszFilename; } } else { return pszFilename; } delete [] pszFilename; } if (bCheck) { LPTSTR pszMessage; pszMessage = (iEditID == IDC_EDIT_INFILE) ? TEXT("Please enter a valid input filename.") : TEXT("Please enter a valid output filename."); MessageBox(hMainDlg, pszMessage, TEXT("Demo"), MB_OK); SetFocus(hWndFilename); SendMessage(hWndFilename, EM_SETSEL, 0, -1); } return NULL; }