Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to compress / decompress an array of bytes? #229

Open
a1880 opened this issue Aug 9, 2024 · 5 comments
Open

How to compress / decompress an array of bytes? #229

a1880 opened this issue Aug 9, 2024 · 5 comments
Assignees
Labels

Comments

@a1880
Copy link

a1880 commented Aug 9, 2024

I've been trying to compress / decompress a vector of bytes by feeding it into a BitOutputArchive or a BitInputArchive respectively. This was rejected as unpermitted operation. Should I use BitMemoryCompressor? How?

Any help would be appreciated.

Greetings,

Axel

@rikyoz rikyoz self-assigned this Aug 10, 2024
@rikyoz
Copy link
Owner

rikyoz commented Aug 10, 2024

I've been trying to compress / decompress a vector of bytes by feeding it into a BitOutputArchive or a BitInputArchive respectively.

Usually, you don't want to directly use BitOutputArchive/BitInputArchive, and should use BitArchiveWriter/BitArchiveReader instead. This is because the former classes need a separate BitAbstractArchiveCreator/BitAbstractArchiveHandler instance, while the writer and reader classes already implement these abstractions.

This was rejected as unpermitted operation.

What is the exact error message and error code thrown by bit7z?

Should I use BitMemoryCompressor?

BitMemCompressor internally uses BitOutputArchive, so it will likely behave exactly as this latter. In general, it is useful when you want to create multiple archives from memory data using the same compression settings/callbacks. In all other cases, e.g., creating only one archive, BitArchiveWriter is the standard choice.

The same applies to the BitMemExtractor vs BitArchiveReader.

@a1880
Copy link
Author

a1880 commented Aug 12, 2024

Thank you for your time and your gracious help.

I tried the following:

bit7z::Bit7zLibrary lib{ LR"(C:\util\7z.dll)" };

void compress(const std::vector<bit7z::byte_t>& data, std::vector<bit7z::byte_t>& compressed)
{
	try
	{
		bit7z::BitArchiveWriter writer(lib, bit7z::BitFormat::GZip);
		writer.compressTo(compressed);

		std::cout << "Compression succeeded!" << std::endl;
	}
	catch (bit7z::BitException ex)
	{
		std::cout << "Compression failed! " << ex.what() << std::endl;
	}
}

This throws an exception in compressTo().
Within writer.compressTo(), the exception is thrown in compressOut().
Variable outMemStream might be the culprit.
Result of outArc->UpdateItems() is E_INVALIDARG One or more arguments are invalid.

@rikyoz
Copy link
Owner

rikyoz commented Aug 12, 2024

The problem is that, in your function, you're not adding any data to the archive (e.g., using writer.addFile(data, "filename")).
7-Zip doesn't support creating empty GZip archives, hence your error.
Also, the GZip format itself doesn't allow adding more than one file, so only one file/buffer of data can be added to the archive; otherwise, a similar error will be thrown by the compressTo method.

@a1880
Copy link
Author

a1880 commented Aug 12, 2024

That makes sense. Thank you again!

I've now managed to make it work.
Please find my code attached as example usage of bit7z.

BZip7.zip

@rikyoz
Copy link
Owner

rikyoz commented Aug 12, 2024

That makes sense. Thank you again!

No problem!

As a side note, I definitely need to improve the error message and code in such cases, as 7-Zip is really not good at reporting the causes of such errors, unfortunately.

Please find my code attached as example usage of bit7z.

I took a look at your code and it seems fine to me.
Just a note: BitArchiveReader can directly extract to a buffer, so the decompression function can be simplified as follows

void BZip7::decompress(const std::vector<bit7z::byte_t>& data, std::vector<bit7z::byte_t>& decompressed) const
{
	try
	{
		bit7z::BitArchiveReader reader(lib, data, bit7z::BitFormat::GZip);
		reader.extractTo(decompressed);
		std::cout << "Decompression succeeded!" << std::endl;
	}
	catch (bit7z::BitException ex)
	{
		std::cout << "Decompression failed! " << ex.what() << std::endl;
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants