fastlz.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #if defined(__GNUC__) && (__GNUC__ > 2)
  2. #define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
  3. #define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
  4. #else
  5. #define FASTLZ_EXPECT_CONDITIONAL(c) (c)
  6. #define FASTLZ_UNEXPECT_CONDITIONAL(c) (c)
  7. #endif
  8. /*
  9. * Use inlined functions for supported systems.
  10. */
  11. #if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C)
  12. #define FASTLZ_INLINE inline
  13. #elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__)
  14. #define FASTLZ_INLINE __inline
  15. #else
  16. #define FASTLZ_INLINE
  17. #endif
  18. typedef unsigned char flzuint8;
  19. typedef unsigned short flzuint16;
  20. typedef unsigned int flzuint32;
  21. /* prototypes */
  22. int fastlz_decompress(const void* input, int length, void* output);
  23. #define MAX_DISTANCE 256
  24. #include <avr/pgmspace.h> /* required by usbdrv.h */
  25. #include <util/delay.h> /* for _delay_ms() */
  26. #include <avr/interrupt.h> /* for sei() */
  27. #include "sram.h"
  28. #include "debug.h"
  29. #include "info.h"
  30. #include "ringbuffer.h"
  31. //#define log2(NUM) printf("%i op=%i(%x) ip=%i(%x) ref=%i(%x) dist=%i buf->end=%i len=%i ctrl=%i ofs=%i(%i) limit=%i\n",NUM, output_index,output[output_index], input_index,input[input_index],ref_index,input[ref_index],output_index - ref_index,ref_buffer_ptr->end, len, ctrl, ofs, ofs>>6,input_index < ip_limit);
  32. #define log2(NUM) info_P(PSTR("%i op=%i ip=%i ref=%i dist=%i buf->end=%i len=%i ctrl=%i ofs=%i(%i) limit=%i\n"),NUM, output_index, input_index,ref_index,output_index - ref_index,ref_buffer_ptr->end, len, ctrl, ofs, ofs>>6,input_index < ip_limit);
  33. #define OUTPUT_INC(B) do { \
  34. __b = B;\
  35. sram_bulk_write(__b);\
  36. sram_bulk_write_next();\
  37. bufferWrite(ref_buffer_ptr, __b);\
  38. output_index++;\
  39. } while (0)
  40. #define OUTPUT_INC_FROM_REFINC() do { \
  41. __dist = (output_index-ref_index); \
  42. __c = buffer_get(ref_buffer_ptr, __dist); \
  43. sram_bulk_write(__c);\
  44. sram_bulk_write_next();\
  45. output_index++;\
  46. bufferWrite(ref_buffer_ptr, __c);\
  47. ref_index++;\
  48. } while (0)
  49. #define FROM_REF(OUT) do { \
  50. flzuint16 __dist = (output_index-ref_index+1); \
  51. OUT = buffer_get(ref_buffer_ptr, __dist); \
  52. } while (0)
  53. #define OUTBYTE(OUT) do { \
  54. sram_bulk_write(OUT);\
  55. sram_bulk_write_next();\
  56. output_index++;\
  57. } while(0)
  58. #define INBYTE(IN) do { \
  59. cli();\
  60. IN = pgm_read_byte((PGM_VOID_P)input_index++); \
  61. sei();\
  62. } while(0)
  63. #define INPUT_INC(IN) do { \
  64. cli();\
  65. if (input_index<32768) { \
  66. IN = pgm_read_byte((PGM_VOID_P)input_index++); \
  67. } else { \
  68. IN = pgm_read_byte((PGM_VOID_P)input_index-32768); \
  69. input_index++; \
  70. }\
  71. sei();\
  72. } while (0)
  73. ring_buffer_typedef(unsigned char, byte_buffer);
  74. int fastlz_decompress2(unsigned char* input1, unsigned char* input2, int length)
  75. {
  76. flzuint32 input_index = 0;
  77. flzuint32 ip_limit = length;
  78. flzuint32 output_index = 0;
  79. flzuint32 ref_index = 0;
  80. //flzuint32 ctrl = (input[input_index++]) & 31;
  81. flzuint32 ctrl;
  82. INPUT_INC(ctrl);
  83. ctrl = ctrl & 31;
  84. int loop = 1;
  85. byte_buffer ref_buffer;
  86. buffer_init(ref_buffer, MAX_DISTANCE, unsigned char);
  87. byte_buffer* ref_buffer_ptr;
  88. ref_buffer_ptr = &ref_buffer;
  89. do
  90. {
  91. flzuint8 __b;
  92. flzuint16 __dist;
  93. flzuint8 __c;
  94. flzuint8 tmp;
  95. ref_index = output_index;
  96. flzuint32 len = ctrl >> 5;
  97. flzuint32 ofs = (ctrl & 31) << 6;
  98. //log2(1)
  99. if(ctrl >= 32)
  100. {
  101. len--;
  102. ref_index -= ofs;
  103. if (len == 7-1){
  104. INPUT_INC(tmp);
  105. len += tmp;
  106. //len += input[input_index++];
  107. }
  108. INPUT_INC(tmp);
  109. ref_index -= tmp;
  110. //ref_index -= input[input_index++];
  111. //log2(1)
  112. if(FASTLZ_EXPECT_CONDITIONAL( input_index < ip_limit))
  113. INPUT_INC(ctrl);
  114. //ctrl = input[input_index++];
  115. else
  116. loop = 0;
  117. //log2(1)
  118. if(ref_index == output_index)
  119. {
  120. //log2(2)
  121. //flzuint8 b = output[ref_index-1];
  122. flzuint8 b;
  123. FROM_REF(b);
  124. OUTPUT_INC(b);
  125. OUTPUT_INC(b);
  126. OUTPUT_INC(b);
  127. for(; len; --len)
  128. OUTPUT_INC(b);
  129. }
  130. else
  131. {
  132. //log2(3)
  133. ref_index--;
  134. OUTPUT_INC_FROM_REFINC();
  135. OUTPUT_INC_FROM_REFINC();
  136. OUTPUT_INC_FROM_REFINC();
  137. for(; len; --len)
  138. OUTPUT_INC_FROM_REFINC();
  139. }
  140. }
  141. else
  142. {
  143. ctrl++;
  144. //log2(4)
  145. INPUT_INC(tmp);
  146. OUTPUT_INC(tmp);
  147. //OUTPUT_INC(input[input_index++]);
  148. for(--ctrl; ctrl; ctrl--){
  149. //log2(5)
  150. INPUT_INC(tmp);
  151. OUTPUT_INC(tmp);
  152. //OUTPUT_INC(input[input_index++]);
  153. }
  154. loop = FASTLZ_EXPECT_CONDITIONAL(input_index < ip_limit);
  155. if (loop){
  156. INPUT_INC(ctrl);
  157. //ctrl = input[input_index++];
  158. }
  159. //log2(6)
  160. }
  161. }
  162. while(FASTLZ_EXPECT_CONDITIONAL(loop));
  163. buffer_destroy(ref_buffer_ptr);
  164. return 0;
  165. }