File size: 3,047 Bytes
2bc6d22 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
import * as avif from '@jsquash/avif';
import * as jpeg from '@jsquash/jpeg';
import * as jxl from '@jsquash/jxl';
import * as png from '@jsquash/png';
import * as webp from '@jsquash/webp';
import type { OutputType, CompressionOptions } from '../types';
import type { AvifEncodeOptions, JpegEncodeOptions, JxlEncodeOptions, WebpEncodeOptions } from '../types/encoders';
import { ensureWasmLoaded } from './wasm';
export async function decode(sourceType: string, fileBuffer: ArrayBuffer): Promise<ImageData> {
// Ensure WASM is loaded for the source type
await ensureWasmLoaded(sourceType as OutputType);
try {
switch (sourceType) {
case 'avif':
return await avif.decode(fileBuffer);
case 'jpeg':
case 'jpg':
return await jpeg.decode(fileBuffer);
case 'jxl':
return await jxl.decode(fileBuffer);
case 'png':
return await png.decode(fileBuffer);
case 'webp':
return await webp.decode(fileBuffer);
default:
throw new Error(`Unsupported source type: ${sourceType}`);
}
} catch (error) {
console.error(`Failed to decode ${sourceType} image:`, error);
throw new Error(`Failed to decode ${sourceType} image`);
}
}
export async function encode(outputType: OutputType, imageData: ImageData, options: CompressionOptions): Promise<ArrayBuffer> {
// Ensure WASM is loaded for the output type
await ensureWasmLoaded(outputType);
try {
switch (outputType) {
case 'avif': {
const avifOptions: AvifEncodeOptions = {
quality: options.quality,
effort: 4 // Medium encoding effort
};
return await avif.encode(imageData, avifOptions as any);
}
case 'jpeg': {
const jpegOptions: JpegEncodeOptions = {
quality: options.quality
};
return await jpeg.encode(imageData, jpegOptions as any);
}
case 'jxl': {
const jxlOptions: JxlEncodeOptions = {
quality: options.quality
};
return await jxl.encode(imageData, jxlOptions as any);
}
case 'png':
return await png.encode(imageData);
case 'webp': {
const webpOptions: WebpEncodeOptions = {
quality: options.quality
};
return await webp.encode(imageData, webpOptions as any);
}
default:
throw new Error(`Unsupported output type: ${outputType}`);
}
} catch (error) {
console.error(`Failed to encode to ${outputType}:`, error);
throw new Error(`Failed to encode to ${outputType}`);
}
}
export function getFileType(file: File): string {
if (file.name.toLowerCase().endsWith('jxl')) return 'jxl';
const type = file.type.split('/')[1];
return type === 'jpeg' ? 'jpg' : type;
}
export function formatFileSize(bytes: number): string {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
}
|