Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Luiz Phelipe Steinbach

Arquivo .PAK descompressão

Recommended Posts

Olá gente, preciso de uma ajuda enorme, tenho um jogo no PC, e já consegui fazer a Extração dos arquivos de Audio .PAK, (Sound1.pak), só que agora preciso fazer a extração dos arquivos de imagem, (imagefile1.pak), só que parece que está em outra compressão, mesmo sendo um .PAK, pelo que disseram em um fórum gringo, é que as imagens estão em uma compressão chamada LZ77, e o cara até postou o Algoritmo da compressão e acho que é em C++, alguém saberia como extrair? Por algum programa universal? Por alguma forma? E como fazer? Desde já agradeço e muito!
O Algoritmo de Compressão C++
template <typename Callback>
void compressed_block_iterate(const uint8_t *source_data, uint64_t source_size, Callback callback)
{
    uint64_t position = 0xc;
    while (position < source_size)
    {
        uint32_t compressed_size = *reinterpret_cast<const uint32_t*>(source_data + position);
        position += sizeof(uint32_t);
        uint32_t uncompressed_size = *reinterpret_cast<const uint32_t*> (source_data + position);
        position += sizeof(uint32_t);
        const uint8_t *block_data = source_data + position;
        position += compressed_size;
        if (position >= source_size)
            break;
        position = (position + 3) & ~3; //make alignment
        callback(block_data, compressed_size, uncompressed_size);
    }
}

uint64_t calculate_uncompressed_size(const uint8_t *source_data, uint64_t source_size)
{
    uint64_t result = 0;
    compressed_block_iterate(source_data, source_size, [&](const uint8_t *block_data, uint64_t compressed_size, uint64_t uncompressed_size)
    {
        result += uncompressed_size;
    });
    return result;
}
void decompress_block(const uint8_t *source_data, uint64_t source_size,
    uint8_t *destination_data, uint64_t destination_size)
{
    uint64_t source_position = 0;
    uint64_t destination_position = 0;

    while (source_position < source_size)
    {
        uint8_t comp_byte = source_data[source_position++];
        uint32_t data_length = (comp_byte >> 4) & 0xf;
        uint32_t repeat_count = (comp_byte & 0xf);

        if (data_length == 0x0f)
        {
            while (true)
            {
                uint8_t data_length_byte = source_data[source_position++];
                data_length += data_length_byte;
                if (data_length_byte != 0xff)
                    break;
            }
        }

        while (data_length--)
        {
            destination_data[destination_position++] = source_data[source_position++];
        }

        if (source_position >= source_size)
        {
            break;
        }

        uint32_t repeat_offset = *reinterpret_cast<const uint16_t*>(source_data + source_position);
        source_position += sizeof(uint16_t);

        uint64_t global_repeat_offset = destination_position - repeat_offset;

        if (repeat_count == 0x0f)
        {
            while (true)
            {
                uint8_t repeat_count_byte = source_data[source_position++];
                repeat_count += repeat_count_byte;
                if (repeat_count_byte != 0xff)
                    break;
            }
        }
        for (uint32_t i = 0; i < repeat_count + 4; i++)
        {
            destination_data[destination_position++] = destination_data[global_repeat_offset + i];
        }
    }
}
std::unique_ptr<uint8_t[]> decompress_data(const uint8_t *source_data,
    uint64_t source_size, uint64_t &result_size)
{
    result_size = calculate_uncompressed_size(source_data, source_size);
    std::unique_ptr<uint8_t[]> result_data = std::make_unique<uint8_t[]>(result_size);
    uint64_t destination_position = 0;

    compressed_block_iterate(source_data, source_size, [&](const uint8_t *block_data, uint64_t compressed_size, uint64_t uncompressed_size)
    {
        decompress_block(block_data, compressed_size,
            result_data.get() + destination_position, uncompressed_size);
        destination_position += uncompressed_size;
    });
    return result_data;
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.