圧縮

現行標準 — 最終更新

参加方法:
GitHub whatwg/compression (新しいissue, オープン中のissue)
Matrixでチャット
コミット:
GitHub whatwg/compression/commits
このコミット時点のスナップショット
@compressionapi
テスト:
web-platform-tests compression/ (進行中の作業)
翻訳 (参考訳):
简体中文
日本語
한국어

概要

この文書は、バイナリデータのストリームを圧縮および展開するためのJavaScript APIのセットを定義します。

1. はじめに

この節は参考情報です。

本仕様で定義されているAPIは、データストリームの圧縮および展開に使用されます。"deflate"、"deflate-raw"、"gzip"の各圧縮アルゴリズムをサポートしており、Web開発者に広く利用されています。

2. インフラストラクチャー

本仕様はInfraに依存しています。[INFRA]

チャンクとはデータの断片です。CompressionStreamおよびDecompressionStreamの場合、出力チャンクの型はUint8Arrayです。入力としては、任意のBufferSource 型を受け付けます。

ストリームは、順序付けられたチャンクの列を表します。ReadableStream およびWritableStream という用語はStreamsで定義されています。[STREAMS]

圧縮コンテキストとは、圧縮または展開アルゴリズムによって管理される内部状態のことです。圧縮コンテキストの内容は、使用するフォーマット・アルゴリズム・実装によって異なります。本仕様の観点からは、不透明なオブジェクトです。圧縮コンテキストは、最初は入力の最初のバイトを待ち受ける開始状態です。

3. 対応フォーマット

brotli

「Brotli 圧縮データフォーマット」 [RFC7932]

  • 実装は [RFC7932] 1.4節で説明されているとおり「準拠(compliant)」でなければなりません。

  • [RFC7932] 非準拠のブロックは CompressionStream によって作成されてはならず、 DecompressionStream にとってはエラーとなります。

deflate

「ZLIB 圧縮データフォーマット」 [RFC1950]

注: このフォーマットは HTTP Content-Encodings との一貫性のために "deflate" と呼ばれています。[RFC7230] 4.2.2節参照。

  • 実装は [RFC1950] 2.3節で説明されているとおり「準拠(compliant)」でなければなりません。

  • [RFC1950] で無効と記載されているフィールド値は、 CompressionStream によって作成されてはならず、 DecompressionStream にとってはエラーとなります。

  • CMF フィールドの CM (圧縮方式) 部の唯一の有効値は 8 です。

  • FDICT フラグはこれらのAPIでサポートされておらず、設定されている場合はストリームはエラーとなります。

  • FLEVEL フラグは DecompressionStream により無視されます。

  • ADLER32 チェックサムが正しくない場合、DecompressionStream はエラーとなります。

  • ADLER32 チェックサム以降に入力データが存在する場合はエラーです。

deflate-raw

「DEFLATE アルゴリズム」 [RFC1951]

  • 実装は [RFC1951] 1.4節で説明されているとおり「準拠(compliant)」でなければなりません。

  • [RFC1951] 非準拠のブロックは CompressionStream によって作成されてはならず、 DecompressionStream にとってはエラーとなります。

  • BFINAL フラグで示される最終ブロック以降に追加の入力データがある場合はエラーです。

gzip

「GZIP ファイルフォーマット」 [RFC1952]

  • 実装は [RFC1952] 2.3.1.2節で説明されているとおり「準拠(compliant)」でなければなりません。

  • [RFC1952] で無効と記載されているフィールド値は CompressionStream によって作成されてはならず、 DecompressionStream にとってはエラーとなります。

  • CM (圧縮方法) フィールドの唯一の有効値は 8 です。

  • FTEXT フラグは DecompressionStream により無視されなければなりません。

  • FHCRC フィールドが存在し、それが正しくない場合はエラーとなります。

  • 全ての FEXTRA, FNAME, FCOMMENT フィールドの内容は DecompressionStream によって、正しく終了していることを検証する以外は無視しなければなりません。

  • MTIME, XFL, OS 各フィールドの内容は DecompressionStream により無視されなければなりません。

  • CRC32 または ISIZE が展開データと一致しない場合はエラーです。

  • gzip ストリームには「メンバー」はひとつしか含まれてはなりません。

  • 「メンバー」末尾以降に追加の入力データが存在する場合はエラーです。

4. インターフェース CompressionStream

enum CompressionFormat {
  "brotli",
  "deflate",
  "deflate-raw",
  "gzip",
};

[Exposed=*]
interface CompressionStream {
  constructor(CompressionFormat format);
};
CompressionStream includes GenericTransformStream;

CompressionStream には、関連付けられた format(フォーマット) および compression context(圧縮コンテキスト) context(コンテキスト)があります。

new CompressionStream(format) の手順は以下の通りです:
  1. もし formatCompressionStream でサポートされていなければ、 TypeError をスローする。

  2. thisformatformat に設定する。

  3. transformAlgorithm を、chunk 引数を受け取り compress and enqueue a chunk(圧縮してチャンクをエンキュー)アルゴリズムを thischunk で実行するアルゴリズムとする。

  4. flushAlgorithm を、引数なしで compress flush and enqueue(圧縮してフラッシュ・エンキュー) アルゴリズムを this で実行するアルゴリズムとする。

  5. thistransformnew TransformStream に設定する。

  6. セットアップthistransform に対して、 transformAlgorithmtransformAlgorithm に、 flushAlgorithmflushAlgorithm でセットする。

compress and enqueue a chunk(圧縮してチャンクをエンキュー) アルゴリズムは、 CompressionStream オブジェクト cschunk を受けて次の手順を実行する:
  1. もし chunkBufferSource 型でなければ、TypeError をスローする。

  2. buffercsformatcontextchunk を圧縮した結果とする。

  3. もし buffer が空なら、returnする。

  4. arraysbuffer をひとつまたは複数の非空の部分に分割し、それぞれを Uint8Array に変換した結果とする。

  5. Uint8Array arrayarrays から取り出して enqueue(エンキュー) し、 cstransform に入れる。

compress flush and enqueue(圧縮してフラッシュ・エンキュー) アルゴリズムは、入力 ReadableStream オブジェクトからデータの終端を扱うもので、CompressionStream オブジェクト cs を受けて次の手順を実行する:
  1. buffer を、空入力を csformatcontext で フィニッシュフラグ付きで圧縮した結果とする。

  2. もし buffer が空なら、returnする。

  3. arraysbuffer をひとつまたは複数の非空の部分に分割し、それぞれを Uint8Array に変換した結果とする。

  4. Uint8Array arrayarrays から取り出して enqueue(エンキュー) し、 cstransform に入れる。

5. インターフェース DecompressionStream

[Exposed=*]
interface DecompressionStream {
  constructor(CompressionFormat format);
};
DecompressionStream includes GenericTransformStream;

DecompressionStream には、関連付けられた format(フォーマット) および compression context(圧縮コンテキスト) context(コンテキスト)があります。

new DecompressionStream(format) の手順は以下の通りです:
  1. もし formatDecompressionStream でサポートされていなければ、 TypeError をスローする。

  2. thisformatformat に設定する。

  3. transformAlgorithm を、chunk 引数を受け取り decompress and enqueue a chunk(展開してチャンクをエンキュー)アルゴリズムを thischunk で実行するアルゴリズムとする。

  4. flushAlgorithm を、引数なしで decompress flush and enqueue(展開してフラッシュ・エンキュー) アルゴリズムを this で実行するアルゴリズムとする。

  5. thistransformnew TransformStream に設定する。

  6. セットアップthistransform に対して、 transformAlgorithmtransformAlgorithm に、 flushAlgorithmflushAlgorithm でセットする。

decompress and enqueue a chunk(展開してチャンクをエンキュー) アルゴリズムは、 DecompressionStream オブジェクト dschunk を受けて次の手順を実行する:
  1. もし chunkBufferSource 型でなければ、TypeError をスローする。

  2. bufferdsformatcontextchunk を展開(デコード)した結果とする。もしこれによりエラーが発生した場合、TypeError をスローする。

  3. もし buffer が空なら、returnする。

  4. arraysbuffer をひとつまたは複数の非空の部分に分割し、それぞれを Uint8Array に変換した結果とする。

  5. Uint8Array arrayarrays から取り出して enqueue(エンキュー) し、 dstransform に入れる。

  6. 圧縮入力の終端に到達し、かつ dscontextchunk を完全に消費していない場合は、TypeError をスローする。

decompress flush and enqueue(展開してフラッシュ・エンキュー) アルゴリズムは、入力 ReadableStream オブジェクトからデータの終端を扱うもので、DecompressionStream オブジェクト ds を受けて次の手順を実行する:
  1. buffer を、空入力を dsformatcontext で フィニッシュフラグ付きで展開(デコード)した結果とする。

  2. もし buffer が空でない場合:

    1. arraysbuffer をひとつまたは複数の非空の部分に分割し、それぞれを Uint8Array に変換した結果とする。

    2. Uint8Array arrayarrays から取り出して enqueue(エンキュー) し、 dstransform に入れる。

  3. 圧縮入力の終端にまだ到達していない場合は、TypeError をスローする。

6. プライバシーおよびセキュリティの考慮事項

このAPIはWebプラットフォームに新たな権限を追加しません。

ただし、攻撃者がデータの長さを取得できる場合、Web開発者は注意する必要があります。その場合、データの内容を推測される可能性があります。

7.

7.1. ストリームをGzip圧縮する

const compressedReadableStream
    = inputReadableStream.pipeThrough(new CompressionStream('gzip'));

7.2. ArrayBufferをDeflate圧縮してUint8Arrayに変換

async function compressArrayBuffer(input) {
  const cs = new CompressionStream('deflate');

  const writer = cs.writable.getWriter();
  writer.write(input);
  writer.close();

  const output = [];
  let totalSize = 0;
  for (const chunk of cs.readable) {
    output.push(value);
    totalSize += value.byteLength;
  }

  const concatenated = new Uint8Array(totalSize);
  let offset = 0;
  for (const array of output) {
    concatenated.set(array, offset);
    offset += array.byteLength;
  }

  return concatenated;
}

7.3. BlobをGzip展開してBlobに変換

function decompressBlob(blob) {
  const ds = new DecompressionStream('gzip');
  const decompressionStream = blob.stream().pipeThrough(ds);
  return new Response(decompressionStream).blob();
}

謝辞

Canon Mukai、Domenic Denicola、そして平野豊に感謝します。

この標準はAdam Rice(Googlericea@chromium.org)によって執筆されました。

知的財産権

この現行標準はもともとW3C WICGで開発され、W3Cソフトウェアおよびドキュメントライセンスの下で公開されていました。

Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). この作業はクリエイティブ・コモンズ 表示 4.0 国際 ライセンスの下で提供されます。その一部がソースコードに組み込まれている場合、ソースコード部分は代わりにBSD 3-Clause Licenseの下でライセンスされます。

これは現行標準です。 特許審査バージョンに関心のある方は、 現行標準審査ドラフトを参照してください。

索引

本仕様で定義されている用語

他仕様で定義されている用語

参考文献

規範的参考文献

[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard(インフラ標準). Living Standard(リビングスタンダード). URL: https://infra.spec.whatwg.org/
[RFC1950]
P. Deutsch; J-L. Gailly. ZLIB圧縮データフォーマット仕様 バージョン3.3. 1996年5月. Informational. URL: https://www.rfc-editor.org/rfc/rfc1950
[RFC1951]
P. Deutsch. DEFLATE圧縮データフォーマット仕様 バージョン1.3. 1996年5月. Informational. URL: https://www.rfc-editor.org/rfc/rfc1951
[RFC1952]
P. Deutsch. GZIPファイルフォーマット仕様 バージョン4.3. 1996年5月. Informational. URL: https://www.rfc-editor.org/rfc/rfc1952
[RFC7932]
J. Alakuijala; Z. Szabadka. Brotli圧縮データフォーマット. 2016年7月. Informational. URL: https://www.rfc-editor.org/rfc/rfc7932
[STREAMS]
Adam Rice; et al. Streams Standard(ストリーム標準). Living Standard(リビングスタンダード). URL: https://streams.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard(Web IDL標準). Living Standard(リビングスタンダード). URL: https://webidl.spec.whatwg.org/

非規範的参考文献<< /span>

[RFC7230]
R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing. 2014年6月. Proposed Standard. URL: https://httpwg.org/specs/rfc7230.html

IDL索引

enum CompressionFormat {
  "brotli",
  "deflate",
  "deflate-raw",
  "gzip",
};

[Exposed=*]
interface CompressionStream {
  constructor(CompressionFormat format);
};
CompressionStream includes GenericTransformStream;

[Exposed=*]
interface DecompressionStream {
  constructor(CompressionFormat format);
};
DecompressionStream includes GenericTransformStream;

MDN

CompressionStream/CompressionStream

In all current engines.

Firefox113+Safari16.4+Chrome80+
Opera?Edge80+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js17.0.0+
MDN

CompressionStream

In all current engines.

Firefox113+Safari16.4+Chrome80+
Opera?Edge80+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js18.0.0+
MDN

DecompressionStream/DecompressionStream

In all current engines.

Firefox113+Safari16.4+Chrome80+
Opera?Edge80+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js17.0.0+
MDN

DecompressionStream

In all current engines.

Firefox113+Safari16.4+Chrome80+
Opera?Edge80+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js18.0.0+