mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
parent
0b1de66bdf
commit
ca52f841b0
12
bam.lua
12
bam.lua
|
@ -182,7 +182,9 @@ function build(settings)
|
|||
end
|
||||
|
||||
opus_settings = settings:Copy()
|
||||
|
||||
opus_settings.cc.flags:Add("-DHAVE_CONFIG_H")
|
||||
|
||||
opus_settings.cc.includes:Add("src/engine/external/opus/")
|
||||
opus_settings.cc.includes:Add("src/engine/external/opus/celt/")
|
||||
opus_settings.cc.includes:Add("src/engine/external/opus/silk/")
|
||||
|
@ -192,11 +194,6 @@ function build(settings)
|
|||
opus_settings.cc.includes:Add("src/engine/external/opus/celt/arm/")
|
||||
opus_settings.cc.includes:Add("src/engine/external/opus/celt/x86/")
|
||||
|
||||
opusfile_settings = settings:Copy()
|
||||
opusfile_settings.cc.includes:Add("src/engine/external/opus/")
|
||||
opusfile_settings.cc.includes:Add("src/engine/external/ogg/")
|
||||
opusfile_settings.cc.includes:Add("src/engine/external/opusfile/")
|
||||
|
||||
-- set some platform specific settings
|
||||
settings.cc.includes:Add("src")
|
||||
settings.cc.includes:Add("other/mysql/include")
|
||||
|
@ -241,8 +238,7 @@ function build(settings)
|
|||
pnglite = Compile(settings, Collect("src/engine/external/pnglite/*.c"))
|
||||
jsonparser = Compile(settings, Collect("src/engine/external/json-parser/*.c"))
|
||||
ogg = Compile(settings, Collect("src/engine/external/ogg/*.c"))
|
||||
opus = Compile(opus_settings, Collect("src/engine/external/opus/*.c", "src/engine/external/opus/celt/*.c", "src/engine/external/opus/silk/*.c"))
|
||||
opusfile = Compile(opusfile_settings, Collect("src/engine/external/opusfile/*.c"))
|
||||
opus= Compile(opus_settings, Collect("src/engine/external/opus/*.c", "src/engine/external/opus/celt/*.c", "src/engine/external/opus/silk/*.c"))
|
||||
|
||||
-- build game components
|
||||
engine_settings = settings:Copy()
|
||||
|
@ -328,7 +324,7 @@ function build(settings)
|
|||
|
||||
-- build client, server, version server and master server
|
||||
client_exe = Link(client_settings, "DDNet", game_shared, game_client,
|
||||
engine, client, game_editor, zlib, pnglite, wavpack, ogg, opus, opusfile,
|
||||
engine, client, game_editor, zlib, pnglite, wavpack, ogg, opus,
|
||||
client_link_other, client_osxlaunch, jsonparser)
|
||||
|
||||
server_exe = Link(server_settings, "DDNet-Server", engine, server,
|
||||
|
|
3391
src/engine/external/opusfile/http.c
vendored
3391
src/engine/external/opusfile/http.c
vendored
File diff suppressed because it is too large
Load diff
687
src/engine/external/opusfile/info.c
vendored
687
src/engine/external/opusfile/info.c
vendored
|
@ -1,687 +0,0 @@
|
|||
/********************************************************************
|
||||
* *
|
||||
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. *
|
||||
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
||||
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2012 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "internal.h"
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
static unsigned op_parse_uint16le(const unsigned char *_data){
|
||||
return _data[0]|_data[1]<<8;
|
||||
}
|
||||
|
||||
static int op_parse_int16le(const unsigned char *_data){
|
||||
int ret;
|
||||
ret=_data[0]|_data[1]<<8;
|
||||
return (ret^0x8000)-0x8000;
|
||||
}
|
||||
|
||||
static opus_uint32 op_parse_uint32le(const unsigned char *_data){
|
||||
return _data[0]|(opus_uint32)_data[1]<<8|
|
||||
(opus_uint32)_data[2]<<16|(opus_uint32)_data[3]<<24;
|
||||
}
|
||||
|
||||
static opus_uint32 op_parse_uint32be(const unsigned char *_data){
|
||||
return _data[3]|(opus_uint32)_data[2]<<8|
|
||||
(opus_uint32)_data[1]<<16|(opus_uint32)_data[0]<<24;
|
||||
}
|
||||
|
||||
int opus_head_parse(OpusHead *_head,const unsigned char *_data,size_t _len){
|
||||
OpusHead head;
|
||||
if(_len<8)return OP_ENOTFORMAT;
|
||||
if(memcmp(_data,"OpusHead",8)!=0)return OP_ENOTFORMAT;
|
||||
if(_len<9)return OP_EBADHEADER;
|
||||
head.version=_data[8];
|
||||
if(head.version>15)return OP_EVERSION;
|
||||
if(_len<19)return OP_EBADHEADER;
|
||||
head.channel_count=_data[9];
|
||||
head.pre_skip=op_parse_uint16le(_data+10);
|
||||
head.input_sample_rate=op_parse_uint32le(_data+12);
|
||||
head.output_gain=op_parse_int16le(_data+16);
|
||||
head.mapping_family=_data[18];
|
||||
if(head.mapping_family==0){
|
||||
if(head.channel_count<1||head.channel_count>2)return OP_EBADHEADER;
|
||||
if(head.version<=1&&_len>19)return OP_EBADHEADER;
|
||||
head.stream_count=1;
|
||||
head.coupled_count=head.channel_count-1;
|
||||
if(_head!=NULL){
|
||||
_head->mapping[0]=0;
|
||||
_head->mapping[1]=1;
|
||||
}
|
||||
}
|
||||
else if(head.mapping_family==1){
|
||||
size_t size;
|
||||
int ci;
|
||||
if(head.channel_count<1||head.channel_count>8)return OP_EBADHEADER;
|
||||
size=21+head.channel_count;
|
||||
if(_len<size||head.version<=1&&_len>size)return OP_EBADHEADER;
|
||||
head.stream_count=_data[19];
|
||||
if(head.stream_count<1)return OP_EBADHEADER;
|
||||
head.coupled_count=_data[20];
|
||||
if(head.coupled_count>head.stream_count)return OP_EBADHEADER;
|
||||
for(ci=0;ci<head.channel_count;ci++){
|
||||
if(_data[21+ci]>=head.stream_count+head.coupled_count
|
||||
&&_data[21+ci]!=255){
|
||||
return OP_EBADHEADER;
|
||||
}
|
||||
}
|
||||
if(_head!=NULL)memcpy(_head->mapping,_data+21,head.channel_count);
|
||||
}
|
||||
/*General purpose players should not attempt to play back content with
|
||||
channel mapping family 255.*/
|
||||
else if(head.mapping_family==255)return OP_EIMPL;
|
||||
/*No other channel mapping families are currently defined.*/
|
||||
else return OP_EBADHEADER;
|
||||
if(_head!=NULL)memcpy(_head,&head,head.mapping-(unsigned char *)&head);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void opus_tags_init(OpusTags *_tags){
|
||||
memset(_tags,0,sizeof(*_tags));
|
||||
}
|
||||
|
||||
void opus_tags_clear(OpusTags *_tags){
|
||||
int ci;
|
||||
for(ci=_tags->comments;ci-->0;)_ogg_free(_tags->user_comments[ci]);
|
||||
_ogg_free(_tags->user_comments);
|
||||
_ogg_free(_tags->comment_lengths);
|
||||
_ogg_free(_tags->vendor);
|
||||
}
|
||||
|
||||
/*Ensure there's room for up to _ncomments comments.*/
|
||||
static int op_tags_ensure_capacity(OpusTags *_tags,size_t _ncomments){
|
||||
char **user_comments;
|
||||
int *comment_lengths;
|
||||
size_t size;
|
||||
if(OP_UNLIKELY(_ncomments>=(size_t)INT_MAX))return OP_EFAULT;
|
||||
size=sizeof(*_tags->comment_lengths)*(_ncomments+1);
|
||||
if(size/sizeof(*_tags->comment_lengths)!=_ncomments+1)return OP_EFAULT;
|
||||
comment_lengths=(int *)_ogg_realloc(_tags->comment_lengths,size);
|
||||
if(OP_UNLIKELY(comment_lengths==NULL))return OP_EFAULT;
|
||||
comment_lengths[_ncomments]=0;
|
||||
_tags->comment_lengths=comment_lengths;
|
||||
size=sizeof(*_tags->user_comments)*(_ncomments+1);
|
||||
if(size/sizeof(*_tags->user_comments)!=_ncomments+1)return OP_EFAULT;
|
||||
user_comments=(char **)_ogg_realloc(_tags->user_comments,size);
|
||||
if(OP_UNLIKELY(user_comments==NULL))return OP_EFAULT;
|
||||
user_comments[_ncomments]=NULL;
|
||||
_tags->user_comments=user_comments;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*Duplicate a (possibly non-NUL terminated) string with a known length.*/
|
||||
static char *op_strdup_with_len(const char *_s,size_t _len){
|
||||
size_t size;
|
||||
char *ret;
|
||||
size=sizeof(*ret)*(_len+1);
|
||||
if(OP_UNLIKELY(size<_len))return NULL;
|
||||
ret=(char *)_ogg_malloc(size);
|
||||
if(OP_LIKELY(ret!=NULL)){
|
||||
ret=(char *)memcpy(ret,_s,sizeof(*ret)*_len);
|
||||
ret[_len]='\0';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*The actual implementation of opus_tags_parse().
|
||||
Unlike the public API, this function requires _tags to already be
|
||||
initialized, modifies its contents before success is guaranteed, and assumes
|
||||
the caller will clear it on error.*/
|
||||
static int opus_tags_parse_impl(OpusTags *_tags,
|
||||
const unsigned char *_data,size_t _len){
|
||||
opus_uint32 count;
|
||||
size_t len;
|
||||
int ncomments;
|
||||
int ci;
|
||||
len=_len;
|
||||
if(len<8)return OP_ENOTFORMAT;
|
||||
if(memcmp(_data,"OpusTags",8)!=0)return OP_ENOTFORMAT;
|
||||
if(len<16)return OP_EBADHEADER;
|
||||
_data+=8;
|
||||
len-=8;
|
||||
count=op_parse_uint32le(_data);
|
||||
_data+=4;
|
||||
len-=4;
|
||||
if(count>len)return OP_EBADHEADER;
|
||||
if(_tags!=NULL){
|
||||
_tags->vendor=op_strdup_with_len((char *)_data,count);
|
||||
if(_tags->vendor==NULL)return OP_EFAULT;
|
||||
}
|
||||
_data+=count;
|
||||
len-=count;
|
||||
if(len<4)return OP_EBADHEADER;
|
||||
count=op_parse_uint32le(_data);
|
||||
_data+=4;
|
||||
len-=4;
|
||||
/*Check to make sure there's minimally sufficient data left in the packet.*/
|
||||
if(count>len>>2)return OP_EBADHEADER;
|
||||
/*Check for overflow (the API limits this to an int).*/
|
||||
if(count>(opus_uint32)INT_MAX-1)return OP_EFAULT;
|
||||
if(_tags!=NULL){
|
||||
int ret;
|
||||
ret=op_tags_ensure_capacity(_tags,count);
|
||||
if(ret<0)return ret;
|
||||
}
|
||||
ncomments=(int)count;
|
||||
for(ci=0;ci<ncomments;ci++){
|
||||
/*Check to make sure there's minimally sufficient data left in the packet.*/
|
||||
if((size_t)(ncomments-ci)>len>>2)return OP_EBADHEADER;
|
||||
count=op_parse_uint32le(_data);
|
||||
_data+=4;
|
||||
len-=4;
|
||||
if(count>len)return OP_EBADHEADER;
|
||||
/*Check for overflow (the API limits this to an int).*/
|
||||
if(count>(opus_uint32)INT_MAX)return OP_EFAULT;
|
||||
if(_tags!=NULL){
|
||||
_tags->user_comments[ci]=op_strdup_with_len((char *)_data,count);
|
||||
if(_tags->user_comments[ci]==NULL)return OP_EFAULT;
|
||||
_tags->comment_lengths[ci]=(int)count;
|
||||
_tags->comments=ci+1;
|
||||
}
|
||||
_data+=count;
|
||||
len-=count;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opus_tags_parse(OpusTags *_tags,const unsigned char *_data,size_t _len){
|
||||
if(_tags!=NULL){
|
||||
OpusTags tags;
|
||||
int ret;
|
||||
opus_tags_init(&tags);
|
||||
ret=opus_tags_parse_impl(&tags,_data,_len);
|
||||
if(ret<0)opus_tags_clear(&tags);
|
||||
else *_tags=*&tags;
|
||||
return ret;
|
||||
}
|
||||
else return opus_tags_parse_impl(NULL,_data,_len);
|
||||
}
|
||||
|
||||
/*The actual implementation of opus_tags_copy().
|
||||
Unlike the public API, this function requires _dst to already be
|
||||
initialized, modifies its contents before success is guaranteed, and assumes
|
||||
the caller will clear it on error.*/
|
||||
static int opus_tags_copy_impl(OpusTags *_dst,const OpusTags *_src){
|
||||
char *vendor;
|
||||
int ncomments;
|
||||
int ret;
|
||||
int ci;
|
||||
vendor=_src->vendor;
|
||||
_dst->vendor=op_strdup_with_len(vendor,strlen(vendor));
|
||||
if(OP_UNLIKELY(_dst->vendor==NULL))return OP_EFAULT;
|
||||
ncomments=_src->comments;
|
||||
ret=op_tags_ensure_capacity(_dst,ncomments);
|
||||
if(OP_UNLIKELY(ret<0))return ret;
|
||||
for(ci=0;ci<ncomments;ci++){
|
||||
int len;
|
||||
len=_src->comment_lengths[ci];
|
||||
OP_ASSERT(len>=0);
|
||||
_dst->user_comments[ci]=op_strdup_with_len(_src->user_comments[ci],len);
|
||||
if(OP_UNLIKELY(_dst->user_comments[ci]==NULL))return OP_EFAULT;
|
||||
_dst->comment_lengths[ci]=len;
|
||||
_dst->comments=ci+1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opus_tags_copy(OpusTags *_dst,const OpusTags *_src){
|
||||
OpusTags dst;
|
||||
int ret;
|
||||
opus_tags_init(&dst);
|
||||
ret=opus_tags_copy_impl(&dst,_src);
|
||||
if(OP_UNLIKELY(ret<0))opus_tags_clear(&dst);
|
||||
else *_dst=*&dst;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opus_tags_add(OpusTags *_tags,const char *_tag,const char *_value){
|
||||
char *comment;
|
||||
int tag_len;
|
||||
int value_len;
|
||||
int ncomments;
|
||||
int ret;
|
||||
ncomments=_tags->comments;
|
||||
ret=op_tags_ensure_capacity(_tags,ncomments+1);
|
||||
if(OP_UNLIKELY(ret<0))return ret;
|
||||
tag_len=strlen(_tag);
|
||||
value_len=strlen(_value);
|
||||
/*+2 for '=' and '\0'.*/
|
||||
_tags->comment_lengths[ncomments]=0;
|
||||
_tags->user_comments[ncomments]=comment=
|
||||
(char *)_ogg_malloc(sizeof(*comment)*(tag_len+value_len+2));
|
||||
if(OP_UNLIKELY(comment==NULL))return OP_EFAULT;
|
||||
memcpy(comment,_tag,sizeof(*comment)*tag_len);
|
||||
comment[tag_len]='=';
|
||||
memcpy(comment+tag_len+1,_value,sizeof(*comment)*(value_len+1));
|
||||
_tags->comment_lengths[ncomments]=tag_len+value_len+1;
|
||||
_tags->comments=ncomments+1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opus_tags_add_comment(OpusTags *_tags,const char *_comment){
|
||||
int comment_len;
|
||||
int ncomments;
|
||||
int ret;
|
||||
ncomments=_tags->comments;
|
||||
ret=op_tags_ensure_capacity(_tags,ncomments+1);
|
||||
if(OP_UNLIKELY(ret<0))return ret;
|
||||
comment_len=(int)strlen(_comment);
|
||||
_tags->comment_lengths[ncomments]=0;
|
||||
_tags->user_comments[ncomments]=op_strdup_with_len(_comment,comment_len);
|
||||
if(OP_UNLIKELY(_tags->user_comments[ncomments]==NULL))return OP_EFAULT;
|
||||
_tags->comment_lengths[ncomments]=comment_len;
|
||||
_tags->comments=ncomments+1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opus_tagcompare(const char *_tag_name,const char *_comment){
|
||||
return opus_tagncompare(_tag_name,strlen(_tag_name),_comment);
|
||||
}
|
||||
|
||||
int opus_tagncompare(const char *_tag_name,int _tag_len,const char *_comment){
|
||||
int ret;
|
||||
OP_ASSERT(_tag_len>=0);
|
||||
ret=op_strncasecmp(_tag_name,_comment,_tag_len);
|
||||
return ret?ret:'='-_comment[_tag_len];
|
||||
}
|
||||
|
||||
const char *opus_tags_query(const OpusTags *_tags,const char *_tag,int _count){
|
||||
char **user_comments;
|
||||
int tag_len;
|
||||
int found;
|
||||
int ncomments;
|
||||
int ci;
|
||||
tag_len=strlen(_tag);
|
||||
ncomments=_tags->comments;
|
||||
user_comments=_tags->user_comments;
|
||||
found=0;
|
||||
for(ci=0;ci<ncomments;ci++){
|
||||
if(!opus_tagncompare(_tag,tag_len,user_comments[ci])){
|
||||
/*We return a pointer to the data, not a copy.*/
|
||||
if(_count==found++)return user_comments[ci]+tag_len+1;
|
||||
}
|
||||
}
|
||||
/*Didn't find anything.*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int opus_tags_query_count(const OpusTags *_tags,const char *_tag){
|
||||
char **user_comments;
|
||||
int tag_len;
|
||||
int found;
|
||||
int ncomments;
|
||||
int ci;
|
||||
tag_len=strlen(_tag);
|
||||
ncomments=_tags->comments;
|
||||
user_comments=_tags->user_comments;
|
||||
found=0;
|
||||
for(ci=0;ci<ncomments;ci++){
|
||||
if(!opus_tagncompare(_tag,tag_len,user_comments[ci]))found++;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
int opus_tags_get_track_gain(const OpusTags *_tags,int *_gain_q8){
|
||||
char **comments;
|
||||
int ncomments;
|
||||
int ci;
|
||||
comments=_tags->user_comments;
|
||||
ncomments=_tags->comments;
|
||||
/*Look for the first valid R128_TRACK_GAIN tag and use that.*/
|
||||
for(ci=0;ci<ncomments;ci++){
|
||||
if(opus_tagncompare("R128_TRACK_GAIN",15,comments[ci])==0){
|
||||
char *p;
|
||||
opus_int32 gain_q8;
|
||||
int negative;
|
||||
p=comments[ci]+16;
|
||||
negative=0;
|
||||
if(*p=='-'){
|
||||
negative=-1;
|
||||
p++;
|
||||
}
|
||||
else if(*p=='+')p++;
|
||||
gain_q8=0;
|
||||
while(*p>='0'&&*p<='9'){
|
||||
gain_q8=10*gain_q8+*p-'0';
|
||||
if(gain_q8>32767-negative)break;
|
||||
p++;
|
||||
}
|
||||
/*This didn't look like a signed 16-bit decimal integer.
|
||||
Not a valid R128_TRACK_GAIN tag.*/
|
||||
if(*p!='\0')continue;
|
||||
*_gain_q8=(int)(gain_q8+negative^negative);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return OP_FALSE;
|
||||
}
|
||||
|
||||
static int op_is_jpeg(const unsigned char *_buf,size_t _buf_sz){
|
||||
return _buf_sz>=11&&memcmp(_buf,"\xFF\xD8\xFF\xE0",4)==0
|
||||
&&(_buf[4]<<8|_buf[5])>=16&&memcmp(_buf+6,"JFIF",5)==0;
|
||||
}
|
||||
|
||||
/*Tries to extract the width, height, bits per pixel, and palette size of a
|
||||
JPEG.
|
||||
On failure, simply leaves its outputs unmodified.*/
|
||||
static void op_extract_jpeg_params(const unsigned char *_buf,size_t _buf_sz,
|
||||
opus_uint32 *_width,opus_uint32 *_height,
|
||||
opus_uint32 *_depth,opus_uint32 *_colors,int *_has_palette){
|
||||
if(op_is_jpeg(_buf,_buf_sz)){
|
||||
size_t offs;
|
||||
offs=2;
|
||||
for(;;){
|
||||
size_t segment_len;
|
||||
int marker;
|
||||
while(offs<_buf_sz&&_buf[offs]!=0xFF)offs++;
|
||||
while(offs<_buf_sz&&_buf[offs]==0xFF)offs++;
|
||||
marker=_buf[offs];
|
||||
offs++;
|
||||
/*If we hit EOI* (end of image), or another SOI* (start of image),
|
||||
or SOS (start of scan), then stop now.*/
|
||||
if(offs>=_buf_sz||(marker>=0xD8&&marker<=0xDA))break;
|
||||
/*RST* (restart markers): skip (no segment length).*/
|
||||
else if(marker>=0xD0&&marker<=0xD7)continue;
|
||||
/*Read the length of the marker segment.*/
|
||||
if(_buf_sz-offs<2)break;
|
||||
segment_len=_buf[offs]<<8|_buf[offs+1];
|
||||
if(segment_len<2||_buf_sz-offs<segment_len)break;
|
||||
if(marker==0xC0||(marker>0xC0&&marker<0xD0&&(marker&3)!=0)){
|
||||
/*Found a SOFn (start of frame) marker segment:*/
|
||||
if(segment_len>=8){
|
||||
*_height=_buf[offs+3]<<8|_buf[offs+4];
|
||||
*_width=_buf[offs+5]<<8|_buf[offs+6];
|
||||
*_depth=_buf[offs+2]*_buf[offs+7];
|
||||
*_colors=0;
|
||||
*_has_palette=0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/*Other markers: skip the whole marker segment.*/
|
||||
offs+=segment_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int op_is_png(const unsigned char *_buf,size_t _buf_sz){
|
||||
return _buf_sz>=8&&memcmp(_buf,"\x89PNG\x0D\x0A\x1A\x0A",8)==0;
|
||||
}
|
||||
|
||||
/*Tries to extract the width, height, bits per pixel, and palette size of a
|
||||
PNG.
|
||||
On failure, simply leaves its outputs unmodified.*/
|
||||
static void op_extract_png_params(const unsigned char *_buf,size_t _buf_sz,
|
||||
opus_uint32 *_width,opus_uint32 *_height,
|
||||
opus_uint32 *_depth,opus_uint32 *_colors,int *_has_palette){
|
||||
if(op_is_png(_buf,_buf_sz)){
|
||||
size_t offs;
|
||||
offs=8;
|
||||
while(_buf_sz-offs>=12){
|
||||
ogg_uint32_t chunk_len;
|
||||
chunk_len=op_parse_uint32be(_buf+offs);
|
||||
if(chunk_len>_buf_sz-(offs+12))break;
|
||||
else if(chunk_len==13&&memcmp(_buf+offs+4,"IHDR",4)==0){
|
||||
int color_type;
|
||||
*_width=op_parse_uint32be(_buf+offs+8);
|
||||
*_height=op_parse_uint32be(_buf+offs+12);
|
||||
color_type=_buf[offs+17];
|
||||
if(color_type==3){
|
||||
*_depth=24;
|
||||
*_has_palette=1;
|
||||
}
|
||||
else{
|
||||
int sample_depth;
|
||||
sample_depth=_buf[offs+16];
|
||||
if(color_type==0)*_depth=sample_depth;
|
||||
else if(color_type==2)*_depth=sample_depth*3;
|
||||
else if(color_type==4)*_depth=sample_depth*2;
|
||||
else if(color_type==6)*_depth=sample_depth*4;
|
||||
*_colors=0;
|
||||
*_has_palette=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(*_has_palette>0&&memcmp(_buf+offs+4,"PLTE",4)==0){
|
||||
*_colors=chunk_len/3;
|
||||
break;
|
||||
}
|
||||
offs+=12+chunk_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int op_is_gif(const unsigned char *_buf,size_t _buf_sz){
|
||||
return _buf_sz>=6&&(memcmp(_buf,"GIF87a",6)==0||memcmp(_buf,"GIF89a",6)==0);
|
||||
}
|
||||
|
||||
/*Tries to extract the width, height, bits per pixel, and palette size of a
|
||||
GIF.
|
||||
On failure, simply leaves its outputs unmodified.*/
|
||||
static void op_extract_gif_params(const unsigned char *_buf,size_t _buf_sz,
|
||||
opus_uint32 *_width,opus_uint32 *_height,
|
||||
opus_uint32 *_depth,opus_uint32 *_colors,int *_has_palette){
|
||||
if(op_is_gif(_buf,_buf_sz)&&_buf_sz>=14){
|
||||
*_width=_buf[6]|_buf[7]<<8;
|
||||
*_height=_buf[8]|_buf[9]<<8;
|
||||
/*libFLAC hard-codes the depth to 24.*/
|
||||
*_depth=24;
|
||||
*_colors=1<<((_buf[10]&7)+1);
|
||||
*_has_palette=1;
|
||||
}
|
||||
}
|
||||
|
||||
/*The actual implementation of opus_picture_tag_parse().
|
||||
Unlike the public API, this function requires _pic to already be
|
||||
initialized, modifies its contents before success is guaranteed, and assumes
|
||||
the caller will clear it on error.*/
|
||||
static int opus_picture_tag_parse_impl(OpusPictureTag *_pic,const char *_tag,
|
||||
unsigned char *_buf,size_t _buf_sz,size_t _base64_sz){
|
||||
opus_int32 picture_type;
|
||||
opus_uint32 mime_type_length;
|
||||
char *mime_type;
|
||||
opus_uint32 description_length;
|
||||
char *description;
|
||||
opus_uint32 width;
|
||||
opus_uint32 height;
|
||||
opus_uint32 depth;
|
||||
opus_uint32 colors;
|
||||
opus_uint32 data_length;
|
||||
opus_uint32 file_width;
|
||||
opus_uint32 file_height;
|
||||
opus_uint32 file_depth;
|
||||
opus_uint32 file_colors;
|
||||
int format;
|
||||
int has_palette;
|
||||
int colors_set;
|
||||
size_t i;
|
||||
/*Decode the BASE64 data.*/
|
||||
for(i=0;i<_base64_sz;i++){
|
||||
opus_uint32 value;
|
||||
int j;
|
||||
value=0;
|
||||
for(j=0;j<4;j++){
|
||||
unsigned c;
|
||||
unsigned d;
|
||||
c=(unsigned char)_tag[4*i+j];
|
||||
if(c=='+')d=62;
|
||||
else if(c=='/')d=63;
|
||||
else if(c>='0'&&c<='9')d=52+c-'0';
|
||||
else if(c>='a'&&c<='z')d=26+c-'a';
|
||||
else if(c>='A'&&c<='Z')d=c-'A';
|
||||
else if(c=='='&&3*i+j>_buf_sz)d=0;
|
||||
else return OP_ENOTFORMAT;
|
||||
value=value<<6|d;
|
||||
}
|
||||
_buf[3*i]=(unsigned char)(value>>16);
|
||||
if(3*i+1<_buf_sz){
|
||||
_buf[3*i+1]=(unsigned char)(value>>8);
|
||||
if(3*i+2<_buf_sz)_buf[3*i+2]=(unsigned char)value;
|
||||
}
|
||||
}
|
||||
i=0;
|
||||
picture_type=op_parse_uint32be(_buf+i);
|
||||
i+=4;
|
||||
/*Extract the MIME type.*/
|
||||
mime_type_length=op_parse_uint32be(_buf+i);
|
||||
i+=4;
|
||||
if(mime_type_length>_buf_sz-32)return OP_ENOTFORMAT;
|
||||
mime_type=(char *)_ogg_malloc(sizeof(*_pic->mime_type)*(mime_type_length+1));
|
||||
if(mime_type==NULL)return OP_EFAULT;
|
||||
memcpy(mime_type,_buf+i,sizeof(*mime_type)*mime_type_length);
|
||||
mime_type[mime_type_length]='\0';
|
||||
_pic->mime_type=mime_type;
|
||||
i+=mime_type_length;
|
||||
/*Extract the description string.*/
|
||||
description_length=op_parse_uint32be(_buf+i);
|
||||
i+=4;
|
||||
if(description_length>_buf_sz-mime_type_length-32)return OP_ENOTFORMAT;
|
||||
description=
|
||||
(char *)_ogg_malloc(sizeof(*_pic->mime_type)*(description_length+1));
|
||||
if(description==NULL)return OP_EFAULT;
|
||||
memcpy(description,_buf+i,sizeof(*description)*description_length);
|
||||
description[description_length]='\0';
|
||||
_pic->description=description;
|
||||
i+=description_length;
|
||||
/*Extract the remaining fields.*/
|
||||
width=op_parse_uint32be(_buf+i);
|
||||
i+=4;
|
||||
height=op_parse_uint32be(_buf+i);
|
||||
i+=4;
|
||||
depth=op_parse_uint32be(_buf+i);
|
||||
i+=4;
|
||||
colors=op_parse_uint32be(_buf+i);
|
||||
i+=4;
|
||||
/*If one of these is set, they all must be, but colors==0 is a valid value.*/
|
||||
colors_set=width!=0||height!=0||depth!=0||colors!=0;
|
||||
if((width==0||height==0||depth==0)&&colors_set)return OP_ENOTFORMAT;
|
||||
data_length=op_parse_uint32be(_buf+i);
|
||||
i+=4;
|
||||
if(data_length>_buf_sz-i)return OP_ENOTFORMAT;
|
||||
/*Trim extraneous data so we don't copy it below.*/
|
||||
_buf_sz=i+data_length;
|
||||
/*Attempt to determine the image format.*/
|
||||
format=OP_PIC_FORMAT_UNKNOWN;
|
||||
if(mime_type_length==3&&strcmp(mime_type,"-->")==0){
|
||||
format=OP_PIC_FORMAT_URL;
|
||||
/*Picture type 1 must be a 32x32 PNG.*/
|
||||
if(picture_type==1&&(width!=0||height!=0)&&(width!=32||height!=32)){
|
||||
return OP_ENOTFORMAT;
|
||||
}
|
||||
/*Append a terminating NUL for the convenience of our callers.*/
|
||||
_buf[_buf_sz++]='\0';
|
||||
}
|
||||
else{
|
||||
if(mime_type_length==10
|
||||
&&op_strncasecmp(mime_type,"image/jpeg",mime_type_length)==0){
|
||||
if(op_is_jpeg(_buf+i,data_length))format=OP_PIC_FORMAT_JPEG;
|
||||
}
|
||||
else if(mime_type_length==9
|
||||
&&op_strncasecmp(mime_type,"image/png",mime_type_length)==0){
|
||||
if(op_is_png(_buf+i,data_length))format=OP_PIC_FORMAT_PNG;
|
||||
}
|
||||
else if(mime_type_length==9
|
||||
&&op_strncasecmp(mime_type,"image/gif",mime_type_length)==0){
|
||||
if(op_is_gif(_buf+i,data_length))format=OP_PIC_FORMAT_GIF;
|
||||
}
|
||||
else if(mime_type_length==0||(mime_type_length==6
|
||||
&&op_strncasecmp(mime_type,"image/",mime_type_length)==0)){
|
||||
if(op_is_jpeg(_buf+i,data_length))format=OP_PIC_FORMAT_JPEG;
|
||||
else if(op_is_png(_buf+i,data_length))format=OP_PIC_FORMAT_PNG;
|
||||
else if(op_is_gif(_buf+i,data_length))format=OP_PIC_FORMAT_GIF;
|
||||
}
|
||||
file_width=file_height=file_depth=file_colors=0;
|
||||
has_palette=-1;
|
||||
switch(format){
|
||||
case OP_PIC_FORMAT_JPEG:{
|
||||
op_extract_jpeg_params(_buf+i,data_length,
|
||||
&file_width,&file_height,&file_depth,&file_colors,&has_palette);
|
||||
}break;
|
||||
case OP_PIC_FORMAT_PNG:{
|
||||
op_extract_png_params(_buf+i,data_length,
|
||||
&file_width,&file_height,&file_depth,&file_colors,&has_palette);
|
||||
}break;
|
||||
case OP_PIC_FORMAT_GIF:{
|
||||
op_extract_gif_params(_buf+i,data_length,
|
||||
&file_width,&file_height,&file_depth,&file_colors,&has_palette);
|
||||
}break;
|
||||
}
|
||||
if(has_palette>=0){
|
||||
/*If we successfully extracted these parameters from the image, override
|
||||
any declared values.*/
|
||||
width=file_width;
|
||||
height=file_height;
|
||||
depth=file_depth;
|
||||
colors=file_colors;
|
||||
}
|
||||
/*Picture type 1 must be a 32x32 PNG.*/
|
||||
if(picture_type==1&&(format!=OP_PIC_FORMAT_PNG||width!=32||height!=32)){
|
||||
return OP_ENOTFORMAT;
|
||||
}
|
||||
}
|
||||
/*Adjust _buf_sz instead of using data_length to capture the terminating NUL
|
||||
for URLs.*/
|
||||
_buf_sz-=i;
|
||||
memmove(_buf,_buf+i,sizeof(*_buf)*_buf_sz);
|
||||
_buf=(unsigned char *)_ogg_realloc(_buf,_buf_sz);
|
||||
if(_buf_sz>0&&_buf==NULL)return OP_EFAULT;
|
||||
_pic->type=picture_type;
|
||||
_pic->width=width;
|
||||
_pic->height=height;
|
||||
_pic->depth=depth;
|
||||
_pic->colors=colors;
|
||||
_pic->data_length=data_length;
|
||||
_pic->data=_buf;
|
||||
_pic->format=format;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opus_picture_tag_parse(OpusPictureTag *_pic,const char *_tag){
|
||||
OpusPictureTag pic;
|
||||
unsigned char *buf;
|
||||
size_t base64_sz;
|
||||
size_t buf_sz;
|
||||
size_t tag_length;
|
||||
int ret;
|
||||
if(opus_tagncompare("METADATA_BLOCK_PICTURE",22,_tag)==0)_tag+=23;
|
||||
/*Figure out how much BASE64-encoded data we have.*/
|
||||
tag_length=strlen(_tag);
|
||||
if(tag_length&3)return OP_ENOTFORMAT;
|
||||
base64_sz=tag_length>>2;
|
||||
buf_sz=3*base64_sz;
|
||||
if(buf_sz<32)return OP_ENOTFORMAT;
|
||||
if(_tag[tag_length-1]=='=')buf_sz--;
|
||||
if(_tag[tag_length-2]=='=')buf_sz--;
|
||||
if(buf_sz<32)return OP_ENOTFORMAT;
|
||||
/*Allocate an extra byte to allow appending a terminating NUL to URL data.*/
|
||||
buf=(unsigned char *)_ogg_malloc(sizeof(*buf)*(buf_sz+1));
|
||||
if(buf==NULL)return OP_EFAULT;
|
||||
opus_picture_tag_init(&pic);
|
||||
ret=opus_picture_tag_parse_impl(&pic,_tag,buf,buf_sz,base64_sz);
|
||||
if(ret<0){
|
||||
opus_picture_tag_clear(&pic);
|
||||
_ogg_free(buf);
|
||||
}
|
||||
else *_pic=*&pic;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void opus_picture_tag_init(OpusPictureTag *_pic){
|
||||
memset(_pic,0,sizeof(*_pic));
|
||||
}
|
||||
|
||||
void opus_picture_tag_clear(OpusPictureTag *_pic){
|
||||
_ogg_free(_pic->description);
|
||||
_ogg_free(_pic->mime_type);
|
||||
_ogg_free(_pic->data);
|
||||
}
|
42
src/engine/external/opusfile/internal.c
vendored
42
src/engine/external/opusfile/internal.c
vendored
|
@ -1,42 +0,0 @@
|
|||
/********************************************************************
|
||||
* *
|
||||
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. *
|
||||
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
||||
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2012 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(OP_ENABLE_ASSERTIONS)
|
||||
void op_fatal_impl(const char *_str,const char *_file,int _line){
|
||||
fprintf(stderr,"Fatal (internal) error in %s, line %i: %s\n",
|
||||
_file,_line,_str);
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*A version of strncasecmp() that is guaranteed to only ignore the case of
|
||||
ASCII characters.*/
|
||||
int op_strncasecmp(const char *_a,const char *_b,int _n){
|
||||
int i;
|
||||
for(i=0;i<_n;i++){
|
||||
int a;
|
||||
int b;
|
||||
int d;
|
||||
a=_a[i];
|
||||
b=_b[i];
|
||||
if(a>='a'&&a<='z')a-='a'-'A';
|
||||
if(b>='a'&&b<='z')b-='a'-'A';
|
||||
d=a-b;
|
||||
if(d)return d;
|
||||
}
|
||||
return 0;
|
||||
}
|
249
src/engine/external/opusfile/internal.h
vendored
249
src/engine/external/opusfile/internal.h
vendored
|
@ -1,249 +0,0 @@
|
|||
/********************************************************************
|
||||
* *
|
||||
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. *
|
||||
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
||||
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2012 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************/
|
||||
#if !defined(_opusfile_internal_h)
|
||||
# define _opusfile_internal_h (1)
|
||||
|
||||
# if !defined(_REENTRANT)
|
||||
# define _REENTRANT
|
||||
# endif
|
||||
# if !defined(_GNU_SOURCE)
|
||||
# define _GNU_SOURCE
|
||||
# endif
|
||||
# if !defined(_LARGEFILE_SOURCE)
|
||||
# define _LARGEFILE_SOURCE
|
||||
# endif
|
||||
# if !defined(_LARGEFILE64_SOURCE)
|
||||
# define _LARGEFILE64_SOURCE
|
||||
# endif
|
||||
# if !defined(_FILE_OFFSET_BITS)
|
||||
# define _FILE_OFFSET_BITS 64
|
||||
# endif
|
||||
|
||||
# include <stdlib.h>
|
||||
# include <opusfile.h>
|
||||
|
||||
typedef struct OggOpusLink OggOpusLink;
|
||||
|
||||
# if defined(OP_FIXED_POINT)
|
||||
|
||||
typedef opus_int16 op_sample;
|
||||
|
||||
# else
|
||||
|
||||
typedef float op_sample;
|
||||
|
||||
/*We're using this define to test for libopus 1.1 or later until libopus
|
||||
provides a better mechanism.*/
|
||||
# if defined(OPUS_GET_EXPERT_FRAME_DURATION_REQUEST)
|
||||
/*Enable soft clipping prevention in 16-bit decodes.*/
|
||||
# define OP_SOFT_CLIP (1)
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
# if OP_GNUC_PREREQ(4,2)
|
||||
/*Disable excessive warnings about the order of operations.*/
|
||||
# pragma GCC diagnostic ignored "-Wparentheses"
|
||||
# elif defined(_MSC_VER)
|
||||
/*Disable excessive warnings about the order of operations.*/
|
||||
# pragma warning(disable:4554)
|
||||
/*Disable warnings about "deprecated" POSIX functions.*/
|
||||
# pragma warning(disable:4996)
|
||||
# endif
|
||||
|
||||
# if OP_GNUC_PREREQ(3,0)
|
||||
/*Another alternative is
|
||||
(__builtin_constant_p(_x)?!!(_x):__builtin_expect(!!(_x),1))
|
||||
but that evaluates _x multiple times, which may be bad.*/
|
||||
# define OP_LIKELY(_x) (__builtin_expect(!!(_x),1))
|
||||
# define OP_UNLIKELY(_x) (__builtin_expect(!!(_x),0))
|
||||
# else
|
||||
# define OP_LIKELY(_x) (!!(_x))
|
||||
# define OP_UNLIKELY(_x) (!!(_x))
|
||||
# endif
|
||||
|
||||
# if defined(OP_ENABLE_ASSERTIONS)
|
||||
# if OP_GNUC_PREREQ(2,5)||__SUNPRO_C>=0x590
|
||||
__attribute__((noreturn))
|
||||
# endif
|
||||
void op_fatal_impl(const char *_str,const char *_file,int _line);
|
||||
|
||||
# define OP_FATAL(_str) (op_fatal_impl(_str,__FILE__,__LINE__))
|
||||
|
||||
# define OP_ASSERT(_cond) \
|
||||
do{ \
|
||||
if(OP_UNLIKELY(!(_cond)))OP_FATAL("assertion failed: " #_cond); \
|
||||
} \
|
||||
while(0)
|
||||
# define OP_ALWAYS_TRUE(_cond) OP_ASSERT(_cond)
|
||||
|
||||
# else
|
||||
# define OP_FATAL(_str) abort()
|
||||
# define OP_ASSERT(_cond)
|
||||
# define OP_ALWAYS_TRUE(_cond) ((void)(_cond))
|
||||
# endif
|
||||
|
||||
# define OP_INT64_MAX (2*(((ogg_int64_t)1<<62)-1)|1)
|
||||
# define OP_INT64_MIN (-OP_INT64_MAX-1)
|
||||
# define OP_INT32_MAX (2*(((ogg_int32_t)1<<30)-1)|1)
|
||||
# define OP_INT32_MIN (-OP_INT32_MAX-1)
|
||||
|
||||
# define OP_MIN(_a,_b) ((_a)<(_b)?(_a):(_b))
|
||||
# define OP_MAX(_a,_b) ((_a)>(_b)?(_a):(_b))
|
||||
# define OP_CLAMP(_lo,_x,_hi) (OP_MAX(_lo,OP_MIN(_x,_hi)))
|
||||
|
||||
/*Advance a file offset by the given amount, clamping against OP_INT64_MAX.
|
||||
This is used to advance a known offset by things like OP_CHUNK_SIZE or
|
||||
OP_PAGE_SIZE_MAX, while making sure to avoid signed overflow.
|
||||
It assumes that both _offset and _amount are non-negative.*/
|
||||
#define OP_ADV_OFFSET(_offset,_amount) \
|
||||
(OP_MIN(_offset,OP_INT64_MAX-(_amount))+(_amount))
|
||||
|
||||
/*The maximum channel count for any mapping we'll actually decode.*/
|
||||
# define OP_NCHANNELS_MAX (8)
|
||||
|
||||
/*Initial state.*/
|
||||
# define OP_NOTOPEN (0)
|
||||
/*We've found the first Opus stream in the first link.*/
|
||||
# define OP_PARTOPEN (1)
|
||||
# define OP_OPENED (2)
|
||||
/*We've found the first Opus stream in the current link.*/
|
||||
# define OP_STREAMSET (3)
|
||||
/*We've initialized the decoder for the chosen Opus stream in the current
|
||||
link.*/
|
||||
# define OP_INITSET (4)
|
||||
|
||||
/*Information cached for a single link in a chained Ogg Opus file.
|
||||
We choose the first Opus stream encountered in each link to play back (and
|
||||
require at least one).*/
|
||||
struct OggOpusLink{
|
||||
/*The byte offset of the first header page in this link.*/
|
||||
opus_int64 offset;
|
||||
/*The byte offset of the first data page from the chosen Opus stream in this
|
||||
link (after the headers).*/
|
||||
opus_int64 data_offset;
|
||||
/*The byte offset of the last page from the chosen Opus stream in this link.
|
||||
This is used when seeking to ensure we find a page before the last one, so
|
||||
that end-trimming calculations work properly.
|
||||
This is only valid for seekable sources.*/
|
||||
opus_int64 end_offset;
|
||||
/*The granule position of the last sample.
|
||||
This is only valid for seekable sources.*/
|
||||
ogg_int64_t pcm_end;
|
||||
/*The granule position before the first sample.*/
|
||||
ogg_int64_t pcm_start;
|
||||
/*The serial number.*/
|
||||
ogg_uint32_t serialno;
|
||||
/*The contents of the info header.*/
|
||||
OpusHead head;
|
||||
/*The contents of the comment header.*/
|
||||
OpusTags tags;
|
||||
};
|
||||
|
||||
struct OggOpusFile{
|
||||
/*The callbacks used to access the data source.*/
|
||||
OpusFileCallbacks callbacks;
|
||||
/*A FILE *, memory bufer, etc.*/
|
||||
void *source;
|
||||
/*Whether or not we can seek with this data source.*/
|
||||
int seekable;
|
||||
/*The number of links in this chained Ogg Opus file.*/
|
||||
int nlinks;
|
||||
/*The cached information from each link in a chained Ogg Opus file.
|
||||
If source isn't seekable (e.g., it's a pipe), only the current link
|
||||
appears.*/
|
||||
OggOpusLink *links;
|
||||
/*The number of serial numbers from a single link.*/
|
||||
int nserialnos;
|
||||
/*The capacity of the list of serial numbers from a single link.*/
|
||||
int cserialnos;
|
||||
/*Storage for the list of serial numbers from a single link.*/
|
||||
ogg_uint32_t *serialnos;
|
||||
/*This is the current offset of the data processed by the ogg_sync_state.
|
||||
After a seek, this should be set to the target offset so that we can track
|
||||
the byte offsets of subsequent pages.
|
||||
After a call to op_get_next_page(), this will point to the first byte after
|
||||
that page.*/
|
||||
opus_int64 offset;
|
||||
/*The total size of this data source, or -1 if it's unseekable.*/
|
||||
opus_int64 end;
|
||||
/*Used to locate pages in the data source.*/
|
||||
ogg_sync_state oy;
|
||||
/*One of OP_NOTOPEN, OP_PARTOPEN, OP_OPENED, OP_STREAMSET, OP_INITSET.*/
|
||||
int ready_state;
|
||||
/*The current link being played back.*/
|
||||
int cur_link;
|
||||
/*The number of decoded samples to discard from the start of decoding.*/
|
||||
opus_int32 cur_discard_count;
|
||||
/*The granule position of the previous packet (current packet start time).*/
|
||||
ogg_int64_t prev_packet_gp;
|
||||
/*The number of bytes read since the last bitrate query, including framing.*/
|
||||
opus_int64 bytes_tracked;
|
||||
/*The number of samples decoded since the last bitrate query.*/
|
||||
ogg_int64_t samples_tracked;
|
||||
/*Takes physical pages and welds them into a logical stream of packets.*/
|
||||
ogg_stream_state os;
|
||||
/*Re-timestamped packets from a single page.
|
||||
Buffering these relies on the undocumented libogg behavior that ogg_packet
|
||||
pointers remain valid until the next page is submitted to the
|
||||
ogg_stream_state they came from.*/
|
||||
ogg_packet op[255];
|
||||
/*The index of the next packet to return.*/
|
||||
int op_pos;
|
||||
/*The total number of packets available.*/
|
||||
int op_count;
|
||||
/*Central working state for the packet-to-PCM decoder.*/
|
||||
OpusMSDecoder *od;
|
||||
/*The application-provided packet decode callback.*/
|
||||
op_decode_cb_func decode_cb;
|
||||
/*The application-provided packet decode callback context.*/
|
||||
void *decode_cb_ctx;
|
||||
/*The stream count used to initialize the decoder.*/
|
||||
int od_stream_count;
|
||||
/*The coupled stream count used to initialize the decoder.*/
|
||||
int od_coupled_count;
|
||||
/*The channel count used to initialize the decoder.*/
|
||||
int od_channel_count;
|
||||
/*The channel mapping used to initialize the decoder.*/
|
||||
unsigned char od_mapping[OP_NCHANNELS_MAX];
|
||||
/*The buffered data for one decoded packet.*/
|
||||
op_sample *od_buffer;
|
||||
/*The current position in the decoded buffer.*/
|
||||
int od_buffer_pos;
|
||||
/*The number of valid samples in the decoded buffer.*/
|
||||
int od_buffer_size;
|
||||
/*The type of gain offset to apply.
|
||||
One of OP_HEADER_GAIN, OP_TRACK_GAIN, or OP_ABSOLUTE_GAIN.*/
|
||||
int gain_type;
|
||||
/*The offset to apply to the gain.*/
|
||||
opus_int32 gain_offset_q8;
|
||||
/*Internal state for soft clipping and dithering float->short output.*/
|
||||
#if !defined(OP_FIXED_POINT)
|
||||
# if defined(OP_SOFT_CLIP)
|
||||
float clip_state[OP_NCHANNELS_MAX];
|
||||
# endif
|
||||
float dither_a[OP_NCHANNELS_MAX*4];
|
||||
float dither_b[OP_NCHANNELS_MAX*4];
|
||||
opus_uint32 dither_seed;
|
||||
int dither_mute;
|
||||
int dither_disabled;
|
||||
/*The number of channels represented by the internal state.
|
||||
This gets set to 0 whenever anything that would prevent state propagation
|
||||
occurs (switching between the float/short APIs, or between the
|
||||
stereo/multistream APIs).*/
|
||||
int state_channel_count;
|
||||
#endif
|
||||
};
|
||||
|
||||
int op_strncasecmp(const char *_a,const char *_b,int _n);
|
||||
|
||||
#endif
|
3158
src/engine/external/opusfile/opusfile.c
vendored
3158
src/engine/external/opusfile/opusfile.c
vendored
File diff suppressed because it is too large
Load diff
2102
src/engine/external/opusfile/opusfile.h
vendored
2102
src/engine/external/opusfile/opusfile.h
vendored
File diff suppressed because it is too large
Load diff
366
src/engine/external/opusfile/stream.c
vendored
366
src/engine/external/opusfile/stream.c
vendored
|
@ -1,366 +0,0 @@
|
|||
/********************************************************************
|
||||
* *
|
||||
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. *
|
||||
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
||||
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 1994-2012 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: stdio-based convenience library for opening/seeking/decoding
|
||||
last mod: $Id: vorbisfile.c 17573 2010-10-27 14:53:59Z xiphmont $
|
||||
|
||||
********************************************************************/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "internal.h"
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#if defined(_WIN32)
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
typedef struct OpusMemStream OpusMemStream;
|
||||
|
||||
#define OP_MEM_SIZE_MAX (~(size_t)0>>1)
|
||||
#define OP_MEM_DIFF_MAX ((ptrdiff_t)OP_MEM_SIZE_MAX)
|
||||
|
||||
/*The context information needed to read from a block of memory as if it were a
|
||||
file.*/
|
||||
struct OpusMemStream{
|
||||
/*The block of memory to read from.*/
|
||||
const unsigned char *data;
|
||||
/*The total size of the block.
|
||||
This must be at most OP_MEM_SIZE_MAX to prevent signed overflow while
|
||||
seeking.*/
|
||||
ptrdiff_t size;
|
||||
/*The current file position.
|
||||
This is allowed to be set arbitrarily greater than size (i.e., past the end
|
||||
of the block, though we will not read data past the end of the block), but
|
||||
is not allowed to be negative (i.e., before the beginning of the block).*/
|
||||
ptrdiff_t pos;
|
||||
};
|
||||
|
||||
static int op_fread(void *_stream,unsigned char *_ptr,int _buf_size){
|
||||
FILE *stream;
|
||||
size_t ret;
|
||||
/*Check for empty read.*/
|
||||
if(_buf_size<=0)return 0;
|
||||
stream=(FILE *)_stream;
|
||||
ret=fread(_ptr,1,_buf_size,stream);
|
||||
OP_ASSERT(ret<=(size_t)_buf_size);
|
||||
/*If ret==0 and !feof(stream), there was a read error.*/
|
||||
return ret>0||feof(stream)?(int)ret:OP_EREAD;
|
||||
}
|
||||
|
||||
static int op_fseek(void *_stream,opus_int64 _offset,int _whence){
|
||||
#if defined(_WIN32)
|
||||
/*_fseeki64() is not exposed until MSCVCRT80.
|
||||
This is the default starting with MSVC 2005 (_MSC_VER>=1400), but we want
|
||||
to allow linking against older MSVCRT versions for compatibility back to
|
||||
XP without installing extra runtime libraries.
|
||||
i686-pc-mingw32 does not have fseeko() and requires
|
||||
__MSVCRT_VERSION__>=0x800 for _fseeki64(), which screws up linking with
|
||||
other libraries (that don't use MSVCRT80 from MSVC 2005 by default).
|
||||
i686-w64-mingw32 does have fseeko() and respects _FILE_OFFSET_BITS, but I
|
||||
don't know how to detect that at compile time.
|
||||
We could just use fseeko64() (which is available in both), but its
|
||||
implemented using fgetpos()/fsetpos() just like this code, except without
|
||||
the overflow checking, so we prefer our version.*/
|
||||
opus_int64 pos;
|
||||
/*We don't use fpos_t directly because it might be a struct if __STDC__ is
|
||||
non-zero or _INTEGRAL_MAX_BITS < 64.
|
||||
I'm not certain when the latter is true, but someone could in theory set
|
||||
the former.
|
||||
Either way, it should be binary compatible with a normal 64-bit int (this
|
||||
assumption is not portable, but I believe it is true for MSVCRT).*/
|
||||
OP_ASSERT(sizeof(pos)==sizeof(fpos_t));
|
||||
/*Translate the seek to an absolute one.*/
|
||||
if(_whence==SEEK_CUR){
|
||||
int ret;
|
||||
ret=fgetpos((FILE *)_stream,(fpos_t *)&pos);
|
||||
if(ret)return ret;
|
||||
}
|
||||
else if(_whence==SEEK_END)pos=_filelengthi64(_fileno((FILE *)_stream));
|
||||
else if(_whence==SEEK_SET)pos=0;
|
||||
else return -1;
|
||||
/*Check for errors or overflow.*/
|
||||
if(pos<0||_offset<-pos||_offset>OP_INT64_MAX-pos)return -1;
|
||||
pos+=_offset;
|
||||
return fsetpos((FILE *)_stream,(fpos_t *)&pos);
|
||||
#else
|
||||
/*This function actually conforms to the SUSv2 and POSIX.1-2001, so we prefer
|
||||
it except on Windows.*/
|
||||
return fseeko((FILE *)_stream,(off_t)_offset,_whence);
|
||||
#endif
|
||||
}
|
||||
|
||||
static opus_int64 op_ftell(void *_stream){
|
||||
#if defined(_WIN32)
|
||||
/*_ftelli64() is not exposed until MSCVCRT80, and ftello()/ftello64() have
|
||||
the same problems as fseeko()/fseeko64() in MingW.
|
||||
See above for a more detailed explanation.*/
|
||||
opus_int64 pos;
|
||||
OP_ASSERT(sizeof(pos)==sizeof(fpos_t));
|
||||
return fgetpos((FILE *)_stream,(fpos_t *)&pos)?-1:pos;
|
||||
#else
|
||||
/*This function actually conforms to the SUSv2 and POSIX.1-2001, so we prefer
|
||||
it except on Windows.*/
|
||||
return ftello((FILE *)_stream);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const OpusFileCallbacks OP_FILE_CALLBACKS={
|
||||
op_fread,
|
||||
op_fseek,
|
||||
op_ftell,
|
||||
(op_close_func)fclose
|
||||
};
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <stddef.h>
|
||||
# include <errno.h>
|
||||
|
||||
/*Windows doesn't accept UTF-8 by default, and we don't have a wchar_t API,
|
||||
so if we just pass the path to fopen(), then there'd be no way for a user
|
||||
of our API to open a Unicode filename.
|
||||
Instead, we translate from UTF-8 to UTF-16 and use Windows' wchar_t API.
|
||||
This makes this API more consistent with platforms where the character set
|
||||
used by fopen is the same as used on disk, which is generally UTF-8, and
|
||||
with our metadata API, which always uses UTF-8.*/
|
||||
static wchar_t *op_utf8_to_utf16(const char *_src){
|
||||
wchar_t *dst;
|
||||
size_t len;
|
||||
len=strlen(_src);
|
||||
/*Worst-case output is 1 wide character per 1 input character.*/
|
||||
dst=(wchar_t *)_ogg_malloc(sizeof(*dst)*(len+1));
|
||||
if(dst!=NULL){
|
||||
size_t si;
|
||||
size_t di;
|
||||
for(di=si=0;si<len;si++){
|
||||
int c0;
|
||||
c0=(unsigned char)_src[si];
|
||||
if(!(c0&0x80)){
|
||||
/*Start byte says this is a 1-byte sequence.*/
|
||||
dst[di++]=(wchar_t)c0;
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
int c1;
|
||||
/*This is safe, because c0 was not 0 and _src is NUL-terminated.*/
|
||||
c1=(unsigned char)_src[si+1];
|
||||
if((c1&0xC0)==0x80){
|
||||
/*Found at least one continuation byte.*/
|
||||
if((c0&0xE0)==0xC0){
|
||||
wchar_t w;
|
||||
/*Start byte says this is a 2-byte sequence.*/
|
||||
w=(c0&0x1F)<<6|c1&0x3F;
|
||||
if(w>=0x80U){
|
||||
/*This is a 2-byte sequence that is not overlong.*/
|
||||
dst[di++]=w;
|
||||
si++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else{
|
||||
int c2;
|
||||
/*This is safe, because c1 was not 0 and _src is NUL-terminated.*/
|
||||
c2=(unsigned char)_src[si+2];
|
||||
if((c2&0xC0)==0x80){
|
||||
/*Found at least two continuation bytes.*/
|
||||
if((c0&0xF0)==0xE0){
|
||||
wchar_t w;
|
||||
/*Start byte says this is a 3-byte sequence.*/
|
||||
w=(c0&0xF)<<12|(c1&0x3F)<<6|c2&0x3F;
|
||||
if(w>=0x800U&&(w<0xD800||w>=0xE000)&&w<0xFFFE){
|
||||
/*This is a 3-byte sequence that is not overlong, not a
|
||||
UTF-16 surrogate pair value, and not a 'not a character'
|
||||
value.*/
|
||||
dst[di++]=w;
|
||||
si+=2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else{
|
||||
int c3;
|
||||
/*This is safe, because c2 was not 0 and _src is
|
||||
NUL-terminated.*/
|
||||
c3=(unsigned char)_src[si+3];
|
||||
if((c3&0xC0)==0x80){
|
||||
/*Found at least three continuation bytes.*/
|
||||
if((c0&0xF8)==0xF0){
|
||||
opus_uint32 w;
|
||||
/*Start byte says this is a 4-byte sequence.*/
|
||||
w=(c0&7)<<18|(c1&0x3F)<<12|(c2&0x3F)<<6&(c3&0x3F);
|
||||
if(w>=0x10000U&&w<0x110000U){
|
||||
/*This is a 4-byte sequence that is not overlong and not
|
||||
greater than the largest valid Unicode code point.
|
||||
Convert it to a surrogate pair.*/
|
||||
w-=0x10000;
|
||||
dst[di++]=(wchar_t)(0xD800+(w>>10));
|
||||
dst[di++]=(wchar_t)(0xDC00+(w&0x3FF));
|
||||
si+=3;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*If we got here, we encountered an illegal UTF-8 sequence.*/
|
||||
_ogg_free(dst);
|
||||
return NULL;
|
||||
}
|
||||
OP_ASSERT(di<=len);
|
||||
dst[di]='\0';
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void *op_fopen(OpusFileCallbacks *_cb,const char *_path,const char *_mode){
|
||||
FILE *fp;
|
||||
#if !defined(_WIN32)
|
||||
fp=fopen(_path,_mode);
|
||||
#else
|
||||
fp=NULL;
|
||||
if(_path==NULL||_mode==NULL)errno=EINVAL;
|
||||
else{
|
||||
wchar_t *wpath;
|
||||
wchar_t *wmode;
|
||||
wpath=op_utf8_to_utf16(_path);
|
||||
wmode=op_utf8_to_utf16(_mode);
|
||||
if(wmode==NULL)errno=EINVAL;
|
||||
else if(wpath==NULL)errno=ENOENT;
|
||||
else fp=_wfopen(wpath,wmode);
|
||||
_ogg_free(wmode);
|
||||
_ogg_free(wpath);
|
||||
}
|
||||
#endif
|
||||
if(fp!=NULL)*_cb=*&OP_FILE_CALLBACKS;
|
||||
return fp;
|
||||
}
|
||||
|
||||
void *op_fdopen(OpusFileCallbacks *_cb,int _fd,const char *_mode){
|
||||
FILE *fp;
|
||||
fp=fdopen(_fd,_mode);
|
||||
if(fp!=NULL)*_cb=*&OP_FILE_CALLBACKS;
|
||||
return fp;
|
||||
}
|
||||
|
||||
void *op_freopen(OpusFileCallbacks *_cb,const char *_path,const char *_mode,
|
||||
void *_stream){
|
||||
FILE *fp;
|
||||
#if !defined(_WIN32)
|
||||
fp=freopen(_path,_mode,(FILE *)_stream);
|
||||
#else
|
||||
fp=NULL;
|
||||
if(_path==NULL||_mode==NULL)errno=EINVAL;
|
||||
else{
|
||||
wchar_t *wpath;
|
||||
wchar_t *wmode;
|
||||
wpath=op_utf8_to_utf16(_path);
|
||||
wmode=op_utf8_to_utf16(_mode);
|
||||
if(wmode==NULL)errno=EINVAL;
|
||||
else if(wpath==NULL)errno=ENOENT;
|
||||
else fp=_wfreopen(wpath,wmode,(FILE *)_stream);
|
||||
_ogg_free(wmode);
|
||||
_ogg_free(wpath);
|
||||
}
|
||||
#endif
|
||||
if(fp!=NULL)*_cb=*&OP_FILE_CALLBACKS;
|
||||
return fp;
|
||||
}
|
||||
|
||||
static int op_mem_read(void *_stream,unsigned char *_ptr,int _buf_size){
|
||||
OpusMemStream *stream;
|
||||
ptrdiff_t size;
|
||||
ptrdiff_t pos;
|
||||
stream=(OpusMemStream *)_stream;
|
||||
/*Check for empty read.*/
|
||||
if(_buf_size<=0)return 0;
|
||||
size=stream->size;
|
||||
pos=stream->pos;
|
||||
/*Check for EOF.*/
|
||||
if(pos>=size)return 0;
|
||||
/*Check for a short read.*/
|
||||
_buf_size=(int)OP_MIN(size-pos,_buf_size);
|
||||
memcpy(_ptr,stream->data+pos,_buf_size);
|
||||
pos+=_buf_size;
|
||||
stream->pos=pos;
|
||||
return _buf_size;
|
||||
}
|
||||
|
||||
static int op_mem_seek(void *_stream,opus_int64 _offset,int _whence){
|
||||
OpusMemStream *stream;
|
||||
ptrdiff_t pos;
|
||||
stream=(OpusMemStream *)_stream;
|
||||
pos=stream->pos;
|
||||
OP_ASSERT(pos>=0);
|
||||
switch(_whence){
|
||||
case SEEK_SET:{
|
||||
/*Check for overflow:*/
|
||||
if(_offset<0||_offset>OP_MEM_DIFF_MAX)return -1;
|
||||
pos=(ptrdiff_t)_offset;
|
||||
}break;
|
||||
case SEEK_CUR:{
|
||||
/*Check for overflow:*/
|
||||
if(_offset<-pos||_offset>OP_MEM_DIFF_MAX-pos)return -1;
|
||||
pos=(ptrdiff_t)(pos+_offset);
|
||||
}break;
|
||||
case SEEK_END:{
|
||||
ptrdiff_t size;
|
||||
size=stream->size;
|
||||
OP_ASSERT(size>=0);
|
||||
/*Check for overflow:*/
|
||||
if(_offset>size||_offset<size-OP_MEM_DIFF_MAX)return -1;
|
||||
pos=(ptrdiff_t)(size-_offset);
|
||||
}break;
|
||||
default:return -1;
|
||||
}
|
||||
stream->pos=pos;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static opus_int64 op_mem_tell(void *_stream){
|
||||
OpusMemStream *stream;
|
||||
stream=(OpusMemStream *)_stream;
|
||||
return (ogg_int64_t)stream->pos;
|
||||
}
|
||||
|
||||
static int op_mem_close(void *_stream){
|
||||
_ogg_free(_stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const OpusFileCallbacks OP_MEM_CALLBACKS={
|
||||
op_mem_read,
|
||||
op_mem_seek,
|
||||
op_mem_tell,
|
||||
op_mem_close
|
||||
};
|
||||
|
||||
void *op_mem_stream_create(OpusFileCallbacks *_cb,
|
||||
const unsigned char *_data,size_t _size){
|
||||
OpusMemStream *stream;
|
||||
if(_size>OP_MEM_SIZE_MAX)return NULL;
|
||||
stream=(OpusMemStream *)_ogg_malloc(sizeof(*stream));
|
||||
if(stream!=NULL){
|
||||
*_cb=*&OP_MEM_CALLBACKS;
|
||||
stream->data=_data;
|
||||
stream->size=_size;
|
||||
stream->pos=0;
|
||||
}
|
||||
return stream;
|
||||
}
|
171
src/engine/external/opusfile/wincerts.c
vendored
171
src/engine/external/opusfile/wincerts.c
vendored
|
@ -1,171 +0,0 @@
|
|||
/********************************************************************
|
||||
* *
|
||||
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. *
|
||||
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
||||
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2013 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************/
|
||||
|
||||
/*This should really be part of OpenSSL, but there's been a patch [1] sitting
|
||||
in their bugtracker for over two years that implements this, without any
|
||||
action, so I'm giving up and re-implementing it locally.
|
||||
|
||||
[1] <http://rt.openssl.org/Ticket/Display.html?id=2158>*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "internal.h"
|
||||
#if defined(OP_ENABLE_HTTP)&&defined(_WIN32)
|
||||
/*You must include windows.h before wincrypt.h and x509.h.*/
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_EXTRA_LEAN
|
||||
# include <windows.h>
|
||||
/*You must include wincrypt.h before x509.h, too, or X509_NAME doesn't get
|
||||
defined properly.*/
|
||||
# include <wincrypt.h>
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/x509.h>
|
||||
|
||||
static int op_capi_new(X509_LOOKUP *_lu){
|
||||
HCERTSTORE h_store;
|
||||
h_store=CertOpenStore(CERT_STORE_PROV_SYSTEM_A,0,0,
|
||||
CERT_STORE_OPEN_EXISTING_FLAG|CERT_STORE_READONLY_FLAG|
|
||||
CERT_SYSTEM_STORE_CURRENT_USER|CERT_STORE_SHARE_CONTEXT_FLAG,"ROOT");
|
||||
if(h_store!=NULL){
|
||||
_lu->method_data=(char *)h_store;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void op_capi_free(X509_LOOKUP *_lu){
|
||||
HCERTSTORE h_store;
|
||||
h_store=(HCERTSTORE)_lu->method_data;
|
||||
# if defined(OP_ENABLE_ASSERTIONS)
|
||||
OP_ALWAYS_TRUE(CertCloseStore(h_store,CERT_CLOSE_STORE_CHECK_FLAG));
|
||||
# else
|
||||
CertCloseStore(h_store,0);
|
||||
# endif
|
||||
}
|
||||
|
||||
static int op_capi_retrieve_by_subject(X509_LOOKUP *_lu,int _type,
|
||||
X509_NAME *_name,X509_OBJECT *_ret){
|
||||
X509_OBJECT *obj;
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
|
||||
obj=X509_OBJECT_retrieve_by_subject(_lu->store_ctx->objs,_type,_name);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
|
||||
if(obj!=NULL){
|
||||
_ret->type=obj->type;
|
||||
memcpy(&_ret->data,&obj->data,sizeof(_ret->data));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int op_capi_get_by_subject(X509_LOOKUP *_lu,int _type,X509_NAME *_name,
|
||||
X509_OBJECT *_ret){
|
||||
HCERTSTORE h_store;
|
||||
if(_name==NULL)return 0;
|
||||
if(_name->bytes==NULL||_name->bytes->length<=0||_name->modified){
|
||||
if(i2d_X509_NAME(_name,NULL)<0)return 0;
|
||||
OP_ASSERT(_name->bytes->length>0);
|
||||
}
|
||||
h_store=(HCERTSTORE)_lu->method_data;
|
||||
switch(_type){
|
||||
case X509_LU_X509:{
|
||||
CERT_NAME_BLOB find_para;
|
||||
PCCERT_CONTEXT cert;
|
||||
X509 *x;
|
||||
int ret;
|
||||
/*Although X509_NAME contains a canon_enc field, that "canonical" [1]
|
||||
encoding was just made up by OpenSSL.
|
||||
It doesn't correspond to any actual standard, and since it drops the
|
||||
initial sequence header, won't be recognized by the Crypto API.
|
||||
The assumption here is that CertFindCertificateInStore() will allow any
|
||||
appropriate variations in the encoding when it does its comparison.
|
||||
This is, however, emphatically not true under Wine, which just compares
|
||||
the encodings with memcmp().
|
||||
Most of the time things work anyway, though, and there isn't really
|
||||
anything we can do to make the situation better.
|
||||
|
||||
[1] A "canonical form" is defined as the one where, if you locked 10
|
||||
mathematicians in a room and asked them to come up with a
|
||||
representation for something, it's the answer that 9 of them would
|
||||
give you back.
|
||||
I don't think OpenSSL's encoding qualifies.*/
|
||||
find_para.cbData=_name->bytes->length;
|
||||
find_para.pbData=(unsigned char *)_name->bytes->data;
|
||||
cert=CertFindCertificateInStore(h_store,X509_ASN_ENCODING,0,
|
||||
CERT_FIND_SUBJECT_NAME,&find_para,NULL);
|
||||
if(cert==NULL)return 0;
|
||||
x=d2i_X509(NULL,(const unsigned char **)&cert->pbCertEncoded,
|
||||
cert->cbCertEncoded);
|
||||
CertFreeCertificateContext(cert);
|
||||
if(x==NULL)return 0;
|
||||
ret=X509_STORE_add_cert(_lu->store_ctx,x);
|
||||
X509_free(x);
|
||||
if(ret)return op_capi_retrieve_by_subject(_lu,_type,_name,_ret);
|
||||
}break;
|
||||
case X509_LU_CRL:{
|
||||
CERT_INFO cert_info;
|
||||
CERT_CONTEXT find_para;
|
||||
PCCRL_CONTEXT crl;
|
||||
X509_CRL *x;
|
||||
int ret;
|
||||
ret=op_capi_retrieve_by_subject(_lu,_type,_name,_ret);
|
||||
if(ret>0)return ret;
|
||||
memset(&cert_info,0,sizeof(cert_info));
|
||||
cert_info.Issuer.cbData=_name->bytes->length;
|
||||
cert_info.Issuer.pbData=(unsigned char *)_name->bytes->data;
|
||||
memset(&find_para,0,sizeof(find_para));
|
||||
find_para.pCertInfo=&cert_info;
|
||||
crl=CertFindCRLInStore(h_store,0,0,CRL_FIND_ISSUED_BY,&find_para,NULL);
|
||||
if(crl==NULL)return 0;
|
||||
x=d2i_X509_CRL(NULL,(const unsigned char **)&crl->pbCrlEncoded,
|
||||
crl->cbCrlEncoded);
|
||||
CertFreeCRLContext(crl);
|
||||
if(x==NULL)return 0;
|
||||
ret=X509_STORE_add_crl(_lu->store_ctx,x);
|
||||
X509_CRL_free(x);
|
||||
if(ret)return op_capi_retrieve_by_subject(_lu,_type,_name,_ret);
|
||||
}break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*This is not const because OpenSSL doesn't allow it, even though it won't
|
||||
write to it.*/
|
||||
static X509_LOOKUP_METHOD X509_LOOKUP_CAPI={
|
||||
"Load Crypto API store into cache",
|
||||
op_capi_new,
|
||||
op_capi_free,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
op_capi_get_by_subject,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
int SSL_CTX_set_default_verify_paths_win32(SSL_CTX *_ssl_ctx){
|
||||
X509_STORE *store;
|
||||
X509_LOOKUP *lu;
|
||||
/*We intentionally do not add the normal default paths, as they are usually
|
||||
wrong, and are just asking to be used as an exploit vector.*/
|
||||
store=SSL_CTX_get_cert_store(_ssl_ctx);
|
||||
OP_ASSERT(store!=NULL);
|
||||
lu=X509_STORE_add_lookup(store,&X509_LOOKUP_CAPI);
|
||||
if(lu==NULL)return 0;
|
||||
ERR_clear_error();
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
90
src/engine/external/opusfile/winerrno.h
vendored
90
src/engine/external/opusfile/winerrno.h
vendored
|
@ -1,90 +0,0 @@
|
|||
/********************************************************************
|
||||
* *
|
||||
* THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. *
|
||||
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
|
||||
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE libopusfile SOURCE CODE IS (C) COPYRIGHT 2012 *
|
||||
* by the Xiph.Org Foundation and contributors http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************/
|
||||
#if !defined(_opusfile_winerrno_h)
|
||||
# define _opusfile_winerrno_h (1)
|
||||
|
||||
# include <errno.h>
|
||||
# include <winerror.h>
|
||||
|
||||
/*These conflict with the MSVC errno.h definitions, but we don't need to use
|
||||
the original ones in any file that deals with sockets.
|
||||
We could map the WSA errors to the errno.h ones (most of which are only
|
||||
available on sufficiently new versions of MSVC), but they aren't ordered the
|
||||
same, and given how rarely we actually look at the values, I don't think
|
||||
it's worth a lookup table.*/
|
||||
# undef EWOULDBLOCK
|
||||
# undef EINPROGRESS
|
||||
# undef EALREADY
|
||||
# undef ENOTSOCK
|
||||
# undef EDESTADDRREQ
|
||||
# undef EMSGSIZE
|
||||
# undef EPROTOTYPE
|
||||
# undef ENOPROTOOPT
|
||||
# undef EPROTONOSUPPORT
|
||||
# undef EOPNOTSUPP
|
||||
# undef EAFNOSUPPORT
|
||||
# undef EADDRINUSE
|
||||
# undef EADDRNOTAVAIL
|
||||
# undef ENETDOWN
|
||||
# undef ENETUNREACH
|
||||
# undef ENETRESET
|
||||
# undef ECONNABORTED
|
||||
# undef ECONNRESET
|
||||
# undef ENOBUFS
|
||||
# undef EISCONN
|
||||
# undef ENOTCONN
|
||||
# undef ETIMEDOUT
|
||||
# undef ECONNREFUSED
|
||||
# undef ELOOP
|
||||
# undef ENAMETOOLONG
|
||||
# undef EHOSTUNREACH
|
||||
# undef ENOTEMPTY
|
||||
|
||||
# define EWOULDBLOCK (WSAEWOULDBLOCK-WSABASEERR)
|
||||
# define EINPROGRESS (WSAEINPROGRESS-WSABASEERR)
|
||||
# define EALREADY (WSAEALREADY-WSABASEERR)
|
||||
# define ENOTSOCK (WSAENOTSOCK-WSABASEERR)
|
||||
# define EDESTADDRREQ (WSAEDESTADDRREQ-WSABASEERR)
|
||||
# define EMSGSIZE (WSAEMSGSIZE-WSABASEERR)
|
||||
# define EPROTOTYPE (WSAEPROTOTYPE-WSABASEERR)
|
||||
# define ENOPROTOOPT (WSAENOPROTOOPT-WSABASEERR)
|
||||
# define EPROTONOSUPPORT (WSAEPROTONOSUPPORT-WSABASEERR)
|
||||
# define ESOCKTNOSUPPORT (WSAESOCKTNOSUPPORT-WSABASEERR)
|
||||
# define EOPNOTSUPP (WSAEOPNOTSUPP-WSABASEERR)
|
||||
# define EPFNOSUPPORT (WSAEPFNOSUPPORT-WSABASEERR)
|
||||
# define EAFNOSUPPORT (WSAEAFNOSUPPORT-WSABASEERR)
|
||||
# define EADDRINUSE (WSAEADDRINUSE-WSABASEERR)
|
||||
# define EADDRNOTAVAIL (WSAEADDRNOTAVAIL-WSABASEERR)
|
||||
# define ENETDOWN (WSAENETDOWN-WSABASEERR)
|
||||
# define ENETUNREACH (WSAENETUNREACH-WSABASEERR)
|
||||
# define ENETRESET (WSAENETRESET-WSABASEERR)
|
||||
# define ECONNABORTED (WSAECONNABORTED-WSABASEERR)
|
||||
# define ECONNRESET (WSAECONNRESET-WSABASEERR)
|
||||
# define ENOBUFS (WSAENOBUFS-WSABASEERR)
|
||||
# define EISCONN (WSAEISCONN-WSABASEERR)
|
||||
# define ENOTCONN (WSAENOTCONN-WSABASEERR)
|
||||
# define ESHUTDOWN (WSAESHUTDOWN-WSABASEERR)
|
||||
# define ETOOMANYREFS (WSAETOOMANYREFS-WSABASEERR)
|
||||
# define ETIMEDOUT (WSAETIMEDOUT-WSABASEERR)
|
||||
# define ECONNREFUSED (WSAECONNREFUSED-WSABASEERR)
|
||||
# define ELOOP (WSAELOOP-WSABASEERR)
|
||||
# define ENAMETOOLONG (WSAENAMETOOLONG-WSABASEERR)
|
||||
# define EHOSTDOWN (WSAEHOSTDOWN-WSABASEERR)
|
||||
# define EHOSTUNREACH (WSAEHOSTUNREACH-WSABASEERR)
|
||||
# define ENOTEMPTY (WSAENOTEMPTY-WSABASEERR)
|
||||
# define EPROCLIM (WSAEPROCLIM-WSABASEERR)
|
||||
# define EUSERS (WSAEUSERS-WSABASEERR)
|
||||
# define EDQUOT (WSAEDQUOT-WSABASEERR)
|
||||
# define ESTALE (WSAESTALE-WSABASEERR)
|
||||
# define EREMOTE (WSAEREMOTE-WSABASEERR)
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue