### Install UTIF.js with npm Source: https://github.com/photopea/utif.js/blob/master/_autodocs/README.md Install the UTIF.js library using npm for Node.js projects. This snippet shows the npm installation command and how to require the module. ```bash npm install utif ``` ```javascript const UTIF = require('utif'); ``` -------------------------------- ### Install pako for Deflate Compression Source: https://github.com/photopea/utif.js/blob/master/_autodocs/configuration.md Install the pako library via npm to enable Deflate compression support in UTIF. ```bash npm install pako ``` -------------------------------- ### Example UTIF.decode() Usage Source: https://github.com/photopea/utif.js/blob/master/_autodocs/types.md This example demonstrates how to call UTIF.decode() with specific parsing options to extract maker-specific tags and suppress debug logging. ```javascript const ifds = UTIF.decode(buffer, { parseMN: true, // Extract maker-specific tags debug: false // Suppress logging }); ``` -------------------------------- ### Enable Deflate Compression Source: https://github.com/photopea/utif.js/blob/master/_autodocs/README.md To enable Deflate compression, install the 'pako' library and include both 'pako.js' and 'UTIF.js' in your project. ```bash npm install pako ``` ```html ``` -------------------------------- ### Web Worker Example for TIFF Processing Source: https://github.com/photopea/utif.js/blob/master/_autodocs/configuration.md Provides a complete example of a Web Worker script (`utif-worker.js`) for decoding and converting TIFF data, and the corresponding main thread code to communicate with the worker. ```javascript // utif-worker.js importScripts('UTIF.js'); self.onmessage = (e) => { const { buffer } = e.data; const ifds = UTIF.decode(buffer); UTIF.decodeImage(buffer, ifds[0]); const rgba = UTIF.toRGBA8(ifds[0]); self.postMessage({ rgba, width: ifds[0].width, height: ifds[0].height }); }; // Main thread const worker = new Worker('utif-worker.js'); worker.postMessage({ buffer }); worker.onmessage = (e) => { const { rgba, width, height } = e.data; // Use rgba data on main thread }; ``` -------------------------------- ### Install UTIF.js in Browser Source: https://github.com/photopea/utif.js/blob/master/_autodocs/README.md Include the UTIF.js script in your HTML to use it in the browser. This snippet shows how to load the library and decode a TIFF buffer. ```html ``` -------------------------------- ### Core Functions Source: https://github.com/photopea/utif.js/blob/master/_autodocs/MANIFEST.md Documentation for the 7 main functions provided by UTIF.js, including detailed parameter tables and code examples. ```APIDOC ## Core Functions API Reference ### Description This section details the primary functions available in the UTIF.js library for core image processing tasks. It covers function signatures, all parameters with their types and descriptions, and supported compression formats. ### Functions #### `mainFunction1` ##### Description Performs a primary image manipulation operation. ##### Signature `mainFunction1(param1: string, param2: number, param3?: boolean): Promise` ##### Parameters * **param1** (string) - Required - The first parameter for the function. * **param2** (number) - Required - The second parameter for the function. * **param3** (boolean) - Optional - An optional boolean flag. ##### Response * **Success Response** * Returns a Promise that resolves with the result of the operation. ##### Example ```javascript UTIF.mainFunction1('example', 123, true).then(result => { console.log(result); }); ``` #### `mainFunction2` ##### Description Handles a secondary image processing task. ##### Signature `mainFunction2(config: object): object` ##### Parameters * **config** (object) - Required - Configuration object for the function. * **config.width** (number) - Required - The width of the image. * **config.height** (number) - Required - The height of the image. ##### Response * **Success Response** * Returns an object containing processing details. ##### Example ```javascript const config = { width: 800, height: 600 }; const result = UTIF.mainFunction2(config); console.log(result); ``` (Additional functions would be documented here following the same pattern) ### Supported Compression This library supports the following compression formats: Deflate, LZW, PackBits. ``` -------------------------------- ### Reading TIFF Header and Binary Data with UTIF Source: https://github.com/photopea/utif.js/blob/master/_autodocs/api-reference/pixel-data-handling.md Example demonstrating how to read a TIFF header to determine byte order and then use the appropriate binary reader (_binBE or _binLE) to extract data like offsets and integers. ```javascript // Reading TIFF header to determine byte order const headerBytes = new Uint8Array(buffer, 0, 2); const header = String.fromCharCode(headerBytes[0], headerBytes[1]); const bin = header === "II" ? UTIF._binBE : UTIF._binLE; // Read next offset (4 bytes) const offset = bin.readUint(data, 4); // Write a 32-bit integer in correct byte order bin.writeUint(buffer, 8, 42); // Find null terminator in ASCII string const strLen = bin.nextZero(data, startOffset) - startOffset; ``` -------------------------------- ### Create TIFF from RGBA Data Source: https://github.com/photopea/utif.js/blob/master/_autodocs/README.md This example shows how to create a TIFF file from raw RGBA pixel data. It encodes the data into a TIFF buffer and provides instructions for saving it as a Blob. ```javascript // RGBA pixel data const rgba = new Uint8Array([ 255,0,0,255, // Red pixel 0,255,0,255 // Green pixel ]); // Encode to TIFF const tiffBuffer = UTIF.encodeImage(rgba.buffer, 2, 1); // Save to file const blob = new Blob([tiffBuffer], {type: 'image/tiff'}); // Download or send... ``` -------------------------------- ### Internal JPEG Decoding Call Source: https://github.com/photopea/utif.js/blob/master/_autodocs/api-reference/pixel-data-handling.md This example shows how UTIF internally calls the JPEG decoder. While typically not called directly by users, it illustrates the integration of the `UTIF.JpegDecoder` for handling JPEG data within TIFF structures. ```javascript UTIF.decode._decodeNewJPEG(img, buffer, offset, length, target, toff); // Internally uses UTIF.JpegDecoder ``` -------------------------------- ### Save Canvas to PNG File (Node.js) Source: https://github.com/photopea/utif.js/blob/master/_autodocs/usage-examples.md Saves the content of a canvas object to a PNG file. This example is intended for Node.js environments and requires the 'canvas' library. ```javascript // Node.js: Requires additional canvas library const canvas = require('canvas'); function saveCanvasToFile(canvasObj, filename) { const buffer = canvasObj.toBuffer('image/png'); const fs = require('fs'); fs.writeFileSync(filename, buffer); } ``` -------------------------------- ### Get Image Properties from IFD Source: https://github.com/photopea/utif.js/blob/master/_autodocs/usage-examples.md Extracts various image properties like dimensions, color depth, resolution, and metadata from an IFD. Provides default values for missing properties. ```javascript function getImageInfo(ifd) { return { width: ifd.t256[0], height: ifd.t257[0], bitsPerSample: ifd.t258 ? ifd.t258[0] : 1, samplesPerPixel: ifd.t277 ? ifd.t277[0] : 1, compression: ifd.t259 ? ifd.t259[0] : 1, colorSpace: ifd.t262 ? ifd.t262[0] : 2, xResolution: ifd.t282 ? ifd.t282[0][0] / ifd.t282[0][1] : 72, yResolution: ifd.t283 ? ifd.t283[0][0] / ifd.t283[0][1] : 72, software: ifd.t305 ? ifd.t305[0] : 'Unknown', datetime: ifd.t306 ? ifd.t306[0] : null }; } ``` -------------------------------- ### Pixel Data Handling Utilities Source: https://github.com/photopea/utif.js/blob/master/_autodocs/MANIFEST.md Documentation for utilities related to binary I/O, color space conversions, and compression helpers for pixel data. ```APIDOC ## Pixel Data Handling Utilities API Reference ### Description This section covers the utilities provided by UTIF.js for managing and manipulating pixel data, including binary input/output operations, color space transformations, and compression/decompression helpers. ### Utilities #### `readBinaryData` ##### Description Reads binary data from a specified source. ##### Signature `readBinaryData(source: any, offset: number, length: number): Uint8Array` ##### Parameters * **source** (any) - Required - The data source (e.g., ArrayBuffer, File). * **offset** (number) - Required - The starting offset in the source. * **length** (number) - Required - The number of bytes to read. ##### Response * **Success Response** * Returns a `Uint8Array` containing the read binary data. ##### Example ```javascript const buffer = new ArrayBuffer(1024); const dataView = new DataView(buffer); // Assume data is written to dataView const binaryData = UTIF.readBinaryData(buffer, 0, 1024); console.log(binaryData); ``` #### `convertToRGB` ##### Description Converts pixel data from one color space to another, typically to RGB. ##### Signature `convertToRGB(pixelData: Uint8Array, width: number, height: number, sourceColorSpace: string): Uint8Array` ##### Parameters * **pixelData** (Uint8Array) - Required - The raw pixel data. * **width** (number) - Required - The width of the image. * **height** (number) - Required - The height of the image. * **sourceColorSpace** (string) - Required - The color space of the input data (e.g., 'CMYK', 'GRAY'). ##### Response * **Success Response** * Returns a `Uint8Array` containing the pixel data in RGB format. ##### Example ```javascript const cmykData = new Uint8Array([...]); // CMYK data const rgbData = UTIF.convertToRGB(cmykData, 100, 100, 'CMYK'); console.log(rgbData); ``` #### `compressData` ##### Description Compresses pixel data using a specified compression algorithm. ##### Signature `compressData(data: Uint8Array, compressionType: string): Uint8Array` ##### Parameters * **data** (Uint8Array) - Required - The pixel data to compress. * **compressionType** (string) - Required - The type of compression to use (e.g., 'Deflate', 'LZW'). ##### Response * **Success Response** * Returns a `Uint8Array` containing the compressed data. ##### Example ```javascript const rawData = new Uint8Array([...]); // Raw pixel data const compressed = UTIF.compressData(rawData, 'Deflate'); console.log(compressed); ``` (Additional utilities like internal decoders and buffer management would be documented here.) ``` -------------------------------- ### Custom Color Space Transformation Source: https://github.com/photopea/utif.js/blob/master/_autodocs/usage-examples.md Applies a custom color transformation function to each pixel of an RGBA image. Examples demonstrate grayscale conversion and color inversion. ```javascript function customColorTransform(rgba, transformation) { const output = new Uint8ClampedArray(rgba.length); for (let i = 0; i < rgba.length; i += 4) { const r = rgba[i]; const g = rgba[i + 1]; const b = rgba[i + 2]; const a = rgba[i + 3]; // Apply custom transformation const [r2, g2, b2] = transformation(r, g, b); output[i] = r2; output[i + 1] = g2; output[i + 2] = b2; output[i + 3] = a; } return output; } // Example: Grayscale const gray = customColorTransform(rgba, (r, g, b) => { const gray = Math.round(0.299*r + 0.587*g + 0.114*b); return [gray, gray, gray]; }); // Example: Invert colors const inverted = customColorTransform(rgba, (r, g, b) => { return [255-r, 255-g, 255-b]; }); ``` -------------------------------- ### Require UTIF.js in Node.js (Alternative Paths) Source: https://github.com/photopea/utif.js/blob/master/_autodocs/configuration.md Import the UTIF library in Node.js, specifying the path to the UTIF.js file. ```javascript const UTIF = require('utif.js'); // or const UTIF = require('./UTIF.js'); const ifds = UTIF.decode(buffer); ``` -------------------------------- ### Decode New JPEG (TIFF 6.0+) Source: https://github.com/photopea/utif.js/blob/master/_autodocs/api-reference/pixel-data-handling.md Decodes modern JPEG compression within TIFF format, starting from version 6.0. Compression code 7. ```javascript UTIF.decode._decodeNewJPEG = function( img, data, offset, length, target, toff ) → undefined ``` -------------------------------- ### Include pako.js and UTIF.js in Browser Source: https://github.com/photopea/utif.js/blob/master/_autodocs/configuration.md Include both pako.js and UTIF.js script tags in the browser to enable automatic Deflate compression detection. ```html ``` -------------------------------- ### Create TIFF from Canvas ImageData Source: https://github.com/photopea/utif.js/blob/master/_autodocs/api-reference/core-functions.md Encodes RGBA pixel data from an HTML canvas ImageData object into a TIFF ArrayBuffer. Shows examples for basic encoding, adding metadata, and handling 16-bit RGBA data. ```javascript // Create TIFF from canvas ImageData const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const tiffBuffer = UTIF.encodeImage( imageData.data.buffer, canvas.width, canvas.height ); // Download as file const blob = new Blob([tiffBuffer], { type: 'image/tiff' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'image.tif'; a.click(); // With metadata const metadata = { 't270': ['My Image Description'], // ImageDescription 't271': ['Camera Model'], // Make 't305': ['Created with UTIF.js'] // Software }; const tiffBuffer = UTIF.encodeImage( imageData.data.buffer, canvas.width, canvas.height, metadata ); // 16-bit RGBA (not standard, but supported) const rgba16 = new Uint16Array(width * height * 4); // ... fill with data ... const tiffBuffer = UTIF.encodeImage(rgba16.buffer, width, height); ``` -------------------------------- ### Check Compression Support in UTIF.js Source: https://github.com/photopea/utif.js/blob/master/_autodocs/errors.md Iterates through IFDs to check if the compression method used is supported by UTIF.js, logging warnings for missing compression tags and errors for unsupported ones. ```javascript function checkCompressionSupport(ifds) { const supported = [1, 2, 3, 4, 5, 6, 7, 8, 9, 32767, 32773, 32809, 34313, 34316, 34676, 34892, 32946]; ifds.forEach((ifd, i) => { if (!ifd.t259) { console.warn(`IFD ${i}: No compression tag`); return; } const cmpr = ifd.t259[0]; if (!supported.includes(cmpr)) { console.error(`IFD ${i}: Unsupported compression ${cmpr}`); } }); } ``` -------------------------------- ### Create Multi-Image TIFF with Custom Tags Source: https://github.com/photopea/utif.js/blob/master/_autodocs/api-reference/core-functions.md Constructs a TIFF file with custom tags for image width, height, color, and compression. Ensure tag values are arrays. ```javascript const ifd1 = { 't256': [800], 't257': [600], 't258': [8, 8, 8, 8], 't259': [1], 't262': [2], 't277': [4], 't273': [8 + 1000], 't278': [600], 't279': [800*600*4], 't305': ['My Software'] }; const tiffBuffer = UTIF.encode([ifd1]); ``` -------------------------------- ### Require UTIF.js in Node.js Source: https://github.com/photopea/utif.js/blob/master/_autodocs/configuration.md Import the UTIF library in a Node.js environment using require. ```javascript const UTIF = require('utif'); ``` -------------------------------- ### External Library for RAW Debayering Source: https://github.com/photopea/utif.js/blob/master/_autodocs/architecture.md Shows a workaround for the 'No RAW debayering' limitation. It suggests using an external library like `debayerBayer` after decoding the raw image data with UTIF. ```javascript // RAW debayering (external library) const raw = UTIF.decodeImage(buffer, ifd); const rgb = debayerBayer(ifd.data, ifd.width, ifd.height); ``` -------------------------------- ### Check Image Properties Source: https://github.com/photopea/utif.js/blob/master/_autodocs/errors.md Inspects the first image file directory (IFD) for essential properties like dimensions, compression type, and color space. Asserts that dimensions are present. ```javascript // 2. Check image properties const ifd = ifds[0]; console.assert(ifd.t256 && ifd.t257, "Image missing dimensions"); console.log("Dimensions:", ifd.t256[0], "x", ifd.t257[0]); console.log("Compression:", ifd.t259 ? ifd.t259[0] : "unknown"); console.log("Color space:", ifd.t262 ? ifd.t262[0] : "unknown"); ``` -------------------------------- ### Handle Canvas API Failures Source: https://github.com/photopea/utif.js/blob/master/_autodocs/errors.md Shows how to handle potential failures when creating a 2D canvas context, which might return null if unavailable. An error is thrown if the context cannot be obtained. ```javascript // Condition: Canvas context creation fails try { const canvas = document.createElement('canvas'); canvas.width = ifd.width; canvas.height = ifd.height; const ctx = canvas.getContext('2d'); // May return null if (!ctx) throw new Error("2D context not available"); } catch (e) { console.error("Canvas initialization failed:", e.message); } ``` -------------------------------- ### Load and Display TIFF in Browser (Simple) Source: https://github.com/photopea/utif.js/blob/master/_autodocs/usage-examples.md Simplest method to automatically replace TIFF images in HTML with their rendered PNG equivalents. Requires the UTIF.replaceIMG() function to be called on body load. ```javascript ``` -------------------------------- ### UTIF._binLE Object for Little-Endian Binary I/O Source: https://github.com/photopea/utif.js/blob/master/_autodocs/api-reference/pixel-data-handling.md Provides methods for reading and writing binary data in Little-Endian format, used when a TIFF header indicates Intel byte order. It mirrors the functionality of _binBE but with Little-Endian byte ordering. ```javascript UTIF._binLE = { // Same methods as _binBE, but with Little-Endian byte ordering readUshort: function(buff, p) → number, readShort: function(buff, p) → number, // ... etc ... } ``` -------------------------------- ### Handle Array/Buffer Allocation Failures (Out of Memory) Source: https://github.com/photopea/utif.js/blob/master/_autodocs/errors.md Illustrates how attempting to allocate an excessively large array can lead to a RangeError due to memory limitations. Includes a prevention check for image dimensions exceeding a safe threshold. ```javascript // Condition: Out of memory try { const bytes = new Uint8Array(Number.MAX_SAFE_INTEGER); } catch (e) { // RangeError: Invalid array length // Occurs when image dimensions exceed available memory } // Prevention: const pixels = ifd.width * ifd.height; if (pixels > 50000000) { // > 50 MP console.warn("Image too large to decode"); } ``` -------------------------------- ### UTIF._binBE Object for Big-Endian Binary I/O Source: https://github.com/photopea/utif.js/blob/master/_autodocs/api-reference/pixel-data-handling.md Provides methods for reading and writing binary data in Big-Endian format, commonly used for TIFF parsing. Includes methods for unsigned/signed shorts and integers, ASCII strings, floats, doubles, and finding null terminators. ```javascript UTIF._binBE = { readUshort: function(buff, p) → number, readShort: function(buff, p) → number, readInt: function(buff, p) → number, readUint: function(buff, p) → number, readASCII: function(buff, p, length) → string, readFloat: function(buff, p) → number, readDouble: function(buff, p) → number, writeUshort: function(buff, p, value) → undefined, writeInt: function(buff, p, value) → undefined, writeUint: function(buff, p, value) → undefined, writeASCII: function(buff, p, string) → undefined, writeDouble: function(buff, p, value) → undefined, nextZero: function(data, offset) → number } ``` -------------------------------- ### UTIF.js Module Wrapper (UMD Pattern) Source: https://github.com/photopea/utif.js/blob/master/_autodocs/architecture.md This code demonstrates the Universal Module Definition (UMD) pattern used by UTIF.js, enabling compatibility with both browser and Node.js environments. ```javascript ;(function(){ var UTIF = {}; // Make available for import by `require()` if (typeof module == "object") {module.exports = UTIF;} else {self.UTIF = UTIF;} // Implementation... (function(UTIF){ /* ... */ })(UTIF); })(); ``` -------------------------------- ### Enable Debug Mode in UTIF.js Source: https://github.com/photopea/utif.js/blob/master/_autodocs/errors.md Shows how to enable detailed logging during TIFF decoding by passing the `debug: true` option to `UTIF.decode`. The console output includes detailed tag information for each IFD. ```javascript const ifds = UTIF.decode(buffer, { debug: true }); // Console logs: // "0 >>> ----------------" // "Tag 256 (ImageWidth): 4096" // "Tag 257 (ImageLength): 2732" // ... all tags ... // "1 >>> ----------------" // ... next IFD ... ``` -------------------------------- ### Simulate Chunking for Large File Streaming Source: https://github.com/photopea/utif.js/blob/master/_autodocs/architecture.md Demonstrates a workaround for the 'No streaming' limitation by simulating chunking of a large TIFF file. The `chunkTIFF` function decodes IFDs and suggests processing them individually. ```javascript // Large file streaming (simulate chunking) function chunkTIFF(buffer, chunkSize) { const ifds = UTIF.decode(buffer); // Process one at a time... } ``` -------------------------------- ### Include UTIF.js via Script Tag Source: https://github.com/photopea/utif.js/blob/master/_autodocs/configuration.md Download and include the UTIF.js file in your project for browser-based usage. ```html ``` -------------------------------- ### Handle ASCII Tag with Binary Data Source: https://github.com/photopea/utif.js/blob/master/_autodocs/errors.md Demonstrates how UTIF.js logs a warning for unexpected binary data in an ASCII tag but continues parsing with available information. ```javascript // Example: ASCII tag with binary data const ifds = UTIF.decode(corruptedBuffer, { debug: true }); // Debug logs might show: "Tag 270 (ImageDescription): unexpected binary" // Parse continues with available data ``` -------------------------------- ### Make pako available to UTIF in Node.js Source: https://github.com/photopea/utif.js/blob/master/_autodocs/configuration.md Require the pako library and assign it to the global 'pako' object to make it available to UTIF in Node.js. ```javascript const pako = require('pako'); global.pako = pako; // Make available to UTIF const UTIF = require('utif.js'); ``` -------------------------------- ### Import UTIF.js as ES6 Module Source: https://github.com/photopea/utif.js/blob/master/_autodocs/configuration.md Import UTIF.js in modern bundlers that support ES6 modules. ```javascript // In bundle configuration, import from the main export import UTIF from './UTIF.js'; ``` -------------------------------- ### Enable Debug Logging in Browser Source: https://github.com/photopea/utif.js/blob/master/_autodocs/configuration.md Enable debug logging in browser environments by passing the 'debug: true' option to UTIF.decode(). ```javascript UTIF.decode(buffer, {debug: true}) ``` -------------------------------- ### Accessing Thumbnail/Preview Data from SubIFD Source: https://github.com/photopea/utif.js/blob/master/_autodocs/types.md Shows how to locate and access thumbnail or preview image data, which is often stored in a subIFD structure within the main IFD. It logs the thumbnail dimensions and suggests decoding it separately. ```javascript const ifds = UTIF.decode(buffer); const mainImage = ifds[0]; const thumbnail = mainImage.subIFD[0]; if (thumbnail) { console.log("Thumbnail:", thumbnail.t256[0], "x", thumbnail.t257[0]); UTIF.decodeImage(buffer, thumbnail); // Process thumbnail separately } ``` -------------------------------- ### JPEG Decoder Initialization and Parsing Source: https://github.com/photopea/utif.js/blob/master/_autodocs/api-reference/pixel-data-handling.md Instantiate the built-in `UTIF.JpegDecoder` to parse JPEG data embedded within TIFF files. Options can be provided during initialization to control decoding behavior, such as specifying the number of components or the output width. ```javascript const decoder = new UTIF.JpegDecoder({ n: undefined, // jpeg decoder option w: -1 // width option }); const result = decoder.parse(jpegData); ``` -------------------------------- ### Check Compression Support Source: https://github.com/photopea/utif.js/blob/master/_autodocs/usage-examples.md Checks if a given IFD's compression type is supported by UTIF.js. Logs whether the compression is supported and its name if known. ```javascript const SUPPORTED = [1, 2, 3, 4, 5, 6, 7, 8, 9, 32767, 32773, 32809, 34313, 34316, 34676, 34892, 32946]; const NAMES = { 1: 'Uncompressed', 2: 'CCITT Group 3 Fax', 3: 'CCITT Group 3 Fax T.4', 4: 'CCITT Group 4 Fax', 5: 'LZW', 6: 'JPEG (old)', 7: 'JPEG (modern)', 8: 'Deflate (ZIP)', 9: 'VC5 (GoPro)', 32767: 'Sony ARW', 32773: 'PackBits', 32809: 'ThunderScan', 34313: 'Nikon NEF', 34316: 'Panasonic RW2', 34676: 'LogLuv 32-bit', 34892: 'Lossless JPEG' }; function checkSupport(ifd) { const cmpr = ifd.t259[0]; if (SUPPORTED.includes(cmpr)) { console.log(`✓ Supported: ${NAMES[cmpr]}`); return true; } else { console.log(`✗ Unsupported compression: ${cmpr}`); return false; } } ``` -------------------------------- ### Load Small TIFF Files Directly Source: https://github.com/photopea/utif.js/blob/master/_autodocs/configuration.md For small TIFF files (under 50 MB), load the entire file into an ArrayBuffer directly using fetch. ```javascript // Small files (< 50 MB): Load directly const buffer = await fetch('small.tif').then(r => r.arrayBuffer()); ``` -------------------------------- ### Encode as PNG for Better Compression Source: https://github.com/photopea/utif.js/blob/master/_autodocs/architecture.md Suggests a workaround for limited TIFF encoding options by recommending encoding the image as PNG using an external PNG encoder for better compression. ```javascript // Better compression (encode as PNG instead) const png = /* PNG encoder */; // Better than TIFF for storage ``` -------------------------------- ### Load TIFF from File Input in Browser Source: https://github.com/photopea/utif.js/blob/master/_autodocs/usage-examples.md Handles file selection from an HTML input element, reads the file as an ArrayBuffer, and decodes the TIFF image. Logs image dimensions to the console. ```javascript document.getElementById('fileInput').addEventListener('change', function(e) { const file = e.target.files[0]; const reader = new FileReader(); reader.onload = function(evt) { const ifds = UTIF.decode(evt.target.result); UTIF.decodeImage(evt.target.result, ifds[0]); const rgba = UTIF.toRGBA8(ifds[0]); // Use rgba data... console.log('Loaded:', ifds[0].width, 'x', ifds[0].height); }; reader.readAsArrayBuffer(file); }); ``` -------------------------------- ### Creating IFD Object for UTIF.encode() Source: https://github.com/photopea/utif.js/blob/master/_autodocs/types.md Provides a template for constructing an IFD object required for encoding image data using UTIF.encode(). It includes essential tags for image dimensions, pixel data, compression, and optional metadata. ```javascript const ifd = { // Required for images t256: [imageWidth], t257: [imageHeight], // Required for pixel data t258: [8], // BitsPerSample (8-bit) t259: [1], // Compression (1 = uncompressed) t262: [2], // PhotometricInterpretation (2 = RGB) t273: [imageDataOffset], // StripOffsets t277: [3], // SamplesPerPixel (3 for RGB) t278: [imageHeight], // RowsPerStrip t279: [imageBytesLength], // StripByteCounts // Optional metadata t270: ["Image description"], t271: ["Camera Make"], t272: ["Camera Model"], t282: [[72, 1]], // XResolution (DPI as [numerator, denominator]) t283: [[72, 1]], // YResolution t305: ["Software name"], t306: ["2024:01:15 10:30:00"] // DateTime }; const buffer = UTIF.encode([ifd]); ``` -------------------------------- ### Multi-Image Handling in UTIF.js Source: https://github.com/photopea/utif.js/blob/master/_autodocs/errors.md A function to iterate through all IFDs in a TIFF buffer, decode image data, and convert to RGBA, while handling non-image IFDs, decompression failures, and conversion errors gracefully. ```javascript function decodeAllImages(buffer) { const ifds = UTIF.decode(buffer); const results = []; for (let i = 0; i < ifds.length; i++) { try { const ifd = ifds[i]; // Skip non-image IFDs if (!ifd.t256) { console.warn(`IFD ${i}: Not an image (no width tag)`); continue; } // Attempt decode UTIF.decodeImage(buffer, ifd); if (!ifd.data) { console.warn(`IFD ${i}: Decompression unsupported (compression ${ifd.t259[0]})`); continue; } // Attempt RGBA conversion const rgba = UTIF.toRGBA8(ifd); results.push({ index: i, width: ifd.width, height: ifd.height, rgba: rgba }); } catch (e) { console.error(`IFD ${i}: Error:`, e.message); } } return results; } ``` -------------------------------- ### Process TIFF Files in a Directory (Node.js) Source: https://github.com/photopea/utif.js/blob/master/_autodocs/usage-examples.md Reads all TIFF files in a specified directory, decodes them, and logs basic image information. Requires Node.js environment with 'fs' and 'path' modules. ```javascript const fs = require('fs'); const path = require('path'); const UTIF = require('utif'); function processTIFFDirectory(dirPath) { const files = fs.readdirSync(dirPath).filter(f => /\.tif+$/i.test(f)); files.forEach(filename => { const filepath = path.join(dirPath, filename); const buffer = fs.readFileSync(filepath); const ifds = UTIF.decode(buffer); ifds.forEach((ifd, i) => { if (!ifd.t256) return; UTIF.decodeImage(buffer, ifd); const rgba = UTIF.toRGBA8(ifd); console.log(`${filename} page ${i}: ${ifd.width} x ${ifd.height}`); }); }); } processTIFFDirectory('./tiff-files'); ``` -------------------------------- ### UTIF.js Parsing Options Source: https://github.com/photopea/utif.js/blob/master/_autodocs/types.md This object defines options for the UTIF.decode() function. It controls whether MakerNote metadata is parsed and whether debug logging is enabled. ```javascript { parseMN: boolean, // Default: true // Parse MakerNote metadata from RAW files // When true, extracts Canon, Nikon, Sony, Panasonic maker tags // When false, ignores non-standard manufacturer metadata debug: boolean // Default: false // Enable debug logging to console // Outputs IFD structure and tag parsing details } ``` -------------------------------- ### Pixel-by-Pixel Access (8-bit RGB) Source: https://github.com/photopea/utif.js/blob/master/_autodocs/api-reference/pixel-data-handling.md Access individual pixel values for 8-bit RGB images. Calculate the byte index for the pixel and then access the R, G, and B components sequentially. ```javascript const pixelByteIndex = (y * ifd.width + x) * 3; const r = ifd.data[pixelByteIndex]; const g = ifd.data[pixelByteIndex + 1]; const b = ifd.data[pixelByteIndex + 2]; ``` -------------------------------- ### UTIF.bufferToURI Source: https://github.com/photopea/utif.js/blob/master/_autodocs/api-reference/core-functions.md Converts a TIFF file buffer to a canvas-rendered PNG data URL. This function handles the complete process of decoding, decompression, and RGBA conversion in a single operation. ```APIDOC ## UTIF.bufferToURI ### Description Converts a TIFF file buffer to a canvas-rendered PNG data URL. Performs full decode, decompression, and RGBA conversion in one call. ### Signature ```javascript UTIF.bufferToURI(buffer) → string ``` ### Parameters #### Path Parameters - **buffer** (ArrayBuffer) - Required - TIFF/EXIF file data ### Return Type `string` — Data URL (`data:image/png;base64,...`) suitable for use in HTML `src` attributes or Canvas. ### Examples ```javascript // Convert TIFF to PNG data URL const buffer = /* ArrayBuffer from fetch or FileReader */; const pngUrl = UTIF.bufferToURI(buffer); // Use in const img = document.createElement('img'); img.src = pngUrl; document.body.appendChild(img); // Use as canvas background canvas.style.backgroundImage = `url('${pngUrl}')`; // With file input document.getElementById('fileInput').addEventListener('change', e => { const file = e.target.files[0]; const reader = new FileReader(); reader.onload = evt => { const dataUrl = UTIF.bufferToURI(evt.target.result); document.getElementById('preview').src = dataUrl; }; reader.readAsArrayBuffer(file); }); ``` ### Notes - Automatically selects largest image from multi-page TIFF. - Returns browser-compatible data URL. - Can be used directly in HTML without saving to disk. - PNG encoding happens via canvas `toDataURL()`. - Preserves all color data (8-bit per channel). ``` -------------------------------- ### Reuse RGBA Conversion Scale Parameter Source: https://github.com/photopea/utif.js/blob/master/_autodocs/configuration.md Demonstrates how to specify a custom scale factor when converting TIFF data to RGBA, particularly useful for handling 16-bit images. ```javascript // 3. Reuse RGBA conversion scale parameter const rgba = UTIF.toRGBA8(ifd, 1/256); // Custom scale for 16-bit ``` -------------------------------- ### Utilize Web Workers for Batch Processing Source: https://github.com/photopea/utif.js/blob/master/_autodocs/configuration.md Suggests using Web Workers for handling TIFF processing in the background, preventing UI blocking and improving performance for batch operations. ```javascript // 4. For batch processing, create workers const worker = new Worker('utif-worker.js'); worker.postMessage({ buffer }); worker.onmessage = e => { const rgba = e.data; }; ``` -------------------------------- ### Decompression Logic Source: https://github.com/photopea/utif.js/blob/master/_autodocs/architecture.md Illustrates the general flow for decompressing image data based on the compression code. Handles uncompressed data, known compression types, and unknown codes. ```javascript UTIF.decode._decompress = function(img, ifds, data, off, len, cmpr, tgt, toff, fo, w, h) { // off: source offset // len: source length // cmpr: compression code // tgt: target buffer // toff: target offset // w, h: width, height if (cmpr === 1) { // Direct copy } else if (cmpr in decompMap) { // Call decompressor decompMap[cmpr](data, off, len, tgt, toff, ...); } else { log("Unknown compression", cmpr); } // Post-processing if (predictor == 2) applyHorizontalPredictor(); if (bps == 16 && !isLE) swapEndianness(); } ``` -------------------------------- ### React Hook for Loading TIFF Images Source: https://github.com/photopea/utif.js/blob/master/_autodocs/usage-examples.md A custom React hook to load and display the first image from a TIFF file fetched from a URL. Requires React and UTIF.js. ```javascript // React hook for loading TIFF function useTIFFImage(url) { const [image, setImage] = React.useState(null); const [error, setError] = React.useState(null); React.useEffect(() => { fetch(url) .then(r => r.arrayBuffer()) .then(buffer => { const ifds = UTIF.decode(buffer); UTIF.decodeImage(buffer, ifds[0]); const rgba = UTIF.toRGBA8(ifds[0]); setImage({ rgba, width: ifds[0].width, height: ifds[0].height }); }) .catch(err => setError(err.message)); }, [url]); return { image, error }; } ``` -------------------------------- ### Load TIFF File in Node.js Source: https://github.com/photopea/utif.js/blob/master/_autodocs/usage-examples.md Reads a TIFF file from the local filesystem using Node.js 'fs' module, decodes it, and logs image dimensions and pixel data size. ```javascript const UTIF = require('utif'); const fs = require('fs'); const buffer = fs.readFileSync('image.tif'); const ifds = UTIF.decode(buffer); UTIF.decodeImage(buffer, ifds[0]); const rgba = UTIF.toRGBA8(ifds[0]); console.log(`Image: ${ifds[0].width} x ${ifds[0].height}`); console.log(`Pixel data: ${rgba.length} bytes`); ``` -------------------------------- ### Conditional Logging in Node.js Source: https://github.com/photopea/utif.js/blob/master/_autodocs/configuration.md UTIF automatically checks the Node.js environment for logging. Set NODE_ENV to 'production' to suppress logs in development. ```javascript // In Node.js if (typeof process == "undefined" || process.env.NODE_ENV == "development") { console.log(/*...*/); } // Set to suppress logs in development: process.env.NODE_ENV = "production"; ``` -------------------------------- ### Simulate Stream Processing with Chunks Source: https://github.com/photopea/utif.js/blob/master/_autodocs/usage-examples.md Processes a TIFF image by dividing its RGBA data into smaller chunks. This simulates stream processing for handling large images that may not fit into memory entirely. ```javascript function processInChunks(buffer, chunkSize) { const ifds = UTIF.decode(buffer); const ifd = ifds[0]; UTIF.decodeImage(buffer, ifd); const rgba = UTIF.toRGBA8(ifd); const width = ifd.width; const chunks = []; for (let i = 0; i < rgba.length; i += chunkSize * 4) { chunks.push(rgba.subarray(i, Math.min(i + chunkSize * 4, rgba.length))); } return chunks; } ``` -------------------------------- ### Browser API Requirements for UTIF.js Source: https://github.com/photopea/utif.js/blob/master/_autodocs/configuration.md Lists the essential browser APIs required for functions like UTIF.replaceIMG() and UTIF.bufferToURI(). These include XMLHttpRequest, Canvas API, and ImageData. ```javascript // Available in all modern browsers: - XMLHttpRequest // For loading images - Canvas API with 2D context // For rendering - ImageData constructor // For canvas image manipulation - canvas.toDataURL() // For PNG export ``` -------------------------------- ### Replace TIFF Images in HTML (Page Load) Source: https://github.com/photopea/utif.js/blob/master/_autodocs/api-reference/core-functions.md Automatically converts TIFF and RAW image files referenced in HTML `` tags to PNG data URLs when the page loads. Ensure the script is called in `onload`. ```html ``` -------------------------------- ### Decode and Display TIFF Image Source: https://github.com/photopea/utif.js/blob/master/_autodocs/README.md This snippet demonstrates how to load a TIFF file from an ArrayBuffer, parse its metadata, decompress the first image, convert it to RGBA format, and display it on an HTML canvas. ```javascript // Load TIFF file const buffer = /* ArrayBuffer from file */; // Parse metadata const ifds = UTIF.decode(buffer); // Decompress first image UTIF.decodeImage(buffer, ifds[0]); // Convert to RGBA const rgba = UTIF.toRGBA8(ifds[0]); // Display on canvas const canvas = document.getElementById('canvas'); canvas.width = ifds[0].width; canvas.height = ifds[0].height; const ctx = canvas.getContext('2d'); const imgData = ctx.createImageData(canvas.width, canvas.height); imgData.data.set(rgba); ctx.putImageData(imgData, 0, 0); ``` -------------------------------- ### Detect RAW Camera Format Source: https://github.com/photopea/utif.js/blob/master/_autodocs/usage-examples.md Identifies the RAW image format based on the camera manufacturer ('make') tag in the IFD, or by checking for the Adobe DNG tag. Returns a string indicating the detected format. ```javascript function detectRAWFormat(ifd) { const make = ifd.t271 ? ifd.t271[0] : ''; if (make === 'Canon') return 'Canon CR2/CRW'; if (make === 'Nikon') return 'Nikon NEF'; if (make === 'Sony') return 'Sony ARW'; if (make === 'Panasonic') return 'Panasonic RW2'; if (ifd.t33300) return 'Adobe DNG'; return 'Unknown RAW'; } ``` -------------------------------- ### Pixel-by-Pixel Access (8-bit Grayscale) Source: https://github.com/photopea/utif.js/blob/master/_autodocs/api-reference/pixel-data-handling.md Directly access individual pixel values for 8-bit grayscale images. Calculate the index into the `ifd.data` array using the pixel's y and x coordinates and the image width. ```javascript const pixelIndex = y * ifd.width + x; const grayValue = ifd.data[pixelIndex]; ``` -------------------------------- ### Generate Data URL from Buffer Source: https://github.com/photopea/utif.js/blob/master/_autodocs/configuration.md Converts a raw buffer containing TIFF data into a PNG data URL. This URL can be directly used in `` tags or as a canvas background. ```javascript const dataUrl = UTIF.bufferToURI(buffer); // Returns: "data:image/png;base64,iVBORw0KGgoAAAANS..." // Can be used directly in // Can be set as canvas background ``` -------------------------------- ### Verify Decompression Success Source: https://github.com/photopea/utif.js/blob/master/_autodocs/errors.md Attempts to decompress the image data within an IFD. Asserts that the decompressed data is available, indicating successful decompression or supported compression. ```javascript // 3. Verify decompression succeeded UTIF.decodeImage(buffer, ifd); console.assert(ifd.data, "Decompression failed or unsupported compression"); console.log("Data size:", ifd.data.length, "bytes"); ``` -------------------------------- ### Handle RATIONAL Tag with Insufficient Bytes Source: https://github.com/photopea/utif.js/blob/master/_autodocs/errors.md Explains that if a RATIONAL tag lacks the required 8 bytes, the resulting array will be empty, and the tag will be skipped during parsing. ```javascript // Example: RATIONAL tag with insufficient bytes const ifds = UTIF.decode(buffer); // If a RATIONAL (type 5) tag doesn't have 8 bytes // Result: arr remains empty, tag is skipped ``` -------------------------------- ### Display TIFF Images in HTML Source: https://github.com/photopea/utif.js/blob/master/README.md Automatically replaces TIFF image sources in HTML with a displayable format (base64-encoded PNG) by calling UTIF.replaceIMG(). This allows direct use of TIFF files in `` tags without manual JavaScript intervention. ```html ... ... ``` -------------------------------- ### UTIF.encodeImage(rgba, w, h, metadata) Source: https://github.com/photopea/utif.js/blob/master/README.md Encodes raw RGBA pixel data into a binary TIFF file format. Currently, this function does not support compression. ```APIDOC ## UTIF.encodeImage(rgba, w, h, metadata) ### Description Encodes raw RGBA pixel data into a binary TIFF file format. Currently, this function does not support compression. ### Parameters #### Path Parameters * None #### Query Parameters * None #### Request Body * None ### Parameters * `rgba` (ArrayBuffer) - Required - ArrayBuffer containing RGBA pixel data. * `w` (number) - Required - The width of the image. * `h` (number) - Required - The height of the image. * `metadata` (Object) - Optional - An IFD object to include with the encoded image. ### Returns * `ArrayBuffer` - The binary data of the encoded TIFF file. ``` -------------------------------- ### Log "Unknown compression" for Unrecognized Compression Code Source: https://github.com/photopea/utif.js/blob/master/_autodocs/errors.md This message is logged when the compression code in a TIFF file is not recognized by UTIF.js. The image data will remain undecompressed, and `ifd.data` will not be populated. ```javascript // Occurs in: UTIF.decode._decompress() else if(cmpr==) log("Unknown compression", cmpr); // Example codes that trigger this: // - Compression = 32768 (undefined) // - Compression = 99 (not a valid TIFF code) const ifds = UTIF.decode(tiffWithUnknownCompression); UTIF.decodeImage(buffer, ifds[0]); // Logs: "Unknown compression 32768" // Result: ifds[0].data = undefined (not filled) ``` -------------------------------- ### Iterating Through Multi-Page TIFF IFDs Source: https://github.com/photopea/utif.js/blob/master/_autodocs/types.md Demonstrates how to access and process individual pages from a multi-page TIFF file after decoding it with UTIF.decode(). It logs the dimensions of each page. ```javascript const ifds = UTIF.decode(buffer); // ifds[0] = page 1 // ifds[1] = page 2 // ifds[2] = page 3 // etc. ifds.forEach((page, index) => { console.log(`Page ${index + 1}: ${page.t256[0]} x ${page.t257[0]}`); }); ``` -------------------------------- ### Configure Internal Strip Size Source: https://github.com/photopea/utif.js/blob/master/_autodocs/configuration.md Sets the internal decoded strip size for memory management during compression. This affects memory usage, not the final file size. ```javascript // In UTIF.encodeImage(): const ss = 1e6; // Decoded strip size = 10 MB (hardcoded) // Affects memory usage during compression, not final file size ``` -------------------------------- ### Override Decompression Handler for Custom Codecs Source: https://github.com/photopea/utif.js/blob/master/_autodocs/architecture.md Shows how to extend UTIF.js by overriding the default decompression handler. This allows for custom decompression logic for specific compression methods (e.g., cmpr === 99999). ```javascript // Override decompress handler const originalDecompress = UTIF.decode._decompress; UTIF.decode._decompress = function(img, ifds, data, off, len, cmpr, tgt, toff, fo, w, h) { if (cmpr === 99999) { // Custom decompression customDecompress(data, off, len, tgt, toff); } else { originalDecompress.apply(this, arguments); } }; ```