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
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." )
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.')
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