···
2
+
interface Uint8Array {
7
+
const blobBytes = async (blob: Blob) => {
8
+
if ("bytes" in blob) return blob.bytes();
9
+
return new Response(blob).arrayBuffer().then((buffer) => {
10
+
const uint = new Uint8Array(buffer);
15
+
export const createDong = async (
18
+
): Promise<Blob | string> => {
20
+
image.type === "" ||
21
+
!image.type.startsWith("image/") ||
22
+
audio.type === "" ||
23
+
!audio.type.startsWith("audio/")
25
+
return "Mime types invalid";
29
+
const version = new Int8Array(new ArrayBuffer(2));
37
+
new ArrayBuffer(256 - image.type.length),
40
+
const value = new Uint32Array(1);
41
+
value[0] = image.size;
47
+
new ArrayBuffer(256 - audio.type.length),
50
+
const value = new Uint32Array(1);
51
+
value[0] = audio.size;
55
+
await blobBytes(image),
57
+
await blobBytes(audio),
61
+
export async function readDong(dongFile: File): Promise<
63
+
image: { data: Uint8Array; mime: string };
64
+
audio: { data: Uint8Array; mime: string };
68
+
// get first 2 bytes and verify
69
+
const version = new Uint8Array(await blobBytes(dongFile.slice(0, 2)));
70
+
if (version[0] !== 0xd0 || version[1] !== 2) return "Invalid file";
72
+
// get next 256 bytes and get mime type
73
+
const imgMimeType: string | undefined = (
74
+
await dongFile.slice(2, 258).text()
75
+
).match(/[a-zA-Z0-9.]+\/[a-zA-Z0-9.]+/gm)?.[0];
76
+
if (!imgMimeType) return "Image mime type parse failed";
78
+
// get next 4 bytes and get image size
79
+
const imgSize = new Uint32Array(
80
+
(await blobBytes(dongFile.slice(258, 262))).buffer
83
+
// get next 256 bytes and get mime type
84
+
const audMimeType: string | undefined = (
85
+
await dongFile.slice(262, 518).text()
86
+
).match(/[a-zA-Z0-9.]+\/[a-zA-Z0-9.]+/gm)?.[0];
87
+
if (!audMimeType) return "Audio mime type parse failed";
89
+
// get next 4 bytes and get image size
90
+
const audSize = new Uint32Array(
91
+
(await blobBytes(dongFile.slice(518, 522))).buffer
94
+
const imageBytes = await blobBytes(dongFile.slice(522, 522 + imgSize));
95
+
const audioBytes = await blobBytes(
96
+
dongFile.slice(522 + imgSize, 522 + imgSize + audSize)
111
+
export const download = (file: File) => {
112
+
const url = URL.createObjectURL(file);
113
+
const a = document.createElement("a");
115
+
a.download = file.name;
116
+
document.body.appendChild(a);
118
+
document.body.removeChild(a);
119
+
URL.revokeObjectURL(url);