Hi,
I found a bug in DicomDirectoryWriter. I guess it's been around for a while. I think changes made in Feb or March to DicomFile() DicomFile constructors broke it: _metaInfo[DicomTags.TransferSyntaxUid].SetStringValue(TransferSyntax.ExplicitVrLittleEndian.UidString);
This added something to the _metaInfo so this line of code in DicomDirectoryWriter.Save(string) failed:
if (dicomFile.MetaInfo.Count == 0) dicomFile.Load(DicomReadOptions.Default);
So the dicom file was never loaded so dicomFile.DataSet was empty and thus couldn't get patient and study info, etc.
So the above line needs to be changed to:
if (dicomFile.DataSet.Count == 0) dicomFile.Load(DicomReadOptions.Default);
I also found another bug with setting a blank MultiValue string VR (LO) - if the value is empty, then this does not work properly:
dataSet[DicomTags.SeriesDescription].Values = new string[ 0 ];
(something like this gets called in DicomDirectoryWriter.AddSequenceItem() method - dicomSequenceItem[dicomTag].Values = dataSet[dicomTag].Values; )
Thus, a blank SeriesDescription tag was not getting written the Dicom Directory and eFilm Lite would not read the whole DICOMDIR file.
I think the problem is in the DicomAttributeMultiValueText class - Values set property is inconsistent with the SetStringValue() method. In SetStringValue(), when the stringValue to be set is null or empty string, then the Count is set to 1:
if (stringValue == null || stringValue.Length == 0) { Count = 1; StreamLength = 0; _values = new String[0]; return; }
In the Values set property, this happens:
if (value is string[]) { _values = (string[])value; Count =_values.Length; StreamLength = (uint)ToString().Length; }
however when the value is string[0] (which is empty string), then the Count is set to 0, which is different from the SetStringValue(), which it is set to 1. I believe the solution is:
if (value is string[]) { _values = (string[])value; Count = _values.Length == 0 ? 1 : _values.Length; StreamLength = (uint)ToString().Length; }
Also, another bug I found with the SetString() method, to demonstate:
dataSet[DicomTags.SeriesDescription].SetStringValue(""); // the above makes the value string[0] dataSet[DicomTags.SeriesDescription].SetString(0, ""); // this last one calls AppendString() cos IsNull is true, and then at the end of AppendString() it does this:
Count++;
which makes the Count = 2, I think the fix is:
Count = newArray.Length;
Anyway, I guess I could have made a patch but when I started writing this email there was only the first fix but then I found the rest while I was testing the fix! Plus I wasn't sure the exact logic with Count property. Instead of having it a local var, for DicomAttributeMultiValueText class why don't you override and return Values.length? something like:
public override Count { get { if (_values == null) return 0; else if (_values.length == 0) return 1; else return _values.Length; } protected set { throw new InvalidOperationException("cannot set multivalue count property"); } }
Dan
|