掲載予定のサンプルソースコードは現在調整中です
環境情報
WindowsXP SP3
VisualStduio2005 SP1
本稿の対象者
自分でlibpngを利用したpng読込・書込処理を実装したいWindows(VisualStudio)ユーザー。足がかりになるための資料として活用してもらえることを目標に投稿しています。
必要最低限のライブラリのみ参考にしたいというのであれば、libpngの中の下記ディレクトリにWindows/VisualStudio向けにPngの読み込み・書き込み実装されているlibpngライセンスのソースコードがありますので、そちらを導入して微調整をするといいでしょう。
- libpng/contrib/visupng/PngFile.c
- libpng/contrib/visupng/PngFile.h
単純にC/C++でpngを手軽に読み込みたい場合はSDLやGDI+等の画像ライブラリを使用することをお勧めします。
導入
sourceforgeから最新版のlibpngとzlibをダウンロードしてください。
http://sourceforge.net/projects/libpng/files/
解凍後はlibpng-x.x.xとzlib-x.x.xはフォルダのバージョン名等をリネームして「libpng」「zlib」というフォルダ名で同レベルの階層に配置してください。
次に、libpng/projects/visualc71/libpng.slnを開いてください。VC6.0以前だと開けない場合がありますが、その場合は独自にプロジェクトを作成してコンパイル環境を構築するか、無料版のVSの最新版を利用してlibpng/projects/vstudio/vstudio.slnを利用してください。
後はビルド構成をDebug/Releaseに切り替えてリビルドすれば、libpngd.libとlibpng.libが生成されます。
プロジェクトで使用するにはプロジェクトに直接png.h,zlib.h,zconf.h等のヘッダファイルを取り込み、pragmaプリプロセッサかプロジェクトの依存ライブラリにlibpng.libをリンクしてください。詳細な手順は別サイトで画像付で詳しく書かれていると思いますので、そちらに任せます。
自力解決に向けてのアドバイス
libpng,zlib等の3rdparty製のライブラリの使用方法をネットで探して実装しようとしている人はネットに落ちていない問題が出ると、結構な確率で開発に行き詰ります。その時に状況を打破するためのアドバイスを一つ。
libpngのフォルダ内にはpng導入用のテストコードやマニュアルが用意されています。それを順に追っていくことで、そもそもlibpngの開発者たちがどのように使うことを想定しているかを知ることができます。
英語だから読めない?技術文書は文学作品と違い、形容詞の微妙なニュアンスがわからなくても理解することが可能です。
プログラマーという人種は白黒つけるのが職業病みたいなもので、誤訳が少なくなるようにわかりづらい文法、一般的でない慣用句はほぼ使用されません。そのため、ネット翻訳や辞書を使えばそれなりの精度で訳してもくれます。
文書を完全に訳せなくとも、開発者たちが何を言いたいのかわかるレベルさえあれば理解可能です。
我々には言語や文化の差を埋めてくれるプログラム言語という共通言語があります。
本質的に何が言いたいのかは、ソースコードに書いてあるのでそこから読み取ればいいだけです。
さて、また脱線しましたがlibpngでは下記ファイルを基点に調査してみてください。
- contrib/visupng - このフォルダのPngFile.cはWindowsの開発環境であればC&Pを行い、調整すればすぐに使えるzlib/libpngライセンスなソースコードが含まれています。VS使用者には取り付きやすいサンプルです。
- example.c - 実装前にどのようなlibpngの使い方について学習するのに使えそうです。
- pngtest.c - pngの読み込み・書き込みテスト用コード。コンパイル可能。
- libpng-manual.txt - libpngのマニュアルテキスト。各関数がどのような動作をするのかを調べたいときに使用できそうです。
- contrib - このフォルダ内にはサンプルソースコードが数点含まれています。デコーダー・エンコーダーの実装例等も含まれているので研究用に使えそうです。
pngファイルの読み込み実装
pngの高レベル関数を使用した画像の読み込みはそれほど難しくありません。
pngの読み込み処理の流れは最低限かつ簡単にまとめると、下記のようになります。
- pngのシグネチャ比較(png_sig_cmp)
- png読込構造体を生成(png_create_read_struct)
- png情報構造体を生成(png_create_info_struct)
- pngファイルのファイルからの読み込み(png_init_io)
- pngファイルフォーマットへ読込済みデータを変換(png_read_png)
- pngファイルの画像データ部分の抽出(png_get_rows)
- png処理の後始末(png_read_end等)
順番に実行していくだけであれば簡単に見えますね。
この間にエラー時処理・画像用メモリ領域の確保・高さ、幅、深度の計算等を含めていく必要があります。
png_init_ioとpng_set_read_fnはどちらを使用すれば?
ドキュメントを意訳すると下記のようになるはず。超意訳なのでこんな文章がどこに書いてあるのかとか探さないでください。
png_init_ioは「Stardard C」で実装されており、内部処理としてfreadで実装されています。
そのため、freadを使用できる環境であるのであれば、png_init_ioを使用することが可能です。
組み込み環境等特殊な実行環境である場合、png_set_read_fnを使用して、ファイルIO処理を行ってください。
Windows + VisualStudioが実行環境であるならば、png_init_ioを使用すれば問題ないでしょう。
何らかの手法で高速に読み出したい場合や特殊な機器構成により低レベルなファイルIO処理を利用しないといけない場合などはpng_set_read_fnを使用して呼ばれる関数内で読み込み処理を実装するといいでしょう。
例えば、libpngの中に含まれているexample.cの中で「Progressively read a file」という実装について書かれており、この実装はpng_set_read_fnに指定した関数内でpngの読み込み状況の進捗度合を算出しています。巨大なpngファイルが対象となっている場合には便利な処理です。
不明点等コメントいただければ可能であれば補足します。
以上