TIFFReader

Introduction

vtkTIFFReader is a source object that reads TIFF files.

Methods

extend

Method used to decorate a given object (publicAPI+model) with vtkTIFFReader characteristics.

Argument Type Required Description
publicAPI Yes object on which methods will be bounds (public)
model Yes object on which data structure will be bounds (protected)
initialValues ITIFFReaderInitialValues No (default: {})

getBaseURL

Get the base url.

getDataAccessHelper

Get the dataAccess helper.

getFlipY

Get if the image is flipped vertically.

getUrl

Get the url of the object to load.

loadData

Load the object data.

Argument Type Required Description
options ITIFFReaderOptions No

newInstance

Method used to create a new instance of vtkTIFFReader

Argument Type Required Description
initialValues ITIFFReaderInitialValues No for pre-setting some of its content

parse

Parse data.

Argument Type Required Description
content ArrayBuffer Yes The content to parse.

parseAsArrayBuffer

Parse data as ArrayBuffer.

Argument Type Required Description
content ArrayBuffer Yes The content to parse.

requestData

Argument Type Required Description
inData Yes
outData Yes

setDataAccessHelper

Argument Type Required Description
dataAccessHelper Yes

setFlipY

Flip the image vertically.

Argument Type Required Description
flipY String Yes If true, flip the image vertically.

setUrl

Set the url of the object to load.

Argument Type Required Description
url String Yes the url of the object to load.
option ITIFFReaderOptions No The PLY reader options.

Source

index.d.ts
import { vtkAlgorithm, vtkObject } from '../../../interfaces';
import HtmlDataAccessHelper from '../../Core/DataAccessHelper/HtmlDataAccessHelper';
import HttpDataAccessHelper from '../../Core/DataAccessHelper/HttpDataAccessHelper';
import JSZipDataAccessHelper from '../../Core/DataAccessHelper/JSZipDataAccessHelper';
import LiteHttpDataAccessHelper from '../../Core/DataAccessHelper/LiteHttpDataAccessHelper';

interface ITIFFReaderOptions {
compression?: string;
progressCallback?: any;
flipY?: boolean;
}

/**
*
*/
export interface ITIFFReaderInitialValues {}

type vtkTIFFReaderBase = vtkObject &
Omit<
vtkAlgorithm,
| 'getInputData'
| 'setInputData'
| 'setInputConnection'
| 'getInputConnection'
| 'addInputConnection'
| 'addInputData'
>;

export interface vtkTIFFReader extends vtkTIFFReaderBase {
/**
* Get the base url.
*/
getBaseURL(): string;

/**
* Get if the image is flipped vertically.
*/
getFlipY(): boolean;

/**
* Get the dataAccess helper.
*/
getDataAccessHelper():
| HtmlDataAccessHelper
| HttpDataAccessHelper
| JSZipDataAccessHelper
| LiteHttpDataAccessHelper;

/**
* Get the url of the object to load.
*/
getUrl(): string;

/**
* Load the object data.
* @param {ITIFFReaderOptions} [options]
*/
loadData(options?: ITIFFReaderOptions): Promise<any>;

/**
* Parse data.
* @param {ArrayBuffer} content The content to parse.
*/
parse(content: ArrayBuffer): void;

/**
* Parse data as ArrayBuffer.
* @param {ArrayBuffer} content The content to parse.
*/
parseAsArrayBuffer(content: ArrayBuffer): void;

/**
*
* @param inData
* @param outData
*/
requestData(inData: any, outData: any): void;

/**
* Flip the image vertically.
* @param {String} flipY If true, flip the image vertically.
*/
setFlipY(flipY: boolean): boolean;

/**
*
* @param dataAccessHelper
*/
setDataAccessHelper(
dataAccessHelper:
| HtmlDataAccessHelper
| HttpDataAccessHelper
| JSZipDataAccessHelper
| LiteHttpDataAccessHelper
): boolean;

/**
* Set the url of the object to load.
* @param {String} url the url of the object to load.
* @param {ITIFFReaderOptions} [option] The PLY reader options.
*/
setUrl(url: string, option?: ITIFFReaderOptions): Promise<string | any>;
}

/**
* Method used to decorate a given object (publicAPI+model) with vtkTIFFReader characteristics.
*
* @param publicAPI object on which methods will be bounds (public)
* @param model object on which data structure will be bounds (protected)
* @param {ITIFFReaderInitialValues} [initialValues] (default: {})
*/
export function extend(
publicAPI: object,
model: object,
initialValues?: ITIFFReaderInitialValues
): void;

/**
* Method used to create a new instance of vtkTIFFReader
* @param {ITIFFReaderInitialValues} [initialValues] for pre-setting some of its content
*/
export function newInstance(
initialValues?: ITIFFReaderInitialValues
): vtkTIFFReader;

/**
* vtkTIFFReader is a source object that reads TIFF files.
*/
export declare const vtkTIFFReader: {
newInstance: typeof newInstance;
extend: typeof extend;
};
export default vtkTIFFReader;
index.js
import macro from 'vtk.js/Sources/macros';

// Enable data soure for DataAccessHelper
import 'vtk.js/Sources/IO/Core/DataAccessHelper/LiteHttpDataAccessHelper'; // Just need HTTP
// import 'vtk.js/Sources/IO/Core/DataAccessHelper/HttpDataAccessHelper'; // HTTP + zip
// import 'vtk.js/Sources/IO/Core/DataAccessHelper/HtmlDataAccessHelper'; // html + base64 + zip
// import 'vtk.js/Sources/IO/Core/DataAccessHelper/JSZipDataAccessHelper'; // zip

import DataAccessHelper from 'vtk.js/Sources/IO/Core/DataAccessHelper';
import vtkImageData from 'vtk.js/Sources/Common/DataModel/ImageData';
import vtkDataArray from 'vtk.js/Sources/Common/Core/DataArray';
import UTIF from 'utif';

// ----------------------------------------------------------------------------
// vtkTIFFReader methods
// ----------------------------------------------------------------------------

function vtkTIFFReader(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkTIFFReader');

// Create default dataAccessHelper if not available
if (!model.dataAccessHelper) {
model.dataAccessHelper = DataAccessHelper.get('http');
}

// Internal method to fetch Array
function fetchData(url, option = {}) {
const { compression, progressCallback } = model;
return model.dataAccessHelper.fetchBinary(url, {
compression,
progressCallback,
});
}

// Set DataSet url
publicAPI.setUrl = (url, option = { binary: true }) => {
model.url = url;

// Remove the file in the URL
const path = url.split('/');
path.pop();
model.baseURL = path.join('/');

model.compression = option.compression;

// Fetch metadata
return publicAPI.loadData({
progressCallback: option.progressCallback,
});
};

// Fetch the actual data arrays
publicAPI.loadData = (option = {}) => {
const promise = fetchData(model.url, option);
promise.then(publicAPI.parse);
return promise;
};

publicAPI.parse = (content) => {
publicAPI.parseAsArrayBuffer(content);
};

publicAPI.parseAsArrayBuffer = (content) => {
if (!content) {
return;
}

// Read Header
const ifds = UTIF.decode(content);
UTIF.decodeImage(content, ifds[0]);
const data = UTIF.toRGBA8(ifds[0]);

const width = ifds[0].width;
const height = ifds[0].height;
const output = new Uint8Array(data.length);

if (model.flipY) {
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const srcIndex = (y * width + x) * 4;
const destIndex = ((height - y - 1) * width + x) * 4;

output[destIndex] = data[srcIndex]; // R
output[destIndex + 1] = data[srcIndex + 1]; // G
output[destIndex + 2] = data[srcIndex + 2]; // B
output[destIndex + 3] = data[srcIndex + 3]; // A
}
}
}

const dataExtent = [0, width - 1, 0, height - 1];
const dataSpacing = [1, 1, 1];

const imageData = vtkImageData.newInstance();
imageData.setDimensions(width, height, 1);
imageData.setExtent(dataExtent);
imageData.setSpacing(dataSpacing);

const dataArray = vtkDataArray.newInstance({
name: 'TIFFImage',
numberOfComponents: 4,
values: output,
});

imageData.getPointData().setScalars(dataArray);
model.output[0] = imageData;
};

publicAPI.requestData = (inData, outData) => {
publicAPI.parse(model.parseData);
};
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
flipY: true,
compression: null,
progressCallback: null,
};

// ----------------------------------------------------------------------------

export function extend(publicAPI, model, initialValues = {}) {
Object.assign(model, DEFAULT_VALUES, initialValues);

// Make this a VTK object
macro.obj(publicAPI, model);

// Also make it an algorithm with one input and one output
macro.algo(publicAPI, model, 0, 1);

macro.get(publicAPI, model, ['url', 'baseURL']);
macro.setGet(publicAPI, model, ['dataAccessHelper', 'flipY']);

// Object specific methods
vtkTIFFReader(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(extend, 'vtkTIFFReader');

// ----------------------------------------------------------------------------

export default { newInstance, extend };