IV. HEIF Reader JavaScript Implementation
This is a pre-built JavaScript port of the HEIF Reader library and API using Emscripten and asm.js. It can be used with an HEVC/H.265 decoder JavaScript implementation (such as libde265.JS)
All the JavaScript files can be found here
Please follow this link to see HEIF file examples that use the JavaScript implementation.
This section describes the usage of heif-api.js interface. The interface provides all the needed functions to read properties and items from a HEIF (*.heic) file. In addition, the documentation briefly describes other JavaScript files used in the HEIF web site to decode image data and display or animate it in many different layouts.
This javascript file provides HEIFReader object. User first creates a HEIFReader object giving file URL as construction parameter. After that user calls requestFileInfo(callback) function to request file information. FileInfo may be requested as follows:
HEIFReader reader = new HEIFReader(url);
reader.requestFileInfo(function(payload) {
if(payload.success !== true) {
console.error("Could not read file:", url);
} else {
var fileInfo = payload;
console.log("FileInfo contents:", fileInfo);
}
});
In case the file contains single images, rootLevelMetaBoxProperties item is present in the FileInfo. The example code below shows how rootLevelMetaBox master item ids can be requested using the API.
// META file containing still images
if (fileInfo.rootLevelMetaBoxProperties) {
var masterContextId = fileInfo.rootLevelMetaBoxProperties.contextId;
var masterItemIds = [];
var imageFeaturesMap = fileInfo.rootLevelMetaBoxProperties.imageFeaturesMap;
for (i in imageFeaturesMap) {
if (imageFeaturesMap.hasOwnProperty(i) && imageFeaturesMap[i].isMasterImage === true) {
masterItemIds.push(parseInt(i));
}
}
console.log("Master images in the file:", masterItemIds);
}
The next step is to retrieve hevc encoded bitstream data for a specific master image item. The item may have dependencies to other items that has to be resolved. Image data for all the master image items in the file can be requested as follows:
/** Request decoded image data for given item id's.
* @param {number} contextId Id of the context.
* @param {Array.<number>} itemIds Array of item id's to be decoded.
* @param {function} callback Callback function that receives the payload as a parameter. */
this.requestImageData = function (contextId, itemIds, callback) {
console.log(_name + ": REQUEST IMAGE DATA: " + itemIds);
if (itemIds.constructor !== Array) {
itemIds = [itemIds];
}
if (itemIds.length < 1) {
return;
}
var stream = new Uint8Array();
var decodeIds = [];
var dependencies = {};
var displayDependencies = {};
for (var i = 0; i < itemIds.length; i++) {
var refs = self._heifReader.getItemDecodeDependencies(contextId, itemIds[i]);
for (var j = 0; j < refs.length; j++) {
if (refs[j] !== itemIds[i]) {
// Add dependency data to the stream if the id is not already listed in dependencies
if(!(refs[j] in dependencies) && !(refs[j] in displayDependencies)) {
dependencies[refs[j]] = true;
stream = _appendBuffer(stream, new Uint8Array(self._heifReader.getItemDataWithDecoderParameters(contextId, refs[j])));
decodeIds.push(refs[j]);
}
} else {
// Item has itself as dependency => we want to display that item despite being a dependency
displayDependencies[refs[j]] = true;
}
}
}
// Add data of the actual items to the stream (that already contains dependency data)
for (i = 0; i < itemIds.length; i++) {
stream = _appendBuffer(stream, new Uint8Array(self._heifReader.getItemDataWithDecoderParameters(contextId, itemIds[i])));
decodeIds.push(itemIds[i]);
}
var payload = new Payload(true, [], 0, 0);
self._hevcDecoder.pushRequestContext(new RequestContext(callback, decodeIds, stream, dependencies, payload));
self._hevcDecoder.decode();
};
The stream
object contains the hevc encoded binary data retrieved by the getItemDataWithDecoderParameters()
call.
HevcDecoder, RequestContext and Payload objects are helper classes used in the HEIF website examples.
HevcDecoder decodes hevc encoded stream to RGBA image data.
Example sequence diagram is shown below: <TODO: Insert image>
The examples presented in the HEIF file format web site include the following JavaScript files to implement full HEIF file format support from parsing to rendering:
- heif-api.js
- described in the previous chapter.
- libde265.js
- HEVC/H.265 decoder implementation from https://github.com/strukturag/libde265 compiled to JavaScript.
- See https://github.com/strukturag/libde265.js
- hevc-decoder.js
- interface for using libde265.js H265 decoder.
- image-provider.js
- contains helper functions to use heif-api.js and hevc-decoder.js
- heif-extension.js
- walks through all the
<img>
and<video>
HTML elements and replaces them by HEIF canvas elements.
- walks through all the
The overall architecture for the examples is shown below <TODO: Insert image>