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>