예제 #1
0
    def testImplVRLittleEndianUndefLength(self):
        """Raw read: Impl VR Little Endian with undefined length................"""
        # (7fe0,0010), OB, 2-byte reserved, 4-byte-length (UNDEFINED)
        hexstr1 = "e0 7f 10 00 ff ff ff ff"
        hexstr2 = " 41 42 43 44 45 46 47 48 49 4a"  # 'content'
        hexstr3 = " fe ff dd e0 00 00 00 00"          # Sequence Delimiter
        hexstr = hexstr1 + hexstr2 + hexstr3
        infile = BytesIO(hex2bytes(hexstr))
        expected = ((0x7fe0, 0x10), 'OB or OW', 0xffffffff, b'ABCDEFGHIJ', 0x8, True, True)
        de_gen = data_element_generator(infile, is_implicit_VR=True, is_little_endian=True)
        got = next(de_gen)
        msg_loc = "in read of undefined length Implicit VR ='OB' short value)"
        self.assertEqual(got, expected, "Expected: %r, got %r in %s" % (expected, got, msg_loc))

        # Test again such that delimiter crosses default 128-byte read "chunks", etc
        for multiplier in (116, 117, 118, 120):
            multiplier = 116
            hexstr2b = hexstr2 + " 00" * multiplier
            hexstr = hexstr1 + hexstr2b + hexstr3
            infile = BytesIO(hex2bytes(hexstr))
            expected = len('ABCDEFGHIJ' + '\0' * multiplier)
            de_gen = data_element_generator(infile, is_implicit_VR=True, is_little_endian=True)
            got = next(de_gen)
            got_len = len(got.value)
            msg_loc = "in read of undefined length Implicit VR with 'multiplier' %d" % multiplier
            self.assertEqual(expected, got_len, "Expected value length %d, got %d in %s" % (expected, got_len, msg_loc))
            msg = "Unexpected value start with multiplier %d on Implicit VR undefined length" % multiplier
            self.assertTrue(got.value.startswith(b'ABCDEFGHIJ\0'), msg)
예제 #2
0
    def testImplVRLittleEndianUndefLength(self):
        """Raw read: Impl VR Little Endian with undefined length................"""
        # (7fe0,0010), OB, 2-byte reserved, 4-byte-length (UNDEFINED)
        hexstr1 = "e0 7f 10 00 ff ff ff ff"
        hexstr2 = " 41 42 43 44 45 46 47 48 49 4a"  # 'content'
        hexstr3 = " fe ff dd e0 00 00 00 00"          # Sequence Delimiter
        hexstr = hexstr1 + hexstr2 + hexstr3
        infile = BytesIO(hex2bytes(hexstr))
        expected = ((0x7fe0, 0x10), 'OW or OB', 0xffffffffL, b'ABCDEFGHIJ', 0x8, True, True)
        de_gen = data_element_generator(infile, is_implicit_VR=True, is_little_endian=True)
        got = next(de_gen)
        msg_loc = "in read of undefined length Implicit VR ='OB' short value)"
        self.assertEqual(got, expected, "Expected: %r, got %r in %s" % (expected, got, msg_loc))

        # Test again such that delimiter crosses default 128-byte read "chunks", etc
        for multiplier in (116, 117, 118, 120):
            multiplier = 116
            hexstr2b = hexstr2 + " 00" * multiplier
            hexstr = hexstr1 + hexstr2b + hexstr3
            infile = BytesIO(hex2bytes(hexstr))
            expected = len('ABCDEFGHIJ' + '\0' * multiplier)
            de_gen = data_element_generator(infile, is_implicit_VR=True, is_little_endian=True)
            got = next(de_gen)
            got_len = len(got.value)
            msg_loc = "in read of undefined length Implicit VR with 'multiplier' %d" % multiplier
            self.assertEqual(expected, got_len, "Expected value length %d, got %d in %s" % (expected, got_len, msg_loc))
            msg = "Unexpected value start with multiplier %d on Implicit VR undefined length" % multiplier
            self.assertTrue(got.value.startswith(b'ABCDEFGHIJ\0'), msg)
예제 #3
0
    def testEmptyItem(self):
        """Read sequence with a single empty item..............................."""
        # This is fix for issue 27
        hexstr = (
            "08 00 32 10"    # (0008, 1032) SQ "Procedure Code Sequence"
            " 08 00 00 00"    # length 8
            " fe ff 00 e0"    # (fffe, e000) Item Tag
            " 00 00 00 00"    # length = 0
        ) + (             # --------------- end of Sequence
            " 08 00 3e 10"    # (0008, 103e) LO "Series Description"  nopep8
            " 0c 00 00 00"    # length     nopep8
            " 52 20 41 44 44 20 56 49 45 57 53 20"  # value     nopep8
        )
        # "\x08\x00\x32\x10\x08\x00\x00\x00\xfe\xff\x00\xe0\x00\x00\x00\x00" # from issue 27, procedure code sequence (0008,1032)
        # hexstr += "\x08\x00\x3e\x10\x0c\x00\x00\x00\x52\x20\x41\x44\x44\x20\x56\x49\x45\x57\x53\x20" # data element following

        fp = BytesIO(hex2bytes(hexstr))
        gen = data_element_generator(fp, is_implicit_VR=True, is_little_endian=True)
        raw_seq = next(gen)
        seq = convert_value("SQ", raw_seq)

        self.assertTrue(isinstance(seq, Sequence), "Did not get Sequence, got type {0}".format(str(type(seq))))
        self.assertTrue(len(seq) == 1, "Expected Sequence with single (empty) item, got {0:d} item(s)".format(len(seq)))
        self.assertTrue(len(seq[0]) == 0, "Expected the sequence item (dataset) to be empty")
        elem2 = next(gen)
        self.assertEqual(elem2.tag, 0x0008103e, "Expected a data element after empty sequence item")
예제 #4
0
    def testEmptyItem(self):
        """Read sequence with a single empty item..............................."""
        # This is fix for issue 27
        hexstr = (
            "08 00 32 10"    # (0008, 1032) SQ "Procedure Code Sequence"
            " 08 00 00 00"    # length 8
            " fe ff 00 e0"    # (fffe, e000) Item Tag
            " 00 00 00 00"    # length = 0
        ) + (             # --------------- end of Sequence
            " 08 00 3e 10"    # (0008, 103e) LO "Series Description"  nopep8
            " 0c 00 00 00"    # length     nopep8
            " 52 20 41 44 44 20 56 49 45 57 53 20"  # value     nopep8
        )
        # "\x08\x00\x32\x10\x08\x00\x00\x00\xfe\xff\x00\xe0\x00\x00\x00\x00" # from issue 27, procedure code sequence (0008,1032)
        # hexstr += "\x08\x00\x3e\x10\x0c\x00\x00\x00\x52\x20\x41\x44\x44\x20\x56\x49\x45\x57\x53\x20" # data element following

        fp = BytesIO(hex2bytes(hexstr))
        gen = data_element_generator(fp, is_implicit_VR=True, is_little_endian=True)
        raw_seq = next(gen)
        seq = convert_value("SQ", raw_seq)

        self.assertTrue(isinstance(seq, Sequence), "Did not get Sequence, got type {0:s}".format(type(seq)))
        self.assertTrue(len(seq) == 1, "Expected Sequence with single (empty) item, got {0:d} item(s)".format(len(seq)))
        self.assertTrue(len(seq[0]) == 0, "Expected the sequence item (dataset) to be empty")
        elem2 = next(gen)
        self.assertEqual(elem2.tag, 0x0008103e, "Expected a data element after empty sequence item")
예제 #5
0
 def testExplVRLittleEndianLongLength(self):
     """Raw read: Explicit VR Little Endian long length......................"""
     # (0002,0001) OB 2-byte-reserved 4-byte-length, value 0x00 0x01
     infile = BytesIO(hex2bytes("02 00 01 00 4f 42 00 00 02 00 00 00 00 01"))
     expected = ((2, 1), 'OB', 2, b'\00\01', 0xc, False, True)
     de_gen = data_element_generator(infile, is_implicit_VR=False, is_little_endian=True)
     got = next(de_gen)
     msg_loc = "in read of Explicit VR='OB' data element (long length format)"
     self.assertEqual(got, expected, "Expected: %r, got %r in %s" % (expected, got, msg_loc))
예제 #6
0
 def testImplVRLittleEndian(self):
     """Raw read: Implicit VR Little Endian.................................."""
     # (0008,212a) {IS} 4-byte-length, value '1 '
     infile = BytesIO(hex2bytes("08 00 2a 21 02 00 00 00 31 20"))
     expected = ((8, 0x212a), None, 2, b'1 ', 0x8, True, True)
     de_gen = data_element_generator(infile, is_implicit_VR=True, is_little_endian=True)
     got = next(de_gen)
     msg_loc = "in read of Implicit VR='IS' data element (short length format)"
     self.assertEqual(got, expected, "Expected: %r, got %r in %s" % (expected, got, msg_loc))
예제 #7
0
 def testExplVRLittleEndianShortLength(self):
     """Raw read: Explicit VR Little Endian short length....................."""
     # (0008,212a) IS 2-byte-length, value '1 '
     infile = BytesIO(hex2bytes("08 00 2a 21 49 53 02 00 31 20"))
     expected = ((8, 0x212a), 'IS', 2, '1 ', 0x8, False, True)
     de_gen = data_element_generator(infile, is_implicit_VR=False, is_little_endian=True)
     got = next(de_gen)
     msg_loc = "in read of Explicit VR='IS' data element (short length format)"
     self.assertEqual(got, expected, "Expected: %r, got %r in %s" % (expected, got, msg_loc))
예제 #8
0
 def testExplVRLittleEndianLongLength(self):
     """Raw read: Explicit VR Little Endian long length......................"""
     # (0002,0001) OB 2-byte-reserved 4-byte-length, value 0x00 0x01
     infile = BytesIO(hex2bytes("02 00 01 00 4f 42 00 00 02 00 00 00 00 01"))
     expected = ((2, 1), 'OB', 2, b'\00\01', 0xc, False, True)
     de_gen = data_element_generator(infile, is_implicit_VR=False, is_little_endian=True)
     got = next(de_gen)
     msg_loc = "in read of Explicit VR='OB' data element (long length format)"
     self.assertEqual(got, expected, "Expected: %r, got %r in %s" % (expected, got, msg_loc))
예제 #9
0
 def testImplVRLittleEndian(self):
     """Raw read: Implicit VR Little Endian.................................."""
     # (0008,212a) {IS} 4-byte-length, value '1 '
     infile = BytesIO(hex2bytes("08 00 2a 21 02 00 00 00 31 20"))
     expected = ((8, 0x212a), None, 2, b'1 ', 0x8, True, True)
     de_gen = data_element_generator(infile, is_implicit_VR=True, is_little_endian=True)
     got = next(de_gen)
     msg_loc = "in read of Implicit VR='IS' data element (short length format)"
     self.assertEqual(got, expected, "Expected: %r, got %r in %s" % (expected, got, msg_loc))
예제 #10
0
 def testExplVRLittleEndianShortLength(self):
     """Raw read: Explicit VR Little Endian short length....................."""
     # (0008,212a) IS 2-byte-length, value '1 '
     infile = BytesIO(hex2bytes("08 00 2a 21 49 53 02 00 31 20"))
     # XXX Assumes that a RawDataElement doesn't convert the value based
     # upon the VR value, thus it will remain a byte string since that is
     # the input
     expected = ((8, 0x212a), 'IS', 2, b'1 ', 0x8, False, True)
     de_gen = data_element_generator(infile, is_implicit_VR=False, is_little_endian=True)
     got = next(de_gen)
     msg_loc = "in read of Explicit VR='IS' data element (short length format)"
     self.assertEqual(got, expected, "Expected: %r, got %r in %s" % (expected, got, msg_loc))
예제 #11
0
 def testExplVRLittleEndianShortLength(self):
     """Raw read: Explicit VR Little Endian short length....................."""
     # (0008,212a) IS 2-byte-length, value '1 '
     infile = BytesIO(hex2bytes("08 00 2a 21 49 53 02 00 31 20"))
     # XXX Assumes that a RawDataElement doesn't convert the value based
     # upon the VR value, thus it will remain a byte string since that is
     # the input
     expected = ((8, 0x212a), 'IS', 2, b'1 ', 0x8, False, True)
     de_gen = data_element_generator(infile, is_implicit_VR=False, is_little_endian=True)
     got = next(de_gen)
     msg_loc = "in read of Explicit VR='IS' data element (short length format)"
     self.assertEqual(got, expected, "Expected: %r, got %r in %s" % (expected, got, msg_loc))
예제 #12
0
    def testExplVRBigEndian_UndefinedLengthSeq(self):
        """Raw read: ExplVR BigEndian Undefined Length SQ......................."""
        # Create a fictional sequence with bytes directly,
        #    similar to PS 3.5-2008 Table 7.5-2 p42
        item1_value_bytes = "\1" * 126
        item2_value_bytes = "\2" * 222
        hexstr = (
            "30 0a 00 B0"  # (300a, 00b0) Beam Sequence
            " 53 51"  # SQ
            " 00 00"  # reserved
            " ff ff ff ff"  # undefined length
            " ff fe e0 00"  # (fffe, e000) Item Tag
            " 00 00 00 18"  # Item (dataset) Length
            " 30 0a 00 c0"  # (300A, 00C0) Beam Number
            " 49 53"  # IS
            " 00 02"  # length
            " 31 20"  # value '1 '
            " 30 0a 00 c2"  # (300A, 00C2) Beam Name
            " 4c 4F"  # LO
            " 00 06"  # length
            " 42 65 61 6d 20 31"  # value 'Beam 1'
            # -------------
            " ff fe e0 00"  # (fffe, e000) Item Tag
            " 00 00 00 18"  # Item (dataset) Length
            " 30 0a 00 c0"  # (300A, 00C0) Beam Number
            " 49 53"  # IS
            " 00 02"  # length
            " 32 20"  # value '2 '
            " 30 0a 00 c2"  # (300A, 00C2) Beam Name
            " 4C 4F"  # LO
            " 00 06"  # length
            " 42 65 61 6d 20 32"  # value 'Beam 2'
            " ff fe E0 dd"  # SQ delimiter
            " 00 00 00 00"  # zero length
        )

        infile = BytesIO(hex2bytes(hexstr))
        de_gen = data_element_generator(infile,
                                        is_implicit_VR=False,
                                        is_little_endian=False)
        seq = next(de_gen)
        # Note seq itself is not a raw data element.
        #     The parser does parse undefined length SQ

        # The sequence is parsed, but only into raw data elements.
        # They will be converted when asked for. Check some:
        got = seq[0].BeamNumber
        self.assertTrue(got == 1,
                        "Expected Beam Number 1, got {0!r}".format(got))
        got = seq[1].BeamName
        self.assertTrue(got == 'Beam 2',
                        "Expected Beam Name 'Beam 2', got {0:s}".format(got))
예제 #13
0
 def test_empty_AT(self):
     """Write empty AT correctly.........."""
     # Was issue 74
     data_elem = DataElement(0x00280009, "AT", [])
     expected = hex2bytes((
         " 28 00 09 00"  # (0028,0009) Frame Increment Pointer
         " 00 00 00 00"  # length 0
     ))
     write_data_element(self.f1, data_elem)
     got = self.f1.parent.getvalue()
     msg = ("Did not write zero-length AT value correctly. "
            "Expected %r, got %r") % (bytes2hex(expected), bytes2hex(got))
     msg = "%r %r" % (type(expected), type(got))
     msg = "'%r' '%r'" % (expected, got)
     self.assertEqual(expected, got, msg)
예제 #14
0
 def test_empty_AT(self):
     """Write empty AT correctly.........."""
     # Was issue 74
     data_elem = DataElement(0x00280009, "AT", [])
     expected = hex2bytes((
         " 28 00 09 00"   # (0028,0009) Frame Increment Pointer
         " 00 00 00 00"   # length 0
         ))
     write_data_element(self.f1, data_elem)
     got = self.f1.parent.getvalue()
     msg = ("Did not write zero-length AT value correctly. "
         "Expected %r, got %r") % (bytes2hex(expected), bytes2hex(got))
     msg = "%r %r" % (type(expected), type(got))
     msg = "'%r' '%r'" % (expected, got)
     self.assertEqual(expected, got, msg)
예제 #15
0
    def testExplVRBigEndian_UndefinedLengthSeq(self):
        """Raw read: ExplVR BigEndian Undefined Length SQ......................."""
        # Create a fictional sequence with bytes directly,
        #    similar to PS 3.5-2008 Table 7.5-2 p42
        item1_value_bytes = "\1" * 126
        item2_value_bytes = "\2" * 222
        hexstr = (
            "30 0a 00 B0"    # (300a, 00b0) Beam Sequence
            " 53 51"         # SQ
            " 00 00"         # reserved
            " ff ff ff ff"    # undefined length
                " ff fe e0 00"    # (fffe, e000) Item Tag
                " 00 00 00 18"    # Item (dataset) Length
                " 30 0a 00 c0"    # (300A, 00C0) Beam Number
                " 49 53"          # IS
                " 00 02"          # length
                " 31 20"          # value '1 '
                " 30 0a 00 c2"    # (300A, 00C2) Beam Name
                " 4c 4F"          # LO
                " 00 06"          # length
                " 42 65 61 6d 20 31"  # value 'Beam 1'
                # -------------
                " ff fe e0 00"    # (fffe, e000) Item Tag
                " 00 00 00 18"    # Item (dataset) Length
                " 30 0a 00 c0"    # (300A, 00C0) Beam Number
                " 49 53"          # IS
                " 00 02"          # length
                " 32 20"          # value '2 '
                " 30 0a 00 c2"    # (300A, 00C2) Beam Name
                " 4C 4F"          # LO
                " 00 06"          # length
                " 42 65 61 6d 20 32"  # value 'Beam 2'
            " ff fe E0 dd"    # SQ delimiter
            " 00 00 00 00"    # zero length
                )

        infile = BytesIO(hex2bytes(hexstr))
        de_gen = data_element_generator(infile, is_implicit_VR=False, is_little_endian=False)
        seq = next(de_gen)
        # Note seq itself is not a raw data element.
        #     The parser does parse undefined length SQ

        # The sequence is parsed, but only into raw data elements.
        # They will be converted when asked for. Check some:
        got = seq[0].BeamNumber
        self.assertTrue(got == 1, "Expected Beam Number 1, got {0!r}".format(got))
        got = seq[1].BeamName
        self.assertTrue(got == 'Beam 2', "Expected Beam Name 'Beam 2', got {0:s}".format(got))
예제 #16
0
 def compare_write(self, hex_std, file_ds):
     """Write file and compare with expected byte string
     
     :arg hex_std: the bytes which should be written, as space separated hex 
     :arg file_ds: a FileDataset instance containing the dataset to write
     """
     out_filename = "scratch.dcm"
     write_file(out_filename, file_ds)
     std = hex2bytes(hex_std)
     bytes_written = open(out_filename,'rb').read()
     # print "std    :", bytes2hex(std)
     # print "written:", bytes2hex(bytes_written)
     same, pos = bytes_identical(std, bytes_written)
     self.assert_(same, "Writing from scratch not expected result - first difference at 0x%x" % pos)
     if os.path.exists(out_filename):
         os.remove(out_filename)  # get rid of the file
예제 #17
0
    def compare_write(self, hex_std, file_ds):
        """Write file and compare with expected byte string

        :arg hex_std: the bytes which should be written, as space separated hex
        :arg file_ds: a FileDataset instance containing the dataset to write
        """
        out_filename = "scratch.dcm"
        file_ds.save_as(out_filename)
        std = hex2bytes(hex_std)
        bytes_written = open(out_filename, 'rb').read()
        # print "std    :", bytes2hex(std)
        # print "written:", bytes2hex(bytes_written)
        same, pos = bytes_identical(std, bytes_written)
        self.assertTrue(same,
            "Writing from scratch unexpected result - 1st diff at 0x%x" % pos)
        if os.path.exists(out_filename):
            os.remove(out_filename)  # get rid of the file
예제 #18
0
    def testImplVRBigEndian_ExplicitLengthSeq(self):
        """Raw read: ImplVR BigEndian SQ with explicit lengths.................."""
        # Create a fictional sequence with bytes directly,
        #    similar to PS 3.5-2008 Table 7.5-1 p42
        hexstr = (
            "30 0a 00 B0"  # (300a, 00b0) Beam Sequence
            " 00 00 00 40"  # length
            " ff fe e0 00"  # (fffe, e000) Item Tag
            " 00 00 00 18"  # Item (dataset) Length
            " 30 0a 00 c0"  # (300A, 00C0) Beam Number
            " 00 00 00 02"  # length
            " 31 20"  # value '1 '
            " 30 0a 00 c2"  # (300A, 00C2) Beam Name
            " 00 00 00 06"  # length
            " 42 65 61 6d 20 31"  # value 'Beam 1'
            # -------------
            " ff fe e0 00"  # (fffe, e000) Item Tag
            " 00 00 00 18"  # Item (dataset) Length
            " 30 0a 00 c0"  # (300A, 00C0) Beam Number
            " 00 00 00 02"  # length
            " 32 20"  # value '2 '
            " 30 0a 00 c2"  # (300A, 00C2) Beam Name
            " 00 00 00 06"  # length
            " 42 65 61 6d 20 32"  # value 'Beam 2'
        )

        infile = BytesIO(hex2bytes(hexstr))
        de_gen = data_element_generator(infile,
                                        is_implicit_VR=True,
                                        is_little_endian=False)
        raw_seq = next(de_gen)
        seq = convert_value("SQ", raw_seq)

        # The sequence is parsed, but only into raw data elements.
        # They will be converted when asked for. Check some:
        got = seq[0].BeamNumber
        self.assertTrue(got == 1,
                        "Expected Beam Number 1, got {0!r}".format(got))
        got = seq[1].BeamName
        self.assertTrue(got == 'Beam 2',
                        "Expected Beam Name 'Beam 2', got {0:s}".format(got))
예제 #19
0
    def testImplVRBigEndian_ExplicitLengthSeq(self):
        """Raw read: ImplVR BigEndian SQ with explicit lengths.................."""
        # Create a fictional sequence with bytes directly,
        #    similar to PS 3.5-2008 Table 7.5-1 p42
        hexstr = (
            "30 0a 00 B0"    # (300a, 00b0) Beam Sequence
            " 00 00 00 40"    # length
            " ff fe e0 00"    # (fffe, e000) Item Tag
            " 00 00 00 18"    # Item (dataset) Length
            " 30 0a 00 c0"    # (300A, 00C0) Beam Number
            " 00 00 00 02"    # length
            " 31 20"          # value '1 '
            " 30 0a 00 c2"    # (300A, 00C2) Beam Name
            " 00 00 00 06"    # length
            " 42 65 61 6d 20 31"  # value 'Beam 1'
            # -------------
            " ff fe e0 00"    # (fffe, e000) Item Tag
            " 00 00 00 18"    # Item (dataset) Length
            " 30 0a 00 c0"    # (300A, 00C0) Beam Number
            " 00 00 00 02"    # length
            " 32 20"          # value '2 '
            " 30 0a 00 c2"    # (300A, 00C2) Beam Name
            " 00 00 00 06"    # length
            " 42 65 61 6d 20 32"  # value 'Beam 2'
        )

        infile = BytesIO(hex2bytes(hexstr))
        de_gen = data_element_generator(infile, is_implicit_VR=True, is_little_endian=False)
        raw_seq = next(de_gen)
        seq = convert_value("SQ", raw_seq)

        # The sequence is parsed, but only into raw data elements.
        # They will be converted when asked for. Check some:
        got = seq[0].BeamNumber
        self.assertTrue(got == 1, "Expected Beam Number 1, got {0!r}".format(got))
        got = seq[1].BeamName
        self.assertTrue(got == 'Beam 2', "Expected Beam Name 'Beam 2', got {0:s}".format(got))