michael@0: /******************************************************************** michael@0: * * michael@0: * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * michael@0: * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * michael@0: * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * michael@0: * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * michael@0: * * michael@0: * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * michael@0: * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * michael@0: * * michael@0: ******************************************************************** michael@0: michael@0: function: michael@0: last mod: $Id: info.c 16503 2009-08-22 18:14:02Z giles $ michael@0: michael@0: ********************************************************************/ michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #include "internal.h" michael@0: michael@0: michael@0: michael@0: /*This is more or less the same as strncasecmp, but that doesn't exist michael@0: everywhere, and this is a fairly trivial function, so we include it. michael@0: Note: We take advantage of the fact that we know _n is less than or equal to michael@0: the length of at least one of the strings.*/ michael@0: static int oc_tagcompare(const char *_s1,const char *_s2,int _n){ michael@0: int c; michael@0: for(c=0;c<_n;c++){ michael@0: if(toupper(_s1[c])!=toupper(_s2[c]))return !0; michael@0: } michael@0: return _s1[c]!='='; michael@0: } michael@0: michael@0: michael@0: michael@0: void th_info_init(th_info *_info){ michael@0: memset(_info,0,sizeof(*_info)); michael@0: _info->version_major=TH_VERSION_MAJOR; michael@0: _info->version_minor=TH_VERSION_MINOR; michael@0: _info->version_subminor=TH_VERSION_SUB; michael@0: _info->keyframe_granule_shift=6; michael@0: } michael@0: michael@0: void th_info_clear(th_info *_info){ michael@0: memset(_info,0,sizeof(*_info)); michael@0: } michael@0: michael@0: michael@0: michael@0: void th_comment_init(th_comment *_tc){ michael@0: memset(_tc,0,sizeof(*_tc)); michael@0: } michael@0: michael@0: void th_comment_add(th_comment *_tc,char *_comment){ michael@0: char **user_comments; michael@0: int *comment_lengths; michael@0: int comment_len; michael@0: user_comments=_ogg_realloc(_tc->user_comments, michael@0: (_tc->comments+2)*sizeof(*_tc->user_comments)); michael@0: if(user_comments==NULL)return; michael@0: _tc->user_comments=user_comments; michael@0: comment_lengths=_ogg_realloc(_tc->comment_lengths, michael@0: (_tc->comments+2)*sizeof(*_tc->comment_lengths)); michael@0: if(comment_lengths==NULL)return; michael@0: _tc->comment_lengths=comment_lengths; michael@0: comment_len=strlen(_comment); michael@0: comment_lengths[_tc->comments]=comment_len; michael@0: user_comments[_tc->comments]=_ogg_malloc(comment_len+1); michael@0: if(user_comments[_tc->comments]==NULL)return; michael@0: memcpy(_tc->user_comments[_tc->comments],_comment,comment_len+1); michael@0: _tc->comments++; michael@0: _tc->user_comments[_tc->comments]=NULL; michael@0: } michael@0: michael@0: void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val){ michael@0: char *comment; michael@0: int tag_len; michael@0: int val_len; michael@0: tag_len=strlen(_tag); michael@0: val_len=strlen(_val); michael@0: /*+2 for '=' and '\0'.*/ michael@0: comment=_ogg_malloc(tag_len+val_len+2); michael@0: if(comment==NULL)return; michael@0: memcpy(comment,_tag,tag_len); michael@0: comment[tag_len]='='; michael@0: memcpy(comment+tag_len+1,_val,val_len+1); michael@0: th_comment_add(_tc,comment); michael@0: _ogg_free(comment); michael@0: } michael@0: michael@0: char *th_comment_query(th_comment *_tc,char *_tag,int _count){ michael@0: long i; michael@0: int found; michael@0: int tag_len; michael@0: tag_len=strlen(_tag); michael@0: found=0; michael@0: for(i=0;i<_tc->comments;i++){ michael@0: if(!oc_tagcompare(_tc->user_comments[i],_tag,tag_len)){ michael@0: /*We return a pointer to the data, not a copy.*/ michael@0: if(_count==found++)return _tc->user_comments[i]+tag_len+1; michael@0: } michael@0: } michael@0: /*Didn't find anything.*/ michael@0: return NULL; michael@0: } michael@0: michael@0: int th_comment_query_count(th_comment *_tc,char *_tag){ michael@0: long i; michael@0: int tag_len; michael@0: int count; michael@0: tag_len=strlen(_tag); michael@0: count=0; michael@0: for(i=0;i<_tc->comments;i++){ michael@0: if(!oc_tagcompare(_tc->user_comments[i],_tag,tag_len))count++; michael@0: } michael@0: return count; michael@0: } michael@0: michael@0: void th_comment_clear(th_comment *_tc){ michael@0: if(_tc!=NULL){ michael@0: long i; michael@0: for(i=0;i<_tc->comments;i++)_ogg_free(_tc->user_comments[i]); michael@0: _ogg_free(_tc->user_comments); michael@0: _ogg_free(_tc->comment_lengths); michael@0: _ogg_free(_tc->vendor); michael@0: memset(_tc,0,sizeof(*_tc)); michael@0: } michael@0: }