@ubercode/dcmtk 0.12.0 → 0.13.0
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/{DicomInstance-CxLKC-oM.d.cts → DicomInstance-BGXtON9T.d.cts} +2 -0
- package/dist/{DicomInstance-BKUiir0G.d.ts → DicomInstance-DGWB2mfD.d.ts} +2 -0
- package/dist/dicom.cjs +30 -16
- package/dist/dicom.cjs.map +1 -1
- package/dist/dicom.d.cts +2 -2
- package/dist/dicom.d.ts +2 -2
- package/dist/dicom.js +30 -16
- package/dist/dicom.js.map +1 -1
- package/dist/{index-DV8HaHEX.d.cts → index-B1eynCVv.d.cts} +4 -1
- package/dist/{index-B5FQoIqM.d.ts → index-DM0yFtPO.d.ts} +4 -1
- package/dist/index.cjs +39 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +39 -17
- package/dist/index.js.map +1 -1
- package/dist/servers.cjs +39 -17
- package/dist/servers.cjs.map +1 -1
- package/dist/servers.d.cts +2 -2
- package/dist/servers.d.ts +2 -2
- package/dist/servers.js +39 -17
- package/dist/servers.js.map +1 -1
- package/dist/tools.cjs +28 -15
- package/dist/tools.cjs.map +1 -1
- package/dist/tools.d.cts +2 -0
- package/dist/tools.d.ts +2 -0
- package/dist/tools.js +28 -15
- package/dist/tools.js.map +1 -1
- package/package.json +1 -1
package/dist/servers.cjs
CHANGED
|
@@ -2246,7 +2246,12 @@ var parser = new fastXmlParser.XMLParser({
|
|
|
2246
2246
|
ignoreAttributes: false,
|
|
2247
2247
|
attributeNamePrefix: "@_",
|
|
2248
2248
|
parseTagValue: false,
|
|
2249
|
-
isArray: (name) => ARRAY_TAG_NAMES.has(name)
|
|
2249
|
+
isArray: (name) => ARRAY_TAG_NAMES.has(name),
|
|
2250
|
+
// DICOM XML does not use XML entities. Disable entity processing to avoid
|
|
2251
|
+
// the default expansion limit (1000) which rejects files with >1000 tags.
|
|
2252
|
+
// Without this, large studies fall through to dcm2json which hangs on
|
|
2253
|
+
// compressed pixel data (DCMTK bug).
|
|
2254
|
+
processEntities: false
|
|
2250
2255
|
});
|
|
2251
2256
|
function xmlToJson(xml) {
|
|
2252
2257
|
try {
|
|
@@ -2307,6 +2312,7 @@ var Dcm2jsonOptionsSchema = zod.z.object({
|
|
|
2307
2312
|
signal: zod.z.instanceof(AbortSignal).optional(),
|
|
2308
2313
|
directOnly: zod.z.boolean().optional(),
|
|
2309
2314
|
charsetAssume: zod.z.string().min(1).optional(),
|
|
2315
|
+
charsetFallback: zod.z.string().min(1).optional(),
|
|
2310
2316
|
verbosity: zod.z.enum(["verbose", "debug"]).optional()
|
|
2311
2317
|
}).strict().optional();
|
|
2312
2318
|
var VERBOSITY_FLAGS = { verbose: "-v", debug: "-d" };
|
|
@@ -2320,27 +2326,34 @@ function buildXmlOpts(options) {
|
|
|
2320
2326
|
const result = {};
|
|
2321
2327
|
if (options?.verbosity !== void 0) result["verbosity"] = options.verbosity;
|
|
2322
2328
|
if (options?.charsetAssume !== void 0) result["charsetAssume"] = options.charsetAssume;
|
|
2329
|
+
if (options?.charsetFallback !== void 0) result["charsetFallback"] = options.charsetFallback;
|
|
2323
2330
|
return result;
|
|
2324
2331
|
}
|
|
2332
|
+
function isCharsetError(stderrOutput) {
|
|
2333
|
+
return stderrOutput.includes("convert character encoding") || stderrOutput.includes("Illegal byte sequence");
|
|
2334
|
+
}
|
|
2335
|
+
async function runXmlAndParse(binary, args, execOpts) {
|
|
2336
|
+
const xmlResult = await execCommand(binary, args, execOpts);
|
|
2337
|
+
if (!xmlResult.ok) return err(xmlResult.error);
|
|
2338
|
+
if (xmlResult.value.exitCode !== 0) {
|
|
2339
|
+
return err(createToolError("dcm2xml", args, xmlResult.value.exitCode, xmlResult.value.stderr));
|
|
2340
|
+
}
|
|
2341
|
+
const jsonResult = xmlToJson(xmlResult.value.stdout);
|
|
2342
|
+
if (!jsonResult.ok) return err(jsonResult.error);
|
|
2343
|
+
return ok({ data: jsonResult.value, source: "xml" });
|
|
2344
|
+
}
|
|
2325
2345
|
async function tryXmlPath(inputPath, timeoutMs, signal, opts) {
|
|
2326
2346
|
const xmlBinary = resolveBinary("dcm2xml");
|
|
2327
|
-
if (!xmlBinary.ok)
|
|
2328
|
-
return err(xmlBinary.error);
|
|
2329
|
-
}
|
|
2347
|
+
if (!xmlBinary.ok) return err(xmlBinary.error);
|
|
2330
2348
|
const charsetArgs = opts?.charsetAssume !== void 0 ? ["+Ca", opts.charsetAssume] : [];
|
|
2331
2349
|
const xmlArgs = [...buildVerbosityArgs(opts?.verbosity), ...charsetArgs, "-nat", inputPath];
|
|
2332
|
-
const
|
|
2333
|
-
|
|
2334
|
-
|
|
2350
|
+
const execOpts = signal !== void 0 ? { timeoutMs, signal } : { timeoutMs };
|
|
2351
|
+
const result = await runXmlAndParse(xmlBinary.value, xmlArgs, execOpts);
|
|
2352
|
+
if (!result.ok && opts?.charsetFallback !== void 0 && isCharsetError(result.error.message)) {
|
|
2353
|
+
const fallbackArgs = [...buildVerbosityArgs(opts.verbosity), "+Ca", opts.charsetFallback, "-nat", inputPath];
|
|
2354
|
+
return runXmlAndParse(xmlBinary.value, fallbackArgs, execOpts);
|
|
2335
2355
|
}
|
|
2336
|
-
|
|
2337
|
-
return err(createToolError("dcm2xml", xmlArgs, xmlResult.value.exitCode, xmlResult.value.stderr));
|
|
2338
|
-
}
|
|
2339
|
-
const jsonResult = xmlToJson(xmlResult.value.stdout);
|
|
2340
|
-
if (!jsonResult.ok) {
|
|
2341
|
-
return err(jsonResult.error);
|
|
2342
|
-
}
|
|
2343
|
-
return ok({ data: jsonResult.value, source: "xml" });
|
|
2356
|
+
return result;
|
|
2344
2357
|
}
|
|
2345
2358
|
async function tryDirectPath(inputPath, timeoutMs, signal, verbosity) {
|
|
2346
2359
|
const jsonBinary = resolveBinary("dcm2json");
|
|
@@ -2525,7 +2538,8 @@ var DicomInstance = class _DicomInstance {
|
|
|
2525
2538
|
const jsonResult = await dcm2json(path2, {
|
|
2526
2539
|
timeoutMs: options?.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
2527
2540
|
signal: options?.signal,
|
|
2528
|
-
charsetAssume: options?.charsetAssume
|
|
2541
|
+
charsetAssume: options?.charsetAssume,
|
|
2542
|
+
charsetFallback: options?.charsetFallback
|
|
2529
2543
|
});
|
|
2530
2544
|
if (!jsonResult.ok) return err(jsonResult.error);
|
|
2531
2545
|
const datasetResult = DicomDataset.fromJson(jsonResult.value.data);
|
|
@@ -2843,6 +2857,12 @@ var DicomReceiverOptionsSchema = zod.z.object({
|
|
|
2843
2857
|
filenameMode: zod.z.enum(["default", "unique", "short-unique", "system-time"]).optional(),
|
|
2844
2858
|
filenameExtension: zod.z.string().min(1).optional(),
|
|
2845
2859
|
storageMode: zod.z.enum(["normal", "bit-preserving", "ignore"]).optional(),
|
|
2860
|
+
instanceOpenOptions: zod.z.object({
|
|
2861
|
+
timeoutMs: zod.z.number().int().positive().optional(),
|
|
2862
|
+
signal: zod.z.instanceof(AbortSignal).optional(),
|
|
2863
|
+
charsetAssume: zod.z.string().min(1).optional(),
|
|
2864
|
+
charsetFallback: zod.z.string().min(1).optional()
|
|
2865
|
+
}).strict().optional(),
|
|
2846
2866
|
signal: zod.z.instanceof(AbortSignal).optional()
|
|
2847
2867
|
}).strict().refine((data) => (data.minPoolSize ?? DEFAULT_MIN_POOL_SIZE) <= (data.maxPoolSize ?? DEFAULT_MAX_POOL_SIZE), {
|
|
2848
2868
|
message: "minPoolSize must be <= maxPoolSize"
|
|
@@ -3012,6 +3032,7 @@ var DicomReceiver = class _DicomReceiver extends events.EventEmitter {
|
|
|
3012
3032
|
__publicField(this, "minPoolSize");
|
|
3013
3033
|
__publicField(this, "maxPoolSize");
|
|
3014
3034
|
__publicField(this, "connectionTimeoutMs");
|
|
3035
|
+
__publicField(this, "resolvedInstanceOpenOptions");
|
|
3015
3036
|
__publicField(this, "workers", /* @__PURE__ */ new Map());
|
|
3016
3037
|
__publicField(this, "tcpServer");
|
|
3017
3038
|
__publicField(this, "associationCounter", 0);
|
|
@@ -3023,6 +3044,7 @@ var DicomReceiver = class _DicomReceiver extends events.EventEmitter {
|
|
|
3023
3044
|
this.minPoolSize = options.minPoolSize ?? DEFAULT_MIN_POOL_SIZE;
|
|
3024
3045
|
this.maxPoolSize = options.maxPoolSize ?? DEFAULT_MAX_POOL_SIZE;
|
|
3025
3046
|
this.connectionTimeoutMs = options.connectionTimeoutMs ?? DEFAULT_CONNECTION_TIMEOUT_MS;
|
|
3047
|
+
this.resolvedInstanceOpenOptions = { charsetFallback: "Latin1", ...options.instanceOpenOptions };
|
|
3026
3048
|
}
|
|
3027
3049
|
// -----------------------------------------------------------------------
|
|
3028
3050
|
// Public API
|
|
@@ -3489,7 +3511,7 @@ var DicomReceiver = class _DicomReceiver extends events.EventEmitter {
|
|
|
3489
3511
|
/** Parses a DICOM file and emits INSTANCE_RECEIVED or INSTANCE_ERROR. */
|
|
3490
3512
|
async parseAndEmitInstance(worker, ctx) {
|
|
3491
3513
|
try {
|
|
3492
|
-
const openResult = await DicomInstance.open(ctx.filePath);
|
|
3514
|
+
const openResult = await DicomInstance.open(ctx.filePath, this.resolvedInstanceOpenOptions);
|
|
3493
3515
|
if (!openResult.ok) {
|
|
3494
3516
|
worker.recordInstanceError();
|
|
3495
3517
|
this.emit("INSTANCE_ERROR", { error: openResult.error, thrown: false, ...ctx });
|