PageRenderTime 560ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/src/tools/win32/krdevui/tpc/tlg5/slide.cpp

http://tvpcn.codeplex.com
C++ | 213 lines | 182 code | 18 blank | 13 comment | 51 complexity | da9883fc321df4074492c9076f861026 MD5 | raw file
Possible License(s): LGPL-3.0, MIT, LGPL-2.0
  1. //---------------------------------------------------------------------------
  2. #include "slide.h"
  3. //---------------------------------------------------------------------------
  4. SlideCompressor::SlideCompressor()
  5. {
  6. S = 0;
  7. for(int i = 0; i < SLIDE_N + SLIDE_M; i++) Text[i] = 0;
  8. for(int i = 0; i < 256*256; i++)
  9. Map[i] = -1;
  10. for(int i = 0; i < SLIDE_N; i++)
  11. Chains[i].Prev = Chains[i].Next = -1;
  12. for(int i = SLIDE_N - 1; i >= 0; i--)
  13. AddMap(i);
  14. }
  15. //---------------------------------------------------------------------------
  16. SlideCompressor::~SlideCompressor()
  17. {
  18. }
  19. //---------------------------------------------------------------------------
  20. int SlideCompressor::GetMatch(const unsigned char*cur, int curlen, int &pos, int s)
  21. {
  22. // get match length
  23. if(curlen < 3) return 0;
  24. int place = cur[0] + ((int)cur[1] << 8);
  25. int maxlen = 0;
  26. if((place = Map[place]) != -1)
  27. {
  28. int place_org;
  29. curlen -= 1;
  30. do
  31. {
  32. place_org = place;
  33. if(s == place || s == ((place + 1) & (SLIDE_N -1))) continue;
  34. place += 2;
  35. int lim = (SLIDE_M < curlen ? SLIDE_M : curlen) + place_org;
  36. const unsigned char *c = cur + 2;
  37. if(lim >= SLIDE_N)
  38. {
  39. if(place_org <= s && s < SLIDE_N)
  40. lim = s;
  41. else if(s < (lim&(SLIDE_N-1)))
  42. lim = s + SLIDE_N;
  43. }
  44. else
  45. {
  46. if(place_org <= s && s < lim)
  47. lim = s;
  48. }
  49. while(Text[place] == *(c++) && place < lim) place++;
  50. int matchlen = place - place_org;
  51. if(matchlen > maxlen) pos = place_org, maxlen = matchlen;
  52. if(matchlen == SLIDE_M) return maxlen;
  53. } while((place = Chains[place_org].Next) != -1);
  54. }
  55. return maxlen;
  56. }
  57. //---------------------------------------------------------------------------
  58. void SlideCompressor::AddMap(int p)
  59. {
  60. int place = Text[p] + ((int)Text[(p + 1) & (SLIDE_N - 1)] << 8);
  61. if(Map[place] == -1)
  62. {
  63. // first insertion
  64. Map[place] = p;
  65. }
  66. else
  67. {
  68. // not first insertion
  69. int old = Map[place];
  70. Map[place] = p;
  71. Chains[old].Prev = p;
  72. Chains[p].Next = old;
  73. Chains[p].Prev = -1;
  74. }
  75. }
  76. //---------------------------------------------------------------------------
  77. void SlideCompressor::DeleteMap(int p)
  78. {
  79. int n;
  80. if((n = Chains[p].Next) != -1)
  81. Chains[n].Prev = Chains[p].Prev;
  82. if((n = Chains[p].Prev) != -1)
  83. {
  84. Chains[n].Next = Chains[p].Next;
  85. }
  86. else if(Chains[p].Next != -1)
  87. {
  88. int place = Text[p] + ((int)Text[(p + 1) & (SLIDE_N - 1)] << 8);
  89. Map[place] = Chains[p].Next;
  90. }
  91. else
  92. {
  93. int place = Text[p] + ((int)Text[(p + 1) & (SLIDE_N - 1)] << 8);
  94. Map[place] = -1;
  95. }
  96. Chains[p].Prev = -1;
  97. Chains[p].Next = -1;
  98. }
  99. //---------------------------------------------------------------------------
  100. void SlideCompressor::Encode(const unsigned char *in, long inlen,
  101. unsigned char *out, long & outlen)
  102. {
  103. unsigned char code[40], codeptr, mask;
  104. if(inlen == 0) return;
  105. outlen = 0;
  106. code[0] = 0;
  107. codeptr = mask = 1;
  108. int s = S;
  109. while(inlen > 0)
  110. {
  111. int pos = 0;
  112. int len = GetMatch(in, inlen, pos, s);
  113. if(len >= 3)
  114. {
  115. code[0] |= mask;
  116. if(len >= 18)
  117. {
  118. code[codeptr++] = pos & 0xff;
  119. code[codeptr++] = ((pos &0xf00)>> 8) | 0xf0;
  120. code[codeptr++] = len - 18;
  121. }
  122. else
  123. {
  124. code[codeptr++] = pos & 0xff;
  125. code[codeptr++] = ((pos&0xf00)>> 8) | ((len-3)<<4);
  126. }
  127. while(len--)
  128. {
  129. unsigned char c = 0[in++];
  130. DeleteMap((s - 1) & (SLIDE_N - 1));
  131. DeleteMap(s);
  132. if(s < SLIDE_M - 1) Text[s + SLIDE_N] = c;
  133. Text[s] = c;
  134. AddMap((s - 1) & (SLIDE_N - 1));
  135. AddMap(s);
  136. s++;
  137. inlen--;
  138. s &= (SLIDE_N - 1);
  139. }
  140. }
  141. else
  142. {
  143. unsigned char c = 0[in++];
  144. DeleteMap((s - 1) & (SLIDE_N - 1));
  145. DeleteMap(s);
  146. if(s < SLIDE_M - 1) Text[s + SLIDE_N] = c;
  147. Text[s] = c;
  148. AddMap((s - 1) & (SLIDE_N - 1));
  149. AddMap(s);
  150. s++;
  151. inlen--;
  152. s &= (SLIDE_N - 1);
  153. code[codeptr++] = c;
  154. }
  155. mask <<= 1;
  156. if(mask == 0)
  157. {
  158. for(int i = 0; i < codeptr; i++)
  159. out[outlen++] = code[i];
  160. mask = codeptr = 1;
  161. code[0] = 0;
  162. }
  163. }
  164. if(mask != 1)
  165. {
  166. for(int i = 0; i < codeptr; i++)
  167. out[outlen++] = code[i];
  168. }
  169. S = s;
  170. }
  171. //---------------------------------------------------------------------------
  172. void SlideCompressor::Store()
  173. {
  174. S2 = S;
  175. int i;
  176. for(i = 0; i < SLIDE_N + SLIDE_M - 1; i++)
  177. Text2[i] = Text[i];
  178. for(i = 0; i < 256*256; i++)
  179. Map2[i] = Map[i];
  180. for(i = 0; i < SLIDE_N; i++)
  181. Chains2[i] = Chains[i];
  182. }
  183. //---------------------------------------------------------------------------
  184. void SlideCompressor::Restore()
  185. {
  186. S = S2;
  187. int i;
  188. for(i = 0; i < SLIDE_N + SLIDE_M - 1; i++)
  189. Text[i] = Text2[i];
  190. for(i = 0; i < 256*256; i++)
  191. Map[i] = Map2[i];
  192. for(i = 0; i < SLIDE_N; i++)
  193. Chains[i] = Chains2[i];
  194. }
  195. //---------------------------------------------------------------------------