Skip to content

Commit a9bb303

Browse files
committed
WIP2
1 parent 9d644aa commit a9bb303

File tree

3 files changed

+203
-85
lines changed

3 files changed

+203
-85
lines changed

rle/tests/test_decode.py

Lines changed: 112 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,19 @@ def as_bytes(self, offsets):
6969

7070
def test_bits_allocated_zero_raises(self):
7171
"""Test exception raised for BitsAllocated 0."""
72-
msg = r"The \(0028,0100\) 'Bits Allocated' value must be 8, 16, 32 or 64"
72+
msg = r"The \(0028,0100\) 'Bits Allocated' value must be 1, 8, 16, 32 or 64"
7373
with pytest.raises(ValueError, match=msg):
7474
decode_frame(b"\x00\x00\x00\x00", 1, 0, "<")
7575

7676
def test_bits_allocated_not_octal_raises(self):
77-
"""Test exception raised for BitsAllocated not a multiple of 8."""
78-
msg = r"The \(0028,0100\) 'Bits Allocated' value must be 8, 16, 32 or 64"
77+
"""Test exception raised for BitsAllocated not 1 or a multiple of 8."""
78+
msg = r"The \(0028,0100\) 'Bits Allocated' value must be 1, 8, 16, 32 or 64"
7979
with pytest.raises(ValueError, match=msg):
8080
decode_frame(b"\x00\x00\x00\x00", 1, 12, "<")
8181

8282
def test_bits_allocated_large_raises(self):
8383
"""Test exception raised for BitsAllocated greater than 64."""
84-
msg = r"The \(0028,0100\) 'Bits Allocated' value must be 8, 16, 32 or 64"
84+
msg = r"The \(0028,0100\) 'Bits Allocated' value must be 1, 8, 16, 32 or 64"
8585
with pytest.raises(ValueError, match=msg):
8686
decode_frame(b"\x00\x00\x00\x00", 1, 72, "<")
8787

@@ -357,6 +357,114 @@ def test_u32_3s(self):
357357
assert [4294967295, 16777216, 65536, 256, 1, 0] == arr[6:12].tolist()
358358
assert [1, 16777216, 65536, 256, 1, 4294967294] == arr[12:].tolist()
359359

360+
def test_u8_1s_bs1(self):
361+
"""Test decoding bit packed 1 sample/px."""
362+
header = b"\x01\x00\x00\x00\x40\x00\x00\x00"
363+
header += (64 - len(header)) * b"\x00"
364+
# 0, 64, 128, 160, 192, 255
365+
data = b"\x05\x00\x40\x80\xA0\xC0\xFF"
366+
# Big endian
367+
# 48 px - byte aligned in 6 bytes
368+
decoded = decode_frame(header + data, 6 * 8, 1, ">")
369+
arr = np.frombuffer(decoded, np.dtype("uint8"))
370+
assert [0, 64, 128, 160, 192, 255] == arr.tolist()
371+
372+
# 37 px -> 5 bytes
373+
decoded = decode_frame(header + data, 4 * 8 + 5, 1, ">")
374+
arr = np.frombuffer(decoded, np.dtype("uint8"))
375+
assert [0, 64, 128, 160, 192] == arr.tolist()
376+
377+
# 2 px -> 1 byte
378+
decoded = decode_frame(header + data, 2, 1, ">")
379+
arr = np.frombuffer(decoded, np.dtype("uint8"))
380+
assert [0] == arr.tolist()
381+
382+
# Little-endian
383+
decoded = decode_frame(header + data, 6 * 8, 1, "<")
384+
arr = np.frombuffer(decoded, np.dtype("uint8"))
385+
assert [0, 64, 128, 160, 192, 255] == arr.tolist()
386+
387+
decoded = decode_frame(header + data, 4 * 8 + 5, 1, "<")
388+
arr = np.frombuffer(decoded, np.dtype("uint8"))
389+
assert [0, 64, 128, 160, 192] == arr.tolist()
390+
391+
decoded = decode_frame(header + data, 2, 1, "<")
392+
arr = np.frombuffer(decoded, np.dtype("uint8"))
393+
assert [0] == arr.tolist()
394+
395+
def test_u8_3s_bs1(self):
396+
"""Test decoding bit packed 3 sample/px."""
397+
header = (
398+
b"\x03\x00\x00\x00" # 3 segments
399+
b"\x40\x00\x00\x00" # 64
400+
b"\x47\x00\x00\x00" # 71
401+
b"\x4E\x00\x00\x00" # 78
402+
)
403+
header += (64 - len(header)) * b"\x00"
404+
# 0, 64, 128, 160, 192, 255
405+
data = (
406+
b"\x05\x00\x40\x80\xA0\xC0\xFF" # R
407+
b"\x05\x7F\xC0\x80\x40\x00\xFF" # B
408+
b"\x05\x01\x40\x80\xA0\xC0\xFE" # G
409+
)
410+
# 48 px - byte aligned in 18 bytes
411+
decoded = decode_frame(header + data, 6 * 8, 1, "<")
412+
arr = np.frombuffer(decoded, np.dtype("uint8"))
413+
# Ordered all R, all G, all B
414+
assert [0, 64, 128, 160, 192, 255] == arr[:6].tolist()
415+
assert [127, 192, 128, 64, 0, 255] == arr[6:12].tolist()
416+
assert [1, 64, 128, 160, 192, 254] == arr[12:].tolist()
417+
418+
# 47 px - non-byte aligned in 18 bytes
419+
decoded = decode_frame(header + data, 6 * 8 - 1, 1, "<")
420+
arr = np.frombuffer(decoded, np.dtype("uint8"))
421+
# Boundaries are 47 | 94 | 141
422+
# v removed
423+
# 255 | 127: 0b[1111_111x 0b0]111_1111 -> 0b1111_1110
424+
assert [0, 64, 128, 160, 192, 254] == arr[:6].tolist()
425+
# Left shift values by 1 bit
426+
# 127 | 192: 0b0[111_1111 0b1]100_0000 -> 0b1111_1111
427+
# 192 | 128: 0b1[100_0000 0b1]000_0000 -> 0b1000_0001
428+
# 128 | 64: 0b1[000_0000 0b0]100_0000 -> 0b0000_0000
429+
# 64 | 0: 0b0[100_0000 0b0]000_0000 -> 0b1000_0000
430+
# 0 | 255: 0b0[000_0000 0b1]111_1111 -> 0b0000_0001
431+
# v removed
432+
# 255 | 1: 0b1[111_111x 0b00]00_0001 -> 0b1111_1100
433+
assert [255, 129, 0, 128, 1, 252] == arr[6:12].tolist()
434+
# Left shift values by 2 bits
435+
# 1 | 64: 0b00[00_0001 0b01]00_0000 -> 0b0000_0101
436+
# 64 | 128: 0b01[00_0000 0b10]00_0000 -> 0b0000_0010
437+
# 128 | 160: 0b10[00_0000 0b10]10_0000 -> 0b0000_0010
438+
# 160 | 192: 0b10[10_0000 0b11]00_0000 -> 0b1000_0011
439+
# 192 | 254: 0b11[00_0000 0b11]11_1110 -> 0b0000_0011
440+
# v removed
441+
# 254 | x: 0b11[11_111x -> 0b1111_1000
442+
assert [5, 2, 2, 131, 3, 248] == arr[12:].tolist()
443+
444+
# 41 px - non-byte aligned in 16 bytes
445+
decoded = decode_frame(header + data, 5 * 8 + 1, 1, "<")
446+
arr = np.frombuffer(decoded, np.dtype("uint8"))
447+
# Boundaries are 48 | 96 | 144 -> 41 | 82 | 123
448+
# vvv vvvv removed
449+
# 255 | 255: 0b[1xxx_xxxx 0b0111_111]1 -> 0b1011_1111
450+
assert [0, 64, 128, 160, 192, 191] == arr[:6].tolist()
451+
# Left shift values by 7 bits
452+
# 255 | 192: 0b1111_111[1 0b1100_000]0 -> 0b1110_0000
453+
# 192 | 128: 0b1100_000[0 0b1000_000]0 -> 0b0100_0000
454+
# 128 | 64: 0b1000_000[0 0b0100_000]0 -> 0b0010_0000
455+
# 64 | 0: 0b0100_000[0 0b0000_000]0 -> 0b0000_0000
456+
# vvv vvvv removed
457+
# 0 | 255 | 1: 0b0000_000[0 0b1xxx_xxxx 0b0000_00]01 -> 0b0100_0000
458+
assert [224, 64, 32, 0, 64] == arr[6:11].tolist()
459+
# Left shift values by 14 bits
460+
# 1 | 64: 0b0000_00[01 0b0100_00]00 -> 0b0101_0000
461+
# 64 | 128: 0b0100_00[00 0b1000_00]00 -> 0b0010_0000
462+
# 128 | 160: 0b1000_00[00 0b1010_00]00 -> 0b0010_1000
463+
# 160 | 192: 0b1010_00[00 0b1100_00]00 -> 0b0011_0000
464+
# vvv vvvv removed
465+
# 192 | 254: 0b1100_[00 0b1]xxx_xxxx -> 0b0010_0000
466+
assert [80, 32, 40, 48, 32] == arr[11:].tolist()
467+
360468

361469
@pytest.mark.skipif(not HAVE_PYDICOM, reason="No pydicom")
362470
class TestDecodeFrame_Datasets:

rle/tests/test_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ def test_bad_bits_allocated_raises(self):
199199
"byteorder": "<",
200200
}
201201

202-
msg = r"'bits_allocated' must be 8, 16, 32 or 64"
202+
msg = r"'bits_allocated' must be 1, 8, 16, 32 or 64"
203203
with pytest.raises(ValueError, match=msg):
204204
encode_pixel_data(b"", **kwargs)
205205

0 commit comments

Comments
 (0)