Efferent-Health / fo-dicom.Codecs

Cross-platform Dicom native codecs for fo-dicom
Other
64 stars 22 forks source link

Clone on multiframe image creates invalid Dicom: Encapsulated pixel data fragment is not even length #36

Closed osklu002 closed 1 year ago

osklu002 commented 1 year ago

I am trying to convert a multi-frame image into Jpeg2000 LS. When I run the following code:

public void CreateDicomFile(DicomDataset dicomDataset) 
{
    var inPath = @"C:\temp\multiframe_image.dcm";
    var outPath = @"C:\temp\output.dcm";
    var newDicomFile = DicomFile.Open(inPath);
    var result = newDicomFile.Clone(DicomTransferSyntax.JPEG2000Lossless,
        new FellowOakDicom.Imaging.NativeCodec.DicomJpeg2000Params { UpdatePhotometricInterpretation = false, ProgressionOrder = FellowOakDicom.Imaging.NativeCodec.OPJ_PROG_ORDER.RLCP });
    result.Save(outPath);
}

The Dicom that is produced gets the following issue when I am running DicomVerify (https://dclunie.com/dicom3tools/dciodvfy.html): Warning - Encapsulated pixel data fragment is not even length multiframe_image.zip

cbeltran1306 commented 1 year ago

Hi @osklu002, we have used this code below, it doesn't have any problem with the transcoder to JPEG2000Lossless.

        new DicomSetupBuilder()
                 .RegisterServices(s => s.AddFellowOakDicom().AddTranscoderManager<NativeTranscoderManager>())
                 .SkipValidation()
                  .Build();

        var file = "multiframe.dcm";
        var data = DicomFile.Open(file).Dataset;

        var output = new DicomFile(data).Clone(DicomTransferSyntax.JPEG2000Lossless, new FellowOakDicom.Imaging.NativeCodec.DicomJpeg2000Params{
            UpdatePhotometricInterpretation = false,
            ProgressionOrder = FellowOakDicom.Imaging.NativeCodec.OPJ_PROG_ORDER.RLCP
        });

        output.Save("output.dcm");
jaime-olivares commented 1 year ago

@osklu002 please confirm you are using a code similar to @cbeltran1306 and let us know

osklu002 commented 1 year ago

Hello, I tried your code. I believe the only difference was that you took the Dataset and recreated the Dicomfile? Unfortunately I got the same issue, did you also verify your Dicom after? Like I wrote in the original post I do get a dicomfile out but it does not adhere to the standard.

osklu002 commented 1 year ago

Also note that this depends on the input data. If the data happens to result in a dicomfile with even length pixel data there is no issue. Hence why I included a file that causes the issue.

cbeltran1306 commented 1 year ago

Hi @osklu002, can you share your C# project you have used, please?

osklu002 commented 1 year ago

Hello @cbeltran1306 I am not able to share my entire project since it is for work but the code I provided is enough to cause the issue, or am I missing something?

cbeltran1306 commented 1 year ago

I have used the same code your shared above and dicom file, we did not have any issue. The problem got when it was missing in your code adding the NativeTranscoderManager transcodeManager .

jaime-olivares commented 1 year ago

@osklu002 please try to create another tiny project reproducing the issue.

osklu002 commented 1 year ago

Here is an example project that gets the issue: https://github.com/osklu002/DicomTest

cbeltran1306 commented 1 year ago

Hi @osklu002, this issue is not a bug from ourside, in your code you have to modify the UpdatePhotometricInterpretation value as true from DicomJpeg2000Params or omit it, because it causes the tag PhotometricInterpretation does not update correctly. It should be YBR_RCT not RGB value. Please confirm and let us know.

  new FellowOakDicom.Imaging.NativeCodec.DicomJpeg2000Params { UpdatePhotometricInterpretation = true, ProgressionOrder = 
    FellowOakDicom.Imaging.NativeCodec.OPJ_PROG_ORDER.RLCP });
    result.Save(outPath);
osklu002 commented 1 year ago

Hello again, thank you for looking into this. I think I had a bad example since the issue I am trying to ask about is the "Encapsulated pixel data fragment is not even length" which is not resolved by changing "UpdatePhotometricInterpretation = true", that does however remove the other error in dicomverify.

cbeltran1306 commented 1 year ago

That error you got with multifram_image.dcm dicom file?

osklu002 commented 1 year ago

Yes exactly

On Fri, May 5, 2023, 15:17 Christian Beltrán @.***> wrote:

That error you got with multifram_image.dcm dicom file?

— Reply to this email directly, view it on GitHub https://github.com/Efferent-Health/fo-dicom.Codecs/issues/36#issuecomment-1536250029, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABHGRQHKCMLH5657IBRR4WLXET4XVANCNFSM6AAAAAAVZAARKA . You are receiving this because you were mentioned.Message ID: @.***>

cbeltran1306 commented 1 year ago

When we run your test project, we didn't get any issue, but only if it is missing to set the transcoderManager, as you can see below

new DicomSetupBuilder().RegisterServices(s => 
   s.AddFellowOakDicom().AddTranscoderManager<FellowOakDicom.Imaging.NativeCodec.NativeTranscoderManager> 
   ()).SkipValidation().Build();

will get this error

 Unhandled exception. FellowOakDicom.Imaging.Codec.DicomCodecException: Encoding dataset to transfer syntax JPEG 
2000 Image Compression (Lossless Only) is not supported.
at FellowOakDicom.Imaging.Codec.DicomTranscoder.Encode(DicomDataset oldDataset, DicomTransferSyntax outSyntax, 
IDicomCodec codec, DicomCodecParams parameters)
at FellowOakDicom.Imaging.Codec.DicomTranscoder.Transcode(DicomDataset dataset)
 at FellowOakDicom.Imaging.Codec.DicomTranscoder.Transcode(DicomFile file)
 at FellowOakDicom.Imaging.Codec.DicomCodecExtensions.Clone(DicomFile file, DicomTransferSyntax syntax, 
DicomCodecParams parameters)
osklu002 commented 1 year ago

So, trying to clarify a bit better. The Dicom I get, I am then verifying like this: dicomverify

Are you also running the verify after?

cbeltran1306 commented 1 year ago

Hi @osklu002, we have reproduced it. This is a warning from dciodvfy tool, because the dicom file (Jpeg2000) you got has a first frame size different from the other ones, you can see below, it means the uncompressed (multiframe_image.dcm) dicom file has not the first frame even length. Please check your original dicom file when you created.

image

osklu002 commented 1 year ago

But running dciodvfy on the original dicom does not give any warnings/errors?

pdgmdm commented 1 year ago

Hello I have the same issue when cloning to transfer syntax JPEGProcess14SV1. Using DCMTK dcmdump, I get this output.

W: DcmItem: Length of element (7fe0,0010) is not a multiple of 2 (VR=OW)
W: DcmSequenceOfItems: Length of item in sequence PixelData (7fe0,0010) is odd
W: DcmSequenceOfItems: Length of item in sequence PixelData (7fe0,0010) is odd
...

Note: I am using versions fo-dicom.Codecs 5.10.6 together with fo-dicom 5.1.0 (.NET6 on Windows OS)

Is there any workaround to fix these odd pixel lengths ?

jaime-olivares commented 1 year ago

We will provide a solution within a week from now

cbeltran1306 commented 1 year ago

Hi guys, this bug has been fixed, please you can use new nuget published https://www.nuget.org/packages/fo-dicom.Codecs/5.10.8

pdgmdm commented 12 months ago

Hi @jaime-olivares ,

It seems not completely fixed: now I do not see the odd lengths for the DcmSequenceOfItems, however for the DcmItem it is still present:

W: DcmItem: Length of element (7fe0,0010) is not a multiple of 2 (VR=OW)

cbeltran1306 commented 12 months ago

Hi @pdgmdm, can you send your sample dicom file, please?

pdgmdm commented 12 months ago

Hi @pdgmdm, can you send your sample dicom file, please?

Hello @cbeltran1306 , here you can find the sample docomo file and the source code I used to compress. Note that I used DCMTK's dcmdump and the output starts with W: DcmItem: Length of element (7fe0,0010) is not a multiple of 2 (VR=OW)

DicomCompressionTest.zip

osklu002 commented 12 months ago

I just wanted to let you know that my issue was resolved by the fix! Thanks!