[インデックス 13597] ファイルの概要
このコミットは、Go言語の image/jpeg
パッケージにおいて、JPEGファイルのStart Of Scan (SOS) ヘッダーが正しく生成されるように修正するものです。特に、スペクトル選択の終了 (Se) バイトの値が、一部のJPEGデコーダで問題を引き起こす可能性があったため、その値を仕様に準拠するように変更しています。
コミット
commit 5f7bec693d3d383061586d6f29f4fea2648399a7
Author: Nigel Tao <nigeltao@golang.org>
Date: Wed Aug 8 09:57:09 2012 +1000
image/jpeg: send a correct Start Of Scan (SOS) header.
Section B.2.3 of http://www.w3.org/Graphics/JPEG/itu-t81.pdf discusses
the End of spectral selection (Se) byte.
Apparently many JPEG decoders ignore the Se byte (or let it through
with a warning), but some configurations reject them. For example,
http://download.blender.org/source/chest/blender_2.03_tree/jpeg/jcmaster.c
has these lines:
if (Ss != 0 || Se != DCTSIZE2-1 || Ah != 0 || Al != 0)
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);\n
Fixes #3916.
R=r
CC=golang-dev
https://golang.org/cl/6459052
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/5f7bec693d3d383061586d6f29f4fea2648399a7
元コミット内容
このコミットは、Go言語の image/jpeg
パッケージが生成するJPEG画像のStart Of Scan (SOS) ヘッダーが、一部のデコーダで正しく処理されない問題を修正します。具体的には、SOSヘッダー内の「スペクトル選択の終了 (Se)」バイトの値が、JPEGの仕様(ITU-T T.81, セクション B.2.3)に準拠していなかったため、一部の厳格なデコーダ(例: BlenderのJPEGライブラリ)が画像を拒否していました。この修正により、SOSヘッダーが仕様に沿った形式で出力されるようになり、より多くのJPEGデコーダとの互換性が向上します。
変更の背景
JPEG画像は、そのエンコード方式やヘッダー情報に厳密な仕様が存在します。Go言語の image/jpeg
パッケージは、JPEG画像を生成する際に、Start Of Scan (SOS) ヘッダーと呼ばれる重要な部分を書き出します。このSOSヘッダーには、画像データのスキャン方法に関する情報が含まれており、その中には「スペクトル選択の終了 (Se)」というバイトが含まれています。
従来のGoのJPEGエンコーダは、この Se
バイトに誤った値(または、仕様で規定された値ではない値)を設定していました。多くのJPEGデコーダは、この Se
バイトの値を寛容に解釈するか、警告を出すだけで処理を続行していました。しかし、一部の厳格なデコーダ、特にBlenderのソースコード(jcmaster.c
)に示されているような実装では、Ss
(スペクトル選択の開始)、Se
、Ah
(高次ビット)、Al
(低次ビット) の値が特定の条件を満たさない場合にエラーとして画像を拒否していました。
具体的には、Blenderのコードでは Se != DCTSIZE2-1
(ここで DCTSIZE2
は64) の場合にエラーを発生させていました。これは、シーケンシャルDCT(逐次式DCT)モードでエンコードされたJPEG画像の場合、Se
の値が 0x3f
(63) であるべきという仕様に準拠していない場合に問題となります。
この互換性の問題が、GoのIssue #3916として報告されました。このコミットは、この問題を解決し、Goで生成されたJPEG画像がより広範なJPEGデコーダで問題なく読み込めるようにするために行われました。
前提知識の解説
JPEG (Joint Photographic Experts Group)
JPEGは、静止画像を圧縮するための標準的な方法です。非可逆圧縮方式であり、画質とファイルサイズのバランスを取ることができます。JPEG画像は、複数の「マーカー」と呼ばれるセクションで構成されており、それぞれが画像データやエンコードに関するメタデータを含んでいます。
DCT (Discrete Cosine Transform)
離散コサイン変換。JPEG圧縮の主要なステップの一つで、画像を周波数領域に変換します。これにより、人間の視覚が感知しにくい高周波成分を効率的に破棄し、圧縮率を高めます。
SOS (Start Of Scan) マーカー
JPEGファイル内の重要なマーカーの一つで、実際の画像データ(スキャンデータ)が始まることを示します。SOSマーカーには、スキャンに含まれるコンポーネントの数、各コンポーネントのDC/ACエントロピー符号化テーブルの選択、そしてスペクトル選択の開始/終了、高次ビット/低次ビットに関する情報が含まれます。
スペクトル選択 (Spectral Selection)
JPEGのプログレッシブモード(段階的表示)で使用される概念です。画像データを複数のスキャンに分割し、各スキャンで特定の周波数範囲(スペクトル)のデータを送信することで、低解像度から高解像度へと徐々に画像を表示することができます。
- Ss (Start of spectral selection): スペクトル選択の開始。
- Se (End of spectral selection): スペクトル選択の終了。
高次ビット/低次ビット (Successive Approximation)
これもプログレッシブモードで使用される概念です。各スキャンで、DCT係数の高次ビットから低次ビットへと徐々にデータを送信することで、画像の品質を段階的に向上させることができます。
- Ah (Successive approximation bit high): 高次ビット。
- Al (Successive approximation bit low): 低次ビット。
シーケンシャルDCT (Sequential DCT)
JPEGの基本的なエンコードモードです。画像データは一度に完全にエンコードされ、プログレッシブモードのように段階的に表示されることはありません。シーケンシャルDCTの場合、スペクトル選択や高次ビット/低次ビットの概念は適用されません。そのため、SOSヘッダー内の Ss
, Se
, Ah
, Al
の値は特定の固定値である必要があります。
ITU-T T.81 (JPEG標準)
JPEGの国際標準規格です。このドキュメントには、JPEGファイルの構造、圧縮アルゴリズム、マーカーの定義などが詳細に記述されています。コミットメッセージで参照されている「Section B.2.3」は、SOSマーカー内の Ss
, Se
, Ah
, Al
バイトの定義と、シーケンシャルDCTモードにおけるそれらの値について説明しています。シーケンシャルDCTの場合、Ss
は0、Se
は63 (0x3f)、Ah
は0、Al
は0であるべきと規定されています。
技術的詳細
JPEGのSOS (Start Of Scan) マーカーは、画像データがどのようにエンコードされ、デコードされるかを示す重要な情報を含んでいます。SOSマーカーの構造は以下のようになります(ITU-T T.81, セクション B.2.3より):
| バイト数 | 説明 ```