1import sys 2import os 3 4nbits = int(sys.argv[1]) 5 6for block_size in range(1, nbits + 1): 7 if (block_size * 8) % nbits == 0: 8 break 9 10def gen_pack_bytes(num_values): 11 code = [] 12 nbytes = (num_values * nbits + 7) // 8 13 for i in range(num_values): 14 code.append('const unsigned char s{} = *src++;'.format(i)) 15 for i in range(nbytes): 16 byte_shift = i * 8 17 byte_mask = 0xff << byte_shift 18 values = [] 19 for j in range(num_values): 20 value_shift = j * nbits 21 value_mask = ((1 << nbits) - 1) << value_shift 22 mask = value_mask & byte_mask 23 if not mask: 24 continue 25 if value_shift == byte_shift: 26 values.append('((s{} & 0x{:02x}))'.format(j, mask >> value_shift)) 27 elif value_shift > byte_shift: 28 values.append('((s{} & 0x{:02x}) << {})'.format(j, mask >> value_shift, value_shift - byte_shift)) 29 else: 30 values.append('((s{} & 0x{:02x}) >> {})'.format(j, mask >> value_shift, byte_shift - value_shift)) 31 code.append('*dest++ = (unsigned char) {};'.format(' | '.join(values))) 32 return i + 1, code 33 34print '// Copyright (C) 2016 Lukas Lalinsky' 35print '// Distributed under the MIT license, see the LICENSE file for details.' 36print 37print '// This file was automatically generate using {}, do not edit.'.format(os.path.basename(__file__)) 38print 39print '#ifndef CHROMAPRINT_UTILS_PACK_INT{}_ARRAY_H_'.format(nbits) 40print '#define CHROMAPRINT_UTILS_PACK_INT{}_ARRAY_H_'.format(nbits) 41print 42print '#include <algorithm>' 43print 44print 'namespace chromaprint {' 45print 46print 'inline size_t GetPackedInt{}ArraySize(size_t size) {{'.format(nbits) 47print '\treturn (size * {} + {}) / {};'.format(block_size, block_size * 8 // nbits - 1, block_size * 8 // nbits) 48print '}' 49print 50print 'template <typename InputIt, typename OutputIt>' 51print 'inline OutputIt PackInt{}Array(const InputIt first, const InputIt last, OutputIt dest) {{'.format(nbits) 52print '\tauto size = std::distance(first, last);' 53print '\tauto src = first;' 54first_if = True 55for nbytes in range(block_size * 8 // nbits, 0, -1): 56 if nbytes == block_size * 8 // nbits: 57 print '\twhile (size >= {}) {{'.format(nbytes) 58 else: 59 if not first_if: 60 print 'else', 61 else: 62 print '\t', 63 print 'if (size == {}) {{'.format(nbytes) 64 first_if = False 65 packed_bits, code = gen_pack_bytes(nbytes) 66 for line in code: 67 print '\t\t{}'.format(line) 68 if nbytes == block_size * 8 // nbits: 69 print '\t\tsize -= {};'.format(nbytes) 70 if nbytes == block_size * 8 // nbits or nbytes == 1: 71 print '\t}' 72 else: 73 print '\t}', 74print '\t return dest;' 75print '}' 76print 77print '}; // namespace chromaprint' 78print 79print '#endif' 80