UNPKG

@micrio/tiler-base

Version:

The base Micrio client-side tiler package used by the Micrio CLI and GUI tools

76 lines (75 loc) 2.78 kB
import { promises as fs } from 'node:fs'; import path from 'path'; import { walkSync } from './utils.js'; /** Generate a single preloader .bin file containing omni/album image thumbnails */ export async function getArchiveBin(outDir, format, containerId, entries, omniId) { const archiveDir = path.join(outDir, containerId + '_basebin'); const start = Date.now(); const isOmni = !!omniId; await fs.mkdir(archiveDir); const delta = isOmni ? 0 : entries.length > 200 ? 2 : entries.length > 50 ? 1 : 0; const albumImages = []; for (let [fileName, info] of entries) { const level = getThumbLevel(info, delta).toString(); const archiveImgDir = path.join(archiveDir, (info.omniFrame ?? info.id).toString()); await fs.mkdir(archiveImgDir); await fs.rename(path.join(info.baseDir, level), path.join(archiveImgDir, level)); if (!isOmni) albumImages.push({ id: info.id, width: info.width, height: info.height, created: start, title: fileName, isWebP: format == 'webp', isPng: format == 'png', isDeepZoom: true }); } // Files to be included in the binary const bundleFiles = []; // For (PDF) album, include static album JSON if (!isOmni) bundleFiles.push({ path: `${containerId}.json`, buffer: new Uint8Array(new TextEncoder().encode(JSON.stringify({ delta, images: albumImages }))) }); // Add the tiles await walkSync(archiveDir).then(async (files) => { for (const f of files) bundleFiles.push({ path: f.replace(/\\/g, '/').replace(/^.*_basebin\//, ''), buffer: await fs.readFile(f) }); }); return generateMDP(bundleFiles).arrayBuffer().then(r => new Uint8Array(r)); } function getThumbLevel(info, delta) { let d = Math.max(info.width, info.height), l = delta; while (d > 1024) { d /= 2; l++; } let dzLevels = 0, max = Math.max(info.width, info.height); do dzLevels++; while ((max /= 2) > 1); return dzLevels - l; } function generateMDP(files) { const enc = new TextEncoder(); const arr = []; files.forEach(i => { if (!i.buffer || !i.path) return; const name = enc.encode(i.path); // byte[20] const size = i.buffer.byteLength.toString(8); // byte[12] arr.push(name, new Uint8Array(20 - name.byteLength)); arr.push(enc.encode('0'.repeat(12 - size.length) + size)); arr.push(i.buffer); }); return new Blob(arr, { type: 'application/octet-stream' }); }