Zlib.cpp 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*
  2. * Copyright (c) 2020, the SerenityOS developers.
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Span.h>
  7. #include <AK/Types.h>
  8. #include <LibCompress/Deflate.h>
  9. #include <LibCompress/Zlib.h>
  10. namespace Compress {
  11. Optional<Zlib> Zlib::try_create(ReadonlyBytes data)
  12. {
  13. if (data.size() < 6)
  14. return {}; // header + footer size is 6
  15. Zlib zlib { data };
  16. u8 compression_info = data.at(0);
  17. u8 flags = data.at(1);
  18. zlib.m_compression_method = compression_info & 0xF;
  19. zlib.m_compression_info = (compression_info >> 4) & 0xF;
  20. zlib.m_check_bits = flags & 0xF;
  21. zlib.m_has_dictionary = (flags >> 5) & 0x1;
  22. zlib.m_compression_level = (flags >> 6) & 0x3;
  23. if (zlib.m_compression_method != 8 || zlib.m_compression_info > 7)
  24. return {}; // non-deflate compression
  25. if (zlib.m_has_dictionary)
  26. return {}; // we dont support pre-defined dictionaries
  27. if ((compression_info * 256 + flags) % 31 != 0)
  28. return {}; // error correction code doesn't match
  29. zlib.m_data_bytes = data.slice(2, data.size() - 2 - 4);
  30. return zlib;
  31. }
  32. Zlib::Zlib(ReadonlyBytes data)
  33. : m_input_data(data)
  34. {
  35. }
  36. Optional<ByteBuffer> Zlib::decompress()
  37. {
  38. return DeflateDecompressor::decompress_all(m_data_bytes);
  39. }
  40. Optional<ByteBuffer> Zlib::decompress_all(ReadonlyBytes bytes)
  41. {
  42. auto zlib = try_create(bytes);
  43. if (!zlib.has_value())
  44. return {};
  45. return zlib->decompress();
  46. }
  47. u32 Zlib::checksum()
  48. {
  49. if (!m_checksum) {
  50. auto bytes = m_input_data.slice(m_input_data.size() - 4, 4);
  51. m_checksum = bytes.at(0) << 24 | bytes.at(1) << 16 | bytes.at(2) << 8 || bytes.at(3);
  52. }
  53. return m_checksum;
  54. }
  55. }