FastLED 3.9.15
Loading...
Searching...
No Matches

◆ start_decoder()

static int32_t fl::third_party::vorbis::start_decoder ( vorb * f)
static

Definition at line 3310 of file stb_vorbis.cpp.hpp.

3311{
3312
3313 uint8 header[6], x,y;
3314 int32_t len,i,j,k, max_submaps = 0;
3315 int32_t longest_floorlist=0;
3316
3317 // first page, first packet
3318 f->first_decode = true;
3319
3320
3321 if (!start_page(f)) return false;
3322 // validate page flag
3326 // check for expected packet length
3327 if (f->segment_count != 1) return error(f, VORBIS_invalid_first_page);
3328 if (f->segments[0] != 30) {
3329 // check for the Ogg skeleton fishead identifying header to refine our error
3330 if (f->segments[0] == 64 &&
3331 getn(f, header, 6) &&
3332 header[0] == 'f' &&
3333 header[1] == 'i' &&
3334 header[2] == 's' &&
3335 header[3] == 'h' &&
3336 header[4] == 'e' &&
3337 header[5] == 'a' &&
3338 get8(f) == 'd' &&
3339 get8(f) == '\0') return error(f, VORBIS_ogg_skeleton_not_supported);
3340 else
3342 }
3343
3344 // read packet
3345 // check packet header
3347 if (!getn(f, header, 6)) return error(f, VORBIS_unexpected_eof);
3348 if (!vorbis_validate(header)) return error(f, VORBIS_invalid_first_page);
3349 // vorbis_version
3350 if (get32(f) != 0) return error(f, VORBIS_invalid_first_page);
3351 f->channels = get8(f); if (!f->channels) return error(f, VORBIS_invalid_first_page);
3353 f->sample_rate = get32(f); if (!f->sample_rate) return error(f, VORBIS_invalid_first_page);
3354 get32(f); // bitrate_maximum
3355 get32(f); // bitrate_nominal
3356 get32(f); // bitrate_minimum
3357 x = get8(f);
3358 {
3359 int32_t log0,log1;
3360 log0 = x & 15;
3361 log1 = x >> 4;
3362 f->blocksize_0 = 1 << log0;
3363 f->blocksize_1 = 1 << log1;
3364 if (log0 < 6 || log0 > 13) return error(f, VORBIS_invalid_setup);
3365 if (log1 < 6 || log1 > 13) return error(f, VORBIS_invalid_setup);
3366 if (log0 > log1) return error(f, VORBIS_invalid_setup);
3367 }
3368
3369 // framing_flag
3370 x = get8(f);
3371 if (!(x & 1)) return error(f, VORBIS_invalid_first_page);
3372
3373
3374
3375 // second packet!
3376
3377 if (!start_page(f)) return false;
3378
3379 if (!start_packet(f)) return false;
3380
3381 if (!next_segment(f)) return false;
3382
3384 for (i=0; i < 6; ++i) header[i] = get8_packet(f);
3385 if (!vorbis_validate(header)) return error(f, VORBIS_invalid_setup);
3386 //file vendor
3387 len = get32_packet(f);
3388 f->vendor = (char*)setup_malloc(f, sizeof(char) * (len+1));
3389 if (f->vendor == nullptr) return error(f, VORBIS_outofmem);
3390 for(i=0; i < len; ++i) {
3391 f->vendor[i] = get8_packet(f);
3392 }
3393 f->vendor[len] = (char)'\0';
3394 //user comments
3396 f->comment_list = nullptr;
3397 if (f->comment_list_length > 0)
3398 {
3399 f->comment_list = (char**) setup_malloc(f, sizeof(char*) * (f->comment_list_length));
3400 if (f->comment_list == nullptr) return error(f, VORBIS_outofmem);
3401 }
3402
3403 for(i=0; i < f->comment_list_length; ++i) {
3404 len = get32_packet(f);
3405 f->comment_list[i] = (char*)setup_malloc(f, sizeof(char) * (len+1));
3406 if (f->comment_list[i] == nullptr) return error(f, VORBIS_outofmem);
3407
3408 for(j=0; j < len; ++j) {
3409 f->comment_list[i][j] = get8_packet(f);
3410 }
3411 f->comment_list[i][len] = (char)'\0';
3412 }
3413
3414 // framing_flag
3415 x = get8_packet(f);
3416 if (!(x & 1)) return error(f, VORBIS_invalid_setup);
3417
3418 skip(f, f->bytes_in_seg);
3419 f->bytes_in_seg = 0;
3420
3421 do {
3422 len = next_segment(f);
3423 skip(f, len);
3424 f->bytes_in_seg = 0;
3425 } while (len);
3426
3427 // third packet!
3428
3429 if (!start_packet(f)) return false;
3430
3431 #ifndef FL_STB_VORBIS_NO_PUSHDATA_API
3432 if (FL_STBV_IS_PUSH_MODE(f)) {
3433 if (!is_whole_packet_present(f)) {
3434 // convert error in ogg header to write type
3435 if (f->error == VORBIS_invalid_stream)
3437 return false;
3438 }
3439 }
3440 #endif
3441
3442 crc32_init(); // always init it, to avoid multithread race conditions
3443
3445 for (i=0; i < 6; ++i) header[i] = get8_packet(f);
3446 if (!vorbis_validate(header)) return error(f, VORBIS_invalid_setup);
3447
3448 // codebooks
3449
3450
3451 f->codebook_count = get_bits(f,8) + 1;
3452
3453 f->codebooks = (Codebook *) setup_malloc(f, sizeof(*f->codebooks) * f->codebook_count);
3454 if (f->codebooks == nullptr) return error(f, VORBIS_outofmem);
3455 memset(f->codebooks, 0, sizeof(*f->codebooks) * f->codebook_count);
3456 for (i=0; i < f->codebook_count; ++i) {
3457
3458 uint32 *values;
3459 int32_t ordered, sorted_count;
3460 int32_t total=0;
3461 uint8 *lengths;
3462 Codebook *c = f->codebooks+i;
3463 FL_STBV_CHECK(f);
3464
3465 x = get_bits(f, 8); if (x != 0x42) return error(f, VORBIS_invalid_setup);
3466 x = get_bits(f, 8); if (x != 0x43) return error(f, VORBIS_invalid_setup);
3467 x = get_bits(f, 8); if (x != 0x56) return error(f, VORBIS_invalid_setup);
3468
3469 x = get_bits(f, 8);
3470 c->dimensions = (get_bits(f, 8)<<8) + x;
3471 x = get_bits(f, 8);
3472 y = get_bits(f, 8);
3473 c->entries = (get_bits(f, 8)<<16) + (y<<8) + x;
3474 ordered = get_bits(f,1);
3475 c->sparse = ordered ? 0 : get_bits(f,1);
3476
3477
3478 if (c->dimensions == 0 && c->entries != 0) return error(f, VORBIS_invalid_setup);
3479
3480 if (c->sparse)
3481 lengths = (uint8 *) setup_temp_malloc(f, c->entries);
3482 else
3483 lengths = c->codeword_lengths = (uint8 *) setup_malloc(f, c->entries);
3484
3485 if (!lengths) return error(f, VORBIS_outofmem);
3486
3487 if (ordered) {
3488
3489 int32_t current_entry = 0;
3490 int32_t current_length = get_bits(f,5) + 1;
3491 int32_t loop_counter = 0;
3492 while (current_entry < c->entries) {
3493 if (++loop_counter > 100000) {
3494
3495 return error(f, VORBIS_invalid_setup);
3496 }
3497 int32_t limit = c->entries - current_entry;
3498 int32_t n = get_bits(f, ilog(limit));
3499 if (current_length >= 32) return error(f, VORBIS_invalid_setup);
3500 if (current_entry + n > (int32_t) c->entries) { return error(f, VORBIS_invalid_setup); }
3501 memset(lengths + current_entry, current_length, n);
3502 current_entry += n;
3503 ++current_length;
3504 }
3505
3506 } else {
3507
3508 for (j=0; j < c->entries; ++j) {
3509 int32_t present = c->sparse ? get_bits(f,1) : 1;
3510 if (present) {
3511 lengths[j] = get_bits(f, 5) + 1;
3512 ++total;
3513 if (lengths[j] == 32)
3514 return error(f, VORBIS_invalid_setup);
3515 } else {
3516 lengths[j] = NO_CODE;
3517 }
3518 }
3519
3520 }
3521
3522 if (c->sparse && total >= c->entries >> 2) {
3523 // convert sparse items to non-sparse!
3524 if (c->entries > (int32_t) f->setup_temp_memory_required)
3525 f->setup_temp_memory_required = c->entries;
3526
3527 c->codeword_lengths = (uint8 *) setup_malloc(f, c->entries);
3528 if (c->codeword_lengths == nullptr) return error(f, VORBIS_outofmem);
3529 memcpy(c->codeword_lengths, lengths, c->entries);
3530 setup_temp_free(f, lengths, c->entries); // note this is only safe if there have been no intervening temp mallocs!
3531 lengths = c->codeword_lengths;
3532 c->sparse = 0;
3533 }
3534
3535 // compute the size of the sorted tables
3536 if (c->sparse) {
3537 sorted_count = total;
3538 } else {
3539 sorted_count = 0;
3540 #ifndef FL_STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH
3541 for (j=0; j < c->entries; ++j)
3543 ++sorted_count;
3544 #endif
3545 }
3546
3547 c->sorted_entries = sorted_count;
3548 values = nullptr;
3549
3550 FL_STBV_CHECK(f);
3551 if (!c->sparse) {
3552 c->codewords = (uint32 *) setup_malloc(f, sizeof(c->codewords[0]) * c->entries);
3553 if (!c->codewords) return error(f, VORBIS_outofmem);
3554 } else {
3555 uint32_t size;
3556 if (c->sorted_entries) {
3557 c->codeword_lengths = (uint8 *) setup_malloc(f, c->sorted_entries);
3558 if (!c->codeword_lengths) return error(f, VORBIS_outofmem);
3559 c->codewords = (uint32 *) setup_temp_malloc(f, sizeof(*c->codewords) * c->sorted_entries);
3560 if (!c->codewords) return error(f, VORBIS_outofmem);
3561 values = (uint32 *) setup_temp_malloc(f, sizeof(*values) * c->sorted_entries);
3562 if (!values) return error(f, VORBIS_outofmem);
3563 }
3564 size = c->entries + (sizeof(*c->codewords) + sizeof(*values)) * c->sorted_entries;
3565 if (size > f->setup_temp_memory_required)
3567 }
3568
3569
3570 if (!compute_codewords(c, lengths, c->entries, values)) {
3571 if (c->sparse) setup_temp_free(f, values, 0);
3572 return error(f, VORBIS_invalid_setup);
3573 }
3574
3575
3576 if (c->sorted_entries) {
3577
3578 // allocate an extra slot for sentinels
3579 c->sorted_codewords = (uint32 *) setup_malloc(f, sizeof(*c->sorted_codewords) * (c->sorted_entries+1));
3580 if (c->sorted_codewords == nullptr) return error(f, VORBIS_outofmem);
3581 // allocate an extra slot at the front so that c->sorted_values[-1] is defined
3582 // so that we can catch that case without an extra if
3583 c->sorted_values = ( int32_t *) setup_malloc(f, sizeof(*c->sorted_values ) * (c->sorted_entries+1));
3584 if (c->sorted_values == nullptr) return error(f, VORBIS_outofmem);
3585 ++c->sorted_values;
3586 c->sorted_values[-1] = -1;
3587
3588 compute_sorted_huffman(c, lengths, values);
3589
3590 }
3591
3592 if (c->sparse) {
3593 setup_temp_free(f, values, sizeof(*values)*c->sorted_entries);
3594 setup_temp_free(f, c->codewords, sizeof(*c->codewords)*c->sorted_entries);
3595 setup_temp_free(f, lengths, c->entries);
3596 c->codewords = nullptr;
3597 }
3598
3599
3601
3602
3603 FL_STBV_CHECK(f);
3604 c->lookup_type = get_bits(f, 4);
3605 if (c->lookup_type > 2) return error(f, VORBIS_invalid_setup);
3606 if (c->lookup_type > 0) {
3607 uint16 *mults;
3608 c->minimum_value = float32_unpack(get_bits(f, 32));
3609 c->delta_value = float32_unpack(get_bits(f, 32));
3610 c->value_bits = get_bits(f, 4)+1;
3611 c->sequence_p = get_bits(f,1);
3612 if (c->lookup_type == 1) {
3613 int32_t values = lookup1_values(c->entries, c->dimensions);
3614 if (values < 0) return error(f, VORBIS_invalid_setup);
3615 c->lookup_values = (uint32) values;
3616 } else {
3617 c->lookup_values = c->entries * c->dimensions;
3618 }
3619 if (c->lookup_values == 0) return error(f, VORBIS_invalid_setup);
3620 mults = (uint16 *) setup_temp_malloc(f, sizeof(mults[0]) * c->lookup_values);
3621 if (mults == nullptr) return error(f, VORBIS_outofmem);
3622 for (j=0; j < (int32_t) c->lookup_values; ++j) {
3623 int32_t q = get_bits(f, c->value_bits);
3624 if (q == EOP) { setup_temp_free(f,mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_invalid_setup); }
3625 mults[j] = q;
3626 }
3627
3628#ifndef FL_STB_VORBIS_DIVIDES_IN_CODEBOOK
3629 if (c->lookup_type == 1) {
3630 int32_t len, sparse = c->sparse;
3631 float last=0;
3632 // pre-expand the lookup1-style multiplicands, to avoid a divide in the inner loop
3633 if (sparse) {
3634 if (c->sorted_entries == 0) goto skip;
3635 c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->sorted_entries * c->dimensions);
3636 } else
3637 c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->entries * c->dimensions);
3638 if (c->multiplicands == nullptr) { setup_temp_free(f,mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_outofmem); }
3639 len = sparse ? c->sorted_entries : c->entries;
3640 for (j=0; j < len; ++j) {
3641 uint32_t z = sparse ? c->sorted_values[j] : j;
3642 uint32_t div=1;
3643 for (k=0; k < c->dimensions; ++k) {
3644 int32_t off = (z / div) % c->lookup_values;
3645 float val = mults[off]*c->delta_value + c->minimum_value + last;
3646 c->multiplicands[j*c->dimensions + k] = val;
3647 if (c->sequence_p)
3648 last = val;
3649 if (k+1 < c->dimensions) {
3650 if (div > fl::numeric_limits<uint32_t>::max() / (uint32_t) c->lookup_values) {
3651 setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values);
3652 return error(f, VORBIS_invalid_setup);
3653 }
3654 div *= c->lookup_values;
3655 }
3656 }
3657 }
3658 c->lookup_type = 2;
3659 }
3660 else
3661#endif
3662 {
3663 float last=0;
3664 FL_STBV_CHECK(f);
3665 c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->lookup_values);
3666 if (c->multiplicands == nullptr) { setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_outofmem); }
3667 for (j=0; j < (int32_t) c->lookup_values; ++j) {
3668 float val = mults[j] * c->delta_value + c->minimum_value + last;
3669 c->multiplicands[j] = val;
3670 if (c->sequence_p)
3671 last = val;
3672 }
3673 }
3674#ifndef FL_STB_VORBIS_DIVIDES_IN_CODEBOOK
3675 skip:;
3676#endif
3677 setup_temp_free(f, mults, sizeof(mults[0])*c->lookup_values);
3678
3679 FL_STBV_CHECK(f);
3680 }
3681 FL_STBV_CHECK(f);
3682 }
3683
3684 // time domain transfers (notused)
3685
3686 x = get_bits(f, 6) + 1;
3687 for (i=0; i < x; ++i) {
3688 uint32 z = get_bits(f, 16);
3689 if (z != 0) return error(f, VORBIS_invalid_setup);
3690 }
3691
3692 // Floors
3693 f->floor_count = get_bits(f, 6)+1;
3694 f->floor_config = (Floor *) setup_malloc(f, f->floor_count * sizeof(*f->floor_config));
3695 if (f->floor_config == nullptr) return error(f, VORBIS_outofmem);
3696 for (i=0; i < f->floor_count; ++i) {
3697 f->floor_types[i] = get_bits(f, 16);
3698 if (f->floor_types[i] > 1) return error(f, VORBIS_invalid_setup);
3699 if (f->floor_types[i] == 0) {
3700 Floor0 *g = &f->floor_config[i].floor0;
3701 g->order = get_bits(f,8);
3702 g->rate = get_bits(f,16);
3703 g->bark_map_size = get_bits(f,16);
3704 g->amplitude_bits = get_bits(f,6);
3705 g->amplitude_offset = get_bits(f,8);
3706 g->number_of_books = get_bits(f,4) + 1;
3707 for (j=0; j < g->number_of_books; ++j)
3708 g->book_list[j] = get_bits(f,8);
3710 } else {
3711 stbv__floor_ordering p[31*8+2];
3712 Floor1 *g = &f->floor_config[i].floor1;
3713 int32_t max_class = -1;
3714 g->partitions = get_bits(f, 5);
3715 for (j=0; j < g->partitions; ++j) {
3716 g->partition_class_list[j] = get_bits(f, 4);
3717 if (g->partition_class_list[j] > max_class)
3718 max_class = g->partition_class_list[j];
3719 }
3720 for (j=0; j <= max_class; ++j) {
3721 g->class_dimensions[j] = get_bits(f, 3)+1;
3722 g->class_subclasses[j] = get_bits(f, 2);
3723 if (g->class_subclasses[j]) {
3724 g->class_masterbooks[j] = get_bits(f, 8);
3725 if (g->class_masterbooks[j] >= f->codebook_count) return error(f, VORBIS_invalid_setup);
3726 }
3727 for (k=0; k < 1 << g->class_subclasses[j]; ++k) {
3728 g->subclass_books[j][k] = (int16)get_bits(f,8)-1;
3729 if (g->subclass_books[j][k] >= f->codebook_count) return error(f, VORBIS_invalid_setup);
3730 }
3731 }
3732 g->floor1_multiplier = get_bits(f,2)+1;
3733 g->rangebits = get_bits(f,4);
3734 g->Xlist[0] = 0;
3735 g->Xlist[1] = 1 << g->rangebits;
3736 g->values = 2;
3737 for (j=0; j < g->partitions; ++j) {
3738 int32_t c = g->partition_class_list[j];
3739 for (k=0; k < g->class_dimensions[c]; ++k) {
3740 g->Xlist[g->values] = get_bits(f, g->rangebits);
3741 ++g->values;
3742 }
3743 }
3744 // precompute the sorting
3745 for (j=0; j < g->values; ++j) {
3746 p[j].x = g->Xlist[j];
3747 p[j].id = j;
3748 }
3749 fl::qsort(p, g->values, sizeof(p[0]), point_compare);
3750 for (j=0; j < g->values-1; ++j)
3751 if (p[j].x == p[j+1].x)
3752 return error(f, VORBIS_invalid_setup);
3753 for (j=0; j < g->values; ++j)
3754 g->sorted_order[j] = (uint8) p[j].id;
3755 // precompute the neighbors
3756 for (j=2; j < g->values; ++j) {
3757 int32_t low = 0,hi = 0;
3758 neighbors(g->Xlist, j, &low,&hi);
3759 g->neighbors[j][0] = low;
3760 g->neighbors[j][1] = hi;
3761 }
3762
3763 if (g->values > longest_floorlist)
3764 longest_floorlist = g->values;
3765 }
3766 }
3767
3768 // Residue
3769 f->residue_count = get_bits(f, 6)+1;
3770 f->residue_config = (Residue *) setup_malloc(f, f->residue_count * sizeof(f->residue_config[0]));
3771 if (f->residue_config == nullptr) return error(f, VORBIS_outofmem);
3772 memset(f->residue_config, 0, f->residue_count * sizeof(f->residue_config[0]));
3773 for (i=0; i < f->residue_count; ++i) {
3774 uint8 residue_cascade[64];
3775 Residue *r = f->residue_config+i;
3776 f->residue_types[i] = get_bits(f, 16);
3777 if (f->residue_types[i] > 2) return error(f, VORBIS_invalid_setup);
3778 r->begin = get_bits(f, 24);
3779 r->end = get_bits(f, 24);
3780 if (r->end < r->begin) return error(f, VORBIS_invalid_setup);
3781 r->part_size = get_bits(f,24)+1;
3782 r->classifications = get_bits(f,6)+1;
3783 r->classbook = get_bits(f,8);
3784 if (r->classbook >= f->codebook_count) return error(f, VORBIS_invalid_setup);
3785 for (j=0; j < r->classifications; ++j) {
3786 uint8 high_bits=0;
3787 uint8 low_bits=get_bits(f,3);
3788 if (get_bits(f,1))
3789 high_bits = get_bits(f,5);
3790 residue_cascade[j] = high_bits*8 + low_bits;
3791 }
3792 r->residue_books = (short (*)[8]) setup_malloc(f, sizeof(r->residue_books[0]) * r->classifications);
3793 if (r->residue_books == nullptr) return error(f, VORBIS_outofmem);
3794 for (j=0; j < r->classifications; ++j) {
3795 for (k=0; k < 8; ++k) {
3796 if (residue_cascade[j] & (1 << k)) {
3797 r->residue_books[j][k] = get_bits(f, 8);
3798 if (r->residue_books[j][k] >= f->codebook_count) return error(f, VORBIS_invalid_setup);
3799 } else {
3800 r->residue_books[j][k] = -1;
3801 }
3802 }
3803 }
3804 // precompute the classifications[] array to avoid inner-loop mod/divide
3805 // call it 'classdata' since we already have r->classifications
3806 r->classdata = (uint8 **) setup_malloc(f, sizeof(*r->classdata) * f->codebooks[r->classbook].entries);
3807 if (!r->classdata) return error(f, VORBIS_outofmem);
3808 memset(r->classdata, 0, sizeof(*r->classdata) * f->codebooks[r->classbook].entries);
3809 for (j=0; j < f->codebooks[r->classbook].entries; ++j) {
3810 int32_t classwords = f->codebooks[r->classbook].dimensions;
3811 int32_t temp = j;
3812 r->classdata[j] = (uint8 *) setup_malloc(f, sizeof(r->classdata[j][0]) * classwords);
3813 if (r->classdata[j] == nullptr) return error(f, VORBIS_outofmem);
3814 for (k=classwords-1; k >= 0; --k) {
3815 r->classdata[j][k] = temp % r->classifications;
3816 temp /= r->classifications;
3817 }
3818 }
3819 }
3820
3821 f->mapping_count = get_bits(f,6)+1;
3822 f->mapping = (Mapping *) setup_malloc(f, f->mapping_count * sizeof(*f->mapping));
3823 if (f->mapping == nullptr) return error(f, VORBIS_outofmem);
3824 memset(f->mapping, 0, f->mapping_count * sizeof(*f->mapping));
3825 for (i=0; i < f->mapping_count; ++i) {
3826 Mapping *m = f->mapping + i;
3827 int32_t mapping_type = get_bits(f,16);
3828 if (mapping_type != 0) return error(f, VORBIS_invalid_setup);
3829 m->chan = (MappingChannel *) setup_malloc(f, f->channels * sizeof(*m->chan));
3830 if (m->chan == nullptr) return error(f, VORBIS_outofmem);
3831 if (get_bits(f,1))
3832 m->submaps = get_bits(f,4)+1;
3833 else
3834 m->submaps = 1;
3835 if (m->submaps > max_submaps)
3836 max_submaps = m->submaps;
3837 if (get_bits(f,1)) {
3838 m->coupling_steps = get_bits(f,8)+1;
3839 if (m->coupling_steps > f->channels) return error(f, VORBIS_invalid_setup);
3840 for (k=0; k < m->coupling_steps; ++k) {
3841 m->chan[k].magnitude = get_bits(f, ilog(f->channels-1));
3842 m->chan[k].angle = get_bits(f, ilog(f->channels-1));
3843 if (m->chan[k].magnitude >= f->channels) return error(f, VORBIS_invalid_setup);
3844 if (m->chan[k].angle >= f->channels) return error(f, VORBIS_invalid_setup);
3845 if (m->chan[k].magnitude == m->chan[k].angle) return error(f, VORBIS_invalid_setup);
3846 }
3847 } else
3848 m->coupling_steps = 0;
3849
3850 // reserved field
3851 if (get_bits(f,2)) return error(f, VORBIS_invalid_setup);
3852 if (m->submaps > 1) {
3853 for (j=0; j < f->channels; ++j) {
3854 m->chan[j].mux = get_bits(f, 4);
3855 if (m->chan[j].mux >= m->submaps) return error(f, VORBIS_invalid_setup);
3856 }
3857 } else
3858 // @SPECIFICATION: this case is missing from the spec
3859 for (j=0; j < f->channels; ++j)
3860 m->chan[j].mux = 0;
3861
3862 for (j=0; j < m->submaps; ++j) {
3863 get_bits(f,8); // discard
3864 m->submap_floor[j] = get_bits(f,8);
3865 m->submap_residue[j] = get_bits(f,8);
3866 if (m->submap_floor[j] >= f->floor_count) return error(f, VORBIS_invalid_setup);
3867 if (m->submap_residue[j] >= f->residue_count) return error(f, VORBIS_invalid_setup);
3868 }
3869 }
3870
3871 // Modes
3872 f->mode_count = get_bits(f, 6)+1;
3873 for (i=0; i < f->mode_count; ++i) {
3874 Mode *m = f->mode_config+i;
3875 m->blockflag = get_bits(f,1);
3876 m->windowtype = get_bits(f,16);
3877 m->transformtype = get_bits(f,16);
3878 m->mapping = get_bits(f,8);
3879 if (m->windowtype != 0) return error(f, VORBIS_invalid_setup);
3880 if (m->transformtype != 0) return error(f, VORBIS_invalid_setup);
3881 if (m->mapping >= f->mapping_count) return error(f, VORBIS_invalid_setup);
3882 }
3883
3884 flush_packet(f);
3885
3886 f->previous_length = 0;
3887
3888 for (i=0; i < f->channels; ++i) {
3889 f->channel_buffers[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1);
3890 f->previous_window[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1/2);
3891 f->finalY[i] = (int16 *) setup_malloc(f, sizeof(int16) * longest_floorlist);
3892 if (f->channel_buffers[i] == nullptr || f->previous_window[i] == nullptr || f->finalY[i] == nullptr) return error(f, VORBIS_outofmem);
3893 memset(f->channel_buffers[i], 0, sizeof(float) * f->blocksize_1);
3894 #ifdef FL_STB_VORBIS_NO_DEFER_FLOOR
3895 f->floor_buffers[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1/2);
3896 if (f->floor_buffers[i] == nullptr) return error(f, VORBIS_outofmem);
3897 #endif
3898 }
3899
3900 if (!init_blocksize(f, 0, f->blocksize_0)) return false;
3901 if (!init_blocksize(f, 1, f->blocksize_1)) return false;
3902 f->blocksize[0] = f->blocksize_0;
3903 f->blocksize[1] = f->blocksize_1;
3904
3905#ifdef FL_STB_VORBIS_DIVIDE_TABLE
3906 if (integer_divide_table[1][1]==0)
3907 for (i=0; i < DIVTAB_NUMER; ++i)
3908 for (j=1; j < DIVTAB_DENOM; ++j)
3909 integer_divide_table[i][j] = i / j;
3910#endif
3911
3912 // compute how much temporary memory is needed
3913
3914 // 1.
3915 {
3916 uint32 imdct_mem = (f->blocksize_1 * sizeof(float) >> 1);
3917 uint32 classify_mem;
3918 int32_t i,max_part_read=0;
3919 for (i=0; i < f->residue_count; ++i) {
3920 Residue *r = f->residue_config + i;
3921 uint32_t actual_size = f->blocksize_1 / 2;
3922 uint32_t limit_r_begin = r->begin < actual_size ? r->begin : actual_size;
3923 uint32_t limit_r_end = r->end < actual_size ? r->end : actual_size;
3924 int32_t n_read = limit_r_end - limit_r_begin;
3925 int32_t part_read = n_read / r->part_size;
3926 if (part_read > max_part_read)
3927 max_part_read = part_read;
3928 }
3929 #ifndef FL_STB_VORBIS_DIVIDES_IN_RESIDUE
3930 classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(uint8 *));
3931 #else
3932 classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(int32_t*));
3933 #endif
3934
3935 // maximum reasonable partition size is f->blocksize_1
3936
3937 f->temp_memory_required = classify_mem;
3938 if (imdct_mem > f->temp_memory_required)
3939 f->temp_memory_required = imdct_mem;
3940 }
3941
3942
3943 if (f->alloc.alloc_buffer) {
3944 FL_ASSERT(f->temp_offset == f->alloc.alloc_buffer_length_in_bytes, "temp_offset must equal alloc_buffer_length");
3945 // check if there's enough temp memory so we don't error later
3946 if (f->setup_offset + sizeof(*f) + f->temp_memory_required > (unsigned) f->temp_offset)
3947 return error(f, VORBIS_outofmem);
3948 }
3949
3950 // @TODO: stb_vorbis_seek_start expects first_audio_page_offset to point to a page
3951 // without PAGEFLAG_continued_packet, so this either points to the first page, or
3952 // the page after the end of the headers. It might be cleaner to point to a page
3953 // in the middle of the headers, when that's the page where the first audio packet
3954 // starts, but we'd have to also correctly skip the end of any continued packet in
3955 // stb_vorbis_seek_start.
3956 if (f->next_seg == -1) {
3958 } else {
3960 }
3961
3962
3963 return true;
3964}
constexpr int lengths[]
uint32_t z[NUM_LAYERS]
Definition Fire2023.h:93
#define FL_ASSERT(x, MSG)
Definition assert.h:6
void * memcpy(void *dest, const void *src, size_t n) FL_NOEXCEPT
static void flush_packet(vorb *f) FL_NOEXCEPT
static int32_t start_page(vorb *f) FL_NOEXCEPT
static int32_t ilog(int32 n) FL_NOEXCEPT
static int32_t error(vorb *f, enum STBVorbisError e) FL_NOEXCEPT
int8 integer_divide_table[DIVTAB_NUMER][DIVTAB_DENOM]
static constexpr uint8_t NO_CODE
static int32_t init_blocksize(vorb *f, int32_t b, int32_t n) FL_NOEXCEPT
static void setup_temp_free(vorb *f, void *p, int32_t sz) FL_NOEXCEPT
static int32_t is_whole_packet_present(stb_vorbis *f) FL_NOEXCEPT
static constexpr uint8_t PAGEFLAG_last_page
void * memset(void *s, int c, size_t n) FL_NOEXCEPT
static void skip(vorb *z, int32_t n) FL_NOEXCEPT
static constexpr int32_t EOP
static float float32_unpack(uint32 x) FL_NOEXCEPT
static constexpr uint8_t PAGEFLAG_continued_packet
static int32_t vorbis_validate(uint8 *data) FL_NOEXCEPT
static constexpr int32_t DIVTAB_DENOM
static void crc32_init(void) FL_NOEXCEPT
static constexpr int32_t DIVTAB_NUMER
static int32_t getn(vorb *z, uint8 *data, int32_t n) FL_NOEXCEPT
static uint8 get8(vorb *z) FL_NOEXCEPT
static void * setup_malloc(vorb *f, int32_t sz) FL_NOEXCEPT
uint32_t stb_vorbis_get_file_offset(stb_vorbis *f) FL_NOEXCEPT
static void compute_sorted_huffman(Codebook *c, uint8 *lengths, uint32 *values) FL_NOEXCEPT
static int32_t lookup1_values(int32_t entries, int32_t dim) FL_NOEXCEPT
static int32_t compute_codewords(Codebook *c, uint8 *len, int32_t n, uint32 *values) FL_NOEXCEPT
static int32_t start_packet(vorb *f) FL_NOEXCEPT
static void neighbors(uint16 *x, int32_t n, int32_t *plow, int32_t *phigh) FL_NOEXCEPT
static void * setup_temp_malloc(vorb *f, int32_t sz) FL_NOEXCEPT
static int32_t get32_packet(vorb *f) FL_NOEXCEPT
static int point_compare(const void *p, const void *q) FL_NOEXCEPT
static constexpr uint8_t PAGEFLAG_first_page
static uint32 get32(vorb *f) FL_NOEXCEPT
static uint32 get_bits(vorb *f, int32_t n) FL_NOEXCEPT
static void compute_accelerated_huffman(Codebook *c) FL_NOEXCEPT
static int32_t get8_packet(vorb *f) FL_NOEXCEPT
static int32_t next_segment(vorb *f) FL_NOEXCEPT
float * previous_window[FL_STB_VORBIS_MAX_CHANNELS]
int16 * finalY[FL_STB_VORBIS_MAX_CHANNELS]
float * channel_buffers[FL_STB_VORBIS_MAX_CHANNELS]
fl::u32 uint32_t
Definition coder.h:219
fl::i32 int32_t
Definition coder.h:220
void qsort(void *base, size_t nmemb, size_t size, qsort_compare_fn compar)
#define FL_STB_VORBIS_MAX_CHANNELS
#define FL_STB_VORBIS_FAST_HUFFMAN_LENGTH
#define FL_STBV_CHECK(f)
#define FL_STBV_IS_PUSH_MODE(f)
static constexpr T max() FL_NOEXCEPT
Definition limits.h:108

References fl::third_party::vorbis::Floor0::amplitude_bits, fl::third_party::vorbis::Floor0::amplitude_offset, fl::third_party::vorbis::MappingChannel::angle, fl::third_party::vorbis::Floor0::bark_map_size, fl::third_party::vorbis::Residue::begin, fl::third_party::vorbis::Mode::blockflag, fl::third_party::vorbis::Floor0::book_list, fl::third_party::vorbis::Mapping::chan, fl::third_party::vorbis::Floor1::class_dimensions, fl::third_party::vorbis::Floor1::class_masterbooks, fl::third_party::vorbis::Floor1::class_subclasses, fl::third_party::vorbis::Residue::classbook, fl::third_party::vorbis::Residue::classdata, fl::third_party::vorbis::Residue::classifications, fl::third_party::vorbis::Codebook::codeword_lengths, fl::third_party::vorbis::Codebook::codewords, compute_accelerated_huffman(), compute_codewords(), compute_sorted_huffman(), fl::third_party::vorbis::Mapping::coupling_steps, crc32_init(), fl::third_party::vorbis::Codebook::delta_value, fl::third_party::vorbis::Codebook::dimensions, DIVTAB_DENOM, DIVTAB_NUMER, fl::third_party::vorbis::Residue::end, fl::third_party::vorbis::Codebook::entries, EOP, error(), FL_ASSERT, FL_NOEXCEPT, FL_STB_VORBIS_FAST_HUFFMAN_LENGTH, FL_STB_VORBIS_MAX_CHANNELS, FL_STBV_CHECK, FL_STBV_IS_PUSH_MODE, float32_unpack(), fl::third_party::vorbis::Floor1::floor1_multiplier, flush_packet(), get32(), get32_packet(), get8(), get8_packet(), get_bits(), getn(), fl::third_party::vorbis::stbv__floor_ordering::id, ilog(), init_blocksize(), integer_divide_table, is_whole_packet_present(), lengths, lookup1_values(), fl::third_party::vorbis::Codebook::lookup_type, fl::third_party::vorbis::Codebook::lookup_values, fl::third_party::vorbis::MappingChannel::magnitude, fl::third_party::vorbis::Mode::mapping, fl::numeric_limits< T >::max(), memcpy(), memset(), fl::third_party::vorbis::Codebook::minimum_value, fl::third_party::vorbis::Codebook::multiplicands, fl::third_party::vorbis::MappingChannel::mux, fl::third_party::vorbis::Floor1::neighbors, neighbors(), next_segment(), NO_CODE, fl::third_party::vorbis::Floor0::number_of_books, fl::third_party::vorbis::Floor0::order, PAGEFLAG_continued_packet, PAGEFLAG_first_page, PAGEFLAG_last_page, fl::third_party::vorbis::Residue::part_size, fl::third_party::vorbis::Floor1::partition_class_list, fl::third_party::vorbis::Floor1::partitions, point_compare(), fl::qsort(), fl::third_party::vorbis::Floor1::rangebits, fl::third_party::vorbis::Floor0::rate, fl::third_party::vorbis::Residue::residue_books, fl::third_party::vorbis::Codebook::sequence_p, setup_malloc(), setup_temp_free(), setup_temp_malloc(), skip(), fl::third_party::vorbis::Codebook::sorted_codewords, fl::third_party::vorbis::Codebook::sorted_entries, fl::third_party::vorbis::Floor1::sorted_order, fl::third_party::vorbis::Codebook::sorted_values, fl::third_party::vorbis::Codebook::sparse, start_packet(), start_page(), stb_vorbis_get_file_offset(), fl::third_party::vorbis::Floor1::subclass_books, fl::third_party::vorbis::Mapping::submap_floor, fl::third_party::vorbis::Mapping::submap_residue, fl::third_party::vorbis::Mapping::submaps, fl::third_party::vorbis::Mode::transformtype, fl::third_party::vorbis::Codebook::value_bits, fl::third_party::vorbis::Floor1::values, VORBIS_feature_not_supported, VORBIS_invalid_first_page, VORBIS_invalid_setup, VORBIS_invalid_stream, VORBIS_ogg_skeleton_not_supported, VORBIS_outofmem, VORBIS_packet_comment, VORBIS_packet_id, VORBIS_packet_setup, VORBIS_too_many_channels, VORBIS_unexpected_eof, vorbis_validate(), fl::third_party::vorbis::Mode::windowtype, fl::third_party::vorbis::stbv__floor_ordering::x, fl::x, fl::third_party::vorbis::Floor1::Xlist, fl::y, and z.

Referenced by stb_vorbis_open_file_section(), stb_vorbis_open_memory(), and stb_vorbis_open_pushdata().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: