Initial commit
This commit is contained in:
135
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/pydicom/util/dump.py
vendored
Executable file
135
dist/dicom2pacs.app/Contents/Resources/lib/python3.13/pydicom/util/dump.py
vendored
Executable file
@@ -0,0 +1,135 @@
|
||||
# Copyright 2008-2021 pydicom authors. See LICENSE file for details.
|
||||
"""Utility functions used in debugging writing and reading"""
|
||||
|
||||
from io import BytesIO
|
||||
import os
|
||||
import sys
|
||||
from typing import BinaryIO, TYPE_CHECKING
|
||||
|
||||
from pydicom.valuerep import VR
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from pydicom.dataset import Dataset
|
||||
|
||||
|
||||
def print_character(ordchr: int) -> str:
|
||||
"""Return a printable character, or '.' for non-printable ones."""
|
||||
if 31 < ordchr < 126 and ordchr != 92:
|
||||
return chr(ordchr)
|
||||
|
||||
return "."
|
||||
|
||||
|
||||
def filedump(
|
||||
filename: str | bytes | os.PathLike,
|
||||
start_address: int = 0,
|
||||
stop_address: int | None = None,
|
||||
) -> str:
|
||||
"""Dump out the contents of a file to a standard hex dump 16 bytes wide"""
|
||||
|
||||
with open(filename, "rb") as f:
|
||||
return hexdump(f, start_address, stop_address)
|
||||
|
||||
|
||||
def datadump(
|
||||
data: bytes, start_address: int = 0, stop_address: int | None = None
|
||||
) -> str:
|
||||
"""Return a hex string representation of `data`."""
|
||||
return hexdump(BytesIO(data), start_address, stop_address)
|
||||
|
||||
|
||||
def hexdump(
|
||||
f: BinaryIO,
|
||||
start_address: int = 0,
|
||||
stop_address: int | None = None,
|
||||
show_address: bool = True,
|
||||
) -> str:
|
||||
"""Return a formatted string of hex bytes and characters in data.
|
||||
|
||||
This is a utility function for debugging file writing.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
f : BinaryIO
|
||||
The file-like to dump.
|
||||
start_address : int, optional
|
||||
The offset where the dump should start (default ``0``)
|
||||
stop_address : int, optional
|
||||
The offset where the dump should end, by default the entire file will
|
||||
be dumped.
|
||||
show_address : bool, optional
|
||||
If ``True`` (default) then include the offset of each line of output.
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
"""
|
||||
|
||||
s = []
|
||||
|
||||
# Determine the maximum number of characters for the offset
|
||||
max_offset_len = len(f"{f.seek(0, 2):X}")
|
||||
if stop_address:
|
||||
max_offset_len = len(f"{stop_address:X}")
|
||||
|
||||
f.seek(start_address)
|
||||
while True:
|
||||
offset = f.tell()
|
||||
if stop_address and offset > stop_address:
|
||||
break
|
||||
|
||||
data = f.read(16)
|
||||
if not data:
|
||||
break
|
||||
|
||||
current = []
|
||||
|
||||
if show_address:
|
||||
# Offset at the start of the current line
|
||||
current.append(f"{offset:0{max_offset_len}X} ")
|
||||
|
||||
# Add hex version of the current line
|
||||
b = " ".join([f"{x:02X}" for x in data])
|
||||
current.append(f"{b:<49}") # if fewer than 16 bytes, pad out to length
|
||||
|
||||
# Append the ASCII version of the current line (or . if not ASCII)
|
||||
current.append("".join([print_character(x) for x in data]))
|
||||
|
||||
s.append("".join(current))
|
||||
|
||||
return "\n".join(s)
|
||||
|
||||
|
||||
def pretty_print(
|
||||
ds: "Dataset", indent_level: int = 0, indent_chars: str = " "
|
||||
) -> None:
|
||||
"""Print a dataset directly, with indented levels.
|
||||
|
||||
This is just like Dataset._pretty_str, but more useful for debugging as it
|
||||
prints each item immediately rather than composing a string, making it
|
||||
easier to immediately see where an error in processing a dataset starts.
|
||||
|
||||
"""
|
||||
|
||||
indent = indent_chars * indent_level
|
||||
next_indent = indent_chars * (indent_level + 1)
|
||||
for elem in ds:
|
||||
if elem.VR == VR.SQ: # a sequence
|
||||
print(f"{indent}{elem.tag} {elem.name} -- {len(elem.value)} item(s)")
|
||||
for dataset in elem.value:
|
||||
pretty_print(dataset, indent_level + 1)
|
||||
print(next_indent + "---------")
|
||||
else:
|
||||
print(indent + repr(elem))
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
filename = sys.argv[1]
|
||||
start_address = 0
|
||||
stop_address = None
|
||||
if len(sys.argv) > 2: # then have start address
|
||||
start_address = eval(sys.argv[2])
|
||||
if len(sys.argv) > 3:
|
||||
stop_address = eval(sys.argv[3])
|
||||
|
||||
print(filedump(filename, start_address, stop_address))
|
||||
Reference in New Issue
Block a user