1d4afb5ceSopenharmony_ci/* inftrees.c -- generate Huffman trees for efficient decoding 2d4afb5ceSopenharmony_ci * Copyright (C) 1995-2010 Mark Adler 3d4afb5ceSopenharmony_ci * For conditions of distribution and use, see copyright notice in zlib.h 4d4afb5ceSopenharmony_ci */ 5d4afb5ceSopenharmony_ci 6d4afb5ceSopenharmony_ci#include "zutil.h" 7d4afb5ceSopenharmony_ci#include "inftrees.h" 8d4afb5ceSopenharmony_ci 9d4afb5ceSopenharmony_ci#define MAXBITS 15 10d4afb5ceSopenharmony_ci 11d4afb5ceSopenharmony_ciconst char inflate_copyright[] = 12d4afb5ceSopenharmony_ci " inflate 1.2.5 Copyright 1995-2010 Mark Adler "; 13d4afb5ceSopenharmony_ci/* 14d4afb5ceSopenharmony_ci If you use the zlib library in a product, an acknowledgment is welcome 15d4afb5ceSopenharmony_ci in the documentation of your product. If for some reason you cannot 16d4afb5ceSopenharmony_ci include such an acknowledgment, I would appreciate that you keep this 17d4afb5ceSopenharmony_ci copyright string in the executable of your product. 18d4afb5ceSopenharmony_ci */ 19d4afb5ceSopenharmony_ci 20d4afb5ceSopenharmony_ci/* 21d4afb5ceSopenharmony_ci Build a set of tables to decode the provided canonical Huffman code. 22d4afb5ceSopenharmony_ci The code lengths are lens[0..codes-1]. The result starts at *table, 23d4afb5ceSopenharmony_ci whose indices are 0..2^bits-1. work is a writable array of at least 24d4afb5ceSopenharmony_ci lens shorts, which is used as a work area. type is the type of code 25d4afb5ceSopenharmony_ci to be generated, CODES, LENS, or DISTS. On return, zero is success, 26d4afb5ceSopenharmony_ci -1 is an invalid code, and +1 means that ENOUGH isn't enough. table 27d4afb5ceSopenharmony_ci on return points to the next available entry's address. bits is the 28d4afb5ceSopenharmony_ci requested root table index bits, and on return it is the actual root 29d4afb5ceSopenharmony_ci table index bits. It will differ if the request is greater than the 30d4afb5ceSopenharmony_ci longest code or if it is less than the shortest code. 31d4afb5ceSopenharmony_ci */ 32d4afb5ceSopenharmony_ciint ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) 33d4afb5ceSopenharmony_cicodetype type; 34d4afb5ceSopenharmony_ciunsigned short FAR *lens; 35d4afb5ceSopenharmony_ciunsigned codes; 36d4afb5ceSopenharmony_cicode FAR * FAR *table; 37d4afb5ceSopenharmony_ciunsigned FAR *bits; 38d4afb5ceSopenharmony_ciunsigned short FAR *work; 39d4afb5ceSopenharmony_ci{ 40d4afb5ceSopenharmony_ci unsigned len; /* a code's length in bits */ 41d4afb5ceSopenharmony_ci unsigned sym; /* index of code symbols */ 42d4afb5ceSopenharmony_ci unsigned min, max; /* minimum and maximum code lengths */ 43d4afb5ceSopenharmony_ci unsigned root; /* number of index bits for root table */ 44d4afb5ceSopenharmony_ci unsigned curr; /* number of index bits for current table */ 45d4afb5ceSopenharmony_ci unsigned drop; /* code bits to drop for sub-table */ 46d4afb5ceSopenharmony_ci int left; /* number of prefix codes available */ 47d4afb5ceSopenharmony_ci unsigned used; /* code entries in table used */ 48d4afb5ceSopenharmony_ci unsigned huff; /* Huffman code */ 49d4afb5ceSopenharmony_ci unsigned incr; /* for incrementing code, index */ 50d4afb5ceSopenharmony_ci unsigned fill; /* index for replicating entries */ 51d4afb5ceSopenharmony_ci unsigned low; /* low bits for current root entry */ 52d4afb5ceSopenharmony_ci unsigned mask; /* mask for low root bits */ 53d4afb5ceSopenharmony_ci code here; /* table entry for duplication */ 54d4afb5ceSopenharmony_ci code FAR *next; /* next available space in table */ 55d4afb5ceSopenharmony_ci const unsigned short FAR *base; /* base value table to use */ 56d4afb5ceSopenharmony_ci const unsigned short FAR *extra; /* extra bits table to use */ 57d4afb5ceSopenharmony_ci unsigned match; /* use base and extra for symbol >= match */ 58d4afb5ceSopenharmony_ci unsigned short count[MAXBITS+1]; /* number of codes of each length */ 59d4afb5ceSopenharmony_ci unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ 60d4afb5ceSopenharmony_ci static const unsigned short lbase[31] = { /* Length codes 257..285 base */ 61d4afb5ceSopenharmony_ci 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 62d4afb5ceSopenharmony_ci 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; 63d4afb5ceSopenharmony_ci static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 64d4afb5ceSopenharmony_ci 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 65d4afb5ceSopenharmony_ci 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195}; 66d4afb5ceSopenharmony_ci static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 67d4afb5ceSopenharmony_ci 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 68d4afb5ceSopenharmony_ci 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 69d4afb5ceSopenharmony_ci 8193, 12289, 16385, 24577, 0, 0}; 70d4afb5ceSopenharmony_ci static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ 71d4afb5ceSopenharmony_ci 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 72d4afb5ceSopenharmony_ci 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 73d4afb5ceSopenharmony_ci 28, 28, 29, 29, 64, 64}; 74d4afb5ceSopenharmony_ci 75d4afb5ceSopenharmony_ci /* 76d4afb5ceSopenharmony_ci Process a set of code lengths to create a canonical Huffman code. The 77d4afb5ceSopenharmony_ci code lengths are lens[0..codes-1]. Each length corresponds to the 78d4afb5ceSopenharmony_ci symbols 0..codes-1. The Huffman code is generated by first sorting the 79d4afb5ceSopenharmony_ci symbols by length from short to long, and retaining the symbol order 80d4afb5ceSopenharmony_ci for codes with equal lengths. Then the code starts with all zero bits 81d4afb5ceSopenharmony_ci for the first code of the shortest length, and the codes are integer 82d4afb5ceSopenharmony_ci increments for the same length, and zeros are appended as the length 83d4afb5ceSopenharmony_ci increases. For the deflate format, these bits are stored backwards 84d4afb5ceSopenharmony_ci from their more natural integer increment ordering, and so when the 85d4afb5ceSopenharmony_ci decoding tables are built in the large loop below, the integer codes 86d4afb5ceSopenharmony_ci are incremented backwards. 87d4afb5ceSopenharmony_ci 88d4afb5ceSopenharmony_ci This routine assumes, but does not check, that all of the entries in 89d4afb5ceSopenharmony_ci lens[] are in the range 0..MAXBITS. The caller must assure this. 90d4afb5ceSopenharmony_ci 1..MAXBITS is interpreted as that code length. zero means that that 91d4afb5ceSopenharmony_ci symbol does not occur in this code. 92d4afb5ceSopenharmony_ci 93d4afb5ceSopenharmony_ci The codes are sorted by computing a count of codes for each length, 94d4afb5ceSopenharmony_ci creating from that a table of starting indices for each length in the 95d4afb5ceSopenharmony_ci sorted table, and then entering the symbols in order in the sorted 96d4afb5ceSopenharmony_ci table. The sorted table is work[], with that space being provided by 97d4afb5ceSopenharmony_ci the caller. 98d4afb5ceSopenharmony_ci 99d4afb5ceSopenharmony_ci The length counts are used for other purposes as well, i.e. finding 100d4afb5ceSopenharmony_ci the minimum and maximum length codes, determining if there are any 101d4afb5ceSopenharmony_ci codes at all, checking for a valid set of lengths, and looking ahead 102d4afb5ceSopenharmony_ci at length counts to determine sub-table sizes when building the 103d4afb5ceSopenharmony_ci decoding tables. 104d4afb5ceSopenharmony_ci */ 105d4afb5ceSopenharmony_ci 106d4afb5ceSopenharmony_ci /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ 107d4afb5ceSopenharmony_ci for (len = 0; len <= MAXBITS; len++) 108d4afb5ceSopenharmony_ci count[len] = 0; 109d4afb5ceSopenharmony_ci for (sym = 0; sym < codes; sym++) 110d4afb5ceSopenharmony_ci count[lens[sym]]++; 111d4afb5ceSopenharmony_ci 112d4afb5ceSopenharmony_ci /* bound code lengths, force root to be within code lengths */ 113d4afb5ceSopenharmony_ci root = *bits; 114d4afb5ceSopenharmony_ci for (max = MAXBITS; max >= 1; max--) 115d4afb5ceSopenharmony_ci if (count[max] != 0) break; 116d4afb5ceSopenharmony_ci if (root > max) root = max; 117d4afb5ceSopenharmony_ci if (max == 0) { /* no symbols to code at all */ 118d4afb5ceSopenharmony_ci here.op = (unsigned char)64; /* invalid code marker */ 119d4afb5ceSopenharmony_ci here.bits = (unsigned char)1; 120d4afb5ceSopenharmony_ci here.val = (unsigned short)0; 121d4afb5ceSopenharmony_ci *(*table)++ = here; /* make a table to force an error */ 122d4afb5ceSopenharmony_ci *(*table)++ = here; 123d4afb5ceSopenharmony_ci *bits = 1; 124d4afb5ceSopenharmony_ci return 0; /* no symbols, but wait for decoding to report error */ 125d4afb5ceSopenharmony_ci } 126d4afb5ceSopenharmony_ci for (min = 1; min < max; min++) 127d4afb5ceSopenharmony_ci if (count[min] != 0) break; 128d4afb5ceSopenharmony_ci if (root < min) root = min; 129d4afb5ceSopenharmony_ci 130d4afb5ceSopenharmony_ci /* check for an over-subscribed or incomplete set of lengths */ 131d4afb5ceSopenharmony_ci left = 1; 132d4afb5ceSopenharmony_ci for (len = 1; len <= MAXBITS; len++) { 133d4afb5ceSopenharmony_ci left <<= 1; 134d4afb5ceSopenharmony_ci left -= count[len]; 135d4afb5ceSopenharmony_ci if (left < 0) return -1; /* over-subscribed */ 136d4afb5ceSopenharmony_ci } 137d4afb5ceSopenharmony_ci if (left > 0 && (type == CODES || max != 1)) 138d4afb5ceSopenharmony_ci return -1; /* incomplete set */ 139d4afb5ceSopenharmony_ci 140d4afb5ceSopenharmony_ci /* generate offsets into symbol table for each length for sorting */ 141d4afb5ceSopenharmony_ci offs[1] = 0; 142d4afb5ceSopenharmony_ci for (len = 1; len < MAXBITS; len++) 143d4afb5ceSopenharmony_ci offs[len + 1] = offs[len] + count[len]; 144d4afb5ceSopenharmony_ci 145d4afb5ceSopenharmony_ci /* sort symbols by length, by symbol order within each length */ 146d4afb5ceSopenharmony_ci for (sym = 0; sym < codes; sym++) 147d4afb5ceSopenharmony_ci if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; 148d4afb5ceSopenharmony_ci 149d4afb5ceSopenharmony_ci /* 150d4afb5ceSopenharmony_ci Create and fill in decoding tables. In this loop, the table being 151d4afb5ceSopenharmony_ci filled is at next and has curr index bits. The code being used is huff 152d4afb5ceSopenharmony_ci with length len. That code is converted to an index by dropping drop 153d4afb5ceSopenharmony_ci bits off of the bottom. For codes where len is less than drop + curr, 154d4afb5ceSopenharmony_ci those top drop + curr - len bits are incremented through all values to 155d4afb5ceSopenharmony_ci fill the table with replicated entries. 156d4afb5ceSopenharmony_ci 157d4afb5ceSopenharmony_ci root is the number of index bits for the root table. When len exceeds 158d4afb5ceSopenharmony_ci root, sub-tables are created pointed to by the root entry with an index 159d4afb5ceSopenharmony_ci of the low root bits of huff. This is saved in low to check for when a 160d4afb5ceSopenharmony_ci new sub-table should be started. drop is zero when the root table is 161d4afb5ceSopenharmony_ci being filled, and drop is root when sub-tables are being filled. 162d4afb5ceSopenharmony_ci 163d4afb5ceSopenharmony_ci When a new sub-table is needed, it is necessary to look ahead in the 164d4afb5ceSopenharmony_ci code lengths to determine what size sub-table is needed. The length 165d4afb5ceSopenharmony_ci counts are used for this, and so count[] is decremented as codes are 166d4afb5ceSopenharmony_ci entered in the tables. 167d4afb5ceSopenharmony_ci 168d4afb5ceSopenharmony_ci used keeps track of how many table entries have been allocated from the 169d4afb5ceSopenharmony_ci provided *table space. It is checked for LENS and DIST tables against 170d4afb5ceSopenharmony_ci the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in 171d4afb5ceSopenharmony_ci the initial root table size constants. See the comments in inftrees.h 172d4afb5ceSopenharmony_ci for more information. 173d4afb5ceSopenharmony_ci 174d4afb5ceSopenharmony_ci sym increments through all symbols, and the loop terminates when 175d4afb5ceSopenharmony_ci all codes of length max, i.e. all codes, have been processed. This 176d4afb5ceSopenharmony_ci routine permits incomplete codes, so another loop after this one fills 177d4afb5ceSopenharmony_ci in the rest of the decoding tables with invalid code markers. 178d4afb5ceSopenharmony_ci */ 179d4afb5ceSopenharmony_ci 180d4afb5ceSopenharmony_ci /* set up for code type */ 181d4afb5ceSopenharmony_ci switch (type) { 182d4afb5ceSopenharmony_ci case CODES: 183d4afb5ceSopenharmony_ci base = extra = work; /* dummy value--not used */ 184d4afb5ceSopenharmony_ci match = 20; 185d4afb5ceSopenharmony_ci break; 186d4afb5ceSopenharmony_ci case LENS: 187d4afb5ceSopenharmony_ci base = lbase; 188d4afb5ceSopenharmony_ci extra = lext; 189d4afb5ceSopenharmony_ci match = 257; 190d4afb5ceSopenharmony_ci break; 191d4afb5ceSopenharmony_ci default: /* DISTS */ 192d4afb5ceSopenharmony_ci base = dbase; 193d4afb5ceSopenharmony_ci extra = dext; 194d4afb5ceSopenharmony_ci match = 0; 195d4afb5ceSopenharmony_ci } 196d4afb5ceSopenharmony_ci 197d4afb5ceSopenharmony_ci /* initialize state for loop */ 198d4afb5ceSopenharmony_ci huff = 0; /* starting code */ 199d4afb5ceSopenharmony_ci sym = 0; /* starting code symbol */ 200d4afb5ceSopenharmony_ci len = min; /* starting code length */ 201d4afb5ceSopenharmony_ci next = *table; /* current table to fill in */ 202d4afb5ceSopenharmony_ci curr = root; /* current table index bits */ 203d4afb5ceSopenharmony_ci drop = 0; /* current bits to drop from code for index */ 204d4afb5ceSopenharmony_ci low = (unsigned)(-1); /* trigger new sub-table when len > root */ 205d4afb5ceSopenharmony_ci used = 1U << root; /* use root table entries */ 206d4afb5ceSopenharmony_ci mask = used - 1; /* mask for comparing low */ 207d4afb5ceSopenharmony_ci 208d4afb5ceSopenharmony_ci /* check available table space */ 209d4afb5ceSopenharmony_ci if ((type == LENS && used >= ENOUGH_LENS) || 210d4afb5ceSopenharmony_ci (type == DISTS && used >= ENOUGH_DISTS)) 211d4afb5ceSopenharmony_ci return 1; 212d4afb5ceSopenharmony_ci 213d4afb5ceSopenharmony_ci /* process all codes and make table entries */ 214d4afb5ceSopenharmony_ci for (;;) { 215d4afb5ceSopenharmony_ci /* create table entry */ 216d4afb5ceSopenharmony_ci here.bits = (unsigned char)(len - drop); 217d4afb5ceSopenharmony_ci if (work[sym] + 1 < match) { 218d4afb5ceSopenharmony_ci here.op = (unsigned char)0; 219d4afb5ceSopenharmony_ci here.val = work[sym]; 220d4afb5ceSopenharmony_ci } 221d4afb5ceSopenharmony_ci else if (work[sym] >= match) { 222d4afb5ceSopenharmony_ci here.op = (unsigned char)(extra[work[sym] - match]); 223d4afb5ceSopenharmony_ci here.val = base[work[sym] - match]; 224d4afb5ceSopenharmony_ci } 225d4afb5ceSopenharmony_ci else { 226d4afb5ceSopenharmony_ci here.op = (unsigned char)(32 + 64); /* end of block */ 227d4afb5ceSopenharmony_ci here.val = 0; 228d4afb5ceSopenharmony_ci } 229d4afb5ceSopenharmony_ci 230d4afb5ceSopenharmony_ci /* replicate for those indices with low len bits equal to huff */ 231d4afb5ceSopenharmony_ci incr = 1U << (len - drop); 232d4afb5ceSopenharmony_ci fill = 1U << curr; 233d4afb5ceSopenharmony_ci min = fill; /* save offset to next table */ 234d4afb5ceSopenharmony_ci do { 235d4afb5ceSopenharmony_ci fill -= incr; 236d4afb5ceSopenharmony_ci next[(huff >> drop) + fill] = here; 237d4afb5ceSopenharmony_ci } while (fill != 0); 238d4afb5ceSopenharmony_ci 239d4afb5ceSopenharmony_ci /* backwards increment the len-bit code huff */ 240d4afb5ceSopenharmony_ci incr = 1U << (len - 1); 241d4afb5ceSopenharmony_ci while (huff & incr) 242d4afb5ceSopenharmony_ci incr >>= 1; 243d4afb5ceSopenharmony_ci if (incr != 0) { 244d4afb5ceSopenharmony_ci huff &= incr - 1; 245d4afb5ceSopenharmony_ci huff += incr; 246d4afb5ceSopenharmony_ci } 247d4afb5ceSopenharmony_ci else 248d4afb5ceSopenharmony_ci huff = 0; 249d4afb5ceSopenharmony_ci 250d4afb5ceSopenharmony_ci /* go to next symbol, update count, len */ 251d4afb5ceSopenharmony_ci sym++; 252d4afb5ceSopenharmony_ci if (--(count[len]) == 0) { 253d4afb5ceSopenharmony_ci if (len == max) break; 254d4afb5ceSopenharmony_ci len = lens[work[sym]]; 255d4afb5ceSopenharmony_ci } 256d4afb5ceSopenharmony_ci 257d4afb5ceSopenharmony_ci /* create new sub-table if needed */ 258d4afb5ceSopenharmony_ci if (len > root && (huff & mask) != low) { 259d4afb5ceSopenharmony_ci /* if first time, transition to sub-tables */ 260d4afb5ceSopenharmony_ci if (drop == 0) 261d4afb5ceSopenharmony_ci drop = root; 262d4afb5ceSopenharmony_ci 263d4afb5ceSopenharmony_ci /* increment past last table */ 264d4afb5ceSopenharmony_ci next += min; /* here min is 1 << curr */ 265d4afb5ceSopenharmony_ci 266d4afb5ceSopenharmony_ci /* determine length of next table */ 267d4afb5ceSopenharmony_ci curr = len - drop; 268d4afb5ceSopenharmony_ci left = (int)(1 << curr); 269d4afb5ceSopenharmony_ci while (curr + drop < max) { 270d4afb5ceSopenharmony_ci left -= count[curr + drop]; 271d4afb5ceSopenharmony_ci if (left <= 0) break; 272d4afb5ceSopenharmony_ci curr++; 273d4afb5ceSopenharmony_ci left <<= 1; 274d4afb5ceSopenharmony_ci } 275d4afb5ceSopenharmony_ci 276d4afb5ceSopenharmony_ci /* check for enough space */ 277d4afb5ceSopenharmony_ci used += 1U << curr; 278d4afb5ceSopenharmony_ci if ((type == LENS && used >= ENOUGH_LENS) || 279d4afb5ceSopenharmony_ci (type == DISTS && used >= ENOUGH_DISTS)) 280d4afb5ceSopenharmony_ci return 1; 281d4afb5ceSopenharmony_ci 282d4afb5ceSopenharmony_ci /* point entry in root table to sub-table */ 283d4afb5ceSopenharmony_ci low = huff & mask; 284d4afb5ceSopenharmony_ci (*table)[low].op = (unsigned char)curr; 285d4afb5ceSopenharmony_ci (*table)[low].bits = (unsigned char)root; 286d4afb5ceSopenharmony_ci (*table)[low].val = (unsigned short)(next - *table); 287d4afb5ceSopenharmony_ci } 288d4afb5ceSopenharmony_ci } 289d4afb5ceSopenharmony_ci 290d4afb5ceSopenharmony_ci /* 291d4afb5ceSopenharmony_ci Fill in rest of table for incomplete codes. This loop is similar to the 292d4afb5ceSopenharmony_ci loop above in incrementing huff for table indices. It is assumed that 293d4afb5ceSopenharmony_ci len is equal to curr + drop, so there is no loop needed to increment 294d4afb5ceSopenharmony_ci through high index bits. When the current sub-table is filled, the loop 295d4afb5ceSopenharmony_ci drops back to the root table to fill in any remaining entries there. 296d4afb5ceSopenharmony_ci */ 297d4afb5ceSopenharmony_ci here.op = (unsigned char)64; /* invalid code marker */ 298d4afb5ceSopenharmony_ci here.bits = (unsigned char)(len - drop); 299d4afb5ceSopenharmony_ci here.val = (unsigned short)0; 300d4afb5ceSopenharmony_ci while (huff != 0) { 301d4afb5ceSopenharmony_ci /* when done with sub-table, drop back to root table */ 302d4afb5ceSopenharmony_ci if (drop != 0 && (huff & mask) != low) { 303d4afb5ceSopenharmony_ci drop = 0; 304d4afb5ceSopenharmony_ci len = root; 305d4afb5ceSopenharmony_ci next = *table; 306d4afb5ceSopenharmony_ci here.bits = (unsigned char)len; 307d4afb5ceSopenharmony_ci } 308d4afb5ceSopenharmony_ci 309d4afb5ceSopenharmony_ci /* put invalid code marker in table */ 310d4afb5ceSopenharmony_ci next[huff >> drop] = here; 311d4afb5ceSopenharmony_ci 312d4afb5ceSopenharmony_ci /* backwards increment the len-bit code huff */ 313d4afb5ceSopenharmony_ci incr = 1U << (len - 1); 314d4afb5ceSopenharmony_ci while (huff & incr) 315d4afb5ceSopenharmony_ci incr >>= 1; 316d4afb5ceSopenharmony_ci if (incr != 0) { 317d4afb5ceSopenharmony_ci huff &= incr - 1; 318d4afb5ceSopenharmony_ci huff += incr; 319d4afb5ceSopenharmony_ci } 320d4afb5ceSopenharmony_ci else 321d4afb5ceSopenharmony_ci huff = 0; 322d4afb5ceSopenharmony_ci } 323d4afb5ceSopenharmony_ci 324d4afb5ceSopenharmony_ci /* set return parameters */ 325d4afb5ceSopenharmony_ci *table += used; 326d4afb5ceSopenharmony_ci *bits = root; 327d4afb5ceSopenharmony_ci return 0; 328d4afb5ceSopenharmony_ci} 329