Skip to content

Commit

Permalink
Refactor with better jsdoc and move function within ValueRepresentati…
Browse files Browse the repository at this point in the history
…on.js class
  • Loading branch information
Craig Berry committed Aug 27, 2024
1 parent 5f7e4a0 commit f760f78
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 19 deletions.
7 changes: 4 additions & 3 deletions src/DicomMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { DicomMetaDictionary } from "./DicomMetaDictionary.js";
import { Tag } from "./Tag.js";
import { log } from "./log.js";
import { deepEqual } from "./utilities/deepEqual";
import { dropPadByte, ValueRepresentation } from "./ValueRepresentation.js";
import { ValueRepresentation } from "./ValueRepresentation.js";

const singleVRs = ["SQ", "OF", "OW", "OB", "UN", "LT"];

Expand Down Expand Up @@ -376,8 +376,9 @@ class DicomMessage {
rawValues = rawValue;
values = value
if (typeof value === "string") {
rawValues = dropPadByte(rawValue.split(String.fromCharCode(VM_DELIMITER)), vr);
values = value.split(String.fromCharCode(VM_DELIMITER));
const delimiterChar = String.fromCharCode(VM_DELIMITER);
rawValues = vr.dropPadByte(rawValue.split(delimiterChar))
values = value.split(delimiterChar);
}
} else if (vr.type == "SQ") {
rawValues = rawValue;
Expand Down
54 changes: 38 additions & 16 deletions src/ValueRepresentation.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,6 @@ function toWindows(inputArray, size) {
);
}

// TODO: Move into value representation?
export function dropPadByte(values, vr) {
if (values.length > 1) {
const last = values[values.length - 1];

// trim padding byte if last element exceeds length by exactly 1
if (last.length === vr.maxLength + 1 && last.charAt(vr.maxLength) === String.fromCharCode(vr.padByte)) {
values[values.length - 1] = last.substring(0, vr.maxLength);
}
}
return values;
}

let DicomMessage, Tag;

var binaryVRs = ["FL", "FD", "SL", "SS", "UL", "US", "AT"],
Expand Down Expand Up @@ -149,6 +136,41 @@ class ValueRepresentation {
return tag;
}

/**
* Removes padding byte, if it exists, from the last value in a multiple-value data element.
*
* This function ensures that data elements with multiple values maintain their integrity for lossless
* read/write operations. In cases where the last value of a multi-valued data element is at the maximum allowed length,
* an odd-length total can result in a padding byte being added. This padding byte, can cause a length violation
* when writing back to the file. To prevent this, we remove the padding byte if it is the only additional character
* in the last element. Otherwise, it leaves the values as-is to minimize changes to the original data.
*
* @param {string[]} values - An array of strings representing the values of a DICOM data element.
* @returns {string[]} The modified array, with the padding byte potentially removed from the last value.
*/
dropPadByte(values) {
if (!Array.isArray(values) || !this.maxLength || !this.padByte) {
return values;
}

// Only consider multiple-value data elements, as max length issues arise from a delimiter
// making the total length odd and necessitating a padding byte.
if (values.length > 1) {
const padChar = String.fromCharCode(this.padByte);
const lastIdx = values.length - 1;
const lastValue = values[lastIdx];

// If the last element exceeds the max length by exactly one character and ends with the padding byte,
// trim the padding byte to avoid a max length violation during write.
if (lastValue.length === this.maxLength + 1 && lastValue.endsWith(padChar)) {
values[lastIdx] = lastValue.substring(0, this.maxLength); // Trim the padding byte
}
}

return values;
}


read(stream, length, syntax, readOptions = { forceStoreRaw: false }) {
if (this.fixed && this.maxLength) {
if (!length) return this.defaultValue;
Expand Down Expand Up @@ -621,7 +643,7 @@ class CodeString extends AsciiStringRepresentation {

readBytes(stream, length) {
const BACKSLASH = String.fromCharCode(VM_DELIMITER);
return dropPadByte(stream.readAsciiString(length).split(BACKSLASH), this);
return this.dropPadByte(stream.readAsciiString(length).split(BACKSLASH));
}

applyFormatting(value) {
Expand Down Expand Up @@ -684,7 +706,7 @@ class NumericStringRepresentation extends AsciiStringRepresentation {
const BACKSLASH = String.fromCharCode(VM_DELIMITER);
const numStr = stream.readAsciiString(length);

return dropPadByte(numStr.split(BACKSLASH), this);
return this.dropPadByte(numStr.split(BACKSLASH));
}
}

Expand Down Expand Up @@ -1305,7 +1327,7 @@ class UniqueIdentifier extends AsciiStringRepresentation {
if (result.indexOf(BACKSLASH) === -1) {
return result
} else {
return dropPadByte(result.split(BACKSLASH), this);
return this.dropPadByte(result.split(BACKSLASH));
}
}

Expand Down

0 comments on commit f760f78

Please sign in to comment.