示例#1
0
    def compress(self, data, signature: int, file_version: int = None) -> bytes:
        uncompressed_size = len(data)

        if file_version is None:
            file_version = 3 if zstandard and not (Signatures.SCLZ & signature) else 1

        if Signatures.ZSTD & signature and not zstandard or \
           Signatures.SCLZ & signature and not lzham:
            signature = Signatures.SC

        super().__init__('little')
        if signature is Signatures.NONE:
            return data
        elif ((Signatures.LZMA | Signatures.SIG) & signature) or (Signatures.SC & signature and file_version != 3):
            compressed = lzma.compress(data, format=lzma.FORMAT_ALONE, filters=self.lzma_filters)

            self.write(compressed[:5])

            self.writeInt32(uncompressed_size)

            self.write(compressed[13:])

            compressed = self.buffer
        elif (Signatures.SCLZ & signature) and lzham:
            compressed = lzham.compress(data, filters=self.lzham_filters)

            self.write(b'SCLZ')
            self.writeUByte(self.lzham_filters['dict_size_log2'])
            self.writeInt32(uncompressed_size)
            self.write(compressed)

            compressed = self.buffer
        elif (Signatures.SC | Signatures.ZSTD) & signature and file_version == 3:
            compressor = zstandard.ZstdCompressor()
            compressed = compressor.compress(data)
        else:
            raise TypeError('Unknown Signature!')

        super().__init__('big')
        if (Signatures.SC | Signatures.SCLZ) & signature:
            data_hash = md5(data).digest()

            self.write(b'SC')
            self.writeInt32(file_version)
            if file_version == 4:
                self.writeInt32(1)
            self.writeInt32(len(data_hash))
            self.write(data_hash)
            compressed = self.buffer + compressed
        elif signature == Signatures.SIG:
            self.write(b'Sig:')
            self.write(b'\x00' * 64)  # sha64
            compressed = self.buffer + compressed

        return compressed
示例#2
0
    def compress_data(self):
        if self.settings['use_lzma']:
            print('[*] Compressing texture with lzma')

            filters = [
                       {
                        "id": lzma.FILTER_LZMA1,
                        "dict_size": 256 * 1024,
                        "lc": 3,
                        "lp": 0,
                        "pb": 2,
                        "mode": lzma.MODE_NORMAL
                        },
                       ]

            compressed = lzma.compress(self.buffer, format=lzma.FORMAT_ALONE, filters=filters)
            compressed = compressed[0:5] + len(self.buffer).to_bytes(4, 'little') + compressed[13:]

        elif self.settings['use_lzham']:
            print('[*] Compressing texture with lzham')

            dict_size = 18

            compressed = lzham.compress(self.buffer, {'dict_size_log2': dict_size})
            compressed = 'SCLZ'.encode('utf-8') + dict_size.to_bytes(1, 'big') + len(self.buffer).to_bytes(4, 'little') + compressed

        else:
            print('[*] Compressing texture with zstandard')
            compressed = zstandard.compress(self.buffer, level=zstandard.MAX_COMPRESSION_LEVEL)

        fileMD5 = hashlib.md5(self.buffer).digest()

        # Flush the previous buffer
        self.buffer = b''

        if self.settings['header']:
            self.write('SC'.encode('utf-8'))

            if self.settings['use_zstd']:
                self.write_uint32(3, 'big')

            else:
                self.write_uint32(1, 'big')

            self.write_uint32(len(fileMD5), 'big')
            self.write(fileMD5)

            print('[*] Header wrote !')

        self.write(compressed)

        print('[*] Compression done !')
示例#3
0
def compileSC(_dir, from_memory=[], imgdata=None, folder_export=None):
    name = _dir.split('/')[-2]
    if from_memory:
        files = from_memory
    else:
        files = []
        [
            files.append(i) if i.endswith(".png") else None
            for i in os.listdir(_dir)
        ]
        files.sort()
        if not files:
            return info(string.dir_empty % _dir.split('/')[-2])
        files = [Image.open(f'{_dir}{i}') for i in files]

    exe = False
    info(string.collecting_inf)
    sc = io.BytesIO()

    if from_memory:
        uselzham = imgdata['uselzham']
    else:
        try:
            scdata = open(f"{_dir}{name}.xcod", "rb")
            scdata.read(4)
            uselzham, = struct.unpack("?", scdata.read(1))
            scdata.read(1)
            hasxcod = True
        except:
            info(string.not_xcod)
            info(string.standart_types)
            hasxcod = False
            uselzham = False

    if uselzham:
        try:
            import lzham
        except:
            if not isWin:
                return info(string.not_installed2 % 'LZHAM')
            exe = True
    else:
        try:
            import lzma
        except:
            if not isWin:
                return info(string.not_installed2 % 'LZMA')
            exe = True

    for picCount in range(len(files)):
        print()
        img = files[picCount]

        if from_memory:
            fileType = imgdata['data'][picCount]['fileType']
            subType = imgdata['data'][picCount]['subType']
        else:
            if hasxcod:
                fileType, subType, width, height = struct.unpack(
                    ">BBHH", scdata.read(6))

                if (width, height) != img.size:
                    info(string.illegal_size %
                         (width, height, img.width, img.height))
                    if question(string.resize_qu):
                        info(string.resizing)
                        img = img.resize((width, height), Image.ANTIALIAS)
            else:
                fileType, subType = 1, 0

        width, height = img.size
        pixelSize = pixelsize(subType)
        img = img.convert(format(subType))

        fileSize = width * height * pixelSize + 5

        info(string.about_sc % (name + '_' * picCount, fileType, fileSize,
                                subType, width, height))

        sc.write(
            struct.pack("<BIBHH", fileType, fileSize, subType, width, height))

        if fileType in (27, 28):
            split_image(img)
            print()

        rgba2bytes(sc, img, subType)
        print()

    sc.write(bytes(5))
    sc = sc.getvalue()
    print()
    with open(f"{folder_export}{name}.sc", "wb") as fout:
        fout.write(
            struct.pack(">2sII16s", b'SC', 1, 16,
                        hashlib.md5(sc).digest()))
        info(string.header_done)
        if uselzham:
            info(string.comp_with % 'LZHAM')
            fout.write(struct.pack("<4sBI", b'SCLZ', 18, len(sc)))
            if exe:
                with open('temp.sc', 'wb') as s:
                    s.write(sc)
                if os.system(f'{lzham_path} -d18 -c c temp.sc _temp.sc{nul}'):
                    raise Exception(string.comp_err)
                with open('_temp.sc', 'rb') as s:
                    s.read(13)
                    compressed = s.read()
                [os.remove(i) for i in ('temp.sc', '_temp.sc')]

            else:
                compressed = lzham.compress(sc, {"dict_size_log2": 18})

            fout.write(compressed)
        else:
            info(string.comp_with % 'LZMA')
            l = struct.pack("<I", len(sc))
            sc = lzma.compress(sc,
                               format=lzma.FORMAT_ALONE,
                               filters=[{
                                   "id": lzma.FILTER_LZMA1,
                                   "dict_size": 0x40000,
                                   "lc": 3,
                                   "lp": 0,
                                   "pb": 2,
                                   "mode": lzma.MODE_NORMAL
                               }])
            fout.write(sc[:5] + l + sc[13:])
        info(string.comp_done)
        print()