shithub: riscv

Download patch

ref: c138c7d8813dcd77cfe33e37f1416427819b5e93
parent: b868b9919f570cbcbdb3c713bf1431b9d843ea43
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Tue Jun 27 11:10:37 EDT 2023

readtags, zuke: extract cover images stored in the audio files (thanks g-w1)

--- a/sys/src/cmd/audio/readtags/readtags.c
+++ b/sys/src/cmd/audio/readtags/readtags.c
@@ -24,10 +24,47 @@
 	[Timage] = "image",
 };
 
+static int image;
+
 static void
 tag(Tagctx *ctx, int t, const char *k, const char *v, int offset, int size, Tagread f)
 {
-	USED(ctx); USED(k); USED(f);
+	char *prog, *buf, tmp[32];
+	int p[2], n, pid;
+	Waitmsg *w;
+
+	USED(k);
+	if(image){
+		if(t != Timage)
+			return;
+		prog = nil;
+		if(strcmp(v, "image/jpeg") == 0)
+			prog = "jpg";
+		else if(strcmp(v, "image/png") == 0)
+			prog = "png";
+		else
+			sysfatal("unknown image type: %s", v);
+		if((buf = malloc(size)) == nil)
+			sysfatal("no memory");
+		if(ctx->seek(ctx, offset, 0) != offset || (n = ctx->read(ctx, buf, size)) != size)
+			sysfatal("image load failed");
+		if(f != nil)
+			n = f(buf, &n);
+		pipe(p);
+		if((pid = rfork(RFPROC|RFFDG|RFNOTEG|RFCENVG)) < 0)
+			sysfatal("rfork: %r");
+		if(pid == 0){
+			dup(p[0], 0); close(p[0]);
+			close(p[1]);
+			snprint(tmp, sizeof(tmp), "/bin/%s", prog);
+			execl(tmp, prog, "-9t", nil);
+			sysfatal("execl: %r");
+		}
+		close(p[0]);
+		write(p[1], buf, n);
+		close(p[1]);
+		exits((w = wait()) != nil ? w->msg : nil);
+	}
 	if(t == Timage)
 		print("%-12s %s %d %d\n", t2s[t], v, offset, size);
 	else if(t != Tunknown)
@@ -57,7 +94,7 @@
 static void
 usage(void)
 {
-	fprint(2, "usage: %s FILE...\n", argv0);
+	fprint(2, "usage: %s [-i] [file ...]\n", argv0);
 	exits("usage");
 }
 
@@ -79,21 +116,29 @@
 	};
 
 	ARGBEGIN{
+	case 'i':
+		image++;
+		break;
 	default:
 		usage();
 	}ARGEND
 
-	if(argc < 1)
-		usage();
+	i = 0;
+	if(argc < 1){
+		aux.fd = 0;
+		goto stdin;
+	}
 
-	for(i = 0; i < argc; i++){
-		print("*** %s\n", argv[i]);
+	for(; i < argc; i++){
+		if(!image)
+			print("*** %s\n", argv[i]);
 		if((aux.fd = open(argv[i], OREAD)) < 0)
 			print("failed to open\n");
 		else{
-			if(tagsget(&ctx) != 0)
+stdin:
+			if(tagsget(&ctx) != 0 && !image)
 				print("no tags or failed to read tags\n");
-			else{
+			else if(!image){
 				if(ctx.duration > 0)
 					print("%-12s %d ms\n", "duration", ctx.duration);
 				if(ctx.samplerate > 0)
@@ -105,8 +150,11 @@
 			}
 			close(aux.fd);
 		}
-		print("\n");
+		if(!image)
+			print("\n");
 	}
+	if(image)
+		sysfatal("no image found");
 
 	exits(nil);
 }
--- a/sys/src/cmd/audio/zuke/zuke.c
+++ b/sys/src/cmd/audio/zuke/zuke.c
@@ -493,7 +493,7 @@
 coverload(void *player_)
 {
 	int p[2], pid, fd, i;
-	char *prog, *path, *s, tmp[32];
+	char *prog, *path, *s, tmp[64];
 	Meta *m;
 	Channel *ch;
 	Player *player;
@@ -507,14 +507,9 @@
 	fd = -1;
 	prog = nil;
 
-	if(m->imagefmt != nil && m->imagereader == 0){
-		if(strcmp(m->imagefmt, "image/png") == 0)
-			prog = "png";
-		else if(strcmp(m->imagefmt, "image/jpeg") == 0)
-			prog = "jpg";
-	}
-
-	if(prog == nil){
+	if(m->imagefmt != nil)
+		prog = "audio/readtags -i";
+	else{
 		path = strdup(m->path);
 		if(path != nil && (s = utfrrune(path, '/')) != nil){
 			*s = 0;
@@ -521,11 +516,11 @@
 
 			for(i = 0; i < nelem(covers) && prog == nil; i++){
 				if((s = smprint("%s/%s.jpg", path, covers[i])) != nil && (fd = open(s, OREAD|OCEXEC)) >= 0)
-					prog = "jpg";
+					prog = "jpg -9t";
 				free(s);
 				s = nil;
 				if(fd < 0 && (s = smprint("%s/%s.png", path, covers[i])) != nil && (fd = open(s, OREAD|OCEXEC)) >= 0)
-					prog = "png";
+					prog = "png -9t";
 				free(s);
 			}
 		}
@@ -534,11 +529,9 @@
 
 	if(prog == nil)
 		goto done;
-
-	if(fd < 0){
+	if(fd < 0)
 		fd = open(m->path, OREAD|OCEXEC);
-		seek(fd, m->imageoffset, 0);
-	}
+	snprint(tmp, sizeof(tmp), "%s | resample -x%d", prog, Coversz);
 	pipe(p);
 	if((pid = rfork(RFPROC|RFFDG|RFNOTEG|RFCENVG|RFNOWAIT)) == 0){
 		dup(fd, 0); close(fd);
@@ -547,7 +540,6 @@
 			dup(fd = open("/dev/null", OWRITE), 2);
 			close(fd);
 		}
-		snprint(tmp, sizeof(tmp), "%s -9t | resample -x%d", prog, Coversz);
 		execl("/bin/rc", "rc", "-c", tmp, nil);
 		sysfatal("execl: %r");
 	}
@@ -556,6 +548,7 @@
 
 	if(pid > 0){
 		newcover = readimage(display, p[0], 1);
+		/* if readtags fails, readimage will also fail, and we send nil over ch */
 		sendp(ch, newcover);
 	}
 	close(p[0]);
@@ -1206,7 +1199,7 @@
 				for(; (i = chartorune(&c, s)) > 0 && c != Runeerror; s += i)
 					sendul(kbd, c);
 				continue;
-			} 
+			}
 			if(*s != '/' && m->wdir != nil)
 				s = smprint("%s/%.*s", m->wdir, m->ndata, m->data);