From: Josh Coalson Date: Fri, 23 Feb 2001 23:09:32 +0000 (+0000) Subject: add basic list functionality X-Git-Tag: 1.2.0~2628 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b8973c2b8a6fa5f372a5e90376741348fdff0977;p=platform%2Fupstream%2Fflac.git add basic list functionality --- diff --git a/src/metaflac/main.c b/src/metaflac/main.c index a811da4..41fccdd 100644 --- a/src/metaflac/main.c +++ b/src/metaflac/main.c @@ -31,9 +31,17 @@ #include "FLAC/all.h" static const char *sync_string_ = "fLaC"; /* DUPLICATE:FLAC__STREAM_SYNC_STRING */ +static const char *metadata_type_string_[] = { /* DUPLICATE:FLAC__MetaDataTypeString */ + "STREAMINFO", + "PADDING", + "APPLICATION" +}; static int usage(const char *message, ...); static bool list(FILE *f, bool verbose); +static uint32 unpack_uint32(byte *b, unsigned bytes); +static uint64 unpack_uint64(byte *b, unsigned bytes); +static void hexdump(const byte *buf, unsigned bytes); int main(int argc, char *argv[]) { @@ -113,15 +121,15 @@ int usage(const char *message, ...) printf("options:\n"); printf(" -l : list metadata blocks\n"); printf(" -v : verbose\n"); - printf(" -v- can all be used to turn off a particular option\n"); return 1; } bool list(FILE *f, bool verbose) { - static byte buf[65536]; + static byte buf[65536], *b; FLAC__StreamMetaData metadata; + unsigned blocknum = 0, i; /* read the stream sync code */ if(fread(buf, 1, 4, f) < 4 || memcmp(buf, sync_string_, 4)) { @@ -138,16 +146,163 @@ bool list(FILE *f, bool verbose) } metadata.is_last = (buf[0] & 0x80)? true:false; metadata.type = (FLAC__MetaDataType)(buf[0] & 0x7f); - metadata.length = (((unsigned)buf[1]) << 16) | (((unsigned)buf[2]) << 8) | ((unsigned)buf[3]); + metadata.length = unpack_uint32(buf+1, 3); + + /* print header */ + printf("METADATA block #%u:\n", blocknum); + printf("type: %u (%s)\n", (unsigned)metadata.type, metadata.type<=FLAC__METADATA_TYPE_APPLICATION? metadata_type_string_[metadata.type] : "UNKNOWN"); + printf("is last: %s\n", metadata.is_last? "true":"false"); + printf("length: %u\n", metadata.length); + + if(metadata.length > sizeof(buf)) { + printf("SKIPPING large block\n\n"); + continue; + } /* read the metadata block data */ + if(fread(buf, 1, metadata.length, f) < metadata.length) { + fprintf(stderr, "ERROR: short count reading metadata block data\n\n"); + return false; + } + switch(metadata.type) { + case FLAC__METADATA_TYPE_STREAMINFO: + b = buf; + metadata.data.stream_info.min_blocksize = unpack_uint32(b, 2); b += 2; + metadata.data.stream_info.max_blocksize = unpack_uint32(b, 2); b += 2; + metadata.data.stream_info.min_framesize = unpack_uint32(b, 3); b += 3; + metadata.data.stream_info.max_framesize = unpack_uint32(b, 3); b += 3; + metadata.data.stream_info.sample_rate = (unpack_uint32(b, 2) << 4) | ((unsigned)(b[2] & 0xf0) >> 4); + metadata.data.stream_info.channels = (unsigned)((b[2] & 0x0e) >> 1) + 1; + metadata.data.stream_info.bits_per_sample = ((((unsigned)(b[2] & 0x01)) << 1) | (((unsigned)(b[3] & 0xf0)) >> 4)) + 1; + metadata.data.stream_info.total_samples = (((uint64)(b[3] & 0x0f)) << 32) | unpack_uint64(b+4, 4); + memcpy(metadata.data.stream_info.md5sum, b+8, 16); + break; + case FLAC__METADATA_TYPE_PADDING: + if(verbose) { + /* dump contents */ + } + break; + case FLAC__METADATA_TYPE_APPLICATION: + memcpy(buf, metadata.data.application.id, 4); + metadata.data.application.data = buf+4; + break; + default: + printf("SKIPPING block of unknown type\n\n"); + continue; + } - /* print it */ - printf("METADATA block:\n"); - printf("\ttype: %u\n", (unsigned)metadata.type); - printf("\tis last: %s\n", metadata.is_last? "true":"false"); - printf("\tlength: %u\n", metadata.length); + /* print data */ + switch(metadata.type) { + case FLAC__METADATA_TYPE_STREAMINFO: + printf("minumum blocksize: %u samples\n", metadata.data.stream_info.min_blocksize); + printf("maxumum blocksize: %u samples\n", metadata.data.stream_info.max_blocksize); + printf("minimum framesize: %u bytes\n", metadata.data.stream_info.min_framesize); + printf("maximum framesize: %u bytes\n", metadata.data.stream_info.max_framesize); + printf("sample_rate: %u Hz\n", metadata.data.stream_info.sample_rate); + printf("channels: %u\n", metadata.data.stream_info.channels); + printf("bits-per-sample: %u\n", metadata.data.stream_info.bits_per_sample); + printf("total samples: %llu\n", metadata.data.stream_info.total_samples); + printf("MD5 signature: "); + for(i = 0; i < 16; i++) + printf("%02x", metadata.data.stream_info.md5sum[i]); + printf("\n"); + break; + case FLAC__METADATA_TYPE_PADDING: + if(verbose) { + printf("pad contents:\n"); + hexdump(buf, metadata.length); + } + break; + case FLAC__METADATA_TYPE_APPLICATION: + printf("Application ID: "); + for(i = 0; i < 4; i++) + printf("%02x", metadata.data.application.id[i]); + printf("\n"); + if(verbose) { + printf("data contents:\n"); + hexdump(metadata.data.application.data, metadata.length); + } + break; + default: + assert(0); + } + + if(!metadata.is_last) + printf("\n"); + + blocknum++; } while (!metadata.is_last); return true; } + +static uint32 unpack_uint32(byte *b, unsigned bytes) +{ + uint32 ret = 0; + unsigned i; + + for(i = 0; i < bytes; i++) + ret = (ret << 8) | (uint32)(*b++); + + return ret; +} + +static uint64 unpack_uint64(byte *b, unsigned bytes) +{ + uint64 ret = 0; + unsigned i; + + for(i = 0; i < bytes; i++) + ret = (ret << 8) | (uint64)(*b++); + + return ret; +} + +void hexdump(const byte *buf, unsigned bytes) +{ + unsigned i, left = bytes; + const byte *b = buf; + + for(i = 0; i < bytes; i += 16) { + printf("%08X: " + "%02X %02X %02X %02X %02X %02X %02X %02X " + "%02X %02X %02X %02X %02X %02X %02X %02X " + "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", + i, + left > 0? (unsigned char)b[ 0] : 0, + left > 1? (unsigned char)b[ 1] : 0, + left > 2? (unsigned char)b[ 2] : 0, + left > 3? (unsigned char)b[ 3] : 0, + left > 4? (unsigned char)b[ 4] : 0, + left > 5? (unsigned char)b[ 5] : 0, + left > 6? (unsigned char)b[ 6] : 0, + left > 7? (unsigned char)b[ 7] : 0, + left > 8? (unsigned char)b[ 8] : 0, + left > 9? (unsigned char)b[ 9] : 0, + left > 10? (unsigned char)b[10] : 0, + left > 11? (unsigned char)b[11] : 0, + left > 12? (unsigned char)b[12] : 0, + left > 13? (unsigned char)b[13] : 0, + left > 14? (unsigned char)b[14] : 0, + left > 15? (unsigned char)b[15] : 0, + (left > 0) ? (isprint(b[ 0]) ? b[ 0] : '.') : ' ', + (left > 1) ? (isprint(b[ 1]) ? b[ 1] : '.') : ' ', + (left > 2) ? (isprint(b[ 2]) ? b[ 2] : '.') : ' ', + (left > 3) ? (isprint(b[ 3]) ? b[ 3] : '.') : ' ', + (left > 4) ? (isprint(b[ 4]) ? b[ 4] : '.') : ' ', + (left > 5) ? (isprint(b[ 5]) ? b[ 5] : '.') : ' ', + (left > 6) ? (isprint(b[ 6]) ? b[ 6] : '.') : ' ', + (left > 7) ? (isprint(b[ 7]) ? b[ 7] : '.') : ' ', + (left > 8) ? (isprint(b[ 8]) ? b[ 8] : '.') : ' ', + (left > 9) ? (isprint(b[ 9]) ? b[ 9] : '.') : ' ', + (left > 10) ? (isprint(b[10]) ? b[10] : '.') : ' ', + (left > 11) ? (isprint(b[11]) ? b[11] : '.') : ' ', + (left > 12) ? (isprint(b[12]) ? b[12] : '.') : ' ', + (left > 13) ? (isprint(b[13]) ? b[13] : '.') : ' ', + (left > 14) ? (isprint(b[14]) ? b[14] : '.') : ' ', + (left > 15) ? (isprint(b[15]) ? b[15] : '.') : ' ' + ); + left -= 16; + b += 16; + } +}