How HEIC to JPG Conversion Runs in Your Browser
HEIC files are ISO Base Media File Format (ISOBMFF) containers. Inside the box structure — ftyp, meta, iloc, and friends — the actual pixels are stored as HEVC (H.265) intra-coded image items, which is exactly why a plain <img> tag cannot render them. To decode that bitstream without a server, this page loads libheif compiled to WebAssembly (shipped through the heic2any library). When you drop a file, the browser reads it into an ArrayBuffer; that buffer is handed to the WASM module, which allocates its own linear memory inside the module instance, parses the HEIF box tree, and runs an H.265 decoder on your CPU to produce a raw RGBA pixel buffer.
From there the pipeline is pure Canvas 2D. The decoded frame is copied into an ImageData whose alpha channel was initialized to 255 — because JPEG has nowhere to store transparency — and placed onto a canvas at full resolution with putImageData(), bypassing any resampling. Then canvas.toBlob(..., 'image/jpeg', 0.92) invokes the browser's native JPEG encoder: the RGBA surface is converted to YCbCr, chroma is subsampled, and the entropy-coded stream is written by the engine's own baseline encoder, so the file that downloads is fully standards-compliant and openable everywhere — with EXIF intentionally absent, since the canvas path carries pixels only.
Color handling is the subtle part. iPhone HEIC photos are frequently tagged with a Display P3 ICC profile at 10-bit depth; that wide-gamut-to-sRGB conversion is performed by libheif inside the WASM module while it produces the 8-bit RGBA frame, and the raw bytes then pass through putImageData() without any further color transform — which is why output colors stay consistent across Macs, Windows machines, and Android devices. The whole process consumes zero network bandwidth for your data — the only download is the decoder library itself, fetched once from a CDN and cached. That is why the conversion is private by construction: your photo's bytes are touched only by code executing on your own device.