dicom icon indicating copy to clipboard operation
dicom copied to clipboard

dicom.NewParser() creation limited by 100 bytes

Open cajund opened this issue 5 months ago • 2 comments

I'm incorporating this library into a new version of the netdicom libraries out there, and during data transfer, it is often necessary to convert byte data to dicom elements. This would normally be performed by the dicom.Parse() function in this library.

However, it is common for the length of bytes that need conversion to be less than the hard coded 100 "peak" bytes in the dicom.NewParser() function:

https://github.com/suyashkumar/dicom/blob/4c45b44e60ab7e6cdbb4788160527799e01613a9/parse.go#L181

In such a case, the Parser is never created.

Have you considered the addition of a NewBytesParser that is similar to NewParser in that it creates the same structure, but is less restrictive. In most cases in the older dicom and netdicom libraries, a NewBytesDecoder() function was present and the transfer syntax was set by the consumer (as it is required). But in many cases, there's usually a transfer syntax that is standard for various elements on the netdicom process (for example, PDU data is always ILE).

I'm going to experiment with lowering this hard coded 100 byte look ahead value, but I would appreciate your thoughts on this. Thanks.

cajund avatar Jul 23 '25 12:07 cajund

This is interesting, and relates to another issue I've been looking into. The next100 is only invoked when the library fails to parse the header and it's attempting to infer a transfer syntax. Could you work around it by including a header for your data?

I'm not 100% sure, but I think you'd just need the 128b preamble + DICM + a transfer syntax.

I wonder if there's more appetite for a parser option that's intended as a single-element parser rather than a full file.

patrickwhite256 avatar Jul 24 '25 20:07 patrickwhite256

This data is coming from the network, and while there is a transfer syntax available from the consumer, I can't create a parser by supplying it.

What I am looking to accomplish is simply to convert the bytes that are coming in from the network into DICOM elements, which the standard uses as well to do its network interaction. The Parser in this library is making the assumption that it's working with an entire file, which is fine for most purposes.

For example, you might create one of these:

https://github.com/grailbio/go-dicom/blob/b0e216a1c5cd39a087b0b20538327cc4ae16abdd/dicomio/buffer.go#L269

And, after setting the transfer syntax:

	d.PushTransferSyntax(binary.LittleEndian, dicomio.ImplicitVR)

use this:

https://github.com/grailbio/go-dicom/blob/b0e216a1c5cd39a087b0b20538327cc4ae16abdd/element.go#L441

(this is all in the original repo, of course)

Re: your comment about a single-element parser, typically it's done in a loop:

	for !d.EOF() {
		elem := dicom.ReadElement(d, dicom.ReadOptions{})
		if d.Error() != nil {
			break
		}
		elems = append(elems, elem)
	}

So it may be a possible solution.

Thanks for the reply.

cajund avatar Jul 24 '25 21:07 cajund