~ft/libtags

f68e997ecefd77b3d1cd33c21264d5ced6e5d021 — Sigrid Solveig Haflínudóttir 2 months ago c074cc2
flac: parse seek table as toc
2 files changed, 34 insertions(+), 2 deletions(-)

M flac.c
M tagspriv.h
M flac.c => flac.c +33 -2
@@ 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 @@ tagflac(Tagctx *ctx)
		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;



@@ 117,5 122,31 @@ tagflac(Tagctx *ctx)
			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;
}

M tagspriv.h => tagspriv.h +1 -0
@@ 1,3 1,4 @@
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>