退行性JPEG: プログレッシブJPEGスキャンによるアニメーションの作成
退行性JPEG: プログレッシブJPEGスキャンによるアニメーションの作成
プログレッシブJPEGスキャンをアニメーションに悪用する
プログレッシブJPEGの構造を操作することで、読み込み中に異なる画像へと切り替わる単一の画像ファイルを作成することが可能です。これは、プログレッシブJPEGが低周波成分を最初に保存するように設計されており、ブラウザが低解像度のプレビューを表示し、データが届くにつれて詳細が洗練される仕組みを利用しています。複数の画像を連結し、特定のマーカーを削除することで、開発者はデコーダーに、以前にレンダリングされたデータを新しい画像の内容で上書きさせる強制的な動作を引き起こすことができます。
プログレッシブJPEGの仕組み
標準的なプログレッシブJPEGは、圧縮データを複数の「スキャン」に分割し、各スキャンにはヘッダーが付与されます。これらのスキャンにより、ダウンロード中に画像が上から下へと途切れるのではなく、低解像度で表示されるようになります。
スキャンの構造
典型的なスキャンヘッダーには以下が含まれます:
- Start of Scan (SOS) Marker:
FF DA - Length Field: スキャンのサイズを示すビッグエンディアンの値。
- Channel Information: チャネル数(通常は YCbCr)と、それに関連付けられた Huffman テーブルのインデックス。
- Spectral Range: 開始および終了の離散コサイン変換 (DCT) ビン。 例えば、DC (0) ビンのみを含むスキャンは、最も低い周波数の成分を提供します。
- Precision: 詳細度(例:半精度または全精度)。
色空間と輝度
JPEGは RGB ではなく YCbCr 色空間を使用します。人間の目は色よりも明るさに敏感であるため、輝度 (Y) が優先されます。色差 (Cb および Cr) は、より低い解像度(半解像度/4分の1ピクセル数)で保存できるため、完全な色差データは、輝度データよりも少ないスペースを占めることが一般的です。
「退行性」JPEGの実装
コンテンツが変化する画像を作成するために、著者は同じ解像度の複数の画像を連結し、Start-of-Image (SOI)、Start-of-Frame (SOF)、および End-of-Image (EOI) マーカーをフィルタリングして削除しました。
デコーダーの制限を克服する
ほとんどのブラウザのデコーダーは、「zip bomb」スタイルのリソース枯渇を防ぐために、スキャンの数を制限しています。プログレッシブJPEGを単純に連結すると、多くの場合、約9フレーム後に停止してしまいます。
フレーム数を増やす(Chrome では最大 90 フレームまで)ために、著者は DC-only scans を使用してフレームを最適化しました。プログレッシブモードでは、1つのスキャンに AC (ビン 0 より大きい値) と DC (ビン 0) のデータを同時に含めることはできません。単一の DC-only スキャンのみで構成されるフレームを作成することで、著者は2つの目標を達成しました:
- フレーム数の増加: 1フレームあたりのスキャン数を減らすことで、デコーダーの制限内に収まるより多くのフレームを格納できます。
- ゴースト現象の排除: AC スキャンは既存のデータを洗練させるように設計されているため、DC のみのスキャンを使用することで、新しいフレームが前のフレームと混ざり合うのを防ぐことができます。
生成方法
DC-only フレームは、Y, Cb, および Cr チャネルの DC ビンのみを含むスキャン構成を指定することで、jpegtran を使用して生成できます:
cat > frame.scans << EOF
# DC only scan: 0,1,2:0-0,0,0; # and nothing else
EOF
jpegtran -scans frame.scans -outfile out.jpg in.jpg
実用的な制限とブラウザの挙動動向
JPEG フォーマットにはタイミング情報が含まれていないため、これらの「アニメーション」の再生速度は、ネットワークのダウンロード速度に完全に依存します。
ブラウザの互換性
Chrome: 約 90 フレームまでレンダリングし、その後停止します。
Firefox: 一般的に Chrome よりも多くのスキャン数に対して忍耐強いです。
Safari: 画像が完全にダウンロードされるまでその場でフリーズし、エフェクトが打ち消されると報告されています。
タイミング制御のための潜在的な回避策
コミュニティの議論では、制御された再生をシミュレートするいくつかの方法が示唆されています:
- Server-side Timing: ウェブサーバーが、クライアントに対してタイミングを合わせたチャンク(分割データ)で画像データを送信します。
- Service Workers: Service Worker を使用して、スキャンの配信を制御するために、低速な接続をエミュレートします。
コミュニティによる技術的洞察
コミュニティの専門家は、プログレッシブ JPEG は知覚的なロード時間を短わせるのに有益ですが、デコーディングのオーバーヘッドを導入する可能性があると指摘しています。あるユーザーは、JPEG Turbo や OpenGL を使用している場合、プログレッシブモードを有効にするとデコーディング速度が大幅に遅くなる可能性があると言及しており、これは、プログ覚性プログレッシブな構築による視覚的利点が、現代の高速ネットワーク環境では価値が低くなっていることを示唆しています。