Skip to content

Commit 890e08a

Browse files
author
Craig Berry
committed
Trim padding byte from numeric strings if they exceed VR max length
1 parent 0621e56 commit 890e08a

File tree

2 files changed

+89
-24
lines changed

2 files changed

+89
-24
lines changed

src/ValueRepresentation.js

+25-24
Original file line numberDiff line numberDiff line change
@@ -661,22 +661,33 @@ class DateValue extends AsciiStringRepresentation {
661661
}
662662
}
663663

664-
class DecimalString extends AsciiStringRepresentation {
665-
constructor() {
666-
super("DS");
667-
this.maxLength = 16;
668-
this.padByte = PADDING_SPACE;
669-
}
664+
class NumericStringRepresentation extends AsciiStringRepresentation {
670665

671666
readBytes(stream, length) {
672667
const BACKSLASH = String.fromCharCode(VM_DELIMITER);
673-
const ds = stream.readAsciiString(length);
674-
if (ds.indexOf(BACKSLASH) !== -1) {
675-
// handle decimal string with multiplicity
676-
return ds.split(BACKSLASH);
668+
const numStr = stream.readAsciiString(length);
669+
const nums = numStr.split(BACKSLASH);
670+
671+
// final element in list may have a padding byte for even length, this should be removed as it is not part of
672+
// the original value and prevents max length issues during write
673+
if (nums.length > 1) {
674+
const last = nums[nums.length - 1];
675+
676+
// trim padding byte if last element exceeds length
677+
if (last.length > this.maxLength) {
678+
nums[nums.length - 1] = last.substring(0, this.maxLength);
679+
}
677680
}
678681

679-
return [ds];
682+
return nums;
683+
}
684+
}
685+
686+
class DecimalString extends NumericStringRepresentation {
687+
constructor() {
688+
super("DS");
689+
this.maxLength = 16;
690+
this.padByte = PADDING_SPACE;
680691
}
681692

682693
applyFormatting(value) {
@@ -694,6 +705,7 @@ class DecimalString extends AsciiStringRepresentation {
694705

695706
convertToString(value) {
696707
if (value === null) return "";
708+
if (typeof value === 'string') return value;
697709

698710
let str = String(value);
699711
if (str.length > this.maxLength) {
@@ -798,25 +810,13 @@ class FloatingPointDouble extends ValueRepresentation {
798810
}
799811
}
800812

801-
class IntegerString extends AsciiStringRepresentation {
813+
class IntegerString extends NumericStringRepresentation {
802814
constructor() {
803815
super("IS");
804816
this.maxLength = 12;
805817
this.padByte = PADDING_SPACE;
806818
}
807819

808-
readBytes(stream, length) {
809-
const BACKSLASH = String.fromCharCode(VM_DELIMITER);
810-
const is = stream.readAsciiString(length);
811-
812-
if (is.indexOf(BACKSLASH) !== -1) {
813-
// handle integer string with multiplicity
814-
return is.split(BACKSLASH);
815-
}
816-
817-
return [is];
818-
}
819-
820820
applyFormatting(value) {
821821
const formatNumber = (numberStr) => {
822822
let returnVal = numberStr.trim().replace(/[^0-9.\\\-+e]/gi, "");
@@ -831,6 +831,7 @@ class IntegerString extends AsciiStringRepresentation {
831831
}
832832

833833
convertToString(value) {
834+
if (typeof value === 'string') return value;
834835
return value === null ? "" : String(value);
835836
}
836837

test/lossless-read-write.test.js

+64
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,70 @@ describe('lossless-read-write', () => {
128128
expect(outputDicomDict.dict['00181041'].Value).toEqual([9007199254740992])
129129
});
130130

131+
test('test DS with multiplicity > 1 and added space for even padding is read and written correctly', () => {
132+
const dataset = {
133+
'00200037': {
134+
vr: 'DS',
135+
Value: [0.99924236548978, -0.0322633220972, -0.0217663285287, 0.02949870928067, 0.99267261121054, -0.1171789789306]
136+
}
137+
};
138+
139+
const dicomDict = new DicomDict({});
140+
dicomDict.dict = dataset;
141+
142+
// write and re-read
143+
const outputDicomDict = DicomMessage.readFile(dicomDict.write());
144+
145+
// ensure _rawValue strings have no added trailing spaces
146+
const expectedDataset = {
147+
'00200037': {
148+
vr: 'DS',
149+
Value: [0.99924236548978, -0.0322633220972, -0.0217663285287, 0.02949870928067, 0.99267261121054, -0.1171789789306],
150+
_rawValue: ["0.99924236548978", "-0.0322633220972", "-0.0217663285287", "0.02949870928067", "0.99267261121054", "-0.1171789789306"]
151+
}
152+
};
153+
154+
expect(deepEqual(expectedDataset, outputDicomDict.dict)).toBeTruthy();
155+
156+
// re-write should succeeed
157+
const outputDicomDictPass2 = DicomMessage.readFile(dicomDict.write());
158+
159+
// dataset should still be equal
160+
expect(deepEqual(expectedDataset, outputDicomDictPass2.dict)).toBeTruthy();
161+
});
162+
163+
test('test IS with multiplicity > 1 and added space for even padding is read and written correctly', () => {
164+
const dataset = {
165+
'00081160': {
166+
vr: 'IS',
167+
Value: [1234, 5678]
168+
}
169+
};
170+
171+
const dicomDict = new DicomDict({});
172+
dicomDict.dict = dataset;
173+
174+
// write and re-read
175+
const outputDicomDict = DicomMessage.readFile(dicomDict.write());
176+
177+
// ensure _rawValue strings have no added trailing spaces
178+
const expectedDataset = {
179+
'00081160': {
180+
vr: 'IS',
181+
Value: [1234, 5678],
182+
_rawValue: ["1234", "5678 "]
183+
}
184+
};
185+
186+
expect(deepEqual(expectedDataset, outputDicomDict.dict)).toBeTruthy();
187+
188+
// re-write should succeeed
189+
const outputDicomDictPass2 = DicomMessage.readFile(dicomDict.write());
190+
191+
// dataset should still be equal
192+
expect(deepEqual(expectedDataset, outputDicomDictPass2.dict)).toBeTruthy();
193+
});
194+
131195
describe('Individual VR comparisons', () => {
132196

133197
const unchangedTestCases = [

0 commit comments

Comments
 (0)