1use std::fmt;
2use bit_reverse::reverse_bits;
3use lzvalue::StoredLength;
4
5pub const NUM_LENGTH_CODES: usize = 29;
7
8pub const NUM_DISTANCE_CODES: usize = 30;
11
12pub const NUM_LITERALS_AND_LENGTHS: usize = 286;
15
16
17pub const MAX_CODE_LENGTH: usize = 15;
19
20pub const MIN_MATCH: u16 = 3;
22pub const MAX_MATCH: u16 = 258;
23
24pub const MIN_DISTANCE: u16 = 1;
25pub const MAX_DISTANCE: u16 = 32768;
26
27
28pub const END_OF_BLOCK_POSITION: usize = 256;
30
31pub static FIXED_CODE_LENGTHS: [u8; NUM_LITERALS_AND_LENGTHS + 2] = [
34 8,
35 8,
36 8,
37 8,
38 8,
39 8,
40 8,
41 8,
42 8,
43 8,
44 8,
45 8,
46 8,
47 8,
48 8,
49 8,
50 8,
51 8,
52 8,
53 8,
54 8,
55 8,
56 8,
57 8,
58 8,
59 8,
60 8,
61 8,
62 8,
63 8,
64 8,
65 8,
66 8,
67 8,
68 8,
69 8,
70 8,
71 8,
72 8,
73 8,
74 8,
75 8,
76 8,
77 8,
78 8,
79 8,
80 8,
81 8,
82 8,
83 8,
84 8,
85 8,
86 8,
87 8,
88 8,
89 8,
90 8,
91 8,
92 8,
93 8,
94 8,
95 8,
96 8,
97 8,
98 8,
99 8,
100 8,
101 8,
102 8,
103 8,
104 8,
105 8,
106 8,
107 8,
108 8,
109 8,
110 8,
111 8,
112 8,
113 8,
114 8,
115 8,
116 8,
117 8,
118 8,
119 8,
120 8,
121 8,
122 8,
123 8,
124 8,
125 8,
126 8,
127 8,
128 8,
129 8,
130 8,
131 8,
132 8,
133 8,
134 8,
135 8,
136 8,
137 8,
138 8,
139 8,
140 8,
141 8,
142 8,
143 8,
144 8,
145 8,
146 8,
147 8,
148 8,
149 8,
150 8,
151 8,
152 8,
153 8,
154 8,
155 8,
156 8,
157 8,
158 8,
159 8,
160 8,
161 8,
162 8,
163 8,
164 8,
165 8,
166 8,
167 8,
168 8,
169 8,
170 8,
171 8,
172 8,
173 8,
174 8,
175 8,
176 8,
177 8,
178 9,
179 9,
180 9,
181 9,
182 9,
183 9,
184 9,
185 9,
186 9,
187 9,
188 9,
189 9,
190 9,
191 9,
192 9,
193 9,
194 9,
195 9,
196 9,
197 9,
198 9,
199 9,
200 9,
201 9,
202 9,
203 9,
204 9,
205 9,
206 9,
207 9,
208 9,
209 9,
210 9,
211 9,
212 9,
213 9,
214 9,
215 9,
216 9,
217 9,
218 9,
219 9,
220 9,
221 9,
222 9,
223 9,
224 9,
225 9,
226 9,
227 9,
228 9,
229 9,
230 9,
231 9,
232 9,
233 9,
234 9,
235 9,
236 9,
237 9,
238 9,
239 9,
240 9,
241 9,
242 9,
243 9,
244 9,
245 9,
246 9,
247 9,
248 9,
249 9,
250 9,
251 9,
252 9,
253 9,
254 9,
255 9,
256 9,
257 9,
258 9,
259 9,
260 9,
261 9,
262 9,
263 9,
264 9,
265 9,
266 9,
267 9,
268 9,
269 9,
270 9,
271 9,
272 9,
273 9,
274 9,
275 9,
276 9,
277 9,
278 9,
279 9,
280 9,
281 9,
282 9,
283 9,
284 9,
285 9,
286 9,
287 9,
288 9,
289 9,
290 7,
291 7,
292 7,
293 7,
294 7,
295 7,
296 7,
297 7,
298 7,
299 7,
300 7,
301 7,
302 7,
303 7,
304 7,
305 7,
306 7,
307 7,
308 7,
309 7,
310 7,
311 7,
312 7,
313 7,
314 8,
315 8,
316 8,
317 8,
318 8,
319 8,
320 8,
321 8,
322];
323
324
325
326const LENGTH_EXTRA_BITS_LENGTH: [u8; NUM_LENGTH_CODES] = [
328 0,
329 0,
330 0,
331 0,
332 0,
333 0,
334 0,
335 0,
336 1,
337 1,
338 1,
339 1,
340 2,
341 2,
342 2,
343 2,
344 3,
345 3,
346 3,
347 3,
348 4,
349 4,
350 4,
351 4,
352 5,
353 5,
354 5,
355 5,
356 0,
357];
358
359const LENGTH_CODE: [u8; 256] = [
361 0,
362 1,
363 2,
364 3,
365 4,
366 5,
367 6,
368 7,
369 8,
370 8,
371 9,
372 9,
373 10,
374 10,
375 11,
376 11,
377 12,
378 12,
379 12,
380 12,
381 13,
382 13,
383 13,
384 13,
385 14,
386 14,
387 14,
388 14,
389 15,
390 15,
391 15,
392 15,
393 16,
394 16,
395 16,
396 16,
397 16,
398 16,
399 16,
400 16,
401 17,
402 17,
403 17,
404 17,
405 17,
406 17,
407 17,
408 17,
409 18,
410 18,
411 18,
412 18,
413 18,
414 18,
415 18,
416 18,
417 19,
418 19,
419 19,
420 19,
421 19,
422 19,
423 19,
424 19,
425 20,
426 20,
427 20,
428 20,
429 20,
430 20,
431 20,
432 20,
433 20,
434 20,
435 20,
436 20,
437 20,
438 20,
439 20,
440 20,
441 21,
442 21,
443 21,
444 21,
445 21,
446 21,
447 21,
448 21,
449 21,
450 21,
451 21,
452 21,
453 21,
454 21,
455 21,
456 21,
457 22,
458 22,
459 22,
460 22,
461 22,
462 22,
463 22,
464 22,
465 22,
466 22,
467 22,
468 22,
469 22,
470 22,
471 22,
472 22,
473 23,
474 23,
475 23,
476 23,
477 23,
478 23,
479 23,
480 23,
481 23,
482 23,
483 23,
484 23,
485 23,
486 23,
487 23,
488 23,
489 24,
490 24,
491 24,
492 24,
493 24,
494 24,
495 24,
496 24,
497 24,
498 24,
499 24,
500 24,
501 24,
502 24,
503 24,
504 24,
505 24,
506 24,
507 24,
508 24,
509 24,
510 24,
511 24,
512 24,
513 24,
514 24,
515 24,
516 24,
517 24,
518 24,
519 24,
520 24,
521 25,
522 25,
523 25,
524 25,
525 25,
526 25,
527 25,
528 25,
529 25,
530 25,
531 25,
532 25,
533 25,
534 25,
535 25,
536 25,
537 25,
538 25,
539 25,
540 25,
541 25,
542 25,
543 25,
544 25,
545 25,
546 25,
547 25,
548 25,
549 25,
550 25,
551 25,
552 25,
553 26,
554 26,
555 26,
556 26,
557 26,
558 26,
559 26,
560 26,
561 26,
562 26,
563 26,
564 26,
565 26,
566 26,
567 26,
568 26,
569 26,
570 26,
571 26,
572 26,
573 26,
574 26,
575 26,
576 26,
577 26,
578 26,
579 26,
580 26,
581 26,
582 26,
583 26,
584 26,
585 27,
586 27,
587 27,
588 27,
589 27,
590 27,
591 27,
592 27,
593 27,
594 27,
595 27,
596 27,
597 27,
598 27,
599 27,
600 27,
601 27,
602 27,
603 27,
604 27,
605 27,
606 27,
607 27,
608 27,
609 27,
610 27,
611 27,
612 27,
613 27,
614 27,
615 27,
616 28,
617];
618
619const BASE_LENGTH: [u8; NUM_LENGTH_CODES] = [
621 0,
622 1,
623 2,
624 3,
625 4,
626 5,
627 6,
628 7,
629 8,
630 10,
631 12,
632 14,
633 16,
634 20,
635 24,
636 28,
637 32,
638 40,
639 48,
640 56,
641 64,
642 80,
643 96,
644 112,
645 128,
646 160,
647 192,
648 224,
649 255,
650]; pub const LENGTH_BITS_START: u16 = 257;
654
655pub const FIXED_CODE_LENGTHS_DISTANCE: [u8; NUM_DISTANCE_CODES + 2] = [5; NUM_DISTANCE_CODES + 2];
658
659const DISTANCE_CODES: [u8; 512] = [
660 0,
661 1,
662 2,
663 3,
664 4,
665 4,
666 5,
667 5,
668 6,
669 6,
670 6,
671 6,
672 7,
673 7,
674 7,
675 7,
676 8,
677 8,
678 8,
679 8,
680 8,
681 8,
682 8,
683 8,
684 9,
685 9,
686 9,
687 9,
688 9,
689 9,
690 9,
691 9,
692 10,
693 10,
694 10,
695 10,
696 10,
697 10,
698 10,
699 10,
700 10,
701 10,
702 10,
703 10,
704 10,
705 10,
706 10,
707 10,
708 11,
709 11,
710 11,
711 11,
712 11,
713 11,
714 11,
715 11,
716 11,
717 11,
718 11,
719 11,
720 11,
721 11,
722 11,
723 11,
724 12,
725 12,
726 12,
727 12,
728 12,
729 12,
730 12,
731 12,
732 12,
733 12,
734 12,
735 12,
736 12,
737 12,
738 12,
739 12,
740 12,
741 12,
742 12,
743 12,
744 12,
745 12,
746 12,
747 12,
748 12,
749 12,
750 12,
751 12,
752 12,
753 12,
754 12,
755 12,
756 13,
757 13,
758 13,
759 13,
760 13,
761 13,
762 13,
763 13,
764 13,
765 13,
766 13,
767 13,
768 13,
769 13,
770 13,
771 13,
772 13,
773 13,
774 13,
775 13,
776 13,
777 13,
778 13,
779 13,
780 13,
781 13,
782 13,
783 13,
784 13,
785 13,
786 13,
787 13,
788 14,
789 14,
790 14,
791 14,
792 14,
793 14,
794 14,
795 14,
796 14,
797 14,
798 14,
799 14,
800 14,
801 14,
802 14,
803 14,
804 14,
805 14,
806 14,
807 14,
808 14,
809 14,
810 14,
811 14,
812 14,
813 14,
814 14,
815 14,
816 14,
817 14,
818 14,
819 14,
820 14,
821 14,
822 14,
823 14,
824 14,
825 14,
826 14,
827 14,
828 14,
829 14,
830 14,
831 14,
832 14,
833 14,
834 14,
835 14,
836 14,
837 14,
838 14,
839 14,
840 14,
841 14,
842 14,
843 14,
844 14,
845 14,
846 14,
847 14,
848 14,
849 14,
850 14,
851 14,
852 15,
853 15,
854 15,
855 15,
856 15,
857 15,
858 15,
859 15,
860 15,
861 15,
862 15,
863 15,
864 15,
865 15,
866 15,
867 15,
868 15,
869 15,
870 15,
871 15,
872 15,
873 15,
874 15,
875 15,
876 15,
877 15,
878 15,
879 15,
880 15,
881 15,
882 15,
883 15,
884 15,
885 15,
886 15,
887 15,
888 15,
889 15,
890 15,
891 15,
892 15,
893 15,
894 15,
895 15,
896 15,
897 15,
898 15,
899 15,
900 15,
901 15,
902 15,
903 15,
904 15,
905 15,
906 15,
907 15,
908 15,
909 15,
910 15,
911 15,
912 15,
913 15,
914 15,
915 15,
916 0,
917 0,
918 16,
919 17,
920 18,
921 18,
922 19,
923 19,
924 20,
925 20,
926 20,
927 20,
928 21,
929 21,
930 21,
931 21,
932 22,
933 22,
934 22,
935 22,
936 22,
937 22,
938 22,
939 22,
940 23,
941 23,
942 23,
943 23,
944 23,
945 23,
946 23,
947 23,
948 24,
949 24,
950 24,
951 24,
952 24,
953 24,
954 24,
955 24,
956 24,
957 24,
958 24,
959 24,
960 24,
961 24,
962 24,
963 24,
964 25,
965 25,
966 25,
967 25,
968 25,
969 25,
970 25,
971 25,
972 25,
973 25,
974 25,
975 25,
976 25,
977 25,
978 25,
979 25,
980 26,
981 26,
982 26,
983 26,
984 26,
985 26,
986 26,
987 26,
988 26,
989 26,
990 26,
991 26,
992 26,
993 26,
994 26,
995 26,
996 26,
997 26,
998 26,
999 26,
1000 26,
1001 26,
1002 26,
1003 26,
1004 26,
1005 26,
1006 26,
1007 26,
1008 26,
1009 26,
1010 26,
1011 26,
1012 27,
1013 27,
1014 27,
1015 27,
1016 27,
1017 27,
1018 27,
1019 27,
1020 27,
1021 27,
1022 27,
1023 27,
1024 27,
1025 27,
1026 27,
1027 27,
1028 27,
1029 27,
1030 27,
1031 27,
1032 27,
1033 27,
1034 27,
1035 27,
1036 27,
1037 27,
1038 27,
1039 27,
1040 27,
1041 27,
1042 27,
1043 27,
1044 28,
1045 28,
1046 28,
1047 28,
1048 28,
1049 28,
1050 28,
1051 28,
1052 28,
1053 28,
1054 28,
1055 28,
1056 28,
1057 28,
1058 28,
1059 28,
1060 28,
1061 28,
1062 28,
1063 28,
1064 28,
1065 28,
1066 28,
1067 28,
1068 28,
1069 28,
1070 28,
1071 28,
1072 28,
1073 28,
1074 28,
1075 28,
1076 28,
1077 28,
1078 28,
1079 28,
1080 28,
1081 28,
1082 28,
1083 28,
1084 28,
1085 28,
1086 28,
1087 28,
1088 28,
1089 28,
1090 28,
1091 28,
1092 28,
1093 28,
1094 28,
1095 28,
1096 28,
1097 28,
1098 28,
1099 28,
1100 28,
1101 28,
1102 28,
1103 28,
1104 28,
1105 28,
1106 28,
1107 28,
1108 29,
1109 29,
1110 29,
1111 29,
1112 29,
1113 29,
1114 29,
1115 29,
1116 29,
1117 29,
1118 29,
1119 29,
1120 29,
1121 29,
1122 29,
1123 29,
1124 29,
1125 29,
1126 29,
1127 29,
1128 29,
1129 29,
1130 29,
1131 29,
1132 29,
1133 29,
1134 29,
1135 29,
1136 29,
1137 29,
1138 29,
1139 29,
1140 29,
1141 29,
1142 29,
1143 29,
1144 29,
1145 29,
1146 29,
1147 29,
1148 29,
1149 29,
1150 29,
1151 29,
1152 29,
1153 29,
1154 29,
1155 29,
1156 29,
1157 29,
1158 29,
1159 29,
1160 29,
1161 29,
1162 29,
1163 29,
1164 29,
1165 29,
1166 29,
1167 29,
1168 29,
1169 29,
1170 29,
1171 29,
1172];
1173
1174#[cfg(test)]
1176const DISTANCE_EXTRA_BITS: [u8; NUM_DISTANCE_CODES] = [
1177 0,
1178 0,
1179 0,
1180 0,
1181 1,
1182 1,
1183 2,
1184 2,
1185 3,
1186 3,
1187 4,
1188 4,
1189 5,
1190 5,
1191 6,
1192 6,
1193 7,
1194 7,
1195 8,
1196 8,
1197 9,
1198 9,
1199 10,
1200 10,
1201 11,
1202 11,
1203 12,
1204 12,
1205 13,
1206 13,
1207];
1208
1209const DISTANCE_BASE: [u16; NUM_DISTANCE_CODES] = [
1210 0,
1211 1,
1212 2,
1213 3,
1214 4,
1215 6,
1216 8,
1217 12,
1218 16,
1219 24,
1220 32,
1221 48,
1222 64,
1223 96,
1224 128,
1225 192,
1226 256,
1227 384,
1228 512,
1229 768,
1230 1024,
1231 1536,
1232 2048,
1233 3072,
1234 4096,
1235 6144,
1236 8192,
1237 12288,
1238 16384,
1239 24576,
1240];
1241
1242pub fn num_extra_bits_for_length_code(code: u8) -> u8 {
1243 LENGTH_EXTRA_BITS_LENGTH[code as usize]
1244}
1245
1246pub fn num_extra_bits_for_distance_code(code: u8) -> u8 {
1250 let mut c = code >> 1;
1253 c -= (c != 0) as u8;
1254 c
1255}
1256
1257#[derive(Copy, Clone)]
1260struct ExtraBits {
1261 pub code_number: u16,
1263 pub num_bits: u8,
1265 pub value: u16,
1268}
1269
1270pub fn get_length_code(length: u16) -> usize {
1273 usize::from(LENGTH_CODE[(length.wrapping_sub(MIN_MATCH)) as u8 as usize]) +
1275 LENGTH_BITS_START as usize
1276}
1277
1278fn get_length_code_and_extra_bits(length: StoredLength) -> ExtraBits {
1280 let n = LENGTH_CODE[length.stored_length() as usize];
1283
1284 let base = BASE_LENGTH[n as usize];
1287 let num_bits = num_extra_bits_for_length_code(n);
1288 ExtraBits {
1289 code_number: u16::from(n) + LENGTH_BITS_START,
1290 num_bits: num_bits,
1291 value: (length.stored_length() - base).into(),
1292 }
1293
1294}
1295
1296pub fn get_distance_code(distance: u16) -> u8 {
1301 let distance = distance as usize;
1302
1303 match distance {
1304 1...256 => DISTANCE_CODES[distance - 1],
1306 257...32768 => DISTANCE_CODES[256 + ((distance - 1) >> 7)],
1310 _ => 0,
1311 }
1312}
1313
1314
1315fn get_distance_code_and_extra_bits(distance: u16) -> ExtraBits {
1316 let distance_code = get_distance_code(distance);
1317 let extra = num_extra_bits_for_distance_code(distance_code);
1318 let base = DISTANCE_BASE[distance_code as usize] + 1;
1320 ExtraBits {
1321 code_number: distance_code.into(),
1322 num_bits: extra,
1323 value: distance - base,
1324 }
1325}
1326
1327#[derive(Copy, Clone, Default)]
1328pub struct HuffmanCode {
1329 pub code: u16,
1330 pub length: u8,
1331}
1332
1333impl fmt::Debug for HuffmanCode {
1334 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1335 write!(
1336 f,
1337 "HuffmanCode {{ code: {:b}, length: {}}}",
1338 self.code,
1339 self.length
1340 )
1341 }
1342}
1343
1344impl HuffmanCode {
1345 #[inline]
1346 fn new(code: u16, length: u8) -> HuffmanCode {
1348 HuffmanCode {
1349 code: code,
1350 length: length,
1351 }
1352 }
1353}
1354
1355#[cfg(test)]
1356pub struct LengthAndDistanceBits {
1357 pub length_code: HuffmanCode,
1358 pub length_extra_bits: HuffmanCode,
1359 pub distance_code: HuffmanCode,
1360 pub distance_extra_bits: HuffmanCode,
1361}
1362
1363fn build_length_count_table(table: &[u8], len_counts: &mut [u16; 16]) -> (usize, usize) {
1368 let max_length = (*table.iter().max().expect("BUG! Empty lengths!")).into();
1370
1371 assert!(max_length <= MAX_CODE_LENGTH);
1372
1373 let mut max_length_pos = 0;
1374
1375 for (n, &length) in table.iter().enumerate() {
1376 if length > 0 {
1379 len_counts[usize::from(length)] += 1;
1380 max_length_pos = n;
1381 }
1382 }
1383 (max_length, max_length_pos)
1384}
1385
1386pub fn create_codes_in_place(code_table: &mut [u16], length_table: &[u8]) {
1389 let mut len_counts = [0; 16];
1390 let (max_length, max_length_pos) = build_length_count_table(length_table, &mut len_counts);
1391 let lengths = len_counts;
1392
1393 let mut code = 0u16;
1394 let mut next_code = Vec::with_capacity(length_table.len());
1395 next_code.push(code);
1396
1397 for bits in 1..max_length + 1 {
1398 code = (code + lengths[bits - 1]) << 1;
1399 next_code.push(code);
1400 }
1401
1402 for n in 0..max_length_pos + 1 {
1403 let length = usize::from(length_table[n]);
1404 if length != 0 {
1405 code_table[n] = reverse_bits(next_code[length], length as u8);
1408 next_code[length] = next_code[length].wrapping_add(1);
1411 }
1412 }
1413}
1414
1415pub struct HuffmanTable {
1417 codes: [u16; 288],
1419 code_lengths: [u8; 288],
1420 distance_codes: [u16; 32],
1422 distance_code_lengths: [u8; 32],
1423}
1424
1425impl HuffmanTable {
1426 pub fn empty() -> HuffmanTable {
1427 HuffmanTable {
1428 codes: [0; 288],
1429 code_lengths: [0; 288],
1430 distance_codes: [0; 32],
1431 distance_code_lengths: [0; 32],
1432 }
1433 }
1434
1435 #[cfg(test)]
1436 pub fn from_length_tables(
1437 literals_and_lengths: &[u8; 288],
1438 distances: &[u8; 32],
1439 ) -> HuffmanTable {
1440 let mut table = HuffmanTable {
1441 codes: [0; 288],
1442 code_lengths: *literals_and_lengths,
1443 distance_codes: [0; 32],
1444 distance_code_lengths: *distances,
1445 };
1446
1447 table.update_from_lengths();
1448 table
1449 }
1450
1451 #[inline]
1453 pub fn get_lengths(&self) -> (&[u8; 288], &[u8; 32]) {
1454 (&self.code_lengths, &self.distance_code_lengths)
1455 }
1456
1457 #[inline]
1461 pub fn get_lengths_mut(&mut self) -> (&mut [u8; 288], &mut [u8; 32]) {
1462 (&mut self.code_lengths, &mut self.distance_code_lengths)
1463 }
1464
1465 pub fn update_from_lengths(&mut self) {
1467 create_codes_in_place(self.codes.as_mut(), &self.code_lengths[..]);
1468 create_codes_in_place(
1469 self.distance_codes.as_mut(),
1470 &self.distance_code_lengths[..],
1471 );
1472 }
1473
1474 pub fn set_to_fixed(&mut self) {
1475 self.code_lengths = FIXED_CODE_LENGTHS;
1476 self.distance_code_lengths = FIXED_CODE_LENGTHS_DISTANCE;
1477 self.update_from_lengths();
1478 }
1479
1480 #[cfg(test)]
1482 pub fn fixed_table() -> HuffmanTable {
1483 HuffmanTable::from_length_tables(&FIXED_CODE_LENGTHS, &FIXED_CODE_LENGTHS_DISTANCE)
1486 }
1487
1488 #[inline]
1489 fn get_ll_huff(&self, value: usize) -> HuffmanCode {
1490 HuffmanCode::new(self.codes[value], self.code_lengths[value])
1491 }
1492
1493 #[inline]
1495 pub fn get_literal(&self, value: u8) -> HuffmanCode {
1496 let index = usize::from(value);
1497 HuffmanCode::new(self.codes[index], self.code_lengths[index])
1498 }
1499
1500 #[inline]
1502 pub fn get_end_of_block(&self) -> HuffmanCode {
1503 self.get_ll_huff(END_OF_BLOCK_POSITION)
1504 }
1505
1506 #[inline]
1508 pub fn get_length_huffman(&self, length: StoredLength) -> (HuffmanCode, HuffmanCode) {
1509
1510 let length_data = get_length_code_and_extra_bits(length);
1511
1512 let length_huffman_code = self.get_ll_huff(length_data.code_number as usize);
1513
1514 (
1515 length_huffman_code,
1516 HuffmanCode {
1517 code: length_data.value,
1518 length: length_data.num_bits,
1519 },
1520 )
1521 }
1522
1523 #[inline]
1527 pub fn get_distance_huffman(&self, distance: u16) -> (HuffmanCode, HuffmanCode) {
1528 debug_assert!(distance >= MIN_DISTANCE && distance <= MAX_DISTANCE);
1529
1530 let distance_data = get_distance_code_and_extra_bits(distance);
1531
1532 let distance_huffman_code = self.distance_codes[distance_data.code_number as usize];
1533 let distance_huffman_length =
1534 self.distance_code_lengths[distance_data.code_number as usize];
1535
1536 (
1537 HuffmanCode {
1538 code: distance_huffman_code,
1539 length: distance_huffman_length,
1540 },
1541 HuffmanCode {
1542 code: distance_data.value,
1543 length: distance_data.num_bits,
1544 },
1545 )
1546 }
1547
1548 #[cfg(test)]
1549 pub fn get_length_distance_code(&self, length: u16, distance: u16) -> LengthAndDistanceBits {
1550 assert!(length >= MIN_MATCH && length < MAX_DISTANCE);
1551 let l_codes = self.get_length_huffman(StoredLength::from_actual_length(length));
1552 let d_codes = self.get_distance_huffman(distance);
1553 LengthAndDistanceBits {
1554 length_code: l_codes.0,
1555 length_extra_bits: l_codes.1,
1556 distance_code: d_codes.0,
1557 distance_extra_bits: d_codes.1,
1558 }
1559 }
1560}
1561
1562#[cfg(test)]
1563mod test {
1564 use super::*;
1565 use super::{get_length_code_and_extra_bits, get_distance_code_and_extra_bits,
1566 build_length_count_table};
1567
1568 use lzvalue::StoredLength;
1569
1570 fn l(length: u16) -> StoredLength {
1571 StoredLength::from_actual_length(length)
1572 }
1573
1574 #[test]
1575 fn test_get_length_code() {
1576 let extra_bits = get_length_code_and_extra_bits(l(4));
1577 assert_eq!(extra_bits.code_number, 258);
1578 assert_eq!(extra_bits.num_bits, 0);
1579 assert_eq!(extra_bits.value, 0);
1580
1581 let extra_bits = get_length_code_and_extra_bits(l(165));
1582 assert_eq!(extra_bits.code_number, 282);
1583 assert_eq!(extra_bits.num_bits, 5);
1584 assert_eq!(extra_bits.value, 2);
1585
1586 let extra_bits = get_length_code_and_extra_bits(l(257));
1587 assert_eq!(extra_bits.code_number, 284);
1588 assert_eq!(extra_bits.num_bits, 5);
1589 assert_eq!(extra_bits.value, 30);
1590
1591 let extra_bits = get_length_code_and_extra_bits(l(258));
1592 assert_eq!(extra_bits.code_number, 285);
1593 assert_eq!(extra_bits.num_bits, 0);
1594 }
1595
1596 #[test]
1597 fn test_distance_code() {
1598 assert_eq!(get_distance_code(1), 0);
1599 assert_eq!(get_distance_code(0), 0);
1601 assert_eq!(get_distance_code(50000), 0);
1602 assert_eq!(get_distance_code(6146), 25);
1603 assert_eq!(get_distance_code(256), 15);
1604 assert_eq!(get_distance_code(4733), 24);
1605 assert_eq!(get_distance_code(257), 16);
1606 }
1607
1608 #[test]
1609 fn test_distance_extra_bits() {
1610 let extra = get_distance_code_and_extra_bits(527);
1611 assert_eq!(extra.value, 0b1110);
1612 assert_eq!(extra.code_number, 18);
1613 assert_eq!(extra.num_bits, 8);
1614 let extra = get_distance_code_and_extra_bits(256);
1615 assert_eq!(extra.code_number, 15);
1616 assert_eq!(extra.num_bits, 6);
1617 let extra = get_distance_code_and_extra_bits(4733);
1618 assert_eq!(extra.code_number, 24);
1619 assert_eq!(extra.num_bits, 11);
1620 }
1621
1622 #[test]
1623 fn test_length_table_fixed() {
1624 let _ = build_length_count_table(&FIXED_CODE_LENGTHS, &mut [0; 16]);
1625 }
1626
1627 #[test]
1628 #[should_panic]
1629 fn test_length_table_max_length() {
1630 let table = [16u8; 288];
1631 build_length_count_table(&table, &mut [0; 16]);
1632 }
1633
1634 #[test]
1635 #[should_panic]
1636 fn test_empty_table() {
1637 let table = [];
1638 build_length_count_table(&table, &mut [0; 16]);
1639 }
1640
1641 #[test]
1642 fn make_table_fixed() {
1643 let table = HuffmanTable::fixed_table();
1644 assert_eq!(table.codes[0], 0b00001100);
1645 assert_eq!(table.codes[143], 0b11111101);
1646 assert_eq!(table.codes[144], 0b000010011);
1647 assert_eq!(table.codes[255], 0b111111111);
1648 assert_eq!(table.codes[256], 0b0000000);
1649 assert_eq!(table.codes[279], 0b1110100);
1650 assert_eq!(table.codes[280], 0b00000011);
1651 assert_eq!(table.codes[287], 0b11100011);
1652
1653 assert_eq!(table.distance_codes[0], 0);
1654 assert_eq!(table.distance_codes[5], 20);
1655
1656 let ld = table.get_length_distance_code(4, 5);
1657
1658 assert_eq!(ld.length_code.code, 0b00100000);
1659 assert_eq!(ld.distance_code.code, 0b00100);
1660 assert_eq!(ld.distance_extra_bits.length, 1);
1661 assert_eq!(ld.distance_extra_bits.code, 0);
1662 }
1663
1664 #[test]
1665 fn extra_bits_distance() {
1666 use std::mem::size_of;
1667 for i in 0..NUM_DISTANCE_CODES {
1668 assert_eq!(
1669 num_extra_bits_for_distance_code(i as u8),
1670 DISTANCE_EXTRA_BITS[i]
1671 );
1672 }
1673 println!("Size of huffmanCode struct: {}", size_of::<HuffmanCode>());
1674 }
1675
1676}