def test_not_little_endian(self): """Test reading big endian raises exception""" bytestream = b'\xFE\xFF\x00\xE0' \ b'\x00\x00\x00\x00' fp = DicomBytesIO(bytestream) fp.is_little_endian = False with pytest.raises(ValueError, match="'fp.is_little_endian' must be True"): get_frame_offsets(fp)
def test_not_little_endian(self): """Test reading big endian raises exception""" bytestream = b'\xFE\xFF\x00\xE0' \ b'\x00\x00\x00\x00' fp = DicomBytesIO(bytestream) fp.is_little_endian = False with pytest.raises(ValueError, match="'fp.is_little_endian' must be True"): get_frame_offsets(fp)
def test_bad_length_multiple(self): """Test raises exception if the item length is not a multiple of 4.""" # Length 10 bytestream = b'\xFE\xFF\x00\xE0' \ b'\x0A\x00\x00\x00' \ b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A' fp = DicomBytesIO(bytestream) fp.is_little_endian = True with pytest.raises(ValueError, match="The length of the Basic Offset Table item" " is not a multiple of 4."): get_frame_offsets(fp)
def test_bad_tag(self): """Test raises exception if no item tag.""" # (fffe,e100) bytestream = b'\xFE\xFF\x00\xE1' \ b'\x08\x00\x00\x00' \ b'\x01\x02\x03\x04\x05\x06\x07\x08' fp = DicomBytesIO(bytestream) fp.is_little_endian = True with pytest.raises(ValueError, match="Unexpected tag '\(fffe, e100\)' when " "parsing the Basic Table Offset item."): get_frame_offsets(fp)
def test_bad_length_multiple(self): """Test raises exception if the item length is not a multiple of 4.""" # Length 10 bytestream = b'\xFE\xFF\x00\xE0' \ b'\x0A\x00\x00\x00' \ b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A' fp = DicomBytesIO(bytestream) fp.is_little_endian = True with pytest.raises(ValueError, match="The length of the Basic Offset Table item" " is not a multiple of 4."): get_frame_offsets(fp)
def test_bad_tag(self): """Test raises exception if no item tag.""" # (fffe,e100) bytestream = b'\xFE\xFF\x00\xE1' \ b'\x08\x00\x00\x00' \ b'\x01\x02\x03\x04\x05\x06\x07\x08' fp = DicomBytesIO(bytestream) fp.is_little_endian = True with pytest.raises(ValueError, match="Unexpected tag '\(fffe, e100\)' when " "parsing the Basic Table Offset item."): get_frame_offsets(fp)
def test_zero_length(self): """Test reading BOT with zero length""" bytestream = b'\xFE\xFF\x00\xE0' \ b'\x00\x00\x00\x00' fp = DicomBytesIO(bytestream) fp.is_little_endian = True assert [0] == get_frame_offsets(fp)
def test_encapsulate_single_fragment_per_frame_bot(self): """Test encapsulating single fragment per frame with BOT values.""" ds = dcmread(JP2K_10FRAME_NOBOT) frames = decode_data_sequence(ds.PixelData) assert len(frames) == 10 data = encapsulate(frames, fragments_per_frame=1, has_bot=True) test_frames = decode_data_sequence(data) for a, b in zip(test_frames, frames): assert a == b fp = DicomBytesIO(data) fp.is_little_endian = True length, offsets = get_frame_offsets(fp) assert offsets == [ 0x0000, # 0 0x0eee, # 3822 0x1df6, # 7670 0x2cf8, # 11512 0x3bfc, # 15356 0x4ade, # 19166 0x59a2, # 22946 0x6834, # 26676 0x76e2, # 30434 0x8594 # 34196 ]
def test_zero_length(self): """Test reading BOT with zero length""" bytestream = b'\xFE\xFF\x00\xE0' \ b'\x00\x00\x00\x00' fp = DicomBytesIO(bytestream) fp.is_little_endian = True assert [0] == get_frame_offsets(fp)
def test_encapsulate_single_fragment_per_frame_bot(self): """Test encapsulating single fragment per frame with BOT values.""" ds = dcmread(JP2K_10FRAME_NOBOT) frames = decode_data_sequence(ds.PixelData) assert len(frames) == 10 data = encapsulate(frames, fragments_per_frame=1, has_bot=True) test_frames = decode_data_sequence(data) for a, b in zip(test_frames, frames): assert a == b fp = DicomBytesIO(data) fp.is_little_endian = True offsets = get_frame_offsets(fp) assert offsets == [ 0x0000, # 0 0x0eee, # 3822 0x1df6, # 7670 0x2cf8, # 11512 0x3bfc, # 15356 0x4ade, # 19166 0x59a2, # 22946 0x6834, # 26676 0x76e2, # 30434 0x8594 # 34196 ]
def test_single_frame(self): """Test reading single-frame BOT item""" bytestream = b'\xFE\xFF\x00\xE0' \ b'\x04\x00\x00\x00' \ b'\x00\x00\x00\x00' fp = DicomBytesIO(bytestream) fp.is_little_endian = True assert [0] == get_frame_offsets(fp)
def test_single_frame(self): """Test reading single-frame BOT item""" bytestream = b'\xFE\xFF\x00\xE0' \ b'\x04\x00\x00\x00' \ b'\x00\x00\x00\x00' fp = DicomBytesIO(bytestream) fp.is_little_endian = True assert [0] == get_frame_offsets(fp)
def test_multi_frame(self): """Test reading multi-frame BOT item""" bytestream = b'\xFE\xFF\x00\xE0' \ b'\x10\x00\x00\x00' \ b'\x00\x00\x00\x00' \ b'\x66\x13\x00\x00' \ b'\xF4\x25\x00\x00' \ b'\xFE\x37\x00\x00' fp = DicomBytesIO(bytestream) fp.is_little_endian = True assert [0, 4966, 9716, 14334] == get_frame_offsets(fp)
def test_multi_frame(self): """Test reading multi-frame BOT item""" bytestream = b'\xFE\xFF\x00\xE0' \ b'\x10\x00\x00\x00' \ b'\x00\x00\x00\x00' \ b'\x66\x13\x00\x00' \ b'\xF4\x25\x00\x00' \ b'\xFE\x37\x00\x00' fp = DicomBytesIO(bytestream) fp.is_little_endian = True assert [0, 4966, 9716, 14334] == get_frame_offsets(fp)
def _read_bot(fp: DicomFile) -> List[int]: """Reads the Basic Offset Table (BOT) item of an encapsulated Pixel Data element. Parameters ---------- fp: pydicom.filebase.DicomFile Pointer for DICOM PS3.10 file stream positioned at the first byte of the Pixel Data element Returns ------- List[int] Offset of each Frame item in bytes from the first byte of the Pixel Data element following the BOT item Note ---- Moves the pointer to the first byte of the open file following the BOT item (the first byte of the first Frame item). Raises ------ IOError When file pointer is not positioned at first byte of Pixel Data element """ tag = TupleTag(fp.read_tag()) if int(tag) not in _PIXEL_DATA_TAGS: raise IOError( 'Expected file pointer at first byte of Pixel Data element.') # Skip Pixel Data element header (tag, VR, length) pixel_data_element_value_offset = data_element_offset_to_value( fp.is_implicit_VR, 'OB') fp.seek(pixel_data_element_value_offset - 4, 1) is_empty, offsets = get_frame_offsets(fp) return offsets