Esempio n. 1
0
def test_read_bitshort():
    bs = BitStream(b"\xe0")
    assert bs.read_bit_short() == 256  # 11
    assert bs.read_bit_short() == 0  # 10
    bs = BitStream(b"\x00\xff\xff")
    bs.read_bits(6)
    assert bs.read_bit_short() == -1
    assert BitStream(b"\x7f\x00").read_bit_short() == 252
Esempio n. 2
0
    def load_classes(self) -> Iterable[Tuple[int, DXFClass]]:
        sentinel = self.data[:SENTINEL_SIZE]
        if (
            sentinel
            != b"\x8D\xA1\xC4\xB8\xC4\xA9\xF8\xC5\xC0\xDC\xF4\x5F\xE7\xCF\xB6\x8A"
        ):
            raise DwgCorruptedClassesSection(
                "Sentinel for start of CLASSES section not found."
            )
        start_index = SENTINEL_SIZE
        bs = BitStream(
            self.data[start_index:],
            dxfversion=self.specs.version,
            encoding=self.specs.encoding,
        )
        class_data_size = bs.read_unsigned_long()  # data size in bytes
        end_sentinel_index = SENTINEL_SIZE + 6 + class_data_size
        end_index = end_sentinel_index - 2
        end_bit_index = (3 + class_data_size) << 3

        while bs.bit_index < end_bit_index:
            class_num = bs.read_bit_short()
            dxfattribs = {
                "flags": bs.read_bit_short(),  # version?
                "app_name": bs.read_text(),
                "cpp_class_name": bs.read_text(),
                "name": bs.read_text(),
                "was_a_proxy": bs.read_bit(),
                "is_an_entity": int(bs.read_bit_short() == 0x1F2),
            }
            yield class_num, DXFClass.new(dxfattribs=dxfattribs)

        if self.crc_check and False:
            check = struct.unpack_from("<H", self.data, end_index)[0]
            # TODO: classes crc check
            # Which data should be checked? This is not correct:
            crc = crc8(self.data[start_index:end_index])
            if check != crc:
                raise CRCError("CRC error in classes section.")
        sentinel = self.data[
            end_sentinel_index : end_sentinel_index + SENTINEL_SIZE
        ]
        if (
            sentinel
            != b"\x72\x5E\x3B\x47\x3B\x56\x07\x3A\x3F\x23\x0B\xA0\x18\x30\x49\x75"
        ):
            raise DwgCorruptedClassesSection(
                "Sentinel for end of CLASSES section not found."
            )
Esempio n. 3
0
    def classes_R2000(self) -> None:
        seeker, section_size = self.specs.sections[CLASSES_ID]
        sentinel = self.data[seeker:seeker + SENTINEL_SIZE]
        if sentinel != b'\x8D\xA1\xC4\xB8\xC4\xA9\xF8\xC5\xC0\xDC\xF4\x5F\xE7\xCF\xB6\x8A':
            raise DwgCorruptedClassesSection(
                'Sentinel for start of section not found.')

        cls_tag = DXFTag(0, 'CLASS')
        classes = self.sections['CLASSES']
        bs = BitStream(
            self.data[seeker + SENTINEL_SIZE:seeker + section_size],
            dxfversion=self.specs.version,
            encoding=self.specs.encoding,
        )
        class_data_size = bs.read_unsigned_long()  # data size in bytes
        end_index = (3 + class_data_size) << 3

        while bs.bit_index < end_index:
            class_num = bs.read_bit_short()
            flags = bs.read_bit_short()  # version?
            app_name = bs.read_text()
            cpp_class_name = bs.read_text()
            class_dxf_name = bs.read_text()
            was_a_zombie = bs.read_bit()
            item_class_id = bs.read_bit_short()
            # print((class_num, flags, app_name, class_dxf_name, cpp_class_name, was_a_zombie, item_class_id))
            classes.append(
                Tags([
                    cls_tag,
                    DXFTag(1, class_dxf_name),
                    DXFTag(2, cpp_class_name),
                    DXFTag(3, app_name),
                    DXFTag(90, flags),
                    DXFTag(280, was_a_zombie),
                    DXFTag(281, 1 if item_class_id == 0x1f2 else 0)
                ]))
            self.dxf_object_types[class_num] = class_dxf_name

        # Ignore crc for the sake of speed.
        # _index = index + (20 + class_data_size)
        # crc = struct.unpack_from('<h', self.data, index)
        _index = seeker + (SENTINEL_SIZE + 6 + class_data_size)
        sentinel = self.data[_index:_index + SENTINEL_SIZE]
        if sentinel != b'\x72\x5E\x3B\x47\x3B\x56\x07\x3A\x3F\x23\x0B\xA0\x18\x30\x49\x75':
            raise DwgCorruptedClassesSection(
                'Sentinel for end of section not found.')
Esempio n. 4
0
    def lwpolyline(self, data: bytes):
        # OpenDesign Specs LWPLINE: 20.4.85 Page 211
        logger.warning(
            'Untested proxy graphic entity: LWPOLYLINE - Need examples!')
        bs = BitStream(data)
        flag = bs.read_bit_short()
        attribs = self._build_dxf_attribs()
        if flag & 4:
            attribs['const_width'] = bs.read_bit_double()
        if flag & 8:
            attribs['elevation'] = bs.read_bit_double()
        if flag & 2:
            attribs['thickness'] = bs.read_bit_double()
        if flag & 1:
            attribs['extrusion'] = Vec3(bs.read_bit_double(3))

        num_points = bs.read_bit_long()
        if flag & 16:
            num_bulges = bs.read_bit_long()
        else:
            num_bulges = 0

        if self.dxfversion >= 'AC1024':  # R2010+
            vertex_id_count = bs.read_bit_long()
        else:
            vertex_id_count = 0

        if flag & 32:
            num_width = bs.read_bit_long()
        else:
            num_width = 0
        # ignore DXF R13/14 special vertex order

        vertices = [bs.read_raw_double(2)]
        prev_point = vertices[-1]
        for _ in range(num_points - 1):
            x = bs.read_bit_double_default(default=prev_point[0])
            y = bs.read_bit_double_default(default=prev_point[1])
            prev_point = (x, y)
            vertices.append(prev_point)
        bulges = [bs.read_bit_double() for _ in range(num_bulges)]
        vertex_ids = [bs.read_bit_long() for _ in range(vertex_id_count)]
        widths = [(bs.read_bit_double(), bs.read_bit_double())
                  for _ in range(num_width)]
        if len(bulges) == 0:
            bulges = list(repeat(0, num_points))
        if len(widths) == 0:
            widths = list(repeat((0, 0), num_points))
        points = []
        for v, w, b in zip(vertices, widths, bulges):
            points.append((v[0], v[1], w[0], w[1], b))
        lwpolyline = cast('LWPolyline',
                          self._factory('LWPOLYLINE', dxfattribs=attribs))
        lwpolyline.set_points(points)
        return lwpolyline