How TIFF to JPG Conversion Runs in Your Browser
A TIFF is structured around Image File Directories (IFDs): a header declares the byte order (II or MM), then a linked list of IFDs follows, each holding a set of typed tags that describe one image — width, height, bits per sample, compression scheme, photometric interpretation, and a pointer to the raw pixel strip data. Decoding a TIFF means walking that structure and then decompressing the strips according to the scheme the file declares. This page loads UTIF.js, a compact pure-JavaScript TIFF decoder, to do exactly that: UTIF.decode() parses the header and IFD chain into an array of image objects, and UTIF.decodeImage() decompresses the first image's strips, handling LZW, Deflate, PackBits, and uncompressed layouts as the tags dictate.
Compression is only half the battle — TIFFs also carry arbitrary photometric and bit-depth combinations. UTIF.toRGBA8() normalizes them into a single 8-bit RGBA buffer, converting 16-bit samples down to 8-bit and translating CMYK, grayscale, and paletted interpretations into RGB. That buffer is written into a canvas through createImageData() and putImageData(), which places pixels directly without any resampling, and the canvas is handed to canvas.toBlob(..., 'image/jpeg', 0.92) for the final lossy encode. The whole decode-to-encode chain uses an ArrayBuffer read from the file object — no network copy of the scan is ever made.
That last point matters most for this format. TIFF is the format of scanners, prepress, and archives, and its files are routinely tens of megabytes. Uploading one to a hosted converter is slow and, for medical or legal scans, a genuine privacy risk. Running the decode in-browser means a 300 MB uncompressed scan stays exactly where it should — in your RAM — while your device does all the work, and the output JPG typically lands at 5% of the source size.