Exemplo n.º 1
0
ogg_status
read_ogg_page_header(BitstreamReader *ogg_stream,
                     struct ogg_page_header *header) {
    unsigned i;
    struct bs_callback callback;

    if ((header->magic_number =
         ogg_stream->read(ogg_stream, 32)) != 0x5367674F) {
        return OGG_INVALID_MAGIC_NUMBER;
    }

    if ((header->version = ogg_stream->read(ogg_stream, 8)) != 0) {
        return OGG_INVALID_STREAM_VERSION;
    }

    header->packet_continuation = ogg_stream->read(ogg_stream, 1);
    header->stream_beginning = ogg_stream->read(ogg_stream, 1);
    header->stream_end = ogg_stream->read(ogg_stream, 1);
    ogg_stream->skip(ogg_stream, 5);
    header->granule_position = ogg_stream->read_signed_64(ogg_stream, 64);
    header->bitstream_serial_number = ogg_stream->read(ogg_stream, 32);
    header->sequence_number = ogg_stream->read(ogg_stream, 32);

    /*the checksum field is *not* checksummed itself, naturally
      those 4 bytes are treated as 0*/
    ogg_stream->pop_callback(ogg_stream, &callback);
    if (!setjmp(*br_try(ogg_stream))) {
        header->checksum = ogg_stream->read(ogg_stream, 32);
        br_etry(ogg_stream);
        ogg_stream->push_callback(ogg_stream, &callback);
    } else {
        /*restore callback before propagating read error*/
        br_etry(ogg_stream);
        ogg_stream->push_callback(ogg_stream, &callback);
        br_abort(ogg_stream);
    }
    ogg_stream->call_callbacks(ogg_stream, 0);
    ogg_stream->call_callbacks(ogg_stream, 0);
    ogg_stream->call_callbacks(ogg_stream, 0);
    ogg_stream->call_callbacks(ogg_stream, 0);

    header->segment_count = ogg_stream->read(ogg_stream, 8);
    for (i = 0; i < header->segment_count; i++) {
        header->segment_lengths[i] = ogg_stream->read(ogg_stream, 8);
    }

    return OGG_OK;
}
Exemplo n.º 2
0
flac_status
flacdec_read_frame_header(BitstreamReader *bitstream,
                          struct flac_STREAMINFO *streaminfo,
                          struct flac_frame_header *header)
{
    unsigned block_size_bits;
    unsigned sample_rate_bits;
    uint8_t crc8 = 0;

    if (!setjmp(*br_try(bitstream))) {
        br_add_callback(bitstream, (bs_callback_f)flac_crc8, &crc8);

        /*read and verify sync code*/
        if (bitstream->read(bitstream, 14) != 0x3FFE) {
            br_pop_callback(bitstream, NULL);
            br_etry(bitstream);
            return ERR_INVALID_SYNC_CODE;
        }

        /*read and verify reserved bit*/
        if (bitstream->read(bitstream, 1) != 0) {
            br_pop_callback(bitstream, NULL);
            br_etry(bitstream);
            return ERR_INVALID_RESERVED_BIT;
        }

        header->blocking_strategy = bitstream->read(bitstream, 1);

        block_size_bits = bitstream->read(bitstream, 4);
        sample_rate_bits = bitstream->read(bitstream, 4);
        header->channel_assignment = bitstream->read(bitstream, 4);
        switch (header->channel_assignment) {
        case 0x8:
        case 0x9:
        case 0xA:
            header->channel_count = 2;
            break;
        default:
            header->channel_count = header->channel_assignment + 1;
            break;
        }

        switch (bitstream->read(bitstream, 3)) {
        case 0:
            header->bits_per_sample = streaminfo->bits_per_sample;
            break;
        case 1:
            header->bits_per_sample = 8; break;
        case 2:
            header->bits_per_sample = 12; break;
        case 4:
            header->bits_per_sample = 16; break;
        case 5:
            header->bits_per_sample = 20; break;
        case 6:
            header->bits_per_sample = 24; break;
        default:
            return ERR_INVALID_BITS_PER_SAMPLE;
        }
        bitstream->read(bitstream, 1); /*padding*/

        header->frame_number = read_utf8(bitstream);

        switch (block_size_bits) {
        case 0x0: header->block_size = streaminfo->maximum_block_size;
            break;
        case 0x1: header->block_size = 192; break;
        case 0x2: header->block_size = 576; break;
        case 0x3: header->block_size = 1152; break;
        case 0x4: header->block_size = 2304; break;
        case 0x5: header->block_size = 4608; break;
        case 0x6: header->block_size = bitstream->read(bitstream, 8) + 1;
            break;
        case 0x7: header->block_size = bitstream->read(bitstream, 16) + 1;
            break;
        case 0x8: header->block_size = 256; break;
        case 0x9: header->block_size = 512; break;
        case 0xA: header->block_size = 1024; break;
        case 0xB: header->block_size = 2048; break;
        case 0xC: header->block_size = 4096; break;
        case 0xD: header->block_size = 8192; break;
        case 0xE: header->block_size = 16384; break;
        case 0xF: header->block_size = 32768; break;
        }

        switch (sample_rate_bits) {
        case 0x0: header->sample_rate = streaminfo->sample_rate; break;
        case 0x1: header->sample_rate = 88200; break;
        case 0x2: header->sample_rate = 176400; break;
        case 0x3: header->sample_rate = 192000; break;
        case 0x4: header->sample_rate = 8000; break;
        case 0x5: header->sample_rate = 16000; break;
        case 0x6: header->sample_rate = 22050; break;
        case 0x7: header->sample_rate = 24000; break;
        case 0x8: header->sample_rate = 32000; break;
        case 0x9: header->sample_rate = 44100; break;
        case 0xA: header->sample_rate = 48000; break;
        case 0xB: header->sample_rate = 96000; break;
        case 0xC: header->sample_rate = bitstream->read(bitstream, 8) * 1000;
            break;
        case 0xD: header->sample_rate = bitstream->read(bitstream, 16);
            break;
        case 0xE: header->sample_rate = bitstream->read(bitstream, 16) * 10;
            break;
        case 0xF:
            return ERR_INVALID_SAMPLE_RATE;
        }

        /*check for valid CRC-8 value*/
        bitstream->read(bitstream, 8);

        /*no more I/O after this point*/
        br_pop_callback(bitstream, NULL);
        br_etry(bitstream);

        if (crc8 != 0)
            return ERR_INVALID_FRAME_CRC;

        /*Once we've read everything,
          ensure the values are compatible with STREAMINFO.*/

        if (streaminfo->sample_rate != header->sample_rate) {
            return ERR_SAMPLE_RATE_MISMATCH;
        }
        if (streaminfo->channels != header->channel_count) {
            return ERR_CHANNEL_COUNT_MISMATCH;
        }
        if (streaminfo->bits_per_sample != header->bits_per_sample) {
            return ERR_BITS_PER_SAMPLE_MISMATCH;
        }
        if (header->block_size > streaminfo->maximum_block_size) {
            return ERR_MAXIMUM_BLOCK_SIZE_EXCEEDED;
        }

        return OK;
    } else {
        /*push read error to calling function*/
        br_pop_callback(bitstream, NULL);
        br_etry(bitstream);
        br_abort(bitstream);
        return OK;  /*won't get here*/
    }
}