@radicalimaging/static-wado-creator 1.3.0 → 1.5.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.
@@ -1,6 +1,5 @@
1
1
  /* eslint-disable no-param-reassign */
2
2
  const { Tags, readBulkData } = require("@radicalimaging/static-wado-util");
3
- const fs = require("fs");
4
3
  const dcmjs = require("dcmjs");
5
4
 
6
5
  const StaticWado = require("./StaticWado");
@@ -72,7 +72,7 @@ const { mkdicomwebConfig } = ConfigPoint.register({
72
72
  {
73
73
  key: "-t, --content-type <type>",
74
74
  description: 'Destination type to compress to (choices: "jpeg", "jls", "lei", "jls-lossy", "jhc", "jxl" or DICOM Transfer Syntax UID - default: "jls")',
75
- defaultValue: "jhc",
75
+ defaultValue: "jls",
76
76
  customParser: compressionOptionParser,
77
77
  },
78
78
  {
@@ -135,8 +135,8 @@ const { mkdicomwebConfig } = ConfigPoint.register({
135
135
  defaultValue: false,
136
136
  },
137
137
  {
138
- key: "--no-thumb",
139
- description: "Skip thumbnail generation",
138
+ key: "--thumb",
139
+ description: "Generate thumbnails",
140
140
  },
141
141
  {
142
142
  key: "--dcm2jpg",
@@ -110,10 +110,6 @@ class ThumbnailService {
110
110
  async generateThumbnails(itemId, dataSet, metadata, callback, options) {
111
111
  const { imageFrame, id } = this.favoriteThumbnailObj;
112
112
 
113
- if (!options.thumb) {
114
- return null;
115
- }
116
-
117
113
  // There are various reasons no thumbnails might be generated, so just return
118
114
  if (!id) {
119
115
  const pixelData = metadata[Tags.PixelData];
@@ -133,6 +129,11 @@ class ThumbnailService {
133
129
  }
134
130
  return null;
135
131
  }
132
+
133
+ if (!options.thumb) {
134
+ return null;
135
+ }
136
+
136
137
  if (options.dcm2jpg) {
137
138
  return this.dcm2jpg(id.filename, id.imageFrameRootPath.replace(/frames/, "thumbnail"), {});
138
139
  }
@@ -201,14 +201,14 @@ const beforeEncode = (options, encoder) => {
201
201
 
202
202
  function scale(imageFrame, imageInfo) {
203
203
  const { rows, columns, bitsPerPixel, pixelRepresentation, samplesPerPixel } = imageInfo;
204
- let arrayConstructor = Float32Array;
204
+ let ArrayConstructor = Float32Array;
205
205
  if (bitsPerPixel === 8) {
206
- arrayConstructor = pixelRepresentation ? Int8Array : Uint8Array;
206
+ ArrayConstructor = pixelRepresentation ? Int8Array : Uint8Array;
207
207
  } else if (bitsPerPixel > 8 && bitsPerPixel <= 16) {
208
- arrayConstructor = pixelRepresentation ? Int16Array : Uint16Array;
208
+ ArrayConstructor = pixelRepresentation ? Int16Array : Uint16Array;
209
209
  }
210
210
  const src = {
211
- pixelData: new arrayConstructor(imageFrame.buffer),
211
+ pixelData: new ArrayConstructor(imageFrame.buffer),
212
212
  rows,
213
213
  columns,
214
214
  samplesPerPixel,
@@ -218,7 +218,7 @@ function scale(imageFrame, imageInfo) {
218
218
  columns: Math.round(columns / 4),
219
219
  samplesPerPixel,
220
220
  };
221
- dest.pixelData = new arrayConstructor(dest.rows * dest.columns * samplesPerPixel);
221
+ dest.pixelData = new ArrayConstructor(dest.rows * dest.columns * samplesPerPixel);
222
222
  replicate(src, dest);
223
223
 
224
224
  return {
@@ -286,6 +286,10 @@ async function generateLossyImage(id, decoded, options) {
286
286
  }
287
287
  }
288
288
 
289
+ function isPalette(dataSet) {
290
+ return dataSet.string(Tags.RawPhotometricInterpretation) === "PALETTE COLOR";
291
+ }
292
+
289
293
  /**
290
294
  * Transcode imageFrame. It uses transcodeMap to define the target encoding based on source encoding.
291
295
  *
@@ -302,7 +306,7 @@ async function transcodeImageFrame(id, targetIdSrc, imageFrame, dataSet, options
302
306
 
303
307
  const samplesPerPixel = dataSet.uint16(Tags.RawSamplesPerPixel);
304
308
  const planarConfiguration = dataSet.uint16("x00280006");
305
- if (!shouldTranscodeImageFrame(id, options, samplesPerPixel) || planarConfiguration === 1) {
309
+ if (!shouldTranscodeImageFrame(id, options, samplesPerPixel) || planarConfiguration === 1 || isPalette(dataSet)) {
306
310
  console.verbose("Shouldn't transcode");
307
311
  return {
308
312
  id,
@@ -8,7 +8,9 @@ function decodeUtf8(s, options) {
8
8
  }
9
9
 
10
10
  /** Gets a value as a UTF-8 string - todo, make UTF-8 decode optional. */
11
- const getValueInlineString = (dataSet, attr, options) => [decodeUtf8(dataSet.string(attr.tag), options)];
11
+ const getValueInlineString = (dataSet, attr, options) => [
12
+ decodeUtf8(dataSet.string(attr.tag), options),
13
+ ];
12
14
 
13
15
  const getStrings = (dataSet, attr, options) => {
14
16
  const ret = dataSet.string(attr.tag);
@@ -20,21 +22,27 @@ const getStrings = (dataSet, attr, options) => {
20
22
 
21
23
  const getValuePatientName = (dataSet, attr) => {
22
24
  const strings = getStrings(dataSet, attr);
23
- return (strings && strings.map((item) => ({ Alphabetic: item }))) || undefined;
25
+ return (
26
+ (strings && strings.map((item) => ({ Alphabetic: item }))) || undefined
27
+ );
24
28
  };
25
29
 
26
30
  /** Gets either InlineBinary or BulkDataURI, if already defined */
27
31
  const getValueInlineBinary = (dataSet, attr) => {
28
32
  if (attr.BulkDataURI) return { BulkDataURI: attr.BulkDataURI };
29
- const binaryValue = dataSet.byteArray.slice(attr.dataOffset, attr.dataOffset + attr.length);
33
+ const binaryValue = dataSet.byteArray.slice(
34
+ attr.dataOffset,
35
+ attr.dataOffset + attr.length
36
+ );
30
37
  return { InlineBinary: binaryValue.toString("base64") };
31
38
  };
32
39
 
33
40
  const getValueInlineSignedShort = (dataSet, attr) => {
34
- if (attr.length > 2) {
35
- return getValueInlineBinary(dataSet, attr);
41
+ const ret = [];
42
+ for (let i = 0; i < attr.length / 2; i++) {
43
+ ret.push(dataSet.int16(attr.tag, i));
36
44
  }
37
- return [dataSet.int16(attr.tag)];
45
+ return ret;
38
46
  };
39
47
 
40
48
  const getValueInlineUnsignedShort = (dataSet, attr) => {
@@ -70,9 +78,11 @@ const getValueInlineFloat = (dataSet, attr) => {
70
78
  return ret;
71
79
  };
72
80
 
73
- const getValueInlineIntString = (dataSet, attr) => getStrings(dataSet, attr).map((val) => parseInt(val));
81
+ const getValueInlineIntString = (dataSet, attr) =>
82
+ getStrings(dataSet, attr).map((val) => parseInt(val));
74
83
 
75
- const getValueInlineFloatString = (dataSet, attr) => getStrings(dataSet, attr).map((val) => parseFloat(val));
84
+ const getValueInlineFloatString = (dataSet, attr) =>
85
+ getStrings(dataSet, attr).map((val) => parseFloat(val));
76
86
 
77
87
  const getValueInlineFloatDouble = (dataSet, attr) => {
78
88
  if (attr.length > 8) {
@@ -177,15 +187,30 @@ const isValueInline = (attr, options) => {
177
187
  * @param {*} parentAttr attr's parent. If not present means attr is at root level.
178
188
  * @returns
179
189
  */
180
- const getValue = async (dataSet, attr, vr, getDataSet, callback, options, parentAttr) => {
190
+ const getValue = async (
191
+ dataSet,
192
+ attr,
193
+ vr,
194
+ getDataSet,
195
+ callback,
196
+ options,
197
+ parentAttr
198
+ ) => {
181
199
  // It will only process pixelData tag if on metadata root. Otherwise it will be skiped.
182
200
  if (attr.tag === "x7fe00010" && !parentAttr) {
183
- const BulkDataURI = await extractImageFrames(dataSet, attr, vr, callback, options);
201
+ const BulkDataURI = await extractImageFrames(
202
+ dataSet,
203
+ attr,
204
+ vr,
205
+ callback,
206
+ options
207
+ );
184
208
  return { BulkDataURI };
185
209
  }
186
210
  if (attr.tag === "xfffee00d") return undefined;
187
211
  // Group length
188
- if (attr.tag.length == 9 && attr.tag.substring(5, 9) === "0000") return undefined;
212
+ if (attr.tag.length == 9 && attr.tag.substring(5, 9) === "0000")
213
+ return undefined;
189
214
  if (attr.items) {
190
215
  // sequences
191
216
  const result = [];
@@ -202,7 +227,10 @@ const getValue = async (dataSet, attr, vr, getDataSet, callback, options, parent
202
227
  if (isValueInline(attr, options)) {
203
228
  return getValueInline(dataSet, attr, vr, options);
204
229
  }
205
- const binaryValue = dataSet.byteArray.slice(attr.dataOffset, attr.dataOffset + attr.length);
230
+ const binaryValue = dataSet.byteArray.slice(
231
+ attr.dataOffset,
232
+ attr.dataOffset + attr.length
233
+ );
206
234
  const mimeType = attr.tag == "x00420011" && dataSet.string("x00420012");
207
235
 
208
236
  const BulkDataURI = await callback.bulkdata(binaryValue, { mimeType });
@@ -16,7 +16,6 @@ const extensions = {
16
16
  };
17
17
 
18
18
  const baseHasher = hashFactory.hasher();
19
- const MAX_HASH = 1024 * 1024;
20
19
 
21
20
  const hasher = {
22
21
  hash: (v) => {
@@ -19,16 +19,23 @@ const VIDEO_TYPES = {
19
19
  // TODO - add the new multi-segment MPEG2 and H264 variants
20
20
  };
21
21
 
22
- const isVideo = (value) => VIDEO_TYPES[value && value.string ? value.string(Tags.RawTransferSyntaxUID) : value];
22
+ const isVideo = (value) =>
23
+ VIDEO_TYPES[
24
+ value && value.string ? value.string(Tags.RawTransferSyntaxUID) : value
25
+ ];
23
26
 
24
27
  const VideoWriter = () =>
25
28
  async function run(id, dataSet) {
26
29
  console.log(`Writing video ${id.sopInstanceUid}`);
27
30
  const extension = VIDEO_TYPES[dataSet.string(Tags.RawTransferSyntaxUID)];
28
31
  const filename = `index.${extension}`;
29
- const writeStream = WriteStream(`${id.sopInstanceRootPath}/rendered`, filename, {
30
- mkdir: true,
31
- });
32
+ const writeStream = WriteStream(
33
+ `${id.sopInstanceRootPath}/rendered`,
34
+ filename,
35
+ {
36
+ mkdir: true,
37
+ }
38
+ );
32
39
  let length = 0;
33
40
  const { fragments } = dataSet.elements.x7fe00010;
34
41
 
@@ -39,13 +46,18 @@ const VideoWriter = () =>
39
46
  // The zero position fragment isn't available, even though present in the original data
40
47
  for (let i = 0; i < fragments.length; i++) {
41
48
  const fragment = fragments[i];
42
- const blob = dataSet.byteArray.slice(fragment.position, fragment.position + fragment.length);
49
+ const blob = dataSet.byteArray.slice(
50
+ fragment.position,
51
+ fragment.position + fragment.length
52
+ );
43
53
  length += blob.length;
44
54
  await writeStream.write(blob);
45
55
  }
46
56
  await writeStream.close();
47
- console.log(`Done video ${id.sopInstanceRootPath}\\${filename} of length ${length}`);
48
- return `series/${id.seriesInstanceUid}/instances/${id.sopInstanceUid}/pixeldata.${extension}?length=${length}&offset=0`;
57
+ console.log(
58
+ `Done video ${id.sopInstanceRootPath}\\${filename} of length ${length}`
59
+ );
60
+ return `series/${id.seriesInstanceUid}/instances/${id.sopInstanceUid}/rendered?length=${length}&offset=0&accept=video/mp4`;
49
61
  };
50
62
 
51
63
  module.exports = VideoWriter;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@radicalimaging/static-wado-creator",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "description": "Library to convert DICOMP10 to DICOMweb format. Original upstream: https://github.com/chafey/dicomp10-to-dicomweb-js",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -55,15 +55,16 @@
55
55
  "verbose": true
56
56
  },
57
57
  "dependencies": {
58
- "@cornerstonejs/dicom-codec": ">=1.0.2",
59
- "@radicalimaging/static-cs-lite": ">=1.3.0",
60
- "@radicalimaging/static-wado-util": ">=1.3.0",
58
+ "@cornerstonejs/dicom-codec": ">=1.0.5",
59
+ "@radicalimaging/static-cs-lite": "^1.5.0",
60
+ "@radicalimaging/static-wado-util": "^1.5.0",
61
61
  "canvas": "^2.11.1",
62
62
  "config-point": ">=0.5.1",
63
63
  "dcmjs": "^0.29.5",
64
64
  "dicom-parser": "^1.8.13",
65
65
  "glob": "^7.2.0",
66
66
  "node-object-hash": "^3.0.0",
67
+ "npmjs": "npm publish",
67
68
  "uuid": "^8.3.2"
68
69
  },
69
70
  "devDependencies": {
package/CHANGELOG.md DELETED
@@ -1,67 +0,0 @@
1
- # Change Log
2
-
3
- All notable changes to this project will be documented in this file.
4
- See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
-
6
- ## [0.6.4](https://github.com/OHIF/static-wado/compare/@radicalimaging/static-wado-creator@0.6.3...@radicalimaging/static-wado-creator@0.6.4) (2022-04-04)
7
-
8
- **Note:** Version bump only for package @radicalimaging/static-wado-creator
9
-
10
-
11
-
12
-
13
-
14
- ## [0.6.3](https://github.com/OHIF/static-wado/compare/@radicalimaging/static-wado-creator@0.6.2...@radicalimaging/static-wado-creator@0.6.3) (2022-03-14)
15
-
16
- **Note:** Version bump only for package @radicalimaging/static-wado-creator
17
-
18
-
19
-
20
-
21
-
22
- ## [0.6.2](https://github.com/OHIF/static-wado/compare/@radicalimaging/static-wado-creator@0.6.1...@radicalimaging/static-wado-creator@0.6.2) (2022-03-04)
23
-
24
- **Note:** Version bump only for package @radicalimaging/static-wado-creator
25
-
26
-
27
-
28
-
29
-
30
- ## [0.6.1](https://github.com/OHIF/static-wado/compare/@radicalimaging/static-wado-creator@0.6.0...@radicalimaging/static-wado-creator@0.6.1) (2022-03-04)
31
-
32
- **Note:** Version bump only for package @radicalimaging/static-wado-creator
33
-
34
-
35
-
36
-
37
-
38
- # [0.6.0](https://github.com/OHIF/static-wado/compare/@radicalimaging/static-wado-creator@0.5.1...@radicalimaging/static-wado-creator@0.6.0) (2022-03-03)
39
-
40
-
41
- ### Bug Fixes
42
-
43
- * **static-wado:** make the various constructors use a straight configuration without using the program data ([1997d9f](https://github.com/OHIF/static-wado/commit/1997d9f0fe2e0a084d31edeb475494bcec78fd77))
44
-
45
-
46
- ### Features
47
-
48
- * **static-wado:** qido series fallback to retrieve from proxyAe ([#8](https://github.com/OHIF/static-wado/issues/8)) ([47b5550](https://github.com/OHIF/static-wado/commit/47b55503732e25be08b215bdc201593f64de52e6))
49
-
50
-
51
-
52
-
53
-
54
- ## 0.5.1 (2022-02-16)
55
-
56
-
57
- ### Bug Fixes
58
-
59
- * **pencil:** add more files to lint, increase test config and README ([89b667c](https://github.com/OHIF/static-wado/commit/89b667c83d324ab9fa540cda0c037af8fe088f72))
60
- * **pencil:** adding must package and minor test changes ([9194f3f](https://github.com/OHIF/static-wado/commit/9194f3f1bb52da57e20bb8bb9f07262bcebdffbf))
61
- * **pencil:** code review.lint ([fa1a58a](https://github.com/OHIF/static-wado/commit/fa1a58a0c62015503575fbeb172b71810c6833de))
62
- * **pencil:** fix format ([68fbc9b](https://github.com/OHIF/static-wado/commit/68fbc9bf5a3e9bf85e3fbcddfb3e0759e79b769d))
63
- * **pencil:** fix lint and add pre-commit restr ([deec345](https://github.com/OHIF/static-wado/commit/deec34524531d5a8595a775bac414f63f60e9f23))
64
- * **pencil:** lint/prettier ([d6ecbc6](https://github.com/OHIF/static-wado/commit/d6ecbc6b5961e03e8a557f4fcc78af53549132cd))
65
- * **pencil:** moving from wado-js to wado repo ([5916aec](https://github.com/OHIF/static-wado/commit/5916aecd7c77dbc4882681877e2b51210976427f))
66
- * **pencil:** readme link name ([40408ab](https://github.com/OHIF/static-wado/commit/40408ab6b4e97c8656e30b1dd2c30b92440b9f90))
67
- * **pencil:** unit tests migration ([d9d56dd](https://github.com/OHIF/static-wado/commit/d9d56dd619fb1f41ed1d5ad85f7f804e013c6527))