rle.hpp 935 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. #pragma once
  2. namespace nall::Decode {
  3. template<uint S = 1, uint M = 4 / S> //S = word size; M = match length
  4. inline auto RLE(array_view<uint8_t> input) -> vector<uint8_t> {
  5. vector<uint8_t> output;
  6. auto load = [&]() -> uint8_t {
  7. return input ? *input++ : 0;
  8. };
  9. uint base = 0;
  10. uint64_t size = 0;
  11. for(uint byte : range(8)) size |= load() << byte * 8;
  12. output.resize(size);
  13. auto read = [&]() -> uint64_t {
  14. uint64_t value = 0;
  15. for(uint byte : range(S)) value |= load() << byte * 8;
  16. return value;
  17. };
  18. auto write = [&](uint64_t value) -> void {
  19. if(base >= size) return;
  20. for(uint byte : range(S)) output[base++] = value >> byte * 8;
  21. };
  22. while(base < size) {
  23. auto byte = load();
  24. if(byte < 128) {
  25. byte++;
  26. while(byte--) write(read());
  27. } else {
  28. auto value = read();
  29. byte = (byte & 127) + M;
  30. while(byte--) write(value);
  31. }
  32. }
  33. return output;
  34. }
  35. }