def read(self, stream: Stream, version): if version in (3, 4, 5): self.picture = stream.read_object('picture') elif version in (7, 8): _ = stream.read_ushort('pic version?') _ = stream.read_uint('picture type?') self.picture = stream.read_object('picture') elif version == 9: self.picture = Picture.create_from_stream(stream) if version < 4: _ = stream.read_object() if version <= 8: _ = stream.read_object() self.color_foreground = stream.read_object('color 1') self.color_background = stream.read_object('color 2') if version >= 9: self.color_transparent = stream.read_object('color 3') self.angle = stream.read_double('angle') self.size = stream.read_double('size') self.x_offset = stream.read_double('x offset') self.y_offset = stream.read_double('y offset') self.x_scale = stream.read_double('x scale') self.y_scale = stream.read_double('y scale') self.symbol_level = SymbolLayer.read_symbol_level(stream) self.swap_fb_gb = bool(stream.read_uchar('swap fgbg')) self.rotate_with_transform = stream.read_ushort( 'rotate with transform') != 0 if version < 5: return stream.read_int('unknown', expected=0) stream.read_ushort('unknown', expected=0) if version == 7: return if 5 < version <= 8: size = stream.read_int('unknown size') stream.read(size)
def read(self, stream: Stream, version): version = binascii.hexlify(stream.read(1)) if version != b'01': raise UnsupportedVersionException( 'Unsupported Font version {}'.format(version)) self.charset = stream.read_ushort('charset') # Not exposed in ArcMap front end: attributes = stream.read_uchar('attributes') self.italic = bool(attributes & self.Italic) self.underline = bool(attributes & self.Underline) self.strikethrough = bool(attributes & self.Strikethrough) self.weight = stream.read_ushort('weight') # From https://docs.microsoft.com/en-us/windows/desktop/api/olectl/ns-olectl-tagfontdesc # Use the int64 member of the CY structure and scale your font size (in points) by 10000. self.size = stream.read_int('font size') / 10000 name_length = stream.read_uchar('font name size') self.font_name = stream.read(name_length).decode( Font.CHARSET_MAP[self.charset])
def read(self, stream: Stream, version): if version <= 4: self.picture = stream.read_object('picture') elif version == 7: _ = stream.read_ushort('pic version?') _ = stream.read_uint('picture type?') self.picture = stream.read_object('picture') elif version == 8: self.picture = Picture.create_from_stream(stream) self.color_background = stream.read_object('color bg') self.color_foreground = stream.read_object('color fg') self.color_transparent = stream.read_object('color trans') # either an entire LineSymbol or just a LineSymbolLayer self.outline = stream.read_object('outline') self.angle = stream.read_double('angle') self.scale_x = stream.read_double('scale_x') self.scale_y = stream.read_double('scale_y') self.offset_x = stream.read_double('offset x') self.offset_y = stream.read_double('offset y') self.separation_x = stream.read_double('separation x') self.separation_y = stream.read_double('separation y') stream.read(16) self.symbol_level = SymbolLayer.read_symbol_level(stream) self.swap_fb_gb = bool(stream.read_uchar('swap fgbg')) if version < 4: return stream.read(6) if 4 < version < 8: stream.read(4)
def read(self, stream: Stream, version): size = stream.read_int('size') # TODO - reverse engineer stream.read(size) return
def read_from_stream(self, stream: Stream): """ Reads a picture object from a stream """ size = stream.read_uint('Pixmap size') check = stream.read(2) if check == b'BM': # BMP file # next bit should be size again size2 = struct.unpack("<I", stream.read(4))[0] if size != size2: raise UnreadablePictureException( 'Bitmap size {} did not match size in header {}'.format( size, size2)) self.format = BmpPicture.FORMAT_BMP stream.rewind(6) return stream.read(size) elif check == b'\x01\x00': # EMF file stream.rewind(2) self.format = BmpPicture.FORMAT_EMF return stream.read(size) elif check == b'\xff\xd8': # JPG file check = stream.read(1) assert check == b'\xff' stream.rewind(3) self.format = BmpPicture.FORMAT_JPG return stream.read(size) elif check == b'\x89\x50': # PNG file start = stream.tell() - 2 if stream.read(6) != b'\x4e\x47\x0d\x0a\x1a\x0a': # where is 0d? raise UnreadablePictureException('Corrupt PNG header') first = True while True: chunk_size = struct.unpack(">I", stream.read(4))[0] chunk_type = stream.read(4) if first: if not chunk_type == b'IHDR': raise UnreadablePictureException( 'Missing PNG IHDR chunk') first = False stream.read(chunk_size) stream.read(4) # CRC if chunk_type == b'IEND': break found_size = stream.tell() - start if size != found_size: raise UnreadablePictureException( 'PNG size {} did not match size in header {}'.format( found_size, size)) self.format = BmpPicture.FORMAT_PNG stream.seek(start) return stream.read(found_size) else: stream.rewind(2) raise UnreadablePictureException( 'Expected 424d (\'BM\'), got {}'.format(check))
def read(self, stream: Stream, version): size = stream.read_int('size') # TODO - reverse engineer stream.read(size) self.crs = stream.read_object('crs')