Error while converting Video to DCM

All other questions regarding DCMTK

Moderator: Moderator Team

Message
Author
annapurne.s
Posts: 24
Joined: Wed, 2024-01-31, 10:42

Error while converting Video to DCM

#1 Post by annapurne.s »

OFCondition result = frame->createValueFromTempFile(dcmFileStream.newFactory(), OFstatic_cast(Uint32, length), EBO_LittleEndian);
std::cout << result.text() << std::endl;
I receive the Illegal call, perhaps wrong parameters error some time. Why this happen?. Please help me.

Marco Eichelberg
OFFIS DICOM Team
OFFIS DICOM Team
Posts: 1512
Joined: Tue, 2004-11-02, 17:22
Location: Oldenburg, Germany
Contact:

Re: Error while converting Video to DCM

#2 Post by Marco Eichelberg »

Unfortunately, DCMTK functions often return EC_IllegalCall whenever the developer of the class was too lazy to produce a more meaningful error message. So this could be all kind of things.
The most probable reason is that your temp file has an odd number of bytes (i.e. length & 1 != 0). In DICOM, attributes must always be even length, and this rule is enforced here.

annapurne.s
Posts: 24
Joined: Wed, 2024-01-31, 10:42

Re: Error while converting Video to DCM

#3 Post by annapurne.s »

Hi, yes i checked the length of the video after your reply, if the length is odd i got that error if it is even it will returns normal. Can you please how to convert the odd length video to even byte length, and i have more doubt is this MPEG4 tag supports for HEVC?, because now a days iPhone, iPad has this format also. If DICOM supports HEVC please let me know the tag.

annapurne.s
Posts: 24
Joined: Wed, 2024-01-31, 10:42

Memory not get release after convert img to dcm

#4 Post by annapurne.s »

Hi, i am using this convertion i2d.convertFirstFrame(inputPlug, outPlug, 1, dataset, writeXfer); it takes 10 MB after all work finish and send to PACS memory not get decreased and also i used autoreleasepool for this line. Please help me how to release the memory after send to PACS.

Marco Eichelberg
OFFIS DICOM Team
OFFIS DICOM Team
Posts: 1512
Joined: Tue, 2004-11-02, 17:22
Location: Oldenburg, Germany
Contact:

Re: Error while converting Video to DCM

#5 Post by Marco Eichelberg »

  • I don't know how to pad a bitstream to even size for MPEG data. JPEG uses a marker format where the last two bytes of the bitstream are normally FF D9. However, the marker can also be written as FF FF D9, and this is used to pad a JPEG bitstream to even length.
  • MPEG4 in DICOM is not a tag, but a transfer syntax. Perhaps you should book one of our wonderful DICOM courses to get a better overview of "what is what" in DICOM :)
  • With regard to memory consumption, you probably need to delete the dataset that is passed as fourth parameter to this call in order to release it.

annapurne.s
Posts: 24
Joined: Wed, 2024-01-31, 10:42

C-Store response is too much of delay

#6 Post by annapurne.s »

Hi, i saw the C-Store response came with 1 more min delay why this happen, how to handle in code side. I also try to set the setDIMSEBlockingMode, setConnectionTimeout, setDIMSETimeout, setACSETimeout all to 30 but no response for this also. How to i get rid from these. please post your replay.

Marco Eichelberg
OFFIS DICOM Team
OFFIS DICOM Team
Posts: 1512
Joined: Tue, 2004-11-02, 17:22
Location: Oldenburg, Germany
Contact:

Re: Error while converting Video to DCM

#7 Post by Marco Eichelberg »

Please describe your problem more precisely. Who is sending what where? Furthermore, are you certain that the delay is caused by your application, or could this be a problem on the "other side"?

annapurne.s
Posts: 24
Joined: Wed, 2024-01-31, 10:42

C-Store response is too much of delay

#8 Post by annapurne.s »

1. Created dataset

2. storageSCU.setDIMSEBlockingMode(DIMSE_NONBLOCKING);
storageSCU.setConnectionTimeout(10);
storageSCU.setDIMSETimeout(10);
storageSCU.setACSETimeout(10);

3. storageSCU.setPeerHostName(commandHost);
storageSCU.setPeerPort(portNumberint);
storageSCU.setPeerAETitle(commandAE);
storageSCU.setAETitle(commandlocalAE);
status = storageSCU.addDataset(dataset, writeXfer);

4. PresentationContext
5. initNetwork
6. negotiateAssociation
7. sendECHORequest
8. sendSOPInstances

in this sendSOPInstances request send works fine, but the response taking too long. Why this happening?

Marco Eichelberg
OFFIS DICOM Team
OFFIS DICOM Team
Posts: 1512
Joined: Tue, 2004-11-02, 17:22
Location: Oldenburg, Germany
Contact:

Re: Error while converting Video to DCM

#9 Post by Marco Eichelberg »

I see two possibilities:
  • During association negotiation, the server does not accept a presentation context for the compressed transfer syntax. In this case, the SCU will decompress the object before transmitting it
  • The image is transmitted in compressed form, but the server does some local processing after receipt, and that takes rather long
When you run in debug mode, you should be able to determine whether the first case is happening; otherwise it has to be the second one.

annapurne.s
Posts: 24
Joined: Wed, 2024-01-31, 10:42

Error when try to convert jpeg image to JPEGLSLossless after update DCMTK 3.6.8

#10 Post by annapurne.s »

Hi, before the update of DCMTK 3.6.8 i use DCMTK 3.6.0 it have the method
convert(I2DImgSource *inputPlug,
I2DOutputPlug *outPlug,
DcmDataset*& resultDset,
E_TransferSyntax& proposedTS);

after the update the method not supported now it changed to
convertFirstFrame(
I2DImgSource *inputPlug,
I2DOutputPlug *outPlug,
size_t numberOfFrames,
DcmDataset*& resultDset,
E_TransferSyntax& proposedTS);
Now i try to convert jpeg to dcm works fine but jpeg to JPEGLSLossless not working, it just shows error in
delete m_offsetTable; inside the method insertEncapsulatedPixelDataFirstFrame in i2d file
EXC_BAD_ACCESS not more explanation and also i use register codes also for JPEG-LS. How to find it out. Please give your suggestions.

Marco Eichelberg
OFFIS DICOM Team
OFFIS DICOM Team
Posts: 1512
Joined: Tue, 2004-11-02, 17:22
Location: Oldenburg, Germany
Contact:

Re: Error while converting Video to DCM

#11 Post by Marco Eichelberg »

You cannot directly convert JPEG to JPEG-LS. These are two entirely different file formats (despite the similar name). If you want to generate a JPEG-LS encoded DICOM file from a JPEG file, you must
  • use class Image2Dcm to convert the JPEG file to a DICOM file in JPEG Baseline transfer syntax
  • decompress the resulting DICOM dataset (parameter resultDset)
  • compress the (now uncompressed) dataset with JPEG-LS
  • then save to file

annapurne.s
Posts: 24
Joined: Wed, 2024-01-31, 10:42

Re: Error while converting Video to DCM

#12 Post by annapurne.s »

Thankyou. Now how to convert jpeg to jpeg2000

Marco Eichelberg
OFFIS DICOM Team
OFFIS DICOM Team
Posts: 1512
Joined: Tue, 2004-11-02, 17:22
Location: Oldenburg, Germany
Contact:

Re: Error while converting Video to DCM

#13 Post by Marco Eichelberg »

Same procedure as for JPEG-LS. You need a JPEG 2000 encoder, however, which is not included in DCMTK.
The (commercially available) DCMJP2K module, which is an extension to DCMTK, provides this.

annapurne.s
Posts: 24
Joined: Wed, 2024-01-31, 10:42

Re: Error while converting Video to DCM

#14 Post by annapurne.s »

Hi, can you please give some example for convert JPEG2000 to DICOM file programmatically using DCMTK?


I using openjpeg in swift and decompress the jpeg2000 image like this,
public func getImageDecode(jpeg2000Data data: Data) -> UnsafeMutablePointer<opj_image_t>? {
// Create JP2 decompressor:
let decompressor = opj_create_decompress(OPJ_CODEC_JP2)
if (decompressor == nil) {
fatalError("Failed to create decompressor")
}

// Setup info/warning/error handlers (optional):
opj_set_info_handler(decompressor, infoHandler, nil)
opj_set_warning_handler(decompressor, warningHandler, nil)
opj_set_error_handler(decompressor, errorHandler, nil)

// Set default params:
var params = opj_dparameters_t()
opj_set_default_decoder_parameters(&params)

if (opj_setup_decoder(decompressor, &params) == 0) {
fatalError("Cannot setup decoder")
}

var mutableData = data
var opjImage: UnsafeMutablePointer<opj_image_t>?

mutableData.withUnsafeMutableBytes { unsafeBytes in

let bytes = unsafeBytes.bindMemory(to: UInt8.self).baseAddress!

// cio functions were removed in newer versions of libopenjp2, so need to do this ourselves:
var memoryStream = opj_memory_stream(pData: bytes, dataSize: data.count, offset: 0)
let stream = opj_stream_create_default_memory_stream(&memoryStream, OPJ_TRUE)

opjImage = UnsafeMutablePointer<opj_image_t>.allocate(capacity: 1)

// Must read header first:
if (opj_read_header(stream, decompressor, &opjImage) == 0) {
fatalError("Failed to read header")
}

// Decode image:
if (opj_decode(decompressor, stream, opjImage) == 0) {
fatalError("Failed to decode image")
}
opj_stream_destroy(stream)
}

opj_destroy_codec(decompressor)

return opjImage
}

then i send this image to DCMTK and made the below process,

if (image == nullptr) {
std::cerr << "Invalid image data." << std::endl;
}

// Check the number of components in the image
int numComponents = image->numcomps;

if (numComponents == 3) {
// If the image has 3 components, it could be either RGB or YBR
std::string photometricInterpretation = "Unknown";

// Check if it's likely YBR (YCbCr)
if (image->comps[0].prec == 8 &&
image->comps[1].prec == 8 &&
image->comps[2].prec == 8) {
photometricInterpretation = "YBR"; // Likely YBR
} else {
photometricInterpretation = "RGB"; // Likely RGB
}

std::cout << "Image color space: " << photometricInterpretation << std::endl;
}
else if (numComponents == 4) {
// 4 components, likely YBR with Alpha (RGBA)
std::cout << "Image color space: YBR with Alpha (RGBA)" << std::endl;
}
else if (numComponents == 1) {
// Single component, likely grayscale (Y only in YBR)
std::cout << "Image color space: Grayscale" << std::endl;
} else {
std::cout << "Unexpected number of components: " << numComponents << std::endl;
}

uint32_t width = image->comps[0].w;
uint32_t height = image->comps[0].h;
uint16_t channels = 3; // Only RGB components (ignoring 4th if present)

// Check for 4 components (likely RGB + Alpha or YCbCrA)
if (image->numcomps < 3) {
std::cerr << "Unexpected number of components. Need at least 3." << std::endl;
}

// Create buffer for interleaved RGB pixel data
size_t imageSize = width * height * channels;
uint8_t* interleavedData = new uint8_t[imageSize];

// Interleave only the first 3 components (ignore 4th component)
for (uint32_t i = 0; i < height; ++i) {
for (uint32_t j = 0; j < width; ++j) {
size_t index = (i * width + j) * channels;
interleavedData[index] = static_cast<uint8_t>(image->comps[0].data[i * width + j]); // R or Y
interleavedData[index + 1] = static_cast<uint8_t>(image->comps[1].data[i * width + j]); // G or Cb
interleavedData[index + 2] = static_cast<uint8_t>(image->comps[2].data[i * width + j]); // B or Cr
// Ignore image->comps[3] (alpha or extra channel)
}
}

// Insert pixel data into DICOM dataset
DcmOtherByteOtherWord* pixelData = new DcmOtherByteOtherWord(DCM_PixelData);
dataset->insert(pixelData);
OFCondition cond = pixelData->putUint8Array(interleavedData, imageSize);
if (cond.good()) {
std::cout << "Pixel data added successfully." << std::endl;
} else {
std::cerr << "Failed to add pixel data: " << cond.text() << std::endl;
}

delete[] interleavedData;
dataset->putAndInsertString(DCM_PatientName, [sName UTF8String]);
dataset->putAndInsertString(DCM_PatientID, [sID UTF8String]);
dataset->putAndInsertString(DCM_SpecificCharacterSet, "ISO_IR 192");
dataset->putAndInsertString(DCM_PatientSex, [sGender UTF8String]);
dataset->putAndInsertString(DCM_PatientBirthDate, [sBirthDate UTF8String]);
dataset->putAndInsertString(DCM_StudyDate, [studyDate UTF8String]);
dataset->putAndInsertString(DCM_StudyTime, [studyTime UTF8String]);
dataset->putAndInsertString(DCM_StudyDescription, [studyDes UTF8String]);
dataset->putAndInsertString(DCM_SeriesDescription, [seriesDes UTF8String]);
dataset->putAndInsertString(DCM_StudyID, [studyID UTF8String]);
dataset->putAndInsertString(DCM_InstanceNumber, [instanceNum UTF8String]);
dataset->putAndInsertString(DCM_SeriesNumber, [seriesNum UTF8String]);
dataset->putAndInsertString(DCM_SOPClassUID, UID_SecondaryCaptureImageStorage);
dataset->putAndInsertString(DCM_SOPInstanceUID, generate);
dataset->putAndInsertString(DCM_MediaStorageSOPClassUID, UID_SecondaryCaptureImageStorage);
dataset->putAndInsertString(DCM_MediaStorageSOPInstanceUID, generate);
dataset->putAndInsertString(DCM_PhotometricInterpretation, "YBR_FULL");
dataset->putAndInsertString(DCM_SamplesPerPixel, "3");
dataset->putAndInsertString(DCM_NumberOfFrames, "1");
dataset->putAndInsertString(DCM_Rows, "1600"); // Replace with actual resolution
dataset->putAndInsertString(DCM_Columns, "1200"); // Replace with actual resolution
dataset->putAndInsertString(DCM_BitsAllocated, "8");
dataset->putAndInsertString(DCM_BitsStored, "8");
dataset->putAndInsertString(DCM_HighBit, "7");
dataset->putAndInsertString(DCM_TransferSyntaxUID, UID_JPEG2000TransferSyntax);
dataset->putAndInsertString(DCM_PlanarConfiguration, "0");
dataset->putAndInsertString(DCM_PixelRepresentation, "0");
dataset->putAndInsertString(DCM_TransferSyntaxUID, UID_JPEG2000TransferSyntax);
dataset->putAndInsertString(DCM_SeriesInstanceUID, [sGeneratedSeriesInstanceUid UTF8String]);
dataset->putAndInsertString(DCM_AccessionNumber, [accessionNumber UTF8String]);
dataset->putAndInsertString(DCM_Modality, [dicomImageFormat UTF8String]);
dataset->putAndInsertString(DCM_SeriesDate, [studyDate UTF8String]);
dataset->putAndInsertString(DCM_SeriesTime, [studyTime UTF8String]);
dataset->putAndInsertString(DCM_BurnedInAnnotation, "NO");
DcmFileFormat fileformat(dataset);
resultz = fileformat.saveFile([jpegLosslessPath UTF8String], EXS_JPEG2000);
after open this file pixeldata not set properly. what is the mistake i done in this. Please help me to complete this process.

annapurne.s
Posts: 24
Joined: Wed, 2024-01-31, 10:42

Re: Error while converting Video to DCM

#15 Post by annapurne.s »

Why no reply for DICOM team side?

Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 1 guest