HydrogenAudio

Lossless Audio Compression => FLAC => Topic started by: Peter on 2016-04-04 12:19:58

Title: libFLAC: Shrink the file when removing oversized metadata / attached pictures
Post by: Peter on 2016-04-04 12:19:58
Today, by user request, I attempted shrinking FLAC files when removing oversized metadata.

It turns out that libFLAC only decides if it's necessary to fully rewrite the file or if it can be rewritten in place.

I want to conditionally rewrite the file if there is more than <count> bytes of padding; libFLAC does not present this info to me or use it when deciding whether to rewrite the file or not.

Essentially, it's not possible to do what I'm trying to achieve without hacking a function in libFLAC.

If anybody responsible for libFLAC is reading this - can this please be addressed in a future libFLAC update?


[edited - first I could not figure out how to shrink the file at all, turns out FLAC__metadata_chain_write_with_callbacks_and_tempfile() with use_padding=false does it]
Title: Re: libFLAC: Shrink the file when removing oversized metadata / attached pictures
Post by: lvqcl on 2016-04-04 19:34:42
I want to conditionally rewrite the file if there is more than <count> bytes of padding; libFLAC does not present this info to me or use it when deciding whether to rewrite the file or not.

I'm not responsible for libFLAC development, but AFAIK you can enumerate all metadata blocks, find all FLAC__METADATA_TYPE_PADDING blocks and find their length.

Something like this:
Code: [Select]
size_t padding = 0;
FLAC__StreamMetadata* block = 0;

FLAC__Metadata_Chain* chain = FLAC__metadata_chain_new();
FLAC__metadata_chain_read(chain, filename); // or FLAC__metadata_chain_read_ogg()

FLAC__Metadata_Iterator* iter = FLAC__metadata_iterator_new();
FLAC__metadata_iterator_init(iter, chain);
do {
    block = FLAC__metadata_iterator_get_block(iter);
    if(block->type == FLAC__METADATA_TYPE_PADDING)
        padding += block->length;
}while(FLAC__metadata_iterator_next(iter));

FLAC__metadata_iterator_delete(iter);
FLAC__metadata_chain_delete(chain);
Title: Re: libFLAC: Shrink the file when removing oversized metadata / attached pictures
Post by: lvqcl on 2016-04-05 14:40:12
A side note: include\FLAC\metadata.h says: "Always check FLAC__metadata_chain_check_if_tempfile_needed() before writing via callbacks." That is, it's possible to use FLAC__metadata_chain_write_with_callbacks_and_tempfile() only when FLAC__metadata_chain_check_if_tempfile_needed() returns true.
Code: [Select]
if (FLAC__metadata_chain_check_if_tempfile_needed(...) {
    ...
    FLAC__metadata_chain_write_with_callbacks_and_tempfile(...);
    ...
} else {
    ...
    FLAC__metadata_chain_write_with_callbacks(...);
    ...
}