型指定された配列を使用したバイナリ データの操作

本記事は、マイクロソフト本社の IE チームのブログ から記事を抜粋し、翻訳したものです。 

【元記事】Working with Binary Data using Typed Arrays 2011/12/2 8:03 AM

HTML5 には、メディアやリアルタイム通信を活用して既存の枠を超えたユーザー エクスペリエンスを実現する、多くの API が用意されています。その多くは、MP3 オーディオや PNG 画像、MP4 動画などのバイナリ ファイル形式を使用します。

バイナリ ファイル形式の使用は、使用帯域幅を削減し、期待されるパフォーマンスを実現し、既存のファイル形式との相互運用性を確保するという点で重要です。

しかしながら最近まで Web 開発者はこれらのバイナリ ファイルやその他のカスタム バイナリ ファイルの内容に直接アクセスできませんでした。

この記事では、Web 開発者が JavaScript の 型指定された配列 API を使用してバイナリの障壁を取り払う方法について説明し、その使用法を Test Drive デモの Binary File Inspector ( 英語 ) で実証します。

型指定された配列は IE10 Platform Preview 4 で提供されています。これを使用すると、Web アプリケーションで幅広い種類のバイナリ ファイル形式が使用可能になると共に、ブラウザーで既にサポートされているファイルのバイナリ コンテンツを直接操作できるようになります。

型指定された配列のサポートは、JavaScript、XMLHttpRequestFile API、および Stream API など IE10 全体にわたって追加されています。

Binary File Inspector

Test Drive デモの Binary File Inspector ( 英語 ) は、これらの新機能の組み合わせにより可能になる新しい操作をいくつか示しています。

たとえば、楽曲ファイルの ID3 ヘッダーや動画ファイルのバイト データを確認する方法や、PCX 画像ファイル形式などの新しく追加されたファイル形式を JavaScript や Canvas を使用してブラウザーでサポートする方法を紹介しています。

Screen shot of the Binary File Inspector Test Drive demo.

上の例では、MP4 動画が <video> 要素を用いて左側にレンダリングされています。また、右側にはファイルのバイナリ コンテンツが、HEX 形式と対応する ASCII 文字の両方で表示されています。この例では、MPEG ファイル形式の特徴的な要素、たとえば “ftyp” (ここでは “mp4”) などを確認できます。

型指定された配列と ArrayBuffer

型指定された配列は、特定の型を通じてデータのバイナリ コンテンツを確認する方法を提供します。

たとえば、生のバイナリ データを 1 バイトずつ見たい場合は、Uint8Array を使用できます (Uint8 は 8 ビットの符号なし整数値、すなわち一般的な “バイト” を表します)。生のデータを浮動小数点数の配列として読み込みたい場合は、Float32Array を使用します (Float32 は 32 ビットの IEE754 浮動小数点値、すなわち一般な “浮動小数点数” を表します)。以下の型がサポートされています。

配列の種類

要素のサイズと説明

Int8Array

8 ビット符号付き整数

Uint8Array

8 ビット符号なし整数

Int16Array

16 ビット符号付き整数

Uint16Array

16 ビット符号なし整数

Int23Array

32 ビット符号付き整数

Uint32Array

32 ビット符号なし整数

Float32Array

32 ビット IEEE754 浮動小数点数

Float64Array

64 ビット IEEE754 浮動小数点数

各配列の種類はそれぞれ ArrayBuffer に対するビューとなります。ArrayBuffer はバイナリ データへの参照を示しますが、データを直接操作することはできません。ArrayBuffer の型指定された配列ビューを作成すると、バイナリ コンテンツにアクセスして読み書きできるようになります。

下の例は、新しい ArrayBuffer をゼロから作成して、コンテンツを異なる方法で解釈しています。

// 8 バイトのバッファーを作成

var buffer = new ArrayBuffer(8);

 

// Uint8 の配列として表示し、各バイトに 0x05 を挿入

var uint8s = new Uint8Array(buffer);

for (var i = 0; i < 8; i++) {

uint8s[i] = 5; // 各バイトに 0x05 を指定

}

 

// 生成された配列を検証

uint8s[0] === 5; // true – 各バイトの値が 5

uint8s.byteLength === 8; // true - Uint8 が 8 個ある

 

// 同じバッファーを、Uint32 の配列として表示

var uint32s = new Uint32Array(buffer);

 

// 同じバイト データが、異なる方法で解釈される

uint32s[0] === 84215045 // true - 0x05050505 == 84215045

 

このように、型指定された配列は、バイト単位成要素からの浮動小数点値の作成や、効率化や相互運用性のためにデータの特別なレイアウトを必要とするデータ構造体の作成といったタスクに使用できます。

型指定された配列を使用してバイナリ ファイル形式を読み込む

型指定された配列が可能にする新しい重要な処理として、ブラウザーが標準でサポートしていないカスタム バイナリ ファイル形式のコンテンツの読み込みおよびレンダリングが挙げられます。上で紹介したさまざまな種類の配列のほかに、型指定された配列には DataView オブジェクトが用意されており、これを使用して ArrayBuffer の内容を構造化されていない方法で読み書きできます。これは異種データが混在する新しいファイル形式の読み込みに最適です。

Binary File Inspector デモでは、DataView を使用して PCX ファイル形式を読み込み、<canvas> 要素を使用してレンダリングしています。このデモがファイル ヘッダーの読み込みに使用しているマークアップを若干簡略化したものを次に示します。ヘッダーには幅、高さ、DPI、色深度のビット/ピクセルなどが含まれます。

var buffer = getPCXFileContents();

var reader = new DataView(buffer);

 

// PCX ファイルのヘッダーを読み込む

var header = {}

 

// 最初のセクションはシングルバイト値

header.manufacturer = reader.getUint8(0);

header.version = reader.getUint8(1);

header.encoding = reader.getUint8(2);

header.bitsPerPixel = reader.getUint8(3);

 

// 次のセクションは Int16 値 (リトル エンディアン)

header.xmin = reader.getInt16(4, true);

header.ymin = reader.getInt16(6, true);

header.xmax = reader.getInt16(8, true);

header.ymax = reader.getInt16(10, true);

header.hdpi = reader.getInt16(12, true);

header.vdpi = reader.getInt16(14, true);

 

上記のようなコードを使用して、カスタム画像形式、新しい動画ファイル形式、ドメイン固有の地図データ形式など、幅広い種類の新しいデータ形式のレンダリングをブラウザーでサポートできるようになります。

XHR と File API でバイナリ データを取得する

型指定された配列 API を使用してファイルのコンテンツを操作するには、まずブラウザー API を使用して生のデータにアクセスする必要があります。サーバーからファイルにアクセスできるように、XMLHttpRequest API が拡張され、各種 “responseType” をサポートするようになっています。

たとえば、“arraybuffer” responseType によって、要求したサーバー リソースのコンテンツを ArrayBuffer オブジェクトとして JavaScript で使用できます。

この他にも、“blob”、“text”、および “document” の responseType がサポートされています。

function getServerFileToArrayBufffer(url, successCallback) {

// XDR オブジェクトを作成

var xhr = new XMLHttpRequest();

 

xhr.onreadystatechange = function () {

if (xhr.readyState == xhr.DONE) {

if (xhr.status == 200 && xhr.response) {

// 'response' プロパティが ArrayBuffer を返す

successCallback(xhr.response);

} else {

alert("Failed to download:" + xhr.status + " " + xhr.statusText);

}

}

}

 

// 指定された URL へのリクエストを作成

xhr.open("GET", url, true);

 

// ArrayBuffer オブジェクトでの応答を得るため、responseType を 'arraybuffer' に設定

xhr.responseType = "arraybuffer";

 

xhr.send();

}

 

多くの場合、ファイルはユーザーが提供します。たとえば、Web メール アプリケーションで使用される電子メールの添付ファイルなどです。

File API を使用することで、Web 開発者は <input> 要素やドラッグ アンド ドロップなどを経由して、BLOB またはファイル形式で提供されたファイルの内容を読み込むことができます。

FileReader オブジェクトを使用してファイルの内容を ArrayBuffer に読み込むことができます。このオブジェクトは、XHR オブジェクトと同様に、ディスクからの読み込みによってユーザー インターフェイスの応答を妨げないよう非同期で処理を行います。

function readFileToArrayBuffer(file, successCallback) {

// FileReader を作成

var reader = new FileReader();

 

// 'load' イベントと 'error' イベントに登録

reader.onload = function () {

// 'result' プロパティが readAsArrayBuffer 用の ArrayBuffer を返す

var buffer = reader.result;

successCallback(buffer);

}

 

reader.onerror = function (evt) {

// エラーの理由を示すエラー コードを記述

if (evt.target.error.code == evt.target.error.NOT_READABLE_ERR) {

alert("Failed to read file: " + file.name);

}

}

 

// ArrayBuffer へのファイル内容の読み込みを開始

reader.readAsArrayBuffer(file);

}

まとめ

バイナリ データは Web ブラウザーで多用されています。

IE10 の型指定された配列、XHR2、および File API のサポートにより、Web アプリケーションはバイナリ データを直接操作できるようになります。バイト単位のデータ操作、新たなバイナリ データ形式のレンダリング、および既存のメディア ファイル形式からのデータの抽出が可能になります。Test Drive デモの Binary File Inspector ( 英語 ) にアクセスして、型指定された配列を IE10 で動作させてみてください。

—JavaScript プログラム マネージャー Luke Hoban