export function getOrientation(arrayBuffer: ArrayBuffer): number { try { const view = new DataView(arrayBuffer); if (view.getUint16(0, false) !== 0xFFD8) { return 1; } let offset = 2; const length = view.byteLength; while (offset < length) { if (view.getUint16(offset + 2, false) <= 8) return 1; const marker = view.getUint16(offset, false); offset += 2; if (marker === 0xFFE1) { const exifOffset = offset + 10; if (exifOffset > length) return 1; const little = view.getUint16(exifOffset, false) === 0x4949; offset += 4 + view.getUint32(exifOffset + 4, little); const tags = view.getUint16(offset, little); offset += 2; for (let i = 0; i < tags; i++) { const tagOffset = offset + (i * 12); if (view.getUint16(tagOffset, little) === 0x0112) { return view.getUint16(tagOffset + 8, little); } } } else if ((marker & 0xFF00) !== 0xFF00) { break; } else { offset += view.getUint16(offset, false); } } } catch (error) { console.warn("Could not read EXIF orientation, using default:", error); } return 1; } export function applyOrientation( ctx: CanvasRenderingContext2D, orientation: number, width: number, height: number, ) { switch (orientation) { case 2: ctx.transform(-1, 0, 0, 1, width, 0); break; case 3: ctx.transform(-1, 0, 0, -1, width, height); break; case 4: ctx.transform(1, 0, 0, -1, 0, height); break; case 5: ctx.transform(0, 1, 1, 0, 0, 0); break; case 6: ctx.transform(0, 1, -1, 0, height, 0); break; case 7: ctx.transform(0, -1, -1, 0, height, width); break; case 8: ctx.transform(0, -1, 1, 0, 0, width); break; default: break; } }