@cosyte/dicom 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -9,7 +9,7 @@ var __export = (target, all) => {
9
9
  };
10
10
 
11
11
  // src/version.ts
12
- var VERSION = "0.1.3";
12
+ var VERSION = "0.1.5";
13
13
 
14
14
  // src/dictionary/index.ts
15
15
  var dictionary_exports = {};
@@ -13221,7 +13221,18 @@ var MULTIBYTE_LABELS = /* @__PURE__ */ new Set([
13221
13221
  ]);
13222
13222
  function parseSpecificCharacterSet(bytes) {
13223
13223
  const raw = bytes.toString("latin1");
13224
- return raw.split("\\").map((t) => t.replace(/[ ]+$/u, "").replace(/^[ ]+/u, "")).map((t) => t === "" || TERM_TO_LABEL.has(t) ? t : WITHHELD);
13224
+ return raw.split("\\").map(trimTermPad).map((t) => t === "" || TERM_TO_LABEL.has(t) ? t : WITHHELD);
13225
+ }
13226
+ function trimTermPad(term) {
13227
+ let end = term.length;
13228
+ while (end > 0) {
13229
+ const code = term.charCodeAt(end - 1);
13230
+ if (code !== 0 && code !== 32) break;
13231
+ end--;
13232
+ }
13233
+ let start = 0;
13234
+ while (start < end && term.charCodeAt(start) === 32) start++;
13235
+ return term.slice(start, end);
13225
13236
  }
13226
13237
  function isKnownCharsetTerm(term) {
13227
13238
  return TERM_TO_LABEL.has(term);
@@ -13788,6 +13799,14 @@ function stripPad(bytes, tag, vr, position, warnings) {
13788
13799
  }
13789
13800
  return bytes.subarray(0, end);
13790
13801
  }
13802
+ function trimSpaces(value) {
13803
+ let start = 0;
13804
+ let end = value.length;
13805
+ while (start < end && value.charCodeAt(start) === SPACE2) start++;
13806
+ while (end > start && value.charCodeAt(end - 1) === SPACE2) end--;
13807
+ return value.slice(start, end);
13808
+ }
13809
+ var DECIMAL_STRING = /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/u;
13791
13810
  function attachWarnings(value, warnings) {
13792
13811
  return warnings.length > 0 ? { ...value, warnings } : value;
13793
13812
  }
@@ -13839,7 +13858,7 @@ function decodeElementValue(element) {
13839
13858
  }
13840
13859
  if (vr === "LO" || vr === "SH" || vr === "UC") {
13841
13860
  const text = decodeCharsetString(trimmed, tag, vr, charset, position, warnings);
13842
- const values = text.split("\\").map((v) => v.replace(/^ +| +$/gu, ""));
13861
+ const values = text.split("\\").map(trimSpaces);
13843
13862
  return attachWarnings({ kind: "strings", values }, warnings);
13844
13863
  }
13845
13864
  if (vr === "LT" || vr === "ST" || vr === "UT") {
@@ -13852,7 +13871,7 @@ function decodeElementValue(element) {
13852
13871
  }
13853
13872
  if (vr === "AE" || vr === "CS" || vr === "AS" || vr === "UI") {
13854
13873
  const text = decodeAsciiString(trimmed, tag, vr, position, warnings);
13855
- const values = text.split("\\").map((v) => v.replace(/^ +| +$/gu, ""));
13874
+ const values = text.split("\\").map(trimSpaces);
13856
13875
  return attachWarnings({ kind: "strings", values }, warnings);
13857
13876
  }
13858
13877
  if (vr === "DS") {
@@ -13860,7 +13879,7 @@ function decodeElementValue(element) {
13860
13879
  const values = text.split("\\").map((v) => {
13861
13880
  const t = v.trim();
13862
13881
  if (t.length === 0) return null;
13863
- if (!/^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/u.test(t)) return null;
13882
+ if (!DECIMAL_STRING.test(t)) return null;
13864
13883
  const n = Number(t);
13865
13884
  return Number.isFinite(n) ? n : null;
13866
13885
  });
@@ -14922,6 +14941,7 @@ function toDate(value, options) {
14922
14941
  return Number.isNaN(instant.getTime()) ? void 0 : instant;
14923
14942
  }
14924
14943
  var UNDEFINED_LENGTH4 = 4294967295;
14944
+ var MAX_SHORT_FORM_LENGTH = 65534;
14925
14945
  var NULL_PAD_VRS = /* @__PURE__ */ new Set(["UI", "OB", "OW", "OF", "OD", "OL", "OV", "UN"]);
14926
14946
  function padValue(value, vr) {
14927
14947
  if (value.length % 2 === 0) return Buffer.from(value);
@@ -14940,6 +14960,19 @@ function uint32(n, littleEndian) {
14940
14960
  else buf.writeUInt32BE(n, 0);
14941
14961
  return buf;
14942
14962
  }
14963
+ function littleEndianValue(value, vr, littleEndian) {
14964
+ const stride = BE_VR_STRIDE[vr];
14965
+ if (littleEndian || stride === 0) return value;
14966
+ const swapped = Buffer.from(value);
14967
+ const whole = swapped.subarray(0, swapped.length - swapped.length % stride);
14968
+ if (stride === 2) whole.swap16();
14969
+ else if (stride === 4) whole.swap32();
14970
+ else whole.swap64();
14971
+ return swapped;
14972
+ }
14973
+ function isPrivateCreator(group, element) {
14974
+ return group % 2 === 1 && element >= 16 && element <= 255;
14975
+ }
14943
14976
  function isFullSpanElement(el, encoding) {
14944
14977
  if (el.length === UNDEFINED_LENGTH4) return true;
14945
14978
  return el.vr === "SQ" && encoding !== "implicit";
@@ -14971,6 +15004,17 @@ function encodeDatasetElement(el, encoding, rawBytes = el.rawBytes) {
14971
15004
  value
14972
15005
  ]);
14973
15006
  }
15007
+ if (value.length > MAX_SHORT_FORM_LENGTH && !isPrivateCreator(group, element)) {
15008
+ return Buffer.concat([
15009
+ uint16(group, littleEndian),
15010
+ uint16(element, littleEndian),
15011
+ Buffer.from("UN", "ascii"),
15012
+ Buffer.from([0, 0]),
15013
+ // reserved (PS3.5 §7.1.2)
15014
+ uint32(value.length, littleEndian),
15015
+ littleEndianValue(value, el.vr, littleEndian)
15016
+ ]);
15017
+ }
14974
15018
  return Buffer.concat([
14975
15019
  uint16(group, littleEndian),
14976
15020
  uint16(element, littleEndian),
@@ -16693,7 +16737,7 @@ function effectiveCode(action, active) {
16693
16737
  return action.basicProfile;
16694
16738
  }
16695
16739
  function resolveAction(code) {
16696
- const first = code.split("/", 1)[0]?.replace("*", "") ?? "K";
16740
+ const first = code.split("/", 1)[0]?.replaceAll("*", "") ?? "K";
16697
16741
  return first;
16698
16742
  }
16699
16743
  var TEXT_DUMMIES = {