void CompressedBlobReader::GetBlock(u64 block_num, u8 *out_ptr) { bool uncompressed = false; u32 comp_block_size = (u32)GetBlockCompressedSize(block_num); u64 offset = m_block_pointers[block_num] + m_data_offset; if (offset & (1ULL << 63)) { if (comp_block_size != m_header.block_size) PanicAlert("Uncompressed block with wrong size"); uncompressed = true; offset &= ~(1ULL << 63); } // clear unused part of zlib buffer. maybe this can be deleted when it works fully. memset(&m_zlib_buffer[comp_block_size], 0, m_zlib_buffer.size() - comp_block_size); m_file.Seek(offset, SEEK_SET); m_file.ReadBytes(m_zlib_buffer.data(), comp_block_size); // First, check hash. u32 block_hash = HashAdler32(m_zlib_buffer.data(), comp_block_size); if (block_hash != m_hashes[block_num]) PanicAlertT("The disc image \"%s\" is corrupt.\n" "Hash of block %" PRIu64 " is %08x instead of %08x.", m_file_name.c_str(), block_num, block_hash, m_hashes[block_num]); if (uncompressed) { std::copy(m_zlib_buffer.begin(), m_zlib_buffer.begin() + comp_block_size, out_ptr); } else { z_stream z = {}; z.next_in = m_zlib_buffer.data(); z.avail_in = comp_block_size; if (z.avail_in > m_header.block_size) { PanicAlert("We have a problem"); } z.next_out = out_ptr; z.avail_out = m_header.block_size; inflateInit(&z); int status = inflate(&z, Z_FULL_FLUSH); u32 uncomp_size = m_header.block_size - z.avail_out; if (status != Z_STREAM_END) { // this seem to fire wrongly from time to time // to be sure, don't use compressed isos :P PanicAlert("Failure reading block %" PRIu64 " - out of data and not at end.", block_num); } inflateEnd(&z); if (uncomp_size != m_header.block_size) PanicAlert("Wrong block size"); } }
void CompressedBlobReader::GetBlock(u64 block_num, u8 *out_ptr) { bool uncompressed = false; u32 comp_block_size = (u32)GetBlockCompressedSize(block_num); u64 offset = block_pointers[block_num] + data_offset; if (offset & (1ULL << 63)) { if (comp_block_size != header.block_size) PanicAlert("Uncompressed block with wrong size"); uncompressed = true; offset &= ~(1ULL << 63); } // clear unused part of zlib buffer. maybe this can be deleted when it works fully. memset(zlib_buffer + comp_block_size, 0, zlib_buffer_size - comp_block_size); m_file.Seek(offset, SEEK_SET); m_file.ReadBytes(zlib_buffer, comp_block_size); u8* source = zlib_buffer; u8* dest = out_ptr; // First, check hash. u32 block_hash = HashAdler32(source, comp_block_size); if (block_hash != hashes[block_num]) PanicAlert("Hash of block %lli is %08x instead of %08x.\n" "Your ISO, %s, is corrupt.", block_num, block_hash, hashes[block_num], file_name.c_str()); if (uncompressed) { memcpy(dest, source, comp_block_size); } else { z_stream z; memset(&z, 0, sizeof(z)); z.next_in = source; z.avail_in = comp_block_size; if (z.avail_in > header.block_size) { PanicAlert("We have a problem"); } z.next_out = dest; z.avail_out = header.block_size; inflateInit(&z); int status = inflate(&z, Z_FULL_FLUSH); u32 uncomp_size = header.block_size - z.avail_out; if (status != Z_STREAM_END) { // this seem to fire wrongly from time to time // to be sure, don't use compressed isos :P PanicAlert("Failure reading block %lli - out of data and not at end.", block_num); } inflateEnd(&z); if (uncomp_size != header.block_size) PanicAlert("Wrong block size"); } }