diff options
| author | Clement Sibille <clements+git@lisible.xyz> | 2024-02-26 02:20:32 +0900 |
|---|---|---|
| committer | Clement Sibille <clements+git@lisible.xyz> | 2024-02-26 02:20:32 +0900 |
| commit | ea36f30a8e1993d4aacc8974cd0994db67902467 (patch) | |
| tree | 71fbf9ce5aa8d468277d2caf25ae925a0d42d59d /lisiblepng/src/deflate.c | |
Initial commit
Diffstat (limited to 'lisiblepng/src/deflate.c')
| -rw-r--r-- | lisiblepng/src/deflate.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/lisiblepng/src/deflate.c b/lisiblepng/src/deflate.c new file mode 100644 index 0000000..3f8ce2e --- /dev/null +++ b/lisiblepng/src/deflate.c @@ -0,0 +1,56 @@ +#include "deflate.h" +#include "assert.h" +#include "bitstream.h" + +#define CM_LENGTH_BITS 4 +#define CINFO_LENGTH_BITS 4 +#define FCHECK_LENGTH_BITS 5 +#define FDICT_LENGTH_BITS 1 +#define FLEVEL_LENGTH_BITS 2 + +bool deflate_decompress(Bitstream *bitstream); + +bool zlib_decompress(const uint8_t *compressed_data_buffer, + const size_t compressed_data_length) { + ASSERT(compressed_data_buffer != NULL); + + Bitstream bitstream; + Bitstream_init(&bitstream, compressed_data_buffer, compressed_data_length); + + uint16_t cm = Bitstream_next_bits(&bitstream, CM_LENGTH_BITS); + uint16_t cinfo = Bitstream_next_bits(&bitstream, CINFO_LENGTH_BITS); + uint16_t fcheck = Bitstream_next_bits(&bitstream, FCHECK_LENGTH_BITS); + uint16_t fdict = Bitstream_next_bits(&bitstream, FDICT_LENGTH_BITS); + uint16_t flevel = Bitstream_next_bits(&bitstream, FLEVEL_LENGTH_BITS); + + LOGN("zlib informations:\n" + "- CM (compression method): %d\n" + "- CINFO (compression info): %d\n" + "- FCHECK (check bits for CMF and FLG): %d\n" + "- FDICT (preset dictionary): %d\n" + "- FLEVEL (compression level): %d", + cm, cinfo, fcheck, fdict, flevel); + uint16_t cmf = bitstream.data[0]; + uint16_t flg = bitstream.data[1]; + if ((cmf * 256 + flg) % 31 != 0) { + LOG0("fcheck validation failed"); + return false; + } + + uint32_t dictionary_identifier = 0; + if (fdict != 0) { + uint16_t dictionary_identifier_0 = Bitstream_next_bits(&bitstream, 16); + uint16_t dictionary_identifier_1 = Bitstream_next_bits(&bitstream, 16); + dictionary_identifier = + (dictionary_identifier_0 << 0) + (dictionary_identifier_1 << 16); + LOGN("Dictionary identifier: %d", dictionary_identifier); + } + + if (!deflate_decompress(&bitstream)) { + return false; + } + + // TODO adler32 checksum + + return true; +} |
