Onega

a lot of VC++ posts, a few C# posts, and some miscellaneous stuff

Wednesday, April 25, 2012

CppUnit command line TestRunner

Two useful posts: CppUnit-runner and Structuring CppUnit Tests.

CToolTipCtrl and CResizableDialog

It seems that tooltip control does not work well with CResizableDialog. I followed a few posts,
http://support.microsoft.com/kb/141758
http://support.microsoft.com/kb/143313
CWindowTip class from www.codeproject.com/dialog/windowtip.asp
CHwmDataTip class from www.codeguru.com/cpp/controls/controls/tooltipcontrols/article.php/c2183/
But all of them do not work well with CResizableDialog, the same code works well with CDialog derived dialogs.

Convert JPG file to DICOM file

There is a utility provided by dcmtk 3.6 to convert image to dicom file, but the source code is a little bit complex (about 400 lines of code in dcmtk-3.6.0\dcmdata\apps\img2dcm.cc). The following code snippet is less than 80 lines of code, and easier to understand.
#include <iostream>
#include "dicomlib/dicomlib.hpp" // http://code.google.com/p/dicomlib/
#include "ximage.h" // http://www.codeproject.com/KB/graphics/cximage.aspx
// This code is created under Windows XP, built by VC++ 2010 (onega)
void test_create_dicom(const std::string filename)
{
CxImage* plain_image;
int nType = CxImage::GetTypeIdFromName("jpg");
plain_image = new CxImage(filename.c_str(), nType);
dicom::DataSet outset;
outset.Put(dicom::TAG_IMAGE_TYPE, std::string("ORIGINAL\\PRIMARY"));
//InstanceCreationDate
//InstanceCreationTime
outset.Put(dicom::TAG_SOP_CLASS_UID, dicom::UID("1.2.840.10008.5.1.4.1.1.1"));
outset.Put(dicom::TAG_SOP_INST_UID, dicom::UID("1.2.392.200036.9125.0.20110320112207"));
outset.Put(dicom::TAG_ACQUISITION_DATE, std::string("2011.03.20"));
outset.Put(dicom::TAG_ACQUISITION_TIME, std::string("19:58:00"));
outset.Put(dicom::TAG_MODALITY, std::string("SC"));
outset.Put(dicom::TAG_MANUFACTOR, std::string("Manufacture name"));
outset.Put(dicom::TAG_INSTITUT_NAME, std::string("hospital name"));
outset.Put(dicom::TAG_INSTITUT_DEPT_NAME, std::string("Department name"));
outset.Put(dicom::TAG_MANFAC_MODEL_NAME, std::string("Manufacture model 2011"));
outset.Put(dicom::TAG_PAT_NAME, std::string("patient name"));
outset.Put(dicom::TAG_BODY_PART_EXAMINED, std::string("head"));
outset.Put(dicom::TAG_STUDY_INST_UID, dicom::UID("1.2.392.200036.9125.0.201103201758.16"));
outset.Put(dicom::TAG_SERIES_INST_UID, dicom::UID("1.2.392.200036.9125.0.201103201758.16"));
outset.Put(dicom::TAG_IMAGE_NO, std::string("1"));
outset.Put(dicom::TAG_SAMPLES_PER_PX, (unsigned short)3); // RGB is 3
outset.Put(dicom::TAG_PHOTOMETRIC, std::string("RGB"));//MONOCHROME1 MONOCHROME2, RGB, and PALETTECOLOR YBR_FULL_422 ARGB, CMYK, YBR Full 422, YBR Full
//0 = The sample values for the first pixel are followed by the sample values for the second pixel, etc.
//For RGB images, this means the order of the pixel values sent shall be R1, G1, B1, R2, G2, B2, ..., etc.
//1 = Each color plane shall be sent contiguously.
//For RGB images, this means the order of the pixel values sent is R1, R2, R3, ..., G1, G2, G3, ..., B1, B2, B3, etc.
//refer to http://www.dabsoft.ch/dicom/3/C.7.6.3/
outset.Put(dicom::Tag(0x00280006), (unsigned short)0);// RGB
outset.Put(dicom::TAG_BITS_STORED, (unsigned short)8);
outset.Put(dicom::TAG_BITS_ALLOC, (unsigned short)8);
outset.Put(dicom::TAG_HIGH_BIT, (unsigned short)7);
outset.Put(dicom::TAG_PX_REPRESENT, (unsigned short)0); //1 signed, 0 unsigned
outset.Put(dicom::TAG_COLUMNS, (unsigned short)plain_image->GetWidth());
outset.Put(dicom::TAG_ROWS, (unsigned short)plain_image->GetHeight());
std::vector PixelData(plain_image->GetWidth()*plain_image->GetHeight()*3);
std::cout << "Image h: " << plain_image->GetHeight() << ", w: " << plain_image->GetWidth()<
int index = 0;
for (int hhh=0; hhhGetHeight(); hhh++)
for(int ww=0; wwGetWidth(); ww++)
{
RGBQUAD color = plain_image->GetPixelColor(ww, hhh, false);
PixelData[index] = color.rgbRed;
PixelData[index+1] = color.rgbGreen;
PixelData[index+2] = color.rgbBlue;
index+= 3;
}
outset.Put(dicom::TAG_PIXEL_DATA, PixelData);
dicom::Write(outset, "test.dcm");
delete plain_image;
}
int main(int argc, char* argv[])
{
try
{
if (argc>1)
return test_create_dicom(argv[1]);
std::cout << "Usage: " << argv[0] << " \n";
}
catch(std::exception& e)
{
std::cout << e.what() << std::endl;
}
return 0;
}
// todo: jpg compressed stream in dicom image file
// todo: padding
// todo: other image file like png, gif, bmp, etc.
// todo: output file path
// todo: error handling

VirtualBox-4.1.12-77245-Win.exe

It can't boot from CentOS-6.2-x86_64-LiveDVD.iso, but it can boot with KNOPPIX_V6.7.1CD-2011-09-14-EN.iso and Fedora-16-i686-Live-Desktop.iso. I can also install CentOS-5.6-i386-bin-DVD.iso.