ref: 78aa2362a55bfb147a995a7df2ec5691ef280aa8
dir: /examples/readtags.c/
#include <stdio.h> #include <stdbool.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include "tags.h" #define USED(x) (void)x typedef struct Aux Aux; struct Aux { int fd; }; static const char *t2s[] = { [Talbum] = "album", [Talbumartist] = "albumartist", [Talbumgain] = "albumgain", [Talbumpeak] = "albumpeak", [Tartist] = "artist", [Tcomment] = "comment", [Tcomposer] = "composer", [Tdate] = "date", [Tgenre] = "genre", [Timage] = "image", [Ttitle] = "title", [Ttrack] = "track", [Ttrackgain] = "trackgain", [Ttrackpeak] = "trackpeak", }; static bool image; static void tag(Tagctx *ctx, int t, const char *k, const char *v, int offset, int size, Tagread f) { USED(k); USED(f); if(image){ if(t != Timage) return; char *raw = malloc(size); Aux *aux = ctx->aux; int prevoffset = lseek(aux->fd, 0, 1); if(lseek(aux->fd, offset, 0) != offset || read(aux->fd, raw, size) != size || (f != NULL && f(raw, &size) != 0)){ fprintf(stderr, "failed to read the image\n"); exit(1); } lseek(aux->fd, prevoffset, 0); write(1, raw, size); exit(0); return; } if(t == Timage) printf("%-12s %s %d %d\n", t2s[t], v, offset, size); else if(t == Tunknown) printf("%-12s %s\n", k, v); else printf("%-12s %s\n", t2s[t], v); } static void toc(Tagctx *ctx, int ms, int offset) { USED(ctx); USED(ms); USED(offset); } static int ctxread(Tagctx *ctx, void *buf, int cnt) { Aux *aux = ctx->aux; return read(aux->fd, buf, cnt); } static int ctxseek(Tagctx *ctx, int offset, int whence) { Aux *aux = ctx->aux; return lseek(aux->fd, offset, whence); } int main(int argc, char **argv) { int i; char buf[256], *argv0; Aux aux; Tagctx ctx = { .read = ctxread, .seek = ctxseek, .tag = tag, .toc = toc, .buf = buf, .bufsz = sizeof(buf), .aux = &aux, }; argv0 = argv[0]; if(argc > 1 && strcmp(argv[1], "-i") == 0){ image = true; argc--; argv++; } if(argc < 2){ fprintf(stderr, "usage: %s [-i] FILE...\n", argv0); return 1; } for(i = 1; i < argc; i++){ if(!image) printf("*** %s\n", argv[i]); if((aux.fd = open(argv[i], O_RDONLY)) < 0) perror("failed to open"); else{ if(tagsget(&ctx) != 0){ fprintf(stderr, "no tags or failed to read tags\n"); return 1; }else if(image){ fprintf(stderr, "no images found\n"); return 1; }else{ if(ctx.duration > 0) printf("%-12s %d ms\n", "duration", ctx.duration); if(ctx.samplerate > 0) printf("%-12s %d\n", "samplerate", ctx.samplerate); if(ctx.channels > 0) printf("%-12s %d\n", "channels", ctx.channels); if(ctx.bitrate > 0) printf("%-12s %d\n", "bitrate", ctx.bitrate); } close(aux.fd); } if(i+1 < argc) printf("\n"); } return 0; }