📄 metadata_iterators.c
字号:
} save = iterator->current->prev; if(replace_with_padding) { FLAC__metadata_object_delete_data(iterator->current->data); iterator->current->data->type = FLAC__METADATA_TYPE_PADDING; } else { chain_delete_node_(iterator->chain, iterator->current); } iterator->current = save; return true;}FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_before(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block){ FLAC__Metadata_Node *node; FLAC__ASSERT(0 != iterator); FLAC__ASSERT(0 != iterator->current); FLAC__ASSERT(0 != block); if(block->type == FLAC__METADATA_TYPE_STREAMINFO) return false; if(0 == iterator->current->prev) { FLAC__ASSERT(iterator->current->data->type == FLAC__METADATA_TYPE_STREAMINFO); return false; } if(0 == (node = node_new_())) return false; node->data = block; iterator_insert_node_(iterator, node); iterator->current = node; return true;}FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_after(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block){ FLAC__Metadata_Node *node; FLAC__ASSERT(0 != iterator); FLAC__ASSERT(0 != iterator->current); FLAC__ASSERT(0 != block); if(block->type == FLAC__METADATA_TYPE_STREAMINFO) return false; if(0 == (node = node_new_())) return false; node->data = block; iterator_insert_node_after_(iterator, node); iterator->current = node; return true;}/**************************************************************************** * * Local function definitions * ***************************************************************************/void pack_uint32_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes){ unsigned i; b += bytes; for(i = 0; i < bytes; i++) { *(--b) = (FLAC__byte)(val & 0xff); val >>= 8; }}void pack_uint32_little_endian_(FLAC__uint32 val, FLAC__byte *b, unsigned bytes){ unsigned i; for(i = 0; i < bytes; i++) { *(b++) = (FLAC__byte)(val & 0xff); val >>= 8; }}void pack_uint64_(FLAC__uint64 val, FLAC__byte *b, unsigned bytes){ unsigned i; b += bytes; for(i = 0; i < bytes; i++) { *(--b) = (FLAC__byte)(val & 0xff); val >>= 8; }}FLAC__uint32 unpack_uint32_(FLAC__byte *b, unsigned bytes){ FLAC__uint32 ret = 0; unsigned i; for(i = 0; i < bytes; i++) ret = (ret << 8) | (FLAC__uint32)(*b++); return ret;}FLAC__uint32 unpack_uint32_little_endian_(FLAC__byte *b, unsigned bytes){ FLAC__uint32 ret = 0; unsigned i; b += bytes; for(i = 0; i < bytes; i++) ret = (ret << 8) | (FLAC__uint32)(*--b); return ret;}FLAC__uint64 unpack_uint64_(FLAC__byte *b, unsigned bytes){ FLAC__uint64 ret = 0; unsigned i; for(i = 0; i < bytes; i++) ret = (ret << 8) | (FLAC__uint64)(*b++); return ret;}FLAC__bool read_metadata_block_header_(FLAC__Metadata_SimpleIterator *iterator){ FLAC__ASSERT(0 != iterator); FLAC__ASSERT(0 != iterator->file); if(!read_metadata_block_header_cb_((FLAC__IOHandle)iterator->file, (FLAC__IOCallback_Read)fread, &iterator->is_last, &iterator->type, &iterator->length)) { iterator->status = FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; return false; } return true;}FLAC__bool read_metadata_block_data_(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block){ FLAC__ASSERT(0 != iterator); FLAC__ASSERT(0 != iterator->file); iterator->status = read_metadata_block_data_cb_((FLAC__IOHandle)iterator->file, (FLAC__IOCallback_Read)fread, fseek_wrapper_, block); return (iterator->status == FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK);}FLAC__bool read_metadata_block_header_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__bool *is_last, FLAC__MetadataType *type, unsigned *length){ FLAC__byte raw_header[FLAC__STREAM_METADATA_HEADER_LENGTH]; if(read_cb(raw_header, 1, FLAC__STREAM_METADATA_HEADER_LENGTH, handle) != FLAC__STREAM_METADATA_HEADER_LENGTH) return false; *is_last = raw_header[0] & 0x80? true : false; *type = (FLAC__MetadataType)(raw_header[0] & 0x7f); *length = unpack_uint32_(raw_header + 1, 3); /* Note that we don't check: * if(iterator->type >= FLAC__METADATA_TYPE_UNDEFINED) * we just will read in an opaque block */ return true;}FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata *block){ switch(block->type) { case FLAC__METADATA_TYPE_STREAMINFO: return read_metadata_block_data_streaminfo_cb_(handle, read_cb, &block->data.stream_info); case FLAC__METADATA_TYPE_PADDING: return read_metadata_block_data_padding_cb_(handle, seek_cb, &block->data.padding, block->length); case FLAC__METADATA_TYPE_APPLICATION: return read_metadata_block_data_application_cb_(handle, read_cb, &block->data.application, block->length); case FLAC__METADATA_TYPE_SEEKTABLE: return read_metadata_block_data_seektable_cb_(handle, read_cb, &block->data.seek_table, block->length); case FLAC__METADATA_TYPE_VORBIS_COMMENT: return read_metadata_block_data_vorbis_comment_cb_(handle, read_cb, &block->data.vorbis_comment); case FLAC__METADATA_TYPE_CUESHEET: return read_metadata_block_data_cuesheet_cb_(handle, read_cb, &block->data.cue_sheet); default: return read_metadata_block_data_unknown_cb_(handle, read_cb, &block->data.unknown, block->length); }}FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_streaminfo_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_StreamInfo *block){ FLAC__byte buffer[FLAC__STREAM_METADATA_STREAMINFO_LENGTH], *b; if(read_cb(buffer, 1, FLAC__STREAM_METADATA_STREAMINFO_LENGTH, handle) != FLAC__STREAM_METADATA_STREAMINFO_LENGTH) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; b = buffer; /* we are using hardcoded numbers for simplicity but we should * probably eventually write a bit-level unpacker and use the * _STREAMINFO_ constants. */ block->min_blocksize = unpack_uint32_(b, 2); b += 2; block->max_blocksize = unpack_uint32_(b, 2); b += 2; block->min_framesize = unpack_uint32_(b, 3); b += 3; block->max_framesize = unpack_uint32_(b, 3); b += 3; block->sample_rate = (unpack_uint32_(b, 2) << 4) | ((unsigned)(b[2] & 0xf0) >> 4); block->channels = (unsigned)((b[2] & 0x0e) >> 1) + 1; block->bits_per_sample = ((((unsigned)(b[2] & 0x01)) << 4) | (((unsigned)(b[3] & 0xf0)) >> 4)) + 1; block->total_samples = (((FLAC__uint64)(b[3] & 0x0f)) << 32) | unpack_uint64_(b+4, 4); memcpy(block->md5sum, b+8, 16); return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;}FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_padding_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Seek seek_cb, FLAC__StreamMetadata_Padding *block, unsigned block_length){ (void)block; /* nothing to do; we don't care about reading the padding bytes */ if(0 != seek_cb(handle, block_length, SEEK_CUR)) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR; return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;}FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_application_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_Application *block, unsigned block_length){ const unsigned id_bytes = FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8; if(read_cb(block->id, 1, id_bytes, handle) != id_bytes) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; block_length -= id_bytes; if(block_length == 0) { block->data = 0; } else { if(0 == (block->data = (FLAC__byte*)malloc(block_length))) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; if(read_cb(block->data, 1, block_length, handle) != block_length) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; } return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;}FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_seektable_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_SeekTable *block, unsigned block_length){ unsigned i; FLAC__byte buffer[FLAC__STREAM_METADATA_SEEKPOINT_LENGTH]; FLAC__ASSERT(block_length % FLAC__STREAM_METADATA_SEEKPOINT_LENGTH == 0); block->num_points = block_length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH; if(block->num_points == 0) block->points = 0; else if(0 == (block->points = (FLAC__StreamMetadata_SeekPoint*)malloc(block->num_points * sizeof(FLAC__StreamMetadata_SeekPoint)))) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; for(i = 0; i < block->num_points; i++) { if(read_cb(buffer, 1, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH, handle) != FLAC__STREAM_METADATA_SEEKPOINT_LENGTH) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; /* some MAGIC NUMBERs here */ block->points[i].sample_number = unpack_uint64_(buffer, 8); block->points[i].stream_offset = unpack_uint64_(buffer+8, 8); block->points[i].frame_samples = unpack_uint32_(buffer+16, 2); } return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;}FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_entry_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_VorbisComment_Entry *entry){ const unsigned entry_length_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8; FLAC__byte buffer[4]; /* magic number is asserted below */ FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN / 8 == 4); if(read_cb(buffer, 1, entry_length_len, handle) != entry_length_len) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; entry->length = unpack_uint32_little_endian_(buffer, entry_length_len); if(0 != entry->entry) free(entry->entry); if(entry->length == 0) { entry->entry = 0; } else { if(0 == (entry->entry = (FLAC__byte*)malloc(entry->length+1))) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; if(read_cb(entry->entry, 1, entry->length, handle) != entry->length) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; entry->entry[entry->length] = '\0'; } return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;}FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_vorbis_comment_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_VorbisComment *block){ unsigned i; FLAC__Metadata_SimpleIteratorStatus status; const unsigned num_comments_len = FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN / 8; FLAC__byte buffer[4]; /* magic number is asserted below */ FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN / 8 == 4); if(FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK != (status = read_metadata_block_data_vorbis_comment_entry_cb_(handle, read_cb, &(block->vendor_string)))) return status; if(read_cb(buffer, 1, num_comments_len, handle) != num_comments_len) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; block->num_comments = unpack_uint32_little_endian_(buffer, num_comments_len); if(block->num_comments == 0) { block->comments = 0; } else if(0 == (block->comments = (FLAC__StreamMetadata_VorbisComment_Entry*)calloc(block->num_comments, sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR; for(i = 0; i < block->num_comments; i++) { if(FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK != (status = read_metadata_block_data_vorbis_comment_entry_cb_(handle, read_cb, block->comments + i))) return status; } return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK;}FLAC__Metadata_SimpleIteratorStatus read_metadata_block_data_cuesheet_track_cb_(FLAC__IOHandle handle, FLAC__IOCallback_Read read_cb, FLAC__StreamMetadata_CueSheet_Track *track){ unsigned i, len; FLAC__byte buffer[32]; /* asserted below that this is big enough */ FLAC__ASSERT(sizeof(buffer) >= sizeof(FLAC__uint64)); FLAC__ASSERT(sizeof(buffer) >= FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN/8); FLAC__ASSERT(sizeof(buffer) >= (FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) / 8); FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN % 8 == 0); len = FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN / 8; if(read_cb(buffer, 1, len, handle) != len) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; track->offset = unpack_uint64_(buffer, len); FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN % 8 == 0); len = FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN / 8; if(read_cb(buffer, 1, len, handle) != len) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; track->number = (FLAC__byte)unpack_uint32_(buffer, len); FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0); len = FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN / 8; if(read_cb(track->isrc, 1, len, handle) != len) return FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR; FLAC__ASSERT((FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) % 8 == 0); len = (FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN + FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN) / 8; if(read_cb(buffer, 1, len, handle) != len) return FLAC__METADATA_SIMPLE_ITE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -