Esempio n. 1
0
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");
	}
}
Esempio n. 2
0
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");
	}
}