ガイド

PNGが開かない:チャンク、CRC、そして復元できるもの

PNGは、自分自身の損傷について並外れて正直です。内部のすべてのブロックがチェックサムを持っているため、このフォーマットは何が起きたのかを正確に教えてくれることが多く、ときには元に戻す方法まで正確に示してくれます。しかし同じ構造が、はっきりとした一線も引きます。ある種の破損はきれいで確定的に直せますが、別の種類の破損は画像の下半分を永久に道連れにしてしまうのです。

PNGはどう組み立てられているか

PNGは8バイトのシグネチャで始まります。これは固定の指紋 であり、どんなプログラムでもそのファイルが本当にPNGであることを確認でき ます。それ以降はすべて一連のチャンクで、各チャンクは きちんと整理された小さなパッケージです——長さ、4文字のタイプ、データ そのもの、そして4バイトのチェックサム。

3種類のチャンクが画像全体を担います。IHDRが最初に来て、 要となる情報を保存します——幅、高さ、ビット深度、そしてカラータイプ。IDATは圧縮された画像データを保持し、ときには連続する 複数のIDATチャンクに分割されます。IENDは、ファイルが 完結していることを示す小さな終端マーカーです。IDATチャンクの内部では、 ピクセルがdeflate——ZIPが使うのと同じアルゴリズム——で圧縮され、画像の 一番上の行から一番下まで、ひとつの連続したストリームになっています。

PNGを先頭から末尾まで:シグネチャ、寸法を持つヘッダー、圧縮された画像データ、そして終端マーカー。

PNGを特別なものにしている細部は、すべてのチャンクに付くチェックサムです。 それはチャンクのタイプとデータから計算されるCRC-32であり、このフォーマット を絶えず自己監査するものへと変えています。だからこそPNGは、ほとんどの フォーマットには到底できない精度で、自分自身の損傷を指し示せるのです。

PNGが平然と受け流せる損傷

各チャンクが自己検査と自己記述を備えているため、PNGの損傷のまるごと一つ のカテゴリーには、きれいで確定的な修正法があります。正しい答えは推測する ものではなく、知りうるものなのです。

チェックサムは誤り、データは正しい

最も穏やかなケースです。チャンクのデータは正常なのに、保存されている CRCがもはや一致せず、厳格なデコーダーがファイルを拒否します。データから CRCを再計算して書き戻せば、ファイルは損失ゼロで再び有効になります。 誤っていたのはチェックサムだけだったのです。

ゼロ化された、または誤った寸法

IHDR内の幅や高さがゼロ化されたりかき乱されたりすると、どのデコーダーも キャンバスを用意できず、ファイルは開きません。しかしIHDRは、寸法が正しかった 当時に計算された自分自身のCRCを持っています。これにより、修復ツールは答え を総当たりで求められます——幅と高さの候補値を試し、そのたびにチェックサム を再計算し、保存されているCRCと一致したところで止める。元の寸法は計算から そのまま導き出され、推測は一切要りません。

転送中に壊された改行

定番の例です。改行コードを「気を利かせて」変換してしまうシステムを通った PNG、テキストモードの古いFTPクライアント、あるいはファイルをテキストとして 書き直したスクリプト。それはすべてのキャリッジリターンとラインフィードの組 を単独のラインフィードに、あるいはその逆に置き換え、ファイル全体のバイトを 破損させます。PNGのシグネチャは、まさにこれを検出するために設計されており、 この改変が一貫した可逆的な置換であるとき、その変換は取り消され、元のバイト を復元できます。

切り詰め:上部の行は戻ってくる

切り詰めは、PNGが壊れる最もよくある原因です——80パーセントで止まった ダウンロード、ドライブが抜かれて中断されたコピー、書き込みの途中で クラッシュしたプログラムが保存したファイル。ファイルの前半は無傷で、 末尾は単に存在せず、たいていはIENDマーカーも含めて失われています。 だからこそ、これほど多くのビューアがファイルは不完全だと訴えるのです。

切り詰められたPNG:ヘッダーと画像データの上部は生き残り、ストリームの残りと終端マーカーは届かなかった。

画像は上から下へ書き込まれるため、切り詰められたPNGは絵の上部として サルベージできます——データが終わる地点までの本物のピクセルです。修復は、 デコーダーがファイルを受け入れて生き残った部分を描けるよう、有効な終端を 書き直します。切断より下の行は損傷しているのではなく、存在しないのであり、 だから戻すことはできません。これは正直な部分結果であり、写真修復の側で切り詰められたJPEGが返すのと同じ形の結果です。

ストリーム途中の損傷:なぜ下の行が失われるのか

末尾ではなくIDATデータの途中に起きる損傷は難しいケースであり、その理由は deflateにあります。deflateは画像を、各部分がそれ以前の部分に依存するひとつ の連続したストリームとして圧縮します。再同期のための周期的なマーカーを持た ないため、デコーダーはひとたび破損したバイトにぶつかると、筋道を見失い、 それを取り戻せません。損傷より後のすべてがノイズとしてデコードされます。

実際には、これは途中の1つの不良バイトが、たった1行だけでなく、その下の すべての行を奪いうるということです。絵は被害地点より上ではきれいで、その下 ではゴミになります。修復は、損傷より前にデコードできた行はなおもサルベージ でき、それは確かに得るに値するものですが、破断を越えてストリームを縫い合わせ 直すことはできません。これを、インデックスをデータとは別に保存するフォーマット と比べてみてください。そちらではインデックスを再構築すれば全体を救い出せる ことがあります。PNGはピクセルを分割できないひとつのdeflateストリームに保持 しているため、ストリーム途中の傷は切断より下では永久に残ります。

復元できるもの、ひとつの正直なリストで

壊れたPNGを次のいずれかに分類すれば、労力を費やす前に見通しがわかります。

  • チェックサムの不一致、データは無傷。 確定的な修正、 損失なし。CRCを再計算すればファイルは再び有効になります。
  • ゼロ化された、またはかき乱された寸法。 ほとんどの場合、 確定的な修正。保存されたIHDRのチェックサムが元のサイズを明かします。
  • 転送による改行の破損。 置換が一貫していれば可逆。 変換を取り消し、バイトを復元します。
  • 切り詰められたファイル。 部分的。画像の上部は戻り ますが、欠けた末尾は戻りません。
  • ストリーム途中のIDAT破損。 よくても部分的。損傷より 上はきれい、下は失われます。deflateが再同期できないからです。
  • ゼロバイト、あるいはすべてゼロ。 修復のケースでは ありません。ファイルに再構築すべき画像がそもそもありません。それは 復旧(リカバリ)の問題です。

PNG修復は、修復ツール一覧にある他のフォーマット用 ツールと並んでいます。あなたのファイルがどの区分に入ろうと、良いツールは グレーの行を取り戻すと約束するのではなく、それについての真実を伝えます。

FAQ

なぜPNGが開かないのか?

たいていは次の3つのうちのどれかです。先頭にある8バイトのシグネチャが壊れていて、ビューアがそもそもファイルをPNGだと認識できない。画像の寸法を保持するヘッダーチャンク(IHDR)が誤っていたりゼロで埋められていたりして、デコーダーがキャンバスを用意できない。あるいは、圧縮された画像データが途中で切り詰められたり破損したりしている。最初の2つは、PNGがすべてのチャンクにチェックサムを保存しているため、確定的に直せることが多いです。3つ目は正直な限界が始まる場所です。ファイルに存在しなかった画像の行は、どうやっても取り戻せません。

PNGのCRCエラーとは何を意味するのか?

PNGのすべてのチャンクは、そのチャンクのタイプとデータから計算された4バイトのCRC-32チェックサムで終わります。デコーダーがチェックサムを再計算し、保存されている値と一致しない場合、CRCエラーが報告されます。これは、ファイルが書き込まれてから、そのチャンクのバイトが変化したことを意味します。もしチェックサム自体だけが誤っていてデータは正常なら、それを再計算するだけでファイルは完全に直ります。データが変化していた場合、CRCは警告を出すという本来の役目を果たしているのであり、画像がどれだけ復元できるかは、どのチャンクが被害を受けたかによります。

切り詰められたPNGは復元できるか?

部分的に、しかも上部だけです。PNGは画像をdeflateで圧縮し、行を上から下へと書き込みます。そのため、途中で切れたファイルは、データが終わる地点まではきれいにデコードでき、そこで止まります。画像の上部が本物のピクセルとして戻ってきます。切断より下の行は、そもそもファイルに存在しなかったので、どんなツールでも復元できません。修復された切り詰めPNGは正直な部分結果です。バイトが続くところまでの、あなたの本物の画像です。

なぜPNGの下部が欠けていたり乱れていたりするのか?

PNGが使う圧縮方式であるdeflateが、損傷後に再同期する手段を持たない連続的なストリームだからです。破損が末尾ではなく画像データの途中に起きると、デコーダーはそのバイトで筋道を見失い、それ以降のすべてが、被害を受けた1行だけでなくノイズとしてデコードされます。だからこそ、ストリーム途中の損傷は通常、被害地点より下のすべての行を奪う一方で、きれいな切り詰めなら少なくとも上部は無傷で残るのです。

下半分がグレーで開く写真には、JPEGの世界に近い親戚がいます:JPEGの半分がグレーになる理由