shithub: plan9front

Download patch

ref: 7cff84371d4cdf1964651fd04c60b98a0d6014a4
parent: c3593c1a7a9dc1e888d56fc29f4f150d9b5d2fab
author: Sigrid <ftrvxmtrx@gmail.com>
date: Thu Apr 29 15:44:06 EDT 2021

libtags: use CP437 as the default encoding for module formats

--- /dev/null	Sun Oct 31 09:33:26 2021
+++ b/sys/src/cmd/audio/libtags/437.c	Thu Apr 29 15:44:06 2021
@@ -0,0 +1,34 @@
+/* https://en.wikipedia.org/wiki/Code_page_437 */
+#include "tagspriv.h"
+
+static Rune rh[] =
+	L"ΔÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧"
+	L"ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│d┤╡╢╖╕╣║╗╝╜"
+	L"╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌"
+	L"▐▀αßeΓπfΣgσµhτΦΘΩiδj∞φkεl∩≡±≥≤⌠m"
+	L"⌡÷≈°∙n·√oⁿ²■ ";
+
+int
+cp437toutf8(char *o, int osz, const char *s, int sz)
+{
+	char c[UTFmax];
+	int i, n;
+	Rune r;
+
+	for(i = 0; i < sz && osz > 1 && s[i] != 0; i++){
+		if((uchar)s[i] < 127){
+			*o++ = s[i];
+			osz--;
+			continue;
+		}
+		r = rh[(uchar)s[i] - 127];
+		if((n = runetochar(c, &r)) >= osz)
+			break;
+		memmove(o, c, n);
+		o += n;
+		osz -= n;
+	}
+
+	*o = 0;
+	return i;
+}
--- a/sys/src/cmd/audio/libtags/it.c	Tue Apr 27 10:08:06 2021
+++ b/sys/src/cmd/audio/libtags/it.c	Thu Apr 29 15:44:06 2021
@@ -3,12 +3,13 @@
 int
 tagit(Tagctx *ctx)
 {
-	char d[4+26+1];
+	char d[4+26+1], o[26*UTFmax+1];
 
 	if(ctx->read(ctx, d, 4+26) != 4+26 || memcmp(d, "IMPM", 4) != 0)
 		return -1;
 	d[4+26] = 0;
-	txtcb(ctx, Ttitle, "", d+4);
+	cp437toutf8(o, sizeof(o), d+4, 26);
+	txtcb(ctx, Ttitle, "", o);
 
 	return 0;
 }
--- a/sys/src/cmd/audio/libtags/mkfile	Tue Apr 27 10:08:06 2021
+++ b/sys/src/cmd/audio/libtags/mkfile	Thu Apr 29 15:44:06 2021
@@ -2,6 +2,7 @@
 LIB=libtags.a$O
 
 OFILES=\
+	437.$O\
 	8859.$O\
 	flac.$O\
 	id3genres.$O\
--- a/sys/src/cmd/audio/libtags/mod.c	Tue Apr 27 10:08:06 2021
+++ b/sys/src/cmd/audio/libtags/mod.c	Thu Apr 29 15:44:06 2021
@@ -1,7 +1,7 @@
 #include "tagspriv.h"
 
 /* insane. */
-static char* variants[] =
+static char *variants[] =
 {
 	"M.K.",
 	"M!K!",
@@ -24,23 +24,25 @@
 int
 tagmod(Tagctx *ctx)
 {
-	char d[20+1];
+	char d[20], o[20*UTFmax+1];
 	int i;
 
-	if (ctx->seek(ctx, 1080, 0) != 1080)
+	if(ctx->seek(ctx, 1080, 0) != 1080)
 		return -1;
-	if (ctx->read(ctx, d, 4) != 4)
+	if(ctx->read(ctx, d, 4) != 4)
 		return -1;
-	for (i = 0; ; i++)
-		if (variants[i] == nil)
+	for(i = 0; ; i++){
+		if(variants[i] == nil)
 			return -1;
-		else if (memcmp(d, variants[i], 4) == 0)
+		if(memcmp(d, variants[i], 4) == 0)
 			break;
-	memset(d, 0, sizeof d);
-	if (ctx->seek(ctx, 0, 0) != 0)
+	}
+	if(ctx->seek(ctx, 0, 0) != 0)
 		return -1;
-	if (ctx->read(ctx, d, 20) != 20)
+	if(ctx->read(ctx, d, 20) != 20)
 		return -1;
-	txtcb(ctx, Ttitle, "", d);
+	cp437toutf8(o, sizeof(o), d, 20);
+	txtcb(ctx, Ttitle, "", o);
+
 	return 0;
 }
--- a/sys/src/cmd/audio/libtags/s3m.c	Tue Apr 27 10:08:06 2021
+++ b/sys/src/cmd/audio/libtags/s3m.c	Thu Apr 29 15:44:06 2021
@@ -3,14 +3,15 @@
 int
 tags3m(Tagctx *ctx)
 {
-	char d[28+1+1], *s;
+	char d[28+1+1], o[28*UTFmax+1], *s;
 
 	if(ctx->read(ctx, d, 28+1+1) != 28+1+1 || (d[28] != 0x1a && d[28] != 0) || d[29] != 0x10)
 		return -1;
 	d[28] = 0;
 	for(s = d+27; s != d-1 && (*s == ' ' || *s == 0); s--);
 	s[1] = 0;
-	txtcb(ctx, Ttitle, "", d);
+	cp437toutf8(o, sizeof(o), d, s+1-d);
+	txtcb(ctx, Ttitle, "", o);
 
 	return 0;
 }
--- a/sys/src/cmd/audio/libtags/tagspriv.h	Tue Apr 27 10:08:06 2021
+++ b/sys/src/cmd/audio/libtags/tagspriv.h	Thu Apr 29 15:44:06 2021
@@ -28,6 +28,11 @@
 int utf16to8(uchar *out, int osz, const uchar *src, int sz);
 
 /*
+ * Same as utf16to8, but CP437 to UTF-8.
+ */
+int cp437toutf8(char *o, int osz, const char *s, int sz);
+
+/*
  * This one is common for both vorbis.c and flac.c
  * It maps a string k to tag type and executes the callback from ctx.
  * Returns 1 if callback was called, 0 otherwise.
--- a/sys/src/cmd/audio/libtags/xm.c	Tue Apr 27 10:08:06 2021
+++ b/sys/src/cmd/audio/libtags/xm.c	Thu Apr 29 15:44:06 2021
@@ -3,13 +3,14 @@
 int
 tagxm(Tagctx *ctx)
 {
-	char d[17+20+1], *s;
+	char d[17+20+1], o[20*UTFmax+1], *s;
 
 	if(ctx->read(ctx, d, 17+20) != 17+20 || memcmp(d, "Extended Module: ", 17) != 0)
 		return -1;
 	d[17+20] = 0;
 	for(s = d+17; *s == ' '; s++);
-	txtcb(ctx, Ttitle, "", s);
+	cp437toutf8(o, sizeof(o), d+17, 20);
+	txtcb(ctx, Ttitle, "", o);
 
 	return 0;
 }