{"id":20147590,"url":"https://github.com/headwinds/dicom","last_synced_at":"2025-08-29T21:40:37.224Z","repository":{"id":262027472,"uuid":"886020894","full_name":"headwinds/dicom","owner":"headwinds","description":"experiment to parse a dicom array buffer","archived":false,"fork":false,"pushed_at":"2024-11-19T23:12:35.000Z","size":316,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-03T00:23:16.706Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/headwinds.png","metadata":{"files":{"readme":"README.md","changelog":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-11-10T01:15:20.000Z","updated_at":"2024-11-19T23:12:39.000Z","dependencies_parsed_at":"2024-11-10T02:23:36.899Z","dependency_job_id":"44c17c60-c51b-4af2-a4bc-12c3a2fe40a4","html_url":"https://github.com/headwinds/dicom","commit_stats":null,"previous_names":["headwinds/dicom"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/headwinds/dicom","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/headwinds%2Fdicom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/headwinds%2Fdicom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/headwinds%2Fdicom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/headwinds%2Fdicom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/headwinds","download_url":"https://codeload.github.com/headwinds/dicom/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/headwinds%2Fdicom/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272766964,"owners_count":24989408,"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","status":"online","status_checked_at":"2025-08-29T02:00:10.610Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-11-13T22:29:48.181Z","updated_at":"2025-08-29T21:40:37.198Z","avatar_url":"https://github.com/headwinds.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Parse a DICOM Buffered Array\n\nAn experiment to parse [DICOM](https://www.dicomstandard.org/about) and learn more about it's [Multipart](https://dicom.nema.org/medical/dicom/current/output/chtml/part18/sect_8.7.html) content type and how [dcmjs](https://github.com/dcmjs-org/dcmjs) uses an [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) to make DICOM post requests.\n\n### Demo \u0026 Prototype\n\nYou can copy and paste Int32 array from your clipboard into the input. See the included sample.json for an example.\n\n- [dicom-standard.vercel.app](https://dicom-standard.vercel.app/)\n- [dicom-buffer.verce.app](https://dicom-buffer.vercel.app/)\n- [v0 convo](https://v0.dev/chat/XB512mtnRje?b=b_qDriYBBHbbZ)\n\n### More About DICOM\n\nDICOM is a [standard](https://www.dicomstandard.org/current) for files (.dcm) contain both metadata (tags) and pixel data.\n\nThe data is organized into a series of data elements with specific Value Representations (VR) that define their data types.\n\n### Why Multipart content type instead of JSON?\n\nDICOM uses Multipart content type to encapsulate multiple data elements in a single message. This is because DICOM is designed to handle large medical images and other data types that are not easily represented in JSON format. Multipart content type allows DICOM to efficiently transmit and store complex data structures without the need for additional encoding or compression.\n\nMultipart messages allow combining multiple parts of data that are merged after request completion.\n\nParts are separated by boundaries specified in the Content-Type header.\n\n[OHIF](https://ohif.org/) relies on cornerstonejs and the dcmjs library to parse DICOM files and make http requests to the DICOM server.\n\nThe [Cornerstone dicomParser](https://github.com/cornerstonejs/dicomParser) library actually doesn't include a built-in data dictionary by design1. This is an intentional choice as the library focuses on lightweight parsing without requiring a data dictionary.\n\n## Why tags and not English?\n\nDICOM uses tags to identify data elements. Tags are 32-bit numbers that are divided into two parts: a group number and an element number. The group number identifies the type of data element, while the element number identifies the specific data element within that group.\n\nBy using tags instead of English names, DICOM ensures that data elements are uniquely identified and can be easily referenced by software applications. This allows DICOM files to be easily parsed and processed by different systems without the need for translation or conversion. Thus, Radiologists in Russia or China can easily read the DICOM files without the need for translation.\n\nSince there are an overwhelming number of tags, it is recommended for each company to create their own dictionary for the tags they require. To get started, companies can use a data dictionary to map tags to human-readable names.\n\n## Tag System\n\n[DICOM (wikipedia)](https://en.wikipedia.org/wiki/DICOM) uses a comprehensive system where:\n\n- Tags are organized in groups and elements (XXXX,XXXX format)\n- Public data elements have even group numbers (defined in the DICOM data dictionary)\n- Private data elements have odd group numbers (manufacturer-specific)\n\nExample: (0008,0020) is the Study Date tag\n\nEach DICOM tag consists of:\n\n- A unique identifier in (group,element) format\n- One of 27 explicit Value Representations (VRs)\n- A value length\n- The actual value data\n\nThere is an extensive list of tags that can be found in the [DICOM data dictionary](https://www.dicomlibrary.com/dicom/dicom-tags/).\n\n## Javascript\n\n- [dcmjs](https://github.com/dcmjs-org/dcmjs)\n- [dcmjs dictionary](https://github.com/dcmjs-org/dcmjs/blob/6840af9d20333144675227b7006772a3a1b84e46/src/dictionary.js)\n\n## Typescript\n\n- [dicom.ts](https://github.com/wearemothership/dicom.ts) by [wearemothership](https://wearemothership.com/)\n\n## Console Logging ArrayBuffer\n\n```\nArrayBuffer(2908)\n    byteLength: 2908\n    detached: false\n    maxByteLength: 2908\n    resizable: false\n    [[Prototype]]: ArrayBuffer\n    [[Int8Array]]: Int8Array(2908)\n    [[Uint8Array]]: Uint8Array(2908)\n    [[Int16Array]]: Int16Array(1454)\n    [[Int32Array]]: Int32Array(727)\n    [[ArrayBufferByteLength]]: 2908\n    [[ArrayBufferData]]: 92529\n```\n\nThe ArrayBuffer holds 2908 bytes of raw binary data.\n\nEach array type provides a different way to read/interpret those same bytes.\n\neach array type is viewing the exact same bytes, just grouping them differently by size and interpreting their values according to their type (signed vs unsigned).\n\n```\n// Same 4 bytes could be read as:\nInt8Array:   [1, 2, 3, 4]         // Four 8-bit numbers\nInt16Array:  [513, 1027]          // Two 16-bit numbers\nInt32Array:  [67305985]           // One 32-bit number\n```\n\nDICOM files the Int32Array data is typically organized into distinct sections. Here's the standard structure:\n\n## DICOM Data Organization\n\n#### Preamble \u0026 Prefix (128 + 4 bytes)\n\n```\n// First 132 bytes\nconst preamble = new Uint8Array(arrayBuffer, 0, 128);\nconst pre\n```\n\n#### Meta Information Header\n\n- Usually follows prefix\n- Contains file metadata (Transfer Syntax, - Implementation details)\n- Group number (0002,xxxx)\n\n#### Data Elements\n\nOrganized as sequences of:\n\n```\nTag (4 bytes) - Group,Element numbers\nVR (2 bytes) - Value Representation\nLength (2 or 4 bytes)\nValue (variable length)\n\n```\n\n#### Pixel Data\n\n- Usually at the end\n- Tag (7FE0,0010)\n- Contains actual image data\n\n```\nconst dicomData = new Int32Array(arrayBuffer);\n\n// Accessing sections\nconst metaHeaderStart = 132 / 4; // Convert bytes to 32-bit integers\nconst elementStart = metaHeaderStart + (metaHeaderLength / 4);\nconst pixelDataStart = (pixelDataOffset / 4);\n```\n\nNote: Exact offsets depend on transfer syntax and encoding used in the file.\n\n## Python\n\n- [pydicom](https://github.com/pydicom/pydicom)\n\nAnd many more [awesome dicom](https://github.com/open-dicom/awesome-dicom) resources\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fheadwinds%2Fdicom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fheadwinds%2Fdicom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fheadwinds%2Fdicom/lists"}