shithub: libtags

Download patch

ref: f68e997ecefd77b3d1cd33c21264d5ced6e5d021
parent: c074cc2a8b2d8e2721457f3c8723298dfd1fd212
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sun Mar 17 23:22:41 EDT 2024

flac: parse seek table as toc

--- a/flac.c
+++ b/flac.c
@@ -6,8 +6,8 @@
 int
 tagflac(Tagctx *ctx)
 {
+	int sz, last, type, seektbloff, seektblsz, off;
 	uint8_t *d;
-	int sz, last, type;
 	uint64_t g;
 
 	d = (uint8_t*)ctx->buf;
@@ -37,7 +37,12 @@
 		if((d[0] & 0x80) != 0)
 			last = 1;
 
-		if((d[0] & 0x7f) == 6){ /* 6 = picture */
+		if((d[0] & 0x7f) == 3 && ctx->toc != nil){ /* 3 = seek table */
+			seektbloff = ctx->seek(ctx, 0, 1);
+			seektblsz = sz;
+			if(ctx->seek(ctx, sz, 1) <= 0)
+				return -1;
+		}else if((d[0] & 0x7f) == 6){ /* 6 = picture */
 			int n, offset;
 			char *mime;
 
@@ -115,6 +120,32 @@
 			}
 		}else if(ctx->seek(ctx, sz, 1) <= 0)
 			return -1;
+	}
+
+	if(ctx->toc == nil)
+		return 0;
+	off = ctx->seek(ctx, 0, 1);
+	if(seektbloff <= 0 || off <= seektbloff || ctx->seek(ctx, seektbloff, 0) != seektbloff)
+		return 0;
+
+	for(; seektblsz >= 18; seektblsz -= 18){
+		if(ctx->read(ctx, d, 18) != 18)
+			break;
+
+		/* sample offset */
+		g = (uint64_t)beuint(d+0)<<32 | beuint(d+4);
+		if(g == ~0ULL) /* placeholder */
+			break;
+		g = g * 1000 / ctx->samplerate;
+		if(g > INT_MAX)
+			break;
+		int ms = g;
+
+		/* frame offset */
+		g = off + ((uint64_t)beuint(d+8)<<32 | beuint(d+12));
+		if(g > INT_MAX)
+			break;
+		ctx->toc(ctx, ms, g);
 	}
 
 	return 0;
--- a/tagspriv.h
+++ b/tagspriv.h
@@ -1,3 +1,4 @@
+#include <limits.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>