vgmstream/src/coding/vorbis_custom_utils_ogl.c

78 lines
3.0 KiB
C
Raw Normal View History

#include "vorbis_custom_decoder.h"
#ifdef VGM_USE_VORBIS
#include <vorbis/codec.h>
/* **************************************************************************** */
/* EXTERNAL API */
/* **************************************************************************** */
/**
* OGL removes the Ogg layer and uses 16b packet headers, that have the size of the next packet, but
* the lower 2b need to be removed (usually 00 but 01 for the id packet, not sure about the meaning).
*/
int vorbis_custom_setup_init_ogl(STREAMFILE *streamFile, off_t start_offset, vorbis_custom_codec_data *data) {
off_t offset = start_offset;
size_t packet_size;
/* read 3 packets with triad (id/comment/setup), each with an OGL header */
/* normal identificacion packet */
packet_size = (uint16_t)read_16bitLE(offset, streamFile) >> 2;
if (packet_size > data->buffer_size) goto fail;
data->op.bytes = read_streamfile(data->buffer,offset+2,packet_size, streamFile);
if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) goto fail; /* parse identification header */
offset += 2+packet_size;
/* normal comment packet */
packet_size = (uint16_t)read_16bitLE(offset, streamFile) >> 2;
if (packet_size > data->buffer_size) goto fail;
data->op.bytes = read_streamfile(data->buffer,offset+2,packet_size, streamFile);
if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) !=0 ) goto fail; /* parse comment header */
offset += 2+packet_size;
/* normal setup packet */
packet_size = (uint16_t)read_16bitLE(offset, streamFile) >> 2;
if (packet_size > data->buffer_size) goto fail;
data->op.bytes = read_streamfile(data->buffer,offset+2,packet_size, streamFile);
if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) goto fail; /* parse setup header */
offset += 2+packet_size;
/* data starts after triad */
data->config.data_start_offset = offset;
return 1;
fail:
return 0;
}
int vorbis_custom_parse_packet_ogl(VGMSTREAMCHANNEL *stream, vorbis_custom_codec_data *data) {
size_t bytes;
/* get next packet size from the OGL 16b header (upper 14b) */
data->op.bytes = (uint16_t)read_16bitLE(stream->offset, stream->streamfile) >> 2;
stream->offset += 2;
if (data->op.bytes == 0 || data->op.bytes == 0xFFFF || data->op.bytes > data->buffer_size) {
VGM_LOG("OGL Vorbis: wrong packet (0x%lx) @ %lx\n", data->op.bytes, stream->offset-2);
goto fail; /* EOF or end padding */
}
/* read raw block */
bytes = read_streamfile(data->buffer,stream->offset, data->op.bytes,stream->streamfile);
stream->offset += data->op.bytes;
if (bytes != data->op.bytes) {
VGM_LOG("OGL Vorbis: wrong bytes (0x%lx) @ %lx\n", data->op.bytes, stream->offset-bytes);
goto fail; /* wrong packet? */
}
return 1;
fail:
return 0;
}
#endif