nroduit / weasis-dicom-tools

Basic dicom API
Other
33 stars 33 forks source link

ImageAdapter cannot deal with IncludeBulkData.YES and compressed image data #30

Closed mikhail-timofeev closed 3 days ago

mikhail-timofeev commented 1 month ago

It is my understanding that the flag IncludeBulkData.YES of the dcm4che DicomInputStream results in the image data being stored in the as a Fragments object with each element being a byte array, while weasis-dicom-tools attempts to cast the byte array into BulkData here: https://github.com/nroduit/weasis-dicom-tools/blob/520d96bba041748c3ad50bbf380ea29ba86bc4d6/weasis-dicom-tools/src/main/java/org/dcm4che3/img/stream/ImageAdapter.java#L313 I am getting the exception on the getBytes call: Exception in thread "main" java.lang.ClassCastException: class [B cannot be cast to class org.dcm4che3.data.BulkData ([B is in module java.base of loader 'bootstrap'; org.dcm4che3.data.BulkData is in unnamed module of loader 'app')

    ```
    File src =  new File("input.dcm");
    File dest = new File("output.dcm");

    DicomImageReader reader = new DicomImageReader(new DicomImageReaderSpi());
    try (FileInputStream fis = new FileInputStream( src ); DicomInputStream dicomInputStream = new DicomInputStream( fis ))
    {
        dicomInputStream.setIncludeBulkData( DicomInputStream.IncludeBulkData.YES );
        ImageAdapter.AdaptTransferSyntax syntax = new ImageAdapter.AdaptTransferSyntax( UID.JPEGLossless, UID.ExplicitVRLittleEndian );
        Attributes data = dicomInputStream.readDataset();
        AttributeEditorContext context =
                new AttributeEditorContext(syntax.getOriginal(), null, null);
        BytesWithImageDescriptor bytesWithImageDescriptor = ImageAdapter.imageTranscode( data, syntax, context );
        var bytes = bytesWithImageDescriptor.getBytes( 0 );
nroduit commented 1 month ago

You need to use the APIs described in the readme, which allow you to make more conversions than in dcm4che, and in a simpler way. It is not advisable to manipulate streams.

    Path src = Paths.get("input.dcm");
    Path dest = Paths.get("output.dcm");

    try {
      DicomTranscodeParam params = new DicomTranscodeParam(UID.JPEGLossless);
      Transcoder.dcm2dcm(src, dest, params);
    }
    catch (IOException e) {
      e.printStackTrace();
    }
mikhail-timofeev commented 3 days ago

thank you for the response, however I have to work on the streams as I am working on a network-based tool. I have solved the original problem by wrapping the byte arrays as BulkData objects

nroduit commented 15 hours ago

The library already implements all transcoding situations and smart multiframe management to store in memory only frames in lazy loading mode. That's why it's not advisable to manipulate the bulkdata part directly. There's also the possibility of applying processing to the image using Editable.

This library is used in a DICOM gateway for tag morphing and pixel data transformation by applying masks.

Please specify more precisely which use case cannot be managed