ES-2024 reverter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
2.9KB

  1. #include <stdio.h>
  2. #include <stdint.h>
  3. struct lzs_state {
  4. uint8_t *srcblkstart;
  5. uint8_t *src;
  6. uint32_t srcsize;
  7. uint8_t *dstblkstart;
  8. uint8_t *dst;
  9. uint32_t dstsize;
  10. uint32_t bitbuf;
  11. uint32_t bitcnt;
  12. };
  13. static uint32_t get_bits(struct lzs_state *state, int num)
  14. {
  15. while (state->bitcnt < num) {
  16. state->bitbuf = (state->bitbuf << 8) | *(state->src)++;
  17. state->bitcnt += 8;
  18. }
  19. state->bitcnt -= num;
  20. return (state->bitbuf >> state->bitcnt) & ((1 << num) -1);
  21. }
  22. static uint32_t get_len(struct lzs_state *state)
  23. {
  24. uint32_t bits;
  25. uint32_t length = 2;
  26. do {
  27. bits = get_bits(state, 2);
  28. length += bits;
  29. } while ((bits == 3) && (length < 8));
  30. if (length == 8) {
  31. do {
  32. bits = get_bits(state, 4);
  33. length += bits;
  34. } while (bits == 15);
  35. }
  36. return length;
  37. }
  38. static int get_zyxel_header(struct lzs_state *state)
  39. {
  40. uint8_t *p = state->srcblkstart;
  41. uint32_t a = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
  42. uint32_t b = ((state->dst - state->dstblkstart) << 16) & 0xFFFF0000;
  43. b |= ((state->src - state->srcblkstart) & 0xFFFF);
  44. /* remove own header */
  45. b -= 4;
  46. printf("header of previous block is=0x%08x expected=0x%08x %s\n", a, b, ((a == b) ? "OK" : "ERROR"));
  47. return 0;
  48. }
  49. /*
  50. * TODO: check src/dst sizes
  51. */
  52. uint32_t lzs_unpack(uint8_t *srcbuf, uint32_t srcsize, uint8_t *dstbuf, uint32_t dstsize)
  53. {
  54. struct lzs_state state = {
  55. .srcblkstart = srcbuf,
  56. .src = srcbuf,
  57. .srcsize = srcsize,
  58. .dstblkstart = dstbuf,
  59. .dst = dstbuf,
  60. .dstsize = dstsize,
  61. .bitbuf = 0,
  62. .bitcnt = 0,
  63. };
  64. while (1) {
  65. /* jump over header */
  66. if (state.srcblkstart == state.src)
  67. state.src += 4;
  68. uint32_t tag = get_bits(&state, 1);
  69. /* Uncompressed byte */
  70. if (tag == 0) {
  71. *(state.dst)++ = get_bits(&state, 8);
  72. // printf("uncompressed byte: 0x%02x\n", *(state.dst -1));
  73. /* Compressed string */
  74. } else {
  75. /* read 7 or 11 bit offset */
  76. tag = get_bits(&state, 1);
  77. uint32_t offset = get_bits(&state, (tag == 1) ? 7 : 11);
  78. /* end condition (7bit offset == 0x00) */
  79. if (tag == 1 && offset == 0) {
  80. /* align src to next byte */
  81. uint32_t cnt = state.bitcnt;
  82. uint32_t tmp = get_bits(&state, cnt);
  83. // printf("=== BLOCK END (align=%d bits=0x%x) === \n", cnt, tmp);
  84. get_zyxel_header(&state);
  85. state.srcblkstart = state.src;
  86. state.dstblkstart = state.dst;
  87. /* all src bytes used? */
  88. if (state.src >= srcbuf + srcsize)
  89. break;
  90. continue;
  91. }
  92. uint8_t *dict = state.dst - offset;
  93. if (dict < dstbuf) {
  94. printf("lzs_unpack: invalid dict: %p < %p (tag=%d, offset=0x%x)\n",
  95. dict, dstbuf, tag, offset);
  96. break;
  97. }
  98. uint32_t len = get_len(&state);
  99. // printf("compressed string, offset(%d)=0x%03x len=0x%04x\n", tag, offset, len);
  100. while (len--)
  101. *(state.dst)++ = *dict++;
  102. }
  103. }
  104. printf("lzs_unpack: decompressed %d (%d) bytes to %d (%d) bytes\n",
  105. (state.src - srcbuf), srcsize, (state.dst - dstbuf), dstsize);
  106. return state.dst - dstbuf;
  107. }