CompressedFramesOutput.java incorrect logic

16 views
Skip to first unread message

Phong Trần Đức

unread,
Jun 4, 2025, 10:35:02 PMJun 4
to dcm4che
Hi All,
I skimmed the dcm4chee arc light source code and thought that there is a problematic issue in class CompressedFramesOutput.java . This class is used in WadoRs.java in the following code snippet

    private void writeCompressedFrames(MultipartRelatedOutput output, RetrieveContext ctx, InstanceLocations inst,
                                       int[] frameList, MediaType mediaType, StringBuffer bulkdataURL)
            throws IOException {
        int length = bulkdataURL.length();
        compressedFramesOutput = new CompressedFramesOutput(ctx, inst, frameList, spoolDirectory(frameList));
        for (int frame : frameList) {
            OutputPart outputPart = output.addPart(compressedFramesOutput, mediaType);
            bulkdataURL.setLength(length);
            bulkdataURL.append(frame);
            outputPart.getHeaders().putSingle("Content-Location", bulkdataURL.toString());
        }
    }

CompressedFramesOutput will be working if the frameList is passed as : [4, 2, 5]. 
Let see what happens in the code

    @Override
    public void write(OutputStream out) throws IOException {
        try {
            if (frameListIndex == 0)
                initDicomInputStream();

            if (dis == null) {
                Files.copy(spoolFiles[frameListIndex++], out);
                return;
            }
            int nextFrame =  frameList[frameListIndex++];
            while (frame < nextFrame) {
                skipFrame();
                frame++;
            }
            if (!dis.readItemHeader())
                throw new IOException(
                        "Number of data fragments not sufficient for number of frames in requested object");

            LOG.debug("Start writing compressed frame of {}", inst);
            StreamUtils.copy(dis, out, dis.length());
            LOG.debug("Finished writing compressed frame of {}", inst);
            frame++;
            if (allFramesRead())
                close();
        } catch (IOException e) {
            close();
            throw e;
        }
    }


Let’s simulate the execution:

  • Initial State:
    • frameList = [4, 2, 5], frame = 1, frameListIndex = 0.
    • dis is initialized to read the DICOM file’s pixel data.
  • First Call to write:
    • nextFrame = frameList[0] = 4.
    • frame = 1 < 4, so call skipFrame:
      • frame = 1 doesn’t match any frame in frameList[0..2], so skip.
      • Increment frame = 2.
    • frame = 2 < 4, so call skipFrame:
      • frame = 2 matches frameList[1] = 2, so spool frame 2 to spoolFiles[1].
      • Increment frame = 3.
    • frame = 3 < 4, so call skipFrame:
      • frame = 3 doesn’t match any frame, so skip.
      • Increment frame = 4.
    • frame = 4 == nextFrame, read and write frame 4 to the output stream.
    • Increment frame = 5, frameListIndex = 1.
  • Second Call to write:
    • nextFrame = frameList[1] = 2.
    • frame = 5 > 2, so the logic breaks:
      • The code doesn’t expect nextFrame to be less than the current frame, as it assumes frameList is sorted.
      • It may attempt to skip or read incorrectly, potentially throwing an exception or writing the wrong frame.
  • Spooling Issue:
    • frame 2 was spooled correctly, but when frameListIndex = 1, the code expects to write frame 2 from the spooled file.
    • However, the DICOM stream is already at frame 5, so it can’t go back to process frame 2 without re-reading the file, which the code doesn’t do.
  • Result:
    • The output may include frame 4, then attempt to write frame 2 from the spooled file, but frame 5 may be missed or written out of order.
    • The code may throw an IOException if it tries to read past the available frames or encounters an invalid state.

David Nguyen

unread,
Jun 4, 2025, 10:51:11 PMJun 4
to dcm...@googlegroups.com
What errors or bugs will this issue lead to during use? Can you share if you encounter such a situation, is there a way to fix it?

Vào Th 5, 5 thg 6, 2025 vào lúc 09:35 Phong Trần Đức <phtra...@gmail.com> đã viết:
--
You received this message because you are subscribed to the Google Groups "dcm4che" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dcm4che+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/dcm4che/065f0206-d713-46d9-9474-1b6a1cae8413n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages