RVZ: Make m_rvz a template parameter

Needed for the next commit.
This commit is contained in:
JosJuice 2020-05-17 15:34:50 +02:00
parent ca4e4a6207
commit f2c38c0e67
6 changed files with 222 additions and 170 deletions

View File

@ -207,8 +207,9 @@ std::unique_ptr<BlobReader> CreateBlobReader(const std::string& filename)
case WBFS_MAGIC: case WBFS_MAGIC:
return WbfsFileReader::Create(std::move(file), filename); return WbfsFileReader::Create(std::move(file), filename);
case WIA_MAGIC: case WIA_MAGIC:
case RVZ_MAGIC:
return WIAFileReader::Create(std::move(file), filename); return WIAFileReader::Create(std::move(file), filename);
case RVZ_MAGIC:
return RVZFileReader::Create(std::move(file), filename);
default: default:
if (auto directory_blob = DirectoryBlobReader::Create(filename)) if (auto directory_blob = DirectoryBlobReader::Create(filename))
return std::move(directory_blob); return std::move(directory_blob);

View File

@ -25,7 +25,7 @@
namespace DiscIO namespace DiscIO
{ {
enum class WIACompressionType : u32; enum class WIARVZCompressionType : u32;
// Increment CACHE_REVISION (GameFileCache.cpp) if the enum below is modified // Increment CACHE_REVISION (GameFileCache.cpp) if the enum below is modified
enum class BlobType enum class BlobType
@ -176,9 +176,9 @@ bool ConvertToGCZ(BlobReader* infile, const std::string& infile_path,
bool ConvertToPlain(BlobReader* infile, const std::string& infile_path, bool ConvertToPlain(BlobReader* infile, const std::string& infile_path,
const std::string& outfile_path, CompressCB callback = nullptr, const std::string& outfile_path, CompressCB callback = nullptr,
void* arg = nullptr); void* arg = nullptr);
bool ConvertToWIA(BlobReader* infile, const std::string& infile_path, bool ConvertToWIAOrRVZ(BlobReader* infile, const std::string& infile_path,
const std::string& outfile_path, bool rvz, WIACompressionType compression_type, const std::string& outfile_path, bool rvz,
int compression_level, int chunk_size, CompressCB callback = nullptr, WIARVZCompressionType compression_type, int compression_level,
void* arg = nullptr); int chunk_size, CompressCB callback = nullptr, void* arg = nullptr);
} // namespace DiscIO } // namespace DiscIO

View File

@ -42,15 +42,31 @@
namespace DiscIO namespace DiscIO
{ {
std::pair<int, int> GetAllowedCompressionLevels(WIACompressionType compression_type) static void PushBack(std::vector<u8>* vector, const u8* begin, const u8* end)
{
const size_t offset_in_vector = vector->size();
vector->resize(offset_in_vector + (end - begin));
std::copy(begin, end, vector->data() + offset_in_vector);
}
template <typename T>
static void PushBack(std::vector<u8>* vector, const T& x)
{
static_assert(std::is_trivially_copyable_v<T>);
const u8* x_ptr = reinterpret_cast<const u8*>(&x);
PushBack(vector, x_ptr, x_ptr + sizeof(T));
}
std::pair<int, int> GetAllowedCompressionLevels(WIARVZCompressionType compression_type)
{ {
switch (compression_type) switch (compression_type)
{ {
case WIACompressionType::Bzip2: case WIARVZCompressionType::Bzip2:
case WIACompressionType::LZMA: case WIARVZCompressionType::LZMA:
case WIACompressionType::LZMA2: case WIARVZCompressionType::LZMA2:
return {1, 9}; return {1, 9};
case WIACompressionType::Zstd: case WIARVZCompressionType::Zstd:
// The actual minimum level can be gotten by calling ZSTD_minCLevel(). However, returning that // The actual minimum level can be gotten by calling ZSTD_minCLevel(). However, returning that
// would make the UI rather weird, because it is a negative number with very large magnitude. // would make the UI rather weird, because it is a negative number with very large magnitude.
// Note: Level 0 is a special number which means "default level" (level 3 as of this writing). // Note: Level 0 is a special number which means "default level" (level 3 as of this writing).
@ -60,27 +76,28 @@ std::pair<int, int> GetAllowedCompressionLevels(WIACompressionType compression_t
} }
} }
WIAFileReader::WIAFileReader(File::IOFile file, const std::string& path) template <bool RVZ>
WIARVZFileReader<RVZ>::WIARVZFileReader(File::IOFile file, const std::string& path)
: m_file(std::move(file)), m_encryption_cache(this) : m_file(std::move(file)), m_encryption_cache(this)
{ {
m_valid = Initialize(path); m_valid = Initialize(path);
} }
WIAFileReader::~WIAFileReader() = default; template <bool RVZ>
WIARVZFileReader<RVZ>::~WIARVZFileReader() = default;
bool WIAFileReader::Initialize(const std::string& path) template <bool RVZ>
bool WIARVZFileReader<RVZ>::Initialize(const std::string& path)
{ {
if (!m_file.Seek(0, SEEK_SET) || !m_file.ReadArray(&m_header_1, 1)) if (!m_file.Seek(0, SEEK_SET) || !m_file.ReadArray(&m_header_1, 1))
return false; return false;
if (m_header_1.magic != WIA_MAGIC && m_header_1.magic != RVZ_MAGIC) if ((!RVZ && m_header_1.magic != WIA_MAGIC) || (RVZ && m_header_1.magic != RVZ_MAGIC))
return false; return false;
m_rvz = m_header_1.magic == RVZ_MAGIC; const u32 version = RVZ ? RVZ_VERSION : WIA_VERSION;
const u32 version = m_rvz ? RVZ_VERSION : WIA_VERSION;
const u32 version_read_compatible = const u32 version_read_compatible =
m_rvz ? RVZ_VERSION_READ_COMPATIBLE : WIA_VERSION_READ_COMPATIBLE; RVZ ? RVZ_VERSION_READ_COMPATIBLE : WIA_VERSION_READ_COMPATIBLE;
const u32 file_version = Common::swap32(m_header_1.version); const u32 file_version = Common::swap32(m_header_1.version);
const u32 file_version_compatible = Common::swap32(m_header_1.version_compatible); const u32 file_version_compatible = Common::swap32(m_header_1.version_compatible);
@ -128,16 +145,16 @@ bool WIAFileReader::Initialize(const std::string& path)
const u32 chunk_size = Common::swap32(m_header_2.chunk_size); const u32 chunk_size = Common::swap32(m_header_2.chunk_size);
const auto is_power_of_two = [](u32 x) { return (x & (x - 1)) == 0; }; const auto is_power_of_two = [](u32 x) { return (x & (x - 1)) == 0; };
if ((!m_rvz || chunk_size < VolumeWii::BLOCK_TOTAL_SIZE || !is_power_of_two(chunk_size)) && if ((!RVZ || chunk_size < VolumeWii::BLOCK_TOTAL_SIZE || !is_power_of_two(chunk_size)) &&
chunk_size % VolumeWii::GROUP_TOTAL_SIZE != 0) chunk_size % VolumeWii::GROUP_TOTAL_SIZE != 0)
{ {
return false; return false;
} }
const u32 compression_type = Common::swap32(m_header_2.compression_type); const u32 compression_type = Common::swap32(m_header_2.compression_type);
m_compression_type = static_cast<WIACompressionType>(compression_type); m_compression_type = static_cast<WIARVZCompressionType>(compression_type);
if (m_compression_type > (m_rvz ? WIACompressionType::Zstd : WIACompressionType::LZMA2) || if (m_compression_type > (RVZ ? WIARVZCompressionType::Zstd : WIARVZCompressionType::LZMA2) ||
(m_rvz && m_compression_type == WIACompressionType::Purge)) (RVZ && m_compression_type == WIARVZCompressionType::Purge))
{ {
ERROR_LOG(DISCIO, "Unsupported compression type %u in %s", compression_type, path.c_str()); ERROR_LOG(DISCIO, "Unsupported compression type %u in %s", compression_type, path.c_str());
return false; return false;
@ -221,7 +238,8 @@ bool WIAFileReader::Initialize(const std::string& path)
return true; return true;
} }
bool WIAFileReader::HasDataOverlap() const template <bool RVZ>
bool WIARVZFileReader<RVZ>::HasDataOverlap() const
{ {
for (size_t i = 0; i < m_partition_entries.size(); ++i) for (size_t i = 0; i < m_partition_entries.size(); ++i)
{ {
@ -256,18 +274,22 @@ bool WIAFileReader::HasDataOverlap() const
return false; return false;
} }
std::unique_ptr<WIAFileReader> WIAFileReader::Create(File::IOFile file, const std::string& path) template <bool RVZ>
std::unique_ptr<WIARVZFileReader<RVZ>> WIARVZFileReader<RVZ>::Create(File::IOFile file,
const std::string& path)
{ {
std::unique_ptr<WIAFileReader> blob(new WIAFileReader(std::move(file), path)); std::unique_ptr<WIARVZFileReader> blob(new WIARVZFileReader(std::move(file), path));
return blob->m_valid ? std::move(blob) : nullptr; return blob->m_valid ? std::move(blob) : nullptr;
} }
BlobType WIAFileReader::GetBlobType() const template <bool RVZ>
BlobType WIARVZFileReader<RVZ>::GetBlobType() const
{ {
return m_rvz ? BlobType::RVZ : BlobType::WIA; return RVZ ? BlobType::RVZ : BlobType::WIA;
} }
bool WIAFileReader::Read(u64 offset, u64 size, u8* out_ptr) template <bool RVZ>
bool WIARVZFileReader<RVZ>::Read(u64 offset, u64 size, u8* out_ptr)
{ {
if (offset + size > Common::swap64(m_header_1.iso_file_size)) if (offset + size > Common::swap64(m_header_1.iso_file_size))
return false; return false;
@ -368,12 +390,15 @@ bool WIAFileReader::Read(u64 offset, u64 size, u8* out_ptr)
return true; return true;
} }
bool WIAFileReader::SupportsReadWiiDecrypted() const template <bool RVZ>
bool WIARVZFileReader<RVZ>::SupportsReadWiiDecrypted() const
{ {
return !m_partition_entries.empty(); return !m_partition_entries.empty();
} }
bool WIAFileReader::ReadWiiDecrypted(u64 offset, u64 size, u8* out_ptr, u64 partition_data_offset) template <bool RVZ>
bool WIARVZFileReader<RVZ>::ReadWiiDecrypted(u64 offset, u64 size, u8* out_ptr,
u64 partition_data_offset)
{ {
const u64 chunk_size = Common::swap32(m_header_2.chunk_size) * VolumeWii::BLOCK_DATA_SIZE / const u64 chunk_size = Common::swap32(m_header_2.chunk_size) * VolumeWii::BLOCK_DATA_SIZE /
VolumeWii::BLOCK_TOTAL_SIZE; VolumeWii::BLOCK_TOTAL_SIZE;
@ -408,9 +433,11 @@ bool WIAFileReader::ReadWiiDecrypted(u64 offset, u64 size, u8* out_ptr, u64 part
return size == 0; return size == 0;
} }
bool WIAFileReader::ReadFromGroups(u64* offset, u64* size, u8** out_ptr, u64 chunk_size, template <bool RVZ>
u32 sector_size, u64 data_offset, u64 data_size, u32 group_index, bool WIARVZFileReader<RVZ>::ReadFromGroups(u64* offset, u64* size, u8** out_ptr, u64 chunk_size,
u32 number_of_groups, u32 exception_lists) u32 sector_size, u64 data_offset, u64 data_size,
u32 group_index, u32 number_of_groups,
u32 exception_lists)
{ {
if (data_offset + data_size <= *offset) if (data_offset + data_size <= *offset)
return true; return true;
@ -445,7 +472,7 @@ bool WIAFileReader::ReadFromGroups(u64* offset, u64* size, u8** out_ptr, u64 chu
{ {
const u64 group_offset_in_file = static_cast<u64>(Common::swap32(group.data_offset)) << 2; const u64 group_offset_in_file = static_cast<u64>(Common::swap32(group.data_offset)) << 2;
Chunk& chunk = ReadCompressedData(group_offset_in_file, group_data_size, chunk_size, Chunk& chunk = ReadCompressedData(group_offset_in_file, group_data_size, chunk_size,
exception_lists, m_rvz, group_offset_in_data); exception_lists, RVZ, group_offset_in_data);
if (!chunk.Read(offset_in_group, bytes_to_read, *out_ptr)) if (!chunk.Read(offset_in_group, bytes_to_read, *out_ptr))
{ {
m_cached_chunk_offset = std::numeric_limits<u64>::max(); // Invalidate the cache m_cached_chunk_offset = std::numeric_limits<u64>::max(); // Invalidate the cache
@ -471,9 +498,11 @@ bool WIAFileReader::ReadFromGroups(u64* offset, u64* size, u8** out_ptr, u64 chu
return true; return true;
} }
WIAFileReader::Chunk& WIAFileReader::ReadCompressedData(u64 offset_in_file, u64 compressed_size, template <bool RVZ>
u64 decompressed_size, u32 exception_lists, typename WIARVZFileReader<RVZ>::Chunk&
bool rvz_pack, u64 data_offset) WIARVZFileReader<RVZ>::ReadCompressedData(u64 offset_in_file, u64 compressed_size,
u64 decompressed_size, u32 exception_lists, bool rvz_pack,
u64 data_offset)
{ {
if (offset_in_file == m_cached_chunk_offset) if (offset_in_file == m_cached_chunk_offset)
return m_cached_chunk; return m_cached_chunk;
@ -481,29 +510,29 @@ WIAFileReader::Chunk& WIAFileReader::ReadCompressedData(u64 offset_in_file, u64
std::unique_ptr<Decompressor> decompressor; std::unique_ptr<Decompressor> decompressor;
switch (m_compression_type) switch (m_compression_type)
{ {
case WIACompressionType::None: case WIARVZCompressionType::None:
decompressor = std::make_unique<NoneDecompressor>(); decompressor = std::make_unique<NoneDecompressor>();
break; break;
case WIACompressionType::Purge: case WIARVZCompressionType::Purge:
decompressor = std::make_unique<PurgeDecompressor>(decompressed_size); decompressor = std::make_unique<PurgeDecompressor>(decompressed_size);
break; break;
case WIACompressionType::Bzip2: case WIARVZCompressionType::Bzip2:
decompressor = std::make_unique<Bzip2Decompressor>(); decompressor = std::make_unique<Bzip2Decompressor>();
break; break;
case WIACompressionType::LZMA: case WIARVZCompressionType::LZMA:
decompressor = std::make_unique<LZMADecompressor>(false, m_header_2.compressor_data, decompressor = std::make_unique<LZMADecompressor>(false, m_header_2.compressor_data,
m_header_2.compressor_data_size); m_header_2.compressor_data_size);
break; break;
case WIACompressionType::LZMA2: case WIARVZCompressionType::LZMA2:
decompressor = std::make_unique<LZMADecompressor>(true, m_header_2.compressor_data, decompressor = std::make_unique<LZMADecompressor>(true, m_header_2.compressor_data,
m_header_2.compressor_data_size); m_header_2.compressor_data_size);
break; break;
case WIACompressionType::Zstd: case WIARVZCompressionType::Zstd:
decompressor = std::make_unique<ZstdDecompressor>(); decompressor = std::make_unique<ZstdDecompressor>();
break; break;
} }
const bool compressed_exception_lists = m_compression_type > WIACompressionType::Purge; const bool compressed_exception_lists = m_compression_type > WIARVZCompressionType::Purge;
m_cached_chunk = m_cached_chunk =
Chunk(&m_file, offset_in_file, compressed_size, decompressed_size, exception_lists, Chunk(&m_file, offset_in_file, compressed_size, decompressed_size, exception_lists,
@ -512,7 +541,8 @@ WIAFileReader::Chunk& WIAFileReader::ReadCompressedData(u64 offset_in_file, u64
return m_cached_chunk; return m_cached_chunk;
} }
std::string WIAFileReader::VersionToString(u32 version) template <bool RVZ>
std::string WIARVZFileReader<RVZ>::VersionToString(u32 version)
{ {
const u8 a = version >> 24; const u8 a = version >> 24;
const u8 b = (version >> 16) & 0xff; const u8 b = (version >> 16) & 0xff;
@ -525,12 +555,14 @@ std::string WIAFileReader::VersionToString(u32 version)
return StringFromFormat("%u.%02x.%02x.beta%u", a, b, c, d); return StringFromFormat("%u.%02x.%02x.beta%u", a, b, c, d);
} }
WIAFileReader::Chunk::Chunk() = default; template <bool RVZ>
WIARVZFileReader<RVZ>::Chunk::Chunk() = default;
WIAFileReader::Chunk::Chunk(File::IOFile* file, u64 offset_in_file, u64 compressed_size, template <bool RVZ>
u64 decompressed_size, u32 exception_lists, WIARVZFileReader<RVZ>::Chunk::Chunk(File::IOFile* file, u64 offset_in_file, u64 compressed_size,
bool compressed_exception_lists, bool rvz_pack, u64 data_offset, u64 decompressed_size, u32 exception_lists,
std::unique_ptr<Decompressor> decompressor) bool compressed_exception_lists, bool rvz_pack, u64 data_offset,
std::unique_ptr<Decompressor> decompressor)
: m_file(file), m_offset_in_file(offset_in_file), m_exception_lists(exception_lists), : m_file(file), m_offset_in_file(offset_in_file), m_exception_lists(exception_lists),
m_compressed_exception_lists(compressed_exception_lists), m_rvz_pack(rvz_pack), m_compressed_exception_lists(compressed_exception_lists), m_rvz_pack(rvz_pack),
m_data_offset(data_offset), m_decompressor(std::move(decompressor)) m_data_offset(data_offset), m_decompressor(std::move(decompressor))
@ -547,7 +579,8 @@ WIAFileReader::Chunk::Chunk(File::IOFile* file, u64 offset_in_file, u64 compress
m_out.data.resize(decompressed_size + m_out_bytes_allocated_for_exceptions); m_out.data.resize(decompressed_size + m_out_bytes_allocated_for_exceptions);
} }
bool WIAFileReader::Chunk::Read(u64 offset, u64 size, u8* out_ptr) template <bool RVZ>
bool WIARVZFileReader<RVZ>::Chunk::Read(u64 offset, u64 size, u8* out_ptr)
{ {
if (!m_decompressor || !m_file || if (!m_decompressor || !m_file ||
offset + size > m_out.data.size() - m_out_bytes_allocated_for_exceptions) offset + size > m_out.data.size() - m_out_bytes_allocated_for_exceptions)
@ -655,7 +688,8 @@ bool WIAFileReader::Chunk::Read(u64 offset, u64 size, u8* out_ptr)
return true; return true;
} }
bool WIAFileReader::Chunk::Decompress() template <bool RVZ>
bool WIARVZFileReader<RVZ>::Chunk::Decompress()
{ {
if (m_rvz_pack && m_exception_lists == 0) if (m_rvz_pack && m_exception_lists == 0)
{ {
@ -675,8 +709,10 @@ bool WIAFileReader::Chunk::Decompress()
return m_decompressor->Decompress(m_in, &m_out, &m_in_bytes_read); return m_decompressor->Decompress(m_in, &m_out, &m_in_bytes_read);
} }
bool WIAFileReader::Chunk::HandleExceptions(const u8* data, size_t bytes_allocated, template <bool RVZ>
size_t bytes_written, size_t* bytes_used, bool align) bool WIARVZFileReader<RVZ>::Chunk::HandleExceptions(const u8* data, size_t bytes_allocated,
size_t bytes_written, size_t* bytes_used,
bool align)
{ {
while (m_exception_lists > 0) while (m_exception_lists > 0)
{ {
@ -709,8 +745,10 @@ bool WIAFileReader::Chunk::HandleExceptions(const u8* data, size_t bytes_allocat
return true; return true;
} }
void WIAFileReader::Chunk::GetHashExceptions(std::vector<HashExceptionEntry>* exception_list, template <bool RVZ>
u64 exception_list_index, u16 additional_offset) const void WIARVZFileReader<RVZ>::Chunk::GetHashExceptions(
std::vector<HashExceptionEntry>* exception_list, u64 exception_list_index,
u16 additional_offset) const
{ {
ASSERT(m_exception_lists == 0); ASSERT(m_exception_lists == 0);
@ -736,7 +774,8 @@ void WIAFileReader::Chunk::GetHashExceptions(std::vector<HashExceptionEntry>* ex
m_in_bytes_used_for_exceptions)); m_in_bytes_used_for_exceptions));
} }
bool WIAFileReader::ApplyHashExceptions( template <bool RVZ>
bool WIARVZFileReader<RVZ>::ApplyHashExceptions(
const std::vector<HashExceptionEntry>& exception_list, const std::vector<HashExceptionEntry>& exception_list,
VolumeWii::HashBlock hash_blocks[VolumeWii::BLOCKS_PER_GROUP]) VolumeWii::HashBlock hash_blocks[VolumeWii::BLOCKS_PER_GROUP])
{ {
@ -759,7 +798,8 @@ bool WIAFileReader::ApplyHashExceptions(
return true; return true;
} }
bool WIAFileReader::PadTo4(File::IOFile* file, u64* bytes_written) template <bool RVZ>
bool WIARVZFileReader<RVZ>::PadTo4(File::IOFile* file, u64* bytes_written)
{ {
constexpr u32 ZEROES = 0; constexpr u32 ZEROES = 0;
const u64 bytes_to_write = Common::AlignUp(*bytes_written, 4) - *bytes_written; const u64 bytes_to_write = Common::AlignUp(*bytes_written, 4) - *bytes_written;
@ -770,9 +810,10 @@ bool WIAFileReader::PadTo4(File::IOFile* file, u64* bytes_written)
return file->WriteBytes(&ZEROES, bytes_to_write); return file->WriteBytes(&ZEROES, bytes_to_write);
} }
void WIAFileReader::AddRawDataEntry(u64 offset, u64 size, int chunk_size, u32* total_groups, template <bool RVZ>
std::vector<RawDataEntry>* raw_data_entries, void WIARVZFileReader<RVZ>::AddRawDataEntry(u64 offset, u64 size, int chunk_size, u32* total_groups,
std::vector<DataEntry>* data_entries) std::vector<RawDataEntry>* raw_data_entries,
std::vector<DataEntry>* data_entries)
{ {
constexpr size_t SKIP_SIZE = sizeof(WIAHeader2::disc_header); constexpr size_t SKIP_SIZE = sizeof(WIAHeader2::disc_header);
const u64 skip = offset < SKIP_SIZE ? std::min(SKIP_SIZE - offset, size) : 0; const u64 skip = offset < SKIP_SIZE ? std::min(SKIP_SIZE - offset, size) : 0;
@ -792,7 +833,8 @@ void WIAFileReader::AddRawDataEntry(u64 offset, u64 size, int chunk_size, u32* t
Common::swap32(group_index), Common::swap32(groups)}); Common::swap32(group_index), Common::swap32(groups)});
} }
WIAFileReader::PartitionDataEntry WIAFileReader::CreatePartitionDataEntry( template <bool RVZ>
typename WIARVZFileReader<RVZ>::PartitionDataEntry WIARVZFileReader<RVZ>::CreatePartitionDataEntry(
u64 offset, u64 size, u32 index, int chunk_size, u32* total_groups, u64 offset, u64 size, u32 index, int chunk_size, u32* total_groups,
const std::vector<PartitionEntry>& partition_entries, std::vector<DataEntry>* data_entries) const std::vector<PartitionEntry>& partition_entries, std::vector<DataEntry>* data_entries)
{ {
@ -807,7 +849,8 @@ WIAFileReader::PartitionDataEntry WIAFileReader::CreatePartitionDataEntry(
Common::swap32(group_index), Common::swap32(groups)}; Common::swap32(group_index), Common::swap32(groups)};
} }
ConversionResultCode WIAFileReader::SetUpDataEntriesForWriting( template <bool RVZ>
ConversionResultCode WIARVZFileReader<RVZ>::SetUpDataEntriesForWriting(
const VolumeDisc* volume, int chunk_size, u64 iso_size, u32* total_groups, const VolumeDisc* volume, int chunk_size, u64 iso_size, u32* total_groups,
std::vector<PartitionEntry>* partition_entries, std::vector<RawDataEntry>* raw_data_entries, std::vector<PartitionEntry>* partition_entries, std::vector<RawDataEntry>* raw_data_entries,
std::vector<DataEntry>* data_entries, std::vector<const FileSystem*>* partition_file_systems) std::vector<DataEntry>* data_entries, std::vector<const FileSystem*>* partition_file_systems)
@ -924,8 +967,9 @@ ConversionResultCode WIAFileReader::SetUpDataEntriesForWriting(
return ConversionResultCode::Success; return ConversionResultCode::Success;
} }
std::optional<std::vector<u8>> WIAFileReader::Compress(Compressor* compressor, const u8* data, template <bool RVZ>
size_t size) std::optional<std::vector<u8>> WIARVZFileReader<RVZ>::Compress(Compressor* compressor,
const u8* data, size_t size)
{ {
if (compressor) if (compressor)
{ {
@ -939,23 +983,24 @@ std::optional<std::vector<u8>> WIAFileReader::Compress(Compressor* compressor, c
return std::vector<u8>(data, data + size); return std::vector<u8>(data, data + size);
} }
void WIAFileReader::SetUpCompressor(std::unique_ptr<Compressor>* compressor, template <bool RVZ>
WIACompressionType compression_type, int compression_level, void WIARVZFileReader<RVZ>::SetUpCompressor(std::unique_ptr<Compressor>* compressor,
WIAHeader2* header_2) WIARVZCompressionType compression_type,
int compression_level, WIAHeader2* header_2)
{ {
switch (compression_type) switch (compression_type)
{ {
case WIACompressionType::None: case WIARVZCompressionType::None:
*compressor = nullptr; *compressor = nullptr;
break; break;
case WIACompressionType::Purge: case WIARVZCompressionType::Purge:
*compressor = std::make_unique<PurgeCompressor>(); *compressor = std::make_unique<PurgeCompressor>();
break; break;
case WIACompressionType::Bzip2: case WIARVZCompressionType::Bzip2:
*compressor = std::make_unique<Bzip2Compressor>(compression_level); *compressor = std::make_unique<Bzip2Compressor>(compression_level);
break; break;
case WIACompressionType::LZMA: case WIARVZCompressionType::LZMA:
case WIACompressionType::LZMA2: case WIARVZCompressionType::LZMA2:
{ {
u8* compressor_data = nullptr; u8* compressor_data = nullptr;
u8* compressor_data_size = nullptr; u8* compressor_data_size = nullptr;
@ -966,19 +1011,21 @@ void WIAFileReader::SetUpCompressor(std::unique_ptr<Compressor>* compressor,
compressor_data_size = &header_2->compressor_data_size; compressor_data_size = &header_2->compressor_data_size;
} }
const bool lzma2 = compression_type == WIACompressionType::LZMA2; const bool lzma2 = compression_type == WIARVZCompressionType::LZMA2;
*compressor = std::make_unique<LZMACompressor>(lzma2, compression_level, compressor_data, *compressor = std::make_unique<LZMACompressor>(lzma2, compression_level, compressor_data,
compressor_data_size); compressor_data_size);
break; break;
} }
case WIACompressionType::Zstd: case WIARVZCompressionType::Zstd:
*compressor = std::make_unique<ZstdCompressor>(compression_level); *compressor = std::make_unique<ZstdCompressor>(compression_level);
break; break;
} }
} }
bool WIAFileReader::TryReuse(std::map<ReuseID, GroupEntry>* reusable_groups, template <bool RVZ>
std::mutex* reusable_groups_mutex, OutputParametersEntry* entry) bool WIARVZFileReader<RVZ>::TryReuse(std::map<ReuseID, GroupEntry>* reusable_groups,
std::mutex* reusable_groups_mutex,
OutputParametersEntry* entry)
{ {
if (entry->reused_group) if (entry->reused_group)
return true; return true;
@ -1020,9 +1067,10 @@ static bool AllSame(const u8* begin, const u8* end)
return AllAre(begin, end, *begin); return AllAre(begin, end, *begin);
}; };
void WIAFileReader::RVZPack(const u8* in, OutputParametersEntry* out, u64 bytes_per_chunk, template <typename OutputParametersEntry>
size_t chunks, u64 total_size, u64 data_offset, u64 in_offset, static void RVZPack(const u8* in, OutputParametersEntry* out, u64 bytes_per_chunk, size_t chunks,
bool allow_junk_reuse, bool compression, const FileSystem* file_system) u64 total_size, u64 data_offset, u64 in_offset, bool allow_junk_reuse,
bool compression, const FileSystem* file_system)
{ {
using Seed = std::array<u32, LaggedFibonacciGenerator::SEED_SIZE>; using Seed = std::array<u32, LaggedFibonacciGenerator::SEED_SIZE>;
struct JunkInfo struct JunkInfo
@ -1140,19 +1188,23 @@ void WIAFileReader::RVZPack(const u8* in, OutputParametersEntry* out, u64 bytes_
} }
} }
void WIAFileReader::RVZPack(const u8* in, OutputParametersEntry* out, u64 size, u64 data_offset, template <typename OutputParametersEntry>
bool allow_junk_reuse, bool compression, const FileSystem* file_system) static void RVZPack(const u8* in, OutputParametersEntry* out, u64 size, u64 data_offset,
bool allow_junk_reuse, bool compression, const FileSystem* file_system)
{ {
RVZPack(in, out, size, 1, size, data_offset, 0, allow_junk_reuse, compression, file_system); RVZPack(in, out, size, 1, size, data_offset, 0, allow_junk_reuse, compression, file_system);
} }
ConversionResult<WIAFileReader::OutputParameters> WIAFileReader::ProcessAndCompress( template <bool RVZ>
CompressThreadState* state, CompressParameters parameters, ConversionResult<typename WIARVZFileReader<RVZ>::OutputParameters>
const std::vector<PartitionEntry>& partition_entries, WIARVZFileReader<RVZ>::ProcessAndCompress(CompressThreadState* state, CompressParameters parameters,
const std::vector<DataEntry>& data_entries, const FileSystem* file_system, const std::vector<PartitionEntry>& partition_entries,
std::map<ReuseID, GroupEntry>* reusable_groups, std::mutex* reusable_groups_mutex, const std::vector<DataEntry>& data_entries,
u64 chunks_per_wii_group, u64 exception_lists_per_chunk, bool compressed_exception_lists, const FileSystem* file_system,
bool compression, bool rvz) std::map<ReuseID, GroupEntry>* reusable_groups,
std::mutex* reusable_groups_mutex,
u64 chunks_per_wii_group, u64 exception_lists_per_chunk,
bool compressed_exception_lists, bool compression)
{ {
std::vector<OutputParametersEntry> output_entries; std::vector<OutputParametersEntry> output_entries;
@ -1164,7 +1216,7 @@ ConversionResult<WIAFileReader::OutputParameters> WIAFileReader::ProcessAndCompr
if (AllSame(data)) if (AllSame(data))
entry.reuse_id = ReuseID{nullptr, data.size(), false, data.front()}; entry.reuse_id = ReuseID{nullptr, data.size(), false, data.front()};
if (rvz) if constexpr (RVZ)
{ {
RVZPack(data.data(), output_entries.data(), data.size(), parameters.data_offset, true, RVZPack(data.data(), output_entries.data(), data.size(), parameters.data_offset, true,
compression, file_system); compression, file_system);
@ -1315,9 +1367,9 @@ ConversionResult<WIAFileReader::OutputParameters> WIAFileReader::ProcessAndCompr
compare_hashes(offsetof(HashBlock, padding_2), sizeof(HashBlock::padding_2)); compare_hashes(offsetof(HashBlock, padding_2), sizeof(HashBlock::padding_2));
} }
static_assert(std::is_trivially_copyable_v<decltype( static_assert(std::is_trivially_copyable_v<typename decltype(
CompressThreadState::decryption_buffer)::value_type>); CompressThreadState::decryption_buffer)::value_type>);
if (rvz) if constexpr (RVZ)
{ {
// We must not store junk efficiently for chunks that may get reused at a position // We must not store junk efficiently for chunks that may get reused at a position
// which has a different value of data_offset % VolumeWii::BLOCK_TOTAL_SIZE // which has a different value of data_offset % VolumeWii::BLOCK_TOTAL_SIZE
@ -1471,11 +1523,12 @@ ConversionResult<WIAFileReader::OutputParameters> WIAFileReader::ProcessAndCompr
return OutputParameters{std::move(output_entries), parameters.bytes_read, parameters.group_index}; return OutputParameters{std::move(output_entries), parameters.bytes_read, parameters.group_index};
} }
ConversionResultCode WIAFileReader::Output(std::vector<OutputParametersEntry>* entries, template <bool RVZ>
File::IOFile* outfile, ConversionResultCode WIARVZFileReader<RVZ>::Output(std::vector<OutputParametersEntry>* entries,
std::map<ReuseID, GroupEntry>* reusable_groups, File::IOFile* outfile,
std::mutex* reusable_groups_mutex, std::map<ReuseID, GroupEntry>* reusable_groups,
GroupEntry* group_entry, u64* bytes_written) std::mutex* reusable_groups_mutex,
GroupEntry* group_entry, u64* bytes_written)
{ {
for (OutputParametersEntry& entry : *entries) for (OutputParametersEntry& entry : *entries)
{ {
@ -1518,9 +1571,10 @@ ConversionResultCode WIAFileReader::Output(std::vector<OutputParametersEntry>* e
return ConversionResultCode::Success; return ConversionResultCode::Success;
} }
ConversionResultCode WIAFileReader::RunCallback(size_t groups_written, u64 bytes_read, template <bool RVZ>
u64 bytes_written, u32 total_groups, u64 iso_size, ConversionResultCode
CompressCB callback, void* arg) WIARVZFileReader<RVZ>::RunCallback(size_t groups_written, u64 bytes_read, u64 bytes_written,
u32 total_groups, u64 iso_size, CompressCB callback, void* arg)
{ {
int ratio = 0; int ratio = 0;
if (bytes_read != 0) if (bytes_read != 0)
@ -1536,8 +1590,9 @@ ConversionResultCode WIAFileReader::RunCallback(size_t groups_written, u64 bytes
ConversionResultCode::Canceled; ConversionResultCode::Canceled;
} }
bool WIAFileReader::WriteHeader(File::IOFile* file, const u8* data, size_t size, u64 upper_bound, template <bool RVZ>
u64* bytes_written, u64* offset_out) bool WIARVZFileReader<RVZ>::WriteHeader(File::IOFile* file, const u8* data, size_t size,
u64 upper_bound, u64* bytes_written, u64* offset_out)
{ {
// The first part of the check is to prevent this from running more than once. If *bytes_written // The first part of the check is to prevent this from running more than once. If *bytes_written
// is past the upper bound, we are already at the end of the file, so we don't need to do anything // is past the upper bound, we are already at the end of the file, so we don't need to do anything
@ -1556,10 +1611,12 @@ bool WIAFileReader::WriteHeader(File::IOFile* file, const u8* data, size_t size,
return PadTo4(file, bytes_written); return PadTo4(file, bytes_written);
} }
template <bool RVZ>
ConversionResultCode ConversionResultCode
WIAFileReader::ConvertToWIA(BlobReader* infile, const VolumeDisc* infile_volume, WIARVZFileReader<RVZ>::Convert(BlobReader* infile, const VolumeDisc* infile_volume,
File::IOFile* outfile, bool rvz, WIACompressionType compression_type, File::IOFile* outfile, WIARVZCompressionType compression_type,
int compression_level, int chunk_size, CompressCB callback, void* arg) int compression_level, int chunk_size, CompressCB callback,
void* arg)
{ {
ASSERT(infile->IsDataSizeAccurate()); ASSERT(infile->IsDataSizeAccurate());
ASSERT(chunk_size > 0); ASSERT(chunk_size > 0);
@ -1567,7 +1624,7 @@ WIAFileReader::ConvertToWIA(BlobReader* infile, const VolumeDisc* infile_volume,
const u64 iso_size = infile->GetDataSize(); const u64 iso_size = infile->GetDataSize();
const u64 chunks_per_wii_group = std::max<u64>(1, VolumeWii::GROUP_TOTAL_SIZE / chunk_size); const u64 chunks_per_wii_group = std::max<u64>(1, VolumeWii::GROUP_TOTAL_SIZE / chunk_size);
const u64 exception_lists_per_chunk = std::max<u64>(1, chunk_size / VolumeWii::GROUP_TOTAL_SIZE); const u64 exception_lists_per_chunk = std::max<u64>(1, chunk_size / VolumeWii::GROUP_TOTAL_SIZE);
const bool compressed_exception_lists = compression_type > WIACompressionType::Purge; const bool compressed_exception_lists = compression_type > WIARVZCompressionType::Purge;
u64 bytes_read = 0; u64 bytes_read = 0;
u64 bytes_written = 0; u64 bytes_written = 0;
@ -1631,12 +1688,12 @@ WIAFileReader::ConvertToWIA(BlobReader* infile, const VolumeDisc* infile_volume,
partition_file_systems[data_entry.index] : partition_file_systems[data_entry.index] :
non_partition_file_system; non_partition_file_system;
const bool compression = compression_type != WIACompressionType::None; const bool compression = compression_type != WIARVZCompressionType::None;
return ProcessAndCompress(state, std::move(parameters), partition_entries, data_entries, return ProcessAndCompress(state, std::move(parameters), partition_entries, data_entries,
file_system, &reusable_groups, &reusable_groups_mutex, file_system, &reusable_groups, &reusable_groups_mutex,
chunks_per_wii_group, exception_lists_per_chunk, chunks_per_wii_group, exception_lists_per_chunk,
compressed_exception_lists, compression, rvz); compressed_exception_lists, compression);
}; };
const auto output = [&](OutputParameters parameters) { const auto output = [&](OutputParameters parameters) {
@ -1820,10 +1877,10 @@ WIAFileReader::ConvertToWIA(BlobReader* infile, const VolumeDisc* infile_volume,
header_2.group_entries_offset = Common::swap64(group_entries_offset); header_2.group_entries_offset = Common::swap64(group_entries_offset);
header_2.group_entries_size = Common::swap32(static_cast<u32>(compressed_group_entries->size())); header_2.group_entries_size = Common::swap32(static_cast<u32>(compressed_group_entries->size()));
header_1.magic = rvz ? RVZ_MAGIC : WIA_MAGIC; header_1.magic = RVZ ? RVZ_MAGIC : WIA_MAGIC;
header_1.version = Common::swap32(rvz ? RVZ_VERSION : WIA_VERSION); header_1.version = Common::swap32(RVZ ? RVZ_VERSION : WIA_VERSION);
header_1.version_compatible = header_1.version_compatible =
Common::swap32(rvz ? RVZ_VERSION_WRITE_COMPATIBLE : WIA_VERSION_WRITE_COMPATIBLE); Common::swap32(RVZ ? RVZ_VERSION_WRITE_COMPATIBLE : WIA_VERSION_WRITE_COMPATIBLE);
header_1.header_2_size = Common::swap32(sizeof(WIAHeader2)); header_1.header_2_size = Common::swap32(sizeof(WIAHeader2));
mbedtls_sha1_ret(reinterpret_cast<const u8*>(&header_2), sizeof(header_2), mbedtls_sha1_ret(reinterpret_cast<const u8*>(&header_2), sizeof(header_2),
header_1.header_2_hash.data()); header_1.header_2_hash.data());
@ -1843,9 +1900,10 @@ WIAFileReader::ConvertToWIA(BlobReader* infile, const VolumeDisc* infile_volume,
return ConversionResultCode::Success; return ConversionResultCode::Success;
} }
bool ConvertToWIA(BlobReader* infile, const std::string& infile_path, bool ConvertToWIAOrRVZ(BlobReader* infile, const std::string& infile_path,
const std::string& outfile_path, bool rvz, WIACompressionType compression_type, const std::string& outfile_path, bool rvz,
int compression_level, int chunk_size, CompressCB callback, void* arg) WIARVZCompressionType compression_type, int compression_level,
int chunk_size, CompressCB callback, void* arg)
{ {
File::IOFile outfile(outfile_path, "wb"); File::IOFile outfile(outfile_path, "wb");
if (!outfile) if (!outfile)
@ -1859,9 +1917,10 @@ bool ConvertToWIA(BlobReader* infile, const std::string& infile_path,
std::unique_ptr<VolumeDisc> infile_volume = CreateDisc(infile_path); std::unique_ptr<VolumeDisc> infile_volume = CreateDisc(infile_path);
const auto convert = rvz ? RVZFileReader::Convert : WIAFileReader::Convert;
const ConversionResultCode result = const ConversionResultCode result =
WIAFileReader::ConvertToWIA(infile, infile_volume.get(), &outfile, rvz, compression_type, convert(infile, infile_volume.get(), &outfile, compression_type, compression_level,
compression_level, chunk_size, callback, arg); chunk_size, callback, arg);
if (result == ConversionResultCode::ReadFailed) if (result == ConversionResultCode::ReadFailed)
PanicAlertT("Failed to read from the input file \"%s\".", infile_path.c_str()); PanicAlertT("Failed to read from the input file \"%s\".", infile_path.c_str());
@ -1883,4 +1942,7 @@ bool ConvertToWIA(BlobReader* infile, const std::string& infile_path,
return result == ConversionResultCode::Success; return result == ConversionResultCode::Success;
} }
template class WIARVZFileReader<false>;
template class WIARVZFileReader<true>;
} // namespace DiscIO } // namespace DiscIO

View File

@ -25,7 +25,7 @@ namespace DiscIO
class FileSystem; class FileSystem;
class VolumeDisc; class VolumeDisc;
enum class WIACompressionType : u32 enum class WIARVZCompressionType : u32
{ {
None = 0, None = 0,
Purge = 1, Purge = 1,
@ -35,17 +35,18 @@ enum class WIACompressionType : u32
Zstd = 5, Zstd = 5,
}; };
std::pair<int, int> GetAllowedCompressionLevels(WIACompressionType compression_type); std::pair<int, int> GetAllowedCompressionLevels(WIARVZCompressionType compression_type);
constexpr u32 WIA_MAGIC = 0x01414957; // "WIA\x1" (byteswapped to little endian) constexpr u32 WIA_MAGIC = 0x01414957; // "WIA\x1" (byteswapped to little endian)
constexpr u32 RVZ_MAGIC = 0x015A5652; // "RVZ\x1" (byteswapped to little endian) constexpr u32 RVZ_MAGIC = 0x015A5652; // "RVZ\x1" (byteswapped to little endian)
class WIAFileReader : public BlobReader template <bool RVZ>
class WIARVZFileReader : public BlobReader
{ {
public: public:
~WIAFileReader(); ~WIARVZFileReader();
static std::unique_ptr<WIAFileReader> Create(File::IOFile file, const std::string& path); static std::unique_ptr<WIARVZFileReader> Create(File::IOFile file, const std::string& path);
BlobType GetBlobType() const override; BlobType GetBlobType() const override;
@ -60,11 +61,10 @@ public:
bool SupportsReadWiiDecrypted() const override; bool SupportsReadWiiDecrypted() const override;
bool ReadWiiDecrypted(u64 offset, u64 size, u8* out_ptr, u64 partition_data_offset) override; bool ReadWiiDecrypted(u64 offset, u64 size, u8* out_ptr, u64 partition_data_offset) override;
static ConversionResultCode ConvertToWIA(BlobReader* infile, const VolumeDisc* infile_volume, static ConversionResultCode Convert(BlobReader* infile, const VolumeDisc* infile_volume,
File::IOFile* outfile, bool rvz, File::IOFile* outfile, WIARVZCompressionType compression_type,
WIACompressionType compression_type, int compression_level, int chunk_size, CompressCB callback,
int compression_level, int chunk_size, void* arg);
CompressCB callback, void* arg);
private: private:
using SHA1 = std::array<u8, 20>; using SHA1 = std::array<u8, 20>;
@ -209,7 +209,7 @@ private:
u64 m_data_offset = 0; u64 m_data_offset = 0;
}; };
explicit WIAFileReader(File::IOFile file, const std::string& path); explicit WIARVZFileReader(File::IOFile file, const std::string& path);
bool Initialize(const std::string& path); bool Initialize(const std::string& path);
bool HasDataOverlap() const; bool HasDataOverlap() const;
@ -306,15 +306,10 @@ private:
u64* bytes_written, u64* offset_out); u64* bytes_written, u64* offset_out);
static void SetUpCompressor(std::unique_ptr<Compressor>* compressor, static void SetUpCompressor(std::unique_ptr<Compressor>* compressor,
WIACompressionType compression_type, int compression_level, WIARVZCompressionType compression_type, int compression_level,
WIAHeader2* header_2); WIAHeader2* header_2);
static bool TryReuse(std::map<ReuseID, GroupEntry>* reusable_groups, static bool TryReuse(std::map<ReuseID, GroupEntry>* reusable_groups,
std::mutex* reusable_groups_mutex, OutputParametersEntry* entry); std::mutex* reusable_groups_mutex, OutputParametersEntry* entry);
static void RVZPack(const u8* in, OutputParametersEntry* out, u64 bytes_per_chunk, size_t chunks,
u64 total_size, u64 data_offset, u64 in_offset, bool allow_junk_reuse,
bool compression, const FileSystem* file_system);
static void RVZPack(const u8* in, OutputParametersEntry* out, u64 size, u64 data_offset,
bool allow_junk_reuse, bool compression, const FileSystem* file_system);
static ConversionResult<OutputParameters> static ConversionResult<OutputParameters>
ProcessAndCompress(CompressThreadState* state, CompressParameters parameters, ProcessAndCompress(CompressThreadState* state, CompressParameters parameters,
const std::vector<PartitionEntry>& partition_entries, const std::vector<PartitionEntry>& partition_entries,
@ -322,7 +317,7 @@ private:
std::map<ReuseID, GroupEntry>* reusable_groups, std::map<ReuseID, GroupEntry>* reusable_groups,
std::mutex* reusable_groups_mutex, u64 chunks_per_wii_group, std::mutex* reusable_groups_mutex, u64 chunks_per_wii_group,
u64 exception_lists_per_chunk, bool compressed_exception_lists, u64 exception_lists_per_chunk, bool compressed_exception_lists,
bool compression, bool rvz); bool compression);
static ConversionResultCode Output(std::vector<OutputParametersEntry>* entries, static ConversionResultCode Output(std::vector<OutputParametersEntry>* entries,
File::IOFile* outfile, File::IOFile* outfile,
std::map<ReuseID, GroupEntry>* reusable_groups, std::map<ReuseID, GroupEntry>* reusable_groups,
@ -332,25 +327,8 @@ private:
u32 total_groups, u64 iso_size, CompressCB callback, u32 total_groups, u64 iso_size, CompressCB callback,
void* arg); void* arg);
static void PushBack(std::vector<u8>* vector, const u8* begin, const u8* end)
{
const size_t offset_in_vector = vector->size();
vector->resize(offset_in_vector + (end - begin));
std::copy(begin, end, vector->data() + offset_in_vector);
}
template <typename T>
static void PushBack(std::vector<u8>* vector, const T& x)
{
static_assert(std::is_trivially_copyable_v<T>);
const u8* x_ptr = reinterpret_cast<const u8*>(&x);
PushBack(vector, x_ptr, x_ptr + sizeof(T));
}
bool m_valid; bool m_valid;
bool m_rvz; WIARVZCompressionType m_compression_type;
WIACompressionType m_compression_type;
File::IOFile m_file; File::IOFile m_file;
Chunk m_cached_chunk; Chunk m_cached_chunk;
@ -382,4 +360,7 @@ private:
static constexpr u32 RVZ_VERSION_READ_COMPATIBLE = 0x00020000; static constexpr u32 RVZ_VERSION_READ_COMPATIBLE = 0x00020000;
}; };
using WIAFileReader = WIARVZFileReader<false>;
using RVZFileReader = WIARVZFileReader<true>;
} // namespace DiscIO } // namespace DiscIO

View File

@ -139,7 +139,8 @@ void ConvertDialog::AddToBlockSizeComboBox(int size)
m_block_size->setCurrentIndex(m_block_size->count() - 1); m_block_size->setCurrentIndex(m_block_size->count() - 1);
} }
void ConvertDialog::AddToCompressionComboBox(const QString& name, DiscIO::WIACompressionType type) void ConvertDialog::AddToCompressionComboBox(const QString& name,
DiscIO::WIARVZCompressionType type)
{ {
m_compression->addItem(name, static_cast<int>(type)); m_compression->addItem(name, static_cast<int>(type));
} }
@ -227,7 +228,7 @@ void ConvertDialog::OnFormatChanged()
{ {
case DiscIO::BlobType::GCZ: case DiscIO::BlobType::GCZ:
m_compression->setEnabled(true); m_compression->setEnabled(true);
AddToCompressionComboBox(QStringLiteral("Deflate"), DiscIO::WIACompressionType::None); AddToCompressionComboBox(QStringLiteral("Deflate"), DiscIO::WIARVZCompressionType::None);
break; break;
case DiscIO::BlobType::WIA: case DiscIO::BlobType::WIA:
case DiscIO::BlobType::RVZ: case DiscIO::BlobType::RVZ:
@ -237,15 +238,22 @@ void ConvertDialog::OnFormatChanged()
// i18n: %1 is the name of a compression method (e.g. LZMA) // i18n: %1 is the name of a compression method (e.g. LZMA)
const QString slow = tr("%1 (slow)"); const QString slow = tr("%1 (slow)");
AddToCompressionComboBox(tr("No Compression"), DiscIO::WIACompressionType::None); AddToCompressionComboBox(tr("No Compression"), DiscIO::WIARVZCompressionType::None);
if (format == DiscIO::BlobType::WIA) if (format == DiscIO::BlobType::WIA)
AddToCompressionComboBox(QStringLiteral("Purge"), DiscIO::WIACompressionType::Purge); AddToCompressionComboBox(QStringLiteral("Purge"), DiscIO::WIARVZCompressionType::Purge);
AddToCompressionComboBox(slow.arg(QStringLiteral("bzip2")), DiscIO::WIACompressionType::Bzip2);
AddToCompressionComboBox(slow.arg(QStringLiteral("LZMA")), DiscIO::WIACompressionType::LZMA); AddToCompressionComboBox(slow.arg(QStringLiteral("bzip2")),
AddToCompressionComboBox(slow.arg(QStringLiteral("LZMA2")), DiscIO::WIACompressionType::LZMA2); DiscIO::WIARVZCompressionType::Bzip2);
AddToCompressionComboBox(slow.arg(QStringLiteral("LZMA")), DiscIO::WIARVZCompressionType::LZMA);
AddToCompressionComboBox(slow.arg(QStringLiteral("LZMA2")),
DiscIO::WIARVZCompressionType::LZMA2);
if (format == DiscIO::BlobType::RVZ) if (format == DiscIO::BlobType::RVZ)
{ {
AddToCompressionComboBox(QStringLiteral("Zstandard"), DiscIO::WIACompressionType::Zstd); AddToCompressionComboBox(QStringLiteral("Zstandard"), DiscIO::WIARVZCompressionType::Zstd);
m_compression->setCurrentIndex(m_compression->count() - 1); m_compression->setCurrentIndex(m_compression->count() - 1);
} }
@ -269,7 +277,7 @@ void ConvertDialog::OnCompressionChanged()
m_compression_level->clear(); m_compression_level->clear();
const auto compression_type = const auto compression_type =
static_cast<DiscIO::WIACompressionType>(m_compression->currentData().toInt()); static_cast<DiscIO::WIARVZCompressionType>(m_compression->currentData().toInt());
const std::pair<int, int> range = DiscIO::GetAllowedCompressionLevels(compression_type); const std::pair<int, int> range = DiscIO::GetAllowedCompressionLevels(compression_type);
@ -299,8 +307,8 @@ void ConvertDialog::Convert()
{ {
const DiscIO::BlobType format = static_cast<DiscIO::BlobType>(m_format->currentData().toInt()); const DiscIO::BlobType format = static_cast<DiscIO::BlobType>(m_format->currentData().toInt());
const int block_size = m_block_size->currentData().toInt(); const int block_size = m_block_size->currentData().toInt();
const DiscIO::WIACompressionType compression = const DiscIO::WIARVZCompressionType compression =
static_cast<DiscIO::WIACompressionType>(m_compression->currentData().toInt()); static_cast<DiscIO::WIARVZCompressionType>(m_compression->currentData().toInt());
const int compression_level = m_compression_level->currentData().toInt(); const int compression_level = m_compression_level->currentData().toInt();
const bool scrub = m_scrub->isChecked(); const bool scrub = m_scrub->isChecked();
@ -477,10 +485,10 @@ void ConvertDialog::Convert()
case DiscIO::BlobType::WIA: case DiscIO::BlobType::WIA:
case DiscIO::BlobType::RVZ: case DiscIO::BlobType::RVZ:
good = std::async(std::launch::async, [&] { good = std::async(std::launch::async, [&] {
const bool good = const bool good = DiscIO::ConvertToWIAOrRVZ(
DiscIO::ConvertToWIA(blob_reader.get(), original_path, dst_path.toStdString(), blob_reader.get(), original_path, dst_path.toStdString(),
format == DiscIO::BlobType::RVZ, compression, compression_level, format == DiscIO::BlobType::RVZ, compression, compression_level, block_size,
block_size, &CompressCB, &progress_dialog); &CompressCB, &progress_dialog);
progress_dialog.Reset(); progress_dialog.Reset();
return good; return good;
}); });

View File

@ -16,7 +16,7 @@ class QComboBox;
namespace DiscIO namespace DiscIO
{ {
enum class WIACompressionType : u32; enum class WIARVZCompressionType : u32;
} }
namespace UICommon namespace UICommon
@ -39,7 +39,7 @@ private slots:
private: private:
void AddToBlockSizeComboBox(int size); void AddToBlockSizeComboBox(int size);
void AddToCompressionComboBox(const QString& name, DiscIO::WIACompressionType type); void AddToCompressionComboBox(const QString& name, DiscIO::WIARVZCompressionType type);
void AddToCompressionLevelComboBox(int level); void AddToCompressionLevelComboBox(int level);
bool ShowAreYouSureDialog(const QString& text); bool ShowAreYouSureDialog(const QString& text);