def time_decode_16bit_1sample_10frame(self): """Time decoding the pixel data from 10 RLE frames.""" for ii in range(self.no_runs): for frame in self.frames: _rle_decode_frame(frame, self.ds.Rows, self.ds.Columns, self.ds.SamplesPerPixel, self.ds.BitsAllocated)
def time_decode_16bit_1sample_1frame(self): """Time decoding the pixel data from a single RLE frame.""" for ii in range(self.no_runs): _rle_decode_frame(self.frames[0], self.ds.Rows, self.ds.Columns, self.ds.SamplesPerPixel, self.ds.BitsAllocated)
def test_unsupported_bits_allocated_raises(self): """Test exception raised for BitsAllocated not a multiple of 8.""" msg = ( r"Unable to decode RLE encoded pixel data with a \(0028,0100\) " r"'Bits Allocated' value of 12" ) with pytest.raises(NotImplementedError, match=msg): _rle_decode_frame(b'\x00\x00\x00\x00', 1, 1, 1, 12)
def test_invalid_nr_segments_raises(self, header, samples, bits): """Test having too many segments in the data raises exception.""" # This should probably be ValueError with pytest.raises(AttributeError, match='Unexpected number of planes'): _rle_decode_frame(header, rows=1, columns=1, samples_per_pixel=samples, bits_allocated=bits)
def test_invalid_segment_data_raises(self): """Test invalid segment data raises exception""" ds = dcmread(RLE_16_1_1F) pixel_data = defragment_data(ds.PixelData) msg = r"amount \(4095 vs. 4096 bytes\)" with pytest.raises(ValueError, match=msg): _rle_decode_frame( pixel_data[:-1], ds.Rows, ds.Columns, ds.SamplesPerPixel, ds.BitsAllocated )
def test_invalid_nr_segments_raises(self, header, samples, bits): """Test having too many segments in the data raises exception.""" # This should probably be ValueError expected = samples * bits // 8 actual = unpack('<L', header)[0] header += b'\x00' * (64 - len(header)) msg = ( r"expected amount \({} vs. {} segments\)".format(actual, expected) ) with pytest.raises(ValueError, match=msg): _rle_decode_frame( header, rows=1, columns=1, nr_samples=samples, nr_bits=bits )
def test_invalid_frame_data_raises(self): """Test that invalid segment data raises exception.""" ds = dcmread(MR_RLE_1F) pixel_data = defragment_data(ds.PixelData) # Missing byte with pytest.raises(ValueError, match=r'amount \(4095 vs. 4096 bytes\)'): _rle_decode_frame(pixel_data[:-1], ds.Rows, ds.Columns, ds.SamplesPerPixel, ds.BitsAllocated) # Extra byte with pytest.raises(ValueError, match=r'amount \(4097 vs. 4096 bytes\)'): _rle_decode_frame(pixel_data + b'\x00\x01', ds.Rows, ds.Columns, ds.SamplesPerPixel, ds.BitsAllocated)
def test_16bit_3sample(self): """Test decoding 16-bit, 3 sample/pixel.""" header = ( b'\x06\x00\x00\x00' # 6 segments b'\x40\x00\x00\x00' # 64 b'\x47\x00\x00\x00' # 71 b'\x4E\x00\x00\x00' # 78 b'\x55\x00\x00\x00' # 85 b'\x5C\x00\x00\x00' # 92 b'\x63\x00\x00\x00' # 99 ) header += (64 - len(header)) * b'\x00' # 2 x 3 data data = ( # 0, 1, 256, 255, 65280, 65535 b'\x05\x00\x00\x01\x00\xFF\xFF' # MSB b'\x05\x00\x01\x00\xFF\x00\xFF' # LSB b'\x05\xFF\x00\x01\x00\xFF\x00' # MSB b'\x05\xFF\x01\x00\xFF\x00\x00' # LSB b'\x05\x00\x00\x01\x00\xFF\xFF' # MSB b'\x05\x01\x01\x00\xFF\x00\xFE' # LSB ) decoded = _rle_decode_frame(header + data, 2, 3, 3, 16) arr = np.frombuffer(decoded, np.dtype('>u2')) assert [0, 1, 256, 255, 65280, 65535] == arr[:6].tolist() assert [65535, 1, 256, 255, 65280, 0] == arr[6:12].tolist() assert [1, 1, 256, 255, 65280, 65534] == arr[12:].tolist()
def test_8bit_1sample(self): """Test decoding 8-bit, 1 sample/pixel.""" header = (b'\x01\x00\x00\x00' b'\x40\x00\x00\x00') header += (64 - len(header)) * b'\x00' # 2 x 3 data # 0, 64, 128, 160, 192, 255 data = b'\x05\x00\x40\x80\xA0\xC0\xFF' decoded = _rle_decode_frame(header + data, 2, 3, 1, 8) arr = np.frombuffer(decoded, np.dtype('>u1')) assert [0, 64, 128, 160, 192, 255] == arr.tolist()
def test_invalid_frame_data_raises(self): """Test that invalid segment data raises exception.""" ds = dcmread(MR_RLE_1F) pixel_data = defragment_data(ds.PixelData) # Missing byte # This should probably be ValueError with pytest.raises(AttributeError, match='Different number of bytes'): _rle_decode_frame(pixel_data[:-1], ds.Rows, ds.Columns, ds.SamplesPerPixel, ds.BitsAllocated) # Extra byte with pytest.raises(AttributeError, match='Different number of bytes'): _rle_decode_frame(pixel_data + b'\x00\x01', ds.Rows, ds.Columns, ds.SamplesPerPixel, ds.BitsAllocated)
def test_16bit_1sample(self): """Test decoding 16-bit, 1 sample/pixel.""" header = (b'\x02\x00\x00\x00' b'\x40\x00\x00\x00' b'\x47\x00\x00\x00') header += (64 - len(header)) * b'\x00' # 2 x 3 data data = ( # 0, 1, 256, 255, 65280, 65535 b'\x05\x00\x00\x01\x00\xFF\xFF' # MSB b'\x05\x00\x01\x00\xFF\x00\xFF' # LSB ) decoded = _rle_decode_frame(header + data, 2, 3, 1, 16) arr = np.frombuffer(decoded, np.dtype('>u2')) assert [0, 1, 256, 255, 65280, 65535] == arr.tolist()
def test_cycle_32bit_1sample(self): """Test an encode/decode cycle for 32-bit 1 sample/pixel.""" ds = dcmread(EXPL_32_1_1F) ref = ds.pixel_array assert 32 == ds.BitsAllocated assert 1 == ds.SamplesPerPixel kwargs = RLELosslessEncoder.kwargs_from_ds(ds) encoded = _encode_frame(ds.PixelData, **kwargs) decoded = _rle_decode_frame( encoded, ds.Rows, ds.Columns, ds.SamplesPerPixel, ds.BitsAllocated ) arr = np.frombuffer(decoded, '<u4') arr = reshape_pixel_array(ds, arr) assert np.array_equal(ref, arr)
def test_cycle_u8_1s_1f(self): """Test an encode/decode cycle for 8-bit 1 sample/pixel.""" ds = dcmread(EXPL_8_1_1F) ref = ds.pixel_array assert ds.BitsAllocated == 8 assert ds.SamplesPerPixel == 1 assert ds.PixelRepresentation == 0 assert ds.PhotometricInterpretation == 'PALETTE COLOR' enc = RLELosslessEncoder encoded = enc.encode(ds, idx=0, encoding_plugin='gdcm') decoded = _rle_decode_frame(encoded, ds.Rows, ds.Columns, ds.SamplesPerPixel, ds.BitsAllocated) arr = np.frombuffer(decoded, '|u1') assert np.array_equal(ref.ravel(), arr)
def test_nonconf_segment_padding_warns(self): """Test non-conformant segment padding warns""" ds = dcmread(RLE_16_1_1F) pixel_data = defragment_data(ds.PixelData) msg = ( r"The decoded RLE segment contains non-conformant padding - 4097 " r"vs. 4096 bytes expected" ) with pytest.warns(UserWarning, match=msg): frame = _rle_decode_frame( pixel_data + b'\x00\x01', 4096, 1, ds.SamplesPerPixel, ds.BitsAllocated )
def test_cycle_u32_1s_1f(self): """Test an encode/decode cycle for 32-bit 1 sample/pixel.""" ds = dcmread(EXPL_32_1_1F) ref = ds.pixel_array assert ds.BitsAllocated == 32 assert ds.SamplesPerPixel == 1 assert ds.PixelRepresentation == 0 assert ds.PhotometricInterpretation == 'MONOCHROME2' enc = RLELosslessEncoder encoded = enc.encode(ds, idx=0, encoding_plugin='gdcm') decoded = _rle_decode_frame(encoded, ds.Rows, ds.Columns, ds.SamplesPerPixel, ds.BitsAllocated) arr = np.frombuffer(decoded, '>u4') arr = reshape_pixel_array(ds, arr) assert np.array_equal(ref, arr)
def test_functional(self): """Test function works OK.""" ds = dcmread(EXPL_16_3_1F) ref = ds.pixel_array assert ds.BitsAllocated == 16 assert ds.SamplesPerPixel == 3 assert ds.PixelRepresentation == 0 encoded = rle_encode_frame(ref) decoded = _rle_decode_frame( encoded, ds.Rows, ds.Columns, ds.SamplesPerPixel, ds.BitsAllocated ) ds.PlanarConfiguration = 1 arr = np.frombuffer(decoded, '<u2') arr = reshape_pixel_array(ds, arr) assert np.array_equal(ref, arr)
def test_cycle_32bit_3sample(self): """Test an encode/decode cycle for 32-bit 3 sample/pixel.""" ds = dcmread(EXPL_32_3_1F) ref = ds.pixel_array assert ds.BitsAllocated == 32 assert ds.SamplesPerPixel == 3 assert ds.PixelRepresentation == 0 kwargs = RLELosslessEncoder.kwargs_from_ds(ds) encoded = _encode_frame(ds.PixelData, **kwargs) decoded = _rle_decode_frame( encoded, ds.Rows, ds.Columns, ds.SamplesPerPixel, ds.BitsAllocated ) # The decoded data is planar configuration 1 ds.PlanarConfiguration = 1 arr = np.frombuffer(decoded, '<u4') arr = reshape_pixel_array(ds, arr) assert np.array_equal(ref, arr)
def test_cycle_u16_3s_1f(self): """Test an encode/decode cycle for 16-bit 3 sample/pixel.""" ds = dcmread(EXPL_16_3_1F) ref = ds.pixel_array assert ds.BitsAllocated == 16 assert ds.SamplesPerPixel == 3 assert ds.PixelRepresentation == 0 assert ds.PhotometricInterpretation == 'RGB' assert ds.PlanarConfiguration == 0 enc = RLELosslessEncoder encoded = enc.encode(ds, idx=0, encoding_plugin='gdcm') decoded = _rle_decode_frame(encoded, ds.Rows, ds.Columns, ds.SamplesPerPixel, ds.BitsAllocated) arr = np.frombuffer(decoded, '<u2') # The decoded data is planar configuration 1 ds.PlanarConfiguration = 1 arr = reshape_pixel_array(ds, arr) assert np.array_equal(ref, arr)
def test_big_endian_arr(self): """Test using a big endian array works.""" ds = dcmread(EXPL_16_3_1F) ref = ds.pixel_array assert ds.BitsAllocated == 16 assert ds.SamplesPerPixel == 3 assert ds.PixelRepresentation == 0 arr = ref.newbyteorder('>') assert id(arr) != id(ref) assert arr.dtype == '>u2' encoded = rle_encode_frame(arr) decoded = _rle_decode_frame( encoded, ds.Rows, ds.Columns, ds.SamplesPerPixel, ds.BitsAllocated ) ds.PlanarConfiguration = 1 arr = np.frombuffer(decoded, '<u2') arr = reshape_pixel_array(ds, arr) assert np.array_equal(ref, arr)
def test_32bit_1sample(self): """Test decoding 32-bit, 1 sample/pixel.""" header = ( b'\x04\x00\x00\x00' # 4 segments b'\x40\x00\x00\x00' # 64 offset b'\x47\x00\x00\x00' # 71 offset b'\x4E\x00\x00\x00' # 78 offset b'\x55\x00\x00\x00' # 85 offset ) header += (64 - len(header)) * b'\x00' # 2 x 3 data data = ( # 0, 16777216, 65536, 256, 4294967295 b'\x05\x00\x01\x00\x00\x00\xFF' # MSB b'\x05\x00\x00\x01\x00\x00\xFF' b'\x05\x00\x00\x00\x01\x00\xFF' b'\x05\x00\x00\x00\x00\x01\xFF' # LSB ) decoded = _rle_decode_frame(header + data, 2, 3, 1, 32) arr = np.frombuffer(decoded, np.dtype('>u4')) assert [0, 16777216, 65536, 256, 1, 4294967295] == arr.tolist()
def test_8bit_3sample(self): """Test decoding 8-bit, 3 sample/pixel.""" header = ( b'\x03\x00\x00\x00' # 3 segments b'\x40\x00\x00\x00' # 64 b'\x47\x00\x00\x00' # 71 b'\x4E\x00\x00\x00' # 78 ) header += (64 - len(header)) * b'\x00' # 2 x 3 data # 0, 64, 128, 160, 192, 255 data = ( b'\x05\x00\x40\x80\xA0\xC0\xFF' # R b'\x05\xFF\xC0\x80\x40\x00\xFF' # B b'\x05\x01\x40\x80\xA0\xC0\xFE' # G ) decoded = _rle_decode_frame(header + data, 2, 3, 3, 8) arr = np.frombuffer(decoded, np.dtype('>u1')) # Ordered all R, all G, all B assert [0, 64, 128, 160, 192, 255] == arr[:6].tolist() assert [255, 192, 128, 64, 0, 255] == arr[6:12].tolist() assert [1, 64, 128, 160, 192, 254] == arr[12:].tolist()
def test_32bit_3sample(self): """Test decoding 32-bit, 3 sample/pixel.""" header = ( b'\x0C\x00\x00\x00' # 12 segments b'\x40\x00\x00\x00' # 64 b'\x47\x00\x00\x00' # 71 b'\x4E\x00\x00\x00' # 78 b'\x55\x00\x00\x00' # 85 b'\x5C\x00\x00\x00' # 92 b'\x63\x00\x00\x00' # 99 b'\x6A\x00\x00\x00' # 106 b'\x71\x00\x00\x00' # 113 b'\x78\x00\x00\x00' # 120 b'\x7F\x00\x00\x00' # 127 b'\x86\x00\x00\x00' # 134 b'\x8D\x00\x00\x00' # 141 ) header += (64 - len(header)) * b'\x00' # 2 x 3 data data = ( # 0, 16777216, 65536, 256, 4294967295 b'\x05\x00\x01\x00\x00\x00\xFF' # MSB b'\x05\x00\x00\x01\x00\x00\xFF' b'\x05\x00\x00\x00\x01\x00\xFF' b'\x05\x00\x00\x00\x00\x01\xFF' # LSB b'\x05\xFF\x01\x00\x00\x00\x00' # MSB b'\x05\xFF\x00\x01\x00\x00\x00' b'\x05\xFF\x00\x00\x01\x00\x00' b'\x05\xFF\x00\x00\x00\x01\x00' # LSB b'\x05\x00\x01\x00\x00\x00\xFF' # MSB b'\x05\x00\x00\x01\x00\x00\xFF' b'\x05\x00\x00\x00\x01\x00\xFF' b'\x05\x01\x00\x00\x00\x01\xFE' # LSB ) decoded = _rle_decode_frame(header + data, 2, 3, 3, 32) arr = np.frombuffer(decoded, np.dtype('>u4')) assert [0, 16777216, 65536, 256, 1, 4294967295] == arr[:6].tolist() assert [4294967295, 16777216, 65536, 256, 1, 0] == arr[6:12].tolist() assert [1, 16777216, 65536, 256, 1, 4294967294] == arr[12:].tolist()
def test_unsupported_bits_allocated_raises(self): """Test exception raised for BitsAllocated not a multiple of 8.""" with pytest.raises(NotImplementedError, match='multiple of bytes'): _rle_decode_frame(b'\x00\x00\x00\x00', 1, 1, 1, 12)