metadata_object.c
来自「这是著名的TCPMP播放器在WINDWOWS,和WINCE下编译通过的源程序.笔」· C语言 代码 · 共 1,474 行 · 第 1/4 页
C
1,474 行
cuesheet_calculate_length_(object);
return true;
}
/****************************************************************************
*
* Metadata object routines
*
***************************************************************************/
FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_new(FLAC__MetadataType type)
{
FLAC__StreamMetadata *object;
if(type > FLAC__MAX_METADATA_TYPE_CODE)
return 0;
object = (FLAC__StreamMetadata*)calloc(1, sizeof(FLAC__StreamMetadata));
if(0 != object) {
object->is_last = false;
object->type = type;
switch(type) {
case FLAC__METADATA_TYPE_STREAMINFO:
object->length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
break;
case FLAC__METADATA_TYPE_PADDING:
/* calloc() took care of this for us:
object->length = 0;
*/
break;
case FLAC__METADATA_TYPE_APPLICATION:
object->length = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8;
/* calloc() took care of this for us:
object->data.application.data = 0;
*/
break;
case FLAC__METADATA_TYPE_SEEKTABLE:
/* calloc() took care of this for us:
object->length = 0;
object->data.seek_table.num_points = 0;
object->data.seek_table.points = 0;
*/
break;
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
{
object->data.vorbis_comment.vendor_string.length = (unsigned)strlen(FLAC__VENDOR_STRING);
if(!copy_bytes_(&object->data.vorbis_comment.vendor_string.entry, (const FLAC__byte*)FLAC__VENDOR_STRING, object->data.vorbis_comment.vendor_string.length+1)) {
free(object);
return 0;
}
vorbiscomment_calculate_length_(object);
}
break;
case FLAC__METADATA_TYPE_CUESHEET:
cuesheet_calculate_length_(object);
break;
default:
/* calloc() took care of this for us:
object->length = 0;
object->data.unknown.data = 0;
*/
break;
}
}
return object;
}
FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMetadata *object)
{
FLAC__StreamMetadata *to;
FLAC__ASSERT(0 != object);
if(0 != (to = FLAC__metadata_object_new(object->type))) {
to->is_last = object->is_last;
to->type = object->type;
to->length = object->length;
switch(to->type) {
case FLAC__METADATA_TYPE_STREAMINFO:
memcpy(&to->data.stream_info, &object->data.stream_info, sizeof(FLAC__StreamMetadata_StreamInfo));
break;
case FLAC__METADATA_TYPE_PADDING:
break;
case FLAC__METADATA_TYPE_APPLICATION:
memcpy(&to->data.application.id, &object->data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8);
if(!copy_bytes_(&to->data.application.data, object->data.application.data, object->length - FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)) {
FLAC__metadata_object_delete(to);
return 0;
}
break;
case FLAC__METADATA_TYPE_SEEKTABLE:
to->data.seek_table.num_points = object->data.seek_table.num_points;
if(!copy_bytes_((FLAC__byte**)&to->data.seek_table.points, (FLAC__byte*)object->data.seek_table.points, object->data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint))) {
FLAC__metadata_object_delete(to);
return 0;
}
break;
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
if(0 != to->data.vorbis_comment.vendor_string.entry) {
free(to->data.vorbis_comment.vendor_string.entry);
to->data.vorbis_comment.vendor_string.entry = 0;
}
if(!copy_vcentry_(&to->data.vorbis_comment.vendor_string, &object->data.vorbis_comment.vendor_string)) {
FLAC__metadata_object_delete(to);
return 0;
}
if(object->data.vorbis_comment.num_comments == 0) {
FLAC__ASSERT(0 == object->data.vorbis_comment.comments);
to->data.vorbis_comment.comments = 0;
}
else {
FLAC__ASSERT(0 != object->data.vorbis_comment.comments);
to->data.vorbis_comment.comments = vorbiscomment_entry_array_copy_(object->data.vorbis_comment.comments, object->data.vorbis_comment.num_comments);
if(0 == to->data.vorbis_comment.comments) {
FLAC__metadata_object_delete(to);
return 0;
}
}
to->data.vorbis_comment.num_comments = object->data.vorbis_comment.num_comments;
break;
case FLAC__METADATA_TYPE_CUESHEET:
memcpy(&to->data.cue_sheet, &object->data.cue_sheet, sizeof(FLAC__StreamMetadata_CueSheet));
if(object->data.cue_sheet.num_tracks == 0) {
FLAC__ASSERT(0 == object->data.cue_sheet.tracks);
}
else {
FLAC__ASSERT(0 != object->data.cue_sheet.tracks);
to->data.cue_sheet.tracks = cuesheet_track_array_copy_(object->data.cue_sheet.tracks, object->data.cue_sheet.num_tracks);
if(0 == to->data.cue_sheet.tracks) {
FLAC__metadata_object_delete(to);
return 0;
}
}
break;
default:
if(!copy_bytes_(&to->data.unknown.data, object->data.unknown.data, object->length)) {
FLAC__metadata_object_delete(to);
return 0;
}
break;
}
}
return to;
}
void FLAC__metadata_object_delete_data(FLAC__StreamMetadata *object)
{
FLAC__ASSERT(0 != object);
switch(object->type) {
case FLAC__METADATA_TYPE_STREAMINFO:
case FLAC__METADATA_TYPE_PADDING:
break;
case FLAC__METADATA_TYPE_APPLICATION:
if(0 != object->data.application.data) {
free(object->data.application.data);
object->data.application.data = 0;
}
break;
case FLAC__METADATA_TYPE_SEEKTABLE:
if(0 != object->data.seek_table.points) {
free(object->data.seek_table.points);
object->data.seek_table.points = 0;
}
break;
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
if(0 != object->data.vorbis_comment.vendor_string.entry) {
free(object->data.vorbis_comment.vendor_string.entry);
object->data.vorbis_comment.vendor_string.entry = 0;
}
if(0 != object->data.vorbis_comment.comments) {
FLAC__ASSERT(object->data.vorbis_comment.num_comments > 0);
vorbiscomment_entry_array_delete_(object->data.vorbis_comment.comments, object->data.vorbis_comment.num_comments);
}
break;
case FLAC__METADATA_TYPE_CUESHEET:
if(0 != object->data.cue_sheet.tracks) {
FLAC__ASSERT(object->data.cue_sheet.num_tracks > 0);
cuesheet_track_array_delete_(object->data.cue_sheet.tracks, object->data.cue_sheet.num_tracks);
}
break;
default:
if(0 != object->data.unknown.data) {
free(object->data.unknown.data);
object->data.unknown.data = 0;
}
break;
}
}
FLAC_API void FLAC__metadata_object_delete(FLAC__StreamMetadata *object)
{
FLAC__metadata_object_delete_data(object);
free(object);
}
static FLAC__bool compare_block_data_streaminfo_(const FLAC__StreamMetadata_StreamInfo *block1, const FLAC__StreamMetadata_StreamInfo *block2)
{
if(block1->min_blocksize != block2->min_blocksize)
return false;
if(block1->max_blocksize != block2->max_blocksize)
return false;
if(block1->min_framesize != block2->min_framesize)
return false;
if(block1->max_framesize != block2->max_framesize)
return false;
if(block1->sample_rate != block2->sample_rate)
return false;
if(block1->channels != block2->channels)
return false;
if(block1->bits_per_sample != block2->bits_per_sample)
return false;
if(block1->total_samples != block2->total_samples)
return false;
if(0 != memcmp(block1->md5sum, block2->md5sum, 16))
return false;
return true;
}
static FLAC__bool compare_block_data_application_(const FLAC__StreamMetadata_Application *block1, const FLAC__StreamMetadata_Application *block2, unsigned block_length)
{
FLAC__ASSERT(0 != block1);
FLAC__ASSERT(0 != block2);
FLAC__ASSERT(block_length >= sizeof(block1->id));
if(0 != memcmp(block1->id, block2->id, sizeof(block1->id)))
return false;
if(0 != block1->data && 0 != block2->data)
return 0 == memcmp(block1->data, block2->data, block_length - sizeof(block1->id));
else
return block1->data == block2->data;
}
static FLAC__bool compare_block_data_seektable_(const FLAC__StreamMetadata_SeekTable *block1, const FLAC__StreamMetadata_SeekTable *block2)
{
unsigned i;
FLAC__ASSERT(0 != block1);
FLAC__ASSERT(0 != block2);
if(block1->num_points != block2->num_points)
return false;
if(0 != block1->points && 0 != block2->points) {
for(i = 0; i < block1->num_points; i++) {
if(block1->points[i].sample_number != block2->points[i].sample_number)
return false;
if(block1->points[i].stream_offset != block2->points[i].stream_offset)
return false;
if(block1->points[i].frame_samples != block2->points[i].frame_samples)
return false;
}
return true;
}
else
return block1->points == block2->points;
}
static FLAC__bool compare_block_data_vorbiscomment_(const FLAC__StreamMetadata_VorbisComment *block1, const FLAC__StreamMetadata_VorbisComment *block2)
{
unsigned i;
if(block1->vendor_string.length != block2->vendor_string.length)
return false;
if(0 != block1->vendor_string.entry && 0 != block2->vendor_string.entry) {
if(0 != memcmp(block1->vendor_string.entry, block2->vendor_string.entry, block1->vendor_string.length))
return false;
}
else if(block1->vendor_string.entry != block2->vendor_string.entry)
return false;
if(block1->num_comments != block2->num_comments)
return false;
for(i = 0; i < block1->num_comments; i++) {
if(0 != block1->comments[i].entry && 0 != block2->comments[i].entry) {
if(0 != memcmp(block1->comments[i].entry, block2->comments[i].entry, block1->comments[i].length))
return false;
}
else if(block1->comments[i].entry != block2->comments[i].entry)
return false;
}
return true;
}
static FLAC__bool compare_block_data_cuesheet_(const FLAC__StreamMetadata_CueSheet *block1, const FLAC__StreamMetadata_CueSheet *block2)
{
unsigned i, j;
if(0 != strcmp(block1->media_catalog_number, block2->media_catalog_number))
return false;
if(block1->lead_in != block2->lead_in)
return false;
if(block1->is_cd != block2->is_cd)
return false;
if(block1->num_tracks != block2->num_tracks)
return false;
if(0 != block1->tracks && 0 != block2->tracks) {
FLAC__ASSERT(block1->num_tracks > 0);
for(i = 0; i < block1->num_tracks; i++) {
if(block1->tracks[i].offset != block2->tracks[i].offset)
return false;
if(block1->tracks[i].number != block2->tracks[i].number)
return false;
if(0 != memcmp(block1->tracks[i].isrc, block2->tracks[i].isrc, sizeof(block1->tracks[i].isrc)))
return false;
if(block1->tracks[i].type != block2->tracks[i].type)
return false;
if(block1->tracks[i].pre_emphasis != block2->tracks[i].pre_emphasis)
return false;
if(block1->tracks[i].num_indices != block2->tracks[i].num_indices)
return false;
if(0 != block1->tracks[i].indices && 0 != block2->tracks[i].indices) {
FLAC__ASSERT(block1->tracks[i].num_indices > 0);
for(j = 0; j < block1->tracks[i].num_indices; j++) {
if(block1->tracks[i].indices[j].offset != block2->tracks[i].indices[j].offset)
return false;
if(block1->tracks[i].indices[j].number != block2->tracks[i].indices[j].number)
return false;
}
}
else if(block1->tracks[i].indices != block2->tracks[i].indices)
return false;
}
}
else if(block1->tracks != block2->tracks)
return false;
return true;
}
static FLAC__bool compare_block_data_unknown_(const FLAC__StreamMetadata_Unknown *block1, const FLAC__StreamMetadata_Unknown *block2, unsigned block_length)
{
FLAC__ASSERT(0 != block1);
FLAC__ASSERT(0 != block2);
if(0 != block1->data && 0 != block2->data)
return 0 == memcmp(block1->data, block2->data, block_length);
else
return block1->data == block2->data;
}
FLAC_API FLAC__bool FLAC__metadata_object_is_equal(const FLAC__StreamMetadata *block1, const FLAC__StreamMetadata *block2)
{
FLAC__ASSERT(0 != block1);
FLAC__ASSERT(0 != block2);
if(block1->type != block2->type) {
return false;
}
if(block1->is_last != block2->is_last) {
return false;
}
if(block1->length != block2->length) {
return false;
}
switch(block1->type) {
case FLAC__METADATA_TYPE_STREAMINFO:
return compare_block_data_streaminfo_(&block1->data.stream_info, &block2->data.stream_info);
case FLAC__METADATA_TYPE_PADDING:
return true; /* we don't compare the padding guts */
case FLAC__METADATA_TYPE_APPLICATION:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?