| 441 | } |
| 442 | |
| 443 | int64_t |
| 444 | huffman_encode(uint8_t *dst_start, const uint8_t *src, uint32_t src_len) |
| 445 | { |
| 446 | uint8_t *dst = dst_start; |
| 447 | // NOTE: The maximum length of Huffman Code is 30, thus using uint32_t as buffer. |
| 448 | uint32_t buf = 0; |
| 449 | uint32_t remain_bits = 32; |
| 450 | |
| 451 | for (uint32_t i = 0; i < src_len; ++i) { |
| 452 | const uint32_t hex = huffman_table[src[i]].code_as_hex; |
| 453 | const uint32_t bit_len = huffman_table[src[i]].bit_len; |
| 454 | |
| 455 | if (remain_bits > bit_len) { |
| 456 | remain_bits = remain_bits - bit_len; |
| 457 | buf |= hex << remain_bits; |
| 458 | } else if (remain_bits == bit_len) { |
| 459 | buf |= hex; |
| 460 | dst = huffman_encode_append(dst, buf); |
| 461 | remain_bits = 32; |
| 462 | buf = 0; |
| 463 | } else { |
| 464 | buf |= hex >> (bit_len - remain_bits); |
| 465 | dst = huffman_encode_append(dst, buf); |
| 466 | remain_bits = (32 - (bit_len - remain_bits)); |
| 467 | buf = hex << remain_bits; |
| 468 | } |
| 469 | } |
| 470 | |
| 471 | dst = huffman_encode_append(dst, buf, remain_bits / 8); |
| 472 | |
| 473 | // NOTE: Add padding w/ EOS |
| 474 | uint32_t pad_len = remain_bits % 8; |
| 475 | if (pad_len) { |
| 476 | *(dst - 1) |= 0xff >> (8 - pad_len); |
| 477 | } |
| 478 | |
| 479 | return dst - dst_start; |
| 480 | } |
no test coverage detected