lz4k_compress.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. /*
  2. * LZ4K Compressor by Vovo
  3. */
  4. #include <linux/lz4k.h>
  5. #include <linux/types.h>
  6. #include <linux/string.h>
  7. unsigned short lz4k_matchlen_encode[32] = {
  8. 0, 0, 0, 1024, 1026, 2049, 2053, 2057, 2061, 3091, 3123, 3083, 2563, 3643, 3707, 3115, 3099,
  9. 4119, 3591, 4247, 3655, 4791, 4183, 4311, 3623, 5047, 4727, 4983, 3687, 4855, 5111, 4151, };
  10. unsigned short lz4k_matchoff_encode[32] = {
  11. 1024, 1032, 1292, 1028, 1554, 1308, 1586, 1546, 1578, 1562, 1830, 1594, 1894, 1282, 1814,
  12. 1542, 2158, 1878, 2286, 1846, 2078, 1910, 2206, 1806, 2142, 2270, 2110, 1870, 2238, 1838, 2174, 2302, };
  13. unsigned short lz4k_literallen_encode[18] = {
  14. 0, 128, 385, 517, 525, 515, 651, 775, 807, 667, 919, 983, 951, 1015, 911, 975, 943, 1007, };
  15. unsigned short lz4k_literalch_encode[256] = {
  16. 2048, 3092, 3596, 3660, 3628, 4154, 4282, 4218, 3692, 3612, 3676, 4346, 4102, 4230, 4166,
  17. 4294, 3644, 4134, 4262, 4198, 4326, 4861, 5117, 4611, 4118, 4867, 4246, 4182, 4310, 4150, 4278, 4214, 3124, 4342, 4110,
  18. 4238, 4174, 4302, 4739, 4995, 3708, 4142, 4675, 4931, 4270, 4803, 4206, 4334, 3586, 4126, 4254, 4190, 4318, 5059, 4643,
  19. 4899, 4158, 4771, 5027, 4707, 4963, 4835, 5091, 4627, 2564, 3650, 4286, 4222, 4350, 4883, 4755, 5011, 4097, 4691, 4947,
  20. 4225, 4161, 4289, 4129, 4257, 3618, 3682, 4193, 4321, 4113, 4819, 5075, 4659, 4241, 4915, 4787, 5043, 4723, 4979, 4851,
  21. 4177, 4305, 3602, 4145, 4273, 4209, 3666, 4337, 4105, 4233, 3634, 5107, 4619, 4169, 4297, 3698, 3594, 3658, 4137, 3626,
  22. 4265, 3690, 4201, 4329, 4875, 4121, 4249, 4747, 5003, 4683, 4939, 4811, 5067, 3610, 4651, 4907, 4779, 4185, 5035, 4715,
  23. 4971, 4313, 4843, 5099, 4635, 4891, 4763, 5019, 4699, 4153, 4955, 4827, 5083, 4667, 4923, 4795, 5051, 4281, 4731, 4987,
  24. 4859, 5115, 4615, 4871, 4743, 4217, 4999, 4679, 4935, 4807, 5063, 4647, 4903, 4345, 4775, 5031, 4711, 4967, 4839, 5095,
  25. 4631, 4101, 4887, 4759, 5015, 4229, 4695, 4951, 4823, 4165, 5079, 4663, 4919, 4293, 4791, 5047, 4727, 4133, 4983, 4855,
  26. 5111, 4623, 4879, 4751, 5007, 4261, 4687, 4943, 4815, 5071, 4655, 4911, 4783, 4197, 4325, 4117, 4245, 4181, 4309, 5039,
  27. 4719, 4149, 4975, 4847, 5103, 4639, 4895, 4767, 5023, 3674, 4277, 4703, 4213, 4959, 4341, 4831, 5087, 4109, 4671, 4927,
  28. 4799, 4237, 4173, 4301, 5055, 4141, 4269, 4205, 4333, 4125, 4253, 4735, 4189, 4317, 4157, 4285, 4991, 4221, 4863, 5119,
  29. 2056, };
  30. #define RESERVE_16_BITS() \
  31. {if (bitstobeoutput >= 16) { \
  32. *((unsigned short *)op) = (unsigned short) (bits_buffer32 & 0xffff); \
  33. op += 2; \
  34. bits_buffer32 = bits_buffer32 >> 16; \
  35. bitstobeoutput -= 16; \
  36. } }
  37. #define STORE_BITS(bits, code) do { bits_buffer32 |= (code) << bitstobeoutput; bitstobeoutput += (bits); } while (0)
  38. static size_t
  39. _lz4k_do_compress_zram(const unsigned char *in, size_t in_len,
  40. unsigned char *out, size_t *out_len, void *wrkmem, int *checksum)
  41. {
  42. const unsigned char *ip = in;
  43. unsigned char *op = out;
  44. const unsigned char * const in_end = in + in_len;
  45. const unsigned char * const ip_end = in + in_len - 3;
  46. const unsigned char *ii = ip;
  47. const unsigned char ** const dict = wrkmem;
  48. unsigned int bitstobeoutput = 0;
  49. unsigned int bits_buffer32 = 0;
  50. int hash = (int)0x4e4de069; /* initial hash value chosen randomly */
  51. bitstobeoutput = 1;
  52. for (;;) {
  53. const unsigned char *m_pos;
  54. {
  55. size_t dindex;
  56. unsigned int ip_content = *(unsigned int *)ip;
  57. unsigned int hash_temp = ip_content ^ (ip_content >> 12);
  58. dindex = hash_temp & 0xfff;
  59. m_pos = dict[dindex];
  60. dict[dindex] = ip;
  61. if (m_pos < in || m_pos >= ip ||
  62. ((*(unsigned int *)m_pos << 8) != (ip_content << 8))) {
  63. ++ip;
  64. dindex = (hash_temp >> 8) & 0xfff;
  65. m_pos = dict[dindex];
  66. dict[dindex] = ip;
  67. if (m_pos < in || m_pos >= ip ||
  68. ((*(unsigned int *)m_pos << 8) !=
  69. (ip_content & 0xffffff00))) {
  70. ++ip;
  71. if (__builtin_expect(!!(ip >= ip_end), 0))
  72. break;
  73. continue;
  74. }
  75. }
  76. }
  77. hash = ((hash << 5) + hash) + (int)bits_buffer32;
  78. {
  79. size_t lit = ip - ii;
  80. if (lit <= 0) {
  81. if (bitstobeoutput == 32) {
  82. *((unsigned int *)op) = bits_buffer32;
  83. op += 4;
  84. bits_buffer32 = 1;
  85. bitstobeoutput = 1;
  86. } else {
  87. bits_buffer32 |= 1 << bitstobeoutput;
  88. bitstobeoutput += 1;
  89. }
  90. } else if (lit == 1) {
  91. int value, bits, code;
  92. RESERVE_16_BITS();
  93. value = lz4k_literalch_encode[*ii++];
  94. bits = value >> 9;
  95. code = (value & 0x1ff) << 2;
  96. STORE_BITS(bits + 2, code);
  97. } else if (lit == 2) {
  98. int value, bits, code;
  99. int value2, bits2, code2;
  100. RESERVE_16_BITS();
  101. if (bitstobeoutput > (32 - 22)) {
  102. *op++ = (unsigned char) (bits_buffer32 & 0xff);
  103. bits_buffer32 = bits_buffer32 >> 8;
  104. bitstobeoutput -= 8;
  105. }
  106. value = lz4k_literalch_encode[*ii++];
  107. bits = value >> 9;
  108. code = value & 0x1ff;
  109. value2 = lz4k_literalch_encode[*ii++];
  110. bits2 = value2 >> 9;
  111. code2 = value2 & 0x1ff;
  112. bits_buffer32 |=
  113. ((((code2 << bits) | code) << 4) | 2) << bitstobeoutput;
  114. bitstobeoutput += bits2 + bits + 4;
  115. } else {
  116. if (lit <= 17) {
  117. int value, bits, code;
  118. RESERVE_16_BITS();
  119. value = lz4k_literallen_encode[lit];
  120. bits = value >> 7;
  121. code = (value & 0x7f) << 1;
  122. STORE_BITS(bits + 1, code);
  123. } else {
  124. int code = ((lit - 1) << 6) | 0x3e;
  125. RESERVE_16_BITS();
  126. if (bitstobeoutput > (32 - 18)) {
  127. *op++ =
  128. (unsigned char) (bits_buffer32 & 0xff);
  129. bits_buffer32 = bits_buffer32 >> 8;
  130. bitstobeoutput -= 8;
  131. }
  132. STORE_BITS(17 + 1, code);
  133. }
  134. while (1) {
  135. while (bitstobeoutput < 24) {
  136. int value, bits, code;
  137. value = lz4k_literalch_encode[*ii++];
  138. bits = value >> 9;
  139. code = value & 0x1ff;
  140. STORE_BITS(bits, code);
  141. if (__builtin_expect(!!(ii == ip), 0))
  142. goto break_literal_1;
  143. }
  144. /* update hash */
  145. hash += (int)bits_buffer32;
  146. *((unsigned int *)op) = bits_buffer32;
  147. op += 3;
  148. bits_buffer32 = bits_buffer32 >> 24;
  149. bitstobeoutput -= 24;
  150. }
  151. }
  152. /* update hash */
  153. hash += (int)bits_buffer32;
  154. }
  155. break_literal_1:
  156. m_pos += 3;
  157. ip += 3;
  158. if (__builtin_expect(!!(ip < in_end), 1) && *m_pos == *ip) {
  159. m_pos++, ip++;
  160. while (__builtin_expect(!!(ip < (in_end-1)), 1)
  161. && *(unsigned short *)m_pos == *(unsigned short *)ip)
  162. m_pos += 2, ip += 2;
  163. if (__builtin_expect(!!(ip < in_end), 1) && *m_pos == *ip)
  164. m_pos += 1, ip += 1;
  165. }
  166. RESERVE_16_BITS();
  167. {
  168. size_t m_off = ip - m_pos;
  169. if ((m_off & 3) == 0 && m_off <= 128) {
  170. int value = lz4k_matchoff_encode[(m_off / 4) - 1];
  171. int bits = value >> 8;
  172. int code = value & 0xff;
  173. STORE_BITS(bits, code);
  174. } else {
  175. int code = (m_off << 1) | 0x1;
  176. STORE_BITS(13, code);
  177. }
  178. }
  179. RESERVE_16_BITS();
  180. {
  181. size_t m_len = ip - ii;
  182. if (m_len < 32) {
  183. int value = lz4k_matchlen_encode[m_len];
  184. int bits = value >> 9;
  185. int code = value & 0x1ff;
  186. STORE_BITS(bits, code);
  187. } else {
  188. int code = (m_len << 4) | 0xf;
  189. STORE_BITS(16, code);
  190. }
  191. }
  192. ii = ip;
  193. if (__builtin_expect(!!(ip >= ip_end), 0))
  194. break;
  195. }
  196. if ((in_end - ii) > 0) {
  197. size_t t = in_end - ii;
  198. if (t == 1) {
  199. int value, bits, code;
  200. RESERVE_16_BITS();
  201. value = lz4k_literalch_encode[*ii++];
  202. bits = value >> 9;
  203. code = (value & 0x1ff) << 2;
  204. bits_buffer32 |= code << bitstobeoutput;
  205. bitstobeoutput += bits + 2;
  206. } else {
  207. while (bitstobeoutput >= 8) {
  208. *op++ = (unsigned char) (bits_buffer32 & 0xff);
  209. bits_buffer32 = bits_buffer32 >> 8;
  210. bitstobeoutput -= 8;
  211. }
  212. bitstobeoutput += 1;
  213. if (t <= 17) {
  214. int value = lz4k_literallen_encode[t];
  215. int bits = value >> 7;
  216. int code = value & 0x7f;
  217. bits_buffer32 |= code << bitstobeoutput;
  218. bitstobeoutput += bits;
  219. } else {
  220. int code = ((t - 1) << 5) | 0x1f;
  221. bits_buffer32 |= code << bitstobeoutput;
  222. bitstobeoutput += 17;
  223. }
  224. while (1) {
  225. while (bitstobeoutput < 24) {
  226. int value, bits, code;
  227. value = lz4k_literalch_encode[*ii++];
  228. bits = value >> 9;
  229. code = value & 0x1ff;
  230. bits_buffer32 |= code << bitstobeoutput;
  231. bitstobeoutput += bits;
  232. if (__builtin_expect(!!(--t == 0), 0))
  233. goto break_literal_2;
  234. }
  235. *((unsigned int *)op) = bits_buffer32;
  236. op += 3;
  237. bits_buffer32 = bits_buffer32 >> 24;
  238. bitstobeoutput -= 24;
  239. }
  240. }
  241. }
  242. /* update hash */
  243. hash += (hash << 7) + (int)bits_buffer32;
  244. break_literal_2:
  245. while (bitstobeoutput >= 8) {
  246. *op++ = (unsigned char) (bits_buffer32 & 0xff);
  247. bits_buffer32 = bits_buffer32 >> 8;
  248. bitstobeoutput -= 8;
  249. }
  250. if (bitstobeoutput != 0)
  251. *op++ = (unsigned char) (bits_buffer32 & 0xff);
  252. /* 4 bytes padding */
  253. *((unsigned int *)op) = LZ4K_TAG;
  254. op += 4;
  255. /* update hash */
  256. hash += op - out;
  257. hash += hash << 13;
  258. *checksum = hash;
  259. *out_len = op - out;
  260. return 0;
  261. }
  262. static size_t
  263. _lz4k_do_compress(const unsigned char *in, size_t in_len,
  264. unsigned char *out, size_t *out_len, void *wrkmem)
  265. {
  266. const unsigned char *ip = in;
  267. unsigned char *op = out;
  268. const unsigned char *const in_end = in + in_len;
  269. const unsigned char *const ip_end = in + in_len - 3;
  270. const unsigned char *ii = ip;
  271. const unsigned char **const dict = wrkmem;
  272. unsigned int bitstobeoutput = 0;
  273. unsigned int bits_buffer32 = 0;
  274. bitstobeoutput = 1;
  275. for (;;) {
  276. const unsigned char *m_pos;
  277. {
  278. size_t dindex;
  279. unsigned int ip_content = *(unsigned int *)ip;
  280. unsigned int hash_temp = ip_content ^ (ip_content >> 12);
  281. dindex = hash_temp & 0xfff;
  282. m_pos = dict[dindex];
  283. dict[dindex] = ip;
  284. if (m_pos < in || m_pos >= ip
  285. || ((*(unsigned int *)m_pos << 8) != (ip_content << 8))) {
  286. ++ip;
  287. dindex = (hash_temp >> 8) & 0xfff;
  288. m_pos = dict[dindex];
  289. dict[dindex] = ip;
  290. if (m_pos < in || m_pos >= ip
  291. || ((*(unsigned int *)m_pos << 8) !=
  292. (ip_content & 0xffffff00))) {
  293. ++ip;
  294. if (__builtin_expect(!!(ip >= ip_end), 0))
  295. break;
  296. continue;
  297. }
  298. }
  299. }
  300. {
  301. size_t lit = ip - ii;
  302. if (lit <= 0) {
  303. if (bitstobeoutput == 32) {
  304. *((unsigned int *)op) = bits_buffer32;
  305. op += 4;
  306. bits_buffer32 = 1;
  307. bitstobeoutput = 1;
  308. } else {
  309. bits_buffer32 |= 1 << bitstobeoutput;
  310. bitstobeoutput += 1;
  311. }
  312. } else if (lit == 1) {
  313. int value, bits, code;
  314. RESERVE_16_BITS();
  315. value = lz4k_literalch_encode[*ii++];
  316. bits = value >> 9;
  317. code = (value & 0x1ff) << 2;
  318. STORE_BITS(bits + 2, code);
  319. } else if (lit == 2) {
  320. int value, bits, code;
  321. int value2, bits2, code2;
  322. RESERVE_16_BITS();
  323. if (bitstobeoutput > (32 - 22)) {
  324. *op++ = (unsigned char)(bits_buffer32 & 0xff);
  325. bits_buffer32 = bits_buffer32 >> 8;
  326. bitstobeoutput -= 8;
  327. }
  328. value = lz4k_literalch_encode[*ii++];
  329. bits = value >> 9;
  330. code = value & 0x1ff;
  331. value2 = lz4k_literalch_encode[*ii++];
  332. bits2 = value2 >> 9;
  333. code2 = value2 & 0x1ff;
  334. bits_buffer32 |=
  335. ((((code2 << bits) | code) << 4) | 2) << bitstobeoutput;
  336. bitstobeoutput += bits2 + bits + 4;
  337. } else {
  338. if (lit <= 17) {
  339. int value, bits, code;
  340. RESERVE_16_BITS();
  341. value = lz4k_literallen_encode[lit];
  342. bits = value >> 7;
  343. code = (value & 0x7f) << 1;
  344. STORE_BITS(bits + 1, code);
  345. } else {
  346. int code = ((lit - 1) << 6) | 0x3e;
  347. RESERVE_16_BITS();
  348. if (bitstobeoutput > (32 - 18)) {
  349. *op++ =
  350. (unsigned char)(bits_buffer32 & 0xff);
  351. bits_buffer32 = bits_buffer32 >> 8;
  352. bitstobeoutput -= 8;
  353. }
  354. STORE_BITS(17 + 1, code);
  355. }
  356. while (1) {
  357. while (bitstobeoutput < 24) {
  358. int value, bits, code;
  359. value = lz4k_literalch_encode[*ii++];
  360. bits = value >> 9;
  361. code = value & 0x1ff;
  362. STORE_BITS(bits, code);
  363. if (__builtin_expect(!!(ii == ip), 0))
  364. goto break_literal_1;
  365. }
  366. *((unsigned int *)op) = bits_buffer32;
  367. op += 3;
  368. bits_buffer32 = bits_buffer32 >> 24;
  369. bitstobeoutput -= 24;
  370. }
  371. }
  372. }
  373. break_literal_1:
  374. m_pos += 3;
  375. ip += 3;
  376. if (__builtin_expect(!!(ip < in_end), 1) && *m_pos == *ip) {
  377. m_pos++, ip++;
  378. while (__builtin_expect(!!(ip < (in_end - 1)), 1)
  379. && *(unsigned short *)m_pos == *(unsigned short *)ip)
  380. m_pos += 2, ip += 2;
  381. if (__builtin_expect(!!(ip < in_end), 1) && *m_pos == *ip)
  382. m_pos += 1, ip += 1;
  383. }
  384. RESERVE_16_BITS();
  385. {
  386. size_t m_off = ip - m_pos;
  387. if ((m_off & 3) == 0 && m_off <= 128) {
  388. int value = lz4k_matchoff_encode[(m_off / 4) - 1];
  389. int bits = value >> 8;
  390. int code = value & 0xff;
  391. STORE_BITS(bits, code);
  392. } else {
  393. int code = (m_off << 1) | 0x1;
  394. STORE_BITS(13, code);
  395. }
  396. }
  397. RESERVE_16_BITS();
  398. {
  399. size_t m_len = ip - ii;
  400. if (m_len < 32) {
  401. int value = lz4k_matchlen_encode[m_len];
  402. int bits = value >> 9;
  403. int code = value & 0x1ff;
  404. STORE_BITS(bits, code);
  405. } else {
  406. int code = (m_len << 4) | 0xf;
  407. STORE_BITS(16, code);
  408. }
  409. }
  410. ii = ip;
  411. if (__builtin_expect(!!(ip >= ip_end), 0))
  412. break;
  413. }
  414. if ((in_end - ii) > 0) {
  415. size_t t = in_end - ii;
  416. if (t == 1) {
  417. int value, bits, code;
  418. RESERVE_16_BITS();
  419. value = lz4k_literalch_encode[*ii++];
  420. bits = value >> 9;
  421. code = (value & 0x1ff) << 2;
  422. bits_buffer32 |= code << bitstobeoutput;
  423. bitstobeoutput += bits + 2;
  424. } else {
  425. while (bitstobeoutput >= 8) {
  426. *op++ = (unsigned char)(bits_buffer32 & 0xff);
  427. bits_buffer32 = bits_buffer32 >> 8;
  428. bitstobeoutput -= 8;
  429. }
  430. bitstobeoutput += 1;
  431. if (t <= 17) {
  432. int value = lz4k_literallen_encode[t];
  433. int bits = value >> 7;
  434. int code = value & 0x7f;
  435. bits_buffer32 |= code << bitstobeoutput;
  436. bitstobeoutput += bits;
  437. } else {
  438. int code = ((t - 1) << 5) | 0x1f;
  439. bits_buffer32 |= code << bitstobeoutput;
  440. bitstobeoutput += 17;
  441. }
  442. while (1) {
  443. while (bitstobeoutput < 24) {
  444. int value, bits, code;
  445. value = lz4k_literalch_encode[*ii++];
  446. bits = value >> 9;
  447. code = value & 0x1ff;
  448. bits_buffer32 |= code << bitstobeoutput;
  449. bitstobeoutput += bits;
  450. if (__builtin_expect(!!(--t == 0), 0))
  451. goto break_literal_2;
  452. }
  453. *((unsigned int *)op) = bits_buffer32;
  454. op += 3;
  455. bits_buffer32 = bits_buffer32 >> 24;
  456. bitstobeoutput -= 24;
  457. }
  458. }
  459. }
  460. break_literal_2:
  461. while (bitstobeoutput >= 8) {
  462. *op++ = (unsigned char)(bits_buffer32 & 0xff);
  463. bits_buffer32 = bits_buffer32 >> 8;
  464. bitstobeoutput -= 8;
  465. }
  466. if (bitstobeoutput != 0)
  467. *op++ = (unsigned char)(bits_buffer32 & 0xff);
  468. *((unsigned int *)op) = LZ4K_TAG;
  469. op += 4;
  470. *out_len = op - out;
  471. return 0;
  472. }
  473. int lz4k_compress_zram(const unsigned char *in, size_t in_len, unsigned char *out,
  474. size_t *out_len, void *wrkmem, int *checksum)
  475. {
  476. unsigned char *op = out;
  477. if (in_len > 4096)
  478. return -1;
  479. if (__builtin_expect(!!(in_len == 0), 0)) {
  480. *out_len = 0;
  481. return -1;
  482. }
  483. memset(wrkmem, 0, LZ4K_MEM_COMPRESS);
  484. _lz4k_do_compress_zram(in, in_len, op, out_len, wrkmem, checksum);
  485. if (*out_len <= 0)
  486. return -1;
  487. return 0;
  488. }
  489. int lz4k_compress(const unsigned char *in, size_t in_len, unsigned char *out,
  490. size_t *out_len, void *wrkmem)
  491. {
  492. unsigned char *op = out;
  493. if (in_len > 4096)
  494. return -1;
  495. if (__builtin_expect(!!(in_len == 0), 0)) {
  496. *out_len = 0;
  497. return -1;
  498. }
  499. memset(wrkmem, 0, LZ4K_MEM_COMPRESS);
  500. _lz4k_do_compress(in, in_len, op, out_len, wrkmem);
  501. if (*out_len <= 0)
  502. return -1;
  503. return 0;
  504. }