{"id":13654503,"url":"https://github.com/cornerstonejs/dicomParser","last_synced_at":"2025-04-23T09:33:32.311Z","repository":{"id":15508163,"uuid":"18242315","full_name":"cornerstonejs/dicomParser","owner":"cornerstonejs","description":"JavaScript parser for DICOM Part 10 data","archived":false,"fork":false,"pushed_at":"2024-05-16T16:12:52.000Z","size":6031,"stargazers_count":730,"open_issues_count":42,"forks_count":230,"subscribers_count":69,"default_branch":"master","last_synced_at":"2025-04-16T01:08:55.494Z","etag":null,"topics":["dicom","javascript","nci-itcr"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cornerstonejs.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-03-29T13:57:18.000Z","updated_at":"2025-04-12T22:05:09.000Z","dependencies_parsed_at":"2024-01-14T16:10:34.778Z","dependency_job_id":"8e162edb-68b4-4745-9a83-b4c447573240","html_url":"https://github.com/cornerstonejs/dicomParser","commit_stats":{"total_commits":291,"total_committers":33,"mean_commits":8.818181818181818,"dds":"0.45704467353951894","last_synced_commit":"7d2084349bf2bdaffe74021e27b286a6c295ca66"},"previous_names":["chafey/dicomparser"],"tags_count":74,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cornerstonejs%2FdicomParser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cornerstonejs%2FdicomParser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cornerstonejs%2FdicomParser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cornerstonejs%2FdicomParser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cornerstonejs","download_url":"https://codeload.github.com/cornerstonejs/dicomParser/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250407712,"owners_count":21425549,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dicom","javascript","nci-itcr"],"created_at":"2024-08-02T03:00:36.180Z","updated_at":"2025-04-23T09:33:30.531Z","avatar_url":"https://github.com/cornerstonejs.png","language":"JavaScript","readme":"[![NPM version][npm-version-image]][npm-url] [![NPM downloads][npm-downloads-image]][npm-url] [![MIT License][license-image]][license-url] [![Build Status][travis-image]][travis-url]\n[![Coverage Status][coverage-image]][coverage-url]\n\ndicomParser\n===========\n\ndicomParser is a lightweight library for parsing DICOM P10 byte streams, as well as raw (not encapsulated in part 10) byte streams, in modern HTML5 based web browsers (IE10+),\nNode.js and Meteor.  dicomParser is fast, easy to use and has no required external dependencies.\n\nLive Examples\n---------------\n\nThe best way to see the power of this library is to actually see it in use.  A number of live examples are\nincluded that are not only useful but also show how to use dicomParser.\n[Click here for a list of all live examples](https://cornerstonejs.github.io/dicomParser/examples/index.html)\nMake sure you try out the [DICOM Dump with Data Dictionary](https://cornerstonejs.github.io/dicomParser/examples/dumpWithDataDictionary/index.html)\nwhich is a very useful tool and excellent example of most features.\n\nCommunity\n---------\n\nHave questions?  Try posting on our [google groups forum](https://groups.google.com/forum/#!forum/cornerstone-platform).\n\n\nInstall\n-------\n\nGet a packaged source file:\n\n* [dicomParser.js](https://unpkg.com/dicom-parser@latest/dist/dicomParser.js)\n* [dicomParser.min.js](https://unpkg.com/dicom-parser@latest/dist/dicomParser.min.js)\n\nOr install via [NPM](https://www.npmjs.com/):\n\n\u003e npm install dicom-parser\n\nOr install via atmosphere for [Meteor](https://www.meteor.com/) applications\n\n\u003e meteor add chafey:dicom-parser\n\n* Note - make sure you install [pako](https://github.com/nodeca/pako) if you need to support\nthe Deflated Explicit VR Little Endian transfer syntax\n\nUsage\n-----\n\n```javascript\n// create a Uint8Array or node.js Buffer with the contents of the DICOM P10 byte stream\n// you want to parse (e.g. XMLHttpRequest to a WADO server)\nvar arrayBuffer = new ArrayBuffer(bufferSize);\nvar byteArray = new Uint8Array(arrayBuffer);\n\ntry\n{\n    // Allow raw files\n    const options = { TransferSyntaxUID: '1.2.840.10008.1.2' };\n    // Parse the byte array to get a DataSet object that has the parsed contents\n    var dataSet = dicomParser.parseDicom(byteArray, options);\n\n    // access a string element\n    var studyInstanceUid = dataSet.string('x0020000d');\n\n    // get the pixel data element (contains the offset and length of the data)\n    var pixelDataElement = dataSet.elements.x7fe00010;\n\n    // create a typed array on the pixel data (this example assumes 16 bit unsigned data)\n    var pixelData = new Uint16Array(dataSet.byteArray.buffer, pixelDataElement.dataOffset, pixelDataElement.length / 2);\n}\ncatch(ex)\n{\n   console.log('Error parsing byte stream', ex);\n}\n```\n\n[See the live examples for more in depth usage of the library](https://cornerstonejs.github.io/dicomParser/examples/index.html)\n\nNote that actually displaying DICOM images is quite complex due to the variety of pixel formats and compression\nalgorithms that DICOM supports.  If you are interested in displaying images, please take a look at the\n[cornerstone library](https://github.com/cornerstonejs/cornerstone) and the\n[cornerstoneWADOImageLoader](https://github.com/cornerstonejs/cornerstoneWADOImageLoader) which uses this\nlibrary to extract the pixel data from DICOM files and display the images with\n[cornerstone library](https://github.com/cornerstonejs/cornerstone).\nYou can find the actual code that extracts pixel data using this library\n[here](https://github.com/cornerstonejs/cornerstoneWADOImageLoader/blob/master/src/imageLoader/createImage.js).\n\nOptions\n-------\n\n```dicomParser.parseDicom``` accepts an optional second argument that is an options object. The accepted properties are:\n\n#### TransferSyntaxUID\nA string value used as the default transfer syntax uid for parsing raw DICOM (not encapsualted in Part 10).\nFor raw DICOM files, this value should be the LEI UID value.\n\n#### untilTag\n\nA tag in the form xggggeeee (where gggg is the hexadecimal group number and eeee is the hexadecimal element number,\ne.g. 'x7fe00010') that specifies the final tag to parse. Any tags occurring after this in the file will be ignored.\nUseful for partial reading of byte streams.\n\n#### vrCallback\n\nA callback that, given a tag, will return the two-character Value Representation associated with that tag (see PS 3.5\nof the DICOM standard for more information). It may return undefined to indicate that the VR was not provided.\n\n#### inflater\n\nA callback that given the underlying byteArray and position of the deflated buffer returns a byteArray containing the\nDICOM P10 header and inflated data set concatenated together.\n\nKey Features\n------------\n\n* Parses all known valid DICOM Part 10 byte arrays\n  * Explicit and implicit\n  * Little endian and big endian\n  * Deflated Explicit VR Little Endian transfer syntax\n    * Uses zlib when running node.js\n    * requires [pako](https://github.com/nodeca/pako) in web browsers\n    * has callback to support use of other inflate libraries\n* Supports all VR's including sequences\n* Supports elements with undefined length\n* Supports sequence items with undefined length\n* Provides functions to convert from all VR types to native Javascript types\n* Does not require a data dictionary\n* Designed for use in the browser\n* Each element exposes the offset and length of its data in the underlying byte stream\n* Packaged using the module pattern, as an AMD module and as a CommonJS module for Node.js\n* No external dependencies\n* Supports extraction of encapsulated pixel data frames\n  * Basic Offset Table decoded\n  * Fragments decoded\n  * Function to extract image frame when basic offset table is present\n  * Function to extract image frame from fragments when no basic offset table is present\n* Convenient utility functions to parse strings formatted in DA, TM and PN VRs and return JavaScript objects\n* Convenient utility function to create a string version of an explicit element\n* Convenient utility function to convert a parsed explicit dataSet into a javascript object\n* Convenient utility function to generate a basic offset table for JPEG images\n* Supports reading incomplete/partial byte streams\n  * By specifying a tag to stop reading at (e.g. parseDicom(byteArray, {untilTag: \"x7fe00010\"}); )\n  * By returning the elements parsed so far in the exception thrown during a parse error (the elements parsed will be\n    in the dataSet property of the exception)\n* Supports reading from Uint8Arrays and Node.js Buffers\n\nBuild System\n============\n\nThis project uses Webpack to build the software.\n\nPre-requisites:\n---------------\n\nNodeJs - [click to visit web site for installation instructions](http://nodejs.org).\n\nCommon Tasks\n------------\n\nUpdate dependencies (after each pull):\n\u003e npm install\n\nRunning the build:\n\u003e npm run build\n\nAutomatically running the build and unit tests after each source change:\n\u003e npm run watch\n\n## Publish\n\nThis library uses `semantic-release` to publish packages. The syntax of commits against the `master` branch\ndetermine how the new version calculated.\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eExample Commit\u003c/th\u003e\n    \u003cth\u003eRelease Type\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003efix(pencil): stop graphite breaking when too much pressure applied\u003c/td\u003e\n    \u003ctd\u003ePatch Release\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003efeat(pencil): add 'graphiteWidth' option\u003c/td\u003e\n    \u003ctd\u003eFeature Release\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\n      perf(pencil): remove graphiteWidth option\u003cbr /\u003e\n      \u003cbr /\u003e\n      BREAKING CHANGE: The graphiteWidth option has been removed. \n      The default graphite width of 10mm is always used for performance reasons.\n    \u003c/td\u003e\n    \u003ctd\u003e\n      Major Breaking Release\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\nBacklog\n------------\n\nFuture:\n\n* Add unit tests for sequence parsing functionality and encapsulated pixel frames\n* Figure out how to automatically generate documentation from the source (jsdoc)\n* Optimize findItemDelimitationItemAndSetElementLength() for speed\n* Optimize functions in byteArrayParser.js for speed\n* Add example that allows you to compare two sop instances against each other\n* Figure out how to not have a global dicomParser object when used with an AMD loader\n* See what needs to be done to support different character sets (assumes ASCII currently)\n* Support for parsing from streams on Node.js and Meteor\n* Switch to JavaScript ES6\n* Separate the parsing logic from the dataSet creation logic (e.g. parsing generates events\n  which dataSet creation logic creates the dataSet from).  Similar concept to SAX parsers.\n  * dataSet creation logic could filter out unwanted tags to improve performance of parse\n  * dataSet creation logic could defer creation of sequence dataSets to improve performance of parse\n* Function to parse non P10 byte streams given the byte stream and the transfer syntax\n* Support for encrypted dicom\n\nContributors\n============================================\n\n* @neandrake for help with getting Node.js support\n* @ggerade for implementing support for floats/doubles with VM \u003e 1\n* @yagni for bug fix related to parsing implicit little endian files and big endian support\n* @snagytx, @doncharkowsky - for bug fix related to reading encapsulated frames\n* @bbunderson, @jpambrun - bug fix for reading encapsulated frames\n* @henryqdineen, adil.tiadi@gmail.com - bug report for sequences with undefined lengths and zero items\n* @swederik - bug fixes on sequences with undefined lengths and zero items\n* @jkrot - performance enhancement in byteArrayParser\n* @cancan101 - issue related to multi-frame with multiple fragments and no basic offset table\n\nWhy another Javascript DICOM parsing library?\n============================================\n\nWhile building the WADO Image Loader for [cornerstone](https://github.com/cornerstonejs/cornerstone), I couldn't find a Javascript DICOM parser that exactly met\nmy needs.  DICOM really isn't that hard to parse so I figured I would just make my own.  Here are some of the key things that I\nreally wanted out of a DICOM library that I am hoping to deliver:\n\n* License is extremely liberal so it could be used in any type of project\n* Only deals with parsing DICOM - no code to actually display the images\n* Designed to work well in a browser (modern ones at least)\n* Follows modern javascript best practices\n* Has documentation and examples on how to use it\n* Does not hide the underlying data stream from you\n* Does not require a data dictionary\n* Decodes individual elements \"on demand\" - this goes with not needing a data dictionary\n* Code guards against corrupt or invalid data streams by sanity checking lengths and offsets\n* Does not depend on any external dependencies - just drop it in and go\n* Has unit tests\n* Code is easy to understand\n\nInterested in knowing why the above goals are important to me?  Here you go:\n\n_License is extremely liberal so it could be used in any type of project_\n\nDICOM is an open standard and parsing it is easy enough that it should be freely available for\nall types of products - personal, open source and commercial.  I am hoping that the MIT license\nwill help it see the widest possible adoption (which will in the end help the most patients).\nI will dual license it under GPL if someone asks.\n\n_Only deals with parsing DICOM - no code to actually display the images_\n\nI am a big believer in small reusable pieces of software and loose coupling.  There is no reason to\ntightly couple the parser with image display.  I hope that keeping this library small and simple will\nhelp it reach the widest adoption.\n\n_Designed to work well in a browser (modern ones at least)_\n\nThere are some [good javascript DICOM parsing libraries](https://github.com/grmble/node-dicom) available for server development on node.js but they\nwon't automatically work in a browser.  I needed a library that let me easily parse WADO responses and\nI figured others would also prefer a simple library to do this with no dependencies.\nThe library does make use of the [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBuffer)\nobject which is widely supported except for IE (it is available on IE10+).  I have no current plans to add support\nfor older versions of IE but would be open to contributions if someone wants to do the work.\n\n_Follows modern javascript best practices_\n\nThis of course means different things to different people but I have found great benefit from making sure\nmy javascript passes [jshint](http://www.jshint.com/) and leveraging the\n[module pattern](http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html).  I also have a great affinity to\n[AMD modules](http://requirejs.org/docs/whyamd.html) but I understand that not everyone wants to use them.\nSo for this library I am shooting for simply making sure the code uses the module pattern and passes jshint.\n\n_Has documentation and examples on how to use it_\n\nDo I really need to convince you that this is needed?\n\n_Does not hide the underlying data stream from you_\n\nI have used many DICOM parsing libraries over the years and most of them either hide the underlying byte stream\nfrom you or make it difficult to access.  There are times when you need to access the underlying bytes  - and\nit is frustrating when the library works against you.  A few examples of the need for this include\nUN VR's, private attributes, encapsulated pixel data and implicit little endian transfer\nsyntaxes (which unfortunately are still widely being used) when you don't have a complete data dictionary.\n\nThis library addresses this issue by exposing the offset and length of the data portion of each\n element.  It also defers parsing (and type converting) the data until it is actually asked to do so.\n So what you get from a parse is basically a set of pointers to where the data for each element is in the\nbyte stream and then you call the function you want to extract the type you want.  An awesome side\neffect of this is that you don't need a data dictionary to parse a file even if it uses implicit\nlittle endian.  It also turns out that parsing this way is very fast as it avoids doing unneeded type conversions.\n\nNote that you cannot 100% reliably parse sequence elements in an implicit little endian\ntransfer syntax without a data dictionary.  I therefore *strongly* recommend that you work with explicit transfer\nsyntaxes whenever possible.  Fortunately most Image Archives should be able to give you an explicit\ntransfer syntax encoding of your sop instance even if it received it in implicit little endian.\n\nNote that WADO's default transfer syntax is explicit little endian so one would assume that an\nImage Archive supporting WADO would have a good data dictionary management system.\nInitially I wasn't going to support parsing of implicit data at all but decided to mainly for\nconvenience (and the fact that many of my test data sets are in little endian transfer syntax and I am too\nlazy to convert them to explicit transfer syntax).\n\n_Does not require a data dictionary_\n\nAs a client, you usually you know which elements you want to access and know what type they are so designing a\nclient oriented parser around a data dictionary is adding unnecessary complexity, especially if you can stick to\nexplicit transfer syntaxes.  I also believe it is the the server's responsibility to provide the client\n safe and easily digestable data (i.e. explicit transfer syntaxes).  A server typically supports\nmany types of clients so it makes sense to centralize data dictionary management in one place rather\nthan burden each client with it.\n\nData dictionaries are not required for most client use cases anyway so I decided not to support it in this library\nat all.  For those use cases that do require a data dictionary, you can layer it on top of this library.  An example\nof doing so is provided in the live examples.  If you do want to know the VR, request the instance in an\nexplicit transfer syntax and you can have it.  If your Image Archive can't do this for you, get a new one - seriously.\n\n_Decodes individual elements \"on demand\" - this goes with not needing a data dictionary_\n\nSee above, this is related to not requiring a data dictionary.  Usually you know exactly what elements you need\nand what their types are.  The only time this is not the case is when you are building a DICOM Dump utility or\nyou can't get an explicit transfer syntax and have one of those problematic elements that can be either OB or OW (and you\ncan _usually_ figure out which one it is without the VR anyway)\n\n_Code guards against corrupt or invalid data streams by sanity checking lengths and offsets_\n\nEven though you would expect an Image Archive to _never_ send you data that isn't 100% DICOM compliant,\nthat is not a bet I would make.  As I like to say - there is no \"DICOM police\" to penalize vendors\nwho ship software that creates bytes streams that violate the DICOM standard.  Regardless, it is good\npractice to never trust data from another system - even one that you are in full control of.\n\n_Does not depend on any external dependencies - just drop it in and go_\n\nSort of addressed above as maximizing adoption requires that the library minimize the burden on its users.  I did\nfind a few interesting libraries that were targeted at making it easier and safer to parse byte streams but\nthey just seemed like overkill so I decided to do it all in one to keep it as simple as it could be.  In general\nI am a big fan of building complex systems from lots of smaller simpler pieces.  Some good\nreferences on this include the [microjs site](http://microjs.com/#) and the\n[cujo.js manifseto](http://cujojs.com/manifesto.html)\n\n_Has unit tests_\n\nI generally feel that units tests are _often_ a waste of time for front end development.  Where unit tests do make sense\nis code that is decoupled from the user interface - like a DICOM parsing module.  I did use\n[TDD](http://en.wikipedia.org/wiki/Test-driven_development) on this project and had unit tests\ncovering ~ 80% of the code paths passing before I even tried to load my first real DICOM file.  Before I wrote\nthis library, I did a quick prototype without unit tests that actually took me much less time\n(writing tests takes time....).   So in the end I don't think it saved me much time getting to a first release,\nbut I am hoping it will pay for itself in the long run (especially if this library receives wide adoption).\nI also know that some people out there won't even look at it unless it has good test coverage.\n\nInteresting note here - I did not write unit tests for sequence parsing and undefined lengths mainly because I found\nthe standard difficult to understand in these areas and didn't want to waste my time building tests that were not\ncorrect.  I ended up making these work by throwing a variety of data sets at it and fixing the issues that I found.\nGetting this working took about 3x longer than everything else combined so perhaps it would have been faster if I had\nused TDD on this part.\n\n_Code is easy to understand_\n\nIn my experience, writing code that is easy to understand is *far more important* than writing documentation or unit\ntests for that code.  The reason is that when a developer needs to fix or enhance a piece of code, they _almost never_\nstart with the unit tests or documentation - they jump straight into the code and start thrashing about in the debugger.\nIf some other developer is looking at your code, you probably made a mistake - either a simple typo or a design issue if you\nreally blew it.  In either case, you should have mercy on them in advance and make their unenviable task of fixing\nor extending your code the best it can be.  Some principles I try to follow include:\n\n* Clear names for source files, functions and variables.  These names can get very long but I find that doing so is\nbetter than writing comments in the source file\n* Small source files.  Generally I try to keep each source file to under 300 lines or so.  The longer it gets, the\nharder it is to remember what you are looking at\n* Small functions.  The longer the function is, the harder it is to understand\n\nYou can find out more about this by googling for \"self documenting code\"\n\nIn the Wild\n===========\n\n- [VS Code: DICOM Dump Extension](https://github.com/smikitky/vscode-dicom-dump)\n\nCopyright\n============\nCopyright 2016 Chris Hafey [chafey@gmail.com](mailto:chafey@gmail.com)\n\n[license-image]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat\n[license-url]: LICENSE\n\n[npm-url]: https://npmjs.org/package/dicom-parser\n[npm-version-image]: http://img.shields.io/npm/v/dicom-parser.svg?style=flat\n[npm-downloads-image]: http://img.shields.io/npm/dm/dicom-parser.svg?style=flat\n\n[travis-url]: http://travis-ci.org/cornerstonejs/dicomParser\n[travis-image]: https://travis-ci.org/cornerstonejs/dicomParser.svg?branch=master\n\n[coverage-url]: https://coveralls.io/github/cornerstonejs/dicomParser?branch=master\n[coverage-image]: https://coveralls.io/repos/github/cornerstonejs/dicomParser/badge.svg?branch=master\n","funding_links":[],"categories":["Libraries"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcornerstonejs%2FdicomParser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcornerstonejs%2FdicomParser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcornerstonejs%2FdicomParser/lists"}