From a6d2f9146d06183e702a37a75b0f17c14e9b0163 Mon Sep 17 00:00:00 2001 From: Mike Iovine <mike.iovine7@gmail.com> Date: Fri, 3 Apr 2020 14:29:00 -0700 Subject: [PATCH] Update Huffman tests --- deflated.original | Bin 45119 -> 8 bytes include/inflate.h | 7 ++-- tests/inflate_test.cpp | 73 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 76 insertions(+), 4 deletions(-) diff --git a/deflated.original b/deflated.original index 0892b339f7276bf3488c14cf51327f5c15c843e0..5666cb41916c6b3ac8878666871ad350b696aeb1 100644 GIT binary patch literal 8 PcmZQja7buaaNq#|3Wx)N literal 45119 zcmd6wS#ummmZjh0SETh*wHe56Nwtmm1THF3BT5_+RkF6Rc?e_%fD{v%=v)Y*e*Jvs z-0L1534mht^z=-db&1G~@a3-OF7EkuyZN|W42#+M-R!ULUu@R9{c?ZUFE{I_>tWwL z`RxC7-T(Y)vmd^ly&G<Ze#I#J;nRM$+|AaTz5bt1mh0L6icdZc+nq+8&EDS(tJQLS zIUBay&2~4t>OT&%^I=$b^UZcU%pZR1yUljiuV;sKedvV0nWNY9Ir?mK!E8g<?&D<k zak*RWXIK0E&A0#ZFSob1PY=8K(MJEpA3VL<U$18WtLuIlG|cSnu(??cIq2-K>!qf8 zuNikI+St$A#ju_2H?xb)_IlROt~c9Zb~9`**n}S6tWUaOx9`ta%iY!NhXb^o4|;QV z;K9Y_nlG30+1a*V|NCLNTJG;oW;ekQ4e2$^H`mvjb+;HUhP7Vi`)dg6?=FY+u<ci~ zUxw91zvat*y_oHWxklIepRb194odH|g&&va!*+kia=Xo8yBk&?hn-*Gui4wpZa-|j zfW>CE*)Dpvr_sjcn~N=B%M!Z@VKmk0HDk^Dr(JitWrL9LEB^f+sz8$2SKaAqHCqjr z%iXHqFJb=M%`MU~yBf9w(_TUj5qfvk^W6CWb6K1vsh_cc%PqSqoSw{mGP}K6&ad)K zv2?lH>&brheptgcZ|VEZVP~cywG1_^VJNHEHB0=uJA-_WJvgom=G<&{tc^L|4A&5N zH=AGa$$B;*l6PXpX1(bCZRoesu=_%_({r$}NR?==r(Ug~mb3$c3_W}D12J=FjnPy8 z<It~`7m!+n-OaWGVuY*@W=$P}#p&T|csyGl;0*+rJ%`E+ySeD}U5x%?@&x&T7(Z=L zfb9;BRZjHM^oC~8dz0Tv<GrqazejkW33{QSPcKF6Zhs4*?`9X`x5$A8X|K|IsPvKl z^{24v#d5#=JAdc0k2tKCn6-;FF{_v^dW⋙zR<2op`;z>d%*ZBq_$}_qj*t8A8I+ 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 Hf7<<T7Nz1H diff --git a/include/inflate.h b/include/inflate.h index 5c66117..9cb5705 100644 --- a/include/inflate.h +++ b/include/inflate.h @@ -25,8 +25,11 @@ typedef struct huffman { /* Reset the position state variable */ void reset_pos(); -/* Create a Huffman mapping from a sequence of lengths. */ -huffman_t *make_huffman(int *lens, int *alphabet, int n_symbols); +/* + * Create a Huffman mapping from a sequence of lengths. + * The alphabet used is (0, 1, ..., n_symbols - 1) + */ +huffman_t *make_huffman(int *lens, int n_symbols); /* Clean up a heap allocated Huffman map */ void destroy_huffman(huffman_t *hf); diff --git a/tests/inflate_test.cpp b/tests/inflate_test.cpp index 4d5df58..53fbf79 100644 --- a/tests/inflate_test.cpp +++ b/tests/inflate_test.cpp @@ -78,10 +78,79 @@ TEST (BufferTests, RevStreamOrderTest) { ASSERT_EQ (get_n_bits((char *) buf, 6, true), 36); } +/* Test making a huffman tree from a sequence of lengths */ +TEST (HuffmanTests, TestMakeHuffman) { + int n_symbols = 8; + int lens[8] = {3, 3, 3, 3, 3, 2, 4, 4}; + + huffman_t *hf = make_huffman(lens, n_symbols); + + int bl_counts[MAX_LENGTH + 1] = {0, 0, 1, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + /* Check bl_counts */ + for (int i = 0; i < MAX_LENGTH + 1; i++) { + ASSERT_EQ (hf->bl_counts[i], bl_counts[i]); + } + + /* + * Check min_codes for entries with non-zero bl_count + * It doesn't really matter what the other entries are. + */ + ASSERT_EQ (hf->min_codes[2], 0); + ASSERT_EQ (hf->min_codes[3], 2); + ASSERT_EQ (hf->min_codes[4], 14); + + /* Check that the alphabet arrays were populated correctly. */ + ASSERT_EQ (hf->alphabet[2][0], 5); + for (int i = 0; i < 5; i++) ASSERT_EQ (hf->alphabet[3][i], i); + ASSERT_EQ (hf->alphabet[4][0], 6); + ASSERT_EQ (hf->alphabet[4][1], 7); + + destroy_huffman(hf); +} + +/* + * Test that make_huffman does not assign a code to symbols with + * a length of 0. + */ +TEST (HuffmanTests, TestMakeHuffmanZeroLens) { + int n_symbols = 8; + int lens[8] = {1, 0, 2, 3, 3, 0, 4, 3}; + + huffman_t *hf = make_huffman(lens, n_symbols); + + int bl_counts[MAX_LENGTH + 1] = {0, 1, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + /* Check bl_counts */ + for (int i = 0; i < MAX_LENGTH + 1; i++) { + ASSERT_EQ (hf->bl_counts[i], bl_counts[i]); + } + + /* Check min_codes */ + ASSERT_EQ (hf->min_codes[1], 0); + ASSERT_EQ (hf->min_codes[2], 2); + ASSERT_EQ (hf->min_codes[3], 6); + ASSERT_EQ (hf->min_codes[4], 18); + + /* Check alphabet. */ + ASSERT_EQ (hf->alphabet[1][0], 0); + + /* 1 and 5 are not used! (length = 0) */ + ASSERT_EQ (hf->alphabet[2][0], 2); + + ASSERT_EQ (hf->alphabet[3][0], 3); + ASSERT_EQ (hf->alphabet[3][1], 4); + ASSERT_EQ (hf->alphabet[3][2], 7); + + ASSERT_EQ (hf->alphabet[4][0], 6); + + destroy_huffman(hf); +} + // TODO -TEST (HuffmanTests, TestMakeHuffman) {} +TEST (HuffmanTests, TestReadChunk) { -TEST (HuffmanTests, TestReadChunk) {} +} TEST (HuffmanTests, TestReadLens) {} -- GitLab