diff options
Diffstat (limited to 'apps/codecs/libwavpack/words.c')
-rw-r--r-- | apps/codecs/libwavpack/words.c | 256 |
1 files changed, 120 insertions, 136 deletions
diff --git a/apps/codecs/libwavpack/words.c b/apps/codecs/libwavpack/words.c index 75d8a86af7..d46bb56911 100644 --- a/apps/codecs/libwavpack/words.c +++ b/apps/codecs/libwavpack/words.c | |||
@@ -66,28 +66,6 @@ | |||
66 | 66 | ||
67 | ///////////////////////////// local table storage //////////////////////////// | 67 | ///////////////////////////// local table storage //////////////////////////// |
68 | 68 | ||
69 | const ulong bitset [] = { | ||
70 | 1L << 0, 1L << 1, 1L << 2, 1L << 3, | ||
71 | 1L << 4, 1L << 5, 1L << 6, 1L << 7, | ||
72 | 1L << 8, 1L << 9, 1L << 10, 1L << 11, | ||
73 | 1L << 12, 1L << 13, 1L << 14, 1L << 15, | ||
74 | 1L << 16, 1L << 17, 1L << 18, 1L << 19, | ||
75 | 1L << 20, 1L << 21, 1L << 22, 1L << 23, | ||
76 | 1L << 24, 1L << 25, 1L << 26, 1L << 27, | ||
77 | 1L << 28, 1L << 29, 1L << 30, 1L << 31 | ||
78 | }; | ||
79 | |||
80 | const ulong bitmask [] = { | ||
81 | (1L << 0) - 1, (1L << 1) - 1, (1L << 2) - 1, (1L << 3) - 1, | ||
82 | (1L << 4) - 1, (1L << 5) - 1, (1L << 6) - 1, (1L << 7) - 1, | ||
83 | (1L << 8) - 1, (1L << 9) - 1, (1L << 10) - 1, (1L << 11) - 1, | ||
84 | (1L << 12) - 1, (1L << 13) - 1, (1L << 14) - 1, (1L << 15) - 1, | ||
85 | (1L << 16) - 1, (1L << 17) - 1, (1L << 18) - 1, (1L << 19) - 1, | ||
86 | (1L << 20) - 1, (1L << 21) - 1, (1L << 22) - 1, (1L << 23) - 1, | ||
87 | (1L << 24) - 1, (1L << 25) - 1, (1L << 26) - 1, (1L << 27) - 1, | ||
88 | (1L << 28) - 1, (1L << 29) - 1, (1L << 30) - 1, 0x7fffffff | ||
89 | }; | ||
90 | |||
91 | const char nbits_table [] = { | 69 | const char nbits_table [] = { |
92 | 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, // 0 - 15 | 70 | 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, // 0 - 15 |
93 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 16 - 31 | 71 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 16 - 31 |
@@ -536,177 +514,183 @@ static ulong read_code (Bitstream *bs, ulong maxcode) | |||
536 | return code; | 514 | return code; |
537 | } | 515 | } |
538 | 516 | ||
539 | // This function is an optimized version of send_word() that only handles | 517 | void send_words (long *buffer, int nsamples, ulong flags, |
540 | // lossless (error_limit == 0). It does not return a value because it always | 518 | struct words_data *w, Bitstream *bs) |
541 | // encodes the exact value passed. | ||
542 | |||
543 | void send_word_lossless (WavpackStream *wps, long value, int chan) | ||
544 | { | 519 | { |
545 | register struct words_data *w = &wps->w; | 520 | register struct entropy_data *c = w->c; |
546 | register struct entropy_data *c = w->c + chan; | 521 | |
547 | int sign = (value < 0) ? 1 : 0; | 522 | if (!(flags & MONO_FLAG)) |
548 | ulong ones_count, low, high; | 523 | nsamples *= 2; |
549 | 524 | ||
550 | if (!(wps->w.c [0].median [0] & ~1) && !wps->w.holding_zero && !(wps->w.c [1].median [0] & ~1)) { | 525 | while (nsamples--) { |
551 | if (wps->w.zeros_acc) { | 526 | long value = *buffer++; |
552 | if (value) | 527 | int sign = (value < 0) ? 1 : 0; |
553 | flush_word (wps); | 528 | ulong ones_count, low, high; |
529 | |||
530 | if (!(flags & MONO_FLAG)) | ||
531 | c = w->c + (~nsamples & 1); | ||
532 | |||
533 | if (!(w->c [0].median [0] & ~1) && !w->holding_zero && !(w->c [1].median [0] & ~1)) { | ||
534 | if (w->zeros_acc) { | ||
535 | if (value) | ||
536 | flush_word (w, bs); | ||
537 | else { | ||
538 | w->zeros_acc++; | ||
539 | continue; | ||
540 | } | ||
541 | } | ||
542 | else if (value) { | ||
543 | putbit_0 (bs); | ||
544 | } | ||
554 | else { | 545 | else { |
555 | wps->w.zeros_acc++; | 546 | CLEAR (w->c [0].median); |
556 | return; | 547 | CLEAR (w->c [1].median); |
548 | w->zeros_acc = 1; | ||
549 | continue; | ||
557 | } | 550 | } |
558 | } | 551 | } |
559 | else if (value) { | ||
560 | putbit_0 (&wps->wvbits); | ||
561 | } | ||
562 | else { | ||
563 | CLEAR (wps->w.c [0].median); | ||
564 | CLEAR (wps->w.c [1].median); | ||
565 | wps->w.zeros_acc = 1; | ||
566 | return; | ||
567 | } | ||
568 | } | ||
569 | |||
570 | if (sign) | ||
571 | value = ~value; | ||
572 | 552 | ||
573 | if ((unsigned long) value < GET_MED (0)) { | 553 | if (sign) |
574 | ones_count = low = 0; | 554 | value = ~value; |
575 | high = GET_MED (0) - 1; | ||
576 | DEC_MED0 (); | ||
577 | } | ||
578 | else { | ||
579 | low = GET_MED (0); | ||
580 | INC_MED0 (); | ||
581 | 555 | ||
582 | if (value - low < GET_MED (1)) { | 556 | if ((unsigned long) value < GET_MED (0)) { |
583 | ones_count = 1; | 557 | ones_count = low = 0; |
584 | high = low + GET_MED (1) - 1; | 558 | high = GET_MED (0) - 1; |
585 | DEC_MED1 (); | 559 | DEC_MED0 (); |
586 | } | 560 | } |
587 | else { | 561 | else { |
588 | low += GET_MED (1); | 562 | low = GET_MED (0); |
589 | INC_MED1 (); | 563 | INC_MED0 (); |
590 | 564 | ||
591 | if (value - low < GET_MED (2)) { | 565 | if (value - low < GET_MED (1)) { |
592 | ones_count = 2; | 566 | ones_count = 1; |
593 | high = low + GET_MED (2) - 1; | 567 | high = low + GET_MED (1) - 1; |
594 | DEC_MED2 (); | 568 | DEC_MED1 (); |
595 | } | 569 | } |
596 | else { | 570 | else { |
597 | ones_count = 2 + (value - low) / GET_MED (2); | 571 | low += GET_MED (1); |
598 | low += (ones_count - 2) * GET_MED (2); | 572 | INC_MED1 (); |
599 | high = low + GET_MED (2) - 1; | 573 | |
600 | INC_MED2 (); | 574 | if (value - low < GET_MED (2)) { |
575 | ones_count = 2; | ||
576 | high = low + GET_MED (2) - 1; | ||
577 | DEC_MED2 (); | ||
578 | } | ||
579 | else { | ||
580 | ones_count = 2 + (value - low) / GET_MED (2); | ||
581 | low += (ones_count - 2) * GET_MED (2); | ||
582 | high = low + GET_MED (2) - 1; | ||
583 | INC_MED2 (); | ||
584 | } | ||
601 | } | 585 | } |
602 | } | 586 | } |
603 | } | ||
604 | 587 | ||
605 | if (wps->w.holding_zero) { | 588 | if (w->holding_zero) { |
606 | if (ones_count) | 589 | if (ones_count) |
607 | wps->w.holding_one++; | 590 | w->holding_one++; |
608 | 591 | ||
609 | flush_word (wps); | 592 | flush_word (w, bs); |
610 | 593 | ||
611 | if (ones_count) { | 594 | if (ones_count) { |
612 | wps->w.holding_zero = 1; | 595 | w->holding_zero = 1; |
613 | ones_count--; | 596 | ones_count--; |
597 | } | ||
598 | else | ||
599 | w->holding_zero = 0; | ||
614 | } | 600 | } |
615 | else | 601 | else |
616 | wps->w.holding_zero = 0; | 602 | w->holding_zero = 1; |
617 | } | ||
618 | else | ||
619 | wps->w.holding_zero = 1; | ||
620 | 603 | ||
621 | wps->w.holding_one = ones_count * 2; | 604 | w->holding_one = ones_count * 2; |
622 | 605 | ||
623 | if (high != low) { | 606 | if (high != low) { |
624 | ulong maxcode = high - low, code = value - low; | 607 | ulong maxcode = high - low, code = value - low; |
625 | int bitcount = count_bits (maxcode); | 608 | int bitcount = count_bits (maxcode); |
626 | ulong extras = bitset [bitcount] - maxcode - 1; | 609 | ulong extras = (1L << bitcount) - maxcode - 1; |
627 | 610 | ||
628 | if (code < extras) { | 611 | if (code < extras) { |
629 | wps->w.pend_data |= code << wps->w.pend_count; | 612 | w->pend_data |= code << w->pend_count; |
630 | wps->w.pend_count += bitcount - 1; | 613 | w->pend_count += bitcount - 1; |
631 | } | 614 | } |
632 | else { | 615 | else { |
633 | wps->w.pend_data |= ((code + extras) >> 1) << wps->w.pend_count; | 616 | w->pend_data |= ((code + extras) >> 1) << w->pend_count; |
634 | wps->w.pend_count += bitcount - 1; | 617 | w->pend_count += bitcount - 1; |
635 | wps->w.pend_data |= ((code + extras) & 1) << wps->w.pend_count++; | 618 | w->pend_data |= ((code + extras) & 1) << w->pend_count++; |
619 | } | ||
636 | } | 620 | } |
637 | } | ||
638 | 621 | ||
639 | wps->w.pend_data |= ((long) sign << wps->w.pend_count++); | 622 | w->pend_data |= ((long) sign << w->pend_count++); |
640 | 623 | ||
641 | if (!wps->w.holding_zero) | 624 | if (!w->holding_zero) |
642 | flush_word (wps); | 625 | flush_word (w, bs); |
626 | } | ||
643 | } | 627 | } |
644 | 628 | ||
645 | // Used by send_word() and send_word_lossless() to actually send most the | 629 | // Used by send_word() and send_word_lossless() to actually send most the |
646 | // accumulated data onto the bitstream. This is also called directly from | 630 | // accumulated data onto the bitstream. This is also called directly from |
647 | // clients when all words have been sent. | 631 | // clients when all words have been sent. |
648 | 632 | ||
649 | void flush_word (WavpackStream *wps) | 633 | void flush_word (struct words_data *w, Bitstream *bs) |
650 | { | 634 | { |
651 | if (wps->w.zeros_acc) { | 635 | int cbits; |
652 | int cbits = count_bits (wps->w.zeros_acc); | 636 | |
637 | if (w->zeros_acc) { | ||
638 | cbits = count_bits (w->zeros_acc); | ||
653 | 639 | ||
654 | while (cbits--) { | 640 | while (cbits--) { |
655 | putbit_1 (&wps->wvbits); | 641 | putbit_1 (bs); |
656 | } | 642 | } |
657 | 643 | ||
658 | putbit_0 (&wps->wvbits); | 644 | putbit_0 (bs); |
659 | 645 | ||
660 | while (wps->w.zeros_acc > 1) { | 646 | while (w->zeros_acc > 1) { |
661 | putbit (wps->w.zeros_acc & 1, &wps->wvbits); | 647 | putbit (w->zeros_acc & 1, bs); |
662 | wps->w.zeros_acc >>= 1; | 648 | w->zeros_acc >>= 1; |
663 | } | 649 | } |
664 | 650 | ||
665 | wps->w.zeros_acc = 0; | 651 | w->zeros_acc = 0; |
666 | } | 652 | } |
667 | 653 | ||
668 | if (wps->w.holding_one) { | 654 | if (w->holding_one) { |
669 | if (wps->w.holding_one >= LIMIT_ONES) { | 655 | if (w->holding_one >= LIMIT_ONES) { |
670 | int cbits; | 656 | putbits ((1L << LIMIT_ONES) - 1, LIMIT_ONES + 1, bs); |
671 | 657 | w->holding_one -= LIMIT_ONES; | |
672 | putbits ((1L << LIMIT_ONES) - 1, LIMIT_ONES + 1, &wps->wvbits); | 658 | cbits = count_bits (w->holding_one); |
673 | wps->w.holding_one -= LIMIT_ONES; | ||
674 | cbits = count_bits (wps->w.holding_one); | ||
675 | 659 | ||
676 | while (cbits--) { | 660 | while (cbits--) { |
677 | putbit_1 (&wps->wvbits); | 661 | putbit_1 (bs); |
678 | } | 662 | } |
679 | 663 | ||
680 | putbit_0 (&wps->wvbits); | 664 | putbit_0 (bs); |
681 | 665 | ||
682 | while (wps->w.holding_one > 1) { | 666 | while (w->holding_one > 1) { |
683 | putbit (wps->w.holding_one & 1, &wps->wvbits); | 667 | putbit (w->holding_one & 1, bs); |
684 | wps->w.holding_one >>= 1; | 668 | w->holding_one >>= 1; |
685 | } | 669 | } |
686 | 670 | ||
687 | wps->w.holding_zero = 0; | 671 | w->holding_zero = 0; |
688 | } | 672 | } |
689 | else | 673 | else |
690 | putbits (bitmask [wps->w.holding_one], wps->w.holding_one, &wps->wvbits); | 674 | putbits ((1L << w->holding_one) - 1, w->holding_one, bs); |
691 | 675 | ||
692 | wps->w.holding_one = 0; | 676 | w->holding_one = 0; |
693 | } | 677 | } |
694 | 678 | ||
695 | if (wps->w.holding_zero) { | 679 | if (w->holding_zero) { |
696 | putbit_0 (&wps->wvbits); | 680 | putbit_0 (bs); |
697 | wps->w.holding_zero = 0; | 681 | w->holding_zero = 0; |
698 | } | 682 | } |
699 | 683 | ||
700 | if (wps->w.pend_count) { | 684 | if (w->pend_count) { |
701 | 685 | ||
702 | while (wps->w.pend_count > 24) { | 686 | while (w->pend_count > 24) { |
703 | putbit (wps->w.pend_data & 1, &wps->wvbits); | 687 | putbit (w->pend_data & 1, bs); |
704 | wps->w.pend_data >>= 1; | 688 | w->pend_data >>= 1; |
705 | wps->w.pend_count--; | 689 | w->pend_count--; |
706 | } | 690 | } |
707 | 691 | ||
708 | putbits (wps->w.pend_data, wps->w.pend_count, &wps->wvbits); | 692 | putbits (w->pend_data, w->pend_count, bs); |
709 | wps->w.pend_data = wps->w.pend_count = 0; | 693 | w->pend_data = w->pend_count = 0; |
710 | } | 694 | } |
711 | } | 695 | } |
712 | 696 | ||