From 3c0aad169b278b83bc4432bc23bf81f17678104b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Mangano-Tarumi?= Date: Sat, 3 Nov 2018 17:18:15 -0400 Subject: [PATCH] move the opus-related functions in opus.cc --- CMakeLists.txt | 6 +- src/opus.cc | 153 ++++++++++++++++++++++++++++++++++++++++++++++++ src/opustags.cc | 142 -------------------------------------------- src/opustags.h | 8 +++ 4 files changed, 166 insertions(+), 143 deletions(-) create mode 100644 src/opus.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ee4b05..26f6ed6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,11 @@ pkg_check_modules(OGG REQUIRED ogg) configure_file(src/config.h.in config.h @ONLY) include_directories(${CMAKE_CURRENT_BINARY_DIR}) -add_executable(opustags src/opustags.cc) +add_executable( + opustags + src/opus.cc + src/opustags.cc +) target_compile_options(opustags PUBLIC ${OGG_CFLAGS}) target_link_libraries(opustags PUBLIC ${OGG_LIBRARIES}) diff --git a/src/opus.cc b/src/opus.cc new file mode 100644 index 0000000..0a882bc --- /dev/null +++ b/src/opus.cc @@ -0,0 +1,153 @@ +#include "opustags.h" + +#include +#include +#include + +#ifdef __APPLE__ +#include +#define htole32(x) OSSwapHostToLittleInt32(x) +#define le32toh(x) OSSwapLittleToHostInt32(x) +#endif + +int ot::parse_tags(char *data, long len, opus_tags *tags) +{ + long pos; + if (len < 8+4+4) + return -1; + if (strncmp(data, "OpusTags", 8) != 0) + return -1; + // Vendor + pos = 8; + tags->vendor_length = le32toh(*((uint32_t*) (data + pos))); + tags->vendor_string = data + pos + 4; + pos += 4 + tags->vendor_length; + if (pos + 4 > len) + return -1; + // Count + tags->count = le32toh(*((uint32_t*) (data + pos))); + if (tags->count == 0) + return 0; + tags->lengths = static_cast(calloc(tags->count, sizeof(uint32_t))); + if (tags->lengths == NULL) + return -1; + tags->comment = static_cast(calloc(tags->count, sizeof(char*))); + if (tags->comment == NULL) { + free(tags->lengths); + return -1; + } + pos += 4; + // Comment + uint32_t i; + for (i=0; icount; i++) { + tags->lengths[i] = le32toh(*((uint32_t*) (data + pos))); + tags->comment[i] = data + pos + 4; + pos += 4 + tags->lengths[i]; + if (pos > len) + return -1; + } + + if (pos < len) + fprintf(stderr, "warning: %ld unused bytes at the end of the OpusTags packet\n", len - pos); + + return 0; +} + +int ot::render_tags(opus_tags *tags, ogg_packet *op) +{ + // Note: op->packet must be manually freed. + op->b_o_s = 0; + op->e_o_s = 0; + op->granulepos = 0; + op->packetno = 1; + long len = 8 + 4 + tags->vendor_length + 4; + uint32_t i; + for (i=0; icount; i++) + len += 4 + tags->lengths[i]; + op->bytes = len; + char *data = static_cast(malloc(len)); + if (!data) + return -1; + op->packet = (unsigned char*) data; + uint32_t n; + memcpy(data, "OpusTags", 8); + n = htole32(tags->vendor_length); + memcpy(data+8, &n, 4); + memcpy(data+12, tags->vendor_string, tags->vendor_length); + data += 12 + tags->vendor_length; + n = htole32(tags->count); + memcpy(data, &n, 4); + data += 4; + for (i=0; icount; i++) { + n = htole32(tags->lengths[i]); + memcpy(data, &n, 4); + memcpy(data+4, tags->comment[i], tags->lengths[i]); + data += 4 + tags->lengths[i]; + } + return 0; +} + +static int match_field(const char *comment, uint32_t len, const char *field) +{ + size_t field_len; + for (field_len = 0; field[field_len] != '\0' && field[field_len] != '='; field_len++); + if (len <= field_len) + return 0; + if (comment[field_len] != '=') + return 0; + if (strncmp(comment, field, field_len) != 0) + return 0; + return 1; +} + +void ot::delete_tags(opus_tags *tags, const char *field) +{ + uint32_t i; + for (i=0; icount; i++) { + if (match_field(tags->comment[i], tags->lengths[i], field)) { + // We want to delete the current element, so we move the last tag at + // position i, then decrease the array size. We need decrease i to inspect + // at the next iteration the tag we just moved. + tags->count--; + tags->lengths[i] = tags->lengths[tags->count]; + tags->comment[i] = tags->comment[tags->count]; + --i; + // No need to resize the arrays. + } + } +} + +int ot::add_tags(opus_tags *tags, const char **tags_to_add, uint32_t count) +{ + if (count == 0) + return 0; + uint32_t *lengths = static_cast(realloc(tags->lengths, (tags->count + count) * sizeof(uint32_t))); + const char **comment = static_cast(realloc(tags->comment, (tags->count + count) * sizeof(char*))); + if (lengths == NULL || comment == NULL) + return -1; + tags->lengths = lengths; + tags->comment = comment; + uint32_t i; + for (i=0; ilengths[tags->count + i] = strlen(tags_to_add[i]); + tags->comment[tags->count + i] = tags_to_add[i]; + } + tags->count += count; + return 0; +} + +void ot::print_tags(opus_tags *tags) +{ + for (uint32_t i=0; icount; i++) { + fwrite(tags->comment[i], 1, tags->lengths[i], stdout); + puts(""); + } +} + +void ot::free_tags(opus_tags *tags) +{ + if (tags->count > 0) { + free(tags->lengths); + free(tags->comment); + } +} diff --git a/src/opustags.cc b/src/opustags.cc index ffb8a10..b9bcaa5 100644 --- a/src/opustags.cc +++ b/src/opustags.cc @@ -11,150 +11,8 @@ #include #include -#ifdef __APPLE__ -#include -#define htole32(x) OSSwapHostToLittleInt32(x) -#define le32toh(x) OSSwapLittleToHostInt32(x) -#endif - using namespace ot; -int parse_tags(char *data, long len, opus_tags *tags){ - long pos; - if(len < 8+4+4) - return -1; - if(strncmp(data, "OpusTags", 8) != 0) - return -1; - // Vendor - pos = 8; - tags->vendor_length = le32toh(*((uint32_t*) (data + pos))); - tags->vendor_string = data + pos + 4; - pos += 4 + tags->vendor_length; - if(pos + 4 > len) - return -1; - // Count - tags->count = le32toh(*((uint32_t*) (data + pos))); - if(tags->count == 0) - return 0; - tags->lengths = static_cast(calloc(tags->count, sizeof(uint32_t))); - if(tags->lengths == NULL) - return -1; - tags->comment = static_cast(calloc(tags->count, sizeof(char*))); - if(tags->comment == NULL){ - free(tags->lengths); - return -1; - } - pos += 4; - // Comment - uint32_t i; - for(i=0; icount; i++){ - tags->lengths[i] = le32toh(*((uint32_t*) (data + pos))); - tags->comment[i] = data + pos + 4; - pos += 4 + tags->lengths[i]; - if(pos > len) - return -1; - } - - if(pos < len) - fprintf(stderr, "warning: %ld unused bytes at the end of the OpusTags packet\n", len - pos); - - return 0; -} - -int render_tags(opus_tags *tags, ogg_packet *op){ - // Note: op->packet must be manually freed. - op->b_o_s = 0; - op->e_o_s = 0; - op->granulepos = 0; - op->packetno = 1; - long len = 8 + 4 + tags->vendor_length + 4; - uint32_t i; - for(i=0; icount; i++) - len += 4 + tags->lengths[i]; - op->bytes = len; - char *data = static_cast(malloc(len)); - if(!data) - return -1; - op->packet = (unsigned char*) data; - uint32_t n; - memcpy(data, "OpusTags", 8); - n = htole32(tags->vendor_length); - memcpy(data+8, &n, 4); - memcpy(data+12, tags->vendor_string, tags->vendor_length); - data += 12 + tags->vendor_length; - n = htole32(tags->count); - memcpy(data, &n, 4); - data += 4; - for(i=0; icount; i++){ - n = htole32(tags->lengths[i]); - memcpy(data, &n, 4); - memcpy(data+4, tags->comment[i], tags->lengths[i]); - data += 4 + tags->lengths[i]; - } - return 0; -} - -int match_field(const char *comment, uint32_t len, const char *field){ - size_t field_len; - for(field_len = 0; field[field_len] != '\0' && field[field_len] != '='; field_len++); - if(len <= field_len) - return 0; - if(comment[field_len] != '=') - return 0; - if(strncmp(comment, field, field_len) != 0) - return 0; - return 1; - -} - -void delete_tags(opus_tags *tags, const char *field){ - uint32_t i; - for(i=0; icount; i++){ - if(match_field(tags->comment[i], tags->lengths[i], field)){ - // We want to delete the current element, so we move the last tag at position i, then - // decrease the array size. We need decrease i to inspect at the next iteration the tag - // we just moved. - tags->count--; - tags->lengths[i] = tags->lengths[tags->count]; - tags->comment[i] = tags->comment[tags->count]; - --i; - // No need to resize the arrays. - } - } -} - -int add_tags(opus_tags *tags, const char **tags_to_add, uint32_t count){ - if(count == 0) - return 0; - uint32_t *lengths = static_cast(realloc(tags->lengths, (tags->count + count) * sizeof(uint32_t))); - const char **comment = static_cast(realloc(tags->comment, (tags->count + count) * sizeof(char*))); - if(lengths == NULL || comment == NULL) - return -1; - tags->lengths = lengths; - tags->comment = comment; - uint32_t i; - for(i=0; ilengths[tags->count + i] = strlen(tags_to_add[i]); - tags->comment[tags->count + i] = tags_to_add[i]; - } - tags->count += count; - return 0; -} - -void print_tags(opus_tags *tags){ - for(uint32_t i=0; icount; i++){ - fwrite(tags->comment[i], 1, tags->lengths[i], stdout); - puts(""); - } -} - -void free_tags(opus_tags *tags){ - if(tags->count > 0){ - free(tags->lengths); - free(tags->comment); - } -} - int write_page(ogg_page *og, FILE *stream){ if((ssize_t) fwrite(og->header, 1, og->header_len, stream) < og->header_len) return -1; diff --git a/src/opustags.h b/src/opustags.h index de7fbb3..c64fe86 100644 --- a/src/opustags.h +++ b/src/opustags.h @@ -4,6 +4,7 @@ */ #include +#include namespace ot { @@ -27,6 +28,13 @@ struct opus_tags { const char **comment; }; +int parse_tags(char *data, long len, opus_tags *tags); +int render_tags(opus_tags *tags, ogg_packet *op); +void delete_tags(opus_tags *tags, const char *field); +int add_tags(opus_tags *tags, const char **tags_to_add, uint32_t count); +void print_tags(opus_tags *tags); +void free_tags(opus_tags *tags); + /** \} */ }