Guest User

Untitled

a guest
Feb 20th, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.92 KB | None | 0 0
  1. #include <stdint.h>
  2. #include <stddef.h>
  3.  
  4. size_t lz77_decode(const uint8_t *src, uint8_t *dst) {
  5.  
  6. // size of ring buffer
  7. static const uint32_t N = 4096;
  8. // upper limit for match_length
  9. static const uint32_t F = 18;
  10. // wrap mask for ring buffer
  11. static const uint32_t WRAP = N - 1;
  12. // encode string into position and length if match length > than this
  13. static const uint32_t THRESHOLD = 2;
  14. // ring buffer of size N with extra F-1 bytes for string comparison
  15. uint8_t text_buf[N + F - 1];
  16.  
  17. uint32_t i, j;
  18. // dst base used later to recover bytes written
  19. const uint8_t *base = dst;
  20.  
  21. // clear ring buffer
  22. for (i = 0; i < N - F; i++) {
  23. text_buf[i] = ' ';
  24. }
  25.  
  26. // set initial ring position
  27. uint32_t r = N - F;
  28. // clear flags
  29. uint16_t flags = 0;
  30.  
  31. // loop until all is decoded
  32. for (;;) {
  33. // shift flags down 1 bit
  34. flags >>= 1;
  35. // if high byte of flags is 0
  36. if ((flags & 0xff00) == 0) {
  37. // read byte
  38. const uint8_t c = *src++;
  39. if (!c) break;
  40. // use high bytes to loop 8 times
  41. flags = c | 0xff00;
  42. }
  43. // if LSB in flags is 1
  44. if (flags & 1) {
  45. // read byte
  46. const uint8_t c = *src++;
  47. if (!c) break;
  48. // write byte directly to output
  49. *(dst++) = c;
  50. // insert into ring buffer
  51. text_buf[r++] = c;
  52. r &= WRAP;
  53. // if LSB in flags is 0
  54. } else {
  55. // read two src byte
  56. i = *src++;
  57. j = *src++;
  58. // high nibble has ring offset high nibble
  59. i |= (j & 0xf0) << 4;
  60. // low nibble has entry match count
  61. j = (j & 0x0f) + THRESHOLD;
  62. // loop for byte count
  63. for (int k = 0; k <= j; k++) {
  64. // read byte from ring buffer
  65. const uint8_t c = text_buf[(i + k) & WRAP];
  66. // put byte into output file
  67. *(dst++) = c;
  68. // insert into ring buffer
  69. text_buf[r++] = c;
  70. r &= WRAP;
  71. } // for
  72. }
  73. } // for
  74. // number of bytes written
  75. return dst - base;
  76. }
Add Comment
Please, Sign In to add comment