Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 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 (スペクトル選択の開始)、SeAh (高次ビット)、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より):

| バイト数 | 説明 ```