def read_item(fp: DicomFileLike) -> Optional[bytes]: """Read and return a single Item in the fragmented data stream. Parameters ---------- fp : filebase.DicomIO The file-like to read the item from. Returns ------- bytes The Item's raw bytes. """ logger = pydicom.config.logger try: tag = fp.read_tag() # already read delimiter before passing data here # so should just run out except EOFError: return None # No more items, time for sequence to stop reading if tag == SequenceDelimiterTag: length = fp.read_UL() logger.debug( "%04x: Sequence Delimiter, length 0x%x", fp.tell() - 8, length) if length != 0: logger.warning( "Expected 0x00000000 after delimiter, found 0x%x," " at data position 0x%x", length, fp.tell() - 4) return None if tag != ItemTag: logger.warning( "Expected Item with tag %s at data position 0x%x", ItemTag, fp.tell() - 4) length = fp.read_UL() else: length = fp.read_UL() logger.debug( "%04x: Item, length 0x%x", fp.tell() - 8, length) if length == 0xFFFFFFFF: raise ValueError( "Encapsulated data fragment had Undefined Length" " at data position 0x%x" % (fp.tell() - 4, )) item_data = fp.read(length) return item_data
def write_dataset_to_bytes(dataset): # 버퍼 생성 with BytesIO() as buffer: # DicomFileLike 오브젝트 생성 memory_dataset = DicomFileLike(buffer) dcmwrite(memory_dataset, dataset) memory_dataset.seek(0) return memory_dataset.read()
def write_dataset_to_bytes(dataset): # create a buffer with BytesIO() as buffer: # create a DicomFileLike object that has some properties of DataSet memory_dataset = DicomFileLike(buffer) # write the dataset to the DicomFileLike object dcmwrite(memory_dataset, dataset) # to read from the object, you have to rewind it memory_dataset.seek(0) # read the contents as bytes return memory_dataset.read()
def write_dataset_to_bytes(dataset): # 버퍼를 생성한다. with BytesIO() as buffer: # Dataset의 속성들을 담을 DicomFileLike 객체를 만든다. memory_dataset = DicomFileLike(buffer) # Dataset을 DicomFileLike 객체에 write 한다. dcmwrite(memory_dataset, dataset) # 객체에서 읽어오기 위해 rewind 한다. memory_dataset.seek(0) # 바이트로 읽어서 리턴한다. return memory_dataset.read()
def to_bytes(dcm: pydicom.dataset.FileDataset): """Converts dicom object to byte sequence, source https://pydicom.github.io/pydicom/dev/auto_examples/memory_dataset.html""" with BytesIO() as buffer: memory_dataset = DicomFileLike( buffer ) # create a DicomFileLike object that has some properties of DataSet dcmwrite(memory_dataset, dcm) # write the dataset to the DicomFileLike object memory_dataset.seek( 0) # to read from the object, you have to rewind it return memory_dataset.read() # read the contents as bytes
def generate_pixel_data_fragment( fp: DicomFileLike) -> Generator[bytes, None, None]: """Yield the encapsulated pixel data fragments. For compressed (encapsulated) Transfer Syntaxes, the (7FE0,0010) *Pixel Data* element is encoded in an encapsulated format. **Encapsulation** The encoded pixel data stream is fragmented into one or more Items. The stream may represent a single or multi-frame image. Each *Data Stream Fragment* shall have tag of (FFFE,E000), followed by a 4 byte *Item Length* field encoding the explicit number of bytes in the Item. All Items containing an encoded fragment shall have an even number of bytes greater than or equal to 2, with the last fragment being padded if necessary. The first Item in the Sequence of Items shall be a 'Basic Offset Table', however the Basic Offset Table item value is not required to be present. It is assumed that the Basic Offset Table item has already been read prior to calling this function (and that `fp` is positioned past this item). The remaining items in the Sequence of Items are the pixel data fragments and it is these items that will be read and returned by this function. The Sequence of Items is terminated by a (FFFE,E0DD) *Sequence Delimiter Item* with an Item Length field of value ``0x00000000``. The presence or absence of the *Sequence Delimiter Item* in `fp` has no effect on the returned fragments. *Encoding* The encoding of the data shall be little endian. Parameters ---------- fp : filebase.DicomFileLike The encoded (7FE0,0010) *Pixel Data* element value, positioned at the start of the item tag for the first item after the Basic Offset Table item. ``fp.is_little_endian`` should be set to ``True``. Yields ------ bytes A pixel data fragment. Raises ------ ValueError If the data contains an item with an undefined length or an unknown tag. References ---------- DICOM Standard Part 5, :dcm:`Annex A.4 <part05/sect_A.4.html>` """ if not fp.is_little_endian: raise ValueError("'fp.is_little_endian' must be True") # We should be positioned at the start of the Item Tag for the first # fragment after the Basic Offset Table while True: try: tag = Tag(fp.read_tag()) except EOFError: break if tag == 0xFFFEE000: # Item length = fp.read_UL() if length == 0xFFFFFFFF: raise ValueError( f"Undefined item length at offset {fp.tell() - 4} when " "parsing the encapsulated pixel data fragments") yield fp.read(length) elif tag == 0xFFFEE0DD: # Sequence Delimiter # Behave nicely and rewind back to the end of the items fp.seek(-4, 1) break else: raise ValueError( f"Unexpected tag '{tag}' at offset {fp.tell() - 4} when " "parsing the encapsulated pixel data fragment items")